From python-checkins at python.org Wed Apr 1 00:03:41 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Apr 2009 00:03:41 +0200 (CEST) Subject: [Python-checkins] r70905 - python/trunk/Doc/distutils/apiref.rst Message-ID: <20090331220341.373321E43C6@bag.python.org> Author: georg.brandl Date: Wed Apr 1 00:03:40 2009 New Revision: 70905 Log: #5563: more documentation for bdist_msi. Modified: python/trunk/Doc/distutils/apiref.rst Modified: python/trunk/Doc/distutils/apiref.rst ============================================================================== --- python/trunk/Doc/distutils/apiref.rst (original) +++ python/trunk/Doc/distutils/apiref.rst Wed Apr 1 00:03:40 2009 @@ -1758,8 +1758,16 @@ .. module:: distutils.command.bdist_msi :synopsis: Build a binary distribution as a Windows MSI file +.. class:: bdist_msi(Command) -.. % todo + Builds a `Windows Installer`_ (.msi) binary package. + + .. _Windows Installer: http://msdn.microsoft.com/en-us/library/cc185688(VS.85).aspx + + In most cases, the ``bdist_msi`` installer is a better choice than the + ``bdist_wininst`` installer, because it provides better support for + Win64 platforms, allows administrators to perform non-interactive + installations, and allows installation through group policies. :mod:`distutils.command.bdist_rpm` --- Build a binary distribution as a Redhat RPM and SRPM From python-checkins at python.org Wed Apr 1 00:11:54 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Apr 2009 00:11:54 +0200 (CEST) Subject: [Python-checkins] r70906 - in python/trunk/Lib: sgmllib.py test/test_sgmllib.py Message-ID: <20090331221154.1AC2E1E406D@bag.python.org> Author: georg.brandl Date: Wed Apr 1 00:11:53 2009 New Revision: 70906 Log: #1651995: fix _convert_ref for non-ASCII characters. Modified: python/trunk/Lib/sgmllib.py python/trunk/Lib/test/test_sgmllib.py Modified: python/trunk/Lib/sgmllib.py ============================================================================== --- python/trunk/Lib/sgmllib.py (original) +++ python/trunk/Lib/sgmllib.py Wed Apr 1 00:11:53 2009 @@ -396,7 +396,7 @@ n = int(name) except ValueError: return - if not 0 <= n <= 255: + if not 0 <= n <= 127: return return self.convert_codepoint(n) Modified: python/trunk/Lib/test/test_sgmllib.py ============================================================================== --- python/trunk/Lib/test/test_sgmllib.py (original) +++ python/trunk/Lib/test/test_sgmllib.py Wed Apr 1 00:11:53 2009 @@ -373,6 +373,15 @@ if len(data) != CHUNK: break + def test_only_decode_ascii(self): + # SF bug #1651995, make sure non-ascii character references are not decoded + s = '' + self.check_events(s, [ + ('starttag', 'signs', + [('exclamation', '!'), ('copyright', '©'), + ('quoteleft', '‘')]), + ]) + # XXX These tests have been disabled by prefixing their names with # an underscore. The first two exercise outstanding bugs in the # sgmllib module, and the third exhibits questionable behavior From python-checkins at python.org Wed Apr 1 00:18:20 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Apr 2009 00:18:20 +0200 (CEST) Subject: [Python-checkins] r70907 - python/trunk/Doc/library/urllib.rst Message-ID: <20090331221820.06EA61E4033@bag.python.org> Author: georg.brandl Date: Wed Apr 1 00:18:19 2009 New Revision: 70907 Log: #3427: document correct return type for urlopen().info(). Modified: python/trunk/Doc/library/urllib.rst Modified: python/trunk/Doc/library/urllib.rst ============================================================================== --- python/trunk/Doc/library/urllib.rst (original) +++ python/trunk/Doc/library/urllib.rst Wed Apr 1 00:18:19 2009 @@ -49,7 +49,7 @@ .. index:: module: mimetools The :meth:`info` method returns an instance of the class - :class:`mimetools.Message` containing meta-information associated with the + :class:`httplib.HTTPMessage` containing meta-information associated with the URL. When the method is HTTP, these headers are those returned by the server at the head of the retrieved HTML page (including Content-Length and Content-Type). When the method is FTP, a Content-Length header will be From buildbot at python.org Wed Apr 1 00:20:15 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 31 Mar 2009 22:20:15 +0000 Subject: [Python-checkins] buildbot failure in x86 XP-4 3.x Message-ID: <20090331222015.9A6AE1E4033@bag.python.org> The Buildbot has detected a new failure of x86 XP-4 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20XP-4%203.x/builds/407 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: bolen-windows Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl,hirokazu.yamamoto,jeremy.hylton,jesse.noller,kristjan.jonsson,r.david.murray,raymond.hettinger BUILD FAILED: failed test Excerpt from the test logfile: 6 tests failed: test_distutils test_importlib test_memoryio test_posix test_urllib2net test_wait4 ====================================================================== ERROR: test_reg_class (distutils.tests.test_msvc9compiler.msvc9compilerTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\distutils\tests\test_msvc9compiler.py", line 51, in test_reg_class import _winreg ImportError: No module named _winreg ====================================================================== FAIL: test_package (importlib.test.source.test_abc_loader.PyLoaderTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\importlib\test\source\test_abc_loader.py", line 149, in test_package __loader__=mock) File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\importlib\test\source\test_abc_loader.py", line 126, in eq_attrs self.assertEqual(getattr(ob, attr), val) AssertionError: ['/path/to//__init__'] != ['/path/to/'] ====================================================================== FAIL: test_package (importlib.test.source.test_abc_loader.PyPycLoaderTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\importlib\test\source\test_abc_loader.py", line 264, in test_package mock, name = super().test_package() File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\importlib\test\source\test_abc_loader.py", line 149, in test_package __loader__=mock) File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\importlib\test\source\test_abc_loader.py", line 126, in eq_attrs self.assertEqual(getattr(ob, attr), val) AssertionError: ['/path/to//__init__'] != ['/path/to/'] ====================================================================== FAIL: test_issue5265 (test.test_memoryio.PyStringIOTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\test\test_memoryio.py", line 516, in test_issue5265 self.assertEqual(memio.read(5), "a\nb\n") AssertionError: 'a\n\nb\n' != 'a\nb\n' ====================================================================== FAIL: test_newline_none (test.test_memoryio.PyStringIOTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\test\test_memoryio.py", line 461, in test_newline_none self.assertEqual(list(memio), ["a\n", "b\n", "c\n", "d"]) AssertionError: ['a\n', 'b\n', '\n', 'c\n', 'd'] != ['a\n', 'b\n', 'c\n', 'd'] ====================================================================== FAIL: test_newlines_property (test.test_memoryio.PyStringIOTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\test\test_memoryio.py", line 431, in test_newlines_property self.assertEqual(memio.newlines, "\n") AssertionError: '\r\n' != '\n' Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\test\test_posix.py", line 6, in import posix ImportError: No module named posix Traceback (most recent call last): File "../lib/test/regrtest.py", line 612, in runtest_inner the_package = __import__(abstest, globals(), locals(), []) File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\test\test_posix.py", line 8, in raise unittest.SkipTest("posix is not available") NameError: name 'unittest' is not defined ====================================================================== ERROR: test_http_basic (test.test_urllib2net.TimeoutTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\test\test_urllib2net.py", line 198, in test_http_basic self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None) AttributeError: '_io.BufferedReader' object has no attribute 'fp' ====================================================================== ERROR: test_http_default_timeout (test.test_urllib2net.TimeoutTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\test\test_urllib2net.py", line 207, in test_http_default_timeout self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60) AttributeError: '_io.BufferedReader' object has no attribute 'fp' ====================================================================== ERROR: test_http_no_timeout (test.test_urllib2net.TimeoutTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\test\test_urllib2net.py", line 216, in test_http_no_timeout self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None) AttributeError: '_io.BufferedReader' object has no attribute 'fp' ====================================================================== ERROR: test_http_timeout (test.test_urllib2net.TimeoutTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\test\test_urllib2net.py", line 220, in test_http_timeout self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 120) AttributeError: '_io.BufferedReader' object has no attribute 'fp' Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\test\test_wait4.py", line 10, in os.fork AttributeError: 'module' object has no attribute 'fork' Traceback (most recent call last): File "../lib/test/regrtest.py", line 612, in runtest_inner the_package = __import__(abstest, globals(), locals(), []) File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\test\test_wait4.py", line 12, in raise unittest.SkipTest("os.fork not defined -- skipping test_wait4") NameError: name 'unittest' is not defined sincerely, -The Buildbot From python-checkins at python.org Wed Apr 1 00:20:36 2009 From: python-checkins at python.org (jesse.noller) Date: Wed, 1 Apr 2009 00:20:36 +0200 (CEST) Subject: [Python-checkins] r70908 - in python/trunk: Misc/ACKS Misc/NEWS Modules/_multiprocessing/win32_functions.c Python/pythonrun.c Message-ID: <20090331222036.34D921E4033@bag.python.org> Author: jesse.noller Date: Wed Apr 1 00:20:35 2009 New Revision: 70908 Log: Issue 5619: Pass MS CRT debug flags into subprocesses Modified: python/trunk/Misc/ACKS python/trunk/Misc/NEWS python/trunk/Modules/_multiprocessing/win32_functions.c python/trunk/Python/pythonrun.c Modified: python/trunk/Misc/ACKS ============================================================================== --- python/trunk/Misc/ACKS (original) +++ python/trunk/Misc/ACKS Wed Apr 1 00:20:35 2009 @@ -685,6 +685,7 @@ Nathan Sullivan Mark Summerfield Hisao Suzuki +Andrew Svetlov Kalle Svensson Paul Swartz Thenault Sylvain Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Apr 1 00:20:35 2009 @@ -199,6 +199,9 @@ Library ------- +- Issue #5619: Multiprocessing children disobey the debug flag and causes + popups on windows buildbots. Patch applied to work around this issue. + - Issue #5632: Thread.ident was None for the main thread and threads not created with the threading module. Modified: python/trunk/Modules/_multiprocessing/win32_functions.c ============================================================================== --- python/trunk/Modules/_multiprocessing/win32_functions.c (original) +++ python/trunk/Modules/_multiprocessing/win32_functions.c Wed Apr 1 00:20:35 2009 @@ -130,6 +130,12 @@ if (!PyArg_ParseTuple(args, "I", &uExitCode)) return NULL; + #if defined(Py_DEBUG) + SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOALIGNMENTFAULTEXCEPT|SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX); + _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); + #endif + + ExitProcess(uExitCode); return NULL; Modified: python/trunk/Python/pythonrun.c ============================================================================== --- python/trunk/Python/pythonrun.c (original) +++ python/trunk/Python/pythonrun.c Wed Apr 1 00:20:35 2009 @@ -1634,6 +1634,8 @@ Py_FatalError(const char *msg) { fprintf(stderr, "Fatal Python error: %s\n", msg); + fflush(stderr); /* it helps in Windows debug build */ + #ifdef MS_WINDOWS { size_t len = strlen(msg); From python-checkins at python.org Wed Apr 1 00:25:20 2009 From: python-checkins at python.org (jesse.noller) Date: Wed, 1 Apr 2009 00:25:20 +0200 (CEST) Subject: [Python-checkins] r70909 - in python/branches/release26-maint: Misc/ACKS Misc/NEWS Modules/_multiprocessing/win32_functions.c Python/pythonrun.c Message-ID: <20090331222520.6DCDF1E406D@bag.python.org> Author: jesse.noller Date: Wed Apr 1 00:25:20 2009 New Revision: 70909 Log: Merged revisions 70908 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70908 | jesse.noller | 2009-03-31 17:20:35 -0500 (Tue, 31 Mar 2009) | 1 line Issue 5619: Pass MS CRT debug flags into subprocesses ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Misc/ACKS python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Modules/_multiprocessing/win32_functions.c python/branches/release26-maint/Python/pythonrun.c Modified: python/branches/release26-maint/Misc/ACKS ============================================================================== --- python/branches/release26-maint/Misc/ACKS (original) +++ python/branches/release26-maint/Misc/ACKS Wed Apr 1 00:25:20 2009 @@ -674,6 +674,7 @@ Nathan Sullivan Mark Summerfield Hisao Suzuki +Andrew Svetlov Kalle Svensson Paul Swartz Thenault Sylvain Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Wed Apr 1 00:25:20 2009 @@ -92,6 +92,9 @@ Library ------- +- Issue #5619: Multiprocessing children disobey the debug flag and causes + popups on windows buildbots. Patch applied to work around this issue. + - Issue #5632: Thread.ident was None for the main thread and threads not created with the threading module. Modified: python/branches/release26-maint/Modules/_multiprocessing/win32_functions.c ============================================================================== --- python/branches/release26-maint/Modules/_multiprocessing/win32_functions.c (original) +++ python/branches/release26-maint/Modules/_multiprocessing/win32_functions.c Wed Apr 1 00:25:20 2009 @@ -130,6 +130,12 @@ if (!PyArg_ParseTuple(args, "I", &uExitCode)) return NULL; + #if defined(Py_DEBUG) + SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOALIGNMENTFAULTEXCEPT|SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX); + _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); + #endif + + ExitProcess(uExitCode); return NULL; Modified: python/branches/release26-maint/Python/pythonrun.c ============================================================================== --- python/branches/release26-maint/Python/pythonrun.c (original) +++ python/branches/release26-maint/Python/pythonrun.c Wed Apr 1 00:25:20 2009 @@ -1631,6 +1631,8 @@ Py_FatalError(const char *msg) { fprintf(stderr, "Fatal Python error: %s\n", msg); + fflush(stderr); /* it helps in Windows debug build */ + #ifdef MS_WINDOWS { size_t len = strlen(msg); From python-checkins at python.org Wed Apr 1 00:27:24 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 1 Apr 2009 00:27:24 +0200 (CEST) Subject: [Python-checkins] r70910 - in python/trunk: Doc/distutils/setupscript.rst Lib/distutils/command/build_ext.py Lib/distutils/extension.py Lib/distutils/tests/test_build_ext.py Misc/NEWS Message-ID: <20090331222724.3862A1E406D@bag.python.org> Author: tarek.ziade Date: Wed Apr 1 00:27:23 2009 New Revision: 70910 Log: #5583 Added optional Extensions in Distutils Modified: python/trunk/Doc/distutils/setupscript.rst python/trunk/Lib/distutils/command/build_ext.py python/trunk/Lib/distutils/extension.py python/trunk/Lib/distutils/tests/test_build_ext.py python/trunk/Misc/NEWS Modified: python/trunk/Doc/distutils/setupscript.rst ============================================================================== --- python/trunk/Doc/distutils/setupscript.rst (original) +++ python/trunk/Doc/distutils/setupscript.rst Wed Apr 1 00:27:23 2009 @@ -334,6 +334,10 @@ There are still some other options which can be used to handle special cases. +The :option:`optional` option is a boolean; if it is true, that specifies that +a build failure in the extension should not abort the build process, but simply +not install the failing extension. + The :option:`extra_objects` option is a list of object files to be passed to the linker. These files must not have extensions, as the default extension for the compiler is used. Modified: python/trunk/Lib/distutils/command/build_ext.py ============================================================================== --- python/trunk/Lib/distutils/command/build_ext.py (original) +++ python/trunk/Lib/distutils/command/build_ext.py Wed Apr 1 00:27:23 2009 @@ -476,7 +476,13 @@ self.check_extensions_list(self.extensions) for ext in self.extensions: - self.build_extension(ext) + try: + self.build_extension(ext) + except (CCompilerError, DistutilsError), e: + if not ext.optional: + raise + self.warn('building extension "%s" failed: %s' % + (ext.name, e)) def build_extension(self, ext): sources = ext.sources Modified: python/trunk/Lib/distutils/extension.py ============================================================================== --- python/trunk/Lib/distutils/extension.py (original) +++ python/trunk/Lib/distutils/extension.py Wed Apr 1 00:27:23 2009 @@ -83,6 +83,9 @@ language : string extension language (i.e. "c", "c++", "objc"). Will be detected from the source extensions if not provided. + optional : boolean + specifies that a build failure in the extension should not abort the + build process, but simply not install the failing extension. """ # When adding arguments to this constructor, be sure to update @@ -101,6 +104,7 @@ swig_opts = None, depends=None, language=None, + optional=None, **kw # To catch unknown keywords ): assert type(name) is StringType, "'name' must be a string" @@ -123,6 +127,7 @@ self.swig_opts = swig_opts or [] self.depends = depends or [] self.language = language + self.optional = optional # If there are unknown keyword options, warn about them if len(kw): Modified: python/trunk/Lib/distutils/tests/test_build_ext.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_build_ext.py (original) +++ python/trunk/Lib/distutils/tests/test_build_ext.py Wed Apr 1 00:27:23 2009 @@ -8,6 +8,8 @@ from distutils.command.build_ext import build_ext from distutils import sysconfig from distutils.tests import support +from distutils.extension import Extension +from distutils.errors import UnknownFileError import unittest from test import test_support @@ -20,7 +22,9 @@ srcdir = sysconfig.get_config_var('srcdir') return os.path.join(srcdir, 'Modules', 'xxmodule.c') -class BuildExtTestCase(support.TempdirManager, unittest.TestCase): +class BuildExtTestCase(support.TempdirManager, + support.LoggingSilencer, + unittest.TestCase): def setUp(self): # Create a simple test environment # Note that we're making changes to sys.path @@ -142,6 +146,22 @@ self.assert_(lib in cmd.library_dirs) self.assert_(incl in cmd.include_dirs) + def test_optional_extension(self): + + # this extension will fail, but let's ignore this failure + # with the optional argument. + modules = [Extension('foo', ['xxx'], optional=False)] + dist = Distribution({'name': 'xx', 'ext_modules': modules}) + cmd = build_ext(dist) + cmd.ensure_finalized() + self.assertRaises(UnknownFileError, cmd.run) # should raise an error + + modules = [Extension('foo', ['xxx'], optional=True)] + dist = Distribution({'name': 'xx', 'ext_modules': modules}) + cmd = build_ext(dist) + cmd.ensure_finalized() + cmd.run() # should pass + def test_suite(): src = _get_source_filename() if not os.path.exists(src): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Apr 1 00:27:23 2009 @@ -199,6 +199,9 @@ Library ------- +- Issue #5583: Added optional Extensions in Distutils. Initial patch by Georg + Brandl. + - Issue #5619: Multiprocessing children disobey the debug flag and causes popups on windows buildbots. Patch applied to work around this issue. From python-checkins at python.org Wed Apr 1 00:29:11 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 1 Apr 2009 00:29:11 +0200 (CEST) Subject: [Python-checkins] r70911 - python/branches/release26-maint Message-ID: <20090331222911.298701E406D@bag.python.org> Author: tarek.ziade Date: Wed Apr 1 00:29:10 2009 New Revision: 70911 Log: Blocked revisions 70910 via svnmerge ........ r70910 | tarek.ziade | 2009-03-31 17:27:23 -0500 (Tue, 31 Mar 2009) | 1 line #5583 Added optional Extensions in Distutils ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Wed Apr 1 00:35:46 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Apr 2009 00:35:46 +0200 (CEST) Subject: [Python-checkins] r70912 - python/trunk/Misc/gdbinit Message-ID: <20090331223546.D58851E406D@bag.python.org> Author: georg.brandl Date: Wed Apr 1 00:35:46 2009 New Revision: 70912 Log: #5617: add a handy function to print a unicode string to gdbinit. Modified: python/trunk/Misc/gdbinit Modified: python/trunk/Misc/gdbinit ============================================================================== --- python/trunk/Misc/gdbinit (original) +++ python/trunk/Misc/gdbinit Wed Apr 1 00:35:46 2009 @@ -138,3 +138,16 @@ end select-frame 0 end + +# generally useful macro to print a Unicode string +def pu + set $uni = $arg0 + set $i = 0 + while (*$uni && $i++<100) + if (*$uni < 0x80) + print *(char*)$uni++ + else + print /x *(short*)$uni++ + end + end +end From python-checkins at python.org Wed Apr 1 00:36:44 2009 From: python-checkins at python.org (jesse.noller) Date: Wed, 1 Apr 2009 00:36:44 +0200 (CEST) Subject: [Python-checkins] r70913 - in python/branches/py3k: Misc/ACKS Misc/NEWS Modules/_multiprocessing/win32_functions.c Python/pythonrun.c Message-ID: <20090331223644.DDCEA1E406D@bag.python.org> Author: jesse.noller Date: Wed Apr 1 00:36:44 2009 New Revision: 70913 Log: Merged revisions 70908 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70908 | jesse.noller | 2009-03-31 17:20:35 -0500 (Tue, 31 Mar 2009) | 1 line Issue 5619: Pass MS CRT debug flags into subprocesses ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_multiprocessing/win32_functions.c python/branches/py3k/Python/pythonrun.c Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Wed Apr 1 00:36:44 2009 @@ -689,6 +689,7 @@ Nathan Sullivan Mark Summerfield Hisao Suzuki +Andrew Svetlov Kalle Svensson Andrew Svetlov Paul Swartz Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Apr 1 00:36:44 2009 @@ -53,6 +53,9 @@ Library ------- +- Issue #5619: Multiprocessing children disobey the debug flag and causes + popups on windows buildbots. Patch applied to work around this issue. + - Issue #5400: Added patch for multiprocessing on netbsd compilation/support - Issue #5387: Fixed mmap.move crash by integer overflow. Modified: python/branches/py3k/Modules/_multiprocessing/win32_functions.c ============================================================================== --- python/branches/py3k/Modules/_multiprocessing/win32_functions.c (original) +++ python/branches/py3k/Modules/_multiprocessing/win32_functions.c Wed Apr 1 00:36:44 2009 @@ -130,6 +130,12 @@ if (!PyArg_ParseTuple(args, "I", &uExitCode)) return NULL; + #if defined(Py_DEBUG) + SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOALIGNMENTFAULTEXCEPT|SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX); + _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); + #endif + + ExitProcess(uExitCode); return NULL; Modified: python/branches/py3k/Python/pythonrun.c ============================================================================== --- python/branches/py3k/Python/pythonrun.c (original) +++ python/branches/py3k/Python/pythonrun.c Wed Apr 1 00:36:44 2009 @@ -2006,6 +2006,7 @@ Py_FatalError(const char *msg) { fprintf(stderr, "Fatal Python error: %s\n", msg); + fflush(stderr); /* it helps in Windows debug build */ if (PyErr_Occurred()) { PyErr_Print(); } From python-checkins at python.org Wed Apr 1 00:37:55 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 1 Apr 2009 00:37:55 +0200 (CEST) Subject: [Python-checkins] r70914 - in python/branches/py3k: Doc/distutils/setupscript.rst Lib/distutils/command/build_ext.py Lib/distutils/extension.py Lib/distutils/tests/test_build_ext.py Misc/NEWS Message-ID: <20090331223755.A49531E4133@bag.python.org> Author: tarek.ziade Date: Wed Apr 1 00:37:55 2009 New Revision: 70914 Log: Merged revisions 70910 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70910 | tarek.ziade | 2009-03-31 17:27:23 -0500 (Tue, 31 Mar 2009) | 1 line #5583 Added optional Extensions in Distutils ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/distutils/setupscript.rst python/branches/py3k/Lib/distutils/command/build_ext.py python/branches/py3k/Lib/distutils/extension.py python/branches/py3k/Lib/distutils/tests/test_build_ext.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/distutils/setupscript.rst ============================================================================== --- python/branches/py3k/Doc/distutils/setupscript.rst (original) +++ python/branches/py3k/Doc/distutils/setupscript.rst Wed Apr 1 00:37:55 2009 @@ -334,6 +334,10 @@ There are still some other options which can be used to handle special cases. +The :option:`optional` option is a boolean; if it is true, that specifies that +a build failure in the extension should not abort the build process, but simply +not install the failing extension. + The :option:`extra_objects` option is a list of object files to be passed to the linker. These files must not have extensions, as the default extension for the compiler is used. Modified: python/branches/py3k/Lib/distutils/command/build_ext.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/build_ext.py (original) +++ python/branches/py3k/Lib/distutils/command/build_ext.py Wed Apr 1 00:37:55 2009 @@ -455,7 +455,13 @@ self.check_extensions_list(self.extensions) for ext in self.extensions: - self.build_extension(ext) + try: + self.build_extension(ext) + except (CCompilerError, DistutilsError) as e: + if not ext.optional: + raise + self.warn('building extension "%s" failed: %s' % + (ext.name, e)) def build_extension(self, ext): sources = ext.sources Modified: python/branches/py3k/Lib/distutils/extension.py ============================================================================== --- python/branches/py3k/Lib/distutils/extension.py (original) +++ python/branches/py3k/Lib/distutils/extension.py Wed Apr 1 00:37:55 2009 @@ -82,6 +82,9 @@ language : string extension language (i.e. "c", "c++", "objc"). Will be detected from the source extensions if not provided. + optional : boolean + specifies that a build failure in the extension should not abort the + build process, but simply not install the failing extension. """ # When adding arguments to this constructor, be sure to update @@ -100,6 +103,7 @@ swig_opts = None, depends=None, language=None, + optional=None, **kw # To catch unknown keywords ): assert isinstance(name, str), "'name' must be a string" @@ -122,6 +126,7 @@ self.swig_opts = swig_opts or [] self.depends = depends or [] self.language = language + self.optional = optional # If there are unknown keyword options, warn about them if len(kw): Modified: python/branches/py3k/Lib/distutils/tests/test_build_ext.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_build_ext.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_build_ext.py Wed Apr 1 00:37:55 2009 @@ -8,6 +8,9 @@ from distutils.command.build_ext import build_ext from distutils import sysconfig from distutils.tests.support import TempdirManager +from distutils.tests.support import LoggingSilencer +from distutils.extension import Extension +from distutils.errors import UnknownFileError import unittest from test import support @@ -20,7 +23,9 @@ srcdir = sysconfig.get_config_var('srcdir') return os.path.join(srcdir, 'Modules', 'xxmodule.c') -class BuildExtTestCase(TempdirManager, unittest.TestCase): +class BuildExtTestCase(TempdirManager, + LoggingSilencer, + unittest.TestCase): def setUp(self): # Create a simple test environment # Note that we're making changes to sys.path @@ -141,6 +146,22 @@ self.assert_(lib in cmd.library_dirs) self.assert_(incl in cmd.include_dirs) + def test_optional_extension(self): + + # this extension will fail, but let's ignore this failure + # with the optional argument. + modules = [Extension('foo', ['xxx'], optional=False)] + dist = Distribution({'name': 'xx', 'ext_modules': modules}) + cmd = build_ext(dist) + cmd.ensure_finalized() + self.assertRaises(UnknownFileError, cmd.run) # should raise an error + + modules = [Extension('foo', ['xxx'], optional=True)] + dist = Distribution({'name': 'xx', 'ext_modules': modules}) + cmd = build_ext(dist) + cmd.ensure_finalized() + cmd.run() # should pass + def test_suite(): src = _get_source_filename() if not os.path.exists(src): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Apr 1 00:37:55 2009 @@ -282,6 +282,9 @@ Library ------- +- Issue #5583: Added optional Extensions in Distutils. Initial patch by Georg + Brandl. + - Issue #1222: locale.format() bug when the thousands separator is a space character. From python-checkins at python.org Wed Apr 1 00:40:16 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Apr 2009 00:40:16 +0200 (CEST) Subject: [Python-checkins] r70915 - python/trunk/Doc/tutorial/datastructures.rst Message-ID: <20090331224016.7A06D1E4074@bag.python.org> Author: georg.brandl Date: Wed Apr 1 00:40:16 2009 New Revision: 70915 Log: #5018: remove confusing paragraph. Modified: python/trunk/Doc/tutorial/datastructures.rst Modified: python/trunk/Doc/tutorial/datastructures.rst ============================================================================== --- python/trunk/Doc/tutorial/datastructures.rst (original) +++ python/trunk/Doc/tutorial/datastructures.rst Wed Apr 1 00:40:16 2009 @@ -401,13 +401,11 @@ >>> x, y, z = t -This is called, appropriately enough, *sequence unpacking*. Sequence unpacking -requires the list of variables on the left to have the same number of elements -as the length of the sequence. Note that multiple assignment is really just a -combination of tuple packing and sequence unpacking! - -There is a small bit of asymmetry here: packing multiple values always creates -a tuple, and unpacking works for any sequence. +This is called, appropriately enough, *sequence unpacking* and works for any +sequence on the right-hand side. Sequence unpacking requires the list of +variables on the left to have the same number of elements as the length of the +sequence. Note that multiple assignment is really just a combination of tuple +packing and sequence unpacking! .. XXX Add a bit on the difference between tuples and lists. From python-checkins at python.org Wed Apr 1 00:42:05 2009 From: python-checkins at python.org (jesse.noller) Date: Wed, 1 Apr 2009 00:42:05 +0200 (CEST) Subject: [Python-checkins] r70916 - in python/branches/release30-maint: Misc/ACKS Misc/NEWS Modules/_multiprocessing/win32_functions.c Python/pythonrun.c Message-ID: <20090331224205.E76271E4074@bag.python.org> Author: jesse.noller Date: Wed Apr 1 00:42:05 2009 New Revision: 70916 Log: Merged revisions 70913 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r70913 | jesse.noller | 2009-03-31 17:36:44 -0500 (Tue, 31 Mar 2009) | 9 lines Merged revisions 70908 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70908 | jesse.noller | 2009-03-31 17:20:35 -0500 (Tue, 31 Mar 2009) | 1 line Issue 5619: Pass MS CRT debug flags into subprocesses ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Misc/ACKS python/branches/release30-maint/Misc/NEWS python/branches/release30-maint/Modules/_multiprocessing/win32_functions.c python/branches/release30-maint/Python/pythonrun.c Modified: python/branches/release30-maint/Misc/ACKS ============================================================================== --- python/branches/release30-maint/Misc/ACKS (original) +++ python/branches/release30-maint/Misc/ACKS Wed Apr 1 00:42:05 2009 @@ -674,6 +674,7 @@ Nathan Sullivan Mark Summerfield Hisao Suzuki +Andrew Svetlov Kalle Svensson Andrew Svetlov Paul Swartz Modified: python/branches/release30-maint/Misc/NEWS ============================================================================== --- python/branches/release30-maint/Misc/NEWS (original) +++ python/branches/release30-maint/Misc/NEWS Wed Apr 1 00:42:05 2009 @@ -30,6 +30,9 @@ Library ------- +- Issue #5619: Multiprocessing children disobey the debug flag and causes + popups on windows buildbots. Patch applied to work around this issue. + - Issue #5387: Fixed mmap.move crash by integer overflow. - Issue #5595: Fix UnboundedLocalError in ntpath.ismount(). Modified: python/branches/release30-maint/Modules/_multiprocessing/win32_functions.c ============================================================================== --- python/branches/release30-maint/Modules/_multiprocessing/win32_functions.c (original) +++ python/branches/release30-maint/Modules/_multiprocessing/win32_functions.c Wed Apr 1 00:42:05 2009 @@ -130,6 +130,12 @@ if (!PyArg_ParseTuple(args, "I", &uExitCode)) return NULL; + #if defined(Py_DEBUG) + SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOALIGNMENTFAULTEXCEPT|SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX); + _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); + #endif + + ExitProcess(uExitCode); return NULL; Modified: python/branches/release30-maint/Python/pythonrun.c ============================================================================== --- python/branches/release30-maint/Python/pythonrun.c (original) +++ python/branches/release30-maint/Python/pythonrun.c Wed Apr 1 00:42:05 2009 @@ -1998,6 +1998,7 @@ Py_FatalError(const char *msg) { fprintf(stderr, "Fatal Python error: %s\n", msg); + fflush(stderr); /* it helps in Windows debug build */ if (PyErr_Occurred()) { PyErr_Print(); } From python-checkins at python.org Wed Apr 1 00:42:41 2009 From: python-checkins at python.org (martin.v.loewis) Date: Wed, 1 Apr 2009 00:42:41 +0200 (CEST) Subject: [Python-checkins] r70917 - python/branches/py3k/Tools/buildbot/test.bat Message-ID: <20090331224241.CD0771E4074@bag.python.org> Author: martin.v.loewis Date: Wed Apr 1 00:42:41 2009 New Revision: 70917 Log: Readd -n. 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 Wed Apr 1 00:42:41 2009 @@ -1,4 +1,4 @@ @rem Used by the buildbot "test" step. cd PCbuild -call rt.bat -d -q -uall -rw +call rt.bat -d -q -uall -rw -n From python-checkins at python.org Wed Apr 1 00:43:03 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 1 Apr 2009 00:43:03 +0200 (CEST) Subject: [Python-checkins] r70918 - python/trunk/Doc/library/collections.rst Message-ID: <20090331224303.75BC21E4074@bag.python.org> Author: raymond.hettinger Date: Wed Apr 1 00:43:03 2009 New Revision: 70918 Log: Improve examples for collections.deque() Modified: python/trunk/Doc/library/collections.rst Modified: python/trunk/Doc/library/collections.rst ============================================================================== --- python/trunk/Doc/library/collections.rst (original) +++ python/trunk/Doc/library/collections.rst Wed Apr 1 00:43:03 2009 @@ -463,6 +463,30 @@ This section shows various approaches to working with deques. +Bounded length deques provide functionality similar to the ``tail`` filter +in Unix:: + + def tail(filename, n=10): + 'Return the last n lines of a file' + return deque(open(filename), n) + +Another approach to using deques is to maintain a sequence of recently +added elements by appending to the right and popping to the left:: + + def moving_average(iterable, n=3): + # moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0 + # http://en.wikipedia.org/wiki/Moving_average + n = float(n) + it = iter(iterable) + d = deque(itertools.islice(it, n)) + s = sum(d) + if len(d) == n: + yield s / n + for elem in it: + s += elem - d.popleft() + d.append(elem) + yield s / n + The :meth:`rotate` method provides a way to implement :class:`deque` slicing and deletion. For example, a pure python implementation of ``del d[n]`` relies on the :meth:`rotate` method to position elements to be popped:: @@ -480,31 +504,6 @@ stack manipulations such as ``dup``, ``drop``, ``swap``, ``over``, ``pick``, ``rot``, and ``roll``. -Multi-pass data reduction algorithms can be succinctly expressed and efficiently -coded by extracting elements with multiple calls to :meth:`popleft`, applying -a reduction function, and calling :meth:`append` to add the result back to the -deque. - -For example, building a balanced binary tree of nested lists entails reducing -two adjacent nodes into one by grouping them in a list: - - >>> def maketree(iterable): - ... d = deque(iterable) - ... while len(d) > 1: - ... pair = [d.popleft(), d.popleft()] - ... d.append(pair) - ... return list(d) - ... - >>> print maketree('abcdefgh') - [[[['a', 'b'], ['c', 'd']], [['e', 'f'], ['g', 'h']]]] - -Bounded length deques provide functionality similar to the ``tail`` filter -in Unix:: - - def tail(filename, n=10): - 'Return the last n lines of a file' - return deque(open(filename), n) - :class:`defaultdict` objects ---------------------------- From python-checkins at python.org Wed Apr 1 00:43:15 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 1 Apr 2009 00:43:15 +0200 (CEST) Subject: [Python-checkins] r70919 - python/branches/release30-maint Message-ID: <20090331224315.E99831E4074@bag.python.org> Author: tarek.ziade Date: Wed Apr 1 00:43:15 2009 New Revision: 70919 Log: Blocked revisions 70914 via svnmerge ................ r70914 | tarek.ziade | 2009-03-31 17:37:55 -0500 (Tue, 31 Mar 2009) | 9 lines Merged revisions 70910 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70910 | tarek.ziade | 2009-03-31 17:27:23 -0500 (Tue, 31 Mar 2009) | 1 line #5583 Added optional Extensions in Distutils ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Wed Apr 1 00:44:10 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 1 Apr 2009 00:44:10 +0200 (CEST) Subject: [Python-checkins] r70920 - python/trunk/Lib/distutils/command/build_ext.py Message-ID: <20090331224410.ED59D1E40C1@bag.python.org> Author: tarek.ziade Date: Wed Apr 1 00:44:10 2009 New Revision: 70920 Log: catching msvc9compiler error as well Modified: python/trunk/Lib/distutils/command/build_ext.py Modified: python/trunk/Lib/distutils/command/build_ext.py ============================================================================== --- python/trunk/Lib/distutils/command/build_ext.py (original) +++ python/trunk/Lib/distutils/command/build_ext.py Wed Apr 1 00:44:10 2009 @@ -478,7 +478,7 @@ for ext in self.extensions: try: self.build_extension(ext) - except (CCompilerError, DistutilsError), e: + except (CCompilerError, DistutilsError, CompileError), e: if not ext.optional: raise self.warn('building extension "%s" failed: %s' % From python-checkins at python.org Wed Apr 1 00:46:50 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Apr 2009 00:46:50 +0200 (CEST) Subject: [Python-checkins] r70921 - python/branches/py3k/Tools/scripts/reindent-rst.py Message-ID: <20090331224650.8AE901E406D@bag.python.org> Author: georg.brandl Date: Wed Apr 1 00:46:50 2009 New Revision: 70921 Log: Run 2to3 over new script. Modified: python/branches/py3k/Tools/scripts/reindent-rst.py Modified: python/branches/py3k/Tools/scripts/reindent-rst.py ============================================================================== --- python/branches/py3k/Tools/scripts/reindent-rst.py (original) +++ python/branches/py3k/Tools/scripts/reindent-rst.py Wed Apr 1 00:46:50 2009 @@ -3,7 +3,7 @@ # Make a reST file compliant to our pre-commit hook. # Currently just remove trailing whitespace. -from __future__ import with_statement + import sys, re, shutil ws_re = re.compile(r'\s+(\r?\n)$') @@ -16,12 +16,12 @@ lines = f.readlines() new_lines = [ws_re.sub(r'\1', line) for line in lines] if new_lines != lines: - print 'Fixing %s...' % filename + print('Fixing %s...' % filename) shutil.copyfile(filename, filename + '.bak') with open(filename, 'wb') as f: f.writelines(new_lines) - except Exception, err: - print 'Cannot fix %s: %s' % (filename, err) + except Exception as err: + print('Cannot fix %s: %s' % (filename, err)) rv = 1 return rv From python-checkins at python.org Wed Apr 1 00:47:01 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 1 Apr 2009 00:47:01 +0200 (CEST) Subject: [Python-checkins] r70922 - python/trunk/Lib/distutils/tests/test_build_ext.py Message-ID: <20090331224701.7E7381E406D@bag.python.org> Author: tarek.ziade Date: Wed Apr 1 00:47:01 2009 New Revision: 70922 Log: fixed the test for win32 CompileError Modified: python/trunk/Lib/distutils/tests/test_build_ext.py Modified: python/trunk/Lib/distutils/tests/test_build_ext.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_build_ext.py (original) +++ python/trunk/Lib/distutils/tests/test_build_ext.py Wed Apr 1 00:47:01 2009 @@ -10,6 +10,7 @@ from distutils.tests import support from distutils.extension import Extension from distutils.errors import UnknownFileError +from distutils.errors import CompileError import unittest from test import test_support @@ -154,7 +155,8 @@ dist = Distribution({'name': 'xx', 'ext_modules': modules}) cmd = build_ext(dist) cmd.ensure_finalized() - self.assertRaises(UnknownFileError, cmd.run) # should raise an error + self.assertRaises((UnknownFileError, CompileError), + cmd.run) # should raise an error modules = [Extension('foo', ['xxx'], optional=True)] dist = Distribution({'name': 'xx', 'ext_modules': modules}) From python at rcn.com Wed Apr 1 00:47:01 2009 From: python at rcn.com (Raymond Hettinger) Date: Tue, 31 Mar 2009 15:47:01 -0700 Subject: [Python-checkins] r70915 -python/trunk/Doc/tutorial/datastructures.rst References: <20090331224016.7A06D1E4074@bag.python.org> Message-ID: <13BFBDAB0FF044C1868725499EEABE1F@RaymondLaptop1> > -This is called, appropriately enough, *sequence unpacking*. Sequence unpacking > -requires the list of variables on the left to have the same number of elements > -as the length of the sequence. Note that multiple assignment is really just a > -combination of tuple packing and sequence unpacking! > - > -There is a small bit of asymmetry here: packing multiple values always creates > -a tuple, and unpacking works for any sequence. > +This is called, appropriately enough, *sequence unpacking* and works for any > +sequence on the right-hand side. Sequence unpacking requires the list of > +variables on the left to have the same number of elements as the length of the > +sequence. Note that multiple assignment is really just a combination of tuple > +packing and sequence unpacking! A general comment on writing style in the docs: we ought to go easy on exclamation points and keep a more even-toned style. Raymond From python-checkins at python.org Wed Apr 1 00:48:36 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 1 Apr 2009 00:48:36 +0200 (CEST) Subject: [Python-checkins] r70923 - python/branches/release26-maint Message-ID: <20090331224836.3DD941E406D@bag.python.org> Author: tarek.ziade Date: Wed Apr 1 00:48:36 2009 New Revision: 70923 Log: Blocked revisions 70920,70922 via svnmerge ........ r70920 | tarek.ziade | 2009-03-31 17:44:10 -0500 (Tue, 31 Mar 2009) | 1 line catching msvc9compiler error as well ........ r70922 | tarek.ziade | 2009-03-31 17:47:01 -0500 (Tue, 31 Mar 2009) | 1 line fixed the test for win32 CompileError ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Wed Apr 1 00:50:54 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 1 Apr 2009 00:50:54 +0200 (CEST) Subject: [Python-checkins] r70924 - in python/branches/py3k: Lib/distutils/command/build_ext.py Lib/distutils/tests/test_build_ext.py Message-ID: <20090331225054.B8ADB1E406D@bag.python.org> Author: tarek.ziade Date: Wed Apr 1 00:50:54 2009 New Revision: 70924 Log: Merged revisions 70920,70922 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70920 | tarek.ziade | 2009-03-31 17:44:10 -0500 (Tue, 31 Mar 2009) | 1 line catching msvc9compiler error as well ........ r70922 | tarek.ziade | 2009-03-31 17:47:01 -0500 (Tue, 31 Mar 2009) | 1 line fixed the test for win32 CompileError ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/command/build_ext.py python/branches/py3k/Lib/distutils/tests/test_build_ext.py Modified: python/branches/py3k/Lib/distutils/command/build_ext.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/build_ext.py (original) +++ python/branches/py3k/Lib/distutils/command/build_ext.py Wed Apr 1 00:50:54 2009 @@ -457,7 +457,7 @@ for ext in self.extensions: try: self.build_extension(ext) - except (CCompilerError, DistutilsError) as e: + except (CCompilerError, DistutilsError, CompileError) as e: if not ext.optional: raise self.warn('building extension "%s" failed: %s' % Modified: python/branches/py3k/Lib/distutils/tests/test_build_ext.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_build_ext.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_build_ext.py Wed Apr 1 00:50:54 2009 @@ -11,6 +11,7 @@ from distutils.tests.support import LoggingSilencer from distutils.extension import Extension from distutils.errors import UnknownFileError +from distutils.errors import CompileError import unittest from test import support @@ -154,7 +155,8 @@ dist = Distribution({'name': 'xx', 'ext_modules': modules}) cmd = build_ext(dist) cmd.ensure_finalized() - self.assertRaises(UnknownFileError, cmd.run) # should raise an error + self.assertRaises((UnknownFileError, CompileError), + cmd.run) # should raise an error modules = [Extension('foo', ['xxx'], optional=True)] dist = Distribution({'name': 'xx', 'ext_modules': modules}) From python-checkins at python.org Wed Apr 1 00:52:48 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 1 Apr 2009 00:52:48 +0200 (CEST) Subject: [Python-checkins] r70925 - python/branches/py3k/Doc/library/collections.rst Message-ID: <20090331225248.F0AD31E406D@bag.python.org> Author: raymond.hettinger Date: Wed Apr 1 00:52:48 2009 New Revision: 70925 Log: Improve examples for collections.deque() Modified: python/branches/py3k/Doc/library/collections.rst Modified: python/branches/py3k/Doc/library/collections.rst ============================================================================== --- python/branches/py3k/Doc/library/collections.rst (original) +++ python/branches/py3k/Doc/library/collections.rst Wed Apr 1 00:52:48 2009 @@ -442,6 +442,29 @@ This section shows various approaches to working with deques. +Bounded length deques provide functionality similar to the ``tail`` filter +in Unix:: + + def tail(filename, n=10): + 'Return the last n lines of a file' + return deque(open(filename), n) + +Another approach to using deques is to maintain a sequence of recently +added elements by appending to the right and popping to the left:: + + def moving_average(iterable, n=3): + # moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0 + # http://en.wikipedia.org/wiki/Moving_average + it = iter(iterable) + d = deque(itertools.islice(it, n)) + s = sum(d) + if len(d) == n: + yield s / n + for elem in it: + s += elem - d.popleft() + d.append(elem) + yield s / n + The :meth:`rotate` method provides a way to implement :class:`deque` slicing and deletion. For example, a pure python implementation of ``del d[n]`` relies on the :meth:`rotate` method to position elements to be popped:: @@ -459,31 +482,6 @@ stack manipulations such as ``dup``, ``drop``, ``swap``, ``over``, ``pick``, ``rot``, and ``roll``. -Multi-pass data reduction algorithms can be succinctly expressed and efficiently -coded by extracting elements with multiple calls to :meth:`popleft`, applying -a reduction function, and calling :meth:`append` to add the result back to the -deque. - -For example, building a balanced binary tree of nested lists entails reducing -two adjacent nodes into one by grouping them in a list: - - >>> def maketree(iterable): - ... d = deque(iterable) - ... while len(d) > 1: - ... pair = [d.popleft(), d.popleft()] - ... d.append(pair) - ... return list(d) - ... - >>> print(maketree('abcdefgh')) - [[[['a', 'b'], ['c', 'd']], [['e', 'f'], ['g', 'h']]]] - -Bounded length deques provide functionality similar to the ``tail`` filter -in Unix:: - - def tail(filename, n=10): - 'Return the last n lines of a file' - return deque(open(filename), n) - :class:`defaultdict` objects ---------------------------- From python-checkins at python.org Wed Apr 1 00:52:58 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 1 Apr 2009 00:52:58 +0200 (CEST) Subject: [Python-checkins] r70926 - python/branches/release30-maint Message-ID: <20090331225258.CC6951E406D@bag.python.org> Author: tarek.ziade Date: Wed Apr 1 00:52:58 2009 New Revision: 70926 Log: Blocked revisions 70924 via svnmerge ................ r70924 | tarek.ziade | 2009-03-31 17:50:54 -0500 (Tue, 31 Mar 2009) | 13 lines Merged revisions 70920,70922 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70920 | tarek.ziade | 2009-03-31 17:44:10 -0500 (Tue, 31 Mar 2009) | 1 line catching msvc9compiler error as well ........ r70922 | tarek.ziade | 2009-03-31 17:47:01 -0500 (Tue, 31 Mar 2009) | 1 line fixed the test for win32 CompileError ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Wed Apr 1 01:01:27 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Apr 2009 01:01:27 +0200 (CEST) Subject: [Python-checkins] r70927 - python/trunk/Doc/tutorial/datastructures.rst Message-ID: <20090331230127.403051E406D@bag.python.org> Author: georg.brandl Date: Wed Apr 1 01:01:27 2009 New Revision: 70927 Log: Dont shout to users. Modified: python/trunk/Doc/tutorial/datastructures.rst Modified: python/trunk/Doc/tutorial/datastructures.rst ============================================================================== --- python/trunk/Doc/tutorial/datastructures.rst (original) +++ python/trunk/Doc/tutorial/datastructures.rst Wed Apr 1 01:01:27 2009 @@ -405,7 +405,7 @@ sequence on the right-hand side. Sequence unpacking requires the list of variables on the left to have the same number of elements as the length of the sequence. Note that multiple assignment is really just a combination of tuple -packing and sequence unpacking! +packing and sequence unpacking. .. XXX Add a bit on the difference between tuples and lists. From python-checkins at python.org Wed Apr 1 01:11:33 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 1 Apr 2009 01:11:33 +0200 (CEST) Subject: [Python-checkins] r70928 - in python/branches/py3k: Lib/_pyio.py Lib/test/test_io.py Misc/NEWS Modules/_textio.c Message-ID: <20090331231133.2DCD01E43D0@bag.python.org> Author: benjamin.peterson Date: Wed Apr 1 01:11:32 2009 New Revision: 70928 Log: fix TextIOWrapper.read() when the buffer is not readable #5628 Modified: python/branches/py3k/Lib/_pyio.py python/branches/py3k/Lib/test/test_io.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_textio.c Modified: python/branches/py3k/Lib/_pyio.py ============================================================================== --- python/branches/py3k/Lib/_pyio.py (original) +++ python/branches/py3k/Lib/_pyio.py Wed Apr 1 01:11:32 2009 @@ -1696,6 +1696,7 @@ return cookie def read(self, n=None): + self._checkReadable() if n is None: n = -1 decoder = self._decoder or self._get_decoder() 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 Wed Apr 1 01:11:32 2009 @@ -1754,6 +1754,13 @@ self.assertEquals(f.read(), data * 2) self.assertEquals(buf.getvalue(), (data * 2).encode(encoding)) + def test_unreadable(self): + class UnReadable(self.BytesIO): + def readable(self): + return False + txt = self.TextIOWrapper(UnReadable()) + self.assertRaises(IOError, txt.read) + def test_read_one_by_one(self): txt = self.TextIOWrapper(self.BytesIO(b"AA\r\nBB")) reads = "" Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Apr 1 01:11:32 2009 @@ -53,6 +53,8 @@ Library ------- +- Issue #5628: Fix io.TextIOWrapper.read() with a unreadable buffer. + - Issue #5619: Multiprocessing children disobey the debug flag and causes popups on windows buildbots. Patch applied to work around this issue. Modified: python/branches/py3k/Modules/_textio.c ============================================================================== --- python/branches/py3k/Modules/_textio.c (original) +++ python/branches/py3k/Modules/_textio.c Wed Apr 1 01:11:32 2009 @@ -1348,6 +1348,11 @@ CHECK_CLOSED(self); + if (self->decoder == NULL) { + PyErr_SetString(PyExc_IOError, "not readable"); + return NULL; + } + if (_TextIOWrapper_writeflush(self) < 0) return NULL; From python-checkins at python.org Wed Apr 1 01:16:51 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 1 Apr 2009 01:16:51 +0200 (CEST) Subject: [Python-checkins] r70929 - in python/branches/py3k: Lib/test/regrtest.py Lib/test/support.py Lib/test/test_asynchat.py Lib/test/test_bz2.py Lib/test/test_crypt.py Lib/test/test_ctypes.py Lib/test/test_curses.py Lib/test/test_dbm.py Lib/test/test_fcntl.py Lib/test/test_fork1.py Lib/test/test_grp.py Lib/test/test_ioctl.py Lib/test/test_mmap.py Lib/test/test_multiprocessing.py Lib/test/test_nis.py Lib/test/test_ossaudiodev.py Lib/test/test_posix.py Lib/test/test_pwd.py Lib/test/test_resource.py Lib/test/test_sqlite.py Lib/test/test_startfile.py Lib/test/test_tcl.py Lib/test/test_tk.py Lib/test/test_ttk_guionly.py Lib/test/test_ttk_textonly.py Lib/test/test_winreg.py Lib/test/test_winsound.py Lib/test/test_xml_etree_c.py Lib/test/test_zlib.py Misc/NEWS Message-ID: <20090331231651.5E3C71E4070@bag.python.org> Author: r.david.murray Date: Wed Apr 1 01:16:50 2009 New Revision: 70929 Log: Blocked revisions 70734,70775,70856,70874,70876-70877 via svnmerge ........ r70734 | r.david.murray | 2009-03-30 15:04:00 -0400 (Mon, 30 Mar 2009) | 7 lines Add import_function method to test.test_support, and modify a number of tests that expect to be skipped if imports fail or functions don't exist to use import_function and import_module. The ultimate goal is to change regrtest to not skip automatically on ImportError. Checking in now to make sure the buldbots don't show any errors on platforms I can't direct test on. ........ r70775 | r.david.murray | 2009-03-30 19:05:48 -0400 (Mon, 30 Mar 2009) | 4 lines Change more tests to use import_module for the modules that should cause tests to be skipped. Also rename import_function to the more descriptive get_attribute and add a docstring. ........ r70856 | r.david.murray | 2009-03-31 14:32:17 -0400 (Tue, 31 Mar 2009) | 7 lines A few more test skips via import_module, and change import_module to return the error message produced by importlib, so that if an import in the package whose import is being wrapped is what failed the skip message will contain the name of that module instead of the name of the wrapped module. Also fixed formatting of some previous comments. ........ r70874 | r.david.murray | 2009-03-31 15:33:15 -0400 (Tue, 31 Mar 2009) | 5 lines Improve test_support.import_module docstring, remove deprecated flag from get_attribute since it isn't likely to do anything useful. ........ r70876 | r.david.murray | 2009-03-31 15:49:15 -0400 (Tue, 31 Mar 2009) | 4 lines Remove the regrtest check that turns any ImportError into a skipped test. Hopefully all modules whose imports legitimately result in a skipped test have been properly wrapped by the previous commits. ........ r70877 | r.david.murray | 2009-03-31 15:57:24 -0400 (Tue, 31 Mar 2009) | 2 lines Add NEWS entry for regrtest change. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/regrtest.py python/branches/py3k/Lib/test/support.py python/branches/py3k/Lib/test/test_asynchat.py python/branches/py3k/Lib/test/test_bz2.py python/branches/py3k/Lib/test/test_crypt.py python/branches/py3k/Lib/test/test_ctypes.py python/branches/py3k/Lib/test/test_curses.py python/branches/py3k/Lib/test/test_dbm.py python/branches/py3k/Lib/test/test_fcntl.py python/branches/py3k/Lib/test/test_fork1.py python/branches/py3k/Lib/test/test_grp.py python/branches/py3k/Lib/test/test_ioctl.py python/branches/py3k/Lib/test/test_mmap.py python/branches/py3k/Lib/test/test_multiprocessing.py python/branches/py3k/Lib/test/test_nis.py python/branches/py3k/Lib/test/test_ossaudiodev.py python/branches/py3k/Lib/test/test_posix.py python/branches/py3k/Lib/test/test_pwd.py python/branches/py3k/Lib/test/test_resource.py python/branches/py3k/Lib/test/test_sqlite.py python/branches/py3k/Lib/test/test_startfile.py python/branches/py3k/Lib/test/test_tcl.py python/branches/py3k/Lib/test/test_tk.py python/branches/py3k/Lib/test/test_ttk_guionly.py python/branches/py3k/Lib/test/test_ttk_textonly.py python/branches/py3k/Lib/test/test_winreg.py python/branches/py3k/Lib/test/test_winsound.py python/branches/py3k/Lib/test/test_xml_etree_c.py python/branches/py3k/Lib/test/test_zlib.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 Wed Apr 1 01:16:50 2009 @@ -628,7 +628,7 @@ print(test, "skipped --", msg) sys.stdout.flush() return -2 - except (ImportError, unittest.SkipTest) as msg: + except unittest.SkipTest as msg: if not quiet: print(test, "skipped --", msg) sys.stdout.flush() Modified: python/branches/py3k/Lib/test/support.py ============================================================================== --- python/branches/py3k/Lib/test/support.py (original) +++ python/branches/py3k/Lib/test/support.py Wed Apr 1 01:16:50 2009 @@ -12,6 +12,7 @@ import shutil import warnings import unittest +import importlib __all__ = ["Error", "TestFailed", "ResourceDenied", "import_module", "verbose", "use_resources", "max_memuse", "record_original_stdout", @@ -24,7 +25,7 @@ "TransientResource", "transient_internet", "run_with_locale", "set_memlimit", "bigmemtest", "bigaddrspacetest", "BasicTestRunner", "run_unittest", "run_doctest", "threading_setup", "threading_cleanup", - "reap_children", "cpython_only", "check_impl_detail"] + "reap_children", "cpython_only", "check_impl_detail", "get_attribute"] class Error(Exception): """Base class for regression test exceptions.""" @@ -41,19 +42,32 @@ """ def import_module(name, deprecated=False): - """Import the module to be tested, raising SkipTest if it is not - available.""" + """Import and return the module to be tested, raising SkipTest if + it is not available. + + If deprecated is True, any module or package deprecation messages + will be suppressed.""" with warnings.catch_warnings(): if deprecated: warnings.filterwarnings("ignore", ".+ (module|package)", DeprecationWarning) try: - module = __import__(name, level=0) - except ImportError: - raise unittest.SkipTest("No module named " + name) + module = importlib.import_module(name) + except ImportError as msg: + raise unittest.SkipTest(str(msg)) else: return module +def get_attribute(obj, name): + """Get an attribute, raising SkipTest if AttributeError is raised.""" + try: + attribute = getattr(obj, name) + except AttributeError: + raise unittest.SkipTest("module %s has no attribute %s" % ( + obj.__name__, name)) + else: + return attribute + verbose = 1 # Flag set to 0 by regrtest.py use_resources = None # Flag set to [] by regrtest.py max_memuse = 0 # Disable bigmem tests (they will still be run with Modified: python/branches/py3k/Lib/test/test_asynchat.py ============================================================================== --- python/branches/py3k/Lib/test/test_asynchat.py (original) +++ python/branches/py3k/Lib/test/test_asynchat.py Wed Apr 1 01:16:50 2009 @@ -1,10 +1,13 @@ -# test asynchat -- requires threading +# test asynchat + +from test import support + +# If this fails, the test will be skipped. +thread = support.import_module('_thread') -import _thread as thread # If this fails, we can't test this module import asyncore, asynchat, socket, threading, time import unittest import sys -from test import support HOST = support.HOST SERVER_QUIT = b'QUIT\n' Modified: python/branches/py3k/Lib/test/test_bz2.py ============================================================================== --- python/branches/py3k/Lib/test/test_bz2.py (original) +++ python/branches/py3k/Lib/test/test_bz2.py Wed Apr 1 01:16:50 2009 @@ -8,7 +8,9 @@ import subprocess import sys -import bz2 +# Skip tests if the bz2 module doesn't exist. +bz2 = support.import_module('bz2') + from bz2 import BZ2File, BZ2Compressor, BZ2Decompressor has_cmdline_bunzip2 = sys.platform not in ("win32", "os2emx") Modified: python/branches/py3k/Lib/test/test_crypt.py ============================================================================== --- python/branches/py3k/Lib/test/test_crypt.py (original) +++ python/branches/py3k/Lib/test/test_crypt.py Wed Apr 1 01:16:50 2009 @@ -1,6 +1,7 @@ from test import support import unittest -import crypt + +crypt = support.import_module('crypt') class CryptTestCase(unittest.TestCase): Modified: python/branches/py3k/Lib/test/test_ctypes.py ============================================================================== --- python/branches/py3k/Lib/test/test_ctypes.py (original) +++ python/branches/py3k/Lib/test/test_ctypes.py Wed Apr 1 01:16:50 2009 @@ -1,6 +1,10 @@ import unittest -from test.support import run_unittest +from test.support import run_unittest, import_module + +# Skip tests if _ctypes module was not built. +import_module('_ctypes') + import ctypes.test def test_main(): Modified: python/branches/py3k/Lib/test/test_curses.py ============================================================================== --- python/branches/py3k/Lib/test/test_curses.py (original) +++ python/branches/py3k/Lib/test/test_curses.py Wed Apr 1 01:16:50 2009 @@ -9,16 +9,19 @@ # Only called, not tested: getmouse(), ungetmouse() # -import curses, sys, tempfile, os -import curses.panel +import sys, tempfile, os # Optionally test curses module. This currently requires that the # 'curses' resource be given on the regrtest command line using the -u # option. If not available, nothing after this line will be executed. -from test.support import requires +from test.support import requires, import_module requires('curses') +# If either of these don't exist, skip the tests. +curses = import_module('curses') +curses.panel = import_module('curses.panel') + # XXX: if newterm was supported we could use it instead of initscr and not exit term = os.environ.get('TERM') if not term or term == 'unknown': Modified: python/branches/py3k/Lib/test/test_dbm.py ============================================================================== --- python/branches/py3k/Lib/test/test_dbm.py (original) +++ python/branches/py3k/Lib/test/test_dbm.py Wed Apr 1 01:16:50 2009 @@ -3,10 +3,12 @@ import os import unittest -import dbm import glob import test.support +# Skip tests if dbm module doesn't exist. +dbm = test.support.import_module('dbm') + _fname = test.support.TESTFN # Modified: python/branches/py3k/Lib/test/test_fcntl.py ============================================================================== --- python/branches/py3k/Lib/test/test_fcntl.py (original) +++ python/branches/py3k/Lib/test/test_fcntl.py Wed Apr 1 01:16:50 2009 @@ -3,12 +3,15 @@ OS/2+EMX doesn't support the file locking operations. """ -import fcntl import os import struct import sys import unittest -from test.support import verbose, TESTFN, unlink, run_unittest +from test.support import verbose, TESTFN, unlink, run_unittest, import_module + +# Skip test if no fnctl module. +fcntl = import_module('fcntl') + # TODO - Write tests for flock() and lockf(). 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 Wed Apr 1 01:16:50 2009 @@ -3,14 +3,12 @@ import os import time -import unittest from test.fork_wait import ForkWait -from test.support import run_unittest, reap_children +from test.support import run_unittest, reap_children, get_attribute + +# Skip test if fork does not exist. +get_attribute(os, 'fork') -try: - os.fork -except AttributeError: - raise unittest.SkipTest("os.fork not defined -- skipping test_fork1") class ForkTest(ForkWait): def wait_impl(self, cpid): 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 Wed Apr 1 01:16:50 2009 @@ -1,9 +1,10 @@ """Test script for the grp module.""" -import grp import unittest from test import support +grp = support.import_module('grp') + class GroupDatabaseTestCase(unittest.TestCase): def check_value(self, value): Modified: python/branches/py3k/Lib/test/test_ioctl.py ============================================================================== --- python/branches/py3k/Lib/test/test_ioctl.py (original) +++ python/branches/py3k/Lib/test/test_ioctl.py Wed Apr 1 01:16:50 2009 @@ -1,12 +1,9 @@ import unittest -from test.support import run_unittest +from test.support import run_unittest, import_module, get_attribute import os, struct -try: - import fcntl, termios -except ImportError: - raise unittest.SkipTest("No fcntl or termios module") -if not hasattr(termios,'TIOCGPGRP'): - raise unittest.SkipTest("termios module doesn't have TIOCGPGRP") +fcntl = import_module('fcntl') +termios = import_module('termios') +get_attribute(termios, 'TIOCGPGRP') #Can't run tests without this feature try: tty = open("/dev/tty", "r") Modified: python/branches/py3k/Lib/test/test_mmap.py ============================================================================== --- python/branches/py3k/Lib/test/test_mmap.py (original) +++ python/branches/py3k/Lib/test/test_mmap.py Wed Apr 1 01:16:50 2009 @@ -1,8 +1,10 @@ -from test.support import TESTFN, run_unittest -import mmap +from test.support import TESTFN, run_unittest, import_module import unittest import os, re, itertools +# Skip test if we can't import mmap. +mmap = import_module('mmap') + PAGESIZE = mmap.PAGESIZE class MmapTests(unittest.TestCase): Modified: python/branches/py3k/Lib/test/test_multiprocessing.py ============================================================================== --- python/branches/py3k/Lib/test/test_multiprocessing.py (original) +++ python/branches/py3k/Lib/test/test_multiprocessing.py Wed Apr 1 01:16:50 2009 @@ -17,20 +17,19 @@ import socket import random import logging +import test.support -# Work around broken sem_open implementations -try: - import multiprocessing.synchronize -except ImportError as e: - raise unittest.SkipTest(e) +# Skip tests if _multiprocessing wasn't built. +_multiprocessing = test.support.import_module('_multiprocessing') +# Skip tests if sem_open implementation is broken. +test.support.import_module('multiprocessing.synchronize') import multiprocessing.dummy import multiprocessing.connection import multiprocessing.managers import multiprocessing.heap import multiprocessing.pool -import _multiprocessing from multiprocessing import util Modified: python/branches/py3k/Lib/test/test_nis.py ============================================================================== --- python/branches/py3k/Lib/test/test_nis.py (original) +++ python/branches/py3k/Lib/test/test_nis.py Wed Apr 1 01:16:50 2009 @@ -1,6 +1,8 @@ from test import support import unittest -import nis + +# Skip test if nis module does not exist. +nis = support.import_module('nis') raise unittest.SkipTest("test_nis hangs on Solaris") Modified: python/branches/py3k/Lib/test/test_ossaudiodev.py ============================================================================== --- python/branches/py3k/Lib/test/test_ossaudiodev.py (original) +++ python/branches/py3k/Lib/test/test_ossaudiodev.py Wed Apr 1 01:16:50 2009 @@ -3,8 +3,9 @@ from test.support import findfile +ossaudiodev = support.import_module('ossaudiodev') + import errno -import ossaudiodev import sys import sunau import time Modified: python/branches/py3k/Lib/test/test_posix.py ============================================================================== --- python/branches/py3k/Lib/test/test_posix.py (original) +++ python/branches/py3k/Lib/test/test_posix.py Wed Apr 1 01:16:50 2009 @@ -2,17 +2,15 @@ from test import support -try: - import posix -except ImportError: - raise unittest.SkipTest("posix is not available") - import time import os import pwd import shutil import unittest import warnings + +posix = support.import_module('posix') + warnings.filterwarnings('ignore', '.* potential security risk .*', RuntimeWarning) Modified: python/branches/py3k/Lib/test/test_pwd.py ============================================================================== --- python/branches/py3k/Lib/test/test_pwd.py (original) +++ python/branches/py3k/Lib/test/test_pwd.py Wed Apr 1 01:16:50 2009 @@ -1,7 +1,7 @@ import unittest from test import support -import pwd +pwd = support.import_module('pwd') class PwdTest(unittest.TestCase): Modified: python/branches/py3k/Lib/test/test_resource.py ============================================================================== --- python/branches/py3k/Lib/test/test_resource.py (original) +++ python/branches/py3k/Lib/test/test_resource.py Wed Apr 1 01:16:50 2009 @@ -1,9 +1,9 @@ import unittest from test import support - -import resource import time +resource = support.import_module('resource') + # This test is checking a few specific problem spots with the resource module. class ResourceTest(unittest.TestCase): Modified: python/branches/py3k/Lib/test/test_sqlite.py ============================================================================== --- python/branches/py3k/Lib/test/test_sqlite.py (original) +++ python/branches/py3k/Lib/test/test_sqlite.py Wed Apr 1 01:16:50 2009 @@ -1,10 +1,9 @@ import unittest -from test.support import run_unittest +from test.support import run_unittest, import_module + +# Skip test if _sqlite3 module not installed +import_module('_sqlite3') -try: - import _sqlite3 -except ImportError: - raise unittest.SkipTest('no sqlite available') from sqlite3.test import (dbapi, types, userfunctions, factory, transactions, hooks, regression, dump) Modified: python/branches/py3k/Lib/test/test_startfile.py ============================================================================== --- python/branches/py3k/Lib/test/test_startfile.py (original) +++ python/branches/py3k/Lib/test/test_startfile.py Wed Apr 1 01:16:50 2009 @@ -9,9 +9,11 @@ import unittest from test import support +import os +from os import path + +startfile = support.get_attribute(os, 'startfile') -# use this form so that the test is skipped when startfile is not available: -from os import startfile, path class TestCase(unittest.TestCase): def test_nonexisting(self): Modified: python/branches/py3k/Lib/test/test_tcl.py ============================================================================== --- python/branches/py3k/Lib/test/test_tcl.py (original) +++ python/branches/py3k/Lib/test/test_tcl.py Wed Apr 1 01:16:50 2009 @@ -2,8 +2,11 @@ import unittest import os -import _tkinter from test import support + +# Skip this test if the _tkinter module wasn't built. +_tkinter = support.import_module('_tkinter') + from tkinter import Tcl from _tkinter import TclError Modified: python/branches/py3k/Lib/test/test_tk.py ============================================================================== --- python/branches/py3k/Lib/test/test_tk.py (original) +++ python/branches/py3k/Lib/test/test_tk.py Wed Apr 1 01:16:50 2009 @@ -3,6 +3,11 @@ from test import support import unittest +# Skip test if _tkinter wasn't built. +support.import_module('_tkinter') + +import tkinter + try: tkinter.Button() except tkinter.TclError as msg: Modified: python/branches/py3k/Lib/test/test_ttk_guionly.py ============================================================================== --- python/branches/py3k/Lib/test/test_ttk_guionly.py (original) +++ python/branches/py3k/Lib/test/test_ttk_guionly.py Wed Apr 1 01:16:50 2009 @@ -1,11 +1,15 @@ import os import sys -from tkinter import ttk -from tkinter.test import runtktests import unittest -from _tkinter import TclError from test import support +# Skip this test if _tkinter wasn't built. +support.import_module('_tkinter') + +from _tkinter import TclError +from tkinter import ttk +from tkinter.test import runtktests + try: ttk.Button() except TclError as msg: Modified: python/branches/py3k/Lib/test/test_ttk_textonly.py ============================================================================== --- python/branches/py3k/Lib/test/test_ttk_textonly.py (original) +++ python/branches/py3k/Lib/test/test_ttk_textonly.py Wed Apr 1 01:16:50 2009 @@ -1,6 +1,10 @@ import os import sys from test import support + +# Skip this test if _tkinter does not exist. +support.import_module('_tkinter') + from tkinter.test import runtktests def test_main(): Modified: python/branches/py3k/Lib/test/test_winreg.py ============================================================================== --- python/branches/py3k/Lib/test/test_winreg.py (original) +++ python/branches/py3k/Lib/test/test_winreg.py Wed Apr 1 01:16:50 2009 @@ -2,12 +2,15 @@ # Test the windows specific win32reg module. # Only win32reg functions not hit here: FlushKey, LoadKey and SaveKey -from winreg import * import os, sys import unittest - from test import support +# Do this first so test will be skipped if module doesn't exist +support.import_module('winreg') +# Now import everything +from winreg import * + test_key_name = "SOFTWARE\\Python Registry Test Key - Delete Me" test_data = [ Modified: python/branches/py3k/Lib/test/test_winsound.py ============================================================================== --- python/branches/py3k/Lib/test/test_winsound.py (original) +++ python/branches/py3k/Lib/test/test_winsound.py Wed Apr 1 01:16:50 2009 @@ -3,10 +3,12 @@ import unittest from test import support support.requires('audio') -import winsound, time +import time import os import subprocess +winsound = support.import_module('winsound') + class BeepTest(unittest.TestCase): # As with PlaySoundTest, incorporate the _have_soundcard() check 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 Wed Apr 1 01:16:50 2009 @@ -5,7 +5,7 @@ from test import support -from xml.etree import cElementTree as ET +ET = support.import_module('xml.etree.cElementTree') SAMPLE_XML = """ 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 Apr 1 01:16:50 2009 @@ -1,9 +1,10 @@ import unittest from test import support -import zlib import binascii import random +zlib = support.import_module('zlib') + class ChecksumTestCase(unittest.TestCase): # checksum test cases Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Apr 1 01:16:50 2009 @@ -725,6 +725,10 @@ Tests ----- +- regrtest no longer treats ImportError as equivalent to SkipTest. Imports + that should cause a test to be skipped are now done using import_module + from test support, which does the conversion. + - Issue #5083: New 'gui' resource for regrtest. From python-checkins at python.org Wed Apr 1 01:22:11 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Apr 2009 01:22:11 +0200 (CEST) Subject: [Python-checkins] r70929 - svn:log Message-ID: <20090331232212.1F3121E4146@bag.python.org> Author: georg.brandl Revision: 70929 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -1,4 +1,4 @@ -Blocked revisions 70734,70775,70856,70874,70876-70877 via svnmerge +Merged revisions 70734,70775,70856,70874,70876-70877 via svnmerge ........ r70734 | r.david.murray | 2009-03-30 15:04:00 -0400 (Mon, 30 Mar 2009) | 7 lines From python-checkins at python.org Wed Apr 1 01:45:39 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 1 Apr 2009 01:45:39 +0200 (CEST) Subject: [Python-checkins] r70930 - in python/trunk/Lib/test: test_sqlite.py test_wait4.py Message-ID: <20090331234539.360F31E406D@bag.python.org> Author: r.david.murray Date: Wed Apr 1 01:45:39 2009 New Revision: 70930 Log: Fix Windows test skip error revealed by buildbot. Also a comment spelling correction in a previously fixed test. Modified: python/trunk/Lib/test/test_sqlite.py python/trunk/Lib/test/test_wait4.py Modified: python/trunk/Lib/test/test_sqlite.py ============================================================================== --- python/trunk/Lib/test/test_sqlite.py (original) +++ python/trunk/Lib/test/test_sqlite.py Wed Apr 1 01:45:39 2009 @@ -1,7 +1,7 @@ import unittest from test.test_support import run_unittest, import_module -#Skip test of _sqlite3 module not installed +# Skip test if _sqlite3 module was not built. import_module('_sqlite3') from sqlite3.test import (dbapi, types, userfunctions, py25tests, Modified: python/trunk/Lib/test/test_wait4.py ============================================================================== --- python/trunk/Lib/test/test_wait4.py (original) +++ python/trunk/Lib/test/test_wait4.py Wed Apr 1 01:45:39 2009 @@ -4,17 +4,12 @@ import os import time from test.fork_wait import ForkWait -from test.test_support import run_unittest, reap_children +from test.test_support import run_unittest, reap_children, get_attribute -try: - os.fork -except AttributeError: - raise unittest.SkipTest, "os.fork not defined -- skipping test_wait4" +# If either of these do not exist, skip this test. +get_attribute(os, 'fork') +get_attribute(os, 'wait4') -try: - os.wait4 -except AttributeError: - raise unittest.SkipTest, "os.wait4 not defined -- skipping test_wait4" class Wait4Test(ForkWait): def wait_impl(self, cpid): From python-checkins at python.org Wed Apr 1 01:46:48 2009 From: python-checkins at python.org (jack.diederich) Date: Wed, 1 Apr 2009 01:46:48 +0200 (CEST) Subject: [Python-checkins] r70931 - in python/trunk: Lib/test/test_functools.py Misc/ACKS Misc/NEWS Modules/_functoolsmodule.c Message-ID: <20090331234648.E4B091E406D@bag.python.org> Author: jack.diederich Date: Wed Apr 1 01:46:48 2009 New Revision: 70931 Log: #5228: add pickle support to functools.partial Modified: python/trunk/Lib/test/test_functools.py python/trunk/Misc/ACKS python/trunk/Misc/NEWS python/trunk/Modules/_functoolsmodule.c Modified: python/trunk/Lib/test/test_functools.py ============================================================================== --- python/trunk/Lib/test/test_functools.py (original) +++ python/trunk/Lib/test/test_functools.py Wed Apr 1 01:46:48 2009 @@ -2,6 +2,7 @@ import unittest from test import test_support from weakref import proxy +import pickle @staticmethod def PythonPartial(func, *args, **keywords): @@ -19,6 +20,10 @@ """capture all positional and keyword arguments""" return args, kw +def signature(part): + """ return the signature of a partial object """ + return (part.func, part.args, part.keywords, part.__dict__) + class TestPartial(unittest.TestCase): thetype = functools.partial @@ -140,6 +145,12 @@ join = self.thetype(''.join) self.assertEqual(join(data), '0123456789') + def test_pickle(self): + f = self.thetype(signature, 'asdf', bar=True) + f.add_something_to__dict__ = True + f_copy = pickle.loads(pickle.dumps(f)) + self.assertEqual(signature(f), signature(f_copy)) + class PartialSubclass(functools.partial): pass @@ -147,11 +158,13 @@ thetype = PartialSubclass - class TestPythonPartial(TestPartial): thetype = PythonPartial + # the python version isn't picklable + def test_pickle(self): pass + class TestUpdateWrapper(unittest.TestCase): def check_wrapper(self, wrapper, wrapped, Modified: python/trunk/Misc/ACKS ============================================================================== --- python/trunk/Misc/ACKS (original) +++ python/trunk/Misc/ACKS Wed Apr 1 01:46:48 2009 @@ -168,6 +168,7 @@ Raghuram Devarakonda Toby Dickenson Mark Dickinson +Jack Diederich Yves Dionne Daniel Dittmar Jaromir Dolecek Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Apr 1 01:46:48 2009 @@ -710,6 +710,8 @@ - Issue #4396: The parser module now correctly validates the with statement. +- Issue #5228: Make functools.partial objects can now be pickled. + Tests ----- Modified: python/trunk/Modules/_functoolsmodule.c ============================================================================== --- python/trunk/Modules/_functoolsmodule.c (original) +++ python/trunk/Modules/_functoolsmodule.c Wed Apr 1 01:46:48 2009 @@ -274,6 +274,53 @@ {NULL} /* Sentinel */ }; +/* Pickle strategy: + __reduce__ by itself doesn't support getting kwargs in the unpickle + operation so we define a __setstate__ that replaces all the information + about the partial. If we only replaced part of it someone would use + it as a hook to do stange things. + */ + +PyObject * +partial_reduce(partialobject *pto, PyObject *unused) +{ + return Py_BuildValue("O(O)(OOOO)", Py_TYPE(pto), pto->fn, pto->fn, + pto->args, pto->kw, + pto->dict ? pto->dict : Py_None); +} + +PyObject * +partial_setstate(partialobject *pto, PyObject *args) +{ + PyObject *fn, *fnargs, *kw, *dict; + if (!PyArg_ParseTuple(args, "(OOOO):__setstate__", + &fn, &fnargs, &kw, &dict)) + return NULL; + Py_XDECREF(pto->fn); + Py_XDECREF(pto->args); + Py_XDECREF(pto->kw); + Py_XDECREF(pto->dict); + pto->fn = fn; + pto->args = fnargs; + pto->kw = kw; + if (dict != Py_None) { + pto->dict = dict; + Py_INCREF(dict); + } else { + pto->dict = NULL; + } + Py_INCREF(fn); + Py_INCREF(fnargs); + Py_INCREF(kw); + Py_RETURN_NONE; +} + +static PyMethodDef partial_methods[] = { + {"__reduce__", (PyCFunction)partial_reduce, METH_NOARGS}, + {"__setstate__", (PyCFunction)partial_setstate, METH_VARARGS}, + {NULL, NULL} /* sentinel */ +}; + static PyTypeObject partial_type = { PyVarObject_HEAD_INIT(NULL, 0) "functools.partial", /* tp_name */ @@ -304,7 +351,7 @@ offsetof(partialobject, weakreflist), /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - 0, /* tp_methods */ + partial_methods, /* tp_methods */ partial_memberlist, /* tp_members */ partial_getsetlist, /* tp_getset */ 0, /* tp_base */ From python-checkins at python.org Wed Apr 1 01:50:31 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 1 Apr 2009 01:50:31 +0200 (CEST) Subject: [Python-checkins] r70932 - in python/branches/py3k: Lib/test/test_wait4.py Message-ID: <20090331235031.5A3751E406D@bag.python.org> Author: r.david.murray Date: Wed Apr 1 01:50:31 2009 New Revision: 70932 Log: Merged revisions 70930 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70930 | r.david.murray | 2009-03-31 19:45:39 -0400 (Tue, 31 Mar 2009) | 3 lines Fix Windows test skip error revealed by buildbot. Also a comment spelling correction in a previously fixed test. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_wait4.py Modified: python/branches/py3k/Lib/test/test_wait4.py ============================================================================== --- python/branches/py3k/Lib/test/test_wait4.py (original) +++ python/branches/py3k/Lib/test/test_wait4.py Wed Apr 1 01:50:31 2009 @@ -4,17 +4,12 @@ import os import time from test.fork_wait import ForkWait -from test.support import run_unittest, reap_children +from test.support import run_unittest, reap_children, get_attribute -try: - os.fork -except AttributeError: - raise unittest.SkipTest("os.fork not defined -- skipping test_wait4") +# If either of these do not exist, skip this test. +get_attribute(os, 'fork') +get_attribute(os, 'wait4') -try: - os.wait4 -except AttributeError: - raise unittest.SkipTest("os.wait4 not defined -- skipping test_wait4") class Wait4Test(ForkWait): def wait_impl(self, cpid): From python-checkins at python.org Wed Apr 1 02:04:33 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Apr 2009 02:04:33 +0200 (CEST) Subject: [Python-checkins] r70933 - in python/trunk: Lib/test/test_sys.py Misc/NEWS Message-ID: <20090401000433.A28E01E42F3@bag.python.org> Author: georg.brandl Date: Wed Apr 1 02:04:33 2009 New Revision: 70933 Log: Issue #5635: Fix running test_sys with tracing enabled. Modified: python/trunk/Lib/test/test_sys.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/test/test_sys.py ============================================================================== --- python/trunk/Lib/test/test_sys.py (original) +++ python/trunk/Lib/test/test_sys.py Wed Apr 1 02:04:33 2009 @@ -221,6 +221,11 @@ sys.setdlopenflags(oldflags) def test_refcount(self): + # n here must be a global in order for this test to pass while + # tracing with a python function. Tracing calls PyFrame_FastToLocals + # which will add a copy of any locals to the frame object, causing + # the reference count to increase by 2 instead of 1. + global n self.assertRaises(TypeError, sys.getrefcount) c = sys.getrefcount(None) n = None Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Apr 1 02:04:33 2009 @@ -1,4 +1,5 @@ -+++++++++++ Python News ++++++++++++ +Python News +++++++++++ (editors: check NEWS.help for information about editing NEWS using ReST.) @@ -715,6 +716,8 @@ Tests ----- +- Issue #5635: Fix running test_sys with tracing enabled. + - regrtest no longer treats ImportError as equivalent to SkipTest. Imports that should cause a test to be skipped are now done using import_module from test support, which does the conversion. From buildbot at python.org Wed Apr 1 02:12:51 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 01 Apr 2009 00:12:51 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable trunk Message-ID: <20090401001251.C2EFA1E406D@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%20trunk/builds/297 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: benjamin.peterson,georg.brandl,gregory.p.smith,hirokazu.yamamoto,josiah.carlson,r.david.murray,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_asyncore test_multiprocessing ====================================================================== FAIL: test_readwrite (test.test_asyncore.HelperFunctionTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/test/test_asyncore.py", line 144, in test_readwrite self.assertEqual(tobj.read, True) AssertionError: False != True ====================================================================== FAIL: test_unhandled (test.test_asyncore.DispatcherTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/test/test_asyncore.py", line 321, in test_unhandled self.assertEquals(lines, expected) AssertionError: First differing element 0: ====================================================================== FAIL: test_event (test.test_multiprocessing.WithThreadsTestEvent) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/test/test_multiprocessing.py", line 754, in test_event self.assertEqual(wait(0.0), None) AssertionError: False != None ====================================================================== FAIL: test_event (test.test_multiprocessing.WithManagerTestEvent) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/test/test_multiprocessing.py", line 754, in test_event self.assertEqual(wait(0.0), None) AssertionError: False != None make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Wed Apr 1 02:38:32 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 01 Apr 2009 00:38:32 +0000 Subject: [Python-checkins] buildbot failure in x86 XP-4 trunk Message-ID: <20090401003832.E4A7E1E4066@bag.python.org> The Buildbot has detected a new failure of x86 XP-4 trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20XP-4%20trunk/builds/2005 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: bolen-windows Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: georg.brandl,gregory.p.smith,hirokazu.yamamoto,jesse.noller,josiah.carlson,r.david.murray,raymond.hettinger BUILD FAILED: failed failed slave lost sincerely, -The Buildbot From python-checkins at python.org Wed Apr 1 03:28:12 2009 From: python-checkins at python.org (josiah.carlson) Date: Wed, 1 Apr 2009 03:28:12 +0200 (CEST) Subject: [Python-checkins] r70934 - in python/trunk: Doc/library/asyncore.rst Lib/asyncore.py Lib/test/test_asyncore.py Message-ID: <20090401012812.075C71E4090@bag.python.org> Author: josiah.carlson Date: Wed Apr 1 03:28:11 2009 New Revision: 70934 Log: Fix for failing asyncore tests. Modified: python/trunk/Doc/library/asyncore.rst python/trunk/Lib/asyncore.py python/trunk/Lib/test/test_asyncore.py Modified: python/trunk/Doc/library/asyncore.rst ============================================================================== --- python/trunk/Doc/library/asyncore.rst (original) +++ python/trunk/Doc/library/asyncore.rst Wed Apr 1 03:28:11 2009 @@ -81,7 +81,8 @@ +----------------------+----------------------------------------+ | Event | Description | +======================+========================================+ - | ``handle_connect()`` | Implied by the first write event | + | ``handle_connect()`` | Implied by the first read or write | + | | event | +----------------------+----------------------------------------+ | ``handle_close()`` | Implied by a read event with no data | | | available | Modified: python/trunk/Lib/asyncore.py ============================================================================== --- python/trunk/Lib/asyncore.py (original) +++ python/trunk/Lib/asyncore.py Wed Apr 1 03:28:11 2009 @@ -401,7 +401,7 @@ sys.stderr.write('log: %s\n' % str(message)) def log_info(self, message, type='info'): - if __debug__ or type not in self.ignore_log_types: + if type not in self.ignore_log_types: print '%s: %s' % (type, message) def handle_read_event(self): Modified: python/trunk/Lib/test/test_asyncore.py ============================================================================== --- python/trunk/Lib/test/test_asyncore.py (original) +++ python/trunk/Lib/test/test_asyncore.py Wed Apr 1 03:28:11 2009 @@ -298,6 +298,7 @@ def test_unhandled(self): d = asyncore.dispatcher() + d.ignore_log_types = () # capture output of dispatcher.log_info() (to stdout via print) fp = StringIO() @@ -313,7 +314,7 @@ sys.stdout = stdout lines = fp.getvalue().splitlines() - expected = ['warning: unhandled exception', + expected = ['warning: unhandled incoming priority event', 'warning: unhandled read event', 'warning: unhandled write event', 'warning: unhandled connect event', From buildbot at python.org Wed Apr 1 03:33:06 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 01 Apr 2009 01:33:06 +0000 Subject: [Python-checkins] buildbot failure in x86 XP-4 3.x Message-ID: <20090401013306.C56251E4090@bag.python.org> The Buildbot has detected a new failure of x86 XP-4 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20XP-4%203.x/builds/409 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: bolen-windows Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson,georg.brandl,jesse.noller,martin.v.loewis,r.david.murray,raymond.hettinger,tarek.ziade BUILD FAILED: failed compile sincerely, -The Buildbot From buildbot at python.org Wed Apr 1 03:35:44 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 01 Apr 2009 01:35:44 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 3.0 Message-ID: <20090401013545.05CBB1E4070@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%20gentoo%203.0/builds/216 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-amd64 Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: jesse.noller,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_smtplib make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Wed Apr 1 04:19:07 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 01 Apr 2009 02:19:07 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 3.0 Message-ID: <20090401021908.2487E1E405D@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%203.0/builds/237 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: jesse.noller,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Wed Apr 1 04:35:57 2009 From: python-checkins at python.org (jeremy.hylton) Date: Wed, 1 Apr 2009 04:35:57 +0200 (CEST) Subject: [Python-checkins] r70935 - python/branches/py3k/Lib/http/client.py Message-ID: <20090401023557.278761E40E0@bag.python.org> Author: jeremy.hylton Date: Wed Apr 1 04:35:56 2009 New Revision: 70935 Log: An HTTPResponse is, by its nature, readable. Modified: python/branches/py3k/Lib/http/client.py Modified: python/branches/py3k/Lib/http/client.py ============================================================================== --- python/branches/py3k/Lib/http/client.py (original) +++ python/branches/py3k/Lib/http/client.py Wed Apr 1 04:35:56 2009 @@ -469,6 +469,9 @@ def flush(self): self.fp.flush() + def readable(self): + return True + # End of "raw stream" methods def isclosed(self): From buildbot at python.org Wed Apr 1 04:39:48 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 01 Apr 2009 02:39:48 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090401023948.A5FF81E4090@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/239 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: jesse.noller,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From buildbot at python.org Wed Apr 1 04:46:20 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 01 Apr 2009 02:46:20 +0000 Subject: [Python-checkins] buildbot failure in x86 XP-4 2.6 Message-ID: <20090401024620.6AE961E43D4@bag.python.org> The Buildbot has detected a new failure of x86 XP-4 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20XP-4%202.6/builds/167 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: bolen-windows Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: benjamin.peterson,jesse.noller,tarek.ziade BUILD FAILED: failed compile sincerely, -The Buildbot From python-checkins at python.org Wed Apr 1 05:21:43 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 1 Apr 2009 05:21:43 +0200 (CEST) Subject: [Python-checkins] r70936 - in python/trunk: Lib/locale.py Lib/test/test_locale.py Misc/ACKS Misc/NEWS Message-ID: <20090401032143.E38BC1E4515@bag.python.org> Author: r.david.murray Date: Wed Apr 1 05:21:43 2009 New Revision: 70936 Log: Fix issue 2522. locale.format now checks that it is passed exactly one pattern, which avoids mysterious errors where it had seemed to fail to do localization. Modified: python/trunk/Lib/locale.py python/trunk/Lib/test/test_locale.py python/trunk/Misc/ACKS python/trunk/Misc/NEWS Modified: python/trunk/Lib/locale.py ============================================================================== --- python/trunk/Lib/locale.py (original) +++ python/trunk/Lib/locale.py Wed Apr 1 05:21:43 2009 @@ -11,7 +11,11 @@ """ -import sys, encodings, encodings.aliases +import sys +import encodings +import encodings.aliases +import re +import operator import functools # Try importing the _locale module. @@ -166,6 +170,9 @@ amount -= 1 return s[lpos:rpos+1] +_percent_re = re.compile(r'%(?:\((?P.*?)\))?' + r'(?P[-#0-9 +*.hlL]*?)[eEfFgGdiouxXcrs%]') + def format(percent, value, grouping=False, monetary=False, *additional): """Returns the locale-aware substitution of a %? specifier (percent). @@ -173,9 +180,13 @@ additional is for format strings which contain one or more '*' modifiers.""" # this is only for one-percent-specifier strings and this should be checked - if percent[0] != '%': - raise ValueError("format() must be given exactly one %char " - "format specifier") + match = _percent_re.match(percent) + if not match or len(match.group())!= len(percent): + raise ValueError(("format() must be given exactly one %%char " + "format specifier, %s not valid") % repr(percent)) + return _format(percent, value, grouping, monetary, *additional) + +def _format(percent, value, grouping=False, monetary=False, *additional): if additional: formatted = percent % ((value,) + additional) else: @@ -199,10 +210,6 @@ formatted = _strip_padding(formatted, seps) return formatted -import re, operator -_percent_re = re.compile(r'%(?:\((?P.*?)\))?' - r'(?P[-#0-9 +*.hlL]*?)[eEfFgGdiouxXcrs%]') - def format_string(f, val, grouping=False): """Formats a string in the same way that the % formatting would use, but takes the current locale into account. Modified: python/trunk/Lib/test/test_locale.py ============================================================================== --- python/trunk/Lib/test/test_locale.py (original) +++ python/trunk/Lib/test/test_locale.py Wed Apr 1 05:21:43 2009 @@ -221,6 +221,19 @@ (self.sep, self.sep)) +class TestFormatPatternArg(unittest.TestCase): + # Test handling of pattern argument of format + + def test_onlyOnePattern(self): + # Issue 2522: accept exactly one % pattern, and no extra chars. + self.assertRaises(ValueError, locale.format, "%f\n", 'foo') + self.assertRaises(ValueError, locale.format, "%f\r", 'foo') + self.assertRaises(ValueError, locale.format, "%f\r\n", 'foo') + self.assertRaises(ValueError, locale.format, " %f", 'foo') + self.assertRaises(ValueError, locale.format, "%fg", 'foo') + self.assertRaises(ValueError, locale.format, "%^g", 'foo') + + class TestNumberFormatting(BaseLocalizedTest, EnUSNumberFormatting): # Test number formatting with a real English locale. @@ -351,6 +364,7 @@ def test_main(): tests = [ TestMiscellaneous, + TestFormatPatternArg, TestEnUSNumberFormatting, TestCNumberFormatting, TestFrFRNumberFormatting, Modified: python/trunk/Misc/ACKS ============================================================================== --- python/trunk/Misc/ACKS (original) +++ python/trunk/Misc/ACKS Wed Apr 1 05:21:43 2009 @@ -480,6 +480,7 @@ Chad Miller Jay T. Miller Roman Milner +Andrii V. Mishkovskyi Dustin J. Mitchell Dom Mitchell Doug Moen @@ -490,6 +491,7 @@ Sjoerd Mullender Sape Mullender Michael Muller +R. David Murray Piotr Meyer John Nagle Takahiro Nakayama Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Apr 1 05:21:43 2009 @@ -200,6 +200,10 @@ Library ------- +- Issue #2522: locale.format now checks its first argument to ensure it has + been passed only one pattern, avoiding mysterious errors where it appeared + that it was failing to do localization. + - Issue #5583: Added optional Extensions in Distutils. Initial patch by Georg Brandl. From python-checkins at python.org Wed Apr 1 05:35:21 2009 From: python-checkins at python.org (brett.cannon) Date: Wed, 1 Apr 2009 05:35:21 +0200 (CEST) Subject: [Python-checkins] r70937 - python/branches/py3k/Lib/importlib/_bootstrap.py Message-ID: <20090401033521.27CCD1E4090@bag.python.org> Author: brett.cannon Date: Wed Apr 1 05:35:20 2009 New Revision: 70937 Log: Rip out a useless method that the superclass implements properly. Modified: python/branches/py3k/Lib/importlib/_bootstrap.py Modified: python/branches/py3k/Lib/importlib/_bootstrap.py ============================================================================== --- python/branches/py3k/Lib/importlib/_bootstrap.py (original) +++ python/branches/py3k/Lib/importlib/_bootstrap.py Wed Apr 1 05:35:20 2009 @@ -475,25 +475,6 @@ # Not a property so that it is easy to override. return self._find_path(imp.PY_SOURCE) - @_check_name - def get_source(self, fullname): - """Return the source for the module as a string. - - Return None if the source is not available. Raise ImportError if the - laoder cannot handle the specified module. - - """ - source_path = self._source_path(name) - if source_path is None: - return None - import tokenize - with _closing(_io.FileIO(source_path, 'r')) as file: # Assuming bytes. - encoding, lines = tokenize.detect_encoding(file.readline) - # XXX Will fail when passed to compile() if the encoding is - # anything other than UTF-8. - return open(source_path, encoding=encoding).read() - - def get_data(self, path): """Return the data from path as raw bytes.""" return _io.FileIO(path, 'r').read() # Assuming bytes. From python-checkins at python.org Wed Apr 1 05:42:00 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 1 Apr 2009 05:42:00 +0200 (CEST) Subject: [Python-checkins] r70938 - in python/branches/py3k: Lib/locale.py Lib/test/test_locale.py Misc/ACKS Misc/NEWS Message-ID: <20090401034200.7A5331E4090@bag.python.org> Author: r.david.murray Date: Wed Apr 1 05:42:00 2009 New Revision: 70938 Log: Merged revisions 70936 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70936 | r.david.murray | 2009-03-31 23:21:43 -0400 (Tue, 31 Mar 2009) | 4 lines Fix issue 2522. locale.format now checks that it is passed exactly one pattern, which avoids mysterious errors where it had seemed to fail to do localization. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/locale.py python/branches/py3k/Lib/test/test_locale.py python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/locale.py ============================================================================== --- python/branches/py3k/Lib/locale.py (original) +++ python/branches/py3k/Lib/locale.py Wed Apr 1 05:42:00 2009 @@ -11,7 +11,11 @@ """ -import sys, encodings, encodings.aliases +import sys +import encodings +import encodings.aliases +import re +import collections from builtins import str as _builtin_str import functools @@ -173,6 +177,9 @@ amount -= 1 return s[lpos:rpos+1] +_percent_re = re.compile(r'%(?:\((?P.*?)\))?' + r'(?P[-#0-9 +*.hlL]*?)[eEfFgGdiouxXcrs%]') + def format(percent, value, grouping=False, monetary=False, *additional): """Returns the locale-aware substitution of a %? specifier (percent). @@ -180,9 +187,13 @@ additional is for format strings which contain one or more '*' modifiers.""" # this is only for one-percent-specifier strings and this should be checked - if percent[0] != '%': - raise ValueError("format() must be given exactly one %char " - "format specifier") + match = _percent_re.match(percent) + if not match or len(match.group())!= len(percent): + raise ValueError(("format() must be given exactly one %%char " + "format specifier, %s not valid") % repr(percent)) + return _format(percent, value, grouping, monetary, *additional) + +def _format(percent, value, grouping=False, monetary=False, *additional): if additional: formatted = percent % ((value,) + additional) else: @@ -206,10 +217,6 @@ formatted = _strip_padding(formatted, seps) return formatted -import re, collections -_percent_re = re.compile(r'%(?:\((?P.*?)\))?' - r'(?P[-#0-9 +*.hlL]*?)[eEfFgGdiouxXcrs%]') - def format_string(f, val, grouping=False): """Formats a string in the same way that the % formatting would use, but takes the current locale into account. Modified: python/branches/py3k/Lib/test/test_locale.py ============================================================================== --- python/branches/py3k/Lib/test/test_locale.py (original) +++ python/branches/py3k/Lib/test/test_locale.py Wed Apr 1 05:42:00 2009 @@ -219,6 +219,19 @@ (self.sep, self.sep)) +class TestFormatPatternArg(unittest.TestCase): + # Test handling of pattern argument of format + + def test_onlyOnePattern(self): + # Issue 2522: accept exactly one % pattern, and no extra chars. + self.assertRaises(ValueError, locale.format, "%f\n", 'foo') + self.assertRaises(ValueError, locale.format, "%f\r", 'foo') + self.assertRaises(ValueError, locale.format, "%f\r\n", 'foo') + self.assertRaises(ValueError, locale.format, " %f", 'foo') + self.assertRaises(ValueError, locale.format, "%fg", 'foo') + self.assertRaises(ValueError, locale.format, "%^g", 'foo') + + class TestNumberFormatting(BaseLocalizedTest, EnUSNumberFormatting): # Test number formatting with a real English locale. @@ -314,6 +327,7 @@ def test_main(): tests = [ TestMiscellaneous, + TestFormatPatternArg, TestEnUSNumberFormatting, TestCNumberFormatting, TestFrFRNumberFormatting, Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Wed Apr 1 05:42:00 2009 @@ -482,6 +482,7 @@ Chad Miller Jay T. Miller Roman Milner +Andrii V. Mishkovskyi Dustin J. Mitchell Dom Mitchell Doug Moen @@ -492,6 +493,7 @@ Sjoerd Mullender Sape Mullender Michael Muller +R. David Murray Piotr Meyer John Nagle Takahiro Nakayama Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Apr 1 05:42:00 2009 @@ -284,6 +284,10 @@ Library ------- +- Issue #2522: locale.format now checks its first argument to ensure it has + been passed only one pattern, avoiding mysterious errors where it appeared + that it was failing to do localization. + - Issue #5583: Added optional Extensions in Distutils. Initial patch by Georg Brandl. From python-checkins at python.org Wed Apr 1 05:45:50 2009 From: python-checkins at python.org (jesse.noller) Date: Wed, 1 Apr 2009 05:45:50 +0200 (CEST) Subject: [Python-checkins] r70939 - in python/trunk: Doc/library/multiprocessing.rst Lib/multiprocessing/synchronize.py Lib/test/test_multiprocessing.py Message-ID: <20090401034550.A76981E4090@bag.python.org> Author: jesse.noller Date: Wed Apr 1 05:45:50 2009 New Revision: 70939 Log: Fix multiprocessing.event to match the new threading.Event API Modified: python/trunk/Doc/library/multiprocessing.rst python/trunk/Lib/multiprocessing/synchronize.py python/trunk/Lib/test/test_multiprocessing.py Modified: python/trunk/Doc/library/multiprocessing.rst ============================================================================== --- python/trunk/Doc/library/multiprocessing.rst (original) +++ python/trunk/Doc/library/multiprocessing.rst Wed Apr 1 05:45:50 2009 @@ -836,6 +836,12 @@ .. class:: Event() A clone of :class:`threading.Event`. + This method returns the state of the internal semaphore on exit, so it + will always return ``True`` except if a timeout is given and the operation + times out. + + .. versionchanged:: 2.7 + Previously, the method always returned ``None``. .. class:: Lock() Modified: python/trunk/Lib/multiprocessing/synchronize.py ============================================================================== --- python/trunk/Lib/multiprocessing/synchronize.py (original) +++ python/trunk/Lib/multiprocessing/synchronize.py Wed Apr 1 05:45:50 2009 @@ -301,5 +301,10 @@ self._flag.release() else: self._cond.wait(timeout) + + if self._flag.acquire(False): + self._flag.release() + return True + return False finally: self._cond.release() Modified: python/trunk/Lib/test/test_multiprocessing.py ============================================================================== --- python/trunk/Lib/test/test_multiprocessing.py (original) +++ python/trunk/Lib/test/test_multiprocessing.py Wed Apr 1 05:45:50 2009 @@ -749,20 +749,22 @@ # Removed temporaily, due to API shear, this does not # work with threading._Event objects. is_set == isSet - #self.assertEqual(event.is_set(), False) + self.assertEqual(event.is_set(), False) - self.assertEqual(wait(0.0), None) + # Removed, threading.Event.wait() will return the value of the __flag + # instead of None. API Shear with the semaphore backed mp.Event + self.assertEqual(wait(0.0), False) self.assertTimingAlmostEqual(wait.elapsed, 0.0) - self.assertEqual(wait(TIMEOUT1), None) + self.assertEqual(wait(TIMEOUT1), False) self.assertTimingAlmostEqual(wait.elapsed, TIMEOUT1) event.set() # See note above on the API differences - # self.assertEqual(event.is_set(), True) - self.assertEqual(wait(), None) + self.assertEqual(event.is_set(), True) + self.assertEqual(wait(), True) self.assertTimingAlmostEqual(wait.elapsed, 0.0) - self.assertEqual(wait(TIMEOUT1), None) + self.assertEqual(wait(TIMEOUT1), True) self.assertTimingAlmostEqual(wait.elapsed, 0.0) # self.assertEqual(event.is_set(), True) @@ -771,7 +773,7 @@ #self.assertEqual(event.is_set(), False) self.Process(target=self._test_event, args=(event,)).start() - self.assertEqual(wait(), None) + self.assertEqual(wait(), True) # # From buildbot at python.org Wed Apr 1 05:57:26 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 01 Apr 2009 03:57:26 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 2.6 Message-ID: <20090401035727.0D1411E4090@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%202.6/builds/202 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: jesse.noller,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_bsddb3 make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Wed Apr 1 06:21:14 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Apr 2009 06:21:14 +0200 (CEST) Subject: [Python-checkins] r70940 - in python/trunk: Lib/SimpleXMLRPCServer.py Misc/NEWS Message-ID: <20090401042114.AD7571E43A1@bag.python.org> Author: georg.brandl Date: Wed Apr 1 06:21:14 2009 New Revision: 70940 Log: The SimpleXMLRPCServer's CGI handler now runs like a pony. Modified: python/trunk/Lib/SimpleXMLRPCServer.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/SimpleXMLRPCServer.py ============================================================================== --- python/trunk/Lib/SimpleXMLRPCServer.py (original) +++ python/trunk/Lib/SimpleXMLRPCServer.py Wed Apr 1 06:21:14 2009 @@ -598,8 +598,12 @@ self.handle_get() else: # POST data is normally available through stdin + try: + length = int(os.environ.get('CONTENT_LENGTH', None)) + except ValueError: + length = -1 if request_text is None: - request_text = sys.stdin.read() + request_text = sys.stdin.read(length) self.handle_xmlrpc(request_text) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Apr 1 06:21:14 2009 @@ -200,6 +200,8 @@ Library ------- +- Actually make the SimpleXMLRPCServer CGI handler work. + - Issue #2522: locale.format now checks its first argument to ensure it has been passed only one pattern, avoiding mysterious errors where it appeared that it was failing to do localization. From python-checkins at python.org Wed Apr 1 06:27:09 2009 From: python-checkins at python.org (jack.diederich) Date: Wed, 1 Apr 2009 06:27:09 +0200 (CEST) Subject: [Python-checkins] r70941 - in python/branches/py3k: Lib/test/test_functools.py Misc/ACKS Misc/NEWS Modules/_functoolsmodule.c Message-ID: <20090401042709.C623F1E406D@bag.python.org> Author: jack.diederich Date: Wed Apr 1 06:27:09 2009 New Revision: 70941 Log: Merged revisions 70931 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70931 | jack.diederich | 2009-03-31 19:46:48 -0400 (Tue, 31 Mar 2009) | 1 line #5228: add pickle support to functools.partial ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_functools.py python/branches/py3k/Misc/ACKS 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 Apr 1 06:27:09 2009 @@ -2,6 +2,7 @@ import unittest from test import support from weakref import proxy +import pickle @staticmethod def PythonPartial(func, *args, **keywords): @@ -19,6 +20,9 @@ """capture all positional and keyword arguments""" return args, kw +def signature(part): + """ return the signature of a partial object """ + return (part.func, part.args, part.keywords, part.__dict__) class TestPartial(unittest.TestCase): @@ -141,6 +145,12 @@ join = self.thetype(''.join) self.assertEqual(join(data), '0123456789') + def test_pickle(self): + f = self.thetype(signature, 'asdf', bar=True) + f.add_something_to__dict__ = True + f_copy = pickle.loads(pickle.dumps(f)) + self.assertEqual(signature(f), signature(f_copy)) + class PartialSubclass(functools.partial): pass @@ -148,11 +158,13 @@ thetype = PartialSubclass - class TestPythonPartial(TestPartial): thetype = PythonPartial + # the python version isn't picklable + def test_pickle(self): pass + class TestUpdateWrapper(unittest.TestCase): def check_wrapper(self, wrapper, wrapped, Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Wed Apr 1 06:27:09 2009 @@ -167,6 +167,7 @@ Raghuram Devarakonda Toby Dickenson Mark Dickinson +Jack Diederich Humberto Diogenes Yves Dionne Daniel Dittmar Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Apr 1 06:27:09 2009 @@ -726,6 +726,8 @@ buffer. +- Issue #5228: Make functools.partial objects can now be pickled. + Tests ----- Modified: python/branches/py3k/Modules/_functoolsmodule.c ============================================================================== --- python/branches/py3k/Modules/_functoolsmodule.c (original) +++ python/branches/py3k/Modules/_functoolsmodule.c Wed Apr 1 06:27:09 2009 @@ -196,6 +196,53 @@ {NULL} /* Sentinel */ }; +/* Pickle strategy: + __reduce__ by itself doesn't support getting kwargs in the unpickle + operation so we define a __setstate__ that replaces all the information + about the partial. If we only replaced part of it someone would use + it as a hook to do stange things. + */ + +PyObject * +partial_reduce(partialobject *pto, PyObject *unused) +{ + return Py_BuildValue("O(O)(OOOO)", Py_TYPE(pto), pto->fn, pto->fn, + pto->args, pto->kw, + pto->dict ? pto->dict : Py_None); +} + +PyObject * +partial_setstate(partialobject *pto, PyObject *args) +{ + PyObject *fn, *fnargs, *kw, *dict; + if (!PyArg_ParseTuple(args, "(OOOO):__setstate__", + &fn, &fnargs, &kw, &dict)) + return NULL; + Py_XDECREF(pto->fn); + Py_XDECREF(pto->args); + Py_XDECREF(pto->kw); + Py_XDECREF(pto->dict); + pto->fn = fn; + pto->args = fnargs; + pto->kw = kw; + if (dict != Py_None) { + pto->dict = dict; + Py_INCREF(dict); + } else { + pto->dict = NULL; + } + Py_INCREF(fn); + Py_INCREF(fnargs); + Py_INCREF(kw); + Py_RETURN_NONE; +} + +static PyMethodDef partial_methods[] = { + {"__reduce__", (PyCFunction)partial_reduce, METH_NOARGS}, + {"__setstate__", (PyCFunction)partial_setstate, METH_VARARGS}, + {NULL, NULL} /* sentinel */ +}; + static PyTypeObject partial_type = { PyVarObject_HEAD_INIT(NULL, 0) "functools.partial", /* tp_name */ @@ -226,7 +273,7 @@ offsetof(partialobject, weakreflist), /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - 0, /* tp_methods */ + partial_methods, /* tp_methods */ partial_memberlist, /* tp_members */ partial_getsetlist, /* tp_getset */ 0, /* tp_base */ From python-checkins at python.org Wed Apr 1 06:27:47 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Apr 2009 06:27:47 +0200 (CEST) Subject: [Python-checkins] r70942 - in python/branches/py3k: Lib/xmlrpc/server.py Message-ID: <20090401042747.AEAD91E406D@bag.python.org> Author: georg.brandl Date: Wed Apr 1 06:27:47 2009 New Revision: 70942 Log: Merged revisions 70940 via svnmerge ........ r70940 | georg.brandl | 2009-03-31 23:21:14 -0500 (Di, 31 M?r 2009) | 2 lines The SimpleXMLRPCServer's CGI handler now runs like a pony. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/xmlrpc/server.py Modified: python/branches/py3k/Lib/xmlrpc/server.py ============================================================================== --- python/branches/py3k/Lib/xmlrpc/server.py (original) +++ python/branches/py3k/Lib/xmlrpc/server.py Wed Apr 1 06:27:47 2009 @@ -588,8 +588,12 @@ self.handle_get() else: # POST data is normally available through stdin + try: + length = int(os.environ.get('CONTENT_LENGTH', None)) + except ValueError: + length = -1 if request_text is None: - request_text = sys.stdin.read() + request_text = sys.stdin.read(length) self.handle_xmlrpc(request_text) From python-checkins at python.org Wed Apr 1 06:28:33 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Apr 2009 06:28:33 +0200 (CEST) Subject: [Python-checkins] r70943 - in python/branches/py3k: Lib/distutils/tests/test_msvc9compiler.py Lib/urllib/request.py Misc/NEWS Tools/msi/msilib.py Message-ID: <20090401042833.D7ACD1E406D@bag.python.org> Author: georg.brandl Date: Wed Apr 1 06:28:33 2009 New Revision: 70943 Log: Merged revisions 70940 via svnmerge ........ r70940 | georg.brandl | 2009-03-31 23:21:14 -0500 (Di, 31 M?r 2009) | 2 lines The SimpleXMLRPCServer's CGI handler now runs like a pony. ........ Modified: python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py python/branches/py3k/Lib/urllib/request.py python/branches/py3k/Misc/NEWS python/branches/py3k/Tools/msi/msilib.py Modified: python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py Wed Apr 1 06:28:33 2009 @@ -48,8 +48,8 @@ v = Reg.get_value(path, "lfitalic") self.assert_(v in (0, 1)) - import _winreg - HKCU = _winreg.HKEY_CURRENT_USER + import winreg + HKCU = winreg.HKEY_CURRENT_USER keys = Reg.read_keys(HKCU, 'xxxx') self.assertEquals(keys, None) Modified: python/branches/py3k/Lib/urllib/request.py ============================================================================== --- python/branches/py3k/Lib/urllib/request.py (original) +++ python/branches/py3k/Lib/urllib/request.py Wed Apr 1 06:28:33 2009 @@ -2160,18 +2160,18 @@ """ proxies = {} try: - import _winreg + import winreg except ImportError: # Std module, so should be around - but you never know! return proxies try: - internetSettings = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, + internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\Microsoft\Windows\CurrentVersion\Internet Settings') - proxyEnable = _winreg.QueryValueEx(internetSettings, + proxyEnable = winreg.QueryValueEx(internetSettings, 'ProxyEnable')[0] if proxyEnable: # Returned as Unicode but problems if not converted to ASCII - proxyServer = str(_winreg.QueryValueEx(internetSettings, + proxyServer = str(winreg.QueryValueEx(internetSettings, 'ProxyServer')[0]) if '=' in proxyServer: # Per-protocol settings @@ -2208,17 +2208,17 @@ def proxy_bypass_registry(host): try: - import _winreg + import winreg import re except ImportError: # Std modules, so should be around - but you never know! return 0 try: - internetSettings = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, + internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\Microsoft\Windows\CurrentVersion\Internet Settings') - proxyEnable = _winreg.QueryValueEx(internetSettings, + proxyEnable = winreg.QueryValueEx(internetSettings, 'ProxyEnable')[0] - proxyOverride = str(_winreg.QueryValueEx(internetSettings, + proxyOverride = str(winreg.QueryValueEx(internetSettings, 'ProxyOverride')[0]) # ^^^^ Returned as Unicode but problems if not converted to ASCII except WindowsError: Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Apr 1 06:28:33 2009 @@ -53,6 +53,8 @@ Library ------- +- Issue #5624: Fix the _winreg module name still used in several modules. + - Issue #5628: Fix io.TextIOWrapper.read() with a unreadable buffer. - Issue #5619: Multiprocessing children disobey the debug flag and causes Modified: python/branches/py3k/Tools/msi/msilib.py ============================================================================== --- python/branches/py3k/Tools/msi/msilib.py (original) +++ python/branches/py3k/Tools/msi/msilib.py Wed Apr 1 06:28:33 2009 @@ -5,7 +5,7 @@ import win32com.client import pythoncom, pywintypes from win32com.client import constants -import re, string, os, sets, glob, subprocess, sys, _winreg, struct +import re, string, os, sets, glob, subprocess, sys, winreg, struct try: basestring @@ -387,9 +387,9 @@ (r"Software\Microsoft\Win32SDK\Directories", "Install Dir"), ]: try: - key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, k) - dir = _winreg.QueryValueEx(key, v)[0] - _winreg.CloseKey(key) + key = winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, k) + dir = winreg.QueryValueEx(key, v)[0] + winreg.CloseKey(key) except (WindowsError, IndexError): continue cabarc = os.path.join(dir, r"Bin", "cabarc.exe") From python-checkins at python.org Wed Apr 1 06:32:39 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Apr 2009 06:32:39 +0200 (CEST) Subject: [Python-checkins] r70944 - python/trunk/Lib/distutils/command/__init__.py Message-ID: <20090401043239.83D761E406D@bag.python.org> Author: georg.brandl Date: Wed Apr 1 06:32:39 2009 New Revision: 70944 Log: #5631: add upload to list of possible commands, which is presented in --help-commands. Modified: python/trunk/Lib/distutils/command/__init__.py Modified: python/trunk/Lib/distutils/command/__init__.py ============================================================================== --- python/trunk/Lib/distutils/command/__init__.py (original) +++ python/trunk/Lib/distutils/command/__init__.py Wed Apr 1 06:32:39 2009 @@ -22,6 +22,8 @@ 'bdist_dumb', 'bdist_rpm', 'bdist_wininst', + 'upload', + # These two are reserved for future use: #'bdist_sdux', #'bdist_pkgtool', From python-checkins at python.org Wed Apr 1 07:08:41 2009 From: python-checkins at python.org (brett.cannon) Date: Wed, 1 Apr 2009 07:08:41 +0200 (CEST) Subject: [Python-checkins] r70945 - in python/branches/py3k: Grammar/Grammar Include/code.h Include/compile.h Include/parsetok.h Include/pythonrun.h Lib/__future__.py Lib/test/test_flufl.py Parser/parser.c Parser/parsetok.c Parser/tokenizer.c Python/future.c Python/graminit.c Python/pythonrun.c Message-ID: <20090401050841.D5B051E40F1@bag.python.org> Author: brett.cannon Date: Wed Apr 1 07:08:41 2009 New Revision: 70945 Log: The BDFL has retired! Long live the FLUFL (Friendly Language Uncle For Life)! Added: python/branches/py3k/Lib/test/test_flufl.py Modified: python/branches/py3k/Grammar/Grammar python/branches/py3k/Include/code.h python/branches/py3k/Include/compile.h python/branches/py3k/Include/parsetok.h python/branches/py3k/Include/pythonrun.h python/branches/py3k/Lib/__future__.py python/branches/py3k/Parser/parser.c python/branches/py3k/Parser/parsetok.c python/branches/py3k/Parser/tokenizer.c python/branches/py3k/Python/future.c python/branches/py3k/Python/graminit.c python/branches/py3k/Python/pythonrun.c Modified: python/branches/py3k/Grammar/Grammar ============================================================================== --- python/branches/py3k/Grammar/Grammar (original) +++ python/branches/py3k/Grammar/Grammar Wed Apr 1 07:08:41 2009 @@ -87,7 +87,7 @@ and_test: not_test ('and' not_test)* not_test: 'not' not_test | comparison comparison: star_expr (comp_op star_expr)* -comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is'|'is' 'not' +comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' star_expr: ['*'] expr expr: xor_expr ('|' xor_expr)* xor_expr: and_expr ('^' and_expr)* Modified: python/branches/py3k/Include/code.h ============================================================================== --- python/branches/py3k/Include/code.h (original) +++ python/branches/py3k/Include/code.h Wed Apr 1 07:08:41 2009 @@ -52,10 +52,12 @@ #define CO_FUTURE_UNICODE_LITERALS 0x20000 #endif +#define CO_FUTURE_BARRY_AS_BDFL 0x40000 + /* This should be defined if a future statement modifies the syntax. For example, when a keyword is added. */ -/* #define PY_PARSER_REQUIRES_FUTURE_KEYWORD */ +#define PY_PARSER_REQUIRES_FUTURE_KEYWORD #define CO_MAXBLOCKS 20 /* Max static block nesting within a function */ Modified: python/branches/py3k/Include/compile.h ============================================================================== --- python/branches/py3k/Include/compile.h (original) +++ python/branches/py3k/Include/compile.h Wed Apr 1 07:08:41 2009 @@ -26,6 +26,7 @@ #define FUTURE_WITH_STATEMENT "with_statement" #define FUTURE_PRINT_FUNCTION "print_function" #define FUTURE_UNICODE_LITERALS "unicode_literals" +#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 *, Modified: python/branches/py3k/Include/parsetok.h ============================================================================== --- python/branches/py3k/Include/parsetok.h (original) +++ python/branches/py3k/Include/parsetok.h Wed Apr 1 07:08:41 2009 @@ -30,6 +30,7 @@ #endif #define PyPARSE_IGNORE_COOKIE 0x0010 +#define PyPARSE_BARRY_AS_BDFL 0x0020 PyAPI_FUNC(node *) PyParser_ParseString(const char *, grammar *, int, perrdetail *); Modified: python/branches/py3k/Include/pythonrun.h ============================================================================== --- python/branches/py3k/Include/pythonrun.h (original) +++ python/branches/py3k/Include/pythonrun.h Wed Apr 1 07:08:41 2009 @@ -7,7 +7,7 @@ extern "C" { #endif -#define PyCF_MASK 0 +#define PyCF_MASK CO_FUTURE_BARRY_AS_BDFL #define PyCF_MASK_OBSOLETE 0 #define PyCF_SOURCE_IS_UTF8 0x0100 #define PyCF_DONT_IMPLY_DEDENT 0x0200 Modified: python/branches/py3k/Lib/__future__.py ============================================================================== --- python/branches/py3k/Lib/__future__.py (original) +++ python/branches/py3k/Lib/__future__.py Wed Apr 1 07:08:41 2009 @@ -70,6 +70,7 @@ CO_FUTURE_WITH_STATEMENT = 0x8000 # with statement CO_FUTURE_PRINT_FUNCTION = 0x10000 # print function CO_FUTURE_UNICODE_LITERALS = 0x20000 # unicode string literals +CO_FUTURE_BARRY_AS_BDFL = 0x40000 class _Feature: def __init__(self, optionalRelease, mandatoryRelease, compiler_flag): @@ -126,3 +127,7 @@ unicode_literals = _Feature((2, 6, 0, "alpha", 2), (3, 0, 0, "alpha", 0), CO_FUTURE_UNICODE_LITERALS) + +barry_as_FLUFL = _Feature((3, 1, 0, "alpha", 2), + (3, 9, 0, "alpha", 0), + CO_FUTURE_BARRY_AS_BDFL) Added: python/branches/py3k/Lib/test/test_flufl.py ============================================================================== --- (empty file) +++ python/branches/py3k/Lib/test/test_flufl.py Wed Apr 1 07:08:41 2009 @@ -0,0 +1,27 @@ +import __future__ +import unittest + +class FLUFLTests(unittest.TestCase): + + def test_barry_as_bdfl(self): + code = "from __future__ import barry_as_FLUFL; 2 {0} 3" + compile(code.format('<>'), '', 'exec', + __future__.CO_FUTURE_BARRY_AS_BDFL) + self.assertRaises(SyntaxError, compile, code.format('!='), + '', 'exec', + __future__.CO_FUTURE_BARRY_AS_BDFL) + + def test_guido_as_bdfl(self): + code = '2 {0} 3' + compile(code.format('!='), '', 'exec') + self.assertRaises(SyntaxError, compile, code.format('<>'), + '', 'exec') + + +def test_main(): + from test.support import run_unittest + run_unittest(FLUFLTests) + + +if __name__ == '__main__': + test_main() Modified: python/branches/py3k/Parser/parser.c ============================================================================== --- python/branches/py3k/Parser/parser.c (original) +++ python/branches/py3k/Parser/parser.c Wed Apr 1 07:08:41 2009 @@ -149,6 +149,7 @@ strcmp(l->lb_str, s) != 0) continue; #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD +#if 0 /* Leaving this in as an example */ if (!(ps->p_flags & CO_FUTURE_WITH_STATEMENT)) { if (s[0] == 'w' && strcmp(s, "with") == 0) @@ -157,6 +158,7 @@ break; /* not a keyword yet */ } #endif +#endif D(printf("It's a keyword\n")); return n - i; } @@ -178,6 +180,7 @@ } #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD +#if 0 /* Leaving this in as an example */ static void future_hack(parser_state *ps) @@ -218,6 +221,7 @@ } } } +#endif #endif /* future keyword */ int @@ -278,11 +282,13 @@ d->d_name, ps->p_stack.s_top->s_state)); #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD +#if 0 if (d->d_name[0] == 'i' && strcmp(d->d_name, "import_stmt") == 0) future_hack(ps); #endif +#endif s_pop(&ps->p_stack); if (s_empty(&ps->p_stack)) { D(printf(" ACCEPT.\n")); @@ -296,10 +302,12 @@ if (s->s_accept) { #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD +#if 0 if (d->d_name[0] == 'i' && strcmp(d->d_name, "import_stmt") == 0) future_hack(ps); #endif +#endif /* Pop this dfa and try again */ s_pop(&ps->p_stack); D(printf(" Pop ...\n")); Modified: python/branches/py3k/Parser/parsetok.c ============================================================================== --- python/branches/py3k/Parser/parsetok.c (original) +++ python/branches/py3k/Parser/parsetok.c Wed Apr 1 07:08:41 2009 @@ -100,6 +100,7 @@ } #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD +#if 0 static char with_msg[] = "%s:%d: Warning: 'with' will become a reserved keyword in Python 2.6\n"; @@ -114,6 +115,7 @@ PySys_WriteStderr(msg, filename, lineno); } #endif +#endif /* Parse input coming from the given tokenizer structure. Return error code. */ @@ -133,8 +135,8 @@ return NULL; } #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD - if (*flags & PyPARSE_WITH_IS_KEYWORD) - ps->p_flags |= CO_FUTURE_WITH_STATEMENT; + if (*flags & PyPARSE_BARRY_AS_BDFL) + ps->p_flags |= CO_FUTURE_BARRY_AS_BDFL; #endif for (;;) { @@ -177,26 +179,20 @@ str[len] = '\0'; #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD - /* This is only necessary to support the "as" warning, but - we don't want to warn about "as" in import statements. */ - if (type == NAME && - len == 6 && str[0] == 'i' && strcmp(str, "import") == 0) - handling_import = 1; - - /* Warn about with as NAME */ - if (type == NAME && - !(ps->p_flags & CO_FUTURE_WITH_STATEMENT)) { - if (len == 4 && str[0] == 'w' && strcmp(str, "with") == 0) - warn(with_msg, err_ret->filename, tok->lineno); - else if (!(handling_import || handling_with) && - len == 2 && str[0] == 'a' && - strcmp(str, "as") == 0) - warn(as_msg, err_ret->filename, tok->lineno); - } - else if (type == NAME && - (ps->p_flags & CO_FUTURE_WITH_STATEMENT) && - len == 4 && str[0] == 'w' && strcmp(str, "with") == 0) - handling_with = 1; + if (type == NOTEQUAL) { + if (!(ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) && + strcmp(str, "!=")) { + err_ret->error = E_SYNTAX; + break; + } + else if ((ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) && + strcmp(str, "<>")) { + err_ret->text = "with Barry as BDFL, use '<>' " + "instead of '!='"; + err_ret->error = E_SYNTAX; + break; + } + } #endif if (a >= tok->line_start) col_offset = a - tok->line_start; Modified: python/branches/py3k/Parser/tokenizer.c ============================================================================== --- python/branches/py3k/Parser/tokenizer.c (original) +++ python/branches/py3k/Parser/tokenizer.c Wed Apr 1 07:08:41 2009 @@ -1040,6 +1040,7 @@ break; case '<': switch (c2) { + case '>': return NOTEQUAL; case '=': return LESSEQUAL; case '<': return LEFTSHIFT; } Modified: python/branches/py3k/Python/future.c ============================================================================== --- python/branches/py3k/Python/future.c (original) +++ python/branches/py3k/Python/future.c Wed Apr 1 07:08:41 2009 @@ -39,6 +39,8 @@ continue; } else if (strcmp(feature, FUTURE_UNICODE_LITERALS) == 0) { continue; + } else if (strcmp(feature, FUTURE_BARRY_AS_BDFL) == 0) { + ff->ff_features |= CO_FUTURE_BARRY_AS_BDFL; } else if (strcmp(feature, "braces") == 0) { PyErr_SetString(PyExc_SyntaxError, "not a chance"); Modified: python/branches/py3k/Python/graminit.c ============================================================================== --- python/branches/py3k/Python/graminit.c (original) +++ python/branches/py3k/Python/graminit.c Wed Apr 1 07:08:41 2009 @@ -1129,16 +1129,17 @@ {1, arcs_52_0}, {2, arcs_52_1}, }; -static arc arcs_53_0[9] = { +static arc arcs_53_0[10] = { {118, 1}, {119, 1}, {120, 1}, {121, 1}, {122, 1}, {123, 1}, + {124, 1}, {95, 1}, {114, 2}, - {124, 3}, + {125, 3}, }; static arc arcs_53_1[1] = { {0, 1}, @@ -1151,7 +1152,7 @@ {0, 3}, }; static state states_53[4] = { - {9, arcs_53_0}, + {10, arcs_53_0}, {1, arcs_53_1}, {1, arcs_53_2}, {2, arcs_53_3}, @@ -1172,10 +1173,10 @@ {1, arcs_54_2}, }; static arc arcs_55_0[1] = { - {125, 1}, + {126, 1}, }; static arc arcs_55_1[2] = { - {126, 0}, + {127, 0}, {0, 1}, }; static state states_55[2] = { @@ -1183,10 +1184,10 @@ {2, arcs_55_1}, }; static arc arcs_56_0[1] = { - {127, 1}, + {128, 1}, }; static arc arcs_56_1[2] = { - {128, 0}, + {129, 0}, {0, 1}, }; static state states_56[2] = { @@ -1194,10 +1195,10 @@ {2, arcs_56_1}, }; static arc arcs_57_0[1] = { - {129, 1}, + {130, 1}, }; static arc arcs_57_1[2] = { - {130, 0}, + {131, 0}, {0, 1}, }; static state states_57[2] = { @@ -1205,11 +1206,11 @@ {2, arcs_57_1}, }; static arc arcs_58_0[1] = { - {131, 1}, + {132, 1}, }; static arc arcs_58_1[3] = { - {132, 0}, {133, 0}, + {134, 0}, {0, 1}, }; static state states_58[2] = { @@ -1217,11 +1218,11 @@ {3, arcs_58_1}, }; static arc arcs_59_0[1] = { - {134, 1}, + {135, 1}, }; static arc arcs_59_1[3] = { - {135, 0}, {136, 0}, + {137, 0}, {0, 1}, }; static state states_59[2] = { @@ -1229,13 +1230,13 @@ {3, arcs_59_1}, }; static arc arcs_60_0[1] = { - {137, 1}, + {138, 1}, }; static arc arcs_60_1[5] = { {31, 0}, - {138, 0}, {139, 0}, {140, 0}, + {141, 0}, {0, 1}, }; static state states_60[2] = { @@ -1243,13 +1244,13 @@ {5, arcs_60_1}, }; static arc arcs_61_0[4] = { - {135, 1}, {136, 1}, - {141, 1}, - {142, 2}, + {137, 1}, + {142, 1}, + {143, 2}, }; static arc arcs_61_1[1] = { - {137, 2}, + {138, 2}, }; static arc arcs_61_2[1] = { {0, 2}, @@ -1260,15 +1261,15 @@ {1, arcs_61_2}, }; static arc arcs_62_0[1] = { - {143, 1}, + {144, 1}, }; static arc arcs_62_1[3] = { - {144, 1}, + {145, 1}, {32, 2}, {0, 1}, }; static arc arcs_62_2[1] = { - {137, 3}, + {138, 3}, }; static arc arcs_62_3[1] = { {0, 3}, @@ -1281,44 +1282,44 @@ }; static arc arcs_63_0[10] = { {13, 1}, - {146, 2}, - {148, 3}, + {147, 2}, + {149, 3}, {21, 4}, - {151, 4}, - {152, 5}, + {152, 4}, + {153, 5}, {77, 4}, - {153, 4}, {154, 4}, {155, 4}, + {156, 4}, }; static arc arcs_63_1[3] = { {46, 6}, - {145, 6}, + {146, 6}, {15, 4}, }; static arc arcs_63_2[2] = { - {145, 7}, - {147, 4}, + {146, 7}, + {148, 4}, }; static arc arcs_63_3[2] = { - {149, 8}, - {150, 4}, + {150, 8}, + {151, 4}, }; static arc arcs_63_4[1] = { {0, 4}, }; static arc arcs_63_5[2] = { - {152, 5}, + {153, 5}, {0, 5}, }; static arc arcs_63_6[1] = { {15, 4}, }; static arc arcs_63_7[1] = { - {147, 4}, + {148, 4}, }; static arc arcs_63_8[1] = { - {150, 4}, + {151, 4}, }; static state states_63[9] = { {10, arcs_63_0}, @@ -1335,7 +1336,7 @@ {24, 1}, }; static arc arcs_64_1[3] = { - {156, 2}, + {157, 2}, {30, 3}, {0, 1}, }; @@ -1359,7 +1360,7 @@ }; static arc arcs_65_0[3] = { {13, 1}, - {146, 2}, + {147, 2}, {76, 3}, }; static arc arcs_65_1[2] = { @@ -1367,7 +1368,7 @@ {15, 5}, }; static arc arcs_65_2[1] = { - {157, 6}, + {158, 6}, }; static arc arcs_65_3[1] = { {21, 5}, @@ -1379,7 +1380,7 @@ {0, 5}, }; static arc arcs_65_6[1] = { - {147, 5}, + {148, 5}, }; static state states_65[7] = { {3, arcs_65_0}, @@ -1391,14 +1392,14 @@ {1, arcs_65_6}, }; static arc arcs_66_0[1] = { - {158, 1}, + {159, 1}, }; static arc arcs_66_1[2] = { {30, 2}, {0, 1}, }; static arc arcs_66_2[2] = { - {158, 1}, + {159, 1}, {0, 2}, }; static state states_66[3] = { @@ -1416,11 +1417,11 @@ }; static arc arcs_67_2[3] = { {24, 3}, - {159, 4}, + {160, 4}, {0, 2}, }; static arc arcs_67_3[2] = { - {159, 4}, + {160, 4}, {0, 3}, }; static arc arcs_67_4[1] = { @@ -1485,7 +1486,7 @@ }; static arc arcs_71_1[4] = { {25, 2}, - {156, 3}, + {157, 3}, {30, 4}, {0, 1}, }; @@ -1500,7 +1501,7 @@ {0, 4}, }; static arc arcs_71_5[3] = { - {156, 3}, + {157, 3}, {30, 7}, {0, 5}, }; @@ -1536,7 +1537,7 @@ {2, arcs_71_10}, }; static arc arcs_72_0[1] = { - {160, 1}, + {161, 1}, }; static arc arcs_72_1[1] = { {21, 2}, @@ -1572,7 +1573,7 @@ {1, arcs_72_7}, }; static arc arcs_73_0[3] = { - {161, 1}, + {162, 1}, {31, 2}, {32, 3}, }; @@ -1587,7 +1588,7 @@ {24, 6}, }; static arc arcs_73_4[4] = { - {161, 1}, + {162, 1}, {31, 2}, {32, 3}, {0, 4}, @@ -1600,7 +1601,7 @@ {0, 6}, }; static arc arcs_73_7[2] = { - {161, 5}, + {162, 5}, {32, 3}, }; static state states_73[8] = { @@ -1617,7 +1618,7 @@ {24, 1}, }; static arc arcs_74_1[3] = { - {156, 2}, + {157, 2}, {29, 3}, {0, 1}, }; @@ -1634,8 +1635,8 @@ {1, arcs_74_3}, }; static arc arcs_75_0[2] = { - {156, 1}, - {163, 1}, + {157, 1}, + {164, 1}, }; static arc arcs_75_1[1] = { {0, 1}, @@ -1657,7 +1658,7 @@ {105, 4}, }; static arc arcs_76_4[2] = { - {162, 5}, + {163, 5}, {0, 4}, }; static arc arcs_76_5[1] = { @@ -1678,7 +1679,7 @@ {107, 2}, }; static arc arcs_77_2[2] = { - {162, 3}, + {163, 3}, {0, 2}, }; static arc arcs_77_3[1] = { @@ -1712,7 +1713,7 @@ {1, arcs_79_1}, }; static arc arcs_80_0[1] = { - {166, 1}, + {167, 1}, }; static arc arcs_80_1[2] = { {9, 2}, @@ -1728,11 +1729,11 @@ }; static dfa dfas[81] = { {256, "single_input", 0, 3, states_0, - "\004\050\060\200\000\000\000\050\370\044\034\144\011\040\004\000\200\041\224\017\101"}, + "\004\050\060\200\000\000\000\050\370\044\034\144\011\040\004\000\000\103\050\037\202"}, {257, "file_input", 0, 2, states_1, - "\204\050\060\200\000\000\000\050\370\044\034\144\011\040\004\000\200\041\224\017\101"}, + "\204\050\060\200\000\000\000\050\370\044\034\144\011\040\004\000\000\103\050\037\202"}, {258, "eval_input", 0, 3, states_2, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {259, "decorator", 0, 7, states_3, "\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {260, "decorators", 0, 2, states_4, @@ -1752,13 +1753,13 @@ {267, "vfpdef", 0, 2, states_11, "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {268, "stmt", 0, 2, states_12, - "\000\050\060\200\000\000\000\050\370\044\034\144\011\040\004\000\200\041\224\017\101"}, + "\000\050\060\200\000\000\000\050\370\044\034\144\011\040\004\000\000\103\050\037\202"}, {269, "simple_stmt", 0, 4, states_13, - "\000\040\040\200\000\000\000\050\370\044\034\000\000\040\004\000\200\041\224\017\100"}, + "\000\040\040\200\000\000\000\050\370\044\034\000\000\040\004\000\000\103\050\037\200"}, {270, "small_stmt", 0, 2, states_14, - "\000\040\040\200\000\000\000\050\370\044\034\000\000\040\004\000\200\041\224\017\100"}, + "\000\040\040\200\000\000\000\050\370\044\034\000\000\040\004\000\000\103\050\037\200"}, {271, "expr_stmt", 0, 6, states_15, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {272, "augassign", 0, 2, states_16, "\000\000\000\000\000\200\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {273, "del_stmt", 0, 3, states_17, @@ -1766,7 +1767,7 @@ {274, "pass_stmt", 0, 2, states_18, "\000\000\000\000\000\000\000\040\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\170\000\000\000\000\000\000\000\000\000\000\000\100"}, + "\000\000\000\000\000\000\000\000\170\000\000\000\000\000\000\000\000\000\000\000\200"}, {276, "break_stmt", 0, 2, states_20, "\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000"}, {277, "continue_stmt", 0, 2, states_21, @@ -1774,7 +1775,7 @@ {278, "return_stmt", 0, 3, states_22, "\000\000\000\000\000\000\000\000\040\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\100"}, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200"}, {280, "raise_stmt", 0, 5, states_24, "\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000"}, {281, "import_stmt", 0, 2, states_25, @@ -1800,7 +1801,7 @@ {291, "assert_stmt", 0, 5, states_35, "\000\000\000\000\000\000\000\000\000\000\020\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\144\011\000\000\000\000\000\000\000\001"}, + "\000\010\020\000\000\000\000\000\000\000\000\144\011\000\000\000\000\000\000\000\002"}, {293, "if_stmt", 0, 8, states_37, "\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000"}, {294, "while_stmt", 0, 8, states_38, @@ -1816,67 +1817,67 @@ {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"}, {300, "suite", 0, 5, states_44, - "\004\040\040\200\000\000\000\050\370\044\034\000\000\040\004\000\200\041\224\017\100"}, + "\004\040\040\200\000\000\000\050\370\044\034\000\000\040\004\000\000\103\050\037\200"}, {301, "test", 0, 6, states_45, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {302, "test_nocond", 0, 2, states_46, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {303, "lambdef", 0, 5, states_47, "\000\000\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000"}, {304, "lambdef_nocond", 0, 5, states_48, "\000\000\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000"}, {305, "or_test", 0, 2, states_49, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\004\000\000\103\050\037\000"}, {306, "and_test", 0, 2, states_50, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\004\000\000\103\050\037\000"}, {307, "not_test", 0, 3, states_51, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\004\000\000\103\050\037\000"}, {308, "comparison", 0, 2, states_52, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\000\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\000\000\000\103\050\037\000"}, {309, "comp_op", 0, 4, states_53, - "\000\000\000\000\000\000\000\000\000\000\000\200\000\000\304\037\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\200\000\000\304\077\000\000\000\000\000"}, {310, "star_expr", 0, 3, states_54, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\000\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\000\000\000\103\050\037\000"}, {311, "expr", 0, 2, states_55, - "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\200\041\224\017\000"}, + "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\103\050\037\000"}, {312, "xor_expr", 0, 2, states_56, - "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\200\041\224\017\000"}, + "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\103\050\037\000"}, {313, "and_expr", 0, 2, states_57, - "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\200\041\224\017\000"}, + "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\103\050\037\000"}, {314, "shift_expr", 0, 2, states_58, - "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\200\041\224\017\000"}, + "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\103\050\037\000"}, {315, "arith_expr", 0, 2, states_59, - "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\200\041\224\017\000"}, + "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\103\050\037\000"}, {316, "term", 0, 2, states_60, - "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\200\041\224\017\000"}, + "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\103\050\037\000"}, {317, "factor", 0, 3, states_61, - "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\200\041\224\017\000"}, + "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\103\050\037\000"}, {318, "power", 0, 4, states_62, - "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\224\017\000"}, + "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\050\037\000"}, {319, "atom", 0, 9, states_63, - "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\224\017\000"}, + "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\050\037\000"}, {320, "testlist_comp", 0, 5, states_64, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {321, "trailer", 0, 7, states_65, - "\000\040\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\004\000\000"}, + "\000\040\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\010\000\000"}, {322, "subscriptlist", 0, 3, states_66, - "\000\040\040\202\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\202\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {323, "subscript", 0, 5, states_67, - "\000\040\040\202\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\202\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {324, "sliceop", 0, 3, states_68, "\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {325, "exprlist", 0, 3, states_69, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\000\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\000\000\000\103\050\037\000"}, {326, "testlist", 0, 3, states_70, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {327, "dictorsetmaker", 0, 11, states_71, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {328, "classdef", 0, 8, states_72, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001"}, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002"}, {329, "arglist", 0, 8, states_73, - "\000\040\040\200\001\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\200\001\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {330, "argument", 0, 4, states_74, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {331, "comp_iter", 0, 2, states_75, "\000\000\000\000\000\000\000\000\000\000\000\104\000\000\000\000\000\000\000\000\000"}, {332, "comp_for", 0, 6, states_76, @@ -1884,13 +1885,13 @@ {333, "comp_if", 0, 4, states_77, "\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000"}, {334, "testlist1", 0, 2, states_78, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {335, "encoding_decl", 0, 2, states_79, "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {336, "yield_expr", 0, 3, states_80, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\100"}, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200"}, }; -static label labels[167] = { +static label labels[168] = { {0, "EMPTY"}, {256, 0}, {4, 0}, @@ -2015,6 +2016,7 @@ {31, 0}, {30, 0}, {29, 0}, + {29, 0}, {1, "is"}, {312, 0}, {18, 0}, @@ -2062,6 +2064,6 @@ grammar _PyParser_Grammar = { 81, dfas, - {167, labels}, + {168, labels}, 256 }; Modified: python/branches/py3k/Python/pythonrun.c ============================================================================== --- python/branches/py3k/Python/pythonrun.c (original) +++ python/branches/py3k/Python/pythonrun.c Wed Apr 1 07:08:41 2009 @@ -1011,6 +1011,8 @@ parser_flags |= PyPARSE_DONT_IMPLY_DEDENT; if (flags->cf_flags & PyCF_IGNORE_COOKIE) parser_flags |= PyPARSE_IGNORE_COOKIE; + if (flags->cf_flags & CO_FUTURE_BARRY_AS_BDFL) + parser_flags |= PyPARSE_BARRY_AS_BDFL; return parser_flags; } From python-checkins at python.org Wed Apr 1 07:09:14 2009 From: python-checkins at python.org (brett.cannon) Date: Wed, 1 Apr 2009 07:09:14 +0200 (CEST) Subject: [Python-checkins] r70946 - peps/trunk/pep-0401.txt Message-ID: <20090401050914.9D1F71E40F1@bag.python.org> Author: brett.cannon Date: Wed Apr 1 07:09:14 2009 New Revision: 70946 Log: Add PEP 401: BDFL retirement. Added: peps/trunk/pep-0401.txt (contents, props changed) Added: peps/trunk/pep-0401.txt ============================================================================== --- (empty file) +++ peps/trunk/pep-0401.txt Wed Apr 1 07:09:14 2009 @@ -0,0 +1,118 @@ +PEP: 401 +Title: BDFL Retirement +Version: $Revision$ +Last-Modified: $Date: 2009-04-01 00:00:00 -0400 (Wed, 1 Apr 2009)$ +Author: Barry Warsaw, Brett Cannon +Status: Accepted +Type: Process +Content-Type: text/x-rst +Created: 01-Apr-2009 +Post-History: 01-Apr-2009 + + +Abstract +======== + +The BDFL, having shepherded Python development for 20 years, +officially announces his retirement, effective immediately. Following +a unanimous vote, his replacement is named. + + +Rationale +========= + +Guido wrote the original implementation of Python in 1989, and after +nearly 20 years of leading the community, has decided to step aside as +its Benevolent Dictator For Life. His official title is now +Benevolent Dictator Emeritus Vacationing Indefinitely from the +Language (BDEVIL). Guido leaves Python in the good hands of its new +leader and its vibrant community, in order to train for his lifelong +dream of climbing Mount Everest. + +After unanimous vote of the Python Steering Union (not to be confused +with the Python Secret Underground, which emphatically does not exist) +at the 2009 Python Conference (PyCon_ 2009), Guido's successor has been +chosen: Barry Warsaw, or as he is affectionately known, Uncle Barry. +Uncle Barry's official title is Friendly Language Uncle For Life (FLUFL). + +.. _PyCon: http://us.pycon.org/ + + +Official Acts of the FLUFL +========================== + +FLUFL Uncle Barry enacts the following decisions, in order to +demonstrate his intention to lead the community in the same +responsible and open manner as his predecessor, whose name escapes +him: + +* Recognized that the selection of ``Hg`` as the DVCS of choice was + clear proof of the onset of the BDEVIL's insanity, and reverting + this decision to switch to ``Bzr`` instead, the only true choice. + +* Recognized that the ``!=`` inequality operator in Python 3.0 was a + horrible, finger pain inducing mistake, the FLUFL reinstates the + ``<>`` diamond operator as the sole spelling. This change is + important enough to be implemented for, and released in Python + 3.1. To help transition to this feature, a new future statement, + ``from __future__ import barry_as_flufl`` has been added. + +* Recognized that the ``print`` function in Python 3.0 was a horrible, + pain-inducing mistake, the FLUFL reinstates the ``print`` + statement. This change is important enough to be implemented for, + and released in Python 3.0.2. + +* Recognized that the disappointing adoption curve of Python 3.0 + signals its abject failure, all work on Python 3.1 and subsequent + Python 3.x versions is hereby terminated. All features in Python + 3.0 shall be back ported to Python 2.7 which will be the official + and sole next release. The Python 3.0 string and bytes types will + be back ported to Python 2.6.2 for the convenience of developers. + +* Recognized that C is a 20th century language with almost universal + rejection by programmers under the age of 30, the CPython + implementation will terminate with the release of Python 2.6.2 and + 3.0.2. Thereafter, the reference implementation of Python will + target the Parrot [1]_ virtual machine. Alternative implementations + of Python (e.g. Jython [2]_ and IronPython [3]_) are officially + discouraged but tolerated. + +* Recognized that the Python Software Foundation [4]_ having fulfilled + its mission admirably, is hereby disbanded. They Python Steering + Union [5]_ (not to be confused with the Python Secret Underground, + which emphatically does not exist), is now the sole steward for all + of Python's intellectual property. All PSF funds are hereby + transferred to the PSU (not that PSU, the other PSU). + + +References +========== + +.. [1] http://www.parrot.org + +.. [2] http://www.jython.org + +.. [3] http://www.ironpython.com + +.. [4] http://www.python.org/psf + +.. [5] http://www.pythonlabs.com + + +Copyright +========= + +This document is the property of the Python Steering Union (not to be +confused with the Python Secret Underground, which emphatically does +not exist). We suppose it's okay for you to read this, but don't even +think about quoting, copying, modifying, or distributing it. + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + coding: utf-8 + End: From python-checkins at python.org Wed Apr 1 07:17:23 2009 From: python-checkins at python.org (brett.cannon) Date: Wed, 1 Apr 2009 07:17:23 +0200 (CEST) Subject: [Python-checkins] r70947 - peps/trunk/pep-0401.txt Message-ID: <20090401051723.BA3211E40F1@bag.python.org> Author: brett.cannon Date: Wed Apr 1 07:17:13 2009 New Revision: 70947 Log: Fix a typo. Modified: peps/trunk/pep-0401.txt Modified: peps/trunk/pep-0401.txt ============================================================================== --- peps/trunk/pep-0401.txt (original) +++ peps/trunk/pep-0401.txt Wed Apr 1 07:17:13 2009 @@ -55,7 +55,7 @@ ``<>`` diamond operator as the sole spelling. This change is important enough to be implemented for, and released in Python 3.1. To help transition to this feature, a new future statement, - ``from __future__ import barry_as_flufl`` has been added. + ``from __future__ import barry_as_FLUFL`` has been added. * Recognized that the ``print`` function in Python 3.0 was a horrible, pain-inducing mistake, the FLUFL reinstates the ``print`` From eric at trueblade.com Wed Apr 1 10:55:40 2009 From: eric at trueblade.com (Eric Smith) Date: Wed, 01 Apr 2009 04:55:40 -0400 Subject: [Python-checkins] r70945 - in python/branches/py3k: Grammar/Grammar Include/code.h Include/compile.h Include/parsetok.h Include/pythonrun.h Lib/__future__.py Lib/test/test_flufl.py Parser/parser.c Parser/parsetok.c Parser/tokenizer.c Python/future.c Python/graminit.c Python/pythonrun.c In-Reply-To: <20090401050841.D5B051E40F1@bag.python.org> References: <20090401050841.D5B051E40F1@bag.python.org> Message-ID: <49D32C0C.10802@trueblade.com> brett.cannon wrote: > -comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is'|'is' 'not' > +comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' The PEP says that '<>' is the one true spelling, yet this leaves in '!='. I realize we want to have a transition period where both are accepted. I'll get busy on switching the standard library over so we can keep the transition period to an ample 12 hour duration. Eric. From solipsis at pitrou.net Wed Apr 1 13:06:35 2009 From: solipsis at pitrou.net (Antoine Pitrou) Date: Wed, 1 Apr 2009 11:06:35 +0000 (UTC) Subject: [Python-checkins] =?utf-8?q?r70945_-_in_python/branches/py3k=3A_G?= =?utf-8?q?rammar/Grammar=09Include/code=2Eh_Include/compile=2Eh_In?= =?utf-8?q?clude/parsetok=2Eh=09Include/pythonrun=2EhLib/=5F=5Ffutu?= =?utf-8?q?re=5F=5F=2EpyLib/test/test=5Fflufl=2Epy=09Parser/parser?= =?utf-8?q?=2Ec_Parser/parsetok=2Ec_Parser/tokenizer=2Ec=09Python/f?= =?utf-8?q?uture=2Ec_Python/graminit=2Ec_Python/pythonrun=2Ec?= References: <20090401050841.D5B051E40F1@bag.python.org> Message-ID: writes: > > Author: brett.cannon > Date: Wed Apr 1 07:08:41 2009 > New Revision: 70945 > > Log: > The BDFL has retired! Long live the FLUFL (Friendly Language Uncle For Life)! Haven't you forgotten the part where Mark Shuttleworth becomes the new release manager (Benjamin Peterson having died after he ate a poisoned memoryview) and the Bazaar developers will make Python 3x faster real soon now? Regards Antoine. From python-checkins at python.org Wed Apr 1 13:28:47 2009 From: python-checkins at python.org (kristjan.jonsson) Date: Wed, 1 Apr 2009 13:28:47 +0200 (CEST) Subject: [Python-checkins] r70948 - in python/branches/py3k/Lib/test: regrtest.py test_dbm_gnu.py test_dbm_ndbm.py test_posix.py test_pty.py test_syslog.py test_tk.py Message-ID: <20090401112847.7465A1E4010@bag.python.org> Author: kristjan.jonsson Date: Wed Apr 1 13:28:47 2009 New Revision: 70948 Log: Allow skipping of regression tests not supported on windows. This reduces noise in the regression test suite for py3k on Windows. Modified: python/branches/py3k/Lib/test/regrtest.py python/branches/py3k/Lib/test/test_dbm_gnu.py python/branches/py3k/Lib/test/test_dbm_ndbm.py python/branches/py3k/Lib/test/test_posix.py python/branches/py3k/Lib/test/test_pty.py python/branches/py3k/Lib/test/test_syslog.py python/branches/py3k/Lib/test/test_tk.py Modified: python/branches/py3k/Lib/test/regrtest.py ============================================================================== --- python/branches/py3k/Lib/test/regrtest.py (original) +++ python/branches/py3k/Lib/test/regrtest.py Wed Apr 1 13:28:47 2009 @@ -892,6 +892,7 @@ test_fork1 test_epoll test_dbm_gnu + test_dbm_ndbm test_grp test_ioctl test_largefile 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 Wed Apr 1 13:28:47 2009 @@ -1,4 +1,5 @@ -import dbm.gnu as gdbm +from test import support +gdbm = support.import_module("dbm.gnu") #skip if not supported import unittest import os from test.support import verbose, TESTFN, run_unittest, unlink Modified: python/branches/py3k/Lib/test/test_dbm_ndbm.py ============================================================================== --- python/branches/py3k/Lib/test/test_dbm_ndbm.py (original) +++ python/branches/py3k/Lib/test/test_dbm_ndbm.py Wed Apr 1 13:28:47 2009 @@ -1,4 +1,5 @@ from test import support +support.import_module("dbm.ndbm") #skip if not supported import unittest import os import random Modified: python/branches/py3k/Lib/test/test_posix.py ============================================================================== --- python/branches/py3k/Lib/test/test_posix.py (original) +++ python/branches/py3k/Lib/test/test_posix.py Wed Apr 1 13:28:47 2009 @@ -1,6 +1,7 @@ "Test posix functions" from test import support +posix = support.import_module('posix') #skip if not supported import time import os @@ -9,8 +10,6 @@ import unittest import warnings -posix = support.import_module('posix') - warnings.filterwarnings('ignore', '.* potential security risk .*', RuntimeWarning) Modified: python/branches/py3k/Lib/test/test_pty.py ============================================================================== --- python/branches/py3k/Lib/test/test_pty.py (original) +++ python/branches/py3k/Lib/test/test_pty.py Wed Apr 1 13:28:47 2009 @@ -1,6 +1,7 @@ +from test import support +pty = support.import_module("pty") #skip if not supported import errno import fcntl -import pty import os import sys import signal 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 Wed Apr 1 13:28:47 2009 @@ -1,7 +1,7 @@ -import syslog -import unittest from test import support +syslog = support.import_module("syslog") #skip if not supported +import unittest # XXX(nnorwitz): This test sucks. I don't know of a platform independent way # to verify that the messages were really logged. Modified: python/branches/py3k/Lib/test/test_tk.py ============================================================================== --- python/branches/py3k/Lib/test/test_tk.py (original) +++ python/branches/py3k/Lib/test/test_tk.py Wed Apr 1 13:28:47 2009 @@ -1,10 +1,11 @@ +from test import support +# Skip test if _tkinter wasn't built. +support.import_module('_tkinter') + import tkinter from tkinter.test import runtktests -from test import support import unittest -# Skip test if _tkinter wasn't built. -support.import_module('_tkinter') import tkinter From python-checkins at python.org Wed Apr 1 14:54:16 2009 From: python-checkins at python.org (david.goodger) Date: Wed, 1 Apr 2009 14:54:16 +0200 (CEST) Subject: [Python-checkins] r70949 - peps/trunk/pep-0401.txt Message-ID: <20090401125416.590A31E4018@bag.python.org> Author: david.goodger Date: Wed Apr 1 14:54:16 2009 New Revision: 70949 Log: typo fix Modified: peps/trunk/pep-0401.txt Modified: peps/trunk/pep-0401.txt ============================================================================== --- peps/trunk/pep-0401.txt (original) +++ peps/trunk/pep-0401.txt Wed Apr 1 14:54:16 2009 @@ -78,7 +78,7 @@ discouraged but tolerated. * Recognized that the Python Software Foundation [4]_ having fulfilled - its mission admirably, is hereby disbanded. They Python Steering + its mission admirably, is hereby disbanded. The Python Steering Union [5]_ (not to be confused with the Python Secret Underground, which emphatically does not exist), is now the sole steward for all of Python's intellectual property. All PSF funds are hereby From python-checkins at python.org Wed Apr 1 15:46:47 2009 From: python-checkins at python.org (ronald.oussoren) Date: Wed, 1 Apr 2009 15:46:47 +0200 (CEST) Subject: [Python-checkins] r70950 - python/branches/release26-maint/Mac/BuildScript/seticon.m Message-ID: <20090401134647.6BA1A1E4010@bag.python.org> Author: ronald.oussoren Date: Wed Apr 1 15:46:47 2009 New Revision: 70950 Log: Merge seticon.m file, for some reason 'svnmerge' didn't actually add this file to the repository (probably due me not being awake enough at the time of the initial merge) Added: python/branches/release26-maint/Mac/BuildScript/seticon.m Added: python/branches/release26-maint/Mac/BuildScript/seticon.m ============================================================================== --- (empty file) +++ python/branches/release26-maint/Mac/BuildScript/seticon.m Wed Apr 1 15:46:47 2009 @@ -0,0 +1,26 @@ +/* + * Simple tool for setting an icon on a file. + */ +#import +#include + +int main(int argc, char** argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: seticon ICON TARGET"); + return 1; + } + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSString* iconPath = [NSString stringWithUTF8String:argv[1]]; + NSString* filePath = [NSString stringWithUTF8String:argv[2]]; + + [NSApplication sharedApplication]; + + [[NSWorkspace sharedWorkspace] + setIcon: [[NSImage alloc] initWithContentsOfFile: iconPath] + forFile: filePath + options: 0]; + [pool release]; + return 0; +} From python-checkins at python.org Wed Apr 1 16:02:27 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Apr 2009 16:02:27 +0200 (CEST) Subject: [Python-checkins] r70951 - python/trunk/Misc/ACKS Message-ID: <20090401140227.8EBD81E428B@bag.python.org> Author: georg.brandl Date: Wed Apr 1 16:02:27 2009 New Revision: 70951 Log: Add Maksim, who worked on several issues at the sprint. Modified: python/trunk/Misc/ACKS Modified: python/trunk/Misc/ACKS ============================================================================== --- python/trunk/Misc/ACKS (original) +++ python/trunk/Misc/ACKS Wed Apr 1 16:02:27 2009 @@ -391,6 +391,7 @@ Greg Kochanski Damon Kohler Joseph Koshy +Maksim Kozyarchuk Bob Kras Holger Krekel Michael Kremer From buildbot at python.org Wed Apr 1 16:26:54 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 01 Apr 2009 14:26:54 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 2.6 Message-ID: <20090401142654.AEB7B1E463E@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%202.6/builds/210 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: ronald.oussoren BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Wed Apr 1 16:59:59 2009 From: python-checkins at python.org (ronald.oussoren) Date: Wed, 1 Apr 2009 16:59:59 +0200 (CEST) Subject: [Python-checkins] r70952 - python/branches/py3k/Mac/BuildScript/build-installer.py Message-ID: <20090401145959.3C9141E4126@bag.python.org> Author: ronald.oussoren Date: Wed Apr 1 16:59:59 2009 New Revision: 70952 Log: Fix typo in configure line that caused the build installer to not use the right LDFLAGS settings. Modified: python/branches/py3k/Mac/BuildScript/build-installer.py 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 Wed Apr 1 16:59:59 2009 @@ -651,7 +651,7 @@ 'libraries', 'usr', 'local', 'lib') print "Running configure..." runCommand("%s -C --enable-framework --enable-universalsdk=%s " - "--with-universal-archs=%s --with-computed-gotos" + "--with-universal-archs=%s --with-computed-gotos " "LDFLAGS='-g -L%s/libraries/usr/local/lib' " "OPT='-g -O3 -I%s/libraries/usr/local/include' 2>&1"%( shellQuote(os.path.join(SRCDIR, 'configure')), shellQuote(SDKPATH), From ncoghlan at gmail.com Wed Apr 1 16:59:58 2009 From: ncoghlan at gmail.com (Nick Coghlan) Date: Thu, 02 Apr 2009 00:59:58 +1000 Subject: [Python-checkins] r70879 - in python/trunk: Lib/test/test_mmap.py Modules/mmapmodule.c In-Reply-To: References: <20090331201404.8FED71E4054@bag.python.org> Message-ID: <49D3816E.9050504@gmail.com> Jack diederich wrote: > FYI, PEP-8 > > Imports should usually be on separate lines, e.g.: > > Yes: import os > import sys > > No: import sys, os Of all the PEP 8 guidelines, I think that's the one that I deviate from most frequently. This is especially so for modules with names which are shorter than the import keyword itself (sys, os, re, time being the main offenders there). Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- From python-checkins at python.org Wed Apr 1 17:13:53 2009 From: python-checkins at python.org (hirokazu.yamamoto) Date: Wed, 1 Apr 2009 17:13:53 +0200 (CEST) Subject: [Python-checkins] r70953 - python/trunk/Modules/_multiprocessing/multiprocessing.h Message-ID: <20090401151353.288AE1E4070@bag.python.org> Author: hirokazu.yamamoto Date: Wed Apr 1 17:13:52 2009 New Revision: 70953 Log: Fixed compile error on windows. Modified: python/trunk/Modules/_multiprocessing/multiprocessing.h Modified: python/trunk/Modules/_multiprocessing/multiprocessing.h ============================================================================== --- python/trunk/Modules/_multiprocessing/multiprocessing.h (original) +++ python/trunk/Modules/_multiprocessing/multiprocessing.h Wed Apr 1 17:13:52 2009 @@ -16,6 +16,9 @@ # include # include # include /* getpid() */ +# ifdef Py_DEBUG +# include +# endif # define SEM_HANDLE HANDLE # define SEM_VALUE_MAX LONG_MAX #else From brett at python.org Wed Apr 1 17:15:54 2009 From: brett at python.org (Brett Cannon) Date: Wed, 1 Apr 2009 08:15:54 -0700 Subject: [Python-checkins] r70945 - in python/branches/py3k: Grammar/Grammar Include/code.h Include/compile.h Include/parsetok.h Include/pythonrun.h Lib/__future__.py Lib/test/test_flufl.py Parser/parser.c Parser/parsetok.c Parser/tokenizer.c Python/futur Message-ID: On Wed, Apr 1, 2009 at 01:55, Eric Smith wrote: > brett.cannon wrote: > >> -comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is'|'is' 'not' >> +comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' >> > > The PEP says that '<>' is the one true spelling, yet this leaves in '!='. > The __future__ statement takes care of enforcing only one of the operators. > > I realize we want to have a transition period where both are accepted. I'll > get busy on switching the standard library over so we can keep the > transition period to an ample 12 hour duration. Well, the __future__ statement is permanent, so don't go too nuts. =) -Brett -------------- next part -------------- An HTML attachment was scrubbed... URL: From python-checkins at python.org Wed Apr 1 17:23:43 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Apr 2009 17:23:43 +0200 (CEST) Subject: [Python-checkins] r70954 - in python/trunk/Lib: SimpleXMLRPCServer.py test/test_xmlrpc.py Message-ID: <20090401152343.7EA1B1E41E4@bag.python.org> Author: georg.brandl Date: Wed Apr 1 17:23:43 2009 New Revision: 70954 Log: Fix test_xmlrpc and make the CGI handler work with no CONTENT_LENGTH. Modified: python/trunk/Lib/SimpleXMLRPCServer.py python/trunk/Lib/test/test_xmlrpc.py Modified: python/trunk/Lib/SimpleXMLRPCServer.py ============================================================================== --- python/trunk/Lib/SimpleXMLRPCServer.py (original) +++ python/trunk/Lib/SimpleXMLRPCServer.py Wed Apr 1 17:23:43 2009 @@ -600,7 +600,7 @@ # POST data is normally available through stdin try: length = int(os.environ.get('CONTENT_LENGTH', None)) - except ValueError: + except (TypeError, ValueError): length = -1 if request_text is None: request_text = sys.stdin.read(length) Modified: python/trunk/Lib/test/test_xmlrpc.py ============================================================================== --- python/trunk/Lib/test/test_xmlrpc.py (original) +++ python/trunk/Lib/test/test_xmlrpc.py Wed Apr 1 17:23:43 2009 @@ -629,7 +629,11 @@ sys.stdin = open("xmldata.txt", "r") sys.stdout = open(test_support.TESTFN, "w") - self.cgi.handle_request() + os.environ['CONTENT_LENGTH'] = str(len(data)) + try: + self.cgi.handle_request() + finally: + del os.environ['CONTENT_LENGTH'] sys.stdin.close() sys.stdout.close() From python-checkins at python.org Wed Apr 1 17:53:15 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Apr 2009 17:53:15 +0200 (CEST) Subject: [Python-checkins] r70955 - in python/branches/py3k: Doc/library/csv.rst Lib/test/test_xmlrpc.py Lib/xmlrpc/server.py Message-ID: <20090401155315.6B9D21E4079@bag.python.org> Author: georg.brandl Date: Wed Apr 1 17:53:15 2009 New Revision: 70955 Log: #5636: fix next -> __next__ in csv reader docs. Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/csv.rst python/branches/py3k/Lib/test/test_xmlrpc.py python/branches/py3k/Lib/xmlrpc/server.py Modified: python/branches/py3k/Doc/library/csv.rst ============================================================================== --- python/branches/py3k/Doc/library/csv.rst (original) +++ python/branches/py3k/Doc/library/csv.rst Wed Apr 1 17:53:15 2009 @@ -351,14 +351,13 @@ Reader objects (:class:`DictReader` instances and objects returned by the :func:`reader` function) have the following public methods: - -.. method:: csvreader.next() +.. method:: csvreader.__next__() Return the next row of the reader's iterable object as a list, parsed according - to the current dialect. + to the current dialect. Usually you should call this as ``next(reader)``. -Reader objects have the following public attributes: +Reader objects have the following public attributes: .. attribute:: csvreader.dialect @@ -371,10 +370,8 @@ number of records returned, as records can span multiple lines. - DictReader objects have the following public attribute: - .. attribute:: csvreader.fieldnames If not passed as a parameter when creating the object, this attribute is 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 Apr 1 17:53:15 2009 @@ -598,7 +598,11 @@ sys.stdin = open("xmldata.txt", "r") sys.stdout = open(support.TESTFN, "w") - self.cgi.handle_request() + os.environ['CONTENT_LENGTH'] = str(len(data)) + try: + self.cgi.handle_request() + finally: + del os.environ['CONTENT_LENGTH'] sys.stdin.close() sys.stdout.close() Modified: python/branches/py3k/Lib/xmlrpc/server.py ============================================================================== --- python/branches/py3k/Lib/xmlrpc/server.py (original) +++ python/branches/py3k/Lib/xmlrpc/server.py Wed Apr 1 17:53:15 2009 @@ -590,7 +590,7 @@ # POST data is normally available through stdin try: length = int(os.environ.get('CONTENT_LENGTH', None)) - except ValueError: + except (ValueError, TypeError): length = -1 if request_text is None: request_text = sys.stdin.read(length) From jnoller at gmail.com Wed Apr 1 17:53:28 2009 From: jnoller at gmail.com (Jesse Noller) Date: Wed, 1 Apr 2009 10:53:28 -0500 Subject: [Python-checkins] r70953 - python/trunk/Modules/_multiprocessing/multiprocessing.h In-Reply-To: <20090401151353.288AE1E4070@bag.python.org> References: <20090401151353.288AE1E4070@bag.python.org> Message-ID: <4222a8490904010853q860f951o5cbe3765acfa01b4@mail.gmail.com> Hi Hiro, I saw this checkin - talking to Martin this shouldn't be an issue - what version of VStudio and Windows are you using? Additionally, if this is an issue, this change needs to be merged to all of the active branches. -jesse On Wed, Apr 1, 2009 at 10:13 AM, hirokazu.yamamoto wrote: > Author: hirokazu.yamamoto > Date: Wed Apr ?1 17:13:52 2009 > New Revision: 70953 > > Log: > Fixed compile error on windows. > > Modified: > ? python/trunk/Modules/_multiprocessing/multiprocessing.h > > Modified: python/trunk/Modules/_multiprocessing/multiprocessing.h > ============================================================================== > --- python/trunk/Modules/_multiprocessing/multiprocessing.h ? ? (original) > +++ python/trunk/Modules/_multiprocessing/multiprocessing.h ? ? Wed Apr ?1 17:13:52 2009 > @@ -16,6 +16,9 @@ > ?# ?include > ?# ?include > ?# ?include ? ? ? ? ? ? ?/* getpid() */ > +# ?ifdef Py_DEBUG > +# ? ?include > +# ?endif > ?# ?define SEM_HANDLE HANDLE > ?# ?define SEM_VALUE_MAX LONG_MAX > ?#else > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > http://mail.python.org/mailman/listinfo/python-checkins > From python-checkins at python.org Wed Apr 1 18:00:34 2009 From: python-checkins at python.org (brett.cannon) Date: Wed, 1 Apr 2009 18:00:34 +0200 (CEST) Subject: [Python-checkins] r70956 - in python/trunk: Lib/cgitb.py Misc/NEWS Message-ID: <20090401160034.CA2E51E4070@bag.python.org> Author: brett.cannon Date: Wed Apr 1 18:00:34 2009 New Revision: 70956 Log: The cgitb module had imports in its functions. This can cause deadlock with the import lock if called from within a thread that was triggered by an import. Partially fixes issue #1665206. Modified: python/trunk/Lib/cgitb.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/cgitb.py ============================================================================== --- python/trunk/Lib/cgitb.py (original) +++ python/trunk/Lib/cgitb.py Wed Apr 1 18:00:34 2009 @@ -19,13 +19,19 @@ for you, call cgitb.handler(). The optional argument to handler() is a 3-item tuple (etype, evalue, etb) just like the value of sys.exc_info(). The default handler displays output as HTML. -""" - -__author__ = 'Ka-Ping Yee' - -__version__ = '$Revision$' +""" +import inspect +import keyword +import linecache +import os +import pydoc import sys +import tempfile +import time +import tokenize +import traceback +import types def reset(): """Return a string that resets the CGI and browser to a known state.""" @@ -74,7 +80,6 @@ def scanvars(reader, frame, locals): """Scan one logical line of Python and look up values of variables used.""" - import tokenize, keyword vars, lasttoken, parent, prefix, value = [], None, None, '', __UNDEF__ for ttype, token, start, end, line in tokenize.generate_tokens(reader): if ttype == tokenize.NEWLINE: break @@ -96,8 +101,6 @@ def html((etype, evalue, etb), context=5): """Return a nice HTML document describing a given traceback.""" - import os, types, time, traceback, linecache, inspect, pydoc - if type(etype) is types.ClassType: etype = etype.__name__ pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable @@ -173,7 +176,6 @@ value = pydoc.html.repr(getattr(evalue, name)) exception.append('\n
%s%s =\n%s' % (indent, name, value)) - import traceback return head + ''.join(frames) + ''.join(exception) + ''' @@ -188,8 +190,6 @@ def text((etype, evalue, etb), context=5): """Return a plain text document describing a given traceback.""" - import os, types, time, traceback, linecache, inspect, pydoc - if type(etype) is types.ClassType: etype = etype.__name__ pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable @@ -245,7 +245,6 @@ value = pydoc.text.repr(getattr(evalue, name)) exception.append('\n%s%s = %s' % (" "*4, name, value)) - import traceback return head + ''.join(frames) + ''.join(exception) + ''' The above is a description of an error in a Python program. Here is @@ -278,7 +277,6 @@ try: doc = formatter(info, self.context) except: # just in case something goes wrong - import traceback doc = ''.join(traceback.format_exception(*info)) plain = True @@ -292,7 +290,6 @@ self.file.write('

A problem occurred in a Python script.\n') if self.logdir is not None: - import os, tempfile suffix = ['.txt', '.html'][self.format=="html"] (fd, path) = tempfile.mkstemp(suffix=suffix, dir=self.logdir) try: Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Apr 1 18:00:34 2009 @@ -200,6 +200,10 @@ Library ------- +- Issue #1665206 (partially): Move imports in cgitb to the top of the module + instead of performing them in functions. Helps prevent import deadlocking in + threads. + - Actually make the SimpleXMLRPCServer CGI handler work. - Issue #2522: locale.format now checks its first argument to ensure it has From python-checkins at python.org Wed Apr 1 18:06:02 2009 From: python-checkins at python.org (brett.cannon) Date: Wed, 1 Apr 2009 18:06:02 +0200 (CEST) Subject: [Python-checkins] r70957 - in python/branches/py3k: Lib/cgitb.py Misc/NEWS Message-ID: <20090401160602.1344C1E4070@bag.python.org> Author: brett.cannon Date: Wed Apr 1 18:06:01 2009 New Revision: 70957 Log: Merged revisions 70956 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70956 | brett.cannon | 2009-04-01 09:00:34 -0700 (Wed, 01 Apr 2009) | 5 lines The cgitb module had imports in its functions. This can cause deadlock with the import lock if called from within a thread that was triggered by an import. Partially fixes issue #1665206. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/cgitb.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/cgitb.py ============================================================================== --- python/branches/py3k/Lib/cgitb.py (original) +++ python/branches/py3k/Lib/cgitb.py Wed Apr 1 18:06:01 2009 @@ -19,13 +19,19 @@ for you, call cgitb.handler(). The optional argument to handler() is a 3-item tuple (etype, evalue, etb) just like the value of sys.exc_info(). The default handler displays output as HTML. -""" - -__author__ = 'Ka-Ping Yee' - -__version__ = '$Revision$' +""" +import inspect +import keyword +import linecache +import os +import pydoc import sys +import tempfile +import time +import tokenize +import traceback +import types def reset(): """Return a string that resets the CGI and browser to a known state.""" @@ -74,7 +80,6 @@ def scanvars(reader, frame, locals): """Scan one logical line of Python and look up values of variables used.""" - import tokenize, keyword vars, lasttoken, parent, prefix, value = [], None, None, '', __UNDEF__ for ttype, token, start, end, line in tokenize.generate_tokens(reader): if ttype == tokenize.NEWLINE: break @@ -96,8 +101,6 @@ def html(einfo, context=5): """Return a nice HTML document describing a given traceback.""" - import os, time, traceback, linecache, inspect, pydoc - etype, evalue, etb = einfo if isinstance(etype, type): etype = etype.__name__ @@ -173,7 +176,6 @@ value = pydoc.html.repr(getattr(evalue, name)) exception.append('\n
%s%s =\n%s' % (indent, name, value)) - import traceback return head + ''.join(frames) + ''.join(exception) + ''' @@ -188,8 +190,6 @@ def text(einfo, context=5): """Return a plain text document describing a given traceback.""" - import os, time, traceback, linecache, inspect, pydoc - etype, evalue, etb = einfo if isinstance(etype, type): etype = etype.__name__ @@ -245,7 +245,6 @@ value = pydoc.text.repr(getattr(evalue, name)) exception.append('\n%s%s = %s' % (" "*4, name, value)) - import traceback return head + ''.join(frames) + ''.join(exception) + ''' The above is a description of an error in a Python program. Here is @@ -278,7 +277,6 @@ try: doc = formatter(info, self.context) except: # just in case something goes wrong - import traceback doc = ''.join(traceback.format_exception(*info)) plain = True @@ -292,7 +290,6 @@ self.file.write('

A problem occurred in a Python script.\n') if self.logdir is not None: - import os, tempfile suffix = ['.txt', '.html'][self.format=="html"] (fd, path) = tempfile.mkstemp(suffix=suffix, dir=self.logdir) try: Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Apr 1 18:06:01 2009 @@ -286,6 +286,10 @@ Library ------- +- Issue #1665206 (partially): Move imports in cgitb to the top of the module + instead of performing them in functions. Helps prevent import deadlocking in + threads. + - Issue #2522: locale.format now checks its first argument to ensure it has been passed only one pattern, avoiding mysterious errors where it appeared that it was failing to do localization. From python-checkins at python.org Wed Apr 1 18:08:35 2009 From: python-checkins at python.org (kristjan.jonsson) Date: Wed, 1 Apr 2009 18:08:35 +0200 (CEST) Subject: [Python-checkins] r70958 - python/trunk/Modules/posixmodule.c Message-ID: <20090401160835.129D71E4070@bag.python.org> Author: kristjan.jonsson Date: Wed Apr 1 18:08:34 2009 New Revision: 70958 Log: http://bugs.python.org/issue5623 Dynamically discoverd the size of the ioinfo struct used by the crt for its file descriptors. This should work across all flavors of the CRT. Thanks to Amaury Forgeot d'Arc Needs porting to 3.1 Modified: python/trunk/Modules/posixmodule.c Modified: python/trunk/Modules/posixmodule.c ============================================================================== --- python/trunk/Modules/posixmodule.c (original) +++ python/trunk/Modules/posixmodule.c Wed Apr 1 18:08:34 2009 @@ -269,6 +269,7 @@ #include #endif #include "osdefs.h" +#include #include #include /* for ShellExecute() */ #define popen _popen @@ -364,41 +365,15 @@ * (all of this is to avoid globally modifying the CRT behaviour using * _set_invalid_parameter_handler() and _CrtSetReportMode()) */ -#if _MSC_VER >= 1500 /* VS 2008 */ -typedef struct { - intptr_t osfhnd; - char osfile; - char pipech; - int lockinitflag; - CRITICAL_SECTION lock; -#ifndef _SAFECRT_IMPL - char textmode : 7; - char unicode : 1; - char pipech2[2]; - __int64 startpos; - BOOL utf8translations; - char dbcsBuffer; - BOOL dbcsBufferUsed; -#endif /* _SAFECRT_IMPL */ - } ioinfo; -#elif _MSC_VER >= 1400 /* VS 2005 */ +/* The actual size of the structure is determined at runtime. + * Only the first items must be present. + */ typedef struct { intptr_t osfhnd; char osfile; - char pipech; - int lockinitflag; - CRITICAL_SECTION lock; -#ifndef _SAFECRT_IMPL - char textmode : 7; - char unicode : 1; - char pipech2[2]; - __int64 startpos; - BOOL utf8translations; -#endif /* _SAFECRT_IMPL */ - } ioinfo; -#endif +} my_ioinfo; -extern __declspec(dllimport) ioinfo * __pioinfo[]; +extern __declspec(dllimport) char * __pioinfo[]; #define IOINFO_L2E 5 #define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) #define IOINFO_ARRAYS 64 @@ -412,6 +387,19 @@ { const int i1 = fd >> IOINFO_L2E; const int i2 = fd & ((1 << IOINFO_L2E) - 1); + + static int sizeof_ioinfo = 0; + + /* Determine the actual size of the ioinfo structure, + * as used by the CRT loaded in memory + */ + if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) { + sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS; + } + if (sizeof_ioinfo == 0) { + /* This should not happen... */ + goto fail; + } /* See that it isn't a special CLEAR fileno */ if (fd != _NO_CONSOLE_FILENO) { @@ -420,10 +408,13 @@ */ if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) { /* finally, check that the file is open */ - if (__pioinfo[i1][i2].osfile & FOPEN) + my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo); + if (info->osfile & FOPEN) { return 1; + } } } + fail: errno = EBADF; return 0; } From python-checkins at python.org Wed Apr 1 18:39:21 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 1 Apr 2009 18:39:21 +0200 (CEST) Subject: [Python-checkins] r70959 - python/branches/py3k/Lib/test/test_tk.py Message-ID: <20090401163921.EF30A1E40A7@bag.python.org> Author: r.david.murray Date: Wed Apr 1 18:39:21 2009 New Revision: 70959 Log: Remove redundant import of tkinter. Modified: python/branches/py3k/Lib/test/test_tk.py Modified: python/branches/py3k/Lib/test/test_tk.py ============================================================================== --- python/branches/py3k/Lib/test/test_tk.py (original) +++ python/branches/py3k/Lib/test/test_tk.py Wed Apr 1 18:39:21 2009 @@ -6,9 +6,6 @@ from tkinter.test import runtktests import unittest - -import tkinter - try: tkinter.Button() except tkinter.TclError as msg: From python-checkins at python.org Wed Apr 1 18:42:19 2009 From: python-checkins at python.org (jesse.noller) Date: Wed, 1 Apr 2009 18:42:19 +0200 (CEST) Subject: [Python-checkins] r70960 - python/trunk/Doc/library/multiprocessing.rst Message-ID: <20090401164219.9FA9E1E4070@bag.python.org> Author: jesse.noller Date: Wed Apr 1 18:42:19 2009 New Revision: 70960 Log: Issue 3270: document Listener address restrictions on windows Modified: python/trunk/Doc/library/multiprocessing.rst Modified: python/trunk/Doc/library/multiprocessing.rst ============================================================================== --- python/trunk/Doc/library/multiprocessing.rst (original) +++ python/trunk/Doc/library/multiprocessing.rst Wed Apr 1 18:42:19 2009 @@ -1705,6 +1705,12 @@ *address* is the address to be used by the bound socket or named pipe of the listener object. + .. note:: + + If an address of '0.0.0.0' is used, the address will not be a connectable + end point on Windows. If you require a connectable end-point, + you should use '127.0.0.1'. + *family* is the type of socket (or named pipe) to use. This can be one of the strings ``'AF_INET'`` (for a TCP socket), ``'AF_UNIX'`` (for a Unix domain socket) or ``'AF_PIPE'`` (for a Windows named pipe). Of these only From python-checkins at python.org Wed Apr 1 18:44:24 2009 From: python-checkins at python.org (jesse.noller) Date: Wed, 1 Apr 2009 18:44:24 +0200 (CEST) Subject: [Python-checkins] r70961 - in python/branches/release26-maint: Doc/library/multiprocessing.rst Message-ID: <20090401164424.AB9121E4070@bag.python.org> Author: jesse.noller Date: Wed Apr 1 18:44:24 2009 New Revision: 70961 Log: Merged revisions 70960 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70960 | jesse.noller | 2009-04-01 11:42:19 -0500 (Wed, 01 Apr 2009) | 1 line Issue 3270: document Listener address restrictions on windows ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/multiprocessing.rst Modified: python/branches/release26-maint/Doc/library/multiprocessing.rst ============================================================================== --- python/branches/release26-maint/Doc/library/multiprocessing.rst (original) +++ python/branches/release26-maint/Doc/library/multiprocessing.rst Wed Apr 1 18:44:24 2009 @@ -1697,6 +1697,12 @@ *address* is the address to be used by the bound socket or named pipe of the listener object. + .. note:: + + If an address of '0.0.0.0' is used, the address will not be a connectable + end point on Windows. If you require a connectable end-point, + you should use '127.0.0.1'. + *family* is the type of socket (or named pipe) to use. This can be one of the strings ``'AF_INET'`` (for a TCP socket), ``'AF_UNIX'`` (for a Unix domain socket) or ``'AF_PIPE'`` (for a Windows named pipe). Of these only From ocean-city at m2.ccsnet.ne.jp Wed Apr 1 19:03:00 2009 From: ocean-city at m2.ccsnet.ne.jp (Hirokazu Yamamoto) Date: Thu, 02 Apr 2009 02:03:00 +0900 Subject: [Python-checkins] r70953 - python/trunk/Modules/_multiprocessing/multiprocessing.h In-Reply-To: <4222a8490904010853q860f951o5cbe3765acfa01b4@mail.gmail.com> References: <20090401151353.288AE1E4070@bag.python.org> <4222a8490904010853q860f951o5cbe3765acfa01b4@mail.gmail.com> Message-ID: <49D39E44.2050809@m2.ccsnet.ne.jp> Jesse Noller wrote: > Hi Hiro, I saw this checkin - talking to Martin this shouldn't be an > issue - what version of VStudio and Windows are you using? I'm using VC6, but I can see this compile error on buildbot too. http://www.python.org/dev/buildbot/trunk.stable/x86%20XP-4%20trunk/builds/2010/step-compile/0 > Additionally, if this is an issue, this change needs to be merged to > all of the active branches. Yes, I was waiting for buildbot result. And I had a feeling that some reaction I could get. (ex: this include should be done in win32_functions.c rather than header file...?) ;-) From python-checkins at python.org Wed Apr 1 19:07:16 2009 From: python-checkins at python.org (brett.cannon) Date: Wed, 1 Apr 2009 19:07:16 +0200 (CEST) Subject: [Python-checkins] r70962 - python/trunk/Misc/developers.txt Message-ID: <20090401170716.C3C041E4070@bag.python.org> Author: brett.cannon Date: Wed Apr 1 19:07:16 2009 New Revision: 70962 Log: Ron DuPlain was given commit privileges at PyCon 2009 to work on 3to2. Modified: python/trunk/Misc/developers.txt Modified: python/trunk/Misc/developers.txt ============================================================================== --- python/trunk/Misc/developers.txt (original) +++ python/trunk/Misc/developers.txt Wed Apr 1 19:07:16 2009 @@ -17,6 +17,8 @@ Permissions History ------------------- +- Ron DuPlain was given commit privileges at PyCon 2009 by BAC to work on 3to2. + - Several developers of alternative Python implementations where given access for test suite and library adaptions by MvL: Allison Randal (Parrot), Michael Foord (IronPython), From python-checkins at python.org Wed Apr 1 19:46:01 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Apr 2009 19:46:01 +0200 (CEST) Subject: [Python-checkins] r70963 - python/trunk/Lib/glob.py Message-ID: <20090401174601.893F71E474A@bag.python.org> Author: georg.brandl Date: Wed Apr 1 19:46:01 2009 New Revision: 70963 Log: #5655: fix docstring oversight. Modified: python/trunk/Lib/glob.py Modified: python/trunk/Lib/glob.py ============================================================================== --- python/trunk/Lib/glob.py (original) +++ python/trunk/Lib/glob.py Wed Apr 1 19:46:01 2009 @@ -16,7 +16,7 @@ return list(iglob(pathname)) def iglob(pathname): - """Return a list of paths matching a pathname pattern. + """Return an iterator which yields the paths matching a pathname pattern. The pattern may contain simple shell-style wildcards a la fnmatch. From python-checkins at python.org Wed Apr 1 19:52:13 2009 From: python-checkins at python.org (brett.cannon) Date: Wed, 1 Apr 2009 19:52:13 +0200 (CEST) Subject: [Python-checkins] r70964 - python/trunk/Misc/developers.txt Message-ID: <20090401175213.C55581E437B@bag.python.org> Author: brett.cannon Date: Wed Apr 1 19:52:13 2009 New Revision: 70964 Log: Paul Kippes was given commit privileges to work on 3to2. Modified: python/trunk/Misc/developers.txt Modified: python/trunk/Misc/developers.txt ============================================================================== --- python/trunk/Misc/developers.txt (original) +++ python/trunk/Misc/developers.txt Wed Apr 1 19:52:13 2009 @@ -17,6 +17,8 @@ Permissions History ------------------- +- Paul Kippes was given commit privileges at PyCon 2009 by BAC to work on 3to2. + - Ron DuPlain was given commit privileges at PyCon 2009 by BAC to work on 3to2. - Several developers of alternative Python implementations where From python-checkins at python.org Wed Apr 1 20:03:59 2009 From: python-checkins at python.org (brett.cannon) Date: Wed, 1 Apr 2009 20:03:59 +0200 (CEST) Subject: [Python-checkins] r70965 - in python/trunk: Lib/test/test_warnings.py Misc/NEWS Python/_warnings.c Message-ID: <20090401180359.60DDD1E4070@bag.python.org> Author: brett.cannon Date: Wed Apr 1 20:03:59 2009 New Revision: 70965 Log: _warnings was importing itself to get an attribute. That's bad if warnings gets called in a thread that was spawned by an import itself. Last part to close #1665206. Modified: python/trunk/Lib/test/test_warnings.py python/trunk/Misc/NEWS python/trunk/Python/_warnings.c Modified: python/trunk/Lib/test/test_warnings.py ============================================================================== --- python/trunk/Lib/test/test_warnings.py (original) +++ python/trunk/Lib/test/test_warnings.py Wed Apr 1 20:03:59 2009 @@ -413,6 +413,41 @@ finally: self.module.onceregistry = original_registry + def test_default_action(self): + # Replacing or removing defaultaction should be okay. + message = UserWarning("defaultaction test") + original = self.module.defaultaction + try: + with original_warnings.catch_warnings(record=True, + module=self.module) as w: + self.module.resetwarnings() + registry = {} + self.module.warn_explicit(message, UserWarning, "", 42, + registry=registry) + self.assertEqual(w[-1].message, message) + self.assertEqual(len(w), 1) + self.assertEqual(len(registry), 1) + del w[:] + # Test removal. + del self.module.defaultaction + __warningregistry__ = {} + registry = {} + self.module.warn_explicit(message, UserWarning, "", 43, + registry=registry) + self.assertEqual(w[-1].message, message) + self.assertEqual(len(w), 1) + self.assertEqual(len(registry), 1) + del w[:] + # Test setting. + self.module.defaultaction = "ignore" + __warningregistry__ = {} + registry = {} + self.module.warn_explicit(message, UserWarning, "", 44, + registry=registry) + self.assertEqual(len(w), 0) + finally: + self.module.defaultaction = original + def test_showwarning_missing(self): # Test that showwarning() missing is okay. text = 'del showwarning test' Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Apr 1 20:03:59 2009 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #1665206: Remove the last eager import in _warnings.c and make it lazy. + - Issue #4865: On MacOSX /Library/Python/2.7/site-packages is added to the end sys.path, for compatibility with the system install of Python. Modified: python/trunk/Python/_warnings.c ============================================================================== --- python/trunk/Python/_warnings.c (original) +++ python/trunk/Python/_warnings.c Wed Apr 1 20:03:59 2009 @@ -2,7 +2,6 @@ #include "frameobject.h" #define MODULE_NAME "_warnings" -#define DEFAULT_ACTION_NAME "default_action" PyDoc_STRVAR(warnings__doc__, MODULE_NAME " provides basic warning filtering support.\n" @@ -12,6 +11,7 @@ get_warnings_attr() will reset these variables accordingly. */ static PyObject *_filters; /* List */ static PyObject *_once_registry; /* Dict */ +static PyObject *_default_action; /* String */ static int @@ -78,12 +78,31 @@ } +static PyObject * +get_default_action(void) +{ + PyObject *default_action; + + default_action = get_warnings_attr("defaultaction"); + if (default_action == NULL) { + if (PyErr_Occurred()) { + return NULL; + } + return _default_action; + } + + Py_DECREF(_default_action); + _default_action = default_action; + return default_action; +} + + /* The item is a borrowed reference. */ static const char * get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, PyObject *module, PyObject **item) { - PyObject *action, *m, *d; + PyObject *action; Py_ssize_t i; PyObject *warnings_filters; @@ -135,22 +154,17 @@ return PyString_AsString(action); } - m = PyImport_ImportModule(MODULE_NAME); - if (m == NULL) - return NULL; - d = PyModule_GetDict(m); - Py_DECREF(m); - if (d == NULL) - return NULL; - action = PyDict_GetItemString(d, DEFAULT_ACTION_NAME); - if (action != NULL) + action = get_default_action(); + if (action != NULL) { return PyString_AsString(action); + } PyErr_SetString(PyExc_ValueError, - MODULE_NAME "." DEFAULT_ACTION_NAME " not found"); + MODULE_NAME ".defaultaction not found"); return NULL; } + static int already_warned(PyObject *registry, PyObject *key, int should_set) { @@ -854,7 +868,7 @@ PyMODINIT_FUNC _PyWarnings_Init(void) { - PyObject *m, *default_action; + PyObject *m; m = Py_InitModule3(MODULE_NAME, warnings_functions, warnings__doc__); if (m == NULL) @@ -874,9 +888,9 @@ if (PyModule_AddObject(m, "once_registry", _once_registry) < 0) return; - default_action = PyString_InternFromString("default"); - if (default_action == NULL) + _default_action = PyString_FromString("default"); + if (_default_action == NULL) return; - if (PyModule_AddObject(m, DEFAULT_ACTION_NAME, default_action) < 0) + if (PyModule_AddObject(m, "default_action", _default_action) < 0) return; } From python-checkins at python.org Wed Apr 1 20:13:08 2009 From: python-checkins at python.org (brett.cannon) Date: Wed, 1 Apr 2009 20:13:08 +0200 (CEST) Subject: [Python-checkins] r70966 - in python/branches/py3k: Lib/test/test_warnings.py Misc/NEWS Python/_warnings.c Message-ID: <20090401181308.2F2D11E4070@bag.python.org> Author: brett.cannon Date: Wed Apr 1 20:13:07 2009 New Revision: 70966 Log: Merged revisions 70965 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70965 | brett.cannon | 2009-04-01 11:03:59 -0700 (Wed, 01 Apr 2009) | 5 lines _warnings was importing itself to get an attribute. That's bad if warnings gets called in a thread that was spawned by an import itself. Last part to close #1665206. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_warnings.py python/branches/py3k/Misc/NEWS python/branches/py3k/Python/_warnings.c Modified: python/branches/py3k/Lib/test/test_warnings.py ============================================================================== --- python/branches/py3k/Lib/test/test_warnings.py (original) +++ python/branches/py3k/Lib/test/test_warnings.py Wed Apr 1 20:13:07 2009 @@ -423,6 +423,41 @@ finally: self.module.onceregistry = original_registry + def test_default_action(self): + # Replacing or removing defaultaction should be okay. + message = UserWarning("defaultaction test") + original = self.module.defaultaction + try: + with original_warnings.catch_warnings(record=True, + module=self.module) as w: + self.module.resetwarnings() + registry = {} + self.module.warn_explicit(message, UserWarning, "", 42, + registry=registry) + self.assertEqual(w[-1].message, message) + self.assertEqual(len(w), 1) + self.assertEqual(len(registry), 1) + del w[:] + # Test removal. + del self.module.defaultaction + __warningregistry__ = {} + registry = {} + self.module.warn_explicit(message, UserWarning, "", 43, + registry=registry) + self.assertEqual(w[-1].message, message) + self.assertEqual(len(w), 1) + self.assertEqual(len(registry), 1) + del w[:] + # Test setting. + self.module.defaultaction = "ignore" + __warningregistry__ = {} + registry = {} + self.module.warn_explicit(message, UserWarning, "", 44, + registry=registry) + self.assertEqual(len(w), 0) + finally: + self.module.defaultaction = original + def test_showwarning_missing(self): # Test that showwarning() missing is okay. text = 'del showwarning test' Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Apr 1 20:13:07 2009 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #1665206: Remove the last eager import in _warnings.c and make it lazy. + - Fix a segfault when running test_exceptions with coverage, caused by insufficient checks in accessors of Exception.__context__. Modified: python/branches/py3k/Python/_warnings.c ============================================================================== --- python/branches/py3k/Python/_warnings.c (original) +++ python/branches/py3k/Python/_warnings.c Wed Apr 1 20:13:07 2009 @@ -2,7 +2,6 @@ #include "frameobject.h" #define MODULE_NAME "_warnings" -#define DEFAULT_ACTION_NAME "default_action" PyDoc_STRVAR(warnings__doc__, MODULE_NAME " provides basic warning filtering support.\n" @@ -12,6 +11,7 @@ get_warnings_attr() will reset these variables accordingly. */ static PyObject *_filters; /* List */ static PyObject *_once_registry; /* Dict */ +static PyObject *_default_action; /* String */ static int @@ -78,12 +78,31 @@ } +static PyObject * +get_default_action(void) +{ + PyObject *default_action; + + default_action = get_warnings_attr("defaultaction"); + if (default_action == NULL) { + if (PyErr_Occurred()) { + return NULL; + } + return _default_action; + } + + Py_DECREF(_default_action); + _default_action = default_action; + return default_action; +} + + /* The item is a borrowed reference. */ static const char * get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, PyObject *module, PyObject **item) { - PyObject *action, *m, *d; + PyObject *action; Py_ssize_t i; PyObject *warnings_filters; @@ -135,22 +154,17 @@ return _PyUnicode_AsString(action); } - m = PyImport_ImportModule(MODULE_NAME); - if (m == NULL) - return NULL; - d = PyModule_GetDict(m); - Py_DECREF(m); - if (d == NULL) - return NULL; - action = PyDict_GetItemString(d, DEFAULT_ACTION_NAME); - if (action != NULL) + action = get_default_action(); + if (action != NULL) { return _PyUnicode_AsString(action); + } PyErr_SetString(PyExc_ValueError, - MODULE_NAME "." DEFAULT_ACTION_NAME " not found"); + MODULE_NAME ".defaultaction not found"); return NULL; } + static int already_warned(PyObject *registry, PyObject *key, int should_set) { @@ -874,7 +888,7 @@ PyMODINIT_FUNC _PyWarnings_Init(void) { - PyObject *m, *default_action; + PyObject *m; m = PyModule_Create(&warningsmodule); if (m == NULL) @@ -894,10 +908,10 @@ if (PyModule_AddObject(m, "once_registry", _once_registry) < 0) return NULL; - default_action = PyUnicode_InternFromString("default"); - if (default_action == NULL) + _default_action = PyUnicode_FromString("default"); + if (_default_action == NULL) return NULL; - if (PyModule_AddObject(m, DEFAULT_ACTION_NAME, default_action) < 0) + if (PyModule_AddObject(m, "default_action", _default_action) < 0) return NULL; return m; } From python-checkins at python.org Wed Apr 1 20:25:03 2009 From: python-checkins at python.org (ron.duplain) Date: Wed, 1 Apr 2009 20:25:03 +0200 (CEST) Subject: [Python-checkins] r70967 - sandbox/trunk/refactor_pkg Message-ID: <20090401182503.763BC1E4070@bag.python.org> Author: ron.duplain Date: Wed Apr 1 20:25:03 2009 New Revision: 70967 Log: Creating a sandbox home for 3to2, refactor_pkg. Added: sandbox/trunk/refactor_pkg/ From python-checkins at python.org Wed Apr 1 20:25:39 2009 From: python-checkins at python.org (michael.foord) Date: Wed, 1 Apr 2009 20:25:39 +0200 (CEST) Subject: [Python-checkins] r70968 - in python/trunk/Misc: README python-wing.wpr Message-ID: <20090401182539.31ECF1E4747@bag.python.org> Author: michael.foord Date: Wed Apr 1 20:25:38 2009 New Revision: 70968 Log: Adding Wing project file Added: python/trunk/Misc/python-wing.wpr (contents, props changed) Modified: python/trunk/Misc/ (props changed) python/trunk/Misc/README Modified: python/trunk/Misc/README ============================================================================== --- python/trunk/Misc/README (original) +++ python/trunk/Misc/README Wed Apr 1 20:25:38 2009 @@ -23,6 +23,7 @@ pymemcompat.h Memory interface compatibility file. python.man UNIX man page for the python interpreter python-mode.el Emacs mode for editing Python programs +python-wing.wpr Wing IDE project file README The file you're reading now README.valgrind Information for Valgrind users, see valgrind-python.supp RFD Request For Discussion about a Python newsgroup Added: python/trunk/Misc/python-wing.wpr ============================================================================== --- (empty file) +++ python/trunk/Misc/python-wing.wpr Wed Apr 1 20:25:38 2009 @@ -0,0 +1,13 @@ +#!wing +#!version=3.0 +################################################################## +# Wing IDE project file # +################################################################## +[project attributes] +proj.directory-list = [{'dirloc': loc('..'), + 'excludes': (), + 'filter': '*', + 'include_hidden': False, + 'recursive': True, + 'watch_for_changes': True}] +proj.file-type = 'shared' From buildbot at python.org Wed Apr 1 20:39:17 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 01 Apr 2009 18:39:17 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo trunk Message-ID: <20090401183917.9E0C61E4070@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo trunk. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%20gentoo%20trunk/builds/2057 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-amd64 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: brett.cannon BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_asyncore ====================================================================== FAIL: test_readwrite (test.test_asyncore.HelperFunctionTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/trunk.norwitz-amd64/build/Lib/test/test_asyncore.py", line 144, in test_readwrite self.assertEqual(tobj.read, True) AssertionError: False != True make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Wed Apr 1 20:50:57 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 1 Apr 2009 20:50:57 +0200 (CEST) Subject: [Python-checkins] r70969 - in python/trunk: Lib/_abcoll.py Lib/test/test_collections.py Misc/NEWS Message-ID: <20090401185057.1DE2B1E4070@bag.python.org> Author: raymond.hettinger Date: Wed Apr 1 20:50:56 2009 New Revision: 70969 Log: Issue #5647: MutableSet.__iand__() no longer mutates self during iteration. Modified: python/trunk/Lib/_abcoll.py python/trunk/Lib/test/test_collections.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/_abcoll.py ============================================================================== --- python/trunk/Lib/_abcoll.py (original) +++ python/trunk/Lib/_abcoll.py Wed Apr 1 20:50:56 2009 @@ -286,10 +286,9 @@ self.add(value) return self - def __iand__(self, c): - for value in self: - if value not in c: - self.discard(value) + def __iand__(self, it): + for value in (self - it): + self.discard(value) return self def __ixor__(self, it): Modified: python/trunk/Lib/test/test_collections.py ============================================================================== --- python/trunk/Lib/test/test_collections.py (original) +++ python/trunk/Lib/test/test_collections.py Wed Apr 1 20:50:56 2009 @@ -327,6 +327,25 @@ B.register(C) self.failUnless(issubclass(C, B)) +class WithSet(MutableSet): + + def __init__(self, it=()): + self.data = set(it) + + def __len__(self): + return len(self.data) + + def __iter__(self): + return iter(self.data) + + def __contains__(self, item): + return item in self.data + + def add(self, item): + self.data.add(item) + + def discard(self, item): + self.data.discard(item) class TestCollectionABCs(ABCTestCase): @@ -363,6 +382,12 @@ self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__', 'add', 'discard') + def test_issue_5647(self): + # MutableSet.__iand__ mutated the set during iteration + s = WithSet('abcd') + s &= WithSet('cdef') # This used to fail + self.assertEqual(set(s), set('cd')) + def test_issue_4920(self): # MutableSet.pop() method did not work class MySet(collections.MutableSet): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Apr 1 20:50:56 2009 @@ -206,6 +206,8 @@ instead of performing them in functions. Helps prevent import deadlocking in threads. +- Issue #5647: MutableSet.__iand__() no longer mutates self during iteration. + - Actually make the SimpleXMLRPCServer CGI handler work. - Issue #2522: locale.format now checks its first argument to ensure it has From python-checkins at python.org Wed Apr 1 20:55:57 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 1 Apr 2009 20:55:57 +0200 (CEST) Subject: [Python-checkins] r70970 - in python/branches/release26-maint/Lib: _abcoll.py test/test_collections.py Message-ID: <20090401185557.6A1D01E4070@bag.python.org> Author: raymond.hettinger Date: Wed Apr 1 20:55:57 2009 New Revision: 70970 Log: Issue #5647: MutableSet.__iand__() no longer mutates self during iteration. Modified: python/branches/release26-maint/Lib/_abcoll.py python/branches/release26-maint/Lib/test/test_collections.py Modified: python/branches/release26-maint/Lib/_abcoll.py ============================================================================== --- python/branches/release26-maint/Lib/_abcoll.py (original) +++ python/branches/release26-maint/Lib/_abcoll.py Wed Apr 1 20:55:57 2009 @@ -286,10 +286,9 @@ self.add(value) return self - def __iand__(self, c): - for value in self: - if value not in c: - self.discard(value) + def __iand__(self, it): + for value in (self - it): + self.discard(value) return self def __ixor__(self, it): Modified: python/branches/release26-maint/Lib/test/test_collections.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_collections.py (original) +++ python/branches/release26-maint/Lib/test/test_collections.py Wed Apr 1 20:55:57 2009 @@ -311,6 +311,25 @@ B.register(C) self.failUnless(issubclass(C, B)) +class WithSet(MutableSet): + + def __init__(self, it=()): + self.data = set(it) + + def __len__(self): + return len(self.data) + + def __iter__(self): + return iter(self.data) + + def __contains__(self, item): + return item in self.data + + def add(self, item): + self.data.add(item) + + def discard(self, item): + self.data.discard(item) class TestCollectionABCs(ABCTestCase): @@ -347,6 +366,12 @@ self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__', 'add', 'discard') + def test_issue_5647(self): + # MutableSet.__iand__ mutated the set during iteration + s = WithSet('abcd') + s &= WithSet('cdef') # This used to fail + self.assertEqual(set(s), set('cd')) + def test_issue_4920(self): # MutableSet.pop() method did not work class MySet(collections.MutableSet): From python-checkins at python.org Wed Apr 1 20:57:45 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 1 Apr 2009 20:57:45 +0200 (CEST) Subject: [Python-checkins] r70971 - python/branches/release26-maint/Misc/NEWS Message-ID: <20090401185745.A7BD71E40D9@bag.python.org> Author: raymond.hettinger Date: Wed Apr 1 20:57:45 2009 New Revision: 70971 Log: Add NEWS item. Modified: python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Wed Apr 1 20:57:45 2009 @@ -92,6 +92,8 @@ Library ------- +- Issue #5647: MutableSet.__iand__() no longer mutates self during iteration. + - Issue #5619: Multiprocessing children disobey the debug flag and causes popups on windows buildbots. Patch applied to work around this issue. From python-checkins at python.org Wed Apr 1 21:02:12 2009 From: python-checkins at python.org (paul.kippes) Date: Wed, 1 Apr 2009 21:02:12 +0200 (CEST) Subject: [Python-checkins] r70972 - in sandbox/trunk/refactor_pkg: 2to3 3to2 HACKING README TODO diff_from_r70785.diff example.py lib2to3 lib2to3/Grammar.txt lib2to3/PatternGrammar.txt lib2to3/__init__.py lib2to3/fixes lib2to3/fixes/__init__.py lib2to3/pgen2 lib2to3/pgen2/__init__.py lib2to3/tests lib2to3/tests/__init__.py lib2to3/tests/data lib2to3/tests/data/README lib2to3/tests/data/fixers lib2to3/tests/data/fixers/bad_order.py lib2to3/tests/data/fixers/myfixes lib2to3/tests/data/fixers/myfixes/__init__.py lib2to3/tests/data/fixers/myfixes/fix_explicit.py lib2to3/tests/data/fixers/myfixes/fix_first.py lib2to3/tests/data/fixers/myfixes/fix_last.py lib2to3/tests/data/fixers/myfixes/fix_parrot.py lib2to3/tests/data/fixers/myfixes/fix_preorder.py lib2to3/tests/data/fixers/no_fixer_cls.py lib2to3/tests/data/fixers/parrot_example.py lib2to3/tests/data/infinite_recursion.py lib2to3/tests/data/py2_test_grammar.py lib2to3/tests/data/py3_test_grammar.py lib2to3/tests/pytree_idempotency.py lib2to3/tests/support.py lib2to3/tests/test_all_fixers.py lib2to3/tests/test_fixers.py lib2to3/tests/test_parser.py lib2to3/tests/test_pytree.py lib2to3/tests/test_refactor.py lib2to3/tests/test_util.py refactor refactor/Grammar.txt refactor/PatternGrammar.txt refactor/__init__.py refactor/fixer_base.py refactor/fixer_util.py refactor/fixes refactor/fixes/__init__.py refactor/fixes/fixer_common.py refactor/fixes/from2 refactor/fixes/from2/__init__.py refactor/fixes/from2/fix_apply.py refactor/fixes/from2/fix_basestring.py refactor/fixes/from2/fix_buffer.py refactor/fixes/from2/fix_callable.py refactor/fixes/from2/fix_dict.py refactor/fixes/from2/fix_except.py refactor/fixes/from2/fix_exec.py refactor/fixes/from2/fix_execfile.py refactor/fixes/from2/fix_filter.py refactor/fixes/from2/fix_funcattrs.py refactor/fixes/from2/fix_future.py refactor/fixes/from2/fix_getcwdu.py refactor/fixes/from2/fix_has_key.py refactor/fixes/from2/fix_idioms.py refactor/fixes/from2/fix_import.py refactor/fixes/from2/fix_imports.py refactor/fixes/from2/fix_imports2.py refactor/fixes/from2/fix_input.py refactor/fixes/from2/fix_intern.py refactor/fixes/from2/fix_isinstance.py refactor/fixes/from2/fix_itertools.py refactor/fixes/from2/fix_itertools_imports.py refactor/fixes/from2/fix_long.py refactor/fixes/from2/fix_map.py refactor/fixes/from2/fix_metaclass.py refactor/fixes/from2/fix_methodattrs.py refactor/fixes/from2/fix_ne.py refactor/fixes/from2/fix_next.py refactor/fixes/from2/fix_nonzero.py refactor/fixes/from2/fix_numliterals.py refactor/fixes/from2/fix_paren.py refactor/fixes/from2/fix_print.py refactor/fixes/from2/fix_raise.py refactor/fixes/from2/fix_raw_input.py refactor/fixes/from2/fix_reduce.py refactor/fixes/from2/fix_renames.py refactor/fixes/from2/fix_repr.py refactor/fixes/from2/fix_set_literal.py refactor/fixes/from2/fix_standarderror.py refactor/fixes/from2/fix_sys_exc.py refactor/fixes/from2/fix_throw.py refactor/fixes/from2/fix_tuple_params.py refactor/fixes/from2/fix_types.py refactor/fixes/from2/fix_unicode.py refactor/fixes/from2/fix_urllib.py refactor/fixes/from2/fix_ws_comma.py re Message-ID: <20090401190212.7BEE31E4070@bag.python.org> Author: paul.kippes Date: Wed Apr 1 21:02:05 2009 New Revision: 70972 Log: Pycon 2009 sprint work containing 2to3 refactoring; based on r70785 of sandbox/2to3 work in progress... Added: sandbox/trunk/refactor_pkg/2to3 (contents, props changed) sandbox/trunk/refactor_pkg/3to2 (contents, props changed) sandbox/trunk/refactor_pkg/HACKING sandbox/trunk/refactor_pkg/README sandbox/trunk/refactor_pkg/TODO sandbox/trunk/refactor_pkg/diff_from_r70785.diff sandbox/trunk/refactor_pkg/example.py sandbox/trunk/refactor_pkg/lib2to3/ sandbox/trunk/refactor_pkg/lib2to3/Grammar.txt sandbox/trunk/refactor_pkg/lib2to3/PatternGrammar.txt sandbox/trunk/refactor_pkg/lib2to3/__init__.py sandbox/trunk/refactor_pkg/lib2to3/fixes/ sandbox/trunk/refactor_pkg/lib2to3/fixes/__init__.py sandbox/trunk/refactor_pkg/lib2to3/pgen2/ sandbox/trunk/refactor_pkg/lib2to3/pgen2/__init__.py sandbox/trunk/refactor_pkg/lib2to3/tests/ sandbox/trunk/refactor_pkg/lib2to3/tests/__init__.py sandbox/trunk/refactor_pkg/lib2to3/tests/data/ sandbox/trunk/refactor_pkg/lib2to3/tests/data/README sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/ sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/bad_order.py sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/myfixes/ sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/myfixes/__init__.py sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/myfixes/fix_explicit.py sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/myfixes/fix_first.py sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/myfixes/fix_last.py sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/myfixes/fix_parrot.py sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/myfixes/fix_preorder.py sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/no_fixer_cls.py sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/parrot_example.py sandbox/trunk/refactor_pkg/lib2to3/tests/data/infinite_recursion.py sandbox/trunk/refactor_pkg/lib2to3/tests/data/py2_test_grammar.py sandbox/trunk/refactor_pkg/lib2to3/tests/data/py3_test_grammar.py sandbox/trunk/refactor_pkg/lib2to3/tests/pytree_idempotency.py (contents, props changed) sandbox/trunk/refactor_pkg/lib2to3/tests/support.py sandbox/trunk/refactor_pkg/lib2to3/tests/test_all_fixers.py sandbox/trunk/refactor_pkg/lib2to3/tests/test_fixers.py (contents, props changed) sandbox/trunk/refactor_pkg/lib2to3/tests/test_parser.py sandbox/trunk/refactor_pkg/lib2to3/tests/test_pytree.py (contents, props changed) sandbox/trunk/refactor_pkg/lib2to3/tests/test_refactor.py sandbox/trunk/refactor_pkg/lib2to3/tests/test_util.py sandbox/trunk/refactor_pkg/refactor/ sandbox/trunk/refactor_pkg/refactor/Grammar.txt sandbox/trunk/refactor_pkg/refactor/PatternGrammar.txt sandbox/trunk/refactor_pkg/refactor/__init__.py sandbox/trunk/refactor_pkg/refactor/fixer_base.py sandbox/trunk/refactor_pkg/refactor/fixer_util.py sandbox/trunk/refactor_pkg/refactor/fixes/ sandbox/trunk/refactor_pkg/refactor/fixes/__init__.py sandbox/trunk/refactor_pkg/refactor/fixes/fixer_common.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/ sandbox/trunk/refactor_pkg/refactor/fixes/from2/__init__.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_apply.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_basestring.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_buffer.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_callable.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_dict.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_except.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_exec.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_execfile.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_filter.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_funcattrs.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_future.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_getcwdu.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_has_key.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_idioms.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_import.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_imports.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_imports2.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_input.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_intern.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_isinstance.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_itertools.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_itertools_imports.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_long.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_map.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_metaclass.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_methodattrs.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_ne.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_next.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_nonzero.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_numliterals.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_paren.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_print.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_raise.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_raw_input.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_reduce.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_renames.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_repr.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_set_literal.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_standarderror.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_sys_exc.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_throw.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_tuple_params.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_types.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_unicode.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_urllib.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_ws_comma.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_xrange.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_xreadlines.py sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_zip.py sandbox/trunk/refactor_pkg/refactor/fixes/from3/ sandbox/trunk/refactor_pkg/refactor/fixes/from3/__init__.py sandbox/trunk/refactor_pkg/refactor/fixes/from3/fix_range.py sandbox/trunk/refactor_pkg/refactor/fixes/from3/fix_renames.py sandbox/trunk/refactor_pkg/refactor/main.py sandbox/trunk/refactor_pkg/refactor/patcomp.py sandbox/trunk/refactor_pkg/refactor/pgen2/ sandbox/trunk/refactor_pkg/refactor/pgen2/__init__.py sandbox/trunk/refactor_pkg/refactor/pgen2/conv.py sandbox/trunk/refactor_pkg/refactor/pgen2/driver.py sandbox/trunk/refactor_pkg/refactor/pgen2/grammar.py sandbox/trunk/refactor_pkg/refactor/pgen2/literals.py sandbox/trunk/refactor_pkg/refactor/pgen2/parse.py sandbox/trunk/refactor_pkg/refactor/pgen2/pgen.py sandbox/trunk/refactor_pkg/refactor/pgen2/token.py (contents, props changed) sandbox/trunk/refactor_pkg/refactor/pgen2/tokenize.py sandbox/trunk/refactor_pkg/refactor/pygram.py sandbox/trunk/refactor_pkg/refactor/pytree.py sandbox/trunk/refactor_pkg/refactor/refactor.py (contents, props changed) sandbox/trunk/refactor_pkg/refactor/tests/ sandbox/trunk/refactor_pkg/refactor/tests/__init__.py sandbox/trunk/refactor_pkg/refactor/tests/data/ sandbox/trunk/refactor_pkg/refactor/tests/data/README sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/ sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/bad_order.py sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/myfixes/ sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/myfixes/__init__.py sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/myfixes/fix_explicit.py sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/myfixes/fix_first.py sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/myfixes/fix_last.py sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/myfixes/fix_parrot.py sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/myfixes/fix_preorder.py sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/no_fixer_cls.py sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/parrot_example.py sandbox/trunk/refactor_pkg/refactor/tests/data/infinite_recursion.py sandbox/trunk/refactor_pkg/refactor/tests/data/py2_test_grammar.py sandbox/trunk/refactor_pkg/refactor/tests/data/py3_test_grammar.py sandbox/trunk/refactor_pkg/refactor/tests/pytree_idempotency.py (contents, props changed) sandbox/trunk/refactor_pkg/refactor/tests/support.py sandbox/trunk/refactor_pkg/refactor/tests/test_all_fixers.py sandbox/trunk/refactor_pkg/refactor/tests/test_fixers.py (contents, props changed) sandbox/trunk/refactor_pkg/refactor/tests/test_parser.py sandbox/trunk/refactor_pkg/refactor/tests/test_pytree.py (contents, props changed) sandbox/trunk/refactor_pkg/refactor/tests/test_refactor.py sandbox/trunk/refactor_pkg/refactor/tests/test_util.py sandbox/trunk/refactor_pkg/scripts/ sandbox/trunk/refactor_pkg/scripts/benchmark.py sandbox/trunk/refactor_pkg/scripts/find_pattern.py (contents, props changed) sandbox/trunk/refactor_pkg/setup.py sandbox/trunk/refactor_pkg/test.py (contents, props changed) Added: sandbox/trunk/refactor_pkg/2to3 ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/2to3 Wed Apr 1 21:02:05 2009 @@ -0,0 +1,6 @@ +#!/usr/bin/env python +import lib2to3 +import sys +import os + +sys.exit(lib2to3.main.main("refactor.fixes.from2")) Added: sandbox/trunk/refactor_pkg/3to2 ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/3to2 Wed Apr 1 21:02:05 2009 @@ -0,0 +1,6 @@ +#!/usr/bin/env python +from refactor.main import main +import sys +import os + +sys.exit(main("refactor.fixes.from3")) Added: sandbox/trunk/refactor_pkg/HACKING ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/HACKING Wed Apr 1 21:02:05 2009 @@ -0,0 +1,74 @@ +Running tests: + + * 2to3 and 3to2 will fail with Python 2.5, but should work w/ Python trunk + $ python test.py --help + + * test lib2to3 + $ python test.py --base lib2to3 + + * test refactor + $ python test.py + + +Tips/tricks/hints for writing new fixers: + + * Don't write your own PATTERN from scratch; that's what + scripts/find_pattern.py is for. + + e.g. + ./scripts/find_pattern.py + + This will give choices of tokens to parse. + Press enter to skip, any key to see the grammar. + + $ ./scripts/find_pattern.py "print('hello, world')" + "('hello, world')" + + "print('hello, world')" + . + print_stmt< 'print' atom< '(' "'hello, world'" ')' > > + + * If your fixer works by changing a node's children list or a leaf's value, + be sure to call the node/leaf's changed() method. This to be sure the main + script will recognize that the tree has changed. + + +Putting 2to3 to work somewhere else: + + * By default, 2to3 uses a merger of Python 2.x and Python 3's grammars. If + you want to support a different grammar, just replace the Grammar.txt file + with Grammar/Grammar from your chosen Python version. + + * The real heart of 2to3 is the concrete syntax tree parser in pgen2; this + chunk of the system is suitable for a wide range of applications that + require CST transformation. All that's required is to rip off the fixer + layer and replace it with something else that walks the tree. One + application would be a tool to check/enforce style guidelines; this could + leverage 90% of the existing infrastructure with primarily cosmetic + changes (e.g., fixes/fix_*.py -> styles/style_*.py). + + +TODO + + Simple: + ####### + + * Refactor common code out of fixes/fix_*.py into fixer_util (on-going). + + * Document how to write fixers. + + + Complex: + ######## + + * Come up with a scheme to hide the details of suite indentation (some kind + of custom pytree node for suites, probably). This will automatically + reindent all code with spaces, tied into a refactor.py flag that allows + you to specify the indent level. + + * Remove the need to explicitly assign a node's parent attribute. This + could be gone with a magic children list. + + * Import statements are complicated and a pain to handle, and there are many + fixers that manipulate them. It would be nice to have a little API for + manipulating imports in fixers. Added: sandbox/trunk/refactor_pkg/README ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/README Wed Apr 1 21:02:05 2009 @@ -0,0 +1,260 @@ +Abstract +======== + +The refactor package -- 2to3 and back again -- is a fork of lib2to3. + +lib2to3: + +A refactoring tool for converting Python 2.x code to 3.0. + +This is a work in progress! Bugs should be reported to http://bugs.python.org/ +under the "2to3" category. + + +General usage +============= + +Run ``./2to3`` to convert stdin (``-``), files or directories given as +arguments. By default, the tool outputs a unified diff-formatted patch on +standard output and a "what was changed" summary on standard error, but the +``-w`` option can be given to write back converted files, creating +``.bak``-named backup files. + +2to3 must be run with at least Python 2.5. The intended path for migrating to +Python 3.x is to first migrate to 2.6 (in order to take advantage of Python +2.6's runtime compatibility checks). + + +Files +===== + +README - this file +lib2to3/refactor.py - main program; use this to convert files or directory trees +test.py - runs all unittests for 2to3 +lib2to3/patcomp.py - pattern compiler +lib2to3/pytree.py - parse tree nodes (not specific to Python, despite the name!) +lib2to3/pygram.py - code specific to the Python grammar +example.py - example input for play.py and fix_*.py +find_pattern.py - script to help determine the PATTERN for a new fix +lib2to3/Grammar.txt - Python grammar input (accepts 2.x and 3.x syntax) +lib2to3/Grammar.pickle - pickled grammar tables (generated file, not in subversion) +lib2to3/PatternGrammar.txt - grammar for the pattern language used by patcomp.py +lib2to3/PatternGrammar.pickle - pickled pattern grammar tables (generated file) +lib2to3/pgen2/ - Parser generator and driver ([1]_, [2]_) +lib2to3/fixes/ - Individual transformations +lib2to3tests/ - Test files for pytree, fixers, grammar, etc + + +Capabilities +============ + +A quick run-through of 2to3's current fixers: + +* **fix_apply** - convert apply() calls to real function calls. + +* **fix_callable** - converts callable(obj) into hasattr(obj, '__call__'). + +* **fix_dict** - fix up dict.keys(), .values(), .items() and their iterator + versions. + +* **fix_except** - adjust "except" statements to Python 3 syntax (PEP 3110). + +* **fix_exec** - convert "exec" statements to exec() function calls. + +* **fix_execfile** - execfile(filename, ...) -> exec(open(filename).read()) + +* **fix_filter** - changes filter(F, X) into list(filter(F, X)). + +* **fix_funcattrs** - fix function attribute names (f.func_x -> f.__x__). + +* **fix_has_key** - "d.has_key(x)" -> "x in d". + +* **fix_idioms** - convert type(x) == T to isinstance(x, T), "while 1:" to + "while True:", plus others. This fixer must be explicitly requested + with "-f idioms". + +* **fix_imports** - Fix (some) incompatible imports. + +* **fix_imports2** - Fix (some) incompatible imports that must run after + **test_imports**. + +* **fix_input** - "input()" -> "eval(input())" (PEP 3111). + +* **fix_intern** - "intern(x)" -> "sys.intern(x)". + +* **fix_long** - remove all usage of explicit longs in favor of ints. + +* **fix_map** - generally changes map(F, ...) into list(map(F, ...)). + +* **fix_ne** - convert the "<>" operator to "!=". + +* **fix_next** - fixer for it.next() -> next(it) (PEP 3114). + +* **fix_nonzero** - convert __nonzero__() methods to __bool__() methods. + +* **fix_numliterals** - tweak certain numeric literals to be 3.0-compliant. + +* **fix_paren** - Add parentheses to places where they are needed in list + comprehensions and generator expressions. + +* **fix_print** - convert "print" statements to print() function calls. + +* **fix_raise** - convert "raise" statements to Python 3 syntax (PEP 3109). + +* **fix_raw_input** - "raw_input()" -> "input()" (PEP 3111). + +* **fix_repr** - swap backticks for repr() calls. + +* **fix_standarderror** - StandardError -> Exception. + +* **fix_sys_exc** - Converts * **"sys.exc_info", "sys.exc_type", and + "sys.exc_value" to sys.exc_info() + +* **fix_throw** - fix generator.throw() calls to be 3.0-compliant (PEP 3109). + +* **fix_tuple_params** - remove tuple parameters from function, method and + lambda declarations (PEP 3113). + +* **fix_unicode** - convert, e.g., u"..." to "...", unicode(x) to str(x), etc. + +* **fix_urllib** - Fix imports for urllib and urllib2. + +* **fix_xrange** - "xrange()" -> "range()". + +* **fix_xreadlines** - "for x in f.xreadlines():" -> "for x in f:". Also, + "g(f.xreadlines)" -> "g(f.__iter__)". + +* **fix_metaclass** - move __metaclass__ = M to class X(metaclass=M) + + +Limitations +=========== + +General Limitations +------------------- + +* In general, fixers that convert a function or method call will not detect + something like :: + + a = apply + a(f, *args) + + or :: + + m = d.has_key + if m(5): + ... + +* Fixers that look for attribute references will not detect when getattr() or + setattr() is used to access those attributes. + +* The contents of eval() calls and "exec" statements will not be checked by + 2to3. + + +Caveats for Specific Fixers +--------------------------- + +fix_except +'''''''''' + +"except" statements like :: + + except Exception, (a, b): + ... + +are not fixed up. The ability to treat exceptions as sequences is being +removed in Python 3, so there is no straightforward, automatic way to +adjust these statements. + +This is seen frequently when dealing with OSError. + + +fix_filter +'''''''''' + +The transformation is not correct if the original code depended on +filter(F, X) returning a string if X is a string (or a tuple if X is a +tuple, etc). That would require type inference, which we don't do. Python +2.6's Python 3 compatibility mode should be used to detect such cases. + + +fix_has_key +''''''''''' + +While the primary target of this fixer is dict.has_key(), the +fixer will change any has_key() method call, regardless of what class it +belongs to. Anyone using non-dictionary classes with has_key() methods is +advised to pay close attention when using this fixer. + + +fix_map +''''''' + +The transformation is not correct if the original code was depending on +map(F, X, Y, ...) to go on until the longest argument is exhausted, +substituting None for missing values -- like zip(), it now stops as +soon as the shortest argument is exhausted. + + +fix_raise +''''''''' + +"raise E, V" will be incorrectly translated if V is an exception instance. +The correct Python 3 idiom is :: + + raise E from V + +but since we can't detect instance-hood by syntax alone and since any client +code would have to be changed as well, we don't automate this. + +Another translation problem is this: :: + + t = ((E, E2), E3) + raise t + +2to3 has no way of knowing that t is a tuple, and so this code will raise an +exception at runtime since the ability to raise tuples is going away. + + +Notes +===== + +.. [#1] I modified tokenize.py to yield a NL pseudo-token for backslash + continuations, so the original source can be reproduced exactly. The + modified version can be found at lib2to3/pgen2/tokenize.py. + +.. [#2] I developed pgen2 while I was at Elemental Security. I modified + it while at Google to suit the needs of this refactoring tool. + + +Development +=========== + +The HACKING file has a list of TODOs -- some simple, some complex -- that would +make good introductions for anyone new to 2to3. + + +Licensing +========= + +The original pgen2 module is copyrighted by Elemental Security. All +new code I wrote specifically for this tool is copyrighted by Google. +New code by others is copyrighted by the respective authors. All code +(whether by me or by others) is licensed to the PSF under a contributor +agreement. + +--Guido van Rossum + + +All code I wrote specifically for this tool before 9 April 2007 is +copyrighted by me. All new code I wrote specifically for this tool after +9 April 2007 is copyrighted by Google. Regardless, my contributions are +licensed to the PSF under a contributor agreement. + +--Collin Winter + +All of my contributions are copyrighted to me and licensed to PSF under the +Python contributor agreement. + +--Benjamin Peterson Added: sandbox/trunk/refactor_pkg/TODO ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/TODO Wed Apr 1 21:02:05 2009 @@ -0,0 +1,9 @@ +2.6: + byte lit. without b + unicode with u + from __future__ import print_statement + +2.5: + from __future__ import with + exceptions + print Added: sandbox/trunk/refactor_pkg/diff_from_r70785.diff ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/diff_from_r70785.diff Wed Apr 1 21:02:05 2009 @@ -0,0 +1,52557 @@ +diff -r 531f2e948299 .hgignore +--- a/.hgignore Mon Mar 30 20:02:09 2009 -0500 ++++ b/.hgignore Wed Apr 01 13:59:47 2009 -0500 +@@ -4,10 +4,11 @@ + # * hg add + # note that `hg add *` will add files even if they match in this file. + +-syntax: glob +-*.pickle ++# syntax: glob + + syntax: regexp ++\.out$ ++\.pickle$ + \.log$ + ~$ + ^bin/* +@@ -28,7 +29,7 @@ + ^\.# + (^|/)RCS($|/) + ,v$ +-(^|/)\.svn($|/) ++# (^|/)\.svn($|/) + (^|/)\.bzr($|/) + \_darcs$ + (^|/)SCCS($|/) +diff -r 531f2e948299 .svn/entries +--- a/.svn/entries Mon Mar 30 20:02:09 2009 -0500 ++++ b/.svn/entries Wed Apr 01 13:59:47 2009 -0500 +@@ -1,7 +1,7 @@ + 9 + + dir +-70785 ++70822 + http://svn.python.org/projects/sandbox/trunk/2to3 + http://svn.python.org/projects + +diff -r 531f2e948299 2to3 +--- a/2to3 Mon Mar 30 20:02:09 2009 -0500 ++++ b/2to3 Wed Apr 01 13:59:47 2009 -0500 +@@ -1,6 +1,6 @@ + #!/usr/bin/env python +-from lib2to3.main import main ++import lib2to3 + import sys + import os + +-sys.exit(main("lib2to3.fixes")) ++sys.exit(lib2to3.main.main("refactor.fixes.from2")) +diff -r 531f2e948299 3to2 +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/3to2 Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,6 @@ ++#!/usr/bin/env python ++from refactor.main import main ++import sys ++import os ++ ++sys.exit(main("refactor.fixes.from3")) +diff -r 531f2e948299 HACKING +--- a/HACKING Mon Mar 30 20:02:09 2009 -0500 ++++ b/HACKING Wed Apr 01 13:59:47 2009 -0500 +@@ -1,7 +1,32 @@ ++Running tests: ++ ++ * 2to3 and 3to2 will fail with Python 2.5, but should work w/ Python trunk ++ $ python test.py --help ++ ++ * test lib2to3 ++ $ python test.py --base lib2to3 ++ ++ * test refactor ++ $ python test.py ++ ++ + Tips/tricks/hints for writing new fixers: + + * Don't write your own PATTERN from scratch; that's what + scripts/find_pattern.py is for. ++ ++ e.g. ++ ./scripts/find_pattern.py ++ ++ This will give choices of tokens to parse. ++ Press enter to skip, any key to see the grammar. ++ ++ $ ./scripts/find_pattern.py "print('hello, world')" ++ "('hello, world')" ++ ++ "print('hello, world')" ++ . ++ print_stmt< 'print' atom< '(' "'hello, world'" ')' > > + + * If your fixer works by changing a node's children list or a leaf's value, + be sure to call the node/leaf's changed() method. This to be sure the main +diff -r 531f2e948299 README +--- a/README Mon Mar 30 20:02:09 2009 -0500 ++++ b/README Wed Apr 01 13:59:47 2009 -0500 +@@ -1,6 +1,10 @@ + Abstract + ======== + ++The refactor package -- 2to3 and back again -- is a fork of lib2to3. ++ ++lib2to3: ++ + A refactoring tool for converting Python 2.x code to 3.0. + + This is a work in progress! Bugs should be reported to http://bugs.python.org/ +diff -r 531f2e948299 TODO +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/TODO Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++2.6: ++ byte lit. without b ++ unicode with u ++ from __future__ import print_statement ++ ++2.5: ++ from __future__ import with ++ exceptions ++ print +diff -r 531f2e948299 lib2to3/.svn/entries +--- a/lib2to3/.svn/entries Mon Mar 30 20:02:09 2009 -0500 ++++ b/lib2to3/.svn/entries Wed Apr 01 13:59:47 2009 -0500 +@@ -1,7 +1,7 @@ + 9 + + dir +-70785 ++70822 + http://svn.python.org/projects/sandbox/trunk/2to3/lib2to3 + http://svn.python.org/projects + +diff -r 531f2e948299 lib2to3/Grammar2.7.0.alpha.0.pickle +Binary file lib2to3/Grammar2.7.0.alpha.0.pickle has changed +diff -r 531f2e948299 lib2to3/PatternGrammar2.7.0.alpha.0.pickle +Binary file lib2to3/PatternGrammar2.7.0.alpha.0.pickle has changed +diff -r 531f2e948299 lib2to3/__init__.py +--- a/lib2to3/__init__.py Mon Mar 30 20:02:09 2009 -0500 ++++ b/lib2to3/__init__.py Wed Apr 01 13:59:47 2009 -0500 +@@ -1,1 +1,1 @@ +-#empty ++from refactor import * +diff -r 531f2e948299 lib2to3/fixer_base.py +--- a/lib2to3/fixer_base.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,178 +0,0 @@ +-# Copyright 2006 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Base class for fixers (optional, but recommended).""" +- +-# Python imports +-import logging +-import itertools +- +-# Local imports +-from .patcomp import PatternCompiler +-from . import pygram +-from .fixer_util import does_tree_import +- +-class BaseFix(object): +- +- """Optional base class for fixers. +- +- The subclass name must be FixFooBar where FooBar is the result of +- removing underscores and capitalizing the words of the fix name. +- For example, the class name for a fixer named 'has_key' should be +- FixHasKey. +- """ +- +- PATTERN = None # Most subclasses should override with a string literal +- pattern = None # Compiled pattern, set by compile_pattern() +- options = None # Options object passed to initializer +- filename = None # The filename (set by set_filename) +- logger = None # A logger (set by set_filename) +- numbers = itertools.count(1) # For new_name() +- used_names = set() # A set of all used NAMEs +- order = "post" # Does the fixer prefer pre- or post-order traversal +- explicit = False # Is this ignored by refactor.py -f all? +- run_order = 5 # Fixers will be sorted by run order before execution +- # Lower numbers will be run first. +- +- # Shortcut for access to Python grammar symbols +- syms = pygram.python_symbols +- +- def __init__(self, options, log): +- """Initializer. Subclass may override. +- +- Args: +- options: an dict containing the options passed to RefactoringTool +- that could be used to customize the fixer through the command line. +- log: a list to append warnings and other messages to. +- """ +- self.options = options +- self.log = log +- self.compile_pattern() +- +- def compile_pattern(self): +- """Compiles self.PATTERN into self.pattern. +- +- Subclass may override if it doesn't want to use +- self.{pattern,PATTERN} in .match(). +- """ +- if self.PATTERN is not None: +- self.pattern = PatternCompiler().compile_pattern(self.PATTERN) +- +- def set_filename(self, filename): +- """Set the filename, and a logger derived from it. +- +- The main refactoring tool should call this. +- """ +- self.filename = filename +- self.logger = logging.getLogger(filename) +- +- def match(self, node): +- """Returns match for a given parse tree node. +- +- Should return a true or false object (not necessarily a bool). +- It may return a non-empty dict of matching sub-nodes as +- returned by a matching pattern. +- +- Subclass may override. +- """ +- results = {"node": node} +- return self.pattern.match(node, results) and results +- +- def transform(self, node, results): +- """Returns the transformation for a given parse tree node. +- +- Args: +- node: the root of the parse tree that matched the fixer. +- results: a dict mapping symbolic names to part of the match. +- +- Returns: +- None, or a node that is a modified copy of the +- argument node. The node argument may also be modified in-place to +- effect the same change. +- +- Subclass *must* override. +- """ +- raise NotImplementedError() +- +- def new_name(self, template="xxx_todo_changeme"): +- """Return a string suitable for use as an identifier +- +- The new name is guaranteed not to conflict with other identifiers. +- """ +- name = template +- while name in self.used_names: +- name = template + str(self.numbers.next()) +- self.used_names.add(name) +- return name +- +- def log_message(self, message): +- if self.first_log: +- self.first_log = False +- self.log.append("### In file %s ###" % self.filename) +- self.log.append(message) +- +- def cannot_convert(self, node, reason=None): +- """Warn the user that a given chunk of code is not valid Python 3, +- but that it cannot be converted automatically. +- +- First argument is the top-level node for the code in question. +- Optional second argument is why it can't be converted. +- """ +- lineno = node.get_lineno() +- for_output = node.clone() +- for_output.set_prefix("") +- msg = "Line %d: could not convert: %s" +- self.log_message(msg % (lineno, for_output)) +- if reason: +- self.log_message(reason) +- +- def warning(self, node, reason): +- """Used for warning the user about possible uncertainty in the +- translation. +- +- First argument is the top-level node for the code in question. +- Optional second argument is why it can't be converted. +- """ +- lineno = node.get_lineno() +- self.log_message("Line %d: %s" % (lineno, reason)) +- +- def start_tree(self, tree, filename): +- """Some fixers need to maintain tree-wide state. +- This method is called once, at the start of tree fix-up. +- +- tree - the root node of the tree to be processed. +- filename - the name of the file the tree came from. +- """ +- self.used_names = tree.used_names +- self.set_filename(filename) +- self.numbers = itertools.count(1) +- self.first_log = True +- +- def finish_tree(self, tree, filename): +- """Some fixers need to maintain tree-wide state. +- This method is called once, at the conclusion of tree fix-up. +- +- tree - the root node of the tree to be processed. +- filename - the name of the file the tree came from. +- """ +- pass +- +- +-class ConditionalFix(BaseFix): +- """ Base class for fixers which not execute if an import is found. """ +- +- # This is the name of the import which, if found, will cause the test to be skipped +- skip_on = None +- +- def start_tree(self, *args): +- super(ConditionalFix, self).start_tree(*args) +- self._should_skip = None +- +- def should_skip(self, node): +- if self._should_skip is not None: +- return self._should_skip +- pkg = self.skip_on.split(".") +- name = pkg[-1] +- pkg = ".".join(pkg[:-1]) +- self._should_skip = does_tree_import(pkg, name, node) +- return self._should_skip +diff -r 531f2e948299 lib2to3/fixer_util.py +--- a/lib2to3/fixer_util.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,425 +0,0 @@ +-"""Utility functions, node construction macros, etc.""" +-# Author: Collin Winter +- +-# Local imports +-from .pgen2 import token +-from .pytree import Leaf, Node +-from .pygram import python_symbols as syms +-from . import patcomp +- +- +-########################################################### +-### Common node-construction "macros" +-########################################################### +- +-def KeywordArg(keyword, value): +- return Node(syms.argument, +- [keyword, Leaf(token.EQUAL, '='), value]) +- +-def LParen(): +- return Leaf(token.LPAR, "(") +- +-def RParen(): +- return Leaf(token.RPAR, ")") +- +-def Assign(target, source): +- """Build an assignment statement""" +- if not isinstance(target, list): +- target = [target] +- if not isinstance(source, list): +- source.set_prefix(" ") +- source = [source] +- +- return Node(syms.atom, +- target + [Leaf(token.EQUAL, "=", prefix=" ")] + source) +- +-def Name(name, prefix=None): +- """Return a NAME leaf""" +- return Leaf(token.NAME, name, prefix=prefix) +- +-def Attr(obj, attr): +- """A node tuple for obj.attr""" +- return [obj, Node(syms.trailer, [Dot(), attr])] +- +-def Comma(): +- """A comma leaf""" +- return Leaf(token.COMMA, ",") +- +-def Dot(): +- """A period (.) leaf""" +- return Leaf(token.DOT, ".") +- +-def ArgList(args, lparen=LParen(), rparen=RParen()): +- """A parenthesised argument list, used by Call()""" +- node = Node(syms.trailer, [lparen.clone(), rparen.clone()]) +- if args: +- node.insert_child(1, Node(syms.arglist, args)) +- return node +- +-def Call(func_name, args=None, prefix=None): +- """A function call""" +- node = Node(syms.power, [func_name, ArgList(args)]) +- if prefix is not None: +- node.set_prefix(prefix) +- return node +- +-def Newline(): +- """A newline literal""" +- return Leaf(token.NEWLINE, "\n") +- +-def BlankLine(): +- """A blank line""" +- return Leaf(token.NEWLINE, "") +- +-def Number(n, prefix=None): +- return Leaf(token.NUMBER, n, prefix=prefix) +- +-def Subscript(index_node): +- """A numeric or string subscript""" +- return Node(syms.trailer, [Leaf(token.LBRACE, '['), +- index_node, +- Leaf(token.RBRACE, ']')]) +- +-def String(string, prefix=None): +- """A string leaf""" +- return Leaf(token.STRING, string, prefix=prefix) +- +-def ListComp(xp, fp, it, test=None): +- """A list comprehension of the form [xp for fp in it if test]. +- +- If test is None, the "if test" part is omitted. +- """ +- xp.set_prefix("") +- fp.set_prefix(" ") +- it.set_prefix(" ") +- for_leaf = Leaf(token.NAME, "for") +- for_leaf.set_prefix(" ") +- in_leaf = Leaf(token.NAME, "in") +- in_leaf.set_prefix(" ") +- inner_args = [for_leaf, fp, in_leaf, it] +- if test: +- test.set_prefix(" ") +- if_leaf = Leaf(token.NAME, "if") +- if_leaf.set_prefix(" ") +- inner_args.append(Node(syms.comp_if, [if_leaf, test])) +- inner = Node(syms.listmaker, [xp, Node(syms.comp_for, inner_args)]) +- return Node(syms.atom, +- [Leaf(token.LBRACE, "["), +- inner, +- Leaf(token.RBRACE, "]")]) +- +-def FromImport(package_name, name_leafs): +- """ Return an import statement in the form: +- from package import name_leafs""" +- # XXX: May not handle dotted imports properly (eg, package_name='foo.bar') +- #assert package_name == '.' or '.' not in package_name, "FromImport has "\ +- # "not been tested with dotted package names -- use at your own "\ +- # "peril!" +- +- for leaf in name_leafs: +- # Pull the leaves out of their old tree +- leaf.remove() +- +- children = [Leaf(token.NAME, 'from'), +- Leaf(token.NAME, package_name, prefix=" "), +- Leaf(token.NAME, 'import', prefix=" "), +- Node(syms.import_as_names, name_leafs)] +- imp = Node(syms.import_from, children) +- return imp +- +- +-########################################################### +-### Determine whether a node represents a given literal +-########################################################### +- +-def is_tuple(node): +- """Does the node represent a tuple literal?""" +- if isinstance(node, Node) and node.children == [LParen(), RParen()]: +- return True +- return (isinstance(node, Node) +- and len(node.children) == 3 +- and isinstance(node.children[0], Leaf) +- and isinstance(node.children[1], Node) +- and isinstance(node.children[2], Leaf) +- and node.children[0].value == "(" +- and node.children[2].value == ")") +- +-def is_list(node): +- """Does the node represent a list literal?""" +- return (isinstance(node, Node) +- and len(node.children) > 1 +- and isinstance(node.children[0], Leaf) +- and isinstance(node.children[-1], Leaf) +- and node.children[0].value == "[" +- and node.children[-1].value == "]") +- +- +-########################################################### +-### Misc +-########################################################### +- +-def parenthesize(node): +- return Node(syms.atom, [LParen(), node, RParen()]) +- +- +-consuming_calls = set(["sorted", "list", "set", "any", "all", "tuple", "sum", +- "min", "max"]) +- +-def attr_chain(obj, attr): +- """Follow an attribute chain. +- +- If you have a chain of objects where a.foo -> b, b.foo-> c, etc, +- use this to iterate over all objects in the chain. Iteration is +- terminated by getattr(x, attr) is None. +- +- Args: +- obj: the starting object +- attr: the name of the chaining attribute +- +- Yields: +- Each successive object in the chain. +- """ +- next = getattr(obj, attr) +- while next: +- yield next +- next = getattr(next, attr) +- +-p0 = """for_stmt< 'for' any 'in' node=any ':' any* > +- | comp_for< 'for' any 'in' node=any any* > +- """ +-p1 = """ +-power< +- ( 'iter' | 'list' | 'tuple' | 'sorted' | 'set' | 'sum' | +- 'any' | 'all' | (any* trailer< '.' 'join' >) ) +- trailer< '(' node=any ')' > +- any* +-> +-""" +-p2 = """ +-power< +- 'sorted' +- trailer< '(' arglist ')' > +- any* +-> +-""" +-pats_built = False +-def in_special_context(node): +- """ Returns true if node is in an environment where all that is required +- of it is being itterable (ie, it doesn't matter if it returns a list +- or an itterator). +- See test_map_nochange in test_fixers.py for some examples and tests. +- """ +- global p0, p1, p2, pats_built +- if not pats_built: +- p1 = patcomp.compile_pattern(p1) +- p0 = patcomp.compile_pattern(p0) +- p2 = patcomp.compile_pattern(p2) +- pats_built = True +- patterns = [p0, p1, p2] +- for pattern, parent in zip(patterns, attr_chain(node, "parent")): +- results = {} +- if pattern.match(parent, results) and results["node"] is node: +- return True +- return False +- +-def is_probably_builtin(node): +- """ +- Check that something isn't an attribute or function name etc. +- """ +- prev = node.prev_sibling +- if prev is not None and prev.type == token.DOT: +- # Attribute lookup. +- return False +- parent = node.parent +- if parent.type in (syms.funcdef, syms.classdef): +- return False +- if parent.type == syms.expr_stmt and parent.children[0] is node: +- # Assignment. +- return False +- if parent.type == syms.parameters or \ +- (parent.type == syms.typedargslist and ( +- (prev is not None and prev.type == token.COMMA) or +- parent.children[0] is node +- )): +- # The name of an argument. +- return False +- return True +- +-########################################################### +-### The following functions are to find bindings in a suite +-########################################################### +- +-def make_suite(node): +- if node.type == syms.suite: +- return node +- node = node.clone() +- parent, node.parent = node.parent, None +- suite = Node(syms.suite, [node]) +- suite.parent = parent +- return suite +- +-def find_root(node): +- """Find the top level namespace.""" +- # Scamper up to the top level namespace +- while node.type != syms.file_input: +- assert node.parent, "Tree is insane! root found before "\ +- "file_input node was found." +- node = node.parent +- return node +- +-def does_tree_import(package, name, node): +- """ Returns true if name is imported from package at the +- top level of the tree which node belongs to. +- To cover the case of an import like 'import foo', use +- None for the package and 'foo' for the name. """ +- binding = find_binding(name, find_root(node), package) +- return bool(binding) +- +-def is_import(node): +- """Returns true if the node is an import statement.""" +- return node.type in (syms.import_name, syms.import_from) +- +-def touch_import(package, name, node): +- """ Works like `does_tree_import` but adds an import statement +- if it was not imported. """ +- def is_import_stmt(node): +- return node.type == syms.simple_stmt and node.children and \ +- is_import(node.children[0]) +- +- root = find_root(node) +- +- if does_tree_import(package, name, root): +- return +- +- add_newline_before = False +- +- # figure out where to insert the new import. First try to find +- # the first import and then skip to the last one. +- insert_pos = offset = 0 +- for idx, node in enumerate(root.children): +- if not is_import_stmt(node): +- continue +- for offset, node2 in enumerate(root.children[idx:]): +- if not is_import_stmt(node2): +- break +- insert_pos = idx + offset +- break +- +- # if there are no imports where we can insert, find the docstring. +- # if that also fails, we stick to the beginning of the file +- if insert_pos == 0: +- for idx, node in enumerate(root.children): +- if node.type == syms.simple_stmt and node.children and \ +- node.children[0].type == token.STRING: +- insert_pos = idx + 1 +- add_newline_before +- break +- +- if package is None: +- import_ = Node(syms.import_name, [ +- Leaf(token.NAME, 'import'), +- Leaf(token.NAME, name, prefix=' ') +- ]) +- else: +- import_ = FromImport(package, [Leaf(token.NAME, name, prefix=' ')]) +- +- children = [import_, Newline()] +- if add_newline_before: +- children.insert(0, Newline()) +- root.insert_child(insert_pos, Node(syms.simple_stmt, children)) +- +- +-_def_syms = set([syms.classdef, syms.funcdef]) +-def find_binding(name, node, package=None): +- """ Returns the node which binds variable name, otherwise None. +- If optional argument package is supplied, only imports will +- be returned. +- See test cases for examples.""" +- for child in node.children: +- ret = None +- if child.type == syms.for_stmt: +- if _find(name, child.children[1]): +- return child +- n = find_binding(name, make_suite(child.children[-1]), package) +- if n: ret = n +- elif child.type in (syms.if_stmt, syms.while_stmt): +- n = find_binding(name, make_suite(child.children[-1]), package) +- if n: ret = n +- elif child.type == syms.try_stmt: +- n = find_binding(name, make_suite(child.children[2]), package) +- if n: +- ret = n +- else: +- for i, kid in enumerate(child.children[3:]): +- if kid.type == token.COLON and kid.value == ":": +- # i+3 is the colon, i+4 is the suite +- n = find_binding(name, make_suite(child.children[i+4]), package) +- if n: ret = n +- elif child.type in _def_syms and child.children[1].value == name: +- ret = child +- elif _is_import_binding(child, name, package): +- ret = child +- elif child.type == syms.simple_stmt: +- ret = find_binding(name, child, package) +- elif child.type == syms.expr_stmt: +- if _find(name, child.children[0]): +- ret = child +- +- if ret: +- if not package: +- return ret +- if is_import(ret): +- return ret +- return None +- +-_block_syms = set([syms.funcdef, syms.classdef, syms.trailer]) +-def _find(name, node): +- nodes = [node] +- while nodes: +- node = nodes.pop() +- if node.type > 256 and node.type not in _block_syms: +- nodes.extend(node.children) +- elif node.type == token.NAME and node.value == name: +- return node +- return None +- +-def _is_import_binding(node, name, package=None): +- """ Will reuturn node if node will import name, or node +- will import * from package. None is returned otherwise. +- See test cases for examples. """ +- +- if node.type == syms.import_name and not package: +- imp = node.children[1] +- if imp.type == syms.dotted_as_names: +- for child in imp.children: +- if child.type == syms.dotted_as_name: +- if child.children[2].value == name: +- return node +- elif child.type == token.NAME and child.value == name: +- return node +- elif imp.type == syms.dotted_as_name: +- last = imp.children[-1] +- if last.type == token.NAME and last.value == name: +- return node +- elif imp.type == token.NAME and imp.value == name: +- return node +- elif node.type == syms.import_from: +- # unicode(...) is used to make life easier here, because +- # from a.b import parses to ['import', ['a', '.', 'b'], ...] +- if package and unicode(node.children[1]).strip() != package: +- return None +- n = node.children[3] +- if package and _find('as', n): +- # See test_from_import_as for explanation +- return None +- elif n.type == syms.import_as_names and _find(name, n): +- return node +- elif n.type == syms.import_as_name: +- child = n.children[2] +- if child.type == token.NAME and child.value == name: +- return node +- elif n.type == token.NAME and n.value == name: +- return node +- elif package and n.type == token.STAR: +- return node +- return None +diff -r 531f2e948299 lib2to3/fixes/.svn/all-wcprops +--- a/lib2to3/fixes/.svn/all-wcprops Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,305 +0,0 @@ +-K 25 +-svn:wc:ra_dav:version-url +-V 57 +-/projects/!svn/ver/69679/sandbox/trunk/2to3/lib2to3/fixes +-END +-fix_dict.py +-K 25 +-svn:wc:ra_dav:version-url +-V 69 +-/projects/!svn/ver/67389/sandbox/trunk/2to3/lib2to3/fixes/fix_dict.py +-END +-fix_has_key.py +-K 25 +-svn:wc:ra_dav:version-url +-V 72 +-/projects/!svn/ver/67769/sandbox/trunk/2to3/lib2to3/fixes/fix_has_key.py +-END +-fix_exec.py +-K 25 +-svn:wc:ra_dav:version-url +-V 69 +-/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_exec.py +-END +-fix_idioms.py +-K 25 +-svn:wc:ra_dav:version-url +-V 71 +-/projects/!svn/ver/67433/sandbox/trunk/2to3/lib2to3/fixes/fix_idioms.py +-END +-__init__.py +-K 25 +-svn:wc:ra_dav:version-url +-V 69 +-/projects/!svn/ver/61428/sandbox/trunk/2to3/lib2to3/fixes/__init__.py +-END +-fix_urllib.py +-K 25 +-svn:wc:ra_dav:version-url +-V 71 +-/projects/!svn/ver/68368/sandbox/trunk/2to3/lib2to3/fixes/fix_urllib.py +-END +-fix_nonzero.py +-K 25 +-svn:wc:ra_dav:version-url +-V 72 +-/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_nonzero.py +-END +-fix_print.py +-K 25 +-svn:wc:ra_dav:version-url +-V 70 +-/projects/!svn/ver/66418/sandbox/trunk/2to3/lib2to3/fixes/fix_print.py +-END +-fix_imports.py +-K 25 +-svn:wc:ra_dav:version-url +-V 72 +-/projects/!svn/ver/69054/sandbox/trunk/2to3/lib2to3/fixes/fix_imports.py +-END +-fix_numliterals.py +-K 25 +-svn:wc:ra_dav:version-url +-V 76 +-/projects/!svn/ver/67389/sandbox/trunk/2to3/lib2to3/fixes/fix_numliterals.py +-END +-fix_input.py +-K 25 +-svn:wc:ra_dav:version-url +-V 70 +-/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_input.py +-END +-fix_itertools_imports.py +-K 25 +-svn:wc:ra_dav:version-url +-V 82 +-/projects/!svn/ver/69673/sandbox/trunk/2to3/lib2to3/fixes/fix_itertools_imports.py +-END +-fix_getcwdu.py +-K 25 +-svn:wc:ra_dav:version-url +-V 72 +-/projects/!svn/ver/66782/sandbox/trunk/2to3/lib2to3/fixes/fix_getcwdu.py +-END +-fix_zip.py +-K 25 +-svn:wc:ra_dav:version-url +-V 68 +-/projects/!svn/ver/67433/sandbox/trunk/2to3/lib2to3/fixes/fix_zip.py +-END +-fix_raise.py +-K 25 +-svn:wc:ra_dav:version-url +-V 70 +-/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_raise.py +-END +-fix_throw.py +-K 25 +-svn:wc:ra_dav:version-url +-V 70 +-/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_throw.py +-END +-fix_types.py +-K 25 +-svn:wc:ra_dav:version-url +-V 70 +-/projects/!svn/ver/67433/sandbox/trunk/2to3/lib2to3/fixes/fix_types.py +-END +-fix_paren.py +-K 25 +-svn:wc:ra_dav:version-url +-V 70 +-/projects/!svn/ver/65981/sandbox/trunk/2to3/lib2to3/fixes/fix_paren.py +-END +-fix_ws_comma.py +-K 25 +-svn:wc:ra_dav:version-url +-V 73 +-/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_ws_comma.py +-END +-fix_reduce.py +-K 25 +-svn:wc:ra_dav:version-url +-V 71 +-/projects/!svn/ver/67657/sandbox/trunk/2to3/lib2to3/fixes/fix_reduce.py +-END +-fix_raw_input.py +-K 25 +-svn:wc:ra_dav:version-url +-V 74 +-/projects/!svn/ver/65887/sandbox/trunk/2to3/lib2to3/fixes/fix_raw_input.py +-END +-fix_repr.py +-K 25 +-svn:wc:ra_dav:version-url +-V 69 +-/projects/!svn/ver/67769/sandbox/trunk/2to3/lib2to3/fixes/fix_repr.py +-END +-fix_buffer.py +-K 25 +-svn:wc:ra_dav:version-url +-V 71 +-/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_buffer.py +-END +-fix_funcattrs.py +-K 25 +-svn:wc:ra_dav:version-url +-V 74 +-/projects/!svn/ver/67433/sandbox/trunk/2to3/lib2to3/fixes/fix_funcattrs.py +-END +-fix_import.py +-K 25 +-svn:wc:ra_dav:version-url +-V 71 +-/projects/!svn/ver/67928/sandbox/trunk/2to3/lib2to3/fixes/fix_import.py +-END +-fix_standarderror.py +-K 25 +-svn:wc:ra_dav:version-url +-V 78 +-/projects/!svn/ver/67433/sandbox/trunk/2to3/lib2to3/fixes/fix_standarderror.py +-END +-fix_map.py +-K 25 +-svn:wc:ra_dav:version-url +-V 68 +-/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_map.py +-END +-fix_next.py +-K 25 +-svn:wc:ra_dav:version-url +-V 69 +-/projects/!svn/ver/67389/sandbox/trunk/2to3/lib2to3/fixes/fix_next.py +-END +-fix_itertools.py +-K 25 +-svn:wc:ra_dav:version-url +-V 74 +-/projects/!svn/ver/67433/sandbox/trunk/2to3/lib2to3/fixes/fix_itertools.py +-END +-fix_execfile.py +-K 25 +-svn:wc:ra_dav:version-url +-V 73 +-/projects/!svn/ver/67901/sandbox/trunk/2to3/lib2to3/fixes/fix_execfile.py +-END +-fix_xrange.py +-K 25 +-svn:wc:ra_dav:version-url +-V 71 +-/projects/!svn/ver/67705/sandbox/trunk/2to3/lib2to3/fixes/fix_xrange.py +-END +-fix_apply.py +-K 25 +-svn:wc:ra_dav:version-url +-V 70 +-/projects/!svn/ver/67769/sandbox/trunk/2to3/lib2to3/fixes/fix_apply.py +-END +-fix_filter.py +-K 25 +-svn:wc:ra_dav:version-url +-V 71 +-/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_filter.py +-END +-fix_unicode.py +-K 25 +-svn:wc:ra_dav:version-url +-V 72 +-/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_unicode.py +-END +-fix_except.py +-K 25 +-svn:wc:ra_dav:version-url +-V 71 +-/projects/!svn/ver/68694/sandbox/trunk/2to3/lib2to3/fixes/fix_except.py +-END +-fix_renames.py +-K 25 +-svn:wc:ra_dav:version-url +-V 72 +-/projects/!svn/ver/67389/sandbox/trunk/2to3/lib2to3/fixes/fix_renames.py +-END +-fix_tuple_params.py +-K 25 +-svn:wc:ra_dav:version-url +-V 77 +-/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_tuple_params.py +-END +-fix_methodattrs.py +-K 25 +-svn:wc:ra_dav:version-url +-V 76 +-/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_methodattrs.py +-END +-fix_xreadlines.py +-K 25 +-svn:wc:ra_dav:version-url +-V 75 +-/projects/!svn/ver/67433/sandbox/trunk/2to3/lib2to3/fixes/fix_xreadlines.py +-END +-fix_long.py +-K 25 +-svn:wc:ra_dav:version-url +-V 69 +-/projects/!svn/ver/68110/sandbox/trunk/2to3/lib2to3/fixes/fix_long.py +-END +-fix_intern.py +-K 25 +-svn:wc:ra_dav:version-url +-V 71 +-/projects/!svn/ver/67657/sandbox/trunk/2to3/lib2to3/fixes/fix_intern.py +-END +-fix_callable.py +-K 25 +-svn:wc:ra_dav:version-url +-V 73 +-/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_callable.py +-END +-fix_isinstance.py +-K 25 +-svn:wc:ra_dav:version-url +-V 75 +-/projects/!svn/ver/67767/sandbox/trunk/2to3/lib2to3/fixes/fix_isinstance.py +-END +-fix_basestring.py +-K 25 +-svn:wc:ra_dav:version-url +-V 75 +-/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_basestring.py +-END +-fix_ne.py +-K 25 +-svn:wc:ra_dav:version-url +-V 67 +-/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_ne.py +-END +-fix_set_literal.py +-K 25 +-svn:wc:ra_dav:version-url +-V 76 +-/projects/!svn/ver/69679/sandbox/trunk/2to3/lib2to3/fixes/fix_set_literal.py +-END +-fix_future.py +-K 25 +-svn:wc:ra_dav:version-url +-V 71 +-/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_future.py +-END +-fix_metaclass.py +-K 25 +-svn:wc:ra_dav:version-url +-V 74 +-/projects/!svn/ver/67371/sandbox/trunk/2to3/lib2to3/fixes/fix_metaclass.py +-END +-fix_sys_exc.py +-K 25 +-svn:wc:ra_dav:version-url +-V 72 +-/projects/!svn/ver/65968/sandbox/trunk/2to3/lib2to3/fixes/fix_sys_exc.py +-END +-fix_imports2.py +-K 25 +-svn:wc:ra_dav:version-url +-V 73 +-/projects/!svn/ver/68422/sandbox/trunk/2to3/lib2to3/fixes/fix_imports2.py +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/dir-prop-base +--- a/lib2to3/fixes/.svn/dir-prop-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,10 +0,0 @@ +-K 10 +-svn:ignore +-V 25 +-*.pyc +-*.pyo +-*.pickle +-@* +- +- +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/entries +--- a/lib2to3/fixes/.svn/entries Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,1728 +0,0 @@ +-9 +- +-dir +-70785 +-http://svn.python.org/projects/sandbox/trunk/2to3/lib2to3/fixes +-http://svn.python.org/projects +- +- +- +-2009-02-16T17:36:06.789054Z +-69679 +-benjamin.peterson +-has-props +- +-svn:special svn:externals svn:needs-lock +- +- +- +- +- +- +- +- +- +- +- +-6015fed2-1504-0410-9fe1-9d1591cc4771 +- +-fix_dict.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-d12677f15a5a34c7754e90cb06bc153e +-2008-11-25T23:13:17.968453Z +-67389 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-3588 +- +-fix_has_key.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-1b88e2b6b4c60df9b85a168a07e13fa7 +-2008-12-14T20:59:10.846867Z +-67769 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-3209 +- +-fix_exec.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-679db75847dfd56367a8cd2b4286949c +-2008-06-01T23:09:38.597843Z +-63880 +-collin.winter +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-985 +- +-fix_idioms.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-0281b19c721594c6eb341c83270d37bd +-2008-11-28T23:18:48.744865Z +-67433 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-3939 +- +-__init__.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-97781d2954bbc2eebdc963de519fe2de +-2006-12-12T14:56:29.604692Z +-53006 +-guido.van.rossum +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-47 +- +-fix_urllib.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-c883d34902a6e74c08f4370a978e5b86 +-2009-01-06T23:56:10.682943Z +-68368 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-7484 +- +-fix_nonzero.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-6f8983345b023d63ddce248a93c5db83 +-2008-06-01T23:09:38.597843Z +-63880 +-collin.winter +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-578 +- +-fix_print.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-478786e57412307d598aee1a20595102 +-2008-09-12T23:49:48.354778Z +-66418 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-2957 +- +-fix_imports.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-fa0f30cff73ee261c93c85286007c761 +-2009-01-28T16:01:54.183761Z +-69054 +-guilherme.polo +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-5692 +- +-fix_numliterals.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-7e04fa79f3ff3ff475ec1716021b8489 +-2008-11-25T23:13:17.968453Z +-67389 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-789 +- +-fix_input.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-3a704e4f30c9f72c236274118f093034 +-2008-06-01T23:09:38.597843Z +-63880 +-collin.winter +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-692 +- +-fix_itertools_imports.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-05420b3d189c8130eca6bf051bd31a17 +-2009-02-16T15:38:22.416590Z +-69673 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-1837 +- +-fix_getcwdu.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-1bf89e0a81cc997173d5d63078f8ea5a +-2008-10-03T22:51:36.115136Z +-66782 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-432 +- +-fix_zip.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-8e61d2105f3122181e793e7c9b4caf31 +-2008-11-28T23:18:48.744865Z +-67433 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-889 +- +-fix_throw.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-52c18fcf966a4c7f44940e331784f51c +-2008-06-01T23:09:38.597843Z +-63880 +-collin.winter +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-1564 +- +-fix_raise.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-7f69130d4008f2b870fbc5d88ed726de +-2008-06-01T23:09:38.597843Z +-63880 +-collin.winter +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-2587 +- +-fix_types.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-08728aeba77665139ce3f967cb24c2f1 +-2008-11-28T23:18:48.744865Z +-67433 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-1779 +- +-fix_paren.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-e2b3bd30551e285f3bc45eed6a797014 +-2008-08-22T20:41:30.636639Z +-65981 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-1213 +- +-fix_ws_comma.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-8e92e7f56434c9b2263874296578ea53 +-2008-06-01T23:09:38.597843Z +-63880 +-collin.winter +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-1108 +- +-fix_reduce.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-2fee5cc1f796c98a749dc789199da016 +-2008-12-08T00:29:35.627027Z +-67657 +-armin.ronacher +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-816 +- +-fix_raw_input.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-18666e7c36b850f0b6d5666504bec0ae +-2008-08-19T22:45:04.505207Z +-65887 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-435 +- +-fix_repr.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-badd6b1054395732bd64df829d16cf96 +-2008-12-14T20:59:10.846867Z +-67769 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-594 +- +-fix_buffer.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-d6f8cc141ad7ab3f197f1638b9e3e1aa +-2008-06-01T23:09:38.597843Z +-63880 +-collin.winter +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-566 +- +-fix_funcattrs.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-7a7b9d2abe6fbecfdf2e5c0095978f0b +-2008-11-28T23:18:48.744865Z +-67433 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-624 +- +-fix_import.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-9973617c9e868b2b9afb0a609ef30b35 +-2008-12-27T02:49:30.983707Z +-67928 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-2953 +- +-fix_standarderror.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-f76efc435650b1eba8bf73dbdfdeef3e +-2008-11-28T23:18:48.744865Z +-67433 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-431 +- +-fix_map.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-0cdf1b348ed0dc9348377ad6ce1aef42 +-2008-06-01T23:09:38.597843Z +-63880 +-collin.winter +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-2537 +- +-fix_next.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-46917a2b5128a18a5224f6ae5dc021db +-2008-11-25T23:13:17.968453Z +-67389 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-3205 +- +-fix_itertools.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-d2b48acbc9d415b64f3c71575fbfb9df +-2008-11-28T23:18:48.744865Z +-67433 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-1483 +- +-fix_execfile.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-f968686ed347fd544fc69fd9cb6073cd +-2008-12-22T20:09:55.444195Z +-67901 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-1974 +- +-fix_xrange.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-4f054eb9bb8f4d4916f1b33eec5175f9 +-2008-12-11T19:04:08.320821Z +-67705 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-2291 +- +-fix_apply.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-2a00b679f13c1dca9b45bc23a3b2a695 +-2008-12-14T20:59:10.846867Z +-67769 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-1894 +- +-fix_filter.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-0879d4b1af4eeb93b1a8baff1fd298c1 +-2008-06-01T23:09:38.597843Z +-63880 +-collin.winter +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-2089 +- +-fix_unicode.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-05e9e9ae6cbc1c396bc11b19b5dab25a +-2008-06-01T23:09:38.597843Z +-63880 +-collin.winter +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-832 +- +-fix_except.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-450c9cbb28a5be9d21719abcb33a59f5 +-2009-01-17T23:55:59.992428Z +-68694 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-3251 +- +-fix_renames.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-52f66737c4206d8cfa77bbb07af4a056 +-2008-11-25T23:13:17.968453Z +-67389 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-2192 +- +-fix_tuple_params.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-557690cc5399b0ade14c16089df2effb +-2008-06-01T23:09:38.597843Z +-63880 +-collin.winter +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-5405 +- +-fix_methodattrs.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-6ee0925ec01e9ae632326855ab5cb016 +-2008-06-01T23:09:38.597843Z +-63880 +-collin.winter +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-587 +- +-fix_xreadlines.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-ade2c0b61ba9f8effa9df543a2fbdc4a +-2008-11-28T23:18:48.744865Z +-67433 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-670 +- +-fix_long.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-2aaca612bae42bfe84dd0d6139260749 +-2008-12-31T20:13:26.408132Z +-68110 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-538 +- +-fix_intern.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-00e20c0723e807004c3fd0ae88d26b09 +-2008-12-08T00:29:35.627027Z +-67657 +-armin.ronacher +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-1368 +- +-fix_callable.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-37990663703ff5ea2fabb3095a9ad189 +-2008-06-01T23:09:38.597843Z +-63880 +-collin.winter +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-952 +- +-fix_isinstance.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-921a0f20d0a6e47b4b1291d37599bf09 +-2008-12-14T20:28:12.506842Z +-67767 +-benjamin.peterson +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-1594 +- +-fix_basestring.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-0fe11afa759b94c75323aa2a3188089d +-2008-06-01T23:09:38.597843Z +-63880 +-collin.winter +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-301 +- +-fix_ne.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-a787f8744fda47bffd7f2b6a9ee4ff38 +-2008-06-01T23:09:38.597843Z +-63880 +-collin.winter +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-590 +- +-fix_set_literal.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-fc4742a5a8d78f9dd84b1c5f0040003b +-2009-02-16T17:36:06.789054Z +-69679 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-1699 +- +-fix_future.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-0e2786c94aac6b11a47d8ec46d8b19d6 +-2008-06-01T23:09:38.597843Z +-63880 +-collin.winter +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-527 +- +-fix_metaclass.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-c608b0bf4a9c0c1028051ffe82d055f4 +-2008-11-24T22:02:00.590445Z +-67371 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-8213 +- +-fix_sys_exc.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-2b412acd29c54b0101163bb8be2ab5c7 +-2008-08-21T23:45:13.840810Z +-65968 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-1030 +- +-fix_imports2.py +-file +- +- +- +- +-2009-03-31T00:29:37.000000Z +-15274809df396bec14aeafccd2ab9875 +-2009-01-09T02:01:03.956074Z +-68422 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-289 +- +diff -r 531f2e948299 lib2to3/fixes/.svn/format +--- a/lib2to3/fixes/.svn/format Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,1 +0,0 @@ +-9 +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/__init__.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/__init__.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_apply.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_apply.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_basestring.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_basestring.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_buffer.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_buffer.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_callable.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_callable.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_dict.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_dict.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_except.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_except.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_exec.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_exec.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_execfile.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_execfile.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,5 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_filter.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_filter.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_funcattrs.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_funcattrs.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,5 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_future.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_future.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 13 +-'Id Revision' +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_getcwdu.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_getcwdu.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_has_key.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_has_key.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_idioms.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_idioms.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,5 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_import.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_import.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,5 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_imports.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_imports.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,5 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_imports2.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_imports2.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,5 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_input.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_input.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_intern.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_intern.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,5 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_itertools.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_itertools.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,5 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_itertools_imports.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_itertools_imports.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,5 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_long.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_long.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_map.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_map.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_metaclass.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_metaclass.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_methodattrs.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_methodattrs.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 13 +-'Id Revision' +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_ne.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_ne.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_next.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_next.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_nonzero.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_nonzero.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_numliterals.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_numliterals.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,5 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_paren.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_paren.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_print.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_print.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_raise.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_raise.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_raw_input.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_raw_input.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_renames.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_renames.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 13 +-'Id Revision' +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_repr.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_repr.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_set_literal.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_set_literal.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_standarderror.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_standarderror.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,5 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_sys_exc.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_sys_exc.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_throw.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_throw.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_tuple_params.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_tuple_params.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_types.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_types.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,5 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_unicode.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_unicode.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_urllib.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_urllib.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,5 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_ws_comma.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_ws_comma.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_xrange.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_xrange.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_xreadlines.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_xreadlines.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,5 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/prop-base/fix_zip.py.svn-base +--- a/lib2to3/fixes/.svn/prop-base/fix_zip.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,5 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-END +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/__init__.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/__init__.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,1 +0,0 @@ +-# Dummy file to make this directory a package. +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_apply.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_apply.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,58 +0,0 @@ +-# Copyright 2006 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for apply(). +- +-This converts apply(func, v, k) into (func)(*v, **k).""" +- +-# Local imports +-from .. import pytree +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Call, Comma, parenthesize +- +-class FixApply(fixer_base.BaseFix): +- +- PATTERN = """ +- power< 'apply' +- trailer< +- '(' +- arglist< +- (not argument +- ')' +- > +- > +- """ +- +- def transform(self, node, results): +- syms = self.syms +- assert results +- func = results["func"] +- args = results["args"] +- kwds = results.get("kwds") +- prefix = node.get_prefix() +- func = func.clone() +- if (func.type not in (token.NAME, syms.atom) and +- (func.type != syms.power or +- func.children[-2].type == token.DOUBLESTAR)): +- # Need to parenthesize +- func = parenthesize(func) +- func.set_prefix("") +- args = args.clone() +- args.set_prefix("") +- if kwds is not None: +- kwds = kwds.clone() +- kwds.set_prefix("") +- l_newargs = [pytree.Leaf(token.STAR, "*"), args] +- if kwds is not None: +- l_newargs.extend([Comma(), +- pytree.Leaf(token.DOUBLESTAR, "**"), +- kwds]) +- l_newargs[-2].set_prefix(" ") # that's the ** token +- # XXX Sometimes we could be cleverer, e.g. apply(f, (x, y) + t) +- # can be translated into f(x, y, *t) instead of f(*(x, y) + t) +- #new = pytree.Node(syms.power, (func, ArgList(l_newargs))) +- return Call(func, l_newargs, prefix=prefix) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_basestring.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_basestring.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,13 +0,0 @@ +-"""Fixer for basestring -> str.""" +-# Author: Christian Heimes +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name +- +-class FixBasestring(fixer_base.BaseFix): +- +- PATTERN = "'basestring'" +- +- def transform(self, node, results): +- return Name("str", prefix=node.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_buffer.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_buffer.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,21 +0,0 @@ +-# Copyright 2007 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer that changes buffer(...) into memoryview(...).""" +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name +- +- +-class FixBuffer(fixer_base.BaseFix): +- +- explicit = True # The user must ask for this fixer +- +- PATTERN = """ +- power< name='buffer' trailer< '(' [any] ')' > > +- """ +- +- def transform(self, node, results): +- name = results["name"] +- name.replace(Name("memoryview", prefix=name.get_prefix())) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_callable.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_callable.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,31 +0,0 @@ +-# Copyright 2007 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for callable(). +- +-This converts callable(obj) into hasattr(obj, '__call__').""" +- +-# Local imports +-from .. import pytree +-from .. import fixer_base +-from ..fixer_util import Call, Name, String +- +-class FixCallable(fixer_base.BaseFix): +- +- # Ignore callable(*args) or use of keywords. +- # Either could be a hint that the builtin callable() is not being used. +- PATTERN = """ +- power< 'callable' +- trailer< lpar='(' +- ( not(arglist | argument) any ','> ) +- rpar=')' > +- after=any* +- > +- """ +- +- def transform(self, node, results): +- func = results["func"] +- +- args = [func.clone(), String(', '), String("'__call__'")] +- return Call(Name("hasattr"), args, prefix=node.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_dict.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_dict.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,99 +0,0 @@ +-# Copyright 2007 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for dict methods. +- +-d.keys() -> list(d.keys()) +-d.items() -> list(d.items()) +-d.values() -> list(d.values()) +- +-d.iterkeys() -> iter(d.keys()) +-d.iteritems() -> iter(d.items()) +-d.itervalues() -> iter(d.values()) +- +-Except in certain very specific contexts: the iter() can be dropped +-when the context is list(), sorted(), iter() or for...in; the list() +-can be dropped when the context is list() or sorted() (but not iter() +-or for...in!). Special contexts that apply to both: list(), sorted(), tuple() +-set(), any(), all(), sum(). +- +-Note: iter(d.keys()) could be written as iter(d) but since the +-original d.iterkeys() was also redundant we don't fix this. And there +-are (rare) contexts where it makes a difference (e.g. when passing it +-as an argument to a function that introspects the argument). +-""" +- +-# Local imports +-from .. import pytree +-from .. import patcomp +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Name, Call, LParen, RParen, ArgList, Dot +-from .. import fixer_util +- +- +-iter_exempt = fixer_util.consuming_calls | set(["iter"]) +- +- +-class FixDict(fixer_base.BaseFix): +- PATTERN = """ +- power< head=any+ +- trailer< '.' method=('keys'|'items'|'values'| +- 'iterkeys'|'iteritems'|'itervalues') > +- parens=trailer< '(' ')' > +- tail=any* +- > +- """ +- +- def transform(self, node, results): +- head = results["head"] +- method = results["method"][0] # Extract node for method name +- tail = results["tail"] +- syms = self.syms +- method_name = method.value +- isiter = method_name.startswith("iter") +- if isiter: +- method_name = method_name[4:] +- assert method_name in ("keys", "items", "values"), repr(method) +- head = [n.clone() for n in head] +- tail = [n.clone() for n in tail] +- special = not tail and self.in_special_context(node, isiter) +- args = head + [pytree.Node(syms.trailer, +- [Dot(), +- Name(method_name, +- prefix=method.get_prefix())]), +- results["parens"].clone()] +- new = pytree.Node(syms.power, args) +- if not special: +- new.set_prefix("") +- new = Call(Name(isiter and "iter" or "list"), [new]) +- if tail: +- new = pytree.Node(syms.power, [new] + tail) +- new.set_prefix(node.get_prefix()) +- return new +- +- P1 = "power< func=NAME trailer< '(' node=any ')' > any* >" +- p1 = patcomp.compile_pattern(P1) +- +- P2 = """for_stmt< 'for' any 'in' node=any ':' any* > +- | comp_for< 'for' any 'in' node=any any* > +- """ +- p2 = patcomp.compile_pattern(P2) +- +- def in_special_context(self, node, isiter): +- if node.parent is None: +- return False +- results = {} +- if (node.parent.parent is not None and +- self.p1.match(node.parent.parent, results) and +- results["node"] is node): +- if isiter: +- # iter(d.iterkeys()) -> iter(d.keys()), etc. +- return results["func"].value in iter_exempt +- else: +- # list(d.keys()) -> list(d.keys()), etc. +- return results["func"].value in fixer_util.consuming_calls +- if not isiter: +- return False +- # for ... in d.iterkeys() -> for ... in d.keys(), etc. +- return self.p2.match(node.parent, results) and results["node"] is node +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_except.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_except.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,92 +0,0 @@ +-"""Fixer for except statements with named exceptions. +- +-The following cases will be converted: +- +-- "except E, T:" where T is a name: +- +- except E as T: +- +-- "except E, T:" where T is not a name, tuple or list: +- +- except E as t: +- T = t +- +- This is done because the target of an "except" clause must be a +- name. +- +-- "except E, T:" where T is a tuple or list literal: +- +- except E as t: +- T = t.args +-""" +-# Author: Collin Winter +- +-# Local imports +-from .. import pytree +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Assign, Attr, Name, is_tuple, is_list, syms +- +-def find_excepts(nodes): +- for i, n in enumerate(nodes): +- if n.type == syms.except_clause: +- if n.children[0].value == 'except': +- yield (n, nodes[i+2]) +- +-class FixExcept(fixer_base.BaseFix): +- +- PATTERN = """ +- try_stmt< 'try' ':' suite +- cleanup=(except_clause ':' suite)+ +- tail=(['except' ':' suite] +- ['else' ':' suite] +- ['finally' ':' suite]) > +- """ +- +- def transform(self, node, results): +- syms = self.syms +- +- tail = [n.clone() for n in results["tail"]] +- +- try_cleanup = [ch.clone() for ch in results["cleanup"]] +- for except_clause, e_suite in find_excepts(try_cleanup): +- if len(except_clause.children) == 4: +- (E, comma, N) = except_clause.children[1:4] +- comma.replace(Name("as", prefix=" ")) +- +- if N.type != token.NAME: +- # Generate a new N for the except clause +- new_N = Name(self.new_name(), prefix=" ") +- target = N.clone() +- target.set_prefix("") +- N.replace(new_N) +- new_N = new_N.clone() +- +- # Insert "old_N = new_N" as the first statement in +- # the except body. This loop skips leading whitespace +- # and indents +- #TODO(cwinter) suite-cleanup +- suite_stmts = e_suite.children +- for i, stmt in enumerate(suite_stmts): +- if isinstance(stmt, pytree.Node): +- break +- +- # The assignment is different if old_N is a tuple or list +- # In that case, the assignment is old_N = new_N.args +- if is_tuple(N) or is_list(N): +- assign = Assign(target, Attr(new_N, Name('args'))) +- else: +- assign = Assign(target, new_N) +- +- #TODO(cwinter) stopgap until children becomes a smart list +- for child in reversed(suite_stmts[:i]): +- e_suite.insert_child(0, child) +- e_suite.insert_child(i, assign) +- elif N.get_prefix() == "": +- # No space after a comma is legal; no space after "as", +- # not so much. +- N.set_prefix(" ") +- +- #TODO(cwinter) fix this when children becomes a smart list +- children = [c.clone() for c in node.children[:3]] + try_cleanup + tail +- return pytree.Node(node.type, children) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_exec.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_exec.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,39 +0,0 @@ +-# Copyright 2006 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for exec. +- +-This converts usages of the exec statement into calls to a built-in +-exec() function. +- +-exec code in ns1, ns2 -> exec(code, ns1, ns2) +-""" +- +-# Local imports +-from .. import pytree +-from .. import fixer_base +-from ..fixer_util import Comma, Name, Call +- +- +-class FixExec(fixer_base.BaseFix): +- +- PATTERN = """ +- exec_stmt< 'exec' a=any 'in' b=any [',' c=any] > +- | +- exec_stmt< 'exec' (not atom<'(' [any] ')'>) a=any > +- """ +- +- def transform(self, node, results): +- assert results +- syms = self.syms +- a = results["a"] +- b = results.get("b") +- c = results.get("c") +- args = [a.clone()] +- args[0].set_prefix("") +- if b is not None: +- args.extend([Comma(), b.clone()]) +- if c is not None: +- args.extend([Comma(), c.clone()]) +- +- return Call(Name("exec"), args, prefix=node.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_execfile.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_execfile.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,51 +0,0 @@ +-# Copyright 2006 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for execfile. +- +-This converts usages of the execfile function into calls to the built-in +-exec() function. +-""" +- +-from .. import fixer_base +-from ..fixer_util import (Comma, Name, Call, LParen, RParen, Dot, Node, +- ArgList, String, syms) +- +- +-class FixExecfile(fixer_base.BaseFix): +- +- PATTERN = """ +- power< 'execfile' trailer< '(' arglist< filename=any [',' globals=any [',' locals=any ] ] > ')' > > +- | +- power< 'execfile' trailer< '(' filename=any ')' > > +- """ +- +- def transform(self, node, results): +- assert results +- filename = results["filename"] +- globals = results.get("globals") +- locals = results.get("locals") +- +- # Copy over the prefix from the right parentheses end of the execfile +- # call. +- execfile_paren = node.children[-1].children[-1].clone() +- # Construct open().read(). +- open_args = ArgList([filename.clone()], rparen=execfile_paren) +- open_call = Node(syms.power, [Name("open"), open_args]) +- read = [Node(syms.trailer, [Dot(), Name('read')]), +- Node(syms.trailer, [LParen(), RParen()])] +- open_expr = [open_call] + read +- # Wrap the open call in a compile call. This is so the filename will be +- # preserved in the execed code. +- filename_arg = filename.clone() +- filename_arg.set_prefix(" ") +- exec_str = String("'exec'", " ") +- compile_args = open_expr + [Comma(), filename_arg, Comma(), exec_str] +- compile_call = Call(Name("compile"), compile_args, "") +- # Finally, replace the execfile call with an exec call. +- args = [compile_call] +- if globals is not None: +- args.extend([Comma(), globals.clone()]) +- if locals is not None: +- args.extend([Comma(), locals.clone()]) +- return Call(Name("exec"), args, prefix=node.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_filter.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_filter.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,75 +0,0 @@ +-# Copyright 2007 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer that changes filter(F, X) into list(filter(F, X)). +- +-We avoid the transformation if the filter() call is directly contained +-in iter(<>), list(<>), tuple(<>), sorted(<>), ...join(<>), or +-for V in <>:. +- +-NOTE: This is still not correct if the original code was depending on +-filter(F, X) to return a string if X is a string and a tuple if X is a +-tuple. That would require type inference, which we don't do. Let +-Python 2.6 figure it out. +-""" +- +-# Local imports +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Name, Call, ListComp, in_special_context +- +-class FixFilter(fixer_base.ConditionalFix): +- +- PATTERN = """ +- filter_lambda=power< +- 'filter' +- trailer< +- '(' +- arglist< +- lambdef< 'lambda' +- (fp=NAME | vfpdef< '(' fp=NAME ')'> ) ':' xp=any +- > +- ',' +- it=any +- > +- ')' +- > +- > +- | +- power< +- 'filter' +- trailer< '(' arglist< none='None' ',' seq=any > ')' > +- > +- | +- power< +- 'filter' +- args=trailer< '(' [any] ')' > +- > +- """ +- +- skip_on = "future_builtins.filter" +- +- def transform(self, node, results): +- if self.should_skip(node): +- return +- +- if "filter_lambda" in results: +- new = ListComp(results.get("fp").clone(), +- results.get("fp").clone(), +- results.get("it").clone(), +- results.get("xp").clone()) +- +- elif "none" in results: +- new = ListComp(Name("_f"), +- Name("_f"), +- results["seq"].clone(), +- Name("_f")) +- +- else: +- if in_special_context(node): +- return None +- new = node.clone() +- new.set_prefix("") +- new = Call(Name("list"), [new]) +- new.set_prefix(node.get_prefix()) +- return new +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_funcattrs.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_funcattrs.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,19 +0,0 @@ +-"""Fix function attribute names (f.func_x -> f.__x__).""" +-# Author: Collin Winter +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name +- +- +-class FixFuncattrs(fixer_base.BaseFix): +- PATTERN = """ +- power< any+ trailer< '.' attr=('func_closure' | 'func_doc' | 'func_globals' +- | 'func_name' | 'func_defaults' | 'func_code' +- | 'func_dict') > any* > +- """ +- +- def transform(self, node, results): +- attr = results["attr"][0] +- attr.replace(Name(("__%s__" % attr.value[5:]), +- prefix=attr.get_prefix())) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_future.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_future.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,20 +0,0 @@ +-"""Remove __future__ imports +- +-from __future__ import foo is replaced with an empty line. +-""" +-# Author: Christian Heimes +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import BlankLine +- +-class FixFuture(fixer_base.BaseFix): +- PATTERN = """import_from< 'from' module_name="__future__" 'import' any >""" +- +- # This should be run last -- some things check for the import +- run_order = 10 +- +- def transform(self, node, results): +- new = BlankLine() +- new.prefix = node.get_prefix() +- return new +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_getcwdu.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_getcwdu.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,18 +0,0 @@ +-""" +-Fixer that changes os.getcwdu() to os.getcwd(). +-""" +-# Author: Victor Stinner +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name +- +-class FixGetcwdu(fixer_base.BaseFix): +- +- PATTERN = """ +- power< 'os' trailer< dot='.' name='getcwdu' > any* > +- """ +- +- def transform(self, node, results): +- name = results["name"] +- name.replace(Name("getcwd", prefix=name.get_prefix())) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_has_key.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_has_key.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,109 +0,0 @@ +-# Copyright 2006 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for has_key(). +- +-Calls to .has_key() methods are expressed in terms of the 'in' +-operator: +- +- d.has_key(k) -> k in d +- +-CAVEATS: +-1) While the primary target of this fixer is dict.has_key(), the +- fixer will change any has_key() method call, regardless of its +- class. +- +-2) Cases like this will not be converted: +- +- m = d.has_key +- if m(k): +- ... +- +- Only *calls* to has_key() are converted. While it is possible to +- convert the above to something like +- +- m = d.__contains__ +- if m(k): +- ... +- +- this is currently not done. +-""" +- +-# Local imports +-from .. import pytree +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Name, parenthesize +- +- +-class FixHasKey(fixer_base.BaseFix): +- +- PATTERN = """ +- anchor=power< +- before=any+ +- trailer< '.' 'has_key' > +- trailer< +- '(' +- ( not(arglist | argument) arg=any ','> +- ) +- ')' +- > +- after=any* +- > +- | +- negation=not_test< +- 'not' +- anchor=power< +- before=any+ +- trailer< '.' 'has_key' > +- trailer< +- '(' +- ( not(arglist | argument) arg=any ','> +- ) +- ')' +- > +- > +- > +- """ +- +- def transform(self, node, results): +- assert results +- syms = self.syms +- if (node.parent.type == syms.not_test and +- self.pattern.match(node.parent)): +- # Don't transform a node matching the first alternative of the +- # pattern when its parent matches the second alternative +- return None +- negation = results.get("negation") +- anchor = results["anchor"] +- prefix = node.get_prefix() +- before = [n.clone() for n in results["before"]] +- arg = results["arg"].clone() +- after = results.get("after") +- if after: +- after = [n.clone() for n in after] +- if arg.type in (syms.comparison, syms.not_test, syms.and_test, +- syms.or_test, syms.test, syms.lambdef, syms.argument): +- arg = parenthesize(arg) +- if len(before) == 1: +- before = before[0] +- else: +- before = pytree.Node(syms.power, before) +- before.set_prefix(" ") +- n_op = Name("in", prefix=" ") +- if negation: +- n_not = Name("not", prefix=" ") +- n_op = pytree.Node(syms.comp_op, (n_not, n_op)) +- new = pytree.Node(syms.comparison, (arg, n_op, before)) +- if after: +- new = parenthesize(new) +- new = pytree.Node(syms.power, (new,) + tuple(after)) +- if node.parent.type in (syms.comparison, syms.expr, syms.xor_expr, +- syms.and_expr, syms.shift_expr, +- syms.arith_expr, syms.term, +- syms.factor, syms.power): +- new = parenthesize(new) +- new.set_prefix(prefix) +- return new +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_idioms.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_idioms.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,134 +0,0 @@ +-"""Adjust some old Python 2 idioms to their modern counterparts. +- +-* Change some type comparisons to isinstance() calls: +- type(x) == T -> isinstance(x, T) +- type(x) is T -> isinstance(x, T) +- type(x) != T -> not isinstance(x, T) +- type(x) is not T -> not isinstance(x, T) +- +-* Change "while 1:" into "while True:". +- +-* Change both +- +- v = list(EXPR) +- v.sort() +- foo(v) +- +-and the more general +- +- v = EXPR +- v.sort() +- foo(v) +- +-into +- +- v = sorted(EXPR) +- foo(v) +-""" +-# Author: Jacques Frechet, Collin Winter +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Call, Comma, Name, Node, syms +- +-CMP = "(n='!=' | '==' | 'is' | n=comp_op< 'is' 'not' >)" +-TYPE = "power< 'type' trailer< '(' x=any ')' > >" +- +-class FixIdioms(fixer_base.BaseFix): +- +- explicit = True # The user must ask for this fixer +- +- PATTERN = r""" +- isinstance=comparison< %s %s T=any > +- | +- isinstance=comparison< T=any %s %s > +- | +- while_stmt< 'while' while='1' ':' any+ > +- | +- sorted=any< +- any* +- simple_stmt< +- expr_stmt< id1=any '=' +- power< list='list' trailer< '(' (not arglist) any ')' > > +- > +- '\n' +- > +- sort= +- simple_stmt< +- power< id2=any +- trailer< '.' 'sort' > trailer< '(' ')' > +- > +- '\n' +- > +- next=any* +- > +- | +- sorted=any< +- any* +- simple_stmt< expr_stmt< id1=any '=' expr=any > '\n' > +- sort= +- simple_stmt< +- power< id2=any +- trailer< '.' 'sort' > trailer< '(' ')' > +- > +- '\n' +- > +- next=any* +- > +- """ % (TYPE, CMP, CMP, TYPE) +- +- def match(self, node): +- r = super(FixIdioms, self).match(node) +- # If we've matched one of the sort/sorted subpatterns above, we +- # want to reject matches where the initial assignment and the +- # subsequent .sort() call involve different identifiers. +- if r and "sorted" in r: +- if r["id1"] == r["id2"]: +- return r +- return None +- return r +- +- def transform(self, node, results): +- if "isinstance" in results: +- return self.transform_isinstance(node, results) +- elif "while" in results: +- return self.transform_while(node, results) +- elif "sorted" in results: +- return self.transform_sort(node, results) +- else: +- raise RuntimeError("Invalid match") +- +- def transform_isinstance(self, node, results): +- x = results["x"].clone() # The thing inside of type() +- T = results["T"].clone() # The type being compared against +- x.set_prefix("") +- T.set_prefix(" ") +- test = Call(Name("isinstance"), [x, Comma(), T]) +- if "n" in results: +- test.set_prefix(" ") +- test = Node(syms.not_test, [Name("not"), test]) +- test.set_prefix(node.get_prefix()) +- return test +- +- def transform_while(self, node, results): +- one = results["while"] +- one.replace(Name("True", prefix=one.get_prefix())) +- +- def transform_sort(self, node, results): +- sort_stmt = results["sort"] +- next_stmt = results["next"] +- list_call = results.get("list") +- simple_expr = results.get("expr") +- +- if list_call: +- list_call.replace(Name("sorted", prefix=list_call.get_prefix())) +- elif simple_expr: +- new = simple_expr.clone() +- new.set_prefix("") +- simple_expr.replace(Call(Name("sorted"), [new], +- prefix=simple_expr.get_prefix())) +- else: +- raise RuntimeError("should not have reached here") +- sort_stmt.remove() +- if next_stmt: +- next_stmt[0].set_prefix(sort_stmt.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_import.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_import.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,90 +0,0 @@ +-"""Fixer for import statements. +-If spam is being imported from the local directory, this import: +- from spam import eggs +-Becomes: +- from .spam import eggs +- +-And this import: +- import spam +-Becomes: +- from . import spam +-""" +- +-# Local imports +-from .. import fixer_base +-from os.path import dirname, join, exists, pathsep +-from ..fixer_util import FromImport, syms, token +- +- +-def traverse_imports(names): +- """ +- Walks over all the names imported in a dotted_as_names node. +- """ +- pending = [names] +- while pending: +- node = pending.pop() +- if node.type == token.NAME: +- yield node.value +- elif node.type == syms.dotted_name: +- yield "".join([ch.value for ch in node.children]) +- elif node.type == syms.dotted_as_name: +- pending.append(node.children[0]) +- elif node.type == syms.dotted_as_names: +- pending.extend(node.children[::-2]) +- else: +- raise AssertionError("unkown node type") +- +- +-class FixImport(fixer_base.BaseFix): +- +- PATTERN = """ +- import_from< 'from' imp=any 'import' ['('] any [')'] > +- | +- import_name< 'import' imp=any > +- """ +- +- def transform(self, node, results): +- imp = results['imp'] +- +- if node.type == syms.import_from: +- # Some imps are top-level (eg: 'import ham') +- # some are first level (eg: 'import ham.eggs') +- # some are third level (eg: 'import ham.eggs as spam') +- # Hence, the loop +- while not hasattr(imp, 'value'): +- imp = imp.children[0] +- if self.probably_a_local_import(imp.value): +- imp.value = "." + imp.value +- imp.changed() +- return node +- else: +- have_local = False +- have_absolute = False +- for mod_name in traverse_imports(imp): +- if self.probably_a_local_import(mod_name): +- have_local = True +- else: +- have_absolute = True +- if have_absolute: +- if have_local: +- # We won't handle both sibling and absolute imports in the +- # same statement at the moment. +- self.warning(node, "absolute and local imports together") +- return +- +- new = FromImport('.', [imp]) +- new.set_prefix(node.get_prefix()) +- return new +- +- def probably_a_local_import(self, imp_name): +- imp_name = imp_name.split('.', 1)[0] +- base_path = dirname(self.filename) +- base_path = join(base_path, imp_name) +- # If there is no __init__.py next to the file its not in a package +- # so can't be a relative import. +- if not exists(join(dirname(base_path), '__init__.py')): +- return False +- for ext in ['.py', pathsep, '.pyc', '.so', '.sl', '.pyd']: +- if exists(base_path + ext): +- return True +- return False +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_imports.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_imports.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,145 +0,0 @@ +-"""Fix incompatible imports and module references.""" +-# Authors: Collin Winter, Nick Edds +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name, attr_chain +- +-MAPPING = {'StringIO': 'io', +- 'cStringIO': 'io', +- 'cPickle': 'pickle', +- '__builtin__' : 'builtins', +- 'copy_reg': 'copyreg', +- 'Queue': 'queue', +- 'SocketServer': 'socketserver', +- 'ConfigParser': 'configparser', +- 'repr': 'reprlib', +- 'FileDialog': 'tkinter.filedialog', +- 'tkFileDialog': 'tkinter.filedialog', +- 'SimpleDialog': 'tkinter.simpledialog', +- 'tkSimpleDialog': 'tkinter.simpledialog', +- 'tkColorChooser': 'tkinter.colorchooser', +- 'tkCommonDialog': 'tkinter.commondialog', +- 'Dialog': 'tkinter.dialog', +- 'Tkdnd': 'tkinter.dnd', +- 'tkFont': 'tkinter.font', +- 'tkMessageBox': 'tkinter.messagebox', +- 'ScrolledText': 'tkinter.scrolledtext', +- 'Tkconstants': 'tkinter.constants', +- 'Tix': 'tkinter.tix', +- 'ttk': 'tkinter.ttk', +- 'Tkinter': 'tkinter', +- 'markupbase': '_markupbase', +- '_winreg': 'winreg', +- 'thread': '_thread', +- 'dummy_thread': '_dummy_thread', +- # anydbm and whichdb are handled by fix_imports2 +- 'dbhash': 'dbm.bsd', +- 'dumbdbm': 'dbm.dumb', +- 'dbm': 'dbm.ndbm', +- 'gdbm': 'dbm.gnu', +- 'xmlrpclib': 'xmlrpc.client', +- 'DocXMLRPCServer': 'xmlrpc.server', +- 'SimpleXMLRPCServer': 'xmlrpc.server', +- 'httplib': 'http.client', +- 'htmlentitydefs' : 'html.entities', +- 'HTMLParser' : 'html.parser', +- 'Cookie': 'http.cookies', +- 'cookielib': 'http.cookiejar', +- 'BaseHTTPServer': 'http.server', +- 'SimpleHTTPServer': 'http.server', +- 'CGIHTTPServer': 'http.server', +- #'test.test_support': 'test.support', +- 'commands': 'subprocess', +- 'UserString' : 'collections', +- 'UserList' : 'collections', +- 'urlparse' : 'urllib.parse', +- 'robotparser' : 'urllib.robotparser', +-} +- +- +-def alternates(members): +- return "(" + "|".join(map(repr, members)) + ")" +- +- +-def build_pattern(mapping=MAPPING): +- mod_list = ' | '.join(["module_name='%s'" % key for key in mapping]) +- bare_names = alternates(mapping.keys()) +- +- yield """name_import=import_name< 'import' ((%s) | +- multiple_imports=dotted_as_names< any* (%s) any* >) > +- """ % (mod_list, mod_list) +- yield """import_from< 'from' (%s) 'import' ['('] +- ( any | import_as_name< any 'as' any > | +- import_as_names< any* >) [')'] > +- """ % mod_list +- yield """import_name< 'import' (dotted_as_name< (%s) 'as' any > | +- multiple_imports=dotted_as_names< +- any* dotted_as_name< (%s) 'as' any > any* >) > +- """ % (mod_list, mod_list) +- +- # Find usages of module members in code e.g. thread.foo(bar) +- yield "power< bare_with_attr=(%s) trailer<'.' any > any* >" % bare_names +- +- +-class FixImports(fixer_base.BaseFix): +- +- order = "pre" # Pre-order tree traversal +- +- # This is overridden in fix_imports2. +- mapping = MAPPING +- +- # We want to run this fixer late, so fix_import doesn't try to make stdlib +- # renames into relative imports. +- run_order = 6 +- +- def build_pattern(self): +- return "|".join(build_pattern(self.mapping)) +- +- def compile_pattern(self): +- # We override this, so MAPPING can be pragmatically altered and the +- # changes will be reflected in PATTERN. +- self.PATTERN = self.build_pattern() +- super(FixImports, self).compile_pattern() +- +- # Don't match the node if it's within another match. +- def match(self, node): +- match = super(FixImports, self).match +- results = match(node) +- if results: +- # Module usage could be in the trailer of an attribute lookup, so we +- # might have nested matches when "bare_with_attr" is present. +- if "bare_with_attr" not in results and \ +- any([match(obj) for obj in attr_chain(node, "parent")]): +- return False +- return results +- return False +- +- def start_tree(self, tree, filename): +- super(FixImports, self).start_tree(tree, filename) +- self.replace = {} +- +- def transform(self, node, results): +- import_mod = results.get("module_name") +- if import_mod: +- mod_name = import_mod.value +- new_name = self.mapping[mod_name] +- import_mod.replace(Name(new_name, prefix=import_mod.get_prefix())) +- if "name_import" in results: +- # If it's not a "from x import x, y" or "import x as y" import, +- # marked its usage to be replaced. +- self.replace[mod_name] = new_name +- if "multiple_imports" in results: +- # This is a nasty hack to fix multiple imports on a line (e.g., +- # "import StringIO, urlparse"). The problem is that I can't +- # figure out an easy way to make a pattern recognize the keys of +- # MAPPING randomly sprinkled in an import statement. +- results = self.match(node) +- if results: +- self.transform(node, results) +- else: +- # Replace usage of the module. +- bare_name = results["bare_with_attr"][0] +- new_name = self.replace.get(bare_name.value) +- if new_name: +- bare_name.replace(Name(new_name, prefix=bare_name.get_prefix())) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_imports2.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_imports2.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,16 +0,0 @@ +-"""Fix incompatible imports and module references that must be fixed after +-fix_imports.""" +-from . import fix_imports +- +- +-MAPPING = { +- 'whichdb': 'dbm', +- 'anydbm': 'dbm', +- } +- +- +-class FixImports2(fix_imports.FixImports): +- +- run_order = 7 +- +- mapping = MAPPING +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_input.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_input.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,26 +0,0 @@ +-"""Fixer that changes input(...) into eval(input(...)).""" +-# Author: Andre Roberge +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Call, Name +-from .. import patcomp +- +- +-context = patcomp.compile_pattern("power< 'eval' trailer< '(' any ')' > >") +- +- +-class FixInput(fixer_base.BaseFix): +- +- PATTERN = """ +- power< 'input' args=trailer< '(' [any] ')' > > +- """ +- +- def transform(self, node, results): +- # If we're already wrapped in a eval() call, we're done. +- if context.match(node.parent.parent): +- return +- +- new = node.clone() +- new.set_prefix("") +- return Call(Name("eval"), [new], prefix=node.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_intern.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_intern.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,44 +0,0 @@ +-# Copyright 2006 Georg Brandl. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for intern(). +- +-intern(s) -> sys.intern(s)""" +- +-# Local imports +-from .. import pytree +-from .. import fixer_base +-from ..fixer_util import Name, Attr, touch_import +- +- +-class FixIntern(fixer_base.BaseFix): +- +- PATTERN = """ +- power< 'intern' +- trailer< lpar='(' +- ( not(arglist | argument) any ','> ) +- rpar=')' > +- after=any* +- > +- """ +- +- def transform(self, node, results): +- syms = self.syms +- obj = results["obj"].clone() +- if obj.type == syms.arglist: +- newarglist = obj.clone() +- else: +- newarglist = pytree.Node(syms.arglist, [obj.clone()]) +- after = results["after"] +- if after: +- after = [n.clone() for n in after] +- new = pytree.Node(syms.power, +- Attr(Name("sys"), Name("intern")) + +- [pytree.Node(syms.trailer, +- [results["lpar"].clone(), +- newarglist, +- results["rpar"].clone()])] + after) +- new.set_prefix(node.get_prefix()) +- touch_import(None, 'sys', node) +- return new +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_isinstance.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_isinstance.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,52 +0,0 @@ +-# Copyright 2008 Armin Ronacher. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer that cleans up a tuple argument to isinstance after the tokens +-in it were fixed. This is mainly used to remove double occurrences of +-tokens as a leftover of the long -> int / unicode -> str conversion. +- +-eg. isinstance(x, (int, long)) -> isinstance(x, (int, int)) +- -> isinstance(x, int) +-""" +- +-from .. import fixer_base +-from ..fixer_util import token +- +- +-class FixIsinstance(fixer_base.BaseFix): +- +- PATTERN = """ +- power< +- 'isinstance' +- trailer< '(' arglist< any ',' atom< '(' +- args=testlist_gexp< any+ > +- ')' > > ')' > +- > +- """ +- +- run_order = 6 +- +- def transform(self, node, results): +- names_inserted = set() +- testlist = results["args"] +- args = testlist.children +- new_args = [] +- iterator = enumerate(args) +- for idx, arg in iterator: +- if arg.type == token.NAME and arg.value in names_inserted: +- if idx < len(args) - 1 and args[idx + 1].type == token.COMMA: +- iterator.next() +- continue +- else: +- new_args.append(arg) +- if arg.type == token.NAME: +- names_inserted.add(arg.value) +- if new_args and new_args[-1].type == token.COMMA: +- del new_args[-1] +- if len(new_args) == 1: +- atom = testlist.parent +- new_args[0].set_prefix(atom.get_prefix()) +- atom.replace(new_args[0]) +- else: +- args[:] = new_args +- node.changed() +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_itertools.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_itertools.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,41 +0,0 @@ +-""" Fixer for itertools.(imap|ifilter|izip) --> (map|filter|zip) and +- itertools.ifilterfalse --> itertools.filterfalse (bugs 2360-2363) +- +- imports from itertools are fixed in fix_itertools_import.py +- +- If itertools is imported as something else (ie: import itertools as it; +- it.izip(spam, eggs)) method calls will not get fixed. +- """ +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name +- +-class FixItertools(fixer_base.BaseFix): +- it_funcs = "('imap'|'ifilter'|'izip'|'ifilterfalse')" +- PATTERN = """ +- power< it='itertools' +- trailer< +- dot='.' func=%(it_funcs)s > trailer< '(' [any] ')' > > +- | +- power< func=%(it_funcs)s trailer< '(' [any] ')' > > +- """ %(locals()) +- +- # Needs to be run after fix_(map|zip|filter) +- run_order = 6 +- +- def transform(self, node, results): +- prefix = None +- func = results['func'][0] +- if 'it' in results and func.value != 'ifilterfalse': +- dot, it = (results['dot'], results['it']) +- # Remove the 'itertools' +- prefix = it.get_prefix() +- it.remove() +- # Replace the node wich contains ('.', 'function') with the +- # function (to be consistant with the second part of the pattern) +- dot.remove() +- func.parent.replace(func) +- +- prefix = prefix or func.get_prefix() +- func.replace(Name(func.value[1:], prefix=prefix)) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_itertools_imports.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_itertools_imports.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,52 +0,0 @@ +-""" Fixer for imports of itertools.(imap|ifilter|izip|ifilterfalse) """ +- +-# Local imports +-from lib2to3 import fixer_base +-from lib2to3.fixer_util import BlankLine, syms, token +- +- +-class FixItertoolsImports(fixer_base.BaseFix): +- PATTERN = """ +- import_from< 'from' 'itertools' 'import' imports=any > +- """ %(locals()) +- +- def transform(self, node, results): +- imports = results['imports'] +- if imports.type == syms.import_as_name or not imports.children: +- children = [imports] +- else: +- children = imports.children +- for child in children[::2]: +- if child.type == token.NAME: +- member = child.value +- name_node = child +- else: +- assert child.type == syms.import_as_name +- name_node = child.children[0] +- member_name = name_node.value +- if member_name in ('imap', 'izip', 'ifilter'): +- child.value = None +- child.remove() +- elif member_name == 'ifilterfalse': +- node.changed() +- name_node.value = 'filterfalse' +- +- # Make sure the import statement is still sane +- children = imports.children[:] or [imports] +- remove_comma = True +- for child in children: +- if remove_comma and child.type == token.COMMA: +- child.remove() +- else: +- remove_comma ^= True +- +- if children[-1].type == token.COMMA: +- children[-1].remove() +- +- # If there are no imports left, just get rid of the entire statement +- if not (imports.children or getattr(imports, 'value', None)) or \ +- imports.parent is None: +- p = node.get_prefix() +- node = BlankLine() +- node.prefix = p +- return node +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_long.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_long.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,22 +0,0 @@ +-# Copyright 2006 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer that turns 'long' into 'int' everywhere. +-""" +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name, Number, is_probably_builtin +- +- +-class FixLong(fixer_base.BaseFix): +- +- PATTERN = "'long'" +- +- static_int = Name("int") +- +- def transform(self, node, results): +- if is_probably_builtin(node): +- new = self.static_int.clone() +- new.set_prefix(node.get_prefix()) +- return new +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_map.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_map.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,82 +0,0 @@ +-# Copyright 2007 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer that changes map(F, ...) into list(map(F, ...)) unless there +-exists a 'from future_builtins import map' statement in the top-level +-namespace. +- +-As a special case, map(None, X) is changed into list(X). (This is +-necessary because the semantics are changed in this case -- the new +-map(None, X) is equivalent to [(x,) for x in X].) +- +-We avoid the transformation (except for the special case mentioned +-above) if the map() call is directly contained in iter(<>), list(<>), +-tuple(<>), sorted(<>), ...join(<>), or for V in <>:. +- +-NOTE: This is still not correct if the original code was depending on +-map(F, X, Y, ...) to go on until the longest argument is exhausted, +-substituting None for missing values -- like zip(), it now stops as +-soon as the shortest argument is exhausted. +-""" +- +-# Local imports +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Name, Call, ListComp, in_special_context +-from ..pygram import python_symbols as syms +- +-class FixMap(fixer_base.ConditionalFix): +- +- PATTERN = """ +- map_none=power< +- 'map' +- trailer< '(' arglist< 'None' ',' arg=any [','] > ')' > +- > +- | +- map_lambda=power< +- 'map' +- trailer< +- '(' +- arglist< +- lambdef< 'lambda' +- (fp=NAME | vfpdef< '(' fp=NAME ')'> ) ':' xp=any +- > +- ',' +- it=any +- > +- ')' +- > +- > +- | +- power< +- 'map' +- args=trailer< '(' [any] ')' > +- > +- """ +- +- skip_on = 'future_builtins.map' +- +- def transform(self, node, results): +- if self.should_skip(node): +- return +- +- if node.parent.type == syms.simple_stmt: +- self.warning(node, "You should use a for loop here") +- new = node.clone() +- new.set_prefix("") +- new = Call(Name("list"), [new]) +- elif "map_lambda" in results: +- new = ListComp(results.get("xp").clone(), +- results.get("fp").clone(), +- results.get("it").clone()) +- else: +- if "map_none" in results: +- new = results["arg"].clone() +- else: +- if in_special_context(node): +- return None +- new = node.clone() +- new.set_prefix("") +- new = Call(Name("list"), [new]) +- new.set_prefix(node.get_prefix()) +- return new +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_metaclass.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_metaclass.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,227 +0,0 @@ +-"""Fixer for __metaclass__ = X -> (metaclass=X) methods. +- +- The various forms of classef (inherits nothing, inherits once, inherints +- many) don't parse the same in the CST so we look at ALL classes for +- a __metaclass__ and if we find one normalize the inherits to all be +- an arglist. +- +- For one-liner classes ('class X: pass') there is no indent/dedent so +- we normalize those into having a suite. +- +- Moving the __metaclass__ into the classdef can also cause the class +- body to be empty so there is some special casing for that as well. +- +- This fixer also tries very hard to keep original indenting and spacing +- in all those corner cases. +- +-""" +-# Author: Jack Diederich +- +-# Local imports +-from .. import fixer_base +-from ..pygram import token +-from ..fixer_util import Name, syms, Node, Leaf +- +- +-def has_metaclass(parent): +- """ we have to check the cls_node without changing it. +- There are two possiblities: +- 1) clsdef => suite => simple_stmt => expr_stmt => Leaf('__meta') +- 2) clsdef => simple_stmt => expr_stmt => Leaf('__meta') +- """ +- for node in parent.children: +- if node.type == syms.suite: +- return has_metaclass(node) +- elif node.type == syms.simple_stmt and node.children: +- expr_node = node.children[0] +- if expr_node.type == syms.expr_stmt and expr_node.children: +- left_side = expr_node.children[0] +- if isinstance(left_side, Leaf) and \ +- left_side.value == '__metaclass__': +- return True +- return False +- +- +-def fixup_parse_tree(cls_node): +- """ one-line classes don't get a suite in the parse tree so we add +- one to normalize the tree +- """ +- for node in cls_node.children: +- if node.type == syms.suite: +- # already in the prefered format, do nothing +- return +- +- # !%@#! oneliners have no suite node, we have to fake one up +- for i, node in enumerate(cls_node.children): +- if node.type == token.COLON: +- break +- else: +- raise ValueError("No class suite and no ':'!") +- +- # move everything into a suite node +- suite = Node(syms.suite, []) +- while cls_node.children[i+1:]: +- move_node = cls_node.children[i+1] +- suite.append_child(move_node.clone()) +- move_node.remove() +- cls_node.append_child(suite) +- node = suite +- +- +-def fixup_simple_stmt(parent, i, stmt_node): +- """ if there is a semi-colon all the parts count as part of the same +- simple_stmt. We just want the __metaclass__ part so we move +- everything efter the semi-colon into its own simple_stmt node +- """ +- for semi_ind, node in enumerate(stmt_node.children): +- if node.type == token.SEMI: # *sigh* +- break +- else: +- return +- +- node.remove() # kill the semicolon +- new_expr = Node(syms.expr_stmt, []) +- new_stmt = Node(syms.simple_stmt, [new_expr]) +- while stmt_node.children[semi_ind:]: +- move_node = stmt_node.children[semi_ind] +- new_expr.append_child(move_node.clone()) +- move_node.remove() +- parent.insert_child(i, new_stmt) +- new_leaf1 = new_stmt.children[0].children[0] +- old_leaf1 = stmt_node.children[0].children[0] +- new_leaf1.set_prefix(old_leaf1.get_prefix()) +- +- +-def remove_trailing_newline(node): +- if node.children and node.children[-1].type == token.NEWLINE: +- node.children[-1].remove() +- +- +-def find_metas(cls_node): +- # find the suite node (Mmm, sweet nodes) +- for node in cls_node.children: +- if node.type == syms.suite: +- break +- else: +- raise ValueError("No class suite!") +- +- # look for simple_stmt[ expr_stmt[ Leaf('__metaclass__') ] ] +- for i, simple_node in list(enumerate(node.children)): +- if simple_node.type == syms.simple_stmt and simple_node.children: +- expr_node = simple_node.children[0] +- if expr_node.type == syms.expr_stmt and expr_node.children: +- # Check if the expr_node is a simple assignment. +- left_node = expr_node.children[0] +- if isinstance(left_node, Leaf) and \ +- left_node.value == '__metaclass__': +- # We found a assignment to __metaclass__. +- fixup_simple_stmt(node, i, simple_node) +- remove_trailing_newline(simple_node) +- yield (node, i, simple_node) +- +- +-def fixup_indent(suite): +- """ If an INDENT is followed by a thing with a prefix then nuke the prefix +- Otherwise we get in trouble when removing __metaclass__ at suite start +- """ +- kids = suite.children[::-1] +- # find the first indent +- while kids: +- node = kids.pop() +- if node.type == token.INDENT: +- break +- +- # find the first Leaf +- while kids: +- node = kids.pop() +- if isinstance(node, Leaf) and node.type != token.DEDENT: +- if node.prefix: +- node.set_prefix('') +- return +- else: +- kids.extend(node.children[::-1]) +- +- +-class FixMetaclass(fixer_base.BaseFix): +- +- PATTERN = """ +- classdef +- """ +- +- def transform(self, node, results): +- if not has_metaclass(node): +- return node +- +- fixup_parse_tree(node) +- +- # find metaclasses, keep the last one +- last_metaclass = None +- for suite, i, stmt in find_metas(node): +- last_metaclass = stmt +- stmt.remove() +- +- text_type = node.children[0].type # always Leaf(nnn, 'class') +- +- # figure out what kind of classdef we have +- if len(node.children) == 7: +- # Node(classdef, ['class', 'name', '(', arglist, ')', ':', suite]) +- # 0 1 2 3 4 5 6 +- if node.children[3].type == syms.arglist: +- arglist = node.children[3] +- # Node(classdef, ['class', 'name', '(', 'Parent', ')', ':', suite]) +- else: +- parent = node.children[3].clone() +- arglist = Node(syms.arglist, [parent]) +- node.set_child(3, arglist) +- elif len(node.children) == 6: +- # Node(classdef, ['class', 'name', '(', ')', ':', suite]) +- # 0 1 2 3 4 5 +- arglist = Node(syms.arglist, []) +- node.insert_child(3, arglist) +- elif len(node.children) == 4: +- # Node(classdef, ['class', 'name', ':', suite]) +- # 0 1 2 3 +- arglist = Node(syms.arglist, []) +- node.insert_child(2, Leaf(token.RPAR, ')')) +- node.insert_child(2, arglist) +- node.insert_child(2, Leaf(token.LPAR, '(')) +- else: +- raise ValueError("Unexpected class definition") +- +- # now stick the metaclass in the arglist +- meta_txt = last_metaclass.children[0].children[0] +- meta_txt.value = 'metaclass' +- orig_meta_prefix = meta_txt.get_prefix() +- +- if arglist.children: +- arglist.append_child(Leaf(token.COMMA, ',')) +- meta_txt.set_prefix(' ') +- else: +- meta_txt.set_prefix('') +- +- # compact the expression "metaclass = Meta" -> "metaclass=Meta" +- expr_stmt = last_metaclass.children[0] +- assert expr_stmt.type == syms.expr_stmt +- expr_stmt.children[1].set_prefix('') +- expr_stmt.children[2].set_prefix('') +- +- arglist.append_child(last_metaclass) +- +- fixup_indent(suite) +- +- # check for empty suite +- if not suite.children: +- # one-liner that was just __metaclass_ +- suite.remove() +- pass_leaf = Leaf(text_type, 'pass') +- pass_leaf.set_prefix(orig_meta_prefix) +- node.append_child(pass_leaf) +- node.append_child(Leaf(token.NEWLINE, '\n')) +- +- elif len(suite.children) > 1 and \ +- (suite.children[-2].type == token.INDENT and +- suite.children[-1].type == token.DEDENT): +- # there was only one line in the class body and it was __metaclass__ +- pass_leaf = Leaf(text_type, 'pass') +- suite.insert_child(-1, pass_leaf) +- suite.insert_child(-1, Leaf(token.NEWLINE, '\n')) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_methodattrs.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_methodattrs.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,23 +0,0 @@ +-"""Fix bound method attributes (method.im_? -> method.__?__). +-""" +-# Author: Christian Heimes +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name +- +-MAP = { +- "im_func" : "__func__", +- "im_self" : "__self__", +- "im_class" : "__self__.__class__" +- } +- +-class FixMethodattrs(fixer_base.BaseFix): +- PATTERN = """ +- power< any+ trailer< '.' attr=('im_func' | 'im_self' | 'im_class') > any* > +- """ +- +- def transform(self, node, results): +- attr = results["attr"][0] +- new = MAP[attr.value] +- attr.replace(Name(new, prefix=attr.get_prefix())) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_ne.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_ne.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,22 +0,0 @@ +-# Copyright 2006 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer that turns <> into !=.""" +- +-# Local imports +-from .. import pytree +-from ..pgen2 import token +-from .. import fixer_base +- +- +-class FixNe(fixer_base.BaseFix): +- # This is so simple that we don't need the pattern compiler. +- +- def match(self, node): +- # Override +- return node.type == token.NOTEQUAL and node.value == "<>" +- +- def transform(self, node, results): +- new = pytree.Leaf(token.NOTEQUAL, "!=") +- new.set_prefix(node.get_prefix()) +- return new +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_next.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_next.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,103 +0,0 @@ +-"""Fixer for it.next() -> next(it), per PEP 3114.""" +-# Author: Collin Winter +- +-# Things that currently aren't covered: +-# - listcomp "next" names aren't warned +-# - "with" statement targets aren't checked +- +-# Local imports +-from ..pgen2 import token +-from ..pygram import python_symbols as syms +-from .. import fixer_base +-from ..fixer_util import Name, Call, find_binding +- +-bind_warning = "Calls to builtin next() possibly shadowed by global binding" +- +- +-class FixNext(fixer_base.BaseFix): +- PATTERN = """ +- power< base=any+ trailer< '.' attr='next' > trailer< '(' ')' > > +- | +- power< head=any+ trailer< '.' attr='next' > not trailer< '(' ')' > > +- | +- classdef< 'class' any+ ':' +- suite< any* +- funcdef< 'def' +- name='next' +- parameters< '(' NAME ')' > any+ > +- any* > > +- | +- global=global_stmt< 'global' any* 'next' any* > +- """ +- +- order = "pre" # Pre-order tree traversal +- +- def start_tree(self, tree, filename): +- super(FixNext, self).start_tree(tree, filename) +- +- n = find_binding('next', tree) +- if n: +- self.warning(n, bind_warning) +- self.shadowed_next = True +- else: +- self.shadowed_next = False +- +- def transform(self, node, results): +- assert results +- +- base = results.get("base") +- attr = results.get("attr") +- name = results.get("name") +- mod = results.get("mod") +- +- if base: +- if self.shadowed_next: +- attr.replace(Name("__next__", prefix=attr.get_prefix())) +- else: +- base = [n.clone() for n in base] +- base[0].set_prefix("") +- node.replace(Call(Name("next", prefix=node.get_prefix()), base)) +- elif name: +- n = Name("__next__", prefix=name.get_prefix()) +- name.replace(n) +- elif attr: +- # We don't do this transformation if we're assigning to "x.next". +- # Unfortunately, it doesn't seem possible to do this in PATTERN, +- # so it's being done here. +- if is_assign_target(node): +- head = results["head"] +- if "".join([str(n) for n in head]).strip() == '__builtin__': +- self.warning(node, bind_warning) +- return +- attr.replace(Name("__next__")) +- elif "global" in results: +- self.warning(node, bind_warning) +- self.shadowed_next = True +- +- +-### The following functions help test if node is part of an assignment +-### target. +- +-def is_assign_target(node): +- assign = find_assign(node) +- if assign is None: +- return False +- +- for child in assign.children: +- if child.type == token.EQUAL: +- return False +- elif is_subtree(child, node): +- return True +- return False +- +-def find_assign(node): +- if node.type == syms.expr_stmt: +- return node +- if node.type == syms.simple_stmt or node.parent is None: +- return None +- return find_assign(node.parent) +- +-def is_subtree(root, node): +- if root == node: +- return True +- return any([is_subtree(c, node) for c in root.children]) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_nonzero.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_nonzero.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,20 +0,0 @@ +-"""Fixer for __nonzero__ -> __bool__ methods.""" +-# Author: Collin Winter +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name, syms +- +-class FixNonzero(fixer_base.BaseFix): +- PATTERN = """ +- classdef< 'class' any+ ':' +- suite< any* +- funcdef< 'def' name='__nonzero__' +- parameters< '(' NAME ')' > any+ > +- any* > > +- """ +- +- def transform(self, node, results): +- name = results["name"] +- new = Name("__bool__", prefix=name.get_prefix()) +- name.replace(new) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_numliterals.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_numliterals.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,27 +0,0 @@ +-"""Fixer that turns 1L into 1, 0755 into 0o755. +-""" +-# Copyright 2007 Georg Brandl. +-# Licensed to PSF under a Contributor Agreement. +- +-# Local imports +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Number +- +- +-class FixNumliterals(fixer_base.BaseFix): +- # This is so simple that we don't need the pattern compiler. +- +- def match(self, node): +- # Override +- return (node.type == token.NUMBER and +- (node.value.startswith("0") or node.value[-1] in "Ll")) +- +- def transform(self, node, results): +- val = node.value +- if val[-1] in 'Ll': +- val = val[:-1] +- elif val.startswith('0') and val.isdigit() and len(set(val)) > 1: +- val = "0o" + val[1:] +- +- return Number(val, prefix=node.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_paren.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_paren.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,42 +0,0 @@ +-"""Fixer that addes parentheses where they are required +- +-This converts ``[x for x in 1, 2]`` to ``[x for x in (1, 2)]``.""" +- +-# By Taek Joo Kim and Benjamin Peterson +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import LParen, RParen +- +-# XXX This doesn't support nested for loops like [x for x in 1, 2 for x in 1, 2] +-class FixParen(fixer_base.BaseFix): +- PATTERN = """ +- atom< ('[' | '(') +- (listmaker< any +- comp_for< +- 'for' NAME 'in' +- target=testlist_safe< any (',' any)+ [','] +- > +- [any] +- > +- > +- | +- testlist_gexp< any +- comp_for< +- 'for' NAME 'in' +- target=testlist_safe< any (',' any)+ [','] +- > +- [any] +- > +- >) +- (']' | ')') > +- """ +- +- def transform(self, node, results): +- target = results["target"] +- +- lparen = LParen() +- lparen.set_prefix(target.get_prefix()) +- target.set_prefix("") # Make it hug the parentheses +- target.insert_child(0, lparen) +- target.append_child(RParen()) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_print.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_print.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,90 +0,0 @@ +-# Copyright 2006 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for print. +- +-Change: +- 'print' into 'print()' +- 'print ...' into 'print(...)' +- 'print ... ,' into 'print(..., end=" ")' +- 'print >>x, ...' into 'print(..., file=x)' +- +-No changes are applied if print_function is imported from __future__ +- +-""" +- +-# Local imports +-from .. import patcomp +-from .. import pytree +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Name, Call, Comma, String, is_tuple +- +- +-parend_expr = patcomp.compile_pattern( +- """atom< '(' [atom|STRING|NAME] ')' >""" +- ) +- +- +-class FixPrint(fixer_base.ConditionalFix): +- +- PATTERN = """ +- simple_stmt< any* bare='print' any* > | print_stmt +- """ +- +- skip_on = '__future__.print_function' +- +- def transform(self, node, results): +- assert results +- +- if self.should_skip(node): +- return +- +- bare_print = results.get("bare") +- +- if bare_print: +- # Special-case print all by itself +- bare_print.replace(Call(Name("print"), [], +- prefix=bare_print.get_prefix())) +- return +- assert node.children[0] == Name("print") +- args = node.children[1:] +- if len(args) == 1 and parend_expr.match(args[0]): +- # We don't want to keep sticking parens around an +- # already-parenthesised expression. +- return +- +- sep = end = file = None +- if args and args[-1] == Comma(): +- args = args[:-1] +- end = " " +- if args and args[0] == pytree.Leaf(token.RIGHTSHIFT, ">>"): +- assert len(args) >= 2 +- file = args[1].clone() +- args = args[3:] # Strip a possible comma after the file expression +- # Now synthesize a print(args, sep=..., end=..., file=...) node. +- l_args = [arg.clone() for arg in args] +- if l_args: +- l_args[0].set_prefix("") +- if sep is not None or end is not None or file is not None: +- if sep is not None: +- self.add_kwarg(l_args, "sep", String(repr(sep))) +- if end is not None: +- self.add_kwarg(l_args, "end", String(repr(end))) +- if file is not None: +- self.add_kwarg(l_args, "file", file) +- n_stmt = Call(Name("print"), l_args) +- n_stmt.set_prefix(node.get_prefix()) +- return n_stmt +- +- def add_kwarg(self, l_nodes, s_kwd, n_expr): +- # XXX All this prefix-setting may lose comments (though rarely) +- n_expr.set_prefix("") +- n_argument = pytree.Node(self.syms.argument, +- (Name(s_kwd), +- pytree.Leaf(token.EQUAL, "="), +- n_expr)) +- if l_nodes: +- l_nodes.append(Comma()) +- n_argument.set_prefix(" ") +- l_nodes.append(n_argument) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_raise.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_raise.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,82 +0,0 @@ +-"""Fixer for 'raise E, V, T' +- +-raise -> raise +-raise E -> raise E +-raise E, V -> raise E(V) +-raise E, V, T -> raise E(V).with_traceback(T) +- +-raise (((E, E'), E''), E'''), V -> raise E(V) +-raise "foo", V, T -> warns about string exceptions +- +- +-CAVEATS: +-1) "raise E, V" will be incorrectly translated if V is an exception +- instance. The correct Python 3 idiom is +- +- raise E from V +- +- but since we can't detect instance-hood by syntax alone and since +- any client code would have to be changed as well, we don't automate +- this. +-""" +-# Author: Collin Winter +- +-# Local imports +-from .. import pytree +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Name, Call, Attr, ArgList, is_tuple +- +-class FixRaise(fixer_base.BaseFix): +- +- PATTERN = """ +- raise_stmt< 'raise' exc=any [',' val=any [',' tb=any]] > +- """ +- +- def transform(self, node, results): +- syms = self.syms +- +- exc = results["exc"].clone() +- if exc.type is token.STRING: +- self.cannot_convert(node, "Python 3 does not support string exceptions") +- return +- +- # Python 2 supports +- # raise ((((E1, E2), E3), E4), E5), V +- # as a synonym for +- # raise E1, V +- # Since Python 3 will not support this, we recurse down any tuple +- # literals, always taking the first element. +- if is_tuple(exc): +- while is_tuple(exc): +- # exc.children[1:-1] is the unparenthesized tuple +- # exc.children[1].children[0] is the first element of the tuple +- exc = exc.children[1].children[0].clone() +- exc.set_prefix(" ") +- +- if "val" not in results: +- # One-argument raise +- new = pytree.Node(syms.raise_stmt, [Name("raise"), exc]) +- new.set_prefix(node.get_prefix()) +- return new +- +- val = results["val"].clone() +- if is_tuple(val): +- args = [c.clone() for c in val.children[1:-1]] +- else: +- val.set_prefix("") +- args = [val] +- +- if "tb" in results: +- tb = results["tb"].clone() +- tb.set_prefix("") +- +- e = Call(exc, args) +- with_tb = Attr(e, Name('with_traceback')) + [ArgList([tb])] +- new = pytree.Node(syms.simple_stmt, [Name("raise")] + with_tb) +- new.set_prefix(node.get_prefix()) +- return new +- else: +- return pytree.Node(syms.raise_stmt, +- [Name("raise"), Call(exc, args)], +- prefix=node.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_raw_input.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_raw_input.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,16 +0,0 @@ +-"""Fixer that changes raw_input(...) into input(...).""" +-# Author: Andre Roberge +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name +- +-class FixRawInput(fixer_base.BaseFix): +- +- PATTERN = """ +- power< name='raw_input' trailer< '(' [any] ')' > any* > +- """ +- +- def transform(self, node, results): +- name = results["name"] +- name.replace(Name("input", prefix=name.get_prefix())) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_reduce.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_reduce.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,33 +0,0 @@ +-# Copyright 2008 Armin Ronacher. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for reduce(). +- +-Makes sure reduce() is imported from the functools module if reduce is +-used in that module. +-""" +- +-from .. import pytree +-from .. import fixer_base +-from ..fixer_util import Name, Attr, touch_import +- +- +- +-class FixReduce(fixer_base.BaseFix): +- +- PATTERN = """ +- power< 'reduce' +- trailer< '(' +- arglist< ( +- (not(argument) any ',' +- not(argument +- > +- """ +- +- def transform(self, node, results): +- touch_import('functools', 'reduce', node) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_renames.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_renames.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,69 +0,0 @@ +-"""Fix incompatible renames +- +-Fixes: +- * sys.maxint -> sys.maxsize +-""" +-# Author: Christian Heimes +-# based on Collin Winter's fix_import +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name, attr_chain +- +-MAPPING = {"sys": {"maxint" : "maxsize"}, +- } +-LOOKUP = {} +- +-def alternates(members): +- return "(" + "|".join(map(repr, members)) + ")" +- +- +-def build_pattern(): +- #bare = set() +- for module, replace in MAPPING.items(): +- for old_attr, new_attr in replace.items(): +- LOOKUP[(module, old_attr)] = new_attr +- #bare.add(module) +- #bare.add(old_attr) +- #yield """ +- # import_name< 'import' (module=%r +- # | dotted_as_names< any* module=%r any* >) > +- # """ % (module, module) +- yield """ +- import_from< 'from' module_name=%r 'import' +- ( attr_name=%r | import_as_name< attr_name=%r 'as' any >) > +- """ % (module, old_attr, old_attr) +- yield """ +- power< module_name=%r trailer< '.' attr_name=%r > any* > +- """ % (module, old_attr) +- #yield """bare_name=%s""" % alternates(bare) +- +- +-class FixRenames(fixer_base.BaseFix): +- PATTERN = "|".join(build_pattern()) +- +- order = "pre" # Pre-order tree traversal +- +- # Don't match the node if it's within another match +- def match(self, node): +- match = super(FixRenames, self).match +- results = match(node) +- if results: +- if any([match(obj) for obj in attr_chain(node, "parent")]): +- return False +- return results +- return False +- +- #def start_tree(self, tree, filename): +- # super(FixRenames, self).start_tree(tree, filename) +- # self.replace = {} +- +- def transform(self, node, results): +- mod_name = results.get("module_name") +- attr_name = results.get("attr_name") +- #bare_name = results.get("bare_name") +- #import_mod = results.get("module") +- +- if mod_name and attr_name: +- new_attr = LOOKUP[(mod_name.value, attr_name.value)] +- attr_name.replace(Name(new_attr, prefix=attr_name.get_prefix())) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_repr.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_repr.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,22 +0,0 @@ +-# Copyright 2006 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer that transforms `xyzzy` into repr(xyzzy).""" +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Call, Name, parenthesize +- +- +-class FixRepr(fixer_base.BaseFix): +- +- PATTERN = """ +- atom < '`' expr=any '`' > +- """ +- +- def transform(self, node, results): +- expr = results["expr"].clone() +- +- if expr.type == self.syms.testlist1: +- expr = parenthesize(expr) +- return Call(Name("repr"), [expr], prefix=node.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_set_literal.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_set_literal.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,52 +0,0 @@ +-""" +-Optional fixer to transform set() calls to set literals. +-""" +- +-# Author: Benjamin Peterson +- +-from lib2to3 import fixer_base, pytree +-from lib2to3.fixer_util import token, syms +- +- +- +-class FixSetLiteral(fixer_base.BaseFix): +- +- explicit = True +- +- PATTERN = """power< 'set' trailer< '(' +- (atom=atom< '[' (items=listmaker< any ((',' any)* [',']) > +- | +- single=any) ']' > +- | +- atom< '(' items=testlist_gexp< any ((',' any)* [',']) > ')' > +- ) +- ')' > > +- """ +- +- def transform(self, node, results): +- single = results.get("single") +- if single: +- # Make a fake listmaker +- fake = pytree.Node(syms.listmaker, [single.clone()]) +- single.replace(fake) +- items = fake +- else: +- items = results["items"] +- +- # Build the contents of the literal +- literal = [pytree.Leaf(token.LBRACE, "{")] +- literal.extend(n.clone() for n in items.children) +- literal.append(pytree.Leaf(token.RBRACE, "}")) +- # Set the prefix of the right brace to that of the ')' or ']' +- literal[-1].set_prefix(items.next_sibling.get_prefix()) +- maker = pytree.Node(syms.dictsetmaker, literal) +- maker.set_prefix(node.get_prefix()) +- +- # If the original was a one tuple, we need to remove the extra comma. +- if len(maker.children) == 4: +- n = maker.children[2] +- n.remove() +- maker.children[-1].set_prefix(n.get_prefix()) +- +- # Finally, replace the set call with our shiny new literal. +- return maker +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_standarderror.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_standarderror.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,18 +0,0 @@ +-# Copyright 2007 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for StandardError -> Exception.""" +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name +- +- +-class FixStandarderror(fixer_base.BaseFix): +- +- PATTERN = """ +- 'StandardError' +- """ +- +- def transform(self, node, results): +- return Name("Exception", prefix=node.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_sys_exc.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_sys_exc.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,29 +0,0 @@ +-"""Fixer for sys.exc_{type, value, traceback} +- +-sys.exc_type -> sys.exc_info()[0] +-sys.exc_value -> sys.exc_info()[1] +-sys.exc_traceback -> sys.exc_info()[2] +-""" +- +-# By Jeff Balogh and Benjamin Peterson +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Attr, Call, Name, Number, Subscript, Node, syms +- +-class FixSysExc(fixer_base.BaseFix): +- # This order matches the ordering of sys.exc_info(). +- exc_info = ["exc_type", "exc_value", "exc_traceback"] +- PATTERN = """ +- power< 'sys' trailer< dot='.' attribute=(%s) > > +- """ % '|'.join("'%s'" % e for e in exc_info) +- +- def transform(self, node, results): +- sys_attr = results["attribute"][0] +- index = Number(self.exc_info.index(sys_attr.value)) +- +- call = Call(Name("exc_info"), prefix=sys_attr.get_prefix()) +- attr = Attr(Name("sys"), call) +- attr[1].children[0].set_prefix(results["dot"].get_prefix()) +- attr.append(Subscript(index)) +- return Node(syms.power, attr, prefix=node.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_throw.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_throw.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,56 +0,0 @@ +-"""Fixer for generator.throw(E, V, T). +- +-g.throw(E) -> g.throw(E) +-g.throw(E, V) -> g.throw(E(V)) +-g.throw(E, V, T) -> g.throw(E(V).with_traceback(T)) +- +-g.throw("foo"[, V[, T]]) will warn about string exceptions.""" +-# Author: Collin Winter +- +-# Local imports +-from .. import pytree +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Name, Call, ArgList, Attr, is_tuple +- +-class FixThrow(fixer_base.BaseFix): +- +- PATTERN = """ +- power< any trailer< '.' 'throw' > +- trailer< '(' args=arglist< exc=any ',' val=any [',' tb=any] > ')' > +- > +- | +- power< any trailer< '.' 'throw' > trailer< '(' exc=any ')' > > +- """ +- +- def transform(self, node, results): +- syms = self.syms +- +- exc = results["exc"].clone() +- if exc.type is token.STRING: +- self.cannot_convert(node, "Python 3 does not support string exceptions") +- return +- +- # Leave "g.throw(E)" alone +- val = results.get("val") +- if val is None: +- return +- +- val = val.clone() +- if is_tuple(val): +- args = [c.clone() for c in val.children[1:-1]] +- else: +- val.set_prefix("") +- args = [val] +- +- throw_args = results["args"] +- +- if "tb" in results: +- tb = results["tb"].clone() +- tb.set_prefix("") +- +- e = Call(exc, args) +- with_tb = Attr(e, Name('with_traceback')) + [ArgList([tb])] +- throw_args.replace(pytree.Node(syms.power, with_tb)) +- else: +- throw_args.replace(Call(exc, args)) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_tuple_params.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_tuple_params.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,169 +0,0 @@ +-"""Fixer for function definitions with tuple parameters. +- +-def func(((a, b), c), d): +- ... +- +- -> +- +-def func(x, d): +- ((a, b), c) = x +- ... +- +-It will also support lambdas: +- +- lambda (x, y): x + y -> lambda t: t[0] + t[1] +- +- # The parens are a syntax error in Python 3 +- lambda (x): x + y -> lambda x: x + y +-""" +-# Author: Collin Winter +- +-# Local imports +-from .. import pytree +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Assign, Name, Newline, Number, Subscript, syms +- +-def is_docstring(stmt): +- return isinstance(stmt, pytree.Node) and \ +- stmt.children[0].type == token.STRING +- +-class FixTupleParams(fixer_base.BaseFix): +- PATTERN = """ +- funcdef< 'def' any parameters< '(' args=any ')' > +- ['->' any] ':' suite=any+ > +- | +- lambda= +- lambdef< 'lambda' args=vfpdef< '(' inner=any ')' > +- ':' body=any +- > +- """ +- +- def transform(self, node, results): +- if "lambda" in results: +- return self.transform_lambda(node, results) +- +- new_lines = [] +- suite = results["suite"] +- args = results["args"] +- # This crap is so "def foo(...): x = 5; y = 7" is handled correctly. +- # TODO(cwinter): suite-cleanup +- if suite[0].children[1].type == token.INDENT: +- start = 2 +- indent = suite[0].children[1].value +- end = Newline() +- else: +- start = 0 +- indent = "; " +- end = pytree.Leaf(token.INDENT, "") +- +- # We need access to self for new_name(), and making this a method +- # doesn't feel right. Closing over self and new_lines makes the +- # code below cleaner. +- def handle_tuple(tuple_arg, add_prefix=False): +- n = Name(self.new_name()) +- arg = tuple_arg.clone() +- arg.set_prefix("") +- stmt = Assign(arg, n.clone()) +- if add_prefix: +- n.set_prefix(" ") +- tuple_arg.replace(n) +- new_lines.append(pytree.Node(syms.simple_stmt, +- [stmt, end.clone()])) +- +- if args.type == syms.tfpdef: +- handle_tuple(args) +- elif args.type == syms.typedargslist: +- for i, arg in enumerate(args.children): +- if arg.type == syms.tfpdef: +- # Without add_prefix, the emitted code is correct, +- # just ugly. +- handle_tuple(arg, add_prefix=(i > 0)) +- +- if not new_lines: +- return node +- +- # This isn't strictly necessary, but it plays nicely with other fixers. +- # TODO(cwinter) get rid of this when children becomes a smart list +- for line in new_lines: +- line.parent = suite[0] +- +- # TODO(cwinter) suite-cleanup +- after = start +- if start == 0: +- new_lines[0].set_prefix(" ") +- elif is_docstring(suite[0].children[start]): +- new_lines[0].set_prefix(indent) +- after = start + 1 +- +- suite[0].children[after:after] = new_lines +- for i in range(after+1, after+len(new_lines)+1): +- suite[0].children[i].set_prefix(indent) +- suite[0].changed() +- +- def transform_lambda(self, node, results): +- args = results["args"] +- body = results["body"] +- inner = simplify_args(results["inner"]) +- +- # Replace lambda ((((x)))): x with lambda x: x +- if inner.type == token.NAME: +- inner = inner.clone() +- inner.set_prefix(" ") +- args.replace(inner) +- return +- +- params = find_params(args) +- to_index = map_to_index(params) +- tup_name = self.new_name(tuple_name(params)) +- +- new_param = Name(tup_name, prefix=" ") +- args.replace(new_param.clone()) +- for n in body.post_order(): +- if n.type == token.NAME and n.value in to_index: +- subscripts = [c.clone() for c in to_index[n.value]] +- new = pytree.Node(syms.power, +- [new_param.clone()] + subscripts) +- new.set_prefix(n.get_prefix()) +- n.replace(new) +- +- +-### Helper functions for transform_lambda() +- +-def simplify_args(node): +- if node.type in (syms.vfplist, token.NAME): +- return node +- elif node.type == syms.vfpdef: +- # These look like vfpdef< '(' x ')' > where x is NAME +- # or another vfpdef instance (leading to recursion). +- while node.type == syms.vfpdef: +- node = node.children[1] +- return node +- raise RuntimeError("Received unexpected node %s" % node) +- +-def find_params(node): +- if node.type == syms.vfpdef: +- return find_params(node.children[1]) +- elif node.type == token.NAME: +- return node.value +- return [find_params(c) for c in node.children if c.type != token.COMMA] +- +-def map_to_index(param_list, prefix=[], d=None): +- if d is None: +- d = {} +- for i, obj in enumerate(param_list): +- trailer = [Subscript(Number(i))] +- if isinstance(obj, list): +- map_to_index(obj, trailer, d=d) +- else: +- d[obj] = prefix + trailer +- return d +- +-def tuple_name(param_list): +- l = [] +- for obj in param_list: +- if isinstance(obj, list): +- l.append(tuple_name(obj)) +- else: +- l.append(obj) +- return "_".join(l) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_types.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_types.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,62 +0,0 @@ +-# Copyright 2007 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for removing uses of the types module. +- +-These work for only the known names in the types module. The forms above +-can include types. or not. ie, It is assumed the module is imported either as: +- +- import types +- from types import ... # either * or specific types +- +-The import statements are not modified. +- +-There should be another fixer that handles at least the following constants: +- +- type([]) -> list +- type(()) -> tuple +- type('') -> str +- +-""" +- +-# Local imports +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Name +- +-_TYPE_MAPPING = { +- 'BooleanType' : 'bool', +- 'BufferType' : 'memoryview', +- 'ClassType' : 'type', +- 'ComplexType' : 'complex', +- 'DictType': 'dict', +- 'DictionaryType' : 'dict', +- 'EllipsisType' : 'type(Ellipsis)', +- #'FileType' : 'io.IOBase', +- 'FloatType': 'float', +- 'IntType': 'int', +- 'ListType': 'list', +- 'LongType': 'int', +- 'ObjectType' : 'object', +- 'NoneType': 'type(None)', +- 'NotImplementedType' : 'type(NotImplemented)', +- 'SliceType' : 'slice', +- 'StringType': 'bytes', # XXX ? +- 'StringTypes' : 'str', # XXX ? +- 'TupleType': 'tuple', +- 'TypeType' : 'type', +- 'UnicodeType': 'str', +- 'XRangeType' : 'range', +- } +- +-_pats = ["power< 'types' trailer< '.' name='%s' > >" % t for t in _TYPE_MAPPING] +- +-class FixTypes(fixer_base.BaseFix): +- +- PATTERN = '|'.join(_pats) +- +- def transform(self, node, results): +- new_value = _TYPE_MAPPING.get(results["name"].value) +- if new_value: +- return Name(new_value, prefix=node.get_prefix()) +- return None +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_unicode.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_unicode.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,28 +0,0 @@ +-"""Fixer that changes unicode to str, unichr to chr, and u"..." into "...". +- +-""" +- +-import re +-from ..pgen2 import token +-from .. import fixer_base +- +-class FixUnicode(fixer_base.BaseFix): +- +- PATTERN = "STRING | NAME<'unicode' | 'unichr'>" +- +- def transform(self, node, results): +- if node.type == token.NAME: +- if node.value == "unicode": +- new = node.clone() +- new.value = "str" +- return new +- if node.value == "unichr": +- new = node.clone() +- new.value = "chr" +- return new +- # XXX Warn when __unicode__ found? +- elif node.type == token.STRING: +- if re.match(r"[uU][rR]?[\'\"]", node.value): +- new = node.clone() +- new.value = new.value[1:] +- return new +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_urllib.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_urllib.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,180 +0,0 @@ +-"""Fix changes imports of urllib which are now incompatible. +- This is rather similar to fix_imports, but because of the more +- complex nature of the fixing for urllib, it has its own fixer. +-""" +-# Author: Nick Edds +- +-# Local imports +-from .fix_imports import alternates, FixImports +-from .. import fixer_base +-from ..fixer_util import Name, Comma, FromImport, Newline, attr_chain +- +-MAPPING = {'urllib': [ +- ('urllib.request', +- ['URLOpener', 'FancyURLOpener', 'urlretrieve', +- '_urlopener', 'urlcleanup']), +- ('urllib.parse', +- ['quote', 'quote_plus', 'unquote', 'unquote_plus', +- 'urlencode', 'pathname2url', 'url2pathname', 'splitattr', +- 'splithost', 'splitnport', 'splitpasswd', 'splitport', +- 'splitquery', 'splittag', 'splittype', 'splituser', +- 'splitvalue', ]), +- ('urllib.error', +- ['ContentTooShortError'])], +- 'urllib2' : [ +- ('urllib.request', +- ['urlopen', 'install_opener', 'build_opener', +- 'Request', 'OpenerDirector', 'BaseHandler', +- 'HTTPDefaultErrorHandler', 'HTTPRedirectHandler', +- 'HTTPCookieProcessor', 'ProxyHandler', +- 'HTTPPasswordMgr', +- 'HTTPPasswordMgrWithDefaultRealm', +- 'AbstractBasicAuthHandler', +- 'HTTPBasicAuthHandler', 'ProxyBasicAuthHandler', +- 'AbstractDigestAuthHandler', +- 'HTTPDigestAuthHandler', 'ProxyDigestAuthHandler', +- 'HTTPHandler', 'HTTPSHandler', 'FileHandler', +- 'FTPHandler', 'CacheFTPHandler', +- 'UnknownHandler']), +- ('urllib.error', +- ['URLError', 'HTTPError']), +- ] +-} +- +-# Duplicate the url parsing functions for urllib2. +-MAPPING["urllib2"].append(MAPPING["urllib"][1]) +- +- +-def build_pattern(): +- bare = set() +- for old_module, changes in MAPPING.items(): +- for change in changes: +- new_module, members = change +- members = alternates(members) +- yield """import_name< 'import' (module=%r +- | dotted_as_names< any* module=%r any* >) > +- """ % (old_module, old_module) +- yield """import_from< 'from' mod_member=%r 'import' +- ( member=%s | import_as_name< member=%s 'as' any > | +- import_as_names< members=any* >) > +- """ % (old_module, members, members) +- yield """import_from< 'from' module_star=%r 'import' star='*' > +- """ % old_module +- yield """import_name< 'import' +- dotted_as_name< module_as=%r 'as' any > > +- """ % old_module +- yield """power< module_dot=%r trailer< '.' member=%s > any* > +- """ % (old_module, members) +- +- +-class FixUrllib(FixImports): +- +- def build_pattern(self): +- return "|".join(build_pattern()) +- +- def transform_import(self, node, results): +- """Transform for the basic import case. Replaces the old +- import name with a comma separated list of its +- replacements. +- """ +- import_mod = results.get('module') +- pref = import_mod.get_prefix() +- +- names = [] +- +- # create a Node list of the replacement modules +- for name in MAPPING[import_mod.value][:-1]: +- names.extend([Name(name[0], prefix=pref), Comma()]) +- names.append(Name(MAPPING[import_mod.value][-1][0], prefix=pref)) +- import_mod.replace(names) +- +- def transform_member(self, node, results): +- """Transform for imports of specific module elements. Replaces +- the module to be imported from with the appropriate new +- module. +- """ +- mod_member = results.get('mod_member') +- pref = mod_member.get_prefix() +- member = results.get('member') +- +- # Simple case with only a single member being imported +- if member: +- # this may be a list of length one, or just a node +- if isinstance(member, list): +- member = member[0] +- new_name = None +- for change in MAPPING[mod_member.value]: +- if member.value in change[1]: +- new_name = change[0] +- break +- if new_name: +- mod_member.replace(Name(new_name, prefix=pref)) +- else: +- self.cannot_convert(node, +- 'This is an invalid module element') +- +- # Multiple members being imported +- else: +- # a dictionary for replacements, order matters +- modules = [] +- mod_dict = {} +- members = results.get('members') +- for member in members: +- member = member.value +- # we only care about the actual members +- if member != ',': +- for change in MAPPING[mod_member.value]: +- if member in change[1]: +- if change[0] in mod_dict: +- mod_dict[change[0]].append(member) +- else: +- mod_dict[change[0]] = [member] +- modules.append(change[0]) +- +- new_nodes = [] +- for module in modules: +- elts = mod_dict[module] +- names = [] +- for elt in elts[:-1]: +- names.extend([Name(elt, prefix=pref), Comma()]) +- names.append(Name(elts[-1], prefix=pref)) +- new_nodes.append(FromImport(module, names)) +- if new_nodes: +- nodes = [] +- for new_node in new_nodes[:-1]: +- nodes.extend([new_node, Newline()]) +- nodes.append(new_nodes[-1]) +- node.replace(nodes) +- else: +- self.cannot_convert(node, 'All module elements are invalid') +- +- def transform_dot(self, node, results): +- """Transform for calls to module members in code.""" +- module_dot = results.get('module_dot') +- member = results.get('member') +- # this may be a list of length one, or just a node +- if isinstance(member, list): +- member = member[0] +- new_name = None +- for change in MAPPING[module_dot.value]: +- if member.value in change[1]: +- new_name = change[0] +- break +- if new_name: +- module_dot.replace(Name(new_name, +- prefix=module_dot.get_prefix())) +- else: +- self.cannot_convert(node, 'This is an invalid module element') +- +- def transform(self, node, results): +- if results.get('module'): +- self.transform_import(node, results) +- elif results.get('mod_member'): +- self.transform_member(node, results) +- elif results.get('module_dot'): +- self.transform_dot(node, results) +- # Renaming and star imports are not supported for these modules. +- elif results.get('module_star'): +- self.cannot_convert(node, 'Cannot handle star imports.') +- elif results.get('module_as'): +- self.cannot_convert(node, 'This module is now multiple modules') +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_ws_comma.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_ws_comma.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,39 +0,0 @@ +-"""Fixer that changes 'a ,b' into 'a, b'. +- +-This also changes '{a :b}' into '{a: b}', but does not touch other +-uses of colons. It does not touch other uses of whitespace. +- +-""" +- +-from .. import pytree +-from ..pgen2 import token +-from .. import fixer_base +- +-class FixWsComma(fixer_base.BaseFix): +- +- explicit = True # The user must ask for this fixers +- +- PATTERN = """ +- any<(not(',') any)+ ',' ((not(',') any)+ ',')* [not(',') any]> +- """ +- +- COMMA = pytree.Leaf(token.COMMA, ",") +- COLON = pytree.Leaf(token.COLON, ":") +- SEPS = (COMMA, COLON) +- +- def transform(self, node, results): +- new = node.clone() +- comma = False +- for child in new.children: +- if child in self.SEPS: +- prefix = child.get_prefix() +- if prefix.isspace() and "\n" not in prefix: +- child.set_prefix("") +- comma = True +- else: +- if comma: +- prefix = child.get_prefix() +- if not prefix: +- child.set_prefix(" ") +- comma = False +- return new +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_xrange.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_xrange.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,64 +0,0 @@ +-# Copyright 2007 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer that changes xrange(...) into range(...).""" +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name, Call, consuming_calls +-from .. import patcomp +- +- +-class FixXrange(fixer_base.BaseFix): +- +- PATTERN = """ +- power< +- (name='range'|name='xrange') trailer< '(' args=any ')' > +- rest=any* > +- """ +- +- def transform(self, node, results): +- name = results["name"] +- if name.value == "xrange": +- return self.transform_xrange(node, results) +- elif name.value == "range": +- return self.transform_range(node, results) +- else: +- raise ValueError(repr(name)) +- +- def transform_xrange(self, node, results): +- name = results["name"] +- name.replace(Name("range", prefix=name.get_prefix())) +- +- def transform_range(self, node, results): +- if not self.in_special_context(node): +- range_call = Call(Name("range"), [results["args"].clone()]) +- # Encase the range call in list(). +- list_call = Call(Name("list"), [range_call], +- prefix=node.get_prefix()) +- # Put things that were after the range() call after the list call. +- for n in results["rest"]: +- list_call.append_child(n) +- return list_call +- return node +- +- P1 = "power< func=NAME trailer< '(' node=any ')' > any* >" +- p1 = patcomp.compile_pattern(P1) +- +- P2 = """for_stmt< 'for' any 'in' node=any ':' any* > +- | comp_for< 'for' any 'in' node=any any* > +- | comparison< any 'in' node=any any*> +- """ +- p2 = patcomp.compile_pattern(P2) +- +- def in_special_context(self, node): +- if node.parent is None: +- return False +- results = {} +- if (node.parent.parent is not None and +- self.p1.match(node.parent.parent, results) and +- results["node"] is node): +- # list(d.keys()) -> list(d.keys()), etc. +- return results["func"].value in consuming_calls +- # for ... in d.iterkeys() -> for ... in d.keys(), etc. +- return self.p2.match(node.parent, results) and results["node"] is node +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_xreadlines.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_xreadlines.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,24 +0,0 @@ +-"""Fix "for x in f.xreadlines()" -> "for x in f". +- +-This fixer will also convert g(f.xreadlines) into g(f.__iter__).""" +-# Author: Collin Winter +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name +- +- +-class FixXreadlines(fixer_base.BaseFix): +- PATTERN = """ +- power< call=any+ trailer< '.' 'xreadlines' > trailer< '(' ')' > > +- | +- power< any+ trailer< '.' no_call='xreadlines' > > +- """ +- +- def transform(self, node, results): +- no_call = results.get("no_call") +- +- if no_call: +- no_call.replace(Name("__iter__", prefix=no_call.get_prefix())) +- else: +- node.replace([x.clone() for x in results["call"]]) +diff -r 531f2e948299 lib2to3/fixes/.svn/text-base/fix_zip.py.svn-base +--- a/lib2to3/fixes/.svn/text-base/fix_zip.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,34 +0,0 @@ +-""" +-Fixer that changes zip(seq0, seq1, ...) into list(zip(seq0, seq1, ...) +-unless there exists a 'from future_builtins import zip' statement in the +-top-level namespace. +- +-We avoid the transformation if the zip() call is directly contained in +-iter(<>), list(<>), tuple(<>), sorted(<>), ...join(<>), or for V in <>:. +-""" +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name, Call, in_special_context +- +-class FixZip(fixer_base.ConditionalFix): +- +- PATTERN = """ +- power< 'zip' args=trailer< '(' [any] ')' > +- > +- """ +- +- skip_on = "future_builtins.zip" +- +- def transform(self, node, results): +- if self.should_skip(node): +- return +- +- if in_special_context(node): +- return None +- +- new = node.clone() +- new.set_prefix("") +- new = Call(Name("list"), [new]) +- new.set_prefix(node.get_prefix()) +- return new +diff -r 531f2e948299 lib2to3/fixes/__init__.py +--- a/lib2to3/fixes/__init__.py Mon Mar 30 20:02:09 2009 -0500 ++++ b/lib2to3/fixes/__init__.py Wed Apr 01 13:59:47 2009 -0500 +@@ -1,1 +1,2 @@ +-# Dummy file to make this directory a package. ++from refactor.fixes import from2 ++from refactor.fixes.from2 import * +diff -r 531f2e948299 lib2to3/fixes/fix_apply.py +--- a/lib2to3/fixes/fix_apply.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,58 +0,0 @@ +-# Copyright 2006 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for apply(). +- +-This converts apply(func, v, k) into (func)(*v, **k).""" +- +-# Local imports +-from .. import pytree +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Call, Comma, parenthesize +- +-class FixApply(fixer_base.BaseFix): +- +- PATTERN = """ +- power< 'apply' +- trailer< +- '(' +- arglist< +- (not argument +- ')' +- > +- > +- """ +- +- def transform(self, node, results): +- syms = self.syms +- assert results +- func = results["func"] +- args = results["args"] +- kwds = results.get("kwds") +- prefix = node.get_prefix() +- func = func.clone() +- if (func.type not in (token.NAME, syms.atom) and +- (func.type != syms.power or +- func.children[-2].type == token.DOUBLESTAR)): +- # Need to parenthesize +- func = parenthesize(func) +- func.set_prefix("") +- args = args.clone() +- args.set_prefix("") +- if kwds is not None: +- kwds = kwds.clone() +- kwds.set_prefix("") +- l_newargs = [pytree.Leaf(token.STAR, "*"), args] +- if kwds is not None: +- l_newargs.extend([Comma(), +- pytree.Leaf(token.DOUBLESTAR, "**"), +- kwds]) +- l_newargs[-2].set_prefix(" ") # that's the ** token +- # XXX Sometimes we could be cleverer, e.g. apply(f, (x, y) + t) +- # can be translated into f(x, y, *t) instead of f(*(x, y) + t) +- #new = pytree.Node(syms.power, (func, ArgList(l_newargs))) +- return Call(func, l_newargs, prefix=prefix) +diff -r 531f2e948299 lib2to3/fixes/fix_basestring.py +--- a/lib2to3/fixes/fix_basestring.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,13 +0,0 @@ +-"""Fixer for basestring -> str.""" +-# Author: Christian Heimes +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name +- +-class FixBasestring(fixer_base.BaseFix): +- +- PATTERN = "'basestring'" +- +- def transform(self, node, results): +- return Name("str", prefix=node.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/fix_buffer.py +--- a/lib2to3/fixes/fix_buffer.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,21 +0,0 @@ +-# Copyright 2007 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer that changes buffer(...) into memoryview(...).""" +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name +- +- +-class FixBuffer(fixer_base.BaseFix): +- +- explicit = True # The user must ask for this fixer +- +- PATTERN = """ +- power< name='buffer' trailer< '(' [any] ')' > > +- """ +- +- def transform(self, node, results): +- name = results["name"] +- name.replace(Name("memoryview", prefix=name.get_prefix())) +diff -r 531f2e948299 lib2to3/fixes/fix_callable.py +--- a/lib2to3/fixes/fix_callable.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,31 +0,0 @@ +-# Copyright 2007 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for callable(). +- +-This converts callable(obj) into hasattr(obj, '__call__').""" +- +-# Local imports +-from .. import pytree +-from .. import fixer_base +-from ..fixer_util import Call, Name, String +- +-class FixCallable(fixer_base.BaseFix): +- +- # Ignore callable(*args) or use of keywords. +- # Either could be a hint that the builtin callable() is not being used. +- PATTERN = """ +- power< 'callable' +- trailer< lpar='(' +- ( not(arglist | argument) any ','> ) +- rpar=')' > +- after=any* +- > +- """ +- +- def transform(self, node, results): +- func = results["func"] +- +- args = [func.clone(), String(', '), String("'__call__'")] +- return Call(Name("hasattr"), args, prefix=node.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/fix_dict.py +--- a/lib2to3/fixes/fix_dict.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,99 +0,0 @@ +-# Copyright 2007 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for dict methods. +- +-d.keys() -> list(d.keys()) +-d.items() -> list(d.items()) +-d.values() -> list(d.values()) +- +-d.iterkeys() -> iter(d.keys()) +-d.iteritems() -> iter(d.items()) +-d.itervalues() -> iter(d.values()) +- +-Except in certain very specific contexts: the iter() can be dropped +-when the context is list(), sorted(), iter() or for...in; the list() +-can be dropped when the context is list() or sorted() (but not iter() +-or for...in!). Special contexts that apply to both: list(), sorted(), tuple() +-set(), any(), all(), sum(). +- +-Note: iter(d.keys()) could be written as iter(d) but since the +-original d.iterkeys() was also redundant we don't fix this. And there +-are (rare) contexts where it makes a difference (e.g. when passing it +-as an argument to a function that introspects the argument). +-""" +- +-# Local imports +-from .. import pytree +-from .. import patcomp +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Name, Call, LParen, RParen, ArgList, Dot +-from .. import fixer_util +- +- +-iter_exempt = fixer_util.consuming_calls | set(["iter"]) +- +- +-class FixDict(fixer_base.BaseFix): +- PATTERN = """ +- power< head=any+ +- trailer< '.' method=('keys'|'items'|'values'| +- 'iterkeys'|'iteritems'|'itervalues') > +- parens=trailer< '(' ')' > +- tail=any* +- > +- """ +- +- def transform(self, node, results): +- head = results["head"] +- method = results["method"][0] # Extract node for method name +- tail = results["tail"] +- syms = self.syms +- method_name = method.value +- isiter = method_name.startswith("iter") +- if isiter: +- method_name = method_name[4:] +- assert method_name in ("keys", "items", "values"), repr(method) +- head = [n.clone() for n in head] +- tail = [n.clone() for n in tail] +- special = not tail and self.in_special_context(node, isiter) +- args = head + [pytree.Node(syms.trailer, +- [Dot(), +- Name(method_name, +- prefix=method.get_prefix())]), +- results["parens"].clone()] +- new = pytree.Node(syms.power, args) +- if not special: +- new.set_prefix("") +- new = Call(Name(isiter and "iter" or "list"), [new]) +- if tail: +- new = pytree.Node(syms.power, [new] + tail) +- new.set_prefix(node.get_prefix()) +- return new +- +- P1 = "power< func=NAME trailer< '(' node=any ')' > any* >" +- p1 = patcomp.compile_pattern(P1) +- +- P2 = """for_stmt< 'for' any 'in' node=any ':' any* > +- | comp_for< 'for' any 'in' node=any any* > +- """ +- p2 = patcomp.compile_pattern(P2) +- +- def in_special_context(self, node, isiter): +- if node.parent is None: +- return False +- results = {} +- if (node.parent.parent is not None and +- self.p1.match(node.parent.parent, results) and +- results["node"] is node): +- if isiter: +- # iter(d.iterkeys()) -> iter(d.keys()), etc. +- return results["func"].value in iter_exempt +- else: +- # list(d.keys()) -> list(d.keys()), etc. +- return results["func"].value in fixer_util.consuming_calls +- if not isiter: +- return False +- # for ... in d.iterkeys() -> for ... in d.keys(), etc. +- return self.p2.match(node.parent, results) and results["node"] is node +diff -r 531f2e948299 lib2to3/fixes/fix_except.py +--- a/lib2to3/fixes/fix_except.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,92 +0,0 @@ +-"""Fixer for except statements with named exceptions. +- +-The following cases will be converted: +- +-- "except E, T:" where T is a name: +- +- except E as T: +- +-- "except E, T:" where T is not a name, tuple or list: +- +- except E as t: +- T = t +- +- This is done because the target of an "except" clause must be a +- name. +- +-- "except E, T:" where T is a tuple or list literal: +- +- except E as t: +- T = t.args +-""" +-# Author: Collin Winter +- +-# Local imports +-from .. import pytree +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Assign, Attr, Name, is_tuple, is_list, syms +- +-def find_excepts(nodes): +- for i, n in enumerate(nodes): +- if n.type == syms.except_clause: +- if n.children[0].value == 'except': +- yield (n, nodes[i+2]) +- +-class FixExcept(fixer_base.BaseFix): +- +- PATTERN = """ +- try_stmt< 'try' ':' suite +- cleanup=(except_clause ':' suite)+ +- tail=(['except' ':' suite] +- ['else' ':' suite] +- ['finally' ':' suite]) > +- """ +- +- def transform(self, node, results): +- syms = self.syms +- +- tail = [n.clone() for n in results["tail"]] +- +- try_cleanup = [ch.clone() for ch in results["cleanup"]] +- for except_clause, e_suite in find_excepts(try_cleanup): +- if len(except_clause.children) == 4: +- (E, comma, N) = except_clause.children[1:4] +- comma.replace(Name("as", prefix=" ")) +- +- if N.type != token.NAME: +- # Generate a new N for the except clause +- new_N = Name(self.new_name(), prefix=" ") +- target = N.clone() +- target.set_prefix("") +- N.replace(new_N) +- new_N = new_N.clone() +- +- # Insert "old_N = new_N" as the first statement in +- # the except body. This loop skips leading whitespace +- # and indents +- #TODO(cwinter) suite-cleanup +- suite_stmts = e_suite.children +- for i, stmt in enumerate(suite_stmts): +- if isinstance(stmt, pytree.Node): +- break +- +- # The assignment is different if old_N is a tuple or list +- # In that case, the assignment is old_N = new_N.args +- if is_tuple(N) or is_list(N): +- assign = Assign(target, Attr(new_N, Name('args'))) +- else: +- assign = Assign(target, new_N) +- +- #TODO(cwinter) stopgap until children becomes a smart list +- for child in reversed(suite_stmts[:i]): +- e_suite.insert_child(0, child) +- e_suite.insert_child(i, assign) +- elif N.get_prefix() == "": +- # No space after a comma is legal; no space after "as", +- # not so much. +- N.set_prefix(" ") +- +- #TODO(cwinter) fix this when children becomes a smart list +- children = [c.clone() for c in node.children[:3]] + try_cleanup + tail +- return pytree.Node(node.type, children) +diff -r 531f2e948299 lib2to3/fixes/fix_exec.py +--- a/lib2to3/fixes/fix_exec.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,39 +0,0 @@ +-# Copyright 2006 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for exec. +- +-This converts usages of the exec statement into calls to a built-in +-exec() function. +- +-exec code in ns1, ns2 -> exec(code, ns1, ns2) +-""" +- +-# Local imports +-from .. import pytree +-from .. import fixer_base +-from ..fixer_util import Comma, Name, Call +- +- +-class FixExec(fixer_base.BaseFix): +- +- PATTERN = """ +- exec_stmt< 'exec' a=any 'in' b=any [',' c=any] > +- | +- exec_stmt< 'exec' (not atom<'(' [any] ')'>) a=any > +- """ +- +- def transform(self, node, results): +- assert results +- syms = self.syms +- a = results["a"] +- b = results.get("b") +- c = results.get("c") +- args = [a.clone()] +- args[0].set_prefix("") +- if b is not None: +- args.extend([Comma(), b.clone()]) +- if c is not None: +- args.extend([Comma(), c.clone()]) +- +- return Call(Name("exec"), args, prefix=node.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/fix_execfile.py +--- a/lib2to3/fixes/fix_execfile.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,51 +0,0 @@ +-# Copyright 2006 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for execfile. +- +-This converts usages of the execfile function into calls to the built-in +-exec() function. +-""" +- +-from .. import fixer_base +-from ..fixer_util import (Comma, Name, Call, LParen, RParen, Dot, Node, +- ArgList, String, syms) +- +- +-class FixExecfile(fixer_base.BaseFix): +- +- PATTERN = """ +- power< 'execfile' trailer< '(' arglist< filename=any [',' globals=any [',' locals=any ] ] > ')' > > +- | +- power< 'execfile' trailer< '(' filename=any ')' > > +- """ +- +- def transform(self, node, results): +- assert results +- filename = results["filename"] +- globals = results.get("globals") +- locals = results.get("locals") +- +- # Copy over the prefix from the right parentheses end of the execfile +- # call. +- execfile_paren = node.children[-1].children[-1].clone() +- # Construct open().read(). +- open_args = ArgList([filename.clone()], rparen=execfile_paren) +- open_call = Node(syms.power, [Name("open"), open_args]) +- read = [Node(syms.trailer, [Dot(), Name('read')]), +- Node(syms.trailer, [LParen(), RParen()])] +- open_expr = [open_call] + read +- # Wrap the open call in a compile call. This is so the filename will be +- # preserved in the execed code. +- filename_arg = filename.clone() +- filename_arg.set_prefix(" ") +- exec_str = String("'exec'", " ") +- compile_args = open_expr + [Comma(), filename_arg, Comma(), exec_str] +- compile_call = Call(Name("compile"), compile_args, "") +- # Finally, replace the execfile call with an exec call. +- args = [compile_call] +- if globals is not None: +- args.extend([Comma(), globals.clone()]) +- if locals is not None: +- args.extend([Comma(), locals.clone()]) +- return Call(Name("exec"), args, prefix=node.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/fix_filter.py +--- a/lib2to3/fixes/fix_filter.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,75 +0,0 @@ +-# Copyright 2007 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer that changes filter(F, X) into list(filter(F, X)). +- +-We avoid the transformation if the filter() call is directly contained +-in iter(<>), list(<>), tuple(<>), sorted(<>), ...join(<>), or +-for V in <>:. +- +-NOTE: This is still not correct if the original code was depending on +-filter(F, X) to return a string if X is a string and a tuple if X is a +-tuple. That would require type inference, which we don't do. Let +-Python 2.6 figure it out. +-""" +- +-# Local imports +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Name, Call, ListComp, in_special_context +- +-class FixFilter(fixer_base.ConditionalFix): +- +- PATTERN = """ +- filter_lambda=power< +- 'filter' +- trailer< +- '(' +- arglist< +- lambdef< 'lambda' +- (fp=NAME | vfpdef< '(' fp=NAME ')'> ) ':' xp=any +- > +- ',' +- it=any +- > +- ')' +- > +- > +- | +- power< +- 'filter' +- trailer< '(' arglist< none='None' ',' seq=any > ')' > +- > +- | +- power< +- 'filter' +- args=trailer< '(' [any] ')' > +- > +- """ +- +- skip_on = "future_builtins.filter" +- +- def transform(self, node, results): +- if self.should_skip(node): +- return +- +- if "filter_lambda" in results: +- new = ListComp(results.get("fp").clone(), +- results.get("fp").clone(), +- results.get("it").clone(), +- results.get("xp").clone()) +- +- elif "none" in results: +- new = ListComp(Name("_f"), +- Name("_f"), +- results["seq"].clone(), +- Name("_f")) +- +- else: +- if in_special_context(node): +- return None +- new = node.clone() +- new.set_prefix("") +- new = Call(Name("list"), [new]) +- new.set_prefix(node.get_prefix()) +- return new +diff -r 531f2e948299 lib2to3/fixes/fix_funcattrs.py +--- a/lib2to3/fixes/fix_funcattrs.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,19 +0,0 @@ +-"""Fix function attribute names (f.func_x -> f.__x__).""" +-# Author: Collin Winter +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name +- +- +-class FixFuncattrs(fixer_base.BaseFix): +- PATTERN = """ +- power< any+ trailer< '.' attr=('func_closure' | 'func_doc' | 'func_globals' +- | 'func_name' | 'func_defaults' | 'func_code' +- | 'func_dict') > any* > +- """ +- +- def transform(self, node, results): +- attr = results["attr"][0] +- attr.replace(Name(("__%s__" % attr.value[5:]), +- prefix=attr.get_prefix())) +diff -r 531f2e948299 lib2to3/fixes/fix_future.py +--- a/lib2to3/fixes/fix_future.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,20 +0,0 @@ +-"""Remove __future__ imports +- +-from __future__ import foo is replaced with an empty line. +-""" +-# Author: Christian Heimes +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import BlankLine +- +-class FixFuture(fixer_base.BaseFix): +- PATTERN = """import_from< 'from' module_name="__future__" 'import' any >""" +- +- # This should be run last -- some things check for the import +- run_order = 10 +- +- def transform(self, node, results): +- new = BlankLine() +- new.prefix = node.get_prefix() +- return new +diff -r 531f2e948299 lib2to3/fixes/fix_getcwdu.py +--- a/lib2to3/fixes/fix_getcwdu.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,18 +0,0 @@ +-""" +-Fixer that changes os.getcwdu() to os.getcwd(). +-""" +-# Author: Victor Stinner +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name +- +-class FixGetcwdu(fixer_base.BaseFix): +- +- PATTERN = """ +- power< 'os' trailer< dot='.' name='getcwdu' > any* > +- """ +- +- def transform(self, node, results): +- name = results["name"] +- name.replace(Name("getcwd", prefix=name.get_prefix())) +diff -r 531f2e948299 lib2to3/fixes/fix_has_key.py +--- a/lib2to3/fixes/fix_has_key.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,109 +0,0 @@ +-# Copyright 2006 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for has_key(). +- +-Calls to .has_key() methods are expressed in terms of the 'in' +-operator: +- +- d.has_key(k) -> k in d +- +-CAVEATS: +-1) While the primary target of this fixer is dict.has_key(), the +- fixer will change any has_key() method call, regardless of its +- class. +- +-2) Cases like this will not be converted: +- +- m = d.has_key +- if m(k): +- ... +- +- Only *calls* to has_key() are converted. While it is possible to +- convert the above to something like +- +- m = d.__contains__ +- if m(k): +- ... +- +- this is currently not done. +-""" +- +-# Local imports +-from .. import pytree +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Name, parenthesize +- +- +-class FixHasKey(fixer_base.BaseFix): +- +- PATTERN = """ +- anchor=power< +- before=any+ +- trailer< '.' 'has_key' > +- trailer< +- '(' +- ( not(arglist | argument) arg=any ','> +- ) +- ')' +- > +- after=any* +- > +- | +- negation=not_test< +- 'not' +- anchor=power< +- before=any+ +- trailer< '.' 'has_key' > +- trailer< +- '(' +- ( not(arglist | argument) arg=any ','> +- ) +- ')' +- > +- > +- > +- """ +- +- def transform(self, node, results): +- assert results +- syms = self.syms +- if (node.parent.type == syms.not_test and +- self.pattern.match(node.parent)): +- # Don't transform a node matching the first alternative of the +- # pattern when its parent matches the second alternative +- return None +- negation = results.get("negation") +- anchor = results["anchor"] +- prefix = node.get_prefix() +- before = [n.clone() for n in results["before"]] +- arg = results["arg"].clone() +- after = results.get("after") +- if after: +- after = [n.clone() for n in after] +- if arg.type in (syms.comparison, syms.not_test, syms.and_test, +- syms.or_test, syms.test, syms.lambdef, syms.argument): +- arg = parenthesize(arg) +- if len(before) == 1: +- before = before[0] +- else: +- before = pytree.Node(syms.power, before) +- before.set_prefix(" ") +- n_op = Name("in", prefix=" ") +- if negation: +- n_not = Name("not", prefix=" ") +- n_op = pytree.Node(syms.comp_op, (n_not, n_op)) +- new = pytree.Node(syms.comparison, (arg, n_op, before)) +- if after: +- new = parenthesize(new) +- new = pytree.Node(syms.power, (new,) + tuple(after)) +- if node.parent.type in (syms.comparison, syms.expr, syms.xor_expr, +- syms.and_expr, syms.shift_expr, +- syms.arith_expr, syms.term, +- syms.factor, syms.power): +- new = parenthesize(new) +- new.set_prefix(prefix) +- return new +diff -r 531f2e948299 lib2to3/fixes/fix_idioms.py +--- a/lib2to3/fixes/fix_idioms.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,134 +0,0 @@ +-"""Adjust some old Python 2 idioms to their modern counterparts. +- +-* Change some type comparisons to isinstance() calls: +- type(x) == T -> isinstance(x, T) +- type(x) is T -> isinstance(x, T) +- type(x) != T -> not isinstance(x, T) +- type(x) is not T -> not isinstance(x, T) +- +-* Change "while 1:" into "while True:". +- +-* Change both +- +- v = list(EXPR) +- v.sort() +- foo(v) +- +-and the more general +- +- v = EXPR +- v.sort() +- foo(v) +- +-into +- +- v = sorted(EXPR) +- foo(v) +-""" +-# Author: Jacques Frechet, Collin Winter +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Call, Comma, Name, Node, syms +- +-CMP = "(n='!=' | '==' | 'is' | n=comp_op< 'is' 'not' >)" +-TYPE = "power< 'type' trailer< '(' x=any ')' > >" +- +-class FixIdioms(fixer_base.BaseFix): +- +- explicit = True # The user must ask for this fixer +- +- PATTERN = r""" +- isinstance=comparison< %s %s T=any > +- | +- isinstance=comparison< T=any %s %s > +- | +- while_stmt< 'while' while='1' ':' any+ > +- | +- sorted=any< +- any* +- simple_stmt< +- expr_stmt< id1=any '=' +- power< list='list' trailer< '(' (not arglist) any ')' > > +- > +- '\n' +- > +- sort= +- simple_stmt< +- power< id2=any +- trailer< '.' 'sort' > trailer< '(' ')' > +- > +- '\n' +- > +- next=any* +- > +- | +- sorted=any< +- any* +- simple_stmt< expr_stmt< id1=any '=' expr=any > '\n' > +- sort= +- simple_stmt< +- power< id2=any +- trailer< '.' 'sort' > trailer< '(' ')' > +- > +- '\n' +- > +- next=any* +- > +- """ % (TYPE, CMP, CMP, TYPE) +- +- def match(self, node): +- r = super(FixIdioms, self).match(node) +- # If we've matched one of the sort/sorted subpatterns above, we +- # want to reject matches where the initial assignment and the +- # subsequent .sort() call involve different identifiers. +- if r and "sorted" in r: +- if r["id1"] == r["id2"]: +- return r +- return None +- return r +- +- def transform(self, node, results): +- if "isinstance" in results: +- return self.transform_isinstance(node, results) +- elif "while" in results: +- return self.transform_while(node, results) +- elif "sorted" in results: +- return self.transform_sort(node, results) +- else: +- raise RuntimeError("Invalid match") +- +- def transform_isinstance(self, node, results): +- x = results["x"].clone() # The thing inside of type() +- T = results["T"].clone() # The type being compared against +- x.set_prefix("") +- T.set_prefix(" ") +- test = Call(Name("isinstance"), [x, Comma(), T]) +- if "n" in results: +- test.set_prefix(" ") +- test = Node(syms.not_test, [Name("not"), test]) +- test.set_prefix(node.get_prefix()) +- return test +- +- def transform_while(self, node, results): +- one = results["while"] +- one.replace(Name("True", prefix=one.get_prefix())) +- +- def transform_sort(self, node, results): +- sort_stmt = results["sort"] +- next_stmt = results["next"] +- list_call = results.get("list") +- simple_expr = results.get("expr") +- +- if list_call: +- list_call.replace(Name("sorted", prefix=list_call.get_prefix())) +- elif simple_expr: +- new = simple_expr.clone() +- new.set_prefix("") +- simple_expr.replace(Call(Name("sorted"), [new], +- prefix=simple_expr.get_prefix())) +- else: +- raise RuntimeError("should not have reached here") +- sort_stmt.remove() +- if next_stmt: +- next_stmt[0].set_prefix(sort_stmt.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/fix_import.py +--- a/lib2to3/fixes/fix_import.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,90 +0,0 @@ +-"""Fixer for import statements. +-If spam is being imported from the local directory, this import: +- from spam import eggs +-Becomes: +- from .spam import eggs +- +-And this import: +- import spam +-Becomes: +- from . import spam +-""" +- +-# Local imports +-from .. import fixer_base +-from os.path import dirname, join, exists, pathsep +-from ..fixer_util import FromImport, syms, token +- +- +-def traverse_imports(names): +- """ +- Walks over all the names imported in a dotted_as_names node. +- """ +- pending = [names] +- while pending: +- node = pending.pop() +- if node.type == token.NAME: +- yield node.value +- elif node.type == syms.dotted_name: +- yield "".join([ch.value for ch in node.children]) +- elif node.type == syms.dotted_as_name: +- pending.append(node.children[0]) +- elif node.type == syms.dotted_as_names: +- pending.extend(node.children[::-2]) +- else: +- raise AssertionError("unkown node type") +- +- +-class FixImport(fixer_base.BaseFix): +- +- PATTERN = """ +- import_from< 'from' imp=any 'import' ['('] any [')'] > +- | +- import_name< 'import' imp=any > +- """ +- +- def transform(self, node, results): +- imp = results['imp'] +- +- if node.type == syms.import_from: +- # Some imps are top-level (eg: 'import ham') +- # some are first level (eg: 'import ham.eggs') +- # some are third level (eg: 'import ham.eggs as spam') +- # Hence, the loop +- while not hasattr(imp, 'value'): +- imp = imp.children[0] +- if self.probably_a_local_import(imp.value): +- imp.value = "." + imp.value +- imp.changed() +- return node +- else: +- have_local = False +- have_absolute = False +- for mod_name in traverse_imports(imp): +- if self.probably_a_local_import(mod_name): +- have_local = True +- else: +- have_absolute = True +- if have_absolute: +- if have_local: +- # We won't handle both sibling and absolute imports in the +- # same statement at the moment. +- self.warning(node, "absolute and local imports together") +- return +- +- new = FromImport('.', [imp]) +- new.set_prefix(node.get_prefix()) +- return new +- +- def probably_a_local_import(self, imp_name): +- imp_name = imp_name.split('.', 1)[0] +- base_path = dirname(self.filename) +- base_path = join(base_path, imp_name) +- # If there is no __init__.py next to the file its not in a package +- # so can't be a relative import. +- if not exists(join(dirname(base_path), '__init__.py')): +- return False +- for ext in ['.py', pathsep, '.pyc', '.so', '.sl', '.pyd']: +- if exists(base_path + ext): +- return True +- return False +diff -r 531f2e948299 lib2to3/fixes/fix_imports.py +--- a/lib2to3/fixes/fix_imports.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,145 +0,0 @@ +-"""Fix incompatible imports and module references.""" +-# Authors: Collin Winter, Nick Edds +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name, attr_chain +- +-MAPPING = {'StringIO': 'io', +- 'cStringIO': 'io', +- 'cPickle': 'pickle', +- '__builtin__' : 'builtins', +- 'copy_reg': 'copyreg', +- 'Queue': 'queue', +- 'SocketServer': 'socketserver', +- 'ConfigParser': 'configparser', +- 'repr': 'reprlib', +- 'FileDialog': 'tkinter.filedialog', +- 'tkFileDialog': 'tkinter.filedialog', +- 'SimpleDialog': 'tkinter.simpledialog', +- 'tkSimpleDialog': 'tkinter.simpledialog', +- 'tkColorChooser': 'tkinter.colorchooser', +- 'tkCommonDialog': 'tkinter.commondialog', +- 'Dialog': 'tkinter.dialog', +- 'Tkdnd': 'tkinter.dnd', +- 'tkFont': 'tkinter.font', +- 'tkMessageBox': 'tkinter.messagebox', +- 'ScrolledText': 'tkinter.scrolledtext', +- 'Tkconstants': 'tkinter.constants', +- 'Tix': 'tkinter.tix', +- 'ttk': 'tkinter.ttk', +- 'Tkinter': 'tkinter', +- 'markupbase': '_markupbase', +- '_winreg': 'winreg', +- 'thread': '_thread', +- 'dummy_thread': '_dummy_thread', +- # anydbm and whichdb are handled by fix_imports2 +- 'dbhash': 'dbm.bsd', +- 'dumbdbm': 'dbm.dumb', +- 'dbm': 'dbm.ndbm', +- 'gdbm': 'dbm.gnu', +- 'xmlrpclib': 'xmlrpc.client', +- 'DocXMLRPCServer': 'xmlrpc.server', +- 'SimpleXMLRPCServer': 'xmlrpc.server', +- 'httplib': 'http.client', +- 'htmlentitydefs' : 'html.entities', +- 'HTMLParser' : 'html.parser', +- 'Cookie': 'http.cookies', +- 'cookielib': 'http.cookiejar', +- 'BaseHTTPServer': 'http.server', +- 'SimpleHTTPServer': 'http.server', +- 'CGIHTTPServer': 'http.server', +- #'test.test_support': 'test.support', +- 'commands': 'subprocess', +- 'UserString' : 'collections', +- 'UserList' : 'collections', +- 'urlparse' : 'urllib.parse', +- 'robotparser' : 'urllib.robotparser', +-} +- +- +-def alternates(members): +- return "(" + "|".join(map(repr, members)) + ")" +- +- +-def build_pattern(mapping=MAPPING): +- mod_list = ' | '.join(["module_name='%s'" % key for key in mapping]) +- bare_names = alternates(mapping.keys()) +- +- yield """name_import=import_name< 'import' ((%s) | +- multiple_imports=dotted_as_names< any* (%s) any* >) > +- """ % (mod_list, mod_list) +- yield """import_from< 'from' (%s) 'import' ['('] +- ( any | import_as_name< any 'as' any > | +- import_as_names< any* >) [')'] > +- """ % mod_list +- yield """import_name< 'import' (dotted_as_name< (%s) 'as' any > | +- multiple_imports=dotted_as_names< +- any* dotted_as_name< (%s) 'as' any > any* >) > +- """ % (mod_list, mod_list) +- +- # Find usages of module members in code e.g. thread.foo(bar) +- yield "power< bare_with_attr=(%s) trailer<'.' any > any* >" % bare_names +- +- +-class FixImports(fixer_base.BaseFix): +- +- order = "pre" # Pre-order tree traversal +- +- # This is overridden in fix_imports2. +- mapping = MAPPING +- +- # We want to run this fixer late, so fix_import doesn't try to make stdlib +- # renames into relative imports. +- run_order = 6 +- +- def build_pattern(self): +- return "|".join(build_pattern(self.mapping)) +- +- def compile_pattern(self): +- # We override this, so MAPPING can be pragmatically altered and the +- # changes will be reflected in PATTERN. +- self.PATTERN = self.build_pattern() +- super(FixImports, self).compile_pattern() +- +- # Don't match the node if it's within another match. +- def match(self, node): +- match = super(FixImports, self).match +- results = match(node) +- if results: +- # Module usage could be in the trailer of an attribute lookup, so we +- # might have nested matches when "bare_with_attr" is present. +- if "bare_with_attr" not in results and \ +- any([match(obj) for obj in attr_chain(node, "parent")]): +- return False +- return results +- return False +- +- def start_tree(self, tree, filename): +- super(FixImports, self).start_tree(tree, filename) +- self.replace = {} +- +- def transform(self, node, results): +- import_mod = results.get("module_name") +- if import_mod: +- mod_name = import_mod.value +- new_name = self.mapping[mod_name] +- import_mod.replace(Name(new_name, prefix=import_mod.get_prefix())) +- if "name_import" in results: +- # If it's not a "from x import x, y" or "import x as y" import, +- # marked its usage to be replaced. +- self.replace[mod_name] = new_name +- if "multiple_imports" in results: +- # This is a nasty hack to fix multiple imports on a line (e.g., +- # "import StringIO, urlparse"). The problem is that I can't +- # figure out an easy way to make a pattern recognize the keys of +- # MAPPING randomly sprinkled in an import statement. +- results = self.match(node) +- if results: +- self.transform(node, results) +- else: +- # Replace usage of the module. +- bare_name = results["bare_with_attr"][0] +- new_name = self.replace.get(bare_name.value) +- if new_name: +- bare_name.replace(Name(new_name, prefix=bare_name.get_prefix())) +diff -r 531f2e948299 lib2to3/fixes/fix_imports2.py +--- a/lib2to3/fixes/fix_imports2.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,16 +0,0 @@ +-"""Fix incompatible imports and module references that must be fixed after +-fix_imports.""" +-from . import fix_imports +- +- +-MAPPING = { +- 'whichdb': 'dbm', +- 'anydbm': 'dbm', +- } +- +- +-class FixImports2(fix_imports.FixImports): +- +- run_order = 7 +- +- mapping = MAPPING +diff -r 531f2e948299 lib2to3/fixes/fix_input.py +--- a/lib2to3/fixes/fix_input.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,26 +0,0 @@ +-"""Fixer that changes input(...) into eval(input(...)).""" +-# Author: Andre Roberge +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Call, Name +-from .. import patcomp +- +- +-context = patcomp.compile_pattern("power< 'eval' trailer< '(' any ')' > >") +- +- +-class FixInput(fixer_base.BaseFix): +- +- PATTERN = """ +- power< 'input' args=trailer< '(' [any] ')' > > +- """ +- +- def transform(self, node, results): +- # If we're already wrapped in a eval() call, we're done. +- if context.match(node.parent.parent): +- return +- +- new = node.clone() +- new.set_prefix("") +- return Call(Name("eval"), [new], prefix=node.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/fix_intern.py +--- a/lib2to3/fixes/fix_intern.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,44 +0,0 @@ +-# Copyright 2006 Georg Brandl. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for intern(). +- +-intern(s) -> sys.intern(s)""" +- +-# Local imports +-from .. import pytree +-from .. import fixer_base +-from ..fixer_util import Name, Attr, touch_import +- +- +-class FixIntern(fixer_base.BaseFix): +- +- PATTERN = """ +- power< 'intern' +- trailer< lpar='(' +- ( not(arglist | argument) any ','> ) +- rpar=')' > +- after=any* +- > +- """ +- +- def transform(self, node, results): +- syms = self.syms +- obj = results["obj"].clone() +- if obj.type == syms.arglist: +- newarglist = obj.clone() +- else: +- newarglist = pytree.Node(syms.arglist, [obj.clone()]) +- after = results["after"] +- if after: +- after = [n.clone() for n in after] +- new = pytree.Node(syms.power, +- Attr(Name("sys"), Name("intern")) + +- [pytree.Node(syms.trailer, +- [results["lpar"].clone(), +- newarglist, +- results["rpar"].clone()])] + after) +- new.set_prefix(node.get_prefix()) +- touch_import(None, 'sys', node) +- return new +diff -r 531f2e948299 lib2to3/fixes/fix_isinstance.py +--- a/lib2to3/fixes/fix_isinstance.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,52 +0,0 @@ +-# Copyright 2008 Armin Ronacher. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer that cleans up a tuple argument to isinstance after the tokens +-in it were fixed. This is mainly used to remove double occurrences of +-tokens as a leftover of the long -> int / unicode -> str conversion. +- +-eg. isinstance(x, (int, long)) -> isinstance(x, (int, int)) +- -> isinstance(x, int) +-""" +- +-from .. import fixer_base +-from ..fixer_util import token +- +- +-class FixIsinstance(fixer_base.BaseFix): +- +- PATTERN = """ +- power< +- 'isinstance' +- trailer< '(' arglist< any ',' atom< '(' +- args=testlist_gexp< any+ > +- ')' > > ')' > +- > +- """ +- +- run_order = 6 +- +- def transform(self, node, results): +- names_inserted = set() +- testlist = results["args"] +- args = testlist.children +- new_args = [] +- iterator = enumerate(args) +- for idx, arg in iterator: +- if arg.type == token.NAME and arg.value in names_inserted: +- if idx < len(args) - 1 and args[idx + 1].type == token.COMMA: +- iterator.next() +- continue +- else: +- new_args.append(arg) +- if arg.type == token.NAME: +- names_inserted.add(arg.value) +- if new_args and new_args[-1].type == token.COMMA: +- del new_args[-1] +- if len(new_args) == 1: +- atom = testlist.parent +- new_args[0].set_prefix(atom.get_prefix()) +- atom.replace(new_args[0]) +- else: +- args[:] = new_args +- node.changed() +diff -r 531f2e948299 lib2to3/fixes/fix_itertools.py +--- a/lib2to3/fixes/fix_itertools.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,41 +0,0 @@ +-""" Fixer for itertools.(imap|ifilter|izip) --> (map|filter|zip) and +- itertools.ifilterfalse --> itertools.filterfalse (bugs 2360-2363) +- +- imports from itertools are fixed in fix_itertools_import.py +- +- If itertools is imported as something else (ie: import itertools as it; +- it.izip(spam, eggs)) method calls will not get fixed. +- """ +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name +- +-class FixItertools(fixer_base.BaseFix): +- it_funcs = "('imap'|'ifilter'|'izip'|'ifilterfalse')" +- PATTERN = """ +- power< it='itertools' +- trailer< +- dot='.' func=%(it_funcs)s > trailer< '(' [any] ')' > > +- | +- power< func=%(it_funcs)s trailer< '(' [any] ')' > > +- """ %(locals()) +- +- # Needs to be run after fix_(map|zip|filter) +- run_order = 6 +- +- def transform(self, node, results): +- prefix = None +- func = results['func'][0] +- if 'it' in results and func.value != 'ifilterfalse': +- dot, it = (results['dot'], results['it']) +- # Remove the 'itertools' +- prefix = it.get_prefix() +- it.remove() +- # Replace the node wich contains ('.', 'function') with the +- # function (to be consistant with the second part of the pattern) +- dot.remove() +- func.parent.replace(func) +- +- prefix = prefix or func.get_prefix() +- func.replace(Name(func.value[1:], prefix=prefix)) +diff -r 531f2e948299 lib2to3/fixes/fix_itertools_imports.py +--- a/lib2to3/fixes/fix_itertools_imports.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,52 +0,0 @@ +-""" Fixer for imports of itertools.(imap|ifilter|izip|ifilterfalse) """ +- +-# Local imports +-from lib2to3 import fixer_base +-from lib2to3.fixer_util import BlankLine, syms, token +- +- +-class FixItertoolsImports(fixer_base.BaseFix): +- PATTERN = """ +- import_from< 'from' 'itertools' 'import' imports=any > +- """ %(locals()) +- +- def transform(self, node, results): +- imports = results['imports'] +- if imports.type == syms.import_as_name or not imports.children: +- children = [imports] +- else: +- children = imports.children +- for child in children[::2]: +- if child.type == token.NAME: +- member = child.value +- name_node = child +- else: +- assert child.type == syms.import_as_name +- name_node = child.children[0] +- member_name = name_node.value +- if member_name in ('imap', 'izip', 'ifilter'): +- child.value = None +- child.remove() +- elif member_name == 'ifilterfalse': +- node.changed() +- name_node.value = 'filterfalse' +- +- # Make sure the import statement is still sane +- children = imports.children[:] or [imports] +- remove_comma = True +- for child in children: +- if remove_comma and child.type == token.COMMA: +- child.remove() +- else: +- remove_comma ^= True +- +- if children[-1].type == token.COMMA: +- children[-1].remove() +- +- # If there are no imports left, just get rid of the entire statement +- if not (imports.children or getattr(imports, 'value', None)) or \ +- imports.parent is None: +- p = node.get_prefix() +- node = BlankLine() +- node.prefix = p +- return node +diff -r 531f2e948299 lib2to3/fixes/fix_long.py +--- a/lib2to3/fixes/fix_long.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,22 +0,0 @@ +-# Copyright 2006 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer that turns 'long' into 'int' everywhere. +-""" +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name, Number, is_probably_builtin +- +- +-class FixLong(fixer_base.BaseFix): +- +- PATTERN = "'long'" +- +- static_int = Name("int") +- +- def transform(self, node, results): +- if is_probably_builtin(node): +- new = self.static_int.clone() +- new.set_prefix(node.get_prefix()) +- return new +diff -r 531f2e948299 lib2to3/fixes/fix_map.py +--- a/lib2to3/fixes/fix_map.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,82 +0,0 @@ +-# Copyright 2007 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer that changes map(F, ...) into list(map(F, ...)) unless there +-exists a 'from future_builtins import map' statement in the top-level +-namespace. +- +-As a special case, map(None, X) is changed into list(X). (This is +-necessary because the semantics are changed in this case -- the new +-map(None, X) is equivalent to [(x,) for x in X].) +- +-We avoid the transformation (except for the special case mentioned +-above) if the map() call is directly contained in iter(<>), list(<>), +-tuple(<>), sorted(<>), ...join(<>), or for V in <>:. +- +-NOTE: This is still not correct if the original code was depending on +-map(F, X, Y, ...) to go on until the longest argument is exhausted, +-substituting None for missing values -- like zip(), it now stops as +-soon as the shortest argument is exhausted. +-""" +- +-# Local imports +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Name, Call, ListComp, in_special_context +-from ..pygram import python_symbols as syms +- +-class FixMap(fixer_base.ConditionalFix): +- +- PATTERN = """ +- map_none=power< +- 'map' +- trailer< '(' arglist< 'None' ',' arg=any [','] > ')' > +- > +- | +- map_lambda=power< +- 'map' +- trailer< +- '(' +- arglist< +- lambdef< 'lambda' +- (fp=NAME | vfpdef< '(' fp=NAME ')'> ) ':' xp=any +- > +- ',' +- it=any +- > +- ')' +- > +- > +- | +- power< +- 'map' +- args=trailer< '(' [any] ')' > +- > +- """ +- +- skip_on = 'future_builtins.map' +- +- def transform(self, node, results): +- if self.should_skip(node): +- return +- +- if node.parent.type == syms.simple_stmt: +- self.warning(node, "You should use a for loop here") +- new = node.clone() +- new.set_prefix("") +- new = Call(Name("list"), [new]) +- elif "map_lambda" in results: +- new = ListComp(results.get("xp").clone(), +- results.get("fp").clone(), +- results.get("it").clone()) +- else: +- if "map_none" in results: +- new = results["arg"].clone() +- else: +- if in_special_context(node): +- return None +- new = node.clone() +- new.set_prefix("") +- new = Call(Name("list"), [new]) +- new.set_prefix(node.get_prefix()) +- return new +diff -r 531f2e948299 lib2to3/fixes/fix_metaclass.py +--- a/lib2to3/fixes/fix_metaclass.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,227 +0,0 @@ +-"""Fixer for __metaclass__ = X -> (metaclass=X) methods. +- +- The various forms of classef (inherits nothing, inherits once, inherints +- many) don't parse the same in the CST so we look at ALL classes for +- a __metaclass__ and if we find one normalize the inherits to all be +- an arglist. +- +- For one-liner classes ('class X: pass') there is no indent/dedent so +- we normalize those into having a suite. +- +- Moving the __metaclass__ into the classdef can also cause the class +- body to be empty so there is some special casing for that as well. +- +- This fixer also tries very hard to keep original indenting and spacing +- in all those corner cases. +- +-""" +-# Author: Jack Diederich +- +-# Local imports +-from .. import fixer_base +-from ..pygram import token +-from ..fixer_util import Name, syms, Node, Leaf +- +- +-def has_metaclass(parent): +- """ we have to check the cls_node without changing it. +- There are two possiblities: +- 1) clsdef => suite => simple_stmt => expr_stmt => Leaf('__meta') +- 2) clsdef => simple_stmt => expr_stmt => Leaf('__meta') +- """ +- for node in parent.children: +- if node.type == syms.suite: +- return has_metaclass(node) +- elif node.type == syms.simple_stmt and node.children: +- expr_node = node.children[0] +- if expr_node.type == syms.expr_stmt and expr_node.children: +- left_side = expr_node.children[0] +- if isinstance(left_side, Leaf) and \ +- left_side.value == '__metaclass__': +- return True +- return False +- +- +-def fixup_parse_tree(cls_node): +- """ one-line classes don't get a suite in the parse tree so we add +- one to normalize the tree +- """ +- for node in cls_node.children: +- if node.type == syms.suite: +- # already in the prefered format, do nothing +- return +- +- # !%@#! oneliners have no suite node, we have to fake one up +- for i, node in enumerate(cls_node.children): +- if node.type == token.COLON: +- break +- else: +- raise ValueError("No class suite and no ':'!") +- +- # move everything into a suite node +- suite = Node(syms.suite, []) +- while cls_node.children[i+1:]: +- move_node = cls_node.children[i+1] +- suite.append_child(move_node.clone()) +- move_node.remove() +- cls_node.append_child(suite) +- node = suite +- +- +-def fixup_simple_stmt(parent, i, stmt_node): +- """ if there is a semi-colon all the parts count as part of the same +- simple_stmt. We just want the __metaclass__ part so we move +- everything efter the semi-colon into its own simple_stmt node +- """ +- for semi_ind, node in enumerate(stmt_node.children): +- if node.type == token.SEMI: # *sigh* +- break +- else: +- return +- +- node.remove() # kill the semicolon +- new_expr = Node(syms.expr_stmt, []) +- new_stmt = Node(syms.simple_stmt, [new_expr]) +- while stmt_node.children[semi_ind:]: +- move_node = stmt_node.children[semi_ind] +- new_expr.append_child(move_node.clone()) +- move_node.remove() +- parent.insert_child(i, new_stmt) +- new_leaf1 = new_stmt.children[0].children[0] +- old_leaf1 = stmt_node.children[0].children[0] +- new_leaf1.set_prefix(old_leaf1.get_prefix()) +- +- +-def remove_trailing_newline(node): +- if node.children and node.children[-1].type == token.NEWLINE: +- node.children[-1].remove() +- +- +-def find_metas(cls_node): +- # find the suite node (Mmm, sweet nodes) +- for node in cls_node.children: +- if node.type == syms.suite: +- break +- else: +- raise ValueError("No class suite!") +- +- # look for simple_stmt[ expr_stmt[ Leaf('__metaclass__') ] ] +- for i, simple_node in list(enumerate(node.children)): +- if simple_node.type == syms.simple_stmt and simple_node.children: +- expr_node = simple_node.children[0] +- if expr_node.type == syms.expr_stmt and expr_node.children: +- # Check if the expr_node is a simple assignment. +- left_node = expr_node.children[0] +- if isinstance(left_node, Leaf) and \ +- left_node.value == '__metaclass__': +- # We found a assignment to __metaclass__. +- fixup_simple_stmt(node, i, simple_node) +- remove_trailing_newline(simple_node) +- yield (node, i, simple_node) +- +- +-def fixup_indent(suite): +- """ If an INDENT is followed by a thing with a prefix then nuke the prefix +- Otherwise we get in trouble when removing __metaclass__ at suite start +- """ +- kids = suite.children[::-1] +- # find the first indent +- while kids: +- node = kids.pop() +- if node.type == token.INDENT: +- break +- +- # find the first Leaf +- while kids: +- node = kids.pop() +- if isinstance(node, Leaf) and node.type != token.DEDENT: +- if node.prefix: +- node.set_prefix('') +- return +- else: +- kids.extend(node.children[::-1]) +- +- +-class FixMetaclass(fixer_base.BaseFix): +- +- PATTERN = """ +- classdef +- """ +- +- def transform(self, node, results): +- if not has_metaclass(node): +- return node +- +- fixup_parse_tree(node) +- +- # find metaclasses, keep the last one +- last_metaclass = None +- for suite, i, stmt in find_metas(node): +- last_metaclass = stmt +- stmt.remove() +- +- text_type = node.children[0].type # always Leaf(nnn, 'class') +- +- # figure out what kind of classdef we have +- if len(node.children) == 7: +- # Node(classdef, ['class', 'name', '(', arglist, ')', ':', suite]) +- # 0 1 2 3 4 5 6 +- if node.children[3].type == syms.arglist: +- arglist = node.children[3] +- # Node(classdef, ['class', 'name', '(', 'Parent', ')', ':', suite]) +- else: +- parent = node.children[3].clone() +- arglist = Node(syms.arglist, [parent]) +- node.set_child(3, arglist) +- elif len(node.children) == 6: +- # Node(classdef, ['class', 'name', '(', ')', ':', suite]) +- # 0 1 2 3 4 5 +- arglist = Node(syms.arglist, []) +- node.insert_child(3, arglist) +- elif len(node.children) == 4: +- # Node(classdef, ['class', 'name', ':', suite]) +- # 0 1 2 3 +- arglist = Node(syms.arglist, []) +- node.insert_child(2, Leaf(token.RPAR, ')')) +- node.insert_child(2, arglist) +- node.insert_child(2, Leaf(token.LPAR, '(')) +- else: +- raise ValueError("Unexpected class definition") +- +- # now stick the metaclass in the arglist +- meta_txt = last_metaclass.children[0].children[0] +- meta_txt.value = 'metaclass' +- orig_meta_prefix = meta_txt.get_prefix() +- +- if arglist.children: +- arglist.append_child(Leaf(token.COMMA, ',')) +- meta_txt.set_prefix(' ') +- else: +- meta_txt.set_prefix('') +- +- # compact the expression "metaclass = Meta" -> "metaclass=Meta" +- expr_stmt = last_metaclass.children[0] +- assert expr_stmt.type == syms.expr_stmt +- expr_stmt.children[1].set_prefix('') +- expr_stmt.children[2].set_prefix('') +- +- arglist.append_child(last_metaclass) +- +- fixup_indent(suite) +- +- # check for empty suite +- if not suite.children: +- # one-liner that was just __metaclass_ +- suite.remove() +- pass_leaf = Leaf(text_type, 'pass') +- pass_leaf.set_prefix(orig_meta_prefix) +- node.append_child(pass_leaf) +- node.append_child(Leaf(token.NEWLINE, '\n')) +- +- elif len(suite.children) > 1 and \ +- (suite.children[-2].type == token.INDENT and +- suite.children[-1].type == token.DEDENT): +- # there was only one line in the class body and it was __metaclass__ +- pass_leaf = Leaf(text_type, 'pass') +- suite.insert_child(-1, pass_leaf) +- suite.insert_child(-1, Leaf(token.NEWLINE, '\n')) +diff -r 531f2e948299 lib2to3/fixes/fix_methodattrs.py +--- a/lib2to3/fixes/fix_methodattrs.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,23 +0,0 @@ +-"""Fix bound method attributes (method.im_? -> method.__?__). +-""" +-# Author: Christian Heimes +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name +- +-MAP = { +- "im_func" : "__func__", +- "im_self" : "__self__", +- "im_class" : "__self__.__class__" +- } +- +-class FixMethodattrs(fixer_base.BaseFix): +- PATTERN = """ +- power< any+ trailer< '.' attr=('im_func' | 'im_self' | 'im_class') > any* > +- """ +- +- def transform(self, node, results): +- attr = results["attr"][0] +- new = MAP[attr.value] +- attr.replace(Name(new, prefix=attr.get_prefix())) +diff -r 531f2e948299 lib2to3/fixes/fix_ne.py +--- a/lib2to3/fixes/fix_ne.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,22 +0,0 @@ +-# Copyright 2006 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer that turns <> into !=.""" +- +-# Local imports +-from .. import pytree +-from ..pgen2 import token +-from .. import fixer_base +- +- +-class FixNe(fixer_base.BaseFix): +- # This is so simple that we don't need the pattern compiler. +- +- def match(self, node): +- # Override +- return node.type == token.NOTEQUAL and node.value == "<>" +- +- def transform(self, node, results): +- new = pytree.Leaf(token.NOTEQUAL, "!=") +- new.set_prefix(node.get_prefix()) +- return new +diff -r 531f2e948299 lib2to3/fixes/fix_next.py +--- a/lib2to3/fixes/fix_next.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,103 +0,0 @@ +-"""Fixer for it.next() -> next(it), per PEP 3114.""" +-# Author: Collin Winter +- +-# Things that currently aren't covered: +-# - listcomp "next" names aren't warned +-# - "with" statement targets aren't checked +- +-# Local imports +-from ..pgen2 import token +-from ..pygram import python_symbols as syms +-from .. import fixer_base +-from ..fixer_util import Name, Call, find_binding +- +-bind_warning = "Calls to builtin next() possibly shadowed by global binding" +- +- +-class FixNext(fixer_base.BaseFix): +- PATTERN = """ +- power< base=any+ trailer< '.' attr='next' > trailer< '(' ')' > > +- | +- power< head=any+ trailer< '.' attr='next' > not trailer< '(' ')' > > +- | +- classdef< 'class' any+ ':' +- suite< any* +- funcdef< 'def' +- name='next' +- parameters< '(' NAME ')' > any+ > +- any* > > +- | +- global=global_stmt< 'global' any* 'next' any* > +- """ +- +- order = "pre" # Pre-order tree traversal +- +- def start_tree(self, tree, filename): +- super(FixNext, self).start_tree(tree, filename) +- +- n = find_binding('next', tree) +- if n: +- self.warning(n, bind_warning) +- self.shadowed_next = True +- else: +- self.shadowed_next = False +- +- def transform(self, node, results): +- assert results +- +- base = results.get("base") +- attr = results.get("attr") +- name = results.get("name") +- mod = results.get("mod") +- +- if base: +- if self.shadowed_next: +- attr.replace(Name("__next__", prefix=attr.get_prefix())) +- else: +- base = [n.clone() for n in base] +- base[0].set_prefix("") +- node.replace(Call(Name("next", prefix=node.get_prefix()), base)) +- elif name: +- n = Name("__next__", prefix=name.get_prefix()) +- name.replace(n) +- elif attr: +- # We don't do this transformation if we're assigning to "x.next". +- # Unfortunately, it doesn't seem possible to do this in PATTERN, +- # so it's being done here. +- if is_assign_target(node): +- head = results["head"] +- if "".join([str(n) for n in head]).strip() == '__builtin__': +- self.warning(node, bind_warning) +- return +- attr.replace(Name("__next__")) +- elif "global" in results: +- self.warning(node, bind_warning) +- self.shadowed_next = True +- +- +-### The following functions help test if node is part of an assignment +-### target. +- +-def is_assign_target(node): +- assign = find_assign(node) +- if assign is None: +- return False +- +- for child in assign.children: +- if child.type == token.EQUAL: +- return False +- elif is_subtree(child, node): +- return True +- return False +- +-def find_assign(node): +- if node.type == syms.expr_stmt: +- return node +- if node.type == syms.simple_stmt or node.parent is None: +- return None +- return find_assign(node.parent) +- +-def is_subtree(root, node): +- if root == node: +- return True +- return any([is_subtree(c, node) for c in root.children]) +diff -r 531f2e948299 lib2to3/fixes/fix_nonzero.py +--- a/lib2to3/fixes/fix_nonzero.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,20 +0,0 @@ +-"""Fixer for __nonzero__ -> __bool__ methods.""" +-# Author: Collin Winter +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name, syms +- +-class FixNonzero(fixer_base.BaseFix): +- PATTERN = """ +- classdef< 'class' any+ ':' +- suite< any* +- funcdef< 'def' name='__nonzero__' +- parameters< '(' NAME ')' > any+ > +- any* > > +- """ +- +- def transform(self, node, results): +- name = results["name"] +- new = Name("__bool__", prefix=name.get_prefix()) +- name.replace(new) +diff -r 531f2e948299 lib2to3/fixes/fix_numliterals.py +--- a/lib2to3/fixes/fix_numliterals.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,27 +0,0 @@ +-"""Fixer that turns 1L into 1, 0755 into 0o755. +-""" +-# Copyright 2007 Georg Brandl. +-# Licensed to PSF under a Contributor Agreement. +- +-# Local imports +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Number +- +- +-class FixNumliterals(fixer_base.BaseFix): +- # This is so simple that we don't need the pattern compiler. +- +- def match(self, node): +- # Override +- return (node.type == token.NUMBER and +- (node.value.startswith("0") or node.value[-1] in "Ll")) +- +- def transform(self, node, results): +- val = node.value +- if val[-1] in 'Ll': +- val = val[:-1] +- elif val.startswith('0') and val.isdigit() and len(set(val)) > 1: +- val = "0o" + val[1:] +- +- return Number(val, prefix=node.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/fix_paren.py +--- a/lib2to3/fixes/fix_paren.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,42 +0,0 @@ +-"""Fixer that addes parentheses where they are required +- +-This converts ``[x for x in 1, 2]`` to ``[x for x in (1, 2)]``.""" +- +-# By Taek Joo Kim and Benjamin Peterson +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import LParen, RParen +- +-# XXX This doesn't support nested for loops like [x for x in 1, 2 for x in 1, 2] +-class FixParen(fixer_base.BaseFix): +- PATTERN = """ +- atom< ('[' | '(') +- (listmaker< any +- comp_for< +- 'for' NAME 'in' +- target=testlist_safe< any (',' any)+ [','] +- > +- [any] +- > +- > +- | +- testlist_gexp< any +- comp_for< +- 'for' NAME 'in' +- target=testlist_safe< any (',' any)+ [','] +- > +- [any] +- > +- >) +- (']' | ')') > +- """ +- +- def transform(self, node, results): +- target = results["target"] +- +- lparen = LParen() +- lparen.set_prefix(target.get_prefix()) +- target.set_prefix("") # Make it hug the parentheses +- target.insert_child(0, lparen) +- target.append_child(RParen()) +diff -r 531f2e948299 lib2to3/fixes/fix_print.py +--- a/lib2to3/fixes/fix_print.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,90 +0,0 @@ +-# Copyright 2006 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for print. +- +-Change: +- 'print' into 'print()' +- 'print ...' into 'print(...)' +- 'print ... ,' into 'print(..., end=" ")' +- 'print >>x, ...' into 'print(..., file=x)' +- +-No changes are applied if print_function is imported from __future__ +- +-""" +- +-# Local imports +-from .. import patcomp +-from .. import pytree +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Name, Call, Comma, String, is_tuple +- +- +-parend_expr = patcomp.compile_pattern( +- """atom< '(' [atom|STRING|NAME] ')' >""" +- ) +- +- +-class FixPrint(fixer_base.ConditionalFix): +- +- PATTERN = """ +- simple_stmt< any* bare='print' any* > | print_stmt +- """ +- +- skip_on = '__future__.print_function' +- +- def transform(self, node, results): +- assert results +- +- if self.should_skip(node): +- return +- +- bare_print = results.get("bare") +- +- if bare_print: +- # Special-case print all by itself +- bare_print.replace(Call(Name("print"), [], +- prefix=bare_print.get_prefix())) +- return +- assert node.children[0] == Name("print") +- args = node.children[1:] +- if len(args) == 1 and parend_expr.match(args[0]): +- # We don't want to keep sticking parens around an +- # already-parenthesised expression. +- return +- +- sep = end = file = None +- if args and args[-1] == Comma(): +- args = args[:-1] +- end = " " +- if args and args[0] == pytree.Leaf(token.RIGHTSHIFT, ">>"): +- assert len(args) >= 2 +- file = args[1].clone() +- args = args[3:] # Strip a possible comma after the file expression +- # Now synthesize a print(args, sep=..., end=..., file=...) node. +- l_args = [arg.clone() for arg in args] +- if l_args: +- l_args[0].set_prefix("") +- if sep is not None or end is not None or file is not None: +- if sep is not None: +- self.add_kwarg(l_args, "sep", String(repr(sep))) +- if end is not None: +- self.add_kwarg(l_args, "end", String(repr(end))) +- if file is not None: +- self.add_kwarg(l_args, "file", file) +- n_stmt = Call(Name("print"), l_args) +- n_stmt.set_prefix(node.get_prefix()) +- return n_stmt +- +- def add_kwarg(self, l_nodes, s_kwd, n_expr): +- # XXX All this prefix-setting may lose comments (though rarely) +- n_expr.set_prefix("") +- n_argument = pytree.Node(self.syms.argument, +- (Name(s_kwd), +- pytree.Leaf(token.EQUAL, "="), +- n_expr)) +- if l_nodes: +- l_nodes.append(Comma()) +- n_argument.set_prefix(" ") +- l_nodes.append(n_argument) +diff -r 531f2e948299 lib2to3/fixes/fix_raise.py +--- a/lib2to3/fixes/fix_raise.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,82 +0,0 @@ +-"""Fixer for 'raise E, V, T' +- +-raise -> raise +-raise E -> raise E +-raise E, V -> raise E(V) +-raise E, V, T -> raise E(V).with_traceback(T) +- +-raise (((E, E'), E''), E'''), V -> raise E(V) +-raise "foo", V, T -> warns about string exceptions +- +- +-CAVEATS: +-1) "raise E, V" will be incorrectly translated if V is an exception +- instance. The correct Python 3 idiom is +- +- raise E from V +- +- but since we can't detect instance-hood by syntax alone and since +- any client code would have to be changed as well, we don't automate +- this. +-""" +-# Author: Collin Winter +- +-# Local imports +-from .. import pytree +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Name, Call, Attr, ArgList, is_tuple +- +-class FixRaise(fixer_base.BaseFix): +- +- PATTERN = """ +- raise_stmt< 'raise' exc=any [',' val=any [',' tb=any]] > +- """ +- +- def transform(self, node, results): +- syms = self.syms +- +- exc = results["exc"].clone() +- if exc.type is token.STRING: +- self.cannot_convert(node, "Python 3 does not support string exceptions") +- return +- +- # Python 2 supports +- # raise ((((E1, E2), E3), E4), E5), V +- # as a synonym for +- # raise E1, V +- # Since Python 3 will not support this, we recurse down any tuple +- # literals, always taking the first element. +- if is_tuple(exc): +- while is_tuple(exc): +- # exc.children[1:-1] is the unparenthesized tuple +- # exc.children[1].children[0] is the first element of the tuple +- exc = exc.children[1].children[0].clone() +- exc.set_prefix(" ") +- +- if "val" not in results: +- # One-argument raise +- new = pytree.Node(syms.raise_stmt, [Name("raise"), exc]) +- new.set_prefix(node.get_prefix()) +- return new +- +- val = results["val"].clone() +- if is_tuple(val): +- args = [c.clone() for c in val.children[1:-1]] +- else: +- val.set_prefix("") +- args = [val] +- +- if "tb" in results: +- tb = results["tb"].clone() +- tb.set_prefix("") +- +- e = Call(exc, args) +- with_tb = Attr(e, Name('with_traceback')) + [ArgList([tb])] +- new = pytree.Node(syms.simple_stmt, [Name("raise")] + with_tb) +- new.set_prefix(node.get_prefix()) +- return new +- else: +- return pytree.Node(syms.raise_stmt, +- [Name("raise"), Call(exc, args)], +- prefix=node.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/fix_raw_input.py +--- a/lib2to3/fixes/fix_raw_input.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,16 +0,0 @@ +-"""Fixer that changes raw_input(...) into input(...).""" +-# Author: Andre Roberge +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name +- +-class FixRawInput(fixer_base.BaseFix): +- +- PATTERN = """ +- power< name='raw_input' trailer< '(' [any] ')' > any* > +- """ +- +- def transform(self, node, results): +- name = results["name"] +- name.replace(Name("input", prefix=name.get_prefix())) +diff -r 531f2e948299 lib2to3/fixes/fix_reduce.py +--- a/lib2to3/fixes/fix_reduce.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,33 +0,0 @@ +-# Copyright 2008 Armin Ronacher. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for reduce(). +- +-Makes sure reduce() is imported from the functools module if reduce is +-used in that module. +-""" +- +-from .. import pytree +-from .. import fixer_base +-from ..fixer_util import Name, Attr, touch_import +- +- +- +-class FixReduce(fixer_base.BaseFix): +- +- PATTERN = """ +- power< 'reduce' +- trailer< '(' +- arglist< ( +- (not(argument) any ',' +- not(argument +- > +- """ +- +- def transform(self, node, results): +- touch_import('functools', 'reduce', node) +diff -r 531f2e948299 lib2to3/fixes/fix_renames.py +--- a/lib2to3/fixes/fix_renames.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,69 +0,0 @@ +-"""Fix incompatible renames +- +-Fixes: +- * sys.maxint -> sys.maxsize +-""" +-# Author: Christian Heimes +-# based on Collin Winter's fix_import +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name, attr_chain +- +-MAPPING = {"sys": {"maxint" : "maxsize"}, +- } +-LOOKUP = {} +- +-def alternates(members): +- return "(" + "|".join(map(repr, members)) + ")" +- +- +-def build_pattern(): +- #bare = set() +- for module, replace in MAPPING.items(): +- for old_attr, new_attr in replace.items(): +- LOOKUP[(module, old_attr)] = new_attr +- #bare.add(module) +- #bare.add(old_attr) +- #yield """ +- # import_name< 'import' (module=%r +- # | dotted_as_names< any* module=%r any* >) > +- # """ % (module, module) +- yield """ +- import_from< 'from' module_name=%r 'import' +- ( attr_name=%r | import_as_name< attr_name=%r 'as' any >) > +- """ % (module, old_attr, old_attr) +- yield """ +- power< module_name=%r trailer< '.' attr_name=%r > any* > +- """ % (module, old_attr) +- #yield """bare_name=%s""" % alternates(bare) +- +- +-class FixRenames(fixer_base.BaseFix): +- PATTERN = "|".join(build_pattern()) +- +- order = "pre" # Pre-order tree traversal +- +- # Don't match the node if it's within another match +- def match(self, node): +- match = super(FixRenames, self).match +- results = match(node) +- if results: +- if any([match(obj) for obj in attr_chain(node, "parent")]): +- return False +- return results +- return False +- +- #def start_tree(self, tree, filename): +- # super(FixRenames, self).start_tree(tree, filename) +- # self.replace = {} +- +- def transform(self, node, results): +- mod_name = results.get("module_name") +- attr_name = results.get("attr_name") +- #bare_name = results.get("bare_name") +- #import_mod = results.get("module") +- +- if mod_name and attr_name: +- new_attr = LOOKUP[(mod_name.value, attr_name.value)] +- attr_name.replace(Name(new_attr, prefix=attr_name.get_prefix())) +diff -r 531f2e948299 lib2to3/fixes/fix_repr.py +--- a/lib2to3/fixes/fix_repr.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,22 +0,0 @@ +-# Copyright 2006 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer that transforms `xyzzy` into repr(xyzzy).""" +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Call, Name, parenthesize +- +- +-class FixRepr(fixer_base.BaseFix): +- +- PATTERN = """ +- atom < '`' expr=any '`' > +- """ +- +- def transform(self, node, results): +- expr = results["expr"].clone() +- +- if expr.type == self.syms.testlist1: +- expr = parenthesize(expr) +- return Call(Name("repr"), [expr], prefix=node.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/fix_set_literal.py +--- a/lib2to3/fixes/fix_set_literal.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,52 +0,0 @@ +-""" +-Optional fixer to transform set() calls to set literals. +-""" +- +-# Author: Benjamin Peterson +- +-from lib2to3 import fixer_base, pytree +-from lib2to3.fixer_util import token, syms +- +- +- +-class FixSetLiteral(fixer_base.BaseFix): +- +- explicit = True +- +- PATTERN = """power< 'set' trailer< '(' +- (atom=atom< '[' (items=listmaker< any ((',' any)* [',']) > +- | +- single=any) ']' > +- | +- atom< '(' items=testlist_gexp< any ((',' any)* [',']) > ')' > +- ) +- ')' > > +- """ +- +- def transform(self, node, results): +- single = results.get("single") +- if single: +- # Make a fake listmaker +- fake = pytree.Node(syms.listmaker, [single.clone()]) +- single.replace(fake) +- items = fake +- else: +- items = results["items"] +- +- # Build the contents of the literal +- literal = [pytree.Leaf(token.LBRACE, "{")] +- literal.extend(n.clone() for n in items.children) +- literal.append(pytree.Leaf(token.RBRACE, "}")) +- # Set the prefix of the right brace to that of the ')' or ']' +- literal[-1].set_prefix(items.next_sibling.get_prefix()) +- maker = pytree.Node(syms.dictsetmaker, literal) +- maker.set_prefix(node.get_prefix()) +- +- # If the original was a one tuple, we need to remove the extra comma. +- if len(maker.children) == 4: +- n = maker.children[2] +- n.remove() +- maker.children[-1].set_prefix(n.get_prefix()) +- +- # Finally, replace the set call with our shiny new literal. +- return maker +diff -r 531f2e948299 lib2to3/fixes/fix_standarderror.py +--- a/lib2to3/fixes/fix_standarderror.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,18 +0,0 @@ +-# Copyright 2007 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for StandardError -> Exception.""" +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name +- +- +-class FixStandarderror(fixer_base.BaseFix): +- +- PATTERN = """ +- 'StandardError' +- """ +- +- def transform(self, node, results): +- return Name("Exception", prefix=node.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/fix_sys_exc.py +--- a/lib2to3/fixes/fix_sys_exc.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,29 +0,0 @@ +-"""Fixer for sys.exc_{type, value, traceback} +- +-sys.exc_type -> sys.exc_info()[0] +-sys.exc_value -> sys.exc_info()[1] +-sys.exc_traceback -> sys.exc_info()[2] +-""" +- +-# By Jeff Balogh and Benjamin Peterson +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Attr, Call, Name, Number, Subscript, Node, syms +- +-class FixSysExc(fixer_base.BaseFix): +- # This order matches the ordering of sys.exc_info(). +- exc_info = ["exc_type", "exc_value", "exc_traceback"] +- PATTERN = """ +- power< 'sys' trailer< dot='.' attribute=(%s) > > +- """ % '|'.join("'%s'" % e for e in exc_info) +- +- def transform(self, node, results): +- sys_attr = results["attribute"][0] +- index = Number(self.exc_info.index(sys_attr.value)) +- +- call = Call(Name("exc_info"), prefix=sys_attr.get_prefix()) +- attr = Attr(Name("sys"), call) +- attr[1].children[0].set_prefix(results["dot"].get_prefix()) +- attr.append(Subscript(index)) +- return Node(syms.power, attr, prefix=node.get_prefix()) +diff -r 531f2e948299 lib2to3/fixes/fix_throw.py +--- a/lib2to3/fixes/fix_throw.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,56 +0,0 @@ +-"""Fixer for generator.throw(E, V, T). +- +-g.throw(E) -> g.throw(E) +-g.throw(E, V) -> g.throw(E(V)) +-g.throw(E, V, T) -> g.throw(E(V).with_traceback(T)) +- +-g.throw("foo"[, V[, T]]) will warn about string exceptions.""" +-# Author: Collin Winter +- +-# Local imports +-from .. import pytree +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Name, Call, ArgList, Attr, is_tuple +- +-class FixThrow(fixer_base.BaseFix): +- +- PATTERN = """ +- power< any trailer< '.' 'throw' > +- trailer< '(' args=arglist< exc=any ',' val=any [',' tb=any] > ')' > +- > +- | +- power< any trailer< '.' 'throw' > trailer< '(' exc=any ')' > > +- """ +- +- def transform(self, node, results): +- syms = self.syms +- +- exc = results["exc"].clone() +- if exc.type is token.STRING: +- self.cannot_convert(node, "Python 3 does not support string exceptions") +- return +- +- # Leave "g.throw(E)" alone +- val = results.get("val") +- if val is None: +- return +- +- val = val.clone() +- if is_tuple(val): +- args = [c.clone() for c in val.children[1:-1]] +- else: +- val.set_prefix("") +- args = [val] +- +- throw_args = results["args"] +- +- if "tb" in results: +- tb = results["tb"].clone() +- tb.set_prefix("") +- +- e = Call(exc, args) +- with_tb = Attr(e, Name('with_traceback')) + [ArgList([tb])] +- throw_args.replace(pytree.Node(syms.power, with_tb)) +- else: +- throw_args.replace(Call(exc, args)) +diff -r 531f2e948299 lib2to3/fixes/fix_tuple_params.py +--- a/lib2to3/fixes/fix_tuple_params.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,169 +0,0 @@ +-"""Fixer for function definitions with tuple parameters. +- +-def func(((a, b), c), d): +- ... +- +- -> +- +-def func(x, d): +- ((a, b), c) = x +- ... +- +-It will also support lambdas: +- +- lambda (x, y): x + y -> lambda t: t[0] + t[1] +- +- # The parens are a syntax error in Python 3 +- lambda (x): x + y -> lambda x: x + y +-""" +-# Author: Collin Winter +- +-# Local imports +-from .. import pytree +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Assign, Name, Newline, Number, Subscript, syms +- +-def is_docstring(stmt): +- return isinstance(stmt, pytree.Node) and \ +- stmt.children[0].type == token.STRING +- +-class FixTupleParams(fixer_base.BaseFix): +- PATTERN = """ +- funcdef< 'def' any parameters< '(' args=any ')' > +- ['->' any] ':' suite=any+ > +- | +- lambda= +- lambdef< 'lambda' args=vfpdef< '(' inner=any ')' > +- ':' body=any +- > +- """ +- +- def transform(self, node, results): +- if "lambda" in results: +- return self.transform_lambda(node, results) +- +- new_lines = [] +- suite = results["suite"] +- args = results["args"] +- # This crap is so "def foo(...): x = 5; y = 7" is handled correctly. +- # TODO(cwinter): suite-cleanup +- if suite[0].children[1].type == token.INDENT: +- start = 2 +- indent = suite[0].children[1].value +- end = Newline() +- else: +- start = 0 +- indent = "; " +- end = pytree.Leaf(token.INDENT, "") +- +- # We need access to self for new_name(), and making this a method +- # doesn't feel right. Closing over self and new_lines makes the +- # code below cleaner. +- def handle_tuple(tuple_arg, add_prefix=False): +- n = Name(self.new_name()) +- arg = tuple_arg.clone() +- arg.set_prefix("") +- stmt = Assign(arg, n.clone()) +- if add_prefix: +- n.set_prefix(" ") +- tuple_arg.replace(n) +- new_lines.append(pytree.Node(syms.simple_stmt, +- [stmt, end.clone()])) +- +- if args.type == syms.tfpdef: +- handle_tuple(args) +- elif args.type == syms.typedargslist: +- for i, arg in enumerate(args.children): +- if arg.type == syms.tfpdef: +- # Without add_prefix, the emitted code is correct, +- # just ugly. +- handle_tuple(arg, add_prefix=(i > 0)) +- +- if not new_lines: +- return node +- +- # This isn't strictly necessary, but it plays nicely with other fixers. +- # TODO(cwinter) get rid of this when children becomes a smart list +- for line in new_lines: +- line.parent = suite[0] +- +- # TODO(cwinter) suite-cleanup +- after = start +- if start == 0: +- new_lines[0].set_prefix(" ") +- elif is_docstring(suite[0].children[start]): +- new_lines[0].set_prefix(indent) +- after = start + 1 +- +- suite[0].children[after:after] = new_lines +- for i in range(after+1, after+len(new_lines)+1): +- suite[0].children[i].set_prefix(indent) +- suite[0].changed() +- +- def transform_lambda(self, node, results): +- args = results["args"] +- body = results["body"] +- inner = simplify_args(results["inner"]) +- +- # Replace lambda ((((x)))): x with lambda x: x +- if inner.type == token.NAME: +- inner = inner.clone() +- inner.set_prefix(" ") +- args.replace(inner) +- return +- +- params = find_params(args) +- to_index = map_to_index(params) +- tup_name = self.new_name(tuple_name(params)) +- +- new_param = Name(tup_name, prefix=" ") +- args.replace(new_param.clone()) +- for n in body.post_order(): +- if n.type == token.NAME and n.value in to_index: +- subscripts = [c.clone() for c in to_index[n.value]] +- new = pytree.Node(syms.power, +- [new_param.clone()] + subscripts) +- new.set_prefix(n.get_prefix()) +- n.replace(new) +- +- +-### Helper functions for transform_lambda() +- +-def simplify_args(node): +- if node.type in (syms.vfplist, token.NAME): +- return node +- elif node.type == syms.vfpdef: +- # These look like vfpdef< '(' x ')' > where x is NAME +- # or another vfpdef instance (leading to recursion). +- while node.type == syms.vfpdef: +- node = node.children[1] +- return node +- raise RuntimeError("Received unexpected node %s" % node) +- +-def find_params(node): +- if node.type == syms.vfpdef: +- return find_params(node.children[1]) +- elif node.type == token.NAME: +- return node.value +- return [find_params(c) for c in node.children if c.type != token.COMMA] +- +-def map_to_index(param_list, prefix=[], d=None): +- if d is None: +- d = {} +- for i, obj in enumerate(param_list): +- trailer = [Subscript(Number(i))] +- if isinstance(obj, list): +- map_to_index(obj, trailer, d=d) +- else: +- d[obj] = prefix + trailer +- return d +- +-def tuple_name(param_list): +- l = [] +- for obj in param_list: +- if isinstance(obj, list): +- l.append(tuple_name(obj)) +- else: +- l.append(obj) +- return "_".join(l) +diff -r 531f2e948299 lib2to3/fixes/fix_types.py +--- a/lib2to3/fixes/fix_types.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,62 +0,0 @@ +-# Copyright 2007 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer for removing uses of the types module. +- +-These work for only the known names in the types module. The forms above +-can include types. or not. ie, It is assumed the module is imported either as: +- +- import types +- from types import ... # either * or specific types +- +-The import statements are not modified. +- +-There should be another fixer that handles at least the following constants: +- +- type([]) -> list +- type(()) -> tuple +- type('') -> str +- +-""" +- +-# Local imports +-from ..pgen2 import token +-from .. import fixer_base +-from ..fixer_util import Name +- +-_TYPE_MAPPING = { +- 'BooleanType' : 'bool', +- 'BufferType' : 'memoryview', +- 'ClassType' : 'type', +- 'ComplexType' : 'complex', +- 'DictType': 'dict', +- 'DictionaryType' : 'dict', +- 'EllipsisType' : 'type(Ellipsis)', +- #'FileType' : 'io.IOBase', +- 'FloatType': 'float', +- 'IntType': 'int', +- 'ListType': 'list', +- 'LongType': 'int', +- 'ObjectType' : 'object', +- 'NoneType': 'type(None)', +- 'NotImplementedType' : 'type(NotImplemented)', +- 'SliceType' : 'slice', +- 'StringType': 'bytes', # XXX ? +- 'StringTypes' : 'str', # XXX ? +- 'TupleType': 'tuple', +- 'TypeType' : 'type', +- 'UnicodeType': 'str', +- 'XRangeType' : 'range', +- } +- +-_pats = ["power< 'types' trailer< '.' name='%s' > >" % t for t in _TYPE_MAPPING] +- +-class FixTypes(fixer_base.BaseFix): +- +- PATTERN = '|'.join(_pats) +- +- def transform(self, node, results): +- new_value = _TYPE_MAPPING.get(results["name"].value) +- if new_value: +- return Name(new_value, prefix=node.get_prefix()) +- return None +diff -r 531f2e948299 lib2to3/fixes/fix_unicode.py +--- a/lib2to3/fixes/fix_unicode.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,28 +0,0 @@ +-"""Fixer that changes unicode to str, unichr to chr, and u"..." into "...". +- +-""" +- +-import re +-from ..pgen2 import token +-from .. import fixer_base +- +-class FixUnicode(fixer_base.BaseFix): +- +- PATTERN = "STRING | NAME<'unicode' | 'unichr'>" +- +- def transform(self, node, results): +- if node.type == token.NAME: +- if node.value == "unicode": +- new = node.clone() +- new.value = "str" +- return new +- if node.value == "unichr": +- new = node.clone() +- new.value = "chr" +- return new +- # XXX Warn when __unicode__ found? +- elif node.type == token.STRING: +- if re.match(r"[uU][rR]?[\'\"]", node.value): +- new = node.clone() +- new.value = new.value[1:] +- return new +diff -r 531f2e948299 lib2to3/fixes/fix_urllib.py +--- a/lib2to3/fixes/fix_urllib.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,180 +0,0 @@ +-"""Fix changes imports of urllib which are now incompatible. +- This is rather similar to fix_imports, but because of the more +- complex nature of the fixing for urllib, it has its own fixer. +-""" +-# Author: Nick Edds +- +-# Local imports +-from .fix_imports import alternates, FixImports +-from .. import fixer_base +-from ..fixer_util import Name, Comma, FromImport, Newline, attr_chain +- +-MAPPING = {'urllib': [ +- ('urllib.request', +- ['URLOpener', 'FancyURLOpener', 'urlretrieve', +- '_urlopener', 'urlcleanup']), +- ('urllib.parse', +- ['quote', 'quote_plus', 'unquote', 'unquote_plus', +- 'urlencode', 'pathname2url', 'url2pathname', 'splitattr', +- 'splithost', 'splitnport', 'splitpasswd', 'splitport', +- 'splitquery', 'splittag', 'splittype', 'splituser', +- 'splitvalue', ]), +- ('urllib.error', +- ['ContentTooShortError'])], +- 'urllib2' : [ +- ('urllib.request', +- ['urlopen', 'install_opener', 'build_opener', +- 'Request', 'OpenerDirector', 'BaseHandler', +- 'HTTPDefaultErrorHandler', 'HTTPRedirectHandler', +- 'HTTPCookieProcessor', 'ProxyHandler', +- 'HTTPPasswordMgr', +- 'HTTPPasswordMgrWithDefaultRealm', +- 'AbstractBasicAuthHandler', +- 'HTTPBasicAuthHandler', 'ProxyBasicAuthHandler', +- 'AbstractDigestAuthHandler', +- 'HTTPDigestAuthHandler', 'ProxyDigestAuthHandler', +- 'HTTPHandler', 'HTTPSHandler', 'FileHandler', +- 'FTPHandler', 'CacheFTPHandler', +- 'UnknownHandler']), +- ('urllib.error', +- ['URLError', 'HTTPError']), +- ] +-} +- +-# Duplicate the url parsing functions for urllib2. +-MAPPING["urllib2"].append(MAPPING["urllib"][1]) +- +- +-def build_pattern(): +- bare = set() +- for old_module, changes in MAPPING.items(): +- for change in changes: +- new_module, members = change +- members = alternates(members) +- yield """import_name< 'import' (module=%r +- | dotted_as_names< any* module=%r any* >) > +- """ % (old_module, old_module) +- yield """import_from< 'from' mod_member=%r 'import' +- ( member=%s | import_as_name< member=%s 'as' any > | +- import_as_names< members=any* >) > +- """ % (old_module, members, members) +- yield """import_from< 'from' module_star=%r 'import' star='*' > +- """ % old_module +- yield """import_name< 'import' +- dotted_as_name< module_as=%r 'as' any > > +- """ % old_module +- yield """power< module_dot=%r trailer< '.' member=%s > any* > +- """ % (old_module, members) +- +- +-class FixUrllib(FixImports): +- +- def build_pattern(self): +- return "|".join(build_pattern()) +- +- def transform_import(self, node, results): +- """Transform for the basic import case. Replaces the old +- import name with a comma separated list of its +- replacements. +- """ +- import_mod = results.get('module') +- pref = import_mod.get_prefix() +- +- names = [] +- +- # create a Node list of the replacement modules +- for name in MAPPING[import_mod.value][:-1]: +- names.extend([Name(name[0], prefix=pref), Comma()]) +- names.append(Name(MAPPING[import_mod.value][-1][0], prefix=pref)) +- import_mod.replace(names) +- +- def transform_member(self, node, results): +- """Transform for imports of specific module elements. Replaces +- the module to be imported from with the appropriate new +- module. +- """ +- mod_member = results.get('mod_member') +- pref = mod_member.get_prefix() +- member = results.get('member') +- +- # Simple case with only a single member being imported +- if member: +- # this may be a list of length one, or just a node +- if isinstance(member, list): +- member = member[0] +- new_name = None +- for change in MAPPING[mod_member.value]: +- if member.value in change[1]: +- new_name = change[0] +- break +- if new_name: +- mod_member.replace(Name(new_name, prefix=pref)) +- else: +- self.cannot_convert(node, +- 'This is an invalid module element') +- +- # Multiple members being imported +- else: +- # a dictionary for replacements, order matters +- modules = [] +- mod_dict = {} +- members = results.get('members') +- for member in members: +- member = member.value +- # we only care about the actual members +- if member != ',': +- for change in MAPPING[mod_member.value]: +- if member in change[1]: +- if change[0] in mod_dict: +- mod_dict[change[0]].append(member) +- else: +- mod_dict[change[0]] = [member] +- modules.append(change[0]) +- +- new_nodes = [] +- for module in modules: +- elts = mod_dict[module] +- names = [] +- for elt in elts[:-1]: +- names.extend([Name(elt, prefix=pref), Comma()]) +- names.append(Name(elts[-1], prefix=pref)) +- new_nodes.append(FromImport(module, names)) +- if new_nodes: +- nodes = [] +- for new_node in new_nodes[:-1]: +- nodes.extend([new_node, Newline()]) +- nodes.append(new_nodes[-1]) +- node.replace(nodes) +- else: +- self.cannot_convert(node, 'All module elements are invalid') +- +- def transform_dot(self, node, results): +- """Transform for calls to module members in code.""" +- module_dot = results.get('module_dot') +- member = results.get('member') +- # this may be a list of length one, or just a node +- if isinstance(member, list): +- member = member[0] +- new_name = None +- for change in MAPPING[module_dot.value]: +- if member.value in change[1]: +- new_name = change[0] +- break +- if new_name: +- module_dot.replace(Name(new_name, +- prefix=module_dot.get_prefix())) +- else: +- self.cannot_convert(node, 'This is an invalid module element') +- +- def transform(self, node, results): +- if results.get('module'): +- self.transform_import(node, results) +- elif results.get('mod_member'): +- self.transform_member(node, results) +- elif results.get('module_dot'): +- self.transform_dot(node, results) +- # Renaming and star imports are not supported for these modules. +- elif results.get('module_star'): +- self.cannot_convert(node, 'Cannot handle star imports.') +- elif results.get('module_as'): +- self.cannot_convert(node, 'This module is now multiple modules') +diff -r 531f2e948299 lib2to3/fixes/fix_ws_comma.py +--- a/lib2to3/fixes/fix_ws_comma.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,39 +0,0 @@ +-"""Fixer that changes 'a ,b' into 'a, b'. +- +-This also changes '{a :b}' into '{a: b}', but does not touch other +-uses of colons. It does not touch other uses of whitespace. +- +-""" +- +-from .. import pytree +-from ..pgen2 import token +-from .. import fixer_base +- +-class FixWsComma(fixer_base.BaseFix): +- +- explicit = True # The user must ask for this fixers +- +- PATTERN = """ +- any<(not(',') any)+ ',' ((not(',') any)+ ',')* [not(',') any]> +- """ +- +- COMMA = pytree.Leaf(token.COMMA, ",") +- COLON = pytree.Leaf(token.COLON, ":") +- SEPS = (COMMA, COLON) +- +- def transform(self, node, results): +- new = node.clone() +- comma = False +- for child in new.children: +- if child in self.SEPS: +- prefix = child.get_prefix() +- if prefix.isspace() and "\n" not in prefix: +- child.set_prefix("") +- comma = True +- else: +- if comma: +- prefix = child.get_prefix() +- if not prefix: +- child.set_prefix(" ") +- comma = False +- return new +diff -r 531f2e948299 lib2to3/fixes/fix_xrange.py +--- a/lib2to3/fixes/fix_xrange.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,64 +0,0 @@ +-# Copyright 2007 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Fixer that changes xrange(...) into range(...).""" +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name, Call, consuming_calls +-from .. import patcomp +- +- +-class FixXrange(fixer_base.BaseFix): +- +- PATTERN = """ +- power< +- (name='range'|name='xrange') trailer< '(' args=any ')' > +- rest=any* > +- """ +- +- def transform(self, node, results): +- name = results["name"] +- if name.value == "xrange": +- return self.transform_xrange(node, results) +- elif name.value == "range": +- return self.transform_range(node, results) +- else: +- raise ValueError(repr(name)) +- +- def transform_xrange(self, node, results): +- name = results["name"] +- name.replace(Name("range", prefix=name.get_prefix())) +- +- def transform_range(self, node, results): +- if not self.in_special_context(node): +- range_call = Call(Name("range"), [results["args"].clone()]) +- # Encase the range call in list(). +- list_call = Call(Name("list"), [range_call], +- prefix=node.get_prefix()) +- # Put things that were after the range() call after the list call. +- for n in results["rest"]: +- list_call.append_child(n) +- return list_call +- return node +- +- P1 = "power< func=NAME trailer< '(' node=any ')' > any* >" +- p1 = patcomp.compile_pattern(P1) +- +- P2 = """for_stmt< 'for' any 'in' node=any ':' any* > +- | comp_for< 'for' any 'in' node=any any* > +- | comparison< any 'in' node=any any*> +- """ +- p2 = patcomp.compile_pattern(P2) +- +- def in_special_context(self, node): +- if node.parent is None: +- return False +- results = {} +- if (node.parent.parent is not None and +- self.p1.match(node.parent.parent, results) and +- results["node"] is node): +- # list(d.keys()) -> list(d.keys()), etc. +- return results["func"].value in consuming_calls +- # for ... in d.iterkeys() -> for ... in d.keys(), etc. +- return self.p2.match(node.parent, results) and results["node"] is node +diff -r 531f2e948299 lib2to3/fixes/fix_xreadlines.py +--- a/lib2to3/fixes/fix_xreadlines.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,24 +0,0 @@ +-"""Fix "for x in f.xreadlines()" -> "for x in f". +- +-This fixer will also convert g(f.xreadlines) into g(f.__iter__).""" +-# Author: Collin Winter +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name +- +- +-class FixXreadlines(fixer_base.BaseFix): +- PATTERN = """ +- power< call=any+ trailer< '.' 'xreadlines' > trailer< '(' ')' > > +- | +- power< any+ trailer< '.' no_call='xreadlines' > > +- """ +- +- def transform(self, node, results): +- no_call = results.get("no_call") +- +- if no_call: +- no_call.replace(Name("__iter__", prefix=no_call.get_prefix())) +- else: +- node.replace([x.clone() for x in results["call"]]) +diff -r 531f2e948299 lib2to3/fixes/fix_zip.py +--- a/lib2to3/fixes/fix_zip.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,34 +0,0 @@ +-""" +-Fixer that changes zip(seq0, seq1, ...) into list(zip(seq0, seq1, ...) +-unless there exists a 'from future_builtins import zip' statement in the +-top-level namespace. +- +-We avoid the transformation if the zip() call is directly contained in +-iter(<>), list(<>), tuple(<>), sorted(<>), ...join(<>), or for V in <>:. +-""" +- +-# Local imports +-from .. import fixer_base +-from ..fixer_util import Name, Call, in_special_context +- +-class FixZip(fixer_base.ConditionalFix): +- +- PATTERN = """ +- power< 'zip' args=trailer< '(' [any] ')' > +- > +- """ +- +- skip_on = "future_builtins.zip" +- +- def transform(self, node, results): +- if self.should_skip(node): +- return +- +- if in_special_context(node): +- return None +- +- new = node.clone() +- new.set_prefix("") +- new = Call(Name("list"), [new]) +- new.set_prefix(node.get_prefix()) +- return new +diff -r 531f2e948299 lib2to3/main.py +--- a/lib2to3/main.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,133 +0,0 @@ +-""" +-Main program for 2to3. +-""" +- +-import sys +-import os +-import logging +-import shutil +-import optparse +- +-from . import refactor +- +- +-class StdoutRefactoringTool(refactor.RefactoringTool): +- """ +- Prints output to stdout. +- """ +- +- def __init__(self, fixers, options, explicit, nobackups): +- self.nobackups = nobackups +- super(StdoutRefactoringTool, self).__init__(fixers, options, explicit) +- +- def log_error(self, msg, *args, **kwargs): +- self.errors.append((msg, args, kwargs)) +- self.logger.error(msg, *args, **kwargs) +- +- def write_file(self, new_text, filename, old_text): +- if not self.nobackups: +- # Make backup +- backup = filename + ".bak" +- if os.path.lexists(backup): +- try: +- os.remove(backup) +- except os.error, err: +- self.log_message("Can't remove backup %s", backup) +- try: +- os.rename(filename, backup) +- except os.error, err: +- self.log_message("Can't rename %s to %s", filename, backup) +- # Actually write the new file +- super(StdoutRefactoringTool, self).write_file(new_text, +- filename, old_text) +- if not self.nobackups: +- shutil.copymode(backup, filename) +- +- def print_output(self, lines): +- for line in lines: +- print line +- +- +-def main(fixer_pkg, args=None): +- """Main program. +- +- Args: +- fixer_pkg: the name of a package where the fixers are located. +- args: optional; a list of command line arguments. If omitted, +- sys.argv[1:] is used. +- +- Returns a suggested exit status (0, 1, 2). +- """ +- # Set up option parser +- parser = optparse.OptionParser(usage="2to3 [options] file|dir ...") +- parser.add_option("-d", "--doctests_only", action="store_true", +- help="Fix up doctests only") +- parser.add_option("-f", "--fix", action="append", default=[], +- help="Each FIX specifies a transformation; default: all") +- parser.add_option("-x", "--nofix", action="append", default=[], +- help="Prevent a fixer from being run.") +- parser.add_option("-l", "--list-fixes", action="store_true", +- help="List available transformations (fixes/fix_*.py)") +- parser.add_option("-p", "--print-function", action="store_true", +- help="Modify the grammar so that print() is a function") +- parser.add_option("-v", "--verbose", action="store_true", +- help="More verbose logging") +- 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.") +- +- # Parse command line arguments +- refactor_stdin = False +- options, args = parser.parse_args(args) +- if not options.write and options.nobackups: +- parser.error("Can't use -n without -w") +- if options.list_fixes: +- print "Available transformations for the -f/--fix option:" +- for fixname in refactor.get_all_fix_names(fixer_pkg): +- print fixname +- if not args: +- return 0 +- if not args: +- print >>sys.stderr, "At least one file or directory argument required." +- print >>sys.stderr, "Use --help to show usage." +- return 2 +- if "-" in args: +- refactor_stdin = True +- if options.write: +- print >>sys.stderr, "Can't write to stdin." +- return 2 +- +- # Set up logging handler +- level = logging.DEBUG if options.verbose else logging.INFO +- logging.basicConfig(format='%(name)s: %(message)s', level=level) +- +- # Initialize the refactoring tool +- rt_opts = {"print_function" : options.print_function} +- avail_fixes = set(refactor.get_fixers_from_package(fixer_pkg)) +- unwanted_fixes = set(fixer_pkg + ".fix_" + fix for fix in options.nofix) +- explicit = set() +- if options.fix: +- all_present = False +- for fix in options.fix: +- if fix == "all": +- all_present = True +- else: +- explicit.add(fixer_pkg + ".fix_" + fix) +- requested = avail_fixes.union(explicit) if all_present else explicit +- else: +- requested = avail_fixes.union(explicit) +- fixer_names = requested.difference(unwanted_fixes) +- rt = StdoutRefactoringTool(sorted(fixer_names), rt_opts, sorted(explicit), +- options.nobackups) +- +- # Refactor all files and directories passed as arguments +- if not rt.errors: +- if refactor_stdin: +- rt.refactor_stdin() +- else: +- rt.refactor(args, options.write, options.doctests_only) +- rt.summarize() +- +- # Return error status (0 if rt.errors is zero) +- return int(bool(rt.errors)) +diff -r 531f2e948299 lib2to3/patcomp.py +--- a/lib2to3/patcomp.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,186 +0,0 @@ +-# Copyright 2006 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Pattern compiler. +- +-The grammer is taken from PatternGrammar.txt. +- +-The compiler compiles a pattern to a pytree.*Pattern instance. +-""" +- +-__author__ = "Guido van Rossum " +- +-# Python imports +-import os +- +-# Fairly local imports +-from .pgen2 import driver +-from .pgen2 import literals +-from .pgen2 import token +-from .pgen2 import tokenize +- +-# Really local imports +-from . import pytree +-from . import pygram +- +-# The pattern grammar file +-_PATTERN_GRAMMAR_FILE = os.path.join(os.path.dirname(__file__), +- "PatternGrammar.txt") +- +- +-def tokenize_wrapper(input): +- """Tokenizes a string suppressing significant whitespace.""" +- skip = set((token.NEWLINE, token.INDENT, token.DEDENT)) +- tokens = tokenize.generate_tokens(driver.generate_lines(input).next) +- for quintuple in tokens: +- type, value, start, end, line_text = quintuple +- if type not in skip: +- yield quintuple +- +- +-class PatternCompiler(object): +- +- def __init__(self, grammar_file=_PATTERN_GRAMMAR_FILE): +- """Initializer. +- +- Takes an optional alternative filename for the pattern grammar. +- """ +- self.grammar = driver.load_grammar(grammar_file) +- self.syms = pygram.Symbols(self.grammar) +- self.pygrammar = pygram.python_grammar +- self.pysyms = pygram.python_symbols +- self.driver = driver.Driver(self.grammar, convert=pattern_convert) +- +- def compile_pattern(self, input, debug=False): +- """Compiles a pattern string to a nested pytree.*Pattern object.""" +- tokens = tokenize_wrapper(input) +- root = self.driver.parse_tokens(tokens, debug=debug) +- return self.compile_node(root) +- +- def compile_node(self, node): +- """Compiles a node, recursively. +- +- This is one big switch on the node type. +- """ +- # XXX Optimize certain Wildcard-containing-Wildcard patterns +- # that can be merged +- if node.type == self.syms.Matcher: +- node = node.children[0] # Avoid unneeded recursion +- +- if node.type == self.syms.Alternatives: +- # Skip the odd children since they are just '|' tokens +- alts = [self.compile_node(ch) for ch in node.children[::2]] +- if len(alts) == 1: +- return alts[0] +- p = pytree.WildcardPattern([[a] for a in alts], min=1, max=1) +- return p.optimize() +- +- if node.type == self.syms.Alternative: +- units = [self.compile_node(ch) for ch in node.children] +- if len(units) == 1: +- return units[0] +- p = pytree.WildcardPattern([units], min=1, max=1) +- return p.optimize() +- +- if node.type == self.syms.NegatedUnit: +- pattern = self.compile_basic(node.children[1:]) +- p = pytree.NegatedPattern(pattern) +- return p.optimize() +- +- assert node.type == self.syms.Unit +- +- name = None +- nodes = node.children +- if len(nodes) >= 3 and nodes[1].type == token.EQUAL: +- name = nodes[0].value +- nodes = nodes[2:] +- repeat = None +- if len(nodes) >= 2 and nodes[-1].type == self.syms.Repeater: +- repeat = nodes[-1] +- nodes = nodes[:-1] +- +- # Now we've reduced it to: STRING | NAME [Details] | (...) | [...] +- pattern = self.compile_basic(nodes, repeat) +- +- if repeat is not None: +- assert repeat.type == self.syms.Repeater +- children = repeat.children +- child = children[0] +- if child.type == token.STAR: +- min = 0 +- max = pytree.HUGE +- elif child.type == token.PLUS: +- min = 1 +- max = pytree.HUGE +- elif child.type == token.LBRACE: +- assert children[-1].type == token.RBRACE +- assert len(children) in (3, 5) +- min = max = self.get_int(children[1]) +- if len(children) == 5: +- max = self.get_int(children[3]) +- else: +- assert False +- if min != 1 or max != 1: +- pattern = pattern.optimize() +- pattern = pytree.WildcardPattern([[pattern]], min=min, max=max) +- +- if name is not None: +- pattern.name = name +- return pattern.optimize() +- +- def compile_basic(self, nodes, repeat=None): +- # Compile STRING | NAME [Details] | (...) | [...] +- assert len(nodes) >= 1 +- node = nodes[0] +- if node.type == token.STRING: +- value = literals.evalString(node.value) +- return pytree.LeafPattern(content=value) +- elif node.type == token.NAME: +- value = node.value +- if value.isupper(): +- if value not in TOKEN_MAP: +- raise SyntaxError("Invalid token: %r" % value) +- return pytree.LeafPattern(TOKEN_MAP[value]) +- else: +- if value == "any": +- type = None +- elif not value.startswith("_"): +- type = getattr(self.pysyms, value, None) +- if type is None: +- raise SyntaxError("Invalid symbol: %r" % value) +- if nodes[1:]: # Details present +- content = [self.compile_node(nodes[1].children[1])] +- else: +- content = None +- return pytree.NodePattern(type, content) +- elif node.value == "(": +- return self.compile_node(nodes[1]) +- elif node.value == "[": +- assert repeat is None +- subpattern = self.compile_node(nodes[1]) +- return pytree.WildcardPattern([[subpattern]], min=0, max=1) +- assert False, node +- +- def get_int(self, node): +- assert node.type == token.NUMBER +- return int(node.value) +- +- +-# Map named tokens to the type value for a LeafPattern +-TOKEN_MAP = {"NAME": token.NAME, +- "STRING": token.STRING, +- "NUMBER": token.NUMBER, +- "TOKEN": None} +- +- +-def pattern_convert(grammar, raw_node_info): +- """Converts raw node information to a Node or Leaf instance.""" +- type, value, context, children = raw_node_info +- if children or type in grammar.number2symbol: +- return pytree.Node(type, children, context=context) +- else: +- return pytree.Leaf(type, value, context=context) +- +- +-def compile_pattern(pattern): +- return PatternCompiler().compile_pattern(pattern) +diff -r 531f2e948299 lib2to3/pgen2/.svn/all-wcprops +--- a/lib2to3/pgen2/.svn/all-wcprops Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,59 +0,0 @@ +-K 25 +-svn:wc:ra_dav:version-url +-V 57 +-/projects/!svn/ver/68340/sandbox/trunk/2to3/lib2to3/pgen2 +-END +-tokenize.py +-K 25 +-svn:wc:ra_dav:version-url +-V 69 +-/projects/!svn/ver/61441/sandbox/trunk/2to3/lib2to3/pgen2/tokenize.py +-END +-pgen.py +-K 25 +-svn:wc:ra_dav:version-url +-V 65 +-/projects/!svn/ver/61629/sandbox/trunk/2to3/lib2to3/pgen2/pgen.py +-END +-parse.py +-K 25 +-svn:wc:ra_dav:version-url +-V 66 +-/projects/!svn/ver/67389/sandbox/trunk/2to3/lib2to3/pgen2/parse.py +-END +-driver.py +-K 25 +-svn:wc:ra_dav:version-url +-V 67 +-/projects/!svn/ver/68340/sandbox/trunk/2to3/lib2to3/pgen2/driver.py +-END +-__init__.py +-K 25 +-svn:wc:ra_dav:version-url +-V 69 +-/projects/!svn/ver/61441/sandbox/trunk/2to3/lib2to3/pgen2/__init__.py +-END +-literals.py +-K 25 +-svn:wc:ra_dav:version-url +-V 69 +-/projects/!svn/ver/61441/sandbox/trunk/2to3/lib2to3/pgen2/literals.py +-END +-token.py +-K 25 +-svn:wc:ra_dav:version-url +-V 66 +-/projects/!svn/ver/61441/sandbox/trunk/2to3/lib2to3/pgen2/token.py +-END +-conv.py +-K 25 +-svn:wc:ra_dav:version-url +-V 65 +-/projects/!svn/ver/61441/sandbox/trunk/2to3/lib2to3/pgen2/conv.py +-END +-grammar.py +-K 25 +-svn:wc:ra_dav:version-url +-V 68 +-/projects/!svn/ver/61441/sandbox/trunk/2to3/lib2to3/pgen2/grammar.py +-END +diff -r 531f2e948299 lib2to3/pgen2/.svn/dir-prop-base +--- a/lib2to3/pgen2/.svn/dir-prop-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,8 +0,0 @@ +-K 10 +-svn:ignore +-V 13 +-*.pyc +-*.pyo +- +- +-END +diff -r 531f2e948299 lib2to3/pgen2/.svn/entries +--- a/lib2to3/pgen2/.svn/entries Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,334 +0,0 @@ +-9 +- +-dir +-70785 +-http://svn.python.org/projects/sandbox/trunk/2to3/lib2to3/pgen2 +-http://svn.python.org/projects +- +- +- +-2009-01-05T08:11:39.704315Z +-68340 +-georg.brandl +-has-props +- +-svn:special svn:externals svn:needs-lock +- +- +- +- +- +- +- +- +- +- +- +-6015fed2-1504-0410-9fe1-9d1591cc4771 +- +-tokenize.py +-file +- +- +- +- +-2009-03-31T00:29:32.000000Z +-06aea8121aa7b0fc71345d011813d4b4 +-2008-03-17T16:59:51.273602Z +-61441 +-martin.v.loewis +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-16184 +- +-pgen.py +-file +- +- +- +- +-2009-03-31T00:29:32.000000Z +-40f1eec8af5247a511bf6acc34eac994 +-2008-03-19T16:58:19.069158Z +-61629 +-collin.winter +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-13740 +- +-parse.py +-file +- +- +- +- +-2009-03-31T00:29:32.000000Z +-80c0ee069eab8de116e1c13572d6cd4b +-2008-11-25T23:13:17.968453Z +-67389 +-benjamin.peterson +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-8053 +- +-driver.py +-file +- +- +- +- +-2009-03-31T00:29:32.000000Z +-e2c063aca0163f8f47fefeab1a5cdff7 +-2009-01-05T08:11:39.704315Z +-68340 +-georg.brandl +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-4809 +- +-__init__.py +-file +- +- +- +- +-2009-03-31T00:29:32.000000Z +-5cb6bc9b6c96e165df87b615f2df9f1a +-2006-11-29T17:38:40.278528Z +-52858 +-guido.van.rossum +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-143 +- +-literals.py +-file +- +- +- +- +-2009-03-31T00:29:32.000000Z +-e3b1d03cade5fa0c3a1a5324e0b1e539 +-2006-11-29T17:38:40.278528Z +-52858 +-guido.van.rossum +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-1614 +- +-token.py +-file +- +- +- +- +-2009-03-31T00:29:32.000000Z +-8fd1f5c3fc2ad1b2afa7e17064b0ba04 +-2007-02-12T23:59:44.048119Z +-53758 +-collin.winter +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-1244 +- +-conv.py +-file +- +- +- +- +-2009-03-31T00:29:32.000000Z +-942a8910f37b9e5d202806ea05f7b2f1 +-2007-02-12T23:59:44.048119Z +-53758 +-collin.winter +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-9625 +- +-grammar.py +-file +- +- +- +- +-2009-03-31T00:29:32.000000Z +-612ee8e1a84660a7c44f7d5af3e7db69 +-2008-03-17T16:59:51.273602Z +-61441 +-martin.v.loewis +-has-props +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-4947 +- +diff -r 531f2e948299 lib2to3/pgen2/.svn/format +--- a/lib2to3/pgen2/.svn/format Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,1 +0,0 @@ +-9 +diff -r 531f2e948299 lib2to3/pgen2/.svn/prop-base/__init__.py.svn-base +--- a/lib2to3/pgen2/.svn/prop-base/__init__.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/pgen2/.svn/prop-base/conv.py.svn-base +--- a/lib2to3/pgen2/.svn/prop-base/conv.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/pgen2/.svn/prop-base/driver.py.svn-base +--- a/lib2to3/pgen2/.svn/prop-base/driver.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/pgen2/.svn/prop-base/grammar.py.svn-base +--- a/lib2to3/pgen2/.svn/prop-base/grammar.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/pgen2/.svn/prop-base/literals.py.svn-base +--- a/lib2to3/pgen2/.svn/prop-base/literals.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/pgen2/.svn/prop-base/parse.py.svn-base +--- a/lib2to3/pgen2/.svn/prop-base/parse.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/pgen2/.svn/prop-base/pgen.py.svn-base +--- a/lib2to3/pgen2/.svn/prop-base/pgen.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/pgen2/.svn/prop-base/token.py.svn-base +--- a/lib2to3/pgen2/.svn/prop-base/token.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,13 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 14 +-svn:executable +-V 1 +-* +-K 12 +-svn:keywords +-V 2 +-Id +-END +diff -r 531f2e948299 lib2to3/pgen2/.svn/prop-base/tokenize.py.svn-base +--- a/lib2to3/pgen2/.svn/prop-base/tokenize.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,9 +0,0 @@ +-K 13 +-svn:eol-style +-V 6 +-native +-K 12 +-svn:keywords +-V 23 +-Author Date Id Revision +-END +diff -r 531f2e948299 lib2to3/pgen2/.svn/text-base/__init__.py.svn-base +--- a/lib2to3/pgen2/.svn/text-base/__init__.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,4 +0,0 @@ +-# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""The pgen2 package.""" +diff -r 531f2e948299 lib2to3/pgen2/.svn/text-base/conv.py.svn-base +--- a/lib2to3/pgen2/.svn/text-base/conv.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,257 +0,0 @@ +-# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Convert graminit.[ch] spit out by pgen to Python code. +- +-Pgen is the Python parser generator. It is useful to quickly create a +-parser from a grammar file in Python's grammar notation. But I don't +-want my parsers to be written in C (yet), so I'm translating the +-parsing tables to Python data structures and writing a Python parse +-engine. +- +-Note that the token numbers are constants determined by the standard +-Python tokenizer. The standard token module defines these numbers and +-their names (the names are not used much). The token numbers are +-hardcoded into the Python tokenizer and into pgen. A Python +-implementation of the Python tokenizer is also available, in the +-standard tokenize module. +- +-On the other hand, symbol numbers (representing the grammar's +-non-terminals) are assigned by pgen based on the actual grammar +-input. +- +-Note: this module is pretty much obsolete; the pgen module generates +-equivalent grammar tables directly from the Grammar.txt input file +-without having to invoke the Python pgen C program. +- +-""" +- +-# Python imports +-import re +- +-# Local imports +-from pgen2 import grammar, token +- +- +-class Converter(grammar.Grammar): +- """Grammar subclass that reads classic pgen output files. +- +- The run() method reads the tables as produced by the pgen parser +- generator, typically contained in two C files, graminit.h and +- graminit.c. The other methods are for internal use only. +- +- See the base class for more documentation. +- +- """ +- +- def run(self, graminit_h, graminit_c): +- """Load the grammar tables from the text files written by pgen.""" +- self.parse_graminit_h(graminit_h) +- self.parse_graminit_c(graminit_c) +- self.finish_off() +- +- def parse_graminit_h(self, filename): +- """Parse the .h file writen by pgen. (Internal) +- +- This file is a sequence of #define statements defining the +- nonterminals of the grammar as numbers. We build two tables +- mapping the numbers to names and back. +- +- """ +- try: +- f = open(filename) +- except IOError, err: +- print "Can't open %s: %s" % (filename, err) +- return False +- self.symbol2number = {} +- self.number2symbol = {} +- lineno = 0 +- for line in f: +- lineno += 1 +- mo = re.match(r"^#define\s+(\w+)\s+(\d+)$", line) +- if not mo and line.strip(): +- print "%s(%s): can't parse %s" % (filename, lineno, +- line.strip()) +- else: +- symbol, number = mo.groups() +- number = int(number) +- assert symbol not in self.symbol2number +- assert number not in self.number2symbol +- self.symbol2number[symbol] = number +- self.number2symbol[number] = symbol +- return True +- +- def parse_graminit_c(self, filename): +- """Parse the .c file writen by pgen. (Internal) +- +- The file looks as follows. The first two lines are always this: +- +- #include "pgenheaders.h" +- #include "grammar.h" +- +- After that come four blocks: +- +- 1) one or more state definitions +- 2) a table defining dfas +- 3) a table defining labels +- 4) a struct defining the grammar +- +- A state definition has the following form: +- - one or more arc arrays, each of the form: +- static arc arcs__[] = { +- {, }, +- ... +- }; +- - followed by a state array, of the form: +- static state states_[] = { +- {, arcs__}, +- ... +- }; +- +- """ +- try: +- f = open(filename) +- except IOError, err: +- print "Can't open %s: %s" % (filename, err) +- return False +- # The code below essentially uses f's iterator-ness! +- lineno = 0 +- +- # Expect the two #include lines +- lineno, line = lineno+1, f.next() +- assert line == '#include "pgenheaders.h"\n', (lineno, line) +- lineno, line = lineno+1, f.next() +- assert line == '#include "grammar.h"\n', (lineno, line) +- +- # Parse the state definitions +- lineno, line = lineno+1, f.next() +- allarcs = {} +- states = [] +- while line.startswith("static arc "): +- while line.startswith("static arc "): +- mo = re.match(r"static arc arcs_(\d+)_(\d+)\[(\d+)\] = {$", +- line) +- assert mo, (lineno, line) +- n, m, k = map(int, mo.groups()) +- arcs = [] +- for _ in range(k): +- lineno, line = lineno+1, f.next() +- mo = re.match(r"\s+{(\d+), (\d+)},$", line) +- assert mo, (lineno, line) +- i, j = map(int, mo.groups()) +- arcs.append((i, j)) +- lineno, line = lineno+1, f.next() +- assert line == "};\n", (lineno, line) +- allarcs[(n, m)] = arcs +- lineno, line = lineno+1, f.next() +- mo = re.match(r"static state states_(\d+)\[(\d+)\] = {$", line) +- assert mo, (lineno, line) +- s, t = map(int, mo.groups()) +- assert s == len(states), (lineno, line) +- state = [] +- for _ in range(t): +- lineno, line = lineno+1, f.next() +- mo = re.match(r"\s+{(\d+), arcs_(\d+)_(\d+)},$", line) +- assert mo, (lineno, line) +- k, n, m = map(int, mo.groups()) +- arcs = allarcs[n, m] +- assert k == len(arcs), (lineno, line) +- state.append(arcs) +- states.append(state) +- lineno, line = lineno+1, f.next() +- assert line == "};\n", (lineno, line) +- lineno, line = lineno+1, f.next() +- self.states = states +- +- # Parse the dfas +- dfas = {} +- mo = re.match(r"static dfa dfas\[(\d+)\] = {$", line) +- assert mo, (lineno, line) +- ndfas = int(mo.group(1)) +- for i in range(ndfas): +- lineno, line = lineno+1, f.next() +- mo = re.match(r'\s+{(\d+), "(\w+)", (\d+), (\d+), states_(\d+),$', +- line) +- assert mo, (lineno, line) +- symbol = mo.group(2) +- number, x, y, z = map(int, mo.group(1, 3, 4, 5)) +- assert self.symbol2number[symbol] == number, (lineno, line) +- assert self.number2symbol[number] == symbol, (lineno, line) +- assert x == 0, (lineno, line) +- state = states[z] +- assert y == len(state), (lineno, line) +- lineno, line = lineno+1, f.next() +- mo = re.match(r'\s+("(?:\\\d\d\d)*")},$', line) +- assert mo, (lineno, line) +- first = {} +- rawbitset = eval(mo.group(1)) +- for i, c in enumerate(rawbitset): +- byte = ord(c) +- for j in range(8): +- if byte & (1<= os.path.getmtime(b) +diff -r 531f2e948299 lib2to3/pgen2/.svn/text-base/grammar.py.svn-base +--- a/lib2to3/pgen2/.svn/text-base/grammar.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,171 +0,0 @@ +-# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""This module defines the data structures used to represent a grammar. +- +-These are a bit arcane because they are derived from the data +-structures used by Python's 'pgen' parser generator. +- +-There's also a table here mapping operators to their names in the +-token module; the Python tokenize module reports all operators as the +-fallback token code OP, but the parser needs the actual token code. +- +-""" +- +-# Python imports +-import pickle +- +-# Local imports +-from . import token, tokenize +- +- +-class Grammar(object): +- """Pgen parsing tables tables conversion class. +- +- Once initialized, this class supplies the grammar tables for the +- parsing engine implemented by parse.py. The parsing engine +- accesses the instance variables directly. The class here does not +- provide initialization of the tables; several subclasses exist to +- do this (see the conv and pgen modules). +- +- The load() method reads the tables from a pickle file, which is +- much faster than the other ways offered by subclasses. The pickle +- file is written by calling dump() (after loading the grammar +- tables using a subclass). The report() method prints a readable +- representation of the tables to stdout, for debugging. +- +- The instance variables are as follows: +- +- symbol2number -- a dict mapping symbol names to numbers. Symbol +- numbers are always 256 or higher, to distinguish +- them from token numbers, which are between 0 and +- 255 (inclusive). +- +- number2symbol -- a dict mapping numbers to symbol names; +- these two are each other's inverse. +- +- states -- a list of DFAs, where each DFA is a list of +- states, each state is is a list of arcs, and each +- arc is a (i, j) pair where i is a label and j is +- a state number. The DFA number is the index into +- this list. (This name is slightly confusing.) +- Final states are represented by a special arc of +- the form (0, j) where j is its own state number. +- +- dfas -- a dict mapping symbol numbers to (DFA, first) +- pairs, where DFA is an item from the states list +- above, and first is a set of tokens that can +- begin this grammar rule (represented by a dict +- whose values are always 1). +- +- labels -- a list of (x, y) pairs where x is either a token +- number or a symbol number, and y is either None +- or a string; the strings are keywords. The label +- number is the index in this list; label numbers +- are used to mark state transitions (arcs) in the +- DFAs. +- +- start -- the number of the grammar's start symbol. +- +- keywords -- a dict mapping keyword strings to arc labels. +- +- tokens -- a dict mapping token numbers to arc labels. +- +- """ +- +- def __init__(self): +- self.symbol2number = {} +- self.number2symbol = {} +- self.states = [] +- self.dfas = {} +- self.labels = [(0, "EMPTY")] +- self.keywords = {} +- self.tokens = {} +- self.symbol2label = {} +- self.start = 256 +- +- def dump(self, filename): +- """Dump the grammar tables to a pickle file.""" +- f = open(filename, "wb") +- pickle.dump(self.__dict__, f, 2) +- f.close() +- +- def load(self, filename): +- """Load the grammar tables from a pickle file.""" +- f = open(filename, "rb") +- d = pickle.load(f) +- f.close() +- self.__dict__.update(d) +- +- def report(self): +- """Dump the grammar tables to standard output, for debugging.""" +- from pprint import pprint +- print "s2n" +- pprint(self.symbol2number) +- print "n2s" +- pprint(self.number2symbol) +- print "states" +- pprint(self.states) +- print "dfas" +- pprint(self.dfas) +- print "labels" +- pprint(self.labels) +- print "start", self.start +- +- +-# Map from operator to number (since tokenize doesn't do this) +- +-opmap_raw = """ +-( LPAR +-) RPAR +-[ LSQB +-] RSQB +-: COLON +-, COMMA +-; SEMI +-+ PLUS +-- MINUS +-* STAR +-/ SLASH +-| VBAR +-& AMPER +-< LESS +-> GREATER +-= EQUAL +-. DOT +-% PERCENT +-` BACKQUOTE +-{ LBRACE +-} RBRACE +-@ AT +-== EQEQUAL +-!= NOTEQUAL +-<> NOTEQUAL +-<= LESSEQUAL +->= GREATEREQUAL +-~ TILDE +-^ CIRCUMFLEX +-<< LEFTSHIFT +->> RIGHTSHIFT +-** DOUBLESTAR +-+= PLUSEQUAL +--= MINEQUAL +-*= STAREQUAL +-/= SLASHEQUAL +-%= PERCENTEQUAL +-&= AMPEREQUAL +-|= VBAREQUAL +-^= CIRCUMFLEXEQUAL +-<<= LEFTSHIFTEQUAL +->>= RIGHTSHIFTEQUAL +-**= DOUBLESTAREQUAL +-// DOUBLESLASH +-//= DOUBLESLASHEQUAL +--> RARROW +-""" +- +-opmap = {} +-for line in opmap_raw.splitlines(): +- if line: +- op, name = line.split() +- opmap[op] = getattr(token, name) +diff -r 531f2e948299 lib2to3/pgen2/.svn/text-base/literals.py.svn-base +--- a/lib2to3/pgen2/.svn/text-base/literals.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,60 +0,0 @@ +-# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Safely evaluate Python string literals without using eval().""" +- +-import re +- +-simple_escapes = {"a": "\a", +- "b": "\b", +- "f": "\f", +- "n": "\n", +- "r": "\r", +- "t": "\t", +- "v": "\v", +- "'": "'", +- '"': '"', +- "\\": "\\"} +- +-def escape(m): +- all, tail = m.group(0, 1) +- assert all.startswith("\\") +- esc = simple_escapes.get(tail) +- if esc is not None: +- return esc +- if tail.startswith("x"): +- hexes = tail[1:] +- if len(hexes) < 2: +- raise ValueError("invalid hex string escape ('\\%s')" % tail) +- try: +- i = int(hexes, 16) +- except ValueError: +- raise ValueError("invalid hex string escape ('\\%s')" % tail) +- else: +- try: +- i = int(tail, 8) +- except ValueError: +- raise ValueError("invalid octal string escape ('\\%s')" % tail) +- return chr(i) +- +-def evalString(s): +- assert s.startswith("'") or s.startswith('"'), repr(s[:1]) +- q = s[0] +- if s[:3] == q*3: +- q = q*3 +- assert s.endswith(q), repr(s[-len(q):]) +- assert len(s) >= 2*len(q) +- s = s[len(q):-len(q)] +- return re.sub(r"\\(\'|\"|\\|[abfnrtv]|x.{0,2}|[0-7]{1,3})", escape, s) +- +-def test(): +- for i in range(256): +- c = chr(i) +- s = repr(c) +- e = evalString(s) +- if e != c: +- print i, c, s, e +- +- +-if __name__ == "__main__": +- test() +diff -r 531f2e948299 lib2to3/pgen2/.svn/text-base/parse.py.svn-base +--- a/lib2to3/pgen2/.svn/text-base/parse.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,201 +0,0 @@ +-# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Parser engine for the grammar tables generated by pgen. +- +-The grammar table must be loaded first. +- +-See Parser/parser.c in the Python distribution for additional info on +-how this parsing engine works. +- +-""" +- +-# Local imports +-from . import token +- +-class ParseError(Exception): +- """Exception to signal the parser is stuck.""" +- +- def __init__(self, msg, type, value, context): +- Exception.__init__(self, "%s: type=%r, value=%r, context=%r" % +- (msg, type, value, context)) +- self.msg = msg +- self.type = type +- self.value = value +- self.context = context +- +-class Parser(object): +- """Parser engine. +- +- The proper usage sequence is: +- +- p = Parser(grammar, [converter]) # create instance +- p.setup([start]) # prepare for parsing +- : +- if p.addtoken(...): # parse a token; may raise ParseError +- break +- root = p.rootnode # root of abstract syntax tree +- +- A Parser instance may be reused by calling setup() repeatedly. +- +- A Parser instance contains state pertaining to the current token +- sequence, and should not be used concurrently by different threads +- to parse separate token sequences. +- +- See driver.py for how to get input tokens by tokenizing a file or +- string. +- +- Parsing is complete when addtoken() returns True; the root of the +- abstract syntax tree can then be retrieved from the rootnode +- instance variable. When a syntax error occurs, addtoken() raises +- the ParseError exception. There is no error recovery; the parser +- cannot be used after a syntax error was reported (but it can be +- reinitialized by calling setup()). +- +- """ +- +- def __init__(self, grammar, convert=None): +- """Constructor. +- +- The grammar argument is a grammar.Grammar instance; see the +- grammar module for more information. +- +- The parser is not ready yet for parsing; you must call the +- setup() method to get it started. +- +- The optional convert argument is a function mapping concrete +- syntax tree nodes to abstract syntax tree nodes. If not +- given, no conversion is done and the syntax tree produced is +- the concrete syntax tree. If given, it must be a function of +- two arguments, the first being the grammar (a grammar.Grammar +- instance), and the second being the concrete syntax tree node +- to be converted. The syntax tree is converted from the bottom +- up. +- +- A concrete syntax tree node is a (type, value, context, nodes) +- tuple, where type is the node type (a token or symbol number), +- value is None for symbols and a string for tokens, context is +- None or an opaque value used for error reporting (typically a +- (lineno, offset) pair), and nodes is a list of children for +- symbols, and None for tokens. +- +- An abstract syntax tree node may be anything; this is entirely +- up to the converter function. +- +- """ +- self.grammar = grammar +- self.convert = convert or (lambda grammar, node: node) +- +- def setup(self, start=None): +- """Prepare for parsing. +- +- This *must* be called before starting to parse. +- +- The optional argument is an alternative start symbol; it +- defaults to the grammar's start symbol. +- +- You can use a Parser instance to parse any number of programs; +- each time you call setup() the parser is reset to an initial +- state determined by the (implicit or explicit) start symbol. +- +- """ +- if start is None: +- start = self.grammar.start +- # Each stack entry is a tuple: (dfa, state, node). +- # A node is a tuple: (type, value, context, children), +- # where children is a list of nodes or None, and context may be None. +- newnode = (start, None, None, []) +- stackentry = (self.grammar.dfas[start], 0, newnode) +- self.stack = [stackentry] +- self.rootnode = None +- self.used_names = set() # Aliased to self.rootnode.used_names in pop() +- +- def addtoken(self, type, value, context): +- """Add a token; return True iff this is the end of the program.""" +- # Map from token to label +- ilabel = self.classify(type, value, context) +- # Loop until the token is shifted; may raise exceptions +- while True: +- dfa, state, node = self.stack[-1] +- states, first = dfa +- arcs = states[state] +- # Look for a state with this label +- for i, newstate in arcs: +- t, v = self.grammar.labels[i] +- if ilabel == i: +- # Look it up in the list of labels +- assert t < 256 +- # Shift a token; we're done with it +- self.shift(type, value, newstate, context) +- # Pop while we are in an accept-only state +- state = newstate +- while states[state] == [(0, state)]: +- self.pop() +- if not self.stack: +- # Done parsing! +- return True +- dfa, state, node = self.stack[-1] +- states, first = dfa +- # Done with this token +- return False +- elif t >= 256: +- # See if it's a symbol and if we're in its first set +- itsdfa = self.grammar.dfas[t] +- itsstates, itsfirst = itsdfa +- if ilabel in itsfirst: +- # Push a symbol +- self.push(t, self.grammar.dfas[t], newstate, context) +- break # To continue the outer while loop +- else: +- if (0, state) in arcs: +- # An accepting state, pop it and try something else +- self.pop() +- if not self.stack: +- # Done parsing, but another token is input +- raise ParseError("too much input", +- type, value, context) +- else: +- # No success finding a transition +- raise ParseError("bad input", type, value, context) +- +- def classify(self, type, value, context): +- """Turn a token into a label. (Internal)""" +- if type == token.NAME: +- # Keep a listing of all used names +- self.used_names.add(value) +- # Check for reserved words +- ilabel = self.grammar.keywords.get(value) +- if ilabel is not None: +- return ilabel +- ilabel = self.grammar.tokens.get(type) +- if ilabel is None: +- raise ParseError("bad token", type, value, context) +- return ilabel +- +- def shift(self, type, value, newstate, context): +- """Shift a token. (Internal)""" +- dfa, state, node = self.stack[-1] +- newnode = (type, value, context, None) +- newnode = self.convert(self.grammar, newnode) +- if newnode is not None: +- node[-1].append(newnode) +- self.stack[-1] = (dfa, newstate, node) +- +- def push(self, type, newdfa, newstate, context): +- """Push a nonterminal. (Internal)""" +- dfa, state, node = self.stack[-1] +- newnode = (type, None, context, []) +- self.stack[-1] = (dfa, newstate, node) +- self.stack.append((newdfa, 0, newnode)) +- +- def pop(self): +- """Pop a nonterminal. (Internal)""" +- popdfa, popstate, popnode = self.stack.pop() +- newnode = self.convert(self.grammar, popnode) +- if newnode is not None: +- if self.stack: +- dfa, state, node = self.stack[-1] +- node[-1].append(newnode) +- else: +- self.rootnode = newnode +- self.rootnode.used_names = self.used_names +diff -r 531f2e948299 lib2to3/pgen2/.svn/text-base/pgen.py.svn-base +--- a/lib2to3/pgen2/.svn/text-base/pgen.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,384 +0,0 @@ +-# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-# Pgen imports +-from . import grammar, token, tokenize +- +-class PgenGrammar(grammar.Grammar): +- pass +- +-class ParserGenerator(object): +- +- def __init__(self, filename, stream=None): +- close_stream = None +- if stream is None: +- stream = open(filename) +- close_stream = stream.close +- self.filename = filename +- self.stream = stream +- self.generator = tokenize.generate_tokens(stream.readline) +- self.gettoken() # Initialize lookahead +- self.dfas, self.startsymbol = self.parse() +- if close_stream is not None: +- close_stream() +- self.first = {} # map from symbol name to set of tokens +- self.addfirstsets() +- +- def make_grammar(self): +- c = PgenGrammar() +- names = self.dfas.keys() +- names.sort() +- names.remove(self.startsymbol) +- names.insert(0, self.startsymbol) +- for name in names: +- i = 256 + len(c.symbol2number) +- c.symbol2number[name] = i +- c.number2symbol[i] = name +- for name in names: +- dfa = self.dfas[name] +- states = [] +- for state in dfa: +- arcs = [] +- for label, next in state.arcs.iteritems(): +- arcs.append((self.make_label(c, label), dfa.index(next))) +- if state.isfinal: +- arcs.append((0, dfa.index(state))) +- states.append(arcs) +- c.states.append(states) +- c.dfas[c.symbol2number[name]] = (states, self.make_first(c, name)) +- c.start = c.symbol2number[self.startsymbol] +- return c +- +- def make_first(self, c, name): +- rawfirst = self.first[name] +- first = {} +- for label in rawfirst: +- ilabel = self.make_label(c, label) +- ##assert ilabel not in first # XXX failed on <> ... != +- first[ilabel] = 1 +- return first +- +- def make_label(self, c, label): +- # XXX Maybe this should be a method on a subclass of converter? +- ilabel = len(c.labels) +- if label[0].isalpha(): +- # Either a symbol name or a named token +- if label in c.symbol2number: +- # A symbol name (a non-terminal) +- if label in c.symbol2label: +- return c.symbol2label[label] +- else: +- c.labels.append((c.symbol2number[label], None)) +- c.symbol2label[label] = ilabel +- return ilabel +- else: +- # A named token (NAME, NUMBER, STRING) +- itoken = getattr(token, label, None) +- assert isinstance(itoken, int), label +- assert itoken in token.tok_name, label +- if itoken in c.tokens: +- return c.tokens[itoken] +- else: +- c.labels.append((itoken, None)) +- c.tokens[itoken] = ilabel +- return ilabel +- else: +- # Either a keyword or an operator +- assert label[0] in ('"', "'"), label +- value = eval(label) +- if value[0].isalpha(): +- # A keyword +- if value in c.keywords: +- return c.keywords[value] +- else: +- c.labels.append((token.NAME, value)) +- c.keywords[value] = ilabel +- return ilabel +- else: +- # An operator (any non-numeric token) +- itoken = grammar.opmap[value] # Fails if unknown token +- if itoken in c.tokens: +- return c.tokens[itoken] +- else: +- c.labels.append((itoken, None)) +- c.tokens[itoken] = ilabel +- return ilabel +- +- def addfirstsets(self): +- names = self.dfas.keys() +- names.sort() +- for name in names: +- if name not in self.first: +- self.calcfirst(name) +- #print name, self.first[name].keys() +- +- def calcfirst(self, name): +- dfa = self.dfas[name] +- self.first[name] = None # dummy to detect left recursion +- state = dfa[0] +- totalset = {} +- overlapcheck = {} +- for label, next in state.arcs.iteritems(): +- if label in self.dfas: +- if label in self.first: +- fset = self.first[label] +- if fset is None: +- raise ValueError("recursion for rule %r" % name) +- else: +- self.calcfirst(label) +- fset = self.first[label] +- totalset.update(fset) +- overlapcheck[label] = fset +- else: +- totalset[label] = 1 +- overlapcheck[label] = {label: 1} +- inverse = {} +- for label, itsfirst in overlapcheck.iteritems(): +- for symbol in itsfirst: +- if symbol in inverse: +- raise ValueError("rule %s is ambiguous; %s is in the" +- " first sets of %s as well as %s" % +- (name, symbol, label, inverse[symbol])) +- inverse[symbol] = label +- self.first[name] = totalset +- +- def parse(self): +- dfas = {} +- startsymbol = None +- # MSTART: (NEWLINE | RULE)* ENDMARKER +- while self.type != token.ENDMARKER: +- while self.type == token.NEWLINE: +- self.gettoken() +- # RULE: NAME ':' RHS NEWLINE +- name = self.expect(token.NAME) +- self.expect(token.OP, ":") +- a, z = self.parse_rhs() +- self.expect(token.NEWLINE) +- #self.dump_nfa(name, a, z) +- dfa = self.make_dfa(a, z) +- #self.dump_dfa(name, dfa) +- oldlen = len(dfa) +- self.simplify_dfa(dfa) +- newlen = len(dfa) +- dfas[name] = dfa +- #print name, oldlen, newlen +- if startsymbol is None: +- startsymbol = name +- return dfas, startsymbol +- +- def make_dfa(self, start, finish): +- # To turn an NFA into a DFA, we define the states of the DFA +- # to correspond to *sets* of states of the NFA. Then do some +- # state reduction. Let's represent sets as dicts with 1 for +- # values. +- assert isinstance(start, NFAState) +- assert isinstance(finish, NFAState) +- def closure(state): +- base = {} +- addclosure(state, base) +- return base +- def addclosure(state, base): +- assert isinstance(state, NFAState) +- if state in base: +- return +- base[state] = 1 +- for label, next in state.arcs: +- if label is None: +- addclosure(next, base) +- states = [DFAState(closure(start), finish)] +- for state in states: # NB states grows while we're iterating +- arcs = {} +- for nfastate in state.nfaset: +- for label, next in nfastate.arcs: +- if label is not None: +- addclosure(next, arcs.setdefault(label, {})) +- for label, nfaset in arcs.iteritems(): +- for st in states: +- if st.nfaset == nfaset: +- break +- else: +- st = DFAState(nfaset, finish) +- states.append(st) +- state.addarc(st, label) +- return states # List of DFAState instances; first one is start +- +- def dump_nfa(self, name, start, finish): +- print "Dump of NFA for", name +- todo = [start] +- for i, state in enumerate(todo): +- print " State", i, state is finish and "(final)" or "" +- for label, next in state.arcs: +- if next in todo: +- j = todo.index(next) +- else: +- j = len(todo) +- todo.append(next) +- if label is None: +- print " -> %d" % j +- else: +- print " %s -> %d" % (label, j) +- +- def dump_dfa(self, name, dfa): +- print "Dump of DFA for", name +- for i, state in enumerate(dfa): +- print " State", i, state.isfinal and "(final)" or "" +- for label, next in state.arcs.iteritems(): +- print " %s -> %d" % (label, dfa.index(next)) +- +- def simplify_dfa(self, dfa): +- # This is not theoretically optimal, but works well enough. +- # Algorithm: repeatedly look for two states that have the same +- # set of arcs (same labels pointing to the same nodes) and +- # unify them, until things stop changing. +- +- # dfa is a list of DFAState instances +- changes = True +- while changes: +- changes = False +- for i, state_i in enumerate(dfa): +- for j in range(i+1, len(dfa)): +- state_j = dfa[j] +- if state_i == state_j: +- #print " unify", i, j +- del dfa[j] +- for state in dfa: +- state.unifystate(state_j, state_i) +- changes = True +- break +- +- def parse_rhs(self): +- # RHS: ALT ('|' ALT)* +- a, z = self.parse_alt() +- if self.value != "|": +- return a, z +- else: +- aa = NFAState() +- zz = NFAState() +- aa.addarc(a) +- z.addarc(zz) +- while self.value == "|": +- self.gettoken() +- a, z = self.parse_alt() +- aa.addarc(a) +- z.addarc(zz) +- return aa, zz +- +- def parse_alt(self): +- # ALT: ITEM+ +- a, b = self.parse_item() +- while (self.value in ("(", "[") or +- self.type in (token.NAME, token.STRING)): +- c, d = self.parse_item() +- b.addarc(c) +- b = d +- return a, b +- +- def parse_item(self): +- # ITEM: '[' RHS ']' | ATOM ['+' | '*'] +- if self.value == "[": +- self.gettoken() +- a, z = self.parse_rhs() +- self.expect(token.OP, "]") +- a.addarc(z) +- return a, z +- else: +- a, z = self.parse_atom() +- value = self.value +- if value not in ("+", "*"): +- return a, z +- self.gettoken() +- z.addarc(a) +- if value == "+": +- return a, z +- else: +- return a, a +- +- def parse_atom(self): +- # ATOM: '(' RHS ')' | NAME | STRING +- if self.value == "(": +- self.gettoken() +- a, z = self.parse_rhs() +- self.expect(token.OP, ")") +- return a, z +- elif self.type in (token.NAME, token.STRING): +- a = NFAState() +- z = NFAState() +- a.addarc(z, self.value) +- self.gettoken() +- return a, z +- else: +- self.raise_error("expected (...) or NAME or STRING, got %s/%s", +- self.type, self.value) +- +- def expect(self, type, value=None): +- if self.type != type or (value is not None and self.value != value): +- self.raise_error("expected %s/%s, got %s/%s", +- type, value, self.type, self.value) +- value = self.value +- self.gettoken() +- return value +- +- def gettoken(self): +- tup = self.generator.next() +- while tup[0] in (tokenize.COMMENT, tokenize.NL): +- tup = self.generator.next() +- self.type, self.value, self.begin, self.end, self.line = tup +- #print token.tok_name[self.type], repr(self.value) +- +- def raise_error(self, msg, *args): +- if args: +- try: +- msg = msg % args +- except: +- msg = " ".join([msg] + map(str, args)) +- raise SyntaxError(msg, (self.filename, self.end[0], +- self.end[1], self.line)) +- +-class NFAState(object): +- +- def __init__(self): +- self.arcs = [] # list of (label, NFAState) pairs +- +- def addarc(self, next, label=None): +- assert label is None or isinstance(label, str) +- assert isinstance(next, NFAState) +- self.arcs.append((label, next)) +- +-class DFAState(object): +- +- def __init__(self, nfaset, final): +- assert isinstance(nfaset, dict) +- assert isinstance(iter(nfaset).next(), NFAState) +- assert isinstance(final, NFAState) +- self.nfaset = nfaset +- self.isfinal = final in nfaset +- self.arcs = {} # map from label to DFAState +- +- def addarc(self, next, label): +- assert isinstance(label, str) +- assert label not in self.arcs +- assert isinstance(next, DFAState) +- self.arcs[label] = next +- +- def unifystate(self, old, new): +- for label, next in self.arcs.iteritems(): +- if next is old: +- self.arcs[label] = new +- +- def __eq__(self, other): +- # Equality test -- ignore the nfaset instance variable +- assert isinstance(other, DFAState) +- if self.isfinal != other.isfinal: +- return False +- # Can't just return self.arcs == other.arcs, because that +- # would invoke this method recursively, with cycles... +- if len(self.arcs) != len(other.arcs): +- return False +- for label, next in self.arcs.iteritems(): +- if next is not other.arcs.get(label): +- return False +- return True +- +-def generate_grammar(filename="Grammar.txt"): +- p = ParserGenerator(filename) +- return p.make_grammar() +diff -r 531f2e948299 lib2to3/pgen2/.svn/text-base/token.py.svn-base +--- a/lib2to3/pgen2/.svn/text-base/token.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,82 +0,0 @@ +-#! /usr/bin/env python +- +-"""Token constants (from "token.h").""" +- +-# Taken from Python (r53757) and modified to include some tokens +-# originally monkeypatched in by pgen2.tokenize +- +-#--start constants-- +-ENDMARKER = 0 +-NAME = 1 +-NUMBER = 2 +-STRING = 3 +-NEWLINE = 4 +-INDENT = 5 +-DEDENT = 6 +-LPAR = 7 +-RPAR = 8 +-LSQB = 9 +-RSQB = 10 +-COLON = 11 +-COMMA = 12 +-SEMI = 13 +-PLUS = 14 +-MINUS = 15 +-STAR = 16 +-SLASH = 17 +-VBAR = 18 +-AMPER = 19 +-LESS = 20 +-GREATER = 21 +-EQUAL = 22 +-DOT = 23 +-PERCENT = 24 +-BACKQUOTE = 25 +-LBRACE = 26 +-RBRACE = 27 +-EQEQUAL = 28 +-NOTEQUAL = 29 +-LESSEQUAL = 30 +-GREATEREQUAL = 31 +-TILDE = 32 +-CIRCUMFLEX = 33 +-LEFTSHIFT = 34 +-RIGHTSHIFT = 35 +-DOUBLESTAR = 36 +-PLUSEQUAL = 37 +-MINEQUAL = 38 +-STAREQUAL = 39 +-SLASHEQUAL = 40 +-PERCENTEQUAL = 41 +-AMPEREQUAL = 42 +-VBAREQUAL = 43 +-CIRCUMFLEXEQUAL = 44 +-LEFTSHIFTEQUAL = 45 +-RIGHTSHIFTEQUAL = 46 +-DOUBLESTAREQUAL = 47 +-DOUBLESLASH = 48 +-DOUBLESLASHEQUAL = 49 +-AT = 50 +-OP = 51 +-COMMENT = 52 +-NL = 53 +-RARROW = 54 +-ERRORTOKEN = 55 +-N_TOKENS = 56 +-NT_OFFSET = 256 +-#--end constants-- +- +-tok_name = {} +-for _name, _value in globals().items(): +- if type(_value) is type(0): +- tok_name[_value] = _name +- +- +-def ISTERMINAL(x): +- return x < NT_OFFSET +- +-def ISNONTERMINAL(x): +- return x >= NT_OFFSET +- +-def ISEOF(x): +- return x == ENDMARKER +diff -r 531f2e948299 lib2to3/pgen2/.svn/text-base/tokenize.py.svn-base +--- a/lib2to3/pgen2/.svn/text-base/tokenize.py.svn-base Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,405 +0,0 @@ +-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation. +-# All rights reserved. +- +-"""Tokenization help for Python programs. +- +-generate_tokens(readline) is a generator that breaks a stream of +-text into Python tokens. It accepts a readline-like method which is called +-repeatedly to get the next line of input (or "" for EOF). It generates +-5-tuples with these members: +- +- the token type (see token.py) +- the token (a string) +- the starting (row, column) indices of the token (a 2-tuple of ints) +- the ending (row, column) indices of the token (a 2-tuple of ints) +- the original line (string) +- +-It is designed to match the working of the Python tokenizer exactly, except +-that it produces COMMENT tokens for comments and gives type OP for all +-operators +- +-Older entry points +- tokenize_loop(readline, tokeneater) +- tokenize(readline, tokeneater=printtoken) +-are the same, except instead of generating tokens, tokeneater is a callback +-function to which the 5 fields described above are passed as 5 arguments, +-each time a new token is found.""" +- +-__author__ = 'Ka-Ping Yee ' +-__credits__ = \ +- 'GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, Skip Montanaro' +- +-import string, re +-from lib2to3.pgen2.token import * +- +-from . import token +-__all__ = [x for x in dir(token) if x[0] != '_'] + ["tokenize", +- "generate_tokens", "untokenize"] +-del token +- +-def group(*choices): return '(' + '|'.join(choices) + ')' +-def any(*choices): return group(*choices) + '*' +-def maybe(*choices): return group(*choices) + '?' +- +-Whitespace = r'[ \f\t]*' +-Comment = r'#[^\r\n]*' +-Ignore = Whitespace + any(r'\\\r?\n' + Whitespace) + maybe(Comment) +-Name = r'[a-zA-Z_]\w*' +- +-Binnumber = r'0[bB][01]*' +-Hexnumber = r'0[xX][\da-fA-F]*[lL]?' +-Octnumber = r'0[oO]?[0-7]*[lL]?' +-Decnumber = r'[1-9]\d*[lL]?' +-Intnumber = group(Binnumber, Hexnumber, Octnumber, Decnumber) +-Exponent = r'[eE][-+]?\d+' +-Pointfloat = group(r'\d+\.\d*', r'\.\d+') + maybe(Exponent) +-Expfloat = r'\d+' + Exponent +-Floatnumber = group(Pointfloat, Expfloat) +-Imagnumber = group(r'\d+[jJ]', Floatnumber + r'[jJ]') +-Number = group(Imagnumber, Floatnumber, Intnumber) +- +-# Tail end of ' string. +-Single = r"[^'\\]*(?:\\.[^'\\]*)*'" +-# Tail end of " string. +-Double = r'[^"\\]*(?:\\.[^"\\]*)*"' +-# Tail end of ''' string. +-Single3 = r"[^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*'''" +-# Tail end of """ string. +-Double3 = r'[^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*"""' +-Triple = group("[ubUB]?[rR]?'''", '[ubUB]?[rR]?"""') +-# Single-line ' or " string. +-String = group(r"[uU]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*'", +- r'[uU]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*"') +- +-# Because of leftmost-then-longest match semantics, be sure to put the +-# longest operators first (e.g., if = came before ==, == would get +-# recognized as two instances of =). +-Operator = group(r"\*\*=?", r">>=?", r"<<=?", r"<>", r"!=", +- r"//=?", r"->", +- r"[+\-*/%&|^=<>]=?", +- r"~") +- +-Bracket = '[][(){}]' +-Special = group(r'\r?\n', r'[:;.,`@]') +-Funny = group(Operator, Bracket, Special) +- +-PlainToken = group(Number, Funny, String, Name) +-Token = Ignore + PlainToken +- +-# First (or only) line of ' or " string. +-ContStr = group(r"[uUbB]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*" + +- group("'", r'\\\r?\n'), +- r'[uUbB]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*' + +- group('"', r'\\\r?\n')) +-PseudoExtras = group(r'\\\r?\n', Comment, Triple) +-PseudoToken = Whitespace + group(PseudoExtras, Number, Funny, ContStr, Name) +- +-tokenprog, pseudoprog, single3prog, double3prog = map( +- re.compile, (Token, PseudoToken, Single3, Double3)) +-endprogs = {"'": re.compile(Single), '"': re.compile(Double), +- "'''": single3prog, '"""': double3prog, +- "r'''": single3prog, 'r"""': double3prog, +- "u'''": single3prog, 'u"""': double3prog, +- "b'''": single3prog, 'b"""': double3prog, +- "ur'''": single3prog, 'ur"""': double3prog, +- "br'''": single3prog, 'br"""': double3prog, +- "R'''": single3prog, 'R"""': double3prog, +- "U'''": single3prog, 'U"""': double3prog, +- "B'''": single3prog, 'B"""': double3prog, +- "uR'''": single3prog, 'uR"""': double3prog, +- "Ur'''": single3prog, 'Ur"""': double3prog, +- "UR'''": single3prog, 'UR"""': double3prog, +- "bR'''": single3prog, 'bR"""': double3prog, +- "Br'''": single3prog, 'Br"""': double3prog, +- "BR'''": single3prog, 'BR"""': double3prog, +- 'r': None, 'R': None, +- 'u': None, 'U': None, +- 'b': None, 'B': None} +- +-triple_quoted = {} +-for t in ("'''", '"""', +- "r'''", 'r"""', "R'''", 'R"""', +- "u'''", 'u"""', "U'''", 'U"""', +- "b'''", 'b"""', "B'''", 'B"""', +- "ur'''", 'ur"""', "Ur'''", 'Ur"""', +- "uR'''", 'uR"""', "UR'''", 'UR"""', +- "br'''", 'br"""', "Br'''", 'Br"""', +- "bR'''", 'bR"""', "BR'''", 'BR"""',): +- triple_quoted[t] = t +-single_quoted = {} +-for t in ("'", '"', +- "r'", 'r"', "R'", 'R"', +- "u'", 'u"', "U'", 'U"', +- "b'", 'b"', "B'", 'B"', +- "ur'", 'ur"', "Ur'", 'Ur"', +- "uR'", 'uR"', "UR'", 'UR"', +- "br'", 'br"', "Br'", 'Br"', +- "bR'", 'bR"', "BR'", 'BR"', ): +- single_quoted[t] = t +- +-tabsize = 8 +- +-class TokenError(Exception): pass +- +-class StopTokenizing(Exception): pass +- +-def printtoken(type, token, (srow, scol), (erow, ecol), line): # for testing +- print "%d,%d-%d,%d:\t%s\t%s" % \ +- (srow, scol, erow, ecol, tok_name[type], repr(token)) +- +-def tokenize(readline, tokeneater=printtoken): +- """ +- The tokenize() function accepts two parameters: one representing the +- input stream, and one providing an output mechanism for tokenize(). +- +- The first parameter, readline, must be a callable object which provides +- the same interface as the readline() method of built-in file objects. +- Each call to the function should return one line of input as a string. +- +- The second parameter, tokeneater, must also be a callable object. It is +- called once for each token, with five arguments, corresponding to the +- tuples generated by generate_tokens(). +- """ +- try: +- tokenize_loop(readline, tokeneater) +- except StopTokenizing: +- pass +- +-# backwards compatible interface +-def tokenize_loop(readline, tokeneater): +- for token_info in generate_tokens(readline): +- tokeneater(*token_info) +- +-class Untokenizer: +- +- def __init__(self): +- self.tokens = [] +- self.prev_row = 1 +- self.prev_col = 0 +- +- def add_whitespace(self, start): +- row, col = start +- assert row <= self.prev_row +- col_offset = col - self.prev_col +- if col_offset: +- self.tokens.append(" " * col_offset) +- +- def untokenize(self, iterable): +- for t in iterable: +- if len(t) == 2: +- self.compat(t, iterable) +- break +- tok_type, token, start, end, line = t +- self.add_whitespace(start) +- self.tokens.append(token) +- self.prev_row, self.prev_col = end +- if tok_type in (NEWLINE, NL): +- self.prev_row += 1 +- self.prev_col = 0 +- return "".join(self.tokens) +- +- def compat(self, token, iterable): +- startline = False +- indents = [] +- toks_append = self.tokens.append +- toknum, tokval = token +- if toknum in (NAME, NUMBER): +- tokval += ' ' +- if toknum in (NEWLINE, NL): +- startline = True +- for tok in iterable: +- toknum, tokval = tok[:2] +- +- if toknum in (NAME, NUMBER): +- tokval += ' ' +- +- if toknum == INDENT: +- indents.append(tokval) +- continue +- elif toknum == DEDENT: +- indents.pop() +- continue +- elif toknum in (NEWLINE, NL): +- startline = True +- elif startline and indents: +- toks_append(indents[-1]) +- startline = False +- toks_append(tokval) +- +-def untokenize(iterable): +- """Transform tokens back into Python source code. +- +- Each element returned by the iterable must be a token sequence +- with at least two elements, a token number and token value. If +- only two tokens are passed, the resulting output is poor. +- +- Round-trip invariant for full input: +- Untokenized source will match input source exactly +- +- Round-trip invariant for limited intput: +- # Output text will tokenize the back to the input +- t1 = [tok[:2] for tok in generate_tokens(f.readline)] +- newcode = untokenize(t1) +- readline = iter(newcode.splitlines(1)).next +- t2 = [tok[:2] for tokin generate_tokens(readline)] +- assert t1 == t2 +- """ +- ut = Untokenizer() +- return ut.untokenize(iterable) +- +-def generate_tokens(readline): +- """ +- The generate_tokens() generator requires one argment, readline, which +- must be a callable object which provides the same interface as the +- readline() method of built-in file objects. Each call to the function +- should return one line of input as a string. Alternately, readline +- can be a callable function terminating with StopIteration: +- readline = open(myfile).next # Example of alternate readline +- +- The generator produces 5-tuples with these members: the token type; the +- token string; a 2-tuple (srow, scol) of ints specifying the row and +- column where the token begins in the source; a 2-tuple (erow, ecol) of +- ints specifying the row and column where the token ends in the source; +- and the line on which the token was found. The line passed is the +- logical line; continuation lines are included. +- """ +- lnum = parenlev = continued = 0 +- namechars, numchars = string.ascii_letters + '_', '0123456789' +- contstr, needcont = '', 0 +- contline = None +- indents = [0] +- +- while 1: # loop over lines in stream +- try: +- line = readline() +- except StopIteration: +- line = '' +- lnum = lnum + 1 +- pos, max = 0, len(line) +- +- if contstr: # continued string +- if not line: +- raise TokenError, ("EOF in multi-line string", strstart) +- endmatch = endprog.match(line) +- if endmatch: +- pos = end = endmatch.end(0) +- yield (STRING, contstr + line[:end], +- strstart, (lnum, end), contline + line) +- contstr, needcont = '', 0 +- contline = None +- elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n': +- yield (ERRORTOKEN, contstr + line, +- strstart, (lnum, len(line)), contline) +- contstr = '' +- contline = None +- continue +- else: +- contstr = contstr + line +- contline = contline + line +- continue +- +- elif parenlev == 0 and not continued: # new statement +- if not line: break +- column = 0 +- while pos < max: # measure leading whitespace +- if line[pos] == ' ': column = column + 1 +- elif line[pos] == '\t': column = (column/tabsize + 1)*tabsize +- elif line[pos] == '\f': column = 0 +- else: break +- pos = pos + 1 +- if pos == max: break +- +- if line[pos] in '#\r\n': # skip comments or blank lines +- if line[pos] == '#': +- comment_token = line[pos:].rstrip('\r\n') +- nl_pos = pos + len(comment_token) +- yield (COMMENT, comment_token, +- (lnum, pos), (lnum, pos + len(comment_token)), line) +- yield (NL, line[nl_pos:], +- (lnum, nl_pos), (lnum, len(line)), line) +- else: +- yield ((NL, COMMENT)[line[pos] == '#'], line[pos:], +- (lnum, pos), (lnum, len(line)), line) +- continue +- +- if column > indents[-1]: # count indents or dedents +- indents.append(column) +- yield (INDENT, line[:pos], (lnum, 0), (lnum, pos), line) +- while column < indents[-1]: +- if column not in indents: +- raise IndentationError( +- "unindent does not match any outer indentation level", +- ("", lnum, pos, line)) +- indents = indents[:-1] +- yield (DEDENT, '', (lnum, pos), (lnum, pos), line) +- +- else: # continued statement +- if not line: +- raise TokenError, ("EOF in multi-line statement", (lnum, 0)) +- continued = 0 +- +- while pos < max: +- pseudomatch = pseudoprog.match(line, pos) +- if pseudomatch: # scan for tokens +- start, end = pseudomatch.span(1) +- spos, epos, pos = (lnum, start), (lnum, end), end +- token, initial = line[start:end], line[start] +- +- if initial in numchars or \ +- (initial == '.' and token != '.'): # ordinary number +- yield (NUMBER, token, spos, epos, line) +- elif initial in '\r\n': +- newline = NEWLINE +- if parenlev > 0: +- newline = NL +- yield (newline, token, spos, epos, line) +- elif initial == '#': +- assert not token.endswith("\n") +- yield (COMMENT, token, spos, epos, line) +- elif token in triple_quoted: +- endprog = endprogs[token] +- endmatch = endprog.match(line, pos) +- if endmatch: # all on one line +- pos = endmatch.end(0) +- token = line[start:pos] +- yield (STRING, token, spos, (lnum, pos), line) +- else: +- strstart = (lnum, start) # multiple lines +- contstr = line[start:] +- contline = line +- break +- elif initial in single_quoted or \ +- token[:2] in single_quoted or \ +- token[:3] in single_quoted: +- if token[-1] == '\n': # continued string +- strstart = (lnum, start) +- endprog = (endprogs[initial] or endprogs[token[1]] or +- endprogs[token[2]]) +- contstr, needcont = line[start:], 1 +- contline = line +- break +- else: # ordinary string +- yield (STRING, token, spos, epos, line) +- elif initial in namechars: # ordinary name +- yield (NAME, token, spos, epos, line) +- elif initial == '\\': # continued stmt +- # This yield is new; needed for better idempotency: +- yield (NL, token, spos, (lnum, pos), line) +- continued = 1 +- else: +- if initial in '([{': parenlev = parenlev + 1 +- elif initial in ')]}': parenlev = parenlev - 1 +- yield (OP, token, spos, epos, line) +- else: +- yield (ERRORTOKEN, line[pos], +- (lnum, pos), (lnum, pos+1), line) +- pos = pos + 1 +- +- for indent in indents[1:]: # pop remaining indent levels +- yield (DEDENT, '', (lnum, 0), (lnum, 0), '') +- yield (ENDMARKER, '', (lnum, 0), (lnum, 0), '') +- +-if __name__ == '__main__': # testing +- import sys +- if len(sys.argv) > 1: tokenize(open(sys.argv[1]).readline) +- else: tokenize(sys.stdin.readline) +diff -r 531f2e948299 lib2to3/pgen2/__init__.py +--- a/lib2to3/pgen2/__init__.py Mon Mar 30 20:02:09 2009 -0500 ++++ b/lib2to3/pgen2/__init__.py Wed Apr 01 13:59:47 2009 -0500 +@@ -1,4 +1,1 @@ +-# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""The pgen2 package.""" ++from refactor.pgen2 import * +diff -r 531f2e948299 lib2to3/pgen2/conv.py +--- a/lib2to3/pgen2/conv.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,257 +0,0 @@ +-# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Convert graminit.[ch] spit out by pgen to Python code. +- +-Pgen is the Python parser generator. It is useful to quickly create a +-parser from a grammar file in Python's grammar notation. But I don't +-want my parsers to be written in C (yet), so I'm translating the +-parsing tables to Python data structures and writing a Python parse +-engine. +- +-Note that the token numbers are constants determined by the standard +-Python tokenizer. The standard token module defines these numbers and +-their names (the names are not used much). The token numbers are +-hardcoded into the Python tokenizer and into pgen. A Python +-implementation of the Python tokenizer is also available, in the +-standard tokenize module. +- +-On the other hand, symbol numbers (representing the grammar's +-non-terminals) are assigned by pgen based on the actual grammar +-input. +- +-Note: this module is pretty much obsolete; the pgen module generates +-equivalent grammar tables directly from the Grammar.txt input file +-without having to invoke the Python pgen C program. +- +-""" +- +-# Python imports +-import re +- +-# Local imports +-from pgen2 import grammar, token +- +- +-class Converter(grammar.Grammar): +- """Grammar subclass that reads classic pgen output files. +- +- The run() method reads the tables as produced by the pgen parser +- generator, typically contained in two C files, graminit.h and +- graminit.c. The other methods are for internal use only. +- +- See the base class for more documentation. +- +- """ +- +- def run(self, graminit_h, graminit_c): +- """Load the grammar tables from the text files written by pgen.""" +- self.parse_graminit_h(graminit_h) +- self.parse_graminit_c(graminit_c) +- self.finish_off() +- +- def parse_graminit_h(self, filename): +- """Parse the .h file writen by pgen. (Internal) +- +- This file is a sequence of #define statements defining the +- nonterminals of the grammar as numbers. We build two tables +- mapping the numbers to names and back. +- +- """ +- try: +- f = open(filename) +- except IOError, err: +- print "Can't open %s: %s" % (filename, err) +- return False +- self.symbol2number = {} +- self.number2symbol = {} +- lineno = 0 +- for line in f: +- lineno += 1 +- mo = re.match(r"^#define\s+(\w+)\s+(\d+)$", line) +- if not mo and line.strip(): +- print "%s(%s): can't parse %s" % (filename, lineno, +- line.strip()) +- else: +- symbol, number = mo.groups() +- number = int(number) +- assert symbol not in self.symbol2number +- assert number not in self.number2symbol +- self.symbol2number[symbol] = number +- self.number2symbol[number] = symbol +- return True +- +- def parse_graminit_c(self, filename): +- """Parse the .c file writen by pgen. (Internal) +- +- The file looks as follows. The first two lines are always this: +- +- #include "pgenheaders.h" +- #include "grammar.h" +- +- After that come four blocks: +- +- 1) one or more state definitions +- 2) a table defining dfas +- 3) a table defining labels +- 4) a struct defining the grammar +- +- A state definition has the following form: +- - one or more arc arrays, each of the form: +- static arc arcs__[] = { +- {, }, +- ... +- }; +- - followed by a state array, of the form: +- static state states_[] = { +- {, arcs__}, +- ... +- }; +- +- """ +- try: +- f = open(filename) +- except IOError, err: +- print "Can't open %s: %s" % (filename, err) +- return False +- # The code below essentially uses f's iterator-ness! +- lineno = 0 +- +- # Expect the two #include lines +- lineno, line = lineno+1, f.next() +- assert line == '#include "pgenheaders.h"\n', (lineno, line) +- lineno, line = lineno+1, f.next() +- assert line == '#include "grammar.h"\n', (lineno, line) +- +- # Parse the state definitions +- lineno, line = lineno+1, f.next() +- allarcs = {} +- states = [] +- while line.startswith("static arc "): +- while line.startswith("static arc "): +- mo = re.match(r"static arc arcs_(\d+)_(\d+)\[(\d+)\] = {$", +- line) +- assert mo, (lineno, line) +- n, m, k = map(int, mo.groups()) +- arcs = [] +- for _ in range(k): +- lineno, line = lineno+1, f.next() +- mo = re.match(r"\s+{(\d+), (\d+)},$", line) +- assert mo, (lineno, line) +- i, j = map(int, mo.groups()) +- arcs.append((i, j)) +- lineno, line = lineno+1, f.next() +- assert line == "};\n", (lineno, line) +- allarcs[(n, m)] = arcs +- lineno, line = lineno+1, f.next() +- mo = re.match(r"static state states_(\d+)\[(\d+)\] = {$", line) +- assert mo, (lineno, line) +- s, t = map(int, mo.groups()) +- assert s == len(states), (lineno, line) +- state = [] +- for _ in range(t): +- lineno, line = lineno+1, f.next() +- mo = re.match(r"\s+{(\d+), arcs_(\d+)_(\d+)},$", line) +- assert mo, (lineno, line) +- k, n, m = map(int, mo.groups()) +- arcs = allarcs[n, m] +- assert k == len(arcs), (lineno, line) +- state.append(arcs) +- states.append(state) +- lineno, line = lineno+1, f.next() +- assert line == "};\n", (lineno, line) +- lineno, line = lineno+1, f.next() +- self.states = states +- +- # Parse the dfas +- dfas = {} +- mo = re.match(r"static dfa dfas\[(\d+)\] = {$", line) +- assert mo, (lineno, line) +- ndfas = int(mo.group(1)) +- for i in range(ndfas): +- lineno, line = lineno+1, f.next() +- mo = re.match(r'\s+{(\d+), "(\w+)", (\d+), (\d+), states_(\d+),$', +- line) +- assert mo, (lineno, line) +- symbol = mo.group(2) +- number, x, y, z = map(int, mo.group(1, 3, 4, 5)) +- assert self.symbol2number[symbol] == number, (lineno, line) +- assert self.number2symbol[number] == symbol, (lineno, line) +- assert x == 0, (lineno, line) +- state = states[z] +- assert y == len(state), (lineno, line) +- lineno, line = lineno+1, f.next() +- mo = re.match(r'\s+("(?:\\\d\d\d)*")},$', line) +- assert mo, (lineno, line) +- first = {} +- rawbitset = eval(mo.group(1)) +- for i, c in enumerate(rawbitset): +- byte = ord(c) +- for j in range(8): +- if byte & (1<= os.path.getmtime(b) +diff -r 531f2e948299 lib2to3/pgen2/grammar.py +--- a/lib2to3/pgen2/grammar.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,171 +0,0 @@ +-# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""This module defines the data structures used to represent a grammar. +- +-These are a bit arcane because they are derived from the data +-structures used by Python's 'pgen' parser generator. +- +-There's also a table here mapping operators to their names in the +-token module; the Python tokenize module reports all operators as the +-fallback token code OP, but the parser needs the actual token code. +- +-""" +- +-# Python imports +-import pickle +- +-# Local imports +-from . import token, tokenize +- +- +-class Grammar(object): +- """Pgen parsing tables tables conversion class. +- +- Once initialized, this class supplies the grammar tables for the +- parsing engine implemented by parse.py. The parsing engine +- accesses the instance variables directly. The class here does not +- provide initialization of the tables; several subclasses exist to +- do this (see the conv and pgen modules). +- +- The load() method reads the tables from a pickle file, which is +- much faster than the other ways offered by subclasses. The pickle +- file is written by calling dump() (after loading the grammar +- tables using a subclass). The report() method prints a readable +- representation of the tables to stdout, for debugging. +- +- The instance variables are as follows: +- +- symbol2number -- a dict mapping symbol names to numbers. Symbol +- numbers are always 256 or higher, to distinguish +- them from token numbers, which are between 0 and +- 255 (inclusive). +- +- number2symbol -- a dict mapping numbers to symbol names; +- these two are each other's inverse. +- +- states -- a list of DFAs, where each DFA is a list of +- states, each state is is a list of arcs, and each +- arc is a (i, j) pair where i is a label and j is +- a state number. The DFA number is the index into +- this list. (This name is slightly confusing.) +- Final states are represented by a special arc of +- the form (0, j) where j is its own state number. +- +- dfas -- a dict mapping symbol numbers to (DFA, first) +- pairs, where DFA is an item from the states list +- above, and first is a set of tokens that can +- begin this grammar rule (represented by a dict +- whose values are always 1). +- +- labels -- a list of (x, y) pairs where x is either a token +- number or a symbol number, and y is either None +- or a string; the strings are keywords. The label +- number is the index in this list; label numbers +- are used to mark state transitions (arcs) in the +- DFAs. +- +- start -- the number of the grammar's start symbol. +- +- keywords -- a dict mapping keyword strings to arc labels. +- +- tokens -- a dict mapping token numbers to arc labels. +- +- """ +- +- def __init__(self): +- self.symbol2number = {} +- self.number2symbol = {} +- self.states = [] +- self.dfas = {} +- self.labels = [(0, "EMPTY")] +- self.keywords = {} +- self.tokens = {} +- self.symbol2label = {} +- self.start = 256 +- +- def dump(self, filename): +- """Dump the grammar tables to a pickle file.""" +- f = open(filename, "wb") +- pickle.dump(self.__dict__, f, 2) +- f.close() +- +- def load(self, filename): +- """Load the grammar tables from a pickle file.""" +- f = open(filename, "rb") +- d = pickle.load(f) +- f.close() +- self.__dict__.update(d) +- +- def report(self): +- """Dump the grammar tables to standard output, for debugging.""" +- from pprint import pprint +- print "s2n" +- pprint(self.symbol2number) +- print "n2s" +- pprint(self.number2symbol) +- print "states" +- pprint(self.states) +- print "dfas" +- pprint(self.dfas) +- print "labels" +- pprint(self.labels) +- print "start", self.start +- +- +-# Map from operator to number (since tokenize doesn't do this) +- +-opmap_raw = """ +-( LPAR +-) RPAR +-[ LSQB +-] RSQB +-: COLON +-, COMMA +-; SEMI +-+ PLUS +-- MINUS +-* STAR +-/ SLASH +-| VBAR +-& AMPER +-< LESS +-> GREATER +-= EQUAL +-. DOT +-% PERCENT +-` BACKQUOTE +-{ LBRACE +-} RBRACE +-@ AT +-== EQEQUAL +-!= NOTEQUAL +-<> NOTEQUAL +-<= LESSEQUAL +->= GREATEREQUAL +-~ TILDE +-^ CIRCUMFLEX +-<< LEFTSHIFT +->> RIGHTSHIFT +-** DOUBLESTAR +-+= PLUSEQUAL +--= MINEQUAL +-*= STAREQUAL +-/= SLASHEQUAL +-%= PERCENTEQUAL +-&= AMPEREQUAL +-|= VBAREQUAL +-^= CIRCUMFLEXEQUAL +-<<= LEFTSHIFTEQUAL +->>= RIGHTSHIFTEQUAL +-**= DOUBLESTAREQUAL +-// DOUBLESLASH +-//= DOUBLESLASHEQUAL +--> RARROW +-""" +- +-opmap = {} +-for line in opmap_raw.splitlines(): +- if line: +- op, name = line.split() +- opmap[op] = getattr(token, name) +diff -r 531f2e948299 lib2to3/pgen2/literals.py +--- a/lib2to3/pgen2/literals.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,60 +0,0 @@ +-# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Safely evaluate Python string literals without using eval().""" +- +-import re +- +-simple_escapes = {"a": "\a", +- "b": "\b", +- "f": "\f", +- "n": "\n", +- "r": "\r", +- "t": "\t", +- "v": "\v", +- "'": "'", +- '"': '"', +- "\\": "\\"} +- +-def escape(m): +- all, tail = m.group(0, 1) +- assert all.startswith("\\") +- esc = simple_escapes.get(tail) +- if esc is not None: +- return esc +- if tail.startswith("x"): +- hexes = tail[1:] +- if len(hexes) < 2: +- raise ValueError("invalid hex string escape ('\\%s')" % tail) +- try: +- i = int(hexes, 16) +- except ValueError: +- raise ValueError("invalid hex string escape ('\\%s')" % tail) +- else: +- try: +- i = int(tail, 8) +- except ValueError: +- raise ValueError("invalid octal string escape ('\\%s')" % tail) +- return chr(i) +- +-def evalString(s): +- assert s.startswith("'") or s.startswith('"'), repr(s[:1]) +- q = s[0] +- if s[:3] == q*3: +- q = q*3 +- assert s.endswith(q), repr(s[-len(q):]) +- assert len(s) >= 2*len(q) +- s = s[len(q):-len(q)] +- return re.sub(r"\\(\'|\"|\\|[abfnrtv]|x.{0,2}|[0-7]{1,3})", escape, s) +- +-def test(): +- for i in range(256): +- c = chr(i) +- s = repr(c) +- e = evalString(s) +- if e != c: +- print i, c, s, e +- +- +-if __name__ == "__main__": +- test() +diff -r 531f2e948299 lib2to3/pgen2/parse.py +--- a/lib2to3/pgen2/parse.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,201 +0,0 @@ +-# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Parser engine for the grammar tables generated by pgen. +- +-The grammar table must be loaded first. +- +-See Parser/parser.c in the Python distribution for additional info on +-how this parsing engine works. +- +-""" +- +-# Local imports +-from . import token +- +-class ParseError(Exception): +- """Exception to signal the parser is stuck.""" +- +- def __init__(self, msg, type, value, context): +- Exception.__init__(self, "%s: type=%r, value=%r, context=%r" % +- (msg, type, value, context)) +- self.msg = msg +- self.type = type +- self.value = value +- self.context = context +- +-class Parser(object): +- """Parser engine. +- +- The proper usage sequence is: +- +- p = Parser(grammar, [converter]) # create instance +- p.setup([start]) # prepare for parsing +- : +- if p.addtoken(...): # parse a token; may raise ParseError +- break +- root = p.rootnode # root of abstract syntax tree +- +- A Parser instance may be reused by calling setup() repeatedly. +- +- A Parser instance contains state pertaining to the current token +- sequence, and should not be used concurrently by different threads +- to parse separate token sequences. +- +- See driver.py for how to get input tokens by tokenizing a file or +- string. +- +- Parsing is complete when addtoken() returns True; the root of the +- abstract syntax tree can then be retrieved from the rootnode +- instance variable. When a syntax error occurs, addtoken() raises +- the ParseError exception. There is no error recovery; the parser +- cannot be used after a syntax error was reported (but it can be +- reinitialized by calling setup()). +- +- """ +- +- def __init__(self, grammar, convert=None): +- """Constructor. +- +- The grammar argument is a grammar.Grammar instance; see the +- grammar module for more information. +- +- The parser is not ready yet for parsing; you must call the +- setup() method to get it started. +- +- The optional convert argument is a function mapping concrete +- syntax tree nodes to abstract syntax tree nodes. If not +- given, no conversion is done and the syntax tree produced is +- the concrete syntax tree. If given, it must be a function of +- two arguments, the first being the grammar (a grammar.Grammar +- instance), and the second being the concrete syntax tree node +- to be converted. The syntax tree is converted from the bottom +- up. +- +- A concrete syntax tree node is a (type, value, context, nodes) +- tuple, where type is the node type (a token or symbol number), +- value is None for symbols and a string for tokens, context is +- None or an opaque value used for error reporting (typically a +- (lineno, offset) pair), and nodes is a list of children for +- symbols, and None for tokens. +- +- An abstract syntax tree node may be anything; this is entirely +- up to the converter function. +- +- """ +- self.grammar = grammar +- self.convert = convert or (lambda grammar, node: node) +- +- def setup(self, start=None): +- """Prepare for parsing. +- +- This *must* be called before starting to parse. +- +- The optional argument is an alternative start symbol; it +- defaults to the grammar's start symbol. +- +- You can use a Parser instance to parse any number of programs; +- each time you call setup() the parser is reset to an initial +- state determined by the (implicit or explicit) start symbol. +- +- """ +- if start is None: +- start = self.grammar.start +- # Each stack entry is a tuple: (dfa, state, node). +- # A node is a tuple: (type, value, context, children), +- # where children is a list of nodes or None, and context may be None. +- newnode = (start, None, None, []) +- stackentry = (self.grammar.dfas[start], 0, newnode) +- self.stack = [stackentry] +- self.rootnode = None +- self.used_names = set() # Aliased to self.rootnode.used_names in pop() +- +- def addtoken(self, type, value, context): +- """Add a token; return True iff this is the end of the program.""" +- # Map from token to label +- ilabel = self.classify(type, value, context) +- # Loop until the token is shifted; may raise exceptions +- while True: +- dfa, state, node = self.stack[-1] +- states, first = dfa +- arcs = states[state] +- # Look for a state with this label +- for i, newstate in arcs: +- t, v = self.grammar.labels[i] +- if ilabel == i: +- # Look it up in the list of labels +- assert t < 256 +- # Shift a token; we're done with it +- self.shift(type, value, newstate, context) +- # Pop while we are in an accept-only state +- state = newstate +- while states[state] == [(0, state)]: +- self.pop() +- if not self.stack: +- # Done parsing! +- return True +- dfa, state, node = self.stack[-1] +- states, first = dfa +- # Done with this token +- return False +- elif t >= 256: +- # See if it's a symbol and if we're in its first set +- itsdfa = self.grammar.dfas[t] +- itsstates, itsfirst = itsdfa +- if ilabel in itsfirst: +- # Push a symbol +- self.push(t, self.grammar.dfas[t], newstate, context) +- break # To continue the outer while loop +- else: +- if (0, state) in arcs: +- # An accepting state, pop it and try something else +- self.pop() +- if not self.stack: +- # Done parsing, but another token is input +- raise ParseError("too much input", +- type, value, context) +- else: +- # No success finding a transition +- raise ParseError("bad input", type, value, context) +- +- def classify(self, type, value, context): +- """Turn a token into a label. (Internal)""" +- if type == token.NAME: +- # Keep a listing of all used names +- self.used_names.add(value) +- # Check for reserved words +- ilabel = self.grammar.keywords.get(value) +- if ilabel is not None: +- return ilabel +- ilabel = self.grammar.tokens.get(type) +- if ilabel is None: +- raise ParseError("bad token", type, value, context) +- return ilabel +- +- def shift(self, type, value, newstate, context): +- """Shift a token. (Internal)""" +- dfa, state, node = self.stack[-1] +- newnode = (type, value, context, None) +- newnode = self.convert(self.grammar, newnode) +- if newnode is not None: +- node[-1].append(newnode) +- self.stack[-1] = (dfa, newstate, node) +- +- def push(self, type, newdfa, newstate, context): +- """Push a nonterminal. (Internal)""" +- dfa, state, node = self.stack[-1] +- newnode = (type, None, context, []) +- self.stack[-1] = (dfa, newstate, node) +- self.stack.append((newdfa, 0, newnode)) +- +- def pop(self): +- """Pop a nonterminal. (Internal)""" +- popdfa, popstate, popnode = self.stack.pop() +- newnode = self.convert(self.grammar, popnode) +- if newnode is not None: +- if self.stack: +- dfa, state, node = self.stack[-1] +- node[-1].append(newnode) +- else: +- self.rootnode = newnode +- self.rootnode.used_names = self.used_names +diff -r 531f2e948299 lib2to3/pgen2/pgen.py +--- a/lib2to3/pgen2/pgen.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,384 +0,0 @@ +-# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-# Pgen imports +-from . import grammar, token, tokenize +- +-class PgenGrammar(grammar.Grammar): +- pass +- +-class ParserGenerator(object): +- +- def __init__(self, filename, stream=None): +- close_stream = None +- if stream is None: +- stream = open(filename) +- close_stream = stream.close +- self.filename = filename +- self.stream = stream +- self.generator = tokenize.generate_tokens(stream.readline) +- self.gettoken() # Initialize lookahead +- self.dfas, self.startsymbol = self.parse() +- if close_stream is not None: +- close_stream() +- self.first = {} # map from symbol name to set of tokens +- self.addfirstsets() +- +- def make_grammar(self): +- c = PgenGrammar() +- names = self.dfas.keys() +- names.sort() +- names.remove(self.startsymbol) +- names.insert(0, self.startsymbol) +- for name in names: +- i = 256 + len(c.symbol2number) +- c.symbol2number[name] = i +- c.number2symbol[i] = name +- for name in names: +- dfa = self.dfas[name] +- states = [] +- for state in dfa: +- arcs = [] +- for label, next in state.arcs.iteritems(): +- arcs.append((self.make_label(c, label), dfa.index(next))) +- if state.isfinal: +- arcs.append((0, dfa.index(state))) +- states.append(arcs) +- c.states.append(states) +- c.dfas[c.symbol2number[name]] = (states, self.make_first(c, name)) +- c.start = c.symbol2number[self.startsymbol] +- return c +- +- def make_first(self, c, name): +- rawfirst = self.first[name] +- first = {} +- for label in rawfirst: +- ilabel = self.make_label(c, label) +- ##assert ilabel not in first # XXX failed on <> ... != +- first[ilabel] = 1 +- return first +- +- def make_label(self, c, label): +- # XXX Maybe this should be a method on a subclass of converter? +- ilabel = len(c.labels) +- if label[0].isalpha(): +- # Either a symbol name or a named token +- if label in c.symbol2number: +- # A symbol name (a non-terminal) +- if label in c.symbol2label: +- return c.symbol2label[label] +- else: +- c.labels.append((c.symbol2number[label], None)) +- c.symbol2label[label] = ilabel +- return ilabel +- else: +- # A named token (NAME, NUMBER, STRING) +- itoken = getattr(token, label, None) +- assert isinstance(itoken, int), label +- assert itoken in token.tok_name, label +- if itoken in c.tokens: +- return c.tokens[itoken] +- else: +- c.labels.append((itoken, None)) +- c.tokens[itoken] = ilabel +- return ilabel +- else: +- # Either a keyword or an operator +- assert label[0] in ('"', "'"), label +- value = eval(label) +- if value[0].isalpha(): +- # A keyword +- if value in c.keywords: +- return c.keywords[value] +- else: +- c.labels.append((token.NAME, value)) +- c.keywords[value] = ilabel +- return ilabel +- else: +- # An operator (any non-numeric token) +- itoken = grammar.opmap[value] # Fails if unknown token +- if itoken in c.tokens: +- return c.tokens[itoken] +- else: +- c.labels.append((itoken, None)) +- c.tokens[itoken] = ilabel +- return ilabel +- +- def addfirstsets(self): +- names = self.dfas.keys() +- names.sort() +- for name in names: +- if name not in self.first: +- self.calcfirst(name) +- #print name, self.first[name].keys() +- +- def calcfirst(self, name): +- dfa = self.dfas[name] +- self.first[name] = None # dummy to detect left recursion +- state = dfa[0] +- totalset = {} +- overlapcheck = {} +- for label, next in state.arcs.iteritems(): +- if label in self.dfas: +- if label in self.first: +- fset = self.first[label] +- if fset is None: +- raise ValueError("recursion for rule %r" % name) +- else: +- self.calcfirst(label) +- fset = self.first[label] +- totalset.update(fset) +- overlapcheck[label] = fset +- else: +- totalset[label] = 1 +- overlapcheck[label] = {label: 1} +- inverse = {} +- for label, itsfirst in overlapcheck.iteritems(): +- for symbol in itsfirst: +- if symbol in inverse: +- raise ValueError("rule %s is ambiguous; %s is in the" +- " first sets of %s as well as %s" % +- (name, symbol, label, inverse[symbol])) +- inverse[symbol] = label +- self.first[name] = totalset +- +- def parse(self): +- dfas = {} +- startsymbol = None +- # MSTART: (NEWLINE | RULE)* ENDMARKER +- while self.type != token.ENDMARKER: +- while self.type == token.NEWLINE: +- self.gettoken() +- # RULE: NAME ':' RHS NEWLINE +- name = self.expect(token.NAME) +- self.expect(token.OP, ":") +- a, z = self.parse_rhs() +- self.expect(token.NEWLINE) +- #self.dump_nfa(name, a, z) +- dfa = self.make_dfa(a, z) +- #self.dump_dfa(name, dfa) +- oldlen = len(dfa) +- self.simplify_dfa(dfa) +- newlen = len(dfa) +- dfas[name] = dfa +- #print name, oldlen, newlen +- if startsymbol is None: +- startsymbol = name +- return dfas, startsymbol +- +- def make_dfa(self, start, finish): +- # To turn an NFA into a DFA, we define the states of the DFA +- # to correspond to *sets* of states of the NFA. Then do some +- # state reduction. Let's represent sets as dicts with 1 for +- # values. +- assert isinstance(start, NFAState) +- assert isinstance(finish, NFAState) +- def closure(state): +- base = {} +- addclosure(state, base) +- return base +- def addclosure(state, base): +- assert isinstance(state, NFAState) +- if state in base: +- return +- base[state] = 1 +- for label, next in state.arcs: +- if label is None: +- addclosure(next, base) +- states = [DFAState(closure(start), finish)] +- for state in states: # NB states grows while we're iterating +- arcs = {} +- for nfastate in state.nfaset: +- for label, next in nfastate.arcs: +- if label is not None: +- addclosure(next, arcs.setdefault(label, {})) +- for label, nfaset in arcs.iteritems(): +- for st in states: +- if st.nfaset == nfaset: +- break +- else: +- st = DFAState(nfaset, finish) +- states.append(st) +- state.addarc(st, label) +- return states # List of DFAState instances; first one is start +- +- def dump_nfa(self, name, start, finish): +- print "Dump of NFA for", name +- todo = [start] +- for i, state in enumerate(todo): +- print " State", i, state is finish and "(final)" or "" +- for label, next in state.arcs: +- if next in todo: +- j = todo.index(next) +- else: +- j = len(todo) +- todo.append(next) +- if label is None: +- print " -> %d" % j +- else: +- print " %s -> %d" % (label, j) +- +- def dump_dfa(self, name, dfa): +- print "Dump of DFA for", name +- for i, state in enumerate(dfa): +- print " State", i, state.isfinal and "(final)" or "" +- for label, next in state.arcs.iteritems(): +- print " %s -> %d" % (label, dfa.index(next)) +- +- def simplify_dfa(self, dfa): +- # This is not theoretically optimal, but works well enough. +- # Algorithm: repeatedly look for two states that have the same +- # set of arcs (same labels pointing to the same nodes) and +- # unify them, until things stop changing. +- +- # dfa is a list of DFAState instances +- changes = True +- while changes: +- changes = False +- for i, state_i in enumerate(dfa): +- for j in range(i+1, len(dfa)): +- state_j = dfa[j] +- if state_i == state_j: +- #print " unify", i, j +- del dfa[j] +- for state in dfa: +- state.unifystate(state_j, state_i) +- changes = True +- break +- +- def parse_rhs(self): +- # RHS: ALT ('|' ALT)* +- a, z = self.parse_alt() +- if self.value != "|": +- return a, z +- else: +- aa = NFAState() +- zz = NFAState() +- aa.addarc(a) +- z.addarc(zz) +- while self.value == "|": +- self.gettoken() +- a, z = self.parse_alt() +- aa.addarc(a) +- z.addarc(zz) +- return aa, zz +- +- def parse_alt(self): +- # ALT: ITEM+ +- a, b = self.parse_item() +- while (self.value in ("(", "[") or +- self.type in (token.NAME, token.STRING)): +- c, d = self.parse_item() +- b.addarc(c) +- b = d +- return a, b +- +- def parse_item(self): +- # ITEM: '[' RHS ']' | ATOM ['+' | '*'] +- if self.value == "[": +- self.gettoken() +- a, z = self.parse_rhs() +- self.expect(token.OP, "]") +- a.addarc(z) +- return a, z +- else: +- a, z = self.parse_atom() +- value = self.value +- if value not in ("+", "*"): +- return a, z +- self.gettoken() +- z.addarc(a) +- if value == "+": +- return a, z +- else: +- return a, a +- +- def parse_atom(self): +- # ATOM: '(' RHS ')' | NAME | STRING +- if self.value == "(": +- self.gettoken() +- a, z = self.parse_rhs() +- self.expect(token.OP, ")") +- return a, z +- elif self.type in (token.NAME, token.STRING): +- a = NFAState() +- z = NFAState() +- a.addarc(z, self.value) +- self.gettoken() +- return a, z +- else: +- self.raise_error("expected (...) or NAME or STRING, got %s/%s", +- self.type, self.value) +- +- def expect(self, type, value=None): +- if self.type != type or (value is not None and self.value != value): +- self.raise_error("expected %s/%s, got %s/%s", +- type, value, self.type, self.value) +- value = self.value +- self.gettoken() +- return value +- +- def gettoken(self): +- tup = self.generator.next() +- while tup[0] in (tokenize.COMMENT, tokenize.NL): +- tup = self.generator.next() +- self.type, self.value, self.begin, self.end, self.line = tup +- #print token.tok_name[self.type], repr(self.value) +- +- def raise_error(self, msg, *args): +- if args: +- try: +- msg = msg % args +- except: +- msg = " ".join([msg] + map(str, args)) +- raise SyntaxError(msg, (self.filename, self.end[0], +- self.end[1], self.line)) +- +-class NFAState(object): +- +- def __init__(self): +- self.arcs = [] # list of (label, NFAState) pairs +- +- def addarc(self, next, label=None): +- assert label is None or isinstance(label, str) +- assert isinstance(next, NFAState) +- self.arcs.append((label, next)) +- +-class DFAState(object): +- +- def __init__(self, nfaset, final): +- assert isinstance(nfaset, dict) +- assert isinstance(iter(nfaset).next(), NFAState) +- assert isinstance(final, NFAState) +- self.nfaset = nfaset +- self.isfinal = final in nfaset +- self.arcs = {} # map from label to DFAState +- +- def addarc(self, next, label): +- assert isinstance(label, str) +- assert label not in self.arcs +- assert isinstance(next, DFAState) +- self.arcs[label] = next +- +- def unifystate(self, old, new): +- for label, next in self.arcs.iteritems(): +- if next is old: +- self.arcs[label] = new +- +- def __eq__(self, other): +- # Equality test -- ignore the nfaset instance variable +- assert isinstance(other, DFAState) +- if self.isfinal != other.isfinal: +- return False +- # Can't just return self.arcs == other.arcs, because that +- # would invoke this method recursively, with cycles... +- if len(self.arcs) != len(other.arcs): +- return False +- for label, next in self.arcs.iteritems(): +- if next is not other.arcs.get(label): +- return False +- return True +- +-def generate_grammar(filename="Grammar.txt"): +- p = ParserGenerator(filename) +- return p.make_grammar() +diff -r 531f2e948299 lib2to3/pgen2/token.py +--- a/lib2to3/pgen2/token.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,82 +0,0 @@ +-#! /usr/bin/env python +- +-"""Token constants (from "token.h").""" +- +-# Taken from Python (r53757) and modified to include some tokens +-# originally monkeypatched in by pgen2.tokenize +- +-#--start constants-- +-ENDMARKER = 0 +-NAME = 1 +-NUMBER = 2 +-STRING = 3 +-NEWLINE = 4 +-INDENT = 5 +-DEDENT = 6 +-LPAR = 7 +-RPAR = 8 +-LSQB = 9 +-RSQB = 10 +-COLON = 11 +-COMMA = 12 +-SEMI = 13 +-PLUS = 14 +-MINUS = 15 +-STAR = 16 +-SLASH = 17 +-VBAR = 18 +-AMPER = 19 +-LESS = 20 +-GREATER = 21 +-EQUAL = 22 +-DOT = 23 +-PERCENT = 24 +-BACKQUOTE = 25 +-LBRACE = 26 +-RBRACE = 27 +-EQEQUAL = 28 +-NOTEQUAL = 29 +-LESSEQUAL = 30 +-GREATEREQUAL = 31 +-TILDE = 32 +-CIRCUMFLEX = 33 +-LEFTSHIFT = 34 +-RIGHTSHIFT = 35 +-DOUBLESTAR = 36 +-PLUSEQUAL = 37 +-MINEQUAL = 38 +-STAREQUAL = 39 +-SLASHEQUAL = 40 +-PERCENTEQUAL = 41 +-AMPEREQUAL = 42 +-VBAREQUAL = 43 +-CIRCUMFLEXEQUAL = 44 +-LEFTSHIFTEQUAL = 45 +-RIGHTSHIFTEQUAL = 46 +-DOUBLESTAREQUAL = 47 +-DOUBLESLASH = 48 +-DOUBLESLASHEQUAL = 49 +-AT = 50 +-OP = 51 +-COMMENT = 52 +-NL = 53 +-RARROW = 54 +-ERRORTOKEN = 55 +-N_TOKENS = 56 +-NT_OFFSET = 256 +-#--end constants-- +- +-tok_name = {} +-for _name, _value in globals().items(): +- if type(_value) is type(0): +- tok_name[_value] = _name +- +- +-def ISTERMINAL(x): +- return x < NT_OFFSET +- +-def ISNONTERMINAL(x): +- return x >= NT_OFFSET +- +-def ISEOF(x): +- return x == ENDMARKER +diff -r 531f2e948299 lib2to3/pgen2/tokenize.py +--- a/lib2to3/pgen2/tokenize.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,405 +0,0 @@ +-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation. +-# All rights reserved. +- +-"""Tokenization help for Python programs. +- +-generate_tokens(readline) is a generator that breaks a stream of +-text into Python tokens. It accepts a readline-like method which is called +-repeatedly to get the next line of input (or "" for EOF). It generates +-5-tuples with these members: +- +- the token type (see token.py) +- the token (a string) +- the starting (row, column) indices of the token (a 2-tuple of ints) +- the ending (row, column) indices of the token (a 2-tuple of ints) +- the original line (string) +- +-It is designed to match the working of the Python tokenizer exactly, except +-that it produces COMMENT tokens for comments and gives type OP for all +-operators +- +-Older entry points +- tokenize_loop(readline, tokeneater) +- tokenize(readline, tokeneater=printtoken) +-are the same, except instead of generating tokens, tokeneater is a callback +-function to which the 5 fields described above are passed as 5 arguments, +-each time a new token is found.""" +- +-__author__ = 'Ka-Ping Yee ' +-__credits__ = \ +- 'GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, Skip Montanaro' +- +-import string, re +-from lib2to3.pgen2.token import * +- +-from . import token +-__all__ = [x for x in dir(token) if x[0] != '_'] + ["tokenize", +- "generate_tokens", "untokenize"] +-del token +- +-def group(*choices): return '(' + '|'.join(choices) + ')' +-def any(*choices): return group(*choices) + '*' +-def maybe(*choices): return group(*choices) + '?' +- +-Whitespace = r'[ \f\t]*' +-Comment = r'#[^\r\n]*' +-Ignore = Whitespace + any(r'\\\r?\n' + Whitespace) + maybe(Comment) +-Name = r'[a-zA-Z_]\w*' +- +-Binnumber = r'0[bB][01]*' +-Hexnumber = r'0[xX][\da-fA-F]*[lL]?' +-Octnumber = r'0[oO]?[0-7]*[lL]?' +-Decnumber = r'[1-9]\d*[lL]?' +-Intnumber = group(Binnumber, Hexnumber, Octnumber, Decnumber) +-Exponent = r'[eE][-+]?\d+' +-Pointfloat = group(r'\d+\.\d*', r'\.\d+') + maybe(Exponent) +-Expfloat = r'\d+' + Exponent +-Floatnumber = group(Pointfloat, Expfloat) +-Imagnumber = group(r'\d+[jJ]', Floatnumber + r'[jJ]') +-Number = group(Imagnumber, Floatnumber, Intnumber) +- +-# Tail end of ' string. +-Single = r"[^'\\]*(?:\\.[^'\\]*)*'" +-# Tail end of " string. +-Double = r'[^"\\]*(?:\\.[^"\\]*)*"' +-# Tail end of ''' string. +-Single3 = r"[^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*'''" +-# Tail end of """ string. +-Double3 = r'[^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*"""' +-Triple = group("[ubUB]?[rR]?'''", '[ubUB]?[rR]?"""') +-# Single-line ' or " string. +-String = group(r"[uU]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*'", +- r'[uU]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*"') +- +-# Because of leftmost-then-longest match semantics, be sure to put the +-# longest operators first (e.g., if = came before ==, == would get +-# recognized as two instances of =). +-Operator = group(r"\*\*=?", r">>=?", r"<<=?", r"<>", r"!=", +- r"//=?", r"->", +- r"[+\-*/%&|^=<>]=?", +- r"~") +- +-Bracket = '[][(){}]' +-Special = group(r'\r?\n', r'[:;.,`@]') +-Funny = group(Operator, Bracket, Special) +- +-PlainToken = group(Number, Funny, String, Name) +-Token = Ignore + PlainToken +- +-# First (or only) line of ' or " string. +-ContStr = group(r"[uUbB]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*" + +- group("'", r'\\\r?\n'), +- r'[uUbB]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*' + +- group('"', r'\\\r?\n')) +-PseudoExtras = group(r'\\\r?\n', Comment, Triple) +-PseudoToken = Whitespace + group(PseudoExtras, Number, Funny, ContStr, Name) +- +-tokenprog, pseudoprog, single3prog, double3prog = map( +- re.compile, (Token, PseudoToken, Single3, Double3)) +-endprogs = {"'": re.compile(Single), '"': re.compile(Double), +- "'''": single3prog, '"""': double3prog, +- "r'''": single3prog, 'r"""': double3prog, +- "u'''": single3prog, 'u"""': double3prog, +- "b'''": single3prog, 'b"""': double3prog, +- "ur'''": single3prog, 'ur"""': double3prog, +- "br'''": single3prog, 'br"""': double3prog, +- "R'''": single3prog, 'R"""': double3prog, +- "U'''": single3prog, 'U"""': double3prog, +- "B'''": single3prog, 'B"""': double3prog, +- "uR'''": single3prog, 'uR"""': double3prog, +- "Ur'''": single3prog, 'Ur"""': double3prog, +- "UR'''": single3prog, 'UR"""': double3prog, +- "bR'''": single3prog, 'bR"""': double3prog, +- "Br'''": single3prog, 'Br"""': double3prog, +- "BR'''": single3prog, 'BR"""': double3prog, +- 'r': None, 'R': None, +- 'u': None, 'U': None, +- 'b': None, 'B': None} +- +-triple_quoted = {} +-for t in ("'''", '"""', +- "r'''", 'r"""', "R'''", 'R"""', +- "u'''", 'u"""', "U'''", 'U"""', +- "b'''", 'b"""', "B'''", 'B"""', +- "ur'''", 'ur"""', "Ur'''", 'Ur"""', +- "uR'''", 'uR"""', "UR'''", 'UR"""', +- "br'''", 'br"""', "Br'''", 'Br"""', +- "bR'''", 'bR"""', "BR'''", 'BR"""',): +- triple_quoted[t] = t +-single_quoted = {} +-for t in ("'", '"', +- "r'", 'r"', "R'", 'R"', +- "u'", 'u"', "U'", 'U"', +- "b'", 'b"', "B'", 'B"', +- "ur'", 'ur"', "Ur'", 'Ur"', +- "uR'", 'uR"', "UR'", 'UR"', +- "br'", 'br"', "Br'", 'Br"', +- "bR'", 'bR"', "BR'", 'BR"', ): +- single_quoted[t] = t +- +-tabsize = 8 +- +-class TokenError(Exception): pass +- +-class StopTokenizing(Exception): pass +- +-def printtoken(type, token, (srow, scol), (erow, ecol), line): # for testing +- print "%d,%d-%d,%d:\t%s\t%s" % \ +- (srow, scol, erow, ecol, tok_name[type], repr(token)) +- +-def tokenize(readline, tokeneater=printtoken): +- """ +- The tokenize() function accepts two parameters: one representing the +- input stream, and one providing an output mechanism for tokenize(). +- +- The first parameter, readline, must be a callable object which provides +- the same interface as the readline() method of built-in file objects. +- Each call to the function should return one line of input as a string. +- +- The second parameter, tokeneater, must also be a callable object. It is +- called once for each token, with five arguments, corresponding to the +- tuples generated by generate_tokens(). +- """ +- try: +- tokenize_loop(readline, tokeneater) +- except StopTokenizing: +- pass +- +-# backwards compatible interface +-def tokenize_loop(readline, tokeneater): +- for token_info in generate_tokens(readline): +- tokeneater(*token_info) +- +-class Untokenizer: +- +- def __init__(self): +- self.tokens = [] +- self.prev_row = 1 +- self.prev_col = 0 +- +- def add_whitespace(self, start): +- row, col = start +- assert row <= self.prev_row +- col_offset = col - self.prev_col +- if col_offset: +- self.tokens.append(" " * col_offset) +- +- def untokenize(self, iterable): +- for t in iterable: +- if len(t) == 2: +- self.compat(t, iterable) +- break +- tok_type, token, start, end, line = t +- self.add_whitespace(start) +- self.tokens.append(token) +- self.prev_row, self.prev_col = end +- if tok_type in (NEWLINE, NL): +- self.prev_row += 1 +- self.prev_col = 0 +- return "".join(self.tokens) +- +- def compat(self, token, iterable): +- startline = False +- indents = [] +- toks_append = self.tokens.append +- toknum, tokval = token +- if toknum in (NAME, NUMBER): +- tokval += ' ' +- if toknum in (NEWLINE, NL): +- startline = True +- for tok in iterable: +- toknum, tokval = tok[:2] +- +- if toknum in (NAME, NUMBER): +- tokval += ' ' +- +- if toknum == INDENT: +- indents.append(tokval) +- continue +- elif toknum == DEDENT: +- indents.pop() +- continue +- elif toknum in (NEWLINE, NL): +- startline = True +- elif startline and indents: +- toks_append(indents[-1]) +- startline = False +- toks_append(tokval) +- +-def untokenize(iterable): +- """Transform tokens back into Python source code. +- +- Each element returned by the iterable must be a token sequence +- with at least two elements, a token number and token value. If +- only two tokens are passed, the resulting output is poor. +- +- Round-trip invariant for full input: +- Untokenized source will match input source exactly +- +- Round-trip invariant for limited intput: +- # Output text will tokenize the back to the input +- t1 = [tok[:2] for tok in generate_tokens(f.readline)] +- newcode = untokenize(t1) +- readline = iter(newcode.splitlines(1)).next +- t2 = [tok[:2] for tokin generate_tokens(readline)] +- assert t1 == t2 +- """ +- ut = Untokenizer() +- return ut.untokenize(iterable) +- +-def generate_tokens(readline): +- """ +- The generate_tokens() generator requires one argment, readline, which +- must be a callable object which provides the same interface as the +- readline() method of built-in file objects. Each call to the function +- should return one line of input as a string. Alternately, readline +- can be a callable function terminating with StopIteration: +- readline = open(myfile).next # Example of alternate readline +- +- The generator produces 5-tuples with these members: the token type; the +- token string; a 2-tuple (srow, scol) of ints specifying the row and +- column where the token begins in the source; a 2-tuple (erow, ecol) of +- ints specifying the row and column where the token ends in the source; +- and the line on which the token was found. The line passed is the +- logical line; continuation lines are included. +- """ +- lnum = parenlev = continued = 0 +- namechars, numchars = string.ascii_letters + '_', '0123456789' +- contstr, needcont = '', 0 +- contline = None +- indents = [0] +- +- while 1: # loop over lines in stream +- try: +- line = readline() +- except StopIteration: +- line = '' +- lnum = lnum + 1 +- pos, max = 0, len(line) +- +- if contstr: # continued string +- if not line: +- raise TokenError, ("EOF in multi-line string", strstart) +- endmatch = endprog.match(line) +- if endmatch: +- pos = end = endmatch.end(0) +- yield (STRING, contstr + line[:end], +- strstart, (lnum, end), contline + line) +- contstr, needcont = '', 0 +- contline = None +- elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n': +- yield (ERRORTOKEN, contstr + line, +- strstart, (lnum, len(line)), contline) +- contstr = '' +- contline = None +- continue +- else: +- contstr = contstr + line +- contline = contline + line +- continue +- +- elif parenlev == 0 and not continued: # new statement +- if not line: break +- column = 0 +- while pos < max: # measure leading whitespace +- if line[pos] == ' ': column = column + 1 +- elif line[pos] == '\t': column = (column/tabsize + 1)*tabsize +- elif line[pos] == '\f': column = 0 +- else: break +- pos = pos + 1 +- if pos == max: break +- +- if line[pos] in '#\r\n': # skip comments or blank lines +- if line[pos] == '#': +- comment_token = line[pos:].rstrip('\r\n') +- nl_pos = pos + len(comment_token) +- yield (COMMENT, comment_token, +- (lnum, pos), (lnum, pos + len(comment_token)), line) +- yield (NL, line[nl_pos:], +- (lnum, nl_pos), (lnum, len(line)), line) +- else: +- yield ((NL, COMMENT)[line[pos] == '#'], line[pos:], +- (lnum, pos), (lnum, len(line)), line) +- continue +- +- if column > indents[-1]: # count indents or dedents +- indents.append(column) +- yield (INDENT, line[:pos], (lnum, 0), (lnum, pos), line) +- while column < indents[-1]: +- if column not in indents: +- raise IndentationError( +- "unindent does not match any outer indentation level", +- ("", lnum, pos, line)) +- indents = indents[:-1] +- yield (DEDENT, '', (lnum, pos), (lnum, pos), line) +- +- else: # continued statement +- if not line: +- raise TokenError, ("EOF in multi-line statement", (lnum, 0)) +- continued = 0 +- +- while pos < max: +- pseudomatch = pseudoprog.match(line, pos) +- if pseudomatch: # scan for tokens +- start, end = pseudomatch.span(1) +- spos, epos, pos = (lnum, start), (lnum, end), end +- token, initial = line[start:end], line[start] +- +- if initial in numchars or \ +- (initial == '.' and token != '.'): # ordinary number +- yield (NUMBER, token, spos, epos, line) +- elif initial in '\r\n': +- newline = NEWLINE +- if parenlev > 0: +- newline = NL +- yield (newline, token, spos, epos, line) +- elif initial == '#': +- assert not token.endswith("\n") +- yield (COMMENT, token, spos, epos, line) +- elif token in triple_quoted: +- endprog = endprogs[token] +- endmatch = endprog.match(line, pos) +- if endmatch: # all on one line +- pos = endmatch.end(0) +- token = line[start:pos] +- yield (STRING, token, spos, (lnum, pos), line) +- else: +- strstart = (lnum, start) # multiple lines +- contstr = line[start:] +- contline = line +- break +- elif initial in single_quoted or \ +- token[:2] in single_quoted or \ +- token[:3] in single_quoted: +- if token[-1] == '\n': # continued string +- strstart = (lnum, start) +- endprog = (endprogs[initial] or endprogs[token[1]] or +- endprogs[token[2]]) +- contstr, needcont = line[start:], 1 +- contline = line +- break +- else: # ordinary string +- yield (STRING, token, spos, epos, line) +- elif initial in namechars: # ordinary name +- yield (NAME, token, spos, epos, line) +- elif initial == '\\': # continued stmt +- # This yield is new; needed for better idempotency: +- yield (NL, token, spos, (lnum, pos), line) +- continued = 1 +- else: +- if initial in '([{': parenlev = parenlev + 1 +- elif initial in ')]}': parenlev = parenlev - 1 +- yield (OP, token, spos, epos, line) +- else: +- yield (ERRORTOKEN, line[pos], +- (lnum, pos), (lnum, pos+1), line) +- pos = pos + 1 +- +- for indent in indents[1:]: # pop remaining indent levels +- yield (DEDENT, '', (lnum, 0), (lnum, 0), '') +- yield (ENDMARKER, '', (lnum, 0), (lnum, 0), '') +- +-if __name__ == '__main__': # testing +- import sys +- if len(sys.argv) > 1: tokenize(open(sys.argv[1]).readline) +- else: tokenize(sys.stdin.readline) +diff -r 531f2e948299 lib2to3/pygram.py +--- a/lib2to3/pygram.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,31 +0,0 @@ +-# Copyright 2006 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Export the Python grammar and symbols.""" +- +-# Python imports +-import os +- +-# Local imports +-from .pgen2 import token +-from .pgen2 import driver +-from . import pytree +- +-# The grammar file +-_GRAMMAR_FILE = os.path.join(os.path.dirname(__file__), "Grammar.txt") +- +- +-class Symbols(object): +- +- def __init__(self, grammar): +- """Initializer. +- +- Creates an attribute for each grammar symbol (nonterminal), +- whose value is the symbol's type (an int >= 256). +- """ +- for name, symbol in grammar.symbol2number.iteritems(): +- setattr(self, name, symbol) +- +- +-python_grammar = driver.load_grammar(_GRAMMAR_FILE) +-python_symbols = Symbols(python_grammar) +diff -r 531f2e948299 lib2to3/pytree.py +--- a/lib2to3/pytree.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,846 +0,0 @@ +-# Copyright 2006 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-""" +-Python parse tree definitions. +- +-This is a very concrete parse tree; we need to keep every token and +-even the comments and whitespace between tokens. +- +-There's also a pattern matching implementation here. +-""" +- +-__author__ = "Guido van Rossum " +- +-import sys +-from StringIO import StringIO +- +- +-HUGE = 0x7FFFFFFF # maximum repeat count, default max +- +-_type_reprs = {} +-def type_repr(type_num): +- global _type_reprs +- if not _type_reprs: +- from .pygram import python_symbols +- # printing tokens is possible but not as useful +- # from .pgen2 import token // token.__dict__.items(): +- for name, val in python_symbols.__dict__.items(): +- if type(val) == int: _type_reprs[val] = name +- return _type_reprs.setdefault(type_num, type_num) +- +- +-class Base(object): +- +- """ +- Abstract base class for Node and Leaf. +- +- This provides some default functionality and boilerplate using the +- template pattern. +- +- A node may be a subnode of at most one parent. +- """ +- +- # Default values for instance variables +- type = None # int: token number (< 256) or symbol number (>= 256) +- parent = None # Parent node pointer, or None +- children = () # Tuple of subnodes +- was_changed = False +- +- def __new__(cls, *args, **kwds): +- """Constructor that prevents Base from being instantiated.""" +- assert cls is not Base, "Cannot instantiate Base" +- return object.__new__(cls) +- +- def __eq__(self, other): +- """ +- Compare two nodes for equality. +- +- This calls the method _eq(). +- """ +- if self.__class__ is not other.__class__: +- return NotImplemented +- return self._eq(other) +- +- def __ne__(self, other): +- """ +- Compare two nodes for inequality. +- +- This calls the method _eq(). +- """ +- if self.__class__ is not other.__class__: +- return NotImplemented +- return not self._eq(other) +- +- def _eq(self, other): +- """ +- Compare two nodes for equality. +- +- This is called by __eq__ and __ne__. It is only called if the two nodes +- have the same type. This must be implemented by the concrete subclass. +- Nodes should be considered equal if they have the same structure, +- ignoring the prefix string and other context information. +- """ +- raise NotImplementedError +- +- def clone(self): +- """ +- Return a cloned (deep) copy of self. +- +- This must be implemented by the concrete subclass. +- """ +- raise NotImplementedError +- +- def post_order(self): +- """ +- Return a post-order iterator for the tree. +- +- This must be implemented by the concrete subclass. +- """ +- raise NotImplementedError +- +- def pre_order(self): +- """ +- Return a pre-order iterator for the tree. +- +- This must be implemented by the concrete subclass. +- """ +- raise NotImplementedError +- +- def set_prefix(self, prefix): +- """ +- Set the prefix for the node (see Leaf class). +- +- This must be implemented by the concrete subclass. +- """ +- raise NotImplementedError +- +- def get_prefix(self): +- """ +- Return the prefix for the node (see Leaf class). +- +- This must be implemented by the concrete subclass. +- """ +- raise NotImplementedError +- +- def replace(self, new): +- """Replace this node with a new one in the parent.""" +- assert self.parent is not None, str(self) +- assert new is not None +- if not isinstance(new, list): +- new = [new] +- l_children = [] +- found = False +- for ch in self.parent.children: +- if ch is self: +- assert not found, (self.parent.children, self, new) +- if new is not None: +- l_children.extend(new) +- found = True +- else: +- l_children.append(ch) +- assert found, (self.children, self, new) +- self.parent.changed() +- self.parent.children = l_children +- for x in new: +- x.parent = self.parent +- self.parent = None +- +- def get_lineno(self): +- """Return the line number which generated the invocant node.""" +- node = self +- while not isinstance(node, Leaf): +- if not node.children: +- return +- node = node.children[0] +- return node.lineno +- +- def changed(self): +- if self.parent: +- self.parent.changed() +- self.was_changed = True +- +- def remove(self): +- """ +- Remove the node from the tree. Returns the position of the node in its +- parent's children before it was removed. +- """ +- if self.parent: +- for i, node in enumerate(self.parent.children): +- if node is self: +- self.parent.changed() +- del self.parent.children[i] +- self.parent = None +- return i +- +- @property +- def next_sibling(self): +- """ +- The node immediately following the invocant in their parent's children +- list. If the invocant does not have a next sibling, it is None +- """ +- if self.parent is None: +- return None +- +- # Can't use index(); we need to test by identity +- for i, child in enumerate(self.parent.children): +- if child is self: +- try: +- return self.parent.children[i+1] +- except IndexError: +- return None +- +- @property +- def prev_sibling(self): +- """ +- The node immediately preceding the invocant in their parent's children +- list. If the invocant does not have a previous sibling, it is None. +- """ +- if self.parent is None: +- return None +- +- # Can't use index(); we need to test by identity +- for i, child in enumerate(self.parent.children): +- if child is self: +- if i == 0: +- return None +- return self.parent.children[i-1] +- +- def get_suffix(self): +- """ +- Return the string immediately following the invocant node. This is +- effectively equivalent to node.next_sibling.get_prefix() +- """ +- next_sib = self.next_sibling +- if next_sib is None: +- return "" +- return next_sib.get_prefix() +- +- +-class Node(Base): +- +- """Concrete implementation for interior nodes.""" +- +- def __init__(self, type, children, context=None, prefix=None): +- """ +- Initializer. +- +- Takes a type constant (a symbol number >= 256), a sequence of +- child nodes, and an optional context keyword argument. +- +- As a side effect, the parent pointers of the children are updated. +- """ +- assert type >= 256, type +- self.type = type +- self.children = list(children) +- for ch in self.children: +- assert ch.parent is None, repr(ch) +- ch.parent = self +- if prefix is not None: +- self.set_prefix(prefix) +- +- def __repr__(self): +- """Return a canonical string representation.""" +- return "%s(%s, %r)" % (self.__class__.__name__, +- type_repr(self.type), +- self.children) +- +- def __str__(self): +- """ +- Return a pretty string representation. +- +- This reproduces the input source exactly. +- """ +- return "".join(map(str, self.children)) +- +- def _eq(self, other): +- """Compare two nodes for equality.""" +- return (self.type, self.children) == (other.type, other.children) +- +- def clone(self): +- """Return a cloned (deep) copy of self.""" +- return Node(self.type, [ch.clone() for ch in self.children]) +- +- def post_order(self): +- """Return a post-order iterator for the tree.""" +- for child in self.children: +- for node in child.post_order(): +- yield node +- yield self +- +- def pre_order(self): +- """Return a pre-order iterator for the tree.""" +- yield self +- for child in self.children: +- for node in child.post_order(): +- yield node +- +- def set_prefix(self, prefix): +- """ +- Set the prefix for the node. +- +- This passes the responsibility on to the first child. +- """ +- if self.children: +- self.children[0].set_prefix(prefix) +- +- def get_prefix(self): +- """ +- Return the prefix for the node. +- +- This passes the call on to the first child. +- """ +- if not self.children: +- return "" +- return self.children[0].get_prefix() +- +- def set_child(self, i, child): +- """ +- Equivalent to 'node.children[i] = child'. This method also sets the +- child's parent attribute appropriately. +- """ +- child.parent = self +- self.children[i].parent = None +- self.children[i] = child +- self.changed() +- +- def insert_child(self, i, child): +- """ +- Equivalent to 'node.children.insert(i, child)'. This method also sets +- the child's parent attribute appropriately. +- """ +- child.parent = self +- self.children.insert(i, child) +- self.changed() +- +- def append_child(self, child): +- """ +- Equivalent to 'node.children.append(child)'. This method also sets the +- child's parent attribute appropriately. +- """ +- child.parent = self +- self.children.append(child) +- self.changed() +- +- +-class Leaf(Base): +- +- """Concrete implementation for leaf nodes.""" +- +- # Default values for instance variables +- prefix = "" # Whitespace and comments preceding this token in the input +- lineno = 0 # Line where this token starts in the input +- column = 0 # Column where this token tarts in the input +- +- def __init__(self, type, value, context=None, prefix=None): +- """ +- Initializer. +- +- Takes a type constant (a token number < 256), a string value, and an +- optional context keyword argument. +- """ +- assert 0 <= type < 256, type +- if context is not None: +- self.prefix, (self.lineno, self.column) = context +- self.type = type +- self.value = value +- if prefix is not None: +- self.prefix = prefix +- +- def __repr__(self): +- """Return a canonical string representation.""" +- return "%s(%r, %r)" % (self.__class__.__name__, +- self.type, +- self.value) +- +- def __str__(self): +- """ +- Return a pretty string representation. +- +- This reproduces the input source exactly. +- """ +- return self.prefix + str(self.value) +- +- def _eq(self, other): +- """Compare two nodes for equality.""" +- return (self.type, self.value) == (other.type, other.value) +- +- def clone(self): +- """Return a cloned (deep) copy of self.""" +- return Leaf(self.type, self.value, +- (self.prefix, (self.lineno, self.column))) +- +- def post_order(self): +- """Return a post-order iterator for the tree.""" +- yield self +- +- def pre_order(self): +- """Return a pre-order iterator for the tree.""" +- yield self +- +- def set_prefix(self, prefix): +- """Set the prefix for the node.""" +- self.changed() +- self.prefix = prefix +- +- def get_prefix(self): +- """Return the prefix for the node.""" +- return self.prefix +- +- +-def convert(gr, raw_node): +- """ +- Convert raw node information to a Node or Leaf instance. +- +- This is passed to the parser driver which calls it whenever a reduction of a +- grammar rule produces a new complete node, so that the tree is build +- strictly bottom-up. +- """ +- type, value, context, children = raw_node +- if children or type in gr.number2symbol: +- # If there's exactly one child, return that child instead of +- # creating a new node. +- if len(children) == 1: +- return children[0] +- return Node(type, children, context=context) +- else: +- return Leaf(type, value, context=context) +- +- +-class BasePattern(object): +- +- """ +- A pattern is a tree matching pattern. +- +- It looks for a specific node type (token or symbol), and +- optionally for a specific content. +- +- This is an abstract base class. There are three concrete +- subclasses: +- +- - LeafPattern matches a single leaf node; +- - NodePattern matches a single node (usually non-leaf); +- - WildcardPattern matches a sequence of nodes of variable length. +- """ +- +- # Defaults for instance variables +- type = None # Node type (token if < 256, symbol if >= 256) +- content = None # Optional content matching pattern +- name = None # Optional name used to store match in results dict +- +- def __new__(cls, *args, **kwds): +- """Constructor that prevents BasePattern from being instantiated.""" +- assert cls is not BasePattern, "Cannot instantiate BasePattern" +- return object.__new__(cls) +- +- def __repr__(self): +- args = [type_repr(self.type), self.content, self.name] +- while args and args[-1] is None: +- del args[-1] +- return "%s(%s)" % (self.__class__.__name__, ", ".join(map(repr, args))) +- +- def optimize(self): +- """ +- A subclass can define this as a hook for optimizations. +- +- Returns either self or another node with the same effect. +- """ +- return self +- +- def match(self, node, results=None): +- """ +- Does this pattern exactly match a node? +- +- Returns True if it matches, False if not. +- +- If results is not None, it must be a dict which will be +- updated with the nodes matching named subpatterns. +- +- Default implementation for non-wildcard patterns. +- """ +- if self.type is not None and node.type != self.type: +- return False +- if self.content is not None: +- r = None +- if results is not None: +- r = {} +- if not self._submatch(node, r): +- return False +- if r: +- results.update(r) +- if results is not None and self.name: +- results[self.name] = node +- return True +- +- def match_seq(self, nodes, results=None): +- """ +- Does this pattern exactly match a sequence of nodes? +- +- Default implementation for non-wildcard patterns. +- """ +- if len(nodes) != 1: +- return False +- return self.match(nodes[0], results) +- +- def generate_matches(self, nodes): +- """ +- Generator yielding all matches for this pattern. +- +- Default implementation for non-wildcard patterns. +- """ +- r = {} +- if nodes and self.match(nodes[0], r): +- yield 1, r +- +- +-class LeafPattern(BasePattern): +- +- def __init__(self, type=None, content=None, name=None): +- """ +- Initializer. Takes optional type, content, and name. +- +- The type, if given must be a token type (< 256). If not given, +- this matches any *leaf* node; the content may still be required. +- +- The content, if given, must be a string. +- +- If a name is given, the matching node is stored in the results +- dict under that key. +- """ +- if type is not None: +- assert 0 <= type < 256, type +- if content is not None: +- assert isinstance(content, basestring), repr(content) +- self.type = type +- self.content = content +- self.name = name +- +- def match(self, node, results=None): +- """Override match() to insist on a leaf node.""" +- if not isinstance(node, Leaf): +- return False +- return BasePattern.match(self, node, results) +- +- def _submatch(self, node, results=None): +- """ +- Match the pattern's content to the node's children. +- +- This assumes the node type matches and self.content is not None. +- +- Returns True if it matches, False if not. +- +- If results is not None, it must be a dict which will be +- updated with the nodes matching named subpatterns. +- +- When returning False, the results dict may still be updated. +- """ +- return self.content == node.value +- +- +-class NodePattern(BasePattern): +- +- wildcards = False +- +- def __init__(self, type=None, content=None, name=None): +- """ +- Initializer. Takes optional type, content, and name. +- +- The type, if given, must be a symbol type (>= 256). If the +- type is None this matches *any* single node (leaf or not), +- except if content is not None, in which it only matches +- non-leaf nodes that also match the content pattern. +- +- The content, if not None, must be a sequence of Patterns that +- must match the node's children exactly. If the content is +- given, the type must not be None. +- +- If a name is given, the matching node is stored in the results +- dict under that key. +- """ +- if type is not None: +- assert type >= 256, type +- if content is not None: +- assert not isinstance(content, basestring), repr(content) +- content = list(content) +- for i, item in enumerate(content): +- assert isinstance(item, BasePattern), (i, item) +- if isinstance(item, WildcardPattern): +- self.wildcards = True +- self.type = type +- self.content = content +- self.name = name +- +- def _submatch(self, node, results=None): +- """ +- Match the pattern's content to the node's children. +- +- This assumes the node type matches and self.content is not None. +- +- Returns True if it matches, False if not. +- +- If results is not None, it must be a dict which will be +- updated with the nodes matching named subpatterns. +- +- When returning False, the results dict may still be updated. +- """ +- if self.wildcards: +- for c, r in generate_matches(self.content, node.children): +- if c == len(node.children): +- if results is not None: +- results.update(r) +- return True +- return False +- if len(self.content) != len(node.children): +- return False +- for subpattern, child in zip(self.content, node.children): +- if not subpattern.match(child, results): +- return False +- return True +- +- +-class WildcardPattern(BasePattern): +- +- """ +- A wildcard pattern can match zero or more nodes. +- +- This has all the flexibility needed to implement patterns like: +- +- .* .+ .? .{m,n} +- (a b c | d e | f) +- (...)* (...)+ (...)? (...){m,n} +- +- except it always uses non-greedy matching. +- """ +- +- def __init__(self, content=None, min=0, max=HUGE, name=None): +- """ +- Initializer. +- +- Args: +- content: optional sequence of subsequences of patterns; +- if absent, matches one node; +- if present, each subsequence is an alternative [*] +- min: optinal minumum number of times to match, default 0 +- max: optional maximum number of times tro match, default HUGE +- name: optional name assigned to this match +- +- [*] Thus, if content is [[a, b, c], [d, e], [f, g, h]] this is +- equivalent to (a b c | d e | f g h); if content is None, +- this is equivalent to '.' in regular expression terms. +- The min and max parameters work as follows: +- min=0, max=maxint: .* +- min=1, max=maxint: .+ +- min=0, max=1: .? +- min=1, max=1: . +- If content is not None, replace the dot with the parenthesized +- list of alternatives, e.g. (a b c | d e | f g h)* +- """ +- assert 0 <= min <= max <= HUGE, (min, max) +- if content is not None: +- content = tuple(map(tuple, content)) # Protect against alterations +- # Check sanity of alternatives +- assert len(content), repr(content) # Can't have zero alternatives +- for alt in content: +- assert len(alt), repr(alt) # Can have empty alternatives +- self.content = content +- self.min = min +- self.max = max +- self.name = name +- +- def optimize(self): +- """Optimize certain stacked wildcard patterns.""" +- subpattern = None +- if (self.content is not None and +- len(self.content) == 1 and len(self.content[0]) == 1): +- subpattern = self.content[0][0] +- if self.min == 1 and self.max == 1: +- if self.content is None: +- return NodePattern(name=self.name) +- if subpattern is not None and self.name == subpattern.name: +- return subpattern.optimize() +- if (self.min <= 1 and isinstance(subpattern, WildcardPattern) and +- subpattern.min <= 1 and self.name == subpattern.name): +- return WildcardPattern(subpattern.content, +- self.min*subpattern.min, +- self.max*subpattern.max, +- subpattern.name) +- return self +- +- def match(self, node, results=None): +- """Does this pattern exactly match a node?""" +- return self.match_seq([node], results) +- +- def match_seq(self, nodes, results=None): +- """Does this pattern exactly match a sequence of nodes?""" +- for c, r in self.generate_matches(nodes): +- if c == len(nodes): +- if results is not None: +- results.update(r) +- if self.name: +- results[self.name] = list(nodes) +- return True +- return False +- +- def generate_matches(self, nodes): +- """ +- Generator yielding matches for a sequence of nodes. +- +- Args: +- nodes: sequence of nodes +- +- Yields: +- (count, results) tuples where: +- count: the match comprises nodes[:count]; +- results: dict containing named submatches. +- """ +- if self.content is None: +- # Shortcut for special case (see __init__.__doc__) +- for count in xrange(self.min, 1 + min(len(nodes), self.max)): +- r = {} +- if self.name: +- r[self.name] = nodes[:count] +- yield count, r +- elif self.name == "bare_name": +- yield self._bare_name_matches(nodes) +- else: +- # The reason for this is that hitting the recursion limit usually +- # results in some ugly messages about how RuntimeErrors are being +- # ignored. +- save_stderr = sys.stderr +- sys.stderr = StringIO() +- try: +- for count, r in self._recursive_matches(nodes, 0): +- if self.name: +- r[self.name] = nodes[:count] +- yield count, r +- except RuntimeError: +- # We fall back to the iterative pattern matching scheme if the recursive +- # scheme hits the recursion limit. +- for count, r in self._iterative_matches(nodes): +- if self.name: +- r[self.name] = nodes[:count] +- yield count, r +- finally: +- sys.stderr = save_stderr +- +- def _iterative_matches(self, nodes): +- """Helper to iteratively yield the matches.""" +- nodelen = len(nodes) +- if 0 >= self.min: +- yield 0, {} +- +- results = [] +- # generate matches that use just one alt from self.content +- for alt in self.content: +- for c, r in generate_matches(alt, nodes): +- yield c, r +- results.append((c, r)) +- +- # for each match, iterate down the nodes +- while results: +- new_results = [] +- for c0, r0 in results: +- # stop if the entire set of nodes has been matched +- if c0 < nodelen and c0 <= self.max: +- for alt in self.content: +- for c1, r1 in generate_matches(alt, nodes[c0:]): +- if c1 > 0: +- r = {} +- r.update(r0) +- r.update(r1) +- yield c0 + c1, r +- new_results.append((c0 + c1, r)) +- results = new_results +- +- def _bare_name_matches(self, nodes): +- """Special optimized matcher for bare_name.""" +- count = 0 +- r = {} +- done = False +- max = len(nodes) +- while not done and count < max: +- done = True +- for leaf in self.content: +- if leaf[0].match(nodes[count], r): +- count += 1 +- done = False +- break +- r[self.name] = nodes[:count] +- return count, r +- +- def _recursive_matches(self, nodes, count): +- """Helper to recursively yield the matches.""" +- assert self.content is not None +- if count >= self.min: +- yield 0, {} +- if count < self.max: +- for alt in self.content: +- for c0, r0 in generate_matches(alt, nodes): +- for c1, r1 in self._recursive_matches(nodes[c0:], count+1): +- r = {} +- r.update(r0) +- r.update(r1) +- yield c0 + c1, r +- +- +-class NegatedPattern(BasePattern): +- +- def __init__(self, content=None): +- """ +- Initializer. +- +- The argument is either a pattern or None. If it is None, this +- only matches an empty sequence (effectively '$' in regex +- lingo). If it is not None, this matches whenever the argument +- pattern doesn't have any matches. +- """ +- if content is not None: +- assert isinstance(content, BasePattern), repr(content) +- self.content = content +- +- def match(self, node): +- # We never match a node in its entirety +- return False +- +- def match_seq(self, nodes): +- # We only match an empty sequence of nodes in its entirety +- return len(nodes) == 0 +- +- def generate_matches(self, nodes): +- if self.content is None: +- # Return a match if there is an empty sequence +- if len(nodes) == 0: +- yield 0, {} +- else: +- # Return a match if the argument pattern has no matches +- for c, r in self.content.generate_matches(nodes): +- return +- yield 0, {} +- +- +-def generate_matches(patterns, nodes): +- """ +- Generator yielding matches for a sequence of patterns and nodes. +- +- Args: +- patterns: a sequence of patterns +- nodes: a sequence of nodes +- +- Yields: +- (count, results) tuples where: +- count: the entire sequence of patterns matches nodes[:count]; +- results: dict containing named submatches. +- """ +- if not patterns: +- yield 0, {} +- else: +- p, rest = patterns[0], patterns[1:] +- for c0, r0 in p.generate_matches(nodes): +- if not rest: +- yield c0, r0 +- else: +- for c1, r1 in generate_matches(rest, nodes[c0:]): +- r = {} +- r.update(r0) +- r.update(r1) +- yield c0 + c1, r +diff -r 531f2e948299 lib2to3/refactor.py +--- a/lib2to3/refactor.py Mon Mar 30 20:02:09 2009 -0500 ++++ /dev/null Thu Jan 01 00:00:00 1970 +0000 +@@ -1,515 +0,0 @@ +-#!/usr/bin/env python2.5 +-# Copyright 2006 Google, Inc. All Rights Reserved. +-# Licensed to PSF under a Contributor Agreement. +- +-"""Refactoring framework. +- +-Used as a main program, this can refactor any number of files and/or +-recursively descend down directories. Imported as a module, this +-provides infrastructure to write your own refactoring tool. +-""" +- +-__author__ = "Guido van Rossum " +- +- +-# Python imports +-import os +-import sys +-import difflib +-import logging +-import operator +-from collections import defaultdict +-from itertools import chain +- +-# Local imports +-from .pgen2 import driver +-from .pgen2 import tokenize +- +-from . import pytree +-from . import patcomp +-from . import fixes +-from . import pygram +- +- +-def get_all_fix_names(fixer_pkg, remove_prefix=True): +- """Return a sorted list of all available fix names in the given package.""" +- pkg = __import__(fixer_pkg, [], [], ["*"]) +- fixer_dir = os.path.dirname(pkg.__file__) +- fix_names = [] +- for name in sorted(os.listdir(fixer_dir)): +- if name.startswith("fix_") and name.endswith(".py"): +- if remove_prefix: +- name = name[4:] +- fix_names.append(name[:-3]) +- return fix_names +- +-def get_head_types(pat): +- """ Accepts a pytree Pattern Node and returns a set +- of the pattern types which will match first. """ +- +- if isinstance(pat, (pytree.NodePattern, pytree.LeafPattern)): +- # NodePatters must either have no type and no content +- # or a type and content -- so they don't get any farther +- # Always return leafs +- return set([pat.type]) +- +- if isinstance(pat, pytree.NegatedPattern): +- if pat.content: +- return get_head_types(pat.content) +- return set([None]) # Negated Patterns don't have a type +- +- if isinstance(pat, pytree.WildcardPattern): +- # Recurse on each node in content +- r = set() +- for p in pat.content: +- for x in p: +- r.update(get_head_types(x)) +- return r +- +- raise Exception("Oh no! I don't understand pattern %s" %(pat)) +- +-def get_headnode_dict(fixer_list): +- """ Accepts a list of fixers and returns a dictionary +- of head node type --> fixer list. """ +- head_nodes = defaultdict(list) +- for fixer in fixer_list: +- if not fixer.pattern: +- head_nodes[None].append(fixer) +- continue +- for t in get_head_types(fixer.pattern): +- head_nodes[t].append(fixer) +- return head_nodes +- +-def get_fixers_from_package(pkg_name): +- """ +- Return the fully qualified names for fixers in the package pkg_name. +- """ +- return [pkg_name + "." + fix_name +- for fix_name in get_all_fix_names(pkg_name, False)] +- +- +-class FixerError(Exception): +- """A fixer could not be loaded.""" +- +- +-class RefactoringTool(object): +- +- _default_options = {"print_function": False} +- +- CLASS_PREFIX = "Fix" # The prefix for fixer classes +- FILE_PREFIX = "fix_" # The prefix for modules with a fixer within +- +- def __init__(self, fixer_names, options=None, explicit=None): +- """Initializer. +- +- Args: +- fixer_names: a list of fixers to import +- options: an dict with configuration. +- explicit: a list of fixers to run even if they are explicit. +- """ +- self.fixers = fixer_names +- self.explicit = explicit or [] +- self.options = self._default_options.copy() +- if options is not None: +- self.options.update(options) +- self.errors = [] +- self.logger = logging.getLogger("RefactoringTool") +- self.fixer_log = [] +- self.wrote = False +- if self.options["print_function"]: +- del pygram.python_grammar.keywords["print"] +- self.driver = driver.Driver(pygram.python_grammar, +- convert=pytree.convert, +- logger=self.logger) +- self.pre_order, self.post_order = self.get_fixers() +- +- self.pre_order_heads = get_headnode_dict(self.pre_order) +- self.post_order_heads = get_headnode_dict(self.post_order) +- +- self.files = [] # List of files that were or should be modified +- +- def get_fixers(self): +- """Inspects the options to load the requested patterns and handlers. +- +- Returns: +- (pre_order, post_order), where pre_order is the list of fixers that +- want a pre-order AST traversal, and post_order is the list that want +- post-order traversal. +- """ +- pre_order_fixers = [] +- post_order_fixers = [] +- for fix_mod_path in self.fixers: +- mod = __import__(fix_mod_path, {}, {}, ["*"]) +- fix_name = fix_mod_path.rsplit(".", 1)[-1] +- if fix_name.startswith(self.FILE_PREFIX): +- fix_name = fix_name[len(self.FILE_PREFIX):] +- parts = fix_name.split("_") +- class_name = self.CLASS_PREFIX + "".join([p.title() for p in parts]) +- try: +- fix_class = getattr(mod, class_name) +- except AttributeError: +- raise FixerError("Can't find %s.%s" % (fix_name, class_name)) +- fixer = fix_class(self.options, self.fixer_log) +- if fixer.explicit and self.explicit is not True and \ +- fix_mod_path not in self.explicit: +- self.log_message("Skipping implicit fixer: %s", fix_name) +- continue +- +- self.log_debug("Adding transformation: %s", fix_name) +- if fixer.order == "pre": +- pre_order_fixers.append(fixer) +- elif fixer.order == "post": +- post_order_fixers.append(fixer) +- else: +- raise FixerError("Illegal fixer order: %r" % fixer.order) +- +- key_func = operator.attrgetter("run_order") +- pre_order_fixers.sort(key=key_func) +- post_order_fixers.sort(key=key_func) +- return (pre_order_fixers, post_order_fixers) +- +- def log_error(self, msg, *args, **kwds): +- """Called when an error occurs.""" +- raise +- +- def log_message(self, msg, *args): +- """Hook to log a message.""" +- if args: +- msg = msg % args +- self.logger.info(msg) +- +- def log_debug(self, msg, *args): +- if args: +- msg = msg % args +- self.logger.debug(msg) +- +- def print_output(self, lines): +- """Called with lines of output to give to the user.""" +- pass +- +- def refactor(self, items, write=False, doctests_only=False): +- """Refactor a list of files and directories.""" +- for dir_or_file in items: +- if os.path.isdir(dir_or_file): +- self.refactor_dir(dir_or_file, write, doctests_only) +- else: +- self.refactor_file(dir_or_file, write, doctests_only) +- +- def refactor_dir(self, dir_name, write=False, doctests_only=False): +- """Descends down a directory and refactor every Python file found. +- +- Python files are assumed to have a .py extension. +- +- Files and subdirectories starting with '.' are skipped. +- """ +- 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 name.endswith("py"): +- fullname = os.path.join(dirpath, name) +- self.refactor_file(fullname, write, doctests_only) +- # Modify dirnames in-place to remove subdirs with leading dots +- dirnames[:] = [dn for dn in dirnames if not dn.startswith(".")] +- +- def refactor_file(self, filename, write=False, doctests_only=False): +- """Refactors a file.""" +- try: +- f = open(filename) +- except IOError, err: +- self.log_error("Can't open %s: %s", filename, err) +- return +- try: +- input = f.read() + "\n" # Silence certain parse errors +- finally: +- f.close() +- if doctests_only: +- self.log_debug("Refactoring doctests in %s", filename) +- output = self.refactor_docstring(input, filename) +- if output != input: +- self.processed_file(output, filename, input, write=write) +- else: +- self.log_debug("No doctest changes in %s", filename) +- else: +- tree = self.refactor_string(input, filename) +- if tree and tree.was_changed: +- # The [:-1] is to take off the \n we added earlier +- self.processed_file(str(tree)[:-1], filename, write=write) +- else: +- self.log_debug("No changes in %s", filename) +- +- def refactor_string(self, data, name): +- """Refactor a given input string. +- +- Args: +- data: a string holding the code to be refactored. +- name: a human-readable name for use in error/log messages. +- +- Returns: +- An AST corresponding to the refactored input stream; None if +- there were errors during the parse. +- """ +- try: +- tree = self.driver.parse_string(data) +- except Exception, err: +- self.log_error("Can't parse %s: %s: %s", +- name, err.__class__.__name__, err) +- return +- self.log_debug("Refactoring %s", name) +- self.refactor_tree(tree, name) +- return tree +- +- def refactor_stdin(self, doctests_only=False): +- input = sys.stdin.read() +- if doctests_only: +- self.log_debug("Refactoring doctests in stdin") +- output = self.refactor_docstring(input, "") +- if output != input: +- self.processed_file(output, "", input) +- else: +- self.log_debug("No doctest changes in stdin") +- else: +- tree = self.refactor_string(input, "") +- if tree and tree.was_changed: +- self.processed_file(str(tree), "", input) +- else: +- self.log_debug("No changes in stdin") +- +- def refactor_tree(self, tree, name): +- """Refactors a parse tree (modifying the tree in place). +- +- Args: +- tree: a pytree.Node instance representing the root of the tree +- to be refactored. +- name: a human-readable name for this tree. +- +- Returns: +- True if the tree was modified, False otherwise. +- """ +- for fixer in chain(self.pre_order, self.post_order): +- fixer.start_tree(tree, name) +- +- self.traverse_by(self.pre_order_heads, tree.pre_order()) +- self.traverse_by(self.post_order_heads, tree.post_order()) +- +- for fixer in chain(self.pre_order, self.post_order): +- fixer.finish_tree(tree, name) +- return tree.was_changed +- +- def traverse_by(self, fixers, traversal): +- """Traverse an AST, applying a set of fixers to each node. +- +- This is a helper method for refactor_tree(). +- +- Args: +- fixers: a list of fixer instances. +- traversal: a generator that yields AST nodes. +- +- Returns: +- None +- """ +- if not fixers: +- return +- for node in traversal: +- for fixer in fixers[node.type] + fixers[None]: +- results = fixer.match(node) +- if results: +- new = fixer.transform(node, results) +- if new is not None and (new != node or +- str(new) != str(node)): +- node.replace(new) +- node = new +- +- def processed_file(self, new_text, filename, old_text=None, write=False): +- """ +- Called when a file has been refactored, and there are changes. +- """ +- self.files.append(filename) +- if old_text is None: +- try: +- f = open(filename, "r") +- except IOError, err: +- self.log_error("Can't read %s: %s", filename, err) +- return +- try: +- old_text = f.read() +- finally: +- f.close() +- if old_text == new_text: +- self.log_debug("No changes to %s", filename) +- return +- self.print_output(diff_texts(old_text, new_text, filename)) +- if write: +- self.write_file(new_text, filename, old_text) +- else: +- self.log_debug("Not writing changes to %s", filename) +- +- def write_file(self, new_text, filename, old_text): +- """Writes a string to a file. +- +- It first shows a unified diff between the old text and the new text, and +- then rewrites the file; the latter is only done if the write option is +- set. +- """ +- try: +- f = open(filename, "w") +- except os.error, err: +- self.log_error("Can't create %s: %s", filename, err) +- return +- try: +- f.write(new_text) +- except os.error, err: +- self.log_error("Can't write %s: %s", filename, err) +- finally: +- f.close() +- self.log_debug("Wrote changes to %s", filename) +- self.wrote = True +- +- PS1 = ">>> " +- PS2 = "... " +- +- def refactor_docstring(self, input, filename): +- """Refactors a docstring, looking for doctests. +- +- This returns a modified version of the input string. It looks +- for doctests, which start with a ">>>" prompt, and may be +- continued with "..." prompts, as long as the "..." is indented +- the same as the ">>>". +- +- (Unfortunately we can't use the doctest module's parser, +- since, like most parsers, it is not geared towards preserving +- the original source.) +- """ +- result = [] +- block = None +- block_lineno = None +- indent = None +- lineno = 0 +- for line in input.splitlines(True): +- lineno += 1 +- if line.lstrip().startswith(self.PS1): +- if block is not None: +- result.extend(self.refactor_doctest(block, block_lineno, +- indent, filename)) +- block_lineno = lineno +- block = [line] +- i = line.find(self.PS1) +- indent = line[:i] +- elif (indent is not None and +- (line.startswith(indent + self.PS2) or +- line == indent + self.PS2.rstrip() + "\n")): +- block.append(line) +- else: +- if block is not None: +- result.extend(self.refactor_doctest(block, block_lineno, +- indent, filename)) +- block = None +- indent = None +- result.append(line) +- if block is not None: +- result.extend(self.refactor_doctest(block, block_lineno, +- indent, filename)) +- return "".join(result) +- +- def refactor_doctest(self, block, lineno, indent, filename): +- """Refactors one doctest. +- +- A doctest is given as a block of lines, the first of which starts +- with ">>>" (possibly indented), while the remaining lines start +- with "..." (identically indented). +- +- """ +- try: +- tree = self.parse_block(block, lineno, indent) +- except Exception, err: +- if self.log.isEnabledFor(logging.DEBUG): +- for line in block: +- self.log_debug("Source: %s", line.rstrip("\n")) +- self.log_error("Can't parse docstring in %s line %s: %s: %s", +- filename, lineno, err.__class__.__name__, err) +- return block +- if self.refactor_tree(tree, filename): +- new = str(tree).splitlines(True) +- # Undo the adjustment of the line numbers in wrap_toks() below. +- clipped, new = new[:lineno-1], new[lineno-1:] +- assert clipped == ["\n"] * (lineno-1), clipped +- if not new[-1].endswith("\n"): +- new[-1] += "\n" +- block = [indent + self.PS1 + new.pop(0)] +- if new: +- block += [indent + self.PS2 + line for line in new] +- return block +- +- def summarize(self): +- if self.wrote: +- were = "were" +- else: +- were = "need to be" +- if not self.files: +- self.log_message("No files %s modified.", were) +- else: +- self.log_message("Files that %s modified:", were) +- for file in self.files: +- self.log_message(file) +- if self.fixer_log: +- self.log_message("Warnings/messages while refactoring:") +- for message in self.fixer_log: +- self.log_message(message) +- if self.errors: +- if len(self.errors) == 1: +- self.log_message("There was 1 error:") +- else: +- self.log_message("There were %d errors:", len(self.errors)) +- for msg, args, kwds in self.errors: +- self.log_message(msg, *args, **kwds) +- +- def parse_block(self, block, lineno, indent): +- """Parses a block into a tree. +- +- This is necessary to get correct line number / offset information +- in the parser diagnostics and embedded into the parse tree. +- """ +- return self.driver.parse_tokens(self.wrap_toks(block, lineno, indent)) +- +- def wrap_toks(self, block, lineno, indent): +- """Wraps a tokenize stream to systematically modify start/end.""" +- tokens = tokenize.generate_tokens(self.gen_lines(block, indent).next) +- for type, value, (line0, col0), (line1, col1), line_text in tokens: +- line0 += lineno - 1 +- line1 += lineno - 1 +- # Don't bother updating the columns; this is too complicated +- # since line_text would also have to be updated and it would +- # still break for tokens spanning lines. Let the user guess +- # that the column numbers for doctests are relative to the +- # end of the prompt string (PS1 or PS2). +- yield type, value, (line0, col0), (line1, col1), line_text +- +- +- def gen_lines(self, block, indent): +- """Generates lines as expected by tokenize from a list of lines. +- +- This strips the first len(indent + self.PS1) characters off each line. +- """ +- prefix1 = indent + self.PS1 +- prefix2 = indent + self.PS2 +- prefix = prefix1 +- for line in block: +- if line.startswith(prefix): +- yield line[len(prefix):] +- elif line == prefix.rstrip() + "\n": +- yield "\n" +- else: +- raise AssertionError("line=%r, prefix=%r" % (line, prefix)) +- prefix = prefix2 +- while True: +- yield "" +- +- +-def diff_texts(a, b, filename): +- """Return a unified diff of two strings.""" +- a = a.splitlines() +- b = b.splitlines() +- return difflib.unified_diff(a, b, filename, filename, +- "(original)", "(refactored)", +- lineterm="") +diff -r 531f2e948299 lib2to3/tests/.svn/entries +--- a/lib2to3/tests/.svn/entries Mon Mar 30 20:02:09 2009 -0500 ++++ b/lib2to3/tests/.svn/entries Wed Apr 01 13:59:47 2009 -0500 +@@ -1,7 +1,7 @@ + 9 + + dir +-70785 ++70822 + http://svn.python.org/projects/sandbox/trunk/2to3/lib2to3/tests + http://svn.python.org/projects + +diff -r 531f2e948299 lib2to3/tests/data/.svn/entries +--- a/lib2to3/tests/data/.svn/entries Mon Mar 30 20:02:09 2009 -0500 ++++ b/lib2to3/tests/data/.svn/entries Wed Apr 01 13:59:47 2009 -0500 +@@ -1,7 +1,7 @@ + 9 + + dir +-70785 ++70822 + http://svn.python.org/projects/sandbox/trunk/2to3/lib2to3/tests/data + http://svn.python.org/projects + +diff -r 531f2e948299 lib2to3/tests/data/fixers/.svn/entries +--- a/lib2to3/tests/data/fixers/.svn/entries Mon Mar 30 20:02:09 2009 -0500 ++++ b/lib2to3/tests/data/fixers/.svn/entries Wed Apr 01 13:59:47 2009 -0500 +@@ -1,7 +1,7 @@ + 9 + + dir +-70785 ++70822 + http://svn.python.org/projects/sandbox/trunk/2to3/lib2to3/tests/data/fixers + http://svn.python.org/projects + +diff -r 531f2e948299 lib2to3/tests/data/fixers/bad_order.py +--- a/lib2to3/tests/data/fixers/bad_order.py Mon Mar 30 20:02:09 2009 -0500 ++++ b/lib2to3/tests/data/fixers/bad_order.py Wed Apr 01 13:59:47 2009 -0500 +@@ -1,4 +1,4 @@ +-from lib2to3.fixer_base import BaseFix ++from refactor.fixer_base import BaseFix + + class FixBadOrder(BaseFix): + +diff -r 531f2e948299 lib2to3/tests/data/fixers/myfixes/.svn/entries +--- a/lib2to3/tests/data/fixers/myfixes/.svn/entries Mon Mar 30 20:02:09 2009 -0500 ++++ b/lib2to3/tests/data/fixers/myfixes/.svn/entries Wed Apr 01 13:59:47 2009 -0500 +@@ -1,7 +1,7 @@ + 9 + + dir +-70785 ++70822 + http://svn.python.org/projects/sandbox/trunk/2to3/lib2to3/tests/data/fixers/myfixes + http://svn.python.org/projects + +diff -r 531f2e948299 lib2to3/tests/data/fixers/myfixes/fix_explicit.py +--- a/lib2to3/tests/data/fixers/myfixes/fix_explicit.py Mon Mar 30 20:02:09 2009 -0500 ++++ b/lib2to3/tests/data/fixers/myfixes/fix_explicit.py Wed Apr 01 13:59:47 2009 -0500 +@@ -1,4 +1,4 @@ +-from lib2to3.fixer_base import BaseFix ++from refactor.fixer_base import BaseFix + + class FixExplicit(BaseFix): + explicit = True +diff -r 531f2e948299 lib2to3/tests/data/fixers/myfixes/fix_first.py +--- a/lib2to3/tests/data/fixers/myfixes/fix_first.py Mon Mar 30 20:02:09 2009 -0500 ++++ b/lib2to3/tests/data/fixers/myfixes/fix_first.py Wed Apr 01 13:59:47 2009 -0500 +@@ -1,4 +1,4 @@ +-from lib2to3.fixer_base import BaseFix ++from refactor.fixer_base import BaseFix + + class FixFirst(BaseFix): + run_order = 1 +diff -r 531f2e948299 lib2to3/tests/data/fixers/myfixes/fix_last.py +--- a/lib2to3/tests/data/fixers/myfixes/fix_last.py Mon Mar 30 20:02:09 2009 -0500 ++++ b/lib2to3/tests/data/fixers/myfixes/fix_last.py Wed Apr 01 13:59:47 2009 -0500 +@@ -1,4 +1,4 @@ +-from lib2to3.fixer_base import BaseFix ++from refactor.fixer_base import BaseFix + + class FixLast(BaseFix): + +diff -r 531f2e948299 lib2to3/tests/data/fixers/myfixes/fix_parrot.py +--- a/lib2to3/tests/data/fixers/myfixes/fix_parrot.py Mon Mar 30 20:02:09 2009 -0500 ++++ b/lib2to3/tests/data/fixers/myfixes/fix_parrot.py Wed Apr 01 13:59:47 2009 -0500 +@@ -1,5 +1,5 @@ +-from lib2to3.fixer_base import BaseFix +-from lib2to3.fixer_util import Name ++from refactor.fixer_base import BaseFix ++from refactor.fixer_util import Name + + class FixParrot(BaseFix): + """ +diff -r 531f2e948299 lib2to3/tests/data/fixers/myfixes/fix_preorder.py +--- a/lib2to3/tests/data/fixers/myfixes/fix_preorder.py Mon Mar 30 20:02:09 2009 -0500 ++++ b/lib2to3/tests/data/fixers/myfixes/fix_preorder.py Wed Apr 01 13:59:47 2009 -0500 +@@ -1,4 +1,4 @@ +-from lib2to3.fixer_base import BaseFix ++from refactor.fixer_base import BaseFix + + class FixPreorder(BaseFix): + order = "pre" +diff -r 531f2e948299 lib2to3/tests/support.py +--- a/lib2to3/tests/support.py Mon Mar 30 20:02:09 2009 -0500 ++++ b/lib2to3/tests/support.py Wed Apr 01 13:59:47 2009 -0500 +@@ -1,5 +1,5 @@ + """Support code for test_*.py files""" +-# Author: Collin Winter ++# Original Author: Collin Winter + + # Python imports + import unittest +@@ -16,12 +16,26 @@ + from .. import refactor + from ..pgen2 import driver + ++test_pkg = "refactor.fixes" + test_dir = os.path.dirname(__file__) + proj_dir = os.path.normpath(os.path.join(test_dir, "..")) + grammar_path = os.path.join(test_dir, "..", "Grammar.txt") + grammar = driver.load_grammar(grammar_path) + driver = driver.Driver(grammar, convert=pytree.convert) + ++def parse_version(version_string): ++ """Returns a version tuple matching input version_string.""" ++ if not version_string: ++ return () ++ ++ version_list = [] ++ for token in version_string.split('.'): ++ try: ++ version_list.append(int(token)) ++ except ValueError: ++ version_list.append(token) ++ return tuple(version_list) ++ + def parse_string(string): + return driver.parse_string(reformat(string), debug=True) + +@@ -39,18 +53,19 @@ + def reformat(string): + return dedent(string) + "\n\n" + +-def get_refactorer(fixers=None, options=None): ++def get_refactorer(fixers=None, options=None, pkg_name=None): + """ + A convenience function for creating a RefactoringTool for tests. + + fixers is a list of fixers for the RefactoringTool to use. By default +- "lib2to3.fixes.*" is used. options is an optional dictionary of options to ++ "refactor.fixes.*" is used. options is an optional dictionary of options to + be passed to the RefactoringTool. + """ ++ pkg_name = pkg_name or test_pkg + if fixers is not None: +- fixers = ["lib2to3.fixes.fix_" + fix for fix in fixers] ++ fixers = [pkg_name + ".fix_" + fix for fix in fixers] + else: +- fixers = refactor.get_fixers_from_package("lib2to3.fixes") ++ fixers = refactor.get_fixers_from_package(pkg_name) + options = options or {} + return refactor.RefactoringTool(fixers, options, explicit=True) + +diff -r 531f2e948299 lib2to3/tests/test_fixers.py +--- a/lib2to3/tests/test_fixers.py Mon Mar 30 20:02:09 2009 -0500 ++++ b/lib2to3/tests/test_fixers.py Wed Apr 01 13:59:47 2009 -0500 +@@ -23,7 +23,7 @@ + if fix_list is None: + fix_list = [self.fixer] + options = {"print_function" : False} +- self.refactor = support.get_refactorer(fix_list, options) ++ self.refactor = support.get_refactorer(fix_list, options, "refactor.fixes.from2") + self.fixer_log = [] + self.filename = "" + +@@ -1625,7 +1625,7 @@ + + class Test_imports(FixerTestCase, ImportsFixerTests): + fixer = "imports" +- from ..fixes.fix_imports import MAPPING as modules ++ from refactor.fixes.from2.fix_imports import MAPPING as modules + + def test_multiple_imports(self): + b = """import urlparse, cStringIO""" +@@ -1646,23 +1646,23 @@ + + class Test_imports2(FixerTestCase, ImportsFixerTests): + fixer = "imports2" +- from ..fixes.fix_imports2 import MAPPING as modules ++ from refactor.fixes.from2.fix_imports2 import MAPPING as modules + + + class Test_imports_fixer_order(FixerTestCase, ImportsFixerTests): + + def setUp(self): + super(Test_imports_fixer_order, self).setUp(['imports', 'imports2']) +- from ..fixes.fix_imports2 import MAPPING as mapping2 ++ from refactor.fixes.from2.fix_imports2 import MAPPING as mapping2 + self.modules = mapping2.copy() +- from ..fixes.fix_imports import MAPPING as mapping1 ++ from refactor.fixes.from2.fix_imports import MAPPING as mapping1 + for key in ('dbhash', 'dumbdbm', 'dbm', 'gdbm'): + self.modules[key] = mapping1[key] + + + class Test_urllib(FixerTestCase): + fixer = "urllib" +- from ..fixes.fix_urllib import MAPPING as modules ++ from refactor.fixes.from2.fix_urllib import MAPPING as modules + + def test_import_module(self): + for old, changes in self.modules.items(): +@@ -3449,7 +3449,7 @@ + self.files_checked.append(name) + return self.always_exists or (name in self.present_files) + +- from ..fixes import fix_import ++ from refactor.fixes.from2 import fix_import + fix_import.exists = fake_exists + + def tearDown(self): +diff -r 531f2e948299 lib2to3/tests/test_parser.py +--- a/lib2to3/tests/test_parser.py Mon Mar 30 20:02:09 2009 -0500 ++++ b/lib2to3/tests/test_parser.py Wed Apr 01 13:59:47 2009 -0500 +@@ -17,7 +17,7 @@ + import os.path + + # Local imports +-from ..pgen2.parse import ParseError ++from refactor.pgen2.parse import ParseError + + + class GrammarTest(support.TestCase): +diff -r 531f2e948299 lib2to3/tests/test_util.py +--- a/lib2to3/tests/test_util.py Mon Mar 30 20:02:09 2009 -0500 ++++ b/lib2to3/tests/test_util.py Wed Apr 01 13:59:47 2009 -0500 +@@ -11,7 +11,7 @@ + # Local imports + from .. import pytree + from .. import fixer_util +-from ..fixer_util import Attr, Name ++from refactor.fixer_util import Attr, Name + + + def parse(code, strip_levels=0): +diff -r 531f2e948299 refactor/.svn/all-wcprops +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/all-wcprops Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,65 @@ ++K 25 ++svn:wc:ra_dav:version-url ++V 51 ++/projects/!svn/ver/69681/sandbox/trunk/2to3/lib2to3 ++END ++pytree.py ++K 25 ++svn:wc:ra_dav:version-url ++V 61 ++/projects/!svn/ver/69680/sandbox/trunk/2to3/lib2to3/pytree.py ++END ++fixer_util.py ++K 25 ++svn:wc:ra_dav:version-url ++V 65 ++/projects/!svn/ver/69679/sandbox/trunk/2to3/lib2to3/fixer_util.py ++END ++PatternGrammar.txt ++K 25 ++svn:wc:ra_dav:version-url ++V 70 ++/projects/!svn/ver/61428/sandbox/trunk/2to3/lib2to3/PatternGrammar.txt ++END ++Grammar.txt ++K 25 ++svn:wc:ra_dav:version-url ++V 63 ++/projects/!svn/ver/66191/sandbox/trunk/2to3/lib2to3/Grammar.txt ++END ++__init__.py ++K 25 ++svn:wc:ra_dav:version-url ++V 63 ++/projects/!svn/ver/67433/sandbox/trunk/2to3/lib2to3/__init__.py ++END ++pygram.py ++K 25 ++svn:wc:ra_dav:version-url ++V 61 ++/projects/!svn/ver/67769/sandbox/trunk/2to3/lib2to3/pygram.py ++END ++patcomp.py ++K 25 ++svn:wc:ra_dav:version-url ++V 62 ++/projects/!svn/ver/69681/sandbox/trunk/2to3/lib2to3/patcomp.py ++END ++main.py ++K 25 ++svn:wc:ra_dav:version-url ++V 59 ++/projects/!svn/ver/67919/sandbox/trunk/2to3/lib2to3/main.py ++END ++refactor.py ++K 25 ++svn:wc:ra_dav:version-url ++V 63 ++/projects/!svn/ver/67991/sandbox/trunk/2to3/lib2to3/refactor.py ++END ++fixer_base.py ++K 25 ++svn:wc:ra_dav:version-url ++V 65 ++/projects/!svn/ver/67769/sandbox/trunk/2to3/lib2to3/fixer_base.py ++END +diff -r 531f2e948299 refactor/.svn/dir-prop-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/dir-prop-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 10 ++svn:ignore ++V 24 ++*.pyc ++*.pyo ++*.pickle ++@* ++ ++END +diff -r 531f2e948299 refactor/.svn/entries +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/entries Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,377 @@ ++9 ++ ++dir ++70822 ++http://svn.python.org/projects/sandbox/trunk/2to3/lib2to3 ++http://svn.python.org/projects ++ ++ ++ ++2009-02-16T17:43:09.878955Z ++69681 ++benjamin.peterson ++has-props ++ ++svn:special svn:externals svn:needs-lock ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++6015fed2-1504-0410-9fe1-9d1591cc4771 ++ ++pytree.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++04e7d771f65eaa3bd221cb8451652cad ++2009-02-16T17:41:48.036309Z ++69680 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++27575 ++ ++fixer_util.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++ceed30974a584bd7ca461077b735aa61 ++2009-02-16T17:36:06.789054Z ++69679 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++14348 ++ ++tests ++dir ++ ++PatternGrammar.txt ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++4b47e92dafaedf0ea24c8097b65797c4 ++2008-03-16T19:36:15.363093Z ++61428 ++martin.v.loewis ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++793 ++ ++Grammar.txt ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++a6aa611a634ddccccf9fef17bbbbeadb ++2008-09-03T22:00:52.351755Z ++66191 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++6331 ++ ++__init__.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++191142a35d9dceef524b32c6d9676e51 ++2008-11-28T23:18:48.744865Z ++67433 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++7 ++ ++pygram.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++3a20d757a7db6a30ec477352f7c9cf6a ++2008-12-14T20:59:10.846867Z ++67769 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++774 ++ ++patcomp.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++e1a5a1fa70f5b518e4dfe6abb24adf1a ++2009-02-16T17:43:09.878955Z ++69681 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++6529 ++ ++pgen2 ++dir ++ ++main.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++85da2f9b910a7b8af322a872949da4e1 ++2008-12-23T19:12:22.717389Z ++67919 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++4921 ++ ++refactor.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++93cfbef5d9bcae247382e78984d5b8e5 ++2008-12-28T20:30:26.284113Z ++67991 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++19094 ++ ++fixes ++dir ++ ++fixer_base.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++decf389028d0e267eb33ff8a0a69285c ++2008-12-14T20:59:10.846867Z ++67769 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++6215 ++ +diff -r 531f2e948299 refactor/.svn/format +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/format Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,1 @@ ++9 +diff -r 531f2e948299 refactor/.svn/prop-base/Grammar.txt.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/prop-base/Grammar.txt.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 23 ++Author Date Id Revision ++END +diff -r 531f2e948299 refactor/.svn/prop-base/PatternGrammar.txt.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/prop-base/PatternGrammar.txt.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 23 ++Author Date Id Revision ++END +diff -r 531f2e948299 refactor/.svn/prop-base/__init__.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/prop-base/__init__.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,5 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++END +diff -r 531f2e948299 refactor/.svn/prop-base/fixer_base.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/prop-base/fixer_base.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/.svn/prop-base/fixer_util.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/prop-base/fixer_util.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/.svn/prop-base/main.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/prop-base/main.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/.svn/prop-base/patcomp.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/prop-base/patcomp.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/.svn/prop-base/pygram.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/prop-base/pygram.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/.svn/prop-base/pytree.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/prop-base/pytree.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/.svn/prop-base/refactor.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/prop-base/refactor.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,13 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 14 ++svn:executable ++V 1 ++* ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/.svn/text-base/Grammar.txt.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/text-base/Grammar.txt.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,155 @@ ++# Grammar for Python ++ ++# Note: Changing the grammar specified in this file will most likely ++# require corresponding changes in the parser module ++# (../Modules/parsermodule.c). If you can't make the changes to ++# that module yourself, please co-ordinate the required changes ++# with someone who can; ask around on python-dev for help. Fred ++# Drake will probably be listening there. ++ ++# NOTE WELL: You should also follow all the steps listed in PEP 306, ++# "How to Change Python's Grammar" ++ ++# Commands for Kees Blom's railroad program ++#diagram:token NAME ++#diagram:token NUMBER ++#diagram:token STRING ++#diagram:token NEWLINE ++#diagram:token ENDMARKER ++#diagram:token INDENT ++#diagram:output\input python.bla ++#diagram:token DEDENT ++#diagram:output\textwidth 20.04cm\oddsidemargin 0.0cm\evensidemargin 0.0cm ++#diagram:rules ++ ++# Start symbols for the grammar: ++# file_input is a module or sequence of commands read from an input file; ++# single_input is a single interactive statement; ++# eval_input is the input for the eval() and input() functions. ++# NB: compound_stmt in single_input is followed by extra NEWLINE! ++file_input: (NEWLINE | stmt)* ENDMARKER ++single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE ++eval_input: testlist NEWLINE* ENDMARKER ++ ++decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE ++decorators: decorator+ ++decorated: decorators (classdef | funcdef) ++funcdef: 'def' NAME parameters ['->' test] ':' suite ++parameters: '(' [typedargslist] ')' ++typedargslist: ((tfpdef ['=' test] ',')* ++ ('*' [tname] (',' tname ['=' test])* [',' '**' tname] | '**' tname) ++ | tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) ++tname: NAME [':' test] ++tfpdef: tname | '(' tfplist ')' ++tfplist: tfpdef (',' tfpdef)* [','] ++varargslist: ((vfpdef ['=' test] ',')* ++ ('*' [vname] (',' vname ['=' test])* [',' '**' vname] | '**' vname) ++ | vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) ++vname: NAME ++vfpdef: vname | '(' vfplist ')' ++vfplist: vfpdef (',' vfpdef)* [','] ++ ++stmt: simple_stmt | compound_stmt ++simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE ++small_stmt: (expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | ++ import_stmt | global_stmt | exec_stmt | assert_stmt) ++expr_stmt: testlist (augassign (yield_expr|testlist) | ++ ('=' (yield_expr|testlist))*) ++augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | ++ '<<=' | '>>=' | '**=' | '//=') ++# For normal assignments, additional restrictions enforced by the interpreter ++print_stmt: 'print' ( [ test (',' test)* [','] ] | ++ '>>' test [ (',' test)+ [','] ] ) ++del_stmt: 'del' exprlist ++pass_stmt: 'pass' ++flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt ++break_stmt: 'break' ++continue_stmt: 'continue' ++return_stmt: 'return' [testlist] ++yield_stmt: yield_expr ++raise_stmt: 'raise' [test ['from' test | ',' test [',' test]]] ++import_stmt: import_name | import_from ++import_name: 'import' dotted_as_names ++import_from: ('from' ('.'* dotted_name | '.'+) ++ 'import' ('*' | '(' import_as_names ')' | import_as_names)) ++import_as_name: NAME ['as' NAME] ++dotted_as_name: dotted_name ['as' NAME] ++import_as_names: import_as_name (',' import_as_name)* [','] ++dotted_as_names: dotted_as_name (',' dotted_as_name)* ++dotted_name: NAME ('.' NAME)* ++global_stmt: ('global' | 'nonlocal') NAME (',' NAME)* ++exec_stmt: 'exec' expr ['in' test [',' test]] ++assert_stmt: 'assert' test [',' test] ++ ++compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated ++if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] ++while_stmt: 'while' test ':' suite ['else' ':' suite] ++for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] ++try_stmt: ('try' ':' suite ++ ((except_clause ':' suite)+ ++ ['else' ':' suite] ++ ['finally' ':' suite] | ++ 'finally' ':' suite)) ++with_stmt: 'with' test [ with_var ] ':' suite ++with_var: 'as' expr ++# NB compile.c makes sure that the default except clause is last ++except_clause: 'except' [test [(',' | 'as') test]] ++suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT ++ ++# Backward compatibility cruft to support: ++# [ x for x in lambda: True, lambda: False if x() ] ++# even while also allowing: ++# lambda x: 5 if x else 2 ++# (But not a mix of the two) ++testlist_safe: old_test [(',' old_test)+ [',']] ++old_test: or_test | old_lambdef ++old_lambdef: 'lambda' [varargslist] ':' old_test ++ ++test: or_test ['if' or_test 'else' test] | lambdef ++or_test: and_test ('or' and_test)* ++and_test: not_test ('and' not_test)* ++not_test: 'not' not_test | comparison ++comparison: expr (comp_op expr)* ++comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' ++expr: xor_expr ('|' xor_expr)* ++xor_expr: and_expr ('^' and_expr)* ++and_expr: shift_expr ('&' shift_expr)* ++shift_expr: arith_expr (('<<'|'>>') arith_expr)* ++arith_expr: term (('+'|'-') term)* ++term: factor (('*'|'/'|'%'|'//') factor)* ++factor: ('+'|'-'|'~') factor | power ++power: atom trailer* ['**' factor] ++atom: ('(' [yield_expr|testlist_gexp] ')' | ++ '[' [listmaker] ']' | ++ '{' [dictsetmaker] '}' | ++ '`' testlist1 '`' | ++ NAME | NUMBER | STRING+ | '.' '.' '.') ++listmaker: test ( comp_for | (',' test)* [','] ) ++testlist_gexp: test ( comp_for | (',' test)* [','] ) ++lambdef: 'lambda' [varargslist] ':' test ++trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME ++subscriptlist: subscript (',' subscript)* [','] ++subscript: test | [test] ':' [test] [sliceop] ++sliceop: ':' [test] ++exprlist: expr (',' expr)* [','] ++testlist: test (',' test)* [','] ++dictsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) | ++ (test (comp_for | (',' test)* [','])) ) ++ ++classdef: 'class' NAME ['(' [arglist] ')'] ':' suite ++ ++arglist: (argument ',')* (argument [','] ++ |'*' test (',' argument)* [',' '**' test] ++ |'**' test) ++argument: test [comp_for] | test '=' test # Really [keyword '='] test ++ ++comp_iter: comp_for | comp_if ++comp_for: 'for' exprlist 'in' testlist_safe [comp_iter] ++comp_if: 'if' old_test [comp_iter] ++ ++testlist1: test (',' test)* ++ ++# not used in grammar, but may appear in "node" passed from Parser to Compiler ++encoding_decl: NAME ++ ++yield_expr: 'yield' [testlist] +diff -r 531f2e948299 refactor/.svn/text-base/PatternGrammar.txt.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/text-base/PatternGrammar.txt.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,28 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++# A grammar to describe tree matching patterns. ++# Not shown here: ++# - 'TOKEN' stands for any token (leaf node) ++# - 'any' stands for any node (leaf or interior) ++# With 'any' we can still specify the sub-structure. ++ ++# The start symbol is 'Matcher'. ++ ++Matcher: Alternatives ENDMARKER ++ ++Alternatives: Alternative ('|' Alternative)* ++ ++Alternative: (Unit | NegatedUnit)+ ++ ++Unit: [NAME '='] ( STRING [Repeater] ++ | NAME [Details] [Repeater] ++ | '(' Alternatives ')' [Repeater] ++ | '[' Alternatives ']' ++ ) ++ ++NegatedUnit: 'not' (STRING | NAME [Details] | '(' Alternatives ')') ++ ++Repeater: '*' | '+' | '{' NUMBER [',' NUMBER] '}' ++ ++Details: '<' Alternatives '>' +diff -r 531f2e948299 refactor/.svn/text-base/__init__.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/text-base/__init__.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,1 @@ ++#empty +diff -r 531f2e948299 refactor/.svn/text-base/fixer_base.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/text-base/fixer_base.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,178 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Base class for fixers (optional, but recommended).""" ++ ++# Python imports ++import logging ++import itertools ++ ++# Local imports ++from .patcomp import PatternCompiler ++from . import pygram ++from .fixer_util import does_tree_import ++ ++class BaseFix(object): ++ ++ """Optional base class for fixers. ++ ++ The subclass name must be FixFooBar where FooBar is the result of ++ removing underscores and capitalizing the words of the fix name. ++ For example, the class name for a fixer named 'has_key' should be ++ FixHasKey. ++ """ ++ ++ PATTERN = None # Most subclasses should override with a string literal ++ pattern = None # Compiled pattern, set by compile_pattern() ++ options = None # Options object passed to initializer ++ filename = None # The filename (set by set_filename) ++ logger = None # A logger (set by set_filename) ++ numbers = itertools.count(1) # For new_name() ++ used_names = set() # A set of all used NAMEs ++ order = "post" # Does the fixer prefer pre- or post-order traversal ++ explicit = False # Is this ignored by refactor.py -f all? ++ run_order = 5 # Fixers will be sorted by run order before execution ++ # Lower numbers will be run first. ++ ++ # Shortcut for access to Python grammar symbols ++ syms = pygram.python_symbols ++ ++ def __init__(self, options, log): ++ """Initializer. Subclass may override. ++ ++ Args: ++ options: an dict containing the options passed to RefactoringTool ++ that could be used to customize the fixer through the command line. ++ log: a list to append warnings and other messages to. ++ """ ++ self.options = options ++ self.log = log ++ self.compile_pattern() ++ ++ def compile_pattern(self): ++ """Compiles self.PATTERN into self.pattern. ++ ++ Subclass may override if it doesn't want to use ++ self.{pattern,PATTERN} in .match(). ++ """ ++ if self.PATTERN is not None: ++ self.pattern = PatternCompiler().compile_pattern(self.PATTERN) ++ ++ def set_filename(self, filename): ++ """Set the filename, and a logger derived from it. ++ ++ The main refactoring tool should call this. ++ """ ++ self.filename = filename ++ self.logger = logging.getLogger(filename) ++ ++ def match(self, node): ++ """Returns match for a given parse tree node. ++ ++ Should return a true or false object (not necessarily a bool). ++ It may return a non-empty dict of matching sub-nodes as ++ returned by a matching pattern. ++ ++ Subclass may override. ++ """ ++ results = {"node": node} ++ return self.pattern.match(node, results) and results ++ ++ def transform(self, node, results): ++ """Returns the transformation for a given parse tree node. ++ ++ Args: ++ node: the root of the parse tree that matched the fixer. ++ results: a dict mapping symbolic names to part of the match. ++ ++ Returns: ++ None, or a node that is a modified copy of the ++ argument node. The node argument may also be modified in-place to ++ effect the same change. ++ ++ Subclass *must* override. ++ """ ++ raise NotImplementedError() ++ ++ def new_name(self, template="xxx_todo_changeme"): ++ """Return a string suitable for use as an identifier ++ ++ The new name is guaranteed not to conflict with other identifiers. ++ """ ++ name = template ++ while name in self.used_names: ++ name = template + str(self.numbers.next()) ++ self.used_names.add(name) ++ return name ++ ++ def log_message(self, message): ++ if self.first_log: ++ self.first_log = False ++ self.log.append("### In file %s ###" % self.filename) ++ self.log.append(message) ++ ++ def cannot_convert(self, node, reason=None): ++ """Warn the user that a given chunk of code is not valid Python 3, ++ but that it cannot be converted automatically. ++ ++ First argument is the top-level node for the code in question. ++ Optional second argument is why it can't be converted. ++ """ ++ lineno = node.get_lineno() ++ for_output = node.clone() ++ for_output.set_prefix("") ++ msg = "Line %d: could not convert: %s" ++ self.log_message(msg % (lineno, for_output)) ++ if reason: ++ self.log_message(reason) ++ ++ def warning(self, node, reason): ++ """Used for warning the user about possible uncertainty in the ++ translation. ++ ++ First argument is the top-level node for the code in question. ++ Optional second argument is why it can't be converted. ++ """ ++ lineno = node.get_lineno() ++ self.log_message("Line %d: %s" % (lineno, reason)) ++ ++ def start_tree(self, tree, filename): ++ """Some fixers need to maintain tree-wide state. ++ This method is called once, at the start of tree fix-up. ++ ++ tree - the root node of the tree to be processed. ++ filename - the name of the file the tree came from. ++ """ ++ self.used_names = tree.used_names ++ self.set_filename(filename) ++ self.numbers = itertools.count(1) ++ self.first_log = True ++ ++ def finish_tree(self, tree, filename): ++ """Some fixers need to maintain tree-wide state. ++ This method is called once, at the conclusion of tree fix-up. ++ ++ tree - the root node of the tree to be processed. ++ filename - the name of the file the tree came from. ++ """ ++ pass ++ ++ ++class ConditionalFix(BaseFix): ++ """ Base class for fixers which not execute if an import is found. """ ++ ++ # This is the name of the import which, if found, will cause the test to be skipped ++ skip_on = None ++ ++ def start_tree(self, *args): ++ super(ConditionalFix, self).start_tree(*args) ++ self._should_skip = None ++ ++ def should_skip(self, node): ++ if self._should_skip is not None: ++ return self._should_skip ++ pkg = self.skip_on.split(".") ++ name = pkg[-1] ++ pkg = ".".join(pkg[:-1]) ++ self._should_skip = does_tree_import(pkg, name, node) ++ return self._should_skip +diff -r 531f2e948299 refactor/.svn/text-base/fixer_util.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/text-base/fixer_util.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,425 @@ ++"""Utility functions, node construction macros, etc.""" ++# Author: Collin Winter ++ ++# Local imports ++from .pgen2 import token ++from .pytree import Leaf, Node ++from .pygram import python_symbols as syms ++from . import patcomp ++ ++ ++########################################################### ++### Common node-construction "macros" ++########################################################### ++ ++def KeywordArg(keyword, value): ++ return Node(syms.argument, ++ [keyword, Leaf(token.EQUAL, '='), value]) ++ ++def LParen(): ++ return Leaf(token.LPAR, "(") ++ ++def RParen(): ++ return Leaf(token.RPAR, ")") ++ ++def Assign(target, source): ++ """Build an assignment statement""" ++ if not isinstance(target, list): ++ target = [target] ++ if not isinstance(source, list): ++ source.set_prefix(" ") ++ source = [source] ++ ++ return Node(syms.atom, ++ target + [Leaf(token.EQUAL, "=", prefix=" ")] + source) ++ ++def Name(name, prefix=None): ++ """Return a NAME leaf""" ++ return Leaf(token.NAME, name, prefix=prefix) ++ ++def Attr(obj, attr): ++ """A node tuple for obj.attr""" ++ return [obj, Node(syms.trailer, [Dot(), attr])] ++ ++def Comma(): ++ """A comma leaf""" ++ return Leaf(token.COMMA, ",") ++ ++def Dot(): ++ """A period (.) leaf""" ++ return Leaf(token.DOT, ".") ++ ++def ArgList(args, lparen=LParen(), rparen=RParen()): ++ """A parenthesised argument list, used by Call()""" ++ node = Node(syms.trailer, [lparen.clone(), rparen.clone()]) ++ if args: ++ node.insert_child(1, Node(syms.arglist, args)) ++ return node ++ ++def Call(func_name, args=None, prefix=None): ++ """A function call""" ++ node = Node(syms.power, [func_name, ArgList(args)]) ++ if prefix is not None: ++ node.set_prefix(prefix) ++ return node ++ ++def Newline(): ++ """A newline literal""" ++ return Leaf(token.NEWLINE, "\n") ++ ++def BlankLine(): ++ """A blank line""" ++ return Leaf(token.NEWLINE, "") ++ ++def Number(n, prefix=None): ++ return Leaf(token.NUMBER, n, prefix=prefix) ++ ++def Subscript(index_node): ++ """A numeric or string subscript""" ++ return Node(syms.trailer, [Leaf(token.LBRACE, '['), ++ index_node, ++ Leaf(token.RBRACE, ']')]) ++ ++def String(string, prefix=None): ++ """A string leaf""" ++ return Leaf(token.STRING, string, prefix=prefix) ++ ++def ListComp(xp, fp, it, test=None): ++ """A list comprehension of the form [xp for fp in it if test]. ++ ++ If test is None, the "if test" part is omitted. ++ """ ++ xp.set_prefix("") ++ fp.set_prefix(" ") ++ it.set_prefix(" ") ++ for_leaf = Leaf(token.NAME, "for") ++ for_leaf.set_prefix(" ") ++ in_leaf = Leaf(token.NAME, "in") ++ in_leaf.set_prefix(" ") ++ inner_args = [for_leaf, fp, in_leaf, it] ++ if test: ++ test.set_prefix(" ") ++ if_leaf = Leaf(token.NAME, "if") ++ if_leaf.set_prefix(" ") ++ inner_args.append(Node(syms.comp_if, [if_leaf, test])) ++ inner = Node(syms.listmaker, [xp, Node(syms.comp_for, inner_args)]) ++ return Node(syms.atom, ++ [Leaf(token.LBRACE, "["), ++ inner, ++ Leaf(token.RBRACE, "]")]) ++ ++def FromImport(package_name, name_leafs): ++ """ Return an import statement in the form: ++ from package import name_leafs""" ++ # XXX: May not handle dotted imports properly (eg, package_name='foo.bar') ++ #assert package_name == '.' or '.' not in package_name, "FromImport has "\ ++ # "not been tested with dotted package names -- use at your own "\ ++ # "peril!" ++ ++ for leaf in name_leafs: ++ # Pull the leaves out of their old tree ++ leaf.remove() ++ ++ children = [Leaf(token.NAME, 'from'), ++ Leaf(token.NAME, package_name, prefix=" "), ++ Leaf(token.NAME, 'import', prefix=" "), ++ Node(syms.import_as_names, name_leafs)] ++ imp = Node(syms.import_from, children) ++ return imp ++ ++ ++########################################################### ++### Determine whether a node represents a given literal ++########################################################### ++ ++def is_tuple(node): ++ """Does the node represent a tuple literal?""" ++ if isinstance(node, Node) and node.children == [LParen(), RParen()]: ++ return True ++ return (isinstance(node, Node) ++ and len(node.children) == 3 ++ and isinstance(node.children[0], Leaf) ++ and isinstance(node.children[1], Node) ++ and isinstance(node.children[2], Leaf) ++ and node.children[0].value == "(" ++ and node.children[2].value == ")") ++ ++def is_list(node): ++ """Does the node represent a list literal?""" ++ return (isinstance(node, Node) ++ and len(node.children) > 1 ++ and isinstance(node.children[0], Leaf) ++ and isinstance(node.children[-1], Leaf) ++ and node.children[0].value == "[" ++ and node.children[-1].value == "]") ++ ++ ++########################################################### ++### Misc ++########################################################### ++ ++def parenthesize(node): ++ return Node(syms.atom, [LParen(), node, RParen()]) ++ ++ ++consuming_calls = set(["sorted", "list", "set", "any", "all", "tuple", "sum", ++ "min", "max"]) ++ ++def attr_chain(obj, attr): ++ """Follow an attribute chain. ++ ++ If you have a chain of objects where a.foo -> b, b.foo-> c, etc, ++ use this to iterate over all objects in the chain. Iteration is ++ terminated by getattr(x, attr) is None. ++ ++ Args: ++ obj: the starting object ++ attr: the name of the chaining attribute ++ ++ Yields: ++ Each successive object in the chain. ++ """ ++ next = getattr(obj, attr) ++ while next: ++ yield next ++ next = getattr(next, attr) ++ ++p0 = """for_stmt< 'for' any 'in' node=any ':' any* > ++ | comp_for< 'for' any 'in' node=any any* > ++ """ ++p1 = """ ++power< ++ ( 'iter' | 'list' | 'tuple' | 'sorted' | 'set' | 'sum' | ++ 'any' | 'all' | (any* trailer< '.' 'join' >) ) ++ trailer< '(' node=any ')' > ++ any* ++> ++""" ++p2 = """ ++power< ++ 'sorted' ++ trailer< '(' arglist ')' > ++ any* ++> ++""" ++pats_built = False ++def in_special_context(node): ++ """ Returns true if node is in an environment where all that is required ++ of it is being itterable (ie, it doesn't matter if it returns a list ++ or an itterator). ++ See test_map_nochange in test_fixers.py for some examples and tests. ++ """ ++ global p0, p1, p2, pats_built ++ if not pats_built: ++ p1 = patcomp.compile_pattern(p1) ++ p0 = patcomp.compile_pattern(p0) ++ p2 = patcomp.compile_pattern(p2) ++ pats_built = True ++ patterns = [p0, p1, p2] ++ for pattern, parent in zip(patterns, attr_chain(node, "parent")): ++ results = {} ++ if pattern.match(parent, results) and results["node"] is node: ++ return True ++ return False ++ ++def is_probably_builtin(node): ++ """ ++ Check that something isn't an attribute or function name etc. ++ """ ++ prev = node.prev_sibling ++ if prev is not None and prev.type == token.DOT: ++ # Attribute lookup. ++ return False ++ parent = node.parent ++ if parent.type in (syms.funcdef, syms.classdef): ++ return False ++ if parent.type == syms.expr_stmt and parent.children[0] is node: ++ # Assignment. ++ return False ++ if parent.type == syms.parameters or \ ++ (parent.type == syms.typedargslist and ( ++ (prev is not None and prev.type == token.COMMA) or ++ parent.children[0] is node ++ )): ++ # The name of an argument. ++ return False ++ return True ++ ++########################################################### ++### The following functions are to find bindings in a suite ++########################################################### ++ ++def make_suite(node): ++ if node.type == syms.suite: ++ return node ++ node = node.clone() ++ parent, node.parent = node.parent, None ++ suite = Node(syms.suite, [node]) ++ suite.parent = parent ++ return suite ++ ++def find_root(node): ++ """Find the top level namespace.""" ++ # Scamper up to the top level namespace ++ while node.type != syms.file_input: ++ assert node.parent, "Tree is insane! root found before "\ ++ "file_input node was found." ++ node = node.parent ++ return node ++ ++def does_tree_import(package, name, node): ++ """ Returns true if name is imported from package at the ++ top level of the tree which node belongs to. ++ To cover the case of an import like 'import foo', use ++ None for the package and 'foo' for the name. """ ++ binding = find_binding(name, find_root(node), package) ++ return bool(binding) ++ ++def is_import(node): ++ """Returns true if the node is an import statement.""" ++ return node.type in (syms.import_name, syms.import_from) ++ ++def touch_import(package, name, node): ++ """ Works like `does_tree_import` but adds an import statement ++ if it was not imported. """ ++ def is_import_stmt(node): ++ return node.type == syms.simple_stmt and node.children and \ ++ is_import(node.children[0]) ++ ++ root = find_root(node) ++ ++ if does_tree_import(package, name, root): ++ return ++ ++ add_newline_before = False ++ ++ # figure out where to insert the new import. First try to find ++ # the first import and then skip to the last one. ++ insert_pos = offset = 0 ++ for idx, node in enumerate(root.children): ++ if not is_import_stmt(node): ++ continue ++ for offset, node2 in enumerate(root.children[idx:]): ++ if not is_import_stmt(node2): ++ break ++ insert_pos = idx + offset ++ break ++ ++ # if there are no imports where we can insert, find the docstring. ++ # if that also fails, we stick to the beginning of the file ++ if insert_pos == 0: ++ for idx, node in enumerate(root.children): ++ if node.type == syms.simple_stmt and node.children and \ ++ node.children[0].type == token.STRING: ++ insert_pos = idx + 1 ++ add_newline_before ++ break ++ ++ if package is None: ++ import_ = Node(syms.import_name, [ ++ Leaf(token.NAME, 'import'), ++ Leaf(token.NAME, name, prefix=' ') ++ ]) ++ else: ++ import_ = FromImport(package, [Leaf(token.NAME, name, prefix=' ')]) ++ ++ children = [import_, Newline()] ++ if add_newline_before: ++ children.insert(0, Newline()) ++ root.insert_child(insert_pos, Node(syms.simple_stmt, children)) ++ ++ ++_def_syms = set([syms.classdef, syms.funcdef]) ++def find_binding(name, node, package=None): ++ """ Returns the node which binds variable name, otherwise None. ++ If optional argument package is supplied, only imports will ++ be returned. ++ See test cases for examples.""" ++ for child in node.children: ++ ret = None ++ if child.type == syms.for_stmt: ++ if _find(name, child.children[1]): ++ return child ++ n = find_binding(name, make_suite(child.children[-1]), package) ++ if n: ret = n ++ elif child.type in (syms.if_stmt, syms.while_stmt): ++ n = find_binding(name, make_suite(child.children[-1]), package) ++ if n: ret = n ++ elif child.type == syms.try_stmt: ++ n = find_binding(name, make_suite(child.children[2]), package) ++ if n: ++ ret = n ++ else: ++ for i, kid in enumerate(child.children[3:]): ++ if kid.type == token.COLON and kid.value == ":": ++ # i+3 is the colon, i+4 is the suite ++ n = find_binding(name, make_suite(child.children[i+4]), package) ++ if n: ret = n ++ elif child.type in _def_syms and child.children[1].value == name: ++ ret = child ++ elif _is_import_binding(child, name, package): ++ ret = child ++ elif child.type == syms.simple_stmt: ++ ret = find_binding(name, child, package) ++ elif child.type == syms.expr_stmt: ++ if _find(name, child.children[0]): ++ ret = child ++ ++ if ret: ++ if not package: ++ return ret ++ if is_import(ret): ++ return ret ++ return None ++ ++_block_syms = set([syms.funcdef, syms.classdef, syms.trailer]) ++def _find(name, node): ++ nodes = [node] ++ while nodes: ++ node = nodes.pop() ++ if node.type > 256 and node.type not in _block_syms: ++ nodes.extend(node.children) ++ elif node.type == token.NAME and node.value == name: ++ return node ++ return None ++ ++def _is_import_binding(node, name, package=None): ++ """ Will reuturn node if node will import name, or node ++ will import * from package. None is returned otherwise. ++ See test cases for examples. """ ++ ++ if node.type == syms.import_name and not package: ++ imp = node.children[1] ++ if imp.type == syms.dotted_as_names: ++ for child in imp.children: ++ if child.type == syms.dotted_as_name: ++ if child.children[2].value == name: ++ return node ++ elif child.type == token.NAME and child.value == name: ++ return node ++ elif imp.type == syms.dotted_as_name: ++ last = imp.children[-1] ++ if last.type == token.NAME and last.value == name: ++ return node ++ elif imp.type == token.NAME and imp.value == name: ++ return node ++ elif node.type == syms.import_from: ++ # unicode(...) is used to make life easier here, because ++ # from a.b import parses to ['import', ['a', '.', 'b'], ...] ++ if package and unicode(node.children[1]).strip() != package: ++ return None ++ n = node.children[3] ++ if package and _find('as', n): ++ # See test_from_import_as for explanation ++ return None ++ elif n.type == syms.import_as_names and _find(name, n): ++ return node ++ elif n.type == syms.import_as_name: ++ child = n.children[2] ++ if child.type == token.NAME and child.value == name: ++ return node ++ elif n.type == token.NAME and n.value == name: ++ return node ++ elif package and n.type == token.STAR: ++ return node ++ return None +diff -r 531f2e948299 refactor/.svn/text-base/main.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/text-base/main.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,133 @@ ++""" ++Main program for 2to3. ++""" ++ ++import sys ++import os ++import logging ++import shutil ++import optparse ++ ++from . import refactor ++ ++ ++class StdoutRefactoringTool(refactor.RefactoringTool): ++ """ ++ Prints output to stdout. ++ """ ++ ++ def __init__(self, fixers, options, explicit, nobackups): ++ self.nobackups = nobackups ++ super(StdoutRefactoringTool, self).__init__(fixers, options, explicit) ++ ++ def log_error(self, msg, *args, **kwargs): ++ self.errors.append((msg, args, kwargs)) ++ self.logger.error(msg, *args, **kwargs) ++ ++ def write_file(self, new_text, filename, old_text): ++ if not self.nobackups: ++ # Make backup ++ backup = filename + ".bak" ++ if os.path.lexists(backup): ++ try: ++ os.remove(backup) ++ except os.error, err: ++ self.log_message("Can't remove backup %s", backup) ++ try: ++ os.rename(filename, backup) ++ except os.error, err: ++ self.log_message("Can't rename %s to %s", filename, backup) ++ # Actually write the new file ++ super(StdoutRefactoringTool, self).write_file(new_text, ++ filename, old_text) ++ if not self.nobackups: ++ shutil.copymode(backup, filename) ++ ++ def print_output(self, lines): ++ for line in lines: ++ print line ++ ++ ++def main(fixer_pkg, args=None): ++ """Main program. ++ ++ Args: ++ fixer_pkg: the name of a package where the fixers are located. ++ args: optional; a list of command line arguments. If omitted, ++ sys.argv[1:] is used. ++ ++ Returns a suggested exit status (0, 1, 2). ++ """ ++ # Set up option parser ++ parser = optparse.OptionParser(usage="2to3 [options] file|dir ...") ++ parser.add_option("-d", "--doctests_only", action="store_true", ++ help="Fix up doctests only") ++ parser.add_option("-f", "--fix", action="append", default=[], ++ help="Each FIX specifies a transformation; default: all") ++ parser.add_option("-x", "--nofix", action="append", default=[], ++ help="Prevent a fixer from being run.") ++ parser.add_option("-l", "--list-fixes", action="store_true", ++ help="List available transformations (fixes/fix_*.py)") ++ parser.add_option("-p", "--print-function", action="store_true", ++ help="Modify the grammar so that print() is a function") ++ parser.add_option("-v", "--verbose", action="store_true", ++ help="More verbose logging") ++ 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.") ++ ++ # Parse command line arguments ++ refactor_stdin = False ++ options, args = parser.parse_args(args) ++ if not options.write and options.nobackups: ++ parser.error("Can't use -n without -w") ++ if options.list_fixes: ++ print "Available transformations for the -f/--fix option:" ++ for fixname in refactor.get_all_fix_names(fixer_pkg): ++ print fixname ++ if not args: ++ return 0 ++ if not args: ++ print >>sys.stderr, "At least one file or directory argument required." ++ print >>sys.stderr, "Use --help to show usage." ++ return 2 ++ if "-" in args: ++ refactor_stdin = True ++ if options.write: ++ print >>sys.stderr, "Can't write to stdin." ++ return 2 ++ ++ # Set up logging handler ++ level = logging.DEBUG if options.verbose else logging.INFO ++ logging.basicConfig(format='%(name)s: %(message)s', level=level) ++ ++ # Initialize the refactoring tool ++ rt_opts = {"print_function" : options.print_function} ++ avail_fixes = set(refactor.get_fixers_from_package(fixer_pkg)) ++ unwanted_fixes = set(fixer_pkg + ".fix_" + fix for fix in options.nofix) ++ explicit = set() ++ if options.fix: ++ all_present = False ++ for fix in options.fix: ++ if fix == "all": ++ all_present = True ++ else: ++ explicit.add(fixer_pkg + ".fix_" + fix) ++ requested = avail_fixes.union(explicit) if all_present else explicit ++ else: ++ requested = avail_fixes.union(explicit) ++ fixer_names = requested.difference(unwanted_fixes) ++ rt = StdoutRefactoringTool(sorted(fixer_names), rt_opts, sorted(explicit), ++ options.nobackups) ++ ++ # Refactor all files and directories passed as arguments ++ if not rt.errors: ++ if refactor_stdin: ++ rt.refactor_stdin() ++ else: ++ rt.refactor(args, options.write, options.doctests_only) ++ rt.summarize() ++ ++ # Return error status (0 if rt.errors is zero) ++ return int(bool(rt.errors)) +diff -r 531f2e948299 refactor/.svn/text-base/patcomp.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/text-base/patcomp.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,186 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Pattern compiler. ++ ++The grammer is taken from PatternGrammar.txt. ++ ++The compiler compiles a pattern to a pytree.*Pattern instance. ++""" ++ ++__author__ = "Guido van Rossum " ++ ++# Python imports ++import os ++ ++# Fairly local imports ++from .pgen2 import driver ++from .pgen2 import literals ++from .pgen2 import token ++from .pgen2 import tokenize ++ ++# Really local imports ++from . import pytree ++from . import pygram ++ ++# The pattern grammar file ++_PATTERN_GRAMMAR_FILE = os.path.join(os.path.dirname(__file__), ++ "PatternGrammar.txt") ++ ++ ++def tokenize_wrapper(input): ++ """Tokenizes a string suppressing significant whitespace.""" ++ skip = set((token.NEWLINE, token.INDENT, token.DEDENT)) ++ tokens = tokenize.generate_tokens(driver.generate_lines(input).next) ++ for quintuple in tokens: ++ type, value, start, end, line_text = quintuple ++ if type not in skip: ++ yield quintuple ++ ++ ++class PatternCompiler(object): ++ ++ def __init__(self, grammar_file=_PATTERN_GRAMMAR_FILE): ++ """Initializer. ++ ++ Takes an optional alternative filename for the pattern grammar. ++ """ ++ self.grammar = driver.load_grammar(grammar_file) ++ self.syms = pygram.Symbols(self.grammar) ++ self.pygrammar = pygram.python_grammar ++ self.pysyms = pygram.python_symbols ++ self.driver = driver.Driver(self.grammar, convert=pattern_convert) ++ ++ def compile_pattern(self, input, debug=False): ++ """Compiles a pattern string to a nested pytree.*Pattern object.""" ++ tokens = tokenize_wrapper(input) ++ root = self.driver.parse_tokens(tokens, debug=debug) ++ return self.compile_node(root) ++ ++ def compile_node(self, node): ++ """Compiles a node, recursively. ++ ++ This is one big switch on the node type. ++ """ ++ # XXX Optimize certain Wildcard-containing-Wildcard patterns ++ # that can be merged ++ if node.type == self.syms.Matcher: ++ node = node.children[0] # Avoid unneeded recursion ++ ++ if node.type == self.syms.Alternatives: ++ # Skip the odd children since they are just '|' tokens ++ alts = [self.compile_node(ch) for ch in node.children[::2]] ++ if len(alts) == 1: ++ return alts[0] ++ p = pytree.WildcardPattern([[a] for a in alts], min=1, max=1) ++ return p.optimize() ++ ++ if node.type == self.syms.Alternative: ++ units = [self.compile_node(ch) for ch in node.children] ++ if len(units) == 1: ++ return units[0] ++ p = pytree.WildcardPattern([units], min=1, max=1) ++ return p.optimize() ++ ++ if node.type == self.syms.NegatedUnit: ++ pattern = self.compile_basic(node.children[1:]) ++ p = pytree.NegatedPattern(pattern) ++ return p.optimize() ++ ++ assert node.type == self.syms.Unit ++ ++ name = None ++ nodes = node.children ++ if len(nodes) >= 3 and nodes[1].type == token.EQUAL: ++ name = nodes[0].value ++ nodes = nodes[2:] ++ repeat = None ++ if len(nodes) >= 2 and nodes[-1].type == self.syms.Repeater: ++ repeat = nodes[-1] ++ nodes = nodes[:-1] ++ ++ # Now we've reduced it to: STRING | NAME [Details] | (...) | [...] ++ pattern = self.compile_basic(nodes, repeat) ++ ++ if repeat is not None: ++ assert repeat.type == self.syms.Repeater ++ children = repeat.children ++ child = children[0] ++ if child.type == token.STAR: ++ min = 0 ++ max = pytree.HUGE ++ elif child.type == token.PLUS: ++ min = 1 ++ max = pytree.HUGE ++ elif child.type == token.LBRACE: ++ assert children[-1].type == token.RBRACE ++ assert len(children) in (3, 5) ++ min = max = self.get_int(children[1]) ++ if len(children) == 5: ++ max = self.get_int(children[3]) ++ else: ++ assert False ++ if min != 1 or max != 1: ++ pattern = pattern.optimize() ++ pattern = pytree.WildcardPattern([[pattern]], min=min, max=max) ++ ++ if name is not None: ++ pattern.name = name ++ return pattern.optimize() ++ ++ def compile_basic(self, nodes, repeat=None): ++ # Compile STRING | NAME [Details] | (...) | [...] ++ assert len(nodes) >= 1 ++ node = nodes[0] ++ if node.type == token.STRING: ++ value = literals.evalString(node.value) ++ return pytree.LeafPattern(content=value) ++ elif node.type == token.NAME: ++ value = node.value ++ if value.isupper(): ++ if value not in TOKEN_MAP: ++ raise SyntaxError("Invalid token: %r" % value) ++ return pytree.LeafPattern(TOKEN_MAP[value]) ++ else: ++ if value == "any": ++ type = None ++ elif not value.startswith("_"): ++ type = getattr(self.pysyms, value, None) ++ if type is None: ++ raise SyntaxError("Invalid symbol: %r" % value) ++ if nodes[1:]: # Details present ++ content = [self.compile_node(nodes[1].children[1])] ++ else: ++ content = None ++ return pytree.NodePattern(type, content) ++ elif node.value == "(": ++ return self.compile_node(nodes[1]) ++ elif node.value == "[": ++ assert repeat is None ++ subpattern = self.compile_node(nodes[1]) ++ return pytree.WildcardPattern([[subpattern]], min=0, max=1) ++ assert False, node ++ ++ def get_int(self, node): ++ assert node.type == token.NUMBER ++ return int(node.value) ++ ++ ++# Map named tokens to the type value for a LeafPattern ++TOKEN_MAP = {"NAME": token.NAME, ++ "STRING": token.STRING, ++ "NUMBER": token.NUMBER, ++ "TOKEN": None} ++ ++ ++def pattern_convert(grammar, raw_node_info): ++ """Converts raw node information to a Node or Leaf instance.""" ++ type, value, context, children = raw_node_info ++ if children or type in grammar.number2symbol: ++ return pytree.Node(type, children, context=context) ++ else: ++ return pytree.Leaf(type, value, context=context) ++ ++ ++def compile_pattern(pattern): ++ return PatternCompiler().compile_pattern(pattern) +diff -r 531f2e948299 refactor/.svn/text-base/pygram.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/text-base/pygram.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,31 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Export the Python grammar and symbols.""" ++ ++# Python imports ++import os ++ ++# Local imports ++from .pgen2 import token ++from .pgen2 import driver ++from . import pytree ++ ++# The grammar file ++_GRAMMAR_FILE = os.path.join(os.path.dirname(__file__), "Grammar.txt") ++ ++ ++class Symbols(object): ++ ++ def __init__(self, grammar): ++ """Initializer. ++ ++ Creates an attribute for each grammar symbol (nonterminal), ++ whose value is the symbol's type (an int >= 256). ++ """ ++ for name, symbol in grammar.symbol2number.iteritems(): ++ setattr(self, name, symbol) ++ ++ ++python_grammar = driver.load_grammar(_GRAMMAR_FILE) ++python_symbols = Symbols(python_grammar) +diff -r 531f2e948299 refactor/.svn/text-base/pytree.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/text-base/pytree.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,846 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++""" ++Python parse tree definitions. ++ ++This is a very concrete parse tree; we need to keep every token and ++even the comments and whitespace between tokens. ++ ++There's also a pattern matching implementation here. ++""" ++ ++__author__ = "Guido van Rossum " ++ ++import sys ++from StringIO import StringIO ++ ++ ++HUGE = 0x7FFFFFFF # maximum repeat count, default max ++ ++_type_reprs = {} ++def type_repr(type_num): ++ global _type_reprs ++ if not _type_reprs: ++ from .pygram import python_symbols ++ # printing tokens is possible but not as useful ++ # from .pgen2 import token // token.__dict__.items(): ++ for name, val in python_symbols.__dict__.items(): ++ if type(val) == int: _type_reprs[val] = name ++ return _type_reprs.setdefault(type_num, type_num) ++ ++ ++class Base(object): ++ ++ """ ++ Abstract base class for Node and Leaf. ++ ++ This provides some default functionality and boilerplate using the ++ template pattern. ++ ++ A node may be a subnode of at most one parent. ++ """ ++ ++ # Default values for instance variables ++ type = None # int: token number (< 256) or symbol number (>= 256) ++ parent = None # Parent node pointer, or None ++ children = () # Tuple of subnodes ++ was_changed = False ++ ++ def __new__(cls, *args, **kwds): ++ """Constructor that prevents Base from being instantiated.""" ++ assert cls is not Base, "Cannot instantiate Base" ++ return object.__new__(cls) ++ ++ def __eq__(self, other): ++ """ ++ Compare two nodes for equality. ++ ++ This calls the method _eq(). ++ """ ++ if self.__class__ is not other.__class__: ++ return NotImplemented ++ return self._eq(other) ++ ++ def __ne__(self, other): ++ """ ++ Compare two nodes for inequality. ++ ++ This calls the method _eq(). ++ """ ++ if self.__class__ is not other.__class__: ++ return NotImplemented ++ return not self._eq(other) ++ ++ def _eq(self, other): ++ """ ++ Compare two nodes for equality. ++ ++ This is called by __eq__ and __ne__. It is only called if the two nodes ++ have the same type. This must be implemented by the concrete subclass. ++ Nodes should be considered equal if they have the same structure, ++ ignoring the prefix string and other context information. ++ """ ++ raise NotImplementedError ++ ++ def clone(self): ++ """ ++ Return a cloned (deep) copy of self. ++ ++ This must be implemented by the concrete subclass. ++ """ ++ raise NotImplementedError ++ ++ def post_order(self): ++ """ ++ Return a post-order iterator for the tree. ++ ++ This must be implemented by the concrete subclass. ++ """ ++ raise NotImplementedError ++ ++ def pre_order(self): ++ """ ++ Return a pre-order iterator for the tree. ++ ++ This must be implemented by the concrete subclass. ++ """ ++ raise NotImplementedError ++ ++ def set_prefix(self, prefix): ++ """ ++ Set the prefix for the node (see Leaf class). ++ ++ This must be implemented by the concrete subclass. ++ """ ++ raise NotImplementedError ++ ++ def get_prefix(self): ++ """ ++ Return the prefix for the node (see Leaf class). ++ ++ This must be implemented by the concrete subclass. ++ """ ++ raise NotImplementedError ++ ++ def replace(self, new): ++ """Replace this node with a new one in the parent.""" ++ assert self.parent is not None, str(self) ++ assert new is not None ++ if not isinstance(new, list): ++ new = [new] ++ l_children = [] ++ found = False ++ for ch in self.parent.children: ++ if ch is self: ++ assert not found, (self.parent.children, self, new) ++ if new is not None: ++ l_children.extend(new) ++ found = True ++ else: ++ l_children.append(ch) ++ assert found, (self.children, self, new) ++ self.parent.changed() ++ self.parent.children = l_children ++ for x in new: ++ x.parent = self.parent ++ self.parent = None ++ ++ def get_lineno(self): ++ """Return the line number which generated the invocant node.""" ++ node = self ++ while not isinstance(node, Leaf): ++ if not node.children: ++ return ++ node = node.children[0] ++ return node.lineno ++ ++ def changed(self): ++ if self.parent: ++ self.parent.changed() ++ self.was_changed = True ++ ++ def remove(self): ++ """ ++ Remove the node from the tree. Returns the position of the node in its ++ parent's children before it was removed. ++ """ ++ if self.parent: ++ for i, node in enumerate(self.parent.children): ++ if node is self: ++ self.parent.changed() ++ del self.parent.children[i] ++ self.parent = None ++ return i ++ ++ @property ++ def next_sibling(self): ++ """ ++ The node immediately following the invocant in their parent's children ++ list. If the invocant does not have a next sibling, it is None ++ """ ++ if self.parent is None: ++ return None ++ ++ # Can't use index(); we need to test by identity ++ for i, child in enumerate(self.parent.children): ++ if child is self: ++ try: ++ return self.parent.children[i+1] ++ except IndexError: ++ return None ++ ++ @property ++ def prev_sibling(self): ++ """ ++ The node immediately preceding the invocant in their parent's children ++ list. If the invocant does not have a previous sibling, it is None. ++ """ ++ if self.parent is None: ++ return None ++ ++ # Can't use index(); we need to test by identity ++ for i, child in enumerate(self.parent.children): ++ if child is self: ++ if i == 0: ++ return None ++ return self.parent.children[i-1] ++ ++ def get_suffix(self): ++ """ ++ Return the string immediately following the invocant node. This is ++ effectively equivalent to node.next_sibling.get_prefix() ++ """ ++ next_sib = self.next_sibling ++ if next_sib is None: ++ return "" ++ return next_sib.get_prefix() ++ ++ ++class Node(Base): ++ ++ """Concrete implementation for interior nodes.""" ++ ++ def __init__(self, type, children, context=None, prefix=None): ++ """ ++ Initializer. ++ ++ Takes a type constant (a symbol number >= 256), a sequence of ++ child nodes, and an optional context keyword argument. ++ ++ As a side effect, the parent pointers of the children are updated. ++ """ ++ assert type >= 256, type ++ self.type = type ++ self.children = list(children) ++ for ch in self.children: ++ assert ch.parent is None, repr(ch) ++ ch.parent = self ++ if prefix is not None: ++ self.set_prefix(prefix) ++ ++ def __repr__(self): ++ """Return a canonical string representation.""" ++ return "%s(%s, %r)" % (self.__class__.__name__, ++ type_repr(self.type), ++ self.children) ++ ++ def __str__(self): ++ """ ++ Return a pretty string representation. ++ ++ This reproduces the input source exactly. ++ """ ++ return "".join(map(str, self.children)) ++ ++ def _eq(self, other): ++ """Compare two nodes for equality.""" ++ return (self.type, self.children) == (other.type, other.children) ++ ++ def clone(self): ++ """Return a cloned (deep) copy of self.""" ++ return Node(self.type, [ch.clone() for ch in self.children]) ++ ++ def post_order(self): ++ """Return a post-order iterator for the tree.""" ++ for child in self.children: ++ for node in child.post_order(): ++ yield node ++ yield self ++ ++ def pre_order(self): ++ """Return a pre-order iterator for the tree.""" ++ yield self ++ for child in self.children: ++ for node in child.post_order(): ++ yield node ++ ++ def set_prefix(self, prefix): ++ """ ++ Set the prefix for the node. ++ ++ This passes the responsibility on to the first child. ++ """ ++ if self.children: ++ self.children[0].set_prefix(prefix) ++ ++ def get_prefix(self): ++ """ ++ Return the prefix for the node. ++ ++ This passes the call on to the first child. ++ """ ++ if not self.children: ++ return "" ++ return self.children[0].get_prefix() ++ ++ def set_child(self, i, child): ++ """ ++ Equivalent to 'node.children[i] = child'. This method also sets the ++ child's parent attribute appropriately. ++ """ ++ child.parent = self ++ self.children[i].parent = None ++ self.children[i] = child ++ self.changed() ++ ++ def insert_child(self, i, child): ++ """ ++ Equivalent to 'node.children.insert(i, child)'. This method also sets ++ the child's parent attribute appropriately. ++ """ ++ child.parent = self ++ self.children.insert(i, child) ++ self.changed() ++ ++ def append_child(self, child): ++ """ ++ Equivalent to 'node.children.append(child)'. This method also sets the ++ child's parent attribute appropriately. ++ """ ++ child.parent = self ++ self.children.append(child) ++ self.changed() ++ ++ ++class Leaf(Base): ++ ++ """Concrete implementation for leaf nodes.""" ++ ++ # Default values for instance variables ++ prefix = "" # Whitespace and comments preceding this token in the input ++ lineno = 0 # Line where this token starts in the input ++ column = 0 # Column where this token tarts in the input ++ ++ def __init__(self, type, value, context=None, prefix=None): ++ """ ++ Initializer. ++ ++ Takes a type constant (a token number < 256), a string value, and an ++ optional context keyword argument. ++ """ ++ assert 0 <= type < 256, type ++ if context is not None: ++ self.prefix, (self.lineno, self.column) = context ++ self.type = type ++ self.value = value ++ if prefix is not None: ++ self.prefix = prefix ++ ++ def __repr__(self): ++ """Return a canonical string representation.""" ++ return "%s(%r, %r)" % (self.__class__.__name__, ++ self.type, ++ self.value) ++ ++ def __str__(self): ++ """ ++ Return a pretty string representation. ++ ++ This reproduces the input source exactly. ++ """ ++ return self.prefix + str(self.value) ++ ++ def _eq(self, other): ++ """Compare two nodes for equality.""" ++ return (self.type, self.value) == (other.type, other.value) ++ ++ def clone(self): ++ """Return a cloned (deep) copy of self.""" ++ return Leaf(self.type, self.value, ++ (self.prefix, (self.lineno, self.column))) ++ ++ def post_order(self): ++ """Return a post-order iterator for the tree.""" ++ yield self ++ ++ def pre_order(self): ++ """Return a pre-order iterator for the tree.""" ++ yield self ++ ++ def set_prefix(self, prefix): ++ """Set the prefix for the node.""" ++ self.changed() ++ self.prefix = prefix ++ ++ def get_prefix(self): ++ """Return the prefix for the node.""" ++ return self.prefix ++ ++ ++def convert(gr, raw_node): ++ """ ++ Convert raw node information to a Node or Leaf instance. ++ ++ This is passed to the parser driver which calls it whenever a reduction of a ++ grammar rule produces a new complete node, so that the tree is build ++ strictly bottom-up. ++ """ ++ type, value, context, children = raw_node ++ if children or type in gr.number2symbol: ++ # If there's exactly one child, return that child instead of ++ # creating a new node. ++ if len(children) == 1: ++ return children[0] ++ return Node(type, children, context=context) ++ else: ++ return Leaf(type, value, context=context) ++ ++ ++class BasePattern(object): ++ ++ """ ++ A pattern is a tree matching pattern. ++ ++ It looks for a specific node type (token or symbol), and ++ optionally for a specific content. ++ ++ This is an abstract base class. There are three concrete ++ subclasses: ++ ++ - LeafPattern matches a single leaf node; ++ - NodePattern matches a single node (usually non-leaf); ++ - WildcardPattern matches a sequence of nodes of variable length. ++ """ ++ ++ # Defaults for instance variables ++ type = None # Node type (token if < 256, symbol if >= 256) ++ content = None # Optional content matching pattern ++ name = None # Optional name used to store match in results dict ++ ++ def __new__(cls, *args, **kwds): ++ """Constructor that prevents BasePattern from being instantiated.""" ++ assert cls is not BasePattern, "Cannot instantiate BasePattern" ++ return object.__new__(cls) ++ ++ def __repr__(self): ++ args = [type_repr(self.type), self.content, self.name] ++ while args and args[-1] is None: ++ del args[-1] ++ return "%s(%s)" % (self.__class__.__name__, ", ".join(map(repr, args))) ++ ++ def optimize(self): ++ """ ++ A subclass can define this as a hook for optimizations. ++ ++ Returns either self or another node with the same effect. ++ """ ++ return self ++ ++ def match(self, node, results=None): ++ """ ++ Does this pattern exactly match a node? ++ ++ Returns True if it matches, False if not. ++ ++ If results is not None, it must be a dict which will be ++ updated with the nodes matching named subpatterns. ++ ++ Default implementation for non-wildcard patterns. ++ """ ++ if self.type is not None and node.type != self.type: ++ return False ++ if self.content is not None: ++ r = None ++ if results is not None: ++ r = {} ++ if not self._submatch(node, r): ++ return False ++ if r: ++ results.update(r) ++ if results is not None and self.name: ++ results[self.name] = node ++ return True ++ ++ def match_seq(self, nodes, results=None): ++ """ ++ Does this pattern exactly match a sequence of nodes? ++ ++ Default implementation for non-wildcard patterns. ++ """ ++ if len(nodes) != 1: ++ return False ++ return self.match(nodes[0], results) ++ ++ def generate_matches(self, nodes): ++ """ ++ Generator yielding all matches for this pattern. ++ ++ Default implementation for non-wildcard patterns. ++ """ ++ r = {} ++ if nodes and self.match(nodes[0], r): ++ yield 1, r ++ ++ ++class LeafPattern(BasePattern): ++ ++ def __init__(self, type=None, content=None, name=None): ++ """ ++ Initializer. Takes optional type, content, and name. ++ ++ The type, if given must be a token type (< 256). If not given, ++ this matches any *leaf* node; the content may still be required. ++ ++ The content, if given, must be a string. ++ ++ If a name is given, the matching node is stored in the results ++ dict under that key. ++ """ ++ if type is not None: ++ assert 0 <= type < 256, type ++ if content is not None: ++ assert isinstance(content, basestring), repr(content) ++ self.type = type ++ self.content = content ++ self.name = name ++ ++ def match(self, node, results=None): ++ """Override match() to insist on a leaf node.""" ++ if not isinstance(node, Leaf): ++ return False ++ return BasePattern.match(self, node, results) ++ ++ def _submatch(self, node, results=None): ++ """ ++ Match the pattern's content to the node's children. ++ ++ This assumes the node type matches and self.content is not None. ++ ++ Returns True if it matches, False if not. ++ ++ If results is not None, it must be a dict which will be ++ updated with the nodes matching named subpatterns. ++ ++ When returning False, the results dict may still be updated. ++ """ ++ return self.content == node.value ++ ++ ++class NodePattern(BasePattern): ++ ++ wildcards = False ++ ++ def __init__(self, type=None, content=None, name=None): ++ """ ++ Initializer. Takes optional type, content, and name. ++ ++ The type, if given, must be a symbol type (>= 256). If the ++ type is None this matches *any* single node (leaf or not), ++ except if content is not None, in which it only matches ++ non-leaf nodes that also match the content pattern. ++ ++ The content, if not None, must be a sequence of Patterns that ++ must match the node's children exactly. If the content is ++ given, the type must not be None. ++ ++ If a name is given, the matching node is stored in the results ++ dict under that key. ++ """ ++ if type is not None: ++ assert type >= 256, type ++ if content is not None: ++ assert not isinstance(content, basestring), repr(content) ++ content = list(content) ++ for i, item in enumerate(content): ++ assert isinstance(item, BasePattern), (i, item) ++ if isinstance(item, WildcardPattern): ++ self.wildcards = True ++ self.type = type ++ self.content = content ++ self.name = name ++ ++ def _submatch(self, node, results=None): ++ """ ++ Match the pattern's content to the node's children. ++ ++ This assumes the node type matches and self.content is not None. ++ ++ Returns True if it matches, False if not. ++ ++ If results is not None, it must be a dict which will be ++ updated with the nodes matching named subpatterns. ++ ++ When returning False, the results dict may still be updated. ++ """ ++ if self.wildcards: ++ for c, r in generate_matches(self.content, node.children): ++ if c == len(node.children): ++ if results is not None: ++ results.update(r) ++ return True ++ return False ++ if len(self.content) != len(node.children): ++ return False ++ for subpattern, child in zip(self.content, node.children): ++ if not subpattern.match(child, results): ++ return False ++ return True ++ ++ ++class WildcardPattern(BasePattern): ++ ++ """ ++ A wildcard pattern can match zero or more nodes. ++ ++ This has all the flexibility needed to implement patterns like: ++ ++ .* .+ .? .{m,n} ++ (a b c | d e | f) ++ (...)* (...)+ (...)? (...){m,n} ++ ++ except it always uses non-greedy matching. ++ """ ++ ++ def __init__(self, content=None, min=0, max=HUGE, name=None): ++ """ ++ Initializer. ++ ++ Args: ++ content: optional sequence of subsequences of patterns; ++ if absent, matches one node; ++ if present, each subsequence is an alternative [*] ++ min: optinal minumum number of times to match, default 0 ++ max: optional maximum number of times tro match, default HUGE ++ name: optional name assigned to this match ++ ++ [*] Thus, if content is [[a, b, c], [d, e], [f, g, h]] this is ++ equivalent to (a b c | d e | f g h); if content is None, ++ this is equivalent to '.' in regular expression terms. ++ The min and max parameters work as follows: ++ min=0, max=maxint: .* ++ min=1, max=maxint: .+ ++ min=0, max=1: .? ++ min=1, max=1: . ++ If content is not None, replace the dot with the parenthesized ++ list of alternatives, e.g. (a b c | d e | f g h)* ++ """ ++ assert 0 <= min <= max <= HUGE, (min, max) ++ if content is not None: ++ content = tuple(map(tuple, content)) # Protect against alterations ++ # Check sanity of alternatives ++ assert len(content), repr(content) # Can't have zero alternatives ++ for alt in content: ++ assert len(alt), repr(alt) # Can have empty alternatives ++ self.content = content ++ self.min = min ++ self.max = max ++ self.name = name ++ ++ def optimize(self): ++ """Optimize certain stacked wildcard patterns.""" ++ subpattern = None ++ if (self.content is not None and ++ len(self.content) == 1 and len(self.content[0]) == 1): ++ subpattern = self.content[0][0] ++ if self.min == 1 and self.max == 1: ++ if self.content is None: ++ return NodePattern(name=self.name) ++ if subpattern is not None and self.name == subpattern.name: ++ return subpattern.optimize() ++ if (self.min <= 1 and isinstance(subpattern, WildcardPattern) and ++ subpattern.min <= 1 and self.name == subpattern.name): ++ return WildcardPattern(subpattern.content, ++ self.min*subpattern.min, ++ self.max*subpattern.max, ++ subpattern.name) ++ return self ++ ++ def match(self, node, results=None): ++ """Does this pattern exactly match a node?""" ++ return self.match_seq([node], results) ++ ++ def match_seq(self, nodes, results=None): ++ """Does this pattern exactly match a sequence of nodes?""" ++ for c, r in self.generate_matches(nodes): ++ if c == len(nodes): ++ if results is not None: ++ results.update(r) ++ if self.name: ++ results[self.name] = list(nodes) ++ return True ++ return False ++ ++ def generate_matches(self, nodes): ++ """ ++ Generator yielding matches for a sequence of nodes. ++ ++ Args: ++ nodes: sequence of nodes ++ ++ Yields: ++ (count, results) tuples where: ++ count: the match comprises nodes[:count]; ++ results: dict containing named submatches. ++ """ ++ if self.content is None: ++ # Shortcut for special case (see __init__.__doc__) ++ for count in xrange(self.min, 1 + min(len(nodes), self.max)): ++ r = {} ++ if self.name: ++ r[self.name] = nodes[:count] ++ yield count, r ++ elif self.name == "bare_name": ++ yield self._bare_name_matches(nodes) ++ else: ++ # The reason for this is that hitting the recursion limit usually ++ # results in some ugly messages about how RuntimeErrors are being ++ # ignored. ++ save_stderr = sys.stderr ++ sys.stderr = StringIO() ++ try: ++ for count, r in self._recursive_matches(nodes, 0): ++ if self.name: ++ r[self.name] = nodes[:count] ++ yield count, r ++ except RuntimeError: ++ # We fall back to the iterative pattern matching scheme if the recursive ++ # scheme hits the recursion limit. ++ for count, r in self._iterative_matches(nodes): ++ if self.name: ++ r[self.name] = nodes[:count] ++ yield count, r ++ finally: ++ sys.stderr = save_stderr ++ ++ def _iterative_matches(self, nodes): ++ """Helper to iteratively yield the matches.""" ++ nodelen = len(nodes) ++ if 0 >= self.min: ++ yield 0, {} ++ ++ results = [] ++ # generate matches that use just one alt from self.content ++ for alt in self.content: ++ for c, r in generate_matches(alt, nodes): ++ yield c, r ++ results.append((c, r)) ++ ++ # for each match, iterate down the nodes ++ while results: ++ new_results = [] ++ for c0, r0 in results: ++ # stop if the entire set of nodes has been matched ++ if c0 < nodelen and c0 <= self.max: ++ for alt in self.content: ++ for c1, r1 in generate_matches(alt, nodes[c0:]): ++ if c1 > 0: ++ r = {} ++ r.update(r0) ++ r.update(r1) ++ yield c0 + c1, r ++ new_results.append((c0 + c1, r)) ++ results = new_results ++ ++ def _bare_name_matches(self, nodes): ++ """Special optimized matcher for bare_name.""" ++ count = 0 ++ r = {} ++ done = False ++ max = len(nodes) ++ while not done and count < max: ++ done = True ++ for leaf in self.content: ++ if leaf[0].match(nodes[count], r): ++ count += 1 ++ done = False ++ break ++ r[self.name] = nodes[:count] ++ return count, r ++ ++ def _recursive_matches(self, nodes, count): ++ """Helper to recursively yield the matches.""" ++ assert self.content is not None ++ if count >= self.min: ++ yield 0, {} ++ if count < self.max: ++ for alt in self.content: ++ for c0, r0 in generate_matches(alt, nodes): ++ for c1, r1 in self._recursive_matches(nodes[c0:], count+1): ++ r = {} ++ r.update(r0) ++ r.update(r1) ++ yield c0 + c1, r ++ ++ ++class NegatedPattern(BasePattern): ++ ++ def __init__(self, content=None): ++ """ ++ Initializer. ++ ++ The argument is either a pattern or None. If it is None, this ++ only matches an empty sequence (effectively '$' in regex ++ lingo). If it is not None, this matches whenever the argument ++ pattern doesn't have any matches. ++ """ ++ if content is not None: ++ assert isinstance(content, BasePattern), repr(content) ++ self.content = content ++ ++ def match(self, node): ++ # We never match a node in its entirety ++ return False ++ ++ def match_seq(self, nodes): ++ # We only match an empty sequence of nodes in its entirety ++ return len(nodes) == 0 ++ ++ def generate_matches(self, nodes): ++ if self.content is None: ++ # Return a match if there is an empty sequence ++ if len(nodes) == 0: ++ yield 0, {} ++ else: ++ # Return a match if the argument pattern has no matches ++ for c, r in self.content.generate_matches(nodes): ++ return ++ yield 0, {} ++ ++ ++def generate_matches(patterns, nodes): ++ """ ++ Generator yielding matches for a sequence of patterns and nodes. ++ ++ Args: ++ patterns: a sequence of patterns ++ nodes: a sequence of nodes ++ ++ Yields: ++ (count, results) tuples where: ++ count: the entire sequence of patterns matches nodes[:count]; ++ results: dict containing named submatches. ++ """ ++ if not patterns: ++ yield 0, {} ++ else: ++ p, rest = patterns[0], patterns[1:] ++ for c0, r0 in p.generate_matches(nodes): ++ if not rest: ++ yield c0, r0 ++ else: ++ for c1, r1 in generate_matches(rest, nodes[c0:]): ++ r = {} ++ r.update(r0) ++ r.update(r1) ++ yield c0 + c1, r +diff -r 531f2e948299 refactor/.svn/text-base/refactor.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/.svn/text-base/refactor.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,515 @@ ++#!/usr/bin/env python2.5 ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Refactoring framework. ++ ++Used as a main program, this can refactor any number of files and/or ++recursively descend down directories. Imported as a module, this ++provides infrastructure to write your own refactoring tool. ++""" ++ ++__author__ = "Guido van Rossum " ++ ++ ++# Python imports ++import os ++import sys ++import difflib ++import logging ++import operator ++from collections import defaultdict ++from itertools import chain ++ ++# Local imports ++from .pgen2 import driver ++from .pgen2 import tokenize ++ ++from . import pytree ++from . import patcomp ++from . import fixes ++from . import pygram ++ ++ ++def get_all_fix_names(fixer_pkg, remove_prefix=True): ++ """Return a sorted list of all available fix names in the given package.""" ++ pkg = __import__(fixer_pkg, [], [], ["*"]) ++ fixer_dir = os.path.dirname(pkg.__file__) ++ fix_names = [] ++ for name in sorted(os.listdir(fixer_dir)): ++ if name.startswith("fix_") and name.endswith(".py"): ++ if remove_prefix: ++ name = name[4:] ++ fix_names.append(name[:-3]) ++ return fix_names ++ ++def get_head_types(pat): ++ """ Accepts a pytree Pattern Node and returns a set ++ of the pattern types which will match first. """ ++ ++ if isinstance(pat, (pytree.NodePattern, pytree.LeafPattern)): ++ # NodePatters must either have no type and no content ++ # or a type and content -- so they don't get any farther ++ # Always return leafs ++ return set([pat.type]) ++ ++ if isinstance(pat, pytree.NegatedPattern): ++ if pat.content: ++ return get_head_types(pat.content) ++ return set([None]) # Negated Patterns don't have a type ++ ++ if isinstance(pat, pytree.WildcardPattern): ++ # Recurse on each node in content ++ r = set() ++ for p in pat.content: ++ for x in p: ++ r.update(get_head_types(x)) ++ return r ++ ++ raise Exception("Oh no! I don't understand pattern %s" %(pat)) ++ ++def get_headnode_dict(fixer_list): ++ """ Accepts a list of fixers and returns a dictionary ++ of head node type --> fixer list. """ ++ head_nodes = defaultdict(list) ++ for fixer in fixer_list: ++ if not fixer.pattern: ++ head_nodes[None].append(fixer) ++ continue ++ for t in get_head_types(fixer.pattern): ++ head_nodes[t].append(fixer) ++ return head_nodes ++ ++def get_fixers_from_package(pkg_name): ++ """ ++ Return the fully qualified names for fixers in the package pkg_name. ++ """ ++ return [pkg_name + "." + fix_name ++ for fix_name in get_all_fix_names(pkg_name, False)] ++ ++ ++class FixerError(Exception): ++ """A fixer could not be loaded.""" ++ ++ ++class RefactoringTool(object): ++ ++ _default_options = {"print_function": False} ++ ++ CLASS_PREFIX = "Fix" # The prefix for fixer classes ++ FILE_PREFIX = "fix_" # The prefix for modules with a fixer within ++ ++ def __init__(self, fixer_names, options=None, explicit=None): ++ """Initializer. ++ ++ Args: ++ fixer_names: a list of fixers to import ++ options: an dict with configuration. ++ explicit: a list of fixers to run even if they are explicit. ++ """ ++ self.fixers = fixer_names ++ self.explicit = explicit or [] ++ self.options = self._default_options.copy() ++ if options is not None: ++ self.options.update(options) ++ self.errors = [] ++ self.logger = logging.getLogger("RefactoringTool") ++ self.fixer_log = [] ++ self.wrote = False ++ if self.options["print_function"]: ++ del pygram.python_grammar.keywords["print"] ++ self.driver = driver.Driver(pygram.python_grammar, ++ convert=pytree.convert, ++ logger=self.logger) ++ self.pre_order, self.post_order = self.get_fixers() ++ ++ self.pre_order_heads = get_headnode_dict(self.pre_order) ++ self.post_order_heads = get_headnode_dict(self.post_order) ++ ++ self.files = [] # List of files that were or should be modified ++ ++ def get_fixers(self): ++ """Inspects the options to load the requested patterns and handlers. ++ ++ Returns: ++ (pre_order, post_order), where pre_order is the list of fixers that ++ want a pre-order AST traversal, and post_order is the list that want ++ post-order traversal. ++ """ ++ pre_order_fixers = [] ++ post_order_fixers = [] ++ for fix_mod_path in self.fixers: ++ mod = __import__(fix_mod_path, {}, {}, ["*"]) ++ fix_name = fix_mod_path.rsplit(".", 1)[-1] ++ if fix_name.startswith(self.FILE_PREFIX): ++ fix_name = fix_name[len(self.FILE_PREFIX):] ++ parts = fix_name.split("_") ++ class_name = self.CLASS_PREFIX + "".join([p.title() for p in parts]) ++ try: ++ fix_class = getattr(mod, class_name) ++ except AttributeError: ++ raise FixerError("Can't find %s.%s" % (fix_name, class_name)) ++ fixer = fix_class(self.options, self.fixer_log) ++ if fixer.explicit and self.explicit is not True and \ ++ fix_mod_path not in self.explicit: ++ self.log_message("Skipping implicit fixer: %s", fix_name) ++ continue ++ ++ self.log_debug("Adding transformation: %s", fix_name) ++ if fixer.order == "pre": ++ pre_order_fixers.append(fixer) ++ elif fixer.order == "post": ++ post_order_fixers.append(fixer) ++ else: ++ raise FixerError("Illegal fixer order: %r" % fixer.order) ++ ++ key_func = operator.attrgetter("run_order") ++ pre_order_fixers.sort(key=key_func) ++ post_order_fixers.sort(key=key_func) ++ return (pre_order_fixers, post_order_fixers) ++ ++ def log_error(self, msg, *args, **kwds): ++ """Called when an error occurs.""" ++ raise ++ ++ def log_message(self, msg, *args): ++ """Hook to log a message.""" ++ if args: ++ msg = msg % args ++ self.logger.info(msg) ++ ++ def log_debug(self, msg, *args): ++ if args: ++ msg = msg % args ++ self.logger.debug(msg) ++ ++ def print_output(self, lines): ++ """Called with lines of output to give to the user.""" ++ pass ++ ++ def refactor(self, items, write=False, doctests_only=False): ++ """Refactor a list of files and directories.""" ++ for dir_or_file in items: ++ if os.path.isdir(dir_or_file): ++ self.refactor_dir(dir_or_file, write, doctests_only) ++ else: ++ self.refactor_file(dir_or_file, write, doctests_only) ++ ++ def refactor_dir(self, dir_name, write=False, doctests_only=False): ++ """Descends down a directory and refactor every Python file found. ++ ++ Python files are assumed to have a .py extension. ++ ++ Files and subdirectories starting with '.' are skipped. ++ """ ++ 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 name.endswith("py"): ++ fullname = os.path.join(dirpath, name) ++ self.refactor_file(fullname, write, doctests_only) ++ # Modify dirnames in-place to remove subdirs with leading dots ++ dirnames[:] = [dn for dn in dirnames if not dn.startswith(".")] ++ ++ def refactor_file(self, filename, write=False, doctests_only=False): ++ """Refactors a file.""" ++ try: ++ f = open(filename) ++ except IOError, err: ++ self.log_error("Can't open %s: %s", filename, err) ++ return ++ try: ++ input = f.read() + "\n" # Silence certain parse errors ++ finally: ++ f.close() ++ if doctests_only: ++ self.log_debug("Refactoring doctests in %s", filename) ++ output = self.refactor_docstring(input, filename) ++ if output != input: ++ self.processed_file(output, filename, input, write=write) ++ else: ++ self.log_debug("No doctest changes in %s", filename) ++ else: ++ tree = self.refactor_string(input, filename) ++ if tree and tree.was_changed: ++ # The [:-1] is to take off the \n we added earlier ++ self.processed_file(str(tree)[:-1], filename, write=write) ++ else: ++ self.log_debug("No changes in %s", filename) ++ ++ def refactor_string(self, data, name): ++ """Refactor a given input string. ++ ++ Args: ++ data: a string holding the code to be refactored. ++ name: a human-readable name for use in error/log messages. ++ ++ Returns: ++ An AST corresponding to the refactored input stream; None if ++ there were errors during the parse. ++ """ ++ try: ++ tree = self.driver.parse_string(data) ++ except Exception, err: ++ self.log_error("Can't parse %s: %s: %s", ++ name, err.__class__.__name__, err) ++ return ++ self.log_debug("Refactoring %s", name) ++ self.refactor_tree(tree, name) ++ return tree ++ ++ def refactor_stdin(self, doctests_only=False): ++ input = sys.stdin.read() ++ if doctests_only: ++ self.log_debug("Refactoring doctests in stdin") ++ output = self.refactor_docstring(input, "") ++ if output != input: ++ self.processed_file(output, "", input) ++ else: ++ self.log_debug("No doctest changes in stdin") ++ else: ++ tree = self.refactor_string(input, "") ++ if tree and tree.was_changed: ++ self.processed_file(str(tree), "", input) ++ else: ++ self.log_debug("No changes in stdin") ++ ++ def refactor_tree(self, tree, name): ++ """Refactors a parse tree (modifying the tree in place). ++ ++ Args: ++ tree: a pytree.Node instance representing the root of the tree ++ to be refactored. ++ name: a human-readable name for this tree. ++ ++ Returns: ++ True if the tree was modified, False otherwise. ++ """ ++ for fixer in chain(self.pre_order, self.post_order): ++ fixer.start_tree(tree, name) ++ ++ self.traverse_by(self.pre_order_heads, tree.pre_order()) ++ self.traverse_by(self.post_order_heads, tree.post_order()) ++ ++ for fixer in chain(self.pre_order, self.post_order): ++ fixer.finish_tree(tree, name) ++ return tree.was_changed ++ ++ def traverse_by(self, fixers, traversal): ++ """Traverse an AST, applying a set of fixers to each node. ++ ++ This is a helper method for refactor_tree(). ++ ++ Args: ++ fixers: a list of fixer instances. ++ traversal: a generator that yields AST nodes. ++ ++ Returns: ++ None ++ """ ++ if not fixers: ++ return ++ for node in traversal: ++ for fixer in fixers[node.type] + fixers[None]: ++ results = fixer.match(node) ++ if results: ++ new = fixer.transform(node, results) ++ if new is not None and (new != node or ++ str(new) != str(node)): ++ node.replace(new) ++ node = new ++ ++ def processed_file(self, new_text, filename, old_text=None, write=False): ++ """ ++ Called when a file has been refactored, and there are changes. ++ """ ++ self.files.append(filename) ++ if old_text is None: ++ try: ++ f = open(filename, "r") ++ except IOError, err: ++ self.log_error("Can't read %s: %s", filename, err) ++ return ++ try: ++ old_text = f.read() ++ finally: ++ f.close() ++ if old_text == new_text: ++ self.log_debug("No changes to %s", filename) ++ return ++ self.print_output(diff_texts(old_text, new_text, filename)) ++ if write: ++ self.write_file(new_text, filename, old_text) ++ else: ++ self.log_debug("Not writing changes to %s", filename) ++ ++ def write_file(self, new_text, filename, old_text): ++ """Writes a string to a file. ++ ++ It first shows a unified diff between the old text and the new text, and ++ then rewrites the file; the latter is only done if the write option is ++ set. ++ """ ++ try: ++ f = open(filename, "w") ++ except os.error, err: ++ self.log_error("Can't create %s: %s", filename, err) ++ return ++ try: ++ f.write(new_text) ++ except os.error, err: ++ self.log_error("Can't write %s: %s", filename, err) ++ finally: ++ f.close() ++ self.log_debug("Wrote changes to %s", filename) ++ self.wrote = True ++ ++ PS1 = ">>> " ++ PS2 = "... " ++ ++ def refactor_docstring(self, input, filename): ++ """Refactors a docstring, looking for doctests. ++ ++ This returns a modified version of the input string. It looks ++ for doctests, which start with a ">>>" prompt, and may be ++ continued with "..." prompts, as long as the "..." is indented ++ the same as the ">>>". ++ ++ (Unfortunately we can't use the doctest module's parser, ++ since, like most parsers, it is not geared towards preserving ++ the original source.) ++ """ ++ result = [] ++ block = None ++ block_lineno = None ++ indent = None ++ lineno = 0 ++ for line in input.splitlines(True): ++ lineno += 1 ++ if line.lstrip().startswith(self.PS1): ++ if block is not None: ++ result.extend(self.refactor_doctest(block, block_lineno, ++ indent, filename)) ++ block_lineno = lineno ++ block = [line] ++ i = line.find(self.PS1) ++ indent = line[:i] ++ elif (indent is not None and ++ (line.startswith(indent + self.PS2) or ++ line == indent + self.PS2.rstrip() + "\n")): ++ block.append(line) ++ else: ++ if block is not None: ++ result.extend(self.refactor_doctest(block, block_lineno, ++ indent, filename)) ++ block = None ++ indent = None ++ result.append(line) ++ if block is not None: ++ result.extend(self.refactor_doctest(block, block_lineno, ++ indent, filename)) ++ return "".join(result) ++ ++ def refactor_doctest(self, block, lineno, indent, filename): ++ """Refactors one doctest. ++ ++ A doctest is given as a block of lines, the first of which starts ++ with ">>>" (possibly indented), while the remaining lines start ++ with "..." (identically indented). ++ ++ """ ++ try: ++ tree = self.parse_block(block, lineno, indent) ++ except Exception, err: ++ if self.log.isEnabledFor(logging.DEBUG): ++ for line in block: ++ self.log_debug("Source: %s", line.rstrip("\n")) ++ self.log_error("Can't parse docstring in %s line %s: %s: %s", ++ filename, lineno, err.__class__.__name__, err) ++ return block ++ if self.refactor_tree(tree, filename): ++ new = str(tree).splitlines(True) ++ # Undo the adjustment of the line numbers in wrap_toks() below. ++ clipped, new = new[:lineno-1], new[lineno-1:] ++ assert clipped == ["\n"] * (lineno-1), clipped ++ if not new[-1].endswith("\n"): ++ new[-1] += "\n" ++ block = [indent + self.PS1 + new.pop(0)] ++ if new: ++ block += [indent + self.PS2 + line for line in new] ++ return block ++ ++ def summarize(self): ++ if self.wrote: ++ were = "were" ++ else: ++ were = "need to be" ++ if not self.files: ++ self.log_message("No files %s modified.", were) ++ else: ++ self.log_message("Files that %s modified:", were) ++ for file in self.files: ++ self.log_message(file) ++ if self.fixer_log: ++ self.log_message("Warnings/messages while refactoring:") ++ for message in self.fixer_log: ++ self.log_message(message) ++ if self.errors: ++ if len(self.errors) == 1: ++ self.log_message("There was 1 error:") ++ else: ++ self.log_message("There were %d errors:", len(self.errors)) ++ for msg, args, kwds in self.errors: ++ self.log_message(msg, *args, **kwds) ++ ++ def parse_block(self, block, lineno, indent): ++ """Parses a block into a tree. ++ ++ This is necessary to get correct line number / offset information ++ in the parser diagnostics and embedded into the parse tree. ++ """ ++ return self.driver.parse_tokens(self.wrap_toks(block, lineno, indent)) ++ ++ def wrap_toks(self, block, lineno, indent): ++ """Wraps a tokenize stream to systematically modify start/end.""" ++ tokens = tokenize.generate_tokens(self.gen_lines(block, indent).next) ++ for type, value, (line0, col0), (line1, col1), line_text in tokens: ++ line0 += lineno - 1 ++ line1 += lineno - 1 ++ # Don't bother updating the columns; this is too complicated ++ # since line_text would also have to be updated and it would ++ # still break for tokens spanning lines. Let the user guess ++ # that the column numbers for doctests are relative to the ++ # end of the prompt string (PS1 or PS2). ++ yield type, value, (line0, col0), (line1, col1), line_text ++ ++ ++ def gen_lines(self, block, indent): ++ """Generates lines as expected by tokenize from a list of lines. ++ ++ This strips the first len(indent + self.PS1) characters off each line. ++ """ ++ prefix1 = indent + self.PS1 ++ prefix2 = indent + self.PS2 ++ prefix = prefix1 ++ for line in block: ++ if line.startswith(prefix): ++ yield line[len(prefix):] ++ elif line == prefix.rstrip() + "\n": ++ yield "\n" ++ else: ++ raise AssertionError("line=%r, prefix=%r" % (line, prefix)) ++ prefix = prefix2 ++ while True: ++ yield "" ++ ++ ++def diff_texts(a, b, filename): ++ """Return a unified diff of two strings.""" ++ a = a.splitlines() ++ b = b.splitlines() ++ return difflib.unified_diff(a, b, filename, filename, ++ "(original)", "(refactored)", ++ lineterm="") +diff -r 531f2e948299 refactor/Grammar.txt +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/Grammar.txt Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,155 @@ ++# Grammar for Python ++ ++# Note: Changing the grammar specified in this file will most likely ++# require corresponding changes in the parser module ++# (../Modules/parsermodule.c). If you can't make the changes to ++# that module yourself, please co-ordinate the required changes ++# with someone who can; ask around on python-dev for help. Fred ++# Drake will probably be listening there. ++ ++# NOTE WELL: You should also follow all the steps listed in PEP 306, ++# "How to Change Python's Grammar" ++ ++# Commands for Kees Blom's railroad program ++#diagram:token NAME ++#diagram:token NUMBER ++#diagram:token STRING ++#diagram:token NEWLINE ++#diagram:token ENDMARKER ++#diagram:token INDENT ++#diagram:output\input python.bla ++#diagram:token DEDENT ++#diagram:output\textwidth 20.04cm\oddsidemargin 0.0cm\evensidemargin 0.0cm ++#diagram:rules ++ ++# Start symbols for the grammar: ++# file_input is a module or sequence of commands read from an input file; ++# single_input is a single interactive statement; ++# eval_input is the input for the eval() and input() functions. ++# NB: compound_stmt in single_input is followed by extra NEWLINE! ++file_input: (NEWLINE | stmt)* ENDMARKER ++single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE ++eval_input: testlist NEWLINE* ENDMARKER ++ ++decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE ++decorators: decorator+ ++decorated: decorators (classdef | funcdef) ++funcdef: 'def' NAME parameters ['->' test] ':' suite ++parameters: '(' [typedargslist] ')' ++typedargslist: ((tfpdef ['=' test] ',')* ++ ('*' [tname] (',' tname ['=' test])* [',' '**' tname] | '**' tname) ++ | tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) ++tname: NAME [':' test] ++tfpdef: tname | '(' tfplist ')' ++tfplist: tfpdef (',' tfpdef)* [','] ++varargslist: ((vfpdef ['=' test] ',')* ++ ('*' [vname] (',' vname ['=' test])* [',' '**' vname] | '**' vname) ++ | vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) ++vname: NAME ++vfpdef: vname | '(' vfplist ')' ++vfplist: vfpdef (',' vfpdef)* [','] ++ ++stmt: simple_stmt | compound_stmt ++simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE ++small_stmt: (expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | ++ import_stmt | global_stmt | exec_stmt | assert_stmt) ++expr_stmt: testlist (augassign (yield_expr|testlist) | ++ ('=' (yield_expr|testlist))*) ++augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | ++ '<<=' | '>>=' | '**=' | '//=') ++# For normal assignments, additional restrictions enforced by the interpreter ++print_stmt: 'print' ( [ test (',' test)* [','] ] | ++ '>>' test [ (',' test)+ [','] ] ) ++del_stmt: 'del' exprlist ++pass_stmt: 'pass' ++flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt ++break_stmt: 'break' ++continue_stmt: 'continue' ++return_stmt: 'return' [testlist] ++yield_stmt: yield_expr ++raise_stmt: 'raise' [test ['from' test | ',' test [',' test]]] ++import_stmt: import_name | import_from ++import_name: 'import' dotted_as_names ++import_from: ('from' ('.'* dotted_name | '.'+) ++ 'import' ('*' | '(' import_as_names ')' | import_as_names)) ++import_as_name: NAME ['as' NAME] ++dotted_as_name: dotted_name ['as' NAME] ++import_as_names: import_as_name (',' import_as_name)* [','] ++dotted_as_names: dotted_as_name (',' dotted_as_name)* ++dotted_name: NAME ('.' NAME)* ++global_stmt: ('global' | 'nonlocal') NAME (',' NAME)* ++exec_stmt: 'exec' expr ['in' test [',' test]] ++assert_stmt: 'assert' test [',' test] ++ ++compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated ++if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] ++while_stmt: 'while' test ':' suite ['else' ':' suite] ++for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] ++try_stmt: ('try' ':' suite ++ ((except_clause ':' suite)+ ++ ['else' ':' suite] ++ ['finally' ':' suite] | ++ 'finally' ':' suite)) ++with_stmt: 'with' test [ with_var ] ':' suite ++with_var: 'as' expr ++# NB compile.c makes sure that the default except clause is last ++except_clause: 'except' [test [(',' | 'as') test]] ++suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT ++ ++# Backward compatibility cruft to support: ++# [ x for x in lambda: True, lambda: False if x() ] ++# even while also allowing: ++# lambda x: 5 if x else 2 ++# (But not a mix of the two) ++testlist_safe: old_test [(',' old_test)+ [',']] ++old_test: or_test | old_lambdef ++old_lambdef: 'lambda' [varargslist] ':' old_test ++ ++test: or_test ['if' or_test 'else' test] | lambdef ++or_test: and_test ('or' and_test)* ++and_test: not_test ('and' not_test)* ++not_test: 'not' not_test | comparison ++comparison: expr (comp_op expr)* ++comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' ++expr: xor_expr ('|' xor_expr)* ++xor_expr: and_expr ('^' and_expr)* ++and_expr: shift_expr ('&' shift_expr)* ++shift_expr: arith_expr (('<<'|'>>') arith_expr)* ++arith_expr: term (('+'|'-') term)* ++term: factor (('*'|'/'|'%'|'//') factor)* ++factor: ('+'|'-'|'~') factor | power ++power: atom trailer* ['**' factor] ++atom: ('(' [yield_expr|testlist_gexp] ')' | ++ '[' [listmaker] ']' | ++ '{' [dictsetmaker] '}' | ++ '`' testlist1 '`' | ++ NAME | NUMBER | STRING+ | '.' '.' '.') ++listmaker: test ( comp_for | (',' test)* [','] ) ++testlist_gexp: test ( comp_for | (',' test)* [','] ) ++lambdef: 'lambda' [varargslist] ':' test ++trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME ++subscriptlist: subscript (',' subscript)* [','] ++subscript: test | [test] ':' [test] [sliceop] ++sliceop: ':' [test] ++exprlist: expr (',' expr)* [','] ++testlist: test (',' test)* [','] ++dictsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) | ++ (test (comp_for | (',' test)* [','])) ) ++ ++classdef: 'class' NAME ['(' [arglist] ')'] ':' suite ++ ++arglist: (argument ',')* (argument [','] ++ |'*' test (',' argument)* [',' '**' test] ++ |'**' test) ++argument: test [comp_for] | test '=' test # Really [keyword '='] test ++ ++comp_iter: comp_for | comp_if ++comp_for: 'for' exprlist 'in' testlist_safe [comp_iter] ++comp_if: 'if' old_test [comp_iter] ++ ++testlist1: test (',' test)* ++ ++# not used in grammar, but may appear in "node" passed from Parser to Compiler ++encoding_decl: NAME ++ ++yield_expr: 'yield' [testlist] +diff -r 531f2e948299 refactor/PatternGrammar.txt +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/PatternGrammar.txt Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,28 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++# A grammar to describe tree matching patterns. ++# Not shown here: ++# - 'TOKEN' stands for any token (leaf node) ++# - 'any' stands for any node (leaf or interior) ++# With 'any' we can still specify the sub-structure. ++ ++# The start symbol is 'Matcher'. ++ ++Matcher: Alternatives ENDMARKER ++ ++Alternatives: Alternative ('|' Alternative)* ++ ++Alternative: (Unit | NegatedUnit)+ ++ ++Unit: [NAME '='] ( STRING [Repeater] ++ | NAME [Details] [Repeater] ++ | '(' Alternatives ')' [Repeater] ++ | '[' Alternatives ']' ++ ) ++ ++NegatedUnit: 'not' (STRING | NAME [Details] | '(' Alternatives ')') ++ ++Repeater: '*' | '+' | '{' NUMBER [',' NUMBER] '}' ++ ++Details: '<' Alternatives '>' +diff -r 531f2e948299 refactor/__init__.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/__init__.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,8 @@ ++from . import fixer_base ++from . import fixer_util ++from . import main ++from . import patcomp ++from . import pgen2 ++from . import pygram ++from . import pytree ++from . import refactor +diff -r 531f2e948299 refactor/fixer_base.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixer_base.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,178 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Base class for fixers (optional, but recommended).""" ++ ++# Python imports ++import logging ++import itertools ++ ++# Local imports ++from .patcomp import PatternCompiler ++from . import pygram ++from .fixer_util import does_tree_import ++ ++class BaseFix(object): ++ ++ """Optional base class for fixers. ++ ++ The subclass name must be FixFooBar where FooBar is the result of ++ removing underscores and capitalizing the words of the fix name. ++ For example, the class name for a fixer named 'has_key' should be ++ FixHasKey. ++ """ ++ ++ PATTERN = None # Most subclasses should override with a string literal ++ pattern = None # Compiled pattern, set by compile_pattern() ++ options = None # Options object passed to initializer ++ filename = None # The filename (set by set_filename) ++ logger = None # A logger (set by set_filename) ++ numbers = itertools.count(1) # For new_name() ++ used_names = set() # A set of all used NAMEs ++ order = "post" # Does the fixer prefer pre- or post-order traversal ++ explicit = False # Is this ignored by refactor.py -f all? ++ run_order = 5 # Fixers will be sorted by run order before execution ++ # Lower numbers will be run first. ++ ++ # Shortcut for access to Python grammar symbols ++ syms = pygram.python_symbols ++ ++ def __init__(self, options, log): ++ """Initializer. Subclass may override. ++ ++ Args: ++ options: an dict containing the options passed to RefactoringTool ++ that could be used to customize the fixer through the command line. ++ log: a list to append warnings and other messages to. ++ """ ++ self.options = options ++ self.log = log ++ self.compile_pattern() ++ ++ def compile_pattern(self): ++ """Compiles self.PATTERN into self.pattern. ++ ++ Subclass may override if it doesn't want to use ++ self.{pattern,PATTERN} in .match(). ++ """ ++ if self.PATTERN is not None: ++ self.pattern = PatternCompiler().compile_pattern(self.PATTERN) ++ ++ def set_filename(self, filename): ++ """Set the filename, and a logger derived from it. ++ ++ The main refactoring tool should call this. ++ """ ++ self.filename = filename ++ self.logger = logging.getLogger(filename) ++ ++ def match(self, node): ++ """Returns match for a given parse tree node. ++ ++ Should return a true or false object (not necessarily a bool). ++ It may return a non-empty dict of matching sub-nodes as ++ returned by a matching pattern. ++ ++ Subclass may override. ++ """ ++ results = {"node": node} ++ return self.pattern.match(node, results) and results ++ ++ def transform(self, node, results): ++ """Returns the transformation for a given parse tree node. ++ ++ Args: ++ node: the root of the parse tree that matched the fixer. ++ results: a dict mapping symbolic names to part of the match. ++ ++ Returns: ++ None, or a node that is a modified copy of the ++ argument node. The node argument may also be modified in-place to ++ effect the same change. ++ ++ Subclass *must* override. ++ """ ++ raise NotImplementedError() ++ ++ def new_name(self, template="xxx_todo_changeme"): ++ """Return a string suitable for use as an identifier ++ ++ The new name is guaranteed not to conflict with other identifiers. ++ """ ++ name = template ++ while name in self.used_names: ++ name = template + str(self.numbers.next()) ++ self.used_names.add(name) ++ return name ++ ++ def log_message(self, message): ++ if self.first_log: ++ self.first_log = False ++ self.log.append("### In file %s ###" % self.filename) ++ self.log.append(message) ++ ++ def cannot_convert(self, node, reason=None): ++ """Warn the user that a given chunk of code is not valid Python 3, ++ but that it cannot be converted automatically. ++ ++ First argument is the top-level node for the code in question. ++ Optional second argument is why it can't be converted. ++ """ ++ lineno = node.get_lineno() ++ for_output = node.clone() ++ for_output.set_prefix("") ++ msg = "Line %d: could not convert: %s" ++ self.log_message(msg % (lineno, for_output)) ++ if reason: ++ self.log_message(reason) ++ ++ def warning(self, node, reason): ++ """Used for warning the user about possible uncertainty in the ++ translation. ++ ++ First argument is the top-level node for the code in question. ++ Optional second argument is why it can't be converted. ++ """ ++ lineno = node.get_lineno() ++ self.log_message("Line %d: %s" % (lineno, reason)) ++ ++ def start_tree(self, tree, filename): ++ """Some fixers need to maintain tree-wide state. ++ This method is called once, at the start of tree fix-up. ++ ++ tree - the root node of the tree to be processed. ++ filename - the name of the file the tree came from. ++ """ ++ self.used_names = tree.used_names ++ self.set_filename(filename) ++ self.numbers = itertools.count(1) ++ self.first_log = True ++ ++ def finish_tree(self, tree, filename): ++ """Some fixers need to maintain tree-wide state. ++ This method is called once, at the conclusion of tree fix-up. ++ ++ tree - the root node of the tree to be processed. ++ filename - the name of the file the tree came from. ++ """ ++ pass ++ ++ ++class ConditionalFix(BaseFix): ++ """ Base class for fixers which not execute if an import is found. """ ++ ++ # This is the name of the import which, if found, will cause the test to be skipped ++ skip_on = None ++ ++ def start_tree(self, *args): ++ super(ConditionalFix, self).start_tree(*args) ++ self._should_skip = None ++ ++ def should_skip(self, node): ++ if self._should_skip is not None: ++ return self._should_skip ++ pkg = self.skip_on.split(".") ++ name = pkg[-1] ++ pkg = ".".join(pkg[:-1]) ++ self._should_skip = does_tree_import(pkg, name, node) ++ return self._should_skip +diff -r 531f2e948299 refactor/fixer_util.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixer_util.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,425 @@ ++"""Utility functions, node construction macros, etc.""" ++# Author: Collin Winter ++ ++# Local imports ++from .pgen2 import token ++from .pytree import Leaf, Node ++from .pygram import python_symbols as syms ++from . import patcomp ++ ++ ++########################################################### ++### Common node-construction "macros" ++########################################################### ++ ++def KeywordArg(keyword, value): ++ return Node(syms.argument, ++ [keyword, Leaf(token.EQUAL, '='), value]) ++ ++def LParen(): ++ return Leaf(token.LPAR, "(") ++ ++def RParen(): ++ return Leaf(token.RPAR, ")") ++ ++def Assign(target, source): ++ """Build an assignment statement""" ++ if not isinstance(target, list): ++ target = [target] ++ if not isinstance(source, list): ++ source.set_prefix(" ") ++ source = [source] ++ ++ return Node(syms.atom, ++ target + [Leaf(token.EQUAL, "=", prefix=" ")] + source) ++ ++def Name(name, prefix=None): ++ """Return a NAME leaf""" ++ return Leaf(token.NAME, name, prefix=prefix) ++ ++def Attr(obj, attr): ++ """A node tuple for obj.attr""" ++ return [obj, Node(syms.trailer, [Dot(), attr])] ++ ++def Comma(): ++ """A comma leaf""" ++ return Leaf(token.COMMA, ",") ++ ++def Dot(): ++ """A period (.) leaf""" ++ return Leaf(token.DOT, ".") ++ ++def ArgList(args, lparen=LParen(), rparen=RParen()): ++ """A parenthesised argument list, used by Call()""" ++ node = Node(syms.trailer, [lparen.clone(), rparen.clone()]) ++ if args: ++ node.insert_child(1, Node(syms.arglist, args)) ++ return node ++ ++def Call(func_name, args=None, prefix=None): ++ """A function call""" ++ node = Node(syms.power, [func_name, ArgList(args)]) ++ if prefix is not None: ++ node.set_prefix(prefix) ++ return node ++ ++def Newline(): ++ """A newline literal""" ++ return Leaf(token.NEWLINE, "\n") ++ ++def BlankLine(): ++ """A blank line""" ++ return Leaf(token.NEWLINE, "") ++ ++def Number(n, prefix=None): ++ return Leaf(token.NUMBER, n, prefix=prefix) ++ ++def Subscript(index_node): ++ """A numeric or string subscript""" ++ return Node(syms.trailer, [Leaf(token.LBRACE, '['), ++ index_node, ++ Leaf(token.RBRACE, ']')]) ++ ++def String(string, prefix=None): ++ """A string leaf""" ++ return Leaf(token.STRING, string, prefix=prefix) ++ ++def ListComp(xp, fp, it, test=None): ++ """A list comprehension of the form [xp for fp in it if test]. ++ ++ If test is None, the "if test" part is omitted. ++ """ ++ xp.set_prefix("") ++ fp.set_prefix(" ") ++ it.set_prefix(" ") ++ for_leaf = Leaf(token.NAME, "for") ++ for_leaf.set_prefix(" ") ++ in_leaf = Leaf(token.NAME, "in") ++ in_leaf.set_prefix(" ") ++ inner_args = [for_leaf, fp, in_leaf, it] ++ if test: ++ test.set_prefix(" ") ++ if_leaf = Leaf(token.NAME, "if") ++ if_leaf.set_prefix(" ") ++ inner_args.append(Node(syms.comp_if, [if_leaf, test])) ++ inner = Node(syms.listmaker, [xp, Node(syms.comp_for, inner_args)]) ++ return Node(syms.atom, ++ [Leaf(token.LBRACE, "["), ++ inner, ++ Leaf(token.RBRACE, "]")]) ++ ++def FromImport(package_name, name_leafs): ++ """ Return an import statement in the form: ++ from package import name_leafs""" ++ # XXX: May not handle dotted imports properly (eg, package_name='foo.bar') ++ #assert package_name == '.' or '.' not in package_name, "FromImport has "\ ++ # "not been tested with dotted package names -- use at your own "\ ++ # "peril!" ++ ++ for leaf in name_leafs: ++ # Pull the leaves out of their old tree ++ leaf.remove() ++ ++ children = [Leaf(token.NAME, 'from'), ++ Leaf(token.NAME, package_name, prefix=" "), ++ Leaf(token.NAME, 'import', prefix=" "), ++ Node(syms.import_as_names, name_leafs)] ++ imp = Node(syms.import_from, children) ++ return imp ++ ++ ++########################################################### ++### Determine whether a node represents a given literal ++########################################################### ++ ++def is_tuple(node): ++ """Does the node represent a tuple literal?""" ++ if isinstance(node, Node) and node.children == [LParen(), RParen()]: ++ return True ++ return (isinstance(node, Node) ++ and len(node.children) == 3 ++ and isinstance(node.children[0], Leaf) ++ and isinstance(node.children[1], Node) ++ and isinstance(node.children[2], Leaf) ++ and node.children[0].value == "(" ++ and node.children[2].value == ")") ++ ++def is_list(node): ++ """Does the node represent a list literal?""" ++ return (isinstance(node, Node) ++ and len(node.children) > 1 ++ and isinstance(node.children[0], Leaf) ++ and isinstance(node.children[-1], Leaf) ++ and node.children[0].value == "[" ++ and node.children[-1].value == "]") ++ ++ ++########################################################### ++### Misc ++########################################################### ++ ++def parenthesize(node): ++ return Node(syms.atom, [LParen(), node, RParen()]) ++ ++ ++consuming_calls = set(["sorted", "list", "set", "any", "all", "tuple", "sum", ++ "min", "max"]) ++ ++def attr_chain(obj, attr): ++ """Follow an attribute chain. ++ ++ If you have a chain of objects where a.foo -> b, b.foo-> c, etc, ++ use this to iterate over all objects in the chain. Iteration is ++ terminated by getattr(x, attr) is None. ++ ++ Args: ++ obj: the starting object ++ attr: the name of the chaining attribute ++ ++ Yields: ++ Each successive object in the chain. ++ """ ++ next = getattr(obj, attr) ++ while next: ++ yield next ++ next = getattr(next, attr) ++ ++p0 = """for_stmt< 'for' any 'in' node=any ':' any* > ++ | comp_for< 'for' any 'in' node=any any* > ++ """ ++p1 = """ ++power< ++ ( 'iter' | 'list' | 'tuple' | 'sorted' | 'set' | 'sum' | ++ 'any' | 'all' | (any* trailer< '.' 'join' >) ) ++ trailer< '(' node=any ')' > ++ any* ++> ++""" ++p2 = """ ++power< ++ 'sorted' ++ trailer< '(' arglist ')' > ++ any* ++> ++""" ++pats_built = False ++def in_special_context(node): ++ """ Returns true if node is in an environment where all that is required ++ of it is being itterable (ie, it doesn't matter if it returns a list ++ or an itterator). ++ See test_map_nochange in test_fixers.py for some examples and tests. ++ """ ++ global p0, p1, p2, pats_built ++ if not pats_built: ++ p1 = patcomp.compile_pattern(p1) ++ p0 = patcomp.compile_pattern(p0) ++ p2 = patcomp.compile_pattern(p2) ++ pats_built = True ++ patterns = [p0, p1, p2] ++ for pattern, parent in zip(patterns, attr_chain(node, "parent")): ++ results = {} ++ if pattern.match(parent, results) and results["node"] is node: ++ return True ++ return False ++ ++def is_probably_builtin(node): ++ """ ++ Check that something isn't an attribute or function name etc. ++ """ ++ prev = node.prev_sibling ++ if prev is not None and prev.type == token.DOT: ++ # Attribute lookup. ++ return False ++ parent = node.parent ++ if parent.type in (syms.funcdef, syms.classdef): ++ return False ++ if parent.type == syms.expr_stmt and parent.children[0] is node: ++ # Assignment. ++ return False ++ if parent.type == syms.parameters or \ ++ (parent.type == syms.typedargslist and ( ++ (prev is not None and prev.type == token.COMMA) or ++ parent.children[0] is node ++ )): ++ # The name of an argument. ++ return False ++ return True ++ ++########################################################### ++### The following functions are to find bindings in a suite ++########################################################### ++ ++def make_suite(node): ++ if node.type == syms.suite: ++ return node ++ node = node.clone() ++ parent, node.parent = node.parent, None ++ suite = Node(syms.suite, [node]) ++ suite.parent = parent ++ return suite ++ ++def find_root(node): ++ """Find the top level namespace.""" ++ # Scamper up to the top level namespace ++ while node.type != syms.file_input: ++ assert node.parent, "Tree is insane! root found before "\ ++ "file_input node was found." ++ node = node.parent ++ return node ++ ++def does_tree_import(package, name, node): ++ """ Returns true if name is imported from package at the ++ top level of the tree which node belongs to. ++ To cover the case of an import like 'import foo', use ++ None for the package and 'foo' for the name. """ ++ binding = find_binding(name, find_root(node), package) ++ return bool(binding) ++ ++def is_import(node): ++ """Returns true if the node is an import statement.""" ++ return node.type in (syms.import_name, syms.import_from) ++ ++def touch_import(package, name, node): ++ """ Works like `does_tree_import` but adds an import statement ++ if it was not imported. """ ++ def is_import_stmt(node): ++ return node.type == syms.simple_stmt and node.children and \ ++ is_import(node.children[0]) ++ ++ root = find_root(node) ++ ++ if does_tree_import(package, name, root): ++ return ++ ++ add_newline_before = False ++ ++ # figure out where to insert the new import. First try to find ++ # the first import and then skip to the last one. ++ insert_pos = offset = 0 ++ for idx, node in enumerate(root.children): ++ if not is_import_stmt(node): ++ continue ++ for offset, node2 in enumerate(root.children[idx:]): ++ if not is_import_stmt(node2): ++ break ++ insert_pos = idx + offset ++ break ++ ++ # if there are no imports where we can insert, find the docstring. ++ # if that also fails, we stick to the beginning of the file ++ if insert_pos == 0: ++ for idx, node in enumerate(root.children): ++ if node.type == syms.simple_stmt and node.children and \ ++ node.children[0].type == token.STRING: ++ insert_pos = idx + 1 ++ add_newline_before ++ break ++ ++ if package is None: ++ import_ = Node(syms.import_name, [ ++ Leaf(token.NAME, 'import'), ++ Leaf(token.NAME, name, prefix=' ') ++ ]) ++ else: ++ import_ = FromImport(package, [Leaf(token.NAME, name, prefix=' ')]) ++ ++ children = [import_, Newline()] ++ if add_newline_before: ++ children.insert(0, Newline()) ++ root.insert_child(insert_pos, Node(syms.simple_stmt, children)) ++ ++ ++_def_syms = set([syms.classdef, syms.funcdef]) ++def find_binding(name, node, package=None): ++ """ Returns the node which binds variable name, otherwise None. ++ If optional argument package is supplied, only imports will ++ be returned. ++ See test cases for examples.""" ++ for child in node.children: ++ ret = None ++ if child.type == syms.for_stmt: ++ if _find(name, child.children[1]): ++ return child ++ n = find_binding(name, make_suite(child.children[-1]), package) ++ if n: ret = n ++ elif child.type in (syms.if_stmt, syms.while_stmt): ++ n = find_binding(name, make_suite(child.children[-1]), package) ++ if n: ret = n ++ elif child.type == syms.try_stmt: ++ n = find_binding(name, make_suite(child.children[2]), package) ++ if n: ++ ret = n ++ else: ++ for i, kid in enumerate(child.children[3:]): ++ if kid.type == token.COLON and kid.value == ":": ++ # i+3 is the colon, i+4 is the suite ++ n = find_binding(name, make_suite(child.children[i+4]), package) ++ if n: ret = n ++ elif child.type in _def_syms and child.children[1].value == name: ++ ret = child ++ elif _is_import_binding(child, name, package): ++ ret = child ++ elif child.type == syms.simple_stmt: ++ ret = find_binding(name, child, package) ++ elif child.type == syms.expr_stmt: ++ if _find(name, child.children[0]): ++ ret = child ++ ++ if ret: ++ if not package: ++ return ret ++ if is_import(ret): ++ return ret ++ return None ++ ++_block_syms = set([syms.funcdef, syms.classdef, syms.trailer]) ++def _find(name, node): ++ nodes = [node] ++ while nodes: ++ node = nodes.pop() ++ if node.type > 256 and node.type not in _block_syms: ++ nodes.extend(node.children) ++ elif node.type == token.NAME and node.value == name: ++ return node ++ return None ++ ++def _is_import_binding(node, name, package=None): ++ """ Will reuturn node if node will import name, or node ++ will import * from package. None is returned otherwise. ++ See test cases for examples. """ ++ ++ if node.type == syms.import_name and not package: ++ imp = node.children[1] ++ if imp.type == syms.dotted_as_names: ++ for child in imp.children: ++ if child.type == syms.dotted_as_name: ++ if child.children[2].value == name: ++ return node ++ elif child.type == token.NAME and child.value == name: ++ return node ++ elif imp.type == syms.dotted_as_name: ++ last = imp.children[-1] ++ if last.type == token.NAME and last.value == name: ++ return node ++ elif imp.type == token.NAME and imp.value == name: ++ return node ++ elif node.type == syms.import_from: ++ # unicode(...) is used to make life easier here, because ++ # from a.b import parses to ['import', ['a', '.', 'b'], ...] ++ if package and unicode(node.children[1]).strip() != package: ++ return None ++ n = node.children[3] ++ if package and _find('as', n): ++ # See test_from_import_as for explanation ++ return None ++ elif n.type == syms.import_as_names and _find(name, n): ++ return node ++ elif n.type == syms.import_as_name: ++ child = n.children[2] ++ if child.type == token.NAME and child.value == name: ++ return node ++ elif n.type == token.NAME and n.value == name: ++ return node ++ elif package and n.type == token.STAR: ++ return node ++ return None +diff -r 531f2e948299 refactor/fixes/.svn/all-wcprops +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/all-wcprops Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,305 @@ ++K 25 ++svn:wc:ra_dav:version-url ++V 57 ++/projects/!svn/ver/69679/sandbox/trunk/2to3/lib2to3/fixes ++END ++fix_dict.py ++K 25 ++svn:wc:ra_dav:version-url ++V 69 ++/projects/!svn/ver/67389/sandbox/trunk/2to3/lib2to3/fixes/fix_dict.py ++END ++fix_has_key.py ++K 25 ++svn:wc:ra_dav:version-url ++V 72 ++/projects/!svn/ver/67769/sandbox/trunk/2to3/lib2to3/fixes/fix_has_key.py ++END ++fix_exec.py ++K 25 ++svn:wc:ra_dav:version-url ++V 69 ++/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_exec.py ++END ++fix_idioms.py ++K 25 ++svn:wc:ra_dav:version-url ++V 71 ++/projects/!svn/ver/67433/sandbox/trunk/2to3/lib2to3/fixes/fix_idioms.py ++END ++__init__.py ++K 25 ++svn:wc:ra_dav:version-url ++V 69 ++/projects/!svn/ver/61428/sandbox/trunk/2to3/lib2to3/fixes/__init__.py ++END ++fix_urllib.py ++K 25 ++svn:wc:ra_dav:version-url ++V 71 ++/projects/!svn/ver/68368/sandbox/trunk/2to3/lib2to3/fixes/fix_urllib.py ++END ++fix_nonzero.py ++K 25 ++svn:wc:ra_dav:version-url ++V 72 ++/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_nonzero.py ++END ++fix_print.py ++K 25 ++svn:wc:ra_dav:version-url ++V 70 ++/projects/!svn/ver/66418/sandbox/trunk/2to3/lib2to3/fixes/fix_print.py ++END ++fix_imports.py ++K 25 ++svn:wc:ra_dav:version-url ++V 72 ++/projects/!svn/ver/69054/sandbox/trunk/2to3/lib2to3/fixes/fix_imports.py ++END ++fix_numliterals.py ++K 25 ++svn:wc:ra_dav:version-url ++V 76 ++/projects/!svn/ver/67389/sandbox/trunk/2to3/lib2to3/fixes/fix_numliterals.py ++END ++fix_input.py ++K 25 ++svn:wc:ra_dav:version-url ++V 70 ++/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_input.py ++END ++fix_itertools_imports.py ++K 25 ++svn:wc:ra_dav:version-url ++V 82 ++/projects/!svn/ver/69673/sandbox/trunk/2to3/lib2to3/fixes/fix_itertools_imports.py ++END ++fix_getcwdu.py ++K 25 ++svn:wc:ra_dav:version-url ++V 72 ++/projects/!svn/ver/66782/sandbox/trunk/2to3/lib2to3/fixes/fix_getcwdu.py ++END ++fix_zip.py ++K 25 ++svn:wc:ra_dav:version-url ++V 68 ++/projects/!svn/ver/67433/sandbox/trunk/2to3/lib2to3/fixes/fix_zip.py ++END ++fix_raise.py ++K 25 ++svn:wc:ra_dav:version-url ++V 70 ++/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_raise.py ++END ++fix_throw.py ++K 25 ++svn:wc:ra_dav:version-url ++V 70 ++/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_throw.py ++END ++fix_types.py ++K 25 ++svn:wc:ra_dav:version-url ++V 70 ++/projects/!svn/ver/67433/sandbox/trunk/2to3/lib2to3/fixes/fix_types.py ++END ++fix_paren.py ++K 25 ++svn:wc:ra_dav:version-url ++V 70 ++/projects/!svn/ver/65981/sandbox/trunk/2to3/lib2to3/fixes/fix_paren.py ++END ++fix_ws_comma.py ++K 25 ++svn:wc:ra_dav:version-url ++V 73 ++/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_ws_comma.py ++END ++fix_reduce.py ++K 25 ++svn:wc:ra_dav:version-url ++V 71 ++/projects/!svn/ver/67657/sandbox/trunk/2to3/lib2to3/fixes/fix_reduce.py ++END ++fix_raw_input.py ++K 25 ++svn:wc:ra_dav:version-url ++V 74 ++/projects/!svn/ver/65887/sandbox/trunk/2to3/lib2to3/fixes/fix_raw_input.py ++END ++fix_repr.py ++K 25 ++svn:wc:ra_dav:version-url ++V 69 ++/projects/!svn/ver/67769/sandbox/trunk/2to3/lib2to3/fixes/fix_repr.py ++END ++fix_buffer.py ++K 25 ++svn:wc:ra_dav:version-url ++V 71 ++/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_buffer.py ++END ++fix_funcattrs.py ++K 25 ++svn:wc:ra_dav:version-url ++V 74 ++/projects/!svn/ver/67433/sandbox/trunk/2to3/lib2to3/fixes/fix_funcattrs.py ++END ++fix_import.py ++K 25 ++svn:wc:ra_dav:version-url ++V 71 ++/projects/!svn/ver/67928/sandbox/trunk/2to3/lib2to3/fixes/fix_import.py ++END ++fix_standarderror.py ++K 25 ++svn:wc:ra_dav:version-url ++V 78 ++/projects/!svn/ver/67433/sandbox/trunk/2to3/lib2to3/fixes/fix_standarderror.py ++END ++fix_map.py ++K 25 ++svn:wc:ra_dav:version-url ++V 68 ++/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_map.py ++END ++fix_next.py ++K 25 ++svn:wc:ra_dav:version-url ++V 69 ++/projects/!svn/ver/67389/sandbox/trunk/2to3/lib2to3/fixes/fix_next.py ++END ++fix_itertools.py ++K 25 ++svn:wc:ra_dav:version-url ++V 74 ++/projects/!svn/ver/67433/sandbox/trunk/2to3/lib2to3/fixes/fix_itertools.py ++END ++fix_execfile.py ++K 25 ++svn:wc:ra_dav:version-url ++V 73 ++/projects/!svn/ver/67901/sandbox/trunk/2to3/lib2to3/fixes/fix_execfile.py ++END ++fix_xrange.py ++K 25 ++svn:wc:ra_dav:version-url ++V 71 ++/projects/!svn/ver/67705/sandbox/trunk/2to3/lib2to3/fixes/fix_xrange.py ++END ++fix_apply.py ++K 25 ++svn:wc:ra_dav:version-url ++V 70 ++/projects/!svn/ver/67769/sandbox/trunk/2to3/lib2to3/fixes/fix_apply.py ++END ++fix_filter.py ++K 25 ++svn:wc:ra_dav:version-url ++V 71 ++/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_filter.py ++END ++fix_unicode.py ++K 25 ++svn:wc:ra_dav:version-url ++V 72 ++/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_unicode.py ++END ++fix_except.py ++K 25 ++svn:wc:ra_dav:version-url ++V 71 ++/projects/!svn/ver/68694/sandbox/trunk/2to3/lib2to3/fixes/fix_except.py ++END ++fix_renames.py ++K 25 ++svn:wc:ra_dav:version-url ++V 72 ++/projects/!svn/ver/67389/sandbox/trunk/2to3/lib2to3/fixes/fix_renames.py ++END ++fix_tuple_params.py ++K 25 ++svn:wc:ra_dav:version-url ++V 77 ++/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_tuple_params.py ++END ++fix_methodattrs.py ++K 25 ++svn:wc:ra_dav:version-url ++V 76 ++/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_methodattrs.py ++END ++fix_xreadlines.py ++K 25 ++svn:wc:ra_dav:version-url ++V 75 ++/projects/!svn/ver/67433/sandbox/trunk/2to3/lib2to3/fixes/fix_xreadlines.py ++END ++fix_long.py ++K 25 ++svn:wc:ra_dav:version-url ++V 69 ++/projects/!svn/ver/68110/sandbox/trunk/2to3/lib2to3/fixes/fix_long.py ++END ++fix_intern.py ++K 25 ++svn:wc:ra_dav:version-url ++V 71 ++/projects/!svn/ver/67657/sandbox/trunk/2to3/lib2to3/fixes/fix_intern.py ++END ++fix_callable.py ++K 25 ++svn:wc:ra_dav:version-url ++V 73 ++/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_callable.py ++END ++fix_isinstance.py ++K 25 ++svn:wc:ra_dav:version-url ++V 75 ++/projects/!svn/ver/67767/sandbox/trunk/2to3/lib2to3/fixes/fix_isinstance.py ++END ++fix_basestring.py ++K 25 ++svn:wc:ra_dav:version-url ++V 75 ++/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_basestring.py ++END ++fix_ne.py ++K 25 ++svn:wc:ra_dav:version-url ++V 67 ++/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_ne.py ++END ++fix_set_literal.py ++K 25 ++svn:wc:ra_dav:version-url ++V 76 ++/projects/!svn/ver/69679/sandbox/trunk/2to3/lib2to3/fixes/fix_set_literal.py ++END ++fix_future.py ++K 25 ++svn:wc:ra_dav:version-url ++V 71 ++/projects/!svn/ver/63880/sandbox/trunk/2to3/lib2to3/fixes/fix_future.py ++END ++fix_metaclass.py ++K 25 ++svn:wc:ra_dav:version-url ++V 74 ++/projects/!svn/ver/67371/sandbox/trunk/2to3/lib2to3/fixes/fix_metaclass.py ++END ++fix_sys_exc.py ++K 25 ++svn:wc:ra_dav:version-url ++V 72 ++/projects/!svn/ver/65968/sandbox/trunk/2to3/lib2to3/fixes/fix_sys_exc.py ++END ++fix_imports2.py ++K 25 ++svn:wc:ra_dav:version-url ++V 73 ++/projects/!svn/ver/68422/sandbox/trunk/2to3/lib2to3/fixes/fix_imports2.py ++END +diff -r 531f2e948299 refactor/fixes/.svn/dir-prop-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/dir-prop-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,10 @@ ++K 10 ++svn:ignore ++V 25 ++*.pyc ++*.pyo ++*.pickle ++@* ++ ++ ++END +diff -r 531f2e948299 refactor/fixes/.svn/entries +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/entries Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,1728 @@ ++9 ++ ++dir ++70822 ++http://svn.python.org/projects/sandbox/trunk/2to3/lib2to3/fixes ++http://svn.python.org/projects ++ ++ ++ ++2009-02-16T17:36:06.789054Z ++69679 ++benjamin.peterson ++has-props ++ ++svn:special svn:externals svn:needs-lock ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++6015fed2-1504-0410-9fe1-9d1591cc4771 ++ ++fix_dict.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++d12677f15a5a34c7754e90cb06bc153e ++2008-11-25T23:13:17.968453Z ++67389 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++3588 ++ ++fix_has_key.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++1b88e2b6b4c60df9b85a168a07e13fa7 ++2008-12-14T20:59:10.846867Z ++67769 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++3209 ++ ++fix_exec.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++679db75847dfd56367a8cd2b4286949c ++2008-06-01T23:09:38.597843Z ++63880 ++collin.winter ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++985 ++ ++fix_idioms.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++0281b19c721594c6eb341c83270d37bd ++2008-11-28T23:18:48.744865Z ++67433 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++3939 ++ ++__init__.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++97781d2954bbc2eebdc963de519fe2de ++2006-12-12T14:56:29.604692Z ++53006 ++guido.van.rossum ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++47 ++ ++fix_urllib.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++c883d34902a6e74c08f4370a978e5b86 ++2009-01-06T23:56:10.682943Z ++68368 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++7484 ++ ++fix_nonzero.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++6f8983345b023d63ddce248a93c5db83 ++2008-06-01T23:09:38.597843Z ++63880 ++collin.winter ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++578 ++ ++fix_print.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++478786e57412307d598aee1a20595102 ++2008-09-12T23:49:48.354778Z ++66418 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++2957 ++ ++fix_imports.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++fa0f30cff73ee261c93c85286007c761 ++2009-01-28T16:01:54.183761Z ++69054 ++guilherme.polo ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++5692 ++ ++fix_numliterals.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++7e04fa79f3ff3ff475ec1716021b8489 ++2008-11-25T23:13:17.968453Z ++67389 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++789 ++ ++fix_input.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++3a704e4f30c9f72c236274118f093034 ++2008-06-01T23:09:38.597843Z ++63880 ++collin.winter ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++692 ++ ++fix_itertools_imports.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++05420b3d189c8130eca6bf051bd31a17 ++2009-02-16T15:38:22.416590Z ++69673 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++1837 ++ ++fix_getcwdu.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++1bf89e0a81cc997173d5d63078f8ea5a ++2008-10-03T22:51:36.115136Z ++66782 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++432 ++ ++fix_zip.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++8e61d2105f3122181e793e7c9b4caf31 ++2008-11-28T23:18:48.744865Z ++67433 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++889 ++ ++fix_throw.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++52c18fcf966a4c7f44940e331784f51c ++2008-06-01T23:09:38.597843Z ++63880 ++collin.winter ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++1564 ++ ++fix_raise.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++7f69130d4008f2b870fbc5d88ed726de ++2008-06-01T23:09:38.597843Z ++63880 ++collin.winter ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++2587 ++ ++fix_types.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++08728aeba77665139ce3f967cb24c2f1 ++2008-11-28T23:18:48.744865Z ++67433 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++1779 ++ ++fix_paren.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++e2b3bd30551e285f3bc45eed6a797014 ++2008-08-22T20:41:30.636639Z ++65981 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++1213 ++ ++fix_ws_comma.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++8e92e7f56434c9b2263874296578ea53 ++2008-06-01T23:09:38.597843Z ++63880 ++collin.winter ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++1108 ++ ++fix_reduce.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++2fee5cc1f796c98a749dc789199da016 ++2008-12-08T00:29:35.627027Z ++67657 ++armin.ronacher ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++816 ++ ++fix_raw_input.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++18666e7c36b850f0b6d5666504bec0ae ++2008-08-19T22:45:04.505207Z ++65887 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++435 ++ ++fix_repr.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++badd6b1054395732bd64df829d16cf96 ++2008-12-14T20:59:10.846867Z ++67769 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++594 ++ ++fix_buffer.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++d6f8cc141ad7ab3f197f1638b9e3e1aa ++2008-06-01T23:09:38.597843Z ++63880 ++collin.winter ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++566 ++ ++fix_funcattrs.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++7a7b9d2abe6fbecfdf2e5c0095978f0b ++2008-11-28T23:18:48.744865Z ++67433 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++624 ++ ++fix_import.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++9973617c9e868b2b9afb0a609ef30b35 ++2008-12-27T02:49:30.983707Z ++67928 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++2953 ++ ++fix_standarderror.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++f76efc435650b1eba8bf73dbdfdeef3e ++2008-11-28T23:18:48.744865Z ++67433 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++431 ++ ++fix_map.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++0cdf1b348ed0dc9348377ad6ce1aef42 ++2008-06-01T23:09:38.597843Z ++63880 ++collin.winter ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++2537 ++ ++fix_next.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++46917a2b5128a18a5224f6ae5dc021db ++2008-11-25T23:13:17.968453Z ++67389 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++3205 ++ ++fix_itertools.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++d2b48acbc9d415b64f3c71575fbfb9df ++2008-11-28T23:18:48.744865Z ++67433 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++1483 ++ ++fix_execfile.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++f968686ed347fd544fc69fd9cb6073cd ++2008-12-22T20:09:55.444195Z ++67901 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++1974 ++ ++fix_xrange.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++4f054eb9bb8f4d4916f1b33eec5175f9 ++2008-12-11T19:04:08.320821Z ++67705 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++2291 ++ ++fix_apply.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++2a00b679f13c1dca9b45bc23a3b2a695 ++2008-12-14T20:59:10.846867Z ++67769 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++1894 ++ ++fix_filter.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++0879d4b1af4eeb93b1a8baff1fd298c1 ++2008-06-01T23:09:38.597843Z ++63880 ++collin.winter ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++2089 ++ ++fix_unicode.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++05e9e9ae6cbc1c396bc11b19b5dab25a ++2008-06-01T23:09:38.597843Z ++63880 ++collin.winter ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++832 ++ ++fix_except.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++450c9cbb28a5be9d21719abcb33a59f5 ++2009-01-17T23:55:59.992428Z ++68694 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++3251 ++ ++fix_renames.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++52f66737c4206d8cfa77bbb07af4a056 ++2008-11-25T23:13:17.968453Z ++67389 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++2192 ++ ++fix_tuple_params.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++557690cc5399b0ade14c16089df2effb ++2008-06-01T23:09:38.597843Z ++63880 ++collin.winter ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++5405 ++ ++fix_methodattrs.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++6ee0925ec01e9ae632326855ab5cb016 ++2008-06-01T23:09:38.597843Z ++63880 ++collin.winter ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++587 ++ ++fix_xreadlines.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++ade2c0b61ba9f8effa9df543a2fbdc4a ++2008-11-28T23:18:48.744865Z ++67433 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++670 ++ ++fix_long.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++2aaca612bae42bfe84dd0d6139260749 ++2008-12-31T20:13:26.408132Z ++68110 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++538 ++ ++fix_intern.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++00e20c0723e807004c3fd0ae88d26b09 ++2008-12-08T00:29:35.627027Z ++67657 ++armin.ronacher ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++1368 ++ ++fix_callable.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++37990663703ff5ea2fabb3095a9ad189 ++2008-06-01T23:09:38.597843Z ++63880 ++collin.winter ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++952 ++ ++fix_isinstance.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++921a0f20d0a6e47b4b1291d37599bf09 ++2008-12-14T20:28:12.506842Z ++67767 ++benjamin.peterson ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++1594 ++ ++fix_basestring.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++0fe11afa759b94c75323aa2a3188089d ++2008-06-01T23:09:38.597843Z ++63880 ++collin.winter ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++301 ++ ++fix_ne.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++a787f8744fda47bffd7f2b6a9ee4ff38 ++2008-06-01T23:09:38.597843Z ++63880 ++collin.winter ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++590 ++ ++fix_set_literal.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++fc4742a5a8d78f9dd84b1c5f0040003b ++2009-02-16T17:36:06.789054Z ++69679 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++1699 ++ ++fix_future.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++0e2786c94aac6b11a47d8ec46d8b19d6 ++2008-06-01T23:09:38.597843Z ++63880 ++collin.winter ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++527 ++ ++fix_metaclass.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++c608b0bf4a9c0c1028051ffe82d055f4 ++2008-11-24T22:02:00.590445Z ++67371 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++8213 ++ ++fix_sys_exc.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++2b412acd29c54b0101163bb8be2ab5c7 ++2008-08-21T23:45:13.840810Z ++65968 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++1030 ++ ++fix_imports2.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:37.000000Z ++15274809df396bec14aeafccd2ab9875 ++2009-01-09T02:01:03.956074Z ++68422 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++289 ++ +diff -r 531f2e948299 refactor/fixes/.svn/format +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/format Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,1 @@ ++9 +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/__init__.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/__init__.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_apply.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_apply.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_basestring.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_basestring.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_buffer.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_buffer.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_callable.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_callable.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_dict.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_dict.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_except.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_except.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_exec.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_exec.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_execfile.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_execfile.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,5 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_filter.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_filter.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_funcattrs.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_funcattrs.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,5 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_future.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_future.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 13 ++'Id Revision' ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_getcwdu.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_getcwdu.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_has_key.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_has_key.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_idioms.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_idioms.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,5 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_import.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_import.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,5 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_imports.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_imports.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,5 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_imports2.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_imports2.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,5 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_input.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_input.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_intern.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_intern.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,5 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_itertools.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_itertools.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,5 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_itertools_imports.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_itertools_imports.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,5 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_long.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_long.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_map.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_map.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_metaclass.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_metaclass.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_methodattrs.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_methodattrs.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 13 ++'Id Revision' ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_ne.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_ne.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_next.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_next.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_nonzero.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_nonzero.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_numliterals.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_numliterals.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,5 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_paren.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_paren.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_print.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_print.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_raise.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_raise.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_raw_input.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_raw_input.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_renames.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_renames.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 13 ++'Id Revision' ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_repr.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_repr.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_set_literal.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_set_literal.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_standarderror.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_standarderror.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,5 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_sys_exc.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_sys_exc.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_throw.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_throw.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_tuple_params.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_tuple_params.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_types.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_types.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,5 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_unicode.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_unicode.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_urllib.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_urllib.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,5 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_ws_comma.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_ws_comma.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_xrange.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_xrange.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_xreadlines.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_xreadlines.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,5 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++END +diff -r 531f2e948299 refactor/fixes/.svn/prop-base/fix_zip.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/prop-base/fix_zip.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,5 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++END +diff -r 531f2e948299 refactor/fixes/.svn/text-base/__init__.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/__init__.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,1 @@ ++# Dummy file to make this directory a package. +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_apply.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_apply.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,58 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for apply(). ++ ++This converts apply(func, v, k) into (func)(*v, **k).""" ++ ++# Local imports ++from .. import pytree ++from ..pgen2 import token ++from .. import fixer_base ++from ..fixer_util import Call, Comma, parenthesize ++ ++class FixApply(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ power< 'apply' ++ trailer< ++ '(' ++ arglist< ++ (not argument ++ ')' ++ > ++ > ++ """ ++ ++ def transform(self, node, results): ++ syms = self.syms ++ assert results ++ func = results["func"] ++ args = results["args"] ++ kwds = results.get("kwds") ++ prefix = node.get_prefix() ++ func = func.clone() ++ if (func.type not in (token.NAME, syms.atom) and ++ (func.type != syms.power or ++ func.children[-2].type == token.DOUBLESTAR)): ++ # Need to parenthesize ++ func = parenthesize(func) ++ func.set_prefix("") ++ args = args.clone() ++ args.set_prefix("") ++ if kwds is not None: ++ kwds = kwds.clone() ++ kwds.set_prefix("") ++ l_newargs = [pytree.Leaf(token.STAR, "*"), args] ++ if kwds is not None: ++ l_newargs.extend([Comma(), ++ pytree.Leaf(token.DOUBLESTAR, "**"), ++ kwds]) ++ l_newargs[-2].set_prefix(" ") # that's the ** token ++ # XXX Sometimes we could be cleverer, e.g. apply(f, (x, y) + t) ++ # can be translated into f(x, y, *t) instead of f(*(x, y) + t) ++ #new = pytree.Node(syms.power, (func, ArgList(l_newargs))) ++ return Call(func, l_newargs, prefix=prefix) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_basestring.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_basestring.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,13 @@ ++"""Fixer for basestring -> str.""" ++# Author: Christian Heimes ++ ++# Local imports ++from .. import fixer_base ++from ..fixer_util import Name ++ ++class FixBasestring(fixer_base.BaseFix): ++ ++ PATTERN = "'basestring'" ++ ++ def transform(self, node, results): ++ return Name("str", prefix=node.get_prefix()) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_buffer.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_buffer.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,21 @@ ++# Copyright 2007 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer that changes buffer(...) into memoryview(...).""" ++ ++# Local imports ++from .. import fixer_base ++from ..fixer_util import Name ++ ++ ++class FixBuffer(fixer_base.BaseFix): ++ ++ explicit = True # The user must ask for this fixer ++ ++ PATTERN = """ ++ power< name='buffer' trailer< '(' [any] ')' > > ++ """ ++ ++ def transform(self, node, results): ++ name = results["name"] ++ name.replace(Name("memoryview", prefix=name.get_prefix())) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_callable.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_callable.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,31 @@ ++# Copyright 2007 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for callable(). ++ ++This converts callable(obj) into hasattr(obj, '__call__').""" ++ ++# Local imports ++from .. import pytree ++from .. import fixer_base ++from ..fixer_util import Call, Name, String ++ ++class FixCallable(fixer_base.BaseFix): ++ ++ # Ignore callable(*args) or use of keywords. ++ # Either could be a hint that the builtin callable() is not being used. ++ PATTERN = """ ++ power< 'callable' ++ trailer< lpar='(' ++ ( not(arglist | argument) any ','> ) ++ rpar=')' > ++ after=any* ++ > ++ """ ++ ++ def transform(self, node, results): ++ func = results["func"] ++ ++ args = [func.clone(), String(', '), String("'__call__'")] ++ return Call(Name("hasattr"), args, prefix=node.get_prefix()) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_dict.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_dict.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,99 @@ ++# Copyright 2007 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for dict methods. ++ ++d.keys() -> list(d.keys()) ++d.items() -> list(d.items()) ++d.values() -> list(d.values()) ++ ++d.iterkeys() -> iter(d.keys()) ++d.iteritems() -> iter(d.items()) ++d.itervalues() -> iter(d.values()) ++ ++Except in certain very specific contexts: the iter() can be dropped ++when the context is list(), sorted(), iter() or for...in; the list() ++can be dropped when the context is list() or sorted() (but not iter() ++or for...in!). Special contexts that apply to both: list(), sorted(), tuple() ++set(), any(), all(), sum(). ++ ++Note: iter(d.keys()) could be written as iter(d) but since the ++original d.iterkeys() was also redundant we don't fix this. And there ++are (rare) contexts where it makes a difference (e.g. when passing it ++as an argument to a function that introspects the argument). ++""" ++ ++# Local imports ++from .. import pytree ++from .. import patcomp ++from ..pgen2 import token ++from .. import fixer_base ++from ..fixer_util import Name, Call, LParen, RParen, ArgList, Dot ++from .. import fixer_util ++ ++ ++iter_exempt = fixer_util.consuming_calls | set(["iter"]) ++ ++ ++class FixDict(fixer_base.BaseFix): ++ PATTERN = """ ++ power< head=any+ ++ trailer< '.' method=('keys'|'items'|'values'| ++ 'iterkeys'|'iteritems'|'itervalues') > ++ parens=trailer< '(' ')' > ++ tail=any* ++ > ++ """ ++ ++ def transform(self, node, results): ++ head = results["head"] ++ method = results["method"][0] # Extract node for method name ++ tail = results["tail"] ++ syms = self.syms ++ method_name = method.value ++ isiter = method_name.startswith("iter") ++ if isiter: ++ method_name = method_name[4:] ++ assert method_name in ("keys", "items", "values"), repr(method) ++ head = [n.clone() for n in head] ++ tail = [n.clone() for n in tail] ++ special = not tail and self.in_special_context(node, isiter) ++ args = head + [pytree.Node(syms.trailer, ++ [Dot(), ++ Name(method_name, ++ prefix=method.get_prefix())]), ++ results["parens"].clone()] ++ new = pytree.Node(syms.power, args) ++ if not special: ++ new.set_prefix("") ++ new = Call(Name(isiter and "iter" or "list"), [new]) ++ if tail: ++ new = pytree.Node(syms.power, [new] + tail) ++ new.set_prefix(node.get_prefix()) ++ return new ++ ++ P1 = "power< func=NAME trailer< '(' node=any ')' > any* >" ++ p1 = patcomp.compile_pattern(P1) ++ ++ P2 = """for_stmt< 'for' any 'in' node=any ':' any* > ++ | comp_for< 'for' any 'in' node=any any* > ++ """ ++ p2 = patcomp.compile_pattern(P2) ++ ++ def in_special_context(self, node, isiter): ++ if node.parent is None: ++ return False ++ results = {} ++ if (node.parent.parent is not None and ++ self.p1.match(node.parent.parent, results) and ++ results["node"] is node): ++ if isiter: ++ # iter(d.iterkeys()) -> iter(d.keys()), etc. ++ return results["func"].value in iter_exempt ++ else: ++ # list(d.keys()) -> list(d.keys()), etc. ++ return results["func"].value in fixer_util.consuming_calls ++ if not isiter: ++ return False ++ # for ... in d.iterkeys() -> for ... in d.keys(), etc. ++ return self.p2.match(node.parent, results) and results["node"] is node +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_except.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_except.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,92 @@ ++"""Fixer for except statements with named exceptions. ++ ++The following cases will be converted: ++ ++- "except E, T:" where T is a name: ++ ++ except E as T: ++ ++- "except E, T:" where T is not a name, tuple or list: ++ ++ except E as t: ++ T = t ++ ++ This is done because the target of an "except" clause must be a ++ name. ++ ++- "except E, T:" where T is a tuple or list literal: ++ ++ except E as t: ++ T = t.args ++""" ++# Author: Collin Winter ++ ++# Local imports ++from .. import pytree ++from ..pgen2 import token ++from .. import fixer_base ++from ..fixer_util import Assign, Attr, Name, is_tuple, is_list, syms ++ ++def find_excepts(nodes): ++ for i, n in enumerate(nodes): ++ if n.type == syms.except_clause: ++ if n.children[0].value == 'except': ++ yield (n, nodes[i+2]) ++ ++class FixExcept(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ try_stmt< 'try' ':' suite ++ cleanup=(except_clause ':' suite)+ ++ tail=(['except' ':' suite] ++ ['else' ':' suite] ++ ['finally' ':' suite]) > ++ """ ++ ++ def transform(self, node, results): ++ syms = self.syms ++ ++ tail = [n.clone() for n in results["tail"]] ++ ++ try_cleanup = [ch.clone() for ch in results["cleanup"]] ++ for except_clause, e_suite in find_excepts(try_cleanup): ++ if len(except_clause.children) == 4: ++ (E, comma, N) = except_clause.children[1:4] ++ comma.replace(Name("as", prefix=" ")) ++ ++ if N.type != token.NAME: ++ # Generate a new N for the except clause ++ new_N = Name(self.new_name(), prefix=" ") ++ target = N.clone() ++ target.set_prefix("") ++ N.replace(new_N) ++ new_N = new_N.clone() ++ ++ # Insert "old_N = new_N" as the first statement in ++ # the except body. This loop skips leading whitespace ++ # and indents ++ #TODO(cwinter) suite-cleanup ++ suite_stmts = e_suite.children ++ for i, stmt in enumerate(suite_stmts): ++ if isinstance(stmt, pytree.Node): ++ break ++ ++ # The assignment is different if old_N is a tuple or list ++ # In that case, the assignment is old_N = new_N.args ++ if is_tuple(N) or is_list(N): ++ assign = Assign(target, Attr(new_N, Name('args'))) ++ else: ++ assign = Assign(target, new_N) ++ ++ #TODO(cwinter) stopgap until children becomes a smart list ++ for child in reversed(suite_stmts[:i]): ++ e_suite.insert_child(0, child) ++ e_suite.insert_child(i, assign) ++ elif N.get_prefix() == "": ++ # No space after a comma is legal; no space after "as", ++ # not so much. ++ N.set_prefix(" ") ++ ++ #TODO(cwinter) fix this when children becomes a smart list ++ children = [c.clone() for c in node.children[:3]] + try_cleanup + tail ++ return pytree.Node(node.type, children) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_exec.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_exec.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,39 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for exec. ++ ++This converts usages of the exec statement into calls to a built-in ++exec() function. ++ ++exec code in ns1, ns2 -> exec(code, ns1, ns2) ++""" ++ ++# Local imports ++from .. import pytree ++from .. import fixer_base ++from ..fixer_util import Comma, Name, Call ++ ++ ++class FixExec(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ exec_stmt< 'exec' a=any 'in' b=any [',' c=any] > ++ | ++ exec_stmt< 'exec' (not atom<'(' [any] ')'>) a=any > ++ """ ++ ++ def transform(self, node, results): ++ assert results ++ syms = self.syms ++ a = results["a"] ++ b = results.get("b") ++ c = results.get("c") ++ args = [a.clone()] ++ args[0].set_prefix("") ++ if b is not None: ++ args.extend([Comma(), b.clone()]) ++ if c is not None: ++ args.extend([Comma(), c.clone()]) ++ ++ return Call(Name("exec"), args, prefix=node.get_prefix()) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_execfile.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_execfile.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,51 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for execfile. ++ ++This converts usages of the execfile function into calls to the built-in ++exec() function. ++""" ++ ++from .. import fixer_base ++from ..fixer_util import (Comma, Name, Call, LParen, RParen, Dot, Node, ++ ArgList, String, syms) ++ ++ ++class FixExecfile(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ power< 'execfile' trailer< '(' arglist< filename=any [',' globals=any [',' locals=any ] ] > ')' > > ++ | ++ power< 'execfile' trailer< '(' filename=any ')' > > ++ """ ++ ++ def transform(self, node, results): ++ assert results ++ filename = results["filename"] ++ globals = results.get("globals") ++ locals = results.get("locals") ++ ++ # Copy over the prefix from the right parentheses end of the execfile ++ # call. ++ execfile_paren = node.children[-1].children[-1].clone() ++ # Construct open().read(). ++ open_args = ArgList([filename.clone()], rparen=execfile_paren) ++ open_call = Node(syms.power, [Name("open"), open_args]) ++ read = [Node(syms.trailer, [Dot(), Name('read')]), ++ Node(syms.trailer, [LParen(), RParen()])] ++ open_expr = [open_call] + read ++ # Wrap the open call in a compile call. This is so the filename will be ++ # preserved in the execed code. ++ filename_arg = filename.clone() ++ filename_arg.set_prefix(" ") ++ exec_str = String("'exec'", " ") ++ compile_args = open_expr + [Comma(), filename_arg, Comma(), exec_str] ++ compile_call = Call(Name("compile"), compile_args, "") ++ # Finally, replace the execfile call with an exec call. ++ args = [compile_call] ++ if globals is not None: ++ args.extend([Comma(), globals.clone()]) ++ if locals is not None: ++ args.extend([Comma(), locals.clone()]) ++ return Call(Name("exec"), args, prefix=node.get_prefix()) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_filter.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_filter.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,75 @@ ++# Copyright 2007 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer that changes filter(F, X) into list(filter(F, X)). ++ ++We avoid the transformation if the filter() call is directly contained ++in iter(<>), list(<>), tuple(<>), sorted(<>), ...join(<>), or ++for V in <>:. ++ ++NOTE: This is still not correct if the original code was depending on ++filter(F, X) to return a string if X is a string and a tuple if X is a ++tuple. That would require type inference, which we don't do. Let ++Python 2.6 figure it out. ++""" ++ ++# Local imports ++from ..pgen2 import token ++from .. import fixer_base ++from ..fixer_util import Name, Call, ListComp, in_special_context ++ ++class FixFilter(fixer_base.ConditionalFix): ++ ++ PATTERN = """ ++ filter_lambda=power< ++ 'filter' ++ trailer< ++ '(' ++ arglist< ++ lambdef< 'lambda' ++ (fp=NAME | vfpdef< '(' fp=NAME ')'> ) ':' xp=any ++ > ++ ',' ++ it=any ++ > ++ ')' ++ > ++ > ++ | ++ power< ++ 'filter' ++ trailer< '(' arglist< none='None' ',' seq=any > ')' > ++ > ++ | ++ power< ++ 'filter' ++ args=trailer< '(' [any] ')' > ++ > ++ """ ++ ++ skip_on = "future_builtins.filter" ++ ++ def transform(self, node, results): ++ if self.should_skip(node): ++ return ++ ++ if "filter_lambda" in results: ++ new = ListComp(results.get("fp").clone(), ++ results.get("fp").clone(), ++ results.get("it").clone(), ++ results.get("xp").clone()) ++ ++ elif "none" in results: ++ new = ListComp(Name("_f"), ++ Name("_f"), ++ results["seq"].clone(), ++ Name("_f")) ++ ++ else: ++ if in_special_context(node): ++ return None ++ new = node.clone() ++ new.set_prefix("") ++ new = Call(Name("list"), [new]) ++ new.set_prefix(node.get_prefix()) ++ return new +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_funcattrs.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_funcattrs.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,19 @@ ++"""Fix function attribute names (f.func_x -> f.__x__).""" ++# Author: Collin Winter ++ ++# Local imports ++from .. import fixer_base ++from ..fixer_util import Name ++ ++ ++class FixFuncattrs(fixer_base.BaseFix): ++ PATTERN = """ ++ power< any+ trailer< '.' attr=('func_closure' | 'func_doc' | 'func_globals' ++ | 'func_name' | 'func_defaults' | 'func_code' ++ | 'func_dict') > any* > ++ """ ++ ++ def transform(self, node, results): ++ attr = results["attr"][0] ++ attr.replace(Name(("__%s__" % attr.value[5:]), ++ prefix=attr.get_prefix())) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_future.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_future.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,20 @@ ++"""Remove __future__ imports ++ ++from __future__ import foo is replaced with an empty line. ++""" ++# Author: Christian Heimes ++ ++# Local imports ++from .. import fixer_base ++from ..fixer_util import BlankLine ++ ++class FixFuture(fixer_base.BaseFix): ++ PATTERN = """import_from< 'from' module_name="__future__" 'import' any >""" ++ ++ # This should be run last -- some things check for the import ++ run_order = 10 ++ ++ def transform(self, node, results): ++ new = BlankLine() ++ new.prefix = node.get_prefix() ++ return new +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_getcwdu.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_getcwdu.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,18 @@ ++""" ++Fixer that changes os.getcwdu() to os.getcwd(). ++""" ++# Author: Victor Stinner ++ ++# Local imports ++from .. import fixer_base ++from ..fixer_util import Name ++ ++class FixGetcwdu(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ power< 'os' trailer< dot='.' name='getcwdu' > any* > ++ """ ++ ++ def transform(self, node, results): ++ name = results["name"] ++ name.replace(Name("getcwd", prefix=name.get_prefix())) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_has_key.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_has_key.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,109 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for has_key(). ++ ++Calls to .has_key() methods are expressed in terms of the 'in' ++operator: ++ ++ d.has_key(k) -> k in d ++ ++CAVEATS: ++1) While the primary target of this fixer is dict.has_key(), the ++ fixer will change any has_key() method call, regardless of its ++ class. ++ ++2) Cases like this will not be converted: ++ ++ m = d.has_key ++ if m(k): ++ ... ++ ++ Only *calls* to has_key() are converted. While it is possible to ++ convert the above to something like ++ ++ m = d.__contains__ ++ if m(k): ++ ... ++ ++ this is currently not done. ++""" ++ ++# Local imports ++from .. import pytree ++from ..pgen2 import token ++from .. import fixer_base ++from ..fixer_util import Name, parenthesize ++ ++ ++class FixHasKey(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ anchor=power< ++ before=any+ ++ trailer< '.' 'has_key' > ++ trailer< ++ '(' ++ ( not(arglist | argument) arg=any ','> ++ ) ++ ')' ++ > ++ after=any* ++ > ++ | ++ negation=not_test< ++ 'not' ++ anchor=power< ++ before=any+ ++ trailer< '.' 'has_key' > ++ trailer< ++ '(' ++ ( not(arglist | argument) arg=any ','> ++ ) ++ ')' ++ > ++ > ++ > ++ """ ++ ++ def transform(self, node, results): ++ assert results ++ syms = self.syms ++ if (node.parent.type == syms.not_test and ++ self.pattern.match(node.parent)): ++ # Don't transform a node matching the first alternative of the ++ # pattern when its parent matches the second alternative ++ return None ++ negation = results.get("negation") ++ anchor = results["anchor"] ++ prefix = node.get_prefix() ++ before = [n.clone() for n in results["before"]] ++ arg = results["arg"].clone() ++ after = results.get("after") ++ if after: ++ after = [n.clone() for n in after] ++ if arg.type in (syms.comparison, syms.not_test, syms.and_test, ++ syms.or_test, syms.test, syms.lambdef, syms.argument): ++ arg = parenthesize(arg) ++ if len(before) == 1: ++ before = before[0] ++ else: ++ before = pytree.Node(syms.power, before) ++ before.set_prefix(" ") ++ n_op = Name("in", prefix=" ") ++ if negation: ++ n_not = Name("not", prefix=" ") ++ n_op = pytree.Node(syms.comp_op, (n_not, n_op)) ++ new = pytree.Node(syms.comparison, (arg, n_op, before)) ++ if after: ++ new = parenthesize(new) ++ new = pytree.Node(syms.power, (new,) + tuple(after)) ++ if node.parent.type in (syms.comparison, syms.expr, syms.xor_expr, ++ syms.and_expr, syms.shift_expr, ++ syms.arith_expr, syms.term, ++ syms.factor, syms.power): ++ new = parenthesize(new) ++ new.set_prefix(prefix) ++ return new +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_idioms.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_idioms.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,134 @@ ++"""Adjust some old Python 2 idioms to their modern counterparts. ++ ++* Change some type comparisons to isinstance() calls: ++ type(x) == T -> isinstance(x, T) ++ type(x) is T -> isinstance(x, T) ++ type(x) != T -> not isinstance(x, T) ++ type(x) is not T -> not isinstance(x, T) ++ ++* Change "while 1:" into "while True:". ++ ++* Change both ++ ++ v = list(EXPR) ++ v.sort() ++ foo(v) ++ ++and the more general ++ ++ v = EXPR ++ v.sort() ++ foo(v) ++ ++into ++ ++ v = sorted(EXPR) ++ foo(v) ++""" ++# Author: Jacques Frechet, Collin Winter ++ ++# Local imports ++from .. import fixer_base ++from ..fixer_util import Call, Comma, Name, Node, syms ++ ++CMP = "(n='!=' | '==' | 'is' | n=comp_op< 'is' 'not' >)" ++TYPE = "power< 'type' trailer< '(' x=any ')' > >" ++ ++class FixIdioms(fixer_base.BaseFix): ++ ++ explicit = True # The user must ask for this fixer ++ ++ PATTERN = r""" ++ isinstance=comparison< %s %s T=any > ++ | ++ isinstance=comparison< T=any %s %s > ++ | ++ while_stmt< 'while' while='1' ':' any+ > ++ | ++ sorted=any< ++ any* ++ simple_stmt< ++ expr_stmt< id1=any '=' ++ power< list='list' trailer< '(' (not arglist) any ')' > > ++ > ++ '\n' ++ > ++ sort= ++ simple_stmt< ++ power< id2=any ++ trailer< '.' 'sort' > trailer< '(' ')' > ++ > ++ '\n' ++ > ++ next=any* ++ > ++ | ++ sorted=any< ++ any* ++ simple_stmt< expr_stmt< id1=any '=' expr=any > '\n' > ++ sort= ++ simple_stmt< ++ power< id2=any ++ trailer< '.' 'sort' > trailer< '(' ')' > ++ > ++ '\n' ++ > ++ next=any* ++ > ++ """ % (TYPE, CMP, CMP, TYPE) ++ ++ def match(self, node): ++ r = super(FixIdioms, self).match(node) ++ # If we've matched one of the sort/sorted subpatterns above, we ++ # want to reject matches where the initial assignment and the ++ # subsequent .sort() call involve different identifiers. ++ if r and "sorted" in r: ++ if r["id1"] == r["id2"]: ++ return r ++ return None ++ return r ++ ++ def transform(self, node, results): ++ if "isinstance" in results: ++ return self.transform_isinstance(node, results) ++ elif "while" in results: ++ return self.transform_while(node, results) ++ elif "sorted" in results: ++ return self.transform_sort(node, results) ++ else: ++ raise RuntimeError("Invalid match") ++ ++ def transform_isinstance(self, node, results): ++ x = results["x"].clone() # The thing inside of type() ++ T = results["T"].clone() # The type being compared against ++ x.set_prefix("") ++ T.set_prefix(" ") ++ test = Call(Name("isinstance"), [x, Comma(), T]) ++ if "n" in results: ++ test.set_prefix(" ") ++ test = Node(syms.not_test, [Name("not"), test]) ++ test.set_prefix(node.get_prefix()) ++ return test ++ ++ def transform_while(self, node, results): ++ one = results["while"] ++ one.replace(Name("True", prefix=one.get_prefix())) ++ ++ def transform_sort(self, node, results): ++ sort_stmt = results["sort"] ++ next_stmt = results["next"] ++ list_call = results.get("list") ++ simple_expr = results.get("expr") ++ ++ if list_call: ++ list_call.replace(Name("sorted", prefix=list_call.get_prefix())) ++ elif simple_expr: ++ new = simple_expr.clone() ++ new.set_prefix("") ++ simple_expr.replace(Call(Name("sorted"), [new], ++ prefix=simple_expr.get_prefix())) ++ else: ++ raise RuntimeError("should not have reached here") ++ sort_stmt.remove() ++ if next_stmt: ++ next_stmt[0].set_prefix(sort_stmt.get_prefix()) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_import.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_import.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,90 @@ ++"""Fixer for import statements. ++If spam is being imported from the local directory, this import: ++ from spam import eggs ++Becomes: ++ from .spam import eggs ++ ++And this import: ++ import spam ++Becomes: ++ from . import spam ++""" ++ ++# Local imports ++from .. import fixer_base ++from os.path import dirname, join, exists, pathsep ++from ..fixer_util import FromImport, syms, token ++ ++ ++def traverse_imports(names): ++ """ ++ Walks over all the names imported in a dotted_as_names node. ++ """ ++ pending = [names] ++ while pending: ++ node = pending.pop() ++ if node.type == token.NAME: ++ yield node.value ++ elif node.type == syms.dotted_name: ++ yield "".join([ch.value for ch in node.children]) ++ elif node.type == syms.dotted_as_name: ++ pending.append(node.children[0]) ++ elif node.type == syms.dotted_as_names: ++ pending.extend(node.children[::-2]) ++ else: ++ raise AssertionError("unkown node type") ++ ++ ++class FixImport(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ import_from< 'from' imp=any 'import' ['('] any [')'] > ++ | ++ import_name< 'import' imp=any > ++ """ ++ ++ def transform(self, node, results): ++ imp = results['imp'] ++ ++ if node.type == syms.import_from: ++ # Some imps are top-level (eg: 'import ham') ++ # some are first level (eg: 'import ham.eggs') ++ # some are third level (eg: 'import ham.eggs as spam') ++ # Hence, the loop ++ while not hasattr(imp, 'value'): ++ imp = imp.children[0] ++ if self.probably_a_local_import(imp.value): ++ imp.value = "." + imp.value ++ imp.changed() ++ return node ++ else: ++ have_local = False ++ have_absolute = False ++ for mod_name in traverse_imports(imp): ++ if self.probably_a_local_import(mod_name): ++ have_local = True ++ else: ++ have_absolute = True ++ if have_absolute: ++ if have_local: ++ # We won't handle both sibling and absolute imports in the ++ # same statement at the moment. ++ self.warning(node, "absolute and local imports together") ++ return ++ ++ new = FromImport('.', [imp]) ++ new.set_prefix(node.get_prefix()) ++ return new ++ ++ def probably_a_local_import(self, imp_name): ++ imp_name = imp_name.split('.', 1)[0] ++ base_path = dirname(self.filename) ++ base_path = join(base_path, imp_name) ++ # If there is no __init__.py next to the file its not in a package ++ # so can't be a relative import. ++ if not exists(join(dirname(base_path), '__init__.py')): ++ return False ++ for ext in ['.py', pathsep, '.pyc', '.so', '.sl', '.pyd']: ++ if exists(base_path + ext): ++ return True ++ return False +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_imports.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_imports.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,145 @@ ++"""Fix incompatible imports and module references.""" ++# Authors: Collin Winter, Nick Edds ++ ++# Local imports ++from .. import fixer_base ++from ..fixer_util import Name, attr_chain ++ ++MAPPING = {'StringIO': 'io', ++ 'cStringIO': 'io', ++ 'cPickle': 'pickle', ++ '__builtin__' : 'builtins', ++ 'copy_reg': 'copyreg', ++ 'Queue': 'queue', ++ 'SocketServer': 'socketserver', ++ 'ConfigParser': 'configparser', ++ 'repr': 'reprlib', ++ 'FileDialog': 'tkinter.filedialog', ++ 'tkFileDialog': 'tkinter.filedialog', ++ 'SimpleDialog': 'tkinter.simpledialog', ++ 'tkSimpleDialog': 'tkinter.simpledialog', ++ 'tkColorChooser': 'tkinter.colorchooser', ++ 'tkCommonDialog': 'tkinter.commondialog', ++ 'Dialog': 'tkinter.dialog', ++ 'Tkdnd': 'tkinter.dnd', ++ 'tkFont': 'tkinter.font', ++ 'tkMessageBox': 'tkinter.messagebox', ++ 'ScrolledText': 'tkinter.scrolledtext', ++ 'Tkconstants': 'tkinter.constants', ++ 'Tix': 'tkinter.tix', ++ 'ttk': 'tkinter.ttk', ++ 'Tkinter': 'tkinter', ++ 'markupbase': '_markupbase', ++ '_winreg': 'winreg', ++ 'thread': '_thread', ++ 'dummy_thread': '_dummy_thread', ++ # anydbm and whichdb are handled by fix_imports2 ++ 'dbhash': 'dbm.bsd', ++ 'dumbdbm': 'dbm.dumb', ++ 'dbm': 'dbm.ndbm', ++ 'gdbm': 'dbm.gnu', ++ 'xmlrpclib': 'xmlrpc.client', ++ 'DocXMLRPCServer': 'xmlrpc.server', ++ 'SimpleXMLRPCServer': 'xmlrpc.server', ++ 'httplib': 'http.client', ++ 'htmlentitydefs' : 'html.entities', ++ 'HTMLParser' : 'html.parser', ++ 'Cookie': 'http.cookies', ++ 'cookielib': 'http.cookiejar', ++ 'BaseHTTPServer': 'http.server', ++ 'SimpleHTTPServer': 'http.server', ++ 'CGIHTTPServer': 'http.server', ++ #'test.test_support': 'test.support', ++ 'commands': 'subprocess', ++ 'UserString' : 'collections', ++ 'UserList' : 'collections', ++ 'urlparse' : 'urllib.parse', ++ 'robotparser' : 'urllib.robotparser', ++} ++ ++ ++def alternates(members): ++ return "(" + "|".join(map(repr, members)) + ")" ++ ++ ++def build_pattern(mapping=MAPPING): ++ mod_list = ' | '.join(["module_name='%s'" % key for key in mapping]) ++ bare_names = alternates(mapping.keys()) ++ ++ yield """name_import=import_name< 'import' ((%s) | ++ multiple_imports=dotted_as_names< any* (%s) any* >) > ++ """ % (mod_list, mod_list) ++ yield """import_from< 'from' (%s) 'import' ['('] ++ ( any | import_as_name< any 'as' any > | ++ import_as_names< any* >) [')'] > ++ """ % mod_list ++ yield """import_name< 'import' (dotted_as_name< (%s) 'as' any > | ++ multiple_imports=dotted_as_names< ++ any* dotted_as_name< (%s) 'as' any > any* >) > ++ """ % (mod_list, mod_list) ++ ++ # Find usages of module members in code e.g. thread.foo(bar) ++ yield "power< bare_with_attr=(%s) trailer<'.' any > any* >" % bare_names ++ ++ ++class FixImports(fixer_base.BaseFix): ++ ++ order = "pre" # Pre-order tree traversal ++ ++ # This is overridden in fix_imports2. ++ mapping = MAPPING ++ ++ # We want to run this fixer late, so fix_import doesn't try to make stdlib ++ # renames into relative imports. ++ run_order = 6 ++ ++ def build_pattern(self): ++ return "|".join(build_pattern(self.mapping)) ++ ++ def compile_pattern(self): ++ # We override this, so MAPPING can be pragmatically altered and the ++ # changes will be reflected in PATTERN. ++ self.PATTERN = self.build_pattern() ++ super(FixImports, self).compile_pattern() ++ ++ # Don't match the node if it's within another match. ++ def match(self, node): ++ match = super(FixImports, self).match ++ results = match(node) ++ if results: ++ # Module usage could be in the trailer of an attribute lookup, so we ++ # might have nested matches when "bare_with_attr" is present. ++ if "bare_with_attr" not in results and \ ++ any([match(obj) for obj in attr_chain(node, "parent")]): ++ return False ++ return results ++ return False ++ ++ def start_tree(self, tree, filename): ++ super(FixImports, self).start_tree(tree, filename) ++ self.replace = {} ++ ++ def transform(self, node, results): ++ import_mod = results.get("module_name") ++ if import_mod: ++ mod_name = import_mod.value ++ new_name = self.mapping[mod_name] ++ import_mod.replace(Name(new_name, prefix=import_mod.get_prefix())) ++ if "name_import" in results: ++ # If it's not a "from x import x, y" or "import x as y" import, ++ # marked its usage to be replaced. ++ self.replace[mod_name] = new_name ++ if "multiple_imports" in results: ++ # This is a nasty hack to fix multiple imports on a line (e.g., ++ # "import StringIO, urlparse"). The problem is that I can't ++ # figure out an easy way to make a pattern recognize the keys of ++ # MAPPING randomly sprinkled in an import statement. ++ results = self.match(node) ++ if results: ++ self.transform(node, results) ++ else: ++ # Replace usage of the module. ++ bare_name = results["bare_with_attr"][0] ++ new_name = self.replace.get(bare_name.value) ++ if new_name: ++ bare_name.replace(Name(new_name, prefix=bare_name.get_prefix())) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_imports2.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_imports2.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,16 @@ ++"""Fix incompatible imports and module references that must be fixed after ++fix_imports.""" ++from . import fix_imports ++ ++ ++MAPPING = { ++ 'whichdb': 'dbm', ++ 'anydbm': 'dbm', ++ } ++ ++ ++class FixImports2(fix_imports.FixImports): ++ ++ run_order = 7 ++ ++ mapping = MAPPING +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_input.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_input.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,26 @@ ++"""Fixer that changes input(...) into eval(input(...)).""" ++# Author: Andre Roberge ++ ++# Local imports ++from .. import fixer_base ++from ..fixer_util import Call, Name ++from .. import patcomp ++ ++ ++context = patcomp.compile_pattern("power< 'eval' trailer< '(' any ')' > >") ++ ++ ++class FixInput(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ power< 'input' args=trailer< '(' [any] ')' > > ++ """ ++ ++ def transform(self, node, results): ++ # If we're already wrapped in a eval() call, we're done. ++ if context.match(node.parent.parent): ++ return ++ ++ new = node.clone() ++ new.set_prefix("") ++ return Call(Name("eval"), [new], prefix=node.get_prefix()) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_intern.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_intern.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,44 @@ ++# Copyright 2006 Georg Brandl. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for intern(). ++ ++intern(s) -> sys.intern(s)""" ++ ++# Local imports ++from .. import pytree ++from .. import fixer_base ++from ..fixer_util import Name, Attr, touch_import ++ ++ ++class FixIntern(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ power< 'intern' ++ trailer< lpar='(' ++ ( not(arglist | argument) any ','> ) ++ rpar=')' > ++ after=any* ++ > ++ """ ++ ++ def transform(self, node, results): ++ syms = self.syms ++ obj = results["obj"].clone() ++ if obj.type == syms.arglist: ++ newarglist = obj.clone() ++ else: ++ newarglist = pytree.Node(syms.arglist, [obj.clone()]) ++ after = results["after"] ++ if after: ++ after = [n.clone() for n in after] ++ new = pytree.Node(syms.power, ++ Attr(Name("sys"), Name("intern")) + ++ [pytree.Node(syms.trailer, ++ [results["lpar"].clone(), ++ newarglist, ++ results["rpar"].clone()])] + after) ++ new.set_prefix(node.get_prefix()) ++ touch_import(None, 'sys', node) ++ return new +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_isinstance.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_isinstance.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,52 @@ ++# Copyright 2008 Armin Ronacher. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer that cleans up a tuple argument to isinstance after the tokens ++in it were fixed. This is mainly used to remove double occurrences of ++tokens as a leftover of the long -> int / unicode -> str conversion. ++ ++eg. isinstance(x, (int, long)) -> isinstance(x, (int, int)) ++ -> isinstance(x, int) ++""" ++ ++from .. import fixer_base ++from ..fixer_util import token ++ ++ ++class FixIsinstance(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ power< ++ 'isinstance' ++ trailer< '(' arglist< any ',' atom< '(' ++ args=testlist_gexp< any+ > ++ ')' > > ')' > ++ > ++ """ ++ ++ run_order = 6 ++ ++ def transform(self, node, results): ++ names_inserted = set() ++ testlist = results["args"] ++ args = testlist.children ++ new_args = [] ++ iterator = enumerate(args) ++ for idx, arg in iterator: ++ if arg.type == token.NAME and arg.value in names_inserted: ++ if idx < len(args) - 1 and args[idx + 1].type == token.COMMA: ++ iterator.next() ++ continue ++ else: ++ new_args.append(arg) ++ if arg.type == token.NAME: ++ names_inserted.add(arg.value) ++ if new_args and new_args[-1].type == token.COMMA: ++ del new_args[-1] ++ if len(new_args) == 1: ++ atom = testlist.parent ++ new_args[0].set_prefix(atom.get_prefix()) ++ atom.replace(new_args[0]) ++ else: ++ args[:] = new_args ++ node.changed() +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_itertools.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_itertools.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,41 @@ ++""" Fixer for itertools.(imap|ifilter|izip) --> (map|filter|zip) and ++ itertools.ifilterfalse --> itertools.filterfalse (bugs 2360-2363) ++ ++ imports from itertools are fixed in fix_itertools_import.py ++ ++ If itertools is imported as something else (ie: import itertools as it; ++ it.izip(spam, eggs)) method calls will not get fixed. ++ """ ++ ++# Local imports ++from .. import fixer_base ++from ..fixer_util import Name ++ ++class FixItertools(fixer_base.BaseFix): ++ it_funcs = "('imap'|'ifilter'|'izip'|'ifilterfalse')" ++ PATTERN = """ ++ power< it='itertools' ++ trailer< ++ dot='.' func=%(it_funcs)s > trailer< '(' [any] ')' > > ++ | ++ power< func=%(it_funcs)s trailer< '(' [any] ')' > > ++ """ %(locals()) ++ ++ # Needs to be run after fix_(map|zip|filter) ++ run_order = 6 ++ ++ def transform(self, node, results): ++ prefix = None ++ func = results['func'][0] ++ if 'it' in results and func.value != 'ifilterfalse': ++ dot, it = (results['dot'], results['it']) ++ # Remove the 'itertools' ++ prefix = it.get_prefix() ++ it.remove() ++ # Replace the node wich contains ('.', 'function') with the ++ # function (to be consistant with the second part of the pattern) ++ dot.remove() ++ func.parent.replace(func) ++ ++ prefix = prefix or func.get_prefix() ++ func.replace(Name(func.value[1:], prefix=prefix)) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_itertools_imports.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_itertools_imports.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,52 @@ ++""" Fixer for imports of itertools.(imap|ifilter|izip|ifilterfalse) """ ++ ++# Local imports ++from lib2to3 import fixer_base ++from lib2to3.fixer_util import BlankLine, syms, token ++ ++ ++class FixItertoolsImports(fixer_base.BaseFix): ++ PATTERN = """ ++ import_from< 'from' 'itertools' 'import' imports=any > ++ """ %(locals()) ++ ++ def transform(self, node, results): ++ imports = results['imports'] ++ if imports.type == syms.import_as_name or not imports.children: ++ children = [imports] ++ else: ++ children = imports.children ++ for child in children[::2]: ++ if child.type == token.NAME: ++ member = child.value ++ name_node = child ++ else: ++ assert child.type == syms.import_as_name ++ name_node = child.children[0] ++ member_name = name_node.value ++ if member_name in ('imap', 'izip', 'ifilter'): ++ child.value = None ++ child.remove() ++ elif member_name == 'ifilterfalse': ++ node.changed() ++ name_node.value = 'filterfalse' ++ ++ # Make sure the import statement is still sane ++ children = imports.children[:] or [imports] ++ remove_comma = True ++ for child in children: ++ if remove_comma and child.type == token.COMMA: ++ child.remove() ++ else: ++ remove_comma ^= True ++ ++ if children[-1].type == token.COMMA: ++ children[-1].remove() ++ ++ # If there are no imports left, just get rid of the entire statement ++ if not (imports.children or getattr(imports, 'value', None)) or \ ++ imports.parent is None: ++ p = node.get_prefix() ++ node = BlankLine() ++ node.prefix = p ++ return node +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_long.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_long.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,22 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer that turns 'long' into 'int' everywhere. ++""" ++ ++# Local imports ++from .. import fixer_base ++from ..fixer_util import Name, Number, is_probably_builtin ++ ++ ++class FixLong(fixer_base.BaseFix): ++ ++ PATTERN = "'long'" ++ ++ static_int = Name("int") ++ ++ def transform(self, node, results): ++ if is_probably_builtin(node): ++ new = self.static_int.clone() ++ new.set_prefix(node.get_prefix()) ++ return new +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_map.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_map.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,82 @@ ++# Copyright 2007 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer that changes map(F, ...) into list(map(F, ...)) unless there ++exists a 'from future_builtins import map' statement in the top-level ++namespace. ++ ++As a special case, map(None, X) is changed into list(X). (This is ++necessary because the semantics are changed in this case -- the new ++map(None, X) is equivalent to [(x,) for x in X].) ++ ++We avoid the transformation (except for the special case mentioned ++above) if the map() call is directly contained in iter(<>), list(<>), ++tuple(<>), sorted(<>), ...join(<>), or for V in <>:. ++ ++NOTE: This is still not correct if the original code was depending on ++map(F, X, Y, ...) to go on until the longest argument is exhausted, ++substituting None for missing values -- like zip(), it now stops as ++soon as the shortest argument is exhausted. ++""" ++ ++# Local imports ++from ..pgen2 import token ++from .. import fixer_base ++from ..fixer_util import Name, Call, ListComp, in_special_context ++from ..pygram import python_symbols as syms ++ ++class FixMap(fixer_base.ConditionalFix): ++ ++ PATTERN = """ ++ map_none=power< ++ 'map' ++ trailer< '(' arglist< 'None' ',' arg=any [','] > ')' > ++ > ++ | ++ map_lambda=power< ++ 'map' ++ trailer< ++ '(' ++ arglist< ++ lambdef< 'lambda' ++ (fp=NAME | vfpdef< '(' fp=NAME ')'> ) ':' xp=any ++ > ++ ',' ++ it=any ++ > ++ ')' ++ > ++ > ++ | ++ power< ++ 'map' ++ args=trailer< '(' [any] ')' > ++ > ++ """ ++ ++ skip_on = 'future_builtins.map' ++ ++ def transform(self, node, results): ++ if self.should_skip(node): ++ return ++ ++ if node.parent.type == syms.simple_stmt: ++ self.warning(node, "You should use a for loop here") ++ new = node.clone() ++ new.set_prefix("") ++ new = Call(Name("list"), [new]) ++ elif "map_lambda" in results: ++ new = ListComp(results.get("xp").clone(), ++ results.get("fp").clone(), ++ results.get("it").clone()) ++ else: ++ if "map_none" in results: ++ new = results["arg"].clone() ++ else: ++ if in_special_context(node): ++ return None ++ new = node.clone() ++ new.set_prefix("") ++ new = Call(Name("list"), [new]) ++ new.set_prefix(node.get_prefix()) ++ return new +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_metaclass.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_metaclass.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,227 @@ ++"""Fixer for __metaclass__ = X -> (metaclass=X) methods. ++ ++ The various forms of classef (inherits nothing, inherits once, inherints ++ many) don't parse the same in the CST so we look at ALL classes for ++ a __metaclass__ and if we find one normalize the inherits to all be ++ an arglist. ++ ++ For one-liner classes ('class X: pass') there is no indent/dedent so ++ we normalize those into having a suite. ++ ++ Moving the __metaclass__ into the classdef can also cause the class ++ body to be empty so there is some special casing for that as well. ++ ++ This fixer also tries very hard to keep original indenting and spacing ++ in all those corner cases. ++ ++""" ++# Author: Jack Diederich ++ ++# Local imports ++from .. import fixer_base ++from ..pygram import token ++from ..fixer_util import Name, syms, Node, Leaf ++ ++ ++def has_metaclass(parent): ++ """ we have to check the cls_node without changing it. ++ There are two possiblities: ++ 1) clsdef => suite => simple_stmt => expr_stmt => Leaf('__meta') ++ 2) clsdef => simple_stmt => expr_stmt => Leaf('__meta') ++ """ ++ for node in parent.children: ++ if node.type == syms.suite: ++ return has_metaclass(node) ++ elif node.type == syms.simple_stmt and node.children: ++ expr_node = node.children[0] ++ if expr_node.type == syms.expr_stmt and expr_node.children: ++ left_side = expr_node.children[0] ++ if isinstance(left_side, Leaf) and \ ++ left_side.value == '__metaclass__': ++ return True ++ return False ++ ++ ++def fixup_parse_tree(cls_node): ++ """ one-line classes don't get a suite in the parse tree so we add ++ one to normalize the tree ++ """ ++ for node in cls_node.children: ++ if node.type == syms.suite: ++ # already in the prefered format, do nothing ++ return ++ ++ # !%@#! oneliners have no suite node, we have to fake one up ++ for i, node in enumerate(cls_node.children): ++ if node.type == token.COLON: ++ break ++ else: ++ raise ValueError("No class suite and no ':'!") ++ ++ # move everything into a suite node ++ suite = Node(syms.suite, []) ++ while cls_node.children[i+1:]: ++ move_node = cls_node.children[i+1] ++ suite.append_child(move_node.clone()) ++ move_node.remove() ++ cls_node.append_child(suite) ++ node = suite ++ ++ ++def fixup_simple_stmt(parent, i, stmt_node): ++ """ if there is a semi-colon all the parts count as part of the same ++ simple_stmt. We just want the __metaclass__ part so we move ++ everything efter the semi-colon into its own simple_stmt node ++ """ ++ for semi_ind, node in enumerate(stmt_node.children): ++ if node.type == token.SEMI: # *sigh* ++ break ++ else: ++ return ++ ++ node.remove() # kill the semicolon ++ new_expr = Node(syms.expr_stmt, []) ++ new_stmt = Node(syms.simple_stmt, [new_expr]) ++ while stmt_node.children[semi_ind:]: ++ move_node = stmt_node.children[semi_ind] ++ new_expr.append_child(move_node.clone()) ++ move_node.remove() ++ parent.insert_child(i, new_stmt) ++ new_leaf1 = new_stmt.children[0].children[0] ++ old_leaf1 = stmt_node.children[0].children[0] ++ new_leaf1.set_prefix(old_leaf1.get_prefix()) ++ ++ ++def remove_trailing_newline(node): ++ if node.children and node.children[-1].type == token.NEWLINE: ++ node.children[-1].remove() ++ ++ ++def find_metas(cls_node): ++ # find the suite node (Mmm, sweet nodes) ++ for node in cls_node.children: ++ if node.type == syms.suite: ++ break ++ else: ++ raise ValueError("No class suite!") ++ ++ # look for simple_stmt[ expr_stmt[ Leaf('__metaclass__') ] ] ++ for i, simple_node in list(enumerate(node.children)): ++ if simple_node.type == syms.simple_stmt and simple_node.children: ++ expr_node = simple_node.children[0] ++ if expr_node.type == syms.expr_stmt and expr_node.children: ++ # Check if the expr_node is a simple assignment. ++ left_node = expr_node.children[0] ++ if isinstance(left_node, Leaf) and \ ++ left_node.value == '__metaclass__': ++ # We found a assignment to __metaclass__. ++ fixup_simple_stmt(node, i, simple_node) ++ remove_trailing_newline(simple_node) ++ yield (node, i, simple_node) ++ ++ ++def fixup_indent(suite): ++ """ If an INDENT is followed by a thing with a prefix then nuke the prefix ++ Otherwise we get in trouble when removing __metaclass__ at suite start ++ """ ++ kids = suite.children[::-1] ++ # find the first indent ++ while kids: ++ node = kids.pop() ++ if node.type == token.INDENT: ++ break ++ ++ # find the first Leaf ++ while kids: ++ node = kids.pop() ++ if isinstance(node, Leaf) and node.type != token.DEDENT: ++ if node.prefix: ++ node.set_prefix('') ++ return ++ else: ++ kids.extend(node.children[::-1]) ++ ++ ++class FixMetaclass(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ classdef ++ """ ++ ++ def transform(self, node, results): ++ if not has_metaclass(node): ++ return node ++ ++ fixup_parse_tree(node) ++ ++ # find metaclasses, keep the last one ++ last_metaclass = None ++ for suite, i, stmt in find_metas(node): ++ last_metaclass = stmt ++ stmt.remove() ++ ++ text_type = node.children[0].type # always Leaf(nnn, 'class') ++ ++ # figure out what kind of classdef we have ++ if len(node.children) == 7: ++ # Node(classdef, ['class', 'name', '(', arglist, ')', ':', suite]) ++ # 0 1 2 3 4 5 6 ++ if node.children[3].type == syms.arglist: ++ arglist = node.children[3] ++ # Node(classdef, ['class', 'name', '(', 'Parent', ')', ':', suite]) ++ else: ++ parent = node.children[3].clone() ++ arglist = Node(syms.arglist, [parent]) ++ node.set_child(3, arglist) ++ elif len(node.children) == 6: ++ # Node(classdef, ['class', 'name', '(', ')', ':', suite]) ++ # 0 1 2 3 4 5 ++ arglist = Node(syms.arglist, []) ++ node.insert_child(3, arglist) ++ elif len(node.children) == 4: ++ # Node(classdef, ['class', 'name', ':', suite]) ++ # 0 1 2 3 ++ arglist = Node(syms.arglist, []) ++ node.insert_child(2, Leaf(token.RPAR, ')')) ++ node.insert_child(2, arglist) ++ node.insert_child(2, Leaf(token.LPAR, '(')) ++ else: ++ raise ValueError("Unexpected class definition") ++ ++ # now stick the metaclass in the arglist ++ meta_txt = last_metaclass.children[0].children[0] ++ meta_txt.value = 'metaclass' ++ orig_meta_prefix = meta_txt.get_prefix() ++ ++ if arglist.children: ++ arglist.append_child(Leaf(token.COMMA, ',')) ++ meta_txt.set_prefix(' ') ++ else: ++ meta_txt.set_prefix('') ++ ++ # compact the expression "metaclass = Meta" -> "metaclass=Meta" ++ expr_stmt = last_metaclass.children[0] ++ assert expr_stmt.type == syms.expr_stmt ++ expr_stmt.children[1].set_prefix('') ++ expr_stmt.children[2].set_prefix('') ++ ++ arglist.append_child(last_metaclass) ++ ++ fixup_indent(suite) ++ ++ # check for empty suite ++ if not suite.children: ++ # one-liner that was just __metaclass_ ++ suite.remove() ++ pass_leaf = Leaf(text_type, 'pass') ++ pass_leaf.set_prefix(orig_meta_prefix) ++ node.append_child(pass_leaf) ++ node.append_child(Leaf(token.NEWLINE, '\n')) ++ ++ elif len(suite.children) > 1 and \ ++ (suite.children[-2].type == token.INDENT and ++ suite.children[-1].type == token.DEDENT): ++ # there was only one line in the class body and it was __metaclass__ ++ pass_leaf = Leaf(text_type, 'pass') ++ suite.insert_child(-1, pass_leaf) ++ suite.insert_child(-1, Leaf(token.NEWLINE, '\n')) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_methodattrs.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_methodattrs.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,23 @@ ++"""Fix bound method attributes (method.im_? -> method.__?__). ++""" ++# Author: Christian Heimes ++ ++# Local imports ++from .. import fixer_base ++from ..fixer_util import Name ++ ++MAP = { ++ "im_func" : "__func__", ++ "im_self" : "__self__", ++ "im_class" : "__self__.__class__" ++ } ++ ++class FixMethodattrs(fixer_base.BaseFix): ++ PATTERN = """ ++ power< any+ trailer< '.' attr=('im_func' | 'im_self' | 'im_class') > any* > ++ """ ++ ++ def transform(self, node, results): ++ attr = results["attr"][0] ++ new = MAP[attr.value] ++ attr.replace(Name(new, prefix=attr.get_prefix())) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_ne.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_ne.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,22 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer that turns <> into !=.""" ++ ++# Local imports ++from .. import pytree ++from ..pgen2 import token ++from .. import fixer_base ++ ++ ++class FixNe(fixer_base.BaseFix): ++ # This is so simple that we don't need the pattern compiler. ++ ++ def match(self, node): ++ # Override ++ return node.type == token.NOTEQUAL and node.value == "<>" ++ ++ def transform(self, node, results): ++ new = pytree.Leaf(token.NOTEQUAL, "!=") ++ new.set_prefix(node.get_prefix()) ++ return new +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_next.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_next.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,103 @@ ++"""Fixer for it.next() -> next(it), per PEP 3114.""" ++# Author: Collin Winter ++ ++# Things that currently aren't covered: ++# - listcomp "next" names aren't warned ++# - "with" statement targets aren't checked ++ ++# Local imports ++from ..pgen2 import token ++from ..pygram import python_symbols as syms ++from .. import fixer_base ++from ..fixer_util import Name, Call, find_binding ++ ++bind_warning = "Calls to builtin next() possibly shadowed by global binding" ++ ++ ++class FixNext(fixer_base.BaseFix): ++ PATTERN = """ ++ power< base=any+ trailer< '.' attr='next' > trailer< '(' ')' > > ++ | ++ power< head=any+ trailer< '.' attr='next' > not trailer< '(' ')' > > ++ | ++ classdef< 'class' any+ ':' ++ suite< any* ++ funcdef< 'def' ++ name='next' ++ parameters< '(' NAME ')' > any+ > ++ any* > > ++ | ++ global=global_stmt< 'global' any* 'next' any* > ++ """ ++ ++ order = "pre" # Pre-order tree traversal ++ ++ def start_tree(self, tree, filename): ++ super(FixNext, self).start_tree(tree, filename) ++ ++ n = find_binding('next', tree) ++ if n: ++ self.warning(n, bind_warning) ++ self.shadowed_next = True ++ else: ++ self.shadowed_next = False ++ ++ def transform(self, node, results): ++ assert results ++ ++ base = results.get("base") ++ attr = results.get("attr") ++ name = results.get("name") ++ mod = results.get("mod") ++ ++ if base: ++ if self.shadowed_next: ++ attr.replace(Name("__next__", prefix=attr.get_prefix())) ++ else: ++ base = [n.clone() for n in base] ++ base[0].set_prefix("") ++ node.replace(Call(Name("next", prefix=node.get_prefix()), base)) ++ elif name: ++ n = Name("__next__", prefix=name.get_prefix()) ++ name.replace(n) ++ elif attr: ++ # We don't do this transformation if we're assigning to "x.next". ++ # Unfortunately, it doesn't seem possible to do this in PATTERN, ++ # so it's being done here. ++ if is_assign_target(node): ++ head = results["head"] ++ if "".join([str(n) for n in head]).strip() == '__builtin__': ++ self.warning(node, bind_warning) ++ return ++ attr.replace(Name("__next__")) ++ elif "global" in results: ++ self.warning(node, bind_warning) ++ self.shadowed_next = True ++ ++ ++### The following functions help test if node is part of an assignment ++### target. ++ ++def is_assign_target(node): ++ assign = find_assign(node) ++ if assign is None: ++ return False ++ ++ for child in assign.children: ++ if child.type == token.EQUAL: ++ return False ++ elif is_subtree(child, node): ++ return True ++ return False ++ ++def find_assign(node): ++ if node.type == syms.expr_stmt: ++ return node ++ if node.type == syms.simple_stmt or node.parent is None: ++ return None ++ return find_assign(node.parent) ++ ++def is_subtree(root, node): ++ if root == node: ++ return True ++ return any([is_subtree(c, node) for c in root.children]) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_nonzero.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_nonzero.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,20 @@ ++"""Fixer for __nonzero__ -> __bool__ methods.""" ++# Author: Collin Winter ++ ++# Local imports ++from .. import fixer_base ++from ..fixer_util import Name, syms ++ ++class FixNonzero(fixer_base.BaseFix): ++ PATTERN = """ ++ classdef< 'class' any+ ':' ++ suite< any* ++ funcdef< 'def' name='__nonzero__' ++ parameters< '(' NAME ')' > any+ > ++ any* > > ++ """ ++ ++ def transform(self, node, results): ++ name = results["name"] ++ new = Name("__bool__", prefix=name.get_prefix()) ++ name.replace(new) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_numliterals.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_numliterals.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,27 @@ ++"""Fixer that turns 1L into 1, 0755 into 0o755. ++""" ++# Copyright 2007 Georg Brandl. ++# Licensed to PSF under a Contributor Agreement. ++ ++# Local imports ++from ..pgen2 import token ++from .. import fixer_base ++from ..fixer_util import Number ++ ++ ++class FixNumliterals(fixer_base.BaseFix): ++ # This is so simple that we don't need the pattern compiler. ++ ++ def match(self, node): ++ # Override ++ return (node.type == token.NUMBER and ++ (node.value.startswith("0") or node.value[-1] in "Ll")) ++ ++ def transform(self, node, results): ++ val = node.value ++ if val[-1] in 'Ll': ++ val = val[:-1] ++ elif val.startswith('0') and val.isdigit() and len(set(val)) > 1: ++ val = "0o" + val[1:] ++ ++ return Number(val, prefix=node.get_prefix()) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_paren.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_paren.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,42 @@ ++"""Fixer that addes parentheses where they are required ++ ++This converts ``[x for x in 1, 2]`` to ``[x for x in (1, 2)]``.""" ++ ++# By Taek Joo Kim and Benjamin Peterson ++ ++# Local imports ++from .. import fixer_base ++from ..fixer_util import LParen, RParen ++ ++# XXX This doesn't support nested for loops like [x for x in 1, 2 for x in 1, 2] ++class FixParen(fixer_base.BaseFix): ++ PATTERN = """ ++ atom< ('[' | '(') ++ (listmaker< any ++ comp_for< ++ 'for' NAME 'in' ++ target=testlist_safe< any (',' any)+ [','] ++ > ++ [any] ++ > ++ > ++ | ++ testlist_gexp< any ++ comp_for< ++ 'for' NAME 'in' ++ target=testlist_safe< any (',' any)+ [','] ++ > ++ [any] ++ > ++ >) ++ (']' | ')') > ++ """ ++ ++ def transform(self, node, results): ++ target = results["target"] ++ ++ lparen = LParen() ++ lparen.set_prefix(target.get_prefix()) ++ target.set_prefix("") # Make it hug the parentheses ++ target.insert_child(0, lparen) ++ target.append_child(RParen()) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_print.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_print.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,90 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for print. ++ ++Change: ++ 'print' into 'print()' ++ 'print ...' into 'print(...)' ++ 'print ... ,' into 'print(..., end=" ")' ++ 'print >>x, ...' into 'print(..., file=x)' ++ ++No changes are applied if print_function is imported from __future__ ++ ++""" ++ ++# Local imports ++from .. import patcomp ++from .. import pytree ++from ..pgen2 import token ++from .. import fixer_base ++from ..fixer_util import Name, Call, Comma, String, is_tuple ++ ++ ++parend_expr = patcomp.compile_pattern( ++ """atom< '(' [atom|STRING|NAME] ')' >""" ++ ) ++ ++ ++class FixPrint(fixer_base.ConditionalFix): ++ ++ PATTERN = """ ++ simple_stmt< any* bare='print' any* > | print_stmt ++ """ ++ ++ skip_on = '__future__.print_function' ++ ++ def transform(self, node, results): ++ assert results ++ ++ if self.should_skip(node): ++ return ++ ++ bare_print = results.get("bare") ++ ++ if bare_print: ++ # Special-case print all by itself ++ bare_print.replace(Call(Name("print"), [], ++ prefix=bare_print.get_prefix())) ++ return ++ assert node.children[0] == Name("print") ++ args = node.children[1:] ++ if len(args) == 1 and parend_expr.match(args[0]): ++ # We don't want to keep sticking parens around an ++ # already-parenthesised expression. ++ return ++ ++ sep = end = file = None ++ if args and args[-1] == Comma(): ++ args = args[:-1] ++ end = " " ++ if args and args[0] == pytree.Leaf(token.RIGHTSHIFT, ">>"): ++ assert len(args) >= 2 ++ file = args[1].clone() ++ args = args[3:] # Strip a possible comma after the file expression ++ # Now synthesize a print(args, sep=..., end=..., file=...) node. ++ l_args = [arg.clone() for arg in args] ++ if l_args: ++ l_args[0].set_prefix("") ++ if sep is not None or end is not None or file is not None: ++ if sep is not None: ++ self.add_kwarg(l_args, "sep", String(repr(sep))) ++ if end is not None: ++ self.add_kwarg(l_args, "end", String(repr(end))) ++ if file is not None: ++ self.add_kwarg(l_args, "file", file) ++ n_stmt = Call(Name("print"), l_args) ++ n_stmt.set_prefix(node.get_prefix()) ++ return n_stmt ++ ++ def add_kwarg(self, l_nodes, s_kwd, n_expr): ++ # XXX All this prefix-setting may lose comments (though rarely) ++ n_expr.set_prefix("") ++ n_argument = pytree.Node(self.syms.argument, ++ (Name(s_kwd), ++ pytree.Leaf(token.EQUAL, "="), ++ n_expr)) ++ if l_nodes: ++ l_nodes.append(Comma()) ++ n_argument.set_prefix(" ") ++ l_nodes.append(n_argument) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_raise.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_raise.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,82 @@ ++"""Fixer for 'raise E, V, T' ++ ++raise -> raise ++raise E -> raise E ++raise E, V -> raise E(V) ++raise E, V, T -> raise E(V).with_traceback(T) ++ ++raise (((E, E'), E''), E'''), V -> raise E(V) ++raise "foo", V, T -> warns about string exceptions ++ ++ ++CAVEATS: ++1) "raise E, V" will be incorrectly translated if V is an exception ++ instance. The correct Python 3 idiom is ++ ++ raise E from V ++ ++ but since we can't detect instance-hood by syntax alone and since ++ any client code would have to be changed as well, we don't automate ++ this. ++""" ++# Author: Collin Winter ++ ++# Local imports ++from .. import pytree ++from ..pgen2 import token ++from .. import fixer_base ++from ..fixer_util import Name, Call, Attr, ArgList, is_tuple ++ ++class FixRaise(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ raise_stmt< 'raise' exc=any [',' val=any [',' tb=any]] > ++ """ ++ ++ def transform(self, node, results): ++ syms = self.syms ++ ++ exc = results["exc"].clone() ++ if exc.type is token.STRING: ++ self.cannot_convert(node, "Python 3 does not support string exceptions") ++ return ++ ++ # Python 2 supports ++ # raise ((((E1, E2), E3), E4), E5), V ++ # as a synonym for ++ # raise E1, V ++ # Since Python 3 will not support this, we recurse down any tuple ++ # literals, always taking the first element. ++ if is_tuple(exc): ++ while is_tuple(exc): ++ # exc.children[1:-1] is the unparenthesized tuple ++ # exc.children[1].children[0] is the first element of the tuple ++ exc = exc.children[1].children[0].clone() ++ exc.set_prefix(" ") ++ ++ if "val" not in results: ++ # One-argument raise ++ new = pytree.Node(syms.raise_stmt, [Name("raise"), exc]) ++ new.set_prefix(node.get_prefix()) ++ return new ++ ++ val = results["val"].clone() ++ if is_tuple(val): ++ args = [c.clone() for c in val.children[1:-1]] ++ else: ++ val.set_prefix("") ++ args = [val] ++ ++ if "tb" in results: ++ tb = results["tb"].clone() ++ tb.set_prefix("") ++ ++ e = Call(exc, args) ++ with_tb = Attr(e, Name('with_traceback')) + [ArgList([tb])] ++ new = pytree.Node(syms.simple_stmt, [Name("raise")] + with_tb) ++ new.set_prefix(node.get_prefix()) ++ return new ++ else: ++ return pytree.Node(syms.raise_stmt, ++ [Name("raise"), Call(exc, args)], ++ prefix=node.get_prefix()) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_raw_input.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_raw_input.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,16 @@ ++"""Fixer that changes raw_input(...) into input(...).""" ++# Author: Andre Roberge ++ ++# Local imports ++from .. import fixer_base ++from ..fixer_util import Name ++ ++class FixRawInput(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ power< name='raw_input' trailer< '(' [any] ')' > any* > ++ """ ++ ++ def transform(self, node, results): ++ name = results["name"] ++ name.replace(Name("input", prefix=name.get_prefix())) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_reduce.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_reduce.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,33 @@ ++# Copyright 2008 Armin Ronacher. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for reduce(). ++ ++Makes sure reduce() is imported from the functools module if reduce is ++used in that module. ++""" ++ ++from .. import pytree ++from .. import fixer_base ++from ..fixer_util import Name, Attr, touch_import ++ ++ ++ ++class FixReduce(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ power< 'reduce' ++ trailer< '(' ++ arglist< ( ++ (not(argument) any ',' ++ not(argument ++ > ++ """ ++ ++ def transform(self, node, results): ++ touch_import('functools', 'reduce', node) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_renames.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_renames.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,69 @@ ++"""Fix incompatible renames ++ ++Fixes: ++ * sys.maxint -> sys.maxsize ++""" ++# Author: Christian Heimes ++# based on Collin Winter's fix_import ++ ++# Local imports ++from .. import fixer_base ++from ..fixer_util import Name, attr_chain ++ ++MAPPING = {"sys": {"maxint" : "maxsize"}, ++ } ++LOOKUP = {} ++ ++def alternates(members): ++ return "(" + "|".join(map(repr, members)) + ")" ++ ++ ++def build_pattern(): ++ #bare = set() ++ for module, replace in MAPPING.items(): ++ for old_attr, new_attr in replace.items(): ++ LOOKUP[(module, old_attr)] = new_attr ++ #bare.add(module) ++ #bare.add(old_attr) ++ #yield """ ++ # import_name< 'import' (module=%r ++ # | dotted_as_names< any* module=%r any* >) > ++ # """ % (module, module) ++ yield """ ++ import_from< 'from' module_name=%r 'import' ++ ( attr_name=%r | import_as_name< attr_name=%r 'as' any >) > ++ """ % (module, old_attr, old_attr) ++ yield """ ++ power< module_name=%r trailer< '.' attr_name=%r > any* > ++ """ % (module, old_attr) ++ #yield """bare_name=%s""" % alternates(bare) ++ ++ ++class FixRenames(fixer_base.BaseFix): ++ PATTERN = "|".join(build_pattern()) ++ ++ order = "pre" # Pre-order tree traversal ++ ++ # Don't match the node if it's within another match ++ def match(self, node): ++ match = super(FixRenames, self).match ++ results = match(node) ++ if results: ++ if any([match(obj) for obj in attr_chain(node, "parent")]): ++ return False ++ return results ++ return False ++ ++ #def start_tree(self, tree, filename): ++ # super(FixRenames, self).start_tree(tree, filename) ++ # self.replace = {} ++ ++ def transform(self, node, results): ++ mod_name = results.get("module_name") ++ attr_name = results.get("attr_name") ++ #bare_name = results.get("bare_name") ++ #import_mod = results.get("module") ++ ++ if mod_name and attr_name: ++ new_attr = LOOKUP[(mod_name.value, attr_name.value)] ++ attr_name.replace(Name(new_attr, prefix=attr_name.get_prefix())) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_repr.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_repr.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,22 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer that transforms `xyzzy` into repr(xyzzy).""" ++ ++# Local imports ++from .. import fixer_base ++from ..fixer_util import Call, Name, parenthesize ++ ++ ++class FixRepr(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ atom < '`' expr=any '`' > ++ """ ++ ++ def transform(self, node, results): ++ expr = results["expr"].clone() ++ ++ if expr.type == self.syms.testlist1: ++ expr = parenthesize(expr) ++ return Call(Name("repr"), [expr], prefix=node.get_prefix()) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_set_literal.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_set_literal.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,52 @@ ++""" ++Optional fixer to transform set() calls to set literals. ++""" ++ ++# Author: Benjamin Peterson ++ ++from lib2to3 import fixer_base, pytree ++from lib2to3.fixer_util import token, syms ++ ++ ++ ++class FixSetLiteral(fixer_base.BaseFix): ++ ++ explicit = True ++ ++ PATTERN = """power< 'set' trailer< '(' ++ (atom=atom< '[' (items=listmaker< any ((',' any)* [',']) > ++ | ++ single=any) ']' > ++ | ++ atom< '(' items=testlist_gexp< any ((',' any)* [',']) > ')' > ++ ) ++ ')' > > ++ """ ++ ++ def transform(self, node, results): ++ single = results.get("single") ++ if single: ++ # Make a fake listmaker ++ fake = pytree.Node(syms.listmaker, [single.clone()]) ++ single.replace(fake) ++ items = fake ++ else: ++ items = results["items"] ++ ++ # Build the contents of the literal ++ literal = [pytree.Leaf(token.LBRACE, "{")] ++ literal.extend(n.clone() for n in items.children) ++ literal.append(pytree.Leaf(token.RBRACE, "}")) ++ # Set the prefix of the right brace to that of the ')' or ']' ++ literal[-1].set_prefix(items.next_sibling.get_prefix()) ++ maker = pytree.Node(syms.dictsetmaker, literal) ++ maker.set_prefix(node.get_prefix()) ++ ++ # If the original was a one tuple, we need to remove the extra comma. ++ if len(maker.children) == 4: ++ n = maker.children[2] ++ n.remove() ++ maker.children[-1].set_prefix(n.get_prefix()) ++ ++ # Finally, replace the set call with our shiny new literal. ++ return maker +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_standarderror.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_standarderror.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,18 @@ ++# Copyright 2007 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for StandardError -> Exception.""" ++ ++# Local imports ++from .. import fixer_base ++from ..fixer_util import Name ++ ++ ++class FixStandarderror(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ 'StandardError' ++ """ ++ ++ def transform(self, node, results): ++ return Name("Exception", prefix=node.get_prefix()) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_sys_exc.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_sys_exc.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,29 @@ ++"""Fixer for sys.exc_{type, value, traceback} ++ ++sys.exc_type -> sys.exc_info()[0] ++sys.exc_value -> sys.exc_info()[1] ++sys.exc_traceback -> sys.exc_info()[2] ++""" ++ ++# By Jeff Balogh and Benjamin Peterson ++ ++# Local imports ++from .. import fixer_base ++from ..fixer_util import Attr, Call, Name, Number, Subscript, Node, syms ++ ++class FixSysExc(fixer_base.BaseFix): ++ # This order matches the ordering of sys.exc_info(). ++ exc_info = ["exc_type", "exc_value", "exc_traceback"] ++ PATTERN = """ ++ power< 'sys' trailer< dot='.' attribute=(%s) > > ++ """ % '|'.join("'%s'" % e for e in exc_info) ++ ++ def transform(self, node, results): ++ sys_attr = results["attribute"][0] ++ index = Number(self.exc_info.index(sys_attr.value)) ++ ++ call = Call(Name("exc_info"), prefix=sys_attr.get_prefix()) ++ attr = Attr(Name("sys"), call) ++ attr[1].children[0].set_prefix(results["dot"].get_prefix()) ++ attr.append(Subscript(index)) ++ return Node(syms.power, attr, prefix=node.get_prefix()) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_throw.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_throw.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,56 @@ ++"""Fixer for generator.throw(E, V, T). ++ ++g.throw(E) -> g.throw(E) ++g.throw(E, V) -> g.throw(E(V)) ++g.throw(E, V, T) -> g.throw(E(V).with_traceback(T)) ++ ++g.throw("foo"[, V[, T]]) will warn about string exceptions.""" ++# Author: Collin Winter ++ ++# Local imports ++from .. import pytree ++from ..pgen2 import token ++from .. import fixer_base ++from ..fixer_util import Name, Call, ArgList, Attr, is_tuple ++ ++class FixThrow(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ power< any trailer< '.' 'throw' > ++ trailer< '(' args=arglist< exc=any ',' val=any [',' tb=any] > ')' > ++ > ++ | ++ power< any trailer< '.' 'throw' > trailer< '(' exc=any ')' > > ++ """ ++ ++ def transform(self, node, results): ++ syms = self.syms ++ ++ exc = results["exc"].clone() ++ if exc.type is token.STRING: ++ self.cannot_convert(node, "Python 3 does not support string exceptions") ++ return ++ ++ # Leave "g.throw(E)" alone ++ val = results.get("val") ++ if val is None: ++ return ++ ++ val = val.clone() ++ if is_tuple(val): ++ args = [c.clone() for c in val.children[1:-1]] ++ else: ++ val.set_prefix("") ++ args = [val] ++ ++ throw_args = results["args"] ++ ++ if "tb" in results: ++ tb = results["tb"].clone() ++ tb.set_prefix("") ++ ++ e = Call(exc, args) ++ with_tb = Attr(e, Name('with_traceback')) + [ArgList([tb])] ++ throw_args.replace(pytree.Node(syms.power, with_tb)) ++ else: ++ throw_args.replace(Call(exc, args)) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_tuple_params.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_tuple_params.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,169 @@ ++"""Fixer for function definitions with tuple parameters. ++ ++def func(((a, b), c), d): ++ ... ++ ++ -> ++ ++def func(x, d): ++ ((a, b), c) = x ++ ... ++ ++It will also support lambdas: ++ ++ lambda (x, y): x + y -> lambda t: t[0] + t[1] ++ ++ # The parens are a syntax error in Python 3 ++ lambda (x): x + y -> lambda x: x + y ++""" ++# Author: Collin Winter ++ ++# Local imports ++from .. import pytree ++from ..pgen2 import token ++from .. import fixer_base ++from ..fixer_util import Assign, Name, Newline, Number, Subscript, syms ++ ++def is_docstring(stmt): ++ return isinstance(stmt, pytree.Node) and \ ++ stmt.children[0].type == token.STRING ++ ++class FixTupleParams(fixer_base.BaseFix): ++ PATTERN = """ ++ funcdef< 'def' any parameters< '(' args=any ')' > ++ ['->' any] ':' suite=any+ > ++ | ++ lambda= ++ lambdef< 'lambda' args=vfpdef< '(' inner=any ')' > ++ ':' body=any ++ > ++ """ ++ ++ def transform(self, node, results): ++ if "lambda" in results: ++ return self.transform_lambda(node, results) ++ ++ new_lines = [] ++ suite = results["suite"] ++ args = results["args"] ++ # This crap is so "def foo(...): x = 5; y = 7" is handled correctly. ++ # TODO(cwinter): suite-cleanup ++ if suite[0].children[1].type == token.INDENT: ++ start = 2 ++ indent = suite[0].children[1].value ++ end = Newline() ++ else: ++ start = 0 ++ indent = "; " ++ end = pytree.Leaf(token.INDENT, "") ++ ++ # We need access to self for new_name(), and making this a method ++ # doesn't feel right. Closing over self and new_lines makes the ++ # code below cleaner. ++ def handle_tuple(tuple_arg, add_prefix=False): ++ n = Name(self.new_name()) ++ arg = tuple_arg.clone() ++ arg.set_prefix("") ++ stmt = Assign(arg, n.clone()) ++ if add_prefix: ++ n.set_prefix(" ") ++ tuple_arg.replace(n) ++ new_lines.append(pytree.Node(syms.simple_stmt, ++ [stmt, end.clone()])) ++ ++ if args.type == syms.tfpdef: ++ handle_tuple(args) ++ elif args.type == syms.typedargslist: ++ for i, arg in enumerate(args.children): ++ if arg.type == syms.tfpdef: ++ # Without add_prefix, the emitted code is correct, ++ # just ugly. ++ handle_tuple(arg, add_prefix=(i > 0)) ++ ++ if not new_lines: ++ return node ++ ++ # This isn't strictly necessary, but it plays nicely with other fixers. ++ # TODO(cwinter) get rid of this when children becomes a smart list ++ for line in new_lines: ++ line.parent = suite[0] ++ ++ # TODO(cwinter) suite-cleanup ++ after = start ++ if start == 0: ++ new_lines[0].set_prefix(" ") ++ elif is_docstring(suite[0].children[start]): ++ new_lines[0].set_prefix(indent) ++ after = start + 1 ++ ++ suite[0].children[after:after] = new_lines ++ for i in range(after+1, after+len(new_lines)+1): ++ suite[0].children[i].set_prefix(indent) ++ suite[0].changed() ++ ++ def transform_lambda(self, node, results): ++ args = results["args"] ++ body = results["body"] ++ inner = simplify_args(results["inner"]) ++ ++ # Replace lambda ((((x)))): x with lambda x: x ++ if inner.type == token.NAME: ++ inner = inner.clone() ++ inner.set_prefix(" ") ++ args.replace(inner) ++ return ++ ++ params = find_params(args) ++ to_index = map_to_index(params) ++ tup_name = self.new_name(tuple_name(params)) ++ ++ new_param = Name(tup_name, prefix=" ") ++ args.replace(new_param.clone()) ++ for n in body.post_order(): ++ if n.type == token.NAME and n.value in to_index: ++ subscripts = [c.clone() for c in to_index[n.value]] ++ new = pytree.Node(syms.power, ++ [new_param.clone()] + subscripts) ++ new.set_prefix(n.get_prefix()) ++ n.replace(new) ++ ++ ++### Helper functions for transform_lambda() ++ ++def simplify_args(node): ++ if node.type in (syms.vfplist, token.NAME): ++ return node ++ elif node.type == syms.vfpdef: ++ # These look like vfpdef< '(' x ')' > where x is NAME ++ # or another vfpdef instance (leading to recursion). ++ while node.type == syms.vfpdef: ++ node = node.children[1] ++ return node ++ raise RuntimeError("Received unexpected node %s" % node) ++ ++def find_params(node): ++ if node.type == syms.vfpdef: ++ return find_params(node.children[1]) ++ elif node.type == token.NAME: ++ return node.value ++ return [find_params(c) for c in node.children if c.type != token.COMMA] ++ ++def map_to_index(param_list, prefix=[], d=None): ++ if d is None: ++ d = {} ++ for i, obj in enumerate(param_list): ++ trailer = [Subscript(Number(i))] ++ if isinstance(obj, list): ++ map_to_index(obj, trailer, d=d) ++ else: ++ d[obj] = prefix + trailer ++ return d ++ ++def tuple_name(param_list): ++ l = [] ++ for obj in param_list: ++ if isinstance(obj, list): ++ l.append(tuple_name(obj)) ++ else: ++ l.append(obj) ++ return "_".join(l) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_types.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_types.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,62 @@ ++# Copyright 2007 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for removing uses of the types module. ++ ++These work for only the known names in the types module. The forms above ++can include types. or not. ie, It is assumed the module is imported either as: ++ ++ import types ++ from types import ... # either * or specific types ++ ++The import statements are not modified. ++ ++There should be another fixer that handles at least the following constants: ++ ++ type([]) -> list ++ type(()) -> tuple ++ type('') -> str ++ ++""" ++ ++# Local imports ++from ..pgen2 import token ++from .. import fixer_base ++from ..fixer_util import Name ++ ++_TYPE_MAPPING = { ++ 'BooleanType' : 'bool', ++ 'BufferType' : 'memoryview', ++ 'ClassType' : 'type', ++ 'ComplexType' : 'complex', ++ 'DictType': 'dict', ++ 'DictionaryType' : 'dict', ++ 'EllipsisType' : 'type(Ellipsis)', ++ #'FileType' : 'io.IOBase', ++ 'FloatType': 'float', ++ 'IntType': 'int', ++ 'ListType': 'list', ++ 'LongType': 'int', ++ 'ObjectType' : 'object', ++ 'NoneType': 'type(None)', ++ 'NotImplementedType' : 'type(NotImplemented)', ++ 'SliceType' : 'slice', ++ 'StringType': 'bytes', # XXX ? ++ 'StringTypes' : 'str', # XXX ? ++ 'TupleType': 'tuple', ++ 'TypeType' : 'type', ++ 'UnicodeType': 'str', ++ 'XRangeType' : 'range', ++ } ++ ++_pats = ["power< 'types' trailer< '.' name='%s' > >" % t for t in _TYPE_MAPPING] ++ ++class FixTypes(fixer_base.BaseFix): ++ ++ PATTERN = '|'.join(_pats) ++ ++ def transform(self, node, results): ++ new_value = _TYPE_MAPPING.get(results["name"].value) ++ if new_value: ++ return Name(new_value, prefix=node.get_prefix()) ++ return None +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_unicode.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_unicode.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,28 @@ ++"""Fixer that changes unicode to str, unichr to chr, and u"..." into "...". ++ ++""" ++ ++import re ++from ..pgen2 import token ++from .. import fixer_base ++ ++class FixUnicode(fixer_base.BaseFix): ++ ++ PATTERN = "STRING | NAME<'unicode' | 'unichr'>" ++ ++ def transform(self, node, results): ++ if node.type == token.NAME: ++ if node.value == "unicode": ++ new = node.clone() ++ new.value = "str" ++ return new ++ if node.value == "unichr": ++ new = node.clone() ++ new.value = "chr" ++ return new ++ # XXX Warn when __unicode__ found? ++ elif node.type == token.STRING: ++ if re.match(r"[uU][rR]?[\'\"]", node.value): ++ new = node.clone() ++ new.value = new.value[1:] ++ return new +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_urllib.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_urllib.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,180 @@ ++"""Fix changes imports of urllib which are now incompatible. ++ This is rather similar to fix_imports, but because of the more ++ complex nature of the fixing for urllib, it has its own fixer. ++""" ++# Author: Nick Edds ++ ++# Local imports ++from .fix_imports import alternates, FixImports ++from .. import fixer_base ++from ..fixer_util import Name, Comma, FromImport, Newline, attr_chain ++ ++MAPPING = {'urllib': [ ++ ('urllib.request', ++ ['URLOpener', 'FancyURLOpener', 'urlretrieve', ++ '_urlopener', 'urlcleanup']), ++ ('urllib.parse', ++ ['quote', 'quote_plus', 'unquote', 'unquote_plus', ++ 'urlencode', 'pathname2url', 'url2pathname', 'splitattr', ++ 'splithost', 'splitnport', 'splitpasswd', 'splitport', ++ 'splitquery', 'splittag', 'splittype', 'splituser', ++ 'splitvalue', ]), ++ ('urllib.error', ++ ['ContentTooShortError'])], ++ 'urllib2' : [ ++ ('urllib.request', ++ ['urlopen', 'install_opener', 'build_opener', ++ 'Request', 'OpenerDirector', 'BaseHandler', ++ 'HTTPDefaultErrorHandler', 'HTTPRedirectHandler', ++ 'HTTPCookieProcessor', 'ProxyHandler', ++ 'HTTPPasswordMgr', ++ 'HTTPPasswordMgrWithDefaultRealm', ++ 'AbstractBasicAuthHandler', ++ 'HTTPBasicAuthHandler', 'ProxyBasicAuthHandler', ++ 'AbstractDigestAuthHandler', ++ 'HTTPDigestAuthHandler', 'ProxyDigestAuthHandler', ++ 'HTTPHandler', 'HTTPSHandler', 'FileHandler', ++ 'FTPHandler', 'CacheFTPHandler', ++ 'UnknownHandler']), ++ ('urllib.error', ++ ['URLError', 'HTTPError']), ++ ] ++} ++ ++# Duplicate the url parsing functions for urllib2. ++MAPPING["urllib2"].append(MAPPING["urllib"][1]) ++ ++ ++def build_pattern(): ++ bare = set() ++ for old_module, changes in MAPPING.items(): ++ for change in changes: ++ new_module, members = change ++ members = alternates(members) ++ yield """import_name< 'import' (module=%r ++ | dotted_as_names< any* module=%r any* >) > ++ """ % (old_module, old_module) ++ yield """import_from< 'from' mod_member=%r 'import' ++ ( member=%s | import_as_name< member=%s 'as' any > | ++ import_as_names< members=any* >) > ++ """ % (old_module, members, members) ++ yield """import_from< 'from' module_star=%r 'import' star='*' > ++ """ % old_module ++ yield """import_name< 'import' ++ dotted_as_name< module_as=%r 'as' any > > ++ """ % old_module ++ yield """power< module_dot=%r trailer< '.' member=%s > any* > ++ """ % (old_module, members) ++ ++ ++class FixUrllib(FixImports): ++ ++ def build_pattern(self): ++ return "|".join(build_pattern()) ++ ++ def transform_import(self, node, results): ++ """Transform for the basic import case. Replaces the old ++ import name with a comma separated list of its ++ replacements. ++ """ ++ import_mod = results.get('module') ++ pref = import_mod.get_prefix() ++ ++ names = [] ++ ++ # create a Node list of the replacement modules ++ for name in MAPPING[import_mod.value][:-1]: ++ names.extend([Name(name[0], prefix=pref), Comma()]) ++ names.append(Name(MAPPING[import_mod.value][-1][0], prefix=pref)) ++ import_mod.replace(names) ++ ++ def transform_member(self, node, results): ++ """Transform for imports of specific module elements. Replaces ++ the module to be imported from with the appropriate new ++ module. ++ """ ++ mod_member = results.get('mod_member') ++ pref = mod_member.get_prefix() ++ member = results.get('member') ++ ++ # Simple case with only a single member being imported ++ if member: ++ # this may be a list of length one, or just a node ++ if isinstance(member, list): ++ member = member[0] ++ new_name = None ++ for change in MAPPING[mod_member.value]: ++ if member.value in change[1]: ++ new_name = change[0] ++ break ++ if new_name: ++ mod_member.replace(Name(new_name, prefix=pref)) ++ else: ++ self.cannot_convert(node, ++ 'This is an invalid module element') ++ ++ # Multiple members being imported ++ else: ++ # a dictionary for replacements, order matters ++ modules = [] ++ mod_dict = {} ++ members = results.get('members') ++ for member in members: ++ member = member.value ++ # we only care about the actual members ++ if member != ',': ++ for change in MAPPING[mod_member.value]: ++ if member in change[1]: ++ if change[0] in mod_dict: ++ mod_dict[change[0]].append(member) ++ else: ++ mod_dict[change[0]] = [member] ++ modules.append(change[0]) ++ ++ new_nodes = [] ++ for module in modules: ++ elts = mod_dict[module] ++ names = [] ++ for elt in elts[:-1]: ++ names.extend([Name(elt, prefix=pref), Comma()]) ++ names.append(Name(elts[-1], prefix=pref)) ++ new_nodes.append(FromImport(module, names)) ++ if new_nodes: ++ nodes = [] ++ for new_node in new_nodes[:-1]: ++ nodes.extend([new_node, Newline()]) ++ nodes.append(new_nodes[-1]) ++ node.replace(nodes) ++ else: ++ self.cannot_convert(node, 'All module elements are invalid') ++ ++ def transform_dot(self, node, results): ++ """Transform for calls to module members in code.""" ++ module_dot = results.get('module_dot') ++ member = results.get('member') ++ # this may be a list of length one, or just a node ++ if isinstance(member, list): ++ member = member[0] ++ new_name = None ++ for change in MAPPING[module_dot.value]: ++ if member.value in change[1]: ++ new_name = change[0] ++ break ++ if new_name: ++ module_dot.replace(Name(new_name, ++ prefix=module_dot.get_prefix())) ++ else: ++ self.cannot_convert(node, 'This is an invalid module element') ++ ++ def transform(self, node, results): ++ if results.get('module'): ++ self.transform_import(node, results) ++ elif results.get('mod_member'): ++ self.transform_member(node, results) ++ elif results.get('module_dot'): ++ self.transform_dot(node, results) ++ # Renaming and star imports are not supported for these modules. ++ elif results.get('module_star'): ++ self.cannot_convert(node, 'Cannot handle star imports.') ++ elif results.get('module_as'): ++ self.cannot_convert(node, 'This module is now multiple modules') +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_ws_comma.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_ws_comma.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,39 @@ ++"""Fixer that changes 'a ,b' into 'a, b'. ++ ++This also changes '{a :b}' into '{a: b}', but does not touch other ++uses of colons. It does not touch other uses of whitespace. ++ ++""" ++ ++from .. import pytree ++from ..pgen2 import token ++from .. import fixer_base ++ ++class FixWsComma(fixer_base.BaseFix): ++ ++ explicit = True # The user must ask for this fixers ++ ++ PATTERN = """ ++ any<(not(',') any)+ ',' ((not(',') any)+ ',')* [not(',') any]> ++ """ ++ ++ COMMA = pytree.Leaf(token.COMMA, ",") ++ COLON = pytree.Leaf(token.COLON, ":") ++ SEPS = (COMMA, COLON) ++ ++ def transform(self, node, results): ++ new = node.clone() ++ comma = False ++ for child in new.children: ++ if child in self.SEPS: ++ prefix = child.get_prefix() ++ if prefix.isspace() and "\n" not in prefix: ++ child.set_prefix("") ++ comma = True ++ else: ++ if comma: ++ prefix = child.get_prefix() ++ if not prefix: ++ child.set_prefix(" ") ++ comma = False ++ return new +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_xrange.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_xrange.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,64 @@ ++# Copyright 2007 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer that changes xrange(...) into range(...).""" ++ ++# Local imports ++from .. import fixer_base ++from ..fixer_util import Name, Call, consuming_calls ++from .. import patcomp ++ ++ ++class FixXrange(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ power< ++ (name='range'|name='xrange') trailer< '(' args=any ')' > ++ rest=any* > ++ """ ++ ++ def transform(self, node, results): ++ name = results["name"] ++ if name.value == "xrange": ++ return self.transform_xrange(node, results) ++ elif name.value == "range": ++ return self.transform_range(node, results) ++ else: ++ raise ValueError(repr(name)) ++ ++ def transform_xrange(self, node, results): ++ name = results["name"] ++ name.replace(Name("range", prefix=name.get_prefix())) ++ ++ def transform_range(self, node, results): ++ if not self.in_special_context(node): ++ range_call = Call(Name("range"), [results["args"].clone()]) ++ # Encase the range call in list(). ++ list_call = Call(Name("list"), [range_call], ++ prefix=node.get_prefix()) ++ # Put things that were after the range() call after the list call. ++ for n in results["rest"]: ++ list_call.append_child(n) ++ return list_call ++ return node ++ ++ P1 = "power< func=NAME trailer< '(' node=any ')' > any* >" ++ p1 = patcomp.compile_pattern(P1) ++ ++ P2 = """for_stmt< 'for' any 'in' node=any ':' any* > ++ | comp_for< 'for' any 'in' node=any any* > ++ | comparison< any 'in' node=any any*> ++ """ ++ p2 = patcomp.compile_pattern(P2) ++ ++ def in_special_context(self, node): ++ if node.parent is None: ++ return False ++ results = {} ++ if (node.parent.parent is not None and ++ self.p1.match(node.parent.parent, results) and ++ results["node"] is node): ++ # list(d.keys()) -> list(d.keys()), etc. ++ return results["func"].value in consuming_calls ++ # for ... in d.iterkeys() -> for ... in d.keys(), etc. ++ return self.p2.match(node.parent, results) and results["node"] is node +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_xreadlines.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_xreadlines.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,24 @@ ++"""Fix "for x in f.xreadlines()" -> "for x in f". ++ ++This fixer will also convert g(f.xreadlines) into g(f.__iter__).""" ++# Author: Collin Winter ++ ++# Local imports ++from .. import fixer_base ++from ..fixer_util import Name ++ ++ ++class FixXreadlines(fixer_base.BaseFix): ++ PATTERN = """ ++ power< call=any+ trailer< '.' 'xreadlines' > trailer< '(' ')' > > ++ | ++ power< any+ trailer< '.' no_call='xreadlines' > > ++ """ ++ ++ def transform(self, node, results): ++ no_call = results.get("no_call") ++ ++ if no_call: ++ no_call.replace(Name("__iter__", prefix=no_call.get_prefix())) ++ else: ++ node.replace([x.clone() for x in results["call"]]) +diff -r 531f2e948299 refactor/fixes/.svn/text-base/fix_zip.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/.svn/text-base/fix_zip.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,34 @@ ++""" ++Fixer that changes zip(seq0, seq1, ...) into list(zip(seq0, seq1, ...) ++unless there exists a 'from future_builtins import zip' statement in the ++top-level namespace. ++ ++We avoid the transformation if the zip() call is directly contained in ++iter(<>), list(<>), tuple(<>), sorted(<>), ...join(<>), or for V in <>:. ++""" ++ ++# Local imports ++from .. import fixer_base ++from ..fixer_util import Name, Call, in_special_context ++ ++class FixZip(fixer_base.ConditionalFix): ++ ++ PATTERN = """ ++ power< 'zip' args=trailer< '(' [any] ')' > ++ > ++ """ ++ ++ skip_on = "future_builtins.zip" ++ ++ def transform(self, node, results): ++ if self.should_skip(node): ++ return ++ ++ if in_special_context(node): ++ return None ++ ++ new = node.clone() ++ new.set_prefix("") ++ new = Call(Name("list"), [new]) ++ new.set_prefix(node.get_prefix()) ++ return new +diff -r 531f2e948299 refactor/fixes/__init__.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/__init__.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,3 @@ ++from . import from2 ++from . import from3 ++from .from2 import * +diff -r 531f2e948299 refactor/fixes/fixer_common.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/fixer_common.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,4 @@ ++# Common fixer imports ++from .. import fixer_base ++from ..fixer_util import Name, Call, consuming_calls, attr_chain ++from .. import patcomp +diff -r 531f2e948299 refactor/fixes/from2/__init__.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/__init__.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,49 @@ ++from . import fix_apply ++from . import fix_basestring ++from . import fix_buffer ++from . import fix_callable ++from . import fix_dict ++from . import fix_except ++from . import fix_exec ++from . import fix_execfile ++from . import fix_filter ++from . import fix_funcattrs ++from . import fix_future ++from . import fix_getcwdu ++from . import fix_has_key ++from . import fix_idioms ++from . import fix_import ++from . import fix_imports ++from . import fix_imports2 ++from . import fix_input ++from . import fix_intern ++from . import fix_isinstance ++from . import fix_itertools ++from . import fix_itertools_imports ++from . import fix_long ++from . import fix_map ++from . import fix_metaclass ++from . import fix_methodattrs ++from . import fix_ne ++from . import fix_next ++from . import fix_nonzero ++from . import fix_numliterals ++from . import fix_paren ++from . import fix_print ++from . import fix_raise ++from . import fix_raw_input ++from . import fix_reduce ++from . import fix_renames ++from . import fix_repr ++from . import fix_set_literal ++from . import fix_standarderror ++from . import fix_sys_exc ++from . import fix_throw ++from . import fix_tuple_params ++from . import fix_types ++from . import fix_unicode ++from . import fix_urllib ++from . import fix_ws_comma ++from . import fix_xrange ++from . import fix_xreadlines ++from . import fix_zip +diff -r 531f2e948299 refactor/fixes/from2/fix_apply.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_apply.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,58 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for apply(). ++ ++This converts apply(func, v, k) into (func)(*v, **k).""" ++ ++# Local imports ++from ... import pytree ++from ...pgen2 import token ++from ... import fixer_base ++from ...fixer_util import Call, Comma, parenthesize ++ ++class FixApply(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ power< 'apply' ++ trailer< ++ '(' ++ arglist< ++ (not argument ++ ')' ++ > ++ > ++ """ ++ ++ def transform(self, node, results): ++ syms = self.syms ++ assert results ++ func = results["func"] ++ args = results["args"] ++ kwds = results.get("kwds") ++ prefix = node.get_prefix() ++ func = func.clone() ++ if (func.type not in (token.NAME, syms.atom) and ++ (func.type != syms.power or ++ func.children[-2].type == token.DOUBLESTAR)): ++ # Need to parenthesize ++ func = parenthesize(func) ++ func.set_prefix("") ++ args = args.clone() ++ args.set_prefix("") ++ if kwds is not None: ++ kwds = kwds.clone() ++ kwds.set_prefix("") ++ l_newargs = [pytree.Leaf(token.STAR, "*"), args] ++ if kwds is not None: ++ l_newargs.extend([Comma(), ++ pytree.Leaf(token.DOUBLESTAR, "**"), ++ kwds]) ++ l_newargs[-2].set_prefix(" ") # that's the ** token ++ # XXX Sometimes we could be cleverer, e.g. apply(f, (x, y) + t) ++ # can be translated into f(x, y, *t) instead of f(*(x, y) + t) ++ #new = pytree.Node(syms.power, (func, ArgList(l_newargs))) ++ return Call(func, l_newargs, prefix=prefix) +diff -r 531f2e948299 refactor/fixes/from2/fix_basestring.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_basestring.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,13 @@ ++"""Fixer for basestring -> str.""" ++# Author: Christian Heimes ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import Name ++ ++class FixBasestring(fixer_base.BaseFix): ++ ++ PATTERN = "'basestring'" ++ ++ def transform(self, node, results): ++ return Name("str", prefix=node.get_prefix()) +diff -r 531f2e948299 refactor/fixes/from2/fix_buffer.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_buffer.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,21 @@ ++# Copyright 2007 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer that changes buffer(...) into memoryview(...).""" ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import Name ++ ++ ++class FixBuffer(fixer_base.BaseFix): ++ ++ explicit = True # The user must ask for this fixer ++ ++ PATTERN = """ ++ power< name='buffer' trailer< '(' [any] ')' > > ++ """ ++ ++ def transform(self, node, results): ++ name = results["name"] ++ name.replace(Name("memoryview", prefix=name.get_prefix())) +diff -r 531f2e948299 refactor/fixes/from2/fix_callable.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_callable.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,31 @@ ++# Copyright 2007 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for callable(). ++ ++This converts callable(obj) into hasattr(obj, '__call__').""" ++ ++# Local imports ++from ... import pytree ++from ... import fixer_base ++from ...fixer_util import Call, Name, String ++ ++class FixCallable(fixer_base.BaseFix): ++ ++ # Ignore callable(*args) or use of keywords. ++ # Either could be a hint that the builtin callable() is not being used. ++ PATTERN = """ ++ power< 'callable' ++ trailer< lpar='(' ++ ( not(arglist | argument) any ','> ) ++ rpar=')' > ++ after=any* ++ > ++ """ ++ ++ def transform(self, node, results): ++ func = results["func"] ++ ++ args = [func.clone(), String(', '), String("'__call__'")] ++ return Call(Name("hasattr"), args, prefix=node.get_prefix()) +diff -r 531f2e948299 refactor/fixes/from2/fix_dict.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_dict.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,99 @@ ++# Copyright 2007 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for dict methods. ++ ++d.keys() -> list(d.keys()) ++d.items() -> list(d.items()) ++d.values() -> list(d.values()) ++ ++d.iterkeys() -> iter(d.keys()) ++d.iteritems() -> iter(d.items()) ++d.itervalues() -> iter(d.values()) ++ ++Except in certain very specific contexts: the iter() can be dropped ++when the context is list(), sorted(), iter() or for...in; the list() ++can be dropped when the context is list() or sorted() (but not iter() ++or for...in!). Special contexts that apply to both: list(), sorted(), tuple() ++set(), any(), all(), sum(). ++ ++Note: iter(d.keys()) could be written as iter(d) but since the ++original d.iterkeys() was also redundant we don't fix this. And there ++are (rare) contexts where it makes a difference (e.g. when passing it ++as an argument to a function that introspects the argument). ++""" ++ ++# Local imports ++from ... import pytree ++from ... import patcomp ++from ...pgen2 import token ++from ... import fixer_base ++from ...fixer_util import Name, Call, LParen, RParen, ArgList, Dot ++from ... import fixer_util ++ ++ ++iter_exempt = fixer_util.consuming_calls | set(["iter"]) ++ ++ ++class FixDict(fixer_base.BaseFix): ++ PATTERN = """ ++ power< head=any+ ++ trailer< '.' method=('keys'|'items'|'values'| ++ 'iterkeys'|'iteritems'|'itervalues') > ++ parens=trailer< '(' ')' > ++ tail=any* ++ > ++ """ ++ ++ def transform(self, node, results): ++ head = results["head"] ++ method = results["method"][0] # Extract node for method name ++ tail = results["tail"] ++ syms = self.syms ++ method_name = method.value ++ isiter = method_name.startswith("iter") ++ if isiter: ++ method_name = method_name[4:] ++ assert method_name in ("keys", "items", "values"), repr(method) ++ head = [n.clone() for n in head] ++ tail = [n.clone() for n in tail] ++ special = not tail and self.in_special_context(node, isiter) ++ args = head + [pytree.Node(syms.trailer, ++ [Dot(), ++ Name(method_name, ++ prefix=method.get_prefix())]), ++ results["parens"].clone()] ++ new = pytree.Node(syms.power, args) ++ if not special: ++ new.set_prefix("") ++ new = Call(Name(isiter and "iter" or "list"), [new]) ++ if tail: ++ new = pytree.Node(syms.power, [new] + tail) ++ new.set_prefix(node.get_prefix()) ++ return new ++ ++ P1 = "power< func=NAME trailer< '(' node=any ')' > any* >" ++ p1 = patcomp.compile_pattern(P1) ++ ++ P2 = """for_stmt< 'for' any 'in' node=any ':' any* > ++ | comp_for< 'for' any 'in' node=any any* > ++ """ ++ p2 = patcomp.compile_pattern(P2) ++ ++ def in_special_context(self, node, isiter): ++ if node.parent is None: ++ return False ++ results = {} ++ if (node.parent.parent is not None and ++ self.p1.match(node.parent.parent, results) and ++ results["node"] is node): ++ if isiter: ++ # iter(d.iterkeys()) -> iter(d.keys()), etc. ++ return results["func"].value in iter_exempt ++ else: ++ # list(d.keys()) -> list(d.keys()), etc. ++ return results["func"].value in fixer_util.consuming_calls ++ if not isiter: ++ return False ++ # for ... in d.iterkeys() -> for ... in d.keys(), etc. ++ return self.p2.match(node.parent, results) and results["node"] is node +diff -r 531f2e948299 refactor/fixes/from2/fix_except.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_except.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,92 @@ ++"""Fixer for except statements with named exceptions. ++ ++The following cases will be converted: ++ ++- "except E, T:" where T is a name: ++ ++ except E as T: ++ ++- "except E, T:" where T is not a name, tuple or list: ++ ++ except E as t: ++ T = t ++ ++ This is done because the target of an "except" clause must be a ++ name. ++ ++- "except E, T:" where T is a tuple or list literal: ++ ++ except E as t: ++ T = t.args ++""" ++# Author: Collin Winter ++ ++# Local imports ++from ... import pytree ++from ...pgen2 import token ++from ... import fixer_base ++from ...fixer_util import Assign, Attr, Name, is_tuple, is_list, syms ++ ++def find_excepts(nodes): ++ for i, n in enumerate(nodes): ++ if n.type == syms.except_clause: ++ if n.children[0].value == 'except': ++ yield (n, nodes[i+2]) ++ ++class FixExcept(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ try_stmt< 'try' ':' suite ++ cleanup=(except_clause ':' suite)+ ++ tail=(['except' ':' suite] ++ ['else' ':' suite] ++ ['finally' ':' suite]) > ++ """ ++ ++ def transform(self, node, results): ++ syms = self.syms ++ ++ tail = [n.clone() for n in results["tail"]] ++ ++ try_cleanup = [ch.clone() for ch in results["cleanup"]] ++ for except_clause, e_suite in find_excepts(try_cleanup): ++ if len(except_clause.children) == 4: ++ (E, comma, N) = except_clause.children[1:4] ++ comma.replace(Name("as", prefix=" ")) ++ ++ if N.type != token.NAME: ++ # Generate a new N for the except clause ++ new_N = Name(self.new_name(), prefix=" ") ++ target = N.clone() ++ target.set_prefix("") ++ N.replace(new_N) ++ new_N = new_N.clone() ++ ++ # Insert "old_N = new_N" as the first statement in ++ # the except body. This loop skips leading whitespace ++ # and indents ++ #TODO(cwinter) suite-cleanup ++ suite_stmts = e_suite.children ++ for i, stmt in enumerate(suite_stmts): ++ if isinstance(stmt, pytree.Node): ++ break ++ ++ # The assignment is different if old_N is a tuple or list ++ # In that case, the assignment is old_N = new_N.args ++ if is_tuple(N) or is_list(N): ++ assign = Assign(target, Attr(new_N, Name('args'))) ++ else: ++ assign = Assign(target, new_N) ++ ++ #TODO(cwinter) stopgap until children becomes a smart list ++ for child in reversed(suite_stmts[:i]): ++ e_suite.insert_child(0, child) ++ e_suite.insert_child(i, assign) ++ elif N.get_prefix() == "": ++ # No space after a comma is legal; no space after "as", ++ # not so much. ++ N.set_prefix(" ") ++ ++ #TODO(cwinter) fix this when children becomes a smart list ++ children = [c.clone() for c in node.children[:3]] + try_cleanup + tail ++ return pytree.Node(node.type, children) +diff -r 531f2e948299 refactor/fixes/from2/fix_exec.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_exec.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,39 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for exec. ++ ++This converts usages of the exec statement into calls to a built-in ++exec() function. ++ ++exec code in ns1, ns2 -> exec(code, ns1, ns2) ++""" ++ ++# Local imports ++from ... import pytree ++from ... import fixer_base ++from ...fixer_util import Comma, Name, Call ++ ++ ++class FixExec(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ exec_stmt< 'exec' a=any 'in' b=any [',' c=any] > ++ | ++ exec_stmt< 'exec' (not atom<'(' [any] ')'>) a=any > ++ """ ++ ++ def transform(self, node, results): ++ assert results ++ syms = self.syms ++ a = results["a"] ++ b = results.get("b") ++ c = results.get("c") ++ args = [a.clone()] ++ args[0].set_prefix("") ++ if b is not None: ++ args.extend([Comma(), b.clone()]) ++ if c is not None: ++ args.extend([Comma(), c.clone()]) ++ ++ return Call(Name("exec"), args, prefix=node.get_prefix()) +diff -r 531f2e948299 refactor/fixes/from2/fix_execfile.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_execfile.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,51 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for execfile. ++ ++This converts usages of the execfile function into calls to the built-in ++exec() function. ++""" ++ ++from ... import fixer_base ++from ...fixer_util import (Comma, Name, Call, LParen, RParen, Dot, Node, ++ ArgList, String, syms) ++ ++ ++class FixExecfile(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ power< 'execfile' trailer< '(' arglist< filename=any [',' globals=any [',' locals=any ] ] > ')' > > ++ | ++ power< 'execfile' trailer< '(' filename=any ')' > > ++ """ ++ ++ def transform(self, node, results): ++ assert results ++ filename = results["filename"] ++ globals = results.get("globals") ++ locals = results.get("locals") ++ ++ # Copy over the prefix from the right parentheses end of the execfile ++ # call. ++ execfile_paren = node.children[-1].children[-1].clone() ++ # Construct open().read(). ++ open_args = ArgList([filename.clone()], rparen=execfile_paren) ++ open_call = Node(syms.power, [Name("open"), open_args]) ++ read = [Node(syms.trailer, [Dot(), Name('read')]), ++ Node(syms.trailer, [LParen(), RParen()])] ++ open_expr = [open_call] + read ++ # Wrap the open call in a compile call. This is so the filename will be ++ # preserved in the execed code. ++ filename_arg = filename.clone() ++ filename_arg.set_prefix(" ") ++ exec_str = String("'exec'", " ") ++ compile_args = open_expr + [Comma(), filename_arg, Comma(), exec_str] ++ compile_call = Call(Name("compile"), compile_args, "") ++ # Finally, replace the execfile call with an exec call. ++ args = [compile_call] ++ if globals is not None: ++ args.extend([Comma(), globals.clone()]) ++ if locals is not None: ++ args.extend([Comma(), locals.clone()]) ++ return Call(Name("exec"), args, prefix=node.get_prefix()) +diff -r 531f2e948299 refactor/fixes/from2/fix_filter.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_filter.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,75 @@ ++# Copyright 2007 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer that changes filter(F, X) into list(filter(F, X)). ++ ++We avoid the transformation if the filter() call is directly contained ++in iter(<>), list(<>), tuple(<>), sorted(<>), ...join(<>), or ++for V in <>:. ++ ++NOTE: This is still not correct if the original code was depending on ++filter(F, X) to return a string if X is a string and a tuple if X is a ++tuple. That would require type inference, which we don't do. Let ++Python 2.6 figure it out. ++""" ++ ++# Local imports ++from ...pgen2 import token ++from ... import fixer_base ++from ...fixer_util import Name, Call, ListComp, in_special_context ++ ++class FixFilter(fixer_base.ConditionalFix): ++ ++ PATTERN = """ ++ filter_lambda=power< ++ 'filter' ++ trailer< ++ '(' ++ arglist< ++ lambdef< 'lambda' ++ (fp=NAME | vfpdef< '(' fp=NAME ')'> ) ':' xp=any ++ > ++ ',' ++ it=any ++ > ++ ')' ++ > ++ > ++ | ++ power< ++ 'filter' ++ trailer< '(' arglist< none='None' ',' seq=any > ')' > ++ > ++ | ++ power< ++ 'filter' ++ args=trailer< '(' [any] ')' > ++ > ++ """ ++ ++ skip_on = "future_builtins.filter" ++ ++ def transform(self, node, results): ++ if self.should_skip(node): ++ return ++ ++ if "filter_lambda" in results: ++ new = ListComp(results.get("fp").clone(), ++ results.get("fp").clone(), ++ results.get("it").clone(), ++ results.get("xp").clone()) ++ ++ elif "none" in results: ++ new = ListComp(Name("_f"), ++ Name("_f"), ++ results["seq"].clone(), ++ Name("_f")) ++ ++ else: ++ if in_special_context(node): ++ return None ++ new = node.clone() ++ new.set_prefix("") ++ new = Call(Name("list"), [new]) ++ new.set_prefix(node.get_prefix()) ++ return new +diff -r 531f2e948299 refactor/fixes/from2/fix_funcattrs.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_funcattrs.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,19 @@ ++"""Fix function attribute names (f.func_x -> f.__x__).""" ++# Author: Collin Winter ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import Name ++ ++ ++class FixFuncattrs(fixer_base.BaseFix): ++ PATTERN = """ ++ power< any+ trailer< '.' attr=('func_closure' | 'func_doc' | 'func_globals' ++ | 'func_name' | 'func_defaults' | 'func_code' ++ | 'func_dict') > any* > ++ """ ++ ++ def transform(self, node, results): ++ attr = results["attr"][0] ++ attr.replace(Name(("__%s__" % attr.value[5:]), ++ prefix=attr.get_prefix())) +diff -r 531f2e948299 refactor/fixes/from2/fix_future.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_future.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,20 @@ ++"""Remove __future__ imports ++ ++from __future__ import foo is replaced with an empty line. ++""" ++# Author: Christian Heimes ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import BlankLine ++ ++class FixFuture(fixer_base.BaseFix): ++ PATTERN = """import_from< 'from' module_name="__future__" 'import' any >""" ++ ++ # This should be run last -- some things check for the import ++ run_order = 10 ++ ++ def transform(self, node, results): ++ new = BlankLine() ++ new.prefix = node.get_prefix() ++ return new +diff -r 531f2e948299 refactor/fixes/from2/fix_getcwdu.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_getcwdu.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,18 @@ ++""" ++Fixer that changes os.getcwdu() to os.getcwd(). ++""" ++# Author: Victor Stinner ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import Name ++ ++class FixGetcwdu(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ power< 'os' trailer< dot='.' name='getcwdu' > any* > ++ """ ++ ++ def transform(self, node, results): ++ name = results["name"] ++ name.replace(Name("getcwd", prefix=name.get_prefix())) +diff -r 531f2e948299 refactor/fixes/from2/fix_has_key.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_has_key.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,109 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for has_key(). ++ ++Calls to .has_key() methods are expressed in terms of the 'in' ++operator: ++ ++ d.has_key(k) -> k in d ++ ++CAVEATS: ++1) While the primary target of this fixer is dict.has_key(), the ++ fixer will change any has_key() method call, regardless of its ++ class. ++ ++2) Cases like this will not be converted: ++ ++ m = d.has_key ++ if m(k): ++ ... ++ ++ Only *calls* to has_key() are converted. While it is possible to ++ convert the above to something like ++ ++ m = d.__contains__ ++ if m(k): ++ ... ++ ++ this is currently not done. ++""" ++ ++# Local imports ++from ... import pytree ++from ...pgen2 import token ++from ... import fixer_base ++from ...fixer_util import Name, parenthesize ++ ++ ++class FixHasKey(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ anchor=power< ++ before=any+ ++ trailer< '.' 'has_key' > ++ trailer< ++ '(' ++ ( not(arglist | argument) arg=any ','> ++ ) ++ ')' ++ > ++ after=any* ++ > ++ | ++ negation=not_test< ++ 'not' ++ anchor=power< ++ before=any+ ++ trailer< '.' 'has_key' > ++ trailer< ++ '(' ++ ( not(arglist | argument) arg=any ','> ++ ) ++ ')' ++ > ++ > ++ > ++ """ ++ ++ def transform(self, node, results): ++ assert results ++ syms = self.syms ++ if (node.parent.type == syms.not_test and ++ self.pattern.match(node.parent)): ++ # Don't transform a node matching the first alternative of the ++ # pattern when its parent matches the second alternative ++ return None ++ negation = results.get("negation") ++ anchor = results["anchor"] ++ prefix = node.get_prefix() ++ before = [n.clone() for n in results["before"]] ++ arg = results["arg"].clone() ++ after = results.get("after") ++ if after: ++ after = [n.clone() for n in after] ++ if arg.type in (syms.comparison, syms.not_test, syms.and_test, ++ syms.or_test, syms.test, syms.lambdef, syms.argument): ++ arg = parenthesize(arg) ++ if len(before) == 1: ++ before = before[0] ++ else: ++ before = pytree.Node(syms.power, before) ++ before.set_prefix(" ") ++ n_op = Name("in", prefix=" ") ++ if negation: ++ n_not = Name("not", prefix=" ") ++ n_op = pytree.Node(syms.comp_op, (n_not, n_op)) ++ new = pytree.Node(syms.comparison, (arg, n_op, before)) ++ if after: ++ new = parenthesize(new) ++ new = pytree.Node(syms.power, (new,) + tuple(after)) ++ if node.parent.type in (syms.comparison, syms.expr, syms.xor_expr, ++ syms.and_expr, syms.shift_expr, ++ syms.arith_expr, syms.term, ++ syms.factor, syms.power): ++ new = parenthesize(new) ++ new.set_prefix(prefix) ++ return new +diff -r 531f2e948299 refactor/fixes/from2/fix_idioms.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_idioms.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,134 @@ ++"""Adjust some old Python 2 idioms to their modern counterparts. ++ ++* Change some type comparisons to isinstance() calls: ++ type(x) == T -> isinstance(x, T) ++ type(x) is T -> isinstance(x, T) ++ type(x) != T -> not isinstance(x, T) ++ type(x) is not T -> not isinstance(x, T) ++ ++* Change "while 1:" into "while True:". ++ ++* Change both ++ ++ v = list(EXPR) ++ v.sort() ++ foo(v) ++ ++and the more general ++ ++ v = EXPR ++ v.sort() ++ foo(v) ++ ++into ++ ++ v = sorted(EXPR) ++ foo(v) ++""" ++# Author: Jacques Frechet, Collin Winter ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import Call, Comma, Name, Node, syms ++ ++CMP = "(n='!=' | '==' | 'is' | n=comp_op< 'is' 'not' >)" ++TYPE = "power< 'type' trailer< '(' x=any ')' > >" ++ ++class FixIdioms(fixer_base.BaseFix): ++ ++ explicit = True # The user must ask for this fixer ++ ++ PATTERN = r""" ++ isinstance=comparison< %s %s T=any > ++ | ++ isinstance=comparison< T=any %s %s > ++ | ++ while_stmt< 'while' while='1' ':' any+ > ++ | ++ sorted=any< ++ any* ++ simple_stmt< ++ expr_stmt< id1=any '=' ++ power< list='list' trailer< '(' (not arglist) any ')' > > ++ > ++ '\n' ++ > ++ sort= ++ simple_stmt< ++ power< id2=any ++ trailer< '.' 'sort' > trailer< '(' ')' > ++ > ++ '\n' ++ > ++ next=any* ++ > ++ | ++ sorted=any< ++ any* ++ simple_stmt< expr_stmt< id1=any '=' expr=any > '\n' > ++ sort= ++ simple_stmt< ++ power< id2=any ++ trailer< '.' 'sort' > trailer< '(' ')' > ++ > ++ '\n' ++ > ++ next=any* ++ > ++ """ % (TYPE, CMP, CMP, TYPE) ++ ++ def match(self, node): ++ r = super(FixIdioms, self).match(node) ++ # If we've matched one of the sort/sorted subpatterns above, we ++ # want to reject matches where the initial assignment and the ++ # subsequent .sort() call involve different identifiers. ++ if r and "sorted" in r: ++ if r["id1"] == r["id2"]: ++ return r ++ return None ++ return r ++ ++ def transform(self, node, results): ++ if "isinstance" in results: ++ return self.transform_isinstance(node, results) ++ elif "while" in results: ++ return self.transform_while(node, results) ++ elif "sorted" in results: ++ return self.transform_sort(node, results) ++ else: ++ raise RuntimeError("Invalid match") ++ ++ def transform_isinstance(self, node, results): ++ x = results["x"].clone() # The thing inside of type() ++ T = results["T"].clone() # The type being compared against ++ x.set_prefix("") ++ T.set_prefix(" ") ++ test = Call(Name("isinstance"), [x, Comma(), T]) ++ if "n" in results: ++ test.set_prefix(" ") ++ test = Node(syms.not_test, [Name("not"), test]) ++ test.set_prefix(node.get_prefix()) ++ return test ++ ++ def transform_while(self, node, results): ++ one = results["while"] ++ one.replace(Name("True", prefix=one.get_prefix())) ++ ++ def transform_sort(self, node, results): ++ sort_stmt = results["sort"] ++ next_stmt = results["next"] ++ list_call = results.get("list") ++ simple_expr = results.get("expr") ++ ++ if list_call: ++ list_call.replace(Name("sorted", prefix=list_call.get_prefix())) ++ elif simple_expr: ++ new = simple_expr.clone() ++ new.set_prefix("") ++ simple_expr.replace(Call(Name("sorted"), [new], ++ prefix=simple_expr.get_prefix())) ++ else: ++ raise RuntimeError("should not have reached here") ++ sort_stmt.remove() ++ if next_stmt: ++ next_stmt[0].set_prefix(sort_stmt.get_prefix()) +diff -r 531f2e948299 refactor/fixes/from2/fix_import.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_import.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,90 @@ ++"""Fixer for import statements. ++If spam is being imported from the local directory, this import: ++ from spam import eggs ++Becomes: ++ from .spam import eggs ++ ++And this import: ++ import spam ++Becomes: ++ from . import spam ++""" ++ ++# Local imports ++from ... import fixer_base ++from os.path import dirname, join, exists, pathsep ++from ...fixer_util import FromImport, syms, token ++ ++ ++def traverse_imports(names): ++ """ ++ Walks over all the names imported in a dotted_as_names node. ++ """ ++ pending = [names] ++ while pending: ++ node = pending.pop() ++ if node.type == token.NAME: ++ yield node.value ++ elif node.type == syms.dotted_name: ++ yield "".join([ch.value for ch in node.children]) ++ elif node.type == syms.dotted_as_name: ++ pending.append(node.children[0]) ++ elif node.type == syms.dotted_as_names: ++ pending.extend(node.children[::-2]) ++ else: ++ raise AssertionError("unkown node type") ++ ++ ++class FixImport(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ import_from< 'from' imp=any 'import' ['('] any [')'] > ++ | ++ import_name< 'import' imp=any > ++ """ ++ ++ def transform(self, node, results): ++ imp = results['imp'] ++ ++ if node.type == syms.import_from: ++ # Some imps are top-level (eg: 'import ham') ++ # some are first level (eg: 'import ham.eggs') ++ # some are third level (eg: 'import ham.eggs as spam') ++ # Hence, the loop ++ while not hasattr(imp, 'value'): ++ imp = imp.children[0] ++ if self.probably_a_local_import(imp.value): ++ imp.value = "." + imp.value ++ imp.changed() ++ return node ++ else: ++ have_local = False ++ have_absolute = False ++ for mod_name in traverse_imports(imp): ++ if self.probably_a_local_import(mod_name): ++ have_local = True ++ else: ++ have_absolute = True ++ if have_absolute: ++ if have_local: ++ # We won't handle both sibling and absolute imports in the ++ # same statement at the moment. ++ self.warning(node, "absolute and local imports together") ++ return ++ ++ new = FromImport('.', [imp]) ++ new.set_prefix(node.get_prefix()) ++ return new ++ ++ def probably_a_local_import(self, imp_name): ++ imp_name = imp_name.split('.', 1)[0] ++ base_path = dirname(self.filename) ++ base_path = join(base_path, imp_name) ++ # If there is no __init__.py next to the file its not in a package ++ # so can't be a relative import. ++ if not exists(join(dirname(base_path), '__init__.py')): ++ return False ++ for ext in ['.py', pathsep, '.pyc', '.so', '.sl', '.pyd']: ++ if exists(base_path + ext): ++ return True ++ return False +diff -r 531f2e948299 refactor/fixes/from2/fix_imports.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_imports.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,145 @@ ++"""Fix incompatible imports and module references.""" ++# Authors: Collin Winter, Nick Edds ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import Name, attr_chain ++ ++MAPPING = {'StringIO': 'io', ++ 'cStringIO': 'io', ++ 'cPickle': 'pickle', ++ '__builtin__' : 'builtins', ++ 'copy_reg': 'copyreg', ++ 'Queue': 'queue', ++ 'SocketServer': 'socketserver', ++ 'ConfigParser': 'configparser', ++ 'repr': 'reprlib', ++ 'FileDialog': 'tkinter.filedialog', ++ 'tkFileDialog': 'tkinter.filedialog', ++ 'SimpleDialog': 'tkinter.simpledialog', ++ 'tkSimpleDialog': 'tkinter.simpledialog', ++ 'tkColorChooser': 'tkinter.colorchooser', ++ 'tkCommonDialog': 'tkinter.commondialog', ++ 'Dialog': 'tkinter.dialog', ++ 'Tkdnd': 'tkinter.dnd', ++ 'tkFont': 'tkinter.font', ++ 'tkMessageBox': 'tkinter.messagebox', ++ 'ScrolledText': 'tkinter.scrolledtext', ++ 'Tkconstants': 'tkinter.constants', ++ 'Tix': 'tkinter.tix', ++ 'ttk': 'tkinter.ttk', ++ 'Tkinter': 'tkinter', ++ 'markupbase': '_markupbase', ++ '_winreg': 'winreg', ++ 'thread': '_thread', ++ 'dummy_thread': '_dummy_thread', ++ # anydbm and whichdb are handled by fix_imports2 ++ 'dbhash': 'dbm.bsd', ++ 'dumbdbm': 'dbm.dumb', ++ 'dbm': 'dbm.ndbm', ++ 'gdbm': 'dbm.gnu', ++ 'xmlrpclib': 'xmlrpc.client', ++ 'DocXMLRPCServer': 'xmlrpc.server', ++ 'SimpleXMLRPCServer': 'xmlrpc.server', ++ 'httplib': 'http.client', ++ 'htmlentitydefs' : 'html.entities', ++ 'HTMLParser' : 'html.parser', ++ 'Cookie': 'http.cookies', ++ 'cookielib': 'http.cookiejar', ++ 'BaseHTTPServer': 'http.server', ++ 'SimpleHTTPServer': 'http.server', ++ 'CGIHTTPServer': 'http.server', ++ #'test.test_support': 'test.support', ++ 'commands': 'subprocess', ++ 'UserString' : 'collections', ++ 'UserList' : 'collections', ++ 'urlparse' : 'urllib.parse', ++ 'robotparser' : 'urllib.robotparser', ++} ++ ++ ++def alternates(members): ++ return "(" + "|".join(map(repr, members)) + ")" ++ ++ ++def build_pattern(mapping=MAPPING): ++ mod_list = ' | '.join(["module_name='%s'" % key for key in mapping]) ++ bare_names = alternates(mapping.keys()) ++ ++ yield """name_import=import_name< 'import' ((%s) | ++ multiple_imports=dotted_as_names< any* (%s) any* >) > ++ """ % (mod_list, mod_list) ++ yield """import_from< 'from' (%s) 'import' ['('] ++ ( any | import_as_name< any 'as' any > | ++ import_as_names< any* >) [')'] > ++ """ % mod_list ++ yield """import_name< 'import' (dotted_as_name< (%s) 'as' any > | ++ multiple_imports=dotted_as_names< ++ any* dotted_as_name< (%s) 'as' any > any* >) > ++ """ % (mod_list, mod_list) ++ ++ # Find usages of module members in code e.g. thread.foo(bar) ++ yield "power< bare_with_attr=(%s) trailer<'.' any > any* >" % bare_names ++ ++ ++class FixImports(fixer_base.BaseFix): ++ ++ order = "pre" # Pre-order tree traversal ++ ++ # This is overridden in fix_imports2. ++ mapping = MAPPING ++ ++ # We want to run this fixer late, so fix_import doesn't try to make stdlib ++ # renames into relative imports. ++ run_order = 6 ++ ++ def build_pattern(self): ++ return "|".join(build_pattern(self.mapping)) ++ ++ def compile_pattern(self): ++ # We override this, so MAPPING can be pragmatically altered and the ++ # changes will be reflected in PATTERN. ++ self.PATTERN = self.build_pattern() ++ super(FixImports, self).compile_pattern() ++ ++ # Don't match the node if it's within another match. ++ def match(self, node): ++ match = super(FixImports, self).match ++ results = match(node) ++ if results: ++ # Module usage could be in the trailer of an attribute lookup, so we ++ # might have nested matches when "bare_with_attr" is present. ++ if "bare_with_attr" not in results and \ ++ any([match(obj) for obj in attr_chain(node, "parent")]): ++ return False ++ return results ++ return False ++ ++ def start_tree(self, tree, filename): ++ super(FixImports, self).start_tree(tree, filename) ++ self.replace = {} ++ ++ def transform(self, node, results): ++ import_mod = results.get("module_name") ++ if import_mod: ++ mod_name = import_mod.value ++ new_name = self.mapping[mod_name] ++ import_mod.replace(Name(new_name, prefix=import_mod.get_prefix())) ++ if "name_import" in results: ++ # If it's not a "from x import x, y" or "import x as y" import, ++ # marked its usage to be replaced. ++ self.replace[mod_name] = new_name ++ if "multiple_imports" in results: ++ # This is a nasty hack to fix multiple imports on a line (e.g., ++ # "import StringIO, urlparse"). The problem is that I can't ++ # figure out an easy way to make a pattern recognize the keys of ++ # MAPPING randomly sprinkled in an import statement. ++ results = self.match(node) ++ if results: ++ self.transform(node, results) ++ else: ++ # Replace usage of the module. ++ bare_name = results["bare_with_attr"][0] ++ new_name = self.replace.get(bare_name.value) ++ if new_name: ++ bare_name.replace(Name(new_name, prefix=bare_name.get_prefix())) +diff -r 531f2e948299 refactor/fixes/from2/fix_imports2.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_imports2.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,16 @@ ++"""Fix incompatible imports and module references that must be fixed after ++fix_imports.""" ++from . import fix_imports ++ ++ ++MAPPING = { ++ 'whichdb': 'dbm', ++ 'anydbm': 'dbm', ++ } ++ ++ ++class FixImports2(fix_imports.FixImports): ++ ++ run_order = 7 ++ ++ mapping = MAPPING +diff -r 531f2e948299 refactor/fixes/from2/fix_input.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_input.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,26 @@ ++"""Fixer that changes input(...) into eval(input(...)).""" ++# Author: Andre Roberge ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import Call, Name ++from ... import patcomp ++ ++ ++context = patcomp.compile_pattern("power< 'eval' trailer< '(' any ')' > >") ++ ++ ++class FixInput(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ power< 'input' args=trailer< '(' [any] ')' > > ++ """ ++ ++ def transform(self, node, results): ++ # If we're already wrapped in a eval() call, we're done. ++ if context.match(node.parent.parent): ++ return ++ ++ new = node.clone() ++ new.set_prefix("") ++ return Call(Name("eval"), [new], prefix=node.get_prefix()) +diff -r 531f2e948299 refactor/fixes/from2/fix_intern.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_intern.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,44 @@ ++# Copyright 2006 Georg Brandl. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for intern(). ++ ++intern(s) -> sys.intern(s)""" ++ ++# Local imports ++from ... import pytree ++from ... import fixer_base ++from ...fixer_util import Name, Attr, touch_import ++ ++ ++class FixIntern(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ power< 'intern' ++ trailer< lpar='(' ++ ( not(arglist | argument) any ','> ) ++ rpar=')' > ++ after=any* ++ > ++ """ ++ ++ def transform(self, node, results): ++ syms = self.syms ++ obj = results["obj"].clone() ++ if obj.type == syms.arglist: ++ newarglist = obj.clone() ++ else: ++ newarglist = pytree.Node(syms.arglist, [obj.clone()]) ++ after = results["after"] ++ if after: ++ after = [n.clone() for n in after] ++ new = pytree.Node(syms.power, ++ Attr(Name("sys"), Name("intern")) + ++ [pytree.Node(syms.trailer, ++ [results["lpar"].clone(), ++ newarglist, ++ results["rpar"].clone()])] + after) ++ new.set_prefix(node.get_prefix()) ++ touch_import(None, 'sys', node) ++ return new +diff -r 531f2e948299 refactor/fixes/from2/fix_isinstance.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_isinstance.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,52 @@ ++# Copyright 2008 Armin Ronacher. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer that cleans up a tuple argument to isinstance after the tokens ++in it were fixed. This is mainly used to remove double occurrences of ++tokens as a leftover of the long -> int / unicode -> str conversion. ++ ++eg. isinstance(x, (int, long)) -> isinstance(x, (int, int)) ++ -> isinstance(x, int) ++""" ++ ++from ... import fixer_base ++from ...fixer_util import token ++ ++ ++class FixIsinstance(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ power< ++ 'isinstance' ++ trailer< '(' arglist< any ',' atom< '(' ++ args=testlist_gexp< any+ > ++ ')' > > ')' > ++ > ++ """ ++ ++ run_order = 6 ++ ++ def transform(self, node, results): ++ names_inserted = set() ++ testlist = results["args"] ++ args = testlist.children ++ new_args = [] ++ iterator = enumerate(args) ++ for idx, arg in iterator: ++ if arg.type == token.NAME and arg.value in names_inserted: ++ if idx < len(args) - 1 and args[idx + 1].type == token.COMMA: ++ iterator.next() ++ continue ++ else: ++ new_args.append(arg) ++ if arg.type == token.NAME: ++ names_inserted.add(arg.value) ++ if new_args and new_args[-1].type == token.COMMA: ++ del new_args[-1] ++ if len(new_args) == 1: ++ atom = testlist.parent ++ new_args[0].set_prefix(atom.get_prefix()) ++ atom.replace(new_args[0]) ++ else: ++ args[:] = new_args ++ node.changed() +diff -r 531f2e948299 refactor/fixes/from2/fix_itertools.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_itertools.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,41 @@ ++""" Fixer for itertools.(imap|ifilter|izip) --> (map|filter|zip) and ++ itertools.ifilterfalse --> itertools.filterfalse (bugs 2360-2363) ++ ++ imports from itertools are fixed in fix_itertools_import.py ++ ++ If itertools is imported as something else (ie: import itertools as it; ++ it.izip(spam, eggs)) method calls will not get fixed. ++ """ ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import Name ++ ++class FixItertools(fixer_base.BaseFix): ++ it_funcs = "('imap'|'ifilter'|'izip'|'ifilterfalse')" ++ PATTERN = """ ++ power< it='itertools' ++ trailer< ++ dot='.' func=%(it_funcs)s > trailer< '(' [any] ')' > > ++ | ++ power< func=%(it_funcs)s trailer< '(' [any] ')' > > ++ """ %(locals()) ++ ++ # Needs to be run after fix_(map|zip|filter) ++ run_order = 6 ++ ++ def transform(self, node, results): ++ prefix = None ++ func = results['func'][0] ++ if 'it' in results and func.value != 'ifilterfalse': ++ dot, it = (results['dot'], results['it']) ++ # Remove the 'itertools' ++ prefix = it.get_prefix() ++ it.remove() ++ # Replace the node wich contains ('.', 'function') with the ++ # function (to be consistant with the second part of the pattern) ++ dot.remove() ++ func.parent.replace(func) ++ ++ prefix = prefix or func.get_prefix() ++ func.replace(Name(func.value[1:], prefix=prefix)) +diff -r 531f2e948299 refactor/fixes/from2/fix_itertools_imports.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_itertools_imports.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,52 @@ ++""" Fixer for imports of itertools.(imap|ifilter|izip|ifilterfalse) """ ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import BlankLine, syms, token ++ ++ ++class FixItertoolsImports(fixer_base.BaseFix): ++ PATTERN = """ ++ import_from< 'from' 'itertools' 'import' imports=any > ++ """ %(locals()) ++ ++ def transform(self, node, results): ++ imports = results['imports'] ++ if imports.type == syms.import_as_name or not imports.children: ++ children = [imports] ++ else: ++ children = imports.children ++ for child in children[::2]: ++ if child.type == token.NAME: ++ member = child.value ++ name_node = child ++ else: ++ assert child.type == syms.import_as_name ++ name_node = child.children[0] ++ member_name = name_node.value ++ if member_name in ('imap', 'izip', 'ifilter'): ++ child.value = None ++ child.remove() ++ elif member_name == 'ifilterfalse': ++ node.changed() ++ name_node.value = 'filterfalse' ++ ++ # Make sure the import statement is still sane ++ children = imports.children[:] or [imports] ++ remove_comma = True ++ for child in children: ++ if remove_comma and child.type == token.COMMA: ++ child.remove() ++ else: ++ remove_comma ^= True ++ ++ if children[-1].type == token.COMMA: ++ children[-1].remove() ++ ++ # If there are no imports left, just get rid of the entire statement ++ if not (imports.children or getattr(imports, 'value', None)) or \ ++ imports.parent is None: ++ p = node.get_prefix() ++ node = BlankLine() ++ node.prefix = p ++ return node +diff -r 531f2e948299 refactor/fixes/from2/fix_long.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_long.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,22 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer that turns 'long' into 'int' everywhere. ++""" ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import Name, Number, is_probably_builtin ++ ++ ++class FixLong(fixer_base.BaseFix): ++ ++ PATTERN = "'long'" ++ ++ static_int = Name("int") ++ ++ def transform(self, node, results): ++ if is_probably_builtin(node): ++ new = self.static_int.clone() ++ new.set_prefix(node.get_prefix()) ++ return new +diff -r 531f2e948299 refactor/fixes/from2/fix_map.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_map.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,82 @@ ++# Copyright 2007 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer that changes map(F, ...) into list(map(F, ...)) unless there ++exists a 'from future_builtins import map' statement in the top-level ++namespace. ++ ++As a special case, map(None, X) is changed into list(X). (This is ++necessary because the semantics are changed in this case -- the new ++map(None, X) is equivalent to [(x,) for x in X].) ++ ++We avoid the transformation (except for the special case mentioned ++above) if the map() call is directly contained in iter(<>), list(<>), ++tuple(<>), sorted(<>), ...join(<>), or for V in <>:. ++ ++NOTE: This is still not correct if the original code was depending on ++map(F, X, Y, ...) to go on until the longest argument is exhausted, ++substituting None for missing values -- like zip(), it now stops as ++soon as the shortest argument is exhausted. ++""" ++ ++# Local imports ++from ...pgen2 import token ++from ... import fixer_base ++from ...fixer_util import Name, Call, ListComp, in_special_context ++from ...pygram import python_symbols as syms ++ ++class FixMap(fixer_base.ConditionalFix): ++ ++ PATTERN = """ ++ map_none=power< ++ 'map' ++ trailer< '(' arglist< 'None' ',' arg=any [','] > ')' > ++ > ++ | ++ map_lambda=power< ++ 'map' ++ trailer< ++ '(' ++ arglist< ++ lambdef< 'lambda' ++ (fp=NAME | vfpdef< '(' fp=NAME ')'> ) ':' xp=any ++ > ++ ',' ++ it=any ++ > ++ ')' ++ > ++ > ++ | ++ power< ++ 'map' ++ args=trailer< '(' [any] ')' > ++ > ++ """ ++ ++ skip_on = 'future_builtins.map' ++ ++ def transform(self, node, results): ++ if self.should_skip(node): ++ return ++ ++ if node.parent.type == syms.simple_stmt: ++ self.warning(node, "You should use a for loop here") ++ new = node.clone() ++ new.set_prefix("") ++ new = Call(Name("list"), [new]) ++ elif "map_lambda" in results: ++ new = ListComp(results.get("xp").clone(), ++ results.get("fp").clone(), ++ results.get("it").clone()) ++ else: ++ if "map_none" in results: ++ new = results["arg"].clone() ++ else: ++ if in_special_context(node): ++ return None ++ new = node.clone() ++ new.set_prefix("") ++ new = Call(Name("list"), [new]) ++ new.set_prefix(node.get_prefix()) ++ return new +diff -r 531f2e948299 refactor/fixes/from2/fix_metaclass.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_metaclass.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,227 @@ ++"""Fixer for __metaclass__ = X -> (metaclass=X) methods. ++ ++ The various forms of classef (inherits nothing, inherits once, inherints ++ many) don't parse the same in the CST so we look at ALL classes for ++ a __metaclass__ and if we find one normalize the inherits to all be ++ an arglist. ++ ++ For one-liner classes ('class X: pass') there is no indent/dedent so ++ we normalize those into having a suite. ++ ++ Moving the __metaclass__ into the classdef can also cause the class ++ body to be empty so there is some special casing for that as well. ++ ++ This fixer also tries very hard to keep original indenting and spacing ++ in all those corner cases. ++ ++""" ++# Author: Jack Diederich ++ ++# Local imports ++from ... import fixer_base ++from ...pygram import token ++from ...fixer_util import Name, syms, Node, Leaf ++ ++ ++def has_metaclass(parent): ++ """ we have to check the cls_node without changing it. ++ There are two possiblities: ++ 1) clsdef => suite => simple_stmt => expr_stmt => Leaf('__meta') ++ 2) clsdef => simple_stmt => expr_stmt => Leaf('__meta') ++ """ ++ for node in parent.children: ++ if node.type == syms.suite: ++ return has_metaclass(node) ++ elif node.type == syms.simple_stmt and node.children: ++ expr_node = node.children[0] ++ if expr_node.type == syms.expr_stmt and expr_node.children: ++ left_side = expr_node.children[0] ++ if isinstance(left_side, Leaf) and \ ++ left_side.value == '__metaclass__': ++ return True ++ return False ++ ++ ++def fixup_parse_tree(cls_node): ++ """ one-line classes don't get a suite in the parse tree so we add ++ one to normalize the tree ++ """ ++ for node in cls_node.children: ++ if node.type == syms.suite: ++ # already in the prefered format, do nothing ++ return ++ ++ # !%@#! oneliners have no suite node, we have to fake one up ++ for i, node in enumerate(cls_node.children): ++ if node.type == token.COLON: ++ break ++ else: ++ raise ValueError("No class suite and no ':'!") ++ ++ # move everything into a suite node ++ suite = Node(syms.suite, []) ++ while cls_node.children[i+1:]: ++ move_node = cls_node.children[i+1] ++ suite.append_child(move_node.clone()) ++ move_node.remove() ++ cls_node.append_child(suite) ++ node = suite ++ ++ ++def fixup_simple_stmt(parent, i, stmt_node): ++ """ if there is a semi-colon all the parts count as part of the same ++ simple_stmt. We just want the __metaclass__ part so we move ++ everything efter the semi-colon into its own simple_stmt node ++ """ ++ for semi_ind, node in enumerate(stmt_node.children): ++ if node.type == token.SEMI: # *sigh* ++ break ++ else: ++ return ++ ++ node.remove() # kill the semicolon ++ new_expr = Node(syms.expr_stmt, []) ++ new_stmt = Node(syms.simple_stmt, [new_expr]) ++ while stmt_node.children[semi_ind:]: ++ move_node = stmt_node.children[semi_ind] ++ new_expr.append_child(move_node.clone()) ++ move_node.remove() ++ parent.insert_child(i, new_stmt) ++ new_leaf1 = new_stmt.children[0].children[0] ++ old_leaf1 = stmt_node.children[0].children[0] ++ new_leaf1.set_prefix(old_leaf1.get_prefix()) ++ ++ ++def remove_trailing_newline(node): ++ if node.children and node.children[-1].type == token.NEWLINE: ++ node.children[-1].remove() ++ ++ ++def find_metas(cls_node): ++ # find the suite node (Mmm, sweet nodes) ++ for node in cls_node.children: ++ if node.type == syms.suite: ++ break ++ else: ++ raise ValueError("No class suite!") ++ ++ # look for simple_stmt[ expr_stmt[ Leaf('__metaclass__') ] ] ++ for i, simple_node in list(enumerate(node.children)): ++ if simple_node.type == syms.simple_stmt and simple_node.children: ++ expr_node = simple_node.children[0] ++ if expr_node.type == syms.expr_stmt and expr_node.children: ++ # Check if the expr_node is a simple assignment. ++ left_node = expr_node.children[0] ++ if isinstance(left_node, Leaf) and \ ++ left_node.value == '__metaclass__': ++ # We found a assignment to __metaclass__. ++ fixup_simple_stmt(node, i, simple_node) ++ remove_trailing_newline(simple_node) ++ yield (node, i, simple_node) ++ ++ ++def fixup_indent(suite): ++ """ If an INDENT is followed by a thing with a prefix then nuke the prefix ++ Otherwise we get in trouble when removing __metaclass__ at suite start ++ """ ++ kids = suite.children[::-1] ++ # find the first indent ++ while kids: ++ node = kids.pop() ++ if node.type == token.INDENT: ++ break ++ ++ # find the first Leaf ++ while kids: ++ node = kids.pop() ++ if isinstance(node, Leaf) and node.type != token.DEDENT: ++ if node.prefix: ++ node.set_prefix('') ++ return ++ else: ++ kids.extend(node.children[::-1]) ++ ++ ++class FixMetaclass(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ classdef ++ """ ++ ++ def transform(self, node, results): ++ if not has_metaclass(node): ++ return node ++ ++ fixup_parse_tree(node) ++ ++ # find metaclasses, keep the last one ++ last_metaclass = None ++ for suite, i, stmt in find_metas(node): ++ last_metaclass = stmt ++ stmt.remove() ++ ++ text_type = node.children[0].type # always Leaf(nnn, 'class') ++ ++ # figure out what kind of classdef we have ++ if len(node.children) == 7: ++ # Node(classdef, ['class', 'name', '(', arglist, ')', ':', suite]) ++ # 0 1 2 3 4 5 6 ++ if node.children[3].type == syms.arglist: ++ arglist = node.children[3] ++ # Node(classdef, ['class', 'name', '(', 'Parent', ')', ':', suite]) ++ else: ++ parent = node.children[3].clone() ++ arglist = Node(syms.arglist, [parent]) ++ node.set_child(3, arglist) ++ elif len(node.children) == 6: ++ # Node(classdef, ['class', 'name', '(', ')', ':', suite]) ++ # 0 1 2 3 4 5 ++ arglist = Node(syms.arglist, []) ++ node.insert_child(3, arglist) ++ elif len(node.children) == 4: ++ # Node(classdef, ['class', 'name', ':', suite]) ++ # 0 1 2 3 ++ arglist = Node(syms.arglist, []) ++ node.insert_child(2, Leaf(token.RPAR, ')')) ++ node.insert_child(2, arglist) ++ node.insert_child(2, Leaf(token.LPAR, '(')) ++ else: ++ raise ValueError("Unexpected class definition") ++ ++ # now stick the metaclass in the arglist ++ meta_txt = last_metaclass.children[0].children[0] ++ meta_txt.value = 'metaclass' ++ orig_meta_prefix = meta_txt.get_prefix() ++ ++ if arglist.children: ++ arglist.append_child(Leaf(token.COMMA, ',')) ++ meta_txt.set_prefix(' ') ++ else: ++ meta_txt.set_prefix('') ++ ++ # compact the expression "metaclass = Meta" -> "metaclass=Meta" ++ expr_stmt = last_metaclass.children[0] ++ assert expr_stmt.type == syms.expr_stmt ++ expr_stmt.children[1].set_prefix('') ++ expr_stmt.children[2].set_prefix('') ++ ++ arglist.append_child(last_metaclass) ++ ++ fixup_indent(suite) ++ ++ # check for empty suite ++ if not suite.children: ++ # one-liner that was just __metaclass_ ++ suite.remove() ++ pass_leaf = Leaf(text_type, 'pass') ++ pass_leaf.set_prefix(orig_meta_prefix) ++ node.append_child(pass_leaf) ++ node.append_child(Leaf(token.NEWLINE, '\n')) ++ ++ elif len(suite.children) > 1 and \ ++ (suite.children[-2].type == token.INDENT and ++ suite.children[-1].type == token.DEDENT): ++ # there was only one line in the class body and it was __metaclass__ ++ pass_leaf = Leaf(text_type, 'pass') ++ suite.insert_child(-1, pass_leaf) ++ suite.insert_child(-1, Leaf(token.NEWLINE, '\n')) +diff -r 531f2e948299 refactor/fixes/from2/fix_methodattrs.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_methodattrs.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,23 @@ ++"""Fix bound method attributes (method.im_? -> method.__?__). ++""" ++# Author: Christian Heimes ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import Name ++ ++MAP = { ++ "im_func" : "__func__", ++ "im_self" : "__self__", ++ "im_class" : "__self__.__class__" ++ } ++ ++class FixMethodattrs(fixer_base.BaseFix): ++ PATTERN = """ ++ power< any+ trailer< '.' attr=('im_func' | 'im_self' | 'im_class') > any* > ++ """ ++ ++ def transform(self, node, results): ++ attr = results["attr"][0] ++ new = MAP[attr.value] ++ attr.replace(Name(new, prefix=attr.get_prefix())) +diff -r 531f2e948299 refactor/fixes/from2/fix_ne.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_ne.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,22 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer that turns <> into !=.""" ++ ++# Local imports ++from ... import pytree ++from ...pgen2 import token ++from ... import fixer_base ++ ++ ++class FixNe(fixer_base.BaseFix): ++ # This is so simple that we don't need the pattern compiler. ++ ++ def match(self, node): ++ # Override ++ return node.type == token.NOTEQUAL and node.value == "<>" ++ ++ def transform(self, node, results): ++ new = pytree.Leaf(token.NOTEQUAL, "!=") ++ new.set_prefix(node.get_prefix()) ++ return new +diff -r 531f2e948299 refactor/fixes/from2/fix_next.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_next.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,103 @@ ++"""Fixer for it.next() -> next(it), per PEP 3114.""" ++# Author: Collin Winter ++ ++# Things that currently aren't covered: ++# - listcomp "next" names aren't warned ++# - "with" statement targets aren't checked ++ ++# Local imports ++from ...pgen2 import token ++from ...pygram import python_symbols as syms ++from ... import fixer_base ++from ...fixer_util import Name, Call, find_binding ++ ++bind_warning = "Calls to builtin next() possibly shadowed by global binding" ++ ++ ++class FixNext(fixer_base.BaseFix): ++ PATTERN = """ ++ power< base=any+ trailer< '.' attr='next' > trailer< '(' ')' > > ++ | ++ power< head=any+ trailer< '.' attr='next' > not trailer< '(' ')' > > ++ | ++ classdef< 'class' any+ ':' ++ suite< any* ++ funcdef< 'def' ++ name='next' ++ parameters< '(' NAME ')' > any+ > ++ any* > > ++ | ++ global=global_stmt< 'global' any* 'next' any* > ++ """ ++ ++ order = "pre" # Pre-order tree traversal ++ ++ def start_tree(self, tree, filename): ++ super(FixNext, self).start_tree(tree, filename) ++ ++ n = find_binding('next', tree) ++ if n: ++ self.warning(n, bind_warning) ++ self.shadowed_next = True ++ else: ++ self.shadowed_next = False ++ ++ def transform(self, node, results): ++ assert results ++ ++ base = results.get("base") ++ attr = results.get("attr") ++ name = results.get("name") ++ mod = results.get("mod") ++ ++ if base: ++ if self.shadowed_next: ++ attr.replace(Name("__next__", prefix=attr.get_prefix())) ++ else: ++ base = [n.clone() for n in base] ++ base[0].set_prefix("") ++ node.replace(Call(Name("next", prefix=node.get_prefix()), base)) ++ elif name: ++ n = Name("__next__", prefix=name.get_prefix()) ++ name.replace(n) ++ elif attr: ++ # We don't do this transformation if we're assigning to "x.next". ++ # Unfortunately, it doesn't seem possible to do this in PATTERN, ++ # so it's being done here. ++ if is_assign_target(node): ++ head = results["head"] ++ if "".join([str(n) for n in head]).strip() == '__builtin__': ++ self.warning(node, bind_warning) ++ return ++ attr.replace(Name("__next__")) ++ elif "global" in results: ++ self.warning(node, bind_warning) ++ self.shadowed_next = True ++ ++ ++### The following functions help test if node is part of an assignment ++### target. ++ ++def is_assign_target(node): ++ assign = find_assign(node) ++ if assign is None: ++ return False ++ ++ for child in assign.children: ++ if child.type == token.EQUAL: ++ return False ++ elif is_subtree(child, node): ++ return True ++ return False ++ ++def find_assign(node): ++ if node.type == syms.expr_stmt: ++ return node ++ if node.type == syms.simple_stmt or node.parent is None: ++ return None ++ return find_assign(node.parent) ++ ++def is_subtree(root, node): ++ if root == node: ++ return True ++ return any([is_subtree(c, node) for c in root.children]) +diff -r 531f2e948299 refactor/fixes/from2/fix_nonzero.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_nonzero.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,20 @@ ++"""Fixer for __nonzero__ -> __bool__ methods.""" ++# Author: Collin Winter ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import Name, syms ++ ++class FixNonzero(fixer_base.BaseFix): ++ PATTERN = """ ++ classdef< 'class' any+ ':' ++ suite< any* ++ funcdef< 'def' name='__nonzero__' ++ parameters< '(' NAME ')' > any+ > ++ any* > > ++ """ ++ ++ def transform(self, node, results): ++ name = results["name"] ++ new = Name("__bool__", prefix=name.get_prefix()) ++ name.replace(new) +diff -r 531f2e948299 refactor/fixes/from2/fix_numliterals.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_numliterals.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,27 @@ ++"""Fixer that turns 1L into 1, 0755 into 0o755. ++""" ++# Copyright 2007 Georg Brandl. ++# Licensed to PSF under a Contributor Agreement. ++ ++# Local imports ++from ...pgen2 import token ++from ... import fixer_base ++from ...fixer_util import Number ++ ++ ++class FixNumliterals(fixer_base.BaseFix): ++ # This is so simple that we don't need the pattern compiler. ++ ++ def match(self, node): ++ # Override ++ return (node.type == token.NUMBER and ++ (node.value.startswith("0") or node.value[-1] in "Ll")) ++ ++ def transform(self, node, results): ++ val = node.value ++ if val[-1] in 'Ll': ++ val = val[:-1] ++ elif val.startswith('0') and val.isdigit() and len(set(val)) > 1: ++ val = "0o" + val[1:] ++ ++ return Number(val, prefix=node.get_prefix()) +diff -r 531f2e948299 refactor/fixes/from2/fix_paren.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_paren.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,42 @@ ++"""Fixer that addes parentheses where they are required ++ ++This converts ``[x for x in 1, 2]`` to ``[x for x in (1, 2)]``.""" ++ ++# By Taek Joo Kim and Benjamin Peterson ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import LParen, RParen ++ ++# XXX This doesn't support nested for loops like [x for x in 1, 2 for x in 1, 2] ++class FixParen(fixer_base.BaseFix): ++ PATTERN = """ ++ atom< ('[' | '(') ++ (listmaker< any ++ comp_for< ++ 'for' NAME 'in' ++ target=testlist_safe< any (',' any)+ [','] ++ > ++ [any] ++ > ++ > ++ | ++ testlist_gexp< any ++ comp_for< ++ 'for' NAME 'in' ++ target=testlist_safe< any (',' any)+ [','] ++ > ++ [any] ++ > ++ >) ++ (']' | ')') > ++ """ ++ ++ def transform(self, node, results): ++ target = results["target"] ++ ++ lparen = LParen() ++ lparen.set_prefix(target.get_prefix()) ++ target.set_prefix("") # Make it hug the parentheses ++ target.insert_child(0, lparen) ++ target.append_child(RParen()) +diff -r 531f2e948299 refactor/fixes/from2/fix_print.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_print.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,90 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for print. ++ ++Change: ++ 'print' into 'print()' ++ 'print ...' into 'print(...)' ++ 'print ... ,' into 'print(..., end=" ")' ++ 'print >>x, ...' into 'print(..., file=x)' ++ ++No changes are applied if print_function is imported from __future__ ++ ++""" ++ ++# Local imports ++from ... import patcomp ++from ... import pytree ++from ...pgen2 import token ++from ... import fixer_base ++from ...fixer_util import Name, Call, Comma, String, is_tuple ++ ++ ++parend_expr = patcomp.compile_pattern( ++ """atom< '(' [atom|STRING|NAME] ')' >""" ++ ) ++ ++ ++class FixPrint(fixer_base.ConditionalFix): ++ ++ PATTERN = """ ++ simple_stmt< any* bare='print' any* > | print_stmt ++ """ ++ ++ skip_on = '__future__.print_function' ++ ++ def transform(self, node, results): ++ assert results ++ ++ if self.should_skip(node): ++ return ++ ++ bare_print = results.get("bare") ++ ++ if bare_print: ++ # Special-case print all by itself ++ bare_print.replace(Call(Name("print"), [], ++ prefix=bare_print.get_prefix())) ++ return ++ assert node.children[0] == Name("print") ++ args = node.children[1:] ++ if len(args) == 1 and parend_expr.match(args[0]): ++ # We don't want to keep sticking parens around an ++ # already-parenthesised expression. ++ return ++ ++ sep = end = file = None ++ if args and args[-1] == Comma(): ++ args = args[:-1] ++ end = " " ++ if args and args[0] == pytree.Leaf(token.RIGHTSHIFT, ">>"): ++ assert len(args) >= 2 ++ file = args[1].clone() ++ args = args[3:] # Strip a possible comma after the file expression ++ # Now synthesize a print(args, sep=..., end=..., file=...) node. ++ l_args = [arg.clone() for arg in args] ++ if l_args: ++ l_args[0].set_prefix("") ++ if sep is not None or end is not None or file is not None: ++ if sep is not None: ++ self.add_kwarg(l_args, "sep", String(repr(sep))) ++ if end is not None: ++ self.add_kwarg(l_args, "end", String(repr(end))) ++ if file is not None: ++ self.add_kwarg(l_args, "file", file) ++ n_stmt = Call(Name("print"), l_args) ++ n_stmt.set_prefix(node.get_prefix()) ++ return n_stmt ++ ++ def add_kwarg(self, l_nodes, s_kwd, n_expr): ++ # XXX All this prefix-setting may lose comments (though rarely) ++ n_expr.set_prefix("") ++ n_argument = pytree.Node(self.syms.argument, ++ (Name(s_kwd), ++ pytree.Leaf(token.EQUAL, "="), ++ n_expr)) ++ if l_nodes: ++ l_nodes.append(Comma()) ++ n_argument.set_prefix(" ") ++ l_nodes.append(n_argument) +diff -r 531f2e948299 refactor/fixes/from2/fix_raise.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_raise.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,82 @@ ++"""Fixer for 'raise E, V, T' ++ ++raise -> raise ++raise E -> raise E ++raise E, V -> raise E(V) ++raise E, V, T -> raise E(V).with_traceback(T) ++ ++raise (((E, E'), E''), E'''), V -> raise E(V) ++raise "foo", V, T -> warns about string exceptions ++ ++ ++CAVEATS: ++1) "raise E, V" will be incorrectly translated if V is an exception ++ instance. The correct Python 3 idiom is ++ ++ raise E from V ++ ++ but since we can't detect instance-hood by syntax alone and since ++ any client code would have to be changed as well, we don't automate ++ this. ++""" ++# Author: Collin Winter ++ ++# Local imports ++from ... import pytree ++from ...pgen2 import token ++from ... import fixer_base ++from ...fixer_util import Name, Call, Attr, ArgList, is_tuple ++ ++class FixRaise(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ raise_stmt< 'raise' exc=any [',' val=any [',' tb=any]] > ++ """ ++ ++ def transform(self, node, results): ++ syms = self.syms ++ ++ exc = results["exc"].clone() ++ if exc.type is token.STRING: ++ self.cannot_convert(node, "Python 3 does not support string exceptions") ++ return ++ ++ # Python 2 supports ++ # raise ((((E1, E2), E3), E4), E5), V ++ # as a synonym for ++ # raise E1, V ++ # Since Python 3 will not support this, we recurse down any tuple ++ # literals, always taking the first element. ++ if is_tuple(exc): ++ while is_tuple(exc): ++ # exc.children[1:-1] is the unparenthesized tuple ++ # exc.children[1].children[0] is the first element of the tuple ++ exc = exc.children[1].children[0].clone() ++ exc.set_prefix(" ") ++ ++ if "val" not in results: ++ # One-argument raise ++ new = pytree.Node(syms.raise_stmt, [Name("raise"), exc]) ++ new.set_prefix(node.get_prefix()) ++ return new ++ ++ val = results["val"].clone() ++ if is_tuple(val): ++ args = [c.clone() for c in val.children[1:-1]] ++ else: ++ val.set_prefix("") ++ args = [val] ++ ++ if "tb" in results: ++ tb = results["tb"].clone() ++ tb.set_prefix("") ++ ++ e = Call(exc, args) ++ with_tb = Attr(e, Name('with_traceback')) + [ArgList([tb])] ++ new = pytree.Node(syms.simple_stmt, [Name("raise")] + with_tb) ++ new.set_prefix(node.get_prefix()) ++ return new ++ else: ++ return pytree.Node(syms.raise_stmt, ++ [Name("raise"), Call(exc, args)], ++ prefix=node.get_prefix()) +diff -r 531f2e948299 refactor/fixes/from2/fix_raw_input.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_raw_input.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,16 @@ ++"""Fixer that changes raw_input(...) into input(...).""" ++# Author: Andre Roberge ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import Name ++ ++class FixRawInput(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ power< name='raw_input' trailer< '(' [any] ')' > any* > ++ """ ++ ++ def transform(self, node, results): ++ name = results["name"] ++ name.replace(Name("input", prefix=name.get_prefix())) +diff -r 531f2e948299 refactor/fixes/from2/fix_reduce.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_reduce.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,33 @@ ++# Copyright 2008 Armin Ronacher. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for reduce(). ++ ++Makes sure reduce() is imported from the functools module if reduce is ++used in that module. ++""" ++ ++from ... import pytree ++from ... import fixer_base ++from ...fixer_util import Name, Attr, touch_import ++ ++ ++ ++class FixReduce(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ power< 'reduce' ++ trailer< '(' ++ arglist< ( ++ (not(argument) any ',' ++ not(argument ++ > ++ """ ++ ++ def transform(self, node, results): ++ touch_import('functools', 'reduce', node) +diff -r 531f2e948299 refactor/fixes/from2/fix_renames.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_renames.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,69 @@ ++"""Fix incompatible renames ++ ++Fixes: ++ * sys.maxint -> sys.maxsize ++""" ++# Author: Christian Heimes ++# based on Collin Winter's fix_import ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import Name, attr_chain ++ ++MAPPING = {"sys": {"maxint" : "maxsize"}, ++ } ++LOOKUP = {} ++ ++def alternates(members): ++ return "(" + "|".join(map(repr, members)) + ")" ++ ++ ++def build_pattern(): ++ #bare = set() ++ for module, replace in MAPPING.items(): ++ for old_attr, new_attr in replace.items(): ++ LOOKUP[(module, old_attr)] = new_attr ++ #bare.add(module) ++ #bare.add(old_attr) ++ #yield """ ++ # import_name< 'import' (module=%r ++ # | dotted_as_names< any* module=%r any* >) > ++ # """ % (module, module) ++ yield """ ++ import_from< 'from' module_name=%r 'import' ++ ( attr_name=%r | import_as_name< attr_name=%r 'as' any >) > ++ """ % (module, old_attr, old_attr) ++ yield """ ++ power< module_name=%r trailer< '.' attr_name=%r > any* > ++ """ % (module, old_attr) ++ #yield """bare_name=%s""" % alternates(bare) ++ ++ ++class FixRenames(fixer_base.BaseFix): ++ PATTERN = "|".join(build_pattern()) ++ ++ order = "pre" # Pre-order tree traversal ++ ++ # Don't match the node if it's within another match ++ def match(self, node): ++ match = super(FixRenames, self).match ++ results = match(node) ++ if results: ++ if any([match(obj) for obj in attr_chain(node, "parent")]): ++ return False ++ return results ++ return False ++ ++ #def start_tree(self, tree, filename): ++ # super(FixRenames, self).start_tree(tree, filename) ++ # self.replace = {} ++ ++ def transform(self, node, results): ++ mod_name = results.get("module_name") ++ attr_name = results.get("attr_name") ++ #bare_name = results.get("bare_name") ++ #import_mod = results.get("module") ++ ++ if mod_name and attr_name: ++ new_attr = LOOKUP[(mod_name.value, attr_name.value)] ++ attr_name.replace(Name(new_attr, prefix=attr_name.get_prefix())) +diff -r 531f2e948299 refactor/fixes/from2/fix_repr.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_repr.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,22 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer that transforms `xyzzy` into repr(xyzzy).""" ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import Call, Name, parenthesize ++ ++ ++class FixRepr(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ atom < '`' expr=any '`' > ++ """ ++ ++ def transform(self, node, results): ++ expr = results["expr"].clone() ++ ++ if expr.type == self.syms.testlist1: ++ expr = parenthesize(expr) ++ return Call(Name("repr"), [expr], prefix=node.get_prefix()) +diff -r 531f2e948299 refactor/fixes/from2/fix_set_literal.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_set_literal.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,50 @@ ++""" ++Optional fixer to transform set() calls to set literals. ++""" ++ ++# Author: Benjamin Peterson ++ ++from ... import fixer_base, pytree ++from ...fixer_util import token, syms ++ ++class FixSetLiteral(fixer_base.BaseFix): ++ ++ explicit = True ++ ++ PATTERN = """power< 'set' trailer< '(' ++ (atom=atom< '[' (items=listmaker< any ((',' any)* [',']) > ++ | ++ single=any) ']' > ++ | ++ atom< '(' items=testlist_gexp< any ((',' any)* [',']) > ')' > ++ ) ++ ')' > > ++ """ ++ ++ def transform(self, node, results): ++ single = results.get("single") ++ if single: ++ # Make a fake listmaker ++ fake = pytree.Node(syms.listmaker, [single.clone()]) ++ single.replace(fake) ++ items = fake ++ else: ++ items = results["items"] ++ ++ # Build the contents of the literal ++ literal = [pytree.Leaf(token.LBRACE, "{")] ++ literal.extend(n.clone() for n in items.children) ++ literal.append(pytree.Leaf(token.RBRACE, "}")) ++ # Set the prefix of the right brace to that of the ')' or ']' ++ literal[-1].set_prefix(items.next_sibling.get_prefix()) ++ maker = pytree.Node(syms.dictsetmaker, literal) ++ maker.set_prefix(node.get_prefix()) ++ ++ # If the original was a one tuple, we need to remove the extra comma. ++ if len(maker.children) == 4: ++ n = maker.children[2] ++ n.remove() ++ maker.children[-1].set_prefix(n.get_prefix()) ++ ++ # Finally, replace the set call with our shiny new literal. ++ return maker +diff -r 531f2e948299 refactor/fixes/from2/fix_standarderror.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_standarderror.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,18 @@ ++# Copyright 2007 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for StandardError -> Exception.""" ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import Name ++ ++ ++class FixStandarderror(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ 'StandardError' ++ """ ++ ++ def transform(self, node, results): ++ return Name("Exception", prefix=node.get_prefix()) +diff -r 531f2e948299 refactor/fixes/from2/fix_sys_exc.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_sys_exc.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,29 @@ ++"""Fixer for sys.exc_{type, value, traceback} ++ ++sys.exc_type -> sys.exc_info()[0] ++sys.exc_value -> sys.exc_info()[1] ++sys.exc_traceback -> sys.exc_info()[2] ++""" ++ ++# By Jeff Balogh and Benjamin Peterson ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import Attr, Call, Name, Number, Subscript, Node, syms ++ ++class FixSysExc(fixer_base.BaseFix): ++ # This order matches the ordering of sys.exc_info(). ++ exc_info = ["exc_type", "exc_value", "exc_traceback"] ++ PATTERN = """ ++ power< 'sys' trailer< dot='.' attribute=(%s) > > ++ """ % '|'.join("'%s'" % e for e in exc_info) ++ ++ def transform(self, node, results): ++ sys_attr = results["attribute"][0] ++ index = Number(self.exc_info.index(sys_attr.value)) ++ ++ call = Call(Name("exc_info"), prefix=sys_attr.get_prefix()) ++ attr = Attr(Name("sys"), call) ++ attr[1].children[0].set_prefix(results["dot"].get_prefix()) ++ attr.append(Subscript(index)) ++ return Node(syms.power, attr, prefix=node.get_prefix()) +diff -r 531f2e948299 refactor/fixes/from2/fix_throw.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_throw.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,56 @@ ++"""Fixer for generator.throw(E, V, T). ++ ++g.throw(E) -> g.throw(E) ++g.throw(E, V) -> g.throw(E(V)) ++g.throw(E, V, T) -> g.throw(E(V).with_traceback(T)) ++ ++g.throw("foo"[, V[, T]]) will warn about string exceptions.""" ++# Author: Collin Winter ++ ++# Local imports ++from ... import pytree ++from ...pgen2 import token ++from ... import fixer_base ++from ...fixer_util import Name, Call, ArgList, Attr, is_tuple ++ ++class FixThrow(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ power< any trailer< '.' 'throw' > ++ trailer< '(' args=arglist< exc=any ',' val=any [',' tb=any] > ')' > ++ > ++ | ++ power< any trailer< '.' 'throw' > trailer< '(' exc=any ')' > > ++ """ ++ ++ def transform(self, node, results): ++ syms = self.syms ++ ++ exc = results["exc"].clone() ++ if exc.type is token.STRING: ++ self.cannot_convert(node, "Python 3 does not support string exceptions") ++ return ++ ++ # Leave "g.throw(E)" alone ++ val = results.get("val") ++ if val is None: ++ return ++ ++ val = val.clone() ++ if is_tuple(val): ++ args = [c.clone() for c in val.children[1:-1]] ++ else: ++ val.set_prefix("") ++ args = [val] ++ ++ throw_args = results["args"] ++ ++ if "tb" in results: ++ tb = results["tb"].clone() ++ tb.set_prefix("") ++ ++ e = Call(exc, args) ++ with_tb = Attr(e, Name('with_traceback')) + [ArgList([tb])] ++ throw_args.replace(pytree.Node(syms.power, with_tb)) ++ else: ++ throw_args.replace(Call(exc, args)) +diff -r 531f2e948299 refactor/fixes/from2/fix_tuple_params.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_tuple_params.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,169 @@ ++"""Fixer for function definitions with tuple parameters. ++ ++def func(((a, b), c), d): ++ ... ++ ++ -> ++ ++def func(x, d): ++ ((a, b), c) = x ++ ... ++ ++It will also support lambdas: ++ ++ lambda (x, y): x + y -> lambda t: t[0] + t[1] ++ ++ # The parens are a syntax error in Python 3 ++ lambda (x): x + y -> lambda x: x + y ++""" ++# Author: Collin Winter ++ ++# Local imports ++from ... import pytree ++from ...pgen2 import token ++from ... import fixer_base ++from ...fixer_util import Assign, Name, Newline, Number, Subscript, syms ++ ++def is_docstring(stmt): ++ return isinstance(stmt, pytree.Node) and \ ++ stmt.children[0].type == token.STRING ++ ++class FixTupleParams(fixer_base.BaseFix): ++ PATTERN = """ ++ funcdef< 'def' any parameters< '(' args=any ')' > ++ ['->' any] ':' suite=any+ > ++ | ++ lambda= ++ lambdef< 'lambda' args=vfpdef< '(' inner=any ')' > ++ ':' body=any ++ > ++ """ ++ ++ def transform(self, node, results): ++ if "lambda" in results: ++ return self.transform_lambda(node, results) ++ ++ new_lines = [] ++ suite = results["suite"] ++ args = results["args"] ++ # This crap is so "def foo(...): x = 5; y = 7" is handled correctly. ++ # TODO(cwinter): suite-cleanup ++ if suite[0].children[1].type == token.INDENT: ++ start = 2 ++ indent = suite[0].children[1].value ++ end = Newline() ++ else: ++ start = 0 ++ indent = "; " ++ end = pytree.Leaf(token.INDENT, "") ++ ++ # We need access to self for new_name(), and making this a method ++ # doesn't feel right. Closing over self and new_lines makes the ++ # code below cleaner. ++ def handle_tuple(tuple_arg, add_prefix=False): ++ n = Name(self.new_name()) ++ arg = tuple_arg.clone() ++ arg.set_prefix("") ++ stmt = Assign(arg, n.clone()) ++ if add_prefix: ++ n.set_prefix(" ") ++ tuple_arg.replace(n) ++ new_lines.append(pytree.Node(syms.simple_stmt, ++ [stmt, end.clone()])) ++ ++ if args.type == syms.tfpdef: ++ handle_tuple(args) ++ elif args.type == syms.typedargslist: ++ for i, arg in enumerate(args.children): ++ if arg.type == syms.tfpdef: ++ # Without add_prefix, the emitted code is correct, ++ # just ugly. ++ handle_tuple(arg, add_prefix=(i > 0)) ++ ++ if not new_lines: ++ return node ++ ++ # This isn't strictly necessary, but it plays nicely with other fixers. ++ # TODO(cwinter) get rid of this when children becomes a smart list ++ for line in new_lines: ++ line.parent = suite[0] ++ ++ # TODO(cwinter) suite-cleanup ++ after = start ++ if start == 0: ++ new_lines[0].set_prefix(" ") ++ elif is_docstring(suite[0].children[start]): ++ new_lines[0].set_prefix(indent) ++ after = start + 1 ++ ++ suite[0].children[after:after] = new_lines ++ for i in range(after+1, after+len(new_lines)+1): ++ suite[0].children[i].set_prefix(indent) ++ suite[0].changed() ++ ++ def transform_lambda(self, node, results): ++ args = results["args"] ++ body = results["body"] ++ inner = simplify_args(results["inner"]) ++ ++ # Replace lambda ((((x)))): x with lambda x: x ++ if inner.type == token.NAME: ++ inner = inner.clone() ++ inner.set_prefix(" ") ++ args.replace(inner) ++ return ++ ++ params = find_params(args) ++ to_index = map_to_index(params) ++ tup_name = self.new_name(tuple_name(params)) ++ ++ new_param = Name(tup_name, prefix=" ") ++ args.replace(new_param.clone()) ++ for n in body.post_order(): ++ if n.type == token.NAME and n.value in to_index: ++ subscripts = [c.clone() for c in to_index[n.value]] ++ new = pytree.Node(syms.power, ++ [new_param.clone()] + subscripts) ++ new.set_prefix(n.get_prefix()) ++ n.replace(new) ++ ++ ++### Helper functions for transform_lambda() ++ ++def simplify_args(node): ++ if node.type in (syms.vfplist, token.NAME): ++ return node ++ elif node.type == syms.vfpdef: ++ # These look like vfpdef< '(' x ')' > where x is NAME ++ # or another vfpdef instance (leading to recursion). ++ while node.type == syms.vfpdef: ++ node = node.children[1] ++ return node ++ raise RuntimeError("Received unexpected node %s" % node) ++ ++def find_params(node): ++ if node.type == syms.vfpdef: ++ return find_params(node.children[1]) ++ elif node.type == token.NAME: ++ return node.value ++ return [find_params(c) for c in node.children if c.type != token.COMMA] ++ ++def map_to_index(param_list, prefix=[], d=None): ++ if d is None: ++ d = {} ++ for i, obj in enumerate(param_list): ++ trailer = [Subscript(Number(i))] ++ if isinstance(obj, list): ++ map_to_index(obj, trailer, d=d) ++ else: ++ d[obj] = prefix + trailer ++ return d ++ ++def tuple_name(param_list): ++ l = [] ++ for obj in param_list: ++ if isinstance(obj, list): ++ l.append(tuple_name(obj)) ++ else: ++ l.append(obj) ++ return "_".join(l) +diff -r 531f2e948299 refactor/fixes/from2/fix_types.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_types.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,62 @@ ++# Copyright 2007 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer for removing uses of the types module. ++ ++These work for only the known names in the types module. The forms above ++can include types. or not. ie, It is assumed the module is imported either as: ++ ++ import types ++ from types import ... # either * or specific types ++ ++The import statements are not modified. ++ ++There should be another fixer that handles at least the following constants: ++ ++ type([]) -> list ++ type(()) -> tuple ++ type('') -> str ++ ++""" ++ ++# Local imports ++from ...pgen2 import token ++from ... import fixer_base ++from ...fixer_util import Name ++ ++_TYPE_MAPPING = { ++ 'BooleanType' : 'bool', ++ 'BufferType' : 'memoryview', ++ 'ClassType' : 'type', ++ 'ComplexType' : 'complex', ++ 'DictType': 'dict', ++ 'DictionaryType' : 'dict', ++ 'EllipsisType' : 'type(Ellipsis)', ++ #'FileType' : 'io.IOBase', ++ 'FloatType': 'float', ++ 'IntType': 'int', ++ 'ListType': 'list', ++ 'LongType': 'int', ++ 'ObjectType' : 'object', ++ 'NoneType': 'type(None)', ++ 'NotImplementedType' : 'type(NotImplemented)', ++ 'SliceType' : 'slice', ++ 'StringType': 'bytes', # XXX ? ++ 'StringTypes' : 'str', # XXX ? ++ 'TupleType': 'tuple', ++ 'TypeType' : 'type', ++ 'UnicodeType': 'str', ++ 'XRangeType' : 'range', ++ } ++ ++_pats = ["power< 'types' trailer< '.' name='%s' > >" % t for t in _TYPE_MAPPING] ++ ++class FixTypes(fixer_base.BaseFix): ++ ++ PATTERN = '|'.join(_pats) ++ ++ def transform(self, node, results): ++ new_value = _TYPE_MAPPING.get(results["name"].value) ++ if new_value: ++ return Name(new_value, prefix=node.get_prefix()) ++ return None +diff -r 531f2e948299 refactor/fixes/from2/fix_unicode.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_unicode.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,28 @@ ++"""Fixer that changes unicode to str, unichr to chr, and u"..." into "...". ++ ++""" ++ ++import re ++from ...pgen2 import token ++from ... import fixer_base ++ ++class FixUnicode(fixer_base.BaseFix): ++ ++ PATTERN = "STRING | NAME<'unicode' | 'unichr'>" ++ ++ def transform(self, node, results): ++ if node.type == token.NAME: ++ if node.value == "unicode": ++ new = node.clone() ++ new.value = "str" ++ return new ++ if node.value == "unichr": ++ new = node.clone() ++ new.value = "chr" ++ return new ++ # XXX Warn when __unicode__ found? ++ elif node.type == token.STRING: ++ if re.match(r"[uU][rR]?[\'\"]", node.value): ++ new = node.clone() ++ new.value = new.value[1:] ++ return new +diff -r 531f2e948299 refactor/fixes/from2/fix_urllib.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_urllib.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,180 @@ ++"""Fix changes imports of urllib which are now incompatible. ++ This is rather similar to fix_imports, but because of the more ++ complex nature of the fixing for urllib, it has its own fixer. ++""" ++# Author: Nick Edds ++ ++# Local imports ++from .fix_imports import alternates, FixImports ++from ... import fixer_base ++from ...fixer_util import Name, Comma, FromImport, Newline, attr_chain ++ ++MAPPING = {'urllib': [ ++ ('urllib.request', ++ ['URLOpener', 'FancyURLOpener', 'urlretrieve', ++ '_urlopener', 'urlcleanup']), ++ ('urllib.parse', ++ ['quote', 'quote_plus', 'unquote', 'unquote_plus', ++ 'urlencode', 'pathname2url', 'url2pathname', 'splitattr', ++ 'splithost', 'splitnport', 'splitpasswd', 'splitport', ++ 'splitquery', 'splittag', 'splittype', 'splituser', ++ 'splitvalue', ]), ++ ('urllib.error', ++ ['ContentTooShortError'])], ++ 'urllib2' : [ ++ ('urllib.request', ++ ['urlopen', 'install_opener', 'build_opener', ++ 'Request', 'OpenerDirector', 'BaseHandler', ++ 'HTTPDefaultErrorHandler', 'HTTPRedirectHandler', ++ 'HTTPCookieProcessor', 'ProxyHandler', ++ 'HTTPPasswordMgr', ++ 'HTTPPasswordMgrWithDefaultRealm', ++ 'AbstractBasicAuthHandler', ++ 'HTTPBasicAuthHandler', 'ProxyBasicAuthHandler', ++ 'AbstractDigestAuthHandler', ++ 'HTTPDigestAuthHandler', 'ProxyDigestAuthHandler', ++ 'HTTPHandler', 'HTTPSHandler', 'FileHandler', ++ 'FTPHandler', 'CacheFTPHandler', ++ 'UnknownHandler']), ++ ('urllib.error', ++ ['URLError', 'HTTPError']), ++ ] ++} ++ ++# Duplicate the url parsing functions for urllib2. ++MAPPING["urllib2"].append(MAPPING["urllib"][1]) ++ ++ ++def build_pattern(): ++ bare = set() ++ for old_module, changes in MAPPING.items(): ++ for change in changes: ++ new_module, members = change ++ members = alternates(members) ++ yield """import_name< 'import' (module=%r ++ | dotted_as_names< any* module=%r any* >) > ++ """ % (old_module, old_module) ++ yield """import_from< 'from' mod_member=%r 'import' ++ ( member=%s | import_as_name< member=%s 'as' any > | ++ import_as_names< members=any* >) > ++ """ % (old_module, members, members) ++ yield """import_from< 'from' module_star=%r 'import' star='*' > ++ """ % old_module ++ yield """import_name< 'import' ++ dotted_as_name< module_as=%r 'as' any > > ++ """ % old_module ++ yield """power< module_dot=%r trailer< '.' member=%s > any* > ++ """ % (old_module, members) ++ ++ ++class FixUrllib(FixImports): ++ ++ def build_pattern(self): ++ return "|".join(build_pattern()) ++ ++ def transform_import(self, node, results): ++ """Transform for the basic import case. Replaces the old ++ import name with a comma separated list of its ++ replacements. ++ """ ++ import_mod = results.get('module') ++ pref = import_mod.get_prefix() ++ ++ names = [] ++ ++ # create a Node list of the replacement modules ++ for name in MAPPING[import_mod.value][:-1]: ++ names.extend([Name(name[0], prefix=pref), Comma()]) ++ names.append(Name(MAPPING[import_mod.value][-1][0], prefix=pref)) ++ import_mod.replace(names) ++ ++ def transform_member(self, node, results): ++ """Transform for imports of specific module elements. Replaces ++ the module to be imported from with the appropriate new ++ module. ++ """ ++ mod_member = results.get('mod_member') ++ pref = mod_member.get_prefix() ++ member = results.get('member') ++ ++ # Simple case with only a single member being imported ++ if member: ++ # this may be a list of length one, or just a node ++ if isinstance(member, list): ++ member = member[0] ++ new_name = None ++ for change in MAPPING[mod_member.value]: ++ if member.value in change[1]: ++ new_name = change[0] ++ break ++ if new_name: ++ mod_member.replace(Name(new_name, prefix=pref)) ++ else: ++ self.cannot_convert(node, ++ 'This is an invalid module element') ++ ++ # Multiple members being imported ++ else: ++ # a dictionary for replacements, order matters ++ modules = [] ++ mod_dict = {} ++ members = results.get('members') ++ for member in members: ++ member = member.value ++ # we only care about the actual members ++ if member != ',': ++ for change in MAPPING[mod_member.value]: ++ if member in change[1]: ++ if change[0] in mod_dict: ++ mod_dict[change[0]].append(member) ++ else: ++ mod_dict[change[0]] = [member] ++ modules.append(change[0]) ++ ++ new_nodes = [] ++ for module in modules: ++ elts = mod_dict[module] ++ names = [] ++ for elt in elts[:-1]: ++ names.extend([Name(elt, prefix=pref), Comma()]) ++ names.append(Name(elts[-1], prefix=pref)) ++ new_nodes.append(FromImport(module, names)) ++ if new_nodes: ++ nodes = [] ++ for new_node in new_nodes[:-1]: ++ nodes.extend([new_node, Newline()]) ++ nodes.append(new_nodes[-1]) ++ node.replace(nodes) ++ else: ++ self.cannot_convert(node, 'All module elements are invalid') ++ ++ def transform_dot(self, node, results): ++ """Transform for calls to module members in code.""" ++ module_dot = results.get('module_dot') ++ member = results.get('member') ++ # this may be a list of length one, or just a node ++ if isinstance(member, list): ++ member = member[0] ++ new_name = None ++ for change in MAPPING[module_dot.value]: ++ if member.value in change[1]: ++ new_name = change[0] ++ break ++ if new_name: ++ module_dot.replace(Name(new_name, ++ prefix=module_dot.get_prefix())) ++ else: ++ self.cannot_convert(node, 'This is an invalid module element') ++ ++ def transform(self, node, results): ++ if results.get('module'): ++ self.transform_import(node, results) ++ elif results.get('mod_member'): ++ self.transform_member(node, results) ++ elif results.get('module_dot'): ++ self.transform_dot(node, results) ++ # Renaming and star imports are not supported for these modules. ++ elif results.get('module_star'): ++ self.cannot_convert(node, 'Cannot handle star imports.') ++ elif results.get('module_as'): ++ self.cannot_convert(node, 'This module is now multiple modules') +diff -r 531f2e948299 refactor/fixes/from2/fix_ws_comma.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_ws_comma.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,39 @@ ++"""Fixer that changes 'a ,b' into 'a, b'. ++ ++This also changes '{a :b}' into '{a: b}', but does not touch other ++uses of colons. It does not touch other uses of whitespace. ++ ++""" ++ ++from ... import pytree ++from ...pgen2 import token ++from ... import fixer_base ++ ++class FixWsComma(fixer_base.BaseFix): ++ ++ explicit = True # The user must ask for this fixers ++ ++ PATTERN = """ ++ any<(not(',') any)+ ',' ((not(',') any)+ ',')* [not(',') any]> ++ """ ++ ++ COMMA = pytree.Leaf(token.COMMA, ",") ++ COLON = pytree.Leaf(token.COLON, ":") ++ SEPS = (COMMA, COLON) ++ ++ def transform(self, node, results): ++ new = node.clone() ++ comma = False ++ for child in new.children: ++ if child in self.SEPS: ++ prefix = child.get_prefix() ++ if prefix.isspace() and "\n" not in prefix: ++ child.set_prefix("") ++ comma = True ++ else: ++ if comma: ++ prefix = child.get_prefix() ++ if not prefix: ++ child.set_prefix(" ") ++ comma = False ++ return new +diff -r 531f2e948299 refactor/fixes/from2/fix_xrange.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_xrange.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,64 @@ ++# Copyright 2007 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Fixer that changes xrange(...) into range(...).""" ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import Name, Call, consuming_calls ++from ... import patcomp ++ ++ ++class FixXrange(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ power< ++ (name='range'|name='xrange') trailer< '(' args=any ')' > ++ rest=any* > ++ """ ++ ++ def transform(self, node, results): ++ name = results["name"] ++ if name.value == "xrange": ++ return self.transform_xrange(node, results) ++ elif name.value == "range": ++ return self.transform_range(node, results) ++ else: ++ raise ValueError(repr(name)) ++ ++ def transform_xrange(self, node, results): ++ name = results["name"] ++ name.replace(Name("range", prefix=name.get_prefix())) ++ ++ def transform_range(self, node, results): ++ if not self.in_special_context(node): ++ range_call = Call(Name("range"), [results["args"].clone()]) ++ # Encase the range call in list(). ++ list_call = Call(Name("list"), [range_call], ++ prefix=node.get_prefix()) ++ # Put things that were after the range() call after the list call. ++ for n in results["rest"]: ++ list_call.append_child(n) ++ return list_call ++ return node ++ ++ P1 = "power< func=NAME trailer< '(' node=any ')' > any* >" ++ p1 = patcomp.compile_pattern(P1) ++ ++ P2 = """for_stmt< 'for' any 'in' node=any ':' any* > ++ | comp_for< 'for' any 'in' node=any any* > ++ | comparison< any 'in' node=any any*> ++ """ ++ p2 = patcomp.compile_pattern(P2) ++ ++ def in_special_context(self, node): ++ if node.parent is None: ++ return False ++ results = {} ++ if (node.parent.parent is not None and ++ self.p1.match(node.parent.parent, results) and ++ results["node"] is node): ++ # list(d.keys()) -> list(d.keys()), etc. ++ return results["func"].value in consuming_calls ++ # for ... in d.iterkeys() -> for ... in d.keys(), etc. ++ return self.p2.match(node.parent, results) and results["node"] is node +diff -r 531f2e948299 refactor/fixes/from2/fix_xreadlines.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_xreadlines.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,24 @@ ++"""Fix "for x in f.xreadlines()" -> "for x in f". ++ ++This fixer will also convert g(f.xreadlines) into g(f.__iter__).""" ++# Author: Collin Winter ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import Name ++ ++ ++class FixXreadlines(fixer_base.BaseFix): ++ PATTERN = """ ++ power< call=any+ trailer< '.' 'xreadlines' > trailer< '(' ')' > > ++ | ++ power< any+ trailer< '.' no_call='xreadlines' > > ++ """ ++ ++ def transform(self, node, results): ++ no_call = results.get("no_call") ++ ++ if no_call: ++ no_call.replace(Name("__iter__", prefix=no_call.get_prefix())) ++ else: ++ node.replace([x.clone() for x in results["call"]]) +diff -r 531f2e948299 refactor/fixes/from2/fix_zip.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from2/fix_zip.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,34 @@ ++""" ++Fixer that changes zip(seq0, seq1, ...) into list(zip(seq0, seq1, ...) ++unless there exists a 'from future_builtins import zip' statement in the ++top-level namespace. ++ ++We avoid the transformation if the zip() call is directly contained in ++iter(<>), list(<>), tuple(<>), sorted(<>), ...join(<>), or for V in <>:. ++""" ++ ++# Local imports ++from ... import fixer_base ++from ...fixer_util import Name, Call, in_special_context ++ ++class FixZip(fixer_base.ConditionalFix): ++ ++ PATTERN = """ ++ power< 'zip' args=trailer< '(' [any] ')' > ++ > ++ """ ++ ++ skip_on = "future_builtins.zip" ++ ++ def transform(self, node, results): ++ if self.should_skip(node): ++ return ++ ++ if in_special_context(node): ++ return None ++ ++ new = node.clone() ++ new.set_prefix("") ++ new = Call(Name("list"), [new]) ++ new.set_prefix(node.get_prefix()) ++ return new +diff -r 531f2e948299 refactor/fixes/from3/__init__.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from3/__init__.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,2 @@ ++from . import fix_range ++from . import fix_renames +diff -r 531f2e948299 refactor/fixes/from3/fix_range.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from3/fix_range.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,21 @@ ++# Based on fix_xrange.py ++# 3to2 modification by Paul Kippes ++ ++""" ++range(...) -> xrange(...) ++""" ++ ++from ..fixer_common import * ++ ++class FixRange(fixer_base.BaseFix): ++ ++ PATTERN = """ ++ power< ++ (name='range') trailer< '(' args=any ')' > ++ rest=any* > ++ """ ++ ++ def transform(self, node, results): ++ name = results["name"] ++ name.replace(Name("xrange", prefix=name.get_prefix())) ++ return node +diff -r 531f2e948299 refactor/fixes/from3/fix_renames.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/fixes/from3/fix_renames.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,69 @@ ++"""Fix incompatible renames ++ ++Incorporates simple compliment 3-to-2 transforms: ++ ++Fixes: ++ * sys.maxsize -> sys.maxint ++""" ++ ++# Local imports ++from ..fixer_common import * ++ ++MAPPING = {'sys': {'maxsize' : 'maxint', ++ }, ++ } ++LOOKUP = {} ++ ++def alternates(members): ++ return "(" + "|".join(map(repr, members)) + ")" ++ ++ ++def build_pattern(): ++ #bare = set() ++ for module, replace in MAPPING.items(): ++ for old_attr, new_attr in replace.items(): ++ LOOKUP[(module, old_attr)] = new_attr ++ #bare.add(module) ++ #bare.add(old_attr) ++ #yield """ ++ # import_name< 'import' (module=%r ++ # | dotted_as_names< any* module=%r any* >) > ++ # """ % (module, module) ++ yield """ ++ import_from< 'from' module_name=%r 'import' ++ ( attr_name=%r | import_as_name< attr_name=%r 'as' any >) > ++ """ % (module, old_attr, old_attr) ++ yield """ ++ power< module_name=%r trailer< '.' attr_name=%r > any* > ++ """ % (module, old_attr) ++ #yield """bare_name=%s""" % alternates(bare) ++ ++ ++class FixRenames(fixer_base.BaseFix): ++ PATTERN = "|".join(build_pattern()) ++ ++ order = "pre" # Pre-order tree traversal ++ ++ # Don't match the node if it's within another match ++ def match(self, node): ++ match = super(FixRenames, self).match ++ results = match(node) ++ if results: ++ if any([match(obj) for obj in attr_chain(node, "parent")]): ++ return False ++ return results ++ return False ++ ++ #def start_tree(self, tree, filename): ++ # super(FixRenames, self).start_tree(tree, filename) ++ # self.replace = {} ++ ++ def transform(self, node, results): ++ mod_name = results.get("module_name") ++ attr_name = results.get("attr_name") ++ #bare_name = results.get("bare_name") ++ #import_mod = results.get("module") ++ ++ if mod_name and attr_name: ++ new_attr = LOOKUP[(mod_name.value, attr_name.value)] ++ attr_name.replace(Name(new_attr, prefix=attr_name.get_prefix())) +diff -r 531f2e948299 refactor/main.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/main.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,134 @@ ++""" ++Main program for refactor. ++""" ++ ++import sys ++import os ++import logging ++import shutil ++import optparse ++ ++from . import refactor ++ ++ ++class StdoutRefactoringTool(refactor.RefactoringTool): ++ """ ++ Prints output to stdout. ++ """ ++ ++ def __init__(self, fixers, options, explicit, nobackups): ++ self.nobackups = nobackups ++ super(StdoutRefactoringTool, self).__init__(fixers, options, explicit) ++ ++ def log_error(self, msg, *args, **kwargs): ++ self.errors.append((msg, args, kwargs)) ++ self.logger.error(msg, *args, **kwargs) ++ ++ def write_file(self, new_text, filename, old_text): ++ if not self.nobackups: ++ # Make backup ++ backup = filename + ".bak" ++ if os.path.lexists(backup): ++ try: ++ os.remove(backup) ++ except os.error, err: ++ self.log_message("Can't remove backup %s", backup) ++ try: ++ os.rename(filename, backup) ++ except os.error, err: ++ self.log_message("Can't rename %s to %s", filename, backup) ++ # Actually write the new file ++ super(StdoutRefactoringTool, self).write_file(new_text, ++ filename, old_text) ++ if not self.nobackups: ++ shutil.copymode(backup, filename) ++ ++ def print_output(self, lines): ++ for line in lines: ++ print line ++ ++ ++def main(fixer_pkg, args=None): ++ """Main program. ++ ++ Args: ++ fixer_pkg: the name of a package where the fixers are located. ++ args: optional; a list of command line arguments. If omitted, ++ sys.argv[1:] is used. ++ ++ Returns a suggested exit status (0, 1, 2). ++ """ ++ # Set up option parser ++ parser = optparse.OptionParser(usage="%s [options] file|dir ..." % ++ sys.argv[0]) ++ parser.add_option("-d", "--doctests_only", action="store_true", ++ help="Fix up doctests only") ++ parser.add_option("-f", "--fix", action="append", default=[], ++ help="Each FIX specifies a transformation; default: all") ++ parser.add_option("-x", "--nofix", action="append", default=[], ++ help="Prevent a fixer from being run.") ++ parser.add_option("-l", "--list-fixes", action="store_true", ++ help="List available transformations (fixes/fix_*.py)") ++ parser.add_option("-p", "--print-function", action="store_true", ++ help="Modify the grammar so that print() is a function") ++ parser.add_option("-v", "--verbose", action="store_true", ++ help="More verbose logging") ++ 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.") ++ ++ # Parse command line arguments ++ refactor_stdin = False ++ options, args = parser.parse_args(args) ++ if not options.write and options.nobackups: ++ parser.error("Can't use -n without -w") ++ if options.list_fixes: ++ print "Available transformations for the -f/--fix option:" ++ for fixname in refactor.get_all_fix_names(fixer_pkg): ++ print fixname ++ if not args: ++ return 0 ++ if not args: ++ print >>sys.stderr, "At least one file or directory argument required." ++ print >>sys.stderr, "Use --help to show usage." ++ return 2 ++ if "-" in args: ++ refactor_stdin = True ++ if options.write: ++ print >>sys.stderr, "Can't write to stdin." ++ return 2 ++ ++ # Set up logging handler ++ level = logging.DEBUG if options.verbose else logging.INFO ++ logging.basicConfig(format='%(name)s: %(message)s', level=level) ++ ++ # Initialize the refactoring tool ++ rt_opts = {"print_function" : options.print_function} ++ avail_fixes = set(refactor.get_fixers_from_package(fixer_pkg)) ++ unwanted_fixes = set(fixer_pkg + ".fix_" + fix for fix in options.nofix) ++ explicit = set() ++ if options.fix: ++ all_present = False ++ for fix in options.fix: ++ if fix == "all": ++ all_present = True ++ else: ++ explicit.add(fixer_pkg + ".fix_" + fix) ++ requested = avail_fixes.union(explicit) if all_present else explicit ++ else: ++ requested = avail_fixes.union(explicit) ++ fixer_names = requested.difference(unwanted_fixes) ++ rt = StdoutRefactoringTool(sorted(fixer_names), rt_opts, sorted(explicit), ++ options.nobackups) ++ ++ # Refactor all files and directories passed as arguments ++ if not rt.errors: ++ if refactor_stdin: ++ rt.refactor_stdin() ++ else: ++ rt.refactor(args, options.write, options.doctests_only) ++ rt.summarize() ++ ++ # Return error status (0 if rt.errors is zero) ++ return int(bool(rt.errors)) +diff -r 531f2e948299 refactor/patcomp.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/patcomp.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,186 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Pattern compiler. ++ ++The grammer is taken from PatternGrammar.txt. ++ ++The compiler compiles a pattern to a pytree.*Pattern instance. ++""" ++ ++__author__ = "Guido van Rossum " ++ ++# Python imports ++import os ++ ++# Fairly local imports ++from .pgen2 import driver ++from .pgen2 import literals ++from .pgen2 import token ++from .pgen2 import tokenize ++ ++# Really local imports ++from . import pytree ++from . import pygram ++ ++# The pattern grammar file ++_PATTERN_GRAMMAR_FILE = os.path.join(os.path.dirname(__file__), ++ "PatternGrammar.txt") ++ ++ ++def tokenize_wrapper(input): ++ """Tokenizes a string suppressing significant whitespace.""" ++ skip = set((token.NEWLINE, token.INDENT, token.DEDENT)) ++ tokens = tokenize.generate_tokens(driver.generate_lines(input).next) ++ for quintuple in tokens: ++ type, value, start, end, line_text = quintuple ++ if type not in skip: ++ yield quintuple ++ ++ ++class PatternCompiler(object): ++ ++ def __init__(self, grammar_file=_PATTERN_GRAMMAR_FILE): ++ """Initializer. ++ ++ Takes an optional alternative filename for the pattern grammar. ++ """ ++ self.grammar = driver.load_grammar(grammar_file) ++ self.syms = pygram.Symbols(self.grammar) ++ self.pygrammar = pygram.python_grammar ++ self.pysyms = pygram.python_symbols ++ self.driver = driver.Driver(self.grammar, convert=pattern_convert) ++ ++ def compile_pattern(self, input, debug=False): ++ """Compiles a pattern string to a nested pytree.*Pattern object.""" ++ tokens = tokenize_wrapper(input) ++ root = self.driver.parse_tokens(tokens, debug=debug) ++ return self.compile_node(root) ++ ++ def compile_node(self, node): ++ """Compiles a node, recursively. ++ ++ This is one big switch on the node type. ++ """ ++ # XXX Optimize certain Wildcard-containing-Wildcard patterns ++ # that can be merged ++ if node.type == self.syms.Matcher: ++ node = node.children[0] # Avoid unneeded recursion ++ ++ if node.type == self.syms.Alternatives: ++ # Skip the odd children since they are just '|' tokens ++ alts = [self.compile_node(ch) for ch in node.children[::2]] ++ if len(alts) == 1: ++ return alts[0] ++ p = pytree.WildcardPattern([[a] for a in alts], min=1, max=1) ++ return p.optimize() ++ ++ if node.type == self.syms.Alternative: ++ units = [self.compile_node(ch) for ch in node.children] ++ if len(units) == 1: ++ return units[0] ++ p = pytree.WildcardPattern([units], min=1, max=1) ++ return p.optimize() ++ ++ if node.type == self.syms.NegatedUnit: ++ pattern = self.compile_basic(node.children[1:]) ++ p = pytree.NegatedPattern(pattern) ++ return p.optimize() ++ ++ assert node.type == self.syms.Unit ++ ++ name = None ++ nodes = node.children ++ if len(nodes) >= 3 and nodes[1].type == token.EQUAL: ++ name = nodes[0].value ++ nodes = nodes[2:] ++ repeat = None ++ if len(nodes) >= 2 and nodes[-1].type == self.syms.Repeater: ++ repeat = nodes[-1] ++ nodes = nodes[:-1] ++ ++ # Now we've reduced it to: STRING | NAME [Details] | (...) | [...] ++ pattern = self.compile_basic(nodes, repeat) ++ ++ if repeat is not None: ++ assert repeat.type == self.syms.Repeater ++ children = repeat.children ++ child = children[0] ++ if child.type == token.STAR: ++ min = 0 ++ max = pytree.HUGE ++ elif child.type == token.PLUS: ++ min = 1 ++ max = pytree.HUGE ++ elif child.type == token.LBRACE: ++ assert children[-1].type == token.RBRACE ++ assert len(children) in (3, 5) ++ min = max = self.get_int(children[1]) ++ if len(children) == 5: ++ max = self.get_int(children[3]) ++ else: ++ assert False ++ if min != 1 or max != 1: ++ pattern = pattern.optimize() ++ pattern = pytree.WildcardPattern([[pattern]], min=min, max=max) ++ ++ if name is not None: ++ pattern.name = name ++ return pattern.optimize() ++ ++ def compile_basic(self, nodes, repeat=None): ++ # Compile STRING | NAME [Details] | (...) | [...] ++ assert len(nodes) >= 1 ++ node = nodes[0] ++ if node.type == token.STRING: ++ value = literals.evalString(node.value) ++ return pytree.LeafPattern(content=value) ++ elif node.type == token.NAME: ++ value = node.value ++ if value.isupper(): ++ if value not in TOKEN_MAP: ++ raise SyntaxError("Invalid token: %r" % value) ++ return pytree.LeafPattern(TOKEN_MAP[value]) ++ else: ++ if value == "any": ++ type = None ++ elif not value.startswith("_"): ++ type = getattr(self.pysyms, value, None) ++ if type is None: ++ raise SyntaxError("Invalid symbol: %r" % value) ++ if nodes[1:]: # Details present ++ content = [self.compile_node(nodes[1].children[1])] ++ else: ++ content = None ++ return pytree.NodePattern(type, content) ++ elif node.value == "(": ++ return self.compile_node(nodes[1]) ++ elif node.value == "[": ++ assert repeat is None ++ subpattern = self.compile_node(nodes[1]) ++ return pytree.WildcardPattern([[subpattern]], min=0, max=1) ++ assert False, node ++ ++ def get_int(self, node): ++ assert node.type == token.NUMBER ++ return int(node.value) ++ ++ ++# Map named tokens to the type value for a LeafPattern ++TOKEN_MAP = {"NAME": token.NAME, ++ "STRING": token.STRING, ++ "NUMBER": token.NUMBER, ++ "TOKEN": None} ++ ++ ++def pattern_convert(grammar, raw_node_info): ++ """Converts raw node information to a Node or Leaf instance.""" ++ type, value, context, children = raw_node_info ++ if children or type in grammar.number2symbol: ++ return pytree.Node(type, children, context=context) ++ else: ++ return pytree.Leaf(type, value, context=context) ++ ++ ++def compile_pattern(pattern): ++ return PatternCompiler().compile_pattern(pattern) +diff -r 531f2e948299 refactor/pgen2/.svn/all-wcprops +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/.svn/all-wcprops Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,59 @@ ++K 25 ++svn:wc:ra_dav:version-url ++V 57 ++/projects/!svn/ver/68340/sandbox/trunk/2to3/lib2to3/pgen2 ++END ++tokenize.py ++K 25 ++svn:wc:ra_dav:version-url ++V 69 ++/projects/!svn/ver/61441/sandbox/trunk/2to3/lib2to3/pgen2/tokenize.py ++END ++pgen.py ++K 25 ++svn:wc:ra_dav:version-url ++V 65 ++/projects/!svn/ver/61629/sandbox/trunk/2to3/lib2to3/pgen2/pgen.py ++END ++parse.py ++K 25 ++svn:wc:ra_dav:version-url ++V 66 ++/projects/!svn/ver/67389/sandbox/trunk/2to3/lib2to3/pgen2/parse.py ++END ++driver.py ++K 25 ++svn:wc:ra_dav:version-url ++V 67 ++/projects/!svn/ver/68340/sandbox/trunk/2to3/lib2to3/pgen2/driver.py ++END ++__init__.py ++K 25 ++svn:wc:ra_dav:version-url ++V 69 ++/projects/!svn/ver/61441/sandbox/trunk/2to3/lib2to3/pgen2/__init__.py ++END ++literals.py ++K 25 ++svn:wc:ra_dav:version-url ++V 69 ++/projects/!svn/ver/61441/sandbox/trunk/2to3/lib2to3/pgen2/literals.py ++END ++token.py ++K 25 ++svn:wc:ra_dav:version-url ++V 66 ++/projects/!svn/ver/61441/sandbox/trunk/2to3/lib2to3/pgen2/token.py ++END ++conv.py ++K 25 ++svn:wc:ra_dav:version-url ++V 65 ++/projects/!svn/ver/61441/sandbox/trunk/2to3/lib2to3/pgen2/conv.py ++END ++grammar.py ++K 25 ++svn:wc:ra_dav:version-url ++V 68 ++/projects/!svn/ver/61441/sandbox/trunk/2to3/lib2to3/pgen2/grammar.py ++END +diff -r 531f2e948299 refactor/pgen2/.svn/dir-prop-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/.svn/dir-prop-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,8 @@ ++K 10 ++svn:ignore ++V 13 ++*.pyc ++*.pyo ++ ++ ++END +diff -r 531f2e948299 refactor/pgen2/.svn/entries +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/.svn/entries Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,334 @@ ++9 ++ ++dir ++70822 ++http://svn.python.org/projects/sandbox/trunk/2to3/lib2to3/pgen2 ++http://svn.python.org/projects ++ ++ ++ ++2009-01-05T08:11:39.704315Z ++68340 ++georg.brandl ++has-props ++ ++svn:special svn:externals svn:needs-lock ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++6015fed2-1504-0410-9fe1-9d1591cc4771 ++ ++tokenize.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:32.000000Z ++06aea8121aa7b0fc71345d011813d4b4 ++2008-03-17T16:59:51.273602Z ++61441 ++martin.v.loewis ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++16184 ++ ++pgen.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:32.000000Z ++40f1eec8af5247a511bf6acc34eac994 ++2008-03-19T16:58:19.069158Z ++61629 ++collin.winter ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++13740 ++ ++parse.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:32.000000Z ++80c0ee069eab8de116e1c13572d6cd4b ++2008-11-25T23:13:17.968453Z ++67389 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++8053 ++ ++driver.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:32.000000Z ++e2c063aca0163f8f47fefeab1a5cdff7 ++2009-01-05T08:11:39.704315Z ++68340 ++georg.brandl ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++4809 ++ ++__init__.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:32.000000Z ++5cb6bc9b6c96e165df87b615f2df9f1a ++2006-11-29T17:38:40.278528Z ++52858 ++guido.van.rossum ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++143 ++ ++literals.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:32.000000Z ++e3b1d03cade5fa0c3a1a5324e0b1e539 ++2006-11-29T17:38:40.278528Z ++52858 ++guido.van.rossum ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++1614 ++ ++token.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:32.000000Z ++8fd1f5c3fc2ad1b2afa7e17064b0ba04 ++2007-02-12T23:59:44.048119Z ++53758 ++collin.winter ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++1244 ++ ++conv.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:32.000000Z ++942a8910f37b9e5d202806ea05f7b2f1 ++2007-02-12T23:59:44.048119Z ++53758 ++collin.winter ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++9625 ++ ++grammar.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:32.000000Z ++612ee8e1a84660a7c44f7d5af3e7db69 ++2008-03-17T16:59:51.273602Z ++61441 ++martin.v.loewis ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++4947 ++ +diff -r 531f2e948299 refactor/pgen2/.svn/format +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/.svn/format Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,1 @@ ++9 +diff -r 531f2e948299 refactor/pgen2/.svn/prop-base/__init__.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/.svn/prop-base/__init__.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/pgen2/.svn/prop-base/conv.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/.svn/prop-base/conv.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/pgen2/.svn/prop-base/driver.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/.svn/prop-base/driver.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/pgen2/.svn/prop-base/grammar.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/.svn/prop-base/grammar.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/pgen2/.svn/prop-base/literals.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/.svn/prop-base/literals.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/pgen2/.svn/prop-base/parse.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/.svn/prop-base/parse.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/pgen2/.svn/prop-base/pgen.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/.svn/prop-base/pgen.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/pgen2/.svn/prop-base/token.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/.svn/prop-base/token.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,13 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 14 ++svn:executable ++V 1 ++* ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/pgen2/.svn/prop-base/tokenize.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/.svn/prop-base/tokenize.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 23 ++Author Date Id Revision ++END +diff -r 531f2e948299 refactor/pgen2/.svn/text-base/__init__.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/.svn/text-base/__init__.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,4 @@ ++# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""The pgen2 package.""" +diff -r 531f2e948299 refactor/pgen2/.svn/text-base/conv.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/.svn/text-base/conv.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,257 @@ ++# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Convert graminit.[ch] spit out by pgen to Python code. ++ ++Pgen is the Python parser generator. It is useful to quickly create a ++parser from a grammar file in Python's grammar notation. But I don't ++want my parsers to be written in C (yet), so I'm translating the ++parsing tables to Python data structures and writing a Python parse ++engine. ++ ++Note that the token numbers are constants determined by the standard ++Python tokenizer. The standard token module defines these numbers and ++their names (the names are not used much). The token numbers are ++hardcoded into the Python tokenizer and into pgen. A Python ++implementation of the Python tokenizer is also available, in the ++standard tokenize module. ++ ++On the other hand, symbol numbers (representing the grammar's ++non-terminals) are assigned by pgen based on the actual grammar ++input. ++ ++Note: this module is pretty much obsolete; the pgen module generates ++equivalent grammar tables directly from the Grammar.txt input file ++without having to invoke the Python pgen C program. ++ ++""" ++ ++# Python imports ++import re ++ ++# Local imports ++from pgen2 import grammar, token ++ ++ ++class Converter(grammar.Grammar): ++ """Grammar subclass that reads classic pgen output files. ++ ++ The run() method reads the tables as produced by the pgen parser ++ generator, typically contained in two C files, graminit.h and ++ graminit.c. The other methods are for internal use only. ++ ++ See the base class for more documentation. ++ ++ """ ++ ++ def run(self, graminit_h, graminit_c): ++ """Load the grammar tables from the text files written by pgen.""" ++ self.parse_graminit_h(graminit_h) ++ self.parse_graminit_c(graminit_c) ++ self.finish_off() ++ ++ def parse_graminit_h(self, filename): ++ """Parse the .h file writen by pgen. (Internal) ++ ++ This file is a sequence of #define statements defining the ++ nonterminals of the grammar as numbers. We build two tables ++ mapping the numbers to names and back. ++ ++ """ ++ try: ++ f = open(filename) ++ except IOError, err: ++ print "Can't open %s: %s" % (filename, err) ++ return False ++ self.symbol2number = {} ++ self.number2symbol = {} ++ lineno = 0 ++ for line in f: ++ lineno += 1 ++ mo = re.match(r"^#define\s+(\w+)\s+(\d+)$", line) ++ if not mo and line.strip(): ++ print "%s(%s): can't parse %s" % (filename, lineno, ++ line.strip()) ++ else: ++ symbol, number = mo.groups() ++ number = int(number) ++ assert symbol not in self.symbol2number ++ assert number not in self.number2symbol ++ self.symbol2number[symbol] = number ++ self.number2symbol[number] = symbol ++ return True ++ ++ def parse_graminit_c(self, filename): ++ """Parse the .c file writen by pgen. (Internal) ++ ++ The file looks as follows. The first two lines are always this: ++ ++ #include "pgenheaders.h" ++ #include "grammar.h" ++ ++ After that come four blocks: ++ ++ 1) one or more state definitions ++ 2) a table defining dfas ++ 3) a table defining labels ++ 4) a struct defining the grammar ++ ++ A state definition has the following form: ++ - one or more arc arrays, each of the form: ++ static arc arcs__[] = { ++ {, }, ++ ... ++ }; ++ - followed by a state array, of the form: ++ static state states_[] = { ++ {, arcs__}, ++ ... ++ }; ++ ++ """ ++ try: ++ f = open(filename) ++ except IOError, err: ++ print "Can't open %s: %s" % (filename, err) ++ return False ++ # The code below essentially uses f's iterator-ness! ++ lineno = 0 ++ ++ # Expect the two #include lines ++ lineno, line = lineno+1, f.next() ++ assert line == '#include "pgenheaders.h"\n', (lineno, line) ++ lineno, line = lineno+1, f.next() ++ assert line == '#include "grammar.h"\n', (lineno, line) ++ ++ # Parse the state definitions ++ lineno, line = lineno+1, f.next() ++ allarcs = {} ++ states = [] ++ while line.startswith("static arc "): ++ while line.startswith("static arc "): ++ mo = re.match(r"static arc arcs_(\d+)_(\d+)\[(\d+)\] = {$", ++ line) ++ assert mo, (lineno, line) ++ n, m, k = map(int, mo.groups()) ++ arcs = [] ++ for _ in range(k): ++ lineno, line = lineno+1, f.next() ++ mo = re.match(r"\s+{(\d+), (\d+)},$", line) ++ assert mo, (lineno, line) ++ i, j = map(int, mo.groups()) ++ arcs.append((i, j)) ++ lineno, line = lineno+1, f.next() ++ assert line == "};\n", (lineno, line) ++ allarcs[(n, m)] = arcs ++ lineno, line = lineno+1, f.next() ++ mo = re.match(r"static state states_(\d+)\[(\d+)\] = {$", line) ++ assert mo, (lineno, line) ++ s, t = map(int, mo.groups()) ++ assert s == len(states), (lineno, line) ++ state = [] ++ for _ in range(t): ++ lineno, line = lineno+1, f.next() ++ mo = re.match(r"\s+{(\d+), arcs_(\d+)_(\d+)},$", line) ++ assert mo, (lineno, line) ++ k, n, m = map(int, mo.groups()) ++ arcs = allarcs[n, m] ++ assert k == len(arcs), (lineno, line) ++ state.append(arcs) ++ states.append(state) ++ lineno, line = lineno+1, f.next() ++ assert line == "};\n", (lineno, line) ++ lineno, line = lineno+1, f.next() ++ self.states = states ++ ++ # Parse the dfas ++ dfas = {} ++ mo = re.match(r"static dfa dfas\[(\d+)\] = {$", line) ++ assert mo, (lineno, line) ++ ndfas = int(mo.group(1)) ++ for i in range(ndfas): ++ lineno, line = lineno+1, f.next() ++ mo = re.match(r'\s+{(\d+), "(\w+)", (\d+), (\d+), states_(\d+),$', ++ line) ++ assert mo, (lineno, line) ++ symbol = mo.group(2) ++ number, x, y, z = map(int, mo.group(1, 3, 4, 5)) ++ assert self.symbol2number[symbol] == number, (lineno, line) ++ assert self.number2symbol[number] == symbol, (lineno, line) ++ assert x == 0, (lineno, line) ++ state = states[z] ++ assert y == len(state), (lineno, line) ++ lineno, line = lineno+1, f.next() ++ mo = re.match(r'\s+("(?:\\\d\d\d)*")},$', line) ++ assert mo, (lineno, line) ++ first = {} ++ rawbitset = eval(mo.group(1)) ++ for i, c in enumerate(rawbitset): ++ byte = ord(c) ++ for j in range(8): ++ if byte & (1<= os.path.getmtime(b) +diff -r 531f2e948299 refactor/pgen2/.svn/text-base/grammar.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/.svn/text-base/grammar.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,171 @@ ++# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""This module defines the data structures used to represent a grammar. ++ ++These are a bit arcane because they are derived from the data ++structures used by Python's 'pgen' parser generator. ++ ++There's also a table here mapping operators to their names in the ++token module; the Python tokenize module reports all operators as the ++fallback token code OP, but the parser needs the actual token code. ++ ++""" ++ ++# Python imports ++import pickle ++ ++# Local imports ++from . import token, tokenize ++ ++ ++class Grammar(object): ++ """Pgen parsing tables tables conversion class. ++ ++ Once initialized, this class supplies the grammar tables for the ++ parsing engine implemented by parse.py. The parsing engine ++ accesses the instance variables directly. The class here does not ++ provide initialization of the tables; several subclasses exist to ++ do this (see the conv and pgen modules). ++ ++ The load() method reads the tables from a pickle file, which is ++ much faster than the other ways offered by subclasses. The pickle ++ file is written by calling dump() (after loading the grammar ++ tables using a subclass). The report() method prints a readable ++ representation of the tables to stdout, for debugging. ++ ++ The instance variables are as follows: ++ ++ symbol2number -- a dict mapping symbol names to numbers. Symbol ++ numbers are always 256 or higher, to distinguish ++ them from token numbers, which are between 0 and ++ 255 (inclusive). ++ ++ number2symbol -- a dict mapping numbers to symbol names; ++ these two are each other's inverse. ++ ++ states -- a list of DFAs, where each DFA is a list of ++ states, each state is is a list of arcs, and each ++ arc is a (i, j) pair where i is a label and j is ++ a state number. The DFA number is the index into ++ this list. (This name is slightly confusing.) ++ Final states are represented by a special arc of ++ the form (0, j) where j is its own state number. ++ ++ dfas -- a dict mapping symbol numbers to (DFA, first) ++ pairs, where DFA is an item from the states list ++ above, and first is a set of tokens that can ++ begin this grammar rule (represented by a dict ++ whose values are always 1). ++ ++ labels -- a list of (x, y) pairs where x is either a token ++ number or a symbol number, and y is either None ++ or a string; the strings are keywords. The label ++ number is the index in this list; label numbers ++ are used to mark state transitions (arcs) in the ++ DFAs. ++ ++ start -- the number of the grammar's start symbol. ++ ++ keywords -- a dict mapping keyword strings to arc labels. ++ ++ tokens -- a dict mapping token numbers to arc labels. ++ ++ """ ++ ++ def __init__(self): ++ self.symbol2number = {} ++ self.number2symbol = {} ++ self.states = [] ++ self.dfas = {} ++ self.labels = [(0, "EMPTY")] ++ self.keywords = {} ++ self.tokens = {} ++ self.symbol2label = {} ++ self.start = 256 ++ ++ def dump(self, filename): ++ """Dump the grammar tables to a pickle file.""" ++ f = open(filename, "wb") ++ pickle.dump(self.__dict__, f, 2) ++ f.close() ++ ++ def load(self, filename): ++ """Load the grammar tables from a pickle file.""" ++ f = open(filename, "rb") ++ d = pickle.load(f) ++ f.close() ++ self.__dict__.update(d) ++ ++ def report(self): ++ """Dump the grammar tables to standard output, for debugging.""" ++ from pprint import pprint ++ print "s2n" ++ pprint(self.symbol2number) ++ print "n2s" ++ pprint(self.number2symbol) ++ print "states" ++ pprint(self.states) ++ print "dfas" ++ pprint(self.dfas) ++ print "labels" ++ pprint(self.labels) ++ print "start", self.start ++ ++ ++# Map from operator to number (since tokenize doesn't do this) ++ ++opmap_raw = """ ++( LPAR ++) RPAR ++[ LSQB ++] RSQB ++: COLON ++, COMMA ++; SEMI +++ PLUS ++- MINUS ++* STAR ++/ SLASH ++| VBAR ++& AMPER ++< LESS ++> GREATER ++= EQUAL ++. DOT ++% PERCENT ++` BACKQUOTE ++{ LBRACE ++} RBRACE ++@ AT ++== EQEQUAL ++!= NOTEQUAL ++<> NOTEQUAL ++<= LESSEQUAL ++>= GREATEREQUAL ++~ TILDE ++^ CIRCUMFLEX ++<< LEFTSHIFT ++>> RIGHTSHIFT ++** DOUBLESTAR +++= PLUSEQUAL ++-= MINEQUAL ++*= STAREQUAL ++/= SLASHEQUAL ++%= PERCENTEQUAL ++&= AMPEREQUAL ++|= VBAREQUAL ++^= CIRCUMFLEXEQUAL ++<<= LEFTSHIFTEQUAL ++>>= RIGHTSHIFTEQUAL ++**= DOUBLESTAREQUAL ++// DOUBLESLASH ++//= DOUBLESLASHEQUAL ++-> RARROW ++""" ++ ++opmap = {} ++for line in opmap_raw.splitlines(): ++ if line: ++ op, name = line.split() ++ opmap[op] = getattr(token, name) +diff -r 531f2e948299 refactor/pgen2/.svn/text-base/literals.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/.svn/text-base/literals.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,60 @@ ++# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Safely evaluate Python string literals without using eval().""" ++ ++import re ++ ++simple_escapes = {"a": "\a", ++ "b": "\b", ++ "f": "\f", ++ "n": "\n", ++ "r": "\r", ++ "t": "\t", ++ "v": "\v", ++ "'": "'", ++ '"': '"', ++ "\\": "\\"} ++ ++def escape(m): ++ all, tail = m.group(0, 1) ++ assert all.startswith("\\") ++ esc = simple_escapes.get(tail) ++ if esc is not None: ++ return esc ++ if tail.startswith("x"): ++ hexes = tail[1:] ++ if len(hexes) < 2: ++ raise ValueError("invalid hex string escape ('\\%s')" % tail) ++ try: ++ i = int(hexes, 16) ++ except ValueError: ++ raise ValueError("invalid hex string escape ('\\%s')" % tail) ++ else: ++ try: ++ i = int(tail, 8) ++ except ValueError: ++ raise ValueError("invalid octal string escape ('\\%s')" % tail) ++ return chr(i) ++ ++def evalString(s): ++ assert s.startswith("'") or s.startswith('"'), repr(s[:1]) ++ q = s[0] ++ if s[:3] == q*3: ++ q = q*3 ++ assert s.endswith(q), repr(s[-len(q):]) ++ assert len(s) >= 2*len(q) ++ s = s[len(q):-len(q)] ++ return re.sub(r"\\(\'|\"|\\|[abfnrtv]|x.{0,2}|[0-7]{1,3})", escape, s) ++ ++def test(): ++ for i in range(256): ++ c = chr(i) ++ s = repr(c) ++ e = evalString(s) ++ if e != c: ++ print i, c, s, e ++ ++ ++if __name__ == "__main__": ++ test() +diff -r 531f2e948299 refactor/pgen2/.svn/text-base/parse.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/.svn/text-base/parse.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,201 @@ ++# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Parser engine for the grammar tables generated by pgen. ++ ++The grammar table must be loaded first. ++ ++See Parser/parser.c in the Python distribution for additional info on ++how this parsing engine works. ++ ++""" ++ ++# Local imports ++from . import token ++ ++class ParseError(Exception): ++ """Exception to signal the parser is stuck.""" ++ ++ def __init__(self, msg, type, value, context): ++ Exception.__init__(self, "%s: type=%r, value=%r, context=%r" % ++ (msg, type, value, context)) ++ self.msg = msg ++ self.type = type ++ self.value = value ++ self.context = context ++ ++class Parser(object): ++ """Parser engine. ++ ++ The proper usage sequence is: ++ ++ p = Parser(grammar, [converter]) # create instance ++ p.setup([start]) # prepare for parsing ++ : ++ if p.addtoken(...): # parse a token; may raise ParseError ++ break ++ root = p.rootnode # root of abstract syntax tree ++ ++ A Parser instance may be reused by calling setup() repeatedly. ++ ++ A Parser instance contains state pertaining to the current token ++ sequence, and should not be used concurrently by different threads ++ to parse separate token sequences. ++ ++ See driver.py for how to get input tokens by tokenizing a file or ++ string. ++ ++ Parsing is complete when addtoken() returns True; the root of the ++ abstract syntax tree can then be retrieved from the rootnode ++ instance variable. When a syntax error occurs, addtoken() raises ++ the ParseError exception. There is no error recovery; the parser ++ cannot be used after a syntax error was reported (but it can be ++ reinitialized by calling setup()). ++ ++ """ ++ ++ def __init__(self, grammar, convert=None): ++ """Constructor. ++ ++ The grammar argument is a grammar.Grammar instance; see the ++ grammar module for more information. ++ ++ The parser is not ready yet for parsing; you must call the ++ setup() method to get it started. ++ ++ The optional convert argument is a function mapping concrete ++ syntax tree nodes to abstract syntax tree nodes. If not ++ given, no conversion is done and the syntax tree produced is ++ the concrete syntax tree. If given, it must be a function of ++ two arguments, the first being the grammar (a grammar.Grammar ++ instance), and the second being the concrete syntax tree node ++ to be converted. The syntax tree is converted from the bottom ++ up. ++ ++ A concrete syntax tree node is a (type, value, context, nodes) ++ tuple, where type is the node type (a token or symbol number), ++ value is None for symbols and a string for tokens, context is ++ None or an opaque value used for error reporting (typically a ++ (lineno, offset) pair), and nodes is a list of children for ++ symbols, and None for tokens. ++ ++ An abstract syntax tree node may be anything; this is entirely ++ up to the converter function. ++ ++ """ ++ self.grammar = grammar ++ self.convert = convert or (lambda grammar, node: node) ++ ++ def setup(self, start=None): ++ """Prepare for parsing. ++ ++ This *must* be called before starting to parse. ++ ++ The optional argument is an alternative start symbol; it ++ defaults to the grammar's start symbol. ++ ++ You can use a Parser instance to parse any number of programs; ++ each time you call setup() the parser is reset to an initial ++ state determined by the (implicit or explicit) start symbol. ++ ++ """ ++ if start is None: ++ start = self.grammar.start ++ # Each stack entry is a tuple: (dfa, state, node). ++ # A node is a tuple: (type, value, context, children), ++ # where children is a list of nodes or None, and context may be None. ++ newnode = (start, None, None, []) ++ stackentry = (self.grammar.dfas[start], 0, newnode) ++ self.stack = [stackentry] ++ self.rootnode = None ++ self.used_names = set() # Aliased to self.rootnode.used_names in pop() ++ ++ def addtoken(self, type, value, context): ++ """Add a token; return True iff this is the end of the program.""" ++ # Map from token to label ++ ilabel = self.classify(type, value, context) ++ # Loop until the token is shifted; may raise exceptions ++ while True: ++ dfa, state, node = self.stack[-1] ++ states, first = dfa ++ arcs = states[state] ++ # Look for a state with this label ++ for i, newstate in arcs: ++ t, v = self.grammar.labels[i] ++ if ilabel == i: ++ # Look it up in the list of labels ++ assert t < 256 ++ # Shift a token; we're done with it ++ self.shift(type, value, newstate, context) ++ # Pop while we are in an accept-only state ++ state = newstate ++ while states[state] == [(0, state)]: ++ self.pop() ++ if not self.stack: ++ # Done parsing! ++ return True ++ dfa, state, node = self.stack[-1] ++ states, first = dfa ++ # Done with this token ++ return False ++ elif t >= 256: ++ # See if it's a symbol and if we're in its first set ++ itsdfa = self.grammar.dfas[t] ++ itsstates, itsfirst = itsdfa ++ if ilabel in itsfirst: ++ # Push a symbol ++ self.push(t, self.grammar.dfas[t], newstate, context) ++ break # To continue the outer while loop ++ else: ++ if (0, state) in arcs: ++ # An accepting state, pop it and try something else ++ self.pop() ++ if not self.stack: ++ # Done parsing, but another token is input ++ raise ParseError("too much input", ++ type, value, context) ++ else: ++ # No success finding a transition ++ raise ParseError("bad input", type, value, context) ++ ++ def classify(self, type, value, context): ++ """Turn a token into a label. (Internal)""" ++ if type == token.NAME: ++ # Keep a listing of all used names ++ self.used_names.add(value) ++ # Check for reserved words ++ ilabel = self.grammar.keywords.get(value) ++ if ilabel is not None: ++ return ilabel ++ ilabel = self.grammar.tokens.get(type) ++ if ilabel is None: ++ raise ParseError("bad token", type, value, context) ++ return ilabel ++ ++ def shift(self, type, value, newstate, context): ++ """Shift a token. (Internal)""" ++ dfa, state, node = self.stack[-1] ++ newnode = (type, value, context, None) ++ newnode = self.convert(self.grammar, newnode) ++ if newnode is not None: ++ node[-1].append(newnode) ++ self.stack[-1] = (dfa, newstate, node) ++ ++ def push(self, type, newdfa, newstate, context): ++ """Push a nonterminal. (Internal)""" ++ dfa, state, node = self.stack[-1] ++ newnode = (type, None, context, []) ++ self.stack[-1] = (dfa, newstate, node) ++ self.stack.append((newdfa, 0, newnode)) ++ ++ def pop(self): ++ """Pop a nonterminal. (Internal)""" ++ popdfa, popstate, popnode = self.stack.pop() ++ newnode = self.convert(self.grammar, popnode) ++ if newnode is not None: ++ if self.stack: ++ dfa, state, node = self.stack[-1] ++ node[-1].append(newnode) ++ else: ++ self.rootnode = newnode ++ self.rootnode.used_names = self.used_names +diff -r 531f2e948299 refactor/pgen2/.svn/text-base/pgen.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/.svn/text-base/pgen.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,384 @@ ++# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++# Pgen imports ++from . import grammar, token, tokenize ++ ++class PgenGrammar(grammar.Grammar): ++ pass ++ ++class ParserGenerator(object): ++ ++ def __init__(self, filename, stream=None): ++ close_stream = None ++ if stream is None: ++ stream = open(filename) ++ close_stream = stream.close ++ self.filename = filename ++ self.stream = stream ++ self.generator = tokenize.generate_tokens(stream.readline) ++ self.gettoken() # Initialize lookahead ++ self.dfas, self.startsymbol = self.parse() ++ if close_stream is not None: ++ close_stream() ++ self.first = {} # map from symbol name to set of tokens ++ self.addfirstsets() ++ ++ def make_grammar(self): ++ c = PgenGrammar() ++ names = self.dfas.keys() ++ names.sort() ++ names.remove(self.startsymbol) ++ names.insert(0, self.startsymbol) ++ for name in names: ++ i = 256 + len(c.symbol2number) ++ c.symbol2number[name] = i ++ c.number2symbol[i] = name ++ for name in names: ++ dfa = self.dfas[name] ++ states = [] ++ for state in dfa: ++ arcs = [] ++ for label, next in state.arcs.iteritems(): ++ arcs.append((self.make_label(c, label), dfa.index(next))) ++ if state.isfinal: ++ arcs.append((0, dfa.index(state))) ++ states.append(arcs) ++ c.states.append(states) ++ c.dfas[c.symbol2number[name]] = (states, self.make_first(c, name)) ++ c.start = c.symbol2number[self.startsymbol] ++ return c ++ ++ def make_first(self, c, name): ++ rawfirst = self.first[name] ++ first = {} ++ for label in rawfirst: ++ ilabel = self.make_label(c, label) ++ ##assert ilabel not in first # XXX failed on <> ... != ++ first[ilabel] = 1 ++ return first ++ ++ def make_label(self, c, label): ++ # XXX Maybe this should be a method on a subclass of converter? ++ ilabel = len(c.labels) ++ if label[0].isalpha(): ++ # Either a symbol name or a named token ++ if label in c.symbol2number: ++ # A symbol name (a non-terminal) ++ if label in c.symbol2label: ++ return c.symbol2label[label] ++ else: ++ c.labels.append((c.symbol2number[label], None)) ++ c.symbol2label[label] = ilabel ++ return ilabel ++ else: ++ # A named token (NAME, NUMBER, STRING) ++ itoken = getattr(token, label, None) ++ assert isinstance(itoken, int), label ++ assert itoken in token.tok_name, label ++ if itoken in c.tokens: ++ return c.tokens[itoken] ++ else: ++ c.labels.append((itoken, None)) ++ c.tokens[itoken] = ilabel ++ return ilabel ++ else: ++ # Either a keyword or an operator ++ assert label[0] in ('"', "'"), label ++ value = eval(label) ++ if value[0].isalpha(): ++ # A keyword ++ if value in c.keywords: ++ return c.keywords[value] ++ else: ++ c.labels.append((token.NAME, value)) ++ c.keywords[value] = ilabel ++ return ilabel ++ else: ++ # An operator (any non-numeric token) ++ itoken = grammar.opmap[value] # Fails if unknown token ++ if itoken in c.tokens: ++ return c.tokens[itoken] ++ else: ++ c.labels.append((itoken, None)) ++ c.tokens[itoken] = ilabel ++ return ilabel ++ ++ def addfirstsets(self): ++ names = self.dfas.keys() ++ names.sort() ++ for name in names: ++ if name not in self.first: ++ self.calcfirst(name) ++ #print name, self.first[name].keys() ++ ++ def calcfirst(self, name): ++ dfa = self.dfas[name] ++ self.first[name] = None # dummy to detect left recursion ++ state = dfa[0] ++ totalset = {} ++ overlapcheck = {} ++ for label, next in state.arcs.iteritems(): ++ if label in self.dfas: ++ if label in self.first: ++ fset = self.first[label] ++ if fset is None: ++ raise ValueError("recursion for rule %r" % name) ++ else: ++ self.calcfirst(label) ++ fset = self.first[label] ++ totalset.update(fset) ++ overlapcheck[label] = fset ++ else: ++ totalset[label] = 1 ++ overlapcheck[label] = {label: 1} ++ inverse = {} ++ for label, itsfirst in overlapcheck.iteritems(): ++ for symbol in itsfirst: ++ if symbol in inverse: ++ raise ValueError("rule %s is ambiguous; %s is in the" ++ " first sets of %s as well as %s" % ++ (name, symbol, label, inverse[symbol])) ++ inverse[symbol] = label ++ self.first[name] = totalset ++ ++ def parse(self): ++ dfas = {} ++ startsymbol = None ++ # MSTART: (NEWLINE | RULE)* ENDMARKER ++ while self.type != token.ENDMARKER: ++ while self.type == token.NEWLINE: ++ self.gettoken() ++ # RULE: NAME ':' RHS NEWLINE ++ name = self.expect(token.NAME) ++ self.expect(token.OP, ":") ++ a, z = self.parse_rhs() ++ self.expect(token.NEWLINE) ++ #self.dump_nfa(name, a, z) ++ dfa = self.make_dfa(a, z) ++ #self.dump_dfa(name, dfa) ++ oldlen = len(dfa) ++ self.simplify_dfa(dfa) ++ newlen = len(dfa) ++ dfas[name] = dfa ++ #print name, oldlen, newlen ++ if startsymbol is None: ++ startsymbol = name ++ return dfas, startsymbol ++ ++ def make_dfa(self, start, finish): ++ # To turn an NFA into a DFA, we define the states of the DFA ++ # to correspond to *sets* of states of the NFA. Then do some ++ # state reduction. Let's represent sets as dicts with 1 for ++ # values. ++ assert isinstance(start, NFAState) ++ assert isinstance(finish, NFAState) ++ def closure(state): ++ base = {} ++ addclosure(state, base) ++ return base ++ def addclosure(state, base): ++ assert isinstance(state, NFAState) ++ if state in base: ++ return ++ base[state] = 1 ++ for label, next in state.arcs: ++ if label is None: ++ addclosure(next, base) ++ states = [DFAState(closure(start), finish)] ++ for state in states: # NB states grows while we're iterating ++ arcs = {} ++ for nfastate in state.nfaset: ++ for label, next in nfastate.arcs: ++ if label is not None: ++ addclosure(next, arcs.setdefault(label, {})) ++ for label, nfaset in arcs.iteritems(): ++ for st in states: ++ if st.nfaset == nfaset: ++ break ++ else: ++ st = DFAState(nfaset, finish) ++ states.append(st) ++ state.addarc(st, label) ++ return states # List of DFAState instances; first one is start ++ ++ def dump_nfa(self, name, start, finish): ++ print "Dump of NFA for", name ++ todo = [start] ++ for i, state in enumerate(todo): ++ print " State", i, state is finish and "(final)" or "" ++ for label, next in state.arcs: ++ if next in todo: ++ j = todo.index(next) ++ else: ++ j = len(todo) ++ todo.append(next) ++ if label is None: ++ print " -> %d" % j ++ else: ++ print " %s -> %d" % (label, j) ++ ++ def dump_dfa(self, name, dfa): ++ print "Dump of DFA for", name ++ for i, state in enumerate(dfa): ++ print " State", i, state.isfinal and "(final)" or "" ++ for label, next in state.arcs.iteritems(): ++ print " %s -> %d" % (label, dfa.index(next)) ++ ++ def simplify_dfa(self, dfa): ++ # This is not theoretically optimal, but works well enough. ++ # Algorithm: repeatedly look for two states that have the same ++ # set of arcs (same labels pointing to the same nodes) and ++ # unify them, until things stop changing. ++ ++ # dfa is a list of DFAState instances ++ changes = True ++ while changes: ++ changes = False ++ for i, state_i in enumerate(dfa): ++ for j in range(i+1, len(dfa)): ++ state_j = dfa[j] ++ if state_i == state_j: ++ #print " unify", i, j ++ del dfa[j] ++ for state in dfa: ++ state.unifystate(state_j, state_i) ++ changes = True ++ break ++ ++ def parse_rhs(self): ++ # RHS: ALT ('|' ALT)* ++ a, z = self.parse_alt() ++ if self.value != "|": ++ return a, z ++ else: ++ aa = NFAState() ++ zz = NFAState() ++ aa.addarc(a) ++ z.addarc(zz) ++ while self.value == "|": ++ self.gettoken() ++ a, z = self.parse_alt() ++ aa.addarc(a) ++ z.addarc(zz) ++ return aa, zz ++ ++ def parse_alt(self): ++ # ALT: ITEM+ ++ a, b = self.parse_item() ++ while (self.value in ("(", "[") or ++ self.type in (token.NAME, token.STRING)): ++ c, d = self.parse_item() ++ b.addarc(c) ++ b = d ++ return a, b ++ ++ def parse_item(self): ++ # ITEM: '[' RHS ']' | ATOM ['+' | '*'] ++ if self.value == "[": ++ self.gettoken() ++ a, z = self.parse_rhs() ++ self.expect(token.OP, "]") ++ a.addarc(z) ++ return a, z ++ else: ++ a, z = self.parse_atom() ++ value = self.value ++ if value not in ("+", "*"): ++ return a, z ++ self.gettoken() ++ z.addarc(a) ++ if value == "+": ++ return a, z ++ else: ++ return a, a ++ ++ def parse_atom(self): ++ # ATOM: '(' RHS ')' | NAME | STRING ++ if self.value == "(": ++ self.gettoken() ++ a, z = self.parse_rhs() ++ self.expect(token.OP, ")") ++ return a, z ++ elif self.type in (token.NAME, token.STRING): ++ a = NFAState() ++ z = NFAState() ++ a.addarc(z, self.value) ++ self.gettoken() ++ return a, z ++ else: ++ self.raise_error("expected (...) or NAME or STRING, got %s/%s", ++ self.type, self.value) ++ ++ def expect(self, type, value=None): ++ if self.type != type or (value is not None and self.value != value): ++ self.raise_error("expected %s/%s, got %s/%s", ++ type, value, self.type, self.value) ++ value = self.value ++ self.gettoken() ++ return value ++ ++ def gettoken(self): ++ tup = self.generator.next() ++ while tup[0] in (tokenize.COMMENT, tokenize.NL): ++ tup = self.generator.next() ++ self.type, self.value, self.begin, self.end, self.line = tup ++ #print token.tok_name[self.type], repr(self.value) ++ ++ def raise_error(self, msg, *args): ++ if args: ++ try: ++ msg = msg % args ++ except: ++ msg = " ".join([msg] + map(str, args)) ++ raise SyntaxError(msg, (self.filename, self.end[0], ++ self.end[1], self.line)) ++ ++class NFAState(object): ++ ++ def __init__(self): ++ self.arcs = [] # list of (label, NFAState) pairs ++ ++ def addarc(self, next, label=None): ++ assert label is None or isinstance(label, str) ++ assert isinstance(next, NFAState) ++ self.arcs.append((label, next)) ++ ++class DFAState(object): ++ ++ def __init__(self, nfaset, final): ++ assert isinstance(nfaset, dict) ++ assert isinstance(iter(nfaset).next(), NFAState) ++ assert isinstance(final, NFAState) ++ self.nfaset = nfaset ++ self.isfinal = final in nfaset ++ self.arcs = {} # map from label to DFAState ++ ++ def addarc(self, next, label): ++ assert isinstance(label, str) ++ assert label not in self.arcs ++ assert isinstance(next, DFAState) ++ self.arcs[label] = next ++ ++ def unifystate(self, old, new): ++ for label, next in self.arcs.iteritems(): ++ if next is old: ++ self.arcs[label] = new ++ ++ def __eq__(self, other): ++ # Equality test -- ignore the nfaset instance variable ++ assert isinstance(other, DFAState) ++ if self.isfinal != other.isfinal: ++ return False ++ # Can't just return self.arcs == other.arcs, because that ++ # would invoke this method recursively, with cycles... ++ if len(self.arcs) != len(other.arcs): ++ return False ++ for label, next in self.arcs.iteritems(): ++ if next is not other.arcs.get(label): ++ return False ++ return True ++ ++def generate_grammar(filename="Grammar.txt"): ++ p = ParserGenerator(filename) ++ return p.make_grammar() +diff -r 531f2e948299 refactor/pgen2/.svn/text-base/token.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/.svn/text-base/token.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,82 @@ ++#! /usr/bin/env python ++ ++"""Token constants (from "token.h").""" ++ ++# Taken from Python (r53757) and modified to include some tokens ++# originally monkeypatched in by pgen2.tokenize ++ ++#--start constants-- ++ENDMARKER = 0 ++NAME = 1 ++NUMBER = 2 ++STRING = 3 ++NEWLINE = 4 ++INDENT = 5 ++DEDENT = 6 ++LPAR = 7 ++RPAR = 8 ++LSQB = 9 ++RSQB = 10 ++COLON = 11 ++COMMA = 12 ++SEMI = 13 ++PLUS = 14 ++MINUS = 15 ++STAR = 16 ++SLASH = 17 ++VBAR = 18 ++AMPER = 19 ++LESS = 20 ++GREATER = 21 ++EQUAL = 22 ++DOT = 23 ++PERCENT = 24 ++BACKQUOTE = 25 ++LBRACE = 26 ++RBRACE = 27 ++EQEQUAL = 28 ++NOTEQUAL = 29 ++LESSEQUAL = 30 ++GREATEREQUAL = 31 ++TILDE = 32 ++CIRCUMFLEX = 33 ++LEFTSHIFT = 34 ++RIGHTSHIFT = 35 ++DOUBLESTAR = 36 ++PLUSEQUAL = 37 ++MINEQUAL = 38 ++STAREQUAL = 39 ++SLASHEQUAL = 40 ++PERCENTEQUAL = 41 ++AMPEREQUAL = 42 ++VBAREQUAL = 43 ++CIRCUMFLEXEQUAL = 44 ++LEFTSHIFTEQUAL = 45 ++RIGHTSHIFTEQUAL = 46 ++DOUBLESTAREQUAL = 47 ++DOUBLESLASH = 48 ++DOUBLESLASHEQUAL = 49 ++AT = 50 ++OP = 51 ++COMMENT = 52 ++NL = 53 ++RARROW = 54 ++ERRORTOKEN = 55 ++N_TOKENS = 56 ++NT_OFFSET = 256 ++#--end constants-- ++ ++tok_name = {} ++for _name, _value in globals().items(): ++ if type(_value) is type(0): ++ tok_name[_value] = _name ++ ++ ++def ISTERMINAL(x): ++ return x < NT_OFFSET ++ ++def ISNONTERMINAL(x): ++ return x >= NT_OFFSET ++ ++def ISEOF(x): ++ return x == ENDMARKER +diff -r 531f2e948299 refactor/pgen2/.svn/text-base/tokenize.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/.svn/text-base/tokenize.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,405 @@ ++# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation. ++# All rights reserved. ++ ++"""Tokenization help for Python programs. ++ ++generate_tokens(readline) is a generator that breaks a stream of ++text into Python tokens. It accepts a readline-like method which is called ++repeatedly to get the next line of input (or "" for EOF). It generates ++5-tuples with these members: ++ ++ the token type (see token.py) ++ the token (a string) ++ the starting (row, column) indices of the token (a 2-tuple of ints) ++ the ending (row, column) indices of the token (a 2-tuple of ints) ++ the original line (string) ++ ++It is designed to match the working of the Python tokenizer exactly, except ++that it produces COMMENT tokens for comments and gives type OP for all ++operators ++ ++Older entry points ++ tokenize_loop(readline, tokeneater) ++ tokenize(readline, tokeneater=printtoken) ++are the same, except instead of generating tokens, tokeneater is a callback ++function to which the 5 fields described above are passed as 5 arguments, ++each time a new token is found.""" ++ ++__author__ = 'Ka-Ping Yee ' ++__credits__ = \ ++ 'GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, Skip Montanaro' ++ ++import string, re ++from lib2to3.pgen2.token import * ++ ++from . import token ++__all__ = [x for x in dir(token) if x[0] != '_'] + ["tokenize", ++ "generate_tokens", "untokenize"] ++del token ++ ++def group(*choices): return '(' + '|'.join(choices) + ')' ++def any(*choices): return group(*choices) + '*' ++def maybe(*choices): return group(*choices) + '?' ++ ++Whitespace = r'[ \f\t]*' ++Comment = r'#[^\r\n]*' ++Ignore = Whitespace + any(r'\\\r?\n' + Whitespace) + maybe(Comment) ++Name = r'[a-zA-Z_]\w*' ++ ++Binnumber = r'0[bB][01]*' ++Hexnumber = r'0[xX][\da-fA-F]*[lL]?' ++Octnumber = r'0[oO]?[0-7]*[lL]?' ++Decnumber = r'[1-9]\d*[lL]?' ++Intnumber = group(Binnumber, Hexnumber, Octnumber, Decnumber) ++Exponent = r'[eE][-+]?\d+' ++Pointfloat = group(r'\d+\.\d*', r'\.\d+') + maybe(Exponent) ++Expfloat = r'\d+' + Exponent ++Floatnumber = group(Pointfloat, Expfloat) ++Imagnumber = group(r'\d+[jJ]', Floatnumber + r'[jJ]') ++Number = group(Imagnumber, Floatnumber, Intnumber) ++ ++# Tail end of ' string. ++Single = r"[^'\\]*(?:\\.[^'\\]*)*'" ++# Tail end of " string. ++Double = r'[^"\\]*(?:\\.[^"\\]*)*"' ++# Tail end of ''' string. ++Single3 = r"[^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*'''" ++# Tail end of """ string. ++Double3 = r'[^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*"""' ++Triple = group("[ubUB]?[rR]?'''", '[ubUB]?[rR]?"""') ++# Single-line ' or " string. ++String = group(r"[uU]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*'", ++ r'[uU]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*"') ++ ++# Because of leftmost-then-longest match semantics, be sure to put the ++# longest operators first (e.g., if = came before ==, == would get ++# recognized as two instances of =). ++Operator = group(r"\*\*=?", r">>=?", r"<<=?", r"<>", r"!=", ++ r"//=?", r"->", ++ r"[+\-*/%&|^=<>]=?", ++ r"~") ++ ++Bracket = '[][(){}]' ++Special = group(r'\r?\n', r'[:;.,`@]') ++Funny = group(Operator, Bracket, Special) ++ ++PlainToken = group(Number, Funny, String, Name) ++Token = Ignore + PlainToken ++ ++# First (or only) line of ' or " string. ++ContStr = group(r"[uUbB]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*" + ++ group("'", r'\\\r?\n'), ++ r'[uUbB]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*' + ++ group('"', r'\\\r?\n')) ++PseudoExtras = group(r'\\\r?\n', Comment, Triple) ++PseudoToken = Whitespace + group(PseudoExtras, Number, Funny, ContStr, Name) ++ ++tokenprog, pseudoprog, single3prog, double3prog = map( ++ re.compile, (Token, PseudoToken, Single3, Double3)) ++endprogs = {"'": re.compile(Single), '"': re.compile(Double), ++ "'''": single3prog, '"""': double3prog, ++ "r'''": single3prog, 'r"""': double3prog, ++ "u'''": single3prog, 'u"""': double3prog, ++ "b'''": single3prog, 'b"""': double3prog, ++ "ur'''": single3prog, 'ur"""': double3prog, ++ "br'''": single3prog, 'br"""': double3prog, ++ "R'''": single3prog, 'R"""': double3prog, ++ "U'''": single3prog, 'U"""': double3prog, ++ "B'''": single3prog, 'B"""': double3prog, ++ "uR'''": single3prog, 'uR"""': double3prog, ++ "Ur'''": single3prog, 'Ur"""': double3prog, ++ "UR'''": single3prog, 'UR"""': double3prog, ++ "bR'''": single3prog, 'bR"""': double3prog, ++ "Br'''": single3prog, 'Br"""': double3prog, ++ "BR'''": single3prog, 'BR"""': double3prog, ++ 'r': None, 'R': None, ++ 'u': None, 'U': None, ++ 'b': None, 'B': None} ++ ++triple_quoted = {} ++for t in ("'''", '"""', ++ "r'''", 'r"""', "R'''", 'R"""', ++ "u'''", 'u"""', "U'''", 'U"""', ++ "b'''", 'b"""', "B'''", 'B"""', ++ "ur'''", 'ur"""', "Ur'''", 'Ur"""', ++ "uR'''", 'uR"""', "UR'''", 'UR"""', ++ "br'''", 'br"""', "Br'''", 'Br"""', ++ "bR'''", 'bR"""', "BR'''", 'BR"""',): ++ triple_quoted[t] = t ++single_quoted = {} ++for t in ("'", '"', ++ "r'", 'r"', "R'", 'R"', ++ "u'", 'u"', "U'", 'U"', ++ "b'", 'b"', "B'", 'B"', ++ "ur'", 'ur"', "Ur'", 'Ur"', ++ "uR'", 'uR"', "UR'", 'UR"', ++ "br'", 'br"', "Br'", 'Br"', ++ "bR'", 'bR"', "BR'", 'BR"', ): ++ single_quoted[t] = t ++ ++tabsize = 8 ++ ++class TokenError(Exception): pass ++ ++class StopTokenizing(Exception): pass ++ ++def printtoken(type, token, (srow, scol), (erow, ecol), line): # for testing ++ print "%d,%d-%d,%d:\t%s\t%s" % \ ++ (srow, scol, erow, ecol, tok_name[type], repr(token)) ++ ++def tokenize(readline, tokeneater=printtoken): ++ """ ++ The tokenize() function accepts two parameters: one representing the ++ input stream, and one providing an output mechanism for tokenize(). ++ ++ The first parameter, readline, must be a callable object which provides ++ the same interface as the readline() method of built-in file objects. ++ Each call to the function should return one line of input as a string. ++ ++ The second parameter, tokeneater, must also be a callable object. It is ++ called once for each token, with five arguments, corresponding to the ++ tuples generated by generate_tokens(). ++ """ ++ try: ++ tokenize_loop(readline, tokeneater) ++ except StopTokenizing: ++ pass ++ ++# backwards compatible interface ++def tokenize_loop(readline, tokeneater): ++ for token_info in generate_tokens(readline): ++ tokeneater(*token_info) ++ ++class Untokenizer: ++ ++ def __init__(self): ++ self.tokens = [] ++ self.prev_row = 1 ++ self.prev_col = 0 ++ ++ def add_whitespace(self, start): ++ row, col = start ++ assert row <= self.prev_row ++ col_offset = col - self.prev_col ++ if col_offset: ++ self.tokens.append(" " * col_offset) ++ ++ def untokenize(self, iterable): ++ for t in iterable: ++ if len(t) == 2: ++ self.compat(t, iterable) ++ break ++ tok_type, token, start, end, line = t ++ self.add_whitespace(start) ++ self.tokens.append(token) ++ self.prev_row, self.prev_col = end ++ if tok_type in (NEWLINE, NL): ++ self.prev_row += 1 ++ self.prev_col = 0 ++ return "".join(self.tokens) ++ ++ def compat(self, token, iterable): ++ startline = False ++ indents = [] ++ toks_append = self.tokens.append ++ toknum, tokval = token ++ if toknum in (NAME, NUMBER): ++ tokval += ' ' ++ if toknum in (NEWLINE, NL): ++ startline = True ++ for tok in iterable: ++ toknum, tokval = tok[:2] ++ ++ if toknum in (NAME, NUMBER): ++ tokval += ' ' ++ ++ if toknum == INDENT: ++ indents.append(tokval) ++ continue ++ elif toknum == DEDENT: ++ indents.pop() ++ continue ++ elif toknum in (NEWLINE, NL): ++ startline = True ++ elif startline and indents: ++ toks_append(indents[-1]) ++ startline = False ++ toks_append(tokval) ++ ++def untokenize(iterable): ++ """Transform tokens back into Python source code. ++ ++ Each element returned by the iterable must be a token sequence ++ with at least two elements, a token number and token value. If ++ only two tokens are passed, the resulting output is poor. ++ ++ Round-trip invariant for full input: ++ Untokenized source will match input source exactly ++ ++ Round-trip invariant for limited intput: ++ # Output text will tokenize the back to the input ++ t1 = [tok[:2] for tok in generate_tokens(f.readline)] ++ newcode = untokenize(t1) ++ readline = iter(newcode.splitlines(1)).next ++ t2 = [tok[:2] for tokin generate_tokens(readline)] ++ assert t1 == t2 ++ """ ++ ut = Untokenizer() ++ return ut.untokenize(iterable) ++ ++def generate_tokens(readline): ++ """ ++ The generate_tokens() generator requires one argment, readline, which ++ must be a callable object which provides the same interface as the ++ readline() method of built-in file objects. Each call to the function ++ should return one line of input as a string. Alternately, readline ++ can be a callable function terminating with StopIteration: ++ readline = open(myfile).next # Example of alternate readline ++ ++ The generator produces 5-tuples with these members: the token type; the ++ token string; a 2-tuple (srow, scol) of ints specifying the row and ++ column where the token begins in the source; a 2-tuple (erow, ecol) of ++ ints specifying the row and column where the token ends in the source; ++ and the line on which the token was found. The line passed is the ++ logical line; continuation lines are included. ++ """ ++ lnum = parenlev = continued = 0 ++ namechars, numchars = string.ascii_letters + '_', '0123456789' ++ contstr, needcont = '', 0 ++ contline = None ++ indents = [0] ++ ++ while 1: # loop over lines in stream ++ try: ++ line = readline() ++ except StopIteration: ++ line = '' ++ lnum = lnum + 1 ++ pos, max = 0, len(line) ++ ++ if contstr: # continued string ++ if not line: ++ raise TokenError, ("EOF in multi-line string", strstart) ++ endmatch = endprog.match(line) ++ if endmatch: ++ pos = end = endmatch.end(0) ++ yield (STRING, contstr + line[:end], ++ strstart, (lnum, end), contline + line) ++ contstr, needcont = '', 0 ++ contline = None ++ elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n': ++ yield (ERRORTOKEN, contstr + line, ++ strstart, (lnum, len(line)), contline) ++ contstr = '' ++ contline = None ++ continue ++ else: ++ contstr = contstr + line ++ contline = contline + line ++ continue ++ ++ elif parenlev == 0 and not continued: # new statement ++ if not line: break ++ column = 0 ++ while pos < max: # measure leading whitespace ++ if line[pos] == ' ': column = column + 1 ++ elif line[pos] == '\t': column = (column/tabsize + 1)*tabsize ++ elif line[pos] == '\f': column = 0 ++ else: break ++ pos = pos + 1 ++ if pos == max: break ++ ++ if line[pos] in '#\r\n': # skip comments or blank lines ++ if line[pos] == '#': ++ comment_token = line[pos:].rstrip('\r\n') ++ nl_pos = pos + len(comment_token) ++ yield (COMMENT, comment_token, ++ (lnum, pos), (lnum, pos + len(comment_token)), line) ++ yield (NL, line[nl_pos:], ++ (lnum, nl_pos), (lnum, len(line)), line) ++ else: ++ yield ((NL, COMMENT)[line[pos] == '#'], line[pos:], ++ (lnum, pos), (lnum, len(line)), line) ++ continue ++ ++ if column > indents[-1]: # count indents or dedents ++ indents.append(column) ++ yield (INDENT, line[:pos], (lnum, 0), (lnum, pos), line) ++ while column < indents[-1]: ++ if column not in indents: ++ raise IndentationError( ++ "unindent does not match any outer indentation level", ++ ("", lnum, pos, line)) ++ indents = indents[:-1] ++ yield (DEDENT, '', (lnum, pos), (lnum, pos), line) ++ ++ else: # continued statement ++ if not line: ++ raise TokenError, ("EOF in multi-line statement", (lnum, 0)) ++ continued = 0 ++ ++ while pos < max: ++ pseudomatch = pseudoprog.match(line, pos) ++ if pseudomatch: # scan for tokens ++ start, end = pseudomatch.span(1) ++ spos, epos, pos = (lnum, start), (lnum, end), end ++ token, initial = line[start:end], line[start] ++ ++ if initial in numchars or \ ++ (initial == '.' and token != '.'): # ordinary number ++ yield (NUMBER, token, spos, epos, line) ++ elif initial in '\r\n': ++ newline = NEWLINE ++ if parenlev > 0: ++ newline = NL ++ yield (newline, token, spos, epos, line) ++ elif initial == '#': ++ assert not token.endswith("\n") ++ yield (COMMENT, token, spos, epos, line) ++ elif token in triple_quoted: ++ endprog = endprogs[token] ++ endmatch = endprog.match(line, pos) ++ if endmatch: # all on one line ++ pos = endmatch.end(0) ++ token = line[start:pos] ++ yield (STRING, token, spos, (lnum, pos), line) ++ else: ++ strstart = (lnum, start) # multiple lines ++ contstr = line[start:] ++ contline = line ++ break ++ elif initial in single_quoted or \ ++ token[:2] in single_quoted or \ ++ token[:3] in single_quoted: ++ if token[-1] == '\n': # continued string ++ strstart = (lnum, start) ++ endprog = (endprogs[initial] or endprogs[token[1]] or ++ endprogs[token[2]]) ++ contstr, needcont = line[start:], 1 ++ contline = line ++ break ++ else: # ordinary string ++ yield (STRING, token, spos, epos, line) ++ elif initial in namechars: # ordinary name ++ yield (NAME, token, spos, epos, line) ++ elif initial == '\\': # continued stmt ++ # This yield is new; needed for better idempotency: ++ yield (NL, token, spos, (lnum, pos), line) ++ continued = 1 ++ else: ++ if initial in '([{': parenlev = parenlev + 1 ++ elif initial in ')]}': parenlev = parenlev - 1 ++ yield (OP, token, spos, epos, line) ++ else: ++ yield (ERRORTOKEN, line[pos], ++ (lnum, pos), (lnum, pos+1), line) ++ pos = pos + 1 ++ ++ for indent in indents[1:]: # pop remaining indent levels ++ yield (DEDENT, '', (lnum, 0), (lnum, 0), '') ++ yield (ENDMARKER, '', (lnum, 0), (lnum, 0), '') ++ ++if __name__ == '__main__': # testing ++ import sys ++ if len(sys.argv) > 1: tokenize(open(sys.argv[1]).readline) ++ else: tokenize(sys.stdin.readline) +diff -r 531f2e948299 refactor/pgen2/__init__.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/__init__.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,12 @@ ++# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""The pgen2 package.""" ++import conv ++import driver ++import grammar ++import literals ++import parse ++import pgen ++import tokenize ++import token +diff -r 531f2e948299 refactor/pgen2/conv.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/conv.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,257 @@ ++# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Convert graminit.[ch] spit out by pgen to Python code. ++ ++Pgen is the Python parser generator. It is useful to quickly create a ++parser from a grammar file in Python's grammar notation. But I don't ++want my parsers to be written in C (yet), so I'm translating the ++parsing tables to Python data structures and writing a Python parse ++engine. ++ ++Note that the token numbers are constants determined by the standard ++Python tokenizer. The standard token module defines these numbers and ++their names (the names are not used much). The token numbers are ++hardcoded into the Python tokenizer and into pgen. A Python ++implementation of the Python tokenizer is also available, in the ++standard tokenize module. ++ ++On the other hand, symbol numbers (representing the grammar's ++non-terminals) are assigned by pgen based on the actual grammar ++input. ++ ++Note: this module is pretty much obsolete; the pgen module generates ++equivalent grammar tables directly from the Grammar.txt input file ++without having to invoke the Python pgen C program. ++ ++""" ++ ++# Python imports ++import re ++ ++# Local imports ++from . import grammar, token ++ ++ ++class Converter(grammar.Grammar): ++ """Grammar subclass that reads classic pgen output files. ++ ++ The run() method reads the tables as produced by the pgen parser ++ generator, typically contained in two C files, graminit.h and ++ graminit.c. The other methods are for internal use only. ++ ++ See the base class for more documentation. ++ ++ """ ++ ++ def run(self, graminit_h, graminit_c): ++ """Load the grammar tables from the text files written by pgen.""" ++ self.parse_graminit_h(graminit_h) ++ self.parse_graminit_c(graminit_c) ++ self.finish_off() ++ ++ def parse_graminit_h(self, filename): ++ """Parse the .h file writen by pgen. (Internal) ++ ++ This file is a sequence of #define statements defining the ++ nonterminals of the grammar as numbers. We build two tables ++ mapping the numbers to names and back. ++ ++ """ ++ try: ++ f = open(filename) ++ except IOError, err: ++ print "Can't open %s: %s" % (filename, err) ++ return False ++ self.symbol2number = {} ++ self.number2symbol = {} ++ lineno = 0 ++ for line in f: ++ lineno += 1 ++ mo = re.match(r"^#define\s+(\w+)\s+(\d+)$", line) ++ if not mo and line.strip(): ++ print "%s(%s): can't parse %s" % (filename, lineno, ++ line.strip()) ++ else: ++ symbol, number = mo.groups() ++ number = int(number) ++ assert symbol not in self.symbol2number ++ assert number not in self.number2symbol ++ self.symbol2number[symbol] = number ++ self.number2symbol[number] = symbol ++ return True ++ ++ def parse_graminit_c(self, filename): ++ """Parse the .c file writen by pgen. (Internal) ++ ++ The file looks as follows. The first two lines are always this: ++ ++ #include "pgenheaders.h" ++ #include "grammar.h" ++ ++ After that come four blocks: ++ ++ 1) one or more state definitions ++ 2) a table defining dfas ++ 3) a table defining labels ++ 4) a struct defining the grammar ++ ++ A state definition has the following form: ++ - one or more arc arrays, each of the form: ++ static arc arcs__[] = { ++ {, }, ++ ... ++ }; ++ - followed by a state array, of the form: ++ static state states_[] = { ++ {, arcs__}, ++ ... ++ }; ++ ++ """ ++ try: ++ f = open(filename) ++ except IOError, err: ++ print "Can't open %s: %s" % (filename, err) ++ return False ++ # The code below essentially uses f's iterator-ness! ++ lineno = 0 ++ ++ # Expect the two #include lines ++ lineno, line = lineno+1, f.next() ++ assert line == '#include "pgenheaders.h"\n', (lineno, line) ++ lineno, line = lineno+1, f.next() ++ assert line == '#include "grammar.h"\n', (lineno, line) ++ ++ # Parse the state definitions ++ lineno, line = lineno+1, f.next() ++ allarcs = {} ++ states = [] ++ while line.startswith("static arc "): ++ while line.startswith("static arc "): ++ mo = re.match(r"static arc arcs_(\d+)_(\d+)\[(\d+)\] = {$", ++ line) ++ assert mo, (lineno, line) ++ n, m, k = map(int, mo.groups()) ++ arcs = [] ++ for _ in range(k): ++ lineno, line = lineno+1, f.next() ++ mo = re.match(r"\s+{(\d+), (\d+)},$", line) ++ assert mo, (lineno, line) ++ i, j = map(int, mo.groups()) ++ arcs.append((i, j)) ++ lineno, line = lineno+1, f.next() ++ assert line == "};\n", (lineno, line) ++ allarcs[(n, m)] = arcs ++ lineno, line = lineno+1, f.next() ++ mo = re.match(r"static state states_(\d+)\[(\d+)\] = {$", line) ++ assert mo, (lineno, line) ++ s, t = map(int, mo.groups()) ++ assert s == len(states), (lineno, line) ++ state = [] ++ for _ in range(t): ++ lineno, line = lineno+1, f.next() ++ mo = re.match(r"\s+{(\d+), arcs_(\d+)_(\d+)},$", line) ++ assert mo, (lineno, line) ++ k, n, m = map(int, mo.groups()) ++ arcs = allarcs[n, m] ++ assert k == len(arcs), (lineno, line) ++ state.append(arcs) ++ states.append(state) ++ lineno, line = lineno+1, f.next() ++ assert line == "};\n", (lineno, line) ++ lineno, line = lineno+1, f.next() ++ self.states = states ++ ++ # Parse the dfas ++ dfas = {} ++ mo = re.match(r"static dfa dfas\[(\d+)\] = {$", line) ++ assert mo, (lineno, line) ++ ndfas = int(mo.group(1)) ++ for i in range(ndfas): ++ lineno, line = lineno+1, f.next() ++ mo = re.match(r'\s+{(\d+), "(\w+)", (\d+), (\d+), states_(\d+),$', ++ line) ++ assert mo, (lineno, line) ++ symbol = mo.group(2) ++ number, x, y, z = map(int, mo.group(1, 3, 4, 5)) ++ assert self.symbol2number[symbol] == number, (lineno, line) ++ assert self.number2symbol[number] == symbol, (lineno, line) ++ assert x == 0, (lineno, line) ++ state = states[z] ++ assert y == len(state), (lineno, line) ++ lineno, line = lineno+1, f.next() ++ mo = re.match(r'\s+("(?:\\\d\d\d)*")},$', line) ++ assert mo, (lineno, line) ++ first = {} ++ rawbitset = eval(mo.group(1)) ++ for i, c in enumerate(rawbitset): ++ byte = ord(c) ++ for j in range(8): ++ if byte & (1<= os.path.getmtime(b) +diff -r 531f2e948299 refactor/pgen2/grammar.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/grammar.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,171 @@ ++# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""This module defines the data structures used to represent a grammar. ++ ++These are a bit arcane because they are derived from the data ++structures used by Python's 'pgen' parser generator. ++ ++There's also a table here mapping operators to their names in the ++token module; the Python tokenize module reports all operators as the ++fallback token code OP, but the parser needs the actual token code. ++ ++""" ++ ++# Python imports ++import pickle ++ ++# Local imports ++from . import token, tokenize ++ ++ ++class Grammar(object): ++ """Pgen parsing tables tables conversion class. ++ ++ Once initialized, this class supplies the grammar tables for the ++ parsing engine implemented by parse.py. The parsing engine ++ accesses the instance variables directly. The class here does not ++ provide initialization of the tables; several subclasses exist to ++ do this (see the conv and pgen modules). ++ ++ The load() method reads the tables from a pickle file, which is ++ much faster than the other ways offered by subclasses. The pickle ++ file is written by calling dump() (after loading the grammar ++ tables using a subclass). The report() method prints a readable ++ representation of the tables to stdout, for debugging. ++ ++ The instance variables are as follows: ++ ++ symbol2number -- a dict mapping symbol names to numbers. Symbol ++ numbers are always 256 or higher, to distinguish ++ them from token numbers, which are between 0 and ++ 255 (inclusive). ++ ++ number2symbol -- a dict mapping numbers to symbol names; ++ these two are each other's inverse. ++ ++ states -- a list of DFAs, where each DFA is a list of ++ states, each state is is a list of arcs, and each ++ arc is a (i, j) pair where i is a label and j is ++ a state number. The DFA number is the index into ++ this list. (This name is slightly confusing.) ++ Final states are represented by a special arc of ++ the form (0, j) where j is its own state number. ++ ++ dfas -- a dict mapping symbol numbers to (DFA, first) ++ pairs, where DFA is an item from the states list ++ above, and first is a set of tokens that can ++ begin this grammar rule (represented by a dict ++ whose values are always 1). ++ ++ labels -- a list of (x, y) pairs where x is either a token ++ number or a symbol number, and y is either None ++ or a string; the strings are keywords. The label ++ number is the index in this list; label numbers ++ are used to mark state transitions (arcs) in the ++ DFAs. ++ ++ start -- the number of the grammar's start symbol. ++ ++ keywords -- a dict mapping keyword strings to arc labels. ++ ++ tokens -- a dict mapping token numbers to arc labels. ++ ++ """ ++ ++ def __init__(self): ++ self.symbol2number = {} ++ self.number2symbol = {} ++ self.states = [] ++ self.dfas = {} ++ self.labels = [(0, "EMPTY")] ++ self.keywords = {} ++ self.tokens = {} ++ self.symbol2label = {} ++ self.start = 256 ++ ++ def dump(self, filename): ++ """Dump the grammar tables to a pickle file.""" ++ f = open(filename, "wb") ++ pickle.dump(self.__dict__, f, 2) ++ f.close() ++ ++ def load(self, filename): ++ """Load the grammar tables from a pickle file.""" ++ f = open(filename, "rb") ++ d = pickle.load(f) ++ f.close() ++ self.__dict__.update(d) ++ ++ def report(self): ++ """Dump the grammar tables to standard output, for debugging.""" ++ from pprint import pprint ++ print "s2n" ++ pprint(self.symbol2number) ++ print "n2s" ++ pprint(self.number2symbol) ++ print "states" ++ pprint(self.states) ++ print "dfas" ++ pprint(self.dfas) ++ print "labels" ++ pprint(self.labels) ++ print "start", self.start ++ ++ ++# Map from operator to number (since tokenize doesn't do this) ++ ++opmap_raw = """ ++( LPAR ++) RPAR ++[ LSQB ++] RSQB ++: COLON ++, COMMA ++; SEMI +++ PLUS ++- MINUS ++* STAR ++/ SLASH ++| VBAR ++& AMPER ++< LESS ++> GREATER ++= EQUAL ++. DOT ++% PERCENT ++` BACKQUOTE ++{ LBRACE ++} RBRACE ++@ AT ++== EQEQUAL ++!= NOTEQUAL ++<> NOTEQUAL ++<= LESSEQUAL ++>= GREATEREQUAL ++~ TILDE ++^ CIRCUMFLEX ++<< LEFTSHIFT ++>> RIGHTSHIFT ++** DOUBLESTAR +++= PLUSEQUAL ++-= MINEQUAL ++*= STAREQUAL ++/= SLASHEQUAL ++%= PERCENTEQUAL ++&= AMPEREQUAL ++|= VBAREQUAL ++^= CIRCUMFLEXEQUAL ++<<= LEFTSHIFTEQUAL ++>>= RIGHTSHIFTEQUAL ++**= DOUBLESTAREQUAL ++// DOUBLESLASH ++//= DOUBLESLASHEQUAL ++-> RARROW ++""" ++ ++opmap = {} ++for line in opmap_raw.splitlines(): ++ if line: ++ op, name = line.split() ++ opmap[op] = getattr(token, name) +diff -r 531f2e948299 refactor/pgen2/literals.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/literals.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,60 @@ ++# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Safely evaluate Python string literals without using eval().""" ++ ++import re ++ ++simple_escapes = {"a": "\a", ++ "b": "\b", ++ "f": "\f", ++ "n": "\n", ++ "r": "\r", ++ "t": "\t", ++ "v": "\v", ++ "'": "'", ++ '"': '"', ++ "\\": "\\"} ++ ++def escape(m): ++ all, tail = m.group(0, 1) ++ assert all.startswith("\\") ++ esc = simple_escapes.get(tail) ++ if esc is not None: ++ return esc ++ if tail.startswith("x"): ++ hexes = tail[1:] ++ if len(hexes) < 2: ++ raise ValueError("invalid hex string escape ('\\%s')" % tail) ++ try: ++ i = int(hexes, 16) ++ except ValueError: ++ raise ValueError("invalid hex string escape ('\\%s')" % tail) ++ else: ++ try: ++ i = int(tail, 8) ++ except ValueError: ++ raise ValueError("invalid octal string escape ('\\%s')" % tail) ++ return chr(i) ++ ++def evalString(s): ++ assert s.startswith("'") or s.startswith('"'), repr(s[:1]) ++ q = s[0] ++ if s[:3] == q*3: ++ q = q*3 ++ assert s.endswith(q), repr(s[-len(q):]) ++ assert len(s) >= 2*len(q) ++ s = s[len(q):-len(q)] ++ return re.sub(r"\\(\'|\"|\\|[abfnrtv]|x.{0,2}|[0-7]{1,3})", escape, s) ++ ++def test(): ++ for i in range(256): ++ c = chr(i) ++ s = repr(c) ++ e = evalString(s) ++ if e != c: ++ print i, c, s, e ++ ++ ++if __name__ == "__main__": ++ test() +diff -r 531f2e948299 refactor/pgen2/parse.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/parse.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,201 @@ ++# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Parser engine for the grammar tables generated by pgen. ++ ++The grammar table must be loaded first. ++ ++See Parser/parser.c in the Python distribution for additional info on ++how this parsing engine works. ++ ++""" ++ ++# Local imports ++from . import token ++ ++class ParseError(Exception): ++ """Exception to signal the parser is stuck.""" ++ ++ def __init__(self, msg, type, value, context): ++ Exception.__init__(self, "%s: type=%r, value=%r, context=%r" % ++ (msg, type, value, context)) ++ self.msg = msg ++ self.type = type ++ self.value = value ++ self.context = context ++ ++class Parser(object): ++ """Parser engine. ++ ++ The proper usage sequence is: ++ ++ p = Parser(grammar, [converter]) # create instance ++ p.setup([start]) # prepare for parsing ++ : ++ if p.addtoken(...): # parse a token; may raise ParseError ++ break ++ root = p.rootnode # root of abstract syntax tree ++ ++ A Parser instance may be reused by calling setup() repeatedly. ++ ++ A Parser instance contains state pertaining to the current token ++ sequence, and should not be used concurrently by different threads ++ to parse separate token sequences. ++ ++ See driver.py for how to get input tokens by tokenizing a file or ++ string. ++ ++ Parsing is complete when addtoken() returns True; the root of the ++ abstract syntax tree can then be retrieved from the rootnode ++ instance variable. When a syntax error occurs, addtoken() raises ++ the ParseError exception. There is no error recovery; the parser ++ cannot be used after a syntax error was reported (but it can be ++ reinitialized by calling setup()). ++ ++ """ ++ ++ def __init__(self, grammar, convert=None): ++ """Constructor. ++ ++ The grammar argument is a grammar.Grammar instance; see the ++ grammar module for more information. ++ ++ The parser is not ready yet for parsing; you must call the ++ setup() method to get it started. ++ ++ The optional convert argument is a function mapping concrete ++ syntax tree nodes to abstract syntax tree nodes. If not ++ given, no conversion is done and the syntax tree produced is ++ the concrete syntax tree. If given, it must be a function of ++ two arguments, the first being the grammar (a grammar.Grammar ++ instance), and the second being the concrete syntax tree node ++ to be converted. The syntax tree is converted from the bottom ++ up. ++ ++ A concrete syntax tree node is a (type, value, context, nodes) ++ tuple, where type is the node type (a token or symbol number), ++ value is None for symbols and a string for tokens, context is ++ None or an opaque value used for error reporting (typically a ++ (lineno, offset) pair), and nodes is a list of children for ++ symbols, and None for tokens. ++ ++ An abstract syntax tree node may be anything; this is entirely ++ up to the converter function. ++ ++ """ ++ self.grammar = grammar ++ self.convert = convert or (lambda grammar, node: node) ++ ++ def setup(self, start=None): ++ """Prepare for parsing. ++ ++ This *must* be called before starting to parse. ++ ++ The optional argument is an alternative start symbol; it ++ defaults to the grammar's start symbol. ++ ++ You can use a Parser instance to parse any number of programs; ++ each time you call setup() the parser is reset to an initial ++ state determined by the (implicit or explicit) start symbol. ++ ++ """ ++ if start is None: ++ start = self.grammar.start ++ # Each stack entry is a tuple: (dfa, state, node). ++ # A node is a tuple: (type, value, context, children), ++ # where children is a list of nodes or None, and context may be None. ++ newnode = (start, None, None, []) ++ stackentry = (self.grammar.dfas[start], 0, newnode) ++ self.stack = [stackentry] ++ self.rootnode = None ++ self.used_names = set() # Aliased to self.rootnode.used_names in pop() ++ ++ def addtoken(self, type, value, context): ++ """Add a token; return True iff this is the end of the program.""" ++ # Map from token to label ++ ilabel = self.classify(type, value, context) ++ # Loop until the token is shifted; may raise exceptions ++ while True: ++ dfa, state, node = self.stack[-1] ++ states, first = dfa ++ arcs = states[state] ++ # Look for a state with this label ++ for i, newstate in arcs: ++ t, v = self.grammar.labels[i] ++ if ilabel == i: ++ # Look it up in the list of labels ++ assert t < 256 ++ # Shift a token; we're done with it ++ self.shift(type, value, newstate, context) ++ # Pop while we are in an accept-only state ++ state = newstate ++ while states[state] == [(0, state)]: ++ self.pop() ++ if not self.stack: ++ # Done parsing! ++ return True ++ dfa, state, node = self.stack[-1] ++ states, first = dfa ++ # Done with this token ++ return False ++ elif t >= 256: ++ # See if it's a symbol and if we're in its first set ++ itsdfa = self.grammar.dfas[t] ++ itsstates, itsfirst = itsdfa ++ if ilabel in itsfirst: ++ # Push a symbol ++ self.push(t, self.grammar.dfas[t], newstate, context) ++ break # To continue the outer while loop ++ else: ++ if (0, state) in arcs: ++ # An accepting state, pop it and try something else ++ self.pop() ++ if not self.stack: ++ # Done parsing, but another token is input ++ raise ParseError("too much input", ++ type, value, context) ++ else: ++ # No success finding a transition ++ raise ParseError("bad input", type, value, context) ++ ++ def classify(self, type, value, context): ++ """Turn a token into a label. (Internal)""" ++ if type == token.NAME: ++ # Keep a listing of all used names ++ self.used_names.add(value) ++ # Check for reserved words ++ ilabel = self.grammar.keywords.get(value) ++ if ilabel is not None: ++ return ilabel ++ ilabel = self.grammar.tokens.get(type) ++ if ilabel is None: ++ raise ParseError("bad token", type, value, context) ++ return ilabel ++ ++ def shift(self, type, value, newstate, context): ++ """Shift a token. (Internal)""" ++ dfa, state, node = self.stack[-1] ++ newnode = (type, value, context, None) ++ newnode = self.convert(self.grammar, newnode) ++ if newnode is not None: ++ node[-1].append(newnode) ++ self.stack[-1] = (dfa, newstate, node) ++ ++ def push(self, type, newdfa, newstate, context): ++ """Push a nonterminal. (Internal)""" ++ dfa, state, node = self.stack[-1] ++ newnode = (type, None, context, []) ++ self.stack[-1] = (dfa, newstate, node) ++ self.stack.append((newdfa, 0, newnode)) ++ ++ def pop(self): ++ """Pop a nonterminal. (Internal)""" ++ popdfa, popstate, popnode = self.stack.pop() ++ newnode = self.convert(self.grammar, popnode) ++ if newnode is not None: ++ if self.stack: ++ dfa, state, node = self.stack[-1] ++ node[-1].append(newnode) ++ else: ++ self.rootnode = newnode ++ self.rootnode.used_names = self.used_names +diff -r 531f2e948299 refactor/pgen2/pgen.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/pgen.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,384 @@ ++# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++# Pgen imports ++from . import grammar, token, tokenize ++ ++class PgenGrammar(grammar.Grammar): ++ pass ++ ++class ParserGenerator(object): ++ ++ def __init__(self, filename, stream=None): ++ close_stream = None ++ if stream is None: ++ stream = open(filename) ++ close_stream = stream.close ++ self.filename = filename ++ self.stream = stream ++ self.generator = tokenize.generate_tokens(stream.readline) ++ self.gettoken() # Initialize lookahead ++ self.dfas, self.startsymbol = self.parse() ++ if close_stream is not None: ++ close_stream() ++ self.first = {} # map from symbol name to set of tokens ++ self.addfirstsets() ++ ++ def make_grammar(self): ++ c = PgenGrammar() ++ names = self.dfas.keys() ++ names.sort() ++ names.remove(self.startsymbol) ++ names.insert(0, self.startsymbol) ++ for name in names: ++ i = 256 + len(c.symbol2number) ++ c.symbol2number[name] = i ++ c.number2symbol[i] = name ++ for name in names: ++ dfa = self.dfas[name] ++ states = [] ++ for state in dfa: ++ arcs = [] ++ for label, next in state.arcs.iteritems(): ++ arcs.append((self.make_label(c, label), dfa.index(next))) ++ if state.isfinal: ++ arcs.append((0, dfa.index(state))) ++ states.append(arcs) ++ c.states.append(states) ++ c.dfas[c.symbol2number[name]] = (states, self.make_first(c, name)) ++ c.start = c.symbol2number[self.startsymbol] ++ return c ++ ++ def make_first(self, c, name): ++ rawfirst = self.first[name] ++ first = {} ++ for label in rawfirst: ++ ilabel = self.make_label(c, label) ++ ##assert ilabel not in first # XXX failed on <> ... != ++ first[ilabel] = 1 ++ return first ++ ++ def make_label(self, c, label): ++ # XXX Maybe this should be a method on a subclass of converter? ++ ilabel = len(c.labels) ++ if label[0].isalpha(): ++ # Either a symbol name or a named token ++ if label in c.symbol2number: ++ # A symbol name (a non-terminal) ++ if label in c.symbol2label: ++ return c.symbol2label[label] ++ else: ++ c.labels.append((c.symbol2number[label], None)) ++ c.symbol2label[label] = ilabel ++ return ilabel ++ else: ++ # A named token (NAME, NUMBER, STRING) ++ itoken = getattr(token, label, None) ++ assert isinstance(itoken, int), label ++ assert itoken in token.tok_name, label ++ if itoken in c.tokens: ++ return c.tokens[itoken] ++ else: ++ c.labels.append((itoken, None)) ++ c.tokens[itoken] = ilabel ++ return ilabel ++ else: ++ # Either a keyword or an operator ++ assert label[0] in ('"', "'"), label ++ value = eval(label) ++ if value[0].isalpha(): ++ # A keyword ++ if value in c.keywords: ++ return c.keywords[value] ++ else: ++ c.labels.append((token.NAME, value)) ++ c.keywords[value] = ilabel ++ return ilabel ++ else: ++ # An operator (any non-numeric token) ++ itoken = grammar.opmap[value] # Fails if unknown token ++ if itoken in c.tokens: ++ return c.tokens[itoken] ++ else: ++ c.labels.append((itoken, None)) ++ c.tokens[itoken] = ilabel ++ return ilabel ++ ++ def addfirstsets(self): ++ names = self.dfas.keys() ++ names.sort() ++ for name in names: ++ if name not in self.first: ++ self.calcfirst(name) ++ #print name, self.first[name].keys() ++ ++ def calcfirst(self, name): ++ dfa = self.dfas[name] ++ self.first[name] = None # dummy to detect left recursion ++ state = dfa[0] ++ totalset = {} ++ overlapcheck = {} ++ for label, next in state.arcs.iteritems(): ++ if label in self.dfas: ++ if label in self.first: ++ fset = self.first[label] ++ if fset is None: ++ raise ValueError("recursion for rule %r" % name) ++ else: ++ self.calcfirst(label) ++ fset = self.first[label] ++ totalset.update(fset) ++ overlapcheck[label] = fset ++ else: ++ totalset[label] = 1 ++ overlapcheck[label] = {label: 1} ++ inverse = {} ++ for label, itsfirst in overlapcheck.iteritems(): ++ for symbol in itsfirst: ++ if symbol in inverse: ++ raise ValueError("rule %s is ambiguous; %s is in the" ++ " first sets of %s as well as %s" % ++ (name, symbol, label, inverse[symbol])) ++ inverse[symbol] = label ++ self.first[name] = totalset ++ ++ def parse(self): ++ dfas = {} ++ startsymbol = None ++ # MSTART: (NEWLINE | RULE)* ENDMARKER ++ while self.type != token.ENDMARKER: ++ while self.type == token.NEWLINE: ++ self.gettoken() ++ # RULE: NAME ':' RHS NEWLINE ++ name = self.expect(token.NAME) ++ self.expect(token.OP, ":") ++ a, z = self.parse_rhs() ++ self.expect(token.NEWLINE) ++ #self.dump_nfa(name, a, z) ++ dfa = self.make_dfa(a, z) ++ #self.dump_dfa(name, dfa) ++ oldlen = len(dfa) ++ self.simplify_dfa(dfa) ++ newlen = len(dfa) ++ dfas[name] = dfa ++ #print name, oldlen, newlen ++ if startsymbol is None: ++ startsymbol = name ++ return dfas, startsymbol ++ ++ def make_dfa(self, start, finish): ++ # To turn an NFA into a DFA, we define the states of the DFA ++ # to correspond to *sets* of states of the NFA. Then do some ++ # state reduction. Let's represent sets as dicts with 1 for ++ # values. ++ assert isinstance(start, NFAState) ++ assert isinstance(finish, NFAState) ++ def closure(state): ++ base = {} ++ addclosure(state, base) ++ return base ++ def addclosure(state, base): ++ assert isinstance(state, NFAState) ++ if state in base: ++ return ++ base[state] = 1 ++ for label, next in state.arcs: ++ if label is None: ++ addclosure(next, base) ++ states = [DFAState(closure(start), finish)] ++ for state in states: # NB states grows while we're iterating ++ arcs = {} ++ for nfastate in state.nfaset: ++ for label, next in nfastate.arcs: ++ if label is not None: ++ addclosure(next, arcs.setdefault(label, {})) ++ for label, nfaset in arcs.iteritems(): ++ for st in states: ++ if st.nfaset == nfaset: ++ break ++ else: ++ st = DFAState(nfaset, finish) ++ states.append(st) ++ state.addarc(st, label) ++ return states # List of DFAState instances; first one is start ++ ++ def dump_nfa(self, name, start, finish): ++ print "Dump of NFA for", name ++ todo = [start] ++ for i, state in enumerate(todo): ++ print " State", i, state is finish and "(final)" or "" ++ for label, next in state.arcs: ++ if next in todo: ++ j = todo.index(next) ++ else: ++ j = len(todo) ++ todo.append(next) ++ if label is None: ++ print " -> %d" % j ++ else: ++ print " %s -> %d" % (label, j) ++ ++ def dump_dfa(self, name, dfa): ++ print "Dump of DFA for", name ++ for i, state in enumerate(dfa): ++ print " State", i, state.isfinal and "(final)" or "" ++ for label, next in state.arcs.iteritems(): ++ print " %s -> %d" % (label, dfa.index(next)) ++ ++ def simplify_dfa(self, dfa): ++ # This is not theoretically optimal, but works well enough. ++ # Algorithm: repeatedly look for two states that have the same ++ # set of arcs (same labels pointing to the same nodes) and ++ # unify them, until things stop changing. ++ ++ # dfa is a list of DFAState instances ++ changes = True ++ while changes: ++ changes = False ++ for i, state_i in enumerate(dfa): ++ for j in range(i+1, len(dfa)): ++ state_j = dfa[j] ++ if state_i == state_j: ++ #print " unify", i, j ++ del dfa[j] ++ for state in dfa: ++ state.unifystate(state_j, state_i) ++ changes = True ++ break ++ ++ def parse_rhs(self): ++ # RHS: ALT ('|' ALT)* ++ a, z = self.parse_alt() ++ if self.value != "|": ++ return a, z ++ else: ++ aa = NFAState() ++ zz = NFAState() ++ aa.addarc(a) ++ z.addarc(zz) ++ while self.value == "|": ++ self.gettoken() ++ a, z = self.parse_alt() ++ aa.addarc(a) ++ z.addarc(zz) ++ return aa, zz ++ ++ def parse_alt(self): ++ # ALT: ITEM+ ++ a, b = self.parse_item() ++ while (self.value in ("(", "[") or ++ self.type in (token.NAME, token.STRING)): ++ c, d = self.parse_item() ++ b.addarc(c) ++ b = d ++ return a, b ++ ++ def parse_item(self): ++ # ITEM: '[' RHS ']' | ATOM ['+' | '*'] ++ if self.value == "[": ++ self.gettoken() ++ a, z = self.parse_rhs() ++ self.expect(token.OP, "]") ++ a.addarc(z) ++ return a, z ++ else: ++ a, z = self.parse_atom() ++ value = self.value ++ if value not in ("+", "*"): ++ return a, z ++ self.gettoken() ++ z.addarc(a) ++ if value == "+": ++ return a, z ++ else: ++ return a, a ++ ++ def parse_atom(self): ++ # ATOM: '(' RHS ')' | NAME | STRING ++ if self.value == "(": ++ self.gettoken() ++ a, z = self.parse_rhs() ++ self.expect(token.OP, ")") ++ return a, z ++ elif self.type in (token.NAME, token.STRING): ++ a = NFAState() ++ z = NFAState() ++ a.addarc(z, self.value) ++ self.gettoken() ++ return a, z ++ else: ++ self.raise_error("expected (...) or NAME or STRING, got %s/%s", ++ self.type, self.value) ++ ++ def expect(self, type, value=None): ++ if self.type != type or (value is not None and self.value != value): ++ self.raise_error("expected %s/%s, got %s/%s", ++ type, value, self.type, self.value) ++ value = self.value ++ self.gettoken() ++ return value ++ ++ def gettoken(self): ++ tup = self.generator.next() ++ while tup[0] in (tokenize.COMMENT, tokenize.NL): ++ tup = self.generator.next() ++ self.type, self.value, self.begin, self.end, self.line = tup ++ #print token.tok_name[self.type], repr(self.value) ++ ++ def raise_error(self, msg, *args): ++ if args: ++ try: ++ msg = msg % args ++ except: ++ msg = " ".join([msg] + map(str, args)) ++ raise SyntaxError(msg, (self.filename, self.end[0], ++ self.end[1], self.line)) ++ ++class NFAState(object): ++ ++ def __init__(self): ++ self.arcs = [] # list of (label, NFAState) pairs ++ ++ def addarc(self, next, label=None): ++ assert label is None or isinstance(label, str) ++ assert isinstance(next, NFAState) ++ self.arcs.append((label, next)) ++ ++class DFAState(object): ++ ++ def __init__(self, nfaset, final): ++ assert isinstance(nfaset, dict) ++ assert isinstance(iter(nfaset).next(), NFAState) ++ assert isinstance(final, NFAState) ++ self.nfaset = nfaset ++ self.isfinal = final in nfaset ++ self.arcs = {} # map from label to DFAState ++ ++ def addarc(self, next, label): ++ assert isinstance(label, str) ++ assert label not in self.arcs ++ assert isinstance(next, DFAState) ++ self.arcs[label] = next ++ ++ def unifystate(self, old, new): ++ for label, next in self.arcs.iteritems(): ++ if next is old: ++ self.arcs[label] = new ++ ++ def __eq__(self, other): ++ # Equality test -- ignore the nfaset instance variable ++ assert isinstance(other, DFAState) ++ if self.isfinal != other.isfinal: ++ return False ++ # Can't just return self.arcs == other.arcs, because that ++ # would invoke this method recursively, with cycles... ++ if len(self.arcs) != len(other.arcs): ++ return False ++ for label, next in self.arcs.iteritems(): ++ if next is not other.arcs.get(label): ++ return False ++ return True ++ ++def generate_grammar(filename="Grammar.txt"): ++ p = ParserGenerator(filename) ++ return p.make_grammar() +diff -r 531f2e948299 refactor/pgen2/token.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/token.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,82 @@ ++#! /usr/bin/env python ++ ++"""Token constants (from "token.h").""" ++ ++# Taken from Python (r53757) and modified to include some tokens ++# originally monkeypatched in by pgen2.tokenize ++ ++#--start constants-- ++ENDMARKER = 0 ++NAME = 1 ++NUMBER = 2 ++STRING = 3 ++NEWLINE = 4 ++INDENT = 5 ++DEDENT = 6 ++LPAR = 7 ++RPAR = 8 ++LSQB = 9 ++RSQB = 10 ++COLON = 11 ++COMMA = 12 ++SEMI = 13 ++PLUS = 14 ++MINUS = 15 ++STAR = 16 ++SLASH = 17 ++VBAR = 18 ++AMPER = 19 ++LESS = 20 ++GREATER = 21 ++EQUAL = 22 ++DOT = 23 ++PERCENT = 24 ++BACKQUOTE = 25 ++LBRACE = 26 ++RBRACE = 27 ++EQEQUAL = 28 ++NOTEQUAL = 29 ++LESSEQUAL = 30 ++GREATEREQUAL = 31 ++TILDE = 32 ++CIRCUMFLEX = 33 ++LEFTSHIFT = 34 ++RIGHTSHIFT = 35 ++DOUBLESTAR = 36 ++PLUSEQUAL = 37 ++MINEQUAL = 38 ++STAREQUAL = 39 ++SLASHEQUAL = 40 ++PERCENTEQUAL = 41 ++AMPEREQUAL = 42 ++VBAREQUAL = 43 ++CIRCUMFLEXEQUAL = 44 ++LEFTSHIFTEQUAL = 45 ++RIGHTSHIFTEQUAL = 46 ++DOUBLESTAREQUAL = 47 ++DOUBLESLASH = 48 ++DOUBLESLASHEQUAL = 49 ++AT = 50 ++OP = 51 ++COMMENT = 52 ++NL = 53 ++RARROW = 54 ++ERRORTOKEN = 55 ++N_TOKENS = 56 ++NT_OFFSET = 256 ++#--end constants-- ++ ++tok_name = {} ++for _name, _value in globals().items(): ++ if type(_value) is type(0): ++ tok_name[_value] = _name ++ ++ ++def ISTERMINAL(x): ++ return x < NT_OFFSET ++ ++def ISNONTERMINAL(x): ++ return x >= NT_OFFSET ++ ++def ISEOF(x): ++ return x == ENDMARKER +diff -r 531f2e948299 refactor/pgen2/tokenize.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pgen2/tokenize.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,405 @@ ++# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation. ++# All rights reserved. ++ ++"""Tokenization help for Python programs. ++ ++generate_tokens(readline) is a generator that breaks a stream of ++text into Python tokens. It accepts a readline-like method which is called ++repeatedly to get the next line of input (or "" for EOF). It generates ++5-tuples with these members: ++ ++ the token type (see token.py) ++ the token (a string) ++ the starting (row, column) indices of the token (a 2-tuple of ints) ++ the ending (row, column) indices of the token (a 2-tuple of ints) ++ the original line (string) ++ ++It is designed to match the working of the Python tokenizer exactly, except ++that it produces COMMENT tokens for comments and gives type OP for all ++operators ++ ++Older entry points ++ tokenize_loop(readline, tokeneater) ++ tokenize(readline, tokeneater=printtoken) ++are the same, except instead of generating tokens, tokeneater is a callback ++function to which the 5 fields described above are passed as 5 arguments, ++each time a new token is found.""" ++ ++__author__ = 'Ka-Ping Yee ' ++__credits__ = \ ++ 'GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, Skip Montanaro' ++ ++import string, re ++from .token import * ++ ++from . import token ++__all__ = [x for x in dir(token) if x[0] != '_'] + ["tokenize", ++ "generate_tokens", "untokenize"] ++del token ++ ++def group(*choices): return '(' + '|'.join(choices) + ')' ++def any(*choices): return group(*choices) + '*' ++def maybe(*choices): return group(*choices) + '?' ++ ++Whitespace = r'[ \f\t]*' ++Comment = r'#[^\r\n]*' ++Ignore = Whitespace + any(r'\\\r?\n' + Whitespace) + maybe(Comment) ++Name = r'[a-zA-Z_]\w*' ++ ++Binnumber = r'0[bB][01]*' ++Hexnumber = r'0[xX][\da-fA-F]*[lL]?' ++Octnumber = r'0[oO]?[0-7]*[lL]?' ++Decnumber = r'[1-9]\d*[lL]?' ++Intnumber = group(Binnumber, Hexnumber, Octnumber, Decnumber) ++Exponent = r'[eE][-+]?\d+' ++Pointfloat = group(r'\d+\.\d*', r'\.\d+') + maybe(Exponent) ++Expfloat = r'\d+' + Exponent ++Floatnumber = group(Pointfloat, Expfloat) ++Imagnumber = group(r'\d+[jJ]', Floatnumber + r'[jJ]') ++Number = group(Imagnumber, Floatnumber, Intnumber) ++ ++# Tail end of ' string. ++Single = r"[^'\\]*(?:\\.[^'\\]*)*'" ++# Tail end of " string. ++Double = r'[^"\\]*(?:\\.[^"\\]*)*"' ++# Tail end of ''' string. ++Single3 = r"[^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*'''" ++# Tail end of """ string. ++Double3 = r'[^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*"""' ++Triple = group("[ubUB]?[rR]?'''", '[ubUB]?[rR]?"""') ++# Single-line ' or " string. ++String = group(r"[uU]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*'", ++ r'[uU]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*"') ++ ++# Because of leftmost-then-longest match semantics, be sure to put the ++# longest operators first (e.g., if = came before ==, == would get ++# recognized as two instances of =). ++Operator = group(r"\*\*=?", r">>=?", r"<<=?", r"<>", r"!=", ++ r"//=?", r"->", ++ r"[+\-*/%&|^=<>]=?", ++ r"~") ++ ++Bracket = '[][(){}]' ++Special = group(r'\r?\n', r'[:;.,`@]') ++Funny = group(Operator, Bracket, Special) ++ ++PlainToken = group(Number, Funny, String, Name) ++Token = Ignore + PlainToken ++ ++# First (or only) line of ' or " string. ++ContStr = group(r"[uUbB]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*" + ++ group("'", r'\\\r?\n'), ++ r'[uUbB]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*' + ++ group('"', r'\\\r?\n')) ++PseudoExtras = group(r'\\\r?\n', Comment, Triple) ++PseudoToken = Whitespace + group(PseudoExtras, Number, Funny, ContStr, Name) ++ ++tokenprog, pseudoprog, single3prog, double3prog = map( ++ re.compile, (Token, PseudoToken, Single3, Double3)) ++endprogs = {"'": re.compile(Single), '"': re.compile(Double), ++ "'''": single3prog, '"""': double3prog, ++ "r'''": single3prog, 'r"""': double3prog, ++ "u'''": single3prog, 'u"""': double3prog, ++ "b'''": single3prog, 'b"""': double3prog, ++ "ur'''": single3prog, 'ur"""': double3prog, ++ "br'''": single3prog, 'br"""': double3prog, ++ "R'''": single3prog, 'R"""': double3prog, ++ "U'''": single3prog, 'U"""': double3prog, ++ "B'''": single3prog, 'B"""': double3prog, ++ "uR'''": single3prog, 'uR"""': double3prog, ++ "Ur'''": single3prog, 'Ur"""': double3prog, ++ "UR'''": single3prog, 'UR"""': double3prog, ++ "bR'''": single3prog, 'bR"""': double3prog, ++ "Br'''": single3prog, 'Br"""': double3prog, ++ "BR'''": single3prog, 'BR"""': double3prog, ++ 'r': None, 'R': None, ++ 'u': None, 'U': None, ++ 'b': None, 'B': None} ++ ++triple_quoted = {} ++for t in ("'''", '"""', ++ "r'''", 'r"""', "R'''", 'R"""', ++ "u'''", 'u"""', "U'''", 'U"""', ++ "b'''", 'b"""', "B'''", 'B"""', ++ "ur'''", 'ur"""', "Ur'''", 'Ur"""', ++ "uR'''", 'uR"""', "UR'''", 'UR"""', ++ "br'''", 'br"""', "Br'''", 'Br"""', ++ "bR'''", 'bR"""', "BR'''", 'BR"""',): ++ triple_quoted[t] = t ++single_quoted = {} ++for t in ("'", '"', ++ "r'", 'r"', "R'", 'R"', ++ "u'", 'u"', "U'", 'U"', ++ "b'", 'b"', "B'", 'B"', ++ "ur'", 'ur"', "Ur'", 'Ur"', ++ "uR'", 'uR"', "UR'", 'UR"', ++ "br'", 'br"', "Br'", 'Br"', ++ "bR'", 'bR"', "BR'", 'BR"', ): ++ single_quoted[t] = t ++ ++tabsize = 8 ++ ++class TokenError(Exception): pass ++ ++class StopTokenizing(Exception): pass ++ ++def printtoken(type, token, (srow, scol), (erow, ecol), line): # for testing ++ print "%d,%d-%d,%d:\t%s\t%s" % \ ++ (srow, scol, erow, ecol, tok_name[type], repr(token)) ++ ++def tokenize(readline, tokeneater=printtoken): ++ """ ++ The tokenize() function accepts two parameters: one representing the ++ input stream, and one providing an output mechanism for tokenize(). ++ ++ The first parameter, readline, must be a callable object which provides ++ the same interface as the readline() method of built-in file objects. ++ Each call to the function should return one line of input as a string. ++ ++ The second parameter, tokeneater, must also be a callable object. It is ++ called once for each token, with five arguments, corresponding to the ++ tuples generated by generate_tokens(). ++ """ ++ try: ++ tokenize_loop(readline, tokeneater) ++ except StopTokenizing: ++ pass ++ ++# backwards compatible interface ++def tokenize_loop(readline, tokeneater): ++ for token_info in generate_tokens(readline): ++ tokeneater(*token_info) ++ ++class Untokenizer: ++ ++ def __init__(self): ++ self.tokens = [] ++ self.prev_row = 1 ++ self.prev_col = 0 ++ ++ def add_whitespace(self, start): ++ row, col = start ++ assert row <= self.prev_row ++ col_offset = col - self.prev_col ++ if col_offset: ++ self.tokens.append(" " * col_offset) ++ ++ def untokenize(self, iterable): ++ for t in iterable: ++ if len(t) == 2: ++ self.compat(t, iterable) ++ break ++ tok_type, token, start, end, line = t ++ self.add_whitespace(start) ++ self.tokens.append(token) ++ self.prev_row, self.prev_col = end ++ if tok_type in (NEWLINE, NL): ++ self.prev_row += 1 ++ self.prev_col = 0 ++ return "".join(self.tokens) ++ ++ def compat(self, token, iterable): ++ startline = False ++ indents = [] ++ toks_append = self.tokens.append ++ toknum, tokval = token ++ if toknum in (NAME, NUMBER): ++ tokval += ' ' ++ if toknum in (NEWLINE, NL): ++ startline = True ++ for tok in iterable: ++ toknum, tokval = tok[:2] ++ ++ if toknum in (NAME, NUMBER): ++ tokval += ' ' ++ ++ if toknum == INDENT: ++ indents.append(tokval) ++ continue ++ elif toknum == DEDENT: ++ indents.pop() ++ continue ++ elif toknum in (NEWLINE, NL): ++ startline = True ++ elif startline and indents: ++ toks_append(indents[-1]) ++ startline = False ++ toks_append(tokval) ++ ++def untokenize(iterable): ++ """Transform tokens back into Python source code. ++ ++ Each element returned by the iterable must be a token sequence ++ with at least two elements, a token number and token value. If ++ only two tokens are passed, the resulting output is poor. ++ ++ Round-trip invariant for full input: ++ Untokenized source will match input source exactly ++ ++ Round-trip invariant for limited intput: ++ # Output text will tokenize the back to the input ++ t1 = [tok[:2] for tok in generate_tokens(f.readline)] ++ newcode = untokenize(t1) ++ readline = iter(newcode.splitlines(1)).next ++ t2 = [tok[:2] for tokin generate_tokens(readline)] ++ assert t1 == t2 ++ """ ++ ut = Untokenizer() ++ return ut.untokenize(iterable) ++ ++def generate_tokens(readline): ++ """ ++ The generate_tokens() generator requires one argment, readline, which ++ must be a callable object which provides the same interface as the ++ readline() method of built-in file objects. Each call to the function ++ should return one line of input as a string. Alternately, readline ++ can be a callable function terminating with StopIteration: ++ readline = open(myfile).next # Example of alternate readline ++ ++ The generator produces 5-tuples with these members: the token type; the ++ token string; a 2-tuple (srow, scol) of ints specifying the row and ++ column where the token begins in the source; a 2-tuple (erow, ecol) of ++ ints specifying the row and column where the token ends in the source; ++ and the line on which the token was found. The line passed is the ++ logical line; continuation lines are included. ++ """ ++ lnum = parenlev = continued = 0 ++ namechars, numchars = string.ascii_letters + '_', '0123456789' ++ contstr, needcont = '', 0 ++ contline = None ++ indents = [0] ++ ++ while 1: # loop over lines in stream ++ try: ++ line = readline() ++ except StopIteration: ++ line = '' ++ lnum = lnum + 1 ++ pos, max = 0, len(line) ++ ++ if contstr: # continued string ++ if not line: ++ raise TokenError, ("EOF in multi-line string", strstart) ++ endmatch = endprog.match(line) ++ if endmatch: ++ pos = end = endmatch.end(0) ++ yield (STRING, contstr + line[:end], ++ strstart, (lnum, end), contline + line) ++ contstr, needcont = '', 0 ++ contline = None ++ elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n': ++ yield (ERRORTOKEN, contstr + line, ++ strstart, (lnum, len(line)), contline) ++ contstr = '' ++ contline = None ++ continue ++ else: ++ contstr = contstr + line ++ contline = contline + line ++ continue ++ ++ elif parenlev == 0 and not continued: # new statement ++ if not line: break ++ column = 0 ++ while pos < max: # measure leading whitespace ++ if line[pos] == ' ': column = column + 1 ++ elif line[pos] == '\t': column = (column/tabsize + 1)*tabsize ++ elif line[pos] == '\f': column = 0 ++ else: break ++ pos = pos + 1 ++ if pos == max: break ++ ++ if line[pos] in '#\r\n': # skip comments or blank lines ++ if line[pos] == '#': ++ comment_token = line[pos:].rstrip('\r\n') ++ nl_pos = pos + len(comment_token) ++ yield (COMMENT, comment_token, ++ (lnum, pos), (lnum, pos + len(comment_token)), line) ++ yield (NL, line[nl_pos:], ++ (lnum, nl_pos), (lnum, len(line)), line) ++ else: ++ yield ((NL, COMMENT)[line[pos] == '#'], line[pos:], ++ (lnum, pos), (lnum, len(line)), line) ++ continue ++ ++ if column > indents[-1]: # count indents or dedents ++ indents.append(column) ++ yield (INDENT, line[:pos], (lnum, 0), (lnum, pos), line) ++ while column < indents[-1]: ++ if column not in indents: ++ raise IndentationError( ++ "unindent does not match any outer indentation level", ++ ("", lnum, pos, line)) ++ indents = indents[:-1] ++ yield (DEDENT, '', (lnum, pos), (lnum, pos), line) ++ ++ else: # continued statement ++ if not line: ++ raise TokenError, ("EOF in multi-line statement", (lnum, 0)) ++ continued = 0 ++ ++ while pos < max: ++ pseudomatch = pseudoprog.match(line, pos) ++ if pseudomatch: # scan for tokens ++ start, end = pseudomatch.span(1) ++ spos, epos, pos = (lnum, start), (lnum, end), end ++ token, initial = line[start:end], line[start] ++ ++ if initial in numchars or \ ++ (initial == '.' and token != '.'): # ordinary number ++ yield (NUMBER, token, spos, epos, line) ++ elif initial in '\r\n': ++ newline = NEWLINE ++ if parenlev > 0: ++ newline = NL ++ yield (newline, token, spos, epos, line) ++ elif initial == '#': ++ assert not token.endswith("\n") ++ yield (COMMENT, token, spos, epos, line) ++ elif token in triple_quoted: ++ endprog = endprogs[token] ++ endmatch = endprog.match(line, pos) ++ if endmatch: # all on one line ++ pos = endmatch.end(0) ++ token = line[start:pos] ++ yield (STRING, token, spos, (lnum, pos), line) ++ else: ++ strstart = (lnum, start) # multiple lines ++ contstr = line[start:] ++ contline = line ++ break ++ elif initial in single_quoted or \ ++ token[:2] in single_quoted or \ ++ token[:3] in single_quoted: ++ if token[-1] == '\n': # continued string ++ strstart = (lnum, start) ++ endprog = (endprogs[initial] or endprogs[token[1]] or ++ endprogs[token[2]]) ++ contstr, needcont = line[start:], 1 ++ contline = line ++ break ++ else: # ordinary string ++ yield (STRING, token, spos, epos, line) ++ elif initial in namechars: # ordinary name ++ yield (NAME, token, spos, epos, line) ++ elif initial == '\\': # continued stmt ++ # This yield is new; needed for better idempotency: ++ yield (NL, token, spos, (lnum, pos), line) ++ continued = 1 ++ else: ++ if initial in '([{': parenlev = parenlev + 1 ++ elif initial in ')]}': parenlev = parenlev - 1 ++ yield (OP, token, spos, epos, line) ++ else: ++ yield (ERRORTOKEN, line[pos], ++ (lnum, pos), (lnum, pos+1), line) ++ pos = pos + 1 ++ ++ for indent in indents[1:]: # pop remaining indent levels ++ yield (DEDENT, '', (lnum, 0), (lnum, 0), '') ++ yield (ENDMARKER, '', (lnum, 0), (lnum, 0), '') ++ ++if __name__ == '__main__': # testing ++ import sys ++ if len(sys.argv) > 1: tokenize(open(sys.argv[1]).readline) ++ else: tokenize(sys.stdin.readline) +diff -r 531f2e948299 refactor/pygram.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pygram.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,31 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Export the Python grammar and symbols.""" ++ ++# Python imports ++import os ++ ++# Local imports ++from .pgen2 import token ++from .pgen2 import driver ++from . import pytree ++ ++# The grammar file ++_GRAMMAR_FILE = os.path.join(os.path.dirname(__file__), "Grammar.txt") ++ ++ ++class Symbols(object): ++ ++ def __init__(self, grammar): ++ """Initializer. ++ ++ Creates an attribute for each grammar symbol (nonterminal), ++ whose value is the symbol's type (an int >= 256). ++ """ ++ for name, symbol in grammar.symbol2number.iteritems(): ++ setattr(self, name, symbol) ++ ++ ++python_grammar = driver.load_grammar(_GRAMMAR_FILE) ++python_symbols = Symbols(python_grammar) +diff -r 531f2e948299 refactor/pytree.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/pytree.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,846 @@ ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++""" ++Python parse tree definitions. ++ ++This is a very concrete parse tree; we need to keep every token and ++even the comments and whitespace between tokens. ++ ++There's also a pattern matching implementation here. ++""" ++ ++__author__ = "Guido van Rossum " ++ ++import sys ++from StringIO import StringIO ++ ++ ++HUGE = 0x7FFFFFFF # maximum repeat count, default max ++ ++_type_reprs = {} ++def type_repr(type_num): ++ global _type_reprs ++ if not _type_reprs: ++ from .pygram import python_symbols ++ # printing tokens is possible but not as useful ++ # from .pgen2 import token // token.__dict__.items(): ++ for name, val in python_symbols.__dict__.items(): ++ if type(val) == int: _type_reprs[val] = name ++ return _type_reprs.setdefault(type_num, type_num) ++ ++ ++class Base(object): ++ ++ """ ++ Abstract base class for Node and Leaf. ++ ++ This provides some default functionality and boilerplate using the ++ template pattern. ++ ++ A node may be a subnode of at most one parent. ++ """ ++ ++ # Default values for instance variables ++ type = None # int: token number (< 256) or symbol number (>= 256) ++ parent = None # Parent node pointer, or None ++ children = () # Tuple of subnodes ++ was_changed = False ++ ++ def __new__(cls, *args, **kwds): ++ """Constructor that prevents Base from being instantiated.""" ++ assert cls is not Base, "Cannot instantiate Base" ++ return object.__new__(cls) ++ ++ def __eq__(self, other): ++ """ ++ Compare two nodes for equality. ++ ++ This calls the method _eq(). ++ """ ++ if self.__class__ is not other.__class__: ++ return NotImplemented ++ return self._eq(other) ++ ++ def __ne__(self, other): ++ """ ++ Compare two nodes for inequality. ++ ++ This calls the method _eq(). ++ """ ++ if self.__class__ is not other.__class__: ++ return NotImplemented ++ return not self._eq(other) ++ ++ def _eq(self, other): ++ """ ++ Compare two nodes for equality. ++ ++ This is called by __eq__ and __ne__. It is only called if the two nodes ++ have the same type. This must be implemented by the concrete subclass. ++ Nodes should be considered equal if they have the same structure, ++ ignoring the prefix string and other context information. ++ """ ++ raise NotImplementedError ++ ++ def clone(self): ++ """ ++ Return a cloned (deep) copy of self. ++ ++ This must be implemented by the concrete subclass. ++ """ ++ raise NotImplementedError ++ ++ def post_order(self): ++ """ ++ Return a post-order iterator for the tree. ++ ++ This must be implemented by the concrete subclass. ++ """ ++ raise NotImplementedError ++ ++ def pre_order(self): ++ """ ++ Return a pre-order iterator for the tree. ++ ++ This must be implemented by the concrete subclass. ++ """ ++ raise NotImplementedError ++ ++ def set_prefix(self, prefix): ++ """ ++ Set the prefix for the node (see Leaf class). ++ ++ This must be implemented by the concrete subclass. ++ """ ++ raise NotImplementedError ++ ++ def get_prefix(self): ++ """ ++ Return the prefix for the node (see Leaf class). ++ ++ This must be implemented by the concrete subclass. ++ """ ++ raise NotImplementedError ++ ++ def replace(self, new): ++ """Replace this node with a new one in the parent.""" ++ assert self.parent is not None, str(self) ++ assert new is not None ++ if not isinstance(new, list): ++ new = [new] ++ l_children = [] ++ found = False ++ for ch in self.parent.children: ++ if ch is self: ++ assert not found, (self.parent.children, self, new) ++ if new is not None: ++ l_children.extend(new) ++ found = True ++ else: ++ l_children.append(ch) ++ assert found, (self.children, self, new) ++ self.parent.changed() ++ self.parent.children = l_children ++ for x in new: ++ x.parent = self.parent ++ self.parent = None ++ ++ def get_lineno(self): ++ """Return the line number which generated the invocant node.""" ++ node = self ++ while not isinstance(node, Leaf): ++ if not node.children: ++ return ++ node = node.children[0] ++ return node.lineno ++ ++ def changed(self): ++ if self.parent: ++ self.parent.changed() ++ self.was_changed = True ++ ++ def remove(self): ++ """ ++ Remove the node from the tree. Returns the position of the node in its ++ parent's children before it was removed. ++ """ ++ if self.parent: ++ for i, node in enumerate(self.parent.children): ++ if node is self: ++ self.parent.changed() ++ del self.parent.children[i] ++ self.parent = None ++ return i ++ ++ @property ++ def next_sibling(self): ++ """ ++ The node immediately following the invocant in their parent's children ++ list. If the invocant does not have a next sibling, it is None ++ """ ++ if self.parent is None: ++ return None ++ ++ # Can't use index(); we need to test by identity ++ for i, child in enumerate(self.parent.children): ++ if child is self: ++ try: ++ return self.parent.children[i+1] ++ except IndexError: ++ return None ++ ++ @property ++ def prev_sibling(self): ++ """ ++ The node immediately preceding the invocant in their parent's children ++ list. If the invocant does not have a previous sibling, it is None. ++ """ ++ if self.parent is None: ++ return None ++ ++ # Can't use index(); we need to test by identity ++ for i, child in enumerate(self.parent.children): ++ if child is self: ++ if i == 0: ++ return None ++ return self.parent.children[i-1] ++ ++ def get_suffix(self): ++ """ ++ Return the string immediately following the invocant node. This is ++ effectively equivalent to node.next_sibling.get_prefix() ++ """ ++ next_sib = self.next_sibling ++ if next_sib is None: ++ return "" ++ return next_sib.get_prefix() ++ ++ ++class Node(Base): ++ ++ """Concrete implementation for interior nodes.""" ++ ++ def __init__(self, type, children, context=None, prefix=None): ++ """ ++ Initializer. ++ ++ Takes a type constant (a symbol number >= 256), a sequence of ++ child nodes, and an optional context keyword argument. ++ ++ As a side effect, the parent pointers of the children are updated. ++ """ ++ assert type >= 256, type ++ self.type = type ++ self.children = list(children) ++ for ch in self.children: ++ assert ch.parent is None, repr(ch) ++ ch.parent = self ++ if prefix is not None: ++ self.set_prefix(prefix) ++ ++ def __repr__(self): ++ """Return a canonical string representation.""" ++ return "%s(%s, %r)" % (self.__class__.__name__, ++ type_repr(self.type), ++ self.children) ++ ++ def __str__(self): ++ """ ++ Return a pretty string representation. ++ ++ This reproduces the input source exactly. ++ """ ++ return "".join(map(str, self.children)) ++ ++ def _eq(self, other): ++ """Compare two nodes for equality.""" ++ return (self.type, self.children) == (other.type, other.children) ++ ++ def clone(self): ++ """Return a cloned (deep) copy of self.""" ++ return Node(self.type, [ch.clone() for ch in self.children]) ++ ++ def post_order(self): ++ """Return a post-order iterator for the tree.""" ++ for child in self.children: ++ for node in child.post_order(): ++ yield node ++ yield self ++ ++ def pre_order(self): ++ """Return a pre-order iterator for the tree.""" ++ yield self ++ for child in self.children: ++ for node in child.post_order(): ++ yield node ++ ++ def set_prefix(self, prefix): ++ """ ++ Set the prefix for the node. ++ ++ This passes the responsibility on to the first child. ++ """ ++ if self.children: ++ self.children[0].set_prefix(prefix) ++ ++ def get_prefix(self): ++ """ ++ Return the prefix for the node. ++ ++ This passes the call on to the first child. ++ """ ++ if not self.children: ++ return "" ++ return self.children[0].get_prefix() ++ ++ def set_child(self, i, child): ++ """ ++ Equivalent to 'node.children[i] = child'. This method also sets the ++ child's parent attribute appropriately. ++ """ ++ child.parent = self ++ self.children[i].parent = None ++ self.children[i] = child ++ self.changed() ++ ++ def insert_child(self, i, child): ++ """ ++ Equivalent to 'node.children.insert(i, child)'. This method also sets ++ the child's parent attribute appropriately. ++ """ ++ child.parent = self ++ self.children.insert(i, child) ++ self.changed() ++ ++ def append_child(self, child): ++ """ ++ Equivalent to 'node.children.append(child)'. This method also sets the ++ child's parent attribute appropriately. ++ """ ++ child.parent = self ++ self.children.append(child) ++ self.changed() ++ ++ ++class Leaf(Base): ++ ++ """Concrete implementation for leaf nodes.""" ++ ++ # Default values for instance variables ++ prefix = "" # Whitespace and comments preceding this token in the input ++ lineno = 0 # Line where this token starts in the input ++ column = 0 # Column where this token tarts in the input ++ ++ def __init__(self, type, value, context=None, prefix=None): ++ """ ++ Initializer. ++ ++ Takes a type constant (a token number < 256), a string value, and an ++ optional context keyword argument. ++ """ ++ assert 0 <= type < 256, type ++ if context is not None: ++ self.prefix, (self.lineno, self.column) = context ++ self.type = type ++ self.value = value ++ if prefix is not None: ++ self.prefix = prefix ++ ++ def __repr__(self): ++ """Return a canonical string representation.""" ++ return "%s(%r, %r)" % (self.__class__.__name__, ++ self.type, ++ self.value) ++ ++ def __str__(self): ++ """ ++ Return a pretty string representation. ++ ++ This reproduces the input source exactly. ++ """ ++ return self.prefix + str(self.value) ++ ++ def _eq(self, other): ++ """Compare two nodes for equality.""" ++ return (self.type, self.value) == (other.type, other.value) ++ ++ def clone(self): ++ """Return a cloned (deep) copy of self.""" ++ return Leaf(self.type, self.value, ++ (self.prefix, (self.lineno, self.column))) ++ ++ def post_order(self): ++ """Return a post-order iterator for the tree.""" ++ yield self ++ ++ def pre_order(self): ++ """Return a pre-order iterator for the tree.""" ++ yield self ++ ++ def set_prefix(self, prefix): ++ """Set the prefix for the node.""" ++ self.changed() ++ self.prefix = prefix ++ ++ def get_prefix(self): ++ """Return the prefix for the node.""" ++ return self.prefix ++ ++ ++def convert(gr, raw_node): ++ """ ++ Convert raw node information to a Node or Leaf instance. ++ ++ This is passed to the parser driver which calls it whenever a reduction of a ++ grammar rule produces a new complete node, so that the tree is build ++ strictly bottom-up. ++ """ ++ type, value, context, children = raw_node ++ if children or type in gr.number2symbol: ++ # If there's exactly one child, return that child instead of ++ # creating a new node. ++ if len(children) == 1: ++ return children[0] ++ return Node(type, children, context=context) ++ else: ++ return Leaf(type, value, context=context) ++ ++ ++class BasePattern(object): ++ ++ """ ++ A pattern is a tree matching pattern. ++ ++ It looks for a specific node type (token or symbol), and ++ optionally for a specific content. ++ ++ This is an abstract base class. There are three concrete ++ subclasses: ++ ++ - LeafPattern matches a single leaf node; ++ - NodePattern matches a single node (usually non-leaf); ++ - WildcardPattern matches a sequence of nodes of variable length. ++ """ ++ ++ # Defaults for instance variables ++ type = None # Node type (token if < 256, symbol if >= 256) ++ content = None # Optional content matching pattern ++ name = None # Optional name used to store match in results dict ++ ++ def __new__(cls, *args, **kwds): ++ """Constructor that prevents BasePattern from being instantiated.""" ++ assert cls is not BasePattern, "Cannot instantiate BasePattern" ++ return object.__new__(cls) ++ ++ def __repr__(self): ++ args = [type_repr(self.type), self.content, self.name] ++ while args and args[-1] is None: ++ del args[-1] ++ return "%s(%s)" % (self.__class__.__name__, ", ".join(map(repr, args))) ++ ++ def optimize(self): ++ """ ++ A subclass can define this as a hook for optimizations. ++ ++ Returns either self or another node with the same effect. ++ """ ++ return self ++ ++ def match(self, node, results=None): ++ """ ++ Does this pattern exactly match a node? ++ ++ Returns True if it matches, False if not. ++ ++ If results is not None, it must be a dict which will be ++ updated with the nodes matching named subpatterns. ++ ++ Default implementation for non-wildcard patterns. ++ """ ++ if self.type is not None and node.type != self.type: ++ return False ++ if self.content is not None: ++ r = None ++ if results is not None: ++ r = {} ++ if not self._submatch(node, r): ++ return False ++ if r: ++ results.update(r) ++ if results is not None and self.name: ++ results[self.name] = node ++ return True ++ ++ def match_seq(self, nodes, results=None): ++ """ ++ Does this pattern exactly match a sequence of nodes? ++ ++ Default implementation for non-wildcard patterns. ++ """ ++ if len(nodes) != 1: ++ return False ++ return self.match(nodes[0], results) ++ ++ def generate_matches(self, nodes): ++ """ ++ Generator yielding all matches for this pattern. ++ ++ Default implementation for non-wildcard patterns. ++ """ ++ r = {} ++ if nodes and self.match(nodes[0], r): ++ yield 1, r ++ ++ ++class LeafPattern(BasePattern): ++ ++ def __init__(self, type=None, content=None, name=None): ++ """ ++ Initializer. Takes optional type, content, and name. ++ ++ The type, if given must be a token type (< 256). If not given, ++ this matches any *leaf* node; the content may still be required. ++ ++ The content, if given, must be a string. ++ ++ If a name is given, the matching node is stored in the results ++ dict under that key. ++ """ ++ if type is not None: ++ assert 0 <= type < 256, type ++ if content is not None: ++ assert isinstance(content, basestring), repr(content) ++ self.type = type ++ self.content = content ++ self.name = name ++ ++ def match(self, node, results=None): ++ """Override match() to insist on a leaf node.""" ++ if not isinstance(node, Leaf): ++ return False ++ return BasePattern.match(self, node, results) ++ ++ def _submatch(self, node, results=None): ++ """ ++ Match the pattern's content to the node's children. ++ ++ This assumes the node type matches and self.content is not None. ++ ++ Returns True if it matches, False if not. ++ ++ If results is not None, it must be a dict which will be ++ updated with the nodes matching named subpatterns. ++ ++ When returning False, the results dict may still be updated. ++ """ ++ return self.content == node.value ++ ++ ++class NodePattern(BasePattern): ++ ++ wildcards = False ++ ++ def __init__(self, type=None, content=None, name=None): ++ """ ++ Initializer. Takes optional type, content, and name. ++ ++ The type, if given, must be a symbol type (>= 256). If the ++ type is None this matches *any* single node (leaf or not), ++ except if content is not None, in which it only matches ++ non-leaf nodes that also match the content pattern. ++ ++ The content, if not None, must be a sequence of Patterns that ++ must match the node's children exactly. If the content is ++ given, the type must not be None. ++ ++ If a name is given, the matching node is stored in the results ++ dict under that key. ++ """ ++ if type is not None: ++ assert type >= 256, type ++ if content is not None: ++ assert not isinstance(content, basestring), repr(content) ++ content = list(content) ++ for i, item in enumerate(content): ++ assert isinstance(item, BasePattern), (i, item) ++ if isinstance(item, WildcardPattern): ++ self.wildcards = True ++ self.type = type ++ self.content = content ++ self.name = name ++ ++ def _submatch(self, node, results=None): ++ """ ++ Match the pattern's content to the node's children. ++ ++ This assumes the node type matches and self.content is not None. ++ ++ Returns True if it matches, False if not. ++ ++ If results is not None, it must be a dict which will be ++ updated with the nodes matching named subpatterns. ++ ++ When returning False, the results dict may still be updated. ++ """ ++ if self.wildcards: ++ for c, r in generate_matches(self.content, node.children): ++ if c == len(node.children): ++ if results is not None: ++ results.update(r) ++ return True ++ return False ++ if len(self.content) != len(node.children): ++ return False ++ for subpattern, child in zip(self.content, node.children): ++ if not subpattern.match(child, results): ++ return False ++ return True ++ ++ ++class WildcardPattern(BasePattern): ++ ++ """ ++ A wildcard pattern can match zero or more nodes. ++ ++ This has all the flexibility needed to implement patterns like: ++ ++ .* .+ .? .{m,n} ++ (a b c | d e | f) ++ (...)* (...)+ (...)? (...){m,n} ++ ++ except it always uses non-greedy matching. ++ """ ++ ++ def __init__(self, content=None, min=0, max=HUGE, name=None): ++ """ ++ Initializer. ++ ++ Args: ++ content: optional sequence of subsequences of patterns; ++ if absent, matches one node; ++ if present, each subsequence is an alternative [*] ++ min: optinal minumum number of times to match, default 0 ++ max: optional maximum number of times tro match, default HUGE ++ name: optional name assigned to this match ++ ++ [*] Thus, if content is [[a, b, c], [d, e], [f, g, h]] this is ++ equivalent to (a b c | d e | f g h); if content is None, ++ this is equivalent to '.' in regular expression terms. ++ The min and max parameters work as follows: ++ min=0, max=maxint: .* ++ min=1, max=maxint: .+ ++ min=0, max=1: .? ++ min=1, max=1: . ++ If content is not None, replace the dot with the parenthesized ++ list of alternatives, e.g. (a b c | d e | f g h)* ++ """ ++ assert 0 <= min <= max <= HUGE, (min, max) ++ if content is not None: ++ content = tuple(map(tuple, content)) # Protect against alterations ++ # Check sanity of alternatives ++ assert len(content), repr(content) # Can't have zero alternatives ++ for alt in content: ++ assert len(alt), repr(alt) # Can have empty alternatives ++ self.content = content ++ self.min = min ++ self.max = max ++ self.name = name ++ ++ def optimize(self): ++ """Optimize certain stacked wildcard patterns.""" ++ subpattern = None ++ if (self.content is not None and ++ len(self.content) == 1 and len(self.content[0]) == 1): ++ subpattern = self.content[0][0] ++ if self.min == 1 and self.max == 1: ++ if self.content is None: ++ return NodePattern(name=self.name) ++ if subpattern is not None and self.name == subpattern.name: ++ return subpattern.optimize() ++ if (self.min <= 1 and isinstance(subpattern, WildcardPattern) and ++ subpattern.min <= 1 and self.name == subpattern.name): ++ return WildcardPattern(subpattern.content, ++ self.min*subpattern.min, ++ self.max*subpattern.max, ++ subpattern.name) ++ return self ++ ++ def match(self, node, results=None): ++ """Does this pattern exactly match a node?""" ++ return self.match_seq([node], results) ++ ++ def match_seq(self, nodes, results=None): ++ """Does this pattern exactly match a sequence of nodes?""" ++ for c, r in self.generate_matches(nodes): ++ if c == len(nodes): ++ if results is not None: ++ results.update(r) ++ if self.name: ++ results[self.name] = list(nodes) ++ return True ++ return False ++ ++ def generate_matches(self, nodes): ++ """ ++ Generator yielding matches for a sequence of nodes. ++ ++ Args: ++ nodes: sequence of nodes ++ ++ Yields: ++ (count, results) tuples where: ++ count: the match comprises nodes[:count]; ++ results: dict containing named submatches. ++ """ ++ if self.content is None: ++ # Shortcut for special case (see __init__.__doc__) ++ for count in xrange(self.min, 1 + min(len(nodes), self.max)): ++ r = {} ++ if self.name: ++ r[self.name] = nodes[:count] ++ yield count, r ++ elif self.name == "bare_name": ++ yield self._bare_name_matches(nodes) ++ else: ++ # The reason for this is that hitting the recursion limit usually ++ # results in some ugly messages about how RuntimeErrors are being ++ # ignored. ++ save_stderr = sys.stderr ++ sys.stderr = StringIO() ++ try: ++ for count, r in self._recursive_matches(nodes, 0): ++ if self.name: ++ r[self.name] = nodes[:count] ++ yield count, r ++ except RuntimeError: ++ # We fall back to the iterative pattern matching scheme if the recursive ++ # scheme hits the recursion limit. ++ for count, r in self._iterative_matches(nodes): ++ if self.name: ++ r[self.name] = nodes[:count] ++ yield count, r ++ finally: ++ sys.stderr = save_stderr ++ ++ def _iterative_matches(self, nodes): ++ """Helper to iteratively yield the matches.""" ++ nodelen = len(nodes) ++ if 0 >= self.min: ++ yield 0, {} ++ ++ results = [] ++ # generate matches that use just one alt from self.content ++ for alt in self.content: ++ for c, r in generate_matches(alt, nodes): ++ yield c, r ++ results.append((c, r)) ++ ++ # for each match, iterate down the nodes ++ while results: ++ new_results = [] ++ for c0, r0 in results: ++ # stop if the entire set of nodes has been matched ++ if c0 < nodelen and c0 <= self.max: ++ for alt in self.content: ++ for c1, r1 in generate_matches(alt, nodes[c0:]): ++ if c1 > 0: ++ r = {} ++ r.update(r0) ++ r.update(r1) ++ yield c0 + c1, r ++ new_results.append((c0 + c1, r)) ++ results = new_results ++ ++ def _bare_name_matches(self, nodes): ++ """Special optimized matcher for bare_name.""" ++ count = 0 ++ r = {} ++ done = False ++ max = len(nodes) ++ while not done and count < max: ++ done = True ++ for leaf in self.content: ++ if leaf[0].match(nodes[count], r): ++ count += 1 ++ done = False ++ break ++ r[self.name] = nodes[:count] ++ return count, r ++ ++ def _recursive_matches(self, nodes, count): ++ """Helper to recursively yield the matches.""" ++ assert self.content is not None ++ if count >= self.min: ++ yield 0, {} ++ if count < self.max: ++ for alt in self.content: ++ for c0, r0 in generate_matches(alt, nodes): ++ for c1, r1 in self._recursive_matches(nodes[c0:], count+1): ++ r = {} ++ r.update(r0) ++ r.update(r1) ++ yield c0 + c1, r ++ ++ ++class NegatedPattern(BasePattern): ++ ++ def __init__(self, content=None): ++ """ ++ Initializer. ++ ++ The argument is either a pattern or None. If it is None, this ++ only matches an empty sequence (effectively '$' in regex ++ lingo). If it is not None, this matches whenever the argument ++ pattern doesn't have any matches. ++ """ ++ if content is not None: ++ assert isinstance(content, BasePattern), repr(content) ++ self.content = content ++ ++ def match(self, node): ++ # We never match a node in its entirety ++ return False ++ ++ def match_seq(self, nodes): ++ # We only match an empty sequence of nodes in its entirety ++ return len(nodes) == 0 ++ ++ def generate_matches(self, nodes): ++ if self.content is None: ++ # Return a match if there is an empty sequence ++ if len(nodes) == 0: ++ yield 0, {} ++ else: ++ # Return a match if the argument pattern has no matches ++ for c, r in self.content.generate_matches(nodes): ++ return ++ yield 0, {} ++ ++ ++def generate_matches(patterns, nodes): ++ """ ++ Generator yielding matches for a sequence of patterns and nodes. ++ ++ Args: ++ patterns: a sequence of patterns ++ nodes: a sequence of nodes ++ ++ Yields: ++ (count, results) tuples where: ++ count: the entire sequence of patterns matches nodes[:count]; ++ results: dict containing named submatches. ++ """ ++ if not patterns: ++ yield 0, {} ++ else: ++ p, rest = patterns[0], patterns[1:] ++ for c0, r0 in p.generate_matches(nodes): ++ if not rest: ++ yield c0, r0 ++ else: ++ for c1, r1 in generate_matches(rest, nodes[c0:]): ++ r = {} ++ r.update(r0) ++ r.update(r1) ++ yield c0 + c1, r +diff -r 531f2e948299 refactor/refactor.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/refactor.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,515 @@ ++#!/usr/bin/env python2.5 ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Refactoring framework. ++ ++Used as a main program, this can refactor any number of files and/or ++recursively descend down directories. Imported as a module, this ++provides infrastructure to write your own refactoring tool. ++""" ++ ++__author__ = "Guido van Rossum " ++ ++ ++# Python imports ++import os ++import sys ++import difflib ++import logging ++import operator ++from collections import defaultdict ++from itertools import chain ++ ++# Local imports ++from .pgen2 import driver ++from .pgen2 import tokenize ++ ++from . import pytree ++from . import patcomp ++from . import fixes ++from . import pygram ++ ++ ++def get_all_fix_names(fixer_pkg, remove_prefix=True): ++ """Return a sorted list of all available fix names in the given package.""" ++ pkg = __import__(fixer_pkg, [], [], ["*"]) ++ fixer_dir = os.path.dirname(pkg.__file__) ++ fix_names = [] ++ for name in sorted(os.listdir(fixer_dir)): ++ if name.startswith("fix_") and name.endswith(".py"): ++ if remove_prefix: ++ name = name[4:] ++ fix_names.append(name[:-3]) ++ return fix_names ++ ++def get_head_types(pat): ++ """ Accepts a pytree Pattern Node and returns a set ++ of the pattern types which will match first. """ ++ ++ if isinstance(pat, (pytree.NodePattern, pytree.LeafPattern)): ++ # NodePatters must either have no type and no content ++ # or a type and content -- so they don't get any farther ++ # Always return leafs ++ return set([pat.type]) ++ ++ if isinstance(pat, pytree.NegatedPattern): ++ if pat.content: ++ return get_head_types(pat.content) ++ return set([None]) # Negated Patterns don't have a type ++ ++ if isinstance(pat, pytree.WildcardPattern): ++ # Recurse on each node in content ++ r = set() ++ for p in pat.content: ++ for x in p: ++ r.update(get_head_types(x)) ++ return r ++ ++ raise Exception("Oh no! I don't understand pattern %s" %(pat)) ++ ++def get_headnode_dict(fixer_list): ++ """ Accepts a list of fixers and returns a dictionary ++ of head node type --> fixer list. """ ++ head_nodes = defaultdict(list) ++ for fixer in fixer_list: ++ if not fixer.pattern: ++ head_nodes[None].append(fixer) ++ continue ++ for t in get_head_types(fixer.pattern): ++ head_nodes[t].append(fixer) ++ return head_nodes ++ ++def get_fixers_from_package(pkg_name): ++ """ ++ Return the fully qualified names for fixers in the package pkg_name. ++ """ ++ return [pkg_name + "." + fix_name ++ for fix_name in get_all_fix_names(pkg_name, False)] ++ ++ ++class FixerError(Exception): ++ """A fixer could not be loaded.""" ++ ++ ++class RefactoringTool(object): ++ ++ _default_options = {"print_function": False} ++ ++ CLASS_PREFIX = "Fix" # The prefix for fixer classes ++ FILE_PREFIX = "fix_" # The prefix for modules with a fixer within ++ ++ def __init__(self, fixer_names, options=None, explicit=None): ++ """Initializer. ++ ++ Args: ++ fixer_names: a list of fixers to import ++ options: an dict with configuration. ++ explicit: a list of fixers to run even if they are explicit. ++ """ ++ self.fixers = fixer_names ++ self.explicit = explicit or [] ++ self.options = self._default_options.copy() ++ if options is not None: ++ self.options.update(options) ++ self.errors = [] ++ self.logger = logging.getLogger("RefactoringTool") ++ self.fixer_log = [] ++ self.wrote = False ++ if self.options["print_function"]: ++ del pygram.python_grammar.keywords["print"] ++ self.driver = driver.Driver(pygram.python_grammar, ++ convert=pytree.convert, ++ logger=self.logger) ++ self.pre_order, self.post_order = self.get_fixers() ++ ++ self.pre_order_heads = get_headnode_dict(self.pre_order) ++ self.post_order_heads = get_headnode_dict(self.post_order) ++ ++ self.files = [] # List of files that were or should be modified ++ ++ def get_fixers(self): ++ """Inspects the options to load the requested patterns and handlers. ++ ++ Returns: ++ (pre_order, post_order), where pre_order is the list of fixers that ++ want a pre-order AST traversal, and post_order is the list that want ++ post-order traversal. ++ """ ++ pre_order_fixers = [] ++ post_order_fixers = [] ++ for fix_mod_path in self.fixers: ++ mod = __import__(fix_mod_path, {}, {}, ["*"]) ++ fix_name = fix_mod_path.rsplit(".", 1)[-1] ++ if fix_name.startswith(self.FILE_PREFIX): ++ fix_name = fix_name[len(self.FILE_PREFIX):] ++ parts = fix_name.split("_") ++ class_name = self.CLASS_PREFIX + "".join([p.title() for p in parts]) ++ try: ++ fix_class = getattr(mod, class_name) ++ except AttributeError: ++ raise FixerError("Can't find %s.%s" % (fix_name, class_name)) ++ fixer = fix_class(self.options, self.fixer_log) ++ if fixer.explicit and self.explicit is not True and \ ++ fix_mod_path not in self.explicit: ++ self.log_message("Skipping implicit fixer: %s", fix_name) ++ continue ++ ++ self.log_debug("Adding transformation: %s", fix_name) ++ if fixer.order == "pre": ++ pre_order_fixers.append(fixer) ++ elif fixer.order == "post": ++ post_order_fixers.append(fixer) ++ else: ++ raise FixerError("Illegal fixer order: %r" % fixer.order) ++ ++ key_func = operator.attrgetter("run_order") ++ pre_order_fixers.sort(key=key_func) ++ post_order_fixers.sort(key=key_func) ++ return (pre_order_fixers, post_order_fixers) ++ ++ def log_error(self, msg, *args, **kwds): ++ """Called when an error occurs.""" ++ raise ++ ++ def log_message(self, msg, *args): ++ """Hook to log a message.""" ++ if args: ++ msg = msg % args ++ self.logger.info(msg) ++ ++ def log_debug(self, msg, *args): ++ if args: ++ msg = msg % args ++ self.logger.debug(msg) ++ ++ def print_output(self, lines): ++ """Called with lines of output to give to the user.""" ++ pass ++ ++ def refactor(self, items, write=False, doctests_only=False): ++ """Refactor a list of files and directories.""" ++ for dir_or_file in items: ++ if os.path.isdir(dir_or_file): ++ self.refactor_dir(dir_or_file, write, doctests_only) ++ else: ++ self.refactor_file(dir_or_file, write, doctests_only) ++ ++ def refactor_dir(self, dir_name, write=False, doctests_only=False): ++ """Descends down a directory and refactor every Python file found. ++ ++ Python files are assumed to have a .py extension. ++ ++ Files and subdirectories starting with '.' are skipped. ++ """ ++ 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 name.endswith("py"): ++ fullname = os.path.join(dirpath, name) ++ self.refactor_file(fullname, write, doctests_only) ++ # Modify dirnames in-place to remove subdirs with leading dots ++ dirnames[:] = [dn for dn in dirnames if not dn.startswith(".")] ++ ++ def refactor_file(self, filename, write=False, doctests_only=False): ++ """Refactors a file.""" ++ try: ++ f = open(filename) ++ except IOError, err: ++ self.log_error("Can't open %s: %s", filename, err) ++ return ++ try: ++ input = f.read() + "\n" # Silence certain parse errors ++ finally: ++ f.close() ++ if doctests_only: ++ self.log_debug("Refactoring doctests in %s", filename) ++ output = self.refactor_docstring(input, filename) ++ if output != input: ++ self.processed_file(output, filename, input, write=write) ++ else: ++ self.log_debug("No doctest changes in %s", filename) ++ else: ++ tree = self.refactor_string(input, filename) ++ if tree and tree.was_changed: ++ # The [:-1] is to take off the \n we added earlier ++ self.processed_file(str(tree)[:-1], filename, write=write) ++ else: ++ self.log_debug("No changes in %s", filename) ++ ++ def refactor_string(self, data, name): ++ """Refactor a given input string. ++ ++ Args: ++ data: a string holding the code to be refactored. ++ name: a human-readable name for use in error/log messages. ++ ++ Returns: ++ An AST corresponding to the refactored input stream; None if ++ there were errors during the parse. ++ """ ++ try: ++ tree = self.driver.parse_string(data) ++ except Exception, err: ++ self.log_error("Can't parse %s: %s: %s", ++ name, err.__class__.__name__, err) ++ return ++ self.log_debug("Refactoring %s", name) ++ self.refactor_tree(tree, name) ++ return tree ++ ++ def refactor_stdin(self, doctests_only=False): ++ input = sys.stdin.read() ++ if doctests_only: ++ self.log_debug("Refactoring doctests in stdin") ++ output = self.refactor_docstring(input, "") ++ if output != input: ++ self.processed_file(output, "", input) ++ else: ++ self.log_debug("No doctest changes in stdin") ++ else: ++ tree = self.refactor_string(input, "") ++ if tree and tree.was_changed: ++ self.processed_file(str(tree), "", input) ++ else: ++ self.log_debug("No changes in stdin") ++ ++ def refactor_tree(self, tree, name): ++ """Refactors a parse tree (modifying the tree in place). ++ ++ Args: ++ tree: a pytree.Node instance representing the root of the tree ++ to be refactored. ++ name: a human-readable name for this tree. ++ ++ Returns: ++ True if the tree was modified, False otherwise. ++ """ ++ for fixer in chain(self.pre_order, self.post_order): ++ fixer.start_tree(tree, name) ++ ++ self.traverse_by(self.pre_order_heads, tree.pre_order()) ++ self.traverse_by(self.post_order_heads, tree.post_order()) ++ ++ for fixer in chain(self.pre_order, self.post_order): ++ fixer.finish_tree(tree, name) ++ return tree.was_changed ++ ++ def traverse_by(self, fixers, traversal): ++ """Traverse an AST, applying a set of fixers to each node. ++ ++ This is a helper method for refactor_tree(). ++ ++ Args: ++ fixers: a list of fixer instances. ++ traversal: a generator that yields AST nodes. ++ ++ Returns: ++ None ++ """ ++ if not fixers: ++ return ++ for node in traversal: ++ for fixer in fixers[node.type] + fixers[None]: ++ results = fixer.match(node) ++ if results: ++ new = fixer.transform(node, results) ++ if new is not None and (new != node or ++ str(new) != str(node)): ++ node.replace(new) ++ node = new ++ ++ def processed_file(self, new_text, filename, old_text=None, write=False): ++ """ ++ Called when a file has been refactored, and there are changes. ++ """ ++ self.files.append(filename) ++ if old_text is None: ++ try: ++ f = open(filename, "r") ++ except IOError, err: ++ self.log_error("Can't read %s: %s", filename, err) ++ return ++ try: ++ old_text = f.read() ++ finally: ++ f.close() ++ if old_text == new_text: ++ self.log_debug("No changes to %s", filename) ++ return ++ self.print_output(diff_texts(old_text, new_text, filename)) ++ if write: ++ self.write_file(new_text, filename, old_text) ++ else: ++ self.log_debug("Not writing changes to %s", filename) ++ ++ def write_file(self, new_text, filename, old_text): ++ """Writes a string to a file. ++ ++ It first shows a unified diff between the old text and the new text, and ++ then rewrites the file; the latter is only done if the write option is ++ set. ++ """ ++ try: ++ f = open(filename, "w") ++ except os.error, err: ++ self.log_error("Can't create %s: %s", filename, err) ++ return ++ try: ++ f.write(new_text) ++ except os.error, err: ++ self.log_error("Can't write %s: %s", filename, err) ++ finally: ++ f.close() ++ self.log_debug("Wrote changes to %s", filename) ++ self.wrote = True ++ ++ PS1 = ">>> " ++ PS2 = "... " ++ ++ def refactor_docstring(self, input, filename): ++ """Refactors a docstring, looking for doctests. ++ ++ This returns a modified version of the input string. It looks ++ for doctests, which start with a ">>>" prompt, and may be ++ continued with "..." prompts, as long as the "..." is indented ++ the same as the ">>>". ++ ++ (Unfortunately we can't use the doctest module's parser, ++ since, like most parsers, it is not geared towards preserving ++ the original source.) ++ """ ++ result = [] ++ block = None ++ block_lineno = None ++ indent = None ++ lineno = 0 ++ for line in input.splitlines(True): ++ lineno += 1 ++ if line.lstrip().startswith(self.PS1): ++ if block is not None: ++ result.extend(self.refactor_doctest(block, block_lineno, ++ indent, filename)) ++ block_lineno = lineno ++ block = [line] ++ i = line.find(self.PS1) ++ indent = line[:i] ++ elif (indent is not None and ++ (line.startswith(indent + self.PS2) or ++ line == indent + self.PS2.rstrip() + "\n")): ++ block.append(line) ++ else: ++ if block is not None: ++ result.extend(self.refactor_doctest(block, block_lineno, ++ indent, filename)) ++ block = None ++ indent = None ++ result.append(line) ++ if block is not None: ++ result.extend(self.refactor_doctest(block, block_lineno, ++ indent, filename)) ++ return "".join(result) ++ ++ def refactor_doctest(self, block, lineno, indent, filename): ++ """Refactors one doctest. ++ ++ A doctest is given as a block of lines, the first of which starts ++ with ">>>" (possibly indented), while the remaining lines start ++ with "..." (identically indented). ++ ++ """ ++ try: ++ tree = self.parse_block(block, lineno, indent) ++ except Exception, err: ++ if self.log.isEnabledFor(logging.DEBUG): ++ for line in block: ++ self.log_debug("Source: %s", line.rstrip("\n")) ++ self.log_error("Can't parse docstring in %s line %s: %s: %s", ++ filename, lineno, err.__class__.__name__, err) ++ return block ++ if self.refactor_tree(tree, filename): ++ new = str(tree).splitlines(True) ++ # Undo the adjustment of the line numbers in wrap_toks() below. ++ clipped, new = new[:lineno-1], new[lineno-1:] ++ assert clipped == ["\n"] * (lineno-1), clipped ++ if not new[-1].endswith("\n"): ++ new[-1] += "\n" ++ block = [indent + self.PS1 + new.pop(0)] ++ if new: ++ block += [indent + self.PS2 + line for line in new] ++ return block ++ ++ def summarize(self): ++ if self.wrote: ++ were = "were" ++ else: ++ were = "need to be" ++ if not self.files: ++ self.log_message("No files %s modified.", were) ++ else: ++ self.log_message("Files that %s modified:", were) ++ for file in self.files: ++ self.log_message(file) ++ if self.fixer_log: ++ self.log_message("Warnings/messages while refactoring:") ++ for message in self.fixer_log: ++ self.log_message(message) ++ if self.errors: ++ if len(self.errors) == 1: ++ self.log_message("There was 1 error:") ++ else: ++ self.log_message("There were %d errors:", len(self.errors)) ++ for msg, args, kwds in self.errors: ++ self.log_message(msg, *args, **kwds) ++ ++ def parse_block(self, block, lineno, indent): ++ """Parses a block into a tree. ++ ++ This is necessary to get correct line number / offset information ++ in the parser diagnostics and embedded into the parse tree. ++ """ ++ return self.driver.parse_tokens(self.wrap_toks(block, lineno, indent)) ++ ++ def wrap_toks(self, block, lineno, indent): ++ """Wraps a tokenize stream to systematically modify start/end.""" ++ tokens = tokenize.generate_tokens(self.gen_lines(block, indent).next) ++ for type, value, (line0, col0), (line1, col1), line_text in tokens: ++ line0 += lineno - 1 ++ line1 += lineno - 1 ++ # Don't bother updating the columns; this is too complicated ++ # since line_text would also have to be updated and it would ++ # still break for tokens spanning lines. Let the user guess ++ # that the column numbers for doctests are relative to the ++ # end of the prompt string (PS1 or PS2). ++ yield type, value, (line0, col0), (line1, col1), line_text ++ ++ ++ def gen_lines(self, block, indent): ++ """Generates lines as expected by tokenize from a list of lines. ++ ++ This strips the first len(indent + self.PS1) characters off each line. ++ """ ++ prefix1 = indent + self.PS1 ++ prefix2 = indent + self.PS2 ++ prefix = prefix1 ++ for line in block: ++ if line.startswith(prefix): ++ yield line[len(prefix):] ++ elif line == prefix.rstrip() + "\n": ++ yield "\n" ++ else: ++ raise AssertionError("line=%r, prefix=%r" % (line, prefix)) ++ prefix = prefix2 ++ while True: ++ yield "" ++ ++ ++def diff_texts(a, b, filename): ++ """Return a unified diff of two strings.""" ++ a = a.splitlines() ++ b = b.splitlines() ++ return difflib.unified_diff(a, b, filename, filename, ++ "(original)", "(refactored)", ++ lineterm="") +diff -r 531f2e948299 refactor/tests/.svn/all-wcprops +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/all-wcprops Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,59 @@ ++K 25 ++svn:wc:ra_dav:version-url ++V 57 ++/projects/!svn/ver/69679/sandbox/trunk/2to3/lib2to3/tests ++END ++pytree_idempotency.py ++K 25 ++svn:wc:ra_dav:version-url ++V 79 ++/projects/!svn/ver/61730/sandbox/trunk/2to3/lib2to3/tests/pytree_idempotency.py ++END ++test_parser.py ++K 25 ++svn:wc:ra_dav:version-url ++V 72 ++/projects/!svn/ver/67433/sandbox/trunk/2to3/lib2to3/tests/test_parser.py ++END ++support.py ++K 25 ++svn:wc:ra_dav:version-url ++V 68 ++/projects/!svn/ver/66173/sandbox/trunk/2to3/lib2to3/tests/support.py ++END ++test_util.py ++K 25 ++svn:wc:ra_dav:version-url ++V 70 ++/projects/!svn/ver/67657/sandbox/trunk/2to3/lib2to3/tests/test_util.py ++END ++__init__.py ++K 25 ++svn:wc:ra_dav:version-url ++V 69 ++/projects/!svn/ver/61428/sandbox/trunk/2to3/lib2to3/tests/__init__.py ++END ++test_fixers.py ++K 25 ++svn:wc:ra_dav:version-url ++V 72 ++/projects/!svn/ver/69673/sandbox/trunk/2to3/lib2to3/tests/test_fixers.py ++END ++test_refactor.py ++K 25 ++svn:wc:ra_dav:version-url ++V 74 ++/projects/!svn/ver/67387/sandbox/trunk/2to3/lib2to3/tests/test_refactor.py ++END ++test_all_fixers.py ++K 25 ++svn:wc:ra_dav:version-url ++V 76 ++/projects/!svn/ver/67433/sandbox/trunk/2to3/lib2to3/tests/test_all_fixers.py ++END ++test_pytree.py ++K 25 ++svn:wc:ra_dav:version-url ++V 72 ++/projects/!svn/ver/69679/sandbox/trunk/2to3/lib2to3/tests/test_pytree.py ++END +diff -r 531f2e948299 refactor/tests/.svn/dir-prop-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/dir-prop-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,7 @@ ++K 10 ++svn:ignore ++V 10 ++*.py[co] ++ ++ ++END +diff -r 531f2e948299 refactor/tests/.svn/entries +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/entries Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,337 @@ ++9 ++ ++dir ++70822 ++http://svn.python.org/projects/sandbox/trunk/2to3/lib2to3/tests ++http://svn.python.org/projects ++ ++ ++ ++2009-02-16T17:36:06.789054Z ++69679 ++benjamin.peterson ++has-props ++ ++svn:special svn:externals svn:needs-lock ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++6015fed2-1504-0410-9fe1-9d1591cc4771 ++ ++pytree_idempotency.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++e986d49af7eaec7f1c3b4aad0eba7a5f ++2008-03-22T01:20:58.257475Z ++61730 ++martin.v.loewis ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++2388 ++ ++test_parser.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++cbd31809d8ce5f34919c9cc1e562af92 ++2008-11-28T23:18:48.744865Z ++67433 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++5442 ++ ++support.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++a6fa869036ac2d67729bfaef53816ea8 ++2008-09-02T23:57:48.132672Z ++66173 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++1940 ++ ++test_util.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++34b1ab2a57dada2c15c0b151b66ad03f ++2008-12-08T00:29:35.627027Z ++67657 ++armin.ronacher ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++19381 ++ ++__init__.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++330a2c5032ea141b9040018e7a8b3592 ++2008-03-16T19:36:15.363093Z ++61428 ++martin.v.loewis ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++673 ++ ++test_fixers.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++419bb7e4c3fdb437f6a96a41d08b8018 ++2009-02-16T15:38:22.416590Z ++69673 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++105540 ++ ++data ++dir ++ ++test_refactor.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++2feffd023443365043e7d4b84a2d51fe ++2008-11-25T22:47:54.627063Z ++67387 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++5263 ++ ++test_all_fixers.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++1b89e96fcb7c0ff2d9ef4f956297a15b ++2008-11-28T23:18:48.744865Z ++67433 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++838 ++ ++test_pytree.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++fb40a7fff78f0f87d810ec19de7505da ++2009-02-16T17:36:06.789054Z ++69679 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++15756 ++ +diff -r 531f2e948299 refactor/tests/.svn/format +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/format Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,1 @@ ++9 +diff -r 531f2e948299 refactor/tests/.svn/prop-base/__init__.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/prop-base/__init__.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/tests/.svn/prop-base/pytree_idempotency.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/prop-base/pytree_idempotency.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,13 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 14 ++svn:executable ++V 1 ++* ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/tests/.svn/prop-base/support.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/prop-base/support.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/tests/.svn/prop-base/test_all_fixers.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/prop-base/test_all_fixers.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,5 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++END +diff -r 531f2e948299 refactor/tests/.svn/prop-base/test_fixers.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/prop-base/test_fixers.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,13 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 14 ++svn:executable ++V 1 ++* ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/tests/.svn/prop-base/test_parser.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/prop-base/test_parser.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,5 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++END +diff -r 531f2e948299 refactor/tests/.svn/prop-base/test_pytree.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/prop-base/test_pytree.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,13 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 14 ++svn:executable ++V 1 ++* ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/tests/.svn/prop-base/test_refactor.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/prop-base/test_refactor.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/tests/.svn/prop-base/test_util.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/prop-base/test_util.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/tests/.svn/text-base/__init__.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/text-base/__init__.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,24 @@ ++"""Make tests/ into a package. This allows us to "import tests" and ++have tests.all_tests be a TestSuite representing all test cases ++from all test_*.py files in tests/.""" ++# Author: Collin Winter ++ ++import os ++import os.path ++import unittest ++import types ++ ++from . import support ++ ++all_tests = unittest.TestSuite() ++ ++tests_dir = os.path.join(os.path.dirname(__file__), '..', 'tests') ++tests = [t[0:-3] for t in os.listdir(tests_dir) ++ if t.startswith('test_') and t.endswith('.py')] ++ ++loader = unittest.TestLoader() ++ ++for t in tests: ++ __import__("",globals(),locals(),[t],level=1) ++ mod = globals()[t] ++ all_tests.addTests(loader.loadTestsFromModule(mod)) +diff -r 531f2e948299 refactor/tests/.svn/text-base/pytree_idempotency.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/text-base/pytree_idempotency.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,92 @@ ++#!/usr/bin/env python2.5 ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Main program for testing the infrastructure.""" ++ ++__author__ = "Guido van Rossum " ++ ++# Support imports (need to be imported first) ++from . import support ++ ++# Python imports ++import os ++import sys ++import logging ++ ++# Local imports ++from .. import pytree ++import pgen2 ++from pgen2 import driver ++ ++logging.basicConfig() ++ ++def main(): ++ gr = driver.load_grammar("Grammar.txt") ++ dr = driver.Driver(gr, convert=pytree.convert) ++ ++ fn = "example.py" ++ tree = dr.parse_file(fn, debug=True) ++ if not diff(fn, tree): ++ print "No diffs." ++ if not sys.argv[1:]: ++ return # Pass a dummy argument to run the complete test suite below ++ ++ problems = [] ++ ++ # Process every imported module ++ for name in sys.modules: ++ mod = sys.modules[name] ++ if mod is None or not hasattr(mod, "__file__"): ++ continue ++ fn = mod.__file__ ++ if fn.endswith(".pyc"): ++ fn = fn[:-1] ++ if not fn.endswith(".py"): ++ continue ++ print >>sys.stderr, "Parsing", fn ++ tree = dr.parse_file(fn, debug=True) ++ if diff(fn, tree): ++ problems.append(fn) ++ ++ # Process every single module on sys.path (but not in packages) ++ for dir in sys.path: ++ try: ++ names = os.listdir(dir) ++ except os.error: ++ continue ++ print >>sys.stderr, "Scanning", dir, "..." ++ for name in names: ++ if not name.endswith(".py"): ++ continue ++ print >>sys.stderr, "Parsing", name ++ fn = os.path.join(dir, name) ++ try: ++ tree = dr.parse_file(fn, debug=True) ++ except pgen2.parse.ParseError, err: ++ print "ParseError:", err ++ else: ++ if diff(fn, tree): ++ problems.append(fn) ++ ++ # Show summary of problem files ++ if not problems: ++ print "No problems. Congratulations!" ++ else: ++ print "Problems in following files:" ++ for fn in problems: ++ print "***", fn ++ ++def diff(fn, tree): ++ f = open("@", "w") ++ try: ++ f.write(str(tree)) ++ finally: ++ f.close() ++ try: ++ return os.system("diff -u %s @" % fn) ++ finally: ++ os.remove("@") ++ ++if __name__ == "__main__": ++ main() +diff -r 531f2e948299 refactor/tests/.svn/text-base/support.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/text-base/support.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,63 @@ ++"""Support code for test_*.py files""" ++# Author: Collin Winter ++ ++# Python imports ++import unittest ++import sys ++import os ++import os.path ++import re ++from textwrap import dedent ++ ++#sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) ++ ++# Local imports ++from .. import pytree ++from .. import refactor ++from ..pgen2 import driver ++ ++test_dir = os.path.dirname(__file__) ++proj_dir = os.path.normpath(os.path.join(test_dir, "..")) ++grammar_path = os.path.join(test_dir, "..", "Grammar.txt") ++grammar = driver.load_grammar(grammar_path) ++driver = driver.Driver(grammar, convert=pytree.convert) ++ ++def parse_string(string): ++ return driver.parse_string(reformat(string), debug=True) ++ ++# Python 2.3's TestSuite is not iter()-able ++if sys.version_info < (2, 4): ++ def TestSuite_iter(self): ++ return iter(self._tests) ++ unittest.TestSuite.__iter__ = TestSuite_iter ++ ++def run_all_tests(test_mod=None, tests=None): ++ if tests is None: ++ tests = unittest.TestLoader().loadTestsFromModule(test_mod) ++ unittest.TextTestRunner(verbosity=2).run(tests) ++ ++def reformat(string): ++ return dedent(string) + "\n\n" ++ ++def get_refactorer(fixers=None, options=None): ++ """ ++ A convenience function for creating a RefactoringTool for tests. ++ ++ fixers is a list of fixers for the RefactoringTool to use. By default ++ "lib2to3.fixes.*" is used. options is an optional dictionary of options to ++ be passed to the RefactoringTool. ++ """ ++ if fixers is not None: ++ fixers = ["lib2to3.fixes.fix_" + fix for fix in fixers] ++ else: ++ fixers = refactor.get_fixers_from_package("lib2to3.fixes") ++ options = options or {} ++ return refactor.RefactoringTool(fixers, options, explicit=True) ++ ++def all_project_files(): ++ for dirpath, dirnames, filenames in os.walk(proj_dir): ++ for filename in filenames: ++ if filename.endswith(".py"): ++ yield os.path.join(dirpath, filename) ++ ++TestCase = unittest.TestCase +diff -r 531f2e948299 refactor/tests/.svn/text-base/test_all_fixers.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/text-base/test_all_fixers.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,35 @@ ++#!/usr/bin/env python2.5 ++"""Tests that run all fixer modules over an input stream. ++ ++This has been broken out into its own test module because of its ++running time. ++""" ++# Author: Collin Winter ++ ++# Testing imports ++try: ++ from . import support ++except ImportError: ++ import support ++ ++# Python imports ++import unittest ++ ++# Local imports ++from .. import pytree ++from .. import refactor ++ ++class Test_all(support.TestCase): ++ def setUp(self): ++ options = {"print_function" : False} ++ self.refactor = support.get_refactorer(options=options) ++ ++ def test_all_project_files(self): ++ for filepath in support.all_project_files(): ++ print "Fixing %s..." % filepath ++ self.refactor.refactor_string(open(filepath).read(), filepath) ++ ++ ++if __name__ == "__main__": ++ import __main__ ++ support.run_all_tests(__main__) +diff -r 531f2e948299 refactor/tests/.svn/text-base/test_fixers.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/text-base/test_fixers.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,4033 @@ ++#!/usr/bin/env python2.5 ++""" Test suite for the fixer modules """ ++# Author: Collin Winter ++ ++# Testing imports ++try: ++ from tests import support ++except ImportError: ++ import support ++ ++# Python imports ++import os ++import unittest ++from itertools import chain ++from operator import itemgetter ++ ++# Local imports ++from lib2to3 import pygram, pytree, refactor, fixer_util ++ ++ ++class FixerTestCase(support.TestCase): ++ def setUp(self, fix_list=None): ++ if fix_list is None: ++ fix_list = [self.fixer] ++ options = {"print_function" : False} ++ self.refactor = support.get_refactorer(fix_list, options) ++ self.fixer_log = [] ++ self.filename = "" ++ ++ for fixer in chain(self.refactor.pre_order, ++ self.refactor.post_order): ++ fixer.log = self.fixer_log ++ ++ def _check(self, before, after): ++ before = support.reformat(before) ++ after = support.reformat(after) ++ tree = self.refactor.refactor_string(before, self.filename) ++ self.failUnlessEqual(after, str(tree)) ++ return tree ++ ++ def check(self, before, after, ignore_warnings=False): ++ tree = self._check(before, after) ++ self.failUnless(tree.was_changed) ++ if not ignore_warnings: ++ self.failUnlessEqual(self.fixer_log, []) ++ ++ def warns(self, before, after, message, unchanged=False): ++ tree = self._check(before, after) ++ self.failUnless(message in "".join(self.fixer_log)) ++ if not unchanged: ++ self.failUnless(tree.was_changed) ++ ++ def warns_unchanged(self, before, message): ++ self.warns(before, before, message, unchanged=True) ++ ++ def unchanged(self, before, ignore_warnings=False): ++ self._check(before, before) ++ if not ignore_warnings: ++ self.failUnlessEqual(self.fixer_log, []) ++ ++ def assert_runs_after(self, *names): ++ fixes = [self.fixer] ++ fixes.extend(names) ++ options = {"print_function" : False} ++ r = support.get_refactorer(fixes, options) ++ (pre, post) = r.get_fixers() ++ n = "fix_" + self.fixer ++ if post and post[-1].__class__.__module__.endswith(n): ++ # We're the last fixer to run ++ return ++ if pre and pre[-1].__class__.__module__.endswith(n) and not post: ++ # We're the last in pre and post is empty ++ return ++ self.fail("Fixer run order (%s) is incorrect; %s should be last."\ ++ %(", ".join([x.__class__.__module__ for x in (pre+post)]), n)) ++ ++class Test_ne(FixerTestCase): ++ fixer = "ne" ++ ++ def test_basic(self): ++ b = """if x <> y: ++ pass""" ++ ++ a = """if x != y: ++ pass""" ++ self.check(b, a) ++ ++ def test_no_spaces(self): ++ b = """if x<>y: ++ pass""" ++ ++ a = """if x!=y: ++ pass""" ++ self.check(b, a) ++ ++ def test_chained(self): ++ b = """if x<>y<>z: ++ pass""" ++ ++ a = """if x!=y!=z: ++ pass""" ++ self.check(b, a) ++ ++class Test_has_key(FixerTestCase): ++ fixer = "has_key" ++ ++ def test_1(self): ++ b = """x = d.has_key("x") or d.has_key("y")""" ++ a = """x = "x" in d or "y" in d""" ++ self.check(b, a) ++ ++ def test_2(self): ++ b = """x = a.b.c.d.has_key("x") ** 3""" ++ a = """x = ("x" in a.b.c.d) ** 3""" ++ self.check(b, a) ++ ++ def test_3(self): ++ b = """x = a.b.has_key(1 + 2).__repr__()""" ++ a = """x = (1 + 2 in a.b).__repr__()""" ++ self.check(b, a) ++ ++ def test_4(self): ++ b = """x = a.b.has_key(1 + 2).__repr__() ** -3 ** 4""" ++ a = """x = (1 + 2 in a.b).__repr__() ** -3 ** 4""" ++ self.check(b, a) ++ ++ def test_5(self): ++ b = """x = a.has_key(f or g)""" ++ a = """x = (f or g) in a""" ++ self.check(b, a) ++ ++ def test_6(self): ++ b = """x = a + b.has_key(c)""" ++ a = """x = a + (c in b)""" ++ self.check(b, a) ++ ++ def test_7(self): ++ b = """x = a.has_key(lambda: 12)""" ++ a = """x = (lambda: 12) in a""" ++ self.check(b, a) ++ ++ def test_8(self): ++ b = """x = a.has_key(a for a in b)""" ++ a = """x = (a for a in b) in a""" ++ self.check(b, a) ++ ++ def test_9(self): ++ b = """if not a.has_key(b): pass""" ++ a = """if b not in a: pass""" ++ self.check(b, a) ++ ++ def test_10(self): ++ b = """if not a.has_key(b).__repr__(): pass""" ++ a = """if not (b in a).__repr__(): pass""" ++ self.check(b, a) ++ ++ def test_11(self): ++ b = """if not a.has_key(b) ** 2: pass""" ++ a = """if not (b in a) ** 2: pass""" ++ self.check(b, a) ++ ++class Test_apply(FixerTestCase): ++ fixer = "apply" ++ ++ def test_1(self): ++ b = """x = apply(f, g + h)""" ++ a = """x = f(*g + h)""" ++ self.check(b, a) ++ ++ def test_2(self): ++ b = """y = apply(f, g, h)""" ++ a = """y = f(*g, **h)""" ++ self.check(b, a) ++ ++ def test_3(self): ++ b = """z = apply(fs[0], g or h, h or g)""" ++ a = """z = fs[0](*g or h, **h or g)""" ++ self.check(b, a) ++ ++ def test_4(self): ++ b = """apply(f, (x, y) + t)""" ++ a = """f(*(x, y) + t)""" ++ self.check(b, a) ++ ++ def test_5(self): ++ b = """apply(f, args,)""" ++ a = """f(*args)""" ++ self.check(b, a) ++ ++ def test_6(self): ++ b = """apply(f, args, kwds,)""" ++ a = """f(*args, **kwds)""" ++ self.check(b, a) ++ ++ # Test that complex functions are parenthesized ++ ++ def test_complex_1(self): ++ b = """x = apply(f+g, args)""" ++ a = """x = (f+g)(*args)""" ++ self.check(b, a) ++ ++ def test_complex_2(self): ++ b = """x = apply(f*g, args)""" ++ a = """x = (f*g)(*args)""" ++ self.check(b, a) ++ ++ def test_complex_3(self): ++ b = """x = apply(f**g, args)""" ++ a = """x = (f**g)(*args)""" ++ self.check(b, a) ++ ++ # But dotted names etc. not ++ ++ def test_dotted_name(self): ++ b = """x = apply(f.g, args)""" ++ a = """x = f.g(*args)""" ++ self.check(b, a) ++ ++ def test_subscript(self): ++ b = """x = apply(f[x], args)""" ++ a = """x = f[x](*args)""" ++ self.check(b, a) ++ ++ def test_call(self): ++ b = """x = apply(f(), args)""" ++ a = """x = f()(*args)""" ++ self.check(b, a) ++ ++ # Extreme case ++ def test_extreme(self): ++ b = """x = apply(a.b.c.d.e.f, args, kwds)""" ++ a = """x = a.b.c.d.e.f(*args, **kwds)""" ++ self.check(b, a) ++ ++ # XXX Comments in weird places still get lost ++ def test_weird_comments(self): ++ b = """apply( # foo ++ f, # bar ++ args)""" ++ a = """f(*args)""" ++ self.check(b, a) ++ ++ # These should *not* be touched ++ ++ def test_unchanged_1(self): ++ s = """apply()""" ++ self.unchanged(s) ++ ++ def test_unchanged_2(self): ++ s = """apply(f)""" ++ self.unchanged(s) ++ ++ def test_unchanged_3(self): ++ s = """apply(f,)""" ++ self.unchanged(s) ++ ++ def test_unchanged_4(self): ++ s = """apply(f, args, kwds, extras)""" ++ self.unchanged(s) ++ ++ def test_unchanged_5(self): ++ s = """apply(f, *args, **kwds)""" ++ self.unchanged(s) ++ ++ def test_unchanged_6(self): ++ s = """apply(f, *args)""" ++ self.unchanged(s) ++ ++ def test_unchanged_7(self): ++ s = """apply(func=f, args=args, kwds=kwds)""" ++ self.unchanged(s) ++ ++ def test_unchanged_8(self): ++ s = """apply(f, args=args, kwds=kwds)""" ++ self.unchanged(s) ++ ++ def test_unchanged_9(self): ++ s = """apply(f, args, kwds=kwds)""" ++ self.unchanged(s) ++ ++ def test_space_1(self): ++ a = """apply( f, args, kwds)""" ++ b = """f(*args, **kwds)""" ++ self.check(a, b) ++ ++ def test_space_2(self): ++ a = """apply( f ,args,kwds )""" ++ b = """f(*args, **kwds)""" ++ self.check(a, b) ++ ++class Test_intern(FixerTestCase): ++ fixer = "intern" ++ ++ def test_prefix_preservation(self): ++ b = """x = intern( a )""" ++ a = """import sys\nx = sys.intern( a )""" ++ self.check(b, a) ++ ++ b = """y = intern("b" # test ++ )""" ++ a = """import sys\ny = sys.intern("b" # test ++ )""" ++ self.check(b, a) ++ ++ b = """z = intern(a+b+c.d, )""" ++ a = """import sys\nz = sys.intern(a+b+c.d, )""" ++ self.check(b, a) ++ ++ def test(self): ++ b = """x = intern(a)""" ++ a = """import sys\nx = sys.intern(a)""" ++ self.check(b, a) ++ ++ b = """z = intern(a+b+c.d,)""" ++ a = """import sys\nz = sys.intern(a+b+c.d,)""" ++ self.check(b, a) ++ ++ b = """intern("y%s" % 5).replace("y", "")""" ++ a = """import sys\nsys.intern("y%s" % 5).replace("y", "")""" ++ self.check(b, a) ++ ++ # These should not be refactored ++ ++ def test_unchanged(self): ++ s = """intern(a=1)""" ++ self.unchanged(s) ++ ++ s = """intern(f, g)""" ++ self.unchanged(s) ++ ++ s = """intern(*h)""" ++ self.unchanged(s) ++ ++ s = """intern(**i)""" ++ self.unchanged(s) ++ ++ s = """intern()""" ++ self.unchanged(s) ++ ++class Test_reduce(FixerTestCase): ++ fixer = "reduce" ++ ++ def test_simple_call(self): ++ b = "reduce(a, b, c)" ++ a = "from functools import reduce\nreduce(a, b, c)" ++ self.check(b, a) ++ ++ def test_call_with_lambda(self): ++ b = "reduce(lambda x, y: x + y, seq)" ++ a = "from functools import reduce\nreduce(lambda x, y: x + y, seq)" ++ self.check(b, a) ++ ++ def test_unchanged(self): ++ s = "reduce(a)" ++ self.unchanged(s) ++ ++ s = "reduce(a, b=42)" ++ self.unchanged(s) ++ ++ s = "reduce(a, b, c, d)" ++ self.unchanged(s) ++ ++ s = "reduce(**c)" ++ self.unchanged(s) ++ ++ s = "reduce()" ++ self.unchanged(s) ++ ++class Test_print(FixerTestCase): ++ fixer = "print" ++ ++ def test_prefix_preservation(self): ++ b = """print 1, 1+1, 1+1+1""" ++ a = """print(1, 1+1, 1+1+1)""" ++ self.check(b, a) ++ ++ def test_idempotency(self): ++ s = """print()""" ++ self.unchanged(s) ++ ++ s = """print('')""" ++ self.unchanged(s) ++ ++ def test_idempotency_print_as_function(self): ++ print_stmt = pygram.python_grammar.keywords.pop("print") ++ try: ++ s = """print(1, 1+1, 1+1+1)""" ++ self.unchanged(s) ++ ++ s = """print()""" ++ self.unchanged(s) ++ ++ s = """print('')""" ++ self.unchanged(s) ++ finally: ++ pygram.python_grammar.keywords["print"] = print_stmt ++ ++ def test_1(self): ++ b = """print 1, 1+1, 1+1+1""" ++ a = """print(1, 1+1, 1+1+1)""" ++ self.check(b, a) ++ ++ def test_2(self): ++ b = """print 1, 2""" ++ a = """print(1, 2)""" ++ self.check(b, a) ++ ++ def test_3(self): ++ b = """print""" ++ a = """print()""" ++ self.check(b, a) ++ ++ def test_4(self): ++ # from bug 3000 ++ b = """print whatever; print""" ++ a = """print(whatever); print()""" ++ self.check(b, a) ++ ++ def test_5(self): ++ b = """print; print whatever;""" ++ a = """print(); print(whatever);""" ++ ++ def test_tuple(self): ++ b = """print (a, b, c)""" ++ a = """print((a, b, c))""" ++ self.check(b, a) ++ ++ # trailing commas ++ ++ def test_trailing_comma_1(self): ++ b = """print 1, 2, 3,""" ++ a = """print(1, 2, 3, end=' ')""" ++ self.check(b, a) ++ ++ def test_trailing_comma_2(self): ++ b = """print 1, 2,""" ++ a = """print(1, 2, end=' ')""" ++ self.check(b, a) ++ ++ def test_trailing_comma_3(self): ++ b = """print 1,""" ++ a = """print(1, end=' ')""" ++ self.check(b, a) ++ ++ # >> stuff ++ ++ def test_vargs_without_trailing_comma(self): ++ b = """print >>sys.stderr, 1, 2, 3""" ++ a = """print(1, 2, 3, file=sys.stderr)""" ++ self.check(b, a) ++ ++ def test_with_trailing_comma(self): ++ b = """print >>sys.stderr, 1, 2,""" ++ a = """print(1, 2, end=' ', file=sys.stderr)""" ++ self.check(b, a) ++ ++ def test_no_trailing_comma(self): ++ b = """print >>sys.stderr, 1+1""" ++ a = """print(1+1, file=sys.stderr)""" ++ self.check(b, a) ++ ++ def test_spaces_before_file(self): ++ b = """print >> sys.stderr""" ++ a = """print(file=sys.stderr)""" ++ self.check(b, a) ++ ++ # With from __future__ import print_function ++ def test_with_future_print_function(self): ++ # XXX: These tests won't actually do anything until the parser ++ # is fixed so it won't crash when it sees print(x=y). ++ # When #2412 is fixed, the try/except block can be taken ++ # out and the tests can be run like normal. ++ try: ++ s = "from __future__ import print_function\n"\ ++ "print('Hai!', end=' ')" ++ self.unchanged(s) ++ ++ b = "print 'Hello, world!'" ++ a = "print('Hello, world!')" ++ self.check(b, a) ++ ++ s = "from __future__ import *\n"\ ++ "print('Hai!', end=' ')" ++ self.unchanged(s) ++ except: ++ return ++ else: ++ self.assertFalse(True, "#2421 has been fixed -- printing tests "\ ++ "need to be updated!") ++ ++class Test_exec(FixerTestCase): ++ fixer = "exec" ++ ++ def test_prefix_preservation(self): ++ b = """ exec code in ns1, ns2""" ++ a = """ exec(code, ns1, ns2)""" ++ self.check(b, a) ++ ++ def test_basic(self): ++ b = """exec code""" ++ a = """exec(code)""" ++ self.check(b, a) ++ ++ def test_with_globals(self): ++ b = """exec code in ns""" ++ a = """exec(code, ns)""" ++ self.check(b, a) ++ ++ def test_with_globals_locals(self): ++ b = """exec code in ns1, ns2""" ++ a = """exec(code, ns1, ns2)""" ++ self.check(b, a) ++ ++ def test_complex_1(self): ++ b = """exec (a.b()) in ns""" ++ a = """exec((a.b()), ns)""" ++ self.check(b, a) ++ ++ def test_complex_2(self): ++ b = """exec a.b() + c in ns""" ++ a = """exec(a.b() + c, ns)""" ++ self.check(b, a) ++ ++ # These should not be touched ++ ++ def test_unchanged_1(self): ++ s = """exec(code)""" ++ self.unchanged(s) ++ ++ def test_unchanged_2(self): ++ s = """exec (code)""" ++ self.unchanged(s) ++ ++ def test_unchanged_3(self): ++ s = """exec(code, ns)""" ++ self.unchanged(s) ++ ++ def test_unchanged_4(self): ++ s = """exec(code, ns1, ns2)""" ++ self.unchanged(s) ++ ++class Test_repr(FixerTestCase): ++ fixer = "repr" ++ ++ def test_prefix_preservation(self): ++ b = """x = `1 + 2`""" ++ a = """x = repr(1 + 2)""" ++ self.check(b, a) ++ ++ def test_simple_1(self): ++ b = """x = `1 + 2`""" ++ a = """x = repr(1 + 2)""" ++ self.check(b, a) ++ ++ def test_simple_2(self): ++ b = """y = `x`""" ++ a = """y = repr(x)""" ++ self.check(b, a) ++ ++ def test_complex(self): ++ b = """z = `y`.__repr__()""" ++ a = """z = repr(y).__repr__()""" ++ self.check(b, a) ++ ++ def test_tuple(self): ++ b = """x = `1, 2, 3`""" ++ a = """x = repr((1, 2, 3))""" ++ self.check(b, a) ++ ++ def test_nested(self): ++ b = """x = `1 + `2``""" ++ a = """x = repr(1 + repr(2))""" ++ self.check(b, a) ++ ++ def test_nested_tuples(self): ++ b = """x = `1, 2 + `3, 4``""" ++ a = """x = repr((1, 2 + repr((3, 4))))""" ++ self.check(b, a) ++ ++class Test_except(FixerTestCase): ++ fixer = "except" ++ ++ def test_prefix_preservation(self): ++ b = """ ++ try: ++ pass ++ except (RuntimeError, ImportError), e: ++ pass""" ++ a = """ ++ try: ++ pass ++ except (RuntimeError, ImportError) as e: ++ pass""" ++ self.check(b, a) ++ ++ def test_simple(self): ++ b = """ ++ try: ++ pass ++ except Foo, e: ++ pass""" ++ a = """ ++ try: ++ pass ++ except Foo as e: ++ pass""" ++ self.check(b, a) ++ ++ def test_simple_no_space_before_target(self): ++ b = """ ++ try: ++ pass ++ except Foo,e: ++ pass""" ++ a = """ ++ try: ++ pass ++ except Foo as e: ++ pass""" ++ self.check(b, a) ++ ++ def test_tuple_unpack(self): ++ b = """ ++ def foo(): ++ try: ++ pass ++ except Exception, (f, e): ++ pass ++ except ImportError, e: ++ pass""" ++ ++ a = """ ++ def foo(): ++ try: ++ pass ++ except Exception as xxx_todo_changeme: ++ (f, e) = xxx_todo_changeme.args ++ pass ++ except ImportError as e: ++ pass""" ++ self.check(b, a) ++ ++ def test_multi_class(self): ++ b = """ ++ try: ++ pass ++ except (RuntimeError, ImportError), e: ++ pass""" ++ ++ a = """ ++ try: ++ pass ++ except (RuntimeError, ImportError) as e: ++ pass""" ++ self.check(b, a) ++ ++ def test_list_unpack(self): ++ b = """ ++ try: ++ pass ++ except Exception, [a, b]: ++ pass""" ++ ++ a = """ ++ try: ++ pass ++ except Exception as xxx_todo_changeme: ++ [a, b] = xxx_todo_changeme.args ++ pass""" ++ self.check(b, a) ++ ++ def test_weird_target_1(self): ++ b = """ ++ try: ++ pass ++ except Exception, d[5]: ++ pass""" ++ ++ a = """ ++ try: ++ pass ++ except Exception as xxx_todo_changeme: ++ d[5] = xxx_todo_changeme ++ pass""" ++ self.check(b, a) ++ ++ def test_weird_target_2(self): ++ b = """ ++ try: ++ pass ++ except Exception, a.foo: ++ pass""" ++ ++ a = """ ++ try: ++ pass ++ except Exception as xxx_todo_changeme: ++ a.foo = xxx_todo_changeme ++ pass""" ++ self.check(b, a) ++ ++ def test_weird_target_3(self): ++ b = """ ++ try: ++ pass ++ except Exception, a().foo: ++ pass""" ++ ++ a = """ ++ try: ++ pass ++ except Exception as xxx_todo_changeme: ++ a().foo = xxx_todo_changeme ++ pass""" ++ self.check(b, a) ++ ++ def test_bare_except(self): ++ b = """ ++ try: ++ pass ++ except Exception, a: ++ pass ++ except: ++ pass""" ++ ++ a = """ ++ try: ++ pass ++ except Exception as a: ++ pass ++ except: ++ pass""" ++ self.check(b, a) ++ ++ def test_bare_except_and_else_finally(self): ++ b = """ ++ try: ++ pass ++ except Exception, a: ++ pass ++ except: ++ pass ++ else: ++ pass ++ finally: ++ pass""" ++ ++ a = """ ++ try: ++ pass ++ except Exception as a: ++ pass ++ except: ++ pass ++ else: ++ pass ++ finally: ++ pass""" ++ self.check(b, a) ++ ++ def test_multi_fixed_excepts_before_bare_except(self): ++ b = """ ++ try: ++ pass ++ except TypeError, b: ++ pass ++ except Exception, a: ++ pass ++ except: ++ pass""" ++ ++ a = """ ++ try: ++ pass ++ except TypeError as b: ++ pass ++ except Exception as a: ++ pass ++ except: ++ pass""" ++ self.check(b, a) ++ ++ # These should not be touched: ++ ++ def test_unchanged_1(self): ++ s = """ ++ try: ++ pass ++ except: ++ pass""" ++ self.unchanged(s) ++ ++ def test_unchanged_2(self): ++ s = """ ++ try: ++ pass ++ except Exception: ++ pass""" ++ self.unchanged(s) ++ ++ def test_unchanged_3(self): ++ s = """ ++ try: ++ pass ++ except (Exception, SystemExit): ++ pass""" ++ self.unchanged(s) ++ ++class Test_raise(FixerTestCase): ++ fixer = "raise" ++ ++ def test_basic(self): ++ b = """raise Exception, 5""" ++ a = """raise Exception(5)""" ++ self.check(b, a) ++ ++ def test_prefix_preservation(self): ++ b = """raise Exception,5""" ++ a = """raise Exception(5)""" ++ self.check(b, a) ++ ++ b = """raise Exception, 5""" ++ a = """raise Exception(5)""" ++ self.check(b, a) ++ ++ def test_with_comments(self): ++ b = """raise Exception, 5 # foo""" ++ a = """raise Exception(5) # foo""" ++ self.check(b, a) ++ ++ b = """raise E, (5, 6) % (a, b) # foo""" ++ a = """raise E((5, 6) % (a, b)) # foo""" ++ self.check(b, a) ++ ++ b = """def foo(): ++ raise Exception, 5, 6 # foo""" ++ a = """def foo(): ++ raise Exception(5).with_traceback(6) # foo""" ++ self.check(b, a) ++ ++ def test_tuple_value(self): ++ b = """raise Exception, (5, 6, 7)""" ++ a = """raise Exception(5, 6, 7)""" ++ self.check(b, a) ++ ++ def test_tuple_detection(self): ++ b = """raise E, (5, 6) % (a, b)""" ++ a = """raise E((5, 6) % (a, b))""" ++ self.check(b, a) ++ ++ def test_tuple_exc_1(self): ++ b = """raise (((E1, E2), E3), E4), V""" ++ a = """raise E1(V)""" ++ self.check(b, a) ++ ++ def test_tuple_exc_2(self): ++ b = """raise (E1, (E2, E3), E4), V""" ++ a = """raise E1(V)""" ++ self.check(b, a) ++ ++ # These should produce a warning ++ ++ def test_string_exc(self): ++ s = """raise 'foo'""" ++ self.warns_unchanged(s, "Python 3 does not support string exceptions") ++ ++ def test_string_exc_val(self): ++ s = """raise "foo", 5""" ++ self.warns_unchanged(s, "Python 3 does not support string exceptions") ++ ++ def test_string_exc_val_tb(self): ++ s = """raise "foo", 5, 6""" ++ self.warns_unchanged(s, "Python 3 does not support string exceptions") ++ ++ # These should result in traceback-assignment ++ ++ def test_tb_1(self): ++ b = """def foo(): ++ raise Exception, 5, 6""" ++ a = """def foo(): ++ raise Exception(5).with_traceback(6)""" ++ self.check(b, a) ++ ++ def test_tb_2(self): ++ b = """def foo(): ++ a = 5 ++ raise Exception, 5, 6 ++ b = 6""" ++ a = """def foo(): ++ a = 5 ++ raise Exception(5).with_traceback(6) ++ b = 6""" ++ self.check(b, a) ++ ++ def test_tb_3(self): ++ b = """def foo(): ++ raise Exception,5,6""" ++ a = """def foo(): ++ raise Exception(5).with_traceback(6)""" ++ self.check(b, a) ++ ++ def test_tb_4(self): ++ b = """def foo(): ++ a = 5 ++ raise Exception,5,6 ++ b = 6""" ++ a = """def foo(): ++ a = 5 ++ raise Exception(5).with_traceback(6) ++ b = 6""" ++ self.check(b, a) ++ ++ def test_tb_5(self): ++ b = """def foo(): ++ raise Exception, (5, 6, 7), 6""" ++ a = """def foo(): ++ raise Exception(5, 6, 7).with_traceback(6)""" ++ self.check(b, a) ++ ++ def test_tb_6(self): ++ b = """def foo(): ++ a = 5 ++ raise Exception, (5, 6, 7), 6 ++ b = 6""" ++ a = """def foo(): ++ a = 5 ++ raise Exception(5, 6, 7).with_traceback(6) ++ b = 6""" ++ self.check(b, a) ++ ++class Test_throw(FixerTestCase): ++ fixer = "throw" ++ ++ def test_1(self): ++ b = """g.throw(Exception, 5)""" ++ a = """g.throw(Exception(5))""" ++ self.check(b, a) ++ ++ def test_2(self): ++ b = """g.throw(Exception,5)""" ++ a = """g.throw(Exception(5))""" ++ self.check(b, a) ++ ++ def test_3(self): ++ b = """g.throw(Exception, (5, 6, 7))""" ++ a = """g.throw(Exception(5, 6, 7))""" ++ self.check(b, a) ++ ++ def test_4(self): ++ b = """5 + g.throw(Exception, 5)""" ++ a = """5 + g.throw(Exception(5))""" ++ self.check(b, a) ++ ++ # These should produce warnings ++ ++ def test_warn_1(self): ++ s = """g.throw("foo")""" ++ self.warns_unchanged(s, "Python 3 does not support string exceptions") ++ ++ def test_warn_2(self): ++ s = """g.throw("foo", 5)""" ++ self.warns_unchanged(s, "Python 3 does not support string exceptions") ++ ++ def test_warn_3(self): ++ s = """g.throw("foo", 5, 6)""" ++ self.warns_unchanged(s, "Python 3 does not support string exceptions") ++ ++ # These should not be touched ++ ++ def test_untouched_1(self): ++ s = """g.throw(Exception)""" ++ self.unchanged(s) ++ ++ def test_untouched_2(self): ++ s = """g.throw(Exception(5, 6))""" ++ self.unchanged(s) ++ ++ def test_untouched_3(self): ++ s = """5 + g.throw(Exception(5, 6))""" ++ self.unchanged(s) ++ ++ # These should result in traceback-assignment ++ ++ def test_tb_1(self): ++ b = """def foo(): ++ g.throw(Exception, 5, 6)""" ++ a = """def foo(): ++ g.throw(Exception(5).with_traceback(6))""" ++ self.check(b, a) ++ ++ def test_tb_2(self): ++ b = """def foo(): ++ a = 5 ++ g.throw(Exception, 5, 6) ++ b = 6""" ++ a = """def foo(): ++ a = 5 ++ g.throw(Exception(5).with_traceback(6)) ++ b = 6""" ++ self.check(b, a) ++ ++ def test_tb_3(self): ++ b = """def foo(): ++ g.throw(Exception,5,6)""" ++ a = """def foo(): ++ g.throw(Exception(5).with_traceback(6))""" ++ self.check(b, a) ++ ++ def test_tb_4(self): ++ b = """def foo(): ++ a = 5 ++ g.throw(Exception,5,6) ++ b = 6""" ++ a = """def foo(): ++ a = 5 ++ g.throw(Exception(5).with_traceback(6)) ++ b = 6""" ++ self.check(b, a) ++ ++ def test_tb_5(self): ++ b = """def foo(): ++ g.throw(Exception, (5, 6, 7), 6)""" ++ a = """def foo(): ++ g.throw(Exception(5, 6, 7).with_traceback(6))""" ++ self.check(b, a) ++ ++ def test_tb_6(self): ++ b = """def foo(): ++ a = 5 ++ g.throw(Exception, (5, 6, 7), 6) ++ b = 6""" ++ a = """def foo(): ++ a = 5 ++ g.throw(Exception(5, 6, 7).with_traceback(6)) ++ b = 6""" ++ self.check(b, a) ++ ++ def test_tb_7(self): ++ b = """def foo(): ++ a + g.throw(Exception, 5, 6)""" ++ a = """def foo(): ++ a + g.throw(Exception(5).with_traceback(6))""" ++ self.check(b, a) ++ ++ def test_tb_8(self): ++ b = """def foo(): ++ a = 5 ++ a + g.throw(Exception, 5, 6) ++ b = 6""" ++ a = """def foo(): ++ a = 5 ++ a + g.throw(Exception(5).with_traceback(6)) ++ b = 6""" ++ self.check(b, a) ++ ++class Test_long(FixerTestCase): ++ fixer = "long" ++ ++ def test_1(self): ++ b = """x = long(x)""" ++ a = """x = int(x)""" ++ self.check(b, a) ++ ++ def test_2(self): ++ b = """y = isinstance(x, long)""" ++ a = """y = isinstance(x, int)""" ++ self.check(b, a) ++ ++ def test_3(self): ++ b = """z = type(x) in (int, long)""" ++ a = """z = type(x) in (int, int)""" ++ self.check(b, a) ++ ++ def test_unchanged(self): ++ s = """long = True""" ++ self.unchanged(s) ++ ++ s = """s.long = True""" ++ self.unchanged(s) ++ ++ s = """def long(): pass""" ++ self.unchanged(s) ++ ++ s = """class long(): pass""" ++ self.unchanged(s) ++ ++ s = """def f(long): pass""" ++ self.unchanged(s) ++ ++ s = """def f(g, long): pass""" ++ self.unchanged(s) ++ ++ s = """def f(x, long=True): pass""" ++ self.unchanged(s) ++ ++ def test_prefix_preservation(self): ++ b = """x = long( x )""" ++ a = """x = int( x )""" ++ self.check(b, a) ++ ++ ++class Test_execfile(FixerTestCase): ++ fixer = "execfile" ++ ++ def test_conversion(self): ++ b = """execfile("fn")""" ++ a = """exec(compile(open("fn").read(), "fn", 'exec'))""" ++ self.check(b, a) ++ ++ b = """execfile("fn", glob)""" ++ a = """exec(compile(open("fn").read(), "fn", 'exec'), glob)""" ++ self.check(b, a) ++ ++ b = """execfile("fn", glob, loc)""" ++ a = """exec(compile(open("fn").read(), "fn", 'exec'), glob, loc)""" ++ self.check(b, a) ++ ++ b = """execfile("fn", globals=glob)""" ++ a = """exec(compile(open("fn").read(), "fn", 'exec'), globals=glob)""" ++ self.check(b, a) ++ ++ b = """execfile("fn", locals=loc)""" ++ a = """exec(compile(open("fn").read(), "fn", 'exec'), locals=loc)""" ++ self.check(b, a) ++ ++ b = """execfile("fn", globals=glob, locals=loc)""" ++ a = """exec(compile(open("fn").read(), "fn", 'exec'), globals=glob, locals=loc)""" ++ self.check(b, a) ++ ++ def test_spacing(self): ++ b = """execfile( "fn" )""" ++ a = """exec(compile(open( "fn" ).read(), "fn", 'exec'))""" ++ self.check(b, a) ++ ++ b = """execfile("fn", globals = glob)""" ++ a = """exec(compile(open("fn").read(), "fn", 'exec'), globals = glob)""" ++ self.check(b, a) ++ ++ ++class Test_isinstance(FixerTestCase): ++ fixer = "isinstance" ++ ++ def test_remove_multiple_items(self): ++ b = """isinstance(x, (int, int, int))""" ++ a = """isinstance(x, int)""" ++ self.check(b, a) ++ ++ b = """isinstance(x, (int, float, int, int, float))""" ++ a = """isinstance(x, (int, float))""" ++ self.check(b, a) ++ ++ b = """isinstance(x, (int, float, int, int, float, str))""" ++ a = """isinstance(x, (int, float, str))""" ++ self.check(b, a) ++ ++ b = """isinstance(foo() + bar(), (x(), y(), x(), int, int))""" ++ a = """isinstance(foo() + bar(), (x(), y(), x(), int))""" ++ self.check(b, a) ++ ++ def test_prefix_preservation(self): ++ b = """if isinstance( foo(), ( bar, bar, baz )) : pass""" ++ a = """if isinstance( foo(), ( bar, baz )) : pass""" ++ self.check(b, a) ++ ++ def test_unchanged(self): ++ self.unchanged("isinstance(x, (str, int))") ++ ++class Test_dict(FixerTestCase): ++ fixer = "dict" ++ ++ def test_prefix_preservation(self): ++ b = "if d. keys ( ) : pass" ++ a = "if list(d. keys ( )) : pass" ++ self.check(b, a) ++ ++ b = "if d. items ( ) : pass" ++ a = "if list(d. items ( )) : pass" ++ self.check(b, a) ++ ++ b = "if d. iterkeys ( ) : pass" ++ a = "if iter(d. keys ( )) : pass" ++ self.check(b, a) ++ ++ b = "[i for i in d. iterkeys( ) ]" ++ a = "[i for i in d. keys( ) ]" ++ self.check(b, a) ++ ++ def test_trailing_comment(self): ++ b = "d.keys() # foo" ++ a = "list(d.keys()) # foo" ++ self.check(b, a) ++ ++ b = "d.items() # foo" ++ a = "list(d.items()) # foo" ++ self.check(b, a) ++ ++ b = "d.iterkeys() # foo" ++ a = "iter(d.keys()) # foo" ++ self.check(b, a) ++ ++ b = """[i for i in d.iterkeys() # foo ++ ]""" ++ a = """[i for i in d.keys() # foo ++ ]""" ++ self.check(b, a) ++ ++ def test_unchanged(self): ++ for wrapper in fixer_util.consuming_calls: ++ s = "s = %s(d.keys())" % wrapper ++ self.unchanged(s) ++ ++ s = "s = %s(d.values())" % wrapper ++ self.unchanged(s) ++ ++ s = "s = %s(d.items())" % wrapper ++ self.unchanged(s) ++ ++ def test_01(self): ++ b = "d.keys()" ++ a = "list(d.keys())" ++ self.check(b, a) ++ ++ b = "a[0].foo().keys()" ++ a = "list(a[0].foo().keys())" ++ self.check(b, a) ++ ++ def test_02(self): ++ b = "d.items()" ++ a = "list(d.items())" ++ self.check(b, a) ++ ++ def test_03(self): ++ b = "d.values()" ++ a = "list(d.values())" ++ self.check(b, a) ++ ++ def test_04(self): ++ b = "d.iterkeys()" ++ a = "iter(d.keys())" ++ self.check(b, a) ++ ++ def test_05(self): ++ b = "d.iteritems()" ++ a = "iter(d.items())" ++ self.check(b, a) ++ ++ def test_06(self): ++ b = "d.itervalues()" ++ a = "iter(d.values())" ++ self.check(b, a) ++ ++ def test_07(self): ++ s = "list(d.keys())" ++ self.unchanged(s) ++ ++ def test_08(self): ++ s = "sorted(d.keys())" ++ self.unchanged(s) ++ ++ def test_09(self): ++ b = "iter(d.keys())" ++ a = "iter(list(d.keys()))" ++ self.check(b, a) ++ ++ def test_10(self): ++ b = "foo(d.keys())" ++ a = "foo(list(d.keys()))" ++ self.check(b, a) ++ ++ def test_11(self): ++ b = "for i in d.keys(): print i" ++ a = "for i in list(d.keys()): print i" ++ self.check(b, a) ++ ++ def test_12(self): ++ b = "for i in d.iterkeys(): print i" ++ a = "for i in d.keys(): print i" ++ self.check(b, a) ++ ++ def test_13(self): ++ b = "[i for i in d.keys()]" ++ a = "[i for i in list(d.keys())]" ++ self.check(b, a) ++ ++ def test_14(self): ++ b = "[i for i in d.iterkeys()]" ++ a = "[i for i in d.keys()]" ++ self.check(b, a) ++ ++ def test_15(self): ++ b = "(i for i in d.keys())" ++ a = "(i for i in list(d.keys()))" ++ self.check(b, a) ++ ++ def test_16(self): ++ b = "(i for i in d.iterkeys())" ++ a = "(i for i in d.keys())" ++ self.check(b, a) ++ ++ def test_17(self): ++ b = "iter(d.iterkeys())" ++ a = "iter(d.keys())" ++ self.check(b, a) ++ ++ def test_18(self): ++ b = "list(d.iterkeys())" ++ a = "list(d.keys())" ++ self.check(b, a) ++ ++ def test_19(self): ++ b = "sorted(d.iterkeys())" ++ a = "sorted(d.keys())" ++ self.check(b, a) ++ ++ def test_20(self): ++ b = "foo(d.iterkeys())" ++ a = "foo(iter(d.keys()))" ++ self.check(b, a) ++ ++ def test_21(self): ++ b = "print h.iterkeys().next()" ++ a = "print iter(h.keys()).next()" ++ self.check(b, a) ++ ++ def test_22(self): ++ b = "print h.keys()[0]" ++ a = "print list(h.keys())[0]" ++ self.check(b, a) ++ ++ def test_23(self): ++ b = "print list(h.iterkeys().next())" ++ a = "print list(iter(h.keys()).next())" ++ self.check(b, a) ++ ++ def test_24(self): ++ b = "for x in h.keys()[0]: print x" ++ a = "for x in list(h.keys())[0]: print x" ++ self.check(b, a) ++ ++class Test_xrange(FixerTestCase): ++ fixer = "xrange" ++ ++ def test_prefix_preservation(self): ++ b = """x = xrange( 10 )""" ++ a = """x = range( 10 )""" ++ self.check(b, a) ++ ++ b = """x = xrange( 1 , 10 )""" ++ a = """x = range( 1 , 10 )""" ++ self.check(b, a) ++ ++ b = """x = xrange( 0 , 10 , 2 )""" ++ a = """x = range( 0 , 10 , 2 )""" ++ self.check(b, a) ++ ++ def test_single_arg(self): ++ b = """x = xrange(10)""" ++ a = """x = range(10)""" ++ self.check(b, a) ++ ++ def test_two_args(self): ++ b = """x = xrange(1, 10)""" ++ a = """x = range(1, 10)""" ++ self.check(b, a) ++ ++ def test_three_args(self): ++ b = """x = xrange(0, 10, 2)""" ++ a = """x = range(0, 10, 2)""" ++ self.check(b, a) ++ ++ def test_wrap_in_list(self): ++ b = """x = range(10, 3, 9)""" ++ a = """x = list(range(10, 3, 9))""" ++ self.check(b, a) ++ ++ b = """x = foo(range(10, 3, 9))""" ++ a = """x = foo(list(range(10, 3, 9)))""" ++ self.check(b, a) ++ ++ b = """x = range(10, 3, 9) + [4]""" ++ a = """x = list(range(10, 3, 9)) + [4]""" ++ self.check(b, a) ++ ++ b = """x = range(10)[::-1]""" ++ a = """x = list(range(10))[::-1]""" ++ self.check(b, a) ++ ++ b = """x = range(10) [3]""" ++ a = """x = list(range(10)) [3]""" ++ self.check(b, a) ++ ++ def test_xrange_in_for(self): ++ b = """for i in xrange(10):\n j=i""" ++ a = """for i in range(10):\n j=i""" ++ self.check(b, a) ++ ++ b = """[i for i in xrange(10)]""" ++ a = """[i for i in range(10)]""" ++ self.check(b, a) ++ ++ def test_range_in_for(self): ++ self.unchanged("for i in range(10): pass") ++ self.unchanged("[i for i in range(10)]") ++ ++ def test_in_contains_test(self): ++ self.unchanged("x in range(10, 3, 9)") ++ ++ def test_in_consuming_context(self): ++ for call in fixer_util.consuming_calls: ++ self.unchanged("a = %s(range(10))" % call) ++ ++class Test_raw_input(FixerTestCase): ++ fixer = "raw_input" ++ ++ def test_prefix_preservation(self): ++ b = """x = raw_input( )""" ++ a = """x = input( )""" ++ self.check(b, a) ++ ++ b = """x = raw_input( '' )""" ++ a = """x = input( '' )""" ++ self.check(b, a) ++ ++ def test_1(self): ++ b = """x = raw_input()""" ++ a = """x = input()""" ++ self.check(b, a) ++ ++ def test_2(self): ++ b = """x = raw_input('')""" ++ a = """x = input('')""" ++ self.check(b, a) ++ ++ def test_3(self): ++ b = """x = raw_input('prompt')""" ++ a = """x = input('prompt')""" ++ self.check(b, a) ++ ++ def test_4(self): ++ b = """x = raw_input(foo(a) + 6)""" ++ a = """x = input(foo(a) + 6)""" ++ self.check(b, a) ++ ++ def test_5(self): ++ b = """x = raw_input(invite).split()""" ++ a = """x = input(invite).split()""" ++ self.check(b, a) ++ ++ def test_6(self): ++ b = """x = raw_input(invite) . split ()""" ++ a = """x = input(invite) . split ()""" ++ self.check(b, a) ++ ++ def test_8(self): ++ b = "x = int(raw_input())" ++ a = "x = int(input())" ++ self.check(b, a) ++ ++class Test_funcattrs(FixerTestCase): ++ fixer = "funcattrs" ++ ++ attrs = ["closure", "doc", "name", "defaults", "code", "globals", "dict"] ++ ++ def test(self): ++ for attr in self.attrs: ++ b = "a.func_%s" % attr ++ a = "a.__%s__" % attr ++ self.check(b, a) ++ ++ b = "self.foo.func_%s.foo_bar" % attr ++ a = "self.foo.__%s__.foo_bar" % attr ++ self.check(b, a) ++ ++ def test_unchanged(self): ++ for attr in self.attrs: ++ s = "foo(func_%s + 5)" % attr ++ self.unchanged(s) ++ ++ s = "f(foo.__%s__)" % attr ++ self.unchanged(s) ++ ++ s = "f(foo.__%s__.foo)" % attr ++ self.unchanged(s) ++ ++class Test_xreadlines(FixerTestCase): ++ fixer = "xreadlines" ++ ++ def test_call(self): ++ b = "for x in f.xreadlines(): pass" ++ a = "for x in f: pass" ++ self.check(b, a) ++ ++ b = "for x in foo().xreadlines(): pass" ++ a = "for x in foo(): pass" ++ self.check(b, a) ++ ++ b = "for x in (5 + foo()).xreadlines(): pass" ++ a = "for x in (5 + foo()): pass" ++ self.check(b, a) ++ ++ def test_attr_ref(self): ++ b = "foo(f.xreadlines + 5)" ++ a = "foo(f.__iter__ + 5)" ++ self.check(b, a) ++ ++ b = "foo(f().xreadlines + 5)" ++ a = "foo(f().__iter__ + 5)" ++ self.check(b, a) ++ ++ b = "foo((5 + f()).xreadlines + 5)" ++ a = "foo((5 + f()).__iter__ + 5)" ++ self.check(b, a) ++ ++ def test_unchanged(self): ++ s = "for x in f.xreadlines(5): pass" ++ self.unchanged(s) ++ ++ s = "for x in f.xreadlines(k=5): pass" ++ self.unchanged(s) ++ ++ s = "for x in f.xreadlines(*k, **v): pass" ++ self.unchanged(s) ++ ++ s = "foo(xreadlines)" ++ self.unchanged(s) ++ ++ ++class ImportsFixerTests: ++ ++ def test_import_module(self): ++ for old, new in self.modules.items(): ++ b = "import %s" % old ++ a = "import %s" % new ++ self.check(b, a) ++ ++ b = "import foo, %s, bar" % old ++ a = "import foo, %s, bar" % new ++ self.check(b, a) ++ ++ def test_import_from(self): ++ for old, new in self.modules.items(): ++ b = "from %s import foo" % old ++ a = "from %s import foo" % new ++ self.check(b, a) ++ ++ b = "from %s import foo, bar" % old ++ a = "from %s import foo, bar" % new ++ self.check(b, a) ++ ++ b = "from %s import (yes, no)" % old ++ a = "from %s import (yes, no)" % new ++ self.check(b, a) ++ ++ def test_import_module_as(self): ++ for old, new in self.modules.items(): ++ b = "import %s as foo_bar" % old ++ a = "import %s as foo_bar" % new ++ self.check(b, a) ++ ++ b = "import %s as foo_bar" % old ++ a = "import %s as foo_bar" % new ++ self.check(b, a) ++ ++ def test_import_from_as(self): ++ for old, new in self.modules.items(): ++ b = "from %s import foo as bar" % old ++ a = "from %s import foo as bar" % new ++ self.check(b, a) ++ ++ def test_star(self): ++ for old, new in self.modules.items(): ++ b = "from %s import *" % old ++ a = "from %s import *" % new ++ self.check(b, a) ++ ++ def test_import_module_usage(self): ++ for old, new in self.modules.items(): ++ b = """ ++ import %s ++ foo(%s.bar) ++ """ % (old, old) ++ a = """ ++ import %s ++ foo(%s.bar) ++ """ % (new, new) ++ self.check(b, a) ++ ++ b = """ ++ from %s import x ++ %s = 23 ++ """ % (old, old) ++ a = """ ++ from %s import x ++ %s = 23 ++ """ % (new, old) ++ self.check(b, a) ++ ++ s = """ ++ def f(): ++ %s.method() ++ """ % (old,) ++ self.unchanged(s) ++ ++ # test nested usage ++ b = """ ++ import %s ++ %s.bar(%s.foo) ++ """ % (old, old, old) ++ a = """ ++ import %s ++ %s.bar(%s.foo) ++ """ % (new, new, new) ++ self.check(b, a) ++ ++ b = """ ++ import %s ++ x.%s ++ """ % (old, old) ++ a = """ ++ import %s ++ x.%s ++ """ % (new, old) ++ self.check(b, a) ++ ++ ++class Test_imports(FixerTestCase, ImportsFixerTests): ++ fixer = "imports" ++ from ..fixes.fix_imports import MAPPING as modules ++ ++ def test_multiple_imports(self): ++ b = """import urlparse, cStringIO""" ++ a = """import urllib.parse, io""" ++ self.check(b, a) ++ ++ def test_multiple_imports_as(self): ++ b = """ ++ import copy_reg as bar, HTMLParser as foo, urlparse ++ s = urlparse.spam(bar.foo()) ++ """ ++ a = """ ++ import copyreg as bar, html.parser as foo, urllib.parse ++ s = urllib.parse.spam(bar.foo()) ++ """ ++ self.check(b, a) ++ ++ ++class Test_imports2(FixerTestCase, ImportsFixerTests): ++ fixer = "imports2" ++ from ..fixes.fix_imports2 import MAPPING as modules ++ ++ ++class Test_imports_fixer_order(FixerTestCase, ImportsFixerTests): ++ ++ def setUp(self): ++ super(Test_imports_fixer_order, self).setUp(['imports', 'imports2']) ++ from ..fixes.fix_imports2 import MAPPING as mapping2 ++ self.modules = mapping2.copy() ++ from ..fixes.fix_imports import MAPPING as mapping1 ++ for key in ('dbhash', 'dumbdbm', 'dbm', 'gdbm'): ++ self.modules[key] = mapping1[key] ++ ++ ++class Test_urllib(FixerTestCase): ++ fixer = "urllib" ++ from ..fixes.fix_urllib import MAPPING as modules ++ ++ def test_import_module(self): ++ for old, changes in self.modules.items(): ++ b = "import %s" % old ++ a = "import %s" % ", ".join(map(itemgetter(0), changes)) ++ self.check(b, a) ++ ++ def test_import_from(self): ++ for old, changes in self.modules.items(): ++ all_members = [] ++ for new, members in changes: ++ for member in members: ++ all_members.append(member) ++ b = "from %s import %s" % (old, member) ++ a = "from %s import %s" % (new, member) ++ self.check(b, a) ++ ++ s = "from foo import %s" % member ++ self.unchanged(s) ++ ++ b = "from %s import %s" % (old, ", ".join(members)) ++ a = "from %s import %s" % (new, ", ".join(members)) ++ self.check(b, a) ++ ++ s = "from foo import %s" % ", ".join(members) ++ self.unchanged(s) ++ ++ # test the breaking of a module into multiple replacements ++ b = "from %s import %s" % (old, ", ".join(all_members)) ++ a = "\n".join(["from %s import %s" % (new, ", ".join(members)) ++ for (new, members) in changes]) ++ self.check(b, a) ++ ++ def test_import_module_as(self): ++ for old in self.modules: ++ s = "import %s as foo" % old ++ self.warns_unchanged(s, "This module is now multiple modules") ++ ++ def test_import_from_as(self): ++ for old, changes in self.modules.items(): ++ for new, members in changes: ++ for member in members: ++ b = "from %s import %s as foo_bar" % (old, member) ++ a = "from %s import %s as foo_bar" % (new, member) ++ self.check(b, a) ++ ++ def test_star(self): ++ for old in self.modules: ++ s = "from %s import *" % old ++ self.warns_unchanged(s, "Cannot handle star imports") ++ ++ def test_import_module_usage(self): ++ for old, changes in self.modules.items(): ++ for new, members in changes: ++ for member in members: ++ b = """ ++ import %s ++ foo(%s.%s) ++ """ % (old, old, member) ++ a = """ ++ import %s ++ foo(%s.%s) ++ """ % (", ".join([n for (n, mems) ++ in self.modules[old]]), ++ new, member) ++ self.check(b, a) ++ ++ ++class Test_input(FixerTestCase): ++ fixer = "input" ++ ++ def test_prefix_preservation(self): ++ b = """x = input( )""" ++ a = """x = eval(input( ))""" ++ self.check(b, a) ++ ++ b = """x = input( '' )""" ++ a = """x = eval(input( '' ))""" ++ self.check(b, a) ++ ++ def test_trailing_comment(self): ++ b = """x = input() # foo""" ++ a = """x = eval(input()) # foo""" ++ self.check(b, a) ++ ++ def test_idempotency(self): ++ s = """x = eval(input())""" ++ self.unchanged(s) ++ ++ s = """x = eval(input(''))""" ++ self.unchanged(s) ++ ++ s = """x = eval(input(foo(5) + 9))""" ++ self.unchanged(s) ++ ++ def test_1(self): ++ b = """x = input()""" ++ a = """x = eval(input())""" ++ self.check(b, a) ++ ++ def test_2(self): ++ b = """x = input('')""" ++ a = """x = eval(input(''))""" ++ self.check(b, a) ++ ++ def test_3(self): ++ b = """x = input('prompt')""" ++ a = """x = eval(input('prompt'))""" ++ self.check(b, a) ++ ++ def test_4(self): ++ b = """x = input(foo(5) + 9)""" ++ a = """x = eval(input(foo(5) + 9))""" ++ self.check(b, a) ++ ++class Test_tuple_params(FixerTestCase): ++ fixer = "tuple_params" ++ ++ def test_unchanged_1(self): ++ s = """def foo(): pass""" ++ self.unchanged(s) ++ ++ def test_unchanged_2(self): ++ s = """def foo(a, b, c): pass""" ++ self.unchanged(s) ++ ++ def test_unchanged_3(self): ++ s = """def foo(a=3, b=4, c=5): pass""" ++ self.unchanged(s) ++ ++ def test_1(self): ++ b = """ ++ def foo(((a, b), c)): ++ x = 5""" ++ ++ a = """ ++ def foo(xxx_todo_changeme): ++ ((a, b), c) = xxx_todo_changeme ++ x = 5""" ++ self.check(b, a) ++ ++ def test_2(self): ++ b = """ ++ def foo(((a, b), c), d): ++ x = 5""" ++ ++ a = """ ++ def foo(xxx_todo_changeme, d): ++ ((a, b), c) = xxx_todo_changeme ++ x = 5""" ++ self.check(b, a) ++ ++ def test_3(self): ++ b = """ ++ def foo(((a, b), c), d) -> e: ++ x = 5""" ++ ++ a = """ ++ def foo(xxx_todo_changeme, d) -> e: ++ ((a, b), c) = xxx_todo_changeme ++ x = 5""" ++ self.check(b, a) ++ ++ def test_semicolon(self): ++ b = """ ++ def foo(((a, b), c)): x = 5; y = 7""" ++ ++ a = """ ++ def foo(xxx_todo_changeme): ((a, b), c) = xxx_todo_changeme; x = 5; y = 7""" ++ self.check(b, a) ++ ++ def test_keywords(self): ++ b = """ ++ def foo(((a, b), c), d, e=5) -> z: ++ x = 5""" ++ ++ a = """ ++ def foo(xxx_todo_changeme, d, e=5) -> z: ++ ((a, b), c) = xxx_todo_changeme ++ x = 5""" ++ self.check(b, a) ++ ++ def test_varargs(self): ++ b = """ ++ def foo(((a, b), c), d, *vargs, **kwargs) -> z: ++ x = 5""" ++ ++ a = """ ++ def foo(xxx_todo_changeme, d, *vargs, **kwargs) -> z: ++ ((a, b), c) = xxx_todo_changeme ++ x = 5""" ++ self.check(b, a) ++ ++ def test_multi_1(self): ++ b = """ ++ def foo(((a, b), c), (d, e, f)) -> z: ++ x = 5""" ++ ++ a = """ ++ def foo(xxx_todo_changeme, xxx_todo_changeme1) -> z: ++ ((a, b), c) = xxx_todo_changeme ++ (d, e, f) = xxx_todo_changeme1 ++ x = 5""" ++ self.check(b, a) ++ ++ def test_multi_2(self): ++ b = """ ++ def foo(x, ((a, b), c), d, (e, f, g), y) -> z: ++ x = 5""" ++ ++ a = """ ++ def foo(x, xxx_todo_changeme, d, xxx_todo_changeme1, y) -> z: ++ ((a, b), c) = xxx_todo_changeme ++ (e, f, g) = xxx_todo_changeme1 ++ x = 5""" ++ self.check(b, a) ++ ++ def test_docstring(self): ++ b = """ ++ def foo(((a, b), c), (d, e, f)) -> z: ++ "foo foo foo foo" ++ x = 5""" ++ ++ a = """ ++ def foo(xxx_todo_changeme, xxx_todo_changeme1) -> z: ++ "foo foo foo foo" ++ ((a, b), c) = xxx_todo_changeme ++ (d, e, f) = xxx_todo_changeme1 ++ x = 5""" ++ self.check(b, a) ++ ++ def test_lambda_no_change(self): ++ s = """lambda x: x + 5""" ++ self.unchanged(s) ++ ++ def test_lambda_parens_single_arg(self): ++ b = """lambda (x): x + 5""" ++ a = """lambda x: x + 5""" ++ self.check(b, a) ++ ++ b = """lambda(x): x + 5""" ++ a = """lambda x: x + 5""" ++ self.check(b, a) ++ ++ b = """lambda ((((x)))): x + 5""" ++ a = """lambda x: x + 5""" ++ self.check(b, a) ++ ++ b = """lambda((((x)))): x + 5""" ++ a = """lambda x: x + 5""" ++ self.check(b, a) ++ ++ def test_lambda_simple(self): ++ b = """lambda (x, y): x + f(y)""" ++ a = """lambda x_y: x_y[0] + f(x_y[1])""" ++ self.check(b, a) ++ ++ b = """lambda(x, y): x + f(y)""" ++ a = """lambda x_y: x_y[0] + f(x_y[1])""" ++ self.check(b, a) ++ ++ b = """lambda (((x, y))): x + f(y)""" ++ a = """lambda x_y: x_y[0] + f(x_y[1])""" ++ self.check(b, a) ++ ++ b = """lambda(((x, y))): x + f(y)""" ++ a = """lambda x_y: x_y[0] + f(x_y[1])""" ++ self.check(b, a) ++ ++ def test_lambda_one_tuple(self): ++ b = """lambda (x,): x + f(x)""" ++ a = """lambda x1: x1[0] + f(x1[0])""" ++ self.check(b, a) ++ ++ b = """lambda (((x,))): x + f(x)""" ++ a = """lambda x1: x1[0] + f(x1[0])""" ++ self.check(b, a) ++ ++ def test_lambda_simple_multi_use(self): ++ b = """lambda (x, y): x + x + f(x) + x""" ++ a = """lambda x_y: x_y[0] + x_y[0] + f(x_y[0]) + x_y[0]""" ++ self.check(b, a) ++ ++ def test_lambda_simple_reverse(self): ++ b = """lambda (x, y): y + x""" ++ a = """lambda x_y: x_y[1] + x_y[0]""" ++ self.check(b, a) ++ ++ def test_lambda_nested(self): ++ b = """lambda (x, (y, z)): x + y + z""" ++ a = """lambda x_y_z: x_y_z[0] + x_y_z[1][0] + x_y_z[1][1]""" ++ self.check(b, a) ++ ++ b = """lambda (((x, (y, z)))): x + y + z""" ++ a = """lambda x_y_z: x_y_z[0] + x_y_z[1][0] + x_y_z[1][1]""" ++ self.check(b, a) ++ ++ def test_lambda_nested_multi_use(self): ++ b = """lambda (x, (y, z)): x + y + f(y)""" ++ a = """lambda x_y_z: x_y_z[0] + x_y_z[1][0] + f(x_y_z[1][0])""" ++ self.check(b, a) ++ ++class Test_methodattrs(FixerTestCase): ++ fixer = "methodattrs" ++ ++ attrs = ["func", "self", "class"] ++ ++ def test(self): ++ for attr in self.attrs: ++ b = "a.im_%s" % attr ++ if attr == "class": ++ a = "a.__self__.__class__" ++ else: ++ a = "a.__%s__" % attr ++ self.check(b, a) ++ ++ b = "self.foo.im_%s.foo_bar" % attr ++ if attr == "class": ++ a = "self.foo.__self__.__class__.foo_bar" ++ else: ++ a = "self.foo.__%s__.foo_bar" % attr ++ self.check(b, a) ++ ++ def test_unchanged(self): ++ for attr in self.attrs: ++ s = "foo(im_%s + 5)" % attr ++ self.unchanged(s) ++ ++ s = "f(foo.__%s__)" % attr ++ self.unchanged(s) ++ ++ s = "f(foo.__%s__.foo)" % attr ++ self.unchanged(s) ++ ++class Test_next(FixerTestCase): ++ fixer = "next" ++ ++ def test_1(self): ++ b = """it.next()""" ++ a = """next(it)""" ++ self.check(b, a) ++ ++ def test_2(self): ++ b = """a.b.c.d.next()""" ++ a = """next(a.b.c.d)""" ++ self.check(b, a) ++ ++ def test_3(self): ++ b = """(a + b).next()""" ++ a = """next((a + b))""" ++ self.check(b, a) ++ ++ def test_4(self): ++ b = """a().next()""" ++ a = """next(a())""" ++ self.check(b, a) ++ ++ def test_5(self): ++ b = """a().next() + b""" ++ a = """next(a()) + b""" ++ self.check(b, a) ++ ++ def test_6(self): ++ b = """c( a().next() + b)""" ++ a = """c( next(a()) + b)""" ++ self.check(b, a) ++ ++ def test_prefix_preservation_1(self): ++ b = """ ++ for a in b: ++ foo(a) ++ a.next() ++ """ ++ a = """ ++ for a in b: ++ foo(a) ++ next(a) ++ """ ++ self.check(b, a) ++ ++ def test_prefix_preservation_2(self): ++ b = """ ++ for a in b: ++ foo(a) # abc ++ # def ++ a.next() ++ """ ++ a = """ ++ for a in b: ++ foo(a) # abc ++ # def ++ next(a) ++ """ ++ self.check(b, a) ++ ++ def test_prefix_preservation_3(self): ++ b = """ ++ next = 5 ++ for a in b: ++ foo(a) ++ a.next() ++ """ ++ a = """ ++ next = 5 ++ for a in b: ++ foo(a) ++ a.__next__() ++ """ ++ self.check(b, a, ignore_warnings=True) ++ ++ def test_prefix_preservation_4(self): ++ b = """ ++ next = 5 ++ for a in b: ++ foo(a) # abc ++ # def ++ a.next() ++ """ ++ a = """ ++ next = 5 ++ for a in b: ++ foo(a) # abc ++ # def ++ a.__next__() ++ """ ++ self.check(b, a, ignore_warnings=True) ++ ++ def test_prefix_preservation_5(self): ++ b = """ ++ next = 5 ++ for a in b: ++ foo(foo(a), # abc ++ a.next()) ++ """ ++ a = """ ++ next = 5 ++ for a in b: ++ foo(foo(a), # abc ++ a.__next__()) ++ """ ++ self.check(b, a, ignore_warnings=True) ++ ++ def test_prefix_preservation_6(self): ++ b = """ ++ for a in b: ++ foo(foo(a), # abc ++ a.next()) ++ """ ++ a = """ ++ for a in b: ++ foo(foo(a), # abc ++ next(a)) ++ """ ++ self.check(b, a) ++ ++ def test_method_1(self): ++ b = """ ++ class A: ++ def next(self): ++ pass ++ """ ++ a = """ ++ class A: ++ def __next__(self): ++ pass ++ """ ++ self.check(b, a) ++ ++ def test_method_2(self): ++ b = """ ++ class A(object): ++ def next(self): ++ pass ++ """ ++ a = """ ++ class A(object): ++ def __next__(self): ++ pass ++ """ ++ self.check(b, a) ++ ++ def test_method_3(self): ++ b = """ ++ class A: ++ def next(x): ++ pass ++ """ ++ a = """ ++ class A: ++ def __next__(x): ++ pass ++ """ ++ self.check(b, a) ++ ++ def test_method_4(self): ++ b = """ ++ class A: ++ def __init__(self, foo): ++ self.foo = foo ++ ++ def next(self): ++ pass ++ ++ def __iter__(self): ++ return self ++ """ ++ a = """ ++ class A: ++ def __init__(self, foo): ++ self.foo = foo ++ ++ def __next__(self): ++ pass ++ ++ def __iter__(self): ++ return self ++ """ ++ self.check(b, a) ++ ++ def test_method_unchanged(self): ++ s = """ ++ class A: ++ def next(self, a, b): ++ pass ++ """ ++ self.unchanged(s) ++ ++ def test_shadowing_assign_simple(self): ++ s = """ ++ next = foo ++ ++ class A: ++ def next(self, a, b): ++ pass ++ """ ++ self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") ++ ++ def test_shadowing_assign_tuple_1(self): ++ s = """ ++ (next, a) = foo ++ ++ class A: ++ def next(self, a, b): ++ pass ++ """ ++ self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") ++ ++ def test_shadowing_assign_tuple_2(self): ++ s = """ ++ (a, (b, (next, c)), a) = foo ++ ++ class A: ++ def next(self, a, b): ++ pass ++ """ ++ self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") ++ ++ def test_shadowing_assign_list_1(self): ++ s = """ ++ [next, a] = foo ++ ++ class A: ++ def next(self, a, b): ++ pass ++ """ ++ self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") ++ ++ def test_shadowing_assign_list_2(self): ++ s = """ ++ [a, [b, [next, c]], a] = foo ++ ++ class A: ++ def next(self, a, b): ++ pass ++ """ ++ self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") ++ ++ def test_builtin_assign(self): ++ s = """ ++ def foo(): ++ __builtin__.next = foo ++ ++ class A: ++ def next(self, a, b): ++ pass ++ """ ++ self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") ++ ++ def test_builtin_assign_in_tuple(self): ++ s = """ ++ def foo(): ++ (a, __builtin__.next) = foo ++ ++ class A: ++ def next(self, a, b): ++ pass ++ """ ++ self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") ++ ++ def test_builtin_assign_in_list(self): ++ s = """ ++ def foo(): ++ [a, __builtin__.next] = foo ++ ++ class A: ++ def next(self, a, b): ++ pass ++ """ ++ self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") ++ ++ def test_assign_to_next(self): ++ s = """ ++ def foo(): ++ A.next = foo ++ ++ class A: ++ def next(self, a, b): ++ pass ++ """ ++ self.unchanged(s) ++ ++ def test_assign_to_next_in_tuple(self): ++ s = """ ++ def foo(): ++ (a, A.next) = foo ++ ++ class A: ++ def next(self, a, b): ++ pass ++ """ ++ self.unchanged(s) ++ ++ def test_assign_to_next_in_list(self): ++ s = """ ++ def foo(): ++ [a, A.next] = foo ++ ++ class A: ++ def next(self, a, b): ++ pass ++ """ ++ self.unchanged(s) ++ ++ def test_shadowing_import_1(self): ++ s = """ ++ import foo.bar as next ++ ++ class A: ++ def next(self, a, b): ++ pass ++ """ ++ self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") ++ ++ def test_shadowing_import_2(self): ++ s = """ ++ import bar, bar.foo as next ++ ++ class A: ++ def next(self, a, b): ++ pass ++ """ ++ self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") ++ ++ def test_shadowing_import_3(self): ++ s = """ ++ import bar, bar.foo as next, baz ++ ++ class A: ++ def next(self, a, b): ++ pass ++ """ ++ self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") ++ ++ def test_shadowing_import_from_1(self): ++ s = """ ++ from x import next ++ ++ class A: ++ def next(self, a, b): ++ pass ++ """ ++ self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") ++ ++ def test_shadowing_import_from_2(self): ++ s = """ ++ from x.a import next ++ ++ class A: ++ def next(self, a, b): ++ pass ++ """ ++ self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") ++ ++ def test_shadowing_import_from_3(self): ++ s = """ ++ from x import a, next, b ++ ++ class A: ++ def next(self, a, b): ++ pass ++ """ ++ self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") ++ ++ def test_shadowing_import_from_4(self): ++ s = """ ++ from x.a import a, next, b ++ ++ class A: ++ def next(self, a, b): ++ pass ++ """ ++ self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") ++ ++ def test_shadowing_funcdef_1(self): ++ s = """ ++ def next(a): ++ pass ++ ++ class A: ++ def next(self, a, b): ++ pass ++ """ ++ self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") ++ ++ def test_shadowing_funcdef_2(self): ++ b = """ ++ def next(a): ++ pass ++ ++ class A: ++ def next(self): ++ pass ++ ++ it.next() ++ """ ++ a = """ ++ def next(a): ++ pass ++ ++ class A: ++ def __next__(self): ++ pass ++ ++ it.__next__() ++ """ ++ self.warns(b, a, "Calls to builtin next() possibly shadowed") ++ ++ def test_shadowing_global_1(self): ++ s = """ ++ def f(): ++ global next ++ next = 5 ++ """ ++ self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") ++ ++ def test_shadowing_global_2(self): ++ s = """ ++ def f(): ++ global a, next, b ++ next = 5 ++ """ ++ self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") ++ ++ def test_shadowing_for_simple(self): ++ s = """ ++ for next in it(): ++ pass ++ ++ b = 5 ++ c = 6 ++ """ ++ self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") ++ ++ def test_shadowing_for_tuple_1(self): ++ s = """ ++ for next, b in it(): ++ pass ++ ++ b = 5 ++ c = 6 ++ """ ++ self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") ++ ++ def test_shadowing_for_tuple_2(self): ++ s = """ ++ for a, (next, c), b in it(): ++ pass ++ ++ b = 5 ++ c = 6 ++ """ ++ self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") ++ ++ def test_noncall_access_1(self): ++ b = """gnext = g.next""" ++ a = """gnext = g.__next__""" ++ self.check(b, a) ++ ++ def test_noncall_access_2(self): ++ b = """f(g.next + 5)""" ++ a = """f(g.__next__ + 5)""" ++ self.check(b, a) ++ ++ def test_noncall_access_3(self): ++ b = """f(g().next + 5)""" ++ a = """f(g().__next__ + 5)""" ++ self.check(b, a) ++ ++class Test_nonzero(FixerTestCase): ++ fixer = "nonzero" ++ ++ def test_1(self): ++ b = """ ++ class A: ++ def __nonzero__(self): ++ pass ++ """ ++ a = """ ++ class A: ++ def __bool__(self): ++ pass ++ """ ++ self.check(b, a) ++ ++ def test_2(self): ++ b = """ ++ class A(object): ++ def __nonzero__(self): ++ pass ++ """ ++ a = """ ++ class A(object): ++ def __bool__(self): ++ pass ++ """ ++ self.check(b, a) ++ ++ def test_unchanged_1(self): ++ s = """ ++ class A(object): ++ def __bool__(self): ++ pass ++ """ ++ self.unchanged(s) ++ ++ def test_unchanged_2(self): ++ s = """ ++ class A(object): ++ def __nonzero__(self, a): ++ pass ++ """ ++ self.unchanged(s) ++ ++ def test_unchanged_func(self): ++ s = """ ++ def __nonzero__(self): ++ pass ++ """ ++ self.unchanged(s) ++ ++class Test_numliterals(FixerTestCase): ++ fixer = "numliterals" ++ ++ def test_octal_1(self): ++ b = """0755""" ++ a = """0o755""" ++ self.check(b, a) ++ ++ def test_long_int_1(self): ++ b = """a = 12L""" ++ a = """a = 12""" ++ self.check(b, a) ++ ++ def test_long_int_2(self): ++ b = """a = 12l""" ++ a = """a = 12""" ++ self.check(b, a) ++ ++ def test_long_hex(self): ++ b = """b = 0x12l""" ++ a = """b = 0x12""" ++ self.check(b, a) ++ ++ def test_comments_and_spacing(self): ++ b = """b = 0x12L""" ++ a = """b = 0x12""" ++ self.check(b, a) ++ ++ b = """b = 0755 # spam""" ++ a = """b = 0o755 # spam""" ++ self.check(b, a) ++ ++ def test_unchanged_int(self): ++ s = """5""" ++ self.unchanged(s) ++ ++ def test_unchanged_float(self): ++ s = """5.0""" ++ self.unchanged(s) ++ ++ def test_unchanged_octal(self): ++ s = """0o755""" ++ self.unchanged(s) ++ ++ def test_unchanged_hex(self): ++ s = """0xABC""" ++ self.unchanged(s) ++ ++ def test_unchanged_exp(self): ++ s = """5.0e10""" ++ self.unchanged(s) ++ ++ def test_unchanged_complex_int(self): ++ s = """5 + 4j""" ++ self.unchanged(s) ++ ++ def test_unchanged_complex_float(self): ++ s = """5.4 + 4.9j""" ++ self.unchanged(s) ++ ++ def test_unchanged_complex_bare(self): ++ s = """4j""" ++ self.unchanged(s) ++ s = """4.4j""" ++ self.unchanged(s) ++ ++class Test_renames(FixerTestCase): ++ fixer = "renames" ++ ++ modules = {"sys": ("maxint", "maxsize"), ++ } ++ ++ def test_import_from(self): ++ for mod, (old, new) in self.modules.items(): ++ b = "from %s import %s" % (mod, old) ++ a = "from %s import %s" % (mod, new) ++ self.check(b, a) ++ ++ s = "from foo import %s" % old ++ self.unchanged(s) ++ ++ def test_import_from_as(self): ++ for mod, (old, new) in self.modules.items(): ++ b = "from %s import %s as foo_bar" % (mod, old) ++ a = "from %s import %s as foo_bar" % (mod, new) ++ self.check(b, a) ++ ++ def test_import_module_usage(self): ++ for mod, (old, new) in self.modules.items(): ++ b = """ ++ import %s ++ foo(%s, %s.%s) ++ """ % (mod, mod, mod, old) ++ a = """ ++ import %s ++ foo(%s, %s.%s) ++ """ % (mod, mod, mod, new) ++ self.check(b, a) ++ ++ def XXX_test_from_import_usage(self): ++ # not implemented yet ++ for mod, (old, new) in self.modules.items(): ++ b = """ ++ from %s import %s ++ foo(%s, %s) ++ """ % (mod, old, mod, old) ++ a = """ ++ from %s import %s ++ foo(%s, %s) ++ """ % (mod, new, mod, new) ++ self.check(b, a) ++ ++class Test_unicode(FixerTestCase): ++ fixer = "unicode" ++ ++ def test_unicode_call(self): ++ b = """unicode(x, y, z)""" ++ a = """str(x, y, z)""" ++ self.check(b, a) ++ ++ def test_unicode_literal_1(self): ++ b = '''u"x"''' ++ a = '''"x"''' ++ self.check(b, a) ++ ++ def test_unicode_literal_2(self): ++ b = """ur'x'""" ++ a = """r'x'""" ++ self.check(b, a) ++ ++ def test_unicode_literal_3(self): ++ b = """UR'''x'''""" ++ a = """R'''x'''""" ++ self.check(b, a) ++ ++class Test_callable(FixerTestCase): ++ fixer = "callable" ++ ++ def test_prefix_preservation(self): ++ b = """callable( x)""" ++ a = """hasattr( x, '__call__')""" ++ self.check(b, a) ++ ++ b = """if callable(x): pass""" ++ a = """if hasattr(x, '__call__'): pass""" ++ self.check(b, a) ++ ++ def test_callable_call(self): ++ b = """callable(x)""" ++ a = """hasattr(x, '__call__')""" ++ self.check(b, a) ++ ++ def test_callable_should_not_change(self): ++ a = """callable(*x)""" ++ self.unchanged(a) ++ ++ a = """callable(x, y)""" ++ self.unchanged(a) ++ ++ a = """callable(x, kw=y)""" ++ self.unchanged(a) ++ ++ a = """callable()""" ++ self.unchanged(a) ++ ++class Test_filter(FixerTestCase): ++ fixer = "filter" ++ ++ def test_prefix_preservation(self): ++ b = """x = filter( foo, 'abc' )""" ++ a = """x = list(filter( foo, 'abc' ))""" ++ self.check(b, a) ++ ++ b = """x = filter( None , 'abc' )""" ++ a = """x = [_f for _f in 'abc' if _f]""" ++ self.check(b, a) ++ ++ def test_filter_basic(self): ++ b = """x = filter(None, 'abc')""" ++ a = """x = [_f for _f in 'abc' if _f]""" ++ self.check(b, a) ++ ++ b = """x = len(filter(f, 'abc'))""" ++ a = """x = len(list(filter(f, 'abc')))""" ++ self.check(b, a) ++ ++ b = """x = filter(lambda x: x%2 == 0, range(10))""" ++ a = """x = [x for x in range(10) if x%2 == 0]""" ++ self.check(b, a) ++ ++ # Note the parens around x ++ b = """x = filter(lambda (x): x%2 == 0, range(10))""" ++ a = """x = [x for x in range(10) if x%2 == 0]""" ++ self.check(b, a) ++ ++ # XXX This (rare) case is not supported ++## b = """x = filter(f, 'abc')[0]""" ++## a = """x = list(filter(f, 'abc'))[0]""" ++## self.check(b, a) ++ ++ def test_filter_nochange(self): ++ a = """b.join(filter(f, 'abc'))""" ++ self.unchanged(a) ++ a = """(a + foo(5)).join(filter(f, 'abc'))""" ++ self.unchanged(a) ++ a = """iter(filter(f, 'abc'))""" ++ self.unchanged(a) ++ a = """list(filter(f, 'abc'))""" ++ self.unchanged(a) ++ a = """list(filter(f, 'abc'))[0]""" ++ self.unchanged(a) ++ a = """set(filter(f, 'abc'))""" ++ self.unchanged(a) ++ a = """set(filter(f, 'abc')).pop()""" ++ self.unchanged(a) ++ a = """tuple(filter(f, 'abc'))""" ++ self.unchanged(a) ++ a = """any(filter(f, 'abc'))""" ++ self.unchanged(a) ++ a = """all(filter(f, 'abc'))""" ++ self.unchanged(a) ++ a = """sum(filter(f, 'abc'))""" ++ self.unchanged(a) ++ a = """sorted(filter(f, 'abc'))""" ++ self.unchanged(a) ++ a = """sorted(filter(f, 'abc'), key=blah)""" ++ self.unchanged(a) ++ a = """sorted(filter(f, 'abc'), key=blah)[0]""" ++ self.unchanged(a) ++ a = """for i in filter(f, 'abc'): pass""" ++ self.unchanged(a) ++ a = """[x for x in filter(f, 'abc')]""" ++ self.unchanged(a) ++ a = """(x for x in filter(f, 'abc'))""" ++ self.unchanged(a) ++ ++ def test_future_builtins(self): ++ a = "from future_builtins import spam, filter; filter(f, 'ham')" ++ self.unchanged(a) ++ ++ b = """from future_builtins import spam; x = filter(f, 'abc')""" ++ a = """from future_builtins import spam; x = list(filter(f, 'abc'))""" ++ self.check(b, a) ++ ++ a = "from future_builtins import *; filter(f, 'ham')" ++ self.unchanged(a) ++ ++class Test_map(FixerTestCase): ++ fixer = "map" ++ ++ def check(self, b, a): ++ self.unchanged("from future_builtins import map; " + b, a) ++ super(Test_map, self).check(b, a) ++ ++ def test_prefix_preservation(self): ++ b = """x = map( f, 'abc' )""" ++ a = """x = list(map( f, 'abc' ))""" ++ self.check(b, a) ++ ++ def test_trailing_comment(self): ++ b = """x = map(f, 'abc') # foo""" ++ a = """x = list(map(f, 'abc')) # foo""" ++ self.check(b, a) ++ ++ def test_map_basic(self): ++ b = """x = map(f, 'abc')""" ++ a = """x = list(map(f, 'abc'))""" ++ self.check(b, a) ++ ++ b = """x = len(map(f, 'abc', 'def'))""" ++ a = """x = len(list(map(f, 'abc', 'def')))""" ++ self.check(b, a) ++ ++ b = """x = map(None, 'abc')""" ++ a = """x = list('abc')""" ++ self.check(b, a) ++ ++ b = """x = map(None, 'abc', 'def')""" ++ a = """x = list(map(None, 'abc', 'def'))""" ++ self.check(b, a) ++ ++ b = """x = map(lambda x: x+1, range(4))""" ++ a = """x = [x+1 for x in range(4)]""" ++ self.check(b, a) ++ ++ # Note the parens around x ++ b = """x = map(lambda (x): x+1, range(4))""" ++ a = """x = [x+1 for x in range(4)]""" ++ self.check(b, a) ++ ++ b = """ ++ foo() ++ # foo ++ map(f, x) ++ """ ++ a = """ ++ foo() ++ # foo ++ list(map(f, x)) ++ """ ++ self.warns(b, a, "You should use a for loop here") ++ ++ # XXX This (rare) case is not supported ++## b = """x = map(f, 'abc')[0]""" ++## a = """x = list(map(f, 'abc'))[0]""" ++## self.check(b, a) ++ ++ def test_map_nochange(self): ++ a = """b.join(map(f, 'abc'))""" ++ self.unchanged(a) ++ a = """(a + foo(5)).join(map(f, 'abc'))""" ++ self.unchanged(a) ++ a = """iter(map(f, 'abc'))""" ++ self.unchanged(a) ++ a = """list(map(f, 'abc'))""" ++ self.unchanged(a) ++ a = """list(map(f, 'abc'))[0]""" ++ self.unchanged(a) ++ a = """set(map(f, 'abc'))""" ++ self.unchanged(a) ++ a = """set(map(f, 'abc')).pop()""" ++ self.unchanged(a) ++ a = """tuple(map(f, 'abc'))""" ++ self.unchanged(a) ++ a = """any(map(f, 'abc'))""" ++ self.unchanged(a) ++ a = """all(map(f, 'abc'))""" ++ self.unchanged(a) ++ a = """sum(map(f, 'abc'))""" ++ self.unchanged(a) ++ a = """sorted(map(f, 'abc'))""" ++ self.unchanged(a) ++ a = """sorted(map(f, 'abc'), key=blah)""" ++ self.unchanged(a) ++ a = """sorted(map(f, 'abc'), key=blah)[0]""" ++ self.unchanged(a) ++ a = """for i in map(f, 'abc'): pass""" ++ self.unchanged(a) ++ a = """[x for x in map(f, 'abc')]""" ++ self.unchanged(a) ++ a = """(x for x in map(f, 'abc'))""" ++ self.unchanged(a) ++ ++ def test_future_builtins(self): ++ a = "from future_builtins import spam, map, eggs; map(f, 'ham')" ++ self.unchanged(a) ++ ++ b = """from future_builtins import spam, eggs; x = map(f, 'abc')""" ++ a = """from future_builtins import spam, eggs; x = list(map(f, 'abc'))""" ++ self.check(b, a) ++ ++ a = "from future_builtins import *; map(f, 'ham')" ++ self.unchanged(a) ++ ++class Test_zip(FixerTestCase): ++ fixer = "zip" ++ ++ def check(self, b, a): ++ self.unchanged("from future_builtins import zip; " + b, a) ++ super(Test_zip, self).check(b, a) ++ ++ def test_zip_basic(self): ++ b = """x = zip(a, b, c)""" ++ a = """x = list(zip(a, b, c))""" ++ self.check(b, a) ++ ++ b = """x = len(zip(a, b))""" ++ a = """x = len(list(zip(a, b)))""" ++ self.check(b, a) ++ ++ def test_zip_nochange(self): ++ a = """b.join(zip(a, b))""" ++ self.unchanged(a) ++ a = """(a + foo(5)).join(zip(a, b))""" ++ self.unchanged(a) ++ a = """iter(zip(a, b))""" ++ self.unchanged(a) ++ a = """list(zip(a, b))""" ++ self.unchanged(a) ++ a = """list(zip(a, b))[0]""" ++ self.unchanged(a) ++ a = """set(zip(a, b))""" ++ self.unchanged(a) ++ a = """set(zip(a, b)).pop()""" ++ self.unchanged(a) ++ a = """tuple(zip(a, b))""" ++ self.unchanged(a) ++ a = """any(zip(a, b))""" ++ self.unchanged(a) ++ a = """all(zip(a, b))""" ++ self.unchanged(a) ++ a = """sum(zip(a, b))""" ++ self.unchanged(a) ++ a = """sorted(zip(a, b))""" ++ self.unchanged(a) ++ a = """sorted(zip(a, b), key=blah)""" ++ self.unchanged(a) ++ a = """sorted(zip(a, b), key=blah)[0]""" ++ self.unchanged(a) ++ a = """for i in zip(a, b): pass""" ++ self.unchanged(a) ++ a = """[x for x in zip(a, b)]""" ++ self.unchanged(a) ++ a = """(x for x in zip(a, b))""" ++ self.unchanged(a) ++ ++ def test_future_builtins(self): ++ a = "from future_builtins import spam, zip, eggs; zip(a, b)" ++ self.unchanged(a) ++ ++ b = """from future_builtins import spam, eggs; x = zip(a, b)""" ++ a = """from future_builtins import spam, eggs; x = list(zip(a, b))""" ++ self.check(b, a) ++ ++ a = "from future_builtins import *; zip(a, b)" ++ self.unchanged(a) ++ ++class Test_standarderror(FixerTestCase): ++ fixer = "standarderror" ++ ++ def test(self): ++ b = """x = StandardError()""" ++ a = """x = Exception()""" ++ self.check(b, a) ++ ++ b = """x = StandardError(a, b, c)""" ++ a = """x = Exception(a, b, c)""" ++ self.check(b, a) ++ ++ b = """f(2 + StandardError(a, b, c))""" ++ a = """f(2 + Exception(a, b, c))""" ++ self.check(b, a) ++ ++class Test_types(FixerTestCase): ++ fixer = "types" ++ ++ def test_basic_types_convert(self): ++ b = """types.StringType""" ++ a = """bytes""" ++ self.check(b, a) ++ ++ b = """types.DictType""" ++ a = """dict""" ++ self.check(b, a) ++ ++ b = """types . IntType""" ++ a = """int""" ++ self.check(b, a) ++ ++ b = """types.ListType""" ++ a = """list""" ++ self.check(b, a) ++ ++ b = """types.LongType""" ++ a = """int""" ++ self.check(b, a) ++ ++ b = """types.NoneType""" ++ a = """type(None)""" ++ self.check(b, a) ++ ++class Test_idioms(FixerTestCase): ++ fixer = "idioms" ++ ++ def test_while(self): ++ b = """while 1: foo()""" ++ a = """while True: foo()""" ++ self.check(b, a) ++ ++ b = """while 1: foo()""" ++ a = """while True: foo()""" ++ self.check(b, a) ++ ++ b = """ ++ while 1: ++ foo() ++ """ ++ a = """ ++ while True: ++ foo() ++ """ ++ self.check(b, a) ++ ++ def test_while_unchanged(self): ++ s = """while 11: foo()""" ++ self.unchanged(s) ++ ++ s = """while 0: foo()""" ++ self.unchanged(s) ++ ++ s = """while foo(): foo()""" ++ self.unchanged(s) ++ ++ s = """while []: foo()""" ++ self.unchanged(s) ++ ++ def test_eq_simple(self): ++ b = """type(x) == T""" ++ a = """isinstance(x, T)""" ++ self.check(b, a) ++ ++ b = """if type(x) == T: pass""" ++ a = """if isinstance(x, T): pass""" ++ self.check(b, a) ++ ++ def test_eq_reverse(self): ++ b = """T == type(x)""" ++ a = """isinstance(x, T)""" ++ self.check(b, a) ++ ++ b = """if T == type(x): pass""" ++ a = """if isinstance(x, T): pass""" ++ self.check(b, a) ++ ++ def test_eq_expression(self): ++ b = """type(x+y) == d.get('T')""" ++ a = """isinstance(x+y, d.get('T'))""" ++ self.check(b, a) ++ ++ b = """type( x + y) == d.get('T')""" ++ a = """isinstance(x + y, d.get('T'))""" ++ self.check(b, a) ++ ++ def test_is_simple(self): ++ b = """type(x) is T""" ++ a = """isinstance(x, T)""" ++ self.check(b, a) ++ ++ b = """if type(x) is T: pass""" ++ a = """if isinstance(x, T): pass""" ++ self.check(b, a) ++ ++ def test_is_reverse(self): ++ b = """T is type(x)""" ++ a = """isinstance(x, T)""" ++ self.check(b, a) ++ ++ b = """if T is type(x): pass""" ++ a = """if isinstance(x, T): pass""" ++ self.check(b, a) ++ ++ def test_is_expression(self): ++ b = """type(x+y) is d.get('T')""" ++ a = """isinstance(x+y, d.get('T'))""" ++ self.check(b, a) ++ ++ b = """type( x + y) is d.get('T')""" ++ a = """isinstance(x + y, d.get('T'))""" ++ self.check(b, a) ++ ++ def test_is_not_simple(self): ++ b = """type(x) is not T""" ++ a = """not isinstance(x, T)""" ++ self.check(b, a) ++ ++ b = """if type(x) is not T: pass""" ++ a = """if not isinstance(x, T): pass""" ++ self.check(b, a) ++ ++ def test_is_not_reverse(self): ++ b = """T is not type(x)""" ++ a = """not isinstance(x, T)""" ++ self.check(b, a) ++ ++ b = """if T is not type(x): pass""" ++ a = """if not isinstance(x, T): pass""" ++ self.check(b, a) ++ ++ def test_is_not_expression(self): ++ b = """type(x+y) is not d.get('T')""" ++ a = """not isinstance(x+y, d.get('T'))""" ++ self.check(b, a) ++ ++ b = """type( x + y) is not d.get('T')""" ++ a = """not isinstance(x + y, d.get('T'))""" ++ self.check(b, a) ++ ++ def test_ne_simple(self): ++ b = """type(x) != T""" ++ a = """not isinstance(x, T)""" ++ self.check(b, a) ++ ++ b = """if type(x) != T: pass""" ++ a = """if not isinstance(x, T): pass""" ++ self.check(b, a) ++ ++ def test_ne_reverse(self): ++ b = """T != type(x)""" ++ a = """not isinstance(x, T)""" ++ self.check(b, a) ++ ++ b = """if T != type(x): pass""" ++ a = """if not isinstance(x, T): pass""" ++ self.check(b, a) ++ ++ def test_ne_expression(self): ++ b = """type(x+y) != d.get('T')""" ++ a = """not isinstance(x+y, d.get('T'))""" ++ self.check(b, a) ++ ++ b = """type( x + y) != d.get('T')""" ++ a = """not isinstance(x + y, d.get('T'))""" ++ self.check(b, a) ++ ++ def test_type_unchanged(self): ++ a = """type(x).__name__""" ++ self.unchanged(a) ++ ++ def test_sort_list_call(self): ++ b = """ ++ v = list(t) ++ v.sort() ++ foo(v) ++ """ ++ a = """ ++ v = sorted(t) ++ foo(v) ++ """ ++ self.check(b, a) ++ ++ b = """ ++ v = list(foo(b) + d) ++ v.sort() ++ foo(v) ++ """ ++ a = """ ++ v = sorted(foo(b) + d) ++ foo(v) ++ """ ++ self.check(b, a) ++ ++ b = """ ++ while x: ++ v = list(t) ++ v.sort() ++ foo(v) ++ """ ++ a = """ ++ while x: ++ v = sorted(t) ++ foo(v) ++ """ ++ self.check(b, a) ++ ++ b = """ ++ v = list(t) ++ # foo ++ v.sort() ++ foo(v) ++ """ ++ a = """ ++ v = sorted(t) ++ # foo ++ foo(v) ++ """ ++ self.check(b, a) ++ ++ b = r""" ++ v = list( t) ++ v.sort() ++ foo(v) ++ """ ++ a = r""" ++ v = sorted( t) ++ foo(v) ++ """ ++ self.check(b, a) ++ ++ def test_sort_simple_expr(self): ++ b = """ ++ v = t ++ v.sort() ++ foo(v) ++ """ ++ a = """ ++ v = sorted(t) ++ foo(v) ++ """ ++ self.check(b, a) ++ ++ b = """ ++ v = foo(b) ++ v.sort() ++ foo(v) ++ """ ++ a = """ ++ v = sorted(foo(b)) ++ foo(v) ++ """ ++ self.check(b, a) ++ ++ b = """ ++ v = b.keys() ++ v.sort() ++ foo(v) ++ """ ++ a = """ ++ v = sorted(b.keys()) ++ foo(v) ++ """ ++ self.check(b, a) ++ ++ b = """ ++ v = foo(b) + d ++ v.sort() ++ foo(v) ++ """ ++ a = """ ++ v = sorted(foo(b) + d) ++ foo(v) ++ """ ++ self.check(b, a) ++ ++ b = """ ++ while x: ++ v = t ++ v.sort() ++ foo(v) ++ """ ++ a = """ ++ while x: ++ v = sorted(t) ++ foo(v) ++ """ ++ self.check(b, a) ++ ++ b = """ ++ v = t ++ # foo ++ v.sort() ++ foo(v) ++ """ ++ a = """ ++ v = sorted(t) ++ # foo ++ foo(v) ++ """ ++ self.check(b, a) ++ ++ b = r""" ++ v = t ++ v.sort() ++ foo(v) ++ """ ++ a = r""" ++ v = sorted(t) ++ foo(v) ++ """ ++ self.check(b, a) ++ ++ def test_sort_unchanged(self): ++ s = """ ++ v = list(t) ++ w.sort() ++ foo(w) ++ """ ++ self.unchanged(s) ++ ++ s = """ ++ v = list(t) ++ v.sort(u) ++ foo(v) ++ """ ++ self.unchanged(s) ++ ++class Test_basestring(FixerTestCase): ++ fixer = "basestring" ++ ++ def test_basestring(self): ++ b = """isinstance(x, basestring)""" ++ a = """isinstance(x, str)""" ++ self.check(b, a) ++ ++class Test_buffer(FixerTestCase): ++ fixer = "buffer" ++ ++ def test_buffer(self): ++ b = """x = buffer(y)""" ++ a = """x = memoryview(y)""" ++ self.check(b, a) ++ ++class Test_future(FixerTestCase): ++ fixer = "future" ++ ++ def test_future(self): ++ b = """from __future__ import braces""" ++ a = """""" ++ self.check(b, a) ++ ++ b = """# comment\nfrom __future__ import braces""" ++ a = """# comment\n""" ++ self.check(b, a) ++ ++ b = """from __future__ import braces\n# comment""" ++ a = """\n# comment""" ++ self.check(b, a) ++ ++ def test_run_order(self): ++ self.assert_runs_after('print') ++ ++class Test_itertools(FixerTestCase): ++ fixer = "itertools" ++ ++ def checkall(self, before, after): ++ # Because we need to check with and without the itertools prefix ++ # and on each of the three functions, these loops make it all ++ # much easier ++ for i in ('itertools.', ''): ++ for f in ('map', 'filter', 'zip'): ++ b = before %(i+'i'+f) ++ a = after %(f) ++ self.check(b, a) ++ ++ def test_0(self): ++ # A simple example -- test_1 covers exactly the same thing, ++ # but it's not quite as clear. ++ b = "itertools.izip(a, b)" ++ a = "zip(a, b)" ++ self.check(b, a) ++ ++ def test_1(self): ++ b = """%s(f, a)""" ++ a = """%s(f, a)""" ++ self.checkall(b, a) ++ ++ def test_2(self): ++ b = """itertools.ifilterfalse(a, b)""" ++ a = """itertools.filterfalse(a, b)""" ++ self.check(b, a) ++ ++ def test_4(self): ++ b = """ifilterfalse(a, b)""" ++ a = """filterfalse(a, b)""" ++ self.check(b, a) ++ ++ def test_space_1(self): ++ b = """ %s(f, a)""" ++ a = """ %s(f, a)""" ++ self.checkall(b, a) ++ ++ def test_space_2(self): ++ b = """ itertools.ifilterfalse(a, b)""" ++ a = """ itertools.filterfalse(a, b)""" ++ self.check(b, a) ++ ++ def test_run_order(self): ++ self.assert_runs_after('map', 'zip', 'filter') ++ ++class Test_itertools_imports(FixerTestCase): ++ fixer = 'itertools_imports' ++ ++ def test_reduced(self): ++ b = "from itertools import imap, izip, foo" ++ a = "from itertools import foo" ++ self.check(b, a) ++ ++ b = "from itertools import bar, imap, izip, foo" ++ a = "from itertools import bar, foo" ++ self.check(b, a) ++ ++ def test_comments(self): ++ b = "#foo\nfrom itertools import imap, izip" ++ a = "#foo\n" ++ self.check(b, a) ++ ++ def test_none(self): ++ b = "from itertools import imap, izip" ++ a = "" ++ self.check(b, a) ++ ++ b = "from itertools import izip" ++ a = "" ++ self.check(b, a) ++ ++ def test_import_as(self): ++ b = "from itertools import izip, bar as bang, imap" ++ a = "from itertools import bar as bang" ++ self.check(b, a) ++ ++ b = "from itertools import izip as _zip, imap, bar" ++ a = "from itertools import bar" ++ self.check(b, a) ++ ++ b = "from itertools import imap as _map" ++ a = "" ++ self.check(b, a) ++ ++ b = "from itertools import imap as _map, izip as _zip" ++ a = "" ++ self.check(b, a) ++ ++ s = "from itertools import bar as bang" ++ self.unchanged(s) ++ ++ def test_ifilter(self): ++ b = "from itertools import ifilterfalse" ++ a = "from itertools import filterfalse" ++ self.check(b, a) ++ ++ b = "from itertools import imap, ifilterfalse, foo" ++ a = "from itertools import filterfalse, foo" ++ self.check(b, a) ++ ++ b = "from itertools import bar, ifilterfalse, foo" ++ a = "from itertools import bar, filterfalse, foo" ++ self.check(b, a) ++ ++ ++ def test_unchanged(self): ++ s = "from itertools import foo" ++ self.unchanged(s) ++ ++class Test_import(FixerTestCase): ++ fixer = "import" ++ ++ def setUp(self): ++ super(Test_import, self).setUp() ++ # Need to replace fix_import's exists method ++ # so we can check that it's doing the right thing ++ self.files_checked = [] ++ self.present_files = set() ++ self.always_exists = True ++ def fake_exists(name): ++ self.files_checked.append(name) ++ return self.always_exists or (name in self.present_files) ++ ++ from ..fixes import fix_import ++ fix_import.exists = fake_exists ++ ++ def tearDown(self): ++ from lib2to3.fixes import fix_import ++ fix_import.exists = os.path.exists ++ ++ def check_both(self, b, a): ++ self.always_exists = True ++ super(Test_import, self).check(b, a) ++ self.always_exists = False ++ super(Test_import, self).unchanged(b) ++ ++ def test_files_checked(self): ++ def p(path): ++ # Takes a unix path and returns a path with correct separators ++ return os.path.pathsep.join(path.split("/")) ++ ++ self.always_exists = False ++ self.present_files = set(['__init__.py']) ++ expected_extensions = ('.py', os.path.pathsep, '.pyc', '.so', ++ '.sl', '.pyd') ++ names_to_test = (p("/spam/eggs.py"), "ni.py", p("../../shrubbery.py")) ++ ++ for name in names_to_test: ++ self.files_checked = [] ++ self.filename = name ++ self.unchanged("import jam") ++ ++ if os.path.dirname(name): ++ name = os.path.dirname(name) + '/jam' ++ else: ++ name = 'jam' ++ expected_checks = set(name + ext for ext in expected_extensions) ++ expected_checks.add("__init__.py") ++ ++ self.assertEqual(set(self.files_checked), expected_checks) ++ ++ def test_not_in_package(self): ++ s = "import bar" ++ self.always_exists = False ++ self.present_files = set(["bar.py"]) ++ self.unchanged(s) ++ ++ def test_in_package(self): ++ b = "import bar" ++ a = "from . import bar" ++ self.always_exists = False ++ self.present_files = set(["__init__.py", "bar.py"]) ++ self.check(b, a) ++ ++ def test_comments_and_indent(self): ++ b = "import bar # Foo" ++ a = "from . import bar # Foo" ++ self.check(b, a) ++ ++ def test_from(self): ++ b = "from foo import bar, baz" ++ a = "from .foo import bar, baz" ++ self.check_both(b, a) ++ ++ b = "from foo import bar" ++ a = "from .foo import bar" ++ self.check_both(b, a) ++ ++ b = "from foo import (bar, baz)" ++ a = "from .foo import (bar, baz)" ++ self.check_both(b, a) ++ ++ def test_dotted_from(self): ++ b = "from green.eggs import ham" ++ a = "from .green.eggs import ham" ++ self.check_both(b, a) ++ ++ def test_from_as(self): ++ b = "from green.eggs import ham as spam" ++ a = "from .green.eggs import ham as spam" ++ self.check_both(b, a) ++ ++ def test_import(self): ++ b = "import foo" ++ a = "from . import foo" ++ self.check_both(b, a) ++ ++ b = "import foo, bar" ++ a = "from . import foo, bar" ++ self.check_both(b, a) ++ ++ b = "import foo, bar, x" ++ a = "from . import foo, bar, x" ++ self.check_both(b, a) ++ ++ b = "import x, y, z" ++ a = "from . import x, y, z" ++ self.check_both(b, a) ++ ++ def test_import_as(self): ++ b = "import foo as x" ++ a = "from . import foo as x" ++ self.check_both(b, a) ++ ++ b = "import a as b, b as c, c as d" ++ a = "from . import a as b, b as c, c as d" ++ self.check_both(b, a) ++ ++ def test_local_and_absolute(self): ++ self.always_exists = False ++ self.present_files = set(["foo.py", "__init__.py"]) ++ ++ s = "import foo, bar" ++ self.warns_unchanged(s, "absolute and local imports together") ++ ++ def test_dotted_import(self): ++ b = "import foo.bar" ++ a = "from . import foo.bar" ++ self.check_both(b, a) ++ ++ def test_dotted_import_as(self): ++ b = "import foo.bar as bang" ++ a = "from . import foo.bar as bang" ++ self.check_both(b, a) ++ ++ def test_prefix(self): ++ b = """ ++ # prefix ++ import foo.bar ++ """ ++ a = """ ++ # prefix ++ from . import foo.bar ++ """ ++ self.check_both(b, a) ++ ++ ++class Test_set_literal(FixerTestCase): ++ ++ fixer = "set_literal" ++ ++ def test_basic(self): ++ b = """set([1, 2, 3])""" ++ a = """{1, 2, 3}""" ++ self.check(b, a) ++ ++ b = """set((1, 2, 3))""" ++ a = """{1, 2, 3}""" ++ self.check(b, a) ++ ++ b = """set((1,))""" ++ a = """{1}""" ++ self.check(b, a) ++ ++ b = """set([1])""" ++ self.check(b, a) ++ ++ b = """set((a, b))""" ++ a = """{a, b}""" ++ self.check(b, a) ++ ++ b = """set([a, b])""" ++ self.check(b, a) ++ ++ b = """set((a*234, f(args=23)))""" ++ a = """{a*234, f(args=23)}""" ++ self.check(b, a) ++ ++ b = """set([a*23, f(23)])""" ++ a = """{a*23, f(23)}""" ++ self.check(b, a) ++ ++ b = """set([a-234**23])""" ++ a = """{a-234**23}""" ++ self.check(b, a) ++ ++ def test_listcomps(self): ++ b = """set([x for x in y])""" ++ a = """{x for x in y}""" ++ self.check(b, a) ++ ++ b = """set([x for x in y if x == m])""" ++ a = """{x for x in y if x == m}""" ++ self.check(b, a) ++ ++ b = """set([x for x in y for a in b])""" ++ a = """{x for x in y for a in b}""" ++ self.check(b, a) ++ ++ b = """set([f(x) - 23 for x in y])""" ++ a = """{f(x) - 23 for x in y}""" ++ self.check(b, a) ++ ++ def test_whitespace(self): ++ b = """set( [1, 2])""" ++ a = """{1, 2}""" ++ self.check(b, a) ++ ++ b = """set([1 , 2])""" ++ a = """{1 , 2}""" ++ self.check(b, a) ++ ++ b = """set([ 1 ])""" ++ a = """{ 1 }""" ++ self.check(b, a) ++ ++ b = """set( [1] )""" ++ a = """{1}""" ++ self.check(b, a) ++ ++ b = """set([ 1, 2 ])""" ++ a = """{ 1, 2 }""" ++ self.check(b, a) ++ ++ b = """set([x for x in y ])""" ++ a = """{x for x in y }""" ++ self.check(b, a) ++ ++ b = """set( ++ [1, 2] ++ ) ++ """ ++ a = """{1, 2}\n""" ++ self.check(b, a) ++ ++ def test_comments(self): ++ b = """set((1, 2)) # Hi""" ++ a = """{1, 2} # Hi""" ++ self.check(b, a) ++ ++ # This isn't optimal behavior, but the fixer is optional. ++ b = """ ++ # Foo ++ set( # Bar ++ (1, 2) ++ ) ++ """ ++ a = """ ++ # Foo ++ {1, 2} ++ """ ++ self.check(b, a) ++ ++ def test_unchanged(self): ++ s = """set()""" ++ self.unchanged(s) ++ ++ s = """set(a)""" ++ self.unchanged(s) ++ ++ s = """set(a, b, c)""" ++ self.unchanged(s) ++ ++ # Don't transform generators because they might have to be lazy. ++ s = """set(x for x in y)""" ++ self.unchanged(s) ++ ++ s = """set(x for x in y if z)""" ++ self.unchanged(s) ++ ++ s = """set(a*823-23**2 + f(23))""" ++ self.unchanged(s) ++ ++ ++class Test_sys_exc(FixerTestCase): ++ fixer = "sys_exc" ++ ++ def test_0(self): ++ b = "sys.exc_type" ++ a = "sys.exc_info()[0]" ++ self.check(b, a) ++ ++ def test_1(self): ++ b = "sys.exc_value" ++ a = "sys.exc_info()[1]" ++ self.check(b, a) ++ ++ def test_2(self): ++ b = "sys.exc_traceback" ++ a = "sys.exc_info()[2]" ++ self.check(b, a) ++ ++ def test_3(self): ++ b = "sys.exc_type # Foo" ++ a = "sys.exc_info()[0] # Foo" ++ self.check(b, a) ++ ++ def test_4(self): ++ b = "sys. exc_type" ++ a = "sys. exc_info()[0]" ++ self.check(b, a) ++ ++ def test_5(self): ++ b = "sys .exc_type" ++ a = "sys .exc_info()[0]" ++ self.check(b, a) ++ ++ ++class Test_paren(FixerTestCase): ++ fixer = "paren" ++ ++ def test_0(self): ++ b = """[i for i in 1, 2 ]""" ++ a = """[i for i in (1, 2) ]""" ++ self.check(b, a) ++ ++ def test_1(self): ++ b = """[i for i in 1, 2, ]""" ++ a = """[i for i in (1, 2,) ]""" ++ self.check(b, a) ++ ++ def test_2(self): ++ b = """[i for i in 1, 2 ]""" ++ a = """[i for i in (1, 2) ]""" ++ self.check(b, a) ++ ++ def test_3(self): ++ b = """[i for i in 1, 2 if i]""" ++ a = """[i for i in (1, 2) if i]""" ++ self.check(b, a) ++ ++ def test_4(self): ++ b = """[i for i in 1, 2 ]""" ++ a = """[i for i in (1, 2) ]""" ++ self.check(b, a) ++ ++ def test_5(self): ++ b = """(i for i in 1, 2)""" ++ a = """(i for i in (1, 2))""" ++ self.check(b, a) ++ ++ def test_6(self): ++ b = """(i for i in 1 ,2 if i)""" ++ a = """(i for i in (1 ,2) if i)""" ++ self.check(b, a) ++ ++ def test_unchanged_0(self): ++ s = """[i for i in (1, 2)]""" ++ self.unchanged(s) ++ ++ def test_unchanged_1(self): ++ s = """[i for i in foo()]""" ++ self.unchanged(s) ++ ++ def test_unchanged_2(self): ++ s = """[i for i in (1, 2) if nothing]""" ++ self.unchanged(s) ++ ++ def test_unchanged_3(self): ++ s = """(i for i in (1, 2))""" ++ self.unchanged(s) ++ ++ def test_unchanged_4(self): ++ s = """[i for i in m]""" ++ self.unchanged(s) ++ ++class Test_metaclass(FixerTestCase): ++ ++ fixer = 'metaclass' ++ ++ def test_unchanged(self): ++ self.unchanged("class X(): pass") ++ self.unchanged("class X(object): pass") ++ self.unchanged("class X(object1, object2): pass") ++ self.unchanged("class X(object1, object2, object3): pass") ++ self.unchanged("class X(metaclass=Meta): pass") ++ self.unchanged("class X(b, arg=23, metclass=Meta): pass") ++ self.unchanged("class X(b, arg=23, metaclass=Meta, other=42): pass") ++ ++ s = """ ++ class X: ++ def __metaclass__(self): pass ++ """ ++ self.unchanged(s) ++ ++ s = """ ++ class X: ++ a[23] = 74 ++ """ ++ self.unchanged(s) ++ ++ def test_comments(self): ++ b = """ ++ class X: ++ # hi ++ __metaclass__ = AppleMeta ++ """ ++ a = """ ++ class X(metaclass=AppleMeta): ++ # hi ++ pass ++ """ ++ self.check(b, a) ++ ++ b = """ ++ class X: ++ __metaclass__ = Meta ++ # Bedtime! ++ """ ++ a = """ ++ class X(metaclass=Meta): ++ pass ++ # Bedtime! ++ """ ++ self.check(b, a) ++ ++ def test_meta(self): ++ # no-parent class, odd body ++ b = """ ++ class X(): ++ __metaclass__ = Q ++ pass ++ """ ++ a = """ ++ class X(metaclass=Q): ++ pass ++ """ ++ self.check(b, a) ++ ++ # one parent class, no body ++ b = """class X(object): __metaclass__ = Q""" ++ a = """class X(object, metaclass=Q): pass""" ++ self.check(b, a) ++ ++ ++ # one parent, simple body ++ b = """ ++ class X(object): ++ __metaclass__ = Meta ++ bar = 7 ++ """ ++ a = """ ++ class X(object, metaclass=Meta): ++ bar = 7 ++ """ ++ self.check(b, a) ++ ++ b = """ ++ class X: ++ __metaclass__ = Meta; x = 4; g = 23 ++ """ ++ a = """ ++ class X(metaclass=Meta): ++ x = 4; g = 23 ++ """ ++ self.check(b, a) ++ ++ # one parent, simple body, __metaclass__ last ++ b = """ ++ class X(object): ++ bar = 7 ++ __metaclass__ = Meta ++ """ ++ a = """ ++ class X(object, metaclass=Meta): ++ bar = 7 ++ """ ++ self.check(b, a) ++ ++ # redefining __metaclass__ ++ b = """ ++ class X(): ++ __metaclass__ = A ++ __metaclass__ = B ++ bar = 7 ++ """ ++ a = """ ++ class X(metaclass=B): ++ bar = 7 ++ """ ++ self.check(b, a) ++ ++ # multiple inheritance, simple body ++ b = """ ++ class X(clsA, clsB): ++ __metaclass__ = Meta ++ bar = 7 ++ """ ++ a = """ ++ class X(clsA, clsB, metaclass=Meta): ++ bar = 7 ++ """ ++ self.check(b, a) ++ ++ # keywords in the class statement ++ b = """class m(a, arg=23): __metaclass__ = Meta""" ++ a = """class m(a, arg=23, metaclass=Meta): pass""" ++ self.check(b, a) ++ ++ b = """ ++ class X(expression(2 + 4)): ++ __metaclass__ = Meta ++ """ ++ a = """ ++ class X(expression(2 + 4), metaclass=Meta): ++ pass ++ """ ++ self.check(b, a) ++ ++ b = """ ++ class X(expression(2 + 4), x**4): ++ __metaclass__ = Meta ++ """ ++ a = """ ++ class X(expression(2 + 4), x**4, metaclass=Meta): ++ pass ++ """ ++ self.check(b, a) ++ ++ b = """ ++ class X: ++ __metaclass__ = Meta ++ save.py = 23 ++ """ ++ a = """ ++ class X(metaclass=Meta): ++ save.py = 23 ++ """ ++ self.check(b, a) ++ ++ ++class Test_getcwdu(FixerTestCase): ++ ++ fixer = 'getcwdu' ++ ++ def test_basic(self): ++ b = """os.getcwdu""" ++ a = """os.getcwd""" ++ self.check(b, a) ++ ++ b = """os.getcwdu()""" ++ a = """os.getcwd()""" ++ self.check(b, a) ++ ++ b = """meth = os.getcwdu""" ++ a = """meth = os.getcwd""" ++ self.check(b, a) ++ ++ b = """os.getcwdu(args)""" ++ a = """os.getcwd(args)""" ++ self.check(b, a) ++ ++ def test_comment(self): ++ b = """os.getcwdu() # Foo""" ++ a = """os.getcwd() # Foo""" ++ self.check(b, a) ++ ++ def test_unchanged(self): ++ s = """os.getcwd()""" ++ self.unchanged(s) ++ ++ s = """getcwdu()""" ++ self.unchanged(s) ++ ++ s = """os.getcwdb()""" ++ self.unchanged(s) ++ ++ def test_indentation(self): ++ b = """ ++ if 1: ++ os.getcwdu() ++ """ ++ a = """ ++ if 1: ++ os.getcwd() ++ """ ++ self.check(b, a) ++ ++ def test_multilation(self): ++ b = """os .getcwdu()""" ++ a = """os .getcwd()""" ++ self.check(b, a) ++ ++ b = """os. getcwdu""" ++ a = """os. getcwd""" ++ self.check(b, a) ++ ++ b = """os.getcwdu ( )""" ++ a = """os.getcwd ( )""" ++ self.check(b, a) ++ ++ ++if __name__ == "__main__": ++ import __main__ ++ support.run_all_tests(__main__) +diff -r 531f2e948299 refactor/tests/.svn/text-base/test_parser.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/text-base/test_parser.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,202 @@ ++#!/usr/bin/env python2.5 ++"""Test suite for 2to3's parser and grammar files. ++ ++This is the place to add tests for changes to 2to3's grammar, such as those ++merging the grammars for Python 2 and 3. In addition to specific tests for ++parts of the grammar we've changed, we also make sure we can parse the ++test_grammar.py files from both Python 2 and Python 3. ++""" ++# Author: Collin Winter ++ ++# Testing imports ++from . import support ++from .support import driver, test_dir ++ ++# Python imports ++import os ++import os.path ++ ++# Local imports ++from ..pgen2.parse import ParseError ++ ++ ++class GrammarTest(support.TestCase): ++ def validate(self, code): ++ support.parse_string(code) ++ ++ def invalid_syntax(self, code): ++ try: ++ self.validate(code) ++ except ParseError: ++ pass ++ else: ++ raise AssertionError("Syntax shouldn't have been valid") ++ ++ ++class TestRaiseChanges(GrammarTest): ++ def test_2x_style_1(self): ++ self.validate("raise") ++ ++ def test_2x_style_2(self): ++ self.validate("raise E, V") ++ ++ def test_2x_style_3(self): ++ self.validate("raise E, V, T") ++ ++ def test_2x_style_invalid_1(self): ++ self.invalid_syntax("raise E, V, T, Z") ++ ++ def test_3x_style(self): ++ self.validate("raise E1 from E2") ++ ++ def test_3x_style_invalid_1(self): ++ self.invalid_syntax("raise E, V from E1") ++ ++ def test_3x_style_invalid_2(self): ++ self.invalid_syntax("raise E from E1, E2") ++ ++ def test_3x_style_invalid_3(self): ++ self.invalid_syntax("raise from E1, E2") ++ ++ def test_3x_style_invalid_4(self): ++ self.invalid_syntax("raise E from") ++ ++ ++# Adapated from Python 3's Lib/test/test_grammar.py:GrammarTests.testFuncdef ++class TestFunctionAnnotations(GrammarTest): ++ def test_1(self): ++ self.validate("""def f(x) -> list: pass""") ++ ++ def test_2(self): ++ self.validate("""def f(x:int): pass""") ++ ++ def test_3(self): ++ self.validate("""def f(*x:str): pass""") ++ ++ def test_4(self): ++ self.validate("""def f(**x:float): pass""") ++ ++ def test_5(self): ++ self.validate("""def f(x, y:1+2): pass""") ++ ++ def test_6(self): ++ self.validate("""def f(a, (b:1, c:2, d)): pass""") ++ ++ def test_7(self): ++ self.validate("""def f(a, (b:1, c:2, d), e:3=4, f=5, *g:6): pass""") ++ ++ def test_8(self): ++ s = """def f(a, (b:1, c:2, d), e:3=4, f=5, ++ *g:6, h:7, i=8, j:9=10, **k:11) -> 12: pass""" ++ self.validate(s) ++ ++ ++class TestExcept(GrammarTest): ++ def test_new(self): ++ s = """ ++ try: ++ x ++ except E as N: ++ y""" ++ self.validate(s) ++ ++ def test_old(self): ++ s = """ ++ try: ++ x ++ except E, N: ++ y""" ++ self.validate(s) ++ ++ ++# Adapted from Python 3's Lib/test/test_grammar.py:GrammarTests.testAtoms ++class TestSetLiteral(GrammarTest): ++ def test_1(self): ++ self.validate("""x = {'one'}""") ++ ++ def test_2(self): ++ self.validate("""x = {'one', 1,}""") ++ ++ def test_3(self): ++ self.validate("""x = {'one', 'two', 'three'}""") ++ ++ def test_4(self): ++ self.validate("""x = {2, 3, 4,}""") ++ ++ ++class TestNumericLiterals(GrammarTest): ++ def test_new_octal_notation(self): ++ self.validate("""0o7777777777777""") ++ self.invalid_syntax("""0o7324528887""") ++ ++ def test_new_binary_notation(self): ++ self.validate("""0b101010""") ++ self.invalid_syntax("""0b0101021""") ++ ++ ++class TestClassDef(GrammarTest): ++ def test_new_syntax(self): ++ self.validate("class B(t=7): pass") ++ self.validate("class B(t, *args): pass") ++ self.validate("class B(t, **kwargs): pass") ++ self.validate("class B(t, *args, **kwargs): pass") ++ self.validate("class B(t, y=9, *args, **kwargs): pass") ++ ++ ++class TestParserIdempotency(support.TestCase): ++ ++ """A cut-down version of pytree_idempotency.py.""" ++ ++ def test_all_project_files(self): ++ for filepath in support.all_project_files(): ++ print "Parsing %s..." % filepath ++ tree = driver.parse_file(filepath, debug=True) ++ if diff(filepath, tree): ++ self.fail("Idempotency failed: %s" % filepath) ++ ++ ++class TestLiterals(GrammarTest): ++ ++ def test_multiline_bytes_literals(self): ++ s = """ ++ md5test(b"\xaa" * 80, ++ (b"Test Using Larger Than Block-Size Key " ++ b"and Larger Than One Block-Size Data"), ++ "6f630fad67cda0ee1fb1f562db3aa53e") ++ """ ++ self.validate(s) ++ ++ def test_multiline_bytes_tripquote_literals(self): ++ s = ''' ++ b""" ++ ++ ++ """ ++ ''' ++ self.validate(s) ++ ++ def test_multiline_str_literals(self): ++ s = """ ++ md5test("\xaa" * 80, ++ ("Test Using Larger Than Block-Size Key " ++ "and Larger Than One Block-Size Data"), ++ "6f630fad67cda0ee1fb1f562db3aa53e") ++ """ ++ self.validate(s) ++ ++ ++def diff(fn, tree): ++ f = open("@", "w") ++ try: ++ f.write(str(tree)) ++ finally: ++ f.close() ++ try: ++ return os.system("diff -u %s @" % fn) ++ finally: ++ os.remove("@") ++ ++ ++if __name__ == "__main__": ++ import __main__ ++ support.run_all_tests(__main__) +diff -r 531f2e948299 refactor/tests/.svn/text-base/test_pytree.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/text-base/test_pytree.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,458 @@ ++#!/usr/bin/env python2.5 ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Unit tests for pytree.py. ++ ++NOTE: Please *don't* add doc strings to individual test methods! ++In verbose mode, printing of the module, class and method name is much ++more helpful than printing of (the first line of) the docstring, ++especially when debugging a test. ++""" ++ ++# Testing imports ++from . import support ++ ++# Local imports (XXX should become a package) ++from .. import pytree ++ ++try: ++ sorted ++except NameError: ++ def sorted(lst): ++ l = list(lst) ++ l.sort() ++ return l ++ ++class TestNodes(support.TestCase): ++ ++ """Unit tests for nodes (Base, Leaf, Node).""" ++ ++ def testBaseCantConstruct(self): ++ if __debug__: ++ # Test that instantiating Base() raises an AssertionError ++ self.assertRaises(AssertionError, pytree.Base) ++ ++ def testLeaf(self): ++ l1 = pytree.Leaf(100, "foo") ++ self.assertEqual(l1.type, 100) ++ self.assertEqual(l1.value, "foo") ++ ++ def testLeafRepr(self): ++ l1 = pytree.Leaf(100, "foo") ++ self.assertEqual(repr(l1), "Leaf(100, 'foo')") ++ ++ def testLeafStr(self): ++ l1 = pytree.Leaf(100, "foo") ++ self.assertEqual(str(l1), "foo") ++ l2 = pytree.Leaf(100, "foo", context=(" ", (10, 1))) ++ self.assertEqual(str(l2), " foo") ++ ++ def testLeafStrNumericValue(self): ++ # Make sure that the Leaf's value is stringified. Failing to ++ # do this can cause a TypeError in certain situations. ++ l1 = pytree.Leaf(2, 5) ++ l1.set_prefix("foo_") ++ self.assertEqual(str(l1), "foo_5") ++ ++ def testLeafEq(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "foo", context=(" ", (1, 0))) ++ self.assertEqual(l1, l2) ++ l3 = pytree.Leaf(101, "foo") ++ l4 = pytree.Leaf(100, "bar") ++ self.assertNotEqual(l1, l3) ++ self.assertNotEqual(l1, l4) ++ ++ def testLeafPrefix(self): ++ l1 = pytree.Leaf(100, "foo") ++ self.assertEqual(l1.get_prefix(), "") ++ self.failIf(l1.was_changed) ++ l1.set_prefix(" ##\n\n") ++ self.assertEqual(l1.get_prefix(), " ##\n\n") ++ self.failUnless(l1.was_changed) ++ ++ def testNode(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(200, "bar") ++ n1 = pytree.Node(1000, [l1, l2]) ++ self.assertEqual(n1.type, 1000) ++ self.assertEqual(n1.children, [l1, l2]) ++ ++ def testNodeRepr(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "bar", context=(" ", (1, 0))) ++ n1 = pytree.Node(1000, [l1, l2]) ++ self.assertEqual(repr(n1), ++ "Node(1000, [%s, %s])" % (repr(l1), repr(l2))) ++ ++ def testNodeStr(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "bar", context=(" ", (1, 0))) ++ n1 = pytree.Node(1000, [l1, l2]) ++ self.assertEqual(str(n1), "foo bar") ++ ++ def testNodePrefix(self): ++ l1 = pytree.Leaf(100, "foo") ++ self.assertEqual(l1.get_prefix(), "") ++ n1 = pytree.Node(1000, [l1]) ++ self.assertEqual(n1.get_prefix(), "") ++ n1.set_prefix(" ") ++ self.assertEqual(n1.get_prefix(), " ") ++ self.assertEqual(l1.get_prefix(), " ") ++ ++ def testGetSuffix(self): ++ l1 = pytree.Leaf(100, "foo", prefix="a") ++ l2 = pytree.Leaf(100, "bar", prefix="b") ++ n1 = pytree.Node(1000, [l1, l2]) ++ ++ self.assertEqual(l1.get_suffix(), l2.get_prefix()) ++ self.assertEqual(l2.get_suffix(), "") ++ self.assertEqual(n1.get_suffix(), "") ++ ++ l3 = pytree.Leaf(100, "bar", prefix="c") ++ n2 = pytree.Node(1000, [n1, l3]) ++ ++ self.assertEqual(n1.get_suffix(), l3.get_prefix()) ++ self.assertEqual(l3.get_suffix(), "") ++ self.assertEqual(n2.get_suffix(), "") ++ ++ def testNodeEq(self): ++ n1 = pytree.Node(1000, ()) ++ n2 = pytree.Node(1000, [], context=(" ", (1, 0))) ++ self.assertEqual(n1, n2) ++ n3 = pytree.Node(1001, ()) ++ self.assertNotEqual(n1, n3) ++ ++ def testNodeEqRecursive(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "foo") ++ n1 = pytree.Node(1000, [l1]) ++ n2 = pytree.Node(1000, [l2]) ++ self.assertEqual(n1, n2) ++ l3 = pytree.Leaf(100, "bar") ++ n3 = pytree.Node(1000, [l3]) ++ self.assertNotEqual(n1, n3) ++ ++ def testReplace(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "+") ++ l3 = pytree.Leaf(100, "bar") ++ n1 = pytree.Node(1000, [l1, l2, l3]) ++ self.assertEqual(n1.children, [l1, l2, l3]) ++ self.failUnless(isinstance(n1.children, list)) ++ self.failIf(n1.was_changed) ++ l2new = pytree.Leaf(100, "-") ++ l2.replace(l2new) ++ self.assertEqual(n1.children, [l1, l2new, l3]) ++ self.failUnless(isinstance(n1.children, list)) ++ self.failUnless(n1.was_changed) ++ ++ def testReplaceWithList(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "+") ++ l3 = pytree.Leaf(100, "bar") ++ n1 = pytree.Node(1000, [l1, l2, l3]) ++ ++ l2.replace([pytree.Leaf(100, "*"), pytree.Leaf(100, "*")]) ++ self.assertEqual(str(n1), "foo**bar") ++ self.failUnless(isinstance(n1.children, list)) ++ ++ def testPostOrder(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "bar") ++ n1 = pytree.Node(1000, [l1, l2]) ++ self.assertEqual(list(n1.post_order()), [l1, l2, n1]) ++ ++ def testPreOrder(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "bar") ++ n1 = pytree.Node(1000, [l1, l2]) ++ self.assertEqual(list(n1.pre_order()), [n1, l1, l2]) ++ ++ def testChangedLeaf(self): ++ l1 = pytree.Leaf(100, "f") ++ self.failIf(l1.was_changed) ++ ++ l1.changed() ++ self.failUnless(l1.was_changed) ++ ++ def testChangedNode(self): ++ l1 = pytree.Leaf(100, "f") ++ n1 = pytree.Node(1000, [l1]) ++ self.failIf(n1.was_changed) ++ ++ n1.changed() ++ self.failUnless(n1.was_changed) ++ ++ def testChangedRecursive(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "+") ++ l3 = pytree.Leaf(100, "bar") ++ n1 = pytree.Node(1000, [l1, l2, l3]) ++ n2 = pytree.Node(1000, [n1]) ++ self.failIf(l1.was_changed) ++ self.failIf(n1.was_changed) ++ self.failIf(n2.was_changed) ++ ++ n1.changed() ++ self.failUnless(n1.was_changed) ++ self.failUnless(n2.was_changed) ++ self.failIf(l1.was_changed) ++ ++ def testLeafConstructorPrefix(self): ++ for prefix in ("xyz_", ""): ++ l1 = pytree.Leaf(100, "self", prefix=prefix) ++ self.failUnless(str(l1), prefix + "self") ++ self.assertEqual(l1.get_prefix(), prefix) ++ ++ def testNodeConstructorPrefix(self): ++ for prefix in ("xyz_", ""): ++ l1 = pytree.Leaf(100, "self") ++ l2 = pytree.Leaf(100, "foo", prefix="_") ++ n1 = pytree.Node(1000, [l1, l2], prefix=prefix) ++ self.failUnless(str(n1), prefix + "self_foo") ++ self.assertEqual(n1.get_prefix(), prefix) ++ self.assertEqual(l1.get_prefix(), prefix) ++ self.assertEqual(l2.get_prefix(), "_") ++ ++ def testRemove(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "foo") ++ n1 = pytree.Node(1000, [l1, l2]) ++ n2 = pytree.Node(1000, [n1]) ++ ++ self.assertEqual(n1.remove(), 0) ++ self.assertEqual(n2.children, []) ++ self.assertEqual(l1.parent, n1) ++ self.assertEqual(n1.parent, None) ++ self.assertEqual(n2.parent, None) ++ self.failIf(n1.was_changed) ++ self.failUnless(n2.was_changed) ++ ++ self.assertEqual(l2.remove(), 1) ++ self.assertEqual(l1.remove(), 0) ++ self.assertEqual(n1.children, []) ++ self.assertEqual(l1.parent, None) ++ self.assertEqual(n1.parent, None) ++ self.assertEqual(n2.parent, None) ++ self.failUnless(n1.was_changed) ++ self.failUnless(n2.was_changed) ++ ++ def testRemoveParentless(self): ++ n1 = pytree.Node(1000, []) ++ n1.remove() ++ self.assertEqual(n1.parent, None) ++ ++ l1 = pytree.Leaf(100, "foo") ++ l1.remove() ++ self.assertEqual(l1.parent, None) ++ ++ def testNodeSetChild(self): ++ l1 = pytree.Leaf(100, "foo") ++ n1 = pytree.Node(1000, [l1]) ++ ++ l2 = pytree.Leaf(100, "bar") ++ n1.set_child(0, l2) ++ self.assertEqual(l1.parent, None) ++ self.assertEqual(l2.parent, n1) ++ self.assertEqual(n1.children, [l2]) ++ ++ n2 = pytree.Node(1000, [l1]) ++ n2.set_child(0, n1) ++ self.assertEqual(l1.parent, None) ++ self.assertEqual(n1.parent, n2) ++ self.assertEqual(n2.parent, None) ++ self.assertEqual(n2.children, [n1]) ++ ++ self.assertRaises(IndexError, n1.set_child, 4, l2) ++ # I don't care what it raises, so long as it's an exception ++ self.assertRaises(Exception, n1.set_child, 0, list) ++ ++ def testNodeInsertChild(self): ++ l1 = pytree.Leaf(100, "foo") ++ n1 = pytree.Node(1000, [l1]) ++ ++ l2 = pytree.Leaf(100, "bar") ++ n1.insert_child(0, l2) ++ self.assertEqual(l2.parent, n1) ++ self.assertEqual(n1.children, [l2, l1]) ++ ++ l3 = pytree.Leaf(100, "abc") ++ n1.insert_child(2, l3) ++ self.assertEqual(n1.children, [l2, l1, l3]) ++ ++ # I don't care what it raises, so long as it's an exception ++ self.assertRaises(Exception, n1.insert_child, 0, list) ++ ++ def testNodeAppendChild(self): ++ n1 = pytree.Node(1000, []) ++ ++ l1 = pytree.Leaf(100, "foo") ++ n1.append_child(l1) ++ self.assertEqual(l1.parent, n1) ++ self.assertEqual(n1.children, [l1]) ++ ++ l2 = pytree.Leaf(100, "bar") ++ n1.append_child(l2) ++ self.assertEqual(l2.parent, n1) ++ self.assertEqual(n1.children, [l1, l2]) ++ ++ # I don't care what it raises, so long as it's an exception ++ self.assertRaises(Exception, n1.append_child, list) ++ ++ def testNodeNextSibling(self): ++ n1 = pytree.Node(1000, []) ++ n2 = pytree.Node(1000, []) ++ p1 = pytree.Node(1000, [n1, n2]) ++ ++ self.failUnless(n1.next_sibling is n2) ++ self.assertEqual(n2.next_sibling, None) ++ self.assertEqual(p1.next_sibling, None) ++ ++ def testLeafNextSibling(self): ++ l1 = pytree.Leaf(100, "a") ++ l2 = pytree.Leaf(100, "b") ++ p1 = pytree.Node(1000, [l1, l2]) ++ ++ self.failUnless(l1.next_sibling is l2) ++ self.assertEqual(l2.next_sibling, None) ++ self.assertEqual(p1.next_sibling, None) ++ ++ def testNodePrevSibling(self): ++ n1 = pytree.Node(1000, []) ++ n2 = pytree.Node(1000, []) ++ p1 = pytree.Node(1000, [n1, n2]) ++ ++ self.failUnless(n2.prev_sibling is n1) ++ self.assertEqual(n1.prev_sibling, None) ++ self.assertEqual(p1.prev_sibling, None) ++ ++ def testLeafPrevSibling(self): ++ l1 = pytree.Leaf(100, "a") ++ l2 = pytree.Leaf(100, "b") ++ p1 = pytree.Node(1000, [l1, l2]) ++ ++ self.failUnless(l2.prev_sibling is l1) ++ self.assertEqual(l1.prev_sibling, None) ++ self.assertEqual(p1.prev_sibling, None) ++ ++ ++class TestPatterns(support.TestCase): ++ ++ """Unit tests for tree matching patterns.""" ++ ++ def testBasicPatterns(self): ++ # Build a tree ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "bar") ++ l3 = pytree.Leaf(100, "foo") ++ n1 = pytree.Node(1000, [l1, l2]) ++ n2 = pytree.Node(1000, [l3]) ++ root = pytree.Node(1000, [n1, n2]) ++ # Build a pattern matching a leaf ++ pl = pytree.LeafPattern(100, "foo", name="pl") ++ r = {} ++ self.assertFalse(pl.match(root, results=r)) ++ self.assertEqual(r, {}) ++ self.assertFalse(pl.match(n1, results=r)) ++ self.assertEqual(r, {}) ++ self.assertFalse(pl.match(n2, results=r)) ++ self.assertEqual(r, {}) ++ self.assertTrue(pl.match(l1, results=r)) ++ self.assertEqual(r, {"pl": l1}) ++ r = {} ++ self.assertFalse(pl.match(l2, results=r)) ++ self.assertEqual(r, {}) ++ # Build a pattern matching a node ++ pn = pytree.NodePattern(1000, [pl], name="pn") ++ self.assertFalse(pn.match(root, results=r)) ++ self.assertEqual(r, {}) ++ self.assertFalse(pn.match(n1, results=r)) ++ self.assertEqual(r, {}) ++ self.assertTrue(pn.match(n2, results=r)) ++ self.assertEqual(r, {"pn": n2, "pl": l3}) ++ r = {} ++ self.assertFalse(pn.match(l1, results=r)) ++ self.assertEqual(r, {}) ++ self.assertFalse(pn.match(l2, results=r)) ++ self.assertEqual(r, {}) ++ ++ def testWildcardPatterns(self): ++ # Build a tree for testing ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "bar") ++ l3 = pytree.Leaf(100, "foo") ++ n1 = pytree.Node(1000, [l1, l2]) ++ n2 = pytree.Node(1000, [l3]) ++ root = pytree.Node(1000, [n1, n2]) ++ # Build a pattern ++ pl = pytree.LeafPattern(100, "foo", name="pl") ++ pn = pytree.NodePattern(1000, [pl], name="pn") ++ pw = pytree.WildcardPattern([[pn], [pl, pl]], name="pw") ++ r = {} ++ self.assertFalse(pw.match_seq([root], r)) ++ self.assertEqual(r, {}) ++ self.assertFalse(pw.match_seq([n1], r)) ++ self.assertEqual(r, {}) ++ self.assertTrue(pw.match_seq([n2], r)) ++ # These are easier to debug ++ self.assertEqual(sorted(r.keys()), ["pl", "pn", "pw"]) ++ self.assertEqual(r["pl"], l1) ++ self.assertEqual(r["pn"], n2) ++ self.assertEqual(r["pw"], [n2]) ++ # But this is equivalent ++ self.assertEqual(r, {"pl": l1, "pn": n2, "pw": [n2]}) ++ r = {} ++ self.assertTrue(pw.match_seq([l1, l3], r)) ++ self.assertEqual(r, {"pl": l3, "pw": [l1, l3]}) ++ self.assert_(r["pl"] is l3) ++ r = {} ++ ++ def testGenerateMatches(self): ++ la = pytree.Leaf(1, "a") ++ lb = pytree.Leaf(1, "b") ++ lc = pytree.Leaf(1, "c") ++ ld = pytree.Leaf(1, "d") ++ le = pytree.Leaf(1, "e") ++ lf = pytree.Leaf(1, "f") ++ leaves = [la, lb, lc, ld, le, lf] ++ root = pytree.Node(1000, leaves) ++ pa = pytree.LeafPattern(1, "a", "pa") ++ pb = pytree.LeafPattern(1, "b", "pb") ++ pc = pytree.LeafPattern(1, "c", "pc") ++ pd = pytree.LeafPattern(1, "d", "pd") ++ pe = pytree.LeafPattern(1, "e", "pe") ++ pf = pytree.LeafPattern(1, "f", "pf") ++ pw = pytree.WildcardPattern([[pa, pb, pc], [pd, pe], ++ [pa, pb], [pc, pd], [pe, pf]], ++ min=1, max=4, name="pw") ++ self.assertEqual([x[0] for x in pw.generate_matches(leaves)], ++ [3, 5, 2, 4, 6]) ++ pr = pytree.NodePattern(type=1000, content=[pw], name="pr") ++ matches = list(pytree.generate_matches([pr], [root])) ++ self.assertEqual(len(matches), 1) ++ c, r = matches[0] ++ self.assertEqual(c, 1) ++ self.assertEqual(str(r["pr"]), "abcdef") ++ self.assertEqual(r["pw"], [la, lb, lc, ld, le, lf]) ++ for c in "abcdef": ++ self.assertEqual(r["p" + c], pytree.Leaf(1, c)) ++ ++ def testHasKeyExample(self): ++ pattern = pytree.NodePattern(331, ++ (pytree.LeafPattern(7), ++ pytree.WildcardPattern(name="args"), ++ pytree.LeafPattern(8))) ++ l1 = pytree.Leaf(7, "(") ++ l2 = pytree.Leaf(3, "x") ++ l3 = pytree.Leaf(8, ")") ++ node = pytree.Node(331, [l1, l2, l3]) ++ r = {} ++ self.assert_(pattern.match(node, r)) ++ self.assertEqual(r["args"], [l2]) ++ ++ ++if __name__ == "__main__": ++ import __main__ ++ support.run_all_tests(__main__) +diff -r 531f2e948299 refactor/tests/.svn/text-base/test_refactor.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/text-base/test_refactor.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,168 @@ ++""" ++Unit tests for refactor.py. ++""" ++ ++import sys ++import os ++import operator ++import StringIO ++import tempfile ++import unittest ++ ++from lib2to3 import refactor, pygram, fixer_base ++ ++from . import support ++ ++ ++FIXER_DIR = os.path.join(os.path.dirname(__file__), "data/fixers") ++ ++sys.path.append(FIXER_DIR) ++try: ++ _DEFAULT_FIXERS = refactor.get_fixers_from_package("myfixes") ++finally: ++ sys.path.pop() ++ ++class TestRefactoringTool(unittest.TestCase): ++ ++ def setUp(self): ++ sys.path.append(FIXER_DIR) ++ ++ def tearDown(self): ++ sys.path.pop() ++ ++ def check_instances(self, instances, classes): ++ for inst, cls in zip(instances, classes): ++ if not isinstance(inst, cls): ++ self.fail("%s are not instances of %s" % instances, classes) ++ ++ def rt(self, options=None, fixers=_DEFAULT_FIXERS, explicit=None): ++ return refactor.RefactoringTool(fixers, options, explicit) ++ ++ def test_print_function_option(self): ++ gram = pygram.python_grammar ++ save = gram.keywords["print"] ++ try: ++ rt = self.rt({"print_function" : True}) ++ self.assertRaises(KeyError, operator.itemgetter("print"), ++ gram.keywords) ++ finally: ++ gram.keywords["print"] = save ++ ++ def test_fixer_loading_helpers(self): ++ contents = ["explicit", "first", "last", "parrot", "preorder"] ++ non_prefixed = refactor.get_all_fix_names("myfixes") ++ prefixed = refactor.get_all_fix_names("myfixes", False) ++ full_names = refactor.get_fixers_from_package("myfixes") ++ self.assertEqual(prefixed, ["fix_" + name for name in contents]) ++ self.assertEqual(non_prefixed, contents) ++ self.assertEqual(full_names, ++ ["myfixes.fix_" + name for name in contents]) ++ ++ def test_get_headnode_dict(self): ++ class NoneFix(fixer_base.BaseFix): ++ PATTERN = None ++ ++ class FileInputFix(fixer_base.BaseFix): ++ PATTERN = "file_input< any * >" ++ ++ no_head = NoneFix({}, []) ++ with_head = FileInputFix({}, []) ++ d = refactor.get_headnode_dict([no_head, with_head]) ++ expected = {None: [no_head], ++ pygram.python_symbols.file_input : [with_head]} ++ self.assertEqual(d, expected) ++ ++ def test_fixer_loading(self): ++ from myfixes.fix_first import FixFirst ++ from myfixes.fix_last import FixLast ++ from myfixes.fix_parrot import FixParrot ++ from myfixes.fix_preorder import FixPreorder ++ ++ rt = self.rt() ++ pre, post = rt.get_fixers() ++ ++ self.check_instances(pre, [FixPreorder]) ++ self.check_instances(post, [FixFirst, FixParrot, FixLast]) ++ ++ def test_naughty_fixers(self): ++ self.assertRaises(ImportError, self.rt, fixers=["not_here"]) ++ self.assertRaises(refactor.FixerError, self.rt, fixers=["no_fixer_cls"]) ++ self.assertRaises(refactor.FixerError, self.rt, fixers=["bad_order"]) ++ ++ def test_refactor_string(self): ++ rt = self.rt() ++ input = "def parrot(): pass\n\n" ++ tree = rt.refactor_string(input, "") ++ self.assertNotEqual(str(tree), input) ++ ++ input = "def f(): pass\n\n" ++ tree = rt.refactor_string(input, "") ++ self.assertEqual(str(tree), input) ++ ++ def test_refactor_stdin(self): ++ ++ class MyRT(refactor.RefactoringTool): ++ ++ def print_output(self, lines): ++ diff_lines.extend(lines) ++ ++ diff_lines = [] ++ rt = MyRT(_DEFAULT_FIXERS) ++ save = sys.stdin ++ sys.stdin = StringIO.StringIO("def parrot(): pass\n\n") ++ try: ++ rt.refactor_stdin() ++ finally: ++ sys.stdin = save ++ expected = """--- (original) +++++ (refactored) ++@@ -1,2 +1,2 @@ ++-def parrot(): pass +++def cheese(): pass""".splitlines() ++ self.assertEqual(diff_lines[:-1], expected) ++ ++ def test_refactor_file(self): ++ test_file = os.path.join(FIXER_DIR, "parrot_example.py") ++ old_contents = open(test_file, "r").read() ++ rt = self.rt() ++ ++ rt.refactor_file(test_file) ++ self.assertEqual(old_contents, open(test_file, "r").read()) ++ ++ rt.refactor_file(test_file, True) ++ try: ++ self.assertNotEqual(old_contents, open(test_file, "r").read()) ++ finally: ++ open(test_file, "w").write(old_contents) ++ ++ def test_refactor_docstring(self): ++ rt = self.rt() ++ ++ def example(): ++ """ ++ >>> example() ++ 42 ++ """ ++ out = rt.refactor_docstring(example.__doc__, "") ++ self.assertEqual(out, example.__doc__) ++ ++ def parrot(): ++ """ ++ >>> def parrot(): ++ ... return 43 ++ """ ++ out = rt.refactor_docstring(parrot.__doc__, "") ++ self.assertNotEqual(out, parrot.__doc__) ++ ++ def test_explicit(self): ++ from myfixes.fix_explicit import FixExplicit ++ ++ rt = self.rt(fixers=["myfixes.fix_explicit"]) ++ self.assertEqual(len(rt.post_order), 0) ++ ++ rt = self.rt(explicit=["myfixes.fix_explicit"]) ++ for fix in rt.post_order: ++ if isinstance(fix, FixExplicit): ++ break ++ else: ++ self.fail("explicit fixer not loaded") +diff -r 531f2e948299 refactor/tests/.svn/text-base/test_util.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/.svn/text-base/test_util.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,559 @@ ++#!/usr/bin/env python2.5 ++""" Test suite for the code in fixes.util """ ++# Author: Collin Winter ++ ++# Testing imports ++from . import support ++ ++# Python imports ++import os.path ++ ++# Local imports ++from .. import pytree ++from .. import fixer_util ++from ..fixer_util import Attr, Name ++ ++ ++def parse(code, strip_levels=0): ++ # The topmost node is file_input, which we don't care about. ++ # The next-topmost node is a *_stmt node, which we also don't care about ++ tree = support.parse_string(code) ++ for i in range(strip_levels): ++ tree = tree.children[0] ++ tree.parent = None ++ return tree ++ ++class MacroTestCase(support.TestCase): ++ def assertStr(self, node, string): ++ if isinstance(node, (tuple, list)): ++ node = pytree.Node(fixer_util.syms.simple_stmt, node) ++ self.assertEqual(str(node), string) ++ ++ ++class Test_is_tuple(support.TestCase): ++ def is_tuple(self, string): ++ return fixer_util.is_tuple(parse(string, strip_levels=2)) ++ ++ def test_valid(self): ++ self.failUnless(self.is_tuple("(a, b)")) ++ self.failUnless(self.is_tuple("(a, (b, c))")) ++ self.failUnless(self.is_tuple("((a, (b, c)),)")) ++ self.failUnless(self.is_tuple("(a,)")) ++ self.failUnless(self.is_tuple("()")) ++ ++ def test_invalid(self): ++ self.failIf(self.is_tuple("(a)")) ++ self.failIf(self.is_tuple("('foo') % (b, c)")) ++ ++ ++class Test_is_list(support.TestCase): ++ def is_list(self, string): ++ return fixer_util.is_list(parse(string, strip_levels=2)) ++ ++ def test_valid(self): ++ self.failUnless(self.is_list("[]")) ++ self.failUnless(self.is_list("[a]")) ++ self.failUnless(self.is_list("[a, b]")) ++ self.failUnless(self.is_list("[a, [b, c]]")) ++ self.failUnless(self.is_list("[[a, [b, c]],]")) ++ ++ def test_invalid(self): ++ self.failIf(self.is_list("[]+[]")) ++ ++ ++class Test_Attr(MacroTestCase): ++ def test(self): ++ call = parse("foo()", strip_levels=2) ++ ++ self.assertStr(Attr(Name("a"), Name("b")), "a.b") ++ self.assertStr(Attr(call, Name("b")), "foo().b") ++ ++ def test_returns(self): ++ attr = Attr(Name("a"), Name("b")) ++ self.assertEqual(type(attr), list) ++ ++ ++class Test_Name(MacroTestCase): ++ def test(self): ++ self.assertStr(Name("a"), "a") ++ self.assertStr(Name("foo.foo().bar"), "foo.foo().bar") ++ self.assertStr(Name("a", prefix="b"), "ba") ++ ++ ++class Test_does_tree_import(support.TestCase): ++ def _find_bind_rec(self, name, node): ++ # Search a tree for a binding -- used to find the starting ++ # point for these tests. ++ c = fixer_util.find_binding(name, node) ++ if c: return c ++ for child in node.children: ++ c = self._find_bind_rec(name, child) ++ if c: return c ++ ++ def does_tree_import(self, package, name, string): ++ node = parse(string) ++ # Find the binding of start -- that's what we'll go from ++ node = self._find_bind_rec('start', node) ++ return fixer_util.does_tree_import(package, name, node) ++ ++ def try_with(self, string): ++ failing_tests = (("a", "a", "from a import b"), ++ ("a.d", "a", "from a.d import b"), ++ ("d.a", "a", "from d.a import b"), ++ (None, "a", "import b"), ++ (None, "a", "import b, c, d")) ++ for package, name, import_ in failing_tests: ++ n = self.does_tree_import(package, name, import_ + "\n" + string) ++ self.failIf(n) ++ n = self.does_tree_import(package, name, string + "\n" + import_) ++ self.failIf(n) ++ ++ passing_tests = (("a", "a", "from a import a"), ++ ("x", "a", "from x import a"), ++ ("x", "a", "from x import b, c, a, d"), ++ ("x.b", "a", "from x.b import a"), ++ ("x.b", "a", "from x.b import b, c, a, d"), ++ (None, "a", "import a"), ++ (None, "a", "import b, c, a, d")) ++ for package, name, import_ in passing_tests: ++ n = self.does_tree_import(package, name, import_ + "\n" + string) ++ self.failUnless(n) ++ n = self.does_tree_import(package, name, string + "\n" + import_) ++ self.failUnless(n) ++ ++ def test_in_function(self): ++ self.try_with("def foo():\n\tbar.baz()\n\tstart=3") ++ ++class Test_find_binding(support.TestCase): ++ def find_binding(self, name, string, package=None): ++ return fixer_util.find_binding(name, parse(string), package) ++ ++ def test_simple_assignment(self): ++ self.failUnless(self.find_binding("a", "a = b")) ++ self.failUnless(self.find_binding("a", "a = [b, c, d]")) ++ self.failUnless(self.find_binding("a", "a = foo()")) ++ self.failUnless(self.find_binding("a", "a = foo().foo.foo[6][foo]")) ++ self.failIf(self.find_binding("a", "foo = a")) ++ self.failIf(self.find_binding("a", "foo = (a, b, c)")) ++ ++ def test_tuple_assignment(self): ++ self.failUnless(self.find_binding("a", "(a,) = b")) ++ self.failUnless(self.find_binding("a", "(a, b, c) = [b, c, d]")) ++ self.failUnless(self.find_binding("a", "(c, (d, a), b) = foo()")) ++ self.failUnless(self.find_binding("a", "(a, b) = foo().foo[6][foo]")) ++ self.failIf(self.find_binding("a", "(foo, b) = (b, a)")) ++ self.failIf(self.find_binding("a", "(foo, (b, c)) = (a, b, c)")) ++ ++ def test_list_assignment(self): ++ self.failUnless(self.find_binding("a", "[a] = b")) ++ self.failUnless(self.find_binding("a", "[a, b, c] = [b, c, d]")) ++ self.failUnless(self.find_binding("a", "[c, [d, a], b] = foo()")) ++ self.failUnless(self.find_binding("a", "[a, b] = foo().foo[a][foo]")) ++ self.failIf(self.find_binding("a", "[foo, b] = (b, a)")) ++ self.failIf(self.find_binding("a", "[foo, [b, c]] = (a, b, c)")) ++ ++ def test_invalid_assignments(self): ++ self.failIf(self.find_binding("a", "foo.a = 5")) ++ self.failIf(self.find_binding("a", "foo[a] = 5")) ++ self.failIf(self.find_binding("a", "foo(a) = 5")) ++ self.failIf(self.find_binding("a", "foo(a, b) = 5")) ++ ++ def test_simple_import(self): ++ self.failUnless(self.find_binding("a", "import a")) ++ self.failUnless(self.find_binding("a", "import b, c, a, d")) ++ self.failIf(self.find_binding("a", "import b")) ++ self.failIf(self.find_binding("a", "import b, c, d")) ++ ++ def test_from_import(self): ++ self.failUnless(self.find_binding("a", "from x import a")) ++ self.failUnless(self.find_binding("a", "from a import a")) ++ self.failUnless(self.find_binding("a", "from x import b, c, a, d")) ++ self.failUnless(self.find_binding("a", "from x.b import a")) ++ self.failUnless(self.find_binding("a", "from x.b import b, c, a, d")) ++ self.failIf(self.find_binding("a", "from a import b")) ++ self.failIf(self.find_binding("a", "from a.d import b")) ++ self.failIf(self.find_binding("a", "from d.a import b")) ++ ++ def test_import_as(self): ++ self.failUnless(self.find_binding("a", "import b as a")) ++ self.failUnless(self.find_binding("a", "import b as a, c, a as f, d")) ++ self.failIf(self.find_binding("a", "import a as f")) ++ self.failIf(self.find_binding("a", "import b, c as f, d as e")) ++ ++ def test_from_import_as(self): ++ self.failUnless(self.find_binding("a", "from x import b as a")) ++ self.failUnless(self.find_binding("a", "from x import g as a, d as b")) ++ self.failUnless(self.find_binding("a", "from x.b import t as a")) ++ self.failUnless(self.find_binding("a", "from x.b import g as a, d")) ++ self.failIf(self.find_binding("a", "from a import b as t")) ++ self.failIf(self.find_binding("a", "from a.d import b as t")) ++ self.failIf(self.find_binding("a", "from d.a import b as t")) ++ ++ def test_simple_import_with_package(self): ++ self.failUnless(self.find_binding("b", "import b")) ++ self.failUnless(self.find_binding("b", "import b, c, d")) ++ self.failIf(self.find_binding("b", "import b", "b")) ++ self.failIf(self.find_binding("b", "import b, c, d", "c")) ++ ++ def test_from_import_with_package(self): ++ self.failUnless(self.find_binding("a", "from x import a", "x")) ++ self.failUnless(self.find_binding("a", "from a import a", "a")) ++ self.failUnless(self.find_binding("a", "from x import *", "x")) ++ self.failUnless(self.find_binding("a", "from x import b, c, a, d", "x")) ++ self.failUnless(self.find_binding("a", "from x.b import a", "x.b")) ++ self.failUnless(self.find_binding("a", "from x.b import *", "x.b")) ++ self.failUnless(self.find_binding("a", "from x.b import b, c, a, d", "x.b")) ++ self.failIf(self.find_binding("a", "from a import b", "a")) ++ self.failIf(self.find_binding("a", "from a.d import b", "a.d")) ++ self.failIf(self.find_binding("a", "from d.a import b", "a.d")) ++ self.failIf(self.find_binding("a", "from x.y import *", "a.b")) ++ ++ def test_import_as_with_package(self): ++ self.failIf(self.find_binding("a", "import b.c as a", "b.c")) ++ self.failIf(self.find_binding("a", "import a as f", "f")) ++ self.failIf(self.find_binding("a", "import a as f", "a")) ++ ++ def test_from_import_as_with_package(self): ++ # Because it would take a lot of special-case code in the fixers ++ # to deal with from foo import bar as baz, we'll simply always ++ # fail if there is an "from ... import ... as ..." ++ self.failIf(self.find_binding("a", "from x import b as a", "x")) ++ self.failIf(self.find_binding("a", "from x import g as a, d as b", "x")) ++ self.failIf(self.find_binding("a", "from x.b import t as a", "x.b")) ++ self.failIf(self.find_binding("a", "from x.b import g as a, d", "x.b")) ++ self.failIf(self.find_binding("a", "from a import b as t", "a")) ++ self.failIf(self.find_binding("a", "from a import b as t", "b")) ++ self.failIf(self.find_binding("a", "from a import b as t", "t")) ++ ++ def test_function_def(self): ++ self.failUnless(self.find_binding("a", "def a(): pass")) ++ self.failUnless(self.find_binding("a", "def a(b, c, d): pass")) ++ self.failUnless(self.find_binding("a", "def a(): b = 7")) ++ self.failIf(self.find_binding("a", "def d(b, (c, a), e): pass")) ++ self.failIf(self.find_binding("a", "def d(a=7): pass")) ++ self.failIf(self.find_binding("a", "def d(a): pass")) ++ self.failIf(self.find_binding("a", "def d(): a = 7")) ++ ++ s = """ ++ def d(): ++ def a(): ++ pass""" ++ self.failIf(self.find_binding("a", s)) ++ ++ def test_class_def(self): ++ self.failUnless(self.find_binding("a", "class a: pass")) ++ self.failUnless(self.find_binding("a", "class a(): pass")) ++ self.failUnless(self.find_binding("a", "class a(b): pass")) ++ self.failUnless(self.find_binding("a", "class a(b, c=8): pass")) ++ self.failIf(self.find_binding("a", "class d: pass")) ++ self.failIf(self.find_binding("a", "class d(a): pass")) ++ self.failIf(self.find_binding("a", "class d(b, a=7): pass")) ++ self.failIf(self.find_binding("a", "class d(b, *a): pass")) ++ self.failIf(self.find_binding("a", "class d(b, **a): pass")) ++ self.failIf(self.find_binding("a", "class d: a = 7")) ++ ++ s = """ ++ class d(): ++ class a(): ++ pass""" ++ self.failIf(self.find_binding("a", s)) ++ ++ def test_for(self): ++ self.failUnless(self.find_binding("a", "for a in r: pass")) ++ self.failUnless(self.find_binding("a", "for a, b in r: pass")) ++ self.failUnless(self.find_binding("a", "for (a, b) in r: pass")) ++ self.failUnless(self.find_binding("a", "for c, (a,) in r: pass")) ++ self.failUnless(self.find_binding("a", "for c, (a, b) in r: pass")) ++ self.failUnless(self.find_binding("a", "for c in r: a = c")) ++ self.failIf(self.find_binding("a", "for c in a: pass")) ++ ++ def test_for_nested(self): ++ s = """ ++ for b in r: ++ for a in b: ++ pass""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ for b in r: ++ for a, c in b: ++ pass""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ for b in r: ++ for (a, c) in b: ++ pass""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ for b in r: ++ for (a,) in b: ++ pass""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ for b in r: ++ for c, (a, d) in b: ++ pass""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ for b in r: ++ for c in b: ++ a = 7""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ for b in r: ++ for c in b: ++ d = a""" ++ self.failIf(self.find_binding("a", s)) ++ ++ s = """ ++ for b in r: ++ for c in a: ++ d = 7""" ++ self.failIf(self.find_binding("a", s)) ++ ++ def test_if(self): ++ self.failUnless(self.find_binding("a", "if b in r: a = c")) ++ self.failIf(self.find_binding("a", "if a in r: d = e")) ++ ++ def test_if_nested(self): ++ s = """ ++ if b in r: ++ if c in d: ++ a = c""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ if b in r: ++ if c in d: ++ c = a""" ++ self.failIf(self.find_binding("a", s)) ++ ++ def test_while(self): ++ self.failUnless(self.find_binding("a", "while b in r: a = c")) ++ self.failIf(self.find_binding("a", "while a in r: d = e")) ++ ++ def test_while_nested(self): ++ s = """ ++ while b in r: ++ while c in d: ++ a = c""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ while b in r: ++ while c in d: ++ c = a""" ++ self.failIf(self.find_binding("a", s)) ++ ++ def test_try_except(self): ++ s = """ ++ try: ++ a = 6 ++ except: ++ b = 8""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ except: ++ a = 6""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ except KeyError: ++ pass ++ except: ++ a = 6""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ except: ++ b = 6""" ++ self.failIf(self.find_binding("a", s)) ++ ++ def test_try_except_nested(self): ++ s = """ ++ try: ++ try: ++ a = 6 ++ except: ++ pass ++ except: ++ b = 8""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ except: ++ try: ++ a = 6 ++ except: ++ pass""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ except: ++ try: ++ pass ++ except: ++ a = 6""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ try: ++ b = 8 ++ except KeyError: ++ pass ++ except: ++ a = 6 ++ except: ++ pass""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ pass ++ except: ++ try: ++ b = 8 ++ except KeyError: ++ pass ++ except: ++ a = 6""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ except: ++ b = 6""" ++ self.failIf(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ try: ++ b = 8 ++ except: ++ c = d ++ except: ++ try: ++ b = 6 ++ except: ++ t = 8 ++ except: ++ o = y""" ++ self.failIf(self.find_binding("a", s)) ++ ++ def test_try_except_finally(self): ++ s = """ ++ try: ++ c = 6 ++ except: ++ b = 8 ++ finally: ++ a = 9""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ finally: ++ a = 6""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ finally: ++ b = 6""" ++ self.failIf(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ except: ++ b = 9 ++ finally: ++ b = 6""" ++ self.failIf(self.find_binding("a", s)) ++ ++ def test_try_except_finally_nested(self): ++ s = """ ++ try: ++ c = 6 ++ except: ++ b = 8 ++ finally: ++ try: ++ a = 9 ++ except: ++ b = 9 ++ finally: ++ c = 9""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ finally: ++ try: ++ pass ++ finally: ++ a = 6""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ finally: ++ try: ++ b = 6 ++ finally: ++ b = 7""" ++ self.failIf(self.find_binding("a", s)) ++ ++class Test_touch_import(support.TestCase): ++ ++ def test_after_docstring(self): ++ node = parse('"""foo"""\nbar()') ++ fixer_util.touch_import(None, "foo", node) ++ self.assertEqual(str(node), '"""foo"""\nimport foo\nbar()\n\n') ++ ++ def test_after_imports(self): ++ node = parse('"""foo"""\nimport bar\nbar()') ++ fixer_util.touch_import(None, "foo", node) ++ self.assertEqual(str(node), '"""foo"""\nimport bar\nimport foo\nbar()\n\n') ++ ++ def test_beginning(self): ++ node = parse('bar()') ++ fixer_util.touch_import(None, "foo", node) ++ self.assertEqual(str(node), 'import foo\nbar()\n\n') ++ ++ 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') ++ ++ def test_name_import(self): ++ node = parse('bar()') ++ fixer_util.touch_import(None, "cgi", node) ++ self.assertEqual(str(node), 'import cgi\nbar()\n\n') ++ ++ ++if __name__ == "__main__": ++ import __main__ ++ support.run_all_tests(__main__) +diff -r 531f2e948299 refactor/tests/__init__.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/__init__.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,24 @@ ++"""Make tests/ into a package. This allows us to "import tests" and ++have tests.all_tests be a TestSuite representing all test cases ++from all test_*.py files in tests/.""" ++# Author: Collin Winter ++ ++import os ++import os.path ++import unittest ++import types ++ ++from . import support ++ ++all_tests = unittest.TestSuite() ++ ++tests_dir = os.path.join(os.path.dirname(__file__), '..', 'tests') ++tests = [t[0:-3] for t in os.listdir(tests_dir) ++ if t.startswith('test_') and t.endswith('.py')] ++ ++loader = unittest.TestLoader() ++ ++for t in tests: ++ __import__("",globals(),locals(),[t],level=1) ++ mod = globals()[t] ++ all_tests.addTests(loader.loadTestsFromModule(mod)) +diff -r 531f2e948299 refactor/tests/data/.svn/all-wcprops +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/.svn/all-wcprops Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,29 @@ ++K 25 ++svn:wc:ra_dav:version-url ++V 62 ++/projects/!svn/ver/67993/sandbox/trunk/2to3/lib2to3/tests/data ++END ++infinite_recursion.py ++K 25 ++svn:wc:ra_dav:version-url ++V 84 ++/projects/!svn/ver/67433/sandbox/trunk/2to3/lib2to3/tests/data/infinite_recursion.py ++END ++py2_test_grammar.py ++K 25 ++svn:wc:ra_dav:version-url ++V 82 ++/projects/!svn/ver/66191/sandbox/trunk/2to3/lib2to3/tests/data/py2_test_grammar.py ++END ++py3_test_grammar.py ++K 25 ++svn:wc:ra_dav:version-url ++V 82 ++/projects/!svn/ver/67993/sandbox/trunk/2to3/lib2to3/tests/data/py3_test_grammar.py ++END ++README ++K 25 ++svn:wc:ra_dav:version-url ++V 69 ++/projects/!svn/ver/66805/sandbox/trunk/2to3/lib2to3/tests/data/README ++END +diff -r 531f2e948299 refactor/tests/data/.svn/dir-prop-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/.svn/dir-prop-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,7 @@ ++K 10 ++svn:ignore ++V 10 ++*.py[co] ++ ++ ++END +diff -r 531f2e948299 refactor/tests/data/.svn/entries +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/.svn/entries Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,167 @@ ++9 ++ ++dir ++70822 ++http://svn.python.org/projects/sandbox/trunk/2to3/lib2to3/tests/data ++http://svn.python.org/projects ++ ++ ++ ++2008-12-28T21:04:32.707707Z ++67993 ++benjamin.peterson ++has-props ++ ++svn:special svn:externals svn:needs-lock ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++6015fed2-1504-0410-9fe1-9d1591cc4771 ++ ++fixers ++dir ++ ++infinite_recursion.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++1814d487c988fd5798c42a2f0cd95ddf ++2008-11-28T23:18:48.744865Z ++67433 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++93071 ++ ++py2_test_grammar.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++e942fb49c8000cb9a6b412726618c3a1 ++2008-09-03T22:00:52.351755Z ++66191 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++30527 ++ ++py3_test_grammar.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++420f3727371001b7eeeb3375fbfa95aa ++2008-12-28T21:04:32.707707Z ++67993 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++29861 ++ ++README ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++49f64b8dc7eb5e8d1d21281604faaaa7 ++2008-10-05T01:11:02.545241Z ++66805 ++benjamin.peterson ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++404 ++ +diff -r 531f2e948299 refactor/tests/data/.svn/format +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/.svn/format Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,1 @@ ++9 +diff -r 531f2e948299 refactor/tests/data/.svn/prop-base/infinite_recursion.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/.svn/prop-base/infinite_recursion.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,5 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++END +diff -r 531f2e948299 refactor/tests/data/.svn/prop-base/py2_test_grammar.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/.svn/prop-base/py2_test_grammar.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/tests/data/.svn/prop-base/py3_test_grammar.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/.svn/prop-base/py3_test_grammar.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/tests/data/.svn/text-base/README.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/.svn/text-base/README.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,6 @@ ++In this directory: ++- py2_test_grammar.py -- test file that exercises most/all of Python 2.x's grammar. ++- py3_test_grammar.py -- test file that exercises most/all of Python 3.x's grammar. ++- infinite_recursion.py -- test file that causes lib2to3's faster recursive pattern matching ++ scheme to fail, but passes when lib2to3 falls back to iterative pattern matching. ++- fixes/ -- for use by test_refactor.py +diff -r 531f2e948299 refactor/tests/data/.svn/text-base/infinite_recursion.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/.svn/text-base/infinite_recursion.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,2669 @@ ++# This file is used to verify that 2to3 falls back to a slower, iterative pattern matching ++# scheme in the event that the faster recursive system fails due to infinite recursion. ++from ctypes import * ++STRING = c_char_p ++ ++ ++OSUnknownByteOrder = 0 ++UIT_PROMPT = 1 ++P_PGID = 2 ++P_PID = 1 ++UIT_ERROR = 5 ++UIT_INFO = 4 ++UIT_NONE = 0 ++P_ALL = 0 ++UIT_VERIFY = 2 ++OSBigEndian = 2 ++UIT_BOOLEAN = 3 ++OSLittleEndian = 1 ++__darwin_nl_item = c_int ++__darwin_wctrans_t = c_int ++__darwin_wctype_t = c_ulong ++__int8_t = c_byte ++__uint8_t = c_ubyte ++__int16_t = c_short ++__uint16_t = c_ushort ++__int32_t = c_int ++__uint32_t = c_uint ++__int64_t = c_longlong ++__uint64_t = c_ulonglong ++__darwin_intptr_t = c_long ++__darwin_natural_t = c_uint ++__darwin_ct_rune_t = c_int ++class __mbstate_t(Union): ++ pass ++__mbstate_t._pack_ = 4 ++__mbstate_t._fields_ = [ ++ ('__mbstate8', c_char * 128), ++ ('_mbstateL', c_longlong), ++] ++assert sizeof(__mbstate_t) == 128, sizeof(__mbstate_t) ++assert alignment(__mbstate_t) == 4, alignment(__mbstate_t) ++__darwin_mbstate_t = __mbstate_t ++__darwin_ptrdiff_t = c_int ++__darwin_size_t = c_ulong ++__darwin_va_list = STRING ++__darwin_wchar_t = c_int ++__darwin_rune_t = __darwin_wchar_t ++__darwin_wint_t = c_int ++__darwin_clock_t = c_ulong ++__darwin_socklen_t = __uint32_t ++__darwin_ssize_t = c_long ++__darwin_time_t = c_long ++sig_atomic_t = c_int ++class sigcontext(Structure): ++ pass ++sigcontext._fields_ = [ ++ ('sc_onstack', c_int), ++ ('sc_mask', c_int), ++ ('sc_eax', c_uint), ++ ('sc_ebx', c_uint), ++ ('sc_ecx', c_uint), ++ ('sc_edx', c_uint), ++ ('sc_edi', c_uint), ++ ('sc_esi', c_uint), ++ ('sc_ebp', c_uint), ++ ('sc_esp', c_uint), ++ ('sc_ss', c_uint), ++ ('sc_eflags', c_uint), ++ ('sc_eip', c_uint), ++ ('sc_cs', c_uint), ++ ('sc_ds', c_uint), ++ ('sc_es', c_uint), ++ ('sc_fs', c_uint), ++ ('sc_gs', c_uint), ++] ++assert sizeof(sigcontext) == 72, sizeof(sigcontext) ++assert alignment(sigcontext) == 4, alignment(sigcontext) ++u_int8_t = c_ubyte ++u_int16_t = c_ushort ++u_int32_t = c_uint ++u_int64_t = c_ulonglong ++int32_t = c_int ++register_t = int32_t ++user_addr_t = u_int64_t ++user_size_t = u_int64_t ++int64_t = c_longlong ++user_ssize_t = int64_t ++user_long_t = int64_t ++user_ulong_t = u_int64_t ++user_time_t = int64_t ++syscall_arg_t = u_int64_t ++ ++# values for unnamed enumeration ++class aes_key_st(Structure): ++ pass ++aes_key_st._fields_ = [ ++ ('rd_key', c_ulong * 60), ++ ('rounds', c_int), ++] ++assert sizeof(aes_key_st) == 244, sizeof(aes_key_st) ++assert alignment(aes_key_st) == 4, alignment(aes_key_st) ++AES_KEY = aes_key_st ++class asn1_ctx_st(Structure): ++ pass ++asn1_ctx_st._fields_ = [ ++ ('p', POINTER(c_ubyte)), ++ ('eos', c_int), ++ ('error', c_int), ++ ('inf', c_int), ++ ('tag', c_int), ++ ('xclass', c_int), ++ ('slen', c_long), ++ ('max', POINTER(c_ubyte)), ++ ('q', POINTER(c_ubyte)), ++ ('pp', POINTER(POINTER(c_ubyte))), ++ ('line', c_int), ++] ++assert sizeof(asn1_ctx_st) == 44, sizeof(asn1_ctx_st) ++assert alignment(asn1_ctx_st) == 4, alignment(asn1_ctx_st) ++ASN1_CTX = asn1_ctx_st ++class asn1_object_st(Structure): ++ pass ++asn1_object_st._fields_ = [ ++ ('sn', STRING), ++ ('ln', STRING), ++ ('nid', c_int), ++ ('length', c_int), ++ ('data', POINTER(c_ubyte)), ++ ('flags', c_int), ++] ++assert sizeof(asn1_object_st) == 24, sizeof(asn1_object_st) ++assert alignment(asn1_object_st) == 4, alignment(asn1_object_st) ++ASN1_OBJECT = asn1_object_st ++class asn1_string_st(Structure): ++ pass ++asn1_string_st._fields_ = [ ++ ('length', c_int), ++ ('type', c_int), ++ ('data', POINTER(c_ubyte)), ++ ('flags', c_long), ++] ++assert sizeof(asn1_string_st) == 16, sizeof(asn1_string_st) ++assert alignment(asn1_string_st) == 4, alignment(asn1_string_st) ++ASN1_STRING = asn1_string_st ++class ASN1_ENCODING_st(Structure): ++ pass ++ASN1_ENCODING_st._fields_ = [ ++ ('enc', POINTER(c_ubyte)), ++ ('len', c_long), ++ ('modified', c_int), ++] ++assert sizeof(ASN1_ENCODING_st) == 12, sizeof(ASN1_ENCODING_st) ++assert alignment(ASN1_ENCODING_st) == 4, alignment(ASN1_ENCODING_st) ++ASN1_ENCODING = ASN1_ENCODING_st ++class asn1_string_table_st(Structure): ++ pass ++asn1_string_table_st._fields_ = [ ++ ('nid', c_int), ++ ('minsize', c_long), ++ ('maxsize', c_long), ++ ('mask', c_ulong), ++ ('flags', c_ulong), ++] ++assert sizeof(asn1_string_table_st) == 20, sizeof(asn1_string_table_st) ++assert alignment(asn1_string_table_st) == 4, alignment(asn1_string_table_st) ++ASN1_STRING_TABLE = asn1_string_table_st ++class ASN1_TEMPLATE_st(Structure): ++ pass ++ASN1_TEMPLATE_st._fields_ = [ ++] ++ASN1_TEMPLATE = ASN1_TEMPLATE_st ++class ASN1_ITEM_st(Structure): ++ pass ++ASN1_ITEM = ASN1_ITEM_st ++ASN1_ITEM_st._fields_ = [ ++] ++class ASN1_TLC_st(Structure): ++ pass ++ASN1_TLC = ASN1_TLC_st ++ASN1_TLC_st._fields_ = [ ++] ++class ASN1_VALUE_st(Structure): ++ pass ++ASN1_VALUE_st._fields_ = [ ++] ++ASN1_VALUE = ASN1_VALUE_st ++ASN1_ITEM_EXP = ASN1_ITEM ++class asn1_type_st(Structure): ++ pass ++class N12asn1_type_st4DOLLAR_11E(Union): ++ pass ++ASN1_BOOLEAN = c_int ++ASN1_INTEGER = asn1_string_st ++ASN1_ENUMERATED = asn1_string_st ++ASN1_BIT_STRING = asn1_string_st ++ASN1_OCTET_STRING = asn1_string_st ++ASN1_PRINTABLESTRING = asn1_string_st ++ASN1_T61STRING = asn1_string_st ++ASN1_IA5STRING = asn1_string_st ++ASN1_GENERALSTRING = asn1_string_st ++ASN1_BMPSTRING = asn1_string_st ++ASN1_UNIVERSALSTRING = asn1_string_st ++ASN1_UTCTIME = asn1_string_st ++ASN1_GENERALIZEDTIME = asn1_string_st ++ASN1_VISIBLESTRING = asn1_string_st ++ASN1_UTF8STRING = asn1_string_st ++N12asn1_type_st4DOLLAR_11E._fields_ = [ ++ ('ptr', STRING), ++ ('boolean', ASN1_BOOLEAN), ++ ('asn1_string', POINTER(ASN1_STRING)), ++ ('object', POINTER(ASN1_OBJECT)), ++ ('integer', POINTER(ASN1_INTEGER)), ++ ('enumerated', POINTER(ASN1_ENUMERATED)), ++ ('bit_string', POINTER(ASN1_BIT_STRING)), ++ ('octet_string', POINTER(ASN1_OCTET_STRING)), ++ ('printablestring', POINTER(ASN1_PRINTABLESTRING)), ++ ('t61string', POINTER(ASN1_T61STRING)), ++ ('ia5string', POINTER(ASN1_IA5STRING)), ++ ('generalstring', POINTER(ASN1_GENERALSTRING)), ++ ('bmpstring', POINTER(ASN1_BMPSTRING)), ++ ('universalstring', POINTER(ASN1_UNIVERSALSTRING)), ++ ('utctime', POINTER(ASN1_UTCTIME)), ++ ('generalizedtime', POINTER(ASN1_GENERALIZEDTIME)), ++ ('visiblestring', POINTER(ASN1_VISIBLESTRING)), ++ ('utf8string', POINTER(ASN1_UTF8STRING)), ++ ('set', POINTER(ASN1_STRING)), ++ ('sequence', POINTER(ASN1_STRING)), ++] ++assert sizeof(N12asn1_type_st4DOLLAR_11E) == 4, sizeof(N12asn1_type_st4DOLLAR_11E) ++assert alignment(N12asn1_type_st4DOLLAR_11E) == 4, alignment(N12asn1_type_st4DOLLAR_11E) ++asn1_type_st._fields_ = [ ++ ('type', c_int), ++ ('value', N12asn1_type_st4DOLLAR_11E), ++] ++assert sizeof(asn1_type_st) == 8, sizeof(asn1_type_st) ++assert alignment(asn1_type_st) == 4, alignment(asn1_type_st) ++ASN1_TYPE = asn1_type_st ++class asn1_method_st(Structure): ++ pass ++asn1_method_st._fields_ = [ ++ ('i2d', CFUNCTYPE(c_int)), ++ ('d2i', CFUNCTYPE(STRING)), ++ ('create', CFUNCTYPE(STRING)), ++ ('destroy', CFUNCTYPE(None)), ++] ++assert sizeof(asn1_method_st) == 16, sizeof(asn1_method_st) ++assert alignment(asn1_method_st) == 4, alignment(asn1_method_st) ++ASN1_METHOD = asn1_method_st ++class asn1_header_st(Structure): ++ pass ++asn1_header_st._fields_ = [ ++ ('header', POINTER(ASN1_OCTET_STRING)), ++ ('data', STRING), ++ ('meth', POINTER(ASN1_METHOD)), ++] ++assert sizeof(asn1_header_st) == 12, sizeof(asn1_header_st) ++assert alignment(asn1_header_st) == 4, alignment(asn1_header_st) ++ASN1_HEADER = asn1_header_st ++class BIT_STRING_BITNAME_st(Structure): ++ pass ++BIT_STRING_BITNAME_st._fields_ = [ ++ ('bitnum', c_int), ++ ('lname', STRING), ++ ('sname', STRING), ++] ++assert sizeof(BIT_STRING_BITNAME_st) == 12, sizeof(BIT_STRING_BITNAME_st) ++assert alignment(BIT_STRING_BITNAME_st) == 4, alignment(BIT_STRING_BITNAME_st) ++BIT_STRING_BITNAME = BIT_STRING_BITNAME_st ++class bio_st(Structure): ++ pass ++BIO = bio_st ++bio_info_cb = CFUNCTYPE(None, POINTER(bio_st), c_int, STRING, c_int, c_long, c_long) ++class bio_method_st(Structure): ++ pass ++bio_method_st._fields_ = [ ++ ('type', c_int), ++ ('name', STRING), ++ ('bwrite', CFUNCTYPE(c_int, POINTER(BIO), STRING, c_int)), ++ ('bread', CFUNCTYPE(c_int, POINTER(BIO), STRING, c_int)), ++ ('bputs', CFUNCTYPE(c_int, POINTER(BIO), STRING)), ++ ('bgets', CFUNCTYPE(c_int, POINTER(BIO), STRING, c_int)), ++ ('ctrl', CFUNCTYPE(c_long, POINTER(BIO), c_int, c_long, c_void_p)), ++ ('create', CFUNCTYPE(c_int, POINTER(BIO))), ++ ('destroy', CFUNCTYPE(c_int, POINTER(BIO))), ++ ('callback_ctrl', CFUNCTYPE(c_long, POINTER(BIO), c_int, POINTER(bio_info_cb))), ++] ++assert sizeof(bio_method_st) == 40, sizeof(bio_method_st) ++assert alignment(bio_method_st) == 4, alignment(bio_method_st) ++BIO_METHOD = bio_method_st ++class crypto_ex_data_st(Structure): ++ pass ++class stack_st(Structure): ++ pass ++STACK = stack_st ++crypto_ex_data_st._fields_ = [ ++ ('sk', POINTER(STACK)), ++ ('dummy', c_int), ++] ++assert sizeof(crypto_ex_data_st) == 8, sizeof(crypto_ex_data_st) ++assert alignment(crypto_ex_data_st) == 4, alignment(crypto_ex_data_st) ++CRYPTO_EX_DATA = crypto_ex_data_st ++bio_st._fields_ = [ ++ ('method', POINTER(BIO_METHOD)), ++ ('callback', CFUNCTYPE(c_long, POINTER(bio_st), c_int, STRING, c_int, c_long, c_long)), ++ ('cb_arg', STRING), ++ ('init', c_int), ++ ('shutdown', c_int), ++ ('flags', c_int), ++ ('retry_reason', c_int), ++ ('num', c_int), ++ ('ptr', c_void_p), ++ ('next_bio', POINTER(bio_st)), ++ ('prev_bio', POINTER(bio_st)), ++ ('references', c_int), ++ ('num_read', c_ulong), ++ ('num_write', c_ulong), ++ ('ex_data', CRYPTO_EX_DATA), ++] ++assert sizeof(bio_st) == 64, sizeof(bio_st) ++assert alignment(bio_st) == 4, alignment(bio_st) ++class bio_f_buffer_ctx_struct(Structure): ++ pass ++bio_f_buffer_ctx_struct._fields_ = [ ++ ('ibuf_size', c_int), ++ ('obuf_size', c_int), ++ ('ibuf', STRING), ++ ('ibuf_len', c_int), ++ ('ibuf_off', c_int), ++ ('obuf', STRING), ++ ('obuf_len', c_int), ++ ('obuf_off', c_int), ++] ++assert sizeof(bio_f_buffer_ctx_struct) == 32, sizeof(bio_f_buffer_ctx_struct) ++assert alignment(bio_f_buffer_ctx_struct) == 4, alignment(bio_f_buffer_ctx_struct) ++BIO_F_BUFFER_CTX = bio_f_buffer_ctx_struct ++class hostent(Structure): ++ pass ++hostent._fields_ = [ ++] ++class bf_key_st(Structure): ++ pass ++bf_key_st._fields_ = [ ++ ('P', c_uint * 18), ++ ('S', c_uint * 1024), ++] ++assert sizeof(bf_key_st) == 4168, sizeof(bf_key_st) ++assert alignment(bf_key_st) == 4, alignment(bf_key_st) ++BF_KEY = bf_key_st ++class bignum_st(Structure): ++ pass ++bignum_st._fields_ = [ ++ ('d', POINTER(c_ulong)), ++ ('top', c_int), ++ ('dmax', c_int), ++ ('neg', c_int), ++ ('flags', c_int), ++] ++assert sizeof(bignum_st) == 20, sizeof(bignum_st) ++assert alignment(bignum_st) == 4, alignment(bignum_st) ++BIGNUM = bignum_st ++class bignum_ctx(Structure): ++ pass ++bignum_ctx._fields_ = [ ++] ++BN_CTX = bignum_ctx ++class bn_blinding_st(Structure): ++ pass ++bn_blinding_st._fields_ = [ ++ ('init', c_int), ++ ('A', POINTER(BIGNUM)), ++ ('Ai', POINTER(BIGNUM)), ++ ('mod', POINTER(BIGNUM)), ++ ('thread_id', c_ulong), ++] ++assert sizeof(bn_blinding_st) == 20, sizeof(bn_blinding_st) ++assert alignment(bn_blinding_st) == 4, alignment(bn_blinding_st) ++BN_BLINDING = bn_blinding_st ++class bn_mont_ctx_st(Structure): ++ pass ++bn_mont_ctx_st._fields_ = [ ++ ('ri', c_int), ++ ('RR', BIGNUM), ++ ('N', BIGNUM), ++ ('Ni', BIGNUM), ++ ('n0', c_ulong), ++ ('flags', c_int), ++] ++assert sizeof(bn_mont_ctx_st) == 72, sizeof(bn_mont_ctx_st) ++assert alignment(bn_mont_ctx_st) == 4, alignment(bn_mont_ctx_st) ++BN_MONT_CTX = bn_mont_ctx_st ++class bn_recp_ctx_st(Structure): ++ pass ++bn_recp_ctx_st._fields_ = [ ++ ('N', BIGNUM), ++ ('Nr', BIGNUM), ++ ('num_bits', c_int), ++ ('shift', c_int), ++ ('flags', c_int), ++] ++assert sizeof(bn_recp_ctx_st) == 52, sizeof(bn_recp_ctx_st) ++assert alignment(bn_recp_ctx_st) == 4, alignment(bn_recp_ctx_st) ++BN_RECP_CTX = bn_recp_ctx_st ++class buf_mem_st(Structure): ++ pass ++buf_mem_st._fields_ = [ ++ ('length', c_int), ++ ('data', STRING), ++ ('max', c_int), ++] ++assert sizeof(buf_mem_st) == 12, sizeof(buf_mem_st) ++assert alignment(buf_mem_st) == 4, alignment(buf_mem_st) ++BUF_MEM = buf_mem_st ++class cast_key_st(Structure): ++ pass ++cast_key_st._fields_ = [ ++ ('data', c_ulong * 32), ++ ('short_key', c_int), ++] ++assert sizeof(cast_key_st) == 132, sizeof(cast_key_st) ++assert alignment(cast_key_st) == 4, alignment(cast_key_st) ++CAST_KEY = cast_key_st ++class comp_method_st(Structure): ++ pass ++comp_method_st._fields_ = [ ++ ('type', c_int), ++ ('name', STRING), ++ ('init', CFUNCTYPE(c_int)), ++ ('finish', CFUNCTYPE(None)), ++ ('compress', CFUNCTYPE(c_int)), ++ ('expand', CFUNCTYPE(c_int)), ++ ('ctrl', CFUNCTYPE(c_long)), ++ ('callback_ctrl', CFUNCTYPE(c_long)), ++] ++assert sizeof(comp_method_st) == 32, sizeof(comp_method_st) ++assert alignment(comp_method_st) == 4, alignment(comp_method_st) ++COMP_METHOD = comp_method_st ++class comp_ctx_st(Structure): ++ pass ++comp_ctx_st._fields_ = [ ++ ('meth', POINTER(COMP_METHOD)), ++ ('compress_in', c_ulong), ++ ('compress_out', c_ulong), ++ ('expand_in', c_ulong), ++ ('expand_out', c_ulong), ++ ('ex_data', CRYPTO_EX_DATA), ++] ++assert sizeof(comp_ctx_st) == 28, sizeof(comp_ctx_st) ++assert alignment(comp_ctx_st) == 4, alignment(comp_ctx_st) ++COMP_CTX = comp_ctx_st ++class CRYPTO_dynlock_value(Structure): ++ pass ++CRYPTO_dynlock_value._fields_ = [ ++] ++class CRYPTO_dynlock(Structure): ++ pass ++CRYPTO_dynlock._fields_ = [ ++ ('references', c_int), ++ ('data', POINTER(CRYPTO_dynlock_value)), ++] ++assert sizeof(CRYPTO_dynlock) == 8, sizeof(CRYPTO_dynlock) ++assert alignment(CRYPTO_dynlock) == 4, alignment(CRYPTO_dynlock) ++BIO_dummy = bio_st ++CRYPTO_EX_new = CFUNCTYPE(c_int, c_void_p, c_void_p, POINTER(CRYPTO_EX_DATA), c_int, c_long, c_void_p) ++CRYPTO_EX_free = CFUNCTYPE(None, c_void_p, c_void_p, POINTER(CRYPTO_EX_DATA), c_int, c_long, c_void_p) ++CRYPTO_EX_dup = CFUNCTYPE(c_int, POINTER(CRYPTO_EX_DATA), POINTER(CRYPTO_EX_DATA), c_void_p, c_int, c_long, c_void_p) ++class crypto_ex_data_func_st(Structure): ++ pass ++crypto_ex_data_func_st._fields_ = [ ++ ('argl', c_long), ++ ('argp', c_void_p), ++ ('new_func', POINTER(CRYPTO_EX_new)), ++ ('free_func', POINTER(CRYPTO_EX_free)), ++ ('dup_func', POINTER(CRYPTO_EX_dup)), ++] ++assert sizeof(crypto_ex_data_func_st) == 20, sizeof(crypto_ex_data_func_st) ++assert alignment(crypto_ex_data_func_st) == 4, alignment(crypto_ex_data_func_st) ++CRYPTO_EX_DATA_FUNCS = crypto_ex_data_func_st ++class st_CRYPTO_EX_DATA_IMPL(Structure): ++ pass ++CRYPTO_EX_DATA_IMPL = st_CRYPTO_EX_DATA_IMPL ++st_CRYPTO_EX_DATA_IMPL._fields_ = [ ++] ++CRYPTO_MEM_LEAK_CB = CFUNCTYPE(c_void_p, c_ulong, STRING, c_int, c_int, c_void_p) ++DES_cblock = c_ubyte * 8 ++const_DES_cblock = c_ubyte * 8 ++class DES_ks(Structure): ++ pass ++class N6DES_ks3DOLLAR_9E(Union): ++ pass ++N6DES_ks3DOLLAR_9E._fields_ = [ ++ ('cblock', DES_cblock), ++ ('deslong', c_ulong * 2), ++] ++assert sizeof(N6DES_ks3DOLLAR_9E) == 8, sizeof(N6DES_ks3DOLLAR_9E) ++assert alignment(N6DES_ks3DOLLAR_9E) == 4, alignment(N6DES_ks3DOLLAR_9E) ++DES_ks._fields_ = [ ++ ('ks', N6DES_ks3DOLLAR_9E * 16), ++] ++assert sizeof(DES_ks) == 128, sizeof(DES_ks) ++assert alignment(DES_ks) == 4, alignment(DES_ks) ++DES_key_schedule = DES_ks ++_ossl_old_des_cblock = c_ubyte * 8 ++class _ossl_old_des_ks_struct(Structure): ++ pass ++class N23_ossl_old_des_ks_struct4DOLLAR_10E(Union): ++ pass ++N23_ossl_old_des_ks_struct4DOLLAR_10E._fields_ = [ ++ ('_', _ossl_old_des_cblock), ++ ('pad', c_ulong * 2), ++] ++assert sizeof(N23_ossl_old_des_ks_struct4DOLLAR_10E) == 8, sizeof(N23_ossl_old_des_ks_struct4DOLLAR_10E) ++assert alignment(N23_ossl_old_des_ks_struct4DOLLAR_10E) == 4, alignment(N23_ossl_old_des_ks_struct4DOLLAR_10E) ++_ossl_old_des_ks_struct._fields_ = [ ++ ('ks', N23_ossl_old_des_ks_struct4DOLLAR_10E), ++] ++assert sizeof(_ossl_old_des_ks_struct) == 8, sizeof(_ossl_old_des_ks_struct) ++assert alignment(_ossl_old_des_ks_struct) == 4, alignment(_ossl_old_des_ks_struct) ++_ossl_old_des_key_schedule = _ossl_old_des_ks_struct * 16 ++class dh_st(Structure): ++ pass ++DH = dh_st ++class dh_method(Structure): ++ pass ++dh_method._fields_ = [ ++ ('name', STRING), ++ ('generate_key', CFUNCTYPE(c_int, POINTER(DH))), ++ ('compute_key', CFUNCTYPE(c_int, POINTER(c_ubyte), POINTER(BIGNUM), POINTER(DH))), ++ ('bn_mod_exp', CFUNCTYPE(c_int, POINTER(DH), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BN_CTX), POINTER(BN_MONT_CTX))), ++ ('init', CFUNCTYPE(c_int, POINTER(DH))), ++ ('finish', CFUNCTYPE(c_int, POINTER(DH))), ++ ('flags', c_int), ++ ('app_data', STRING), ++] ++assert sizeof(dh_method) == 32, sizeof(dh_method) ++assert alignment(dh_method) == 4, alignment(dh_method) ++DH_METHOD = dh_method ++class engine_st(Structure): ++ pass ++ENGINE = engine_st ++dh_st._fields_ = [ ++ ('pad', c_int), ++ ('version', c_int), ++ ('p', POINTER(BIGNUM)), ++ ('g', POINTER(BIGNUM)), ++ ('length', c_long), ++ ('pub_key', POINTER(BIGNUM)), ++ ('priv_key', POINTER(BIGNUM)), ++ ('flags', c_int), ++ ('method_mont_p', STRING), ++ ('q', POINTER(BIGNUM)), ++ ('j', POINTER(BIGNUM)), ++ ('seed', POINTER(c_ubyte)), ++ ('seedlen', c_int), ++ ('counter', POINTER(BIGNUM)), ++ ('references', c_int), ++ ('ex_data', CRYPTO_EX_DATA), ++ ('meth', POINTER(DH_METHOD)), ++ ('engine', POINTER(ENGINE)), ++] ++assert sizeof(dh_st) == 76, sizeof(dh_st) ++assert alignment(dh_st) == 4, alignment(dh_st) ++class dsa_st(Structure): ++ pass ++DSA = dsa_st ++class DSA_SIG_st(Structure): ++ pass ++DSA_SIG_st._fields_ = [ ++ ('r', POINTER(BIGNUM)), ++ ('s', POINTER(BIGNUM)), ++] ++assert sizeof(DSA_SIG_st) == 8, sizeof(DSA_SIG_st) ++assert alignment(DSA_SIG_st) == 4, alignment(DSA_SIG_st) ++DSA_SIG = DSA_SIG_st ++class dsa_method(Structure): ++ pass ++dsa_method._fields_ = [ ++ ('name', STRING), ++ ('dsa_do_sign', CFUNCTYPE(POINTER(DSA_SIG), POINTER(c_ubyte), c_int, POINTER(DSA))), ++ ('dsa_sign_setup', CFUNCTYPE(c_int, POINTER(DSA), POINTER(BN_CTX), POINTER(POINTER(BIGNUM)), POINTER(POINTER(BIGNUM)))), ++ ('dsa_do_verify', CFUNCTYPE(c_int, POINTER(c_ubyte), c_int, POINTER(DSA_SIG), POINTER(DSA))), ++ ('dsa_mod_exp', CFUNCTYPE(c_int, POINTER(DSA), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BN_CTX), POINTER(BN_MONT_CTX))), ++ ('bn_mod_exp', CFUNCTYPE(c_int, POINTER(DSA), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BN_CTX), POINTER(BN_MONT_CTX))), ++ ('init', CFUNCTYPE(c_int, POINTER(DSA))), ++ ('finish', CFUNCTYPE(c_int, POINTER(DSA))), ++ ('flags', c_int), ++ ('app_data', STRING), ++] ++assert sizeof(dsa_method) == 40, sizeof(dsa_method) ++assert alignment(dsa_method) == 4, alignment(dsa_method) ++DSA_METHOD = dsa_method ++dsa_st._fields_ = [ ++ ('pad', c_int), ++ ('version', c_long), ++ ('write_params', c_int), ++ ('p', POINTER(BIGNUM)), ++ ('q', POINTER(BIGNUM)), ++ ('g', POINTER(BIGNUM)), ++ ('pub_key', POINTER(BIGNUM)), ++ ('priv_key', POINTER(BIGNUM)), ++ ('kinv', POINTER(BIGNUM)), ++ ('r', POINTER(BIGNUM)), ++ ('flags', c_int), ++ ('method_mont_p', STRING), ++ ('references', c_int), ++ ('ex_data', CRYPTO_EX_DATA), ++ ('meth', POINTER(DSA_METHOD)), ++ ('engine', POINTER(ENGINE)), ++] ++assert sizeof(dsa_st) == 68, sizeof(dsa_st) ++assert alignment(dsa_st) == 4, alignment(dsa_st) ++class evp_pkey_st(Structure): ++ pass ++class N11evp_pkey_st4DOLLAR_12E(Union): ++ pass ++class rsa_st(Structure): ++ pass ++N11evp_pkey_st4DOLLAR_12E._fields_ = [ ++ ('ptr', STRING), ++ ('rsa', POINTER(rsa_st)), ++ ('dsa', POINTER(dsa_st)), ++ ('dh', POINTER(dh_st)), ++] ++assert sizeof(N11evp_pkey_st4DOLLAR_12E) == 4, sizeof(N11evp_pkey_st4DOLLAR_12E) ++assert alignment(N11evp_pkey_st4DOLLAR_12E) == 4, alignment(N11evp_pkey_st4DOLLAR_12E) ++evp_pkey_st._fields_ = [ ++ ('type', c_int), ++ ('save_type', c_int), ++ ('references', c_int), ++ ('pkey', N11evp_pkey_st4DOLLAR_12E), ++ ('save_parameters', c_int), ++ ('attributes', POINTER(STACK)), ++] ++assert sizeof(evp_pkey_st) == 24, sizeof(evp_pkey_st) ++assert alignment(evp_pkey_st) == 4, alignment(evp_pkey_st) ++class env_md_st(Structure): ++ pass ++class env_md_ctx_st(Structure): ++ pass ++EVP_MD_CTX = env_md_ctx_st ++env_md_st._fields_ = [ ++ ('type', c_int), ++ ('pkey_type', c_int), ++ ('md_size', c_int), ++ ('flags', c_ulong), ++ ('init', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX))), ++ ('update', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX), c_void_p, c_ulong)), ++ ('final', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX), POINTER(c_ubyte))), ++ ('copy', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX), POINTER(EVP_MD_CTX))), ++ ('cleanup', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX))), ++ ('sign', CFUNCTYPE(c_int)), ++ ('verify', CFUNCTYPE(c_int)), ++ ('required_pkey_type', c_int * 5), ++ ('block_size', c_int), ++ ('ctx_size', c_int), ++] ++assert sizeof(env_md_st) == 72, sizeof(env_md_st) ++assert alignment(env_md_st) == 4, alignment(env_md_st) ++EVP_MD = env_md_st ++env_md_ctx_st._fields_ = [ ++ ('digest', POINTER(EVP_MD)), ++ ('engine', POINTER(ENGINE)), ++ ('flags', c_ulong), ++ ('md_data', c_void_p), ++] ++assert sizeof(env_md_ctx_st) == 16, sizeof(env_md_ctx_st) ++assert alignment(env_md_ctx_st) == 4, alignment(env_md_ctx_st) ++class evp_cipher_st(Structure): ++ pass ++class evp_cipher_ctx_st(Structure): ++ pass ++EVP_CIPHER_CTX = evp_cipher_ctx_st ++evp_cipher_st._fields_ = [ ++ ('nid', c_int), ++ ('block_size', c_int), ++ ('key_len', c_int), ++ ('iv_len', c_int), ++ ('flags', c_ulong), ++ ('init', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), POINTER(c_ubyte), POINTER(c_ubyte), c_int)), ++ ('do_cipher', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), POINTER(c_ubyte), POINTER(c_ubyte), c_uint)), ++ ('cleanup', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX))), ++ ('ctx_size', c_int), ++ ('set_asn1_parameters', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), POINTER(ASN1_TYPE))), ++ ('get_asn1_parameters', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), POINTER(ASN1_TYPE))), ++ ('ctrl', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), c_int, c_int, c_void_p)), ++ ('app_data', c_void_p), ++] ++assert sizeof(evp_cipher_st) == 52, sizeof(evp_cipher_st) ++assert alignment(evp_cipher_st) == 4, alignment(evp_cipher_st) ++class evp_cipher_info_st(Structure): ++ pass ++EVP_CIPHER = evp_cipher_st ++evp_cipher_info_st._fields_ = [ ++ ('cipher', POINTER(EVP_CIPHER)), ++ ('iv', c_ubyte * 16), ++] ++assert sizeof(evp_cipher_info_st) == 20, sizeof(evp_cipher_info_st) ++assert alignment(evp_cipher_info_st) == 4, alignment(evp_cipher_info_st) ++EVP_CIPHER_INFO = evp_cipher_info_st ++evp_cipher_ctx_st._fields_ = [ ++ ('cipher', POINTER(EVP_CIPHER)), ++ ('engine', POINTER(ENGINE)), ++ ('encrypt', c_int), ++ ('buf_len', c_int), ++ ('oiv', c_ubyte * 16), ++ ('iv', c_ubyte * 16), ++ ('buf', c_ubyte * 32), ++ ('num', c_int), ++ ('app_data', c_void_p), ++ ('key_len', c_int), ++ ('flags', c_ulong), ++ ('cipher_data', c_void_p), ++ ('final_used', c_int), ++ ('block_mask', c_int), ++ ('final', c_ubyte * 32), ++] ++assert sizeof(evp_cipher_ctx_st) == 140, sizeof(evp_cipher_ctx_st) ++assert alignment(evp_cipher_ctx_st) == 4, alignment(evp_cipher_ctx_st) ++class evp_Encode_Ctx_st(Structure): ++ pass ++evp_Encode_Ctx_st._fields_ = [ ++ ('num', c_int), ++ ('length', c_int), ++ ('enc_data', c_ubyte * 80), ++ ('line_num', c_int), ++ ('expect_nl', c_int), ++] ++assert sizeof(evp_Encode_Ctx_st) == 96, sizeof(evp_Encode_Ctx_st) ++assert alignment(evp_Encode_Ctx_st) == 4, alignment(evp_Encode_Ctx_st) ++EVP_ENCODE_CTX = evp_Encode_Ctx_st ++EVP_PBE_KEYGEN = CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), STRING, c_int, POINTER(ASN1_TYPE), POINTER(EVP_CIPHER), POINTER(EVP_MD), c_int) ++class lhash_node_st(Structure): ++ pass ++lhash_node_st._fields_ = [ ++ ('data', c_void_p), ++ ('next', POINTER(lhash_node_st)), ++ ('hash', c_ulong), ++] ++assert sizeof(lhash_node_st) == 12, sizeof(lhash_node_st) ++assert alignment(lhash_node_st) == 4, alignment(lhash_node_st) ++LHASH_NODE = lhash_node_st ++LHASH_COMP_FN_TYPE = CFUNCTYPE(c_int, c_void_p, c_void_p) ++LHASH_HASH_FN_TYPE = CFUNCTYPE(c_ulong, c_void_p) ++LHASH_DOALL_FN_TYPE = CFUNCTYPE(None, c_void_p) ++LHASH_DOALL_ARG_FN_TYPE = CFUNCTYPE(None, c_void_p, c_void_p) ++class lhash_st(Structure): ++ pass ++lhash_st._fields_ = [ ++ ('b', POINTER(POINTER(LHASH_NODE))), ++ ('comp', LHASH_COMP_FN_TYPE), ++ ('hash', LHASH_HASH_FN_TYPE), ++ ('num_nodes', c_uint), ++ ('num_alloc_nodes', c_uint), ++ ('p', c_uint), ++ ('pmax', c_uint), ++ ('up_load', c_ulong), ++ ('down_load', c_ulong), ++ ('num_items', c_ulong), ++ ('num_expands', c_ulong), ++ ('num_expand_reallocs', c_ulong), ++ ('num_contracts', c_ulong), ++ ('num_contract_reallocs', c_ulong), ++ ('num_hash_calls', c_ulong), ++ ('num_comp_calls', c_ulong), ++ ('num_insert', c_ulong), ++ ('num_replace', c_ulong), ++ ('num_delete', c_ulong), ++ ('num_no_delete', c_ulong), ++ ('num_retrieve', c_ulong), ++ ('num_retrieve_miss', c_ulong), ++ ('num_hash_comps', c_ulong), ++ ('error', c_int), ++] ++assert sizeof(lhash_st) == 96, sizeof(lhash_st) ++assert alignment(lhash_st) == 4, alignment(lhash_st) ++LHASH = lhash_st ++class MD2state_st(Structure): ++ pass ++MD2state_st._fields_ = [ ++ ('num', c_int), ++ ('data', c_ubyte * 16), ++ ('cksm', c_uint * 16), ++ ('state', c_uint * 16), ++] ++assert sizeof(MD2state_st) == 148, sizeof(MD2state_st) ++assert alignment(MD2state_st) == 4, alignment(MD2state_st) ++MD2_CTX = MD2state_st ++class MD4state_st(Structure): ++ pass ++MD4state_st._fields_ = [ ++ ('A', c_uint), ++ ('B', c_uint), ++ ('C', c_uint), ++ ('D', c_uint), ++ ('Nl', c_uint), ++ ('Nh', c_uint), ++ ('data', c_uint * 16), ++ ('num', c_int), ++] ++assert sizeof(MD4state_st) == 92, sizeof(MD4state_st) ++assert alignment(MD4state_st) == 4, alignment(MD4state_st) ++MD4_CTX = MD4state_st ++class MD5state_st(Structure): ++ pass ++MD5state_st._fields_ = [ ++ ('A', c_uint), ++ ('B', c_uint), ++ ('C', c_uint), ++ ('D', c_uint), ++ ('Nl', c_uint), ++ ('Nh', c_uint), ++ ('data', c_uint * 16), ++ ('num', c_int), ++] ++assert sizeof(MD5state_st) == 92, sizeof(MD5state_st) ++assert alignment(MD5state_st) == 4, alignment(MD5state_st) ++MD5_CTX = MD5state_st ++class mdc2_ctx_st(Structure): ++ pass ++mdc2_ctx_st._fields_ = [ ++ ('num', c_int), ++ ('data', c_ubyte * 8), ++ ('h', DES_cblock), ++ ('hh', DES_cblock), ++ ('pad_type', c_int), ++] ++assert sizeof(mdc2_ctx_st) == 32, sizeof(mdc2_ctx_st) ++assert alignment(mdc2_ctx_st) == 4, alignment(mdc2_ctx_st) ++MDC2_CTX = mdc2_ctx_st ++class obj_name_st(Structure): ++ pass ++obj_name_st._fields_ = [ ++ ('type', c_int), ++ ('alias', c_int), ++ ('name', STRING), ++ ('data', STRING), ++] ++assert sizeof(obj_name_st) == 16, sizeof(obj_name_st) ++assert alignment(obj_name_st) == 4, alignment(obj_name_st) ++OBJ_NAME = obj_name_st ++ASN1_TIME = asn1_string_st ++ASN1_NULL = c_int ++EVP_PKEY = evp_pkey_st ++class x509_st(Structure): ++ pass ++X509 = x509_st ++class X509_algor_st(Structure): ++ pass ++X509_ALGOR = X509_algor_st ++class X509_crl_st(Structure): ++ pass ++X509_CRL = X509_crl_st ++class X509_name_st(Structure): ++ pass ++X509_NAME = X509_name_st ++class x509_store_st(Structure): ++ pass ++X509_STORE = x509_store_st ++class x509_store_ctx_st(Structure): ++ pass ++X509_STORE_CTX = x509_store_ctx_st ++engine_st._fields_ = [ ++] ++class PEM_Encode_Seal_st(Structure): ++ pass ++PEM_Encode_Seal_st._fields_ = [ ++ ('encode', EVP_ENCODE_CTX), ++ ('md', EVP_MD_CTX), ++ ('cipher', EVP_CIPHER_CTX), ++] ++assert sizeof(PEM_Encode_Seal_st) == 252, sizeof(PEM_Encode_Seal_st) ++assert alignment(PEM_Encode_Seal_st) == 4, alignment(PEM_Encode_Seal_st) ++PEM_ENCODE_SEAL_CTX = PEM_Encode_Seal_st ++class pem_recip_st(Structure): ++ pass ++pem_recip_st._fields_ = [ ++ ('name', STRING), ++ ('dn', POINTER(X509_NAME)), ++ ('cipher', c_int), ++ ('key_enc', c_int), ++] ++assert sizeof(pem_recip_st) == 16, sizeof(pem_recip_st) ++assert alignment(pem_recip_st) == 4, alignment(pem_recip_st) ++PEM_USER = pem_recip_st ++class pem_ctx_st(Structure): ++ pass ++class N10pem_ctx_st4DOLLAR_16E(Structure): ++ pass ++N10pem_ctx_st4DOLLAR_16E._fields_ = [ ++ ('version', c_int), ++ ('mode', c_int), ++] ++assert sizeof(N10pem_ctx_st4DOLLAR_16E) == 8, sizeof(N10pem_ctx_st4DOLLAR_16E) ++assert alignment(N10pem_ctx_st4DOLLAR_16E) == 4, alignment(N10pem_ctx_st4DOLLAR_16E) ++class N10pem_ctx_st4DOLLAR_17E(Structure): ++ pass ++N10pem_ctx_st4DOLLAR_17E._fields_ = [ ++ ('cipher', c_int), ++] ++assert sizeof(N10pem_ctx_st4DOLLAR_17E) == 4, sizeof(N10pem_ctx_st4DOLLAR_17E) ++assert alignment(N10pem_ctx_st4DOLLAR_17E) == 4, alignment(N10pem_ctx_st4DOLLAR_17E) ++pem_ctx_st._fields_ = [ ++ ('type', c_int), ++ ('proc_type', N10pem_ctx_st4DOLLAR_16E), ++ ('domain', STRING), ++ ('DEK_info', N10pem_ctx_st4DOLLAR_17E), ++ ('originator', POINTER(PEM_USER)), ++ ('num_recipient', c_int), ++ ('recipient', POINTER(POINTER(PEM_USER))), ++ ('x509_chain', POINTER(STACK)), ++ ('md', POINTER(EVP_MD)), ++ ('md_enc', c_int), ++ ('md_len', c_int), ++ ('md_data', STRING), ++ ('dec', POINTER(EVP_CIPHER)), ++ ('key_len', c_int), ++ ('key', POINTER(c_ubyte)), ++ ('data_enc', c_int), ++ ('data_len', c_int), ++ ('data', POINTER(c_ubyte)), ++] ++assert sizeof(pem_ctx_st) == 76, sizeof(pem_ctx_st) ++assert alignment(pem_ctx_st) == 4, alignment(pem_ctx_st) ++PEM_CTX = pem_ctx_st ++pem_password_cb = CFUNCTYPE(c_int, STRING, c_int, c_int, c_void_p) ++class pkcs7_issuer_and_serial_st(Structure): ++ pass ++pkcs7_issuer_and_serial_st._fields_ = [ ++ ('issuer', POINTER(X509_NAME)), ++ ('serial', POINTER(ASN1_INTEGER)), ++] ++assert sizeof(pkcs7_issuer_and_serial_st) == 8, sizeof(pkcs7_issuer_and_serial_st) ++assert alignment(pkcs7_issuer_and_serial_st) == 4, alignment(pkcs7_issuer_and_serial_st) ++PKCS7_ISSUER_AND_SERIAL = pkcs7_issuer_and_serial_st ++class pkcs7_signer_info_st(Structure): ++ pass ++pkcs7_signer_info_st._fields_ = [ ++ ('version', POINTER(ASN1_INTEGER)), ++ ('issuer_and_serial', POINTER(PKCS7_ISSUER_AND_SERIAL)), ++ ('digest_alg', POINTER(X509_ALGOR)), ++ ('auth_attr', POINTER(STACK)), ++ ('digest_enc_alg', POINTER(X509_ALGOR)), ++ ('enc_digest', POINTER(ASN1_OCTET_STRING)), ++ ('unauth_attr', POINTER(STACK)), ++ ('pkey', POINTER(EVP_PKEY)), ++] ++assert sizeof(pkcs7_signer_info_st) == 32, sizeof(pkcs7_signer_info_st) ++assert alignment(pkcs7_signer_info_st) == 4, alignment(pkcs7_signer_info_st) ++PKCS7_SIGNER_INFO = pkcs7_signer_info_st ++class pkcs7_recip_info_st(Structure): ++ pass ++pkcs7_recip_info_st._fields_ = [ ++ ('version', POINTER(ASN1_INTEGER)), ++ ('issuer_and_serial', POINTER(PKCS7_ISSUER_AND_SERIAL)), ++ ('key_enc_algor', POINTER(X509_ALGOR)), ++ ('enc_key', POINTER(ASN1_OCTET_STRING)), ++ ('cert', POINTER(X509)), ++] ++assert sizeof(pkcs7_recip_info_st) == 20, sizeof(pkcs7_recip_info_st) ++assert alignment(pkcs7_recip_info_st) == 4, alignment(pkcs7_recip_info_st) ++PKCS7_RECIP_INFO = pkcs7_recip_info_st ++class pkcs7_signed_st(Structure): ++ pass ++class pkcs7_st(Structure): ++ pass ++pkcs7_signed_st._fields_ = [ ++ ('version', POINTER(ASN1_INTEGER)), ++ ('md_algs', POINTER(STACK)), ++ ('cert', POINTER(STACK)), ++ ('crl', POINTER(STACK)), ++ ('signer_info', POINTER(STACK)), ++ ('contents', POINTER(pkcs7_st)), ++] ++assert sizeof(pkcs7_signed_st) == 24, sizeof(pkcs7_signed_st) ++assert alignment(pkcs7_signed_st) == 4, alignment(pkcs7_signed_st) ++PKCS7_SIGNED = pkcs7_signed_st ++class pkcs7_enc_content_st(Structure): ++ pass ++pkcs7_enc_content_st._fields_ = [ ++ ('content_type', POINTER(ASN1_OBJECT)), ++ ('algorithm', POINTER(X509_ALGOR)), ++ ('enc_data', POINTER(ASN1_OCTET_STRING)), ++ ('cipher', POINTER(EVP_CIPHER)), ++] ++assert sizeof(pkcs7_enc_content_st) == 16, sizeof(pkcs7_enc_content_st) ++assert alignment(pkcs7_enc_content_st) == 4, alignment(pkcs7_enc_content_st) ++PKCS7_ENC_CONTENT = pkcs7_enc_content_st ++class pkcs7_enveloped_st(Structure): ++ pass ++pkcs7_enveloped_st._fields_ = [ ++ ('version', POINTER(ASN1_INTEGER)), ++ ('recipientinfo', POINTER(STACK)), ++ ('enc_data', POINTER(PKCS7_ENC_CONTENT)), ++] ++assert sizeof(pkcs7_enveloped_st) == 12, sizeof(pkcs7_enveloped_st) ++assert alignment(pkcs7_enveloped_st) == 4, alignment(pkcs7_enveloped_st) ++PKCS7_ENVELOPE = pkcs7_enveloped_st ++class pkcs7_signedandenveloped_st(Structure): ++ pass ++pkcs7_signedandenveloped_st._fields_ = [ ++ ('version', POINTER(ASN1_INTEGER)), ++ ('md_algs', POINTER(STACK)), ++ ('cert', POINTER(STACK)), ++ ('crl', POINTER(STACK)), ++ ('signer_info', POINTER(STACK)), ++ ('enc_data', POINTER(PKCS7_ENC_CONTENT)), ++ ('recipientinfo', POINTER(STACK)), ++] ++assert sizeof(pkcs7_signedandenveloped_st) == 28, sizeof(pkcs7_signedandenveloped_st) ++assert alignment(pkcs7_signedandenveloped_st) == 4, alignment(pkcs7_signedandenveloped_st) ++PKCS7_SIGN_ENVELOPE = pkcs7_signedandenveloped_st ++class pkcs7_digest_st(Structure): ++ pass ++pkcs7_digest_st._fields_ = [ ++ ('version', POINTER(ASN1_INTEGER)), ++ ('md', POINTER(X509_ALGOR)), ++ ('contents', POINTER(pkcs7_st)), ++ ('digest', POINTER(ASN1_OCTET_STRING)), ++] ++assert sizeof(pkcs7_digest_st) == 16, sizeof(pkcs7_digest_st) ++assert alignment(pkcs7_digest_st) == 4, alignment(pkcs7_digest_st) ++PKCS7_DIGEST = pkcs7_digest_st ++class pkcs7_encrypted_st(Structure): ++ pass ++pkcs7_encrypted_st._fields_ = [ ++ ('version', POINTER(ASN1_INTEGER)), ++ ('enc_data', POINTER(PKCS7_ENC_CONTENT)), ++] ++assert sizeof(pkcs7_encrypted_st) == 8, sizeof(pkcs7_encrypted_st) ++assert alignment(pkcs7_encrypted_st) == 4, alignment(pkcs7_encrypted_st) ++PKCS7_ENCRYPT = pkcs7_encrypted_st ++class N8pkcs7_st4DOLLAR_15E(Union): ++ pass ++N8pkcs7_st4DOLLAR_15E._fields_ = [ ++ ('ptr', STRING), ++ ('data', POINTER(ASN1_OCTET_STRING)), ++ ('sign', POINTER(PKCS7_SIGNED)), ++ ('enveloped', POINTER(PKCS7_ENVELOPE)), ++ ('signed_and_enveloped', POINTER(PKCS7_SIGN_ENVELOPE)), ++ ('digest', POINTER(PKCS7_DIGEST)), ++ ('encrypted', POINTER(PKCS7_ENCRYPT)), ++ ('other', POINTER(ASN1_TYPE)), ++] ++assert sizeof(N8pkcs7_st4DOLLAR_15E) == 4, sizeof(N8pkcs7_st4DOLLAR_15E) ++assert alignment(N8pkcs7_st4DOLLAR_15E) == 4, alignment(N8pkcs7_st4DOLLAR_15E) ++pkcs7_st._fields_ = [ ++ ('asn1', POINTER(c_ubyte)), ++ ('length', c_long), ++ ('state', c_int), ++ ('detached', c_int), ++ ('type', POINTER(ASN1_OBJECT)), ++ ('d', N8pkcs7_st4DOLLAR_15E), ++] ++assert sizeof(pkcs7_st) == 24, sizeof(pkcs7_st) ++assert alignment(pkcs7_st) == 4, alignment(pkcs7_st) ++PKCS7 = pkcs7_st ++class rc2_key_st(Structure): ++ pass ++rc2_key_st._fields_ = [ ++ ('data', c_uint * 64), ++] ++assert sizeof(rc2_key_st) == 256, sizeof(rc2_key_st) ++assert alignment(rc2_key_st) == 4, alignment(rc2_key_st) ++RC2_KEY = rc2_key_st ++class rc4_key_st(Structure): ++ pass ++rc4_key_st._fields_ = [ ++ ('x', c_ubyte), ++ ('y', c_ubyte), ++ ('data', c_ubyte * 256), ++] ++assert sizeof(rc4_key_st) == 258, sizeof(rc4_key_st) ++assert alignment(rc4_key_st) == 1, alignment(rc4_key_st) ++RC4_KEY = rc4_key_st ++class rc5_key_st(Structure): ++ pass ++rc5_key_st._fields_ = [ ++ ('rounds', c_int), ++ ('data', c_ulong * 34), ++] ++assert sizeof(rc5_key_st) == 140, sizeof(rc5_key_st) ++assert alignment(rc5_key_st) == 4, alignment(rc5_key_st) ++RC5_32_KEY = rc5_key_st ++class RIPEMD160state_st(Structure): ++ pass ++RIPEMD160state_st._fields_ = [ ++ ('A', c_uint), ++ ('B', c_uint), ++ ('C', c_uint), ++ ('D', c_uint), ++ ('E', c_uint), ++ ('Nl', c_uint), ++ ('Nh', c_uint), ++ ('data', c_uint * 16), ++ ('num', c_int), ++] ++assert sizeof(RIPEMD160state_st) == 96, sizeof(RIPEMD160state_st) ++assert alignment(RIPEMD160state_st) == 4, alignment(RIPEMD160state_st) ++RIPEMD160_CTX = RIPEMD160state_st ++RSA = rsa_st ++class rsa_meth_st(Structure): ++ pass ++rsa_meth_st._fields_ = [ ++ ('name', STRING), ++ ('rsa_pub_enc', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), POINTER(c_ubyte), POINTER(RSA), c_int)), ++ ('rsa_pub_dec', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), POINTER(c_ubyte), POINTER(RSA), c_int)), ++ ('rsa_priv_enc', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), POINTER(c_ubyte), POINTER(RSA), c_int)), ++ ('rsa_priv_dec', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), POINTER(c_ubyte), POINTER(RSA), c_int)), ++ ('rsa_mod_exp', CFUNCTYPE(c_int, POINTER(BIGNUM), POINTER(BIGNUM), POINTER(RSA))), ++ ('bn_mod_exp', CFUNCTYPE(c_int, POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BN_CTX), POINTER(BN_MONT_CTX))), ++ ('init', CFUNCTYPE(c_int, POINTER(RSA))), ++ ('finish', CFUNCTYPE(c_int, POINTER(RSA))), ++ ('flags', c_int), ++ ('app_data', STRING), ++ ('rsa_sign', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), c_uint, POINTER(c_ubyte), POINTER(c_uint), POINTER(RSA))), ++ ('rsa_verify', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), c_uint, POINTER(c_ubyte), c_uint, POINTER(RSA))), ++] ++assert sizeof(rsa_meth_st) == 52, sizeof(rsa_meth_st) ++assert alignment(rsa_meth_st) == 4, alignment(rsa_meth_st) ++RSA_METHOD = rsa_meth_st ++rsa_st._fields_ = [ ++ ('pad', c_int), ++ ('version', c_long), ++ ('meth', POINTER(RSA_METHOD)), ++ ('engine', POINTER(ENGINE)), ++ ('n', POINTER(BIGNUM)), ++ ('e', POINTER(BIGNUM)), ++ ('d', POINTER(BIGNUM)), ++ ('p', POINTER(BIGNUM)), ++ ('q', POINTER(BIGNUM)), ++ ('dmp1', POINTER(BIGNUM)), ++ ('dmq1', POINTER(BIGNUM)), ++ ('iqmp', POINTER(BIGNUM)), ++ ('ex_data', CRYPTO_EX_DATA), ++ ('references', c_int), ++ ('flags', c_int), ++ ('_method_mod_n', POINTER(BN_MONT_CTX)), ++ ('_method_mod_p', POINTER(BN_MONT_CTX)), ++ ('_method_mod_q', POINTER(BN_MONT_CTX)), ++ ('bignum_data', STRING), ++ ('blinding', POINTER(BN_BLINDING)), ++] ++assert sizeof(rsa_st) == 84, sizeof(rsa_st) ++assert alignment(rsa_st) == 4, alignment(rsa_st) ++openssl_fptr = CFUNCTYPE(None) ++class SHAstate_st(Structure): ++ pass ++SHAstate_st._fields_ = [ ++ ('h0', c_uint), ++ ('h1', c_uint), ++ ('h2', c_uint), ++ ('h3', c_uint), ++ ('h4', c_uint), ++ ('Nl', c_uint), ++ ('Nh', c_uint), ++ ('data', c_uint * 16), ++ ('num', c_int), ++] ++assert sizeof(SHAstate_st) == 96, sizeof(SHAstate_st) ++assert alignment(SHAstate_st) == 4, alignment(SHAstate_st) ++SHA_CTX = SHAstate_st ++class ssl_st(Structure): ++ pass ++ssl_crock_st = POINTER(ssl_st) ++class ssl_cipher_st(Structure): ++ pass ++ssl_cipher_st._fields_ = [ ++ ('valid', c_int), ++ ('name', STRING), ++ ('id', c_ulong), ++ ('algorithms', c_ulong), ++ ('algo_strength', c_ulong), ++ ('algorithm2', c_ulong), ++ ('strength_bits', c_int), ++ ('alg_bits', c_int), ++ ('mask', c_ulong), ++ ('mask_strength', c_ulong), ++] ++assert sizeof(ssl_cipher_st) == 40, sizeof(ssl_cipher_st) ++assert alignment(ssl_cipher_st) == 4, alignment(ssl_cipher_st) ++SSL_CIPHER = ssl_cipher_st ++SSL = ssl_st ++class ssl_ctx_st(Structure): ++ pass ++SSL_CTX = ssl_ctx_st ++class ssl_method_st(Structure): ++ pass ++class ssl3_enc_method(Structure): ++ pass ++ssl_method_st._fields_ = [ ++ ('version', c_int), ++ ('ssl_new', CFUNCTYPE(c_int, POINTER(SSL))), ++ ('ssl_clear', CFUNCTYPE(None, POINTER(SSL))), ++ ('ssl_free', CFUNCTYPE(None, POINTER(SSL))), ++ ('ssl_accept', CFUNCTYPE(c_int, POINTER(SSL))), ++ ('ssl_connect', CFUNCTYPE(c_int, POINTER(SSL))), ++ ('ssl_read', CFUNCTYPE(c_int, POINTER(SSL), c_void_p, c_int)), ++ ('ssl_peek', CFUNCTYPE(c_int, POINTER(SSL), c_void_p, c_int)), ++ ('ssl_write', CFUNCTYPE(c_int, POINTER(SSL), c_void_p, c_int)), ++ ('ssl_shutdown', CFUNCTYPE(c_int, POINTER(SSL))), ++ ('ssl_renegotiate', CFUNCTYPE(c_int, POINTER(SSL))), ++ ('ssl_renegotiate_check', CFUNCTYPE(c_int, POINTER(SSL))), ++ ('ssl_ctrl', CFUNCTYPE(c_long, POINTER(SSL), c_int, c_long, c_void_p)), ++ ('ssl_ctx_ctrl', CFUNCTYPE(c_long, POINTER(SSL_CTX), c_int, c_long, c_void_p)), ++ ('get_cipher_by_char', CFUNCTYPE(POINTER(SSL_CIPHER), POINTER(c_ubyte))), ++ ('put_cipher_by_char', CFUNCTYPE(c_int, POINTER(SSL_CIPHER), POINTER(c_ubyte))), ++ ('ssl_pending', CFUNCTYPE(c_int, POINTER(SSL))), ++ ('num_ciphers', CFUNCTYPE(c_int)), ++ ('get_cipher', CFUNCTYPE(POINTER(SSL_CIPHER), c_uint)), ++ ('get_ssl_method', CFUNCTYPE(POINTER(ssl_method_st), c_int)), ++ ('get_timeout', CFUNCTYPE(c_long)), ++ ('ssl3_enc', POINTER(ssl3_enc_method)), ++ ('ssl_version', CFUNCTYPE(c_int)), ++ ('ssl_callback_ctrl', CFUNCTYPE(c_long, POINTER(SSL), c_int, CFUNCTYPE(None))), ++ ('ssl_ctx_callback_ctrl', CFUNCTYPE(c_long, POINTER(SSL_CTX), c_int, CFUNCTYPE(None))), ++] ++assert sizeof(ssl_method_st) == 100, sizeof(ssl_method_st) ++assert alignment(ssl_method_st) == 4, alignment(ssl_method_st) ++ssl3_enc_method._fields_ = [ ++] ++SSL_METHOD = ssl_method_st ++class ssl_session_st(Structure): ++ pass ++class sess_cert_st(Structure): ++ pass ++ssl_session_st._fields_ = [ ++ ('ssl_version', c_int), ++ ('key_arg_length', c_uint), ++ ('key_arg', c_ubyte * 8), ++ ('master_key_length', c_int), ++ ('master_key', c_ubyte * 48), ++ ('session_id_length', c_uint), ++ ('session_id', c_ubyte * 32), ++ ('sid_ctx_length', c_uint), ++ ('sid_ctx', c_ubyte * 32), ++ ('not_resumable', c_int), ++ ('sess_cert', POINTER(sess_cert_st)), ++ ('peer', POINTER(X509)), ++ ('verify_result', c_long), ++ ('references', c_int), ++ ('timeout', c_long), ++ ('time', c_long), ++ ('compress_meth', c_int), ++ ('cipher', POINTER(SSL_CIPHER)), ++ ('cipher_id', c_ulong), ++ ('ciphers', POINTER(STACK)), ++ ('ex_data', CRYPTO_EX_DATA), ++ ('prev', POINTER(ssl_session_st)), ++ ('next', POINTER(ssl_session_st)), ++] ++assert sizeof(ssl_session_st) == 200, sizeof(ssl_session_st) ++assert alignment(ssl_session_st) == 4, alignment(ssl_session_st) ++sess_cert_st._fields_ = [ ++] ++SSL_SESSION = ssl_session_st ++GEN_SESSION_CB = CFUNCTYPE(c_int, POINTER(SSL), POINTER(c_ubyte), POINTER(c_uint)) ++class ssl_comp_st(Structure): ++ pass ++ssl_comp_st._fields_ = [ ++ ('id', c_int), ++ ('name', STRING), ++ ('method', POINTER(COMP_METHOD)), ++] ++assert sizeof(ssl_comp_st) == 12, sizeof(ssl_comp_st) ++assert alignment(ssl_comp_st) == 4, alignment(ssl_comp_st) ++SSL_COMP = ssl_comp_st ++class N10ssl_ctx_st4DOLLAR_18E(Structure): ++ pass ++N10ssl_ctx_st4DOLLAR_18E._fields_ = [ ++ ('sess_connect', c_int), ++ ('sess_connect_renegotiate', c_int), ++ ('sess_connect_good', c_int), ++ ('sess_accept', c_int), ++ ('sess_accept_renegotiate', c_int), ++ ('sess_accept_good', c_int), ++ ('sess_miss', c_int), ++ ('sess_timeout', c_int), ++ ('sess_cache_full', c_int), ++ ('sess_hit', c_int), ++ ('sess_cb_hit', c_int), ++] ++assert sizeof(N10ssl_ctx_st4DOLLAR_18E) == 44, sizeof(N10ssl_ctx_st4DOLLAR_18E) ++assert alignment(N10ssl_ctx_st4DOLLAR_18E) == 4, alignment(N10ssl_ctx_st4DOLLAR_18E) ++class cert_st(Structure): ++ pass ++ssl_ctx_st._fields_ = [ ++ ('method', POINTER(SSL_METHOD)), ++ ('cipher_list', POINTER(STACK)), ++ ('cipher_list_by_id', POINTER(STACK)), ++ ('cert_store', POINTER(x509_store_st)), ++ ('sessions', POINTER(lhash_st)), ++ ('session_cache_size', c_ulong), ++ ('session_cache_head', POINTER(ssl_session_st)), ++ ('session_cache_tail', POINTER(ssl_session_st)), ++ ('session_cache_mode', c_int), ++ ('session_timeout', c_long), ++ ('new_session_cb', CFUNCTYPE(c_int, POINTER(ssl_st), POINTER(SSL_SESSION))), ++ ('remove_session_cb', CFUNCTYPE(None, POINTER(ssl_ctx_st), POINTER(SSL_SESSION))), ++ ('get_session_cb', CFUNCTYPE(POINTER(SSL_SESSION), POINTER(ssl_st), POINTER(c_ubyte), c_int, POINTER(c_int))), ++ ('stats', N10ssl_ctx_st4DOLLAR_18E), ++ ('references', c_int), ++ ('app_verify_callback', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), c_void_p)), ++ ('app_verify_arg', c_void_p), ++ ('default_passwd_callback', POINTER(pem_password_cb)), ++ ('default_passwd_callback_userdata', c_void_p), ++ ('client_cert_cb', CFUNCTYPE(c_int, POINTER(SSL), POINTER(POINTER(X509)), POINTER(POINTER(EVP_PKEY)))), ++ ('ex_data', CRYPTO_EX_DATA), ++ ('rsa_md5', POINTER(EVP_MD)), ++ ('md5', POINTER(EVP_MD)), ++ ('sha1', POINTER(EVP_MD)), ++ ('extra_certs', POINTER(STACK)), ++ ('comp_methods', POINTER(STACK)), ++ ('info_callback', CFUNCTYPE(None, POINTER(SSL), c_int, c_int)), ++ ('client_CA', POINTER(STACK)), ++ ('options', c_ulong), ++ ('mode', c_ulong), ++ ('max_cert_list', c_long), ++ ('cert', POINTER(cert_st)), ++ ('read_ahead', c_int), ++ ('msg_callback', CFUNCTYPE(None, c_int, c_int, c_int, c_void_p, c_ulong, POINTER(SSL), c_void_p)), ++ ('msg_callback_arg', c_void_p), ++ ('verify_mode', c_int), ++ ('verify_depth', c_int), ++ ('sid_ctx_length', c_uint), ++ ('sid_ctx', c_ubyte * 32), ++ ('default_verify_callback', CFUNCTYPE(c_int, c_int, POINTER(X509_STORE_CTX))), ++ ('generate_session_id', GEN_SESSION_CB), ++ ('purpose', c_int), ++ ('trust', c_int), ++ ('quiet_shutdown', c_int), ++] ++assert sizeof(ssl_ctx_st) == 248, sizeof(ssl_ctx_st) ++assert alignment(ssl_ctx_st) == 4, alignment(ssl_ctx_st) ++cert_st._fields_ = [ ++] ++class ssl2_state_st(Structure): ++ pass ++class ssl3_state_st(Structure): ++ pass ++ssl_st._fields_ = [ ++ ('version', c_int), ++ ('type', c_int), ++ ('method', POINTER(SSL_METHOD)), ++ ('rbio', POINTER(BIO)), ++ ('wbio', POINTER(BIO)), ++ ('bbio', POINTER(BIO)), ++ ('rwstate', c_int), ++ ('in_handshake', c_int), ++ ('handshake_func', CFUNCTYPE(c_int)), ++ ('server', c_int), ++ ('new_session', c_int), ++ ('quiet_shutdown', c_int), ++ ('shutdown', c_int), ++ ('state', c_int), ++ ('rstate', c_int), ++ ('init_buf', POINTER(BUF_MEM)), ++ ('init_msg', c_void_p), ++ ('init_num', c_int), ++ ('init_off', c_int), ++ ('packet', POINTER(c_ubyte)), ++ ('packet_length', c_uint), ++ ('s2', POINTER(ssl2_state_st)), ++ ('s3', POINTER(ssl3_state_st)), ++ ('read_ahead', c_int), ++ ('msg_callback', CFUNCTYPE(None, c_int, c_int, c_int, c_void_p, c_ulong, POINTER(SSL), c_void_p)), ++ ('msg_callback_arg', c_void_p), ++ ('hit', c_int), ++ ('purpose', c_int), ++ ('trust', c_int), ++ ('cipher_list', POINTER(STACK)), ++ ('cipher_list_by_id', POINTER(STACK)), ++ ('enc_read_ctx', POINTER(EVP_CIPHER_CTX)), ++ ('read_hash', POINTER(EVP_MD)), ++ ('expand', POINTER(COMP_CTX)), ++ ('enc_write_ctx', POINTER(EVP_CIPHER_CTX)), ++ ('write_hash', POINTER(EVP_MD)), ++ ('compress', POINTER(COMP_CTX)), ++ ('cert', POINTER(cert_st)), ++ ('sid_ctx_length', c_uint), ++ ('sid_ctx', c_ubyte * 32), ++ ('session', POINTER(SSL_SESSION)), ++ ('generate_session_id', GEN_SESSION_CB), ++ ('verify_mode', c_int), ++ ('verify_depth', c_int), ++ ('verify_callback', CFUNCTYPE(c_int, c_int, POINTER(X509_STORE_CTX))), ++ ('info_callback', CFUNCTYPE(None, POINTER(SSL), c_int, c_int)), ++ ('error', c_int), ++ ('error_code', c_int), ++ ('ctx', POINTER(SSL_CTX)), ++ ('debug', c_int), ++ ('verify_result', c_long), ++ ('ex_data', CRYPTO_EX_DATA), ++ ('client_CA', POINTER(STACK)), ++ ('references', c_int), ++ ('options', c_ulong), ++ ('mode', c_ulong), ++ ('max_cert_list', c_long), ++ ('first_packet', c_int), ++ ('client_version', c_int), ++] ++assert sizeof(ssl_st) == 268, sizeof(ssl_st) ++assert alignment(ssl_st) == 4, alignment(ssl_st) ++class N13ssl2_state_st4DOLLAR_19E(Structure): ++ pass ++N13ssl2_state_st4DOLLAR_19E._fields_ = [ ++ ('conn_id_length', c_uint), ++ ('cert_type', c_uint), ++ ('cert_length', c_uint), ++ ('csl', c_uint), ++ ('clear', c_uint), ++ ('enc', c_uint), ++ ('ccl', c_ubyte * 32), ++ ('cipher_spec_length', c_uint), ++ ('session_id_length', c_uint), ++ ('clen', c_uint), ++ ('rlen', c_uint), ++] ++assert sizeof(N13ssl2_state_st4DOLLAR_19E) == 72, sizeof(N13ssl2_state_st4DOLLAR_19E) ++assert alignment(N13ssl2_state_st4DOLLAR_19E) == 4, alignment(N13ssl2_state_st4DOLLAR_19E) ++ssl2_state_st._fields_ = [ ++ ('three_byte_header', c_int), ++ ('clear_text', c_int), ++ ('escape', c_int), ++ ('ssl2_rollback', c_int), ++ ('wnum', c_uint), ++ ('wpend_tot', c_int), ++ ('wpend_buf', POINTER(c_ubyte)), ++ ('wpend_off', c_int), ++ ('wpend_len', c_int), ++ ('wpend_ret', c_int), ++ ('rbuf_left', c_int), ++ ('rbuf_offs', c_int), ++ ('rbuf', POINTER(c_ubyte)), ++ ('wbuf', POINTER(c_ubyte)), ++ ('write_ptr', POINTER(c_ubyte)), ++ ('padding', c_uint), ++ ('rlength', c_uint), ++ ('ract_data_length', c_int), ++ ('wlength', c_uint), ++ ('wact_data_length', c_int), ++ ('ract_data', POINTER(c_ubyte)), ++ ('wact_data', POINTER(c_ubyte)), ++ ('mac_data', POINTER(c_ubyte)), ++ ('read_key', POINTER(c_ubyte)), ++ ('write_key', POINTER(c_ubyte)), ++ ('challenge_length', c_uint), ++ ('challenge', c_ubyte * 32), ++ ('conn_id_length', c_uint), ++ ('conn_id', c_ubyte * 16), ++ ('key_material_length', c_uint), ++ ('key_material', c_ubyte * 48), ++ ('read_sequence', c_ulong), ++ ('write_sequence', c_ulong), ++ ('tmp', N13ssl2_state_st4DOLLAR_19E), ++] ++assert sizeof(ssl2_state_st) == 288, sizeof(ssl2_state_st) ++assert alignment(ssl2_state_st) == 4, alignment(ssl2_state_st) ++SSL2_STATE = ssl2_state_st ++class ssl3_record_st(Structure): ++ pass ++ssl3_record_st._fields_ = [ ++ ('type', c_int), ++ ('length', c_uint), ++ ('off', c_uint), ++ ('data', POINTER(c_ubyte)), ++ ('input', POINTER(c_ubyte)), ++ ('comp', POINTER(c_ubyte)), ++] ++assert sizeof(ssl3_record_st) == 24, sizeof(ssl3_record_st) ++assert alignment(ssl3_record_st) == 4, alignment(ssl3_record_st) ++SSL3_RECORD = ssl3_record_st ++class ssl3_buffer_st(Structure): ++ pass ++size_t = __darwin_size_t ++ssl3_buffer_st._fields_ = [ ++ ('buf', POINTER(c_ubyte)), ++ ('len', size_t), ++ ('offset', c_int), ++ ('left', c_int), ++] ++assert sizeof(ssl3_buffer_st) == 16, sizeof(ssl3_buffer_st) ++assert alignment(ssl3_buffer_st) == 4, alignment(ssl3_buffer_st) ++SSL3_BUFFER = ssl3_buffer_st ++class N13ssl3_state_st4DOLLAR_20E(Structure): ++ pass ++N13ssl3_state_st4DOLLAR_20E._fields_ = [ ++ ('cert_verify_md', c_ubyte * 72), ++ ('finish_md', c_ubyte * 72), ++ ('finish_md_len', c_int), ++ ('peer_finish_md', c_ubyte * 72), ++ ('peer_finish_md_len', c_int), ++ ('message_size', c_ulong), ++ ('message_type', c_int), ++ ('new_cipher', POINTER(SSL_CIPHER)), ++ ('dh', POINTER(DH)), ++ ('next_state', c_int), ++ ('reuse_message', c_int), ++ ('cert_req', c_int), ++ ('ctype_num', c_int), ++ ('ctype', c_char * 7), ++ ('ca_names', POINTER(STACK)), ++ ('use_rsa_tmp', c_int), ++ ('key_block_length', c_int), ++ ('key_block', POINTER(c_ubyte)), ++ ('new_sym_enc', POINTER(EVP_CIPHER)), ++ ('new_hash', POINTER(EVP_MD)), ++ ('new_compression', POINTER(SSL_COMP)), ++ ('cert_request', c_int), ++] ++assert sizeof(N13ssl3_state_st4DOLLAR_20E) == 296, sizeof(N13ssl3_state_st4DOLLAR_20E) ++assert alignment(N13ssl3_state_st4DOLLAR_20E) == 4, alignment(N13ssl3_state_st4DOLLAR_20E) ++ssl3_state_st._fields_ = [ ++ ('flags', c_long), ++ ('delay_buf_pop_ret', c_int), ++ ('read_sequence', c_ubyte * 8), ++ ('read_mac_secret', c_ubyte * 36), ++ ('write_sequence', c_ubyte * 8), ++ ('write_mac_secret', c_ubyte * 36), ++ ('server_random', c_ubyte * 32), ++ ('client_random', c_ubyte * 32), ++ ('need_empty_fragments', c_int), ++ ('empty_fragment_done', c_int), ++ ('rbuf', SSL3_BUFFER), ++ ('wbuf', SSL3_BUFFER), ++ ('rrec', SSL3_RECORD), ++ ('wrec', SSL3_RECORD), ++ ('alert_fragment', c_ubyte * 2), ++ ('alert_fragment_len', c_uint), ++ ('handshake_fragment', c_ubyte * 4), ++ ('handshake_fragment_len', c_uint), ++ ('wnum', c_uint), ++ ('wpend_tot', c_int), ++ ('wpend_type', c_int), ++ ('wpend_ret', c_int), ++ ('wpend_buf', POINTER(c_ubyte)), ++ ('finish_dgst1', EVP_MD_CTX), ++ ('finish_dgst2', EVP_MD_CTX), ++ ('change_cipher_spec', c_int), ++ ('warn_alert', c_int), ++ ('fatal_alert', c_int), ++ ('alert_dispatch', c_int), ++ ('send_alert', c_ubyte * 2), ++ ('renegotiate', c_int), ++ ('total_renegotiations', c_int), ++ ('num_renegotiations', c_int), ++ ('in_read_app_data', c_int), ++ ('tmp', N13ssl3_state_st4DOLLAR_20E), ++] ++assert sizeof(ssl3_state_st) == 648, sizeof(ssl3_state_st) ++assert alignment(ssl3_state_st) == 4, alignment(ssl3_state_st) ++SSL3_STATE = ssl3_state_st ++stack_st._fields_ = [ ++ ('num', c_int), ++ ('data', POINTER(STRING)), ++ ('sorted', c_int), ++ ('num_alloc', c_int), ++ ('comp', CFUNCTYPE(c_int, POINTER(STRING), POINTER(STRING))), ++] ++assert sizeof(stack_st) == 20, sizeof(stack_st) ++assert alignment(stack_st) == 4, alignment(stack_st) ++class ui_st(Structure): ++ pass ++ui_st._fields_ = [ ++] ++UI = ui_st ++class ui_method_st(Structure): ++ pass ++ui_method_st._fields_ = [ ++] ++UI_METHOD = ui_method_st ++class ui_string_st(Structure): ++ pass ++ui_string_st._fields_ = [ ++] ++UI_STRING = ui_string_st ++ ++# values for enumeration 'UI_string_types' ++UI_string_types = c_int # enum ++class X509_objects_st(Structure): ++ pass ++X509_objects_st._fields_ = [ ++ ('nid', c_int), ++ ('a2i', CFUNCTYPE(c_int)), ++ ('i2a', CFUNCTYPE(c_int)), ++] ++assert sizeof(X509_objects_st) == 12, sizeof(X509_objects_st) ++assert alignment(X509_objects_st) == 4, alignment(X509_objects_st) ++X509_OBJECTS = X509_objects_st ++X509_algor_st._fields_ = [ ++ ('algorithm', POINTER(ASN1_OBJECT)), ++ ('parameter', POINTER(ASN1_TYPE)), ++] ++assert sizeof(X509_algor_st) == 8, sizeof(X509_algor_st) ++assert alignment(X509_algor_st) == 4, alignment(X509_algor_st) ++class X509_val_st(Structure): ++ pass ++X509_val_st._fields_ = [ ++ ('notBefore', POINTER(ASN1_TIME)), ++ ('notAfter', POINTER(ASN1_TIME)), ++] ++assert sizeof(X509_val_st) == 8, sizeof(X509_val_st) ++assert alignment(X509_val_st) == 4, alignment(X509_val_st) ++X509_VAL = X509_val_st ++class X509_pubkey_st(Structure): ++ pass ++X509_pubkey_st._fields_ = [ ++ ('algor', POINTER(X509_ALGOR)), ++ ('public_key', POINTER(ASN1_BIT_STRING)), ++ ('pkey', POINTER(EVP_PKEY)), ++] ++assert sizeof(X509_pubkey_st) == 12, sizeof(X509_pubkey_st) ++assert alignment(X509_pubkey_st) == 4, alignment(X509_pubkey_st) ++X509_PUBKEY = X509_pubkey_st ++class X509_sig_st(Structure): ++ pass ++X509_sig_st._fields_ = [ ++ ('algor', POINTER(X509_ALGOR)), ++ ('digest', POINTER(ASN1_OCTET_STRING)), ++] ++assert sizeof(X509_sig_st) == 8, sizeof(X509_sig_st) ++assert alignment(X509_sig_st) == 4, alignment(X509_sig_st) ++X509_SIG = X509_sig_st ++class X509_name_entry_st(Structure): ++ pass ++X509_name_entry_st._fields_ = [ ++ ('object', POINTER(ASN1_OBJECT)), ++ ('value', POINTER(ASN1_STRING)), ++ ('set', c_int), ++ ('size', c_int), ++] ++assert sizeof(X509_name_entry_st) == 16, sizeof(X509_name_entry_st) ++assert alignment(X509_name_entry_st) == 4, alignment(X509_name_entry_st) ++X509_NAME_ENTRY = X509_name_entry_st ++X509_name_st._fields_ = [ ++ ('entries', POINTER(STACK)), ++ ('modified', c_int), ++ ('bytes', POINTER(BUF_MEM)), ++ ('hash', c_ulong), ++] ++assert sizeof(X509_name_st) == 16, sizeof(X509_name_st) ++assert alignment(X509_name_st) == 4, alignment(X509_name_st) ++class X509_extension_st(Structure): ++ pass ++X509_extension_st._fields_ = [ ++ ('object', POINTER(ASN1_OBJECT)), ++ ('critical', ASN1_BOOLEAN), ++ ('value', POINTER(ASN1_OCTET_STRING)), ++] ++assert sizeof(X509_extension_st) == 12, sizeof(X509_extension_st) ++assert alignment(X509_extension_st) == 4, alignment(X509_extension_st) ++X509_EXTENSION = X509_extension_st ++class x509_attributes_st(Structure): ++ pass ++class N18x509_attributes_st4DOLLAR_13E(Union): ++ pass ++N18x509_attributes_st4DOLLAR_13E._fields_ = [ ++ ('ptr', STRING), ++ ('set', POINTER(STACK)), ++ ('single', POINTER(ASN1_TYPE)), ++] ++assert sizeof(N18x509_attributes_st4DOLLAR_13E) == 4, sizeof(N18x509_attributes_st4DOLLAR_13E) ++assert alignment(N18x509_attributes_st4DOLLAR_13E) == 4, alignment(N18x509_attributes_st4DOLLAR_13E) ++x509_attributes_st._fields_ = [ ++ ('object', POINTER(ASN1_OBJECT)), ++ ('single', c_int), ++ ('value', N18x509_attributes_st4DOLLAR_13E), ++] ++assert sizeof(x509_attributes_st) == 12, sizeof(x509_attributes_st) ++assert alignment(x509_attributes_st) == 4, alignment(x509_attributes_st) ++X509_ATTRIBUTE = x509_attributes_st ++class X509_req_info_st(Structure): ++ pass ++X509_req_info_st._fields_ = [ ++ ('enc', ASN1_ENCODING), ++ ('version', POINTER(ASN1_INTEGER)), ++ ('subject', POINTER(X509_NAME)), ++ ('pubkey', POINTER(X509_PUBKEY)), ++ ('attributes', POINTER(STACK)), ++] ++assert sizeof(X509_req_info_st) == 28, sizeof(X509_req_info_st) ++assert alignment(X509_req_info_st) == 4, alignment(X509_req_info_st) ++X509_REQ_INFO = X509_req_info_st ++class X509_req_st(Structure): ++ pass ++X509_req_st._fields_ = [ ++ ('req_info', POINTER(X509_REQ_INFO)), ++ ('sig_alg', POINTER(X509_ALGOR)), ++ ('signature', POINTER(ASN1_BIT_STRING)), ++ ('references', c_int), ++] ++assert sizeof(X509_req_st) == 16, sizeof(X509_req_st) ++assert alignment(X509_req_st) == 4, alignment(X509_req_st) ++X509_REQ = X509_req_st ++class x509_cinf_st(Structure): ++ pass ++x509_cinf_st._fields_ = [ ++ ('version', POINTER(ASN1_INTEGER)), ++ ('serialNumber', POINTER(ASN1_INTEGER)), ++ ('signature', POINTER(X509_ALGOR)), ++ ('issuer', POINTER(X509_NAME)), ++ ('validity', POINTER(X509_VAL)), ++ ('subject', POINTER(X509_NAME)), ++ ('key', POINTER(X509_PUBKEY)), ++ ('issuerUID', POINTER(ASN1_BIT_STRING)), ++ ('subjectUID', POINTER(ASN1_BIT_STRING)), ++ ('extensions', POINTER(STACK)), ++] ++assert sizeof(x509_cinf_st) == 40, sizeof(x509_cinf_st) ++assert alignment(x509_cinf_st) == 4, alignment(x509_cinf_st) ++X509_CINF = x509_cinf_st ++class x509_cert_aux_st(Structure): ++ pass ++x509_cert_aux_st._fields_ = [ ++ ('trust', POINTER(STACK)), ++ ('reject', POINTER(STACK)), ++ ('alias', POINTER(ASN1_UTF8STRING)), ++ ('keyid', POINTER(ASN1_OCTET_STRING)), ++ ('other', POINTER(STACK)), ++] ++assert sizeof(x509_cert_aux_st) == 20, sizeof(x509_cert_aux_st) ++assert alignment(x509_cert_aux_st) == 4, alignment(x509_cert_aux_st) ++X509_CERT_AUX = x509_cert_aux_st ++class AUTHORITY_KEYID_st(Structure): ++ pass ++x509_st._fields_ = [ ++ ('cert_info', POINTER(X509_CINF)), ++ ('sig_alg', POINTER(X509_ALGOR)), ++ ('signature', POINTER(ASN1_BIT_STRING)), ++ ('valid', c_int), ++ ('references', c_int), ++ ('name', STRING), ++ ('ex_data', CRYPTO_EX_DATA), ++ ('ex_pathlen', c_long), ++ ('ex_flags', c_ulong), ++ ('ex_kusage', c_ulong), ++ ('ex_xkusage', c_ulong), ++ ('ex_nscert', c_ulong), ++ ('skid', POINTER(ASN1_OCTET_STRING)), ++ ('akid', POINTER(AUTHORITY_KEYID_st)), ++ ('sha1_hash', c_ubyte * 20), ++ ('aux', POINTER(X509_CERT_AUX)), ++] ++assert sizeof(x509_st) == 84, sizeof(x509_st) ++assert alignment(x509_st) == 4, alignment(x509_st) ++AUTHORITY_KEYID_st._fields_ = [ ++] ++class x509_trust_st(Structure): ++ pass ++x509_trust_st._fields_ = [ ++ ('trust', c_int), ++ ('flags', c_int), ++ ('check_trust', CFUNCTYPE(c_int, POINTER(x509_trust_st), POINTER(X509), c_int)), ++ ('name', STRING), ++ ('arg1', c_int), ++ ('arg2', c_void_p), ++] ++assert sizeof(x509_trust_st) == 24, sizeof(x509_trust_st) ++assert alignment(x509_trust_st) == 4, alignment(x509_trust_st) ++X509_TRUST = x509_trust_st ++class X509_revoked_st(Structure): ++ pass ++X509_revoked_st._fields_ = [ ++ ('serialNumber', POINTER(ASN1_INTEGER)), ++ ('revocationDate', POINTER(ASN1_TIME)), ++ ('extensions', POINTER(STACK)), ++ ('sequence', c_int), ++] ++assert sizeof(X509_revoked_st) == 16, sizeof(X509_revoked_st) ++assert alignment(X509_revoked_st) == 4, alignment(X509_revoked_st) ++X509_REVOKED = X509_revoked_st ++class X509_crl_info_st(Structure): ++ pass ++X509_crl_info_st._fields_ = [ ++ ('version', POINTER(ASN1_INTEGER)), ++ ('sig_alg', POINTER(X509_ALGOR)), ++ ('issuer', POINTER(X509_NAME)), ++ ('lastUpdate', POINTER(ASN1_TIME)), ++ ('nextUpdate', POINTER(ASN1_TIME)), ++ ('revoked', POINTER(STACK)), ++ ('extensions', POINTER(STACK)), ++ ('enc', ASN1_ENCODING), ++] ++assert sizeof(X509_crl_info_st) == 40, sizeof(X509_crl_info_st) ++assert alignment(X509_crl_info_st) == 4, alignment(X509_crl_info_st) ++X509_CRL_INFO = X509_crl_info_st ++X509_crl_st._fields_ = [ ++ ('crl', POINTER(X509_CRL_INFO)), ++ ('sig_alg', POINTER(X509_ALGOR)), ++ ('signature', POINTER(ASN1_BIT_STRING)), ++ ('references', c_int), ++] ++assert sizeof(X509_crl_st) == 16, sizeof(X509_crl_st) ++assert alignment(X509_crl_st) == 4, alignment(X509_crl_st) ++class private_key_st(Structure): ++ pass ++private_key_st._fields_ = [ ++ ('version', c_int), ++ ('enc_algor', POINTER(X509_ALGOR)), ++ ('enc_pkey', POINTER(ASN1_OCTET_STRING)), ++ ('dec_pkey', POINTER(EVP_PKEY)), ++ ('key_length', c_int), ++ ('key_data', STRING), ++ ('key_free', c_int), ++ ('cipher', EVP_CIPHER_INFO), ++ ('references', c_int), ++] ++assert sizeof(private_key_st) == 52, sizeof(private_key_st) ++assert alignment(private_key_st) == 4, alignment(private_key_st) ++X509_PKEY = private_key_st ++class X509_info_st(Structure): ++ pass ++X509_info_st._fields_ = [ ++ ('x509', POINTER(X509)), ++ ('crl', POINTER(X509_CRL)), ++ ('x_pkey', POINTER(X509_PKEY)), ++ ('enc_cipher', EVP_CIPHER_INFO), ++ ('enc_len', c_int), ++ ('enc_data', STRING), ++ ('references', c_int), ++] ++assert sizeof(X509_info_st) == 44, sizeof(X509_info_st) ++assert alignment(X509_info_st) == 4, alignment(X509_info_st) ++X509_INFO = X509_info_st ++class Netscape_spkac_st(Structure): ++ pass ++Netscape_spkac_st._fields_ = [ ++ ('pubkey', POINTER(X509_PUBKEY)), ++ ('challenge', POINTER(ASN1_IA5STRING)), ++] ++assert sizeof(Netscape_spkac_st) == 8, sizeof(Netscape_spkac_st) ++assert alignment(Netscape_spkac_st) == 4, alignment(Netscape_spkac_st) ++NETSCAPE_SPKAC = Netscape_spkac_st ++class Netscape_spki_st(Structure): ++ pass ++Netscape_spki_st._fields_ = [ ++ ('spkac', POINTER(NETSCAPE_SPKAC)), ++ ('sig_algor', POINTER(X509_ALGOR)), ++ ('signature', POINTER(ASN1_BIT_STRING)), ++] ++assert sizeof(Netscape_spki_st) == 12, sizeof(Netscape_spki_st) ++assert alignment(Netscape_spki_st) == 4, alignment(Netscape_spki_st) ++NETSCAPE_SPKI = Netscape_spki_st ++class Netscape_certificate_sequence(Structure): ++ pass ++Netscape_certificate_sequence._fields_ = [ ++ ('type', POINTER(ASN1_OBJECT)), ++ ('certs', POINTER(STACK)), ++] ++assert sizeof(Netscape_certificate_sequence) == 8, sizeof(Netscape_certificate_sequence) ++assert alignment(Netscape_certificate_sequence) == 4, alignment(Netscape_certificate_sequence) ++NETSCAPE_CERT_SEQUENCE = Netscape_certificate_sequence ++class PBEPARAM_st(Structure): ++ pass ++PBEPARAM_st._fields_ = [ ++ ('salt', POINTER(ASN1_OCTET_STRING)), ++ ('iter', POINTER(ASN1_INTEGER)), ++] ++assert sizeof(PBEPARAM_st) == 8, sizeof(PBEPARAM_st) ++assert alignment(PBEPARAM_st) == 4, alignment(PBEPARAM_st) ++PBEPARAM = PBEPARAM_st ++class PBE2PARAM_st(Structure): ++ pass ++PBE2PARAM_st._fields_ = [ ++ ('keyfunc', POINTER(X509_ALGOR)), ++ ('encryption', POINTER(X509_ALGOR)), ++] ++assert sizeof(PBE2PARAM_st) == 8, sizeof(PBE2PARAM_st) ++assert alignment(PBE2PARAM_st) == 4, alignment(PBE2PARAM_st) ++PBE2PARAM = PBE2PARAM_st ++class PBKDF2PARAM_st(Structure): ++ pass ++PBKDF2PARAM_st._fields_ = [ ++ ('salt', POINTER(ASN1_TYPE)), ++ ('iter', POINTER(ASN1_INTEGER)), ++ ('keylength', POINTER(ASN1_INTEGER)), ++ ('prf', POINTER(X509_ALGOR)), ++] ++assert sizeof(PBKDF2PARAM_st) == 16, sizeof(PBKDF2PARAM_st) ++assert alignment(PBKDF2PARAM_st) == 4, alignment(PBKDF2PARAM_st) ++PBKDF2PARAM = PBKDF2PARAM_st ++class pkcs8_priv_key_info_st(Structure): ++ pass ++pkcs8_priv_key_info_st._fields_ = [ ++ ('broken', c_int), ++ ('version', POINTER(ASN1_INTEGER)), ++ ('pkeyalg', POINTER(X509_ALGOR)), ++ ('pkey', POINTER(ASN1_TYPE)), ++ ('attributes', POINTER(STACK)), ++] ++assert sizeof(pkcs8_priv_key_info_st) == 20, sizeof(pkcs8_priv_key_info_st) ++assert alignment(pkcs8_priv_key_info_st) == 4, alignment(pkcs8_priv_key_info_st) ++PKCS8_PRIV_KEY_INFO = pkcs8_priv_key_info_st ++class x509_hash_dir_st(Structure): ++ pass ++x509_hash_dir_st._fields_ = [ ++ ('num_dirs', c_int), ++ ('dirs', POINTER(STRING)), ++ ('dirs_type', POINTER(c_int)), ++ ('num_dirs_alloced', c_int), ++] ++assert sizeof(x509_hash_dir_st) == 16, sizeof(x509_hash_dir_st) ++assert alignment(x509_hash_dir_st) == 4, alignment(x509_hash_dir_st) ++X509_HASH_DIR_CTX = x509_hash_dir_st ++class x509_file_st(Structure): ++ pass ++x509_file_st._fields_ = [ ++ ('num_paths', c_int), ++ ('num_alloced', c_int), ++ ('paths', POINTER(STRING)), ++ ('path_type', POINTER(c_int)), ++] ++assert sizeof(x509_file_st) == 16, sizeof(x509_file_st) ++assert alignment(x509_file_st) == 4, alignment(x509_file_st) ++X509_CERT_FILE_CTX = x509_file_st ++class x509_object_st(Structure): ++ pass ++class N14x509_object_st4DOLLAR_14E(Union): ++ pass ++N14x509_object_st4DOLLAR_14E._fields_ = [ ++ ('ptr', STRING), ++ ('x509', POINTER(X509)), ++ ('crl', POINTER(X509_CRL)), ++ ('pkey', POINTER(EVP_PKEY)), ++] ++assert sizeof(N14x509_object_st4DOLLAR_14E) == 4, sizeof(N14x509_object_st4DOLLAR_14E) ++assert alignment(N14x509_object_st4DOLLAR_14E) == 4, alignment(N14x509_object_st4DOLLAR_14E) ++x509_object_st._fields_ = [ ++ ('type', c_int), ++ ('data', N14x509_object_st4DOLLAR_14E), ++] ++assert sizeof(x509_object_st) == 8, sizeof(x509_object_st) ++assert alignment(x509_object_st) == 4, alignment(x509_object_st) ++X509_OBJECT = x509_object_st ++class x509_lookup_st(Structure): ++ pass ++X509_LOOKUP = x509_lookup_st ++class x509_lookup_method_st(Structure): ++ pass ++x509_lookup_method_st._fields_ = [ ++ ('name', STRING), ++ ('new_item', CFUNCTYPE(c_int, POINTER(X509_LOOKUP))), ++ ('free', CFUNCTYPE(None, POINTER(X509_LOOKUP))), ++ ('init', CFUNCTYPE(c_int, POINTER(X509_LOOKUP))), ++ ('shutdown', CFUNCTYPE(c_int, POINTER(X509_LOOKUP))), ++ ('ctrl', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, STRING, c_long, POINTER(STRING))), ++ ('get_by_subject', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, POINTER(X509_NAME), POINTER(X509_OBJECT))), ++ ('get_by_issuer_serial', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, POINTER(X509_NAME), POINTER(ASN1_INTEGER), POINTER(X509_OBJECT))), ++ ('get_by_fingerprint', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, POINTER(c_ubyte), c_int, POINTER(X509_OBJECT))), ++ ('get_by_alias', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, STRING, c_int, POINTER(X509_OBJECT))), ++] ++assert sizeof(x509_lookup_method_st) == 40, sizeof(x509_lookup_method_st) ++assert alignment(x509_lookup_method_st) == 4, alignment(x509_lookup_method_st) ++X509_LOOKUP_METHOD = x509_lookup_method_st ++x509_store_st._fields_ = [ ++ ('cache', c_int), ++ ('objs', POINTER(STACK)), ++ ('get_cert_methods', POINTER(STACK)), ++ ('flags', c_ulong), ++ ('purpose', c_int), ++ ('trust', c_int), ++ ('verify', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), ++ ('verify_cb', CFUNCTYPE(c_int, c_int, POINTER(X509_STORE_CTX))), ++ ('get_issuer', CFUNCTYPE(c_int, POINTER(POINTER(X509)), POINTER(X509_STORE_CTX), POINTER(X509))), ++ ('check_issued', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509), POINTER(X509))), ++ ('check_revocation', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), ++ ('get_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(POINTER(X509_CRL)), POINTER(X509))), ++ ('check_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509_CRL))), ++ ('cert_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509_CRL), POINTER(X509))), ++ ('cleanup', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), ++ ('ex_data', CRYPTO_EX_DATA), ++ ('references', c_int), ++ ('depth', c_int), ++] ++assert sizeof(x509_store_st) == 76, sizeof(x509_store_st) ++assert alignment(x509_store_st) == 4, alignment(x509_store_st) ++x509_lookup_st._fields_ = [ ++ ('init', c_int), ++ ('skip', c_int), ++ ('method', POINTER(X509_LOOKUP_METHOD)), ++ ('method_data', STRING), ++ ('store_ctx', POINTER(X509_STORE)), ++] ++assert sizeof(x509_lookup_st) == 20, sizeof(x509_lookup_st) ++assert alignment(x509_lookup_st) == 4, alignment(x509_lookup_st) ++time_t = __darwin_time_t ++x509_store_ctx_st._fields_ = [ ++ ('ctx', POINTER(X509_STORE)), ++ ('current_method', c_int), ++ ('cert', POINTER(X509)), ++ ('untrusted', POINTER(STACK)), ++ ('purpose', c_int), ++ ('trust', c_int), ++ ('check_time', time_t), ++ ('flags', c_ulong), ++ ('other_ctx', c_void_p), ++ ('verify', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), ++ ('verify_cb', CFUNCTYPE(c_int, c_int, POINTER(X509_STORE_CTX))), ++ ('get_issuer', CFUNCTYPE(c_int, POINTER(POINTER(X509)), POINTER(X509_STORE_CTX), POINTER(X509))), ++ ('check_issued', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509), POINTER(X509))), ++ ('check_revocation', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), ++ ('get_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(POINTER(X509_CRL)), POINTER(X509))), ++ ('check_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509_CRL))), ++ ('cert_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509_CRL), POINTER(X509))), ++ ('cleanup', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), ++ ('depth', c_int), ++ ('valid', c_int), ++ ('last_untrusted', c_int), ++ ('chain', POINTER(STACK)), ++ ('error_depth', c_int), ++ ('error', c_int), ++ ('current_cert', POINTER(X509)), ++ ('current_issuer', POINTER(X509)), ++ ('current_crl', POINTER(X509_CRL)), ++ ('ex_data', CRYPTO_EX_DATA), ++] ++assert sizeof(x509_store_ctx_st) == 116, sizeof(x509_store_ctx_st) ++assert alignment(x509_store_ctx_st) == 4, alignment(x509_store_ctx_st) ++va_list = __darwin_va_list ++__darwin_off_t = __int64_t ++fpos_t = __darwin_off_t ++class __sbuf(Structure): ++ pass ++__sbuf._fields_ = [ ++ ('_base', POINTER(c_ubyte)), ++ ('_size', c_int), ++] ++assert sizeof(__sbuf) == 8, sizeof(__sbuf) ++assert alignment(__sbuf) == 4, alignment(__sbuf) ++class __sFILEX(Structure): ++ pass ++__sFILEX._fields_ = [ ++] ++class __sFILE(Structure): ++ pass ++__sFILE._pack_ = 4 ++__sFILE._fields_ = [ ++ ('_p', POINTER(c_ubyte)), ++ ('_r', c_int), ++ ('_w', c_int), ++ ('_flags', c_short), ++ ('_file', c_short), ++ ('_bf', __sbuf), ++ ('_lbfsize', c_int), ++ ('_cookie', c_void_p), ++ ('_close', CFUNCTYPE(c_int, c_void_p)), ++ ('_read', CFUNCTYPE(c_int, c_void_p, STRING, c_int)), ++ ('_seek', CFUNCTYPE(fpos_t, c_void_p, c_longlong, c_int)), ++ ('_write', CFUNCTYPE(c_int, c_void_p, STRING, c_int)), ++ ('_ub', __sbuf), ++ ('_extra', POINTER(__sFILEX)), ++ ('_ur', c_int), ++ ('_ubuf', c_ubyte * 3), ++ ('_nbuf', c_ubyte * 1), ++ ('_lb', __sbuf), ++ ('_blksize', c_int), ++ ('_offset', fpos_t), ++] ++assert sizeof(__sFILE) == 88, sizeof(__sFILE) ++assert alignment(__sFILE) == 4, alignment(__sFILE) ++FILE = __sFILE ++ct_rune_t = __darwin_ct_rune_t ++rune_t = __darwin_rune_t ++class div_t(Structure): ++ pass ++div_t._fields_ = [ ++ ('quot', c_int), ++ ('rem', c_int), ++] ++assert sizeof(div_t) == 8, sizeof(div_t) ++assert alignment(div_t) == 4, alignment(div_t) ++class ldiv_t(Structure): ++ pass ++ldiv_t._fields_ = [ ++ ('quot', c_long), ++ ('rem', c_long), ++] ++assert sizeof(ldiv_t) == 8, sizeof(ldiv_t) ++assert alignment(ldiv_t) == 4, alignment(ldiv_t) ++class lldiv_t(Structure): ++ pass ++lldiv_t._pack_ = 4 ++lldiv_t._fields_ = [ ++ ('quot', c_longlong), ++ ('rem', c_longlong), ++] ++assert sizeof(lldiv_t) == 16, sizeof(lldiv_t) ++assert alignment(lldiv_t) == 4, alignment(lldiv_t) ++__darwin_dev_t = __int32_t ++dev_t = __darwin_dev_t ++__darwin_mode_t = __uint16_t ++mode_t = __darwin_mode_t ++class mcontext(Structure): ++ pass ++mcontext._fields_ = [ ++] ++class mcontext64(Structure): ++ pass ++mcontext64._fields_ = [ ++] ++class __darwin_pthread_handler_rec(Structure): ++ pass ++__darwin_pthread_handler_rec._fields_ = [ ++ ('__routine', CFUNCTYPE(None, c_void_p)), ++ ('__arg', c_void_p), ++ ('__next', POINTER(__darwin_pthread_handler_rec)), ++] ++assert sizeof(__darwin_pthread_handler_rec) == 12, sizeof(__darwin_pthread_handler_rec) ++assert alignment(__darwin_pthread_handler_rec) == 4, alignment(__darwin_pthread_handler_rec) ++class _opaque_pthread_attr_t(Structure): ++ pass ++_opaque_pthread_attr_t._fields_ = [ ++ ('__sig', c_long), ++ ('__opaque', c_char * 36), ++] ++assert sizeof(_opaque_pthread_attr_t) == 40, sizeof(_opaque_pthread_attr_t) ++assert alignment(_opaque_pthread_attr_t) == 4, alignment(_opaque_pthread_attr_t) ++class _opaque_pthread_cond_t(Structure): ++ pass ++_opaque_pthread_cond_t._fields_ = [ ++ ('__sig', c_long), ++ ('__opaque', c_char * 24), ++] ++assert sizeof(_opaque_pthread_cond_t) == 28, sizeof(_opaque_pthread_cond_t) ++assert alignment(_opaque_pthread_cond_t) == 4, alignment(_opaque_pthread_cond_t) ++class _opaque_pthread_condattr_t(Structure): ++ pass ++_opaque_pthread_condattr_t._fields_ = [ ++ ('__sig', c_long), ++ ('__opaque', c_char * 4), ++] ++assert sizeof(_opaque_pthread_condattr_t) == 8, sizeof(_opaque_pthread_condattr_t) ++assert alignment(_opaque_pthread_condattr_t) == 4, alignment(_opaque_pthread_condattr_t) ++class _opaque_pthread_mutex_t(Structure): ++ pass ++_opaque_pthread_mutex_t._fields_ = [ ++ ('__sig', c_long), ++ ('__opaque', c_char * 40), ++] ++assert sizeof(_opaque_pthread_mutex_t) == 44, sizeof(_opaque_pthread_mutex_t) ++assert alignment(_opaque_pthread_mutex_t) == 4, alignment(_opaque_pthread_mutex_t) ++class _opaque_pthread_mutexattr_t(Structure): ++ pass ++_opaque_pthread_mutexattr_t._fields_ = [ ++ ('__sig', c_long), ++ ('__opaque', c_char * 8), ++] ++assert sizeof(_opaque_pthread_mutexattr_t) == 12, sizeof(_opaque_pthread_mutexattr_t) ++assert alignment(_opaque_pthread_mutexattr_t) == 4, alignment(_opaque_pthread_mutexattr_t) ++class _opaque_pthread_once_t(Structure): ++ pass ++_opaque_pthread_once_t._fields_ = [ ++ ('__sig', c_long), ++ ('__opaque', c_char * 4), ++] ++assert sizeof(_opaque_pthread_once_t) == 8, sizeof(_opaque_pthread_once_t) ++assert alignment(_opaque_pthread_once_t) == 4, alignment(_opaque_pthread_once_t) ++class _opaque_pthread_rwlock_t(Structure): ++ pass ++_opaque_pthread_rwlock_t._fields_ = [ ++ ('__sig', c_long), ++ ('__opaque', c_char * 124), ++] ++assert sizeof(_opaque_pthread_rwlock_t) == 128, sizeof(_opaque_pthread_rwlock_t) ++assert alignment(_opaque_pthread_rwlock_t) == 4, alignment(_opaque_pthread_rwlock_t) ++class _opaque_pthread_rwlockattr_t(Structure): ++ pass ++_opaque_pthread_rwlockattr_t._fields_ = [ ++ ('__sig', c_long), ++ ('__opaque', c_char * 12), ++] ++assert sizeof(_opaque_pthread_rwlockattr_t) == 16, sizeof(_opaque_pthread_rwlockattr_t) ++assert alignment(_opaque_pthread_rwlockattr_t) == 4, alignment(_opaque_pthread_rwlockattr_t) ++class _opaque_pthread_t(Structure): ++ pass ++_opaque_pthread_t._fields_ = [ ++ ('__sig', c_long), ++ ('__cleanup_stack', POINTER(__darwin_pthread_handler_rec)), ++ ('__opaque', c_char * 596), ++] ++assert sizeof(_opaque_pthread_t) == 604, sizeof(_opaque_pthread_t) ++assert alignment(_opaque_pthread_t) == 4, alignment(_opaque_pthread_t) ++__darwin_blkcnt_t = __int64_t ++__darwin_blksize_t = __int32_t ++__darwin_fsblkcnt_t = c_uint ++__darwin_fsfilcnt_t = c_uint ++__darwin_gid_t = __uint32_t ++__darwin_id_t = __uint32_t ++__darwin_ino_t = __uint32_t ++__darwin_mach_port_name_t = __darwin_natural_t ++__darwin_mach_port_t = __darwin_mach_port_name_t ++__darwin_mcontext_t = POINTER(mcontext) ++__darwin_mcontext64_t = POINTER(mcontext64) ++__darwin_pid_t = __int32_t ++__darwin_pthread_attr_t = _opaque_pthread_attr_t ++__darwin_pthread_cond_t = _opaque_pthread_cond_t ++__darwin_pthread_condattr_t = _opaque_pthread_condattr_t ++__darwin_pthread_key_t = c_ulong ++__darwin_pthread_mutex_t = _opaque_pthread_mutex_t ++__darwin_pthread_mutexattr_t = _opaque_pthread_mutexattr_t ++__darwin_pthread_once_t = _opaque_pthread_once_t ++__darwin_pthread_rwlock_t = _opaque_pthread_rwlock_t ++__darwin_pthread_rwlockattr_t = _opaque_pthread_rwlockattr_t ++__darwin_pthread_t = POINTER(_opaque_pthread_t) ++__darwin_sigset_t = __uint32_t ++__darwin_suseconds_t = __int32_t ++__darwin_uid_t = __uint32_t ++__darwin_useconds_t = __uint32_t ++__darwin_uuid_t = c_ubyte * 16 ++class sigaltstack(Structure): ++ pass ++sigaltstack._fields_ = [ ++ ('ss_sp', c_void_p), ++ ('ss_size', __darwin_size_t), ++ ('ss_flags', c_int), ++] ++assert sizeof(sigaltstack) == 12, sizeof(sigaltstack) ++assert alignment(sigaltstack) == 4, alignment(sigaltstack) ++__darwin_stack_t = sigaltstack ++class ucontext(Structure): ++ pass ++ucontext._fields_ = [ ++ ('uc_onstack', c_int), ++ ('uc_sigmask', __darwin_sigset_t), ++ ('uc_stack', __darwin_stack_t), ++ ('uc_link', POINTER(ucontext)), ++ ('uc_mcsize', __darwin_size_t), ++ ('uc_mcontext', __darwin_mcontext_t), ++] ++assert sizeof(ucontext) == 32, sizeof(ucontext) ++assert alignment(ucontext) == 4, alignment(ucontext) ++__darwin_ucontext_t = ucontext ++class ucontext64(Structure): ++ pass ++ucontext64._fields_ = [ ++ ('uc_onstack', c_int), ++ ('uc_sigmask', __darwin_sigset_t), ++ ('uc_stack', __darwin_stack_t), ++ ('uc_link', POINTER(ucontext64)), ++ ('uc_mcsize', __darwin_size_t), ++ ('uc_mcontext64', __darwin_mcontext64_t), ++] ++assert sizeof(ucontext64) == 32, sizeof(ucontext64) ++assert alignment(ucontext64) == 4, alignment(ucontext64) ++__darwin_ucontext64_t = ucontext64 ++class timeval(Structure): ++ pass ++timeval._fields_ = [ ++ ('tv_sec', __darwin_time_t), ++ ('tv_usec', __darwin_suseconds_t), ++] ++assert sizeof(timeval) == 8, sizeof(timeval) ++assert alignment(timeval) == 4, alignment(timeval) ++rlim_t = __int64_t ++class rusage(Structure): ++ pass ++rusage._fields_ = [ ++ ('ru_utime', timeval), ++ ('ru_stime', timeval), ++ ('ru_maxrss', c_long), ++ ('ru_ixrss', c_long), ++ ('ru_idrss', c_long), ++ ('ru_isrss', c_long), ++ ('ru_minflt', c_long), ++ ('ru_majflt', c_long), ++ ('ru_nswap', c_long), ++ ('ru_inblock', c_long), ++ ('ru_oublock', c_long), ++ ('ru_msgsnd', c_long), ++ ('ru_msgrcv', c_long), ++ ('ru_nsignals', c_long), ++ ('ru_nvcsw', c_long), ++ ('ru_nivcsw', c_long), ++] ++assert sizeof(rusage) == 72, sizeof(rusage) ++assert alignment(rusage) == 4, alignment(rusage) ++class rlimit(Structure): ++ pass ++rlimit._pack_ = 4 ++rlimit._fields_ = [ ++ ('rlim_cur', rlim_t), ++ ('rlim_max', rlim_t), ++] ++assert sizeof(rlimit) == 16, sizeof(rlimit) ++assert alignment(rlimit) == 4, alignment(rlimit) ++mcontext_t = __darwin_mcontext_t ++mcontext64_t = __darwin_mcontext64_t ++pthread_attr_t = __darwin_pthread_attr_t ++sigset_t = __darwin_sigset_t ++ucontext_t = __darwin_ucontext_t ++ucontext64_t = __darwin_ucontext64_t ++uid_t = __darwin_uid_t ++class sigval(Union): ++ pass ++sigval._fields_ = [ ++ ('sival_int', c_int), ++ ('sival_ptr', c_void_p), ++] ++assert sizeof(sigval) == 4, sizeof(sigval) ++assert alignment(sigval) == 4, alignment(sigval) ++class sigevent(Structure): ++ pass ++sigevent._fields_ = [ ++ ('sigev_notify', c_int), ++ ('sigev_signo', c_int), ++ ('sigev_value', sigval), ++ ('sigev_notify_function', CFUNCTYPE(None, sigval)), ++ ('sigev_notify_attributes', POINTER(pthread_attr_t)), ++] ++assert sizeof(sigevent) == 20, sizeof(sigevent) ++assert alignment(sigevent) == 4, alignment(sigevent) ++class __siginfo(Structure): ++ pass ++pid_t = __darwin_pid_t ++__siginfo._fields_ = [ ++ ('si_signo', c_int), ++ ('si_errno', c_int), ++ ('si_code', c_int), ++ ('si_pid', pid_t), ++ ('si_uid', uid_t), ++ ('si_status', c_int), ++ ('si_addr', c_void_p), ++ ('si_value', sigval), ++ ('si_band', c_long), ++ ('pad', c_ulong * 7), ++] ++assert sizeof(__siginfo) == 64, sizeof(__siginfo) ++assert alignment(__siginfo) == 4, alignment(__siginfo) ++siginfo_t = __siginfo ++class __sigaction_u(Union): ++ pass ++__sigaction_u._fields_ = [ ++ ('__sa_handler', CFUNCTYPE(None, c_int)), ++ ('__sa_sigaction', CFUNCTYPE(None, c_int, POINTER(__siginfo), c_void_p)), ++] ++assert sizeof(__sigaction_u) == 4, sizeof(__sigaction_u) ++assert alignment(__sigaction_u) == 4, alignment(__sigaction_u) ++class __sigaction(Structure): ++ pass ++__sigaction._fields_ = [ ++ ('__sigaction_u', __sigaction_u), ++ ('sa_tramp', CFUNCTYPE(None, c_void_p, c_int, c_int, POINTER(siginfo_t), c_void_p)), ++ ('sa_mask', sigset_t), ++ ('sa_flags', c_int), ++] ++assert sizeof(__sigaction) == 16, sizeof(__sigaction) ++assert alignment(__sigaction) == 4, alignment(__sigaction) ++class sigaction(Structure): ++ pass ++sigaction._fields_ = [ ++ ('__sigaction_u', __sigaction_u), ++ ('sa_mask', sigset_t), ++ ('sa_flags', c_int), ++] ++assert sizeof(sigaction) == 12, sizeof(sigaction) ++assert alignment(sigaction) == 4, alignment(sigaction) ++sig_t = CFUNCTYPE(None, c_int) ++stack_t = __darwin_stack_t ++class sigvec(Structure): ++ pass ++sigvec._fields_ = [ ++ ('sv_handler', CFUNCTYPE(None, c_int)), ++ ('sv_mask', c_int), ++ ('sv_flags', c_int), ++] ++assert sizeof(sigvec) == 12, sizeof(sigvec) ++assert alignment(sigvec) == 4, alignment(sigvec) ++class sigstack(Structure): ++ pass ++sigstack._fields_ = [ ++ ('ss_sp', STRING), ++ ('ss_onstack', c_int), ++] ++assert sizeof(sigstack) == 8, sizeof(sigstack) ++assert alignment(sigstack) == 4, alignment(sigstack) ++u_char = c_ubyte ++u_short = c_ushort ++u_int = c_uint ++u_long = c_ulong ++ushort = c_ushort ++uint = c_uint ++u_quad_t = u_int64_t ++quad_t = int64_t ++qaddr_t = POINTER(quad_t) ++caddr_t = STRING ++daddr_t = int32_t ++fixpt_t = u_int32_t ++blkcnt_t = __darwin_blkcnt_t ++blksize_t = __darwin_blksize_t ++gid_t = __darwin_gid_t ++in_addr_t = __uint32_t ++in_port_t = __uint16_t ++ino_t = __darwin_ino_t ++key_t = __int32_t ++nlink_t = __uint16_t ++off_t = __darwin_off_t ++segsz_t = int32_t ++swblk_t = int32_t ++clock_t = __darwin_clock_t ++ssize_t = __darwin_ssize_t ++useconds_t = __darwin_useconds_t ++suseconds_t = __darwin_suseconds_t ++fd_mask = __int32_t ++class fd_set(Structure): ++ pass ++fd_set._fields_ = [ ++ ('fds_bits', __int32_t * 32), ++] ++assert sizeof(fd_set) == 128, sizeof(fd_set) ++assert alignment(fd_set) == 4, alignment(fd_set) ++pthread_cond_t = __darwin_pthread_cond_t ++pthread_condattr_t = __darwin_pthread_condattr_t ++pthread_mutex_t = __darwin_pthread_mutex_t ++pthread_mutexattr_t = __darwin_pthread_mutexattr_t ++pthread_once_t = __darwin_pthread_once_t ++pthread_rwlock_t = __darwin_pthread_rwlock_t ++pthread_rwlockattr_t = __darwin_pthread_rwlockattr_t ++pthread_t = __darwin_pthread_t ++pthread_key_t = __darwin_pthread_key_t ++fsblkcnt_t = __darwin_fsblkcnt_t ++fsfilcnt_t = __darwin_fsfilcnt_t ++ ++# values for enumeration 'idtype_t' ++idtype_t = c_int # enum ++id_t = __darwin_id_t ++class wait(Union): ++ pass ++class N4wait3DOLLAR_3E(Structure): ++ pass ++N4wait3DOLLAR_3E._fields_ = [ ++ ('w_Termsig', c_uint, 7), ++ ('w_Coredump', c_uint, 1), ++ ('w_Retcode', c_uint, 8), ++ ('w_Filler', c_uint, 16), ++] ++assert sizeof(N4wait3DOLLAR_3E) == 4, sizeof(N4wait3DOLLAR_3E) ++assert alignment(N4wait3DOLLAR_3E) == 4, alignment(N4wait3DOLLAR_3E) ++class N4wait3DOLLAR_4E(Structure): ++ pass ++N4wait3DOLLAR_4E._fields_ = [ ++ ('w_Stopval', c_uint, 8), ++ ('w_Stopsig', c_uint, 8), ++ ('w_Filler', c_uint, 16), ++] ++assert sizeof(N4wait3DOLLAR_4E) == 4, sizeof(N4wait3DOLLAR_4E) ++assert alignment(N4wait3DOLLAR_4E) == 4, alignment(N4wait3DOLLAR_4E) ++wait._fields_ = [ ++ ('w_status', c_int), ++ ('w_T', N4wait3DOLLAR_3E), ++ ('w_S', N4wait3DOLLAR_4E), ++] ++assert sizeof(wait) == 4, sizeof(wait) ++assert alignment(wait) == 4, alignment(wait) ++class timespec(Structure): ++ pass ++timespec._fields_ = [ ++ ('tv_sec', time_t), ++ ('tv_nsec', c_long), ++] ++assert sizeof(timespec) == 8, sizeof(timespec) ++assert alignment(timespec) == 4, alignment(timespec) ++class tm(Structure): ++ pass ++tm._fields_ = [ ++ ('tm_sec', c_int), ++ ('tm_min', c_int), ++ ('tm_hour', c_int), ++ ('tm_mday', c_int), ++ ('tm_mon', c_int), ++ ('tm_year', c_int), ++ ('tm_wday', c_int), ++ ('tm_yday', c_int), ++ ('tm_isdst', c_int), ++ ('tm_gmtoff', c_long), ++ ('tm_zone', STRING), ++] ++assert sizeof(tm) == 44, sizeof(tm) ++assert alignment(tm) == 4, alignment(tm) ++__gnuc_va_list = STRING ++ptrdiff_t = c_int ++int8_t = c_byte ++int16_t = c_short ++uint8_t = c_ubyte ++uint16_t = c_ushort ++uint32_t = c_uint ++uint64_t = c_ulonglong ++int_least8_t = int8_t ++int_least16_t = int16_t ++int_least32_t = int32_t ++int_least64_t = int64_t ++uint_least8_t = uint8_t ++uint_least16_t = uint16_t ++uint_least32_t = uint32_t ++uint_least64_t = uint64_t ++int_fast8_t = int8_t ++int_fast16_t = int16_t ++int_fast32_t = int32_t ++int_fast64_t = int64_t ++uint_fast8_t = uint8_t ++uint_fast16_t = uint16_t ++uint_fast32_t = uint32_t ++uint_fast64_t = uint64_t ++intptr_t = c_long ++uintptr_t = c_ulong ++intmax_t = c_longlong ++uintmax_t = c_ulonglong ++__all__ = ['ENGINE', 'pkcs7_enc_content_st', '__int16_t', ++ 'X509_REVOKED', 'SSL_CTX', 'UIT_BOOLEAN', ++ '__darwin_time_t', 'ucontext64_t', 'int_fast32_t', ++ 'pem_ctx_st', 'uint8_t', 'fpos_t', 'X509', 'COMP_CTX', ++ 'tm', 'N10pem_ctx_st4DOLLAR_17E', 'swblk_t', ++ 'ASN1_TEMPLATE', '__darwin_pthread_t', 'fixpt_t', ++ 'BIO_METHOD', 'ASN1_PRINTABLESTRING', 'EVP_ENCODE_CTX', ++ 'dh_method', 'bio_f_buffer_ctx_struct', 'in_port_t', ++ 'X509_SIG', '__darwin_ssize_t', '__darwin_sigset_t', ++ 'wait', 'uint_fast16_t', 'N12asn1_type_st4DOLLAR_11E', ++ 'uint_least8_t', 'pthread_rwlock_t', 'ASN1_IA5STRING', ++ 'fsfilcnt_t', 'ucontext', '__uint64_t', 'timespec', ++ 'x509_cinf_st', 'COMP_METHOD', 'MD5_CTX', 'buf_mem_st', ++ 'ASN1_ENCODING_st', 'PBEPARAM', 'X509_NAME_ENTRY', ++ '__darwin_va_list', 'ucontext_t', 'lhash_st', ++ 'N4wait3DOLLAR_4E', '__darwin_uuid_t', ++ '_ossl_old_des_ks_struct', 'id_t', 'ASN1_BIT_STRING', ++ 'va_list', '__darwin_wchar_t', 'pthread_key_t', ++ 'pkcs7_signer_info_st', 'ASN1_METHOD', 'DSA_SIG', 'DSA', ++ 'UIT_NONE', 'pthread_t', '__darwin_useconds_t', ++ 'uint_fast8_t', 'UI_STRING', 'DES_cblock', ++ '__darwin_mcontext64_t', 'rlim_t', 'PEM_Encode_Seal_st', ++ 'SHAstate_st', 'u_quad_t', 'openssl_fptr', ++ '_opaque_pthread_rwlockattr_t', ++ 'N18x509_attributes_st4DOLLAR_13E', ++ '__darwin_pthread_rwlock_t', 'daddr_t', 'ui_string_st', ++ 'x509_file_st', 'X509_req_info_st', 'int_least64_t', ++ 'evp_Encode_Ctx_st', 'X509_OBJECTS', 'CRYPTO_EX_DATA', ++ '__int8_t', 'AUTHORITY_KEYID_st', '_opaque_pthread_attr_t', ++ 'sigstack', 'EVP_CIPHER_CTX', 'X509_extension_st', 'pid_t', ++ 'RSA_METHOD', 'PEM_USER', 'pem_recip_st', 'env_md_ctx_st', ++ 'rc5_key_st', 'ui_st', 'X509_PUBKEY', 'u_int8_t', ++ 'ASN1_ITEM_st', 'pkcs7_recip_info_st', 'ssl2_state_st', ++ 'off_t', 'N10ssl_ctx_st4DOLLAR_18E', 'crypto_ex_data_st', ++ 'ui_method_st', '__darwin_pthread_rwlockattr_t', ++ 'CRYPTO_EX_dup', '__darwin_ino_t', '__sFILE', ++ 'OSUnknownByteOrder', 'BN_MONT_CTX', 'ASN1_NULL', 'time_t', ++ 'CRYPTO_EX_new', 'asn1_type_st', 'CRYPTO_EX_DATA_FUNCS', ++ 'user_time_t', 'BIGNUM', 'pthread_rwlockattr_t', ++ 'ASN1_VALUE_st', 'DH_METHOD', '__darwin_off_t', ++ '_opaque_pthread_t', 'bn_blinding_st', 'RSA', 'ssize_t', ++ 'mcontext64_t', 'user_long_t', 'fsblkcnt_t', 'cert_st', ++ '__darwin_pthread_condattr_t', 'X509_PKEY', ++ '__darwin_id_t', '__darwin_nl_item', 'SSL2_STATE', 'FILE', ++ 'pthread_mutexattr_t', 'size_t', ++ '_ossl_old_des_key_schedule', 'pkcs7_issuer_and_serial_st', ++ 'sigval', 'CRYPTO_MEM_LEAK_CB', 'X509_NAME', 'blkcnt_t', ++ 'uint_least16_t', '__darwin_dev_t', 'evp_cipher_info_st', ++ 'BN_BLINDING', 'ssl3_state_st', 'uint_least64_t', ++ 'user_addr_t', 'DES_key_schedule', 'RIPEMD160_CTX', ++ 'u_char', 'X509_algor_st', 'uid_t', 'sess_cert_st', ++ 'u_int64_t', 'u_int16_t', 'sigset_t', '__darwin_ptrdiff_t', ++ 'ASN1_CTX', 'STACK', '__int32_t', 'UI_METHOD', ++ 'NETSCAPE_SPKI', 'UIT_PROMPT', 'st_CRYPTO_EX_DATA_IMPL', ++ 'cast_key_st', 'X509_HASH_DIR_CTX', 'sigevent', ++ 'user_ssize_t', 'clock_t', 'aes_key_st', ++ '__darwin_socklen_t', '__darwin_intptr_t', 'int_fast64_t', ++ 'asn1_string_table_st', 'uint_fast32_t', ++ 'ASN1_VISIBLESTRING', 'DSA_SIG_st', 'obj_name_st', ++ 'X509_LOOKUP_METHOD', 'u_int32_t', 'EVP_CIPHER_INFO', ++ '__gnuc_va_list', 'AES_KEY', 'PKCS7_ISSUER_AND_SERIAL', ++ 'BN_CTX', '__darwin_blkcnt_t', 'key_t', 'SHA_CTX', ++ 'pkcs7_signed_st', 'SSL', 'N10pem_ctx_st4DOLLAR_16E', ++ 'pthread_attr_t', 'EVP_MD', 'uint', 'ASN1_BOOLEAN', ++ 'ino_t', '__darwin_clock_t', 'ASN1_OCTET_STRING', ++ 'asn1_ctx_st', 'BIO_F_BUFFER_CTX', 'bn_mont_ctx_st', ++ 'X509_REQ_INFO', 'PEM_CTX', 'sigvec', ++ '__darwin_pthread_mutexattr_t', 'x509_attributes_st', ++ 'stack_t', '__darwin_mode_t', '__mbstate_t', ++ 'asn1_object_st', 'ASN1_ENCODING', '__uint8_t', ++ 'LHASH_NODE', 'PKCS7_SIGNER_INFO', 'asn1_method_st', ++ 'stack_st', 'bio_info_cb', 'div_t', 'UIT_VERIFY', ++ 'PBEPARAM_st', 'N4wait3DOLLAR_3E', 'quad_t', '__siginfo', ++ '__darwin_mbstate_t', 'rsa_st', 'ASN1_UNIVERSALSTRING', ++ 'uint64_t', 'ssl_comp_st', 'X509_OBJECT', 'pthread_cond_t', ++ 'DH', '__darwin_wctype_t', 'PKCS7_ENVELOPE', 'ASN1_TLC_st', ++ 'sig_atomic_t', 'BIO', 'nlink_t', 'BUF_MEM', 'SSL3_RECORD', ++ 'bio_method_st', 'timeval', 'UI_string_types', 'BIO_dummy', ++ 'ssl_ctx_st', 'NETSCAPE_CERT_SEQUENCE', ++ 'BIT_STRING_BITNAME_st', '__darwin_pthread_attr_t', ++ 'int8_t', '__darwin_wint_t', 'OBJ_NAME', ++ 'PKCS8_PRIV_KEY_INFO', 'PBE2PARAM_st', ++ 'LHASH_DOALL_FN_TYPE', 'x509_st', 'X509_VAL', 'dev_t', ++ 'ASN1_TEMPLATE_st', 'MD5state_st', '__uint16_t', ++ 'LHASH_DOALL_ARG_FN_TYPE', 'mdc2_ctx_st', 'SSL3_STATE', ++ 'ssl3_buffer_st', 'ASN1_ITEM_EXP', ++ '_opaque_pthread_condattr_t', 'mode_t', 'ASN1_VALUE', ++ 'qaddr_t', '__darwin_gid_t', 'EVP_PKEY', 'CRYPTO_EX_free', ++ '_ossl_old_des_cblock', 'X509_INFO', 'asn1_string_st', ++ 'intptr_t', 'UIT_INFO', 'int_fast8_t', 'sigaltstack', ++ 'env_md_st', 'LHASH', '__darwin_ucontext_t', ++ 'PKCS7_SIGN_ENVELOPE', '__darwin_mcontext_t', 'ct_rune_t', ++ 'MD2_CTX', 'pthread_once_t', 'SSL3_BUFFER', 'fd_mask', ++ 'ASN1_TYPE', 'PKCS7_SIGNED', 'ssl3_record_st', 'BF_KEY', ++ 'MD4state_st', 'MD4_CTX', 'int16_t', 'SSL_CIPHER', ++ 'rune_t', 'X509_TRUST', 'siginfo_t', 'X509_STORE', ++ '__sbuf', 'X509_STORE_CTX', '__darwin_blksize_t', 'ldiv_t', ++ 'ASN1_TIME', 'SSL_METHOD', 'X509_LOOKUP', ++ 'Netscape_spki_st', 'P_PID', 'sigaction', 'sig_t', ++ 'hostent', 'x509_cert_aux_st', '_opaque_pthread_cond_t', ++ 'segsz_t', 'ushort', '__darwin_ct_rune_t', 'fd_set', ++ 'BN_RECP_CTX', 'x509_lookup_st', 'uint16_t', 'pkcs7_st', ++ 'asn1_header_st', '__darwin_pthread_key_t', ++ 'x509_trust_st', '__darwin_pthread_handler_rec', 'int32_t', ++ 'X509_CRL_INFO', 'N11evp_pkey_st4DOLLAR_12E', 'MDC2_CTX', ++ 'N23_ossl_old_des_ks_struct4DOLLAR_10E', 'ASN1_HEADER', ++ 'X509_crl_info_st', 'LHASH_HASH_FN_TYPE', ++ '_opaque_pthread_mutexattr_t', 'ssl_st', ++ 'N8pkcs7_st4DOLLAR_15E', 'evp_pkey_st', ++ 'pkcs7_signedandenveloped_st', '__darwin_mach_port_t', ++ 'EVP_PBE_KEYGEN', '_opaque_pthread_mutex_t', ++ 'ASN1_UTCTIME', 'mcontext', 'crypto_ex_data_func_st', ++ 'u_long', 'PBKDF2PARAM_st', 'rc4_key_st', 'DSA_METHOD', ++ 'EVP_CIPHER', 'BIT_STRING_BITNAME', 'PKCS7_RECIP_INFO', ++ 'ssl3_enc_method', 'X509_CERT_AUX', 'uintmax_t', ++ 'int_fast16_t', 'RC5_32_KEY', 'ucontext64', 'ASN1_INTEGER', ++ 'u_short', 'N14x509_object_st4DOLLAR_14E', 'mcontext64', ++ 'X509_sig_st', 'ASN1_GENERALSTRING', 'PKCS7', '__sFILEX', ++ 'X509_name_entry_st', 'ssl_session_st', 'caddr_t', ++ 'bignum_st', 'X509_CINF', '__darwin_pthread_cond_t', ++ 'ASN1_TLC', 'PKCS7_ENCRYPT', 'NETSCAPE_SPKAC', ++ 'Netscape_spkac_st', 'idtype_t', 'UIT_ERROR', ++ 'uint_fast64_t', 'in_addr_t', 'pthread_mutex_t', ++ '__int64_t', 'ASN1_BMPSTRING', 'uint32_t', ++ 'PEM_ENCODE_SEAL_CTX', 'suseconds_t', 'ASN1_OBJECT', ++ 'X509_val_st', 'private_key_st', 'CRYPTO_dynlock', ++ 'X509_objects_st', 'CRYPTO_EX_DATA_IMPL', ++ 'pthread_condattr_t', 'PKCS7_DIGEST', 'uint_least32_t', ++ 'ASN1_STRING', '__uint32_t', 'P_PGID', 'rsa_meth_st', ++ 'X509_crl_st', 'RC2_KEY', '__darwin_fsfilcnt_t', ++ 'X509_revoked_st', 'PBE2PARAM', 'blksize_t', ++ 'Netscape_certificate_sequence', 'ssl_cipher_st', ++ 'bignum_ctx', 'register_t', 'ASN1_UTF8STRING', ++ 'pkcs7_encrypted_st', 'RC4_KEY', '__darwin_ucontext64_t', ++ 'N13ssl2_state_st4DOLLAR_19E', 'bn_recp_ctx_st', ++ 'CAST_KEY', 'X509_ATTRIBUTE', '__darwin_suseconds_t', ++ '__sigaction', 'user_ulong_t', 'syscall_arg_t', ++ 'evp_cipher_ctx_st', 'X509_ALGOR', 'mcontext_t', ++ 'const_DES_cblock', '__darwin_fsblkcnt_t', 'dsa_st', ++ 'int_least8_t', 'MD2state_st', 'X509_EXTENSION', ++ 'GEN_SESSION_CB', 'int_least16_t', '__darwin_wctrans_t', ++ 'PBKDF2PARAM', 'x509_lookup_method_st', 'pem_password_cb', ++ 'X509_info_st', 'x509_store_st', '__darwin_natural_t', ++ 'X509_pubkey_st', 'pkcs7_digest_st', '__darwin_size_t', ++ 'ASN1_STRING_TABLE', 'OSLittleEndian', 'RIPEMD160state_st', ++ 'pkcs7_enveloped_st', 'UI', 'ptrdiff_t', 'X509_REQ', ++ 'CRYPTO_dynlock_value', 'X509_req_st', 'x509_store_ctx_st', ++ 'N13ssl3_state_st4DOLLAR_20E', 'lhash_node_st', ++ '__darwin_pthread_mutex_t', 'LHASH_COMP_FN_TYPE', ++ '__darwin_rune_t', 'rlimit', '__darwin_pthread_once_t', ++ 'OSBigEndian', 'uintptr_t', '__darwin_uid_t', 'u_int', ++ 'ASN1_T61STRING', 'gid_t', 'ssl_method_st', 'ASN1_ITEM', ++ 'ASN1_ENUMERATED', '_opaque_pthread_rwlock_t', ++ 'pkcs8_priv_key_info_st', 'intmax_t', 'sigcontext', ++ 'X509_CRL', 'rc2_key_st', 'engine_st', 'x509_object_st', ++ '_opaque_pthread_once_t', 'DES_ks', 'SSL_COMP', ++ 'dsa_method', 'int64_t', 'bio_st', 'bf_key_st', ++ 'ASN1_GENERALIZEDTIME', 'PKCS7_ENC_CONTENT', ++ '__darwin_pid_t', 'lldiv_t', 'comp_method_st', ++ 'EVP_MD_CTX', 'evp_cipher_st', 'X509_name_st', ++ 'x509_hash_dir_st', '__darwin_mach_port_name_t', ++ 'useconds_t', 'user_size_t', 'SSL_SESSION', 'rusage', ++ 'ssl_crock_st', 'int_least32_t', '__sigaction_u', 'dh_st', ++ 'P_ALL', '__darwin_stack_t', 'N6DES_ks3DOLLAR_9E', ++ 'comp_ctx_st', 'X509_CERT_FILE_CTX'] +diff -r 531f2e948299 refactor/tests/data/.svn/text-base/py2_test_grammar.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/.svn/text-base/py2_test_grammar.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,956 @@ ++# Python 2's Lib/test/test_grammar.py (r66189) ++ ++# Python test set -- part 1, grammar. ++# This just tests whether the parser accepts them all. ++ ++# NOTE: When you run this test as a script from the command line, you ++# get warnings about certain hex/oct constants. Since those are ++# issued by the parser, you can't suppress them by adding a ++# filterwarnings() call to this module. Therefore, to shut up the ++# regression test, the filterwarnings() call has been added to ++# regrtest.py. ++ ++from test.test_support import run_unittest, check_syntax_error ++import unittest ++import sys ++# testing import * ++from sys import * ++ ++class TokenTests(unittest.TestCase): ++ ++ def testBackslash(self): ++ # Backslash means line continuation: ++ x = 1 \ ++ + 1 ++ self.assertEquals(x, 2, 'backslash for line continuation') ++ ++ # Backslash does not means continuation in comments :\ ++ x = 0 ++ self.assertEquals(x, 0, 'backslash ending comment') ++ ++ def testPlainIntegers(self): ++ self.assertEquals(0xff, 255) ++ self.assertEquals(0377, 255) ++ self.assertEquals(2147483647, 017777777777) ++ # "0x" is not a valid literal ++ self.assertRaises(SyntaxError, eval, "0x") ++ from sys import maxint ++ if maxint == 2147483647: ++ self.assertEquals(-2147483647-1, -020000000000) ++ # XXX -2147483648 ++ self.assert_(037777777777 > 0) ++ self.assert_(0xffffffff > 0) ++ for s in '2147483648', '040000000000', '0x100000000': ++ try: ++ x = eval(s) ++ except OverflowError: ++ self.fail("OverflowError on huge integer literal %r" % s) ++ elif maxint == 9223372036854775807: ++ self.assertEquals(-9223372036854775807-1, -01000000000000000000000) ++ self.assert_(01777777777777777777777 > 0) ++ self.assert_(0xffffffffffffffff > 0) ++ for s in '9223372036854775808', '02000000000000000000000', \ ++ '0x10000000000000000': ++ try: ++ x = eval(s) ++ except OverflowError: ++ self.fail("OverflowError on huge integer literal %r" % s) ++ else: ++ self.fail('Weird maxint value %r' % maxint) ++ ++ def testLongIntegers(self): ++ x = 0L ++ x = 0l ++ x = 0xffffffffffffffffL ++ x = 0xffffffffffffffffl ++ x = 077777777777777777L ++ x = 077777777777777777l ++ x = 123456789012345678901234567890L ++ x = 123456789012345678901234567890l ++ ++ def testFloats(self): ++ x = 3.14 ++ x = 314. ++ x = 0.314 ++ # XXX x = 000.314 ++ x = .314 ++ x = 3e14 ++ x = 3E14 ++ x = 3e-14 ++ x = 3e+14 ++ x = 3.e14 ++ x = .3e14 ++ x = 3.1e4 ++ ++ def testStringLiterals(self): ++ x = ''; y = ""; self.assert_(len(x) == 0 and x == y) ++ x = '\''; y = "'"; self.assert_(len(x) == 1 and x == y and ord(x) == 39) ++ x = '"'; y = "\""; self.assert_(len(x) == 1 and x == y and ord(x) == 34) ++ x = "doesn't \"shrink\" does it" ++ y = 'doesn\'t "shrink" does it' ++ self.assert_(len(x) == 24 and x == y) ++ x = "does \"shrink\" doesn't it" ++ y = 'does "shrink" doesn\'t it' ++ self.assert_(len(x) == 24 and x == y) ++ x = """ ++The "quick" ++brown fox ++jumps over ++the 'lazy' dog. ++""" ++ y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n' ++ self.assertEquals(x, y) ++ y = ''' ++The "quick" ++brown fox ++jumps over ++the 'lazy' dog. ++''' ++ self.assertEquals(x, y) ++ y = "\n\ ++The \"quick\"\n\ ++brown fox\n\ ++jumps over\n\ ++the 'lazy' dog.\n\ ++" ++ self.assertEquals(x, y) ++ y = '\n\ ++The \"quick\"\n\ ++brown fox\n\ ++jumps over\n\ ++the \'lazy\' dog.\n\ ++' ++ self.assertEquals(x, y) ++ ++ ++class GrammarTests(unittest.TestCase): ++ ++ # single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE ++ # XXX can't test in a script -- this rule is only used when interactive ++ ++ # file_input: (NEWLINE | stmt)* ENDMARKER ++ # Being tested as this very moment this very module ++ ++ # expr_input: testlist NEWLINE ++ # XXX Hard to test -- used only in calls to input() ++ ++ def testEvalInput(self): ++ # testlist ENDMARKER ++ x = eval('1, 0 or 1') ++ ++ def testFuncdef(self): ++ ### 'def' NAME parameters ':' suite ++ ### parameters: '(' [varargslist] ')' ++ ### varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' ('**'|'*' '*') NAME] ++ ### | ('**'|'*' '*') NAME) ++ ### | fpdef ['=' test] (',' fpdef ['=' test])* [','] ++ ### fpdef: NAME | '(' fplist ')' ++ ### fplist: fpdef (',' fpdef)* [','] ++ ### arglist: (argument ',')* (argument | *' test [',' '**' test] | '**' test) ++ ### argument: [test '='] test # Really [keyword '='] test ++ def f1(): pass ++ f1() ++ f1(*()) ++ f1(*(), **{}) ++ def f2(one_argument): pass ++ def f3(two, arguments): pass ++ def f4(two, (compound, (argument, list))): pass ++ def f5((compound, first), two): pass ++ self.assertEquals(f2.func_code.co_varnames, ('one_argument',)) ++ self.assertEquals(f3.func_code.co_varnames, ('two', 'arguments')) ++ if sys.platform.startswith('java'): ++ self.assertEquals(f4.func_code.co_varnames, ++ ('two', '(compound, (argument, list))', 'compound', 'argument', ++ 'list',)) ++ self.assertEquals(f5.func_code.co_varnames, ++ ('(compound, first)', 'two', 'compound', 'first')) ++ else: ++ self.assertEquals(f4.func_code.co_varnames, ++ ('two', '.1', 'compound', 'argument', 'list')) ++ self.assertEquals(f5.func_code.co_varnames, ++ ('.0', 'two', 'compound', 'first')) ++ def a1(one_arg,): pass ++ def a2(two, args,): pass ++ def v0(*rest): pass ++ def v1(a, *rest): pass ++ def v2(a, b, *rest): pass ++ def v3(a, (b, c), *rest): return a, b, c, rest ++ ++ f1() ++ f2(1) ++ f2(1,) ++ f3(1, 2) ++ f3(1, 2,) ++ f4(1, (2, (3, 4))) ++ v0() ++ v0(1) ++ v0(1,) ++ v0(1,2) ++ v0(1,2,3,4,5,6,7,8,9,0) ++ v1(1) ++ v1(1,) ++ v1(1,2) ++ v1(1,2,3) ++ v1(1,2,3,4,5,6,7,8,9,0) ++ v2(1,2) ++ v2(1,2,3) ++ v2(1,2,3,4) ++ v2(1,2,3,4,5,6,7,8,9,0) ++ v3(1,(2,3)) ++ v3(1,(2,3),4) ++ v3(1,(2,3),4,5,6,7,8,9,0) ++ ++ # ceval unpacks the formal arguments into the first argcount names; ++ # thus, the names nested inside tuples must appear after these names. ++ if sys.platform.startswith('java'): ++ self.assertEquals(v3.func_code.co_varnames, ('a', '(b, c)', 'rest', 'b', 'c')) ++ else: ++ self.assertEquals(v3.func_code.co_varnames, ('a', '.1', 'rest', 'b', 'c')) ++ self.assertEquals(v3(1, (2, 3), 4), (1, 2, 3, (4,))) ++ def d01(a=1): pass ++ d01() ++ d01(1) ++ d01(*(1,)) ++ d01(**{'a':2}) ++ def d11(a, b=1): pass ++ d11(1) ++ d11(1, 2) ++ d11(1, **{'b':2}) ++ def d21(a, b, c=1): pass ++ d21(1, 2) ++ d21(1, 2, 3) ++ d21(*(1, 2, 3)) ++ d21(1, *(2, 3)) ++ d21(1, 2, *(3,)) ++ d21(1, 2, **{'c':3}) ++ def d02(a=1, b=2): pass ++ d02() ++ d02(1) ++ d02(1, 2) ++ d02(*(1, 2)) ++ d02(1, *(2,)) ++ d02(1, **{'b':2}) ++ d02(**{'a': 1, 'b': 2}) ++ def d12(a, b=1, c=2): pass ++ d12(1) ++ d12(1, 2) ++ d12(1, 2, 3) ++ def d22(a, b, c=1, d=2): pass ++ d22(1, 2) ++ d22(1, 2, 3) ++ d22(1, 2, 3, 4) ++ def d01v(a=1, *rest): pass ++ d01v() ++ d01v(1) ++ d01v(1, 2) ++ d01v(*(1, 2, 3, 4)) ++ d01v(*(1,)) ++ d01v(**{'a':2}) ++ def d11v(a, b=1, *rest): pass ++ d11v(1) ++ d11v(1, 2) ++ d11v(1, 2, 3) ++ def d21v(a, b, c=1, *rest): pass ++ d21v(1, 2) ++ d21v(1, 2, 3) ++ d21v(1, 2, 3, 4) ++ d21v(*(1, 2, 3, 4)) ++ d21v(1, 2, **{'c': 3}) ++ def d02v(a=1, b=2, *rest): pass ++ d02v() ++ d02v(1) ++ d02v(1, 2) ++ d02v(1, 2, 3) ++ d02v(1, *(2, 3, 4)) ++ d02v(**{'a': 1, 'b': 2}) ++ def d12v(a, b=1, c=2, *rest): pass ++ d12v(1) ++ d12v(1, 2) ++ d12v(1, 2, 3) ++ d12v(1, 2, 3, 4) ++ d12v(*(1, 2, 3, 4)) ++ d12v(1, 2, *(3, 4, 5)) ++ d12v(1, *(2,), **{'c': 3}) ++ def d22v(a, b, c=1, d=2, *rest): pass ++ d22v(1, 2) ++ d22v(1, 2, 3) ++ d22v(1, 2, 3, 4) ++ d22v(1, 2, 3, 4, 5) ++ d22v(*(1, 2, 3, 4)) ++ d22v(1, 2, *(3, 4, 5)) ++ d22v(1, *(2, 3), **{'d': 4}) ++ def d31v((x)): pass ++ d31v(1) ++ def d32v((x,)): pass ++ d32v((1,)) ++ ++ # keyword arguments after *arglist ++ def f(*args, **kwargs): ++ return args, kwargs ++ self.assertEquals(f(1, x=2, *[3, 4], y=5), ((1, 3, 4), ++ {'x':2, 'y':5})) ++ self.assertRaises(SyntaxError, eval, "f(1, *(2,3), 4)") ++ self.assertRaises(SyntaxError, eval, "f(1, x=2, *(3,4), x=5)") ++ ++ # Check ast errors in *args and *kwargs ++ check_syntax_error(self, "f(*g(1=2))") ++ check_syntax_error(self, "f(**g(1=2))") ++ ++ def testLambdef(self): ++ ### lambdef: 'lambda' [varargslist] ':' test ++ l1 = lambda : 0 ++ self.assertEquals(l1(), 0) ++ l2 = lambda : a[d] # XXX just testing the expression ++ l3 = lambda : [2 < x for x in [-1, 3, 0L]] ++ self.assertEquals(l3(), [0, 1, 0]) ++ l4 = lambda x = lambda y = lambda z=1 : z : y() : x() ++ self.assertEquals(l4(), 1) ++ l5 = lambda x, y, z=2: x + y + z ++ self.assertEquals(l5(1, 2), 5) ++ self.assertEquals(l5(1, 2, 3), 6) ++ check_syntax_error(self, "lambda x: x = 2") ++ check_syntax_error(self, "lambda (None,): None") ++ ++ ### stmt: simple_stmt | compound_stmt ++ # Tested below ++ ++ def testSimpleStmt(self): ++ ### simple_stmt: small_stmt (';' small_stmt)* [';'] ++ x = 1; pass; del x ++ def foo(): ++ # verify statments that end with semi-colons ++ x = 1; pass; del x; ++ foo() ++ ++ ### small_stmt: expr_stmt | print_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt | exec_stmt ++ # Tested below ++ ++ def testExprStmt(self): ++ # (exprlist '=')* exprlist ++ 1 ++ 1, 2, 3 ++ x = 1 ++ x = 1, 2, 3 ++ x = y = z = 1, 2, 3 ++ x, y, z = 1, 2, 3 ++ abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4) ++ ++ check_syntax_error(self, "x + 1 = 1") ++ check_syntax_error(self, "a + 1 = b + 2") ++ ++ def testPrintStmt(self): ++ # 'print' (test ',')* [test] ++ import StringIO ++ ++ # Can't test printing to real stdout without comparing output ++ # which is not available in unittest. ++ save_stdout = sys.stdout ++ sys.stdout = StringIO.StringIO() ++ ++ print 1, 2, 3 ++ print 1, 2, 3, ++ print ++ print 0 or 1, 0 or 1, ++ print 0 or 1 ++ ++ # 'print' '>>' test ',' ++ print >> sys.stdout, 1, 2, 3 ++ print >> sys.stdout, 1, 2, 3, ++ print >> sys.stdout ++ print >> sys.stdout, 0 or 1, 0 or 1, ++ print >> sys.stdout, 0 or 1 ++ ++ # test printing to an instance ++ class Gulp: ++ def write(self, msg): pass ++ ++ gulp = Gulp() ++ print >> gulp, 1, 2, 3 ++ print >> gulp, 1, 2, 3, ++ print >> gulp ++ print >> gulp, 0 or 1, 0 or 1, ++ print >> gulp, 0 or 1 ++ ++ # test print >> None ++ def driver(): ++ oldstdout = sys.stdout ++ sys.stdout = Gulp() ++ try: ++ tellme(Gulp()) ++ tellme() ++ finally: ++ sys.stdout = oldstdout ++ ++ # we should see this once ++ def tellme(file=sys.stdout): ++ print >> file, 'hello world' ++ ++ driver() ++ ++ # we should not see this at all ++ def tellme(file=None): ++ print >> file, 'goodbye universe' ++ ++ driver() ++ ++ self.assertEqual(sys.stdout.getvalue(), '''\ ++1 2 3 ++1 2 3 ++1 1 1 ++1 2 3 ++1 2 3 ++1 1 1 ++hello world ++''') ++ sys.stdout = save_stdout ++ ++ # syntax errors ++ check_syntax_error(self, 'print ,') ++ check_syntax_error(self, 'print >> x,') ++ ++ def testDelStmt(self): ++ # 'del' exprlist ++ abc = [1,2,3] ++ x, y, z = abc ++ xyz = x, y, z ++ ++ del abc ++ del x, y, (z, xyz) ++ ++ def testPassStmt(self): ++ # 'pass' ++ pass ++ ++ # flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt ++ # Tested below ++ ++ def testBreakStmt(self): ++ # 'break' ++ while 1: break ++ ++ def testContinueStmt(self): ++ # 'continue' ++ i = 1 ++ while i: i = 0; continue ++ ++ msg = "" ++ while not msg: ++ msg = "ok" ++ try: ++ continue ++ msg = "continue failed to continue inside try" ++ except: ++ msg = "continue inside try called except block" ++ if msg != "ok": ++ self.fail(msg) ++ ++ msg = "" ++ while not msg: ++ msg = "finally block not called" ++ try: ++ continue ++ finally: ++ msg = "ok" ++ if msg != "ok": ++ self.fail(msg) ++ ++ def test_break_continue_loop(self): ++ # This test warrants an explanation. It is a test specifically for SF bugs ++ # #463359 and #462937. The bug is that a 'break' statement executed or ++ # exception raised inside a try/except inside a loop, *after* a continue ++ # statement has been executed in that loop, will cause the wrong number of ++ # arguments to be popped off the stack and the instruction pointer reset to ++ # a very small number (usually 0.) Because of this, the following test ++ # *must* written as a function, and the tracking vars *must* be function ++ # arguments with default values. Otherwise, the test will loop and loop. ++ ++ def test_inner(extra_burning_oil = 1, count=0): ++ big_hippo = 2 ++ while big_hippo: ++ count += 1 ++ try: ++ if extra_burning_oil and big_hippo == 1: ++ extra_burning_oil -= 1 ++ break ++ big_hippo -= 1 ++ continue ++ except: ++ raise ++ if count > 2 or big_hippo <> 1: ++ self.fail("continue then break in try/except in loop broken!") ++ test_inner() ++ ++ def testReturn(self): ++ # 'return' [testlist] ++ def g1(): return ++ def g2(): return 1 ++ g1() ++ x = g2() ++ check_syntax_error(self, "class foo:return 1") ++ ++ def testYield(self): ++ check_syntax_error(self, "class foo:yield 1") ++ ++ def testRaise(self): ++ # 'raise' test [',' test] ++ try: raise RuntimeError, 'just testing' ++ except RuntimeError: pass ++ try: raise KeyboardInterrupt ++ except KeyboardInterrupt: pass ++ ++ def testImport(self): ++ # 'import' dotted_as_names ++ import sys ++ import time, sys ++ # 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names) ++ from time import time ++ from time import (time) ++ # not testable inside a function, but already done at top of the module ++ # from sys import * ++ from sys import path, argv ++ from sys import (path, argv) ++ from sys import (path, argv,) ++ ++ def testGlobal(self): ++ # 'global' NAME (',' NAME)* ++ global a ++ global a, b ++ global one, two, three, four, five, six, seven, eight, nine, ten ++ ++ def testExec(self): ++ # 'exec' expr ['in' expr [',' expr]] ++ z = None ++ del z ++ exec 'z=1+1\n' ++ if z != 2: self.fail('exec \'z=1+1\'\\n') ++ del z ++ exec 'z=1+1' ++ if z != 2: self.fail('exec \'z=1+1\'') ++ z = None ++ del z ++ import types ++ if hasattr(types, "UnicodeType"): ++ exec r"""if 1: ++ exec u'z=1+1\n' ++ if z != 2: self.fail('exec u\'z=1+1\'\\n') ++ del z ++ exec u'z=1+1' ++ if z != 2: self.fail('exec u\'z=1+1\'')""" ++ g = {} ++ exec 'z = 1' in g ++ if g.has_key('__builtins__'): del g['__builtins__'] ++ if g != {'z': 1}: self.fail('exec \'z = 1\' in g') ++ g = {} ++ l = {} ++ ++ import warnings ++ warnings.filterwarnings("ignore", "global statement", module="") ++ exec 'global a; a = 1; b = 2' in g, l ++ if g.has_key('__builtins__'): del g['__builtins__'] ++ if l.has_key('__builtins__'): del l['__builtins__'] ++ if (g, l) != ({'a':1}, {'b':2}): ++ self.fail('exec ... in g (%s), l (%s)' %(g,l)) ++ ++ def testAssert(self): ++ # assert_stmt: 'assert' test [',' test] ++ assert 1 ++ assert 1, 1 ++ assert lambda x:x ++ assert 1, lambda x:x+1 ++ try: ++ assert 0, "msg" ++ except AssertionError, e: ++ self.assertEquals(e.args[0], "msg") ++ else: ++ if __debug__: ++ self.fail("AssertionError not raised by assert 0") ++ ++ ### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef ++ # Tested below ++ ++ def testIf(self): ++ # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] ++ if 1: pass ++ if 1: pass ++ else: pass ++ if 0: pass ++ elif 0: pass ++ if 0: pass ++ elif 0: pass ++ elif 0: pass ++ elif 0: pass ++ else: pass ++ ++ def testWhile(self): ++ # 'while' test ':' suite ['else' ':' suite] ++ while 0: pass ++ while 0: pass ++ else: pass ++ ++ # Issue1920: "while 0" is optimized away, ++ # ensure that the "else" clause is still present. ++ x = 0 ++ while 0: ++ x = 1 ++ else: ++ x = 2 ++ self.assertEquals(x, 2) ++ ++ def testFor(self): ++ # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] ++ for i in 1, 2, 3: pass ++ for i, j, k in (): pass ++ else: pass ++ class Squares: ++ def __init__(self, max): ++ self.max = max ++ self.sofar = [] ++ def __len__(self): return len(self.sofar) ++ def __getitem__(self, i): ++ if not 0 <= i < self.max: raise IndexError ++ n = len(self.sofar) ++ while n <= i: ++ self.sofar.append(n*n) ++ n = n+1 ++ return self.sofar[i] ++ n = 0 ++ for x in Squares(10): n = n+x ++ if n != 285: ++ self.fail('for over growing sequence') ++ ++ result = [] ++ for x, in [(1,), (2,), (3,)]: ++ result.append(x) ++ self.assertEqual(result, [1, 2, 3]) ++ ++ def testTry(self): ++ ### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] ++ ### | 'try' ':' suite 'finally' ':' suite ++ ### except_clause: 'except' [expr [('as' | ',') expr]] ++ try: ++ 1/0 ++ except ZeroDivisionError: ++ pass ++ else: ++ pass ++ try: 1/0 ++ except EOFError: pass ++ except TypeError as msg: pass ++ except RuntimeError, msg: pass ++ except: pass ++ else: pass ++ try: 1/0 ++ except (EOFError, TypeError, ZeroDivisionError): pass ++ try: 1/0 ++ except (EOFError, TypeError, ZeroDivisionError), msg: pass ++ try: pass ++ finally: pass ++ ++ def testSuite(self): ++ # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT ++ if 1: pass ++ if 1: ++ pass ++ if 1: ++ # ++ # ++ # ++ pass ++ pass ++ # ++ pass ++ # ++ ++ def testTest(self): ++ ### and_test ('or' and_test)* ++ ### and_test: not_test ('and' not_test)* ++ ### not_test: 'not' not_test | comparison ++ if not 1: pass ++ if 1 and 1: pass ++ if 1 or 1: pass ++ if not not not 1: pass ++ if not 1 and 1 and 1: pass ++ if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass ++ ++ def testComparison(self): ++ ### comparison: expr (comp_op expr)* ++ ### comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' ++ if 1: pass ++ x = (1 == 1) ++ if 1 == 1: pass ++ if 1 != 1: pass ++ if 1 <> 1: pass ++ if 1 < 1: pass ++ if 1 > 1: pass ++ if 1 <= 1: pass ++ if 1 >= 1: pass ++ if 1 is 1: pass ++ if 1 is not 1: pass ++ if 1 in (): pass ++ if 1 not in (): pass ++ if 1 < 1 > 1 == 1 >= 1 <= 1 <> 1 != 1 in 1 not in 1 is 1 is not 1: pass ++ ++ def testBinaryMaskOps(self): ++ x = 1 & 1 ++ x = 1 ^ 1 ++ x = 1 | 1 ++ ++ def testShiftOps(self): ++ x = 1 << 1 ++ x = 1 >> 1 ++ x = 1 << 1 >> 1 ++ ++ def testAdditiveOps(self): ++ x = 1 ++ x = 1 + 1 ++ x = 1 - 1 - 1 ++ x = 1 - 1 + 1 - 1 + 1 ++ ++ def testMultiplicativeOps(self): ++ x = 1 * 1 ++ x = 1 / 1 ++ x = 1 % 1 ++ x = 1 / 1 * 1 % 1 ++ ++ def testUnaryOps(self): ++ x = +1 ++ x = -1 ++ x = ~1 ++ x = ~1 ^ 1 & 1 | 1 & 1 ^ -1 ++ x = -1*1/1 + 1*1 - ---1*1 ++ ++ def testSelectors(self): ++ ### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME ++ ### subscript: expr | [expr] ':' [expr] ++ ++ import sys, time ++ c = sys.path[0] ++ x = time.time() ++ x = sys.modules['time'].time() ++ a = '01234' ++ c = a[0] ++ c = a[-1] ++ s = a[0:5] ++ s = a[:5] ++ s = a[0:] ++ s = a[:] ++ s = a[-5:] ++ s = a[:-1] ++ s = a[-4:-3] ++ # A rough test of SF bug 1333982. http://python.org/sf/1333982 ++ # The testing here is fairly incomplete. ++ # Test cases should include: commas with 1 and 2 colons ++ d = {} ++ d[1] = 1 ++ d[1,] = 2 ++ d[1,2] = 3 ++ d[1,2,3] = 4 ++ L = list(d) ++ L.sort() ++ self.assertEquals(str(L), '[1, (1,), (1, 2), (1, 2, 3)]') ++ ++ def testAtoms(self): ++ ### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING ++ ### dictmaker: test ':' test (',' test ':' test)* [','] ++ ++ x = (1) ++ x = (1 or 2 or 3) ++ x = (1 or 2 or 3, 2, 3) ++ ++ x = [] ++ x = [1] ++ x = [1 or 2 or 3] ++ x = [1 or 2 or 3, 2, 3] ++ x = [] ++ ++ x = {} ++ x = {'one': 1} ++ x = {'one': 1,} ++ x = {'one' or 'two': 1 or 2} ++ x = {'one': 1, 'two': 2} ++ x = {'one': 1, 'two': 2,} ++ x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6} ++ ++ x = `x` ++ x = `1 or 2 or 3` ++ self.assertEqual(`1,2`, '(1, 2)') ++ ++ x = x ++ x = 'x' ++ x = 123 ++ ++ ### exprlist: expr (',' expr)* [','] ++ ### testlist: test (',' test)* [','] ++ # These have been exercised enough above ++ ++ def testClassdef(self): ++ # 'class' NAME ['(' [testlist] ')'] ':' suite ++ class B: pass ++ class B2(): pass ++ class C1(B): pass ++ class C2(B): pass ++ class D(C1, C2, B): pass ++ class C: ++ def meth1(self): pass ++ def meth2(self, arg): pass ++ def meth3(self, a1, a2): pass ++ # decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE ++ # decorators: decorator+ ++ # decorated: decorators (classdef | funcdef) ++ def class_decorator(x): ++ x.decorated = True ++ return x ++ @class_decorator ++ class G: ++ pass ++ self.assertEqual(G.decorated, True) ++ ++ def testListcomps(self): ++ # list comprehension tests ++ nums = [1, 2, 3, 4, 5] ++ strs = ["Apple", "Banana", "Coconut"] ++ spcs = [" Apple", " Banana ", "Coco nut "] ++ ++ self.assertEqual([s.strip() for s in spcs], ['Apple', 'Banana', 'Coco nut']) ++ self.assertEqual([3 * x for x in nums], [3, 6, 9, 12, 15]) ++ self.assertEqual([x for x in nums if x > 2], [3, 4, 5]) ++ self.assertEqual([(i, s) for i in nums for s in strs], ++ [(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'), ++ (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'), ++ (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'), ++ (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'), ++ (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')]) ++ self.assertEqual([(i, s) for i in nums for s in [f for f in strs if "n" in f]], ++ [(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'), ++ (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'), ++ (5, 'Banana'), (5, 'Coconut')]) ++ self.assertEqual([(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)], ++ [[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]]) ++ ++ def test_in_func(l): ++ return [None < x < 3 for x in l if x > 2] ++ ++ self.assertEqual(test_in_func(nums), [False, False, False]) ++ ++ def test_nested_front(): ++ self.assertEqual([[y for y in [x, x + 1]] for x in [1,3,5]], ++ [[1, 2], [3, 4], [5, 6]]) ++ ++ test_nested_front() ++ ++ check_syntax_error(self, "[i, s for i in nums for s in strs]") ++ check_syntax_error(self, "[x if y]") ++ ++ suppliers = [ ++ (1, "Boeing"), ++ (2, "Ford"), ++ (3, "Macdonalds") ++ ] ++ ++ parts = [ ++ (10, "Airliner"), ++ (20, "Engine"), ++ (30, "Cheeseburger") ++ ] ++ ++ suppart = [ ++ (1, 10), (1, 20), (2, 20), (3, 30) ++ ] ++ ++ x = [ ++ (sname, pname) ++ for (sno, sname) in suppliers ++ for (pno, pname) in parts ++ for (sp_sno, sp_pno) in suppart ++ if sno == sp_sno and pno == sp_pno ++ ] ++ ++ self.assertEqual(x, [('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), ++ ('Macdonalds', 'Cheeseburger')]) ++ ++ def testGenexps(self): ++ # generator expression tests ++ g = ([x for x in range(10)] for x in range(1)) ++ self.assertEqual(g.next(), [x for x in range(10)]) ++ try: ++ g.next() ++ self.fail('should produce StopIteration exception') ++ except StopIteration: ++ pass ++ ++ a = 1 ++ try: ++ g = (a for d in a) ++ g.next() ++ self.fail('should produce TypeError') ++ except TypeError: ++ pass ++ ++ self.assertEqual(list((x, y) for x in 'abcd' for y in 'abcd'), [(x, y) for x in 'abcd' for y in 'abcd']) ++ self.assertEqual(list((x, y) for x in 'ab' for y in 'xy'), [(x, y) for x in 'ab' for y in 'xy']) ++ ++ a = [x for x in range(10)] ++ b = (x for x in (y for y in a)) ++ self.assertEqual(sum(b), sum([x for x in range(10)])) ++ ++ self.assertEqual(sum(x**2 for x in range(10)), sum([x**2 for x in range(10)])) ++ self.assertEqual(sum(x*x for x in range(10) if x%2), sum([x*x for x in range(10) if x%2])) ++ self.assertEqual(sum(x for x in (y for y in range(10))), sum([x for x in range(10)])) ++ self.assertEqual(sum(x for x in (y for y in (z for z in range(10)))), sum([x for x in range(10)])) ++ self.assertEqual(sum(x for x in [y for y in (z for z in range(10))]), sum([x for x in range(10)])) ++ self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True)) if True), sum([x for x in range(10)])) ++ self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True) if False) if True), 0) ++ check_syntax_error(self, "foo(x for x in range(10), 100)") ++ check_syntax_error(self, "foo(100, x for x in range(10))") ++ ++ def testComprehensionSpecials(self): ++ # test for outmost iterable precomputation ++ x = 10; g = (i for i in range(x)); x = 5 ++ self.assertEqual(len(list(g)), 10) ++ ++ # This should hold, since we're only precomputing outmost iterable. ++ x = 10; t = False; g = ((i,j) for i in range(x) if t for j in range(x)) ++ x = 5; t = True; ++ self.assertEqual([(i,j) for i in range(10) for j in range(5)], list(g)) ++ ++ # Grammar allows multiple adjacent 'if's in listcomps and genexps, ++ # even though it's silly. Make sure it works (ifelse broke this.) ++ self.assertEqual([ x for x in range(10) if x % 2 if x % 3 ], [1, 5, 7]) ++ self.assertEqual(list(x for x in range(10) if x % 2 if x % 3), [1, 5, 7]) ++ ++ # verify unpacking single element tuples in listcomp/genexp. ++ self.assertEqual([x for x, in [(4,), (5,), (6,)]], [4, 5, 6]) ++ self.assertEqual(list(x for x, in [(7,), (8,), (9,)]), [7, 8, 9]) ++ ++ def testIfElseExpr(self): ++ # Test ifelse expressions in various cases ++ def _checkeval(msg, ret): ++ "helper to check that evaluation of expressions is done correctly" ++ print x ++ return ret ++ ++ self.assertEqual([ x() for x in lambda: True, lambda: False if x() ], [True]) ++ self.assertEqual([ x() for x in (lambda: True, lambda: False) if x() ], [True]) ++ self.assertEqual([ x(False) for x in (lambda x: False if x else True, lambda x: True if x else False) if x(False) ], [True]) ++ self.assertEqual((5 if 1 else _checkeval("check 1", 0)), 5) ++ self.assertEqual((_checkeval("check 2", 0) if 0 else 5), 5) ++ self.assertEqual((5 and 6 if 0 else 1), 1) ++ self.assertEqual(((5 and 6) if 0 else 1), 1) ++ self.assertEqual((5 and (6 if 1 else 1)), 6) ++ self.assertEqual((0 or _checkeval("check 3", 2) if 0 else 3), 3) ++ self.assertEqual((1 or _checkeval("check 4", 2) if 1 else _checkeval("check 5", 3)), 1) ++ self.assertEqual((0 or 5 if 1 else _checkeval("check 6", 3)), 5) ++ self.assertEqual((not 5 if 1 else 1), False) ++ self.assertEqual((not 5 if 0 else 1), 1) ++ self.assertEqual((6 + 1 if 1 else 2), 7) ++ self.assertEqual((6 - 1 if 1 else 2), 5) ++ self.assertEqual((6 * 2 if 1 else 4), 12) ++ self.assertEqual((6 / 2 if 1 else 3), 3) ++ self.assertEqual((6 < 4 if 0 else 2), 2) ++ ++ ++def test_main(): ++ run_unittest(TokenTests, GrammarTests) ++ ++if __name__ == '__main__': ++ test_main() +diff -r 531f2e948299 refactor/tests/data/.svn/text-base/py3_test_grammar.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/.svn/text-base/py3_test_grammar.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,903 @@ ++# Python test set -- part 1, grammar. ++# This just tests whether the parser accepts them all. ++ ++# NOTE: When you run this test as a script from the command line, you ++# get warnings about certain hex/oct constants. Since those are ++# issued by the parser, you can't suppress them by adding a ++# filterwarnings() call to this module. Therefore, to shut up the ++# regression test, the filterwarnings() call has been added to ++# regrtest.py. ++ ++from test.support import run_unittest, check_syntax_error ++import unittest ++import sys ++# testing import * ++from sys import * ++ ++class TokenTests(unittest.TestCase): ++ ++ def testBackslash(self): ++ # Backslash means line continuation: ++ x = 1 \ ++ + 1 ++ self.assertEquals(x, 2, 'backslash for line continuation') ++ ++ # Backslash does not means continuation in comments :\ ++ x = 0 ++ self.assertEquals(x, 0, 'backslash ending comment') ++ ++ def testPlainIntegers(self): ++ self.assertEquals(type(000), type(0)) ++ self.assertEquals(0xff, 255) ++ self.assertEquals(0o377, 255) ++ self.assertEquals(2147483647, 0o17777777777) ++ self.assertEquals(0b1001, 9) ++ # "0x" is not a valid literal ++ self.assertRaises(SyntaxError, eval, "0x") ++ from sys import maxsize ++ if maxsize == 2147483647: ++ self.assertEquals(-2147483647-1, -0o20000000000) ++ # XXX -2147483648 ++ self.assert_(0o37777777777 > 0) ++ self.assert_(0xffffffff > 0) ++ self.assert_(0b1111111111111111111111111111111 > 0) ++ for s in ('2147483648', '0o40000000000', '0x100000000', ++ '0b10000000000000000000000000000000'): ++ try: ++ x = eval(s) ++ except OverflowError: ++ self.fail("OverflowError on huge integer literal %r" % s) ++ elif maxsize == 9223372036854775807: ++ self.assertEquals(-9223372036854775807-1, -0o1000000000000000000000) ++ self.assert_(0o1777777777777777777777 > 0) ++ self.assert_(0xffffffffffffffff > 0) ++ self.assert_(0b11111111111111111111111111111111111111111111111111111111111111 > 0) ++ for s in '9223372036854775808', '0o2000000000000000000000', \ ++ '0x10000000000000000', \ ++ '0b100000000000000000000000000000000000000000000000000000000000000': ++ try: ++ x = eval(s) ++ except OverflowError: ++ self.fail("OverflowError on huge integer literal %r" % s) ++ else: ++ self.fail('Weird maxsize value %r' % maxsize) ++ ++ def testLongIntegers(self): ++ x = 0 ++ x = 0xffffffffffffffff ++ x = 0Xffffffffffffffff ++ x = 0o77777777777777777 ++ x = 0O77777777777777777 ++ x = 123456789012345678901234567890 ++ x = 0b100000000000000000000000000000000000000000000000000000000000000000000 ++ x = 0B111111111111111111111111111111111111111111111111111111111111111111111 ++ ++ def testFloats(self): ++ x = 3.14 ++ x = 314. ++ x = 0.314 ++ # XXX x = 000.314 ++ x = .314 ++ x = 3e14 ++ x = 3E14 ++ x = 3e-14 ++ x = 3e+14 ++ x = 3.e14 ++ x = .3e14 ++ x = 3.1e4 ++ ++ def testStringLiterals(self): ++ x = ''; y = ""; self.assert_(len(x) == 0 and x == y) ++ x = '\''; y = "'"; self.assert_(len(x) == 1 and x == y and ord(x) == 39) ++ x = '"'; y = "\""; self.assert_(len(x) == 1 and x == y and ord(x) == 34) ++ x = "doesn't \"shrink\" does it" ++ y = 'doesn\'t "shrink" does it' ++ self.assert_(len(x) == 24 and x == y) ++ x = "does \"shrink\" doesn't it" ++ y = 'does "shrink" doesn\'t it' ++ self.assert_(len(x) == 24 and x == y) ++ x = """ ++The "quick" ++brown fox ++jumps over ++the 'lazy' dog. ++""" ++ y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n' ++ self.assertEquals(x, y) ++ y = ''' ++The "quick" ++brown fox ++jumps over ++the 'lazy' dog. ++''' ++ self.assertEquals(x, y) ++ y = "\n\ ++The \"quick\"\n\ ++brown fox\n\ ++jumps over\n\ ++the 'lazy' dog.\n\ ++" ++ self.assertEquals(x, y) ++ y = '\n\ ++The \"quick\"\n\ ++brown fox\n\ ++jumps over\n\ ++the \'lazy\' dog.\n\ ++' ++ self.assertEquals(x, y) ++ ++ def testEllipsis(self): ++ x = ... ++ self.assert_(x is Ellipsis) ++ self.assertRaises(SyntaxError, eval, ".. .") ++ ++class GrammarTests(unittest.TestCase): ++ ++ # single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE ++ # XXX can't test in a script -- this rule is only used when interactive ++ ++ # file_input: (NEWLINE | stmt)* ENDMARKER ++ # Being tested as this very moment this very module ++ ++ # expr_input: testlist NEWLINE ++ # XXX Hard to test -- used only in calls to input() ++ ++ def testEvalInput(self): ++ # testlist ENDMARKER ++ x = eval('1, 0 or 1') ++ ++ def testFuncdef(self): ++ ### [decorators] 'def' NAME parameters ['->' test] ':' suite ++ ### decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE ++ ### decorators: decorator+ ++ ### parameters: '(' [typedargslist] ')' ++ ### typedargslist: ((tfpdef ['=' test] ',')* ++ ### ('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef) ++ ### | tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) ++ ### tfpdef: NAME [':' test] ++ ### varargslist: ((vfpdef ['=' test] ',')* ++ ### ('*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef) ++ ### | vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) ++ ### vfpdef: NAME ++ def f1(): pass ++ f1() ++ f1(*()) ++ f1(*(), **{}) ++ def f2(one_argument): pass ++ def f3(two, arguments): pass ++ self.assertEquals(f2.__code__.co_varnames, ('one_argument',)) ++ self.assertEquals(f3.__code__.co_varnames, ('two', 'arguments')) ++ def a1(one_arg,): pass ++ def a2(two, args,): pass ++ def v0(*rest): pass ++ def v1(a, *rest): pass ++ def v2(a, b, *rest): pass ++ ++ f1() ++ f2(1) ++ f2(1,) ++ f3(1, 2) ++ f3(1, 2,) ++ v0() ++ v0(1) ++ v0(1,) ++ v0(1,2) ++ v0(1,2,3,4,5,6,7,8,9,0) ++ v1(1) ++ v1(1,) ++ v1(1,2) ++ v1(1,2,3) ++ v1(1,2,3,4,5,6,7,8,9,0) ++ v2(1,2) ++ v2(1,2,3) ++ v2(1,2,3,4) ++ v2(1,2,3,4,5,6,7,8,9,0) ++ ++ def d01(a=1): pass ++ d01() ++ d01(1) ++ d01(*(1,)) ++ d01(**{'a':2}) ++ def d11(a, b=1): pass ++ d11(1) ++ d11(1, 2) ++ d11(1, **{'b':2}) ++ def d21(a, b, c=1): pass ++ d21(1, 2) ++ d21(1, 2, 3) ++ d21(*(1, 2, 3)) ++ d21(1, *(2, 3)) ++ d21(1, 2, *(3,)) ++ d21(1, 2, **{'c':3}) ++ def d02(a=1, b=2): pass ++ d02() ++ d02(1) ++ d02(1, 2) ++ d02(*(1, 2)) ++ d02(1, *(2,)) ++ d02(1, **{'b':2}) ++ d02(**{'a': 1, 'b': 2}) ++ def d12(a, b=1, c=2): pass ++ d12(1) ++ d12(1, 2) ++ d12(1, 2, 3) ++ def d22(a, b, c=1, d=2): pass ++ d22(1, 2) ++ d22(1, 2, 3) ++ d22(1, 2, 3, 4) ++ def d01v(a=1, *rest): pass ++ d01v() ++ d01v(1) ++ d01v(1, 2) ++ d01v(*(1, 2, 3, 4)) ++ d01v(*(1,)) ++ d01v(**{'a':2}) ++ def d11v(a, b=1, *rest): pass ++ d11v(1) ++ d11v(1, 2) ++ d11v(1, 2, 3) ++ def d21v(a, b, c=1, *rest): pass ++ d21v(1, 2) ++ d21v(1, 2, 3) ++ d21v(1, 2, 3, 4) ++ d21v(*(1, 2, 3, 4)) ++ d21v(1, 2, **{'c': 3}) ++ def d02v(a=1, b=2, *rest): pass ++ d02v() ++ d02v(1) ++ d02v(1, 2) ++ d02v(1, 2, 3) ++ d02v(1, *(2, 3, 4)) ++ d02v(**{'a': 1, 'b': 2}) ++ def d12v(a, b=1, c=2, *rest): pass ++ d12v(1) ++ d12v(1, 2) ++ d12v(1, 2, 3) ++ d12v(1, 2, 3, 4) ++ d12v(*(1, 2, 3, 4)) ++ d12v(1, 2, *(3, 4, 5)) ++ d12v(1, *(2,), **{'c': 3}) ++ def d22v(a, b, c=1, d=2, *rest): pass ++ d22v(1, 2) ++ d22v(1, 2, 3) ++ d22v(1, 2, 3, 4) ++ d22v(1, 2, 3, 4, 5) ++ d22v(*(1, 2, 3, 4)) ++ d22v(1, 2, *(3, 4, 5)) ++ d22v(1, *(2, 3), **{'d': 4}) ++ ++ # keyword argument type tests ++ try: ++ str('x', **{b'foo':1 }) ++ except TypeError: ++ pass ++ else: ++ self.fail('Bytes should not work as keyword argument names') ++ # keyword only argument tests ++ def pos0key1(*, key): return key ++ pos0key1(key=100) ++ def pos2key2(p1, p2, *, k1, k2=100): return p1,p2,k1,k2 ++ pos2key2(1, 2, k1=100) ++ pos2key2(1, 2, k1=100, k2=200) ++ pos2key2(1, 2, k2=100, k1=200) ++ def pos2key2dict(p1, p2, *, k1=100, k2, **kwarg): return p1,p2,k1,k2,kwarg ++ pos2key2dict(1,2,k2=100,tokwarg1=100,tokwarg2=200) ++ pos2key2dict(1,2,tokwarg1=100,tokwarg2=200, k2=100) ++ ++ # keyword arguments after *arglist ++ def f(*args, **kwargs): ++ return args, kwargs ++ self.assertEquals(f(1, x=2, *[3, 4], y=5), ((1, 3, 4), ++ {'x':2, 'y':5})) ++ self.assertRaises(SyntaxError, eval, "f(1, *(2,3), 4)") ++ self.assertRaises(SyntaxError, eval, "f(1, x=2, *(3,4), x=5)") ++ ++ # argument annotation tests ++ def f(x) -> list: pass ++ self.assertEquals(f.__annotations__, {'return': list}) ++ def f(x:int): pass ++ self.assertEquals(f.__annotations__, {'x': int}) ++ def f(*x:str): pass ++ self.assertEquals(f.__annotations__, {'x': str}) ++ def f(**x:float): pass ++ self.assertEquals(f.__annotations__, {'x': float}) ++ def f(x, y:1+2): pass ++ self.assertEquals(f.__annotations__, {'y': 3}) ++ def f(a, b:1, c:2, d): pass ++ self.assertEquals(f.__annotations__, {'b': 1, 'c': 2}) ++ def f(a, b:1, c:2, d, e:3=4, f=5, *g:6): pass ++ self.assertEquals(f.__annotations__, ++ {'b': 1, 'c': 2, 'e': 3, 'g': 6}) ++ def f(a, b:1, c:2, d, e:3=4, f=5, *g:6, h:7, i=8, j:9=10, ++ **k:11) -> 12: pass ++ self.assertEquals(f.__annotations__, ++ {'b': 1, 'c': 2, 'e': 3, 'g': 6, 'h': 7, 'j': 9, ++ 'k': 11, 'return': 12}) ++ # Check for SF Bug #1697248 - mixing decorators and a return annotation ++ def null(x): return x ++ @null ++ def f(x) -> list: pass ++ self.assertEquals(f.__annotations__, {'return': list}) ++ ++ # test MAKE_CLOSURE with a variety of oparg's ++ closure = 1 ++ def f(): return closure ++ def f(x=1): return closure ++ def f(*, k=1): return closure ++ def f() -> int: return closure ++ ++ # Check ast errors in *args and *kwargs ++ check_syntax_error(self, "f(*g(1=2))") ++ check_syntax_error(self, "f(**g(1=2))") ++ ++ def testLambdef(self): ++ ### lambdef: 'lambda' [varargslist] ':' test ++ l1 = lambda : 0 ++ self.assertEquals(l1(), 0) ++ l2 = lambda : a[d] # XXX just testing the expression ++ l3 = lambda : [2 < x for x in [-1, 3, 0]] ++ self.assertEquals(l3(), [0, 1, 0]) ++ l4 = lambda x = lambda y = lambda z=1 : z : y() : x() ++ self.assertEquals(l4(), 1) ++ l5 = lambda x, y, z=2: x + y + z ++ self.assertEquals(l5(1, 2), 5) ++ self.assertEquals(l5(1, 2, 3), 6) ++ check_syntax_error(self, "lambda x: x = 2") ++ check_syntax_error(self, "lambda (None,): None") ++ l6 = lambda x, y, *, k=20: x+y+k ++ self.assertEquals(l6(1,2), 1+2+20) ++ self.assertEquals(l6(1,2,k=10), 1+2+10) ++ ++ ++ ### stmt: simple_stmt | compound_stmt ++ # Tested below ++ ++ def testSimpleStmt(self): ++ ### simple_stmt: small_stmt (';' small_stmt)* [';'] ++ x = 1; pass; del x ++ def foo(): ++ # verify statments that end with semi-colons ++ x = 1; pass; del x; ++ foo() ++ ++ ### small_stmt: expr_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt ++ # Tested below ++ ++ def testExprStmt(self): ++ # (exprlist '=')* exprlist ++ 1 ++ 1, 2, 3 ++ x = 1 ++ x = 1, 2, 3 ++ x = y = z = 1, 2, 3 ++ x, y, z = 1, 2, 3 ++ abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4) ++ ++ check_syntax_error(self, "x + 1 = 1") ++ check_syntax_error(self, "a + 1 = b + 2") ++ ++ def testDelStmt(self): ++ # 'del' exprlist ++ abc = [1,2,3] ++ x, y, z = abc ++ xyz = x, y, z ++ ++ del abc ++ del x, y, (z, xyz) ++ ++ def testPassStmt(self): ++ # 'pass' ++ pass ++ ++ # flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt ++ # Tested below ++ ++ def testBreakStmt(self): ++ # 'break' ++ while 1: break ++ ++ def testContinueStmt(self): ++ # 'continue' ++ i = 1 ++ while i: i = 0; continue ++ ++ msg = "" ++ while not msg: ++ msg = "ok" ++ try: ++ continue ++ msg = "continue failed to continue inside try" ++ except: ++ msg = "continue inside try called except block" ++ if msg != "ok": ++ self.fail(msg) ++ ++ msg = "" ++ while not msg: ++ msg = "finally block not called" ++ try: ++ continue ++ finally: ++ msg = "ok" ++ if msg != "ok": ++ self.fail(msg) ++ ++ def test_break_continue_loop(self): ++ # This test warrants an explanation. It is a test specifically for SF bugs ++ # #463359 and #462937. The bug is that a 'break' statement executed or ++ # exception raised inside a try/except inside a loop, *after* a continue ++ # statement has been executed in that loop, will cause the wrong number of ++ # arguments to be popped off the stack and the instruction pointer reset to ++ # a very small number (usually 0.) Because of this, the following test ++ # *must* written as a function, and the tracking vars *must* be function ++ # arguments with default values. Otherwise, the test will loop and loop. ++ ++ def test_inner(extra_burning_oil = 1, count=0): ++ big_hippo = 2 ++ while big_hippo: ++ count += 1 ++ try: ++ if extra_burning_oil and big_hippo == 1: ++ extra_burning_oil -= 1 ++ break ++ big_hippo -= 1 ++ continue ++ except: ++ raise ++ if count > 2 or big_hippo != 1: ++ self.fail("continue then break in try/except in loop broken!") ++ test_inner() ++ ++ def testReturn(self): ++ # 'return' [testlist] ++ def g1(): return ++ def g2(): return 1 ++ g1() ++ x = g2() ++ check_syntax_error(self, "class foo:return 1") ++ ++ def testYield(self): ++ check_syntax_error(self, "class foo:yield 1") ++ ++ def testRaise(self): ++ # 'raise' test [',' test] ++ try: raise RuntimeError('just testing') ++ except RuntimeError: pass ++ try: raise KeyboardInterrupt ++ except KeyboardInterrupt: pass ++ ++ def testImport(self): ++ # 'import' dotted_as_names ++ import sys ++ import time, sys ++ # 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names) ++ from time import time ++ from time import (time) ++ # not testable inside a function, but already done at top of the module ++ # from sys import * ++ from sys import path, argv ++ from sys import (path, argv) ++ from sys import (path, argv,) ++ ++ def testGlobal(self): ++ # 'global' NAME (',' NAME)* ++ global a ++ global a, b ++ global one, two, three, four, five, six, seven, eight, nine, ten ++ ++ def testNonlocal(self): ++ # 'nonlocal' NAME (',' NAME)* ++ x = 0 ++ y = 0 ++ def f(): ++ nonlocal x ++ nonlocal x, y ++ ++ def testAssert(self): ++ # assert_stmt: 'assert' test [',' test] ++ assert 1 ++ assert 1, 1 ++ assert lambda x:x ++ assert 1, lambda x:x+1 ++ try: ++ assert 0, "msg" ++ except AssertionError as e: ++ self.assertEquals(e.args[0], "msg") ++ else: ++ if __debug__: ++ self.fail("AssertionError not raised by assert 0") ++ ++ ### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef ++ # Tested below ++ ++ def testIf(self): ++ # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] ++ if 1: pass ++ if 1: pass ++ else: pass ++ if 0: pass ++ elif 0: pass ++ if 0: pass ++ elif 0: pass ++ elif 0: pass ++ elif 0: pass ++ else: pass ++ ++ def testWhile(self): ++ # 'while' test ':' suite ['else' ':' suite] ++ while 0: pass ++ while 0: pass ++ else: pass ++ ++ # Issue1920: "while 0" is optimized away, ++ # ensure that the "else" clause is still present. ++ x = 0 ++ while 0: ++ x = 1 ++ else: ++ x = 2 ++ self.assertEquals(x, 2) ++ ++ def testFor(self): ++ # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] ++ for i in 1, 2, 3: pass ++ for i, j, k in (): pass ++ else: pass ++ class Squares: ++ def __init__(self, max): ++ self.max = max ++ self.sofar = [] ++ def __len__(self): return len(self.sofar) ++ def __getitem__(self, i): ++ if not 0 <= i < self.max: raise IndexError ++ n = len(self.sofar) ++ while n <= i: ++ self.sofar.append(n*n) ++ n = n+1 ++ return self.sofar[i] ++ n = 0 ++ for x in Squares(10): n = n+x ++ if n != 285: ++ self.fail('for over growing sequence') ++ ++ result = [] ++ for x, in [(1,), (2,), (3,)]: ++ result.append(x) ++ self.assertEqual(result, [1, 2, 3]) ++ ++ def testTry(self): ++ ### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] ++ ### | 'try' ':' suite 'finally' ':' suite ++ ### except_clause: 'except' [expr ['as' expr]] ++ try: ++ 1/0 ++ except ZeroDivisionError: ++ pass ++ else: ++ pass ++ try: 1/0 ++ except EOFError: pass ++ except TypeError as msg: pass ++ except RuntimeError as msg: pass ++ except: pass ++ else: pass ++ try: 1/0 ++ except (EOFError, TypeError, ZeroDivisionError): pass ++ try: 1/0 ++ except (EOFError, TypeError, ZeroDivisionError) as msg: pass ++ try: pass ++ finally: pass ++ ++ def testSuite(self): ++ # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT ++ if 1: pass ++ if 1: ++ pass ++ if 1: ++ # ++ # ++ # ++ pass ++ pass ++ # ++ pass ++ # ++ ++ def testTest(self): ++ ### and_test ('or' and_test)* ++ ### and_test: not_test ('and' not_test)* ++ ### not_test: 'not' not_test | comparison ++ if not 1: pass ++ if 1 and 1: pass ++ if 1 or 1: pass ++ if not not not 1: pass ++ if not 1 and 1 and 1: pass ++ if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass ++ ++ def testComparison(self): ++ ### comparison: expr (comp_op expr)* ++ ### comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is'|'is' 'not' ++ if 1: pass ++ x = (1 == 1) ++ if 1 == 1: pass ++ if 1 != 1: pass ++ if 1 < 1: pass ++ if 1 > 1: pass ++ if 1 <= 1: pass ++ if 1 >= 1: pass ++ if 1 is 1: pass ++ if 1 is not 1: pass ++ if 1 in (): pass ++ if 1 not in (): pass ++ if 1 < 1 > 1 == 1 >= 1 <= 1 != 1 in 1 not in 1 is 1 is not 1: pass ++ ++ def testBinaryMaskOps(self): ++ x = 1 & 1 ++ x = 1 ^ 1 ++ x = 1 | 1 ++ ++ def testShiftOps(self): ++ x = 1 << 1 ++ x = 1 >> 1 ++ x = 1 << 1 >> 1 ++ ++ def testAdditiveOps(self): ++ x = 1 ++ x = 1 + 1 ++ x = 1 - 1 - 1 ++ x = 1 - 1 + 1 - 1 + 1 ++ ++ def testMultiplicativeOps(self): ++ x = 1 * 1 ++ x = 1 / 1 ++ x = 1 % 1 ++ x = 1 / 1 * 1 % 1 ++ ++ def testUnaryOps(self): ++ x = +1 ++ x = -1 ++ x = ~1 ++ x = ~1 ^ 1 & 1 | 1 & 1 ^ -1 ++ x = -1*1/1 + 1*1 - ---1*1 ++ ++ def testSelectors(self): ++ ### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME ++ ### subscript: expr | [expr] ':' [expr] ++ ++ import sys, time ++ c = sys.path[0] ++ x = time.time() ++ x = sys.modules['time'].time() ++ a = '01234' ++ c = a[0] ++ c = a[-1] ++ s = a[0:5] ++ s = a[:5] ++ s = a[0:] ++ s = a[:] ++ s = a[-5:] ++ s = a[:-1] ++ s = a[-4:-3] ++ # A rough test of SF bug 1333982. http://python.org/sf/1333982 ++ # The testing here is fairly incomplete. ++ # Test cases should include: commas with 1 and 2 colons ++ d = {} ++ d[1] = 1 ++ d[1,] = 2 ++ d[1,2] = 3 ++ d[1,2,3] = 4 ++ L = list(d) ++ L.sort(key=lambda x: x if isinstance(x, tuple) else ()) ++ self.assertEquals(str(L), '[1, (1,), (1, 2), (1, 2, 3)]') ++ ++ def testAtoms(self): ++ ### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictsetmaker] '}' | NAME | NUMBER | STRING ++ ### dictsetmaker: (test ':' test (',' test ':' test)* [',']) | (test (',' test)* [',']) ++ ++ x = (1) ++ x = (1 or 2 or 3) ++ x = (1 or 2 or 3, 2, 3) ++ ++ x = [] ++ x = [1] ++ x = [1 or 2 or 3] ++ x = [1 or 2 or 3, 2, 3] ++ x = [] ++ ++ x = {} ++ x = {'one': 1} ++ x = {'one': 1,} ++ x = {'one' or 'two': 1 or 2} ++ x = {'one': 1, 'two': 2} ++ x = {'one': 1, 'two': 2,} ++ x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6} ++ ++ x = {'one'} ++ x = {'one', 1,} ++ x = {'one', 'two', 'three'} ++ x = {2, 3, 4,} ++ ++ x = x ++ x = 'x' ++ x = 123 ++ ++ ### exprlist: expr (',' expr)* [','] ++ ### testlist: test (',' test)* [','] ++ # These have been exercised enough above ++ ++ def testClassdef(self): ++ # 'class' NAME ['(' [testlist] ')'] ':' suite ++ class B: pass ++ class B2(): pass ++ class C1(B): pass ++ class C2(B): pass ++ class D(C1, C2, B): pass ++ class C: ++ def meth1(self): pass ++ def meth2(self, arg): pass ++ def meth3(self, a1, a2): pass ++ ++ # decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE ++ # decorators: decorator+ ++ # decorated: decorators (classdef | funcdef) ++ def class_decorator(x): return x ++ @class_decorator ++ class G: pass ++ ++ def testDictcomps(self): ++ # dictorsetmaker: ( (test ':' test (comp_for | ++ # (',' test ':' test)* [','])) | ++ # (test (comp_for | (',' test)* [','])) ) ++ nums = [1, 2, 3] ++ self.assertEqual({i:i+1 for i in nums}, {1: 2, 2: 3, 3: 4}) ++ ++ def testListcomps(self): ++ # list comprehension tests ++ nums = [1, 2, 3, 4, 5] ++ strs = ["Apple", "Banana", "Coconut"] ++ spcs = [" Apple", " Banana ", "Coco nut "] ++ ++ self.assertEqual([s.strip() for s in spcs], ['Apple', 'Banana', 'Coco nut']) ++ self.assertEqual([3 * x for x in nums], [3, 6, 9, 12, 15]) ++ self.assertEqual([x for x in nums if x > 2], [3, 4, 5]) ++ self.assertEqual([(i, s) for i in nums for s in strs], ++ [(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'), ++ (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'), ++ (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'), ++ (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'), ++ (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')]) ++ self.assertEqual([(i, s) for i in nums for s in [f for f in strs if "n" in f]], ++ [(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'), ++ (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'), ++ (5, 'Banana'), (5, 'Coconut')]) ++ self.assertEqual([(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)], ++ [[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]]) ++ ++ def test_in_func(l): ++ return [0 < x < 3 for x in l if x > 2] ++ ++ self.assertEqual(test_in_func(nums), [False, False, False]) ++ ++ def test_nested_front(): ++ self.assertEqual([[y for y in [x, x + 1]] for x in [1,3,5]], ++ [[1, 2], [3, 4], [5, 6]]) ++ ++ test_nested_front() ++ ++ check_syntax_error(self, "[i, s for i in nums for s in strs]") ++ check_syntax_error(self, "[x if y]") ++ ++ suppliers = [ ++ (1, "Boeing"), ++ (2, "Ford"), ++ (3, "Macdonalds") ++ ] ++ ++ parts = [ ++ (10, "Airliner"), ++ (20, "Engine"), ++ (30, "Cheeseburger") ++ ] ++ ++ suppart = [ ++ (1, 10), (1, 20), (2, 20), (3, 30) ++ ] ++ ++ x = [ ++ (sname, pname) ++ for (sno, sname) in suppliers ++ for (pno, pname) in parts ++ for (sp_sno, sp_pno) in suppart ++ if sno == sp_sno and pno == sp_pno ++ ] ++ ++ self.assertEqual(x, [('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), ++ ('Macdonalds', 'Cheeseburger')]) ++ ++ def testGenexps(self): ++ # generator expression tests ++ g = ([x for x in range(10)] for x in range(1)) ++ self.assertEqual(next(g), [x for x in range(10)]) ++ try: ++ next(g) ++ self.fail('should produce StopIteration exception') ++ except StopIteration: ++ pass ++ ++ a = 1 ++ try: ++ g = (a for d in a) ++ next(g) ++ self.fail('should produce TypeError') ++ except TypeError: ++ pass ++ ++ self.assertEqual(list((x, y) for x in 'abcd' for y in 'abcd'), [(x, y) for x in 'abcd' for y in 'abcd']) ++ self.assertEqual(list((x, y) for x in 'ab' for y in 'xy'), [(x, y) for x in 'ab' for y in 'xy']) ++ ++ a = [x for x in range(10)] ++ b = (x for x in (y for y in a)) ++ self.assertEqual(sum(b), sum([x for x in range(10)])) ++ ++ self.assertEqual(sum(x**2 for x in range(10)), sum([x**2 for x in range(10)])) ++ self.assertEqual(sum(x*x for x in range(10) if x%2), sum([x*x for x in range(10) if x%2])) ++ self.assertEqual(sum(x for x in (y for y in range(10))), sum([x for x in range(10)])) ++ self.assertEqual(sum(x for x in (y for y in (z for z in range(10)))), sum([x for x in range(10)])) ++ self.assertEqual(sum(x for x in [y for y in (z for z in range(10))]), sum([x for x in range(10)])) ++ self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True)) if True), sum([x for x in range(10)])) ++ self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True) if False) if True), 0) ++ check_syntax_error(self, "foo(x for x in range(10), 100)") ++ check_syntax_error(self, "foo(100, x for x in range(10))") ++ ++ def testComprehensionSpecials(self): ++ # test for outmost iterable precomputation ++ x = 10; g = (i for i in range(x)); x = 5 ++ self.assertEqual(len(list(g)), 10) ++ ++ # This should hold, since we're only precomputing outmost iterable. ++ x = 10; t = False; g = ((i,j) for i in range(x) if t for j in range(x)) ++ x = 5; t = True; ++ self.assertEqual([(i,j) for i in range(10) for j in range(5)], list(g)) ++ ++ # Grammar allows multiple adjacent 'if's in listcomps and genexps, ++ # even though it's silly. Make sure it works (ifelse broke this.) ++ self.assertEqual([ x for x in range(10) if x % 2 if x % 3 ], [1, 5, 7]) ++ self.assertEqual(list(x for x in range(10) if x % 2 if x % 3), [1, 5, 7]) ++ ++ # verify unpacking single element tuples in listcomp/genexp. ++ self.assertEqual([x for x, in [(4,), (5,), (6,)]], [4, 5, 6]) ++ self.assertEqual(list(x for x, in [(7,), (8,), (9,)]), [7, 8, 9]) ++ ++ def testIfElseExpr(self): ++ # Test ifelse expressions in various cases ++ def _checkeval(msg, ret): ++ "helper to check that evaluation of expressions is done correctly" ++ print(x) ++ return ret ++ ++ # the next line is not allowed anymore ++ #self.assertEqual([ x() for x in lambda: True, lambda: False if x() ], [True]) ++ self.assertEqual([ x() for x in (lambda: True, lambda: False) if x() ], [True]) ++ self.assertEqual([ x(False) for x in (lambda x: False if x else True, lambda x: True if x else False) if x(False) ], [True]) ++ self.assertEqual((5 if 1 else _checkeval("check 1", 0)), 5) ++ self.assertEqual((_checkeval("check 2", 0) if 0 else 5), 5) ++ self.assertEqual((5 and 6 if 0 else 1), 1) ++ self.assertEqual(((5 and 6) if 0 else 1), 1) ++ self.assertEqual((5 and (6 if 1 else 1)), 6) ++ self.assertEqual((0 or _checkeval("check 3", 2) if 0 else 3), 3) ++ self.assertEqual((1 or _checkeval("check 4", 2) if 1 else _checkeval("check 5", 3)), 1) ++ self.assertEqual((0 or 5 if 1 else _checkeval("check 6", 3)), 5) ++ self.assertEqual((not 5 if 1 else 1), False) ++ self.assertEqual((not 5 if 0 else 1), 1) ++ self.assertEqual((6 + 1 if 1 else 2), 7) ++ self.assertEqual((6 - 1 if 1 else 2), 5) ++ self.assertEqual((6 * 2 if 1 else 4), 12) ++ self.assertEqual((6 / 2 if 1 else 3), 3) ++ self.assertEqual((6 < 4 if 0 else 2), 2) ++ ++ ++def test_main(): ++ run_unittest(TokenTests, GrammarTests) ++ ++if __name__ == '__main__': ++ test_main() +diff -r 531f2e948299 refactor/tests/data/README +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/README Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,6 @@ ++In this directory: ++- py2_test_grammar.py -- test file that exercises most/all of Python 2.x's grammar. ++- py3_test_grammar.py -- test file that exercises most/all of Python 3.x's grammar. ++- infinite_recursion.py -- test file that causes refactor's faster recursive pattern matching ++ scheme to fail, but passes when refactor falls back to iterative pattern matching. ++- fixes/ -- for use by test_refactor.py +diff -r 531f2e948299 refactor/tests/data/fixers/.svn/all-wcprops +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/.svn/all-wcprops Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,23 @@ ++K 25 ++svn:wc:ra_dav:version-url ++V 69 ++/projects/!svn/ver/67400/sandbox/trunk/2to3/lib2to3/tests/data/fixers ++END ++no_fixer_cls.py ++K 25 ++svn:wc:ra_dav:version-url ++V 85 ++/projects/!svn/ver/66652/sandbox/trunk/2to3/lib2to3/tests/data/fixers/no_fixer_cls.py ++END ++bad_order.py ++K 25 ++svn:wc:ra_dav:version-url ++V 82 ++/projects/!svn/ver/66652/sandbox/trunk/2to3/lib2to3/tests/data/fixers/bad_order.py ++END ++parrot_example.py ++K 25 ++svn:wc:ra_dav:version-url ++V 87 ++/projects/!svn/ver/66652/sandbox/trunk/2to3/lib2to3/tests/data/fixers/parrot_example.py ++END +diff -r 531f2e948299 refactor/tests/data/fixers/.svn/dir-prop-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/.svn/dir-prop-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,7 @@ ++K 10 ++svn:ignore ++V 10 ++*.py[co] ++ ++ ++END +diff -r 531f2e948299 refactor/tests/data/fixers/.svn/entries +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/.svn/entries Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,133 @@ ++9 ++ ++dir ++70822 ++http://svn.python.org/projects/sandbox/trunk/2to3/lib2to3/tests/data/fixers ++http://svn.python.org/projects ++ ++ ++ ++2008-11-26T18:07:41.634442Z ++67400 ++benjamin.peterson ++has-props ++ ++svn:special svn:externals svn:needs-lock ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++6015fed2-1504-0410-9fe1-9d1591cc4771 ++ ++no_fixer_cls.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++b0b02321b13a7b85c9da18217f249e0c ++2008-09-27T21:03:06.866139Z ++66652 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++75 ++ ++myfixes ++dir ++ ++bad_order.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++41039de27e0a68465d89dc1718955359 ++2008-09-27T21:03:06.866139Z ++66652 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++89 ++ ++parrot_example.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++576098872ea2b821543ae01af92e50ce ++2008-09-27T21:03:06.866139Z ++66652 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++23 ++ +diff -r 531f2e948299 refactor/tests/data/fixers/.svn/format +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/.svn/format Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,1 @@ ++9 +diff -r 531f2e948299 refactor/tests/data/fixers/.svn/prop-base/bad_order.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/.svn/prop-base/bad_order.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/tests/data/fixers/.svn/prop-base/no_fixer_cls.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/.svn/prop-base/no_fixer_cls.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/tests/data/fixers/.svn/prop-base/parrot_example.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/.svn/prop-base/parrot_example.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/tests/data/fixers/.svn/text-base/bad_order.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/.svn/text-base/bad_order.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,5 @@ ++from lib2to3.fixer_base import BaseFix ++ ++class FixBadOrder(BaseFix): ++ ++ order = "crazy" +diff -r 531f2e948299 refactor/tests/data/fixers/.svn/text-base/no_fixer_cls.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/.svn/text-base/no_fixer_cls.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,1 @@ ++# This is empty so trying to fetch the fixer class gives an AttributeError +diff -r 531f2e948299 refactor/tests/data/fixers/.svn/text-base/parrot_example.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/.svn/text-base/parrot_example.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,2 @@ ++def parrot(): ++ pass +diff -r 531f2e948299 refactor/tests/data/fixers/bad_order.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/bad_order.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,5 @@ ++from refactor.fixer_base import BaseFix ++ ++class FixBadOrder(BaseFix): ++ ++ order = "crazy" +diff -r 531f2e948299 refactor/tests/data/fixers/myfixes/.svn/all-wcprops +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/myfixes/.svn/all-wcprops Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,41 @@ ++K 25 ++svn:wc:ra_dav:version-url ++V 77 ++/projects/!svn/ver/67400/sandbox/trunk/2to3/lib2to3/tests/data/fixers/myfixes ++END ++fix_preorder.py ++K 25 ++svn:wc:ra_dav:version-url ++V 93 ++/projects/!svn/ver/66652/sandbox/trunk/2to3/lib2to3/tests/data/fixers/myfixes/fix_preorder.py ++END ++fix_last.py ++K 25 ++svn:wc:ra_dav:version-url ++V 89 ++/projects/!svn/ver/66652/sandbox/trunk/2to3/lib2to3/tests/data/fixers/myfixes/fix_last.py ++END ++fix_first.py ++K 25 ++svn:wc:ra_dav:version-url ++V 90 ++/projects/!svn/ver/66652/sandbox/trunk/2to3/lib2to3/tests/data/fixers/myfixes/fix_first.py ++END ++fix_parrot.py ++K 25 ++svn:wc:ra_dav:version-url ++V 91 ++/projects/!svn/ver/66652/sandbox/trunk/2to3/lib2to3/tests/data/fixers/myfixes/fix_parrot.py ++END ++__init__.py ++K 25 ++svn:wc:ra_dav:version-url ++V 89 ++/projects/!svn/ver/66652/sandbox/trunk/2to3/lib2to3/tests/data/fixers/myfixes/__init__.py ++END ++fix_explicit.py ++K 25 ++svn:wc:ra_dav:version-url ++V 93 ++/projects/!svn/ver/66652/sandbox/trunk/2to3/lib2to3/tests/data/fixers/myfixes/fix_explicit.py ++END +diff -r 531f2e948299 refactor/tests/data/fixers/myfixes/.svn/dir-prop-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/myfixes/.svn/dir-prop-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,7 @@ ++K 10 ++svn:ignore ++V 10 ++*.py[co] ++ ++ ++END +diff -r 531f2e948299 refactor/tests/data/fixers/myfixes/.svn/entries +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/myfixes/.svn/entries Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,232 @@ ++9 ++ ++dir ++70822 ++http://svn.python.org/projects/sandbox/trunk/2to3/lib2to3/tests/data/fixers/myfixes ++http://svn.python.org/projects ++ ++ ++ ++2008-11-26T18:07:41.634442Z ++67400 ++benjamin.peterson ++has-props ++ ++svn:special svn:externals svn:needs-lock ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++6015fed2-1504-0410-9fe1-9d1591cc4771 ++ ++fix_preorder.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++ac772042a921b251e993ad33e303f2a5 ++2008-09-27T21:03:06.866139Z ++66652 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++127 ++ ++fix_last.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++25d8063f646fd75719f8cf863e857a43 ++2008-09-27T21:03:06.866139Z ++66652 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++125 ++ ++fix_first.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++baf1f88d0b82dae551dd3327f1275082 ++2008-09-27T21:03:06.866139Z ++66652 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++124 ++ ++fix_parrot.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++9f4c64c3e55d4fc7dd3bd17d4046a124 ++2008-09-27T21:03:06.866139Z ++66652 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++353 ++ ++__init__.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++d41d8cd98f00b204e9800998ecf8427e ++2008-09-27T21:03:06.866139Z ++66652 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++0 ++ ++fix_explicit.py ++file ++ ++ ++ ++ ++2009-03-31T00:29:26.000000Z ++23c047bcecfbe7c1481e217117a00414 ++2008-09-27T21:03:06.866139Z ++66652 ++benjamin.peterson ++has-props ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++123 ++ +diff -r 531f2e948299 refactor/tests/data/fixers/myfixes/.svn/format +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/myfixes/.svn/format Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,1 @@ ++9 +diff -r 531f2e948299 refactor/tests/data/fixers/myfixes/.svn/prop-base/__init__.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/myfixes/.svn/prop-base/__init__.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/tests/data/fixers/myfixes/.svn/prop-base/fix_explicit.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/myfixes/.svn/prop-base/fix_explicit.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/tests/data/fixers/myfixes/.svn/prop-base/fix_first.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/myfixes/.svn/prop-base/fix_first.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/tests/data/fixers/myfixes/.svn/prop-base/fix_last.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/myfixes/.svn/prop-base/fix_last.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/tests/data/fixers/myfixes/.svn/prop-base/fix_parrot.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/myfixes/.svn/prop-base/fix_parrot.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/tests/data/fixers/myfixes/.svn/prop-base/fix_preorder.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/myfixes/.svn/prop-base/fix_preorder.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,9 @@ ++K 13 ++svn:eol-style ++V 6 ++native ++K 12 ++svn:keywords ++V 2 ++Id ++END +diff -r 531f2e948299 refactor/tests/data/fixers/myfixes/.svn/text-base/fix_explicit.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/myfixes/.svn/text-base/fix_explicit.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,6 @@ ++from lib2to3.fixer_base import BaseFix ++ ++class FixExplicit(BaseFix): ++ explicit = True ++ ++ def match(self): return False +diff -r 531f2e948299 refactor/tests/data/fixers/myfixes/.svn/text-base/fix_first.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/myfixes/.svn/text-base/fix_first.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,6 @@ ++from lib2to3.fixer_base import BaseFix ++ ++class FixFirst(BaseFix): ++ run_order = 1 ++ ++ def match(self, node): return False +diff -r 531f2e948299 refactor/tests/data/fixers/myfixes/.svn/text-base/fix_last.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/myfixes/.svn/text-base/fix_last.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,7 @@ ++from lib2to3.fixer_base import BaseFix ++ ++class FixLast(BaseFix): ++ ++ run_order = 10 ++ ++ def match(self, node): return False +diff -r 531f2e948299 refactor/tests/data/fixers/myfixes/.svn/text-base/fix_parrot.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/myfixes/.svn/text-base/fix_parrot.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,13 @@ ++from lib2to3.fixer_base import BaseFix ++from lib2to3.fixer_util import Name ++ ++class FixParrot(BaseFix): ++ """ ++ Change functions named 'parrot' to 'cheese'. ++ """ ++ ++ PATTERN = """funcdef < 'def' name='parrot' any* >""" ++ ++ def transform(self, node, results): ++ name = results["name"] ++ name.replace(Name("cheese", name.get_prefix())) +diff -r 531f2e948299 refactor/tests/data/fixers/myfixes/.svn/text-base/fix_preorder.py.svn-base +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/myfixes/.svn/text-base/fix_preorder.py.svn-base Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,6 @@ ++from lib2to3.fixer_base import BaseFix ++ ++class FixPreorder(BaseFix): ++ order = "pre" ++ ++ def match(self, node): return False +diff -r 531f2e948299 refactor/tests/data/fixers/myfixes/fix_explicit.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/myfixes/fix_explicit.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,6 @@ ++from refactor.fixer_base import BaseFix ++ ++class FixExplicit(BaseFix): ++ explicit = True ++ ++ def match(self): return False +diff -r 531f2e948299 refactor/tests/data/fixers/myfixes/fix_first.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/myfixes/fix_first.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,6 @@ ++from refactor.fixer_base import BaseFix ++ ++class FixFirst(BaseFix): ++ run_order = 1 ++ ++ def match(self, node): return False +diff -r 531f2e948299 refactor/tests/data/fixers/myfixes/fix_last.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/myfixes/fix_last.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,7 @@ ++from refactor.fixer_base import BaseFix ++ ++class FixLast(BaseFix): ++ ++ run_order = 10 ++ ++ def match(self, node): return False +diff -r 531f2e948299 refactor/tests/data/fixers/myfixes/fix_parrot.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/myfixes/fix_parrot.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,13 @@ ++from refactor.fixer_base import BaseFix ++from refactor.fixer_util import Name ++ ++class FixParrot(BaseFix): ++ """ ++ Change functions named 'parrot' to 'cheese'. ++ """ ++ ++ PATTERN = """funcdef < 'def' name='parrot' any* >""" ++ ++ def transform(self, node, results): ++ name = results["name"] ++ name.replace(Name("cheese", name.get_prefix())) +diff -r 531f2e948299 refactor/tests/data/fixers/myfixes/fix_preorder.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/myfixes/fix_preorder.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,6 @@ ++from refactor.fixer_base import BaseFix ++ ++class FixPreorder(BaseFix): ++ order = "pre" ++ ++ def match(self, node): return False +diff -r 531f2e948299 refactor/tests/data/fixers/no_fixer_cls.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/no_fixer_cls.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,1 @@ ++# This is empty so trying to fetch the fixer class gives an AttributeError +diff -r 531f2e948299 refactor/tests/data/fixers/parrot_example.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/fixers/parrot_example.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,2 @@ ++def parrot(): ++ pass +diff -r 531f2e948299 refactor/tests/data/infinite_recursion.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/infinite_recursion.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,2670 @@ ++# This file is used to verify that refactor falls back to a slower, iterative ++# pattern matching scheme in the event that the faster recursive system fails ++# due to infinite recursion. ++from ctypes import * ++STRING = c_char_p ++ ++ ++OSUnknownByteOrder = 0 ++UIT_PROMPT = 1 ++P_PGID = 2 ++P_PID = 1 ++UIT_ERROR = 5 ++UIT_INFO = 4 ++UIT_NONE = 0 ++P_ALL = 0 ++UIT_VERIFY = 2 ++OSBigEndian = 2 ++UIT_BOOLEAN = 3 ++OSLittleEndian = 1 ++__darwin_nl_item = c_int ++__darwin_wctrans_t = c_int ++__darwin_wctype_t = c_ulong ++__int8_t = c_byte ++__uint8_t = c_ubyte ++__int16_t = c_short ++__uint16_t = c_ushort ++__int32_t = c_int ++__uint32_t = c_uint ++__int64_t = c_longlong ++__uint64_t = c_ulonglong ++__darwin_intptr_t = c_long ++__darwin_natural_t = c_uint ++__darwin_ct_rune_t = c_int ++class __mbstate_t(Union): ++ pass ++__mbstate_t._pack_ = 4 ++__mbstate_t._fields_ = [ ++ ('__mbstate8', c_char * 128), ++ ('_mbstateL', c_longlong), ++] ++assert sizeof(__mbstate_t) == 128, sizeof(__mbstate_t) ++assert alignment(__mbstate_t) == 4, alignment(__mbstate_t) ++__darwin_mbstate_t = __mbstate_t ++__darwin_ptrdiff_t = c_int ++__darwin_size_t = c_ulong ++__darwin_va_list = STRING ++__darwin_wchar_t = c_int ++__darwin_rune_t = __darwin_wchar_t ++__darwin_wint_t = c_int ++__darwin_clock_t = c_ulong ++__darwin_socklen_t = __uint32_t ++__darwin_ssize_t = c_long ++__darwin_time_t = c_long ++sig_atomic_t = c_int ++class sigcontext(Structure): ++ pass ++sigcontext._fields_ = [ ++ ('sc_onstack', c_int), ++ ('sc_mask', c_int), ++ ('sc_eax', c_uint), ++ ('sc_ebx', c_uint), ++ ('sc_ecx', c_uint), ++ ('sc_edx', c_uint), ++ ('sc_edi', c_uint), ++ ('sc_esi', c_uint), ++ ('sc_ebp', c_uint), ++ ('sc_esp', c_uint), ++ ('sc_ss', c_uint), ++ ('sc_eflags', c_uint), ++ ('sc_eip', c_uint), ++ ('sc_cs', c_uint), ++ ('sc_ds', c_uint), ++ ('sc_es', c_uint), ++ ('sc_fs', c_uint), ++ ('sc_gs', c_uint), ++] ++assert sizeof(sigcontext) == 72, sizeof(sigcontext) ++assert alignment(sigcontext) == 4, alignment(sigcontext) ++u_int8_t = c_ubyte ++u_int16_t = c_ushort ++u_int32_t = c_uint ++u_int64_t = c_ulonglong ++int32_t = c_int ++register_t = int32_t ++user_addr_t = u_int64_t ++user_size_t = u_int64_t ++int64_t = c_longlong ++user_ssize_t = int64_t ++user_long_t = int64_t ++user_ulong_t = u_int64_t ++user_time_t = int64_t ++syscall_arg_t = u_int64_t ++ ++# values for unnamed enumeration ++class aes_key_st(Structure): ++ pass ++aes_key_st._fields_ = [ ++ ('rd_key', c_ulong * 60), ++ ('rounds', c_int), ++] ++assert sizeof(aes_key_st) == 244, sizeof(aes_key_st) ++assert alignment(aes_key_st) == 4, alignment(aes_key_st) ++AES_KEY = aes_key_st ++class asn1_ctx_st(Structure): ++ pass ++asn1_ctx_st._fields_ = [ ++ ('p', POINTER(c_ubyte)), ++ ('eos', c_int), ++ ('error', c_int), ++ ('inf', c_int), ++ ('tag', c_int), ++ ('xclass', c_int), ++ ('slen', c_long), ++ ('max', POINTER(c_ubyte)), ++ ('q', POINTER(c_ubyte)), ++ ('pp', POINTER(POINTER(c_ubyte))), ++ ('line', c_int), ++] ++assert sizeof(asn1_ctx_st) == 44, sizeof(asn1_ctx_st) ++assert alignment(asn1_ctx_st) == 4, alignment(asn1_ctx_st) ++ASN1_CTX = asn1_ctx_st ++class asn1_object_st(Structure): ++ pass ++asn1_object_st._fields_ = [ ++ ('sn', STRING), ++ ('ln', STRING), ++ ('nid', c_int), ++ ('length', c_int), ++ ('data', POINTER(c_ubyte)), ++ ('flags', c_int), ++] ++assert sizeof(asn1_object_st) == 24, sizeof(asn1_object_st) ++assert alignment(asn1_object_st) == 4, alignment(asn1_object_st) ++ASN1_OBJECT = asn1_object_st ++class asn1_string_st(Structure): ++ pass ++asn1_string_st._fields_ = [ ++ ('length', c_int), ++ ('type', c_int), ++ ('data', POINTER(c_ubyte)), ++ ('flags', c_long), ++] ++assert sizeof(asn1_string_st) == 16, sizeof(asn1_string_st) ++assert alignment(asn1_string_st) == 4, alignment(asn1_string_st) ++ASN1_STRING = asn1_string_st ++class ASN1_ENCODING_st(Structure): ++ pass ++ASN1_ENCODING_st._fields_ = [ ++ ('enc', POINTER(c_ubyte)), ++ ('len', c_long), ++ ('modified', c_int), ++] ++assert sizeof(ASN1_ENCODING_st) == 12, sizeof(ASN1_ENCODING_st) ++assert alignment(ASN1_ENCODING_st) == 4, alignment(ASN1_ENCODING_st) ++ASN1_ENCODING = ASN1_ENCODING_st ++class asn1_string_table_st(Structure): ++ pass ++asn1_string_table_st._fields_ = [ ++ ('nid', c_int), ++ ('minsize', c_long), ++ ('maxsize', c_long), ++ ('mask', c_ulong), ++ ('flags', c_ulong), ++] ++assert sizeof(asn1_string_table_st) == 20, sizeof(asn1_string_table_st) ++assert alignment(asn1_string_table_st) == 4, alignment(asn1_string_table_st) ++ASN1_STRING_TABLE = asn1_string_table_st ++class ASN1_TEMPLATE_st(Structure): ++ pass ++ASN1_TEMPLATE_st._fields_ = [ ++] ++ASN1_TEMPLATE = ASN1_TEMPLATE_st ++class ASN1_ITEM_st(Structure): ++ pass ++ASN1_ITEM = ASN1_ITEM_st ++ASN1_ITEM_st._fields_ = [ ++] ++class ASN1_TLC_st(Structure): ++ pass ++ASN1_TLC = ASN1_TLC_st ++ASN1_TLC_st._fields_ = [ ++] ++class ASN1_VALUE_st(Structure): ++ pass ++ASN1_VALUE_st._fields_ = [ ++] ++ASN1_VALUE = ASN1_VALUE_st ++ASN1_ITEM_EXP = ASN1_ITEM ++class asn1_type_st(Structure): ++ pass ++class N12asn1_type_st4DOLLAR_11E(Union): ++ pass ++ASN1_BOOLEAN = c_int ++ASN1_INTEGER = asn1_string_st ++ASN1_ENUMERATED = asn1_string_st ++ASN1_BIT_STRING = asn1_string_st ++ASN1_OCTET_STRING = asn1_string_st ++ASN1_PRINTABLESTRING = asn1_string_st ++ASN1_T61STRING = asn1_string_st ++ASN1_IA5STRING = asn1_string_st ++ASN1_GENERALSTRING = asn1_string_st ++ASN1_BMPSTRING = asn1_string_st ++ASN1_UNIVERSALSTRING = asn1_string_st ++ASN1_UTCTIME = asn1_string_st ++ASN1_GENERALIZEDTIME = asn1_string_st ++ASN1_VISIBLESTRING = asn1_string_st ++ASN1_UTF8STRING = asn1_string_st ++N12asn1_type_st4DOLLAR_11E._fields_ = [ ++ ('ptr', STRING), ++ ('boolean', ASN1_BOOLEAN), ++ ('asn1_string', POINTER(ASN1_STRING)), ++ ('object', POINTER(ASN1_OBJECT)), ++ ('integer', POINTER(ASN1_INTEGER)), ++ ('enumerated', POINTER(ASN1_ENUMERATED)), ++ ('bit_string', POINTER(ASN1_BIT_STRING)), ++ ('octet_string', POINTER(ASN1_OCTET_STRING)), ++ ('printablestring', POINTER(ASN1_PRINTABLESTRING)), ++ ('t61string', POINTER(ASN1_T61STRING)), ++ ('ia5string', POINTER(ASN1_IA5STRING)), ++ ('generalstring', POINTER(ASN1_GENERALSTRING)), ++ ('bmpstring', POINTER(ASN1_BMPSTRING)), ++ ('universalstring', POINTER(ASN1_UNIVERSALSTRING)), ++ ('utctime', POINTER(ASN1_UTCTIME)), ++ ('generalizedtime', POINTER(ASN1_GENERALIZEDTIME)), ++ ('visiblestring', POINTER(ASN1_VISIBLESTRING)), ++ ('utf8string', POINTER(ASN1_UTF8STRING)), ++ ('set', POINTER(ASN1_STRING)), ++ ('sequence', POINTER(ASN1_STRING)), ++] ++assert sizeof(N12asn1_type_st4DOLLAR_11E) == 4, sizeof(N12asn1_type_st4DOLLAR_11E) ++assert alignment(N12asn1_type_st4DOLLAR_11E) == 4, alignment(N12asn1_type_st4DOLLAR_11E) ++asn1_type_st._fields_ = [ ++ ('type', c_int), ++ ('value', N12asn1_type_st4DOLLAR_11E), ++] ++assert sizeof(asn1_type_st) == 8, sizeof(asn1_type_st) ++assert alignment(asn1_type_st) == 4, alignment(asn1_type_st) ++ASN1_TYPE = asn1_type_st ++class asn1_method_st(Structure): ++ pass ++asn1_method_st._fields_ = [ ++ ('i2d', CFUNCTYPE(c_int)), ++ ('d2i', CFUNCTYPE(STRING)), ++ ('create', CFUNCTYPE(STRING)), ++ ('destroy', CFUNCTYPE(None)), ++] ++assert sizeof(asn1_method_st) == 16, sizeof(asn1_method_st) ++assert alignment(asn1_method_st) == 4, alignment(asn1_method_st) ++ASN1_METHOD = asn1_method_st ++class asn1_header_st(Structure): ++ pass ++asn1_header_st._fields_ = [ ++ ('header', POINTER(ASN1_OCTET_STRING)), ++ ('data', STRING), ++ ('meth', POINTER(ASN1_METHOD)), ++] ++assert sizeof(asn1_header_st) == 12, sizeof(asn1_header_st) ++assert alignment(asn1_header_st) == 4, alignment(asn1_header_st) ++ASN1_HEADER = asn1_header_st ++class BIT_STRING_BITNAME_st(Structure): ++ pass ++BIT_STRING_BITNAME_st._fields_ = [ ++ ('bitnum', c_int), ++ ('lname', STRING), ++ ('sname', STRING), ++] ++assert sizeof(BIT_STRING_BITNAME_st) == 12, sizeof(BIT_STRING_BITNAME_st) ++assert alignment(BIT_STRING_BITNAME_st) == 4, alignment(BIT_STRING_BITNAME_st) ++BIT_STRING_BITNAME = BIT_STRING_BITNAME_st ++class bio_st(Structure): ++ pass ++BIO = bio_st ++bio_info_cb = CFUNCTYPE(None, POINTER(bio_st), c_int, STRING, c_int, c_long, c_long) ++class bio_method_st(Structure): ++ pass ++bio_method_st._fields_ = [ ++ ('type', c_int), ++ ('name', STRING), ++ ('bwrite', CFUNCTYPE(c_int, POINTER(BIO), STRING, c_int)), ++ ('bread', CFUNCTYPE(c_int, POINTER(BIO), STRING, c_int)), ++ ('bputs', CFUNCTYPE(c_int, POINTER(BIO), STRING)), ++ ('bgets', CFUNCTYPE(c_int, POINTER(BIO), STRING, c_int)), ++ ('ctrl', CFUNCTYPE(c_long, POINTER(BIO), c_int, c_long, c_void_p)), ++ ('create', CFUNCTYPE(c_int, POINTER(BIO))), ++ ('destroy', CFUNCTYPE(c_int, POINTER(BIO))), ++ ('callback_ctrl', CFUNCTYPE(c_long, POINTER(BIO), c_int, POINTER(bio_info_cb))), ++] ++assert sizeof(bio_method_st) == 40, sizeof(bio_method_st) ++assert alignment(bio_method_st) == 4, alignment(bio_method_st) ++BIO_METHOD = bio_method_st ++class crypto_ex_data_st(Structure): ++ pass ++class stack_st(Structure): ++ pass ++STACK = stack_st ++crypto_ex_data_st._fields_ = [ ++ ('sk', POINTER(STACK)), ++ ('dummy', c_int), ++] ++assert sizeof(crypto_ex_data_st) == 8, sizeof(crypto_ex_data_st) ++assert alignment(crypto_ex_data_st) == 4, alignment(crypto_ex_data_st) ++CRYPTO_EX_DATA = crypto_ex_data_st ++bio_st._fields_ = [ ++ ('method', POINTER(BIO_METHOD)), ++ ('callback', CFUNCTYPE(c_long, POINTER(bio_st), c_int, STRING, c_int, c_long, c_long)), ++ ('cb_arg', STRING), ++ ('init', c_int), ++ ('shutdown', c_int), ++ ('flags', c_int), ++ ('retry_reason', c_int), ++ ('num', c_int), ++ ('ptr', c_void_p), ++ ('next_bio', POINTER(bio_st)), ++ ('prev_bio', POINTER(bio_st)), ++ ('references', c_int), ++ ('num_read', c_ulong), ++ ('num_write', c_ulong), ++ ('ex_data', CRYPTO_EX_DATA), ++] ++assert sizeof(bio_st) == 64, sizeof(bio_st) ++assert alignment(bio_st) == 4, alignment(bio_st) ++class bio_f_buffer_ctx_struct(Structure): ++ pass ++bio_f_buffer_ctx_struct._fields_ = [ ++ ('ibuf_size', c_int), ++ ('obuf_size', c_int), ++ ('ibuf', STRING), ++ ('ibuf_len', c_int), ++ ('ibuf_off', c_int), ++ ('obuf', STRING), ++ ('obuf_len', c_int), ++ ('obuf_off', c_int), ++] ++assert sizeof(bio_f_buffer_ctx_struct) == 32, sizeof(bio_f_buffer_ctx_struct) ++assert alignment(bio_f_buffer_ctx_struct) == 4, alignment(bio_f_buffer_ctx_struct) ++BIO_F_BUFFER_CTX = bio_f_buffer_ctx_struct ++class hostent(Structure): ++ pass ++hostent._fields_ = [ ++] ++class bf_key_st(Structure): ++ pass ++bf_key_st._fields_ = [ ++ ('P', c_uint * 18), ++ ('S', c_uint * 1024), ++] ++assert sizeof(bf_key_st) == 4168, sizeof(bf_key_st) ++assert alignment(bf_key_st) == 4, alignment(bf_key_st) ++BF_KEY = bf_key_st ++class bignum_st(Structure): ++ pass ++bignum_st._fields_ = [ ++ ('d', POINTER(c_ulong)), ++ ('top', c_int), ++ ('dmax', c_int), ++ ('neg', c_int), ++ ('flags', c_int), ++] ++assert sizeof(bignum_st) == 20, sizeof(bignum_st) ++assert alignment(bignum_st) == 4, alignment(bignum_st) ++BIGNUM = bignum_st ++class bignum_ctx(Structure): ++ pass ++bignum_ctx._fields_ = [ ++] ++BN_CTX = bignum_ctx ++class bn_blinding_st(Structure): ++ pass ++bn_blinding_st._fields_ = [ ++ ('init', c_int), ++ ('A', POINTER(BIGNUM)), ++ ('Ai', POINTER(BIGNUM)), ++ ('mod', POINTER(BIGNUM)), ++ ('thread_id', c_ulong), ++] ++assert sizeof(bn_blinding_st) == 20, sizeof(bn_blinding_st) ++assert alignment(bn_blinding_st) == 4, alignment(bn_blinding_st) ++BN_BLINDING = bn_blinding_st ++class bn_mont_ctx_st(Structure): ++ pass ++bn_mont_ctx_st._fields_ = [ ++ ('ri', c_int), ++ ('RR', BIGNUM), ++ ('N', BIGNUM), ++ ('Ni', BIGNUM), ++ ('n0', c_ulong), ++ ('flags', c_int), ++] ++assert sizeof(bn_mont_ctx_st) == 72, sizeof(bn_mont_ctx_st) ++assert alignment(bn_mont_ctx_st) == 4, alignment(bn_mont_ctx_st) ++BN_MONT_CTX = bn_mont_ctx_st ++class bn_recp_ctx_st(Structure): ++ pass ++bn_recp_ctx_st._fields_ = [ ++ ('N', BIGNUM), ++ ('Nr', BIGNUM), ++ ('num_bits', c_int), ++ ('shift', c_int), ++ ('flags', c_int), ++] ++assert sizeof(bn_recp_ctx_st) == 52, sizeof(bn_recp_ctx_st) ++assert alignment(bn_recp_ctx_st) == 4, alignment(bn_recp_ctx_st) ++BN_RECP_CTX = bn_recp_ctx_st ++class buf_mem_st(Structure): ++ pass ++buf_mem_st._fields_ = [ ++ ('length', c_int), ++ ('data', STRING), ++ ('max', c_int), ++] ++assert sizeof(buf_mem_st) == 12, sizeof(buf_mem_st) ++assert alignment(buf_mem_st) == 4, alignment(buf_mem_st) ++BUF_MEM = buf_mem_st ++class cast_key_st(Structure): ++ pass ++cast_key_st._fields_ = [ ++ ('data', c_ulong * 32), ++ ('short_key', c_int), ++] ++assert sizeof(cast_key_st) == 132, sizeof(cast_key_st) ++assert alignment(cast_key_st) == 4, alignment(cast_key_st) ++CAST_KEY = cast_key_st ++class comp_method_st(Structure): ++ pass ++comp_method_st._fields_ = [ ++ ('type', c_int), ++ ('name', STRING), ++ ('init', CFUNCTYPE(c_int)), ++ ('finish', CFUNCTYPE(None)), ++ ('compress', CFUNCTYPE(c_int)), ++ ('expand', CFUNCTYPE(c_int)), ++ ('ctrl', CFUNCTYPE(c_long)), ++ ('callback_ctrl', CFUNCTYPE(c_long)), ++] ++assert sizeof(comp_method_st) == 32, sizeof(comp_method_st) ++assert alignment(comp_method_st) == 4, alignment(comp_method_st) ++COMP_METHOD = comp_method_st ++class comp_ctx_st(Structure): ++ pass ++comp_ctx_st._fields_ = [ ++ ('meth', POINTER(COMP_METHOD)), ++ ('compress_in', c_ulong), ++ ('compress_out', c_ulong), ++ ('expand_in', c_ulong), ++ ('expand_out', c_ulong), ++ ('ex_data', CRYPTO_EX_DATA), ++] ++assert sizeof(comp_ctx_st) == 28, sizeof(comp_ctx_st) ++assert alignment(comp_ctx_st) == 4, alignment(comp_ctx_st) ++COMP_CTX = comp_ctx_st ++class CRYPTO_dynlock_value(Structure): ++ pass ++CRYPTO_dynlock_value._fields_ = [ ++] ++class CRYPTO_dynlock(Structure): ++ pass ++CRYPTO_dynlock._fields_ = [ ++ ('references', c_int), ++ ('data', POINTER(CRYPTO_dynlock_value)), ++] ++assert sizeof(CRYPTO_dynlock) == 8, sizeof(CRYPTO_dynlock) ++assert alignment(CRYPTO_dynlock) == 4, alignment(CRYPTO_dynlock) ++BIO_dummy = bio_st ++CRYPTO_EX_new = CFUNCTYPE(c_int, c_void_p, c_void_p, POINTER(CRYPTO_EX_DATA), c_int, c_long, c_void_p) ++CRYPTO_EX_free = CFUNCTYPE(None, c_void_p, c_void_p, POINTER(CRYPTO_EX_DATA), c_int, c_long, c_void_p) ++CRYPTO_EX_dup = CFUNCTYPE(c_int, POINTER(CRYPTO_EX_DATA), POINTER(CRYPTO_EX_DATA), c_void_p, c_int, c_long, c_void_p) ++class crypto_ex_data_func_st(Structure): ++ pass ++crypto_ex_data_func_st._fields_ = [ ++ ('argl', c_long), ++ ('argp', c_void_p), ++ ('new_func', POINTER(CRYPTO_EX_new)), ++ ('free_func', POINTER(CRYPTO_EX_free)), ++ ('dup_func', POINTER(CRYPTO_EX_dup)), ++] ++assert sizeof(crypto_ex_data_func_st) == 20, sizeof(crypto_ex_data_func_st) ++assert alignment(crypto_ex_data_func_st) == 4, alignment(crypto_ex_data_func_st) ++CRYPTO_EX_DATA_FUNCS = crypto_ex_data_func_st ++class st_CRYPTO_EX_DATA_IMPL(Structure): ++ pass ++CRYPTO_EX_DATA_IMPL = st_CRYPTO_EX_DATA_IMPL ++st_CRYPTO_EX_DATA_IMPL._fields_ = [ ++] ++CRYPTO_MEM_LEAK_CB = CFUNCTYPE(c_void_p, c_ulong, STRING, c_int, c_int, c_void_p) ++DES_cblock = c_ubyte * 8 ++const_DES_cblock = c_ubyte * 8 ++class DES_ks(Structure): ++ pass ++class N6DES_ks3DOLLAR_9E(Union): ++ pass ++N6DES_ks3DOLLAR_9E._fields_ = [ ++ ('cblock', DES_cblock), ++ ('deslong', c_ulong * 2), ++] ++assert sizeof(N6DES_ks3DOLLAR_9E) == 8, sizeof(N6DES_ks3DOLLAR_9E) ++assert alignment(N6DES_ks3DOLLAR_9E) == 4, alignment(N6DES_ks3DOLLAR_9E) ++DES_ks._fields_ = [ ++ ('ks', N6DES_ks3DOLLAR_9E * 16), ++] ++assert sizeof(DES_ks) == 128, sizeof(DES_ks) ++assert alignment(DES_ks) == 4, alignment(DES_ks) ++DES_key_schedule = DES_ks ++_ossl_old_des_cblock = c_ubyte * 8 ++class _ossl_old_des_ks_struct(Structure): ++ pass ++class N23_ossl_old_des_ks_struct4DOLLAR_10E(Union): ++ pass ++N23_ossl_old_des_ks_struct4DOLLAR_10E._fields_ = [ ++ ('_', _ossl_old_des_cblock), ++ ('pad', c_ulong * 2), ++] ++assert sizeof(N23_ossl_old_des_ks_struct4DOLLAR_10E) == 8, sizeof(N23_ossl_old_des_ks_struct4DOLLAR_10E) ++assert alignment(N23_ossl_old_des_ks_struct4DOLLAR_10E) == 4, alignment(N23_ossl_old_des_ks_struct4DOLLAR_10E) ++_ossl_old_des_ks_struct._fields_ = [ ++ ('ks', N23_ossl_old_des_ks_struct4DOLLAR_10E), ++] ++assert sizeof(_ossl_old_des_ks_struct) == 8, sizeof(_ossl_old_des_ks_struct) ++assert alignment(_ossl_old_des_ks_struct) == 4, alignment(_ossl_old_des_ks_struct) ++_ossl_old_des_key_schedule = _ossl_old_des_ks_struct * 16 ++class dh_st(Structure): ++ pass ++DH = dh_st ++class dh_method(Structure): ++ pass ++dh_method._fields_ = [ ++ ('name', STRING), ++ ('generate_key', CFUNCTYPE(c_int, POINTER(DH))), ++ ('compute_key', CFUNCTYPE(c_int, POINTER(c_ubyte), POINTER(BIGNUM), POINTER(DH))), ++ ('bn_mod_exp', CFUNCTYPE(c_int, POINTER(DH), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BN_CTX), POINTER(BN_MONT_CTX))), ++ ('init', CFUNCTYPE(c_int, POINTER(DH))), ++ ('finish', CFUNCTYPE(c_int, POINTER(DH))), ++ ('flags', c_int), ++ ('app_data', STRING), ++] ++assert sizeof(dh_method) == 32, sizeof(dh_method) ++assert alignment(dh_method) == 4, alignment(dh_method) ++DH_METHOD = dh_method ++class engine_st(Structure): ++ pass ++ENGINE = engine_st ++dh_st._fields_ = [ ++ ('pad', c_int), ++ ('version', c_int), ++ ('p', POINTER(BIGNUM)), ++ ('g', POINTER(BIGNUM)), ++ ('length', c_long), ++ ('pub_key', POINTER(BIGNUM)), ++ ('priv_key', POINTER(BIGNUM)), ++ ('flags', c_int), ++ ('method_mont_p', STRING), ++ ('q', POINTER(BIGNUM)), ++ ('j', POINTER(BIGNUM)), ++ ('seed', POINTER(c_ubyte)), ++ ('seedlen', c_int), ++ ('counter', POINTER(BIGNUM)), ++ ('references', c_int), ++ ('ex_data', CRYPTO_EX_DATA), ++ ('meth', POINTER(DH_METHOD)), ++ ('engine', POINTER(ENGINE)), ++] ++assert sizeof(dh_st) == 76, sizeof(dh_st) ++assert alignment(dh_st) == 4, alignment(dh_st) ++class dsa_st(Structure): ++ pass ++DSA = dsa_st ++class DSA_SIG_st(Structure): ++ pass ++DSA_SIG_st._fields_ = [ ++ ('r', POINTER(BIGNUM)), ++ ('s', POINTER(BIGNUM)), ++] ++assert sizeof(DSA_SIG_st) == 8, sizeof(DSA_SIG_st) ++assert alignment(DSA_SIG_st) == 4, alignment(DSA_SIG_st) ++DSA_SIG = DSA_SIG_st ++class dsa_method(Structure): ++ pass ++dsa_method._fields_ = [ ++ ('name', STRING), ++ ('dsa_do_sign', CFUNCTYPE(POINTER(DSA_SIG), POINTER(c_ubyte), c_int, POINTER(DSA))), ++ ('dsa_sign_setup', CFUNCTYPE(c_int, POINTER(DSA), POINTER(BN_CTX), POINTER(POINTER(BIGNUM)), POINTER(POINTER(BIGNUM)))), ++ ('dsa_do_verify', CFUNCTYPE(c_int, POINTER(c_ubyte), c_int, POINTER(DSA_SIG), POINTER(DSA))), ++ ('dsa_mod_exp', CFUNCTYPE(c_int, POINTER(DSA), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BN_CTX), POINTER(BN_MONT_CTX))), ++ ('bn_mod_exp', CFUNCTYPE(c_int, POINTER(DSA), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BN_CTX), POINTER(BN_MONT_CTX))), ++ ('init', CFUNCTYPE(c_int, POINTER(DSA))), ++ ('finish', CFUNCTYPE(c_int, POINTER(DSA))), ++ ('flags', c_int), ++ ('app_data', STRING), ++] ++assert sizeof(dsa_method) == 40, sizeof(dsa_method) ++assert alignment(dsa_method) == 4, alignment(dsa_method) ++DSA_METHOD = dsa_method ++dsa_st._fields_ = [ ++ ('pad', c_int), ++ ('version', c_long), ++ ('write_params', c_int), ++ ('p', POINTER(BIGNUM)), ++ ('q', POINTER(BIGNUM)), ++ ('g', POINTER(BIGNUM)), ++ ('pub_key', POINTER(BIGNUM)), ++ ('priv_key', POINTER(BIGNUM)), ++ ('kinv', POINTER(BIGNUM)), ++ ('r', POINTER(BIGNUM)), ++ ('flags', c_int), ++ ('method_mont_p', STRING), ++ ('references', c_int), ++ ('ex_data', CRYPTO_EX_DATA), ++ ('meth', POINTER(DSA_METHOD)), ++ ('engine', POINTER(ENGINE)), ++] ++assert sizeof(dsa_st) == 68, sizeof(dsa_st) ++assert alignment(dsa_st) == 4, alignment(dsa_st) ++class evp_pkey_st(Structure): ++ pass ++class N11evp_pkey_st4DOLLAR_12E(Union): ++ pass ++class rsa_st(Structure): ++ pass ++N11evp_pkey_st4DOLLAR_12E._fields_ = [ ++ ('ptr', STRING), ++ ('rsa', POINTER(rsa_st)), ++ ('dsa', POINTER(dsa_st)), ++ ('dh', POINTER(dh_st)), ++] ++assert sizeof(N11evp_pkey_st4DOLLAR_12E) == 4, sizeof(N11evp_pkey_st4DOLLAR_12E) ++assert alignment(N11evp_pkey_st4DOLLAR_12E) == 4, alignment(N11evp_pkey_st4DOLLAR_12E) ++evp_pkey_st._fields_ = [ ++ ('type', c_int), ++ ('save_type', c_int), ++ ('references', c_int), ++ ('pkey', N11evp_pkey_st4DOLLAR_12E), ++ ('save_parameters', c_int), ++ ('attributes', POINTER(STACK)), ++] ++assert sizeof(evp_pkey_st) == 24, sizeof(evp_pkey_st) ++assert alignment(evp_pkey_st) == 4, alignment(evp_pkey_st) ++class env_md_st(Structure): ++ pass ++class env_md_ctx_st(Structure): ++ pass ++EVP_MD_CTX = env_md_ctx_st ++env_md_st._fields_ = [ ++ ('type', c_int), ++ ('pkey_type', c_int), ++ ('md_size', c_int), ++ ('flags', c_ulong), ++ ('init', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX))), ++ ('update', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX), c_void_p, c_ulong)), ++ ('final', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX), POINTER(c_ubyte))), ++ ('copy', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX), POINTER(EVP_MD_CTX))), ++ ('cleanup', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX))), ++ ('sign', CFUNCTYPE(c_int)), ++ ('verify', CFUNCTYPE(c_int)), ++ ('required_pkey_type', c_int * 5), ++ ('block_size', c_int), ++ ('ctx_size', c_int), ++] ++assert sizeof(env_md_st) == 72, sizeof(env_md_st) ++assert alignment(env_md_st) == 4, alignment(env_md_st) ++EVP_MD = env_md_st ++env_md_ctx_st._fields_ = [ ++ ('digest', POINTER(EVP_MD)), ++ ('engine', POINTER(ENGINE)), ++ ('flags', c_ulong), ++ ('md_data', c_void_p), ++] ++assert sizeof(env_md_ctx_st) == 16, sizeof(env_md_ctx_st) ++assert alignment(env_md_ctx_st) == 4, alignment(env_md_ctx_st) ++class evp_cipher_st(Structure): ++ pass ++class evp_cipher_ctx_st(Structure): ++ pass ++EVP_CIPHER_CTX = evp_cipher_ctx_st ++evp_cipher_st._fields_ = [ ++ ('nid', c_int), ++ ('block_size', c_int), ++ ('key_len', c_int), ++ ('iv_len', c_int), ++ ('flags', c_ulong), ++ ('init', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), POINTER(c_ubyte), POINTER(c_ubyte), c_int)), ++ ('do_cipher', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), POINTER(c_ubyte), POINTER(c_ubyte), c_uint)), ++ ('cleanup', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX))), ++ ('ctx_size', c_int), ++ ('set_asn1_parameters', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), POINTER(ASN1_TYPE))), ++ ('get_asn1_parameters', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), POINTER(ASN1_TYPE))), ++ ('ctrl', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), c_int, c_int, c_void_p)), ++ ('app_data', c_void_p), ++] ++assert sizeof(evp_cipher_st) == 52, sizeof(evp_cipher_st) ++assert alignment(evp_cipher_st) == 4, alignment(evp_cipher_st) ++class evp_cipher_info_st(Structure): ++ pass ++EVP_CIPHER = evp_cipher_st ++evp_cipher_info_st._fields_ = [ ++ ('cipher', POINTER(EVP_CIPHER)), ++ ('iv', c_ubyte * 16), ++] ++assert sizeof(evp_cipher_info_st) == 20, sizeof(evp_cipher_info_st) ++assert alignment(evp_cipher_info_st) == 4, alignment(evp_cipher_info_st) ++EVP_CIPHER_INFO = evp_cipher_info_st ++evp_cipher_ctx_st._fields_ = [ ++ ('cipher', POINTER(EVP_CIPHER)), ++ ('engine', POINTER(ENGINE)), ++ ('encrypt', c_int), ++ ('buf_len', c_int), ++ ('oiv', c_ubyte * 16), ++ ('iv', c_ubyte * 16), ++ ('buf', c_ubyte * 32), ++ ('num', c_int), ++ ('app_data', c_void_p), ++ ('key_len', c_int), ++ ('flags', c_ulong), ++ ('cipher_data', c_void_p), ++ ('final_used', c_int), ++ ('block_mask', c_int), ++ ('final', c_ubyte * 32), ++] ++assert sizeof(evp_cipher_ctx_st) == 140, sizeof(evp_cipher_ctx_st) ++assert alignment(evp_cipher_ctx_st) == 4, alignment(evp_cipher_ctx_st) ++class evp_Encode_Ctx_st(Structure): ++ pass ++evp_Encode_Ctx_st._fields_ = [ ++ ('num', c_int), ++ ('length', c_int), ++ ('enc_data', c_ubyte * 80), ++ ('line_num', c_int), ++ ('expect_nl', c_int), ++] ++assert sizeof(evp_Encode_Ctx_st) == 96, sizeof(evp_Encode_Ctx_st) ++assert alignment(evp_Encode_Ctx_st) == 4, alignment(evp_Encode_Ctx_st) ++EVP_ENCODE_CTX = evp_Encode_Ctx_st ++EVP_PBE_KEYGEN = CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), STRING, c_int, POINTER(ASN1_TYPE), POINTER(EVP_CIPHER), POINTER(EVP_MD), c_int) ++class lhash_node_st(Structure): ++ pass ++lhash_node_st._fields_ = [ ++ ('data', c_void_p), ++ ('next', POINTER(lhash_node_st)), ++ ('hash', c_ulong), ++] ++assert sizeof(lhash_node_st) == 12, sizeof(lhash_node_st) ++assert alignment(lhash_node_st) == 4, alignment(lhash_node_st) ++LHASH_NODE = lhash_node_st ++LHASH_COMP_FN_TYPE = CFUNCTYPE(c_int, c_void_p, c_void_p) ++LHASH_HASH_FN_TYPE = CFUNCTYPE(c_ulong, c_void_p) ++LHASH_DOALL_FN_TYPE = CFUNCTYPE(None, c_void_p) ++LHASH_DOALL_ARG_FN_TYPE = CFUNCTYPE(None, c_void_p, c_void_p) ++class lhash_st(Structure): ++ pass ++lhash_st._fields_ = [ ++ ('b', POINTER(POINTER(LHASH_NODE))), ++ ('comp', LHASH_COMP_FN_TYPE), ++ ('hash', LHASH_HASH_FN_TYPE), ++ ('num_nodes', c_uint), ++ ('num_alloc_nodes', c_uint), ++ ('p', c_uint), ++ ('pmax', c_uint), ++ ('up_load', c_ulong), ++ ('down_load', c_ulong), ++ ('num_items', c_ulong), ++ ('num_expands', c_ulong), ++ ('num_expand_reallocs', c_ulong), ++ ('num_contracts', c_ulong), ++ ('num_contract_reallocs', c_ulong), ++ ('num_hash_calls', c_ulong), ++ ('num_comp_calls', c_ulong), ++ ('num_insert', c_ulong), ++ ('num_replace', c_ulong), ++ ('num_delete', c_ulong), ++ ('num_no_delete', c_ulong), ++ ('num_retrieve', c_ulong), ++ ('num_retrieve_miss', c_ulong), ++ ('num_hash_comps', c_ulong), ++ ('error', c_int), ++] ++assert sizeof(lhash_st) == 96, sizeof(lhash_st) ++assert alignment(lhash_st) == 4, alignment(lhash_st) ++LHASH = lhash_st ++class MD2state_st(Structure): ++ pass ++MD2state_st._fields_ = [ ++ ('num', c_int), ++ ('data', c_ubyte * 16), ++ ('cksm', c_uint * 16), ++ ('state', c_uint * 16), ++] ++assert sizeof(MD2state_st) == 148, sizeof(MD2state_st) ++assert alignment(MD2state_st) == 4, alignment(MD2state_st) ++MD2_CTX = MD2state_st ++class MD4state_st(Structure): ++ pass ++MD4state_st._fields_ = [ ++ ('A', c_uint), ++ ('B', c_uint), ++ ('C', c_uint), ++ ('D', c_uint), ++ ('Nl', c_uint), ++ ('Nh', c_uint), ++ ('data', c_uint * 16), ++ ('num', c_int), ++] ++assert sizeof(MD4state_st) == 92, sizeof(MD4state_st) ++assert alignment(MD4state_st) == 4, alignment(MD4state_st) ++MD4_CTX = MD4state_st ++class MD5state_st(Structure): ++ pass ++MD5state_st._fields_ = [ ++ ('A', c_uint), ++ ('B', c_uint), ++ ('C', c_uint), ++ ('D', c_uint), ++ ('Nl', c_uint), ++ ('Nh', c_uint), ++ ('data', c_uint * 16), ++ ('num', c_int), ++] ++assert sizeof(MD5state_st) == 92, sizeof(MD5state_st) ++assert alignment(MD5state_st) == 4, alignment(MD5state_st) ++MD5_CTX = MD5state_st ++class mdc2_ctx_st(Structure): ++ pass ++mdc2_ctx_st._fields_ = [ ++ ('num', c_int), ++ ('data', c_ubyte * 8), ++ ('h', DES_cblock), ++ ('hh', DES_cblock), ++ ('pad_type', c_int), ++] ++assert sizeof(mdc2_ctx_st) == 32, sizeof(mdc2_ctx_st) ++assert alignment(mdc2_ctx_st) == 4, alignment(mdc2_ctx_st) ++MDC2_CTX = mdc2_ctx_st ++class obj_name_st(Structure): ++ pass ++obj_name_st._fields_ = [ ++ ('type', c_int), ++ ('alias', c_int), ++ ('name', STRING), ++ ('data', STRING), ++] ++assert sizeof(obj_name_st) == 16, sizeof(obj_name_st) ++assert alignment(obj_name_st) == 4, alignment(obj_name_st) ++OBJ_NAME = obj_name_st ++ASN1_TIME = asn1_string_st ++ASN1_NULL = c_int ++EVP_PKEY = evp_pkey_st ++class x509_st(Structure): ++ pass ++X509 = x509_st ++class X509_algor_st(Structure): ++ pass ++X509_ALGOR = X509_algor_st ++class X509_crl_st(Structure): ++ pass ++X509_CRL = X509_crl_st ++class X509_name_st(Structure): ++ pass ++X509_NAME = X509_name_st ++class x509_store_st(Structure): ++ pass ++X509_STORE = x509_store_st ++class x509_store_ctx_st(Structure): ++ pass ++X509_STORE_CTX = x509_store_ctx_st ++engine_st._fields_ = [ ++] ++class PEM_Encode_Seal_st(Structure): ++ pass ++PEM_Encode_Seal_st._fields_ = [ ++ ('encode', EVP_ENCODE_CTX), ++ ('md', EVP_MD_CTX), ++ ('cipher', EVP_CIPHER_CTX), ++] ++assert sizeof(PEM_Encode_Seal_st) == 252, sizeof(PEM_Encode_Seal_st) ++assert alignment(PEM_Encode_Seal_st) == 4, alignment(PEM_Encode_Seal_st) ++PEM_ENCODE_SEAL_CTX = PEM_Encode_Seal_st ++class pem_recip_st(Structure): ++ pass ++pem_recip_st._fields_ = [ ++ ('name', STRING), ++ ('dn', POINTER(X509_NAME)), ++ ('cipher', c_int), ++ ('key_enc', c_int), ++] ++assert sizeof(pem_recip_st) == 16, sizeof(pem_recip_st) ++assert alignment(pem_recip_st) == 4, alignment(pem_recip_st) ++PEM_USER = pem_recip_st ++class pem_ctx_st(Structure): ++ pass ++class N10pem_ctx_st4DOLLAR_16E(Structure): ++ pass ++N10pem_ctx_st4DOLLAR_16E._fields_ = [ ++ ('version', c_int), ++ ('mode', c_int), ++] ++assert sizeof(N10pem_ctx_st4DOLLAR_16E) == 8, sizeof(N10pem_ctx_st4DOLLAR_16E) ++assert alignment(N10pem_ctx_st4DOLLAR_16E) == 4, alignment(N10pem_ctx_st4DOLLAR_16E) ++class N10pem_ctx_st4DOLLAR_17E(Structure): ++ pass ++N10pem_ctx_st4DOLLAR_17E._fields_ = [ ++ ('cipher', c_int), ++] ++assert sizeof(N10pem_ctx_st4DOLLAR_17E) == 4, sizeof(N10pem_ctx_st4DOLLAR_17E) ++assert alignment(N10pem_ctx_st4DOLLAR_17E) == 4, alignment(N10pem_ctx_st4DOLLAR_17E) ++pem_ctx_st._fields_ = [ ++ ('type', c_int), ++ ('proc_type', N10pem_ctx_st4DOLLAR_16E), ++ ('domain', STRING), ++ ('DEK_info', N10pem_ctx_st4DOLLAR_17E), ++ ('originator', POINTER(PEM_USER)), ++ ('num_recipient', c_int), ++ ('recipient', POINTER(POINTER(PEM_USER))), ++ ('x509_chain', POINTER(STACK)), ++ ('md', POINTER(EVP_MD)), ++ ('md_enc', c_int), ++ ('md_len', c_int), ++ ('md_data', STRING), ++ ('dec', POINTER(EVP_CIPHER)), ++ ('key_len', c_int), ++ ('key', POINTER(c_ubyte)), ++ ('data_enc', c_int), ++ ('data_len', c_int), ++ ('data', POINTER(c_ubyte)), ++] ++assert sizeof(pem_ctx_st) == 76, sizeof(pem_ctx_st) ++assert alignment(pem_ctx_st) == 4, alignment(pem_ctx_st) ++PEM_CTX = pem_ctx_st ++pem_password_cb = CFUNCTYPE(c_int, STRING, c_int, c_int, c_void_p) ++class pkcs7_issuer_and_serial_st(Structure): ++ pass ++pkcs7_issuer_and_serial_st._fields_ = [ ++ ('issuer', POINTER(X509_NAME)), ++ ('serial', POINTER(ASN1_INTEGER)), ++] ++assert sizeof(pkcs7_issuer_and_serial_st) == 8, sizeof(pkcs7_issuer_and_serial_st) ++assert alignment(pkcs7_issuer_and_serial_st) == 4, alignment(pkcs7_issuer_and_serial_st) ++PKCS7_ISSUER_AND_SERIAL = pkcs7_issuer_and_serial_st ++class pkcs7_signer_info_st(Structure): ++ pass ++pkcs7_signer_info_st._fields_ = [ ++ ('version', POINTER(ASN1_INTEGER)), ++ ('issuer_and_serial', POINTER(PKCS7_ISSUER_AND_SERIAL)), ++ ('digest_alg', POINTER(X509_ALGOR)), ++ ('auth_attr', POINTER(STACK)), ++ ('digest_enc_alg', POINTER(X509_ALGOR)), ++ ('enc_digest', POINTER(ASN1_OCTET_STRING)), ++ ('unauth_attr', POINTER(STACK)), ++ ('pkey', POINTER(EVP_PKEY)), ++] ++assert sizeof(pkcs7_signer_info_st) == 32, sizeof(pkcs7_signer_info_st) ++assert alignment(pkcs7_signer_info_st) == 4, alignment(pkcs7_signer_info_st) ++PKCS7_SIGNER_INFO = pkcs7_signer_info_st ++class pkcs7_recip_info_st(Structure): ++ pass ++pkcs7_recip_info_st._fields_ = [ ++ ('version', POINTER(ASN1_INTEGER)), ++ ('issuer_and_serial', POINTER(PKCS7_ISSUER_AND_SERIAL)), ++ ('key_enc_algor', POINTER(X509_ALGOR)), ++ ('enc_key', POINTER(ASN1_OCTET_STRING)), ++ ('cert', POINTER(X509)), ++] ++assert sizeof(pkcs7_recip_info_st) == 20, sizeof(pkcs7_recip_info_st) ++assert alignment(pkcs7_recip_info_st) == 4, alignment(pkcs7_recip_info_st) ++PKCS7_RECIP_INFO = pkcs7_recip_info_st ++class pkcs7_signed_st(Structure): ++ pass ++class pkcs7_st(Structure): ++ pass ++pkcs7_signed_st._fields_ = [ ++ ('version', POINTER(ASN1_INTEGER)), ++ ('md_algs', POINTER(STACK)), ++ ('cert', POINTER(STACK)), ++ ('crl', POINTER(STACK)), ++ ('signer_info', POINTER(STACK)), ++ ('contents', POINTER(pkcs7_st)), ++] ++assert sizeof(pkcs7_signed_st) == 24, sizeof(pkcs7_signed_st) ++assert alignment(pkcs7_signed_st) == 4, alignment(pkcs7_signed_st) ++PKCS7_SIGNED = pkcs7_signed_st ++class pkcs7_enc_content_st(Structure): ++ pass ++pkcs7_enc_content_st._fields_ = [ ++ ('content_type', POINTER(ASN1_OBJECT)), ++ ('algorithm', POINTER(X509_ALGOR)), ++ ('enc_data', POINTER(ASN1_OCTET_STRING)), ++ ('cipher', POINTER(EVP_CIPHER)), ++] ++assert sizeof(pkcs7_enc_content_st) == 16, sizeof(pkcs7_enc_content_st) ++assert alignment(pkcs7_enc_content_st) == 4, alignment(pkcs7_enc_content_st) ++PKCS7_ENC_CONTENT = pkcs7_enc_content_st ++class pkcs7_enveloped_st(Structure): ++ pass ++pkcs7_enveloped_st._fields_ = [ ++ ('version', POINTER(ASN1_INTEGER)), ++ ('recipientinfo', POINTER(STACK)), ++ ('enc_data', POINTER(PKCS7_ENC_CONTENT)), ++] ++assert sizeof(pkcs7_enveloped_st) == 12, sizeof(pkcs7_enveloped_st) ++assert alignment(pkcs7_enveloped_st) == 4, alignment(pkcs7_enveloped_st) ++PKCS7_ENVELOPE = pkcs7_enveloped_st ++class pkcs7_signedandenveloped_st(Structure): ++ pass ++pkcs7_signedandenveloped_st._fields_ = [ ++ ('version', POINTER(ASN1_INTEGER)), ++ ('md_algs', POINTER(STACK)), ++ ('cert', POINTER(STACK)), ++ ('crl', POINTER(STACK)), ++ ('signer_info', POINTER(STACK)), ++ ('enc_data', POINTER(PKCS7_ENC_CONTENT)), ++ ('recipientinfo', POINTER(STACK)), ++] ++assert sizeof(pkcs7_signedandenveloped_st) == 28, sizeof(pkcs7_signedandenveloped_st) ++assert alignment(pkcs7_signedandenveloped_st) == 4, alignment(pkcs7_signedandenveloped_st) ++PKCS7_SIGN_ENVELOPE = pkcs7_signedandenveloped_st ++class pkcs7_digest_st(Structure): ++ pass ++pkcs7_digest_st._fields_ = [ ++ ('version', POINTER(ASN1_INTEGER)), ++ ('md', POINTER(X509_ALGOR)), ++ ('contents', POINTER(pkcs7_st)), ++ ('digest', POINTER(ASN1_OCTET_STRING)), ++] ++assert sizeof(pkcs7_digest_st) == 16, sizeof(pkcs7_digest_st) ++assert alignment(pkcs7_digest_st) == 4, alignment(pkcs7_digest_st) ++PKCS7_DIGEST = pkcs7_digest_st ++class pkcs7_encrypted_st(Structure): ++ pass ++pkcs7_encrypted_st._fields_ = [ ++ ('version', POINTER(ASN1_INTEGER)), ++ ('enc_data', POINTER(PKCS7_ENC_CONTENT)), ++] ++assert sizeof(pkcs7_encrypted_st) == 8, sizeof(pkcs7_encrypted_st) ++assert alignment(pkcs7_encrypted_st) == 4, alignment(pkcs7_encrypted_st) ++PKCS7_ENCRYPT = pkcs7_encrypted_st ++class N8pkcs7_st4DOLLAR_15E(Union): ++ pass ++N8pkcs7_st4DOLLAR_15E._fields_ = [ ++ ('ptr', STRING), ++ ('data', POINTER(ASN1_OCTET_STRING)), ++ ('sign', POINTER(PKCS7_SIGNED)), ++ ('enveloped', POINTER(PKCS7_ENVELOPE)), ++ ('signed_and_enveloped', POINTER(PKCS7_SIGN_ENVELOPE)), ++ ('digest', POINTER(PKCS7_DIGEST)), ++ ('encrypted', POINTER(PKCS7_ENCRYPT)), ++ ('other', POINTER(ASN1_TYPE)), ++] ++assert sizeof(N8pkcs7_st4DOLLAR_15E) == 4, sizeof(N8pkcs7_st4DOLLAR_15E) ++assert alignment(N8pkcs7_st4DOLLAR_15E) == 4, alignment(N8pkcs7_st4DOLLAR_15E) ++pkcs7_st._fields_ = [ ++ ('asn1', POINTER(c_ubyte)), ++ ('length', c_long), ++ ('state', c_int), ++ ('detached', c_int), ++ ('type', POINTER(ASN1_OBJECT)), ++ ('d', N8pkcs7_st4DOLLAR_15E), ++] ++assert sizeof(pkcs7_st) == 24, sizeof(pkcs7_st) ++assert alignment(pkcs7_st) == 4, alignment(pkcs7_st) ++PKCS7 = pkcs7_st ++class rc2_key_st(Structure): ++ pass ++rc2_key_st._fields_ = [ ++ ('data', c_uint * 64), ++] ++assert sizeof(rc2_key_st) == 256, sizeof(rc2_key_st) ++assert alignment(rc2_key_st) == 4, alignment(rc2_key_st) ++RC2_KEY = rc2_key_st ++class rc4_key_st(Structure): ++ pass ++rc4_key_st._fields_ = [ ++ ('x', c_ubyte), ++ ('y', c_ubyte), ++ ('data', c_ubyte * 256), ++] ++assert sizeof(rc4_key_st) == 258, sizeof(rc4_key_st) ++assert alignment(rc4_key_st) == 1, alignment(rc4_key_st) ++RC4_KEY = rc4_key_st ++class rc5_key_st(Structure): ++ pass ++rc5_key_st._fields_ = [ ++ ('rounds', c_int), ++ ('data', c_ulong * 34), ++] ++assert sizeof(rc5_key_st) == 140, sizeof(rc5_key_st) ++assert alignment(rc5_key_st) == 4, alignment(rc5_key_st) ++RC5_32_KEY = rc5_key_st ++class RIPEMD160state_st(Structure): ++ pass ++RIPEMD160state_st._fields_ = [ ++ ('A', c_uint), ++ ('B', c_uint), ++ ('C', c_uint), ++ ('D', c_uint), ++ ('E', c_uint), ++ ('Nl', c_uint), ++ ('Nh', c_uint), ++ ('data', c_uint * 16), ++ ('num', c_int), ++] ++assert sizeof(RIPEMD160state_st) == 96, sizeof(RIPEMD160state_st) ++assert alignment(RIPEMD160state_st) == 4, alignment(RIPEMD160state_st) ++RIPEMD160_CTX = RIPEMD160state_st ++RSA = rsa_st ++class rsa_meth_st(Structure): ++ pass ++rsa_meth_st._fields_ = [ ++ ('name', STRING), ++ ('rsa_pub_enc', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), POINTER(c_ubyte), POINTER(RSA), c_int)), ++ ('rsa_pub_dec', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), POINTER(c_ubyte), POINTER(RSA), c_int)), ++ ('rsa_priv_enc', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), POINTER(c_ubyte), POINTER(RSA), c_int)), ++ ('rsa_priv_dec', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), POINTER(c_ubyte), POINTER(RSA), c_int)), ++ ('rsa_mod_exp', CFUNCTYPE(c_int, POINTER(BIGNUM), POINTER(BIGNUM), POINTER(RSA))), ++ ('bn_mod_exp', CFUNCTYPE(c_int, POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BN_CTX), POINTER(BN_MONT_CTX))), ++ ('init', CFUNCTYPE(c_int, POINTER(RSA))), ++ ('finish', CFUNCTYPE(c_int, POINTER(RSA))), ++ ('flags', c_int), ++ ('app_data', STRING), ++ ('rsa_sign', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), c_uint, POINTER(c_ubyte), POINTER(c_uint), POINTER(RSA))), ++ ('rsa_verify', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), c_uint, POINTER(c_ubyte), c_uint, POINTER(RSA))), ++] ++assert sizeof(rsa_meth_st) == 52, sizeof(rsa_meth_st) ++assert alignment(rsa_meth_st) == 4, alignment(rsa_meth_st) ++RSA_METHOD = rsa_meth_st ++rsa_st._fields_ = [ ++ ('pad', c_int), ++ ('version', c_long), ++ ('meth', POINTER(RSA_METHOD)), ++ ('engine', POINTER(ENGINE)), ++ ('n', POINTER(BIGNUM)), ++ ('e', POINTER(BIGNUM)), ++ ('d', POINTER(BIGNUM)), ++ ('p', POINTER(BIGNUM)), ++ ('q', POINTER(BIGNUM)), ++ ('dmp1', POINTER(BIGNUM)), ++ ('dmq1', POINTER(BIGNUM)), ++ ('iqmp', POINTER(BIGNUM)), ++ ('ex_data', CRYPTO_EX_DATA), ++ ('references', c_int), ++ ('flags', c_int), ++ ('_method_mod_n', POINTER(BN_MONT_CTX)), ++ ('_method_mod_p', POINTER(BN_MONT_CTX)), ++ ('_method_mod_q', POINTER(BN_MONT_CTX)), ++ ('bignum_data', STRING), ++ ('blinding', POINTER(BN_BLINDING)), ++] ++assert sizeof(rsa_st) == 84, sizeof(rsa_st) ++assert alignment(rsa_st) == 4, alignment(rsa_st) ++openssl_fptr = CFUNCTYPE(None) ++class SHAstate_st(Structure): ++ pass ++SHAstate_st._fields_ = [ ++ ('h0', c_uint), ++ ('h1', c_uint), ++ ('h2', c_uint), ++ ('h3', c_uint), ++ ('h4', c_uint), ++ ('Nl', c_uint), ++ ('Nh', c_uint), ++ ('data', c_uint * 16), ++ ('num', c_int), ++] ++assert sizeof(SHAstate_st) == 96, sizeof(SHAstate_st) ++assert alignment(SHAstate_st) == 4, alignment(SHAstate_st) ++SHA_CTX = SHAstate_st ++class ssl_st(Structure): ++ pass ++ssl_crock_st = POINTER(ssl_st) ++class ssl_cipher_st(Structure): ++ pass ++ssl_cipher_st._fields_ = [ ++ ('valid', c_int), ++ ('name', STRING), ++ ('id', c_ulong), ++ ('algorithms', c_ulong), ++ ('algo_strength', c_ulong), ++ ('algorithm2', c_ulong), ++ ('strength_bits', c_int), ++ ('alg_bits', c_int), ++ ('mask', c_ulong), ++ ('mask_strength', c_ulong), ++] ++assert sizeof(ssl_cipher_st) == 40, sizeof(ssl_cipher_st) ++assert alignment(ssl_cipher_st) == 4, alignment(ssl_cipher_st) ++SSL_CIPHER = ssl_cipher_st ++SSL = ssl_st ++class ssl_ctx_st(Structure): ++ pass ++SSL_CTX = ssl_ctx_st ++class ssl_method_st(Structure): ++ pass ++class ssl3_enc_method(Structure): ++ pass ++ssl_method_st._fields_ = [ ++ ('version', c_int), ++ ('ssl_new', CFUNCTYPE(c_int, POINTER(SSL))), ++ ('ssl_clear', CFUNCTYPE(None, POINTER(SSL))), ++ ('ssl_free', CFUNCTYPE(None, POINTER(SSL))), ++ ('ssl_accept', CFUNCTYPE(c_int, POINTER(SSL))), ++ ('ssl_connect', CFUNCTYPE(c_int, POINTER(SSL))), ++ ('ssl_read', CFUNCTYPE(c_int, POINTER(SSL), c_void_p, c_int)), ++ ('ssl_peek', CFUNCTYPE(c_int, POINTER(SSL), c_void_p, c_int)), ++ ('ssl_write', CFUNCTYPE(c_int, POINTER(SSL), c_void_p, c_int)), ++ ('ssl_shutdown', CFUNCTYPE(c_int, POINTER(SSL))), ++ ('ssl_renegotiate', CFUNCTYPE(c_int, POINTER(SSL))), ++ ('ssl_renegotiate_check', CFUNCTYPE(c_int, POINTER(SSL))), ++ ('ssl_ctrl', CFUNCTYPE(c_long, POINTER(SSL), c_int, c_long, c_void_p)), ++ ('ssl_ctx_ctrl', CFUNCTYPE(c_long, POINTER(SSL_CTX), c_int, c_long, c_void_p)), ++ ('get_cipher_by_char', CFUNCTYPE(POINTER(SSL_CIPHER), POINTER(c_ubyte))), ++ ('put_cipher_by_char', CFUNCTYPE(c_int, POINTER(SSL_CIPHER), POINTER(c_ubyte))), ++ ('ssl_pending', CFUNCTYPE(c_int, POINTER(SSL))), ++ ('num_ciphers', CFUNCTYPE(c_int)), ++ ('get_cipher', CFUNCTYPE(POINTER(SSL_CIPHER), c_uint)), ++ ('get_ssl_method', CFUNCTYPE(POINTER(ssl_method_st), c_int)), ++ ('get_timeout', CFUNCTYPE(c_long)), ++ ('ssl3_enc', POINTER(ssl3_enc_method)), ++ ('ssl_version', CFUNCTYPE(c_int)), ++ ('ssl_callback_ctrl', CFUNCTYPE(c_long, POINTER(SSL), c_int, CFUNCTYPE(None))), ++ ('ssl_ctx_callback_ctrl', CFUNCTYPE(c_long, POINTER(SSL_CTX), c_int, CFUNCTYPE(None))), ++] ++assert sizeof(ssl_method_st) == 100, sizeof(ssl_method_st) ++assert alignment(ssl_method_st) == 4, alignment(ssl_method_st) ++ssl3_enc_method._fields_ = [ ++] ++SSL_METHOD = ssl_method_st ++class ssl_session_st(Structure): ++ pass ++class sess_cert_st(Structure): ++ pass ++ssl_session_st._fields_ = [ ++ ('ssl_version', c_int), ++ ('key_arg_length', c_uint), ++ ('key_arg', c_ubyte * 8), ++ ('master_key_length', c_int), ++ ('master_key', c_ubyte * 48), ++ ('session_id_length', c_uint), ++ ('session_id', c_ubyte * 32), ++ ('sid_ctx_length', c_uint), ++ ('sid_ctx', c_ubyte * 32), ++ ('not_resumable', c_int), ++ ('sess_cert', POINTER(sess_cert_st)), ++ ('peer', POINTER(X509)), ++ ('verify_result', c_long), ++ ('references', c_int), ++ ('timeout', c_long), ++ ('time', c_long), ++ ('compress_meth', c_int), ++ ('cipher', POINTER(SSL_CIPHER)), ++ ('cipher_id', c_ulong), ++ ('ciphers', POINTER(STACK)), ++ ('ex_data', CRYPTO_EX_DATA), ++ ('prev', POINTER(ssl_session_st)), ++ ('next', POINTER(ssl_session_st)), ++] ++assert sizeof(ssl_session_st) == 200, sizeof(ssl_session_st) ++assert alignment(ssl_session_st) == 4, alignment(ssl_session_st) ++sess_cert_st._fields_ = [ ++] ++SSL_SESSION = ssl_session_st ++GEN_SESSION_CB = CFUNCTYPE(c_int, POINTER(SSL), POINTER(c_ubyte), POINTER(c_uint)) ++class ssl_comp_st(Structure): ++ pass ++ssl_comp_st._fields_ = [ ++ ('id', c_int), ++ ('name', STRING), ++ ('method', POINTER(COMP_METHOD)), ++] ++assert sizeof(ssl_comp_st) == 12, sizeof(ssl_comp_st) ++assert alignment(ssl_comp_st) == 4, alignment(ssl_comp_st) ++SSL_COMP = ssl_comp_st ++class N10ssl_ctx_st4DOLLAR_18E(Structure): ++ pass ++N10ssl_ctx_st4DOLLAR_18E._fields_ = [ ++ ('sess_connect', c_int), ++ ('sess_connect_renegotiate', c_int), ++ ('sess_connect_good', c_int), ++ ('sess_accept', c_int), ++ ('sess_accept_renegotiate', c_int), ++ ('sess_accept_good', c_int), ++ ('sess_miss', c_int), ++ ('sess_timeout', c_int), ++ ('sess_cache_full', c_int), ++ ('sess_hit', c_int), ++ ('sess_cb_hit', c_int), ++] ++assert sizeof(N10ssl_ctx_st4DOLLAR_18E) == 44, sizeof(N10ssl_ctx_st4DOLLAR_18E) ++assert alignment(N10ssl_ctx_st4DOLLAR_18E) == 4, alignment(N10ssl_ctx_st4DOLLAR_18E) ++class cert_st(Structure): ++ pass ++ssl_ctx_st._fields_ = [ ++ ('method', POINTER(SSL_METHOD)), ++ ('cipher_list', POINTER(STACK)), ++ ('cipher_list_by_id', POINTER(STACK)), ++ ('cert_store', POINTER(x509_store_st)), ++ ('sessions', POINTER(lhash_st)), ++ ('session_cache_size', c_ulong), ++ ('session_cache_head', POINTER(ssl_session_st)), ++ ('session_cache_tail', POINTER(ssl_session_st)), ++ ('session_cache_mode', c_int), ++ ('session_timeout', c_long), ++ ('new_session_cb', CFUNCTYPE(c_int, POINTER(ssl_st), POINTER(SSL_SESSION))), ++ ('remove_session_cb', CFUNCTYPE(None, POINTER(ssl_ctx_st), POINTER(SSL_SESSION))), ++ ('get_session_cb', CFUNCTYPE(POINTER(SSL_SESSION), POINTER(ssl_st), POINTER(c_ubyte), c_int, POINTER(c_int))), ++ ('stats', N10ssl_ctx_st4DOLLAR_18E), ++ ('references', c_int), ++ ('app_verify_callback', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), c_void_p)), ++ ('app_verify_arg', c_void_p), ++ ('default_passwd_callback', POINTER(pem_password_cb)), ++ ('default_passwd_callback_userdata', c_void_p), ++ ('client_cert_cb', CFUNCTYPE(c_int, POINTER(SSL), POINTER(POINTER(X509)), POINTER(POINTER(EVP_PKEY)))), ++ ('ex_data', CRYPTO_EX_DATA), ++ ('rsa_md5', POINTER(EVP_MD)), ++ ('md5', POINTER(EVP_MD)), ++ ('sha1', POINTER(EVP_MD)), ++ ('extra_certs', POINTER(STACK)), ++ ('comp_methods', POINTER(STACK)), ++ ('info_callback', CFUNCTYPE(None, POINTER(SSL), c_int, c_int)), ++ ('client_CA', POINTER(STACK)), ++ ('options', c_ulong), ++ ('mode', c_ulong), ++ ('max_cert_list', c_long), ++ ('cert', POINTER(cert_st)), ++ ('read_ahead', c_int), ++ ('msg_callback', CFUNCTYPE(None, c_int, c_int, c_int, c_void_p, c_ulong, POINTER(SSL), c_void_p)), ++ ('msg_callback_arg', c_void_p), ++ ('verify_mode', c_int), ++ ('verify_depth', c_int), ++ ('sid_ctx_length', c_uint), ++ ('sid_ctx', c_ubyte * 32), ++ ('default_verify_callback', CFUNCTYPE(c_int, c_int, POINTER(X509_STORE_CTX))), ++ ('generate_session_id', GEN_SESSION_CB), ++ ('purpose', c_int), ++ ('trust', c_int), ++ ('quiet_shutdown', c_int), ++] ++assert sizeof(ssl_ctx_st) == 248, sizeof(ssl_ctx_st) ++assert alignment(ssl_ctx_st) == 4, alignment(ssl_ctx_st) ++cert_st._fields_ = [ ++] ++class ssl2_state_st(Structure): ++ pass ++class ssl3_state_st(Structure): ++ pass ++ssl_st._fields_ = [ ++ ('version', c_int), ++ ('type', c_int), ++ ('method', POINTER(SSL_METHOD)), ++ ('rbio', POINTER(BIO)), ++ ('wbio', POINTER(BIO)), ++ ('bbio', POINTER(BIO)), ++ ('rwstate', c_int), ++ ('in_handshake', c_int), ++ ('handshake_func', CFUNCTYPE(c_int)), ++ ('server', c_int), ++ ('new_session', c_int), ++ ('quiet_shutdown', c_int), ++ ('shutdown', c_int), ++ ('state', c_int), ++ ('rstate', c_int), ++ ('init_buf', POINTER(BUF_MEM)), ++ ('init_msg', c_void_p), ++ ('init_num', c_int), ++ ('init_off', c_int), ++ ('packet', POINTER(c_ubyte)), ++ ('packet_length', c_uint), ++ ('s2', POINTER(ssl2_state_st)), ++ ('s3', POINTER(ssl3_state_st)), ++ ('read_ahead', c_int), ++ ('msg_callback', CFUNCTYPE(None, c_int, c_int, c_int, c_void_p, c_ulong, POINTER(SSL), c_void_p)), ++ ('msg_callback_arg', c_void_p), ++ ('hit', c_int), ++ ('purpose', c_int), ++ ('trust', c_int), ++ ('cipher_list', POINTER(STACK)), ++ ('cipher_list_by_id', POINTER(STACK)), ++ ('enc_read_ctx', POINTER(EVP_CIPHER_CTX)), ++ ('read_hash', POINTER(EVP_MD)), ++ ('expand', POINTER(COMP_CTX)), ++ ('enc_write_ctx', POINTER(EVP_CIPHER_CTX)), ++ ('write_hash', POINTER(EVP_MD)), ++ ('compress', POINTER(COMP_CTX)), ++ ('cert', POINTER(cert_st)), ++ ('sid_ctx_length', c_uint), ++ ('sid_ctx', c_ubyte * 32), ++ ('session', POINTER(SSL_SESSION)), ++ ('generate_session_id', GEN_SESSION_CB), ++ ('verify_mode', c_int), ++ ('verify_depth', c_int), ++ ('verify_callback', CFUNCTYPE(c_int, c_int, POINTER(X509_STORE_CTX))), ++ ('info_callback', CFUNCTYPE(None, POINTER(SSL), c_int, c_int)), ++ ('error', c_int), ++ ('error_code', c_int), ++ ('ctx', POINTER(SSL_CTX)), ++ ('debug', c_int), ++ ('verify_result', c_long), ++ ('ex_data', CRYPTO_EX_DATA), ++ ('client_CA', POINTER(STACK)), ++ ('references', c_int), ++ ('options', c_ulong), ++ ('mode', c_ulong), ++ ('max_cert_list', c_long), ++ ('first_packet', c_int), ++ ('client_version', c_int), ++] ++assert sizeof(ssl_st) == 268, sizeof(ssl_st) ++assert alignment(ssl_st) == 4, alignment(ssl_st) ++class N13ssl2_state_st4DOLLAR_19E(Structure): ++ pass ++N13ssl2_state_st4DOLLAR_19E._fields_ = [ ++ ('conn_id_length', c_uint), ++ ('cert_type', c_uint), ++ ('cert_length', c_uint), ++ ('csl', c_uint), ++ ('clear', c_uint), ++ ('enc', c_uint), ++ ('ccl', c_ubyte * 32), ++ ('cipher_spec_length', c_uint), ++ ('session_id_length', c_uint), ++ ('clen', c_uint), ++ ('rlen', c_uint), ++] ++assert sizeof(N13ssl2_state_st4DOLLAR_19E) == 72, sizeof(N13ssl2_state_st4DOLLAR_19E) ++assert alignment(N13ssl2_state_st4DOLLAR_19E) == 4, alignment(N13ssl2_state_st4DOLLAR_19E) ++ssl2_state_st._fields_ = [ ++ ('three_byte_header', c_int), ++ ('clear_text', c_int), ++ ('escape', c_int), ++ ('ssl2_rollback', c_int), ++ ('wnum', c_uint), ++ ('wpend_tot', c_int), ++ ('wpend_buf', POINTER(c_ubyte)), ++ ('wpend_off', c_int), ++ ('wpend_len', c_int), ++ ('wpend_ret', c_int), ++ ('rbuf_left', c_int), ++ ('rbuf_offs', c_int), ++ ('rbuf', POINTER(c_ubyte)), ++ ('wbuf', POINTER(c_ubyte)), ++ ('write_ptr', POINTER(c_ubyte)), ++ ('padding', c_uint), ++ ('rlength', c_uint), ++ ('ract_data_length', c_int), ++ ('wlength', c_uint), ++ ('wact_data_length', c_int), ++ ('ract_data', POINTER(c_ubyte)), ++ ('wact_data', POINTER(c_ubyte)), ++ ('mac_data', POINTER(c_ubyte)), ++ ('read_key', POINTER(c_ubyte)), ++ ('write_key', POINTER(c_ubyte)), ++ ('challenge_length', c_uint), ++ ('challenge', c_ubyte * 32), ++ ('conn_id_length', c_uint), ++ ('conn_id', c_ubyte * 16), ++ ('key_material_length', c_uint), ++ ('key_material', c_ubyte * 48), ++ ('read_sequence', c_ulong), ++ ('write_sequence', c_ulong), ++ ('tmp', N13ssl2_state_st4DOLLAR_19E), ++] ++assert sizeof(ssl2_state_st) == 288, sizeof(ssl2_state_st) ++assert alignment(ssl2_state_st) == 4, alignment(ssl2_state_st) ++SSL2_STATE = ssl2_state_st ++class ssl3_record_st(Structure): ++ pass ++ssl3_record_st._fields_ = [ ++ ('type', c_int), ++ ('length', c_uint), ++ ('off', c_uint), ++ ('data', POINTER(c_ubyte)), ++ ('input', POINTER(c_ubyte)), ++ ('comp', POINTER(c_ubyte)), ++] ++assert sizeof(ssl3_record_st) == 24, sizeof(ssl3_record_st) ++assert alignment(ssl3_record_st) == 4, alignment(ssl3_record_st) ++SSL3_RECORD = ssl3_record_st ++class ssl3_buffer_st(Structure): ++ pass ++size_t = __darwin_size_t ++ssl3_buffer_st._fields_ = [ ++ ('buf', POINTER(c_ubyte)), ++ ('len', size_t), ++ ('offset', c_int), ++ ('left', c_int), ++] ++assert sizeof(ssl3_buffer_st) == 16, sizeof(ssl3_buffer_st) ++assert alignment(ssl3_buffer_st) == 4, alignment(ssl3_buffer_st) ++SSL3_BUFFER = ssl3_buffer_st ++class N13ssl3_state_st4DOLLAR_20E(Structure): ++ pass ++N13ssl3_state_st4DOLLAR_20E._fields_ = [ ++ ('cert_verify_md', c_ubyte * 72), ++ ('finish_md', c_ubyte * 72), ++ ('finish_md_len', c_int), ++ ('peer_finish_md', c_ubyte * 72), ++ ('peer_finish_md_len', c_int), ++ ('message_size', c_ulong), ++ ('message_type', c_int), ++ ('new_cipher', POINTER(SSL_CIPHER)), ++ ('dh', POINTER(DH)), ++ ('next_state', c_int), ++ ('reuse_message', c_int), ++ ('cert_req', c_int), ++ ('ctype_num', c_int), ++ ('ctype', c_char * 7), ++ ('ca_names', POINTER(STACK)), ++ ('use_rsa_tmp', c_int), ++ ('key_block_length', c_int), ++ ('key_block', POINTER(c_ubyte)), ++ ('new_sym_enc', POINTER(EVP_CIPHER)), ++ ('new_hash', POINTER(EVP_MD)), ++ ('new_compression', POINTER(SSL_COMP)), ++ ('cert_request', c_int), ++] ++assert sizeof(N13ssl3_state_st4DOLLAR_20E) == 296, sizeof(N13ssl3_state_st4DOLLAR_20E) ++assert alignment(N13ssl3_state_st4DOLLAR_20E) == 4, alignment(N13ssl3_state_st4DOLLAR_20E) ++ssl3_state_st._fields_ = [ ++ ('flags', c_long), ++ ('delay_buf_pop_ret', c_int), ++ ('read_sequence', c_ubyte * 8), ++ ('read_mac_secret', c_ubyte * 36), ++ ('write_sequence', c_ubyte * 8), ++ ('write_mac_secret', c_ubyte * 36), ++ ('server_random', c_ubyte * 32), ++ ('client_random', c_ubyte * 32), ++ ('need_empty_fragments', c_int), ++ ('empty_fragment_done', c_int), ++ ('rbuf', SSL3_BUFFER), ++ ('wbuf', SSL3_BUFFER), ++ ('rrec', SSL3_RECORD), ++ ('wrec', SSL3_RECORD), ++ ('alert_fragment', c_ubyte * 2), ++ ('alert_fragment_len', c_uint), ++ ('handshake_fragment', c_ubyte * 4), ++ ('handshake_fragment_len', c_uint), ++ ('wnum', c_uint), ++ ('wpend_tot', c_int), ++ ('wpend_type', c_int), ++ ('wpend_ret', c_int), ++ ('wpend_buf', POINTER(c_ubyte)), ++ ('finish_dgst1', EVP_MD_CTX), ++ ('finish_dgst2', EVP_MD_CTX), ++ ('change_cipher_spec', c_int), ++ ('warn_alert', c_int), ++ ('fatal_alert', c_int), ++ ('alert_dispatch', c_int), ++ ('send_alert', c_ubyte * 2), ++ ('renegotiate', c_int), ++ ('total_renegotiations', c_int), ++ ('num_renegotiations', c_int), ++ ('in_read_app_data', c_int), ++ ('tmp', N13ssl3_state_st4DOLLAR_20E), ++] ++assert sizeof(ssl3_state_st) == 648, sizeof(ssl3_state_st) ++assert alignment(ssl3_state_st) == 4, alignment(ssl3_state_st) ++SSL3_STATE = ssl3_state_st ++stack_st._fields_ = [ ++ ('num', c_int), ++ ('data', POINTER(STRING)), ++ ('sorted', c_int), ++ ('num_alloc', c_int), ++ ('comp', CFUNCTYPE(c_int, POINTER(STRING), POINTER(STRING))), ++] ++assert sizeof(stack_st) == 20, sizeof(stack_st) ++assert alignment(stack_st) == 4, alignment(stack_st) ++class ui_st(Structure): ++ pass ++ui_st._fields_ = [ ++] ++UI = ui_st ++class ui_method_st(Structure): ++ pass ++ui_method_st._fields_ = [ ++] ++UI_METHOD = ui_method_st ++class ui_string_st(Structure): ++ pass ++ui_string_st._fields_ = [ ++] ++UI_STRING = ui_string_st ++ ++# values for enumeration 'UI_string_types' ++UI_string_types = c_int # enum ++class X509_objects_st(Structure): ++ pass ++X509_objects_st._fields_ = [ ++ ('nid', c_int), ++ ('a2i', CFUNCTYPE(c_int)), ++ ('i2a', CFUNCTYPE(c_int)), ++] ++assert sizeof(X509_objects_st) == 12, sizeof(X509_objects_st) ++assert alignment(X509_objects_st) == 4, alignment(X509_objects_st) ++X509_OBJECTS = X509_objects_st ++X509_algor_st._fields_ = [ ++ ('algorithm', POINTER(ASN1_OBJECT)), ++ ('parameter', POINTER(ASN1_TYPE)), ++] ++assert sizeof(X509_algor_st) == 8, sizeof(X509_algor_st) ++assert alignment(X509_algor_st) == 4, alignment(X509_algor_st) ++class X509_val_st(Structure): ++ pass ++X509_val_st._fields_ = [ ++ ('notBefore', POINTER(ASN1_TIME)), ++ ('notAfter', POINTER(ASN1_TIME)), ++] ++assert sizeof(X509_val_st) == 8, sizeof(X509_val_st) ++assert alignment(X509_val_st) == 4, alignment(X509_val_st) ++X509_VAL = X509_val_st ++class X509_pubkey_st(Structure): ++ pass ++X509_pubkey_st._fields_ = [ ++ ('algor', POINTER(X509_ALGOR)), ++ ('public_key', POINTER(ASN1_BIT_STRING)), ++ ('pkey', POINTER(EVP_PKEY)), ++] ++assert sizeof(X509_pubkey_st) == 12, sizeof(X509_pubkey_st) ++assert alignment(X509_pubkey_st) == 4, alignment(X509_pubkey_st) ++X509_PUBKEY = X509_pubkey_st ++class X509_sig_st(Structure): ++ pass ++X509_sig_st._fields_ = [ ++ ('algor', POINTER(X509_ALGOR)), ++ ('digest', POINTER(ASN1_OCTET_STRING)), ++] ++assert sizeof(X509_sig_st) == 8, sizeof(X509_sig_st) ++assert alignment(X509_sig_st) == 4, alignment(X509_sig_st) ++X509_SIG = X509_sig_st ++class X509_name_entry_st(Structure): ++ pass ++X509_name_entry_st._fields_ = [ ++ ('object', POINTER(ASN1_OBJECT)), ++ ('value', POINTER(ASN1_STRING)), ++ ('set', c_int), ++ ('size', c_int), ++] ++assert sizeof(X509_name_entry_st) == 16, sizeof(X509_name_entry_st) ++assert alignment(X509_name_entry_st) == 4, alignment(X509_name_entry_st) ++X509_NAME_ENTRY = X509_name_entry_st ++X509_name_st._fields_ = [ ++ ('entries', POINTER(STACK)), ++ ('modified', c_int), ++ ('bytes', POINTER(BUF_MEM)), ++ ('hash', c_ulong), ++] ++assert sizeof(X509_name_st) == 16, sizeof(X509_name_st) ++assert alignment(X509_name_st) == 4, alignment(X509_name_st) ++class X509_extension_st(Structure): ++ pass ++X509_extension_st._fields_ = [ ++ ('object', POINTER(ASN1_OBJECT)), ++ ('critical', ASN1_BOOLEAN), ++ ('value', POINTER(ASN1_OCTET_STRING)), ++] ++assert sizeof(X509_extension_st) == 12, sizeof(X509_extension_st) ++assert alignment(X509_extension_st) == 4, alignment(X509_extension_st) ++X509_EXTENSION = X509_extension_st ++class x509_attributes_st(Structure): ++ pass ++class N18x509_attributes_st4DOLLAR_13E(Union): ++ pass ++N18x509_attributes_st4DOLLAR_13E._fields_ = [ ++ ('ptr', STRING), ++ ('set', POINTER(STACK)), ++ ('single', POINTER(ASN1_TYPE)), ++] ++assert sizeof(N18x509_attributes_st4DOLLAR_13E) == 4, sizeof(N18x509_attributes_st4DOLLAR_13E) ++assert alignment(N18x509_attributes_st4DOLLAR_13E) == 4, alignment(N18x509_attributes_st4DOLLAR_13E) ++x509_attributes_st._fields_ = [ ++ ('object', POINTER(ASN1_OBJECT)), ++ ('single', c_int), ++ ('value', N18x509_attributes_st4DOLLAR_13E), ++] ++assert sizeof(x509_attributes_st) == 12, sizeof(x509_attributes_st) ++assert alignment(x509_attributes_st) == 4, alignment(x509_attributes_st) ++X509_ATTRIBUTE = x509_attributes_st ++class X509_req_info_st(Structure): ++ pass ++X509_req_info_st._fields_ = [ ++ ('enc', ASN1_ENCODING), ++ ('version', POINTER(ASN1_INTEGER)), ++ ('subject', POINTER(X509_NAME)), ++ ('pubkey', POINTER(X509_PUBKEY)), ++ ('attributes', POINTER(STACK)), ++] ++assert sizeof(X509_req_info_st) == 28, sizeof(X509_req_info_st) ++assert alignment(X509_req_info_st) == 4, alignment(X509_req_info_st) ++X509_REQ_INFO = X509_req_info_st ++class X509_req_st(Structure): ++ pass ++X509_req_st._fields_ = [ ++ ('req_info', POINTER(X509_REQ_INFO)), ++ ('sig_alg', POINTER(X509_ALGOR)), ++ ('signature', POINTER(ASN1_BIT_STRING)), ++ ('references', c_int), ++] ++assert sizeof(X509_req_st) == 16, sizeof(X509_req_st) ++assert alignment(X509_req_st) == 4, alignment(X509_req_st) ++X509_REQ = X509_req_st ++class x509_cinf_st(Structure): ++ pass ++x509_cinf_st._fields_ = [ ++ ('version', POINTER(ASN1_INTEGER)), ++ ('serialNumber', POINTER(ASN1_INTEGER)), ++ ('signature', POINTER(X509_ALGOR)), ++ ('issuer', POINTER(X509_NAME)), ++ ('validity', POINTER(X509_VAL)), ++ ('subject', POINTER(X509_NAME)), ++ ('key', POINTER(X509_PUBKEY)), ++ ('issuerUID', POINTER(ASN1_BIT_STRING)), ++ ('subjectUID', POINTER(ASN1_BIT_STRING)), ++ ('extensions', POINTER(STACK)), ++] ++assert sizeof(x509_cinf_st) == 40, sizeof(x509_cinf_st) ++assert alignment(x509_cinf_st) == 4, alignment(x509_cinf_st) ++X509_CINF = x509_cinf_st ++class x509_cert_aux_st(Structure): ++ pass ++x509_cert_aux_st._fields_ = [ ++ ('trust', POINTER(STACK)), ++ ('reject', POINTER(STACK)), ++ ('alias', POINTER(ASN1_UTF8STRING)), ++ ('keyid', POINTER(ASN1_OCTET_STRING)), ++ ('other', POINTER(STACK)), ++] ++assert sizeof(x509_cert_aux_st) == 20, sizeof(x509_cert_aux_st) ++assert alignment(x509_cert_aux_st) == 4, alignment(x509_cert_aux_st) ++X509_CERT_AUX = x509_cert_aux_st ++class AUTHORITY_KEYID_st(Structure): ++ pass ++x509_st._fields_ = [ ++ ('cert_info', POINTER(X509_CINF)), ++ ('sig_alg', POINTER(X509_ALGOR)), ++ ('signature', POINTER(ASN1_BIT_STRING)), ++ ('valid', c_int), ++ ('references', c_int), ++ ('name', STRING), ++ ('ex_data', CRYPTO_EX_DATA), ++ ('ex_pathlen', c_long), ++ ('ex_flags', c_ulong), ++ ('ex_kusage', c_ulong), ++ ('ex_xkusage', c_ulong), ++ ('ex_nscert', c_ulong), ++ ('skid', POINTER(ASN1_OCTET_STRING)), ++ ('akid', POINTER(AUTHORITY_KEYID_st)), ++ ('sha1_hash', c_ubyte * 20), ++ ('aux', POINTER(X509_CERT_AUX)), ++] ++assert sizeof(x509_st) == 84, sizeof(x509_st) ++assert alignment(x509_st) == 4, alignment(x509_st) ++AUTHORITY_KEYID_st._fields_ = [ ++] ++class x509_trust_st(Structure): ++ pass ++x509_trust_st._fields_ = [ ++ ('trust', c_int), ++ ('flags', c_int), ++ ('check_trust', CFUNCTYPE(c_int, POINTER(x509_trust_st), POINTER(X509), c_int)), ++ ('name', STRING), ++ ('arg1', c_int), ++ ('arg2', c_void_p), ++] ++assert sizeof(x509_trust_st) == 24, sizeof(x509_trust_st) ++assert alignment(x509_trust_st) == 4, alignment(x509_trust_st) ++X509_TRUST = x509_trust_st ++class X509_revoked_st(Structure): ++ pass ++X509_revoked_st._fields_ = [ ++ ('serialNumber', POINTER(ASN1_INTEGER)), ++ ('revocationDate', POINTER(ASN1_TIME)), ++ ('extensions', POINTER(STACK)), ++ ('sequence', c_int), ++] ++assert sizeof(X509_revoked_st) == 16, sizeof(X509_revoked_st) ++assert alignment(X509_revoked_st) == 4, alignment(X509_revoked_st) ++X509_REVOKED = X509_revoked_st ++class X509_crl_info_st(Structure): ++ pass ++X509_crl_info_st._fields_ = [ ++ ('version', POINTER(ASN1_INTEGER)), ++ ('sig_alg', POINTER(X509_ALGOR)), ++ ('issuer', POINTER(X509_NAME)), ++ ('lastUpdate', POINTER(ASN1_TIME)), ++ ('nextUpdate', POINTER(ASN1_TIME)), ++ ('revoked', POINTER(STACK)), ++ ('extensions', POINTER(STACK)), ++ ('enc', ASN1_ENCODING), ++] ++assert sizeof(X509_crl_info_st) == 40, sizeof(X509_crl_info_st) ++assert alignment(X509_crl_info_st) == 4, alignment(X509_crl_info_st) ++X509_CRL_INFO = X509_crl_info_st ++X509_crl_st._fields_ = [ ++ ('crl', POINTER(X509_CRL_INFO)), ++ ('sig_alg', POINTER(X509_ALGOR)), ++ ('signature', POINTER(ASN1_BIT_STRING)), ++ ('references', c_int), ++] ++assert sizeof(X509_crl_st) == 16, sizeof(X509_crl_st) ++assert alignment(X509_crl_st) == 4, alignment(X509_crl_st) ++class private_key_st(Structure): ++ pass ++private_key_st._fields_ = [ ++ ('version', c_int), ++ ('enc_algor', POINTER(X509_ALGOR)), ++ ('enc_pkey', POINTER(ASN1_OCTET_STRING)), ++ ('dec_pkey', POINTER(EVP_PKEY)), ++ ('key_length', c_int), ++ ('key_data', STRING), ++ ('key_free', c_int), ++ ('cipher', EVP_CIPHER_INFO), ++ ('references', c_int), ++] ++assert sizeof(private_key_st) == 52, sizeof(private_key_st) ++assert alignment(private_key_st) == 4, alignment(private_key_st) ++X509_PKEY = private_key_st ++class X509_info_st(Structure): ++ pass ++X509_info_st._fields_ = [ ++ ('x509', POINTER(X509)), ++ ('crl', POINTER(X509_CRL)), ++ ('x_pkey', POINTER(X509_PKEY)), ++ ('enc_cipher', EVP_CIPHER_INFO), ++ ('enc_len', c_int), ++ ('enc_data', STRING), ++ ('references', c_int), ++] ++assert sizeof(X509_info_st) == 44, sizeof(X509_info_st) ++assert alignment(X509_info_st) == 4, alignment(X509_info_st) ++X509_INFO = X509_info_st ++class Netscape_spkac_st(Structure): ++ pass ++Netscape_spkac_st._fields_ = [ ++ ('pubkey', POINTER(X509_PUBKEY)), ++ ('challenge', POINTER(ASN1_IA5STRING)), ++] ++assert sizeof(Netscape_spkac_st) == 8, sizeof(Netscape_spkac_st) ++assert alignment(Netscape_spkac_st) == 4, alignment(Netscape_spkac_st) ++NETSCAPE_SPKAC = Netscape_spkac_st ++class Netscape_spki_st(Structure): ++ pass ++Netscape_spki_st._fields_ = [ ++ ('spkac', POINTER(NETSCAPE_SPKAC)), ++ ('sig_algor', POINTER(X509_ALGOR)), ++ ('signature', POINTER(ASN1_BIT_STRING)), ++] ++assert sizeof(Netscape_spki_st) == 12, sizeof(Netscape_spki_st) ++assert alignment(Netscape_spki_st) == 4, alignment(Netscape_spki_st) ++NETSCAPE_SPKI = Netscape_spki_st ++class Netscape_certificate_sequence(Structure): ++ pass ++Netscape_certificate_sequence._fields_ = [ ++ ('type', POINTER(ASN1_OBJECT)), ++ ('certs', POINTER(STACK)), ++] ++assert sizeof(Netscape_certificate_sequence) == 8, sizeof(Netscape_certificate_sequence) ++assert alignment(Netscape_certificate_sequence) == 4, alignment(Netscape_certificate_sequence) ++NETSCAPE_CERT_SEQUENCE = Netscape_certificate_sequence ++class PBEPARAM_st(Structure): ++ pass ++PBEPARAM_st._fields_ = [ ++ ('salt', POINTER(ASN1_OCTET_STRING)), ++ ('iter', POINTER(ASN1_INTEGER)), ++] ++assert sizeof(PBEPARAM_st) == 8, sizeof(PBEPARAM_st) ++assert alignment(PBEPARAM_st) == 4, alignment(PBEPARAM_st) ++PBEPARAM = PBEPARAM_st ++class PBE2PARAM_st(Structure): ++ pass ++PBE2PARAM_st._fields_ = [ ++ ('keyfunc', POINTER(X509_ALGOR)), ++ ('encryption', POINTER(X509_ALGOR)), ++] ++assert sizeof(PBE2PARAM_st) == 8, sizeof(PBE2PARAM_st) ++assert alignment(PBE2PARAM_st) == 4, alignment(PBE2PARAM_st) ++PBE2PARAM = PBE2PARAM_st ++class PBKDF2PARAM_st(Structure): ++ pass ++PBKDF2PARAM_st._fields_ = [ ++ ('salt', POINTER(ASN1_TYPE)), ++ ('iter', POINTER(ASN1_INTEGER)), ++ ('keylength', POINTER(ASN1_INTEGER)), ++ ('prf', POINTER(X509_ALGOR)), ++] ++assert sizeof(PBKDF2PARAM_st) == 16, sizeof(PBKDF2PARAM_st) ++assert alignment(PBKDF2PARAM_st) == 4, alignment(PBKDF2PARAM_st) ++PBKDF2PARAM = PBKDF2PARAM_st ++class pkcs8_priv_key_info_st(Structure): ++ pass ++pkcs8_priv_key_info_st._fields_ = [ ++ ('broken', c_int), ++ ('version', POINTER(ASN1_INTEGER)), ++ ('pkeyalg', POINTER(X509_ALGOR)), ++ ('pkey', POINTER(ASN1_TYPE)), ++ ('attributes', POINTER(STACK)), ++] ++assert sizeof(pkcs8_priv_key_info_st) == 20, sizeof(pkcs8_priv_key_info_st) ++assert alignment(pkcs8_priv_key_info_st) == 4, alignment(pkcs8_priv_key_info_st) ++PKCS8_PRIV_KEY_INFO = pkcs8_priv_key_info_st ++class x509_hash_dir_st(Structure): ++ pass ++x509_hash_dir_st._fields_ = [ ++ ('num_dirs', c_int), ++ ('dirs', POINTER(STRING)), ++ ('dirs_type', POINTER(c_int)), ++ ('num_dirs_alloced', c_int), ++] ++assert sizeof(x509_hash_dir_st) == 16, sizeof(x509_hash_dir_st) ++assert alignment(x509_hash_dir_st) == 4, alignment(x509_hash_dir_st) ++X509_HASH_DIR_CTX = x509_hash_dir_st ++class x509_file_st(Structure): ++ pass ++x509_file_st._fields_ = [ ++ ('num_paths', c_int), ++ ('num_alloced', c_int), ++ ('paths', POINTER(STRING)), ++ ('path_type', POINTER(c_int)), ++] ++assert sizeof(x509_file_st) == 16, sizeof(x509_file_st) ++assert alignment(x509_file_st) == 4, alignment(x509_file_st) ++X509_CERT_FILE_CTX = x509_file_st ++class x509_object_st(Structure): ++ pass ++class N14x509_object_st4DOLLAR_14E(Union): ++ pass ++N14x509_object_st4DOLLAR_14E._fields_ = [ ++ ('ptr', STRING), ++ ('x509', POINTER(X509)), ++ ('crl', POINTER(X509_CRL)), ++ ('pkey', POINTER(EVP_PKEY)), ++] ++assert sizeof(N14x509_object_st4DOLLAR_14E) == 4, sizeof(N14x509_object_st4DOLLAR_14E) ++assert alignment(N14x509_object_st4DOLLAR_14E) == 4, alignment(N14x509_object_st4DOLLAR_14E) ++x509_object_st._fields_ = [ ++ ('type', c_int), ++ ('data', N14x509_object_st4DOLLAR_14E), ++] ++assert sizeof(x509_object_st) == 8, sizeof(x509_object_st) ++assert alignment(x509_object_st) == 4, alignment(x509_object_st) ++X509_OBJECT = x509_object_st ++class x509_lookup_st(Structure): ++ pass ++X509_LOOKUP = x509_lookup_st ++class x509_lookup_method_st(Structure): ++ pass ++x509_lookup_method_st._fields_ = [ ++ ('name', STRING), ++ ('new_item', CFUNCTYPE(c_int, POINTER(X509_LOOKUP))), ++ ('free', CFUNCTYPE(None, POINTER(X509_LOOKUP))), ++ ('init', CFUNCTYPE(c_int, POINTER(X509_LOOKUP))), ++ ('shutdown', CFUNCTYPE(c_int, POINTER(X509_LOOKUP))), ++ ('ctrl', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, STRING, c_long, POINTER(STRING))), ++ ('get_by_subject', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, POINTER(X509_NAME), POINTER(X509_OBJECT))), ++ ('get_by_issuer_serial', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, POINTER(X509_NAME), POINTER(ASN1_INTEGER), POINTER(X509_OBJECT))), ++ ('get_by_fingerprint', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, POINTER(c_ubyte), c_int, POINTER(X509_OBJECT))), ++ ('get_by_alias', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, STRING, c_int, POINTER(X509_OBJECT))), ++] ++assert sizeof(x509_lookup_method_st) == 40, sizeof(x509_lookup_method_st) ++assert alignment(x509_lookup_method_st) == 4, alignment(x509_lookup_method_st) ++X509_LOOKUP_METHOD = x509_lookup_method_st ++x509_store_st._fields_ = [ ++ ('cache', c_int), ++ ('objs', POINTER(STACK)), ++ ('get_cert_methods', POINTER(STACK)), ++ ('flags', c_ulong), ++ ('purpose', c_int), ++ ('trust', c_int), ++ ('verify', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), ++ ('verify_cb', CFUNCTYPE(c_int, c_int, POINTER(X509_STORE_CTX))), ++ ('get_issuer', CFUNCTYPE(c_int, POINTER(POINTER(X509)), POINTER(X509_STORE_CTX), POINTER(X509))), ++ ('check_issued', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509), POINTER(X509))), ++ ('check_revocation', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), ++ ('get_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(POINTER(X509_CRL)), POINTER(X509))), ++ ('check_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509_CRL))), ++ ('cert_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509_CRL), POINTER(X509))), ++ ('cleanup', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), ++ ('ex_data', CRYPTO_EX_DATA), ++ ('references', c_int), ++ ('depth', c_int), ++] ++assert sizeof(x509_store_st) == 76, sizeof(x509_store_st) ++assert alignment(x509_store_st) == 4, alignment(x509_store_st) ++x509_lookup_st._fields_ = [ ++ ('init', c_int), ++ ('skip', c_int), ++ ('method', POINTER(X509_LOOKUP_METHOD)), ++ ('method_data', STRING), ++ ('store_ctx', POINTER(X509_STORE)), ++] ++assert sizeof(x509_lookup_st) == 20, sizeof(x509_lookup_st) ++assert alignment(x509_lookup_st) == 4, alignment(x509_lookup_st) ++time_t = __darwin_time_t ++x509_store_ctx_st._fields_ = [ ++ ('ctx', POINTER(X509_STORE)), ++ ('current_method', c_int), ++ ('cert', POINTER(X509)), ++ ('untrusted', POINTER(STACK)), ++ ('purpose', c_int), ++ ('trust', c_int), ++ ('check_time', time_t), ++ ('flags', c_ulong), ++ ('other_ctx', c_void_p), ++ ('verify', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), ++ ('verify_cb', CFUNCTYPE(c_int, c_int, POINTER(X509_STORE_CTX))), ++ ('get_issuer', CFUNCTYPE(c_int, POINTER(POINTER(X509)), POINTER(X509_STORE_CTX), POINTER(X509))), ++ ('check_issued', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509), POINTER(X509))), ++ ('check_revocation', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), ++ ('get_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(POINTER(X509_CRL)), POINTER(X509))), ++ ('check_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509_CRL))), ++ ('cert_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509_CRL), POINTER(X509))), ++ ('cleanup', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), ++ ('depth', c_int), ++ ('valid', c_int), ++ ('last_untrusted', c_int), ++ ('chain', POINTER(STACK)), ++ ('error_depth', c_int), ++ ('error', c_int), ++ ('current_cert', POINTER(X509)), ++ ('current_issuer', POINTER(X509)), ++ ('current_crl', POINTER(X509_CRL)), ++ ('ex_data', CRYPTO_EX_DATA), ++] ++assert sizeof(x509_store_ctx_st) == 116, sizeof(x509_store_ctx_st) ++assert alignment(x509_store_ctx_st) == 4, alignment(x509_store_ctx_st) ++va_list = __darwin_va_list ++__darwin_off_t = __int64_t ++fpos_t = __darwin_off_t ++class __sbuf(Structure): ++ pass ++__sbuf._fields_ = [ ++ ('_base', POINTER(c_ubyte)), ++ ('_size', c_int), ++] ++assert sizeof(__sbuf) == 8, sizeof(__sbuf) ++assert alignment(__sbuf) == 4, alignment(__sbuf) ++class __sFILEX(Structure): ++ pass ++__sFILEX._fields_ = [ ++] ++class __sFILE(Structure): ++ pass ++__sFILE._pack_ = 4 ++__sFILE._fields_ = [ ++ ('_p', POINTER(c_ubyte)), ++ ('_r', c_int), ++ ('_w', c_int), ++ ('_flags', c_short), ++ ('_file', c_short), ++ ('_bf', __sbuf), ++ ('_lbfsize', c_int), ++ ('_cookie', c_void_p), ++ ('_close', CFUNCTYPE(c_int, c_void_p)), ++ ('_read', CFUNCTYPE(c_int, c_void_p, STRING, c_int)), ++ ('_seek', CFUNCTYPE(fpos_t, c_void_p, c_longlong, c_int)), ++ ('_write', CFUNCTYPE(c_int, c_void_p, STRING, c_int)), ++ ('_ub', __sbuf), ++ ('_extra', POINTER(__sFILEX)), ++ ('_ur', c_int), ++ ('_ubuf', c_ubyte * 3), ++ ('_nbuf', c_ubyte * 1), ++ ('_lb', __sbuf), ++ ('_blksize', c_int), ++ ('_offset', fpos_t), ++] ++assert sizeof(__sFILE) == 88, sizeof(__sFILE) ++assert alignment(__sFILE) == 4, alignment(__sFILE) ++FILE = __sFILE ++ct_rune_t = __darwin_ct_rune_t ++rune_t = __darwin_rune_t ++class div_t(Structure): ++ pass ++div_t._fields_ = [ ++ ('quot', c_int), ++ ('rem', c_int), ++] ++assert sizeof(div_t) == 8, sizeof(div_t) ++assert alignment(div_t) == 4, alignment(div_t) ++class ldiv_t(Structure): ++ pass ++ldiv_t._fields_ = [ ++ ('quot', c_long), ++ ('rem', c_long), ++] ++assert sizeof(ldiv_t) == 8, sizeof(ldiv_t) ++assert alignment(ldiv_t) == 4, alignment(ldiv_t) ++class lldiv_t(Structure): ++ pass ++lldiv_t._pack_ = 4 ++lldiv_t._fields_ = [ ++ ('quot', c_longlong), ++ ('rem', c_longlong), ++] ++assert sizeof(lldiv_t) == 16, sizeof(lldiv_t) ++assert alignment(lldiv_t) == 4, alignment(lldiv_t) ++__darwin_dev_t = __int32_t ++dev_t = __darwin_dev_t ++__darwin_mode_t = __uint16_t ++mode_t = __darwin_mode_t ++class mcontext(Structure): ++ pass ++mcontext._fields_ = [ ++] ++class mcontext64(Structure): ++ pass ++mcontext64._fields_ = [ ++] ++class __darwin_pthread_handler_rec(Structure): ++ pass ++__darwin_pthread_handler_rec._fields_ = [ ++ ('__routine', CFUNCTYPE(None, c_void_p)), ++ ('__arg', c_void_p), ++ ('__next', POINTER(__darwin_pthread_handler_rec)), ++] ++assert sizeof(__darwin_pthread_handler_rec) == 12, sizeof(__darwin_pthread_handler_rec) ++assert alignment(__darwin_pthread_handler_rec) == 4, alignment(__darwin_pthread_handler_rec) ++class _opaque_pthread_attr_t(Structure): ++ pass ++_opaque_pthread_attr_t._fields_ = [ ++ ('__sig', c_long), ++ ('__opaque', c_char * 36), ++] ++assert sizeof(_opaque_pthread_attr_t) == 40, sizeof(_opaque_pthread_attr_t) ++assert alignment(_opaque_pthread_attr_t) == 4, alignment(_opaque_pthread_attr_t) ++class _opaque_pthread_cond_t(Structure): ++ pass ++_opaque_pthread_cond_t._fields_ = [ ++ ('__sig', c_long), ++ ('__opaque', c_char * 24), ++] ++assert sizeof(_opaque_pthread_cond_t) == 28, sizeof(_opaque_pthread_cond_t) ++assert alignment(_opaque_pthread_cond_t) == 4, alignment(_opaque_pthread_cond_t) ++class _opaque_pthread_condattr_t(Structure): ++ pass ++_opaque_pthread_condattr_t._fields_ = [ ++ ('__sig', c_long), ++ ('__opaque', c_char * 4), ++] ++assert sizeof(_opaque_pthread_condattr_t) == 8, sizeof(_opaque_pthread_condattr_t) ++assert alignment(_opaque_pthread_condattr_t) == 4, alignment(_opaque_pthread_condattr_t) ++class _opaque_pthread_mutex_t(Structure): ++ pass ++_opaque_pthread_mutex_t._fields_ = [ ++ ('__sig', c_long), ++ ('__opaque', c_char * 40), ++] ++assert sizeof(_opaque_pthread_mutex_t) == 44, sizeof(_opaque_pthread_mutex_t) ++assert alignment(_opaque_pthread_mutex_t) == 4, alignment(_opaque_pthread_mutex_t) ++class _opaque_pthread_mutexattr_t(Structure): ++ pass ++_opaque_pthread_mutexattr_t._fields_ = [ ++ ('__sig', c_long), ++ ('__opaque', c_char * 8), ++] ++assert sizeof(_opaque_pthread_mutexattr_t) == 12, sizeof(_opaque_pthread_mutexattr_t) ++assert alignment(_opaque_pthread_mutexattr_t) == 4, alignment(_opaque_pthread_mutexattr_t) ++class _opaque_pthread_once_t(Structure): ++ pass ++_opaque_pthread_once_t._fields_ = [ ++ ('__sig', c_long), ++ ('__opaque', c_char * 4), ++] ++assert sizeof(_opaque_pthread_once_t) == 8, sizeof(_opaque_pthread_once_t) ++assert alignment(_opaque_pthread_once_t) == 4, alignment(_opaque_pthread_once_t) ++class _opaque_pthread_rwlock_t(Structure): ++ pass ++_opaque_pthread_rwlock_t._fields_ = [ ++ ('__sig', c_long), ++ ('__opaque', c_char * 124), ++] ++assert sizeof(_opaque_pthread_rwlock_t) == 128, sizeof(_opaque_pthread_rwlock_t) ++assert alignment(_opaque_pthread_rwlock_t) == 4, alignment(_opaque_pthread_rwlock_t) ++class _opaque_pthread_rwlockattr_t(Structure): ++ pass ++_opaque_pthread_rwlockattr_t._fields_ = [ ++ ('__sig', c_long), ++ ('__opaque', c_char * 12), ++] ++assert sizeof(_opaque_pthread_rwlockattr_t) == 16, sizeof(_opaque_pthread_rwlockattr_t) ++assert alignment(_opaque_pthread_rwlockattr_t) == 4, alignment(_opaque_pthread_rwlockattr_t) ++class _opaque_pthread_t(Structure): ++ pass ++_opaque_pthread_t._fields_ = [ ++ ('__sig', c_long), ++ ('__cleanup_stack', POINTER(__darwin_pthread_handler_rec)), ++ ('__opaque', c_char * 596), ++] ++assert sizeof(_opaque_pthread_t) == 604, sizeof(_opaque_pthread_t) ++assert alignment(_opaque_pthread_t) == 4, alignment(_opaque_pthread_t) ++__darwin_blkcnt_t = __int64_t ++__darwin_blksize_t = __int32_t ++__darwin_fsblkcnt_t = c_uint ++__darwin_fsfilcnt_t = c_uint ++__darwin_gid_t = __uint32_t ++__darwin_id_t = __uint32_t ++__darwin_ino_t = __uint32_t ++__darwin_mach_port_name_t = __darwin_natural_t ++__darwin_mach_port_t = __darwin_mach_port_name_t ++__darwin_mcontext_t = POINTER(mcontext) ++__darwin_mcontext64_t = POINTER(mcontext64) ++__darwin_pid_t = __int32_t ++__darwin_pthread_attr_t = _opaque_pthread_attr_t ++__darwin_pthread_cond_t = _opaque_pthread_cond_t ++__darwin_pthread_condattr_t = _opaque_pthread_condattr_t ++__darwin_pthread_key_t = c_ulong ++__darwin_pthread_mutex_t = _opaque_pthread_mutex_t ++__darwin_pthread_mutexattr_t = _opaque_pthread_mutexattr_t ++__darwin_pthread_once_t = _opaque_pthread_once_t ++__darwin_pthread_rwlock_t = _opaque_pthread_rwlock_t ++__darwin_pthread_rwlockattr_t = _opaque_pthread_rwlockattr_t ++__darwin_pthread_t = POINTER(_opaque_pthread_t) ++__darwin_sigset_t = __uint32_t ++__darwin_suseconds_t = __int32_t ++__darwin_uid_t = __uint32_t ++__darwin_useconds_t = __uint32_t ++__darwin_uuid_t = c_ubyte * 16 ++class sigaltstack(Structure): ++ pass ++sigaltstack._fields_ = [ ++ ('ss_sp', c_void_p), ++ ('ss_size', __darwin_size_t), ++ ('ss_flags', c_int), ++] ++assert sizeof(sigaltstack) == 12, sizeof(sigaltstack) ++assert alignment(sigaltstack) == 4, alignment(sigaltstack) ++__darwin_stack_t = sigaltstack ++class ucontext(Structure): ++ pass ++ucontext._fields_ = [ ++ ('uc_onstack', c_int), ++ ('uc_sigmask', __darwin_sigset_t), ++ ('uc_stack', __darwin_stack_t), ++ ('uc_link', POINTER(ucontext)), ++ ('uc_mcsize', __darwin_size_t), ++ ('uc_mcontext', __darwin_mcontext_t), ++] ++assert sizeof(ucontext) == 32, sizeof(ucontext) ++assert alignment(ucontext) == 4, alignment(ucontext) ++__darwin_ucontext_t = ucontext ++class ucontext64(Structure): ++ pass ++ucontext64._fields_ = [ ++ ('uc_onstack', c_int), ++ ('uc_sigmask', __darwin_sigset_t), ++ ('uc_stack', __darwin_stack_t), ++ ('uc_link', POINTER(ucontext64)), ++ ('uc_mcsize', __darwin_size_t), ++ ('uc_mcontext64', __darwin_mcontext64_t), ++] ++assert sizeof(ucontext64) == 32, sizeof(ucontext64) ++assert alignment(ucontext64) == 4, alignment(ucontext64) ++__darwin_ucontext64_t = ucontext64 ++class timeval(Structure): ++ pass ++timeval._fields_ = [ ++ ('tv_sec', __darwin_time_t), ++ ('tv_usec', __darwin_suseconds_t), ++] ++assert sizeof(timeval) == 8, sizeof(timeval) ++assert alignment(timeval) == 4, alignment(timeval) ++rlim_t = __int64_t ++class rusage(Structure): ++ pass ++rusage._fields_ = [ ++ ('ru_utime', timeval), ++ ('ru_stime', timeval), ++ ('ru_maxrss', c_long), ++ ('ru_ixrss', c_long), ++ ('ru_idrss', c_long), ++ ('ru_isrss', c_long), ++ ('ru_minflt', c_long), ++ ('ru_majflt', c_long), ++ ('ru_nswap', c_long), ++ ('ru_inblock', c_long), ++ ('ru_oublock', c_long), ++ ('ru_msgsnd', c_long), ++ ('ru_msgrcv', c_long), ++ ('ru_nsignals', c_long), ++ ('ru_nvcsw', c_long), ++ ('ru_nivcsw', c_long), ++] ++assert sizeof(rusage) == 72, sizeof(rusage) ++assert alignment(rusage) == 4, alignment(rusage) ++class rlimit(Structure): ++ pass ++rlimit._pack_ = 4 ++rlimit._fields_ = [ ++ ('rlim_cur', rlim_t), ++ ('rlim_max', rlim_t), ++] ++assert sizeof(rlimit) == 16, sizeof(rlimit) ++assert alignment(rlimit) == 4, alignment(rlimit) ++mcontext_t = __darwin_mcontext_t ++mcontext64_t = __darwin_mcontext64_t ++pthread_attr_t = __darwin_pthread_attr_t ++sigset_t = __darwin_sigset_t ++ucontext_t = __darwin_ucontext_t ++ucontext64_t = __darwin_ucontext64_t ++uid_t = __darwin_uid_t ++class sigval(Union): ++ pass ++sigval._fields_ = [ ++ ('sival_int', c_int), ++ ('sival_ptr', c_void_p), ++] ++assert sizeof(sigval) == 4, sizeof(sigval) ++assert alignment(sigval) == 4, alignment(sigval) ++class sigevent(Structure): ++ pass ++sigevent._fields_ = [ ++ ('sigev_notify', c_int), ++ ('sigev_signo', c_int), ++ ('sigev_value', sigval), ++ ('sigev_notify_function', CFUNCTYPE(None, sigval)), ++ ('sigev_notify_attributes', POINTER(pthread_attr_t)), ++] ++assert sizeof(sigevent) == 20, sizeof(sigevent) ++assert alignment(sigevent) == 4, alignment(sigevent) ++class __siginfo(Structure): ++ pass ++pid_t = __darwin_pid_t ++__siginfo._fields_ = [ ++ ('si_signo', c_int), ++ ('si_errno', c_int), ++ ('si_code', c_int), ++ ('si_pid', pid_t), ++ ('si_uid', uid_t), ++ ('si_status', c_int), ++ ('si_addr', c_void_p), ++ ('si_value', sigval), ++ ('si_band', c_long), ++ ('pad', c_ulong * 7), ++] ++assert sizeof(__siginfo) == 64, sizeof(__siginfo) ++assert alignment(__siginfo) == 4, alignment(__siginfo) ++siginfo_t = __siginfo ++class __sigaction_u(Union): ++ pass ++__sigaction_u._fields_ = [ ++ ('__sa_handler', CFUNCTYPE(None, c_int)), ++ ('__sa_sigaction', CFUNCTYPE(None, c_int, POINTER(__siginfo), c_void_p)), ++] ++assert sizeof(__sigaction_u) == 4, sizeof(__sigaction_u) ++assert alignment(__sigaction_u) == 4, alignment(__sigaction_u) ++class __sigaction(Structure): ++ pass ++__sigaction._fields_ = [ ++ ('__sigaction_u', __sigaction_u), ++ ('sa_tramp', CFUNCTYPE(None, c_void_p, c_int, c_int, POINTER(siginfo_t), c_void_p)), ++ ('sa_mask', sigset_t), ++ ('sa_flags', c_int), ++] ++assert sizeof(__sigaction) == 16, sizeof(__sigaction) ++assert alignment(__sigaction) == 4, alignment(__sigaction) ++class sigaction(Structure): ++ pass ++sigaction._fields_ = [ ++ ('__sigaction_u', __sigaction_u), ++ ('sa_mask', sigset_t), ++ ('sa_flags', c_int), ++] ++assert sizeof(sigaction) == 12, sizeof(sigaction) ++assert alignment(sigaction) == 4, alignment(sigaction) ++sig_t = CFUNCTYPE(None, c_int) ++stack_t = __darwin_stack_t ++class sigvec(Structure): ++ pass ++sigvec._fields_ = [ ++ ('sv_handler', CFUNCTYPE(None, c_int)), ++ ('sv_mask', c_int), ++ ('sv_flags', c_int), ++] ++assert sizeof(sigvec) == 12, sizeof(sigvec) ++assert alignment(sigvec) == 4, alignment(sigvec) ++class sigstack(Structure): ++ pass ++sigstack._fields_ = [ ++ ('ss_sp', STRING), ++ ('ss_onstack', c_int), ++] ++assert sizeof(sigstack) == 8, sizeof(sigstack) ++assert alignment(sigstack) == 4, alignment(sigstack) ++u_char = c_ubyte ++u_short = c_ushort ++u_int = c_uint ++u_long = c_ulong ++ushort = c_ushort ++uint = c_uint ++u_quad_t = u_int64_t ++quad_t = int64_t ++qaddr_t = POINTER(quad_t) ++caddr_t = STRING ++daddr_t = int32_t ++fixpt_t = u_int32_t ++blkcnt_t = __darwin_blkcnt_t ++blksize_t = __darwin_blksize_t ++gid_t = __darwin_gid_t ++in_addr_t = __uint32_t ++in_port_t = __uint16_t ++ino_t = __darwin_ino_t ++key_t = __int32_t ++nlink_t = __uint16_t ++off_t = __darwin_off_t ++segsz_t = int32_t ++swblk_t = int32_t ++clock_t = __darwin_clock_t ++ssize_t = __darwin_ssize_t ++useconds_t = __darwin_useconds_t ++suseconds_t = __darwin_suseconds_t ++fd_mask = __int32_t ++class fd_set(Structure): ++ pass ++fd_set._fields_ = [ ++ ('fds_bits', __int32_t * 32), ++] ++assert sizeof(fd_set) == 128, sizeof(fd_set) ++assert alignment(fd_set) == 4, alignment(fd_set) ++pthread_cond_t = __darwin_pthread_cond_t ++pthread_condattr_t = __darwin_pthread_condattr_t ++pthread_mutex_t = __darwin_pthread_mutex_t ++pthread_mutexattr_t = __darwin_pthread_mutexattr_t ++pthread_once_t = __darwin_pthread_once_t ++pthread_rwlock_t = __darwin_pthread_rwlock_t ++pthread_rwlockattr_t = __darwin_pthread_rwlockattr_t ++pthread_t = __darwin_pthread_t ++pthread_key_t = __darwin_pthread_key_t ++fsblkcnt_t = __darwin_fsblkcnt_t ++fsfilcnt_t = __darwin_fsfilcnt_t ++ ++# values for enumeration 'idtype_t' ++idtype_t = c_int # enum ++id_t = __darwin_id_t ++class wait(Union): ++ pass ++class N4wait3DOLLAR_3E(Structure): ++ pass ++N4wait3DOLLAR_3E._fields_ = [ ++ ('w_Termsig', c_uint, 7), ++ ('w_Coredump', c_uint, 1), ++ ('w_Retcode', c_uint, 8), ++ ('w_Filler', c_uint, 16), ++] ++assert sizeof(N4wait3DOLLAR_3E) == 4, sizeof(N4wait3DOLLAR_3E) ++assert alignment(N4wait3DOLLAR_3E) == 4, alignment(N4wait3DOLLAR_3E) ++class N4wait3DOLLAR_4E(Structure): ++ pass ++N4wait3DOLLAR_4E._fields_ = [ ++ ('w_Stopval', c_uint, 8), ++ ('w_Stopsig', c_uint, 8), ++ ('w_Filler', c_uint, 16), ++] ++assert sizeof(N4wait3DOLLAR_4E) == 4, sizeof(N4wait3DOLLAR_4E) ++assert alignment(N4wait3DOLLAR_4E) == 4, alignment(N4wait3DOLLAR_4E) ++wait._fields_ = [ ++ ('w_status', c_int), ++ ('w_T', N4wait3DOLLAR_3E), ++ ('w_S', N4wait3DOLLAR_4E), ++] ++assert sizeof(wait) == 4, sizeof(wait) ++assert alignment(wait) == 4, alignment(wait) ++class timespec(Structure): ++ pass ++timespec._fields_ = [ ++ ('tv_sec', time_t), ++ ('tv_nsec', c_long), ++] ++assert sizeof(timespec) == 8, sizeof(timespec) ++assert alignment(timespec) == 4, alignment(timespec) ++class tm(Structure): ++ pass ++tm._fields_ = [ ++ ('tm_sec', c_int), ++ ('tm_min', c_int), ++ ('tm_hour', c_int), ++ ('tm_mday', c_int), ++ ('tm_mon', c_int), ++ ('tm_year', c_int), ++ ('tm_wday', c_int), ++ ('tm_yday', c_int), ++ ('tm_isdst', c_int), ++ ('tm_gmtoff', c_long), ++ ('tm_zone', STRING), ++] ++assert sizeof(tm) == 44, sizeof(tm) ++assert alignment(tm) == 4, alignment(tm) ++__gnuc_va_list = STRING ++ptrdiff_t = c_int ++int8_t = c_byte ++int16_t = c_short ++uint8_t = c_ubyte ++uint16_t = c_ushort ++uint32_t = c_uint ++uint64_t = c_ulonglong ++int_least8_t = int8_t ++int_least16_t = int16_t ++int_least32_t = int32_t ++int_least64_t = int64_t ++uint_least8_t = uint8_t ++uint_least16_t = uint16_t ++uint_least32_t = uint32_t ++uint_least64_t = uint64_t ++int_fast8_t = int8_t ++int_fast16_t = int16_t ++int_fast32_t = int32_t ++int_fast64_t = int64_t ++uint_fast8_t = uint8_t ++uint_fast16_t = uint16_t ++uint_fast32_t = uint32_t ++uint_fast64_t = uint64_t ++intptr_t = c_long ++uintptr_t = c_ulong ++intmax_t = c_longlong ++uintmax_t = c_ulonglong ++__all__ = ['ENGINE', 'pkcs7_enc_content_st', '__int16_t', ++ 'X509_REVOKED', 'SSL_CTX', 'UIT_BOOLEAN', ++ '__darwin_time_t', 'ucontext64_t', 'int_fast32_t', ++ 'pem_ctx_st', 'uint8_t', 'fpos_t', 'X509', 'COMP_CTX', ++ 'tm', 'N10pem_ctx_st4DOLLAR_17E', 'swblk_t', ++ 'ASN1_TEMPLATE', '__darwin_pthread_t', 'fixpt_t', ++ 'BIO_METHOD', 'ASN1_PRINTABLESTRING', 'EVP_ENCODE_CTX', ++ 'dh_method', 'bio_f_buffer_ctx_struct', 'in_port_t', ++ 'X509_SIG', '__darwin_ssize_t', '__darwin_sigset_t', ++ 'wait', 'uint_fast16_t', 'N12asn1_type_st4DOLLAR_11E', ++ 'uint_least8_t', 'pthread_rwlock_t', 'ASN1_IA5STRING', ++ 'fsfilcnt_t', 'ucontext', '__uint64_t', 'timespec', ++ 'x509_cinf_st', 'COMP_METHOD', 'MD5_CTX', 'buf_mem_st', ++ 'ASN1_ENCODING_st', 'PBEPARAM', 'X509_NAME_ENTRY', ++ '__darwin_va_list', 'ucontext_t', 'lhash_st', ++ 'N4wait3DOLLAR_4E', '__darwin_uuid_t', ++ '_ossl_old_des_ks_struct', 'id_t', 'ASN1_BIT_STRING', ++ 'va_list', '__darwin_wchar_t', 'pthread_key_t', ++ 'pkcs7_signer_info_st', 'ASN1_METHOD', 'DSA_SIG', 'DSA', ++ 'UIT_NONE', 'pthread_t', '__darwin_useconds_t', ++ 'uint_fast8_t', 'UI_STRING', 'DES_cblock', ++ '__darwin_mcontext64_t', 'rlim_t', 'PEM_Encode_Seal_st', ++ 'SHAstate_st', 'u_quad_t', 'openssl_fptr', ++ '_opaque_pthread_rwlockattr_t', ++ 'N18x509_attributes_st4DOLLAR_13E', ++ '__darwin_pthread_rwlock_t', 'daddr_t', 'ui_string_st', ++ 'x509_file_st', 'X509_req_info_st', 'int_least64_t', ++ 'evp_Encode_Ctx_st', 'X509_OBJECTS', 'CRYPTO_EX_DATA', ++ '__int8_t', 'AUTHORITY_KEYID_st', '_opaque_pthread_attr_t', ++ 'sigstack', 'EVP_CIPHER_CTX', 'X509_extension_st', 'pid_t', ++ 'RSA_METHOD', 'PEM_USER', 'pem_recip_st', 'env_md_ctx_st', ++ 'rc5_key_st', 'ui_st', 'X509_PUBKEY', 'u_int8_t', ++ 'ASN1_ITEM_st', 'pkcs7_recip_info_st', 'ssl2_state_st', ++ 'off_t', 'N10ssl_ctx_st4DOLLAR_18E', 'crypto_ex_data_st', ++ 'ui_method_st', '__darwin_pthread_rwlockattr_t', ++ 'CRYPTO_EX_dup', '__darwin_ino_t', '__sFILE', ++ 'OSUnknownByteOrder', 'BN_MONT_CTX', 'ASN1_NULL', 'time_t', ++ 'CRYPTO_EX_new', 'asn1_type_st', 'CRYPTO_EX_DATA_FUNCS', ++ 'user_time_t', 'BIGNUM', 'pthread_rwlockattr_t', ++ 'ASN1_VALUE_st', 'DH_METHOD', '__darwin_off_t', ++ '_opaque_pthread_t', 'bn_blinding_st', 'RSA', 'ssize_t', ++ 'mcontext64_t', 'user_long_t', 'fsblkcnt_t', 'cert_st', ++ '__darwin_pthread_condattr_t', 'X509_PKEY', ++ '__darwin_id_t', '__darwin_nl_item', 'SSL2_STATE', 'FILE', ++ 'pthread_mutexattr_t', 'size_t', ++ '_ossl_old_des_key_schedule', 'pkcs7_issuer_and_serial_st', ++ 'sigval', 'CRYPTO_MEM_LEAK_CB', 'X509_NAME', 'blkcnt_t', ++ 'uint_least16_t', '__darwin_dev_t', 'evp_cipher_info_st', ++ 'BN_BLINDING', 'ssl3_state_st', 'uint_least64_t', ++ 'user_addr_t', 'DES_key_schedule', 'RIPEMD160_CTX', ++ 'u_char', 'X509_algor_st', 'uid_t', 'sess_cert_st', ++ 'u_int64_t', 'u_int16_t', 'sigset_t', '__darwin_ptrdiff_t', ++ 'ASN1_CTX', 'STACK', '__int32_t', 'UI_METHOD', ++ 'NETSCAPE_SPKI', 'UIT_PROMPT', 'st_CRYPTO_EX_DATA_IMPL', ++ 'cast_key_st', 'X509_HASH_DIR_CTX', 'sigevent', ++ 'user_ssize_t', 'clock_t', 'aes_key_st', ++ '__darwin_socklen_t', '__darwin_intptr_t', 'int_fast64_t', ++ 'asn1_string_table_st', 'uint_fast32_t', ++ 'ASN1_VISIBLESTRING', 'DSA_SIG_st', 'obj_name_st', ++ 'X509_LOOKUP_METHOD', 'u_int32_t', 'EVP_CIPHER_INFO', ++ '__gnuc_va_list', 'AES_KEY', 'PKCS7_ISSUER_AND_SERIAL', ++ 'BN_CTX', '__darwin_blkcnt_t', 'key_t', 'SHA_CTX', ++ 'pkcs7_signed_st', 'SSL', 'N10pem_ctx_st4DOLLAR_16E', ++ 'pthread_attr_t', 'EVP_MD', 'uint', 'ASN1_BOOLEAN', ++ 'ino_t', '__darwin_clock_t', 'ASN1_OCTET_STRING', ++ 'asn1_ctx_st', 'BIO_F_BUFFER_CTX', 'bn_mont_ctx_st', ++ 'X509_REQ_INFO', 'PEM_CTX', 'sigvec', ++ '__darwin_pthread_mutexattr_t', 'x509_attributes_st', ++ 'stack_t', '__darwin_mode_t', '__mbstate_t', ++ 'asn1_object_st', 'ASN1_ENCODING', '__uint8_t', ++ 'LHASH_NODE', 'PKCS7_SIGNER_INFO', 'asn1_method_st', ++ 'stack_st', 'bio_info_cb', 'div_t', 'UIT_VERIFY', ++ 'PBEPARAM_st', 'N4wait3DOLLAR_3E', 'quad_t', '__siginfo', ++ '__darwin_mbstate_t', 'rsa_st', 'ASN1_UNIVERSALSTRING', ++ 'uint64_t', 'ssl_comp_st', 'X509_OBJECT', 'pthread_cond_t', ++ 'DH', '__darwin_wctype_t', 'PKCS7_ENVELOPE', 'ASN1_TLC_st', ++ 'sig_atomic_t', 'BIO', 'nlink_t', 'BUF_MEM', 'SSL3_RECORD', ++ 'bio_method_st', 'timeval', 'UI_string_types', 'BIO_dummy', ++ 'ssl_ctx_st', 'NETSCAPE_CERT_SEQUENCE', ++ 'BIT_STRING_BITNAME_st', '__darwin_pthread_attr_t', ++ 'int8_t', '__darwin_wint_t', 'OBJ_NAME', ++ 'PKCS8_PRIV_KEY_INFO', 'PBE2PARAM_st', ++ 'LHASH_DOALL_FN_TYPE', 'x509_st', 'X509_VAL', 'dev_t', ++ 'ASN1_TEMPLATE_st', 'MD5state_st', '__uint16_t', ++ 'LHASH_DOALL_ARG_FN_TYPE', 'mdc2_ctx_st', 'SSL3_STATE', ++ 'ssl3_buffer_st', 'ASN1_ITEM_EXP', ++ '_opaque_pthread_condattr_t', 'mode_t', 'ASN1_VALUE', ++ 'qaddr_t', '__darwin_gid_t', 'EVP_PKEY', 'CRYPTO_EX_free', ++ '_ossl_old_des_cblock', 'X509_INFO', 'asn1_string_st', ++ 'intptr_t', 'UIT_INFO', 'int_fast8_t', 'sigaltstack', ++ 'env_md_st', 'LHASH', '__darwin_ucontext_t', ++ 'PKCS7_SIGN_ENVELOPE', '__darwin_mcontext_t', 'ct_rune_t', ++ 'MD2_CTX', 'pthread_once_t', 'SSL3_BUFFER', 'fd_mask', ++ 'ASN1_TYPE', 'PKCS7_SIGNED', 'ssl3_record_st', 'BF_KEY', ++ 'MD4state_st', 'MD4_CTX', 'int16_t', 'SSL_CIPHER', ++ 'rune_t', 'X509_TRUST', 'siginfo_t', 'X509_STORE', ++ '__sbuf', 'X509_STORE_CTX', '__darwin_blksize_t', 'ldiv_t', ++ 'ASN1_TIME', 'SSL_METHOD', 'X509_LOOKUP', ++ 'Netscape_spki_st', 'P_PID', 'sigaction', 'sig_t', ++ 'hostent', 'x509_cert_aux_st', '_opaque_pthread_cond_t', ++ 'segsz_t', 'ushort', '__darwin_ct_rune_t', 'fd_set', ++ 'BN_RECP_CTX', 'x509_lookup_st', 'uint16_t', 'pkcs7_st', ++ 'asn1_header_st', '__darwin_pthread_key_t', ++ 'x509_trust_st', '__darwin_pthread_handler_rec', 'int32_t', ++ 'X509_CRL_INFO', 'N11evp_pkey_st4DOLLAR_12E', 'MDC2_CTX', ++ 'N23_ossl_old_des_ks_struct4DOLLAR_10E', 'ASN1_HEADER', ++ 'X509_crl_info_st', 'LHASH_HASH_FN_TYPE', ++ '_opaque_pthread_mutexattr_t', 'ssl_st', ++ 'N8pkcs7_st4DOLLAR_15E', 'evp_pkey_st', ++ 'pkcs7_signedandenveloped_st', '__darwin_mach_port_t', ++ 'EVP_PBE_KEYGEN', '_opaque_pthread_mutex_t', ++ 'ASN1_UTCTIME', 'mcontext', 'crypto_ex_data_func_st', ++ 'u_long', 'PBKDF2PARAM_st', 'rc4_key_st', 'DSA_METHOD', ++ 'EVP_CIPHER', 'BIT_STRING_BITNAME', 'PKCS7_RECIP_INFO', ++ 'ssl3_enc_method', 'X509_CERT_AUX', 'uintmax_t', ++ 'int_fast16_t', 'RC5_32_KEY', 'ucontext64', 'ASN1_INTEGER', ++ 'u_short', 'N14x509_object_st4DOLLAR_14E', 'mcontext64', ++ 'X509_sig_st', 'ASN1_GENERALSTRING', 'PKCS7', '__sFILEX', ++ 'X509_name_entry_st', 'ssl_session_st', 'caddr_t', ++ 'bignum_st', 'X509_CINF', '__darwin_pthread_cond_t', ++ 'ASN1_TLC', 'PKCS7_ENCRYPT', 'NETSCAPE_SPKAC', ++ 'Netscape_spkac_st', 'idtype_t', 'UIT_ERROR', ++ 'uint_fast64_t', 'in_addr_t', 'pthread_mutex_t', ++ '__int64_t', 'ASN1_BMPSTRING', 'uint32_t', ++ 'PEM_ENCODE_SEAL_CTX', 'suseconds_t', 'ASN1_OBJECT', ++ 'X509_val_st', 'private_key_st', 'CRYPTO_dynlock', ++ 'X509_objects_st', 'CRYPTO_EX_DATA_IMPL', ++ 'pthread_condattr_t', 'PKCS7_DIGEST', 'uint_least32_t', ++ 'ASN1_STRING', '__uint32_t', 'P_PGID', 'rsa_meth_st', ++ 'X509_crl_st', 'RC2_KEY', '__darwin_fsfilcnt_t', ++ 'X509_revoked_st', 'PBE2PARAM', 'blksize_t', ++ 'Netscape_certificate_sequence', 'ssl_cipher_st', ++ 'bignum_ctx', 'register_t', 'ASN1_UTF8STRING', ++ 'pkcs7_encrypted_st', 'RC4_KEY', '__darwin_ucontext64_t', ++ 'N13ssl2_state_st4DOLLAR_19E', 'bn_recp_ctx_st', ++ 'CAST_KEY', 'X509_ATTRIBUTE', '__darwin_suseconds_t', ++ '__sigaction', 'user_ulong_t', 'syscall_arg_t', ++ 'evp_cipher_ctx_st', 'X509_ALGOR', 'mcontext_t', ++ 'const_DES_cblock', '__darwin_fsblkcnt_t', 'dsa_st', ++ 'int_least8_t', 'MD2state_st', 'X509_EXTENSION', ++ 'GEN_SESSION_CB', 'int_least16_t', '__darwin_wctrans_t', ++ 'PBKDF2PARAM', 'x509_lookup_method_st', 'pem_password_cb', ++ 'X509_info_st', 'x509_store_st', '__darwin_natural_t', ++ 'X509_pubkey_st', 'pkcs7_digest_st', '__darwin_size_t', ++ 'ASN1_STRING_TABLE', 'OSLittleEndian', 'RIPEMD160state_st', ++ 'pkcs7_enveloped_st', 'UI', 'ptrdiff_t', 'X509_REQ', ++ 'CRYPTO_dynlock_value', 'X509_req_st', 'x509_store_ctx_st', ++ 'N13ssl3_state_st4DOLLAR_20E', 'lhash_node_st', ++ '__darwin_pthread_mutex_t', 'LHASH_COMP_FN_TYPE', ++ '__darwin_rune_t', 'rlimit', '__darwin_pthread_once_t', ++ 'OSBigEndian', 'uintptr_t', '__darwin_uid_t', 'u_int', ++ 'ASN1_T61STRING', 'gid_t', 'ssl_method_st', 'ASN1_ITEM', ++ 'ASN1_ENUMERATED', '_opaque_pthread_rwlock_t', ++ 'pkcs8_priv_key_info_st', 'intmax_t', 'sigcontext', ++ 'X509_CRL', 'rc2_key_st', 'engine_st', 'x509_object_st', ++ '_opaque_pthread_once_t', 'DES_ks', 'SSL_COMP', ++ 'dsa_method', 'int64_t', 'bio_st', 'bf_key_st', ++ 'ASN1_GENERALIZEDTIME', 'PKCS7_ENC_CONTENT', ++ '__darwin_pid_t', 'lldiv_t', 'comp_method_st', ++ 'EVP_MD_CTX', 'evp_cipher_st', 'X509_name_st', ++ 'x509_hash_dir_st', '__darwin_mach_port_name_t', ++ 'useconds_t', 'user_size_t', 'SSL_SESSION', 'rusage', ++ 'ssl_crock_st', 'int_least32_t', '__sigaction_u', 'dh_st', ++ 'P_ALL', '__darwin_stack_t', 'N6DES_ks3DOLLAR_9E', ++ 'comp_ctx_st', 'X509_CERT_FILE_CTX'] +diff -r 531f2e948299 refactor/tests/data/py2_test_grammar.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/py2_test_grammar.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,956 @@ ++# Python 2's Lib/test/test_grammar.py (r66189) ++ ++# Python test set -- part 1, grammar. ++# This just tests whether the parser accepts them all. ++ ++# NOTE: When you run this test as a script from the command line, you ++# get warnings about certain hex/oct constants. Since those are ++# issued by the parser, you can't suppress them by adding a ++# filterwarnings() call to this module. Therefore, to shut up the ++# regression test, the filterwarnings() call has been added to ++# regrtest.py. ++ ++from test.test_support import run_unittest, check_syntax_error ++import unittest ++import sys ++# testing import * ++from sys import * ++ ++class TokenTests(unittest.TestCase): ++ ++ def testBackslash(self): ++ # Backslash means line continuation: ++ x = 1 \ ++ + 1 ++ self.assertEquals(x, 2, 'backslash for line continuation') ++ ++ # Backslash does not means continuation in comments :\ ++ x = 0 ++ self.assertEquals(x, 0, 'backslash ending comment') ++ ++ def testPlainIntegers(self): ++ self.assertEquals(0xff, 255) ++ self.assertEquals(0377, 255) ++ self.assertEquals(2147483647, 017777777777) ++ # "0x" is not a valid literal ++ self.assertRaises(SyntaxError, eval, "0x") ++ from sys import maxint ++ if maxint == 2147483647: ++ self.assertEquals(-2147483647-1, -020000000000) ++ # XXX -2147483648 ++ self.assert_(037777777777 > 0) ++ self.assert_(0xffffffff > 0) ++ for s in '2147483648', '040000000000', '0x100000000': ++ try: ++ x = eval(s) ++ except OverflowError: ++ self.fail("OverflowError on huge integer literal %r" % s) ++ elif maxint == 9223372036854775807: ++ self.assertEquals(-9223372036854775807-1, -01000000000000000000000) ++ self.assert_(01777777777777777777777 > 0) ++ self.assert_(0xffffffffffffffff > 0) ++ for s in '9223372036854775808', '02000000000000000000000', \ ++ '0x10000000000000000': ++ try: ++ x = eval(s) ++ except OverflowError: ++ self.fail("OverflowError on huge integer literal %r" % s) ++ else: ++ self.fail('Weird maxint value %r' % maxint) ++ ++ def testLongIntegers(self): ++ x = 0L ++ x = 0l ++ x = 0xffffffffffffffffL ++ x = 0xffffffffffffffffl ++ x = 077777777777777777L ++ x = 077777777777777777l ++ x = 123456789012345678901234567890L ++ x = 123456789012345678901234567890l ++ ++ def testFloats(self): ++ x = 3.14 ++ x = 314. ++ x = 0.314 ++ # XXX x = 000.314 ++ x = .314 ++ x = 3e14 ++ x = 3E14 ++ x = 3e-14 ++ x = 3e+14 ++ x = 3.e14 ++ x = .3e14 ++ x = 3.1e4 ++ ++ def testStringLiterals(self): ++ x = ''; y = ""; self.assert_(len(x) == 0 and x == y) ++ x = '\''; y = "'"; self.assert_(len(x) == 1 and x == y and ord(x) == 39) ++ x = '"'; y = "\""; self.assert_(len(x) == 1 and x == y and ord(x) == 34) ++ x = "doesn't \"shrink\" does it" ++ y = 'doesn\'t "shrink" does it' ++ self.assert_(len(x) == 24 and x == y) ++ x = "does \"shrink\" doesn't it" ++ y = 'does "shrink" doesn\'t it' ++ self.assert_(len(x) == 24 and x == y) ++ x = """ ++The "quick" ++brown fox ++jumps over ++the 'lazy' dog. ++""" ++ y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n' ++ self.assertEquals(x, y) ++ y = ''' ++The "quick" ++brown fox ++jumps over ++the 'lazy' dog. ++''' ++ self.assertEquals(x, y) ++ y = "\n\ ++The \"quick\"\n\ ++brown fox\n\ ++jumps over\n\ ++the 'lazy' dog.\n\ ++" ++ self.assertEquals(x, y) ++ y = '\n\ ++The \"quick\"\n\ ++brown fox\n\ ++jumps over\n\ ++the \'lazy\' dog.\n\ ++' ++ self.assertEquals(x, y) ++ ++ ++class GrammarTests(unittest.TestCase): ++ ++ # single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE ++ # XXX can't test in a script -- this rule is only used when interactive ++ ++ # file_input: (NEWLINE | stmt)* ENDMARKER ++ # Being tested as this very moment this very module ++ ++ # expr_input: testlist NEWLINE ++ # XXX Hard to test -- used only in calls to input() ++ ++ def testEvalInput(self): ++ # testlist ENDMARKER ++ x = eval('1, 0 or 1') ++ ++ def testFuncdef(self): ++ ### 'def' NAME parameters ':' suite ++ ### parameters: '(' [varargslist] ')' ++ ### varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' ('**'|'*' '*') NAME] ++ ### | ('**'|'*' '*') NAME) ++ ### | fpdef ['=' test] (',' fpdef ['=' test])* [','] ++ ### fpdef: NAME | '(' fplist ')' ++ ### fplist: fpdef (',' fpdef)* [','] ++ ### arglist: (argument ',')* (argument | *' test [',' '**' test] | '**' test) ++ ### argument: [test '='] test # Really [keyword '='] test ++ def f1(): pass ++ f1() ++ f1(*()) ++ f1(*(), **{}) ++ def f2(one_argument): pass ++ def f3(two, arguments): pass ++ def f4(two, (compound, (argument, list))): pass ++ def f5((compound, first), two): pass ++ self.assertEquals(f2.func_code.co_varnames, ('one_argument',)) ++ self.assertEquals(f3.func_code.co_varnames, ('two', 'arguments')) ++ if sys.platform.startswith('java'): ++ self.assertEquals(f4.func_code.co_varnames, ++ ('two', '(compound, (argument, list))', 'compound', 'argument', ++ 'list',)) ++ self.assertEquals(f5.func_code.co_varnames, ++ ('(compound, first)', 'two', 'compound', 'first')) ++ else: ++ self.assertEquals(f4.func_code.co_varnames, ++ ('two', '.1', 'compound', 'argument', 'list')) ++ self.assertEquals(f5.func_code.co_varnames, ++ ('.0', 'two', 'compound', 'first')) ++ def a1(one_arg,): pass ++ def a2(two, args,): pass ++ def v0(*rest): pass ++ def v1(a, *rest): pass ++ def v2(a, b, *rest): pass ++ def v3(a, (b, c), *rest): return a, b, c, rest ++ ++ f1() ++ f2(1) ++ f2(1,) ++ f3(1, 2) ++ f3(1, 2,) ++ f4(1, (2, (3, 4))) ++ v0() ++ v0(1) ++ v0(1,) ++ v0(1,2) ++ v0(1,2,3,4,5,6,7,8,9,0) ++ v1(1) ++ v1(1,) ++ v1(1,2) ++ v1(1,2,3) ++ v1(1,2,3,4,5,6,7,8,9,0) ++ v2(1,2) ++ v2(1,2,3) ++ v2(1,2,3,4) ++ v2(1,2,3,4,5,6,7,8,9,0) ++ v3(1,(2,3)) ++ v3(1,(2,3),4) ++ v3(1,(2,3),4,5,6,7,8,9,0) ++ ++ # ceval unpacks the formal arguments into the first argcount names; ++ # thus, the names nested inside tuples must appear after these names. ++ if sys.platform.startswith('java'): ++ self.assertEquals(v3.func_code.co_varnames, ('a', '(b, c)', 'rest', 'b', 'c')) ++ else: ++ self.assertEquals(v3.func_code.co_varnames, ('a', '.1', 'rest', 'b', 'c')) ++ self.assertEquals(v3(1, (2, 3), 4), (1, 2, 3, (4,))) ++ def d01(a=1): pass ++ d01() ++ d01(1) ++ d01(*(1,)) ++ d01(**{'a':2}) ++ def d11(a, b=1): pass ++ d11(1) ++ d11(1, 2) ++ d11(1, **{'b':2}) ++ def d21(a, b, c=1): pass ++ d21(1, 2) ++ d21(1, 2, 3) ++ d21(*(1, 2, 3)) ++ d21(1, *(2, 3)) ++ d21(1, 2, *(3,)) ++ d21(1, 2, **{'c':3}) ++ def d02(a=1, b=2): pass ++ d02() ++ d02(1) ++ d02(1, 2) ++ d02(*(1, 2)) ++ d02(1, *(2,)) ++ d02(1, **{'b':2}) ++ d02(**{'a': 1, 'b': 2}) ++ def d12(a, b=1, c=2): pass ++ d12(1) ++ d12(1, 2) ++ d12(1, 2, 3) ++ def d22(a, b, c=1, d=2): pass ++ d22(1, 2) ++ d22(1, 2, 3) ++ d22(1, 2, 3, 4) ++ def d01v(a=1, *rest): pass ++ d01v() ++ d01v(1) ++ d01v(1, 2) ++ d01v(*(1, 2, 3, 4)) ++ d01v(*(1,)) ++ d01v(**{'a':2}) ++ def d11v(a, b=1, *rest): pass ++ d11v(1) ++ d11v(1, 2) ++ d11v(1, 2, 3) ++ def d21v(a, b, c=1, *rest): pass ++ d21v(1, 2) ++ d21v(1, 2, 3) ++ d21v(1, 2, 3, 4) ++ d21v(*(1, 2, 3, 4)) ++ d21v(1, 2, **{'c': 3}) ++ def d02v(a=1, b=2, *rest): pass ++ d02v() ++ d02v(1) ++ d02v(1, 2) ++ d02v(1, 2, 3) ++ d02v(1, *(2, 3, 4)) ++ d02v(**{'a': 1, 'b': 2}) ++ def d12v(a, b=1, c=2, *rest): pass ++ d12v(1) ++ d12v(1, 2) ++ d12v(1, 2, 3) ++ d12v(1, 2, 3, 4) ++ d12v(*(1, 2, 3, 4)) ++ d12v(1, 2, *(3, 4, 5)) ++ d12v(1, *(2,), **{'c': 3}) ++ def d22v(a, b, c=1, d=2, *rest): pass ++ d22v(1, 2) ++ d22v(1, 2, 3) ++ d22v(1, 2, 3, 4) ++ d22v(1, 2, 3, 4, 5) ++ d22v(*(1, 2, 3, 4)) ++ d22v(1, 2, *(3, 4, 5)) ++ d22v(1, *(2, 3), **{'d': 4}) ++ def d31v((x)): pass ++ d31v(1) ++ def d32v((x,)): pass ++ d32v((1,)) ++ ++ # keyword arguments after *arglist ++ def f(*args, **kwargs): ++ return args, kwargs ++ self.assertEquals(f(1, x=2, *[3, 4], y=5), ((1, 3, 4), ++ {'x':2, 'y':5})) ++ self.assertRaises(SyntaxError, eval, "f(1, *(2,3), 4)") ++ self.assertRaises(SyntaxError, eval, "f(1, x=2, *(3,4), x=5)") ++ ++ # Check ast errors in *args and *kwargs ++ check_syntax_error(self, "f(*g(1=2))") ++ check_syntax_error(self, "f(**g(1=2))") ++ ++ def testLambdef(self): ++ ### lambdef: 'lambda' [varargslist] ':' test ++ l1 = lambda : 0 ++ self.assertEquals(l1(), 0) ++ l2 = lambda : a[d] # XXX just testing the expression ++ l3 = lambda : [2 < x for x in [-1, 3, 0L]] ++ self.assertEquals(l3(), [0, 1, 0]) ++ l4 = lambda x = lambda y = lambda z=1 : z : y() : x() ++ self.assertEquals(l4(), 1) ++ l5 = lambda x, y, z=2: x + y + z ++ self.assertEquals(l5(1, 2), 5) ++ self.assertEquals(l5(1, 2, 3), 6) ++ check_syntax_error(self, "lambda x: x = 2") ++ check_syntax_error(self, "lambda (None,): None") ++ ++ ### stmt: simple_stmt | compound_stmt ++ # Tested below ++ ++ def testSimpleStmt(self): ++ ### simple_stmt: small_stmt (';' small_stmt)* [';'] ++ x = 1; pass; del x ++ def foo(): ++ # verify statments that end with semi-colons ++ x = 1; pass; del x; ++ foo() ++ ++ ### small_stmt: expr_stmt | print_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt | exec_stmt ++ # Tested below ++ ++ def testExprStmt(self): ++ # (exprlist '=')* exprlist ++ 1 ++ 1, 2, 3 ++ x = 1 ++ x = 1, 2, 3 ++ x = y = z = 1, 2, 3 ++ x, y, z = 1, 2, 3 ++ abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4) ++ ++ check_syntax_error(self, "x + 1 = 1") ++ check_syntax_error(self, "a + 1 = b + 2") ++ ++ def testPrintStmt(self): ++ # 'print' (test ',')* [test] ++ import StringIO ++ ++ # Can't test printing to real stdout without comparing output ++ # which is not available in unittest. ++ save_stdout = sys.stdout ++ sys.stdout = StringIO.StringIO() ++ ++ print 1, 2, 3 ++ print 1, 2, 3, ++ print ++ print 0 or 1, 0 or 1, ++ print 0 or 1 ++ ++ # 'print' '>>' test ',' ++ print >> sys.stdout, 1, 2, 3 ++ print >> sys.stdout, 1, 2, 3, ++ print >> sys.stdout ++ print >> sys.stdout, 0 or 1, 0 or 1, ++ print >> sys.stdout, 0 or 1 ++ ++ # test printing to an instance ++ class Gulp: ++ def write(self, msg): pass ++ ++ gulp = Gulp() ++ print >> gulp, 1, 2, 3 ++ print >> gulp, 1, 2, 3, ++ print >> gulp ++ print >> gulp, 0 or 1, 0 or 1, ++ print >> gulp, 0 or 1 ++ ++ # test print >> None ++ def driver(): ++ oldstdout = sys.stdout ++ sys.stdout = Gulp() ++ try: ++ tellme(Gulp()) ++ tellme() ++ finally: ++ sys.stdout = oldstdout ++ ++ # we should see this once ++ def tellme(file=sys.stdout): ++ print >> file, 'hello world' ++ ++ driver() ++ ++ # we should not see this at all ++ def tellme(file=None): ++ print >> file, 'goodbye universe' ++ ++ driver() ++ ++ self.assertEqual(sys.stdout.getvalue(), '''\ ++1 2 3 ++1 2 3 ++1 1 1 ++1 2 3 ++1 2 3 ++1 1 1 ++hello world ++''') ++ sys.stdout = save_stdout ++ ++ # syntax errors ++ check_syntax_error(self, 'print ,') ++ check_syntax_error(self, 'print >> x,') ++ ++ def testDelStmt(self): ++ # 'del' exprlist ++ abc = [1,2,3] ++ x, y, z = abc ++ xyz = x, y, z ++ ++ del abc ++ del x, y, (z, xyz) ++ ++ def testPassStmt(self): ++ # 'pass' ++ pass ++ ++ # flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt ++ # Tested below ++ ++ def testBreakStmt(self): ++ # 'break' ++ while 1: break ++ ++ def testContinueStmt(self): ++ # 'continue' ++ i = 1 ++ while i: i = 0; continue ++ ++ msg = "" ++ while not msg: ++ msg = "ok" ++ try: ++ continue ++ msg = "continue failed to continue inside try" ++ except: ++ msg = "continue inside try called except block" ++ if msg != "ok": ++ self.fail(msg) ++ ++ msg = "" ++ while not msg: ++ msg = "finally block not called" ++ try: ++ continue ++ finally: ++ msg = "ok" ++ if msg != "ok": ++ self.fail(msg) ++ ++ def test_break_continue_loop(self): ++ # This test warrants an explanation. It is a test specifically for SF bugs ++ # #463359 and #462937. The bug is that a 'break' statement executed or ++ # exception raised inside a try/except inside a loop, *after* a continue ++ # statement has been executed in that loop, will cause the wrong number of ++ # arguments to be popped off the stack and the instruction pointer reset to ++ # a very small number (usually 0.) Because of this, the following test ++ # *must* written as a function, and the tracking vars *must* be function ++ # arguments with default values. Otherwise, the test will loop and loop. ++ ++ def test_inner(extra_burning_oil = 1, count=0): ++ big_hippo = 2 ++ while big_hippo: ++ count += 1 ++ try: ++ if extra_burning_oil and big_hippo == 1: ++ extra_burning_oil -= 1 ++ break ++ big_hippo -= 1 ++ continue ++ except: ++ raise ++ if count > 2 or big_hippo <> 1: ++ self.fail("continue then break in try/except in loop broken!") ++ test_inner() ++ ++ def testReturn(self): ++ # 'return' [testlist] ++ def g1(): return ++ def g2(): return 1 ++ g1() ++ x = g2() ++ check_syntax_error(self, "class foo:return 1") ++ ++ def testYield(self): ++ check_syntax_error(self, "class foo:yield 1") ++ ++ def testRaise(self): ++ # 'raise' test [',' test] ++ try: raise RuntimeError, 'just testing' ++ except RuntimeError: pass ++ try: raise KeyboardInterrupt ++ except KeyboardInterrupt: pass ++ ++ def testImport(self): ++ # 'import' dotted_as_names ++ import sys ++ import time, sys ++ # 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names) ++ from time import time ++ from time import (time) ++ # not testable inside a function, but already done at top of the module ++ # from sys import * ++ from sys import path, argv ++ from sys import (path, argv) ++ from sys import (path, argv,) ++ ++ def testGlobal(self): ++ # 'global' NAME (',' NAME)* ++ global a ++ global a, b ++ global one, two, three, four, five, six, seven, eight, nine, ten ++ ++ def testExec(self): ++ # 'exec' expr ['in' expr [',' expr]] ++ z = None ++ del z ++ exec 'z=1+1\n' ++ if z != 2: self.fail('exec \'z=1+1\'\\n') ++ del z ++ exec 'z=1+1' ++ if z != 2: self.fail('exec \'z=1+1\'') ++ z = None ++ del z ++ import types ++ if hasattr(types, "UnicodeType"): ++ exec r"""if 1: ++ exec u'z=1+1\n' ++ if z != 2: self.fail('exec u\'z=1+1\'\\n') ++ del z ++ exec u'z=1+1' ++ if z != 2: self.fail('exec u\'z=1+1\'')""" ++ g = {} ++ exec 'z = 1' in g ++ if g.has_key('__builtins__'): del g['__builtins__'] ++ if g != {'z': 1}: self.fail('exec \'z = 1\' in g') ++ g = {} ++ l = {} ++ ++ import warnings ++ warnings.filterwarnings("ignore", "global statement", module="") ++ exec 'global a; a = 1; b = 2' in g, l ++ if g.has_key('__builtins__'): del g['__builtins__'] ++ if l.has_key('__builtins__'): del l['__builtins__'] ++ if (g, l) != ({'a':1}, {'b':2}): ++ self.fail('exec ... in g (%s), l (%s)' %(g,l)) ++ ++ def testAssert(self): ++ # assert_stmt: 'assert' test [',' test] ++ assert 1 ++ assert 1, 1 ++ assert lambda x:x ++ assert 1, lambda x:x+1 ++ try: ++ assert 0, "msg" ++ except AssertionError, e: ++ self.assertEquals(e.args[0], "msg") ++ else: ++ if __debug__: ++ self.fail("AssertionError not raised by assert 0") ++ ++ ### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef ++ # Tested below ++ ++ def testIf(self): ++ # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] ++ if 1: pass ++ if 1: pass ++ else: pass ++ if 0: pass ++ elif 0: pass ++ if 0: pass ++ elif 0: pass ++ elif 0: pass ++ elif 0: pass ++ else: pass ++ ++ def testWhile(self): ++ # 'while' test ':' suite ['else' ':' suite] ++ while 0: pass ++ while 0: pass ++ else: pass ++ ++ # Issue1920: "while 0" is optimized away, ++ # ensure that the "else" clause is still present. ++ x = 0 ++ while 0: ++ x = 1 ++ else: ++ x = 2 ++ self.assertEquals(x, 2) ++ ++ def testFor(self): ++ # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] ++ for i in 1, 2, 3: pass ++ for i, j, k in (): pass ++ else: pass ++ class Squares: ++ def __init__(self, max): ++ self.max = max ++ self.sofar = [] ++ def __len__(self): return len(self.sofar) ++ def __getitem__(self, i): ++ if not 0 <= i < self.max: raise IndexError ++ n = len(self.sofar) ++ while n <= i: ++ self.sofar.append(n*n) ++ n = n+1 ++ return self.sofar[i] ++ n = 0 ++ for x in Squares(10): n = n+x ++ if n != 285: ++ self.fail('for over growing sequence') ++ ++ result = [] ++ for x, in [(1,), (2,), (3,)]: ++ result.append(x) ++ self.assertEqual(result, [1, 2, 3]) ++ ++ def testTry(self): ++ ### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] ++ ### | 'try' ':' suite 'finally' ':' suite ++ ### except_clause: 'except' [expr [('as' | ',') expr]] ++ try: ++ 1/0 ++ except ZeroDivisionError: ++ pass ++ else: ++ pass ++ try: 1/0 ++ except EOFError: pass ++ except TypeError as msg: pass ++ except RuntimeError, msg: pass ++ except: pass ++ else: pass ++ try: 1/0 ++ except (EOFError, TypeError, ZeroDivisionError): pass ++ try: 1/0 ++ except (EOFError, TypeError, ZeroDivisionError), msg: pass ++ try: pass ++ finally: pass ++ ++ def testSuite(self): ++ # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT ++ if 1: pass ++ if 1: ++ pass ++ if 1: ++ # ++ # ++ # ++ pass ++ pass ++ # ++ pass ++ # ++ ++ def testTest(self): ++ ### and_test ('or' and_test)* ++ ### and_test: not_test ('and' not_test)* ++ ### not_test: 'not' not_test | comparison ++ if not 1: pass ++ if 1 and 1: pass ++ if 1 or 1: pass ++ if not not not 1: pass ++ if not 1 and 1 and 1: pass ++ if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass ++ ++ def testComparison(self): ++ ### comparison: expr (comp_op expr)* ++ ### comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' ++ if 1: pass ++ x = (1 == 1) ++ if 1 == 1: pass ++ if 1 != 1: pass ++ if 1 <> 1: pass ++ if 1 < 1: pass ++ if 1 > 1: pass ++ if 1 <= 1: pass ++ if 1 >= 1: pass ++ if 1 is 1: pass ++ if 1 is not 1: pass ++ if 1 in (): pass ++ if 1 not in (): pass ++ if 1 < 1 > 1 == 1 >= 1 <= 1 <> 1 != 1 in 1 not in 1 is 1 is not 1: pass ++ ++ def testBinaryMaskOps(self): ++ x = 1 & 1 ++ x = 1 ^ 1 ++ x = 1 | 1 ++ ++ def testShiftOps(self): ++ x = 1 << 1 ++ x = 1 >> 1 ++ x = 1 << 1 >> 1 ++ ++ def testAdditiveOps(self): ++ x = 1 ++ x = 1 + 1 ++ x = 1 - 1 - 1 ++ x = 1 - 1 + 1 - 1 + 1 ++ ++ def testMultiplicativeOps(self): ++ x = 1 * 1 ++ x = 1 / 1 ++ x = 1 % 1 ++ x = 1 / 1 * 1 % 1 ++ ++ def testUnaryOps(self): ++ x = +1 ++ x = -1 ++ x = ~1 ++ x = ~1 ^ 1 & 1 | 1 & 1 ^ -1 ++ x = -1*1/1 + 1*1 - ---1*1 ++ ++ def testSelectors(self): ++ ### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME ++ ### subscript: expr | [expr] ':' [expr] ++ ++ import sys, time ++ c = sys.path[0] ++ x = time.time() ++ x = sys.modules['time'].time() ++ a = '01234' ++ c = a[0] ++ c = a[-1] ++ s = a[0:5] ++ s = a[:5] ++ s = a[0:] ++ s = a[:] ++ s = a[-5:] ++ s = a[:-1] ++ s = a[-4:-3] ++ # A rough test of SF bug 1333982. http://python.org/sf/1333982 ++ # The testing here is fairly incomplete. ++ # Test cases should include: commas with 1 and 2 colons ++ d = {} ++ d[1] = 1 ++ d[1,] = 2 ++ d[1,2] = 3 ++ d[1,2,3] = 4 ++ L = list(d) ++ L.sort() ++ self.assertEquals(str(L), '[1, (1,), (1, 2), (1, 2, 3)]') ++ ++ def testAtoms(self): ++ ### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING ++ ### dictmaker: test ':' test (',' test ':' test)* [','] ++ ++ x = (1) ++ x = (1 or 2 or 3) ++ x = (1 or 2 or 3, 2, 3) ++ ++ x = [] ++ x = [1] ++ x = [1 or 2 or 3] ++ x = [1 or 2 or 3, 2, 3] ++ x = [] ++ ++ x = {} ++ x = {'one': 1} ++ x = {'one': 1,} ++ x = {'one' or 'two': 1 or 2} ++ x = {'one': 1, 'two': 2} ++ x = {'one': 1, 'two': 2,} ++ x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6} ++ ++ x = `x` ++ x = `1 or 2 or 3` ++ self.assertEqual(`1,2`, '(1, 2)') ++ ++ x = x ++ x = 'x' ++ x = 123 ++ ++ ### exprlist: expr (',' expr)* [','] ++ ### testlist: test (',' test)* [','] ++ # These have been exercised enough above ++ ++ def testClassdef(self): ++ # 'class' NAME ['(' [testlist] ')'] ':' suite ++ class B: pass ++ class B2(): pass ++ class C1(B): pass ++ class C2(B): pass ++ class D(C1, C2, B): pass ++ class C: ++ def meth1(self): pass ++ def meth2(self, arg): pass ++ def meth3(self, a1, a2): pass ++ # decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE ++ # decorators: decorator+ ++ # decorated: decorators (classdef | funcdef) ++ def class_decorator(x): ++ x.decorated = True ++ return x ++ @class_decorator ++ class G: ++ pass ++ self.assertEqual(G.decorated, True) ++ ++ def testListcomps(self): ++ # list comprehension tests ++ nums = [1, 2, 3, 4, 5] ++ strs = ["Apple", "Banana", "Coconut"] ++ spcs = [" Apple", " Banana ", "Coco nut "] ++ ++ self.assertEqual([s.strip() for s in spcs], ['Apple', 'Banana', 'Coco nut']) ++ self.assertEqual([3 * x for x in nums], [3, 6, 9, 12, 15]) ++ self.assertEqual([x for x in nums if x > 2], [3, 4, 5]) ++ self.assertEqual([(i, s) for i in nums for s in strs], ++ [(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'), ++ (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'), ++ (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'), ++ (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'), ++ (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')]) ++ self.assertEqual([(i, s) for i in nums for s in [f for f in strs if "n" in f]], ++ [(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'), ++ (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'), ++ (5, 'Banana'), (5, 'Coconut')]) ++ self.assertEqual([(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)], ++ [[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]]) ++ ++ def test_in_func(l): ++ return [None < x < 3 for x in l if x > 2] ++ ++ self.assertEqual(test_in_func(nums), [False, False, False]) ++ ++ def test_nested_front(): ++ self.assertEqual([[y for y in [x, x + 1]] for x in [1,3,5]], ++ [[1, 2], [3, 4], [5, 6]]) ++ ++ test_nested_front() ++ ++ check_syntax_error(self, "[i, s for i in nums for s in strs]") ++ check_syntax_error(self, "[x if y]") ++ ++ suppliers = [ ++ (1, "Boeing"), ++ (2, "Ford"), ++ (3, "Macdonalds") ++ ] ++ ++ parts = [ ++ (10, "Airliner"), ++ (20, "Engine"), ++ (30, "Cheeseburger") ++ ] ++ ++ suppart = [ ++ (1, 10), (1, 20), (2, 20), (3, 30) ++ ] ++ ++ x = [ ++ (sname, pname) ++ for (sno, sname) in suppliers ++ for (pno, pname) in parts ++ for (sp_sno, sp_pno) in suppart ++ if sno == sp_sno and pno == sp_pno ++ ] ++ ++ self.assertEqual(x, [('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), ++ ('Macdonalds', 'Cheeseburger')]) ++ ++ def testGenexps(self): ++ # generator expression tests ++ g = ([x for x in range(10)] for x in range(1)) ++ self.assertEqual(g.next(), [x for x in range(10)]) ++ try: ++ g.next() ++ self.fail('should produce StopIteration exception') ++ except StopIteration: ++ pass ++ ++ a = 1 ++ try: ++ g = (a for d in a) ++ g.next() ++ self.fail('should produce TypeError') ++ except TypeError: ++ pass ++ ++ self.assertEqual(list((x, y) for x in 'abcd' for y in 'abcd'), [(x, y) for x in 'abcd' for y in 'abcd']) ++ self.assertEqual(list((x, y) for x in 'ab' for y in 'xy'), [(x, y) for x in 'ab' for y in 'xy']) ++ ++ a = [x for x in range(10)] ++ b = (x for x in (y for y in a)) ++ self.assertEqual(sum(b), sum([x for x in range(10)])) ++ ++ self.assertEqual(sum(x**2 for x in range(10)), sum([x**2 for x in range(10)])) ++ self.assertEqual(sum(x*x for x in range(10) if x%2), sum([x*x for x in range(10) if x%2])) ++ self.assertEqual(sum(x for x in (y for y in range(10))), sum([x for x in range(10)])) ++ self.assertEqual(sum(x for x in (y for y in (z for z in range(10)))), sum([x for x in range(10)])) ++ self.assertEqual(sum(x for x in [y for y in (z for z in range(10))]), sum([x for x in range(10)])) ++ self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True)) if True), sum([x for x in range(10)])) ++ self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True) if False) if True), 0) ++ check_syntax_error(self, "foo(x for x in range(10), 100)") ++ check_syntax_error(self, "foo(100, x for x in range(10))") ++ ++ def testComprehensionSpecials(self): ++ # test for outmost iterable precomputation ++ x = 10; g = (i for i in range(x)); x = 5 ++ self.assertEqual(len(list(g)), 10) ++ ++ # This should hold, since we're only precomputing outmost iterable. ++ x = 10; t = False; g = ((i,j) for i in range(x) if t for j in range(x)) ++ x = 5; t = True; ++ self.assertEqual([(i,j) for i in range(10) for j in range(5)], list(g)) ++ ++ # Grammar allows multiple adjacent 'if's in listcomps and genexps, ++ # even though it's silly. Make sure it works (ifelse broke this.) ++ self.assertEqual([ x for x in range(10) if x % 2 if x % 3 ], [1, 5, 7]) ++ self.assertEqual(list(x for x in range(10) if x % 2 if x % 3), [1, 5, 7]) ++ ++ # verify unpacking single element tuples in listcomp/genexp. ++ self.assertEqual([x for x, in [(4,), (5,), (6,)]], [4, 5, 6]) ++ self.assertEqual(list(x for x, in [(7,), (8,), (9,)]), [7, 8, 9]) ++ ++ def testIfElseExpr(self): ++ # Test ifelse expressions in various cases ++ def _checkeval(msg, ret): ++ "helper to check that evaluation of expressions is done correctly" ++ print x ++ return ret ++ ++ self.assertEqual([ x() for x in lambda: True, lambda: False if x() ], [True]) ++ self.assertEqual([ x() for x in (lambda: True, lambda: False) if x() ], [True]) ++ self.assertEqual([ x(False) for x in (lambda x: False if x else True, lambda x: True if x else False) if x(False) ], [True]) ++ self.assertEqual((5 if 1 else _checkeval("check 1", 0)), 5) ++ self.assertEqual((_checkeval("check 2", 0) if 0 else 5), 5) ++ self.assertEqual((5 and 6 if 0 else 1), 1) ++ self.assertEqual(((5 and 6) if 0 else 1), 1) ++ self.assertEqual((5 and (6 if 1 else 1)), 6) ++ self.assertEqual((0 or _checkeval("check 3", 2) if 0 else 3), 3) ++ self.assertEqual((1 or _checkeval("check 4", 2) if 1 else _checkeval("check 5", 3)), 1) ++ self.assertEqual((0 or 5 if 1 else _checkeval("check 6", 3)), 5) ++ self.assertEqual((not 5 if 1 else 1), False) ++ self.assertEqual((not 5 if 0 else 1), 1) ++ self.assertEqual((6 + 1 if 1 else 2), 7) ++ self.assertEqual((6 - 1 if 1 else 2), 5) ++ self.assertEqual((6 * 2 if 1 else 4), 12) ++ self.assertEqual((6 / 2 if 1 else 3), 3) ++ self.assertEqual((6 < 4 if 0 else 2), 2) ++ ++ ++def test_main(): ++ run_unittest(TokenTests, GrammarTests) ++ ++if __name__ == '__main__': ++ test_main() +diff -r 531f2e948299 refactor/tests/data/py3_test_grammar.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/data/py3_test_grammar.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,903 @@ ++# Python test set -- part 1, grammar. ++# This just tests whether the parser accepts them all. ++ ++# NOTE: When you run this test as a script from the command line, you ++# get warnings about certain hex/oct constants. Since those are ++# issued by the parser, you can't suppress them by adding a ++# filterwarnings() call to this module. Therefore, to shut up the ++# regression test, the filterwarnings() call has been added to ++# regrtest.py. ++ ++from test.support import run_unittest, check_syntax_error ++import unittest ++import sys ++# testing import * ++from sys import * ++ ++class TokenTests(unittest.TestCase): ++ ++ def testBackslash(self): ++ # Backslash means line continuation: ++ x = 1 \ ++ + 1 ++ self.assertEquals(x, 2, 'backslash for line continuation') ++ ++ # Backslash does not means continuation in comments :\ ++ x = 0 ++ self.assertEquals(x, 0, 'backslash ending comment') ++ ++ def testPlainIntegers(self): ++ self.assertEquals(type(000), type(0)) ++ self.assertEquals(0xff, 255) ++ self.assertEquals(0o377, 255) ++ self.assertEquals(2147483647, 0o17777777777) ++ self.assertEquals(0b1001, 9) ++ # "0x" is not a valid literal ++ self.assertRaises(SyntaxError, eval, "0x") ++ from sys import maxsize ++ if maxsize == 2147483647: ++ self.assertEquals(-2147483647-1, -0o20000000000) ++ # XXX -2147483648 ++ self.assert_(0o37777777777 > 0) ++ self.assert_(0xffffffff > 0) ++ self.assert_(0b1111111111111111111111111111111 > 0) ++ for s in ('2147483648', '0o40000000000', '0x100000000', ++ '0b10000000000000000000000000000000'): ++ try: ++ x = eval(s) ++ except OverflowError: ++ self.fail("OverflowError on huge integer literal %r" % s) ++ elif maxsize == 9223372036854775807: ++ self.assertEquals(-9223372036854775807-1, -0o1000000000000000000000) ++ self.assert_(0o1777777777777777777777 > 0) ++ self.assert_(0xffffffffffffffff > 0) ++ self.assert_(0b11111111111111111111111111111111111111111111111111111111111111 > 0) ++ for s in '9223372036854775808', '0o2000000000000000000000', \ ++ '0x10000000000000000', \ ++ '0b100000000000000000000000000000000000000000000000000000000000000': ++ try: ++ x = eval(s) ++ except OverflowError: ++ self.fail("OverflowError on huge integer literal %r" % s) ++ else: ++ self.fail('Weird maxsize value %r' % maxsize) ++ ++ def testLongIntegers(self): ++ x = 0 ++ x = 0xffffffffffffffff ++ x = 0Xffffffffffffffff ++ x = 0o77777777777777777 ++ x = 0O77777777777777777 ++ x = 123456789012345678901234567890 ++ x = 0b100000000000000000000000000000000000000000000000000000000000000000000 ++ x = 0B111111111111111111111111111111111111111111111111111111111111111111111 ++ ++ def testFloats(self): ++ x = 3.14 ++ x = 314. ++ x = 0.314 ++ # XXX x = 000.314 ++ x = .314 ++ x = 3e14 ++ x = 3E14 ++ x = 3e-14 ++ x = 3e+14 ++ x = 3.e14 ++ x = .3e14 ++ x = 3.1e4 ++ ++ def testStringLiterals(self): ++ x = ''; y = ""; self.assert_(len(x) == 0 and x == y) ++ x = '\''; y = "'"; self.assert_(len(x) == 1 and x == y and ord(x) == 39) ++ x = '"'; y = "\""; self.assert_(len(x) == 1 and x == y and ord(x) == 34) ++ x = "doesn't \"shrink\" does it" ++ y = 'doesn\'t "shrink" does it' ++ self.assert_(len(x) == 24 and x == y) ++ x = "does \"shrink\" doesn't it" ++ y = 'does "shrink" doesn\'t it' ++ self.assert_(len(x) == 24 and x == y) ++ x = """ ++The "quick" ++brown fox ++jumps over ++the 'lazy' dog. ++""" ++ y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n' ++ self.assertEquals(x, y) ++ y = ''' ++The "quick" ++brown fox ++jumps over ++the 'lazy' dog. ++''' ++ self.assertEquals(x, y) ++ y = "\n\ ++The \"quick\"\n\ ++brown fox\n\ ++jumps over\n\ ++the 'lazy' dog.\n\ ++" ++ self.assertEquals(x, y) ++ y = '\n\ ++The \"quick\"\n\ ++brown fox\n\ ++jumps over\n\ ++the \'lazy\' dog.\n\ ++' ++ self.assertEquals(x, y) ++ ++ def testEllipsis(self): ++ x = ... ++ self.assert_(x is Ellipsis) ++ self.assertRaises(SyntaxError, eval, ".. .") ++ ++class GrammarTests(unittest.TestCase): ++ ++ # single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE ++ # XXX can't test in a script -- this rule is only used when interactive ++ ++ # file_input: (NEWLINE | stmt)* ENDMARKER ++ # Being tested as this very moment this very module ++ ++ # expr_input: testlist NEWLINE ++ # XXX Hard to test -- used only in calls to input() ++ ++ def testEvalInput(self): ++ # testlist ENDMARKER ++ x = eval('1, 0 or 1') ++ ++ def testFuncdef(self): ++ ### [decorators] 'def' NAME parameters ['->' test] ':' suite ++ ### decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE ++ ### decorators: decorator+ ++ ### parameters: '(' [typedargslist] ')' ++ ### typedargslist: ((tfpdef ['=' test] ',')* ++ ### ('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef) ++ ### | tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) ++ ### tfpdef: NAME [':' test] ++ ### varargslist: ((vfpdef ['=' test] ',')* ++ ### ('*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef) ++ ### | vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) ++ ### vfpdef: NAME ++ def f1(): pass ++ f1() ++ f1(*()) ++ f1(*(), **{}) ++ def f2(one_argument): pass ++ def f3(two, arguments): pass ++ self.assertEquals(f2.__code__.co_varnames, ('one_argument',)) ++ self.assertEquals(f3.__code__.co_varnames, ('two', 'arguments')) ++ def a1(one_arg,): pass ++ def a2(two, args,): pass ++ def v0(*rest): pass ++ def v1(a, *rest): pass ++ def v2(a, b, *rest): pass ++ ++ f1() ++ f2(1) ++ f2(1,) ++ f3(1, 2) ++ f3(1, 2,) ++ v0() ++ v0(1) ++ v0(1,) ++ v0(1,2) ++ v0(1,2,3,4,5,6,7,8,9,0) ++ v1(1) ++ v1(1,) ++ v1(1,2) ++ v1(1,2,3) ++ v1(1,2,3,4,5,6,7,8,9,0) ++ v2(1,2) ++ v2(1,2,3) ++ v2(1,2,3,4) ++ v2(1,2,3,4,5,6,7,8,9,0) ++ ++ def d01(a=1): pass ++ d01() ++ d01(1) ++ d01(*(1,)) ++ d01(**{'a':2}) ++ def d11(a, b=1): pass ++ d11(1) ++ d11(1, 2) ++ d11(1, **{'b':2}) ++ def d21(a, b, c=1): pass ++ d21(1, 2) ++ d21(1, 2, 3) ++ d21(*(1, 2, 3)) ++ d21(1, *(2, 3)) ++ d21(1, 2, *(3,)) ++ d21(1, 2, **{'c':3}) ++ def d02(a=1, b=2): pass ++ d02() ++ d02(1) ++ d02(1, 2) ++ d02(*(1, 2)) ++ d02(1, *(2,)) ++ d02(1, **{'b':2}) ++ d02(**{'a': 1, 'b': 2}) ++ def d12(a, b=1, c=2): pass ++ d12(1) ++ d12(1, 2) ++ d12(1, 2, 3) ++ def d22(a, b, c=1, d=2): pass ++ d22(1, 2) ++ d22(1, 2, 3) ++ d22(1, 2, 3, 4) ++ def d01v(a=1, *rest): pass ++ d01v() ++ d01v(1) ++ d01v(1, 2) ++ d01v(*(1, 2, 3, 4)) ++ d01v(*(1,)) ++ d01v(**{'a':2}) ++ def d11v(a, b=1, *rest): pass ++ d11v(1) ++ d11v(1, 2) ++ d11v(1, 2, 3) ++ def d21v(a, b, c=1, *rest): pass ++ d21v(1, 2) ++ d21v(1, 2, 3) ++ d21v(1, 2, 3, 4) ++ d21v(*(1, 2, 3, 4)) ++ d21v(1, 2, **{'c': 3}) ++ def d02v(a=1, b=2, *rest): pass ++ d02v() ++ d02v(1) ++ d02v(1, 2) ++ d02v(1, 2, 3) ++ d02v(1, *(2, 3, 4)) ++ d02v(**{'a': 1, 'b': 2}) ++ def d12v(a, b=1, c=2, *rest): pass ++ d12v(1) ++ d12v(1, 2) ++ d12v(1, 2, 3) ++ d12v(1, 2, 3, 4) ++ d12v(*(1, 2, 3, 4)) ++ d12v(1, 2, *(3, 4, 5)) ++ d12v(1, *(2,), **{'c': 3}) ++ def d22v(a, b, c=1, d=2, *rest): pass ++ d22v(1, 2) ++ d22v(1, 2, 3) ++ d22v(1, 2, 3, 4) ++ d22v(1, 2, 3, 4, 5) ++ d22v(*(1, 2, 3, 4)) ++ d22v(1, 2, *(3, 4, 5)) ++ d22v(1, *(2, 3), **{'d': 4}) ++ ++ # keyword argument type tests ++ try: ++ str('x', **{b'foo':1 }) ++ except TypeError: ++ pass ++ else: ++ self.fail('Bytes should not work as keyword argument names') ++ # keyword only argument tests ++ def pos0key1(*, key): return key ++ pos0key1(key=100) ++ def pos2key2(p1, p2, *, k1, k2=100): return p1,p2,k1,k2 ++ pos2key2(1, 2, k1=100) ++ pos2key2(1, 2, k1=100, k2=200) ++ pos2key2(1, 2, k2=100, k1=200) ++ def pos2key2dict(p1, p2, *, k1=100, k2, **kwarg): return p1,p2,k1,k2,kwarg ++ pos2key2dict(1,2,k2=100,tokwarg1=100,tokwarg2=200) ++ pos2key2dict(1,2,tokwarg1=100,tokwarg2=200, k2=100) ++ ++ # keyword arguments after *arglist ++ def f(*args, **kwargs): ++ return args, kwargs ++ self.assertEquals(f(1, x=2, *[3, 4], y=5), ((1, 3, 4), ++ {'x':2, 'y':5})) ++ self.assertRaises(SyntaxError, eval, "f(1, *(2,3), 4)") ++ self.assertRaises(SyntaxError, eval, "f(1, x=2, *(3,4), x=5)") ++ ++ # argument annotation tests ++ def f(x) -> list: pass ++ self.assertEquals(f.__annotations__, {'return': list}) ++ def f(x:int): pass ++ self.assertEquals(f.__annotations__, {'x': int}) ++ def f(*x:str): pass ++ self.assertEquals(f.__annotations__, {'x': str}) ++ def f(**x:float): pass ++ self.assertEquals(f.__annotations__, {'x': float}) ++ def f(x, y:1+2): pass ++ self.assertEquals(f.__annotations__, {'y': 3}) ++ def f(a, b:1, c:2, d): pass ++ self.assertEquals(f.__annotations__, {'b': 1, 'c': 2}) ++ def f(a, b:1, c:2, d, e:3=4, f=5, *g:6): pass ++ self.assertEquals(f.__annotations__, ++ {'b': 1, 'c': 2, 'e': 3, 'g': 6}) ++ def f(a, b:1, c:2, d, e:3=4, f=5, *g:6, h:7, i=8, j:9=10, ++ **k:11) -> 12: pass ++ self.assertEquals(f.__annotations__, ++ {'b': 1, 'c': 2, 'e': 3, 'g': 6, 'h': 7, 'j': 9, ++ 'k': 11, 'return': 12}) ++ # Check for SF Bug #1697248 - mixing decorators and a return annotation ++ def null(x): return x ++ @null ++ def f(x) -> list: pass ++ self.assertEquals(f.__annotations__, {'return': list}) ++ ++ # test MAKE_CLOSURE with a variety of oparg's ++ closure = 1 ++ def f(): return closure ++ def f(x=1): return closure ++ def f(*, k=1): return closure ++ def f() -> int: return closure ++ ++ # Check ast errors in *args and *kwargs ++ check_syntax_error(self, "f(*g(1=2))") ++ check_syntax_error(self, "f(**g(1=2))") ++ ++ def testLambdef(self): ++ ### lambdef: 'lambda' [varargslist] ':' test ++ l1 = lambda : 0 ++ self.assertEquals(l1(), 0) ++ l2 = lambda : a[d] # XXX just testing the expression ++ l3 = lambda : [2 < x for x in [-1, 3, 0]] ++ self.assertEquals(l3(), [0, 1, 0]) ++ l4 = lambda x = lambda y = lambda z=1 : z : y() : x() ++ self.assertEquals(l4(), 1) ++ l5 = lambda x, y, z=2: x + y + z ++ self.assertEquals(l5(1, 2), 5) ++ self.assertEquals(l5(1, 2, 3), 6) ++ check_syntax_error(self, "lambda x: x = 2") ++ check_syntax_error(self, "lambda (None,): None") ++ l6 = lambda x, y, *, k=20: x+y+k ++ self.assertEquals(l6(1,2), 1+2+20) ++ self.assertEquals(l6(1,2,k=10), 1+2+10) ++ ++ ++ ### stmt: simple_stmt | compound_stmt ++ # Tested below ++ ++ def testSimpleStmt(self): ++ ### simple_stmt: small_stmt (';' small_stmt)* [';'] ++ x = 1; pass; del x ++ def foo(): ++ # verify statments that end with semi-colons ++ x = 1; pass; del x; ++ foo() ++ ++ ### small_stmt: expr_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt ++ # Tested below ++ ++ def testExprStmt(self): ++ # (exprlist '=')* exprlist ++ 1 ++ 1, 2, 3 ++ x = 1 ++ x = 1, 2, 3 ++ x = y = z = 1, 2, 3 ++ x, y, z = 1, 2, 3 ++ abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4) ++ ++ check_syntax_error(self, "x + 1 = 1") ++ check_syntax_error(self, "a + 1 = b + 2") ++ ++ def testDelStmt(self): ++ # 'del' exprlist ++ abc = [1,2,3] ++ x, y, z = abc ++ xyz = x, y, z ++ ++ del abc ++ del x, y, (z, xyz) ++ ++ def testPassStmt(self): ++ # 'pass' ++ pass ++ ++ # flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt ++ # Tested below ++ ++ def testBreakStmt(self): ++ # 'break' ++ while 1: break ++ ++ def testContinueStmt(self): ++ # 'continue' ++ i = 1 ++ while i: i = 0; continue ++ ++ msg = "" ++ while not msg: ++ msg = "ok" ++ try: ++ continue ++ msg = "continue failed to continue inside try" ++ except: ++ msg = "continue inside try called except block" ++ if msg != "ok": ++ self.fail(msg) ++ ++ msg = "" ++ while not msg: ++ msg = "finally block not called" ++ try: ++ continue ++ finally: ++ msg = "ok" ++ if msg != "ok": ++ self.fail(msg) ++ ++ def test_break_continue_loop(self): ++ # This test warrants an explanation. It is a test specifically for SF bugs ++ # #463359 and #462937. The bug is that a 'break' statement executed or ++ # exception raised inside a try/except inside a loop, *after* a continue ++ # statement has been executed in that loop, will cause the wrong number of ++ # arguments to be popped off the stack and the instruction pointer reset to ++ # a very small number (usually 0.) Because of this, the following test ++ # *must* written as a function, and the tracking vars *must* be function ++ # arguments with default values. Otherwise, the test will loop and loop. ++ ++ def test_inner(extra_burning_oil = 1, count=0): ++ big_hippo = 2 ++ while big_hippo: ++ count += 1 ++ try: ++ if extra_burning_oil and big_hippo == 1: ++ extra_burning_oil -= 1 ++ break ++ big_hippo -= 1 ++ continue ++ except: ++ raise ++ if count > 2 or big_hippo != 1: ++ self.fail("continue then break in try/except in loop broken!") ++ test_inner() ++ ++ def testReturn(self): ++ # 'return' [testlist] ++ def g1(): return ++ def g2(): return 1 ++ g1() ++ x = g2() ++ check_syntax_error(self, "class foo:return 1") ++ ++ def testYield(self): ++ check_syntax_error(self, "class foo:yield 1") ++ ++ def testRaise(self): ++ # 'raise' test [',' test] ++ try: raise RuntimeError('just testing') ++ except RuntimeError: pass ++ try: raise KeyboardInterrupt ++ except KeyboardInterrupt: pass ++ ++ def testImport(self): ++ # 'import' dotted_as_names ++ import sys ++ import time, sys ++ # 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names) ++ from time import time ++ from time import (time) ++ # not testable inside a function, but already done at top of the module ++ # from sys import * ++ from sys import path, argv ++ from sys import (path, argv) ++ from sys import (path, argv,) ++ ++ def testGlobal(self): ++ # 'global' NAME (',' NAME)* ++ global a ++ global a, b ++ global one, two, three, four, five, six, seven, eight, nine, ten ++ ++ def testNonlocal(self): ++ # 'nonlocal' NAME (',' NAME)* ++ x = 0 ++ y = 0 ++ def f(): ++ nonlocal x ++ nonlocal x, y ++ ++ def testAssert(self): ++ # assert_stmt: 'assert' test [',' test] ++ assert 1 ++ assert 1, 1 ++ assert lambda x:x ++ assert 1, lambda x:x+1 ++ try: ++ assert 0, "msg" ++ except AssertionError as e: ++ self.assertEquals(e.args[0], "msg") ++ else: ++ if __debug__: ++ self.fail("AssertionError not raised by assert 0") ++ ++ ### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef ++ # Tested below ++ ++ def testIf(self): ++ # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] ++ if 1: pass ++ if 1: pass ++ else: pass ++ if 0: pass ++ elif 0: pass ++ if 0: pass ++ elif 0: pass ++ elif 0: pass ++ elif 0: pass ++ else: pass ++ ++ def testWhile(self): ++ # 'while' test ':' suite ['else' ':' suite] ++ while 0: pass ++ while 0: pass ++ else: pass ++ ++ # Issue1920: "while 0" is optimized away, ++ # ensure that the "else" clause is still present. ++ x = 0 ++ while 0: ++ x = 1 ++ else: ++ x = 2 ++ self.assertEquals(x, 2) ++ ++ def testFor(self): ++ # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] ++ for i in 1, 2, 3: pass ++ for i, j, k in (): pass ++ else: pass ++ class Squares: ++ def __init__(self, max): ++ self.max = max ++ self.sofar = [] ++ def __len__(self): return len(self.sofar) ++ def __getitem__(self, i): ++ if not 0 <= i < self.max: raise IndexError ++ n = len(self.sofar) ++ while n <= i: ++ self.sofar.append(n*n) ++ n = n+1 ++ return self.sofar[i] ++ n = 0 ++ for x in Squares(10): n = n+x ++ if n != 285: ++ self.fail('for over growing sequence') ++ ++ result = [] ++ for x, in [(1,), (2,), (3,)]: ++ result.append(x) ++ self.assertEqual(result, [1, 2, 3]) ++ ++ def testTry(self): ++ ### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] ++ ### | 'try' ':' suite 'finally' ':' suite ++ ### except_clause: 'except' [expr ['as' expr]] ++ try: ++ 1/0 ++ except ZeroDivisionError: ++ pass ++ else: ++ pass ++ try: 1/0 ++ except EOFError: pass ++ except TypeError as msg: pass ++ except RuntimeError as msg: pass ++ except: pass ++ else: pass ++ try: 1/0 ++ except (EOFError, TypeError, ZeroDivisionError): pass ++ try: 1/0 ++ except (EOFError, TypeError, ZeroDivisionError) as msg: pass ++ try: pass ++ finally: pass ++ ++ def testSuite(self): ++ # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT ++ if 1: pass ++ if 1: ++ pass ++ if 1: ++ # ++ # ++ # ++ pass ++ pass ++ # ++ pass ++ # ++ ++ def testTest(self): ++ ### and_test ('or' and_test)* ++ ### and_test: not_test ('and' not_test)* ++ ### not_test: 'not' not_test | comparison ++ if not 1: pass ++ if 1 and 1: pass ++ if 1 or 1: pass ++ if not not not 1: pass ++ if not 1 and 1 and 1: pass ++ if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass ++ ++ def testComparison(self): ++ ### comparison: expr (comp_op expr)* ++ ### comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is'|'is' 'not' ++ if 1: pass ++ x = (1 == 1) ++ if 1 == 1: pass ++ if 1 != 1: pass ++ if 1 < 1: pass ++ if 1 > 1: pass ++ if 1 <= 1: pass ++ if 1 >= 1: pass ++ if 1 is 1: pass ++ if 1 is not 1: pass ++ if 1 in (): pass ++ if 1 not in (): pass ++ if 1 < 1 > 1 == 1 >= 1 <= 1 != 1 in 1 not in 1 is 1 is not 1: pass ++ ++ def testBinaryMaskOps(self): ++ x = 1 & 1 ++ x = 1 ^ 1 ++ x = 1 | 1 ++ ++ def testShiftOps(self): ++ x = 1 << 1 ++ x = 1 >> 1 ++ x = 1 << 1 >> 1 ++ ++ def testAdditiveOps(self): ++ x = 1 ++ x = 1 + 1 ++ x = 1 - 1 - 1 ++ x = 1 - 1 + 1 - 1 + 1 ++ ++ def testMultiplicativeOps(self): ++ x = 1 * 1 ++ x = 1 / 1 ++ x = 1 % 1 ++ x = 1 / 1 * 1 % 1 ++ ++ def testUnaryOps(self): ++ x = +1 ++ x = -1 ++ x = ~1 ++ x = ~1 ^ 1 & 1 | 1 & 1 ^ -1 ++ x = -1*1/1 + 1*1 - ---1*1 ++ ++ def testSelectors(self): ++ ### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME ++ ### subscript: expr | [expr] ':' [expr] ++ ++ import sys, time ++ c = sys.path[0] ++ x = time.time() ++ x = sys.modules['time'].time() ++ a = '01234' ++ c = a[0] ++ c = a[-1] ++ s = a[0:5] ++ s = a[:5] ++ s = a[0:] ++ s = a[:] ++ s = a[-5:] ++ s = a[:-1] ++ s = a[-4:-3] ++ # A rough test of SF bug 1333982. http://python.org/sf/1333982 ++ # The testing here is fairly incomplete. ++ # Test cases should include: commas with 1 and 2 colons ++ d = {} ++ d[1] = 1 ++ d[1,] = 2 ++ d[1,2] = 3 ++ d[1,2,3] = 4 ++ L = list(d) ++ L.sort(key=lambda x: x if isinstance(x, tuple) else ()) ++ self.assertEquals(str(L), '[1, (1,), (1, 2), (1, 2, 3)]') ++ ++ def testAtoms(self): ++ ### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictsetmaker] '}' | NAME | NUMBER | STRING ++ ### dictsetmaker: (test ':' test (',' test ':' test)* [',']) | (test (',' test)* [',']) ++ ++ x = (1) ++ x = (1 or 2 or 3) ++ x = (1 or 2 or 3, 2, 3) ++ ++ x = [] ++ x = [1] ++ x = [1 or 2 or 3] ++ x = [1 or 2 or 3, 2, 3] ++ x = [] ++ ++ x = {} ++ x = {'one': 1} ++ x = {'one': 1,} ++ x = {'one' or 'two': 1 or 2} ++ x = {'one': 1, 'two': 2} ++ x = {'one': 1, 'two': 2,} ++ x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6} ++ ++ x = {'one'} ++ x = {'one', 1,} ++ x = {'one', 'two', 'three'} ++ x = {2, 3, 4,} ++ ++ x = x ++ x = 'x' ++ x = 123 ++ ++ ### exprlist: expr (',' expr)* [','] ++ ### testlist: test (',' test)* [','] ++ # These have been exercised enough above ++ ++ def testClassdef(self): ++ # 'class' NAME ['(' [testlist] ')'] ':' suite ++ class B: pass ++ class B2(): pass ++ class C1(B): pass ++ class C2(B): pass ++ class D(C1, C2, B): pass ++ class C: ++ def meth1(self): pass ++ def meth2(self, arg): pass ++ def meth3(self, a1, a2): pass ++ ++ # decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE ++ # decorators: decorator+ ++ # decorated: decorators (classdef | funcdef) ++ def class_decorator(x): return x ++ @class_decorator ++ class G: pass ++ ++ def testDictcomps(self): ++ # dictorsetmaker: ( (test ':' test (comp_for | ++ # (',' test ':' test)* [','])) | ++ # (test (comp_for | (',' test)* [','])) ) ++ nums = [1, 2, 3] ++ self.assertEqual({i:i+1 for i in nums}, {1: 2, 2: 3, 3: 4}) ++ ++ def testListcomps(self): ++ # list comprehension tests ++ nums = [1, 2, 3, 4, 5] ++ strs = ["Apple", "Banana", "Coconut"] ++ spcs = [" Apple", " Banana ", "Coco nut "] ++ ++ self.assertEqual([s.strip() for s in spcs], ['Apple', 'Banana', 'Coco nut']) ++ self.assertEqual([3 * x for x in nums], [3, 6, 9, 12, 15]) ++ self.assertEqual([x for x in nums if x > 2], [3, 4, 5]) ++ self.assertEqual([(i, s) for i in nums for s in strs], ++ [(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'), ++ (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'), ++ (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'), ++ (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'), ++ (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')]) ++ self.assertEqual([(i, s) for i in nums for s in [f for f in strs if "n" in f]], ++ [(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'), ++ (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'), ++ (5, 'Banana'), (5, 'Coconut')]) ++ self.assertEqual([(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)], ++ [[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]]) ++ ++ def test_in_func(l): ++ return [0 < x < 3 for x in l if x > 2] ++ ++ self.assertEqual(test_in_func(nums), [False, False, False]) ++ ++ def test_nested_front(): ++ self.assertEqual([[y for y in [x, x + 1]] for x in [1,3,5]], ++ [[1, 2], [3, 4], [5, 6]]) ++ ++ test_nested_front() ++ ++ check_syntax_error(self, "[i, s for i in nums for s in strs]") ++ check_syntax_error(self, "[x if y]") ++ ++ suppliers = [ ++ (1, "Boeing"), ++ (2, "Ford"), ++ (3, "Macdonalds") ++ ] ++ ++ parts = [ ++ (10, "Airliner"), ++ (20, "Engine"), ++ (30, "Cheeseburger") ++ ] ++ ++ suppart = [ ++ (1, 10), (1, 20), (2, 20), (3, 30) ++ ] ++ ++ x = [ ++ (sname, pname) ++ for (sno, sname) in suppliers ++ for (pno, pname) in parts ++ for (sp_sno, sp_pno) in suppart ++ if sno == sp_sno and pno == sp_pno ++ ] ++ ++ self.assertEqual(x, [('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), ++ ('Macdonalds', 'Cheeseburger')]) ++ ++ def testGenexps(self): ++ # generator expression tests ++ g = ([x for x in range(10)] for x in range(1)) ++ self.assertEqual(next(g), [x for x in range(10)]) ++ try: ++ next(g) ++ self.fail('should produce StopIteration exception') ++ except StopIteration: ++ pass ++ ++ a = 1 ++ try: ++ g = (a for d in a) ++ next(g) ++ self.fail('should produce TypeError') ++ except TypeError: ++ pass ++ ++ self.assertEqual(list((x, y) for x in 'abcd' for y in 'abcd'), [(x, y) for x in 'abcd' for y in 'abcd']) ++ self.assertEqual(list((x, y) for x in 'ab' for y in 'xy'), [(x, y) for x in 'ab' for y in 'xy']) ++ ++ a = [x for x in range(10)] ++ b = (x for x in (y for y in a)) ++ self.assertEqual(sum(b), sum([x for x in range(10)])) ++ ++ self.assertEqual(sum(x**2 for x in range(10)), sum([x**2 for x in range(10)])) ++ self.assertEqual(sum(x*x for x in range(10) if x%2), sum([x*x for x in range(10) if x%2])) ++ self.assertEqual(sum(x for x in (y for y in range(10))), sum([x for x in range(10)])) ++ self.assertEqual(sum(x for x in (y for y in (z for z in range(10)))), sum([x for x in range(10)])) ++ self.assertEqual(sum(x for x in [y for y in (z for z in range(10))]), sum([x for x in range(10)])) ++ self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True)) if True), sum([x for x in range(10)])) ++ self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True) if False) if True), 0) ++ check_syntax_error(self, "foo(x for x in range(10), 100)") ++ check_syntax_error(self, "foo(100, x for x in range(10))") ++ ++ def testComprehensionSpecials(self): ++ # test for outmost iterable precomputation ++ x = 10; g = (i for i in range(x)); x = 5 ++ self.assertEqual(len(list(g)), 10) ++ ++ # This should hold, since we're only precomputing outmost iterable. ++ x = 10; t = False; g = ((i,j) for i in range(x) if t for j in range(x)) ++ x = 5; t = True; ++ self.assertEqual([(i,j) for i in range(10) for j in range(5)], list(g)) ++ ++ # Grammar allows multiple adjacent 'if's in listcomps and genexps, ++ # even though it's silly. Make sure it works (ifelse broke this.) ++ self.assertEqual([ x for x in range(10) if x % 2 if x % 3 ], [1, 5, 7]) ++ self.assertEqual(list(x for x in range(10) if x % 2 if x % 3), [1, 5, 7]) ++ ++ # verify unpacking single element tuples in listcomp/genexp. ++ self.assertEqual([x for x, in [(4,), (5,), (6,)]], [4, 5, 6]) ++ self.assertEqual(list(x for x, in [(7,), (8,), (9,)]), [7, 8, 9]) ++ ++ def testIfElseExpr(self): ++ # Test ifelse expressions in various cases ++ def _checkeval(msg, ret): ++ "helper to check that evaluation of expressions is done correctly" ++ print(x) ++ return ret ++ ++ # the next line is not allowed anymore ++ #self.assertEqual([ x() for x in lambda: True, lambda: False if x() ], [True]) ++ self.assertEqual([ x() for x in (lambda: True, lambda: False) if x() ], [True]) ++ self.assertEqual([ x(False) for x in (lambda x: False if x else True, lambda x: True if x else False) if x(False) ], [True]) ++ self.assertEqual((5 if 1 else _checkeval("check 1", 0)), 5) ++ self.assertEqual((_checkeval("check 2", 0) if 0 else 5), 5) ++ self.assertEqual((5 and 6 if 0 else 1), 1) ++ self.assertEqual(((5 and 6) if 0 else 1), 1) ++ self.assertEqual((5 and (6 if 1 else 1)), 6) ++ self.assertEqual((0 or _checkeval("check 3", 2) if 0 else 3), 3) ++ self.assertEqual((1 or _checkeval("check 4", 2) if 1 else _checkeval("check 5", 3)), 1) ++ self.assertEqual((0 or 5 if 1 else _checkeval("check 6", 3)), 5) ++ self.assertEqual((not 5 if 1 else 1), False) ++ self.assertEqual((not 5 if 0 else 1), 1) ++ self.assertEqual((6 + 1 if 1 else 2), 7) ++ self.assertEqual((6 - 1 if 1 else 2), 5) ++ self.assertEqual((6 * 2 if 1 else 4), 12) ++ self.assertEqual((6 / 2 if 1 else 3), 3) ++ self.assertEqual((6 < 4 if 0 else 2), 2) ++ ++ ++def test_main(): ++ run_unittest(TokenTests, GrammarTests) ++ ++if __name__ == '__main__': ++ test_main() +diff -r 531f2e948299 refactor/tests/pytree_idempotency.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/pytree_idempotency.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,92 @@ ++#!/usr/bin/env python2.5 ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Main program for testing the infrastructure.""" ++ ++__author__ = "Guido van Rossum " ++ ++# Support imports (need to be imported first) ++from . import support ++ ++# Python imports ++import os ++import sys ++import logging ++ ++# Local imports ++from .. import pytree ++import pgen2 ++from pgen2 import driver ++ ++logging.basicConfig() ++ ++def main(): ++ gr = driver.load_grammar("Grammar.txt") ++ dr = driver.Driver(gr, convert=pytree.convert) ++ ++ fn = "example.py" ++ tree = dr.parse_file(fn, debug=True) ++ if not diff(fn, tree): ++ print "No diffs." ++ if not sys.argv[1:]: ++ return # Pass a dummy argument to run the complete test suite below ++ ++ problems = [] ++ ++ # Process every imported module ++ for name in sys.modules: ++ mod = sys.modules[name] ++ if mod is None or not hasattr(mod, "__file__"): ++ continue ++ fn = mod.__file__ ++ if fn.endswith(".pyc"): ++ fn = fn[:-1] ++ if not fn.endswith(".py"): ++ continue ++ print >>sys.stderr, "Parsing", fn ++ tree = dr.parse_file(fn, debug=True) ++ if diff(fn, tree): ++ problems.append(fn) ++ ++ # Process every single module on sys.path (but not in packages) ++ for dir in sys.path: ++ try: ++ names = os.listdir(dir) ++ except os.error: ++ continue ++ print >>sys.stderr, "Scanning", dir, "..." ++ for name in names: ++ if not name.endswith(".py"): ++ continue ++ print >>sys.stderr, "Parsing", name ++ fn = os.path.join(dir, name) ++ try: ++ tree = dr.parse_file(fn, debug=True) ++ except pgen2.parse.ParseError, err: ++ print "ParseError:", err ++ else: ++ if diff(fn, tree): ++ problems.append(fn) ++ ++ # Show summary of problem files ++ if not problems: ++ print "No problems. Congratulations!" ++ else: ++ print "Problems in following files:" ++ for fn in problems: ++ print "***", fn ++ ++def diff(fn, tree): ++ f = open("@", "w") ++ try: ++ f.write(str(tree)) ++ finally: ++ f.close() ++ try: ++ return os.system("diff -u %s @" % fn) ++ finally: ++ os.remove("@") ++ ++if __name__ == "__main__": ++ main() +diff -r 531f2e948299 refactor/tests/support.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/support.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,78 @@ ++"""Support code for test_*.py files""" ++# Original Author: Collin Winter ++ ++# Python imports ++import unittest ++import sys ++import os ++import os.path ++import re ++from textwrap import dedent ++ ++#sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) ++ ++# Local imports ++from .. import pytree ++from .. import refactor ++from ..pgen2 import driver ++ ++test_pkg = "refactor.fixes" ++test_dir = os.path.dirname(__file__) ++proj_dir = os.path.normpath(os.path.join(test_dir, "..")) ++grammar_path = os.path.join(test_dir, "..", "Grammar.txt") ++grammar = driver.load_grammar(grammar_path) ++driver = driver.Driver(grammar, convert=pytree.convert) ++ ++def parse_version(version_string): ++ """Returns a version tuple matching input version_string.""" ++ if not version_string: ++ return () ++ ++ version_list = [] ++ for token in version_string.split('.'): ++ try: ++ version_list.append(int(token)) ++ except ValueError: ++ version_list.append(token) ++ return tuple(version_list) ++ ++def parse_string(string): ++ return driver.parse_string(reformat(string), debug=True) ++ ++# Python 2.3's TestSuite is not iter()-able ++if sys.version_info < (2, 4): ++ def TestSuite_iter(self): ++ return iter(self._tests) ++ unittest.TestSuite.__iter__ = TestSuite_iter ++ ++def run_all_tests(test_mod=None, tests=None): ++ if tests is None: ++ tests = unittest.TestLoader().loadTestsFromModule(test_mod) ++ unittest.TextTestRunner(verbosity=2).run(tests) ++ ++def reformat(string): ++ return dedent(string) + "\n\n" ++ ++def get_refactorer(fixers=None, options=None, pkg_name=None): ++ """ ++ A convenience function for creating a RefactoringTool for tests. ++ ++ fixers is a list of fixers for the RefactoringTool to use. By default ++ "refactor.fixes.*" is used. options is an optional dictionary of options to ++ be passed to the RefactoringTool. ++ """ ++ pkg_name = pkg_name or test_pkg ++ if fixers is not None: ++ fixers = [pkg_name + ".fix_" + fix for fix in fixers] ++ else: ++ fixers = refactor.get_fixers_from_package(pkg_name) ++ options = options or {} ++ return refactor.RefactoringTool(fixers, options, explicit=True) ++ ++def all_project_files(): ++ for dirpath, dirnames, filenames in os.walk(proj_dir): ++ for filename in filenames: ++ if filename.endswith(".py"): ++ yield os.path.join(dirpath, filename) ++ ++TestCase = unittest.TestCase +diff -r 531f2e948299 refactor/tests/test_all_fixers.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/test_all_fixers.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,35 @@ ++#!/usr/bin/env python2.5 ++"""Tests that run all fixer modules over an input stream. ++ ++This has been broken out into its own test module because of its ++running time. ++""" ++# Author: Collin Winter ++ ++# Testing imports ++try: ++ from . import support ++except ImportError: ++ import support ++ ++# Python imports ++import unittest ++ ++# Local imports ++from .. import pytree ++from .. import refactor ++ ++class Test_all(support.TestCase): ++ def setUp(self): ++ options = {"print_function" : False} ++ self.refactor = support.get_refactorer(options=options) ++ ++ def test_all_project_files(self): ++ for filepath in support.all_project_files(): ++ print "Fixing %s..." % filepath ++ self.refactor.refactor_string(open(filepath).read(), filepath) ++ ++ ++if __name__ == "__main__": ++ import __main__ ++ support.run_all_tests(__main__) +diff -r 531f2e948299 refactor/tests/test_fixers.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/test_fixers.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,222 @@ ++#!/usr/bin/env python2.5 ++""" Test suite for the fixer modules """ ++# Original Author: Collin Winter ++ ++# Testing imports ++try: ++ from tests import support ++except ImportError: ++ import support ++ ++# Python imports ++import os ++import unittest ++from itertools import chain ++from operator import itemgetter ++ ++# Local imports ++from .. import pygram, pytree, refactor, fixer_util ++ ++class FixerTestCase(support.TestCase): ++ old_version = (3, 0) ++ new_version = (2, 5) ++ ++ def setUp(self, fix_list=None): ++ if fix_list is None: ++ fix_list = [self.fixer] ++ options = {"print_function" : False} ++ pkg_name = self.get_pkg_name() ++ self.refactor = support.get_refactorer(fix_list, options, ++ pkg_name=pkg_name) ++ self.fixer_log = [] ++ self.filename = "" ++ ++ for fixer in chain(self.refactor.pre_order, ++ self.refactor.post_order): ++ fixer.log = self.fixer_log ++ ++ def _check(self, versions, ignore_warnings=False): ++ """Verifying a fix matches before and after version ++ ++ versions is a dict mapping version tuples to sample code. ++ ++ Example: ++ check({ (3, 0): 'print()', ++ (2,3): 'print' }) ++ # The same dict applies for 3.x to 2.x and vice versa ++ """ ++ before = self.price_is_right(versions, self.old_version) ++ after = self.price_is_right(versions, self.new_version) ++ ++ # Quit now if neither before nor after won the Price is Right. ++ if before == None or after == None: ++ return ++ ++ before = support.reformat(before) ++ after = support.reformat(after) ++ ++ tree = self.refactor.refactor_string(before, self.filename) ++ self.failUnlessEqual(after, str(tree)) ++ if not ignore_warnings: ++ self.failUnlessEqual(self.fixer_log, []) ++ return tree ++ ++ ++ def price_is_right(self, versions, target_version): ++ """Return the closest version in versions without going over target ++ """ ++ snippet = None ++ for version_key in sorted(versions.keys()): ++ if version_key > target_version: ++ break ++ snippet = versions[version_key] ++ return snippet ++ ++ def check(self, up, down): ++ if self.old_version > self.new_version: ++ self._check(down) ++ elif self.old_version < self.new_version: ++ self._check(up) ++ else: ++ self._check(down) ++ self._check(up) ++ ++ def get_pkg_name(self): ++ if self.old_version >= (3, 0): ++ return 'refactor.fixes.from3' ++ else: ++ return 'refactor.fixes.from2' ++ ++ def warns(self, before, after, message, unchanged=False): ++ tree = self._check(before, after) ++ self.failUnless(message in "".join(self.fixer_log)) ++ if not unchanged: ++ self.failUnless(tree.was_changed) ++ ++ def warns_unchanged(self, before, message): ++ self.warns(before, before, message, unchanged=True) ++ ++ def unchanged(self, before, ignore_warnings=False): ++ self._check(before, before) ++ if not ignore_warnings: ++ self.failUnlessEqual(self.fixer_log, []) ++ ++ def assert_runs_after(self, *names): ++ fixes = [self.fixer] ++ fixes.extend(names) ++ options = {"print_function" : False} ++ r = support.get_refactorer(fixes, options) ++ (pre, post) = r.get_fixers() ++ n = "fix_" + self.fixer ++ if post and post[-1].__class__.__module__.endswith(n): ++ # We're the last fixer to run ++ return ++ if pre and pre[-1].__class__.__module__.endswith(n) and not post: ++ # We're the last in pre and post is empty ++ return ++ self.fail("Fixer run order (%s) is incorrect; %s should be last."\ ++ %(", ".join([x.__class__.__module__ for x in (pre+post)]), n)) ++ ++class Test_range(FixerTestCase): ++ fixer = "range" ++ ++ def test_xrange(self): ++ up = {} ++ down = { ++ (2, 5): """x = xrange(0, 10, 2)""", ++ (3, 0): """x = range(0, 10, 2)""", ++ } ++ self.check(up, down) ++ ++ def test_range(self): ++ up = {} ++ down = { ++ (2, 5): """x = list(xrange(0, 10, 2))""", ++ (3, 0): """x = list(range(0, 10, 2))""", ++ } ++ self.check(up, down) ++ ++class Test_renames(FixerTestCase): ++ fixer = "renames" ++ ++ def test_maxint(self): ++ up = {} ++ down = { ++ (2, 5): """sys.maxint""", ++ (2, 6): """sys.maxsize""", ++ } ++ self.check(up, down) ++ ++class Test_print(FixerTestCase): ++ """ ++ http://docs.python.org/3.0/whatsnew/3.0.html ++ ++ Old: print "The answer is", 2*2 ++ New: print("The answer is", 2*2) ++ ++ Old: print x, # Trailing comma suppresses newline ++ New: print(x, end=" ") # Appends a space instead of a newline ++ ++ Old: print # Prints a newline ++ New: print() # You must call the function! ++ ++ Old: print >>sys.stderr, "fatal error" ++ New: print("fatal error", file=sys.stderr) ++ ++ Old: print (x, y) # prints repr((x, y)) ++ New: print((x, y)) # Not the same as print(x, y)! ++ """ ++ ++ fixer = "print" ++ ++ def test_func(self): ++ up = {} ++ down = { ++ (2, 5): """print""", ++ (3, 0): """print()""", ++ } ++ self.check(up, down) ++ ++ def test_x(self): ++ up = {} ++ down = { ++ (2, 5): """print x""", ++ (3, 0): """print(x)""", ++ } ++ self.check(up, down) ++ ++ def test_str(self): ++ up = {} ++ down = { ++ (2, 5): """print ''""", ++ (3, 0): """print('')""", ++ } ++ self.check(up, down) ++ ++ def test_compound(self): ++ up = {} ++ down = { ++ (2, 5): """print "The answer is", 2*2""", ++ (3, 0): """print("The answer is", 2*2)""", ++ } ++ self.check(up, down) ++ ++ def test_end(self): ++ up = {} ++ down = { ++ (2, 5): """print x, """, ++ (3, 0): """print(x, end=" ")""", ++ } ++ self.check(up, down) ++ ++ def test_stderr(self): ++ up = {} ++ down = { ++ (2, 5): """print >>sys.stderr, 'fatal error'""", ++ (3, 0): """print('fatal error', file=sys.stderr)""", ++ } ++ self.check(up, down) ++ ++if __name__ == "__main__": ++ import __main__ ++ support.run_all_tests(__main__) +diff -r 531f2e948299 refactor/tests/test_parser.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/test_parser.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,202 @@ ++#!/usr/bin/env python2.5 ++"""Test suite for refactor's parser and grammar files. ++ ++This is the place to add tests for changes to refactor's grammar, such as those ++merging the grammars for Python 2 and 3. In addition to specific tests for ++parts of the grammar we've changed, we also make sure we can parse the ++test_grammar.py files from both Python 2 and Python 3. ++""" ++# Author: Collin Winter ++ ++# Testing imports ++from . import support ++from .support import driver, test_dir ++ ++# Python imports ++import os ++import os.path ++ ++# Local imports ++from ..pgen2.parse import ParseError ++ ++ ++class GrammarTest(support.TestCase): ++ def validate(self, code): ++ support.parse_string(code) ++ ++ def invalid_syntax(self, code): ++ try: ++ self.validate(code) ++ except ParseError: ++ pass ++ else: ++ raise AssertionError("Syntax shouldn't have been valid") ++ ++ ++class TestRaiseChanges(GrammarTest): ++ def test_2x_style_1(self): ++ self.validate("raise") ++ ++ def test_2x_style_2(self): ++ self.validate("raise E, V") ++ ++ def test_2x_style_3(self): ++ self.validate("raise E, V, T") ++ ++ def test_2x_style_invalid_1(self): ++ self.invalid_syntax("raise E, V, T, Z") ++ ++ def test_3x_style(self): ++ self.validate("raise E1 from E2") ++ ++ def test_3x_style_invalid_1(self): ++ self.invalid_syntax("raise E, V from E1") ++ ++ def test_3x_style_invalid_2(self): ++ self.invalid_syntax("raise E from E1, E2") ++ ++ def test_3x_style_invalid_3(self): ++ self.invalid_syntax("raise from E1, E2") ++ ++ def test_3x_style_invalid_4(self): ++ self.invalid_syntax("raise E from") ++ ++ ++# Adapated from Python 3's Lib/test/test_grammar.py:GrammarTests.testFuncdef ++class TestFunctionAnnotations(GrammarTest): ++ def test_1(self): ++ self.validate("""def f(x) -> list: pass""") ++ ++ def test_2(self): ++ self.validate("""def f(x:int): pass""") ++ ++ def test_3(self): ++ self.validate("""def f(*x:str): pass""") ++ ++ def test_4(self): ++ self.validate("""def f(**x:float): pass""") ++ ++ def test_5(self): ++ self.validate("""def f(x, y:1+2): pass""") ++ ++ def test_6(self): ++ self.validate("""def f(a, (b:1, c:2, d)): pass""") ++ ++ def test_7(self): ++ self.validate("""def f(a, (b:1, c:2, d), e:3=4, f=5, *g:6): pass""") ++ ++ def test_8(self): ++ s = """def f(a, (b:1, c:2, d), e:3=4, f=5, ++ *g:6, h:7, i=8, j:9=10, **k:11) -> 12: pass""" ++ self.validate(s) ++ ++ ++class TestExcept(GrammarTest): ++ def test_new(self): ++ s = """ ++ try: ++ x ++ except E as N: ++ y""" ++ self.validate(s) ++ ++ def test_old(self): ++ s = """ ++ try: ++ x ++ except E, N: ++ y""" ++ self.validate(s) ++ ++ ++# Adapted from Python 3's Lib/test/test_grammar.py:GrammarTests.testAtoms ++class TestSetLiteral(GrammarTest): ++ def test_1(self): ++ self.validate("""x = {'one'}""") ++ ++ def test_2(self): ++ self.validate("""x = {'one', 1,}""") ++ ++ def test_3(self): ++ self.validate("""x = {'one', 'two', 'three'}""") ++ ++ def test_4(self): ++ self.validate("""x = {2, 3, 4,}""") ++ ++ ++class TestNumericLiterals(GrammarTest): ++ def test_new_octal_notation(self): ++ self.validate("""0o7777777777777""") ++ self.invalid_syntax("""0o7324528887""") ++ ++ def test_new_binary_notation(self): ++ self.validate("""0b101010""") ++ self.invalid_syntax("""0b0101021""") ++ ++ ++class TestClassDef(GrammarTest): ++ def test_new_syntax(self): ++ self.validate("class B(t=7): pass") ++ self.validate("class B(t, *args): pass") ++ self.validate("class B(t, **kwargs): pass") ++ self.validate("class B(t, *args, **kwargs): pass") ++ self.validate("class B(t, y=9, *args, **kwargs): pass") ++ ++ ++class TestParserIdempotency(support.TestCase): ++ ++ """A cut-down version of pytree_idempotency.py.""" ++ ++ def test_all_project_files(self): ++ for filepath in support.all_project_files(): ++ print "Parsing %s..." % filepath ++ tree = driver.parse_file(filepath, debug=True) ++ if diff(filepath, tree): ++ self.fail("Idempotency failed: %s" % filepath) ++ ++ ++class TestLiterals(GrammarTest): ++ ++ def test_multiline_bytes_literals(self): ++ s = """ ++ md5test(b"\xaa" * 80, ++ (b"Test Using Larger Than Block-Size Key " ++ b"and Larger Than One Block-Size Data"), ++ "6f630fad67cda0ee1fb1f562db3aa53e") ++ """ ++ self.validate(s) ++ ++ def test_multiline_bytes_tripquote_literals(self): ++ s = ''' ++ b""" ++ ++ ++ """ ++ ''' ++ self.validate(s) ++ ++ def test_multiline_str_literals(self): ++ s = """ ++ md5test("\xaa" * 80, ++ ("Test Using Larger Than Block-Size Key " ++ "and Larger Than One Block-Size Data"), ++ "6f630fad67cda0ee1fb1f562db3aa53e") ++ """ ++ self.validate(s) ++ ++ ++def diff(fn, tree): ++ f = open("@", "w") ++ try: ++ f.write(str(tree)) ++ finally: ++ f.close() ++ try: ++ return os.system("diff -u %s @" % fn) ++ finally: ++ os.remove("@") ++ ++ ++if __name__ == "__main__": ++ import __main__ ++ support.run_all_tests(__main__) +diff -r 531f2e948299 refactor/tests/test_pytree.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/test_pytree.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,458 @@ ++#!/usr/bin/env python2.5 ++# Copyright 2006 Google, Inc. All Rights Reserved. ++# Licensed to PSF under a Contributor Agreement. ++ ++"""Unit tests for pytree.py. ++ ++NOTE: Please *don't* add doc strings to individual test methods! ++In verbose mode, printing of the module, class and method name is much ++more helpful than printing of (the first line of) the docstring, ++especially when debugging a test. ++""" ++ ++# Testing imports ++from . import support ++ ++# Local imports (XXX should become a package) ++from .. import pytree ++ ++try: ++ sorted ++except NameError: ++ def sorted(lst): ++ l = list(lst) ++ l.sort() ++ return l ++ ++class TestNodes(support.TestCase): ++ ++ """Unit tests for nodes (Base, Leaf, Node).""" ++ ++ def testBaseCantConstruct(self): ++ if __debug__: ++ # Test that instantiating Base() raises an AssertionError ++ self.assertRaises(AssertionError, pytree.Base) ++ ++ def testLeaf(self): ++ l1 = pytree.Leaf(100, "foo") ++ self.assertEqual(l1.type, 100) ++ self.assertEqual(l1.value, "foo") ++ ++ def testLeafRepr(self): ++ l1 = pytree.Leaf(100, "foo") ++ self.assertEqual(repr(l1), "Leaf(100, 'foo')") ++ ++ def testLeafStr(self): ++ l1 = pytree.Leaf(100, "foo") ++ self.assertEqual(str(l1), "foo") ++ l2 = pytree.Leaf(100, "foo", context=(" ", (10, 1))) ++ self.assertEqual(str(l2), " foo") ++ ++ def testLeafStrNumericValue(self): ++ # Make sure that the Leaf's value is stringified. Failing to ++ # do this can cause a TypeError in certain situations. ++ l1 = pytree.Leaf(2, 5) ++ l1.set_prefix("foo_") ++ self.assertEqual(str(l1), "foo_5") ++ ++ def testLeafEq(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "foo", context=(" ", (1, 0))) ++ self.assertEqual(l1, l2) ++ l3 = pytree.Leaf(101, "foo") ++ l4 = pytree.Leaf(100, "bar") ++ self.assertNotEqual(l1, l3) ++ self.assertNotEqual(l1, l4) ++ ++ def testLeafPrefix(self): ++ l1 = pytree.Leaf(100, "foo") ++ self.assertEqual(l1.get_prefix(), "") ++ self.failIf(l1.was_changed) ++ l1.set_prefix(" ##\n\n") ++ self.assertEqual(l1.get_prefix(), " ##\n\n") ++ self.failUnless(l1.was_changed) ++ ++ def testNode(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(200, "bar") ++ n1 = pytree.Node(1000, [l1, l2]) ++ self.assertEqual(n1.type, 1000) ++ self.assertEqual(n1.children, [l1, l2]) ++ ++ def testNodeRepr(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "bar", context=(" ", (1, 0))) ++ n1 = pytree.Node(1000, [l1, l2]) ++ self.assertEqual(repr(n1), ++ "Node(1000, [%s, %s])" % (repr(l1), repr(l2))) ++ ++ def testNodeStr(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "bar", context=(" ", (1, 0))) ++ n1 = pytree.Node(1000, [l1, l2]) ++ self.assertEqual(str(n1), "foo bar") ++ ++ def testNodePrefix(self): ++ l1 = pytree.Leaf(100, "foo") ++ self.assertEqual(l1.get_prefix(), "") ++ n1 = pytree.Node(1000, [l1]) ++ self.assertEqual(n1.get_prefix(), "") ++ n1.set_prefix(" ") ++ self.assertEqual(n1.get_prefix(), " ") ++ self.assertEqual(l1.get_prefix(), " ") ++ ++ def testGetSuffix(self): ++ l1 = pytree.Leaf(100, "foo", prefix="a") ++ l2 = pytree.Leaf(100, "bar", prefix="b") ++ n1 = pytree.Node(1000, [l1, l2]) ++ ++ self.assertEqual(l1.get_suffix(), l2.get_prefix()) ++ self.assertEqual(l2.get_suffix(), "") ++ self.assertEqual(n1.get_suffix(), "") ++ ++ l3 = pytree.Leaf(100, "bar", prefix="c") ++ n2 = pytree.Node(1000, [n1, l3]) ++ ++ self.assertEqual(n1.get_suffix(), l3.get_prefix()) ++ self.assertEqual(l3.get_suffix(), "") ++ self.assertEqual(n2.get_suffix(), "") ++ ++ def testNodeEq(self): ++ n1 = pytree.Node(1000, ()) ++ n2 = pytree.Node(1000, [], context=(" ", (1, 0))) ++ self.assertEqual(n1, n2) ++ n3 = pytree.Node(1001, ()) ++ self.assertNotEqual(n1, n3) ++ ++ def testNodeEqRecursive(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "foo") ++ n1 = pytree.Node(1000, [l1]) ++ n2 = pytree.Node(1000, [l2]) ++ self.assertEqual(n1, n2) ++ l3 = pytree.Leaf(100, "bar") ++ n3 = pytree.Node(1000, [l3]) ++ self.assertNotEqual(n1, n3) ++ ++ def testReplace(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "+") ++ l3 = pytree.Leaf(100, "bar") ++ n1 = pytree.Node(1000, [l1, l2, l3]) ++ self.assertEqual(n1.children, [l1, l2, l3]) ++ self.failUnless(isinstance(n1.children, list)) ++ self.failIf(n1.was_changed) ++ l2new = pytree.Leaf(100, "-") ++ l2.replace(l2new) ++ self.assertEqual(n1.children, [l1, l2new, l3]) ++ self.failUnless(isinstance(n1.children, list)) ++ self.failUnless(n1.was_changed) ++ ++ def testReplaceWithList(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "+") ++ l3 = pytree.Leaf(100, "bar") ++ n1 = pytree.Node(1000, [l1, l2, l3]) ++ ++ l2.replace([pytree.Leaf(100, "*"), pytree.Leaf(100, "*")]) ++ self.assertEqual(str(n1), "foo**bar") ++ self.failUnless(isinstance(n1.children, list)) ++ ++ def testPostOrder(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "bar") ++ n1 = pytree.Node(1000, [l1, l2]) ++ self.assertEqual(list(n1.post_order()), [l1, l2, n1]) ++ ++ def testPreOrder(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "bar") ++ n1 = pytree.Node(1000, [l1, l2]) ++ self.assertEqual(list(n1.pre_order()), [n1, l1, l2]) ++ ++ def testChangedLeaf(self): ++ l1 = pytree.Leaf(100, "f") ++ self.failIf(l1.was_changed) ++ ++ l1.changed() ++ self.failUnless(l1.was_changed) ++ ++ def testChangedNode(self): ++ l1 = pytree.Leaf(100, "f") ++ n1 = pytree.Node(1000, [l1]) ++ self.failIf(n1.was_changed) ++ ++ n1.changed() ++ self.failUnless(n1.was_changed) ++ ++ def testChangedRecursive(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "+") ++ l3 = pytree.Leaf(100, "bar") ++ n1 = pytree.Node(1000, [l1, l2, l3]) ++ n2 = pytree.Node(1000, [n1]) ++ self.failIf(l1.was_changed) ++ self.failIf(n1.was_changed) ++ self.failIf(n2.was_changed) ++ ++ n1.changed() ++ self.failUnless(n1.was_changed) ++ self.failUnless(n2.was_changed) ++ self.failIf(l1.was_changed) ++ ++ def testLeafConstructorPrefix(self): ++ for prefix in ("xyz_", ""): ++ l1 = pytree.Leaf(100, "self", prefix=prefix) ++ self.failUnless(str(l1), prefix + "self") ++ self.assertEqual(l1.get_prefix(), prefix) ++ ++ def testNodeConstructorPrefix(self): ++ for prefix in ("xyz_", ""): ++ l1 = pytree.Leaf(100, "self") ++ l2 = pytree.Leaf(100, "foo", prefix="_") ++ n1 = pytree.Node(1000, [l1, l2], prefix=prefix) ++ self.failUnless(str(n1), prefix + "self_foo") ++ self.assertEqual(n1.get_prefix(), prefix) ++ self.assertEqual(l1.get_prefix(), prefix) ++ self.assertEqual(l2.get_prefix(), "_") ++ ++ def testRemove(self): ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "foo") ++ n1 = pytree.Node(1000, [l1, l2]) ++ n2 = pytree.Node(1000, [n1]) ++ ++ self.assertEqual(n1.remove(), 0) ++ self.assertEqual(n2.children, []) ++ self.assertEqual(l1.parent, n1) ++ self.assertEqual(n1.parent, None) ++ self.assertEqual(n2.parent, None) ++ self.failIf(n1.was_changed) ++ self.failUnless(n2.was_changed) ++ ++ self.assertEqual(l2.remove(), 1) ++ self.assertEqual(l1.remove(), 0) ++ self.assertEqual(n1.children, []) ++ self.assertEqual(l1.parent, None) ++ self.assertEqual(n1.parent, None) ++ self.assertEqual(n2.parent, None) ++ self.failUnless(n1.was_changed) ++ self.failUnless(n2.was_changed) ++ ++ def testRemoveParentless(self): ++ n1 = pytree.Node(1000, []) ++ n1.remove() ++ self.assertEqual(n1.parent, None) ++ ++ l1 = pytree.Leaf(100, "foo") ++ l1.remove() ++ self.assertEqual(l1.parent, None) ++ ++ def testNodeSetChild(self): ++ l1 = pytree.Leaf(100, "foo") ++ n1 = pytree.Node(1000, [l1]) ++ ++ l2 = pytree.Leaf(100, "bar") ++ n1.set_child(0, l2) ++ self.assertEqual(l1.parent, None) ++ self.assertEqual(l2.parent, n1) ++ self.assertEqual(n1.children, [l2]) ++ ++ n2 = pytree.Node(1000, [l1]) ++ n2.set_child(0, n1) ++ self.assertEqual(l1.parent, None) ++ self.assertEqual(n1.parent, n2) ++ self.assertEqual(n2.parent, None) ++ self.assertEqual(n2.children, [n1]) ++ ++ self.assertRaises(IndexError, n1.set_child, 4, l2) ++ # I don't care what it raises, so long as it's an exception ++ self.assertRaises(Exception, n1.set_child, 0, list) ++ ++ def testNodeInsertChild(self): ++ l1 = pytree.Leaf(100, "foo") ++ n1 = pytree.Node(1000, [l1]) ++ ++ l2 = pytree.Leaf(100, "bar") ++ n1.insert_child(0, l2) ++ self.assertEqual(l2.parent, n1) ++ self.assertEqual(n1.children, [l2, l1]) ++ ++ l3 = pytree.Leaf(100, "abc") ++ n1.insert_child(2, l3) ++ self.assertEqual(n1.children, [l2, l1, l3]) ++ ++ # I don't care what it raises, so long as it's an exception ++ self.assertRaises(Exception, n1.insert_child, 0, list) ++ ++ def testNodeAppendChild(self): ++ n1 = pytree.Node(1000, []) ++ ++ l1 = pytree.Leaf(100, "foo") ++ n1.append_child(l1) ++ self.assertEqual(l1.parent, n1) ++ self.assertEqual(n1.children, [l1]) ++ ++ l2 = pytree.Leaf(100, "bar") ++ n1.append_child(l2) ++ self.assertEqual(l2.parent, n1) ++ self.assertEqual(n1.children, [l1, l2]) ++ ++ # I don't care what it raises, so long as it's an exception ++ self.assertRaises(Exception, n1.append_child, list) ++ ++ def testNodeNextSibling(self): ++ n1 = pytree.Node(1000, []) ++ n2 = pytree.Node(1000, []) ++ p1 = pytree.Node(1000, [n1, n2]) ++ ++ self.failUnless(n1.next_sibling is n2) ++ self.assertEqual(n2.next_sibling, None) ++ self.assertEqual(p1.next_sibling, None) ++ ++ def testLeafNextSibling(self): ++ l1 = pytree.Leaf(100, "a") ++ l2 = pytree.Leaf(100, "b") ++ p1 = pytree.Node(1000, [l1, l2]) ++ ++ self.failUnless(l1.next_sibling is l2) ++ self.assertEqual(l2.next_sibling, None) ++ self.assertEqual(p1.next_sibling, None) ++ ++ def testNodePrevSibling(self): ++ n1 = pytree.Node(1000, []) ++ n2 = pytree.Node(1000, []) ++ p1 = pytree.Node(1000, [n1, n2]) ++ ++ self.failUnless(n2.prev_sibling is n1) ++ self.assertEqual(n1.prev_sibling, None) ++ self.assertEqual(p1.prev_sibling, None) ++ ++ def testLeafPrevSibling(self): ++ l1 = pytree.Leaf(100, "a") ++ l2 = pytree.Leaf(100, "b") ++ p1 = pytree.Node(1000, [l1, l2]) ++ ++ self.failUnless(l2.prev_sibling is l1) ++ self.assertEqual(l1.prev_sibling, None) ++ self.assertEqual(p1.prev_sibling, None) ++ ++ ++class TestPatterns(support.TestCase): ++ ++ """Unit tests for tree matching patterns.""" ++ ++ def testBasicPatterns(self): ++ # Build a tree ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "bar") ++ l3 = pytree.Leaf(100, "foo") ++ n1 = pytree.Node(1000, [l1, l2]) ++ n2 = pytree.Node(1000, [l3]) ++ root = pytree.Node(1000, [n1, n2]) ++ # Build a pattern matching a leaf ++ pl = pytree.LeafPattern(100, "foo", name="pl") ++ r = {} ++ self.assertFalse(pl.match(root, results=r)) ++ self.assertEqual(r, {}) ++ self.assertFalse(pl.match(n1, results=r)) ++ self.assertEqual(r, {}) ++ self.assertFalse(pl.match(n2, results=r)) ++ self.assertEqual(r, {}) ++ self.assertTrue(pl.match(l1, results=r)) ++ self.assertEqual(r, {"pl": l1}) ++ r = {} ++ self.assertFalse(pl.match(l2, results=r)) ++ self.assertEqual(r, {}) ++ # Build a pattern matching a node ++ pn = pytree.NodePattern(1000, [pl], name="pn") ++ self.assertFalse(pn.match(root, results=r)) ++ self.assertEqual(r, {}) ++ self.assertFalse(pn.match(n1, results=r)) ++ self.assertEqual(r, {}) ++ self.assertTrue(pn.match(n2, results=r)) ++ self.assertEqual(r, {"pn": n2, "pl": l3}) ++ r = {} ++ self.assertFalse(pn.match(l1, results=r)) ++ self.assertEqual(r, {}) ++ self.assertFalse(pn.match(l2, results=r)) ++ self.assertEqual(r, {}) ++ ++ def testWildcardPatterns(self): ++ # Build a tree for testing ++ l1 = pytree.Leaf(100, "foo") ++ l2 = pytree.Leaf(100, "bar") ++ l3 = pytree.Leaf(100, "foo") ++ n1 = pytree.Node(1000, [l1, l2]) ++ n2 = pytree.Node(1000, [l3]) ++ root = pytree.Node(1000, [n1, n2]) ++ # Build a pattern ++ pl = pytree.LeafPattern(100, "foo", name="pl") ++ pn = pytree.NodePattern(1000, [pl], name="pn") ++ pw = pytree.WildcardPattern([[pn], [pl, pl]], name="pw") ++ r = {} ++ self.assertFalse(pw.match_seq([root], r)) ++ self.assertEqual(r, {}) ++ self.assertFalse(pw.match_seq([n1], r)) ++ self.assertEqual(r, {}) ++ self.assertTrue(pw.match_seq([n2], r)) ++ # These are easier to debug ++ self.assertEqual(sorted(r.keys()), ["pl", "pn", "pw"]) ++ self.assertEqual(r["pl"], l1) ++ self.assertEqual(r["pn"], n2) ++ self.assertEqual(r["pw"], [n2]) ++ # But this is equivalent ++ self.assertEqual(r, {"pl": l1, "pn": n2, "pw": [n2]}) ++ r = {} ++ self.assertTrue(pw.match_seq([l1, l3], r)) ++ self.assertEqual(r, {"pl": l3, "pw": [l1, l3]}) ++ self.assert_(r["pl"] is l3) ++ r = {} ++ ++ def testGenerateMatches(self): ++ la = pytree.Leaf(1, "a") ++ lb = pytree.Leaf(1, "b") ++ lc = pytree.Leaf(1, "c") ++ ld = pytree.Leaf(1, "d") ++ le = pytree.Leaf(1, "e") ++ lf = pytree.Leaf(1, "f") ++ leaves = [la, lb, lc, ld, le, lf] ++ root = pytree.Node(1000, leaves) ++ pa = pytree.LeafPattern(1, "a", "pa") ++ pb = pytree.LeafPattern(1, "b", "pb") ++ pc = pytree.LeafPattern(1, "c", "pc") ++ pd = pytree.LeafPattern(1, "d", "pd") ++ pe = pytree.LeafPattern(1, "e", "pe") ++ pf = pytree.LeafPattern(1, "f", "pf") ++ pw = pytree.WildcardPattern([[pa, pb, pc], [pd, pe], ++ [pa, pb], [pc, pd], [pe, pf]], ++ min=1, max=4, name="pw") ++ self.assertEqual([x[0] for x in pw.generate_matches(leaves)], ++ [3, 5, 2, 4, 6]) ++ pr = pytree.NodePattern(type=1000, content=[pw], name="pr") ++ matches = list(pytree.generate_matches([pr], [root])) ++ self.assertEqual(len(matches), 1) ++ c, r = matches[0] ++ self.assertEqual(c, 1) ++ self.assertEqual(str(r["pr"]), "abcdef") ++ self.assertEqual(r["pw"], [la, lb, lc, ld, le, lf]) ++ for c in "abcdef": ++ self.assertEqual(r["p" + c], pytree.Leaf(1, c)) ++ ++ def testHasKeyExample(self): ++ pattern = pytree.NodePattern(331, ++ (pytree.LeafPattern(7), ++ pytree.WildcardPattern(name="args"), ++ pytree.LeafPattern(8))) ++ l1 = pytree.Leaf(7, "(") ++ l2 = pytree.Leaf(3, "x") ++ l3 = pytree.Leaf(8, ")") ++ node = pytree.Node(331, [l1, l2, l3]) ++ r = {} ++ self.assert_(pattern.match(node, r)) ++ self.assertEqual(r["args"], [l2]) ++ ++ ++if __name__ == "__main__": ++ import __main__ ++ support.run_all_tests(__main__) +diff -r 531f2e948299 refactor/tests/test_refactor.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/test_refactor.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,168 @@ ++""" ++Unit tests for refactor.py. ++""" ++ ++import sys ++import os ++import operator ++import StringIO ++import tempfile ++import unittest ++ ++from .. import refactor, pygram, fixer_base ++ ++from . import support ++ ++ ++FIXER_DIR = os.path.join(os.path.dirname(__file__), "data/fixers") ++ ++sys.path.append(FIXER_DIR) ++try: ++ _DEFAULT_FIXERS = refactor.get_fixers_from_package("myfixes") ++finally: ++ sys.path.pop() ++ ++class TestRefactoringTool(unittest.TestCase): ++ ++ def setUp(self): ++ sys.path.append(FIXER_DIR) ++ ++ def tearDown(self): ++ sys.path.pop() ++ ++ def check_instances(self, instances, classes): ++ for inst, cls in zip(instances, classes): ++ if not isinstance(inst, cls): ++ self.fail("%s are not instances of %s" % instances, classes) ++ ++ def rt(self, options=None, fixers=_DEFAULT_FIXERS, explicit=None): ++ return refactor.RefactoringTool(fixers, options, explicit) ++ ++ def test_print_function_option(self): ++ gram = pygram.python_grammar ++ save = gram.keywords["print"] ++ try: ++ rt = self.rt({"print_function" : True}) ++ self.assertRaises(KeyError, operator.itemgetter("print"), ++ gram.keywords) ++ finally: ++ gram.keywords["print"] = save ++ ++ def test_fixer_loading_helpers(self): ++ contents = ["explicit", "first", "last", "parrot", "preorder"] ++ non_prefixed = refactor.get_all_fix_names("myfixes") ++ prefixed = refactor.get_all_fix_names("myfixes", False) ++ full_names = refactor.get_fixers_from_package("myfixes") ++ self.assertEqual(prefixed, ["fix_" + name for name in contents]) ++ self.assertEqual(non_prefixed, contents) ++ self.assertEqual(full_names, ++ ["myfixes.fix_" + name for name in contents]) ++ ++ def test_get_headnode_dict(self): ++ class NoneFix(fixer_base.BaseFix): ++ PATTERN = None ++ ++ class FileInputFix(fixer_base.BaseFix): ++ PATTERN = "file_input< any * >" ++ ++ no_head = NoneFix({}, []) ++ with_head = FileInputFix({}, []) ++ d = refactor.get_headnode_dict([no_head, with_head]) ++ expected = {None: [no_head], ++ pygram.python_symbols.file_input : [with_head]} ++ self.assertEqual(d, expected) ++ ++ def test_fixer_loading(self): ++ from myfixes.fix_first import FixFirst ++ from myfixes.fix_last import FixLast ++ from myfixes.fix_parrot import FixParrot ++ from myfixes.fix_preorder import FixPreorder ++ ++ rt = self.rt() ++ pre, post = rt.get_fixers() ++ ++ self.check_instances(pre, [FixPreorder]) ++ self.check_instances(post, [FixFirst, FixParrot, FixLast]) ++ ++ def test_naughty_fixers(self): ++ self.assertRaises(ImportError, self.rt, fixers=["not_here"]) ++ self.assertRaises(refactor.FixerError, self.rt, fixers=["no_fixer_cls"]) ++ self.assertRaises(refactor.FixerError, self.rt, fixers=["bad_order"]) ++ ++ def test_refactor_string(self): ++ rt = self.rt() ++ input = "def parrot(): pass\n\n" ++ tree = rt.refactor_string(input, "") ++ self.assertNotEqual(str(tree), input) ++ ++ input = "def f(): pass\n\n" ++ tree = rt.refactor_string(input, "") ++ self.assertEqual(str(tree), input) ++ ++ def test_refactor_stdin(self): ++ ++ class MyRT(refactor.RefactoringTool): ++ ++ def print_output(self, lines): ++ diff_lines.extend(lines) ++ ++ diff_lines = [] ++ rt = MyRT(_DEFAULT_FIXERS) ++ save = sys.stdin ++ sys.stdin = StringIO.StringIO("def parrot(): pass\n\n") ++ try: ++ rt.refactor_stdin() ++ finally: ++ sys.stdin = save ++ expected = """--- (original) +++++ (refactored) ++@@ -1,2 +1,2 @@ ++-def parrot(): pass +++def cheese(): pass""".splitlines() ++ self.assertEqual(diff_lines[:-1], expected) ++ ++ def test_refactor_file(self): ++ test_file = os.path.join(FIXER_DIR, "parrot_example.py") ++ old_contents = open(test_file, "r").read() ++ rt = self.rt() ++ ++ rt.refactor_file(test_file) ++ self.assertEqual(old_contents, open(test_file, "r").read()) ++ ++ rt.refactor_file(test_file, True) ++ try: ++ self.assertNotEqual(old_contents, open(test_file, "r").read()) ++ finally: ++ open(test_file, "w").write(old_contents) ++ ++ def test_refactor_docstring(self): ++ rt = self.rt() ++ ++ def example(): ++ """ ++ >>> example() ++ 42 ++ """ ++ out = rt.refactor_docstring(example.__doc__, "") ++ self.assertEqual(out, example.__doc__) ++ ++ def parrot(): ++ """ ++ >>> def parrot(): ++ ... return 43 ++ """ ++ out = rt.refactor_docstring(parrot.__doc__, "") ++ self.assertNotEqual(out, parrot.__doc__) ++ ++ def test_explicit(self): ++ from myfixes.fix_explicit import FixExplicit ++ ++ rt = self.rt(fixers=["myfixes.fix_explicit"]) ++ self.assertEqual(len(rt.post_order), 0) ++ ++ rt = self.rt(explicit=["myfixes.fix_explicit"]) ++ for fix in rt.post_order: ++ if isinstance(fix, FixExplicit): ++ break ++ else: ++ self.fail("explicit fixer not loaded") +diff -r 531f2e948299 refactor/tests/test_util.py +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/refactor/tests/test_util.py Wed Apr 01 13:59:47 2009 -0500 +@@ -0,0 +1,559 @@ ++#!/usr/bin/env python2.5 ++""" Test suite for the code in fixes.util """ ++# Author: Collin Winter ++ ++# Testing imports ++from . import support ++ ++# Python imports ++import os.path ++ ++# Local imports ++from .. import pytree ++from .. import fixer_util ++from ..fixer_util import Attr, Name ++ ++ ++def parse(code, strip_levels=0): ++ # The topmost node is file_input, which we don't care about. ++ # The next-topmost node is a *_stmt node, which we also don't care about ++ tree = support.parse_string(code) ++ for i in range(strip_levels): ++ tree = tree.children[0] ++ tree.parent = None ++ return tree ++ ++class MacroTestCase(support.TestCase): ++ def assertStr(self, node, string): ++ if isinstance(node, (tuple, list)): ++ node = pytree.Node(fixer_util.syms.simple_stmt, node) ++ self.assertEqual(str(node), string) ++ ++ ++class Test_is_tuple(support.TestCase): ++ def is_tuple(self, string): ++ return fixer_util.is_tuple(parse(string, strip_levels=2)) ++ ++ def test_valid(self): ++ self.failUnless(self.is_tuple("(a, b)")) ++ self.failUnless(self.is_tuple("(a, (b, c))")) ++ self.failUnless(self.is_tuple("((a, (b, c)),)")) ++ self.failUnless(self.is_tuple("(a,)")) ++ self.failUnless(self.is_tuple("()")) ++ ++ def test_invalid(self): ++ self.failIf(self.is_tuple("(a)")) ++ self.failIf(self.is_tuple("('foo') % (b, c)")) ++ ++ ++class Test_is_list(support.TestCase): ++ def is_list(self, string): ++ return fixer_util.is_list(parse(string, strip_levels=2)) ++ ++ def test_valid(self): ++ self.failUnless(self.is_list("[]")) ++ self.failUnless(self.is_list("[a]")) ++ self.failUnless(self.is_list("[a, b]")) ++ self.failUnless(self.is_list("[a, [b, c]]")) ++ self.failUnless(self.is_list("[[a, [b, c]],]")) ++ ++ def test_invalid(self): ++ self.failIf(self.is_list("[]+[]")) ++ ++ ++class Test_Attr(MacroTestCase): ++ def test(self): ++ call = parse("foo()", strip_levels=2) ++ ++ self.assertStr(Attr(Name("a"), Name("b")), "a.b") ++ self.assertStr(Attr(call, Name("b")), "foo().b") ++ ++ def test_returns(self): ++ attr = Attr(Name("a"), Name("b")) ++ self.assertEqual(type(attr), list) ++ ++ ++class Test_Name(MacroTestCase): ++ def test(self): ++ self.assertStr(Name("a"), "a") ++ self.assertStr(Name("foo.foo().bar"), "foo.foo().bar") ++ self.assertStr(Name("a", prefix="b"), "ba") ++ ++ ++class Test_does_tree_import(support.TestCase): ++ def _find_bind_rec(self, name, node): ++ # Search a tree for a binding -- used to find the starting ++ # point for these tests. ++ c = fixer_util.find_binding(name, node) ++ if c: return c ++ for child in node.children: ++ c = self._find_bind_rec(name, child) ++ if c: return c ++ ++ def does_tree_import(self, package, name, string): ++ node = parse(string) ++ # Find the binding of start -- that's what we'll go from ++ node = self._find_bind_rec('start', node) ++ return fixer_util.does_tree_import(package, name, node) ++ ++ def try_with(self, string): ++ failing_tests = (("a", "a", "from a import b"), ++ ("a.d", "a", "from a.d import b"), ++ ("d.a", "a", "from d.a import b"), ++ (None, "a", "import b"), ++ (None, "a", "import b, c, d")) ++ for package, name, import_ in failing_tests: ++ n = self.does_tree_import(package, name, import_ + "\n" + string) ++ self.failIf(n) ++ n = self.does_tree_import(package, name, string + "\n" + import_) ++ self.failIf(n) ++ ++ passing_tests = (("a", "a", "from a import a"), ++ ("x", "a", "from x import a"), ++ ("x", "a", "from x import b, c, a, d"), ++ ("x.b", "a", "from x.b import a"), ++ ("x.b", "a", "from x.b import b, c, a, d"), ++ (None, "a", "import a"), ++ (None, "a", "import b, c, a, d")) ++ for package, name, import_ in passing_tests: ++ n = self.does_tree_import(package, name, import_ + "\n" + string) ++ self.failUnless(n) ++ n = self.does_tree_import(package, name, string + "\n" + import_) ++ self.failUnless(n) ++ ++ def test_in_function(self): ++ self.try_with("def foo():\n\tbar.baz()\n\tstart=3") ++ ++class Test_find_binding(support.TestCase): ++ def find_binding(self, name, string, package=None): ++ return fixer_util.find_binding(name, parse(string), package) ++ ++ def test_simple_assignment(self): ++ self.failUnless(self.find_binding("a", "a = b")) ++ self.failUnless(self.find_binding("a", "a = [b, c, d]")) ++ self.failUnless(self.find_binding("a", "a = foo()")) ++ self.failUnless(self.find_binding("a", "a = foo().foo.foo[6][foo]")) ++ self.failIf(self.find_binding("a", "foo = a")) ++ self.failIf(self.find_binding("a", "foo = (a, b, c)")) ++ ++ def test_tuple_assignment(self): ++ self.failUnless(self.find_binding("a", "(a,) = b")) ++ self.failUnless(self.find_binding("a", "(a, b, c) = [b, c, d]")) ++ self.failUnless(self.find_binding("a", "(c, (d, a), b) = foo()")) ++ self.failUnless(self.find_binding("a", "(a, b) = foo().foo[6][foo]")) ++ self.failIf(self.find_binding("a", "(foo, b) = (b, a)")) ++ self.failIf(self.find_binding("a", "(foo, (b, c)) = (a, b, c)")) ++ ++ def test_list_assignment(self): ++ self.failUnless(self.find_binding("a", "[a] = b")) ++ self.failUnless(self.find_binding("a", "[a, b, c] = [b, c, d]")) ++ self.failUnless(self.find_binding("a", "[c, [d, a], b] = foo()")) ++ self.failUnless(self.find_binding("a", "[a, b] = foo().foo[a][foo]")) ++ self.failIf(self.find_binding("a", "[foo, b] = (b, a)")) ++ self.failIf(self.find_binding("a", "[foo, [b, c]] = (a, b, c)")) ++ ++ def test_invalid_assignments(self): ++ self.failIf(self.find_binding("a", "foo.a = 5")) ++ self.failIf(self.find_binding("a", "foo[a] = 5")) ++ self.failIf(self.find_binding("a", "foo(a) = 5")) ++ self.failIf(self.find_binding("a", "foo(a, b) = 5")) ++ ++ def test_simple_import(self): ++ self.failUnless(self.find_binding("a", "import a")) ++ self.failUnless(self.find_binding("a", "import b, c, a, d")) ++ self.failIf(self.find_binding("a", "import b")) ++ self.failIf(self.find_binding("a", "import b, c, d")) ++ ++ def test_from_import(self): ++ self.failUnless(self.find_binding("a", "from x import a")) ++ self.failUnless(self.find_binding("a", "from a import a")) ++ self.failUnless(self.find_binding("a", "from x import b, c, a, d")) ++ self.failUnless(self.find_binding("a", "from x.b import a")) ++ self.failUnless(self.find_binding("a", "from x.b import b, c, a, d")) ++ self.failIf(self.find_binding("a", "from a import b")) ++ self.failIf(self.find_binding("a", "from a.d import b")) ++ self.failIf(self.find_binding("a", "from d.a import b")) ++ ++ def test_import_as(self): ++ self.failUnless(self.find_binding("a", "import b as a")) ++ self.failUnless(self.find_binding("a", "import b as a, c, a as f, d")) ++ self.failIf(self.find_binding("a", "import a as f")) ++ self.failIf(self.find_binding("a", "import b, c as f, d as e")) ++ ++ def test_from_import_as(self): ++ self.failUnless(self.find_binding("a", "from x import b as a")) ++ self.failUnless(self.find_binding("a", "from x import g as a, d as b")) ++ self.failUnless(self.find_binding("a", "from x.b import t as a")) ++ self.failUnless(self.find_binding("a", "from x.b import g as a, d")) ++ self.failIf(self.find_binding("a", "from a import b as t")) ++ self.failIf(self.find_binding("a", "from a.d import b as t")) ++ self.failIf(self.find_binding("a", "from d.a import b as t")) ++ ++ def test_simple_import_with_package(self): ++ self.failUnless(self.find_binding("b", "import b")) ++ self.failUnless(self.find_binding("b", "import b, c, d")) ++ self.failIf(self.find_binding("b", "import b", "b")) ++ self.failIf(self.find_binding("b", "import b, c, d", "c")) ++ ++ def test_from_import_with_package(self): ++ self.failUnless(self.find_binding("a", "from x import a", "x")) ++ self.failUnless(self.find_binding("a", "from a import a", "a")) ++ self.failUnless(self.find_binding("a", "from x import *", "x")) ++ self.failUnless(self.find_binding("a", "from x import b, c, a, d", "x")) ++ self.failUnless(self.find_binding("a", "from x.b import a", "x.b")) ++ self.failUnless(self.find_binding("a", "from x.b import *", "x.b")) ++ self.failUnless(self.find_binding("a", "from x.b import b, c, a, d", "x.b")) ++ self.failIf(self.find_binding("a", "from a import b", "a")) ++ self.failIf(self.find_binding("a", "from a.d import b", "a.d")) ++ self.failIf(self.find_binding("a", "from d.a import b", "a.d")) ++ self.failIf(self.find_binding("a", "from x.y import *", "a.b")) ++ ++ def test_import_as_with_package(self): ++ self.failIf(self.find_binding("a", "import b.c as a", "b.c")) ++ self.failIf(self.find_binding("a", "import a as f", "f")) ++ self.failIf(self.find_binding("a", "import a as f", "a")) ++ ++ def test_from_import_as_with_package(self): ++ # Because it would take a lot of special-case code in the fixers ++ # to deal with from foo import bar as baz, we'll simply always ++ # fail if there is an "from ... import ... as ..." ++ self.failIf(self.find_binding("a", "from x import b as a", "x")) ++ self.failIf(self.find_binding("a", "from x import g as a, d as b", "x")) ++ self.failIf(self.find_binding("a", "from x.b import t as a", "x.b")) ++ self.failIf(self.find_binding("a", "from x.b import g as a, d", "x.b")) ++ self.failIf(self.find_binding("a", "from a import b as t", "a")) ++ self.failIf(self.find_binding("a", "from a import b as t", "b")) ++ self.failIf(self.find_binding("a", "from a import b as t", "t")) ++ ++ def test_function_def(self): ++ self.failUnless(self.find_binding("a", "def a(): pass")) ++ self.failUnless(self.find_binding("a", "def a(b, c, d): pass")) ++ self.failUnless(self.find_binding("a", "def a(): b = 7")) ++ self.failIf(self.find_binding("a", "def d(b, (c, a), e): pass")) ++ self.failIf(self.find_binding("a", "def d(a=7): pass")) ++ self.failIf(self.find_binding("a", "def d(a): pass")) ++ self.failIf(self.find_binding("a", "def d(): a = 7")) ++ ++ s = """ ++ def d(): ++ def a(): ++ pass""" ++ self.failIf(self.find_binding("a", s)) ++ ++ def test_class_def(self): ++ self.failUnless(self.find_binding("a", "class a: pass")) ++ self.failUnless(self.find_binding("a", "class a(): pass")) ++ self.failUnless(self.find_binding("a", "class a(b): pass")) ++ self.failUnless(self.find_binding("a", "class a(b, c=8): pass")) ++ self.failIf(self.find_binding("a", "class d: pass")) ++ self.failIf(self.find_binding("a", "class d(a): pass")) ++ self.failIf(self.find_binding("a", "class d(b, a=7): pass")) ++ self.failIf(self.find_binding("a", "class d(b, *a): pass")) ++ self.failIf(self.find_binding("a", "class d(b, **a): pass")) ++ self.failIf(self.find_binding("a", "class d: a = 7")) ++ ++ s = """ ++ class d(): ++ class a(): ++ pass""" ++ self.failIf(self.find_binding("a", s)) ++ ++ def test_for(self): ++ self.failUnless(self.find_binding("a", "for a in r: pass")) ++ self.failUnless(self.find_binding("a", "for a, b in r: pass")) ++ self.failUnless(self.find_binding("a", "for (a, b) in r: pass")) ++ self.failUnless(self.find_binding("a", "for c, (a,) in r: pass")) ++ self.failUnless(self.find_binding("a", "for c, (a, b) in r: pass")) ++ self.failUnless(self.find_binding("a", "for c in r: a = c")) ++ self.failIf(self.find_binding("a", "for c in a: pass")) ++ ++ def test_for_nested(self): ++ s = """ ++ for b in r: ++ for a in b: ++ pass""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ for b in r: ++ for a, c in b: ++ pass""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ for b in r: ++ for (a, c) in b: ++ pass""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ for b in r: ++ for (a,) in b: ++ pass""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ for b in r: ++ for c, (a, d) in b: ++ pass""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ for b in r: ++ for c in b: ++ a = 7""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ for b in r: ++ for c in b: ++ d = a""" ++ self.failIf(self.find_binding("a", s)) ++ ++ s = """ ++ for b in r: ++ for c in a: ++ d = 7""" ++ self.failIf(self.find_binding("a", s)) ++ ++ def test_if(self): ++ self.failUnless(self.find_binding("a", "if b in r: a = c")) ++ self.failIf(self.find_binding("a", "if a in r: d = e")) ++ ++ def test_if_nested(self): ++ s = """ ++ if b in r: ++ if c in d: ++ a = c""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ if b in r: ++ if c in d: ++ c = a""" ++ self.failIf(self.find_binding("a", s)) ++ ++ def test_while(self): ++ self.failUnless(self.find_binding("a", "while b in r: a = c")) ++ self.failIf(self.find_binding("a", "while a in r: d = e")) ++ ++ def test_while_nested(self): ++ s = """ ++ while b in r: ++ while c in d: ++ a = c""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ while b in r: ++ while c in d: ++ c = a""" ++ self.failIf(self.find_binding("a", s)) ++ ++ def test_try_except(self): ++ s = """ ++ try: ++ a = 6 ++ except: ++ b = 8""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ except: ++ a = 6""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ except KeyError: ++ pass ++ except: ++ a = 6""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ except: ++ b = 6""" ++ self.failIf(self.find_binding("a", s)) ++ ++ def test_try_except_nested(self): ++ s = """ ++ try: ++ try: ++ a = 6 ++ except: ++ pass ++ except: ++ b = 8""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ except: ++ try: ++ a = 6 ++ except: ++ pass""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ except: ++ try: ++ pass ++ except: ++ a = 6""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ try: ++ b = 8 ++ except KeyError: ++ pass ++ except: ++ a = 6 ++ except: ++ pass""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ pass ++ except: ++ try: ++ b = 8 ++ except KeyError: ++ pass ++ except: ++ a = 6""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ except: ++ b = 6""" ++ self.failIf(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ try: ++ b = 8 ++ except: ++ c = d ++ except: ++ try: ++ b = 6 ++ except: ++ t = 8 ++ except: ++ o = y""" ++ self.failIf(self.find_binding("a", s)) ++ ++ def test_try_except_finally(self): ++ s = """ ++ try: ++ c = 6 ++ except: ++ b = 8 ++ finally: ++ a = 9""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ finally: ++ a = 6""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ finally: ++ b = 6""" ++ self.failIf(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ except: ++ b = 9 ++ finally: ++ b = 6""" ++ self.failIf(self.find_binding("a", s)) ++ ++ def test_try_except_finally_nested(self): ++ s = """ ++ try: ++ c = 6 ++ except: ++ b = 8 ++ finally: ++ try: ++ a = 9 ++ except: ++ b = 9 ++ finally: ++ c = 9""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ finally: ++ try: ++ pass ++ finally: ++ a = 6""" ++ self.failUnless(self.find_binding("a", s)) ++ ++ s = """ ++ try: ++ b = 8 ++ finally: ++ try: ++ b = 6 ++ finally: ++ b = 7""" ++ self.failIf(self.find_binding("a", s)) ++ ++class Test_touch_import(support.TestCase): ++ ++ def test_after_docstring(self): ++ node = parse('"""foo"""\nbar()') ++ fixer_util.touch_import(None, "foo", node) ++ self.assertEqual(str(node), '"""foo"""\nimport foo\nbar()\n\n') ++ ++ def test_after_imports(self): ++ node = parse('"""foo"""\nimport bar\nbar()') ++ fixer_util.touch_import(None, "foo", node) ++ self.assertEqual(str(node), '"""foo"""\nimport bar\nimport foo\nbar()\n\n') ++ ++ def test_beginning(self): ++ node = parse('bar()') ++ fixer_util.touch_import(None, "foo", node) ++ self.assertEqual(str(node), 'import foo\nbar()\n\n') ++ ++ 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') ++ ++ def test_name_import(self): ++ node = parse('bar()') ++ fixer_util.touch_import(None, "cgi", node) ++ self.assertEqual(str(node), 'import cgi\nbar()\n\n') ++ ++ ++if __name__ == "__main__": ++ import __main__ ++ support.run_all_tests(__main__) +diff -r 531f2e948299 scripts/.svn/entries +--- a/scripts/.svn/entries Mon Mar 30 20:02:09 2009 -0500 ++++ b/scripts/.svn/entries Wed Apr 01 13:59:47 2009 -0500 +@@ -1,7 +1,7 @@ + 9 + + dir +-70785 ++70822 + http://svn.python.org/projects/sandbox/trunk/2to3/scripts + http://svn.python.org/projects + +diff -r 531f2e948299 scripts/find_pattern.py +--- a/scripts/find_pattern.py Mon Mar 30 20:02:09 2009 -0500 ++++ b/scripts/find_pattern.py Wed Apr 01 13:59:47 2009 -0500 +@@ -47,19 +47,24 @@ + from StringIO import StringIO + + # Local imports +-from lib2to3 import pytree +-from lib2to3.pgen2 import driver +-from lib2to3.pygram import python_symbols, python_grammar +- +-driver = driver.Driver(python_grammar, convert=pytree.convert) ++from refactor import pytree ++from refactor import pgen2 ++from refactor.pygram import python_symbols, python_grammar + + def main(args): + parser = optparse.OptionParser(usage="find_pattern.py [options] [string]") + parser.add_option("-f", "--file", action="store", + help="Read a code snippet from the specified file") ++ parser.add_option("-p", "--print-function", action="store_true", ++ help="Modify the grammar so that print() is a function") + + # Parse command line arguments + options, args = parser.parse_args(args) ++ ++ if options.print_function: ++ del python_grammar.keywords["print"] ++ ++ driver = pgen2.driver.Driver(python_grammar, convert=pytree.convert) + if options.file: + tree = driver.parse_file(options.file) + elif len(args) > 1: +diff -r 531f2e948299 setup.py +--- a/setup.py Mon Mar 30 20:02:09 2009 -0500 ++++ b/setup.py Wed Apr 01 13:59:47 2009 -0500 +@@ -3,6 +3,13 @@ + setup( + name="2to3", + packages=['lib2to3','lib2to3.fixes','lib2to3.pgen2'], +- package_data={'lib2to3':['Grammar.txt','PatternGrammar.txt']}, ++ package_data={'lib2to3':['lib2to3/Grammar.txt','lib2to3/PatternGrammar.txt']}, + scripts=["2to3"] + ) ++ ++setup( ++ name="refactor", ++ packages=['refactor','refactor.fixes','refactor.fixes.from2','refactor.fixes.from3','refactor.pgen2'], ++ package_data={'refactor':['Grammar.txt','PatternGrammar.txt']}, ++ scripts=["3to2"] ++) +diff -r 531f2e948299 test.py +--- a/test.py Mon Mar 30 20:02:09 2009 -0500 ++++ b/test.py Wed Apr 01 13:59:47 2009 -0500 +@@ -1,32 +1,59 @@ + #!/usr/bin/env python2.5 + +-"""Main test file for 2to3. ++"""Main test file for refactor (2to3 and back again). + + Running "python test.py" will run all tests in tests/test_*.py. + """ +-# Author: Collin Winter ++# Original Author: Collin Winter + + import unittest +-from lib2to3 import tests +-import lib2to3.tests.support +-from sys import exit, argv ++from optparse import OptionParser, OptionGroup ++from sys import exit + +-if "-h" in argv or "--help" in argv or len(argv) > 2: +- print "Usage: %s [-h] [test suite[.test class]]" %(argv[0]) +- print "default : run all tests in lib2to3/tests/test_*.py" +- print "test suite: run tests in lib2to3/tests/" +- print "test class : run tests in ." +- exit(1) ++# Note more imports below, based on optparse output. + +-if len(argv) == 2: ++usage = "usage: %prog [options] arg" ++usage += "\n\narg can be:\n" ++usage += "test suite: run tests in refactor/tests/\n" ++usage += "test class: run tests in .\n" ++usage += "(default: run all tests in refactor/tests/test_*.py)" ++ ++parser = OptionParser(usage=usage) ++parser.add_option("--source", ++ dest="source", ++ help="source version of Python to refactor") ++parser.add_option("--target", ++ dest="target", ++ help="target version of Python") ++parser.add_option("--base", ++ dest="base", default="refactor", ++ help="base package, e.g. lib2to3 or refactor") ++ ++(options, args) = parser.parse_args() ++ ++# It's too late at night to figure out why __import__ is failing. ++exec "from %s import tests" % options.base ++exec "from %s.tests import support" % options.base ++exec "from %s.tests.test_fixers import FixerTestCase as Fixer" % options.base ++ ++old_version = support.parse_version(options.source) ++new_version = support.parse_version(options.target) ++ ++if old_version: ++ Fixer.old_version = old_version ++if new_version: ++ Fixer.new_version = new_version ++ ++if len(args) > 0: ++ arg = args[0] + mod = tests +- for m in argv[1].split("."): ++ for m in arg.split("."): + mod = getattr(mod, m, None) + if not mod: + print "Error importing %s" %(m) + exit(1) + +- if argv[1].find(".") == -1: ++ if arg.find(".") == -1: + # Just the module was specified, load all the tests + suite = unittest.TestLoader().loadTestsFromModule(mod) + else: Added: sandbox/trunk/refactor_pkg/example.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/example.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,387 @@ +#!/usr/bin/python + # comment indented by tab + +"""Docstring. + +Here are some doctest exampes: + +>>> print 42 +42 + + >>> d = {1: 1, 2: 2, 2: 2} + >>> d.keys().sort() + >>> print d + {1: 1, 2: 2} + + >>> for i in d.keys(): + ... print i, d[i] + +And a tricky one: + +>>> class X(Structure): +... _fields_ = [("x", c_int), ("y", c_int), ("array", c_char_p * 5)] +... +>>> x = X() +>>> print x._objects +None +>>> + +""" + +import sys + +def unicode_examples(): + a = unicode(b) + a = u"xxx" + a = U"""xxx""" + a = ur'xxx' + a = UR'''xxx''' + a = Ur"xxx" + a = uR"""xxx""" + b = u"..." u'...' + +def ne_examples(): + if x <> y: + pass + if x<>y: + pass + if x<>y<>z: + pass + +def has_key_examples(): + # + x = d.has_key("x") or d.has_key("y") + # + x = a.b.c.d.has_key("x") ** 3 + # + x = a.b.has_key(1 + 2).__repr__() + # + x = a.b.has_key(1 + 2).__repr__() ** -3 ** 4 + # + x = a.has_key(f or g) + # + x = a + b.has_key(c) + # + x = a.has_key(lambda: 12) + # + x = a.has_key(a for a in b) + # + if not a.has_key(b): pass + # + if not a.has_key(b).__repr__(): pass + # + if not a.has_key(b) ** 2: pass + +def foo(): + pass # body indented by tab + +def test_ws_comma(): + yield 1,2 ,3 + f(1,2 ,3) + `a ,b` + def f(a,b ,c): pass + { a:b,c:d , e : f } + +def apply_examples(): + x = apply(f, g + h) + y = apply(f, g, h) + z = apply(fs[0], g or h, h or g) + # Hello + apply(f, (x, y) + t) + apply(f, args,) + apply(f, args, kwds,) + # Test that complex functions are parenthesized + x = apply(f+g, args) + x = apply(f*g, args) + x = apply(f**g, args) + # But dotted names etc. not + x = apply(f.g, args) + x = apply(f[x], args) + x = apply(f(), args) + # Extreme case + x = apply(a.b.c.d.e.f, args, kwds) + # XXX Comments in weird places still get lost + apply( # foo + f, # bar + args) + +def bad_apply_examples(): + # These should *not* be touched + apply() + apply(f) + apply(f,) + apply(f, args, kwds, extras) + apply(f, *args, **kwds) + apply(f, *args) + apply(func=f, args=args, kwds=kwds) + apply(f, args=args, kwds=kwds) + apply(f, args, kwds=kwds) + +def metaclass_examples(): + class X: + __metaclass__ = Meta + + class X(b1, b2): + bar = 23 # Comment on me! + __metaclass__ = Meta + spam = 27.23 # Laughable + + class X: + __metaclass__ = Meta; x = 23; y = 34 # Yes, I can handle this, too. + +def intern_examples(): + # + # These should be refactored: + # + x = intern(a) + # + y = intern("b" # test + ) + # + z = intern(a+b+c.d,) + # + intern("y%s" % 5).replace("y", "") + # + # These not: + # + intern(a=1) + # + intern(f, g) + # + intern(*h) + # + intern(**i) + +def print_examples(): + # plain vanilla + print 1, 1+1, 1+1+1 + # + print 1, 2 + # + print 1 + + print + + # trailing commas + print 1, 2, 3, + # + print 1, 2, + # + print 1, + # + print + + # >> stuff + print >>sys.stderr, 1, 2, 3 # no trailing comma + # + print >>sys.stdder, 1, 2, # trailing comma + # + print >>sys.stderr, 1+1 # no trailing comma + # + print >> sys.stderr # spaces before sys.stderr + +def exec_examples(): + # + exec code + # + exec code in ns + # + exec code in ns1, ns2 + # + exec (a.b()) in ns + # + exec a.b() + c in ns + # + # These should not be touched: + # + exec(code) + # + exec (code) + # + exec(code, ns) + # + exec(code, ns1, ns2) + +def repr_examples(): + x = `1 + 2` + # + y = `x` + # + z = `y`.__repr__() + # + x = `1, 2, 3` + # + x = `1 + `2`` + # + x = `1, 2 + `3, 4`` + +def except_examples(): + try: + pass + except Exception, (f, e): + pass + except ImportError, e: + print e.args + # + try: + pass + except (RuntimeError, ImportError), e: + pass + # + try: + pass + except Exception, (a, b): + pass + # + try: + pass + except Exception, d[5]: + pass + # + try: + pass + except Exception, a.foo: + pass + # + try: + pass + except Exception, a().foo: + pass + # + # These should not be touched: + # + try: + pass + except: + pass + # + try: + pass + except Exception: + pass + # + try: + pass + except (Exception, SystemExit): + pass + +def raise_examples(): + raise Exception, 5 + # + raise Exception,5 + # + raise Exception, (5, 6, 7) + # + # These should not be touched + # + raise Exception + # + raise Exception(5, 6) + # + # These should produce a warning + # TODO: convert "raise E, V, T" to + # "e = E(V); e.__traceback__ = T; raise e;" + # + raise Exception, 5, 6 + # + raise Exception,5,6 + # + raise Exception, (5, 6, 7), 6 + +def long_examples(): + x = long(x) + y = isinstance(x, long) + z = type(x) in (int, long) + a = 12L + b = 0x12l + # unchanged: + a = 12 + b = 0x12 + c = 3.14 + +def dict_examples(): + # + # Plain method calls + # + print d.keys() + print d.items() + print d.values() + # + # Plain method calls in special contexts + # + print iter(e.keys()) + for i in e.keys(): print i + [i for i in e.keys()] + (i for i in e.keys()) + # + # Iterator method calls + # + print f.iterkeys() + print f.iteritems() + print f.itervalues() + # + # Iterator method calls in special contexts + # + print list(g.iterkeys()) + print sorted(g.iterkeys()) + print iter(g.iterkeys()) + for i in g.iterkeys(): print i + [i for i in g.iterkeys()] + (i for i in g.iterkeys()) + # + # Examples with a "tail"; these are never "special" + # + print h.iterkeys().next() + print h.keys()[0] + print list(h.iterkeys().next()) + for x in h.keys()[0]: print x + +def dict_negative_examples(): + # + # These should all remain unchanged: + # + print list(h.keys()) + print sorted(h.keys()) + +def xrange_examples(): + for i in xrange(100): print i + for i in xrange(0, 100): print i + for i in xrange(0, 100, 10): print i + +def input_examples(): + a = input() + b = input(str(a)) + +def raw_input_examples(): + a = raw_input() + b = raw_input(a.rstrip()) + +def filter_examples(): + filter(os.unlink, filenames) + filter(None, "whatever") + filter(lambda x: not x, range(4)) + +def map_examples(): + map(None, foo.bar) + map(None, foo.bar,) + map(None, foo, bar) + map(f, foo.bar) + map(lambda x: x+1, range(10)) + +def basestring_examples(): + if isinstance(x, basestring): pass + +def buffer_examples(): + x = buffer(y) + +def sys_exc_examples(): + print sys.exc_type, sys.exc_value, sys.exc_traceback + +class X: + def maximum(self): + return max(self.data.values()) + def total(self): + return sum(self.data.values()) + + +# This is the last line. Added: sandbox/trunk/refactor_pkg/lib2to3/Grammar.txt ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/Grammar.txt Wed Apr 1 21:02:05 2009 @@ -0,0 +1,155 @@ +# Grammar for Python + +# Note: Changing the grammar specified in this file will most likely +# require corresponding changes in the parser module +# (../Modules/parsermodule.c). If you can't make the changes to +# that module yourself, please co-ordinate the required changes +# with someone who can; ask around on python-dev for help. Fred +# Drake will probably be listening there. + +# NOTE WELL: You should also follow all the steps listed in PEP 306, +# "How to Change Python's Grammar" + +# Commands for Kees Blom's railroad program +#diagram:token NAME +#diagram:token NUMBER +#diagram:token STRING +#diagram:token NEWLINE +#diagram:token ENDMARKER +#diagram:token INDENT +#diagram:output\input python.bla +#diagram:token DEDENT +#diagram:output\textwidth 20.04cm\oddsidemargin 0.0cm\evensidemargin 0.0cm +#diagram:rules + +# Start symbols for the grammar: +# file_input is a module or sequence of commands read from an input file; +# single_input is a single interactive statement; +# eval_input is the input for the eval() and input() functions. +# NB: compound_stmt in single_input is followed by extra NEWLINE! +file_input: (NEWLINE | stmt)* ENDMARKER +single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE +eval_input: testlist NEWLINE* ENDMARKER + +decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE +decorators: decorator+ +decorated: decorators (classdef | funcdef) +funcdef: 'def' NAME parameters ['->' test] ':' suite +parameters: '(' [typedargslist] ')' +typedargslist: ((tfpdef ['=' test] ',')* + ('*' [tname] (',' tname ['=' test])* [',' '**' tname] | '**' tname) + | tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) +tname: NAME [':' test] +tfpdef: tname | '(' tfplist ')' +tfplist: tfpdef (',' tfpdef)* [','] +varargslist: ((vfpdef ['=' test] ',')* + ('*' [vname] (',' vname ['=' test])* [',' '**' vname] | '**' vname) + | vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) +vname: NAME +vfpdef: vname | '(' vfplist ')' +vfplist: vfpdef (',' vfpdef)* [','] + +stmt: simple_stmt | compound_stmt +simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE +small_stmt: (expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | + import_stmt | global_stmt | exec_stmt | assert_stmt) +expr_stmt: testlist (augassign (yield_expr|testlist) | + ('=' (yield_expr|testlist))*) +augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | + '<<=' | '>>=' | '**=' | '//=') +# For normal assignments, additional restrictions enforced by the interpreter +print_stmt: 'print' ( [ test (',' test)* [','] ] | + '>>' test [ (',' test)+ [','] ] ) +del_stmt: 'del' exprlist +pass_stmt: 'pass' +flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt +break_stmt: 'break' +continue_stmt: 'continue' +return_stmt: 'return' [testlist] +yield_stmt: yield_expr +raise_stmt: 'raise' [test ['from' test | ',' test [',' test]]] +import_stmt: import_name | import_from +import_name: 'import' dotted_as_names +import_from: ('from' ('.'* dotted_name | '.'+) + 'import' ('*' | '(' import_as_names ')' | import_as_names)) +import_as_name: NAME ['as' NAME] +dotted_as_name: dotted_name ['as' NAME] +import_as_names: import_as_name (',' import_as_name)* [','] +dotted_as_names: dotted_as_name (',' dotted_as_name)* +dotted_name: NAME ('.' NAME)* +global_stmt: ('global' | 'nonlocal') NAME (',' NAME)* +exec_stmt: 'exec' expr ['in' test [',' test]] +assert_stmt: 'assert' test [',' test] + +compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated +if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] +while_stmt: 'while' test ':' suite ['else' ':' suite] +for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] +try_stmt: ('try' ':' suite + ((except_clause ':' suite)+ + ['else' ':' suite] + ['finally' ':' suite] | + 'finally' ':' suite)) +with_stmt: 'with' test [ with_var ] ':' suite +with_var: 'as' expr +# NB compile.c makes sure that the default except clause is last +except_clause: 'except' [test [(',' | 'as') test]] +suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT + +# Backward compatibility cruft to support: +# [ x for x in lambda: True, lambda: False if x() ] +# even while also allowing: +# lambda x: 5 if x else 2 +# (But not a mix of the two) +testlist_safe: old_test [(',' old_test)+ [',']] +old_test: or_test | old_lambdef +old_lambdef: 'lambda' [varargslist] ':' old_test + +test: or_test ['if' or_test 'else' test] | lambdef +or_test: and_test ('or' and_test)* +and_test: not_test ('and' not_test)* +not_test: 'not' not_test | comparison +comparison: expr (comp_op expr)* +comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' +expr: xor_expr ('|' xor_expr)* +xor_expr: and_expr ('^' and_expr)* +and_expr: shift_expr ('&' shift_expr)* +shift_expr: arith_expr (('<<'|'>>') arith_expr)* +arith_expr: term (('+'|'-') term)* +term: factor (('*'|'/'|'%'|'//') factor)* +factor: ('+'|'-'|'~') factor | power +power: atom trailer* ['**' factor] +atom: ('(' [yield_expr|testlist_gexp] ')' | + '[' [listmaker] ']' | + '{' [dictsetmaker] '}' | + '`' testlist1 '`' | + NAME | NUMBER | STRING+ | '.' '.' '.') +listmaker: test ( comp_for | (',' test)* [','] ) +testlist_gexp: test ( comp_for | (',' test)* [','] ) +lambdef: 'lambda' [varargslist] ':' test +trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME +subscriptlist: subscript (',' subscript)* [','] +subscript: test | [test] ':' [test] [sliceop] +sliceop: ':' [test] +exprlist: expr (',' expr)* [','] +testlist: test (',' test)* [','] +dictsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) | + (test (comp_for | (',' test)* [','])) ) + +classdef: 'class' NAME ['(' [arglist] ')'] ':' suite + +arglist: (argument ',')* (argument [','] + |'*' test (',' argument)* [',' '**' test] + |'**' test) +argument: test [comp_for] | test '=' test # Really [keyword '='] test + +comp_iter: comp_for | comp_if +comp_for: 'for' exprlist 'in' testlist_safe [comp_iter] +comp_if: 'if' old_test [comp_iter] + +testlist1: test (',' test)* + +# not used in grammar, but may appear in "node" passed from Parser to Compiler +encoding_decl: NAME + +yield_expr: 'yield' [testlist] Added: sandbox/trunk/refactor_pkg/lib2to3/PatternGrammar.txt ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/PatternGrammar.txt Wed Apr 1 21:02:05 2009 @@ -0,0 +1,28 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +# A grammar to describe tree matching patterns. +# Not shown here: +# - 'TOKEN' stands for any token (leaf node) +# - 'any' stands for any node (leaf or interior) +# With 'any' we can still specify the sub-structure. + +# The start symbol is 'Matcher'. + +Matcher: Alternatives ENDMARKER + +Alternatives: Alternative ('|' Alternative)* + +Alternative: (Unit | NegatedUnit)+ + +Unit: [NAME '='] ( STRING [Repeater] + | NAME [Details] [Repeater] + | '(' Alternatives ')' [Repeater] + | '[' Alternatives ']' + ) + +NegatedUnit: 'not' (STRING | NAME [Details] | '(' Alternatives ')') + +Repeater: '*' | '+' | '{' NUMBER [',' NUMBER] '}' + +Details: '<' Alternatives '>' Added: sandbox/trunk/refactor_pkg/lib2to3/__init__.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/__init__.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1 @@ +from refactor import * Added: sandbox/trunk/refactor_pkg/lib2to3/fixes/__init__.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/fixes/__init__.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,2 @@ +from refactor.fixes import from2 +from refactor.fixes.from2 import * Added: sandbox/trunk/refactor_pkg/lib2to3/pgen2/__init__.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/pgen2/__init__.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1 @@ +from refactor.pgen2 import * Added: sandbox/trunk/refactor_pkg/lib2to3/tests/__init__.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/tests/__init__.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,24 @@ +"""Make tests/ into a package. This allows us to "import tests" and +have tests.all_tests be a TestSuite representing all test cases +from all test_*.py files in tests/.""" +# Author: Collin Winter + +import os +import os.path +import unittest +import types + +from . import support + +all_tests = unittest.TestSuite() + +tests_dir = os.path.join(os.path.dirname(__file__), '..', 'tests') +tests = [t[0:-3] for t in os.listdir(tests_dir) + if t.startswith('test_') and t.endswith('.py')] + +loader = unittest.TestLoader() + +for t in tests: + __import__("",globals(),locals(),[t],level=1) + mod = globals()[t] + all_tests.addTests(loader.loadTestsFromModule(mod)) Added: sandbox/trunk/refactor_pkg/lib2to3/tests/data/README ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/tests/data/README Wed Apr 1 21:02:05 2009 @@ -0,0 +1,6 @@ +In this directory: +- py2_test_grammar.py -- test file that exercises most/all of Python 2.x's grammar. +- py3_test_grammar.py -- test file that exercises most/all of Python 3.x's grammar. +- infinite_recursion.py -- test file that causes lib2to3's faster recursive pattern matching + scheme to fail, but passes when lib2to3 falls back to iterative pattern matching. +- fixes/ -- for use by test_refactor.py Added: sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/bad_order.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/bad_order.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,5 @@ +from refactor.fixer_base import BaseFix + +class FixBadOrder(BaseFix): + + order = "crazy" Added: sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/myfixes/__init__.py ============================================================================== Added: sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/myfixes/fix_explicit.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/myfixes/fix_explicit.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,6 @@ +from refactor.fixer_base import BaseFix + +class FixExplicit(BaseFix): + explicit = True + + def match(self): return False Added: sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/myfixes/fix_first.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/myfixes/fix_first.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,6 @@ +from refactor.fixer_base import BaseFix + +class FixFirst(BaseFix): + run_order = 1 + + def match(self, node): return False Added: sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/myfixes/fix_last.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/myfixes/fix_last.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,7 @@ +from refactor.fixer_base import BaseFix + +class FixLast(BaseFix): + + run_order = 10 + + def match(self, node): return False Added: sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/myfixes/fix_parrot.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/myfixes/fix_parrot.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,13 @@ +from refactor.fixer_base import BaseFix +from refactor.fixer_util import Name + +class FixParrot(BaseFix): + """ + Change functions named 'parrot' to 'cheese'. + """ + + PATTERN = """funcdef < 'def' name='parrot' any* >""" + + def transform(self, node, results): + name = results["name"] + name.replace(Name("cheese", name.get_prefix())) Added: sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/myfixes/fix_preorder.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/myfixes/fix_preorder.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,6 @@ +from refactor.fixer_base import BaseFix + +class FixPreorder(BaseFix): + order = "pre" + + def match(self, node): return False Added: sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/no_fixer_cls.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/no_fixer_cls.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1 @@ +# This is empty so trying to fetch the fixer class gives an AttributeError Added: sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/parrot_example.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/tests/data/fixers/parrot_example.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,2 @@ +def parrot(): + pass Added: sandbox/trunk/refactor_pkg/lib2to3/tests/data/infinite_recursion.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/tests/data/infinite_recursion.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,2669 @@ +# This file is used to verify that 2to3 falls back to a slower, iterative pattern matching +# scheme in the event that the faster recursive system fails due to infinite recursion. +from ctypes import * +STRING = c_char_p + + +OSUnknownByteOrder = 0 +UIT_PROMPT = 1 +P_PGID = 2 +P_PID = 1 +UIT_ERROR = 5 +UIT_INFO = 4 +UIT_NONE = 0 +P_ALL = 0 +UIT_VERIFY = 2 +OSBigEndian = 2 +UIT_BOOLEAN = 3 +OSLittleEndian = 1 +__darwin_nl_item = c_int +__darwin_wctrans_t = c_int +__darwin_wctype_t = c_ulong +__int8_t = c_byte +__uint8_t = c_ubyte +__int16_t = c_short +__uint16_t = c_ushort +__int32_t = c_int +__uint32_t = c_uint +__int64_t = c_longlong +__uint64_t = c_ulonglong +__darwin_intptr_t = c_long +__darwin_natural_t = c_uint +__darwin_ct_rune_t = c_int +class __mbstate_t(Union): + pass +__mbstate_t._pack_ = 4 +__mbstate_t._fields_ = [ + ('__mbstate8', c_char * 128), + ('_mbstateL', c_longlong), +] +assert sizeof(__mbstate_t) == 128, sizeof(__mbstate_t) +assert alignment(__mbstate_t) == 4, alignment(__mbstate_t) +__darwin_mbstate_t = __mbstate_t +__darwin_ptrdiff_t = c_int +__darwin_size_t = c_ulong +__darwin_va_list = STRING +__darwin_wchar_t = c_int +__darwin_rune_t = __darwin_wchar_t +__darwin_wint_t = c_int +__darwin_clock_t = c_ulong +__darwin_socklen_t = __uint32_t +__darwin_ssize_t = c_long +__darwin_time_t = c_long +sig_atomic_t = c_int +class sigcontext(Structure): + pass +sigcontext._fields_ = [ + ('sc_onstack', c_int), + ('sc_mask', c_int), + ('sc_eax', c_uint), + ('sc_ebx', c_uint), + ('sc_ecx', c_uint), + ('sc_edx', c_uint), + ('sc_edi', c_uint), + ('sc_esi', c_uint), + ('sc_ebp', c_uint), + ('sc_esp', c_uint), + ('sc_ss', c_uint), + ('sc_eflags', c_uint), + ('sc_eip', c_uint), + ('sc_cs', c_uint), + ('sc_ds', c_uint), + ('sc_es', c_uint), + ('sc_fs', c_uint), + ('sc_gs', c_uint), +] +assert sizeof(sigcontext) == 72, sizeof(sigcontext) +assert alignment(sigcontext) == 4, alignment(sigcontext) +u_int8_t = c_ubyte +u_int16_t = c_ushort +u_int32_t = c_uint +u_int64_t = c_ulonglong +int32_t = c_int +register_t = int32_t +user_addr_t = u_int64_t +user_size_t = u_int64_t +int64_t = c_longlong +user_ssize_t = int64_t +user_long_t = int64_t +user_ulong_t = u_int64_t +user_time_t = int64_t +syscall_arg_t = u_int64_t + +# values for unnamed enumeration +class aes_key_st(Structure): + pass +aes_key_st._fields_ = [ + ('rd_key', c_ulong * 60), + ('rounds', c_int), +] +assert sizeof(aes_key_st) == 244, sizeof(aes_key_st) +assert alignment(aes_key_st) == 4, alignment(aes_key_st) +AES_KEY = aes_key_st +class asn1_ctx_st(Structure): + pass +asn1_ctx_st._fields_ = [ + ('p', POINTER(c_ubyte)), + ('eos', c_int), + ('error', c_int), + ('inf', c_int), + ('tag', c_int), + ('xclass', c_int), + ('slen', c_long), + ('max', POINTER(c_ubyte)), + ('q', POINTER(c_ubyte)), + ('pp', POINTER(POINTER(c_ubyte))), + ('line', c_int), +] +assert sizeof(asn1_ctx_st) == 44, sizeof(asn1_ctx_st) +assert alignment(asn1_ctx_st) == 4, alignment(asn1_ctx_st) +ASN1_CTX = asn1_ctx_st +class asn1_object_st(Structure): + pass +asn1_object_st._fields_ = [ + ('sn', STRING), + ('ln', STRING), + ('nid', c_int), + ('length', c_int), + ('data', POINTER(c_ubyte)), + ('flags', c_int), +] +assert sizeof(asn1_object_st) == 24, sizeof(asn1_object_st) +assert alignment(asn1_object_st) == 4, alignment(asn1_object_st) +ASN1_OBJECT = asn1_object_st +class asn1_string_st(Structure): + pass +asn1_string_st._fields_ = [ + ('length', c_int), + ('type', c_int), + ('data', POINTER(c_ubyte)), + ('flags', c_long), +] +assert sizeof(asn1_string_st) == 16, sizeof(asn1_string_st) +assert alignment(asn1_string_st) == 4, alignment(asn1_string_st) +ASN1_STRING = asn1_string_st +class ASN1_ENCODING_st(Structure): + pass +ASN1_ENCODING_st._fields_ = [ + ('enc', POINTER(c_ubyte)), + ('len', c_long), + ('modified', c_int), +] +assert sizeof(ASN1_ENCODING_st) == 12, sizeof(ASN1_ENCODING_st) +assert alignment(ASN1_ENCODING_st) == 4, alignment(ASN1_ENCODING_st) +ASN1_ENCODING = ASN1_ENCODING_st +class asn1_string_table_st(Structure): + pass +asn1_string_table_st._fields_ = [ + ('nid', c_int), + ('minsize', c_long), + ('maxsize', c_long), + ('mask', c_ulong), + ('flags', c_ulong), +] +assert sizeof(asn1_string_table_st) == 20, sizeof(asn1_string_table_st) +assert alignment(asn1_string_table_st) == 4, alignment(asn1_string_table_st) +ASN1_STRING_TABLE = asn1_string_table_st +class ASN1_TEMPLATE_st(Structure): + pass +ASN1_TEMPLATE_st._fields_ = [ +] +ASN1_TEMPLATE = ASN1_TEMPLATE_st +class ASN1_ITEM_st(Structure): + pass +ASN1_ITEM = ASN1_ITEM_st +ASN1_ITEM_st._fields_ = [ +] +class ASN1_TLC_st(Structure): + pass +ASN1_TLC = ASN1_TLC_st +ASN1_TLC_st._fields_ = [ +] +class ASN1_VALUE_st(Structure): + pass +ASN1_VALUE_st._fields_ = [ +] +ASN1_VALUE = ASN1_VALUE_st +ASN1_ITEM_EXP = ASN1_ITEM +class asn1_type_st(Structure): + pass +class N12asn1_type_st4DOLLAR_11E(Union): + pass +ASN1_BOOLEAN = c_int +ASN1_INTEGER = asn1_string_st +ASN1_ENUMERATED = asn1_string_st +ASN1_BIT_STRING = asn1_string_st +ASN1_OCTET_STRING = asn1_string_st +ASN1_PRINTABLESTRING = asn1_string_st +ASN1_T61STRING = asn1_string_st +ASN1_IA5STRING = asn1_string_st +ASN1_GENERALSTRING = asn1_string_st +ASN1_BMPSTRING = asn1_string_st +ASN1_UNIVERSALSTRING = asn1_string_st +ASN1_UTCTIME = asn1_string_st +ASN1_GENERALIZEDTIME = asn1_string_st +ASN1_VISIBLESTRING = asn1_string_st +ASN1_UTF8STRING = asn1_string_st +N12asn1_type_st4DOLLAR_11E._fields_ = [ + ('ptr', STRING), + ('boolean', ASN1_BOOLEAN), + ('asn1_string', POINTER(ASN1_STRING)), + ('object', POINTER(ASN1_OBJECT)), + ('integer', POINTER(ASN1_INTEGER)), + ('enumerated', POINTER(ASN1_ENUMERATED)), + ('bit_string', POINTER(ASN1_BIT_STRING)), + ('octet_string', POINTER(ASN1_OCTET_STRING)), + ('printablestring', POINTER(ASN1_PRINTABLESTRING)), + ('t61string', POINTER(ASN1_T61STRING)), + ('ia5string', POINTER(ASN1_IA5STRING)), + ('generalstring', POINTER(ASN1_GENERALSTRING)), + ('bmpstring', POINTER(ASN1_BMPSTRING)), + ('universalstring', POINTER(ASN1_UNIVERSALSTRING)), + ('utctime', POINTER(ASN1_UTCTIME)), + ('generalizedtime', POINTER(ASN1_GENERALIZEDTIME)), + ('visiblestring', POINTER(ASN1_VISIBLESTRING)), + ('utf8string', POINTER(ASN1_UTF8STRING)), + ('set', POINTER(ASN1_STRING)), + ('sequence', POINTER(ASN1_STRING)), +] +assert sizeof(N12asn1_type_st4DOLLAR_11E) == 4, sizeof(N12asn1_type_st4DOLLAR_11E) +assert alignment(N12asn1_type_st4DOLLAR_11E) == 4, alignment(N12asn1_type_st4DOLLAR_11E) +asn1_type_st._fields_ = [ + ('type', c_int), + ('value', N12asn1_type_st4DOLLAR_11E), +] +assert sizeof(asn1_type_st) == 8, sizeof(asn1_type_st) +assert alignment(asn1_type_st) == 4, alignment(asn1_type_st) +ASN1_TYPE = asn1_type_st +class asn1_method_st(Structure): + pass +asn1_method_st._fields_ = [ + ('i2d', CFUNCTYPE(c_int)), + ('d2i', CFUNCTYPE(STRING)), + ('create', CFUNCTYPE(STRING)), + ('destroy', CFUNCTYPE(None)), +] +assert sizeof(asn1_method_st) == 16, sizeof(asn1_method_st) +assert alignment(asn1_method_st) == 4, alignment(asn1_method_st) +ASN1_METHOD = asn1_method_st +class asn1_header_st(Structure): + pass +asn1_header_st._fields_ = [ + ('header', POINTER(ASN1_OCTET_STRING)), + ('data', STRING), + ('meth', POINTER(ASN1_METHOD)), +] +assert sizeof(asn1_header_st) == 12, sizeof(asn1_header_st) +assert alignment(asn1_header_st) == 4, alignment(asn1_header_st) +ASN1_HEADER = asn1_header_st +class BIT_STRING_BITNAME_st(Structure): + pass +BIT_STRING_BITNAME_st._fields_ = [ + ('bitnum', c_int), + ('lname', STRING), + ('sname', STRING), +] +assert sizeof(BIT_STRING_BITNAME_st) == 12, sizeof(BIT_STRING_BITNAME_st) +assert alignment(BIT_STRING_BITNAME_st) == 4, alignment(BIT_STRING_BITNAME_st) +BIT_STRING_BITNAME = BIT_STRING_BITNAME_st +class bio_st(Structure): + pass +BIO = bio_st +bio_info_cb = CFUNCTYPE(None, POINTER(bio_st), c_int, STRING, c_int, c_long, c_long) +class bio_method_st(Structure): + pass +bio_method_st._fields_ = [ + ('type', c_int), + ('name', STRING), + ('bwrite', CFUNCTYPE(c_int, POINTER(BIO), STRING, c_int)), + ('bread', CFUNCTYPE(c_int, POINTER(BIO), STRING, c_int)), + ('bputs', CFUNCTYPE(c_int, POINTER(BIO), STRING)), + ('bgets', CFUNCTYPE(c_int, POINTER(BIO), STRING, c_int)), + ('ctrl', CFUNCTYPE(c_long, POINTER(BIO), c_int, c_long, c_void_p)), + ('create', CFUNCTYPE(c_int, POINTER(BIO))), + ('destroy', CFUNCTYPE(c_int, POINTER(BIO))), + ('callback_ctrl', CFUNCTYPE(c_long, POINTER(BIO), c_int, POINTER(bio_info_cb))), +] +assert sizeof(bio_method_st) == 40, sizeof(bio_method_st) +assert alignment(bio_method_st) == 4, alignment(bio_method_st) +BIO_METHOD = bio_method_st +class crypto_ex_data_st(Structure): + pass +class stack_st(Structure): + pass +STACK = stack_st +crypto_ex_data_st._fields_ = [ + ('sk', POINTER(STACK)), + ('dummy', c_int), +] +assert sizeof(crypto_ex_data_st) == 8, sizeof(crypto_ex_data_st) +assert alignment(crypto_ex_data_st) == 4, alignment(crypto_ex_data_st) +CRYPTO_EX_DATA = crypto_ex_data_st +bio_st._fields_ = [ + ('method', POINTER(BIO_METHOD)), + ('callback', CFUNCTYPE(c_long, POINTER(bio_st), c_int, STRING, c_int, c_long, c_long)), + ('cb_arg', STRING), + ('init', c_int), + ('shutdown', c_int), + ('flags', c_int), + ('retry_reason', c_int), + ('num', c_int), + ('ptr', c_void_p), + ('next_bio', POINTER(bio_st)), + ('prev_bio', POINTER(bio_st)), + ('references', c_int), + ('num_read', c_ulong), + ('num_write', c_ulong), + ('ex_data', CRYPTO_EX_DATA), +] +assert sizeof(bio_st) == 64, sizeof(bio_st) +assert alignment(bio_st) == 4, alignment(bio_st) +class bio_f_buffer_ctx_struct(Structure): + pass +bio_f_buffer_ctx_struct._fields_ = [ + ('ibuf_size', c_int), + ('obuf_size', c_int), + ('ibuf', STRING), + ('ibuf_len', c_int), + ('ibuf_off', c_int), + ('obuf', STRING), + ('obuf_len', c_int), + ('obuf_off', c_int), +] +assert sizeof(bio_f_buffer_ctx_struct) == 32, sizeof(bio_f_buffer_ctx_struct) +assert alignment(bio_f_buffer_ctx_struct) == 4, alignment(bio_f_buffer_ctx_struct) +BIO_F_BUFFER_CTX = bio_f_buffer_ctx_struct +class hostent(Structure): + pass +hostent._fields_ = [ +] +class bf_key_st(Structure): + pass +bf_key_st._fields_ = [ + ('P', c_uint * 18), + ('S', c_uint * 1024), +] +assert sizeof(bf_key_st) == 4168, sizeof(bf_key_st) +assert alignment(bf_key_st) == 4, alignment(bf_key_st) +BF_KEY = bf_key_st +class bignum_st(Structure): + pass +bignum_st._fields_ = [ + ('d', POINTER(c_ulong)), + ('top', c_int), + ('dmax', c_int), + ('neg', c_int), + ('flags', c_int), +] +assert sizeof(bignum_st) == 20, sizeof(bignum_st) +assert alignment(bignum_st) == 4, alignment(bignum_st) +BIGNUM = bignum_st +class bignum_ctx(Structure): + pass +bignum_ctx._fields_ = [ +] +BN_CTX = bignum_ctx +class bn_blinding_st(Structure): + pass +bn_blinding_st._fields_ = [ + ('init', c_int), + ('A', POINTER(BIGNUM)), + ('Ai', POINTER(BIGNUM)), + ('mod', POINTER(BIGNUM)), + ('thread_id', c_ulong), +] +assert sizeof(bn_blinding_st) == 20, sizeof(bn_blinding_st) +assert alignment(bn_blinding_st) == 4, alignment(bn_blinding_st) +BN_BLINDING = bn_blinding_st +class bn_mont_ctx_st(Structure): + pass +bn_mont_ctx_st._fields_ = [ + ('ri', c_int), + ('RR', BIGNUM), + ('N', BIGNUM), + ('Ni', BIGNUM), + ('n0', c_ulong), + ('flags', c_int), +] +assert sizeof(bn_mont_ctx_st) == 72, sizeof(bn_mont_ctx_st) +assert alignment(bn_mont_ctx_st) == 4, alignment(bn_mont_ctx_st) +BN_MONT_CTX = bn_mont_ctx_st +class bn_recp_ctx_st(Structure): + pass +bn_recp_ctx_st._fields_ = [ + ('N', BIGNUM), + ('Nr', BIGNUM), + ('num_bits', c_int), + ('shift', c_int), + ('flags', c_int), +] +assert sizeof(bn_recp_ctx_st) == 52, sizeof(bn_recp_ctx_st) +assert alignment(bn_recp_ctx_st) == 4, alignment(bn_recp_ctx_st) +BN_RECP_CTX = bn_recp_ctx_st +class buf_mem_st(Structure): + pass +buf_mem_st._fields_ = [ + ('length', c_int), + ('data', STRING), + ('max', c_int), +] +assert sizeof(buf_mem_st) == 12, sizeof(buf_mem_st) +assert alignment(buf_mem_st) == 4, alignment(buf_mem_st) +BUF_MEM = buf_mem_st +class cast_key_st(Structure): + pass +cast_key_st._fields_ = [ + ('data', c_ulong * 32), + ('short_key', c_int), +] +assert sizeof(cast_key_st) == 132, sizeof(cast_key_st) +assert alignment(cast_key_st) == 4, alignment(cast_key_st) +CAST_KEY = cast_key_st +class comp_method_st(Structure): + pass +comp_method_st._fields_ = [ + ('type', c_int), + ('name', STRING), + ('init', CFUNCTYPE(c_int)), + ('finish', CFUNCTYPE(None)), + ('compress', CFUNCTYPE(c_int)), + ('expand', CFUNCTYPE(c_int)), + ('ctrl', CFUNCTYPE(c_long)), + ('callback_ctrl', CFUNCTYPE(c_long)), +] +assert sizeof(comp_method_st) == 32, sizeof(comp_method_st) +assert alignment(comp_method_st) == 4, alignment(comp_method_st) +COMP_METHOD = comp_method_st +class comp_ctx_st(Structure): + pass +comp_ctx_st._fields_ = [ + ('meth', POINTER(COMP_METHOD)), + ('compress_in', c_ulong), + ('compress_out', c_ulong), + ('expand_in', c_ulong), + ('expand_out', c_ulong), + ('ex_data', CRYPTO_EX_DATA), +] +assert sizeof(comp_ctx_st) == 28, sizeof(comp_ctx_st) +assert alignment(comp_ctx_st) == 4, alignment(comp_ctx_st) +COMP_CTX = comp_ctx_st +class CRYPTO_dynlock_value(Structure): + pass +CRYPTO_dynlock_value._fields_ = [ +] +class CRYPTO_dynlock(Structure): + pass +CRYPTO_dynlock._fields_ = [ + ('references', c_int), + ('data', POINTER(CRYPTO_dynlock_value)), +] +assert sizeof(CRYPTO_dynlock) == 8, sizeof(CRYPTO_dynlock) +assert alignment(CRYPTO_dynlock) == 4, alignment(CRYPTO_dynlock) +BIO_dummy = bio_st +CRYPTO_EX_new = CFUNCTYPE(c_int, c_void_p, c_void_p, POINTER(CRYPTO_EX_DATA), c_int, c_long, c_void_p) +CRYPTO_EX_free = CFUNCTYPE(None, c_void_p, c_void_p, POINTER(CRYPTO_EX_DATA), c_int, c_long, c_void_p) +CRYPTO_EX_dup = CFUNCTYPE(c_int, POINTER(CRYPTO_EX_DATA), POINTER(CRYPTO_EX_DATA), c_void_p, c_int, c_long, c_void_p) +class crypto_ex_data_func_st(Structure): + pass +crypto_ex_data_func_st._fields_ = [ + ('argl', c_long), + ('argp', c_void_p), + ('new_func', POINTER(CRYPTO_EX_new)), + ('free_func', POINTER(CRYPTO_EX_free)), + ('dup_func', POINTER(CRYPTO_EX_dup)), +] +assert sizeof(crypto_ex_data_func_st) == 20, sizeof(crypto_ex_data_func_st) +assert alignment(crypto_ex_data_func_st) == 4, alignment(crypto_ex_data_func_st) +CRYPTO_EX_DATA_FUNCS = crypto_ex_data_func_st +class st_CRYPTO_EX_DATA_IMPL(Structure): + pass +CRYPTO_EX_DATA_IMPL = st_CRYPTO_EX_DATA_IMPL +st_CRYPTO_EX_DATA_IMPL._fields_ = [ +] +CRYPTO_MEM_LEAK_CB = CFUNCTYPE(c_void_p, c_ulong, STRING, c_int, c_int, c_void_p) +DES_cblock = c_ubyte * 8 +const_DES_cblock = c_ubyte * 8 +class DES_ks(Structure): + pass +class N6DES_ks3DOLLAR_9E(Union): + pass +N6DES_ks3DOLLAR_9E._fields_ = [ + ('cblock', DES_cblock), + ('deslong', c_ulong * 2), +] +assert sizeof(N6DES_ks3DOLLAR_9E) == 8, sizeof(N6DES_ks3DOLLAR_9E) +assert alignment(N6DES_ks3DOLLAR_9E) == 4, alignment(N6DES_ks3DOLLAR_9E) +DES_ks._fields_ = [ + ('ks', N6DES_ks3DOLLAR_9E * 16), +] +assert sizeof(DES_ks) == 128, sizeof(DES_ks) +assert alignment(DES_ks) == 4, alignment(DES_ks) +DES_key_schedule = DES_ks +_ossl_old_des_cblock = c_ubyte * 8 +class _ossl_old_des_ks_struct(Structure): + pass +class N23_ossl_old_des_ks_struct4DOLLAR_10E(Union): + pass +N23_ossl_old_des_ks_struct4DOLLAR_10E._fields_ = [ + ('_', _ossl_old_des_cblock), + ('pad', c_ulong * 2), +] +assert sizeof(N23_ossl_old_des_ks_struct4DOLLAR_10E) == 8, sizeof(N23_ossl_old_des_ks_struct4DOLLAR_10E) +assert alignment(N23_ossl_old_des_ks_struct4DOLLAR_10E) == 4, alignment(N23_ossl_old_des_ks_struct4DOLLAR_10E) +_ossl_old_des_ks_struct._fields_ = [ + ('ks', N23_ossl_old_des_ks_struct4DOLLAR_10E), +] +assert sizeof(_ossl_old_des_ks_struct) == 8, sizeof(_ossl_old_des_ks_struct) +assert alignment(_ossl_old_des_ks_struct) == 4, alignment(_ossl_old_des_ks_struct) +_ossl_old_des_key_schedule = _ossl_old_des_ks_struct * 16 +class dh_st(Structure): + pass +DH = dh_st +class dh_method(Structure): + pass +dh_method._fields_ = [ + ('name', STRING), + ('generate_key', CFUNCTYPE(c_int, POINTER(DH))), + ('compute_key', CFUNCTYPE(c_int, POINTER(c_ubyte), POINTER(BIGNUM), POINTER(DH))), + ('bn_mod_exp', CFUNCTYPE(c_int, POINTER(DH), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BN_CTX), POINTER(BN_MONT_CTX))), + ('init', CFUNCTYPE(c_int, POINTER(DH))), + ('finish', CFUNCTYPE(c_int, POINTER(DH))), + ('flags', c_int), + ('app_data', STRING), +] +assert sizeof(dh_method) == 32, sizeof(dh_method) +assert alignment(dh_method) == 4, alignment(dh_method) +DH_METHOD = dh_method +class engine_st(Structure): + pass +ENGINE = engine_st +dh_st._fields_ = [ + ('pad', c_int), + ('version', c_int), + ('p', POINTER(BIGNUM)), + ('g', POINTER(BIGNUM)), + ('length', c_long), + ('pub_key', POINTER(BIGNUM)), + ('priv_key', POINTER(BIGNUM)), + ('flags', c_int), + ('method_mont_p', STRING), + ('q', POINTER(BIGNUM)), + ('j', POINTER(BIGNUM)), + ('seed', POINTER(c_ubyte)), + ('seedlen', c_int), + ('counter', POINTER(BIGNUM)), + ('references', c_int), + ('ex_data', CRYPTO_EX_DATA), + ('meth', POINTER(DH_METHOD)), + ('engine', POINTER(ENGINE)), +] +assert sizeof(dh_st) == 76, sizeof(dh_st) +assert alignment(dh_st) == 4, alignment(dh_st) +class dsa_st(Structure): + pass +DSA = dsa_st +class DSA_SIG_st(Structure): + pass +DSA_SIG_st._fields_ = [ + ('r', POINTER(BIGNUM)), + ('s', POINTER(BIGNUM)), +] +assert sizeof(DSA_SIG_st) == 8, sizeof(DSA_SIG_st) +assert alignment(DSA_SIG_st) == 4, alignment(DSA_SIG_st) +DSA_SIG = DSA_SIG_st +class dsa_method(Structure): + pass +dsa_method._fields_ = [ + ('name', STRING), + ('dsa_do_sign', CFUNCTYPE(POINTER(DSA_SIG), POINTER(c_ubyte), c_int, POINTER(DSA))), + ('dsa_sign_setup', CFUNCTYPE(c_int, POINTER(DSA), POINTER(BN_CTX), POINTER(POINTER(BIGNUM)), POINTER(POINTER(BIGNUM)))), + ('dsa_do_verify', CFUNCTYPE(c_int, POINTER(c_ubyte), c_int, POINTER(DSA_SIG), POINTER(DSA))), + ('dsa_mod_exp', CFUNCTYPE(c_int, POINTER(DSA), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BN_CTX), POINTER(BN_MONT_CTX))), + ('bn_mod_exp', CFUNCTYPE(c_int, POINTER(DSA), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BN_CTX), POINTER(BN_MONT_CTX))), + ('init', CFUNCTYPE(c_int, POINTER(DSA))), + ('finish', CFUNCTYPE(c_int, POINTER(DSA))), + ('flags', c_int), + ('app_data', STRING), +] +assert sizeof(dsa_method) == 40, sizeof(dsa_method) +assert alignment(dsa_method) == 4, alignment(dsa_method) +DSA_METHOD = dsa_method +dsa_st._fields_ = [ + ('pad', c_int), + ('version', c_long), + ('write_params', c_int), + ('p', POINTER(BIGNUM)), + ('q', POINTER(BIGNUM)), + ('g', POINTER(BIGNUM)), + ('pub_key', POINTER(BIGNUM)), + ('priv_key', POINTER(BIGNUM)), + ('kinv', POINTER(BIGNUM)), + ('r', POINTER(BIGNUM)), + ('flags', c_int), + ('method_mont_p', STRING), + ('references', c_int), + ('ex_data', CRYPTO_EX_DATA), + ('meth', POINTER(DSA_METHOD)), + ('engine', POINTER(ENGINE)), +] +assert sizeof(dsa_st) == 68, sizeof(dsa_st) +assert alignment(dsa_st) == 4, alignment(dsa_st) +class evp_pkey_st(Structure): + pass +class N11evp_pkey_st4DOLLAR_12E(Union): + pass +class rsa_st(Structure): + pass +N11evp_pkey_st4DOLLAR_12E._fields_ = [ + ('ptr', STRING), + ('rsa', POINTER(rsa_st)), + ('dsa', POINTER(dsa_st)), + ('dh', POINTER(dh_st)), +] +assert sizeof(N11evp_pkey_st4DOLLAR_12E) == 4, sizeof(N11evp_pkey_st4DOLLAR_12E) +assert alignment(N11evp_pkey_st4DOLLAR_12E) == 4, alignment(N11evp_pkey_st4DOLLAR_12E) +evp_pkey_st._fields_ = [ + ('type', c_int), + ('save_type', c_int), + ('references', c_int), + ('pkey', N11evp_pkey_st4DOLLAR_12E), + ('save_parameters', c_int), + ('attributes', POINTER(STACK)), +] +assert sizeof(evp_pkey_st) == 24, sizeof(evp_pkey_st) +assert alignment(evp_pkey_st) == 4, alignment(evp_pkey_st) +class env_md_st(Structure): + pass +class env_md_ctx_st(Structure): + pass +EVP_MD_CTX = env_md_ctx_st +env_md_st._fields_ = [ + ('type', c_int), + ('pkey_type', c_int), + ('md_size', c_int), + ('flags', c_ulong), + ('init', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX))), + ('update', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX), c_void_p, c_ulong)), + ('final', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX), POINTER(c_ubyte))), + ('copy', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX), POINTER(EVP_MD_CTX))), + ('cleanup', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX))), + ('sign', CFUNCTYPE(c_int)), + ('verify', CFUNCTYPE(c_int)), + ('required_pkey_type', c_int * 5), + ('block_size', c_int), + ('ctx_size', c_int), +] +assert sizeof(env_md_st) == 72, sizeof(env_md_st) +assert alignment(env_md_st) == 4, alignment(env_md_st) +EVP_MD = env_md_st +env_md_ctx_st._fields_ = [ + ('digest', POINTER(EVP_MD)), + ('engine', POINTER(ENGINE)), + ('flags', c_ulong), + ('md_data', c_void_p), +] +assert sizeof(env_md_ctx_st) == 16, sizeof(env_md_ctx_st) +assert alignment(env_md_ctx_st) == 4, alignment(env_md_ctx_st) +class evp_cipher_st(Structure): + pass +class evp_cipher_ctx_st(Structure): + pass +EVP_CIPHER_CTX = evp_cipher_ctx_st +evp_cipher_st._fields_ = [ + ('nid', c_int), + ('block_size', c_int), + ('key_len', c_int), + ('iv_len', c_int), + ('flags', c_ulong), + ('init', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), POINTER(c_ubyte), POINTER(c_ubyte), c_int)), + ('do_cipher', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), POINTER(c_ubyte), POINTER(c_ubyte), c_uint)), + ('cleanup', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX))), + ('ctx_size', c_int), + ('set_asn1_parameters', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), POINTER(ASN1_TYPE))), + ('get_asn1_parameters', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), POINTER(ASN1_TYPE))), + ('ctrl', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), c_int, c_int, c_void_p)), + ('app_data', c_void_p), +] +assert sizeof(evp_cipher_st) == 52, sizeof(evp_cipher_st) +assert alignment(evp_cipher_st) == 4, alignment(evp_cipher_st) +class evp_cipher_info_st(Structure): + pass +EVP_CIPHER = evp_cipher_st +evp_cipher_info_st._fields_ = [ + ('cipher', POINTER(EVP_CIPHER)), + ('iv', c_ubyte * 16), +] +assert sizeof(evp_cipher_info_st) == 20, sizeof(evp_cipher_info_st) +assert alignment(evp_cipher_info_st) == 4, alignment(evp_cipher_info_st) +EVP_CIPHER_INFO = evp_cipher_info_st +evp_cipher_ctx_st._fields_ = [ + ('cipher', POINTER(EVP_CIPHER)), + ('engine', POINTER(ENGINE)), + ('encrypt', c_int), + ('buf_len', c_int), + ('oiv', c_ubyte * 16), + ('iv', c_ubyte * 16), + ('buf', c_ubyte * 32), + ('num', c_int), + ('app_data', c_void_p), + ('key_len', c_int), + ('flags', c_ulong), + ('cipher_data', c_void_p), + ('final_used', c_int), + ('block_mask', c_int), + ('final', c_ubyte * 32), +] +assert sizeof(evp_cipher_ctx_st) == 140, sizeof(evp_cipher_ctx_st) +assert alignment(evp_cipher_ctx_st) == 4, alignment(evp_cipher_ctx_st) +class evp_Encode_Ctx_st(Structure): + pass +evp_Encode_Ctx_st._fields_ = [ + ('num', c_int), + ('length', c_int), + ('enc_data', c_ubyte * 80), + ('line_num', c_int), + ('expect_nl', c_int), +] +assert sizeof(evp_Encode_Ctx_st) == 96, sizeof(evp_Encode_Ctx_st) +assert alignment(evp_Encode_Ctx_st) == 4, alignment(evp_Encode_Ctx_st) +EVP_ENCODE_CTX = evp_Encode_Ctx_st +EVP_PBE_KEYGEN = CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), STRING, c_int, POINTER(ASN1_TYPE), POINTER(EVP_CIPHER), POINTER(EVP_MD), c_int) +class lhash_node_st(Structure): + pass +lhash_node_st._fields_ = [ + ('data', c_void_p), + ('next', POINTER(lhash_node_st)), + ('hash', c_ulong), +] +assert sizeof(lhash_node_st) == 12, sizeof(lhash_node_st) +assert alignment(lhash_node_st) == 4, alignment(lhash_node_st) +LHASH_NODE = lhash_node_st +LHASH_COMP_FN_TYPE = CFUNCTYPE(c_int, c_void_p, c_void_p) +LHASH_HASH_FN_TYPE = CFUNCTYPE(c_ulong, c_void_p) +LHASH_DOALL_FN_TYPE = CFUNCTYPE(None, c_void_p) +LHASH_DOALL_ARG_FN_TYPE = CFUNCTYPE(None, c_void_p, c_void_p) +class lhash_st(Structure): + pass +lhash_st._fields_ = [ + ('b', POINTER(POINTER(LHASH_NODE))), + ('comp', LHASH_COMP_FN_TYPE), + ('hash', LHASH_HASH_FN_TYPE), + ('num_nodes', c_uint), + ('num_alloc_nodes', c_uint), + ('p', c_uint), + ('pmax', c_uint), + ('up_load', c_ulong), + ('down_load', c_ulong), + ('num_items', c_ulong), + ('num_expands', c_ulong), + ('num_expand_reallocs', c_ulong), + ('num_contracts', c_ulong), + ('num_contract_reallocs', c_ulong), + ('num_hash_calls', c_ulong), + ('num_comp_calls', c_ulong), + ('num_insert', c_ulong), + ('num_replace', c_ulong), + ('num_delete', c_ulong), + ('num_no_delete', c_ulong), + ('num_retrieve', c_ulong), + ('num_retrieve_miss', c_ulong), + ('num_hash_comps', c_ulong), + ('error', c_int), +] +assert sizeof(lhash_st) == 96, sizeof(lhash_st) +assert alignment(lhash_st) == 4, alignment(lhash_st) +LHASH = lhash_st +class MD2state_st(Structure): + pass +MD2state_st._fields_ = [ + ('num', c_int), + ('data', c_ubyte * 16), + ('cksm', c_uint * 16), + ('state', c_uint * 16), +] +assert sizeof(MD2state_st) == 148, sizeof(MD2state_st) +assert alignment(MD2state_st) == 4, alignment(MD2state_st) +MD2_CTX = MD2state_st +class MD4state_st(Structure): + pass +MD4state_st._fields_ = [ + ('A', c_uint), + ('B', c_uint), + ('C', c_uint), + ('D', c_uint), + ('Nl', c_uint), + ('Nh', c_uint), + ('data', c_uint * 16), + ('num', c_int), +] +assert sizeof(MD4state_st) == 92, sizeof(MD4state_st) +assert alignment(MD4state_st) == 4, alignment(MD4state_st) +MD4_CTX = MD4state_st +class MD5state_st(Structure): + pass +MD5state_st._fields_ = [ + ('A', c_uint), + ('B', c_uint), + ('C', c_uint), + ('D', c_uint), + ('Nl', c_uint), + ('Nh', c_uint), + ('data', c_uint * 16), + ('num', c_int), +] +assert sizeof(MD5state_st) == 92, sizeof(MD5state_st) +assert alignment(MD5state_st) == 4, alignment(MD5state_st) +MD5_CTX = MD5state_st +class mdc2_ctx_st(Structure): + pass +mdc2_ctx_st._fields_ = [ + ('num', c_int), + ('data', c_ubyte * 8), + ('h', DES_cblock), + ('hh', DES_cblock), + ('pad_type', c_int), +] +assert sizeof(mdc2_ctx_st) == 32, sizeof(mdc2_ctx_st) +assert alignment(mdc2_ctx_st) == 4, alignment(mdc2_ctx_st) +MDC2_CTX = mdc2_ctx_st +class obj_name_st(Structure): + pass +obj_name_st._fields_ = [ + ('type', c_int), + ('alias', c_int), + ('name', STRING), + ('data', STRING), +] +assert sizeof(obj_name_st) == 16, sizeof(obj_name_st) +assert alignment(obj_name_st) == 4, alignment(obj_name_st) +OBJ_NAME = obj_name_st +ASN1_TIME = asn1_string_st +ASN1_NULL = c_int +EVP_PKEY = evp_pkey_st +class x509_st(Structure): + pass +X509 = x509_st +class X509_algor_st(Structure): + pass +X509_ALGOR = X509_algor_st +class X509_crl_st(Structure): + pass +X509_CRL = X509_crl_st +class X509_name_st(Structure): + pass +X509_NAME = X509_name_st +class x509_store_st(Structure): + pass +X509_STORE = x509_store_st +class x509_store_ctx_st(Structure): + pass +X509_STORE_CTX = x509_store_ctx_st +engine_st._fields_ = [ +] +class PEM_Encode_Seal_st(Structure): + pass +PEM_Encode_Seal_st._fields_ = [ + ('encode', EVP_ENCODE_CTX), + ('md', EVP_MD_CTX), + ('cipher', EVP_CIPHER_CTX), +] +assert sizeof(PEM_Encode_Seal_st) == 252, sizeof(PEM_Encode_Seal_st) +assert alignment(PEM_Encode_Seal_st) == 4, alignment(PEM_Encode_Seal_st) +PEM_ENCODE_SEAL_CTX = PEM_Encode_Seal_st +class pem_recip_st(Structure): + pass +pem_recip_st._fields_ = [ + ('name', STRING), + ('dn', POINTER(X509_NAME)), + ('cipher', c_int), + ('key_enc', c_int), +] +assert sizeof(pem_recip_st) == 16, sizeof(pem_recip_st) +assert alignment(pem_recip_st) == 4, alignment(pem_recip_st) +PEM_USER = pem_recip_st +class pem_ctx_st(Structure): + pass +class N10pem_ctx_st4DOLLAR_16E(Structure): + pass +N10pem_ctx_st4DOLLAR_16E._fields_ = [ + ('version', c_int), + ('mode', c_int), +] +assert sizeof(N10pem_ctx_st4DOLLAR_16E) == 8, sizeof(N10pem_ctx_st4DOLLAR_16E) +assert alignment(N10pem_ctx_st4DOLLAR_16E) == 4, alignment(N10pem_ctx_st4DOLLAR_16E) +class N10pem_ctx_st4DOLLAR_17E(Structure): + pass +N10pem_ctx_st4DOLLAR_17E._fields_ = [ + ('cipher', c_int), +] +assert sizeof(N10pem_ctx_st4DOLLAR_17E) == 4, sizeof(N10pem_ctx_st4DOLLAR_17E) +assert alignment(N10pem_ctx_st4DOLLAR_17E) == 4, alignment(N10pem_ctx_st4DOLLAR_17E) +pem_ctx_st._fields_ = [ + ('type', c_int), + ('proc_type', N10pem_ctx_st4DOLLAR_16E), + ('domain', STRING), + ('DEK_info', N10pem_ctx_st4DOLLAR_17E), + ('originator', POINTER(PEM_USER)), + ('num_recipient', c_int), + ('recipient', POINTER(POINTER(PEM_USER))), + ('x509_chain', POINTER(STACK)), + ('md', POINTER(EVP_MD)), + ('md_enc', c_int), + ('md_len', c_int), + ('md_data', STRING), + ('dec', POINTER(EVP_CIPHER)), + ('key_len', c_int), + ('key', POINTER(c_ubyte)), + ('data_enc', c_int), + ('data_len', c_int), + ('data', POINTER(c_ubyte)), +] +assert sizeof(pem_ctx_st) == 76, sizeof(pem_ctx_st) +assert alignment(pem_ctx_st) == 4, alignment(pem_ctx_st) +PEM_CTX = pem_ctx_st +pem_password_cb = CFUNCTYPE(c_int, STRING, c_int, c_int, c_void_p) +class pkcs7_issuer_and_serial_st(Structure): + pass +pkcs7_issuer_and_serial_st._fields_ = [ + ('issuer', POINTER(X509_NAME)), + ('serial', POINTER(ASN1_INTEGER)), +] +assert sizeof(pkcs7_issuer_and_serial_st) == 8, sizeof(pkcs7_issuer_and_serial_st) +assert alignment(pkcs7_issuer_and_serial_st) == 4, alignment(pkcs7_issuer_and_serial_st) +PKCS7_ISSUER_AND_SERIAL = pkcs7_issuer_and_serial_st +class pkcs7_signer_info_st(Structure): + pass +pkcs7_signer_info_st._fields_ = [ + ('version', POINTER(ASN1_INTEGER)), + ('issuer_and_serial', POINTER(PKCS7_ISSUER_AND_SERIAL)), + ('digest_alg', POINTER(X509_ALGOR)), + ('auth_attr', POINTER(STACK)), + ('digest_enc_alg', POINTER(X509_ALGOR)), + ('enc_digest', POINTER(ASN1_OCTET_STRING)), + ('unauth_attr', POINTER(STACK)), + ('pkey', POINTER(EVP_PKEY)), +] +assert sizeof(pkcs7_signer_info_st) == 32, sizeof(pkcs7_signer_info_st) +assert alignment(pkcs7_signer_info_st) == 4, alignment(pkcs7_signer_info_st) +PKCS7_SIGNER_INFO = pkcs7_signer_info_st +class pkcs7_recip_info_st(Structure): + pass +pkcs7_recip_info_st._fields_ = [ + ('version', POINTER(ASN1_INTEGER)), + ('issuer_and_serial', POINTER(PKCS7_ISSUER_AND_SERIAL)), + ('key_enc_algor', POINTER(X509_ALGOR)), + ('enc_key', POINTER(ASN1_OCTET_STRING)), + ('cert', POINTER(X509)), +] +assert sizeof(pkcs7_recip_info_st) == 20, sizeof(pkcs7_recip_info_st) +assert alignment(pkcs7_recip_info_st) == 4, alignment(pkcs7_recip_info_st) +PKCS7_RECIP_INFO = pkcs7_recip_info_st +class pkcs7_signed_st(Structure): + pass +class pkcs7_st(Structure): + pass +pkcs7_signed_st._fields_ = [ + ('version', POINTER(ASN1_INTEGER)), + ('md_algs', POINTER(STACK)), + ('cert', POINTER(STACK)), + ('crl', POINTER(STACK)), + ('signer_info', POINTER(STACK)), + ('contents', POINTER(pkcs7_st)), +] +assert sizeof(pkcs7_signed_st) == 24, sizeof(pkcs7_signed_st) +assert alignment(pkcs7_signed_st) == 4, alignment(pkcs7_signed_st) +PKCS7_SIGNED = pkcs7_signed_st +class pkcs7_enc_content_st(Structure): + pass +pkcs7_enc_content_st._fields_ = [ + ('content_type', POINTER(ASN1_OBJECT)), + ('algorithm', POINTER(X509_ALGOR)), + ('enc_data', POINTER(ASN1_OCTET_STRING)), + ('cipher', POINTER(EVP_CIPHER)), +] +assert sizeof(pkcs7_enc_content_st) == 16, sizeof(pkcs7_enc_content_st) +assert alignment(pkcs7_enc_content_st) == 4, alignment(pkcs7_enc_content_st) +PKCS7_ENC_CONTENT = pkcs7_enc_content_st +class pkcs7_enveloped_st(Structure): + pass +pkcs7_enveloped_st._fields_ = [ + ('version', POINTER(ASN1_INTEGER)), + ('recipientinfo', POINTER(STACK)), + ('enc_data', POINTER(PKCS7_ENC_CONTENT)), +] +assert sizeof(pkcs7_enveloped_st) == 12, sizeof(pkcs7_enveloped_st) +assert alignment(pkcs7_enveloped_st) == 4, alignment(pkcs7_enveloped_st) +PKCS7_ENVELOPE = pkcs7_enveloped_st +class pkcs7_signedandenveloped_st(Structure): + pass +pkcs7_signedandenveloped_st._fields_ = [ + ('version', POINTER(ASN1_INTEGER)), + ('md_algs', POINTER(STACK)), + ('cert', POINTER(STACK)), + ('crl', POINTER(STACK)), + ('signer_info', POINTER(STACK)), + ('enc_data', POINTER(PKCS7_ENC_CONTENT)), + ('recipientinfo', POINTER(STACK)), +] +assert sizeof(pkcs7_signedandenveloped_st) == 28, sizeof(pkcs7_signedandenveloped_st) +assert alignment(pkcs7_signedandenveloped_st) == 4, alignment(pkcs7_signedandenveloped_st) +PKCS7_SIGN_ENVELOPE = pkcs7_signedandenveloped_st +class pkcs7_digest_st(Structure): + pass +pkcs7_digest_st._fields_ = [ + ('version', POINTER(ASN1_INTEGER)), + ('md', POINTER(X509_ALGOR)), + ('contents', POINTER(pkcs7_st)), + ('digest', POINTER(ASN1_OCTET_STRING)), +] +assert sizeof(pkcs7_digest_st) == 16, sizeof(pkcs7_digest_st) +assert alignment(pkcs7_digest_st) == 4, alignment(pkcs7_digest_st) +PKCS7_DIGEST = pkcs7_digest_st +class pkcs7_encrypted_st(Structure): + pass +pkcs7_encrypted_st._fields_ = [ + ('version', POINTER(ASN1_INTEGER)), + ('enc_data', POINTER(PKCS7_ENC_CONTENT)), +] +assert sizeof(pkcs7_encrypted_st) == 8, sizeof(pkcs7_encrypted_st) +assert alignment(pkcs7_encrypted_st) == 4, alignment(pkcs7_encrypted_st) +PKCS7_ENCRYPT = pkcs7_encrypted_st +class N8pkcs7_st4DOLLAR_15E(Union): + pass +N8pkcs7_st4DOLLAR_15E._fields_ = [ + ('ptr', STRING), + ('data', POINTER(ASN1_OCTET_STRING)), + ('sign', POINTER(PKCS7_SIGNED)), + ('enveloped', POINTER(PKCS7_ENVELOPE)), + ('signed_and_enveloped', POINTER(PKCS7_SIGN_ENVELOPE)), + ('digest', POINTER(PKCS7_DIGEST)), + ('encrypted', POINTER(PKCS7_ENCRYPT)), + ('other', POINTER(ASN1_TYPE)), +] +assert sizeof(N8pkcs7_st4DOLLAR_15E) == 4, sizeof(N8pkcs7_st4DOLLAR_15E) +assert alignment(N8pkcs7_st4DOLLAR_15E) == 4, alignment(N8pkcs7_st4DOLLAR_15E) +pkcs7_st._fields_ = [ + ('asn1', POINTER(c_ubyte)), + ('length', c_long), + ('state', c_int), + ('detached', c_int), + ('type', POINTER(ASN1_OBJECT)), + ('d', N8pkcs7_st4DOLLAR_15E), +] +assert sizeof(pkcs7_st) == 24, sizeof(pkcs7_st) +assert alignment(pkcs7_st) == 4, alignment(pkcs7_st) +PKCS7 = pkcs7_st +class rc2_key_st(Structure): + pass +rc2_key_st._fields_ = [ + ('data', c_uint * 64), +] +assert sizeof(rc2_key_st) == 256, sizeof(rc2_key_st) +assert alignment(rc2_key_st) == 4, alignment(rc2_key_st) +RC2_KEY = rc2_key_st +class rc4_key_st(Structure): + pass +rc4_key_st._fields_ = [ + ('x', c_ubyte), + ('y', c_ubyte), + ('data', c_ubyte * 256), +] +assert sizeof(rc4_key_st) == 258, sizeof(rc4_key_st) +assert alignment(rc4_key_st) == 1, alignment(rc4_key_st) +RC4_KEY = rc4_key_st +class rc5_key_st(Structure): + pass +rc5_key_st._fields_ = [ + ('rounds', c_int), + ('data', c_ulong * 34), +] +assert sizeof(rc5_key_st) == 140, sizeof(rc5_key_st) +assert alignment(rc5_key_st) == 4, alignment(rc5_key_st) +RC5_32_KEY = rc5_key_st +class RIPEMD160state_st(Structure): + pass +RIPEMD160state_st._fields_ = [ + ('A', c_uint), + ('B', c_uint), + ('C', c_uint), + ('D', c_uint), + ('E', c_uint), + ('Nl', c_uint), + ('Nh', c_uint), + ('data', c_uint * 16), + ('num', c_int), +] +assert sizeof(RIPEMD160state_st) == 96, sizeof(RIPEMD160state_st) +assert alignment(RIPEMD160state_st) == 4, alignment(RIPEMD160state_st) +RIPEMD160_CTX = RIPEMD160state_st +RSA = rsa_st +class rsa_meth_st(Structure): + pass +rsa_meth_st._fields_ = [ + ('name', STRING), + ('rsa_pub_enc', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), POINTER(c_ubyte), POINTER(RSA), c_int)), + ('rsa_pub_dec', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), POINTER(c_ubyte), POINTER(RSA), c_int)), + ('rsa_priv_enc', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), POINTER(c_ubyte), POINTER(RSA), c_int)), + ('rsa_priv_dec', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), POINTER(c_ubyte), POINTER(RSA), c_int)), + ('rsa_mod_exp', CFUNCTYPE(c_int, POINTER(BIGNUM), POINTER(BIGNUM), POINTER(RSA))), + ('bn_mod_exp', CFUNCTYPE(c_int, POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BN_CTX), POINTER(BN_MONT_CTX))), + ('init', CFUNCTYPE(c_int, POINTER(RSA))), + ('finish', CFUNCTYPE(c_int, POINTER(RSA))), + ('flags', c_int), + ('app_data', STRING), + ('rsa_sign', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), c_uint, POINTER(c_ubyte), POINTER(c_uint), POINTER(RSA))), + ('rsa_verify', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), c_uint, POINTER(c_ubyte), c_uint, POINTER(RSA))), +] +assert sizeof(rsa_meth_st) == 52, sizeof(rsa_meth_st) +assert alignment(rsa_meth_st) == 4, alignment(rsa_meth_st) +RSA_METHOD = rsa_meth_st +rsa_st._fields_ = [ + ('pad', c_int), + ('version', c_long), + ('meth', POINTER(RSA_METHOD)), + ('engine', POINTER(ENGINE)), + ('n', POINTER(BIGNUM)), + ('e', POINTER(BIGNUM)), + ('d', POINTER(BIGNUM)), + ('p', POINTER(BIGNUM)), + ('q', POINTER(BIGNUM)), + ('dmp1', POINTER(BIGNUM)), + ('dmq1', POINTER(BIGNUM)), + ('iqmp', POINTER(BIGNUM)), + ('ex_data', CRYPTO_EX_DATA), + ('references', c_int), + ('flags', c_int), + ('_method_mod_n', POINTER(BN_MONT_CTX)), + ('_method_mod_p', POINTER(BN_MONT_CTX)), + ('_method_mod_q', POINTER(BN_MONT_CTX)), + ('bignum_data', STRING), + ('blinding', POINTER(BN_BLINDING)), +] +assert sizeof(rsa_st) == 84, sizeof(rsa_st) +assert alignment(rsa_st) == 4, alignment(rsa_st) +openssl_fptr = CFUNCTYPE(None) +class SHAstate_st(Structure): + pass +SHAstate_st._fields_ = [ + ('h0', c_uint), + ('h1', c_uint), + ('h2', c_uint), + ('h3', c_uint), + ('h4', c_uint), + ('Nl', c_uint), + ('Nh', c_uint), + ('data', c_uint * 16), + ('num', c_int), +] +assert sizeof(SHAstate_st) == 96, sizeof(SHAstate_st) +assert alignment(SHAstate_st) == 4, alignment(SHAstate_st) +SHA_CTX = SHAstate_st +class ssl_st(Structure): + pass +ssl_crock_st = POINTER(ssl_st) +class ssl_cipher_st(Structure): + pass +ssl_cipher_st._fields_ = [ + ('valid', c_int), + ('name', STRING), + ('id', c_ulong), + ('algorithms', c_ulong), + ('algo_strength', c_ulong), + ('algorithm2', c_ulong), + ('strength_bits', c_int), + ('alg_bits', c_int), + ('mask', c_ulong), + ('mask_strength', c_ulong), +] +assert sizeof(ssl_cipher_st) == 40, sizeof(ssl_cipher_st) +assert alignment(ssl_cipher_st) == 4, alignment(ssl_cipher_st) +SSL_CIPHER = ssl_cipher_st +SSL = ssl_st +class ssl_ctx_st(Structure): + pass +SSL_CTX = ssl_ctx_st +class ssl_method_st(Structure): + pass +class ssl3_enc_method(Structure): + pass +ssl_method_st._fields_ = [ + ('version', c_int), + ('ssl_new', CFUNCTYPE(c_int, POINTER(SSL))), + ('ssl_clear', CFUNCTYPE(None, POINTER(SSL))), + ('ssl_free', CFUNCTYPE(None, POINTER(SSL))), + ('ssl_accept', CFUNCTYPE(c_int, POINTER(SSL))), + ('ssl_connect', CFUNCTYPE(c_int, POINTER(SSL))), + ('ssl_read', CFUNCTYPE(c_int, POINTER(SSL), c_void_p, c_int)), + ('ssl_peek', CFUNCTYPE(c_int, POINTER(SSL), c_void_p, c_int)), + ('ssl_write', CFUNCTYPE(c_int, POINTER(SSL), c_void_p, c_int)), + ('ssl_shutdown', CFUNCTYPE(c_int, POINTER(SSL))), + ('ssl_renegotiate', CFUNCTYPE(c_int, POINTER(SSL))), + ('ssl_renegotiate_check', CFUNCTYPE(c_int, POINTER(SSL))), + ('ssl_ctrl', CFUNCTYPE(c_long, POINTER(SSL), c_int, c_long, c_void_p)), + ('ssl_ctx_ctrl', CFUNCTYPE(c_long, POINTER(SSL_CTX), c_int, c_long, c_void_p)), + ('get_cipher_by_char', CFUNCTYPE(POINTER(SSL_CIPHER), POINTER(c_ubyte))), + ('put_cipher_by_char', CFUNCTYPE(c_int, POINTER(SSL_CIPHER), POINTER(c_ubyte))), + ('ssl_pending', CFUNCTYPE(c_int, POINTER(SSL))), + ('num_ciphers', CFUNCTYPE(c_int)), + ('get_cipher', CFUNCTYPE(POINTER(SSL_CIPHER), c_uint)), + ('get_ssl_method', CFUNCTYPE(POINTER(ssl_method_st), c_int)), + ('get_timeout', CFUNCTYPE(c_long)), + ('ssl3_enc', POINTER(ssl3_enc_method)), + ('ssl_version', CFUNCTYPE(c_int)), + ('ssl_callback_ctrl', CFUNCTYPE(c_long, POINTER(SSL), c_int, CFUNCTYPE(None))), + ('ssl_ctx_callback_ctrl', CFUNCTYPE(c_long, POINTER(SSL_CTX), c_int, CFUNCTYPE(None))), +] +assert sizeof(ssl_method_st) == 100, sizeof(ssl_method_st) +assert alignment(ssl_method_st) == 4, alignment(ssl_method_st) +ssl3_enc_method._fields_ = [ +] +SSL_METHOD = ssl_method_st +class ssl_session_st(Structure): + pass +class sess_cert_st(Structure): + pass +ssl_session_st._fields_ = [ + ('ssl_version', c_int), + ('key_arg_length', c_uint), + ('key_arg', c_ubyte * 8), + ('master_key_length', c_int), + ('master_key', c_ubyte * 48), + ('session_id_length', c_uint), + ('session_id', c_ubyte * 32), + ('sid_ctx_length', c_uint), + ('sid_ctx', c_ubyte * 32), + ('not_resumable', c_int), + ('sess_cert', POINTER(sess_cert_st)), + ('peer', POINTER(X509)), + ('verify_result', c_long), + ('references', c_int), + ('timeout', c_long), + ('time', c_long), + ('compress_meth', c_int), + ('cipher', POINTER(SSL_CIPHER)), + ('cipher_id', c_ulong), + ('ciphers', POINTER(STACK)), + ('ex_data', CRYPTO_EX_DATA), + ('prev', POINTER(ssl_session_st)), + ('next', POINTER(ssl_session_st)), +] +assert sizeof(ssl_session_st) == 200, sizeof(ssl_session_st) +assert alignment(ssl_session_st) == 4, alignment(ssl_session_st) +sess_cert_st._fields_ = [ +] +SSL_SESSION = ssl_session_st +GEN_SESSION_CB = CFUNCTYPE(c_int, POINTER(SSL), POINTER(c_ubyte), POINTER(c_uint)) +class ssl_comp_st(Structure): + pass +ssl_comp_st._fields_ = [ + ('id', c_int), + ('name', STRING), + ('method', POINTER(COMP_METHOD)), +] +assert sizeof(ssl_comp_st) == 12, sizeof(ssl_comp_st) +assert alignment(ssl_comp_st) == 4, alignment(ssl_comp_st) +SSL_COMP = ssl_comp_st +class N10ssl_ctx_st4DOLLAR_18E(Structure): + pass +N10ssl_ctx_st4DOLLAR_18E._fields_ = [ + ('sess_connect', c_int), + ('sess_connect_renegotiate', c_int), + ('sess_connect_good', c_int), + ('sess_accept', c_int), + ('sess_accept_renegotiate', c_int), + ('sess_accept_good', c_int), + ('sess_miss', c_int), + ('sess_timeout', c_int), + ('sess_cache_full', c_int), + ('sess_hit', c_int), + ('sess_cb_hit', c_int), +] +assert sizeof(N10ssl_ctx_st4DOLLAR_18E) == 44, sizeof(N10ssl_ctx_st4DOLLAR_18E) +assert alignment(N10ssl_ctx_st4DOLLAR_18E) == 4, alignment(N10ssl_ctx_st4DOLLAR_18E) +class cert_st(Structure): + pass +ssl_ctx_st._fields_ = [ + ('method', POINTER(SSL_METHOD)), + ('cipher_list', POINTER(STACK)), + ('cipher_list_by_id', POINTER(STACK)), + ('cert_store', POINTER(x509_store_st)), + ('sessions', POINTER(lhash_st)), + ('session_cache_size', c_ulong), + ('session_cache_head', POINTER(ssl_session_st)), + ('session_cache_tail', POINTER(ssl_session_st)), + ('session_cache_mode', c_int), + ('session_timeout', c_long), + ('new_session_cb', CFUNCTYPE(c_int, POINTER(ssl_st), POINTER(SSL_SESSION))), + ('remove_session_cb', CFUNCTYPE(None, POINTER(ssl_ctx_st), POINTER(SSL_SESSION))), + ('get_session_cb', CFUNCTYPE(POINTER(SSL_SESSION), POINTER(ssl_st), POINTER(c_ubyte), c_int, POINTER(c_int))), + ('stats', N10ssl_ctx_st4DOLLAR_18E), + ('references', c_int), + ('app_verify_callback', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), c_void_p)), + ('app_verify_arg', c_void_p), + ('default_passwd_callback', POINTER(pem_password_cb)), + ('default_passwd_callback_userdata', c_void_p), + ('client_cert_cb', CFUNCTYPE(c_int, POINTER(SSL), POINTER(POINTER(X509)), POINTER(POINTER(EVP_PKEY)))), + ('ex_data', CRYPTO_EX_DATA), + ('rsa_md5', POINTER(EVP_MD)), + ('md5', POINTER(EVP_MD)), + ('sha1', POINTER(EVP_MD)), + ('extra_certs', POINTER(STACK)), + ('comp_methods', POINTER(STACK)), + ('info_callback', CFUNCTYPE(None, POINTER(SSL), c_int, c_int)), + ('client_CA', POINTER(STACK)), + ('options', c_ulong), + ('mode', c_ulong), + ('max_cert_list', c_long), + ('cert', POINTER(cert_st)), + ('read_ahead', c_int), + ('msg_callback', CFUNCTYPE(None, c_int, c_int, c_int, c_void_p, c_ulong, POINTER(SSL), c_void_p)), + ('msg_callback_arg', c_void_p), + ('verify_mode', c_int), + ('verify_depth', c_int), + ('sid_ctx_length', c_uint), + ('sid_ctx', c_ubyte * 32), + ('default_verify_callback', CFUNCTYPE(c_int, c_int, POINTER(X509_STORE_CTX))), + ('generate_session_id', GEN_SESSION_CB), + ('purpose', c_int), + ('trust', c_int), + ('quiet_shutdown', c_int), +] +assert sizeof(ssl_ctx_st) == 248, sizeof(ssl_ctx_st) +assert alignment(ssl_ctx_st) == 4, alignment(ssl_ctx_st) +cert_st._fields_ = [ +] +class ssl2_state_st(Structure): + pass +class ssl3_state_st(Structure): + pass +ssl_st._fields_ = [ + ('version', c_int), + ('type', c_int), + ('method', POINTER(SSL_METHOD)), + ('rbio', POINTER(BIO)), + ('wbio', POINTER(BIO)), + ('bbio', POINTER(BIO)), + ('rwstate', c_int), + ('in_handshake', c_int), + ('handshake_func', CFUNCTYPE(c_int)), + ('server', c_int), + ('new_session', c_int), + ('quiet_shutdown', c_int), + ('shutdown', c_int), + ('state', c_int), + ('rstate', c_int), + ('init_buf', POINTER(BUF_MEM)), + ('init_msg', c_void_p), + ('init_num', c_int), + ('init_off', c_int), + ('packet', POINTER(c_ubyte)), + ('packet_length', c_uint), + ('s2', POINTER(ssl2_state_st)), + ('s3', POINTER(ssl3_state_st)), + ('read_ahead', c_int), + ('msg_callback', CFUNCTYPE(None, c_int, c_int, c_int, c_void_p, c_ulong, POINTER(SSL), c_void_p)), + ('msg_callback_arg', c_void_p), + ('hit', c_int), + ('purpose', c_int), + ('trust', c_int), + ('cipher_list', POINTER(STACK)), + ('cipher_list_by_id', POINTER(STACK)), + ('enc_read_ctx', POINTER(EVP_CIPHER_CTX)), + ('read_hash', POINTER(EVP_MD)), + ('expand', POINTER(COMP_CTX)), + ('enc_write_ctx', POINTER(EVP_CIPHER_CTX)), + ('write_hash', POINTER(EVP_MD)), + ('compress', POINTER(COMP_CTX)), + ('cert', POINTER(cert_st)), + ('sid_ctx_length', c_uint), + ('sid_ctx', c_ubyte * 32), + ('session', POINTER(SSL_SESSION)), + ('generate_session_id', GEN_SESSION_CB), + ('verify_mode', c_int), + ('verify_depth', c_int), + ('verify_callback', CFUNCTYPE(c_int, c_int, POINTER(X509_STORE_CTX))), + ('info_callback', CFUNCTYPE(None, POINTER(SSL), c_int, c_int)), + ('error', c_int), + ('error_code', c_int), + ('ctx', POINTER(SSL_CTX)), + ('debug', c_int), + ('verify_result', c_long), + ('ex_data', CRYPTO_EX_DATA), + ('client_CA', POINTER(STACK)), + ('references', c_int), + ('options', c_ulong), + ('mode', c_ulong), + ('max_cert_list', c_long), + ('first_packet', c_int), + ('client_version', c_int), +] +assert sizeof(ssl_st) == 268, sizeof(ssl_st) +assert alignment(ssl_st) == 4, alignment(ssl_st) +class N13ssl2_state_st4DOLLAR_19E(Structure): + pass +N13ssl2_state_st4DOLLAR_19E._fields_ = [ + ('conn_id_length', c_uint), + ('cert_type', c_uint), + ('cert_length', c_uint), + ('csl', c_uint), + ('clear', c_uint), + ('enc', c_uint), + ('ccl', c_ubyte * 32), + ('cipher_spec_length', c_uint), + ('session_id_length', c_uint), + ('clen', c_uint), + ('rlen', c_uint), +] +assert sizeof(N13ssl2_state_st4DOLLAR_19E) == 72, sizeof(N13ssl2_state_st4DOLLAR_19E) +assert alignment(N13ssl2_state_st4DOLLAR_19E) == 4, alignment(N13ssl2_state_st4DOLLAR_19E) +ssl2_state_st._fields_ = [ + ('three_byte_header', c_int), + ('clear_text', c_int), + ('escape', c_int), + ('ssl2_rollback', c_int), + ('wnum', c_uint), + ('wpend_tot', c_int), + ('wpend_buf', POINTER(c_ubyte)), + ('wpend_off', c_int), + ('wpend_len', c_int), + ('wpend_ret', c_int), + ('rbuf_left', c_int), + ('rbuf_offs', c_int), + ('rbuf', POINTER(c_ubyte)), + ('wbuf', POINTER(c_ubyte)), + ('write_ptr', POINTER(c_ubyte)), + ('padding', c_uint), + ('rlength', c_uint), + ('ract_data_length', c_int), + ('wlength', c_uint), + ('wact_data_length', c_int), + ('ract_data', POINTER(c_ubyte)), + ('wact_data', POINTER(c_ubyte)), + ('mac_data', POINTER(c_ubyte)), + ('read_key', POINTER(c_ubyte)), + ('write_key', POINTER(c_ubyte)), + ('challenge_length', c_uint), + ('challenge', c_ubyte * 32), + ('conn_id_length', c_uint), + ('conn_id', c_ubyte * 16), + ('key_material_length', c_uint), + ('key_material', c_ubyte * 48), + ('read_sequence', c_ulong), + ('write_sequence', c_ulong), + ('tmp', N13ssl2_state_st4DOLLAR_19E), +] +assert sizeof(ssl2_state_st) == 288, sizeof(ssl2_state_st) +assert alignment(ssl2_state_st) == 4, alignment(ssl2_state_st) +SSL2_STATE = ssl2_state_st +class ssl3_record_st(Structure): + pass +ssl3_record_st._fields_ = [ + ('type', c_int), + ('length', c_uint), + ('off', c_uint), + ('data', POINTER(c_ubyte)), + ('input', POINTER(c_ubyte)), + ('comp', POINTER(c_ubyte)), +] +assert sizeof(ssl3_record_st) == 24, sizeof(ssl3_record_st) +assert alignment(ssl3_record_st) == 4, alignment(ssl3_record_st) +SSL3_RECORD = ssl3_record_st +class ssl3_buffer_st(Structure): + pass +size_t = __darwin_size_t +ssl3_buffer_st._fields_ = [ + ('buf', POINTER(c_ubyte)), + ('len', size_t), + ('offset', c_int), + ('left', c_int), +] +assert sizeof(ssl3_buffer_st) == 16, sizeof(ssl3_buffer_st) +assert alignment(ssl3_buffer_st) == 4, alignment(ssl3_buffer_st) +SSL3_BUFFER = ssl3_buffer_st +class N13ssl3_state_st4DOLLAR_20E(Structure): + pass +N13ssl3_state_st4DOLLAR_20E._fields_ = [ + ('cert_verify_md', c_ubyte * 72), + ('finish_md', c_ubyte * 72), + ('finish_md_len', c_int), + ('peer_finish_md', c_ubyte * 72), + ('peer_finish_md_len', c_int), + ('message_size', c_ulong), + ('message_type', c_int), + ('new_cipher', POINTER(SSL_CIPHER)), + ('dh', POINTER(DH)), + ('next_state', c_int), + ('reuse_message', c_int), + ('cert_req', c_int), + ('ctype_num', c_int), + ('ctype', c_char * 7), + ('ca_names', POINTER(STACK)), + ('use_rsa_tmp', c_int), + ('key_block_length', c_int), + ('key_block', POINTER(c_ubyte)), + ('new_sym_enc', POINTER(EVP_CIPHER)), + ('new_hash', POINTER(EVP_MD)), + ('new_compression', POINTER(SSL_COMP)), + ('cert_request', c_int), +] +assert sizeof(N13ssl3_state_st4DOLLAR_20E) == 296, sizeof(N13ssl3_state_st4DOLLAR_20E) +assert alignment(N13ssl3_state_st4DOLLAR_20E) == 4, alignment(N13ssl3_state_st4DOLLAR_20E) +ssl3_state_st._fields_ = [ + ('flags', c_long), + ('delay_buf_pop_ret', c_int), + ('read_sequence', c_ubyte * 8), + ('read_mac_secret', c_ubyte * 36), + ('write_sequence', c_ubyte * 8), + ('write_mac_secret', c_ubyte * 36), + ('server_random', c_ubyte * 32), + ('client_random', c_ubyte * 32), + ('need_empty_fragments', c_int), + ('empty_fragment_done', c_int), + ('rbuf', SSL3_BUFFER), + ('wbuf', SSL3_BUFFER), + ('rrec', SSL3_RECORD), + ('wrec', SSL3_RECORD), + ('alert_fragment', c_ubyte * 2), + ('alert_fragment_len', c_uint), + ('handshake_fragment', c_ubyte * 4), + ('handshake_fragment_len', c_uint), + ('wnum', c_uint), + ('wpend_tot', c_int), + ('wpend_type', c_int), + ('wpend_ret', c_int), + ('wpend_buf', POINTER(c_ubyte)), + ('finish_dgst1', EVP_MD_CTX), + ('finish_dgst2', EVP_MD_CTX), + ('change_cipher_spec', c_int), + ('warn_alert', c_int), + ('fatal_alert', c_int), + ('alert_dispatch', c_int), + ('send_alert', c_ubyte * 2), + ('renegotiate', c_int), + ('total_renegotiations', c_int), + ('num_renegotiations', c_int), + ('in_read_app_data', c_int), + ('tmp', N13ssl3_state_st4DOLLAR_20E), +] +assert sizeof(ssl3_state_st) == 648, sizeof(ssl3_state_st) +assert alignment(ssl3_state_st) == 4, alignment(ssl3_state_st) +SSL3_STATE = ssl3_state_st +stack_st._fields_ = [ + ('num', c_int), + ('data', POINTER(STRING)), + ('sorted', c_int), + ('num_alloc', c_int), + ('comp', CFUNCTYPE(c_int, POINTER(STRING), POINTER(STRING))), +] +assert sizeof(stack_st) == 20, sizeof(stack_st) +assert alignment(stack_st) == 4, alignment(stack_st) +class ui_st(Structure): + pass +ui_st._fields_ = [ +] +UI = ui_st +class ui_method_st(Structure): + pass +ui_method_st._fields_ = [ +] +UI_METHOD = ui_method_st +class ui_string_st(Structure): + pass +ui_string_st._fields_ = [ +] +UI_STRING = ui_string_st + +# values for enumeration 'UI_string_types' +UI_string_types = c_int # enum +class X509_objects_st(Structure): + pass +X509_objects_st._fields_ = [ + ('nid', c_int), + ('a2i', CFUNCTYPE(c_int)), + ('i2a', CFUNCTYPE(c_int)), +] +assert sizeof(X509_objects_st) == 12, sizeof(X509_objects_st) +assert alignment(X509_objects_st) == 4, alignment(X509_objects_st) +X509_OBJECTS = X509_objects_st +X509_algor_st._fields_ = [ + ('algorithm', POINTER(ASN1_OBJECT)), + ('parameter', POINTER(ASN1_TYPE)), +] +assert sizeof(X509_algor_st) == 8, sizeof(X509_algor_st) +assert alignment(X509_algor_st) == 4, alignment(X509_algor_st) +class X509_val_st(Structure): + pass +X509_val_st._fields_ = [ + ('notBefore', POINTER(ASN1_TIME)), + ('notAfter', POINTER(ASN1_TIME)), +] +assert sizeof(X509_val_st) == 8, sizeof(X509_val_st) +assert alignment(X509_val_st) == 4, alignment(X509_val_st) +X509_VAL = X509_val_st +class X509_pubkey_st(Structure): + pass +X509_pubkey_st._fields_ = [ + ('algor', POINTER(X509_ALGOR)), + ('public_key', POINTER(ASN1_BIT_STRING)), + ('pkey', POINTER(EVP_PKEY)), +] +assert sizeof(X509_pubkey_st) == 12, sizeof(X509_pubkey_st) +assert alignment(X509_pubkey_st) == 4, alignment(X509_pubkey_st) +X509_PUBKEY = X509_pubkey_st +class X509_sig_st(Structure): + pass +X509_sig_st._fields_ = [ + ('algor', POINTER(X509_ALGOR)), + ('digest', POINTER(ASN1_OCTET_STRING)), +] +assert sizeof(X509_sig_st) == 8, sizeof(X509_sig_st) +assert alignment(X509_sig_st) == 4, alignment(X509_sig_st) +X509_SIG = X509_sig_st +class X509_name_entry_st(Structure): + pass +X509_name_entry_st._fields_ = [ + ('object', POINTER(ASN1_OBJECT)), + ('value', POINTER(ASN1_STRING)), + ('set', c_int), + ('size', c_int), +] +assert sizeof(X509_name_entry_st) == 16, sizeof(X509_name_entry_st) +assert alignment(X509_name_entry_st) == 4, alignment(X509_name_entry_st) +X509_NAME_ENTRY = X509_name_entry_st +X509_name_st._fields_ = [ + ('entries', POINTER(STACK)), + ('modified', c_int), + ('bytes', POINTER(BUF_MEM)), + ('hash', c_ulong), +] +assert sizeof(X509_name_st) == 16, sizeof(X509_name_st) +assert alignment(X509_name_st) == 4, alignment(X509_name_st) +class X509_extension_st(Structure): + pass +X509_extension_st._fields_ = [ + ('object', POINTER(ASN1_OBJECT)), + ('critical', ASN1_BOOLEAN), + ('value', POINTER(ASN1_OCTET_STRING)), +] +assert sizeof(X509_extension_st) == 12, sizeof(X509_extension_st) +assert alignment(X509_extension_st) == 4, alignment(X509_extension_st) +X509_EXTENSION = X509_extension_st +class x509_attributes_st(Structure): + pass +class N18x509_attributes_st4DOLLAR_13E(Union): + pass +N18x509_attributes_st4DOLLAR_13E._fields_ = [ + ('ptr', STRING), + ('set', POINTER(STACK)), + ('single', POINTER(ASN1_TYPE)), +] +assert sizeof(N18x509_attributes_st4DOLLAR_13E) == 4, sizeof(N18x509_attributes_st4DOLLAR_13E) +assert alignment(N18x509_attributes_st4DOLLAR_13E) == 4, alignment(N18x509_attributes_st4DOLLAR_13E) +x509_attributes_st._fields_ = [ + ('object', POINTER(ASN1_OBJECT)), + ('single', c_int), + ('value', N18x509_attributes_st4DOLLAR_13E), +] +assert sizeof(x509_attributes_st) == 12, sizeof(x509_attributes_st) +assert alignment(x509_attributes_st) == 4, alignment(x509_attributes_st) +X509_ATTRIBUTE = x509_attributes_st +class X509_req_info_st(Structure): + pass +X509_req_info_st._fields_ = [ + ('enc', ASN1_ENCODING), + ('version', POINTER(ASN1_INTEGER)), + ('subject', POINTER(X509_NAME)), + ('pubkey', POINTER(X509_PUBKEY)), + ('attributes', POINTER(STACK)), +] +assert sizeof(X509_req_info_st) == 28, sizeof(X509_req_info_st) +assert alignment(X509_req_info_st) == 4, alignment(X509_req_info_st) +X509_REQ_INFO = X509_req_info_st +class X509_req_st(Structure): + pass +X509_req_st._fields_ = [ + ('req_info', POINTER(X509_REQ_INFO)), + ('sig_alg', POINTER(X509_ALGOR)), + ('signature', POINTER(ASN1_BIT_STRING)), + ('references', c_int), +] +assert sizeof(X509_req_st) == 16, sizeof(X509_req_st) +assert alignment(X509_req_st) == 4, alignment(X509_req_st) +X509_REQ = X509_req_st +class x509_cinf_st(Structure): + pass +x509_cinf_st._fields_ = [ + ('version', POINTER(ASN1_INTEGER)), + ('serialNumber', POINTER(ASN1_INTEGER)), + ('signature', POINTER(X509_ALGOR)), + ('issuer', POINTER(X509_NAME)), + ('validity', POINTER(X509_VAL)), + ('subject', POINTER(X509_NAME)), + ('key', POINTER(X509_PUBKEY)), + ('issuerUID', POINTER(ASN1_BIT_STRING)), + ('subjectUID', POINTER(ASN1_BIT_STRING)), + ('extensions', POINTER(STACK)), +] +assert sizeof(x509_cinf_st) == 40, sizeof(x509_cinf_st) +assert alignment(x509_cinf_st) == 4, alignment(x509_cinf_st) +X509_CINF = x509_cinf_st +class x509_cert_aux_st(Structure): + pass +x509_cert_aux_st._fields_ = [ + ('trust', POINTER(STACK)), + ('reject', POINTER(STACK)), + ('alias', POINTER(ASN1_UTF8STRING)), + ('keyid', POINTER(ASN1_OCTET_STRING)), + ('other', POINTER(STACK)), +] +assert sizeof(x509_cert_aux_st) == 20, sizeof(x509_cert_aux_st) +assert alignment(x509_cert_aux_st) == 4, alignment(x509_cert_aux_st) +X509_CERT_AUX = x509_cert_aux_st +class AUTHORITY_KEYID_st(Structure): + pass +x509_st._fields_ = [ + ('cert_info', POINTER(X509_CINF)), + ('sig_alg', POINTER(X509_ALGOR)), + ('signature', POINTER(ASN1_BIT_STRING)), + ('valid', c_int), + ('references', c_int), + ('name', STRING), + ('ex_data', CRYPTO_EX_DATA), + ('ex_pathlen', c_long), + ('ex_flags', c_ulong), + ('ex_kusage', c_ulong), + ('ex_xkusage', c_ulong), + ('ex_nscert', c_ulong), + ('skid', POINTER(ASN1_OCTET_STRING)), + ('akid', POINTER(AUTHORITY_KEYID_st)), + ('sha1_hash', c_ubyte * 20), + ('aux', POINTER(X509_CERT_AUX)), +] +assert sizeof(x509_st) == 84, sizeof(x509_st) +assert alignment(x509_st) == 4, alignment(x509_st) +AUTHORITY_KEYID_st._fields_ = [ +] +class x509_trust_st(Structure): + pass +x509_trust_st._fields_ = [ + ('trust', c_int), + ('flags', c_int), + ('check_trust', CFUNCTYPE(c_int, POINTER(x509_trust_st), POINTER(X509), c_int)), + ('name', STRING), + ('arg1', c_int), + ('arg2', c_void_p), +] +assert sizeof(x509_trust_st) == 24, sizeof(x509_trust_st) +assert alignment(x509_trust_st) == 4, alignment(x509_trust_st) +X509_TRUST = x509_trust_st +class X509_revoked_st(Structure): + pass +X509_revoked_st._fields_ = [ + ('serialNumber', POINTER(ASN1_INTEGER)), + ('revocationDate', POINTER(ASN1_TIME)), + ('extensions', POINTER(STACK)), + ('sequence', c_int), +] +assert sizeof(X509_revoked_st) == 16, sizeof(X509_revoked_st) +assert alignment(X509_revoked_st) == 4, alignment(X509_revoked_st) +X509_REVOKED = X509_revoked_st +class X509_crl_info_st(Structure): + pass +X509_crl_info_st._fields_ = [ + ('version', POINTER(ASN1_INTEGER)), + ('sig_alg', POINTER(X509_ALGOR)), + ('issuer', POINTER(X509_NAME)), + ('lastUpdate', POINTER(ASN1_TIME)), + ('nextUpdate', POINTER(ASN1_TIME)), + ('revoked', POINTER(STACK)), + ('extensions', POINTER(STACK)), + ('enc', ASN1_ENCODING), +] +assert sizeof(X509_crl_info_st) == 40, sizeof(X509_crl_info_st) +assert alignment(X509_crl_info_st) == 4, alignment(X509_crl_info_st) +X509_CRL_INFO = X509_crl_info_st +X509_crl_st._fields_ = [ + ('crl', POINTER(X509_CRL_INFO)), + ('sig_alg', POINTER(X509_ALGOR)), + ('signature', POINTER(ASN1_BIT_STRING)), + ('references', c_int), +] +assert sizeof(X509_crl_st) == 16, sizeof(X509_crl_st) +assert alignment(X509_crl_st) == 4, alignment(X509_crl_st) +class private_key_st(Structure): + pass +private_key_st._fields_ = [ + ('version', c_int), + ('enc_algor', POINTER(X509_ALGOR)), + ('enc_pkey', POINTER(ASN1_OCTET_STRING)), + ('dec_pkey', POINTER(EVP_PKEY)), + ('key_length', c_int), + ('key_data', STRING), + ('key_free', c_int), + ('cipher', EVP_CIPHER_INFO), + ('references', c_int), +] +assert sizeof(private_key_st) == 52, sizeof(private_key_st) +assert alignment(private_key_st) == 4, alignment(private_key_st) +X509_PKEY = private_key_st +class X509_info_st(Structure): + pass +X509_info_st._fields_ = [ + ('x509', POINTER(X509)), + ('crl', POINTER(X509_CRL)), + ('x_pkey', POINTER(X509_PKEY)), + ('enc_cipher', EVP_CIPHER_INFO), + ('enc_len', c_int), + ('enc_data', STRING), + ('references', c_int), +] +assert sizeof(X509_info_st) == 44, sizeof(X509_info_st) +assert alignment(X509_info_st) == 4, alignment(X509_info_st) +X509_INFO = X509_info_st +class Netscape_spkac_st(Structure): + pass +Netscape_spkac_st._fields_ = [ + ('pubkey', POINTER(X509_PUBKEY)), + ('challenge', POINTER(ASN1_IA5STRING)), +] +assert sizeof(Netscape_spkac_st) == 8, sizeof(Netscape_spkac_st) +assert alignment(Netscape_spkac_st) == 4, alignment(Netscape_spkac_st) +NETSCAPE_SPKAC = Netscape_spkac_st +class Netscape_spki_st(Structure): + pass +Netscape_spki_st._fields_ = [ + ('spkac', POINTER(NETSCAPE_SPKAC)), + ('sig_algor', POINTER(X509_ALGOR)), + ('signature', POINTER(ASN1_BIT_STRING)), +] +assert sizeof(Netscape_spki_st) == 12, sizeof(Netscape_spki_st) +assert alignment(Netscape_spki_st) == 4, alignment(Netscape_spki_st) +NETSCAPE_SPKI = Netscape_spki_st +class Netscape_certificate_sequence(Structure): + pass +Netscape_certificate_sequence._fields_ = [ + ('type', POINTER(ASN1_OBJECT)), + ('certs', POINTER(STACK)), +] +assert sizeof(Netscape_certificate_sequence) == 8, sizeof(Netscape_certificate_sequence) +assert alignment(Netscape_certificate_sequence) == 4, alignment(Netscape_certificate_sequence) +NETSCAPE_CERT_SEQUENCE = Netscape_certificate_sequence +class PBEPARAM_st(Structure): + pass +PBEPARAM_st._fields_ = [ + ('salt', POINTER(ASN1_OCTET_STRING)), + ('iter', POINTER(ASN1_INTEGER)), +] +assert sizeof(PBEPARAM_st) == 8, sizeof(PBEPARAM_st) +assert alignment(PBEPARAM_st) == 4, alignment(PBEPARAM_st) +PBEPARAM = PBEPARAM_st +class PBE2PARAM_st(Structure): + pass +PBE2PARAM_st._fields_ = [ + ('keyfunc', POINTER(X509_ALGOR)), + ('encryption', POINTER(X509_ALGOR)), +] +assert sizeof(PBE2PARAM_st) == 8, sizeof(PBE2PARAM_st) +assert alignment(PBE2PARAM_st) == 4, alignment(PBE2PARAM_st) +PBE2PARAM = PBE2PARAM_st +class PBKDF2PARAM_st(Structure): + pass +PBKDF2PARAM_st._fields_ = [ + ('salt', POINTER(ASN1_TYPE)), + ('iter', POINTER(ASN1_INTEGER)), + ('keylength', POINTER(ASN1_INTEGER)), + ('prf', POINTER(X509_ALGOR)), +] +assert sizeof(PBKDF2PARAM_st) == 16, sizeof(PBKDF2PARAM_st) +assert alignment(PBKDF2PARAM_st) == 4, alignment(PBKDF2PARAM_st) +PBKDF2PARAM = PBKDF2PARAM_st +class pkcs8_priv_key_info_st(Structure): + pass +pkcs8_priv_key_info_st._fields_ = [ + ('broken', c_int), + ('version', POINTER(ASN1_INTEGER)), + ('pkeyalg', POINTER(X509_ALGOR)), + ('pkey', POINTER(ASN1_TYPE)), + ('attributes', POINTER(STACK)), +] +assert sizeof(pkcs8_priv_key_info_st) == 20, sizeof(pkcs8_priv_key_info_st) +assert alignment(pkcs8_priv_key_info_st) == 4, alignment(pkcs8_priv_key_info_st) +PKCS8_PRIV_KEY_INFO = pkcs8_priv_key_info_st +class x509_hash_dir_st(Structure): + pass +x509_hash_dir_st._fields_ = [ + ('num_dirs', c_int), + ('dirs', POINTER(STRING)), + ('dirs_type', POINTER(c_int)), + ('num_dirs_alloced', c_int), +] +assert sizeof(x509_hash_dir_st) == 16, sizeof(x509_hash_dir_st) +assert alignment(x509_hash_dir_st) == 4, alignment(x509_hash_dir_st) +X509_HASH_DIR_CTX = x509_hash_dir_st +class x509_file_st(Structure): + pass +x509_file_st._fields_ = [ + ('num_paths', c_int), + ('num_alloced', c_int), + ('paths', POINTER(STRING)), + ('path_type', POINTER(c_int)), +] +assert sizeof(x509_file_st) == 16, sizeof(x509_file_st) +assert alignment(x509_file_st) == 4, alignment(x509_file_st) +X509_CERT_FILE_CTX = x509_file_st +class x509_object_st(Structure): + pass +class N14x509_object_st4DOLLAR_14E(Union): + pass +N14x509_object_st4DOLLAR_14E._fields_ = [ + ('ptr', STRING), + ('x509', POINTER(X509)), + ('crl', POINTER(X509_CRL)), + ('pkey', POINTER(EVP_PKEY)), +] +assert sizeof(N14x509_object_st4DOLLAR_14E) == 4, sizeof(N14x509_object_st4DOLLAR_14E) +assert alignment(N14x509_object_st4DOLLAR_14E) == 4, alignment(N14x509_object_st4DOLLAR_14E) +x509_object_st._fields_ = [ + ('type', c_int), + ('data', N14x509_object_st4DOLLAR_14E), +] +assert sizeof(x509_object_st) == 8, sizeof(x509_object_st) +assert alignment(x509_object_st) == 4, alignment(x509_object_st) +X509_OBJECT = x509_object_st +class x509_lookup_st(Structure): + pass +X509_LOOKUP = x509_lookup_st +class x509_lookup_method_st(Structure): + pass +x509_lookup_method_st._fields_ = [ + ('name', STRING), + ('new_item', CFUNCTYPE(c_int, POINTER(X509_LOOKUP))), + ('free', CFUNCTYPE(None, POINTER(X509_LOOKUP))), + ('init', CFUNCTYPE(c_int, POINTER(X509_LOOKUP))), + ('shutdown', CFUNCTYPE(c_int, POINTER(X509_LOOKUP))), + ('ctrl', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, STRING, c_long, POINTER(STRING))), + ('get_by_subject', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, POINTER(X509_NAME), POINTER(X509_OBJECT))), + ('get_by_issuer_serial', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, POINTER(X509_NAME), POINTER(ASN1_INTEGER), POINTER(X509_OBJECT))), + ('get_by_fingerprint', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, POINTER(c_ubyte), c_int, POINTER(X509_OBJECT))), + ('get_by_alias', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, STRING, c_int, POINTER(X509_OBJECT))), +] +assert sizeof(x509_lookup_method_st) == 40, sizeof(x509_lookup_method_st) +assert alignment(x509_lookup_method_st) == 4, alignment(x509_lookup_method_st) +X509_LOOKUP_METHOD = x509_lookup_method_st +x509_store_st._fields_ = [ + ('cache', c_int), + ('objs', POINTER(STACK)), + ('get_cert_methods', POINTER(STACK)), + ('flags', c_ulong), + ('purpose', c_int), + ('trust', c_int), + ('verify', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), + ('verify_cb', CFUNCTYPE(c_int, c_int, POINTER(X509_STORE_CTX))), + ('get_issuer', CFUNCTYPE(c_int, POINTER(POINTER(X509)), POINTER(X509_STORE_CTX), POINTER(X509))), + ('check_issued', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509), POINTER(X509))), + ('check_revocation', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), + ('get_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(POINTER(X509_CRL)), POINTER(X509))), + ('check_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509_CRL))), + ('cert_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509_CRL), POINTER(X509))), + ('cleanup', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), + ('ex_data', CRYPTO_EX_DATA), + ('references', c_int), + ('depth', c_int), +] +assert sizeof(x509_store_st) == 76, sizeof(x509_store_st) +assert alignment(x509_store_st) == 4, alignment(x509_store_st) +x509_lookup_st._fields_ = [ + ('init', c_int), + ('skip', c_int), + ('method', POINTER(X509_LOOKUP_METHOD)), + ('method_data', STRING), + ('store_ctx', POINTER(X509_STORE)), +] +assert sizeof(x509_lookup_st) == 20, sizeof(x509_lookup_st) +assert alignment(x509_lookup_st) == 4, alignment(x509_lookup_st) +time_t = __darwin_time_t +x509_store_ctx_st._fields_ = [ + ('ctx', POINTER(X509_STORE)), + ('current_method', c_int), + ('cert', POINTER(X509)), + ('untrusted', POINTER(STACK)), + ('purpose', c_int), + ('trust', c_int), + ('check_time', time_t), + ('flags', c_ulong), + ('other_ctx', c_void_p), + ('verify', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), + ('verify_cb', CFUNCTYPE(c_int, c_int, POINTER(X509_STORE_CTX))), + ('get_issuer', CFUNCTYPE(c_int, POINTER(POINTER(X509)), POINTER(X509_STORE_CTX), POINTER(X509))), + ('check_issued', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509), POINTER(X509))), + ('check_revocation', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), + ('get_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(POINTER(X509_CRL)), POINTER(X509))), + ('check_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509_CRL))), + ('cert_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509_CRL), POINTER(X509))), + ('cleanup', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), + ('depth', c_int), + ('valid', c_int), + ('last_untrusted', c_int), + ('chain', POINTER(STACK)), + ('error_depth', c_int), + ('error', c_int), + ('current_cert', POINTER(X509)), + ('current_issuer', POINTER(X509)), + ('current_crl', POINTER(X509_CRL)), + ('ex_data', CRYPTO_EX_DATA), +] +assert sizeof(x509_store_ctx_st) == 116, sizeof(x509_store_ctx_st) +assert alignment(x509_store_ctx_st) == 4, alignment(x509_store_ctx_st) +va_list = __darwin_va_list +__darwin_off_t = __int64_t +fpos_t = __darwin_off_t +class __sbuf(Structure): + pass +__sbuf._fields_ = [ + ('_base', POINTER(c_ubyte)), + ('_size', c_int), +] +assert sizeof(__sbuf) == 8, sizeof(__sbuf) +assert alignment(__sbuf) == 4, alignment(__sbuf) +class __sFILEX(Structure): + pass +__sFILEX._fields_ = [ +] +class __sFILE(Structure): + pass +__sFILE._pack_ = 4 +__sFILE._fields_ = [ + ('_p', POINTER(c_ubyte)), + ('_r', c_int), + ('_w', c_int), + ('_flags', c_short), + ('_file', c_short), + ('_bf', __sbuf), + ('_lbfsize', c_int), + ('_cookie', c_void_p), + ('_close', CFUNCTYPE(c_int, c_void_p)), + ('_read', CFUNCTYPE(c_int, c_void_p, STRING, c_int)), + ('_seek', CFUNCTYPE(fpos_t, c_void_p, c_longlong, c_int)), + ('_write', CFUNCTYPE(c_int, c_void_p, STRING, c_int)), + ('_ub', __sbuf), + ('_extra', POINTER(__sFILEX)), + ('_ur', c_int), + ('_ubuf', c_ubyte * 3), + ('_nbuf', c_ubyte * 1), + ('_lb', __sbuf), + ('_blksize', c_int), + ('_offset', fpos_t), +] +assert sizeof(__sFILE) == 88, sizeof(__sFILE) +assert alignment(__sFILE) == 4, alignment(__sFILE) +FILE = __sFILE +ct_rune_t = __darwin_ct_rune_t +rune_t = __darwin_rune_t +class div_t(Structure): + pass +div_t._fields_ = [ + ('quot', c_int), + ('rem', c_int), +] +assert sizeof(div_t) == 8, sizeof(div_t) +assert alignment(div_t) == 4, alignment(div_t) +class ldiv_t(Structure): + pass +ldiv_t._fields_ = [ + ('quot', c_long), + ('rem', c_long), +] +assert sizeof(ldiv_t) == 8, sizeof(ldiv_t) +assert alignment(ldiv_t) == 4, alignment(ldiv_t) +class lldiv_t(Structure): + pass +lldiv_t._pack_ = 4 +lldiv_t._fields_ = [ + ('quot', c_longlong), + ('rem', c_longlong), +] +assert sizeof(lldiv_t) == 16, sizeof(lldiv_t) +assert alignment(lldiv_t) == 4, alignment(lldiv_t) +__darwin_dev_t = __int32_t +dev_t = __darwin_dev_t +__darwin_mode_t = __uint16_t +mode_t = __darwin_mode_t +class mcontext(Structure): + pass +mcontext._fields_ = [ +] +class mcontext64(Structure): + pass +mcontext64._fields_ = [ +] +class __darwin_pthread_handler_rec(Structure): + pass +__darwin_pthread_handler_rec._fields_ = [ + ('__routine', CFUNCTYPE(None, c_void_p)), + ('__arg', c_void_p), + ('__next', POINTER(__darwin_pthread_handler_rec)), +] +assert sizeof(__darwin_pthread_handler_rec) == 12, sizeof(__darwin_pthread_handler_rec) +assert alignment(__darwin_pthread_handler_rec) == 4, alignment(__darwin_pthread_handler_rec) +class _opaque_pthread_attr_t(Structure): + pass +_opaque_pthread_attr_t._fields_ = [ + ('__sig', c_long), + ('__opaque', c_char * 36), +] +assert sizeof(_opaque_pthread_attr_t) == 40, sizeof(_opaque_pthread_attr_t) +assert alignment(_opaque_pthread_attr_t) == 4, alignment(_opaque_pthread_attr_t) +class _opaque_pthread_cond_t(Structure): + pass +_opaque_pthread_cond_t._fields_ = [ + ('__sig', c_long), + ('__opaque', c_char * 24), +] +assert sizeof(_opaque_pthread_cond_t) == 28, sizeof(_opaque_pthread_cond_t) +assert alignment(_opaque_pthread_cond_t) == 4, alignment(_opaque_pthread_cond_t) +class _opaque_pthread_condattr_t(Structure): + pass +_opaque_pthread_condattr_t._fields_ = [ + ('__sig', c_long), + ('__opaque', c_char * 4), +] +assert sizeof(_opaque_pthread_condattr_t) == 8, sizeof(_opaque_pthread_condattr_t) +assert alignment(_opaque_pthread_condattr_t) == 4, alignment(_opaque_pthread_condattr_t) +class _opaque_pthread_mutex_t(Structure): + pass +_opaque_pthread_mutex_t._fields_ = [ + ('__sig', c_long), + ('__opaque', c_char * 40), +] +assert sizeof(_opaque_pthread_mutex_t) == 44, sizeof(_opaque_pthread_mutex_t) +assert alignment(_opaque_pthread_mutex_t) == 4, alignment(_opaque_pthread_mutex_t) +class _opaque_pthread_mutexattr_t(Structure): + pass +_opaque_pthread_mutexattr_t._fields_ = [ + ('__sig', c_long), + ('__opaque', c_char * 8), +] +assert sizeof(_opaque_pthread_mutexattr_t) == 12, sizeof(_opaque_pthread_mutexattr_t) +assert alignment(_opaque_pthread_mutexattr_t) == 4, alignment(_opaque_pthread_mutexattr_t) +class _opaque_pthread_once_t(Structure): + pass +_opaque_pthread_once_t._fields_ = [ + ('__sig', c_long), + ('__opaque', c_char * 4), +] +assert sizeof(_opaque_pthread_once_t) == 8, sizeof(_opaque_pthread_once_t) +assert alignment(_opaque_pthread_once_t) == 4, alignment(_opaque_pthread_once_t) +class _opaque_pthread_rwlock_t(Structure): + pass +_opaque_pthread_rwlock_t._fields_ = [ + ('__sig', c_long), + ('__opaque', c_char * 124), +] +assert sizeof(_opaque_pthread_rwlock_t) == 128, sizeof(_opaque_pthread_rwlock_t) +assert alignment(_opaque_pthread_rwlock_t) == 4, alignment(_opaque_pthread_rwlock_t) +class _opaque_pthread_rwlockattr_t(Structure): + pass +_opaque_pthread_rwlockattr_t._fields_ = [ + ('__sig', c_long), + ('__opaque', c_char * 12), +] +assert sizeof(_opaque_pthread_rwlockattr_t) == 16, sizeof(_opaque_pthread_rwlockattr_t) +assert alignment(_opaque_pthread_rwlockattr_t) == 4, alignment(_opaque_pthread_rwlockattr_t) +class _opaque_pthread_t(Structure): + pass +_opaque_pthread_t._fields_ = [ + ('__sig', c_long), + ('__cleanup_stack', POINTER(__darwin_pthread_handler_rec)), + ('__opaque', c_char * 596), +] +assert sizeof(_opaque_pthread_t) == 604, sizeof(_opaque_pthread_t) +assert alignment(_opaque_pthread_t) == 4, alignment(_opaque_pthread_t) +__darwin_blkcnt_t = __int64_t +__darwin_blksize_t = __int32_t +__darwin_fsblkcnt_t = c_uint +__darwin_fsfilcnt_t = c_uint +__darwin_gid_t = __uint32_t +__darwin_id_t = __uint32_t +__darwin_ino_t = __uint32_t +__darwin_mach_port_name_t = __darwin_natural_t +__darwin_mach_port_t = __darwin_mach_port_name_t +__darwin_mcontext_t = POINTER(mcontext) +__darwin_mcontext64_t = POINTER(mcontext64) +__darwin_pid_t = __int32_t +__darwin_pthread_attr_t = _opaque_pthread_attr_t +__darwin_pthread_cond_t = _opaque_pthread_cond_t +__darwin_pthread_condattr_t = _opaque_pthread_condattr_t +__darwin_pthread_key_t = c_ulong +__darwin_pthread_mutex_t = _opaque_pthread_mutex_t +__darwin_pthread_mutexattr_t = _opaque_pthread_mutexattr_t +__darwin_pthread_once_t = _opaque_pthread_once_t +__darwin_pthread_rwlock_t = _opaque_pthread_rwlock_t +__darwin_pthread_rwlockattr_t = _opaque_pthread_rwlockattr_t +__darwin_pthread_t = POINTER(_opaque_pthread_t) +__darwin_sigset_t = __uint32_t +__darwin_suseconds_t = __int32_t +__darwin_uid_t = __uint32_t +__darwin_useconds_t = __uint32_t +__darwin_uuid_t = c_ubyte * 16 +class sigaltstack(Structure): + pass +sigaltstack._fields_ = [ + ('ss_sp', c_void_p), + ('ss_size', __darwin_size_t), + ('ss_flags', c_int), +] +assert sizeof(sigaltstack) == 12, sizeof(sigaltstack) +assert alignment(sigaltstack) == 4, alignment(sigaltstack) +__darwin_stack_t = sigaltstack +class ucontext(Structure): + pass +ucontext._fields_ = [ + ('uc_onstack', c_int), + ('uc_sigmask', __darwin_sigset_t), + ('uc_stack', __darwin_stack_t), + ('uc_link', POINTER(ucontext)), + ('uc_mcsize', __darwin_size_t), + ('uc_mcontext', __darwin_mcontext_t), +] +assert sizeof(ucontext) == 32, sizeof(ucontext) +assert alignment(ucontext) == 4, alignment(ucontext) +__darwin_ucontext_t = ucontext +class ucontext64(Structure): + pass +ucontext64._fields_ = [ + ('uc_onstack', c_int), + ('uc_sigmask', __darwin_sigset_t), + ('uc_stack', __darwin_stack_t), + ('uc_link', POINTER(ucontext64)), + ('uc_mcsize', __darwin_size_t), + ('uc_mcontext64', __darwin_mcontext64_t), +] +assert sizeof(ucontext64) == 32, sizeof(ucontext64) +assert alignment(ucontext64) == 4, alignment(ucontext64) +__darwin_ucontext64_t = ucontext64 +class timeval(Structure): + pass +timeval._fields_ = [ + ('tv_sec', __darwin_time_t), + ('tv_usec', __darwin_suseconds_t), +] +assert sizeof(timeval) == 8, sizeof(timeval) +assert alignment(timeval) == 4, alignment(timeval) +rlim_t = __int64_t +class rusage(Structure): + pass +rusage._fields_ = [ + ('ru_utime', timeval), + ('ru_stime', timeval), + ('ru_maxrss', c_long), + ('ru_ixrss', c_long), + ('ru_idrss', c_long), + ('ru_isrss', c_long), + ('ru_minflt', c_long), + ('ru_majflt', c_long), + ('ru_nswap', c_long), + ('ru_inblock', c_long), + ('ru_oublock', c_long), + ('ru_msgsnd', c_long), + ('ru_msgrcv', c_long), + ('ru_nsignals', c_long), + ('ru_nvcsw', c_long), + ('ru_nivcsw', c_long), +] +assert sizeof(rusage) == 72, sizeof(rusage) +assert alignment(rusage) == 4, alignment(rusage) +class rlimit(Structure): + pass +rlimit._pack_ = 4 +rlimit._fields_ = [ + ('rlim_cur', rlim_t), + ('rlim_max', rlim_t), +] +assert sizeof(rlimit) == 16, sizeof(rlimit) +assert alignment(rlimit) == 4, alignment(rlimit) +mcontext_t = __darwin_mcontext_t +mcontext64_t = __darwin_mcontext64_t +pthread_attr_t = __darwin_pthread_attr_t +sigset_t = __darwin_sigset_t +ucontext_t = __darwin_ucontext_t +ucontext64_t = __darwin_ucontext64_t +uid_t = __darwin_uid_t +class sigval(Union): + pass +sigval._fields_ = [ + ('sival_int', c_int), + ('sival_ptr', c_void_p), +] +assert sizeof(sigval) == 4, sizeof(sigval) +assert alignment(sigval) == 4, alignment(sigval) +class sigevent(Structure): + pass +sigevent._fields_ = [ + ('sigev_notify', c_int), + ('sigev_signo', c_int), + ('sigev_value', sigval), + ('sigev_notify_function', CFUNCTYPE(None, sigval)), + ('sigev_notify_attributes', POINTER(pthread_attr_t)), +] +assert sizeof(sigevent) == 20, sizeof(sigevent) +assert alignment(sigevent) == 4, alignment(sigevent) +class __siginfo(Structure): + pass +pid_t = __darwin_pid_t +__siginfo._fields_ = [ + ('si_signo', c_int), + ('si_errno', c_int), + ('si_code', c_int), + ('si_pid', pid_t), + ('si_uid', uid_t), + ('si_status', c_int), + ('si_addr', c_void_p), + ('si_value', sigval), + ('si_band', c_long), + ('pad', c_ulong * 7), +] +assert sizeof(__siginfo) == 64, sizeof(__siginfo) +assert alignment(__siginfo) == 4, alignment(__siginfo) +siginfo_t = __siginfo +class __sigaction_u(Union): + pass +__sigaction_u._fields_ = [ + ('__sa_handler', CFUNCTYPE(None, c_int)), + ('__sa_sigaction', CFUNCTYPE(None, c_int, POINTER(__siginfo), c_void_p)), +] +assert sizeof(__sigaction_u) == 4, sizeof(__sigaction_u) +assert alignment(__sigaction_u) == 4, alignment(__sigaction_u) +class __sigaction(Structure): + pass +__sigaction._fields_ = [ + ('__sigaction_u', __sigaction_u), + ('sa_tramp', CFUNCTYPE(None, c_void_p, c_int, c_int, POINTER(siginfo_t), c_void_p)), + ('sa_mask', sigset_t), + ('sa_flags', c_int), +] +assert sizeof(__sigaction) == 16, sizeof(__sigaction) +assert alignment(__sigaction) == 4, alignment(__sigaction) +class sigaction(Structure): + pass +sigaction._fields_ = [ + ('__sigaction_u', __sigaction_u), + ('sa_mask', sigset_t), + ('sa_flags', c_int), +] +assert sizeof(sigaction) == 12, sizeof(sigaction) +assert alignment(sigaction) == 4, alignment(sigaction) +sig_t = CFUNCTYPE(None, c_int) +stack_t = __darwin_stack_t +class sigvec(Structure): + pass +sigvec._fields_ = [ + ('sv_handler', CFUNCTYPE(None, c_int)), + ('sv_mask', c_int), + ('sv_flags', c_int), +] +assert sizeof(sigvec) == 12, sizeof(sigvec) +assert alignment(sigvec) == 4, alignment(sigvec) +class sigstack(Structure): + pass +sigstack._fields_ = [ + ('ss_sp', STRING), + ('ss_onstack', c_int), +] +assert sizeof(sigstack) == 8, sizeof(sigstack) +assert alignment(sigstack) == 4, alignment(sigstack) +u_char = c_ubyte +u_short = c_ushort +u_int = c_uint +u_long = c_ulong +ushort = c_ushort +uint = c_uint +u_quad_t = u_int64_t +quad_t = int64_t +qaddr_t = POINTER(quad_t) +caddr_t = STRING +daddr_t = int32_t +fixpt_t = u_int32_t +blkcnt_t = __darwin_blkcnt_t +blksize_t = __darwin_blksize_t +gid_t = __darwin_gid_t +in_addr_t = __uint32_t +in_port_t = __uint16_t +ino_t = __darwin_ino_t +key_t = __int32_t +nlink_t = __uint16_t +off_t = __darwin_off_t +segsz_t = int32_t +swblk_t = int32_t +clock_t = __darwin_clock_t +ssize_t = __darwin_ssize_t +useconds_t = __darwin_useconds_t +suseconds_t = __darwin_suseconds_t +fd_mask = __int32_t +class fd_set(Structure): + pass +fd_set._fields_ = [ + ('fds_bits', __int32_t * 32), +] +assert sizeof(fd_set) == 128, sizeof(fd_set) +assert alignment(fd_set) == 4, alignment(fd_set) +pthread_cond_t = __darwin_pthread_cond_t +pthread_condattr_t = __darwin_pthread_condattr_t +pthread_mutex_t = __darwin_pthread_mutex_t +pthread_mutexattr_t = __darwin_pthread_mutexattr_t +pthread_once_t = __darwin_pthread_once_t +pthread_rwlock_t = __darwin_pthread_rwlock_t +pthread_rwlockattr_t = __darwin_pthread_rwlockattr_t +pthread_t = __darwin_pthread_t +pthread_key_t = __darwin_pthread_key_t +fsblkcnt_t = __darwin_fsblkcnt_t +fsfilcnt_t = __darwin_fsfilcnt_t + +# values for enumeration 'idtype_t' +idtype_t = c_int # enum +id_t = __darwin_id_t +class wait(Union): + pass +class N4wait3DOLLAR_3E(Structure): + pass +N4wait3DOLLAR_3E._fields_ = [ + ('w_Termsig', c_uint, 7), + ('w_Coredump', c_uint, 1), + ('w_Retcode', c_uint, 8), + ('w_Filler', c_uint, 16), +] +assert sizeof(N4wait3DOLLAR_3E) == 4, sizeof(N4wait3DOLLAR_3E) +assert alignment(N4wait3DOLLAR_3E) == 4, alignment(N4wait3DOLLAR_3E) +class N4wait3DOLLAR_4E(Structure): + pass +N4wait3DOLLAR_4E._fields_ = [ + ('w_Stopval', c_uint, 8), + ('w_Stopsig', c_uint, 8), + ('w_Filler', c_uint, 16), +] +assert sizeof(N4wait3DOLLAR_4E) == 4, sizeof(N4wait3DOLLAR_4E) +assert alignment(N4wait3DOLLAR_4E) == 4, alignment(N4wait3DOLLAR_4E) +wait._fields_ = [ + ('w_status', c_int), + ('w_T', N4wait3DOLLAR_3E), + ('w_S', N4wait3DOLLAR_4E), +] +assert sizeof(wait) == 4, sizeof(wait) +assert alignment(wait) == 4, alignment(wait) +class timespec(Structure): + pass +timespec._fields_ = [ + ('tv_sec', time_t), + ('tv_nsec', c_long), +] +assert sizeof(timespec) == 8, sizeof(timespec) +assert alignment(timespec) == 4, alignment(timespec) +class tm(Structure): + pass +tm._fields_ = [ + ('tm_sec', c_int), + ('tm_min', c_int), + ('tm_hour', c_int), + ('tm_mday', c_int), + ('tm_mon', c_int), + ('tm_year', c_int), + ('tm_wday', c_int), + ('tm_yday', c_int), + ('tm_isdst', c_int), + ('tm_gmtoff', c_long), + ('tm_zone', STRING), +] +assert sizeof(tm) == 44, sizeof(tm) +assert alignment(tm) == 4, alignment(tm) +__gnuc_va_list = STRING +ptrdiff_t = c_int +int8_t = c_byte +int16_t = c_short +uint8_t = c_ubyte +uint16_t = c_ushort +uint32_t = c_uint +uint64_t = c_ulonglong +int_least8_t = int8_t +int_least16_t = int16_t +int_least32_t = int32_t +int_least64_t = int64_t +uint_least8_t = uint8_t +uint_least16_t = uint16_t +uint_least32_t = uint32_t +uint_least64_t = uint64_t +int_fast8_t = int8_t +int_fast16_t = int16_t +int_fast32_t = int32_t +int_fast64_t = int64_t +uint_fast8_t = uint8_t +uint_fast16_t = uint16_t +uint_fast32_t = uint32_t +uint_fast64_t = uint64_t +intptr_t = c_long +uintptr_t = c_ulong +intmax_t = c_longlong +uintmax_t = c_ulonglong +__all__ = ['ENGINE', 'pkcs7_enc_content_st', '__int16_t', + 'X509_REVOKED', 'SSL_CTX', 'UIT_BOOLEAN', + '__darwin_time_t', 'ucontext64_t', 'int_fast32_t', + 'pem_ctx_st', 'uint8_t', 'fpos_t', 'X509', 'COMP_CTX', + 'tm', 'N10pem_ctx_st4DOLLAR_17E', 'swblk_t', + 'ASN1_TEMPLATE', '__darwin_pthread_t', 'fixpt_t', + 'BIO_METHOD', 'ASN1_PRINTABLESTRING', 'EVP_ENCODE_CTX', + 'dh_method', 'bio_f_buffer_ctx_struct', 'in_port_t', + 'X509_SIG', '__darwin_ssize_t', '__darwin_sigset_t', + 'wait', 'uint_fast16_t', 'N12asn1_type_st4DOLLAR_11E', + 'uint_least8_t', 'pthread_rwlock_t', 'ASN1_IA5STRING', + 'fsfilcnt_t', 'ucontext', '__uint64_t', 'timespec', + 'x509_cinf_st', 'COMP_METHOD', 'MD5_CTX', 'buf_mem_st', + 'ASN1_ENCODING_st', 'PBEPARAM', 'X509_NAME_ENTRY', + '__darwin_va_list', 'ucontext_t', 'lhash_st', + 'N4wait3DOLLAR_4E', '__darwin_uuid_t', + '_ossl_old_des_ks_struct', 'id_t', 'ASN1_BIT_STRING', + 'va_list', '__darwin_wchar_t', 'pthread_key_t', + 'pkcs7_signer_info_st', 'ASN1_METHOD', 'DSA_SIG', 'DSA', + 'UIT_NONE', 'pthread_t', '__darwin_useconds_t', + 'uint_fast8_t', 'UI_STRING', 'DES_cblock', + '__darwin_mcontext64_t', 'rlim_t', 'PEM_Encode_Seal_st', + 'SHAstate_st', 'u_quad_t', 'openssl_fptr', + '_opaque_pthread_rwlockattr_t', + 'N18x509_attributes_st4DOLLAR_13E', + '__darwin_pthread_rwlock_t', 'daddr_t', 'ui_string_st', + 'x509_file_st', 'X509_req_info_st', 'int_least64_t', + 'evp_Encode_Ctx_st', 'X509_OBJECTS', 'CRYPTO_EX_DATA', + '__int8_t', 'AUTHORITY_KEYID_st', '_opaque_pthread_attr_t', + 'sigstack', 'EVP_CIPHER_CTX', 'X509_extension_st', 'pid_t', + 'RSA_METHOD', 'PEM_USER', 'pem_recip_st', 'env_md_ctx_st', + 'rc5_key_st', 'ui_st', 'X509_PUBKEY', 'u_int8_t', + 'ASN1_ITEM_st', 'pkcs7_recip_info_st', 'ssl2_state_st', + 'off_t', 'N10ssl_ctx_st4DOLLAR_18E', 'crypto_ex_data_st', + 'ui_method_st', '__darwin_pthread_rwlockattr_t', + 'CRYPTO_EX_dup', '__darwin_ino_t', '__sFILE', + 'OSUnknownByteOrder', 'BN_MONT_CTX', 'ASN1_NULL', 'time_t', + 'CRYPTO_EX_new', 'asn1_type_st', 'CRYPTO_EX_DATA_FUNCS', + 'user_time_t', 'BIGNUM', 'pthread_rwlockattr_t', + 'ASN1_VALUE_st', 'DH_METHOD', '__darwin_off_t', + '_opaque_pthread_t', 'bn_blinding_st', 'RSA', 'ssize_t', + 'mcontext64_t', 'user_long_t', 'fsblkcnt_t', 'cert_st', + '__darwin_pthread_condattr_t', 'X509_PKEY', + '__darwin_id_t', '__darwin_nl_item', 'SSL2_STATE', 'FILE', + 'pthread_mutexattr_t', 'size_t', + '_ossl_old_des_key_schedule', 'pkcs7_issuer_and_serial_st', + 'sigval', 'CRYPTO_MEM_LEAK_CB', 'X509_NAME', 'blkcnt_t', + 'uint_least16_t', '__darwin_dev_t', 'evp_cipher_info_st', + 'BN_BLINDING', 'ssl3_state_st', 'uint_least64_t', + 'user_addr_t', 'DES_key_schedule', 'RIPEMD160_CTX', + 'u_char', 'X509_algor_st', 'uid_t', 'sess_cert_st', + 'u_int64_t', 'u_int16_t', 'sigset_t', '__darwin_ptrdiff_t', + 'ASN1_CTX', 'STACK', '__int32_t', 'UI_METHOD', + 'NETSCAPE_SPKI', 'UIT_PROMPT', 'st_CRYPTO_EX_DATA_IMPL', + 'cast_key_st', 'X509_HASH_DIR_CTX', 'sigevent', + 'user_ssize_t', 'clock_t', 'aes_key_st', + '__darwin_socklen_t', '__darwin_intptr_t', 'int_fast64_t', + 'asn1_string_table_st', 'uint_fast32_t', + 'ASN1_VISIBLESTRING', 'DSA_SIG_st', 'obj_name_st', + 'X509_LOOKUP_METHOD', 'u_int32_t', 'EVP_CIPHER_INFO', + '__gnuc_va_list', 'AES_KEY', 'PKCS7_ISSUER_AND_SERIAL', + 'BN_CTX', '__darwin_blkcnt_t', 'key_t', 'SHA_CTX', + 'pkcs7_signed_st', 'SSL', 'N10pem_ctx_st4DOLLAR_16E', + 'pthread_attr_t', 'EVP_MD', 'uint', 'ASN1_BOOLEAN', + 'ino_t', '__darwin_clock_t', 'ASN1_OCTET_STRING', + 'asn1_ctx_st', 'BIO_F_BUFFER_CTX', 'bn_mont_ctx_st', + 'X509_REQ_INFO', 'PEM_CTX', 'sigvec', + '__darwin_pthread_mutexattr_t', 'x509_attributes_st', + 'stack_t', '__darwin_mode_t', '__mbstate_t', + 'asn1_object_st', 'ASN1_ENCODING', '__uint8_t', + 'LHASH_NODE', 'PKCS7_SIGNER_INFO', 'asn1_method_st', + 'stack_st', 'bio_info_cb', 'div_t', 'UIT_VERIFY', + 'PBEPARAM_st', 'N4wait3DOLLAR_3E', 'quad_t', '__siginfo', + '__darwin_mbstate_t', 'rsa_st', 'ASN1_UNIVERSALSTRING', + 'uint64_t', 'ssl_comp_st', 'X509_OBJECT', 'pthread_cond_t', + 'DH', '__darwin_wctype_t', 'PKCS7_ENVELOPE', 'ASN1_TLC_st', + 'sig_atomic_t', 'BIO', 'nlink_t', 'BUF_MEM', 'SSL3_RECORD', + 'bio_method_st', 'timeval', 'UI_string_types', 'BIO_dummy', + 'ssl_ctx_st', 'NETSCAPE_CERT_SEQUENCE', + 'BIT_STRING_BITNAME_st', '__darwin_pthread_attr_t', + 'int8_t', '__darwin_wint_t', 'OBJ_NAME', + 'PKCS8_PRIV_KEY_INFO', 'PBE2PARAM_st', + 'LHASH_DOALL_FN_TYPE', 'x509_st', 'X509_VAL', 'dev_t', + 'ASN1_TEMPLATE_st', 'MD5state_st', '__uint16_t', + 'LHASH_DOALL_ARG_FN_TYPE', 'mdc2_ctx_st', 'SSL3_STATE', + 'ssl3_buffer_st', 'ASN1_ITEM_EXP', + '_opaque_pthread_condattr_t', 'mode_t', 'ASN1_VALUE', + 'qaddr_t', '__darwin_gid_t', 'EVP_PKEY', 'CRYPTO_EX_free', + '_ossl_old_des_cblock', 'X509_INFO', 'asn1_string_st', + 'intptr_t', 'UIT_INFO', 'int_fast8_t', 'sigaltstack', + 'env_md_st', 'LHASH', '__darwin_ucontext_t', + 'PKCS7_SIGN_ENVELOPE', '__darwin_mcontext_t', 'ct_rune_t', + 'MD2_CTX', 'pthread_once_t', 'SSL3_BUFFER', 'fd_mask', + 'ASN1_TYPE', 'PKCS7_SIGNED', 'ssl3_record_st', 'BF_KEY', + 'MD4state_st', 'MD4_CTX', 'int16_t', 'SSL_CIPHER', + 'rune_t', 'X509_TRUST', 'siginfo_t', 'X509_STORE', + '__sbuf', 'X509_STORE_CTX', '__darwin_blksize_t', 'ldiv_t', + 'ASN1_TIME', 'SSL_METHOD', 'X509_LOOKUP', + 'Netscape_spki_st', 'P_PID', 'sigaction', 'sig_t', + 'hostent', 'x509_cert_aux_st', '_opaque_pthread_cond_t', + 'segsz_t', 'ushort', '__darwin_ct_rune_t', 'fd_set', + 'BN_RECP_CTX', 'x509_lookup_st', 'uint16_t', 'pkcs7_st', + 'asn1_header_st', '__darwin_pthread_key_t', + 'x509_trust_st', '__darwin_pthread_handler_rec', 'int32_t', + 'X509_CRL_INFO', 'N11evp_pkey_st4DOLLAR_12E', 'MDC2_CTX', + 'N23_ossl_old_des_ks_struct4DOLLAR_10E', 'ASN1_HEADER', + 'X509_crl_info_st', 'LHASH_HASH_FN_TYPE', + '_opaque_pthread_mutexattr_t', 'ssl_st', + 'N8pkcs7_st4DOLLAR_15E', 'evp_pkey_st', + 'pkcs7_signedandenveloped_st', '__darwin_mach_port_t', + 'EVP_PBE_KEYGEN', '_opaque_pthread_mutex_t', + 'ASN1_UTCTIME', 'mcontext', 'crypto_ex_data_func_st', + 'u_long', 'PBKDF2PARAM_st', 'rc4_key_st', 'DSA_METHOD', + 'EVP_CIPHER', 'BIT_STRING_BITNAME', 'PKCS7_RECIP_INFO', + 'ssl3_enc_method', 'X509_CERT_AUX', 'uintmax_t', + 'int_fast16_t', 'RC5_32_KEY', 'ucontext64', 'ASN1_INTEGER', + 'u_short', 'N14x509_object_st4DOLLAR_14E', 'mcontext64', + 'X509_sig_st', 'ASN1_GENERALSTRING', 'PKCS7', '__sFILEX', + 'X509_name_entry_st', 'ssl_session_st', 'caddr_t', + 'bignum_st', 'X509_CINF', '__darwin_pthread_cond_t', + 'ASN1_TLC', 'PKCS7_ENCRYPT', 'NETSCAPE_SPKAC', + 'Netscape_spkac_st', 'idtype_t', 'UIT_ERROR', + 'uint_fast64_t', 'in_addr_t', 'pthread_mutex_t', + '__int64_t', 'ASN1_BMPSTRING', 'uint32_t', + 'PEM_ENCODE_SEAL_CTX', 'suseconds_t', 'ASN1_OBJECT', + 'X509_val_st', 'private_key_st', 'CRYPTO_dynlock', + 'X509_objects_st', 'CRYPTO_EX_DATA_IMPL', + 'pthread_condattr_t', 'PKCS7_DIGEST', 'uint_least32_t', + 'ASN1_STRING', '__uint32_t', 'P_PGID', 'rsa_meth_st', + 'X509_crl_st', 'RC2_KEY', '__darwin_fsfilcnt_t', + 'X509_revoked_st', 'PBE2PARAM', 'blksize_t', + 'Netscape_certificate_sequence', 'ssl_cipher_st', + 'bignum_ctx', 'register_t', 'ASN1_UTF8STRING', + 'pkcs7_encrypted_st', 'RC4_KEY', '__darwin_ucontext64_t', + 'N13ssl2_state_st4DOLLAR_19E', 'bn_recp_ctx_st', + 'CAST_KEY', 'X509_ATTRIBUTE', '__darwin_suseconds_t', + '__sigaction', 'user_ulong_t', 'syscall_arg_t', + 'evp_cipher_ctx_st', 'X509_ALGOR', 'mcontext_t', + 'const_DES_cblock', '__darwin_fsblkcnt_t', 'dsa_st', + 'int_least8_t', 'MD2state_st', 'X509_EXTENSION', + 'GEN_SESSION_CB', 'int_least16_t', '__darwin_wctrans_t', + 'PBKDF2PARAM', 'x509_lookup_method_st', 'pem_password_cb', + 'X509_info_st', 'x509_store_st', '__darwin_natural_t', + 'X509_pubkey_st', 'pkcs7_digest_st', '__darwin_size_t', + 'ASN1_STRING_TABLE', 'OSLittleEndian', 'RIPEMD160state_st', + 'pkcs7_enveloped_st', 'UI', 'ptrdiff_t', 'X509_REQ', + 'CRYPTO_dynlock_value', 'X509_req_st', 'x509_store_ctx_st', + 'N13ssl3_state_st4DOLLAR_20E', 'lhash_node_st', + '__darwin_pthread_mutex_t', 'LHASH_COMP_FN_TYPE', + '__darwin_rune_t', 'rlimit', '__darwin_pthread_once_t', + 'OSBigEndian', 'uintptr_t', '__darwin_uid_t', 'u_int', + 'ASN1_T61STRING', 'gid_t', 'ssl_method_st', 'ASN1_ITEM', + 'ASN1_ENUMERATED', '_opaque_pthread_rwlock_t', + 'pkcs8_priv_key_info_st', 'intmax_t', 'sigcontext', + 'X509_CRL', 'rc2_key_st', 'engine_st', 'x509_object_st', + '_opaque_pthread_once_t', 'DES_ks', 'SSL_COMP', + 'dsa_method', 'int64_t', 'bio_st', 'bf_key_st', + 'ASN1_GENERALIZEDTIME', 'PKCS7_ENC_CONTENT', + '__darwin_pid_t', 'lldiv_t', 'comp_method_st', + 'EVP_MD_CTX', 'evp_cipher_st', 'X509_name_st', + 'x509_hash_dir_st', '__darwin_mach_port_name_t', + 'useconds_t', 'user_size_t', 'SSL_SESSION', 'rusage', + 'ssl_crock_st', 'int_least32_t', '__sigaction_u', 'dh_st', + 'P_ALL', '__darwin_stack_t', 'N6DES_ks3DOLLAR_9E', + 'comp_ctx_st', 'X509_CERT_FILE_CTX'] Added: sandbox/trunk/refactor_pkg/lib2to3/tests/data/py2_test_grammar.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/tests/data/py2_test_grammar.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,956 @@ +# Python 2's Lib/test/test_grammar.py (r66189) + +# Python test set -- part 1, grammar. +# This just tests whether the parser accepts them all. + +# NOTE: When you run this test as a script from the command line, you +# get warnings about certain hex/oct constants. Since those are +# issued by the parser, you can't suppress them by adding a +# filterwarnings() call to this module. Therefore, to shut up the +# regression test, the filterwarnings() call has been added to +# regrtest.py. + +from test.test_support import run_unittest, check_syntax_error +import unittest +import sys +# testing import * +from sys import * + +class TokenTests(unittest.TestCase): + + def testBackslash(self): + # Backslash means line continuation: + x = 1 \ + + 1 + self.assertEquals(x, 2, 'backslash for line continuation') + + # Backslash does not means continuation in comments :\ + x = 0 + self.assertEquals(x, 0, 'backslash ending comment') + + def testPlainIntegers(self): + self.assertEquals(0xff, 255) + self.assertEquals(0377, 255) + self.assertEquals(2147483647, 017777777777) + # "0x" is not a valid literal + self.assertRaises(SyntaxError, eval, "0x") + from sys import maxint + if maxint == 2147483647: + self.assertEquals(-2147483647-1, -020000000000) + # XXX -2147483648 + self.assert_(037777777777 > 0) + self.assert_(0xffffffff > 0) + for s in '2147483648', '040000000000', '0x100000000': + try: + x = eval(s) + except OverflowError: + self.fail("OverflowError on huge integer literal %r" % s) + elif maxint == 9223372036854775807: + self.assertEquals(-9223372036854775807-1, -01000000000000000000000) + self.assert_(01777777777777777777777 > 0) + self.assert_(0xffffffffffffffff > 0) + for s in '9223372036854775808', '02000000000000000000000', \ + '0x10000000000000000': + try: + x = eval(s) + except OverflowError: + self.fail("OverflowError on huge integer literal %r" % s) + else: + self.fail('Weird maxint value %r' % maxint) + + def testLongIntegers(self): + x = 0L + x = 0l + x = 0xffffffffffffffffL + x = 0xffffffffffffffffl + x = 077777777777777777L + x = 077777777777777777l + x = 123456789012345678901234567890L + x = 123456789012345678901234567890l + + def testFloats(self): + x = 3.14 + x = 314. + x = 0.314 + # XXX x = 000.314 + x = .314 + x = 3e14 + x = 3E14 + x = 3e-14 + x = 3e+14 + x = 3.e14 + x = .3e14 + x = 3.1e4 + + def testStringLiterals(self): + x = ''; y = ""; self.assert_(len(x) == 0 and x == y) + x = '\''; y = "'"; self.assert_(len(x) == 1 and x == y and ord(x) == 39) + x = '"'; y = "\""; self.assert_(len(x) == 1 and x == y and ord(x) == 34) + x = "doesn't \"shrink\" does it" + y = 'doesn\'t "shrink" does it' + self.assert_(len(x) == 24 and x == y) + x = "does \"shrink\" doesn't it" + y = 'does "shrink" doesn\'t it' + self.assert_(len(x) == 24 and x == y) + x = """ +The "quick" +brown fox +jumps over +the 'lazy' dog. +""" + y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n' + self.assertEquals(x, y) + y = ''' +The "quick" +brown fox +jumps over +the 'lazy' dog. +''' + self.assertEquals(x, y) + y = "\n\ +The \"quick\"\n\ +brown fox\n\ +jumps over\n\ +the 'lazy' dog.\n\ +" + self.assertEquals(x, y) + y = '\n\ +The \"quick\"\n\ +brown fox\n\ +jumps over\n\ +the \'lazy\' dog.\n\ +' + self.assertEquals(x, y) + + +class GrammarTests(unittest.TestCase): + + # single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE + # XXX can't test in a script -- this rule is only used when interactive + + # file_input: (NEWLINE | stmt)* ENDMARKER + # Being tested as this very moment this very module + + # expr_input: testlist NEWLINE + # XXX Hard to test -- used only in calls to input() + + def testEvalInput(self): + # testlist ENDMARKER + x = eval('1, 0 or 1') + + def testFuncdef(self): + ### 'def' NAME parameters ':' suite + ### parameters: '(' [varargslist] ')' + ### varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' ('**'|'*' '*') NAME] + ### | ('**'|'*' '*') NAME) + ### | fpdef ['=' test] (',' fpdef ['=' test])* [','] + ### fpdef: NAME | '(' fplist ')' + ### fplist: fpdef (',' fpdef)* [','] + ### arglist: (argument ',')* (argument | *' test [',' '**' test] | '**' test) + ### argument: [test '='] test # Really [keyword '='] test + def f1(): pass + f1() + f1(*()) + f1(*(), **{}) + def f2(one_argument): pass + def f3(two, arguments): pass + def f4(two, (compound, (argument, list))): pass + def f5((compound, first), two): pass + self.assertEquals(f2.func_code.co_varnames, ('one_argument',)) + self.assertEquals(f3.func_code.co_varnames, ('two', 'arguments')) + if sys.platform.startswith('java'): + self.assertEquals(f4.func_code.co_varnames, + ('two', '(compound, (argument, list))', 'compound', 'argument', + 'list',)) + self.assertEquals(f5.func_code.co_varnames, + ('(compound, first)', 'two', 'compound', 'first')) + else: + self.assertEquals(f4.func_code.co_varnames, + ('two', '.1', 'compound', 'argument', 'list')) + self.assertEquals(f5.func_code.co_varnames, + ('.0', 'two', 'compound', 'first')) + def a1(one_arg,): pass + def a2(two, args,): pass + def v0(*rest): pass + def v1(a, *rest): pass + def v2(a, b, *rest): pass + def v3(a, (b, c), *rest): return a, b, c, rest + + f1() + f2(1) + f2(1,) + f3(1, 2) + f3(1, 2,) + f4(1, (2, (3, 4))) + v0() + v0(1) + v0(1,) + v0(1,2) + v0(1,2,3,4,5,6,7,8,9,0) + v1(1) + v1(1,) + v1(1,2) + v1(1,2,3) + v1(1,2,3,4,5,6,7,8,9,0) + v2(1,2) + v2(1,2,3) + v2(1,2,3,4) + v2(1,2,3,4,5,6,7,8,9,0) + v3(1,(2,3)) + v3(1,(2,3),4) + v3(1,(2,3),4,5,6,7,8,9,0) + + # ceval unpacks the formal arguments into the first argcount names; + # thus, the names nested inside tuples must appear after these names. + if sys.platform.startswith('java'): + self.assertEquals(v3.func_code.co_varnames, ('a', '(b, c)', 'rest', 'b', 'c')) + else: + self.assertEquals(v3.func_code.co_varnames, ('a', '.1', 'rest', 'b', 'c')) + self.assertEquals(v3(1, (2, 3), 4), (1, 2, 3, (4,))) + def d01(a=1): pass + d01() + d01(1) + d01(*(1,)) + d01(**{'a':2}) + def d11(a, b=1): pass + d11(1) + d11(1, 2) + d11(1, **{'b':2}) + def d21(a, b, c=1): pass + d21(1, 2) + d21(1, 2, 3) + d21(*(1, 2, 3)) + d21(1, *(2, 3)) + d21(1, 2, *(3,)) + d21(1, 2, **{'c':3}) + def d02(a=1, b=2): pass + d02() + d02(1) + d02(1, 2) + d02(*(1, 2)) + d02(1, *(2,)) + d02(1, **{'b':2}) + d02(**{'a': 1, 'b': 2}) + def d12(a, b=1, c=2): pass + d12(1) + d12(1, 2) + d12(1, 2, 3) + def d22(a, b, c=1, d=2): pass + d22(1, 2) + d22(1, 2, 3) + d22(1, 2, 3, 4) + def d01v(a=1, *rest): pass + d01v() + d01v(1) + d01v(1, 2) + d01v(*(1, 2, 3, 4)) + d01v(*(1,)) + d01v(**{'a':2}) + def d11v(a, b=1, *rest): pass + d11v(1) + d11v(1, 2) + d11v(1, 2, 3) + def d21v(a, b, c=1, *rest): pass + d21v(1, 2) + d21v(1, 2, 3) + d21v(1, 2, 3, 4) + d21v(*(1, 2, 3, 4)) + d21v(1, 2, **{'c': 3}) + def d02v(a=1, b=2, *rest): pass + d02v() + d02v(1) + d02v(1, 2) + d02v(1, 2, 3) + d02v(1, *(2, 3, 4)) + d02v(**{'a': 1, 'b': 2}) + def d12v(a, b=1, c=2, *rest): pass + d12v(1) + d12v(1, 2) + d12v(1, 2, 3) + d12v(1, 2, 3, 4) + d12v(*(1, 2, 3, 4)) + d12v(1, 2, *(3, 4, 5)) + d12v(1, *(2,), **{'c': 3}) + def d22v(a, b, c=1, d=2, *rest): pass + d22v(1, 2) + d22v(1, 2, 3) + d22v(1, 2, 3, 4) + d22v(1, 2, 3, 4, 5) + d22v(*(1, 2, 3, 4)) + d22v(1, 2, *(3, 4, 5)) + d22v(1, *(2, 3), **{'d': 4}) + def d31v((x)): pass + d31v(1) + def d32v((x,)): pass + d32v((1,)) + + # keyword arguments after *arglist + def f(*args, **kwargs): + return args, kwargs + self.assertEquals(f(1, x=2, *[3, 4], y=5), ((1, 3, 4), + {'x':2, 'y':5})) + self.assertRaises(SyntaxError, eval, "f(1, *(2,3), 4)") + self.assertRaises(SyntaxError, eval, "f(1, x=2, *(3,4), x=5)") + + # Check ast errors in *args and *kwargs + check_syntax_error(self, "f(*g(1=2))") + check_syntax_error(self, "f(**g(1=2))") + + def testLambdef(self): + ### lambdef: 'lambda' [varargslist] ':' test + l1 = lambda : 0 + self.assertEquals(l1(), 0) + l2 = lambda : a[d] # XXX just testing the expression + l3 = lambda : [2 < x for x in [-1, 3, 0L]] + self.assertEquals(l3(), [0, 1, 0]) + l4 = lambda x = lambda y = lambda z=1 : z : y() : x() + self.assertEquals(l4(), 1) + l5 = lambda x, y, z=2: x + y + z + self.assertEquals(l5(1, 2), 5) + self.assertEquals(l5(1, 2, 3), 6) + check_syntax_error(self, "lambda x: x = 2") + check_syntax_error(self, "lambda (None,): None") + + ### stmt: simple_stmt | compound_stmt + # Tested below + + def testSimpleStmt(self): + ### simple_stmt: small_stmt (';' small_stmt)* [';'] + x = 1; pass; del x + def foo(): + # verify statments that end with semi-colons + x = 1; pass; del x; + foo() + + ### small_stmt: expr_stmt | print_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt | exec_stmt + # Tested below + + def testExprStmt(self): + # (exprlist '=')* exprlist + 1 + 1, 2, 3 + x = 1 + x = 1, 2, 3 + x = y = z = 1, 2, 3 + x, y, z = 1, 2, 3 + abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4) + + check_syntax_error(self, "x + 1 = 1") + check_syntax_error(self, "a + 1 = b + 2") + + def testPrintStmt(self): + # 'print' (test ',')* [test] + import StringIO + + # Can't test printing to real stdout without comparing output + # which is not available in unittest. + save_stdout = sys.stdout + sys.stdout = StringIO.StringIO() + + print 1, 2, 3 + print 1, 2, 3, + print + print 0 or 1, 0 or 1, + print 0 or 1 + + # 'print' '>>' test ',' + print >> sys.stdout, 1, 2, 3 + print >> sys.stdout, 1, 2, 3, + print >> sys.stdout + print >> sys.stdout, 0 or 1, 0 or 1, + print >> sys.stdout, 0 or 1 + + # test printing to an instance + class Gulp: + def write(self, msg): pass + + gulp = Gulp() + print >> gulp, 1, 2, 3 + print >> gulp, 1, 2, 3, + print >> gulp + print >> gulp, 0 or 1, 0 or 1, + print >> gulp, 0 or 1 + + # test print >> None + def driver(): + oldstdout = sys.stdout + sys.stdout = Gulp() + try: + tellme(Gulp()) + tellme() + finally: + sys.stdout = oldstdout + + # we should see this once + def tellme(file=sys.stdout): + print >> file, 'hello world' + + driver() + + # we should not see this at all + def tellme(file=None): + print >> file, 'goodbye universe' + + driver() + + self.assertEqual(sys.stdout.getvalue(), '''\ +1 2 3 +1 2 3 +1 1 1 +1 2 3 +1 2 3 +1 1 1 +hello world +''') + sys.stdout = save_stdout + + # syntax errors + check_syntax_error(self, 'print ,') + check_syntax_error(self, 'print >> x,') + + def testDelStmt(self): + # 'del' exprlist + abc = [1,2,3] + x, y, z = abc + xyz = x, y, z + + del abc + del x, y, (z, xyz) + + def testPassStmt(self): + # 'pass' + pass + + # flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt + # Tested below + + def testBreakStmt(self): + # 'break' + while 1: break + + def testContinueStmt(self): + # 'continue' + i = 1 + while i: i = 0; continue + + msg = "" + while not msg: + msg = "ok" + try: + continue + msg = "continue failed to continue inside try" + except: + msg = "continue inside try called except block" + if msg != "ok": + self.fail(msg) + + msg = "" + while not msg: + msg = "finally block not called" + try: + continue + finally: + msg = "ok" + if msg != "ok": + self.fail(msg) + + def test_break_continue_loop(self): + # This test warrants an explanation. It is a test specifically for SF bugs + # #463359 and #462937. The bug is that a 'break' statement executed or + # exception raised inside a try/except inside a loop, *after* a continue + # statement has been executed in that loop, will cause the wrong number of + # arguments to be popped off the stack and the instruction pointer reset to + # a very small number (usually 0.) Because of this, the following test + # *must* written as a function, and the tracking vars *must* be function + # arguments with default values. Otherwise, the test will loop and loop. + + def test_inner(extra_burning_oil = 1, count=0): + big_hippo = 2 + while big_hippo: + count += 1 + try: + if extra_burning_oil and big_hippo == 1: + extra_burning_oil -= 1 + break + big_hippo -= 1 + continue + except: + raise + if count > 2 or big_hippo <> 1: + self.fail("continue then break in try/except in loop broken!") + test_inner() + + def testReturn(self): + # 'return' [testlist] + def g1(): return + def g2(): return 1 + g1() + x = g2() + check_syntax_error(self, "class foo:return 1") + + def testYield(self): + check_syntax_error(self, "class foo:yield 1") + + def testRaise(self): + # 'raise' test [',' test] + try: raise RuntimeError, 'just testing' + except RuntimeError: pass + try: raise KeyboardInterrupt + except KeyboardInterrupt: pass + + def testImport(self): + # 'import' dotted_as_names + import sys + import time, sys + # 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names) + from time import time + from time import (time) + # not testable inside a function, but already done at top of the module + # from sys import * + from sys import path, argv + from sys import (path, argv) + from sys import (path, argv,) + + def testGlobal(self): + # 'global' NAME (',' NAME)* + global a + global a, b + global one, two, three, four, five, six, seven, eight, nine, ten + + def testExec(self): + # 'exec' expr ['in' expr [',' expr]] + z = None + del z + exec 'z=1+1\n' + if z != 2: self.fail('exec \'z=1+1\'\\n') + del z + exec 'z=1+1' + if z != 2: self.fail('exec \'z=1+1\'') + z = None + del z + import types + if hasattr(types, "UnicodeType"): + exec r"""if 1: + exec u'z=1+1\n' + if z != 2: self.fail('exec u\'z=1+1\'\\n') + del z + exec u'z=1+1' + if z != 2: self.fail('exec u\'z=1+1\'')""" + g = {} + exec 'z = 1' in g + if g.has_key('__builtins__'): del g['__builtins__'] + if g != {'z': 1}: self.fail('exec \'z = 1\' in g') + g = {} + l = {} + + import warnings + warnings.filterwarnings("ignore", "global statement", module="") + exec 'global a; a = 1; b = 2' in g, l + if g.has_key('__builtins__'): del g['__builtins__'] + if l.has_key('__builtins__'): del l['__builtins__'] + if (g, l) != ({'a':1}, {'b':2}): + self.fail('exec ... in g (%s), l (%s)' %(g,l)) + + def testAssert(self): + # assert_stmt: 'assert' test [',' test] + assert 1 + assert 1, 1 + assert lambda x:x + assert 1, lambda x:x+1 + try: + assert 0, "msg" + except AssertionError, e: + self.assertEquals(e.args[0], "msg") + else: + if __debug__: + self.fail("AssertionError not raised by assert 0") + + ### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef + # Tested below + + def testIf(self): + # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] + if 1: pass + if 1: pass + else: pass + if 0: pass + elif 0: pass + if 0: pass + elif 0: pass + elif 0: pass + elif 0: pass + else: pass + + def testWhile(self): + # 'while' test ':' suite ['else' ':' suite] + while 0: pass + while 0: pass + else: pass + + # Issue1920: "while 0" is optimized away, + # ensure that the "else" clause is still present. + x = 0 + while 0: + x = 1 + else: + x = 2 + self.assertEquals(x, 2) + + def testFor(self): + # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] + for i in 1, 2, 3: pass + for i, j, k in (): pass + else: pass + class Squares: + def __init__(self, max): + self.max = max + self.sofar = [] + def __len__(self): return len(self.sofar) + def __getitem__(self, i): + if not 0 <= i < self.max: raise IndexError + n = len(self.sofar) + while n <= i: + self.sofar.append(n*n) + n = n+1 + return self.sofar[i] + n = 0 + for x in Squares(10): n = n+x + if n != 285: + self.fail('for over growing sequence') + + result = [] + for x, in [(1,), (2,), (3,)]: + result.append(x) + self.assertEqual(result, [1, 2, 3]) + + def testTry(self): + ### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] + ### | 'try' ':' suite 'finally' ':' suite + ### except_clause: 'except' [expr [('as' | ',') expr]] + try: + 1/0 + except ZeroDivisionError: + pass + else: + pass + try: 1/0 + except EOFError: pass + except TypeError as msg: pass + except RuntimeError, msg: pass + except: pass + else: pass + try: 1/0 + except (EOFError, TypeError, ZeroDivisionError): pass + try: 1/0 + except (EOFError, TypeError, ZeroDivisionError), msg: pass + try: pass + finally: pass + + def testSuite(self): + # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT + if 1: pass + if 1: + pass + if 1: + # + # + # + pass + pass + # + pass + # + + def testTest(self): + ### and_test ('or' and_test)* + ### and_test: not_test ('and' not_test)* + ### not_test: 'not' not_test | comparison + if not 1: pass + if 1 and 1: pass + if 1 or 1: pass + if not not not 1: pass + if not 1 and 1 and 1: pass + if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass + + def testComparison(self): + ### comparison: expr (comp_op expr)* + ### comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' + if 1: pass + x = (1 == 1) + if 1 == 1: pass + if 1 != 1: pass + if 1 <> 1: pass + if 1 < 1: pass + if 1 > 1: pass + if 1 <= 1: pass + if 1 >= 1: pass + if 1 is 1: pass + if 1 is not 1: pass + if 1 in (): pass + if 1 not in (): pass + if 1 < 1 > 1 == 1 >= 1 <= 1 <> 1 != 1 in 1 not in 1 is 1 is not 1: pass + + def testBinaryMaskOps(self): + x = 1 & 1 + x = 1 ^ 1 + x = 1 | 1 + + def testShiftOps(self): + x = 1 << 1 + x = 1 >> 1 + x = 1 << 1 >> 1 + + def testAdditiveOps(self): + x = 1 + x = 1 + 1 + x = 1 - 1 - 1 + x = 1 - 1 + 1 - 1 + 1 + + def testMultiplicativeOps(self): + x = 1 * 1 + x = 1 / 1 + x = 1 % 1 + x = 1 / 1 * 1 % 1 + + def testUnaryOps(self): + x = +1 + x = -1 + x = ~1 + x = ~1 ^ 1 & 1 | 1 & 1 ^ -1 + x = -1*1/1 + 1*1 - ---1*1 + + def testSelectors(self): + ### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME + ### subscript: expr | [expr] ':' [expr] + + import sys, time + c = sys.path[0] + x = time.time() + x = sys.modules['time'].time() + a = '01234' + c = a[0] + c = a[-1] + s = a[0:5] + s = a[:5] + s = a[0:] + s = a[:] + s = a[-5:] + s = a[:-1] + s = a[-4:-3] + # A rough test of SF bug 1333982. http://python.org/sf/1333982 + # The testing here is fairly incomplete. + # Test cases should include: commas with 1 and 2 colons + d = {} + d[1] = 1 + d[1,] = 2 + d[1,2] = 3 + d[1,2,3] = 4 + L = list(d) + L.sort() + self.assertEquals(str(L), '[1, (1,), (1, 2), (1, 2, 3)]') + + def testAtoms(self): + ### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING + ### dictmaker: test ':' test (',' test ':' test)* [','] + + x = (1) + x = (1 or 2 or 3) + x = (1 or 2 or 3, 2, 3) + + x = [] + x = [1] + x = [1 or 2 or 3] + x = [1 or 2 or 3, 2, 3] + x = [] + + x = {} + x = {'one': 1} + x = {'one': 1,} + x = {'one' or 'two': 1 or 2} + x = {'one': 1, 'two': 2} + x = {'one': 1, 'two': 2,} + x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6} + + x = `x` + x = `1 or 2 or 3` + self.assertEqual(`1,2`, '(1, 2)') + + x = x + x = 'x' + x = 123 + + ### exprlist: expr (',' expr)* [','] + ### testlist: test (',' test)* [','] + # These have been exercised enough above + + def testClassdef(self): + # 'class' NAME ['(' [testlist] ')'] ':' suite + class B: pass + class B2(): pass + class C1(B): pass + class C2(B): pass + class D(C1, C2, B): pass + class C: + def meth1(self): pass + def meth2(self, arg): pass + def meth3(self, a1, a2): pass + # decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE + # decorators: decorator+ + # decorated: decorators (classdef | funcdef) + def class_decorator(x): + x.decorated = True + return x + @class_decorator + class G: + pass + self.assertEqual(G.decorated, True) + + def testListcomps(self): + # list comprehension tests + nums = [1, 2, 3, 4, 5] + strs = ["Apple", "Banana", "Coconut"] + spcs = [" Apple", " Banana ", "Coco nut "] + + self.assertEqual([s.strip() for s in spcs], ['Apple', 'Banana', 'Coco nut']) + self.assertEqual([3 * x for x in nums], [3, 6, 9, 12, 15]) + self.assertEqual([x for x in nums if x > 2], [3, 4, 5]) + self.assertEqual([(i, s) for i in nums for s in strs], + [(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'), + (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'), + (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'), + (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'), + (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')]) + self.assertEqual([(i, s) for i in nums for s in [f for f in strs if "n" in f]], + [(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'), + (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'), + (5, 'Banana'), (5, 'Coconut')]) + self.assertEqual([(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)], + [[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]]) + + def test_in_func(l): + return [None < x < 3 for x in l if x > 2] + + self.assertEqual(test_in_func(nums), [False, False, False]) + + def test_nested_front(): + self.assertEqual([[y for y in [x, x + 1]] for x in [1,3,5]], + [[1, 2], [3, 4], [5, 6]]) + + test_nested_front() + + check_syntax_error(self, "[i, s for i in nums for s in strs]") + check_syntax_error(self, "[x if y]") + + suppliers = [ + (1, "Boeing"), + (2, "Ford"), + (3, "Macdonalds") + ] + + parts = [ + (10, "Airliner"), + (20, "Engine"), + (30, "Cheeseburger") + ] + + suppart = [ + (1, 10), (1, 20), (2, 20), (3, 30) + ] + + x = [ + (sname, pname) + for (sno, sname) in suppliers + for (pno, pname) in parts + for (sp_sno, sp_pno) in suppart + if sno == sp_sno and pno == sp_pno + ] + + self.assertEqual(x, [('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), + ('Macdonalds', 'Cheeseburger')]) + + def testGenexps(self): + # generator expression tests + g = ([x for x in range(10)] for x in range(1)) + self.assertEqual(g.next(), [x for x in range(10)]) + try: + g.next() + self.fail('should produce StopIteration exception') + except StopIteration: + pass + + a = 1 + try: + g = (a for d in a) + g.next() + self.fail('should produce TypeError') + except TypeError: + pass + + self.assertEqual(list((x, y) for x in 'abcd' for y in 'abcd'), [(x, y) for x in 'abcd' for y in 'abcd']) + self.assertEqual(list((x, y) for x in 'ab' for y in 'xy'), [(x, y) for x in 'ab' for y in 'xy']) + + a = [x for x in range(10)] + b = (x for x in (y for y in a)) + self.assertEqual(sum(b), sum([x for x in range(10)])) + + self.assertEqual(sum(x**2 for x in range(10)), sum([x**2 for x in range(10)])) + self.assertEqual(sum(x*x for x in range(10) if x%2), sum([x*x for x in range(10) if x%2])) + self.assertEqual(sum(x for x in (y for y in range(10))), sum([x for x in range(10)])) + self.assertEqual(sum(x for x in (y for y in (z for z in range(10)))), sum([x for x in range(10)])) + self.assertEqual(sum(x for x in [y for y in (z for z in range(10))]), sum([x for x in range(10)])) + self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True)) if True), sum([x for x in range(10)])) + self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True) if False) if True), 0) + check_syntax_error(self, "foo(x for x in range(10), 100)") + check_syntax_error(self, "foo(100, x for x in range(10))") + + def testComprehensionSpecials(self): + # test for outmost iterable precomputation + x = 10; g = (i for i in range(x)); x = 5 + self.assertEqual(len(list(g)), 10) + + # This should hold, since we're only precomputing outmost iterable. + x = 10; t = False; g = ((i,j) for i in range(x) if t for j in range(x)) + x = 5; t = True; + self.assertEqual([(i,j) for i in range(10) for j in range(5)], list(g)) + + # Grammar allows multiple adjacent 'if's in listcomps and genexps, + # even though it's silly. Make sure it works (ifelse broke this.) + self.assertEqual([ x for x in range(10) if x % 2 if x % 3 ], [1, 5, 7]) + self.assertEqual(list(x for x in range(10) if x % 2 if x % 3), [1, 5, 7]) + + # verify unpacking single element tuples in listcomp/genexp. + self.assertEqual([x for x, in [(4,), (5,), (6,)]], [4, 5, 6]) + self.assertEqual(list(x for x, in [(7,), (8,), (9,)]), [7, 8, 9]) + + def testIfElseExpr(self): + # Test ifelse expressions in various cases + def _checkeval(msg, ret): + "helper to check that evaluation of expressions is done correctly" + print x + return ret + + self.assertEqual([ x() for x in lambda: True, lambda: False if x() ], [True]) + self.assertEqual([ x() for x in (lambda: True, lambda: False) if x() ], [True]) + self.assertEqual([ x(False) for x in (lambda x: False if x else True, lambda x: True if x else False) if x(False) ], [True]) + self.assertEqual((5 if 1 else _checkeval("check 1", 0)), 5) + self.assertEqual((_checkeval("check 2", 0) if 0 else 5), 5) + self.assertEqual((5 and 6 if 0 else 1), 1) + self.assertEqual(((5 and 6) if 0 else 1), 1) + self.assertEqual((5 and (6 if 1 else 1)), 6) + self.assertEqual((0 or _checkeval("check 3", 2) if 0 else 3), 3) + self.assertEqual((1 or _checkeval("check 4", 2) if 1 else _checkeval("check 5", 3)), 1) + self.assertEqual((0 or 5 if 1 else _checkeval("check 6", 3)), 5) + self.assertEqual((not 5 if 1 else 1), False) + self.assertEqual((not 5 if 0 else 1), 1) + self.assertEqual((6 + 1 if 1 else 2), 7) + self.assertEqual((6 - 1 if 1 else 2), 5) + self.assertEqual((6 * 2 if 1 else 4), 12) + self.assertEqual((6 / 2 if 1 else 3), 3) + self.assertEqual((6 < 4 if 0 else 2), 2) + + +def test_main(): + run_unittest(TokenTests, GrammarTests) + +if __name__ == '__main__': + test_main() Added: sandbox/trunk/refactor_pkg/lib2to3/tests/data/py3_test_grammar.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/tests/data/py3_test_grammar.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,903 @@ +# Python test set -- part 1, grammar. +# This just tests whether the parser accepts them all. + +# NOTE: When you run this test as a script from the command line, you +# get warnings about certain hex/oct constants. Since those are +# issued by the parser, you can't suppress them by adding a +# filterwarnings() call to this module. Therefore, to shut up the +# regression test, the filterwarnings() call has been added to +# regrtest.py. + +from test.support import run_unittest, check_syntax_error +import unittest +import sys +# testing import * +from sys import * + +class TokenTests(unittest.TestCase): + + def testBackslash(self): + # Backslash means line continuation: + x = 1 \ + + 1 + self.assertEquals(x, 2, 'backslash for line continuation') + + # Backslash does not means continuation in comments :\ + x = 0 + self.assertEquals(x, 0, 'backslash ending comment') + + def testPlainIntegers(self): + self.assertEquals(type(000), type(0)) + self.assertEquals(0xff, 255) + self.assertEquals(0o377, 255) + self.assertEquals(2147483647, 0o17777777777) + self.assertEquals(0b1001, 9) + # "0x" is not a valid literal + self.assertRaises(SyntaxError, eval, "0x") + from sys import maxsize + if maxsize == 2147483647: + self.assertEquals(-2147483647-1, -0o20000000000) + # XXX -2147483648 + self.assert_(0o37777777777 > 0) + self.assert_(0xffffffff > 0) + self.assert_(0b1111111111111111111111111111111 > 0) + for s in ('2147483648', '0o40000000000', '0x100000000', + '0b10000000000000000000000000000000'): + try: + x = eval(s) + except OverflowError: + self.fail("OverflowError on huge integer literal %r" % s) + elif maxsize == 9223372036854775807: + self.assertEquals(-9223372036854775807-1, -0o1000000000000000000000) + self.assert_(0o1777777777777777777777 > 0) + self.assert_(0xffffffffffffffff > 0) + self.assert_(0b11111111111111111111111111111111111111111111111111111111111111 > 0) + for s in '9223372036854775808', '0o2000000000000000000000', \ + '0x10000000000000000', \ + '0b100000000000000000000000000000000000000000000000000000000000000': + try: + x = eval(s) + except OverflowError: + self.fail("OverflowError on huge integer literal %r" % s) + else: + self.fail('Weird maxsize value %r' % maxsize) + + def testLongIntegers(self): + x = 0 + x = 0xffffffffffffffff + x = 0Xffffffffffffffff + x = 0o77777777777777777 + x = 0O77777777777777777 + x = 123456789012345678901234567890 + x = 0b100000000000000000000000000000000000000000000000000000000000000000000 + x = 0B111111111111111111111111111111111111111111111111111111111111111111111 + + def testFloats(self): + x = 3.14 + x = 314. + x = 0.314 + # XXX x = 000.314 + x = .314 + x = 3e14 + x = 3E14 + x = 3e-14 + x = 3e+14 + x = 3.e14 + x = .3e14 + x = 3.1e4 + + def testStringLiterals(self): + x = ''; y = ""; self.assert_(len(x) == 0 and x == y) + x = '\''; y = "'"; self.assert_(len(x) == 1 and x == y and ord(x) == 39) + x = '"'; y = "\""; self.assert_(len(x) == 1 and x == y and ord(x) == 34) + x = "doesn't \"shrink\" does it" + y = 'doesn\'t "shrink" does it' + self.assert_(len(x) == 24 and x == y) + x = "does \"shrink\" doesn't it" + y = 'does "shrink" doesn\'t it' + self.assert_(len(x) == 24 and x == y) + x = """ +The "quick" +brown fox +jumps over +the 'lazy' dog. +""" + y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n' + self.assertEquals(x, y) + y = ''' +The "quick" +brown fox +jumps over +the 'lazy' dog. +''' + self.assertEquals(x, y) + y = "\n\ +The \"quick\"\n\ +brown fox\n\ +jumps over\n\ +the 'lazy' dog.\n\ +" + self.assertEquals(x, y) + y = '\n\ +The \"quick\"\n\ +brown fox\n\ +jumps over\n\ +the \'lazy\' dog.\n\ +' + self.assertEquals(x, y) + + def testEllipsis(self): + x = ... + self.assert_(x is Ellipsis) + self.assertRaises(SyntaxError, eval, ".. .") + +class GrammarTests(unittest.TestCase): + + # single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE + # XXX can't test in a script -- this rule is only used when interactive + + # file_input: (NEWLINE | stmt)* ENDMARKER + # Being tested as this very moment this very module + + # expr_input: testlist NEWLINE + # XXX Hard to test -- used only in calls to input() + + def testEvalInput(self): + # testlist ENDMARKER + x = eval('1, 0 or 1') + + def testFuncdef(self): + ### [decorators] 'def' NAME parameters ['->' test] ':' suite + ### decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE + ### decorators: decorator+ + ### parameters: '(' [typedargslist] ')' + ### typedargslist: ((tfpdef ['=' test] ',')* + ### ('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef) + ### | tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) + ### tfpdef: NAME [':' test] + ### varargslist: ((vfpdef ['=' test] ',')* + ### ('*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef) + ### | vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) + ### vfpdef: NAME + def f1(): pass + f1() + f1(*()) + f1(*(), **{}) + def f2(one_argument): pass + def f3(two, arguments): pass + self.assertEquals(f2.__code__.co_varnames, ('one_argument',)) + self.assertEquals(f3.__code__.co_varnames, ('two', 'arguments')) + def a1(one_arg,): pass + def a2(two, args,): pass + def v0(*rest): pass + def v1(a, *rest): pass + def v2(a, b, *rest): pass + + f1() + f2(1) + f2(1,) + f3(1, 2) + f3(1, 2,) + v0() + v0(1) + v0(1,) + v0(1,2) + v0(1,2,3,4,5,6,7,8,9,0) + v1(1) + v1(1,) + v1(1,2) + v1(1,2,3) + v1(1,2,3,4,5,6,7,8,9,0) + v2(1,2) + v2(1,2,3) + v2(1,2,3,4) + v2(1,2,3,4,5,6,7,8,9,0) + + def d01(a=1): pass + d01() + d01(1) + d01(*(1,)) + d01(**{'a':2}) + def d11(a, b=1): pass + d11(1) + d11(1, 2) + d11(1, **{'b':2}) + def d21(a, b, c=1): pass + d21(1, 2) + d21(1, 2, 3) + d21(*(1, 2, 3)) + d21(1, *(2, 3)) + d21(1, 2, *(3,)) + d21(1, 2, **{'c':3}) + def d02(a=1, b=2): pass + d02() + d02(1) + d02(1, 2) + d02(*(1, 2)) + d02(1, *(2,)) + d02(1, **{'b':2}) + d02(**{'a': 1, 'b': 2}) + def d12(a, b=1, c=2): pass + d12(1) + d12(1, 2) + d12(1, 2, 3) + def d22(a, b, c=1, d=2): pass + d22(1, 2) + d22(1, 2, 3) + d22(1, 2, 3, 4) + def d01v(a=1, *rest): pass + d01v() + d01v(1) + d01v(1, 2) + d01v(*(1, 2, 3, 4)) + d01v(*(1,)) + d01v(**{'a':2}) + def d11v(a, b=1, *rest): pass + d11v(1) + d11v(1, 2) + d11v(1, 2, 3) + def d21v(a, b, c=1, *rest): pass + d21v(1, 2) + d21v(1, 2, 3) + d21v(1, 2, 3, 4) + d21v(*(1, 2, 3, 4)) + d21v(1, 2, **{'c': 3}) + def d02v(a=1, b=2, *rest): pass + d02v() + d02v(1) + d02v(1, 2) + d02v(1, 2, 3) + d02v(1, *(2, 3, 4)) + d02v(**{'a': 1, 'b': 2}) + def d12v(a, b=1, c=2, *rest): pass + d12v(1) + d12v(1, 2) + d12v(1, 2, 3) + d12v(1, 2, 3, 4) + d12v(*(1, 2, 3, 4)) + d12v(1, 2, *(3, 4, 5)) + d12v(1, *(2,), **{'c': 3}) + def d22v(a, b, c=1, d=2, *rest): pass + d22v(1, 2) + d22v(1, 2, 3) + d22v(1, 2, 3, 4) + d22v(1, 2, 3, 4, 5) + d22v(*(1, 2, 3, 4)) + d22v(1, 2, *(3, 4, 5)) + d22v(1, *(2, 3), **{'d': 4}) + + # keyword argument type tests + try: + str('x', **{b'foo':1 }) + except TypeError: + pass + else: + self.fail('Bytes should not work as keyword argument names') + # keyword only argument tests + def pos0key1(*, key): return key + pos0key1(key=100) + def pos2key2(p1, p2, *, k1, k2=100): return p1,p2,k1,k2 + pos2key2(1, 2, k1=100) + pos2key2(1, 2, k1=100, k2=200) + pos2key2(1, 2, k2=100, k1=200) + def pos2key2dict(p1, p2, *, k1=100, k2, **kwarg): return p1,p2,k1,k2,kwarg + pos2key2dict(1,2,k2=100,tokwarg1=100,tokwarg2=200) + pos2key2dict(1,2,tokwarg1=100,tokwarg2=200, k2=100) + + # keyword arguments after *arglist + def f(*args, **kwargs): + return args, kwargs + self.assertEquals(f(1, x=2, *[3, 4], y=5), ((1, 3, 4), + {'x':2, 'y':5})) + self.assertRaises(SyntaxError, eval, "f(1, *(2,3), 4)") + self.assertRaises(SyntaxError, eval, "f(1, x=2, *(3,4), x=5)") + + # argument annotation tests + def f(x) -> list: pass + self.assertEquals(f.__annotations__, {'return': list}) + def f(x:int): pass + self.assertEquals(f.__annotations__, {'x': int}) + def f(*x:str): pass + self.assertEquals(f.__annotations__, {'x': str}) + def f(**x:float): pass + self.assertEquals(f.__annotations__, {'x': float}) + def f(x, y:1+2): pass + self.assertEquals(f.__annotations__, {'y': 3}) + def f(a, b:1, c:2, d): pass + self.assertEquals(f.__annotations__, {'b': 1, 'c': 2}) + def f(a, b:1, c:2, d, e:3=4, f=5, *g:6): pass + self.assertEquals(f.__annotations__, + {'b': 1, 'c': 2, 'e': 3, 'g': 6}) + def f(a, b:1, c:2, d, e:3=4, f=5, *g:6, h:7, i=8, j:9=10, + **k:11) -> 12: pass + self.assertEquals(f.__annotations__, + {'b': 1, 'c': 2, 'e': 3, 'g': 6, 'h': 7, 'j': 9, + 'k': 11, 'return': 12}) + # Check for SF Bug #1697248 - mixing decorators and a return annotation + def null(x): return x + @null + def f(x) -> list: pass + self.assertEquals(f.__annotations__, {'return': list}) + + # test MAKE_CLOSURE with a variety of oparg's + closure = 1 + def f(): return closure + def f(x=1): return closure + def f(*, k=1): return closure + def f() -> int: return closure + + # Check ast errors in *args and *kwargs + check_syntax_error(self, "f(*g(1=2))") + check_syntax_error(self, "f(**g(1=2))") + + def testLambdef(self): + ### lambdef: 'lambda' [varargslist] ':' test + l1 = lambda : 0 + self.assertEquals(l1(), 0) + l2 = lambda : a[d] # XXX just testing the expression + l3 = lambda : [2 < x for x in [-1, 3, 0]] + self.assertEquals(l3(), [0, 1, 0]) + l4 = lambda x = lambda y = lambda z=1 : z : y() : x() + self.assertEquals(l4(), 1) + l5 = lambda x, y, z=2: x + y + z + self.assertEquals(l5(1, 2), 5) + self.assertEquals(l5(1, 2, 3), 6) + check_syntax_error(self, "lambda x: x = 2") + check_syntax_error(self, "lambda (None,): None") + l6 = lambda x, y, *, k=20: x+y+k + self.assertEquals(l6(1,2), 1+2+20) + self.assertEquals(l6(1,2,k=10), 1+2+10) + + + ### stmt: simple_stmt | compound_stmt + # Tested below + + def testSimpleStmt(self): + ### simple_stmt: small_stmt (';' small_stmt)* [';'] + x = 1; pass; del x + def foo(): + # verify statments that end with semi-colons + x = 1; pass; del x; + foo() + + ### small_stmt: expr_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt + # Tested below + + def testExprStmt(self): + # (exprlist '=')* exprlist + 1 + 1, 2, 3 + x = 1 + x = 1, 2, 3 + x = y = z = 1, 2, 3 + x, y, z = 1, 2, 3 + abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4) + + check_syntax_error(self, "x + 1 = 1") + check_syntax_error(self, "a + 1 = b + 2") + + def testDelStmt(self): + # 'del' exprlist + abc = [1,2,3] + x, y, z = abc + xyz = x, y, z + + del abc + del x, y, (z, xyz) + + def testPassStmt(self): + # 'pass' + pass + + # flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt + # Tested below + + def testBreakStmt(self): + # 'break' + while 1: break + + def testContinueStmt(self): + # 'continue' + i = 1 + while i: i = 0; continue + + msg = "" + while not msg: + msg = "ok" + try: + continue + msg = "continue failed to continue inside try" + except: + msg = "continue inside try called except block" + if msg != "ok": + self.fail(msg) + + msg = "" + while not msg: + msg = "finally block not called" + try: + continue + finally: + msg = "ok" + if msg != "ok": + self.fail(msg) + + def test_break_continue_loop(self): + # This test warrants an explanation. It is a test specifically for SF bugs + # #463359 and #462937. The bug is that a 'break' statement executed or + # exception raised inside a try/except inside a loop, *after* a continue + # statement has been executed in that loop, will cause the wrong number of + # arguments to be popped off the stack and the instruction pointer reset to + # a very small number (usually 0.) Because of this, the following test + # *must* written as a function, and the tracking vars *must* be function + # arguments with default values. Otherwise, the test will loop and loop. + + def test_inner(extra_burning_oil = 1, count=0): + big_hippo = 2 + while big_hippo: + count += 1 + try: + if extra_burning_oil and big_hippo == 1: + extra_burning_oil -= 1 + break + big_hippo -= 1 + continue + except: + raise + if count > 2 or big_hippo != 1: + self.fail("continue then break in try/except in loop broken!") + test_inner() + + def testReturn(self): + # 'return' [testlist] + def g1(): return + def g2(): return 1 + g1() + x = g2() + check_syntax_error(self, "class foo:return 1") + + def testYield(self): + check_syntax_error(self, "class foo:yield 1") + + def testRaise(self): + # 'raise' test [',' test] + try: raise RuntimeError('just testing') + except RuntimeError: pass + try: raise KeyboardInterrupt + except KeyboardInterrupt: pass + + def testImport(self): + # 'import' dotted_as_names + import sys + import time, sys + # 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names) + from time import time + from time import (time) + # not testable inside a function, but already done at top of the module + # from sys import * + from sys import path, argv + from sys import (path, argv) + from sys import (path, argv,) + + def testGlobal(self): + # 'global' NAME (',' NAME)* + global a + global a, b + global one, two, three, four, five, six, seven, eight, nine, ten + + def testNonlocal(self): + # 'nonlocal' NAME (',' NAME)* + x = 0 + y = 0 + def f(): + nonlocal x + nonlocal x, y + + def testAssert(self): + # assert_stmt: 'assert' test [',' test] + assert 1 + assert 1, 1 + assert lambda x:x + assert 1, lambda x:x+1 + try: + assert 0, "msg" + except AssertionError as e: + self.assertEquals(e.args[0], "msg") + else: + if __debug__: + self.fail("AssertionError not raised by assert 0") + + ### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef + # Tested below + + def testIf(self): + # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] + if 1: pass + if 1: pass + else: pass + if 0: pass + elif 0: pass + if 0: pass + elif 0: pass + elif 0: pass + elif 0: pass + else: pass + + def testWhile(self): + # 'while' test ':' suite ['else' ':' suite] + while 0: pass + while 0: pass + else: pass + + # Issue1920: "while 0" is optimized away, + # ensure that the "else" clause is still present. + x = 0 + while 0: + x = 1 + else: + x = 2 + self.assertEquals(x, 2) + + def testFor(self): + # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] + for i in 1, 2, 3: pass + for i, j, k in (): pass + else: pass + class Squares: + def __init__(self, max): + self.max = max + self.sofar = [] + def __len__(self): return len(self.sofar) + def __getitem__(self, i): + if not 0 <= i < self.max: raise IndexError + n = len(self.sofar) + while n <= i: + self.sofar.append(n*n) + n = n+1 + return self.sofar[i] + n = 0 + for x in Squares(10): n = n+x + if n != 285: + self.fail('for over growing sequence') + + result = [] + for x, in [(1,), (2,), (3,)]: + result.append(x) + self.assertEqual(result, [1, 2, 3]) + + def testTry(self): + ### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] + ### | 'try' ':' suite 'finally' ':' suite + ### except_clause: 'except' [expr ['as' expr]] + try: + 1/0 + except ZeroDivisionError: + pass + else: + pass + try: 1/0 + except EOFError: pass + except TypeError as msg: pass + except RuntimeError as msg: pass + except: pass + else: pass + try: 1/0 + except (EOFError, TypeError, ZeroDivisionError): pass + try: 1/0 + except (EOFError, TypeError, ZeroDivisionError) as msg: pass + try: pass + finally: pass + + def testSuite(self): + # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT + if 1: pass + if 1: + pass + if 1: + # + # + # + pass + pass + # + pass + # + + def testTest(self): + ### and_test ('or' and_test)* + ### and_test: not_test ('and' not_test)* + ### not_test: 'not' not_test | comparison + if not 1: pass + if 1 and 1: pass + if 1 or 1: pass + if not not not 1: pass + if not 1 and 1 and 1: pass + if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass + + def testComparison(self): + ### comparison: expr (comp_op expr)* + ### comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is'|'is' 'not' + if 1: pass + x = (1 == 1) + if 1 == 1: pass + if 1 != 1: pass + if 1 < 1: pass + if 1 > 1: pass + if 1 <= 1: pass + if 1 >= 1: pass + if 1 is 1: pass + if 1 is not 1: pass + if 1 in (): pass + if 1 not in (): pass + if 1 < 1 > 1 == 1 >= 1 <= 1 != 1 in 1 not in 1 is 1 is not 1: pass + + def testBinaryMaskOps(self): + x = 1 & 1 + x = 1 ^ 1 + x = 1 | 1 + + def testShiftOps(self): + x = 1 << 1 + x = 1 >> 1 + x = 1 << 1 >> 1 + + def testAdditiveOps(self): + x = 1 + x = 1 + 1 + x = 1 - 1 - 1 + x = 1 - 1 + 1 - 1 + 1 + + def testMultiplicativeOps(self): + x = 1 * 1 + x = 1 / 1 + x = 1 % 1 + x = 1 / 1 * 1 % 1 + + def testUnaryOps(self): + x = +1 + x = -1 + x = ~1 + x = ~1 ^ 1 & 1 | 1 & 1 ^ -1 + x = -1*1/1 + 1*1 - ---1*1 + + def testSelectors(self): + ### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME + ### subscript: expr | [expr] ':' [expr] + + import sys, time + c = sys.path[0] + x = time.time() + x = sys.modules['time'].time() + a = '01234' + c = a[0] + c = a[-1] + s = a[0:5] + s = a[:5] + s = a[0:] + s = a[:] + s = a[-5:] + s = a[:-1] + s = a[-4:-3] + # A rough test of SF bug 1333982. http://python.org/sf/1333982 + # The testing here is fairly incomplete. + # Test cases should include: commas with 1 and 2 colons + d = {} + d[1] = 1 + d[1,] = 2 + d[1,2] = 3 + d[1,2,3] = 4 + L = list(d) + L.sort(key=lambda x: x if isinstance(x, tuple) else ()) + self.assertEquals(str(L), '[1, (1,), (1, 2), (1, 2, 3)]') + + def testAtoms(self): + ### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictsetmaker] '}' | NAME | NUMBER | STRING + ### dictsetmaker: (test ':' test (',' test ':' test)* [',']) | (test (',' test)* [',']) + + x = (1) + x = (1 or 2 or 3) + x = (1 or 2 or 3, 2, 3) + + x = [] + x = [1] + x = [1 or 2 or 3] + x = [1 or 2 or 3, 2, 3] + x = [] + + x = {} + x = {'one': 1} + x = {'one': 1,} + x = {'one' or 'two': 1 or 2} + x = {'one': 1, 'two': 2} + x = {'one': 1, 'two': 2,} + x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6} + + x = {'one'} + x = {'one', 1,} + x = {'one', 'two', 'three'} + x = {2, 3, 4,} + + x = x + x = 'x' + x = 123 + + ### exprlist: expr (',' expr)* [','] + ### testlist: test (',' test)* [','] + # These have been exercised enough above + + def testClassdef(self): + # 'class' NAME ['(' [testlist] ')'] ':' suite + class B: pass + class B2(): pass + class C1(B): pass + class C2(B): pass + class D(C1, C2, B): pass + class C: + def meth1(self): pass + def meth2(self, arg): pass + def meth3(self, a1, a2): pass + + # decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE + # decorators: decorator+ + # decorated: decorators (classdef | funcdef) + def class_decorator(x): return x + @class_decorator + class G: pass + + def testDictcomps(self): + # dictorsetmaker: ( (test ':' test (comp_for | + # (',' test ':' test)* [','])) | + # (test (comp_for | (',' test)* [','])) ) + nums = [1, 2, 3] + self.assertEqual({i:i+1 for i in nums}, {1: 2, 2: 3, 3: 4}) + + def testListcomps(self): + # list comprehension tests + nums = [1, 2, 3, 4, 5] + strs = ["Apple", "Banana", "Coconut"] + spcs = [" Apple", " Banana ", "Coco nut "] + + self.assertEqual([s.strip() for s in spcs], ['Apple', 'Banana', 'Coco nut']) + self.assertEqual([3 * x for x in nums], [3, 6, 9, 12, 15]) + self.assertEqual([x for x in nums if x > 2], [3, 4, 5]) + self.assertEqual([(i, s) for i in nums for s in strs], + [(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'), + (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'), + (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'), + (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'), + (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')]) + self.assertEqual([(i, s) for i in nums for s in [f for f in strs if "n" in f]], + [(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'), + (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'), + (5, 'Banana'), (5, 'Coconut')]) + self.assertEqual([(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)], + [[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]]) + + def test_in_func(l): + return [0 < x < 3 for x in l if x > 2] + + self.assertEqual(test_in_func(nums), [False, False, False]) + + def test_nested_front(): + self.assertEqual([[y for y in [x, x + 1]] for x in [1,3,5]], + [[1, 2], [3, 4], [5, 6]]) + + test_nested_front() + + check_syntax_error(self, "[i, s for i in nums for s in strs]") + check_syntax_error(self, "[x if y]") + + suppliers = [ + (1, "Boeing"), + (2, "Ford"), + (3, "Macdonalds") + ] + + parts = [ + (10, "Airliner"), + (20, "Engine"), + (30, "Cheeseburger") + ] + + suppart = [ + (1, 10), (1, 20), (2, 20), (3, 30) + ] + + x = [ + (sname, pname) + for (sno, sname) in suppliers + for (pno, pname) in parts + for (sp_sno, sp_pno) in suppart + if sno == sp_sno and pno == sp_pno + ] + + self.assertEqual(x, [('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), + ('Macdonalds', 'Cheeseburger')]) + + def testGenexps(self): + # generator expression tests + g = ([x for x in range(10)] for x in range(1)) + self.assertEqual(next(g), [x for x in range(10)]) + try: + next(g) + self.fail('should produce StopIteration exception') + except StopIteration: + pass + + a = 1 + try: + g = (a for d in a) + next(g) + self.fail('should produce TypeError') + except TypeError: + pass + + self.assertEqual(list((x, y) for x in 'abcd' for y in 'abcd'), [(x, y) for x in 'abcd' for y in 'abcd']) + self.assertEqual(list((x, y) for x in 'ab' for y in 'xy'), [(x, y) for x in 'ab' for y in 'xy']) + + a = [x for x in range(10)] + b = (x for x in (y for y in a)) + self.assertEqual(sum(b), sum([x for x in range(10)])) + + self.assertEqual(sum(x**2 for x in range(10)), sum([x**2 for x in range(10)])) + self.assertEqual(sum(x*x for x in range(10) if x%2), sum([x*x for x in range(10) if x%2])) + self.assertEqual(sum(x for x in (y for y in range(10))), sum([x for x in range(10)])) + self.assertEqual(sum(x for x in (y for y in (z for z in range(10)))), sum([x for x in range(10)])) + self.assertEqual(sum(x for x in [y for y in (z for z in range(10))]), sum([x for x in range(10)])) + self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True)) if True), sum([x for x in range(10)])) + self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True) if False) if True), 0) + check_syntax_error(self, "foo(x for x in range(10), 100)") + check_syntax_error(self, "foo(100, x for x in range(10))") + + def testComprehensionSpecials(self): + # test for outmost iterable precomputation + x = 10; g = (i for i in range(x)); x = 5 + self.assertEqual(len(list(g)), 10) + + # This should hold, since we're only precomputing outmost iterable. + x = 10; t = False; g = ((i,j) for i in range(x) if t for j in range(x)) + x = 5; t = True; + self.assertEqual([(i,j) for i in range(10) for j in range(5)], list(g)) + + # Grammar allows multiple adjacent 'if's in listcomps and genexps, + # even though it's silly. Make sure it works (ifelse broke this.) + self.assertEqual([ x for x in range(10) if x % 2 if x % 3 ], [1, 5, 7]) + self.assertEqual(list(x for x in range(10) if x % 2 if x % 3), [1, 5, 7]) + + # verify unpacking single element tuples in listcomp/genexp. + self.assertEqual([x for x, in [(4,), (5,), (6,)]], [4, 5, 6]) + self.assertEqual(list(x for x, in [(7,), (8,), (9,)]), [7, 8, 9]) + + def testIfElseExpr(self): + # Test ifelse expressions in various cases + def _checkeval(msg, ret): + "helper to check that evaluation of expressions is done correctly" + print(x) + return ret + + # the next line is not allowed anymore + #self.assertEqual([ x() for x in lambda: True, lambda: False if x() ], [True]) + self.assertEqual([ x() for x in (lambda: True, lambda: False) if x() ], [True]) + self.assertEqual([ x(False) for x in (lambda x: False if x else True, lambda x: True if x else False) if x(False) ], [True]) + self.assertEqual((5 if 1 else _checkeval("check 1", 0)), 5) + self.assertEqual((_checkeval("check 2", 0) if 0 else 5), 5) + self.assertEqual((5 and 6 if 0 else 1), 1) + self.assertEqual(((5 and 6) if 0 else 1), 1) + self.assertEqual((5 and (6 if 1 else 1)), 6) + self.assertEqual((0 or _checkeval("check 3", 2) if 0 else 3), 3) + self.assertEqual((1 or _checkeval("check 4", 2) if 1 else _checkeval("check 5", 3)), 1) + self.assertEqual((0 or 5 if 1 else _checkeval("check 6", 3)), 5) + self.assertEqual((not 5 if 1 else 1), False) + self.assertEqual((not 5 if 0 else 1), 1) + self.assertEqual((6 + 1 if 1 else 2), 7) + self.assertEqual((6 - 1 if 1 else 2), 5) + self.assertEqual((6 * 2 if 1 else 4), 12) + self.assertEqual((6 / 2 if 1 else 3), 3) + self.assertEqual((6 < 4 if 0 else 2), 2) + + +def test_main(): + run_unittest(TokenTests, GrammarTests) + +if __name__ == '__main__': + test_main() Added: sandbox/trunk/refactor_pkg/lib2to3/tests/pytree_idempotency.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/tests/pytree_idempotency.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,92 @@ +#!/usr/bin/env python2.5 +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Main program for testing the infrastructure.""" + +__author__ = "Guido van Rossum " + +# Support imports (need to be imported first) +from . import support + +# Python imports +import os +import sys +import logging + +# Local imports +from .. import pytree +import pgen2 +from pgen2 import driver + +logging.basicConfig() + +def main(): + gr = driver.load_grammar("Grammar.txt") + dr = driver.Driver(gr, convert=pytree.convert) + + fn = "example.py" + tree = dr.parse_file(fn, debug=True) + if not diff(fn, tree): + print "No diffs." + if not sys.argv[1:]: + return # Pass a dummy argument to run the complete test suite below + + problems = [] + + # Process every imported module + for name in sys.modules: + mod = sys.modules[name] + if mod is None or not hasattr(mod, "__file__"): + continue + fn = mod.__file__ + if fn.endswith(".pyc"): + fn = fn[:-1] + if not fn.endswith(".py"): + continue + print >>sys.stderr, "Parsing", fn + tree = dr.parse_file(fn, debug=True) + if diff(fn, tree): + problems.append(fn) + + # Process every single module on sys.path (but not in packages) + for dir in sys.path: + try: + names = os.listdir(dir) + except os.error: + continue + print >>sys.stderr, "Scanning", dir, "..." + for name in names: + if not name.endswith(".py"): + continue + print >>sys.stderr, "Parsing", name + fn = os.path.join(dir, name) + try: + tree = dr.parse_file(fn, debug=True) + except pgen2.parse.ParseError, err: + print "ParseError:", err + else: + if diff(fn, tree): + problems.append(fn) + + # Show summary of problem files + if not problems: + print "No problems. Congratulations!" + else: + print "Problems in following files:" + for fn in problems: + print "***", fn + +def diff(fn, tree): + f = open("@", "w") + try: + f.write(str(tree)) + finally: + f.close() + try: + return os.system("diff -u %s @" % fn) + finally: + os.remove("@") + +if __name__ == "__main__": + main() Added: sandbox/trunk/refactor_pkg/lib2to3/tests/support.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/tests/support.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,78 @@ +"""Support code for test_*.py files""" +# Original Author: Collin Winter + +# Python imports +import unittest +import sys +import os +import os.path +import re +from textwrap import dedent + +#sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) + +# Local imports +from .. import pytree +from .. import refactor +from ..pgen2 import driver + +test_pkg = "refactor.fixes" +test_dir = os.path.dirname(__file__) +proj_dir = os.path.normpath(os.path.join(test_dir, "..")) +grammar_path = os.path.join(test_dir, "..", "Grammar.txt") +grammar = driver.load_grammar(grammar_path) +driver = driver.Driver(grammar, convert=pytree.convert) + +def parse_version(version_string): + """Returns a version tuple matching input version_string.""" + if not version_string: + return () + + version_list = [] + for token in version_string.split('.'): + try: + version_list.append(int(token)) + except ValueError: + version_list.append(token) + return tuple(version_list) + +def parse_string(string): + return driver.parse_string(reformat(string), debug=True) + +# Python 2.3's TestSuite is not iter()-able +if sys.version_info < (2, 4): + def TestSuite_iter(self): + return iter(self._tests) + unittest.TestSuite.__iter__ = TestSuite_iter + +def run_all_tests(test_mod=None, tests=None): + if tests is None: + tests = unittest.TestLoader().loadTestsFromModule(test_mod) + unittest.TextTestRunner(verbosity=2).run(tests) + +def reformat(string): + return dedent(string) + "\n\n" + +def get_refactorer(fixers=None, options=None, pkg_name=None): + """ + A convenience function for creating a RefactoringTool for tests. + + fixers is a list of fixers for the RefactoringTool to use. By default + "refactor.fixes.*" is used. options is an optional dictionary of options to + be passed to the RefactoringTool. + """ + pkg_name = pkg_name or test_pkg + if fixers is not None: + fixers = [pkg_name + ".fix_" + fix for fix in fixers] + else: + fixers = refactor.get_fixers_from_package(pkg_name) + options = options or {} + return refactor.RefactoringTool(fixers, options, explicit=True) + +def all_project_files(): + for dirpath, dirnames, filenames in os.walk(proj_dir): + for filename in filenames: + if filename.endswith(".py"): + yield os.path.join(dirpath, filename) + +TestCase = unittest.TestCase Added: sandbox/trunk/refactor_pkg/lib2to3/tests/test_all_fixers.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/tests/test_all_fixers.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,35 @@ +#!/usr/bin/env python2.5 +"""Tests that run all fixer modules over an input stream. + +This has been broken out into its own test module because of its +running time. +""" +# Author: Collin Winter + +# Testing imports +try: + from . import support +except ImportError: + import support + +# Python imports +import unittest + +# Local imports +from .. import pytree +from .. import refactor + +class Test_all(support.TestCase): + def setUp(self): + options = {"print_function" : False} + self.refactor = support.get_refactorer(options=options) + + def test_all_project_files(self): + for filepath in support.all_project_files(): + print "Fixing %s..." % filepath + self.refactor.refactor_string(open(filepath).read(), filepath) + + +if __name__ == "__main__": + import __main__ + support.run_all_tests(__main__) Added: sandbox/trunk/refactor_pkg/lib2to3/tests/test_fixers.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/tests/test_fixers.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,4033 @@ +#!/usr/bin/env python2.5 +""" Test suite for the fixer modules """ +# Author: Collin Winter + +# Testing imports +try: + from tests import support +except ImportError: + import support + +# Python imports +import os +import unittest +from itertools import chain +from operator import itemgetter + +# Local imports +from lib2to3 import pygram, pytree, refactor, fixer_util + + +class FixerTestCase(support.TestCase): + def setUp(self, fix_list=None): + if fix_list is None: + fix_list = [self.fixer] + options = {"print_function" : False} + self.refactor = support.get_refactorer(fix_list, options, "refactor.fixes.from2") + self.fixer_log = [] + self.filename = "" + + for fixer in chain(self.refactor.pre_order, + self.refactor.post_order): + fixer.log = self.fixer_log + + def _check(self, before, after): + before = support.reformat(before) + after = support.reformat(after) + tree = self.refactor.refactor_string(before, self.filename) + self.failUnlessEqual(after, str(tree)) + return tree + + def check(self, before, after, ignore_warnings=False): + tree = self._check(before, after) + self.failUnless(tree.was_changed) + if not ignore_warnings: + self.failUnlessEqual(self.fixer_log, []) + + def warns(self, before, after, message, unchanged=False): + tree = self._check(before, after) + self.failUnless(message in "".join(self.fixer_log)) + if not unchanged: + self.failUnless(tree.was_changed) + + def warns_unchanged(self, before, message): + self.warns(before, before, message, unchanged=True) + + def unchanged(self, before, ignore_warnings=False): + self._check(before, before) + if not ignore_warnings: + self.failUnlessEqual(self.fixer_log, []) + + def assert_runs_after(self, *names): + fixes = [self.fixer] + fixes.extend(names) + options = {"print_function" : False} + r = support.get_refactorer(fixes, options) + (pre, post) = r.get_fixers() + n = "fix_" + self.fixer + if post and post[-1].__class__.__module__.endswith(n): + # We're the last fixer to run + return + if pre and pre[-1].__class__.__module__.endswith(n) and not post: + # We're the last in pre and post is empty + return + self.fail("Fixer run order (%s) is incorrect; %s should be last."\ + %(", ".join([x.__class__.__module__ for x in (pre+post)]), n)) + +class Test_ne(FixerTestCase): + fixer = "ne" + + def test_basic(self): + b = """if x <> y: + pass""" + + a = """if x != y: + pass""" + self.check(b, a) + + def test_no_spaces(self): + b = """if x<>y: + pass""" + + a = """if x!=y: + pass""" + self.check(b, a) + + def test_chained(self): + b = """if x<>y<>z: + pass""" + + a = """if x!=y!=z: + pass""" + self.check(b, a) + +class Test_has_key(FixerTestCase): + fixer = "has_key" + + def test_1(self): + b = """x = d.has_key("x") or d.has_key("y")""" + a = """x = "x" in d or "y" in d""" + self.check(b, a) + + def test_2(self): + b = """x = a.b.c.d.has_key("x") ** 3""" + a = """x = ("x" in a.b.c.d) ** 3""" + self.check(b, a) + + def test_3(self): + b = """x = a.b.has_key(1 + 2).__repr__()""" + a = """x = (1 + 2 in a.b).__repr__()""" + self.check(b, a) + + def test_4(self): + b = """x = a.b.has_key(1 + 2).__repr__() ** -3 ** 4""" + a = """x = (1 + 2 in a.b).__repr__() ** -3 ** 4""" + self.check(b, a) + + def test_5(self): + b = """x = a.has_key(f or g)""" + a = """x = (f or g) in a""" + self.check(b, a) + + def test_6(self): + b = """x = a + b.has_key(c)""" + a = """x = a + (c in b)""" + self.check(b, a) + + def test_7(self): + b = """x = a.has_key(lambda: 12)""" + a = """x = (lambda: 12) in a""" + self.check(b, a) + + def test_8(self): + b = """x = a.has_key(a for a in b)""" + a = """x = (a for a in b) in a""" + self.check(b, a) + + def test_9(self): + b = """if not a.has_key(b): pass""" + a = """if b not in a: pass""" + self.check(b, a) + + def test_10(self): + b = """if not a.has_key(b).__repr__(): pass""" + a = """if not (b in a).__repr__(): pass""" + self.check(b, a) + + def test_11(self): + b = """if not a.has_key(b) ** 2: pass""" + a = """if not (b in a) ** 2: pass""" + self.check(b, a) + +class Test_apply(FixerTestCase): + fixer = "apply" + + def test_1(self): + b = """x = apply(f, g + h)""" + a = """x = f(*g + h)""" + self.check(b, a) + + def test_2(self): + b = """y = apply(f, g, h)""" + a = """y = f(*g, **h)""" + self.check(b, a) + + def test_3(self): + b = """z = apply(fs[0], g or h, h or g)""" + a = """z = fs[0](*g or h, **h or g)""" + self.check(b, a) + + def test_4(self): + b = """apply(f, (x, y) + t)""" + a = """f(*(x, y) + t)""" + self.check(b, a) + + def test_5(self): + b = """apply(f, args,)""" + a = """f(*args)""" + self.check(b, a) + + def test_6(self): + b = """apply(f, args, kwds,)""" + a = """f(*args, **kwds)""" + self.check(b, a) + + # Test that complex functions are parenthesized + + def test_complex_1(self): + b = """x = apply(f+g, args)""" + a = """x = (f+g)(*args)""" + self.check(b, a) + + def test_complex_2(self): + b = """x = apply(f*g, args)""" + a = """x = (f*g)(*args)""" + self.check(b, a) + + def test_complex_3(self): + b = """x = apply(f**g, args)""" + a = """x = (f**g)(*args)""" + self.check(b, a) + + # But dotted names etc. not + + def test_dotted_name(self): + b = """x = apply(f.g, args)""" + a = """x = f.g(*args)""" + self.check(b, a) + + def test_subscript(self): + b = """x = apply(f[x], args)""" + a = """x = f[x](*args)""" + self.check(b, a) + + def test_call(self): + b = """x = apply(f(), args)""" + a = """x = f()(*args)""" + self.check(b, a) + + # Extreme case + def test_extreme(self): + b = """x = apply(a.b.c.d.e.f, args, kwds)""" + a = """x = a.b.c.d.e.f(*args, **kwds)""" + self.check(b, a) + + # XXX Comments in weird places still get lost + def test_weird_comments(self): + b = """apply( # foo + f, # bar + args)""" + a = """f(*args)""" + self.check(b, a) + + # These should *not* be touched + + def test_unchanged_1(self): + s = """apply()""" + self.unchanged(s) + + def test_unchanged_2(self): + s = """apply(f)""" + self.unchanged(s) + + def test_unchanged_3(self): + s = """apply(f,)""" + self.unchanged(s) + + def test_unchanged_4(self): + s = """apply(f, args, kwds, extras)""" + self.unchanged(s) + + def test_unchanged_5(self): + s = """apply(f, *args, **kwds)""" + self.unchanged(s) + + def test_unchanged_6(self): + s = """apply(f, *args)""" + self.unchanged(s) + + def test_unchanged_7(self): + s = """apply(func=f, args=args, kwds=kwds)""" + self.unchanged(s) + + def test_unchanged_8(self): + s = """apply(f, args=args, kwds=kwds)""" + self.unchanged(s) + + def test_unchanged_9(self): + s = """apply(f, args, kwds=kwds)""" + self.unchanged(s) + + def test_space_1(self): + a = """apply( f, args, kwds)""" + b = """f(*args, **kwds)""" + self.check(a, b) + + def test_space_2(self): + a = """apply( f ,args,kwds )""" + b = """f(*args, **kwds)""" + self.check(a, b) + +class Test_intern(FixerTestCase): + fixer = "intern" + + def test_prefix_preservation(self): + b = """x = intern( a )""" + a = """import sys\nx = sys.intern( a )""" + self.check(b, a) + + b = """y = intern("b" # test + )""" + a = """import sys\ny = sys.intern("b" # test + )""" + self.check(b, a) + + b = """z = intern(a+b+c.d, )""" + a = """import sys\nz = sys.intern(a+b+c.d, )""" + self.check(b, a) + + def test(self): + b = """x = intern(a)""" + a = """import sys\nx = sys.intern(a)""" + self.check(b, a) + + b = """z = intern(a+b+c.d,)""" + a = """import sys\nz = sys.intern(a+b+c.d,)""" + self.check(b, a) + + b = """intern("y%s" % 5).replace("y", "")""" + a = """import sys\nsys.intern("y%s" % 5).replace("y", "")""" + self.check(b, a) + + # These should not be refactored + + def test_unchanged(self): + s = """intern(a=1)""" + self.unchanged(s) + + s = """intern(f, g)""" + self.unchanged(s) + + s = """intern(*h)""" + self.unchanged(s) + + s = """intern(**i)""" + self.unchanged(s) + + s = """intern()""" + self.unchanged(s) + +class Test_reduce(FixerTestCase): + fixer = "reduce" + + def test_simple_call(self): + b = "reduce(a, b, c)" + a = "from functools import reduce\nreduce(a, b, c)" + self.check(b, a) + + def test_call_with_lambda(self): + b = "reduce(lambda x, y: x + y, seq)" + a = "from functools import reduce\nreduce(lambda x, y: x + y, seq)" + self.check(b, a) + + def test_unchanged(self): + s = "reduce(a)" + self.unchanged(s) + + s = "reduce(a, b=42)" + self.unchanged(s) + + s = "reduce(a, b, c, d)" + self.unchanged(s) + + s = "reduce(**c)" + self.unchanged(s) + + s = "reduce()" + self.unchanged(s) + +class Test_print(FixerTestCase): + fixer = "print" + + def test_prefix_preservation(self): + b = """print 1, 1+1, 1+1+1""" + a = """print(1, 1+1, 1+1+1)""" + self.check(b, a) + + def test_idempotency(self): + s = """print()""" + self.unchanged(s) + + s = """print('')""" + self.unchanged(s) + + def test_idempotency_print_as_function(self): + print_stmt = pygram.python_grammar.keywords.pop("print") + try: + s = """print(1, 1+1, 1+1+1)""" + self.unchanged(s) + + s = """print()""" + self.unchanged(s) + + s = """print('')""" + self.unchanged(s) + finally: + pygram.python_grammar.keywords["print"] = print_stmt + + def test_1(self): + b = """print 1, 1+1, 1+1+1""" + a = """print(1, 1+1, 1+1+1)""" + self.check(b, a) + + def test_2(self): + b = """print 1, 2""" + a = """print(1, 2)""" + self.check(b, a) + + def test_3(self): + b = """print""" + a = """print()""" + self.check(b, a) + + def test_4(self): + # from bug 3000 + b = """print whatever; print""" + a = """print(whatever); print()""" + self.check(b, a) + + def test_5(self): + b = """print; print whatever;""" + a = """print(); print(whatever);""" + + def test_tuple(self): + b = """print (a, b, c)""" + a = """print((a, b, c))""" + self.check(b, a) + + # trailing commas + + def test_trailing_comma_1(self): + b = """print 1, 2, 3,""" + a = """print(1, 2, 3, end=' ')""" + self.check(b, a) + + def test_trailing_comma_2(self): + b = """print 1, 2,""" + a = """print(1, 2, end=' ')""" + self.check(b, a) + + def test_trailing_comma_3(self): + b = """print 1,""" + a = """print(1, end=' ')""" + self.check(b, a) + + # >> stuff + + def test_vargs_without_trailing_comma(self): + b = """print >>sys.stderr, 1, 2, 3""" + a = """print(1, 2, 3, file=sys.stderr)""" + self.check(b, a) + + def test_with_trailing_comma(self): + b = """print >>sys.stderr, 1, 2,""" + a = """print(1, 2, end=' ', file=sys.stderr)""" + self.check(b, a) + + def test_no_trailing_comma(self): + b = """print >>sys.stderr, 1+1""" + a = """print(1+1, file=sys.stderr)""" + self.check(b, a) + + def test_spaces_before_file(self): + b = """print >> sys.stderr""" + a = """print(file=sys.stderr)""" + self.check(b, a) + + # With from __future__ import print_function + def test_with_future_print_function(self): + # XXX: These tests won't actually do anything until the parser + # is fixed so it won't crash when it sees print(x=y). + # When #2412 is fixed, the try/except block can be taken + # out and the tests can be run like normal. + try: + s = "from __future__ import print_function\n"\ + "print('Hai!', end=' ')" + self.unchanged(s) + + b = "print 'Hello, world!'" + a = "print('Hello, world!')" + self.check(b, a) + + s = "from __future__ import *\n"\ + "print('Hai!', end=' ')" + self.unchanged(s) + except: + return + else: + self.assertFalse(True, "#2421 has been fixed -- printing tests "\ + "need to be updated!") + +class Test_exec(FixerTestCase): + fixer = "exec" + + def test_prefix_preservation(self): + b = """ exec code in ns1, ns2""" + a = """ exec(code, ns1, ns2)""" + self.check(b, a) + + def test_basic(self): + b = """exec code""" + a = """exec(code)""" + self.check(b, a) + + def test_with_globals(self): + b = """exec code in ns""" + a = """exec(code, ns)""" + self.check(b, a) + + def test_with_globals_locals(self): + b = """exec code in ns1, ns2""" + a = """exec(code, ns1, ns2)""" + self.check(b, a) + + def test_complex_1(self): + b = """exec (a.b()) in ns""" + a = """exec((a.b()), ns)""" + self.check(b, a) + + def test_complex_2(self): + b = """exec a.b() + c in ns""" + a = """exec(a.b() + c, ns)""" + self.check(b, a) + + # These should not be touched + + def test_unchanged_1(self): + s = """exec(code)""" + self.unchanged(s) + + def test_unchanged_2(self): + s = """exec (code)""" + self.unchanged(s) + + def test_unchanged_3(self): + s = """exec(code, ns)""" + self.unchanged(s) + + def test_unchanged_4(self): + s = """exec(code, ns1, ns2)""" + self.unchanged(s) + +class Test_repr(FixerTestCase): + fixer = "repr" + + def test_prefix_preservation(self): + b = """x = `1 + 2`""" + a = """x = repr(1 + 2)""" + self.check(b, a) + + def test_simple_1(self): + b = """x = `1 + 2`""" + a = """x = repr(1 + 2)""" + self.check(b, a) + + def test_simple_2(self): + b = """y = `x`""" + a = """y = repr(x)""" + self.check(b, a) + + def test_complex(self): + b = """z = `y`.__repr__()""" + a = """z = repr(y).__repr__()""" + self.check(b, a) + + def test_tuple(self): + b = """x = `1, 2, 3`""" + a = """x = repr((1, 2, 3))""" + self.check(b, a) + + def test_nested(self): + b = """x = `1 + `2``""" + a = """x = repr(1 + repr(2))""" + self.check(b, a) + + def test_nested_tuples(self): + b = """x = `1, 2 + `3, 4``""" + a = """x = repr((1, 2 + repr((3, 4))))""" + self.check(b, a) + +class Test_except(FixerTestCase): + fixer = "except" + + def test_prefix_preservation(self): + b = """ + try: + pass + except (RuntimeError, ImportError), e: + pass""" + a = """ + try: + pass + except (RuntimeError, ImportError) as e: + pass""" + self.check(b, a) + + def test_simple(self): + b = """ + try: + pass + except Foo, e: + pass""" + a = """ + try: + pass + except Foo as e: + pass""" + self.check(b, a) + + def test_simple_no_space_before_target(self): + b = """ + try: + pass + except Foo,e: + pass""" + a = """ + try: + pass + except Foo as e: + pass""" + self.check(b, a) + + def test_tuple_unpack(self): + b = """ + def foo(): + try: + pass + except Exception, (f, e): + pass + except ImportError, e: + pass""" + + a = """ + def foo(): + try: + pass + except Exception as xxx_todo_changeme: + (f, e) = xxx_todo_changeme.args + pass + except ImportError as e: + pass""" + self.check(b, a) + + def test_multi_class(self): + b = """ + try: + pass + except (RuntimeError, ImportError), e: + pass""" + + a = """ + try: + pass + except (RuntimeError, ImportError) as e: + pass""" + self.check(b, a) + + def test_list_unpack(self): + b = """ + try: + pass + except Exception, [a, b]: + pass""" + + a = """ + try: + pass + except Exception as xxx_todo_changeme: + [a, b] = xxx_todo_changeme.args + pass""" + self.check(b, a) + + def test_weird_target_1(self): + b = """ + try: + pass + except Exception, d[5]: + pass""" + + a = """ + try: + pass + except Exception as xxx_todo_changeme: + d[5] = xxx_todo_changeme + pass""" + self.check(b, a) + + def test_weird_target_2(self): + b = """ + try: + pass + except Exception, a.foo: + pass""" + + a = """ + try: + pass + except Exception as xxx_todo_changeme: + a.foo = xxx_todo_changeme + pass""" + self.check(b, a) + + def test_weird_target_3(self): + b = """ + try: + pass + except Exception, a().foo: + pass""" + + a = """ + try: + pass + except Exception as xxx_todo_changeme: + a().foo = xxx_todo_changeme + pass""" + self.check(b, a) + + def test_bare_except(self): + b = """ + try: + pass + except Exception, a: + pass + except: + pass""" + + a = """ + try: + pass + except Exception as a: + pass + except: + pass""" + self.check(b, a) + + def test_bare_except_and_else_finally(self): + b = """ + try: + pass + except Exception, a: + pass + except: + pass + else: + pass + finally: + pass""" + + a = """ + try: + pass + except Exception as a: + pass + except: + pass + else: + pass + finally: + pass""" + self.check(b, a) + + def test_multi_fixed_excepts_before_bare_except(self): + b = """ + try: + pass + except TypeError, b: + pass + except Exception, a: + pass + except: + pass""" + + a = """ + try: + pass + except TypeError as b: + pass + except Exception as a: + pass + except: + pass""" + self.check(b, a) + + # These should not be touched: + + def test_unchanged_1(self): + s = """ + try: + pass + except: + pass""" + self.unchanged(s) + + def test_unchanged_2(self): + s = """ + try: + pass + except Exception: + pass""" + self.unchanged(s) + + def test_unchanged_3(self): + s = """ + try: + pass + except (Exception, SystemExit): + pass""" + self.unchanged(s) + +class Test_raise(FixerTestCase): + fixer = "raise" + + def test_basic(self): + b = """raise Exception, 5""" + a = """raise Exception(5)""" + self.check(b, a) + + def test_prefix_preservation(self): + b = """raise Exception,5""" + a = """raise Exception(5)""" + self.check(b, a) + + b = """raise Exception, 5""" + a = """raise Exception(5)""" + self.check(b, a) + + def test_with_comments(self): + b = """raise Exception, 5 # foo""" + a = """raise Exception(5) # foo""" + self.check(b, a) + + b = """raise E, (5, 6) % (a, b) # foo""" + a = """raise E((5, 6) % (a, b)) # foo""" + self.check(b, a) + + b = """def foo(): + raise Exception, 5, 6 # foo""" + a = """def foo(): + raise Exception(5).with_traceback(6) # foo""" + self.check(b, a) + + def test_tuple_value(self): + b = """raise Exception, (5, 6, 7)""" + a = """raise Exception(5, 6, 7)""" + self.check(b, a) + + def test_tuple_detection(self): + b = """raise E, (5, 6) % (a, b)""" + a = """raise E((5, 6) % (a, b))""" + self.check(b, a) + + def test_tuple_exc_1(self): + b = """raise (((E1, E2), E3), E4), V""" + a = """raise E1(V)""" + self.check(b, a) + + def test_tuple_exc_2(self): + b = """raise (E1, (E2, E3), E4), V""" + a = """raise E1(V)""" + self.check(b, a) + + # These should produce a warning + + def test_string_exc(self): + s = """raise 'foo'""" + self.warns_unchanged(s, "Python 3 does not support string exceptions") + + def test_string_exc_val(self): + s = """raise "foo", 5""" + self.warns_unchanged(s, "Python 3 does not support string exceptions") + + def test_string_exc_val_tb(self): + s = """raise "foo", 5, 6""" + self.warns_unchanged(s, "Python 3 does not support string exceptions") + + # These should result in traceback-assignment + + def test_tb_1(self): + b = """def foo(): + raise Exception, 5, 6""" + a = """def foo(): + raise Exception(5).with_traceback(6)""" + self.check(b, a) + + def test_tb_2(self): + b = """def foo(): + a = 5 + raise Exception, 5, 6 + b = 6""" + a = """def foo(): + a = 5 + raise Exception(5).with_traceback(6) + b = 6""" + self.check(b, a) + + def test_tb_3(self): + b = """def foo(): + raise Exception,5,6""" + a = """def foo(): + raise Exception(5).with_traceback(6)""" + self.check(b, a) + + def test_tb_4(self): + b = """def foo(): + a = 5 + raise Exception,5,6 + b = 6""" + a = """def foo(): + a = 5 + raise Exception(5).with_traceback(6) + b = 6""" + self.check(b, a) + + def test_tb_5(self): + b = """def foo(): + raise Exception, (5, 6, 7), 6""" + a = """def foo(): + raise Exception(5, 6, 7).with_traceback(6)""" + self.check(b, a) + + def test_tb_6(self): + b = """def foo(): + a = 5 + raise Exception, (5, 6, 7), 6 + b = 6""" + a = """def foo(): + a = 5 + raise Exception(5, 6, 7).with_traceback(6) + b = 6""" + self.check(b, a) + +class Test_throw(FixerTestCase): + fixer = "throw" + + def test_1(self): + b = """g.throw(Exception, 5)""" + a = """g.throw(Exception(5))""" + self.check(b, a) + + def test_2(self): + b = """g.throw(Exception,5)""" + a = """g.throw(Exception(5))""" + self.check(b, a) + + def test_3(self): + b = """g.throw(Exception, (5, 6, 7))""" + a = """g.throw(Exception(5, 6, 7))""" + self.check(b, a) + + def test_4(self): + b = """5 + g.throw(Exception, 5)""" + a = """5 + g.throw(Exception(5))""" + self.check(b, a) + + # These should produce warnings + + def test_warn_1(self): + s = """g.throw("foo")""" + self.warns_unchanged(s, "Python 3 does not support string exceptions") + + def test_warn_2(self): + s = """g.throw("foo", 5)""" + self.warns_unchanged(s, "Python 3 does not support string exceptions") + + def test_warn_3(self): + s = """g.throw("foo", 5, 6)""" + self.warns_unchanged(s, "Python 3 does not support string exceptions") + + # These should not be touched + + def test_untouched_1(self): + s = """g.throw(Exception)""" + self.unchanged(s) + + def test_untouched_2(self): + s = """g.throw(Exception(5, 6))""" + self.unchanged(s) + + def test_untouched_3(self): + s = """5 + g.throw(Exception(5, 6))""" + self.unchanged(s) + + # These should result in traceback-assignment + + def test_tb_1(self): + b = """def foo(): + g.throw(Exception, 5, 6)""" + a = """def foo(): + g.throw(Exception(5).with_traceback(6))""" + self.check(b, a) + + def test_tb_2(self): + b = """def foo(): + a = 5 + g.throw(Exception, 5, 6) + b = 6""" + a = """def foo(): + a = 5 + g.throw(Exception(5).with_traceback(6)) + b = 6""" + self.check(b, a) + + def test_tb_3(self): + b = """def foo(): + g.throw(Exception,5,6)""" + a = """def foo(): + g.throw(Exception(5).with_traceback(6))""" + self.check(b, a) + + def test_tb_4(self): + b = """def foo(): + a = 5 + g.throw(Exception,5,6) + b = 6""" + a = """def foo(): + a = 5 + g.throw(Exception(5).with_traceback(6)) + b = 6""" + self.check(b, a) + + def test_tb_5(self): + b = """def foo(): + g.throw(Exception, (5, 6, 7), 6)""" + a = """def foo(): + g.throw(Exception(5, 6, 7).with_traceback(6))""" + self.check(b, a) + + def test_tb_6(self): + b = """def foo(): + a = 5 + g.throw(Exception, (5, 6, 7), 6) + b = 6""" + a = """def foo(): + a = 5 + g.throw(Exception(5, 6, 7).with_traceback(6)) + b = 6""" + self.check(b, a) + + def test_tb_7(self): + b = """def foo(): + a + g.throw(Exception, 5, 6)""" + a = """def foo(): + a + g.throw(Exception(5).with_traceback(6))""" + self.check(b, a) + + def test_tb_8(self): + b = """def foo(): + a = 5 + a + g.throw(Exception, 5, 6) + b = 6""" + a = """def foo(): + a = 5 + a + g.throw(Exception(5).with_traceback(6)) + b = 6""" + self.check(b, a) + +class Test_long(FixerTestCase): + fixer = "long" + + def test_1(self): + b = """x = long(x)""" + a = """x = int(x)""" + self.check(b, a) + + def test_2(self): + b = """y = isinstance(x, long)""" + a = """y = isinstance(x, int)""" + self.check(b, a) + + def test_3(self): + b = """z = type(x) in (int, long)""" + a = """z = type(x) in (int, int)""" + self.check(b, a) + + def test_unchanged(self): + s = """long = True""" + self.unchanged(s) + + s = """s.long = True""" + self.unchanged(s) + + s = """def long(): pass""" + self.unchanged(s) + + s = """class long(): pass""" + self.unchanged(s) + + s = """def f(long): pass""" + self.unchanged(s) + + s = """def f(g, long): pass""" + self.unchanged(s) + + s = """def f(x, long=True): pass""" + self.unchanged(s) + + def test_prefix_preservation(self): + b = """x = long( x )""" + a = """x = int( x )""" + self.check(b, a) + + +class Test_execfile(FixerTestCase): + fixer = "execfile" + + def test_conversion(self): + b = """execfile("fn")""" + a = """exec(compile(open("fn").read(), "fn", 'exec'))""" + self.check(b, a) + + b = """execfile("fn", glob)""" + a = """exec(compile(open("fn").read(), "fn", 'exec'), glob)""" + self.check(b, a) + + b = """execfile("fn", glob, loc)""" + a = """exec(compile(open("fn").read(), "fn", 'exec'), glob, loc)""" + self.check(b, a) + + b = """execfile("fn", globals=glob)""" + a = """exec(compile(open("fn").read(), "fn", 'exec'), globals=glob)""" + self.check(b, a) + + b = """execfile("fn", locals=loc)""" + a = """exec(compile(open("fn").read(), "fn", 'exec'), locals=loc)""" + self.check(b, a) + + b = """execfile("fn", globals=glob, locals=loc)""" + a = """exec(compile(open("fn").read(), "fn", 'exec'), globals=glob, locals=loc)""" + self.check(b, a) + + def test_spacing(self): + b = """execfile( "fn" )""" + a = """exec(compile(open( "fn" ).read(), "fn", 'exec'))""" + self.check(b, a) + + b = """execfile("fn", globals = glob)""" + a = """exec(compile(open("fn").read(), "fn", 'exec'), globals = glob)""" + self.check(b, a) + + +class Test_isinstance(FixerTestCase): + fixer = "isinstance" + + def test_remove_multiple_items(self): + b = """isinstance(x, (int, int, int))""" + a = """isinstance(x, int)""" + self.check(b, a) + + b = """isinstance(x, (int, float, int, int, float))""" + a = """isinstance(x, (int, float))""" + self.check(b, a) + + b = """isinstance(x, (int, float, int, int, float, str))""" + a = """isinstance(x, (int, float, str))""" + self.check(b, a) + + b = """isinstance(foo() + bar(), (x(), y(), x(), int, int))""" + a = """isinstance(foo() + bar(), (x(), y(), x(), int))""" + self.check(b, a) + + def test_prefix_preservation(self): + b = """if isinstance( foo(), ( bar, bar, baz )) : pass""" + a = """if isinstance( foo(), ( bar, baz )) : pass""" + self.check(b, a) + + def test_unchanged(self): + self.unchanged("isinstance(x, (str, int))") + +class Test_dict(FixerTestCase): + fixer = "dict" + + def test_prefix_preservation(self): + b = "if d. keys ( ) : pass" + a = "if list(d. keys ( )) : pass" + self.check(b, a) + + b = "if d. items ( ) : pass" + a = "if list(d. items ( )) : pass" + self.check(b, a) + + b = "if d. iterkeys ( ) : pass" + a = "if iter(d. keys ( )) : pass" + self.check(b, a) + + b = "[i for i in d. iterkeys( ) ]" + a = "[i for i in d. keys( ) ]" + self.check(b, a) + + def test_trailing_comment(self): + b = "d.keys() # foo" + a = "list(d.keys()) # foo" + self.check(b, a) + + b = "d.items() # foo" + a = "list(d.items()) # foo" + self.check(b, a) + + b = "d.iterkeys() # foo" + a = "iter(d.keys()) # foo" + self.check(b, a) + + b = """[i for i in d.iterkeys() # foo + ]""" + a = """[i for i in d.keys() # foo + ]""" + self.check(b, a) + + def test_unchanged(self): + for wrapper in fixer_util.consuming_calls: + s = "s = %s(d.keys())" % wrapper + self.unchanged(s) + + s = "s = %s(d.values())" % wrapper + self.unchanged(s) + + s = "s = %s(d.items())" % wrapper + self.unchanged(s) + + def test_01(self): + b = "d.keys()" + a = "list(d.keys())" + self.check(b, a) + + b = "a[0].foo().keys()" + a = "list(a[0].foo().keys())" + self.check(b, a) + + def test_02(self): + b = "d.items()" + a = "list(d.items())" + self.check(b, a) + + def test_03(self): + b = "d.values()" + a = "list(d.values())" + self.check(b, a) + + def test_04(self): + b = "d.iterkeys()" + a = "iter(d.keys())" + self.check(b, a) + + def test_05(self): + b = "d.iteritems()" + a = "iter(d.items())" + self.check(b, a) + + def test_06(self): + b = "d.itervalues()" + a = "iter(d.values())" + self.check(b, a) + + def test_07(self): + s = "list(d.keys())" + self.unchanged(s) + + def test_08(self): + s = "sorted(d.keys())" + self.unchanged(s) + + def test_09(self): + b = "iter(d.keys())" + a = "iter(list(d.keys()))" + self.check(b, a) + + def test_10(self): + b = "foo(d.keys())" + a = "foo(list(d.keys()))" + self.check(b, a) + + def test_11(self): + b = "for i in d.keys(): print i" + a = "for i in list(d.keys()): print i" + self.check(b, a) + + def test_12(self): + b = "for i in d.iterkeys(): print i" + a = "for i in d.keys(): print i" + self.check(b, a) + + def test_13(self): + b = "[i for i in d.keys()]" + a = "[i for i in list(d.keys())]" + self.check(b, a) + + def test_14(self): + b = "[i for i in d.iterkeys()]" + a = "[i for i in d.keys()]" + self.check(b, a) + + def test_15(self): + b = "(i for i in d.keys())" + a = "(i for i in list(d.keys()))" + self.check(b, a) + + def test_16(self): + b = "(i for i in d.iterkeys())" + a = "(i for i in d.keys())" + self.check(b, a) + + def test_17(self): + b = "iter(d.iterkeys())" + a = "iter(d.keys())" + self.check(b, a) + + def test_18(self): + b = "list(d.iterkeys())" + a = "list(d.keys())" + self.check(b, a) + + def test_19(self): + b = "sorted(d.iterkeys())" + a = "sorted(d.keys())" + self.check(b, a) + + def test_20(self): + b = "foo(d.iterkeys())" + a = "foo(iter(d.keys()))" + self.check(b, a) + + def test_21(self): + b = "print h.iterkeys().next()" + a = "print iter(h.keys()).next()" + self.check(b, a) + + def test_22(self): + b = "print h.keys()[0]" + a = "print list(h.keys())[0]" + self.check(b, a) + + def test_23(self): + b = "print list(h.iterkeys().next())" + a = "print list(iter(h.keys()).next())" + self.check(b, a) + + def test_24(self): + b = "for x in h.keys()[0]: print x" + a = "for x in list(h.keys())[0]: print x" + self.check(b, a) + +class Test_xrange(FixerTestCase): + fixer = "xrange" + + def test_prefix_preservation(self): + b = """x = xrange( 10 )""" + a = """x = range( 10 )""" + self.check(b, a) + + b = """x = xrange( 1 , 10 )""" + a = """x = range( 1 , 10 )""" + self.check(b, a) + + b = """x = xrange( 0 , 10 , 2 )""" + a = """x = range( 0 , 10 , 2 )""" + self.check(b, a) + + def test_single_arg(self): + b = """x = xrange(10)""" + a = """x = range(10)""" + self.check(b, a) + + def test_two_args(self): + b = """x = xrange(1, 10)""" + a = """x = range(1, 10)""" + self.check(b, a) + + def test_three_args(self): + b = """x = xrange(0, 10, 2)""" + a = """x = range(0, 10, 2)""" + self.check(b, a) + + def test_wrap_in_list(self): + b = """x = range(10, 3, 9)""" + a = """x = list(range(10, 3, 9))""" + self.check(b, a) + + b = """x = foo(range(10, 3, 9))""" + a = """x = foo(list(range(10, 3, 9)))""" + self.check(b, a) + + b = """x = range(10, 3, 9) + [4]""" + a = """x = list(range(10, 3, 9)) + [4]""" + self.check(b, a) + + b = """x = range(10)[::-1]""" + a = """x = list(range(10))[::-1]""" + self.check(b, a) + + b = """x = range(10) [3]""" + a = """x = list(range(10)) [3]""" + self.check(b, a) + + def test_xrange_in_for(self): + b = """for i in xrange(10):\n j=i""" + a = """for i in range(10):\n j=i""" + self.check(b, a) + + b = """[i for i in xrange(10)]""" + a = """[i for i in range(10)]""" + self.check(b, a) + + def test_range_in_for(self): + self.unchanged("for i in range(10): pass") + self.unchanged("[i for i in range(10)]") + + def test_in_contains_test(self): + self.unchanged("x in range(10, 3, 9)") + + def test_in_consuming_context(self): + for call in fixer_util.consuming_calls: + self.unchanged("a = %s(range(10))" % call) + +class Test_raw_input(FixerTestCase): + fixer = "raw_input" + + def test_prefix_preservation(self): + b = """x = raw_input( )""" + a = """x = input( )""" + self.check(b, a) + + b = """x = raw_input( '' )""" + a = """x = input( '' )""" + self.check(b, a) + + def test_1(self): + b = """x = raw_input()""" + a = """x = input()""" + self.check(b, a) + + def test_2(self): + b = """x = raw_input('')""" + a = """x = input('')""" + self.check(b, a) + + def test_3(self): + b = """x = raw_input('prompt')""" + a = """x = input('prompt')""" + self.check(b, a) + + def test_4(self): + b = """x = raw_input(foo(a) + 6)""" + a = """x = input(foo(a) + 6)""" + self.check(b, a) + + def test_5(self): + b = """x = raw_input(invite).split()""" + a = """x = input(invite).split()""" + self.check(b, a) + + def test_6(self): + b = """x = raw_input(invite) . split ()""" + a = """x = input(invite) . split ()""" + self.check(b, a) + + def test_8(self): + b = "x = int(raw_input())" + a = "x = int(input())" + self.check(b, a) + +class Test_funcattrs(FixerTestCase): + fixer = "funcattrs" + + attrs = ["closure", "doc", "name", "defaults", "code", "globals", "dict"] + + def test(self): + for attr in self.attrs: + b = "a.func_%s" % attr + a = "a.__%s__" % attr + self.check(b, a) + + b = "self.foo.func_%s.foo_bar" % attr + a = "self.foo.__%s__.foo_bar" % attr + self.check(b, a) + + def test_unchanged(self): + for attr in self.attrs: + s = "foo(func_%s + 5)" % attr + self.unchanged(s) + + s = "f(foo.__%s__)" % attr + self.unchanged(s) + + s = "f(foo.__%s__.foo)" % attr + self.unchanged(s) + +class Test_xreadlines(FixerTestCase): + fixer = "xreadlines" + + def test_call(self): + b = "for x in f.xreadlines(): pass" + a = "for x in f: pass" + self.check(b, a) + + b = "for x in foo().xreadlines(): pass" + a = "for x in foo(): pass" + self.check(b, a) + + b = "for x in (5 + foo()).xreadlines(): pass" + a = "for x in (5 + foo()): pass" + self.check(b, a) + + def test_attr_ref(self): + b = "foo(f.xreadlines + 5)" + a = "foo(f.__iter__ + 5)" + self.check(b, a) + + b = "foo(f().xreadlines + 5)" + a = "foo(f().__iter__ + 5)" + self.check(b, a) + + b = "foo((5 + f()).xreadlines + 5)" + a = "foo((5 + f()).__iter__ + 5)" + self.check(b, a) + + def test_unchanged(self): + s = "for x in f.xreadlines(5): pass" + self.unchanged(s) + + s = "for x in f.xreadlines(k=5): pass" + self.unchanged(s) + + s = "for x in f.xreadlines(*k, **v): pass" + self.unchanged(s) + + s = "foo(xreadlines)" + self.unchanged(s) + + +class ImportsFixerTests: + + def test_import_module(self): + for old, new in self.modules.items(): + b = "import %s" % old + a = "import %s" % new + self.check(b, a) + + b = "import foo, %s, bar" % old + a = "import foo, %s, bar" % new + self.check(b, a) + + def test_import_from(self): + for old, new in self.modules.items(): + b = "from %s import foo" % old + a = "from %s import foo" % new + self.check(b, a) + + b = "from %s import foo, bar" % old + a = "from %s import foo, bar" % new + self.check(b, a) + + b = "from %s import (yes, no)" % old + a = "from %s import (yes, no)" % new + self.check(b, a) + + def test_import_module_as(self): + for old, new in self.modules.items(): + b = "import %s as foo_bar" % old + a = "import %s as foo_bar" % new + self.check(b, a) + + b = "import %s as foo_bar" % old + a = "import %s as foo_bar" % new + self.check(b, a) + + def test_import_from_as(self): + for old, new in self.modules.items(): + b = "from %s import foo as bar" % old + a = "from %s import foo as bar" % new + self.check(b, a) + + def test_star(self): + for old, new in self.modules.items(): + b = "from %s import *" % old + a = "from %s import *" % new + self.check(b, a) + + def test_import_module_usage(self): + for old, new in self.modules.items(): + b = """ + import %s + foo(%s.bar) + """ % (old, old) + a = """ + import %s + foo(%s.bar) + """ % (new, new) + self.check(b, a) + + b = """ + from %s import x + %s = 23 + """ % (old, old) + a = """ + from %s import x + %s = 23 + """ % (new, old) + self.check(b, a) + + s = """ + def f(): + %s.method() + """ % (old,) + self.unchanged(s) + + # test nested usage + b = """ + import %s + %s.bar(%s.foo) + """ % (old, old, old) + a = """ + import %s + %s.bar(%s.foo) + """ % (new, new, new) + self.check(b, a) + + b = """ + import %s + x.%s + """ % (old, old) + a = """ + import %s + x.%s + """ % (new, old) + self.check(b, a) + + +class Test_imports(FixerTestCase, ImportsFixerTests): + fixer = "imports" + from refactor.fixes.from2.fix_imports import MAPPING as modules + + def test_multiple_imports(self): + b = """import urlparse, cStringIO""" + a = """import urllib.parse, io""" + self.check(b, a) + + def test_multiple_imports_as(self): + b = """ + import copy_reg as bar, HTMLParser as foo, urlparse + s = urlparse.spam(bar.foo()) + """ + a = """ + import copyreg as bar, html.parser as foo, urllib.parse + s = urllib.parse.spam(bar.foo()) + """ + self.check(b, a) + + +class Test_imports2(FixerTestCase, ImportsFixerTests): + fixer = "imports2" + from refactor.fixes.from2.fix_imports2 import MAPPING as modules + + +class Test_imports_fixer_order(FixerTestCase, ImportsFixerTests): + + def setUp(self): + super(Test_imports_fixer_order, self).setUp(['imports', 'imports2']) + from refactor.fixes.from2.fix_imports2 import MAPPING as mapping2 + self.modules = mapping2.copy() + from refactor.fixes.from2.fix_imports import MAPPING as mapping1 + for key in ('dbhash', 'dumbdbm', 'dbm', 'gdbm'): + self.modules[key] = mapping1[key] + + +class Test_urllib(FixerTestCase): + fixer = "urllib" + from refactor.fixes.from2.fix_urllib import MAPPING as modules + + def test_import_module(self): + for old, changes in self.modules.items(): + b = "import %s" % old + a = "import %s" % ", ".join(map(itemgetter(0), changes)) + self.check(b, a) + + def test_import_from(self): + for old, changes in self.modules.items(): + all_members = [] + for new, members in changes: + for member in members: + all_members.append(member) + b = "from %s import %s" % (old, member) + a = "from %s import %s" % (new, member) + self.check(b, a) + + s = "from foo import %s" % member + self.unchanged(s) + + b = "from %s import %s" % (old, ", ".join(members)) + a = "from %s import %s" % (new, ", ".join(members)) + self.check(b, a) + + s = "from foo import %s" % ", ".join(members) + self.unchanged(s) + + # test the breaking of a module into multiple replacements + b = "from %s import %s" % (old, ", ".join(all_members)) + a = "\n".join(["from %s import %s" % (new, ", ".join(members)) + for (new, members) in changes]) + self.check(b, a) + + def test_import_module_as(self): + for old in self.modules: + s = "import %s as foo" % old + self.warns_unchanged(s, "This module is now multiple modules") + + def test_import_from_as(self): + for old, changes in self.modules.items(): + for new, members in changes: + for member in members: + b = "from %s import %s as foo_bar" % (old, member) + a = "from %s import %s as foo_bar" % (new, member) + self.check(b, a) + + def test_star(self): + for old in self.modules: + s = "from %s import *" % old + self.warns_unchanged(s, "Cannot handle star imports") + + def test_import_module_usage(self): + for old, changes in self.modules.items(): + for new, members in changes: + for member in members: + b = """ + import %s + foo(%s.%s) + """ % (old, old, member) + a = """ + import %s + foo(%s.%s) + """ % (", ".join([n for (n, mems) + in self.modules[old]]), + new, member) + self.check(b, a) + + +class Test_input(FixerTestCase): + fixer = "input" + + def test_prefix_preservation(self): + b = """x = input( )""" + a = """x = eval(input( ))""" + self.check(b, a) + + b = """x = input( '' )""" + a = """x = eval(input( '' ))""" + self.check(b, a) + + def test_trailing_comment(self): + b = """x = input() # foo""" + a = """x = eval(input()) # foo""" + self.check(b, a) + + def test_idempotency(self): + s = """x = eval(input())""" + self.unchanged(s) + + s = """x = eval(input(''))""" + self.unchanged(s) + + s = """x = eval(input(foo(5) + 9))""" + self.unchanged(s) + + def test_1(self): + b = """x = input()""" + a = """x = eval(input())""" + self.check(b, a) + + def test_2(self): + b = """x = input('')""" + a = """x = eval(input(''))""" + self.check(b, a) + + def test_3(self): + b = """x = input('prompt')""" + a = """x = eval(input('prompt'))""" + self.check(b, a) + + def test_4(self): + b = """x = input(foo(5) + 9)""" + a = """x = eval(input(foo(5) + 9))""" + self.check(b, a) + +class Test_tuple_params(FixerTestCase): + fixer = "tuple_params" + + def test_unchanged_1(self): + s = """def foo(): pass""" + self.unchanged(s) + + def test_unchanged_2(self): + s = """def foo(a, b, c): pass""" + self.unchanged(s) + + def test_unchanged_3(self): + s = """def foo(a=3, b=4, c=5): pass""" + self.unchanged(s) + + def test_1(self): + b = """ + def foo(((a, b), c)): + x = 5""" + + a = """ + def foo(xxx_todo_changeme): + ((a, b), c) = xxx_todo_changeme + x = 5""" + self.check(b, a) + + def test_2(self): + b = """ + def foo(((a, b), c), d): + x = 5""" + + a = """ + def foo(xxx_todo_changeme, d): + ((a, b), c) = xxx_todo_changeme + x = 5""" + self.check(b, a) + + def test_3(self): + b = """ + def foo(((a, b), c), d) -> e: + x = 5""" + + a = """ + def foo(xxx_todo_changeme, d) -> e: + ((a, b), c) = xxx_todo_changeme + x = 5""" + self.check(b, a) + + def test_semicolon(self): + b = """ + def foo(((a, b), c)): x = 5; y = 7""" + + a = """ + def foo(xxx_todo_changeme): ((a, b), c) = xxx_todo_changeme; x = 5; y = 7""" + self.check(b, a) + + def test_keywords(self): + b = """ + def foo(((a, b), c), d, e=5) -> z: + x = 5""" + + a = """ + def foo(xxx_todo_changeme, d, e=5) -> z: + ((a, b), c) = xxx_todo_changeme + x = 5""" + self.check(b, a) + + def test_varargs(self): + b = """ + def foo(((a, b), c), d, *vargs, **kwargs) -> z: + x = 5""" + + a = """ + def foo(xxx_todo_changeme, d, *vargs, **kwargs) -> z: + ((a, b), c) = xxx_todo_changeme + x = 5""" + self.check(b, a) + + def test_multi_1(self): + b = """ + def foo(((a, b), c), (d, e, f)) -> z: + x = 5""" + + a = """ + def foo(xxx_todo_changeme, xxx_todo_changeme1) -> z: + ((a, b), c) = xxx_todo_changeme + (d, e, f) = xxx_todo_changeme1 + x = 5""" + self.check(b, a) + + def test_multi_2(self): + b = """ + def foo(x, ((a, b), c), d, (e, f, g), y) -> z: + x = 5""" + + a = """ + def foo(x, xxx_todo_changeme, d, xxx_todo_changeme1, y) -> z: + ((a, b), c) = xxx_todo_changeme + (e, f, g) = xxx_todo_changeme1 + x = 5""" + self.check(b, a) + + def test_docstring(self): + b = """ + def foo(((a, b), c), (d, e, f)) -> z: + "foo foo foo foo" + x = 5""" + + a = """ + def foo(xxx_todo_changeme, xxx_todo_changeme1) -> z: + "foo foo foo foo" + ((a, b), c) = xxx_todo_changeme + (d, e, f) = xxx_todo_changeme1 + x = 5""" + self.check(b, a) + + def test_lambda_no_change(self): + s = """lambda x: x + 5""" + self.unchanged(s) + + def test_lambda_parens_single_arg(self): + b = """lambda (x): x + 5""" + a = """lambda x: x + 5""" + self.check(b, a) + + b = """lambda(x): x + 5""" + a = """lambda x: x + 5""" + self.check(b, a) + + b = """lambda ((((x)))): x + 5""" + a = """lambda x: x + 5""" + self.check(b, a) + + b = """lambda((((x)))): x + 5""" + a = """lambda x: x + 5""" + self.check(b, a) + + def test_lambda_simple(self): + b = """lambda (x, y): x + f(y)""" + a = """lambda x_y: x_y[0] + f(x_y[1])""" + self.check(b, a) + + b = """lambda(x, y): x + f(y)""" + a = """lambda x_y: x_y[0] + f(x_y[1])""" + self.check(b, a) + + b = """lambda (((x, y))): x + f(y)""" + a = """lambda x_y: x_y[0] + f(x_y[1])""" + self.check(b, a) + + b = """lambda(((x, y))): x + f(y)""" + a = """lambda x_y: x_y[0] + f(x_y[1])""" + self.check(b, a) + + def test_lambda_one_tuple(self): + b = """lambda (x,): x + f(x)""" + a = """lambda x1: x1[0] + f(x1[0])""" + self.check(b, a) + + b = """lambda (((x,))): x + f(x)""" + a = """lambda x1: x1[0] + f(x1[0])""" + self.check(b, a) + + def test_lambda_simple_multi_use(self): + b = """lambda (x, y): x + x + f(x) + x""" + a = """lambda x_y: x_y[0] + x_y[0] + f(x_y[0]) + x_y[0]""" + self.check(b, a) + + def test_lambda_simple_reverse(self): + b = """lambda (x, y): y + x""" + a = """lambda x_y: x_y[1] + x_y[0]""" + self.check(b, a) + + def test_lambda_nested(self): + b = """lambda (x, (y, z)): x + y + z""" + a = """lambda x_y_z: x_y_z[0] + x_y_z[1][0] + x_y_z[1][1]""" + self.check(b, a) + + b = """lambda (((x, (y, z)))): x + y + z""" + a = """lambda x_y_z: x_y_z[0] + x_y_z[1][0] + x_y_z[1][1]""" + self.check(b, a) + + def test_lambda_nested_multi_use(self): + b = """lambda (x, (y, z)): x + y + f(y)""" + a = """lambda x_y_z: x_y_z[0] + x_y_z[1][0] + f(x_y_z[1][0])""" + self.check(b, a) + +class Test_methodattrs(FixerTestCase): + fixer = "methodattrs" + + attrs = ["func", "self", "class"] + + def test(self): + for attr in self.attrs: + b = "a.im_%s" % attr + if attr == "class": + a = "a.__self__.__class__" + else: + a = "a.__%s__" % attr + self.check(b, a) + + b = "self.foo.im_%s.foo_bar" % attr + if attr == "class": + a = "self.foo.__self__.__class__.foo_bar" + else: + a = "self.foo.__%s__.foo_bar" % attr + self.check(b, a) + + def test_unchanged(self): + for attr in self.attrs: + s = "foo(im_%s + 5)" % attr + self.unchanged(s) + + s = "f(foo.__%s__)" % attr + self.unchanged(s) + + s = "f(foo.__%s__.foo)" % attr + self.unchanged(s) + +class Test_next(FixerTestCase): + fixer = "next" + + def test_1(self): + b = """it.next()""" + a = """next(it)""" + self.check(b, a) + + def test_2(self): + b = """a.b.c.d.next()""" + a = """next(a.b.c.d)""" + self.check(b, a) + + def test_3(self): + b = """(a + b).next()""" + a = """next((a + b))""" + self.check(b, a) + + def test_4(self): + b = """a().next()""" + a = """next(a())""" + self.check(b, a) + + def test_5(self): + b = """a().next() + b""" + a = """next(a()) + b""" + self.check(b, a) + + def test_6(self): + b = """c( a().next() + b)""" + a = """c( next(a()) + b)""" + self.check(b, a) + + def test_prefix_preservation_1(self): + b = """ + for a in b: + foo(a) + a.next() + """ + a = """ + for a in b: + foo(a) + next(a) + """ + self.check(b, a) + + def test_prefix_preservation_2(self): + b = """ + for a in b: + foo(a) # abc + # def + a.next() + """ + a = """ + for a in b: + foo(a) # abc + # def + next(a) + """ + self.check(b, a) + + def test_prefix_preservation_3(self): + b = """ + next = 5 + for a in b: + foo(a) + a.next() + """ + a = """ + next = 5 + for a in b: + foo(a) + a.__next__() + """ + self.check(b, a, ignore_warnings=True) + + def test_prefix_preservation_4(self): + b = """ + next = 5 + for a in b: + foo(a) # abc + # def + a.next() + """ + a = """ + next = 5 + for a in b: + foo(a) # abc + # def + a.__next__() + """ + self.check(b, a, ignore_warnings=True) + + def test_prefix_preservation_5(self): + b = """ + next = 5 + for a in b: + foo(foo(a), # abc + a.next()) + """ + a = """ + next = 5 + for a in b: + foo(foo(a), # abc + a.__next__()) + """ + self.check(b, a, ignore_warnings=True) + + def test_prefix_preservation_6(self): + b = """ + for a in b: + foo(foo(a), # abc + a.next()) + """ + a = """ + for a in b: + foo(foo(a), # abc + next(a)) + """ + self.check(b, a) + + def test_method_1(self): + b = """ + class A: + def next(self): + pass + """ + a = """ + class A: + def __next__(self): + pass + """ + self.check(b, a) + + def test_method_2(self): + b = """ + class A(object): + def next(self): + pass + """ + a = """ + class A(object): + def __next__(self): + pass + """ + self.check(b, a) + + def test_method_3(self): + b = """ + class A: + def next(x): + pass + """ + a = """ + class A: + def __next__(x): + pass + """ + self.check(b, a) + + def test_method_4(self): + b = """ + class A: + def __init__(self, foo): + self.foo = foo + + def next(self): + pass + + def __iter__(self): + return self + """ + a = """ + class A: + def __init__(self, foo): + self.foo = foo + + def __next__(self): + pass + + def __iter__(self): + return self + """ + self.check(b, a) + + def test_method_unchanged(self): + s = """ + class A: + def next(self, a, b): + pass + """ + self.unchanged(s) + + def test_shadowing_assign_simple(self): + s = """ + next = foo + + class A: + def next(self, a, b): + pass + """ + self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") + + def test_shadowing_assign_tuple_1(self): + s = """ + (next, a) = foo + + class A: + def next(self, a, b): + pass + """ + self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") + + def test_shadowing_assign_tuple_2(self): + s = """ + (a, (b, (next, c)), a) = foo + + class A: + def next(self, a, b): + pass + """ + self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") + + def test_shadowing_assign_list_1(self): + s = """ + [next, a] = foo + + class A: + def next(self, a, b): + pass + """ + self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") + + def test_shadowing_assign_list_2(self): + s = """ + [a, [b, [next, c]], a] = foo + + class A: + def next(self, a, b): + pass + """ + self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") + + def test_builtin_assign(self): + s = """ + def foo(): + __builtin__.next = foo + + class A: + def next(self, a, b): + pass + """ + self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") + + def test_builtin_assign_in_tuple(self): + s = """ + def foo(): + (a, __builtin__.next) = foo + + class A: + def next(self, a, b): + pass + """ + self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") + + def test_builtin_assign_in_list(self): + s = """ + def foo(): + [a, __builtin__.next] = foo + + class A: + def next(self, a, b): + pass + """ + self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") + + def test_assign_to_next(self): + s = """ + def foo(): + A.next = foo + + class A: + def next(self, a, b): + pass + """ + self.unchanged(s) + + def test_assign_to_next_in_tuple(self): + s = """ + def foo(): + (a, A.next) = foo + + class A: + def next(self, a, b): + pass + """ + self.unchanged(s) + + def test_assign_to_next_in_list(self): + s = """ + def foo(): + [a, A.next] = foo + + class A: + def next(self, a, b): + pass + """ + self.unchanged(s) + + def test_shadowing_import_1(self): + s = """ + import foo.bar as next + + class A: + def next(self, a, b): + pass + """ + self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") + + def test_shadowing_import_2(self): + s = """ + import bar, bar.foo as next + + class A: + def next(self, a, b): + pass + """ + self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") + + def test_shadowing_import_3(self): + s = """ + import bar, bar.foo as next, baz + + class A: + def next(self, a, b): + pass + """ + self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") + + def test_shadowing_import_from_1(self): + s = """ + from x import next + + class A: + def next(self, a, b): + pass + """ + self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") + + def test_shadowing_import_from_2(self): + s = """ + from x.a import next + + class A: + def next(self, a, b): + pass + """ + self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") + + def test_shadowing_import_from_3(self): + s = """ + from x import a, next, b + + class A: + def next(self, a, b): + pass + """ + self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") + + def test_shadowing_import_from_4(self): + s = """ + from x.a import a, next, b + + class A: + def next(self, a, b): + pass + """ + self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") + + def test_shadowing_funcdef_1(self): + s = """ + def next(a): + pass + + class A: + def next(self, a, b): + pass + """ + self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") + + def test_shadowing_funcdef_2(self): + b = """ + def next(a): + pass + + class A: + def next(self): + pass + + it.next() + """ + a = """ + def next(a): + pass + + class A: + def __next__(self): + pass + + it.__next__() + """ + self.warns(b, a, "Calls to builtin next() possibly shadowed") + + def test_shadowing_global_1(self): + s = """ + def f(): + global next + next = 5 + """ + self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") + + def test_shadowing_global_2(self): + s = """ + def f(): + global a, next, b + next = 5 + """ + self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") + + def test_shadowing_for_simple(self): + s = """ + for next in it(): + pass + + b = 5 + c = 6 + """ + self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") + + def test_shadowing_for_tuple_1(self): + s = """ + for next, b in it(): + pass + + b = 5 + c = 6 + """ + self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") + + def test_shadowing_for_tuple_2(self): + s = """ + for a, (next, c), b in it(): + pass + + b = 5 + c = 6 + """ + self.warns_unchanged(s, "Calls to builtin next() possibly shadowed") + + def test_noncall_access_1(self): + b = """gnext = g.next""" + a = """gnext = g.__next__""" + self.check(b, a) + + def test_noncall_access_2(self): + b = """f(g.next + 5)""" + a = """f(g.__next__ + 5)""" + self.check(b, a) + + def test_noncall_access_3(self): + b = """f(g().next + 5)""" + a = """f(g().__next__ + 5)""" + self.check(b, a) + +class Test_nonzero(FixerTestCase): + fixer = "nonzero" + + def test_1(self): + b = """ + class A: + def __nonzero__(self): + pass + """ + a = """ + class A: + def __bool__(self): + pass + """ + self.check(b, a) + + def test_2(self): + b = """ + class A(object): + def __nonzero__(self): + pass + """ + a = """ + class A(object): + def __bool__(self): + pass + """ + self.check(b, a) + + def test_unchanged_1(self): + s = """ + class A(object): + def __bool__(self): + pass + """ + self.unchanged(s) + + def test_unchanged_2(self): + s = """ + class A(object): + def __nonzero__(self, a): + pass + """ + self.unchanged(s) + + def test_unchanged_func(self): + s = """ + def __nonzero__(self): + pass + """ + self.unchanged(s) + +class Test_numliterals(FixerTestCase): + fixer = "numliterals" + + def test_octal_1(self): + b = """0755""" + a = """0o755""" + self.check(b, a) + + def test_long_int_1(self): + b = """a = 12L""" + a = """a = 12""" + self.check(b, a) + + def test_long_int_2(self): + b = """a = 12l""" + a = """a = 12""" + self.check(b, a) + + def test_long_hex(self): + b = """b = 0x12l""" + a = """b = 0x12""" + self.check(b, a) + + def test_comments_and_spacing(self): + b = """b = 0x12L""" + a = """b = 0x12""" + self.check(b, a) + + b = """b = 0755 # spam""" + a = """b = 0o755 # spam""" + self.check(b, a) + + def test_unchanged_int(self): + s = """5""" + self.unchanged(s) + + def test_unchanged_float(self): + s = """5.0""" + self.unchanged(s) + + def test_unchanged_octal(self): + s = """0o755""" + self.unchanged(s) + + def test_unchanged_hex(self): + s = """0xABC""" + self.unchanged(s) + + def test_unchanged_exp(self): + s = """5.0e10""" + self.unchanged(s) + + def test_unchanged_complex_int(self): + s = """5 + 4j""" + self.unchanged(s) + + def test_unchanged_complex_float(self): + s = """5.4 + 4.9j""" + self.unchanged(s) + + def test_unchanged_complex_bare(self): + s = """4j""" + self.unchanged(s) + s = """4.4j""" + self.unchanged(s) + +class Test_renames(FixerTestCase): + fixer = "renames" + + modules = {"sys": ("maxint", "maxsize"), + } + + def test_import_from(self): + for mod, (old, new) in self.modules.items(): + b = "from %s import %s" % (mod, old) + a = "from %s import %s" % (mod, new) + self.check(b, a) + + s = "from foo import %s" % old + self.unchanged(s) + + def test_import_from_as(self): + for mod, (old, new) in self.modules.items(): + b = "from %s import %s as foo_bar" % (mod, old) + a = "from %s import %s as foo_bar" % (mod, new) + self.check(b, a) + + def test_import_module_usage(self): + for mod, (old, new) in self.modules.items(): + b = """ + import %s + foo(%s, %s.%s) + """ % (mod, mod, mod, old) + a = """ + import %s + foo(%s, %s.%s) + """ % (mod, mod, mod, new) + self.check(b, a) + + def XXX_test_from_import_usage(self): + # not implemented yet + for mod, (old, new) in self.modules.items(): + b = """ + from %s import %s + foo(%s, %s) + """ % (mod, old, mod, old) + a = """ + from %s import %s + foo(%s, %s) + """ % (mod, new, mod, new) + self.check(b, a) + +class Test_unicode(FixerTestCase): + fixer = "unicode" + + def test_unicode_call(self): + b = """unicode(x, y, z)""" + a = """str(x, y, z)""" + self.check(b, a) + + def test_unicode_literal_1(self): + b = '''u"x"''' + a = '''"x"''' + self.check(b, a) + + def test_unicode_literal_2(self): + b = """ur'x'""" + a = """r'x'""" + self.check(b, a) + + def test_unicode_literal_3(self): + b = """UR'''x'''""" + a = """R'''x'''""" + self.check(b, a) + +class Test_callable(FixerTestCase): + fixer = "callable" + + def test_prefix_preservation(self): + b = """callable( x)""" + a = """hasattr( x, '__call__')""" + self.check(b, a) + + b = """if callable(x): pass""" + a = """if hasattr(x, '__call__'): pass""" + self.check(b, a) + + def test_callable_call(self): + b = """callable(x)""" + a = """hasattr(x, '__call__')""" + self.check(b, a) + + def test_callable_should_not_change(self): + a = """callable(*x)""" + self.unchanged(a) + + a = """callable(x, y)""" + self.unchanged(a) + + a = """callable(x, kw=y)""" + self.unchanged(a) + + a = """callable()""" + self.unchanged(a) + +class Test_filter(FixerTestCase): + fixer = "filter" + + def test_prefix_preservation(self): + b = """x = filter( foo, 'abc' )""" + a = """x = list(filter( foo, 'abc' ))""" + self.check(b, a) + + b = """x = filter( None , 'abc' )""" + a = """x = [_f for _f in 'abc' if _f]""" + self.check(b, a) + + def test_filter_basic(self): + b = """x = filter(None, 'abc')""" + a = """x = [_f for _f in 'abc' if _f]""" + self.check(b, a) + + b = """x = len(filter(f, 'abc'))""" + a = """x = len(list(filter(f, 'abc')))""" + self.check(b, a) + + b = """x = filter(lambda x: x%2 == 0, range(10))""" + a = """x = [x for x in range(10) if x%2 == 0]""" + self.check(b, a) + + # Note the parens around x + b = """x = filter(lambda (x): x%2 == 0, range(10))""" + a = """x = [x for x in range(10) if x%2 == 0]""" + self.check(b, a) + + # XXX This (rare) case is not supported +## b = """x = filter(f, 'abc')[0]""" +## a = """x = list(filter(f, 'abc'))[0]""" +## self.check(b, a) + + def test_filter_nochange(self): + a = """b.join(filter(f, 'abc'))""" + self.unchanged(a) + a = """(a + foo(5)).join(filter(f, 'abc'))""" + self.unchanged(a) + a = """iter(filter(f, 'abc'))""" + self.unchanged(a) + a = """list(filter(f, 'abc'))""" + self.unchanged(a) + a = """list(filter(f, 'abc'))[0]""" + self.unchanged(a) + a = """set(filter(f, 'abc'))""" + self.unchanged(a) + a = """set(filter(f, 'abc')).pop()""" + self.unchanged(a) + a = """tuple(filter(f, 'abc'))""" + self.unchanged(a) + a = """any(filter(f, 'abc'))""" + self.unchanged(a) + a = """all(filter(f, 'abc'))""" + self.unchanged(a) + a = """sum(filter(f, 'abc'))""" + self.unchanged(a) + a = """sorted(filter(f, 'abc'))""" + self.unchanged(a) + a = """sorted(filter(f, 'abc'), key=blah)""" + self.unchanged(a) + a = """sorted(filter(f, 'abc'), key=blah)[0]""" + self.unchanged(a) + a = """for i in filter(f, 'abc'): pass""" + self.unchanged(a) + a = """[x for x in filter(f, 'abc')]""" + self.unchanged(a) + a = """(x for x in filter(f, 'abc'))""" + self.unchanged(a) + + def test_future_builtins(self): + a = "from future_builtins import spam, filter; filter(f, 'ham')" + self.unchanged(a) + + b = """from future_builtins import spam; x = filter(f, 'abc')""" + a = """from future_builtins import spam; x = list(filter(f, 'abc'))""" + self.check(b, a) + + a = "from future_builtins import *; filter(f, 'ham')" + self.unchanged(a) + +class Test_map(FixerTestCase): + fixer = "map" + + def check(self, b, a): + self.unchanged("from future_builtins import map; " + b, a) + super(Test_map, self).check(b, a) + + def test_prefix_preservation(self): + b = """x = map( f, 'abc' )""" + a = """x = list(map( f, 'abc' ))""" + self.check(b, a) + + def test_trailing_comment(self): + b = """x = map(f, 'abc') # foo""" + a = """x = list(map(f, 'abc')) # foo""" + self.check(b, a) + + def test_map_basic(self): + b = """x = map(f, 'abc')""" + a = """x = list(map(f, 'abc'))""" + self.check(b, a) + + b = """x = len(map(f, 'abc', 'def'))""" + a = """x = len(list(map(f, 'abc', 'def')))""" + self.check(b, a) + + b = """x = map(None, 'abc')""" + a = """x = list('abc')""" + self.check(b, a) + + b = """x = map(None, 'abc', 'def')""" + a = """x = list(map(None, 'abc', 'def'))""" + self.check(b, a) + + b = """x = map(lambda x: x+1, range(4))""" + a = """x = [x+1 for x in range(4)]""" + self.check(b, a) + + # Note the parens around x + b = """x = map(lambda (x): x+1, range(4))""" + a = """x = [x+1 for x in range(4)]""" + self.check(b, a) + + b = """ + foo() + # foo + map(f, x) + """ + a = """ + foo() + # foo + list(map(f, x)) + """ + self.warns(b, a, "You should use a for loop here") + + # XXX This (rare) case is not supported +## b = """x = map(f, 'abc')[0]""" +## a = """x = list(map(f, 'abc'))[0]""" +## self.check(b, a) + + def test_map_nochange(self): + a = """b.join(map(f, 'abc'))""" + self.unchanged(a) + a = """(a + foo(5)).join(map(f, 'abc'))""" + self.unchanged(a) + a = """iter(map(f, 'abc'))""" + self.unchanged(a) + a = """list(map(f, 'abc'))""" + self.unchanged(a) + a = """list(map(f, 'abc'))[0]""" + self.unchanged(a) + a = """set(map(f, 'abc'))""" + self.unchanged(a) + a = """set(map(f, 'abc')).pop()""" + self.unchanged(a) + a = """tuple(map(f, 'abc'))""" + self.unchanged(a) + a = """any(map(f, 'abc'))""" + self.unchanged(a) + a = """all(map(f, 'abc'))""" + self.unchanged(a) + a = """sum(map(f, 'abc'))""" + self.unchanged(a) + a = """sorted(map(f, 'abc'))""" + self.unchanged(a) + a = """sorted(map(f, 'abc'), key=blah)""" + self.unchanged(a) + a = """sorted(map(f, 'abc'), key=blah)[0]""" + self.unchanged(a) + a = """for i in map(f, 'abc'): pass""" + self.unchanged(a) + a = """[x for x in map(f, 'abc')]""" + self.unchanged(a) + a = """(x for x in map(f, 'abc'))""" + self.unchanged(a) + + def test_future_builtins(self): + a = "from future_builtins import spam, map, eggs; map(f, 'ham')" + self.unchanged(a) + + b = """from future_builtins import spam, eggs; x = map(f, 'abc')""" + a = """from future_builtins import spam, eggs; x = list(map(f, 'abc'))""" + self.check(b, a) + + a = "from future_builtins import *; map(f, 'ham')" + self.unchanged(a) + +class Test_zip(FixerTestCase): + fixer = "zip" + + def check(self, b, a): + self.unchanged("from future_builtins import zip; " + b, a) + super(Test_zip, self).check(b, a) + + def test_zip_basic(self): + b = """x = zip(a, b, c)""" + a = """x = list(zip(a, b, c))""" + self.check(b, a) + + b = """x = len(zip(a, b))""" + a = """x = len(list(zip(a, b)))""" + self.check(b, a) + + def test_zip_nochange(self): + a = """b.join(zip(a, b))""" + self.unchanged(a) + a = """(a + foo(5)).join(zip(a, b))""" + self.unchanged(a) + a = """iter(zip(a, b))""" + self.unchanged(a) + a = """list(zip(a, b))""" + self.unchanged(a) + a = """list(zip(a, b))[0]""" + self.unchanged(a) + a = """set(zip(a, b))""" + self.unchanged(a) + a = """set(zip(a, b)).pop()""" + self.unchanged(a) + a = """tuple(zip(a, b))""" + self.unchanged(a) + a = """any(zip(a, b))""" + self.unchanged(a) + a = """all(zip(a, b))""" + self.unchanged(a) + a = """sum(zip(a, b))""" + self.unchanged(a) + a = """sorted(zip(a, b))""" + self.unchanged(a) + a = """sorted(zip(a, b), key=blah)""" + self.unchanged(a) + a = """sorted(zip(a, b), key=blah)[0]""" + self.unchanged(a) + a = """for i in zip(a, b): pass""" + self.unchanged(a) + a = """[x for x in zip(a, b)]""" + self.unchanged(a) + a = """(x for x in zip(a, b))""" + self.unchanged(a) + + def test_future_builtins(self): + a = "from future_builtins import spam, zip, eggs; zip(a, b)" + self.unchanged(a) + + b = """from future_builtins import spam, eggs; x = zip(a, b)""" + a = """from future_builtins import spam, eggs; x = list(zip(a, b))""" + self.check(b, a) + + a = "from future_builtins import *; zip(a, b)" + self.unchanged(a) + +class Test_standarderror(FixerTestCase): + fixer = "standarderror" + + def test(self): + b = """x = StandardError()""" + a = """x = Exception()""" + self.check(b, a) + + b = """x = StandardError(a, b, c)""" + a = """x = Exception(a, b, c)""" + self.check(b, a) + + b = """f(2 + StandardError(a, b, c))""" + a = """f(2 + Exception(a, b, c))""" + self.check(b, a) + +class Test_types(FixerTestCase): + fixer = "types" + + def test_basic_types_convert(self): + b = """types.StringType""" + a = """bytes""" + self.check(b, a) + + b = """types.DictType""" + a = """dict""" + self.check(b, a) + + b = """types . IntType""" + a = """int""" + self.check(b, a) + + b = """types.ListType""" + a = """list""" + self.check(b, a) + + b = """types.LongType""" + a = """int""" + self.check(b, a) + + b = """types.NoneType""" + a = """type(None)""" + self.check(b, a) + +class Test_idioms(FixerTestCase): + fixer = "idioms" + + def test_while(self): + b = """while 1: foo()""" + a = """while True: foo()""" + self.check(b, a) + + b = """while 1: foo()""" + a = """while True: foo()""" + self.check(b, a) + + b = """ + while 1: + foo() + """ + a = """ + while True: + foo() + """ + self.check(b, a) + + def test_while_unchanged(self): + s = """while 11: foo()""" + self.unchanged(s) + + s = """while 0: foo()""" + self.unchanged(s) + + s = """while foo(): foo()""" + self.unchanged(s) + + s = """while []: foo()""" + self.unchanged(s) + + def test_eq_simple(self): + b = """type(x) == T""" + a = """isinstance(x, T)""" + self.check(b, a) + + b = """if type(x) == T: pass""" + a = """if isinstance(x, T): pass""" + self.check(b, a) + + def test_eq_reverse(self): + b = """T == type(x)""" + a = """isinstance(x, T)""" + self.check(b, a) + + b = """if T == type(x): pass""" + a = """if isinstance(x, T): pass""" + self.check(b, a) + + def test_eq_expression(self): + b = """type(x+y) == d.get('T')""" + a = """isinstance(x+y, d.get('T'))""" + self.check(b, a) + + b = """type( x + y) == d.get('T')""" + a = """isinstance(x + y, d.get('T'))""" + self.check(b, a) + + def test_is_simple(self): + b = """type(x) is T""" + a = """isinstance(x, T)""" + self.check(b, a) + + b = """if type(x) is T: pass""" + a = """if isinstance(x, T): pass""" + self.check(b, a) + + def test_is_reverse(self): + b = """T is type(x)""" + a = """isinstance(x, T)""" + self.check(b, a) + + b = """if T is type(x): pass""" + a = """if isinstance(x, T): pass""" + self.check(b, a) + + def test_is_expression(self): + b = """type(x+y) is d.get('T')""" + a = """isinstance(x+y, d.get('T'))""" + self.check(b, a) + + b = """type( x + y) is d.get('T')""" + a = """isinstance(x + y, d.get('T'))""" + self.check(b, a) + + def test_is_not_simple(self): + b = """type(x) is not T""" + a = """not isinstance(x, T)""" + self.check(b, a) + + b = """if type(x) is not T: pass""" + a = """if not isinstance(x, T): pass""" + self.check(b, a) + + def test_is_not_reverse(self): + b = """T is not type(x)""" + a = """not isinstance(x, T)""" + self.check(b, a) + + b = """if T is not type(x): pass""" + a = """if not isinstance(x, T): pass""" + self.check(b, a) + + def test_is_not_expression(self): + b = """type(x+y) is not d.get('T')""" + a = """not isinstance(x+y, d.get('T'))""" + self.check(b, a) + + b = """type( x + y) is not d.get('T')""" + a = """not isinstance(x + y, d.get('T'))""" + self.check(b, a) + + def test_ne_simple(self): + b = """type(x) != T""" + a = """not isinstance(x, T)""" + self.check(b, a) + + b = """if type(x) != T: pass""" + a = """if not isinstance(x, T): pass""" + self.check(b, a) + + def test_ne_reverse(self): + b = """T != type(x)""" + a = """not isinstance(x, T)""" + self.check(b, a) + + b = """if T != type(x): pass""" + a = """if not isinstance(x, T): pass""" + self.check(b, a) + + def test_ne_expression(self): + b = """type(x+y) != d.get('T')""" + a = """not isinstance(x+y, d.get('T'))""" + self.check(b, a) + + b = """type( x + y) != d.get('T')""" + a = """not isinstance(x + y, d.get('T'))""" + self.check(b, a) + + def test_type_unchanged(self): + a = """type(x).__name__""" + self.unchanged(a) + + def test_sort_list_call(self): + b = """ + v = list(t) + v.sort() + foo(v) + """ + a = """ + v = sorted(t) + foo(v) + """ + self.check(b, a) + + b = """ + v = list(foo(b) + d) + v.sort() + foo(v) + """ + a = """ + v = sorted(foo(b) + d) + foo(v) + """ + self.check(b, a) + + b = """ + while x: + v = list(t) + v.sort() + foo(v) + """ + a = """ + while x: + v = sorted(t) + foo(v) + """ + self.check(b, a) + + b = """ + v = list(t) + # foo + v.sort() + foo(v) + """ + a = """ + v = sorted(t) + # foo + foo(v) + """ + self.check(b, a) + + b = r""" + v = list( t) + v.sort() + foo(v) + """ + a = r""" + v = sorted( t) + foo(v) + """ + self.check(b, a) + + def test_sort_simple_expr(self): + b = """ + v = t + v.sort() + foo(v) + """ + a = """ + v = sorted(t) + foo(v) + """ + self.check(b, a) + + b = """ + v = foo(b) + v.sort() + foo(v) + """ + a = """ + v = sorted(foo(b)) + foo(v) + """ + self.check(b, a) + + b = """ + v = b.keys() + v.sort() + foo(v) + """ + a = """ + v = sorted(b.keys()) + foo(v) + """ + self.check(b, a) + + b = """ + v = foo(b) + d + v.sort() + foo(v) + """ + a = """ + v = sorted(foo(b) + d) + foo(v) + """ + self.check(b, a) + + b = """ + while x: + v = t + v.sort() + foo(v) + """ + a = """ + while x: + v = sorted(t) + foo(v) + """ + self.check(b, a) + + b = """ + v = t + # foo + v.sort() + foo(v) + """ + a = """ + v = sorted(t) + # foo + foo(v) + """ + self.check(b, a) + + b = r""" + v = t + v.sort() + foo(v) + """ + a = r""" + v = sorted(t) + foo(v) + """ + self.check(b, a) + + def test_sort_unchanged(self): + s = """ + v = list(t) + w.sort() + foo(w) + """ + self.unchanged(s) + + s = """ + v = list(t) + v.sort(u) + foo(v) + """ + self.unchanged(s) + +class Test_basestring(FixerTestCase): + fixer = "basestring" + + def test_basestring(self): + b = """isinstance(x, basestring)""" + a = """isinstance(x, str)""" + self.check(b, a) + +class Test_buffer(FixerTestCase): + fixer = "buffer" + + def test_buffer(self): + b = """x = buffer(y)""" + a = """x = memoryview(y)""" + self.check(b, a) + +class Test_future(FixerTestCase): + fixer = "future" + + def test_future(self): + b = """from __future__ import braces""" + a = """""" + self.check(b, a) + + b = """# comment\nfrom __future__ import braces""" + a = """# comment\n""" + self.check(b, a) + + b = """from __future__ import braces\n# comment""" + a = """\n# comment""" + self.check(b, a) + + def test_run_order(self): + self.assert_runs_after('print') + +class Test_itertools(FixerTestCase): + fixer = "itertools" + + def checkall(self, before, after): + # Because we need to check with and without the itertools prefix + # and on each of the three functions, these loops make it all + # much easier + for i in ('itertools.', ''): + for f in ('map', 'filter', 'zip'): + b = before %(i+'i'+f) + a = after %(f) + self.check(b, a) + + def test_0(self): + # A simple example -- test_1 covers exactly the same thing, + # but it's not quite as clear. + b = "itertools.izip(a, b)" + a = "zip(a, b)" + self.check(b, a) + + def test_1(self): + b = """%s(f, a)""" + a = """%s(f, a)""" + self.checkall(b, a) + + def test_2(self): + b = """itertools.ifilterfalse(a, b)""" + a = """itertools.filterfalse(a, b)""" + self.check(b, a) + + def test_4(self): + b = """ifilterfalse(a, b)""" + a = """filterfalse(a, b)""" + self.check(b, a) + + def test_space_1(self): + b = """ %s(f, a)""" + a = """ %s(f, a)""" + self.checkall(b, a) + + def test_space_2(self): + b = """ itertools.ifilterfalse(a, b)""" + a = """ itertools.filterfalse(a, b)""" + self.check(b, a) + + def test_run_order(self): + self.assert_runs_after('map', 'zip', 'filter') + +class Test_itertools_imports(FixerTestCase): + fixer = 'itertools_imports' + + def test_reduced(self): + b = "from itertools import imap, izip, foo" + a = "from itertools import foo" + self.check(b, a) + + b = "from itertools import bar, imap, izip, foo" + a = "from itertools import bar, foo" + self.check(b, a) + + def test_comments(self): + b = "#foo\nfrom itertools import imap, izip" + a = "#foo\n" + self.check(b, a) + + def test_none(self): + b = "from itertools import imap, izip" + a = "" + self.check(b, a) + + b = "from itertools import izip" + a = "" + self.check(b, a) + + def test_import_as(self): + b = "from itertools import izip, bar as bang, imap" + a = "from itertools import bar as bang" + self.check(b, a) + + b = "from itertools import izip as _zip, imap, bar" + a = "from itertools import bar" + self.check(b, a) + + b = "from itertools import imap as _map" + a = "" + self.check(b, a) + + b = "from itertools import imap as _map, izip as _zip" + a = "" + self.check(b, a) + + s = "from itertools import bar as bang" + self.unchanged(s) + + def test_ifilter(self): + b = "from itertools import ifilterfalse" + a = "from itertools import filterfalse" + self.check(b, a) + + b = "from itertools import imap, ifilterfalse, foo" + a = "from itertools import filterfalse, foo" + self.check(b, a) + + b = "from itertools import bar, ifilterfalse, foo" + a = "from itertools import bar, filterfalse, foo" + self.check(b, a) + + + def test_unchanged(self): + s = "from itertools import foo" + self.unchanged(s) + +class Test_import(FixerTestCase): + fixer = "import" + + def setUp(self): + super(Test_import, self).setUp() + # Need to replace fix_import's exists method + # so we can check that it's doing the right thing + self.files_checked = [] + self.present_files = set() + self.always_exists = True + def fake_exists(name): + self.files_checked.append(name) + return self.always_exists or (name in self.present_files) + + from refactor.fixes.from2 import fix_import + fix_import.exists = fake_exists + + def tearDown(self): + from lib2to3.fixes import fix_import + fix_import.exists = os.path.exists + + def check_both(self, b, a): + self.always_exists = True + super(Test_import, self).check(b, a) + self.always_exists = False + super(Test_import, self).unchanged(b) + + def test_files_checked(self): + def p(path): + # Takes a unix path and returns a path with correct separators + return os.path.pathsep.join(path.split("/")) + + self.always_exists = False + self.present_files = set(['__init__.py']) + expected_extensions = ('.py', os.path.pathsep, '.pyc', '.so', + '.sl', '.pyd') + names_to_test = (p("/spam/eggs.py"), "ni.py", p("../../shrubbery.py")) + + for name in names_to_test: + self.files_checked = [] + self.filename = name + self.unchanged("import jam") + + if os.path.dirname(name): + name = os.path.dirname(name) + '/jam' + else: + name = 'jam' + expected_checks = set(name + ext for ext in expected_extensions) + expected_checks.add("__init__.py") + + self.assertEqual(set(self.files_checked), expected_checks) + + def test_not_in_package(self): + s = "import bar" + self.always_exists = False + self.present_files = set(["bar.py"]) + self.unchanged(s) + + def test_in_package(self): + b = "import bar" + a = "from . import bar" + self.always_exists = False + self.present_files = set(["__init__.py", "bar.py"]) + self.check(b, a) + + def test_comments_and_indent(self): + b = "import bar # Foo" + a = "from . import bar # Foo" + self.check(b, a) + + def test_from(self): + b = "from foo import bar, baz" + a = "from .foo import bar, baz" + self.check_both(b, a) + + b = "from foo import bar" + a = "from .foo import bar" + self.check_both(b, a) + + b = "from foo import (bar, baz)" + a = "from .foo import (bar, baz)" + self.check_both(b, a) + + def test_dotted_from(self): + b = "from green.eggs import ham" + a = "from .green.eggs import ham" + self.check_both(b, a) + + def test_from_as(self): + b = "from green.eggs import ham as spam" + a = "from .green.eggs import ham as spam" + self.check_both(b, a) + + def test_import(self): + b = "import foo" + a = "from . import foo" + self.check_both(b, a) + + b = "import foo, bar" + a = "from . import foo, bar" + self.check_both(b, a) + + b = "import foo, bar, x" + a = "from . import foo, bar, x" + self.check_both(b, a) + + b = "import x, y, z" + a = "from . import x, y, z" + self.check_both(b, a) + + def test_import_as(self): + b = "import foo as x" + a = "from . import foo as x" + self.check_both(b, a) + + b = "import a as b, b as c, c as d" + a = "from . import a as b, b as c, c as d" + self.check_both(b, a) + + def test_local_and_absolute(self): + self.always_exists = False + self.present_files = set(["foo.py", "__init__.py"]) + + s = "import foo, bar" + self.warns_unchanged(s, "absolute and local imports together") + + def test_dotted_import(self): + b = "import foo.bar" + a = "from . import foo.bar" + self.check_both(b, a) + + def test_dotted_import_as(self): + b = "import foo.bar as bang" + a = "from . import foo.bar as bang" + self.check_both(b, a) + + def test_prefix(self): + b = """ + # prefix + import foo.bar + """ + a = """ + # prefix + from . import foo.bar + """ + self.check_both(b, a) + + +class Test_set_literal(FixerTestCase): + + fixer = "set_literal" + + def test_basic(self): + b = """set([1, 2, 3])""" + a = """{1, 2, 3}""" + self.check(b, a) + + b = """set((1, 2, 3))""" + a = """{1, 2, 3}""" + self.check(b, a) + + b = """set((1,))""" + a = """{1}""" + self.check(b, a) + + b = """set([1])""" + self.check(b, a) + + b = """set((a, b))""" + a = """{a, b}""" + self.check(b, a) + + b = """set([a, b])""" + self.check(b, a) + + b = """set((a*234, f(args=23)))""" + a = """{a*234, f(args=23)}""" + self.check(b, a) + + b = """set([a*23, f(23)])""" + a = """{a*23, f(23)}""" + self.check(b, a) + + b = """set([a-234**23])""" + a = """{a-234**23}""" + self.check(b, a) + + def test_listcomps(self): + b = """set([x for x in y])""" + a = """{x for x in y}""" + self.check(b, a) + + b = """set([x for x in y if x == m])""" + a = """{x for x in y if x == m}""" + self.check(b, a) + + b = """set([x for x in y for a in b])""" + a = """{x for x in y for a in b}""" + self.check(b, a) + + b = """set([f(x) - 23 for x in y])""" + a = """{f(x) - 23 for x in y}""" + self.check(b, a) + + def test_whitespace(self): + b = """set( [1, 2])""" + a = """{1, 2}""" + self.check(b, a) + + b = """set([1 , 2])""" + a = """{1 , 2}""" + self.check(b, a) + + b = """set([ 1 ])""" + a = """{ 1 }""" + self.check(b, a) + + b = """set( [1] )""" + a = """{1}""" + self.check(b, a) + + b = """set([ 1, 2 ])""" + a = """{ 1, 2 }""" + self.check(b, a) + + b = """set([x for x in y ])""" + a = """{x for x in y }""" + self.check(b, a) + + b = """set( + [1, 2] + ) + """ + a = """{1, 2}\n""" + self.check(b, a) + + def test_comments(self): + b = """set((1, 2)) # Hi""" + a = """{1, 2} # Hi""" + self.check(b, a) + + # This isn't optimal behavior, but the fixer is optional. + b = """ + # Foo + set( # Bar + (1, 2) + ) + """ + a = """ + # Foo + {1, 2} + """ + self.check(b, a) + + def test_unchanged(self): + s = """set()""" + self.unchanged(s) + + s = """set(a)""" + self.unchanged(s) + + s = """set(a, b, c)""" + self.unchanged(s) + + # Don't transform generators because they might have to be lazy. + s = """set(x for x in y)""" + self.unchanged(s) + + s = """set(x for x in y if z)""" + self.unchanged(s) + + s = """set(a*823-23**2 + f(23))""" + self.unchanged(s) + + +class Test_sys_exc(FixerTestCase): + fixer = "sys_exc" + + def test_0(self): + b = "sys.exc_type" + a = "sys.exc_info()[0]" + self.check(b, a) + + def test_1(self): + b = "sys.exc_value" + a = "sys.exc_info()[1]" + self.check(b, a) + + def test_2(self): + b = "sys.exc_traceback" + a = "sys.exc_info()[2]" + self.check(b, a) + + def test_3(self): + b = "sys.exc_type # Foo" + a = "sys.exc_info()[0] # Foo" + self.check(b, a) + + def test_4(self): + b = "sys. exc_type" + a = "sys. exc_info()[0]" + self.check(b, a) + + def test_5(self): + b = "sys .exc_type" + a = "sys .exc_info()[0]" + self.check(b, a) + + +class Test_paren(FixerTestCase): + fixer = "paren" + + def test_0(self): + b = """[i for i in 1, 2 ]""" + a = """[i for i in (1, 2) ]""" + self.check(b, a) + + def test_1(self): + b = """[i for i in 1, 2, ]""" + a = """[i for i in (1, 2,) ]""" + self.check(b, a) + + def test_2(self): + b = """[i for i in 1, 2 ]""" + a = """[i for i in (1, 2) ]""" + self.check(b, a) + + def test_3(self): + b = """[i for i in 1, 2 if i]""" + a = """[i for i in (1, 2) if i]""" + self.check(b, a) + + def test_4(self): + b = """[i for i in 1, 2 ]""" + a = """[i for i in (1, 2) ]""" + self.check(b, a) + + def test_5(self): + b = """(i for i in 1, 2)""" + a = """(i for i in (1, 2))""" + self.check(b, a) + + def test_6(self): + b = """(i for i in 1 ,2 if i)""" + a = """(i for i in (1 ,2) if i)""" + self.check(b, a) + + def test_unchanged_0(self): + s = """[i for i in (1, 2)]""" + self.unchanged(s) + + def test_unchanged_1(self): + s = """[i for i in foo()]""" + self.unchanged(s) + + def test_unchanged_2(self): + s = """[i for i in (1, 2) if nothing]""" + self.unchanged(s) + + def test_unchanged_3(self): + s = """(i for i in (1, 2))""" + self.unchanged(s) + + def test_unchanged_4(self): + s = """[i for i in m]""" + self.unchanged(s) + +class Test_metaclass(FixerTestCase): + + fixer = 'metaclass' + + def test_unchanged(self): + self.unchanged("class X(): pass") + self.unchanged("class X(object): pass") + self.unchanged("class X(object1, object2): pass") + self.unchanged("class X(object1, object2, object3): pass") + self.unchanged("class X(metaclass=Meta): pass") + self.unchanged("class X(b, arg=23, metclass=Meta): pass") + self.unchanged("class X(b, arg=23, metaclass=Meta, other=42): pass") + + s = """ + class X: + def __metaclass__(self): pass + """ + self.unchanged(s) + + s = """ + class X: + a[23] = 74 + """ + self.unchanged(s) + + def test_comments(self): + b = """ + class X: + # hi + __metaclass__ = AppleMeta + """ + a = """ + class X(metaclass=AppleMeta): + # hi + pass + """ + self.check(b, a) + + b = """ + class X: + __metaclass__ = Meta + # Bedtime! + """ + a = """ + class X(metaclass=Meta): + pass + # Bedtime! + """ + self.check(b, a) + + def test_meta(self): + # no-parent class, odd body + b = """ + class X(): + __metaclass__ = Q + pass + """ + a = """ + class X(metaclass=Q): + pass + """ + self.check(b, a) + + # one parent class, no body + b = """class X(object): __metaclass__ = Q""" + a = """class X(object, metaclass=Q): pass""" + self.check(b, a) + + + # one parent, simple body + b = """ + class X(object): + __metaclass__ = Meta + bar = 7 + """ + a = """ + class X(object, metaclass=Meta): + bar = 7 + """ + self.check(b, a) + + b = """ + class X: + __metaclass__ = Meta; x = 4; g = 23 + """ + a = """ + class X(metaclass=Meta): + x = 4; g = 23 + """ + self.check(b, a) + + # one parent, simple body, __metaclass__ last + b = """ + class X(object): + bar = 7 + __metaclass__ = Meta + """ + a = """ + class X(object, metaclass=Meta): + bar = 7 + """ + self.check(b, a) + + # redefining __metaclass__ + b = """ + class X(): + __metaclass__ = A + __metaclass__ = B + bar = 7 + """ + a = """ + class X(metaclass=B): + bar = 7 + """ + self.check(b, a) + + # multiple inheritance, simple body + b = """ + class X(clsA, clsB): + __metaclass__ = Meta + bar = 7 + """ + a = """ + class X(clsA, clsB, metaclass=Meta): + bar = 7 + """ + self.check(b, a) + + # keywords in the class statement + b = """class m(a, arg=23): __metaclass__ = Meta""" + a = """class m(a, arg=23, metaclass=Meta): pass""" + self.check(b, a) + + b = """ + class X(expression(2 + 4)): + __metaclass__ = Meta + """ + a = """ + class X(expression(2 + 4), metaclass=Meta): + pass + """ + self.check(b, a) + + b = """ + class X(expression(2 + 4), x**4): + __metaclass__ = Meta + """ + a = """ + class X(expression(2 + 4), x**4, metaclass=Meta): + pass + """ + self.check(b, a) + + b = """ + class X: + __metaclass__ = Meta + save.py = 23 + """ + a = """ + class X(metaclass=Meta): + save.py = 23 + """ + self.check(b, a) + + +class Test_getcwdu(FixerTestCase): + + fixer = 'getcwdu' + + def test_basic(self): + b = """os.getcwdu""" + a = """os.getcwd""" + self.check(b, a) + + b = """os.getcwdu()""" + a = """os.getcwd()""" + self.check(b, a) + + b = """meth = os.getcwdu""" + a = """meth = os.getcwd""" + self.check(b, a) + + b = """os.getcwdu(args)""" + a = """os.getcwd(args)""" + self.check(b, a) + + def test_comment(self): + b = """os.getcwdu() # Foo""" + a = """os.getcwd() # Foo""" + self.check(b, a) + + def test_unchanged(self): + s = """os.getcwd()""" + self.unchanged(s) + + s = """getcwdu()""" + self.unchanged(s) + + s = """os.getcwdb()""" + self.unchanged(s) + + def test_indentation(self): + b = """ + if 1: + os.getcwdu() + """ + a = """ + if 1: + os.getcwd() + """ + self.check(b, a) + + def test_multilation(self): + b = """os .getcwdu()""" + a = """os .getcwd()""" + self.check(b, a) + + b = """os. getcwdu""" + a = """os. getcwd""" + self.check(b, a) + + b = """os.getcwdu ( )""" + a = """os.getcwd ( )""" + self.check(b, a) + + +if __name__ == "__main__": + import __main__ + support.run_all_tests(__main__) Added: sandbox/trunk/refactor_pkg/lib2to3/tests/test_parser.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/tests/test_parser.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,202 @@ +#!/usr/bin/env python2.5 +"""Test suite for 2to3's parser and grammar files. + +This is the place to add tests for changes to 2to3's grammar, such as those +merging the grammars for Python 2 and 3. In addition to specific tests for +parts of the grammar we've changed, we also make sure we can parse the +test_grammar.py files from both Python 2 and Python 3. +""" +# Author: Collin Winter + +# Testing imports +from . import support +from .support import driver, test_dir + +# Python imports +import os +import os.path + +# Local imports +from refactor.pgen2.parse import ParseError + + +class GrammarTest(support.TestCase): + def validate(self, code): + support.parse_string(code) + + def invalid_syntax(self, code): + try: + self.validate(code) + except ParseError: + pass + else: + raise AssertionError("Syntax shouldn't have been valid") + + +class TestRaiseChanges(GrammarTest): + def test_2x_style_1(self): + self.validate("raise") + + def test_2x_style_2(self): + self.validate("raise E, V") + + def test_2x_style_3(self): + self.validate("raise E, V, T") + + def test_2x_style_invalid_1(self): + self.invalid_syntax("raise E, V, T, Z") + + def test_3x_style(self): + self.validate("raise E1 from E2") + + def test_3x_style_invalid_1(self): + self.invalid_syntax("raise E, V from E1") + + def test_3x_style_invalid_2(self): + self.invalid_syntax("raise E from E1, E2") + + def test_3x_style_invalid_3(self): + self.invalid_syntax("raise from E1, E2") + + def test_3x_style_invalid_4(self): + self.invalid_syntax("raise E from") + + +# Adapated from Python 3's Lib/test/test_grammar.py:GrammarTests.testFuncdef +class TestFunctionAnnotations(GrammarTest): + def test_1(self): + self.validate("""def f(x) -> list: pass""") + + def test_2(self): + self.validate("""def f(x:int): pass""") + + def test_3(self): + self.validate("""def f(*x:str): pass""") + + def test_4(self): + self.validate("""def f(**x:float): pass""") + + def test_5(self): + self.validate("""def f(x, y:1+2): pass""") + + def test_6(self): + self.validate("""def f(a, (b:1, c:2, d)): pass""") + + def test_7(self): + self.validate("""def f(a, (b:1, c:2, d), e:3=4, f=5, *g:6): pass""") + + def test_8(self): + s = """def f(a, (b:1, c:2, d), e:3=4, f=5, + *g:6, h:7, i=8, j:9=10, **k:11) -> 12: pass""" + self.validate(s) + + +class TestExcept(GrammarTest): + def test_new(self): + s = """ + try: + x + except E as N: + y""" + self.validate(s) + + def test_old(self): + s = """ + try: + x + except E, N: + y""" + self.validate(s) + + +# Adapted from Python 3's Lib/test/test_grammar.py:GrammarTests.testAtoms +class TestSetLiteral(GrammarTest): + def test_1(self): + self.validate("""x = {'one'}""") + + def test_2(self): + self.validate("""x = {'one', 1,}""") + + def test_3(self): + self.validate("""x = {'one', 'two', 'three'}""") + + def test_4(self): + self.validate("""x = {2, 3, 4,}""") + + +class TestNumericLiterals(GrammarTest): + def test_new_octal_notation(self): + self.validate("""0o7777777777777""") + self.invalid_syntax("""0o7324528887""") + + def test_new_binary_notation(self): + self.validate("""0b101010""") + self.invalid_syntax("""0b0101021""") + + +class TestClassDef(GrammarTest): + def test_new_syntax(self): + self.validate("class B(t=7): pass") + self.validate("class B(t, *args): pass") + self.validate("class B(t, **kwargs): pass") + self.validate("class B(t, *args, **kwargs): pass") + self.validate("class B(t, y=9, *args, **kwargs): pass") + + +class TestParserIdempotency(support.TestCase): + + """A cut-down version of pytree_idempotency.py.""" + + def test_all_project_files(self): + for filepath in support.all_project_files(): + print "Parsing %s..." % filepath + tree = driver.parse_file(filepath, debug=True) + if diff(filepath, tree): + self.fail("Idempotency failed: %s" % filepath) + + +class TestLiterals(GrammarTest): + + def test_multiline_bytes_literals(self): + s = """ + md5test(b"\xaa" * 80, + (b"Test Using Larger Than Block-Size Key " + b"and Larger Than One Block-Size Data"), + "6f630fad67cda0ee1fb1f562db3aa53e") + """ + self.validate(s) + + def test_multiline_bytes_tripquote_literals(self): + s = ''' + b""" + + + """ + ''' + self.validate(s) + + def test_multiline_str_literals(self): + s = """ + md5test("\xaa" * 80, + ("Test Using Larger Than Block-Size Key " + "and Larger Than One Block-Size Data"), + "6f630fad67cda0ee1fb1f562db3aa53e") + """ + self.validate(s) + + +def diff(fn, tree): + f = open("@", "w") + try: + f.write(str(tree)) + finally: + f.close() + try: + return os.system("diff -u %s @" % fn) + finally: + os.remove("@") + + +if __name__ == "__main__": + import __main__ + support.run_all_tests(__main__) Added: sandbox/trunk/refactor_pkg/lib2to3/tests/test_pytree.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/tests/test_pytree.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,458 @@ +#!/usr/bin/env python2.5 +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Unit tests for pytree.py. + +NOTE: Please *don't* add doc strings to individual test methods! +In verbose mode, printing of the module, class and method name is much +more helpful than printing of (the first line of) the docstring, +especially when debugging a test. +""" + +# Testing imports +from . import support + +# Local imports (XXX should become a package) +from .. import pytree + +try: + sorted +except NameError: + def sorted(lst): + l = list(lst) + l.sort() + return l + +class TestNodes(support.TestCase): + + """Unit tests for nodes (Base, Leaf, Node).""" + + def testBaseCantConstruct(self): + if __debug__: + # Test that instantiating Base() raises an AssertionError + self.assertRaises(AssertionError, pytree.Base) + + def testLeaf(self): + l1 = pytree.Leaf(100, "foo") + self.assertEqual(l1.type, 100) + self.assertEqual(l1.value, "foo") + + def testLeafRepr(self): + l1 = pytree.Leaf(100, "foo") + self.assertEqual(repr(l1), "Leaf(100, 'foo')") + + def testLeafStr(self): + l1 = pytree.Leaf(100, "foo") + self.assertEqual(str(l1), "foo") + l2 = pytree.Leaf(100, "foo", context=(" ", (10, 1))) + self.assertEqual(str(l2), " foo") + + def testLeafStrNumericValue(self): + # Make sure that the Leaf's value is stringified. Failing to + # do this can cause a TypeError in certain situations. + l1 = pytree.Leaf(2, 5) + l1.set_prefix("foo_") + self.assertEqual(str(l1), "foo_5") + + def testLeafEq(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "foo", context=(" ", (1, 0))) + self.assertEqual(l1, l2) + l3 = pytree.Leaf(101, "foo") + l4 = pytree.Leaf(100, "bar") + self.assertNotEqual(l1, l3) + self.assertNotEqual(l1, l4) + + def testLeafPrefix(self): + l1 = pytree.Leaf(100, "foo") + self.assertEqual(l1.get_prefix(), "") + self.failIf(l1.was_changed) + l1.set_prefix(" ##\n\n") + self.assertEqual(l1.get_prefix(), " ##\n\n") + self.failUnless(l1.was_changed) + + def testNode(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(200, "bar") + n1 = pytree.Node(1000, [l1, l2]) + self.assertEqual(n1.type, 1000) + self.assertEqual(n1.children, [l1, l2]) + + def testNodeRepr(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "bar", context=(" ", (1, 0))) + n1 = pytree.Node(1000, [l1, l2]) + self.assertEqual(repr(n1), + "Node(1000, [%s, %s])" % (repr(l1), repr(l2))) + + def testNodeStr(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "bar", context=(" ", (1, 0))) + n1 = pytree.Node(1000, [l1, l2]) + self.assertEqual(str(n1), "foo bar") + + def testNodePrefix(self): + l1 = pytree.Leaf(100, "foo") + self.assertEqual(l1.get_prefix(), "") + n1 = pytree.Node(1000, [l1]) + self.assertEqual(n1.get_prefix(), "") + n1.set_prefix(" ") + self.assertEqual(n1.get_prefix(), " ") + self.assertEqual(l1.get_prefix(), " ") + + def testGetSuffix(self): + l1 = pytree.Leaf(100, "foo", prefix="a") + l2 = pytree.Leaf(100, "bar", prefix="b") + n1 = pytree.Node(1000, [l1, l2]) + + self.assertEqual(l1.get_suffix(), l2.get_prefix()) + self.assertEqual(l2.get_suffix(), "") + self.assertEqual(n1.get_suffix(), "") + + l3 = pytree.Leaf(100, "bar", prefix="c") + n2 = pytree.Node(1000, [n1, l3]) + + self.assertEqual(n1.get_suffix(), l3.get_prefix()) + self.assertEqual(l3.get_suffix(), "") + self.assertEqual(n2.get_suffix(), "") + + def testNodeEq(self): + n1 = pytree.Node(1000, ()) + n2 = pytree.Node(1000, [], context=(" ", (1, 0))) + self.assertEqual(n1, n2) + n3 = pytree.Node(1001, ()) + self.assertNotEqual(n1, n3) + + def testNodeEqRecursive(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "foo") + n1 = pytree.Node(1000, [l1]) + n2 = pytree.Node(1000, [l2]) + self.assertEqual(n1, n2) + l3 = pytree.Leaf(100, "bar") + n3 = pytree.Node(1000, [l3]) + self.assertNotEqual(n1, n3) + + def testReplace(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "+") + l3 = pytree.Leaf(100, "bar") + n1 = pytree.Node(1000, [l1, l2, l3]) + self.assertEqual(n1.children, [l1, l2, l3]) + self.failUnless(isinstance(n1.children, list)) + self.failIf(n1.was_changed) + l2new = pytree.Leaf(100, "-") + l2.replace(l2new) + self.assertEqual(n1.children, [l1, l2new, l3]) + self.failUnless(isinstance(n1.children, list)) + self.failUnless(n1.was_changed) + + def testReplaceWithList(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "+") + l3 = pytree.Leaf(100, "bar") + n1 = pytree.Node(1000, [l1, l2, l3]) + + l2.replace([pytree.Leaf(100, "*"), pytree.Leaf(100, "*")]) + self.assertEqual(str(n1), "foo**bar") + self.failUnless(isinstance(n1.children, list)) + + def testPostOrder(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "bar") + n1 = pytree.Node(1000, [l1, l2]) + self.assertEqual(list(n1.post_order()), [l1, l2, n1]) + + def testPreOrder(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "bar") + n1 = pytree.Node(1000, [l1, l2]) + self.assertEqual(list(n1.pre_order()), [n1, l1, l2]) + + def testChangedLeaf(self): + l1 = pytree.Leaf(100, "f") + self.failIf(l1.was_changed) + + l1.changed() + self.failUnless(l1.was_changed) + + def testChangedNode(self): + l1 = pytree.Leaf(100, "f") + n1 = pytree.Node(1000, [l1]) + self.failIf(n1.was_changed) + + n1.changed() + self.failUnless(n1.was_changed) + + def testChangedRecursive(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "+") + l3 = pytree.Leaf(100, "bar") + n1 = pytree.Node(1000, [l1, l2, l3]) + n2 = pytree.Node(1000, [n1]) + self.failIf(l1.was_changed) + self.failIf(n1.was_changed) + self.failIf(n2.was_changed) + + n1.changed() + self.failUnless(n1.was_changed) + self.failUnless(n2.was_changed) + self.failIf(l1.was_changed) + + def testLeafConstructorPrefix(self): + for prefix in ("xyz_", ""): + l1 = pytree.Leaf(100, "self", prefix=prefix) + self.failUnless(str(l1), prefix + "self") + self.assertEqual(l1.get_prefix(), prefix) + + def testNodeConstructorPrefix(self): + for prefix in ("xyz_", ""): + l1 = pytree.Leaf(100, "self") + l2 = pytree.Leaf(100, "foo", prefix="_") + n1 = pytree.Node(1000, [l1, l2], prefix=prefix) + self.failUnless(str(n1), prefix + "self_foo") + self.assertEqual(n1.get_prefix(), prefix) + self.assertEqual(l1.get_prefix(), prefix) + self.assertEqual(l2.get_prefix(), "_") + + def testRemove(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "foo") + n1 = pytree.Node(1000, [l1, l2]) + n2 = pytree.Node(1000, [n1]) + + self.assertEqual(n1.remove(), 0) + self.assertEqual(n2.children, []) + self.assertEqual(l1.parent, n1) + self.assertEqual(n1.parent, None) + self.assertEqual(n2.parent, None) + self.failIf(n1.was_changed) + self.failUnless(n2.was_changed) + + self.assertEqual(l2.remove(), 1) + self.assertEqual(l1.remove(), 0) + self.assertEqual(n1.children, []) + self.assertEqual(l1.parent, None) + self.assertEqual(n1.parent, None) + self.assertEqual(n2.parent, None) + self.failUnless(n1.was_changed) + self.failUnless(n2.was_changed) + + def testRemoveParentless(self): + n1 = pytree.Node(1000, []) + n1.remove() + self.assertEqual(n1.parent, None) + + l1 = pytree.Leaf(100, "foo") + l1.remove() + self.assertEqual(l1.parent, None) + + def testNodeSetChild(self): + l1 = pytree.Leaf(100, "foo") + n1 = pytree.Node(1000, [l1]) + + l2 = pytree.Leaf(100, "bar") + n1.set_child(0, l2) + self.assertEqual(l1.parent, None) + self.assertEqual(l2.parent, n1) + self.assertEqual(n1.children, [l2]) + + n2 = pytree.Node(1000, [l1]) + n2.set_child(0, n1) + self.assertEqual(l1.parent, None) + self.assertEqual(n1.parent, n2) + self.assertEqual(n2.parent, None) + self.assertEqual(n2.children, [n1]) + + self.assertRaises(IndexError, n1.set_child, 4, l2) + # I don't care what it raises, so long as it's an exception + self.assertRaises(Exception, n1.set_child, 0, list) + + def testNodeInsertChild(self): + l1 = pytree.Leaf(100, "foo") + n1 = pytree.Node(1000, [l1]) + + l2 = pytree.Leaf(100, "bar") + n1.insert_child(0, l2) + self.assertEqual(l2.parent, n1) + self.assertEqual(n1.children, [l2, l1]) + + l3 = pytree.Leaf(100, "abc") + n1.insert_child(2, l3) + self.assertEqual(n1.children, [l2, l1, l3]) + + # I don't care what it raises, so long as it's an exception + self.assertRaises(Exception, n1.insert_child, 0, list) + + def testNodeAppendChild(self): + n1 = pytree.Node(1000, []) + + l1 = pytree.Leaf(100, "foo") + n1.append_child(l1) + self.assertEqual(l1.parent, n1) + self.assertEqual(n1.children, [l1]) + + l2 = pytree.Leaf(100, "bar") + n1.append_child(l2) + self.assertEqual(l2.parent, n1) + self.assertEqual(n1.children, [l1, l2]) + + # I don't care what it raises, so long as it's an exception + self.assertRaises(Exception, n1.append_child, list) + + def testNodeNextSibling(self): + n1 = pytree.Node(1000, []) + n2 = pytree.Node(1000, []) + p1 = pytree.Node(1000, [n1, n2]) + + self.failUnless(n1.next_sibling is n2) + self.assertEqual(n2.next_sibling, None) + self.assertEqual(p1.next_sibling, None) + + def testLeafNextSibling(self): + l1 = pytree.Leaf(100, "a") + l2 = pytree.Leaf(100, "b") + p1 = pytree.Node(1000, [l1, l2]) + + self.failUnless(l1.next_sibling is l2) + self.assertEqual(l2.next_sibling, None) + self.assertEqual(p1.next_sibling, None) + + def testNodePrevSibling(self): + n1 = pytree.Node(1000, []) + n2 = pytree.Node(1000, []) + p1 = pytree.Node(1000, [n1, n2]) + + self.failUnless(n2.prev_sibling is n1) + self.assertEqual(n1.prev_sibling, None) + self.assertEqual(p1.prev_sibling, None) + + def testLeafPrevSibling(self): + l1 = pytree.Leaf(100, "a") + l2 = pytree.Leaf(100, "b") + p1 = pytree.Node(1000, [l1, l2]) + + self.failUnless(l2.prev_sibling is l1) + self.assertEqual(l1.prev_sibling, None) + self.assertEqual(p1.prev_sibling, None) + + +class TestPatterns(support.TestCase): + + """Unit tests for tree matching patterns.""" + + def testBasicPatterns(self): + # Build a tree + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "bar") + l3 = pytree.Leaf(100, "foo") + n1 = pytree.Node(1000, [l1, l2]) + n2 = pytree.Node(1000, [l3]) + root = pytree.Node(1000, [n1, n2]) + # Build a pattern matching a leaf + pl = pytree.LeafPattern(100, "foo", name="pl") + r = {} + self.assertFalse(pl.match(root, results=r)) + self.assertEqual(r, {}) + self.assertFalse(pl.match(n1, results=r)) + self.assertEqual(r, {}) + self.assertFalse(pl.match(n2, results=r)) + self.assertEqual(r, {}) + self.assertTrue(pl.match(l1, results=r)) + self.assertEqual(r, {"pl": l1}) + r = {} + self.assertFalse(pl.match(l2, results=r)) + self.assertEqual(r, {}) + # Build a pattern matching a node + pn = pytree.NodePattern(1000, [pl], name="pn") + self.assertFalse(pn.match(root, results=r)) + self.assertEqual(r, {}) + self.assertFalse(pn.match(n1, results=r)) + self.assertEqual(r, {}) + self.assertTrue(pn.match(n2, results=r)) + self.assertEqual(r, {"pn": n2, "pl": l3}) + r = {} + self.assertFalse(pn.match(l1, results=r)) + self.assertEqual(r, {}) + self.assertFalse(pn.match(l2, results=r)) + self.assertEqual(r, {}) + + def testWildcardPatterns(self): + # Build a tree for testing + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "bar") + l3 = pytree.Leaf(100, "foo") + n1 = pytree.Node(1000, [l1, l2]) + n2 = pytree.Node(1000, [l3]) + root = pytree.Node(1000, [n1, n2]) + # Build a pattern + pl = pytree.LeafPattern(100, "foo", name="pl") + pn = pytree.NodePattern(1000, [pl], name="pn") + pw = pytree.WildcardPattern([[pn], [pl, pl]], name="pw") + r = {} + self.assertFalse(pw.match_seq([root], r)) + self.assertEqual(r, {}) + self.assertFalse(pw.match_seq([n1], r)) + self.assertEqual(r, {}) + self.assertTrue(pw.match_seq([n2], r)) + # These are easier to debug + self.assertEqual(sorted(r.keys()), ["pl", "pn", "pw"]) + self.assertEqual(r["pl"], l1) + self.assertEqual(r["pn"], n2) + self.assertEqual(r["pw"], [n2]) + # But this is equivalent + self.assertEqual(r, {"pl": l1, "pn": n2, "pw": [n2]}) + r = {} + self.assertTrue(pw.match_seq([l1, l3], r)) + self.assertEqual(r, {"pl": l3, "pw": [l1, l3]}) + self.assert_(r["pl"] is l3) + r = {} + + def testGenerateMatches(self): + la = pytree.Leaf(1, "a") + lb = pytree.Leaf(1, "b") + lc = pytree.Leaf(1, "c") + ld = pytree.Leaf(1, "d") + le = pytree.Leaf(1, "e") + lf = pytree.Leaf(1, "f") + leaves = [la, lb, lc, ld, le, lf] + root = pytree.Node(1000, leaves) + pa = pytree.LeafPattern(1, "a", "pa") + pb = pytree.LeafPattern(1, "b", "pb") + pc = pytree.LeafPattern(1, "c", "pc") + pd = pytree.LeafPattern(1, "d", "pd") + pe = pytree.LeafPattern(1, "e", "pe") + pf = pytree.LeafPattern(1, "f", "pf") + pw = pytree.WildcardPattern([[pa, pb, pc], [pd, pe], + [pa, pb], [pc, pd], [pe, pf]], + min=1, max=4, name="pw") + self.assertEqual([x[0] for x in pw.generate_matches(leaves)], + [3, 5, 2, 4, 6]) + pr = pytree.NodePattern(type=1000, content=[pw], name="pr") + matches = list(pytree.generate_matches([pr], [root])) + self.assertEqual(len(matches), 1) + c, r = matches[0] + self.assertEqual(c, 1) + self.assertEqual(str(r["pr"]), "abcdef") + self.assertEqual(r["pw"], [la, lb, lc, ld, le, lf]) + for c in "abcdef": + self.assertEqual(r["p" + c], pytree.Leaf(1, c)) + + def testHasKeyExample(self): + pattern = pytree.NodePattern(331, + (pytree.LeafPattern(7), + pytree.WildcardPattern(name="args"), + pytree.LeafPattern(8))) + l1 = pytree.Leaf(7, "(") + l2 = pytree.Leaf(3, "x") + l3 = pytree.Leaf(8, ")") + node = pytree.Node(331, [l1, l2, l3]) + r = {} + self.assert_(pattern.match(node, r)) + self.assertEqual(r["args"], [l2]) + + +if __name__ == "__main__": + import __main__ + support.run_all_tests(__main__) Added: sandbox/trunk/refactor_pkg/lib2to3/tests/test_refactor.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/tests/test_refactor.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,168 @@ +""" +Unit tests for refactor.py. +""" + +import sys +import os +import operator +import StringIO +import tempfile +import unittest + +from lib2to3 import refactor, pygram, fixer_base + +from . import support + + +FIXER_DIR = os.path.join(os.path.dirname(__file__), "data/fixers") + +sys.path.append(FIXER_DIR) +try: + _DEFAULT_FIXERS = refactor.get_fixers_from_package("myfixes") +finally: + sys.path.pop() + +class TestRefactoringTool(unittest.TestCase): + + def setUp(self): + sys.path.append(FIXER_DIR) + + def tearDown(self): + sys.path.pop() + + def check_instances(self, instances, classes): + for inst, cls in zip(instances, classes): + if not isinstance(inst, cls): + self.fail("%s are not instances of %s" % instances, classes) + + def rt(self, options=None, fixers=_DEFAULT_FIXERS, explicit=None): + return refactor.RefactoringTool(fixers, options, explicit) + + def test_print_function_option(self): + gram = pygram.python_grammar + save = gram.keywords["print"] + try: + rt = self.rt({"print_function" : True}) + self.assertRaises(KeyError, operator.itemgetter("print"), + gram.keywords) + finally: + gram.keywords["print"] = save + + def test_fixer_loading_helpers(self): + contents = ["explicit", "first", "last", "parrot", "preorder"] + non_prefixed = refactor.get_all_fix_names("myfixes") + prefixed = refactor.get_all_fix_names("myfixes", False) + full_names = refactor.get_fixers_from_package("myfixes") + self.assertEqual(prefixed, ["fix_" + name for name in contents]) + self.assertEqual(non_prefixed, contents) + self.assertEqual(full_names, + ["myfixes.fix_" + name for name in contents]) + + def test_get_headnode_dict(self): + class NoneFix(fixer_base.BaseFix): + PATTERN = None + + class FileInputFix(fixer_base.BaseFix): + PATTERN = "file_input< any * >" + + no_head = NoneFix({}, []) + with_head = FileInputFix({}, []) + d = refactor.get_headnode_dict([no_head, with_head]) + expected = {None: [no_head], + pygram.python_symbols.file_input : [with_head]} + self.assertEqual(d, expected) + + def test_fixer_loading(self): + from myfixes.fix_first import FixFirst + from myfixes.fix_last import FixLast + from myfixes.fix_parrot import FixParrot + from myfixes.fix_preorder import FixPreorder + + rt = self.rt() + pre, post = rt.get_fixers() + + self.check_instances(pre, [FixPreorder]) + self.check_instances(post, [FixFirst, FixParrot, FixLast]) + + def test_naughty_fixers(self): + self.assertRaises(ImportError, self.rt, fixers=["not_here"]) + self.assertRaises(refactor.FixerError, self.rt, fixers=["no_fixer_cls"]) + self.assertRaises(refactor.FixerError, self.rt, fixers=["bad_order"]) + + def test_refactor_string(self): + rt = self.rt() + input = "def parrot(): pass\n\n" + tree = rt.refactor_string(input, "") + self.assertNotEqual(str(tree), input) + + input = "def f(): pass\n\n" + tree = rt.refactor_string(input, "") + self.assertEqual(str(tree), input) + + def test_refactor_stdin(self): + + class MyRT(refactor.RefactoringTool): + + def print_output(self, lines): + diff_lines.extend(lines) + + diff_lines = [] + rt = MyRT(_DEFAULT_FIXERS) + save = sys.stdin + sys.stdin = StringIO.StringIO("def parrot(): pass\n\n") + try: + rt.refactor_stdin() + finally: + sys.stdin = save + expected = """--- (original) ++++ (refactored) +@@ -1,2 +1,2 @@ +-def parrot(): pass ++def cheese(): pass""".splitlines() + self.assertEqual(diff_lines[:-1], expected) + + def test_refactor_file(self): + test_file = os.path.join(FIXER_DIR, "parrot_example.py") + old_contents = open(test_file, "r").read() + rt = self.rt() + + rt.refactor_file(test_file) + self.assertEqual(old_contents, open(test_file, "r").read()) + + rt.refactor_file(test_file, True) + try: + self.assertNotEqual(old_contents, open(test_file, "r").read()) + finally: + open(test_file, "w").write(old_contents) + + def test_refactor_docstring(self): + rt = self.rt() + + def example(): + """ + >>> example() + 42 + """ + out = rt.refactor_docstring(example.__doc__, "") + self.assertEqual(out, example.__doc__) + + def parrot(): + """ + >>> def parrot(): + ... return 43 + """ + out = rt.refactor_docstring(parrot.__doc__, "") + self.assertNotEqual(out, parrot.__doc__) + + def test_explicit(self): + from myfixes.fix_explicit import FixExplicit + + rt = self.rt(fixers=["myfixes.fix_explicit"]) + self.assertEqual(len(rt.post_order), 0) + + rt = self.rt(explicit=["myfixes.fix_explicit"]) + for fix in rt.post_order: + if isinstance(fix, FixExplicit): + break + else: + self.fail("explicit fixer not loaded") Added: sandbox/trunk/refactor_pkg/lib2to3/tests/test_util.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/lib2to3/tests/test_util.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,559 @@ +#!/usr/bin/env python2.5 +""" Test suite for the code in fixes.util """ +# Author: Collin Winter + +# Testing imports +from . import support + +# Python imports +import os.path + +# Local imports +from .. import pytree +from .. import fixer_util +from refactor.fixer_util import Attr, Name + + +def parse(code, strip_levels=0): + # The topmost node is file_input, which we don't care about. + # The next-topmost node is a *_stmt node, which we also don't care about + tree = support.parse_string(code) + for i in range(strip_levels): + tree = tree.children[0] + tree.parent = None + return tree + +class MacroTestCase(support.TestCase): + def assertStr(self, node, string): + if isinstance(node, (tuple, list)): + node = pytree.Node(fixer_util.syms.simple_stmt, node) + self.assertEqual(str(node), string) + + +class Test_is_tuple(support.TestCase): + def is_tuple(self, string): + return fixer_util.is_tuple(parse(string, strip_levels=2)) + + def test_valid(self): + self.failUnless(self.is_tuple("(a, b)")) + self.failUnless(self.is_tuple("(a, (b, c))")) + self.failUnless(self.is_tuple("((a, (b, c)),)")) + self.failUnless(self.is_tuple("(a,)")) + self.failUnless(self.is_tuple("()")) + + def test_invalid(self): + self.failIf(self.is_tuple("(a)")) + self.failIf(self.is_tuple("('foo') % (b, c)")) + + +class Test_is_list(support.TestCase): + def is_list(self, string): + return fixer_util.is_list(parse(string, strip_levels=2)) + + def test_valid(self): + self.failUnless(self.is_list("[]")) + self.failUnless(self.is_list("[a]")) + self.failUnless(self.is_list("[a, b]")) + self.failUnless(self.is_list("[a, [b, c]]")) + self.failUnless(self.is_list("[[a, [b, c]],]")) + + def test_invalid(self): + self.failIf(self.is_list("[]+[]")) + + +class Test_Attr(MacroTestCase): + def test(self): + call = parse("foo()", strip_levels=2) + + self.assertStr(Attr(Name("a"), Name("b")), "a.b") + self.assertStr(Attr(call, Name("b")), "foo().b") + + def test_returns(self): + attr = Attr(Name("a"), Name("b")) + self.assertEqual(type(attr), list) + + +class Test_Name(MacroTestCase): + def test(self): + self.assertStr(Name("a"), "a") + self.assertStr(Name("foo.foo().bar"), "foo.foo().bar") + self.assertStr(Name("a", prefix="b"), "ba") + + +class Test_does_tree_import(support.TestCase): + def _find_bind_rec(self, name, node): + # Search a tree for a binding -- used to find the starting + # point for these tests. + c = fixer_util.find_binding(name, node) + if c: return c + for child in node.children: + c = self._find_bind_rec(name, child) + if c: return c + + def does_tree_import(self, package, name, string): + node = parse(string) + # Find the binding of start -- that's what we'll go from + node = self._find_bind_rec('start', node) + return fixer_util.does_tree_import(package, name, node) + + def try_with(self, string): + failing_tests = (("a", "a", "from a import b"), + ("a.d", "a", "from a.d import b"), + ("d.a", "a", "from d.a import b"), + (None, "a", "import b"), + (None, "a", "import b, c, d")) + for package, name, import_ in failing_tests: + n = self.does_tree_import(package, name, import_ + "\n" + string) + self.failIf(n) + n = self.does_tree_import(package, name, string + "\n" + import_) + self.failIf(n) + + passing_tests = (("a", "a", "from a import a"), + ("x", "a", "from x import a"), + ("x", "a", "from x import b, c, a, d"), + ("x.b", "a", "from x.b import a"), + ("x.b", "a", "from x.b import b, c, a, d"), + (None, "a", "import a"), + (None, "a", "import b, c, a, d")) + for package, name, import_ in passing_tests: + n = self.does_tree_import(package, name, import_ + "\n" + string) + self.failUnless(n) + n = self.does_tree_import(package, name, string + "\n" + import_) + self.failUnless(n) + + def test_in_function(self): + self.try_with("def foo():\n\tbar.baz()\n\tstart=3") + +class Test_find_binding(support.TestCase): + def find_binding(self, name, string, package=None): + return fixer_util.find_binding(name, parse(string), package) + + def test_simple_assignment(self): + self.failUnless(self.find_binding("a", "a = b")) + self.failUnless(self.find_binding("a", "a = [b, c, d]")) + self.failUnless(self.find_binding("a", "a = foo()")) + self.failUnless(self.find_binding("a", "a = foo().foo.foo[6][foo]")) + self.failIf(self.find_binding("a", "foo = a")) + self.failIf(self.find_binding("a", "foo = (a, b, c)")) + + def test_tuple_assignment(self): + self.failUnless(self.find_binding("a", "(a,) = b")) + self.failUnless(self.find_binding("a", "(a, b, c) = [b, c, d]")) + self.failUnless(self.find_binding("a", "(c, (d, a), b) = foo()")) + self.failUnless(self.find_binding("a", "(a, b) = foo().foo[6][foo]")) + self.failIf(self.find_binding("a", "(foo, b) = (b, a)")) + self.failIf(self.find_binding("a", "(foo, (b, c)) = (a, b, c)")) + + def test_list_assignment(self): + self.failUnless(self.find_binding("a", "[a] = b")) + self.failUnless(self.find_binding("a", "[a, b, c] = [b, c, d]")) + self.failUnless(self.find_binding("a", "[c, [d, a], b] = foo()")) + self.failUnless(self.find_binding("a", "[a, b] = foo().foo[a][foo]")) + self.failIf(self.find_binding("a", "[foo, b] = (b, a)")) + self.failIf(self.find_binding("a", "[foo, [b, c]] = (a, b, c)")) + + def test_invalid_assignments(self): + self.failIf(self.find_binding("a", "foo.a = 5")) + self.failIf(self.find_binding("a", "foo[a] = 5")) + self.failIf(self.find_binding("a", "foo(a) = 5")) + self.failIf(self.find_binding("a", "foo(a, b) = 5")) + + def test_simple_import(self): + self.failUnless(self.find_binding("a", "import a")) + self.failUnless(self.find_binding("a", "import b, c, a, d")) + self.failIf(self.find_binding("a", "import b")) + self.failIf(self.find_binding("a", "import b, c, d")) + + def test_from_import(self): + self.failUnless(self.find_binding("a", "from x import a")) + self.failUnless(self.find_binding("a", "from a import a")) + self.failUnless(self.find_binding("a", "from x import b, c, a, d")) + self.failUnless(self.find_binding("a", "from x.b import a")) + self.failUnless(self.find_binding("a", "from x.b import b, c, a, d")) + self.failIf(self.find_binding("a", "from a import b")) + self.failIf(self.find_binding("a", "from a.d import b")) + self.failIf(self.find_binding("a", "from d.a import b")) + + def test_import_as(self): + self.failUnless(self.find_binding("a", "import b as a")) + self.failUnless(self.find_binding("a", "import b as a, c, a as f, d")) + self.failIf(self.find_binding("a", "import a as f")) + self.failIf(self.find_binding("a", "import b, c as f, d as e")) + + def test_from_import_as(self): + self.failUnless(self.find_binding("a", "from x import b as a")) + self.failUnless(self.find_binding("a", "from x import g as a, d as b")) + self.failUnless(self.find_binding("a", "from x.b import t as a")) + self.failUnless(self.find_binding("a", "from x.b import g as a, d")) + self.failIf(self.find_binding("a", "from a import b as t")) + self.failIf(self.find_binding("a", "from a.d import b as t")) + self.failIf(self.find_binding("a", "from d.a import b as t")) + + def test_simple_import_with_package(self): + self.failUnless(self.find_binding("b", "import b")) + self.failUnless(self.find_binding("b", "import b, c, d")) + self.failIf(self.find_binding("b", "import b", "b")) + self.failIf(self.find_binding("b", "import b, c, d", "c")) + + def test_from_import_with_package(self): + self.failUnless(self.find_binding("a", "from x import a", "x")) + self.failUnless(self.find_binding("a", "from a import a", "a")) + self.failUnless(self.find_binding("a", "from x import *", "x")) + self.failUnless(self.find_binding("a", "from x import b, c, a, d", "x")) + self.failUnless(self.find_binding("a", "from x.b import a", "x.b")) + self.failUnless(self.find_binding("a", "from x.b import *", "x.b")) + self.failUnless(self.find_binding("a", "from x.b import b, c, a, d", "x.b")) + self.failIf(self.find_binding("a", "from a import b", "a")) + self.failIf(self.find_binding("a", "from a.d import b", "a.d")) + self.failIf(self.find_binding("a", "from d.a import b", "a.d")) + self.failIf(self.find_binding("a", "from x.y import *", "a.b")) + + def test_import_as_with_package(self): + self.failIf(self.find_binding("a", "import b.c as a", "b.c")) + self.failIf(self.find_binding("a", "import a as f", "f")) + self.failIf(self.find_binding("a", "import a as f", "a")) + + def test_from_import_as_with_package(self): + # Because it would take a lot of special-case code in the fixers + # to deal with from foo import bar as baz, we'll simply always + # fail if there is an "from ... import ... as ..." + self.failIf(self.find_binding("a", "from x import b as a", "x")) + self.failIf(self.find_binding("a", "from x import g as a, d as b", "x")) + self.failIf(self.find_binding("a", "from x.b import t as a", "x.b")) + self.failIf(self.find_binding("a", "from x.b import g as a, d", "x.b")) + self.failIf(self.find_binding("a", "from a import b as t", "a")) + self.failIf(self.find_binding("a", "from a import b as t", "b")) + self.failIf(self.find_binding("a", "from a import b as t", "t")) + + def test_function_def(self): + self.failUnless(self.find_binding("a", "def a(): pass")) + self.failUnless(self.find_binding("a", "def a(b, c, d): pass")) + self.failUnless(self.find_binding("a", "def a(): b = 7")) + self.failIf(self.find_binding("a", "def d(b, (c, a), e): pass")) + self.failIf(self.find_binding("a", "def d(a=7): pass")) + self.failIf(self.find_binding("a", "def d(a): pass")) + self.failIf(self.find_binding("a", "def d(): a = 7")) + + s = """ + def d(): + def a(): + pass""" + self.failIf(self.find_binding("a", s)) + + def test_class_def(self): + self.failUnless(self.find_binding("a", "class a: pass")) + self.failUnless(self.find_binding("a", "class a(): pass")) + self.failUnless(self.find_binding("a", "class a(b): pass")) + self.failUnless(self.find_binding("a", "class a(b, c=8): pass")) + self.failIf(self.find_binding("a", "class d: pass")) + self.failIf(self.find_binding("a", "class d(a): pass")) + self.failIf(self.find_binding("a", "class d(b, a=7): pass")) + self.failIf(self.find_binding("a", "class d(b, *a): pass")) + self.failIf(self.find_binding("a", "class d(b, **a): pass")) + self.failIf(self.find_binding("a", "class d: a = 7")) + + s = """ + class d(): + class a(): + pass""" + self.failIf(self.find_binding("a", s)) + + def test_for(self): + self.failUnless(self.find_binding("a", "for a in r: pass")) + self.failUnless(self.find_binding("a", "for a, b in r: pass")) + self.failUnless(self.find_binding("a", "for (a, b) in r: pass")) + self.failUnless(self.find_binding("a", "for c, (a,) in r: pass")) + self.failUnless(self.find_binding("a", "for c, (a, b) in r: pass")) + self.failUnless(self.find_binding("a", "for c in r: a = c")) + self.failIf(self.find_binding("a", "for c in a: pass")) + + def test_for_nested(self): + s = """ + for b in r: + for a in b: + pass""" + self.failUnless(self.find_binding("a", s)) + + s = """ + for b in r: + for a, c in b: + pass""" + self.failUnless(self.find_binding("a", s)) + + s = """ + for b in r: + for (a, c) in b: + pass""" + self.failUnless(self.find_binding("a", s)) + + s = """ + for b in r: + for (a,) in b: + pass""" + self.failUnless(self.find_binding("a", s)) + + s = """ + for b in r: + for c, (a, d) in b: + pass""" + self.failUnless(self.find_binding("a", s)) + + s = """ + for b in r: + for c in b: + a = 7""" + self.failUnless(self.find_binding("a", s)) + + s = """ + for b in r: + for c in b: + d = a""" + self.failIf(self.find_binding("a", s)) + + s = """ + for b in r: + for c in a: + d = 7""" + self.failIf(self.find_binding("a", s)) + + def test_if(self): + self.failUnless(self.find_binding("a", "if b in r: a = c")) + self.failIf(self.find_binding("a", "if a in r: d = e")) + + def test_if_nested(self): + s = """ + if b in r: + if c in d: + a = c""" + self.failUnless(self.find_binding("a", s)) + + s = """ + if b in r: + if c in d: + c = a""" + self.failIf(self.find_binding("a", s)) + + def test_while(self): + self.failUnless(self.find_binding("a", "while b in r: a = c")) + self.failIf(self.find_binding("a", "while a in r: d = e")) + + def test_while_nested(self): + s = """ + while b in r: + while c in d: + a = c""" + self.failUnless(self.find_binding("a", s)) + + s = """ + while b in r: + while c in d: + c = a""" + self.failIf(self.find_binding("a", s)) + + def test_try_except(self): + s = """ + try: + a = 6 + except: + b = 8""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + b = 8 + except: + a = 6""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + b = 8 + except KeyError: + pass + except: + a = 6""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + b = 8 + except: + b = 6""" + self.failIf(self.find_binding("a", s)) + + def test_try_except_nested(self): + s = """ + try: + try: + a = 6 + except: + pass + except: + b = 8""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + b = 8 + except: + try: + a = 6 + except: + pass""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + b = 8 + except: + try: + pass + except: + a = 6""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + try: + b = 8 + except KeyError: + pass + except: + a = 6 + except: + pass""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + pass + except: + try: + b = 8 + except KeyError: + pass + except: + a = 6""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + b = 8 + except: + b = 6""" + self.failIf(self.find_binding("a", s)) + + s = """ + try: + try: + b = 8 + except: + c = d + except: + try: + b = 6 + except: + t = 8 + except: + o = y""" + self.failIf(self.find_binding("a", s)) + + def test_try_except_finally(self): + s = """ + try: + c = 6 + except: + b = 8 + finally: + a = 9""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + b = 8 + finally: + a = 6""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + b = 8 + finally: + b = 6""" + self.failIf(self.find_binding("a", s)) + + s = """ + try: + b = 8 + except: + b = 9 + finally: + b = 6""" + self.failIf(self.find_binding("a", s)) + + def test_try_except_finally_nested(self): + s = """ + try: + c = 6 + except: + b = 8 + finally: + try: + a = 9 + except: + b = 9 + finally: + c = 9""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + b = 8 + finally: + try: + pass + finally: + a = 6""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + b = 8 + finally: + try: + b = 6 + finally: + b = 7""" + self.failIf(self.find_binding("a", s)) + +class Test_touch_import(support.TestCase): + + def test_after_docstring(self): + node = parse('"""foo"""\nbar()') + fixer_util.touch_import(None, "foo", node) + self.assertEqual(str(node), '"""foo"""\nimport foo\nbar()\n\n') + + def test_after_imports(self): + node = parse('"""foo"""\nimport bar\nbar()') + fixer_util.touch_import(None, "foo", node) + self.assertEqual(str(node), '"""foo"""\nimport bar\nimport foo\nbar()\n\n') + + def test_beginning(self): + node = parse('bar()') + fixer_util.touch_import(None, "foo", node) + self.assertEqual(str(node), 'import foo\nbar()\n\n') + + 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') + + def test_name_import(self): + node = parse('bar()') + fixer_util.touch_import(None, "cgi", node) + self.assertEqual(str(node), 'import cgi\nbar()\n\n') + + +if __name__ == "__main__": + import __main__ + support.run_all_tests(__main__) Added: sandbox/trunk/refactor_pkg/refactor/Grammar.txt ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/Grammar.txt Wed Apr 1 21:02:05 2009 @@ -0,0 +1,155 @@ +# Grammar for Python + +# Note: Changing the grammar specified in this file will most likely +# require corresponding changes in the parser module +# (../Modules/parsermodule.c). If you can't make the changes to +# that module yourself, please co-ordinate the required changes +# with someone who can; ask around on python-dev for help. Fred +# Drake will probably be listening there. + +# NOTE WELL: You should also follow all the steps listed in PEP 306, +# "How to Change Python's Grammar" + +# Commands for Kees Blom's railroad program +#diagram:token NAME +#diagram:token NUMBER +#diagram:token STRING +#diagram:token NEWLINE +#diagram:token ENDMARKER +#diagram:token INDENT +#diagram:output\input python.bla +#diagram:token DEDENT +#diagram:output\textwidth 20.04cm\oddsidemargin 0.0cm\evensidemargin 0.0cm +#diagram:rules + +# Start symbols for the grammar: +# file_input is a module or sequence of commands read from an input file; +# single_input is a single interactive statement; +# eval_input is the input for the eval() and input() functions. +# NB: compound_stmt in single_input is followed by extra NEWLINE! +file_input: (NEWLINE | stmt)* ENDMARKER +single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE +eval_input: testlist NEWLINE* ENDMARKER + +decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE +decorators: decorator+ +decorated: decorators (classdef | funcdef) +funcdef: 'def' NAME parameters ['->' test] ':' suite +parameters: '(' [typedargslist] ')' +typedargslist: ((tfpdef ['=' test] ',')* + ('*' [tname] (',' tname ['=' test])* [',' '**' tname] | '**' tname) + | tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) +tname: NAME [':' test] +tfpdef: tname | '(' tfplist ')' +tfplist: tfpdef (',' tfpdef)* [','] +varargslist: ((vfpdef ['=' test] ',')* + ('*' [vname] (',' vname ['=' test])* [',' '**' vname] | '**' vname) + | vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) +vname: NAME +vfpdef: vname | '(' vfplist ')' +vfplist: vfpdef (',' vfpdef)* [','] + +stmt: simple_stmt | compound_stmt +simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE +small_stmt: (expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | + import_stmt | global_stmt | exec_stmt | assert_stmt) +expr_stmt: testlist (augassign (yield_expr|testlist) | + ('=' (yield_expr|testlist))*) +augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | + '<<=' | '>>=' | '**=' | '//=') +# For normal assignments, additional restrictions enforced by the interpreter +print_stmt: 'print' ( [ test (',' test)* [','] ] | + '>>' test [ (',' test)+ [','] ] ) +del_stmt: 'del' exprlist +pass_stmt: 'pass' +flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt +break_stmt: 'break' +continue_stmt: 'continue' +return_stmt: 'return' [testlist] +yield_stmt: yield_expr +raise_stmt: 'raise' [test ['from' test | ',' test [',' test]]] +import_stmt: import_name | import_from +import_name: 'import' dotted_as_names +import_from: ('from' ('.'* dotted_name | '.'+) + 'import' ('*' | '(' import_as_names ')' | import_as_names)) +import_as_name: NAME ['as' NAME] +dotted_as_name: dotted_name ['as' NAME] +import_as_names: import_as_name (',' import_as_name)* [','] +dotted_as_names: dotted_as_name (',' dotted_as_name)* +dotted_name: NAME ('.' NAME)* +global_stmt: ('global' | 'nonlocal') NAME (',' NAME)* +exec_stmt: 'exec' expr ['in' test [',' test]] +assert_stmt: 'assert' test [',' test] + +compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated +if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] +while_stmt: 'while' test ':' suite ['else' ':' suite] +for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] +try_stmt: ('try' ':' suite + ((except_clause ':' suite)+ + ['else' ':' suite] + ['finally' ':' suite] | + 'finally' ':' suite)) +with_stmt: 'with' test [ with_var ] ':' suite +with_var: 'as' expr +# NB compile.c makes sure that the default except clause is last +except_clause: 'except' [test [(',' | 'as') test]] +suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT + +# Backward compatibility cruft to support: +# [ x for x in lambda: True, lambda: False if x() ] +# even while also allowing: +# lambda x: 5 if x else 2 +# (But not a mix of the two) +testlist_safe: old_test [(',' old_test)+ [',']] +old_test: or_test | old_lambdef +old_lambdef: 'lambda' [varargslist] ':' old_test + +test: or_test ['if' or_test 'else' test] | lambdef +or_test: and_test ('or' and_test)* +and_test: not_test ('and' not_test)* +not_test: 'not' not_test | comparison +comparison: expr (comp_op expr)* +comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' +expr: xor_expr ('|' xor_expr)* +xor_expr: and_expr ('^' and_expr)* +and_expr: shift_expr ('&' shift_expr)* +shift_expr: arith_expr (('<<'|'>>') arith_expr)* +arith_expr: term (('+'|'-') term)* +term: factor (('*'|'/'|'%'|'//') factor)* +factor: ('+'|'-'|'~') factor | power +power: atom trailer* ['**' factor] +atom: ('(' [yield_expr|testlist_gexp] ')' | + '[' [listmaker] ']' | + '{' [dictsetmaker] '}' | + '`' testlist1 '`' | + NAME | NUMBER | STRING+ | '.' '.' '.') +listmaker: test ( comp_for | (',' test)* [','] ) +testlist_gexp: test ( comp_for | (',' test)* [','] ) +lambdef: 'lambda' [varargslist] ':' test +trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME +subscriptlist: subscript (',' subscript)* [','] +subscript: test | [test] ':' [test] [sliceop] +sliceop: ':' [test] +exprlist: expr (',' expr)* [','] +testlist: test (',' test)* [','] +dictsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) | + (test (comp_for | (',' test)* [','])) ) + +classdef: 'class' NAME ['(' [arglist] ')'] ':' suite + +arglist: (argument ',')* (argument [','] + |'*' test (',' argument)* [',' '**' test] + |'**' test) +argument: test [comp_for] | test '=' test # Really [keyword '='] test + +comp_iter: comp_for | comp_if +comp_for: 'for' exprlist 'in' testlist_safe [comp_iter] +comp_if: 'if' old_test [comp_iter] + +testlist1: test (',' test)* + +# not used in grammar, but may appear in "node" passed from Parser to Compiler +encoding_decl: NAME + +yield_expr: 'yield' [testlist] Added: sandbox/trunk/refactor_pkg/refactor/PatternGrammar.txt ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/PatternGrammar.txt Wed Apr 1 21:02:05 2009 @@ -0,0 +1,28 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +# A grammar to describe tree matching patterns. +# Not shown here: +# - 'TOKEN' stands for any token (leaf node) +# - 'any' stands for any node (leaf or interior) +# With 'any' we can still specify the sub-structure. + +# The start symbol is 'Matcher'. + +Matcher: Alternatives ENDMARKER + +Alternatives: Alternative ('|' Alternative)* + +Alternative: (Unit | NegatedUnit)+ + +Unit: [NAME '='] ( STRING [Repeater] + | NAME [Details] [Repeater] + | '(' Alternatives ')' [Repeater] + | '[' Alternatives ']' + ) + +NegatedUnit: 'not' (STRING | NAME [Details] | '(' Alternatives ')') + +Repeater: '*' | '+' | '{' NUMBER [',' NUMBER] '}' + +Details: '<' Alternatives '>' Added: sandbox/trunk/refactor_pkg/refactor/__init__.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/__init__.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,8 @@ +from . import fixer_base +from . import fixer_util +from . import main +from . import patcomp +from . import pgen2 +from . import pygram +from . import pytree +from . import refactor Added: sandbox/trunk/refactor_pkg/refactor/fixer_base.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixer_base.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,178 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Base class for fixers (optional, but recommended).""" + +# Python imports +import logging +import itertools + +# Local imports +from .patcomp import PatternCompiler +from . import pygram +from .fixer_util import does_tree_import + +class BaseFix(object): + + """Optional base class for fixers. + + The subclass name must be FixFooBar where FooBar is the result of + removing underscores and capitalizing the words of the fix name. + For example, the class name for a fixer named 'has_key' should be + FixHasKey. + """ + + PATTERN = None # Most subclasses should override with a string literal + pattern = None # Compiled pattern, set by compile_pattern() + options = None # Options object passed to initializer + filename = None # The filename (set by set_filename) + logger = None # A logger (set by set_filename) + numbers = itertools.count(1) # For new_name() + used_names = set() # A set of all used NAMEs + order = "post" # Does the fixer prefer pre- or post-order traversal + explicit = False # Is this ignored by refactor.py -f all? + run_order = 5 # Fixers will be sorted by run order before execution + # Lower numbers will be run first. + + # Shortcut for access to Python grammar symbols + syms = pygram.python_symbols + + def __init__(self, options, log): + """Initializer. Subclass may override. + + Args: + options: an dict containing the options passed to RefactoringTool + that could be used to customize the fixer through the command line. + log: a list to append warnings and other messages to. + """ + self.options = options + self.log = log + self.compile_pattern() + + def compile_pattern(self): + """Compiles self.PATTERN into self.pattern. + + Subclass may override if it doesn't want to use + self.{pattern,PATTERN} in .match(). + """ + if self.PATTERN is not None: + self.pattern = PatternCompiler().compile_pattern(self.PATTERN) + + def set_filename(self, filename): + """Set the filename, and a logger derived from it. + + The main refactoring tool should call this. + """ + self.filename = filename + self.logger = logging.getLogger(filename) + + def match(self, node): + """Returns match for a given parse tree node. + + Should return a true or false object (not necessarily a bool). + It may return a non-empty dict of matching sub-nodes as + returned by a matching pattern. + + Subclass may override. + """ + results = {"node": node} + return self.pattern.match(node, results) and results + + def transform(self, node, results): + """Returns the transformation for a given parse tree node. + + Args: + node: the root of the parse tree that matched the fixer. + results: a dict mapping symbolic names to part of the match. + + Returns: + None, or a node that is a modified copy of the + argument node. The node argument may also be modified in-place to + effect the same change. + + Subclass *must* override. + """ + raise NotImplementedError() + + def new_name(self, template="xxx_todo_changeme"): + """Return a string suitable for use as an identifier + + The new name is guaranteed not to conflict with other identifiers. + """ + name = template + while name in self.used_names: + name = template + str(self.numbers.next()) + self.used_names.add(name) + return name + + def log_message(self, message): + if self.first_log: + self.first_log = False + self.log.append("### In file %s ###" % self.filename) + self.log.append(message) + + def cannot_convert(self, node, reason=None): + """Warn the user that a given chunk of code is not valid Python 3, + but that it cannot be converted automatically. + + First argument is the top-level node for the code in question. + Optional second argument is why it can't be converted. + """ + lineno = node.get_lineno() + for_output = node.clone() + for_output.set_prefix("") + msg = "Line %d: could not convert: %s" + self.log_message(msg % (lineno, for_output)) + if reason: + self.log_message(reason) + + def warning(self, node, reason): + """Used for warning the user about possible uncertainty in the + translation. + + First argument is the top-level node for the code in question. + Optional second argument is why it can't be converted. + """ + lineno = node.get_lineno() + self.log_message("Line %d: %s" % (lineno, reason)) + + def start_tree(self, tree, filename): + """Some fixers need to maintain tree-wide state. + This method is called once, at the start of tree fix-up. + + tree - the root node of the tree to be processed. + filename - the name of the file the tree came from. + """ + self.used_names = tree.used_names + self.set_filename(filename) + self.numbers = itertools.count(1) + self.first_log = True + + def finish_tree(self, tree, filename): + """Some fixers need to maintain tree-wide state. + This method is called once, at the conclusion of tree fix-up. + + tree - the root node of the tree to be processed. + filename - the name of the file the tree came from. + """ + pass + + +class ConditionalFix(BaseFix): + """ Base class for fixers which not execute if an import is found. """ + + # This is the name of the import which, if found, will cause the test to be skipped + skip_on = None + + def start_tree(self, *args): + super(ConditionalFix, self).start_tree(*args) + self._should_skip = None + + def should_skip(self, node): + if self._should_skip is not None: + return self._should_skip + pkg = self.skip_on.split(".") + name = pkg[-1] + pkg = ".".join(pkg[:-1]) + self._should_skip = does_tree_import(pkg, name, node) + return self._should_skip Added: sandbox/trunk/refactor_pkg/refactor/fixer_util.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixer_util.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,425 @@ +"""Utility functions, node construction macros, etc.""" +# Author: Collin Winter + +# Local imports +from .pgen2 import token +from .pytree import Leaf, Node +from .pygram import python_symbols as syms +from . import patcomp + + +########################################################### +### Common node-construction "macros" +########################################################### + +def KeywordArg(keyword, value): + return Node(syms.argument, + [keyword, Leaf(token.EQUAL, '='), value]) + +def LParen(): + return Leaf(token.LPAR, "(") + +def RParen(): + return Leaf(token.RPAR, ")") + +def Assign(target, source): + """Build an assignment statement""" + if not isinstance(target, list): + target = [target] + if not isinstance(source, list): + source.set_prefix(" ") + source = [source] + + return Node(syms.atom, + target + [Leaf(token.EQUAL, "=", prefix=" ")] + source) + +def Name(name, prefix=None): + """Return a NAME leaf""" + return Leaf(token.NAME, name, prefix=prefix) + +def Attr(obj, attr): + """A node tuple for obj.attr""" + return [obj, Node(syms.trailer, [Dot(), attr])] + +def Comma(): + """A comma leaf""" + return Leaf(token.COMMA, ",") + +def Dot(): + """A period (.) leaf""" + return Leaf(token.DOT, ".") + +def ArgList(args, lparen=LParen(), rparen=RParen()): + """A parenthesised argument list, used by Call()""" + node = Node(syms.trailer, [lparen.clone(), rparen.clone()]) + if args: + node.insert_child(1, Node(syms.arglist, args)) + return node + +def Call(func_name, args=None, prefix=None): + """A function call""" + node = Node(syms.power, [func_name, ArgList(args)]) + if prefix is not None: + node.set_prefix(prefix) + return node + +def Newline(): + """A newline literal""" + return Leaf(token.NEWLINE, "\n") + +def BlankLine(): + """A blank line""" + return Leaf(token.NEWLINE, "") + +def Number(n, prefix=None): + return Leaf(token.NUMBER, n, prefix=prefix) + +def Subscript(index_node): + """A numeric or string subscript""" + return Node(syms.trailer, [Leaf(token.LBRACE, '['), + index_node, + Leaf(token.RBRACE, ']')]) + +def String(string, prefix=None): + """A string leaf""" + return Leaf(token.STRING, string, prefix=prefix) + +def ListComp(xp, fp, it, test=None): + """A list comprehension of the form [xp for fp in it if test]. + + If test is None, the "if test" part is omitted. + """ + xp.set_prefix("") + fp.set_prefix(" ") + it.set_prefix(" ") + for_leaf = Leaf(token.NAME, "for") + for_leaf.set_prefix(" ") + in_leaf = Leaf(token.NAME, "in") + in_leaf.set_prefix(" ") + inner_args = [for_leaf, fp, in_leaf, it] + if test: + test.set_prefix(" ") + if_leaf = Leaf(token.NAME, "if") + if_leaf.set_prefix(" ") + inner_args.append(Node(syms.comp_if, [if_leaf, test])) + inner = Node(syms.listmaker, [xp, Node(syms.comp_for, inner_args)]) + return Node(syms.atom, + [Leaf(token.LBRACE, "["), + inner, + Leaf(token.RBRACE, "]")]) + +def FromImport(package_name, name_leafs): + """ Return an import statement in the form: + from package import name_leafs""" + # XXX: May not handle dotted imports properly (eg, package_name='foo.bar') + #assert package_name == '.' or '.' not in package_name, "FromImport has "\ + # "not been tested with dotted package names -- use at your own "\ + # "peril!" + + for leaf in name_leafs: + # Pull the leaves out of their old tree + leaf.remove() + + children = [Leaf(token.NAME, 'from'), + Leaf(token.NAME, package_name, prefix=" "), + Leaf(token.NAME, 'import', prefix=" "), + Node(syms.import_as_names, name_leafs)] + imp = Node(syms.import_from, children) + return imp + + +########################################################### +### Determine whether a node represents a given literal +########################################################### + +def is_tuple(node): + """Does the node represent a tuple literal?""" + if isinstance(node, Node) and node.children == [LParen(), RParen()]: + return True + return (isinstance(node, Node) + and len(node.children) == 3 + and isinstance(node.children[0], Leaf) + and isinstance(node.children[1], Node) + and isinstance(node.children[2], Leaf) + and node.children[0].value == "(" + and node.children[2].value == ")") + +def is_list(node): + """Does the node represent a list literal?""" + return (isinstance(node, Node) + and len(node.children) > 1 + and isinstance(node.children[0], Leaf) + and isinstance(node.children[-1], Leaf) + and node.children[0].value == "[" + and node.children[-1].value == "]") + + +########################################################### +### Misc +########################################################### + +def parenthesize(node): + return Node(syms.atom, [LParen(), node, RParen()]) + + +consuming_calls = set(["sorted", "list", "set", "any", "all", "tuple", "sum", + "min", "max"]) + +def attr_chain(obj, attr): + """Follow an attribute chain. + + If you have a chain of objects where a.foo -> b, b.foo-> c, etc, + use this to iterate over all objects in the chain. Iteration is + terminated by getattr(x, attr) is None. + + Args: + obj: the starting object + attr: the name of the chaining attribute + + Yields: + Each successive object in the chain. + """ + next = getattr(obj, attr) + while next: + yield next + next = getattr(next, attr) + +p0 = """for_stmt< 'for' any 'in' node=any ':' any* > + | comp_for< 'for' any 'in' node=any any* > + """ +p1 = """ +power< + ( 'iter' | 'list' | 'tuple' | 'sorted' | 'set' | 'sum' | + 'any' | 'all' | (any* trailer< '.' 'join' >) ) + trailer< '(' node=any ')' > + any* +> +""" +p2 = """ +power< + 'sorted' + trailer< '(' arglist ')' > + any* +> +""" +pats_built = False +def in_special_context(node): + """ Returns true if node is in an environment where all that is required + of it is being itterable (ie, it doesn't matter if it returns a list + or an itterator). + See test_map_nochange in test_fixers.py for some examples and tests. + """ + global p0, p1, p2, pats_built + if not pats_built: + p1 = patcomp.compile_pattern(p1) + p0 = patcomp.compile_pattern(p0) + p2 = patcomp.compile_pattern(p2) + pats_built = True + patterns = [p0, p1, p2] + for pattern, parent in zip(patterns, attr_chain(node, "parent")): + results = {} + if pattern.match(parent, results) and results["node"] is node: + return True + return False + +def is_probably_builtin(node): + """ + Check that something isn't an attribute or function name etc. + """ + prev = node.prev_sibling + if prev is not None and prev.type == token.DOT: + # Attribute lookup. + return False + parent = node.parent + if parent.type in (syms.funcdef, syms.classdef): + return False + if parent.type == syms.expr_stmt and parent.children[0] is node: + # Assignment. + return False + if parent.type == syms.parameters or \ + (parent.type == syms.typedargslist and ( + (prev is not None and prev.type == token.COMMA) or + parent.children[0] is node + )): + # The name of an argument. + return False + return True + +########################################################### +### The following functions are to find bindings in a suite +########################################################### + +def make_suite(node): + if node.type == syms.suite: + return node + node = node.clone() + parent, node.parent = node.parent, None + suite = Node(syms.suite, [node]) + suite.parent = parent + return suite + +def find_root(node): + """Find the top level namespace.""" + # Scamper up to the top level namespace + while node.type != syms.file_input: + assert node.parent, "Tree is insane! root found before "\ + "file_input node was found." + node = node.parent + return node + +def does_tree_import(package, name, node): + """ Returns true if name is imported from package at the + top level of the tree which node belongs to. + To cover the case of an import like 'import foo', use + None for the package and 'foo' for the name. """ + binding = find_binding(name, find_root(node), package) + return bool(binding) + +def is_import(node): + """Returns true if the node is an import statement.""" + return node.type in (syms.import_name, syms.import_from) + +def touch_import(package, name, node): + """ Works like `does_tree_import` but adds an import statement + if it was not imported. """ + def is_import_stmt(node): + return node.type == syms.simple_stmt and node.children and \ + is_import(node.children[0]) + + root = find_root(node) + + if does_tree_import(package, name, root): + return + + add_newline_before = False + + # figure out where to insert the new import. First try to find + # the first import and then skip to the last one. + insert_pos = offset = 0 + for idx, node in enumerate(root.children): + if not is_import_stmt(node): + continue + for offset, node2 in enumerate(root.children[idx:]): + if not is_import_stmt(node2): + break + insert_pos = idx + offset + break + + # if there are no imports where we can insert, find the docstring. + # if that also fails, we stick to the beginning of the file + if insert_pos == 0: + for idx, node in enumerate(root.children): + if node.type == syms.simple_stmt and node.children and \ + node.children[0].type == token.STRING: + insert_pos = idx + 1 + add_newline_before + break + + if package is None: + import_ = Node(syms.import_name, [ + Leaf(token.NAME, 'import'), + Leaf(token.NAME, name, prefix=' ') + ]) + else: + import_ = FromImport(package, [Leaf(token.NAME, name, prefix=' ')]) + + children = [import_, Newline()] + if add_newline_before: + children.insert(0, Newline()) + root.insert_child(insert_pos, Node(syms.simple_stmt, children)) + + +_def_syms = set([syms.classdef, syms.funcdef]) +def find_binding(name, node, package=None): + """ Returns the node which binds variable name, otherwise None. + If optional argument package is supplied, only imports will + be returned. + See test cases for examples.""" + for child in node.children: + ret = None + if child.type == syms.for_stmt: + if _find(name, child.children[1]): + return child + n = find_binding(name, make_suite(child.children[-1]), package) + if n: ret = n + elif child.type in (syms.if_stmt, syms.while_stmt): + n = find_binding(name, make_suite(child.children[-1]), package) + if n: ret = n + elif child.type == syms.try_stmt: + n = find_binding(name, make_suite(child.children[2]), package) + if n: + ret = n + else: + for i, kid in enumerate(child.children[3:]): + if kid.type == token.COLON and kid.value == ":": + # i+3 is the colon, i+4 is the suite + n = find_binding(name, make_suite(child.children[i+4]), package) + if n: ret = n + elif child.type in _def_syms and child.children[1].value == name: + ret = child + elif _is_import_binding(child, name, package): + ret = child + elif child.type == syms.simple_stmt: + ret = find_binding(name, child, package) + elif child.type == syms.expr_stmt: + if _find(name, child.children[0]): + ret = child + + if ret: + if not package: + return ret + if is_import(ret): + return ret + return None + +_block_syms = set([syms.funcdef, syms.classdef, syms.trailer]) +def _find(name, node): + nodes = [node] + while nodes: + node = nodes.pop() + if node.type > 256 and node.type not in _block_syms: + nodes.extend(node.children) + elif node.type == token.NAME and node.value == name: + return node + return None + +def _is_import_binding(node, name, package=None): + """ Will reuturn node if node will import name, or node + will import * from package. None is returned otherwise. + See test cases for examples. """ + + if node.type == syms.import_name and not package: + imp = node.children[1] + if imp.type == syms.dotted_as_names: + for child in imp.children: + if child.type == syms.dotted_as_name: + if child.children[2].value == name: + return node + elif child.type == token.NAME and child.value == name: + return node + elif imp.type == syms.dotted_as_name: + last = imp.children[-1] + if last.type == token.NAME and last.value == name: + return node + elif imp.type == token.NAME and imp.value == name: + return node + elif node.type == syms.import_from: + # unicode(...) is used to make life easier here, because + # from a.b import parses to ['import', ['a', '.', 'b'], ...] + if package and unicode(node.children[1]).strip() != package: + return None + n = node.children[3] + if package and _find('as', n): + # See test_from_import_as for explanation + return None + elif n.type == syms.import_as_names and _find(name, n): + return node + elif n.type == syms.import_as_name: + child = n.children[2] + if child.type == token.NAME and child.value == name: + return node + elif n.type == token.NAME and n.value == name: + return node + elif package and n.type == token.STAR: + return node + return None Added: sandbox/trunk/refactor_pkg/refactor/fixes/__init__.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/__init__.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,3 @@ +from . import from2 +from . import from3 +from .from2 import * Added: sandbox/trunk/refactor_pkg/refactor/fixes/fixer_common.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/fixer_common.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,4 @@ +# Common fixer imports +from .. import fixer_base +from ..fixer_util import Name, Call, consuming_calls, attr_chain +from .. import patcomp Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/__init__.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/__init__.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,49 @@ +from . import fix_apply +from . import fix_basestring +from . import fix_buffer +from . import fix_callable +from . import fix_dict +from . import fix_except +from . import fix_exec +from . import fix_execfile +from . import fix_filter +from . import fix_funcattrs +from . import fix_future +from . import fix_getcwdu +from . import fix_has_key +from . import fix_idioms +from . import fix_import +from . import fix_imports +from . import fix_imports2 +from . import fix_input +from . import fix_intern +from . import fix_isinstance +from . import fix_itertools +from . import fix_itertools_imports +from . import fix_long +from . import fix_map +from . import fix_metaclass +from . import fix_methodattrs +from . import fix_ne +from . import fix_next +from . import fix_nonzero +from . import fix_numliterals +from . import fix_paren +from . import fix_print +from . import fix_raise +from . import fix_raw_input +from . import fix_reduce +from . import fix_renames +from . import fix_repr +from . import fix_set_literal +from . import fix_standarderror +from . import fix_sys_exc +from . import fix_throw +from . import fix_tuple_params +from . import fix_types +from . import fix_unicode +from . import fix_urllib +from . import fix_ws_comma +from . import fix_xrange +from . import fix_xreadlines +from . import fix_zip Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_apply.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_apply.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,58 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer for apply(). + +This converts apply(func, v, k) into (func)(*v, **k).""" + +# Local imports +from ... import pytree +from ...pgen2 import token +from ... import fixer_base +from ...fixer_util import Call, Comma, parenthesize + +class FixApply(fixer_base.BaseFix): + + PATTERN = """ + power< 'apply' + trailer< + '(' + arglist< + (not argument + ')' + > + > + """ + + def transform(self, node, results): + syms = self.syms + assert results + func = results["func"] + args = results["args"] + kwds = results.get("kwds") + prefix = node.get_prefix() + func = func.clone() + if (func.type not in (token.NAME, syms.atom) and + (func.type != syms.power or + func.children[-2].type == token.DOUBLESTAR)): + # Need to parenthesize + func = parenthesize(func) + func.set_prefix("") + args = args.clone() + args.set_prefix("") + if kwds is not None: + kwds = kwds.clone() + kwds.set_prefix("") + l_newargs = [pytree.Leaf(token.STAR, "*"), args] + if kwds is not None: + l_newargs.extend([Comma(), + pytree.Leaf(token.DOUBLESTAR, "**"), + kwds]) + l_newargs[-2].set_prefix(" ") # that's the ** token + # XXX Sometimes we could be cleverer, e.g. apply(f, (x, y) + t) + # can be translated into f(x, y, *t) instead of f(*(x, y) + t) + #new = pytree.Node(syms.power, (func, ArgList(l_newargs))) + return Call(func, l_newargs, prefix=prefix) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_basestring.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_basestring.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,13 @@ +"""Fixer for basestring -> str.""" +# Author: Christian Heimes + +# Local imports +from ... import fixer_base +from ...fixer_util import Name + +class FixBasestring(fixer_base.BaseFix): + + PATTERN = "'basestring'" + + def transform(self, node, results): + return Name("str", prefix=node.get_prefix()) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_buffer.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_buffer.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,21 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer that changes buffer(...) into memoryview(...).""" + +# Local imports +from ... import fixer_base +from ...fixer_util import Name + + +class FixBuffer(fixer_base.BaseFix): + + explicit = True # The user must ask for this fixer + + PATTERN = """ + power< name='buffer' trailer< '(' [any] ')' > > + """ + + def transform(self, node, results): + name = results["name"] + name.replace(Name("memoryview", prefix=name.get_prefix())) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_callable.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_callable.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,31 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer for callable(). + +This converts callable(obj) into hasattr(obj, '__call__').""" + +# Local imports +from ... import pytree +from ... import fixer_base +from ...fixer_util import Call, Name, String + +class FixCallable(fixer_base.BaseFix): + + # Ignore callable(*args) or use of keywords. + # Either could be a hint that the builtin callable() is not being used. + PATTERN = """ + power< 'callable' + trailer< lpar='(' + ( not(arglist | argument) any ','> ) + rpar=')' > + after=any* + > + """ + + def transform(self, node, results): + func = results["func"] + + args = [func.clone(), String(', '), String("'__call__'")] + return Call(Name("hasattr"), args, prefix=node.get_prefix()) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_dict.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_dict.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,99 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer for dict methods. + +d.keys() -> list(d.keys()) +d.items() -> list(d.items()) +d.values() -> list(d.values()) + +d.iterkeys() -> iter(d.keys()) +d.iteritems() -> iter(d.items()) +d.itervalues() -> iter(d.values()) + +Except in certain very specific contexts: the iter() can be dropped +when the context is list(), sorted(), iter() or for...in; the list() +can be dropped when the context is list() or sorted() (but not iter() +or for...in!). Special contexts that apply to both: list(), sorted(), tuple() +set(), any(), all(), sum(). + +Note: iter(d.keys()) could be written as iter(d) but since the +original d.iterkeys() was also redundant we don't fix this. And there +are (rare) contexts where it makes a difference (e.g. when passing it +as an argument to a function that introspects the argument). +""" + +# Local imports +from ... import pytree +from ... import patcomp +from ...pgen2 import token +from ... import fixer_base +from ...fixer_util import Name, Call, LParen, RParen, ArgList, Dot +from ... import fixer_util + + +iter_exempt = fixer_util.consuming_calls | set(["iter"]) + + +class FixDict(fixer_base.BaseFix): + PATTERN = """ + power< head=any+ + trailer< '.' method=('keys'|'items'|'values'| + 'iterkeys'|'iteritems'|'itervalues') > + parens=trailer< '(' ')' > + tail=any* + > + """ + + def transform(self, node, results): + head = results["head"] + method = results["method"][0] # Extract node for method name + tail = results["tail"] + syms = self.syms + method_name = method.value + isiter = method_name.startswith("iter") + if isiter: + method_name = method_name[4:] + assert method_name in ("keys", "items", "values"), repr(method) + head = [n.clone() for n in head] + tail = [n.clone() for n in tail] + special = not tail and self.in_special_context(node, isiter) + args = head + [pytree.Node(syms.trailer, + [Dot(), + Name(method_name, + prefix=method.get_prefix())]), + results["parens"].clone()] + new = pytree.Node(syms.power, args) + if not special: + new.set_prefix("") + new = Call(Name(isiter and "iter" or "list"), [new]) + if tail: + new = pytree.Node(syms.power, [new] + tail) + new.set_prefix(node.get_prefix()) + return new + + P1 = "power< func=NAME trailer< '(' node=any ')' > any* >" + p1 = patcomp.compile_pattern(P1) + + P2 = """for_stmt< 'for' any 'in' node=any ':' any* > + | comp_for< 'for' any 'in' node=any any* > + """ + p2 = patcomp.compile_pattern(P2) + + def in_special_context(self, node, isiter): + if node.parent is None: + return False + results = {} + if (node.parent.parent is not None and + self.p1.match(node.parent.parent, results) and + results["node"] is node): + if isiter: + # iter(d.iterkeys()) -> iter(d.keys()), etc. + return results["func"].value in iter_exempt + else: + # list(d.keys()) -> list(d.keys()), etc. + return results["func"].value in fixer_util.consuming_calls + if not isiter: + return False + # for ... in d.iterkeys() -> for ... in d.keys(), etc. + return self.p2.match(node.parent, results) and results["node"] is node Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_except.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_except.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,92 @@ +"""Fixer for except statements with named exceptions. + +The following cases will be converted: + +- "except E, T:" where T is a name: + + except E as T: + +- "except E, T:" where T is not a name, tuple or list: + + except E as t: + T = t + + This is done because the target of an "except" clause must be a + name. + +- "except E, T:" where T is a tuple or list literal: + + except E as t: + T = t.args +""" +# Author: Collin Winter + +# Local imports +from ... import pytree +from ...pgen2 import token +from ... import fixer_base +from ...fixer_util import Assign, Attr, Name, is_tuple, is_list, syms + +def find_excepts(nodes): + for i, n in enumerate(nodes): + if n.type == syms.except_clause: + if n.children[0].value == 'except': + yield (n, nodes[i+2]) + +class FixExcept(fixer_base.BaseFix): + + PATTERN = """ + try_stmt< 'try' ':' suite + cleanup=(except_clause ':' suite)+ + tail=(['except' ':' suite] + ['else' ':' suite] + ['finally' ':' suite]) > + """ + + def transform(self, node, results): + syms = self.syms + + tail = [n.clone() for n in results["tail"]] + + try_cleanup = [ch.clone() for ch in results["cleanup"]] + for except_clause, e_suite in find_excepts(try_cleanup): + if len(except_clause.children) == 4: + (E, comma, N) = except_clause.children[1:4] + comma.replace(Name("as", prefix=" ")) + + if N.type != token.NAME: + # Generate a new N for the except clause + new_N = Name(self.new_name(), prefix=" ") + target = N.clone() + target.set_prefix("") + N.replace(new_N) + new_N = new_N.clone() + + # Insert "old_N = new_N" as the first statement in + # the except body. This loop skips leading whitespace + # and indents + #TODO(cwinter) suite-cleanup + suite_stmts = e_suite.children + for i, stmt in enumerate(suite_stmts): + if isinstance(stmt, pytree.Node): + break + + # The assignment is different if old_N is a tuple or list + # In that case, the assignment is old_N = new_N.args + if is_tuple(N) or is_list(N): + assign = Assign(target, Attr(new_N, Name('args'))) + else: + assign = Assign(target, new_N) + + #TODO(cwinter) stopgap until children becomes a smart list + for child in reversed(suite_stmts[:i]): + e_suite.insert_child(0, child) + e_suite.insert_child(i, assign) + elif N.get_prefix() == "": + # No space after a comma is legal; no space after "as", + # not so much. + N.set_prefix(" ") + + #TODO(cwinter) fix this when children becomes a smart list + children = [c.clone() for c in node.children[:3]] + try_cleanup + tail + return pytree.Node(node.type, children) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_exec.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_exec.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,39 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer for exec. + +This converts usages of the exec statement into calls to a built-in +exec() function. + +exec code in ns1, ns2 -> exec(code, ns1, ns2) +""" + +# Local imports +from ... import pytree +from ... import fixer_base +from ...fixer_util import Comma, Name, Call + + +class FixExec(fixer_base.BaseFix): + + PATTERN = """ + exec_stmt< 'exec' a=any 'in' b=any [',' c=any] > + | + exec_stmt< 'exec' (not atom<'(' [any] ')'>) a=any > + """ + + def transform(self, node, results): + assert results + syms = self.syms + a = results["a"] + b = results.get("b") + c = results.get("c") + args = [a.clone()] + args[0].set_prefix("") + if b is not None: + args.extend([Comma(), b.clone()]) + if c is not None: + args.extend([Comma(), c.clone()]) + + return Call(Name("exec"), args, prefix=node.get_prefix()) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_execfile.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_execfile.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,51 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer for execfile. + +This converts usages of the execfile function into calls to the built-in +exec() function. +""" + +from ... import fixer_base +from ...fixer_util import (Comma, Name, Call, LParen, RParen, Dot, Node, + ArgList, String, syms) + + +class FixExecfile(fixer_base.BaseFix): + + PATTERN = """ + power< 'execfile' trailer< '(' arglist< filename=any [',' globals=any [',' locals=any ] ] > ')' > > + | + power< 'execfile' trailer< '(' filename=any ')' > > + """ + + def transform(self, node, results): + assert results + filename = results["filename"] + globals = results.get("globals") + locals = results.get("locals") + + # Copy over the prefix from the right parentheses end of the execfile + # call. + execfile_paren = node.children[-1].children[-1].clone() + # Construct open().read(). + open_args = ArgList([filename.clone()], rparen=execfile_paren) + open_call = Node(syms.power, [Name("open"), open_args]) + read = [Node(syms.trailer, [Dot(), Name('read')]), + Node(syms.trailer, [LParen(), RParen()])] + open_expr = [open_call] + read + # Wrap the open call in a compile call. This is so the filename will be + # preserved in the execed code. + filename_arg = filename.clone() + filename_arg.set_prefix(" ") + exec_str = String("'exec'", " ") + compile_args = open_expr + [Comma(), filename_arg, Comma(), exec_str] + compile_call = Call(Name("compile"), compile_args, "") + # Finally, replace the execfile call with an exec call. + args = [compile_call] + if globals is not None: + args.extend([Comma(), globals.clone()]) + if locals is not None: + args.extend([Comma(), locals.clone()]) + return Call(Name("exec"), args, prefix=node.get_prefix()) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_filter.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_filter.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,75 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer that changes filter(F, X) into list(filter(F, X)). + +We avoid the transformation if the filter() call is directly contained +in iter(<>), list(<>), tuple(<>), sorted(<>), ...join(<>), or +for V in <>:. + +NOTE: This is still not correct if the original code was depending on +filter(F, X) to return a string if X is a string and a tuple if X is a +tuple. That would require type inference, which we don't do. Let +Python 2.6 figure it out. +""" + +# Local imports +from ...pgen2 import token +from ... import fixer_base +from ...fixer_util import Name, Call, ListComp, in_special_context + +class FixFilter(fixer_base.ConditionalFix): + + PATTERN = """ + filter_lambda=power< + 'filter' + trailer< + '(' + arglist< + lambdef< 'lambda' + (fp=NAME | vfpdef< '(' fp=NAME ')'> ) ':' xp=any + > + ',' + it=any + > + ')' + > + > + | + power< + 'filter' + trailer< '(' arglist< none='None' ',' seq=any > ')' > + > + | + power< + 'filter' + args=trailer< '(' [any] ')' > + > + """ + + skip_on = "future_builtins.filter" + + def transform(self, node, results): + if self.should_skip(node): + return + + if "filter_lambda" in results: + new = ListComp(results.get("fp").clone(), + results.get("fp").clone(), + results.get("it").clone(), + results.get("xp").clone()) + + elif "none" in results: + new = ListComp(Name("_f"), + Name("_f"), + results["seq"].clone(), + Name("_f")) + + else: + if in_special_context(node): + return None + new = node.clone() + new.set_prefix("") + new = Call(Name("list"), [new]) + new.set_prefix(node.get_prefix()) + return new Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_funcattrs.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_funcattrs.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,19 @@ +"""Fix function attribute names (f.func_x -> f.__x__).""" +# Author: Collin Winter + +# Local imports +from ... import fixer_base +from ...fixer_util import Name + + +class FixFuncattrs(fixer_base.BaseFix): + PATTERN = """ + power< any+ trailer< '.' attr=('func_closure' | 'func_doc' | 'func_globals' + | 'func_name' | 'func_defaults' | 'func_code' + | 'func_dict') > any* > + """ + + def transform(self, node, results): + attr = results["attr"][0] + attr.replace(Name(("__%s__" % attr.value[5:]), + prefix=attr.get_prefix())) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_future.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_future.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,20 @@ +"""Remove __future__ imports + +from __future__ import foo is replaced with an empty line. +""" +# Author: Christian Heimes + +# Local imports +from ... import fixer_base +from ...fixer_util import BlankLine + +class FixFuture(fixer_base.BaseFix): + PATTERN = """import_from< 'from' module_name="__future__" 'import' any >""" + + # This should be run last -- some things check for the import + run_order = 10 + + def transform(self, node, results): + new = BlankLine() + new.prefix = node.get_prefix() + return new Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_getcwdu.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_getcwdu.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,18 @@ +""" +Fixer that changes os.getcwdu() to os.getcwd(). +""" +# Author: Victor Stinner + +# Local imports +from ... import fixer_base +from ...fixer_util import Name + +class FixGetcwdu(fixer_base.BaseFix): + + PATTERN = """ + power< 'os' trailer< dot='.' name='getcwdu' > any* > + """ + + def transform(self, node, results): + name = results["name"] + name.replace(Name("getcwd", prefix=name.get_prefix())) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_has_key.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_has_key.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,109 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer for has_key(). + +Calls to .has_key() methods are expressed in terms of the 'in' +operator: + + d.has_key(k) -> k in d + +CAVEATS: +1) While the primary target of this fixer is dict.has_key(), the + fixer will change any has_key() method call, regardless of its + class. + +2) Cases like this will not be converted: + + m = d.has_key + if m(k): + ... + + Only *calls* to has_key() are converted. While it is possible to + convert the above to something like + + m = d.__contains__ + if m(k): + ... + + this is currently not done. +""" + +# Local imports +from ... import pytree +from ...pgen2 import token +from ... import fixer_base +from ...fixer_util import Name, parenthesize + + +class FixHasKey(fixer_base.BaseFix): + + PATTERN = """ + anchor=power< + before=any+ + trailer< '.' 'has_key' > + trailer< + '(' + ( not(arglist | argument) arg=any ','> + ) + ')' + > + after=any* + > + | + negation=not_test< + 'not' + anchor=power< + before=any+ + trailer< '.' 'has_key' > + trailer< + '(' + ( not(arglist | argument) arg=any ','> + ) + ')' + > + > + > + """ + + def transform(self, node, results): + assert results + syms = self.syms + if (node.parent.type == syms.not_test and + self.pattern.match(node.parent)): + # Don't transform a node matching the first alternative of the + # pattern when its parent matches the second alternative + return None + negation = results.get("negation") + anchor = results["anchor"] + prefix = node.get_prefix() + before = [n.clone() for n in results["before"]] + arg = results["arg"].clone() + after = results.get("after") + if after: + after = [n.clone() for n in after] + if arg.type in (syms.comparison, syms.not_test, syms.and_test, + syms.or_test, syms.test, syms.lambdef, syms.argument): + arg = parenthesize(arg) + if len(before) == 1: + before = before[0] + else: + before = pytree.Node(syms.power, before) + before.set_prefix(" ") + n_op = Name("in", prefix=" ") + if negation: + n_not = Name("not", prefix=" ") + n_op = pytree.Node(syms.comp_op, (n_not, n_op)) + new = pytree.Node(syms.comparison, (arg, n_op, before)) + if after: + new = parenthesize(new) + new = pytree.Node(syms.power, (new,) + tuple(after)) + if node.parent.type in (syms.comparison, syms.expr, syms.xor_expr, + syms.and_expr, syms.shift_expr, + syms.arith_expr, syms.term, + syms.factor, syms.power): + new = parenthesize(new) + new.set_prefix(prefix) + return new Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_idioms.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_idioms.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,134 @@ +"""Adjust some old Python 2 idioms to their modern counterparts. + +* Change some type comparisons to isinstance() calls: + type(x) == T -> isinstance(x, T) + type(x) is T -> isinstance(x, T) + type(x) != T -> not isinstance(x, T) + type(x) is not T -> not isinstance(x, T) + +* Change "while 1:" into "while True:". + +* Change both + + v = list(EXPR) + v.sort() + foo(v) + +and the more general + + v = EXPR + v.sort() + foo(v) + +into + + v = sorted(EXPR) + foo(v) +""" +# Author: Jacques Frechet, Collin Winter + +# Local imports +from ... import fixer_base +from ...fixer_util import Call, Comma, Name, Node, syms + +CMP = "(n='!=' | '==' | 'is' | n=comp_op< 'is' 'not' >)" +TYPE = "power< 'type' trailer< '(' x=any ')' > >" + +class FixIdioms(fixer_base.BaseFix): + + explicit = True # The user must ask for this fixer + + PATTERN = r""" + isinstance=comparison< %s %s T=any > + | + isinstance=comparison< T=any %s %s > + | + while_stmt< 'while' while='1' ':' any+ > + | + sorted=any< + any* + simple_stmt< + expr_stmt< id1=any '=' + power< list='list' trailer< '(' (not arglist) any ')' > > + > + '\n' + > + sort= + simple_stmt< + power< id2=any + trailer< '.' 'sort' > trailer< '(' ')' > + > + '\n' + > + next=any* + > + | + sorted=any< + any* + simple_stmt< expr_stmt< id1=any '=' expr=any > '\n' > + sort= + simple_stmt< + power< id2=any + trailer< '.' 'sort' > trailer< '(' ')' > + > + '\n' + > + next=any* + > + """ % (TYPE, CMP, CMP, TYPE) + + def match(self, node): + r = super(FixIdioms, self).match(node) + # If we've matched one of the sort/sorted subpatterns above, we + # want to reject matches where the initial assignment and the + # subsequent .sort() call involve different identifiers. + if r and "sorted" in r: + if r["id1"] == r["id2"]: + return r + return None + return r + + def transform(self, node, results): + if "isinstance" in results: + return self.transform_isinstance(node, results) + elif "while" in results: + return self.transform_while(node, results) + elif "sorted" in results: + return self.transform_sort(node, results) + else: + raise RuntimeError("Invalid match") + + def transform_isinstance(self, node, results): + x = results["x"].clone() # The thing inside of type() + T = results["T"].clone() # The type being compared against + x.set_prefix("") + T.set_prefix(" ") + test = Call(Name("isinstance"), [x, Comma(), T]) + if "n" in results: + test.set_prefix(" ") + test = Node(syms.not_test, [Name("not"), test]) + test.set_prefix(node.get_prefix()) + return test + + def transform_while(self, node, results): + one = results["while"] + one.replace(Name("True", prefix=one.get_prefix())) + + def transform_sort(self, node, results): + sort_stmt = results["sort"] + next_stmt = results["next"] + list_call = results.get("list") + simple_expr = results.get("expr") + + if list_call: + list_call.replace(Name("sorted", prefix=list_call.get_prefix())) + elif simple_expr: + new = simple_expr.clone() + new.set_prefix("") + simple_expr.replace(Call(Name("sorted"), [new], + prefix=simple_expr.get_prefix())) + else: + raise RuntimeError("should not have reached here") + sort_stmt.remove() + if next_stmt: + next_stmt[0].set_prefix(sort_stmt.get_prefix()) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_import.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_import.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,90 @@ +"""Fixer for import statements. +If spam is being imported from the local directory, this import: + from spam import eggs +Becomes: + from .spam import eggs + +And this import: + import spam +Becomes: + from . import spam +""" + +# Local imports +from ... import fixer_base +from os.path import dirname, join, exists, pathsep +from ...fixer_util import FromImport, syms, token + + +def traverse_imports(names): + """ + Walks over all the names imported in a dotted_as_names node. + """ + pending = [names] + while pending: + node = pending.pop() + if node.type == token.NAME: + yield node.value + elif node.type == syms.dotted_name: + yield "".join([ch.value for ch in node.children]) + elif node.type == syms.dotted_as_name: + pending.append(node.children[0]) + elif node.type == syms.dotted_as_names: + pending.extend(node.children[::-2]) + else: + raise AssertionError("unkown node type") + + +class FixImport(fixer_base.BaseFix): + + PATTERN = """ + import_from< 'from' imp=any 'import' ['('] any [')'] > + | + import_name< 'import' imp=any > + """ + + def transform(self, node, results): + imp = results['imp'] + + if node.type == syms.import_from: + # Some imps are top-level (eg: 'import ham') + # some are first level (eg: 'import ham.eggs') + # some are third level (eg: 'import ham.eggs as spam') + # Hence, the loop + while not hasattr(imp, 'value'): + imp = imp.children[0] + if self.probably_a_local_import(imp.value): + imp.value = "." + imp.value + imp.changed() + return node + else: + have_local = False + have_absolute = False + for mod_name in traverse_imports(imp): + if self.probably_a_local_import(mod_name): + have_local = True + else: + have_absolute = True + if have_absolute: + if have_local: + # We won't handle both sibling and absolute imports in the + # same statement at the moment. + self.warning(node, "absolute and local imports together") + return + + new = FromImport('.', [imp]) + new.set_prefix(node.get_prefix()) + return new + + def probably_a_local_import(self, imp_name): + imp_name = imp_name.split('.', 1)[0] + base_path = dirname(self.filename) + base_path = join(base_path, imp_name) + # If there is no __init__.py next to the file its not in a package + # so can't be a relative import. + if not exists(join(dirname(base_path), '__init__.py')): + return False + for ext in ['.py', pathsep, '.pyc', '.so', '.sl', '.pyd']: + if exists(base_path + ext): + return True + return False Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_imports.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_imports.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,145 @@ +"""Fix incompatible imports and module references.""" +# Authors: Collin Winter, Nick Edds + +# Local imports +from ... import fixer_base +from ...fixer_util import Name, attr_chain + +MAPPING = {'StringIO': 'io', + 'cStringIO': 'io', + 'cPickle': 'pickle', + '__builtin__' : 'builtins', + 'copy_reg': 'copyreg', + 'Queue': 'queue', + 'SocketServer': 'socketserver', + 'ConfigParser': 'configparser', + 'repr': 'reprlib', + 'FileDialog': 'tkinter.filedialog', + 'tkFileDialog': 'tkinter.filedialog', + 'SimpleDialog': 'tkinter.simpledialog', + 'tkSimpleDialog': 'tkinter.simpledialog', + 'tkColorChooser': 'tkinter.colorchooser', + 'tkCommonDialog': 'tkinter.commondialog', + 'Dialog': 'tkinter.dialog', + 'Tkdnd': 'tkinter.dnd', + 'tkFont': 'tkinter.font', + 'tkMessageBox': 'tkinter.messagebox', + 'ScrolledText': 'tkinter.scrolledtext', + 'Tkconstants': 'tkinter.constants', + 'Tix': 'tkinter.tix', + 'ttk': 'tkinter.ttk', + 'Tkinter': 'tkinter', + 'markupbase': '_markupbase', + '_winreg': 'winreg', + 'thread': '_thread', + 'dummy_thread': '_dummy_thread', + # anydbm and whichdb are handled by fix_imports2 + 'dbhash': 'dbm.bsd', + 'dumbdbm': 'dbm.dumb', + 'dbm': 'dbm.ndbm', + 'gdbm': 'dbm.gnu', + 'xmlrpclib': 'xmlrpc.client', + 'DocXMLRPCServer': 'xmlrpc.server', + 'SimpleXMLRPCServer': 'xmlrpc.server', + 'httplib': 'http.client', + 'htmlentitydefs' : 'html.entities', + 'HTMLParser' : 'html.parser', + 'Cookie': 'http.cookies', + 'cookielib': 'http.cookiejar', + 'BaseHTTPServer': 'http.server', + 'SimpleHTTPServer': 'http.server', + 'CGIHTTPServer': 'http.server', + #'test.test_support': 'test.support', + 'commands': 'subprocess', + 'UserString' : 'collections', + 'UserList' : 'collections', + 'urlparse' : 'urllib.parse', + 'robotparser' : 'urllib.robotparser', +} + + +def alternates(members): + return "(" + "|".join(map(repr, members)) + ")" + + +def build_pattern(mapping=MAPPING): + mod_list = ' | '.join(["module_name='%s'" % key for key in mapping]) + bare_names = alternates(mapping.keys()) + + yield """name_import=import_name< 'import' ((%s) | + multiple_imports=dotted_as_names< any* (%s) any* >) > + """ % (mod_list, mod_list) + yield """import_from< 'from' (%s) 'import' ['('] + ( any | import_as_name< any 'as' any > | + import_as_names< any* >) [')'] > + """ % mod_list + yield """import_name< 'import' (dotted_as_name< (%s) 'as' any > | + multiple_imports=dotted_as_names< + any* dotted_as_name< (%s) 'as' any > any* >) > + """ % (mod_list, mod_list) + + # Find usages of module members in code e.g. thread.foo(bar) + yield "power< bare_with_attr=(%s) trailer<'.' any > any* >" % bare_names + + +class FixImports(fixer_base.BaseFix): + + order = "pre" # Pre-order tree traversal + + # This is overridden in fix_imports2. + mapping = MAPPING + + # We want to run this fixer late, so fix_import doesn't try to make stdlib + # renames into relative imports. + run_order = 6 + + def build_pattern(self): + return "|".join(build_pattern(self.mapping)) + + def compile_pattern(self): + # We override this, so MAPPING can be pragmatically altered and the + # changes will be reflected in PATTERN. + self.PATTERN = self.build_pattern() + super(FixImports, self).compile_pattern() + + # Don't match the node if it's within another match. + def match(self, node): + match = super(FixImports, self).match + results = match(node) + if results: + # Module usage could be in the trailer of an attribute lookup, so we + # might have nested matches when "bare_with_attr" is present. + if "bare_with_attr" not in results and \ + any([match(obj) for obj in attr_chain(node, "parent")]): + return False + return results + return False + + def start_tree(self, tree, filename): + super(FixImports, self).start_tree(tree, filename) + self.replace = {} + + def transform(self, node, results): + import_mod = results.get("module_name") + if import_mod: + mod_name = import_mod.value + new_name = self.mapping[mod_name] + import_mod.replace(Name(new_name, prefix=import_mod.get_prefix())) + if "name_import" in results: + # If it's not a "from x import x, y" or "import x as y" import, + # marked its usage to be replaced. + self.replace[mod_name] = new_name + if "multiple_imports" in results: + # This is a nasty hack to fix multiple imports on a line (e.g., + # "import StringIO, urlparse"). The problem is that I can't + # figure out an easy way to make a pattern recognize the keys of + # MAPPING randomly sprinkled in an import statement. + results = self.match(node) + if results: + self.transform(node, results) + else: + # Replace usage of the module. + bare_name = results["bare_with_attr"][0] + new_name = self.replace.get(bare_name.value) + if new_name: + bare_name.replace(Name(new_name, prefix=bare_name.get_prefix())) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_imports2.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_imports2.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,16 @@ +"""Fix incompatible imports and module references that must be fixed after +fix_imports.""" +from . import fix_imports + + +MAPPING = { + 'whichdb': 'dbm', + 'anydbm': 'dbm', + } + + +class FixImports2(fix_imports.FixImports): + + run_order = 7 + + mapping = MAPPING Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_input.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_input.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,26 @@ +"""Fixer that changes input(...) into eval(input(...)).""" +# Author: Andre Roberge + +# Local imports +from ... import fixer_base +from ...fixer_util import Call, Name +from ... import patcomp + + +context = patcomp.compile_pattern("power< 'eval' trailer< '(' any ')' > >") + + +class FixInput(fixer_base.BaseFix): + + PATTERN = """ + power< 'input' args=trailer< '(' [any] ')' > > + """ + + def transform(self, node, results): + # If we're already wrapped in a eval() call, we're done. + if context.match(node.parent.parent): + return + + new = node.clone() + new.set_prefix("") + return Call(Name("eval"), [new], prefix=node.get_prefix()) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_intern.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_intern.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,44 @@ +# Copyright 2006 Georg Brandl. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer for intern(). + +intern(s) -> sys.intern(s)""" + +# Local imports +from ... import pytree +from ... import fixer_base +from ...fixer_util import Name, Attr, touch_import + + +class FixIntern(fixer_base.BaseFix): + + PATTERN = """ + power< 'intern' + trailer< lpar='(' + ( not(arglist | argument) any ','> ) + rpar=')' > + after=any* + > + """ + + def transform(self, node, results): + syms = self.syms + obj = results["obj"].clone() + if obj.type == syms.arglist: + newarglist = obj.clone() + else: + newarglist = pytree.Node(syms.arglist, [obj.clone()]) + after = results["after"] + if after: + after = [n.clone() for n in after] + new = pytree.Node(syms.power, + Attr(Name("sys"), Name("intern")) + + [pytree.Node(syms.trailer, + [results["lpar"].clone(), + newarglist, + results["rpar"].clone()])] + after) + new.set_prefix(node.get_prefix()) + touch_import(None, 'sys', node) + return new Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_isinstance.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_isinstance.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,52 @@ +# Copyright 2008 Armin Ronacher. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer that cleans up a tuple argument to isinstance after the tokens +in it were fixed. This is mainly used to remove double occurrences of +tokens as a leftover of the long -> int / unicode -> str conversion. + +eg. isinstance(x, (int, long)) -> isinstance(x, (int, int)) + -> isinstance(x, int) +""" + +from ... import fixer_base +from ...fixer_util import token + + +class FixIsinstance(fixer_base.BaseFix): + + PATTERN = """ + power< + 'isinstance' + trailer< '(' arglist< any ',' atom< '(' + args=testlist_gexp< any+ > + ')' > > ')' > + > + """ + + run_order = 6 + + def transform(self, node, results): + names_inserted = set() + testlist = results["args"] + args = testlist.children + new_args = [] + iterator = enumerate(args) + for idx, arg in iterator: + if arg.type == token.NAME and arg.value in names_inserted: + if idx < len(args) - 1 and args[idx + 1].type == token.COMMA: + iterator.next() + continue + else: + new_args.append(arg) + if arg.type == token.NAME: + names_inserted.add(arg.value) + if new_args and new_args[-1].type == token.COMMA: + del new_args[-1] + if len(new_args) == 1: + atom = testlist.parent + new_args[0].set_prefix(atom.get_prefix()) + atom.replace(new_args[0]) + else: + args[:] = new_args + node.changed() Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_itertools.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_itertools.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,41 @@ +""" Fixer for itertools.(imap|ifilter|izip) --> (map|filter|zip) and + itertools.ifilterfalse --> itertools.filterfalse (bugs 2360-2363) + + imports from itertools are fixed in fix_itertools_import.py + + If itertools is imported as something else (ie: import itertools as it; + it.izip(spam, eggs)) method calls will not get fixed. + """ + +# Local imports +from ... import fixer_base +from ...fixer_util import Name + +class FixItertools(fixer_base.BaseFix): + it_funcs = "('imap'|'ifilter'|'izip'|'ifilterfalse')" + PATTERN = """ + power< it='itertools' + trailer< + dot='.' func=%(it_funcs)s > trailer< '(' [any] ')' > > + | + power< func=%(it_funcs)s trailer< '(' [any] ')' > > + """ %(locals()) + + # Needs to be run after fix_(map|zip|filter) + run_order = 6 + + def transform(self, node, results): + prefix = None + func = results['func'][0] + if 'it' in results and func.value != 'ifilterfalse': + dot, it = (results['dot'], results['it']) + # Remove the 'itertools' + prefix = it.get_prefix() + it.remove() + # Replace the node wich contains ('.', 'function') with the + # function (to be consistant with the second part of the pattern) + dot.remove() + func.parent.replace(func) + + prefix = prefix or func.get_prefix() + func.replace(Name(func.value[1:], prefix=prefix)) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_itertools_imports.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_itertools_imports.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,52 @@ +""" Fixer for imports of itertools.(imap|ifilter|izip|ifilterfalse) """ + +# Local imports +from ... import fixer_base +from ...fixer_util import BlankLine, syms, token + + +class FixItertoolsImports(fixer_base.BaseFix): + PATTERN = """ + import_from< 'from' 'itertools' 'import' imports=any > + """ %(locals()) + + def transform(self, node, results): + imports = results['imports'] + if imports.type == syms.import_as_name or not imports.children: + children = [imports] + else: + children = imports.children + for child in children[::2]: + if child.type == token.NAME: + member = child.value + name_node = child + else: + assert child.type == syms.import_as_name + name_node = child.children[0] + member_name = name_node.value + if member_name in ('imap', 'izip', 'ifilter'): + child.value = None + child.remove() + elif member_name == 'ifilterfalse': + node.changed() + name_node.value = 'filterfalse' + + # Make sure the import statement is still sane + children = imports.children[:] or [imports] + remove_comma = True + for child in children: + if remove_comma and child.type == token.COMMA: + child.remove() + else: + remove_comma ^= True + + if children[-1].type == token.COMMA: + children[-1].remove() + + # If there are no imports left, just get rid of the entire statement + if not (imports.children or getattr(imports, 'value', None)) or \ + imports.parent is None: + p = node.get_prefix() + node = BlankLine() + node.prefix = p + return node Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_long.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_long.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,22 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer that turns 'long' into 'int' everywhere. +""" + +# Local imports +from ... import fixer_base +from ...fixer_util import Name, Number, is_probably_builtin + + +class FixLong(fixer_base.BaseFix): + + PATTERN = "'long'" + + static_int = Name("int") + + def transform(self, node, results): + if is_probably_builtin(node): + new = self.static_int.clone() + new.set_prefix(node.get_prefix()) + return new Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_map.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_map.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,82 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer that changes map(F, ...) into list(map(F, ...)) unless there +exists a 'from future_builtins import map' statement in the top-level +namespace. + +As a special case, map(None, X) is changed into list(X). (This is +necessary because the semantics are changed in this case -- the new +map(None, X) is equivalent to [(x,) for x in X].) + +We avoid the transformation (except for the special case mentioned +above) if the map() call is directly contained in iter(<>), list(<>), +tuple(<>), sorted(<>), ...join(<>), or for V in <>:. + +NOTE: This is still not correct if the original code was depending on +map(F, X, Y, ...) to go on until the longest argument is exhausted, +substituting None for missing values -- like zip(), it now stops as +soon as the shortest argument is exhausted. +""" + +# Local imports +from ...pgen2 import token +from ... import fixer_base +from ...fixer_util import Name, Call, ListComp, in_special_context +from ...pygram import python_symbols as syms + +class FixMap(fixer_base.ConditionalFix): + + PATTERN = """ + map_none=power< + 'map' + trailer< '(' arglist< 'None' ',' arg=any [','] > ')' > + > + | + map_lambda=power< + 'map' + trailer< + '(' + arglist< + lambdef< 'lambda' + (fp=NAME | vfpdef< '(' fp=NAME ')'> ) ':' xp=any + > + ',' + it=any + > + ')' + > + > + | + power< + 'map' + args=trailer< '(' [any] ')' > + > + """ + + skip_on = 'future_builtins.map' + + def transform(self, node, results): + if self.should_skip(node): + return + + if node.parent.type == syms.simple_stmt: + self.warning(node, "You should use a for loop here") + new = node.clone() + new.set_prefix("") + new = Call(Name("list"), [new]) + elif "map_lambda" in results: + new = ListComp(results.get("xp").clone(), + results.get("fp").clone(), + results.get("it").clone()) + else: + if "map_none" in results: + new = results["arg"].clone() + else: + if in_special_context(node): + return None + new = node.clone() + new.set_prefix("") + new = Call(Name("list"), [new]) + new.set_prefix(node.get_prefix()) + return new Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_metaclass.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_metaclass.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,227 @@ +"""Fixer for __metaclass__ = X -> (metaclass=X) methods. + + The various forms of classef (inherits nothing, inherits once, inherints + many) don't parse the same in the CST so we look at ALL classes for + a __metaclass__ and if we find one normalize the inherits to all be + an arglist. + + For one-liner classes ('class X: pass') there is no indent/dedent so + we normalize those into having a suite. + + Moving the __metaclass__ into the classdef can also cause the class + body to be empty so there is some special casing for that as well. + + This fixer also tries very hard to keep original indenting and spacing + in all those corner cases. + +""" +# Author: Jack Diederich + +# Local imports +from ... import fixer_base +from ...pygram import token +from ...fixer_util import Name, syms, Node, Leaf + + +def has_metaclass(parent): + """ we have to check the cls_node without changing it. + There are two possiblities: + 1) clsdef => suite => simple_stmt => expr_stmt => Leaf('__meta') + 2) clsdef => simple_stmt => expr_stmt => Leaf('__meta') + """ + for node in parent.children: + if node.type == syms.suite: + return has_metaclass(node) + elif node.type == syms.simple_stmt and node.children: + expr_node = node.children[0] + if expr_node.type == syms.expr_stmt and expr_node.children: + left_side = expr_node.children[0] + if isinstance(left_side, Leaf) and \ + left_side.value == '__metaclass__': + return True + return False + + +def fixup_parse_tree(cls_node): + """ one-line classes don't get a suite in the parse tree so we add + one to normalize the tree + """ + for node in cls_node.children: + if node.type == syms.suite: + # already in the prefered format, do nothing + return + + # !%@#! oneliners have no suite node, we have to fake one up + for i, node in enumerate(cls_node.children): + if node.type == token.COLON: + break + else: + raise ValueError("No class suite and no ':'!") + + # move everything into a suite node + suite = Node(syms.suite, []) + while cls_node.children[i+1:]: + move_node = cls_node.children[i+1] + suite.append_child(move_node.clone()) + move_node.remove() + cls_node.append_child(suite) + node = suite + + +def fixup_simple_stmt(parent, i, stmt_node): + """ if there is a semi-colon all the parts count as part of the same + simple_stmt. We just want the __metaclass__ part so we move + everything efter the semi-colon into its own simple_stmt node + """ + for semi_ind, node in enumerate(stmt_node.children): + if node.type == token.SEMI: # *sigh* + break + else: + return + + node.remove() # kill the semicolon + new_expr = Node(syms.expr_stmt, []) + new_stmt = Node(syms.simple_stmt, [new_expr]) + while stmt_node.children[semi_ind:]: + move_node = stmt_node.children[semi_ind] + new_expr.append_child(move_node.clone()) + move_node.remove() + parent.insert_child(i, new_stmt) + new_leaf1 = new_stmt.children[0].children[0] + old_leaf1 = stmt_node.children[0].children[0] + new_leaf1.set_prefix(old_leaf1.get_prefix()) + + +def remove_trailing_newline(node): + if node.children and node.children[-1].type == token.NEWLINE: + node.children[-1].remove() + + +def find_metas(cls_node): + # find the suite node (Mmm, sweet nodes) + for node in cls_node.children: + if node.type == syms.suite: + break + else: + raise ValueError("No class suite!") + + # look for simple_stmt[ expr_stmt[ Leaf('__metaclass__') ] ] + for i, simple_node in list(enumerate(node.children)): + if simple_node.type == syms.simple_stmt and simple_node.children: + expr_node = simple_node.children[0] + if expr_node.type == syms.expr_stmt and expr_node.children: + # Check if the expr_node is a simple assignment. + left_node = expr_node.children[0] + if isinstance(left_node, Leaf) and \ + left_node.value == '__metaclass__': + # We found a assignment to __metaclass__. + fixup_simple_stmt(node, i, simple_node) + remove_trailing_newline(simple_node) + yield (node, i, simple_node) + + +def fixup_indent(suite): + """ If an INDENT is followed by a thing with a prefix then nuke the prefix + Otherwise we get in trouble when removing __metaclass__ at suite start + """ + kids = suite.children[::-1] + # find the first indent + while kids: + node = kids.pop() + if node.type == token.INDENT: + break + + # find the first Leaf + while kids: + node = kids.pop() + if isinstance(node, Leaf) and node.type != token.DEDENT: + if node.prefix: + node.set_prefix('') + return + else: + kids.extend(node.children[::-1]) + + +class FixMetaclass(fixer_base.BaseFix): + + PATTERN = """ + classdef + """ + + def transform(self, node, results): + if not has_metaclass(node): + return node + + fixup_parse_tree(node) + + # find metaclasses, keep the last one + last_metaclass = None + for suite, i, stmt in find_metas(node): + last_metaclass = stmt + stmt.remove() + + text_type = node.children[0].type # always Leaf(nnn, 'class') + + # figure out what kind of classdef we have + if len(node.children) == 7: + # Node(classdef, ['class', 'name', '(', arglist, ')', ':', suite]) + # 0 1 2 3 4 5 6 + if node.children[3].type == syms.arglist: + arglist = node.children[3] + # Node(classdef, ['class', 'name', '(', 'Parent', ')', ':', suite]) + else: + parent = node.children[3].clone() + arglist = Node(syms.arglist, [parent]) + node.set_child(3, arglist) + elif len(node.children) == 6: + # Node(classdef, ['class', 'name', '(', ')', ':', suite]) + # 0 1 2 3 4 5 + arglist = Node(syms.arglist, []) + node.insert_child(3, arglist) + elif len(node.children) == 4: + # Node(classdef, ['class', 'name', ':', suite]) + # 0 1 2 3 + arglist = Node(syms.arglist, []) + node.insert_child(2, Leaf(token.RPAR, ')')) + node.insert_child(2, arglist) + node.insert_child(2, Leaf(token.LPAR, '(')) + else: + raise ValueError("Unexpected class definition") + + # now stick the metaclass in the arglist + meta_txt = last_metaclass.children[0].children[0] + meta_txt.value = 'metaclass' + orig_meta_prefix = meta_txt.get_prefix() + + if arglist.children: + arglist.append_child(Leaf(token.COMMA, ',')) + meta_txt.set_prefix(' ') + else: + meta_txt.set_prefix('') + + # compact the expression "metaclass = Meta" -> "metaclass=Meta" + expr_stmt = last_metaclass.children[0] + assert expr_stmt.type == syms.expr_stmt + expr_stmt.children[1].set_prefix('') + expr_stmt.children[2].set_prefix('') + + arglist.append_child(last_metaclass) + + fixup_indent(suite) + + # check for empty suite + if not suite.children: + # one-liner that was just __metaclass_ + suite.remove() + pass_leaf = Leaf(text_type, 'pass') + pass_leaf.set_prefix(orig_meta_prefix) + node.append_child(pass_leaf) + node.append_child(Leaf(token.NEWLINE, '\n')) + + elif len(suite.children) > 1 and \ + (suite.children[-2].type == token.INDENT and + suite.children[-1].type == token.DEDENT): + # there was only one line in the class body and it was __metaclass__ + pass_leaf = Leaf(text_type, 'pass') + suite.insert_child(-1, pass_leaf) + suite.insert_child(-1, Leaf(token.NEWLINE, '\n')) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_methodattrs.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_methodattrs.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,23 @@ +"""Fix bound method attributes (method.im_? -> method.__?__). +""" +# Author: Christian Heimes + +# Local imports +from ... import fixer_base +from ...fixer_util import Name + +MAP = { + "im_func" : "__func__", + "im_self" : "__self__", + "im_class" : "__self__.__class__" + } + +class FixMethodattrs(fixer_base.BaseFix): + PATTERN = """ + power< any+ trailer< '.' attr=('im_func' | 'im_self' | 'im_class') > any* > + """ + + def transform(self, node, results): + attr = results["attr"][0] + new = MAP[attr.value] + attr.replace(Name(new, prefix=attr.get_prefix())) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_ne.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_ne.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,22 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer that turns <> into !=.""" + +# Local imports +from ... import pytree +from ...pgen2 import token +from ... import fixer_base + + +class FixNe(fixer_base.BaseFix): + # This is so simple that we don't need the pattern compiler. + + def match(self, node): + # Override + return node.type == token.NOTEQUAL and node.value == "<>" + + def transform(self, node, results): + new = pytree.Leaf(token.NOTEQUAL, "!=") + new.set_prefix(node.get_prefix()) + return new Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_next.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_next.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,103 @@ +"""Fixer for it.next() -> next(it), per PEP 3114.""" +# Author: Collin Winter + +# Things that currently aren't covered: +# - listcomp "next" names aren't warned +# - "with" statement targets aren't checked + +# Local imports +from ...pgen2 import token +from ...pygram import python_symbols as syms +from ... import fixer_base +from ...fixer_util import Name, Call, find_binding + +bind_warning = "Calls to builtin next() possibly shadowed by global binding" + + +class FixNext(fixer_base.BaseFix): + PATTERN = """ + power< base=any+ trailer< '.' attr='next' > trailer< '(' ')' > > + | + power< head=any+ trailer< '.' attr='next' > not trailer< '(' ')' > > + | + classdef< 'class' any+ ':' + suite< any* + funcdef< 'def' + name='next' + parameters< '(' NAME ')' > any+ > + any* > > + | + global=global_stmt< 'global' any* 'next' any* > + """ + + order = "pre" # Pre-order tree traversal + + def start_tree(self, tree, filename): + super(FixNext, self).start_tree(tree, filename) + + n = find_binding('next', tree) + if n: + self.warning(n, bind_warning) + self.shadowed_next = True + else: + self.shadowed_next = False + + def transform(self, node, results): + assert results + + base = results.get("base") + attr = results.get("attr") + name = results.get("name") + mod = results.get("mod") + + if base: + if self.shadowed_next: + attr.replace(Name("__next__", prefix=attr.get_prefix())) + else: + base = [n.clone() for n in base] + base[0].set_prefix("") + node.replace(Call(Name("next", prefix=node.get_prefix()), base)) + elif name: + n = Name("__next__", prefix=name.get_prefix()) + name.replace(n) + elif attr: + # We don't do this transformation if we're assigning to "x.next". + # Unfortunately, it doesn't seem possible to do this in PATTERN, + # so it's being done here. + if is_assign_target(node): + head = results["head"] + if "".join([str(n) for n in head]).strip() == '__builtin__': + self.warning(node, bind_warning) + return + attr.replace(Name("__next__")) + elif "global" in results: + self.warning(node, bind_warning) + self.shadowed_next = True + + +### The following functions help test if node is part of an assignment +### target. + +def is_assign_target(node): + assign = find_assign(node) + if assign is None: + return False + + for child in assign.children: + if child.type == token.EQUAL: + return False + elif is_subtree(child, node): + return True + return False + +def find_assign(node): + if node.type == syms.expr_stmt: + return node + if node.type == syms.simple_stmt or node.parent is None: + return None + return find_assign(node.parent) + +def is_subtree(root, node): + if root == node: + return True + return any([is_subtree(c, node) for c in root.children]) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_nonzero.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_nonzero.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,20 @@ +"""Fixer for __nonzero__ -> __bool__ methods.""" +# Author: Collin Winter + +# Local imports +from ... import fixer_base +from ...fixer_util import Name, syms + +class FixNonzero(fixer_base.BaseFix): + PATTERN = """ + classdef< 'class' any+ ':' + suite< any* + funcdef< 'def' name='__nonzero__' + parameters< '(' NAME ')' > any+ > + any* > > + """ + + def transform(self, node, results): + name = results["name"] + new = Name("__bool__", prefix=name.get_prefix()) + name.replace(new) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_numliterals.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_numliterals.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,27 @@ +"""Fixer that turns 1L into 1, 0755 into 0o755. +""" +# Copyright 2007 Georg Brandl. +# Licensed to PSF under a Contributor Agreement. + +# Local imports +from ...pgen2 import token +from ... import fixer_base +from ...fixer_util import Number + + +class FixNumliterals(fixer_base.BaseFix): + # This is so simple that we don't need the pattern compiler. + + def match(self, node): + # Override + return (node.type == token.NUMBER and + (node.value.startswith("0") or node.value[-1] in "Ll")) + + def transform(self, node, results): + val = node.value + if val[-1] in 'Ll': + val = val[:-1] + elif val.startswith('0') and val.isdigit() and len(set(val)) > 1: + val = "0o" + val[1:] + + return Number(val, prefix=node.get_prefix()) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_paren.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_paren.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,42 @@ +"""Fixer that addes parentheses where they are required + +This converts ``[x for x in 1, 2]`` to ``[x for x in (1, 2)]``.""" + +# By Taek Joo Kim and Benjamin Peterson + +# Local imports +from ... import fixer_base +from ...fixer_util import LParen, RParen + +# XXX This doesn't support nested for loops like [x for x in 1, 2 for x in 1, 2] +class FixParen(fixer_base.BaseFix): + PATTERN = """ + atom< ('[' | '(') + (listmaker< any + comp_for< + 'for' NAME 'in' + target=testlist_safe< any (',' any)+ [','] + > + [any] + > + > + | + testlist_gexp< any + comp_for< + 'for' NAME 'in' + target=testlist_safe< any (',' any)+ [','] + > + [any] + > + >) + (']' | ')') > + """ + + def transform(self, node, results): + target = results["target"] + + lparen = LParen() + lparen.set_prefix(target.get_prefix()) + target.set_prefix("") # Make it hug the parentheses + target.insert_child(0, lparen) + target.append_child(RParen()) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_print.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_print.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,90 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer for print. + +Change: + 'print' into 'print()' + 'print ...' into 'print(...)' + 'print ... ,' into 'print(..., end=" ")' + 'print >>x, ...' into 'print(..., file=x)' + +No changes are applied if print_function is imported from __future__ + +""" + +# Local imports +from ... import patcomp +from ... import pytree +from ...pgen2 import token +from ... import fixer_base +from ...fixer_util import Name, Call, Comma, String, is_tuple + + +parend_expr = patcomp.compile_pattern( + """atom< '(' [atom|STRING|NAME] ')' >""" + ) + + +class FixPrint(fixer_base.ConditionalFix): + + PATTERN = """ + simple_stmt< any* bare='print' any* > | print_stmt + """ + + skip_on = '__future__.print_function' + + def transform(self, node, results): + assert results + + if self.should_skip(node): + return + + bare_print = results.get("bare") + + if bare_print: + # Special-case print all by itself + bare_print.replace(Call(Name("print"), [], + prefix=bare_print.get_prefix())) + return + assert node.children[0] == Name("print") + args = node.children[1:] + if len(args) == 1 and parend_expr.match(args[0]): + # We don't want to keep sticking parens around an + # already-parenthesised expression. + return + + sep = end = file = None + if args and args[-1] == Comma(): + args = args[:-1] + end = " " + if args and args[0] == pytree.Leaf(token.RIGHTSHIFT, ">>"): + assert len(args) >= 2 + file = args[1].clone() + args = args[3:] # Strip a possible comma after the file expression + # Now synthesize a print(args, sep=..., end=..., file=...) node. + l_args = [arg.clone() for arg in args] + if l_args: + l_args[0].set_prefix("") + if sep is not None or end is not None or file is not None: + if sep is not None: + self.add_kwarg(l_args, "sep", String(repr(sep))) + if end is not None: + self.add_kwarg(l_args, "end", String(repr(end))) + if file is not None: + self.add_kwarg(l_args, "file", file) + n_stmt = Call(Name("print"), l_args) + n_stmt.set_prefix(node.get_prefix()) + return n_stmt + + def add_kwarg(self, l_nodes, s_kwd, n_expr): + # XXX All this prefix-setting may lose comments (though rarely) + n_expr.set_prefix("") + n_argument = pytree.Node(self.syms.argument, + (Name(s_kwd), + pytree.Leaf(token.EQUAL, "="), + n_expr)) + if l_nodes: + l_nodes.append(Comma()) + n_argument.set_prefix(" ") + l_nodes.append(n_argument) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_raise.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_raise.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,82 @@ +"""Fixer for 'raise E, V, T' + +raise -> raise +raise E -> raise E +raise E, V -> raise E(V) +raise E, V, T -> raise E(V).with_traceback(T) + +raise (((E, E'), E''), E'''), V -> raise E(V) +raise "foo", V, T -> warns about string exceptions + + +CAVEATS: +1) "raise E, V" will be incorrectly translated if V is an exception + instance. The correct Python 3 idiom is + + raise E from V + + but since we can't detect instance-hood by syntax alone and since + any client code would have to be changed as well, we don't automate + this. +""" +# Author: Collin Winter + +# Local imports +from ... import pytree +from ...pgen2 import token +from ... import fixer_base +from ...fixer_util import Name, Call, Attr, ArgList, is_tuple + +class FixRaise(fixer_base.BaseFix): + + PATTERN = """ + raise_stmt< 'raise' exc=any [',' val=any [',' tb=any]] > + """ + + def transform(self, node, results): + syms = self.syms + + exc = results["exc"].clone() + if exc.type is token.STRING: + self.cannot_convert(node, "Python 3 does not support string exceptions") + return + + # Python 2 supports + # raise ((((E1, E2), E3), E4), E5), V + # as a synonym for + # raise E1, V + # Since Python 3 will not support this, we recurse down any tuple + # literals, always taking the first element. + if is_tuple(exc): + while is_tuple(exc): + # exc.children[1:-1] is the unparenthesized tuple + # exc.children[1].children[0] is the first element of the tuple + exc = exc.children[1].children[0].clone() + exc.set_prefix(" ") + + if "val" not in results: + # One-argument raise + new = pytree.Node(syms.raise_stmt, [Name("raise"), exc]) + new.set_prefix(node.get_prefix()) + return new + + val = results["val"].clone() + if is_tuple(val): + args = [c.clone() for c in val.children[1:-1]] + else: + val.set_prefix("") + args = [val] + + if "tb" in results: + tb = results["tb"].clone() + tb.set_prefix("") + + e = Call(exc, args) + with_tb = Attr(e, Name('with_traceback')) + [ArgList([tb])] + new = pytree.Node(syms.simple_stmt, [Name("raise")] + with_tb) + new.set_prefix(node.get_prefix()) + return new + else: + return pytree.Node(syms.raise_stmt, + [Name("raise"), Call(exc, args)], + prefix=node.get_prefix()) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_raw_input.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_raw_input.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,16 @@ +"""Fixer that changes raw_input(...) into input(...).""" +# Author: Andre Roberge + +# Local imports +from ... import fixer_base +from ...fixer_util import Name + +class FixRawInput(fixer_base.BaseFix): + + PATTERN = """ + power< name='raw_input' trailer< '(' [any] ')' > any* > + """ + + def transform(self, node, results): + name = results["name"] + name.replace(Name("input", prefix=name.get_prefix())) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_reduce.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_reduce.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,33 @@ +# Copyright 2008 Armin Ronacher. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer for reduce(). + +Makes sure reduce() is imported from the functools module if reduce is +used in that module. +""" + +from ... import pytree +from ... import fixer_base +from ...fixer_util import Name, Attr, touch_import + + + +class FixReduce(fixer_base.BaseFix): + + PATTERN = """ + power< 'reduce' + trailer< '(' + arglist< ( + (not(argument) any ',' + not(argument + > + """ + + def transform(self, node, results): + touch_import('functools', 'reduce', node) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_renames.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_renames.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,69 @@ +"""Fix incompatible renames + +Fixes: + * sys.maxint -> sys.maxsize +""" +# Author: Christian Heimes +# based on Collin Winter's fix_import + +# Local imports +from ... import fixer_base +from ...fixer_util import Name, attr_chain + +MAPPING = {"sys": {"maxint" : "maxsize"}, + } +LOOKUP = {} + +def alternates(members): + return "(" + "|".join(map(repr, members)) + ")" + + +def build_pattern(): + #bare = set() + for module, replace in MAPPING.items(): + for old_attr, new_attr in replace.items(): + LOOKUP[(module, old_attr)] = new_attr + #bare.add(module) + #bare.add(old_attr) + #yield """ + # import_name< 'import' (module=%r + # | dotted_as_names< any* module=%r any* >) > + # """ % (module, module) + yield """ + import_from< 'from' module_name=%r 'import' + ( attr_name=%r | import_as_name< attr_name=%r 'as' any >) > + """ % (module, old_attr, old_attr) + yield """ + power< module_name=%r trailer< '.' attr_name=%r > any* > + """ % (module, old_attr) + #yield """bare_name=%s""" % alternates(bare) + + +class FixRenames(fixer_base.BaseFix): + PATTERN = "|".join(build_pattern()) + + order = "pre" # Pre-order tree traversal + + # Don't match the node if it's within another match + def match(self, node): + match = super(FixRenames, self).match + results = match(node) + if results: + if any([match(obj) for obj in attr_chain(node, "parent")]): + return False + return results + return False + + #def start_tree(self, tree, filename): + # super(FixRenames, self).start_tree(tree, filename) + # self.replace = {} + + def transform(self, node, results): + mod_name = results.get("module_name") + attr_name = results.get("attr_name") + #bare_name = results.get("bare_name") + #import_mod = results.get("module") + + if mod_name and attr_name: + new_attr = LOOKUP[(mod_name.value, attr_name.value)] + attr_name.replace(Name(new_attr, prefix=attr_name.get_prefix())) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_repr.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_repr.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,22 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer that transforms `xyzzy` into repr(xyzzy).""" + +# Local imports +from ... import fixer_base +from ...fixer_util import Call, Name, parenthesize + + +class FixRepr(fixer_base.BaseFix): + + PATTERN = """ + atom < '`' expr=any '`' > + """ + + def transform(self, node, results): + expr = results["expr"].clone() + + if expr.type == self.syms.testlist1: + expr = parenthesize(expr) + return Call(Name("repr"), [expr], prefix=node.get_prefix()) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_set_literal.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_set_literal.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,50 @@ +""" +Optional fixer to transform set() calls to set literals. +""" + +# Author: Benjamin Peterson + +from ... import fixer_base, pytree +from ...fixer_util import token, syms + +class FixSetLiteral(fixer_base.BaseFix): + + explicit = True + + PATTERN = """power< 'set' trailer< '(' + (atom=atom< '[' (items=listmaker< any ((',' any)* [',']) > + | + single=any) ']' > + | + atom< '(' items=testlist_gexp< any ((',' any)* [',']) > ')' > + ) + ')' > > + """ + + def transform(self, node, results): + single = results.get("single") + if single: + # Make a fake listmaker + fake = pytree.Node(syms.listmaker, [single.clone()]) + single.replace(fake) + items = fake + else: + items = results["items"] + + # Build the contents of the literal + literal = [pytree.Leaf(token.LBRACE, "{")] + literal.extend(n.clone() for n in items.children) + literal.append(pytree.Leaf(token.RBRACE, "}")) + # Set the prefix of the right brace to that of the ')' or ']' + literal[-1].set_prefix(items.next_sibling.get_prefix()) + maker = pytree.Node(syms.dictsetmaker, literal) + maker.set_prefix(node.get_prefix()) + + # If the original was a one tuple, we need to remove the extra comma. + if len(maker.children) == 4: + n = maker.children[2] + n.remove() + maker.children[-1].set_prefix(n.get_prefix()) + + # Finally, replace the set call with our shiny new literal. + return maker Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_standarderror.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_standarderror.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,18 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer for StandardError -> Exception.""" + +# Local imports +from ... import fixer_base +from ...fixer_util import Name + + +class FixStandarderror(fixer_base.BaseFix): + + PATTERN = """ + 'StandardError' + """ + + def transform(self, node, results): + return Name("Exception", prefix=node.get_prefix()) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_sys_exc.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_sys_exc.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,29 @@ +"""Fixer for sys.exc_{type, value, traceback} + +sys.exc_type -> sys.exc_info()[0] +sys.exc_value -> sys.exc_info()[1] +sys.exc_traceback -> sys.exc_info()[2] +""" + +# By Jeff Balogh and Benjamin Peterson + +# Local imports +from ... import fixer_base +from ...fixer_util import Attr, Call, Name, Number, Subscript, Node, syms + +class FixSysExc(fixer_base.BaseFix): + # This order matches the ordering of sys.exc_info(). + exc_info = ["exc_type", "exc_value", "exc_traceback"] + PATTERN = """ + power< 'sys' trailer< dot='.' attribute=(%s) > > + """ % '|'.join("'%s'" % e for e in exc_info) + + def transform(self, node, results): + sys_attr = results["attribute"][0] + index = Number(self.exc_info.index(sys_attr.value)) + + call = Call(Name("exc_info"), prefix=sys_attr.get_prefix()) + attr = Attr(Name("sys"), call) + attr[1].children[0].set_prefix(results["dot"].get_prefix()) + attr.append(Subscript(index)) + return Node(syms.power, attr, prefix=node.get_prefix()) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_throw.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_throw.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,56 @@ +"""Fixer for generator.throw(E, V, T). + +g.throw(E) -> g.throw(E) +g.throw(E, V) -> g.throw(E(V)) +g.throw(E, V, T) -> g.throw(E(V).with_traceback(T)) + +g.throw("foo"[, V[, T]]) will warn about string exceptions.""" +# Author: Collin Winter + +# Local imports +from ... import pytree +from ...pgen2 import token +from ... import fixer_base +from ...fixer_util import Name, Call, ArgList, Attr, is_tuple + +class FixThrow(fixer_base.BaseFix): + + PATTERN = """ + power< any trailer< '.' 'throw' > + trailer< '(' args=arglist< exc=any ',' val=any [',' tb=any] > ')' > + > + | + power< any trailer< '.' 'throw' > trailer< '(' exc=any ')' > > + """ + + def transform(self, node, results): + syms = self.syms + + exc = results["exc"].clone() + if exc.type is token.STRING: + self.cannot_convert(node, "Python 3 does not support string exceptions") + return + + # Leave "g.throw(E)" alone + val = results.get("val") + if val is None: + return + + val = val.clone() + if is_tuple(val): + args = [c.clone() for c in val.children[1:-1]] + else: + val.set_prefix("") + args = [val] + + throw_args = results["args"] + + if "tb" in results: + tb = results["tb"].clone() + tb.set_prefix("") + + e = Call(exc, args) + with_tb = Attr(e, Name('with_traceback')) + [ArgList([tb])] + throw_args.replace(pytree.Node(syms.power, with_tb)) + else: + throw_args.replace(Call(exc, args)) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_tuple_params.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_tuple_params.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,169 @@ +"""Fixer for function definitions with tuple parameters. + +def func(((a, b), c), d): + ... + + -> + +def func(x, d): + ((a, b), c) = x + ... + +It will also support lambdas: + + lambda (x, y): x + y -> lambda t: t[0] + t[1] + + # The parens are a syntax error in Python 3 + lambda (x): x + y -> lambda x: x + y +""" +# Author: Collin Winter + +# Local imports +from ... import pytree +from ...pgen2 import token +from ... import fixer_base +from ...fixer_util import Assign, Name, Newline, Number, Subscript, syms + +def is_docstring(stmt): + return isinstance(stmt, pytree.Node) and \ + stmt.children[0].type == token.STRING + +class FixTupleParams(fixer_base.BaseFix): + PATTERN = """ + funcdef< 'def' any parameters< '(' args=any ')' > + ['->' any] ':' suite=any+ > + | + lambda= + lambdef< 'lambda' args=vfpdef< '(' inner=any ')' > + ':' body=any + > + """ + + def transform(self, node, results): + if "lambda" in results: + return self.transform_lambda(node, results) + + new_lines = [] + suite = results["suite"] + args = results["args"] + # This crap is so "def foo(...): x = 5; y = 7" is handled correctly. + # TODO(cwinter): suite-cleanup + if suite[0].children[1].type == token.INDENT: + start = 2 + indent = suite[0].children[1].value + end = Newline() + else: + start = 0 + indent = "; " + end = pytree.Leaf(token.INDENT, "") + + # We need access to self for new_name(), and making this a method + # doesn't feel right. Closing over self and new_lines makes the + # code below cleaner. + def handle_tuple(tuple_arg, add_prefix=False): + n = Name(self.new_name()) + arg = tuple_arg.clone() + arg.set_prefix("") + stmt = Assign(arg, n.clone()) + if add_prefix: + n.set_prefix(" ") + tuple_arg.replace(n) + new_lines.append(pytree.Node(syms.simple_stmt, + [stmt, end.clone()])) + + if args.type == syms.tfpdef: + handle_tuple(args) + elif args.type == syms.typedargslist: + for i, arg in enumerate(args.children): + if arg.type == syms.tfpdef: + # Without add_prefix, the emitted code is correct, + # just ugly. + handle_tuple(arg, add_prefix=(i > 0)) + + if not new_lines: + return node + + # This isn't strictly necessary, but it plays nicely with other fixers. + # TODO(cwinter) get rid of this when children becomes a smart list + for line in new_lines: + line.parent = suite[0] + + # TODO(cwinter) suite-cleanup + after = start + if start == 0: + new_lines[0].set_prefix(" ") + elif is_docstring(suite[0].children[start]): + new_lines[0].set_prefix(indent) + after = start + 1 + + suite[0].children[after:after] = new_lines + for i in range(after+1, after+len(new_lines)+1): + suite[0].children[i].set_prefix(indent) + suite[0].changed() + + def transform_lambda(self, node, results): + args = results["args"] + body = results["body"] + inner = simplify_args(results["inner"]) + + # Replace lambda ((((x)))): x with lambda x: x + if inner.type == token.NAME: + inner = inner.clone() + inner.set_prefix(" ") + args.replace(inner) + return + + params = find_params(args) + to_index = map_to_index(params) + tup_name = self.new_name(tuple_name(params)) + + new_param = Name(tup_name, prefix=" ") + args.replace(new_param.clone()) + for n in body.post_order(): + if n.type == token.NAME and n.value in to_index: + subscripts = [c.clone() for c in to_index[n.value]] + new = pytree.Node(syms.power, + [new_param.clone()] + subscripts) + new.set_prefix(n.get_prefix()) + n.replace(new) + + +### Helper functions for transform_lambda() + +def simplify_args(node): + if node.type in (syms.vfplist, token.NAME): + return node + elif node.type == syms.vfpdef: + # These look like vfpdef< '(' x ')' > where x is NAME + # or another vfpdef instance (leading to recursion). + while node.type == syms.vfpdef: + node = node.children[1] + return node + raise RuntimeError("Received unexpected node %s" % node) + +def find_params(node): + if node.type == syms.vfpdef: + return find_params(node.children[1]) + elif node.type == token.NAME: + return node.value + return [find_params(c) for c in node.children if c.type != token.COMMA] + +def map_to_index(param_list, prefix=[], d=None): + if d is None: + d = {} + for i, obj in enumerate(param_list): + trailer = [Subscript(Number(i))] + if isinstance(obj, list): + map_to_index(obj, trailer, d=d) + else: + d[obj] = prefix + trailer + return d + +def tuple_name(param_list): + l = [] + for obj in param_list: + if isinstance(obj, list): + l.append(tuple_name(obj)) + else: + l.append(obj) + return "_".join(l) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_types.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_types.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,62 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer for removing uses of the types module. + +These work for only the known names in the types module. The forms above +can include types. or not. ie, It is assumed the module is imported either as: + + import types + from types import ... # either * or specific types + +The import statements are not modified. + +There should be another fixer that handles at least the following constants: + + type([]) -> list + type(()) -> tuple + type('') -> str + +""" + +# Local imports +from ...pgen2 import token +from ... import fixer_base +from ...fixer_util import Name + +_TYPE_MAPPING = { + 'BooleanType' : 'bool', + 'BufferType' : 'memoryview', + 'ClassType' : 'type', + 'ComplexType' : 'complex', + 'DictType': 'dict', + 'DictionaryType' : 'dict', + 'EllipsisType' : 'type(Ellipsis)', + #'FileType' : 'io.IOBase', + 'FloatType': 'float', + 'IntType': 'int', + 'ListType': 'list', + 'LongType': 'int', + 'ObjectType' : 'object', + 'NoneType': 'type(None)', + 'NotImplementedType' : 'type(NotImplemented)', + 'SliceType' : 'slice', + 'StringType': 'bytes', # XXX ? + 'StringTypes' : 'str', # XXX ? + 'TupleType': 'tuple', + 'TypeType' : 'type', + 'UnicodeType': 'str', + 'XRangeType' : 'range', + } + +_pats = ["power< 'types' trailer< '.' name='%s' > >" % t for t in _TYPE_MAPPING] + +class FixTypes(fixer_base.BaseFix): + + PATTERN = '|'.join(_pats) + + def transform(self, node, results): + new_value = _TYPE_MAPPING.get(results["name"].value) + if new_value: + return Name(new_value, prefix=node.get_prefix()) + return None Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_unicode.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_unicode.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,28 @@ +"""Fixer that changes unicode to str, unichr to chr, and u"..." into "...". + +""" + +import re +from ...pgen2 import token +from ... import fixer_base + +class FixUnicode(fixer_base.BaseFix): + + PATTERN = "STRING | NAME<'unicode' | 'unichr'>" + + def transform(self, node, results): + if node.type == token.NAME: + if node.value == "unicode": + new = node.clone() + new.value = "str" + return new + if node.value == "unichr": + new = node.clone() + new.value = "chr" + return new + # XXX Warn when __unicode__ found? + elif node.type == token.STRING: + if re.match(r"[uU][rR]?[\'\"]", node.value): + new = node.clone() + new.value = new.value[1:] + return new Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_urllib.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_urllib.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,180 @@ +"""Fix changes imports of urllib which are now incompatible. + This is rather similar to fix_imports, but because of the more + complex nature of the fixing for urllib, it has its own fixer. +""" +# Author: Nick Edds + +# Local imports +from .fix_imports import alternates, FixImports +from ... import fixer_base +from ...fixer_util import Name, Comma, FromImport, Newline, attr_chain + +MAPPING = {'urllib': [ + ('urllib.request', + ['URLOpener', 'FancyURLOpener', 'urlretrieve', + '_urlopener', 'urlcleanup']), + ('urllib.parse', + ['quote', 'quote_plus', 'unquote', 'unquote_plus', + 'urlencode', 'pathname2url', 'url2pathname', 'splitattr', + 'splithost', 'splitnport', 'splitpasswd', 'splitport', + 'splitquery', 'splittag', 'splittype', 'splituser', + 'splitvalue', ]), + ('urllib.error', + ['ContentTooShortError'])], + 'urllib2' : [ + ('urllib.request', + ['urlopen', 'install_opener', 'build_opener', + 'Request', 'OpenerDirector', 'BaseHandler', + 'HTTPDefaultErrorHandler', 'HTTPRedirectHandler', + 'HTTPCookieProcessor', 'ProxyHandler', + 'HTTPPasswordMgr', + 'HTTPPasswordMgrWithDefaultRealm', + 'AbstractBasicAuthHandler', + 'HTTPBasicAuthHandler', 'ProxyBasicAuthHandler', + 'AbstractDigestAuthHandler', + 'HTTPDigestAuthHandler', 'ProxyDigestAuthHandler', + 'HTTPHandler', 'HTTPSHandler', 'FileHandler', + 'FTPHandler', 'CacheFTPHandler', + 'UnknownHandler']), + ('urllib.error', + ['URLError', 'HTTPError']), + ] +} + +# Duplicate the url parsing functions for urllib2. +MAPPING["urllib2"].append(MAPPING["urllib"][1]) + + +def build_pattern(): + bare = set() + for old_module, changes in MAPPING.items(): + for change in changes: + new_module, members = change + members = alternates(members) + yield """import_name< 'import' (module=%r + | dotted_as_names< any* module=%r any* >) > + """ % (old_module, old_module) + yield """import_from< 'from' mod_member=%r 'import' + ( member=%s | import_as_name< member=%s 'as' any > | + import_as_names< members=any* >) > + """ % (old_module, members, members) + yield """import_from< 'from' module_star=%r 'import' star='*' > + """ % old_module + yield """import_name< 'import' + dotted_as_name< module_as=%r 'as' any > > + """ % old_module + yield """power< module_dot=%r trailer< '.' member=%s > any* > + """ % (old_module, members) + + +class FixUrllib(FixImports): + + def build_pattern(self): + return "|".join(build_pattern()) + + def transform_import(self, node, results): + """Transform for the basic import case. Replaces the old + import name with a comma separated list of its + replacements. + """ + import_mod = results.get('module') + pref = import_mod.get_prefix() + + names = [] + + # create a Node list of the replacement modules + for name in MAPPING[import_mod.value][:-1]: + names.extend([Name(name[0], prefix=pref), Comma()]) + names.append(Name(MAPPING[import_mod.value][-1][0], prefix=pref)) + import_mod.replace(names) + + def transform_member(self, node, results): + """Transform for imports of specific module elements. Replaces + the module to be imported from with the appropriate new + module. + """ + mod_member = results.get('mod_member') + pref = mod_member.get_prefix() + member = results.get('member') + + # Simple case with only a single member being imported + if member: + # this may be a list of length one, or just a node + if isinstance(member, list): + member = member[0] + new_name = None + for change in MAPPING[mod_member.value]: + if member.value in change[1]: + new_name = change[0] + break + if new_name: + mod_member.replace(Name(new_name, prefix=pref)) + else: + self.cannot_convert(node, + 'This is an invalid module element') + + # Multiple members being imported + else: + # a dictionary for replacements, order matters + modules = [] + mod_dict = {} + members = results.get('members') + for member in members: + member = member.value + # we only care about the actual members + if member != ',': + for change in MAPPING[mod_member.value]: + if member in change[1]: + if change[0] in mod_dict: + mod_dict[change[0]].append(member) + else: + mod_dict[change[0]] = [member] + modules.append(change[0]) + + new_nodes = [] + for module in modules: + elts = mod_dict[module] + names = [] + for elt in elts[:-1]: + names.extend([Name(elt, prefix=pref), Comma()]) + names.append(Name(elts[-1], prefix=pref)) + new_nodes.append(FromImport(module, names)) + if new_nodes: + nodes = [] + for new_node in new_nodes[:-1]: + nodes.extend([new_node, Newline()]) + nodes.append(new_nodes[-1]) + node.replace(nodes) + else: + self.cannot_convert(node, 'All module elements are invalid') + + def transform_dot(self, node, results): + """Transform for calls to module members in code.""" + module_dot = results.get('module_dot') + member = results.get('member') + # this may be a list of length one, or just a node + if isinstance(member, list): + member = member[0] + new_name = None + for change in MAPPING[module_dot.value]: + if member.value in change[1]: + new_name = change[0] + break + if new_name: + module_dot.replace(Name(new_name, + prefix=module_dot.get_prefix())) + else: + self.cannot_convert(node, 'This is an invalid module element') + + def transform(self, node, results): + if results.get('module'): + self.transform_import(node, results) + elif results.get('mod_member'): + self.transform_member(node, results) + elif results.get('module_dot'): + self.transform_dot(node, results) + # Renaming and star imports are not supported for these modules. + elif results.get('module_star'): + self.cannot_convert(node, 'Cannot handle star imports.') + elif results.get('module_as'): + self.cannot_convert(node, 'This module is now multiple modules') Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_ws_comma.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_ws_comma.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,39 @@ +"""Fixer that changes 'a ,b' into 'a, b'. + +This also changes '{a :b}' into '{a: b}', but does not touch other +uses of colons. It does not touch other uses of whitespace. + +""" + +from ... import pytree +from ...pgen2 import token +from ... import fixer_base + +class FixWsComma(fixer_base.BaseFix): + + explicit = True # The user must ask for this fixers + + PATTERN = """ + any<(not(',') any)+ ',' ((not(',') any)+ ',')* [not(',') any]> + """ + + COMMA = pytree.Leaf(token.COMMA, ",") + COLON = pytree.Leaf(token.COLON, ":") + SEPS = (COMMA, COLON) + + def transform(self, node, results): + new = node.clone() + comma = False + for child in new.children: + if child in self.SEPS: + prefix = child.get_prefix() + if prefix.isspace() and "\n" not in prefix: + child.set_prefix("") + comma = True + else: + if comma: + prefix = child.get_prefix() + if not prefix: + child.set_prefix(" ") + comma = False + return new Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_xrange.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_xrange.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,64 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Fixer that changes xrange(...) into range(...).""" + +# Local imports +from ... import fixer_base +from ...fixer_util import Name, Call, consuming_calls +from ... import patcomp + + +class FixXrange(fixer_base.BaseFix): + + PATTERN = """ + power< + (name='range'|name='xrange') trailer< '(' args=any ')' > + rest=any* > + """ + + def transform(self, node, results): + name = results["name"] + if name.value == "xrange": + return self.transform_xrange(node, results) + elif name.value == "range": + return self.transform_range(node, results) + else: + raise ValueError(repr(name)) + + def transform_xrange(self, node, results): + name = results["name"] + name.replace(Name("range", prefix=name.get_prefix())) + + def transform_range(self, node, results): + if not self.in_special_context(node): + range_call = Call(Name("range"), [results["args"].clone()]) + # Encase the range call in list(). + list_call = Call(Name("list"), [range_call], + prefix=node.get_prefix()) + # Put things that were after the range() call after the list call. + for n in results["rest"]: + list_call.append_child(n) + return list_call + return node + + P1 = "power< func=NAME trailer< '(' node=any ')' > any* >" + p1 = patcomp.compile_pattern(P1) + + P2 = """for_stmt< 'for' any 'in' node=any ':' any* > + | comp_for< 'for' any 'in' node=any any* > + | comparison< any 'in' node=any any*> + """ + p2 = patcomp.compile_pattern(P2) + + def in_special_context(self, node): + if node.parent is None: + return False + results = {} + if (node.parent.parent is not None and + self.p1.match(node.parent.parent, results) and + results["node"] is node): + # list(d.keys()) -> list(d.keys()), etc. + return results["func"].value in consuming_calls + # for ... in d.iterkeys() -> for ... in d.keys(), etc. + return self.p2.match(node.parent, results) and results["node"] is node Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_xreadlines.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_xreadlines.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,24 @@ +"""Fix "for x in f.xreadlines()" -> "for x in f". + +This fixer will also convert g(f.xreadlines) into g(f.__iter__).""" +# Author: Collin Winter + +# Local imports +from ... import fixer_base +from ...fixer_util import Name + + +class FixXreadlines(fixer_base.BaseFix): + PATTERN = """ + power< call=any+ trailer< '.' 'xreadlines' > trailer< '(' ')' > > + | + power< any+ trailer< '.' no_call='xreadlines' > > + """ + + def transform(self, node, results): + no_call = results.get("no_call") + + if no_call: + no_call.replace(Name("__iter__", prefix=no_call.get_prefix())) + else: + node.replace([x.clone() for x in results["call"]]) Added: sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_zip.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from2/fix_zip.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,34 @@ +""" +Fixer that changes zip(seq0, seq1, ...) into list(zip(seq0, seq1, ...) +unless there exists a 'from future_builtins import zip' statement in the +top-level namespace. + +We avoid the transformation if the zip() call is directly contained in +iter(<>), list(<>), tuple(<>), sorted(<>), ...join(<>), or for V in <>:. +""" + +# Local imports +from ... import fixer_base +from ...fixer_util import Name, Call, in_special_context + +class FixZip(fixer_base.ConditionalFix): + + PATTERN = """ + power< 'zip' args=trailer< '(' [any] ')' > + > + """ + + skip_on = "future_builtins.zip" + + def transform(self, node, results): + if self.should_skip(node): + return + + if in_special_context(node): + return None + + new = node.clone() + new.set_prefix("") + new = Call(Name("list"), [new]) + new.set_prefix(node.get_prefix()) + return new Added: sandbox/trunk/refactor_pkg/refactor/fixes/from3/__init__.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from3/__init__.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,2 @@ +from . import fix_range +from . import fix_renames Added: sandbox/trunk/refactor_pkg/refactor/fixes/from3/fix_range.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from3/fix_range.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,21 @@ +# Based on fix_xrange.py +# 3to2 modification by Paul Kippes + +""" +range(...) -> xrange(...) +""" + +from ..fixer_common import * + +class FixRange(fixer_base.BaseFix): + + PATTERN = """ + power< + (name='range') trailer< '(' args=any ')' > + rest=any* > + """ + + def transform(self, node, results): + name = results["name"] + name.replace(Name("xrange", prefix=name.get_prefix())) + return node Added: sandbox/trunk/refactor_pkg/refactor/fixes/from3/fix_renames.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from3/fix_renames.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,69 @@ +"""Fix incompatible renames + +Incorporates simple compliment 3-to-2 transforms: + +Fixes: + * sys.maxsize -> sys.maxint +""" + +# Local imports +from ..fixer_common import * + +MAPPING = {'sys': {'maxsize' : 'maxint', + }, + } +LOOKUP = {} + +def alternates(members): + return "(" + "|".join(map(repr, members)) + ")" + + +def build_pattern(): + #bare = set() + for module, replace in MAPPING.items(): + for old_attr, new_attr in replace.items(): + LOOKUP[(module, old_attr)] = new_attr + #bare.add(module) + #bare.add(old_attr) + #yield """ + # import_name< 'import' (module=%r + # | dotted_as_names< any* module=%r any* >) > + # """ % (module, module) + yield """ + import_from< 'from' module_name=%r 'import' + ( attr_name=%r | import_as_name< attr_name=%r 'as' any >) > + """ % (module, old_attr, old_attr) + yield """ + power< module_name=%r trailer< '.' attr_name=%r > any* > + """ % (module, old_attr) + #yield """bare_name=%s""" % alternates(bare) + + +class FixRenames(fixer_base.BaseFix): + PATTERN = "|".join(build_pattern()) + + order = "pre" # Pre-order tree traversal + + # Don't match the node if it's within another match + def match(self, node): + match = super(FixRenames, self).match + results = match(node) + if results: + if any([match(obj) for obj in attr_chain(node, "parent")]): + return False + return results + return False + + #def start_tree(self, tree, filename): + # super(FixRenames, self).start_tree(tree, filename) + # self.replace = {} + + def transform(self, node, results): + mod_name = results.get("module_name") + attr_name = results.get("attr_name") + #bare_name = results.get("bare_name") + #import_mod = results.get("module") + + if mod_name and attr_name: + new_attr = LOOKUP[(mod_name.value, attr_name.value)] + attr_name.replace(Name(new_attr, prefix=attr_name.get_prefix())) Added: sandbox/trunk/refactor_pkg/refactor/main.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/main.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,134 @@ +""" +Main program for refactor. +""" + +import sys +import os +import logging +import shutil +import optparse + +from . import refactor + + +class StdoutRefactoringTool(refactor.RefactoringTool): + """ + Prints output to stdout. + """ + + def __init__(self, fixers, options, explicit, nobackups): + self.nobackups = nobackups + super(StdoutRefactoringTool, self).__init__(fixers, options, explicit) + + def log_error(self, msg, *args, **kwargs): + self.errors.append((msg, args, kwargs)) + self.logger.error(msg, *args, **kwargs) + + def write_file(self, new_text, filename, old_text): + if not self.nobackups: + # Make backup + backup = filename + ".bak" + if os.path.lexists(backup): + try: + os.remove(backup) + except os.error, err: + self.log_message("Can't remove backup %s", backup) + try: + os.rename(filename, backup) + except os.error, err: + self.log_message("Can't rename %s to %s", filename, backup) + # Actually write the new file + super(StdoutRefactoringTool, self).write_file(new_text, + filename, old_text) + if not self.nobackups: + shutil.copymode(backup, filename) + + def print_output(self, lines): + for line in lines: + print line + + +def main(fixer_pkg, args=None): + """Main program. + + Args: + fixer_pkg: the name of a package where the fixers are located. + args: optional; a list of command line arguments. If omitted, + sys.argv[1:] is used. + + Returns a suggested exit status (0, 1, 2). + """ + # Set up option parser + parser = optparse.OptionParser(usage="%s [options] file|dir ..." % + sys.argv[0]) + parser.add_option("-d", "--doctests_only", action="store_true", + help="Fix up doctests only") + parser.add_option("-f", "--fix", action="append", default=[], + help="Each FIX specifies a transformation; default: all") + parser.add_option("-x", "--nofix", action="append", default=[], + help="Prevent a fixer from being run.") + parser.add_option("-l", "--list-fixes", action="store_true", + help="List available transformations (fixes/fix_*.py)") + parser.add_option("-p", "--print-function", action="store_true", + help="Modify the grammar so that print() is a function") + parser.add_option("-v", "--verbose", action="store_true", + help="More verbose logging") + 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.") + + # Parse command line arguments + refactor_stdin = False + options, args = parser.parse_args(args) + if not options.write and options.nobackups: + parser.error("Can't use -n without -w") + if options.list_fixes: + print "Available transformations for the -f/--fix option:" + for fixname in refactor.get_all_fix_names(fixer_pkg): + print fixname + if not args: + return 0 + if not args: + print >>sys.stderr, "At least one file or directory argument required." + print >>sys.stderr, "Use --help to show usage." + return 2 + if "-" in args: + refactor_stdin = True + if options.write: + print >>sys.stderr, "Can't write to stdin." + return 2 + + # Set up logging handler + level = logging.DEBUG if options.verbose else logging.INFO + logging.basicConfig(format='%(name)s: %(message)s', level=level) + + # Initialize the refactoring tool + rt_opts = {"print_function" : options.print_function} + avail_fixes = set(refactor.get_fixers_from_package(fixer_pkg)) + unwanted_fixes = set(fixer_pkg + ".fix_" + fix for fix in options.nofix) + explicit = set() + if options.fix: + all_present = False + for fix in options.fix: + if fix == "all": + all_present = True + else: + explicit.add(fixer_pkg + ".fix_" + fix) + requested = avail_fixes.union(explicit) if all_present else explicit + else: + requested = avail_fixes.union(explicit) + fixer_names = requested.difference(unwanted_fixes) + rt = StdoutRefactoringTool(sorted(fixer_names), rt_opts, sorted(explicit), + options.nobackups) + + # Refactor all files and directories passed as arguments + if not rt.errors: + if refactor_stdin: + rt.refactor_stdin() + else: + rt.refactor(args, options.write, options.doctests_only) + rt.summarize() + + # Return error status (0 if rt.errors is zero) + return int(bool(rt.errors)) Added: sandbox/trunk/refactor_pkg/refactor/patcomp.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/patcomp.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,186 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Pattern compiler. + +The grammer is taken from PatternGrammar.txt. + +The compiler compiles a pattern to a pytree.*Pattern instance. +""" + +__author__ = "Guido van Rossum " + +# Python imports +import os + +# Fairly local imports +from .pgen2 import driver +from .pgen2 import literals +from .pgen2 import token +from .pgen2 import tokenize + +# Really local imports +from . import pytree +from . import pygram + +# The pattern grammar file +_PATTERN_GRAMMAR_FILE = os.path.join(os.path.dirname(__file__), + "PatternGrammar.txt") + + +def tokenize_wrapper(input): + """Tokenizes a string suppressing significant whitespace.""" + skip = set((token.NEWLINE, token.INDENT, token.DEDENT)) + tokens = tokenize.generate_tokens(driver.generate_lines(input).next) + for quintuple in tokens: + type, value, start, end, line_text = quintuple + if type not in skip: + yield quintuple + + +class PatternCompiler(object): + + def __init__(self, grammar_file=_PATTERN_GRAMMAR_FILE): + """Initializer. + + Takes an optional alternative filename for the pattern grammar. + """ + self.grammar = driver.load_grammar(grammar_file) + self.syms = pygram.Symbols(self.grammar) + self.pygrammar = pygram.python_grammar + self.pysyms = pygram.python_symbols + self.driver = driver.Driver(self.grammar, convert=pattern_convert) + + def compile_pattern(self, input, debug=False): + """Compiles a pattern string to a nested pytree.*Pattern object.""" + tokens = tokenize_wrapper(input) + root = self.driver.parse_tokens(tokens, debug=debug) + return self.compile_node(root) + + def compile_node(self, node): + """Compiles a node, recursively. + + This is one big switch on the node type. + """ + # XXX Optimize certain Wildcard-containing-Wildcard patterns + # that can be merged + if node.type == self.syms.Matcher: + node = node.children[0] # Avoid unneeded recursion + + if node.type == self.syms.Alternatives: + # Skip the odd children since they are just '|' tokens + alts = [self.compile_node(ch) for ch in node.children[::2]] + if len(alts) == 1: + return alts[0] + p = pytree.WildcardPattern([[a] for a in alts], min=1, max=1) + return p.optimize() + + if node.type == self.syms.Alternative: + units = [self.compile_node(ch) for ch in node.children] + if len(units) == 1: + return units[0] + p = pytree.WildcardPattern([units], min=1, max=1) + return p.optimize() + + if node.type == self.syms.NegatedUnit: + pattern = self.compile_basic(node.children[1:]) + p = pytree.NegatedPattern(pattern) + return p.optimize() + + assert node.type == self.syms.Unit + + name = None + nodes = node.children + if len(nodes) >= 3 and nodes[1].type == token.EQUAL: + name = nodes[0].value + nodes = nodes[2:] + repeat = None + if len(nodes) >= 2 and nodes[-1].type == self.syms.Repeater: + repeat = nodes[-1] + nodes = nodes[:-1] + + # Now we've reduced it to: STRING | NAME [Details] | (...) | [...] + pattern = self.compile_basic(nodes, repeat) + + if repeat is not None: + assert repeat.type == self.syms.Repeater + children = repeat.children + child = children[0] + if child.type == token.STAR: + min = 0 + max = pytree.HUGE + elif child.type == token.PLUS: + min = 1 + max = pytree.HUGE + elif child.type == token.LBRACE: + assert children[-1].type == token.RBRACE + assert len(children) in (3, 5) + min = max = self.get_int(children[1]) + if len(children) == 5: + max = self.get_int(children[3]) + else: + assert False + if min != 1 or max != 1: + pattern = pattern.optimize() + pattern = pytree.WildcardPattern([[pattern]], min=min, max=max) + + if name is not None: + pattern.name = name + return pattern.optimize() + + def compile_basic(self, nodes, repeat=None): + # Compile STRING | NAME [Details] | (...) | [...] + assert len(nodes) >= 1 + node = nodes[0] + if node.type == token.STRING: + value = literals.evalString(node.value) + return pytree.LeafPattern(content=value) + elif node.type == token.NAME: + value = node.value + if value.isupper(): + if value not in TOKEN_MAP: + raise SyntaxError("Invalid token: %r" % value) + return pytree.LeafPattern(TOKEN_MAP[value]) + else: + if value == "any": + type = None + elif not value.startswith("_"): + type = getattr(self.pysyms, value, None) + if type is None: + raise SyntaxError("Invalid symbol: %r" % value) + if nodes[1:]: # Details present + content = [self.compile_node(nodes[1].children[1])] + else: + content = None + return pytree.NodePattern(type, content) + elif node.value == "(": + return self.compile_node(nodes[1]) + elif node.value == "[": + assert repeat is None + subpattern = self.compile_node(nodes[1]) + return pytree.WildcardPattern([[subpattern]], min=0, max=1) + assert False, node + + def get_int(self, node): + assert node.type == token.NUMBER + return int(node.value) + + +# Map named tokens to the type value for a LeafPattern +TOKEN_MAP = {"NAME": token.NAME, + "STRING": token.STRING, + "NUMBER": token.NUMBER, + "TOKEN": None} + + +def pattern_convert(grammar, raw_node_info): + """Converts raw node information to a Node or Leaf instance.""" + type, value, context, children = raw_node_info + if children or type in grammar.number2symbol: + return pytree.Node(type, children, context=context) + else: + return pytree.Leaf(type, value, context=context) + + +def compile_pattern(pattern): + return PatternCompiler().compile_pattern(pattern) Added: sandbox/trunk/refactor_pkg/refactor/pgen2/__init__.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/pgen2/__init__.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,12 @@ +# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""The pgen2 package.""" +import conv +import driver +import grammar +import literals +import parse +import pgen +import tokenize +import token Added: sandbox/trunk/refactor_pkg/refactor/pgen2/conv.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/pgen2/conv.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,257 @@ +# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Convert graminit.[ch] spit out by pgen to Python code. + +Pgen is the Python parser generator. It is useful to quickly create a +parser from a grammar file in Python's grammar notation. But I don't +want my parsers to be written in C (yet), so I'm translating the +parsing tables to Python data structures and writing a Python parse +engine. + +Note that the token numbers are constants determined by the standard +Python tokenizer. The standard token module defines these numbers and +their names (the names are not used much). The token numbers are +hardcoded into the Python tokenizer and into pgen. A Python +implementation of the Python tokenizer is also available, in the +standard tokenize module. + +On the other hand, symbol numbers (representing the grammar's +non-terminals) are assigned by pgen based on the actual grammar +input. + +Note: this module is pretty much obsolete; the pgen module generates +equivalent grammar tables directly from the Grammar.txt input file +without having to invoke the Python pgen C program. + +""" + +# Python imports +import re + +# Local imports +from . import grammar, token + + +class Converter(grammar.Grammar): + """Grammar subclass that reads classic pgen output files. + + The run() method reads the tables as produced by the pgen parser + generator, typically contained in two C files, graminit.h and + graminit.c. The other methods are for internal use only. + + See the base class for more documentation. + + """ + + def run(self, graminit_h, graminit_c): + """Load the grammar tables from the text files written by pgen.""" + self.parse_graminit_h(graminit_h) + self.parse_graminit_c(graminit_c) + self.finish_off() + + def parse_graminit_h(self, filename): + """Parse the .h file writen by pgen. (Internal) + + This file is a sequence of #define statements defining the + nonterminals of the grammar as numbers. We build two tables + mapping the numbers to names and back. + + """ + try: + f = open(filename) + except IOError, err: + print "Can't open %s: %s" % (filename, err) + return False + self.symbol2number = {} + self.number2symbol = {} + lineno = 0 + for line in f: + lineno += 1 + mo = re.match(r"^#define\s+(\w+)\s+(\d+)$", line) + if not mo and line.strip(): + print "%s(%s): can't parse %s" % (filename, lineno, + line.strip()) + else: + symbol, number = mo.groups() + number = int(number) + assert symbol not in self.symbol2number + assert number not in self.number2symbol + self.symbol2number[symbol] = number + self.number2symbol[number] = symbol + return True + + def parse_graminit_c(self, filename): + """Parse the .c file writen by pgen. (Internal) + + The file looks as follows. The first two lines are always this: + + #include "pgenheaders.h" + #include "grammar.h" + + After that come four blocks: + + 1) one or more state definitions + 2) a table defining dfas + 3) a table defining labels + 4) a struct defining the grammar + + A state definition has the following form: + - one or more arc arrays, each of the form: + static arc arcs__[] = { + {, }, + ... + }; + - followed by a state array, of the form: + static state states_[] = { + {, arcs__}, + ... + }; + + """ + try: + f = open(filename) + except IOError, err: + print "Can't open %s: %s" % (filename, err) + return False + # The code below essentially uses f's iterator-ness! + lineno = 0 + + # Expect the two #include lines + lineno, line = lineno+1, f.next() + assert line == '#include "pgenheaders.h"\n', (lineno, line) + lineno, line = lineno+1, f.next() + assert line == '#include "grammar.h"\n', (lineno, line) + + # Parse the state definitions + lineno, line = lineno+1, f.next() + allarcs = {} + states = [] + while line.startswith("static arc "): + while line.startswith("static arc "): + mo = re.match(r"static arc arcs_(\d+)_(\d+)\[(\d+)\] = {$", + line) + assert mo, (lineno, line) + n, m, k = map(int, mo.groups()) + arcs = [] + for _ in range(k): + lineno, line = lineno+1, f.next() + mo = re.match(r"\s+{(\d+), (\d+)},$", line) + assert mo, (lineno, line) + i, j = map(int, mo.groups()) + arcs.append((i, j)) + lineno, line = lineno+1, f.next() + assert line == "};\n", (lineno, line) + allarcs[(n, m)] = arcs + lineno, line = lineno+1, f.next() + mo = re.match(r"static state states_(\d+)\[(\d+)\] = {$", line) + assert mo, (lineno, line) + s, t = map(int, mo.groups()) + assert s == len(states), (lineno, line) + state = [] + for _ in range(t): + lineno, line = lineno+1, f.next() + mo = re.match(r"\s+{(\d+), arcs_(\d+)_(\d+)},$", line) + assert mo, (lineno, line) + k, n, m = map(int, mo.groups()) + arcs = allarcs[n, m] + assert k == len(arcs), (lineno, line) + state.append(arcs) + states.append(state) + lineno, line = lineno+1, f.next() + assert line == "};\n", (lineno, line) + lineno, line = lineno+1, f.next() + self.states = states + + # Parse the dfas + dfas = {} + mo = re.match(r"static dfa dfas\[(\d+)\] = {$", line) + assert mo, (lineno, line) + ndfas = int(mo.group(1)) + for i in range(ndfas): + lineno, line = lineno+1, f.next() + mo = re.match(r'\s+{(\d+), "(\w+)", (\d+), (\d+), states_(\d+),$', + line) + assert mo, (lineno, line) + symbol = mo.group(2) + number, x, y, z = map(int, mo.group(1, 3, 4, 5)) + assert self.symbol2number[symbol] == number, (lineno, line) + assert self.number2symbol[number] == symbol, (lineno, line) + assert x == 0, (lineno, line) + state = states[z] + assert y == len(state), (lineno, line) + lineno, line = lineno+1, f.next() + mo = re.match(r'\s+("(?:\\\d\d\d)*")},$', line) + assert mo, (lineno, line) + first = {} + rawbitset = eval(mo.group(1)) + for i, c in enumerate(rawbitset): + byte = ord(c) + for j in range(8): + if byte & (1<= os.path.getmtime(b) Added: sandbox/trunk/refactor_pkg/refactor/pgen2/grammar.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/pgen2/grammar.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,171 @@ +# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""This module defines the data structures used to represent a grammar. + +These are a bit arcane because they are derived from the data +structures used by Python's 'pgen' parser generator. + +There's also a table here mapping operators to their names in the +token module; the Python tokenize module reports all operators as the +fallback token code OP, but the parser needs the actual token code. + +""" + +# Python imports +import pickle + +# Local imports +from . import token, tokenize + + +class Grammar(object): + """Pgen parsing tables tables conversion class. + + Once initialized, this class supplies the grammar tables for the + parsing engine implemented by parse.py. The parsing engine + accesses the instance variables directly. The class here does not + provide initialization of the tables; several subclasses exist to + do this (see the conv and pgen modules). + + The load() method reads the tables from a pickle file, which is + much faster than the other ways offered by subclasses. The pickle + file is written by calling dump() (after loading the grammar + tables using a subclass). The report() method prints a readable + representation of the tables to stdout, for debugging. + + The instance variables are as follows: + + symbol2number -- a dict mapping symbol names to numbers. Symbol + numbers are always 256 or higher, to distinguish + them from token numbers, which are between 0 and + 255 (inclusive). + + number2symbol -- a dict mapping numbers to symbol names; + these two are each other's inverse. + + states -- a list of DFAs, where each DFA is a list of + states, each state is is a list of arcs, and each + arc is a (i, j) pair where i is a label and j is + a state number. The DFA number is the index into + this list. (This name is slightly confusing.) + Final states are represented by a special arc of + the form (0, j) where j is its own state number. + + dfas -- a dict mapping symbol numbers to (DFA, first) + pairs, where DFA is an item from the states list + above, and first is a set of tokens that can + begin this grammar rule (represented by a dict + whose values are always 1). + + labels -- a list of (x, y) pairs where x is either a token + number or a symbol number, and y is either None + or a string; the strings are keywords. The label + number is the index in this list; label numbers + are used to mark state transitions (arcs) in the + DFAs. + + start -- the number of the grammar's start symbol. + + keywords -- a dict mapping keyword strings to arc labels. + + tokens -- a dict mapping token numbers to arc labels. + + """ + + def __init__(self): + self.symbol2number = {} + self.number2symbol = {} + self.states = [] + self.dfas = {} + self.labels = [(0, "EMPTY")] + self.keywords = {} + self.tokens = {} + self.symbol2label = {} + self.start = 256 + + def dump(self, filename): + """Dump the grammar tables to a pickle file.""" + f = open(filename, "wb") + pickle.dump(self.__dict__, f, 2) + f.close() + + def load(self, filename): + """Load the grammar tables from a pickle file.""" + f = open(filename, "rb") + d = pickle.load(f) + f.close() + self.__dict__.update(d) + + def report(self): + """Dump the grammar tables to standard output, for debugging.""" + from pprint import pprint + print "s2n" + pprint(self.symbol2number) + print "n2s" + pprint(self.number2symbol) + print "states" + pprint(self.states) + print "dfas" + pprint(self.dfas) + print "labels" + pprint(self.labels) + print "start", self.start + + +# Map from operator to number (since tokenize doesn't do this) + +opmap_raw = """ +( LPAR +) RPAR +[ LSQB +] RSQB +: COLON +, COMMA +; SEMI ++ PLUS +- MINUS +* STAR +/ SLASH +| VBAR +& AMPER +< LESS +> GREATER += EQUAL +. DOT +% PERCENT +` BACKQUOTE +{ LBRACE +} RBRACE +@ AT +== EQEQUAL +!= NOTEQUAL +<> NOTEQUAL +<= LESSEQUAL +>= GREATEREQUAL +~ TILDE +^ CIRCUMFLEX +<< LEFTSHIFT +>> RIGHTSHIFT +** DOUBLESTAR ++= PLUSEQUAL +-= MINEQUAL +*= STAREQUAL +/= SLASHEQUAL +%= PERCENTEQUAL +&= AMPEREQUAL +|= VBAREQUAL +^= CIRCUMFLEXEQUAL +<<= LEFTSHIFTEQUAL +>>= RIGHTSHIFTEQUAL +**= DOUBLESTAREQUAL +// DOUBLESLASH +//= DOUBLESLASHEQUAL +-> RARROW +""" + +opmap = {} +for line in opmap_raw.splitlines(): + if line: + op, name = line.split() + opmap[op] = getattr(token, name) Added: sandbox/trunk/refactor_pkg/refactor/pgen2/literals.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/pgen2/literals.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,60 @@ +# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Safely evaluate Python string literals without using eval().""" + +import re + +simple_escapes = {"a": "\a", + "b": "\b", + "f": "\f", + "n": "\n", + "r": "\r", + "t": "\t", + "v": "\v", + "'": "'", + '"': '"', + "\\": "\\"} + +def escape(m): + all, tail = m.group(0, 1) + assert all.startswith("\\") + esc = simple_escapes.get(tail) + if esc is not None: + return esc + if tail.startswith("x"): + hexes = tail[1:] + if len(hexes) < 2: + raise ValueError("invalid hex string escape ('\\%s')" % tail) + try: + i = int(hexes, 16) + except ValueError: + raise ValueError("invalid hex string escape ('\\%s')" % tail) + else: + try: + i = int(tail, 8) + except ValueError: + raise ValueError("invalid octal string escape ('\\%s')" % tail) + return chr(i) + +def evalString(s): + assert s.startswith("'") or s.startswith('"'), repr(s[:1]) + q = s[0] + if s[:3] == q*3: + q = q*3 + assert s.endswith(q), repr(s[-len(q):]) + assert len(s) >= 2*len(q) + s = s[len(q):-len(q)] + return re.sub(r"\\(\'|\"|\\|[abfnrtv]|x.{0,2}|[0-7]{1,3})", escape, s) + +def test(): + for i in range(256): + c = chr(i) + s = repr(c) + e = evalString(s) + if e != c: + print i, c, s, e + + +if __name__ == "__main__": + test() Added: sandbox/trunk/refactor_pkg/refactor/pgen2/parse.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/pgen2/parse.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,201 @@ +# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Parser engine for the grammar tables generated by pgen. + +The grammar table must be loaded first. + +See Parser/parser.c in the Python distribution for additional info on +how this parsing engine works. + +""" + +# Local imports +from . import token + +class ParseError(Exception): + """Exception to signal the parser is stuck.""" + + def __init__(self, msg, type, value, context): + Exception.__init__(self, "%s: type=%r, value=%r, context=%r" % + (msg, type, value, context)) + self.msg = msg + self.type = type + self.value = value + self.context = context + +class Parser(object): + """Parser engine. + + The proper usage sequence is: + + p = Parser(grammar, [converter]) # create instance + p.setup([start]) # prepare for parsing + : + if p.addtoken(...): # parse a token; may raise ParseError + break + root = p.rootnode # root of abstract syntax tree + + A Parser instance may be reused by calling setup() repeatedly. + + A Parser instance contains state pertaining to the current token + sequence, and should not be used concurrently by different threads + to parse separate token sequences. + + See driver.py for how to get input tokens by tokenizing a file or + string. + + Parsing is complete when addtoken() returns True; the root of the + abstract syntax tree can then be retrieved from the rootnode + instance variable. When a syntax error occurs, addtoken() raises + the ParseError exception. There is no error recovery; the parser + cannot be used after a syntax error was reported (but it can be + reinitialized by calling setup()). + + """ + + def __init__(self, grammar, convert=None): + """Constructor. + + The grammar argument is a grammar.Grammar instance; see the + grammar module for more information. + + The parser is not ready yet for parsing; you must call the + setup() method to get it started. + + The optional convert argument is a function mapping concrete + syntax tree nodes to abstract syntax tree nodes. If not + given, no conversion is done and the syntax tree produced is + the concrete syntax tree. If given, it must be a function of + two arguments, the first being the grammar (a grammar.Grammar + instance), and the second being the concrete syntax tree node + to be converted. The syntax tree is converted from the bottom + up. + + A concrete syntax tree node is a (type, value, context, nodes) + tuple, where type is the node type (a token or symbol number), + value is None for symbols and a string for tokens, context is + None or an opaque value used for error reporting (typically a + (lineno, offset) pair), and nodes is a list of children for + symbols, and None for tokens. + + An abstract syntax tree node may be anything; this is entirely + up to the converter function. + + """ + self.grammar = grammar + self.convert = convert or (lambda grammar, node: node) + + def setup(self, start=None): + """Prepare for parsing. + + This *must* be called before starting to parse. + + The optional argument is an alternative start symbol; it + defaults to the grammar's start symbol. + + You can use a Parser instance to parse any number of programs; + each time you call setup() the parser is reset to an initial + state determined by the (implicit or explicit) start symbol. + + """ + if start is None: + start = self.grammar.start + # Each stack entry is a tuple: (dfa, state, node). + # A node is a tuple: (type, value, context, children), + # where children is a list of nodes or None, and context may be None. + newnode = (start, None, None, []) + stackentry = (self.grammar.dfas[start], 0, newnode) + self.stack = [stackentry] + self.rootnode = None + self.used_names = set() # Aliased to self.rootnode.used_names in pop() + + def addtoken(self, type, value, context): + """Add a token; return True iff this is the end of the program.""" + # Map from token to label + ilabel = self.classify(type, value, context) + # Loop until the token is shifted; may raise exceptions + while True: + dfa, state, node = self.stack[-1] + states, first = dfa + arcs = states[state] + # Look for a state with this label + for i, newstate in arcs: + t, v = self.grammar.labels[i] + if ilabel == i: + # Look it up in the list of labels + assert t < 256 + # Shift a token; we're done with it + self.shift(type, value, newstate, context) + # Pop while we are in an accept-only state + state = newstate + while states[state] == [(0, state)]: + self.pop() + if not self.stack: + # Done parsing! + return True + dfa, state, node = self.stack[-1] + states, first = dfa + # Done with this token + return False + elif t >= 256: + # See if it's a symbol and if we're in its first set + itsdfa = self.grammar.dfas[t] + itsstates, itsfirst = itsdfa + if ilabel in itsfirst: + # Push a symbol + self.push(t, self.grammar.dfas[t], newstate, context) + break # To continue the outer while loop + else: + if (0, state) in arcs: + # An accepting state, pop it and try something else + self.pop() + if not self.stack: + # Done parsing, but another token is input + raise ParseError("too much input", + type, value, context) + else: + # No success finding a transition + raise ParseError("bad input", type, value, context) + + def classify(self, type, value, context): + """Turn a token into a label. (Internal)""" + if type == token.NAME: + # Keep a listing of all used names + self.used_names.add(value) + # Check for reserved words + ilabel = self.grammar.keywords.get(value) + if ilabel is not None: + return ilabel + ilabel = self.grammar.tokens.get(type) + if ilabel is None: + raise ParseError("bad token", type, value, context) + return ilabel + + def shift(self, type, value, newstate, context): + """Shift a token. (Internal)""" + dfa, state, node = self.stack[-1] + newnode = (type, value, context, None) + newnode = self.convert(self.grammar, newnode) + if newnode is not None: + node[-1].append(newnode) + self.stack[-1] = (dfa, newstate, node) + + def push(self, type, newdfa, newstate, context): + """Push a nonterminal. (Internal)""" + dfa, state, node = self.stack[-1] + newnode = (type, None, context, []) + self.stack[-1] = (dfa, newstate, node) + self.stack.append((newdfa, 0, newnode)) + + def pop(self): + """Pop a nonterminal. (Internal)""" + popdfa, popstate, popnode = self.stack.pop() + newnode = self.convert(self.grammar, popnode) + if newnode is not None: + if self.stack: + dfa, state, node = self.stack[-1] + node[-1].append(newnode) + else: + self.rootnode = newnode + self.rootnode.used_names = self.used_names Added: sandbox/trunk/refactor_pkg/refactor/pgen2/pgen.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/pgen2/pgen.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,384 @@ +# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +# Pgen imports +from . import grammar, token, tokenize + +class PgenGrammar(grammar.Grammar): + pass + +class ParserGenerator(object): + + def __init__(self, filename, stream=None): + close_stream = None + if stream is None: + stream = open(filename) + close_stream = stream.close + self.filename = filename + self.stream = stream + self.generator = tokenize.generate_tokens(stream.readline) + self.gettoken() # Initialize lookahead + self.dfas, self.startsymbol = self.parse() + if close_stream is not None: + close_stream() + self.first = {} # map from symbol name to set of tokens + self.addfirstsets() + + def make_grammar(self): + c = PgenGrammar() + names = self.dfas.keys() + names.sort() + names.remove(self.startsymbol) + names.insert(0, self.startsymbol) + for name in names: + i = 256 + len(c.symbol2number) + c.symbol2number[name] = i + c.number2symbol[i] = name + for name in names: + dfa = self.dfas[name] + states = [] + for state in dfa: + arcs = [] + for label, next in state.arcs.iteritems(): + arcs.append((self.make_label(c, label), dfa.index(next))) + if state.isfinal: + arcs.append((0, dfa.index(state))) + states.append(arcs) + c.states.append(states) + c.dfas[c.symbol2number[name]] = (states, self.make_first(c, name)) + c.start = c.symbol2number[self.startsymbol] + return c + + def make_first(self, c, name): + rawfirst = self.first[name] + first = {} + for label in rawfirst: + ilabel = self.make_label(c, label) + ##assert ilabel not in first # XXX failed on <> ... != + first[ilabel] = 1 + return first + + def make_label(self, c, label): + # XXX Maybe this should be a method on a subclass of converter? + ilabel = len(c.labels) + if label[0].isalpha(): + # Either a symbol name or a named token + if label in c.symbol2number: + # A symbol name (a non-terminal) + if label in c.symbol2label: + return c.symbol2label[label] + else: + c.labels.append((c.symbol2number[label], None)) + c.symbol2label[label] = ilabel + return ilabel + else: + # A named token (NAME, NUMBER, STRING) + itoken = getattr(token, label, None) + assert isinstance(itoken, int), label + assert itoken in token.tok_name, label + if itoken in c.tokens: + return c.tokens[itoken] + else: + c.labels.append((itoken, None)) + c.tokens[itoken] = ilabel + return ilabel + else: + # Either a keyword or an operator + assert label[0] in ('"', "'"), label + value = eval(label) + if value[0].isalpha(): + # A keyword + if value in c.keywords: + return c.keywords[value] + else: + c.labels.append((token.NAME, value)) + c.keywords[value] = ilabel + return ilabel + else: + # An operator (any non-numeric token) + itoken = grammar.opmap[value] # Fails if unknown token + if itoken in c.tokens: + return c.tokens[itoken] + else: + c.labels.append((itoken, None)) + c.tokens[itoken] = ilabel + return ilabel + + def addfirstsets(self): + names = self.dfas.keys() + names.sort() + for name in names: + if name not in self.first: + self.calcfirst(name) + #print name, self.first[name].keys() + + def calcfirst(self, name): + dfa = self.dfas[name] + self.first[name] = None # dummy to detect left recursion + state = dfa[0] + totalset = {} + overlapcheck = {} + for label, next in state.arcs.iteritems(): + if label in self.dfas: + if label in self.first: + fset = self.first[label] + if fset is None: + raise ValueError("recursion for rule %r" % name) + else: + self.calcfirst(label) + fset = self.first[label] + totalset.update(fset) + overlapcheck[label] = fset + else: + totalset[label] = 1 + overlapcheck[label] = {label: 1} + inverse = {} + for label, itsfirst in overlapcheck.iteritems(): + for symbol in itsfirst: + if symbol in inverse: + raise ValueError("rule %s is ambiguous; %s is in the" + " first sets of %s as well as %s" % + (name, symbol, label, inverse[symbol])) + inverse[symbol] = label + self.first[name] = totalset + + def parse(self): + dfas = {} + startsymbol = None + # MSTART: (NEWLINE | RULE)* ENDMARKER + while self.type != token.ENDMARKER: + while self.type == token.NEWLINE: + self.gettoken() + # RULE: NAME ':' RHS NEWLINE + name = self.expect(token.NAME) + self.expect(token.OP, ":") + a, z = self.parse_rhs() + self.expect(token.NEWLINE) + #self.dump_nfa(name, a, z) + dfa = self.make_dfa(a, z) + #self.dump_dfa(name, dfa) + oldlen = len(dfa) + self.simplify_dfa(dfa) + newlen = len(dfa) + dfas[name] = dfa + #print name, oldlen, newlen + if startsymbol is None: + startsymbol = name + return dfas, startsymbol + + def make_dfa(self, start, finish): + # To turn an NFA into a DFA, we define the states of the DFA + # to correspond to *sets* of states of the NFA. Then do some + # state reduction. Let's represent sets as dicts with 1 for + # values. + assert isinstance(start, NFAState) + assert isinstance(finish, NFAState) + def closure(state): + base = {} + addclosure(state, base) + return base + def addclosure(state, base): + assert isinstance(state, NFAState) + if state in base: + return + base[state] = 1 + for label, next in state.arcs: + if label is None: + addclosure(next, base) + states = [DFAState(closure(start), finish)] + for state in states: # NB states grows while we're iterating + arcs = {} + for nfastate in state.nfaset: + for label, next in nfastate.arcs: + if label is not None: + addclosure(next, arcs.setdefault(label, {})) + for label, nfaset in arcs.iteritems(): + for st in states: + if st.nfaset == nfaset: + break + else: + st = DFAState(nfaset, finish) + states.append(st) + state.addarc(st, label) + return states # List of DFAState instances; first one is start + + def dump_nfa(self, name, start, finish): + print "Dump of NFA for", name + todo = [start] + for i, state in enumerate(todo): + print " State", i, state is finish and "(final)" or "" + for label, next in state.arcs: + if next in todo: + j = todo.index(next) + else: + j = len(todo) + todo.append(next) + if label is None: + print " -> %d" % j + else: + print " %s -> %d" % (label, j) + + def dump_dfa(self, name, dfa): + print "Dump of DFA for", name + for i, state in enumerate(dfa): + print " State", i, state.isfinal and "(final)" or "" + for label, next in state.arcs.iteritems(): + print " %s -> %d" % (label, dfa.index(next)) + + def simplify_dfa(self, dfa): + # This is not theoretically optimal, but works well enough. + # Algorithm: repeatedly look for two states that have the same + # set of arcs (same labels pointing to the same nodes) and + # unify them, until things stop changing. + + # dfa is a list of DFAState instances + changes = True + while changes: + changes = False + for i, state_i in enumerate(dfa): + for j in range(i+1, len(dfa)): + state_j = dfa[j] + if state_i == state_j: + #print " unify", i, j + del dfa[j] + for state in dfa: + state.unifystate(state_j, state_i) + changes = True + break + + def parse_rhs(self): + # RHS: ALT ('|' ALT)* + a, z = self.parse_alt() + if self.value != "|": + return a, z + else: + aa = NFAState() + zz = NFAState() + aa.addarc(a) + z.addarc(zz) + while self.value == "|": + self.gettoken() + a, z = self.parse_alt() + aa.addarc(a) + z.addarc(zz) + return aa, zz + + def parse_alt(self): + # ALT: ITEM+ + a, b = self.parse_item() + while (self.value in ("(", "[") or + self.type in (token.NAME, token.STRING)): + c, d = self.parse_item() + b.addarc(c) + b = d + return a, b + + def parse_item(self): + # ITEM: '[' RHS ']' | ATOM ['+' | '*'] + if self.value == "[": + self.gettoken() + a, z = self.parse_rhs() + self.expect(token.OP, "]") + a.addarc(z) + return a, z + else: + a, z = self.parse_atom() + value = self.value + if value not in ("+", "*"): + return a, z + self.gettoken() + z.addarc(a) + if value == "+": + return a, z + else: + return a, a + + def parse_atom(self): + # ATOM: '(' RHS ')' | NAME | STRING + if self.value == "(": + self.gettoken() + a, z = self.parse_rhs() + self.expect(token.OP, ")") + return a, z + elif self.type in (token.NAME, token.STRING): + a = NFAState() + z = NFAState() + a.addarc(z, self.value) + self.gettoken() + return a, z + else: + self.raise_error("expected (...) or NAME or STRING, got %s/%s", + self.type, self.value) + + def expect(self, type, value=None): + if self.type != type or (value is not None and self.value != value): + self.raise_error("expected %s/%s, got %s/%s", + type, value, self.type, self.value) + value = self.value + self.gettoken() + return value + + def gettoken(self): + tup = self.generator.next() + while tup[0] in (tokenize.COMMENT, tokenize.NL): + tup = self.generator.next() + self.type, self.value, self.begin, self.end, self.line = tup + #print token.tok_name[self.type], repr(self.value) + + def raise_error(self, msg, *args): + if args: + try: + msg = msg % args + except: + msg = " ".join([msg] + map(str, args)) + raise SyntaxError(msg, (self.filename, self.end[0], + self.end[1], self.line)) + +class NFAState(object): + + def __init__(self): + self.arcs = [] # list of (label, NFAState) pairs + + def addarc(self, next, label=None): + assert label is None or isinstance(label, str) + assert isinstance(next, NFAState) + self.arcs.append((label, next)) + +class DFAState(object): + + def __init__(self, nfaset, final): + assert isinstance(nfaset, dict) + assert isinstance(iter(nfaset).next(), NFAState) + assert isinstance(final, NFAState) + self.nfaset = nfaset + self.isfinal = final in nfaset + self.arcs = {} # map from label to DFAState + + def addarc(self, next, label): + assert isinstance(label, str) + assert label not in self.arcs + assert isinstance(next, DFAState) + self.arcs[label] = next + + def unifystate(self, old, new): + for label, next in self.arcs.iteritems(): + if next is old: + self.arcs[label] = new + + def __eq__(self, other): + # Equality test -- ignore the nfaset instance variable + assert isinstance(other, DFAState) + if self.isfinal != other.isfinal: + return False + # Can't just return self.arcs == other.arcs, because that + # would invoke this method recursively, with cycles... + if len(self.arcs) != len(other.arcs): + return False + for label, next in self.arcs.iteritems(): + if next is not other.arcs.get(label): + return False + return True + +def generate_grammar(filename="Grammar.txt"): + p = ParserGenerator(filename) + return p.make_grammar() Added: sandbox/trunk/refactor_pkg/refactor/pgen2/token.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/pgen2/token.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,82 @@ +#! /usr/bin/env python + +"""Token constants (from "token.h").""" + +# Taken from Python (r53757) and modified to include some tokens +# originally monkeypatched in by pgen2.tokenize + +#--start constants-- +ENDMARKER = 0 +NAME = 1 +NUMBER = 2 +STRING = 3 +NEWLINE = 4 +INDENT = 5 +DEDENT = 6 +LPAR = 7 +RPAR = 8 +LSQB = 9 +RSQB = 10 +COLON = 11 +COMMA = 12 +SEMI = 13 +PLUS = 14 +MINUS = 15 +STAR = 16 +SLASH = 17 +VBAR = 18 +AMPER = 19 +LESS = 20 +GREATER = 21 +EQUAL = 22 +DOT = 23 +PERCENT = 24 +BACKQUOTE = 25 +LBRACE = 26 +RBRACE = 27 +EQEQUAL = 28 +NOTEQUAL = 29 +LESSEQUAL = 30 +GREATEREQUAL = 31 +TILDE = 32 +CIRCUMFLEX = 33 +LEFTSHIFT = 34 +RIGHTSHIFT = 35 +DOUBLESTAR = 36 +PLUSEQUAL = 37 +MINEQUAL = 38 +STAREQUAL = 39 +SLASHEQUAL = 40 +PERCENTEQUAL = 41 +AMPEREQUAL = 42 +VBAREQUAL = 43 +CIRCUMFLEXEQUAL = 44 +LEFTSHIFTEQUAL = 45 +RIGHTSHIFTEQUAL = 46 +DOUBLESTAREQUAL = 47 +DOUBLESLASH = 48 +DOUBLESLASHEQUAL = 49 +AT = 50 +OP = 51 +COMMENT = 52 +NL = 53 +RARROW = 54 +ERRORTOKEN = 55 +N_TOKENS = 56 +NT_OFFSET = 256 +#--end constants-- + +tok_name = {} +for _name, _value in globals().items(): + if type(_value) is type(0): + tok_name[_value] = _name + + +def ISTERMINAL(x): + return x < NT_OFFSET + +def ISNONTERMINAL(x): + return x >= NT_OFFSET + +def ISEOF(x): + return x == ENDMARKER Added: sandbox/trunk/refactor_pkg/refactor/pgen2/tokenize.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/pgen2/tokenize.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,405 @@ +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation. +# All rights reserved. + +"""Tokenization help for Python programs. + +generate_tokens(readline) is a generator that breaks a stream of +text into Python tokens. It accepts a readline-like method which is called +repeatedly to get the next line of input (or "" for EOF). It generates +5-tuples with these members: + + the token type (see token.py) + the token (a string) + the starting (row, column) indices of the token (a 2-tuple of ints) + the ending (row, column) indices of the token (a 2-tuple of ints) + the original line (string) + +It is designed to match the working of the Python tokenizer exactly, except +that it produces COMMENT tokens for comments and gives type OP for all +operators + +Older entry points + tokenize_loop(readline, tokeneater) + tokenize(readline, tokeneater=printtoken) +are the same, except instead of generating tokens, tokeneater is a callback +function to which the 5 fields described above are passed as 5 arguments, +each time a new token is found.""" + +__author__ = 'Ka-Ping Yee ' +__credits__ = \ + 'GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, Skip Montanaro' + +import string, re +from .token import * + +from . import token +__all__ = [x for x in dir(token) if x[0] != '_'] + ["tokenize", + "generate_tokens", "untokenize"] +del token + +def group(*choices): return '(' + '|'.join(choices) + ')' +def any(*choices): return group(*choices) + '*' +def maybe(*choices): return group(*choices) + '?' + +Whitespace = r'[ \f\t]*' +Comment = r'#[^\r\n]*' +Ignore = Whitespace + any(r'\\\r?\n' + Whitespace) + maybe(Comment) +Name = r'[a-zA-Z_]\w*' + +Binnumber = r'0[bB][01]*' +Hexnumber = r'0[xX][\da-fA-F]*[lL]?' +Octnumber = r'0[oO]?[0-7]*[lL]?' +Decnumber = r'[1-9]\d*[lL]?' +Intnumber = group(Binnumber, Hexnumber, Octnumber, Decnumber) +Exponent = r'[eE][-+]?\d+' +Pointfloat = group(r'\d+\.\d*', r'\.\d+') + maybe(Exponent) +Expfloat = r'\d+' + Exponent +Floatnumber = group(Pointfloat, Expfloat) +Imagnumber = group(r'\d+[jJ]', Floatnumber + r'[jJ]') +Number = group(Imagnumber, Floatnumber, Intnumber) + +# Tail end of ' string. +Single = r"[^'\\]*(?:\\.[^'\\]*)*'" +# Tail end of " string. +Double = r'[^"\\]*(?:\\.[^"\\]*)*"' +# Tail end of ''' string. +Single3 = r"[^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*'''" +# Tail end of """ string. +Double3 = r'[^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*"""' +Triple = group("[ubUB]?[rR]?'''", '[ubUB]?[rR]?"""') +# Single-line ' or " string. +String = group(r"[uU]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*'", + r'[uU]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*"') + +# Because of leftmost-then-longest match semantics, be sure to put the +# longest operators first (e.g., if = came before ==, == would get +# recognized as two instances of =). +Operator = group(r"\*\*=?", r">>=?", r"<<=?", r"<>", r"!=", + r"//=?", r"->", + r"[+\-*/%&|^=<>]=?", + r"~") + +Bracket = '[][(){}]' +Special = group(r'\r?\n', r'[:;.,`@]') +Funny = group(Operator, Bracket, Special) + +PlainToken = group(Number, Funny, String, Name) +Token = Ignore + PlainToken + +# First (or only) line of ' or " string. +ContStr = group(r"[uUbB]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*" + + group("'", r'\\\r?\n'), + r'[uUbB]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*' + + group('"', r'\\\r?\n')) +PseudoExtras = group(r'\\\r?\n', Comment, Triple) +PseudoToken = Whitespace + group(PseudoExtras, Number, Funny, ContStr, Name) + +tokenprog, pseudoprog, single3prog, double3prog = map( + re.compile, (Token, PseudoToken, Single3, Double3)) +endprogs = {"'": re.compile(Single), '"': re.compile(Double), + "'''": single3prog, '"""': double3prog, + "r'''": single3prog, 'r"""': double3prog, + "u'''": single3prog, 'u"""': double3prog, + "b'''": single3prog, 'b"""': double3prog, + "ur'''": single3prog, 'ur"""': double3prog, + "br'''": single3prog, 'br"""': double3prog, + "R'''": single3prog, 'R"""': double3prog, + "U'''": single3prog, 'U"""': double3prog, + "B'''": single3prog, 'B"""': double3prog, + "uR'''": single3prog, 'uR"""': double3prog, + "Ur'''": single3prog, 'Ur"""': double3prog, + "UR'''": single3prog, 'UR"""': double3prog, + "bR'''": single3prog, 'bR"""': double3prog, + "Br'''": single3prog, 'Br"""': double3prog, + "BR'''": single3prog, 'BR"""': double3prog, + 'r': None, 'R': None, + 'u': None, 'U': None, + 'b': None, 'B': None} + +triple_quoted = {} +for t in ("'''", '"""', + "r'''", 'r"""', "R'''", 'R"""', + "u'''", 'u"""', "U'''", 'U"""', + "b'''", 'b"""', "B'''", 'B"""', + "ur'''", 'ur"""', "Ur'''", 'Ur"""', + "uR'''", 'uR"""', "UR'''", 'UR"""', + "br'''", 'br"""', "Br'''", 'Br"""', + "bR'''", 'bR"""', "BR'''", 'BR"""',): + triple_quoted[t] = t +single_quoted = {} +for t in ("'", '"', + "r'", 'r"', "R'", 'R"', + "u'", 'u"', "U'", 'U"', + "b'", 'b"', "B'", 'B"', + "ur'", 'ur"', "Ur'", 'Ur"', + "uR'", 'uR"', "UR'", 'UR"', + "br'", 'br"', "Br'", 'Br"', + "bR'", 'bR"', "BR'", 'BR"', ): + single_quoted[t] = t + +tabsize = 8 + +class TokenError(Exception): pass + +class StopTokenizing(Exception): pass + +def printtoken(type, token, (srow, scol), (erow, ecol), line): # for testing + print "%d,%d-%d,%d:\t%s\t%s" % \ + (srow, scol, erow, ecol, tok_name[type], repr(token)) + +def tokenize(readline, tokeneater=printtoken): + """ + The tokenize() function accepts two parameters: one representing the + input stream, and one providing an output mechanism for tokenize(). + + The first parameter, readline, must be a callable object which provides + the same interface as the readline() method of built-in file objects. + Each call to the function should return one line of input as a string. + + The second parameter, tokeneater, must also be a callable object. It is + called once for each token, with five arguments, corresponding to the + tuples generated by generate_tokens(). + """ + try: + tokenize_loop(readline, tokeneater) + except StopTokenizing: + pass + +# backwards compatible interface +def tokenize_loop(readline, tokeneater): + for token_info in generate_tokens(readline): + tokeneater(*token_info) + +class Untokenizer: + + def __init__(self): + self.tokens = [] + self.prev_row = 1 + self.prev_col = 0 + + def add_whitespace(self, start): + row, col = start + assert row <= self.prev_row + col_offset = col - self.prev_col + if col_offset: + self.tokens.append(" " * col_offset) + + def untokenize(self, iterable): + for t in iterable: + if len(t) == 2: + self.compat(t, iterable) + break + tok_type, token, start, end, line = t + self.add_whitespace(start) + self.tokens.append(token) + self.prev_row, self.prev_col = end + if tok_type in (NEWLINE, NL): + self.prev_row += 1 + self.prev_col = 0 + return "".join(self.tokens) + + def compat(self, token, iterable): + startline = False + indents = [] + toks_append = self.tokens.append + toknum, tokval = token + if toknum in (NAME, NUMBER): + tokval += ' ' + if toknum in (NEWLINE, NL): + startline = True + for tok in iterable: + toknum, tokval = tok[:2] + + if toknum in (NAME, NUMBER): + tokval += ' ' + + if toknum == INDENT: + indents.append(tokval) + continue + elif toknum == DEDENT: + indents.pop() + continue + elif toknum in (NEWLINE, NL): + startline = True + elif startline and indents: + toks_append(indents[-1]) + startline = False + toks_append(tokval) + +def untokenize(iterable): + """Transform tokens back into Python source code. + + Each element returned by the iterable must be a token sequence + with at least two elements, a token number and token value. If + only two tokens are passed, the resulting output is poor. + + Round-trip invariant for full input: + Untokenized source will match input source exactly + + Round-trip invariant for limited intput: + # Output text will tokenize the back to the input + t1 = [tok[:2] for tok in generate_tokens(f.readline)] + newcode = untokenize(t1) + readline = iter(newcode.splitlines(1)).next + t2 = [tok[:2] for tokin generate_tokens(readline)] + assert t1 == t2 + """ + ut = Untokenizer() + return ut.untokenize(iterable) + +def generate_tokens(readline): + """ + The generate_tokens() generator requires one argment, readline, which + must be a callable object which provides the same interface as the + readline() method of built-in file objects. Each call to the function + should return one line of input as a string. Alternately, readline + can be a callable function terminating with StopIteration: + readline = open(myfile).next # Example of alternate readline + + The generator produces 5-tuples with these members: the token type; the + token string; a 2-tuple (srow, scol) of ints specifying the row and + column where the token begins in the source; a 2-tuple (erow, ecol) of + ints specifying the row and column where the token ends in the source; + and the line on which the token was found. The line passed is the + logical line; continuation lines are included. + """ + lnum = parenlev = continued = 0 + namechars, numchars = string.ascii_letters + '_', '0123456789' + contstr, needcont = '', 0 + contline = None + indents = [0] + + while 1: # loop over lines in stream + try: + line = readline() + except StopIteration: + line = '' + lnum = lnum + 1 + pos, max = 0, len(line) + + if contstr: # continued string + if not line: + raise TokenError, ("EOF in multi-line string", strstart) + endmatch = endprog.match(line) + if endmatch: + pos = end = endmatch.end(0) + yield (STRING, contstr + line[:end], + strstart, (lnum, end), contline + line) + contstr, needcont = '', 0 + contline = None + elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n': + yield (ERRORTOKEN, contstr + line, + strstart, (lnum, len(line)), contline) + contstr = '' + contline = None + continue + else: + contstr = contstr + line + contline = contline + line + continue + + elif parenlev == 0 and not continued: # new statement + if not line: break + column = 0 + while pos < max: # measure leading whitespace + if line[pos] == ' ': column = column + 1 + elif line[pos] == '\t': column = (column/tabsize + 1)*tabsize + elif line[pos] == '\f': column = 0 + else: break + pos = pos + 1 + if pos == max: break + + if line[pos] in '#\r\n': # skip comments or blank lines + if line[pos] == '#': + comment_token = line[pos:].rstrip('\r\n') + nl_pos = pos + len(comment_token) + yield (COMMENT, comment_token, + (lnum, pos), (lnum, pos + len(comment_token)), line) + yield (NL, line[nl_pos:], + (lnum, nl_pos), (lnum, len(line)), line) + else: + yield ((NL, COMMENT)[line[pos] == '#'], line[pos:], + (lnum, pos), (lnum, len(line)), line) + continue + + if column > indents[-1]: # count indents or dedents + indents.append(column) + yield (INDENT, line[:pos], (lnum, 0), (lnum, pos), line) + while column < indents[-1]: + if column not in indents: + raise IndentationError( + "unindent does not match any outer indentation level", + ("", lnum, pos, line)) + indents = indents[:-1] + yield (DEDENT, '', (lnum, pos), (lnum, pos), line) + + else: # continued statement + if not line: + raise TokenError, ("EOF in multi-line statement", (lnum, 0)) + continued = 0 + + while pos < max: + pseudomatch = pseudoprog.match(line, pos) + if pseudomatch: # scan for tokens + start, end = pseudomatch.span(1) + spos, epos, pos = (lnum, start), (lnum, end), end + token, initial = line[start:end], line[start] + + if initial in numchars or \ + (initial == '.' and token != '.'): # ordinary number + yield (NUMBER, token, spos, epos, line) + elif initial in '\r\n': + newline = NEWLINE + if parenlev > 0: + newline = NL + yield (newline, token, spos, epos, line) + elif initial == '#': + assert not token.endswith("\n") + yield (COMMENT, token, spos, epos, line) + elif token in triple_quoted: + endprog = endprogs[token] + endmatch = endprog.match(line, pos) + if endmatch: # all on one line + pos = endmatch.end(0) + token = line[start:pos] + yield (STRING, token, spos, (lnum, pos), line) + else: + strstart = (lnum, start) # multiple lines + contstr = line[start:] + contline = line + break + elif initial in single_quoted or \ + token[:2] in single_quoted or \ + token[:3] in single_quoted: + if token[-1] == '\n': # continued string + strstart = (lnum, start) + endprog = (endprogs[initial] or endprogs[token[1]] or + endprogs[token[2]]) + contstr, needcont = line[start:], 1 + contline = line + break + else: # ordinary string + yield (STRING, token, spos, epos, line) + elif initial in namechars: # ordinary name + yield (NAME, token, spos, epos, line) + elif initial == '\\': # continued stmt + # This yield is new; needed for better idempotency: + yield (NL, token, spos, (lnum, pos), line) + continued = 1 + else: + if initial in '([{': parenlev = parenlev + 1 + elif initial in ')]}': parenlev = parenlev - 1 + yield (OP, token, spos, epos, line) + else: + yield (ERRORTOKEN, line[pos], + (lnum, pos), (lnum, pos+1), line) + pos = pos + 1 + + for indent in indents[1:]: # pop remaining indent levels + yield (DEDENT, '', (lnum, 0), (lnum, 0), '') + yield (ENDMARKER, '', (lnum, 0), (lnum, 0), '') + +if __name__ == '__main__': # testing + import sys + if len(sys.argv) > 1: tokenize(open(sys.argv[1]).readline) + else: tokenize(sys.stdin.readline) Added: sandbox/trunk/refactor_pkg/refactor/pygram.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/pygram.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,31 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Export the Python grammar and symbols.""" + +# Python imports +import os + +# Local imports +from .pgen2 import token +from .pgen2 import driver +from . import pytree + +# The grammar file +_GRAMMAR_FILE = os.path.join(os.path.dirname(__file__), "Grammar.txt") + + +class Symbols(object): + + def __init__(self, grammar): + """Initializer. + + Creates an attribute for each grammar symbol (nonterminal), + whose value is the symbol's type (an int >= 256). + """ + for name, symbol in grammar.symbol2number.iteritems(): + setattr(self, name, symbol) + + +python_grammar = driver.load_grammar(_GRAMMAR_FILE) +python_symbols = Symbols(python_grammar) Added: sandbox/trunk/refactor_pkg/refactor/pytree.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/pytree.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,846 @@ +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +""" +Python parse tree definitions. + +This is a very concrete parse tree; we need to keep every token and +even the comments and whitespace between tokens. + +There's also a pattern matching implementation here. +""" + +__author__ = "Guido van Rossum " + +import sys +from StringIO import StringIO + + +HUGE = 0x7FFFFFFF # maximum repeat count, default max + +_type_reprs = {} +def type_repr(type_num): + global _type_reprs + if not _type_reprs: + from .pygram import python_symbols + # printing tokens is possible but not as useful + # from .pgen2 import token // token.__dict__.items(): + for name, val in python_symbols.__dict__.items(): + if type(val) == int: _type_reprs[val] = name + return _type_reprs.setdefault(type_num, type_num) + + +class Base(object): + + """ + Abstract base class for Node and Leaf. + + This provides some default functionality and boilerplate using the + template pattern. + + A node may be a subnode of at most one parent. + """ + + # Default values for instance variables + type = None # int: token number (< 256) or symbol number (>= 256) + parent = None # Parent node pointer, or None + children = () # Tuple of subnodes + was_changed = False + + def __new__(cls, *args, **kwds): + """Constructor that prevents Base from being instantiated.""" + assert cls is not Base, "Cannot instantiate Base" + return object.__new__(cls) + + def __eq__(self, other): + """ + Compare two nodes for equality. + + This calls the method _eq(). + """ + if self.__class__ is not other.__class__: + return NotImplemented + return self._eq(other) + + def __ne__(self, other): + """ + Compare two nodes for inequality. + + This calls the method _eq(). + """ + if self.__class__ is not other.__class__: + return NotImplemented + return not self._eq(other) + + def _eq(self, other): + """ + Compare two nodes for equality. + + This is called by __eq__ and __ne__. It is only called if the two nodes + have the same type. This must be implemented by the concrete subclass. + Nodes should be considered equal if they have the same structure, + ignoring the prefix string and other context information. + """ + raise NotImplementedError + + def clone(self): + """ + Return a cloned (deep) copy of self. + + This must be implemented by the concrete subclass. + """ + raise NotImplementedError + + def post_order(self): + """ + Return a post-order iterator for the tree. + + This must be implemented by the concrete subclass. + """ + raise NotImplementedError + + def pre_order(self): + """ + Return a pre-order iterator for the tree. + + This must be implemented by the concrete subclass. + """ + raise NotImplementedError + + def set_prefix(self, prefix): + """ + Set the prefix for the node (see Leaf class). + + This must be implemented by the concrete subclass. + """ + raise NotImplementedError + + def get_prefix(self): + """ + Return the prefix for the node (see Leaf class). + + This must be implemented by the concrete subclass. + """ + raise NotImplementedError + + def replace(self, new): + """Replace this node with a new one in the parent.""" + assert self.parent is not None, str(self) + assert new is not None + if not isinstance(new, list): + new = [new] + l_children = [] + found = False + for ch in self.parent.children: + if ch is self: + assert not found, (self.parent.children, self, new) + if new is not None: + l_children.extend(new) + found = True + else: + l_children.append(ch) + assert found, (self.children, self, new) + self.parent.changed() + self.parent.children = l_children + for x in new: + x.parent = self.parent + self.parent = None + + def get_lineno(self): + """Return the line number which generated the invocant node.""" + node = self + while not isinstance(node, Leaf): + if not node.children: + return + node = node.children[0] + return node.lineno + + def changed(self): + if self.parent: + self.parent.changed() + self.was_changed = True + + def remove(self): + """ + Remove the node from the tree. Returns the position of the node in its + parent's children before it was removed. + """ + if self.parent: + for i, node in enumerate(self.parent.children): + if node is self: + self.parent.changed() + del self.parent.children[i] + self.parent = None + return i + + @property + def next_sibling(self): + """ + The node immediately following the invocant in their parent's children + list. If the invocant does not have a next sibling, it is None + """ + if self.parent is None: + return None + + # Can't use index(); we need to test by identity + for i, child in enumerate(self.parent.children): + if child is self: + try: + return self.parent.children[i+1] + except IndexError: + return None + + @property + def prev_sibling(self): + """ + The node immediately preceding the invocant in their parent's children + list. If the invocant does not have a previous sibling, it is None. + """ + if self.parent is None: + return None + + # Can't use index(); we need to test by identity + for i, child in enumerate(self.parent.children): + if child is self: + if i == 0: + return None + return self.parent.children[i-1] + + def get_suffix(self): + """ + Return the string immediately following the invocant node. This is + effectively equivalent to node.next_sibling.get_prefix() + """ + next_sib = self.next_sibling + if next_sib is None: + return "" + return next_sib.get_prefix() + + +class Node(Base): + + """Concrete implementation for interior nodes.""" + + def __init__(self, type, children, context=None, prefix=None): + """ + Initializer. + + Takes a type constant (a symbol number >= 256), a sequence of + child nodes, and an optional context keyword argument. + + As a side effect, the parent pointers of the children are updated. + """ + assert type >= 256, type + self.type = type + self.children = list(children) + for ch in self.children: + assert ch.parent is None, repr(ch) + ch.parent = self + if prefix is not None: + self.set_prefix(prefix) + + def __repr__(self): + """Return a canonical string representation.""" + return "%s(%s, %r)" % (self.__class__.__name__, + type_repr(self.type), + self.children) + + def __str__(self): + """ + Return a pretty string representation. + + This reproduces the input source exactly. + """ + return "".join(map(str, self.children)) + + def _eq(self, other): + """Compare two nodes for equality.""" + return (self.type, self.children) == (other.type, other.children) + + def clone(self): + """Return a cloned (deep) copy of self.""" + return Node(self.type, [ch.clone() for ch in self.children]) + + def post_order(self): + """Return a post-order iterator for the tree.""" + for child in self.children: + for node in child.post_order(): + yield node + yield self + + def pre_order(self): + """Return a pre-order iterator for the tree.""" + yield self + for child in self.children: + for node in child.post_order(): + yield node + + def set_prefix(self, prefix): + """ + Set the prefix for the node. + + This passes the responsibility on to the first child. + """ + if self.children: + self.children[0].set_prefix(prefix) + + def get_prefix(self): + """ + Return the prefix for the node. + + This passes the call on to the first child. + """ + if not self.children: + return "" + return self.children[0].get_prefix() + + def set_child(self, i, child): + """ + Equivalent to 'node.children[i] = child'. This method also sets the + child's parent attribute appropriately. + """ + child.parent = self + self.children[i].parent = None + self.children[i] = child + self.changed() + + def insert_child(self, i, child): + """ + Equivalent to 'node.children.insert(i, child)'. This method also sets + the child's parent attribute appropriately. + """ + child.parent = self + self.children.insert(i, child) + self.changed() + + def append_child(self, child): + """ + Equivalent to 'node.children.append(child)'. This method also sets the + child's parent attribute appropriately. + """ + child.parent = self + self.children.append(child) + self.changed() + + +class Leaf(Base): + + """Concrete implementation for leaf nodes.""" + + # Default values for instance variables + prefix = "" # Whitespace and comments preceding this token in the input + lineno = 0 # Line where this token starts in the input + column = 0 # Column where this token tarts in the input + + def __init__(self, type, value, context=None, prefix=None): + """ + Initializer. + + Takes a type constant (a token number < 256), a string value, and an + optional context keyword argument. + """ + assert 0 <= type < 256, type + if context is not None: + self.prefix, (self.lineno, self.column) = context + self.type = type + self.value = value + if prefix is not None: + self.prefix = prefix + + def __repr__(self): + """Return a canonical string representation.""" + return "%s(%r, %r)" % (self.__class__.__name__, + self.type, + self.value) + + def __str__(self): + """ + Return a pretty string representation. + + This reproduces the input source exactly. + """ + return self.prefix + str(self.value) + + def _eq(self, other): + """Compare two nodes for equality.""" + return (self.type, self.value) == (other.type, other.value) + + def clone(self): + """Return a cloned (deep) copy of self.""" + return Leaf(self.type, self.value, + (self.prefix, (self.lineno, self.column))) + + def post_order(self): + """Return a post-order iterator for the tree.""" + yield self + + def pre_order(self): + """Return a pre-order iterator for the tree.""" + yield self + + def set_prefix(self, prefix): + """Set the prefix for the node.""" + self.changed() + self.prefix = prefix + + def get_prefix(self): + """Return the prefix for the node.""" + return self.prefix + + +def convert(gr, raw_node): + """ + Convert raw node information to a Node or Leaf instance. + + This is passed to the parser driver which calls it whenever a reduction of a + grammar rule produces a new complete node, so that the tree is build + strictly bottom-up. + """ + type, value, context, children = raw_node + if children or type in gr.number2symbol: + # If there's exactly one child, return that child instead of + # creating a new node. + if len(children) == 1: + return children[0] + return Node(type, children, context=context) + else: + return Leaf(type, value, context=context) + + +class BasePattern(object): + + """ + A pattern is a tree matching pattern. + + It looks for a specific node type (token or symbol), and + optionally for a specific content. + + This is an abstract base class. There are three concrete + subclasses: + + - LeafPattern matches a single leaf node; + - NodePattern matches a single node (usually non-leaf); + - WildcardPattern matches a sequence of nodes of variable length. + """ + + # Defaults for instance variables + type = None # Node type (token if < 256, symbol if >= 256) + content = None # Optional content matching pattern + name = None # Optional name used to store match in results dict + + def __new__(cls, *args, **kwds): + """Constructor that prevents BasePattern from being instantiated.""" + assert cls is not BasePattern, "Cannot instantiate BasePattern" + return object.__new__(cls) + + def __repr__(self): + args = [type_repr(self.type), self.content, self.name] + while args and args[-1] is None: + del args[-1] + return "%s(%s)" % (self.__class__.__name__, ", ".join(map(repr, args))) + + def optimize(self): + """ + A subclass can define this as a hook for optimizations. + + Returns either self or another node with the same effect. + """ + return self + + def match(self, node, results=None): + """ + Does this pattern exactly match a node? + + Returns True if it matches, False if not. + + If results is not None, it must be a dict which will be + updated with the nodes matching named subpatterns. + + Default implementation for non-wildcard patterns. + """ + if self.type is not None and node.type != self.type: + return False + if self.content is not None: + r = None + if results is not None: + r = {} + if not self._submatch(node, r): + return False + if r: + results.update(r) + if results is not None and self.name: + results[self.name] = node + return True + + def match_seq(self, nodes, results=None): + """ + Does this pattern exactly match a sequence of nodes? + + Default implementation for non-wildcard patterns. + """ + if len(nodes) != 1: + return False + return self.match(nodes[0], results) + + def generate_matches(self, nodes): + """ + Generator yielding all matches for this pattern. + + Default implementation for non-wildcard patterns. + """ + r = {} + if nodes and self.match(nodes[0], r): + yield 1, r + + +class LeafPattern(BasePattern): + + def __init__(self, type=None, content=None, name=None): + """ + Initializer. Takes optional type, content, and name. + + The type, if given must be a token type (< 256). If not given, + this matches any *leaf* node; the content may still be required. + + The content, if given, must be a string. + + If a name is given, the matching node is stored in the results + dict under that key. + """ + if type is not None: + assert 0 <= type < 256, type + if content is not None: + assert isinstance(content, basestring), repr(content) + self.type = type + self.content = content + self.name = name + + def match(self, node, results=None): + """Override match() to insist on a leaf node.""" + if not isinstance(node, Leaf): + return False + return BasePattern.match(self, node, results) + + def _submatch(self, node, results=None): + """ + Match the pattern's content to the node's children. + + This assumes the node type matches and self.content is not None. + + Returns True if it matches, False if not. + + If results is not None, it must be a dict which will be + updated with the nodes matching named subpatterns. + + When returning False, the results dict may still be updated. + """ + return self.content == node.value + + +class NodePattern(BasePattern): + + wildcards = False + + def __init__(self, type=None, content=None, name=None): + """ + Initializer. Takes optional type, content, and name. + + The type, if given, must be a symbol type (>= 256). If the + type is None this matches *any* single node (leaf or not), + except if content is not None, in which it only matches + non-leaf nodes that also match the content pattern. + + The content, if not None, must be a sequence of Patterns that + must match the node's children exactly. If the content is + given, the type must not be None. + + If a name is given, the matching node is stored in the results + dict under that key. + """ + if type is not None: + assert type >= 256, type + if content is not None: + assert not isinstance(content, basestring), repr(content) + content = list(content) + for i, item in enumerate(content): + assert isinstance(item, BasePattern), (i, item) + if isinstance(item, WildcardPattern): + self.wildcards = True + self.type = type + self.content = content + self.name = name + + def _submatch(self, node, results=None): + """ + Match the pattern's content to the node's children. + + This assumes the node type matches and self.content is not None. + + Returns True if it matches, False if not. + + If results is not None, it must be a dict which will be + updated with the nodes matching named subpatterns. + + When returning False, the results dict may still be updated. + """ + if self.wildcards: + for c, r in generate_matches(self.content, node.children): + if c == len(node.children): + if results is not None: + results.update(r) + return True + return False + if len(self.content) != len(node.children): + return False + for subpattern, child in zip(self.content, node.children): + if not subpattern.match(child, results): + return False + return True + + +class WildcardPattern(BasePattern): + + """ + A wildcard pattern can match zero or more nodes. + + This has all the flexibility needed to implement patterns like: + + .* .+ .? .{m,n} + (a b c | d e | f) + (...)* (...)+ (...)? (...){m,n} + + except it always uses non-greedy matching. + """ + + def __init__(self, content=None, min=0, max=HUGE, name=None): + """ + Initializer. + + Args: + content: optional sequence of subsequences of patterns; + if absent, matches one node; + if present, each subsequence is an alternative [*] + min: optinal minumum number of times to match, default 0 + max: optional maximum number of times tro match, default HUGE + name: optional name assigned to this match + + [*] Thus, if content is [[a, b, c], [d, e], [f, g, h]] this is + equivalent to (a b c | d e | f g h); if content is None, + this is equivalent to '.' in regular expression terms. + The min and max parameters work as follows: + min=0, max=maxint: .* + min=1, max=maxint: .+ + min=0, max=1: .? + min=1, max=1: . + If content is not None, replace the dot with the parenthesized + list of alternatives, e.g. (a b c | d e | f g h)* + """ + assert 0 <= min <= max <= HUGE, (min, max) + if content is not None: + content = tuple(map(tuple, content)) # Protect against alterations + # Check sanity of alternatives + assert len(content), repr(content) # Can't have zero alternatives + for alt in content: + assert len(alt), repr(alt) # Can have empty alternatives + self.content = content + self.min = min + self.max = max + self.name = name + + def optimize(self): + """Optimize certain stacked wildcard patterns.""" + subpattern = None + if (self.content is not None and + len(self.content) == 1 and len(self.content[0]) == 1): + subpattern = self.content[0][0] + if self.min == 1 and self.max == 1: + if self.content is None: + return NodePattern(name=self.name) + if subpattern is not None and self.name == subpattern.name: + return subpattern.optimize() + if (self.min <= 1 and isinstance(subpattern, WildcardPattern) and + subpattern.min <= 1 and self.name == subpattern.name): + return WildcardPattern(subpattern.content, + self.min*subpattern.min, + self.max*subpattern.max, + subpattern.name) + return self + + def match(self, node, results=None): + """Does this pattern exactly match a node?""" + return self.match_seq([node], results) + + def match_seq(self, nodes, results=None): + """Does this pattern exactly match a sequence of nodes?""" + for c, r in self.generate_matches(nodes): + if c == len(nodes): + if results is not None: + results.update(r) + if self.name: + results[self.name] = list(nodes) + return True + return False + + def generate_matches(self, nodes): + """ + Generator yielding matches for a sequence of nodes. + + Args: + nodes: sequence of nodes + + Yields: + (count, results) tuples where: + count: the match comprises nodes[:count]; + results: dict containing named submatches. + """ + if self.content is None: + # Shortcut for special case (see __init__.__doc__) + for count in xrange(self.min, 1 + min(len(nodes), self.max)): + r = {} + if self.name: + r[self.name] = nodes[:count] + yield count, r + elif self.name == "bare_name": + yield self._bare_name_matches(nodes) + else: + # The reason for this is that hitting the recursion limit usually + # results in some ugly messages about how RuntimeErrors are being + # ignored. + save_stderr = sys.stderr + sys.stderr = StringIO() + try: + for count, r in self._recursive_matches(nodes, 0): + if self.name: + r[self.name] = nodes[:count] + yield count, r + except RuntimeError: + # We fall back to the iterative pattern matching scheme if the recursive + # scheme hits the recursion limit. + for count, r in self._iterative_matches(nodes): + if self.name: + r[self.name] = nodes[:count] + yield count, r + finally: + sys.stderr = save_stderr + + def _iterative_matches(self, nodes): + """Helper to iteratively yield the matches.""" + nodelen = len(nodes) + if 0 >= self.min: + yield 0, {} + + results = [] + # generate matches that use just one alt from self.content + for alt in self.content: + for c, r in generate_matches(alt, nodes): + yield c, r + results.append((c, r)) + + # for each match, iterate down the nodes + while results: + new_results = [] + for c0, r0 in results: + # stop if the entire set of nodes has been matched + if c0 < nodelen and c0 <= self.max: + for alt in self.content: + for c1, r1 in generate_matches(alt, nodes[c0:]): + if c1 > 0: + r = {} + r.update(r0) + r.update(r1) + yield c0 + c1, r + new_results.append((c0 + c1, r)) + results = new_results + + def _bare_name_matches(self, nodes): + """Special optimized matcher for bare_name.""" + count = 0 + r = {} + done = False + max = len(nodes) + while not done and count < max: + done = True + for leaf in self.content: + if leaf[0].match(nodes[count], r): + count += 1 + done = False + break + r[self.name] = nodes[:count] + return count, r + + def _recursive_matches(self, nodes, count): + """Helper to recursively yield the matches.""" + assert self.content is not None + if count >= self.min: + yield 0, {} + if count < self.max: + for alt in self.content: + for c0, r0 in generate_matches(alt, nodes): + for c1, r1 in self._recursive_matches(nodes[c0:], count+1): + r = {} + r.update(r0) + r.update(r1) + yield c0 + c1, r + + +class NegatedPattern(BasePattern): + + def __init__(self, content=None): + """ + Initializer. + + The argument is either a pattern or None. If it is None, this + only matches an empty sequence (effectively '$' in regex + lingo). If it is not None, this matches whenever the argument + pattern doesn't have any matches. + """ + if content is not None: + assert isinstance(content, BasePattern), repr(content) + self.content = content + + def match(self, node): + # We never match a node in its entirety + return False + + def match_seq(self, nodes): + # We only match an empty sequence of nodes in its entirety + return len(nodes) == 0 + + def generate_matches(self, nodes): + if self.content is None: + # Return a match if there is an empty sequence + if len(nodes) == 0: + yield 0, {} + else: + # Return a match if the argument pattern has no matches + for c, r in self.content.generate_matches(nodes): + return + yield 0, {} + + +def generate_matches(patterns, nodes): + """ + Generator yielding matches for a sequence of patterns and nodes. + + Args: + patterns: a sequence of patterns + nodes: a sequence of nodes + + Yields: + (count, results) tuples where: + count: the entire sequence of patterns matches nodes[:count]; + results: dict containing named submatches. + """ + if not patterns: + yield 0, {} + else: + p, rest = patterns[0], patterns[1:] + for c0, r0 in p.generate_matches(nodes): + if not rest: + yield c0, r0 + else: + for c1, r1 in generate_matches(rest, nodes[c0:]): + r = {} + r.update(r0) + r.update(r1) + yield c0 + c1, r Added: sandbox/trunk/refactor_pkg/refactor/refactor.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/refactor.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,515 @@ +#!/usr/bin/env python2.5 +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Refactoring framework. + +Used as a main program, this can refactor any number of files and/or +recursively descend down directories. Imported as a module, this +provides infrastructure to write your own refactoring tool. +""" + +__author__ = "Guido van Rossum " + + +# Python imports +import os +import sys +import difflib +import logging +import operator +from collections import defaultdict +from itertools import chain + +# Local imports +from .pgen2 import driver +from .pgen2 import tokenize + +from . import pytree +from . import patcomp +from . import fixes +from . import pygram + + +def get_all_fix_names(fixer_pkg, remove_prefix=True): + """Return a sorted list of all available fix names in the given package.""" + pkg = __import__(fixer_pkg, [], [], ["*"]) + fixer_dir = os.path.dirname(pkg.__file__) + fix_names = [] + for name in sorted(os.listdir(fixer_dir)): + if name.startswith("fix_") and name.endswith(".py"): + if remove_prefix: + name = name[4:] + fix_names.append(name[:-3]) + return fix_names + +def get_head_types(pat): + """ Accepts a pytree Pattern Node and returns a set + of the pattern types which will match first. """ + + if isinstance(pat, (pytree.NodePattern, pytree.LeafPattern)): + # NodePatters must either have no type and no content + # or a type and content -- so they don't get any farther + # Always return leafs + return set([pat.type]) + + if isinstance(pat, pytree.NegatedPattern): + if pat.content: + return get_head_types(pat.content) + return set([None]) # Negated Patterns don't have a type + + if isinstance(pat, pytree.WildcardPattern): + # Recurse on each node in content + r = set() + for p in pat.content: + for x in p: + r.update(get_head_types(x)) + return r + + raise Exception("Oh no! I don't understand pattern %s" %(pat)) + +def get_headnode_dict(fixer_list): + """ Accepts a list of fixers and returns a dictionary + of head node type --> fixer list. """ + head_nodes = defaultdict(list) + for fixer in fixer_list: + if not fixer.pattern: + head_nodes[None].append(fixer) + continue + for t in get_head_types(fixer.pattern): + head_nodes[t].append(fixer) + return head_nodes + +def get_fixers_from_package(pkg_name): + """ + Return the fully qualified names for fixers in the package pkg_name. + """ + return [pkg_name + "." + fix_name + for fix_name in get_all_fix_names(pkg_name, False)] + + +class FixerError(Exception): + """A fixer could not be loaded.""" + + +class RefactoringTool(object): + + _default_options = {"print_function": False} + + CLASS_PREFIX = "Fix" # The prefix for fixer classes + FILE_PREFIX = "fix_" # The prefix for modules with a fixer within + + def __init__(self, fixer_names, options=None, explicit=None): + """Initializer. + + Args: + fixer_names: a list of fixers to import + options: an dict with configuration. + explicit: a list of fixers to run even if they are explicit. + """ + self.fixers = fixer_names + self.explicit = explicit or [] + self.options = self._default_options.copy() + if options is not None: + self.options.update(options) + self.errors = [] + self.logger = logging.getLogger("RefactoringTool") + self.fixer_log = [] + self.wrote = False + if self.options["print_function"]: + del pygram.python_grammar.keywords["print"] + self.driver = driver.Driver(pygram.python_grammar, + convert=pytree.convert, + logger=self.logger) + self.pre_order, self.post_order = self.get_fixers() + + self.pre_order_heads = get_headnode_dict(self.pre_order) + self.post_order_heads = get_headnode_dict(self.post_order) + + self.files = [] # List of files that were or should be modified + + def get_fixers(self): + """Inspects the options to load the requested patterns and handlers. + + Returns: + (pre_order, post_order), where pre_order is the list of fixers that + want a pre-order AST traversal, and post_order is the list that want + post-order traversal. + """ + pre_order_fixers = [] + post_order_fixers = [] + for fix_mod_path in self.fixers: + mod = __import__(fix_mod_path, {}, {}, ["*"]) + fix_name = fix_mod_path.rsplit(".", 1)[-1] + if fix_name.startswith(self.FILE_PREFIX): + fix_name = fix_name[len(self.FILE_PREFIX):] + parts = fix_name.split("_") + class_name = self.CLASS_PREFIX + "".join([p.title() for p in parts]) + try: + fix_class = getattr(mod, class_name) + except AttributeError: + raise FixerError("Can't find %s.%s" % (fix_name, class_name)) + fixer = fix_class(self.options, self.fixer_log) + if fixer.explicit and self.explicit is not True and \ + fix_mod_path not in self.explicit: + self.log_message("Skipping implicit fixer: %s", fix_name) + continue + + self.log_debug("Adding transformation: %s", fix_name) + if fixer.order == "pre": + pre_order_fixers.append(fixer) + elif fixer.order == "post": + post_order_fixers.append(fixer) + else: + raise FixerError("Illegal fixer order: %r" % fixer.order) + + key_func = operator.attrgetter("run_order") + pre_order_fixers.sort(key=key_func) + post_order_fixers.sort(key=key_func) + return (pre_order_fixers, post_order_fixers) + + def log_error(self, msg, *args, **kwds): + """Called when an error occurs.""" + raise + + def log_message(self, msg, *args): + """Hook to log a message.""" + if args: + msg = msg % args + self.logger.info(msg) + + def log_debug(self, msg, *args): + if args: + msg = msg % args + self.logger.debug(msg) + + def print_output(self, lines): + """Called with lines of output to give to the user.""" + pass + + def refactor(self, items, write=False, doctests_only=False): + """Refactor a list of files and directories.""" + for dir_or_file in items: + if os.path.isdir(dir_or_file): + self.refactor_dir(dir_or_file, write, doctests_only) + else: + self.refactor_file(dir_or_file, write, doctests_only) + + def refactor_dir(self, dir_name, write=False, doctests_only=False): + """Descends down a directory and refactor every Python file found. + + Python files are assumed to have a .py extension. + + Files and subdirectories starting with '.' are skipped. + """ + 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 name.endswith("py"): + fullname = os.path.join(dirpath, name) + self.refactor_file(fullname, write, doctests_only) + # Modify dirnames in-place to remove subdirs with leading dots + dirnames[:] = [dn for dn in dirnames if not dn.startswith(".")] + + def refactor_file(self, filename, write=False, doctests_only=False): + """Refactors a file.""" + try: + f = open(filename) + except IOError, err: + self.log_error("Can't open %s: %s", filename, err) + return + try: + input = f.read() + "\n" # Silence certain parse errors + finally: + f.close() + if doctests_only: + self.log_debug("Refactoring doctests in %s", filename) + output = self.refactor_docstring(input, filename) + if output != input: + self.processed_file(output, filename, input, write=write) + else: + self.log_debug("No doctest changes in %s", filename) + else: + tree = self.refactor_string(input, filename) + if tree and tree.was_changed: + # The [:-1] is to take off the \n we added earlier + self.processed_file(str(tree)[:-1], filename, write=write) + else: + self.log_debug("No changes in %s", filename) + + def refactor_string(self, data, name): + """Refactor a given input string. + + Args: + data: a string holding the code to be refactored. + name: a human-readable name for use in error/log messages. + + Returns: + An AST corresponding to the refactored input stream; None if + there were errors during the parse. + """ + try: + tree = self.driver.parse_string(data) + except Exception, err: + self.log_error("Can't parse %s: %s: %s", + name, err.__class__.__name__, err) + return + self.log_debug("Refactoring %s", name) + self.refactor_tree(tree, name) + return tree + + def refactor_stdin(self, doctests_only=False): + input = sys.stdin.read() + if doctests_only: + self.log_debug("Refactoring doctests in stdin") + output = self.refactor_docstring(input, "") + if output != input: + self.processed_file(output, "", input) + else: + self.log_debug("No doctest changes in stdin") + else: + tree = self.refactor_string(input, "") + if tree and tree.was_changed: + self.processed_file(str(tree), "", input) + else: + self.log_debug("No changes in stdin") + + def refactor_tree(self, tree, name): + """Refactors a parse tree (modifying the tree in place). + + Args: + tree: a pytree.Node instance representing the root of the tree + to be refactored. + name: a human-readable name for this tree. + + Returns: + True if the tree was modified, False otherwise. + """ + for fixer in chain(self.pre_order, self.post_order): + fixer.start_tree(tree, name) + + self.traverse_by(self.pre_order_heads, tree.pre_order()) + self.traverse_by(self.post_order_heads, tree.post_order()) + + for fixer in chain(self.pre_order, self.post_order): + fixer.finish_tree(tree, name) + return tree.was_changed + + def traverse_by(self, fixers, traversal): + """Traverse an AST, applying a set of fixers to each node. + + This is a helper method for refactor_tree(). + + Args: + fixers: a list of fixer instances. + traversal: a generator that yields AST nodes. + + Returns: + None + """ + if not fixers: + return + for node in traversal: + for fixer in fixers[node.type] + fixers[None]: + results = fixer.match(node) + if results: + new = fixer.transform(node, results) + if new is not None and (new != node or + str(new) != str(node)): + node.replace(new) + node = new + + def processed_file(self, new_text, filename, old_text=None, write=False): + """ + Called when a file has been refactored, and there are changes. + """ + self.files.append(filename) + if old_text is None: + try: + f = open(filename, "r") + except IOError, err: + self.log_error("Can't read %s: %s", filename, err) + return + try: + old_text = f.read() + finally: + f.close() + if old_text == new_text: + self.log_debug("No changes to %s", filename) + return + self.print_output(diff_texts(old_text, new_text, filename)) + if write: + self.write_file(new_text, filename, old_text) + else: + self.log_debug("Not writing changes to %s", filename) + + def write_file(self, new_text, filename, old_text): + """Writes a string to a file. + + It first shows a unified diff between the old text and the new text, and + then rewrites the file; the latter is only done if the write option is + set. + """ + try: + f = open(filename, "w") + except os.error, err: + self.log_error("Can't create %s: %s", filename, err) + return + try: + f.write(new_text) + except os.error, err: + self.log_error("Can't write %s: %s", filename, err) + finally: + f.close() + self.log_debug("Wrote changes to %s", filename) + self.wrote = True + + PS1 = ">>> " + PS2 = "... " + + def refactor_docstring(self, input, filename): + """Refactors a docstring, looking for doctests. + + This returns a modified version of the input string. It looks + for doctests, which start with a ">>>" prompt, and may be + continued with "..." prompts, as long as the "..." is indented + the same as the ">>>". + + (Unfortunately we can't use the doctest module's parser, + since, like most parsers, it is not geared towards preserving + the original source.) + """ + result = [] + block = None + block_lineno = None + indent = None + lineno = 0 + for line in input.splitlines(True): + lineno += 1 + if line.lstrip().startswith(self.PS1): + if block is not None: + result.extend(self.refactor_doctest(block, block_lineno, + indent, filename)) + block_lineno = lineno + block = [line] + i = line.find(self.PS1) + indent = line[:i] + elif (indent is not None and + (line.startswith(indent + self.PS2) or + line == indent + self.PS2.rstrip() + "\n")): + block.append(line) + else: + if block is not None: + result.extend(self.refactor_doctest(block, block_lineno, + indent, filename)) + block = None + indent = None + result.append(line) + if block is not None: + result.extend(self.refactor_doctest(block, block_lineno, + indent, filename)) + return "".join(result) + + def refactor_doctest(self, block, lineno, indent, filename): + """Refactors one doctest. + + A doctest is given as a block of lines, the first of which starts + with ">>>" (possibly indented), while the remaining lines start + with "..." (identically indented). + + """ + try: + tree = self.parse_block(block, lineno, indent) + except Exception, err: + if self.log.isEnabledFor(logging.DEBUG): + for line in block: + self.log_debug("Source: %s", line.rstrip("\n")) + self.log_error("Can't parse docstring in %s line %s: %s: %s", + filename, lineno, err.__class__.__name__, err) + return block + if self.refactor_tree(tree, filename): + new = str(tree).splitlines(True) + # Undo the adjustment of the line numbers in wrap_toks() below. + clipped, new = new[:lineno-1], new[lineno-1:] + assert clipped == ["\n"] * (lineno-1), clipped + if not new[-1].endswith("\n"): + new[-1] += "\n" + block = [indent + self.PS1 + new.pop(0)] + if new: + block += [indent + self.PS2 + line for line in new] + return block + + def summarize(self): + if self.wrote: + were = "were" + else: + were = "need to be" + if not self.files: + self.log_message("No files %s modified.", were) + else: + self.log_message("Files that %s modified:", were) + for file in self.files: + self.log_message(file) + if self.fixer_log: + self.log_message("Warnings/messages while refactoring:") + for message in self.fixer_log: + self.log_message(message) + if self.errors: + if len(self.errors) == 1: + self.log_message("There was 1 error:") + else: + self.log_message("There were %d errors:", len(self.errors)) + for msg, args, kwds in self.errors: + self.log_message(msg, *args, **kwds) + + def parse_block(self, block, lineno, indent): + """Parses a block into a tree. + + This is necessary to get correct line number / offset information + in the parser diagnostics and embedded into the parse tree. + """ + return self.driver.parse_tokens(self.wrap_toks(block, lineno, indent)) + + def wrap_toks(self, block, lineno, indent): + """Wraps a tokenize stream to systematically modify start/end.""" + tokens = tokenize.generate_tokens(self.gen_lines(block, indent).next) + for type, value, (line0, col0), (line1, col1), line_text in tokens: + line0 += lineno - 1 + line1 += lineno - 1 + # Don't bother updating the columns; this is too complicated + # since line_text would also have to be updated and it would + # still break for tokens spanning lines. Let the user guess + # that the column numbers for doctests are relative to the + # end of the prompt string (PS1 or PS2). + yield type, value, (line0, col0), (line1, col1), line_text + + + def gen_lines(self, block, indent): + """Generates lines as expected by tokenize from a list of lines. + + This strips the first len(indent + self.PS1) characters off each line. + """ + prefix1 = indent + self.PS1 + prefix2 = indent + self.PS2 + prefix = prefix1 + for line in block: + if line.startswith(prefix): + yield line[len(prefix):] + elif line == prefix.rstrip() + "\n": + yield "\n" + else: + raise AssertionError("line=%r, prefix=%r" % (line, prefix)) + prefix = prefix2 + while True: + yield "" + + +def diff_texts(a, b, filename): + """Return a unified diff of two strings.""" + a = a.splitlines() + b = b.splitlines() + return difflib.unified_diff(a, b, filename, filename, + "(original)", "(refactored)", + lineterm="") Added: sandbox/trunk/refactor_pkg/refactor/tests/__init__.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/tests/__init__.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,24 @@ +"""Make tests/ into a package. This allows us to "import tests" and +have tests.all_tests be a TestSuite representing all test cases +from all test_*.py files in tests/.""" +# Author: Collin Winter + +import os +import os.path +import unittest +import types + +from . import support + +all_tests = unittest.TestSuite() + +tests_dir = os.path.join(os.path.dirname(__file__), '..', 'tests') +tests = [t[0:-3] for t in os.listdir(tests_dir) + if t.startswith('test_') and t.endswith('.py')] + +loader = unittest.TestLoader() + +for t in tests: + __import__("",globals(),locals(),[t],level=1) + mod = globals()[t] + all_tests.addTests(loader.loadTestsFromModule(mod)) Added: sandbox/trunk/refactor_pkg/refactor/tests/data/README ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/tests/data/README Wed Apr 1 21:02:05 2009 @@ -0,0 +1,6 @@ +In this directory: +- py2_test_grammar.py -- test file that exercises most/all of Python 2.x's grammar. +- py3_test_grammar.py -- test file that exercises most/all of Python 3.x's grammar. +- infinite_recursion.py -- test file that causes refactor's faster recursive pattern matching + scheme to fail, but passes when refactor falls back to iterative pattern matching. +- fixes/ -- for use by test_refactor.py Added: sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/bad_order.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/bad_order.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,5 @@ +from refactor.fixer_base import BaseFix + +class FixBadOrder(BaseFix): + + order = "crazy" Added: sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/myfixes/__init__.py ============================================================================== Added: sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/myfixes/fix_explicit.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/myfixes/fix_explicit.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,6 @@ +from refactor.fixer_base import BaseFix + +class FixExplicit(BaseFix): + explicit = True + + def match(self): return False Added: sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/myfixes/fix_first.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/myfixes/fix_first.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,6 @@ +from refactor.fixer_base import BaseFix + +class FixFirst(BaseFix): + run_order = 1 + + def match(self, node): return False Added: sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/myfixes/fix_last.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/myfixes/fix_last.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,7 @@ +from refactor.fixer_base import BaseFix + +class FixLast(BaseFix): + + run_order = 10 + + def match(self, node): return False Added: sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/myfixes/fix_parrot.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/myfixes/fix_parrot.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,13 @@ +from refactor.fixer_base import BaseFix +from refactor.fixer_util import Name + +class FixParrot(BaseFix): + """ + Change functions named 'parrot' to 'cheese'. + """ + + PATTERN = """funcdef < 'def' name='parrot' any* >""" + + def transform(self, node, results): + name = results["name"] + name.replace(Name("cheese", name.get_prefix())) Added: sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/myfixes/fix_preorder.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/myfixes/fix_preorder.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,6 @@ +from refactor.fixer_base import BaseFix + +class FixPreorder(BaseFix): + order = "pre" + + def match(self, node): return False Added: sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/no_fixer_cls.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/no_fixer_cls.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1 @@ +# This is empty so trying to fetch the fixer class gives an AttributeError Added: sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/parrot_example.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/tests/data/fixers/parrot_example.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,2 @@ +def parrot(): + pass Added: sandbox/trunk/refactor_pkg/refactor/tests/data/infinite_recursion.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/tests/data/infinite_recursion.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,2670 @@ +# This file is used to verify that refactor falls back to a slower, iterative +# pattern matching scheme in the event that the faster recursive system fails +# due to infinite recursion. +from ctypes import * +STRING = c_char_p + + +OSUnknownByteOrder = 0 +UIT_PROMPT = 1 +P_PGID = 2 +P_PID = 1 +UIT_ERROR = 5 +UIT_INFO = 4 +UIT_NONE = 0 +P_ALL = 0 +UIT_VERIFY = 2 +OSBigEndian = 2 +UIT_BOOLEAN = 3 +OSLittleEndian = 1 +__darwin_nl_item = c_int +__darwin_wctrans_t = c_int +__darwin_wctype_t = c_ulong +__int8_t = c_byte +__uint8_t = c_ubyte +__int16_t = c_short +__uint16_t = c_ushort +__int32_t = c_int +__uint32_t = c_uint +__int64_t = c_longlong +__uint64_t = c_ulonglong +__darwin_intptr_t = c_long +__darwin_natural_t = c_uint +__darwin_ct_rune_t = c_int +class __mbstate_t(Union): + pass +__mbstate_t._pack_ = 4 +__mbstate_t._fields_ = [ + ('__mbstate8', c_char * 128), + ('_mbstateL', c_longlong), +] +assert sizeof(__mbstate_t) == 128, sizeof(__mbstate_t) +assert alignment(__mbstate_t) == 4, alignment(__mbstate_t) +__darwin_mbstate_t = __mbstate_t +__darwin_ptrdiff_t = c_int +__darwin_size_t = c_ulong +__darwin_va_list = STRING +__darwin_wchar_t = c_int +__darwin_rune_t = __darwin_wchar_t +__darwin_wint_t = c_int +__darwin_clock_t = c_ulong +__darwin_socklen_t = __uint32_t +__darwin_ssize_t = c_long +__darwin_time_t = c_long +sig_atomic_t = c_int +class sigcontext(Structure): + pass +sigcontext._fields_ = [ + ('sc_onstack', c_int), + ('sc_mask', c_int), + ('sc_eax', c_uint), + ('sc_ebx', c_uint), + ('sc_ecx', c_uint), + ('sc_edx', c_uint), + ('sc_edi', c_uint), + ('sc_esi', c_uint), + ('sc_ebp', c_uint), + ('sc_esp', c_uint), + ('sc_ss', c_uint), + ('sc_eflags', c_uint), + ('sc_eip', c_uint), + ('sc_cs', c_uint), + ('sc_ds', c_uint), + ('sc_es', c_uint), + ('sc_fs', c_uint), + ('sc_gs', c_uint), +] +assert sizeof(sigcontext) == 72, sizeof(sigcontext) +assert alignment(sigcontext) == 4, alignment(sigcontext) +u_int8_t = c_ubyte +u_int16_t = c_ushort +u_int32_t = c_uint +u_int64_t = c_ulonglong +int32_t = c_int +register_t = int32_t +user_addr_t = u_int64_t +user_size_t = u_int64_t +int64_t = c_longlong +user_ssize_t = int64_t +user_long_t = int64_t +user_ulong_t = u_int64_t +user_time_t = int64_t +syscall_arg_t = u_int64_t + +# values for unnamed enumeration +class aes_key_st(Structure): + pass +aes_key_st._fields_ = [ + ('rd_key', c_ulong * 60), + ('rounds', c_int), +] +assert sizeof(aes_key_st) == 244, sizeof(aes_key_st) +assert alignment(aes_key_st) == 4, alignment(aes_key_st) +AES_KEY = aes_key_st +class asn1_ctx_st(Structure): + pass +asn1_ctx_st._fields_ = [ + ('p', POINTER(c_ubyte)), + ('eos', c_int), + ('error', c_int), + ('inf', c_int), + ('tag', c_int), + ('xclass', c_int), + ('slen', c_long), + ('max', POINTER(c_ubyte)), + ('q', POINTER(c_ubyte)), + ('pp', POINTER(POINTER(c_ubyte))), + ('line', c_int), +] +assert sizeof(asn1_ctx_st) == 44, sizeof(asn1_ctx_st) +assert alignment(asn1_ctx_st) == 4, alignment(asn1_ctx_st) +ASN1_CTX = asn1_ctx_st +class asn1_object_st(Structure): + pass +asn1_object_st._fields_ = [ + ('sn', STRING), + ('ln', STRING), + ('nid', c_int), + ('length', c_int), + ('data', POINTER(c_ubyte)), + ('flags', c_int), +] +assert sizeof(asn1_object_st) == 24, sizeof(asn1_object_st) +assert alignment(asn1_object_st) == 4, alignment(asn1_object_st) +ASN1_OBJECT = asn1_object_st +class asn1_string_st(Structure): + pass +asn1_string_st._fields_ = [ + ('length', c_int), + ('type', c_int), + ('data', POINTER(c_ubyte)), + ('flags', c_long), +] +assert sizeof(asn1_string_st) == 16, sizeof(asn1_string_st) +assert alignment(asn1_string_st) == 4, alignment(asn1_string_st) +ASN1_STRING = asn1_string_st +class ASN1_ENCODING_st(Structure): + pass +ASN1_ENCODING_st._fields_ = [ + ('enc', POINTER(c_ubyte)), + ('len', c_long), + ('modified', c_int), +] +assert sizeof(ASN1_ENCODING_st) == 12, sizeof(ASN1_ENCODING_st) +assert alignment(ASN1_ENCODING_st) == 4, alignment(ASN1_ENCODING_st) +ASN1_ENCODING = ASN1_ENCODING_st +class asn1_string_table_st(Structure): + pass +asn1_string_table_st._fields_ = [ + ('nid', c_int), + ('minsize', c_long), + ('maxsize', c_long), + ('mask', c_ulong), + ('flags', c_ulong), +] +assert sizeof(asn1_string_table_st) == 20, sizeof(asn1_string_table_st) +assert alignment(asn1_string_table_st) == 4, alignment(asn1_string_table_st) +ASN1_STRING_TABLE = asn1_string_table_st +class ASN1_TEMPLATE_st(Structure): + pass +ASN1_TEMPLATE_st._fields_ = [ +] +ASN1_TEMPLATE = ASN1_TEMPLATE_st +class ASN1_ITEM_st(Structure): + pass +ASN1_ITEM = ASN1_ITEM_st +ASN1_ITEM_st._fields_ = [ +] +class ASN1_TLC_st(Structure): + pass +ASN1_TLC = ASN1_TLC_st +ASN1_TLC_st._fields_ = [ +] +class ASN1_VALUE_st(Structure): + pass +ASN1_VALUE_st._fields_ = [ +] +ASN1_VALUE = ASN1_VALUE_st +ASN1_ITEM_EXP = ASN1_ITEM +class asn1_type_st(Structure): + pass +class N12asn1_type_st4DOLLAR_11E(Union): + pass +ASN1_BOOLEAN = c_int +ASN1_INTEGER = asn1_string_st +ASN1_ENUMERATED = asn1_string_st +ASN1_BIT_STRING = asn1_string_st +ASN1_OCTET_STRING = asn1_string_st +ASN1_PRINTABLESTRING = asn1_string_st +ASN1_T61STRING = asn1_string_st +ASN1_IA5STRING = asn1_string_st +ASN1_GENERALSTRING = asn1_string_st +ASN1_BMPSTRING = asn1_string_st +ASN1_UNIVERSALSTRING = asn1_string_st +ASN1_UTCTIME = asn1_string_st +ASN1_GENERALIZEDTIME = asn1_string_st +ASN1_VISIBLESTRING = asn1_string_st +ASN1_UTF8STRING = asn1_string_st +N12asn1_type_st4DOLLAR_11E._fields_ = [ + ('ptr', STRING), + ('boolean', ASN1_BOOLEAN), + ('asn1_string', POINTER(ASN1_STRING)), + ('object', POINTER(ASN1_OBJECT)), + ('integer', POINTER(ASN1_INTEGER)), + ('enumerated', POINTER(ASN1_ENUMERATED)), + ('bit_string', POINTER(ASN1_BIT_STRING)), + ('octet_string', POINTER(ASN1_OCTET_STRING)), + ('printablestring', POINTER(ASN1_PRINTABLESTRING)), + ('t61string', POINTER(ASN1_T61STRING)), + ('ia5string', POINTER(ASN1_IA5STRING)), + ('generalstring', POINTER(ASN1_GENERALSTRING)), + ('bmpstring', POINTER(ASN1_BMPSTRING)), + ('universalstring', POINTER(ASN1_UNIVERSALSTRING)), + ('utctime', POINTER(ASN1_UTCTIME)), + ('generalizedtime', POINTER(ASN1_GENERALIZEDTIME)), + ('visiblestring', POINTER(ASN1_VISIBLESTRING)), + ('utf8string', POINTER(ASN1_UTF8STRING)), + ('set', POINTER(ASN1_STRING)), + ('sequence', POINTER(ASN1_STRING)), +] +assert sizeof(N12asn1_type_st4DOLLAR_11E) == 4, sizeof(N12asn1_type_st4DOLLAR_11E) +assert alignment(N12asn1_type_st4DOLLAR_11E) == 4, alignment(N12asn1_type_st4DOLLAR_11E) +asn1_type_st._fields_ = [ + ('type', c_int), + ('value', N12asn1_type_st4DOLLAR_11E), +] +assert sizeof(asn1_type_st) == 8, sizeof(asn1_type_st) +assert alignment(asn1_type_st) == 4, alignment(asn1_type_st) +ASN1_TYPE = asn1_type_st +class asn1_method_st(Structure): + pass +asn1_method_st._fields_ = [ + ('i2d', CFUNCTYPE(c_int)), + ('d2i', CFUNCTYPE(STRING)), + ('create', CFUNCTYPE(STRING)), + ('destroy', CFUNCTYPE(None)), +] +assert sizeof(asn1_method_st) == 16, sizeof(asn1_method_st) +assert alignment(asn1_method_st) == 4, alignment(asn1_method_st) +ASN1_METHOD = asn1_method_st +class asn1_header_st(Structure): + pass +asn1_header_st._fields_ = [ + ('header', POINTER(ASN1_OCTET_STRING)), + ('data', STRING), + ('meth', POINTER(ASN1_METHOD)), +] +assert sizeof(asn1_header_st) == 12, sizeof(asn1_header_st) +assert alignment(asn1_header_st) == 4, alignment(asn1_header_st) +ASN1_HEADER = asn1_header_st +class BIT_STRING_BITNAME_st(Structure): + pass +BIT_STRING_BITNAME_st._fields_ = [ + ('bitnum', c_int), + ('lname', STRING), + ('sname', STRING), +] +assert sizeof(BIT_STRING_BITNAME_st) == 12, sizeof(BIT_STRING_BITNAME_st) +assert alignment(BIT_STRING_BITNAME_st) == 4, alignment(BIT_STRING_BITNAME_st) +BIT_STRING_BITNAME = BIT_STRING_BITNAME_st +class bio_st(Structure): + pass +BIO = bio_st +bio_info_cb = CFUNCTYPE(None, POINTER(bio_st), c_int, STRING, c_int, c_long, c_long) +class bio_method_st(Structure): + pass +bio_method_st._fields_ = [ + ('type', c_int), + ('name', STRING), + ('bwrite', CFUNCTYPE(c_int, POINTER(BIO), STRING, c_int)), + ('bread', CFUNCTYPE(c_int, POINTER(BIO), STRING, c_int)), + ('bputs', CFUNCTYPE(c_int, POINTER(BIO), STRING)), + ('bgets', CFUNCTYPE(c_int, POINTER(BIO), STRING, c_int)), + ('ctrl', CFUNCTYPE(c_long, POINTER(BIO), c_int, c_long, c_void_p)), + ('create', CFUNCTYPE(c_int, POINTER(BIO))), + ('destroy', CFUNCTYPE(c_int, POINTER(BIO))), + ('callback_ctrl', CFUNCTYPE(c_long, POINTER(BIO), c_int, POINTER(bio_info_cb))), +] +assert sizeof(bio_method_st) == 40, sizeof(bio_method_st) +assert alignment(bio_method_st) == 4, alignment(bio_method_st) +BIO_METHOD = bio_method_st +class crypto_ex_data_st(Structure): + pass +class stack_st(Structure): + pass +STACK = stack_st +crypto_ex_data_st._fields_ = [ + ('sk', POINTER(STACK)), + ('dummy', c_int), +] +assert sizeof(crypto_ex_data_st) == 8, sizeof(crypto_ex_data_st) +assert alignment(crypto_ex_data_st) == 4, alignment(crypto_ex_data_st) +CRYPTO_EX_DATA = crypto_ex_data_st +bio_st._fields_ = [ + ('method', POINTER(BIO_METHOD)), + ('callback', CFUNCTYPE(c_long, POINTER(bio_st), c_int, STRING, c_int, c_long, c_long)), + ('cb_arg', STRING), + ('init', c_int), + ('shutdown', c_int), + ('flags', c_int), + ('retry_reason', c_int), + ('num', c_int), + ('ptr', c_void_p), + ('next_bio', POINTER(bio_st)), + ('prev_bio', POINTER(bio_st)), + ('references', c_int), + ('num_read', c_ulong), + ('num_write', c_ulong), + ('ex_data', CRYPTO_EX_DATA), +] +assert sizeof(bio_st) == 64, sizeof(bio_st) +assert alignment(bio_st) == 4, alignment(bio_st) +class bio_f_buffer_ctx_struct(Structure): + pass +bio_f_buffer_ctx_struct._fields_ = [ + ('ibuf_size', c_int), + ('obuf_size', c_int), + ('ibuf', STRING), + ('ibuf_len', c_int), + ('ibuf_off', c_int), + ('obuf', STRING), + ('obuf_len', c_int), + ('obuf_off', c_int), +] +assert sizeof(bio_f_buffer_ctx_struct) == 32, sizeof(bio_f_buffer_ctx_struct) +assert alignment(bio_f_buffer_ctx_struct) == 4, alignment(bio_f_buffer_ctx_struct) +BIO_F_BUFFER_CTX = bio_f_buffer_ctx_struct +class hostent(Structure): + pass +hostent._fields_ = [ +] +class bf_key_st(Structure): + pass +bf_key_st._fields_ = [ + ('P', c_uint * 18), + ('S', c_uint * 1024), +] +assert sizeof(bf_key_st) == 4168, sizeof(bf_key_st) +assert alignment(bf_key_st) == 4, alignment(bf_key_st) +BF_KEY = bf_key_st +class bignum_st(Structure): + pass +bignum_st._fields_ = [ + ('d', POINTER(c_ulong)), + ('top', c_int), + ('dmax', c_int), + ('neg', c_int), + ('flags', c_int), +] +assert sizeof(bignum_st) == 20, sizeof(bignum_st) +assert alignment(bignum_st) == 4, alignment(bignum_st) +BIGNUM = bignum_st +class bignum_ctx(Structure): + pass +bignum_ctx._fields_ = [ +] +BN_CTX = bignum_ctx +class bn_blinding_st(Structure): + pass +bn_blinding_st._fields_ = [ + ('init', c_int), + ('A', POINTER(BIGNUM)), + ('Ai', POINTER(BIGNUM)), + ('mod', POINTER(BIGNUM)), + ('thread_id', c_ulong), +] +assert sizeof(bn_blinding_st) == 20, sizeof(bn_blinding_st) +assert alignment(bn_blinding_st) == 4, alignment(bn_blinding_st) +BN_BLINDING = bn_blinding_st +class bn_mont_ctx_st(Structure): + pass +bn_mont_ctx_st._fields_ = [ + ('ri', c_int), + ('RR', BIGNUM), + ('N', BIGNUM), + ('Ni', BIGNUM), + ('n0', c_ulong), + ('flags', c_int), +] +assert sizeof(bn_mont_ctx_st) == 72, sizeof(bn_mont_ctx_st) +assert alignment(bn_mont_ctx_st) == 4, alignment(bn_mont_ctx_st) +BN_MONT_CTX = bn_mont_ctx_st +class bn_recp_ctx_st(Structure): + pass +bn_recp_ctx_st._fields_ = [ + ('N', BIGNUM), + ('Nr', BIGNUM), + ('num_bits', c_int), + ('shift', c_int), + ('flags', c_int), +] +assert sizeof(bn_recp_ctx_st) == 52, sizeof(bn_recp_ctx_st) +assert alignment(bn_recp_ctx_st) == 4, alignment(bn_recp_ctx_st) +BN_RECP_CTX = bn_recp_ctx_st +class buf_mem_st(Structure): + pass +buf_mem_st._fields_ = [ + ('length', c_int), + ('data', STRING), + ('max', c_int), +] +assert sizeof(buf_mem_st) == 12, sizeof(buf_mem_st) +assert alignment(buf_mem_st) == 4, alignment(buf_mem_st) +BUF_MEM = buf_mem_st +class cast_key_st(Structure): + pass +cast_key_st._fields_ = [ + ('data', c_ulong * 32), + ('short_key', c_int), +] +assert sizeof(cast_key_st) == 132, sizeof(cast_key_st) +assert alignment(cast_key_st) == 4, alignment(cast_key_st) +CAST_KEY = cast_key_st +class comp_method_st(Structure): + pass +comp_method_st._fields_ = [ + ('type', c_int), + ('name', STRING), + ('init', CFUNCTYPE(c_int)), + ('finish', CFUNCTYPE(None)), + ('compress', CFUNCTYPE(c_int)), + ('expand', CFUNCTYPE(c_int)), + ('ctrl', CFUNCTYPE(c_long)), + ('callback_ctrl', CFUNCTYPE(c_long)), +] +assert sizeof(comp_method_st) == 32, sizeof(comp_method_st) +assert alignment(comp_method_st) == 4, alignment(comp_method_st) +COMP_METHOD = comp_method_st +class comp_ctx_st(Structure): + pass +comp_ctx_st._fields_ = [ + ('meth', POINTER(COMP_METHOD)), + ('compress_in', c_ulong), + ('compress_out', c_ulong), + ('expand_in', c_ulong), + ('expand_out', c_ulong), + ('ex_data', CRYPTO_EX_DATA), +] +assert sizeof(comp_ctx_st) == 28, sizeof(comp_ctx_st) +assert alignment(comp_ctx_st) == 4, alignment(comp_ctx_st) +COMP_CTX = comp_ctx_st +class CRYPTO_dynlock_value(Structure): + pass +CRYPTO_dynlock_value._fields_ = [ +] +class CRYPTO_dynlock(Structure): + pass +CRYPTO_dynlock._fields_ = [ + ('references', c_int), + ('data', POINTER(CRYPTO_dynlock_value)), +] +assert sizeof(CRYPTO_dynlock) == 8, sizeof(CRYPTO_dynlock) +assert alignment(CRYPTO_dynlock) == 4, alignment(CRYPTO_dynlock) +BIO_dummy = bio_st +CRYPTO_EX_new = CFUNCTYPE(c_int, c_void_p, c_void_p, POINTER(CRYPTO_EX_DATA), c_int, c_long, c_void_p) +CRYPTO_EX_free = CFUNCTYPE(None, c_void_p, c_void_p, POINTER(CRYPTO_EX_DATA), c_int, c_long, c_void_p) +CRYPTO_EX_dup = CFUNCTYPE(c_int, POINTER(CRYPTO_EX_DATA), POINTER(CRYPTO_EX_DATA), c_void_p, c_int, c_long, c_void_p) +class crypto_ex_data_func_st(Structure): + pass +crypto_ex_data_func_st._fields_ = [ + ('argl', c_long), + ('argp', c_void_p), + ('new_func', POINTER(CRYPTO_EX_new)), + ('free_func', POINTER(CRYPTO_EX_free)), + ('dup_func', POINTER(CRYPTO_EX_dup)), +] +assert sizeof(crypto_ex_data_func_st) == 20, sizeof(crypto_ex_data_func_st) +assert alignment(crypto_ex_data_func_st) == 4, alignment(crypto_ex_data_func_st) +CRYPTO_EX_DATA_FUNCS = crypto_ex_data_func_st +class st_CRYPTO_EX_DATA_IMPL(Structure): + pass +CRYPTO_EX_DATA_IMPL = st_CRYPTO_EX_DATA_IMPL +st_CRYPTO_EX_DATA_IMPL._fields_ = [ +] +CRYPTO_MEM_LEAK_CB = CFUNCTYPE(c_void_p, c_ulong, STRING, c_int, c_int, c_void_p) +DES_cblock = c_ubyte * 8 +const_DES_cblock = c_ubyte * 8 +class DES_ks(Structure): + pass +class N6DES_ks3DOLLAR_9E(Union): + pass +N6DES_ks3DOLLAR_9E._fields_ = [ + ('cblock', DES_cblock), + ('deslong', c_ulong * 2), +] +assert sizeof(N6DES_ks3DOLLAR_9E) == 8, sizeof(N6DES_ks3DOLLAR_9E) +assert alignment(N6DES_ks3DOLLAR_9E) == 4, alignment(N6DES_ks3DOLLAR_9E) +DES_ks._fields_ = [ + ('ks', N6DES_ks3DOLLAR_9E * 16), +] +assert sizeof(DES_ks) == 128, sizeof(DES_ks) +assert alignment(DES_ks) == 4, alignment(DES_ks) +DES_key_schedule = DES_ks +_ossl_old_des_cblock = c_ubyte * 8 +class _ossl_old_des_ks_struct(Structure): + pass +class N23_ossl_old_des_ks_struct4DOLLAR_10E(Union): + pass +N23_ossl_old_des_ks_struct4DOLLAR_10E._fields_ = [ + ('_', _ossl_old_des_cblock), + ('pad', c_ulong * 2), +] +assert sizeof(N23_ossl_old_des_ks_struct4DOLLAR_10E) == 8, sizeof(N23_ossl_old_des_ks_struct4DOLLAR_10E) +assert alignment(N23_ossl_old_des_ks_struct4DOLLAR_10E) == 4, alignment(N23_ossl_old_des_ks_struct4DOLLAR_10E) +_ossl_old_des_ks_struct._fields_ = [ + ('ks', N23_ossl_old_des_ks_struct4DOLLAR_10E), +] +assert sizeof(_ossl_old_des_ks_struct) == 8, sizeof(_ossl_old_des_ks_struct) +assert alignment(_ossl_old_des_ks_struct) == 4, alignment(_ossl_old_des_ks_struct) +_ossl_old_des_key_schedule = _ossl_old_des_ks_struct * 16 +class dh_st(Structure): + pass +DH = dh_st +class dh_method(Structure): + pass +dh_method._fields_ = [ + ('name', STRING), + ('generate_key', CFUNCTYPE(c_int, POINTER(DH))), + ('compute_key', CFUNCTYPE(c_int, POINTER(c_ubyte), POINTER(BIGNUM), POINTER(DH))), + ('bn_mod_exp', CFUNCTYPE(c_int, POINTER(DH), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BN_CTX), POINTER(BN_MONT_CTX))), + ('init', CFUNCTYPE(c_int, POINTER(DH))), + ('finish', CFUNCTYPE(c_int, POINTER(DH))), + ('flags', c_int), + ('app_data', STRING), +] +assert sizeof(dh_method) == 32, sizeof(dh_method) +assert alignment(dh_method) == 4, alignment(dh_method) +DH_METHOD = dh_method +class engine_st(Structure): + pass +ENGINE = engine_st +dh_st._fields_ = [ + ('pad', c_int), + ('version', c_int), + ('p', POINTER(BIGNUM)), + ('g', POINTER(BIGNUM)), + ('length', c_long), + ('pub_key', POINTER(BIGNUM)), + ('priv_key', POINTER(BIGNUM)), + ('flags', c_int), + ('method_mont_p', STRING), + ('q', POINTER(BIGNUM)), + ('j', POINTER(BIGNUM)), + ('seed', POINTER(c_ubyte)), + ('seedlen', c_int), + ('counter', POINTER(BIGNUM)), + ('references', c_int), + ('ex_data', CRYPTO_EX_DATA), + ('meth', POINTER(DH_METHOD)), + ('engine', POINTER(ENGINE)), +] +assert sizeof(dh_st) == 76, sizeof(dh_st) +assert alignment(dh_st) == 4, alignment(dh_st) +class dsa_st(Structure): + pass +DSA = dsa_st +class DSA_SIG_st(Structure): + pass +DSA_SIG_st._fields_ = [ + ('r', POINTER(BIGNUM)), + ('s', POINTER(BIGNUM)), +] +assert sizeof(DSA_SIG_st) == 8, sizeof(DSA_SIG_st) +assert alignment(DSA_SIG_st) == 4, alignment(DSA_SIG_st) +DSA_SIG = DSA_SIG_st +class dsa_method(Structure): + pass +dsa_method._fields_ = [ + ('name', STRING), + ('dsa_do_sign', CFUNCTYPE(POINTER(DSA_SIG), POINTER(c_ubyte), c_int, POINTER(DSA))), + ('dsa_sign_setup', CFUNCTYPE(c_int, POINTER(DSA), POINTER(BN_CTX), POINTER(POINTER(BIGNUM)), POINTER(POINTER(BIGNUM)))), + ('dsa_do_verify', CFUNCTYPE(c_int, POINTER(c_ubyte), c_int, POINTER(DSA_SIG), POINTER(DSA))), + ('dsa_mod_exp', CFUNCTYPE(c_int, POINTER(DSA), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BN_CTX), POINTER(BN_MONT_CTX))), + ('bn_mod_exp', CFUNCTYPE(c_int, POINTER(DSA), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BN_CTX), POINTER(BN_MONT_CTX))), + ('init', CFUNCTYPE(c_int, POINTER(DSA))), + ('finish', CFUNCTYPE(c_int, POINTER(DSA))), + ('flags', c_int), + ('app_data', STRING), +] +assert sizeof(dsa_method) == 40, sizeof(dsa_method) +assert alignment(dsa_method) == 4, alignment(dsa_method) +DSA_METHOD = dsa_method +dsa_st._fields_ = [ + ('pad', c_int), + ('version', c_long), + ('write_params', c_int), + ('p', POINTER(BIGNUM)), + ('q', POINTER(BIGNUM)), + ('g', POINTER(BIGNUM)), + ('pub_key', POINTER(BIGNUM)), + ('priv_key', POINTER(BIGNUM)), + ('kinv', POINTER(BIGNUM)), + ('r', POINTER(BIGNUM)), + ('flags', c_int), + ('method_mont_p', STRING), + ('references', c_int), + ('ex_data', CRYPTO_EX_DATA), + ('meth', POINTER(DSA_METHOD)), + ('engine', POINTER(ENGINE)), +] +assert sizeof(dsa_st) == 68, sizeof(dsa_st) +assert alignment(dsa_st) == 4, alignment(dsa_st) +class evp_pkey_st(Structure): + pass +class N11evp_pkey_st4DOLLAR_12E(Union): + pass +class rsa_st(Structure): + pass +N11evp_pkey_st4DOLLAR_12E._fields_ = [ + ('ptr', STRING), + ('rsa', POINTER(rsa_st)), + ('dsa', POINTER(dsa_st)), + ('dh', POINTER(dh_st)), +] +assert sizeof(N11evp_pkey_st4DOLLAR_12E) == 4, sizeof(N11evp_pkey_st4DOLLAR_12E) +assert alignment(N11evp_pkey_st4DOLLAR_12E) == 4, alignment(N11evp_pkey_st4DOLLAR_12E) +evp_pkey_st._fields_ = [ + ('type', c_int), + ('save_type', c_int), + ('references', c_int), + ('pkey', N11evp_pkey_st4DOLLAR_12E), + ('save_parameters', c_int), + ('attributes', POINTER(STACK)), +] +assert sizeof(evp_pkey_st) == 24, sizeof(evp_pkey_st) +assert alignment(evp_pkey_st) == 4, alignment(evp_pkey_st) +class env_md_st(Structure): + pass +class env_md_ctx_st(Structure): + pass +EVP_MD_CTX = env_md_ctx_st +env_md_st._fields_ = [ + ('type', c_int), + ('pkey_type', c_int), + ('md_size', c_int), + ('flags', c_ulong), + ('init', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX))), + ('update', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX), c_void_p, c_ulong)), + ('final', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX), POINTER(c_ubyte))), + ('copy', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX), POINTER(EVP_MD_CTX))), + ('cleanup', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX))), + ('sign', CFUNCTYPE(c_int)), + ('verify', CFUNCTYPE(c_int)), + ('required_pkey_type', c_int * 5), + ('block_size', c_int), + ('ctx_size', c_int), +] +assert sizeof(env_md_st) == 72, sizeof(env_md_st) +assert alignment(env_md_st) == 4, alignment(env_md_st) +EVP_MD = env_md_st +env_md_ctx_st._fields_ = [ + ('digest', POINTER(EVP_MD)), + ('engine', POINTER(ENGINE)), + ('flags', c_ulong), + ('md_data', c_void_p), +] +assert sizeof(env_md_ctx_st) == 16, sizeof(env_md_ctx_st) +assert alignment(env_md_ctx_st) == 4, alignment(env_md_ctx_st) +class evp_cipher_st(Structure): + pass +class evp_cipher_ctx_st(Structure): + pass +EVP_CIPHER_CTX = evp_cipher_ctx_st +evp_cipher_st._fields_ = [ + ('nid', c_int), + ('block_size', c_int), + ('key_len', c_int), + ('iv_len', c_int), + ('flags', c_ulong), + ('init', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), POINTER(c_ubyte), POINTER(c_ubyte), c_int)), + ('do_cipher', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), POINTER(c_ubyte), POINTER(c_ubyte), c_uint)), + ('cleanup', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX))), + ('ctx_size', c_int), + ('set_asn1_parameters', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), POINTER(ASN1_TYPE))), + ('get_asn1_parameters', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), POINTER(ASN1_TYPE))), + ('ctrl', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), c_int, c_int, c_void_p)), + ('app_data', c_void_p), +] +assert sizeof(evp_cipher_st) == 52, sizeof(evp_cipher_st) +assert alignment(evp_cipher_st) == 4, alignment(evp_cipher_st) +class evp_cipher_info_st(Structure): + pass +EVP_CIPHER = evp_cipher_st +evp_cipher_info_st._fields_ = [ + ('cipher', POINTER(EVP_CIPHER)), + ('iv', c_ubyte * 16), +] +assert sizeof(evp_cipher_info_st) == 20, sizeof(evp_cipher_info_st) +assert alignment(evp_cipher_info_st) == 4, alignment(evp_cipher_info_st) +EVP_CIPHER_INFO = evp_cipher_info_st +evp_cipher_ctx_st._fields_ = [ + ('cipher', POINTER(EVP_CIPHER)), + ('engine', POINTER(ENGINE)), + ('encrypt', c_int), + ('buf_len', c_int), + ('oiv', c_ubyte * 16), + ('iv', c_ubyte * 16), + ('buf', c_ubyte * 32), + ('num', c_int), + ('app_data', c_void_p), + ('key_len', c_int), + ('flags', c_ulong), + ('cipher_data', c_void_p), + ('final_used', c_int), + ('block_mask', c_int), + ('final', c_ubyte * 32), +] +assert sizeof(evp_cipher_ctx_st) == 140, sizeof(evp_cipher_ctx_st) +assert alignment(evp_cipher_ctx_st) == 4, alignment(evp_cipher_ctx_st) +class evp_Encode_Ctx_st(Structure): + pass +evp_Encode_Ctx_st._fields_ = [ + ('num', c_int), + ('length', c_int), + ('enc_data', c_ubyte * 80), + ('line_num', c_int), + ('expect_nl', c_int), +] +assert sizeof(evp_Encode_Ctx_st) == 96, sizeof(evp_Encode_Ctx_st) +assert alignment(evp_Encode_Ctx_st) == 4, alignment(evp_Encode_Ctx_st) +EVP_ENCODE_CTX = evp_Encode_Ctx_st +EVP_PBE_KEYGEN = CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), STRING, c_int, POINTER(ASN1_TYPE), POINTER(EVP_CIPHER), POINTER(EVP_MD), c_int) +class lhash_node_st(Structure): + pass +lhash_node_st._fields_ = [ + ('data', c_void_p), + ('next', POINTER(lhash_node_st)), + ('hash', c_ulong), +] +assert sizeof(lhash_node_st) == 12, sizeof(lhash_node_st) +assert alignment(lhash_node_st) == 4, alignment(lhash_node_st) +LHASH_NODE = lhash_node_st +LHASH_COMP_FN_TYPE = CFUNCTYPE(c_int, c_void_p, c_void_p) +LHASH_HASH_FN_TYPE = CFUNCTYPE(c_ulong, c_void_p) +LHASH_DOALL_FN_TYPE = CFUNCTYPE(None, c_void_p) +LHASH_DOALL_ARG_FN_TYPE = CFUNCTYPE(None, c_void_p, c_void_p) +class lhash_st(Structure): + pass +lhash_st._fields_ = [ + ('b', POINTER(POINTER(LHASH_NODE))), + ('comp', LHASH_COMP_FN_TYPE), + ('hash', LHASH_HASH_FN_TYPE), + ('num_nodes', c_uint), + ('num_alloc_nodes', c_uint), + ('p', c_uint), + ('pmax', c_uint), + ('up_load', c_ulong), + ('down_load', c_ulong), + ('num_items', c_ulong), + ('num_expands', c_ulong), + ('num_expand_reallocs', c_ulong), + ('num_contracts', c_ulong), + ('num_contract_reallocs', c_ulong), + ('num_hash_calls', c_ulong), + ('num_comp_calls', c_ulong), + ('num_insert', c_ulong), + ('num_replace', c_ulong), + ('num_delete', c_ulong), + ('num_no_delete', c_ulong), + ('num_retrieve', c_ulong), + ('num_retrieve_miss', c_ulong), + ('num_hash_comps', c_ulong), + ('error', c_int), +] +assert sizeof(lhash_st) == 96, sizeof(lhash_st) +assert alignment(lhash_st) == 4, alignment(lhash_st) +LHASH = lhash_st +class MD2state_st(Structure): + pass +MD2state_st._fields_ = [ + ('num', c_int), + ('data', c_ubyte * 16), + ('cksm', c_uint * 16), + ('state', c_uint * 16), +] +assert sizeof(MD2state_st) == 148, sizeof(MD2state_st) +assert alignment(MD2state_st) == 4, alignment(MD2state_st) +MD2_CTX = MD2state_st +class MD4state_st(Structure): + pass +MD4state_st._fields_ = [ + ('A', c_uint), + ('B', c_uint), + ('C', c_uint), + ('D', c_uint), + ('Nl', c_uint), + ('Nh', c_uint), + ('data', c_uint * 16), + ('num', c_int), +] +assert sizeof(MD4state_st) == 92, sizeof(MD4state_st) +assert alignment(MD4state_st) == 4, alignment(MD4state_st) +MD4_CTX = MD4state_st +class MD5state_st(Structure): + pass +MD5state_st._fields_ = [ + ('A', c_uint), + ('B', c_uint), + ('C', c_uint), + ('D', c_uint), + ('Nl', c_uint), + ('Nh', c_uint), + ('data', c_uint * 16), + ('num', c_int), +] +assert sizeof(MD5state_st) == 92, sizeof(MD5state_st) +assert alignment(MD5state_st) == 4, alignment(MD5state_st) +MD5_CTX = MD5state_st +class mdc2_ctx_st(Structure): + pass +mdc2_ctx_st._fields_ = [ + ('num', c_int), + ('data', c_ubyte * 8), + ('h', DES_cblock), + ('hh', DES_cblock), + ('pad_type', c_int), +] +assert sizeof(mdc2_ctx_st) == 32, sizeof(mdc2_ctx_st) +assert alignment(mdc2_ctx_st) == 4, alignment(mdc2_ctx_st) +MDC2_CTX = mdc2_ctx_st +class obj_name_st(Structure): + pass +obj_name_st._fields_ = [ + ('type', c_int), + ('alias', c_int), + ('name', STRING), + ('data', STRING), +] +assert sizeof(obj_name_st) == 16, sizeof(obj_name_st) +assert alignment(obj_name_st) == 4, alignment(obj_name_st) +OBJ_NAME = obj_name_st +ASN1_TIME = asn1_string_st +ASN1_NULL = c_int +EVP_PKEY = evp_pkey_st +class x509_st(Structure): + pass +X509 = x509_st +class X509_algor_st(Structure): + pass +X509_ALGOR = X509_algor_st +class X509_crl_st(Structure): + pass +X509_CRL = X509_crl_st +class X509_name_st(Structure): + pass +X509_NAME = X509_name_st +class x509_store_st(Structure): + pass +X509_STORE = x509_store_st +class x509_store_ctx_st(Structure): + pass +X509_STORE_CTX = x509_store_ctx_st +engine_st._fields_ = [ +] +class PEM_Encode_Seal_st(Structure): + pass +PEM_Encode_Seal_st._fields_ = [ + ('encode', EVP_ENCODE_CTX), + ('md', EVP_MD_CTX), + ('cipher', EVP_CIPHER_CTX), +] +assert sizeof(PEM_Encode_Seal_st) == 252, sizeof(PEM_Encode_Seal_st) +assert alignment(PEM_Encode_Seal_st) == 4, alignment(PEM_Encode_Seal_st) +PEM_ENCODE_SEAL_CTX = PEM_Encode_Seal_st +class pem_recip_st(Structure): + pass +pem_recip_st._fields_ = [ + ('name', STRING), + ('dn', POINTER(X509_NAME)), + ('cipher', c_int), + ('key_enc', c_int), +] +assert sizeof(pem_recip_st) == 16, sizeof(pem_recip_st) +assert alignment(pem_recip_st) == 4, alignment(pem_recip_st) +PEM_USER = pem_recip_st +class pem_ctx_st(Structure): + pass +class N10pem_ctx_st4DOLLAR_16E(Structure): + pass +N10pem_ctx_st4DOLLAR_16E._fields_ = [ + ('version', c_int), + ('mode', c_int), +] +assert sizeof(N10pem_ctx_st4DOLLAR_16E) == 8, sizeof(N10pem_ctx_st4DOLLAR_16E) +assert alignment(N10pem_ctx_st4DOLLAR_16E) == 4, alignment(N10pem_ctx_st4DOLLAR_16E) +class N10pem_ctx_st4DOLLAR_17E(Structure): + pass +N10pem_ctx_st4DOLLAR_17E._fields_ = [ + ('cipher', c_int), +] +assert sizeof(N10pem_ctx_st4DOLLAR_17E) == 4, sizeof(N10pem_ctx_st4DOLLAR_17E) +assert alignment(N10pem_ctx_st4DOLLAR_17E) == 4, alignment(N10pem_ctx_st4DOLLAR_17E) +pem_ctx_st._fields_ = [ + ('type', c_int), + ('proc_type', N10pem_ctx_st4DOLLAR_16E), + ('domain', STRING), + ('DEK_info', N10pem_ctx_st4DOLLAR_17E), + ('originator', POINTER(PEM_USER)), + ('num_recipient', c_int), + ('recipient', POINTER(POINTER(PEM_USER))), + ('x509_chain', POINTER(STACK)), + ('md', POINTER(EVP_MD)), + ('md_enc', c_int), + ('md_len', c_int), + ('md_data', STRING), + ('dec', POINTER(EVP_CIPHER)), + ('key_len', c_int), + ('key', POINTER(c_ubyte)), + ('data_enc', c_int), + ('data_len', c_int), + ('data', POINTER(c_ubyte)), +] +assert sizeof(pem_ctx_st) == 76, sizeof(pem_ctx_st) +assert alignment(pem_ctx_st) == 4, alignment(pem_ctx_st) +PEM_CTX = pem_ctx_st +pem_password_cb = CFUNCTYPE(c_int, STRING, c_int, c_int, c_void_p) +class pkcs7_issuer_and_serial_st(Structure): + pass +pkcs7_issuer_and_serial_st._fields_ = [ + ('issuer', POINTER(X509_NAME)), + ('serial', POINTER(ASN1_INTEGER)), +] +assert sizeof(pkcs7_issuer_and_serial_st) == 8, sizeof(pkcs7_issuer_and_serial_st) +assert alignment(pkcs7_issuer_and_serial_st) == 4, alignment(pkcs7_issuer_and_serial_st) +PKCS7_ISSUER_AND_SERIAL = pkcs7_issuer_and_serial_st +class pkcs7_signer_info_st(Structure): + pass +pkcs7_signer_info_st._fields_ = [ + ('version', POINTER(ASN1_INTEGER)), + ('issuer_and_serial', POINTER(PKCS7_ISSUER_AND_SERIAL)), + ('digest_alg', POINTER(X509_ALGOR)), + ('auth_attr', POINTER(STACK)), + ('digest_enc_alg', POINTER(X509_ALGOR)), + ('enc_digest', POINTER(ASN1_OCTET_STRING)), + ('unauth_attr', POINTER(STACK)), + ('pkey', POINTER(EVP_PKEY)), +] +assert sizeof(pkcs7_signer_info_st) == 32, sizeof(pkcs7_signer_info_st) +assert alignment(pkcs7_signer_info_st) == 4, alignment(pkcs7_signer_info_st) +PKCS7_SIGNER_INFO = pkcs7_signer_info_st +class pkcs7_recip_info_st(Structure): + pass +pkcs7_recip_info_st._fields_ = [ + ('version', POINTER(ASN1_INTEGER)), + ('issuer_and_serial', POINTER(PKCS7_ISSUER_AND_SERIAL)), + ('key_enc_algor', POINTER(X509_ALGOR)), + ('enc_key', POINTER(ASN1_OCTET_STRING)), + ('cert', POINTER(X509)), +] +assert sizeof(pkcs7_recip_info_st) == 20, sizeof(pkcs7_recip_info_st) +assert alignment(pkcs7_recip_info_st) == 4, alignment(pkcs7_recip_info_st) +PKCS7_RECIP_INFO = pkcs7_recip_info_st +class pkcs7_signed_st(Structure): + pass +class pkcs7_st(Structure): + pass +pkcs7_signed_st._fields_ = [ + ('version', POINTER(ASN1_INTEGER)), + ('md_algs', POINTER(STACK)), + ('cert', POINTER(STACK)), + ('crl', POINTER(STACK)), + ('signer_info', POINTER(STACK)), + ('contents', POINTER(pkcs7_st)), +] +assert sizeof(pkcs7_signed_st) == 24, sizeof(pkcs7_signed_st) +assert alignment(pkcs7_signed_st) == 4, alignment(pkcs7_signed_st) +PKCS7_SIGNED = pkcs7_signed_st +class pkcs7_enc_content_st(Structure): + pass +pkcs7_enc_content_st._fields_ = [ + ('content_type', POINTER(ASN1_OBJECT)), + ('algorithm', POINTER(X509_ALGOR)), + ('enc_data', POINTER(ASN1_OCTET_STRING)), + ('cipher', POINTER(EVP_CIPHER)), +] +assert sizeof(pkcs7_enc_content_st) == 16, sizeof(pkcs7_enc_content_st) +assert alignment(pkcs7_enc_content_st) == 4, alignment(pkcs7_enc_content_st) +PKCS7_ENC_CONTENT = pkcs7_enc_content_st +class pkcs7_enveloped_st(Structure): + pass +pkcs7_enveloped_st._fields_ = [ + ('version', POINTER(ASN1_INTEGER)), + ('recipientinfo', POINTER(STACK)), + ('enc_data', POINTER(PKCS7_ENC_CONTENT)), +] +assert sizeof(pkcs7_enveloped_st) == 12, sizeof(pkcs7_enveloped_st) +assert alignment(pkcs7_enveloped_st) == 4, alignment(pkcs7_enveloped_st) +PKCS7_ENVELOPE = pkcs7_enveloped_st +class pkcs7_signedandenveloped_st(Structure): + pass +pkcs7_signedandenveloped_st._fields_ = [ + ('version', POINTER(ASN1_INTEGER)), + ('md_algs', POINTER(STACK)), + ('cert', POINTER(STACK)), + ('crl', POINTER(STACK)), + ('signer_info', POINTER(STACK)), + ('enc_data', POINTER(PKCS7_ENC_CONTENT)), + ('recipientinfo', POINTER(STACK)), +] +assert sizeof(pkcs7_signedandenveloped_st) == 28, sizeof(pkcs7_signedandenveloped_st) +assert alignment(pkcs7_signedandenveloped_st) == 4, alignment(pkcs7_signedandenveloped_st) +PKCS7_SIGN_ENVELOPE = pkcs7_signedandenveloped_st +class pkcs7_digest_st(Structure): + pass +pkcs7_digest_st._fields_ = [ + ('version', POINTER(ASN1_INTEGER)), + ('md', POINTER(X509_ALGOR)), + ('contents', POINTER(pkcs7_st)), + ('digest', POINTER(ASN1_OCTET_STRING)), +] +assert sizeof(pkcs7_digest_st) == 16, sizeof(pkcs7_digest_st) +assert alignment(pkcs7_digest_st) == 4, alignment(pkcs7_digest_st) +PKCS7_DIGEST = pkcs7_digest_st +class pkcs7_encrypted_st(Structure): + pass +pkcs7_encrypted_st._fields_ = [ + ('version', POINTER(ASN1_INTEGER)), + ('enc_data', POINTER(PKCS7_ENC_CONTENT)), +] +assert sizeof(pkcs7_encrypted_st) == 8, sizeof(pkcs7_encrypted_st) +assert alignment(pkcs7_encrypted_st) == 4, alignment(pkcs7_encrypted_st) +PKCS7_ENCRYPT = pkcs7_encrypted_st +class N8pkcs7_st4DOLLAR_15E(Union): + pass +N8pkcs7_st4DOLLAR_15E._fields_ = [ + ('ptr', STRING), + ('data', POINTER(ASN1_OCTET_STRING)), + ('sign', POINTER(PKCS7_SIGNED)), + ('enveloped', POINTER(PKCS7_ENVELOPE)), + ('signed_and_enveloped', POINTER(PKCS7_SIGN_ENVELOPE)), + ('digest', POINTER(PKCS7_DIGEST)), + ('encrypted', POINTER(PKCS7_ENCRYPT)), + ('other', POINTER(ASN1_TYPE)), +] +assert sizeof(N8pkcs7_st4DOLLAR_15E) == 4, sizeof(N8pkcs7_st4DOLLAR_15E) +assert alignment(N8pkcs7_st4DOLLAR_15E) == 4, alignment(N8pkcs7_st4DOLLAR_15E) +pkcs7_st._fields_ = [ + ('asn1', POINTER(c_ubyte)), + ('length', c_long), + ('state', c_int), + ('detached', c_int), + ('type', POINTER(ASN1_OBJECT)), + ('d', N8pkcs7_st4DOLLAR_15E), +] +assert sizeof(pkcs7_st) == 24, sizeof(pkcs7_st) +assert alignment(pkcs7_st) == 4, alignment(pkcs7_st) +PKCS7 = pkcs7_st +class rc2_key_st(Structure): + pass +rc2_key_st._fields_ = [ + ('data', c_uint * 64), +] +assert sizeof(rc2_key_st) == 256, sizeof(rc2_key_st) +assert alignment(rc2_key_st) == 4, alignment(rc2_key_st) +RC2_KEY = rc2_key_st +class rc4_key_st(Structure): + pass +rc4_key_st._fields_ = [ + ('x', c_ubyte), + ('y', c_ubyte), + ('data', c_ubyte * 256), +] +assert sizeof(rc4_key_st) == 258, sizeof(rc4_key_st) +assert alignment(rc4_key_st) == 1, alignment(rc4_key_st) +RC4_KEY = rc4_key_st +class rc5_key_st(Structure): + pass +rc5_key_st._fields_ = [ + ('rounds', c_int), + ('data', c_ulong * 34), +] +assert sizeof(rc5_key_st) == 140, sizeof(rc5_key_st) +assert alignment(rc5_key_st) == 4, alignment(rc5_key_st) +RC5_32_KEY = rc5_key_st +class RIPEMD160state_st(Structure): + pass +RIPEMD160state_st._fields_ = [ + ('A', c_uint), + ('B', c_uint), + ('C', c_uint), + ('D', c_uint), + ('E', c_uint), + ('Nl', c_uint), + ('Nh', c_uint), + ('data', c_uint * 16), + ('num', c_int), +] +assert sizeof(RIPEMD160state_st) == 96, sizeof(RIPEMD160state_st) +assert alignment(RIPEMD160state_st) == 4, alignment(RIPEMD160state_st) +RIPEMD160_CTX = RIPEMD160state_st +RSA = rsa_st +class rsa_meth_st(Structure): + pass +rsa_meth_st._fields_ = [ + ('name', STRING), + ('rsa_pub_enc', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), POINTER(c_ubyte), POINTER(RSA), c_int)), + ('rsa_pub_dec', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), POINTER(c_ubyte), POINTER(RSA), c_int)), + ('rsa_priv_enc', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), POINTER(c_ubyte), POINTER(RSA), c_int)), + ('rsa_priv_dec', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), POINTER(c_ubyte), POINTER(RSA), c_int)), + ('rsa_mod_exp', CFUNCTYPE(c_int, POINTER(BIGNUM), POINTER(BIGNUM), POINTER(RSA))), + ('bn_mod_exp', CFUNCTYPE(c_int, POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BN_CTX), POINTER(BN_MONT_CTX))), + ('init', CFUNCTYPE(c_int, POINTER(RSA))), + ('finish', CFUNCTYPE(c_int, POINTER(RSA))), + ('flags', c_int), + ('app_data', STRING), + ('rsa_sign', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), c_uint, POINTER(c_ubyte), POINTER(c_uint), POINTER(RSA))), + ('rsa_verify', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), c_uint, POINTER(c_ubyte), c_uint, POINTER(RSA))), +] +assert sizeof(rsa_meth_st) == 52, sizeof(rsa_meth_st) +assert alignment(rsa_meth_st) == 4, alignment(rsa_meth_st) +RSA_METHOD = rsa_meth_st +rsa_st._fields_ = [ + ('pad', c_int), + ('version', c_long), + ('meth', POINTER(RSA_METHOD)), + ('engine', POINTER(ENGINE)), + ('n', POINTER(BIGNUM)), + ('e', POINTER(BIGNUM)), + ('d', POINTER(BIGNUM)), + ('p', POINTER(BIGNUM)), + ('q', POINTER(BIGNUM)), + ('dmp1', POINTER(BIGNUM)), + ('dmq1', POINTER(BIGNUM)), + ('iqmp', POINTER(BIGNUM)), + ('ex_data', CRYPTO_EX_DATA), + ('references', c_int), + ('flags', c_int), + ('_method_mod_n', POINTER(BN_MONT_CTX)), + ('_method_mod_p', POINTER(BN_MONT_CTX)), + ('_method_mod_q', POINTER(BN_MONT_CTX)), + ('bignum_data', STRING), + ('blinding', POINTER(BN_BLINDING)), +] +assert sizeof(rsa_st) == 84, sizeof(rsa_st) +assert alignment(rsa_st) == 4, alignment(rsa_st) +openssl_fptr = CFUNCTYPE(None) +class SHAstate_st(Structure): + pass +SHAstate_st._fields_ = [ + ('h0', c_uint), + ('h1', c_uint), + ('h2', c_uint), + ('h3', c_uint), + ('h4', c_uint), + ('Nl', c_uint), + ('Nh', c_uint), + ('data', c_uint * 16), + ('num', c_int), +] +assert sizeof(SHAstate_st) == 96, sizeof(SHAstate_st) +assert alignment(SHAstate_st) == 4, alignment(SHAstate_st) +SHA_CTX = SHAstate_st +class ssl_st(Structure): + pass +ssl_crock_st = POINTER(ssl_st) +class ssl_cipher_st(Structure): + pass +ssl_cipher_st._fields_ = [ + ('valid', c_int), + ('name', STRING), + ('id', c_ulong), + ('algorithms', c_ulong), + ('algo_strength', c_ulong), + ('algorithm2', c_ulong), + ('strength_bits', c_int), + ('alg_bits', c_int), + ('mask', c_ulong), + ('mask_strength', c_ulong), +] +assert sizeof(ssl_cipher_st) == 40, sizeof(ssl_cipher_st) +assert alignment(ssl_cipher_st) == 4, alignment(ssl_cipher_st) +SSL_CIPHER = ssl_cipher_st +SSL = ssl_st +class ssl_ctx_st(Structure): + pass +SSL_CTX = ssl_ctx_st +class ssl_method_st(Structure): + pass +class ssl3_enc_method(Structure): + pass +ssl_method_st._fields_ = [ + ('version', c_int), + ('ssl_new', CFUNCTYPE(c_int, POINTER(SSL))), + ('ssl_clear', CFUNCTYPE(None, POINTER(SSL))), + ('ssl_free', CFUNCTYPE(None, POINTER(SSL))), + ('ssl_accept', CFUNCTYPE(c_int, POINTER(SSL))), + ('ssl_connect', CFUNCTYPE(c_int, POINTER(SSL))), + ('ssl_read', CFUNCTYPE(c_int, POINTER(SSL), c_void_p, c_int)), + ('ssl_peek', CFUNCTYPE(c_int, POINTER(SSL), c_void_p, c_int)), + ('ssl_write', CFUNCTYPE(c_int, POINTER(SSL), c_void_p, c_int)), + ('ssl_shutdown', CFUNCTYPE(c_int, POINTER(SSL))), + ('ssl_renegotiate', CFUNCTYPE(c_int, POINTER(SSL))), + ('ssl_renegotiate_check', CFUNCTYPE(c_int, POINTER(SSL))), + ('ssl_ctrl', CFUNCTYPE(c_long, POINTER(SSL), c_int, c_long, c_void_p)), + ('ssl_ctx_ctrl', CFUNCTYPE(c_long, POINTER(SSL_CTX), c_int, c_long, c_void_p)), + ('get_cipher_by_char', CFUNCTYPE(POINTER(SSL_CIPHER), POINTER(c_ubyte))), + ('put_cipher_by_char', CFUNCTYPE(c_int, POINTER(SSL_CIPHER), POINTER(c_ubyte))), + ('ssl_pending', CFUNCTYPE(c_int, POINTER(SSL))), + ('num_ciphers', CFUNCTYPE(c_int)), + ('get_cipher', CFUNCTYPE(POINTER(SSL_CIPHER), c_uint)), + ('get_ssl_method', CFUNCTYPE(POINTER(ssl_method_st), c_int)), + ('get_timeout', CFUNCTYPE(c_long)), + ('ssl3_enc', POINTER(ssl3_enc_method)), + ('ssl_version', CFUNCTYPE(c_int)), + ('ssl_callback_ctrl', CFUNCTYPE(c_long, POINTER(SSL), c_int, CFUNCTYPE(None))), + ('ssl_ctx_callback_ctrl', CFUNCTYPE(c_long, POINTER(SSL_CTX), c_int, CFUNCTYPE(None))), +] +assert sizeof(ssl_method_st) == 100, sizeof(ssl_method_st) +assert alignment(ssl_method_st) == 4, alignment(ssl_method_st) +ssl3_enc_method._fields_ = [ +] +SSL_METHOD = ssl_method_st +class ssl_session_st(Structure): + pass +class sess_cert_st(Structure): + pass +ssl_session_st._fields_ = [ + ('ssl_version', c_int), + ('key_arg_length', c_uint), + ('key_arg', c_ubyte * 8), + ('master_key_length', c_int), + ('master_key', c_ubyte * 48), + ('session_id_length', c_uint), + ('session_id', c_ubyte * 32), + ('sid_ctx_length', c_uint), + ('sid_ctx', c_ubyte * 32), + ('not_resumable', c_int), + ('sess_cert', POINTER(sess_cert_st)), + ('peer', POINTER(X509)), + ('verify_result', c_long), + ('references', c_int), + ('timeout', c_long), + ('time', c_long), + ('compress_meth', c_int), + ('cipher', POINTER(SSL_CIPHER)), + ('cipher_id', c_ulong), + ('ciphers', POINTER(STACK)), + ('ex_data', CRYPTO_EX_DATA), + ('prev', POINTER(ssl_session_st)), + ('next', POINTER(ssl_session_st)), +] +assert sizeof(ssl_session_st) == 200, sizeof(ssl_session_st) +assert alignment(ssl_session_st) == 4, alignment(ssl_session_st) +sess_cert_st._fields_ = [ +] +SSL_SESSION = ssl_session_st +GEN_SESSION_CB = CFUNCTYPE(c_int, POINTER(SSL), POINTER(c_ubyte), POINTER(c_uint)) +class ssl_comp_st(Structure): + pass +ssl_comp_st._fields_ = [ + ('id', c_int), + ('name', STRING), + ('method', POINTER(COMP_METHOD)), +] +assert sizeof(ssl_comp_st) == 12, sizeof(ssl_comp_st) +assert alignment(ssl_comp_st) == 4, alignment(ssl_comp_st) +SSL_COMP = ssl_comp_st +class N10ssl_ctx_st4DOLLAR_18E(Structure): + pass +N10ssl_ctx_st4DOLLAR_18E._fields_ = [ + ('sess_connect', c_int), + ('sess_connect_renegotiate', c_int), + ('sess_connect_good', c_int), + ('sess_accept', c_int), + ('sess_accept_renegotiate', c_int), + ('sess_accept_good', c_int), + ('sess_miss', c_int), + ('sess_timeout', c_int), + ('sess_cache_full', c_int), + ('sess_hit', c_int), + ('sess_cb_hit', c_int), +] +assert sizeof(N10ssl_ctx_st4DOLLAR_18E) == 44, sizeof(N10ssl_ctx_st4DOLLAR_18E) +assert alignment(N10ssl_ctx_st4DOLLAR_18E) == 4, alignment(N10ssl_ctx_st4DOLLAR_18E) +class cert_st(Structure): + pass +ssl_ctx_st._fields_ = [ + ('method', POINTER(SSL_METHOD)), + ('cipher_list', POINTER(STACK)), + ('cipher_list_by_id', POINTER(STACK)), + ('cert_store', POINTER(x509_store_st)), + ('sessions', POINTER(lhash_st)), + ('session_cache_size', c_ulong), + ('session_cache_head', POINTER(ssl_session_st)), + ('session_cache_tail', POINTER(ssl_session_st)), + ('session_cache_mode', c_int), + ('session_timeout', c_long), + ('new_session_cb', CFUNCTYPE(c_int, POINTER(ssl_st), POINTER(SSL_SESSION))), + ('remove_session_cb', CFUNCTYPE(None, POINTER(ssl_ctx_st), POINTER(SSL_SESSION))), + ('get_session_cb', CFUNCTYPE(POINTER(SSL_SESSION), POINTER(ssl_st), POINTER(c_ubyte), c_int, POINTER(c_int))), + ('stats', N10ssl_ctx_st4DOLLAR_18E), + ('references', c_int), + ('app_verify_callback', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), c_void_p)), + ('app_verify_arg', c_void_p), + ('default_passwd_callback', POINTER(pem_password_cb)), + ('default_passwd_callback_userdata', c_void_p), + ('client_cert_cb', CFUNCTYPE(c_int, POINTER(SSL), POINTER(POINTER(X509)), POINTER(POINTER(EVP_PKEY)))), + ('ex_data', CRYPTO_EX_DATA), + ('rsa_md5', POINTER(EVP_MD)), + ('md5', POINTER(EVP_MD)), + ('sha1', POINTER(EVP_MD)), + ('extra_certs', POINTER(STACK)), + ('comp_methods', POINTER(STACK)), + ('info_callback', CFUNCTYPE(None, POINTER(SSL), c_int, c_int)), + ('client_CA', POINTER(STACK)), + ('options', c_ulong), + ('mode', c_ulong), + ('max_cert_list', c_long), + ('cert', POINTER(cert_st)), + ('read_ahead', c_int), + ('msg_callback', CFUNCTYPE(None, c_int, c_int, c_int, c_void_p, c_ulong, POINTER(SSL), c_void_p)), + ('msg_callback_arg', c_void_p), + ('verify_mode', c_int), + ('verify_depth', c_int), + ('sid_ctx_length', c_uint), + ('sid_ctx', c_ubyte * 32), + ('default_verify_callback', CFUNCTYPE(c_int, c_int, POINTER(X509_STORE_CTX))), + ('generate_session_id', GEN_SESSION_CB), + ('purpose', c_int), + ('trust', c_int), + ('quiet_shutdown', c_int), +] +assert sizeof(ssl_ctx_st) == 248, sizeof(ssl_ctx_st) +assert alignment(ssl_ctx_st) == 4, alignment(ssl_ctx_st) +cert_st._fields_ = [ +] +class ssl2_state_st(Structure): + pass +class ssl3_state_st(Structure): + pass +ssl_st._fields_ = [ + ('version', c_int), + ('type', c_int), + ('method', POINTER(SSL_METHOD)), + ('rbio', POINTER(BIO)), + ('wbio', POINTER(BIO)), + ('bbio', POINTER(BIO)), + ('rwstate', c_int), + ('in_handshake', c_int), + ('handshake_func', CFUNCTYPE(c_int)), + ('server', c_int), + ('new_session', c_int), + ('quiet_shutdown', c_int), + ('shutdown', c_int), + ('state', c_int), + ('rstate', c_int), + ('init_buf', POINTER(BUF_MEM)), + ('init_msg', c_void_p), + ('init_num', c_int), + ('init_off', c_int), + ('packet', POINTER(c_ubyte)), + ('packet_length', c_uint), + ('s2', POINTER(ssl2_state_st)), + ('s3', POINTER(ssl3_state_st)), + ('read_ahead', c_int), + ('msg_callback', CFUNCTYPE(None, c_int, c_int, c_int, c_void_p, c_ulong, POINTER(SSL), c_void_p)), + ('msg_callback_arg', c_void_p), + ('hit', c_int), + ('purpose', c_int), + ('trust', c_int), + ('cipher_list', POINTER(STACK)), + ('cipher_list_by_id', POINTER(STACK)), + ('enc_read_ctx', POINTER(EVP_CIPHER_CTX)), + ('read_hash', POINTER(EVP_MD)), + ('expand', POINTER(COMP_CTX)), + ('enc_write_ctx', POINTER(EVP_CIPHER_CTX)), + ('write_hash', POINTER(EVP_MD)), + ('compress', POINTER(COMP_CTX)), + ('cert', POINTER(cert_st)), + ('sid_ctx_length', c_uint), + ('sid_ctx', c_ubyte * 32), + ('session', POINTER(SSL_SESSION)), + ('generate_session_id', GEN_SESSION_CB), + ('verify_mode', c_int), + ('verify_depth', c_int), + ('verify_callback', CFUNCTYPE(c_int, c_int, POINTER(X509_STORE_CTX))), + ('info_callback', CFUNCTYPE(None, POINTER(SSL), c_int, c_int)), + ('error', c_int), + ('error_code', c_int), + ('ctx', POINTER(SSL_CTX)), + ('debug', c_int), + ('verify_result', c_long), + ('ex_data', CRYPTO_EX_DATA), + ('client_CA', POINTER(STACK)), + ('references', c_int), + ('options', c_ulong), + ('mode', c_ulong), + ('max_cert_list', c_long), + ('first_packet', c_int), + ('client_version', c_int), +] +assert sizeof(ssl_st) == 268, sizeof(ssl_st) +assert alignment(ssl_st) == 4, alignment(ssl_st) +class N13ssl2_state_st4DOLLAR_19E(Structure): + pass +N13ssl2_state_st4DOLLAR_19E._fields_ = [ + ('conn_id_length', c_uint), + ('cert_type', c_uint), + ('cert_length', c_uint), + ('csl', c_uint), + ('clear', c_uint), + ('enc', c_uint), + ('ccl', c_ubyte * 32), + ('cipher_spec_length', c_uint), + ('session_id_length', c_uint), + ('clen', c_uint), + ('rlen', c_uint), +] +assert sizeof(N13ssl2_state_st4DOLLAR_19E) == 72, sizeof(N13ssl2_state_st4DOLLAR_19E) +assert alignment(N13ssl2_state_st4DOLLAR_19E) == 4, alignment(N13ssl2_state_st4DOLLAR_19E) +ssl2_state_st._fields_ = [ + ('three_byte_header', c_int), + ('clear_text', c_int), + ('escape', c_int), + ('ssl2_rollback', c_int), + ('wnum', c_uint), + ('wpend_tot', c_int), + ('wpend_buf', POINTER(c_ubyte)), + ('wpend_off', c_int), + ('wpend_len', c_int), + ('wpend_ret', c_int), + ('rbuf_left', c_int), + ('rbuf_offs', c_int), + ('rbuf', POINTER(c_ubyte)), + ('wbuf', POINTER(c_ubyte)), + ('write_ptr', POINTER(c_ubyte)), + ('padding', c_uint), + ('rlength', c_uint), + ('ract_data_length', c_int), + ('wlength', c_uint), + ('wact_data_length', c_int), + ('ract_data', POINTER(c_ubyte)), + ('wact_data', POINTER(c_ubyte)), + ('mac_data', POINTER(c_ubyte)), + ('read_key', POINTER(c_ubyte)), + ('write_key', POINTER(c_ubyte)), + ('challenge_length', c_uint), + ('challenge', c_ubyte * 32), + ('conn_id_length', c_uint), + ('conn_id', c_ubyte * 16), + ('key_material_length', c_uint), + ('key_material', c_ubyte * 48), + ('read_sequence', c_ulong), + ('write_sequence', c_ulong), + ('tmp', N13ssl2_state_st4DOLLAR_19E), +] +assert sizeof(ssl2_state_st) == 288, sizeof(ssl2_state_st) +assert alignment(ssl2_state_st) == 4, alignment(ssl2_state_st) +SSL2_STATE = ssl2_state_st +class ssl3_record_st(Structure): + pass +ssl3_record_st._fields_ = [ + ('type', c_int), + ('length', c_uint), + ('off', c_uint), + ('data', POINTER(c_ubyte)), + ('input', POINTER(c_ubyte)), + ('comp', POINTER(c_ubyte)), +] +assert sizeof(ssl3_record_st) == 24, sizeof(ssl3_record_st) +assert alignment(ssl3_record_st) == 4, alignment(ssl3_record_st) +SSL3_RECORD = ssl3_record_st +class ssl3_buffer_st(Structure): + pass +size_t = __darwin_size_t +ssl3_buffer_st._fields_ = [ + ('buf', POINTER(c_ubyte)), + ('len', size_t), + ('offset', c_int), + ('left', c_int), +] +assert sizeof(ssl3_buffer_st) == 16, sizeof(ssl3_buffer_st) +assert alignment(ssl3_buffer_st) == 4, alignment(ssl3_buffer_st) +SSL3_BUFFER = ssl3_buffer_st +class N13ssl3_state_st4DOLLAR_20E(Structure): + pass +N13ssl3_state_st4DOLLAR_20E._fields_ = [ + ('cert_verify_md', c_ubyte * 72), + ('finish_md', c_ubyte * 72), + ('finish_md_len', c_int), + ('peer_finish_md', c_ubyte * 72), + ('peer_finish_md_len', c_int), + ('message_size', c_ulong), + ('message_type', c_int), + ('new_cipher', POINTER(SSL_CIPHER)), + ('dh', POINTER(DH)), + ('next_state', c_int), + ('reuse_message', c_int), + ('cert_req', c_int), + ('ctype_num', c_int), + ('ctype', c_char * 7), + ('ca_names', POINTER(STACK)), + ('use_rsa_tmp', c_int), + ('key_block_length', c_int), + ('key_block', POINTER(c_ubyte)), + ('new_sym_enc', POINTER(EVP_CIPHER)), + ('new_hash', POINTER(EVP_MD)), + ('new_compression', POINTER(SSL_COMP)), + ('cert_request', c_int), +] +assert sizeof(N13ssl3_state_st4DOLLAR_20E) == 296, sizeof(N13ssl3_state_st4DOLLAR_20E) +assert alignment(N13ssl3_state_st4DOLLAR_20E) == 4, alignment(N13ssl3_state_st4DOLLAR_20E) +ssl3_state_st._fields_ = [ + ('flags', c_long), + ('delay_buf_pop_ret', c_int), + ('read_sequence', c_ubyte * 8), + ('read_mac_secret', c_ubyte * 36), + ('write_sequence', c_ubyte * 8), + ('write_mac_secret', c_ubyte * 36), + ('server_random', c_ubyte * 32), + ('client_random', c_ubyte * 32), + ('need_empty_fragments', c_int), + ('empty_fragment_done', c_int), + ('rbuf', SSL3_BUFFER), + ('wbuf', SSL3_BUFFER), + ('rrec', SSL3_RECORD), + ('wrec', SSL3_RECORD), + ('alert_fragment', c_ubyte * 2), + ('alert_fragment_len', c_uint), + ('handshake_fragment', c_ubyte * 4), + ('handshake_fragment_len', c_uint), + ('wnum', c_uint), + ('wpend_tot', c_int), + ('wpend_type', c_int), + ('wpend_ret', c_int), + ('wpend_buf', POINTER(c_ubyte)), + ('finish_dgst1', EVP_MD_CTX), + ('finish_dgst2', EVP_MD_CTX), + ('change_cipher_spec', c_int), + ('warn_alert', c_int), + ('fatal_alert', c_int), + ('alert_dispatch', c_int), + ('send_alert', c_ubyte * 2), + ('renegotiate', c_int), + ('total_renegotiations', c_int), + ('num_renegotiations', c_int), + ('in_read_app_data', c_int), + ('tmp', N13ssl3_state_st4DOLLAR_20E), +] +assert sizeof(ssl3_state_st) == 648, sizeof(ssl3_state_st) +assert alignment(ssl3_state_st) == 4, alignment(ssl3_state_st) +SSL3_STATE = ssl3_state_st +stack_st._fields_ = [ + ('num', c_int), + ('data', POINTER(STRING)), + ('sorted', c_int), + ('num_alloc', c_int), + ('comp', CFUNCTYPE(c_int, POINTER(STRING), POINTER(STRING))), +] +assert sizeof(stack_st) == 20, sizeof(stack_st) +assert alignment(stack_st) == 4, alignment(stack_st) +class ui_st(Structure): + pass +ui_st._fields_ = [ +] +UI = ui_st +class ui_method_st(Structure): + pass +ui_method_st._fields_ = [ +] +UI_METHOD = ui_method_st +class ui_string_st(Structure): + pass +ui_string_st._fields_ = [ +] +UI_STRING = ui_string_st + +# values for enumeration 'UI_string_types' +UI_string_types = c_int # enum +class X509_objects_st(Structure): + pass +X509_objects_st._fields_ = [ + ('nid', c_int), + ('a2i', CFUNCTYPE(c_int)), + ('i2a', CFUNCTYPE(c_int)), +] +assert sizeof(X509_objects_st) == 12, sizeof(X509_objects_st) +assert alignment(X509_objects_st) == 4, alignment(X509_objects_st) +X509_OBJECTS = X509_objects_st +X509_algor_st._fields_ = [ + ('algorithm', POINTER(ASN1_OBJECT)), + ('parameter', POINTER(ASN1_TYPE)), +] +assert sizeof(X509_algor_st) == 8, sizeof(X509_algor_st) +assert alignment(X509_algor_st) == 4, alignment(X509_algor_st) +class X509_val_st(Structure): + pass +X509_val_st._fields_ = [ + ('notBefore', POINTER(ASN1_TIME)), + ('notAfter', POINTER(ASN1_TIME)), +] +assert sizeof(X509_val_st) == 8, sizeof(X509_val_st) +assert alignment(X509_val_st) == 4, alignment(X509_val_st) +X509_VAL = X509_val_st +class X509_pubkey_st(Structure): + pass +X509_pubkey_st._fields_ = [ + ('algor', POINTER(X509_ALGOR)), + ('public_key', POINTER(ASN1_BIT_STRING)), + ('pkey', POINTER(EVP_PKEY)), +] +assert sizeof(X509_pubkey_st) == 12, sizeof(X509_pubkey_st) +assert alignment(X509_pubkey_st) == 4, alignment(X509_pubkey_st) +X509_PUBKEY = X509_pubkey_st +class X509_sig_st(Structure): + pass +X509_sig_st._fields_ = [ + ('algor', POINTER(X509_ALGOR)), + ('digest', POINTER(ASN1_OCTET_STRING)), +] +assert sizeof(X509_sig_st) == 8, sizeof(X509_sig_st) +assert alignment(X509_sig_st) == 4, alignment(X509_sig_st) +X509_SIG = X509_sig_st +class X509_name_entry_st(Structure): + pass +X509_name_entry_st._fields_ = [ + ('object', POINTER(ASN1_OBJECT)), + ('value', POINTER(ASN1_STRING)), + ('set', c_int), + ('size', c_int), +] +assert sizeof(X509_name_entry_st) == 16, sizeof(X509_name_entry_st) +assert alignment(X509_name_entry_st) == 4, alignment(X509_name_entry_st) +X509_NAME_ENTRY = X509_name_entry_st +X509_name_st._fields_ = [ + ('entries', POINTER(STACK)), + ('modified', c_int), + ('bytes', POINTER(BUF_MEM)), + ('hash', c_ulong), +] +assert sizeof(X509_name_st) == 16, sizeof(X509_name_st) +assert alignment(X509_name_st) == 4, alignment(X509_name_st) +class X509_extension_st(Structure): + pass +X509_extension_st._fields_ = [ + ('object', POINTER(ASN1_OBJECT)), + ('critical', ASN1_BOOLEAN), + ('value', POINTER(ASN1_OCTET_STRING)), +] +assert sizeof(X509_extension_st) == 12, sizeof(X509_extension_st) +assert alignment(X509_extension_st) == 4, alignment(X509_extension_st) +X509_EXTENSION = X509_extension_st +class x509_attributes_st(Structure): + pass +class N18x509_attributes_st4DOLLAR_13E(Union): + pass +N18x509_attributes_st4DOLLAR_13E._fields_ = [ + ('ptr', STRING), + ('set', POINTER(STACK)), + ('single', POINTER(ASN1_TYPE)), +] +assert sizeof(N18x509_attributes_st4DOLLAR_13E) == 4, sizeof(N18x509_attributes_st4DOLLAR_13E) +assert alignment(N18x509_attributes_st4DOLLAR_13E) == 4, alignment(N18x509_attributes_st4DOLLAR_13E) +x509_attributes_st._fields_ = [ + ('object', POINTER(ASN1_OBJECT)), + ('single', c_int), + ('value', N18x509_attributes_st4DOLLAR_13E), +] +assert sizeof(x509_attributes_st) == 12, sizeof(x509_attributes_st) +assert alignment(x509_attributes_st) == 4, alignment(x509_attributes_st) +X509_ATTRIBUTE = x509_attributes_st +class X509_req_info_st(Structure): + pass +X509_req_info_st._fields_ = [ + ('enc', ASN1_ENCODING), + ('version', POINTER(ASN1_INTEGER)), + ('subject', POINTER(X509_NAME)), + ('pubkey', POINTER(X509_PUBKEY)), + ('attributes', POINTER(STACK)), +] +assert sizeof(X509_req_info_st) == 28, sizeof(X509_req_info_st) +assert alignment(X509_req_info_st) == 4, alignment(X509_req_info_st) +X509_REQ_INFO = X509_req_info_st +class X509_req_st(Structure): + pass +X509_req_st._fields_ = [ + ('req_info', POINTER(X509_REQ_INFO)), + ('sig_alg', POINTER(X509_ALGOR)), + ('signature', POINTER(ASN1_BIT_STRING)), + ('references', c_int), +] +assert sizeof(X509_req_st) == 16, sizeof(X509_req_st) +assert alignment(X509_req_st) == 4, alignment(X509_req_st) +X509_REQ = X509_req_st +class x509_cinf_st(Structure): + pass +x509_cinf_st._fields_ = [ + ('version', POINTER(ASN1_INTEGER)), + ('serialNumber', POINTER(ASN1_INTEGER)), + ('signature', POINTER(X509_ALGOR)), + ('issuer', POINTER(X509_NAME)), + ('validity', POINTER(X509_VAL)), + ('subject', POINTER(X509_NAME)), + ('key', POINTER(X509_PUBKEY)), + ('issuerUID', POINTER(ASN1_BIT_STRING)), + ('subjectUID', POINTER(ASN1_BIT_STRING)), + ('extensions', POINTER(STACK)), +] +assert sizeof(x509_cinf_st) == 40, sizeof(x509_cinf_st) +assert alignment(x509_cinf_st) == 4, alignment(x509_cinf_st) +X509_CINF = x509_cinf_st +class x509_cert_aux_st(Structure): + pass +x509_cert_aux_st._fields_ = [ + ('trust', POINTER(STACK)), + ('reject', POINTER(STACK)), + ('alias', POINTER(ASN1_UTF8STRING)), + ('keyid', POINTER(ASN1_OCTET_STRING)), + ('other', POINTER(STACK)), +] +assert sizeof(x509_cert_aux_st) == 20, sizeof(x509_cert_aux_st) +assert alignment(x509_cert_aux_st) == 4, alignment(x509_cert_aux_st) +X509_CERT_AUX = x509_cert_aux_st +class AUTHORITY_KEYID_st(Structure): + pass +x509_st._fields_ = [ + ('cert_info', POINTER(X509_CINF)), + ('sig_alg', POINTER(X509_ALGOR)), + ('signature', POINTER(ASN1_BIT_STRING)), + ('valid', c_int), + ('references', c_int), + ('name', STRING), + ('ex_data', CRYPTO_EX_DATA), + ('ex_pathlen', c_long), + ('ex_flags', c_ulong), + ('ex_kusage', c_ulong), + ('ex_xkusage', c_ulong), + ('ex_nscert', c_ulong), + ('skid', POINTER(ASN1_OCTET_STRING)), + ('akid', POINTER(AUTHORITY_KEYID_st)), + ('sha1_hash', c_ubyte * 20), + ('aux', POINTER(X509_CERT_AUX)), +] +assert sizeof(x509_st) == 84, sizeof(x509_st) +assert alignment(x509_st) == 4, alignment(x509_st) +AUTHORITY_KEYID_st._fields_ = [ +] +class x509_trust_st(Structure): + pass +x509_trust_st._fields_ = [ + ('trust', c_int), + ('flags', c_int), + ('check_trust', CFUNCTYPE(c_int, POINTER(x509_trust_st), POINTER(X509), c_int)), + ('name', STRING), + ('arg1', c_int), + ('arg2', c_void_p), +] +assert sizeof(x509_trust_st) == 24, sizeof(x509_trust_st) +assert alignment(x509_trust_st) == 4, alignment(x509_trust_st) +X509_TRUST = x509_trust_st +class X509_revoked_st(Structure): + pass +X509_revoked_st._fields_ = [ + ('serialNumber', POINTER(ASN1_INTEGER)), + ('revocationDate', POINTER(ASN1_TIME)), + ('extensions', POINTER(STACK)), + ('sequence', c_int), +] +assert sizeof(X509_revoked_st) == 16, sizeof(X509_revoked_st) +assert alignment(X509_revoked_st) == 4, alignment(X509_revoked_st) +X509_REVOKED = X509_revoked_st +class X509_crl_info_st(Structure): + pass +X509_crl_info_st._fields_ = [ + ('version', POINTER(ASN1_INTEGER)), + ('sig_alg', POINTER(X509_ALGOR)), + ('issuer', POINTER(X509_NAME)), + ('lastUpdate', POINTER(ASN1_TIME)), + ('nextUpdate', POINTER(ASN1_TIME)), + ('revoked', POINTER(STACK)), + ('extensions', POINTER(STACK)), + ('enc', ASN1_ENCODING), +] +assert sizeof(X509_crl_info_st) == 40, sizeof(X509_crl_info_st) +assert alignment(X509_crl_info_st) == 4, alignment(X509_crl_info_st) +X509_CRL_INFO = X509_crl_info_st +X509_crl_st._fields_ = [ + ('crl', POINTER(X509_CRL_INFO)), + ('sig_alg', POINTER(X509_ALGOR)), + ('signature', POINTER(ASN1_BIT_STRING)), + ('references', c_int), +] +assert sizeof(X509_crl_st) == 16, sizeof(X509_crl_st) +assert alignment(X509_crl_st) == 4, alignment(X509_crl_st) +class private_key_st(Structure): + pass +private_key_st._fields_ = [ + ('version', c_int), + ('enc_algor', POINTER(X509_ALGOR)), + ('enc_pkey', POINTER(ASN1_OCTET_STRING)), + ('dec_pkey', POINTER(EVP_PKEY)), + ('key_length', c_int), + ('key_data', STRING), + ('key_free', c_int), + ('cipher', EVP_CIPHER_INFO), + ('references', c_int), +] +assert sizeof(private_key_st) == 52, sizeof(private_key_st) +assert alignment(private_key_st) == 4, alignment(private_key_st) +X509_PKEY = private_key_st +class X509_info_st(Structure): + pass +X509_info_st._fields_ = [ + ('x509', POINTER(X509)), + ('crl', POINTER(X509_CRL)), + ('x_pkey', POINTER(X509_PKEY)), + ('enc_cipher', EVP_CIPHER_INFO), + ('enc_len', c_int), + ('enc_data', STRING), + ('references', c_int), +] +assert sizeof(X509_info_st) == 44, sizeof(X509_info_st) +assert alignment(X509_info_st) == 4, alignment(X509_info_st) +X509_INFO = X509_info_st +class Netscape_spkac_st(Structure): + pass +Netscape_spkac_st._fields_ = [ + ('pubkey', POINTER(X509_PUBKEY)), + ('challenge', POINTER(ASN1_IA5STRING)), +] +assert sizeof(Netscape_spkac_st) == 8, sizeof(Netscape_spkac_st) +assert alignment(Netscape_spkac_st) == 4, alignment(Netscape_spkac_st) +NETSCAPE_SPKAC = Netscape_spkac_st +class Netscape_spki_st(Structure): + pass +Netscape_spki_st._fields_ = [ + ('spkac', POINTER(NETSCAPE_SPKAC)), + ('sig_algor', POINTER(X509_ALGOR)), + ('signature', POINTER(ASN1_BIT_STRING)), +] +assert sizeof(Netscape_spki_st) == 12, sizeof(Netscape_spki_st) +assert alignment(Netscape_spki_st) == 4, alignment(Netscape_spki_st) +NETSCAPE_SPKI = Netscape_spki_st +class Netscape_certificate_sequence(Structure): + pass +Netscape_certificate_sequence._fields_ = [ + ('type', POINTER(ASN1_OBJECT)), + ('certs', POINTER(STACK)), +] +assert sizeof(Netscape_certificate_sequence) == 8, sizeof(Netscape_certificate_sequence) +assert alignment(Netscape_certificate_sequence) == 4, alignment(Netscape_certificate_sequence) +NETSCAPE_CERT_SEQUENCE = Netscape_certificate_sequence +class PBEPARAM_st(Structure): + pass +PBEPARAM_st._fields_ = [ + ('salt', POINTER(ASN1_OCTET_STRING)), + ('iter', POINTER(ASN1_INTEGER)), +] +assert sizeof(PBEPARAM_st) == 8, sizeof(PBEPARAM_st) +assert alignment(PBEPARAM_st) == 4, alignment(PBEPARAM_st) +PBEPARAM = PBEPARAM_st +class PBE2PARAM_st(Structure): + pass +PBE2PARAM_st._fields_ = [ + ('keyfunc', POINTER(X509_ALGOR)), + ('encryption', POINTER(X509_ALGOR)), +] +assert sizeof(PBE2PARAM_st) == 8, sizeof(PBE2PARAM_st) +assert alignment(PBE2PARAM_st) == 4, alignment(PBE2PARAM_st) +PBE2PARAM = PBE2PARAM_st +class PBKDF2PARAM_st(Structure): + pass +PBKDF2PARAM_st._fields_ = [ + ('salt', POINTER(ASN1_TYPE)), + ('iter', POINTER(ASN1_INTEGER)), + ('keylength', POINTER(ASN1_INTEGER)), + ('prf', POINTER(X509_ALGOR)), +] +assert sizeof(PBKDF2PARAM_st) == 16, sizeof(PBKDF2PARAM_st) +assert alignment(PBKDF2PARAM_st) == 4, alignment(PBKDF2PARAM_st) +PBKDF2PARAM = PBKDF2PARAM_st +class pkcs8_priv_key_info_st(Structure): + pass +pkcs8_priv_key_info_st._fields_ = [ + ('broken', c_int), + ('version', POINTER(ASN1_INTEGER)), + ('pkeyalg', POINTER(X509_ALGOR)), + ('pkey', POINTER(ASN1_TYPE)), + ('attributes', POINTER(STACK)), +] +assert sizeof(pkcs8_priv_key_info_st) == 20, sizeof(pkcs8_priv_key_info_st) +assert alignment(pkcs8_priv_key_info_st) == 4, alignment(pkcs8_priv_key_info_st) +PKCS8_PRIV_KEY_INFO = pkcs8_priv_key_info_st +class x509_hash_dir_st(Structure): + pass +x509_hash_dir_st._fields_ = [ + ('num_dirs', c_int), + ('dirs', POINTER(STRING)), + ('dirs_type', POINTER(c_int)), + ('num_dirs_alloced', c_int), +] +assert sizeof(x509_hash_dir_st) == 16, sizeof(x509_hash_dir_st) +assert alignment(x509_hash_dir_st) == 4, alignment(x509_hash_dir_st) +X509_HASH_DIR_CTX = x509_hash_dir_st +class x509_file_st(Structure): + pass +x509_file_st._fields_ = [ + ('num_paths', c_int), + ('num_alloced', c_int), + ('paths', POINTER(STRING)), + ('path_type', POINTER(c_int)), +] +assert sizeof(x509_file_st) == 16, sizeof(x509_file_st) +assert alignment(x509_file_st) == 4, alignment(x509_file_st) +X509_CERT_FILE_CTX = x509_file_st +class x509_object_st(Structure): + pass +class N14x509_object_st4DOLLAR_14E(Union): + pass +N14x509_object_st4DOLLAR_14E._fields_ = [ + ('ptr', STRING), + ('x509', POINTER(X509)), + ('crl', POINTER(X509_CRL)), + ('pkey', POINTER(EVP_PKEY)), +] +assert sizeof(N14x509_object_st4DOLLAR_14E) == 4, sizeof(N14x509_object_st4DOLLAR_14E) +assert alignment(N14x509_object_st4DOLLAR_14E) == 4, alignment(N14x509_object_st4DOLLAR_14E) +x509_object_st._fields_ = [ + ('type', c_int), + ('data', N14x509_object_st4DOLLAR_14E), +] +assert sizeof(x509_object_st) == 8, sizeof(x509_object_st) +assert alignment(x509_object_st) == 4, alignment(x509_object_st) +X509_OBJECT = x509_object_st +class x509_lookup_st(Structure): + pass +X509_LOOKUP = x509_lookup_st +class x509_lookup_method_st(Structure): + pass +x509_lookup_method_st._fields_ = [ + ('name', STRING), + ('new_item', CFUNCTYPE(c_int, POINTER(X509_LOOKUP))), + ('free', CFUNCTYPE(None, POINTER(X509_LOOKUP))), + ('init', CFUNCTYPE(c_int, POINTER(X509_LOOKUP))), + ('shutdown', CFUNCTYPE(c_int, POINTER(X509_LOOKUP))), + ('ctrl', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, STRING, c_long, POINTER(STRING))), + ('get_by_subject', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, POINTER(X509_NAME), POINTER(X509_OBJECT))), + ('get_by_issuer_serial', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, POINTER(X509_NAME), POINTER(ASN1_INTEGER), POINTER(X509_OBJECT))), + ('get_by_fingerprint', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, POINTER(c_ubyte), c_int, POINTER(X509_OBJECT))), + ('get_by_alias', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, STRING, c_int, POINTER(X509_OBJECT))), +] +assert sizeof(x509_lookup_method_st) == 40, sizeof(x509_lookup_method_st) +assert alignment(x509_lookup_method_st) == 4, alignment(x509_lookup_method_st) +X509_LOOKUP_METHOD = x509_lookup_method_st +x509_store_st._fields_ = [ + ('cache', c_int), + ('objs', POINTER(STACK)), + ('get_cert_methods', POINTER(STACK)), + ('flags', c_ulong), + ('purpose', c_int), + ('trust', c_int), + ('verify', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), + ('verify_cb', CFUNCTYPE(c_int, c_int, POINTER(X509_STORE_CTX))), + ('get_issuer', CFUNCTYPE(c_int, POINTER(POINTER(X509)), POINTER(X509_STORE_CTX), POINTER(X509))), + ('check_issued', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509), POINTER(X509))), + ('check_revocation', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), + ('get_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(POINTER(X509_CRL)), POINTER(X509))), + ('check_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509_CRL))), + ('cert_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509_CRL), POINTER(X509))), + ('cleanup', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), + ('ex_data', CRYPTO_EX_DATA), + ('references', c_int), + ('depth', c_int), +] +assert sizeof(x509_store_st) == 76, sizeof(x509_store_st) +assert alignment(x509_store_st) == 4, alignment(x509_store_st) +x509_lookup_st._fields_ = [ + ('init', c_int), + ('skip', c_int), + ('method', POINTER(X509_LOOKUP_METHOD)), + ('method_data', STRING), + ('store_ctx', POINTER(X509_STORE)), +] +assert sizeof(x509_lookup_st) == 20, sizeof(x509_lookup_st) +assert alignment(x509_lookup_st) == 4, alignment(x509_lookup_st) +time_t = __darwin_time_t +x509_store_ctx_st._fields_ = [ + ('ctx', POINTER(X509_STORE)), + ('current_method', c_int), + ('cert', POINTER(X509)), + ('untrusted', POINTER(STACK)), + ('purpose', c_int), + ('trust', c_int), + ('check_time', time_t), + ('flags', c_ulong), + ('other_ctx', c_void_p), + ('verify', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), + ('verify_cb', CFUNCTYPE(c_int, c_int, POINTER(X509_STORE_CTX))), + ('get_issuer', CFUNCTYPE(c_int, POINTER(POINTER(X509)), POINTER(X509_STORE_CTX), POINTER(X509))), + ('check_issued', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509), POINTER(X509))), + ('check_revocation', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), + ('get_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(POINTER(X509_CRL)), POINTER(X509))), + ('check_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509_CRL))), + ('cert_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509_CRL), POINTER(X509))), + ('cleanup', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))), + ('depth', c_int), + ('valid', c_int), + ('last_untrusted', c_int), + ('chain', POINTER(STACK)), + ('error_depth', c_int), + ('error', c_int), + ('current_cert', POINTER(X509)), + ('current_issuer', POINTER(X509)), + ('current_crl', POINTER(X509_CRL)), + ('ex_data', CRYPTO_EX_DATA), +] +assert sizeof(x509_store_ctx_st) == 116, sizeof(x509_store_ctx_st) +assert alignment(x509_store_ctx_st) == 4, alignment(x509_store_ctx_st) +va_list = __darwin_va_list +__darwin_off_t = __int64_t +fpos_t = __darwin_off_t +class __sbuf(Structure): + pass +__sbuf._fields_ = [ + ('_base', POINTER(c_ubyte)), + ('_size', c_int), +] +assert sizeof(__sbuf) == 8, sizeof(__sbuf) +assert alignment(__sbuf) == 4, alignment(__sbuf) +class __sFILEX(Structure): + pass +__sFILEX._fields_ = [ +] +class __sFILE(Structure): + pass +__sFILE._pack_ = 4 +__sFILE._fields_ = [ + ('_p', POINTER(c_ubyte)), + ('_r', c_int), + ('_w', c_int), + ('_flags', c_short), + ('_file', c_short), + ('_bf', __sbuf), + ('_lbfsize', c_int), + ('_cookie', c_void_p), + ('_close', CFUNCTYPE(c_int, c_void_p)), + ('_read', CFUNCTYPE(c_int, c_void_p, STRING, c_int)), + ('_seek', CFUNCTYPE(fpos_t, c_void_p, c_longlong, c_int)), + ('_write', CFUNCTYPE(c_int, c_void_p, STRING, c_int)), + ('_ub', __sbuf), + ('_extra', POINTER(__sFILEX)), + ('_ur', c_int), + ('_ubuf', c_ubyte * 3), + ('_nbuf', c_ubyte * 1), + ('_lb', __sbuf), + ('_blksize', c_int), + ('_offset', fpos_t), +] +assert sizeof(__sFILE) == 88, sizeof(__sFILE) +assert alignment(__sFILE) == 4, alignment(__sFILE) +FILE = __sFILE +ct_rune_t = __darwin_ct_rune_t +rune_t = __darwin_rune_t +class div_t(Structure): + pass +div_t._fields_ = [ + ('quot', c_int), + ('rem', c_int), +] +assert sizeof(div_t) == 8, sizeof(div_t) +assert alignment(div_t) == 4, alignment(div_t) +class ldiv_t(Structure): + pass +ldiv_t._fields_ = [ + ('quot', c_long), + ('rem', c_long), +] +assert sizeof(ldiv_t) == 8, sizeof(ldiv_t) +assert alignment(ldiv_t) == 4, alignment(ldiv_t) +class lldiv_t(Structure): + pass +lldiv_t._pack_ = 4 +lldiv_t._fields_ = [ + ('quot', c_longlong), + ('rem', c_longlong), +] +assert sizeof(lldiv_t) == 16, sizeof(lldiv_t) +assert alignment(lldiv_t) == 4, alignment(lldiv_t) +__darwin_dev_t = __int32_t +dev_t = __darwin_dev_t +__darwin_mode_t = __uint16_t +mode_t = __darwin_mode_t +class mcontext(Structure): + pass +mcontext._fields_ = [ +] +class mcontext64(Structure): + pass +mcontext64._fields_ = [ +] +class __darwin_pthread_handler_rec(Structure): + pass +__darwin_pthread_handler_rec._fields_ = [ + ('__routine', CFUNCTYPE(None, c_void_p)), + ('__arg', c_void_p), + ('__next', POINTER(__darwin_pthread_handler_rec)), +] +assert sizeof(__darwin_pthread_handler_rec) == 12, sizeof(__darwin_pthread_handler_rec) +assert alignment(__darwin_pthread_handler_rec) == 4, alignment(__darwin_pthread_handler_rec) +class _opaque_pthread_attr_t(Structure): + pass +_opaque_pthread_attr_t._fields_ = [ + ('__sig', c_long), + ('__opaque', c_char * 36), +] +assert sizeof(_opaque_pthread_attr_t) == 40, sizeof(_opaque_pthread_attr_t) +assert alignment(_opaque_pthread_attr_t) == 4, alignment(_opaque_pthread_attr_t) +class _opaque_pthread_cond_t(Structure): + pass +_opaque_pthread_cond_t._fields_ = [ + ('__sig', c_long), + ('__opaque', c_char * 24), +] +assert sizeof(_opaque_pthread_cond_t) == 28, sizeof(_opaque_pthread_cond_t) +assert alignment(_opaque_pthread_cond_t) == 4, alignment(_opaque_pthread_cond_t) +class _opaque_pthread_condattr_t(Structure): + pass +_opaque_pthread_condattr_t._fields_ = [ + ('__sig', c_long), + ('__opaque', c_char * 4), +] +assert sizeof(_opaque_pthread_condattr_t) == 8, sizeof(_opaque_pthread_condattr_t) +assert alignment(_opaque_pthread_condattr_t) == 4, alignment(_opaque_pthread_condattr_t) +class _opaque_pthread_mutex_t(Structure): + pass +_opaque_pthread_mutex_t._fields_ = [ + ('__sig', c_long), + ('__opaque', c_char * 40), +] +assert sizeof(_opaque_pthread_mutex_t) == 44, sizeof(_opaque_pthread_mutex_t) +assert alignment(_opaque_pthread_mutex_t) == 4, alignment(_opaque_pthread_mutex_t) +class _opaque_pthread_mutexattr_t(Structure): + pass +_opaque_pthread_mutexattr_t._fields_ = [ + ('__sig', c_long), + ('__opaque', c_char * 8), +] +assert sizeof(_opaque_pthread_mutexattr_t) == 12, sizeof(_opaque_pthread_mutexattr_t) +assert alignment(_opaque_pthread_mutexattr_t) == 4, alignment(_opaque_pthread_mutexattr_t) +class _opaque_pthread_once_t(Structure): + pass +_opaque_pthread_once_t._fields_ = [ + ('__sig', c_long), + ('__opaque', c_char * 4), +] +assert sizeof(_opaque_pthread_once_t) == 8, sizeof(_opaque_pthread_once_t) +assert alignment(_opaque_pthread_once_t) == 4, alignment(_opaque_pthread_once_t) +class _opaque_pthread_rwlock_t(Structure): + pass +_opaque_pthread_rwlock_t._fields_ = [ + ('__sig', c_long), + ('__opaque', c_char * 124), +] +assert sizeof(_opaque_pthread_rwlock_t) == 128, sizeof(_opaque_pthread_rwlock_t) +assert alignment(_opaque_pthread_rwlock_t) == 4, alignment(_opaque_pthread_rwlock_t) +class _opaque_pthread_rwlockattr_t(Structure): + pass +_opaque_pthread_rwlockattr_t._fields_ = [ + ('__sig', c_long), + ('__opaque', c_char * 12), +] +assert sizeof(_opaque_pthread_rwlockattr_t) == 16, sizeof(_opaque_pthread_rwlockattr_t) +assert alignment(_opaque_pthread_rwlockattr_t) == 4, alignment(_opaque_pthread_rwlockattr_t) +class _opaque_pthread_t(Structure): + pass +_opaque_pthread_t._fields_ = [ + ('__sig', c_long), + ('__cleanup_stack', POINTER(__darwin_pthread_handler_rec)), + ('__opaque', c_char * 596), +] +assert sizeof(_opaque_pthread_t) == 604, sizeof(_opaque_pthread_t) +assert alignment(_opaque_pthread_t) == 4, alignment(_opaque_pthread_t) +__darwin_blkcnt_t = __int64_t +__darwin_blksize_t = __int32_t +__darwin_fsblkcnt_t = c_uint +__darwin_fsfilcnt_t = c_uint +__darwin_gid_t = __uint32_t +__darwin_id_t = __uint32_t +__darwin_ino_t = __uint32_t +__darwin_mach_port_name_t = __darwin_natural_t +__darwin_mach_port_t = __darwin_mach_port_name_t +__darwin_mcontext_t = POINTER(mcontext) +__darwin_mcontext64_t = POINTER(mcontext64) +__darwin_pid_t = __int32_t +__darwin_pthread_attr_t = _opaque_pthread_attr_t +__darwin_pthread_cond_t = _opaque_pthread_cond_t +__darwin_pthread_condattr_t = _opaque_pthread_condattr_t +__darwin_pthread_key_t = c_ulong +__darwin_pthread_mutex_t = _opaque_pthread_mutex_t +__darwin_pthread_mutexattr_t = _opaque_pthread_mutexattr_t +__darwin_pthread_once_t = _opaque_pthread_once_t +__darwin_pthread_rwlock_t = _opaque_pthread_rwlock_t +__darwin_pthread_rwlockattr_t = _opaque_pthread_rwlockattr_t +__darwin_pthread_t = POINTER(_opaque_pthread_t) +__darwin_sigset_t = __uint32_t +__darwin_suseconds_t = __int32_t +__darwin_uid_t = __uint32_t +__darwin_useconds_t = __uint32_t +__darwin_uuid_t = c_ubyte * 16 +class sigaltstack(Structure): + pass +sigaltstack._fields_ = [ + ('ss_sp', c_void_p), + ('ss_size', __darwin_size_t), + ('ss_flags', c_int), +] +assert sizeof(sigaltstack) == 12, sizeof(sigaltstack) +assert alignment(sigaltstack) == 4, alignment(sigaltstack) +__darwin_stack_t = sigaltstack +class ucontext(Structure): + pass +ucontext._fields_ = [ + ('uc_onstack', c_int), + ('uc_sigmask', __darwin_sigset_t), + ('uc_stack', __darwin_stack_t), + ('uc_link', POINTER(ucontext)), + ('uc_mcsize', __darwin_size_t), + ('uc_mcontext', __darwin_mcontext_t), +] +assert sizeof(ucontext) == 32, sizeof(ucontext) +assert alignment(ucontext) == 4, alignment(ucontext) +__darwin_ucontext_t = ucontext +class ucontext64(Structure): + pass +ucontext64._fields_ = [ + ('uc_onstack', c_int), + ('uc_sigmask', __darwin_sigset_t), + ('uc_stack', __darwin_stack_t), + ('uc_link', POINTER(ucontext64)), + ('uc_mcsize', __darwin_size_t), + ('uc_mcontext64', __darwin_mcontext64_t), +] +assert sizeof(ucontext64) == 32, sizeof(ucontext64) +assert alignment(ucontext64) == 4, alignment(ucontext64) +__darwin_ucontext64_t = ucontext64 +class timeval(Structure): + pass +timeval._fields_ = [ + ('tv_sec', __darwin_time_t), + ('tv_usec', __darwin_suseconds_t), +] +assert sizeof(timeval) == 8, sizeof(timeval) +assert alignment(timeval) == 4, alignment(timeval) +rlim_t = __int64_t +class rusage(Structure): + pass +rusage._fields_ = [ + ('ru_utime', timeval), + ('ru_stime', timeval), + ('ru_maxrss', c_long), + ('ru_ixrss', c_long), + ('ru_idrss', c_long), + ('ru_isrss', c_long), + ('ru_minflt', c_long), + ('ru_majflt', c_long), + ('ru_nswap', c_long), + ('ru_inblock', c_long), + ('ru_oublock', c_long), + ('ru_msgsnd', c_long), + ('ru_msgrcv', c_long), + ('ru_nsignals', c_long), + ('ru_nvcsw', c_long), + ('ru_nivcsw', c_long), +] +assert sizeof(rusage) == 72, sizeof(rusage) +assert alignment(rusage) == 4, alignment(rusage) +class rlimit(Structure): + pass +rlimit._pack_ = 4 +rlimit._fields_ = [ + ('rlim_cur', rlim_t), + ('rlim_max', rlim_t), +] +assert sizeof(rlimit) == 16, sizeof(rlimit) +assert alignment(rlimit) == 4, alignment(rlimit) +mcontext_t = __darwin_mcontext_t +mcontext64_t = __darwin_mcontext64_t +pthread_attr_t = __darwin_pthread_attr_t +sigset_t = __darwin_sigset_t +ucontext_t = __darwin_ucontext_t +ucontext64_t = __darwin_ucontext64_t +uid_t = __darwin_uid_t +class sigval(Union): + pass +sigval._fields_ = [ + ('sival_int', c_int), + ('sival_ptr', c_void_p), +] +assert sizeof(sigval) == 4, sizeof(sigval) +assert alignment(sigval) == 4, alignment(sigval) +class sigevent(Structure): + pass +sigevent._fields_ = [ + ('sigev_notify', c_int), + ('sigev_signo', c_int), + ('sigev_value', sigval), + ('sigev_notify_function', CFUNCTYPE(None, sigval)), + ('sigev_notify_attributes', POINTER(pthread_attr_t)), +] +assert sizeof(sigevent) == 20, sizeof(sigevent) +assert alignment(sigevent) == 4, alignment(sigevent) +class __siginfo(Structure): + pass +pid_t = __darwin_pid_t +__siginfo._fields_ = [ + ('si_signo', c_int), + ('si_errno', c_int), + ('si_code', c_int), + ('si_pid', pid_t), + ('si_uid', uid_t), + ('si_status', c_int), + ('si_addr', c_void_p), + ('si_value', sigval), + ('si_band', c_long), + ('pad', c_ulong * 7), +] +assert sizeof(__siginfo) == 64, sizeof(__siginfo) +assert alignment(__siginfo) == 4, alignment(__siginfo) +siginfo_t = __siginfo +class __sigaction_u(Union): + pass +__sigaction_u._fields_ = [ + ('__sa_handler', CFUNCTYPE(None, c_int)), + ('__sa_sigaction', CFUNCTYPE(None, c_int, POINTER(__siginfo), c_void_p)), +] +assert sizeof(__sigaction_u) == 4, sizeof(__sigaction_u) +assert alignment(__sigaction_u) == 4, alignment(__sigaction_u) +class __sigaction(Structure): + pass +__sigaction._fields_ = [ + ('__sigaction_u', __sigaction_u), + ('sa_tramp', CFUNCTYPE(None, c_void_p, c_int, c_int, POINTER(siginfo_t), c_void_p)), + ('sa_mask', sigset_t), + ('sa_flags', c_int), +] +assert sizeof(__sigaction) == 16, sizeof(__sigaction) +assert alignment(__sigaction) == 4, alignment(__sigaction) +class sigaction(Structure): + pass +sigaction._fields_ = [ + ('__sigaction_u', __sigaction_u), + ('sa_mask', sigset_t), + ('sa_flags', c_int), +] +assert sizeof(sigaction) == 12, sizeof(sigaction) +assert alignment(sigaction) == 4, alignment(sigaction) +sig_t = CFUNCTYPE(None, c_int) +stack_t = __darwin_stack_t +class sigvec(Structure): + pass +sigvec._fields_ = [ + ('sv_handler', CFUNCTYPE(None, c_int)), + ('sv_mask', c_int), + ('sv_flags', c_int), +] +assert sizeof(sigvec) == 12, sizeof(sigvec) +assert alignment(sigvec) == 4, alignment(sigvec) +class sigstack(Structure): + pass +sigstack._fields_ = [ + ('ss_sp', STRING), + ('ss_onstack', c_int), +] +assert sizeof(sigstack) == 8, sizeof(sigstack) +assert alignment(sigstack) == 4, alignment(sigstack) +u_char = c_ubyte +u_short = c_ushort +u_int = c_uint +u_long = c_ulong +ushort = c_ushort +uint = c_uint +u_quad_t = u_int64_t +quad_t = int64_t +qaddr_t = POINTER(quad_t) +caddr_t = STRING +daddr_t = int32_t +fixpt_t = u_int32_t +blkcnt_t = __darwin_blkcnt_t +blksize_t = __darwin_blksize_t +gid_t = __darwin_gid_t +in_addr_t = __uint32_t +in_port_t = __uint16_t +ino_t = __darwin_ino_t +key_t = __int32_t +nlink_t = __uint16_t +off_t = __darwin_off_t +segsz_t = int32_t +swblk_t = int32_t +clock_t = __darwin_clock_t +ssize_t = __darwin_ssize_t +useconds_t = __darwin_useconds_t +suseconds_t = __darwin_suseconds_t +fd_mask = __int32_t +class fd_set(Structure): + pass +fd_set._fields_ = [ + ('fds_bits', __int32_t * 32), +] +assert sizeof(fd_set) == 128, sizeof(fd_set) +assert alignment(fd_set) == 4, alignment(fd_set) +pthread_cond_t = __darwin_pthread_cond_t +pthread_condattr_t = __darwin_pthread_condattr_t +pthread_mutex_t = __darwin_pthread_mutex_t +pthread_mutexattr_t = __darwin_pthread_mutexattr_t +pthread_once_t = __darwin_pthread_once_t +pthread_rwlock_t = __darwin_pthread_rwlock_t +pthread_rwlockattr_t = __darwin_pthread_rwlockattr_t +pthread_t = __darwin_pthread_t +pthread_key_t = __darwin_pthread_key_t +fsblkcnt_t = __darwin_fsblkcnt_t +fsfilcnt_t = __darwin_fsfilcnt_t + +# values for enumeration 'idtype_t' +idtype_t = c_int # enum +id_t = __darwin_id_t +class wait(Union): + pass +class N4wait3DOLLAR_3E(Structure): + pass +N4wait3DOLLAR_3E._fields_ = [ + ('w_Termsig', c_uint, 7), + ('w_Coredump', c_uint, 1), + ('w_Retcode', c_uint, 8), + ('w_Filler', c_uint, 16), +] +assert sizeof(N4wait3DOLLAR_3E) == 4, sizeof(N4wait3DOLLAR_3E) +assert alignment(N4wait3DOLLAR_3E) == 4, alignment(N4wait3DOLLAR_3E) +class N4wait3DOLLAR_4E(Structure): + pass +N4wait3DOLLAR_4E._fields_ = [ + ('w_Stopval', c_uint, 8), + ('w_Stopsig', c_uint, 8), + ('w_Filler', c_uint, 16), +] +assert sizeof(N4wait3DOLLAR_4E) == 4, sizeof(N4wait3DOLLAR_4E) +assert alignment(N4wait3DOLLAR_4E) == 4, alignment(N4wait3DOLLAR_4E) +wait._fields_ = [ + ('w_status', c_int), + ('w_T', N4wait3DOLLAR_3E), + ('w_S', N4wait3DOLLAR_4E), +] +assert sizeof(wait) == 4, sizeof(wait) +assert alignment(wait) == 4, alignment(wait) +class timespec(Structure): + pass +timespec._fields_ = [ + ('tv_sec', time_t), + ('tv_nsec', c_long), +] +assert sizeof(timespec) == 8, sizeof(timespec) +assert alignment(timespec) == 4, alignment(timespec) +class tm(Structure): + pass +tm._fields_ = [ + ('tm_sec', c_int), + ('tm_min', c_int), + ('tm_hour', c_int), + ('tm_mday', c_int), + ('tm_mon', c_int), + ('tm_year', c_int), + ('tm_wday', c_int), + ('tm_yday', c_int), + ('tm_isdst', c_int), + ('tm_gmtoff', c_long), + ('tm_zone', STRING), +] +assert sizeof(tm) == 44, sizeof(tm) +assert alignment(tm) == 4, alignment(tm) +__gnuc_va_list = STRING +ptrdiff_t = c_int +int8_t = c_byte +int16_t = c_short +uint8_t = c_ubyte +uint16_t = c_ushort +uint32_t = c_uint +uint64_t = c_ulonglong +int_least8_t = int8_t +int_least16_t = int16_t +int_least32_t = int32_t +int_least64_t = int64_t +uint_least8_t = uint8_t +uint_least16_t = uint16_t +uint_least32_t = uint32_t +uint_least64_t = uint64_t +int_fast8_t = int8_t +int_fast16_t = int16_t +int_fast32_t = int32_t +int_fast64_t = int64_t +uint_fast8_t = uint8_t +uint_fast16_t = uint16_t +uint_fast32_t = uint32_t +uint_fast64_t = uint64_t +intptr_t = c_long +uintptr_t = c_ulong +intmax_t = c_longlong +uintmax_t = c_ulonglong +__all__ = ['ENGINE', 'pkcs7_enc_content_st', '__int16_t', + 'X509_REVOKED', 'SSL_CTX', 'UIT_BOOLEAN', + '__darwin_time_t', 'ucontext64_t', 'int_fast32_t', + 'pem_ctx_st', 'uint8_t', 'fpos_t', 'X509', 'COMP_CTX', + 'tm', 'N10pem_ctx_st4DOLLAR_17E', 'swblk_t', + 'ASN1_TEMPLATE', '__darwin_pthread_t', 'fixpt_t', + 'BIO_METHOD', 'ASN1_PRINTABLESTRING', 'EVP_ENCODE_CTX', + 'dh_method', 'bio_f_buffer_ctx_struct', 'in_port_t', + 'X509_SIG', '__darwin_ssize_t', '__darwin_sigset_t', + 'wait', 'uint_fast16_t', 'N12asn1_type_st4DOLLAR_11E', + 'uint_least8_t', 'pthread_rwlock_t', 'ASN1_IA5STRING', + 'fsfilcnt_t', 'ucontext', '__uint64_t', 'timespec', + 'x509_cinf_st', 'COMP_METHOD', 'MD5_CTX', 'buf_mem_st', + 'ASN1_ENCODING_st', 'PBEPARAM', 'X509_NAME_ENTRY', + '__darwin_va_list', 'ucontext_t', 'lhash_st', + 'N4wait3DOLLAR_4E', '__darwin_uuid_t', + '_ossl_old_des_ks_struct', 'id_t', 'ASN1_BIT_STRING', + 'va_list', '__darwin_wchar_t', 'pthread_key_t', + 'pkcs7_signer_info_st', 'ASN1_METHOD', 'DSA_SIG', 'DSA', + 'UIT_NONE', 'pthread_t', '__darwin_useconds_t', + 'uint_fast8_t', 'UI_STRING', 'DES_cblock', + '__darwin_mcontext64_t', 'rlim_t', 'PEM_Encode_Seal_st', + 'SHAstate_st', 'u_quad_t', 'openssl_fptr', + '_opaque_pthread_rwlockattr_t', + 'N18x509_attributes_st4DOLLAR_13E', + '__darwin_pthread_rwlock_t', 'daddr_t', 'ui_string_st', + 'x509_file_st', 'X509_req_info_st', 'int_least64_t', + 'evp_Encode_Ctx_st', 'X509_OBJECTS', 'CRYPTO_EX_DATA', + '__int8_t', 'AUTHORITY_KEYID_st', '_opaque_pthread_attr_t', + 'sigstack', 'EVP_CIPHER_CTX', 'X509_extension_st', 'pid_t', + 'RSA_METHOD', 'PEM_USER', 'pem_recip_st', 'env_md_ctx_st', + 'rc5_key_st', 'ui_st', 'X509_PUBKEY', 'u_int8_t', + 'ASN1_ITEM_st', 'pkcs7_recip_info_st', 'ssl2_state_st', + 'off_t', 'N10ssl_ctx_st4DOLLAR_18E', 'crypto_ex_data_st', + 'ui_method_st', '__darwin_pthread_rwlockattr_t', + 'CRYPTO_EX_dup', '__darwin_ino_t', '__sFILE', + 'OSUnknownByteOrder', 'BN_MONT_CTX', 'ASN1_NULL', 'time_t', + 'CRYPTO_EX_new', 'asn1_type_st', 'CRYPTO_EX_DATA_FUNCS', + 'user_time_t', 'BIGNUM', 'pthread_rwlockattr_t', + 'ASN1_VALUE_st', 'DH_METHOD', '__darwin_off_t', + '_opaque_pthread_t', 'bn_blinding_st', 'RSA', 'ssize_t', + 'mcontext64_t', 'user_long_t', 'fsblkcnt_t', 'cert_st', + '__darwin_pthread_condattr_t', 'X509_PKEY', + '__darwin_id_t', '__darwin_nl_item', 'SSL2_STATE', 'FILE', + 'pthread_mutexattr_t', 'size_t', + '_ossl_old_des_key_schedule', 'pkcs7_issuer_and_serial_st', + 'sigval', 'CRYPTO_MEM_LEAK_CB', 'X509_NAME', 'blkcnt_t', + 'uint_least16_t', '__darwin_dev_t', 'evp_cipher_info_st', + 'BN_BLINDING', 'ssl3_state_st', 'uint_least64_t', + 'user_addr_t', 'DES_key_schedule', 'RIPEMD160_CTX', + 'u_char', 'X509_algor_st', 'uid_t', 'sess_cert_st', + 'u_int64_t', 'u_int16_t', 'sigset_t', '__darwin_ptrdiff_t', + 'ASN1_CTX', 'STACK', '__int32_t', 'UI_METHOD', + 'NETSCAPE_SPKI', 'UIT_PROMPT', 'st_CRYPTO_EX_DATA_IMPL', + 'cast_key_st', 'X509_HASH_DIR_CTX', 'sigevent', + 'user_ssize_t', 'clock_t', 'aes_key_st', + '__darwin_socklen_t', '__darwin_intptr_t', 'int_fast64_t', + 'asn1_string_table_st', 'uint_fast32_t', + 'ASN1_VISIBLESTRING', 'DSA_SIG_st', 'obj_name_st', + 'X509_LOOKUP_METHOD', 'u_int32_t', 'EVP_CIPHER_INFO', + '__gnuc_va_list', 'AES_KEY', 'PKCS7_ISSUER_AND_SERIAL', + 'BN_CTX', '__darwin_blkcnt_t', 'key_t', 'SHA_CTX', + 'pkcs7_signed_st', 'SSL', 'N10pem_ctx_st4DOLLAR_16E', + 'pthread_attr_t', 'EVP_MD', 'uint', 'ASN1_BOOLEAN', + 'ino_t', '__darwin_clock_t', 'ASN1_OCTET_STRING', + 'asn1_ctx_st', 'BIO_F_BUFFER_CTX', 'bn_mont_ctx_st', + 'X509_REQ_INFO', 'PEM_CTX', 'sigvec', + '__darwin_pthread_mutexattr_t', 'x509_attributes_st', + 'stack_t', '__darwin_mode_t', '__mbstate_t', + 'asn1_object_st', 'ASN1_ENCODING', '__uint8_t', + 'LHASH_NODE', 'PKCS7_SIGNER_INFO', 'asn1_method_st', + 'stack_st', 'bio_info_cb', 'div_t', 'UIT_VERIFY', + 'PBEPARAM_st', 'N4wait3DOLLAR_3E', 'quad_t', '__siginfo', + '__darwin_mbstate_t', 'rsa_st', 'ASN1_UNIVERSALSTRING', + 'uint64_t', 'ssl_comp_st', 'X509_OBJECT', 'pthread_cond_t', + 'DH', '__darwin_wctype_t', 'PKCS7_ENVELOPE', 'ASN1_TLC_st', + 'sig_atomic_t', 'BIO', 'nlink_t', 'BUF_MEM', 'SSL3_RECORD', + 'bio_method_st', 'timeval', 'UI_string_types', 'BIO_dummy', + 'ssl_ctx_st', 'NETSCAPE_CERT_SEQUENCE', + 'BIT_STRING_BITNAME_st', '__darwin_pthread_attr_t', + 'int8_t', '__darwin_wint_t', 'OBJ_NAME', + 'PKCS8_PRIV_KEY_INFO', 'PBE2PARAM_st', + 'LHASH_DOALL_FN_TYPE', 'x509_st', 'X509_VAL', 'dev_t', + 'ASN1_TEMPLATE_st', 'MD5state_st', '__uint16_t', + 'LHASH_DOALL_ARG_FN_TYPE', 'mdc2_ctx_st', 'SSL3_STATE', + 'ssl3_buffer_st', 'ASN1_ITEM_EXP', + '_opaque_pthread_condattr_t', 'mode_t', 'ASN1_VALUE', + 'qaddr_t', '__darwin_gid_t', 'EVP_PKEY', 'CRYPTO_EX_free', + '_ossl_old_des_cblock', 'X509_INFO', 'asn1_string_st', + 'intptr_t', 'UIT_INFO', 'int_fast8_t', 'sigaltstack', + 'env_md_st', 'LHASH', '__darwin_ucontext_t', + 'PKCS7_SIGN_ENVELOPE', '__darwin_mcontext_t', 'ct_rune_t', + 'MD2_CTX', 'pthread_once_t', 'SSL3_BUFFER', 'fd_mask', + 'ASN1_TYPE', 'PKCS7_SIGNED', 'ssl3_record_st', 'BF_KEY', + 'MD4state_st', 'MD4_CTX', 'int16_t', 'SSL_CIPHER', + 'rune_t', 'X509_TRUST', 'siginfo_t', 'X509_STORE', + '__sbuf', 'X509_STORE_CTX', '__darwin_blksize_t', 'ldiv_t', + 'ASN1_TIME', 'SSL_METHOD', 'X509_LOOKUP', + 'Netscape_spki_st', 'P_PID', 'sigaction', 'sig_t', + 'hostent', 'x509_cert_aux_st', '_opaque_pthread_cond_t', + 'segsz_t', 'ushort', '__darwin_ct_rune_t', 'fd_set', + 'BN_RECP_CTX', 'x509_lookup_st', 'uint16_t', 'pkcs7_st', + 'asn1_header_st', '__darwin_pthread_key_t', + 'x509_trust_st', '__darwin_pthread_handler_rec', 'int32_t', + 'X509_CRL_INFO', 'N11evp_pkey_st4DOLLAR_12E', 'MDC2_CTX', + 'N23_ossl_old_des_ks_struct4DOLLAR_10E', 'ASN1_HEADER', + 'X509_crl_info_st', 'LHASH_HASH_FN_TYPE', + '_opaque_pthread_mutexattr_t', 'ssl_st', + 'N8pkcs7_st4DOLLAR_15E', 'evp_pkey_st', + 'pkcs7_signedandenveloped_st', '__darwin_mach_port_t', + 'EVP_PBE_KEYGEN', '_opaque_pthread_mutex_t', + 'ASN1_UTCTIME', 'mcontext', 'crypto_ex_data_func_st', + 'u_long', 'PBKDF2PARAM_st', 'rc4_key_st', 'DSA_METHOD', + 'EVP_CIPHER', 'BIT_STRING_BITNAME', 'PKCS7_RECIP_INFO', + 'ssl3_enc_method', 'X509_CERT_AUX', 'uintmax_t', + 'int_fast16_t', 'RC5_32_KEY', 'ucontext64', 'ASN1_INTEGER', + 'u_short', 'N14x509_object_st4DOLLAR_14E', 'mcontext64', + 'X509_sig_st', 'ASN1_GENERALSTRING', 'PKCS7', '__sFILEX', + 'X509_name_entry_st', 'ssl_session_st', 'caddr_t', + 'bignum_st', 'X509_CINF', '__darwin_pthread_cond_t', + 'ASN1_TLC', 'PKCS7_ENCRYPT', 'NETSCAPE_SPKAC', + 'Netscape_spkac_st', 'idtype_t', 'UIT_ERROR', + 'uint_fast64_t', 'in_addr_t', 'pthread_mutex_t', + '__int64_t', 'ASN1_BMPSTRING', 'uint32_t', + 'PEM_ENCODE_SEAL_CTX', 'suseconds_t', 'ASN1_OBJECT', + 'X509_val_st', 'private_key_st', 'CRYPTO_dynlock', + 'X509_objects_st', 'CRYPTO_EX_DATA_IMPL', + 'pthread_condattr_t', 'PKCS7_DIGEST', 'uint_least32_t', + 'ASN1_STRING', '__uint32_t', 'P_PGID', 'rsa_meth_st', + 'X509_crl_st', 'RC2_KEY', '__darwin_fsfilcnt_t', + 'X509_revoked_st', 'PBE2PARAM', 'blksize_t', + 'Netscape_certificate_sequence', 'ssl_cipher_st', + 'bignum_ctx', 'register_t', 'ASN1_UTF8STRING', + 'pkcs7_encrypted_st', 'RC4_KEY', '__darwin_ucontext64_t', + 'N13ssl2_state_st4DOLLAR_19E', 'bn_recp_ctx_st', + 'CAST_KEY', 'X509_ATTRIBUTE', '__darwin_suseconds_t', + '__sigaction', 'user_ulong_t', 'syscall_arg_t', + 'evp_cipher_ctx_st', 'X509_ALGOR', 'mcontext_t', + 'const_DES_cblock', '__darwin_fsblkcnt_t', 'dsa_st', + 'int_least8_t', 'MD2state_st', 'X509_EXTENSION', + 'GEN_SESSION_CB', 'int_least16_t', '__darwin_wctrans_t', + 'PBKDF2PARAM', 'x509_lookup_method_st', 'pem_password_cb', + 'X509_info_st', 'x509_store_st', '__darwin_natural_t', + 'X509_pubkey_st', 'pkcs7_digest_st', '__darwin_size_t', + 'ASN1_STRING_TABLE', 'OSLittleEndian', 'RIPEMD160state_st', + 'pkcs7_enveloped_st', 'UI', 'ptrdiff_t', 'X509_REQ', + 'CRYPTO_dynlock_value', 'X509_req_st', 'x509_store_ctx_st', + 'N13ssl3_state_st4DOLLAR_20E', 'lhash_node_st', + '__darwin_pthread_mutex_t', 'LHASH_COMP_FN_TYPE', + '__darwin_rune_t', 'rlimit', '__darwin_pthread_once_t', + 'OSBigEndian', 'uintptr_t', '__darwin_uid_t', 'u_int', + 'ASN1_T61STRING', 'gid_t', 'ssl_method_st', 'ASN1_ITEM', + 'ASN1_ENUMERATED', '_opaque_pthread_rwlock_t', + 'pkcs8_priv_key_info_st', 'intmax_t', 'sigcontext', + 'X509_CRL', 'rc2_key_st', 'engine_st', 'x509_object_st', + '_opaque_pthread_once_t', 'DES_ks', 'SSL_COMP', + 'dsa_method', 'int64_t', 'bio_st', 'bf_key_st', + 'ASN1_GENERALIZEDTIME', 'PKCS7_ENC_CONTENT', + '__darwin_pid_t', 'lldiv_t', 'comp_method_st', + 'EVP_MD_CTX', 'evp_cipher_st', 'X509_name_st', + 'x509_hash_dir_st', '__darwin_mach_port_name_t', + 'useconds_t', 'user_size_t', 'SSL_SESSION', 'rusage', + 'ssl_crock_st', 'int_least32_t', '__sigaction_u', 'dh_st', + 'P_ALL', '__darwin_stack_t', 'N6DES_ks3DOLLAR_9E', + 'comp_ctx_st', 'X509_CERT_FILE_CTX'] Added: sandbox/trunk/refactor_pkg/refactor/tests/data/py2_test_grammar.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/tests/data/py2_test_grammar.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,956 @@ +# Python 2's Lib/test/test_grammar.py (r66189) + +# Python test set -- part 1, grammar. +# This just tests whether the parser accepts them all. + +# NOTE: When you run this test as a script from the command line, you +# get warnings about certain hex/oct constants. Since those are +# issued by the parser, you can't suppress them by adding a +# filterwarnings() call to this module. Therefore, to shut up the +# regression test, the filterwarnings() call has been added to +# regrtest.py. + +from test.test_support import run_unittest, check_syntax_error +import unittest +import sys +# testing import * +from sys import * + +class TokenTests(unittest.TestCase): + + def testBackslash(self): + # Backslash means line continuation: + x = 1 \ + + 1 + self.assertEquals(x, 2, 'backslash for line continuation') + + # Backslash does not means continuation in comments :\ + x = 0 + self.assertEquals(x, 0, 'backslash ending comment') + + def testPlainIntegers(self): + self.assertEquals(0xff, 255) + self.assertEquals(0377, 255) + self.assertEquals(2147483647, 017777777777) + # "0x" is not a valid literal + self.assertRaises(SyntaxError, eval, "0x") + from sys import maxint + if maxint == 2147483647: + self.assertEquals(-2147483647-1, -020000000000) + # XXX -2147483648 + self.assert_(037777777777 > 0) + self.assert_(0xffffffff > 0) + for s in '2147483648', '040000000000', '0x100000000': + try: + x = eval(s) + except OverflowError: + self.fail("OverflowError on huge integer literal %r" % s) + elif maxint == 9223372036854775807: + self.assertEquals(-9223372036854775807-1, -01000000000000000000000) + self.assert_(01777777777777777777777 > 0) + self.assert_(0xffffffffffffffff > 0) + for s in '9223372036854775808', '02000000000000000000000', \ + '0x10000000000000000': + try: + x = eval(s) + except OverflowError: + self.fail("OverflowError on huge integer literal %r" % s) + else: + self.fail('Weird maxint value %r' % maxint) + + def testLongIntegers(self): + x = 0L + x = 0l + x = 0xffffffffffffffffL + x = 0xffffffffffffffffl + x = 077777777777777777L + x = 077777777777777777l + x = 123456789012345678901234567890L + x = 123456789012345678901234567890l + + def testFloats(self): + x = 3.14 + x = 314. + x = 0.314 + # XXX x = 000.314 + x = .314 + x = 3e14 + x = 3E14 + x = 3e-14 + x = 3e+14 + x = 3.e14 + x = .3e14 + x = 3.1e4 + + def testStringLiterals(self): + x = ''; y = ""; self.assert_(len(x) == 0 and x == y) + x = '\''; y = "'"; self.assert_(len(x) == 1 and x == y and ord(x) == 39) + x = '"'; y = "\""; self.assert_(len(x) == 1 and x == y and ord(x) == 34) + x = "doesn't \"shrink\" does it" + y = 'doesn\'t "shrink" does it' + self.assert_(len(x) == 24 and x == y) + x = "does \"shrink\" doesn't it" + y = 'does "shrink" doesn\'t it' + self.assert_(len(x) == 24 and x == y) + x = """ +The "quick" +brown fox +jumps over +the 'lazy' dog. +""" + y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n' + self.assertEquals(x, y) + y = ''' +The "quick" +brown fox +jumps over +the 'lazy' dog. +''' + self.assertEquals(x, y) + y = "\n\ +The \"quick\"\n\ +brown fox\n\ +jumps over\n\ +the 'lazy' dog.\n\ +" + self.assertEquals(x, y) + y = '\n\ +The \"quick\"\n\ +brown fox\n\ +jumps over\n\ +the \'lazy\' dog.\n\ +' + self.assertEquals(x, y) + + +class GrammarTests(unittest.TestCase): + + # single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE + # XXX can't test in a script -- this rule is only used when interactive + + # file_input: (NEWLINE | stmt)* ENDMARKER + # Being tested as this very moment this very module + + # expr_input: testlist NEWLINE + # XXX Hard to test -- used only in calls to input() + + def testEvalInput(self): + # testlist ENDMARKER + x = eval('1, 0 or 1') + + def testFuncdef(self): + ### 'def' NAME parameters ':' suite + ### parameters: '(' [varargslist] ')' + ### varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' ('**'|'*' '*') NAME] + ### | ('**'|'*' '*') NAME) + ### | fpdef ['=' test] (',' fpdef ['=' test])* [','] + ### fpdef: NAME | '(' fplist ')' + ### fplist: fpdef (',' fpdef)* [','] + ### arglist: (argument ',')* (argument | *' test [',' '**' test] | '**' test) + ### argument: [test '='] test # Really [keyword '='] test + def f1(): pass + f1() + f1(*()) + f1(*(), **{}) + def f2(one_argument): pass + def f3(two, arguments): pass + def f4(two, (compound, (argument, list))): pass + def f5((compound, first), two): pass + self.assertEquals(f2.func_code.co_varnames, ('one_argument',)) + self.assertEquals(f3.func_code.co_varnames, ('two', 'arguments')) + if sys.platform.startswith('java'): + self.assertEquals(f4.func_code.co_varnames, + ('two', '(compound, (argument, list))', 'compound', 'argument', + 'list',)) + self.assertEquals(f5.func_code.co_varnames, + ('(compound, first)', 'two', 'compound', 'first')) + else: + self.assertEquals(f4.func_code.co_varnames, + ('two', '.1', 'compound', 'argument', 'list')) + self.assertEquals(f5.func_code.co_varnames, + ('.0', 'two', 'compound', 'first')) + def a1(one_arg,): pass + def a2(two, args,): pass + def v0(*rest): pass + def v1(a, *rest): pass + def v2(a, b, *rest): pass + def v3(a, (b, c), *rest): return a, b, c, rest + + f1() + f2(1) + f2(1,) + f3(1, 2) + f3(1, 2,) + f4(1, (2, (3, 4))) + v0() + v0(1) + v0(1,) + v0(1,2) + v0(1,2,3,4,5,6,7,8,9,0) + v1(1) + v1(1,) + v1(1,2) + v1(1,2,3) + v1(1,2,3,4,5,6,7,8,9,0) + v2(1,2) + v2(1,2,3) + v2(1,2,3,4) + v2(1,2,3,4,5,6,7,8,9,0) + v3(1,(2,3)) + v3(1,(2,3),4) + v3(1,(2,3),4,5,6,7,8,9,0) + + # ceval unpacks the formal arguments into the first argcount names; + # thus, the names nested inside tuples must appear after these names. + if sys.platform.startswith('java'): + self.assertEquals(v3.func_code.co_varnames, ('a', '(b, c)', 'rest', 'b', 'c')) + else: + self.assertEquals(v3.func_code.co_varnames, ('a', '.1', 'rest', 'b', 'c')) + self.assertEquals(v3(1, (2, 3), 4), (1, 2, 3, (4,))) + def d01(a=1): pass + d01() + d01(1) + d01(*(1,)) + d01(**{'a':2}) + def d11(a, b=1): pass + d11(1) + d11(1, 2) + d11(1, **{'b':2}) + def d21(a, b, c=1): pass + d21(1, 2) + d21(1, 2, 3) + d21(*(1, 2, 3)) + d21(1, *(2, 3)) + d21(1, 2, *(3,)) + d21(1, 2, **{'c':3}) + def d02(a=1, b=2): pass + d02() + d02(1) + d02(1, 2) + d02(*(1, 2)) + d02(1, *(2,)) + d02(1, **{'b':2}) + d02(**{'a': 1, 'b': 2}) + def d12(a, b=1, c=2): pass + d12(1) + d12(1, 2) + d12(1, 2, 3) + def d22(a, b, c=1, d=2): pass + d22(1, 2) + d22(1, 2, 3) + d22(1, 2, 3, 4) + def d01v(a=1, *rest): pass + d01v() + d01v(1) + d01v(1, 2) + d01v(*(1, 2, 3, 4)) + d01v(*(1,)) + d01v(**{'a':2}) + def d11v(a, b=1, *rest): pass + d11v(1) + d11v(1, 2) + d11v(1, 2, 3) + def d21v(a, b, c=1, *rest): pass + d21v(1, 2) + d21v(1, 2, 3) + d21v(1, 2, 3, 4) + d21v(*(1, 2, 3, 4)) + d21v(1, 2, **{'c': 3}) + def d02v(a=1, b=2, *rest): pass + d02v() + d02v(1) + d02v(1, 2) + d02v(1, 2, 3) + d02v(1, *(2, 3, 4)) + d02v(**{'a': 1, 'b': 2}) + def d12v(a, b=1, c=2, *rest): pass + d12v(1) + d12v(1, 2) + d12v(1, 2, 3) + d12v(1, 2, 3, 4) + d12v(*(1, 2, 3, 4)) + d12v(1, 2, *(3, 4, 5)) + d12v(1, *(2,), **{'c': 3}) + def d22v(a, b, c=1, d=2, *rest): pass + d22v(1, 2) + d22v(1, 2, 3) + d22v(1, 2, 3, 4) + d22v(1, 2, 3, 4, 5) + d22v(*(1, 2, 3, 4)) + d22v(1, 2, *(3, 4, 5)) + d22v(1, *(2, 3), **{'d': 4}) + def d31v((x)): pass + d31v(1) + def d32v((x,)): pass + d32v((1,)) + + # keyword arguments after *arglist + def f(*args, **kwargs): + return args, kwargs + self.assertEquals(f(1, x=2, *[3, 4], y=5), ((1, 3, 4), + {'x':2, 'y':5})) + self.assertRaises(SyntaxError, eval, "f(1, *(2,3), 4)") + self.assertRaises(SyntaxError, eval, "f(1, x=2, *(3,4), x=5)") + + # Check ast errors in *args and *kwargs + check_syntax_error(self, "f(*g(1=2))") + check_syntax_error(self, "f(**g(1=2))") + + def testLambdef(self): + ### lambdef: 'lambda' [varargslist] ':' test + l1 = lambda : 0 + self.assertEquals(l1(), 0) + l2 = lambda : a[d] # XXX just testing the expression + l3 = lambda : [2 < x for x in [-1, 3, 0L]] + self.assertEquals(l3(), [0, 1, 0]) + l4 = lambda x = lambda y = lambda z=1 : z : y() : x() + self.assertEquals(l4(), 1) + l5 = lambda x, y, z=2: x + y + z + self.assertEquals(l5(1, 2), 5) + self.assertEquals(l5(1, 2, 3), 6) + check_syntax_error(self, "lambda x: x = 2") + check_syntax_error(self, "lambda (None,): None") + + ### stmt: simple_stmt | compound_stmt + # Tested below + + def testSimpleStmt(self): + ### simple_stmt: small_stmt (';' small_stmt)* [';'] + x = 1; pass; del x + def foo(): + # verify statments that end with semi-colons + x = 1; pass; del x; + foo() + + ### small_stmt: expr_stmt | print_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt | exec_stmt + # Tested below + + def testExprStmt(self): + # (exprlist '=')* exprlist + 1 + 1, 2, 3 + x = 1 + x = 1, 2, 3 + x = y = z = 1, 2, 3 + x, y, z = 1, 2, 3 + abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4) + + check_syntax_error(self, "x + 1 = 1") + check_syntax_error(self, "a + 1 = b + 2") + + def testPrintStmt(self): + # 'print' (test ',')* [test] + import StringIO + + # Can't test printing to real stdout without comparing output + # which is not available in unittest. + save_stdout = sys.stdout + sys.stdout = StringIO.StringIO() + + print 1, 2, 3 + print 1, 2, 3, + print + print 0 or 1, 0 or 1, + print 0 or 1 + + # 'print' '>>' test ',' + print >> sys.stdout, 1, 2, 3 + print >> sys.stdout, 1, 2, 3, + print >> sys.stdout + print >> sys.stdout, 0 or 1, 0 or 1, + print >> sys.stdout, 0 or 1 + + # test printing to an instance + class Gulp: + def write(self, msg): pass + + gulp = Gulp() + print >> gulp, 1, 2, 3 + print >> gulp, 1, 2, 3, + print >> gulp + print >> gulp, 0 or 1, 0 or 1, + print >> gulp, 0 or 1 + + # test print >> None + def driver(): + oldstdout = sys.stdout + sys.stdout = Gulp() + try: + tellme(Gulp()) + tellme() + finally: + sys.stdout = oldstdout + + # we should see this once + def tellme(file=sys.stdout): + print >> file, 'hello world' + + driver() + + # we should not see this at all + def tellme(file=None): + print >> file, 'goodbye universe' + + driver() + + self.assertEqual(sys.stdout.getvalue(), '''\ +1 2 3 +1 2 3 +1 1 1 +1 2 3 +1 2 3 +1 1 1 +hello world +''') + sys.stdout = save_stdout + + # syntax errors + check_syntax_error(self, 'print ,') + check_syntax_error(self, 'print >> x,') + + def testDelStmt(self): + # 'del' exprlist + abc = [1,2,3] + x, y, z = abc + xyz = x, y, z + + del abc + del x, y, (z, xyz) + + def testPassStmt(self): + # 'pass' + pass + + # flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt + # Tested below + + def testBreakStmt(self): + # 'break' + while 1: break + + def testContinueStmt(self): + # 'continue' + i = 1 + while i: i = 0; continue + + msg = "" + while not msg: + msg = "ok" + try: + continue + msg = "continue failed to continue inside try" + except: + msg = "continue inside try called except block" + if msg != "ok": + self.fail(msg) + + msg = "" + while not msg: + msg = "finally block not called" + try: + continue + finally: + msg = "ok" + if msg != "ok": + self.fail(msg) + + def test_break_continue_loop(self): + # This test warrants an explanation. It is a test specifically for SF bugs + # #463359 and #462937. The bug is that a 'break' statement executed or + # exception raised inside a try/except inside a loop, *after* a continue + # statement has been executed in that loop, will cause the wrong number of + # arguments to be popped off the stack and the instruction pointer reset to + # a very small number (usually 0.) Because of this, the following test + # *must* written as a function, and the tracking vars *must* be function + # arguments with default values. Otherwise, the test will loop and loop. + + def test_inner(extra_burning_oil = 1, count=0): + big_hippo = 2 + while big_hippo: + count += 1 + try: + if extra_burning_oil and big_hippo == 1: + extra_burning_oil -= 1 + break + big_hippo -= 1 + continue + except: + raise + if count > 2 or big_hippo <> 1: + self.fail("continue then break in try/except in loop broken!") + test_inner() + + def testReturn(self): + # 'return' [testlist] + def g1(): return + def g2(): return 1 + g1() + x = g2() + check_syntax_error(self, "class foo:return 1") + + def testYield(self): + check_syntax_error(self, "class foo:yield 1") + + def testRaise(self): + # 'raise' test [',' test] + try: raise RuntimeError, 'just testing' + except RuntimeError: pass + try: raise KeyboardInterrupt + except KeyboardInterrupt: pass + + def testImport(self): + # 'import' dotted_as_names + import sys + import time, sys + # 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names) + from time import time + from time import (time) + # not testable inside a function, but already done at top of the module + # from sys import * + from sys import path, argv + from sys import (path, argv) + from sys import (path, argv,) + + def testGlobal(self): + # 'global' NAME (',' NAME)* + global a + global a, b + global one, two, three, four, five, six, seven, eight, nine, ten + + def testExec(self): + # 'exec' expr ['in' expr [',' expr]] + z = None + del z + exec 'z=1+1\n' + if z != 2: self.fail('exec \'z=1+1\'\\n') + del z + exec 'z=1+1' + if z != 2: self.fail('exec \'z=1+1\'') + z = None + del z + import types + if hasattr(types, "UnicodeType"): + exec r"""if 1: + exec u'z=1+1\n' + if z != 2: self.fail('exec u\'z=1+1\'\\n') + del z + exec u'z=1+1' + if z != 2: self.fail('exec u\'z=1+1\'')""" + g = {} + exec 'z = 1' in g + if g.has_key('__builtins__'): del g['__builtins__'] + if g != {'z': 1}: self.fail('exec \'z = 1\' in g') + g = {} + l = {} + + import warnings + warnings.filterwarnings("ignore", "global statement", module="") + exec 'global a; a = 1; b = 2' in g, l + if g.has_key('__builtins__'): del g['__builtins__'] + if l.has_key('__builtins__'): del l['__builtins__'] + if (g, l) != ({'a':1}, {'b':2}): + self.fail('exec ... in g (%s), l (%s)' %(g,l)) + + def testAssert(self): + # assert_stmt: 'assert' test [',' test] + assert 1 + assert 1, 1 + assert lambda x:x + assert 1, lambda x:x+1 + try: + assert 0, "msg" + except AssertionError, e: + self.assertEquals(e.args[0], "msg") + else: + if __debug__: + self.fail("AssertionError not raised by assert 0") + + ### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef + # Tested below + + def testIf(self): + # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] + if 1: pass + if 1: pass + else: pass + if 0: pass + elif 0: pass + if 0: pass + elif 0: pass + elif 0: pass + elif 0: pass + else: pass + + def testWhile(self): + # 'while' test ':' suite ['else' ':' suite] + while 0: pass + while 0: pass + else: pass + + # Issue1920: "while 0" is optimized away, + # ensure that the "else" clause is still present. + x = 0 + while 0: + x = 1 + else: + x = 2 + self.assertEquals(x, 2) + + def testFor(self): + # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] + for i in 1, 2, 3: pass + for i, j, k in (): pass + else: pass + class Squares: + def __init__(self, max): + self.max = max + self.sofar = [] + def __len__(self): return len(self.sofar) + def __getitem__(self, i): + if not 0 <= i < self.max: raise IndexError + n = len(self.sofar) + while n <= i: + self.sofar.append(n*n) + n = n+1 + return self.sofar[i] + n = 0 + for x in Squares(10): n = n+x + if n != 285: + self.fail('for over growing sequence') + + result = [] + for x, in [(1,), (2,), (3,)]: + result.append(x) + self.assertEqual(result, [1, 2, 3]) + + def testTry(self): + ### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] + ### | 'try' ':' suite 'finally' ':' suite + ### except_clause: 'except' [expr [('as' | ',') expr]] + try: + 1/0 + except ZeroDivisionError: + pass + else: + pass + try: 1/0 + except EOFError: pass + except TypeError as msg: pass + except RuntimeError, msg: pass + except: pass + else: pass + try: 1/0 + except (EOFError, TypeError, ZeroDivisionError): pass + try: 1/0 + except (EOFError, TypeError, ZeroDivisionError), msg: pass + try: pass + finally: pass + + def testSuite(self): + # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT + if 1: pass + if 1: + pass + if 1: + # + # + # + pass + pass + # + pass + # + + def testTest(self): + ### and_test ('or' and_test)* + ### and_test: not_test ('and' not_test)* + ### not_test: 'not' not_test | comparison + if not 1: pass + if 1 and 1: pass + if 1 or 1: pass + if not not not 1: pass + if not 1 and 1 and 1: pass + if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass + + def testComparison(self): + ### comparison: expr (comp_op expr)* + ### comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' + if 1: pass + x = (1 == 1) + if 1 == 1: pass + if 1 != 1: pass + if 1 <> 1: pass + if 1 < 1: pass + if 1 > 1: pass + if 1 <= 1: pass + if 1 >= 1: pass + if 1 is 1: pass + if 1 is not 1: pass + if 1 in (): pass + if 1 not in (): pass + if 1 < 1 > 1 == 1 >= 1 <= 1 <> 1 != 1 in 1 not in 1 is 1 is not 1: pass + + def testBinaryMaskOps(self): + x = 1 & 1 + x = 1 ^ 1 + x = 1 | 1 + + def testShiftOps(self): + x = 1 << 1 + x = 1 >> 1 + x = 1 << 1 >> 1 + + def testAdditiveOps(self): + x = 1 + x = 1 + 1 + x = 1 - 1 - 1 + x = 1 - 1 + 1 - 1 + 1 + + def testMultiplicativeOps(self): + x = 1 * 1 + x = 1 / 1 + x = 1 % 1 + x = 1 / 1 * 1 % 1 + + def testUnaryOps(self): + x = +1 + x = -1 + x = ~1 + x = ~1 ^ 1 & 1 | 1 & 1 ^ -1 + x = -1*1/1 + 1*1 - ---1*1 + + def testSelectors(self): + ### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME + ### subscript: expr | [expr] ':' [expr] + + import sys, time + c = sys.path[0] + x = time.time() + x = sys.modules['time'].time() + a = '01234' + c = a[0] + c = a[-1] + s = a[0:5] + s = a[:5] + s = a[0:] + s = a[:] + s = a[-5:] + s = a[:-1] + s = a[-4:-3] + # A rough test of SF bug 1333982. http://python.org/sf/1333982 + # The testing here is fairly incomplete. + # Test cases should include: commas with 1 and 2 colons + d = {} + d[1] = 1 + d[1,] = 2 + d[1,2] = 3 + d[1,2,3] = 4 + L = list(d) + L.sort() + self.assertEquals(str(L), '[1, (1,), (1, 2), (1, 2, 3)]') + + def testAtoms(self): + ### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING + ### dictmaker: test ':' test (',' test ':' test)* [','] + + x = (1) + x = (1 or 2 or 3) + x = (1 or 2 or 3, 2, 3) + + x = [] + x = [1] + x = [1 or 2 or 3] + x = [1 or 2 or 3, 2, 3] + x = [] + + x = {} + x = {'one': 1} + x = {'one': 1,} + x = {'one' or 'two': 1 or 2} + x = {'one': 1, 'two': 2} + x = {'one': 1, 'two': 2,} + x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6} + + x = `x` + x = `1 or 2 or 3` + self.assertEqual(`1,2`, '(1, 2)') + + x = x + x = 'x' + x = 123 + + ### exprlist: expr (',' expr)* [','] + ### testlist: test (',' test)* [','] + # These have been exercised enough above + + def testClassdef(self): + # 'class' NAME ['(' [testlist] ')'] ':' suite + class B: pass + class B2(): pass + class C1(B): pass + class C2(B): pass + class D(C1, C2, B): pass + class C: + def meth1(self): pass + def meth2(self, arg): pass + def meth3(self, a1, a2): pass + # decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE + # decorators: decorator+ + # decorated: decorators (classdef | funcdef) + def class_decorator(x): + x.decorated = True + return x + @class_decorator + class G: + pass + self.assertEqual(G.decorated, True) + + def testListcomps(self): + # list comprehension tests + nums = [1, 2, 3, 4, 5] + strs = ["Apple", "Banana", "Coconut"] + spcs = [" Apple", " Banana ", "Coco nut "] + + self.assertEqual([s.strip() for s in spcs], ['Apple', 'Banana', 'Coco nut']) + self.assertEqual([3 * x for x in nums], [3, 6, 9, 12, 15]) + self.assertEqual([x for x in nums if x > 2], [3, 4, 5]) + self.assertEqual([(i, s) for i in nums for s in strs], + [(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'), + (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'), + (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'), + (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'), + (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')]) + self.assertEqual([(i, s) for i in nums for s in [f for f in strs if "n" in f]], + [(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'), + (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'), + (5, 'Banana'), (5, 'Coconut')]) + self.assertEqual([(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)], + [[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]]) + + def test_in_func(l): + return [None < x < 3 for x in l if x > 2] + + self.assertEqual(test_in_func(nums), [False, False, False]) + + def test_nested_front(): + self.assertEqual([[y for y in [x, x + 1]] for x in [1,3,5]], + [[1, 2], [3, 4], [5, 6]]) + + test_nested_front() + + check_syntax_error(self, "[i, s for i in nums for s in strs]") + check_syntax_error(self, "[x if y]") + + suppliers = [ + (1, "Boeing"), + (2, "Ford"), + (3, "Macdonalds") + ] + + parts = [ + (10, "Airliner"), + (20, "Engine"), + (30, "Cheeseburger") + ] + + suppart = [ + (1, 10), (1, 20), (2, 20), (3, 30) + ] + + x = [ + (sname, pname) + for (sno, sname) in suppliers + for (pno, pname) in parts + for (sp_sno, sp_pno) in suppart + if sno == sp_sno and pno == sp_pno + ] + + self.assertEqual(x, [('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), + ('Macdonalds', 'Cheeseburger')]) + + def testGenexps(self): + # generator expression tests + g = ([x for x in range(10)] for x in range(1)) + self.assertEqual(g.next(), [x for x in range(10)]) + try: + g.next() + self.fail('should produce StopIteration exception') + except StopIteration: + pass + + a = 1 + try: + g = (a for d in a) + g.next() + self.fail('should produce TypeError') + except TypeError: + pass + + self.assertEqual(list((x, y) for x in 'abcd' for y in 'abcd'), [(x, y) for x in 'abcd' for y in 'abcd']) + self.assertEqual(list((x, y) for x in 'ab' for y in 'xy'), [(x, y) for x in 'ab' for y in 'xy']) + + a = [x for x in range(10)] + b = (x for x in (y for y in a)) + self.assertEqual(sum(b), sum([x for x in range(10)])) + + self.assertEqual(sum(x**2 for x in range(10)), sum([x**2 for x in range(10)])) + self.assertEqual(sum(x*x for x in range(10) if x%2), sum([x*x for x in range(10) if x%2])) + self.assertEqual(sum(x for x in (y for y in range(10))), sum([x for x in range(10)])) + self.assertEqual(sum(x for x in (y for y in (z for z in range(10)))), sum([x for x in range(10)])) + self.assertEqual(sum(x for x in [y for y in (z for z in range(10))]), sum([x for x in range(10)])) + self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True)) if True), sum([x for x in range(10)])) + self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True) if False) if True), 0) + check_syntax_error(self, "foo(x for x in range(10), 100)") + check_syntax_error(self, "foo(100, x for x in range(10))") + + def testComprehensionSpecials(self): + # test for outmost iterable precomputation + x = 10; g = (i for i in range(x)); x = 5 + self.assertEqual(len(list(g)), 10) + + # This should hold, since we're only precomputing outmost iterable. + x = 10; t = False; g = ((i,j) for i in range(x) if t for j in range(x)) + x = 5; t = True; + self.assertEqual([(i,j) for i in range(10) for j in range(5)], list(g)) + + # Grammar allows multiple adjacent 'if's in listcomps and genexps, + # even though it's silly. Make sure it works (ifelse broke this.) + self.assertEqual([ x for x in range(10) if x % 2 if x % 3 ], [1, 5, 7]) + self.assertEqual(list(x for x in range(10) if x % 2 if x % 3), [1, 5, 7]) + + # verify unpacking single element tuples in listcomp/genexp. + self.assertEqual([x for x, in [(4,), (5,), (6,)]], [4, 5, 6]) + self.assertEqual(list(x for x, in [(7,), (8,), (9,)]), [7, 8, 9]) + + def testIfElseExpr(self): + # Test ifelse expressions in various cases + def _checkeval(msg, ret): + "helper to check that evaluation of expressions is done correctly" + print x + return ret + + self.assertEqual([ x() for x in lambda: True, lambda: False if x() ], [True]) + self.assertEqual([ x() for x in (lambda: True, lambda: False) if x() ], [True]) + self.assertEqual([ x(False) for x in (lambda x: False if x else True, lambda x: True if x else False) if x(False) ], [True]) + self.assertEqual((5 if 1 else _checkeval("check 1", 0)), 5) + self.assertEqual((_checkeval("check 2", 0) if 0 else 5), 5) + self.assertEqual((5 and 6 if 0 else 1), 1) + self.assertEqual(((5 and 6) if 0 else 1), 1) + self.assertEqual((5 and (6 if 1 else 1)), 6) + self.assertEqual((0 or _checkeval("check 3", 2) if 0 else 3), 3) + self.assertEqual((1 or _checkeval("check 4", 2) if 1 else _checkeval("check 5", 3)), 1) + self.assertEqual((0 or 5 if 1 else _checkeval("check 6", 3)), 5) + self.assertEqual((not 5 if 1 else 1), False) + self.assertEqual((not 5 if 0 else 1), 1) + self.assertEqual((6 + 1 if 1 else 2), 7) + self.assertEqual((6 - 1 if 1 else 2), 5) + self.assertEqual((6 * 2 if 1 else 4), 12) + self.assertEqual((6 / 2 if 1 else 3), 3) + self.assertEqual((6 < 4 if 0 else 2), 2) + + +def test_main(): + run_unittest(TokenTests, GrammarTests) + +if __name__ == '__main__': + test_main() Added: sandbox/trunk/refactor_pkg/refactor/tests/data/py3_test_grammar.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/tests/data/py3_test_grammar.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,903 @@ +# Python test set -- part 1, grammar. +# This just tests whether the parser accepts them all. + +# NOTE: When you run this test as a script from the command line, you +# get warnings about certain hex/oct constants. Since those are +# issued by the parser, you can't suppress them by adding a +# filterwarnings() call to this module. Therefore, to shut up the +# regression test, the filterwarnings() call has been added to +# regrtest.py. + +from test.support import run_unittest, check_syntax_error +import unittest +import sys +# testing import * +from sys import * + +class TokenTests(unittest.TestCase): + + def testBackslash(self): + # Backslash means line continuation: + x = 1 \ + + 1 + self.assertEquals(x, 2, 'backslash for line continuation') + + # Backslash does not means continuation in comments :\ + x = 0 + self.assertEquals(x, 0, 'backslash ending comment') + + def testPlainIntegers(self): + self.assertEquals(type(000), type(0)) + self.assertEquals(0xff, 255) + self.assertEquals(0o377, 255) + self.assertEquals(2147483647, 0o17777777777) + self.assertEquals(0b1001, 9) + # "0x" is not a valid literal + self.assertRaises(SyntaxError, eval, "0x") + from sys import maxsize + if maxsize == 2147483647: + self.assertEquals(-2147483647-1, -0o20000000000) + # XXX -2147483648 + self.assert_(0o37777777777 > 0) + self.assert_(0xffffffff > 0) + self.assert_(0b1111111111111111111111111111111 > 0) + for s in ('2147483648', '0o40000000000', '0x100000000', + '0b10000000000000000000000000000000'): + try: + x = eval(s) + except OverflowError: + self.fail("OverflowError on huge integer literal %r" % s) + elif maxsize == 9223372036854775807: + self.assertEquals(-9223372036854775807-1, -0o1000000000000000000000) + self.assert_(0o1777777777777777777777 > 0) + self.assert_(0xffffffffffffffff > 0) + self.assert_(0b11111111111111111111111111111111111111111111111111111111111111 > 0) + for s in '9223372036854775808', '0o2000000000000000000000', \ + '0x10000000000000000', \ + '0b100000000000000000000000000000000000000000000000000000000000000': + try: + x = eval(s) + except OverflowError: + self.fail("OverflowError on huge integer literal %r" % s) + else: + self.fail('Weird maxsize value %r' % maxsize) + + def testLongIntegers(self): + x = 0 + x = 0xffffffffffffffff + x = 0Xffffffffffffffff + x = 0o77777777777777777 + x = 0O77777777777777777 + x = 123456789012345678901234567890 + x = 0b100000000000000000000000000000000000000000000000000000000000000000000 + x = 0B111111111111111111111111111111111111111111111111111111111111111111111 + + def testFloats(self): + x = 3.14 + x = 314. + x = 0.314 + # XXX x = 000.314 + x = .314 + x = 3e14 + x = 3E14 + x = 3e-14 + x = 3e+14 + x = 3.e14 + x = .3e14 + x = 3.1e4 + + def testStringLiterals(self): + x = ''; y = ""; self.assert_(len(x) == 0 and x == y) + x = '\''; y = "'"; self.assert_(len(x) == 1 and x == y and ord(x) == 39) + x = '"'; y = "\""; self.assert_(len(x) == 1 and x == y and ord(x) == 34) + x = "doesn't \"shrink\" does it" + y = 'doesn\'t "shrink" does it' + self.assert_(len(x) == 24 and x == y) + x = "does \"shrink\" doesn't it" + y = 'does "shrink" doesn\'t it' + self.assert_(len(x) == 24 and x == y) + x = """ +The "quick" +brown fox +jumps over +the 'lazy' dog. +""" + y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n' + self.assertEquals(x, y) + y = ''' +The "quick" +brown fox +jumps over +the 'lazy' dog. +''' + self.assertEquals(x, y) + y = "\n\ +The \"quick\"\n\ +brown fox\n\ +jumps over\n\ +the 'lazy' dog.\n\ +" + self.assertEquals(x, y) + y = '\n\ +The \"quick\"\n\ +brown fox\n\ +jumps over\n\ +the \'lazy\' dog.\n\ +' + self.assertEquals(x, y) + + def testEllipsis(self): + x = ... + self.assert_(x is Ellipsis) + self.assertRaises(SyntaxError, eval, ".. .") + +class GrammarTests(unittest.TestCase): + + # single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE + # XXX can't test in a script -- this rule is only used when interactive + + # file_input: (NEWLINE | stmt)* ENDMARKER + # Being tested as this very moment this very module + + # expr_input: testlist NEWLINE + # XXX Hard to test -- used only in calls to input() + + def testEvalInput(self): + # testlist ENDMARKER + x = eval('1, 0 or 1') + + def testFuncdef(self): + ### [decorators] 'def' NAME parameters ['->' test] ':' suite + ### decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE + ### decorators: decorator+ + ### parameters: '(' [typedargslist] ')' + ### typedargslist: ((tfpdef ['=' test] ',')* + ### ('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef) + ### | tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) + ### tfpdef: NAME [':' test] + ### varargslist: ((vfpdef ['=' test] ',')* + ### ('*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef) + ### | vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) + ### vfpdef: NAME + def f1(): pass + f1() + f1(*()) + f1(*(), **{}) + def f2(one_argument): pass + def f3(two, arguments): pass + self.assertEquals(f2.__code__.co_varnames, ('one_argument',)) + self.assertEquals(f3.__code__.co_varnames, ('two', 'arguments')) + def a1(one_arg,): pass + def a2(two, args,): pass + def v0(*rest): pass + def v1(a, *rest): pass + def v2(a, b, *rest): pass + + f1() + f2(1) + f2(1,) + f3(1, 2) + f3(1, 2,) + v0() + v0(1) + v0(1,) + v0(1,2) + v0(1,2,3,4,5,6,7,8,9,0) + v1(1) + v1(1,) + v1(1,2) + v1(1,2,3) + v1(1,2,3,4,5,6,7,8,9,0) + v2(1,2) + v2(1,2,3) + v2(1,2,3,4) + v2(1,2,3,4,5,6,7,8,9,0) + + def d01(a=1): pass + d01() + d01(1) + d01(*(1,)) + d01(**{'a':2}) + def d11(a, b=1): pass + d11(1) + d11(1, 2) + d11(1, **{'b':2}) + def d21(a, b, c=1): pass + d21(1, 2) + d21(1, 2, 3) + d21(*(1, 2, 3)) + d21(1, *(2, 3)) + d21(1, 2, *(3,)) + d21(1, 2, **{'c':3}) + def d02(a=1, b=2): pass + d02() + d02(1) + d02(1, 2) + d02(*(1, 2)) + d02(1, *(2,)) + d02(1, **{'b':2}) + d02(**{'a': 1, 'b': 2}) + def d12(a, b=1, c=2): pass + d12(1) + d12(1, 2) + d12(1, 2, 3) + def d22(a, b, c=1, d=2): pass + d22(1, 2) + d22(1, 2, 3) + d22(1, 2, 3, 4) + def d01v(a=1, *rest): pass + d01v() + d01v(1) + d01v(1, 2) + d01v(*(1, 2, 3, 4)) + d01v(*(1,)) + d01v(**{'a':2}) + def d11v(a, b=1, *rest): pass + d11v(1) + d11v(1, 2) + d11v(1, 2, 3) + def d21v(a, b, c=1, *rest): pass + d21v(1, 2) + d21v(1, 2, 3) + d21v(1, 2, 3, 4) + d21v(*(1, 2, 3, 4)) + d21v(1, 2, **{'c': 3}) + def d02v(a=1, b=2, *rest): pass + d02v() + d02v(1) + d02v(1, 2) + d02v(1, 2, 3) + d02v(1, *(2, 3, 4)) + d02v(**{'a': 1, 'b': 2}) + def d12v(a, b=1, c=2, *rest): pass + d12v(1) + d12v(1, 2) + d12v(1, 2, 3) + d12v(1, 2, 3, 4) + d12v(*(1, 2, 3, 4)) + d12v(1, 2, *(3, 4, 5)) + d12v(1, *(2,), **{'c': 3}) + def d22v(a, b, c=1, d=2, *rest): pass + d22v(1, 2) + d22v(1, 2, 3) + d22v(1, 2, 3, 4) + d22v(1, 2, 3, 4, 5) + d22v(*(1, 2, 3, 4)) + d22v(1, 2, *(3, 4, 5)) + d22v(1, *(2, 3), **{'d': 4}) + + # keyword argument type tests + try: + str('x', **{b'foo':1 }) + except TypeError: + pass + else: + self.fail('Bytes should not work as keyword argument names') + # keyword only argument tests + def pos0key1(*, key): return key + pos0key1(key=100) + def pos2key2(p1, p2, *, k1, k2=100): return p1,p2,k1,k2 + pos2key2(1, 2, k1=100) + pos2key2(1, 2, k1=100, k2=200) + pos2key2(1, 2, k2=100, k1=200) + def pos2key2dict(p1, p2, *, k1=100, k2, **kwarg): return p1,p2,k1,k2,kwarg + pos2key2dict(1,2,k2=100,tokwarg1=100,tokwarg2=200) + pos2key2dict(1,2,tokwarg1=100,tokwarg2=200, k2=100) + + # keyword arguments after *arglist + def f(*args, **kwargs): + return args, kwargs + self.assertEquals(f(1, x=2, *[3, 4], y=5), ((1, 3, 4), + {'x':2, 'y':5})) + self.assertRaises(SyntaxError, eval, "f(1, *(2,3), 4)") + self.assertRaises(SyntaxError, eval, "f(1, x=2, *(3,4), x=5)") + + # argument annotation tests + def f(x) -> list: pass + self.assertEquals(f.__annotations__, {'return': list}) + def f(x:int): pass + self.assertEquals(f.__annotations__, {'x': int}) + def f(*x:str): pass + self.assertEquals(f.__annotations__, {'x': str}) + def f(**x:float): pass + self.assertEquals(f.__annotations__, {'x': float}) + def f(x, y:1+2): pass + self.assertEquals(f.__annotations__, {'y': 3}) + def f(a, b:1, c:2, d): pass + self.assertEquals(f.__annotations__, {'b': 1, 'c': 2}) + def f(a, b:1, c:2, d, e:3=4, f=5, *g:6): pass + self.assertEquals(f.__annotations__, + {'b': 1, 'c': 2, 'e': 3, 'g': 6}) + def f(a, b:1, c:2, d, e:3=4, f=5, *g:6, h:7, i=8, j:9=10, + **k:11) -> 12: pass + self.assertEquals(f.__annotations__, + {'b': 1, 'c': 2, 'e': 3, 'g': 6, 'h': 7, 'j': 9, + 'k': 11, 'return': 12}) + # Check for SF Bug #1697248 - mixing decorators and a return annotation + def null(x): return x + @null + def f(x) -> list: pass + self.assertEquals(f.__annotations__, {'return': list}) + + # test MAKE_CLOSURE with a variety of oparg's + closure = 1 + def f(): return closure + def f(x=1): return closure + def f(*, k=1): return closure + def f() -> int: return closure + + # Check ast errors in *args and *kwargs + check_syntax_error(self, "f(*g(1=2))") + check_syntax_error(self, "f(**g(1=2))") + + def testLambdef(self): + ### lambdef: 'lambda' [varargslist] ':' test + l1 = lambda : 0 + self.assertEquals(l1(), 0) + l2 = lambda : a[d] # XXX just testing the expression + l3 = lambda : [2 < x for x in [-1, 3, 0]] + self.assertEquals(l3(), [0, 1, 0]) + l4 = lambda x = lambda y = lambda z=1 : z : y() : x() + self.assertEquals(l4(), 1) + l5 = lambda x, y, z=2: x + y + z + self.assertEquals(l5(1, 2), 5) + self.assertEquals(l5(1, 2, 3), 6) + check_syntax_error(self, "lambda x: x = 2") + check_syntax_error(self, "lambda (None,): None") + l6 = lambda x, y, *, k=20: x+y+k + self.assertEquals(l6(1,2), 1+2+20) + self.assertEquals(l6(1,2,k=10), 1+2+10) + + + ### stmt: simple_stmt | compound_stmt + # Tested below + + def testSimpleStmt(self): + ### simple_stmt: small_stmt (';' small_stmt)* [';'] + x = 1; pass; del x + def foo(): + # verify statments that end with semi-colons + x = 1; pass; del x; + foo() + + ### small_stmt: expr_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt + # Tested below + + def testExprStmt(self): + # (exprlist '=')* exprlist + 1 + 1, 2, 3 + x = 1 + x = 1, 2, 3 + x = y = z = 1, 2, 3 + x, y, z = 1, 2, 3 + abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4) + + check_syntax_error(self, "x + 1 = 1") + check_syntax_error(self, "a + 1 = b + 2") + + def testDelStmt(self): + # 'del' exprlist + abc = [1,2,3] + x, y, z = abc + xyz = x, y, z + + del abc + del x, y, (z, xyz) + + def testPassStmt(self): + # 'pass' + pass + + # flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt + # Tested below + + def testBreakStmt(self): + # 'break' + while 1: break + + def testContinueStmt(self): + # 'continue' + i = 1 + while i: i = 0; continue + + msg = "" + while not msg: + msg = "ok" + try: + continue + msg = "continue failed to continue inside try" + except: + msg = "continue inside try called except block" + if msg != "ok": + self.fail(msg) + + msg = "" + while not msg: + msg = "finally block not called" + try: + continue + finally: + msg = "ok" + if msg != "ok": + self.fail(msg) + + def test_break_continue_loop(self): + # This test warrants an explanation. It is a test specifically for SF bugs + # #463359 and #462937. The bug is that a 'break' statement executed or + # exception raised inside a try/except inside a loop, *after* a continue + # statement has been executed in that loop, will cause the wrong number of + # arguments to be popped off the stack and the instruction pointer reset to + # a very small number (usually 0.) Because of this, the following test + # *must* written as a function, and the tracking vars *must* be function + # arguments with default values. Otherwise, the test will loop and loop. + + def test_inner(extra_burning_oil = 1, count=0): + big_hippo = 2 + while big_hippo: + count += 1 + try: + if extra_burning_oil and big_hippo == 1: + extra_burning_oil -= 1 + break + big_hippo -= 1 + continue + except: + raise + if count > 2 or big_hippo != 1: + self.fail("continue then break in try/except in loop broken!") + test_inner() + + def testReturn(self): + # 'return' [testlist] + def g1(): return + def g2(): return 1 + g1() + x = g2() + check_syntax_error(self, "class foo:return 1") + + def testYield(self): + check_syntax_error(self, "class foo:yield 1") + + def testRaise(self): + # 'raise' test [',' test] + try: raise RuntimeError('just testing') + except RuntimeError: pass + try: raise KeyboardInterrupt + except KeyboardInterrupt: pass + + def testImport(self): + # 'import' dotted_as_names + import sys + import time, sys + # 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names) + from time import time + from time import (time) + # not testable inside a function, but already done at top of the module + # from sys import * + from sys import path, argv + from sys import (path, argv) + from sys import (path, argv,) + + def testGlobal(self): + # 'global' NAME (',' NAME)* + global a + global a, b + global one, two, three, four, five, six, seven, eight, nine, ten + + def testNonlocal(self): + # 'nonlocal' NAME (',' NAME)* + x = 0 + y = 0 + def f(): + nonlocal x + nonlocal x, y + + def testAssert(self): + # assert_stmt: 'assert' test [',' test] + assert 1 + assert 1, 1 + assert lambda x:x + assert 1, lambda x:x+1 + try: + assert 0, "msg" + except AssertionError as e: + self.assertEquals(e.args[0], "msg") + else: + if __debug__: + self.fail("AssertionError not raised by assert 0") + + ### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef + # Tested below + + def testIf(self): + # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] + if 1: pass + if 1: pass + else: pass + if 0: pass + elif 0: pass + if 0: pass + elif 0: pass + elif 0: pass + elif 0: pass + else: pass + + def testWhile(self): + # 'while' test ':' suite ['else' ':' suite] + while 0: pass + while 0: pass + else: pass + + # Issue1920: "while 0" is optimized away, + # ensure that the "else" clause is still present. + x = 0 + while 0: + x = 1 + else: + x = 2 + self.assertEquals(x, 2) + + def testFor(self): + # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] + for i in 1, 2, 3: pass + for i, j, k in (): pass + else: pass + class Squares: + def __init__(self, max): + self.max = max + self.sofar = [] + def __len__(self): return len(self.sofar) + def __getitem__(self, i): + if not 0 <= i < self.max: raise IndexError + n = len(self.sofar) + while n <= i: + self.sofar.append(n*n) + n = n+1 + return self.sofar[i] + n = 0 + for x in Squares(10): n = n+x + if n != 285: + self.fail('for over growing sequence') + + result = [] + for x, in [(1,), (2,), (3,)]: + result.append(x) + self.assertEqual(result, [1, 2, 3]) + + def testTry(self): + ### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] + ### | 'try' ':' suite 'finally' ':' suite + ### except_clause: 'except' [expr ['as' expr]] + try: + 1/0 + except ZeroDivisionError: + pass + else: + pass + try: 1/0 + except EOFError: pass + except TypeError as msg: pass + except RuntimeError as msg: pass + except: pass + else: pass + try: 1/0 + except (EOFError, TypeError, ZeroDivisionError): pass + try: 1/0 + except (EOFError, TypeError, ZeroDivisionError) as msg: pass + try: pass + finally: pass + + def testSuite(self): + # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT + if 1: pass + if 1: + pass + if 1: + # + # + # + pass + pass + # + pass + # + + def testTest(self): + ### and_test ('or' and_test)* + ### and_test: not_test ('and' not_test)* + ### not_test: 'not' not_test | comparison + if not 1: pass + if 1 and 1: pass + if 1 or 1: pass + if not not not 1: pass + if not 1 and 1 and 1: pass + if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass + + def testComparison(self): + ### comparison: expr (comp_op expr)* + ### comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is'|'is' 'not' + if 1: pass + x = (1 == 1) + if 1 == 1: pass + if 1 != 1: pass + if 1 < 1: pass + if 1 > 1: pass + if 1 <= 1: pass + if 1 >= 1: pass + if 1 is 1: pass + if 1 is not 1: pass + if 1 in (): pass + if 1 not in (): pass + if 1 < 1 > 1 == 1 >= 1 <= 1 != 1 in 1 not in 1 is 1 is not 1: pass + + def testBinaryMaskOps(self): + x = 1 & 1 + x = 1 ^ 1 + x = 1 | 1 + + def testShiftOps(self): + x = 1 << 1 + x = 1 >> 1 + x = 1 << 1 >> 1 + + def testAdditiveOps(self): + x = 1 + x = 1 + 1 + x = 1 - 1 - 1 + x = 1 - 1 + 1 - 1 + 1 + + def testMultiplicativeOps(self): + x = 1 * 1 + x = 1 / 1 + x = 1 % 1 + x = 1 / 1 * 1 % 1 + + def testUnaryOps(self): + x = +1 + x = -1 + x = ~1 + x = ~1 ^ 1 & 1 | 1 & 1 ^ -1 + x = -1*1/1 + 1*1 - ---1*1 + + def testSelectors(self): + ### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME + ### subscript: expr | [expr] ':' [expr] + + import sys, time + c = sys.path[0] + x = time.time() + x = sys.modules['time'].time() + a = '01234' + c = a[0] + c = a[-1] + s = a[0:5] + s = a[:5] + s = a[0:] + s = a[:] + s = a[-5:] + s = a[:-1] + s = a[-4:-3] + # A rough test of SF bug 1333982. http://python.org/sf/1333982 + # The testing here is fairly incomplete. + # Test cases should include: commas with 1 and 2 colons + d = {} + d[1] = 1 + d[1,] = 2 + d[1,2] = 3 + d[1,2,3] = 4 + L = list(d) + L.sort(key=lambda x: x if isinstance(x, tuple) else ()) + self.assertEquals(str(L), '[1, (1,), (1, 2), (1, 2, 3)]') + + def testAtoms(self): + ### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictsetmaker] '}' | NAME | NUMBER | STRING + ### dictsetmaker: (test ':' test (',' test ':' test)* [',']) | (test (',' test)* [',']) + + x = (1) + x = (1 or 2 or 3) + x = (1 or 2 or 3, 2, 3) + + x = [] + x = [1] + x = [1 or 2 or 3] + x = [1 or 2 or 3, 2, 3] + x = [] + + x = {} + x = {'one': 1} + x = {'one': 1,} + x = {'one' or 'two': 1 or 2} + x = {'one': 1, 'two': 2} + x = {'one': 1, 'two': 2,} + x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6} + + x = {'one'} + x = {'one', 1,} + x = {'one', 'two', 'three'} + x = {2, 3, 4,} + + x = x + x = 'x' + x = 123 + + ### exprlist: expr (',' expr)* [','] + ### testlist: test (',' test)* [','] + # These have been exercised enough above + + def testClassdef(self): + # 'class' NAME ['(' [testlist] ')'] ':' suite + class B: pass + class B2(): pass + class C1(B): pass + class C2(B): pass + class D(C1, C2, B): pass + class C: + def meth1(self): pass + def meth2(self, arg): pass + def meth3(self, a1, a2): pass + + # decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE + # decorators: decorator+ + # decorated: decorators (classdef | funcdef) + def class_decorator(x): return x + @class_decorator + class G: pass + + def testDictcomps(self): + # dictorsetmaker: ( (test ':' test (comp_for | + # (',' test ':' test)* [','])) | + # (test (comp_for | (',' test)* [','])) ) + nums = [1, 2, 3] + self.assertEqual({i:i+1 for i in nums}, {1: 2, 2: 3, 3: 4}) + + def testListcomps(self): + # list comprehension tests + nums = [1, 2, 3, 4, 5] + strs = ["Apple", "Banana", "Coconut"] + spcs = [" Apple", " Banana ", "Coco nut "] + + self.assertEqual([s.strip() for s in spcs], ['Apple', 'Banana', 'Coco nut']) + self.assertEqual([3 * x for x in nums], [3, 6, 9, 12, 15]) + self.assertEqual([x for x in nums if x > 2], [3, 4, 5]) + self.assertEqual([(i, s) for i in nums for s in strs], + [(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'), + (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'), + (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'), + (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'), + (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')]) + self.assertEqual([(i, s) for i in nums for s in [f for f in strs if "n" in f]], + [(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'), + (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'), + (5, 'Banana'), (5, 'Coconut')]) + self.assertEqual([(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)], + [[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]]) + + def test_in_func(l): + return [0 < x < 3 for x in l if x > 2] + + self.assertEqual(test_in_func(nums), [False, False, False]) + + def test_nested_front(): + self.assertEqual([[y for y in [x, x + 1]] for x in [1,3,5]], + [[1, 2], [3, 4], [5, 6]]) + + test_nested_front() + + check_syntax_error(self, "[i, s for i in nums for s in strs]") + check_syntax_error(self, "[x if y]") + + suppliers = [ + (1, "Boeing"), + (2, "Ford"), + (3, "Macdonalds") + ] + + parts = [ + (10, "Airliner"), + (20, "Engine"), + (30, "Cheeseburger") + ] + + suppart = [ + (1, 10), (1, 20), (2, 20), (3, 30) + ] + + x = [ + (sname, pname) + for (sno, sname) in suppliers + for (pno, pname) in parts + for (sp_sno, sp_pno) in suppart + if sno == sp_sno and pno == sp_pno + ] + + self.assertEqual(x, [('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), + ('Macdonalds', 'Cheeseburger')]) + + def testGenexps(self): + # generator expression tests + g = ([x for x in range(10)] for x in range(1)) + self.assertEqual(next(g), [x for x in range(10)]) + try: + next(g) + self.fail('should produce StopIteration exception') + except StopIteration: + pass + + a = 1 + try: + g = (a for d in a) + next(g) + self.fail('should produce TypeError') + except TypeError: + pass + + self.assertEqual(list((x, y) for x in 'abcd' for y in 'abcd'), [(x, y) for x in 'abcd' for y in 'abcd']) + self.assertEqual(list((x, y) for x in 'ab' for y in 'xy'), [(x, y) for x in 'ab' for y in 'xy']) + + a = [x for x in range(10)] + b = (x for x in (y for y in a)) + self.assertEqual(sum(b), sum([x for x in range(10)])) + + self.assertEqual(sum(x**2 for x in range(10)), sum([x**2 for x in range(10)])) + self.assertEqual(sum(x*x for x in range(10) if x%2), sum([x*x for x in range(10) if x%2])) + self.assertEqual(sum(x for x in (y for y in range(10))), sum([x for x in range(10)])) + self.assertEqual(sum(x for x in (y for y in (z for z in range(10)))), sum([x for x in range(10)])) + self.assertEqual(sum(x for x in [y for y in (z for z in range(10))]), sum([x for x in range(10)])) + self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True)) if True), sum([x for x in range(10)])) + self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True) if False) if True), 0) + check_syntax_error(self, "foo(x for x in range(10), 100)") + check_syntax_error(self, "foo(100, x for x in range(10))") + + def testComprehensionSpecials(self): + # test for outmost iterable precomputation + x = 10; g = (i for i in range(x)); x = 5 + self.assertEqual(len(list(g)), 10) + + # This should hold, since we're only precomputing outmost iterable. + x = 10; t = False; g = ((i,j) for i in range(x) if t for j in range(x)) + x = 5; t = True; + self.assertEqual([(i,j) for i in range(10) for j in range(5)], list(g)) + + # Grammar allows multiple adjacent 'if's in listcomps and genexps, + # even though it's silly. Make sure it works (ifelse broke this.) + self.assertEqual([ x for x in range(10) if x % 2 if x % 3 ], [1, 5, 7]) + self.assertEqual(list(x for x in range(10) if x % 2 if x % 3), [1, 5, 7]) + + # verify unpacking single element tuples in listcomp/genexp. + self.assertEqual([x for x, in [(4,), (5,), (6,)]], [4, 5, 6]) + self.assertEqual(list(x for x, in [(7,), (8,), (9,)]), [7, 8, 9]) + + def testIfElseExpr(self): + # Test ifelse expressions in various cases + def _checkeval(msg, ret): + "helper to check that evaluation of expressions is done correctly" + print(x) + return ret + + # the next line is not allowed anymore + #self.assertEqual([ x() for x in lambda: True, lambda: False if x() ], [True]) + self.assertEqual([ x() for x in (lambda: True, lambda: False) if x() ], [True]) + self.assertEqual([ x(False) for x in (lambda x: False if x else True, lambda x: True if x else False) if x(False) ], [True]) + self.assertEqual((5 if 1 else _checkeval("check 1", 0)), 5) + self.assertEqual((_checkeval("check 2", 0) if 0 else 5), 5) + self.assertEqual((5 and 6 if 0 else 1), 1) + self.assertEqual(((5 and 6) if 0 else 1), 1) + self.assertEqual((5 and (6 if 1 else 1)), 6) + self.assertEqual((0 or _checkeval("check 3", 2) if 0 else 3), 3) + self.assertEqual((1 or _checkeval("check 4", 2) if 1 else _checkeval("check 5", 3)), 1) + self.assertEqual((0 or 5 if 1 else _checkeval("check 6", 3)), 5) + self.assertEqual((not 5 if 1 else 1), False) + self.assertEqual((not 5 if 0 else 1), 1) + self.assertEqual((6 + 1 if 1 else 2), 7) + self.assertEqual((6 - 1 if 1 else 2), 5) + self.assertEqual((6 * 2 if 1 else 4), 12) + self.assertEqual((6 / 2 if 1 else 3), 3) + self.assertEqual((6 < 4 if 0 else 2), 2) + + +def test_main(): + run_unittest(TokenTests, GrammarTests) + +if __name__ == '__main__': + test_main() Added: sandbox/trunk/refactor_pkg/refactor/tests/pytree_idempotency.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/tests/pytree_idempotency.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,92 @@ +#!/usr/bin/env python2.5 +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Main program for testing the infrastructure.""" + +__author__ = "Guido van Rossum " + +# Support imports (need to be imported first) +from . import support + +# Python imports +import os +import sys +import logging + +# Local imports +from .. import pytree +import pgen2 +from pgen2 import driver + +logging.basicConfig() + +def main(): + gr = driver.load_grammar("Grammar.txt") + dr = driver.Driver(gr, convert=pytree.convert) + + fn = "example.py" + tree = dr.parse_file(fn, debug=True) + if not diff(fn, tree): + print "No diffs." + if not sys.argv[1:]: + return # Pass a dummy argument to run the complete test suite below + + problems = [] + + # Process every imported module + for name in sys.modules: + mod = sys.modules[name] + if mod is None or not hasattr(mod, "__file__"): + continue + fn = mod.__file__ + if fn.endswith(".pyc"): + fn = fn[:-1] + if not fn.endswith(".py"): + continue + print >>sys.stderr, "Parsing", fn + tree = dr.parse_file(fn, debug=True) + if diff(fn, tree): + problems.append(fn) + + # Process every single module on sys.path (but not in packages) + for dir in sys.path: + try: + names = os.listdir(dir) + except os.error: + continue + print >>sys.stderr, "Scanning", dir, "..." + for name in names: + if not name.endswith(".py"): + continue + print >>sys.stderr, "Parsing", name + fn = os.path.join(dir, name) + try: + tree = dr.parse_file(fn, debug=True) + except pgen2.parse.ParseError, err: + print "ParseError:", err + else: + if diff(fn, tree): + problems.append(fn) + + # Show summary of problem files + if not problems: + print "No problems. Congratulations!" + else: + print "Problems in following files:" + for fn in problems: + print "***", fn + +def diff(fn, tree): + f = open("@", "w") + try: + f.write(str(tree)) + finally: + f.close() + try: + return os.system("diff -u %s @" % fn) + finally: + os.remove("@") + +if __name__ == "__main__": + main() Added: sandbox/trunk/refactor_pkg/refactor/tests/support.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/tests/support.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,78 @@ +"""Support code for test_*.py files""" +# Original Author: Collin Winter + +# Python imports +import unittest +import sys +import os +import os.path +import re +from textwrap import dedent + +#sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) + +# Local imports +from .. import pytree +from .. import refactor +from ..pgen2 import driver + +test_pkg = "refactor.fixes" +test_dir = os.path.dirname(__file__) +proj_dir = os.path.normpath(os.path.join(test_dir, "..")) +grammar_path = os.path.join(test_dir, "..", "Grammar.txt") +grammar = driver.load_grammar(grammar_path) +driver = driver.Driver(grammar, convert=pytree.convert) + +def parse_version(version_string): + """Returns a version tuple matching input version_string.""" + if not version_string: + return () + + version_list = [] + for token in version_string.split('.'): + try: + version_list.append(int(token)) + except ValueError: + version_list.append(token) + return tuple(version_list) + +def parse_string(string): + return driver.parse_string(reformat(string), debug=True) + +# Python 2.3's TestSuite is not iter()-able +if sys.version_info < (2, 4): + def TestSuite_iter(self): + return iter(self._tests) + unittest.TestSuite.__iter__ = TestSuite_iter + +def run_all_tests(test_mod=None, tests=None): + if tests is None: + tests = unittest.TestLoader().loadTestsFromModule(test_mod) + unittest.TextTestRunner(verbosity=2).run(tests) + +def reformat(string): + return dedent(string) + "\n\n" + +def get_refactorer(fixers=None, options=None, pkg_name=None): + """ + A convenience function for creating a RefactoringTool for tests. + + fixers is a list of fixers for the RefactoringTool to use. By default + "refactor.fixes.*" is used. options is an optional dictionary of options to + be passed to the RefactoringTool. + """ + pkg_name = pkg_name or test_pkg + if fixers is not None: + fixers = [pkg_name + ".fix_" + fix for fix in fixers] + else: + fixers = refactor.get_fixers_from_package(pkg_name) + options = options or {} + return refactor.RefactoringTool(fixers, options, explicit=True) + +def all_project_files(): + for dirpath, dirnames, filenames in os.walk(proj_dir): + for filename in filenames: + if filename.endswith(".py"): + yield os.path.join(dirpath, filename) + +TestCase = unittest.TestCase Added: sandbox/trunk/refactor_pkg/refactor/tests/test_all_fixers.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/tests/test_all_fixers.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,35 @@ +#!/usr/bin/env python2.5 +"""Tests that run all fixer modules over an input stream. + +This has been broken out into its own test module because of its +running time. +""" +# Author: Collin Winter + +# Testing imports +try: + from . import support +except ImportError: + import support + +# Python imports +import unittest + +# Local imports +from .. import pytree +from .. import refactor + +class Test_all(support.TestCase): + def setUp(self): + options = {"print_function" : False} + self.refactor = support.get_refactorer(options=options) + + def test_all_project_files(self): + for filepath in support.all_project_files(): + print "Fixing %s..." % filepath + self.refactor.refactor_string(open(filepath).read(), filepath) + + +if __name__ == "__main__": + import __main__ + support.run_all_tests(__main__) Added: sandbox/trunk/refactor_pkg/refactor/tests/test_fixers.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/tests/test_fixers.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,222 @@ +#!/usr/bin/env python2.5 +""" Test suite for the fixer modules """ +# Original Author: Collin Winter + +# Testing imports +try: + from tests import support +except ImportError: + import support + +# Python imports +import os +import unittest +from itertools import chain +from operator import itemgetter + +# Local imports +from .. import pygram, pytree, refactor, fixer_util + +class FixerTestCase(support.TestCase): + old_version = (3, 0) + new_version = (2, 5) + + def setUp(self, fix_list=None): + if fix_list is None: + fix_list = [self.fixer] + options = {"print_function" : False} + pkg_name = self.get_pkg_name() + self.refactor = support.get_refactorer(fix_list, options, + pkg_name=pkg_name) + self.fixer_log = [] + self.filename = "" + + for fixer in chain(self.refactor.pre_order, + self.refactor.post_order): + fixer.log = self.fixer_log + + def _check(self, versions, ignore_warnings=False): + """Verifying a fix matches before and after version + + versions is a dict mapping version tuples to sample code. + + Example: + check({ (3, 0): 'print()', + (2,3): 'print' }) + # The same dict applies for 3.x to 2.x and vice versa + """ + before = self.price_is_right(versions, self.old_version) + after = self.price_is_right(versions, self.new_version) + + # Quit now if neither before nor after won the Price is Right. + if before == None or after == None: + return + + before = support.reformat(before) + after = support.reformat(after) + + tree = self.refactor.refactor_string(before, self.filename) + self.failUnlessEqual(after, str(tree)) + if not ignore_warnings: + self.failUnlessEqual(self.fixer_log, []) + return tree + + + def price_is_right(self, versions, target_version): + """Return the closest version in versions without going over target + """ + snippet = None + for version_key in sorted(versions.keys()): + if version_key > target_version: + break + snippet = versions[version_key] + return snippet + + def check(self, up, down): + if self.old_version > self.new_version: + self._check(down) + elif self.old_version < self.new_version: + self._check(up) + else: + self._check(down) + self._check(up) + + def get_pkg_name(self): + if self.old_version >= (3, 0): + return 'refactor.fixes.from3' + else: + return 'refactor.fixes.from2' + + def warns(self, before, after, message, unchanged=False): + tree = self._check(before, after) + self.failUnless(message in "".join(self.fixer_log)) + if not unchanged: + self.failUnless(tree.was_changed) + + def warns_unchanged(self, before, message): + self.warns(before, before, message, unchanged=True) + + def unchanged(self, before, ignore_warnings=False): + self._check(before, before) + if not ignore_warnings: + self.failUnlessEqual(self.fixer_log, []) + + def assert_runs_after(self, *names): + fixes = [self.fixer] + fixes.extend(names) + options = {"print_function" : False} + r = support.get_refactorer(fixes, options) + (pre, post) = r.get_fixers() + n = "fix_" + self.fixer + if post and post[-1].__class__.__module__.endswith(n): + # We're the last fixer to run + return + if pre and pre[-1].__class__.__module__.endswith(n) and not post: + # We're the last in pre and post is empty + return + self.fail("Fixer run order (%s) is incorrect; %s should be last."\ + %(", ".join([x.__class__.__module__ for x in (pre+post)]), n)) + +class Test_range(FixerTestCase): + fixer = "range" + + def test_xrange(self): + up = {} + down = { + (2, 5): """x = xrange(0, 10, 2)""", + (3, 0): """x = range(0, 10, 2)""", + } + self.check(up, down) + + def test_range(self): + up = {} + down = { + (2, 5): """x = list(xrange(0, 10, 2))""", + (3, 0): """x = list(range(0, 10, 2))""", + } + self.check(up, down) + +class Test_renames(FixerTestCase): + fixer = "renames" + + def test_maxint(self): + up = {} + down = { + (2, 5): """sys.maxint""", + (2, 6): """sys.maxsize""", + } + self.check(up, down) + +class Test_print(FixerTestCase): + """ + http://docs.python.org/3.0/whatsnew/3.0.html + + Old: print "The answer is", 2*2 + New: print("The answer is", 2*2) + + Old: print x, # Trailing comma suppresses newline + New: print(x, end=" ") # Appends a space instead of a newline + + Old: print # Prints a newline + New: print() # You must call the function! + + Old: print >>sys.stderr, "fatal error" + New: print("fatal error", file=sys.stderr) + + Old: print (x, y) # prints repr((x, y)) + New: print((x, y)) # Not the same as print(x, y)! + """ + + fixer = "print" + + def test_func(self): + up = {} + down = { + (2, 5): """print""", + (3, 0): """print()""", + } + self.check(up, down) + + def test_x(self): + up = {} + down = { + (2, 5): """print x""", + (3, 0): """print(x)""", + } + self.check(up, down) + + def test_str(self): + up = {} + down = { + (2, 5): """print ''""", + (3, 0): """print('')""", + } + self.check(up, down) + + def test_compound(self): + up = {} + down = { + (2, 5): """print "The answer is", 2*2""", + (3, 0): """print("The answer is", 2*2)""", + } + self.check(up, down) + + def test_end(self): + up = {} + down = { + (2, 5): """print x, """, + (3, 0): """print(x, end=" ")""", + } + self.check(up, down) + + def test_stderr(self): + up = {} + down = { + (2, 5): """print >>sys.stderr, 'fatal error'""", + (3, 0): """print('fatal error', file=sys.stderr)""", + } + self.check(up, down) + +if __name__ == "__main__": + import __main__ + support.run_all_tests(__main__) Added: sandbox/trunk/refactor_pkg/refactor/tests/test_parser.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/tests/test_parser.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,202 @@ +#!/usr/bin/env python2.5 +"""Test suite for refactor's parser and grammar files. + +This is the place to add tests for changes to refactor's grammar, such as those +merging the grammars for Python 2 and 3. In addition to specific tests for +parts of the grammar we've changed, we also make sure we can parse the +test_grammar.py files from both Python 2 and Python 3. +""" +# Author: Collin Winter + +# Testing imports +from . import support +from .support import driver, test_dir + +# Python imports +import os +import os.path + +# Local imports +from ..pgen2.parse import ParseError + + +class GrammarTest(support.TestCase): + def validate(self, code): + support.parse_string(code) + + def invalid_syntax(self, code): + try: + self.validate(code) + except ParseError: + pass + else: + raise AssertionError("Syntax shouldn't have been valid") + + +class TestRaiseChanges(GrammarTest): + def test_2x_style_1(self): + self.validate("raise") + + def test_2x_style_2(self): + self.validate("raise E, V") + + def test_2x_style_3(self): + self.validate("raise E, V, T") + + def test_2x_style_invalid_1(self): + self.invalid_syntax("raise E, V, T, Z") + + def test_3x_style(self): + self.validate("raise E1 from E2") + + def test_3x_style_invalid_1(self): + self.invalid_syntax("raise E, V from E1") + + def test_3x_style_invalid_2(self): + self.invalid_syntax("raise E from E1, E2") + + def test_3x_style_invalid_3(self): + self.invalid_syntax("raise from E1, E2") + + def test_3x_style_invalid_4(self): + self.invalid_syntax("raise E from") + + +# Adapated from Python 3's Lib/test/test_grammar.py:GrammarTests.testFuncdef +class TestFunctionAnnotations(GrammarTest): + def test_1(self): + self.validate("""def f(x) -> list: pass""") + + def test_2(self): + self.validate("""def f(x:int): pass""") + + def test_3(self): + self.validate("""def f(*x:str): pass""") + + def test_4(self): + self.validate("""def f(**x:float): pass""") + + def test_5(self): + self.validate("""def f(x, y:1+2): pass""") + + def test_6(self): + self.validate("""def f(a, (b:1, c:2, d)): pass""") + + def test_7(self): + self.validate("""def f(a, (b:1, c:2, d), e:3=4, f=5, *g:6): pass""") + + def test_8(self): + s = """def f(a, (b:1, c:2, d), e:3=4, f=5, + *g:6, h:7, i=8, j:9=10, **k:11) -> 12: pass""" + self.validate(s) + + +class TestExcept(GrammarTest): + def test_new(self): + s = """ + try: + x + except E as N: + y""" + self.validate(s) + + def test_old(self): + s = """ + try: + x + except E, N: + y""" + self.validate(s) + + +# Adapted from Python 3's Lib/test/test_grammar.py:GrammarTests.testAtoms +class TestSetLiteral(GrammarTest): + def test_1(self): + self.validate("""x = {'one'}""") + + def test_2(self): + self.validate("""x = {'one', 1,}""") + + def test_3(self): + self.validate("""x = {'one', 'two', 'three'}""") + + def test_4(self): + self.validate("""x = {2, 3, 4,}""") + + +class TestNumericLiterals(GrammarTest): + def test_new_octal_notation(self): + self.validate("""0o7777777777777""") + self.invalid_syntax("""0o7324528887""") + + def test_new_binary_notation(self): + self.validate("""0b101010""") + self.invalid_syntax("""0b0101021""") + + +class TestClassDef(GrammarTest): + def test_new_syntax(self): + self.validate("class B(t=7): pass") + self.validate("class B(t, *args): pass") + self.validate("class B(t, **kwargs): pass") + self.validate("class B(t, *args, **kwargs): pass") + self.validate("class B(t, y=9, *args, **kwargs): pass") + + +class TestParserIdempotency(support.TestCase): + + """A cut-down version of pytree_idempotency.py.""" + + def test_all_project_files(self): + for filepath in support.all_project_files(): + print "Parsing %s..." % filepath + tree = driver.parse_file(filepath, debug=True) + if diff(filepath, tree): + self.fail("Idempotency failed: %s" % filepath) + + +class TestLiterals(GrammarTest): + + def test_multiline_bytes_literals(self): + s = """ + md5test(b"\xaa" * 80, + (b"Test Using Larger Than Block-Size Key " + b"and Larger Than One Block-Size Data"), + "6f630fad67cda0ee1fb1f562db3aa53e") + """ + self.validate(s) + + def test_multiline_bytes_tripquote_literals(self): + s = ''' + b""" + + + """ + ''' + self.validate(s) + + def test_multiline_str_literals(self): + s = """ + md5test("\xaa" * 80, + ("Test Using Larger Than Block-Size Key " + "and Larger Than One Block-Size Data"), + "6f630fad67cda0ee1fb1f562db3aa53e") + """ + self.validate(s) + + +def diff(fn, tree): + f = open("@", "w") + try: + f.write(str(tree)) + finally: + f.close() + try: + return os.system("diff -u %s @" % fn) + finally: + os.remove("@") + + +if __name__ == "__main__": + import __main__ + support.run_all_tests(__main__) Added: sandbox/trunk/refactor_pkg/refactor/tests/test_pytree.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/tests/test_pytree.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,458 @@ +#!/usr/bin/env python2.5 +# Copyright 2006 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Unit tests for pytree.py. + +NOTE: Please *don't* add doc strings to individual test methods! +In verbose mode, printing of the module, class and method name is much +more helpful than printing of (the first line of) the docstring, +especially when debugging a test. +""" + +# Testing imports +from . import support + +# Local imports (XXX should become a package) +from .. import pytree + +try: + sorted +except NameError: + def sorted(lst): + l = list(lst) + l.sort() + return l + +class TestNodes(support.TestCase): + + """Unit tests for nodes (Base, Leaf, Node).""" + + def testBaseCantConstruct(self): + if __debug__: + # Test that instantiating Base() raises an AssertionError + self.assertRaises(AssertionError, pytree.Base) + + def testLeaf(self): + l1 = pytree.Leaf(100, "foo") + self.assertEqual(l1.type, 100) + self.assertEqual(l1.value, "foo") + + def testLeafRepr(self): + l1 = pytree.Leaf(100, "foo") + self.assertEqual(repr(l1), "Leaf(100, 'foo')") + + def testLeafStr(self): + l1 = pytree.Leaf(100, "foo") + self.assertEqual(str(l1), "foo") + l2 = pytree.Leaf(100, "foo", context=(" ", (10, 1))) + self.assertEqual(str(l2), " foo") + + def testLeafStrNumericValue(self): + # Make sure that the Leaf's value is stringified. Failing to + # do this can cause a TypeError in certain situations. + l1 = pytree.Leaf(2, 5) + l1.set_prefix("foo_") + self.assertEqual(str(l1), "foo_5") + + def testLeafEq(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "foo", context=(" ", (1, 0))) + self.assertEqual(l1, l2) + l3 = pytree.Leaf(101, "foo") + l4 = pytree.Leaf(100, "bar") + self.assertNotEqual(l1, l3) + self.assertNotEqual(l1, l4) + + def testLeafPrefix(self): + l1 = pytree.Leaf(100, "foo") + self.assertEqual(l1.get_prefix(), "") + self.failIf(l1.was_changed) + l1.set_prefix(" ##\n\n") + self.assertEqual(l1.get_prefix(), " ##\n\n") + self.failUnless(l1.was_changed) + + def testNode(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(200, "bar") + n1 = pytree.Node(1000, [l1, l2]) + self.assertEqual(n1.type, 1000) + self.assertEqual(n1.children, [l1, l2]) + + def testNodeRepr(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "bar", context=(" ", (1, 0))) + n1 = pytree.Node(1000, [l1, l2]) + self.assertEqual(repr(n1), + "Node(1000, [%s, %s])" % (repr(l1), repr(l2))) + + def testNodeStr(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "bar", context=(" ", (1, 0))) + n1 = pytree.Node(1000, [l1, l2]) + self.assertEqual(str(n1), "foo bar") + + def testNodePrefix(self): + l1 = pytree.Leaf(100, "foo") + self.assertEqual(l1.get_prefix(), "") + n1 = pytree.Node(1000, [l1]) + self.assertEqual(n1.get_prefix(), "") + n1.set_prefix(" ") + self.assertEqual(n1.get_prefix(), " ") + self.assertEqual(l1.get_prefix(), " ") + + def testGetSuffix(self): + l1 = pytree.Leaf(100, "foo", prefix="a") + l2 = pytree.Leaf(100, "bar", prefix="b") + n1 = pytree.Node(1000, [l1, l2]) + + self.assertEqual(l1.get_suffix(), l2.get_prefix()) + self.assertEqual(l2.get_suffix(), "") + self.assertEqual(n1.get_suffix(), "") + + l3 = pytree.Leaf(100, "bar", prefix="c") + n2 = pytree.Node(1000, [n1, l3]) + + self.assertEqual(n1.get_suffix(), l3.get_prefix()) + self.assertEqual(l3.get_suffix(), "") + self.assertEqual(n2.get_suffix(), "") + + def testNodeEq(self): + n1 = pytree.Node(1000, ()) + n2 = pytree.Node(1000, [], context=(" ", (1, 0))) + self.assertEqual(n1, n2) + n3 = pytree.Node(1001, ()) + self.assertNotEqual(n1, n3) + + def testNodeEqRecursive(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "foo") + n1 = pytree.Node(1000, [l1]) + n2 = pytree.Node(1000, [l2]) + self.assertEqual(n1, n2) + l3 = pytree.Leaf(100, "bar") + n3 = pytree.Node(1000, [l3]) + self.assertNotEqual(n1, n3) + + def testReplace(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "+") + l3 = pytree.Leaf(100, "bar") + n1 = pytree.Node(1000, [l1, l2, l3]) + self.assertEqual(n1.children, [l1, l2, l3]) + self.failUnless(isinstance(n1.children, list)) + self.failIf(n1.was_changed) + l2new = pytree.Leaf(100, "-") + l2.replace(l2new) + self.assertEqual(n1.children, [l1, l2new, l3]) + self.failUnless(isinstance(n1.children, list)) + self.failUnless(n1.was_changed) + + def testReplaceWithList(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "+") + l3 = pytree.Leaf(100, "bar") + n1 = pytree.Node(1000, [l1, l2, l3]) + + l2.replace([pytree.Leaf(100, "*"), pytree.Leaf(100, "*")]) + self.assertEqual(str(n1), "foo**bar") + self.failUnless(isinstance(n1.children, list)) + + def testPostOrder(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "bar") + n1 = pytree.Node(1000, [l1, l2]) + self.assertEqual(list(n1.post_order()), [l1, l2, n1]) + + def testPreOrder(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "bar") + n1 = pytree.Node(1000, [l1, l2]) + self.assertEqual(list(n1.pre_order()), [n1, l1, l2]) + + def testChangedLeaf(self): + l1 = pytree.Leaf(100, "f") + self.failIf(l1.was_changed) + + l1.changed() + self.failUnless(l1.was_changed) + + def testChangedNode(self): + l1 = pytree.Leaf(100, "f") + n1 = pytree.Node(1000, [l1]) + self.failIf(n1.was_changed) + + n1.changed() + self.failUnless(n1.was_changed) + + def testChangedRecursive(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "+") + l3 = pytree.Leaf(100, "bar") + n1 = pytree.Node(1000, [l1, l2, l3]) + n2 = pytree.Node(1000, [n1]) + self.failIf(l1.was_changed) + self.failIf(n1.was_changed) + self.failIf(n2.was_changed) + + n1.changed() + self.failUnless(n1.was_changed) + self.failUnless(n2.was_changed) + self.failIf(l1.was_changed) + + def testLeafConstructorPrefix(self): + for prefix in ("xyz_", ""): + l1 = pytree.Leaf(100, "self", prefix=prefix) + self.failUnless(str(l1), prefix + "self") + self.assertEqual(l1.get_prefix(), prefix) + + def testNodeConstructorPrefix(self): + for prefix in ("xyz_", ""): + l1 = pytree.Leaf(100, "self") + l2 = pytree.Leaf(100, "foo", prefix="_") + n1 = pytree.Node(1000, [l1, l2], prefix=prefix) + self.failUnless(str(n1), prefix + "self_foo") + self.assertEqual(n1.get_prefix(), prefix) + self.assertEqual(l1.get_prefix(), prefix) + self.assertEqual(l2.get_prefix(), "_") + + def testRemove(self): + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "foo") + n1 = pytree.Node(1000, [l1, l2]) + n2 = pytree.Node(1000, [n1]) + + self.assertEqual(n1.remove(), 0) + self.assertEqual(n2.children, []) + self.assertEqual(l1.parent, n1) + self.assertEqual(n1.parent, None) + self.assertEqual(n2.parent, None) + self.failIf(n1.was_changed) + self.failUnless(n2.was_changed) + + self.assertEqual(l2.remove(), 1) + self.assertEqual(l1.remove(), 0) + self.assertEqual(n1.children, []) + self.assertEqual(l1.parent, None) + self.assertEqual(n1.parent, None) + self.assertEqual(n2.parent, None) + self.failUnless(n1.was_changed) + self.failUnless(n2.was_changed) + + def testRemoveParentless(self): + n1 = pytree.Node(1000, []) + n1.remove() + self.assertEqual(n1.parent, None) + + l1 = pytree.Leaf(100, "foo") + l1.remove() + self.assertEqual(l1.parent, None) + + def testNodeSetChild(self): + l1 = pytree.Leaf(100, "foo") + n1 = pytree.Node(1000, [l1]) + + l2 = pytree.Leaf(100, "bar") + n1.set_child(0, l2) + self.assertEqual(l1.parent, None) + self.assertEqual(l2.parent, n1) + self.assertEqual(n1.children, [l2]) + + n2 = pytree.Node(1000, [l1]) + n2.set_child(0, n1) + self.assertEqual(l1.parent, None) + self.assertEqual(n1.parent, n2) + self.assertEqual(n2.parent, None) + self.assertEqual(n2.children, [n1]) + + self.assertRaises(IndexError, n1.set_child, 4, l2) + # I don't care what it raises, so long as it's an exception + self.assertRaises(Exception, n1.set_child, 0, list) + + def testNodeInsertChild(self): + l1 = pytree.Leaf(100, "foo") + n1 = pytree.Node(1000, [l1]) + + l2 = pytree.Leaf(100, "bar") + n1.insert_child(0, l2) + self.assertEqual(l2.parent, n1) + self.assertEqual(n1.children, [l2, l1]) + + l3 = pytree.Leaf(100, "abc") + n1.insert_child(2, l3) + self.assertEqual(n1.children, [l2, l1, l3]) + + # I don't care what it raises, so long as it's an exception + self.assertRaises(Exception, n1.insert_child, 0, list) + + def testNodeAppendChild(self): + n1 = pytree.Node(1000, []) + + l1 = pytree.Leaf(100, "foo") + n1.append_child(l1) + self.assertEqual(l1.parent, n1) + self.assertEqual(n1.children, [l1]) + + l2 = pytree.Leaf(100, "bar") + n1.append_child(l2) + self.assertEqual(l2.parent, n1) + self.assertEqual(n1.children, [l1, l2]) + + # I don't care what it raises, so long as it's an exception + self.assertRaises(Exception, n1.append_child, list) + + def testNodeNextSibling(self): + n1 = pytree.Node(1000, []) + n2 = pytree.Node(1000, []) + p1 = pytree.Node(1000, [n1, n2]) + + self.failUnless(n1.next_sibling is n2) + self.assertEqual(n2.next_sibling, None) + self.assertEqual(p1.next_sibling, None) + + def testLeafNextSibling(self): + l1 = pytree.Leaf(100, "a") + l2 = pytree.Leaf(100, "b") + p1 = pytree.Node(1000, [l1, l2]) + + self.failUnless(l1.next_sibling is l2) + self.assertEqual(l2.next_sibling, None) + self.assertEqual(p1.next_sibling, None) + + def testNodePrevSibling(self): + n1 = pytree.Node(1000, []) + n2 = pytree.Node(1000, []) + p1 = pytree.Node(1000, [n1, n2]) + + self.failUnless(n2.prev_sibling is n1) + self.assertEqual(n1.prev_sibling, None) + self.assertEqual(p1.prev_sibling, None) + + def testLeafPrevSibling(self): + l1 = pytree.Leaf(100, "a") + l2 = pytree.Leaf(100, "b") + p1 = pytree.Node(1000, [l1, l2]) + + self.failUnless(l2.prev_sibling is l1) + self.assertEqual(l1.prev_sibling, None) + self.assertEqual(p1.prev_sibling, None) + + +class TestPatterns(support.TestCase): + + """Unit tests for tree matching patterns.""" + + def testBasicPatterns(self): + # Build a tree + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "bar") + l3 = pytree.Leaf(100, "foo") + n1 = pytree.Node(1000, [l1, l2]) + n2 = pytree.Node(1000, [l3]) + root = pytree.Node(1000, [n1, n2]) + # Build a pattern matching a leaf + pl = pytree.LeafPattern(100, "foo", name="pl") + r = {} + self.assertFalse(pl.match(root, results=r)) + self.assertEqual(r, {}) + self.assertFalse(pl.match(n1, results=r)) + self.assertEqual(r, {}) + self.assertFalse(pl.match(n2, results=r)) + self.assertEqual(r, {}) + self.assertTrue(pl.match(l1, results=r)) + self.assertEqual(r, {"pl": l1}) + r = {} + self.assertFalse(pl.match(l2, results=r)) + self.assertEqual(r, {}) + # Build a pattern matching a node + pn = pytree.NodePattern(1000, [pl], name="pn") + self.assertFalse(pn.match(root, results=r)) + self.assertEqual(r, {}) + self.assertFalse(pn.match(n1, results=r)) + self.assertEqual(r, {}) + self.assertTrue(pn.match(n2, results=r)) + self.assertEqual(r, {"pn": n2, "pl": l3}) + r = {} + self.assertFalse(pn.match(l1, results=r)) + self.assertEqual(r, {}) + self.assertFalse(pn.match(l2, results=r)) + self.assertEqual(r, {}) + + def testWildcardPatterns(self): + # Build a tree for testing + l1 = pytree.Leaf(100, "foo") + l2 = pytree.Leaf(100, "bar") + l3 = pytree.Leaf(100, "foo") + n1 = pytree.Node(1000, [l1, l2]) + n2 = pytree.Node(1000, [l3]) + root = pytree.Node(1000, [n1, n2]) + # Build a pattern + pl = pytree.LeafPattern(100, "foo", name="pl") + pn = pytree.NodePattern(1000, [pl], name="pn") + pw = pytree.WildcardPattern([[pn], [pl, pl]], name="pw") + r = {} + self.assertFalse(pw.match_seq([root], r)) + self.assertEqual(r, {}) + self.assertFalse(pw.match_seq([n1], r)) + self.assertEqual(r, {}) + self.assertTrue(pw.match_seq([n2], r)) + # These are easier to debug + self.assertEqual(sorted(r.keys()), ["pl", "pn", "pw"]) + self.assertEqual(r["pl"], l1) + self.assertEqual(r["pn"], n2) + self.assertEqual(r["pw"], [n2]) + # But this is equivalent + self.assertEqual(r, {"pl": l1, "pn": n2, "pw": [n2]}) + r = {} + self.assertTrue(pw.match_seq([l1, l3], r)) + self.assertEqual(r, {"pl": l3, "pw": [l1, l3]}) + self.assert_(r["pl"] is l3) + r = {} + + def testGenerateMatches(self): + la = pytree.Leaf(1, "a") + lb = pytree.Leaf(1, "b") + lc = pytree.Leaf(1, "c") + ld = pytree.Leaf(1, "d") + le = pytree.Leaf(1, "e") + lf = pytree.Leaf(1, "f") + leaves = [la, lb, lc, ld, le, lf] + root = pytree.Node(1000, leaves) + pa = pytree.LeafPattern(1, "a", "pa") + pb = pytree.LeafPattern(1, "b", "pb") + pc = pytree.LeafPattern(1, "c", "pc") + pd = pytree.LeafPattern(1, "d", "pd") + pe = pytree.LeafPattern(1, "e", "pe") + pf = pytree.LeafPattern(1, "f", "pf") + pw = pytree.WildcardPattern([[pa, pb, pc], [pd, pe], + [pa, pb], [pc, pd], [pe, pf]], + min=1, max=4, name="pw") + self.assertEqual([x[0] for x in pw.generate_matches(leaves)], + [3, 5, 2, 4, 6]) + pr = pytree.NodePattern(type=1000, content=[pw], name="pr") + matches = list(pytree.generate_matches([pr], [root])) + self.assertEqual(len(matches), 1) + c, r = matches[0] + self.assertEqual(c, 1) + self.assertEqual(str(r["pr"]), "abcdef") + self.assertEqual(r["pw"], [la, lb, lc, ld, le, lf]) + for c in "abcdef": + self.assertEqual(r["p" + c], pytree.Leaf(1, c)) + + def testHasKeyExample(self): + pattern = pytree.NodePattern(331, + (pytree.LeafPattern(7), + pytree.WildcardPattern(name="args"), + pytree.LeafPattern(8))) + l1 = pytree.Leaf(7, "(") + l2 = pytree.Leaf(3, "x") + l3 = pytree.Leaf(8, ")") + node = pytree.Node(331, [l1, l2, l3]) + r = {} + self.assert_(pattern.match(node, r)) + self.assertEqual(r["args"], [l2]) + + +if __name__ == "__main__": + import __main__ + support.run_all_tests(__main__) Added: sandbox/trunk/refactor_pkg/refactor/tests/test_refactor.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/tests/test_refactor.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,168 @@ +""" +Unit tests for refactor.py. +""" + +import sys +import os +import operator +import StringIO +import tempfile +import unittest + +from .. import refactor, pygram, fixer_base + +from . import support + + +FIXER_DIR = os.path.join(os.path.dirname(__file__), "data/fixers") + +sys.path.append(FIXER_DIR) +try: + _DEFAULT_FIXERS = refactor.get_fixers_from_package("myfixes") +finally: + sys.path.pop() + +class TestRefactoringTool(unittest.TestCase): + + def setUp(self): + sys.path.append(FIXER_DIR) + + def tearDown(self): + sys.path.pop() + + def check_instances(self, instances, classes): + for inst, cls in zip(instances, classes): + if not isinstance(inst, cls): + self.fail("%s are not instances of %s" % instances, classes) + + def rt(self, options=None, fixers=_DEFAULT_FIXERS, explicit=None): + return refactor.RefactoringTool(fixers, options, explicit) + + def test_print_function_option(self): + gram = pygram.python_grammar + save = gram.keywords["print"] + try: + rt = self.rt({"print_function" : True}) + self.assertRaises(KeyError, operator.itemgetter("print"), + gram.keywords) + finally: + gram.keywords["print"] = save + + def test_fixer_loading_helpers(self): + contents = ["explicit", "first", "last", "parrot", "preorder"] + non_prefixed = refactor.get_all_fix_names("myfixes") + prefixed = refactor.get_all_fix_names("myfixes", False) + full_names = refactor.get_fixers_from_package("myfixes") + self.assertEqual(prefixed, ["fix_" + name for name in contents]) + self.assertEqual(non_prefixed, contents) + self.assertEqual(full_names, + ["myfixes.fix_" + name for name in contents]) + + def test_get_headnode_dict(self): + class NoneFix(fixer_base.BaseFix): + PATTERN = None + + class FileInputFix(fixer_base.BaseFix): + PATTERN = "file_input< any * >" + + no_head = NoneFix({}, []) + with_head = FileInputFix({}, []) + d = refactor.get_headnode_dict([no_head, with_head]) + expected = {None: [no_head], + pygram.python_symbols.file_input : [with_head]} + self.assertEqual(d, expected) + + def test_fixer_loading(self): + from myfixes.fix_first import FixFirst + from myfixes.fix_last import FixLast + from myfixes.fix_parrot import FixParrot + from myfixes.fix_preorder import FixPreorder + + rt = self.rt() + pre, post = rt.get_fixers() + + self.check_instances(pre, [FixPreorder]) + self.check_instances(post, [FixFirst, FixParrot, FixLast]) + + def test_naughty_fixers(self): + self.assertRaises(ImportError, self.rt, fixers=["not_here"]) + self.assertRaises(refactor.FixerError, self.rt, fixers=["no_fixer_cls"]) + self.assertRaises(refactor.FixerError, self.rt, fixers=["bad_order"]) + + def test_refactor_string(self): + rt = self.rt() + input = "def parrot(): pass\n\n" + tree = rt.refactor_string(input, "") + self.assertNotEqual(str(tree), input) + + input = "def f(): pass\n\n" + tree = rt.refactor_string(input, "") + self.assertEqual(str(tree), input) + + def test_refactor_stdin(self): + + class MyRT(refactor.RefactoringTool): + + def print_output(self, lines): + diff_lines.extend(lines) + + diff_lines = [] + rt = MyRT(_DEFAULT_FIXERS) + save = sys.stdin + sys.stdin = StringIO.StringIO("def parrot(): pass\n\n") + try: + rt.refactor_stdin() + finally: + sys.stdin = save + expected = """--- (original) ++++ (refactored) +@@ -1,2 +1,2 @@ +-def parrot(): pass ++def cheese(): pass""".splitlines() + self.assertEqual(diff_lines[:-1], expected) + + def test_refactor_file(self): + test_file = os.path.join(FIXER_DIR, "parrot_example.py") + old_contents = open(test_file, "r").read() + rt = self.rt() + + rt.refactor_file(test_file) + self.assertEqual(old_contents, open(test_file, "r").read()) + + rt.refactor_file(test_file, True) + try: + self.assertNotEqual(old_contents, open(test_file, "r").read()) + finally: + open(test_file, "w").write(old_contents) + + def test_refactor_docstring(self): + rt = self.rt() + + def example(): + """ + >>> example() + 42 + """ + out = rt.refactor_docstring(example.__doc__, "") + self.assertEqual(out, example.__doc__) + + def parrot(): + """ + >>> def parrot(): + ... return 43 + """ + out = rt.refactor_docstring(parrot.__doc__, "") + self.assertNotEqual(out, parrot.__doc__) + + def test_explicit(self): + from myfixes.fix_explicit import FixExplicit + + rt = self.rt(fixers=["myfixes.fix_explicit"]) + self.assertEqual(len(rt.post_order), 0) + + rt = self.rt(explicit=["myfixes.fix_explicit"]) + for fix in rt.post_order: + if isinstance(fix, FixExplicit): + break + else: + self.fail("explicit fixer not loaded") Added: sandbox/trunk/refactor_pkg/refactor/tests/test_util.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/tests/test_util.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,559 @@ +#!/usr/bin/env python2.5 +""" Test suite for the code in fixes.util """ +# Author: Collin Winter + +# Testing imports +from . import support + +# Python imports +import os.path + +# Local imports +from .. import pytree +from .. import fixer_util +from ..fixer_util import Attr, Name + + +def parse(code, strip_levels=0): + # The topmost node is file_input, which we don't care about. + # The next-topmost node is a *_stmt node, which we also don't care about + tree = support.parse_string(code) + for i in range(strip_levels): + tree = tree.children[0] + tree.parent = None + return tree + +class MacroTestCase(support.TestCase): + def assertStr(self, node, string): + if isinstance(node, (tuple, list)): + node = pytree.Node(fixer_util.syms.simple_stmt, node) + self.assertEqual(str(node), string) + + +class Test_is_tuple(support.TestCase): + def is_tuple(self, string): + return fixer_util.is_tuple(parse(string, strip_levels=2)) + + def test_valid(self): + self.failUnless(self.is_tuple("(a, b)")) + self.failUnless(self.is_tuple("(a, (b, c))")) + self.failUnless(self.is_tuple("((a, (b, c)),)")) + self.failUnless(self.is_tuple("(a,)")) + self.failUnless(self.is_tuple("()")) + + def test_invalid(self): + self.failIf(self.is_tuple("(a)")) + self.failIf(self.is_tuple("('foo') % (b, c)")) + + +class Test_is_list(support.TestCase): + def is_list(self, string): + return fixer_util.is_list(parse(string, strip_levels=2)) + + def test_valid(self): + self.failUnless(self.is_list("[]")) + self.failUnless(self.is_list("[a]")) + self.failUnless(self.is_list("[a, b]")) + self.failUnless(self.is_list("[a, [b, c]]")) + self.failUnless(self.is_list("[[a, [b, c]],]")) + + def test_invalid(self): + self.failIf(self.is_list("[]+[]")) + + +class Test_Attr(MacroTestCase): + def test(self): + call = parse("foo()", strip_levels=2) + + self.assertStr(Attr(Name("a"), Name("b")), "a.b") + self.assertStr(Attr(call, Name("b")), "foo().b") + + def test_returns(self): + attr = Attr(Name("a"), Name("b")) + self.assertEqual(type(attr), list) + + +class Test_Name(MacroTestCase): + def test(self): + self.assertStr(Name("a"), "a") + self.assertStr(Name("foo.foo().bar"), "foo.foo().bar") + self.assertStr(Name("a", prefix="b"), "ba") + + +class Test_does_tree_import(support.TestCase): + def _find_bind_rec(self, name, node): + # Search a tree for a binding -- used to find the starting + # point for these tests. + c = fixer_util.find_binding(name, node) + if c: return c + for child in node.children: + c = self._find_bind_rec(name, child) + if c: return c + + def does_tree_import(self, package, name, string): + node = parse(string) + # Find the binding of start -- that's what we'll go from + node = self._find_bind_rec('start', node) + return fixer_util.does_tree_import(package, name, node) + + def try_with(self, string): + failing_tests = (("a", "a", "from a import b"), + ("a.d", "a", "from a.d import b"), + ("d.a", "a", "from d.a import b"), + (None, "a", "import b"), + (None, "a", "import b, c, d")) + for package, name, import_ in failing_tests: + n = self.does_tree_import(package, name, import_ + "\n" + string) + self.failIf(n) + n = self.does_tree_import(package, name, string + "\n" + import_) + self.failIf(n) + + passing_tests = (("a", "a", "from a import a"), + ("x", "a", "from x import a"), + ("x", "a", "from x import b, c, a, d"), + ("x.b", "a", "from x.b import a"), + ("x.b", "a", "from x.b import b, c, a, d"), + (None, "a", "import a"), + (None, "a", "import b, c, a, d")) + for package, name, import_ in passing_tests: + n = self.does_tree_import(package, name, import_ + "\n" + string) + self.failUnless(n) + n = self.does_tree_import(package, name, string + "\n" + import_) + self.failUnless(n) + + def test_in_function(self): + self.try_with("def foo():\n\tbar.baz()\n\tstart=3") + +class Test_find_binding(support.TestCase): + def find_binding(self, name, string, package=None): + return fixer_util.find_binding(name, parse(string), package) + + def test_simple_assignment(self): + self.failUnless(self.find_binding("a", "a = b")) + self.failUnless(self.find_binding("a", "a = [b, c, d]")) + self.failUnless(self.find_binding("a", "a = foo()")) + self.failUnless(self.find_binding("a", "a = foo().foo.foo[6][foo]")) + self.failIf(self.find_binding("a", "foo = a")) + self.failIf(self.find_binding("a", "foo = (a, b, c)")) + + def test_tuple_assignment(self): + self.failUnless(self.find_binding("a", "(a,) = b")) + self.failUnless(self.find_binding("a", "(a, b, c) = [b, c, d]")) + self.failUnless(self.find_binding("a", "(c, (d, a), b) = foo()")) + self.failUnless(self.find_binding("a", "(a, b) = foo().foo[6][foo]")) + self.failIf(self.find_binding("a", "(foo, b) = (b, a)")) + self.failIf(self.find_binding("a", "(foo, (b, c)) = (a, b, c)")) + + def test_list_assignment(self): + self.failUnless(self.find_binding("a", "[a] = b")) + self.failUnless(self.find_binding("a", "[a, b, c] = [b, c, d]")) + self.failUnless(self.find_binding("a", "[c, [d, a], b] = foo()")) + self.failUnless(self.find_binding("a", "[a, b] = foo().foo[a][foo]")) + self.failIf(self.find_binding("a", "[foo, b] = (b, a)")) + self.failIf(self.find_binding("a", "[foo, [b, c]] = (a, b, c)")) + + def test_invalid_assignments(self): + self.failIf(self.find_binding("a", "foo.a = 5")) + self.failIf(self.find_binding("a", "foo[a] = 5")) + self.failIf(self.find_binding("a", "foo(a) = 5")) + self.failIf(self.find_binding("a", "foo(a, b) = 5")) + + def test_simple_import(self): + self.failUnless(self.find_binding("a", "import a")) + self.failUnless(self.find_binding("a", "import b, c, a, d")) + self.failIf(self.find_binding("a", "import b")) + self.failIf(self.find_binding("a", "import b, c, d")) + + def test_from_import(self): + self.failUnless(self.find_binding("a", "from x import a")) + self.failUnless(self.find_binding("a", "from a import a")) + self.failUnless(self.find_binding("a", "from x import b, c, a, d")) + self.failUnless(self.find_binding("a", "from x.b import a")) + self.failUnless(self.find_binding("a", "from x.b import b, c, a, d")) + self.failIf(self.find_binding("a", "from a import b")) + self.failIf(self.find_binding("a", "from a.d import b")) + self.failIf(self.find_binding("a", "from d.a import b")) + + def test_import_as(self): + self.failUnless(self.find_binding("a", "import b as a")) + self.failUnless(self.find_binding("a", "import b as a, c, a as f, d")) + self.failIf(self.find_binding("a", "import a as f")) + self.failIf(self.find_binding("a", "import b, c as f, d as e")) + + def test_from_import_as(self): + self.failUnless(self.find_binding("a", "from x import b as a")) + self.failUnless(self.find_binding("a", "from x import g as a, d as b")) + self.failUnless(self.find_binding("a", "from x.b import t as a")) + self.failUnless(self.find_binding("a", "from x.b import g as a, d")) + self.failIf(self.find_binding("a", "from a import b as t")) + self.failIf(self.find_binding("a", "from a.d import b as t")) + self.failIf(self.find_binding("a", "from d.a import b as t")) + + def test_simple_import_with_package(self): + self.failUnless(self.find_binding("b", "import b")) + self.failUnless(self.find_binding("b", "import b, c, d")) + self.failIf(self.find_binding("b", "import b", "b")) + self.failIf(self.find_binding("b", "import b, c, d", "c")) + + def test_from_import_with_package(self): + self.failUnless(self.find_binding("a", "from x import a", "x")) + self.failUnless(self.find_binding("a", "from a import a", "a")) + self.failUnless(self.find_binding("a", "from x import *", "x")) + self.failUnless(self.find_binding("a", "from x import b, c, a, d", "x")) + self.failUnless(self.find_binding("a", "from x.b import a", "x.b")) + self.failUnless(self.find_binding("a", "from x.b import *", "x.b")) + self.failUnless(self.find_binding("a", "from x.b import b, c, a, d", "x.b")) + self.failIf(self.find_binding("a", "from a import b", "a")) + self.failIf(self.find_binding("a", "from a.d import b", "a.d")) + self.failIf(self.find_binding("a", "from d.a import b", "a.d")) + self.failIf(self.find_binding("a", "from x.y import *", "a.b")) + + def test_import_as_with_package(self): + self.failIf(self.find_binding("a", "import b.c as a", "b.c")) + self.failIf(self.find_binding("a", "import a as f", "f")) + self.failIf(self.find_binding("a", "import a as f", "a")) + + def test_from_import_as_with_package(self): + # Because it would take a lot of special-case code in the fixers + # to deal with from foo import bar as baz, we'll simply always + # fail if there is an "from ... import ... as ..." + self.failIf(self.find_binding("a", "from x import b as a", "x")) + self.failIf(self.find_binding("a", "from x import g as a, d as b", "x")) + self.failIf(self.find_binding("a", "from x.b import t as a", "x.b")) + self.failIf(self.find_binding("a", "from x.b import g as a, d", "x.b")) + self.failIf(self.find_binding("a", "from a import b as t", "a")) + self.failIf(self.find_binding("a", "from a import b as t", "b")) + self.failIf(self.find_binding("a", "from a import b as t", "t")) + + def test_function_def(self): + self.failUnless(self.find_binding("a", "def a(): pass")) + self.failUnless(self.find_binding("a", "def a(b, c, d): pass")) + self.failUnless(self.find_binding("a", "def a(): b = 7")) + self.failIf(self.find_binding("a", "def d(b, (c, a), e): pass")) + self.failIf(self.find_binding("a", "def d(a=7): pass")) + self.failIf(self.find_binding("a", "def d(a): pass")) + self.failIf(self.find_binding("a", "def d(): a = 7")) + + s = """ + def d(): + def a(): + pass""" + self.failIf(self.find_binding("a", s)) + + def test_class_def(self): + self.failUnless(self.find_binding("a", "class a: pass")) + self.failUnless(self.find_binding("a", "class a(): pass")) + self.failUnless(self.find_binding("a", "class a(b): pass")) + self.failUnless(self.find_binding("a", "class a(b, c=8): pass")) + self.failIf(self.find_binding("a", "class d: pass")) + self.failIf(self.find_binding("a", "class d(a): pass")) + self.failIf(self.find_binding("a", "class d(b, a=7): pass")) + self.failIf(self.find_binding("a", "class d(b, *a): pass")) + self.failIf(self.find_binding("a", "class d(b, **a): pass")) + self.failIf(self.find_binding("a", "class d: a = 7")) + + s = """ + class d(): + class a(): + pass""" + self.failIf(self.find_binding("a", s)) + + def test_for(self): + self.failUnless(self.find_binding("a", "for a in r: pass")) + self.failUnless(self.find_binding("a", "for a, b in r: pass")) + self.failUnless(self.find_binding("a", "for (a, b) in r: pass")) + self.failUnless(self.find_binding("a", "for c, (a,) in r: pass")) + self.failUnless(self.find_binding("a", "for c, (a, b) in r: pass")) + self.failUnless(self.find_binding("a", "for c in r: a = c")) + self.failIf(self.find_binding("a", "for c in a: pass")) + + def test_for_nested(self): + s = """ + for b in r: + for a in b: + pass""" + self.failUnless(self.find_binding("a", s)) + + s = """ + for b in r: + for a, c in b: + pass""" + self.failUnless(self.find_binding("a", s)) + + s = """ + for b in r: + for (a, c) in b: + pass""" + self.failUnless(self.find_binding("a", s)) + + s = """ + for b in r: + for (a,) in b: + pass""" + self.failUnless(self.find_binding("a", s)) + + s = """ + for b in r: + for c, (a, d) in b: + pass""" + self.failUnless(self.find_binding("a", s)) + + s = """ + for b in r: + for c in b: + a = 7""" + self.failUnless(self.find_binding("a", s)) + + s = """ + for b in r: + for c in b: + d = a""" + self.failIf(self.find_binding("a", s)) + + s = """ + for b in r: + for c in a: + d = 7""" + self.failIf(self.find_binding("a", s)) + + def test_if(self): + self.failUnless(self.find_binding("a", "if b in r: a = c")) + self.failIf(self.find_binding("a", "if a in r: d = e")) + + def test_if_nested(self): + s = """ + if b in r: + if c in d: + a = c""" + self.failUnless(self.find_binding("a", s)) + + s = """ + if b in r: + if c in d: + c = a""" + self.failIf(self.find_binding("a", s)) + + def test_while(self): + self.failUnless(self.find_binding("a", "while b in r: a = c")) + self.failIf(self.find_binding("a", "while a in r: d = e")) + + def test_while_nested(self): + s = """ + while b in r: + while c in d: + a = c""" + self.failUnless(self.find_binding("a", s)) + + s = """ + while b in r: + while c in d: + c = a""" + self.failIf(self.find_binding("a", s)) + + def test_try_except(self): + s = """ + try: + a = 6 + except: + b = 8""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + b = 8 + except: + a = 6""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + b = 8 + except KeyError: + pass + except: + a = 6""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + b = 8 + except: + b = 6""" + self.failIf(self.find_binding("a", s)) + + def test_try_except_nested(self): + s = """ + try: + try: + a = 6 + except: + pass + except: + b = 8""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + b = 8 + except: + try: + a = 6 + except: + pass""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + b = 8 + except: + try: + pass + except: + a = 6""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + try: + b = 8 + except KeyError: + pass + except: + a = 6 + except: + pass""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + pass + except: + try: + b = 8 + except KeyError: + pass + except: + a = 6""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + b = 8 + except: + b = 6""" + self.failIf(self.find_binding("a", s)) + + s = """ + try: + try: + b = 8 + except: + c = d + except: + try: + b = 6 + except: + t = 8 + except: + o = y""" + self.failIf(self.find_binding("a", s)) + + def test_try_except_finally(self): + s = """ + try: + c = 6 + except: + b = 8 + finally: + a = 9""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + b = 8 + finally: + a = 6""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + b = 8 + finally: + b = 6""" + self.failIf(self.find_binding("a", s)) + + s = """ + try: + b = 8 + except: + b = 9 + finally: + b = 6""" + self.failIf(self.find_binding("a", s)) + + def test_try_except_finally_nested(self): + s = """ + try: + c = 6 + except: + b = 8 + finally: + try: + a = 9 + except: + b = 9 + finally: + c = 9""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + b = 8 + finally: + try: + pass + finally: + a = 6""" + self.failUnless(self.find_binding("a", s)) + + s = """ + try: + b = 8 + finally: + try: + b = 6 + finally: + b = 7""" + self.failIf(self.find_binding("a", s)) + +class Test_touch_import(support.TestCase): + + def test_after_docstring(self): + node = parse('"""foo"""\nbar()') + fixer_util.touch_import(None, "foo", node) + self.assertEqual(str(node), '"""foo"""\nimport foo\nbar()\n\n') + + def test_after_imports(self): + node = parse('"""foo"""\nimport bar\nbar()') + fixer_util.touch_import(None, "foo", node) + self.assertEqual(str(node), '"""foo"""\nimport bar\nimport foo\nbar()\n\n') + + def test_beginning(self): + node = parse('bar()') + fixer_util.touch_import(None, "foo", node) + self.assertEqual(str(node), 'import foo\nbar()\n\n') + + 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') + + def test_name_import(self): + node = parse('bar()') + fixer_util.touch_import(None, "cgi", node) + self.assertEqual(str(node), 'import cgi\nbar()\n\n') + + +if __name__ == "__main__": + import __main__ + support.run_all_tests(__main__) Added: sandbox/trunk/refactor_pkg/scripts/benchmark.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/scripts/benchmark.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,58 @@ +#!/usr/bin/env python2.5 +""" +This is a benchmarking script to test the speed of 2to3's pattern matching +system. It's equivalent to "refactor.py -f all" for every Python module +in sys.modules, but without engaging the actual transformations. +""" + +__author__ = "Collin Winter " + +# Python imports +import os.path +import sys +from time import time + +# Test imports +from .support import adjust_path +adjust_path() + +# Local imports +from .. import refactor + +### Mock code for refactor.py and the fixers +############################################################################### +class Options: + def __init__(self, **kwargs): + for k, v in kwargs.items(): + setattr(self, k, v) + + self.verbose = False + +def dummy_transform(*args, **kwargs): + pass + +### Collect list of modules to match against +############################################################################### +files = [] +for mod in sys.modules.values(): + if mod is None or not hasattr(mod, '__file__'): + continue + f = mod.__file__ + if f.endswith('.pyc'): + f = f[:-1] + if f.endswith('.py'): + files.append(f) + +### Set up refactor and run the benchmark +############################################################################### +options = Options(fix=["all"], print_function=False, doctests_only=False) +refactor = refactor.RefactoringTool(options) +for fixer in refactor.fixers: + # We don't want them to actually fix the tree, just match against it. + fixer.transform = dummy_transform + +t = time() +for f in files: + print "Matching", f + refactor.refactor_file(f) +print "%d seconds to match %d files" % (time() - t, len(sys.modules)) Added: sandbox/trunk/refactor_pkg/scripts/find_pattern.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/scripts/find_pattern.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,102 @@ +#!/usr/bin/env python + +"""Script that makes determining PATTERN for a new fix much easier. + +Figuring out exactly what PATTERN I want for a given fixer class is +getting tedious. This script will step through each possible subtree +for a given string, allowing you to select which one you want. It will +then try to figure out an appropriate pattern to match that tree. This +pattern will require some editing (it will be overly restrictive) but +should provide a solid base to work with and handle the tricky parts. + +Usage: + + python find_pattern.py "g.throw(E, V, T)" + +This will step through each subtree in the parse. To reject a +candidate subtree, hit enter; to accept a candidate, hit "y" and +enter. The pattern will be spit out to stdout. + +For example, the above will yield a succession of possible snippets, +skipping all leaf-only trees. I accept + +'g.throw(E, V, T)' + +This causes find_pattern to spit out + +power< 'g' trailer< '.' 'throw' > + trailer< '(' arglist< 'E' ',' 'V' ',' 'T' > ')' > > + + +Some minor tweaks later, I'm left with + +power< any trailer< '.' 'throw' > + trailer< '(' args=arglist< exc=any ',' val=any [',' tb=any] > ')' > > + +which is exactly what I was after. + +Larger snippets can be placed in a file (as opposed to a command-line +arg) and processed with the -f option. +""" + +__author__ = "Collin Winter " + +# Python imports +import optparse +import sys +from StringIO import StringIO + +# Local imports +from refactor import pytree +from refactor import pgen2 +from refactor.pygram import python_symbols, python_grammar + +def main(args): + parser = optparse.OptionParser(usage="find_pattern.py [options] [string]") + parser.add_option("-f", "--file", action="store", + help="Read a code snippet from the specified file") + parser.add_option("-p", "--print-function", action="store_true", + help="Modify the grammar so that print() is a function") + + # Parse command line arguments + options, args = parser.parse_args(args) + + if options.print_function: + del python_grammar.keywords["print"] + + driver = pgen2.driver.Driver(python_grammar, convert=pytree.convert) + if options.file: + tree = driver.parse_file(options.file) + elif len(args) > 1: + tree = driver.parse_stream(StringIO(args[1] + "\n")) + else: + print >>sys.stderr, "You must specify an input file or an input string" + return 1 + + examine_tree(tree) + return 0 + +def examine_tree(tree): + for node in tree.post_order(): + if isinstance(node, pytree.Leaf): + continue + print repr(str(node)) + verdict = raw_input() + if verdict.strip(): + print find_pattern(node) + return + +def find_pattern(node): + if isinstance(node, pytree.Leaf): + return repr(node.value) + + return find_symbol(node.type) + \ + "< " + " ".join(find_pattern(n) for n in node.children) + " >" + +def find_symbol(sym): + for n, v in python_symbols.__dict__.items(): + if v == sym: + return n + +if __name__ == "__main__": + sys.exit(main(sys.argv)) Added: sandbox/trunk/refactor_pkg/setup.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/setup.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,15 @@ +from distutils.core import setup + +setup( + name="2to3", + packages=['lib2to3','lib2to3.fixes','lib2to3.pgen2'], + package_data={'lib2to3':['lib2to3/Grammar.txt','lib2to3/PatternGrammar.txt']}, + scripts=["2to3"] +) + +setup( + name="refactor", + packages=['refactor','refactor.fixes','refactor.fixes.from2','refactor.fixes.from3','refactor.pgen2'], + package_data={'refactor':['Grammar.txt','PatternGrammar.txt']}, + scripts=["3to2"] +) Added: sandbox/trunk/refactor_pkg/test.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/test.py Wed Apr 1 21:02:05 2009 @@ -0,0 +1,68 @@ +#!/usr/bin/env python2.5 + +"""Main test file for refactor (2to3 and back again). + +Running "python test.py" will run all tests in tests/test_*.py. +""" +# Original Author: Collin Winter + +import unittest +from optparse import OptionParser, OptionGroup +from sys import exit + +# Note more imports below, based on optparse output. + +usage = "usage: %prog [options] arg" +usage += "\n\narg can be:\n" +usage += "test suite: run tests in refactor/tests/\n" +usage += "test class: run tests in .\n" +usage += "(default: run all tests in refactor/tests/test_*.py)" + +parser = OptionParser(usage=usage) +parser.add_option("--source", + dest="source", + help="source version of Python to refactor") +parser.add_option("--target", + dest="target", + help="target version of Python") +parser.add_option("--base", + dest="base", default="refactor", + help="base package, e.g. lib2to3 or refactor") + +(options, args) = parser.parse_args() + +# It's too late at night to figure out why __import__ is failing. +exec "from %s import tests" % options.base +exec "from %s.tests import support" % options.base +exec "from %s.tests.test_fixers import FixerTestCase as Fixer" % options.base + +old_version = support.parse_version(options.source) +new_version = support.parse_version(options.target) + +if old_version: + Fixer.old_version = old_version +if new_version: + Fixer.new_version = new_version + +if len(args) > 0: + arg = args[0] + mod = tests + for m in arg.split("."): + mod = getattr(mod, m, None) + if not mod: + print "Error importing %s" %(m) + exit(1) + + if arg.find(".") == -1: + # Just the module was specified, load all the tests + suite = unittest.TestLoader().loadTestsFromModule(mod) + else: + # A class was specified, load that + suite = unittest.makeSuite(mod) +else: + suite = tests.all_tests + +try: + tests.support.run_all_tests(tests=suite) +except KeyboardInterrupt: + pass From python-checkins at python.org Wed Apr 1 21:03:31 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 1 Apr 2009 21:03:31 +0200 (CEST) Subject: [Python-checkins] r70973 - in python/branches/release30-maint: Lib/_abcoll.py Lib/test/test_collections.py Misc/NEWS Message-ID: <20090401190331.13D651E4402@bag.python.org> Author: raymond.hettinger Date: Wed Apr 1 21:03:30 2009 New Revision: 70973 Log: Issue #5647: MutableSet.__iand__() no longer mutates self during iteration. Modified: python/branches/release30-maint/Lib/_abcoll.py python/branches/release30-maint/Lib/test/test_collections.py python/branches/release30-maint/Misc/NEWS Modified: python/branches/release30-maint/Lib/_abcoll.py ============================================================================== --- python/branches/release30-maint/Lib/_abcoll.py (original) +++ python/branches/release30-maint/Lib/_abcoll.py Wed Apr 1 21:03:30 2009 @@ -320,10 +320,9 @@ self.add(value) return self - def __iand__(self, c: Container): - for value in self: - if value not in c: - self.discard(value) + def __iand__(self, it: Iterable): + for value in (self - it): + self.discard(value) return self def __ixor__(self, it: Iterable): Modified: python/branches/release30-maint/Lib/test/test_collections.py ============================================================================== --- python/branches/release30-maint/Lib/test/test_collections.py (original) +++ python/branches/release30-maint/Lib/test/test_collections.py Wed Apr 1 21:03:30 2009 @@ -312,6 +312,25 @@ B.register(C) self.failUnless(issubclass(C, B)) +class WithSet(MutableSet): + + def __init__(self, it=()): + self.data = set(it) + + def __len__(self): + return len(self.data) + + def __iter__(self): + return iter(self.data) + + def __contains__(self, item): + return item in self.data + + def add(self, item): + self.data.add(item) + + def discard(self, item): + self.data.discard(item) class TestCollectionABCs(ABCTestCase): @@ -348,6 +367,12 @@ self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__', 'add', 'discard') + def test_issue_5647(self): + # MutableSet.__iand__ mutated the set during iteration + s = WithSet('abcd') + s &= WithSet('cdef') # This used to fail + self.assertEqual(set(s), set('cd')) + def test_issue_4920(self): # MutableSet.pop() method did not work class MySet(collections.MutableSet): Modified: python/branches/release30-maint/Misc/NEWS ============================================================================== --- python/branches/release30-maint/Misc/NEWS (original) +++ python/branches/release30-maint/Misc/NEWS Wed Apr 1 21:03:30 2009 @@ -33,6 +33,8 @@ - Issue #5619: Multiprocessing children disobey the debug flag and causes popups on windows buildbots. Patch applied to work around this issue. +- Issue #5647: MutableSet.__iand__() no longer mutates self during iteration. + - Issue #5387: Fixed mmap.move crash by integer overflow. - Issue #5595: Fix UnboundedLocalError in ntpath.ismount(). From python-checkins at python.org Wed Apr 1 21:05:50 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 1 Apr 2009 21:05:50 +0200 (CEST) Subject: [Python-checkins] r70974 - in python/branches/py3k: Lib/_abcoll.py Lib/test/test_collections.py Misc/NEWS Message-ID: <20090401190550.EC77F1E4070@bag.python.org> Author: raymond.hettinger Date: Wed Apr 1 21:05:50 2009 New Revision: 70974 Log: Issue #5647: MutableSet.__iand__() no longer mutates self during iteration. Modified: python/branches/py3k/Lib/_abcoll.py python/branches/py3k/Lib/test/test_collections.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/_abcoll.py ============================================================================== --- python/branches/py3k/Lib/_abcoll.py (original) +++ python/branches/py3k/Lib/_abcoll.py Wed Apr 1 21:05:50 2009 @@ -320,10 +320,9 @@ self.add(value) return self - def __iand__(self, c: Container): - for value in self: - if value not in c: - self.discard(value) + def __iand__(self, it: Iterable): + for value in (self - it): + self.discard(value) return self def __ixor__(self, it: Iterable): Modified: python/branches/py3k/Lib/test/test_collections.py ============================================================================== --- python/branches/py3k/Lib/test/test_collections.py (original) +++ python/branches/py3k/Lib/test/test_collections.py Wed Apr 1 21:05:50 2009 @@ -327,6 +327,25 @@ B.register(C) self.failUnless(issubclass(C, B)) +class WithSet(MutableSet): + + def __init__(self, it=()): + self.data = set(it) + + def __len__(self): + return len(self.data) + + def __iter__(self): + return iter(self.data) + + def __contains__(self, item): + return item in self.data + + def add(self, item): + self.data.add(item) + + def discard(self, item): + self.data.discard(item) class TestCollectionABCs(ABCTestCase): @@ -363,6 +382,12 @@ self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__', 'add', 'discard') + def test_issue_5647(self): + # MutableSet.__iand__ mutated the set during iteration + s = WithSet('abcd') + s &= WithSet('cdef') # This used to fail + self.assertEqual(set(s), set('cd')) + def test_issue_4920(self): # MutableSet.pop() method did not work class MySet(collections.MutableSet): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Apr 1 21:05:50 2009 @@ -55,6 +55,8 @@ Library ------- +- Issue #5647: MutableSet.__iand__() no longer mutates self during iteration. + - Issue #5624: Fix the _winreg module name still used in several modules. - Issue #5628: Fix io.TextIOWrapper.read() with a unreadable buffer. From buildbot at python.org Wed Apr 1 21:11:23 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 01 Apr 2009 19:11:23 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 2.6 Message-ID: <20090401191123.998711E433C@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%202.6/builds/202 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: jesse.noller BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Wed Apr 1 21:57:10 2009 From: python-checkins at python.org (brett.cannon) Date: Wed, 1 Apr 2009 21:57:10 +0200 (CEST) Subject: [Python-checkins] r70975 - in python/trunk: Lib/test/test_logging.py Misc/NEWS Message-ID: <20090401195710.9E84F1E407C@bag.python.org> Author: brett.cannon Date: Wed Apr 1 21:57:10 2009 New Revision: 70975 Log: test_logging was blindly clearing the warnings filter. This caused PendingDeprecationWarnings to be spewed all over by unittest.failIf*(). Fix moves over to using warnings.catch_warning to protect the warnings filter. Modified: python/trunk/Lib/test/test_logging.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/test/test_logging.py ============================================================================== --- python/trunk/Lib/test/test_logging.py (original) +++ python/trunk/Lib/test/test_logging.py Wed Apr 1 21:57:10 2009 @@ -910,30 +910,32 @@ class WarningsTest(BaseTest): + def test_warnings(self): logging.captureWarnings(True) - warnings.filterwarnings("always", category=UserWarning) - try: - file = cStringIO.StringIO() - h = logging.StreamHandler(file) - logger = logging.getLogger("py.warnings") - logger.addHandler(h) - warnings.warn("I'm warning you...") - logger.removeHandler(h) - s = file.getvalue() - h.close() - self.assertTrue(s.find("UserWarning: I'm warning you...\n") > 0) - - #See if an explicit file uses the original implementation - file = cStringIO.StringIO() - warnings.showwarning("Explicit", UserWarning, "dummy.py", 42, file, - "Dummy line") - s = file.getvalue() - file.close() - self.assertEqual(s, "dummy.py:42: UserWarning: Explicit\n Dummy line\n") - finally: - warnings.resetwarnings() - logging.captureWarnings(False) + with warnings.catch_warnings(): + warnings.filterwarnings("always", category=UserWarning) + try: + file = cStringIO.StringIO() + h = logging.StreamHandler(file) + logger = logging.getLogger("py.warnings") + logger.addHandler(h) + warnings.warn("I'm warning you...") + logger.removeHandler(h) + s = file.getvalue() + h.close() + self.assertTrue(s.find("UserWarning: I'm warning you...\n") > 0) + + #See if an explicit file uses the original implementation + file = cStringIO.StringIO() + warnings.showwarning("Explicit", UserWarning, "dummy.py", 42, + file, "Dummy line") + s = file.getvalue() + file.close() + self.assertEqual(s, + "dummy.py:42: UserWarning: Explicit\n Dummy line\n") + finally: + logging.captureWarnings(False) # Set the locale to the platform-dependent default. I have no idea # why the test does this, but in any case we save the current locale Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Apr 1 21:57:10 2009 @@ -730,6 +730,8 @@ Tests ----- +- Fix test_logging to no longer reset the warnings filter. + - Issue #5635: Fix running test_sys with tracing enabled. - regrtest no longer treats ImportError as equivalent to SkipTest. Imports From python-checkins at python.org Wed Apr 1 22:01:47 2009 From: python-checkins at python.org (brett.cannon) Date: Wed, 1 Apr 2009 22:01:47 +0200 (CEST) Subject: [Python-checkins] r70976 - in python/branches/py3k: Lib/test/test_logging.py Message-ID: <20090401200147.E5C7A1E407C@bag.python.org> Author: brett.cannon Date: Wed Apr 1 22:01:47 2009 New Revision: 70976 Log: Merged revisions 70975 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70975 | brett.cannon | 2009-04-01 12:57:10 -0700 (Wed, 01 Apr 2009) | 4 lines test_logging was blindly clearing the warnings filter. This caused PendingDeprecationWarnings to be spewed all over by unittest.failIf*(). Fix moves over to using warnings.catch_warning to protect the warnings filter. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_logging.py 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 Wed Apr 1 22:01:47 2009 @@ -910,30 +910,32 @@ class WarningsTest(BaseTest): + def test_warnings(self): logging.captureWarnings(True) - warnings.filterwarnings("always", category=UserWarning) - try: - file = io.StringIO() - h = logging.StreamHandler(file) - logger = logging.getLogger("py.warnings") - logger.addHandler(h) - warnings.warn("I'm warning you...") - logger.removeHandler(h) - s = file.getvalue() - h.close() - self.assertTrue(s.find("UserWarning: I'm warning you...\n") > 0) - - #See if an explicit file uses the original implementation - file = io.StringIO() - warnings.showwarning("Explicit", UserWarning, "dummy.py", 42, file, - "Dummy line") - s = file.getvalue() - file.close() - self.assertEqual(s, "dummy.py:42: UserWarning: Explicit\n Dummy line\n") - finally: - warnings.resetwarnings() - logging.captureWarnings(False) + with warnings.catch_warnings(): + warnings.filterwarnings("always", category=UserWarning) + try: + file = io.StringIO() + h = logging.StreamHandler(file) + logger = logging.getLogger("py.warnings") + logger.addHandler(h) + warnings.warn("I'm warning you...") + logger.removeHandler(h) + s = file.getvalue() + h.close() + self.assertTrue(s.find("UserWarning: I'm warning you...\n") > 0) + + #See if an explicit file uses the original implementation + file = io.StringIO() + warnings.showwarning("Explicit", UserWarning, "dummy.py", 42, + file, "Dummy line") + s = file.getvalue() + file.close() + self.assertEqual(s, + "dummy.py:42: UserWarning: Explicit\n Dummy line\n") + finally: + logging.captureWarnings(False) # Set the locale to the platform-dependent default. I have no idea # why the test does this, but in any case we save the current locale From python-checkins at python.org Wed Apr 1 22:20:08 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 1 Apr 2009 22:20:08 +0200 (CEST) Subject: [Python-checkins] r70977 - peps/trunk/pep-0401.txt Message-ID: <20090401202008.7A5301E407C@bag.python.org> Author: benjamin.peterson Date: Wed Apr 1 22:20:08 2009 New Revision: 70977 Log: let's not let anybody get away from the policy change Modified: peps/trunk/pep-0401.txt Modified: peps/trunk/pep-0401.txt ============================================================================== --- peps/trunk/pep-0401.txt (original) +++ peps/trunk/pep-0401.txt Wed Apr 1 22:20:08 2009 @@ -74,12 +74,12 @@ implementation will terminate with the release of Python 2.6.2 and 3.0.2. Thereafter, the reference implementation of Python will target the Parrot [1]_ virtual machine. Alternative implementations - of Python (e.g. Jython [2]_ and IronPython [3]_) are officially - discouraged but tolerated. + of Python (e.g. Jython [2]_, IronPython [3]_, and PyPy [4]_) are + officially discouraged but tolerated. -* Recognized that the Python Software Foundation [4]_ having fulfilled +* Recognized that the Python Software Foundation [5]_ having fulfilled its mission admirably, is hereby disbanded. The Python Steering - Union [5]_ (not to be confused with the Python Secret Underground, + Union [6]_ (not to be confused with the Python Secret Underground, which emphatically does not exist), is now the sole steward for all of Python's intellectual property. All PSF funds are hereby transferred to the PSU (not that PSU, the other PSU). @@ -94,9 +94,11 @@ .. [3] http://www.ironpython.com -.. [4] http://www.python.org/psf +.. [4] http://www.codespeak.net/pypy -.. [5] http://www.pythonlabs.com +.. [5] http://www.python.org/psf + +.. [6] http://www.pythonlabs.com Copyright From python-checkins at python.org Wed Apr 1 22:20:43 2009 From: python-checkins at python.org (senthil.kumaran) Date: Wed, 1 Apr 2009 22:20:43 +0200 (CEST) Subject: [Python-checkins] r70978 - in python/branches/py3k/Lib: test/test_xmlrpc.py xmlrpc/client.py xmlrpc/server.py Message-ID: <20090401202043.7A8A41E407C@bag.python.org> Author: senthil.kumaran Date: Wed Apr 1 22:20:43 2009 New Revision: 70978 Log: Fix for issue5040. Adding support for unicode message passing and tests for unicode message and test for Content-Length. Modified: python/branches/py3k/Lib/test/test_xmlrpc.py python/branches/py3k/Lib/xmlrpc/client.py python/branches/py3k/Lib/xmlrpc/server.py 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 Apr 1 22:20:43 2009 @@ -9,6 +9,7 @@ import http.client import socket import os +import re from test import support alist = [{'astring': 'foo at bar.baz.spam', @@ -352,6 +353,19 @@ # protocol error; provide additional information in test output self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) + def test_nonascii(self): + start_string = 'P\N{LATIN SMALL LETTER Y WITH CIRCUMFLEX}t' + end_string = 'h\N{LATIN SMALL LETTER O WITH HORN}n' + try: + p = xmlrpclib.ServerProxy(URL) + self.assertEqual(p.add(start_string, end_string), + start_string + end_string) + except (xmlrpclib.ProtocolError, socket.error) as e: + # ignore failures due to non-blocking socket 'unavailable' errors + if not is_unavailable_exception(e): + # protocol error; provide additional information in test output + self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) + # [ch] The test 404 is causing lots of false alarms. def XXXtest_404(self): # send POST with http.client, it should return 404 header and @@ -616,9 +630,21 @@ # need only xml self.assertRaises(xmlrpclib.Fault, xmlrpclib.loads, handle[44:]) + # Also test the content-length returned by handle_request + # Using the same test method inorder to avoid all the datapassing + # boilerplate code. + # Test for bug: http://bugs.python.org/issue5040 + + content = handle[handle.find(" ['add', 'subtract', 'multiple'] @@ -473,8 +473,6 @@ self.end_headers() else: - # Got a valid XML RPC response; convert to bytes first - response = response.encode("utf-8") self.send_response(200) self.send_header("Content-type", "text/xml") self.send_header("Content-length", str(len(response))) @@ -551,7 +549,9 @@ print('Content-Type: text/xml') print('Content-Length: %d' % len(response)) print() - sys.stdout.write(response) + sys.stdout.flush() + sys.stdout.buffer.write(response) + sys.stdout.buffer.flush() def handle_get(self): """Handle a single HTTP GET request. @@ -569,11 +569,14 @@ 'message' : message, 'explain' : explain } + response = response.encode('utf-8') print('Status: %d %s' % (code, message)) - print('Content-Type: text/html') + print('Content-Type: %s' % http.server.DEFAULT_ERROR_CONTENT_TYPE) print('Content-Length: %d' % len(response)) print() - sys.stdout.write(response) + sys.stdout.flush() + sys.stdout.buffer.write(response) + sys.stdout.buffer.flush() def handle_request(self, request_text = None): """Handle a single XML-RPC request passed through a CGI post method. @@ -814,12 +817,12 @@ self.report_404() return - response = self.server.generate_html_documentation() + response = self.server.generate_html_documentation().encode('utf-8') self.send_response(200) self.send_header("Content-type", "text/html") self.send_header("Content-length", str(len(response))) self.end_headers() - self.wfile.write(response.encode()) + self.wfile.write(response) # shut down the connection self.wfile.flush() @@ -852,12 +855,14 @@ documentation. """ - response = self.generate_html_documentation() + response = self.generate_html_documentation().encode('utf-8') print('Content-Type: text/html') print('Content-Length: %d' % len(response)) print() - sys.stdout.write(response) + sys.stdout.flush() + sys.stdout.buffer.write(response) + sys.stdout.buffer.flush() def __init__(self): CGIXMLRPCRequestHandler.__init__(self) From python-checkins at python.org Wed Apr 1 22:25:48 2009 From: python-checkins at python.org (brett.cannon) Date: Wed, 1 Apr 2009 22:25:48 +0200 (CEST) Subject: [Python-checkins] r70979 - in python/trunk: Lib/test/test_warnings.py Misc/NEWS Message-ID: <20090401202548.DF2C71E470D@bag.python.org> Author: brett.cannon Date: Wed Apr 1 22:25:48 2009 New Revision: 70979 Log: test_warnings ironically had a single test that was not protecting the warnings filter and was resetting it. Modified: python/trunk/Lib/test/test_warnings.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/test/test_warnings.py ============================================================================== --- python/trunk/Lib/test/test_warnings.py (original) +++ python/trunk/Lib/test/test_warnings.py Wed Apr 1 22:25:48 2009 @@ -460,14 +460,14 @@ self.failUnless(text in result) def test_showwarning_not_callable(self): - self.module.filterwarnings("always", category=UserWarning) - old_showwarning = self.module.showwarning - self.module.showwarning = 23 - try: - self.assertRaises(TypeError, self.module.warn, "Warning!") - finally: - self.module.showwarning = old_showwarning - self.module.resetwarnings() + with original_warnings.catch_warnings(module=self.module): + self.module.filterwarnings("always", category=UserWarning) + old_showwarning = self.module.showwarning + self.module.showwarning = 23 + try: + self.assertRaises(TypeError, self.module.warn, "Warning!") + finally: + self.module.showwarning = old_showwarning def test_show_warning_output(self): # With showarning() missing, make sure that output is okay. Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Apr 1 22:25:48 2009 @@ -730,6 +730,8 @@ Tests ----- +- Fix test_warnings to no longer reset the warnings filter. + - Fix test_logging to no longer reset the warnings filter. - Issue #5635: Fix running test_sys with tracing enabled. From python-checkins at python.org Wed Apr 1 22:26:13 2009 From: python-checkins at python.org (jack.diederich) Date: Wed, 1 Apr 2009 22:26:13 +0200 (CEST) Subject: [Python-checkins] r70980 - in python/trunk: Lib/test/test_mmap.py Modules/mmapmodule.c Message-ID: <20090401202613.6E33D1E470D@bag.python.org> Author: jack.diederich Date: Wed Apr 1 22:26:13 2009 New Revision: 70980 Log: bounds check arguments to mmap.move(). All of them. Really. fixes crasher on OS X 10.5 Modified: python/trunk/Lib/test/test_mmap.py python/trunk/Modules/mmapmodule.c Modified: python/trunk/Lib/test/test_mmap.py ============================================================================== --- python/trunk/Lib/test/test_mmap.py (original) +++ python/trunk/Lib/test/test_mmap.py Wed Apr 1 22:26:13 2009 @@ -359,15 +359,22 @@ m.move(source, dest, size) except ValueError: pass - self.assertRaises(ValueError, m.move, -1, -1, -1) - self.assertRaises(ValueError, m.move, -1, -1, 0) - self.assertRaises(ValueError, m.move, -1, 0, -1) - self.assertRaises(ValueError, m.move, 0, -1, -1) - self.assertRaises(ValueError, m.move, -1, 0, 0) - self.assertRaises(ValueError, m.move, 0, -1, 0) - self.assertRaises(ValueError, m.move, 0, 0, -1) + + offsets = [(-1, -1, -1), (-1, -1, 0), (-1, 0, -1), (0, -1, -1), + (-1, 0, 0), (0, -1, 0), (0, 0, -1)] + for source, dest, size in offsets: + self.assertRaises(ValueError, m.move, source, dest, size) + m.close() + m = mmap.mmap(-1, 1) # single byte + self.assertRaises(ValueError, m.move, 0, 0, 2) + self.assertRaises(ValueError, m.move, 1, 0, 1) + self.assertRaises(ValueError, m.move, 0, 1, 1) + m.move(0, 0, 1) + m.move(0, 0, 0) + + def test_anonymous(self): # anonymous mmap.mmap(-1, PAGE) m = mmap.mmap(-1, PAGESIZE) Modified: python/trunk/Modules/mmapmodule.c ============================================================================== --- python/trunk/Modules/mmapmodule.c (original) +++ python/trunk/Modules/mmapmodule.c Wed Apr 1 22:26:13 2009 @@ -609,23 +609,23 @@ static PyObject * mmap_move_method(mmap_object *self, PyObject *args) { - unsigned long dest, src, count; + unsigned long dest, src, cnt; CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "kkk:move", &dest, &src, &count) || + if (!PyArg_ParseTuple(args, "kkk:move", &dest, &src, &cnt) || !is_writeable(self)) { return NULL; } else { /* bounds check the values */ - unsigned long pos = src > dest ? src : dest; - if (self->size < pos || count > self->size - pos) { + if (cnt < 0 || (cnt + dest) < cnt || (cnt + src) < cnt || + src < 0 || src > self->size || (src + cnt) > self->size || + dest < 0 || dest > self->size || (dest + cnt) > self->size) { PyErr_SetString(PyExc_ValueError, - "source or destination out of range"); + "source, destination, or count out of range"); return NULL; - } else { - memmove(self->data+dest, self->data+src, count); - Py_INCREF(Py_None); - return Py_None; } + memmove(self->data+dest, self->data+src, cnt); + Py_INCREF(Py_None); + return Py_None; } } From python-checkins at python.org Wed Apr 1 22:26:34 2009 From: python-checkins at python.org (senthil.kumaran) Date: Wed, 1 Apr 2009 22:26:34 +0200 (CEST) Subject: [Python-checkins] r70981 - in python/trunk/Lib: SimpleXMLRPCServer.py test/test_xmlrpc.py Message-ID: <20090401202634.012C81E4790@bag.python.org> Author: senthil.kumaran Date: Wed Apr 1 22:26:33 2009 New Revision: 70981 Log: Fix for issue5040. Adding test for Content-Length Modified: python/trunk/Lib/SimpleXMLRPCServer.py python/trunk/Lib/test/test_xmlrpc.py Modified: python/trunk/Lib/SimpleXMLRPCServer.py ============================================================================== --- python/trunk/Lib/SimpleXMLRPCServer.py (original) +++ python/trunk/Lib/SimpleXMLRPCServer.py Wed Apr 1 22:26:33 2009 @@ -580,7 +580,7 @@ 'explain' : explain } print 'Status: %d %s' % (code, message) - print 'Content-Type: text/html' + print 'Content-Type: %s' % BaseHTTPServer.DEFAULT_ERROR_CONTENT_TYPE print 'Content-Length: %d' % len(response) print sys.stdout.write(response) Modified: python/trunk/Lib/test/test_xmlrpc.py ============================================================================== --- python/trunk/Lib/test/test_xmlrpc.py (original) +++ python/trunk/Lib/test/test_xmlrpc.py Wed Apr 1 22:26:33 2009 @@ -11,6 +11,7 @@ import socket import StringIO import os +import re from test import test_support try: @@ -385,6 +386,21 @@ # protocol error; provide additional information in test output self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) + def test_nonascii(self): + start_string = 'P\N{LATIN SMALL LETTER Y WITH CIRCUMFLEX}t' + end_string = 'h\N{LATIN SMALL LETTER O WITH HORN}n' + + try: + p = xmlrpclib.ServerProxy(URL) + self.assertEqual(p.add(start_string, end_string), + start_string + end_string) + except (xmlrpclib.ProtocolError, socket.error) as e: + # ignore failures due to non-blocking socket unavailable errors. + if not is_unavailable_exception(e): + # protocol error; provide additional information in test output + self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) + + # [ch] The test 404 is causing lots of false alarms. def XXXtest_404(self): # send POST with httplib, it should return 404 header and @@ -646,6 +662,18 @@ # start with 44th char so as not to get http header, we just need only xml self.assertRaises(xmlrpclib.Fault, xmlrpclib.loads, handle[44:]) + # Also test the content-length returned by handle_request + # Using the same test method inorder to avoid all the datapassing + # boilerplate code. + # Test for bug: http://bugs.python.org/issue5040 + + content = handle[handle.find(" Author: brett.cannon Date: Wed Apr 1 22:27:29 2009 New Revision: 70982 Log: Merged revisions 70979 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70979 | brett.cannon | 2009-04-01 13:25:48 -0700 (Wed, 01 Apr 2009) | 3 lines test_warnings ironically had a single test that was not protecting the warnings filter and was resetting it. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_warnings.py Modified: python/branches/py3k/Lib/test/test_warnings.py ============================================================================== --- python/branches/py3k/Lib/test/test_warnings.py (original) +++ python/branches/py3k/Lib/test/test_warnings.py Wed Apr 1 22:27:29 2009 @@ -470,14 +470,14 @@ self.failUnless(text in result) def test_showwarning_not_callable(self): - self.module.filterwarnings("always", category=UserWarning) - old_showwarning = self.module.showwarning - self.module.showwarning = 23 - try: - self.assertRaises(TypeError, self.module.warn, "Warning!") - finally: - self.module.showwarning = old_showwarning - self.module.resetwarnings() + with original_warnings.catch_warnings(module=self.module): + self.module.filterwarnings("always", category=UserWarning) + old_showwarning = self.module.showwarning + self.module.showwarning = 23 + try: + self.assertRaises(TypeError, self.module.warn, "Warning!") + finally: + self.module.showwarning = old_showwarning def test_show_warning_output(self): # With showarning() missing, make sure that output is okay. From jackdied at gmail.com Wed Apr 1 22:30:13 2009 From: jackdied at gmail.com (Jack diederich) Date: Wed, 1 Apr 2009 16:30:13 -0400 Subject: [Python-checkins] r70980 - in python/trunk: Lib/test/test_mmap.py Modules/mmapmodule.c In-Reply-To: <20090401202613.6E33D1E470D@bag.python.org> References: <20090401202613.6E33D1E470D@bag.python.org> Message-ID: We've gotten this wrong twice so I'm going to let this settle for a few hours before merging accross all the other branches. On Wed, Apr 1, 2009 at 4:26 PM, jack.diederich wrote: > Author: jack.diederich > Date: Wed Apr ?1 22:26:13 2009 > New Revision: 70980 > > Log: > bounds check arguments to mmap.move(). ?All of them. ?Really. > fixes crasher on OS X 10.5 > > > Modified: > ? python/trunk/Lib/test/test_mmap.py > ? python/trunk/Modules/mmapmodule.c > > Modified: python/trunk/Lib/test/test_mmap.py > ============================================================================== > --- python/trunk/Lib/test/test_mmap.py ?(original) > +++ python/trunk/Lib/test/test_mmap.py ?Wed Apr ?1 22:26:13 2009 > @@ -359,15 +359,22 @@ > ? ? ? ? ? ? ? ? m.move(source, dest, size) > ? ? ? ? ? ? except ValueError: > ? ? ? ? ? ? ? ? pass > - ? ? ? ?self.assertRaises(ValueError, m.move, -1, -1, -1) > - ? ? ? ?self.assertRaises(ValueError, m.move, -1, -1, 0) > - ? ? ? ?self.assertRaises(ValueError, m.move, -1, 0, -1) > - ? ? ? ?self.assertRaises(ValueError, m.move, 0, -1, -1) > - ? ? ? ?self.assertRaises(ValueError, m.move, -1, 0, 0) > - ? ? ? ?self.assertRaises(ValueError, m.move, 0, -1, 0) > - ? ? ? ?self.assertRaises(ValueError, m.move, 0, 0, -1) > + > + ? ? ? ?offsets = [(-1, -1, -1), (-1, -1, 0), (-1, 0, -1), (0, -1, -1), > + ? ? ? ? ? ? ? ? ? (-1, 0, 0), (0, -1, 0), (0, 0, -1)] > + ? ? ? ?for source, dest, size in offsets: > + ? ? ? ? ? ?self.assertRaises(ValueError, m.move, source, dest, size) > + > ? ? ? ? m.close() > > + ? ? ? ?m = mmap.mmap(-1, 1) # single byte > + ? ? ? ?self.assertRaises(ValueError, m.move, 0, 0, 2) > + ? ? ? ?self.assertRaises(ValueError, m.move, 1, 0, 1) > + ? ? ? ?self.assertRaises(ValueError, m.move, 0, 1, 1) > + ? ? ? ?m.move(0, 0, 1) > + ? ? ? ?m.move(0, 0, 0) > + > + > ? ? def test_anonymous(self): > ? ? ? ? # anonymous mmap.mmap(-1, PAGE) > ? ? ? ? m = mmap.mmap(-1, PAGESIZE) > > Modified: python/trunk/Modules/mmapmodule.c > ============================================================================== > --- python/trunk/Modules/mmapmodule.c ? (original) > +++ python/trunk/Modules/mmapmodule.c ? Wed Apr ?1 22:26:13 2009 > @@ -609,23 +609,23 @@ > ?static PyObject * > ?mmap_move_method(mmap_object *self, PyObject *args) > ?{ > - ? ? ? unsigned long dest, src, count; > + ? ? ? unsigned long dest, src, cnt; > ? ? ? ?CHECK_VALID(NULL); > - ? ? ? if (!PyArg_ParseTuple(args, "kkk:move", &dest, &src, &count) || > + ? ? ? if (!PyArg_ParseTuple(args, "kkk:move", &dest, &src, &cnt) || > ? ? ? ? ? ?!is_writeable(self)) { > ? ? ? ? ? ? ? ?return NULL; > ? ? ? ?} else { > ? ? ? ? ? ? ? ?/* bounds check the values */ > - ? ? ? ? ? ? ? unsigned long pos = src > dest ? src : dest; > - ? ? ? ? ? ? ? if (self->size < pos || count > self->size - pos) { > + ? ? ? ? ? ? ? if (cnt < 0 || (cnt + dest) < cnt || (cnt + src) < cnt || > + ? ? ? ? ? ? ? ? ?src < 0 || src > self->size || (src + cnt) > self->size || > + ? ? ? ? ? ? ? ? ?dest < 0 || dest > self->size || (dest + cnt) > self->size) { > ? ? ? ? ? ? ? ? ? ? ? ?PyErr_SetString(PyExc_ValueError, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "source or destination out of range"); > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "source, destination, or count out of range"); > ? ? ? ? ? ? ? ? ? ? ? ?return NULL; > - ? ? ? ? ? ? ? } else { > - ? ? ? ? ? ? ? ? ? ? ? memmove(self->data+dest, self->data+src, count); > - ? ? ? ? ? ? ? ? ? ? ? Py_INCREF(Py_None); > - ? ? ? ? ? ? ? ? ? ? ? return Py_None; > ? ? ? ? ? ? ? ?} > + ? ? ? ? ? ? ? memmove(self->data+dest, self->data+src, cnt); > + ? ? ? ? ? ? ? Py_INCREF(Py_None); > + ? ? ? ? ? ? ? return Py_None; > ? ? ? ?} > ?} > > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > http://mail.python.org/mailman/listinfo/python-checkins > From python-checkins at python.org Wed Apr 1 22:38:13 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 1 Apr 2009 22:38:13 +0200 (CEST) Subject: [Python-checkins] r70983 - python/branches/py3k/Lib/__future__.py Message-ID: <20090401203813.C2C3F1E42DD@bag.python.org> Author: benjamin.peterson Date: Wed Apr 1 22:38:13 2009 New Revision: 70983 Log: barry has already been causing test breakage Modified: python/branches/py3k/Lib/__future__.py Modified: python/branches/py3k/Lib/__future__.py ============================================================================== --- python/branches/py3k/Lib/__future__.py (original) +++ python/branches/py3k/Lib/__future__.py Wed Apr 1 22:38:13 2009 @@ -55,6 +55,7 @@ "with_statement", "print_function", "unicode_literals", + "barry_as_FLUFL", ] __all__ = ["all_feature_names"] + all_feature_names From python-checkins at python.org Wed Apr 1 22:47:15 2009 From: python-checkins at python.org (brett.cannon) Date: Wed, 1 Apr 2009 22:47:15 +0200 (CEST) Subject: [Python-checkins] r70984 - python/branches/py3k/Doc/library/importlib.rst Message-ID: <20090401204715.0EF2F1E4297@bag.python.org> Author: brett.cannon Date: Wed Apr 1 22:47:14 2009 New Revision: 70984 Log: Add some clarification to the importlib docs. Modified: python/branches/py3k/Doc/library/importlib.rst Modified: python/branches/py3k/Doc/library/importlib.rst ============================================================================== --- python/branches/py3k/Doc/library/importlib.rst (original) +++ python/branches/py3k/Doc/library/importlib.rst Wed Apr 1 22:47:14 2009 @@ -169,13 +169,11 @@ An abstract method to return the bytes for the data located at *path*. Loaders that have a file-like storage back-end - that allows storing arbitrary data (e.g. a zip archive loader) + that allows storing arbitrary data can implement this abstract method to give direct access to the data stored. :exc:`IOError` is to be raised if the *path* cannot be found. The *path* is expected to be constructed using a module's - :attr:`__path__` attribute or an item from :attr:`__path__`. -.. XXX What's the difference between the latter two? (Maybe one is __file__?) -.. XXX Could use a clarification so as not to depend on PEP 302. + :attr:`__file__` attribute or an item from a package's :attr:`__path__`. .. class:: InspectLoader @@ -380,4 +378,10 @@ Note that the module returned by the loader is what has the attribute set on and not the module found in :data:`sys.modules`. + Reliance on this decorator is discouraged when it is possible to set + :attr:`__package__` before the execution of the code is possible. By + setting it before the code for the module is executed it allows the + attribute to be used at the global level of the module during + initialization. + .. XXX This whole chapter desperately needs examples... From python-checkins at python.org Wed Apr 1 22:50:07 2009 From: python-checkins at python.org (jesse.noller) Date: Wed, 1 Apr 2009 22:50:07 +0200 (CEST) Subject: [Python-checkins] r70985 - in python/branches/release26-maint: Modules/_multiprocessing/multiprocessing.h Message-ID: <20090401205007.A31E71E433C@bag.python.org> Author: jesse.noller Date: Wed Apr 1 22:50:07 2009 New Revision: 70985 Log: Merged revisions 70953 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70953 | hirokazu.yamamoto | 2009-04-01 10:13:52 -0500 (Wed, 01 Apr 2009) | 1 line Fixed compile error on windows. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Modules/_multiprocessing/multiprocessing.h Modified: python/branches/release26-maint/Modules/_multiprocessing/multiprocessing.h ============================================================================== --- python/branches/release26-maint/Modules/_multiprocessing/multiprocessing.h (original) +++ python/branches/release26-maint/Modules/_multiprocessing/multiprocessing.h Wed Apr 1 22:50:07 2009 @@ -16,6 +16,9 @@ # include # include # include /* getpid() */ +# ifdef Py_DEBUG +# include +# endif # define SEM_HANDLE HANDLE # define SEM_VALUE_MAX LONG_MAX #else From python-checkins at python.org Wed Apr 1 22:50:58 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 1 Apr 2009 22:50:58 +0200 (CEST) Subject: [Python-checkins] r70986 - python/trunk/Doc/library/random.rst Message-ID: <20090401205058.D49071E476B@bag.python.org> Author: raymond.hettinger Date: Wed Apr 1 22:50:58 2009 New Revision: 70986 Log: Add link to an alternative generator with a long-period. Modified: python/trunk/Doc/library/random.rst Modified: python/trunk/Doc/library/random.rst ============================================================================== --- python/trunk/Doc/library/random.rst (original) +++ python/trunk/Doc/library/random.rst Wed Apr 1 22:50:58 2009 @@ -325,3 +325,7 @@ Wichmann, B. A. & Hill, I. D., "Algorithm AS 183: An efficient and portable pseudo-random number generator", Applied Statistics 31 (1982) 188-190. + `Complementary-Multiply-with-Carry recipe + `_ for a compatable alternative + random number generator with a long-period and comparatively simple update + operations. From python-checkins at python.org Wed Apr 1 22:51:29 2009 From: python-checkins at python.org (jesse.noller) Date: Wed, 1 Apr 2009 22:51:29 +0200 (CEST) Subject: [Python-checkins] r70987 - in python/branches/py3k: Modules/_multiprocessing/multiprocessing.h Message-ID: <20090401205129.41F121E433C@bag.python.org> Author: jesse.noller Date: Wed Apr 1 22:51:28 2009 New Revision: 70987 Log: Merged revisions 70953 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70953 | hirokazu.yamamoto | 2009-04-01 10:13:52 -0500 (Wed, 01 Apr 2009) | 1 line Fixed compile error on windows. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Modules/_multiprocessing/multiprocessing.h Modified: python/branches/py3k/Modules/_multiprocessing/multiprocessing.h ============================================================================== --- python/branches/py3k/Modules/_multiprocessing/multiprocessing.h (original) +++ python/branches/py3k/Modules/_multiprocessing/multiprocessing.h Wed Apr 1 22:51:28 2009 @@ -16,6 +16,9 @@ # include # include # include /* getpid() */ +# ifdef Py_DEBUG +# include +# endif # define SEM_HANDLE HANDLE # define SEM_VALUE_MAX LONG_MAX #else From python-checkins at python.org Wed Apr 1 22:52:13 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 1 Apr 2009 22:52:13 +0200 (CEST) Subject: [Python-checkins] r70988 - python/branches/py3k/Doc/library/random.rst Message-ID: <20090401205213.D20EF1E433C@bag.python.org> Author: raymond.hettinger Date: Wed Apr 1 22:52:13 2009 New Revision: 70988 Log: Add link to an alternative generator with a long-period. 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 Wed Apr 1 22:52:13 2009 @@ -253,3 +253,7 @@ Modeling and Computer Simulation Vol. 8, No. 1, January pp.3-30 1998. + `Complementary-Multiply-with-Carry recipe + `_ for a compatable alternative + random number generator with a long-period and comparatively simple update + operations. From python-checkins at python.org Wed Apr 1 22:52:52 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 1 Apr 2009 22:52:52 +0200 (CEST) Subject: [Python-checkins] r70989 - python/branches/release26-maint/Doc/library/random.rst Message-ID: <20090401205252.7807F1E433C@bag.python.org> Author: raymond.hettinger Date: Wed Apr 1 22:52:52 2009 New Revision: 70989 Log: Add link to an alternative generator with a long-period. Modified: python/branches/release26-maint/Doc/library/random.rst Modified: python/branches/release26-maint/Doc/library/random.rst ============================================================================== --- python/branches/release26-maint/Doc/library/random.rst (original) +++ python/branches/release26-maint/Doc/library/random.rst Wed Apr 1 22:52:52 2009 @@ -325,3 +325,7 @@ Wichmann, B. A. & Hill, I. D., "Algorithm AS 183: An efficient and portable pseudo-random number generator", Applied Statistics 31 (1982) 188-190. + `Complementary-Multiply-with-Carry recipe + `_ for a compatable alternative + random number generator with a long-period and comparatively simple update + operations. From python-checkins at python.org Wed Apr 1 22:54:19 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 1 Apr 2009 22:54:19 +0200 (CEST) Subject: [Python-checkins] r70990 - python/branches/release30-maint/Doc/library/random.rst Message-ID: <20090401205419.801641E433C@bag.python.org> Author: raymond.hettinger Date: Wed Apr 1 22:54:19 2009 New Revision: 70990 Log: Add link to an alternative generator with a long-period. Modified: python/branches/release30-maint/Doc/library/random.rst Modified: python/branches/release30-maint/Doc/library/random.rst ============================================================================== --- python/branches/release30-maint/Doc/library/random.rst (original) +++ python/branches/release30-maint/Doc/library/random.rst Wed Apr 1 22:54:19 2009 @@ -253,3 +253,7 @@ Modeling and Computer Simulation Vol. 8, No. 1, January pp.3-30 1998. + `Complementary-Multiply-with-Carry recipe + `_ for a compatable alternative + random number generator with a long-period and comparatively simple update + operations. From ocean-city at m2.ccsnet.ne.jp Wed Apr 1 22:54:12 2009 From: ocean-city at m2.ccsnet.ne.jp (Hirokazu Yamamoto) Date: Thu, 02 Apr 2009 05:54:12 +0900 Subject: [Python-checkins] r70980 - in python/trunk: Lib/test/test_mmap.py Modules/mmapmodule.c In-Reply-To: References: <20090401202613.6E33D1E470D@bag.python.org> Message-ID: <49D3D474.8060401@m2.ccsnet.ne.jp> Jack diederich wrote: > We've gotten this wrong twice so I'm going to let this settle for a > few hours before merging accross all the other branches. Hmm, new test_mmap.py doesn't crash on my machine with previous revision of mmapmodule.c. Maybe sizeof(unsigned long) != sizeof(size_t) on your environment? I'll try it on coLinux(debian) later. From python-checkins at python.org Wed Apr 1 22:54:50 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 1 Apr 2009 22:54:50 +0200 (CEST) Subject: [Python-checkins] r70991 - sandbox/trunk/2to3/lib2to3/fixes/fix_urllib.py Message-ID: <20090401205450.ACD4D1E433C@bag.python.org> Author: benjamin.peterson Date: Wed Apr 1 22:54:50 2009 New Revision: 70991 Log: map urllib.urlopen to urllib.request.open #5637 Modified: sandbox/trunk/2to3/lib2to3/fixes/fix_urllib.py Modified: sandbox/trunk/2to3/lib2to3/fixes/fix_urllib.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/fixes/fix_urllib.py (original) +++ sandbox/trunk/2to3/lib2to3/fixes/fix_urllib.py Wed Apr 1 22:54:50 2009 @@ -12,7 +12,7 @@ MAPPING = {'urllib': [ ('urllib.request', ['URLOpener', 'FancyURLOpener', 'urlretrieve', - '_urlopener', 'urlcleanup']), + '_urlopener', 'urlopen', 'urlcleanup']), ('urllib.parse', ['quote', 'quote_plus', 'unquote', 'unquote_plus', 'urlencode', 'pathname2url', 'url2pathname', 'splitattr', From python-checkins at python.org Wed Apr 1 23:00:55 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Apr 2009 23:00:55 +0200 (CEST) Subject: [Python-checkins] r70992 - in python/trunk: Doc/library/io.rst Lib/io.py Message-ID: <20090401210055.C06131E4406@bag.python.org> Author: georg.brandl Date: Wed Apr 1 23:00:55 2009 New Revision: 70992 Log: #4572: add SEEK_* values as constants in io.py. Modified: python/trunk/Doc/library/io.rst python/trunk/Lib/io.py Modified: python/trunk/Doc/library/io.rst ============================================================================== --- python/trunk/Doc/library/io.rst (original) +++ python/trunk/Doc/library/io.rst Wed Apr 1 23:00:55 2009 @@ -265,12 +265,18 @@ interpreted relative to the position indicated by *whence*. Values for *whence* are: - * ``0`` -- start of the stream (the default); *offset* should be zero or positive - * ``1`` -- current stream position; *offset* may be negative - * ``2`` -- end of the stream; *offset* is usually negative + * :data:`SEEK_SET` or ``0`` -- start of the stream (the default); + *offset* should be zero or positive + * :data:`SEEK_CUR` or ``1`` -- current stream position; *offset* may + be negative + * :data:`SEEK_END` or ``2`` -- end of the stream; *offset* is usually + negative Return the new absolute position. + .. versionadded:: 2.7 + The ``SEEK_*`` constants + .. method:: seekable() Return ``True`` if the stream supports random access. If ``False``, Modified: python/trunk/Lib/io.py ============================================================================== --- python/trunk/Lib/io.py (original) +++ python/trunk/Lib/io.py Wed Apr 1 23:00:55 2009 @@ -66,6 +66,11 @@ # open() uses st_blksize whenever we can DEFAULT_BUFFER_SIZE = 8 * 1024 # bytes +# for seek() +SEEK_SET = 0 +SEEK_CUR = 1 +SEEK_END = 2 + # py3k has only new style classes __metaclass__ = type From python-checkins at python.org Wed Apr 1 23:05:44 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Apr 2009 23:05:44 +0200 (CEST) Subject: [Python-checkins] r70993 - in python/trunk: Lib/pdb.py Misc/NEWS Message-ID: <20090401210544.CADF61E4406@bag.python.org> Author: georg.brandl Date: Wed Apr 1 23:05:44 2009 New Revision: 70993 Log: Add NEWS item. Modified: python/trunk/Lib/pdb.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/pdb.py ============================================================================== --- python/trunk/Lib/pdb.py (original) +++ python/trunk/Lib/pdb.py Wed Apr 1 23:05:44 2009 @@ -194,6 +194,9 @@ self.cmdloop() self.forget() + def displayhook(self, item): + print item + def default(self, line): if line[:1] == '!': line = line[1:] locals = self.curframe.f_locals @@ -202,13 +205,16 @@ code = compile(line + '\n', '', 'single') save_stdout = sys.stdout save_stdin = sys.stdin + save_displayhook = sys.displayhook try: sys.stdin = self.stdin sys.stdout = self.stdout + sys.displayhook = self.displayhook exec code in globals, locals finally: sys.stdout = save_stdout sys.stdin = save_stdin + sys.displayhook = save_displayhook except: t, v = sys.exc_info()[:2] if type(t) == type(''): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Apr 1 23:05:44 2009 @@ -202,6 +202,8 @@ Library ------- +- Issue #4572: added SEEK_* symbolic constants to io module. + - Issue #1665206 (partially): Move imports in cgitb to the top of the module instead of performing them in functions. Helps prevent import deadlocking in threads. From python-checkins at python.org Wed Apr 1 23:06:30 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Apr 2009 23:06:30 +0200 (CEST) Subject: [Python-checkins] r70994 - python/trunk/Lib/pdb.py Message-ID: <20090401210630.CBE351E4406@bag.python.org> Author: georg.brandl Date: Wed Apr 1 23:06:30 2009 New Revision: 70994 Log: Revert accidental checkin. Modified: python/trunk/Lib/pdb.py Modified: python/trunk/Lib/pdb.py ============================================================================== --- python/trunk/Lib/pdb.py (original) +++ python/trunk/Lib/pdb.py Wed Apr 1 23:06:30 2009 @@ -194,9 +194,6 @@ self.cmdloop() self.forget() - def displayhook(self, item): - print item - def default(self, line): if line[:1] == '!': line = line[1:] locals = self.curframe.f_locals @@ -205,16 +202,13 @@ code = compile(line + '\n', '', 'single') save_stdout = sys.stdout save_stdin = sys.stdin - save_displayhook = sys.displayhook try: sys.stdin = self.stdin sys.stdout = self.stdout - sys.displayhook = self.displayhook exec code in globals, locals finally: sys.stdout = save_stdout sys.stdin = save_stdin - sys.displayhook = save_displayhook except: t, v = sys.exc_info()[:2] if type(t) == type(''): From python-checkins at python.org Wed Apr 1 23:12:54 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 1 Apr 2009 23:12:54 +0200 (CEST) Subject: [Python-checkins] r70995 - python/trunk/Lib/io.py Message-ID: <20090401211254.720861E4406@bag.python.org> Author: benjamin.peterson Date: Wed Apr 1 23:12:54 2009 New Revision: 70995 Log: add seek constants to __all__ Modified: python/trunk/Lib/io.py Modified: python/trunk/Lib/io.py ============================================================================== --- python/trunk/Lib/io.py (original) +++ python/trunk/Lib/io.py Wed Apr 1 23:12:54 2009 @@ -55,7 +55,8 @@ __all__ = ["BlockingIOError", "open", "IOBase", "RawIOBase", "FileIO", "BytesIO", "StringIO", "BufferedIOBase", "BufferedReader", "BufferedWriter", "BufferedRWPair", - "BufferedRandom", "TextIOBase", "TextIOWrapper"] + "BufferedRandom", "TextIOBase", "TextIOWrapper", + "SEEK_SET", "SEEK_CUR", "SEEK_END"] import os import abc From python-checkins at python.org Wed Apr 1 23:22:20 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 1 Apr 2009 23:22:20 +0200 (CEST) Subject: [Python-checkins] r70996 - in python/branches/py3k: Doc/library/io.rst Lib/io.py Message-ID: <20090401212220.C23261E4406@bag.python.org> Author: benjamin.peterson Date: Wed Apr 1 23:22:20 2009 New Revision: 70996 Log: Merged revisions 70992,70995 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70992 | georg.brandl | 2009-04-01 16:00:55 -0500 (Wed, 01 Apr 2009) | 1 line #4572: add SEEK_* values as constants in io.py. ........ r70995 | benjamin.peterson | 2009-04-01 16:12:54 -0500 (Wed, 01 Apr 2009) | 1 line add seek constants to __all__ ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/io.rst python/branches/py3k/Lib/io.py Modified: python/branches/py3k/Doc/library/io.rst ============================================================================== --- python/branches/py3k/Doc/library/io.rst (original) +++ python/branches/py3k/Doc/library/io.rst Wed Apr 1 23:22:20 2009 @@ -270,12 +270,18 @@ interpreted relative to the position indicated by *whence*. Values for *whence* are: - * ``0`` -- start of the stream (the default); *offset* should be zero or positive - * ``1`` -- current stream position; *offset* may be negative - * ``2`` -- end of the stream; *offset* is usually negative + * :data:`SEEK_SET` or ``0`` -- start of the stream (the default); + *offset* should be zero or positive + * :data:`SEEK_CUR` or ``1`` -- current stream position; *offset* may + be negative + * :data:`SEEK_END` or ``2`` -- end of the stream; *offset* is usually + negative Return the new absolute position. + .. versionadded:: 2.7 + The ``SEEK_*`` constants + .. method:: seekable() Return ``True`` if the stream supports random access. If ``False``, Modified: python/branches/py3k/Lib/io.py ============================================================================== --- python/branches/py3k/Lib/io.py (original) +++ python/branches/py3k/Lib/io.py Wed Apr 1 23:22:20 2009 @@ -52,7 +52,8 @@ __all__ = ["BlockingIOError", "open", "IOBase", "RawIOBase", "FileIO", "BytesIO", "StringIO", "BufferedIOBase", "BufferedReader", "BufferedWriter", "BufferedRWPair", - "BufferedRandom", "TextIOBase", "TextIOWrapper"] + "BufferedRandom", "TextIOBase", "TextIOWrapper", + "SEEK_SET", "SEEK_CUR", "SEEK_END"] import _io @@ -65,6 +66,11 @@ OpenWrapper = _io.open # for compatibility with _pyio +# for seek() +SEEK_SET = 0 +SEEK_CUR = 1 +SEEK_END = 2 + # Declaring ABCs in C is tricky so we do it here. # Method descriptions and default implementations are inherited from the C # version however. From python-checkins at python.org Wed Apr 1 23:26:19 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 1 Apr 2009 23:26:19 +0200 (CEST) Subject: [Python-checkins] r70997 - python/trunk/Lib/test/test_csv.py Message-ID: <20090401212619.091EE1E4100@bag.python.org> Author: r.david.murray Date: Wed Apr 1 23:26:18 2009 New Revision: 70997 Log: Add tests checking the CSV module's ability to handle embedded newlines in quoted field values. Modified: python/trunk/Lib/test/test_csv.py Modified: python/trunk/Lib/test/test_csv.py ============================================================================== --- python/trunk/Lib/test/test_csv.py (original) +++ python/trunk/Lib/test/test_csv.py Wed Apr 1 23:26:18 2009 @@ -166,6 +166,8 @@ quoting = csv.QUOTE_NONNUMERIC) self._write_test(['a',1,'p,q'], '"a","1","p,q"', quoting = csv.QUOTE_ALL) + self._write_test(['a\nb',1], '"a\nb","1"', + quoting = csv.QUOTE_ALL) def test_write_escape(self): self._write_test(['a',1,'p,q'], 'a,1,"p,q"', @@ -245,6 +247,7 @@ # will this fail where locale uses comma for decimals? self._read_test([',3,"5",7.3, 9'], [['', 3, '5', 7.3, 9]], quoting=csv.QUOTE_NONNUMERIC) + self._read_test(['"a\nb", 7'], [['a\nb', ' 7']]) self.assertRaises(ValueError, self._read_test, ['abc,3'], [[]], quoting=csv.QUOTE_NONNUMERIC) @@ -282,6 +285,21 @@ self.assertRaises(StopIteration, r.next) self.assertEqual(r.line_num, 3) + def test_roundtrip_quoteed_newlines(self): + fd, name = tempfile.mkstemp() + fileobj = os.fdopen(fd, "w+b") + try: + writer = csv.writer(fileobj) + self.assertRaises(TypeError, writer.writerows, None) + rows = [['a\nb','b'],['c','x\r\nd']] + writer.writerows(rows) + fileobj.seek(0) + for i, row in enumerate(csv.reader(fileobj)): + self.assertEqual(row, rows[i]) + finally: + fileobj.close() + os.unlink(name) + class TestDialectRegistry(unittest.TestCase): def test_registry_badargs(self): self.assertRaises(TypeError, csv.list_dialects, None) From python-checkins at python.org Wed Apr 1 23:54:21 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 1 Apr 2009 23:54:21 +0200 (CEST) Subject: [Python-checkins] r70998 - in python/trunk: Lib/pdb.py Misc/NEWS Message-ID: <20090401215421.C072A1E40BC@bag.python.org> Author: georg.brandl Date: Wed Apr 1 23:54:21 2009 New Revision: 70998 Log: In Pdb, stop assigning values to __builtin__._ which interferes with the one commonly installed by gettext. Modified: python/trunk/Lib/pdb.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/pdb.py ============================================================================== --- python/trunk/Lib/pdb.py (original) +++ python/trunk/Lib/pdb.py Wed Apr 1 23:54:21 2009 @@ -194,6 +194,12 @@ self.cmdloop() self.forget() + def displayhook(self, obj): + """Custom displayhook for the exec in default(), which prevents + assignment of the _ variable in the builtins. + """ + print obj + def default(self, line): if line[:1] == '!': line = line[1:] locals = self.curframe.f_locals @@ -202,13 +208,16 @@ code = compile(line + '\n', '', 'single') save_stdout = sys.stdout save_stdin = sys.stdin + save_displayhook = sys.displayhook try: sys.stdin = self.stdin sys.stdout = self.stdout + sys.displayhook = self.displayhook exec code in globals, locals finally: sys.stdout = save_stdout sys.stdin = save_stdin + sys.displayhook = save_displayhook except: t, v = sys.exc_info()[:2] if type(t) == type(''): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Apr 1 23:54:21 2009 @@ -202,6 +202,9 @@ Library ------- +- In Pdb, prevent the reassignment of __builtin__._ by sys.displayhook on + printing out values. + - Issue #4572: added SEEK_* symbolic constants to io module. - Issue #1665206 (partially): Move imports in cgitb to the top of the module From python-checkins at python.org Thu Apr 2 00:36:47 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 2 Apr 2009 00:36:47 +0200 (CEST) Subject: [Python-checkins] r70999 - in sandbox/trunk/2to3/lib2to3: main.py refactor.py Message-ID: <20090401223647.6DC241E40BC@bag.python.org> Author: benjamin.peterson Date: Thu Apr 2 00:36:47 2009 New Revision: 70999 Log: add very alpha support to 2to3 for running concurrently with multiprocessing Modified: sandbox/trunk/2to3/lib2to3/main.py sandbox/trunk/2to3/lib2to3/refactor.py Modified: sandbox/trunk/2to3/lib2to3/main.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/main.py (original) +++ sandbox/trunk/2to3/lib2to3/main.py Thu Apr 2 00:36:47 2009 @@ -10,8 +10,12 @@ from . import refactor +HAVE_MULTIPROCESS = hasattr(refactor, "MultiprocessRefactoringTool") -class StdoutRefactoringTool(refactor.RefactoringTool): +base_refactor = getattr(refactor, "MultiprocessRefactoringTool", + refactor.RefactoringTool) + +class StdoutRefactoringTool(base_refactor): """ Prints output to stdout. """ @@ -64,6 +68,9 @@ help="Fix up doctests only") parser.add_option("-f", "--fix", action="append", default=[], help="Each FIX specifies a transformation; default: all") + if HAVE_MULTIPROCESS: + 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.") parser.add_option("-l", "--list-fixes", action="store_true", @@ -126,7 +133,8 @@ if refactor_stdin: rt.refactor_stdin() else: - rt.refactor(args, options.write, options.doctests_only) + rt.refactor(args, options.write, options.doctests_only, + options.processes) rt.summarize() # Return error status (0 if rt.errors is zero) Modified: sandbox/trunk/2to3/lib2to3/refactor.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/refactor.py (original) +++ sandbox/trunk/2to3/lib2to3/refactor.py Thu Apr 2 00:36:47 2009 @@ -506,6 +506,56 @@ yield "" +try: + import multiprocessing +except ImportError: + pass +else: + class MultiprocessRefactoringTool(RefactoringTool): + + def __init__(self, *args, **kwargs): + super(MultiprocessRefactoringTool, self).__init__(*args, **kwargs) + self.queue = None + + def refactor(self, items, write=False, doctests_only=False, + num_processes=1): + if num_processes == 1: + super(MultiprocessRefactoringTool, self).refactor(items, write, + doctests_only) + if self.queue is not None: + raise RuntimeError("already doing multiple processes") + self.queue = multiprocessing.JoinableQueue() + processes = [multiprocessing.Process(target=self._child) + for i in xrange(num_processes)] + try: + for p in processes: + p.start() + super(MultiprocessRefactoringTool, self).refactor(items, write, + doctests_only) + finally: + self.queue.join() + for i in xrange(num_processes): + self.queue.put(None) + for p in processes: + if p.is_alive(): + p.join() + self.queue = None + + def _child(self): + task = self.queue.get() + while task is not None: + args, kwargs = task + try: + super(MultiprocessRefactoringTool, self).refactor_file( + *args, **kwargs) + finally: + self.queue.task_done() + task = self.queue.get() + + def refactor_file(self, *args, **kwargs): + self.queue.put((args, kwargs)) + + def diff_texts(a, b, filename): """Return a unified diff of two strings.""" a = a.splitlines() From python-checkins at python.org Thu Apr 2 00:37:58 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 2 Apr 2009 00:37:58 +0200 (CEST) Subject: [Python-checkins] r71000 - in python/branches/py3k: Lib/test/test_csv.py Message-ID: <20090401223758.576801E45CA@bag.python.org> Author: r.david.murray Date: Thu Apr 2 00:37:58 2009 New Revision: 71000 Log: Merged revisions 70997 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70997 | r.david.murray | 2009-04-01 17:26:18 -0400 (Wed, 01 Apr 2009) | 3 lines Add tests checking the CSV module's ability to handle embedded newlines in quoted field values. ........ Modified: python/branches/py3k/ (props changed) 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 Apr 2 00:37:58 2009 @@ -162,6 +162,8 @@ quoting = csv.QUOTE_NONNUMERIC) self._write_test(['a',1,'p,q'], '"a","1","p,q"', quoting = csv.QUOTE_ALL) + self._write_test(['a\nb',1], '"a\nb","1"', + quoting = csv.QUOTE_ALL) def test_write_escape(self): self._write_test(['a',1,'p,q'], 'a,1,"p,q"', @@ -241,6 +243,7 @@ # will this fail where locale uses comma for decimals? self._read_test([',3,"5",7.3, 9'], [['', 3, '5', 7.3, 9]], quoting=csv.QUOTE_NONNUMERIC) + self._read_test(['"a\nb", 7'], [['a\nb', ' 7']]) self.assertRaises(ValueError, self._read_test, ['abc,3'], [[]], quoting=csv.QUOTE_NONNUMERIC) @@ -276,6 +279,16 @@ self.assertRaises(StopIteration, next, r) self.assertEqual(r.line_num, 3) + def test_roundtrip_quoteed_newlines(self): + with TemporaryFile("w+", newline='') as fileobj: + writer = csv.writer(fileobj) + self.assertRaises(TypeError, writer.writerows, None) + rows = [['a\nb','b'],['c','x\r\nd']] + writer.writerows(rows) + fileobj.seek(0) + for i, row in enumerate(csv.reader(fileobj)): + self.assertEqual(row, rows[i]) + class TestDialectRegistry(unittest.TestCase): def test_registry_badargs(self): self.assertRaises(TypeError, csv.list_dialects, None) From python-checkins at python.org Thu Apr 2 01:01:12 2009 From: python-checkins at python.org (brett.cannon) Date: Thu, 2 Apr 2009 01:01:12 +0200 (CEST) Subject: [Python-checkins] r71001 - python/trunk/Misc/developers.txt Message-ID: <20090401230112.69F171E40CD@bag.python.org> Author: brett.cannon Date: Thu Apr 2 01:01:12 2009 New Revision: 71001 Log: Add my initials to Misc/developers.txt. Names are now sorted by number of characters in the person's name. Modified: python/trunk/Misc/developers.txt Modified: python/trunk/Misc/developers.txt ============================================================================== --- python/trunk/Misc/developers.txt (original) +++ python/trunk/Misc/developers.txt Thu Apr 2 01:01:12 2009 @@ -256,10 +256,11 @@ Initials of Project Admins -------------------------- -GvR: Guido van Rossum -NCN: Neal Norwitz -RDH: Raymond Hettinger TGP: Tim Peters +GFB: Georg Brandl +BAC: Brett Cannon +NCN: Neal Norwitz DJG: David Goodger MvL: Martin v. Loewis -GFB: Georg Brandl +GvR: Guido van Rossum +RDH: Raymond Hettinger From python-checkins at python.org Thu Apr 2 01:07:29 2009 From: python-checkins at python.org (georg.brandl) Date: Thu, 2 Apr 2009 01:07:29 +0200 (CEST) Subject: [Python-checkins] r71002 - in python/branches/py3k: Lib/test/regrtest.py Lib/trace.py Misc/NEWS Message-ID: <20090401230729.B56611E40BC@bag.python.org> Author: georg.brandl Date: Thu Apr 2 01:07:29 2009 New Revision: 71002 Log: #5656: detect correct encoding of files when reporting coverage in trace.py, and ignore files in the temporary directory when reporting. Modified: python/branches/py3k/Lib/test/regrtest.py python/branches/py3k/Lib/trace.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 Thu Apr 2 01:07:29 2009 @@ -404,8 +404,9 @@ print("Using random seed", random_seed) random.shuffle(tests) if trace: - import trace - tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix], + import trace, tempfile + tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix, + tempfile.gettempdir()], trace=False, count=True) test_times = [] support.verbose = verbose # Tell tests to be moderately quiet Modified: python/branches/py3k/Lib/trace.py ============================================================================== --- python/branches/py3k/Lib/trace.py (original) +++ python/branches/py3k/Lib/trace.py Thu Apr 2 01:07:29 2009 @@ -48,6 +48,7 @@ r.write_results(show_missing=True, coverdir="/tmp") """ +import io import linecache import os import re @@ -224,6 +225,13 @@ print(("Skipping counts file %r: %s" % (self.infile, err)), file=sys.stderr) + def is_ignored_filename(self, filename): + """Return True if the filename does not refer to a file + we want to have reported. + """ + return (filename == "" or + filename.startswith("": - continue - if filename.startswith(" Author: benjamin.peterson Date: Thu Apr 2 01:10:43 2009 New Revision: 71003 Log: fix when multiprocessing is not available or used Modified: sandbox/trunk/2to3/lib2to3/main.py sandbox/trunk/2to3/lib2to3/refactor.py Modified: sandbox/trunk/2to3/lib2to3/main.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/main.py (original) +++ sandbox/trunk/2to3/lib2to3/main.py Thu Apr 2 01:10:43 2009 @@ -133,8 +133,11 @@ if refactor_stdin: rt.refactor_stdin() else: - rt.refactor(args, options.write, options.doctests_only, - options.processes) + if HAVE_MULTIPROCESS: + rt.refactor(args, options.write, options.doctests_only, + options.processes) + else: + rt.refactor(args, options.write, options.doctests_only) rt.summarize() # Return error status (0 if rt.errors is zero) Modified: sandbox/trunk/2to3/lib2to3/refactor.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/refactor.py (original) +++ sandbox/trunk/2to3/lib2to3/refactor.py Thu Apr 2 01:10:43 2009 @@ -520,8 +520,8 @@ def refactor(self, items, write=False, doctests_only=False, num_processes=1): if num_processes == 1: - super(MultiprocessRefactoringTool, self).refactor(items, write, - doctests_only) + return super(MultiprocessRefactoringTool, self).refactor( + items, write, doctests_only) if self.queue is not None: raise RuntimeError("already doing multiple processes") self.queue = multiprocessing.JoinableQueue() @@ -553,7 +553,11 @@ task = self.queue.get() def refactor_file(self, *args, **kwargs): - self.queue.put((args, kwargs)) + if self.queue is not None: + self.queue.put((args, kwargs)) + else: + return super(MultiprocessRefactoringTool, self).refactor_file( + *args, **kwargs) def diff_texts(a, b, filename): From python-checkins at python.org Thu Apr 2 01:15:49 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 2 Apr 2009 01:15:49 +0200 (CEST) Subject: [Python-checkins] r71004 - python/trunk/Lib/unittest.py Message-ID: <20090401231549.697091E4389@bag.python.org> Author: benjamin.peterson Date: Thu Apr 2 01:15:49 2009 New Revision: 71004 Log: remove double underscores Modified: python/trunk/Lib/unittest.py Modified: python/trunk/Lib/unittest.py ============================================================================== --- python/trunk/Lib/unittest.py (original) +++ python/trunk/Lib/unittest.py Thu Apr 2 01:15:49 2009 @@ -334,7 +334,7 @@ # Map types to custom assertEqual functions that will compare # instances of said type in more detail to generate a more useful # error message. - self.__type_equality_funcs = {} + self._type_equality_funcs = {} self.addTypeEqualityFunc(dict, self.assertDictEqual) self.addTypeEqualityFunc(list, self.assertListEqual) self.addTypeEqualityFunc(tuple, self.assertTupleEqual) @@ -354,7 +354,7 @@ msg= argument that raises self.failureException with a useful error message when the two arguments are not equal. """ - self.__type_equality_funcs[typeobj] = function + self._type_equality_funcs[typeobj] = function def setUp(self): "Hook method for setting up the test fixture before exercising it." @@ -516,8 +516,8 @@ # See the discussion in http://bugs.python.org/issue2578. # if type(first) is type(second): - return self.__type_equality_funcs.get(type(first), - self._baseAssertEqual) + return self._type_equality_funcs.get(type(first), + self._baseAssertEqual) return self._baseAssertEqual def _baseAssertEqual(self, first, second, msg=None): @@ -576,7 +576,7 @@ # These fail* assertion method names are pending deprecation and will # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578 - def __deprecate(original_func): + def _deprecate(original_func): def deprecated_func(*args, **kwargs): warnings.warn( 'Please use {0} instead.'.format(original_func.__name__), @@ -584,13 +584,13 @@ return original_func(*args, **kwargs) return deprecated_func - failUnlessEqual = __deprecate(assertEqual) - failIfEqual = __deprecate(assertNotEqual) - failUnlessAlmostEqual = __deprecate(assertAlmostEqual) - failIfAlmostEqual = __deprecate(assertNotAlmostEqual) - failUnless = __deprecate(assertTrue) - failUnlessRaises = __deprecate(assertRaises) - failIf = __deprecate(assertFalse) + failUnlessEqual = _deprecate(assertEqual) + failIfEqual = _deprecate(assertNotEqual) + failUnlessAlmostEqual = _deprecate(assertAlmostEqual) + failIfAlmostEqual = _deprecate(assertNotAlmostEqual) + failUnless = _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). @@ -1052,50 +1052,51 @@ def __init__(self, testFunc, setUp=None, tearDown=None, description=None): super(FunctionTestCase, self).__init__() - self.__setUpFunc = setUp - self.__tearDownFunc = tearDown - self.__testFunc = testFunc - self.__description = description + self._setUpFunc = setUp + self._tearDownFunc = tearDown + self._testFunc = testFunc + self._description = description def setUp(self): - if self.__setUpFunc is not None: - self.__setUpFunc() + if self._setUpFunc is not None: + self._setUpFunc() def tearDown(self): - if self.__tearDownFunc is not None: - self.__tearDownFunc() + if self._tearDownFunc is not None: + self._tearDownFunc() def runTest(self): - self.__testFunc() + self._testFunc() def id(self): - return self.__testFunc.__name__ + return self._testFunc.__name__ def __eq__(self, other): if not isinstance(other, self.__class__): return NotImplemented - return self.__setUpFunc == other.__setUpFunc and \ - self.__tearDownFunc == other.__tearDownFunc and \ - self.__testFunc == other.__testFunc and \ - self.__description == other.__description + return self._setUpFunc == other._setUpFunc and \ + self._tearDownFunc == other._tearDownFunc and \ + self._testFunc == other._testFunc and \ + self._description == other._description def __ne__(self, other): return not self == other def __hash__(self): - return hash((type(self), self.__setUpFunc, self.__tearDownFunc, - self.__testFunc, self.__description)) + return hash((type(self), self._setUpFunc, self._tearDownFunc, + self._testFunc, self._description)) def __str__(self): return "%s (%s)" % (_strclass(self.__class__), self.__testFunc.__name__) def __repr__(self): - return "<%s testFunc=%s>" % (_strclass(self.__class__), self.__testFunc) + return "<%s testFunc=%s>" % (_strclass(self.__class__), self._testFunc) def shortDescription(self): - if self.__description is not None: return self.__description - doc = self.__testFunc.__doc__ + if self._description is not None: + return self._description + doc = self._testFunc.__doc__ return doc and doc.split("\n")[0].strip() or None From python-checkins at python.org Thu Apr 2 01:26:47 2009 From: python-checkins at python.org (brett.cannon) Date: Thu, 2 Apr 2009 01:26:47 +0200 (CEST) Subject: [Python-checkins] r71005 - python/branches/py3k/Doc/library/importlib.rst Message-ID: <20090401232647.55B6E1E48DA@bag.python.org> Author: brett.cannon Date: Thu Apr 2 01:26:47 2009 New Revision: 71005 Log: Add a meta path importer example. Modified: python/branches/py3k/Doc/library/importlib.rst Modified: python/branches/py3k/Doc/library/importlib.rst ============================================================================== --- python/branches/py3k/Doc/library/importlib.rst (original) +++ python/branches/py3k/Doc/library/importlib.rst Thu Apr 2 01:26:47 2009 @@ -77,12 +77,12 @@ ``pkg.mod``). The :func:`import_module` function acts as a simplifying wrapper around - :func:`__import__`. This means all semantics of the function are derived - from :func:`__import__`, including requiring the package from which an - import is occurring to have been previously imported (i.e., *package* - must already be imported). The most important difference is that - :func:`import_module` returns the most nested package or module that - was imported (e.g. ``pkg.mod``), while :func:`__import__` returns the + :func:`importlib.__import__`. This means all semantics of the function are + derived from :func:`importlib.__import__`, including requiring the package + from which an import is occurring to have been previously imported + (i.e., *package* must already be imported). The most important difference + is that :func:`import_module` returns the most nested package or module + that was imported (e.g. ``pkg.mod``), while :func:`__import__` returns the top-level package or module (e.g. ``pkg``). @@ -384,4 +384,95 @@ attribute to be used at the global level of the module during initialization. -.. XXX This whole chapter desperately needs examples... + +Example +------- + +.. testcode:: + + """An importer where source is stored in a dict.""" + from importlib import abc + + + class DictImporter(abc.Finder, abc.PyLoader): + + """A meta path importer that stores source code in a dict. + + The keys are the module names -- packages must end in ``.__init__``. + The values must be something that can be passed to 'bytes'. + + """ + + def __init__(self, memory): + """Store the dict.""" + self.memory = memory + + def contains(self, name): + """See if a module or package is in the dict.""" + if name in self.memory: + return name + package_name = '{}.__init__'.format(name) + if package_name in self.memory: + return package_name + return False + + __contains__ = contains # Convenience. + + def find_module(self, fullname, path=None): + """Find the module in the dict.""" + if fullname in self: + return self + return None + + def source_path(self, fullname): + """Return the module name if the module is in the dict.""" + if not fullname in self: + raise ImportError + return fullname + + def get_data(self, path): + """Return the bytes for the source. + + The value found in the dict is passed through 'bytes' before being + returned. + + """ + name = self.contains(path) + if not name: + raise IOError + return bytes(self.memory[name]) + + def is_package(self, fullname): + """Tell if module is a package based on whether the dict contains the + name with ``.__init__`` appended to it.""" + if fullname not in self: + raise ImportError + if fullname in self.memory: + return False + # If name is in this importer but not as it is then it must end in + # ``__init__``. + else: + return True + +.. testcode:: + :hide: + + import importlib + import sys + + + # Build the dict; keys of name, value of __package__. + names = {'_top_level': '', '_pkg.__init__': '_pkg', '_pkg.mod': '_pkg'} + source = {name: "name = {!r}".format(name).encode() for name in names} + + # Register the meta path importer. + importer = DictImporter(source) + sys.meta_path.append(importer) + + # Sanity check. + for name in names: + module = importlib.import_module(name) + assert module.__name__ == name + assert getattr(module, 'name') == name + assert module.__loader__ is importer + assert module.__package__ == names[name] From python-checkins at python.org Thu Apr 2 01:32:18 2009 From: python-checkins at python.org (georg.brandl) Date: Thu, 2 Apr 2009 01:32:18 +0200 (CEST) Subject: [Python-checkins] r71006 - python/trunk/Lib/pdb.py Message-ID: <20090401233218.1DD231E428A@bag.python.org> Author: georg.brandl Date: Thu Apr 2 01:32:17 2009 New Revision: 71006 Log: Cache the f_locals dict of the current frame, since every access to frame.f_locals overrides its contents with the real locals which undoes modifications made by the debugging user. Modified: python/trunk/Lib/pdb.py Modified: python/trunk/Lib/pdb.py ============================================================================== --- python/trunk/Lib/pdb.py (original) +++ python/trunk/Lib/pdb.py Thu Apr 2 01:32:17 2009 @@ -95,10 +95,14 @@ rcFile.close() self.commands = {} # associates a command list to breakpoint numbers - self.commands_doprompt = {} # for each bp num, tells if the prompt must be disp. after execing the cmd list - self.commands_silent = {} # for each bp num, tells if the stack trace must be disp. after execing the cmd list - self.commands_defining = False # True while in the process of defining a command list - self.commands_bnum = None # The breakpoint number for which we are defining a list + self.commands_doprompt = {} # for each bp num, tells if the prompt + # must be disp. after execing the cmd list + self.commands_silent = {} # for each bp num, tells if the stack trace + # must be disp. after execing the cmd list + self.commands_defining = False # True while in the process of defining + # a command list + self.commands_bnum = None # The breakpoint number for which we are + # defining a list def reset(self): bdb.Bdb.reset(self) @@ -114,6 +118,10 @@ self.forget() self.stack, self.curindex = self.get_stack(f, t) self.curframe = self.stack[self.curindex][0] + # The f_locals dictionary is updated from the actual frame + # locals whenever the .f_locals accessor is called, so we + # cache it here to ensure that modifications are not overwritten. + self.curframe_locals = self.curframe.f_locals self.execRcLines() # Can be executed earlier than 'setup' if desired @@ -202,7 +210,7 @@ def default(self, line): if line[:1] == '!': line = line[1:] - locals = self.curframe.f_locals + locals = self.curframe_locals globals = self.curframe.f_globals try: code = compile(line + '\n', '', 'single') @@ -360,7 +368,7 @@ try: func = eval(arg, self.curframe.f_globals, - self.curframe.f_locals) + self.curframe_locals) except: func = arg try: @@ -681,7 +689,7 @@ def do_debug(self, arg): sys.settrace(None) globals = self.curframe.f_globals - locals = self.curframe.f_locals + locals = self.curframe_locals p = Pdb(self.completekey, self.stdin, self.stdout) p.prompt = "(%s) " % self.prompt.strip() print >>self.stdout, "ENTERING RECURSIVE DEBUGGER" @@ -705,9 +713,8 @@ return 1 def do_args(self, arg): - f = self.curframe - co = f.f_code - dict = f.f_locals + co = self.curframe.f_code + dict = self.curframe_locals n = co.co_argcount if co.co_flags & 4: n = n+1 if co.co_flags & 8: n = n+1 @@ -719,8 +726,8 @@ do_a = do_args def do_retval(self, arg): - if '__return__' in self.curframe.f_locals: - print >>self.stdout, self.curframe.f_locals['__return__'] + if '__return__' in self.curframe_locals: + print >>self.stdout, self.curframe_locals['__return__'] else: print >>self.stdout, '*** Not yet returned!' do_rv = do_retval @@ -728,7 +735,7 @@ def _getval(self, arg): try: return eval(arg, self.curframe.f_globals, - self.curframe.f_locals) + self.curframe_locals) except: t, v = sys.exc_info()[:2] if isinstance(t, str): @@ -797,7 +804,7 @@ def do_whatis(self, arg): try: value = eval(arg, self.curframe.f_globals, - self.curframe.f_locals) + self.curframe_locals) except: t, v = sys.exc_info()[:2] if type(t) == type(''): From python-checkins at python.org Thu Apr 2 01:36:48 2009 From: python-checkins at python.org (brett.cannon) Date: Thu, 2 Apr 2009 01:36:48 +0200 (CEST) Subject: [Python-checkins] r71007 - python/branches/py3k/Doc/library/importlib.rst Message-ID: <20090401233649.077031E42D4@bag.python.org> Author: brett.cannon Date: Thu Apr 2 01:36:48 2009 New Revision: 71007 Log: Explain a little about the explanation. Modified: python/branches/py3k/Doc/library/importlib.rst Modified: python/branches/py3k/Doc/library/importlib.rst ============================================================================== --- python/branches/py3k/Doc/library/importlib.rst (original) +++ python/branches/py3k/Doc/library/importlib.rst Thu Apr 2 01:36:48 2009 @@ -388,6 +388,11 @@ Example ------- +Below is an example meta path importer that uses a dict for back-end storage +for source code. While not an optimal solution -- manipulations of +:attr:`__path__` on packages does not influence import -- it does illustrate +what little is required to implement an importer. + .. testcode:: """An importer where source is stored in a dict.""" From python-checkins at python.org Thu Apr 2 02:02:14 2009 From: python-checkins at python.org (andrew.kuchling) Date: Thu, 2 Apr 2009 02:02:14 +0200 (CEST) Subject: [Python-checkins] r71008 - python/trunk/Doc/library/random.rst Message-ID: <20090402000214.8E2891E4034@bag.python.org> Author: andrew.kuchling Date: Thu Apr 2 02:02:14 2009 New Revision: 71008 Log: Typo fix Modified: python/trunk/Doc/library/random.rst Modified: python/trunk/Doc/library/random.rst ============================================================================== --- python/trunk/Doc/library/random.rst (original) +++ python/trunk/Doc/library/random.rst Thu Apr 2 02:02:14 2009 @@ -326,6 +326,6 @@ pseudo-random number generator", Applied Statistics 31 (1982) 188-190. `Complementary-Multiply-with-Carry recipe - `_ for a compatable alternative - random number generator with a long-period and comparatively simple update + `_ for a compatible alternative + random number generator with a long period and comparatively simple update operations. From python-checkins at python.org Thu Apr 2 02:03:28 2009 From: python-checkins at python.org (jesse.noller) Date: Thu, 2 Apr 2009 02:03:28 +0200 (CEST) Subject: [Python-checkins] r71009 - in python/trunk: Modules/_multiprocessing/multiprocessing.c Modules/_multiprocessing/multiprocessing.h Modules/_multiprocessing/semaphore.c configure configure.in pyconfig.h.in setup.py Message-ID: <20090402000328.C826F1E4034@bag.python.org> Author: jesse.noller Date: Thu Apr 2 02:03:28 2009 New Revision: 71009 Log: issue5545: Switch to Autoconf for multiprocessing; special thanks to Martin Lowis for help Modified: python/trunk/Modules/_multiprocessing/multiprocessing.c python/trunk/Modules/_multiprocessing/multiprocessing.h python/trunk/Modules/_multiprocessing/semaphore.c python/trunk/configure python/trunk/configure.in python/trunk/pyconfig.h.in python/trunk/setup.py Modified: python/trunk/Modules/_multiprocessing/multiprocessing.c ============================================================================== --- python/trunk/Modules/_multiprocessing/multiprocessing.c (original) +++ python/trunk/Modules/_multiprocessing/multiprocessing.c Thu Apr 2 02:03:28 2009 @@ -8,6 +8,12 @@ #include "multiprocessing.h" +#ifdef SCM_RIGHTS + #define HAVE_FD_TRANSFER 1 +#else + #define HAVE_FD_TRANSFER 0 +#endif + PyObject *create_win32_namespace(void); PyObject *pickle_dumps, *pickle_loads, *pickle_protocol; @@ -244,7 +250,7 @@ Py_INCREF(&ConnectionType); PyModule_AddObject(module, "Connection", (PyObject*)&ConnectionType); -#if defined(MS_WINDOWS) || HAVE_SEM_OPEN +#if defined(MS_WINDOWS) || defined(HAVE_SEM_OPEN) /* Add SemLock type to module */ if (PyType_Ready(&SemLockType) < 0) return; Modified: python/trunk/Modules/_multiprocessing/multiprocessing.h ============================================================================== --- python/trunk/Modules/_multiprocessing/multiprocessing.h (original) +++ python/trunk/Modules/_multiprocessing/multiprocessing.h Thu Apr 2 02:03:28 2009 @@ -27,7 +27,7 @@ # include # include # include /* htonl() and ntohl() */ -# if HAVE_SEM_OPEN +# ifdef HAVE_SEM_OPEN # include typedef sem_t *SEM_HANDLE; # endif Modified: python/trunk/Modules/_multiprocessing/semaphore.c ============================================================================== --- python/trunk/Modules/_multiprocessing/semaphore.c (original) +++ python/trunk/Modules/_multiprocessing/semaphore.c Thu Apr 2 02:03:28 2009 @@ -197,11 +197,11 @@ #define SEM_GETVALUE(sem, pval) sem_getvalue(sem, pval) #define SEM_UNLINK(name) sem_unlink(name) -#if HAVE_BROKEN_SEM_UNLINK +#ifndef HAVE_SEM_UNLINK # define sem_unlink(name) 0 #endif -#if !HAVE_SEM_TIMEDWAIT +#ifndef HAVE_SEM_TIMEDWAIT # define sem_timedwait(sem,deadline) sem_timedwait_save(sem,deadline,_save) int @@ -348,7 +348,7 @@ } assert(self->count == 1); } else { -#if HAVE_BROKEN_SEM_GETVALUE +#ifdef HAVE_BROKEN_SEM_GETVALUE /* We will only check properly the maxvalue == 1 case */ if (self->maxvalue == 1) { /* make sure that already locked */ @@ -494,7 +494,7 @@ static PyObject * semlock_getvalue(SemLockObject *self) { -#if HAVE_BROKEN_SEM_GETVALUE +#ifdef HAVE_BROKEN_SEM_GETVALUE PyErr_SetNone(PyExc_NotImplementedError); return NULL; #else @@ -512,7 +512,7 @@ static PyObject * semlock_iszero(SemLockObject *self) { -#if HAVE_BROKEN_SEM_GETVALUE +#ifdef HAVE_BROKEN_SEM_GETVALUE if (sem_trywait(self->handle) < 0) { if (errno == EAGAIN) Py_RETURN_TRUE; Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Thu Apr 2 02:03:28 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 70730 . +# From configure.in Revision: 70903 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.7. # @@ -16570,6 +16570,10 @@ + + + + for ac_func in alarm setitimer getitimer bind_textdomain_codeset chown \ clock confstr ctermid execv fchmod fchown fork fpathconf ftime ftruncate \ gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \ @@ -16577,7 +16581,8 @@ kill killpg lchmod lchown lstat mkfifo mknod mktime \ mremap nice pathconf pause plock poll pthread_init \ putenv readlink realpath \ - select setegid seteuid setgid \ + select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ + setgid \ setlocale setregid setreuid setsid setpgid setpgrp setuid setvbuf snprintf \ sigaction siginterrupt sigrelse strftime \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ @@ -21999,6 +22004,86 @@ fi +# Multiprocessing check for broken sem_getvalue +{ echo "$as_me:$LINENO: checking for broken sem_getvalue" >&5 +echo $ECHO_N "checking for broken sem_getvalue... $ECHO_C" >&6; } +if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +#include +#include +#include + +int main(void){ + sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + int count; + int res; + if(a==SEM_FAILED){ + perror("sem_open"); + return 1; + + } + res = sem_getvalue(a, &count); + sem_close(a); + return res==-1 ? 1 : 0; +} + + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_BROKEN_SEM_GETVALUE 1 +_ACEOF + + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + # On FreeBSD 6.2, it appears that tanh(-0.) returns 0. instead of # -0. on some architectures. Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Thu Apr 2 02:03:28 2009 @@ -2474,7 +2474,8 @@ kill killpg lchmod lchown lstat mkfifo mknod mktime \ mremap nice pathconf pause plock poll pthread_init \ putenv readlink realpath \ - select setegid seteuid setgid \ + select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ + setgid \ setlocale setregid setreuid setsid setpgid setpgrp setuid setvbuf snprintf \ sigaction siginterrupt sigrelse strftime \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ @@ -3195,6 +3196,33 @@ [Define if arithmetic is subject to x87-style double rounding issue]) fi +# Multiprocessing check for broken sem_getvalue +AC_MSG_CHECKING(for broken sem_getvalue) +AC_TRY_RUN([ +#include +#include +#include +#include +#include + +int main(void){ + sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + int count; + int res; + if(a==SEM_FAILED){ + perror("sem_open"); + return 1; + + } + res = sem_getvalue(a, &count); + sem_close(a); + return res==-1 ? 1 : 0; +} +] +,AC_MSG_RESULT(no), + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BROKEN_SEM_GETVALUE, 1, define to 1 if your sem_getvalue is broken.) +) # On FreeBSD 6.2, it appears that tanh(-0.) returns 0. instead of # -0. on some architectures. Modified: python/trunk/pyconfig.h.in ============================================================================== --- python/trunk/pyconfig.h.in (original) +++ python/trunk/pyconfig.h.in Thu Apr 2 02:03:28 2009 @@ -73,6 +73,9 @@ /* Define if pthread_sigmask() does not work on your system. */ #undef HAVE_BROKEN_PTHREAD_SIGMASK +/* define to 1 if your sem_getvalue is broken. */ +#undef HAVE_BROKEN_SEM_GETVALUE + /* Define this if you have the type _Bool. */ #undef HAVE_C99_BOOL @@ -504,6 +507,18 @@ /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT +/* Define to 1 if you have the `sem_getvalue' function. */ +#undef HAVE_SEM_GETVALUE + +/* Define to 1 if you have the `sem_open' function. */ +#undef HAVE_SEM_OPEN + +/* Define to 1 if you have the `sem_timedwait' function. */ +#undef HAVE_SEM_TIMEDWAIT + +/* Define to 1 if you have the `sem_unlink' function. */ +#undef HAVE_SEM_UNLINK + /* Define to 1 if you have the `setegid' function. */ #undef HAVE_SETEGID Modified: python/trunk/setup.py ============================================================================== --- python/trunk/setup.py (original) +++ python/trunk/setup.py Thu Apr 2 02:03:28 2009 @@ -1245,56 +1245,29 @@ libraries = ['ws2_32'] elif platform == 'darwin': # Mac OSX - macros = dict( - HAVE_SEM_OPEN=1, - HAVE_SEM_TIMEDWAIT=0, - HAVE_FD_TRANSFER=1, - HAVE_BROKEN_SEM_GETVALUE=1 - ) + macros = dict() libraries = [] elif platform == 'cygwin': # Cygwin - macros = dict( - HAVE_SEM_OPEN=1, - HAVE_SEM_TIMEDWAIT=1, - HAVE_FD_TRANSFER=0, - HAVE_BROKEN_SEM_UNLINK=1 - ) + macros = dict() libraries = [] elif platform in ('freebsd4', 'freebsd5', 'freebsd6', 'freebsd7', 'freebsd8'): # FreeBSD's P1003.1b semaphore support is very experimental # and has many known problems. (as of June 2008) - macros = dict( # FreeBSD - HAVE_SEM_OPEN=0, - HAVE_SEM_TIMEDWAIT=0, - HAVE_FD_TRANSFER=1, - ) + macros = dict() libraries = [] elif platform.startswith('openbsd'): - macros = dict( # OpenBSD - HAVE_SEM_OPEN=0, # Not implemented - HAVE_SEM_TIMEDWAIT=0, - HAVE_FD_TRANSFER=1, - ) + macros = dict() libraries = [] elif platform.startswith('netbsd'): - macros = dict( # at least NetBSD 5 - HAVE_SEM_OPEN=1, - HAVE_SEM_TIMEDWAIT=0, - HAVE_FD_TRANSFER=1, - HAVE_BROKEN_SEM_GETVALUE=1 - ) + macros = dict() libraries = [] else: # Linux and other unices - macros = dict( - HAVE_SEM_OPEN=1, - HAVE_SEM_TIMEDWAIT=1, - HAVE_FD_TRANSFER=1 - ) + macros = dict() libraries = ['rt'] if platform == 'win32': @@ -1309,8 +1282,7 @@ multiprocessing_srcs = [ '_multiprocessing/multiprocessing.c', '_multiprocessing/socket_connection.c' ] - - if macros.get('HAVE_SEM_OPEN', False): + if sysconfig.get_config_var('HAVE_SEM_OPEN'): multiprocessing_srcs.append('_multiprocessing/semaphore.c') if sysconfig.get_config_var('WITH_THREAD'): From python-checkins at python.org Thu Apr 2 02:11:52 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 2 Apr 2009 02:11:52 +0200 (CEST) Subject: [Python-checkins] r71010 - python/trunk/Doc/c-api/object.rst Message-ID: <20090402001152.83D191E4063@bag.python.org> Author: benjamin.peterson Date: Thu Apr 2 02:11:52 2009 New Revision: 71010 Log: fix markup Modified: python/trunk/Doc/c-api/object.rst Modified: python/trunk/Doc/c-api/object.rst ============================================================================== --- python/trunk/Doc/c-api/object.rst (original) +++ python/trunk/Doc/c-api/object.rst Thu Apr 2 02:11:52 2009 @@ -66,8 +66,7 @@ ``o.attr_name = v``. -.. cfunction:: int PyObject_GenericSetAttr(PyObject *o, PyObject *name, PyObject -*value) +.. cfunction:: int PyObject_GenericSetAttr(PyObject *o, PyObject *name, PyObject *value) Generic attribute setter function that is meant to be put into a type object's ``tp_setattro`` slot. It looks for a data descriptor in the From python-checkins at python.org Thu Apr 2 02:12:47 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 2 Apr 2009 02:12:47 +0200 (CEST) Subject: [Python-checkins] r71011 - python/trunk/Doc/howto/regex.rst Message-ID: <20090402001247.875A01E4808@bag.python.org> Author: benjamin.peterson Date: Thu Apr 2 02:12:47 2009 New Revision: 71011 Log: this should be :noindex: Modified: python/trunk/Doc/howto/regex.rst Modified: python/trunk/Doc/howto/regex.rst ============================================================================== --- python/trunk/Doc/howto/regex.rst (original) +++ python/trunk/Doc/howto/regex.rst Thu Apr 2 02:12:47 2009 @@ -600,7 +600,7 @@ .. data:: U UNICODE - :index: + :noindex: Make ``\w``, ``\W``, ``\b``, ``\B``, ``\d``, ``\D``, ``\s`` and ``\S`` dependent on the Unicode character properties database. From python-checkins at python.org Thu Apr 2 02:24:00 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 2 Apr 2009 02:24:00 +0200 (CEST) Subject: [Python-checkins] r71012 - python/branches/py3k/Doc/library/http.client.rst Message-ID: <20090402002400.47B671E4034@bag.python.org> Author: benjamin.peterson Date: Thu Apr 2 02:24:00 2009 New Revision: 71012 Log: fix markup Modified: python/branches/py3k/Doc/library/http.client.rst Modified: python/branches/py3k/Doc/library/http.client.rst ============================================================================== --- python/branches/py3k/Doc/library/http.client.rst (original) +++ python/branches/py3k/Doc/library/http.client.rst Thu Apr 2 02:24:00 2009 @@ -522,8 +522,7 @@ HTTPMessage Objects ------------------- -An :class:`http.client.HTTPMessage` instance holds the headers from an -HTTP response. It is implemented using the -:class:`email.message.Message' class. +An :class:`http.client.HTTPMessage` instance holds the headers from an HTTP +response. It is implemented using the :class:`email.message.Message` class. -XXX Define the methods that clients can depend upon between versions. \ No newline at end of file +.. XXX Define the methods that clients can depend upon between versions. From python-checkins at python.org Thu Apr 2 02:33:56 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 2 Apr 2009 02:33:56 +0200 (CEST) Subject: [Python-checkins] r71013 - in python/branches/py3k: Doc/c-api/arg.rst Lib/test/buffer_tests.py Misc/NEWS Python/getargs.c Message-ID: <20090402003356.3CC7E1E4034@bag.python.org> Author: benjamin.peterson Date: Thu Apr 2 02:33:55 2009 New Revision: 71013 Log: make 'c' only accept bytes and 'C' only unicode #5499 Modified: python/branches/py3k/Doc/c-api/arg.rst python/branches/py3k/Lib/test/buffer_tests.py python/branches/py3k/Misc/NEWS python/branches/py3k/Python/getargs.c Modified: python/branches/py3k/Doc/c-api/arg.rst ============================================================================== --- python/branches/py3k/Doc/c-api/arg.rst (original) +++ python/branches/py3k/Doc/c-api/arg.rst Thu Apr 2 02:33:55 2009 @@ -208,9 +208,13 @@ Convert a Python integer to a C :ctype:`Py_ssize_t`. ``c`` (string of length 1) [char] - Convert a Python character, represented as a string of length 1, to a C + Convert a Python character, represented as a byte string of length 1, to a C :ctype:`char`. +``C`` (string of length 1) [int] + Covert a Python character, represented as a unicode string of length 1, to a + C :ctype:`int`. + ``f`` (float) [float] Convert a Python floating point number to a C :ctype:`float`. Modified: python/branches/py3k/Lib/test/buffer_tests.py ============================================================================== --- python/branches/py3k/Lib/test/buffer_tests.py (original) +++ python/branches/py3k/Lib/test/buffer_tests.py Thu Apr 2 02:33:55 2009 @@ -112,7 +112,7 @@ self.assertEqual(b'abc ', self.marshal(b'abc').ljust(6)) self.assertEqual(b'abc', self.marshal(b'abc').ljust(3)) self.assertEqual(b'abc', self.marshal(b'abc').ljust(2)) - self.assertEqual(b'abc*******', self.marshal(b'abc').ljust(10, '*')) + self.assertEqual(b'abc*******', self.marshal(b'abc').ljust(10, b'*')) self.assertRaises(TypeError, self.marshal(b'abc').ljust) def test_rjust(self): @@ -120,7 +120,7 @@ self.assertEqual(b' abc', self.marshal(b'abc').rjust(6)) self.assertEqual(b'abc', self.marshal(b'abc').rjust(3)) self.assertEqual(b'abc', self.marshal(b'abc').rjust(2)) - self.assertEqual(b'*******abc', self.marshal(b'abc').rjust(10, '*')) + self.assertEqual(b'*******abc', self.marshal(b'abc').rjust(10, b'*')) self.assertRaises(TypeError, self.marshal(b'abc').rjust) def test_center(self): @@ -128,7 +128,7 @@ self.assertEqual(b' abc ', self.marshal(b'abc').center(6)) self.assertEqual(b'abc', self.marshal(b'abc').center(3)) self.assertEqual(b'abc', self.marshal(b'abc').center(2)) - self.assertEqual(b'***abc****', self.marshal(b'abc').center(10, '*')) + self.assertEqual(b'***abc****', self.marshal(b'abc').center(10, b'*')) self.assertRaises(TypeError, self.marshal(b'abc').center) def test_swapcase(self): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Apr 2 02:33:55 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #5499: The 'c' code for argument parsing functions now only accepts a + byte, and the 'C' code only accepts a unicode character. + - Issue #1665206: Remove the last eager import in _warnings.c and make it lazy. - Fix a segfault when running test_exceptions with coverage, caused by Modified: python/branches/py3k/Python/getargs.c ============================================================================== --- python/branches/py3k/Python/getargs.c (original) +++ python/branches/py3k/Python/getargs.c Thu Apr 2 02:33:55 2009 @@ -776,24 +776,18 @@ char *p = va_arg(*p_va, char *); if (PyBytes_Check(arg) && PyBytes_Size(arg) == 1) *p = PyBytes_AS_STRING(arg)[0]; - else if (PyUnicode_Check(arg) && - PyUnicode_GET_SIZE(arg) == 1 && - PyUnicode_AS_UNICODE(arg)[0] < 256) - *p = (char)PyUnicode_AS_UNICODE(arg)[0]; else - return converterr("char < 256", arg, msgbuf, bufsize); + return converterr("a byte string of length 1", arg, msgbuf, bufsize); break; } case 'C': {/* unicode char */ int *p = va_arg(*p_va, int *); - if (PyBytes_Check(arg) && PyBytes_Size(arg) == 1) - *p = PyBytes_AS_STRING(arg)[0]; - else if (PyUnicode_Check(arg) && - PyUnicode_GET_SIZE(arg) == 1) + if (PyUnicode_Check(arg) && + PyUnicode_GET_SIZE(arg) == 1) *p = PyUnicode_AS_UNICODE(arg)[0]; else - return converterr("char", arg, msgbuf, bufsize); + return converterr("a unicode character", arg, msgbuf, bufsize); break; } From python-checkins at python.org Thu Apr 2 03:03:18 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 2 Apr 2009 03:03:18 +0200 (CEST) Subject: [Python-checkins] r71014 - python/trunk/Lib/test/test_io.py Message-ID: <20090402010318.1E3581E4324@bag.python.org> Author: benjamin.peterson Date: Thu Apr 2 03:03:17 2009 New Revision: 71014 Log: handle SEEK_ constants in test_io Modified: python/trunk/Lib/test/test_io.py Modified: python/trunk/Lib/test/test_io.py ============================================================================== --- python/trunk/Lib/test/test_io.py (original) +++ python/trunk/Lib/test/test_io.py Thu Apr 2 03:03:17 2009 @@ -1299,13 +1299,13 @@ def testImport__all__(self): for name in io.__all__: obj = getattr(io, name, None) - self.assert_(obj is not None, name) + self.assertTrue(obj is not None, name) if name == "open": continue elif "error" in name.lower(): - self.assert_(issubclass(obj, Exception), name) - else: - self.assert_(issubclass(obj, io.IOBase)) + self.assertTrue(issubclass(obj, Exception), name) + elif not name.startswith("SEEK_"): + self.assertTrue(issubclass(obj, io.IOBase)) def test_attributes(self): From python-checkins at python.org Thu Apr 2 03:03:26 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 2 Apr 2009 03:03:26 +0200 (CEST) Subject: [Python-checkins] r71015 - python/branches/py3k/Lib/_pyio.py Message-ID: <20090402010326.CC6741E4324@bag.python.org> Author: benjamin.peterson Date: Thu Apr 2 03:03:26 2009 New Revision: 71015 Log: add SEEK_ constants to _pyio Modified: python/branches/py3k/Lib/_pyio.py Modified: python/branches/py3k/Lib/_pyio.py ============================================================================== --- python/branches/py3k/Lib/_pyio.py (original) +++ python/branches/py3k/Lib/_pyio.py Thu Apr 2 03:03:26 2009 @@ -14,6 +14,7 @@ import io from io import __all__ +from io import SEEK_SET, SEEK_CUR, SEEK_END # open() uses st_blksize whenever we can DEFAULT_BUFFER_SIZE = 8 * 1024 # bytes From python-checkins at python.org Thu Apr 2 03:13:40 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 2 Apr 2009 03:13:40 +0200 (CEST) Subject: [Python-checkins] r71016 - in python/branches/py3k: Lib/test/test_io.py Message-ID: <20090402011340.9CF8D1E4324@bag.python.org> Author: benjamin.peterson Date: Thu Apr 2 03:13:40 2009 New Revision: 71016 Log: Merged revisions 71014 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71014 | benjamin.peterson | 2009-04-01 20:03:17 -0500 (Wed, 01 Apr 2009) | 1 line handle SEEK_ constants in test_io ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_io.py 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 Thu Apr 2 03:13:40 2009 @@ -1996,13 +1996,13 @@ def test___all__(self): for name in self.io.__all__: obj = getattr(self.io, name, None) - self.assert_(obj is not None, name) + self.assertTrue(obj is not None, name) if name == "open": continue elif "error" in name.lower(): - self.assert_(issubclass(obj, Exception), name) - else: - self.assert_(issubclass(obj, self.IOBase), name) + self.assertTrue(issubclass(obj, Exception), name) + elif not name.startswith("SEEK_"): + self.assertTrue(issubclass(obj, self.IOBase)) def test_attributes(self): f = self.open(support.TESTFN, "wb", buffering=0) From python-checkins at python.org Thu Apr 2 03:14:45 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 2 Apr 2009 03:14:45 +0200 (CEST) Subject: [Python-checkins] r71017 - python/branches/py3k/Lib/test/test___all__.py Message-ID: <20090402011445.7A9291E4324@bag.python.org> Author: benjamin.peterson Date: Thu Apr 2 03:14:45 2009 New Revision: 71017 Log: add io and _pyio to test___all__ Modified: python/branches/py3k/Lib/test/test___all__.py Modified: python/branches/py3k/Lib/test/test___all__.py ============================================================================== --- python/branches/py3k/Lib/test/test___all__.py (original) +++ python/branches/py3k/Lib/test/test___all__.py Thu Apr 2 03:14:45 2009 @@ -75,6 +75,8 @@ self.check_all("heapq") self.check_all("http.client") self.check_all("ihooks") + self.check_all("io") + self.check_all("_pyio") self.check_all("imaplib") self.check_all("imghdr") self.check_all("keyword") From python-checkins at python.org Thu Apr 2 03:50:37 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 2 Apr 2009 03:50:37 +0200 (CEST) Subject: [Python-checkins] r71018 - python/branches/py3k/Python/symtable.c Message-ID: <20090402015037.E4B631E4696@bag.python.org> Author: benjamin.peterson Date: Thu Apr 2 03:50:37 2009 New Revision: 71018 Log: fix ref leaks Modified: python/branches/py3k/Python/symtable.c Modified: python/branches/py3k/Python/symtable.c ============================================================================== --- python/branches/py3k/Python/symtable.c (original) +++ python/branches/py3k/Python/symtable.c Thu Apr 2 03:50:37 2009 @@ -766,6 +766,7 @@ if (PyNumber_InPlaceOr(newfree, allfree) < 0) goto error; + Py_DECREF(newfree); /* Check if any local variables must be converted to cell variables */ if (ste->ste_type == FunctionBlock && !analyze_cells(scopes, newfree, @@ -824,6 +825,7 @@ if (!analyze_block(entry, temp_bound, temp_free, temp_global)) goto error; success = PyNumber_InPlaceOr(child_free, temp_free) >= 0; + Py_DECREF(child_free); success = 1; error: Py_XDECREF(temp_bound); From python-checkins at python.org Thu Apr 2 04:00:01 2009 From: python-checkins at python.org (georg.brandl) Date: Thu, 2 Apr 2009 04:00:01 +0200 (CEST) Subject: [Python-checkins] r71019 - python/trunk/Lib/pdb.py Message-ID: <20090402020001.BF0CB1E419D@bag.python.org> Author: georg.brandl Date: Thu Apr 2 04:00:01 2009 New Revision: 71019 Log: Fix test_doctest, missed two assignments to curframe. Modified: python/trunk/Lib/pdb.py Modified: python/trunk/Lib/pdb.py ============================================================================== --- python/trunk/Lib/pdb.py (original) +++ python/trunk/Lib/pdb.py Thu Apr 2 04:00:01 2009 @@ -616,6 +616,7 @@ else: self.curindex = self.curindex - 1 self.curframe = self.stack[self.curindex][0] + self.curframe_locals = self.curframe.f_locals self.print_stack_entry(self.stack[self.curindex]) self.lineno = None do_u = do_up @@ -626,6 +627,7 @@ else: self.curindex = self.curindex + 1 self.curframe = self.stack[self.curindex][0] + self.curframe_locals = self.curframe.f_locals self.print_stack_entry(self.stack[self.curindex]) self.lineno = None do_d = do_down From python-checkins at python.org Thu Apr 2 04:27:21 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 2 Apr 2009 04:27:21 +0200 (CEST) Subject: [Python-checkins] r71020 - python/branches/py3k/Python/symtable.c Message-ID: <20090402022721.7ECD31E4139@bag.python.org> Author: benjamin.peterson Date: Thu Apr 2 04:27:20 2009 New Revision: 71020 Log: rewrite error handling to make sense Modified: python/branches/py3k/Python/symtable.c Modified: python/branches/py3k/Python/symtable.c ============================================================================== --- python/branches/py3k/Python/symtable.c (original) +++ python/branches/py3k/Python/symtable.c Thu Apr 2 04:27:20 2009 @@ -824,14 +824,18 @@ if (!analyze_block(entry, temp_bound, temp_free, temp_global)) goto error; - success = PyNumber_InPlaceOr(child_free, temp_free) >= 0; + if (PyNumber_InPlaceOr(child_free, temp_free) < 0) + goto error; Py_DECREF(child_free); - success = 1; + Py_DECREF(temp_bound); + Py_DECREF(temp_free); + Py_DECREF(temp_global); + return 1; error: Py_XDECREF(temp_bound); Py_XDECREF(temp_free); Py_XDECREF(temp_global); - return success; + return 0; } static int From python-checkins at python.org Thu Apr 2 04:27:56 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 2 Apr 2009 04:27:56 +0200 (CEST) Subject: [Python-checkins] r71021 - python/branches/py3k/Python/symtable.c Message-ID: <20090402022756.EE9031E4139@bag.python.org> Author: benjamin.peterson Date: Thu Apr 2 04:27:56 2009 New Revision: 71021 Log: remove unused variable Modified: python/branches/py3k/Python/symtable.c Modified: python/branches/py3k/Python/symtable.c ============================================================================== --- python/branches/py3k/Python/symtable.c (original) +++ python/branches/py3k/Python/symtable.c Thu Apr 2 04:27:56 2009 @@ -803,7 +803,6 @@ PyObject *global, PyObject* child_free) { PyObject *temp_bound = NULL, *temp_global = NULL, *temp_free = NULL; - int success = 0; /* Copy the bound and global dictionaries. From python-checkins at python.org Thu Apr 2 04:32:55 2009 From: python-checkins at python.org (jesse.noller) Date: Thu, 2 Apr 2009 04:32:55 +0200 (CEST) Subject: [Python-checkins] r71022 - in python/trunk: Misc/NEWS Modules/_multiprocessing/multiprocessing.h Message-ID: <20090402023255.B4BAD1E43BC@bag.python.org> Author: jesse.noller Date: Thu Apr 2 04:32:55 2009 New Revision: 71022 Log: Issue 3110: Additional protection for SEM_VALUE_MAX on platforms, thanks to Martin Loewis Modified: python/trunk/Misc/NEWS python/trunk/Modules/_multiprocessing/multiprocessing.h Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Apr 2 04:32:55 2009 @@ -202,6 +202,8 @@ Library ------- +- Issue #3110: Add additional protect around SEM_VALUE_MAX for multiprocessing + - In Pdb, prevent the reassignment of __builtin__._ by sys.displayhook on printing out values. Modified: python/trunk/Modules/_multiprocessing/multiprocessing.h ============================================================================== --- python/trunk/Modules/_multiprocessing/multiprocessing.h (original) +++ python/trunk/Modules/_multiprocessing/multiprocessing.h Thu Apr 2 04:32:55 2009 @@ -45,13 +45,18 @@ * Issue 3110 - Solaris does not define SEM_VALUE_MAX */ #ifndef SEM_VALUE_MAX -# ifdef _SEM_VALUE_MAX -# define SEM_VALUE_MAX _SEM_VALUE_MAX -# else -# define SEM_VALUE_MAX INT_MAX -# endif + #if defined(HAVE_SYSCONF) && defined(_SC_SEM_VALUE_MAX) + # define SEM_VALUE_MAX sysconf(_SC_SEM_VALUE_MAX) + #elif defined(_SEM_VALUE_MAX) + # define SEM_VALUE_MAX _SEM_VALUE_MAX + #elif definef(_POSIX_SEM_VALUE_MAX) + # define SEM_VALUE_MAX _POSIX_SEM_VALUE_MAX + #else + # define SEM_VALUE_MAX INT_MAX + #endif #endif + /* * Make sure Py_ssize_t available */ From python-checkins at python.org Thu Apr 2 04:44:55 2009 From: python-checkins at python.org (kurt.kaiser) Date: Thu, 2 Apr 2009 04:44:55 +0200 (CEST) Subject: [Python-checkins] r71023 - in python/trunk/Lib/idlelib: NEWS.txt run.py Message-ID: <20090402024455.5E3E21E4124@bag.python.org> Author: kurt.kaiser Date: Thu Apr 2 04:44:54 2009 New Revision: 71023 Log: Remove port spec from run.py and fix bug where subprocess fails to extract port from command line when warnings are present. Modified: python/trunk/Lib/idlelib/NEWS.txt python/trunk/Lib/idlelib/run.py Modified: python/trunk/Lib/idlelib/NEWS.txt ============================================================================== --- python/trunk/Lib/idlelib/NEWS.txt (original) +++ python/trunk/Lib/idlelib/NEWS.txt Thu Apr 2 04:44:54 2009 @@ -3,8 +3,11 @@ *Release date: XX-XXX-2009* +- Remove port spec from run.py and fix bug where subprocess fails to + extract port from command line when warnings are present. + - Tk 8.5 Text widget requires 'wordprocessor' tabstyle attr to handle - mixed space/tab properly. Issue 5120, patch by Guilherme Polo. + mixed space/tab properly. Issue 5129, patch by Guilherme Polo. - Issue #3549: On MacOS the preferences menu was not present Modified: python/trunk/Lib/idlelib/run.py ============================================================================== --- python/trunk/Lib/idlelib/run.py (original) +++ python/trunk/Lib/idlelib/run.py Thu Apr 2 04:44:54 2009 @@ -67,10 +67,13 @@ global quitting global no_exitfunc no_exitfunc = del_exitfunc - port = 8833 #time.sleep(15) # test subprocess not responding - if sys.argv[1:]: - port = int(sys.argv[1]) + try: + assert(len(sys.argv) > 1) + port = int(sys.argv[-1]) + except: + print>>sys.stderr, "IDLE Subprocess: no IP port passed in sys.argv." + return sys.argv[:] = [""] sockthread = threading.Thread(target=manage_socket, name='SockThread', From python-checkins at python.org Thu Apr 2 04:47:44 2009 From: python-checkins at python.org (georg.brandl) Date: Thu, 2 Apr 2009 04:47:44 +0200 (CEST) Subject: [Python-checkins] r71024 - python/trunk/Python/errors.c Message-ID: <20090402024744.B210D1E4124@bag.python.org> Author: georg.brandl Date: Thu Apr 2 04:47:44 2009 New Revision: 71024 Log: In PyErr_GivenExceptionMatches, temporarily bump the recursion limit, so that in the most common case PyObject_IsSubclass will not raise a recursion error we have to ignore anyway. Modified: python/trunk/Python/errors.c Modified: python/trunk/Python/errors.c ============================================================================== --- python/trunk/Python/errors.c (original) +++ python/trunk/Python/errors.c Thu Apr 2 04:47:44 2009 @@ -106,10 +106,16 @@ err = PyExceptionInstance_Class(err); if (PyExceptionClass_Check(err) && PyExceptionClass_Check(exc)) { - int res = 0; + int res = 0, reclimit; PyObject *exception, *value, *tb; PyErr_Fetch(&exception, &value, &tb); + /* Temporarily bump the recursion limit, so that in the most + common case PyObject_IsSubclass will not raise a recursion + error we have to ignore anyway. */ + reclimit = Py_GetRecursionLimit(); + Py_SetRecursionLimit(reclimit + 5); res = PyObject_IsSubclass(err, exc); + Py_SetRecursionLimit(reclimit); /* This function must not fail, so print the error here */ if (res == -1) { PyErr_WriteUnraisable(err); From python-checkins at python.org Thu Apr 2 04:52:10 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 2 Apr 2009 04:52:10 +0200 (CEST) Subject: [Python-checkins] r71025 - in python/branches/release30-maint: Python/symtable.c Message-ID: <20090402025210.125211E4124@bag.python.org> Author: benjamin.peterson Date: Thu Apr 2 04:52:09 2009 New Revision: 71025 Log: Merged revisions 71018,71020-71021 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r71018 | benjamin.peterson | 2009-04-01 20:50:37 -0500 (Wed, 01 Apr 2009) | 1 line fix ref leaks ........ r71020 | benjamin.peterson | 2009-04-01 21:27:20 -0500 (Wed, 01 Apr 2009) | 1 line rewrite error handling to make sense ........ r71021 | benjamin.peterson | 2009-04-01 21:27:56 -0500 (Wed, 01 Apr 2009) | 1 line remove unused variable ........ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Python/symtable.c Modified: python/branches/release30-maint/Python/symtable.c ============================================================================== --- python/branches/release30-maint/Python/symtable.c (original) +++ python/branches/release30-maint/Python/symtable.c Thu Apr 2 04:52:09 2009 @@ -765,6 +765,7 @@ if (PyNumber_InPlaceOr(newfree, allfree) < 0) goto error; + Py_DECREF(newfree); /* Check if any local variables must be converted to cell variables */ if (ste->ste_type == FunctionBlock && !analyze_cells(scopes, newfree, @@ -801,7 +802,6 @@ PyObject *global, PyObject* child_free) { PyObject *temp_bound = NULL, *temp_global = NULL, *temp_free = NULL; - int success = 0; /* Copy the bound and global dictionaries. @@ -822,13 +822,18 @@ if (!analyze_block(entry, temp_bound, temp_free, temp_global)) goto error; - success = PyNumber_InPlaceOr(child_free, temp_free) >= 0; - success = 1; + if (PyNumber_InPlaceOr(child_free, temp_free) < 0) + goto error; + Py_DECREF(child_free); + Py_DECREF(temp_bound); + Py_DECREF(temp_free); + Py_DECREF(temp_global); + return 1; error: Py_XDECREF(temp_bound); Py_XDECREF(temp_free); Py_XDECREF(temp_global); - return success; + return 0; } static int From python-checkins at python.org Thu Apr 2 04:52:46 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 2 Apr 2009 04:52:46 +0200 (CEST) Subject: [Python-checkins] r71026 - python/trunk/Python/symtable.c Message-ID: <20090402025246.80C381E4124@bag.python.org> Author: benjamin.peterson Date: Thu Apr 2 04:52:46 2009 New Revision: 71026 Log: fix error handling Modified: python/trunk/Python/symtable.c Modified: python/trunk/Python/symtable.c ============================================================================== --- python/trunk/Python/symtable.c (original) +++ python/trunk/Python/symtable.c Thu Apr 2 04:52:46 2009 @@ -732,7 +732,6 @@ PyObject *global, PyObject* child_free) { PyObject *temp_bound = NULL, *temp_global = NULL, *temp_free = NULL; - int success = 0; /* Copy the bound and global dictionaries. @@ -759,13 +758,17 @@ if (!analyze_block(entry, temp_bound, temp_free, temp_global)) goto error; - success = PyDict_Update(child_free, temp_free) >= 0; - success = 1; + if (PyDict_Update(child_free, temp_free) < 0) + goto error; + Py_DECREF(temp_bound); + Py_DECREF(temp_free); + Py_DECREF(temp_global); + return 1; error: Py_XDECREF(temp_bound); Py_XDECREF(temp_free); Py_XDECREF(temp_global); - return success; + return 0; } static int From python-checkins at python.org Thu Apr 2 04:56:11 2009 From: python-checkins at python.org (georg.brandl) Date: Thu, 2 Apr 2009 04:56:11 +0200 (CEST) Subject: [Python-checkins] r71027 - in python/branches/py3k/Doc/library: abc.rst aifc.rst asynchat.rst atexit.rst base64.rst bdb.rst binascii.rst Message-ID: <20090402025611.424841E4139@bag.python.org> Author: georg.brandl Date: Thu Apr 2 04:56:10 2009 New Revision: 71027 Log: First batch of signature documentation changes; using default argument syntax where applicable. Modified: python/branches/py3k/Doc/library/abc.rst python/branches/py3k/Doc/library/aifc.rst python/branches/py3k/Doc/library/asynchat.rst python/branches/py3k/Doc/library/atexit.rst python/branches/py3k/Doc/library/base64.rst python/branches/py3k/Doc/library/bdb.rst python/branches/py3k/Doc/library/binascii.rst Modified: python/branches/py3k/Doc/library/abc.rst ============================================================================== --- python/branches/py3k/Doc/library/abc.rst (original) +++ python/branches/py3k/Doc/library/abc.rst Thu Apr 2 04:56:10 2009 @@ -158,7 +158,7 @@ multiple-inheritance. -.. function:: abstractproperty(fget[, fset[, fdel[, doc]]]) +.. function:: abstractproperty(fget=None, fset=None, fdel=None, doc=None) A subclass of the built-in :func:`property`, indicating an abstract property. Modified: python/branches/py3k/Doc/library/aifc.rst ============================================================================== --- python/branches/py3k/Doc/library/aifc.rst (original) +++ python/branches/py3k/Doc/library/aifc.rst Thu Apr 2 04:56:10 2009 @@ -37,7 +37,7 @@ Module :mod:`aifc` defines the following function: -.. function:: open(file[, mode]) +.. function:: open(file, mode=None) Open an AIFF or AIFF-C file and return an object instance with methods that are described below. The argument *file* is either a string naming a file or a file Modified: python/branches/py3k/Doc/library/asynchat.rst ============================================================================== --- python/branches/py3k/Doc/library/asynchat.rst (original) +++ python/branches/py3k/Doc/library/asynchat.rst Thu Apr 2 04:56:10 2009 @@ -202,7 +202,7 @@ ------------------------------------------ -.. class:: simple_producer(data[, buffer_size=512]) +.. class:: simple_producer(data, buffer_size=512) A :class:`simple_producer` takes a chunk of data and an optional buffer size. Repeated calls to its :meth:`more` method yield successive chunks of @@ -215,7 +215,7 @@ empty string. -.. class:: fifo([list=None]) +.. class:: fifo(list=None) Each channel maintains a :class:`fifo` holding data which has been pushed by the application but not yet popped for writing to the channel. A Modified: python/branches/py3k/Doc/library/atexit.rst ============================================================================== --- python/branches/py3k/Doc/library/atexit.rst (original) +++ python/branches/py3k/Doc/library/atexit.rst Thu Apr 2 04:56:10 2009 @@ -17,7 +17,7 @@ :func:`os._exit` is called. -.. function:: register(func[, *args[, **kargs]]) +.. function:: register(func, *args, **kargs) Register *func* as a function to be executed at termination. Any optional arguments that are to be passed to *func* must be passed as arguments to @@ -48,7 +48,8 @@ .. seealso:: Module :mod:`readline` - Useful example of :mod:`atexit` to read and write :mod:`readline` history files. + Useful example of :mod:`atexit` to read and write :mod:`readline` history + files. .. _atexit-example: Modified: python/branches/py3k/Doc/library/base64.rst ============================================================================== --- python/branches/py3k/Doc/library/base64.rst (original) +++ python/branches/py3k/Doc/library/base64.rst Thu Apr 2 04:56:10 2009 @@ -23,7 +23,7 @@ The modern interface provides: -.. function:: b64encode(s[, altchars]) +.. function:: b64encode(s, altchars=None) Encode a string use Base64. @@ -36,7 +36,7 @@ The encoded string is returned. -.. function:: b64decode(s[, altchars]) +.. function:: b64decode(s, altchars=None) Decode a Base64 encoded string. @@ -78,7 +78,7 @@ is returned. -.. function:: b32decode(s[, casefold[, map01]]) +.. function:: b32decode(s, casefold=False, map01=None) Decode a Base32 encoded string. @@ -105,7 +105,7 @@ *s* is the string to encode. The encoded string is returned. -.. function:: b16decode(s[, casefold]) +.. function:: b16decode(s, casefold=False) Decode a Base16 encoded string. Modified: python/branches/py3k/Doc/library/bdb.rst ============================================================================== --- python/branches/py3k/Doc/library/bdb.rst (original) +++ python/branches/py3k/Doc/library/bdb.rst Thu Apr 2 04:56:10 2009 @@ -16,7 +16,7 @@ The :mod:`bdb` module also defines two classes: -.. class:: Breakpoint(self, file, line[, temporary=0[, cond=None [, funcname=None]]]) +.. class:: Breakpoint(self, file, line, temporary=0, cond=None, funcname=None) This class implements temporary breakpoints, ignore counts, disabling and (re-)enabling, and conditionals. @@ -50,7 +50,7 @@ Mark the breakpoint as disabled. - .. method:: pprint([out]) + .. method:: bpprint(out=None) Print all the information about the breakpoint: @@ -233,7 +233,7 @@ breakpoints. These methods return a string containing an error message if something went wrong, or ``None`` if all is well. - .. method:: set_break(filename, lineno[, temporary=0[, cond[, funcname]]]) + .. method:: set_break(filename, lineno, temporary=0, cond, funcname) Set a new breakpoint. If the *lineno* line doesn't exist for the *filename* passed as argument, return an error message. The *filename* @@ -285,7 +285,7 @@ Get a list of records for a frame and all higher (calling) and lower frames, and the size of the higher part. - .. method:: format_stack_entry(frame_lineno, [lprefix=': ']) + .. method:: format_stack_entry(frame_lineno, lprefix=': ') Return a string with information about a stack entry, identified by a ``(frame, lineno)`` tuple: @@ -300,12 +300,12 @@ The following two methods can be called by clients to use a debugger to debug a :term:`statement`, given as a string. - .. method:: run(cmd, [globals, [locals]]) + .. method:: run(cmd, globals=None, locals=None) Debug a statement executed via the :func:`exec` function. *globals* defaults to :attr:`__main__.__dict__`, *locals* defaults to *globals*. - .. method:: runeval(expr, [globals, [locals]]) + .. method:: runeval(expr, globals=None, locals=None) Debug an expression executed via the :func:`eval` function. *globals* and *locals* have the same meaning as in :meth:`run`. Modified: python/branches/py3k/Doc/library/binascii.rst ============================================================================== --- python/branches/py3k/Doc/library/binascii.rst (original) +++ python/branches/py3k/Doc/library/binascii.rst Thu Apr 2 04:56:10 2009 @@ -49,14 +49,14 @@ should be at most 57 to adhere to the base64 standard. -.. function:: a2b_qp(string[, header]) +.. function:: a2b_qp(string, header=False) Convert a block of quoted-printable data back to binary and return the binary data. More than one line may be passed at a time. If the optional argument *header* is present and true, underscores will be decoded as spaces. -.. function:: b2a_qp(data[, quotetabs, istext, header]) +.. function:: b2a_qp(data, quotetabs=False, istext=True, header=False) Convert binary data to a line(s) of ASCII characters in quoted-printable encoding. The return value is the converted line(s). If the optional argument From python-checkins at python.org Thu Apr 2 04:58:50 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 2 Apr 2009 04:58:50 +0200 (CEST) Subject: [Python-checkins] r71028 - in python/branches/release26-maint: Python/symtable.c Message-ID: <20090402025850.40AFB1E48D7@bag.python.org> Author: benjamin.peterson Date: Thu Apr 2 04:58:49 2009 New Revision: 71028 Log: Merged revisions 71026 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71026 | benjamin.peterson | 2009-04-01 21:52:46 -0500 (Wed, 01 Apr 2009) | 1 line fix error handling ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Python/symtable.c Modified: python/branches/release26-maint/Python/symtable.c ============================================================================== --- python/branches/release26-maint/Python/symtable.c (original) +++ python/branches/release26-maint/Python/symtable.c Thu Apr 2 04:58:49 2009 @@ -731,7 +731,6 @@ PyObject *global, PyObject* child_free) { PyObject *temp_bound = NULL, *temp_global = NULL, *temp_free = NULL; - int success = 0; /* Copy the bound and global dictionaries. @@ -758,13 +757,17 @@ if (!analyze_block(entry, temp_bound, temp_free, temp_global)) goto error; - success = PyDict_Update(child_free, temp_free) >= 0; - success = 1; + if (PyDict_Update(child_free, temp_free) < 0) + goto error; + Py_DECREF(temp_bound); + Py_DECREF(temp_free); + Py_DECREF(temp_global); + return 1; error: Py_XDECREF(temp_bound); Py_XDECREF(temp_free); Py_XDECREF(temp_global); - return success; + return 0; } static int From python-checkins at python.org Thu Apr 2 05:00:34 2009 From: python-checkins at python.org (senthil.kumaran) Date: Thu, 2 Apr 2009 05:00:34 +0200 (CEST) Subject: [Python-checkins] r71029 - in python/trunk/Lib: Cookie.py test/test_cookie.py Message-ID: <20090402030034.D23AA1E43BC@bag.python.org> Author: senthil.kumaran Date: Thu Apr 2 05:00:34 2009 New Revision: 71029 Log: Fixing the issue4860. Escaping embedded '"' character in js_output() method of Morsel. Modified: python/trunk/Lib/Cookie.py python/trunk/Lib/test/test_cookie.py Modified: python/trunk/Lib/Cookie.py ============================================================================== --- python/trunk/Lib/Cookie.py (original) +++ python/trunk/Lib/Cookie.py Thu Apr 2 05:00:34 2009 @@ -477,7 +477,7 @@ document.cookie = \"%s\"; // end hiding --> - """ % ( self.OutputString(attrs), ) + """ % ( self.OutputString(attrs).replace('"',r'\"'), ) # end js_output() def OutputString(self, attrs=None): Modified: python/trunk/Lib/test/test_cookie.py ============================================================================== --- python/trunk/Lib/test/test_cookie.py (original) +++ python/trunk/Lib/test/test_cookie.py Thu Apr 2 05:00:34 2009 @@ -51,17 +51,17 @@ self.assertEqual(C.output(['path']), 'Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme') - self.assertEqual(C.js_output(), """ + self.assertEqual(C.js_output(), r""" """) - self.assertEqual(C.js_output(['path']), """ + self.assertEqual(C.js_output(['path']), r""" """) From python-checkins at python.org Thu Apr 2 05:02:03 2009 From: python-checkins at python.org (senthil.kumaran) Date: Thu, 2 Apr 2009 05:02:03 +0200 (CEST) Subject: [Python-checkins] r71030 - in python/branches/py3k/Lib: http/cookies.py test/test_http_cookies.py Message-ID: <20090402030203.5D7E81E43BC@bag.python.org> Author: senthil.kumaran Date: Thu Apr 2 05:02:03 2009 New Revision: 71030 Log: Fixing the issue4860. Escaping the embedded '"' in the js_output method of Morsel class. Modified: python/branches/py3k/Lib/http/cookies.py python/branches/py3k/Lib/test/test_http_cookies.py Modified: python/branches/py3k/Lib/http/cookies.py ============================================================================== --- python/branches/py3k/Lib/http/cookies.py (original) +++ python/branches/py3k/Lib/http/cookies.py Thu Apr 2 05:02:03 2009 @@ -392,7 +392,7 @@ document.cookie = \"%s\"; // end hiding --> - """ % ( self.OutputString(attrs), ) + """ % ( self.OutputString(attrs).replace('"',r'\"')) # end js_output() def OutputString(self, attrs=None): Modified: python/branches/py3k/Lib/test/test_http_cookies.py ============================================================================== --- python/branches/py3k/Lib/test/test_http_cookies.py (original) +++ python/branches/py3k/Lib/test/test_http_cookies.py Thu Apr 2 05:02:03 2009 @@ -50,17 +50,17 @@ self.assertEqual(C.output(['path']), 'Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme') - self.assertEqual(C.js_output(), """ + self.assertEqual(C.js_output(), r""" """) - self.assertEqual(C.js_output(['path']), """ + self.assertEqual(C.js_output(['path']), r""" """) From python-checkins at python.org Thu Apr 2 05:17:39 2009 From: python-checkins at python.org (brett.cannon) Date: Thu, 2 Apr 2009 05:17:39 +0200 (CEST) Subject: [Python-checkins] r71031 - in python/trunk: Doc/c-api/import.rst Misc/NEWS Python/import.c Message-ID: <20090402031739.45C881E4259@bag.python.org> Author: brett.cannon Date: Thu Apr 2 05:17:39 2009 New Revision: 71031 Log: PyImport_AppendInittab() took a char * as a first argument even though that string was stored beyond the life of the call. Changed the signature to be const char * to help make this point. Closes issue #1419652. Modified: python/trunk/Doc/c-api/import.rst python/trunk/Misc/NEWS python/trunk/Python/import.c Modified: python/trunk/Doc/c-api/import.rst ============================================================================== --- python/trunk/Doc/c-api/import.rst (original) +++ python/trunk/Doc/c-api/import.rst Thu Apr 2 05:17:39 2009 @@ -232,7 +232,7 @@ tricks with this to provide a dynamically created collection of frozen modules. -.. cfunction:: int PyImport_AppendInittab(char *name, void (*initfunc)(void)) +.. cfunction:: int PyImport_AppendInittab(const char *name, void (*initfunc)(void)) Add a single module to the existing table of built-in modules. This is a convenience wrapper around :cfunc:`PyImport_ExtendInittab`, returning ``-1`` if Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Apr 2 05:17:39 2009 @@ -692,6 +692,9 @@ C-API ----- +- Issue #1419652: Change the first argument to PyImport_AppendInittab() to + ``const char *`` as the string is stored beyond the call. + - Some PyBytes_* aliases have been removed because they don't exist in 3.x. - Issue #5175: PyLong_AsUnsignedLongLong now raises OverflowError Modified: python/trunk/Python/import.c ============================================================================== --- python/trunk/Python/import.c (original) +++ python/trunk/Python/import.c Thu Apr 2 05:17:39 2009 @@ -3376,7 +3376,7 @@ /* Shorthand to add a single entry given a name and a function */ int -PyImport_AppendInittab(char *name, void (*initfunc)(void)) +PyImport_AppendInittab(const char *name, void (*initfunc)(void)) { struct _inittab newtab[2]; From python-checkins at python.org Thu Apr 2 05:20:39 2009 From: python-checkins at python.org (michael.foord) Date: Thu, 2 Apr 2009 05:20:39 +0200 (CEST) Subject: [Python-checkins] r71032 - in python/trunk: Doc/library/unittest.rst Lib/test/test_unittest.py Lib/unittest.py Misc/NEWS Message-ID: <20090402032039.1BBB31E406F@bag.python.org> Author: michael.foord Date: Thu Apr 2 05:20:38 2009 New Revision: 71032 Log: Better exception messages for unittest assert methods. - unittest.assertNotEqual() now uses the inequality operator (!=) instead of the equality operator. - Default assertTrue and assertFalse messages are now useful. - TestCase has a longMessage attribute. This defaults to False, but if set to True useful error messages are shown in addition to explicit messages passed to assert methods. Issue #5663 Modified: python/trunk/Doc/library/unittest.rst python/trunk/Lib/test/test_unittest.py python/trunk/Lib/unittest.py python/trunk/Misc/NEWS Modified: python/trunk/Doc/library/unittest.rst ============================================================================== --- python/trunk/Doc/library/unittest.rst (original) +++ python/trunk/Doc/library/unittest.rst Thu Apr 2 05:20:38 2009 @@ -1,4 +1,3 @@ - :mod:`unittest` --- Unit testing framework ========================================== @@ -885,6 +884,25 @@ fair" with the framework. The initial value of this attribute is :exc:`AssertionError`. + + .. attribute:: longMessage + + If set to True then any explicit failure message you pass in to the + assert methods will be appended to the end of the normal failure message. + The normal messages contain useful information about the objects involved, + for example the message from assertEqual shows you the repr of the two + unequal objects. Setting this attribute 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. + + The class setting can be overridden in individual tests by assigning an + instance attribute to True or False before calling the assert methods. + + .. versionadded:: 2.7 + + Testing frameworks can use the following methods to collect information on the test: Modified: python/trunk/Lib/test/test_unittest.py ============================================================================== --- python/trunk/Lib/test/test_unittest.py (original) +++ python/trunk/Lib/test/test_unittest.py Thu Apr 2 05:20:38 2009 @@ -54,6 +54,8 @@ class TestEquality(object): + """Used as a mixin for TestCase""" + # Check for a valid __eq__ implementation def test_eq(self): for obj_1, obj_2 in self.eq_pairs: @@ -67,6 +69,8 @@ self.failIfEqual(obj_2, obj_1) class TestHashing(object): + """Used as a mixin for TestCase""" + # Check for a valid __hash__ implementation def test_hash(self): for obj_1, obj_2 in self.eq_pairs: @@ -2835,6 +2839,172 @@ self.fail("assertRaises() didn't let exception pass through") +class TestLongMessage(TestCase): + """Test that the individual asserts honour longMessage. + This actually tests all the message behaviour for + asserts that use longMessage.""" + + def setUp(self): + class TestableTestFalse(TestCase): + longMessage = False + failureException = self.failureException + + def testTest(self): + pass + + class TestableTestTrue(TestCase): + longMessage = True + failureException = self.failureException + + def testTest(self): + pass + + self.testableTrue = TestableTestTrue('testTest') + self.testableFalse = TestableTestFalse('testTest') + + def testDefault(self): + self.assertFalse(TestCase.longMessage) + + def test_formatMsg(self): + self.assertEquals(self.testableFalse._formatMessage(None, "foo"), "foo") + self.assertEquals(self.testableFalse._formatMessage("foo", "bar"), "foo") + + self.assertEquals(self.testableTrue._formatMessage(None, "foo"), "foo") + self.assertEquals(self.testableTrue._formatMessage("foo", "bar"), "bar : foo") + + def assertMessages(self, methodName, args, errors): + def getMethod(i): + useTestableFalse = i < 2 + if useTestableFalse: + test = self.testableFalse + else: + test = self.testableTrue + return getattr(test, methodName) + + for i, expected_regexp in enumerate(errors): + testMethod = getMethod(i) + kwargs = {} + withMsg = i % 2 + if withMsg: + kwargs = {"msg": "oops"} + + with self.assertRaisesRegexp(self.failureException, + expected_regexp=expected_regexp): + testMethod(*args, **kwargs) + + def testAssertTrue(self): + self.assertMessages('assertTrue', (False,), + ["^False is not True$", "^oops$", "^False is not True$", + "^False is not True : oops$"]) + + def testAssertFalse(self): + self.assertMessages('assertFalse', (True,), + ["^True is not False$", "^oops$", "^True is not False$", + "^True is not False : oops$"]) + + def testNotEqual(self): + self.assertMessages('assertNotEqual', (1, 1), + ["^1 == 1$", "^oops$", "^1 == 1$", + "^1 == 1 : oops$"]) + + def testAlmostEqual(self): + self.assertMessages('assertAlmostEqual', (1, 2), + ["^1 != 2 within 7 places$", "^oops$", + "^1 != 2 within 7 places$", "^1 != 2 within 7 places : oops$"]) + + def testNotAlmostEqual(self): + self.assertMessages('assertNotAlmostEqual', (1, 1), + ["^1 == 1 within 7 places$", "^oops$", + "^1 == 1 within 7 places$", "^1 == 1 within 7 places : oops$"]) + + def test_baseAssertEqual(self): + self.assertMessages('_baseAssertEqual', (1, 2), + ["^1 != 2$", "^oops$", "^1 != 2$", "^1 != 2 : oops$"]) + + def testAssertSequenceEqual(self): + # Error messages are multiline so not testing on full message + # assertTupleEqual and assertListEqual delegate to this method + self.assertMessages('assertSequenceEqual', ([], [None]), + ["\+ \[None\]$", "^oops$", r"\+ \[None\]$", + r"\+ \[None\] : oops$"]) + + def testAssertSetEqual(self): + self.assertMessages('assertSetEqual', (set(), set([None])), + ["None$", "^oops$", "None$", + "None : oops$"]) + + def testAssertIn(self): + self.assertMessages('assertIn', (None, []), + ['^None not found in \[\]$', "^oops$", + '^None not found in \[\]$', + '^None not found in \[\] : oops$']) + + def testAssertNotIn(self): + self.assertMessages('assertNotIn', (None, [None]), + ['^None unexpectedly found in \[None\]$', "^oops$", + '^None unexpectedly found in \[None\]$', + '^None unexpectedly found in \[None\] : oops$']) + + def testAssertDictEqual(self): + self.assertMessages('assertDictEqual', ({}, {'key': 'value'}), + [r"\+ \{'key': 'value'\}$", "^oops$", + "\+ \{'key': 'value'\}$", + "\+ \{'key': 'value'\} : oops$"]) + + def testAssertDictContainsSubset(self): + self.assertMessages('assertDictContainsSubset', ({'key': 'value'}, {}), + ["^Missing: 'key'$", "^oops$", + "^Missing: 'key'$", + "^Missing: 'key' : oops$"]) + + def testAssertSameElements(self): + self.assertMessages('assertSameElements', ([], [None]), + [r"\[None\]$", "^oops$", + r"\[None\]$", + r"\[None\] : oops$"]) + + def testAssertMultiLineEqual(self): + self.assertMessages('assertMultiLineEqual', ("", "foo"), + [r"\+ foo$", "^oops$", + r"\+ foo$", + r"\+ foo : oops$"]) + + def testAssertLess(self): + self.assertMessages('assertLess', (2, 1), + ["^2 not less than 1$", "^oops$", + "^2 not less than 1$", "^2 not less than 1 : oops$"]) + + def testAssertLessEqual(self): + self.assertMessages('assertLessEqual', (2, 1), + ["^2 not less than or equal to 1$", "^oops$", + "^2 not less than or equal to 1$", + "^2 not less than or equal to 1 : oops$"]) + + def testAssertGreater(self): + self.assertMessages('assertGreater', (1, 2), + ["^1 not greater than 2$", "^oops$", + "^1 not greater than 2$", + "^1 not greater than 2 : oops$"]) + + def testAssertGreaterEqual(self): + self.assertMessages('assertGreaterEqual', (1, 2), + ["^1 not greater than or equal to 2$", "^oops$", + "^1 not greater than or equal to 2$", + "^1 not greater than or equal to 2 : oops$"]) + + def testAssertIsNone(self): + self.assertMessages('assertIsNone', ('not None',), + ["^'not None' is not None$", "^oops$", + "^'not None' is not None$", + "^'not None' is not None : oops$"]) + + def testAssertIsNotNone(self): + self.assertMessages('assertIsNotNone', (None,), + ["^unexpectedly None$", "^oops$", + "^unexpectedly None$", + "^unexpectedly None : oops$"]) + + ###################################################################### ## Main ###################################################################### @@ -2842,7 +3012,7 @@ def test_main(): test_support.run_unittest(Test_TestCase, Test_TestLoader, Test_TestSuite, Test_TestResult, Test_FunctionTestCase, - Test_TestSkipping, Test_Assertions) + Test_TestSkipping, Test_Assertions, TestLongMessage) if __name__ == "__main__": test_main() Modified: python/trunk/Lib/unittest.py ============================================================================== --- python/trunk/Lib/unittest.py (original) +++ python/trunk/Lib/unittest.py Thu Apr 2 05:20:38 2009 @@ -275,7 +275,7 @@ raise self.failureException( "{0} not raised".format(exc_name)) if not issubclass(exc_type, self.expected): - # let unexpexted exceptions pass through + # let unexpected exceptions pass through return False if self.expected_regex is None: return True @@ -318,6 +318,13 @@ failureException = AssertionError + # This attribute determines whether long messages (including repr of + # objects used in assert methods) will be printed on failure in *addition* + # to any explicit message passed. + + longMessage = False + + def __init__(self, methodName='runTest'): """Create an instance of the class that will use the named test method when executed. Raises a ValueError if the instance does @@ -471,13 +478,32 @@ def assertFalse(self, expr, msg=None): "Fail the test if the expression is true." if expr: + msg = self._formatMessage(msg, "%r is not False" % expr) raise self.failureException(msg) def assertTrue(self, expr, msg=None): """Fail the test unless the expression is true.""" if not expr: + msg = self._formatMessage(msg, "%r is not True" % expr) raise self.failureException(msg) + def _formatMessage(self, msg, standardMsg): + """Honour the longMessage attribute when generating failure messages. + If longMessage is False this means: + * Use only an explicit message if it is provided + * Otherwise use the standard message for the assert + + If longMessage is True: + * Use the standard message + * If an explicit message is provided, plus ' : ' and the explicit message + """ + if not self.longMessage: + return msg or standardMsg + if msg is None: + return standardMsg + return standardMsg + ' : ' + msg + + def assertRaises(self, excClass, callableObj=None, *args, **kwargs): """Fail unless an exception of class excClass is thrown by callableObj when invoked with arguments args and keyword @@ -523,7 +549,9 @@ def _baseAssertEqual(self, first, second, msg=None): """The default assertEqual implementation, not type specific.""" if not first == second: - raise self.failureException(msg or '%r != %r' % (first, second)) + standardMsg = '%r != %r' % (first, second) + msg = self._formatMessage(msg, standardMsg) + raise self.failureException(msg) def assertEqual(self, first, second, msg=None): """Fail if the two objects are unequal as determined by the '==' @@ -536,8 +564,9 @@ """Fail if the two objects are equal as determined by the '==' operator. """ - if first == second: - raise self.failureException(msg or '%r == %r' % (first, second)) + if not first != second: + msg = self._formatMessage(msg, '%r == %r' % (first, second)) + raise self.failureException(msg) def assertAlmostEqual(self, first, second, places=7, msg=None): """Fail if the two objects are unequal as determined by their @@ -548,8 +577,9 @@ as significant digits (measured from the most signficant digit). """ if round(abs(second-first), places) != 0: - raise self.failureException( - msg or '%r != %r within %r places' % (first, second, places)) + standardMsg = '%r != %r within %r places' % (first, second, places) + msg = self._formatMessage(msg, standardMsg) + raise self.failureException(msg) def assertNotAlmostEqual(self, first, second, places=7, msg=None): """Fail if the two objects are equal as determined by their @@ -560,8 +590,9 @@ as significant digits (measured from the most signficant digit). """ if round(abs(second-first), places) == 0: - raise self.failureException( - msg or '%r == %r within %r places' % (first, second, places)) + standardMsg = '%r == %r within %r places' % (first, second, places) + msg = self._formatMessage(msg, standardMsg) + raise self.failureException(msg) # Synonyms for assertion methods @@ -680,10 +711,10 @@ except (TypeError, IndexError, NotImplementedError): differing += ('Unable to index element %d ' 'of second %s\n' % (len1, seq_type_name)) - if not msg: - msg = '\n'.join(difflib.ndiff(pprint.pformat(seq1).splitlines(), - pprint.pformat(seq2).splitlines())) - self.fail(differing + msg) + standardMsg = differing + '\n'.join(difflib.ndiff(pprint.pformat(seq1).splitlines(), + pprint.pformat(seq2).splitlines())) + msg = self._formatMessage(msg, standardMsg) + self.fail(msg) def assertListEqual(self, list1, list2, msg=None): """A list-specific equality assertion. @@ -739,9 +770,6 @@ if not (difference1 or difference2): return - if msg is not None: - self.fail(msg) - lines = [] if difference1: lines.append('Items in the first set but not the second:') @@ -751,28 +779,31 @@ lines.append('Items in the second set but not the first:') for item in difference2: lines.append(repr(item)) - self.fail('\n'.join(lines)) - def assertIn(self, a, b, msg=None): - """Just like self.assert_(a in b), but with a nicer default message.""" - if msg is None: - msg = '"%s" not found in "%s"' % (a, b) - self.assert_(a in b, msg) + standardMsg = '\n'.join(lines) + self.fail(self._formatMessage(msg, standardMsg)) - def assertNotIn(self, a, b, msg=None): - """Just like self.assert_(a not in b), but with a nicer default message.""" - if msg is None: - msg = '"%s" unexpectedly found in "%s"' % (a, b) - self.assert_(a not in b, msg) + def assertIn(self, member, container, msg=None): + """Just like self.assertTrue(a in b), but with a nicer default message.""" + if member not in container: + standardMsg = '%r not found in %r' % (member, container) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertNotIn(self, member, container, msg=None): + """Just like self.assertTrue(a not in b), but with a nicer default message.""" + if member in container: + standardMsg = '%r unexpectedly found in %r' % (member, container) + self.fail(self._formatMessage(msg, standardMsg)) def assertDictEqual(self, d1, d2, msg=None): self.assert_(isinstance(d1, dict), 'First argument is not a dictionary') self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary') if d1 != d2: - self.fail(msg or ('\n' + '\n'.join(difflib.ndiff( - pprint.pformat(d1).splitlines(), - pprint.pformat(d2).splitlines())))) + standardMsg = ('\n' + '\n'.join(difflib.ndiff( + pprint.pformat(d1).splitlines(), + pprint.pformat(d2).splitlines()))) + self.fail(self._formatMessage(msg, standardMsg)) def assertDictContainsSubset(self, expected, actual, msg=None): """Checks whether actual is a superset of expected.""" @@ -782,23 +813,20 @@ if key not in actual: missing.append(key) elif value != actual[key]: - mismatched.append('%s, expected: %s, actual: %s' % (key, value, - actual[key])) + mismatched.append('%s, expected: %s, actual: %s' % (key, value, actual[key])) if not (missing or mismatched): return - missing_msg = mismatched_msg = '' + standardMsg = '' if missing: - missing_msg = 'Missing: %s' % ','.join(missing) + standardMsg = 'Missing: %r' % ','.join(missing) if mismatched: - mismatched_msg = 'Mismatched values: %s' % ','.join(mismatched) + if standardMsg: + standardMsg += '; ' + standardMsg += 'Mismatched values: %s' % ','.join(mismatched) - if msg: - msg = '%s: %s; %s' % (msg, missing_msg, mismatched_msg) - else: - msg = '%s; %s' % (missing_msg, mismatched_msg) - self.fail(msg) + self.fail(self._formatMessage(msg, standardMsg)) def assertSameElements(self, expected_seq, actual_seq, msg=None): """An unordered sequence specific comparison. @@ -823,57 +851,59 @@ missing, unexpected = _SortedListDifference(expected, actual) errors = [] if missing: - errors.append('Expected, but missing:\n %r\n' % missing) + errors.append('Expected, but missing:\n %r' % missing) if unexpected: - errors.append('Unexpected, but present:\n %r\n' % unexpected) + errors.append('Unexpected, but present:\n %r' % unexpected) if errors: - self.fail(msg or ''.join(errors)) + standardMsg = '\n'.join(errors) + self.fail(self._formatMessage(msg, standardMsg)) def assertMultiLineEqual(self, first, second, msg=None): """Assert that two multi-line strings are equal.""" - self.assert_(isinstance(first, types.StringTypes), ( + self.assert_(isinstance(first, basestring), ( 'First argument is not a string')) - self.assert_(isinstance(second, types.StringTypes), ( + self.assert_(isinstance(second, basestring), ( 'Second argument is not a string')) if first != second: - raise self.failureException( - msg or '\n' + ''.join(difflib.ndiff(first.splitlines(True), - second.splitlines(True)))) + standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True), second.splitlines(True))) + self.fail(self._formatMessage(msg, standardMsg)) def assertLess(self, a, b, msg=None): - """Just like self.assert_(a < b), but with a nicer default message.""" - if msg is None: - msg = '"%r" unexpectedly not less than "%r"' % (a, b) - self.assert_(a < b, msg) + """Just like self.assertTrue(a < b), but with a nicer default message.""" + if not a < b: + standardMsg = '%r not less than %r' % (a, b) + self.fail(self._formatMessage(msg, standardMsg)) def assertLessEqual(self, a, b, msg=None): - """Just like self.assert_(a <= b), but with a nicer default message.""" - if msg is None: - msg = '"%r" unexpectedly not less than or equal to "%r"' % (a, b) - self.assert_(a <= b, msg) + """Just like self.assertTrue(a <= b), but with a nicer default message.""" + if not a <= b: + standardMsg = '%r not less than or equal to %r' % (a, b) + self.fail(self._formatMessage(msg, standardMsg)) def assertGreater(self, a, b, msg=None): - """Just like self.assert_(a > b), but with a nicer default message.""" - if msg is None: - msg = '"%r" unexpectedly not greater than "%r"' % (a, b) - self.assert_(a > b, msg) + """Just like self.assertTrue(a > b), but with a nicer default message.""" + if not a > b: + standardMsg = '%r not greater than %r' % (a, b) + self.fail(self._formatMessage(msg, standardMsg)) def assertGreaterEqual(self, a, b, msg=None): - """Just like self.assert_(a >= b), but with a nicer default message.""" - if msg is None: - msg = '"%r" unexpectedly not greater than or equal to "%r"' % (a, b) - self.assert_(a >= b, msg) + """Just like self.assertTrue(a >= b), but with a nicer default message.""" + if not a >= b: + standardMsg = '%r not greater than or equal to %r' % (a, b) + self.fail(self._formatMessage(msg, standardMsg)) def assertIsNone(self, obj, msg=None): - """Same as self.assert_(obj is None), with a nicer default message.""" - if msg is None: - msg = '"%s" unexpectedly not None' % obj - self.assert_(obj is None, msg) + """Same as self.assertTrue(obj is None), with a nicer default message.""" + if obj is not None: + standardMsg = '%r is not None' % obj + self.fail(self._formatMessage(msg, standardMsg)) - def assertIsNotNone(self, obj, msg='unexpectedly None'): + def assertIsNotNone(self, obj, msg=None): """Included for symmetry with assertIsNone.""" - self.assert_(obj is not None, msg) + if obj is None: + standardMsg = 'unexpectedly None' + self.fail(self._formatMessage(msg, standardMsg)) def assertRaisesRegexp(self, expected_exception, expected_regexp, callable_obj=None, *args, **kwargs): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Apr 2 05:20:38 2009 @@ -202,6 +202,14 @@ Library ------- +- unittest.assertNotEqual() now uses the inequality operator (!=) instead + of the equality operator. + +- Issue #5663: better failure messages for unittest asserts. Default assertTrue + and assertFalse messages are now useful. TestCase has a longMessage attribute. + This defaults to False, but if set to True useful error messages are shown in + addition to explicit messages passed to assert methods. + - Issue #3110: Add additional protect around SEM_VALUE_MAX for multiprocessing - In Pdb, prevent the reassignment of __builtin__._ by sys.displayhook on From python-checkins at python.org Thu Apr 2 05:34:54 2009 From: python-checkins at python.org (brett.cannon) Date: Thu, 2 Apr 2009 05:34:54 +0200 (CEST) Subject: [Python-checkins] r71033 - in python/trunk: Include/import.h Python/import.c Message-ID: <20090402033454.315DA1E406F@bag.python.org> Author: brett.cannon Date: Thu Apr 2 05:34:53 2009 New Revision: 71033 Log: Fix two issues introduced by issue #71031 by changing the signature of PyImport_AppendInittab() to take a const char *. Modified: python/trunk/Include/import.h python/trunk/Python/import.c Modified: python/trunk/Include/import.h ============================================================================== --- python/trunk/Include/import.h (original) +++ python/trunk/Include/import.h Thu Apr 2 05:34:53 2009 @@ -43,7 +43,7 @@ PyAPI_DATA(PyTypeObject) PyNullImporter_Type; PyAPI_DATA(struct _inittab *) PyImport_Inittab; -PyAPI_FUNC(int) PyImport_AppendInittab(char *name, void (*initfunc)(void)); +PyAPI_FUNC(int) PyImport_AppendInittab(const char *name, void (*initfunc)(void)); PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab); struct _frozen { Modified: python/trunk/Python/import.c ============================================================================== --- python/trunk/Python/import.c (original) +++ python/trunk/Python/import.c Thu Apr 2 05:34:53 2009 @@ -3382,7 +3382,7 @@ memset(newtab, '\0', sizeof newtab); - newtab[0].name = name; + newtab[0].name = (char *)name; newtab[0].initfunc = initfunc; return PyImport_ExtendInittab(newtab); From python-checkins at python.org Thu Apr 2 05:41:47 2009 From: python-checkins at python.org (brett.cannon) Date: Thu, 2 Apr 2009 05:41:47 +0200 (CEST) Subject: [Python-checkins] r71034 - in python/branches/py3k: Doc/c-api/import.rst Include/import.h Python/import.c Message-ID: <20090402034147.261131E406F@bag.python.org> Author: brett.cannon Date: Thu Apr 2 05:41:46 2009 New Revision: 71034 Log: Merged revisions 71031 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71031 | brett.cannon | 2009-04-01 20:17:39 -0700 (Wed, 01 Apr 2009) | 6 lines PyImport_AppendInittab() took a char * as a first argument even though that string was stored beyond the life of the call. Changed the signature to be const char * to help make this point. Closes issue #1419652. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/import.rst python/branches/py3k/Include/import.h python/branches/py3k/Python/import.c Modified: python/branches/py3k/Doc/c-api/import.rst ============================================================================== --- python/branches/py3k/Doc/c-api/import.rst (original) +++ python/branches/py3k/Doc/c-api/import.rst Thu Apr 2 05:41:46 2009 @@ -200,7 +200,7 @@ tricks with this to provide a dynamically created collection of frozen modules. -.. cfunction:: int PyImport_AppendInittab(char *name, PyObject* (*initfunc)(void)) +.. cfunction:: int PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void)) Add a single module to the existing table of built-in modules. This is a convenience wrapper around :cfunc:`PyImport_ExtendInittab`, returning ``-1`` if Modified: python/branches/py3k/Include/import.h ============================================================================== --- python/branches/py3k/Include/import.h (original) +++ python/branches/py3k/Include/import.h Thu Apr 2 05:41:46 2009 @@ -43,7 +43,7 @@ PyAPI_DATA(PyTypeObject) PyNullImporter_Type; PyAPI_DATA(struct _inittab *) PyImport_Inittab; -PyAPI_FUNC(int) PyImport_AppendInittab(char *name, PyObject* (*initfunc)(void)); +PyAPI_FUNC(int) PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void)); PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab); struct _frozen { Modified: python/branches/py3k/Python/import.c ============================================================================== --- python/branches/py3k/Python/import.c (original) +++ python/branches/py3k/Python/import.c Thu Apr 2 05:41:46 2009 @@ -3488,13 +3488,13 @@ /* Shorthand to add a single entry given a name and a function */ int -PyImport_AppendInittab(char *name, PyObject* (*initfunc)(void)) +PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void)) { struct _inittab newtab[2]; memset(newtab, '\0', sizeof newtab); - newtab[0].name = name; + newtab[0].name = (char *)name; newtab[0].initfunc = initfunc; return PyImport_ExtendInittab(newtab); From python-checkins at python.org Thu Apr 2 06:10:08 2009 From: python-checkins at python.org (sean.reifschneider) Date: Thu, 2 Apr 2009 06:10:08 +0200 (CEST) Subject: [Python-checkins] r71035 - tracker/instances/python-dev/detectors/reopenpending.py Message-ID: <20090402041008.6F57A1E406F@bag.python.org> Author: sean.reifschneider Date: Thu Apr 2 06:10:08 2009 New Revision: 71035 Log: Auditor to change the status of pending issues to "open" when they are touched. Added: tracker/instances/python-dev/detectors/reopenpending.py Added: tracker/instances/python-dev/detectors/reopenpending.py ============================================================================== --- (empty file) +++ tracker/instances/python-dev/detectors/reopenpending.py Thu Apr 2 06:10:08 2009 @@ -0,0 +1,14 @@ +def reopen_pending(db, cl, nodeid, newvalues): + """Re-open pending issues when the issue is updated.""" + + if newvalues.has_key('status'): return + + if nodeid is None: oldStatus = None + else: oldStatus = cl.get(nodeid, 'status') + if oldStatus == db.status.lookup('pending'): + newvalues['status'] = db.status.lookup('open') + + +def init(db): + # fire before changes are made + db.issue.audit('set', reopen_pending) From python-checkins at python.org Thu Apr 2 06:22:10 2009 From: python-checkins at python.org (jesse.noller) Date: Thu, 2 Apr 2009 06:22:10 +0200 (CEST) Subject: [Python-checkins] r71036 - in python/trunk: Doc/library/multiprocessing.rst Misc/NEWS Modules/_multiprocessing/connection.h Modules/_multiprocessing/pipe_connection.c Message-ID: <20090402042210.348A41E406F@bag.python.org> Author: jesse.noller Date: Thu Apr 2 06:22:09 2009 New Revision: 71036 Log: Issue 3551: Raise ValueError if the size causes ERROR_NO_SYSTEM_RESOURCES Modified: python/trunk/Doc/library/multiprocessing.rst python/trunk/Misc/NEWS python/trunk/Modules/_multiprocessing/connection.h python/trunk/Modules/_multiprocessing/pipe_connection.c Modified: python/trunk/Doc/library/multiprocessing.rst ============================================================================== --- python/trunk/Doc/library/multiprocessing.rst (original) +++ python/trunk/Doc/library/multiprocessing.rst Thu Apr 2 06:22:09 2009 @@ -710,7 +710,8 @@ Send an object to the other end of the connection which should be read using :meth:`recv`. - The object must be picklable. + The object must be picklable. Very large pickles (approximately 32 MB+, + though it depends on the OS) may raise a ValueError exception. .. method:: recv() @@ -742,7 +743,9 @@ complete message. If *offset* is given then data is read from that position in *buffer*. If - *size* is given then that many bytes will be read from buffer. + *size* is given then that many bytes will be read from buffer. Very large + buffers (approximately 32 MB+, though it depends on the OS) may raise a + ValueError exception .. method:: recv_bytes([maxlength]) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Apr 2 06:22:09 2009 @@ -202,6 +202,10 @@ Library ------- +- Issue 3551: Patch multiprocessing to raise a proper exception if the size of the + object when writefile is called causes a ERROR_NO_SYSTEM_RESOURCES. Added docs + to note the limitation + - unittest.assertNotEqual() now uses the inequality operator (!=) instead of the equality operator. Modified: python/trunk/Modules/_multiprocessing/connection.h ============================================================================== --- python/trunk/Modules/_multiprocessing/connection.h (original) +++ python/trunk/Modules/_multiprocessing/connection.h Thu Apr 2 06:22:09 2009 @@ -131,8 +131,12 @@ res = conn_send_string(self, buffer + offset, size); - if (res < 0) - return mp_SetError(PyExc_IOError, res); + if (res < 0) { + if (PyErr_Occurred()) + return NULL; + else + return mp_SetError(PyExc_IOError, res); + } Py_RETURN_NONE; } Modified: python/trunk/Modules/_multiprocessing/pipe_connection.c ============================================================================== --- python/trunk/Modules/_multiprocessing/pipe_connection.c (original) +++ python/trunk/Modules/_multiprocessing/pipe_connection.c Thu Apr 2 06:22:09 2009 @@ -23,6 +23,12 @@ Py_BEGIN_ALLOW_THREADS ret = WriteFile(conn->handle, string, length, &amount_written, NULL); Py_END_ALLOW_THREADS + + if (ret == 0 && GetLastError() == ERROR_NO_SYSTEM_RESOURCES) { + PyErr_Format(PyExc_ValueError, "Cannnot send %" PY_FORMAT_SIZE_T "d bytes over connection", length); + return MP_STANDARD_ERROR; + } + return ret ? MP_SUCCESS : MP_STANDARD_ERROR; } From buildbot at python.org Thu Apr 2 06:31:18 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 02 Apr 2009 04:31:18 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 2.6 Message-ID: <20090402043118.98A331E406F@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%202.6/builds/214 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: benjamin.peterson BUILD FAILED: failed svn sincerely, -The Buildbot From python-checkins at python.org Thu Apr 2 06:34:05 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 2 Apr 2009 06:34:05 +0200 (CEST) Subject: [Python-checkins] r71037 - python/trunk/Doc/library/datetime.rst Message-ID: <20090402043405.17DE91E406F@bag.python.org> Author: r.david.murray Date: Thu Apr 2 06:34:04 2009 New Revision: 71037 Log: Clarify that datetime strftime does not produce leap seconds and datetime strptime does not accept it in the strftime behavior section of the datetime docs. Closes issue 2568. Modified: python/trunk/Doc/library/datetime.rst Modified: python/trunk/Doc/library/datetime.rst ============================================================================== --- python/trunk/Doc/library/datetime.rst (original) +++ python/trunk/Doc/library/datetime.rst Thu Apr 2 06:34:04 2009 @@ -1629,8 +1629,12 @@ the output hour field if the ``%I`` directive is used to parse the hour. (3) - The range really is ``0`` to ``61``; this accounts for leap seconds and the - (very rare) double leap seconds. + The range really is ``0`` to ``61``; according to the Posix standard this + accounts for leap seconds and the (very rare) double leap seconds. + The :mod:`time` module may produce and does accept leap seconds since + it is based on the Posix standard, but the :mod:`datetime` module + does not accept leap seconds in :func:`strptime` input nor will it + produce them in :func:`strftime` output. (4) When used with the :func:`strptime` function, ``%U`` and ``%W`` are only used in From python-checkins at python.org Thu Apr 2 06:50:27 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 2 Apr 2009 06:50:27 +0200 (CEST) Subject: [Python-checkins] r71038 - python/branches/py3k/Doc/library/datetime.rst Message-ID: <20090402045027.D3C671E406F@bag.python.org> Author: r.david.murray Date: Thu Apr 2 06:50:03 2009 New Revision: 71038 Log: Clarify that datetime strftime does not produce leap seconds and datetime strptime does not accept it in the strftime behavior section of the datetime docs. Closes issue 2568. Porting by hand since svnmerge disclaims all knowledge of the trunk commit. Modified: python/branches/py3k/Doc/library/datetime.rst Modified: python/branches/py3k/Doc/library/datetime.rst ============================================================================== --- python/branches/py3k/Doc/library/datetime.rst (original) +++ python/branches/py3k/Doc/library/datetime.rst Thu Apr 2 06:50:03 2009 @@ -1621,8 +1621,12 @@ the output hour field if the ``%I`` directive is used to parse the hour. (3) - The range really is ``0`` to ``61``; this accounts for leap seconds and the - (very rare) double leap seconds. + The range really is ``0`` to ``61``; according to the Posix standard this + accounts for leap seconds and the (very rare) double leap seconds. + The :mod:`time` module may produce and does accept leap seconds since + it is based on the Posix standard, but the :mod:`datetime` module + does not accept leap seconds in :func:`strptime` input nor will it + produce them in :func:`strftime` output. (4) When used with the :func:`strptime` function, ``%U`` and ``%W`` are only used in From python-checkins at python.org Thu Apr 2 06:52:48 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 2 Apr 2009 06:52:48 +0200 (CEST) Subject: [Python-checkins] r71039 - in python/branches/release26-maint: Doc/library/datetime.rst Message-ID: <20090402045248.DC6CD1E406F@bag.python.org> Author: r.david.murray Date: Thu Apr 2 06:52:48 2009 New Revision: 71039 Log: Merged revisions 71037 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71037 | r.david.murray | 2009-04-02 00:34:04 -0400 (Thu, 02 Apr 2009) | 6 lines Clarify that datetime strftime does not produce leap seconds and datetime strptime does not accept it in the strftime behavior section of the datetime docs. Closes issue 2568. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/datetime.rst Modified: python/branches/release26-maint/Doc/library/datetime.rst ============================================================================== --- python/branches/release26-maint/Doc/library/datetime.rst (original) +++ python/branches/release26-maint/Doc/library/datetime.rst Thu Apr 2 06:52:48 2009 @@ -1629,8 +1629,12 @@ the output hour field if the ``%I`` directive is used to parse the hour. (3) - The range really is ``0`` to ``61``; this accounts for leap seconds and the - (very rare) double leap seconds. + The range really is ``0`` to ``61``; according to the Posix standard this + accounts for leap seconds and the (very rare) double leap seconds. + The :mod:`time` module may produce and does accept leap seconds since + it is based on the Posix standard, but the :mod:`datetime` module + does not accept leap seconds in :func:`strptime` input nor will it + produce them in :func:`strftime` output. (4) When used with the :func:`strptime` function, ``%U`` and ``%W`` are only used in From python-checkins at python.org Thu Apr 2 07:01:10 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 2 Apr 2009 07:01:10 +0200 (CEST) Subject: [Python-checkins] r71040 - in python/branches/release30-maint: Doc/library/datetime.rst Message-ID: <20090402050110.A07541E406F@bag.python.org> Author: r.david.murray Date: Thu Apr 2 07:01:10 2009 New Revision: 71040 Log: Merged revisions 71038 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r71038 | r.david.murray | 2009-04-02 00:50:03 -0400 (Thu, 02 Apr 2009) | 9 lines Clarify that datetime strftime does not produce leap seconds and datetime strptime does not accept it in the strftime behavior section of the datetime docs. Closes issue 2568. ........ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Doc/library/datetime.rst Modified: python/branches/release30-maint/Doc/library/datetime.rst ============================================================================== --- python/branches/release30-maint/Doc/library/datetime.rst (original) +++ python/branches/release30-maint/Doc/library/datetime.rst Thu Apr 2 07:01:10 2009 @@ -1621,8 +1621,12 @@ the output hour field if the ``%I`` directive is used to parse the hour. (3) - The range really is ``0`` to ``61``; this accounts for leap seconds and the - (very rare) double leap seconds. + The range really is ``0`` to ``61``; according to the Posix standard this + accounts for leap seconds and the (very rare) double leap seconds. + The :mod:`time` module may produce and does accept leap seconds since + it is based on the Posix standard, but the :mod:`datetime` module + does not accept leap seconds in :func:`strptime` input nor will it + produce them in :func:`strftime` output. (4) When used with the :func:`strptime` function, ``%U`` and ``%W`` are only used in From buildbot at python.org Thu Apr 2 07:06:32 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 02 Apr 2009 05:06:32 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090402050632.4D83C1E416C@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/241 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: benjamin.peterson,raymond.hettinger BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_distutils test_posix ====================================================================== FAIL: test_get_python_inc (distutils.tests.test_sysconfig.SysconfigTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/distutils/tests/test_sysconfig.py", line 45, in test_get_python_inc self.assert_(os.path.isdir(inc_dir), inc_dir) AssertionError: /home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/Include ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Thu Apr 2 07:17:27 2009 From: python-checkins at python.org (jesse.noller) Date: Thu, 2 Apr 2009 07:17:27 +0200 (CEST) Subject: [Python-checkins] r71041 - in python/trunk: Doc/library/multiprocessing.rst Lib/multiprocessing/managers.py Lib/multiprocessing/pool.py Lib/test/test_multiprocessing.py Misc/NEWS Message-ID: <20090402051727.16C001E416C@bag.python.org> Author: jesse.noller Date: Thu Apr 2 07:17:26 2009 New Revision: 71041 Log: Add custom initializer argument to multiprocess.Manager*, courtesy of lekma Modified: python/trunk/Doc/library/multiprocessing.rst python/trunk/Lib/multiprocessing/managers.py python/trunk/Lib/multiprocessing/pool.py python/trunk/Lib/test/test_multiprocessing.py python/trunk/Misc/NEWS Modified: python/trunk/Doc/library/multiprocessing.rst ============================================================================== --- python/trunk/Doc/library/multiprocessing.rst (original) +++ python/trunk/Doc/library/multiprocessing.rst Thu Apr 2 07:17:26 2009 @@ -1130,9 +1130,10 @@ ``current_process().authkey``. Otherwise *authkey* is used and it must be a string. - .. method:: start() + .. method:: start([initializer[, initargs]]) - Start a subprocess to start the manager. + Start a subprocess to start the manager. If *initializer* is not ``None`` + then the subprocess will call ``initializer(*initargs)`` when it starts. .. method:: serve_forever() Modified: python/trunk/Lib/multiprocessing/managers.py ============================================================================== --- python/trunk/Lib/multiprocessing/managers.py (original) +++ python/trunk/Lib/multiprocessing/managers.py Thu Apr 2 07:17:26 2009 @@ -475,12 +475,15 @@ dispatch(conn, None, 'dummy') self._state.value = State.STARTED - def start(self): + def start(self, initializer=None, initargs=()): ''' Spawn a server process for this manager object ''' assert self._state.value == State.INITIAL + if initializer is not None and not hasattr(initializer, '__call__'): + raise TypeError('initializer must be a callable') + # pipe over which we will retrieve address of server reader, writer = connection.Pipe(duplex=False) @@ -488,7 +491,7 @@ self._process = Process( target=type(self)._run_server, args=(self._registry, self._address, self._authkey, - self._serializer, writer), + self._serializer, writer, initializer, initargs), ) ident = ':'.join(str(i) for i in self._process._identity) self._process.name = type(self).__name__ + '-' + ident @@ -509,10 +512,14 @@ ) @classmethod - def _run_server(cls, registry, address, authkey, serializer, writer): + def _run_server(cls, registry, address, authkey, serializer, writer, + initializer=None, initargs=()): ''' Create a server, report its address and run it ''' + if initializer is not None: + initializer(*initargs) + # create server server = cls._Server(registry, address, authkey, serializer) Modified: python/trunk/Lib/multiprocessing/pool.py ============================================================================== --- python/trunk/Lib/multiprocessing/pool.py (original) +++ python/trunk/Lib/multiprocessing/pool.py Thu Apr 2 07:17:26 2009 @@ -92,6 +92,9 @@ except NotImplementedError: processes = 1 + if initializer is not None and not hasattr(initializer, '__call__'): + raise TypeError('initializer must be a callable') + self._pool = [] for i in range(processes): w = self.Process( Modified: python/trunk/Lib/test/test_multiprocessing.py ============================================================================== --- python/trunk/Lib/test/test_multiprocessing.py (original) +++ python/trunk/Lib/test/test_multiprocessing.py Thu Apr 2 07:17:26 2009 @@ -1831,7 +1831,37 @@ multiprocessing.connection.answer_challenge, _FakeConnection(), b'abc') -testcases_other = [OtherTest, TestInvalidHandle] +# +# Test Manager.start()/Pool.__init__() initializer feature - see issue 5585 +# + +def initializer(ns): + ns.test += 1 + +class TestInitializers(unittest.TestCase): + def setUp(self): + self.mgr = multiprocessing.Manager() + self.ns = self.mgr.Namespace() + self.ns.test = 0 + + def tearDown(self): + self.mgr.shutdown() + + def test_manager_initializer(self): + m = multiprocessing.managers.SyncManager() + self.assertRaises(TypeError, m.start, 1) + m.start(initializer, (self.ns,)) + self.assertEqual(self.ns.test, 1) + m.shutdown() + + def test_pool_initializer(self): + self.assertRaises(TypeError, multiprocessing.Pool, initializer=1) + p = multiprocessing.Pool(1, initializer, (self.ns,)) + p.close() + p.join() + self.assertEqual(self.ns.test, 1) + +testcases_other = [OtherTest, TestInvalidHandle, TestInitializers] # # Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Apr 2 07:17:26 2009 @@ -202,6 +202,9 @@ Library ------- +- Issue 5585: Add the ability to call an initializer to mulitiprocessing.manager + so that users can install custonm handlers/etc. + - Issue 3551: Patch multiprocessing to raise a proper exception if the size of the object when writefile is called causes a ERROR_NO_SYSTEM_RESOURCES. Added docs to note the limitation From python-checkins at python.org Thu Apr 2 07:17:54 2009 From: python-checkins at python.org (brett.cannon) Date: Thu, 2 Apr 2009 07:17:54 +0200 (CEST) Subject: [Python-checkins] r71042 - python/branches/py3k/Lib/importlib/test/util.py Message-ID: <20090402051754.4AF4D1E416C@bag.python.org> Author: brett.cannon Date: Thu Apr 2 07:17:54 2009 New Revision: 71042 Log: Check that on a platform that is expected to have a case-insensitive filesystem that is in fact the case. Closes issue #5442. Modified: python/branches/py3k/Lib/importlib/test/util.py Modified: python/branches/py3k/Lib/importlib/test/util.py ============================================================================== --- python/branches/py3k/Lib/importlib/test/util.py (original) +++ python/branches/py3k/Lib/importlib/test/util.py Thu Apr 2 07:17:54 2009 @@ -1,7 +1,7 @@ from contextlib import contextmanager import imp import os.path -from test.support import unlink +from test import support import unittest import sys @@ -10,6 +10,13 @@ """Class decorator that nullifies tests that require a case-insensitive file system.""" if sys.platform not in ('win32', 'darwin', 'cygwin'): + original_name = os.path.listdir('.')[0] + if name.upper() != name: + changed_name = name.upper() + else: + changed_name = name.lower() + if os.path.exists(changed_name): + return class_ return unittest.TestCase else: return class_ From python-checkins at python.org Thu Apr 2 07:51:54 2009 From: python-checkins at python.org (michael.foord) Date: Thu, 2 Apr 2009 07:51:54 +0200 (CEST) Subject: [Python-checkins] r71043 - in python/trunk/Lib: test/test_unittest.py unittest.py Message-ID: <20090402055154.D3F321E4144@bag.python.org> Author: michael.foord Date: Thu Apr 2 07:51:54 2009 New Revision: 71043 Log: Store the functions in the _type_equality_funcs as wrapped objects that are deep copyable. This allows for the deep copying of TestCase instances. Issue 5660 Modified: python/trunk/Lib/test/test_unittest.py python/trunk/Lib/unittest.py Modified: python/trunk/Lib/test/test_unittest.py ============================================================================== --- python/trunk/Lib/test/test_unittest.py (original) +++ python/trunk/Lib/test/test_unittest.py Thu Apr 2 07:51:54 2009 @@ -11,6 +11,7 @@ import unittest from unittest import TestCase import types +from copy import deepcopy ### Support code ################################################################ @@ -2688,6 +2689,17 @@ self.failUnlessRaises(TypeError, lambda _: 3.14 + u'spam') self.failIf(False) + def testDeepcopy(self): + # Issue: 5660 + class TestableTest(TestCase): + def testNothing(self): + pass + + test = TestableTest('testNothing') + + # This shouldn't blow up + deepcopy(test) + class Test_TestSkipping(TestCase): Modified: python/trunk/Lib/unittest.py ============================================================================== --- python/trunk/Lib/unittest.py (original) +++ python/trunk/Lib/unittest.py Thu Apr 2 07:51:54 2009 @@ -160,7 +160,6 @@ raise _UnexpectedSuccess return wrapper - __unittest = 1 class TestResult(object): @@ -289,6 +288,16 @@ return True +class _AssertWrapper(object): + """Wrap entries in the _type_equality_funcs registry to make them deep + copyable.""" + + def __init__(self, function): + self.function = function + + def __deepcopy__(self, memo): + memo[id(self)] = self + class TestCase(object): """A class whose instances are single test cases. @@ -361,7 +370,7 @@ msg= argument that raises self.failureException with a useful error message when the two arguments are not equal. """ - self._type_equality_funcs[typeobj] = function + self._type_equality_funcs[typeobj] = _AssertWrapper(function) def setUp(self): "Hook method for setting up the test fixture before exercising it." @@ -542,8 +551,10 @@ # See the discussion in http://bugs.python.org/issue2578. # if type(first) is type(second): - return self._type_equality_funcs.get(type(first), - self._baseAssertEqual) + asserter = self._type_equality_funcs.get(type(first)) + if asserter is not None: + return asserter.function + return self._baseAssertEqual def _baseAssertEqual(self, first, second, msg=None): From buildbot at python.org Thu Apr 2 09:41:09 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 02 Apr 2009 07:41:09 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.0 Message-ID: <20090402074109.931181E4884@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.0/builds/241 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: r.david.murray BUILD FAILED: failed failed slave lost sincerely, -The Buildbot From python-checkins at python.org Thu Apr 2 10:31:49 2009 From: python-checkins at python.org (paul.kippes) Date: Thu, 2 Apr 2009 10:31:49 +0200 (CEST) Subject: [Python-checkins] r71044 - sandbox/trunk/refactor_pkg/refactor/fixes/from3/fix_print.py Message-ID: <20090402083149.C64A71E405D@bag.python.org> Author: paul.kippes Date: Thu Apr 2 10:31:49 2009 New Revision: 71044 Log: 3to2 sandbox: added fix_print.py; unittest fails but could be issue with unittest cases Added: sandbox/trunk/refactor_pkg/refactor/fixes/from3/fix_print.py Added: sandbox/trunk/refactor_pkg/refactor/fixes/from3/fix_print.py ============================================================================== --- (empty file) +++ sandbox/trunk/refactor_pkg/refactor/fixes/from3/fix_print.py Thu Apr 2 10:31:49 2009 @@ -0,0 +1,154 @@ +# Based on fix_xrange.py +# 3to2 modification by Paul Kippes + +"""Fixer for print. + +Change: + 'print()' --> 'print' + 'print(..., end="")' --> 'print ... ,' + 'print(..., file=x)' --> 'print >>x, ...' +""" + +#from ..fixer_urllib import * +from ..fixer_common import * +from ...pygram import python_symbols as syms +from ...pytree import Leaf, Node +from ...pgen2 import token + +from pprint import pprint +import pdb + +class FixPrint(fixer_base.BaseFix): + + PATTERN = """ + power< name='print' trailer< '(' [any] ')' > > + """ + + + + + + +# 2-->3 +# print "The answer is" +# [Leaf(3, '"The answer is"')] + +# print "The answer is", 3*3 +# [Leaf(3, '"The answer is"'), Leaf(12, ','), Node(term, [Leaf(2, '3'), Leaf(16, '*'), Leaf(2, '3')])] + +# print "The answer is", 3*3, 5*5 +# [Leaf(3, '"The answer is"'), Leaf(12, ','), Node(term, [Leaf(2, '3'), Leaf(16, '*'), Leaf(2, '3')]), Leaf(12, ','), Node(term, [Leaf(2, '5'), Leaf(16, '*'), Leaf(2, '5')])] + +# print "The answer is", 3*3, 5*5, +# [Leaf(3, '"The answer is"'), Leaf(12, ','), Node(term, [Leaf(2, '3'), Leaf(16, '*'), Leaf(2, '3')]), Leaf(12, ','), Node(term, [Leaf(2, '5'), Leaf(16, '*'), Leaf(2, '5')]), Leaf(12, ',')] + +# print "The answer is %s" % "substring" +# [Node(term, [Leaf(3, '"The answer is %s"'), Leaf(24, '%'), Leaf(3, '"substring"')])] + + + + +# 3-->2 + +# print("The answer is") +# args=[Node(trailer, [Leaf(7, '('), Leaf(3, '"The answer is"'), Leaf(8, ')')])] + +# print("The answer is", 3*3) +# args=[Node(trailer, [Leaf(7, '('), Node(arglist, [Leaf(3, '"The answer is"'), Leaf(12, ','), Node(term, [Leaf(2, '3'), Leaf(16, '*'), Leaf(2, '3')])]), Leaf(8, ')')])] + +# print("The answer is %s" % "substring") +# args=[Node(trailer, [Leaf(7, '('), Node(term, [Leaf(3, '"The answer is %s"'), Leaf(24, '%'), Leaf(3, '"substring"')]), Leaf(8, ')')])] + + + # answer is"'), Leaf(8, ')')])]) + # --------------------------------------------------------------------- + # print '', + # + # Node(print_stmt,[ + # Leaf(1, 'print'), + # Leaf(3, "''"), + # Leaf(12, ',')]) + # --------------------------------------------------------------------- + # print >>sys.stderr, 'test', + # + # Node(print_stmt,[ + # Leaf(1, 'print'), Leaf(35, '>>'), # redirect + # Node(power, [ + # Leaf(1, 'sys'), # FILE + # Node(trailer, [ # .. + # Leaf(23, '.'), # .. + # Leaf(1, 'stderr')])]), # .. + # Leaf(12, ','), + # Leaf(3, '"test"'), # 'test' + # Leaf(12, ',')]) # newline suppression + # --------------------------------------------------------------------- + + def find_argument(self, nodes, arg_name): + """Given an argument or argument list of arguments, return a + copy of the argument's value. + """ + for node in nodes: + # Node is an argument? + if node.type == 260: + if (node.children[0].value == arg_name and + node.children[1].type == token.EQUAL): + return node.children[2] + # Node is an argument list? + elif node.type == 259: + return self.find_argument(node.children, arg_name) + return None + + def arg_clone_and_remove(self, node): + if node: + node_copy = node.clone() + node.parent.remove() + return node_copy + return None + + def transform(self, node, results): + assert node.children[0].value == 'print' + # extract items between parens + args = node.children[1].children[1:-1] + # extract arguments file=value and end=value + arg_file = self.arg_clone_and_remove(self.find_argument(args, 'file')) + arg_end = self.arg_clone_and_remove(self.find_argument(args, 'end')) + # Reevaluate args after potential removal + args = node.children[1].children[1:-1] + # extract all string components and append to string_args + string_args = [] + for outter_arg in args: + if outter_arg.type == token.STRING or outter_arg.type == 321: + # extract print("string") + # extract print("%s" % "string") + string_args.append(outter_arg.clone()) + elif outter_arg.type == 259: + # extract print("string", 5) + # extract print("string", "") + for inner_arg in outter_arg.children: + if inner_arg.type != token.COMMA: + string_args.append(inner_arg.clone()) + # combine extracted parts into print statement + print_stmt = Node(syms.print_stmt, [Leaf(token.NAME, 'print')]) + if arg_file: + print_stmt.append_child(Leaf(token.RIGHTSHIFT, '>>', prefix=' ')) + print_stmt.append_child(arg_file) + if string_args: + print_stmt.append_child(Leaf(token.COMMA, ',')) + for i, string_arg in enumerate(string_args): + if i: + print_stmt.append_child(Leaf(token.COMMA, ',')) + string_arg.set_prefix(' ') + print_stmt.append_child(string_arg) + else: + string_arg.set_prefix(' ') + print_stmt.append_child(string_arg) + # if 'end' argument is specified, add end character to last string + if arg_end and arg_end.value == "''": + print_stmt.append_child(Leaf(token.COMMA, ',')) + elif arg_end: + if string_arg: + print_stmt.append_child(Leaf(token.PLUS, '+', prefix=' ')) + arg_end.set_prefix(' ') + print_stmt.append_child(arg_end) + print_stmt.append_child(Leaf(token.COMMA, ',')) + return print_stmt From chris at simplistix.co.uk Thu Apr 2 11:20:59 2009 From: chris at simplistix.co.uk (Chris Withers) Date: Thu, 02 Apr 2009 10:20:59 +0100 Subject: [Python-checkins] r70772 - in python/trunk: Doc/library/email.header.rst Lib/email/generator.py Lib/email/test/test_email.py Lib/email/test/test_email_renamed.py In-Reply-To: <20090330224217.A62241E4002@bag.python.org> References: <20090330224217.A62241E4002@bag.python.org> Message-ID: <49D4837B.2090303@simplistix.co.uk> barry.warsaw wrote: > - # Header's got lots of smarts, so use it. > + # Header's got lots of smarts, so use it. Note that this is > + # fundamentally broken though because we lose idempotency when > + # the header string is continued with tabs. It will now be > + # continued with spaces. This was reversedly broken before we > + # fixed bug 1974. Either way, we lose. > print >> self._fp, Header( > - v, maxlinelen=self._maxheaderlen, > - header_name=h, continuation_ws='\t').encode() > + v, maxlinelen=self._maxheaderlen, header_name=h).encode() > # A blank line always separates headers from body > print >> self._fp How do we get idempotency back in 3.0? I know we talked about a Header class registry and always using Header objects, but jetlag has rotted my brain as to when and how we planned to deliver that? > @@ -251,7 +251,16 @@ > msg = self._msgobj('msg_01.txt') > fp = openfile('msg_01.txt') > try: > - text = fp.read() > + # BAW 30-Mar-2009 Evil be here. So, the generator is broken with > + # respect to long line breaking. It's also not idempotent when a > + # header from a parsed message is continued with tabs rather than > + # spaces. Before we fixed bug 1974 it was reversedly broken, > + # i.e. headers that were continued with spaces got continued with > + # tabs. For Python 2.x there's really no good fix and in Python > + # 3.x all this stuff is re-written to be right(er). Chris Withers > + # convinced me that using space as the default continuation > + # character is less bad for more applications. Heh, thanks for the blame tag ;-) All looks fine though. #5612 we didn't touch on though, although I have a feeling we decided to head-in-sand that one for 2.x? Chris -- Simplistix - Content Management, Zope & Python Consulting - http://www.simplistix.co.uk From python-checkins at python.org Thu Apr 2 12:33:17 2009 From: python-checkins at python.org (hyeshik.chang) Date: Thu, 2 Apr 2009 12:33:17 +0200 (CEST) Subject: [Python-checkins] r71045 - in python/branches/py3k: Lib/test/test_multibytecodec.py Misc/NEWS Modules/cjkcodecs/multibytecodec.c Message-ID: <20090402103317.3EB721E4217@bag.python.org> Author: hyeshik.chang Date: Thu Apr 2 12:33:16 2009 New Revision: 71045 Log: Issue #5640: Fix _multibytecodec so that CJK codecs don't repeat error replacement returned by codec error callbacks twice in IncrementalEncoder and StreamWriter. Modified: python/branches/py3k/Lib/test/test_multibytecodec.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/cjkcodecs/multibytecodec.c Modified: python/branches/py3k/Lib/test/test_multibytecodec.py ============================================================================== --- python/branches/py3k/Lib/test/test_multibytecodec.py (original) +++ python/branches/py3k/Lib/test/test_multibytecodec.py Thu Apr 2 12:33:16 2009 @@ -112,6 +112,10 @@ self.assertRaises(UnicodeEncodeError, encoder.encode, '\u0123') self.assertEqual(encoder.encode('', True), b'\xa9\xdc') + def test_issue5640(self): + encoder = codecs.getincrementalencoder('shift-jis')('backslashreplace') + self.assertEqual(encoder.encode('\xff'), b'\\xff') + self.assertEqual(encoder.encode('\n'), b'\n') class Test_IncrementalDecoder(unittest.TestCase): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Apr 2 12:33:16 2009 @@ -58,6 +58,10 @@ Library ------- +- Issue #5640: Fix _multibytecodec so that CJK codecs don't repeat + error substitutions from non-strict codec error callbacks in + incrementalencoder and StreamWriter. + - Issue #5656: Fix the coverage reporting when running the test suite with the -T argument. Modified: python/branches/py3k/Modules/cjkcodecs/multibytecodec.c ============================================================================== --- python/branches/py3k/Modules/cjkcodecs/multibytecodec.c (original) +++ python/branches/py3k/Modules/cjkcodecs/multibytecodec.c Thu Apr 2 12:33:16 2009 @@ -506,7 +506,6 @@ outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf); r = codec->encode(state, codec->config, &buf.inbuf, inleft, &buf.outbuf, outleft, flags); - *data = buf.inbuf; if ((r == 0) || (r == MBERR_TOOFEW && !(flags & MBENC_FLUSH))) break; else if (multibytecodec_encerror(codec, state, &buf, errors,r)) @@ -536,6 +535,7 @@ if (_PyBytes_Resize(&buf.outobj, finalsize) == -1) goto errorexit; + *data = buf.inbuf; Py_XDECREF(buf.excobj); return buf.outobj; From hyeshik at gmail.com Thu Apr 2 12:39:04 2009 From: hyeshik at gmail.com (Hyeshik Chang) Date: Thu, 2 Apr 2009 19:39:04 +0900 Subject: [Python-checkins] r71045 - in python/branches/py3k: Lib/test/test_multibytecodec.py Misc/NEWS Modules/cjkcodecs/multibytecodec.c In-Reply-To: <20090402103317.3EB721E4217@bag.python.org> References: <20090402103317.3EB721E4217@bag.python.org> Message-ID: <4f0b69dc0904020339i5b407cfalde82ea5654f9caaa@mail.gmail.com> On Thu, Apr 2, 2009 at 7:33 PM, hyeshik.chang wrote: > Author: hyeshik.chang > Date: Thu Apr ?2 12:33:16 2009 > New Revision: 71045 > > Log: > Issue #5640: Fix _multibytecodec so that CJK codecs don't repeat > error replacement returned by codec error callbacks twice in > IncrementalEncoder and StreamWriter. > > > Modified: > ? python/branches/py3k/Lib/test/test_multibytecodec.py > ? python/branches/py3k/Misc/NEWS > ? python/branches/py3k/Modules/cjkcodecs/multibytecodec.c > Sorry but I just found that this fix should be applied in trunk first because the problem was in 2.x. How can I correct that? Hyeshik From buildbot at python.org Thu Apr 2 13:15:09 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 02 Apr 2009 11:15:09 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090402111510.434DF1E4097@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/503 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: hyeshik.chang BUILD FAILED: failed test Excerpt from the test logfile: 3 tests failed: test_distutils test_importlib test_urllib2net Traceback (most recent call last): File "./Lib/test/regrtest.py", line 620, in runtest_inner indirect_test() File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/test/test_importlib.py", line 6, in test_main run_unittest(importlib.test.test_suite('importlib.test')) File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/importlib/test/__init__.py", line 22, in test_suite package_tests = getattr(sys.modules[package_name], 'test_suite')() File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/importlib/test/source/__init__.py", line 8, in test_suite return importlib.test.test_suite('importlib.test.source', directory) File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/importlib/test/__init__.py", line 16, in test_suite __import__(module_name, level=0) File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/importlib/test/source/test_case_sensitivity.py", line 12, in class CaseSensitivityTest(unittest.TestCase): File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/importlib/test/util.py", line 13, in case_insensitive_tests original_name = os.path.listdir('.')[0] AttributeError: 'module' object has no attribute 'listdir' ====================================================================== ERROR: test_http_basic (test.test_urllib2net.TimeoutTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/test/test_urllib2net.py", line 198, in test_http_basic self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None) AttributeError: '_io.BufferedReader' object has no attribute 'fp' ====================================================================== ERROR: test_http_default_timeout (test.test_urllib2net.TimeoutTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/test/test_urllib2net.py", line 207, in test_http_default_timeout self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60) AttributeError: '_io.BufferedReader' object has no attribute 'fp' ====================================================================== ERROR: test_http_no_timeout (test.test_urllib2net.TimeoutTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/test/test_urllib2net.py", line 216, in test_http_no_timeout self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None) AttributeError: '_io.BufferedReader' object has no attribute 'fp' ====================================================================== ERROR: test_http_timeout (test.test_urllib2net.TimeoutTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/test/test_urllib2net.py", line 220, in test_http_timeout self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 120) AttributeError: '_io.BufferedReader' object has no attribute 'fp' make: *** [buildbottest] Error 1 sincerely, -The Buildbot From ncoghlan at gmail.com Thu Apr 2 13:55:31 2009 From: ncoghlan at gmail.com (Nick Coghlan) Date: Thu, 02 Apr 2009 21:55:31 +1000 Subject: [Python-checkins] r71045 - in python/branches/py3k: Lib/test/test_multibytecodec.py Misc/NEWS Modules/cjkcodecs/multibytecodec.c In-Reply-To: <4f0b69dc0904020339i5b407cfalde82ea5654f9caaa@mail.gmail.com> References: <20090402103317.3EB721E4217@bag.python.org> <4f0b69dc0904020339i5b407cfalde82ea5654f9caaa@mail.gmail.com> Message-ID: <49D4A7B3.2090207@gmail.com> Hyeshik Chang wrote: > On Thu, Apr 2, 2009 at 7:33 PM, hyeshik.chang > wrote: >> Author: hyeshik.chang >> Date: Thu Apr 2 12:33:16 2009 >> New Revision: 71045 >> >> Log: >> Issue #5640: Fix _multibytecodec so that CJK codecs don't repeat >> error replacement returned by codec error callbacks twice in >> IncrementalEncoder and StreamWriter. >> >> >> Modified: >> python/branches/py3k/Lib/test/test_multibytecodec.py >> python/branches/py3k/Misc/NEWS >> python/branches/py3k/Modules/cjkcodecs/multibytecodec.c >> > > Sorry but I just found that this fix should be applied in trunk first because > the problem was in 2.x. How can I correct that? Since it has already been committed to the 3k branch, I believe the easiest way is to backport it manually to the 2.x trunk and then block that checkin from being forward ported (i.e. pretty much the same way that new features that are initially developed for 3.x get backported to 2.x). Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- From python-checkins at python.org Thu Apr 2 16:05:35 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 2 Apr 2009 16:05:35 +0200 (CEST) Subject: [Python-checkins] r71046 - in python/trunk: Lib/mailbox.py Lib/test/test_mailbox.py Misc/NEWS Message-ID: <20090402140535.AEFF11E4024@bag.python.org> Author: r.david.murray Date: Thu Apr 2 16:05:35 2009 New Revision: 71046 Log: Add missing iteritems() call to the for loop in mailbox.MH.get_message(). Fixes issue2625. Modified: python/trunk/Lib/mailbox.py python/trunk/Lib/test/test_mailbox.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/mailbox.py ============================================================================== --- python/trunk/Lib/mailbox.py (original) +++ python/trunk/Lib/mailbox.py Thu Apr 2 16:05:35 2009 @@ -911,7 +911,7 @@ _unlock_file(f) finally: f.close() - for name, key_list in self.get_sequences(): + for name, key_list in self.get_sequences().iteritems(): if key in key_list: msg.add_sequence(name) return msg Modified: python/trunk/Lib/test/test_mailbox.py ============================================================================== --- python/trunk/Lib/test/test_mailbox.py (original) +++ python/trunk/Lib/test/test_mailbox.py Thu Apr 2 16:05:35 2009 @@ -936,6 +936,12 @@ self._box.remove(key1) self.assert_(self._box.get_sequences() == {'flagged':[key0]}) + def test_issue2625(self): + msg0 = mailbox.MHMessage(self._template % 0) + msg0.add_sequence('foo') + key0 = self._box.add(msg0) + refmsg0 = self._box.get_message(key0) + def test_pack(self): # Pack the contents of the mailbox msg0 = mailbox.MHMessage(self._template % 0) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Apr 2 16:05:35 2009 @@ -202,6 +202,9 @@ Library ------- +- Issue 2625: added missing iteritems() call to the for loop in + mailbox.MH.get_message(). + - Issue 5585: Add the ability to call an initializer to mulitiprocessing.manager so that users can install custonm handlers/etc. From python-checkins at python.org Thu Apr 2 16:06:35 2009 From: python-checkins at python.org (eric.smith) Date: Thu, 2 Apr 2009 16:06:35 +0200 (CEST) Subject: [Python-checkins] r71047 - in python/branches/py3k-short-float-repr: Include/pystrtod.h Modules/_pickle.c Objects/complexobject.c Objects/floatobject.c Objects/unicodeobject.c Python/marshal.c Python/pystrtod.c Message-ID: <20090402140635.74A5D1E4024@bag.python.org> Author: eric.smith Date: Thu Apr 2 16:06:34 2009 New Revision: 71047 Log: Removed explicit mode parameter, now derive the mode from the format_code. Added special format_code 'r' for use with repr. Many tests still fail, this is just a checkpoint so Mark and I can synchronize. Modified: python/branches/py3k-short-float-repr/Include/pystrtod.h python/branches/py3k-short-float-repr/Modules/_pickle.c python/branches/py3k-short-float-repr/Objects/complexobject.c python/branches/py3k-short-float-repr/Objects/floatobject.c python/branches/py3k-short-float-repr/Objects/unicodeobject.c python/branches/py3k-short-float-repr/Python/marshal.c python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Include/pystrtod.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/pystrtod.h (original) +++ python/branches/py3k-short-float-repr/Include/pystrtod.h Thu Apr 2 16:06:34 2009 @@ -10,7 +10,6 @@ PyAPI_FUNC(double) PyOS_ascii_atof(const char *str); PyAPI_FUNC(char *) PyOS_ascii_formatd(char *buffer, size_t buf_len, const char *format, double d); PyAPI_FUNC(char *) PyOS_double_to_string(double val, - int mode, char format_code, int precision, int flags); Modified: python/branches/py3k-short-float-repr/Modules/_pickle.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_pickle.c (original) +++ python/branches/py3k-short-float-repr/Modules/_pickle.c Thu Apr 2 16:06:34 2009 @@ -1025,7 +1025,7 @@ if (pickler_write(self, &op, 1) < 0) goto done; - buf = PyOS_double_to_string(x, 2, 'g', 17, 0); + buf = PyOS_double_to_string(x, 'g', 17, 0); if (!buf) { PyErr_NoMemory(); goto done; Modified: python/branches/py3k-short-float-repr/Objects/complexobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/complexobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/complexobject.c Thu Apr 2 16:06:34 2009 @@ -339,7 +339,7 @@ static PyObject * -complex_format(PyComplexObject *v, int mode, int precision) +complex_format(PyComplexObject *v, char format_code, int precision) { PyObject *result = NULL; Py_ssize_t len; @@ -368,7 +368,8 @@ im = "-inf*"; } else { - pim = PyOS_double_to_string(v->cval.imag, mode, 'g', precision, 0); + pim = PyOS_double_to_string(v->cval.imag, format_code, + precision, 0); if (!pim) { PyErr_NoMemory(); goto done; @@ -387,7 +388,8 @@ re = "-inf"; } else { - pre = PyOS_double_to_string(v->cval.real, mode, 'g', precision, 0); + pre = PyOS_double_to_string(v->cval.real, format_code, + precision, 0); if (!pre) { PyErr_NoMemory(); goto done; @@ -405,8 +407,8 @@ im = "-inf*"; } else { - pim = PyOS_double_to_string(v->cval.imag, mode, 'g', precision, - Py_DTSF_SIGN); + pim = PyOS_double_to_string(v->cval.imag, format_code, + precision, Py_DTSF_SIGN); if (!pim) { PyErr_NoMemory(); goto done; @@ -436,13 +438,13 @@ static PyObject * complex_repr(PyComplexObject *v) { - return complex_format(v, 0, 0); + return complex_format(v, 'r', 0); } static PyObject * complex_str(PyComplexObject *v) { - return complex_format(v, 2, PREC_STR); + return complex_format(v, 'g', PREC_STR); } static long Modified: python/branches/py3k-short-float-repr/Objects/floatobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/floatobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/floatobject.c Thu Apr 2 16:06:34 2009 @@ -365,11 +365,12 @@ #define PREC_STR 12 static PyObject * -float_str_or_repr(PyFloatObject *v, int mode, int precision) +float_str_or_repr(PyFloatObject *v, char format_code, int precision) { PyObject *result; char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v), - mode, 'g', precision, Py_DTSF_ADD_DOT_0); + format_code, precision, + Py_DTSF_ADD_DOT_0); if (!buf) return PyErr_NoMemory(); result = PyUnicode_FromString(buf); @@ -380,13 +381,13 @@ static PyObject * float_repr(PyFloatObject *v) { - return float_str_or_repr(v, 0, 0); + return float_str_or_repr(v, 'r', 0); } static PyObject * float_str(PyFloatObject *v) { - return float_str_or_repr(v, 2, PREC_STR); + return float_str_or_repr(v, 'g', PREC_STR); } /* Comparison is pretty much a nightmare. When comparing float to float, @@ -1916,7 +1917,7 @@ if (PyFloat_CheckExact(p) && Py_REFCNT(p) != 0) { char *buf = PyOS_double_to_string( - PyFloat_AS_DOUBLE(p), 0, 'g', + PyFloat_AS_DOUBLE(p), 'g', 0, Py_DTSF_ADD_DOT_0); if (buf) { /* XXX(twouters) cast Modified: python/branches/py3k-short-float-repr/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/unicodeobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/unicodeobject.c Thu Apr 2 16:06:34 2009 @@ -8844,7 +8844,7 @@ goto done; } - p = PyOS_double_to_string(x, 2, type, prec, + p = PyOS_double_to_string(x, type, prec, (flags & F_ALT) ? Py_DTSF_ALT : 0); len = strlen(p); if (len+1 >= buflen) { Modified: python/branches/py3k-short-float-repr/Python/marshal.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/marshal.c (original) +++ python/branches/py3k-short-float-repr/Python/marshal.c Thu Apr 2 16:06:34 2009 @@ -237,7 +237,7 @@ } else { char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v), - 0, 'g', 0, Py_DTSF_ADD_DOT_0); + 'g', 0, Py_DTSF_ADD_DOT_0); if (!buf) return; n = strlen(buf); @@ -269,7 +269,7 @@ char *buf; w_byte(TYPE_COMPLEX, p); buf = PyOS_double_to_string(PyComplex_RealAsDouble(v), - 0, 'g', 0, Py_DTSF_ADD_DOT_0); + 'g', 0, Py_DTSF_ADD_DOT_0); if (!buf) return; n = strlen(buf); @@ -277,7 +277,7 @@ w_string(buf, (int)n, p); PyMem_Free(buf); buf = PyOS_double_to_string(PyComplex_ImagAsDouble(v), - 0, 'g', 0, Py_DTSF_ADD_DOT_0); + 'g', 0, Py_DTSF_ADD_DOT_0); if (!buf) return; n = strlen(buf); Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Thu Apr 2 16:06:34 2009 @@ -524,23 +524,30 @@ number of significant digits. */ static void -format_float_short(char *buf, size_t buflen, double d, char format_code, - int mode, int precision, int always_add_sign, - int add_dot_0_if_integer, int use_alt_formatting, - char **float_strings) +format_float_short(char *buf, Py_ssize_t buflen, double d, char format_code, + int mode, Py_ssize_t precision, + Py_ssize_t n_wanted_digits_after_decimal, + int always_add_sign, int add_dot_0_if_integer, + int use_alt_formatting, char **float_strings) { char *digits, *digits_end; int decpt, sign, exp_len; - Py_ssize_t digits_len, i; int use_exp = 0; int is_integer = 1; /* is the output produced so far just an integer? */ + int add_padding = 0; + Py_ssize_t n_digits_after_decimal = 0; + Py_ssize_t n_digits; + Py_ssize_t i; /* _Py_dg_dtoa returns a digit string (no decimal point or exponent) */ digits = _Py_dg_dtoa(d, mode, precision, &decpt, &sign, &digits_end); + if (!(digits_end != NULL && digits_end > digits)) { + printf("%f %p %p %d %c %d\n", d, digits_end, digits, mode, format_code, precision); + } assert(digits_end != NULL && digits_end > digits); - digits_len = digits_end - digits; + n_digits = digits_end - digits; if (!isdigit(digits[0])) { /* infinities and nans here; adapt Gay's output, @@ -565,7 +572,7 @@ something starting with a digit, an 'I', or an 'N' */ printf("Help! dtoa returned: %.*s\n", - (int)digits_len, digits); + (int)n_digits, digits); assert(0); } *buf = '\0'; @@ -612,62 +619,60 @@ *buf++ = digits[0]; *buf++ = '.'; is_integer = 0; - strncpy(buf, digits+1, digits_len-1); - buf += digits_len-1; + strncpy(buf, digits + 1, n_digits - 1); + buf += n_digits - 1; } else { /* use fixed-point notation */ if (decpt <= 0) { - /* output: 0.00...00dd...dd */ + /* output: 0.00-00dd-dd */ *buf++ = '0'; *buf++ = '.'; is_integer = 0; for (i = 0; i < -decpt; i++) *buf++ = '0'; - strncpy(buf, digits, digits_len); - buf += digits_len; + strncpy(buf, digits, n_digits); + buf += n_digits; + n_digits_after_decimal = n_digits - decpt; } - else if (decpt < digits_len) { - /* output: dd...dd.dd...dd */ + else if (decpt < n_digits) { + /* output: dd-dd.dd-dd */ strncpy(buf, digits, decpt); buf += decpt; *buf++ = '.'; is_integer = 0; - strncpy(buf, digits+decpt, digits_len-decpt); - buf += digits_len-decpt; + strncpy(buf, digits + decpt, n_digits - decpt); + buf += n_digits - decpt; + n_digits_after_decimal = n_digits - decpt; } else { - /* decpt >= digits_len. output: dd...dd00...00.0 */ - strncpy(buf, digits, digits_len); - buf += digits_len; - for (i = 0; i < decpt-digits_len; i++) + /* decpt >= n_digits. output: dd-dd00-00.0 */ + strncpy(buf, digits, n_digits); + buf += n_digits; + for (i = 0; i < decpt - n_digits; i++) *buf++ = '0'; *buf++ = '.'; is_integer = 0; + n_digits_after_decimal = decpt - n_digits; } } - /* Add trailing non-significant zeros for non-mode 0 and non-code g, unless doing alt formatting */ - int pad = 0; + /* Add trailing non-significant zeros for non-mode 0 and non-code g, + unless doing alt formatting */ if (mode != 0) { if (format_code == 'g') { if (use_alt_formatting) - pad = 1; + add_padding = 1; } else - pad = 1; + add_padding = 1; } - if (pad) { - Py_ssize_t nzeros = precision - digits_len; - - /* It should never be the case that nzeros is negative, but - check anyway. And while we're at it, skip 0 zeros. */ - if (nzeros > 0) { - for (i = 0; i < nzeros; i++) - *buf++ = '0'; - } - } + /* It should never be the case that n_trailing_zeros is negative, but + if so this loop executes zero times. */ + if (add_padding) + for (i = n_digits_after_decimal; i < n_wanted_digits_after_decimal; i++) + *buf++ = '0'; /* See if we want to have the trailing decimal or not */ if (format_code == 'g' && buf[-1] == '.') { @@ -694,7 +699,6 @@ PyAPI_FUNC(char *) PyOS_double_to_string(double val, - int mode, char format_code, int precision, int flags) @@ -702,12 +706,15 @@ char* buf = (char *)PyMem_Malloc(512); char lc_format_code = format_code; char** float_strings = lc_float_strings; + Py_ssize_t n_wanted_digits_after_decimal = precision; + int mode = 0; /* Validate format_code, and map upper and lower case */ switch (format_code) { case 'e': case 'f': case 'g': + case 'r': break; case 'E': lc_format_code = 'e'; @@ -726,11 +733,21 @@ if (format_code != lc_format_code) float_strings = uc_float_strings; - /* don't touch precision if we're in mode 0, it should stay 0. if - we're not using 'g', add one to the precision because we need to - include the digit before the decimal. */ - if (mode != 0 && lc_format_code != 'g') + switch (lc_format_code) { + case 'e': + mode = 2; precision += 1; + break; + case 'f': + mode = 3; + break; + case 'g': + mode = 2; + break; + case 'r': + mode = 0; + break; + } // printf("in PyOS_double_to_string %c %c\n", format_code, lc_format_code); if (!buf) @@ -738,7 +755,10 @@ /* XXX validate format_code */ - format_float_short(buf, 512, val, lc_format_code, mode, precision, flags & Py_DTSF_SIGN, flags & Py_DTSF_ADD_DOT_0, flags & Py_DTSF_ALT, float_strings); + format_float_short(buf, 512, val, lc_format_code, mode, precision, + n_wanted_digits_after_decimal, flags & Py_DTSF_SIGN, + flags & Py_DTSF_ADD_DOT_0, flags & Py_DTSF_ALT, + float_strings); return buf; } From python-checkins at python.org Thu Apr 2 16:09:50 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 2 Apr 2009 16:09:50 +0200 (CEST) Subject: [Python-checkins] r71048 - in python/branches/release26-maint: Lib/mailbox.py Lib/test/test_mailbox.py Misc/NEWS Message-ID: <20090402140950.E975C1E4024@bag.python.org> Author: r.david.murray Date: Thu Apr 2 16:09:49 2009 New Revision: 71048 Log: Merged revisions 71046 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71046 | r.david.murray | 2009-04-02 10:05:35 -0400 (Thu, 02 Apr 2009) | 4 lines Add missing iteritems() call to the for loop in mailbox.MH.get_message(). Fixes issue2625. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/mailbox.py python/branches/release26-maint/Lib/test/test_mailbox.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/mailbox.py ============================================================================== --- python/branches/release26-maint/Lib/mailbox.py (original) +++ python/branches/release26-maint/Lib/mailbox.py Thu Apr 2 16:09:49 2009 @@ -911,7 +911,7 @@ _unlock_file(f) finally: f.close() - for name, key_list in self.get_sequences(): + for name, key_list in self.get_sequences().iteritems(): if key in key_list: msg.add_sequence(name) return msg Modified: python/branches/release26-maint/Lib/test/test_mailbox.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_mailbox.py (original) +++ python/branches/release26-maint/Lib/test/test_mailbox.py Thu Apr 2 16:09:49 2009 @@ -936,6 +936,12 @@ self._box.remove(key1) self.assert_(self._box.get_sequences() == {'flagged':[key0]}) + def test_issue2625(self): + msg0 = mailbox.MHMessage(self._template % 0) + msg0.add_sequence('foo') + key0 = self._box.add(msg0) + refmsg0 = self._box.get_message(key0) + def test_pack(self): # Pack the contents of the mailbox msg0 = mailbox.MHMessage(self._template % 0) Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Thu Apr 2 16:09:49 2009 @@ -92,6 +92,35 @@ Library ------- +- Issue 2625: added missing iteritems() call to the for loop in + mailbox.MH.get_message(). + +- Issue 5585: Add the ability to call an initializer to mulitiprocessing.manager + so that users can install custonm handlers/etc. + +- Issue 3551: Patch multiprocessing to raise a proper exception if the size of the + object when writefile is called causes a ERROR_NO_SYSTEM_RESOURCES. Added docs + to note the limitation + +- unittest.assertNotEqual() now uses the inequality operator (!=) instead + of the equality operator. + +- Issue #5663: better failure messages for unittest asserts. Default assertTrue + and assertFalse messages are now useful. TestCase has a longMessage attribute. + This defaults to False, but if set to True useful error messages are shown in + addition to explicit messages passed to assert methods. + +- Issue #3110: Add additional protect around SEM_VALUE_MAX for multiprocessing + +- In Pdb, prevent the reassignment of __builtin__._ by sys.displayhook on + printing out values. + +- Issue #4572: added SEEK_* symbolic constants to io module. + +- Issue #1665206 (partially): Move imports in cgitb to the top of the module + instead of performing them in functions. Helps prevent import deadlocking in + threads. + - Issue #5647: MutableSet.__iand__() no longer mutates self during iteration. - Issue #5619: Multiprocessing children disobey the debug flag and causes From python-checkins at python.org Thu Apr 2 16:12:42 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 2 Apr 2009 16:12:42 +0200 (CEST) Subject: [Python-checkins] r71049 - python/branches/release26-maint/Misc/NEWS Message-ID: <20090402141242.882311E4024@bag.python.org> Author: r.david.murray Date: Thu Apr 2 16:12:42 2009 New Revision: 71049 Log: Fix borked NEWS merge. Modified: python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Thu Apr 2 16:12:42 2009 @@ -95,32 +95,6 @@ - Issue 2625: added missing iteritems() call to the for loop in mailbox.MH.get_message(). -- Issue 5585: Add the ability to call an initializer to mulitiprocessing.manager - so that users can install custonm handlers/etc. - -- Issue 3551: Patch multiprocessing to raise a proper exception if the size of the - object when writefile is called causes a ERROR_NO_SYSTEM_RESOURCES. Added docs - to note the limitation - -- unittest.assertNotEqual() now uses the inequality operator (!=) instead - of the equality operator. - -- Issue #5663: better failure messages for unittest asserts. Default assertTrue - and assertFalse messages are now useful. TestCase has a longMessage attribute. - This defaults to False, but if set to True useful error messages are shown in - addition to explicit messages passed to assert methods. - -- Issue #3110: Add additional protect around SEM_VALUE_MAX for multiprocessing - -- In Pdb, prevent the reassignment of __builtin__._ by sys.displayhook on - printing out values. - -- Issue #4572: added SEEK_* symbolic constants to io module. - -- Issue #1665206 (partially): Move imports in cgitb to the top of the module - instead of performing them in functions. Helps prevent import deadlocking in - threads. - - Issue #5647: MutableSet.__iand__() no longer mutates self during iteration. - Issue #5619: Multiprocessing children disobey the debug flag and causes From buildbot at python.org Thu Apr 2 16:59:43 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 02 Apr 2009 14:59:43 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu trunk Message-ID: <20090402145943.3D7A91E414F@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%20trunk/builds/1195 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_asyncore test_exceptions ====================================================================== FAIL: test_readwrite (test.test_asyncore.HelperFunctionTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/test_asyncore.py", line 144, in test_readwrite self.assertEqual(tobj.read, True) AssertionError: False != True ====================================================================== ERROR: test_badisinstance (test.test_exceptions.ExceptionTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/test_exceptions.py", line 390, in test_badisinstance self.assert_("maximum recursion depth exceeded" in str(v), v) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/contextlib.py", line 23, in __exit__ self.gen.next() File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/test_support.py", line 536, in captured_output setattr(sys, stream_name, orig_stdout) RuntimeError: maximum recursion depth exceeded make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Thu Apr 2 17:25:05 2009 From: python-checkins at python.org (sean.reifschneider) Date: Thu, 2 Apr 2009 17:25:05 +0200 (CEST) Subject: [Python-checkins] r71050 - tracker/instances/python-dev/scripts/close-pending Message-ID: <20090402152505.8AC411E4023@bag.python.org> Author: sean.reifschneider Date: Thu Apr 2 17:25:05 2009 New Revision: 71050 Log: Adding a script that will close pending issues within a date range. Added: tracker/instances/python-dev/scripts/close-pending (contents, props changed) Added: tracker/instances/python-dev/scripts/close-pending ============================================================================== --- (empty file) +++ tracker/instances/python-dev/scripts/close-pending Thu Apr 2 17:25:05 2009 @@ -0,0 +1,80 @@ +#!/usr/bin/python +# Make sure you are using the python that has the roundup runtime used by the +# tracker. Requires Python 2.3 or later. +# +# Based on roundup-summary script to create a tracker summary by +# Richard Jones and Paul Dubois +# +# Changed into close-pending script by Sean Reifschneider, 2009. + +import sys, math + +# kludge +sys.path.insert(1,'/home/roundup/roundup/lib/python2.4/site-packages') +# +import roundup +import roundup.date, roundup.instance +import optparse , datetime +import cStringIO, MimeWriter, smtplib +from roundup.mailer import SMTPConnection + +### CONFIGURATION +# Roundup date range, pending issues that don't have activity in this +# date range will be set to "closed" status. +expireDates = ';-2w' + +##### END CONFIGURATION + +usage = """%prog trackerHome + [--expire-dates 'date1;date2'] + # for maintainers + [--DEBUG] + dates is a roundup date range such as: + '-1w;' -- newer than a week + + Be sure to protect commas and semicolons from the shell with quotes! + Execute %prog --help for detailed help +""" +#### Options +parser = optparse.OptionParser(usage=usage) +parser.add_option('-e','--expire-dates', dest='expire_dates', + default=expireDates, metavar="'expire_dates;'", + help="""Specification for range of dates, such as: \ +';-1w' -- Older than 1 week; +';-1y' -- Older than 1 year""") + +#### Get the command line args: +(options, args) = parser.parse_args() + +if len(args) != 1: + parser.error("""Incorrect number of arguments; + you must supply a tracker home.""") +instanceHome = args[0] + +instance = roundup.instance.open(instanceHome) +db = instance.open('admin') + +pendingID = db.status.lookup('pending') +expireIdList = db.issue.filter(None, + { 'activity' : options.expire_dates, 'status' : pendingID }) + +messageBody = ( +'This issue is being automatically closed due to inactivity while it is in ' +'the pending state. If you are able to provide further information to help ' +'move this along, please update the ticket (which will re-open it).') + +closedID = db.status.lookup('closed') +for issueID in expireIdList: + #print 'Closing issue "%s" with activity "%s"' % ( issueID, + # db.issue.get(issueID, 'activity')) + + messages = db.issue.get(issueID, 'messages') + msgID = db.msg.create(author = db.getuid(), + summary = 'Automatically closing pending issue', + content = messageBody) + messages.append(msgID) + + db.issue.set(issueID, status = closedID, messages = messages) + +db.commit() +sys.exit(0) From python-checkins at python.org Thu Apr 2 17:27:20 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 2 Apr 2009 17:27:20 +0200 (CEST) Subject: [Python-checkins] r71051 - peps/trunk/pep-0382.txt Message-ID: <20090402152720.453BA1E4022@bag.python.org> Author: martin.v.loewis Date: Thu Apr 2 17:27:20 2009 New Revision: 71051 Log: Add Namespace packages PEP. Added: peps/trunk/pep-0382.txt (contents, props changed) Added: peps/trunk/pep-0382.txt ============================================================================== --- (empty file) +++ peps/trunk/pep-0382.txt Thu Apr 2 17:27:20 2009 @@ -0,0 +1,154 @@ +PEP: 382 +Title: Namespace Packages +Version: $Revision$ +Last-Modified: $Date$ +Author: Martin v. L?wis +Status: +Type: Standards Track +Content-Type: text/x-rst +Created: 02-Apr-2009 +Post-History: + +Abstract +======== + +Namespace packages are a mechanism for splitting a single Python package +across multiple directories on disk. In current Python versions, an algorithm +to compute the packages __path__ must be formulated. With the enhancement +proposed here, the import machinery itself will construct the list of +directories that make up the package. + +Terminology +=========== + +Within this PEP, the term package refers to Python packages as defined +by Python's import statement. The term distribution refers to separately +installable sets of Python modules as stored in the Python package index, +and installed by distutils or setuptools. The term vendor package refers +to groups of files installed by an operating system's packaging mechanism +(e.g. Debian or Redhat packages install on Linux systems). + +The term portion refers to a set of files in a single directory (possibly +stored in a zip file) that contribute to a namespace package. + +Namespace packages today +======================== + +Python currently provides the pkgutil.extend_path to denote a package as +a namespace package. The recommended way of using it is to put:: + + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) + +int the package's ``__init__.py``. Every distribution needs to provide +the same contents in its ``__init__.py``, so that extend_path is +invoked independent of which portion of the package gets imported +first. As a consequence, the package's ``__init__.py`` cannot +practically define any names as it depends on the order of the package +fragments on sys.path which portion is imported first. As a special +feature, extend_path reads files named ``*.pkg`` which allow to +declare additional portions. + +setuptools provides a similar function pkg_resources.declare_namespace +that is used in the form:: + + import pkg_resources + pkg_resources.declare_namespace(__name__) + +In the portion's __init__.py, no assignment to __path__ is necessary, +as declare_namespace modifies the package __path__ through sys.modules. +As a special feature, declare_namespace also supports zip files, and +registers the package name internally so that future additions to sys.path +by setuptools can properly add additional portions to each package. + +setuptools allows declaring namespace packages in a distribution's +setup.py, so that distribution developers don't need to put the +magic __path__ modification into __init__.py themselves. + +Rationale +========= + +The current imperative approach to namespace packages has lead to +multiple slightly-incompatible mechanisms for providing namespace +packages. For example, pkgutil supports ``*.pkg`` files; setuptools +doesn't. Likewise, setuptools supports inspecting zip files, and +supports adding portions to its _namespace_packages variable, whereas +pkgutil doesn't. + +In addition, the current approach causes problems for system vendors. +Vendor packages typically must not provide overlapping files, and an +attempt to install a vendor package that has a file already on disk +will fail or cause unpredictable behavior. As vendors might chose to +package distributions such that they will end up all in a single +directory for the namespace package, all portions would contribute +conflicting __init__.py files. + +Specification +============= + +Rather than using an imperative mechanism for importing packages, a +declarative approach is proposed here, as an extension to the existing +``*.pkg`` mechanism. + +The import statement is extended so that it directly considers ``*.pkg`` +files during import; a directory is considered a package if it either +contains a file named __init__.py, or a file whose name ends with +".pkg". + +In addition, the format of the ``*.pkg`` file is extended: a line with +the single character ``*`` indicates that the entire sys.path will +be searched for portions of the namespace package at the time the +namespace packages is imported. + +Importing a package will immediately compute the package's __path__; +the ``*.pkg`` files are not considered anymore after the initial import. +If a ``*.pkg`` package contains an asterisk, this asterisk is prepended +to the package's __path__ to indicate that the package is a namespace +package (and that thus further extensions to sys.path might also +want to extend __path__). At most one such asterisk gets prepended +to the path. + +extend_path will be extended to recognize namespace packages according +to this PEP, and avoid adding directories twice to __path__. + +No other change to the importing mechanism is made; searching +modules (including __init__.py) will continue to stop at the first +module encountered. + +Discussion +========== + +With the addition of ``*.pkg`` files to the import mechanism, namespace +packages can stop filling out the namespace package's __init__.py. +As a consequence, extend_path and declare_namespace become obsolete. + +It is recommended that distributions put a file .pkg +into their namespace packages, with a single asterisk. This allows +vendor packages to install multiple portions of namespace package +into a single directory, with no risk of overlapping files. + +Namespace packages can start providing non-trivial __init__.py +implementations; to do so, it is recommended that a single distribution +provides a portion with just the namespace package's __init__.py +(and potentially other modules that belong to the namespace package +proper). + +The mechanism is mostly compatible with the existing namespace +mechanisms. extend_path will be adjusted to this specification; +any other mechanism might cause portions to get added twice to +__path__. + +Copyright +========= + +This document has been placed in the public domain. + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + coding: utf-8 + End: From python-checkins at python.org Thu Apr 2 17:29:24 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 2 Apr 2009 17:29:24 +0200 (CEST) Subject: [Python-checkins] r71052 - peps/trunk/pep-0382.txt Message-ID: <20090402152924.D2D9E1E4022@bag.python.org> Author: martin.v.loewis Date: Thu Apr 2 17:29:24 2009 New Revision: 71052 Log: Target for Python 3.1. Modified: peps/trunk/pep-0382.txt Modified: peps/trunk/pep-0382.txt ============================================================================== --- peps/trunk/pep-0382.txt (original) +++ peps/trunk/pep-0382.txt Thu Apr 2 17:29:24 2009 @@ -7,6 +7,7 @@ Type: Standards Track Content-Type: text/x-rst Created: 02-Apr-2009 +Python-Version: 3.1 Post-History: Abstract From python-checkins at python.org Thu Apr 2 17:32:07 2009 From: python-checkins at python.org (brett.cannon) Date: Thu, 2 Apr 2009 17:32:07 +0200 (CEST) Subject: [Python-checkins] r71053 - python/branches/py3k/Lib/importlib/test/source/test_abc_loader.py Message-ID: <20090402153207.710BC1E42A7@bag.python.org> Author: brett.cannon Date: Thu Apr 2 17:32:07 2009 New Revision: 71053 Log: Give a more informative message on an importlib test upon failure. Modified: python/branches/py3k/Lib/importlib/test/source/test_abc_loader.py Modified: python/branches/py3k/Lib/importlib/test/source/test_abc_loader.py ============================================================================== --- python/branches/py3k/Lib/importlib/test/source/test_abc_loader.py (original) +++ python/branches/py3k/Lib/importlib/test/source/test_abc_loader.py Thu Apr 2 17:32:07 2009 @@ -123,7 +123,9 @@ def eq_attrs(self, ob, **kwargs): for attr, val in kwargs.items(): - self.assertEqual(getattr(ob, attr), val) + found = getattr(ob, attr) + self.assertEqual(found, val, + "{} attribute: {} != {}".format(attr, found, val)) def test_module(self): name = '' From python-checkins at python.org Thu Apr 2 17:35:09 2009 From: python-checkins at python.org (brett.cannon) Date: Thu, 2 Apr 2009 17:35:09 +0200 (CEST) Subject: [Python-checkins] r71054 - python/branches/py3k/Lib/importlib/test/source/test_abc_loader.py Message-ID: <20090402153509.B371F1E4022@bag.python.org> Author: brett.cannon Date: Thu Apr 2 17:35:09 2009 New Revision: 71054 Log: Make a test in importlib have a more robust test value. Modified: python/branches/py3k/Lib/importlib/test/source/test_abc_loader.py Modified: python/branches/py3k/Lib/importlib/test/source/test_abc_loader.py ============================================================================== --- python/branches/py3k/Lib/importlib/test/source/test_abc_loader.py (original) +++ python/branches/py3k/Lib/importlib/test/source/test_abc_loader.py Thu Apr 2 17:35:09 2009 @@ -141,7 +141,7 @@ def test_package(self): name = '' - path = '/path/to//__init__' + path = '/path/to/{}/__init__'.format(name) mock = self.mocker({name: path}) with util.uncache(name): module = mock.load_module(name) From python-checkins at python.org Thu Apr 2 17:35:39 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 2 Apr 2009 17:35:39 +0200 (CEST) Subject: [Python-checkins] r71055 - peps/trunk/pep-0382.txt Message-ID: <20090402153539.BBBA71E4024@bag.python.org> Author: martin.v.loewis Date: Thu Apr 2 17:35:39 2009 New Revision: 71055 Log: Mark PEP as active. Modified: peps/trunk/pep-0382.txt Modified: peps/trunk/pep-0382.txt ============================================================================== --- peps/trunk/pep-0382.txt (original) +++ peps/trunk/pep-0382.txt Thu Apr 2 17:35:39 2009 @@ -3,7 +3,7 @@ Version: $Revision$ Last-Modified: $Date$ Author: Martin v. L?wis -Status: +Status: Active Type: Standards Track Content-Type: text/x-rst Created: 02-Apr-2009 @@ -13,21 +13,23 @@ Abstract ======== -Namespace packages are a mechanism for splitting a single Python package -across multiple directories on disk. In current Python versions, an algorithm -to compute the packages __path__ must be formulated. With the enhancement -proposed here, the import machinery itself will construct the list of -directories that make up the package. +Namespace packages are a mechanism for splitting a single Python +package across multiple directories on disk. In current Python +versions, an algorithm to compute the packages __path__ must be +formulated. With the enhancement proposed here, the import machinery +itself will construct the list of directories that make up the +package. Terminology =========== Within this PEP, the term package refers to Python packages as defined -by Python's import statement. The term distribution refers to separately -installable sets of Python modules as stored in the Python package index, -and installed by distutils or setuptools. The term vendor package refers -to groups of files installed by an operating system's packaging mechanism -(e.g. Debian or Redhat packages install on Linux systems). +by Python's import statement. The term distribution refers to +separately installable sets of Python modules as stored in the Python +package index, and installed by distutils or setuptools. The term +vendor package refers to groups of files installed by an operating +system's packaging mechanism (e.g. Debian or Redhat packages install +on Linux systems). The term portion refers to a set of files in a single directory (possibly stored in a zip file) that contribute to a namespace package. From python-checkins at python.org Thu Apr 2 19:43:07 2009 From: python-checkins at python.org (georg.brandl) Date: Thu, 2 Apr 2009 19:43:07 +0200 (CEST) Subject: [Python-checkins] r71056 - python/trunk/Lib/pdb.py Message-ID: <20090402174307.D3D6E1E4063@bag.python.org> Author: georg.brandl Date: Thu Apr 2 19:43:07 2009 New Revision: 71056 Log: Actually the displayhook should print the repr. Modified: python/trunk/Lib/pdb.py Modified: python/trunk/Lib/pdb.py ============================================================================== --- python/trunk/Lib/pdb.py (original) +++ python/trunk/Lib/pdb.py Thu Apr 2 19:43:07 2009 @@ -206,7 +206,7 @@ """Custom displayhook for the exec in default(), which prevents assignment of the _ variable in the builtins. """ - print obj + print repr(obj) def default(self, line): if line[:1] == '!': line = line[1:] From python-checkins at python.org Thu Apr 2 19:54:43 2009 From: python-checkins at python.org (brett.cannon) Date: Thu, 2 Apr 2009 19:54:43 +0200 (CEST) Subject: [Python-checkins] r71057 - python/branches/py3k/Lib/importlib/test/source/test_abc_loader.py Message-ID: <20090402175443.AB8D81E4058@bag.python.org> Author: brett.cannon Date: Thu Apr 2 19:54:43 2009 New Revision: 71057 Log: importlib.test.source.test_abc_loader was making a bad assumption that all file paths used '/' as a path separator. Fixes issue #5646. Modified: python/branches/py3k/Lib/importlib/test/source/test_abc_loader.py Modified: python/branches/py3k/Lib/importlib/test/source/test_abc_loader.py ============================================================================== --- python/branches/py3k/Lib/importlib/test/source/test_abc_loader.py (original) +++ python/branches/py3k/Lib/importlib/test/source/test_abc_loader.py Thu Apr 2 19:54:43 2009 @@ -129,7 +129,7 @@ def test_module(self): name = '' - path = 'path/to/module' + path = os.path.join('', 'path', 'to', 'module') mock = self.mocker({name: path}) with util.uncache(name): module = mock.load_module(name) @@ -141,7 +141,7 @@ def test_package(self): name = '' - path = '/path/to/{}/__init__'.format(name) + path = os.path.join('path', 'to', name, '__init__') mock = self.mocker({name: path}) with util.uncache(name): module = mock.load_module(name) @@ -153,7 +153,7 @@ def test_lacking_parent(self): name = 'pkg.mod' - path = 'path/to/pkg/mod' + path = os.path.join('path', 'to', 'pkg', 'mod') mock = self.mocker({name: path}) with util.uncache(name): module = mock.load_module(name) @@ -165,7 +165,7 @@ def test_module_reuse(self): name = 'mod' - path = 'path/to/mod' + path = os.path.join('path', 'to', 'mod') module = imp.new_module(name) mock = self.mocker({name: path}) with util.uncache(name): @@ -179,7 +179,7 @@ name = "mod" module = imp.new_module(name) module.blah = None - mock = self.mocker({name: 'path/to/mod'}) + mock = self.mocker({name: os.path.join('path', 'to', 'mod')}) mock.source = b"1/0" with util.uncache(name): sys.modules[name] = module @@ -190,7 +190,7 @@ def test_unloadable(self): name = "mod" - mock = self.mocker({name: 'path/to/mod'}) + mock = self.mocker({name: os.path.join('path', 'to', 'mod')}) mock.source = b"1/0" with util.uncache(name): self.assertRaises(ZeroDivisionError, mock.load_module, name) @@ -224,7 +224,7 @@ def test_default_encoding(self): # Should have no problems with UTF-8 text. name = 'mod' - mock = PyLoaderMock({name: 'path/to/mod'}) + mock = PyLoaderMock({name: os.path.join('path', 'to', 'mod')}) source = 'x = "?"' mock.source = source.encode('utf-8') returned_source = mock.get_source(name) @@ -233,7 +233,7 @@ def test_decoded_source(self): # Decoding should work. name = 'mod' - mock = PyLoaderMock({name: 'path/to/mod'}) + mock = PyLoaderMock({name: os.path.join('path', 'to', 'mod')}) source = "# coding: Latin-1\nx='?'" assert source.encode('latin-1') != source.encode('utf-8') mock.source = source.encode('latin-1') @@ -289,7 +289,7 @@ @source_util.writes_bytecode def run_test(self, dont_write_bytecode): name = 'mod' - mock = PyPycLoaderMock({name: 'path/to/mod'}) + mock = PyPycLoaderMock({name: os.path.join('path', 'to', 'mod')}) sys.dont_write_bytecode = dont_write_bytecode with util.uncache(name): mock.load_module(name) @@ -313,8 +313,9 @@ name = 'mod' bad_magic = b'\x00\x00\x00\x00' assert bad_magic != imp.get_magic() - mock = PyPycLoaderMock({name: 'path/to/mod'}, - {name: {'path': 'path/to/mod.bytecode', + mock = PyPycLoaderMock({name: os.path.join('path', 'to', 'mod')}, + {name: {'path': os.path.join('path', 'to', + 'mod.bytecode'), 'magic': bad_magic}}) with util.uncache(name): mock.load_module(name) @@ -327,7 +328,7 @@ # Bytecode with an older mtime should be regenerated. name = 'mod' old_mtime = PyPycLoaderMock.default_mtime - 1 - mock = PyPycLoaderMock({name: 'path/to/mod'}, + mock = PyPycLoaderMock({name: os.path.join('path', 'to', 'mod')}, {name: {'path': 'path/to/mod.bytecode', 'mtime': old_mtime}}) with util.uncache(name): mock.load_module(name) @@ -345,7 +346,8 @@ # A bad magic number should lead to an ImportError. name = 'mod' bad_magic = b'\x00\x00\x00\x00' - mock = PyPycLoaderMock({}, {name: {'path': 'path/to/mod', + mock = PyPycLoaderMock({}, {name: {'path': os.path.join('path', 'to', + 'mod'), 'magic': bad_magic}}) with util.uncache(name): self.assertRaises(ImportError, mock.load_module, name) @@ -353,7 +355,9 @@ def test_bad_bytecode(self): # Bad code object bytecode should elad to an ImportError. name = 'mod' - mock = PyPycLoaderMock({}, {name: {'path': '/path/to/mod', 'bc': b''}}) + mock = PyPycLoaderMock({}, {name: {'path': os.path.join('path', 'to', + 'mod'), + 'bc': b''}}) with util.uncache(name): self.assertRaises(ImportError, mock.load_module, name) @@ -389,14 +393,15 @@ def test_source_path_ImportError(self): # An ImportError from source_path should trigger an ImportError. name = 'mod' - mock = PyPycLoaderMock({}, {name: {'path': 'path/to/mod'}}) + mock = PyPycLoaderMock({}, {name: {'path': os.path.join('path', 'to', + 'mod')}}) with util.uncache(name): self.assertRaises(ImportError, mock.load_module, name) def test_bytecode_path_ImportError(self): # An ImportError from bytecode_path should trigger an ImportError. name = 'mod' - mock = PyPycLoaderMock({name: 'path/to/mod'}) + mock = PyPycLoaderMock({name: os.path.join('path', 'to', 'mod')}) bad_meth = types.MethodType(raise_ImportError, mock) mock.bytecode_path = bad_meth with util.uncache(name): From python-checkins at python.org Thu Apr 2 20:09:05 2009 From: python-checkins at python.org (georg.brandl) Date: Thu, 2 Apr 2009 20:09:05 +0200 (CEST) Subject: [Python-checkins] r71058 - in python/trunk: Misc/NEWS Python/errors.c Message-ID: <20090402180905.3843B1E4058@bag.python.org> Author: georg.brandl Date: Thu Apr 2 20:09:04 2009 New Revision: 71058 Log: PyErr_NormalizeException may not set an error, so convert the PyErr_SetObject call on hitting the recursion limit into just assigning it to the arguments provided. Modified: python/trunk/Misc/NEWS python/trunk/Python/errors.c Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Apr 2 20:09:04 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Fix a problem in PyErr_NormalizeException that leads to "undetected errors" + when hitting the recursion limit under certain circumstances. + - Issue #1665206: Remove the last eager import in _warnings.c and make it lazy. - Issue #4865: On MacOSX /Library/Python/2.7/site-packages is added to Modified: python/trunk/Python/errors.c ============================================================================== --- python/trunk/Python/errors.c (original) +++ python/trunk/Python/errors.c Thu Apr 2 20:09:04 2009 @@ -225,7 +225,15 @@ tstate = PyThreadState_GET(); if (++tstate->recursion_depth > Py_GetRecursionLimit()) { --tstate->recursion_depth; - PyErr_SetObject(PyExc_RuntimeError, PyExc_RecursionErrorInst); + /* throw away the old exception... */ + Py_DECREF(*exc); + Py_DECREF(*val); + /* ... and use the recursion error instead */ + *exc = PyExc_RuntimeError; + *val = PyExc_RecursionErrorInst; + Py_INCREF(*exc); + Py_INCREF(*val); + /* just keeping the old traceback */ return; } PyErr_NormalizeException(exc, val, tb); From python-checkins at python.org Thu Apr 2 20:39:37 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 2 Apr 2009 20:39:37 +0200 (CEST) Subject: [Python-checkins] r71059 - in python/trunk: Lib/test/test_sys.py Objects/longobject.c Message-ID: <20090402183937.D775B1E4097@bag.python.org> Author: mark.dickinson Date: Thu Apr 2 20:39:37 2009 New Revision: 71059 Log: sys.long_info attributes should be ints, not longs Modified: python/trunk/Lib/test/test_sys.py python/trunk/Objects/longobject.c Modified: python/trunk/Lib/test/test_sys.py ============================================================================== --- python/trunk/Lib/test/test_sys.py (original) +++ python/trunk/Lib/test/test_sys.py Thu Apr 2 20:39:37 2009 @@ -340,6 +340,8 @@ self.assertEqual(len(sys.long_info), 2) self.assert_(sys.long_info.bits_per_digit % 5 == 0) self.assert_(sys.long_info.sizeof_digit >= 1) + self.assertEqual(type(sys.long_info.bits_per_digit), int) + self.assertEqual(type(sys.long_info.sizeof_digit), int) self.assert_(isinstance(sys.hexversion, int)) self.assert_(isinstance(sys.maxint, int)) if test.test_support.have_unicode: @@ -606,9 +608,9 @@ check(1L, size(vh) + self.longdigit) check(-1L, size(vh) + self.longdigit) PyLong_BASE = 2**sys.long_info.bits_per_digit - check(PyLong_BASE, size(vh) + 2*self.longdigit) - check(PyLong_BASE**2-1, size(vh) + 2*self.longdigit) - check(PyLong_BASE**2, size(vh) + 3*self.longdigit) + check(long(PyLong_BASE), size(vh) + 2*self.longdigit) + check(long(PyLong_BASE**2-1), size(vh) + 2*self.longdigit) + check(long(PyLong_BASE**2), size(vh) + 3*self.longdigit) # module check(unittest, size(h + 'P')) # None Modified: python/trunk/Objects/longobject.c ============================================================================== --- python/trunk/Objects/longobject.c (original) +++ python/trunk/Objects/longobject.c Thu Apr 2 20:39:37 2009 @@ -3736,8 +3736,10 @@ long_info = PyStructSequence_New(&Long_InfoType); if (long_info == NULL) return NULL; - PyStructSequence_SET_ITEM(long_info, field++, PyLong_FromLong(PyLong_SHIFT)); - PyStructSequence_SET_ITEM(long_info, field++, PyLong_FromLong(sizeof(digit))); + PyStructSequence_SET_ITEM(long_info, field++, + PyInt_FromLong(PyLong_SHIFT)); + PyStructSequence_SET_ITEM(long_info, field++, + PyInt_FromLong(sizeof(digit))); if (PyErr_Occurred()) { Py_CLEAR(long_info); return NULL; From python-checkins at python.org Thu Apr 2 20:40:36 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 2 Apr 2009 20:40:36 +0200 (CEST) Subject: [Python-checkins] r71060 - python/branches/release26-maint Message-ID: <20090402184036.8AF6A1E43E5@bag.python.org> Author: mark.dickinson Date: Thu Apr 2 20:40:36 2009 New Revision: 71060 Log: Blocked revisions 71059 via svnmerge ........ r71059 | mark.dickinson | 2009-04-02 19:39:37 +0100 (Thu, 02 Apr 2009) | 2 lines sys.long_info attributes should be ints, not longs ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Thu Apr 2 20:41:40 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 2 Apr 2009 20:41:40 +0200 (CEST) Subject: [Python-checkins] r71061 - python/branches/py3k/Objects/longobject.c Message-ID: <20090402184140.A42901E40E4@bag.python.org> Author: mark.dickinson Date: Thu Apr 2 20:41:40 2009 New Revision: 71061 Log: Rewrap some long lines. 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 Thu Apr 2 20:41:40 2009 @@ -4092,8 +4092,10 @@ int_info = PyStructSequence_New(&Int_InfoType); if (int_info == NULL) return NULL; - PyStructSequence_SET_ITEM(int_info, field++, PyLong_FromLong(PyLong_SHIFT)); - PyStructSequence_SET_ITEM(int_info, field++, PyLong_FromLong(sizeof(digit))); + PyStructSequence_SET_ITEM(int_info, field++, + PyLong_FromLong(PyLong_SHIFT)); + PyStructSequence_SET_ITEM(int_info, field++, + PyLong_FromLong(sizeof(digit))); if (PyErr_Occurred()) { Py_CLEAR(int_info); return NULL; From python-checkins at python.org Thu Apr 2 20:44:10 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 2 Apr 2009 20:44:10 +0200 (CEST) Subject: [Python-checkins] r71062 - python/branches/release30-maint Message-ID: <20090402184410.DB5861E40AE@bag.python.org> Author: mark.dickinson Date: Thu Apr 2 20:44:10 2009 New Revision: 71062 Log: Blocked revisions 71061 via svnmerge ........ r71061 | mark.dickinson | 2009-04-02 19:41:40 +0100 (Thu, 02 Apr 2009) | 2 lines Rewrap some long lines. ........ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Thu Apr 2 20:57:15 2009 From: python-checkins at python.org (brett.cannon) Date: Thu, 2 Apr 2009 20:57:15 +0200 (CEST) Subject: [Python-checkins] r71063 - python/branches/py3k Message-ID: <20090402185715.A93E91E4099@bag.python.org> Author: brett.cannon Date: Thu Apr 2 20:57:15 2009 New Revision: 71063 Log: r71034 somehow deleted all of the metadata for svnmerge. This is my attempt to fix my mistake. Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Thu Apr 2 21:02:06 2009 From: python-checkins at python.org (brett.cannon) Date: Thu, 2 Apr 2009 21:02:06 +0200 (CEST) Subject: [Python-checkins] r71064 - python/branches/py3k Message-ID: <20090402190206.D31781E4135@bag.python.org> Author: brett.cannon Date: Thu Apr 2 21:02:06 2009 New Revision: 71064 Log: A fix for the fix for the svnmerge metadata. Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Thu Apr 2 21:11:42 2009 From: python-checkins at python.org (eric.smith) Date: Thu, 2 Apr 2009 21:11:42 +0200 (CEST) Subject: [Python-checkins] r71065 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090402191142.A5BA51E41AC@bag.python.org> Author: eric.smith Date: Thu Apr 2 21:11:42 2009 New Revision: 71065 Log: A vast improvement. Most tests pass, except complex and several tests that deal with large precision. Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Thu Apr 2 21:11:42 2009 @@ -543,13 +543,10 @@ /* _Py_dg_dtoa returns a digit string (no decimal point or exponent) */ digits = _Py_dg_dtoa(d, mode, precision, &decpt, &sign, &digits_end); - if (!(digits_end != NULL && digits_end > digits)) { - printf("%f %p %p %d %c %d\n", d, digits_end, digits, mode, format_code, precision); - } - assert(digits_end != NULL && digits_end > digits); + assert(digits_end != NULL && digits_end >= digits); n_digits = digits_end - digits; - if (!isdigit(digits[0])) { + if (n_digits && !isdigit(digits[0])) { /* infinities and nans here; adapt Gay's output, so convert Infinity to inf and NaN to nan, and ignore sign of nan. */ @@ -614,16 +611,16 @@ } if (use_exp) { - /* exponential notation: d[.dddd]e(+|-)ee; - at least 2 digits in exponent */ + /* Exponential notation: d[.dddd]e(+|-)ee; at least 2 digits + in exponent */ + n_digits_after_decimal = n_digits - 1; *buf++ = digits[0]; *buf++ = '.'; is_integer = 0; - strncpy(buf, digits + 1, n_digits - 1); - buf += n_digits - 1; - + strncpy(buf, digits + 1, n_digits_after_decimal); + buf += n_digits_after_decimal; } else { - /* use fixed-point notation */ + /* Use fixed-point notation */ if (decpt <= 0) { /* output: 0.00-00dd-dd */ *buf++ = '0'; @@ -636,7 +633,7 @@ n_digits_after_decimal = n_digits - decpt; } else if (decpt < n_digits) { - /* output: dd-dd.dd-dd */ + /* Output: dd-dd.dd-dd */ strncpy(buf, digits, decpt); buf += decpt; *buf++ = '.'; @@ -646,7 +643,7 @@ n_digits_after_decimal = n_digits - decpt; } else { - /* decpt >= n_digits. output: dd-dd00-00.0 */ + /* decpt >= n_digits. Output: dd-dd00-00.0 */ strncpy(buf, digits, n_digits); buf += n_digits; for (i = 0; i < decpt - n_digits; i++) @@ -711,10 +708,10 @@ /* Validate format_code, and map upper and lower case */ switch (format_code) { - case 'e': - case 'f': - case 'g': - case 'r': + case 'e': /* exponent */ + case 'f': /* fixed */ + case 'g': /* general */ + case 'r': /* repr format */ break; case 'E': lc_format_code = 'e'; @@ -736,13 +733,15 @@ switch (lc_format_code) { case 'e': mode = 2; - precision += 1; + precision++; break; case 'f': mode = 3; break; case 'g': mode = 2; + if (flags & Py_DTSF_ALT) + n_wanted_digits_after_decimal--; break; case 'r': mode = 0; From buildbot at python.org Thu Apr 2 21:15:46 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 02 Apr 2009 19:15:46 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090402191546.D8B681E4733@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/457 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: brett.cannon BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_importlib test_urllib2net Traceback (most recent call last): File "./Lib/test/regrtest.py", line 620, in runtest_inner indirect_test() File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_importlib.py", line 6, in test_main run_unittest(importlib.test.test_suite('importlib.test')) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/__init__.py", line 22, in test_suite package_tests = getattr(sys.modules[package_name], 'test_suite')() File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/source/__init__.py", line 8, in test_suite return importlib.test.test_suite('importlib.test.source', directory) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/__init__.py", line 16, in test_suite __import__(module_name, level=0) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/source/test_case_sensitivity.py", line 12, in class CaseSensitivityTest(unittest.TestCase): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/util.py", line 13, in case_insensitive_tests original_name = os.path.listdir('.')[0] AttributeError: 'module' object has no attribute 'listdir' ====================================================================== ERROR: test_http_basic (test.test_urllib2net.TimeoutTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_urllib2net.py", line 198, in test_http_basic self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None) AttributeError: '_io.BufferedReader' object has no attribute 'fp' ====================================================================== ERROR: test_http_default_timeout (test.test_urllib2net.TimeoutTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_urllib2net.py", line 207, in test_http_default_timeout self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60) AttributeError: '_io.BufferedReader' object has no attribute 'fp' ====================================================================== ERROR: test_http_no_timeout (test.test_urllib2net.TimeoutTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_urllib2net.py", line 216, in test_http_no_timeout self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None) AttributeError: '_io.BufferedReader' object has no attribute 'fp' ====================================================================== ERROR: test_http_timeout (test.test_urllib2net.TimeoutTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_urllib2net.py", line 220, in test_http_timeout self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 120) AttributeError: '_io.BufferedReader' object has no attribute 'fp' sincerely, -The Buildbot From python-checkins at python.org Thu Apr 2 21:21:26 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 2 Apr 2009 21:21:26 +0200 (CEST) Subject: [Python-checkins] r71066 - python/branches/py3k Message-ID: <20090402192126.BCA361E44F2@bag.python.org> Author: r.david.murray Date: Thu Apr 2 21:21:26 2009 New Revision: 71066 Log: A fix for Brett's fix for his fix. I think we got it right this time. Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Thu Apr 2 21:44:44 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 2 Apr 2009 21:44:44 +0200 (CEST) Subject: [Python-checkins] r71067 - in python/branches/py3k: Lib/mailbox.py Lib/test/test_mailbox.py Misc/NEWS Message-ID: <20090402194444.402DE1E41AC@bag.python.org> Author: r.david.murray Date: Thu Apr 2 21:44:43 2009 New Revision: 71067 Log: In 3k this becomes an items() call. Merged revisions 71046 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71046 | r.david.murray | 2009-04-02 10:05:35 -0400 (Thu, 02 Apr 2009) | 4 lines Add missing iteritems() call to the for loop in mailbox.MH.get_message(). Fixes issue2625. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/mailbox.py python/branches/py3k/Lib/test/test_mailbox.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/mailbox.py ============================================================================== --- python/branches/py3k/Lib/mailbox.py (original) +++ python/branches/py3k/Lib/mailbox.py Thu Apr 2 21:44:43 2009 @@ -907,7 +907,7 @@ _unlock_file(f) finally: f.close() - for name, key_list in self.get_sequences(): + for name, key_list in self.get_sequences().items(): if key in key_list: msg.add_sequence(name) return msg Modified: python/branches/py3k/Lib/test/test_mailbox.py ============================================================================== --- python/branches/py3k/Lib/test/test_mailbox.py (original) +++ python/branches/py3k/Lib/test/test_mailbox.py Thu Apr 2 21:44:43 2009 @@ -931,6 +931,12 @@ self._box.remove(key1) self.assertEqual(self._box.get_sequences(), {'flagged':[key0]}) + def test_issue2625(self): + msg0 = mailbox.MHMessage(self._template % 0) + msg0.add_sequence('foo') + key0 = self._box.add(msg0) + refmsg0 = self._box.get_message(key0) + def test_pack(self): # Pack the contents of the mailbox msg0 = mailbox.MHMessage(self._template % 0) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Apr 2 21:44:43 2009 @@ -58,6 +58,9 @@ Library ------- +- Issue 2625: added missing items() call to the for loop in + mailbox.MH.get_message(). + - Issue #5640: Fix _multibytecodec so that CJK codecs don't repeat error substitutions from non-strict codec error callbacks in incrementalencoder and StreamWriter. From buildbot at python.org Thu Apr 2 21:58:06 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 02 Apr 2009 19:58:06 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 3.0 Message-ID: <20090402195806.B6F211E40A0@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%20gentoo%203.0/builds/220 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-amd64 Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_doctest make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Thu Apr 2 22:01:08 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 02 Apr 2009 20:01:08 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 2.6 Message-ID: <20090402200108.809BF1E4027@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%202.6/builds/217 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_asynchat make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Thu Apr 2 22:22:30 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 2 Apr 2009 22:22:30 +0200 (CEST) Subject: [Python-checkins] r71068 - in python/branches/release30-maint: Lib/mailbox.py Lib/test/test_mailbox.py Misc/NEWS Message-ID: <20090402202230.8F7CC1E402D@bag.python.org> Author: r.david.murray Date: Thu Apr 2 22:22:29 2009 New Revision: 71068 Log: Actually this was merged by hand because svnmerge messed up the properties on the merge of revision 71067 presumably as a result of my immediately previous fix for Brett's fix for his fix.... Merged revisions 71067 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71067 | r.david.murray | 2009-04-02 15:44:43 -0400 (Thu, 02 Apr 2009) | 13 lines In 3k this becomes an items() call. Merged revisions 71046 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71046 | r.david.murray | 2009-04-02 10:05:35 -0400 (Thu, 02 Apr 2009) | 4 lines Add missing iteritems() call to the for loop in mailbox.MH.get_message(). Fixes issue2625. ........ ................ Modified: python/branches/release30-maint/Lib/mailbox.py python/branches/release30-maint/Lib/test/test_mailbox.py python/branches/release30-maint/Misc/NEWS Modified: python/branches/release30-maint/Lib/mailbox.py ============================================================================== --- python/branches/release30-maint/Lib/mailbox.py (original) +++ python/branches/release30-maint/Lib/mailbox.py Thu Apr 2 22:22:29 2009 @@ -907,7 +907,7 @@ _unlock_file(f) finally: f.close() - for name, key_list in self.get_sequences(): + for name, key_list in self.get_sequences().items(): if key in key_list: msg.add_sequence(name) return msg Modified: python/branches/release30-maint/Lib/test/test_mailbox.py ============================================================================== --- python/branches/release30-maint/Lib/test/test_mailbox.py (original) +++ python/branches/release30-maint/Lib/test/test_mailbox.py Thu Apr 2 22:22:29 2009 @@ -931,6 +931,12 @@ self._box.remove(key1) self.assertEqual(self._box.get_sequences(), {'flagged':[key0]}) + def test_issue2625(self): + msg0 = mailbox.MHMessage(self._template % 0) + msg0.add_sequence('foo') + key0 = self._box.add(msg0) + refmsg0 = self._box.get_message(key0) + def test_pack(self): # Pack the contents of the mailbox msg0 = mailbox.MHMessage(self._template % 0) Modified: python/branches/release30-maint/Misc/NEWS ============================================================================== --- python/branches/release30-maint/Misc/NEWS (original) +++ python/branches/release30-maint/Misc/NEWS Thu Apr 2 22:22:29 2009 @@ -30,6 +30,9 @@ Library ------- +- Issue 2625: added missing items() call to the for loop in + mailbox.MH.get_message(). + - Issue #5619: Multiprocessing children disobey the debug flag and causes popups on windows buildbots. Patch applied to work around this issue. From python-checkins at python.org Thu Apr 2 22:26:12 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 2 Apr 2009 22:26:12 +0200 (CEST) Subject: [Python-checkins] r71069 - python/branches/release30-maint Message-ID: <20090402202612.BB0451E402D@bag.python.org> Author: r.david.murray Date: Thu Apr 2 22:26:12 2009 New Revision: 71069 Log: Mark 71067 as merged. Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Thu Apr 2 23:18:35 2009 From: python-checkins at python.org (antoine.pitrou) Date: Thu, 2 Apr 2009 23:18:35 +0200 (CEST) Subject: [Python-checkins] r71070 - in python/trunk: Doc/c-api/buffer.rst Doc/c-api/objbuffer.rst Doc/library/functions.rst Doc/library/stdtypes.rst Doc/tutorial/modules.rst Include/Python.h Include/memoryobject.h Include/object.h Lib/test/test_memoryview.py Makefile.pre.in Misc/NEWS Objects/abstract.c Objects/memoryobject.c Objects/typeobject.c Python/bltinmodule.c Message-ID: <20090402211835.5163A1E402D@bag.python.org> Author: antoine.pitrou Date: Thu Apr 2 23:18:34 2009 New Revision: 71070 Log: Issue #2396: backport the memoryview object. Added: python/trunk/Include/memoryobject.h (contents, props changed) python/trunk/Lib/test/test_memoryview.py (contents, props changed) python/trunk/Objects/memoryobject.c (contents, props changed) Modified: python/trunk/Doc/c-api/buffer.rst python/trunk/Doc/c-api/objbuffer.rst python/trunk/Doc/library/functions.rst python/trunk/Doc/library/stdtypes.rst python/trunk/Doc/tutorial/modules.rst python/trunk/Include/Python.h python/trunk/Include/object.h python/trunk/Makefile.pre.in python/trunk/Misc/NEWS python/trunk/Objects/abstract.c python/trunk/Objects/typeobject.c python/trunk/Python/bltinmodule.c Modified: python/trunk/Doc/c-api/buffer.rst ============================================================================== --- python/trunk/Doc/c-api/buffer.rst (original) +++ python/trunk/Doc/c-api/buffer.rst Thu Apr 2 23:18:34 2009 @@ -2,10 +2,11 @@ .. _bufferobjects: -Buffer Objects --------------- +Buffers and Memoryview Objects +------------------------------ .. sectionauthor:: Greg Stein +.. sectionauthor:: Benjamin Peterson .. index:: @@ -28,9 +29,296 @@ :cfunc:`PyArg_ParseTuple` that operate against an object's buffer interface, returning data from the target object. +Starting from version 1.6, Python has been providing Python-level buffer +objects and a C-level buffer API so that any builtin or used-defined type +can expose its characteristics. Both, however, have been deprecated because +of various shortcomings, and have been officially removed in Python 3.0 in +favour of a new C-level buffer API and a new Python-level object named +:class:`memoryview`. + +The new buffer API has been backported to Python 2.6, and the +:class:`memoryview` object has been backported to Python 2.7. It is strongly +advised to use them rather than the old APIs, unless you are blocked from +doing so for compatibility reasons. + + +The new-style Py_buffer struct +============================== + + +.. ctype:: Py_buffer + + .. cmember:: void *buf + + A pointer to the start of the memory for the object. + + .. cmember:: Py_ssize_t len + :noindex: + + The total length of the memory in bytes. + + .. cmember:: int readonly + + An indicator of whether the buffer is read only. + + .. cmember:: const char *format + :noindex: + + A *NULL* terminated string in :mod:`struct` module style syntax giving the + contents of the elements available through the buffer. If this is *NULL*, + ``"B"`` (unsigned bytes) is assumed. + + .. cmember:: int ndim + + The number of dimensions the memory represents as a multi-dimensional + array. If it is 0, :cdata:`strides` and :cdata:`suboffsets` must be + *NULL*. + + .. cmember:: Py_ssize_t *shape + + An array of :ctype:`Py_ssize_t`\s the length of :cdata:`ndim` giving the + shape of the memory as a multi-dimensional array. Note that + ``((*shape)[0] * ... * (*shape)[ndims-1])*itemsize`` should be equal to + :cdata:`len`. + + .. cmember:: Py_ssize_t *strides + + An array of :ctype:`Py_ssize_t`\s the length of :cdata:`ndim` giving the + number of bytes to skip to get to a new element in each dimension. + + .. cmember:: Py_ssize_t *suboffsets + + An array of :ctype:`Py_ssize_t`\s the length of :cdata:`ndim`. If these + suboffset numbers are greater than or equal to 0, then the value stored + along the indicated dimension is a pointer and the suboffset value + dictates how many bytes to add to the pointer after de-referencing. A + suboffset value that it negative indicates that no de-referencing should + occur (striding in a contiguous memory block). + + Here is a function that returns a pointer to the element in an N-D array + pointed to by an N-dimesional index when there are both non-NULL strides + and suboffsets:: + + void *get_item_pointer(int ndim, void *buf, Py_ssize_t *strides, + Py_ssize_t *suboffsets, Py_ssize_t *indices) { + char *pointer = (char*)buf; + int i; + for (i = 0; i < ndim; i++) { + pointer += strides[i] * indices[i]; + if (suboffsets[i] >=0 ) { + pointer = *((char**)pointer) + suboffsets[i]; + } + } + return (void*)pointer; + } + + + .. cmember:: Py_ssize_t itemsize + + This is a storage for the itemsize (in bytes) of each element of the + shared memory. It is technically un-necessary as it can be obtained using + :cfunc:`PyBuffer_SizeFromFormat`, however an exporter may know this + information without parsing the format string and it is necessary to know + the itemsize for proper interpretation of striding. Therefore, storing it + is more convenient and faster. + + .. cmember:: void *internal + + This is for use internally by the exporting object. For example, this + might be re-cast as an integer by the exporter and used to store flags + about whether or not the shape, strides, and suboffsets arrays must be + freed when the buffer is released. The consumer should never alter this + value. + + +Buffer related functions +======================== + + +.. cfunction:: int PyObject_CheckBuffer(PyObject *obj) + + Return 1 if *obj* supports the buffer interface otherwise 0. + + +.. cfunction:: int PyObject_GetBuffer(PyObject *obj, PyObject *view, int flags) + + Export *obj* into a :ctype:`Py_buffer`, *view*. These arguments must + never be *NULL*. The *flags* argument is a bit field indicating what kind + of buffer the caller is prepared to deal with and therefore what kind of + buffer the exporter is allowed to return. The buffer interface allows for + complicated memory sharing possibilities, but some caller may not be able + to handle all the complexibity but may want to see if the exporter will + let them take a simpler view to its memory. + + Some exporters may not be able to share memory in every possible way and + may need to raise errors to signal to some consumers that something is + just not possible. These errors should be a :exc:`BufferError` unless + there is another error that is actually causing the problem. The exporter + can use flags information to simplify how much of the :cdata:`Py_buffer` + structure is filled in with non-default values and/or raise an error if + the object can't support a simpler view of its memory. + + 0 is returned on success and -1 on error. + + The following table gives possible values to the *flags* arguments. + + +------------------------------+---------------------------------------------------+ + | Flag | Description | + +==============================+===================================================+ + | :cmacro:`PyBUF_SIMPLE` | This is the default flag state. The returned | + | | buffer may or may not have writable memory. The | + | | format of the data will be assumed to be unsigned | + | | bytes. This is a "stand-alone" flag constant. It | + | | never needs to be '|'d to the others. The exporter| + | | will raise an error if it cannot provide such a | + | | contiguous buffer of bytes. | + | | | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_WRITABLE` | The returned buffer must be writable. If it is | + | | not writable, then raise an error. | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_STRIDES` | This implies :cmacro:`PyBUF_ND`. The returned | + | | buffer must provide strides information (i.e. the | + | | strides cannot be NULL). This would be used when | + | | the consumer can handle strided, discontiguous | + | | arrays. Handling strides automatically assumes | + | | you can handle shape. The exporter can raise an | + | | error if a strided representation of the data is | + | | not possible (i.e. without the suboffsets). | + | | | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_ND` | The returned buffer must provide shape | + | | information. The memory will be assumed C-style | + | | contiguous (last dimension varies the | + | | fastest). The exporter may raise an error if it | + | | cannot provide this kind of contiguous buffer. If | + | | this is not given then shape will be *NULL*. | + | | | + | | | + | | | + +------------------------------+---------------------------------------------------+ + |:cmacro:`PyBUF_C_CONTIGUOUS` | These flags indicate that the contiguity returned | + |:cmacro:`PyBUF_F_CONTIGUOUS` | buffer must be respectively, C-contiguous (last | + |:cmacro:`PyBUF_ANY_CONTIGUOUS`| dimension varies the fastest), Fortran contiguous | + | | (first dimension varies the fastest) or either | + | | one. All of these flags imply | + | | :cmacro:`PyBUF_STRIDES` and guarantee that the | + | | strides buffer info structure will be filled in | + | | correctly. | + | | | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_INDIRECT` | This flag indicates the returned buffer must have | + | | suboffsets information (which can be NULL if no | + | | suboffsets are needed). This can be used when | + | | the consumer can handle indirect array | + | | referencing implied by these suboffsets. This | + | | implies :cmacro:`PyBUF_STRIDES`. | + | | | + | | | + | | | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_FORMAT` | The returned buffer must have true format | + | | information if this flag is provided. This would | + | | be used when the consumer is going to be checking | + | | for what 'kind' of data is actually stored. An | + | | exporter should always be able to provide this | + | | information if requested. If format is not | + | | explicitly requested then the format must be | + | | returned as *NULL* (which means ``'B'``, or | + | | unsigned bytes) | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_STRIDED` | This is equivalent to ``(PyBUF_STRIDES | | + | | PyBUF_WRITABLE)``. | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_STRIDED_RO` | This is equivalent to ``(PyBUF_STRIDES)``. | + | | | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_RECORDS` | This is equivalent to ``(PyBUF_STRIDES | | + | | PyBUF_FORMAT | PyBUF_WRITABLE)``. | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_RECORDS_RO` | This is equivalent to ``(PyBUF_STRIDES | | + | | PyBUF_FORMAT)``. | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_FULL` | This is equivalent to ``(PyBUF_INDIRECT | | + | | PyBUF_FORMAT | PyBUF_WRITABLE)``. | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_FULL_RO`` | This is equivalent to ``(PyBUF_INDIRECT | | + | | PyBUF_FORMAT)``. | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_CONTIG` | This is equivalent to ``(PyBUF_ND | | + | | PyBUF_WRITABLE)``. | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_CONTIG_RO` | This is equivalent to ``(PyBUF_ND)``. | + | | | + +------------------------------+---------------------------------------------------+ + + +.. cfunction:: void PyBuffer_Release(PyObject *obj, Py_buffer *view) + + Release the buffer *view* over *obj*. This shouldd be called when the buffer + is no longer being used as it may free memory from it. + + +.. cfunction:: Py_ssize_t PyBuffer_SizeFromFormat(const char *) + + Return the implied :cdata:`~Py_buffer.itemsize` from the struct-stype + :cdata:`~Py_buffer.format`. + + +.. cfunction:: int PyObject_CopyToObject(PyObject *obj, void *buf, Py_ssize_t len, char fortran) + + Copy *len* bytes of data pointed to by the contiguous chunk of memory pointed + to by *buf* into the buffer exported by obj. The buffer must of course be + writable. Return 0 on success and return -1 and raise an error on failure. + If the object does not have a writable buffer, then an error is raised. If + *fortran* is ``'F'``, then if the object is multi-dimensional, then the data + will be copied into the array in Fortran-style (first dimension varies the + fastest). If *fortran* is ``'C'``, then the data will be copied into the + array in C-style (last dimension varies the fastest). If *fortran* is + ``'A'``, then it does not matter and the copy will be made in whatever way is + more efficient. + + +.. cfunction:: int PyBuffer_IsContiguous(Py_buffer *view, char fortran) + + Return 1 if the memory defined by the *view* is C-style (*fortran* is + ``'C'``) or Fortran-style (*fortran* is ``'F'``) contiguous or either one + (*fortran* is ``'A'``). Return 0 otherwise. + + +.. cfunction:: void PyBuffer_FillContiguousStrides(int ndim, Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t itemsize, char fortran) + + Fill the *strides* array with byte-strides of a contiguous (C-style if + *fortran* is ``'C'`` or Fortran-style if *fortran* is ``'F'`` array of the + given shape with the given number of bytes per element. + + +.. cfunction:: int PyBuffer_FillInfo(Py_buffer *view, void *buf, Py_ssize_t len, int readonly, int infoflags) + + Fill in a buffer-info structure, *view*, correctly for an exporter that can + only share a contiguous chunk of memory of "unsigned bytes" of the given + length. Return 0 on success and -1 (with raising an error) on error. + + +MemoryView objects +================== + +A memoryview object is an extended buffer object that could replace the buffer +object (but doesn't have to as that could be kept as a simple 1-d memoryview +object). It, unlike :ctype:`Py_buffer`, is a Python object (exposed as +:class:`memoryview` in :mod:`builtins`), so it can be used with Python code. + +.. cfunction:: PyObject* PyMemoryView_FromObject(PyObject *obj) + + Return a memoryview object from an object that defines the buffer interface. + + +Old-style buffer objects +======================== + .. index:: single: PyBufferProcs -More information on the buffer interface is provided in the section +More information on the old buffer interface is provided in the section :ref:`buffer-structs`, under the description for :ctype:`PyBufferProcs`. A "buffer object" is defined in the :file:`bufferobject.h` header (included by Modified: python/trunk/Doc/c-api/objbuffer.rst ============================================================================== --- python/trunk/Doc/c-api/objbuffer.rst (original) +++ python/trunk/Doc/c-api/objbuffer.rst Thu Apr 2 23:18:34 2009 @@ -2,8 +2,15 @@ .. _abstract-buffer: -Buffer Protocol -=============== + +Old Buffer Protocol +=================== + +This section describes the legacy buffer protocol, which has been introduced +in Python 1.6. It is still supported but deprecated in the Python 2.x series. +Python 3.0 introduces a new buffer protocol which fixes weaknesses and +shortcomings of the protocol, and has been backported to Python 2.6. +See :ref:`bufferobjects` for more information. .. cfunction:: int PyObject_AsCharBuffer(PyObject *obj, const char **buffer, Py_ssize_t *buffer_len) Modified: python/trunk/Doc/library/functions.rst ============================================================================== --- python/trunk/Doc/library/functions.rst (original) +++ python/trunk/Doc/library/functions.rst Thu Apr 2 23:18:34 2009 @@ -680,6 +680,13 @@ Added support for the optional *key* argument. +.. function:: memoryview(obj) + :noindex: + + Return a "memory view" object created from the given argument. See + :ref:`typememoryview` for more information. + + .. function:: min(iterable[, args...][key]) With a single argument *iterable*, return the smallest item of a non-empty Modified: python/trunk/Doc/library/stdtypes.rst ============================================================================== --- python/trunk/Doc/library/stdtypes.rst (original) +++ python/trunk/Doc/library/stdtypes.rst Thu Apr 2 23:18:34 2009 @@ -2354,6 +2354,104 @@ state. +.. _typememoryview: + +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(obj) + + Create a :class:`memoryview` that references *obj*. *obj* must support the + buffer protocol. Builtin objects that support the buffer protocol include + :class:`str` and :class:`bytearray` (but not :class:`unicode`). + + ``len(view)`` returns the total number of bytes in the memoryview, *view*. + + A :class:`memoryview` supports slicing to expose its data. Taking a single + index will return a single byte. Full slicing will result in a subview:: + + >>> v = memoryview('abcefg') + >>> v[1] + 'b' + >>> v[-1] + 'g' + >>> v[1:4] + + >>> str(v[1:4]) + 'bce' + >>> v[3:-1] + + >>> str(v[4:-1]) + 'f' + + If the object the memory view is over supports changing its data, the + memoryview supports slice assignment:: + + >>> data = bytearray('abcefg') + >>> v = memoryview(data) + >>> v.readonly + False + >>> v[0] = 'z' + >>> data + bytearray(b'zbcefg') + >>> v[1:4] = '123' + >>> data + bytearray(b'z123fg') + >>> v[2] = 'spam' + Traceback (most recent call last): + File "", line 1, in + ValueError: cannot modify size of memoryview object + + Notice how the size of the memoryview object can not be changed. + + + :class:`memoryview` has two methods: + + .. method:: tobytes() + + Return the data in the buffer as a bytestring (an object of class + :class:`str`). + + .. method:: tolist() + + Return the data in the buffer as a list of integers. :: + + >>> memoryview(b'abc').tolist() + [97, 98, 99] + + There are also several readonly attributes available: + + .. attribute:: format + + A string containing the format (in :mod:`struct` module style) for each + element in the view. This defaults to ``'B'``, a simple bytestring. + + .. attribute:: itemsize + + The size in bytes of each element of the memoryview. + + .. attribute:: shape + + A tuple of integers the length of :attr:`ndim` giving the shape of the + memory as a N-dimensional array. + + .. attribute:: ndim + + An integer indicating how many dimensions of a multi-dimensional array the + memory represents. + + .. attribute:: strides + + A tuple of integers the length of :attr:`ndim` giving the size in bytes to + access each element for each dimension of the array. + + .. memoryview.suboffsets isn't documented because it only seems useful for C + + .. _typecontextmanager: Context Manager Types Modified: python/trunk/Doc/tutorial/modules.rst ============================================================================== --- python/trunk/Doc/tutorial/modules.rst (original) +++ python/trunk/Doc/tutorial/modules.rst Thu Apr 2 23:18:34 2009 @@ -328,8 +328,8 @@ 'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter', - 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'min', - 'object', 'oct', 'open', 'ord', 'pow', 'property', 'quit', 'range', + 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'memoryview', + 'min', 'object', 'oct', 'open', 'ord', 'pow', 'property', 'quit', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip'] Modified: python/trunk/Include/Python.h ============================================================================== --- python/trunk/Include/Python.h (original) +++ python/trunk/Include/Python.h Thu Apr 2 23:18:34 2009 @@ -92,7 +92,7 @@ #endif #include "rangeobject.h" #include "stringobject.h" -/* #include "memoryobject.h" */ +#include "memoryobject.h" #include "bufferobject.h" #include "bytesobject.h" #include "bytearrayobject.h" Added: python/trunk/Include/memoryobject.h ============================================================================== --- (empty file) +++ python/trunk/Include/memoryobject.h Thu Apr 2 23:18:34 2009 @@ -0,0 +1,74 @@ +/* Memory view object. In Python this is available as "memoryview". */ + +#ifndef Py_MEMORYOBJECT_H +#define Py_MEMORYOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PyMemoryView_Type; + +#define PyMemoryView_Check(op) (Py_TYPE(op) == &PyMemoryView_Type) + +/* 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) + + +PyAPI_FUNC(PyObject *) PyMemoryView_GetContiguous(PyObject *base, + int buffertype, + char fort); + + /* Return a contiguous chunk of memory representing the buffer + from an object in a memory view object. If a copy is made then the + base object for the memory view will be a *new* bytes object. + + Otherwise, the base-object will be the object itself and no + data-copying will be done. + + The buffertype argument can be PyBUF_READ, PyBUF_WRITE, + PyBUF_SHADOW to determine whether the returned buffer + should be READONLY, WRITABLE, or set to update the + original buffer if a copy must be made. If buffertype is + PyBUF_WRITE and the buffer is not contiguous an error will + be raised. In this circumstance, the user can use + PyBUF_SHADOW to ensure that a a writable temporary + contiguous buffer is returned. The contents of this + contiguous buffer will be copied back into the original + object after the memoryview object is deleted as long as + the original object is writable and allows setting an + exclusive write lock. If this is not allowed by the + original object, then a BufferError is raised. + + If the object is multi-dimensional and if fortran is 'F', + the first dimension of the underlying array will vary the + fastest in the buffer. If fortran is 'C', then the last + dimension will vary the fastest (C-style contiguous). If + fortran is 'A', then it does not matter and you will get + whatever the object decides is more efficient. + + A new reference is returned that must be DECREF'd when finished. + */ + +PyAPI_FUNC(PyObject *) PyMemoryView_FromObject(PyObject *base); + +PyAPI_FUNC(PyObject *) PyMemoryView_FromBuffer(Py_buffer *info); + /* create new if bufptr is NULL + will be a new bytesobject in base */ + + +/* 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! */ +typedef struct { + PyObject_HEAD + PyObject *base; + Py_buffer view; +} PyMemoryViewObject; + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_MEMORYOBJECT_H */ Modified: python/trunk/Include/object.h ============================================================================== --- python/trunk/Include/object.h (original) +++ python/trunk/Include/object.h Thu Apr 2 23:18:34 2009 @@ -159,21 +159,23 @@ typedef Py_ssize_t (*segcountproc)(PyObject *, Py_ssize_t *); typedef Py_ssize_t (*charbufferproc)(PyObject *, Py_ssize_t, char **); -/* Py3k buffer interface */ +/* Py3k buffer interface */ typedef struct bufferinfo { - void *buf; - PyObject *obj; /* borrowed reference */ - Py_ssize_t len; - Py_ssize_t itemsize; /* This is Py_ssize_t so it can be - pointed to by strides in simple case.*/ - int readonly; - int ndim; - char *format; - Py_ssize_t *shape; - Py_ssize_t *strides; - Py_ssize_t *suboffsets; - void *internal; + void *buf; + PyObject *obj; /* owned reference */ + Py_ssize_t len; + Py_ssize_t itemsize; /* This is Py_ssize_t so it can be + pointed to by strides in simple case.*/ + int readonly; + int ndim; + char *format; + Py_ssize_t *shape; + Py_ssize_t *strides; + Py_ssize_t *suboffsets; + Py_ssize_t smalltable[2]; /* static store for shape and strides of + mono-dimensional buffers. */ + void *internal; } Py_buffer; typedef int (*getbufferproc)(PyObject *, Py_buffer *, int); Added: python/trunk/Lib/test/test_memoryview.py ============================================================================== --- (empty file) +++ python/trunk/Lib/test/test_memoryview.py Thu Apr 2 23:18:34 2009 @@ -0,0 +1,328 @@ +"""Unit tests for the memoryview + +XXX We need more tests! Some tests are in test_bytes +""" + +import unittest +import sys +import gc +import weakref +import array +from test import test_support + + +class AbstractMemoryTests: + source_bytes = b"abcdef" + + @property + def _source(self): + return self.source_bytes + + @property + def _types(self): + return filter(None, [self.ro_type, self.rw_type]) + + def check_getitem_with_type(self, tp): + item = self.getitem_type + b = tp(self._source) + oldrefcount = sys.getrefcount(b) + m = self._view(b) + self.assertEquals(m[0], item(b"a")) + self.assert_(isinstance(m[0], bytes), type(m[0])) + self.assertEquals(m[5], item(b"f")) + self.assertEquals(m[-1], item(b"f")) + self.assertEquals(m[-6], item(b"a")) + # Bounds checking + self.assertRaises(IndexError, lambda: m[6]) + self.assertRaises(IndexError, lambda: m[-7]) + self.assertRaises(IndexError, lambda: m[sys.maxsize]) + self.assertRaises(IndexError, lambda: m[-sys.maxsize]) + # Type checking + self.assertRaises(TypeError, lambda: m[None]) + self.assertRaises(TypeError, lambda: m[0.0]) + self.assertRaises(TypeError, lambda: m["a"]) + m = None + self.assertEquals(sys.getrefcount(b), oldrefcount) + + def test_getitem(self): + for tp in self._types: + self.check_getitem_with_type(tp) + + def test_setitem_readonly(self): + if not self.ro_type: + return + b = self.ro_type(self._source) + oldrefcount = sys.getrefcount(b) + m = self._view(b) + def setitem(value): + m[0] = value + self.assertRaises(TypeError, setitem, b"a") + self.assertRaises(TypeError, setitem, 65) + self.assertRaises(TypeError, setitem, memoryview(b"a")) + m = None + self.assertEquals(sys.getrefcount(b), oldrefcount) + + def test_setitem_writable(self): + if not self.rw_type: + return + tp = self.rw_type + b = self.rw_type(self._source) + oldrefcount = sys.getrefcount(b) + m = self._view(b) + m[0] = tp(b"0") + self._check_contents(tp, b, b"0bcdef") + m[1:3] = tp(b"12") + self._check_contents(tp, b, b"012def") + m[1:1] = tp(b"") + self._check_contents(tp, b, b"012def") + m[:] = tp(b"abcdef") + self._check_contents(tp, b, b"abcdef") + + # Overlapping copies of a view into itself + m[0:3] = m[2:5] + self._check_contents(tp, b, b"cdedef") + m[:] = tp(b"abcdef") + m[2:5] = m[0:3] + self._check_contents(tp, b, b"ababcf") + + def setitem(key, value): + m[key] = tp(value) + # Bounds checking + self.assertRaises(IndexError, setitem, 6, b"a") + self.assertRaises(IndexError, setitem, -7, b"a") + self.assertRaises(IndexError, setitem, sys.maxsize, b"a") + self.assertRaises(IndexError, setitem, -sys.maxsize, b"a") + # Wrong index/slice types + self.assertRaises(TypeError, setitem, 0.0, b"a") + self.assertRaises(TypeError, setitem, (0,), b"a") + self.assertRaises(TypeError, setitem, "a", b"a") + # Trying to resize the memory object + self.assertRaises(ValueError, setitem, 0, b"") + self.assertRaises(ValueError, setitem, 0, b"ab") + self.assertRaises(ValueError, setitem, slice(1,1), b"a") + self.assertRaises(ValueError, setitem, slice(0,2), b"a") + + m = None + self.assertEquals(sys.getrefcount(b), oldrefcount) + + def test_tobytes(self): + for tp in self._types: + m = self._view(tp(self._source)) + b = m.tobytes() + # This calls self.getitem_type() on each separate byte of b"abcdef" + expected = b"".join( + self.getitem_type(c) for c in b"abcdef") + self.assertEquals(b, expected) + self.assert_(isinstance(b, bytes), type(b)) + + def test_tolist(self): + for tp in self._types: + m = self._view(tp(self._source)) + l = m.tolist() + self.assertEquals(l, map(ord, b"abcdef")) + + def test_compare(self): + # memoryviews can compare for equality with other objects + # having the buffer interface. + for tp in self._types: + m = self._view(tp(self._source)) + for tp_comp in self._types: + self.assertTrue(m == tp_comp(b"abcdef")) + self.assertFalse(m != tp_comp(b"abcdef")) + self.assertFalse(m == tp_comp(b"abcde")) + self.assertTrue(m != tp_comp(b"abcde")) + self.assertFalse(m == tp_comp(b"abcde1")) + self.assertTrue(m != tp_comp(b"abcde1")) + self.assertTrue(m == m) + self.assertTrue(m == m[:]) + self.assertTrue(m[0:6] == m[:]) + self.assertFalse(m[0:5] == m) + + # Comparison with objects which don't support the buffer API + self.assertFalse(m == u"abcdef") + self.assertTrue(m != u"abcdef") + self.assertFalse(u"abcdef" == m) + self.assertTrue(u"abcdef" != m) + + # Unordered comparisons are unimplemented, and therefore give + # arbitrary results (they raise a TypeError in py3k) + + def check_attributes_with_type(self, tp): + m = self._view(tp(self._source)) + self.assertEquals(m.format, self.format) + self.assertEquals(m.itemsize, self.itemsize) + self.assertEquals(m.ndim, 1) + self.assertEquals(m.shape, (6,)) + self.assertEquals(len(m), 6) + self.assertEquals(m.strides, (self.itemsize,)) + self.assertEquals(m.suboffsets, None) + return m + + def test_attributes_readonly(self): + if not self.ro_type: + return + m = self.check_attributes_with_type(self.ro_type) + self.assertEquals(m.readonly, True) + + def test_attributes_writable(self): + if not self.rw_type: + return + m = self.check_attributes_with_type(self.rw_type) + self.assertEquals(m.readonly, False) + + # Disabled: unicode uses the old buffer API in 2.x + + #def test_getbuffer(self): + ## Test PyObject_GetBuffer() on a memoryview object. + #for tp in self._types: + #b = tp(self._source) + #oldrefcount = sys.getrefcount(b) + #m = self._view(b) + #oldviewrefcount = sys.getrefcount(m) + #s = unicode(m, "utf-8") + #self._check_contents(tp, b, s.encode("utf-8")) + #self.assertEquals(sys.getrefcount(m), oldviewrefcount) + #m = None + #self.assertEquals(sys.getrefcount(b), oldrefcount) + + def test_gc(self): + for tp in self._types: + if not isinstance(tp, type): + # If tp is a factory rather than a plain type, skip + continue + + class MySource(tp): + pass + class MyObject: + pass + + # Create a reference cycle through a memoryview object + b = MySource(tp(b'abc')) + m = self._view(b) + o = MyObject() + b.m = m + b.o = o + wr = weakref.ref(o) + b = m = o = None + # The cycle must be broken + gc.collect() + self.assert_(wr() is None, wr()) + + +# Variations on source objects for the buffer: bytes-like objects, then arrays +# with itemsize > 1. +# NOTE: support for multi-dimensional objects is unimplemented. + +class BaseBytesMemoryTests(AbstractMemoryTests): + ro_type = bytes + rw_type = bytearray + getitem_type = bytes + itemsize = 1 + format = 'B' + +# Disabled: array.array() does not support the new buffer API in 2.x + +#class BaseArrayMemoryTests(AbstractMemoryTests): + #ro_type = None + #rw_type = lambda self, b: array.array('i', map(ord, b)) + #getitem_type = lambda self, b: array.array('i', map(ord, b)).tostring() + #itemsize = array.array('i').itemsize + #format = 'i' + + #def test_getbuffer(self): + ## XXX Test should be adapted for non-byte buffers + #pass + + #def test_tolist(self): + ## XXX NotImplementedError: tolist() only supports byte views + #pass + + +# Variations on indirection levels: memoryview, slice of memoryview, +# slice of slice of memoryview. +# This is important to test allocation subtleties. + +class BaseMemoryviewTests: + def _view(self, obj): + return memoryview(obj) + + def _check_contents(self, tp, obj, contents): + self.assertEquals(obj, tp(contents)) + +class BaseMemorySliceTests: + source_bytes = b"XabcdefY" + + def _view(self, obj): + m = memoryview(obj) + return m[1:7] + + def _check_contents(self, tp, obj, contents): + self.assertEquals(obj[1:7], tp(contents)) + + def test_refs(self): + for tp in self._types: + m = memoryview(tp(self._source)) + oldrefcount = sys.getrefcount(m) + m[1:2] + self.assertEquals(sys.getrefcount(m), oldrefcount) + +class BaseMemorySliceSliceTests: + source_bytes = b"XabcdefY" + + def _view(self, obj): + m = memoryview(obj) + return m[:7][1:] + + def _check_contents(self, tp, obj, contents): + self.assertEquals(obj[1:7], tp(contents)) + + +# Concrete test classes + +class BytesMemoryviewTest(unittest.TestCase, + BaseMemoryviewTests, BaseBytesMemoryTests): + + def test_constructor(self): + for tp in self._types: + ob = tp(self._source) + self.assert_(memoryview(ob)) + self.assert_(memoryview(object=ob)) + self.assertRaises(TypeError, memoryview) + self.assertRaises(TypeError, memoryview, ob, ob) + self.assertRaises(TypeError, memoryview, argument=ob) + self.assertRaises(TypeError, memoryview, ob, argument=True) + +#class ArrayMemoryviewTest(unittest.TestCase, + #BaseMemoryviewTests, BaseArrayMemoryTests): + + #def test_array_assign(self): + ## Issue #4569: segfault when mutating a memoryview with itemsize != 1 + #a = array.array('i', range(10)) + #m = memoryview(a) + #new_a = array.array('i', range(9, -1, -1)) + #m[:] = new_a + #self.assertEquals(a, new_a) + + +class BytesMemorySliceTest(unittest.TestCase, + BaseMemorySliceTests, BaseBytesMemoryTests): + pass + +#class ArrayMemorySliceTest(unittest.TestCase, + #BaseMemorySliceTests, BaseArrayMemoryTests): + #pass + +class BytesMemorySliceSliceTest(unittest.TestCase, + BaseMemorySliceSliceTests, BaseBytesMemoryTests): + pass + +#class ArrayMemorySliceSliceTest(unittest.TestCase, + #BaseMemorySliceSliceTests, BaseArrayMemoryTests): + #pass + + +def test_main(): + test_support.run_unittest(__name__) + +if __name__ == "__main__": + test_main() Modified: python/trunk/Makefile.pre.in ============================================================================== --- python/trunk/Makefile.pre.in (original) +++ python/trunk/Makefile.pre.in Thu Apr 2 23:18:34 2009 @@ -320,6 +320,7 @@ Objects/listobject.o \ Objects/longobject.o \ Objects/dictobject.o \ + Objects/memoryobject.o \ Objects/methodobject.o \ Objects/moduleobject.o \ Objects/object.o \ @@ -617,6 +618,7 @@ Include/longintrepr.h \ Include/longobject.h \ Include/marshal.h \ + Include/memoryobject.h \ Include/metagrammar.h \ Include/methodobject.h \ Include/modsupport.h \ Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Apr 2 23:18:34 2009 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #2396: the memoryview object was backported from Python 3.1. + - Fix a problem in PyErr_NormalizeException that leads to "undetected errors" when hitting the recursion limit under certain circumstances. Modified: python/trunk/Objects/abstract.c ============================================================================== --- python/trunk/Objects/abstract.c (original) +++ python/trunk/Objects/abstract.c Thu Apr 2 23:18:34 2009 @@ -439,7 +439,7 @@ } -static void +void _add_one_to_index_F(int nd, Py_ssize_t *index, Py_ssize_t *shape) { int k; @@ -455,7 +455,7 @@ } } -static void +void _add_one_to_index_C(int nd, Py_ssize_t *index, Py_ssize_t *shape) { int k; Added: python/trunk/Objects/memoryobject.c ============================================================================== --- (empty file) +++ python/trunk/Objects/memoryobject.c Thu Apr 2 23:18:34 2009 @@ -0,0 +1,834 @@ + +/* Memoryview object implementation */ + +#include "Python.h" + +static Py_ssize_t +get_shape0(Py_buffer *buf) +{ + if (buf->shape != NULL) + return buf->shape[0]; + if (buf->ndim == 0) + return 1; + PyErr_SetString(PyExc_TypeError, + "exported buffer does not have any shape information associated " + "to it"); + return -1; +} + +static void +dup_buffer(Py_buffer *dest, Py_buffer *src) +{ + *dest = *src; + if (src->ndim == 1 && src->shape != NULL) { + dest->shape = &(dest->smalltable[0]); + dest->shape[0] = get_shape0(src); + } + if (src->ndim == 1 && src->strides != NULL) { + dest->strides = &(dest->smalltable[1]); + dest->strides[0] = src->strides[0]; + } +} + +static int +memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags) +{ + int res = 0; + /* XXX for whatever reason fixing the flags seems necessary */ + if (self->view.readonly) + flags &= ~PyBUF_WRITABLE; + if (self->view.obj != NULL) + res = PyObject_GetBuffer(self->view.obj, view, flags); + if (view) + dup_buffer(view, &self->view); + return res; +} + +static void +memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view) +{ + PyBuffer_Release(view); +} + +PyDoc_STRVAR(memory_doc, +"memoryview(object)\n\ +\n\ +Create a new memoryview object which references the given object."); + +PyObject * +PyMemoryView_FromBuffer(Py_buffer *info) +{ + PyMemoryViewObject *mview; + + mview = (PyMemoryViewObject *) + PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type); + if (mview == NULL) + return NULL; + mview->base = NULL; + dup_buffer(&mview->view, info); + /* NOTE: mview->view.obj should already have been incref'ed as + part of PyBuffer_FillInfo(). */ + _PyObject_GC_TRACK(mview); + return (PyObject *)mview; +} + +PyObject * +PyMemoryView_FromObject(PyObject *base) +{ + PyMemoryViewObject *mview; + + if (!PyObject_CheckBuffer(base)) { + PyErr_SetString(PyExc_TypeError, + "cannot make memory view because object does " + "not have the buffer interface"); + return NULL; + } + + mview = (PyMemoryViewObject *) + PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type); + if (mview == NULL) + return NULL; + + mview->base = NULL; + if (PyObject_GetBuffer(base, &(mview->view), PyBUF_FULL_RO) < 0) { + Py_DECREF(mview); + return NULL; + } + + mview->base = base; + Py_INCREF(base); + _PyObject_GC_TRACK(mview); + return (PyObject *)mview; +} + +static PyObject * +memory_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) +{ + PyObject *obj; + static char *kwlist[] = {"object", 0}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:memoryview", kwlist, + &obj)) { + return NULL; + } + + return PyMemoryView_FromObject(obj); +} + + +static void +_strided_copy_nd(char *dest, char *src, int nd, Py_ssize_t *shape, + Py_ssize_t *strides, Py_ssize_t itemsize, char fort) +{ + int k; + Py_ssize_t outstride; + + if (nd==0) { + memcpy(dest, src, itemsize); + } + else if (nd == 1) { + for (k = 0; kndim > PY_SSIZE_T_MAX / sizeof(Py_ssize_t)) { + PyErr_NoMemory(); + return -1; + } + + indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view->ndim); + if (indices == NULL) { + PyErr_NoMemory(); + return -1; + } + for (k=0; kndim;k++) { + indices[k] = 0; + } + + elements = 1; + for (k=0; kndim; k++) { + elements *= view->shape[k]; + } + if (fort == 'F') { + func = _add_one_to_index_F; + } + else { + func = _add_one_to_index_C; + } + while (elements--) { + func(view->ndim, indices, view->shape); + ptr = PyBuffer_GetPointer(view, indices); + memcpy(dest, ptr, view->itemsize); + dest += view->itemsize; + } + + PyMem_Free(indices); + return 0; +} + +/* + Get a the data from an object as a contiguous chunk of memory (in + either 'C' or 'F'ortran order) even if it means copying it into a + separate memory area. + + Returns a new reference to a Memory view object. If no copy is needed, + the memory view object points to the original memory and holds a + lock on the original. If a copy is needed, then the memory view object + points to a brand-new Bytes object (and holds a memory lock on it). + + buffertype + + PyBUF_READ buffer only needs to be read-only + PyBUF_WRITE buffer needs to be writable (give error if not contiguous) + PyBUF_SHADOW buffer needs to be writable so shadow it with + a contiguous buffer if it is not. The view will point to + the shadow buffer which can be written to and then + will be copied back into the other buffer when the memory + view is de-allocated. While the shadow buffer is + being used, it will have an exclusive write lock on + the original buffer. + */ + +PyObject * +PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort) +{ + PyMemoryViewObject *mem; + PyObject *bytes; + Py_buffer *view; + int flags; + char *dest; + + if (!PyObject_CheckBuffer(obj)) { + PyErr_SetString(PyExc_TypeError, + "object does not have the buffer interface"); + return NULL; + } + + mem = PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type); + if (mem == NULL) + return NULL; + + view = &mem->view; + flags = PyBUF_FULL_RO; + switch(buffertype) { + case PyBUF_WRITE: + flags = PyBUF_FULL; + break; + } + + if (PyObject_GetBuffer(obj, view, flags) != 0) { + Py_DECREF(mem); + return NULL; + } + + if (PyBuffer_IsContiguous(view, fort)) { + /* no copy needed */ + Py_INCREF(obj); + mem->base = obj; + _PyObject_GC_TRACK(mem); + return (PyObject *)mem; + } + /* otherwise a copy is needed */ + if (buffertype == PyBUF_WRITE) { + Py_DECREF(mem); + PyErr_SetString(PyExc_BufferError, + "writable contiguous buffer requested " + "for a non-contiguousobject."); + return NULL; + } + bytes = PyBytes_FromStringAndSize(NULL, view->len); + if (bytes == NULL) { + Py_DECREF(mem); + return NULL; + } + dest = PyBytes_AS_STRING(bytes); + /* different copying strategy depending on whether + or not any pointer de-referencing is needed + */ + /* strided or in-direct copy */ + if (view->suboffsets==NULL) { + _strided_copy_nd(dest, view->buf, view->ndim, view->shape, + view->strides, view->itemsize, fort); + } + else { + if (_indirect_copy_nd(dest, view, fort) < 0) { + Py_DECREF(bytes); + Py_DECREF(mem); + return NULL; + } + } + if (buffertype == PyBUF_SHADOW) { + /* return a shadowed memory-view object */ + view->buf = dest; + mem->base = PyTuple_Pack(2, obj, bytes); + Py_DECREF(bytes); + if (mem->base == NULL) { + Py_DECREF(mem); + return NULL; + } + } + else { + PyBuffer_Release(view); /* XXX ? */ + /* steal the reference */ + mem->base = bytes; + } + _PyObject_GC_TRACK(mem); + return (PyObject *)mem; +} + + +static PyObject * +memory_format_get(PyMemoryViewObject *self) +{ + return PyUnicode_FromString(self->view.format); +} + +static PyObject * +memory_itemsize_get(PyMemoryViewObject *self) +{ + return PyLong_FromSsize_t(self->view.itemsize); +} + +static PyObject * +_IntTupleFromSsizet(int len, Py_ssize_t *vals) +{ + int i; + PyObject *o; + PyObject *intTuple; + + if (vals == NULL) { + Py_INCREF(Py_None); + return Py_None; + } + intTuple = PyTuple_New(len); + if (!intTuple) return NULL; + for(i=0; iview.ndim, self->view.shape); +} + +static PyObject * +memory_strides_get(PyMemoryViewObject *self) +{ + return _IntTupleFromSsizet(self->view.ndim, self->view.strides); +} + +static PyObject * +memory_suboffsets_get(PyMemoryViewObject *self) +{ + return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets); +} + +static PyObject * +memory_readonly_get(PyMemoryViewObject *self) +{ + return PyBool_FromLong(self->view.readonly); +} + +static PyObject * +memory_ndim_get(PyMemoryViewObject *self) +{ + return PyLong_FromLong(self->view.ndim); +} + +static PyGetSetDef memory_getsetlist[] ={ + {"format", (getter)memory_format_get, NULL, NULL}, + {"itemsize", (getter)memory_itemsize_get, NULL, NULL}, + {"shape", (getter)memory_shape_get, NULL, NULL}, + {"strides", (getter)memory_strides_get, NULL, NULL}, + {"suboffsets", (getter)memory_suboffsets_get, NULL, NULL}, + {"readonly", (getter)memory_readonly_get, NULL, NULL}, + {"ndim", (getter)memory_ndim_get, NULL, NULL}, + {NULL, NULL, NULL, NULL}, +}; + + +static PyObject * +memory_tobytes(PyMemoryViewObject *self, PyObject *noargs) +{ + Py_buffer view; + PyObject *res; + + if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_FULL) < 0) + return NULL; + + res = PyBytes_FromStringAndSize(NULL, view.len); + PyBuffer_ToContiguous(PyBytes_AS_STRING(res), &view, view.len, 'C'); + PyBuffer_Release(&view); + return res; +} + +/* TODO: rewrite this function using the struct module to unpack + each buffer item */ + +static PyObject * +memory_tolist(PyMemoryViewObject *mem, PyObject *noargs) +{ + Py_buffer *view = &(mem->view); + Py_ssize_t i; + PyObject *res, *item; + char *buf; + + if (strcmp(view->format, "B") || view->itemsize != 1) { + PyErr_SetString(PyExc_NotImplementedError, + "tolist() only supports byte views"); + return NULL; + } + if (view->ndim != 1) { + PyErr_SetString(PyExc_NotImplementedError, + "tolist() only supports one-dimensional objects"); + return NULL; + } + res = PyList_New(view->len); + if (res == NULL) + return NULL; + buf = view->buf; + for (i = 0; i < view->len; i++) { + item = PyInt_FromLong((unsigned char) *buf); + if (item == NULL) { + Py_DECREF(res); + return NULL; + } + PyList_SET_ITEM(res, i, item); + buf++; + } + return res; +} + +static PyMethodDef memory_methods[] = { + {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, NULL}, + {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, NULL}, + {NULL, NULL} /* sentinel */ +}; + + +static void +memory_dealloc(PyMemoryViewObject *self) +{ + _PyObject_GC_UNTRACK(self); + if (self->view.obj != NULL) { + if (self->base && PyTuple_Check(self->base)) { + /* Special case when first element is generic object + with buffer interface and the second element is a + contiguous "shadow" that must be copied back into + the data areay of the first tuple element before + releasing the buffer on the first element. + */ + + PyObject_CopyData(PyTuple_GET_ITEM(self->base,0), + PyTuple_GET_ITEM(self->base,1)); + + /* The view member should have readonly == -1 in + this instance indicating that the memory can + be "locked" and was locked and will be unlocked + again after this call. + */ + PyBuffer_Release(&(self->view)); + } + else { + PyBuffer_Release(&(self->view)); + } + Py_CLEAR(self->base); + } + PyObject_GC_Del(self); +} + +static PyObject * +memory_repr(PyMemoryViewObject *self) +{ + return PyUnicode_FromFormat("", self); +} + +/* Sequence methods */ +static Py_ssize_t +memory_length(PyMemoryViewObject *self) +{ + return get_shape0(&self->view); +} + +/* + mem[obj] returns a bytes object holding the data for one element if + obj fully indexes the memory view or another memory-view object + if it does not. + + 0-d memory-view objects can be referenced using ... or () but + not with anything else. + */ +static PyObject * +memory_subscript(PyMemoryViewObject *self, PyObject *key) +{ + Py_buffer *view; + view = &(self->view); + + if (view->ndim == 0) { + if (key == Py_Ellipsis || + (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) { + Py_INCREF(self); + return (PyObject *)self; + } + else { + PyErr_SetString(PyExc_IndexError, + "invalid indexing of 0-dim memory"); + return NULL; + } + } + if (PyIndex_Check(key)) { + Py_ssize_t result; + result = PyNumber_AsSsize_t(key, NULL); + if (result == -1 && PyErr_Occurred()) + return NULL; + if (view->ndim == 1) { + /* Return a bytes object */ + char *ptr; + ptr = (char *)view->buf; + if (result < 0) { + result += get_shape0(view); + } + if ((result < 0) || (result >= get_shape0(view))) { + PyErr_SetString(PyExc_IndexError, + "index out of bounds"); + return NULL; + } + if (view->strides == NULL) + ptr += view->itemsize * result; + else + ptr += view->strides[0] * result; + if (view->suboffsets != NULL && + view->suboffsets[0] >= 0) { + ptr = *((char **)ptr) + view->suboffsets[0]; + } + return PyBytes_FromStringAndSize(ptr, view->itemsize); + } + else { + /* Return a new memory-view object */ + Py_buffer newview; + memset(&newview, 0, sizeof(newview)); + /* XXX: This needs to be fixed so it + actually returns a sub-view + */ + return PyMemoryView_FromBuffer(&newview); + } + } + else if (PySlice_Check(key)) { + Py_ssize_t start, stop, step, slicelength; + + if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view), + &start, &stop, &step, &slicelength) < 0) { + return NULL; + } + + if (step == 1 && view->ndim == 1) { + Py_buffer newview; + void *newbuf = (char *) view->buf + + start * view->itemsize; + int newflags = view->readonly + ? PyBUF_CONTIG_RO : PyBUF_CONTIG; + + /* XXX There should be an API to create a subbuffer */ + if (view->obj != NULL) { + if (PyObject_GetBuffer(view->obj, &newview, newflags) == -1) + return NULL; + } + else { + newview = *view; + } + newview.buf = newbuf; + newview.len = slicelength * newview.itemsize; + newview.format = view->format; + newview.shape = &(newview.smalltable[0]); + newview.shape[0] = slicelength; + newview.strides = &(newview.itemsize); + return PyMemoryView_FromBuffer(&newview); + } + PyErr_SetNone(PyExc_NotImplementedError); + return NULL; + } + PyErr_Format(PyExc_TypeError, + "cannot index memory using \"%.200s\"", + key->ob_type->tp_name); + return NULL; +} + + +/* Need to support assigning memory if we can */ +static int +memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value) +{ + Py_ssize_t start, len, bytelen, i; + Py_buffer srcview; + Py_buffer *view = &(self->view); + char *srcbuf, *destbuf; + + if (view->readonly) { + PyErr_SetString(PyExc_TypeError, + "cannot modify read-only memory"); + return -1; + } + if (view->ndim != 1) { + PyErr_SetNone(PyExc_NotImplementedError); + return -1; + } + if (PyIndex_Check(key)) { + start = PyNumber_AsSsize_t(key, NULL); + if (start == -1 && PyErr_Occurred()) + return -1; + if (start < 0) { + start += get_shape0(view); + } + if ((start < 0) || (start >= get_shape0(view))) { + PyErr_SetString(PyExc_IndexError, + "index out of bounds"); + return -1; + } + len = 1; + } + else if (PySlice_Check(key)) { + Py_ssize_t stop, step; + + if (PySlice_GetIndicesEx((PySliceObject*)key, get_shape0(view), + &start, &stop, &step, &len) < 0) { + return -1; + } + if (step != 1) { + PyErr_SetNone(PyExc_NotImplementedError); + return -1; + } + } + else { + PyErr_Format(PyExc_TypeError, + "cannot index memory using \"%.200s\"", + key->ob_type->tp_name); + return -1; + } + if (PyObject_GetBuffer(value, &srcview, PyBUF_CONTIG_RO) == -1) { + return -1; + } + /* XXX should we allow assignment of different item sizes + as long as the byte length is the same? + (e.g. assign 2 shorts to a 4-byte slice) */ + if (srcview.itemsize != view->itemsize) { + PyErr_Format(PyExc_TypeError, + "mismatching item sizes for \"%.200s\" and \"%.200s\"", + view->obj->ob_type->tp_name, srcview.obj->ob_type->tp_name); + goto _error; + } + bytelen = len * view->itemsize; + if (bytelen != srcview.len) { + PyErr_SetString(PyExc_ValueError, + "cannot modify size of memoryview object"); + goto _error; + } + /* Do the actual copy */ + destbuf = (char *) view->buf + start * view->itemsize; + srcbuf = (char *) srcview.buf; + if (destbuf + bytelen < srcbuf || srcbuf + bytelen < destbuf) + /* No overlapping */ + memcpy(destbuf, srcbuf, bytelen); + else if (destbuf < srcbuf) { + /* Copy in ascending order */ + for (i = 0; i < bytelen; i++) + destbuf[i] = srcbuf[i]; + } + else { + /* Copy in descencing order */ + for (i = bytelen - 1; i >= 0; i--) + destbuf[i] = srcbuf[i]; + } + + PyBuffer_Release(&srcview); + return 0; + +_error: + PyBuffer_Release(&srcview); + return -1; +} + +static PyObject * +memory_richcompare(PyObject *v, PyObject *w, int op) +{ + Py_buffer vv, ww; + int equal = 0; + PyObject *res; + + vv.obj = NULL; + ww.obj = NULL; + if (op != Py_EQ && op != Py_NE) + goto _notimpl; + if (PyObject_GetBuffer(v, &vv, PyBUF_CONTIG_RO) == -1) { + PyErr_Clear(); + goto _notimpl; + } + if (PyObject_GetBuffer(w, &ww, PyBUF_CONTIG_RO) == -1) { + PyErr_Clear(); + goto _notimpl; + } + + if (vv.itemsize != ww.itemsize || vv.len != ww.len) + goto _end; + + equal = !memcmp(vv.buf, ww.buf, vv.len); + +_end: + PyBuffer_Release(&vv); + PyBuffer_Release(&ww); + if ((equal && op == Py_EQ) || (!equal && op == Py_NE)) + res = Py_True; + else + res = Py_False; + Py_INCREF(res); + return res; + +_notimpl: + PyBuffer_Release(&vv); + PyBuffer_Release(&ww); + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; +} + + +static int +memory_traverse(PyMemoryViewObject *self, visitproc visit, void *arg) +{ + if (self->base != NULL) + Py_VISIT(self->base); + if (self->view.obj != NULL) + Py_VISIT(self->view.obj); + return 0; +} + +static int +memory_clear(PyMemoryViewObject *self) +{ + Py_CLEAR(self->base); + PyBuffer_Release(&self->view); + return 0; +} + + +/* As mapping */ +static PyMappingMethods memory_as_mapping = { + (lenfunc)memory_length, /* mp_length */ + (binaryfunc)memory_subscript, /* mp_subscript */ + (objobjargproc)memory_ass_sub, /* mp_ass_subscript */ +}; + + +/* Buffer methods */ +static PyBufferProcs memory_as_buffer = { + 0, /* bf_getreadbuffer */ + 0, /* bf_getwritebuffer */ + 0, /* bf_getsegcount */ + 0, /* bf_getcharbuffer */ + (getbufferproc)memory_getbuf, /* bf_getbuffer */ + (releasebufferproc)memory_releasebuf, /* bf_releasebuffer */ +}; + + +PyTypeObject PyMemoryView_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "memoryview", + sizeof(PyMemoryViewObject), + 0, + (destructor)memory_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + (reprfunc)memory_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + &memory_as_mapping, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + &memory_as_buffer, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */ + memory_doc, /* tp_doc */ + (traverseproc)memory_traverse, /* tp_traverse */ + (inquiry)memory_clear, /* tp_clear */ + memory_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + memory_methods, /* tp_methods */ + 0, /* tp_members */ + memory_getsetlist, /* 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 */ + memory_new, /* tp_new */ +}; Modified: python/trunk/Objects/typeobject.c ============================================================================== --- python/trunk/Objects/typeobject.c (original) +++ python/trunk/Objects/typeobject.c Thu Apr 2 23:18:34 2009 @@ -2304,6 +2304,8 @@ Py_TPFLAGS_BASETYPE; if (base->tp_flags & Py_TPFLAGS_HAVE_GC) type->tp_flags |= Py_TPFLAGS_HAVE_GC; + if (base->tp_flags & Py_TPFLAGS_HAVE_NEWBUFFER) + type->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER; /* It's a new-style number unless it specifically inherits any old-style numeric behavior */ @@ -3596,6 +3598,8 @@ return 0; } +#define BUFFER_FLAGS (Py_TPFLAGS_HAVE_GETCHARBUFFER | Py_TPFLAGS_HAVE_NEWBUFFER) + static void inherit_special(PyTypeObject *type, PyTypeObject *base) { @@ -3603,9 +3607,9 @@ /* Special flag magic */ if (!type->tp_as_buffer && base->tp_as_buffer) { - type->tp_flags &= ~Py_TPFLAGS_HAVE_GETCHARBUFFER; + type->tp_flags &= ~BUFFER_FLAGS; type->tp_flags |= - base->tp_flags & Py_TPFLAGS_HAVE_GETCHARBUFFER; + base->tp_flags & BUFFER_FLAGS; } if (!type->tp_as_sequence && base->tp_as_sequence) { type->tp_flags &= ~Py_TPFLAGS_HAVE_SEQUENCE_IN; Modified: python/trunk/Python/bltinmodule.c ============================================================================== --- python/trunk/Python/bltinmodule.c (original) +++ python/trunk/Python/bltinmodule.c Thu Apr 2 23:18:34 2009 @@ -2573,7 +2573,7 @@ SETBUILTIN("True", Py_True); SETBUILTIN("basestring", &PyBaseString_Type); SETBUILTIN("bool", &PyBool_Type); - /* SETBUILTIN("memoryview", &PyMemoryView_Type); */ + SETBUILTIN("memoryview", &PyMemoryView_Type); SETBUILTIN("bytearray", &PyByteArray_Type); SETBUILTIN("bytes", &PyString_Type); SETBUILTIN("buffer", &PyBuffer_Type); From python-checkins at python.org Thu Apr 2 23:42:25 2009 From: python-checkins at python.org (antoine.pitrou) Date: Thu, 2 Apr 2009 23:42:25 +0200 (CEST) Subject: [Python-checkins] r71071 - python/branches/py3k Message-ID: <20090402214225.0DFB01E402D@bag.python.org> Author: antoine.pitrou Date: Thu Apr 2 23:42:24 2009 New Revision: 71071 Log: Blocked revisions 71070 via svnmerge ........ r71070 | antoine.pitrou | 2009-04-02 23:18:34 +0200 (jeu., 02 avril 2009) | 3 lines Issue #2396: backport the memoryview object. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Thu Apr 2 23:48:06 2009 From: python-checkins at python.org (eric.smith) Date: Thu, 2 Apr 2009 23:48:06 +0200 (CEST) Subject: [Python-checkins] r71072 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090402214806.721DD1E402D@bag.python.org> Author: eric.smith Date: Thu Apr 2 23:48:06 2009 New Revision: 71072 Log: Almost done with string formatting! Only a few edge cases dealing with large numbers remain. Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Thu Apr 2 23:48:06 2009 @@ -533,9 +533,8 @@ char *digits, *digits_end; int decpt, sign, exp_len; int use_exp = 0; - int is_integer = 1; /* is the output produced so far - just an integer? */ - int add_padding = 0; + int is_integer; /* is the output produced so far just an integer? */ + int add_padding; Py_ssize_t n_digits_after_decimal = 0; Py_ssize_t n_digits; Py_ssize_t i; @@ -581,8 +580,8 @@ type = 'g'; over time, those tests should be deleted */ - if (decpt > 50 && format_code == 'f') - format_code = 'g'; +/* if (decpt > 50 && format_code == 'f') + format_code = 'g'; */ /* detect if we're using exponents or not */ switch (format_code) { @@ -616,31 +615,30 @@ n_digits_after_decimal = n_digits - 1; *buf++ = digits[0]; *buf++ = '.'; - is_integer = 0; strncpy(buf, digits + 1, n_digits_after_decimal); buf += n_digits_after_decimal; } else { /* Use fixed-point notation */ + + /* Be aware that n_digits_after_decimal can be negative! */ + n_digits_after_decimal = n_digits - decpt; + if (decpt <= 0) { /* output: 0.00-00dd-dd */ *buf++ = '0'; *buf++ = '.'; - is_integer = 0; for (i = 0; i < -decpt; i++) *buf++ = '0'; strncpy(buf, digits, n_digits); buf += n_digits; - n_digits_after_decimal = n_digits - decpt; } else if (decpt < n_digits) { /* Output: dd-dd.dd-dd */ strncpy(buf, digits, decpt); buf += decpt; *buf++ = '.'; - is_integer = 0; strncpy(buf, digits + decpt, n_digits - decpt); buf += n_digits - decpt; - n_digits_after_decimal = n_digits - decpt; } else { /* decpt >= n_digits. Output: dd-dd00-00.0 */ @@ -649,13 +647,12 @@ for (i = 0; i < decpt - n_digits; i++) *buf++ = '0'; *buf++ = '.'; - is_integer = 0; - n_digits_after_decimal = decpt - n_digits; } } /* Add trailing non-significant zeros for non-mode 0 and non-code g, unless doing alt formatting */ + add_padding = 0; if (mode != 0) { if (format_code == 'g') { if (use_alt_formatting) @@ -665,17 +662,17 @@ add_padding = 1; } - /* It should never be the case that n_trailing_zeros is negative, but - if so this loop executes zero times. */ if (add_padding) for (i = n_digits_after_decimal; i < n_wanted_digits_after_decimal; i++) *buf++ = '0'; - /* See if we want to have the trailing decimal or not */ - if (format_code == 'g' && buf[-1] == '.') { + /* If we're at a trailing decimal, delete it. We are then just an integer. */ + if (buf[-1] == '.') { buf--; - is_integer = 1; /* XXX not sure if this is correct, should probably change this to detect this case and not add it to begin with */ + is_integer = 1; } + else + is_integer = 0; /* Now that we've done zero padding, add an exponent if needed. */ if (use_exp) { @@ -744,6 +741,7 @@ n_wanted_digits_after_decimal--; break; case 'r': + /* "repr" pseudo-mode */ mode = 0; break; } From buildbot at python.org Thu Apr 2 23:58:31 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 02 Apr 2009 21:58:31 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090402215831.F07241E42FE@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/243 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 3 tests failed: test_distutils test_posix test_subprocess ====================================================================== FAIL: test_get_python_inc (distutils.tests.test_sysconfig.SysconfigTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/distutils/tests/test_sysconfig.py", line 45, in test_get_python_inc self.assert_(os.path.isdir(inc_dir), inc_dir) AssertionError: /home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/Include ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From python-checkins at python.org Fri Apr 3 00:25:41 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 3 Apr 2009 00:25:41 +0200 (CEST) Subject: [Python-checkins] r71073 - in python/trunk/Lib: collections.py test/test_collections.py Message-ID: <20090402222541.1A8B71E490B@bag.python.org> Author: raymond.hettinger Date: Fri Apr 3 00:25:40 2009 New Revision: 71073 Log: Have namedtuple's field renamer assign names that are consistent with the corresponding tuple index. Modified: python/trunk/Lib/collections.py python/trunk/Lib/test/test_collections.py Modified: python/trunk/Lib/collections.py ============================================================================== --- python/trunk/Lib/collections.py (original) +++ python/trunk/Lib/collections.py Fri Apr 3 00:25:40 2009 @@ -178,7 +178,7 @@ if (not all(c.isalnum() or c=='_' for c in name) or _iskeyword(name) or not name or name[0].isdigit() or name.startswith('_') or name in seen): - names[i] = '_%d' % (i+1) + names[i] = '_%d' % i seen.add(name) field_names = tuple(names) for name in (typename,) + field_names: Modified: python/trunk/Lib/test/test_collections.py ============================================================================== --- python/trunk/Lib/test/test_collections.py (original) +++ python/trunk/Lib/test/test_collections.py Fri Apr 3 00:25:40 2009 @@ -49,12 +49,12 @@ def test_name_fixer(self): for spec, renamed in [ - [('efg', 'g%hi'), ('efg', '_2')], # field with non-alpha char - [('abc', 'class'), ('abc', '_2')], # field has keyword - [('8efg', '9ghi'), ('_1', '_2')], # field starts with digit - [('abc', '_efg'), ('abc', '_2')], # field with leading underscore - [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_3', 'ghi')], # duplicate field - [('abc', '', 'x'), ('abc', '_2', 'x')], # fieldname is a space + [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char + [('abc', 'class'), ('abc', '_1')], # field has keyword + [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit + [('abc', '_efg'), ('abc', '_1')], # field with leading underscore + [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field + [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space ]: self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed) From python-checkins at python.org Fri Apr 3 00:31:59 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 3 Apr 2009 00:31:59 +0200 (CEST) Subject: [Python-checkins] r71074 - in python/branches/py3k/Lib: collections.py test/test_collections.py Message-ID: <20090402223159.AC24B1E4014@bag.python.org> Author: raymond.hettinger Date: Fri Apr 3 00:31:59 2009 New Revision: 71074 Log: Have namedtuple's field renamer assign names that are consistent with the corresponding tuple index. Modified: python/branches/py3k/Lib/collections.py python/branches/py3k/Lib/test/test_collections.py Modified: python/branches/py3k/Lib/collections.py ============================================================================== --- python/branches/py3k/Lib/collections.py (original) +++ python/branches/py3k/Lib/collections.py Fri Apr 3 00:31:59 2009 @@ -174,7 +174,7 @@ if (not all(c.isalnum() or c=='_' for c in name) or _iskeyword(name) or not name or name[0].isdigit() or name.startswith('_') or name in seen): - names[i] = '_%d' % (i+1) + names[i] = '_%d' % i seen.add(name) field_names = tuple(names) for name in (typename,) + field_names: Modified: python/branches/py3k/Lib/test/test_collections.py ============================================================================== --- python/branches/py3k/Lib/test/test_collections.py (original) +++ python/branches/py3k/Lib/test/test_collections.py Fri Apr 3 00:31:59 2009 @@ -51,12 +51,12 @@ def test_name_fixer(self): for spec, renamed in [ - [('efg', 'g%hi'), ('efg', '_2')], # field with non-alpha char - [('abc', 'class'), ('abc', '_2')], # field has keyword - [('8efg', '9ghi'), ('_1', '_2')], # field starts with digit - [('abc', '_efg'), ('abc', '_2')], # field with leading underscore - [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_3', 'ghi')], # duplicate field - [('abc', '', 'x'), ('abc', '_2', 'x')], # fieldname is a space + [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char + [('abc', 'class'), ('abc', '_1')], # field has keyword + [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit + [('abc', '_efg'), ('abc', '_1')], # field with leading underscore + [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field + [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space ]: self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed) From python-checkins at python.org Fri Apr 3 00:34:18 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 3 Apr 2009 00:34:18 +0200 (CEST) Subject: [Python-checkins] r71075 - python/trunk/Doc/library/collections.rst Message-ID: <20090402223418.156D51E4065@bag.python.org> Author: raymond.hettinger Date: Fri Apr 3 00:34:17 2009 New Revision: 71075 Log: Update docs for namedtuple's renaming change. Modified: python/trunk/Doc/library/collections.rst Modified: python/trunk/Doc/library/collections.rst ============================================================================== --- python/trunk/Doc/library/collections.rst (original) +++ python/trunk/Doc/library/collections.rst Fri Apr 3 00:34:17 2009 @@ -649,7 +649,7 @@ If *rename* is true, invalid fieldnames are automatically replaced with positional names. For example, ``['abc', 'def', 'ghi', 'abc']`` is - converted to ``['abc', '_2', 'ghi', '_4']``, eliminating the keyword + converted to ``['abc', '_1', 'ghi', '_3']``, eliminating the keyword ``def`` and the duplicate fieldname ``abc``. If *verbose* is true, the class definition is printed just before being built. From python-checkins at python.org Fri Apr 3 00:37:59 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 3 Apr 2009 00:37:59 +0200 (CEST) Subject: [Python-checkins] r71076 - python/branches/py3k/Doc/library/collections.rst Message-ID: <20090402223759.399C31E4014@bag.python.org> Author: raymond.hettinger Date: Fri Apr 3 00:37:59 2009 New Revision: 71076 Log: Update docs for namedtuple's renaming change. Modified: python/branches/py3k/Doc/library/collections.rst Modified: python/branches/py3k/Doc/library/collections.rst ============================================================================== --- python/branches/py3k/Doc/library/collections.rst (original) +++ python/branches/py3k/Doc/library/collections.rst Fri Apr 3 00:37:59 2009 @@ -625,7 +625,7 @@ If *rename* is true, invalid fieldnames are automatically replaced with positional names. For example, ``['abc', 'def', 'ghi', 'abc']`` is - converted to ``['abc', '_2', 'ghi', '_4']``, eliminating the keyword + converted to ``['abc', '_1', 'ghi', '_3']``, eliminating the keyword ``def`` and the duplicate fieldname ``abc``. If *verbose* is true, the class definition is printed just before being built. From python-checkins at python.org Fri Apr 3 03:00:31 2009 From: python-checkins at python.org (eric.smith) Date: Fri, 3 Apr 2009 03:00:31 +0200 (CEST) Subject: [Python-checkins] r71077 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090403010031.1B73D1E401C@bag.python.org> Author: eric.smith Date: Fri Apr 3 03:00:30 2009 New Revision: 71077 Log: Cleaned up 'g' formatting case, only 4 tests left that fail. I'm not sure of the right thing to do in the marshal test failure. I also need to look at the locale test failure, that's probably an actual bug. Will look at the others. Also cleaned up many comments and style issues. Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Fri Apr 3 03:00:30 2009 @@ -519,8 +519,8 @@ }; -/* convert a Python float to a minimal string that evaluates back to that - float. The output is minimal in the sense of having the least possible +/* Convert a Python float to a minimal string that evaluates back to that + float. The output is minimal in the sense of having the fewest possible number of significant digits. */ static void @@ -534,10 +534,9 @@ int decpt, sign, exp_len; int use_exp = 0; int is_integer; /* is the output produced so far just an integer? */ - int add_padding; + int add_trailing_zeros; Py_ssize_t n_digits_after_decimal = 0; Py_ssize_t n_digits; - Py_ssize_t i; /* _Py_dg_dtoa returns a digit string (no decimal point or exponent) */ @@ -546,9 +545,9 @@ n_digits = digits_end - digits; if (n_digits && !isdigit(digits[0])) { - /* infinities and nans here; adapt Gay's output, + /* Infinities and nans here; adapt Gay's output, so convert Infinity to inf and NaN to nan, and - ignore sign of nan. */ + ignore sign of nan. Then return. */ if (digits[0] == 'i' || digits[0] == 'I') { if (sign == 1) { *buf++ = '-'; @@ -567,14 +566,18 @@ /* shouldn't get here: Gay's code should always return something starting with a digit, an 'I', or an 'N' */ - printf("Help! dtoa returned: %.*s\n", - (int)n_digits, digits); + /*printf("Help! dtoa returned: %.*s\n", + (int)n_digits, digits);*/ + strncpy(buf, 'ERR', 3); + buf += 3; assert(0); } *buf = '\0'; return; } + /* We got digits back, format them. */ + /* this replaces the various tests in other places like: if (type == 'f' && fabs(x) >= 1e50) type = 'g'; @@ -583,31 +586,25 @@ /* if (decpt > 50 && format_code == 'f') format_code = 'g'; */ - /* detect if we're using exponents or not */ + /* Detect if we're using exponents or not */ switch (format_code) { - case 'e': - use_exp = 1; - break; - case 'f': - use_exp = 0; - break; + case 'e': use_exp = 1; break; + case 'f': use_exp = 0; break; case 'g': { - int min_decpt = -4; - - if ((mode != 0) && (decpt > precision || decpt < min_decpt)) + if ((mode != 0) && (decpt > precision || decpt < -4)) use_exp = 1; - else + else { use_exp = 0; + n_wanted_digits_after_decimal = precision - decpt; + } } } - /* we got digits back, format them */ - - if (sign == 1) { + /* Always add a negative sign, and a plus sign if always_add_sign. */ + if (sign == 1) *buf++ = '-'; - } else if (always_add_sign) { + else if (always_add_sign) *buf++ = '+'; - } if (use_exp) { /* Exponential notation: d[.dddd]e(+|-)ee; at least 2 digits @@ -617,6 +614,9 @@ *buf++ = '.'; strncpy(buf, digits + 1, n_digits_after_decimal); buf += n_digits_after_decimal; + + /* Don't add the exponent yet. That's done later after a bit + more formatting. */ } else { /* Use fixed-point notation */ @@ -624,11 +624,14 @@ n_digits_after_decimal = n_digits - decpt; if (decpt <= 0) { - /* output: 0.00-00dd-dd */ + /* Output: 0.00-00dd-dd */ *buf++ = '0'; *buf++ = '.'; - for (i = 0; i < -decpt; i++) - *buf++ = '0'; + /* Add the appropriate number of zeros. */ + memset(buf, '0', -decpt); + buf += -decpt; + + /* Then the digits */ strncpy(buf, digits, n_digits); buf += n_digits; } @@ -642,29 +645,32 @@ } else { /* decpt >= n_digits. Output: dd-dd00-00.0 */ - strncpy(buf, digits, n_digits); + strncpy(buf, digits, n_digits); /* digits */ buf += n_digits; - for (i = 0; i < decpt - n_digits; i++) - *buf++ = '0'; + + memset(buf, '0', decpt - n_digits); /* zeros */ + buf += decpt - n_digits; + *buf++ = '.'; } } /* Add trailing non-significant zeros for non-mode 0 and non-code g, unless doing alt formatting */ - add_padding = 0; + add_trailing_zeros = 0; if (mode != 0) { if (format_code == 'g') { if (use_alt_formatting) - add_padding = 1; + add_trailing_zeros = 1; } else - add_padding = 1; + add_trailing_zeros = 1; } - if (add_padding) - for (i = n_digits_after_decimal; i < n_wanted_digits_after_decimal; i++) - *buf++ = '0'; + if (add_trailing_zeros) { + memset(buf, '0', n_wanted_digits_after_decimal - n_digits_after_decimal); + buf += n_wanted_digits_after_decimal - n_digits_after_decimal; + } /* If we're at a trailing decimal, delete it. We are then just an integer. */ if (buf[-1] == '.') { @@ -672,6 +678,8 @@ is_integer = 1; } else + /* The decimal isn't at the end, so it's somewhere else in the + string. We are therefore not an integer. */ is_integer = 0; /* Now that we've done zero padding, add an exponent if needed. */ @@ -727,6 +735,8 @@ if (format_code != lc_format_code) float_strings = uc_float_strings; + /* From the format code, compute the mode and make any adjustments as + needed. */ switch (lc_format_code) { case 'e': mode = 2; @@ -746,7 +756,6 @@ break; } -// printf("in PyOS_double_to_string %c %c\n", format_code, lc_format_code); if (!buf) return NULL; From python-checkins at python.org Fri Apr 3 04:43:55 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 3 Apr 2009 04:43:55 +0200 (CEST) Subject: [Python-checkins] r71078 - python/trunk/Lib/timeit.py Message-ID: <20090403024355.B7FE31E4016@bag.python.org> Author: raymond.hettinger Date: Fri Apr 3 04:43:54 2009 New Revision: 71078 Log: Localize the function lookup in timeit. Modified: python/trunk/Lib/timeit.py Modified: python/trunk/Lib/timeit.py ============================================================================== --- python/trunk/Lib/timeit.py (original) +++ python/trunk/Lib/timeit.py Fri Apr 3 04:43:54 2009 @@ -92,11 +92,11 @@ def _template_func(setup, func): """Create a timer function. Used if the "statement" is a callable.""" - def inner(_it, _timer): + def inner(_it, _timer, _func=func): setup() _t0 = _timer() for _i in _it: - func() + _func() _t1 = _timer() return _t1 - _t0 return inner From python-checkins at python.org Fri Apr 3 04:45:36 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 3 Apr 2009 04:45:36 +0200 (CEST) Subject: [Python-checkins] r71079 - python/branches/py3k/Lib/timeit.py Message-ID: <20090403024536.B8D3A1E40DD@bag.python.org> Author: raymond.hettinger Date: Fri Apr 3 04:45:36 2009 New Revision: 71079 Log: Localize the function lookup in timeit. Modified: python/branches/py3k/Lib/timeit.py Modified: python/branches/py3k/Lib/timeit.py ============================================================================== --- python/branches/py3k/Lib/timeit.py (original) +++ python/branches/py3k/Lib/timeit.py Fri Apr 3 04:45:36 2009 @@ -92,11 +92,11 @@ def _template_func(setup, func): """Create a timer function. Used if the "statement" is a callable.""" - def inner(_it, _timer): + def inner(_it, _timer, _func=func): setup() _t0 = _timer() for _i in _it: - func() + _func() _t1 = _timer() return _t1 - _t0 return inner From python-checkins at python.org Fri Apr 3 04:47:58 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 3 Apr 2009 04:47:58 +0200 (CEST) Subject: [Python-checkins] r71080 - python/branches/release26-maint/Lib/timeit.py Message-ID: <20090403024758.D7EB81E4016@bag.python.org> Author: raymond.hettinger Date: Fri Apr 3 04:47:57 2009 New Revision: 71080 Log: Localize the function lookup in timeit. Modified: python/branches/release26-maint/Lib/timeit.py Modified: python/branches/release26-maint/Lib/timeit.py ============================================================================== --- python/branches/release26-maint/Lib/timeit.py (original) +++ python/branches/release26-maint/Lib/timeit.py Fri Apr 3 04:47:57 2009 @@ -92,11 +92,11 @@ def _template_func(setup, func): """Create a timer function. Used if the "statement" is a callable.""" - def inner(_it, _timer): + def inner(_it, _timer, _func=func): setup() _t0 = _timer() for _i in _it: - func() + _func() _t1 = _timer() return _t1 - _t0 return inner From python-checkins at python.org Fri Apr 3 04:49:10 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 3 Apr 2009 04:49:10 +0200 (CEST) Subject: [Python-checkins] r71081 - python/branches/release30-maint/Lib/timeit.py Message-ID: <20090403024910.E60001E4016@bag.python.org> Author: raymond.hettinger Date: Fri Apr 3 04:49:10 2009 New Revision: 71081 Log: Localize the function lookup in timeit. Modified: python/branches/release30-maint/Lib/timeit.py Modified: python/branches/release30-maint/Lib/timeit.py ============================================================================== --- python/branches/release30-maint/Lib/timeit.py (original) +++ python/branches/release30-maint/Lib/timeit.py Fri Apr 3 04:49:10 2009 @@ -92,11 +92,11 @@ def _template_func(setup, func): """Create a timer function. Used if the "statement" is a callable.""" - def inner(_it, _timer): + def inner(_it, _timer, _func=func): setup() _t0 = _timer() for _i in _it: - func() + _func() _t1 = _timer() return _t1 - _t0 return inner From python-checkins at python.org Fri Apr 3 05:54:09 2009 From: python-checkins at python.org (hirokazu.yamamoto) Date: Fri, 3 Apr 2009 05:54:09 +0200 (CEST) Subject: [Python-checkins] r71082 - in python/trunk: PC/VC6/pythoncore.dsp PC/VS7.1/pythoncore.vcproj PC/VS8.0/pythoncore.vcproj PCbuild/pythoncore.vcproj Message-ID: <20090403035409.CBDD81E4016@bag.python.org> Author: hirokazu.yamamoto Date: Fri Apr 3 05:54:08 2009 New Revision: 71082 Log: Fixed compile error on windows. Modified: python/trunk/PC/VC6/pythoncore.dsp python/trunk/PC/VS7.1/pythoncore.vcproj python/trunk/PC/VS8.0/pythoncore.vcproj python/trunk/PCbuild/pythoncore.vcproj Modified: python/trunk/PC/VC6/pythoncore.dsp ============================================================================== --- python/trunk/PC/VC6/pythoncore.dsp (original) +++ python/trunk/PC/VC6/pythoncore.dsp Fri Apr 3 05:54:08 2009 @@ -519,6 +519,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Objects\memoryobject.c +# End Source File +# Begin Source File + SOURCE=..\..\Parser\metagrammar.c # End Source File # Begin Source File Modified: python/trunk/PC/VS7.1/pythoncore.vcproj ============================================================================== --- python/trunk/PC/VS7.1/pythoncore.vcproj (original) +++ python/trunk/PC/VS7.1/pythoncore.vcproj Fri Apr 3 05:54:08 2009 @@ -659,6 +659,9 @@ RelativePath="..\..\Modules\md5module.c"> + + + + Modified: python/trunk/PCbuild/pythoncore.vcproj ============================================================================== --- python/trunk/PCbuild/pythoncore.vcproj (original) +++ python/trunk/PCbuild/pythoncore.vcproj Fri Apr 3 05:54:08 2009 @@ -1459,6 +1459,10 @@ > + + From python-checkins at python.org Fri Apr 3 05:57:45 2009 From: python-checkins at python.org (hirokazu.yamamoto) Date: Fri, 3 Apr 2009 05:57:45 +0200 (CEST) Subject: [Python-checkins] r71083 - python/branches/release26-maint Message-ID: <20090403035745.EA6CD1E4016@bag.python.org> Author: hirokazu.yamamoto Date: Fri Apr 3 05:57:45 2009 New Revision: 71083 Log: Blocked revisions 71082 via svnmerge ........ r71082 | hirokazu.yamamoto | 2009-04-03 12:54:08 +0900 | 1 line Fixed compile error on windows. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Fri Apr 3 06:17:41 2009 From: python-checkins at python.org (alexandre.vassalotti) Date: Fri, 3 Apr 2009 06:17:41 +0200 (CEST) Subject: [Python-checkins] r71084 - python/branches/py3k/Modules/_pickle.c Message-ID: <20090403041741.865271E4016@bag.python.org> Author: alexandre.vassalotti Date: Fri Apr 3 06:17:41 2009 New Revision: 71084 Log: Update a comment about why the __module__ can sometime be NULL. Initialize last_string and arg member of Unpickler. Modified: python/branches/py3k/Modules/_pickle.c Modified: python/branches/py3k/Modules/_pickle.c ============================================================================== --- python/branches/py3k/Modules/_pickle.c (original) +++ python/branches/py3k/Modules/_pickle.c Fri Apr 3 06:17:41 2009 @@ -691,9 +691,9 @@ module_name = PyObject_GetAttr(global, module_str); - /* In some rare cases (e.g., random.getrandbits), __module__ can be - None. If it is so, then search sys.modules for the module of - global. */ + /* In some rare cases (e.g., bound methods of extension types), + __module__ can be None. If it is so, then search sys.modules + for the module of global. */ if (module_name == Py_None) { Py_DECREF(module_name); goto search; @@ -4447,6 +4447,9 @@ if (self->memo == NULL) return -1; + self->last_string = NULL; + self->arg = NULL; + return 0; } From python-checkins at python.org Fri Apr 3 07:41:11 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 3 Apr 2009 07:41:11 +0200 (CEST) Subject: [Python-checkins] r71085 - python/branches/release26-maint/Doc/library/random.rst Message-ID: <20090403054111.054E51E402C@bag.python.org> Author: raymond.hettinger Date: Fri Apr 3 07:41:10 2009 New Revision: 71085 Log: Fix typo. Modified: python/branches/release26-maint/Doc/library/random.rst Modified: python/branches/release26-maint/Doc/library/random.rst ============================================================================== --- python/branches/release26-maint/Doc/library/random.rst (original) +++ python/branches/release26-maint/Doc/library/random.rst Fri Apr 3 07:41:10 2009 @@ -326,6 +326,6 @@ pseudo-random number generator", Applied Statistics 31 (1982) 188-190. `Complementary-Multiply-with-Carry recipe - `_ for a compatable alternative - random number generator with a long-period and comparatively simple update + `_ for a compatible alternative + random number generator with a long period and comparatively simple update operations. From python-checkins at python.org Fri Apr 3 07:46:13 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 3 Apr 2009 07:46:13 +0200 (CEST) Subject: [Python-checkins] r71086 - python/branches/release30-maint/Doc/library/random.rst Message-ID: <20090403054613.8741A1E402C@bag.python.org> Author: raymond.hettinger Date: Fri Apr 3 07:46:13 2009 New Revision: 71086 Log: Fix typo. Modified: python/branches/release30-maint/Doc/library/random.rst Modified: python/branches/release30-maint/Doc/library/random.rst ============================================================================== --- python/branches/release30-maint/Doc/library/random.rst (original) +++ python/branches/release30-maint/Doc/library/random.rst Fri Apr 3 07:46:13 2009 @@ -254,6 +254,6 @@ `Complementary-Multiply-with-Carry recipe - `_ for a compatable alternative - random number generator with a long-period and comparatively simple update + `_ for a compatible alternative + random number generator with a long period and comparatively simple update operations. From python-checkins at python.org Fri Apr 3 07:47:33 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 3 Apr 2009 07:47:33 +0200 (CEST) Subject: [Python-checkins] r71087 - python/branches/py3k/Doc/library/random.rst Message-ID: <20090403054733.7D8D61E402A@bag.python.org> Author: raymond.hettinger Date: Fri Apr 3 07:47:33 2009 New Revision: 71087 Log: Fix typo. 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 Fri Apr 3 07:47:33 2009 @@ -254,6 +254,6 @@ `Complementary-Multiply-with-Carry recipe - `_ for a compatable alternative - random number generator with a long-period and comparatively simple update + `_ for a compatible alternative + random number generator with a long period and comparatively simple update operations. From buildbot at python.org Fri Apr 3 07:53:28 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 03 Apr 2009 05:53:28 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090403055329.21D681E402A@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/245 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: raymond.hettinger BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_distutils test_posix ====================================================================== FAIL: test_get_python_inc (distutils.tests.test_sysconfig.SysconfigTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/distutils/tests/test_sysconfig.py", line 45, in test_get_python_inc self.assert_(os.path.isdir(inc_dir), inc_dir) AssertionError: /home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/Include ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Fri Apr 3 08:07:30 2009 From: python-checkins at python.org (alexandre.vassalotti) Date: Fri, 3 Apr 2009 08:07:30 +0200 (CEST) Subject: [Python-checkins] r71088 - python/branches/py3k/Doc/library/pickletools.rst Message-ID: <20090403060730.D06BC1E402A@bag.python.org> Author: alexandre.vassalotti Date: Fri Apr 3 08:07:29 2009 New Revision: 71088 Log: Remove old reference to cPickle. Modified: python/branches/py3k/Doc/library/pickletools.rst Modified: python/branches/py3k/Doc/library/pickletools.rst ============================================================================== --- python/branches/py3k/Doc/library/pickletools.rst (original) +++ python/branches/py3k/Doc/library/pickletools.rst Fri Apr 3 08:07:29 2009 @@ -3,16 +3,14 @@ =================================================== .. module:: pickletools - :synopsis: Contains extensive comments about the pickle protocols and pickle-machine - opcodes, as well as some useful functions. - + :synopsis: Contains extensive comments about the pickle protocols and pickle-machine opcodes, as well as some useful functions. This module contains various constants relating to the intimate details of the -:mod:`pickle` module, some lengthy comments about the implementation, and a few -useful functions for analyzing pickled data. The contents of this module are -useful for Python core developers who are working on the :mod:`pickle` and -:mod:`cPickle` implementations; ordinary users of the :mod:`pickle` module -probably won't find the :mod:`pickletools` module relevant. +:mod:`pickle` module, some lengthy comments about the implementation, and a +few useful functions for analyzing pickled data. The contents of this module +are useful for Python core developers who are working on the :mod:`pickle`; +ordinary users of the :mod:`pickle` module probably won't find the +:mod:`pickletools` module relevant. .. function:: dis(pickle[, out=None, memo=None, indentlevel=4]) @@ -24,7 +22,6 @@ pickler. Successive levels, indicated by ``MARK`` opcodes in the stream, are indented by *indentlevel* spaces. - .. function:: genops(pickle) Provides an :term:`iterator` over all of the opcodes in a pickle, returning a From python-checkins at python.org Fri Apr 3 08:13:30 2009 From: python-checkins at python.org (alexandre.vassalotti) Date: Fri, 3 Apr 2009 08:13:30 +0200 (CEST) Subject: [Python-checkins] r71089 - python/branches/py3k/Doc/library/pickle.rst Message-ID: <20090403061330.8001A1E402C@bag.python.org> Author: alexandre.vassalotti Date: Fri Apr 3 08:13:29 2009 New Revision: 71089 Log: Add more examples in pickle documentation. Modified: python/branches/py3k/Doc/library/pickle.rst Modified: python/branches/py3k/Doc/library/pickle.rst ============================================================================== --- python/branches/py3k/Doc/library/pickle.rst (original) +++ python/branches/py3k/Doc/library/pickle.rst Fri Apr 3 08:13:29 2009 @@ -14,6 +14,7 @@ .. sectionauthor:: Jim Kerr . .. sectionauthor:: Barry Warsaw + The :mod:`pickle` module implements a fundamental, but powerful algorithm for serializing and de-serializing a Python object structure. "Pickling" is the process whereby a Python object hierarchy is converted into a byte stream, and @@ -282,23 +283,9 @@ .. attribute:: memo - Dictionary holding previously pickled objects to allow shared or - recursive objects to pickled by reference as opposed to by value. - - -.. XXX Move these comments to somewhere more appropriate. - -It is possible to make multiple calls to the :meth:`dump` method of the same -:class:`Pickler` instance. These must then be matched to the same number of -calls to the :meth:`load` method of the corresponding :class:`Unpickler` -instance. If the same object is pickled by multiple :meth:`dump` calls, the -:meth:`load` will all yield references to the same object. - -Please note, this is intended for pickling multiple objects without intervening -modifications to the objects or their parts. If you modify an object and then -pickle it again using the same :class:`Pickler` instance, the object is not -pickled again --- a reference to it is pickled and the :class:`Unpickler` will -return the old value, not the modified one. + Dictionary-like object holding previously pickled objects to allow + shared or recursive objects to pickled by reference as opposed to + by value. .. class:: Unpickler(file, [\*, encoding="ASCII", errors="strict"]) @@ -345,6 +332,11 @@ how they can be loaded, potentially reducing security risks. Refer to :ref:`pickle-restrict` for details. + .. attribute:: memo + + Dictionary holding previously unpickled objects to allow shared or + recursive objects to unpickled by reference as opposed to by value. + .. _pickle-picklable: @@ -593,7 +585,7 @@ line = self.file.readline() if not line: return None - if line.endswith("\n"): + if line.endswith('\n'): line = line[:-1] return "%i: %s" % (self.lineno, line) @@ -707,25 +699,24 @@ As our examples shows, you have to be careful with what you allow to be unpickled. Therefore if security is a concern, you may want to consider -alternatives such as the marshalling API in :mod:`xmlrpc.client` or third-party -solutions. +alternatives such as the marshalling API in :mod:`xmlrpc.client` or +third-party solutions. .. _pickle-example: -Usage Examples --------------- +Examples +-------- -For the simplest code, use the :func:`dump` and :func:`load` functions. Note -that a self-referencing list is pickled and restored correctly. :: +For the simplest code, use the :func:`dump` and :func:`load` functions. :: import pickle # An arbitrary collection of objects supported by pickle. data = { - 'a': [1, 2.0, 3, 4+6j], - 'b': ("character string", b"byte string"), - 'c': set([None, True, False]) + 'a': [1, 2.0, 3, 4+6j], + 'b': ("character string", b"byte string"), + 'c': set([None, True, False]) } with open('data.pickle', 'wb') as f: @@ -743,11 +734,72 @@ data = pickle.load(f) +Reusing Pickler Instances +^^^^^^^^^^^^^^^^^^^^^^^^^ + +It is possible to make multiple calls to the :meth:`dump` method of the same +:class:`Pickler` instance. These must then be matched to the same number of +calls to the :meth:`load` method of the corresponding :class:`Unpickler` +instance. If the same object is pickled by multiple :meth:`dump` calls, the +:meth:`load` will all yield references to the same object. + +Please note, this is intended for pickling multiple objects without intervening +modifications to the objects or their parts. If you modify an object and then +pickle it again using the same :class:`Pickler` instance, the object is not +pickled again --- a reference to it is pickled and the :class:`Unpickler` will +return the old value, not the modified one. :: + + import io + import pickle + + data = {"hello": 0, "spam": 1} + + # Create a binary file-like object to which the Pickler instance will + # write the pickles. + f = io.BytesIO() + p = pickle.Pickler(f) + p.dump(data) + + # This second call appends a new pickle to the file. The modification we + # make is lost because objects are pickled by reference when seen again. + data["eggs"] = 2 + p.dump(data) + + # Now, we load the pickles saved in our file-like object. + f.seek(0) + u = pickle.Unpickler(f) + data1 = u.load() + data2 = u.load() + + if data1 is data2: + print("data1 and data2 are the same object") + else: + print("data1 and data2 are not the same object") + + if "eggs" in data2: + print("The modification was pickled.") + else: + print("The modification was not pickled.") + +Reusing a :class:`Pickler` instance like we shown can be a useful +optimization. For example, a multi-process application could use this feature +to reduce the size of the pickles transmitted across processes over time +(assuming the pickles exchanged are containers sharing common immutable +objects). However, you should take special care to regularly clear +:attr:``Pickler.memo`` and :attr:``Unpickler.memo`` to avoid memory-leaks. + +.. XXX: Add examples showing how to optimize pickles for size (like using +.. pickletools.optimize() or the gzip module). + + .. seealso:: Module :mod:`copyreg` Pickle interface constructor registration for extension types. + Module :mod:`pickletools` + Tools for working with and analyzing pickled data. + Module :mod:`shelve` Indexed databases of objects; uses :mod:`pickle`. From python-checkins at python.org Fri Apr 3 08:19:28 2009 From: python-checkins at python.org (alexandre.vassalotti) Date: Fri, 3 Apr 2009 08:19:28 +0200 (CEST) Subject: [Python-checkins] r71090 - python/branches/py3k/Doc/library/pickle.rst Message-ID: <20090403061928.2D3071E402C@bag.python.org> Author: alexandre.vassalotti Date: Fri Apr 3 08:19:27 2009 New Revision: 71090 Log: Emphasize that Unpickler.memo is not necessarily a dict. Modified: python/branches/py3k/Doc/library/pickle.rst Modified: python/branches/py3k/Doc/library/pickle.rst ============================================================================== --- python/branches/py3k/Doc/library/pickle.rst (original) +++ python/branches/py3k/Doc/library/pickle.rst Fri Apr 3 08:19:27 2009 @@ -334,8 +334,9 @@ .. attribute:: memo - Dictionary holding previously unpickled objects to allow shared or - recursive objects to unpickled by reference as opposed to by value. + Dictionary-like object holding previously unpickled objects to allow + shared or recursive objects to unpickled by reference as opposed to + by value. .. _pickle-picklable: From python-checkins at python.org Fri Apr 3 08:38:02 2009 From: python-checkins at python.org (alexandre.vassalotti) Date: Fri, 3 Apr 2009 08:38:02 +0200 (CEST) Subject: [Python-checkins] r71091 - in python/branches/py3k/Objects: bytearrayobject.c bytesobject.c Message-ID: <20090403063802.B65981E402A@bag.python.org> Author: alexandre.vassalotti Date: Fri Apr 3 08:38:02 2009 New Revision: 71091 Log: Optimize slicing of bytes and bytearray by avoiding useless copying. This restores the behavior that was present in Python 2.x. Modified: python/branches/py3k/Objects/bytearrayobject.c python/branches/py3k/Objects/bytesobject.c Modified: python/branches/py3k/Objects/bytearrayobject.c ============================================================================== --- python/branches/py3k/Objects/bytearrayobject.c (original) +++ python/branches/py3k/Objects/bytearrayobject.c Fri Apr 3 08:38:02 2009 @@ -411,18 +411,18 @@ } else { char *source_buf = PyByteArray_AS_STRING(self); - char *result_buf = (char *)PyMem_Malloc(slicelength); + char *result_buf; PyObject *result; - if (result_buf == NULL) - return PyErr_NoMemory(); + result = PyByteArray_FromStringAndSize(NULL, slicelength); + if (result == NULL) + return NULL; + result_buf = PyByteArray_AS_STRING(result); for (cur = start, i = 0; i < slicelength; cur += step, i++) { result_buf[i] = source_buf[cur]; } - result = PyByteArray_FromStringAndSize(result_buf, slicelength); - PyMem_Free(result_buf); return result; } } Modified: python/branches/py3k/Objects/bytesobject.c ============================================================================== --- python/branches/py3k/Objects/bytesobject.c (original) +++ python/branches/py3k/Objects/bytesobject.c Fri Apr 3 08:38:02 2009 @@ -951,19 +951,17 @@ slicelength); } else { - source_buf = PyBytes_AsString((PyObject*)self); - result_buf = (char *)PyMem_Malloc(slicelength); - if (result_buf == NULL) - return PyErr_NoMemory(); + source_buf = PyBytes_AS_STRING(self); + result = PyBytes_FromStringAndSize(NULL, slicelength); + if (result == NULL) + return NULL; + result_buf = PyBytes_AS_STRING(result); for (cur = start, i = 0; i < slicelength; cur += step, i++) { result_buf[i] = source_buf[cur]; } - result = PyBytes_FromStringAndSize(result_buf, - slicelength); - PyMem_Free(result_buf); return result; } } From python-checkins at python.org Fri Apr 3 08:58:21 2009 From: python-checkins at python.org (alexandre.vassalotti) Date: Fri, 3 Apr 2009 08:58:21 +0200 (CEST) Subject: [Python-checkins] r71092 - python/branches/py3k/Doc/library/pickle.rst Message-ID: <20090403065821.3A27A1E402A@bag.python.org> Author: alexandre.vassalotti Date: Fri Apr 3 08:58:20 2009 New Revision: 71092 Log: Undocument the existence of the memo attribute and its main use-case. Apparently, Guido don't like this behavior. [1] I also agree that the memo should be left as an implementation detail. [1]: http://mail.python.org/pipermail/python-dev/2009-March/086809.html Modified: python/branches/py3k/Doc/library/pickle.rst Modified: python/branches/py3k/Doc/library/pickle.rst ============================================================================== --- python/branches/py3k/Doc/library/pickle.rst (original) +++ python/branches/py3k/Doc/library/pickle.rst Fri Apr 3 08:58:20 2009 @@ -266,11 +266,6 @@ See :ref:`pickle-persistent` for details and examples of uses. - .. method:: clear_memo() - - Deprecated. Use the :meth:`clear` method on :attr:`memo`, instead. - Clear the pickler's memo, useful when reusing picklers. - .. attribute:: fast Deprecated. Enable fast mode if set to a true value. The fast mode @@ -281,12 +276,6 @@ Use :func:`pickletools.optimize` if you need more compact pickles. - .. attribute:: memo - - Dictionary-like object holding previously pickled objects to allow - shared or recursive objects to pickled by reference as opposed to - by value. - .. class:: Unpickler(file, [\*, encoding="ASCII", errors="strict"]) @@ -332,12 +321,6 @@ how they can be loaded, potentially reducing security risks. Refer to :ref:`pickle-restrict` for details. - .. attribute:: memo - - Dictionary-like object holding previously unpickled objects to allow - shared or recursive objects to unpickled by reference as opposed to - by value. - .. _pickle-picklable: @@ -735,60 +718,6 @@ data = pickle.load(f) -Reusing Pickler Instances -^^^^^^^^^^^^^^^^^^^^^^^^^ - -It is possible to make multiple calls to the :meth:`dump` method of the same -:class:`Pickler` instance. These must then be matched to the same number of -calls to the :meth:`load` method of the corresponding :class:`Unpickler` -instance. If the same object is pickled by multiple :meth:`dump` calls, the -:meth:`load` will all yield references to the same object. - -Please note, this is intended for pickling multiple objects without intervening -modifications to the objects or their parts. If you modify an object and then -pickle it again using the same :class:`Pickler` instance, the object is not -pickled again --- a reference to it is pickled and the :class:`Unpickler` will -return the old value, not the modified one. :: - - import io - import pickle - - data = {"hello": 0, "spam": 1} - - # Create a binary file-like object to which the Pickler instance will - # write the pickles. - f = io.BytesIO() - p = pickle.Pickler(f) - p.dump(data) - - # This second call appends a new pickle to the file. The modification we - # make is lost because objects are pickled by reference when seen again. - data["eggs"] = 2 - p.dump(data) - - # Now, we load the pickles saved in our file-like object. - f.seek(0) - u = pickle.Unpickler(f) - data1 = u.load() - data2 = u.load() - - if data1 is data2: - print("data1 and data2 are the same object") - else: - print("data1 and data2 are not the same object") - - if "eggs" in data2: - print("The modification was pickled.") - else: - print("The modification was not pickled.") - -Reusing a :class:`Pickler` instance like we shown can be a useful -optimization. For example, a multi-process application could use this feature -to reduce the size of the pickles transmitted across processes over time -(assuming the pickles exchanged are containers sharing common immutable -objects). However, you should take special care to regularly clear -:attr:``Pickler.memo`` and :attr:``Unpickler.memo`` to avoid memory-leaks. - .. XXX: Add examples showing how to optimize pickles for size (like using .. pickletools.optimize() or the gzip module). From python-checkins at python.org Fri Apr 3 09:16:56 2009 From: python-checkins at python.org (alexandre.vassalotti) Date: Fri, 3 Apr 2009 09:16:56 +0200 (CEST) Subject: [Python-checkins] r71093 - python/branches/py3k/Lib/http/server.py Message-ID: <20090403071656.16D4F1E4032@bag.python.org> Author: alexandre.vassalotti Date: Fri Apr 3 09:16:55 2009 New Revision: 71093 Log: Make http.server main program nicer for interactive use. Remove unreachable calls to test(). This restores the behavior of SimpleHTTPServer, where a user could type "python -m SimpleHTTPServer" and get a simple server for sharing files. Now, you can do the same thing with "python3 -m http.server". Modified: python/branches/py3k/Lib/http/server.py Modified: python/branches/py3k/Lib/http/server.py ============================================================================== --- python/branches/py3k/Lib/http/server.py (original) +++ python/branches/py3k/Lib/http/server.py Fri Apr 3 09:16:55 2009 @@ -1082,10 +1082,12 @@ sa = httpd.socket.getsockname() print("Serving HTTP on", sa[0], "port", sa[1], "...") - httpd.serve_forever() - + try: + httpd.serve_forever() + except KeyboardInterrupt: + print("\nKeyboard interrupt received, exiting.") + httpd.server_close() + sys.exit(0) if __name__ == '__main__': - test(HandlerClass=BaseHTTPRequestHandler) test(HandlerClass=SimpleHTTPRequestHandler) - test(HandlerClass=CGIHTTPRequestHandler) From python-checkins at python.org Fri Apr 3 12:23:18 2009 From: python-checkins at python.org (vinay.sajip) Date: Fri, 3 Apr 2009 12:23:18 +0200 (CEST) Subject: [Python-checkins] r71094 - python/trunk/Doc/library/logging.rst Message-ID: <20090403102318.43D3D1E418D@bag.python.org> Author: vinay.sajip Date: Fri Apr 3 12:23:18 2009 New Revision: 71094 Log: Added warning about logging use from asynchronous signal handlers. Modified: python/trunk/Doc/library/logging.rst Modified: python/trunk/Doc/library/logging.rst ============================================================================== --- python/trunk/Doc/library/logging.rst (original) +++ python/trunk/Doc/library/logging.rst Fri Apr 3 12:23:18 2009 @@ -2351,6 +2351,9 @@ locks; there is one lock to serialize access to the module's shared data, and each handler also creates a lock to serialize access to its underlying I/O. +Note that in Linux/Unix environments, threading APIs may not be usable in +asynchronous signal handlers. This may mean that you cannot use logging from +within asynchronous signal handlers; please check your OS documentation. Configuration ------------- From python-checkins at python.org Fri Apr 3 13:19:31 2009 From: python-checkins at python.org (eric.smith) Date: Fri, 3 Apr 2009 13:19:31 +0200 (CEST) Subject: [Python-checkins] r71095 - python/branches/py3k/Objects/stringlib/formatter.h Message-ID: <20090403111931.E96AB1E4032@bag.python.org> Author: eric.smith Date: Fri Apr 3 13:19:31 2009 New Revision: 71095 Log: Removed mixed tabs and whitespace. Modified: python/branches/py3k/Objects/stringlib/formatter.h Modified: python/branches/py3k/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k/Objects/stringlib/formatter.h (original) +++ python/branches/py3k/Objects/stringlib/formatter.h Fri Apr 3 13:19:31 2009 @@ -132,7 +132,7 @@ */ static int parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec, - Py_ssize_t format_spec_len, + Py_ssize_t format_spec_len, InternalFormatSpec *format, char default_type) { @@ -178,8 +178,8 @@ /* If the next character is #, we're in alternate mode. This only applies to integers. */ if (end-ptr >= 1 && ptr[0] == '#') { - format->alternate = 1; - ++ptr; + format->alternate = 1; + ++ptr; } /* The special case for 0-padding (backwards compat) */ @@ -259,8 +259,8 @@ and more efficient enough to justify a little obfuscation? */ static void calc_number_widths(NumberFieldWidths *spec, STRINGLIB_CHAR actual_sign, - Py_ssize_t n_prefix, Py_ssize_t n_digits, - const InternalFormatSpec *format) + Py_ssize_t n_prefix, Py_ssize_t n_digits, + const InternalFormatSpec *format) { spec->n_lpadding = 0; spec->n_prefix = 0; @@ -327,7 +327,7 @@ else { /* see if any padding is needed */ if (spec->n_lsign + n_digits + spec->n_rsign + - spec->n_prefix >= format->width) { + spec->n_prefix >= format->width) { /* no padding needed, we're already bigger than the requested width */ } @@ -335,8 +335,8 @@ /* determine which of left, space, or right padding is needed */ Py_ssize_t padding = format->width - - (spec->n_lsign + spec->n_prefix + - n_digits + spec->n_rsign); + (spec->n_lsign + spec->n_prefix + + n_digits + spec->n_rsign); if (format->align == '<') spec->n_rpadding = padding; else if (format->align == '>') @@ -352,7 +352,7 @@ } } spec->n_total = spec->n_lpadding + spec->n_lsign + spec->n_prefix + - spec->n_spadding + n_digits + spec->n_rsign + spec->n_rpadding; + spec->n_spadding + n_digits + spec->n_rsign + spec->n_rpadding; } /* fill in the non-digit parts of a numbers's string representation, @@ -360,8 +360,8 @@ where the digits go. */ static STRINGLIB_CHAR * fill_non_digits(STRINGLIB_CHAR *p_buf, const NumberFieldWidths *spec, - STRINGLIB_CHAR *prefix, Py_ssize_t n_digits, - STRINGLIB_CHAR fill_char) + STRINGLIB_CHAR *prefix, Py_ssize_t n_digits, + STRINGLIB_CHAR fill_char) { STRINGLIB_CHAR *p_digits; @@ -373,10 +373,10 @@ *p_buf++ = spec->lsign; } if (spec->n_prefix) { - memmove(p_buf, - prefix, - spec->n_prefix * sizeof(STRINGLIB_CHAR)); - p_buf += spec->n_prefix; + memmove(p_buf, + prefix, + spec->n_prefix * sizeof(STRINGLIB_CHAR)); + p_buf += spec->n_prefix; } if (spec->n_spadding) { STRINGLIB_FILL(p_buf, fill_char, spec->n_spadding); @@ -420,7 +420,7 @@ if (format->alternate) { PyErr_SetString(PyExc_ValueError, "Alternate form (#) not allowed in string format " - "specifier"); + "specifier"); goto done; } @@ -504,7 +504,7 @@ static PyObject * format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format, - IntOrLongToString tostring) + IntOrLongToString tostring) { PyObject *result = NULL; PyObject *tmp = NULL; @@ -516,8 +516,8 @@ string */ Py_ssize_t n_leading_chars; Py_ssize_t n_grouping_chars = 0; /* Count of additional chars to - allocate, used for 'n' - formatting. */ + allocate, used for 'n' + formatting. */ Py_ssize_t n_prefix = 0; /* Count of prefix chars, (e.g., '0x') */ STRINGLIB_CHAR *prefix = NULL; NumberFieldWidths spec; @@ -562,31 +562,31 @@ goto done; } #endif - numeric_char = (STRINGLIB_CHAR)x; - pnumeric_chars = &numeric_char; + numeric_char = (STRINGLIB_CHAR)x; + pnumeric_chars = &numeric_char; n_digits = 1; } else { int base; - int leading_chars_to_skip = 0; /* Number of characters added by - PyNumber_ToBase that we want to - skip over. */ + int leading_chars_to_skip = 0; /* Number of characters added by + PyNumber_ToBase that we want to + skip over. */ /* Compute the base and how many characters will be added by PyNumber_ToBase */ switch (format->type) { case 'b': base = 2; - leading_chars_to_skip = 2; /* 0b */ + leading_chars_to_skip = 2; /* 0b */ break; case 'o': base = 8; - leading_chars_to_skip = 2; /* 0o */ + leading_chars_to_skip = 2; /* 0o */ break; case 'x': case 'X': base = 16; - leading_chars_to_skip = 2; /* 0x */ + leading_chars_to_skip = 2; /* 0x */ break; default: /* shouldn't be needed, but stops a compiler warning */ case 'd': @@ -595,52 +595,52 @@ break; } - /* The number of prefix chars is the same as the leading - chars to skip */ - if (format->alternate) - n_prefix = leading_chars_to_skip; + /* The number of prefix chars is the same as the leading + chars to skip */ + if (format->alternate) + n_prefix = leading_chars_to_skip; /* Do the hard part, converting to a string in a given base */ - tmp = tostring(value, base); + tmp = tostring(value, base); if (tmp == NULL) goto done; - pnumeric_chars = STRINGLIB_STR(tmp); + pnumeric_chars = STRINGLIB_STR(tmp); n_digits = STRINGLIB_LEN(tmp); - prefix = pnumeric_chars; + prefix = pnumeric_chars; - /* Remember not to modify what pnumeric_chars points to. it - might be interned. Only modify it after we copy it into a - newly allocated output buffer. */ + /* Remember not to modify what pnumeric_chars points to. it + might be interned. Only modify it after we copy it into a + newly allocated output buffer. */ /* Is a sign character present in the output? If so, remember it and skip it */ sign = pnumeric_chars[0]; if (sign == '-') { - ++prefix; - ++leading_chars_to_skip; + ++prefix; + ++leading_chars_to_skip; } - /* Skip over the leading chars (0x, 0b, etc.) */ - n_digits -= leading_chars_to_skip; - pnumeric_chars += leading_chars_to_skip; + /* Skip over the leading chars (0x, 0b, etc.) */ + n_digits -= leading_chars_to_skip; + pnumeric_chars += leading_chars_to_skip; } if (format->type == 'n') - /* Compute how many additional chars we need to allocate - to hold the thousands grouping. */ - STRINGLIB_GROUPING(NULL, n_digits, n_digits, - 0, &n_grouping_chars, 0); + /* Compute how many additional chars we need to allocate + to hold the thousands grouping. */ + STRINGLIB_GROUPING(NULL, n_digits, n_digits, + 0, &n_grouping_chars, 0); /* Calculate the widths of the various leading and trailing parts */ calc_number_widths(&spec, sign, n_prefix, n_digits + n_grouping_chars, - format); + format); /* Allocate a new string to hold the result */ result = STRINGLIB_NEW(NULL, spec.n_total); if (!result) - goto done; + goto done; p = STRINGLIB_STR(result); /* XXX There is too much magic here regarding the internals of @@ -651,44 +651,44 @@ /* Fill in the digit parts */ n_leading_chars = spec.n_lpadding + spec.n_lsign + - spec.n_prefix + spec.n_spadding; + spec.n_prefix + spec.n_spadding; memmove(p + n_leading_chars, - pnumeric_chars, - n_digits * sizeof(STRINGLIB_CHAR)); + pnumeric_chars, + n_digits * sizeof(STRINGLIB_CHAR)); /* If type is 'X', convert the filled in digits to uppercase */ if (format->type == 'X') { - Py_ssize_t t; - for (t = 0; t < n_digits; ++t) - p[t + n_leading_chars] = STRINGLIB_TOUPPER(p[t + n_leading_chars]); + Py_ssize_t t; + for (t = 0; t < n_digits; ++t) + p[t + n_leading_chars] = STRINGLIB_TOUPPER(p[t + n_leading_chars]); } /* Insert the grouping, if any, after the uppercasing of the digits, so we can ensure that grouping chars won't be affected. */ if (n_grouping_chars) { - /* We know this can't fail, since we've already - reserved enough space. */ - STRINGLIB_CHAR *pstart = p + n_leading_chars; + /* We know this can't fail, since we've already + reserved enough space. */ + STRINGLIB_CHAR *pstart = p + n_leading_chars; #ifndef NDEBUG - int r = + int r = #endif - STRINGLIB_GROUPING(pstart, n_digits, n_digits, - spec.n_total+n_grouping_chars-n_leading_chars, - NULL, 0); - assert(r); + STRINGLIB_GROUPING(pstart, n_digits, n_digits, + spec.n_total+n_grouping_chars-n_leading_chars, + NULL, 0); + assert(r); } /* Fill in the non-digit parts (padding, sign, etc.) */ fill_non_digits(p, &spec, prefix, n_digits + n_grouping_chars, - format->fill_char == '\0' ? ' ' : format->fill_char); + format->fill_char == '\0' ? ' ' : format->fill_char); /* If type is 'X', uppercase the prefix. This has to be done after the prefix is filled in by fill_non_digits */ if (format->type == 'X') { - Py_ssize_t t; - for (t = 0; t < n_prefix; ++t) - p[t + spec.n_lpadding + spec.n_lsign] = - STRINGLIB_TOUPPER(p[t + spec.n_lpadding + spec.n_lsign]); + Py_ssize_t t; + for (t = 0; t < n_prefix; ++t) + p[t + spec.n_lpadding + spec.n_lsign] = + STRINGLIB_TOUPPER(p[t + spec.n_lpadding + spec.n_lsign]); } @@ -723,7 +723,7 @@ /* much of this is taken from unicodeobject.c */ static PyObject * format_float_internal(PyObject *value, - const InternalFormatSpec *format) + const InternalFormatSpec *format) { /* fmt = '%.' + `prec` + `type` + '%%' worst case length = 2 + 10 (len of INT_MAX) + 1 + 2 = 15 (use 20)*/ @@ -765,7 +765,7 @@ if (format->alternate) { PyErr_SetString(PyExc_ValueError, "Alternate form (#) not allowed in float format " - "specifier"); + "specifier"); goto done; } @@ -796,7 +796,7 @@ 8-bit char. this is safe, because we've restricted what "type" can be */ PyOS_snprintf(fmt, sizeof(fmt), "%%.%" PY_FORMAT_SIZE_T "d%c", precision, - (char)type); + (char)type); /* do the actual formatting */ PyOS_ascii_formatd(charbuf, sizeof(charbuf), fmt, x); @@ -838,11 +838,11 @@ /* Fill in the non-digit parts (padding, sign, etc.) */ fill_non_digits(STRINGLIB_STR(result), &spec, NULL, n_digits, - format->fill_char == '\0' ? ' ' : format->fill_char); + format->fill_char == '\0' ? ' ' : format->fill_char); /* fill in the digit parts */ memmove(STRINGLIB_STR(result) + - (spec.n_lpadding + spec.n_lsign + spec.n_spadding), + (spec.n_lpadding + spec.n_lsign + spec.n_spadding), p, n_digits * sizeof(STRINGLIB_CHAR)); @@ -856,8 +856,8 @@ /************************************************************************/ PyObject * FORMAT_STRING(PyObject *obj, - STRINGLIB_CHAR *format_spec, - Py_ssize_t format_spec_len) + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len) { InternalFormatSpec format; PyObject *result = NULL; @@ -871,7 +871,7 @@ /* parse the format_spec */ if (!parse_internal_render_format_spec(format_spec, format_spec_len, - &format, 's')) + &format, 's')) goto done; /* type conversion? */ @@ -893,9 +893,9 @@ #if defined FORMAT_LONG || defined FORMAT_INT static PyObject* format_int_or_long(PyObject* obj, - STRINGLIB_CHAR *format_spec, - Py_ssize_t format_spec_len, - IntOrLongToString tostring) + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len, + IntOrLongToString tostring) { PyObject *result = NULL; PyObject *tmp = NULL; @@ -910,8 +910,8 @@ /* parse the format_spec */ if (!parse_internal_render_format_spec(format_spec, - format_spec_len, - &format, 'd')) + format_spec_len, + &format, 'd')) goto done; /* type conversion? */ @@ -924,8 +924,8 @@ case 'X': case 'n': /* no type conversion needed, already an int (or long). do - the formatting */ - result = format_int_or_long_internal(obj, &format, tostring); + the formatting */ + result = format_int_or_long_internal(obj, &format, tostring); break; case 'e': @@ -974,11 +974,11 @@ PyObject * FORMAT_LONG(PyObject *obj, - STRINGLIB_CHAR *format_spec, - Py_ssize_t format_spec_len) + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len) { return format_int_or_long(obj, format_spec, format_spec_len, - long_format); + long_format); } #endif /* FORMAT_LONG */ @@ -995,19 +995,19 @@ PyObject * FORMAT_INT(PyObject *obj, - STRINGLIB_CHAR *format_spec, - Py_ssize_t format_spec_len) + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len) { return format_int_or_long(obj, format_spec, format_spec_len, - int_format); + int_format); } #endif /* FORMAT_INT */ #ifdef FORMAT_FLOAT PyObject * FORMAT_FLOAT(PyObject *obj, - STRINGLIB_CHAR *format_spec, - Py_ssize_t format_spec_len) + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len) { PyObject *result = NULL; InternalFormatSpec format; @@ -1021,17 +1021,17 @@ /* parse the format_spec */ if (!parse_internal_render_format_spec(format_spec, - format_spec_len, - &format, '\0')) + format_spec_len, + &format, '\0')) goto done; /* type conversion? */ switch (format.type) { case '\0': - /* 'Z' means like 'g', but with at least one decimal. See - PyOS_ascii_formatd */ - format.type = 'Z'; - /* Deliberate fall through to the next case statement */ + /* 'Z' means like 'g', but with at least one decimal. See + PyOS_ascii_formatd */ + format.type = 'Z'; + /* Deliberate fall through to the next case statement */ case 'e': case 'E': case 'f': From amauryfa at gmail.com Fri Apr 3 13:25:42 2009 From: amauryfa at gmail.com (Amaury Forgeot d'Arc) Date: Fri, 3 Apr 2009 13:25:42 +0200 Subject: [Python-checkins] r71094 - python/trunk/Doc/library/logging.rst Message-ID: Hello, > Log: > Added warning about logging use from asynchronous signal handlers. ... > +Note that in Linux/Unix environments, threading APIs may not be usable in > +asynchronous signal handlers. This may mean that you cannot use logging from > +within asynchronous signal handlers; please check your OS documentation. I am not a Unix expert, but I remember that no python code runs in a signal handler. The signal_handler() function calls Py_AddPendingCall(), which will call the python function when the interpreter loop (in ceval.c) resumes. Python code is never asynchronous. Or does this sentence has another meaning? -- Amaury Forgeot d'Arc From python-checkins at python.org Fri Apr 3 16:45:08 2009 From: python-checkins at python.org (eric.smith) Date: Fri, 3 Apr 2009 16:45:08 +0200 (CEST) Subject: [Python-checkins] r71096 - in python/branches/py3k: Include/bytesobject.h Include/unicodeobject.h Lib/test/test_types.py Objects/bytesobject.c Objects/stringlib/formatter.h Objects/stringlib/localeutil.h Objects/stringlib/stringdefs.h Objects/stringlib/unicodedefs.h Objects/unicodeobject.c Python/pystrtod.c Message-ID: <20090403144508.ADAC71E400C@bag.python.org> Author: eric.smith Date: Fri Apr 3 16:45:06 2009 New Revision: 71096 Log: Added ',' thousands grouping to int.__format__. See PEP 378. This is incomplete, but I want to get some version into the next alpha. I am still working on: Documentation. More tests. Implement for floats. In addition, there's an existing bug with 'n' formatting that carries forward to thousands grouping (issue 5515). Modified: python/branches/py3k/Include/bytesobject.h python/branches/py3k/Include/unicodeobject.h python/branches/py3k/Lib/test/test_types.py python/branches/py3k/Objects/bytesobject.c python/branches/py3k/Objects/stringlib/formatter.h python/branches/py3k/Objects/stringlib/localeutil.h python/branches/py3k/Objects/stringlib/stringdefs.h python/branches/py3k/Objects/stringlib/unicodedefs.h python/branches/py3k/Objects/unicodeobject.c python/branches/py3k/Python/pystrtod.c Modified: python/branches/py3k/Include/bytesobject.h ============================================================================== --- python/branches/py3k/Include/bytesobject.h (original) +++ python/branches/py3k/Include/bytesobject.h Fri Apr 3 16:45:06 2009 @@ -91,13 +91,25 @@ into the string pointed to by buffer. For the argument descriptions, see Objects/stringlib/localeutil.h */ -PyAPI_FUNC(int) _PyBytes_InsertThousandsGrouping(char *buffer, +PyAPI_FUNC(int) _PyBytes_InsertThousandsGroupingLocale(char *buffer, Py_ssize_t n_buffer, Py_ssize_t n_digits, Py_ssize_t buf_size, Py_ssize_t *count, int append_zero_char); +/* 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 */ +PyAPI_FUNC(int) _PyBytes_InsertThousandsGrouping(char *buffer, + Py_ssize_t n_buffer, + Py_ssize_t n_digits, + Py_ssize_t buf_size, + Py_ssize_t *count, + int append_zero_char, + const char *grouping, + const char *thousands_sep); + /* Flags used by string formatting */ #define F_LJUST (1<<0) #define F_SIGN (1<<1) Modified: python/branches/py3k/Include/unicodeobject.h ============================================================================== --- python/branches/py3k/Include/unicodeobject.h (original) +++ python/branches/py3k/Include/unicodeobject.h Fri Apr 3 16:45:06 2009 @@ -1482,13 +1482,24 @@ into the string pointed to by buffer. For the argument descriptions, see Objects/stringlib/localeutil.h */ -PyAPI_FUNC(int) _PyUnicode_InsertThousandsGrouping(Py_UNICODE *buffer, +PyAPI_FUNC(int) _PyUnicode_InsertThousandsGroupingLocale(Py_UNICODE *buffer, Py_ssize_t n_buffer, Py_ssize_t n_digits, Py_ssize_t buf_size, Py_ssize_t *count, int append_zero_char); +/* 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 */ +PyAPI_FUNC(int) _PyUnicode_InsertThousandsGrouping(Py_UNICODE *buffer, + Py_ssize_t n_buffer, + Py_ssize_t n_digits, + Py_ssize_t buf_size, + Py_ssize_t *count, + int append_zero_char, + const char *grouping, + const char *thousands_sep); /* === Characters Type APIs =============================================== */ /* Helper array used by Py_UNICODE_ISSPACE(). */ Modified: python/branches/py3k/Lib/test/test_types.py ============================================================================== --- python/branches/py3k/Lib/test/test_types.py (original) +++ python/branches/py3k/Lib/test/test_types.py Fri Apr 3 16:45:06 2009 @@ -338,6 +338,15 @@ test(123456, "#012X", '0X000001E240') test(-123456, "#012X", '-0X00001E240') + test(123, ',', '123') + test(-123, ',', '-123') + test(1234, ',', '1,234') + test(-1234, ',', '-1,234') + test(123456, ',', '123,456') + test(-123456, ',', '-123,456') + test(1234567, ',', '1,234,567') + test(-1234567, ',', '-1,234,567') + # make sure these are errors # precision disallowed @@ -347,6 +356,8 @@ # format spec must be string self.assertRaises(TypeError, 3 .__format__, None) self.assertRaises(TypeError, 3 .__format__, 0) + # can't have ',' with 'n' + self.assertRaises(ValueError, 3 .__format__, ",n") # ensure that only int and float type specifiers work for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] + Modified: python/branches/py3k/Objects/bytesobject.c ============================================================================== --- python/branches/py3k/Objects/bytesobject.c (original) +++ python/branches/py3k/Objects/bytesobject.c Fri Apr 3 16:45:06 2009 @@ -583,6 +583,7 @@ #include "stringlib/transmogrify.h" #define _Py_InsertThousandsGrouping _PyBytes_InsertThousandsGrouping +#define _Py_InsertThousandsGroupingLocale _PyBytes_InsertThousandsGroupingLocale #include "stringlib/localeutil.h" PyObject * Modified: python/branches/py3k/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k/Objects/stringlib/formatter.h (original) +++ python/branches/py3k/Objects/stringlib/formatter.h Fri Apr 3 16:45:06 2009 @@ -120,6 +120,7 @@ int alternate; STRINGLIB_CHAR sign; Py_ssize_t width; + int thousands_separators; Py_ssize_t precision; STRINGLIB_CHAR type; } InternalFormatSpec; @@ -149,6 +150,7 @@ format->alternate = 0; format->sign = '\0'; format->width = -1; + format->thousands_separators = 0; format->precision = -1; format->type = default_type; @@ -201,6 +203,12 @@ format->width = -1; } + /* Comma signifies add thousands separators */ + if (end-ptr && ptr[0] == ',') { + format->thousands_separators = 1; + ++ptr; + } + /* Parse field precision */ if (end-ptr && ptr[0] == '.') { ++ptr; @@ -230,6 +238,11 @@ ++ptr; } + if (format->type == 'n' && format->thousands_separators) { + PyErr_Format(PyExc_ValueError, "Cannot specify ',' with 'n'."); + return 0; + } + return 1; } @@ -630,8 +643,13 @@ if (format->type == 'n') /* Compute how many additional chars we need to allocate to hold the thousands grouping. */ - STRINGLIB_GROUPING(NULL, n_digits, n_digits, + STRINGLIB_GROUPING_LOCALE(NULL, n_digits, n_digits, 0, &n_grouping_chars, 0); + if (format->thousands_separators) + /* Compute how many additional chars we need to allocate + to hold the thousands grouping. */ + STRINGLIB_GROUPING(NULL, n_digits, n_digits, + 0, &n_grouping_chars, 0, "\3", ","); /* Calculate the widths of the various leading and trailing parts */ calc_number_widths(&spec, sign, n_prefix, n_digits + n_grouping_chars, @@ -670,11 +688,22 @@ reserved enough space. */ STRINGLIB_CHAR *pstart = p + n_leading_chars; #ifndef NDEBUG - int r = + int r; +#endif + if (format->type == 'n') +#ifndef NDEBUG + r = #endif - STRINGLIB_GROUPING(pstart, n_digits, n_digits, + STRINGLIB_GROUPING_LOCALE(pstart, n_digits, n_digits, spec.n_total+n_grouping_chars-n_leading_chars, NULL, 0); + else +#ifndef NDEBUG + r = + STRINGLIB_GROUPING(pstart, n_digits, n_digits, + spec.n_total+n_grouping_chars-n_leading_chars, + NULL, 0, "\3", ","); +#endif assert(r); } Modified: python/branches/py3k/Objects/stringlib/localeutil.h ============================================================================== --- python/branches/py3k/Objects/stringlib/localeutil.h (original) +++ python/branches/py3k/Objects/stringlib/localeutil.h Fri Apr 3 16:45:06 2009 @@ -18,11 +18,13 @@ * @append_zero_char: If non-zero, put a trailing zero at the end of * of the resulting string, if and only if we modified the * string. + * @grouping: see definition in localeconv(). + * @thousands_sep: see definition in localeconv(). * - * Inserts thousand grouping characters (as defined in the current - * locale) into the string between buffer and buffer+n_digits. If - * count is non-NULL, don't do any formatting, just count the number - * of characters to insert. This is used by the caller to + * Inserts thousand grouping characters (as defined by grouping and + * thousands_sep) into the string between buffer and buffer+n_digits. + * If count is non-NULL, don't do any formatting, just count the + * number of characters to insert. This is used by the caller to * appropriately resize the buffer, if needed. If count is non-NULL, * buffer can be NULL (it is not dereferenced at all in that case). * @@ -34,97 +36,130 @@ **/ int _Py_InsertThousandsGrouping(STRINGLIB_CHAR *buffer, - Py_ssize_t n_buffer, - Py_ssize_t n_digits, - Py_ssize_t buf_size, - Py_ssize_t *count, - int append_zero_char) + Py_ssize_t n_buffer, + Py_ssize_t n_digits, + Py_ssize_t buf_size, + Py_ssize_t *count, + int append_zero_char, + const char *grouping, + const char *thousands_sep) { - struct lconv *locale_data = localeconv(); - const char *grouping = locale_data->grouping; - const char *thousands_sep = locale_data->thousands_sep; - Py_ssize_t thousands_sep_len = strlen(thousands_sep); - STRINGLIB_CHAR *pend = NULL; /* current end of buffer */ - STRINGLIB_CHAR *pmax = NULL; /* max of buffer */ - char current_grouping; - Py_ssize_t remaining = n_digits; /* Number of chars remaining to - be looked at */ - - /* Initialize the character count, if we're just counting. */ - if (count) - *count = 0; - else { - /* We're not just counting, we're modifying buffer */ - pend = buffer + n_buffer; - pmax = buffer + buf_size; - } - - /* Starting at the end and working right-to-left, keep track of - what grouping needs to be added and insert that. */ - current_grouping = *grouping++; - - /* If the first character is 0, perform no grouping at all. */ - if (current_grouping == 0) - return 1; - - while (remaining > current_grouping) { - /* Always leave buffer and pend valid at the end of this - loop, since we might leave with a return statement. */ - - remaining -= current_grouping; - if (count) { - /* We're only counting, not touching the memory. */ - *count += thousands_sep_len; - } - else { - /* Do the formatting. */ - - STRINGLIB_CHAR *plast = buffer + remaining; - - /* Is there room to insert thousands_sep_len chars? */ - if (pmax - pend < thousands_sep_len) - /* No room. */ - return 0; - - /* Move the rest of the string down. */ - memmove(plast + thousands_sep_len, - plast, - (pend - plast) * sizeof(STRINGLIB_CHAR)); - /* Copy the thousands_sep chars into the buffer. */ + Py_ssize_t thousands_sep_len = strlen(thousands_sep); + STRINGLIB_CHAR *pend = NULL; /* current end of buffer */ + STRINGLIB_CHAR *pmax = NULL; /* max of buffer */ + char current_grouping; + Py_ssize_t remaining = n_digits; /* Number of chars remaining to + be looked at */ + + /* Initialize the character count, if we're just counting. */ + if (count) + *count = 0; + else { + /* We're not just counting, we're modifying buffer */ + pend = buffer + n_buffer; + pmax = buffer + buf_size; + } + + /* Starting at the end and working right-to-left, keep track of + what grouping needs to be added and insert that. */ + current_grouping = *grouping++; + + /* If the first character is 0, perform no grouping at all. */ + if (current_grouping == 0) + return 1; + + while (remaining > current_grouping) { + /* Always leave buffer and pend valid at the end of this + loop, since we might leave with a return statement. */ + + remaining -= current_grouping; + if (count) { + /* We're only counting, not touching the memory. */ + *count += thousands_sep_len; + } + else { + /* Do the formatting. */ + + STRINGLIB_CHAR *plast = buffer + remaining; + + /* Is there room to insert thousands_sep_len chars? */ + if (pmax - pend < thousands_sep_len) + /* No room. */ + return 0; + + /* Move the rest of the string down. */ + memmove(plast + thousands_sep_len, + plast, + (pend - plast) * sizeof(STRINGLIB_CHAR)); + /* Copy the thousands_sep chars into the buffer. */ #if STRINGLIB_IS_UNICODE - /* Convert from the char's of the thousands_sep from - the locale into unicode. */ - { - Py_ssize_t i; - for (i = 0; i < thousands_sep_len; ++i) - plast[i] = thousands_sep[i]; - } + /* Convert from the char's of the thousands_sep from + the locale into unicode. */ + { + Py_ssize_t i; + for (i = 0; i < thousands_sep_len; ++i) + plast[i] = thousands_sep[i]; + } #else - /* No conversion, just memcpy the thousands_sep. */ - memcpy(plast, thousands_sep, thousands_sep_len); + /* No conversion, just memcpy the thousands_sep. */ + memcpy(plast, thousands_sep, thousands_sep_len); #endif - } + } - /* Adjust end pointer. */ - pend += thousands_sep_len; + /* Adjust end pointer. */ + pend += thousands_sep_len; - /* Move to the next grouping character, unless we're - repeating (which is designated by a grouping of 0). */ - if (*grouping != 0) { - current_grouping = *grouping++; - if (current_grouping == CHAR_MAX) - /* We're done. */ - break; - } - } - if (append_zero_char) { - /* Append a zero character to mark the end of the string, - if there's room. */ - if (pend - (buffer + remaining) < 1) - /* No room, error. */ - return 0; - *pend = 0; - } - return 1; + /* Move to the next grouping character, unless we're + repeating (which is designated by a grouping of 0). */ + if (*grouping != 0) { + current_grouping = *grouping++; + if (current_grouping == CHAR_MAX) + /* We're done. */ + break; + } + } + if (append_zero_char) { + /* Append a zero character to mark the end of the string, + if there's room. */ + if (pend - (buffer + remaining) < 1) + /* No room, error. */ + return 0; + *pend = 0; + } + return 1; +} + +/** + * _Py_InsertThousandsGroupingLocale: + * @buffer: A pointer to the start of a string. + * @n_buffer: The length of the string. + * @n_digits: The number of digits in the string, in which we want + * to put the grouping chars. + * @buf_size: The maximum size of the buffer pointed to by buffer. + * @count: If non-NULL, points to a variable that will receive the + * number of characters we need to insert (and no formatting + * will actually occur). + * @append_zero_char: If non-zero, put a trailing zero at the end of + * of the resulting string, if and only if we modified the + * string. + * + * Reads thee current locale and calls _Py_InsertThousandsGrouping(). + **/ +int +_Py_InsertThousandsGroupingLocale(STRINGLIB_CHAR *buffer, + Py_ssize_t n_buffer, + Py_ssize_t n_digits, + Py_ssize_t buf_size, + Py_ssize_t *count, + int append_zero_char) +{ + struct lconv *locale_data = localeconv(); + const char *grouping = locale_data->grouping; + const char *thousands_sep = locale_data->thousands_sep; + + return _Py_InsertThousandsGrouping(buffer, n_buffer, n_digits, + buf_size, count, + append_zero_char, grouping, + thousands_sep); } #endif /* STRINGLIB_LOCALEUTIL_H */ Modified: python/branches/py3k/Objects/stringlib/stringdefs.h ============================================================================== --- python/branches/py3k/Objects/stringlib/stringdefs.h (original) +++ python/branches/py3k/Objects/stringlib/stringdefs.h Fri Apr 3 16:45:06 2009 @@ -24,5 +24,6 @@ #define STRINGLIB_CMP memcmp #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_GROUPING _PyBytes_InsertThousandsGrouping +#define STRINGLIB_GROUPING_LOCALE _PyBytes_InsertThousandsGroupingLocale #define STRINGLIB_TOASCII PyObject_Repr #endif /* !STRINGLIB_STRINGDEFS_H */ Modified: python/branches/py3k/Objects/stringlib/unicodedefs.h ============================================================================== --- python/branches/py3k/Objects/stringlib/unicodedefs.h (original) +++ python/branches/py3k/Objects/stringlib/unicodedefs.h Fri Apr 3 16:45:06 2009 @@ -22,6 +22,7 @@ #define STRINGLIB_RESIZE PyUnicode_Resize #define STRINGLIB_CHECK PyUnicode_Check #define STRINGLIB_GROUPING _PyUnicode_InsertThousandsGrouping +#define STRINGLIB_GROUPING_LOCALE _PyUnicode_InsertThousandsGroupingLocale #if PY_VERSION_HEX < 0x03000000 #define STRINGLIB_TOSTR PyObject_Unicode Modified: python/branches/py3k/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k/Objects/unicodeobject.c (original) +++ python/branches/py3k/Objects/unicodeobject.c Fri Apr 3 16:45:06 2009 @@ -5635,6 +5635,7 @@ #include "stringlib/partition.h" #define _Py_InsertThousandsGrouping _PyUnicode_InsertThousandsGrouping +#define _Py_InsertThousandsGroupingLocale _PyUnicode_InsertThousandsGroupingLocale #include "stringlib/localeutil.h" /* helper macro to fixup start/end slice values */ Modified: python/branches/py3k/Python/pystrtod.c ============================================================================== --- python/branches/py3k/Python/pystrtod.c (original) +++ python/branches/py3k/Python/pystrtod.c Fri Apr 3 16:45:06 2009 @@ -368,7 +368,7 @@ /* At this point, p points just past the right-most character we want to format. We need to add the grouping string for the characters between buffer and p. */ - return _PyBytes_InsertThousandsGrouping(buffer, len, p-buffer, + return _PyBytes_InsertThousandsGroupingLocale(buffer, len, p-buffer, buf_size, NULL, 1); } From python-checkins at python.org Fri Apr 3 16:46:32 2009 From: python-checkins at python.org (eric.smith) Date: Fri, 3 Apr 2009 16:46:32 +0200 (CEST) Subject: [Python-checkins] r71097 - python/branches/release30-maint Message-ID: <20090403144632.6D53A1E41A1@bag.python.org> Author: eric.smith Date: Fri Apr 3 16:46:32 2009 New Revision: 71097 Log: Blocked revisions 71096 via svnmerge ........ r71096 | eric.smith | 2009-04-03 10:45:06 -0400 (Fri, 03 Apr 2009) | 9 lines Added ',' thousands grouping to int.__format__. See PEP 378. This is incomplete, but I want to get some version into the next alpha. I am still working on: Documentation. More tests. Implement for floats. In addition, there's an existing bug with 'n' formatting that carries forward to thousands grouping (issue 5515). ........ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Fri Apr 3 21:48:22 2009 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 3 Apr 2009 21:48:22 +0200 (CEST) Subject: [Python-checkins] r71098 - peps/trunk/pep-0382.txt Message-ID: <20090403194822.16EE61E4017@bag.python.org> Author: martin.v.loewis Date: Fri Apr 3 21:48:21 2009 New Revision: 71098 Log: Add sys.namespace_packages. Modified: peps/trunk/pep-0382.txt Modified: peps/trunk/pep-0382.txt ============================================================================== --- peps/trunk/pep-0382.txt (original) +++ peps/trunk/pep-0382.txt Fri Apr 3 21:48:21 2009 @@ -109,7 +109,8 @@ to the package's __path__ to indicate that the package is a namespace package (and that thus further extensions to sys.path might also want to extend __path__). At most one such asterisk gets prepended -to the path. +to the path. In addition, the (possibly dotted) names of all namespace +packages are added to the list sys.namespace_packages. extend_path will be extended to recognize namespace packages according to this PEP, and avoid adding directories twice to __path__. From python-checkins at python.org Fri Apr 3 21:49:23 2009 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 3 Apr 2009 21:49:23 +0200 (CEST) Subject: [Python-checkins] r71099 - peps/trunk/pep-0382.txt Message-ID: <20090403194923.D21BA1E4017@bag.python.org> Author: martin.v.loewis Date: Fri Apr 3 21:49:23 2009 New Revision: 71099 Log: Make namespace_packages a set. Modified: peps/trunk/pep-0382.txt Modified: peps/trunk/pep-0382.txt ============================================================================== --- peps/trunk/pep-0382.txt (original) +++ peps/trunk/pep-0382.txt Fri Apr 3 21:49:23 2009 @@ -110,7 +110,7 @@ package (and that thus further extensions to sys.path might also want to extend __path__). At most one such asterisk gets prepended to the path. In addition, the (possibly dotted) names of all namespace -packages are added to the list sys.namespace_packages. +packages are added to the set sys.namespace_packages. extend_path will be extended to recognize namespace packages according to this PEP, and avoid adding directories twice to __path__. From python-checkins at python.org Fri Apr 3 22:00:30 2009 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 3 Apr 2009 22:00:30 +0200 (CEST) Subject: [Python-checkins] r71100 - peps/trunk/pep-0382.txt Message-ID: <20090403200030.8831F1E41C5@bag.python.org> Author: martin.v.loewis Date: Fri Apr 3 22:00:29 2009 New Revision: 71100 Log: Discuss adding 2.7 to Python-Version. Modified: peps/trunk/pep-0382.txt Modified: peps/trunk/pep-0382.txt ============================================================================== --- peps/trunk/pep-0382.txt (original) +++ peps/trunk/pep-0382.txt Fri Apr 3 22:00:29 2009 @@ -142,6 +142,13 @@ any other mechanism might cause portions to get added twice to __path__. +It has been proposed to also add this feature to Python 2.7. Given +that 2.x reaches its end-of-life, it is questionable whether the +addition of the feature would really do more good than harm (in +having users and tools starting to special-case 2.7). Prospective +users of this feature are encouraged to comment on this particular +question. + Copyright ========= From python-checkins at python.org Fri Apr 3 23:43:00 2009 From: python-checkins at python.org (andrew.kuchling) Date: Fri, 3 Apr 2009 23:43:00 +0200 (CEST) Subject: [Python-checkins] r71101 - python/trunk/Doc/whatsnew/2.7.rst Message-ID: <20090403214300.C2F0C1E414C@bag.python.org> Author: andrew.kuchling Date: Fri Apr 3 23:43:00 2009 New Revision: 71101 Log: Add some items Modified: python/trunk/Doc/whatsnew/2.7.rst Modified: python/trunk/Doc/whatsnew/2.7.rst ============================================================================== --- python/trunk/Doc/whatsnew/2.7.rst (original) +++ python/trunk/Doc/whatsnew/2.7.rst Fri Apr 3 23:43:00 2009 @@ -7,7 +7,6 @@ :Date: |today| .. Fix accents on Kristjan Valur Jonsson, Fuerstenau, Tarek Ziade. -.. OrderedDict .. $Id$ Rules for maintenance: @@ -106,6 +105,9 @@ (Contributed by Fredrik Johansson and Victor Stinner; :issue:`3439`.) +* The :class:`bytearray` type's :meth:`translate` method will + now accept None as its first argument. (Fixed by Georg Brandl; + :issue:`4759`.) .. ====================================================================== @@ -174,6 +176,12 @@ integer divisions and modulo operations. (Contributed by Mark Dickinson; :issue:`5512`.) +* The implementation of ``%`` checks for the left-side operand being + a Python string and special-cases it; this results in a 1-3% + performance increase for applications that frequently use ``%`` + with strings, such as templating libraries. + (Implemented by Collin Winter; :issue:`5176`.) + * List comprehensions with an ``if`` condition are compiled into faster bytecode. (Patch by Antoine Pitrou, back-ported to 2.7 by Jeffrey Yasskin; :issue:`4715`.) @@ -227,6 +235,18 @@ Contributed by Raymond Hettinger; :issue:`1696199`. + The :class:`namedtuple` class now has an optional *rename* parameter. + If *rename* is True, field names that are invalid because they've + been repeated or that aren't legal Python identifiers will be + renamed to legal names that are derived from the field's + position within the list of fields: + + >>> T=namedtuple('T', ['field1', '$illegal', 'for', 'field2'], rename=True) + >>> T._fields + ('field1', '_1', '_2', 'field2') + + (Added by Raymond Hettinger; :issue:`1818`.) + * In Distutils, :func:`distutils.sdist.add_defaults` now uses *package_dir* and *data_files* to create the MANIFEST file. @@ -234,7 +254,7 @@ :file:`.pypirc` file when registering and uploading packages to PyPI. As long as the username is present in that file, the :mod:`distutils` package will prompt for the password if not present. (Added by Tarek Ziade, - with the initial contribution by Nathan Van Gheem; :issue:`4394`.) + based on an initial contribution by Nathan Van Gheem; :issue:`4394`.) * New method: the :class:`Decimal` class gained a :meth:`from_float` class method that performs an exact conversion @@ -308,7 +328,7 @@ * A new function in the :mod:`subprocess` module, :func:`check_output`, runs a command with a specified set of arguments - and returns the command's output as a string if the command runs without + and returns the command's output as a string when the command runs without error, or raises a :exc:`CalledProcessError` exception otherwise. :: @@ -323,6 +343,10 @@ (Contributed by Gregory P. Smith.) +* The ``sys.version_info`` value is now a named tuple, with attributes + named ``major``, ``minor``, ``micro``, ``releaselevel``, and ``serial``. + (Contributed by Ross Light; :issue:`4285`.) + * The :mod:`unittest` module was enhanced in several ways. Test cases can raise the :exc:`SkipTest` exception to skip a test. (:issue:`1034053`.) @@ -330,6 +354,15 @@ and 'u' for unexpected successes when run in its verbose mode. (Contributed by Benjamin Peterson.) + The :meth:`assertRaises` and :meth:`failUnlessRaises` methods now + return a context handler when called without providing a callable + object to run. For example, you can write this:: + + with self.assertRaises(KeyError): + raise ValueError + + (Implemented by Antoine Pitrou; :issue:`4444`.) + * The :func:`is_zipfile` function in the :mod:`zipfile` module will now accept a file object, in addition to the path names accepted in earlier versions. (Contributed by Gabriel Genellina; :issue:`4756`.) @@ -375,7 +408,7 @@ debugged doesn't hold the GIL; the macro will now acquire it before printing. (Contributed by Victor Stinner; :issue:`3632`.) -* :cfunc:`Py_AddPendingCall` is now thread safe, letting any +* :cfunc:`Py_AddPendingCall` is now thread-safe, letting any worker thread submit notifications to the main Python thread. This is particularly useful for asynchronous IO operations. (Contributed by Kristjan Valur Jonsson; :issue:`4293`.) From python-checkins at python.org Fri Apr 3 23:44:49 2009 From: python-checkins at python.org (andrew.kuchling) Date: Fri, 3 Apr 2009 23:44:49 +0200 (CEST) Subject: [Python-checkins] r71102 - python/trunk/Doc/c-api/number.rst Message-ID: <20090403214449.5FE0C1E401D@bag.python.org> Author: andrew.kuchling Date: Fri Apr 3 23:44:49 2009 New Revision: 71102 Log: Fix 'the the'; grammar fix Modified: python/trunk/Doc/c-api/number.rst Modified: python/trunk/Doc/c-api/number.rst ============================================================================== --- python/trunk/Doc/c-api/number.rst (original) +++ python/trunk/Doc/c-api/number.rst Fri Apr 3 23:44:49 2009 @@ -292,8 +292,8 @@ .. cfunction:: PyObject* PyNumber_ToBase(PyObject *n, int base) - Returns the the integer *n* converted to *base* as a string with a base - marker of ``'0b'``, ``'0o'``, or ``'0x'`` if appended applicable. When + Returns the integer *n* converted to *base* as a string with a base + marker of ``'0b'``, ``'0o'``, or ``'0x'`` if applicable. When *base* is not 2, 8, 10, or 16, the format is ``'x#num'`` where x is the base. If *n* is not an int object, it is converted with :cfunc:`PyNumber_Index` first. From python-checkins at python.org Fri Apr 3 23:45:30 2009 From: python-checkins at python.org (andrew.kuchling) Date: Fri, 3 Apr 2009 23:45:30 +0200 (CEST) Subject: [Python-checkins] r71103 - in python/trunk/Doc: c-api/init.rst howto/cporting.rst library/abc.rst library/multiprocessing.rst library/pdb.rst library/ssl.rst library/ttk.rst whatsnew/2.6.rst Message-ID: <20090403214530.666511E4028@bag.python.org> Author: andrew.kuchling Date: Fri Apr 3 23:45:29 2009 New Revision: 71103 Log: Fix 'the the' duplication Modified: python/trunk/Doc/c-api/init.rst python/trunk/Doc/howto/cporting.rst python/trunk/Doc/library/abc.rst python/trunk/Doc/library/multiprocessing.rst python/trunk/Doc/library/pdb.rst python/trunk/Doc/library/ssl.rst python/trunk/Doc/library/ttk.rst python/trunk/Doc/whatsnew/2.6.rst Modified: python/trunk/Doc/c-api/init.rst ============================================================================== --- python/trunk/Doc/c-api/init.rst (original) +++ python/trunk/Doc/c-api/init.rst Fri Apr 3 23:45:29 2009 @@ -802,7 +802,7 @@ Asynchronous Notifications ========================== -A mechanism is provided to make asynchronous notifications to the the main +A mechanism is provided to make asynchronous notifications to the main interpreter thread. These notifications take the form of a function pointer and a void argument. Modified: python/trunk/Doc/howto/cporting.rst ============================================================================== --- python/trunk/Doc/howto/cporting.rst (original) +++ python/trunk/Doc/howto/cporting.rst Fri Apr 3 23:45:29 2009 @@ -96,7 +96,7 @@ Python level, but actually corresponds to 2.x's :func:`long` type. In the C-API, ``PyInt_*`` functions are replaced by their ``PyLong_*`` neighbors. The best course of action here is using the ``PyInt_*`` functions aliased to -``PyLong_*`` found in :file:`intobject.h`. The the abstract ``PyNumber_*`` APIs +``PyLong_*`` found in :file:`intobject.h`. The abstract ``PyNumber_*`` APIs can also be used in some cases. :: #include "Python.h" Modified: python/trunk/Doc/library/abc.rst ============================================================================== --- python/trunk/Doc/library/abc.rst (original) +++ python/trunk/Doc/library/abc.rst Fri Apr 3 23:45:29 2009 @@ -134,7 +134,7 @@ A class that has a metaclass derived from :class:`ABCMeta` cannot be instantiated unless all of its abstract methods and properties are overridden. - The abstract methods can be called using any of the the normal 'super' call + The abstract methods can be called using any of the normal 'super' call mechanisms. Dynamically adding abstract methods to a class, or attempting to modify the Modified: python/trunk/Doc/library/multiprocessing.rst ============================================================================== --- python/trunk/Doc/library/multiprocessing.rst (original) +++ python/trunk/Doc/library/multiprocessing.rst Fri Apr 3 23:45:29 2009 @@ -1857,7 +1857,7 @@ any :class:`~multiprocessing.Process` object that the current process creates. This means that (by default) all processes of a multi-process program will share a single authentication key which can be used when setting up connections -between the themselves. +between themselves. Suitable authentication keys can also be generated by using :func:`os.urandom`. Modified: python/trunk/Doc/library/pdb.rst ============================================================================== --- python/trunk/Doc/library/pdb.rst (original) +++ python/trunk/Doc/library/pdb.rst Fri Apr 3 23:45:29 2009 @@ -268,7 +268,7 @@ full speed, only stopping at the next line in the current function.) unt(il) - Continue execution until the line with the the line number greater than the + Continue execution until the line with the line number greater than the current one is reached or when returning from current frame. .. versionadded:: 2.6 Modified: python/trunk/Doc/library/ssl.rst ============================================================================== --- python/trunk/Doc/library/ssl.rst (original) +++ python/trunk/Doc/library/ssl.rst Fri Apr 3 23:45:29 2009 @@ -261,7 +261,7 @@ If there is no certificate for the peer on the other end of the connection, returns ``None``. - If the the parameter ``binary_form`` is :const:`False`, and a + If the parameter ``binary_form`` is :const:`False`, and a certificate was received from the peer, this method returns a :class:`dict` instance. If the certificate was not validated, the dict is empty. If the certificate was validated, it returns a dict Modified: python/trunk/Doc/library/ttk.rst ============================================================================== --- python/trunk/Doc/library/ttk.rst (original) +++ python/trunk/Doc/library/ttk.rst Fri Apr 3 23:45:29 2009 @@ -1381,7 +1381,7 @@ options/values are: * side: whichside - Specifies which side of the cavity to place the the element; one of + Specifies which side of the cavity to place the element; one of top, right, bottom or left. If omitted, the element occupies the entire cavity. Modified: python/trunk/Doc/whatsnew/2.6.rst ============================================================================== --- python/trunk/Doc/whatsnew/2.6.rst (original) +++ python/trunk/Doc/whatsnew/2.6.rst Fri Apr 3 23:45:29 2009 @@ -1672,7 +1672,7 @@ :attr:`__self__`, and :attr:`im_func` is also available as :attr:`__func__`. The old names are still supported in Python 2.6, but are gone in 3.0. -* An obscure change: when you use the the :func:`locals` function inside a +* An obscure change: when you use the :func:`locals` function inside a :keyword:`class` statement, the resulting dictionary no longer returns free variables. (Free variables, in this case, are variables referenced in the :keyword:`class` statement that aren't attributes of the class.) From python-checkins at python.org Fri Apr 3 23:55:34 2009 From: python-checkins at python.org (andrew.kuchling) Date: Fri, 3 Apr 2009 23:55:34 +0200 (CEST) Subject: [Python-checkins] r71104 - python/branches/release26-maint/Doc/c-api/number.rst Message-ID: <20090403215534.736811E401D@bag.python.org> Author: andrew.kuchling Date: Fri Apr 3 23:55:34 2009 New Revision: 71104 Log: Fix 'the the'; grammar fix (backport of r71102 Modified: python/branches/release26-maint/Doc/c-api/number.rst Modified: python/branches/release26-maint/Doc/c-api/number.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/number.rst (original) +++ python/branches/release26-maint/Doc/c-api/number.rst Fri Apr 3 23:55:34 2009 @@ -292,8 +292,8 @@ .. cfunction:: PyObject* PyNumber_ToBase(PyObject *n, int base) - Returns the the integer *n* converted to *base* as a string with a base - marker of ``'0b'``, ``'0o'``, or ``'0x'`` if appended applicable. When + Returns the integer *n* converted to *base* as a string with a base + marker of ``'0b'``, ``'0o'``, or ``'0x'`` if applicable. When *base* is not 2, 8, 10, or 16, the format is ``'x#num'`` where x is the base. If *n* is not an int object, it is converted with :cfunc:`PyNumber_Index` first. From python-checkins at python.org Fri Apr 3 23:56:37 2009 From: python-checkins at python.org (andrew.kuchling) Date: Fri, 3 Apr 2009 23:56:37 +0200 (CEST) Subject: [Python-checkins] r71105 - in python/branches/release26-maint/Doc: howto/cporting.rst library/abc.rst library/multiprocessing.rst library/pdb.rst library/ssl.rst whatsnew/2.6.rst Message-ID: <20090403215637.0B7A41E401D@bag.python.org> Author: andrew.kuchling Date: Fri Apr 3 23:56:36 2009 New Revision: 71105 Log: Fix 'the the' duplication (partial backport of r71103 Modified: python/branches/release26-maint/Doc/howto/cporting.rst python/branches/release26-maint/Doc/library/abc.rst python/branches/release26-maint/Doc/library/multiprocessing.rst python/branches/release26-maint/Doc/library/pdb.rst python/branches/release26-maint/Doc/library/ssl.rst python/branches/release26-maint/Doc/whatsnew/2.6.rst Modified: python/branches/release26-maint/Doc/howto/cporting.rst ============================================================================== --- python/branches/release26-maint/Doc/howto/cporting.rst (original) +++ python/branches/release26-maint/Doc/howto/cporting.rst Fri Apr 3 23:56:36 2009 @@ -96,7 +96,7 @@ Python level, but actually corresponds to 2.x's :func:`long` type. In the C-API, ``PyInt_*`` functions are replaced by their ``PyLong_*`` neighbors. The best course of action here is using the ``PyInt_*`` functions aliased to -``PyLong_*`` found in :file:`intobject.h`. The the abstract ``PyNumber_*`` APIs +``PyLong_*`` found in :file:`intobject.h`. The abstract ``PyNumber_*`` APIs can also be used in some cases. :: #include "Python.h" Modified: python/branches/release26-maint/Doc/library/abc.rst ============================================================================== --- python/branches/release26-maint/Doc/library/abc.rst (original) +++ python/branches/release26-maint/Doc/library/abc.rst Fri Apr 3 23:56:36 2009 @@ -134,7 +134,7 @@ A class that has a metaclass derived from :class:`ABCMeta` cannot be instantiated unless all of its abstract methods and properties are overridden. - The abstract methods can be called using any of the the normal 'super' call + The abstract methods can be called using any of the normal 'super' call mechanisms. Dynamically adding abstract methods to a class, or attempting to modify the Modified: python/branches/release26-maint/Doc/library/multiprocessing.rst ============================================================================== --- python/branches/release26-maint/Doc/library/multiprocessing.rst (original) +++ python/branches/release26-maint/Doc/library/multiprocessing.rst Fri Apr 3 23:56:36 2009 @@ -1845,7 +1845,7 @@ any :class:`~multiprocessing.Process` object that the current process creates. This means that (by default) all processes of a multi-process program will share a single authentication key which can be used when setting up connections -between the themselves. +between themselves. Suitable authentication keys can also be generated by using :func:`os.urandom`. Modified: python/branches/release26-maint/Doc/library/pdb.rst ============================================================================== --- python/branches/release26-maint/Doc/library/pdb.rst (original) +++ python/branches/release26-maint/Doc/library/pdb.rst Fri Apr 3 23:56:36 2009 @@ -268,7 +268,7 @@ full speed, only stopping at the next line in the current function.) unt(il) - Continue execution until the line with the the line number greater than the + Continue execution until the line with the line number greater than the current one is reached or when returning from current frame. .. versionadded:: 2.6 Modified: python/branches/release26-maint/Doc/library/ssl.rst ============================================================================== --- python/branches/release26-maint/Doc/library/ssl.rst (original) +++ python/branches/release26-maint/Doc/library/ssl.rst Fri Apr 3 23:56:36 2009 @@ -261,7 +261,7 @@ If there is no certificate for the peer on the other end of the connection, returns ``None``. - If the the parameter ``binary_form`` is :const:`False`, and a + If the parameter ``binary_form`` is :const:`False`, and a certificate was received from the peer, this method returns a :class:`dict` instance. If the certificate was not validated, the dict is empty. If the certificate was validated, it returns a dict Modified: python/branches/release26-maint/Doc/whatsnew/2.6.rst ============================================================================== --- python/branches/release26-maint/Doc/whatsnew/2.6.rst (original) +++ python/branches/release26-maint/Doc/whatsnew/2.6.rst Fri Apr 3 23:56:36 2009 @@ -1674,7 +1674,7 @@ :attr:`__self__`, and :attr:`im_func` is also available as :attr:`__func__`. The old names are still supported in Python 2.6, but are gone in 3.0. -* An obscure change: when you use the the :func:`locals` function inside a +* An obscure change: when you use the :func:`locals` function inside a :keyword:`class` statement, the resulting dictionary no longer returns free variables. (Free variables, in this case, are variables referenced in the :keyword:`class` statement that aren't attributes of the class.) From python-checkins at python.org Fri Apr 3 23:58:17 2009 From: python-checkins at python.org (vinay.sajip) Date: Fri, 3 Apr 2009 23:58:17 +0200 (CEST) Subject: [Python-checkins] r71106 - python/trunk/Doc/library/logging.rst Message-ID: <20090403215817.07E901E401D@bag.python.org> Author: vinay.sajip Date: Fri Apr 3 23:58:16 2009 New Revision: 71106 Log: Clarified warning about logging use from asynchronous signal handlers. Modified: python/trunk/Doc/library/logging.rst Modified: python/trunk/Doc/library/logging.rst ============================================================================== --- python/trunk/Doc/library/logging.rst (original) +++ python/trunk/Doc/library/logging.rst Fri Apr 3 23:58:16 2009 @@ -2351,9 +2351,10 @@ locks; there is one lock to serialize access to the module's shared data, and each handler also creates a lock to serialize access to its underlying I/O. -Note that in Linux/Unix environments, threading APIs may not be usable in -asynchronous signal handlers. This may mean that you cannot use logging from -within asynchronous signal handlers; please check your OS documentation. +If you are implementing asynchronous signal handlers using the :mod:`signal` +module, you may not be able to use logging from within such handlers. This is +because lock implementations in the :mod:`threading` module are not always +re-entrant, and so cannot be invoked from such signal handlers. Configuration ------------- From python-checkins at python.org Sat Apr 4 00:18:11 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 00:18:11 +0200 (CEST) Subject: [Python-checkins] r71107 - in python/branches/py3k: Doc/c-api/arg.rst Modules/_cursesmodule.c Modules/arraymodule.c Python/modsupport.c Message-ID: <20090403221811.64F4F1E4028@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 00:18:11 2009 New Revision: 71107 Log: Py_BuildValue's 'c' code should use byte strings #5666 Modified: python/branches/py3k/Doc/c-api/arg.rst python/branches/py3k/Modules/_cursesmodule.c python/branches/py3k/Modules/arraymodule.c python/branches/py3k/Python/modsupport.c Modified: python/branches/py3k/Doc/c-api/arg.rst ============================================================================== --- python/branches/py3k/Doc/c-api/arg.rst (original) +++ python/branches/py3k/Doc/c-api/arg.rst Sat Apr 4 00:18:11 2009 @@ -212,7 +212,7 @@ :ctype:`char`. ``C`` (string of length 1) [int] - Covert a Python character, represented as a unicode string of length 1, to a + Convert a Python character, represented as a unicode string of length 1, to a C :ctype:`int`. ``f`` (float) [float] @@ -511,8 +511,12 @@ Convert a C :ctype:`Py_ssize_t` to a Python integer. ``c`` (string of length 1) [char] - Convert a C :ctype:`int` representing a character to a Python string of length - 1. + Convert a C :ctype:`int` representing a byte to a Python byte string of + length 1. + + ``C`` (string of length 1) [int] + Convert a C :ctype:`int` representing a character to Python unicode + string of length 1. ``d`` (float) [double] Convert a C :ctype:`double` to a Python floating point number. Modified: python/branches/py3k/Modules/_cursesmodule.c ============================================================================== --- python/branches/py3k/Modules/_cursesmodule.c (original) +++ python/branches/py3k/Modules/_cursesmodule.c Sat Apr 4 00:18:11 2009 @@ -890,7 +890,7 @@ PyErr_SetString(PyCursesError, "no input"); return NULL; } else if (rtn<=255) - return Py_BuildValue("c", rtn); + return Py_BuildValue("C", rtn); else #if defined(__NetBSD__) return PyUnicode_FromString(unctrl(rtn)); Modified: python/branches/py3k/Modules/arraymodule.c ============================================================================== --- python/branches/py3k/Modules/arraymodule.c (original) +++ python/branches/py3k/Modules/arraymodule.c Sat Apr 4 00:18:11 2009 @@ -1141,14 +1141,14 @@ > PY_SSIZE_T_MAX / Py_SIZE(array)) { return PyErr_NoMemory(); } - result = Py_BuildValue("O(cy#)O", + result = Py_BuildValue("O(Cy#)O", Py_TYPE(array), array->ob_descr->typecode, array->ob_item, Py_SIZE(array) * array->ob_descr->itemsize, dict); } else { - result = Py_BuildValue("O(c)O", + result = Py_BuildValue("O(C)O", Py_TYPE(array), array->ob_descr->typecode, dict); Modified: python/branches/py3k/Python/modsupport.c ============================================================================== --- python/branches/py3k/Python/modsupport.c (original) +++ python/branches/py3k/Python/modsupport.c Sat Apr 4 00:18:11 2009 @@ -289,7 +289,7 @@ { char p[1]; p[0] = (char)va_arg(*p_va, int); - return PyUnicode_FromStringAndSize(p, 1); + return PyBytes_FromStringAndSize(p, 1); } case 'C': { From python-checkins at python.org Sat Apr 4 00:22:42 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 00:22:42 +0200 (CEST) Subject: [Python-checkins] r71108 - python/branches/py3k/Misc/NEWS Message-ID: <20090403222242.A02581E4028@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 00:22:42 2009 New Revision: 71108 Log: update NEWS Modified: python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Apr 4 00:22:42 2009 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #5666: Py_BuildValue's 'c' code should create byte strings. + - Issue #5499: The 'c' code for argument parsing functions now only accepts a byte, and the 'C' code only accepts a unicode character. From python-checkins at python.org Sat Apr 4 00:23:43 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 00:23:43 +0200 (CEST) Subject: [Python-checkins] r71109 - python/branches/py3k/Lib/importlib/test/util.py Message-ID: <20090403222343.E3D181E4028@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 00:23:43 2009 New Revision: 71109 Log: os.path.listdir -> os.listdir Modified: python/branches/py3k/Lib/importlib/test/util.py Modified: python/branches/py3k/Lib/importlib/test/util.py ============================================================================== --- python/branches/py3k/Lib/importlib/test/util.py (original) +++ python/branches/py3k/Lib/importlib/test/util.py Sat Apr 4 00:23:43 2009 @@ -10,7 +10,7 @@ """Class decorator that nullifies tests that require a case-insensitive file system.""" if sys.platform not in ('win32', 'darwin', 'cygwin'): - original_name = os.path.listdir('.')[0] + original_name = os.listdir('.')[0] if name.upper() != name: changed_name = name.upper() else: From python-checkins at python.org Sat Apr 4 00:25:33 2009 From: python-checkins at python.org (eric.smith) Date: Sat, 4 Apr 2009 00:25:33 +0200 (CEST) Subject: [Python-checkins] r71110 - python/branches/py3k/Misc/NEWS Message-ID: <20090403222533.6DEFC1E4028@bag.python.org> Author: eric.smith Date: Sat Apr 4 00:25:33 2009 New Revision: 71110 Log: Added Misc/NEWS entry for PEP 378. Modified: python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Apr 4 00:25:33 2009 @@ -11,6 +11,8 @@ Core and Builtins ----------------- +- Implement PEP 378, Format Specifier for Thousands Separator, for + integers. - Issue #5666: Py_BuildValue's 'c' code should create byte strings. From python-checkins at python.org Sat Apr 4 00:39:45 2009 From: python-checkins at python.org (brett.cannon) Date: Sat, 4 Apr 2009 00:39:45 +0200 (CEST) Subject: [Python-checkins] r71111 - peps/trunk/pep-0382.txt Message-ID: <20090403223945.2E6671E4028@bag.python.org> Author: brett.cannon Date: Sat Apr 4 00:39:44 2009 New Revision: 71111 Log: Fix the status of PEP 382 to be valid for a standards track PEP. Modified: peps/trunk/pep-0382.txt Modified: peps/trunk/pep-0382.txt ============================================================================== --- peps/trunk/pep-0382.txt (original) +++ peps/trunk/pep-0382.txt Sat Apr 4 00:39:44 2009 @@ -3,7 +3,7 @@ Version: $Revision$ Last-Modified: $Date$ Author: Martin v. L?wis -Status: Active +Status: Draft Type: Standards Track Content-Type: text/x-rst Created: 02-Apr-2009 From python-checkins at python.org Sat Apr 4 01:47:27 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 01:47:27 +0200 (CEST) Subject: [Python-checkins] r71112 - python/branches/py3k/Lib/importlib/test/util.py Message-ID: <20090403234727.1223D1E4028@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 01:47:26 2009 New Revision: 71112 Log: fix naming Modified: python/branches/py3k/Lib/importlib/test/util.py Modified: python/branches/py3k/Lib/importlib/test/util.py ============================================================================== --- python/branches/py3k/Lib/importlib/test/util.py (original) +++ python/branches/py3k/Lib/importlib/test/util.py Sat Apr 4 01:47:26 2009 @@ -11,10 +11,10 @@ file system.""" if sys.platform not in ('win32', 'darwin', 'cygwin'): original_name = os.listdir('.')[0] - if name.upper() != name: - changed_name = name.upper() + if name.upper() != original_name: + changed_name = original_name.upper() else: - changed_name = name.lower() + changed_name = original_name.lower() if os.path.exists(changed_name): return class_ return unittest.TestCase From python-checkins at python.org Sat Apr 4 01:57:05 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 01:57:05 +0200 (CEST) Subject: [Python-checkins] r71113 - python/branches/py3k/Lib/test/test_urllib2net.py Message-ID: <20090403235705.4386D1E4028@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 01:57:05 2009 New Revision: 71113 Log: fix this test Modified: python/branches/py3k/Lib/test/test_urllib2net.py Modified: python/branches/py3k/Lib/test/test_urllib2net.py ============================================================================== --- python/branches/py3k/Lib/test/test_urllib2net.py (original) +++ python/branches/py3k/Lib/test/test_urllib2net.py Sat Apr 4 01:57:05 2009 @@ -195,7 +195,7 @@ def test_http_basic(self): self.assertTrue(socket.getdefaulttimeout() is None) u = _urlopen_with_retry("http://www.python.org") - self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None) + self.assertTrue(u.fp.raw._sock.gettimeout() is None) def test_http_default_timeout(self): self.assertTrue(socket.getdefaulttimeout() is None) @@ -204,7 +204,7 @@ u = _urlopen_with_retry("http://www.python.org") finally: socket.setdefaulttimeout(None) - self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60) + self.assertEqual(u.fp.raw._sock.gettimeout(), 60) def test_http_no_timeout(self): self.assertTrue(socket.getdefaulttimeout() is None) @@ -213,11 +213,11 @@ u = _urlopen_with_retry("http://www.python.org", timeout=None) finally: socket.setdefaulttimeout(None) - self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None) + self.assertTrue(u.fp.raw._sock.gettimeout() is None) def test_http_timeout(self): u = _urlopen_with_retry("http://www.python.org", timeout=120) - self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 120) + self.assertEqual(u.fp.raw._sock.gettimeout(), 120) FTP_HOST = "ftp://ftp.mirror.nl/pub/mirror/gnu/" From python-checkins at python.org Sat Apr 4 02:46:16 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 02:46:16 +0200 (CEST) Subject: [Python-checkins] r71114 - python/branches/py3k/Lib/importlib/test/util.py Message-ID: <20090404004616.08D021E405C@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 02:46:15 2009 New Revision: 71114 Log: fix name Modified: python/branches/py3k/Lib/importlib/test/util.py Modified: python/branches/py3k/Lib/importlib/test/util.py ============================================================================== --- python/branches/py3k/Lib/importlib/test/util.py (original) +++ python/branches/py3k/Lib/importlib/test/util.py Sat Apr 4 02:46:15 2009 @@ -11,7 +11,7 @@ file system.""" if sys.platform not in ('win32', 'darwin', 'cygwin'): original_name = os.listdir('.')[0] - if name.upper() != original_name: + if orignal_name.upper() != original_name: changed_name = original_name.upper() else: changed_name = original_name.lower() From python-checkins at python.org Sat Apr 4 03:21:56 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 03:21:56 +0200 (CEST) Subject: [Python-checkins] r71115 - python/branches/py3k/Lib/importlib/test/util.py Message-ID: <20090404012156.8A7521E405C@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 03:21:56 2009 New Revision: 71115 Log: fix name again Modified: python/branches/py3k/Lib/importlib/test/util.py Modified: python/branches/py3k/Lib/importlib/test/util.py ============================================================================== --- python/branches/py3k/Lib/importlib/test/util.py (original) +++ python/branches/py3k/Lib/importlib/test/util.py Sat Apr 4 03:21:56 2009 @@ -11,7 +11,7 @@ file system.""" if sys.platform not in ('win32', 'darwin', 'cygwin'): original_name = os.listdir('.')[0] - if orignal_name.upper() != original_name: + if original_name.upper() != original_name: changed_name = original_name.upper() else: changed_name = original_name.lower() From python-checkins at python.org Sat Apr 4 03:38:38 2009 From: python-checkins at python.org (r.david.murray) Date: Sat, 4 Apr 2009 03:38:38 +0200 (CEST) Subject: [Python-checkins] r71116 - in python/branches/py3k: Doc/library/csv.rst Lib/test/test_csv.py Message-ID: <20090404013838.54B991E405C@bag.python.org> Author: r.david.murray Date: Sat Apr 4 03:38:38 2009 New Revision: 71116 Log: Update documentation for csv module to reflect changes in code, specifically that it now expects unicode input (and therefore the paragraph about it not handling unicode is deleted, as well as the 'how to handle unicode' examples) and that files should be opened with "newline=''" instead of binary mode. Also removed unused BytesIO import from test_csv. This addresses issue 4847. Modified: python/branches/py3k/Doc/library/csv.rst python/branches/py3k/Lib/test/test_csv.py Modified: python/branches/py3k/Doc/library/csv.rst ============================================================================== --- python/branches/py3k/Doc/library/csv.rst (original) +++ python/branches/py3k/Doc/library/csv.rst Sat Apr 4 03:38:38 2009 @@ -33,14 +33,6 @@ write sequences. Programmers can also read and write data in dictionary form using the :class:`DictReader` and :class:`DictWriter` classes. -.. note:: - - This version of the :mod:`csv` module doesn't support Unicode input. Also, - there are currently some issues regarding ASCII NUL characters. Accordingly, - all input should be UTF-8 or printable ASCII to be safe; see the examples in - section :ref:`csv-examples`. These restrictions will be removed in the future. - - .. seealso:: :pep:`305` - CSV File API @@ -60,8 +52,8 @@ Return a reader object which will iterate over lines in the given *csvfile*. *csvfile* can be any object which supports the :term:`iterator` protocol and returns a string each time its :meth:`next` method is called --- file objects and list - objects are both suitable. If *csvfile* is a file object, it must be opened - with the 'b' flag on platforms where that makes a difference. An optional + objects are both suitable. If *csvfile* is a file object, it should be opened + with ``newline=''``. [#]_ An optional *dialect* parameter can be given which is used to define a set of parameters specific to a particular CSV dialect. It may be an instance of a subclass of the :class:`Dialect` class or one of the strings returned by the @@ -71,20 +63,13 @@ section :ref:`csv-fmt-params`. Each row read from the csv file is returned as a list of strings. No - automatic data type conversion is performed. - - The parser is quite strict with respect to multi-line quoted fields. Previously, - if a line ended within a quoted field without a terminating newline character, a - newline would be inserted into the returned field. This behavior caused problems - when reading files which contained carriage return characters within fields. - The behavior was changed to return the field without inserting newlines. As a - consequence, if newlines embedded within fields are important, the input should - be split into lines in a manner which preserves the newline characters. + automatic data type conversion is performed unless the ``QUOTE_NONNUMERIC`` format + option is specified (in which case unquoted fields are transformed into floats). A short usage example:: >>> import csv - >>> spamReader = csv.reader(open('eggs.csv'), delimiter=' ', quotechar='|') + >>> spamReader = csv.reader(open('eggs.csv', newline=''), delimiter=' ', quotechar='|') >>> for row in spamReader: ... print(', '.join(row)) Spam, Spam, Spam, Spam, Spam, Baked Beans @@ -95,8 +80,7 @@ Return a writer object responsible for converting the user's data into delimited strings on the given file-like object. *csvfile* can be any object with a - :func:`write` method. If *csvfile* is a file object, it must be opened with the - 'b' flag on platforms where that makes a difference. An optional *dialect* + :func:`write` method. An optional *dialect* parameter can be given which is used to define a set of parameters specific to a particular CSV dialect. It may be an instance of a subclass of the :class:`Dialect` class or one of the strings returned by the @@ -270,7 +254,6 @@ Raised by any of the functions when an error is detected. - .. _csv-fmt-params: Dialects and Formatting Parameters @@ -419,41 +402,52 @@ The simplest example of reading a CSV file:: import csv - reader = csv.reader(open("some.csv", "rb")) + reader = csv.reader(open("some.csv", newline='')) for row in reader: print(row) Reading a file with an alternate format:: import csv - reader = csv.reader(open("passwd", "rb"), delimiter=':', quoting=csv.QUOTE_NONE) + reader = csv.reader(open("passwd"), delimiter=':', quoting=csv.QUOTE_NONE) for row in reader: print(row) The corresponding simplest possible writing example is:: import csv - writer = csv.writer(open("some.csv", "wb")) + writer = csv.writer(open("some.csv", "w")) writer.writerows(someiterable) +Since :func:`open` is used to open a CSV file for reading, the file +will by default be decoded into unicode using the system default +encoding (see :func:`locale.getpreferredencoding`). To decode a file +using a different encoding, use the ``encoding`` argument of open:: + + import csv + reader = csv.reader(open("some.csv", newline='', encoding='utf-8')) + for row in reader: + print(row) + +The same applies to writing in something other than the system default +encoding: specify the encoding argument when opening the output file. + Registering a new dialect:: import csv - csv.register_dialect('unixpwd', delimiter=':', quoting=csv.QUOTE_NONE) - - reader = csv.reader(open("passwd", "rb"), 'unixpwd') + reader = csv.reader(open("passwd"), 'unixpwd') A slightly more advanced use of the reader --- catching and reporting errors:: import csv, sys filename = "some.csv" - reader = csv.reader(open(filename, "rb")) + reader = csv.reader(open(filename, newline='')) try: for row in reader: print(row) except csv.Error as e: - sys.exit('file %s, line %d: %s' % (filename, reader.line_num, e)) + sys.exit('file {}, line {}: {}'.format(filename, reader.line_num, e)) And while the module doesn't directly support parsing strings, it can easily be done:: @@ -462,94 +456,10 @@ for row in csv.reader(['one,two,three']): print(row) -The :mod:`csv` module doesn't directly support reading and writing Unicode, but -it is 8-bit-clean save for some problems with ASCII NUL characters. So you can -write functions or classes that handle the encoding and decoding for you as long -as you avoid encodings like UTF-16 that use NULs. UTF-8 is recommended. - -:func:`unicode_csv_reader` below is a :term:`generator` that wraps :class:`csv.reader` -to handle Unicode CSV data (a list of Unicode strings). :func:`utf_8_encoder` -is a :term:`generator` that encodes the Unicode strings as UTF-8, one string (or row) at -a time. The encoded strings are parsed by the CSV reader, and -:func:`unicode_csv_reader` decodes the UTF-8-encoded cells back into Unicode:: - - import csv - def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs): - # csv.py doesn't do Unicode; encode temporarily as UTF-8: - csv_reader = csv.reader(utf_8_encoder(unicode_csv_data), - dialect=dialect, **kwargs) - for row in csv_reader: - # decode UTF-8 back to Unicode, cell by cell: - yield [unicode(cell, 'utf-8') for cell in row] - - def utf_8_encoder(unicode_csv_data): - for line in unicode_csv_data: - yield line.encode('utf-8') - -For all other encodings the following :class:`UnicodeReader` and -:class:`UnicodeWriter` classes can be used. They take an additional *encoding* -parameter in their constructor and make sure that the data passes the real -reader or writer encoded as UTF-8:: - - import csv, codecs, io - - class UTF8Recoder: - """ - Iterator that reads an encoded stream and reencodes the input to UTF-8 - """ - def __init__(self, f, encoding): - self.reader = codecs.getreader(encoding)(f) - - def __iter__(self): - return self - - def __next__(self): - return next(self.reader).encode("utf-8") - - class UnicodeReader: - """ - A CSV reader which will iterate over lines in the CSV file "f", - which is encoded in the given encoding. - """ - - def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds): - f = UTF8Recoder(f, encoding) - self.reader = csv.reader(f, dialect=dialect, **kwds) - - def __next__(self): - row = next(self.reader) - return [unicode(s, "utf-8") for s in row] - - def __iter__(self): - return self - - class UnicodeWriter: - """ - A CSV writer which will write rows to CSV file "f", - which is encoded in the given encoding. - """ - - def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds): - # Redirect output to a queue - self.queue = io.StringIO() - self.writer = csv.writer(self.queue, dialect=dialect, **kwds) - self.stream = f - self.encoder = codecs.getincrementalencoder(encoding)() - - def writerow(self, row): - self.writer.writerow([s.encode("utf-8") for s in row]) - # Fetch UTF-8 output from the queue ... - data = self.queue.getvalue() - data = data.decode("utf-8") - # ... and reencode it into the target encoding - data = self.encoder.encode(data) - # write to the target stream - self.stream.write(data) - # empty queue - self.queue.truncate(0) - - def writerows(self, rows): - for row in rows: - self.writerow(row) +.. rubric:: Footnotes +.. [#] If ``newline=''`` is not specified, newlines embedded inside quoted fields + will not be interpreted correctly. It should always be safe to specify + ``newline=''``, since the csv module does its own universal newline handling + on input. 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 Sat Apr 4 03:38:38 2009 @@ -6,7 +6,7 @@ import sys import os import unittest -from io import StringIO, BytesIO +from io import StringIO from tempfile import TemporaryFile import csv import gc From python-checkins at python.org Sat Apr 4 03:43:10 2009 From: python-checkins at python.org (r.david.murray) Date: Sat, 4 Apr 2009 03:43:10 +0200 (CEST) Subject: [Python-checkins] r71117 - in python/branches/release30-maint: Doc/library/csv.rst Lib/test/test_csv.py Message-ID: <20090404014310.15B541E405C@bag.python.org> Author: r.david.murray Date: Sat Apr 4 03:43:09 2009 New Revision: 71117 Log: Merged revisions 71116 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r71116 | r.david.murray | 2009-04-03 21:38:38 -0400 (Fri, 03 Apr 2009) | 10 lines Update documentation for csv module to reflect changes in code, specifically that it now expects unicode input (and therefore the paragraph about it not handling unicode is deleted, as well as the 'how to handle unicode' examples) and that files should be opened with "newline=''" instead of binary mode. Also removed unused BytesIO import from test_csv. This addresses issue 4847. ........ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Doc/library/csv.rst python/branches/release30-maint/Lib/test/test_csv.py Modified: python/branches/release30-maint/Doc/library/csv.rst ============================================================================== --- python/branches/release30-maint/Doc/library/csv.rst (original) +++ python/branches/release30-maint/Doc/library/csv.rst Sat Apr 4 03:43:09 2009 @@ -33,14 +33,6 @@ write sequences. Programmers can also read and write data in dictionary form using the :class:`DictReader` and :class:`DictWriter` classes. -.. note:: - - This version of the :mod:`csv` module doesn't support Unicode input. Also, - there are currently some issues regarding ASCII NUL characters. Accordingly, - all input should be UTF-8 or printable ASCII to be safe; see the examples in - section :ref:`csv-examples`. These restrictions will be removed in the future. - - .. seealso:: :pep:`305` - CSV File API @@ -60,8 +52,8 @@ Return a reader object which will iterate over lines in the given *csvfile*. *csvfile* can be any object which supports the :term:`iterator` protocol and returns a string each time its :meth:`next` method is called --- file objects and list - objects are both suitable. If *csvfile* is a file object, it must be opened - with the 'b' flag on platforms where that makes a difference. An optional + objects are both suitable. If *csvfile* is a file object, it should be opened + with ``newline=''``. [#]_ An optional *dialect* parameter can be given which is used to define a set of parameters specific to a particular CSV dialect. It may be an instance of a subclass of the :class:`Dialect` class or one of the strings returned by the @@ -70,21 +62,14 @@ dialect. For full details about the dialect and formatting parameters, see section :ref:`csv-fmt-params`. - All data read are returned as strings. No automatic data type conversion is - performed. - - The parser is quite strict with respect to multi-line quoted fields. Previously, - if a line ended within a quoted field without a terminating newline character, a - newline would be inserted into the returned field. This behavior caused problems - when reading files which contained carriage return characters within fields. - The behavior was changed to return the field without inserting newlines. As a - consequence, if newlines embedded within fields are important, the input should - be split into lines in a manner which preserves the newline characters. + Each row read from the csv file is returned as a list of strings. No + automatic data type conversion is performed unless the ``QUOTE_NONNUMERIC`` format + option is specified (in which case unquoted fields are transformed into floats). A short usage example:: >>> import csv - >>> spamReader = csv.reader(open('eggs.csv'), delimiter=' ', quotechar='|') + >>> spamReader = csv.reader(open('eggs.csv', newline=''), delimiter=' ', quotechar='|') >>> for row in spamReader: ... print(', '.join(row)) Spam, Spam, Spam, Spam, Spam, Baked Beans @@ -95,8 +80,7 @@ Return a writer object responsible for converting the user's data into delimited strings on the given file-like object. *csvfile* can be any object with a - :func:`write` method. If *csvfile* is a file object, it must be opened with the - 'b' flag on platforms where that makes a difference. An optional *dialect* + :func:`write` method. An optional *dialect* parameter can be given which is used to define a set of parameters specific to a particular CSV dialect. It may be an instance of a subclass of the :class:`Dialect` class or one of the strings returned by the @@ -270,7 +254,6 @@ Raised by any of the functions when an error is detected. - .. _csv-fmt-params: Dialects and Formatting Parameters @@ -422,41 +405,52 @@ The simplest example of reading a CSV file:: import csv - reader = csv.reader(open("some.csv", "rb")) + reader = csv.reader(open("some.csv", newline='')) for row in reader: print(row) Reading a file with an alternate format:: import csv - reader = csv.reader(open("passwd", "rb"), delimiter=':', quoting=csv.QUOTE_NONE) + reader = csv.reader(open("passwd"), delimiter=':', quoting=csv.QUOTE_NONE) for row in reader: print(row) The corresponding simplest possible writing example is:: import csv - writer = csv.writer(open("some.csv", "wb")) + writer = csv.writer(open("some.csv", "w")) writer.writerows(someiterable) +Since :func:`open` is used to open a CSV file for reading, the file +will by default be decoded into unicode using the system default +encoding (see :func:`locale.getpreferredencoding`). To decode a file +using a different encoding, use the ``encoding`` argument of open:: + + import csv + reader = csv.reader(open("some.csv", newline='', encoding='utf-8')) + for row in reader: + print(row) + +The same applies to writing in something other than the system default +encoding: specify the encoding argument when opening the output file. + Registering a new dialect:: import csv - csv.register_dialect('unixpwd', delimiter=':', quoting=csv.QUOTE_NONE) - - reader = csv.reader(open("passwd", "rb"), 'unixpwd') + reader = csv.reader(open("passwd"), 'unixpwd') A slightly more advanced use of the reader --- catching and reporting errors:: import csv, sys filename = "some.csv" - reader = csv.reader(open(filename, "rb")) + reader = csv.reader(open(filename, newline='')) try: for row in reader: print(row) except csv.Error as e: - sys.exit('file %s, line %d: %s' % (filename, reader.line_num, e)) + sys.exit('file {}, line {}: {}'.format(filename, reader.line_num, e)) And while the module doesn't directly support parsing strings, it can easily be done:: @@ -465,94 +459,10 @@ for row in csv.reader(['one,two,three']): print(row) -The :mod:`csv` module doesn't directly support reading and writing Unicode, but -it is 8-bit-clean save for some problems with ASCII NUL characters. So you can -write functions or classes that handle the encoding and decoding for you as long -as you avoid encodings like UTF-16 that use NULs. UTF-8 is recommended. - -:func:`unicode_csv_reader` below is a :term:`generator` that wraps :class:`csv.reader` -to handle Unicode CSV data (a list of Unicode strings). :func:`utf_8_encoder` -is a :term:`generator` that encodes the Unicode strings as UTF-8, one string (or row) at -a time. The encoded strings are parsed by the CSV reader, and -:func:`unicode_csv_reader` decodes the UTF-8-encoded cells back into Unicode:: - - import csv - def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs): - # csv.py doesn't do Unicode; encode temporarily as UTF-8: - csv_reader = csv.reader(utf_8_encoder(unicode_csv_data), - dialect=dialect, **kwargs) - for row in csv_reader: - # decode UTF-8 back to Unicode, cell by cell: - yield [unicode(cell, 'utf-8') for cell in row] - - def utf_8_encoder(unicode_csv_data): - for line in unicode_csv_data: - yield line.encode('utf-8') - -For all other encodings the following :class:`UnicodeReader` and -:class:`UnicodeWriter` classes can be used. They take an additional *encoding* -parameter in their constructor and make sure that the data passes the real -reader or writer encoded as UTF-8:: - - import csv, codecs, io - - class UTF8Recoder: - """ - Iterator that reads an encoded stream and reencodes the input to UTF-8 - """ - def __init__(self, f, encoding): - self.reader = codecs.getreader(encoding)(f) - - def __iter__(self): - return self - - def __next__(self): - return next(self.reader).encode("utf-8") - - class UnicodeReader: - """ - A CSV reader which will iterate over lines in the CSV file "f", - which is encoded in the given encoding. - """ - - def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds): - f = UTF8Recoder(f, encoding) - self.reader = csv.reader(f, dialect=dialect, **kwds) - - def __next__(self): - row = next(self.reader) - return [unicode(s, "utf-8") for s in row] - - def __iter__(self): - return self - - class UnicodeWriter: - """ - A CSV writer which will write rows to CSV file "f", - which is encoded in the given encoding. - """ - - def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds): - # Redirect output to a queue - self.queue = io.StringIO() - self.writer = csv.writer(self.queue, dialect=dialect, **kwds) - self.stream = f - self.encoder = codecs.getincrementalencoder(encoding)() - - def writerow(self, row): - self.writer.writerow([s.encode("utf-8") for s in row]) - # Fetch UTF-8 output from the queue ... - data = self.queue.getvalue() - data = data.decode("utf-8") - # ... and reencode it into the target encoding - data = self.encoder.encode(data) - # write to the target stream - self.stream.write(data) - # empty queue - self.queue.truncate(0) - - def writerows(self, rows): - for row in rows: - self.writerow(row) +.. rubric:: Footnotes +.. [#] If ``newline=''`` is not specified, newlines embedded inside quoted fields + will not be interpreted correctly. It should always be safe to specify + ``newline=''``, since the csv module does its own universal newline handling + on input. Modified: python/branches/release30-maint/Lib/test/test_csv.py ============================================================================== --- python/branches/release30-maint/Lib/test/test_csv.py (original) +++ python/branches/release30-maint/Lib/test/test_csv.py Sat Apr 4 03:43:09 2009 @@ -6,7 +6,7 @@ import sys import os import unittest -from io import StringIO, BytesIO +from io import StringIO from tempfile import TemporaryFile import csv import gc From buildbot at python.org Sat Apr 4 04:02:39 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 02:02:39 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 3.x Message-ID: <20090404020240.475221E4066@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%20gentoo%203.x/builds/556 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-amd64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_codecs test_io ====================================================================== ERROR: test_basics (test.test_codecs.BasicUnicodeTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_codecs.py", line 1344, in test_basics encodedresult += encoder.encode(c) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 22, in encode return codecs.ascii_encode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_encode' ====================================================================== ERROR: test_decoder_state (test.test_codecs.BasicUnicodeTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_codecs.py", line 1429, in test_decoder_state self.check_state_handling_decode(encoding, u, u.encode(encoding)) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_codecs.py", line 30, in check_state_handling_decode part1 = d.decode(s[:i]) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_basic_io (test.test_io.CTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1601, in test_basic_io self.assertEquals(f.read(), "abc") File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_encoding_errors_reading (test.test_io.CTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1425, in test_encoding_errors_reading self.assertRaises(UnicodeError, t.read) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/unittest.py", line 450, in failUnlessRaises callableObj(*args, **kwargs) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_issue1395_1 (test.test_io.CTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1792, in test_issue1395_1 c = txt.read(1) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_issue1395_2 (test.test_io.CTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1804, in test_issue1395_2 c = txt.read(4) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_issue1395_3 (test.test_io.CTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1814, in test_issue1395_3 reads = txt.read(4) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_issue1395_4 (test.test_io.CTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1825, in test_issue1395_4 reads = txt.read(4) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_issue1395_5 (test.test_io.CTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1833, in test_issue1395_5 reads = txt.read(4) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_newlines_input (test.test_io.CTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1517, in test_newlines_input self.assertEquals(txt.readlines(), expected) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_basic_io (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1596, in test_basic_io self.assertEquals(f.write("abc"), 3) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1471, in write b = encoder.encode(s) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 22, in encode return codecs.ascii_encode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_encode' ====================================================================== ERROR: test_destructor (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1548, in test_destructor t.write("abc") File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1471, in write b = encoder.encode(s) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 22, in encode return codecs.ascii_encode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_encode' ====================================================================== ERROR: test_encoding_errors_reading (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1425, in test_encoding_errors_reading self.assertRaises(UnicodeError, t.read) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/unittest.py", line 450, in failUnlessRaises callableObj(*args, **kwargs) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1707, in read decoder.decode(self.buffer.read(), final=True)) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1264, in decode output = self.decoder.decode(input, final=final) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_encoding_errors_writing (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1443, in test_encoding_errors_writing self.assertRaises(UnicodeError, t.write, "\xff") File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/unittest.py", line 450, in failUnlessRaises callableObj(*args, **kwargs) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1471, in write b = encoder.encode(s) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 22, in encode return codecs.ascii_encode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_encode' ====================================================================== ERROR: test_issue1395_1 (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1792, in test_issue1395_1 c = txt.read(1) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1716, in read eof = not self._read_chunk() File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1542, in _read_chunk self._set_decoded_chars(self._decoder.decode(input_chunk, eof)) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1264, in decode output = self.decoder.decode(input, final=final) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_issue1395_2 (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1804, in test_issue1395_2 c = txt.read(4) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1716, in read eof = not self._read_chunk() File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1542, in _read_chunk self._set_decoded_chars(self._decoder.decode(input_chunk, eof)) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1264, in decode output = self.decoder.decode(input, final=final) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_issue1395_3 (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1814, in test_issue1395_3 reads = txt.read(4) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1716, in read eof = not self._read_chunk() File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1542, in _read_chunk self._set_decoded_chars(self._decoder.decode(input_chunk, eof)) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1264, in decode output = self.decoder.decode(input, final=final) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_issue1395_4 (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1825, in test_issue1395_4 reads = txt.read(4) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1716, in read eof = not self._read_chunk() File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1542, in _read_chunk self._set_decoded_chars(self._decoder.decode(input_chunk, eof)) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1264, in decode output = self.decoder.decode(input, final=final) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_issue1395_5 (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1833, in test_issue1395_5 reads = txt.read(4) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1716, in read eof = not self._read_chunk() File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1542, in _read_chunk self._set_decoded_chars(self._decoder.decode(input_chunk, eof)) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1264, in decode output = self.decoder.decode(input, final=final) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_newlines_input (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1517, in test_newlines_input self.assertEquals(txt.readlines(), expected) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 490, in readlines return list(self) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1722, in __next__ line = self.readline() File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1797, in readline while self._read_chunk(): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1542, in _read_chunk self._set_decoded_chars(self._decoder.decode(input_chunk, eof)) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1264, in decode output = self.decoder.decode(input, final=final) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_newlines_output (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1532, in test_newlines_output txt.write("AAA\nB") File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1471, in write b = encoder.encode(s) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 22, in encode return codecs.ascii_encode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_encode' make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Sat Apr 4 05:28:37 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 03:28:37 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090404032837.BD5091E4067@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/247 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_posix test_subprocess ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From python-checkins at python.org Sat Apr 4 05:37:26 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 05:37:26 +0200 (CEST) Subject: [Python-checkins] r71118 - python/branches/py3k Message-ID: <20090404033726.8319A1E4067@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 05:37:26 2009 New Revision: 71118 Log: Blocked revisions 70176,70178,70197,70261,70267,70271,70273,70286,70290,70292-70293,70295-70296,70298,70300,70305,70315,70319,70368,70443,70454,70463,70466,70470-70473,70475,70477,70479,70485,70531,70533,70538,70544,70552-70553,70564,70601,70651,70672,70702,70711-70714,70716,70719,70723,70734,70747,70757,70764-70765,70768-70773,70775-70777,70788-70789,70807,70821,70824-70825,70828,70830,70832,70836-70838,70842,70844,70851,70855-70858,70864,70866-70874,70876-70878,70883,70885,70893-70894,70896-70897,70901-70908,70912,70915,70918,70927,70933-70934,70939-70940,70944,70951,70958,70960,70962-70964,70968-70969,70980-70981,70986,70993-70994,70998,71001,71004,71006,71008-71011,71019,71022-71024,71026,71029,71031-71033,71036-71037,71041,71043,71056,71058-71059,71070,71073,71075,71078 via svnmerge ........ r70176 | ronald.oussoren | 2009-03-04 15:35:05 -0600 (Wed, 04 Mar 2009) | 2 lines Fixes issues 3883 and 5194 ........ r70178 | ronald.oussoren | 2009-03-04 16:49:36 -0600 (Wed, 04 Mar 2009) | 2 lines Fix for issue #1113328. ........ r70197 | jesus.cea | 2009-03-05 13:37:37 -0600 (Thu, 05 Mar 2009) | 1 line Minor bsddb documentation glitch ........ r70261 | raymond.hettinger | 2009-03-09 06:31:39 -0500 (Mon, 09 Mar 2009) | 1 line Issue 5443: Fix typo. ........ r70267 | raymond.hettinger | 2009-03-09 06:57:29 -0500 (Mon, 09 Mar 2009) | 1 line Add consume() recipe to itertools docs. ........ r70271 | raymond.hettinger | 2009-03-09 07:56:23 -0500 (Mon, 09 Mar 2009) | 1 line Add cross-reference to the collections docs. ........ r70273 | georg.brandl | 2009-03-09 09:25:07 -0500 (Mon, 09 Mar 2009) | 2 lines #5458: add a note when we started to raise RuntimeErrors. ........ r70286 | raymond.hettinger | 2009-03-09 19:06:05 -0500 (Mon, 09 Mar 2009) | 1 line Fix markup. ........ r70290 | raymond.hettinger | 2009-03-09 20:07:30 -0500 (Mon, 09 Mar 2009) | 1 line Update url for the spec. ........ r70292 | raymond.hettinger | 2009-03-09 23:40:24 -0500 (Mon, 09 Mar 2009) | 1 line Clarify the meaning of normal and subnormal. ........ r70293 | raymond.hettinger | 2009-03-09 23:49:21 -0500 (Mon, 09 Mar 2009) | 1 line Add a version tag to the decimal module. ........ r70295 | raymond.hettinger | 2009-03-10 03:16:05 -0500 (Tue, 10 Mar 2009) | 1 line Update the decimal FAQ for the from_float() classmethod and improve the recipe for remove_exponent() to make it cut and pasteable. ........ r70296 | raymond.hettinger | 2009-03-10 04:31:48 -0500 (Tue, 10 Mar 2009) | 1 line Small optimization for corner case where maxlen==0. ........ r70298 | raymond.hettinger | 2009-03-10 07:50:59 -0500 (Tue, 10 Mar 2009) | 1 line For collections.deque() objects, expose the maxlen parameter as a read-only attribute. ........ r70300 | raymond.hettinger | 2009-03-10 08:04:30 -0500 (Tue, 10 Mar 2009) | 1 line Fix typo. ........ r70305 | brett.cannon | 2009-03-10 23:51:06 -0500 (Tue, 10 Mar 2009) | 5 lines Require implementations for warnings.showwarning() support the 'line' argument. Was a DeprecationWarning for not supporting it since Python 2.6. Closes issue #3652. ........ r70315 | raymond.hettinger | 2009-03-11 19:25:03 -0500 (Wed, 11 Mar 2009) | 1 line Add reference to solution for a commonly asked question. ........ r70319 | raymond.hettinger | 2009-03-11 19:31:58 -0500 (Wed, 11 Mar 2009) | 1 line Issue 5477: Fix buglet in the itertools documentation. ........ r70368 | eric.smith | 2009-03-14 09:37:38 -0500 (Sat, 14 Mar 2009) | 1 line Unicode format tests weren't actually testing unicode. This was probably due to the original backport from py3k. ........ r70443 | bob.ippolito | 2009-03-17 18:19:00 -0500 (Tue, 17 Mar 2009) | 1 line merge json library with simplejson 2.0.9 (issue 4136) ........ r70454 | mark.dickinson | 2009-03-18 11:07:26 -0500 (Wed, 18 Mar 2009) | 9 lines Issue 4474: On platforms with sizeof(wchar_t) == 4 and sizeof(Py_UNICODE) == 2, PyUnicode_FromWideChar now converts each character outside the BMP to the appropriate surrogate pair. Thanks Victor Stinner for the patch. (backport of r70452 from py3k to trunk) ........ r70463 | benjamin.peterson | 2009-03-18 15:52:15 -0500 (Wed, 18 Mar 2009) | 1 line fix strange errors when setting attributes on tracebacks #4034 ........ r70466 | raymond.hettinger | 2009-03-18 17:13:20 -0500 (Wed, 18 Mar 2009) | 1 line Use mixin methods where possible. (2.7 only -- these don't all exist in 3.0) ........ r70470 | raymond.hettinger | 2009-03-19 10:21:10 -0500 (Thu, 19 Mar 2009) | 6 lines Improve implementation with better underlying data structure for O(1) deletions. Big-Oh performance now the same as regular dictionaries. Uses a doubly-linked list instead of a list/seq to track insertion order. ........ r70471 | raymond.hettinger | 2009-03-19 14:19:03 -0500 (Thu, 19 Mar 2009) | 3 lines Issue 5381: Add object_pairs_hook to the json module. ........ r70472 | raymond.hettinger | 2009-03-19 14:24:43 -0500 (Thu, 19 Mar 2009) | 1 line Silence a compiler warning. ........ r70473 | raymond.hettinger | 2009-03-19 14:59:58 -0500 (Thu, 19 Mar 2009) | 6 lines * Add clearer comment to initialization code. * Add optional argument to popitem() -- modeled after Anthon van der Neut's C version. * Fix method markup in docs. ........ r70475 | raymond.hettinger | 2009-03-19 18:12:41 -0500 (Thu, 19 Mar 2009) | 6 lines * Add implementation notes. * Re-order methods so that those touching the underlying data structure come first and the derived methods come last. ........ r70477 | raymond.hettinger | 2009-03-19 18:22:25 -0500 (Thu, 19 Mar 2009) | 1 line Fix typo ........ r70479 | mark.dickinson | 2009-03-20 10:51:55 -0500 (Fri, 20 Mar 2009) | 3 lines Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms. Backport of r70459. ........ r70485 | raymond.hettinger | 2009-03-20 13:25:49 -0500 (Fri, 20 Mar 2009) | 1 line Add MutableSet example. ........ r70531 | benjamin.peterson | 2009-03-22 17:24:58 -0500 (Sun, 22 Mar 2009) | 1 line AttributeError can be thrown during recursion errors ........ r70533 | raymond.hettinger | 2009-03-22 19:08:09 -0500 (Sun, 22 Mar 2009) | 6 lines Add more comments. Improve variable names. Make links clearer by using a Link object instead of a list. Use proxy links to avoid circular references. ........ r70538 | raymond.hettinger | 2009-03-22 23:42:18 -0500 (Sun, 22 Mar 2009) | 1 line Move initialization of root link to __init__. ........ r70544 | raymond.hettinger | 2009-03-23 13:26:59 -0500 (Mon, 23 Mar 2009) | 1 line Make imported name private and wrap long-line. ........ r70552 | benjamin.peterson | 2009-03-23 15:47:59 -0500 (Mon, 23 Mar 2009) | 1 line fix very old names for exception terms #5543 ........ r70553 | benjamin.peterson | 2009-03-23 16:23:30 -0500 (Mon, 23 Mar 2009) | 1 line revert r70552; wrong fix ........ r70564 | raymond.hettinger | 2009-03-23 19:17:11 -0500 (Mon, 23 Mar 2009) | 1 line Add links to related resources. ........ r70601 | raymond.hettinger | 2009-03-25 17:41:32 -0500 (Wed, 25 Mar 2009) | 1 line Separate initialization from clearing. ........ r70651 | guilherme.polo | 2009-03-28 14:17:16 -0500 (Sat, 28 Mar 2009) | 1 line Typo fix ........ r70672 | collin.winter | 2009-03-28 22:44:19 -0500 (Sat, 28 Mar 2009) | 4 lines Add the ability to control the random seed used by regrtest.py -r. This adds a --randseed option, and makes regrtest.py -r indicate what random seed it's using so that that value can later be fed back to --randseed. This option is useful for tracking down test order-related issues found by make buildbottest, for example. ........ r70702 | bob.ippolito | 2009-03-29 17:33:58 -0500 (Sun, 29 Mar 2009) | 1 line Issue 5381: fix regression in pure python code path, Issue 5584: fix a decoder bug for unicode float literals outside of a container ........ r70711 | r.david.murray | 2009-03-30 10:14:01 -0500 (Mon, 30 Mar 2009) | 2 lines Convert import try/except to use test_support.import_module(). ........ r70712 | benjamin.peterson | 2009-03-30 10:15:38 -0500 (Mon, 30 Mar 2009) | 1 line don't rely on the order dict repr #5605 ........ r70713 | ronald.oussoren | 2009-03-30 10:20:46 -0500 (Mon, 30 Mar 2009) | 2 lines This patch fixes issue 1254695 (wrong argument type conversion in Carbon.Qt) ........ r70714 | brett.cannon | 2009-03-30 10:20:53 -0500 (Mon, 30 Mar 2009) | 1 line Add an entry to developers.txt. ........ r70716 | r.david.murray | 2009-03-30 10:30:34 -0500 (Mon, 30 Mar 2009) | 2 lines Revert incorrect change. ........ r70719 | ronald.oussoren | 2009-03-30 11:01:51 -0500 (Mon, 30 Mar 2009) | 2 lines Fix for issue 896199 (some Carbon modules aren't present in the documentation) ........ r70723 | kurt.kaiser | 2009-03-30 11:22:00 -0500 (Mon, 30 Mar 2009) | 1 line Tk 8.5 Text widget requires 'wordprocessor' tabstyle attr to handle mixed space/tab properly. Issue 5120, patch by Guilherme Polo. ........ r70734 | r.david.murray | 2009-03-30 14:04:00 -0500 (Mon, 30 Mar 2009) | 7 lines Add import_function method to test.test_support, and modify a number of tests that expect to be skipped if imports fail or functions don't exist to use import_function and import_module. The ultimate goal is to change regrtest to not skip automatically on ImportError. Checking in now to make sure the buldbots don't show any errors on platforms I can't direct test on. ........ r70747 | r.david.murray | 2009-03-30 15:04:06 -0500 (Mon, 30 Mar 2009) | 3 lines Remove references to test_socket_ssl which was deleted in trunk in r64392 and py3k in r59038. ........ r70757 | senthil.kumaran | 2009-03-30 16:51:50 -0500 (Mon, 30 Mar 2009) | 3 lines Fix for bugs: Issue4675 and Issue4962. ........ r70764 | martin.v.loewis | 2009-03-30 17:06:33 -0500 (Mon, 30 Mar 2009) | 2 lines Add several VM developers. ........ r70765 | georg.brandl | 2009-03-30 17:09:34 -0500 (Mon, 30 Mar 2009) | 1 line #5199: make warning about vars() assignment more visible. ........ r70768 | andrew.kuchling | 2009-03-30 17:29:15 -0500 (Mon, 30 Mar 2009) | 1 line Typo fixes ........ r70769 | andrew.kuchling | 2009-03-30 17:29:53 -0500 (Mon, 30 Mar 2009) | 1 line Remove comment ........ r70770 | andrew.kuchling | 2009-03-30 17:30:20 -0500 (Mon, 30 Mar 2009) | 1 line Add several items and placeholders ........ r70771 | andrew.kuchling | 2009-03-30 17:31:11 -0500 (Mon, 30 Mar 2009) | 1 line Many edits ........ r70772 | barry.warsaw | 2009-03-30 17:42:17 -0500 (Mon, 30 Mar 2009) | 5 lines A fix for issue 1974, inspired by the patch from Andi Albrecht (aalbrecht), though with some changes by me. This patch should not be back ported or forward ported. It's a bit too risky for 2.6 and 3.x does things fairly differently. ........ r70773 | georg.brandl | 2009-03-30 17:43:00 -0500 (Mon, 30 Mar 2009) | 1 line #5039: make it clear that the impl. note refers to CPython. ........ r70775 | r.david.murray | 2009-03-30 18:05:48 -0500 (Mon, 30 Mar 2009) | 4 lines Change more tests to use import_module for the modules that should cause tests to be skipped. Also rename import_function to the more descriptive get_attribute and add a docstring. ........ r70776 | andrew.kuchling | 2009-03-30 18:08:24 -0500 (Mon, 30 Mar 2009) | 1 line typo fix ........ r70777 | andrew.kuchling | 2009-03-30 18:09:46 -0500 (Mon, 30 Mar 2009) | 1 line Add more items ........ r70788 | andrew.kuchling | 2009-03-30 20:21:01 -0500 (Mon, 30 Mar 2009) | 1 line Add various items ........ r70789 | georg.brandl | 2009-03-30 20:25:15 -0500 (Mon, 30 Mar 2009) | 1 line Fix a wrong struct field assignment (docstring as closure). ........ r70807 | jeremy.hylton | 2009-03-31 08:31:00 -0500 (Tue, 31 Mar 2009) | 2 lines Update quicktest to match Python 3 branch ........ r70821 | jeremy.hylton | 2009-03-31 10:04:15 -0500 (Tue, 31 Mar 2009) | 2 lines Add check for PyDict_Update() error. ........ r70824 | georg.brandl | 2009-03-31 10:43:20 -0500 (Tue, 31 Mar 2009) | 1 line #5519: remove reference to Kodos, which seems dead. ........ r70825 | georg.brandl | 2009-03-31 10:46:30 -0500 (Tue, 31 Mar 2009) | 1 line #5566: fix versionadded from PyLong ssize_t functions. ........ r70828 | georg.brandl | 2009-03-31 10:50:16 -0500 (Tue, 31 Mar 2009) | 1 line #5581: fget argument of abstractproperty is optional as well. ........ r70830 | georg.brandl | 2009-03-31 11:11:45 -0500 (Tue, 31 Mar 2009) | 1 line #5529: backport new docs of import semantics written by Brett to 2.x. ........ r70832 | georg.brandl | 2009-03-31 11:31:11 -0500 (Tue, 31 Mar 2009) | 1 line #1386675: specify WindowsError as the exception, because it has a winerror attribute that EnvironmentError doesnt have. ........ r70836 | georg.brandl | 2009-03-31 11:50:25 -0500 (Tue, 31 Mar 2009) | 1 line #5417: replace references to undocumented functions by ones to documented functions. ........ r70837 | gregory.p.smith | 2009-03-31 11:54:10 -0500 (Tue, 31 Mar 2009) | 9 lines The unittest.TestCase.assertEqual() now displays the differences in lists, tuples, dicts and sets on failure. Many new handy type and comparison specific assert* methods have been added that fail with error messages actually useful for debugging. Contributed in by Google and completed with help from mfoord and GvR at PyCon 2009 sprints. Discussion lives in http://bugs.python.org/issue2578. ........ r70838 | georg.brandl | 2009-03-31 11:54:38 -0500 (Tue, 31 Mar 2009) | 1 line #992207: document that the parser only accepts \\n newlines. ........ r70842 | georg.brandl | 2009-03-31 12:13:06 -0500 (Tue, 31 Mar 2009) | 1 line #970783: document PyObject_Generic[GS]etAttr. ........ r70844 | raymond.hettinger | 2009-03-31 12:47:06 -0500 (Tue, 31 Mar 2009) | 1 line Per the language summit, the optional fastpath imports should use from-import-star. ........ r70851 | georg.brandl | 2009-03-31 13:26:55 -0500 (Tue, 31 Mar 2009) | 1 line #837577: note cryptic return value of spawn*e on invalid env dicts. ........ r70855 | georg.brandl | 2009-03-31 13:30:37 -0500 (Tue, 31 Mar 2009) | 1 line #5245: note that PyRun_SimpleString doesnt return on SystemExit. ........ r70856 | r.david.murray | 2009-03-31 13:32:17 -0500 (Tue, 31 Mar 2009) | 7 lines A few more test skips via import_module, and change import_module to return the error message produced by importlib, so that if an import in the package whose import is being wrapped is what failed the skip message will contain the name of that module instead of the name of the wrapped module. Also fixed formatting of some previous comments. ........ r70857 | georg.brandl | 2009-03-31 13:33:10 -0500 (Tue, 31 Mar 2009) | 1 line #5227: note that Py_Main doesnt return on SystemExit. ........ r70858 | georg.brandl | 2009-03-31 13:38:56 -0500 (Tue, 31 Mar 2009) | 1 line #5241: document missing U in regex howto. ........ r70864 | gregory.p.smith | 2009-03-31 14:03:28 -0500 (Tue, 31 Mar 2009) | 10 lines Rename the actual method definitions to the official assertFoo names. Adds unittests to make sure the old fail* names continue to work now and adds a comment that they are pending deprecation. Also adds a test to confirm that the plural Equals method variants continue to exist even though we're unlikely to deprecate those. http://bugs.python.org/issue2578 ........ r70866 | georg.brandl | 2009-03-31 14:06:57 -0500 (Tue, 31 Mar 2009) | 1 line #4882: document named group behavior a bit better. ........ r70867 | georg.brandl | 2009-03-31 14:10:35 -0500 (Tue, 31 Mar 2009) | 1 line #1096310: document usage of sys.__std*__ a bit better. ........ r70868 | georg.brandl | 2009-03-31 14:12:17 -0500 (Tue, 31 Mar 2009) | 1 line #5190: export make_option in __all__. ........ r70869 | georg.brandl | 2009-03-31 14:14:42 -0500 (Tue, 31 Mar 2009) | 1 line Fix-up unwanted change. ........ r70870 | georg.brandl | 2009-03-31 14:26:24 -0500 (Tue, 31 Mar 2009) | 1 line #4411: document mro() and __mro__. (I hope I got it right.) ........ r70871 | georg.brandl | 2009-03-31 14:30:56 -0500 (Tue, 31 Mar 2009) | 1 line #5618: fix typo. ........ r70872 | r.david.murray | 2009-03-31 14:31:17 -0500 (Tue, 31 Mar 2009) | 3 lines Delete out-of-date and little-known README from the test directory by consensus of devs at pycon sprint. ........ r70873 | josiah.carlson | 2009-03-31 14:32:34 -0500 (Tue, 31 Mar 2009) | 2 lines This resolves issue 1161031. Tests pass. ........ r70874 | r.david.murray | 2009-03-31 14:33:15 -0500 (Tue, 31 Mar 2009) | 5 lines Improve test_support.import_module docstring, remove deprecated flag from get_attribute since it isn't likely to do anything useful. ........ r70876 | r.david.murray | 2009-03-31 14:49:15 -0500 (Tue, 31 Mar 2009) | 4 lines Remove the regrtest check that turns any ImportError into a skipped test. Hopefully all modules whose imports legitimately result in a skipped test have been properly wrapped by the previous commits. ........ r70877 | r.david.murray | 2009-03-31 14:57:24 -0500 (Tue, 31 Mar 2009) | 2 lines Add NEWS entry for regrtest change. ........ r70878 | gregory.p.smith | 2009-03-31 14:59:14 -0500 (Tue, 31 Mar 2009) | 3 lines Issue an actual PendingDeprecationWarning for the TestCase.fail* methods. Document the deprecation. ........ r70883 | georg.brandl | 2009-03-31 15:41:08 -0500 (Tue, 31 Mar 2009) | 1 line #1674032: return value of flag from Event.wait(). OKed by Guido. ........ r70885 | tarek.ziade | 2009-03-31 15:48:31 -0500 (Tue, 31 Mar 2009) | 1 line using log.warn for sys.stderr ........ r70893 | georg.brandl | 2009-03-31 15:56:32 -0500 (Tue, 31 Mar 2009) | 1 line #1530012: move TQS section before raw strings. ........ r70894 | benjamin.peterson | 2009-03-31 16:06:30 -0500 (Tue, 31 Mar 2009) | 1 line take the usual lock precautions around _active_limbo_lock ........ r70896 | georg.brandl | 2009-03-31 16:15:33 -0500 (Tue, 31 Mar 2009) | 1 line #5598: document DocFileSuite *args argument. ........ r70897 | benjamin.peterson | 2009-03-31 16:34:42 -0500 (Tue, 31 Mar 2009) | 1 line fix Thread.ident when it is the main thread or a dummy thread #5632 ........ r70901 | georg.brandl | 2009-03-31 16:40:24 -0500 (Tue, 31 Mar 2009) | 2 lines Remove warning about pending Win9x support removal. ........ r70902 | georg.brandl | 2009-03-31 16:43:03 -0500 (Tue, 31 Mar 2009) | 1 line #1675026: add a note about a strange Windows problem, and remove notes about AtheOS. ........ r70903 | georg.brandl | 2009-03-31 16:45:18 -0500 (Tue, 31 Mar 2009) | 1 line #1676135: remove trailing slashes from --prefix argument. ........ r70904 | josiah.carlson | 2009-03-31 16:49:36 -0500 (Tue, 31 Mar 2009) | 3 lines Made handle_expt_event() be called last, so that we don't accidentally read after closing the socket. ........ r70905 | georg.brandl | 2009-03-31 17:03:40 -0500 (Tue, 31 Mar 2009) | 1 line #5563: more documentation for bdist_msi. ........ r70906 | georg.brandl | 2009-03-31 17:11:53 -0500 (Tue, 31 Mar 2009) | 1 line #1651995: fix _convert_ref for non-ASCII characters. ........ r70907 | georg.brandl | 2009-03-31 17:18:19 -0500 (Tue, 31 Mar 2009) | 1 line #3427: document correct return type for urlopen().info(). ........ r70908 | jesse.noller | 2009-03-31 17:20:35 -0500 (Tue, 31 Mar 2009) | 1 line Issue 5619: Pass MS CRT debug flags into subprocesses ........ r70912 | georg.brandl | 2009-03-31 17:35:46 -0500 (Tue, 31 Mar 2009) | 1 line #5617: add a handy function to print a unicode string to gdbinit. ........ r70915 | georg.brandl | 2009-03-31 17:40:16 -0500 (Tue, 31 Mar 2009) | 1 line #5018: remove confusing paragraph. ........ r70918 | raymond.hettinger | 2009-03-31 17:43:03 -0500 (Tue, 31 Mar 2009) | 1 line Improve examples for collections.deque() ........ r70927 | georg.brandl | 2009-03-31 18:01:27 -0500 (Tue, 31 Mar 2009) | 1 line Dont shout to users. ........ r70933 | georg.brandl | 2009-03-31 19:04:33 -0500 (Tue, 31 Mar 2009) | 2 lines Issue #5635: Fix running test_sys with tracing enabled. ........ r70934 | josiah.carlson | 2009-03-31 20:28:11 -0500 (Tue, 31 Mar 2009) | 2 lines Fix for failing asyncore tests. ........ r70939 | jesse.noller | 2009-03-31 22:45:50 -0500 (Tue, 31 Mar 2009) | 1 line Fix multiprocessing.event to match the new threading.Event API ........ r70940 | georg.brandl | 2009-03-31 23:21:14 -0500 (Tue, 31 Mar 2009) | 2 lines The SimpleXMLRPCServer's CGI handler now runs like a pony. ........ r70944 | georg.brandl | 2009-03-31 23:32:39 -0500 (Tue, 31 Mar 2009) | 1 line #5631: add upload to list of possible commands, which is presented in --help-commands. ........ r70951 | georg.brandl | 2009-04-01 09:02:27 -0500 (Wed, 01 Apr 2009) | 1 line Add Maksim, who worked on several issues at the sprint. ........ r70958 | kristjan.jonsson | 2009-04-01 11:08:34 -0500 (Wed, 01 Apr 2009) | 3 lines http://bugs.python.org/issue5623 Dynamically discoverd the size of the ioinfo struct used by the crt for its file descriptors. This should work across all flavors of the CRT. Thanks to Amaury Forgeot d'Arc Needs porting to 3.1 ........ r70960 | jesse.noller | 2009-04-01 11:42:19 -0500 (Wed, 01 Apr 2009) | 1 line Issue 3270: document Listener address restrictions on windows ........ r70962 | brett.cannon | 2009-04-01 12:07:16 -0500 (Wed, 01 Apr 2009) | 2 lines Ron DuPlain was given commit privileges at PyCon 2009 to work on 3to2. ........ r70963 | georg.brandl | 2009-04-01 12:46:01 -0500 (Wed, 01 Apr 2009) | 1 line #5655: fix docstring oversight. ........ r70964 | brett.cannon | 2009-04-01 12:52:13 -0500 (Wed, 01 Apr 2009) | 2 lines Paul Kippes was given commit privileges to work on 3to2. ........ r70968 | michael.foord | 2009-04-01 13:25:38 -0500 (Wed, 01 Apr 2009) | 1 line Adding Wing project file ........ r70969 | raymond.hettinger | 2009-04-01 13:50:56 -0500 (Wed, 01 Apr 2009) | 1 line Issue #5647: MutableSet.__iand__() no longer mutates self during iteration. ........ r70980 | jack.diederich | 2009-04-01 15:26:13 -0500 (Wed, 01 Apr 2009) | 3 lines bounds check arguments to mmap.move(). All of them. Really. fixes crasher on OS X 10.5 ........ r70981 | senthil.kumaran | 2009-04-01 15:26:33 -0500 (Wed, 01 Apr 2009) | 3 lines Fix for issue5040. Adding test for Content-Length ........ r70986 | raymond.hettinger | 2009-04-01 15:50:58 -0500 (Wed, 01 Apr 2009) | 1 line Add link to an alternative generator with a long-period. ........ r70993 | georg.brandl | 2009-04-01 16:05:44 -0500 (Wed, 01 Apr 2009) | 1 line Add NEWS item. ........ r70994 | georg.brandl | 2009-04-01 16:06:30 -0500 (Wed, 01 Apr 2009) | 1 line Revert accidental checkin. ........ r70998 | georg.brandl | 2009-04-01 16:54:21 -0500 (Wed, 01 Apr 2009) | 1 line In Pdb, stop assigning values to __builtin__._ which interferes with the one commonly installed by gettext. ........ r71001 | brett.cannon | 2009-04-01 18:01:12 -0500 (Wed, 01 Apr 2009) | 3 lines Add my initials to Misc/developers.txt. Names are now sorted by number of characters in the person's name. ........ r71004 | benjamin.peterson | 2009-04-01 18:15:49 -0500 (Wed, 01 Apr 2009) | 1 line remove double underscores ........ r71006 | georg.brandl | 2009-04-01 18:32:17 -0500 (Wed, 01 Apr 2009) | 1 line Cache the f_locals dict of the current frame, since every access to frame.f_locals overrides its contents with the real locals which undoes modifications made by the debugging user. ........ r71008 | andrew.kuchling | 2009-04-01 19:02:14 -0500 (Wed, 01 Apr 2009) | 1 line Typo fix ........ r71009 | jesse.noller | 2009-04-01 19:03:28 -0500 (Wed, 01 Apr 2009) | 1 line issue5545: Switch to Autoconf for multiprocessing; special thanks to Martin Lowis for help ........ r71010 | benjamin.peterson | 2009-04-01 19:11:52 -0500 (Wed, 01 Apr 2009) | 1 line fix markup ........ r71011 | benjamin.peterson | 2009-04-01 19:12:47 -0500 (Wed, 01 Apr 2009) | 1 line this should be :noindex: ........ r71019 | georg.brandl | 2009-04-01 21:00:01 -0500 (Wed, 01 Apr 2009) | 1 line Fix test_doctest, missed two assignments to curframe. ........ r71022 | jesse.noller | 2009-04-01 21:32:55 -0500 (Wed, 01 Apr 2009) | 1 line Issue 3110: Additional protection for SEM_VALUE_MAX on platforms, thanks to Martin Loewis ........ r71023 | kurt.kaiser | 2009-04-01 21:44:54 -0500 (Wed, 01 Apr 2009) | 3 lines Remove port spec from run.py and fix bug where subprocess fails to extract port from command line when warnings are present. ........ r71024 | georg.brandl | 2009-04-01 21:47:44 -0500 (Wed, 01 Apr 2009) | 4 lines In PyErr_GivenExceptionMatches, temporarily bump the recursion limit, so that in the most common case PyObject_IsSubclass will not raise a recursion error we have to ignore anyway. ........ r71026 | benjamin.peterson | 2009-04-01 21:52:46 -0500 (Wed, 01 Apr 2009) | 1 line fix error handling ........ r71029 | senthil.kumaran | 2009-04-01 22:00:34 -0500 (Wed, 01 Apr 2009) | 3 lines Fixing the issue4860. Escaping embedded '"' character in js_output() method of Morsel. ........ r71031 | brett.cannon | 2009-04-01 22:17:39 -0500 (Wed, 01 Apr 2009) | 6 lines PyImport_AppendInittab() took a char * as a first argument even though that string was stored beyond the life of the call. Changed the signature to be const char * to help make this point. Closes issue #1419652. ........ r71032 | michael.foord | 2009-04-01 22:20:38 -0500 (Wed, 01 Apr 2009) | 13 lines Better exception messages for unittest assert methods. - unittest.assertNotEqual() now uses the inequality operator (!=) instead of the equality operator. - Default assertTrue and assertFalse messages are now useful. - TestCase has a longMessage attribute. This defaults to False, but if set to True useful error messages are shown in addition to explicit messages passed to assert methods. Issue #5663 ........ r71033 | brett.cannon | 2009-04-01 22:34:53 -0500 (Wed, 01 Apr 2009) | 3 lines Fix two issues introduced by issue #71031 by changing the signature of PyImport_AppendInittab() to take a const char *. ........ r71036 | jesse.noller | 2009-04-01 23:22:09 -0500 (Wed, 01 Apr 2009) | 1 line Issue 3551: Raise ValueError if the size causes ERROR_NO_SYSTEM_RESOURCES ........ r71037 | r.david.murray | 2009-04-01 23:34:04 -0500 (Wed, 01 Apr 2009) | 6 lines Clarify that datetime strftime does not produce leap seconds and datetime strptime does not accept it in the strftime behavior section of the datetime docs. Closes issue 2568. ........ r71041 | jesse.noller | 2009-04-02 00:17:26 -0500 (Thu, 02 Apr 2009) | 1 line Add custom initializer argument to multiprocess.Manager*, courtesy of lekma ........ r71043 | michael.foord | 2009-04-02 00:51:54 -0500 (Thu, 02 Apr 2009) | 7 lines Store the functions in the _type_equality_funcs as wrapped objects that are deep copyable. This allows for the deep copying of TestCase instances. Issue 5660 ........ r71056 | georg.brandl | 2009-04-02 12:43:07 -0500 (Thu, 02 Apr 2009) | 2 lines Actually the displayhook should print the repr. ........ r71058 | georg.brandl | 2009-04-02 13:09:04 -0500 (Thu, 02 Apr 2009) | 3 lines PyErr_NormalizeException may not set an error, so convert the PyErr_SetObject call on hitting the recursion limit into just assigning it to the arguments provided. ........ r71059 | mark.dickinson | 2009-04-02 13:39:37 -0500 (Thu, 02 Apr 2009) | 2 lines sys.long_info attributes should be ints, not longs ........ r71070 | antoine.pitrou | 2009-04-02 16:18:34 -0500 (Thu, 02 Apr 2009) | 3 lines Issue #2396: backport the memoryview object. ........ r71073 | raymond.hettinger | 2009-04-02 17:25:40 -0500 (Thu, 02 Apr 2009) | 4 lines Have namedtuple's field renamer assign names that are consistent with the corresponding tuple index. ........ r71075 | raymond.hettinger | 2009-04-02 17:34:17 -0500 (Thu, 02 Apr 2009) | 1 line Update docs for namedtuple's renaming change. ........ r71078 | raymond.hettinger | 2009-04-02 21:43:54 -0500 (Thu, 02 Apr 2009) | 4 lines Localize the function lookup in timeit. ........ Modified: python/branches/py3k/ (props changed) From buildbot at python.org Sat Apr 4 06:20:51 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 04:20:51 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090404042051.D1D271E4321@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/472 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 249, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 102, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Sat Apr 4 07:37:50 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 4 Apr 2009 07:37:50 +0200 (CEST) Subject: [Python-checkins] r71119 - python/trunk/Doc/library/shelve.rst Message-ID: <20090404053750.DEC621E4082@bag.python.org> Author: raymond.hettinger Date: Sat Apr 4 07:37:47 2009 New Revision: 71119 Log: Add helpful link. Modified: python/trunk/Doc/library/shelve.rst Modified: python/trunk/Doc/library/shelve.rst ============================================================================== --- python/trunk/Doc/library/shelve.rst (original) +++ python/trunk/Doc/library/shelve.rst Sat Apr 4 07:37:47 2009 @@ -51,6 +51,12 @@ disk, if feasible. This is called automatically when the shelf is closed with :meth:`close`. +.. seealso:: + + `Persistent dictionary recipe `_ + with widely supported storage formats and having the speed of native + dictionaries. + Restrictions ------------ From python-checkins at python.org Sat Apr 4 07:39:19 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 4 Apr 2009 07:39:19 +0200 (CEST) Subject: [Python-checkins] r71120 - python/branches/release30-maint/Doc/library/shelve.rst Message-ID: <20090404053919.591281E4082@bag.python.org> Author: raymond.hettinger Date: Sat Apr 4 07:39:19 2009 New Revision: 71120 Log: Add helpful link. Modified: python/branches/release30-maint/Doc/library/shelve.rst Modified: python/branches/release30-maint/Doc/library/shelve.rst ============================================================================== --- python/branches/release30-maint/Doc/library/shelve.rst (original) +++ python/branches/release30-maint/Doc/library/shelve.rst Sat Apr 4 07:39:19 2009 @@ -48,6 +48,12 @@ disk, if feasible. This is called automatically when the shelf is closed with :meth:`close`. +.. seealso:: + + `Persistent dictionary recipe `_ + with widely supported storage formats and having the speed of native + dictionaries. + Restrictions ------------ From python-checkins at python.org Sat Apr 4 07:39:34 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 4 Apr 2009 07:39:34 +0200 (CEST) Subject: [Python-checkins] r71121 - python/branches/release26-maint/Doc/library/shelve.rst Message-ID: <20090404053934.5DBB61E4082@bag.python.org> Author: raymond.hettinger Date: Sat Apr 4 07:39:34 2009 New Revision: 71121 Log: Add helpful link. Modified: python/branches/release26-maint/Doc/library/shelve.rst Modified: python/branches/release26-maint/Doc/library/shelve.rst ============================================================================== --- python/branches/release26-maint/Doc/library/shelve.rst (original) +++ python/branches/release26-maint/Doc/library/shelve.rst Sat Apr 4 07:39:34 2009 @@ -51,6 +51,12 @@ disk, if feasible. This is called automatically when the shelf is closed with :meth:`close`. +.. seealso:: + + `Persistent dictionary recipe `_ + with widely supported storage formats and having the speed of native + dictionaries. + Restrictions ------------ From python-checkins at python.org Sat Apr 4 07:39:52 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 4 Apr 2009 07:39:52 +0200 (CEST) Subject: [Python-checkins] r71122 - python/branches/py3k/Doc/library/shelve.rst Message-ID: <20090404053952.AB9FB1E4082@bag.python.org> Author: raymond.hettinger Date: Sat Apr 4 07:39:52 2009 New Revision: 71122 Log: Add helpful link. Modified: python/branches/py3k/Doc/library/shelve.rst Modified: python/branches/py3k/Doc/library/shelve.rst ============================================================================== --- python/branches/py3k/Doc/library/shelve.rst (original) +++ python/branches/py3k/Doc/library/shelve.rst Sat Apr 4 07:39:52 2009 @@ -48,6 +48,12 @@ disk, if feasible. This is called automatically when the shelf is closed with :meth:`close`. +.. seealso:: + + `Persistent dictionary recipe `_ + with widely supported storage formats and having the speed of native + dictionaries. + Restrictions ------------ From python-checkins at python.org Sat Apr 4 08:39:56 2009 From: python-checkins at python.org (r.david.murray) Date: Sat, 4 Apr 2009 08:39:56 +0200 (CEST) Subject: [Python-checkins] r71123 - python/trunk/Doc/library/future_builtins.rst Message-ID: <20090404063956.C28F01E4082@bag.python.org> Author: r.david.murray Date: Sat Apr 4 08:39:56 2009 New Revision: 71123 Log: Fix error in description of 'oct' (issue 5678). Modified: python/trunk/Doc/library/future_builtins.rst Modified: python/trunk/Doc/library/future_builtins.rst ============================================================================== --- python/trunk/Doc/library/future_builtins.rst (original) +++ python/trunk/Doc/library/future_builtins.rst Sat Apr 4 08:39:56 2009 @@ -54,7 +54,7 @@ Works like the builtin :func:`oct`, but instead of :meth:`__oct__` it will use the :meth:`__index__` method on its argument to get an integer that is - then converted to hexadecimal. + then converted to octal. .. function:: zip(*iterables) From python-checkins at python.org Sat Apr 4 08:43:40 2009 From: python-checkins at python.org (r.david.murray) Date: Sat, 4 Apr 2009 08:43:40 +0200 (CEST) Subject: [Python-checkins] r71124 - in python/branches/release26-maint: Doc/library/future_builtins.rst Message-ID: <20090404064340.0CA7A1E407C@bag.python.org> Author: r.david.murray Date: Sat Apr 4 08:43:39 2009 New Revision: 71124 Log: Merged revisions 71123 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71123 | r.david.murray | 2009-04-04 02:39:56 -0400 (Sat, 04 Apr 2009) | 2 lines Fix error in description of 'oct' (issue 5678). ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/future_builtins.rst Modified: python/branches/release26-maint/Doc/library/future_builtins.rst ============================================================================== --- python/branches/release26-maint/Doc/library/future_builtins.rst (original) +++ python/branches/release26-maint/Doc/library/future_builtins.rst Sat Apr 4 08:43:39 2009 @@ -54,7 +54,7 @@ Works like the builtin :func:`oct`, but instead of :meth:`__oct__` it will use the :meth:`__index__` method on its argument to get an integer that is - then converted to hexadecimal. + then converted to octal. .. function:: zip(*iterables) From python-checkins at python.org Sat Apr 4 08:46:12 2009 From: python-checkins at python.org (r.david.murray) Date: Sat, 4 Apr 2009 08:46:12 +0200 (CEST) Subject: [Python-checkins] r71125 - python/branches/py3k Message-ID: <20090404064612.1A6BD1E4082@bag.python.org> Author: r.david.murray Date: Sat Apr 4 08:46:11 2009 New Revision: 71125 Log: Blocked revisions 71123 via svnmerge ........ r71123 | r.david.murray | 2009-04-04 02:39:56 -0400 (Sat, 04 Apr 2009) | 2 lines Fix error in description of 'oct' (issue 5678). ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Apr 4 09:03:49 2009 From: python-checkins at python.org (kurt.kaiser) Date: Sat, 4 Apr 2009 09:03:49 +0200 (CEST) Subject: [Python-checkins] r71126 - in python/trunk/Lib/idlelib: NEWS.txt PyShell.py rpc.py Message-ID: <20090404070349.4444A1E42B6@bag.python.org> Author: kurt.kaiser Date: Sat Apr 4 09:03:48 2009 New Revision: 71126 Log: Allow multiple IDLE GUI/subprocess pairs to exist simultaneously. Thanks to David Scherer for suggesting the use of an ephemeral port for the GUI. Patch 1529142 Weeble. Modified: python/trunk/Lib/idlelib/NEWS.txt python/trunk/Lib/idlelib/PyShell.py python/trunk/Lib/idlelib/rpc.py Modified: python/trunk/Lib/idlelib/NEWS.txt ============================================================================== --- python/trunk/Lib/idlelib/NEWS.txt (original) +++ python/trunk/Lib/idlelib/NEWS.txt Sat Apr 4 09:03:48 2009 @@ -3,6 +3,10 @@ *Release date: XX-XXX-2009* +- Allow multiple IDLE GUI/subprocess pairs to exist simultaneously. Thanks to + David Scherer for suggesting the use of an ephemeral port for the GUI. + Patch 1529142 Weeble. + - Remove port spec from run.py and fix bug where subprocess fails to extract port from command line when warnings are present. Modified: python/trunk/Lib/idlelib/PyShell.py ============================================================================== --- python/trunk/Lib/idlelib/PyShell.py (original) +++ python/trunk/Lib/idlelib/PyShell.py Sat Apr 4 09:03:48 2009 @@ -37,7 +37,8 @@ import RemoteDebugger IDENTCHARS = string.ascii_letters + string.digits + "_" -LOCALHOST = '127.0.0.1' +HOST = '127.0.0.1' # python execution server on localhost loopback +PORT = 0 # someday pass in host, port for remote debug capability try: from signal import SIGTERM @@ -342,17 +343,21 @@ InteractiveInterpreter.__init__(self, locals=locals) self.save_warnings_filters = None self.restarting = False - self.subprocess_arglist = self.build_subprocess_arglist() + self.subprocess_arglist = None + self.port = PORT - port = 8833 rpcclt = None rpcpid = None def spawn_subprocess(self): + if self.subprocess_arglist == None: + self.subprocess_arglist = self.build_subprocess_arglist() args = self.subprocess_arglist self.rpcpid = os.spawnv(os.P_NOWAIT, sys.executable, args) def build_subprocess_arglist(self): + assert (self.port!=0), ( + "Socket should have been assigned a port number.") w = ['-W' + s for s in sys.warnoptions] if 1/2 > 0: # account for new division w.append('-Qnew') @@ -373,11 +378,8 @@ return [decorated_exec] + w + ["-c", command, str(self.port)] def start_subprocess(self): - # spawning first avoids passing a listening socket to the subprocess - self.spawn_subprocess() - #time.sleep(20) # test to simulate GUI not accepting connection - addr = (LOCALHOST, self.port) - # Idle starts listening for connection on localhost + addr = (HOST, self.port) + # GUI makes several attempts to acquire socket, listens for connection for i in range(3): time.sleep(i) try: @@ -388,6 +390,18 @@ else: self.display_port_binding_error() return None + # if PORT was 0, system will assign an 'ephemeral' port. Find it out: + self.port = self.rpcclt.listening_sock.getsockname()[1] + # if PORT was not 0, probably working with a remote execution server + if PORT != 0: + # To allow reconnection within the 2MSL wait (cf. Stevens TCP + # V1, 18.6), set SO_REUSEADDR. Note that this can be problematic + # on Windows since the implementation allows two active sockets on + # the same address! + self.rpcclt.listening_sock.setsockopt(socket.SOL_SOCKET, + socket.SO_REUSEADDR, 1) + self.spawn_subprocess() + #time.sleep(20) # test to simulate GUI not accepting connection # Accept the connection from the Python execution server self.rpcclt.listening_sock.settimeout(10) try: @@ -754,13 +768,12 @@ def display_port_binding_error(self): tkMessageBox.showerror( "Port Binding Error", - "IDLE can't bind TCP/IP port 8833, which is necessary to " - "communicate with its Python execution server. Either " - "no networking is installed on this computer or another " - "process (another IDLE?) is using the port. Run IDLE with the -n " - "command line switch to start without a subprocess and refer to " - "Help/IDLE Help 'Running without a subprocess' for further " - "details.", + "IDLE can't bind to a TCP/IP port, which is necessary to " + "communicate with its Python execution server. This might be " + "because no networking is installed on this computer. " + "Run IDLE with the -n command line switch to start without a " + "subprocess and refer to Help/IDLE Help 'Running without a " + "subprocess' for further details.", master=self.tkconsole.text) def display_no_subprocess_error(self): @@ -1300,7 +1313,7 @@ global flist, root, use_subprocess use_subprocess = True - enable_shell = False + enable_shell = True enable_edit = False debug = False cmd = None @@ -1321,6 +1334,7 @@ enable_shell = True if o == '-e': enable_edit = True + enable_shell = False if o == '-h': sys.stdout.write(usage_msg) sys.exit() @@ -1371,7 +1385,6 @@ edit_start = idleConf.GetOption('main', 'General', 'editor-on-startup', type='bool') enable_edit = enable_edit or edit_start - enable_shell = enable_shell or not edit_start # start editor and/or shell windows: root = Tk(className="Idle") Modified: python/trunk/Lib/idlelib/rpc.py ============================================================================== --- python/trunk/Lib/idlelib/rpc.py (original) +++ python/trunk/Lib/idlelib/rpc.py Sat Apr 4 09:03:48 2009 @@ -518,8 +518,6 @@ def __init__(self, address, family=socket.AF_INET, type=socket.SOCK_STREAM): self.listening_sock = socket.socket(family, type) - self.listening_sock.setsockopt(socket.SOL_SOCKET, - socket.SO_REUSEADDR, 1) self.listening_sock.bind(address) self.listening_sock.listen(1) From python-checkins at python.org Sat Apr 4 10:46:59 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 4 Apr 2009 10:46:59 +0200 (CEST) Subject: [Python-checkins] r71127 - python/trunk/Lib/collections.py Message-ID: <20090404084659.35F8D1E4082@bag.python.org> Author: raymond.hettinger Date: Sat Apr 4 10:46:58 2009 New Revision: 71127 Log: Replace the localized min/max calls with normal if/else Modified: python/trunk/Lib/collections.py Modified: python/trunk/Lib/collections.py ============================================================================== --- python/trunk/Lib/collections.py (original) +++ python/trunk/Lib/collections.py Sat Apr 4 10:46:58 2009 @@ -465,10 +465,10 @@ ''' if not isinstance(other, Counter): return NotImplemented - _max = max result = Counter() for elem in set(self) | set(other): - newcount = _max(self[elem], other[elem]) + p, q = self[elem], other[elem] + newcount = q if p < q else p if newcount > 0: result[elem] = newcount return result @@ -482,12 +482,12 @@ ''' if not isinstance(other, Counter): return NotImplemented - _min = min result = Counter() if len(self) < len(other): self, other = other, self for elem in _ifilter(self.__contains__, other): - newcount = _min(self[elem], other[elem]) + p, q = self[elem], other[elem] + newcount = p if p < q else q if newcount > 0: result[elem] = newcount return result From python-checkins at python.org Sat Apr 4 10:48:03 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 4 Apr 2009 10:48:03 +0200 (CEST) Subject: [Python-checkins] r71128 - python/branches/py3k/Lib/collections.py Message-ID: <20090404084803.4FCD91E4082@bag.python.org> Author: raymond.hettinger Date: Sat Apr 4 10:48:03 2009 New Revision: 71128 Log: Replace the localized min/max calls with normal if/else Modified: python/branches/py3k/Lib/collections.py Modified: python/branches/py3k/Lib/collections.py ============================================================================== --- python/branches/py3k/Lib/collections.py (original) +++ python/branches/py3k/Lib/collections.py Sat Apr 4 10:48:03 2009 @@ -461,10 +461,10 @@ ''' if not isinstance(other, Counter): return NotImplemented - _max = max result = Counter() for elem in set(self) | set(other): - newcount = _max(self[elem], other[elem]) + p, q = self[elem], other[elem] + newcount = q if p < q else p if newcount > 0: result[elem] = newcount return result @@ -478,12 +478,12 @@ ''' if not isinstance(other, Counter): return NotImplemented - _min = min result = Counter() if len(self) < len(other): self, other = other, self for elem in filter(self.__contains__, other): - newcount = _min(self[elem], other[elem]) + p, q = self[elem], other[elem] + newcount = p if p < q else q if newcount > 0: result[elem] = newcount return result From python-checkins at python.org Sat Apr 4 10:57:39 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 4 Apr 2009 10:57:39 +0200 (CEST) Subject: [Python-checkins] r71129 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090404085739.091EF1E4082@bag.python.org> Author: mark.dickinson Date: Sat Apr 4 10:57:38 2009 New Revision: 71129 Log: Fix off-by-one bug for 'g' formatting. Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Sat Apr 4 10:57:38 2009 @@ -591,7 +591,7 @@ case 'e': use_exp = 1; break; case 'f': use_exp = 0; break; case 'g': { - if ((mode != 0) && (decpt > precision || decpt < -4)) + if ((mode != 0) && (decpt > precision || decpt <= -4)) use_exp = 1; else { use_exp = 0; From python-checkins at python.org Sat Apr 4 10:58:11 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 4 Apr 2009 10:58:11 +0200 (CEST) Subject: [Python-checkins] r71130 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090404085811.A30BD1E4082@bag.python.org> Author: mark.dickinson Date: Sat Apr 4 10:58:11 2009 New Revision: 71130 Log: Fix string constant Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Sat Apr 4 10:58:11 2009 @@ -568,7 +568,7 @@ 'N' */ /*printf("Help! dtoa returned: %.*s\n", (int)n_digits, digits);*/ - strncpy(buf, 'ERR', 3); + strncpy(buf, "ERR", 3); buf += 3; assert(0); } From python-checkins at python.org Sat Apr 4 11:00:21 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 4 Apr 2009 11:00:21 +0200 (CEST) Subject: [Python-checkins] r71131 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090404090021.7339A1E4082@bag.python.org> Author: mark.dickinson Date: Sat Apr 4 11:00:21 2009 New Revision: 71131 Log: Force precision of at least 1 for 'g' format Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Sat Apr 4 11:00:21 2009 @@ -538,6 +538,10 @@ Py_ssize_t n_digits_after_decimal = 0; Py_ssize_t n_digits; + /* precision of 0 makes no sense for 'g' format; interpret as 1 */ + if (precision == 0 && format_code == 'g') + precision = 1; + /* _Py_dg_dtoa returns a digit string (no decimal point or exponent) */ digits = _Py_dg_dtoa(d, mode, precision, &decpt, &sign, &digits_end); From python-checkins at python.org Sat Apr 4 11:00:59 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 4 Apr 2009 11:00:59 +0200 (CEST) Subject: [Python-checkins] r71132 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090404090059.3954F1E4082@bag.python.org> Author: mark.dickinson Date: Sat Apr 4 11:00:59 2009 New Revision: 71132 Log: Remove surplus braces Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Sat Apr 4 11:00:59 2009 @@ -594,7 +594,7 @@ switch (format_code) { case 'e': use_exp = 1; break; case 'f': use_exp = 0; break; - case 'g': { + case 'g': if ((mode != 0) && (decpt > precision || decpt <= -4)) use_exp = 1; else { @@ -602,7 +602,6 @@ n_wanted_digits_after_decimal = precision - decpt; } } - } /* Always add a negative sign, and a plus sign if always_add_sign. */ if (sign == 1) From python-checkins at python.org Sat Apr 4 11:30:37 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 4 Apr 2009 11:30:37 +0200 (CEST) Subject: [Python-checkins] r71133 - python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt Message-ID: <20090404093037.D90B71E4082@bag.python.org> Author: mark.dickinson Date: Sat Apr 4 11:30:37 2009 New Revision: 71133 Log: Add file containing test cases for float formatting Added: python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt Added: python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt ============================================================================== --- (empty file) +++ python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt Sat Apr 4 11:30:37 2009 @@ -0,0 +1,247 @@ +-- 'f' code formatting, with explicit precision (>= 0). Output always +-- has the given number of places after the point; zeros are added if +-- necessary to make this true. + +-- zeros +%.0f 0 -> 0 +%.1f 0 -> 0.0 +%.2f 0 -> 0.00 +%.3f 0 -> 0.000 +%.50f 0 -> 0.00000000000000000000000000000000000000000000000000 + +-- precision 0; result should never include a . +%.0f 1.5 -> 2 +%.0f 2.5 -> 2 +%.0f 3.5 -> 4 +%.0f 0.0 -> 0 +%.0f 0.1 -> 0 +%.0f 0.001 -> 0 +%.0f 10.0 -> 10 +%.0f 10.1 -> 10 +%.0f 10.01 -> 10 +%.0f 123.456 -> 123 +%.0f 1234.56 -> 1235 +%.0f 1e49 -> 9999999999999999464902769475481793196872414789632 +%.0f 9.9999999999999987e+49 -> 99999999999999986860582406952576489172979654066176 +-- %.0f 1e50 -> 1e50 + +-- precision 1 +%.1f 0.0001 -> 0.0 +%.1f 0.001 -> 0.0 +%.1f 0.01 -> 0.0 +%.1f 0.04 -> 0.0 +%.1f 0.06 -> 0.1 +%.1f 0.25 -> 0.2 +%.1f 0.75 -> 0.8 +%.1f 1.4 -> 1.4 +%.1f 1.5 -> 1.5 +%.1f 10.0 -> 10.0 +%.1f 1000.03 -> 1000.0 +%.1f 1234.5678 -> 1234.6 +%.1f 1234.7499 -> 1234.7 +%.1f 1234.75 -> 1234.8 + +-- precision 2 +%.2f 0.0001 -> 0.00 +%.2f 0.001 -> 0.00 +%.2f 0.004999 -> 0.00 +%.2f 0.005001 -> 0.01 +%.2f 0.01 -> 0.01 +%.2f 0.125 -> 0.12 +%.2f 0.375 -> 0.38 +%.2f 1234500 -> 1234500.00 +%.2f 1234560 -> 1234560.00 +%.2f 1234567 -> 1234567.00 +%.2f 1234567.8 -> 1234567.80 +%.2f 1234567.89 -> 1234567.89 +%.2f 1234567.891 -> 1234567.89 +%.2f 1234567.8912 -> 1234567.89 + + +-- 'e' code formatting with explicit precision (>= 0). Output should +-- always have exactly the number of places after the point that were +-- requested. + +-- zeros +%.0e 0 -> 0e+00 +%.1e 0 -> 0.0e+00 +%.2e 0 -> 0.00e+00 +%.10e 0 -> 0.0000000000e+00 +%.50e 0 -> 0.00000000000000000000000000000000000000000000000000e+00 + +-- precision 0. no decimal point in the output +%.0e 0.01 -> 1e-02 +%.0e 0.1 -> 1e-01 +%.0e 1 -> 1e+00 +%.0e 10 -> 1e+01 +%.0e 100 -> 1e+02 +%.0e 0.012 -> 1e-02 +%.0e 0.12 -> 1e-01 +%.0e 1.2 -> 1e+00 +%.0e 12 -> 1e+01 +%.0e 120 -> 1e+02 +%.0e 123.456 -> 1e+02 +%.0e 0.000123456 -> 1e-04 +%.0e 123456000 -> 1e+08 +%.0e 0.5 -> 5e-01 +%.0e 1.4 -> 1e+00 +%.0e 1.5 -> 2e+00 +%.0e 1.6 -> 2e+00 +%.0e 2.4999999 -> 2e+00 +%.0e 2.5 -> 2e+00 +%.0e 2.5000001 -> 3e+00 +%.0e 3.499999999999 -> 3e+00 +%.0e 3.5 -> 4e+00 +%.0e 4.5 -> 4e+00 +%.0e 5.5 -> 6e+00 +%.0e 6.5 -> 6e+00 +%.0e 7.5 -> 8e+00 +%.0e 8.5 -> 8e+00 +%.0e 9.4999 -> 9e+00 +%.0e 9.5 -> 1e+01 +%.0e 10.5 -> 1e+01 +%.0e 14.999 -> 1e+01 +%.0e 15 -> 2e+01 + +-- precision 1 +%.1e 0.0001 -> 1.0e-04 +%.1e 0.001 -> 1.0e-03 +%.1e 0.01 -> 1.0e-02 +%.1e 0.1 -> 1.0e-01 +%.1e 1 -> 1.0e+00 +%.1e 10 -> 1.0e+01 +%.1e 100 -> 1.0e+02 +%.1e 120 -> 1.2e+02 +%.1e 123 -> 1.2e+02 +%.1e 123.4 -> 1.2e+02 + +-- precision 2 +%.2e 0.00013 -> 1.30e-04 +%.2e 0.000135 -> 1.35e-04 +%.2e 0.0001357 -> 1.36e-04 +%.2e 0.0001 -> 1.00e-04 +%.2e 0.001 -> 1.00e-03 +%.2e 0.01 -> 1.00e-02 +%.2e 0.1 -> 1.00e-01 +%.2e 1 -> 1.00e+00 +%.2e 10 -> 1.00e+01 +%.2e 100 -> 1.00e+02 +%.2e 1000 -> 1.00e+03 +%.2e 1500 -> 1.50e+03 +%.2e 1590 -> 1.59e+03 +%.2e 1598 -> 1.60e+03 +%.2e 1598.7 -> 1.60e+03 +%.2e 1598.76 -> 1.60e+03 +%.2e 9999 -> 1.00e+04 + +-- 'g' code formatting. + +-- zeros +%.0g 0 -> 0 +%.1g 0 -> 0 +%.2g 0 -> 0 +%.3g 0 -> 0 +%.4g 0 -> 0 +%.10g 0 -> 0 +%.50g 0 -> 0 +%.100g 0 -> 0 + +-- precision 0 doesn't make a lot of sense for the 'g' code (what does +-- it mean to have no significant digits?); in practice, it's interpreted +-- as identical to precision 1 +%.0g 1000 -> 1e+03 +%.0g 100 -> 1e+02 +%.0g 10 -> 1e+01 +%.0g 1 -> 1 +%.0g 0.1 -> 0.1 +%.0g 0.01 -> 0.01 +%.0g 1e-3 -> 0.001 +%.0g 1e-4 -> 0.0001 +%.0g 1e-5 -> 1e-05 +%.0g 1e-6 -> 1e-06 +%.0g 12 -> 1e+01 +%.0g 120 -> 1e+02 +%.0g 1.2 -> 1 +%.0g 0.12 -> 0.1 +%.0g 0.012 -> 0.01 +%.0g 0.0012 -> 0.001 +%.0g 0.00012 -> 0.0001 +%.0g 0.000012 -> 1e-05 +%.0g 0.0000012 -> 1e-06 + +-- precision 1 identical to precision 0 +%.1g 1000 -> 1e+03 +%.1g 100 -> 1e+02 +%.1g 10 -> 1e+01 +%.1g 1 -> 1 +%.1g 0.1 -> 0.1 +%.1g 0.01 -> 0.01 +%.1g 1e-3 -> 0.001 +%.1g 1e-4 -> 0.0001 +%.1g 1e-5 -> 1e-05 +%.1g 1e-6 -> 1e-06 +%.1g 12 -> 1e+01 +%.1g 120 -> 1e+02 +%.1g 1.2 -> 1 +%.1g 0.12 -> 0.1 +%.1g 0.012 -> 0.01 +%.1g 0.0012 -> 0.001 +%.1g 0.00012 -> 0.0001 +%.1g 0.000012 -> 1e-05 +%.1g 0.0000012 -> 1e-06 + +-- precision 2 +%.2g 1000 -> 1e+03 +%.2g 100 -> 1e+02 +%.2g 10 -> 10 +%.2g 1 -> 1 +%.2g 0.1 -> 0.1 +%.2g 0.01 -> 0.01 +%.2g 0.001 -> 0.001 +%.2g 1e-4 -> 0.0001 +%.2g 1e-5 -> 1e-05 +%.2g 1e-6 -> 1e-06 +%.2g 1234 -> 1.2e+03 +%.2g 123 -> 1.2e+02 +%.2g 12.3 -> 12 +%.2g 1.23 -> 1.2 +%.2g 0.123 -> 0.12 +%.2g 0.0123 -> 0.012 +%.2g 0.00123 -> 0.0012 +%.2g 0.000123 -> 0.00012 +%.2g 0.0000123 -> 1.2e-05 + +-- alternate g formatting: always include decimal point and +-- exactly significant digits. +%#.0g 0 -> 0. +%#.1g 0 -> 0. +%#.2g 0 -> 0.0 +%#.3g 0 -> 0.00 +%#.4g 0 -> 0.000 + +%#.0g 0.2 -> 0.2 +%#.1g 0.2 -> 0.2 +%#.2g 0.2 -> 0.20 +%#.3g 0.2 -> 0.200 +%#.4g 0.2 -> 0.2000 +%#.10g 0.2 -> 0.2000000000 + +%#.0g 2 -> 2. +%#.1g 2 -> 2. +%#.2g 2 -> 2.0 +%#.3g 2 -> 2.00 +%#.4g 2 -> 2.000 + +%#.0g 20 -> 2.e+01 +%#.1g 20 -> 2.e+01 +%#.2g 20 -> 20. +%#.3g 20 -> 20.0 +%#.4g 20 -> 20.00 + +%#.0g 234.56 -> 2.e+02 +%#.1g 234.56 -> 2.e+02 +%#.2g 234.56 -> 2.3e+02 +%#.3g 234.56 -> 235. +%#.4g 234.56 -> 234.6 +%#.5g 234.56 -> 234.56 +%#.6g 234.56 -> 234.560 From python-checkins at python.org Sat Apr 4 11:34:45 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 4 Apr 2009 11:34:45 +0200 (CEST) Subject: [Python-checkins] r71134 - python/branches/py3k-short-float-repr/test_float_format.py Message-ID: <20090404093445.6D78C1E409B@bag.python.org> Author: mark.dickinson Date: Sat Apr 4 11:34:45 2009 New Revision: 71134 Log: Temporary testing code for float formatting. Needs to be properly integrated. Added: python/branches/py3k-short-float-repr/test_float_format.py Added: python/branches/py3k-short-float-repr/test_float_format.py ============================================================================== --- (empty file) +++ python/branches/py3k-short-float-repr/test_float_format.py Sat Apr 4 11:34:45 2009 @@ -0,0 +1,14 @@ +f = open('Lib/test/formatfloat_testcases.txt') + +for line in f: + if line.startswith('--'): + continue + line = line.strip() + if not line: + continue + + lhs, rhs = map(str.strip, line.split('->')) + fmt, arg = lhs.split() + print(line) + assert fmt % float(arg) == rhs + assert fmt % -float(arg) == '-'+rhs From python-checkins at python.org Sat Apr 4 11:40:47 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 4 Apr 2009 11:40:47 +0200 (CEST) Subject: [Python-checkins] r71135 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090404094047.AC47D1E4082@bag.python.org> Author: mark.dickinson Date: Sat Apr 4 11:40:47 2009 New Revision: 71135 Log: Reworking of float_format_short. Eric, feel free to revert this if you don't like it, or for any other reason... Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Sat Apr 4 11:40:47 2009 @@ -531,12 +531,10 @@ int use_alt_formatting, char **float_strings) { char *digits, *digits_end; - int decpt, sign, exp_len; + int decpt, sign, exp_len, dec_pos; int use_exp = 0; int is_integer; /* is the output produced so far just an integer? */ - int add_trailing_zeros; - Py_ssize_t n_digits_after_decimal = 0; - Py_ssize_t n_digits; + Py_ssize_t n_digits, trailing_zeros; /* precision of 0 makes no sense for 'g' format; interpret as 1 */ if (precision == 0 && format_code == 'g') @@ -592,15 +590,25 @@ /* Detect if we're using exponents or not */ switch (format_code) { - case 'e': use_exp = 1; break; - case 'f': use_exp = 0; break; + case 'e': + use_exp = 1; + trailing_zeros = precision - n_digits; + break; + case 'f': + use_exp = 0; + trailing_zeros = decpt + precision - n_digits; + break; case 'g': if ((mode != 0) && (decpt > precision || decpt <= -4)) use_exp = 1; else { use_exp = 0; - n_wanted_digits_after_decimal = precision - decpt; } + if (use_alt_formatting) + trailing_zeros = precision - n_digits; + else + trailing_zeros = 0; + break; } /* Always add a negative sign, and a plus sign if always_add_sign. */ @@ -609,74 +617,47 @@ else if (always_add_sign) *buf++ = '+'; - if (use_exp) { - /* Exponential notation: d[.dddd]e(+|-)ee; at least 2 digits - in exponent */ - n_digits_after_decimal = n_digits - 1; - *buf++ = digits[0]; - *buf++ = '.'; - strncpy(buf, digits + 1, n_digits_after_decimal); - buf += n_digits_after_decimal; - - /* Don't add the exponent yet. That's done later after a bit - more formatting. */ - } else { - /* Use fixed-point notation */ - - /* Be aware that n_digits_after_decimal can be negative! */ - n_digits_after_decimal = n_digits - decpt; - - if (decpt <= 0) { - /* Output: 0.00-00dd-dd */ - *buf++ = '0'; - *buf++ = '.'; - /* Add the appropriate number of zeros. */ - memset(buf, '0', -decpt); - buf += -decpt; - - /* Then the digits */ - strncpy(buf, digits, n_digits); - buf += n_digits; - } - else if (decpt < n_digits) { - /* Output: dd-dd.dd-dd */ - strncpy(buf, digits, decpt); - buf += decpt; - *buf++ = '.'; - strncpy(buf, digits + decpt, n_digits - decpt); - buf += n_digits - decpt; - } - else { - /* decpt >= n_digits. Output: dd-dd00-00.0 */ - strncpy(buf, digits, n_digits); /* digits */ - buf += n_digits; - - memset(buf, '0', decpt - n_digits); /* zeros */ - buf += decpt - n_digits; + /* dec_pos = position of decimal point in buffer */ + if (use_exp) + dec_pos = 1; + else + dec_pos = decpt; - *buf++ = '.'; - } + /* zero padding on left of digit string */ + if (dec_pos <= 0) { + *buf++ = '0'; + *buf++ = '.'; + memset(buf, '0', -dec_pos); + buf -= dec_pos; } - /* Add trailing non-significant zeros for non-mode 0 and non-code g, - unless doing alt formatting */ - add_trailing_zeros = 0; - if (mode != 0) { - if (format_code == 'g') { - if (use_alt_formatting) - add_trailing_zeros = 1; - } - else - add_trailing_zeros = 1; + /* digits, with included decimal point */ + if (0 < dec_pos && dec_pos <= n_digits) { + strncpy(buf, digits, dec_pos); + buf += dec_pos; + *buf++ = '.'; + strncpy(buf, digits+dec_pos, n_digits-dec_pos); + buf += n_digits-dec_pos; } - - if (add_trailing_zeros) { - memset(buf, '0', n_wanted_digits_after_decimal - n_digits_after_decimal); - buf += n_wanted_digits_after_decimal - n_digits_after_decimal; + else { + strncpy(buf, digits, n_digits); + buf += n_digits; + } + /* and zeros on the right up to the decimal point */ + if (n_digits < dec_pos) { + memset(buf, '0', dec_pos-n_digits); + buf += dec_pos-n_digits; + *buf++ = '.'; + trailing_zeros -= dec_pos-n_digits; + } + /* and more trailing zeros, when necessary */ + if (trailing_zeros > 0) { + memset(buf, '0', trailing_zeros); + buf += trailing_zeros; } /* If we're at a trailing decimal, delete it. We are then just an integer. */ - if (buf[-1] == '.') { + if (buf[-1] == '.' && !(format_code == 'g' && use_alt_formatting)) { buf--; is_integer = 1; } From buildbot at python.org Sat Apr 4 11:44:28 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 09:44:28 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090404094428.8D98C1E4082@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/474 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: raymond.hettinger BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 249, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 102, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Sat Apr 4 12:24:45 2009 From: python-checkins at python.org (eric.smith) Date: Sat, 4 Apr 2009 12:24:45 +0200 (CEST) Subject: [Python-checkins] r71136 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090404102445.642941E432A@bag.python.org> Author: eric.smith Date: Sat Apr 4 12:24:43 2009 New Revision: 71136 Log: Fixed format code 'r' (for repr) to map to 'g', but with mode 0. Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Sat Apr 4 12:24:43 2009 @@ -736,6 +736,7 @@ break; case 'r': /* "repr" pseudo-mode */ + lc_format_code = 'g'; mode = 0; break; } From python-checkins at python.org Sat Apr 4 12:47:36 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 4 Apr 2009 12:47:36 +0200 (CEST) Subject: [Python-checkins] r71137 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090404104736.6D08F1E4082@bag.python.org> Author: raymond.hettinger Date: Sat Apr 4 12:47:35 2009 New Revision: 71137 Log: Start building-up the whatsnew document for Py3.1 Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Sat Apr 4 12:47:35 2009 @@ -4,7 +4,7 @@ .. XXX Add trademark info for Apple, Microsoft. -:Author: No one so far +:Author: Raymond Hettinger :Release: |release| :Date: |today| @@ -66,6 +66,59 @@ .. ====================================================================== +PEP 372: Ordered Dictionaries +============================= + +Regular Python dictionaries iterate over key/value pairs in arbitrary order. +Over the years, a number of authors have written alternative implementations +that remember the order that the keys were originally inserted. Based on +the experiences from those implementations, the :mod:`collections` module +now has an :class:`OrderedDict` class. + +The OrderedDict API is substantially the same as regular dictionaries +but will iterate over keys and values in a guaranteed order depending on +when a key was first inserted. If a new entry overwrites an existing entry, +the original insertion position is left unchanged. Deleting an entry and +reinserting it will move it to the end. + +The standard library now supports use of ordered dictionaries in several +modules. The :mod:`ConfigParser` modules uses them by default. This lets +configuration files be read, modified, and then written back in their original +order. The :mod:`collections` module's :meth:`namedtuple._asdict` method now +returns a dictionary with the values appearing in the same order as the +underlying tuple.count The :mod:`json` module is being built-out with an +*object_pairs_hook* to allow OrderedDicts to be built by the decoder. +Support was also builtin for third-party tools like PyYAML. + +.. seealso:: + + :pep:`372` - Ordered Dictionaries + PEP written by Armin Roancher and Raymond D. Hettinger; implemented by + Raymond Hettinger + +PEP 378: Format Specifier for Thousands Separator +================================================= + +The builtin :func:`format` function and the :meth:`str.format` method use +a mini-language that now includes a simple, non-locale aware way to format +a number with a thousands separator. That provides a way to humanize a +program's output, improving its professional appearance and readability:: + + >>> format(Decimal('1234567.89'), ',f') + '1,234,567.89' + +The currently supported types are :class:`int` and :class:`Decimal`. +Support for :class:`float` is expected before the beta release. +Discussions are underway about how to specify alternative separators +like dots, spaces, apostrophes, or underscores. + +.. seealso:: + + :pep:`378` - Format Specifier for Thousands Separator + PEP written by Raymond Hettinger; implemented by Eric Smith and + Mark Dickinson. + + Other Language Changes ====================== @@ -107,10 +160,36 @@ >>> sys.int_info sys.int_info(bits_per_digit=30, sizeof_digit=4) - (Contributed by Mark Dickinson; :issue:`4258`.) +* Added a :class:`collections.Counter` class to support convenient + counting of unique items in a sequence or iterable:: + + >>> Counter(['red', 'blue', 'red', 'green', 'blue', 'blue']) + Counter({'blue': 3, 'red': 2, 'green': 1}) + + (Contributed by Raymond Hettinger; :issue:`1696199`.) + +* The :class:`gzip.GzipFile` and :class:`bz2.BZ2File` classs now support + the context manager protocol. + + (Contributed by Jacques Frechet; :issue:`4272`.) + +* The :mod:`Decimal` module now supports two new methods to create a + decimal object that from a binary :class:`float`. The conversion is + exact but can sometimes be surprising:: + + >>> Decimal.from_float(1.1) + Decimal('1.100000000000000088817841970012523233890533447265625') + + The long decimal result shows the actual binary fraction being + stored for *1.1*. The fraction has many digits because *1.1* cannot + be exactly represented in binary. + + (Contributed by Raymond Hettinger and Mark Dickinson.) + + .. ====================================================================== @@ -134,5 +213,6 @@ (Contributed by Antoine Pitrou, :issue:`4753`.) +XXX The JSON module is getting a C extension for speed. .. ====================================================================== From python-checkins at python.org Sat Apr 4 13:08:49 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 4 Apr 2009 13:08:49 +0200 (CEST) Subject: [Python-checkins] r71138 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090404110849.009A51E4082@bag.python.org> Author: raymond.hettinger Date: Sat Apr 4 13:08:48 2009 New Revision: 71138 Log: More updates to whatsnew Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Sat Apr 4 13:08:48 2009 @@ -189,6 +189,28 @@ (Contributed by Raymond Hettinger and Mark Dickinson.) +* The fields in :func:`format` strings can now be automatically + numbered:: + + >>> 'Sir {} of {}'.format('Gallahad', 'Camelot') + 'Sir Gallahad of Camelot' + + Formerly, the string would have required numbered fields such as: + ``'Sir {0} of {1}'``. + + (Contributed by Eric Smith; :issue:`5237`.) + +* The :mod:`itertools` module grew two new functions. The + :func:`itertools.combinations_with_replacement` function is one of + four for generating combinatorics including permutations and Cartesian + products. The :func:`itertools.compress` function mimics its namesake + from APL. Also, the existing :func:`itertools.count` function now has + an optional *step* argument and can accept any type of counting + sequence including :class:`fractions.Fraction` and + :class:`decimal.Decimal`. + + (Contributed by Raymond Hettinger.) + .. ====================================================================== @@ -213,6 +235,13 @@ (Contributed by Antoine Pitrou, :issue:`4753`.) +* Add a heuristic so that tuples and dicts containing only untrackable objects + are not tracked by the garbage collector. This can reduce the size of + collections and therefore the garbage collection overhead on long-running + programs, depending on their particular use of datatypes. + + (Contributed by Antoine Pitrou, :issue:`4688`.) + XXX The JSON module is getting a C extension for speed. .. ====================================================================== From python-checkins at python.org Sat Apr 4 13:59:01 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 4 Apr 2009 13:59:01 +0200 (CEST) Subject: [Python-checkins] r71139 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090404115901.660011E4046@bag.python.org> Author: raymond.hettinger Date: Sat Apr 4 13:59:00 2009 New Revision: 71139 Log: More notes on 3.1 improvements. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Sat Apr 4 13:59:00 2009 @@ -88,12 +88,12 @@ returns a dictionary with the values appearing in the same order as the underlying tuple.count The :mod:`json` module is being built-out with an *object_pairs_hook* to allow OrderedDicts to be built by the decoder. -Support was also builtin for third-party tools like PyYAML. +Support was also added for third-party tools like PyYAML. .. seealso:: :pep:`372` - Ordered Dictionaries - PEP written by Armin Roancher and Raymond D. Hettinger; implemented by + PEP written by Armin Ronacher and Raymond Hettinger; implemented by Raymond Hettinger PEP 378: Format Specifier for Thousands Separator @@ -211,6 +211,48 @@ (Contributed by Raymond Hettinger.) +* :class:`collections.deque` objects now have a read-only attribute + called *maxlen*. + + (Contributed by Raymond Hettinger.) + +* :func:`collections.namedtuple` now supports a keyword argument + *rename* which lets invalid fieldnames be automatically converted to + positional names in the form _0, _1, etc. This is useful when + the field names are being created by an external source such as a + CSV header, SQL field list, or user input. + + (Contributed by Raymond Hettinger; :issue:`1818`.) + +* :func:`round`(x, n) now returns an integer if *x* is an integer. + Previously it returned a float. + + (Contributed by Mark Dickinson; :issue:`4707`.) + +* The :func:`re.sub`, :func:`re.subn` and :func:`re.split` functions now + accept a flags parameter. + + (Contributed by Gregory Smith.) + +* The :mod:`runpy` module which supports the ``-m`` command line switch + now supports the execution of packages by looking for and executing + a ``__main__`` submodule when a package name is supplied. + + (Contributed by Andi Vajda; :issue:`4195`.) + +* The :mod:`pdb` module can now access and display source code loaded via + :mod:`zipimport` (or any other conformant :pep:`302` loader). + + (Contributed by Alexander Belopolsky; :issue:`4201`.) + +* :class:`functools.partial` objects can now be pickled. + + (Suggested by Antoine Pitrou and Jesse Noller. Implemented by + Jack Diedrich; :issue:`5228`.) + +XXX Brett Cannon's importlib package + +XXX New unittest assert methods .. ====================================================================== @@ -242,6 +284,19 @@ (Contributed by Antoine Pitrou, :issue:`4688`.) +* Enabling a configure option named ``--with-computed-gotos`` + on compilers that support it (notably: gcc, SunPro, icc), the bytecode + evaluation loop is compiled with a new dispatch mechanism which gives + speedups of up to 20%, depending on the system, on various benchmarks. + + (Contributed by Antoine Pitrou and Jeffrey Yasskin along with a number + of other participants, :issue:`4753`). + +* The decoding of UTF-8, UTF-16 and LATIN-1 is now two to four times + faster. + + (Contributed by Antoine Pitrou and Amaury Forgeot d'Arc, :issue:`4868`.) + XXX The JSON module is getting a C extension for speed. .. ====================================================================== From python-checkins at python.org Sat Apr 4 14:33:52 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 14:33:52 +0200 (CEST) Subject: [Python-checkins] r71140 - python/branches/py3k Message-ID: <20090404123352.CF6A21E4046@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 14:33:52 2009 New Revision: 71140 Log: revert r71118 because it blocked an excess of revisions Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Apr 4 14:35:59 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 4 Apr 2009 14:35:59 +0200 (CEST) Subject: [Python-checkins] r71141 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090404123559.7073E1E4046@bag.python.org> Author: raymond.hettinger Date: Sat Apr 4 14:35:58 2009 New Revision: 71141 Log: Complete the first-pass at whatsnew. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Sat Apr 4 14:35:58 2009 @@ -82,12 +82,12 @@ reinserting it will move it to the end. The standard library now supports use of ordered dictionaries in several -modules. The :mod:`ConfigParser` modules uses them by default. This lets +modules. The :mod:`ConfigParser` module uses them by default. This lets configuration files be read, modified, and then written back in their original order. The :mod:`collections` module's :meth:`namedtuple._asdict` method now -returns a dictionary with the values appearing in the same order as the -underlying tuple.count The :mod:`json` module is being built-out with an -*object_pairs_hook* to allow OrderedDicts to be built by the decoder. +returns an ordered dictionary with the values appearing in the same order as +the underlying tuple indicies. The :mod:`json` module is being built-out with +an *object_pairs_hook* to allow OrderedDicts to be built by the decoder. Support was also added for third-party tools like PyYAML. .. seealso:: @@ -107,10 +107,12 @@ >>> format(Decimal('1234567.89'), ',f') '1,234,567.89' -The currently supported types are :class:`int` and :class:`Decimal`. +The currently supported types are :class:`int` and :class:`decimal.Decimal`. Support for :class:`float` is expected before the beta release. Discussions are underway about how to specify alternative separators -like dots, spaces, apostrophes, or underscores. +like dots, spaces, apostrophes, or underscores. Locale-aware applications +should use the existing *n* format specifier which already has some support +for thousands separators. .. seealso:: @@ -138,30 +140,8 @@ >>> (n+1).bit_length() 124 - (Contributed by Fredrik Johansson and Victor Stinner; :issue:`3439`.) - -* Integers are now stored internally either in base 2**15 or in base - 2**30, the base being determined at build time. Previously, they - were always stored in base 2**15. Using base 2**30 gives - significant performance improvements on 64-bit machines, but - benchmark results on 32-bit machines have been mixed. Therefore, - the default is to use base 2**30 on 64-bit machines and base 2**15 - on 32-bit machines; on Unix, there's a new configure option - --enable-big-digits that can be used to override this default. - - Apart from the performance improvements this change should be - invisible to end users, with one exception: for testing and - debugging purposes there's a new structseq ``sys.int_info`` that - provides information about the internal format, giving the number of - bits per digit and the size in bytes of the C type used to store - each digit:: - - >>> import sys - >>> sys.int_info - sys.int_info(bits_per_digit=30, sizeof_digit=4) - - (Contributed by Mark Dickinson; :issue:`4258`.) - + (Contributed by Fredrik Johansson, Victor Stinner, Raymond Hettinger, + and Mark Dickinson; :issue:`3439`.) * Added a :class:`collections.Counter` class to support convenient counting of unique items in a sequence or iterable:: @@ -224,7 +204,7 @@ (Contributed by Raymond Hettinger; :issue:`1818`.) -* :func:`round`(x, n) now returns an integer if *x* is an integer. +* ``round`(x, n)`` now returns an integer if *x* is an integer. Previously it returned a float. (Contributed by Mark Dickinson; :issue:`4707`.) @@ -250,9 +230,20 @@ (Suggested by Antoine Pitrou and Jesse Noller. Implemented by Jack Diedrich; :issue:`5228`.) -XXX Brett Cannon's importlib package +* The :mod:`unittest` module now supports skipping individual tests or classes + of tests. And it supports marking a test as a expected failure, a test that + is known to be broken, but shouldn?t be counted as a failure on a + TestResult. + + (Contributed by Benjamin Peterson.) + +* A new module, :mod:`importlib` was added. It provides a complete, portable, + pure Python reference implementation of the *import* statement and its + counterpart, the :func:`import__` function. It represents a substantial + step forward in documenting and defining the actions that take place during + imports. -XXX New unittest assert methods + (Contributed by Brett Cannon.) .. ====================================================================== @@ -297,6 +288,31 @@ (Contributed by Antoine Pitrou and Amaury Forgeot d'Arc, :issue:`4868`.) -XXX The JSON module is getting a C extension for speed. +* The :mod:`json` module is getting a C extension to substantially improve + its performance. The code is expected to be added in-time for the beta + release. + + (Contributed by Bob Ippolito.) + +* Integers are now stored internally either in base 2**15 or in base + 2**30, the base being determined at build time. Previously, they + were always stored in base 2**15. Using base 2**30 gives + significant performance improvements on 64-bit machines, but + benchmark results on 32-bit machines have been mixed. Therefore, + the default is to use base 2**30 on 64-bit machines and base 2**15 + on 32-bit machines; on Unix, there's a new configure option + ``--enable-big-digits`` that can be used to override this default. + + Apart from the performance improvements this change should be invisible to + end users, with one exception: for testing and debugging purposes there's a + new :class:`structseq` ``sys.int_info`` that provides information about the + internal format, giving the number of bits per digit and the size in bytes + of the C type used to store each digit:: + + >>> import sys + >>> sys.int_info + sys.int_info(bits_per_digit=30, sizeof_digit=4) + + (Contributed by Mark Dickinson; :issue:`4258`.) .. ====================================================================== From python-checkins at python.org Sat Apr 4 14:40:18 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 14:40:18 +0200 (CEST) Subject: [Python-checkins] r71142 - python/branches/py3k Message-ID: <20090404124018.408401E409B@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 14:40:17 2009 New Revision: 71142 Log: Blocked revisions 70711,70713,70716,70719,70747,70772,70821,70830,70844,70873,70901-70902,70904,70918,70934,70969,70986,71026,71073,71075,71078 via svnmerge ........ r70711 | r.david.murray | 2009-03-30 10:14:01 -0500 (Mon, 30 Mar 2009) | 2 lines Convert import try/except to use test_support.import_module(). ........ r70713 | ronald.oussoren | 2009-03-30 10:20:46 -0500 (Mon, 30 Mar 2009) | 2 lines This patch fixes issue 1254695 (wrong argument type conversion in Carbon.Qt) ........ r70716 | r.david.murray | 2009-03-30 10:30:34 -0500 (Mon, 30 Mar 2009) | 2 lines Revert incorrect change. ........ r70719 | ronald.oussoren | 2009-03-30 11:01:51 -0500 (Mon, 30 Mar 2009) | 2 lines Fix for issue 896199 (some Carbon modules aren't present in the documentation) ........ r70747 | r.david.murray | 2009-03-30 15:04:06 -0500 (Mon, 30 Mar 2009) | 3 lines Remove references to test_socket_ssl which was deleted in trunk in r64392 and py3k in r59038. ........ r70772 | barry.warsaw | 2009-03-30 17:42:17 -0500 (Mon, 30 Mar 2009) | 5 lines A fix for issue 1974, inspired by the patch from Andi Albrecht (aalbrecht), though with some changes by me. This patch should not be back ported or forward ported. It's a bit too risky for 2.6 and 3.x does things fairly differently. ........ r70821 | jeremy.hylton | 2009-03-31 10:04:15 -0500 (Tue, 31 Mar 2009) | 2 lines Add check for PyDict_Update() error. ........ r70830 | georg.brandl | 2009-03-31 11:11:45 -0500 (Tue, 31 Mar 2009) | 1 line #5529: backport new docs of import semantics written by Brett to 2.x. ........ r70844 | raymond.hettinger | 2009-03-31 12:47:06 -0500 (Tue, 31 Mar 2009) | 1 line Per the language summit, the optional fastpath imports should use from-import-star. ........ r70873 | josiah.carlson | 2009-03-31 14:32:34 -0500 (Tue, 31 Mar 2009) | 2 lines This resolves issue 1161031. Tests pass. ........ r70901 | georg.brandl | 2009-03-31 16:40:24 -0500 (Tue, 31 Mar 2009) | 2 lines Remove warning about pending Win9x support removal. ........ r70902 | georg.brandl | 2009-03-31 16:43:03 -0500 (Tue, 31 Mar 2009) | 1 line #1675026: add a note about a strange Windows problem, and remove notes about AtheOS. ........ r70904 | josiah.carlson | 2009-03-31 16:49:36 -0500 (Tue, 31 Mar 2009) | 3 lines Made handle_expt_event() be called last, so that we don't accidentally read after closing the socket. ........ r70918 | raymond.hettinger | 2009-03-31 17:43:03 -0500 (Tue, 31 Mar 2009) | 1 line Improve examples for collections.deque() ........ r70934 | josiah.carlson | 2009-03-31 20:28:11 -0500 (Tue, 31 Mar 2009) | 2 lines Fix for failing asyncore tests. ........ r70969 | raymond.hettinger | 2009-04-01 13:50:56 -0500 (Wed, 01 Apr 2009) | 1 line Issue #5647: MutableSet.__iand__() no longer mutates self during iteration. ........ r70986 | raymond.hettinger | 2009-04-01 15:50:58 -0500 (Wed, 01 Apr 2009) | 1 line Add link to an alternative generator with a long-period. ........ r71026 | benjamin.peterson | 2009-04-01 21:52:46 -0500 (Wed, 01 Apr 2009) | 1 line fix error handling ........ r71073 | raymond.hettinger | 2009-04-02 17:25:40 -0500 (Thu, 02 Apr 2009) | 4 lines Have namedtuple's field renamer assign names that are consistent with the corresponding tuple index. ........ r71075 | raymond.hettinger | 2009-04-02 17:34:17 -0500 (Thu, 02 Apr 2009) | 1 line Update docs for namedtuple's renaming change. ........ r71078 | raymond.hettinger | 2009-04-02 21:43:54 -0500 (Thu, 02 Apr 2009) | 4 lines Localize the function lookup in timeit. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Apr 4 14:42:54 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 14:42:54 +0200 (CEST) Subject: [Python-checkins] r71143 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090404124254.19D381E4046@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 14:42:53 2009 New Revision: 71143 Log: typo Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Sat Apr 4 14:42:53 2009 @@ -239,7 +239,7 @@ * A new module, :mod:`importlib` was added. It provides a complete, portable, pure Python reference implementation of the *import* statement and its - counterpart, the :func:`import__` function. It represents a substantial + counterpart, the :func:`__import__` function. It represents a substantial step forward in documenting and defining the actions that take place during imports. From python-checkins at python.org Sat Apr 4 14:46:57 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 4 Apr 2009 14:46:57 +0200 (CEST) Subject: [Python-checkins] r71144 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090404124657.E2ABF1E4046@bag.python.org> Author: raymond.hettinger Date: Sat Apr 4 14:46:57 2009 New Revision: 71144 Log: Eliminate a duplicate entry. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Sat Apr 4 14:46:57 2009 @@ -262,12 +262,6 @@ (Contributed by Amaury Forgeot d'Arc and Antoine Pitrou.) -* A new configure flag, ``--with-computed-gotos``, enables a faster opcode - dispatch mechanism on compilers which support it. Speedups of up to 20% - have been observed, depending on the system and compiler. - - (Contributed by Antoine Pitrou, :issue:`4753`.) - * Add a heuristic so that tuples and dicts containing only untrackable objects are not tracked by the garbage collector. This can reduce the size of collections and therefore the garbage collection overhead on long-running @@ -278,10 +272,11 @@ * Enabling a configure option named ``--with-computed-gotos`` on compilers that support it (notably: gcc, SunPro, icc), the bytecode evaluation loop is compiled with a new dispatch mechanism which gives - speedups of up to 20%, depending on the system, on various benchmarks. + speedups of up to 20%, depending on the system, the compiler, and + the benchmark. - (Contributed by Antoine Pitrou and Jeffrey Yasskin along with a number - of other participants, :issue:`4753`). + (Contributed by Antoine Pitrou along with a number of other participants, + :issue:`4753`). * The decoding of UTF-8, UTF-16 and LATIN-1 is now two to four times faster. From python-checkins at python.org Sat Apr 4 14:51:52 2009 From: python-checkins at python.org (matthias.klose) Date: Sat, 4 Apr 2009 14:51:52 +0200 (CEST) Subject: [Python-checkins] r71145 - in python/branches/release26-maint: Lib/sgmllib.py Lib/test/test_sgmllib.py Message-ID: <20090404125152.596B41E4156@bag.python.org> Author: matthias.klose Date: Sat Apr 4 14:51:52 2009 New Revision: 71145 Log: Merged revisions 70906 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70906 | georg.brandl | 2009-04-01 00:11:53 +0200 (Mi, 01 Apr 2009) | 1 line #1651995: fix _convert_ref for non-ASCII characters. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/sgmllib.py python/branches/release26-maint/Lib/test/test_sgmllib.py Modified: python/branches/release26-maint/Lib/sgmllib.py ============================================================================== --- python/branches/release26-maint/Lib/sgmllib.py (original) +++ python/branches/release26-maint/Lib/sgmllib.py Sat Apr 4 14:51:52 2009 @@ -396,7 +396,7 @@ n = int(name) except ValueError: return - if not 0 <= n <= 255: + if not 0 <= n <= 127: return return self.convert_codepoint(n) Modified: python/branches/release26-maint/Lib/test/test_sgmllib.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_sgmllib.py (original) +++ python/branches/release26-maint/Lib/test/test_sgmllib.py Sat Apr 4 14:51:52 2009 @@ -373,6 +373,15 @@ if len(data) != CHUNK: break + def test_only_decode_ascii(self): + # SF bug #1651995, make sure non-ascii character references are not decoded + s = '' + self.check_events(s, [ + ('starttag', 'signs', + [('exclamation', '!'), ('copyright', '©'), + ('quoteleft', '‘')]), + ]) + # XXX These tests have been disabled by prefixing their names with # an underscore. The first two exercise outstanding bugs in the # sgmllib module, and the third exhibits questionable behavior From python-checkins at python.org Sat Apr 4 15:01:20 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 4 Apr 2009 15:01:20 +0200 (CEST) Subject: [Python-checkins] r71146 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090404130120.B81D31E4156@bag.python.org> Author: raymond.hettinger Date: Sat Apr 4 15:01:19 2009 New Revision: 71146 Log: Fix nits. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Sat Apr 4 15:01:19 2009 @@ -232,7 +232,7 @@ * The :mod:`unittest` module now supports skipping individual tests or classes of tests. And it supports marking a test as a expected failure, a test that - is known to be broken, but shouldn?t be counted as a failure on a + is known to be broken, but shouldn't be counted as a failure on a TestResult. (Contributed by Benjamin Peterson.) @@ -262,7 +262,7 @@ (Contributed by Amaury Forgeot d'Arc and Antoine Pitrou.) -* Add a heuristic so that tuples and dicts containing only untrackable objects +* Added a heuristic so that tuples and dicts containing only untrackable objects are not tracked by the garbage collector. This can reduce the size of collections and therefore the garbage collection overhead on long-running programs, depending on their particular use of datatypes. From python-checkins at python.org Sat Apr 4 15:13:56 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 4 Apr 2009 15:13:56 +0200 (CEST) Subject: [Python-checkins] r71147 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090404131356.E62A61E4046@bag.python.org> Author: raymond.hettinger Date: Sat Apr 4 15:13:56 2009 New Revision: 71147 Log: Remove minor entry. Add the ttk module. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Sat Apr 4 15:13:56 2009 @@ -93,8 +93,8 @@ .. seealso:: :pep:`372` - Ordered Dictionaries - PEP written by Armin Ronacher and Raymond Hettinger; implemented by - Raymond Hettinger + PEP written by Armin Ronacher and Raymond Hettinger. Implementation + written by Raymond Hettinger. PEP 378: Format Specifier for Thousands Separator ================================================= @@ -151,6 +151,13 @@ (Contributed by Raymond Hettinger; :issue:`1696199`.) +* Add a new module, :mod:`ttk` for access to the Tk themed widget set. The + basic idea of ttk is to separate, to the extent possible, the code + implementing a widget's behavior from the code implementing its appearance. + + (Contributed by Kevin Walzer and Guilherme Polo; :issue:`2618` and + :issue:`2983`.) + * The :class:`gzip.GzipFile` and :class:`bz2.BZ2File` classs now support the context manager protocol. @@ -191,11 +198,6 @@ (Contributed by Raymond Hettinger.) -* :class:`collections.deque` objects now have a read-only attribute - called *maxlen*. - - (Contributed by Raymond Hettinger.) - * :func:`collections.namedtuple` now supports a keyword argument *rename* which lets invalid fieldnames be automatically converted to positional names in the form _0, _1, etc. This is useful when From python-checkins at python.org Sat Apr 4 15:20:55 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 4 Apr 2009 15:20:55 +0200 (CEST) Subject: [Python-checkins] r71148 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090404132055.DC3551E417C@bag.python.org> Author: raymond.hettinger Date: Sat Apr 4 15:20:55 2009 New Revision: 71148 Log: Note an improvement to pydoc. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Sat Apr 4 15:20:55 2009 @@ -232,6 +232,11 @@ (Suggested by Antoine Pitrou and Jesse Noller. Implemented by Jack Diedrich; :issue:`5228`.) +* Add :mod:`pydoc` help topics for symbols so that ``help('@')`` + works as expected in the interactive environment. + + (Contributed by David Laban; :issue:`4739`.) + * The :mod:`unittest` module now supports skipping individual tests or classes of tests. And it supports marking a test as a expected failure, a test that is known to be broken, but shouldn't be counted as a failure on a From python-checkins at python.org Sat Apr 4 15:42:39 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 4 Apr 2009 15:42:39 +0200 (CEST) Subject: [Python-checkins] r71149 - python/trunk/Doc/library/multiprocessing.rst Message-ID: <20090404134239.8CCC31E4046@bag.python.org> Author: georg.brandl Date: Sat Apr 4 15:42:39 2009 New Revision: 71149 Log: #5642: clarify map() compatibility to the builtin. Modified: python/trunk/Doc/library/multiprocessing.rst Modified: python/trunk/Doc/library/multiprocessing.rst ============================================================================== --- python/trunk/Doc/library/multiprocessing.rst (original) +++ python/trunk/Doc/library/multiprocessing.rst Sat Apr 4 15:42:39 2009 @@ -1549,8 +1549,8 @@ .. method:: map(func, iterable[, chunksize]) - A parallel equivalent of the :func:`map` builtin function. It blocks till - the result is ready. + A parallel equivalent of the :func:`map` builtin function (it supports only + one *iterable* argument though). It blocks till the result is ready. This method chops the iterable into a number of chunks which it submits to the process pool as separate tasks. The (approximate) size of these From python-checkins at python.org Sat Apr 4 15:45:49 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 4 Apr 2009 15:45:49 +0200 (CEST) Subject: [Python-checkins] r71150 - python/trunk/Doc/library/webbrowser.rst Message-ID: <20090404134549.E8E2F1E437C@bag.python.org> Author: georg.brandl Date: Sat Apr 4 15:45:49 2009 New Revision: 71150 Log: #5601: clarify that webbrowser is not meant for file names. Modified: python/trunk/Doc/library/webbrowser.rst Modified: python/trunk/Doc/library/webbrowser.rst ============================================================================== --- python/trunk/Doc/library/webbrowser.rst (original) +++ python/trunk/Doc/library/webbrowser.rst Sat Apr 4 15:45:49 2009 @@ -55,6 +55,10 @@ under many window managers this will occur regardless of the setting of this variable). + Note that on some platforms, trying to open a filename using this function, + may work and start the operating system's associated program. However, this + is neither supported nor portable. + .. versionchanged:: 2.5 *new* can now be 2. From buildbot at python.org Sat Apr 4 15:49:54 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 13:49:54 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 2.6 Message-ID: <20090404134954.D3E601E41D3@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%202.6/builds/221 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: matthias.klose BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Sat Apr 4 16:09:32 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 4 Apr 2009 16:09:32 +0200 (CEST) Subject: [Python-checkins] r71151 - python/branches/py3k/Lib/_pyio.py Message-ID: <20090404140932.1F8001E41D3@bag.python.org> Author: antoine.pitrou Date: Sat Apr 4 16:09:30 2009 New Revision: 71151 Log: Fix test_memoryio under Windows Modified: python/branches/py3k/Lib/_pyio.py Modified: python/branches/py3k/Lib/_pyio.py ============================================================================== --- python/branches/py3k/Lib/_pyio.py (original) +++ python/branches/py3k/Lib/_pyio.py Sat Apr 4 16:09:30 2009 @@ -1829,6 +1829,10 @@ encoding="utf-8", errors="strict", newline=newline) + # Issue #5645: make universal newlines semantics the same as in the + # C version, even under Windows. + if newline is None: + self._writetranslate = False if initial_value: if not isinstance(initial_value, str): initial_value = str(initial_value) From python-checkins at python.org Sat Apr 4 16:18:13 2009 From: python-checkins at python.org (matthias.klose) Date: Sat, 4 Apr 2009 16:18:13 +0200 (CEST) Subject: [Python-checkins] r71152 - in python/trunk: Misc/NEWS Python/pythonrun.c Message-ID: <20090404141813.B04DB1E441D@bag.python.org> Author: matthias.klose Date: Sat Apr 4 16:18:13 2009 New Revision: 71152 Log: - Issue #3845: In PyRun_SimpleFileExFlags avoid invalid memory access with short file names. Modified: python/trunk/Misc/NEWS python/trunk/Python/pythonrun.c Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Apr 4 16:18:13 2009 @@ -204,6 +204,9 @@ - The re.sub(), re.subn() and re.split() functions now accept a flags parameter. +- Issue #3845: In PyRun_SimpleFileExFlags avoid invalid memory access with + short file names. + Library ------- Modified: python/trunk/Python/pythonrun.c ============================================================================== --- python/trunk/Python/pythonrun.c (original) +++ python/trunk/Python/pythonrun.c Sat Apr 4 16:18:13 2009 @@ -898,7 +898,7 @@ { PyObject *m, *d, *v; const char *ext; - int set_file_name = 0, ret; + int set_file_name = 0, ret, len; m = PyImport_AddModule("__main__"); if (m == NULL) @@ -915,7 +915,8 @@ set_file_name = 1; Py_DECREF(f); } - ext = filename + strlen(filename) - 4; + len = strlen(filename); + ext = filename + len - (len > 4 ? 4 : 0); if (maybe_pyc_file(fp, filename, ext, closeit)) { /* Try to run a pyc file. First, re-open in binary */ if (closeit) From python-checkins at python.org Sat Apr 4 16:19:57 2009 From: python-checkins at python.org (matthias.klose) Date: Sat, 4 Apr 2009 16:19:57 +0200 (CEST) Subject: [Python-checkins] r71153 - in python/branches/release26-maint: Misc/NEWS Python/pythonrun.c Message-ID: <20090404141957.3086D1E4346@bag.python.org> Author: matthias.klose Date: Sat Apr 4 16:19:56 2009 New Revision: 71153 Log: Merged revisions 71152 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71152 | matthias.klose | 2009-04-04 16:18:13 +0200 (Sa, 04 Apr 2009) | 3 lines - Issue #3845: In PyRun_SimpleFileExFlags avoid invalid memory access with short file names. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Python/pythonrun.c Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sat Apr 4 16:19:56 2009 @@ -89,6 +89,9 @@ - Issue #4509: Various issues surrounding resize of bytearray objects to which there are buffer exports. +- Issue #3845: In PyRun_SimpleFileExFlags avoid invalid memory access with + short file names. + Library ------- Modified: python/branches/release26-maint/Python/pythonrun.c ============================================================================== --- python/branches/release26-maint/Python/pythonrun.c (original) +++ python/branches/release26-maint/Python/pythonrun.c Sat Apr 4 16:19:56 2009 @@ -895,7 +895,7 @@ { PyObject *m, *d, *v; const char *ext; - int set_file_name = 0, ret; + int set_file_name = 0, ret, len; m = PyImport_AddModule("__main__"); if (m == NULL) @@ -912,7 +912,8 @@ set_file_name = 1; Py_DECREF(f); } - ext = filename + strlen(filename) - 4; + len = strlen(filename); + ext = filename + len - (len > 4 ? 4 : 0); if (maybe_pyc_file(fp, filename, ext, closeit)) { /* Try to run a pyc file. First, re-open in binary */ if (closeit) From python-checkins at python.org Sat Apr 4 16:32:42 2009 From: python-checkins at python.org (matthias.klose) Date: Sat, 4 Apr 2009 16:32:42 +0200 (CEST) Subject: [Python-checkins] r71154 - in python/branches/py3k: Misc/NEWS Python/pythonrun.c Message-ID: <20090404143242.B31051E4401@bag.python.org> Author: matthias.klose Date: Sat Apr 4 16:32:42 2009 New Revision: 71154 Log: Merged revisions 71152 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71152 | matthias.klose | 2009-04-04 16:18:13 +0200 (Sa, 04 Apr 2009) | 3 lines - Issue #3845: In PyRun_SimpleFileExFlags avoid invalid memory access with short file names. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Misc/NEWS python/branches/py3k/Python/pythonrun.c Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Apr 4 16:32:42 2009 @@ -59,6 +59,9 @@ - Issue #5392: when a very low recursion limit was set, the interpreter would abort with a fatal error after the recursion limit was hit twice. +- Issue #3845: In PyRun_SimpleFileExFlags avoid invalid memory access with + short file names. + Library ------- Modified: python/branches/py3k/Python/pythonrun.c ============================================================================== --- python/branches/py3k/Python/pythonrun.c (original) +++ python/branches/py3k/Python/pythonrun.c Sat Apr 4 16:32:42 2009 @@ -1145,7 +1145,7 @@ { PyObject *m, *d, *v; const char *ext; - int set_file_name = 0, ret; + int set_file_name = 0, ret, len; m = PyImport_AddModule("__main__"); if (m == NULL) @@ -1163,7 +1163,8 @@ set_file_name = 1; Py_DECREF(f); } - ext = filename + strlen(filename) - 4; + len = strlen(filename); + ext = filename + len - (len > 4 ? 4 : 0); if (maybe_pyc_file(fp, filename, ext, closeit)) { /* Try to run a pyc file. First, re-open in binary */ if (closeit) From buildbot at python.org Sat Apr 4 16:43:14 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 14:43:14 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090404144315.4341A1E4398@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/476 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_importlib test_posix Traceback (most recent call last): File "./Lib/test/regrtest.py", line 620, in runtest_inner File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_importlib.py", line 6, in test_main run_unittest(importlib.test.test_suite('importlib.test')) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/__init__.py", line 22, in test_suite package_tests = getattr(sys.modules[package_name], 'test_suite')() File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/source/__init__.py", line 8, in test_suite return importlib.test.test_suite('importlib.test.source', directory) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/__init__.py", line 16, in test_suite __import__(module_name, level=0) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/source/test_case_sensitivity.py", line 12, in class CaseSensitivityTest(unittest.TestCase): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/util.py", line 13, in case_insensitive_tests original_name = os.listdir('.')[0] IndexError: list index out of range ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 249, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 102, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Sat Apr 4 17:09:28 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 4 Apr 2009 17:09:28 +0200 (CEST) Subject: [Python-checkins] r71155 - in python/branches/py3k-short-float-repr: Lib/test/formatfloat_testcases.txt Python/pystrtod.c Message-ID: <20090404150928.7E02D1E4023@bag.python.org> Author: mark.dickinson Date: Sat Apr 4 17:09:28 2009 New Revision: 71155 Log: Sort out repr formatting Modified: python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt (original) +++ python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt Sat Apr 4 17:09:28 2009 @@ -245,3 +245,33 @@ %#.4g 234.56 -> 234.6 %#.5g 234.56 -> 234.56 %#.6g 234.56 -> 234.560 + +-- repr formatting. Should always include a decimal point or an exponent. +%r 0 -> 0.0 +%r 1 -> 1.0 + +-- short repr: should produce shortest string that rounds correctly +%r 0.01 -> 0.01 +%r 0.02 -> 0.02 +%r 0.03 -> 0.03 +%r 0.04 -> 0.04 +%r 0.05 -> 0.05 +%r 1.23456789 -> 1.23456789 +%r 10 -> 10.0 +%r 100 -> 100.0 + +-- values >= 1e16 get an exponent +%r 1e15 -> 1000000000000000.0 +%r 0.999999999999e16 -> 9999999999990000.0 +%r 1e16 -> 1e+16 +%r 1.000000000001e16 -> 1.000000000001e+16 +%r 1e17 -> 1e+17 + +-- as do values < 1e-4 +%r 1e-3 -> 0.001 +%r 1.001e-4 -> 0.0001001 +%r 1.000000000001e-4 -> 0.0001000000000001 +%r 1e-4 -> 0.0001 +%r 0.999999999999e-4 -> 9.99999999999e-05 +%r 0.999e-4 -> 9.99e-05 +%r 1e-5 -> 1e-05 Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Sat Apr 4 17:09:28 2009 @@ -609,6 +609,14 @@ else trailing_zeros = 0; break; + case 'r': + /* use exponent for values >= 1e16 or < 1e-4 */ + if ((-4 < decpt) && (decpt <= 16)) + use_exp = 0; + else + use_exp = 1; + trailing_zeros = 0; + break; } /* Always add a negative sign, and a plus sign if always_add_sign. */ @@ -736,7 +744,6 @@ break; case 'r': /* "repr" pseudo-mode */ - lc_format_code = 'g'; mode = 0; break; } From python-checkins at python.org Sat Apr 4 17:32:09 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 17:32:09 +0200 (CEST) Subject: [Python-checkins] r71156 - python/branches/py3k Message-ID: <20090404153209.182BC1E4023@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 17:32:08 2009 New Revision: 71156 Log: try to fix svnmerge-blocked property Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Apr 4 17:38:20 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 17:38:20 +0200 (CEST) Subject: [Python-checkins] r71157 - python/branches/py3k Message-ID: <20090404153820.7D28B1E4061@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 17:38:19 2009 New Revision: 71157 Log: Blocked revisions 70711,70713,70716,70719,70747,70772,70821,70830,70844,70873,70901-70902,70904,70918,70934,70969,71026,71073,71075,71078 via svnmerge ........ r70711 | r.david.murray | 2009-03-30 10:14:01 -0500 (Mon, 30 Mar 2009) | 2 lines Convert import try/except to use test_support.import_module(). ........ r70713 | ronald.oussoren | 2009-03-30 10:20:46 -0500 (Mon, 30 Mar 2009) | 2 lines This patch fixes issue 1254695 (wrong argument type conversion in Carbon.Qt) ........ r70716 | r.david.murray | 2009-03-30 10:30:34 -0500 (Mon, 30 Mar 2009) | 2 lines Revert incorrect change. ........ r70719 | ronald.oussoren | 2009-03-30 11:01:51 -0500 (Mon, 30 Mar 2009) | 2 lines Fix for issue 896199 (some Carbon modules aren't present in the documentation) ........ r70747 | r.david.murray | 2009-03-30 15:04:06 -0500 (Mon, 30 Mar 2009) | 3 lines Remove references to test_socket_ssl which was deleted in trunk in r64392 and py3k in r59038. ........ r70772 | barry.warsaw | 2009-03-30 17:42:17 -0500 (Mon, 30 Mar 2009) | 5 lines A fix for issue 1974, inspired by the patch from Andi Albrecht (aalbrecht), though with some changes by me. This patch should not be back ported or forward ported. It's a bit too risky for 2.6 and 3.x does things fairly differently. ........ r70821 | jeremy.hylton | 2009-03-31 10:04:15 -0500 (Tue, 31 Mar 2009) | 2 lines Add check for PyDict_Update() error. ........ r70830 | georg.brandl | 2009-03-31 11:11:45 -0500 (Tue, 31 Mar 2009) | 1 line #5529: backport new docs of import semantics written by Brett to 2.x. ........ r70844 | raymond.hettinger | 2009-03-31 12:47:06 -0500 (Tue, 31 Mar 2009) | 1 line Per the language summit, the optional fastpath imports should use from-import-star. ........ r70873 | josiah.carlson | 2009-03-31 14:32:34 -0500 (Tue, 31 Mar 2009) | 2 lines This resolves issue 1161031. Tests pass. ........ r70901 | georg.brandl | 2009-03-31 16:40:24 -0500 (Tue, 31 Mar 2009) | 2 lines Remove warning about pending Win9x support removal. ........ r70902 | georg.brandl | 2009-03-31 16:43:03 -0500 (Tue, 31 Mar 2009) | 1 line #1675026: add a note about a strange Windows problem, and remove notes about AtheOS. ........ r70904 | josiah.carlson | 2009-03-31 16:49:36 -0500 (Tue, 31 Mar 2009) | 3 lines Made handle_expt_event() be called last, so that we don't accidentally read after closing the socket. ........ r70918 | raymond.hettinger | 2009-03-31 17:43:03 -0500 (Tue, 31 Mar 2009) | 1 line Improve examples for collections.deque() ........ r70934 | josiah.carlson | 2009-03-31 20:28:11 -0500 (Tue, 31 Mar 2009) | 2 lines Fix for failing asyncore tests. ........ r70969 | raymond.hettinger | 2009-04-01 13:50:56 -0500 (Wed, 01 Apr 2009) | 1 line Issue #5647: MutableSet.__iand__() no longer mutates self during iteration. ........ r71026 | benjamin.peterson | 2009-04-01 21:52:46 -0500 (Wed, 01 Apr 2009) | 1 line fix error handling ........ r71073 | raymond.hettinger | 2009-04-02 17:25:40 -0500 (Thu, 02 Apr 2009) | 4 lines Have namedtuple's field renamer assign names that are consistent with the corresponding tuple index. ........ r71075 | raymond.hettinger | 2009-04-02 17:34:17 -0500 (Thu, 02 Apr 2009) | 1 line Update docs for namedtuple's renaming change. ........ r71078 | raymond.hettinger | 2009-04-02 21:43:54 -0500 (Thu, 02 Apr 2009) | 4 lines Localize the function lookup in timeit. ........ Modified: python/branches/py3k/ (props changed) From buildbot at python.org Sat Apr 4 17:41:51 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 15:41:51 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 3.x Message-ID: <20090404154152.341741E4023@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%20gentoo%203.x/builds/565 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-amd64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: matthias.klose BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_io test_smtplib ====================================================================== ERROR: test_basic_io (test.test_io.CTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1601, in test_basic_io self.assertEquals(f.read(), "abc") File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_encoding_errors_reading (test.test_io.CTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1425, in test_encoding_errors_reading self.assertRaises(UnicodeError, t.read) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/unittest.py", line 450, in failUnlessRaises callableObj(*args, **kwargs) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_issue1395_1 (test.test_io.CTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1792, in test_issue1395_1 c = txt.read(1) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_issue1395_2 (test.test_io.CTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1804, in test_issue1395_2 c = txt.read(4) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_issue1395_3 (test.test_io.CTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1814, in test_issue1395_3 reads = txt.read(4) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_issue1395_4 (test.test_io.CTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1825, in test_issue1395_4 reads = txt.read(4) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_issue1395_5 (test.test_io.CTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1833, in test_issue1395_5 reads = txt.read(4) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_newlines_input (test.test_io.CTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1517, in test_newlines_input self.assertEquals(txt.readlines(), expected) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_basic_io (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1596, in test_basic_io self.assertEquals(f.write("abc"), 3) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1471, in write b = encoder.encode(s) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 22, in encode return codecs.ascii_encode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_encode' ====================================================================== ERROR: test_destructor (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1548, in test_destructor t.write("abc") File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1471, in write b = encoder.encode(s) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 22, in encode return codecs.ascii_encode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_encode' ====================================================================== ERROR: test_encoding_errors_reading (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1425, in test_encoding_errors_reading self.assertRaises(UnicodeError, t.read) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/unittest.py", line 450, in failUnlessRaises callableObj(*args, **kwargs) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1707, in read decoder.decode(self.buffer.read(), final=True)) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1264, in decode output = self.decoder.decode(input, final=final) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_encoding_errors_writing (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1443, in test_encoding_errors_writing self.assertRaises(UnicodeError, t.write, "\xff") File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/unittest.py", line 450, in failUnlessRaises callableObj(*args, **kwargs) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1471, in write b = encoder.encode(s) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 22, in encode return codecs.ascii_encode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_encode' ====================================================================== ERROR: test_issue1395_1 (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1792, in test_issue1395_1 c = txt.read(1) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1716, in read eof = not self._read_chunk() File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1542, in _read_chunk self._set_decoded_chars(self._decoder.decode(input_chunk, eof)) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1264, in decode output = self.decoder.decode(input, final=final) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_issue1395_2 (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1804, in test_issue1395_2 c = txt.read(4) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1716, in read eof = not self._read_chunk() File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1542, in _read_chunk self._set_decoded_chars(self._decoder.decode(input_chunk, eof)) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1264, in decode output = self.decoder.decode(input, final=final) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_issue1395_3 (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1814, in test_issue1395_3 reads = txt.read(4) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1716, in read eof = not self._read_chunk() File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1542, in _read_chunk self._set_decoded_chars(self._decoder.decode(input_chunk, eof)) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1264, in decode output = self.decoder.decode(input, final=final) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_issue1395_4 (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1825, in test_issue1395_4 reads = txt.read(4) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1716, in read eof = not self._read_chunk() File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1542, in _read_chunk self._set_decoded_chars(self._decoder.decode(input_chunk, eof)) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1264, in decode output = self.decoder.decode(input, final=final) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_issue1395_5 (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1833, in test_issue1395_5 reads = txt.read(4) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1716, in read eof = not self._read_chunk() File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1542, in _read_chunk self._set_decoded_chars(self._decoder.decode(input_chunk, eof)) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1264, in decode output = self.decoder.decode(input, final=final) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_newlines_input (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1517, in test_newlines_input self.assertEquals(txt.readlines(), expected) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 490, in readlines return list(self) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1722, in __next__ line = self.readline() File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1797, in readline while self._read_chunk(): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1542, in _read_chunk self._set_decoded_chars(self._decoder.decode(input_chunk, eof)) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1264, in decode output = self.decoder.decode(input, final=final) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' ====================================================================== ERROR: test_newlines_output (test.test_io.PyTextIOWrapperTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_io.py", line 1532, in test_newlines_output txt.write("AAA\nB") File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/_pyio.py", line 1471, in write b = encoder.encode(s) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/encodings/ascii.py", line 22, in encode return codecs.ascii_encode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_encode' make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sat Apr 4 17:44:41 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 4 Apr 2009 17:44:41 +0200 (CEST) Subject: [Python-checkins] r71158 - in python/branches/py3k-short-float-repr: Lib/test/formatfloat_testcases.txt Python/pystrtod.c Message-ID: <20090404154441.BCC1F1E4061@bag.python.org> Author: mark.dickinson Date: Sat Apr 4 17:44:41 2009 New Revision: 71158 Log: alt_formatting should apply to 'e' and 'f', not just to 'g' Modified: python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt (original) +++ python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt Sat Apr 4 17:44:41 2009 @@ -23,7 +23,6 @@ %.0f 1234.56 -> 1235 %.0f 1e49 -> 9999999999999999464902769475481793196872414789632 %.0f 9.9999999999999987e+49 -> 99999999999999986860582406952576489172979654066176 --- %.0f 1e50 -> 1e50 -- precision 1 %.1f 0.0001 -> 0.0 @@ -57,6 +56,16 @@ %.2f 1234567.891 -> 1234567.89 %.2f 1234567.8912 -> 1234567.89 +-- alternate form always includes a decimal point. This only +-- makes a difference when the precision is 0. +%#.0f 0 -> 0. +%#.1f 0 -> 0.0 +%#.0f 1.5 -> 2. +%#.0f 2.5 -> 2. +%#.0f 10.1 -> 10. +%#.0f 1234.56 -> 1235. +%#.1f 1.4 -> 1.4 +%#.2f 0.375 -> 0.38 -- 'e' code formatting with explicit precision (>= 0). Output should -- always have exactly the number of places after the point that were @@ -134,6 +143,42 @@ %.2e 1598.76 -> 1.60e+03 %.2e 9999 -> 1.00e+04 +-- alternate form always contains a decimal point. This only makes +-- a difference when precision is 0. + +%#.0e 0.01 -> 1.e-02 +%#.0e 0.1 -> 1.e-01 +%#.0e 1 -> 1.e+00 +%#.0e 10 -> 1.e+01 +%#.0e 100 -> 1.e+02 +%#.0e 0.012 -> 1.e-02 +%#.0e 0.12 -> 1.e-01 +%#.0e 1.2 -> 1.e+00 +%#.0e 12 -> 1.e+01 +%#.0e 120 -> 1.e+02 +%#.0e 123.456 -> 1.e+02 +%#.0e 0.000123456 -> 1.e-04 +%#.0e 123456000 -> 1.e+08 +%#.0e 0.5 -> 5.e-01 +%#.0e 1.4 -> 1.e+00 +%#.0e 1.5 -> 2.e+00 +%#.0e 1.6 -> 2.e+00 +%#.0e 2.4999999 -> 2.e+00 +%#.0e 2.5 -> 2.e+00 +%#.0e 2.5000001 -> 3.e+00 +%#.0e 3.499999999999 -> 3.e+00 +%#.0e 3.5 -> 4.e+00 +%#.0e 4.5 -> 4.e+00 +%#.0e 5.5 -> 6.e+00 +%#.0e 6.5 -> 6.e+00 +%#.0e 7.5 -> 8.e+00 +%#.0e 8.5 -> 8.e+00 +%#.0e 9.4999 -> 9.e+00 +%#.0e 9.5 -> 1.e+01 +%#.0e 10.5 -> 1.e+01 +%#.0e 14.999 -> 1.e+01 +%#.0e 15 -> 2.e+01 + -- 'g' code formatting. -- zeros @@ -246,11 +291,14 @@ %#.5g 234.56 -> 234.56 %#.6g 234.56 -> 234.560 --- repr formatting. Should always include a decimal point or an exponent. +-- repr formatting. Should always include a decimal point (and at +-- least one digit after the point) or an exponent. Produces the shortest +-- string that rounds correctly. + %r 0 -> 0.0 %r 1 -> 1.0 --- short repr: should produce shortest string that rounds correctly +-- check short repr %r 0.01 -> 0.01 %r 0.02 -> 0.02 %r 0.03 -> 0.03 @@ -275,3 +323,45 @@ %r 0.999999999999e-4 -> 9.99999999999e-05 %r 0.999e-4 -> 9.99e-05 %r 1e-5 -> 1e-05 + +-- str formatting. Result always includes decimal point and at +-- least one digit after the point, or an exponent. + +%s 0 -> 0.0 +%s 1 -> 1.0 + +%s 0.01 -> 0.01 +%s 0.02 -> 0.02 +%s 0.03 -> 0.03 +%s 0.04 -> 0.04 +%s 0.05 -> 0.05 + +-- str truncates to 12 significant digits +%s 1.234123412341 -> 1.23412341234 +%s 1.23412341234 -> 1.23412341234 +%s 1.2341234123 -> 1.2341234123 + +-- values >= 1e11 get an exponent +%s 10 -> 10.0 +%s 100 -> 100.0 +%s 1e10 -> 10000000000.0 +%s 9.999e10 -> 99990000000.0 +%s 99999999999 -> 99999999999.0 +%s 1e12 -> 1e+12 + +-- as do values < 1e-4 +%s 1e-3 -> 0.001 +%s 1.001e-4 -> 0.0001001 +%s 1.000000000001e-4 -> 0.0001 +%s 1.00000000001e-4 -> 0.000100000000001 +%s 1.0000000001e-4 -> 0.00010000000001 +%s 1e-4 -> 0.0001 +%s 0.999999999999e-4 -> 9.99999999999e-05 +%s 0.999e-4 -> 9.99e-05 +%s 1e-5 -> 1e-05 + + +-- removed tests: need to decide what to do with these + +-- %s 1e11 -> 1e+11 +-- %.0f 1e50 -> 1e50 Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Sat Apr 4 17:44:41 2009 @@ -664,8 +664,9 @@ buf += trailing_zeros; } - /* If we're at a trailing decimal, delete it. We are then just an integer. */ - if (buf[-1] == '.' && !(format_code == 'g' && use_alt_formatting)) { + /* If we're at a trailing decimal, delete it. We are then just an + integer. */ + if (buf[-1] == '.' && !use_alt_formatting) { buf--; is_integer = 1; } From python-checkins at python.org Sat Apr 4 17:51:24 2009 From: python-checkins at python.org (matthias.klose) Date: Sat, 4 Apr 2009 17:51:24 +0200 (CEST) Subject: [Python-checkins] r71159 - in python/trunk: Include/object.h Misc/NEWS Message-ID: <20090404155124.5F4FF1E4061@bag.python.org> Author: matthias.klose Date: Sat Apr 4 17:51:23 2009 New Revision: 71159 Log: - Py_DECREF: Add `do { ... } while (0)' to avoid compiler warnings. Modified: python/trunk/Include/object.h python/trunk/Misc/NEWS Modified: python/trunk/Include/object.h ============================================================================== --- python/trunk/Include/object.h (original) +++ python/trunk/Include/object.h Sat Apr 4 17:51:23 2009 @@ -749,11 +749,13 @@ ((PyObject*)(op))->ob_refcnt++) #define Py_DECREF(op) \ - if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ - --((PyObject*)(op))->ob_refcnt != 0) \ - _Py_CHECK_REFCNT(op) \ - else \ - _Py_Dealloc((PyObject *)(op)) + do { \ + if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ + --((PyObject*)(op))->ob_refcnt != 0) \ + _Py_CHECK_REFCNT(op) \ + else \ + _Py_Dealloc((PyObject *)(op)) \ + } while (0) /* Safely decref `op` and set `op` to NULL, especially useful in tp_clear * and tp_dealloc implementatons. Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Apr 4 17:51:23 2009 @@ -207,6 +207,8 @@ - Issue #3845: In PyRun_SimpleFileExFlags avoid invalid memory access with short file names. +- Py_DECREF: Add `do { ... } while (0)' to avoid compiler warnings. + Library ------- From python-checkins at python.org Sat Apr 4 17:52:51 2009 From: python-checkins at python.org (matthias.klose) Date: Sat, 4 Apr 2009 17:52:51 +0200 (CEST) Subject: [Python-checkins] r71160 - in python/branches/release26-maint: Include/object.h Misc/NEWS Message-ID: <20090404155251.47FEC1E4061@bag.python.org> Author: matthias.klose Date: Sat Apr 4 17:52:50 2009 New Revision: 71160 Log: Merged revisions 71159 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71159 | matthias.klose | 2009-04-04 17:51:23 +0200 (Sa, 04 Apr 2009) | 2 lines - Py_DECREF: Add `do { ... } while (0)' to avoid compiler warnings. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Include/object.h python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Include/object.h ============================================================================== --- python/branches/release26-maint/Include/object.h (original) +++ python/branches/release26-maint/Include/object.h Sat Apr 4 17:52:50 2009 @@ -746,11 +746,13 @@ ((PyObject*)(op))->ob_refcnt++) #define Py_DECREF(op) \ - if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ - --((PyObject*)(op))->ob_refcnt != 0) \ - _Py_CHECK_REFCNT(op) \ - else \ - _Py_Dealloc((PyObject *)(op)) + do { \ + if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ + --((PyObject*)(op))->ob_refcnt != 0) \ + _Py_CHECK_REFCNT(op) \ + else \ + _Py_Dealloc((PyObject *)(op)) \ + } while (0) /* Safely decref `op` and set `op` to NULL, especially useful in tp_clear * and tp_dealloc implementatons. Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sat Apr 4 17:52:50 2009 @@ -92,6 +92,8 @@ - Issue #3845: In PyRun_SimpleFileExFlags avoid invalid memory access with short file names. +- Py_DECREF: Add `do { ... } while (0)' to avoid compiler warnings. + Library ------- From python-checkins at python.org Sat Apr 4 17:54:00 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 4 Apr 2009 17:54:00 +0200 (CEST) Subject: [Python-checkins] r71161 - python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt Message-ID: <20090404155400.1BB591E4061@bag.python.org> Author: mark.dickinson Date: Sat Apr 4 17:53:59 2009 New Revision: 71161 Log: More tests Modified: python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt Modified: python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt (original) +++ python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt Sat Apr 4 17:53:59 2009 @@ -67,6 +67,19 @@ %#.1f 1.4 -> 1.4 %#.2f 0.375 -> 0.38 +-- if precision is omitted it defaults to 6 +%f 0 -> 0.000000 +%f 1230000 -> 1230000.000000 +%f 1234567 -> 1234567.000000 +%f 123.4567 -> 123.456700 +%f 1.23456789 -> 1.234568 +%f 0.00012 -> 0.000120 +%f 0.000123 -> 0.000123 +%f 0.00012345 -> 0.000123 +%f 0.000001 -> 0.000001 +%f 0.0000005001 -> 0.000001 +%f 0.0000004999 -> 0.000000 + -- 'e' code formatting with explicit precision (>= 0). Output should -- always have exactly the number of places after the point that were -- requested. @@ -143,6 +156,13 @@ %.2e 1598.76 -> 1.60e+03 %.2e 9999 -> 1.00e+04 +-- omitted precision defaults to 6 +%e 0 -> 0.000000e+00 +%e 165 -> 1.650000e+02 +%e 1234567 -> 1.234567e+06 +%e 12345678 -> 1.234568e+07 +%e 1.1 -> 1.100000e+00 + -- alternate form always contains a decimal point. This only makes -- a difference when precision is 0. @@ -178,6 +198,8 @@ %#.0e 10.5 -> 1.e+01 %#.0e 14.999 -> 1.e+01 %#.0e 15 -> 2.e+01 +%#.1e 123.4 -> 1.2e+02 +%#.2e 0.0001357 -> 1.36e-04 -- 'g' code formatting. From python-checkins at python.org Sat Apr 4 17:54:26 2009 From: python-checkins at python.org (matthias.klose) Date: Sat, 4 Apr 2009 17:54:26 +0200 (CEST) Subject: [Python-checkins] r71162 - in python/branches/py3k: Include/object.h Misc/NEWS Message-ID: <20090404155426.2D8591E4061@bag.python.org> Author: matthias.klose Date: Sat Apr 4 17:54:25 2009 New Revision: 71162 Log: Merged revisions 71159 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71159 | matthias.klose | 2009-04-04 17:51:23 +0200 (Sa, 04 Apr 2009) | 2 lines - Py_DECREF: Add `do { ... } while (0)' to avoid compiler warnings. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Include/object.h python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Include/object.h ============================================================================== --- python/branches/py3k/Include/object.h (original) +++ python/branches/py3k/Include/object.h Sat Apr 4 17:54:25 2009 @@ -651,11 +651,13 @@ ((PyObject*)(op))->ob_refcnt++) #define Py_DECREF(op) \ - if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ - --((PyObject*)(op))->ob_refcnt != 0) \ - _Py_CHECK_REFCNT(op) \ - else \ - _Py_Dealloc((PyObject *)(op)) + do { \ + if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ + --((PyObject*)(op))->ob_refcnt != 0) \ + _Py_CHECK_REFCNT(op) \ + else \ + _Py_Dealloc((PyObject *)(op)) \ + } while (0) /* Safely decref `op` and set `op` to NULL, especially useful in tp_clear * and tp_dealloc implementatons. Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Apr 4 17:54:25 2009 @@ -62,6 +62,8 @@ - Issue #3845: In PyRun_SimpleFileExFlags avoid invalid memory access with short file names. +- Py_DECREF: Add `do { ... } while (0)' to avoid compiler warnings. + Library ------- From benjamin at python.org Sat Apr 4 17:56:00 2009 From: benjamin at python.org (Benjamin Peterson) Date: Sat, 4 Apr 2009 10:56:00 -0500 Subject: [Python-checkins] r71159 - in python/trunk: Include/object.h Misc/NEWS In-Reply-To: <20090404155124.5F4FF1E4061@bag.python.org> References: <20090404155124.5F4FF1E4061@bag.python.org> Message-ID: <1afaf6160904040856l7faa55btc31ac99f00921b79@mail.gmail.com> 2009/4/4 matthias.klose : > Author: matthias.klose > Date: Sat Apr ?4 17:51:23 2009 > New Revision: 71159 > > Log: > - Py_DECREF: Add `do { ... } while (0)' to avoid compiler warnings. Did you test the build before checking this in? It fails now. -- Regards, Benjamin From buildbot at python.org Sat Apr 4 17:58:14 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 15:58:14 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 2.6 Message-ID: <20090404155814.E88D11E4063@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%202.6/builds/231 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From buildbot at python.org Sat Apr 4 17:59:33 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 15:59:33 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 2.6 Message-ID: <20090404155933.708551E4066@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%202.6/builds/215 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: matthias.klose BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_bsddb3 make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Sat Apr 4 17:59:48 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 15:59:48 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 3.x Message-ID: <20090404155949.1E7D81E4066@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%203.x/builds/661 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From buildbot at python.org Sat Apr 4 18:01:55 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 16:01:55 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 2.6 Message-ID: <20090404160155.863141E406B@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%20gentoo%202.6/builds/200 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-amd64 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From buildbot at python.org Sat Apr 4 18:02:37 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 16:02:37 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 3.x Message-ID: <20090404160237.AA9831E406B@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%20gentoo%203.x/builds/567 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-amd64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson,matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From python-checkins at python.org Sat Apr 4 18:05:51 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 18:05:51 +0200 (CEST) Subject: [Python-checkins] r71163 - in python/trunk: Include/object.h Misc/NEWS Message-ID: <20090404160551.BFB871E41C1@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 18:05:51 2009 New Revision: 71163 Log: revert r71159 since it broke the build Modified: python/trunk/Include/object.h python/trunk/Misc/NEWS Modified: python/trunk/Include/object.h ============================================================================== --- python/trunk/Include/object.h (original) +++ python/trunk/Include/object.h Sat Apr 4 18:05:51 2009 @@ -749,13 +749,11 @@ ((PyObject*)(op))->ob_refcnt++) #define Py_DECREF(op) \ - do { \ - if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ - --((PyObject*)(op))->ob_refcnt != 0) \ - _Py_CHECK_REFCNT(op) \ - else \ - _Py_Dealloc((PyObject *)(op)) \ - } while (0) + if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ + --((PyObject*)(op))->ob_refcnt != 0) \ + _Py_CHECK_REFCNT(op) \ + else \ + _Py_Dealloc((PyObject *)(op)) /* Safely decref `op` and set `op` to NULL, especially useful in tp_clear * and tp_dealloc implementatons. Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Apr 4 18:05:51 2009 @@ -207,8 +207,6 @@ - Issue #3845: In PyRun_SimpleFileExFlags avoid invalid memory access with short file names. -- Py_DECREF: Add `do { ... } while (0)' to avoid compiler warnings. - Library ------- From buildbot at python.org Sat Apr 4 18:07:37 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 16:07:37 +0000 Subject: [Python-checkins] buildbot failure in OS X x86 2.6 Message-ID: <20090404160738.14E081E406B@bag.python.org> The Buildbot has detected a new failure of OS X x86 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/OS%20X%20x86%202.6/builds/177 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: noller-osx86 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From python-checkins at python.org Sat Apr 4 18:10:42 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 18:10:42 +0200 (CEST) Subject: [Python-checkins] r71164 - in python/branches/release26-maint: Include/object.h Misc/NEWS Message-ID: <20090404161042.645EE1E420F@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 18:10:42 2009 New Revision: 71164 Log: Merged revisions 71163 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71163 | benjamin.peterson | 2009-04-04 11:05:51 -0500 (Sat, 04 Apr 2009) | 1 line revert r71159 since it broke the build ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Include/object.h python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Include/object.h ============================================================================== --- python/branches/release26-maint/Include/object.h (original) +++ python/branches/release26-maint/Include/object.h Sat Apr 4 18:10:42 2009 @@ -746,13 +746,11 @@ ((PyObject*)(op))->ob_refcnt++) #define Py_DECREF(op) \ - do { \ - if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ - --((PyObject*)(op))->ob_refcnt != 0) \ - _Py_CHECK_REFCNT(op) \ - else \ - _Py_Dealloc((PyObject *)(op)) \ - } while (0) + if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ + --((PyObject*)(op))->ob_refcnt != 0) \ + _Py_CHECK_REFCNT(op) \ + else \ + _Py_Dealloc((PyObject *)(op)) /* Safely decref `op` and set `op` to NULL, especially useful in tp_clear * and tp_dealloc implementatons. Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sat Apr 4 18:10:42 2009 @@ -92,8 +92,6 @@ - Issue #3845: In PyRun_SimpleFileExFlags avoid invalid memory access with short file names. -- Py_DECREF: Add `do { ... } while (0)' to avoid compiler warnings. - Library ------- From python-checkins at python.org Sat Apr 4 18:16:33 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 4 Apr 2009 18:16:33 +0200 (CEST) Subject: [Python-checkins] r71165 - python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt Message-ID: <20090404161633.7A51B1E4066@bag.python.org> Author: mark.dickinson Date: Sat Apr 4 18:16:33 2009 New Revision: 71165 Log: A couple more testcases Modified: python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt Modified: python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt (original) +++ python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt Sat Apr 4 18:16:33 2009 @@ -22,6 +22,7 @@ %.0f 123.456 -> 123 %.0f 1234.56 -> 1235 %.0f 1e49 -> 9999999999999999464902769475481793196872414789632 +%.0f 1e50 -> 100000000000000007629769841091887003294964970946560 %.0f 9.9999999999999987e+49 -> 99999999999999986860582406952576489172979654066176 -- precision 1 @@ -348,7 +349,6 @@ -- str formatting. Result always includes decimal point and at -- least one digit after the point, or an exponent. - %s 0 -> 0.0 %s 1 -> 1.0 @@ -369,6 +369,7 @@ %s 1e10 -> 10000000000.0 %s 9.999e10 -> 99990000000.0 %s 99999999999 -> 99999999999.0 +%s 1e11 -> 1e+11 %s 1e12 -> 1e+12 -- as do values < 1e-4 @@ -381,9 +382,3 @@ %s 0.999999999999e-4 -> 9.99999999999e-05 %s 0.999e-4 -> 9.99e-05 %s 1e-5 -> 1e-05 - - --- removed tests: need to decide what to do with these - --- %s 1e11 -> 1e+11 --- %.0f 1e50 -> 1e50 From python-checkins at python.org Sat Apr 4 18:17:21 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 4 Apr 2009 18:17:21 +0200 (CEST) Subject: [Python-checkins] r71166 - in python/branches/py3k-short-float-repr: Objects/floatobject.c Python/pystrtod.c Message-ID: <20090404161721.CA6981E4066@bag.python.org> Author: mark.dickinson Date: Sat Apr 4 18:17:21 2009 New Revision: 71166 Log: Add 's' format code for str formatting. Modified: python/branches/py3k-short-float-repr/Objects/floatobject.c python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Objects/floatobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/floatobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/floatobject.c Sat Apr 4 18:17:21 2009 @@ -387,7 +387,7 @@ static PyObject * float_str(PyFloatObject *v) { - return float_str_or_repr(v, 'g', PREC_STR); + return float_str_or_repr(v, 's', PREC_STR); } /* Comparison is pretty much a nightmare. When comparing float to float, Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Sat Apr 4 18:17:21 2009 @@ -617,6 +617,14 @@ use_exp = 1; trailing_zeros = 0; break; + case 's': + /* str: use exponent for values >= 1e11 or < 1e-4 */ + if (-4 < decpt && decpt < precision) + use_exp = 0; + else + use_exp = 1; + trailing_zeros = 0; + break; } /* Always add a negative sign, and a plus sign if always_add_sign. */ @@ -710,6 +718,7 @@ case 'f': /* fixed */ case 'g': /* general */ case 'r': /* repr format */ + case 's': /* str format */ break; case 'E': lc_format_code = 'e'; @@ -747,6 +756,9 @@ /* "repr" pseudo-mode */ mode = 0; break; + case 's': + mode = 2; + break; } if (!buf) From buildbot at python.org Sat Apr 4 18:20:22 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 16:20:22 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 2.6 Message-ID: <20090404162022.AFD401E4072@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%202.6/builds/223 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From buildbot at python.org Sat Apr 4 18:21:10 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 16:21:10 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 3.x Message-ID: <20090404162110.544CC1E406B@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%203.x/builds/609 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson,matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From buildbot at python.org Sat Apr 4 18:32:53 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 16:32:53 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 3.x Message-ID: <20090404163254.06E761E4015@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%203.x/builds/567 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson,matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From python-checkins at python.org Sat Apr 4 18:33:15 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 4 Apr 2009 18:33:15 +0200 (CEST) Subject: [Python-checkins] r71167 - python/branches/py3k-short-float-repr/Python/marshal.c Message-ID: <20090404163315.9D3271E4015@bag.python.org> Author: mark.dickinson Date: Sat Apr 4 18:33:15 2009 New Revision: 71167 Log: Fix marshalling of floats. Modified: python/branches/py3k-short-float-repr/Python/marshal.c Modified: python/branches/py3k-short-float-repr/Python/marshal.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/marshal.c (original) +++ python/branches/py3k-short-float-repr/Python/marshal.c Sat Apr 4 18:33:15 2009 @@ -237,7 +237,7 @@ } else { char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v), - 'g', 0, Py_DTSF_ADD_DOT_0); + 'r', 0, Py_DTSF_ADD_DOT_0); if (!buf) return; n = strlen(buf); From python-checkins at python.org Sat Apr 4 18:35:45 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 4 Apr 2009 18:35:45 +0200 (CEST) Subject: [Python-checkins] r71168 - python/branches/py3k-short-float-repr/Python/marshal.c Message-ID: <20090404163545.D6F881E4015@bag.python.org> Author: mark.dickinson Date: Sat Apr 4 18:35:45 2009 New Revision: 71168 Log: ... and apply the same fix as in r71167 for complex numbers Modified: python/branches/py3k-short-float-repr/Python/marshal.c Modified: python/branches/py3k-short-float-repr/Python/marshal.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/marshal.c (original) +++ python/branches/py3k-short-float-repr/Python/marshal.c Sat Apr 4 18:35:45 2009 @@ -269,7 +269,7 @@ char *buf; w_byte(TYPE_COMPLEX, p); buf = PyOS_double_to_string(PyComplex_RealAsDouble(v), - 'g', 0, Py_DTSF_ADD_DOT_0); + 'r', 0, Py_DTSF_ADD_DOT_0); if (!buf) return; n = strlen(buf); @@ -277,7 +277,7 @@ w_string(buf, (int)n, p); PyMem_Free(buf); buf = PyOS_double_to_string(PyComplex_ImagAsDouble(v), - 'g', 0, Py_DTSF_ADD_DOT_0); + 'r', 0, Py_DTSF_ADD_DOT_0); if (!buf) return; n = strlen(buf); From python-checkins at python.org Sat Apr 4 18:35:47 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 18:35:47 +0200 (CEST) Subject: [Python-checkins] r71169 - in python/branches/py3k: Doc/library/unittest.rst Lib/test/test_gc.py Lib/test/test_struct.py Lib/test/test_unittest.py Lib/unittest.py Message-ID: <20090404163547.9DA011E407F@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 18:35:46 2009 New Revision: 71169 Log: Merged revisions 70837,70864,70878,71004,71032,71043 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70837 | gregory.p.smith | 2009-03-31 11:54:10 -0500 (Tue, 31 Mar 2009) | 9 lines The unittest.TestCase.assertEqual() now displays the differences in lists, tuples, dicts and sets on failure. Many new handy type and comparison specific assert* methods have been added that fail with error messages actually useful for debugging. Contributed in by Google and completed with help from mfoord and GvR at PyCon 2009 sprints. Discussion lives in http://bugs.python.org/issue2578. ........ r70864 | gregory.p.smith | 2009-03-31 14:03:28 -0500 (Tue, 31 Mar 2009) | 10 lines Rename the actual method definitions to the official assertFoo names. Adds unittests to make sure the old fail* names continue to work now and adds a comment that they are pending deprecation. Also adds a test to confirm that the plural Equals method variants continue to exist even though we're unlikely to deprecate those. http://bugs.python.org/issue2578 ........ r70878 | gregory.p.smith | 2009-03-31 14:59:14 -0500 (Tue, 31 Mar 2009) | 3 lines Issue an actual PendingDeprecationWarning for the TestCase.fail* methods. Document the deprecation. ........ r71004 | benjamin.peterson | 2009-04-01 18:15:49 -0500 (Wed, 01 Apr 2009) | 1 line remove double underscores ........ r71032 | michael.foord | 2009-04-01 22:20:38 -0500 (Wed, 01 Apr 2009) | 13 lines Better exception messages for unittest assert methods. - unittest.assertNotEqual() now uses the inequality operator (!=) instead of the equality operator. - Default assertTrue and assertFalse messages are now useful. - TestCase has a longMessage attribute. This defaults to False, but if set to True useful error messages are shown in addition to explicit messages passed to assert methods. Issue #5663 ........ r71043 | michael.foord | 2009-04-02 00:51:54 -0500 (Thu, 02 Apr 2009) | 7 lines Store the functions in the _type_equality_funcs as wrapped objects that are deep copyable. This allows for the deep copying of TestCase instances. Issue 5660 ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/unittest.rst python/branches/py3k/Lib/test/test_gc.py python/branches/py3k/Lib/test/test_struct.py python/branches/py3k/Lib/test/test_unittest.py python/branches/py3k/Lib/unittest.py Modified: python/branches/py3k/Doc/library/unittest.rst ============================================================================== --- python/branches/py3k/Doc/library/unittest.rst (original) +++ python/branches/py3k/Doc/library/unittest.rst Sat Apr 4 18:35:46 2009 @@ -1,4 +1,3 @@ - :mod:`unittest` --- Unit testing framework ========================================== @@ -207,8 +206,8 @@ widget = Widget('The widget') self.assertEqual(widget.size(), (50, 50), 'incorrect default size') -Note that in order to test something, we use the one of the :meth:`assert\*` or -:meth:`fail\*` methods provided by the :class:`TestCase` base class. If the +Note that in order to test something, we use the one of the :meth:`assert\*` +methods provided by the :class:`TestCase` base class. If the test fails, an exception will be raised, and :mod:`unittest` will identify the test case as a :dfn:`failure`. Any other exceptions will be treated as :dfn:`errors`. This helps you identify where the problem is: :dfn:`failures` are @@ -238,13 +237,13 @@ class DefaultWidgetSizeTestCase(SimpleWidgetTestCase): def runTest(self): - self.failUnless(self.widget.size() == (50,50), + self.assertTrue(self.widget.size() == (50,50), 'incorrect default size') class WidgetResizeTestCase(SimpleWidgetTestCase): def runTest(self): self.widget.resize(100,150) - self.failUnless(self.widget.size() == (100,150), + self.assertTrue(self.widget.size() == (100,150), 'wrong size after resize') If the :meth:`~TestCase.setUp` method raises an exception while the test is @@ -286,12 +285,12 @@ self.widget = None def testDefaultSize(self): - self.failUnless(self.widget.size() == (50,50), + self.assertTrue(self.widget.size() == (50,50), 'incorrect default size') def testResize(self): self.widget.resize(100,150) - self.failUnless(self.widget.size() == (100,150), + self.assertTrue(self.widget.size() == (100,150), 'wrong size after resize') Here we have not provided a :meth:`~TestCase.runTest` method, but have instead @@ -605,23 +604,37 @@ failures. - .. method:: assert_(expr[, msg]) + .. method:: assertTrue(expr[, msg]) + assert_(expr[, msg]) failUnless(expr[, msg]) - assertTrue(expr[, msg]) Signal a test failure if *expr* is false; the explanation for the error will be *msg* if given, otherwise it will be :const:`None`. + .. deprecated:: 2.7 + :meth:`failUnless`. + .. method:: assertEqual(first, second[, msg]) failUnlessEqual(first, second[, msg]) Test that *first* and *second* are equal. If the values do not compare equal, the test will fail with the explanation given by *msg*, or - :const:`None`. Note that using :meth:`failUnlessEqual` improves upon - doing the comparison as the first parameter to :meth:`failUnless`: the - default value for *msg* can be computed to include representations of both - *first* and *second*. + :const:`None`. Note that using :meth:`assertEqual` improves upon + doing the comparison as the first parameter to :meth:`assertTrue`: the + default value for *msg* include representations of both *first* and + *second*. + + In addition, if *first* and *second* are the exact same type and one of + list, tuple, dict, set, or frozenset or any type that a subclass + registers :meth:`addTypeEqualityFunc` the type specific equality function + will be called in order to generate a more useful default error message. + + .. versionchanged:: 2.7 + Added the automatic calling of type specific equality function. + + .. deprecated:: 2.7 + :meth:`failUnlessEqual`. .. method:: assertNotEqual(first, second[, msg]) @@ -629,11 +642,14 @@ Test that *first* and *second* are not equal. If the values do compare equal, the test will fail with the explanation given by *msg*, or - :const:`None`. Note that using :meth:`failIfEqual` improves upon doing - the comparison as the first parameter to :meth:`failUnless` is that the + :const:`None`. Note that using :meth:`assertNotEqual` improves upon doing + the comparison as the first parameter to :meth:`assertTrue` is that the default value for *msg* can be computed to include representations of both *first* and *second*. + .. deprecated:: 2.7 + :meth:`failIfEqual`. + .. method:: assertAlmostEqual(first, second[, places[, msg]]) failUnlessAlmostEqual(first, second[, places[, msg]]) @@ -647,6 +663,9 @@ compare equal, the test will fail with the explanation given by *msg*, or :const:`None`. + .. deprecated:: 2.7 + :meth:`failUnlessAlmostEqual`. + .. method:: assertNotAlmostEqual(first, second[, places[, msg]]) failIfAlmostEqual(first, second[, places[, msg]]) @@ -660,6 +679,128 @@ compare equal, the test will fail with the explanation given by *msg*, or :const:`None`. + .. deprecated:: 2.7 + :meth:`failIfAlmostEqual`. + + + .. method:: assertGreater(first, second, msg=None) + assertGreaterEqual(first, second, msg=None) + assertLess(first, second, msg=None) + assertLessEqual(first, second, msg=None) + + Test that *first* is respectively >, >=, < or <= than *second* depending + on the method name. If not, the test will fail with the nice explanation + or with the explanation given by *msg*:: + + >>> self.assertGreaterEqual(3, 4) + AssertionError: "3" unexpectedly not greater than or equal to "4" + + .. versionadded:: 2.7 + + + .. method:: assertMultiLineEqual(self, first, second, msg=None) + + Test that the multiline string *first* is equal to the string *second*. + When not equal a diff of the two strings highlighting the differences + will be included in the error message. + + If specified *msg* will be used as the error message on failure. + + .. versionadded:: 2.7 + + + .. method:: assertRegexpMatches(text, regexp[, msg=None]): + + Verifies that a *regexp* search matches *text*. Fails with an error + message including the pattern and the *text*. *regexp* may be + a regular expression object or a string containing a regular expression + suitable for use by :func:`re.search`. + + .. versionadded:: 2.7 + + + .. method:: assertIn(first, second, msg=None) + assertNotIn(first, second, msg=None) + + Tests that *first* is or is not in *second* with a nice explanitory error + message as appropriate. + + If specified *msg* will be used as the error message on failure. + + .. versionadded:: 2.7 + + + .. method:: assertSameElements(expected, actual, msg=None) + + Test that sequence *expected* contains the same elements as *actual*. + When they don't an error message listing the differences between the + sequences will be generated. + + If specified *msg* will be used as the error message on failure. + + .. versionadded:: 2.7 + + + .. method:: assertSetEqual(set1, set2, msg=None) + + Tests that two sets are equal. If not, an error message is constructed + that lists the differences between the sets. + + Fails if either of *set1* or *set2* does not have a :meth:`set.difference` + method. + + If specified *msg* will be used as the error message on failure. + + .. versionadded:: 2.7 + + + .. method:: assertDictEqual(expected, actual, msg=None) + + Test that two dictionaries are equal. If not, an error message is + constructed that shows the differences in the dictionaries. + + If specified *msg* will be used as the error message on failure. + + .. versionadded:: 2.7 + + + .. method:: assertDictContainsSubset(expected, actual, msg=None) + + Tests whether the key value pairs in dictionary *actual* are a + superset of those in *expected*. If not, an error message listing + the missing keys and mismatched values is generated. + + If specified *msg* will be used as the error message on failure. + + .. versionadded:: 2.7 + + + .. method:: assertListEqual(list1, list2, msg=None) + assertTupleEqual(tuple1, tuple2, msg=None) + + Tests that two lists or tuples are equal. If not an error message is + constructed that shows only the differences between the two. An error + is also raised if either of the parameters are of the wrong type. + + If specified *msg* will be used as the error message on failure. + + .. versionadded:: 2.7 + + + .. method:: assertSequenceEqual(seq1, seq2, msg=None, seq_type=None) + + Tests that two sequences are equal. If a *seq_type* is supplied, both + *seq1* and *seq2* must be instances of *seq_type* or a failure will + be raised. If the sequences are different an error message is + constructed that shows the difference between the two. + + If specified *msg* will be used as the error message on failure. + + This method is used to implement :meth:`assertListEqual` and + :meth:`assertTupleEqual`. + + .. versionadded:: 2.7 + .. method:: assertRaises(exception[, callable, ...]) failUnlessRaises(exception[, callable, ...]) @@ -680,14 +821,53 @@ .. versionchanged:: 3.1 Added the ability to use :meth:`assertRaises` as a context manager. + .. deprecated:: 2.7 + :meth:`failUnlessRaises`. + + + .. method:: assertRaisesRegexp(exception, regexp[, callable, ...]) + + Like :meth:`assertRaises` but also tests that *regexp* matches + on the string representation of the raised exception. *regexp* 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') + + or:: - .. method:: failIf(expr[, msg]) - assertFalse(expr[, msg]) + with self.assertRaisesRegexp(ValueError, 'literal'): + int('XYZ') - The inverse of the :meth:`failUnless` method is the :meth:`failIf` method. + .. versionadded:: 2.7 + + + .. method:: assertIsNone(expr[, msg]) + + This signals a test failure if *expr* is not None. + + .. versionadded:: 2.7 + + + .. method:: assertIsNotNone(expr[, msg]) + + The inverse of the :meth:`assertIsNone` method. + This signals a test failure if *expr* is None. + + .. versionadded:: 2.7 + + + .. method:: assertFalse(expr[, msg]) + failIf(expr[, msg]) + + The inverse of the :meth:`assertTrue` method is the :meth:`assertFalse` method. This signals a test failure if *expr* is true, with *msg* or :const:`None` for the error message. + .. deprecated:: 2.7 + :meth:`failIf`. + .. method:: fail([msg]) @@ -703,6 +883,25 @@ fair" with the framework. The initial value of this attribute is :exc:`AssertionError`. + + .. attribute:: longMessage + + If set to True then any explicit failure message you pass in to the + assert methods will be appended to the end of the normal failure message. + The normal messages contain useful information about the objects involved, + for example the message from assertEqual shows you the repr of the two + unequal objects. Setting this attribute 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. + + The class setting can be overridden in individual tests by assigning an + instance attribute to True or False before calling the assert methods. + + .. versionadded:: 2.7 + + Testing frameworks can use the following methods to collect information on the test: @@ -732,10 +931,34 @@ .. method:: shortDescription() - Returns a one-line description of the test, or :const:`None` if no - description has been provided. The default implementation of this method - returns the first line of the test method's docstring, if available, or - :const:`None`. + Returns a description of the test, or :const:`None` if no description + has been provided. The default implementation of this method + returns the first line of the test method's docstring, if available, + along with the method name. + + .. versionchanged:: 2.7 + + In earlier versions this only returned the first line of the test + method's docstring, if available or the :const:`None`. That led to + undesirable behavior of not printing the test name when someone was + thoughtful enough to write a docstring. + + + .. method:: addTypeEqualityFunc(typeobj, function) + + Registers a type specific :meth:`assertEqual` equality checking + function to be called by :meth:`assertEqual` when both objects it has + been asked to compare are exactly *typeobj* (not subclasses). + *function* must take two positional arguments and a third msg=None + keyword argument just as :meth:`assertEqual` does. It must raise + self.failureException when inequality between the first two + parameters is detected. + + One good use of custom equality checking functions for a type + is to raise self.failureException with an error message useful + for debugging the by explaining the inequalities in detail. + + .. versionadded:: 2.7 .. class:: FunctionTestCase(testFunc[, setUp[, tearDown[, description]]]) Modified: python/branches/py3k/Lib/test/test_gc.py ============================================================================== --- python/branches/py3k/Lib/test/test_gc.py (original) +++ python/branches/py3k/Lib/test/test_gc.py Sat Apr 4 18:35:46 2009 @@ -244,7 +244,7 @@ # - the call to assertEqual somehow avoids building its args tuple def test_get_count(self): # Avoid future allocation of method object - assertEqual = self.assertEqual + assertEqual = self._baseAssertEqual gc.collect() assertEqual(gc.get_count(), (0, 0, 0)) a = dict() Modified: python/branches/py3k/Lib/test/test_struct.py ============================================================================== --- python/branches/py3k/Lib/test/test_struct.py (original) +++ python/branches/py3k/Lib/test/test_struct.py Sat Apr 4 18:35:46 2009 @@ -207,6 +207,7 @@ class IntTester(unittest.TestCase): def __init__(self, formatpair, bytesize): + super(IntTester, self).__init__(methodName='test_one') self.assertEqual(len(formatpair), 2) self.formatpair = formatpair for direction in "<>!=": 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 Sat Apr 4 18:35:46 2009 @@ -6,10 +6,12 @@ TestCase.{assert,fail}* methods (some are tested implicitly) """ +import re from test import support import unittest from unittest import TestCase import types +from copy import deepcopy ### Support code ################################################################ @@ -53,6 +55,8 @@ class TestEquality(object): + """Used as a mixin for TestCase""" + # Check for a valid __eq__ implementation def test_eq(self): for obj_1, obj_2 in self.eq_pairs: @@ -66,25 +70,26 @@ self.failIfEqual(obj_2, obj_1) class TestHashing(object): + """Used as a mixin for TestCase""" + # Check for a valid __hash__ implementation def test_hash(self): for obj_1, obj_2 in self.eq_pairs: try: - assert hash(obj_1) == hash(obj_2) + if not hash(obj_1) == hash(obj_2): + self.fail("%r and %r do not hash equal" % (obj_1, obj_2)) except KeyboardInterrupt: raise - except AssertionError: - self.fail("%s and %s do not hash equal" % (obj_1, obj_2)) except Exception as e: - self.fail("Problem hashing %s and %s: %s" % (obj_1, obj_2, e)) + self.fail("Problem hashing %r and %r: %s" % (obj_1, obj_2, e)) for obj_1, obj_2 in self.ne_pairs: try: - assert hash(obj_1) != hash(obj_2) + if hash(obj_1) == hash(obj_2): + self.fail("%s and %s hash equal, but shouldn't" % + (obj_1, obj_2)) except KeyboardInterrupt: raise - except AssertionError: - self.fail("%s and %s hash equal, but shouldn't" % (obj_1, obj_2)) except Exception as e: self.fail("Problem hashing %s and %s: %s" % (obj_1, obj_2, e)) @@ -2247,39 +2252,6 @@ self.failUnless(isinstance(Foo().id(), str)) - # "Returns a one-line description of the test, or None if no description - # has been provided. The default implementation of this method returns - # the first line of the test method's docstring, if available, or None." - def test_shortDescription__no_docstring(self): - class Foo(unittest.TestCase): - def runTest(self): - pass - - self.assertEqual(Foo().shortDescription(), None) - - # "Returns a one-line description of the test, or None if no description - # has been provided. The default implementation of this method returns - # the first line of the test method's docstring, if available, or None." - def test_shortDescription__singleline_docstring(self): - class Foo(unittest.TestCase): - def runTest(self): - "this tests foo" - pass - - self.assertEqual(Foo().shortDescription(), "this tests foo") - - # "Returns a one-line description of the test, or None if no description - # has been provided. The default implementation of this method returns - # the first line of the test method's docstring, if available, or None." - def test_shortDescription__multiline_docstring(self): - class Foo(unittest.TestCase): - def runTest(self): - """this tests foo - blah, bar and baz are also tested""" - pass - - self.assertEqual(Foo().shortDescription(), "this tests foo") - # "If result is omitted or None, a temporary result object is created # and used, but is not made available to the caller" def test_run__uses_defaultTestResult(self): @@ -2298,6 +2270,405 @@ expected = ['startTest', 'test', 'addSuccess', 'stopTest'] self.assertEqual(events, expected) + def testShortDescriptionWithoutDocstring(self): + self.assertEqual( + self.shortDescription(), + 'testShortDescriptionWithoutDocstring (' + __name__ + + '.Test_TestCase)') + + def testShortDescriptionWithOneLineDocstring(self): + """Tests shortDescription() for a method with a docstring.""" + self.assertEqual( + self.shortDescription(), + ('testShortDescriptionWithOneLineDocstring ' + '(' + __name__ + '.Test_TestCase)\n' + 'Tests shortDescription() for a method with a docstring.')) + + def testShortDescriptionWithMultiLineDocstring(self): + """Tests shortDescription() for a method with a longer docstring. + + This method ensures that only the first line of a docstring is + returned used in the short description, no matter how long the + whole thing is. + """ + self.assertEqual( + self.shortDescription(), + ('testShortDescriptionWithMultiLineDocstring ' + '(' + __name__ + '.Test_TestCase)\n' + 'Tests shortDescription() for a method with a longer ' + 'docstring.')) + + def testAddTypeEqualityFunc(self): + class SadSnake(object): + """Dummy class for test_addTypeEqualityFunc.""" + s1, s2 = SadSnake(), SadSnake() + self.assertFalse(s1 == s2) + def AllSnakesCreatedEqual(a, b, msg=None): + return type(a) == type(b) == SadSnake + self.addTypeEqualityFunc(SadSnake, AllSnakesCreatedEqual) + self.assertEqual(s1, s2) + # No this doesn't clean up and remove the SadSnake equality func + # from this TestCase instance but since its a local nothing else + # will ever notice that. + + def testAssertIn(self): + animals = {'monkey': 'banana', 'cow': 'grass', 'seal': 'fish'} + + self.assertIn('a', 'abc') + self.assertIn(2, [1, 2, 3]) + self.assertIn('monkey', animals) + + self.assertNotIn('d', 'abc') + self.assertNotIn(0, [1, 2, 3]) + self.assertNotIn('otter', animals) + + self.assertRaises(self.failureException, self.assertIn, 'x', 'abc') + self.assertRaises(self.failureException, self.assertIn, 4, [1, 2, 3]) + self.assertRaises(self.failureException, self.assertIn, 'elephant', + animals) + + self.assertRaises(self.failureException, self.assertNotIn, 'c', 'abc') + self.assertRaises(self.failureException, self.assertNotIn, 1, [1, 2, 3]) + self.assertRaises(self.failureException, self.assertNotIn, 'cow', + animals) + + def testAssertDictContainsSubset(self): + self.assertDictContainsSubset({}, {}) + self.assertDictContainsSubset({}, {'a': 1}) + self.assertDictContainsSubset({'a': 1}, {'a': 1}) + self.assertDictContainsSubset({'a': 1}, {'a': 1, 'b': 2}) + self.assertDictContainsSubset({'a': 1, 'b': 2}, {'a': 1, 'b': 2}) + + self.assertRaises(unittest.TestCase.failureException, + self.assertDictContainsSubset, {'a': 2}, {'a': 1}, + '.*Mismatched values:.*') + + self.assertRaises(unittest.TestCase.failureException, + self.assertDictContainsSubset, {'c': 1}, {'a': 1}, + '.*Missing:.*') + + self.assertRaises(unittest.TestCase.failureException, + self.assertDictContainsSubset, {'a': 1, 'c': 1}, + {'a': 1}, '.*Missing:.*') + + self.assertRaises(unittest.TestCase.failureException, + self.assertDictContainsSubset, {'a': 1, 'c': 1}, + {'a': 1}, '.*Missing:.*Mismatched values:.*') + + def testAssertEqual(self): + equal_pairs = [ + ((), ()), + ({}, {}), + ([], []), + (set(), set()), + (frozenset(), frozenset())] + for a, b in equal_pairs: + # This mess of try excepts is to test the assertEqual behavior + # itself. + try: + self.assertEqual(a, b) + except self.failureException: + self.fail('assertEqual(%r, %r) failed' % (a, b)) + try: + self.assertEqual(a, b, msg='foo') + except self.failureException: + self.fail('assertEqual(%r, %r) with msg= failed' % (a, b)) + try: + self.assertEqual(a, b, 'foo') + except self.failureException: + self.fail('assertEqual(%r, %r) with third parameter failed' % + (a, b)) + + unequal_pairs = [ + ((), []), + ({}, set()), + (set([4,1]), frozenset([4,2])), + (frozenset([4,5]), set([2,3])), + (set([3,4]), set([5,4]))] + for a, b in unequal_pairs: + self.assertRaises(self.failureException, self.assertEqual, a, b) + self.assertRaises(self.failureException, self.assertEqual, a, b, + 'foo') + self.assertRaises(self.failureException, self.assertEqual, a, b, + msg='foo') + + def testEquality(self): + self.assertListEqual([], []) + self.assertTupleEqual((), ()) + self.assertSequenceEqual([], ()) + + a = [0, 'a', []] + b = [] + self.assertRaises(unittest.TestCase.failureException, + self.assertListEqual, a, b) + self.assertRaises(unittest.TestCase.failureException, + self.assertListEqual, tuple(a), tuple(b)) + self.assertRaises(unittest.TestCase.failureException, + self.assertSequenceEqual, a, tuple(b)) + + b.extend(a) + self.assertListEqual(a, b) + self.assertTupleEqual(tuple(a), tuple(b)) + self.assertSequenceEqual(a, tuple(b)) + self.assertSequenceEqual(tuple(a), b) + + self.assertRaises(self.failureException, self.assertListEqual, + a, tuple(b)) + self.assertRaises(self.failureException, self.assertTupleEqual, + tuple(a), b) + self.assertRaises(self.failureException, self.assertListEqual, None, b) + self.assertRaises(self.failureException, self.assertTupleEqual, None, + tuple(b)) + self.assertRaises(self.failureException, self.assertSequenceEqual, + None, tuple(b)) + self.assertRaises(self.failureException, self.assertListEqual, 1, 1) + self.assertRaises(self.failureException, self.assertTupleEqual, 1, 1) + self.assertRaises(self.failureException, self.assertSequenceEqual, + 1, 1) + + self.assertDictEqual({}, {}) + + c = { 'x': 1 } + d = {} + self.assertRaises(unittest.TestCase.failureException, + self.assertDictEqual, c, d) + + d.update(c) + self.assertDictEqual(c, d) + + d['x'] = 0 + self.assertRaises(unittest.TestCase.failureException, + self.assertDictEqual, c, d, 'These are unequal') + + self.assertRaises(self.failureException, self.assertDictEqual, None, d) + self.assertRaises(self.failureException, self.assertDictEqual, [], d) + self.assertRaises(self.failureException, self.assertDictEqual, 1, 1) + + self.assertSameElements([1, 2, 3], [3, 2, 1]) + self.assertSameElements([1, 2] + [3] * 100, [1] * 100 + [2, 3]) + self.assertSameElements(['foo', 'bar', 'baz'], ['bar', 'baz', 'foo']) + self.assertRaises(self.failureException, self.assertSameElements, + [10], [10, 11]) + self.assertRaises(self.failureException, self.assertSameElements, + [10, 11], [10]) + + # Test that sequences of unhashable objects can be tested for sameness: + self.assertSameElements([[1, 2], [3, 4]], [[3, 4], [1, 2]]) + self.assertRaises(self.failureException, self.assertSameElements, + [[1]], [[2]]) + + def testAssertSetEqual(self): + set1 = set() + set2 = set() + self.assertSetEqual(set1, set2) + + self.assertRaises(self.failureException, self.assertSetEqual, None, set2) + self.assertRaises(self.failureException, self.assertSetEqual, [], set2) + self.assertRaises(self.failureException, self.assertSetEqual, set1, None) + self.assertRaises(self.failureException, self.assertSetEqual, set1, []) + + set1 = set(['a']) + set2 = set() + self.assertRaises(self.failureException, self.assertSetEqual, set1, set2) + + set1 = set(['a']) + set2 = set(['a']) + self.assertSetEqual(set1, set2) + + set1 = set(['a']) + set2 = set(['a', 'b']) + self.assertRaises(self.failureException, self.assertSetEqual, set1, set2) + + set1 = set(['a']) + set2 = frozenset(['a', 'b']) + self.assertRaises(self.failureException, self.assertSetEqual, set1, set2) + + set1 = set(['a', 'b']) + set2 = frozenset(['a', 'b']) + self.assertSetEqual(set1, set2) + + set1 = set() + set2 = "foo" + self.assertRaises(self.failureException, self.assertSetEqual, set1, set2) + self.assertRaises(self.failureException, self.assertSetEqual, set2, set1) + + # make sure any string formatting is tuple-safe + set1 = set([(0, 1), (2, 3)]) + set2 = set([(4, 5)]) + self.assertRaises(self.failureException, self.assertSetEqual, set1, set2) + + def testInequality(self): + # Try ints + self.assertGreater(2, 1) + self.assertGreaterEqual(2, 1) + self.assertGreaterEqual(1, 1) + self.assertLess(1, 2) + self.assertLessEqual(1, 2) + self.assertLessEqual(1, 1) + self.assertRaises(self.failureException, self.assertGreater, 1, 2) + self.assertRaises(self.failureException, self.assertGreater, 1, 1) + self.assertRaises(self.failureException, self.assertGreaterEqual, 1, 2) + self.assertRaises(self.failureException, self.assertLess, 2, 1) + self.assertRaises(self.failureException, self.assertLess, 1, 1) + self.assertRaises(self.failureException, self.assertLessEqual, 2, 1) + + # Try Floats + self.assertGreater(1.1, 1.0) + self.assertGreaterEqual(1.1, 1.0) + self.assertGreaterEqual(1.0, 1.0) + self.assertLess(1.0, 1.1) + self.assertLessEqual(1.0, 1.1) + self.assertLessEqual(1.0, 1.0) + self.assertRaises(self.failureException, self.assertGreater, 1.0, 1.1) + self.assertRaises(self.failureException, self.assertGreater, 1.0, 1.0) + self.assertRaises(self.failureException, self.assertGreaterEqual, 1.0, 1.1) + self.assertRaises(self.failureException, self.assertLess, 1.1, 1.0) + self.assertRaises(self.failureException, self.assertLess, 1.0, 1.0) + self.assertRaises(self.failureException, self.assertLessEqual, 1.1, 1.0) + + # Try Strings + self.assertGreater('bug', 'ant') + self.assertGreaterEqual('bug', 'ant') + self.assertGreaterEqual('ant', 'ant') + self.assertLess('ant', 'bug') + self.assertLessEqual('ant', 'bug') + self.assertLessEqual('ant', 'ant') + self.assertRaises(self.failureException, self.assertGreater, 'ant', 'bug') + self.assertRaises(self.failureException, self.assertGreater, 'ant', 'ant') + self.assertRaises(self.failureException, self.assertGreaterEqual, 'ant', 'bug') + self.assertRaises(self.failureException, self.assertLess, 'bug', 'ant') + self.assertRaises(self.failureException, self.assertLess, 'ant', 'ant') + self.assertRaises(self.failureException, self.assertLessEqual, 'bug', 'ant') + + # Try bytes + self.assertGreater(b'bug', b'ant') + self.assertGreaterEqual(b'bug', b'ant') + self.assertGreaterEqual(b'ant', b'ant') + self.assertLess(b'ant', b'bug') + self.assertLessEqual(b'ant', b'bug') + self.assertLessEqual(b'ant', b'ant') + self.assertRaises(self.failureException, self.assertGreater, b'ant', b'bug') + self.assertRaises(self.failureException, self.assertGreater, b'ant', b'ant') + self.assertRaises(self.failureException, self.assertGreaterEqual, b'ant', + b'bug') + self.assertRaises(self.failureException, self.assertLess, b'bug', b'ant') + self.assertRaises(self.failureException, self.assertLess, b'ant', b'ant') + self.assertRaises(self.failureException, self.assertLessEqual, b'bug', b'ant') + + def testAssertMultiLineEqual(self): + sample_text = """\ +http://www.python.org/doc/2.3/lib/module-unittest.html +test case + A test case is the smallest unit of testing. [...] +""" + revised_sample_text = """\ +http://www.python.org/doc/2.4.1/lib/module-unittest.html +test case + A test case is the smallest unit of testing. [...] You may provide your + own implementation that does not subclass from TestCase, of course. +""" + sample_text_error = """ +- http://www.python.org/doc/2.3/lib/module-unittest.html +? ^ ++ http://www.python.org/doc/2.4.1/lib/module-unittest.html +? ^^^ + test case +- A test case is the smallest unit of testing. [...] ++ A test case is the smallest unit of testing. [...] You may provide your +? +++++++++++++++++++++ ++ own implementation that does not subclass from TestCase, of course. +""" + + try: + self.assertMultiLineEqual(sample_text, revised_sample_text) + except self.failureException as e: + # no fair testing ourself with ourself, use assertEqual.. + self.assertEqual(sample_text_error, str(e)) + + def testAssertIsNone(self): + self.assertIsNone(None) + self.assertRaises(self.failureException, self.assertIsNone, False) + 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, + 'saaas', r'aaaa') + + def testAssertRaisesRegexp(self): + class ExceptionMock(Exception): + pass + + def Stub(): + raise ExceptionMock('We expect') + + self.assertRaisesRegexp(ExceptionMock, re.compile('expect$'), Stub) + self.assertRaisesRegexp(ExceptionMock, 'expect$', Stub) + + def testAssertNotRaisesRegexp(self): + self.assertRaisesRegexp( + self.failureException, '^Exception not raised$', + self.assertRaisesRegexp, Exception, re.compile('x'), + lambda: None) + self.assertRaisesRegexp( + self.failureException, '^Exception not raised$', + self.assertRaisesRegexp, Exception, 'x', + lambda: None) + + def testAssertRaisesRegexpMismatch(self): + def Stub(): + raise Exception('Unexpected') + + self.assertRaisesRegexp( + self.failureException, + r'"\^Expected\$" does not match "Unexpected"', + self.assertRaisesRegexp, Exception, '^Expected$', + Stub) + self.assertRaisesRegexp( + self.failureException, + r'"\^Expected\$" does not match "Unexpected"', + self.assertRaisesRegexp, Exception, + re.compile('^Expected$'), Stub) + + def testSynonymAssertMethodNames(self): + """Test undocumented method name synonyms. + + Please do not use these methods names in your own code. + + This test confirms their continued existence and functionality + in order to avoid breaking existing code. + """ + self.assertNotEquals(3, 5) + self.assertEquals(3, 3) + self.assertAlmostEquals(2.0, 2.0) + self.assertNotAlmostEquals(3.0, 5.0) + self.assert_(True) + + def testPendingDeprecationMethodNames(self): + """Test fail* methods pending deprecation, they will warn in 3.2. + + Do not use these methods. They will go away in 3.3. + """ + self.failIfEqual(3, 5) + self.failUnlessEqual(3, 3) + self.failUnlessAlmostEqual(2.0, 2.0) + self.failIfAlmostEqual(3.0, 5.0) + self.failUnless(True) + self.failUnlessRaises(TypeError, lambda _: 3.14 + 'spam') + self.failIf(False) + + def testDeepcopy(self): + # Issue: 5660 + class TestableTest(TestCase): + def testNothing(self): + pass + + test = TestableTest('testNothing') + + # This shouldn't blow up + deepcopy(test) + class Test_TestSkipping(TestCase): @@ -2396,20 +2767,20 @@ def test_AlmostEqual(self): self.failUnlessAlmostEqual(1.00000001, 1.0) self.failIfAlmostEqual(1.0000001, 1.0) - self.assertRaises(AssertionError, + self.assertRaises(self.failureException, self.failUnlessAlmostEqual, 1.0000001, 1.0) - self.assertRaises(AssertionError, + self.assertRaises(self.failureException, self.failIfAlmostEqual, 1.00000001, 1.0) self.failUnlessAlmostEqual(1.1, 1.0, places=0) - self.assertRaises(AssertionError, + self.assertRaises(self.failureException, self.failUnlessAlmostEqual, 1.1, 1.0, places=1) self.failUnlessAlmostEqual(0, .1+.1j, places=0) self.failIfAlmostEqual(0, .1+.1j, places=1) - self.assertRaises(AssertionError, + self.assertRaises(self.failureException, self.failUnlessAlmostEqual, 0, .1+.1j, places=1) - self.assertRaises(AssertionError, + self.assertRaises(self.failureException, self.failIfAlmostEqual, 0, .1+.1j, places=0) def test_assertRaises(self): @@ -2419,7 +2790,7 @@ self.assertRaises(KeyError, _raise, KeyError("key")) try: self.assertRaises(KeyError, lambda: None) - except AssertionError as e: + except self.failureException as e: self.assert_("KeyError not raised" in str(e), str(e)) else: self.fail("assertRaises() didn't fail") @@ -2436,7 +2807,7 @@ try: with self.assertRaises(KeyError): pass - except AssertionError as e: + except self.failureException as e: self.assert_("KeyError not raised" in str(e), str(e)) else: self.fail("assertRaises() didn't fail") @@ -2449,6 +2820,172 @@ self.fail("assertRaises() didn't let exception pass through") +class TestLongMessage(TestCase): + """Test that the individual asserts honour longMessage. + This actually tests all the message behaviour for + asserts that use longMessage.""" + + def setUp(self): + class TestableTestFalse(TestCase): + longMessage = False + failureException = self.failureException + + def testTest(self): + pass + + class TestableTestTrue(TestCase): + longMessage = True + failureException = self.failureException + + def testTest(self): + pass + + self.testableTrue = TestableTestTrue('testTest') + self.testableFalse = TestableTestFalse('testTest') + + def testDefault(self): + self.assertFalse(TestCase.longMessage) + + def test_formatMsg(self): + self.assertEquals(self.testableFalse._formatMessage(None, "foo"), "foo") + self.assertEquals(self.testableFalse._formatMessage("foo", "bar"), "foo") + + self.assertEquals(self.testableTrue._formatMessage(None, "foo"), "foo") + self.assertEquals(self.testableTrue._formatMessage("foo", "bar"), "bar : foo") + + def assertMessages(self, methodName, args, errors): + def getMethod(i): + useTestableFalse = i < 2 + if useTestableFalse: + test = self.testableFalse + else: + test = self.testableTrue + return getattr(test, methodName) + + for i, expected_regexp in enumerate(errors): + testMethod = getMethod(i) + kwargs = {} + withMsg = i % 2 + if withMsg: + kwargs = {"msg": "oops"} + + with self.assertRaisesRegexp(self.failureException, + expected_regexp=expected_regexp): + testMethod(*args, **kwargs) + + def testAssertTrue(self): + self.assertMessages('assertTrue', (False,), + ["^False is not True$", "^oops$", "^False is not True$", + "^False is not True : oops$"]) + + def testAssertFalse(self): + self.assertMessages('assertFalse', (True,), + ["^True is not False$", "^oops$", "^True is not False$", + "^True is not False : oops$"]) + + def testNotEqual(self): + self.assertMessages('assertNotEqual', (1, 1), + ["^1 == 1$", "^oops$", "^1 == 1$", + "^1 == 1 : oops$"]) + + def testAlmostEqual(self): + self.assertMessages('assertAlmostEqual', (1, 2), + ["^1 != 2 within 7 places$", "^oops$", + "^1 != 2 within 7 places$", "^1 != 2 within 7 places : oops$"]) + + def testNotAlmostEqual(self): + self.assertMessages('assertNotAlmostEqual', (1, 1), + ["^1 == 1 within 7 places$", "^oops$", + "^1 == 1 within 7 places$", "^1 == 1 within 7 places : oops$"]) + + def test_baseAssertEqual(self): + self.assertMessages('_baseAssertEqual', (1, 2), + ["^1 != 2$", "^oops$", "^1 != 2$", "^1 != 2 : oops$"]) + + def testAssertSequenceEqual(self): + # Error messages are multiline so not testing on full message + # assertTupleEqual and assertListEqual delegate to this method + self.assertMessages('assertSequenceEqual', ([], [None]), + ["\+ \[None\]$", "^oops$", r"\+ \[None\]$", + r"\+ \[None\] : oops$"]) + + def testAssertSetEqual(self): + self.assertMessages('assertSetEqual', (set(), set([None])), + ["None$", "^oops$", "None$", + "None : oops$"]) + + def testAssertIn(self): + self.assertMessages('assertIn', (None, []), + ['^None not found in \[\]$', "^oops$", + '^None not found in \[\]$', + '^None not found in \[\] : oops$']) + + def testAssertNotIn(self): + self.assertMessages('assertNotIn', (None, [None]), + ['^None unexpectedly found in \[None\]$', "^oops$", + '^None unexpectedly found in \[None\]$', + '^None unexpectedly found in \[None\] : oops$']) + + def testAssertDictEqual(self): + self.assertMessages('assertDictEqual', ({}, {'key': 'value'}), + [r"\+ \{'key': 'value'\}$", "^oops$", + "\+ \{'key': 'value'\}$", + "\+ \{'key': 'value'\} : oops$"]) + + def testAssertDictContainsSubset(self): + self.assertMessages('assertDictContainsSubset', ({'key': 'value'}, {}), + ["^Missing: 'key'$", "^oops$", + "^Missing: 'key'$", + "^Missing: 'key' : oops$"]) + + def testAssertSameElements(self): + self.assertMessages('assertSameElements', ([], [None]), + [r"\[None\]$", "^oops$", + r"\[None\]$", + r"\[None\] : oops$"]) + + def testAssertMultiLineEqual(self): + self.assertMessages('assertMultiLineEqual', ("", "foo"), + [r"\+ foo$", "^oops$", + r"\+ foo$", + r"\+ foo : oops$"]) + + def testAssertLess(self): + self.assertMessages('assertLess', (2, 1), + ["^2 not less than 1$", "^oops$", + "^2 not less than 1$", "^2 not less than 1 : oops$"]) + + def testAssertLessEqual(self): + self.assertMessages('assertLessEqual', (2, 1), + ["^2 not less than or equal to 1$", "^oops$", + "^2 not less than or equal to 1$", + "^2 not less than or equal to 1 : oops$"]) + + def testAssertGreater(self): + self.assertMessages('assertGreater', (1, 2), + ["^1 not greater than 2$", "^oops$", + "^1 not greater than 2$", + "^1 not greater than 2 : oops$"]) + + def testAssertGreaterEqual(self): + self.assertMessages('assertGreaterEqual', (1, 2), + ["^1 not greater than or equal to 2$", "^oops$", + "^1 not greater than or equal to 2$", + "^1 not greater than or equal to 2 : oops$"]) + + def testAssertIsNone(self): + self.assertMessages('assertIsNone', ('not None',), + ["^'not None' is not None$", "^oops$", + "^'not None' is not None$", + "^'not None' is not None : oops$"]) + + def testAssertIsNotNone(self): + self.assertMessages('assertIsNotNone', (None,), + ["^unexpectedly None$", "^oops$", + "^unexpectedly None$", + "^unexpectedly None : oops$"]) + + ###################################################################### ## Main ###################################################################### @@ -2456,7 +2993,7 @@ def test_main(): support.run_unittest(Test_TestCase, Test_TestLoader, Test_TestSuite, Test_TestResult, Test_FunctionTestCase, - Test_TestSkipping, Test_Assertions) + Test_TestSkipping, Test_Assertions, TestLongMessage) if __name__ == "__main__": test_main() Modified: python/branches/py3k/Lib/unittest.py ============================================================================== --- python/branches/py3k/Lib/unittest.py (original) +++ python/branches/py3k/Lib/unittest.py Sat Apr 4 18:35:46 2009 @@ -14,11 +14,11 @@ class IntegerArithmenticTestCase(unittest.TestCase): def testAdd(self): ## test method names begin 'test*' - self.assertEquals((1 + 2), 3) - self.assertEquals(0 + 1, 1) + self.assertEqual((1 + 2), 3) + self.assertEqual(0 + 1, 1) def testMultiply(self): - self.assertEquals((0 * 10), 0) - self.assertEquals((5 * 8), 40) + self.assertEqual((0 * 10), 0) + self.assertEqual((5 * 8), 40) if __name__ == '__main__': unittest.main() @@ -45,12 +45,16 @@ SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. ''' -import time +import difflib +import functools +import os +import pprint +import re import sys +import time import traceback -import os import types -import functools +import warnings ############################################################################## # Exported classes and functions @@ -143,7 +147,6 @@ raise _UnexpectedSuccess return wrapper - __unittest = 1 class TestResult(object): @@ -239,10 +242,12 @@ len(self.failures)) -class AssertRaisesContext(object): +class _AssertRaisesContext(object): + """A context manager used to implement TestCase.assertRaises* methods.""" - def __init__(self, expected, test_case, callable_obj=None): + def __init__(self, expected, test_case, callable_obj=None, + expected_regexp=None): self.expected = expected self.failureException = test_case.failureException if callable_obj is not None: @@ -252,6 +257,7 @@ self.obj_name = str(callable_obj) else: self.obj_name = None + self.expected_regex = expected_regexp def __enter__(self): pass @@ -268,10 +274,30 @@ else: raise self.failureException("{0} not raised" .format(exc_name)) - if issubclass(exc_type, self.expected): + if not issubclass(exc_type, self.expected): + # let unexpected exceptions pass through + return False + if self.expected_regex is None: return True - # Let unexpected exceptions skip through - return False + + expected_regexp = self.expected_regex + if isinstance(expected_regexp, (bytes, str)): + expected_regexp = re.compile(expected_regexp) + if not expected_regexp.search(str(exc_value)): + raise self.failureException('"%s" does not match "%s"' % + (expected_regexp.pattern, str(exc_value))) + return True + + +class _AssertWrapper(object): + """Wrap entries in the _type_equality_funcs registry to make them deep + copyable.""" + + def __init__(self, function): + self.function = function + + def __deepcopy__(self, memo): + memo[id(self)] = self class TestCase(object): @@ -302,6 +328,13 @@ failureException = AssertionError + # This attribute determines whether long messages (including repr of + # objects used in assert methods) will be printed on failure in *addition* + # to any explicit message passed. + + longMessage = False + + def __init__(self, methodName='runTest'): """Create an instance of the class that will use the named test method when executed. Raises a ValueError if the instance does @@ -315,6 +348,31 @@ (self.__class__, methodName)) self._testMethodDoc = testMethod.__doc__ + # Map types to custom assertEqual functions that will compare + # instances of said type in more detail to generate a more useful + # error message. + self._type_equality_funcs = {} + self.addTypeEqualityFunc(dict, self.assertDictEqual) + self.addTypeEqualityFunc(list, self.assertListEqual) + self.addTypeEqualityFunc(tuple, self.assertTupleEqual) + self.addTypeEqualityFunc(set, self.assertSetEqual) + self.addTypeEqualityFunc(frozenset, self.assertSetEqual) + + def addTypeEqualityFunc(self, typeobj, function): + """Add a type specific assertEqual style function to compare a type. + + This method is for use by TestCase subclasses that need to register + their own type equality functions to provide nicer error messages. + + Args: + typeobj: The data type to call this function on when both values + are of the same type in assertEqual(). + function: The callable taking two arguments and an optional + msg= argument that raises self.failureException with a + useful error message when the two arguments are not equal. + """ + self._type_equality_funcs[typeobj] = _AssertWrapper(function) + def setUp(self): "Hook method for setting up the test fixture before exercising it." pass @@ -330,14 +388,22 @@ return TestResult() def shortDescription(self): - """Returns a one-line description of the test, or None if no - description has been provided. + """Returns both the test method name and first line of its docstring. + + If no docstring is given, only returns the method name. - The default implementation of this method returns the first line of - the specified test method's docstring. + This method overrides unittest.TestCase.shortDescription(), which + only returns the first line of the docstring, obscuring the name + of the test upon failure. """ - doc = self._testMethodDoc - return doc and doc.split("\n")[0].strip() or None + desc = str(self) + doc_first_line = None + + if self._testMethodDoc: + doc_first_line = self._testMethodDoc.split("\n")[0].strip() + if doc_first_line: + desc = '\n'.join((desc, doc_first_line)) + return desc def id(self): return "%s.%s" % (_strclass(self.__class__), self._testMethodName) @@ -419,17 +485,36 @@ """Fail immediately, with the given message.""" raise self.failureException(msg) - def failIf(self, expr, msg=None): + def assertFalse(self, expr, msg=None): "Fail the test if the expression is true." if expr: + msg = self._formatMessage(msg, "%r is not False" % expr) raise self.failureException(msg) - def failUnless(self, expr, msg=None): + def assertTrue(self, expr, msg=None): """Fail the test unless the expression is true.""" if not expr: + msg = self._formatMessage(msg, "%r is not True" % expr) raise self.failureException(msg) - def failUnlessRaises(self, excClass, callableObj=None, *args, **kwargs): + def _formatMessage(self, msg, standardMsg): + """Honour the longMessage attribute when generating failure messages. + If longMessage is False this means: + * Use only an explicit message if it is provided + * Otherwise use the standard message for the assert + + If longMessage is True: + * Use the standard message + * If an explicit message is provided, plus ' : ' and the explicit message + """ + if not self.longMessage: + return msg or standardMsg + if msg is None: + return standardMsg + return standardMsg + ' : ' + msg + + + def assertRaises(self, excClass, callableObj=None, *args, **kwargs): """Fail unless an exception of class excClass is thrown by callableObj when invoked with arguments args and keyword arguments kwargs. If a different type of exception is @@ -440,30 +525,62 @@ If called with callableObj omitted or None, will return a context object used like this:: - with self.failUnlessRaises(some_error_class): + with self.assertRaises(some_error_class): do_something() """ - context = AssertRaisesContext(excClass, self, callableObj) + context = _AssertRaisesContext(excClass, self, callableObj) if callableObj is None: return context with context: callableObj(*args, **kwargs) - def failUnlessEqual(self, first, second, msg=None): + def _getAssertEqualityFunc(self, first, second): + """Get a detailed comparison function for the types of the two args. + + Returns: A callable accepting (first, second, msg=None) that will + raise a failure exception if first != second with a useful human + readable error message for those types. + """ + # + # NOTE(gregory.p.smith): I considered isinstance(first, type(second)) + # and vice versa. I opted for the conservative approach in case + # subclasses are not intended to be compared in detail to their super + # class instances using a type equality func. This means testing + # subtypes won't automagically use the detailed comparison. Callers + # should use their type specific assertSpamEqual method to compare + # subclasses if the detailed comparison is desired and appropriate. + # See the discussion in http://bugs.python.org/issue2578. + # + if type(first) is type(second): + asserter = self._type_equality_funcs.get(type(first)) + if asserter is not None: + return asserter.function + + return self._baseAssertEqual + + def _baseAssertEqual(self, first, second, msg=None): + """The default assertEqual implementation, not type specific.""" + if not first == second: + standardMsg = '%r != %r' % (first, second) + msg = self._formatMessage(msg, standardMsg) + raise self.failureException(msg) + + def assertEqual(self, first, second, msg=None): """Fail if the two objects are unequal as determined by the '==' operator. """ - if not first == second: - raise self.failureException(msg or '%r != %r' % (first, second)) + assertion_func = self._getAssertEqualityFunc(first, second) + assertion_func(first, second, msg=msg) - def failIfEqual(self, first, second, msg=None): + def assertNotEqual(self, first, second, msg=None): """Fail if the two objects are equal as determined by the '==' operator. """ - if first == second: - raise self.failureException(msg or '%r == %r' % (first, second)) + if not first != second: + msg = self._formatMessage(msg, '%r == %r' % (first, second)) + raise self.failureException(msg) - def failUnlessAlmostEqual(self, first, second, *, places=7, msg=None): + def assertAlmostEqual(self, first, second, *, places=7, msg=None): """Fail if the two objects are unequal as determined by their difference rounded to the given number of decimal places (default 7) and comparing to zero. @@ -472,10 +589,11 @@ as significant digits (measured from the most signficant digit). """ if round(abs(second-first), places) != 0: - raise self.failureException( - msg or '%r != %r within %r places' % (first, second, places)) + standardMsg = '%r != %r within %r places' % (first, second, places) + msg = self._formatMessage(msg, standardMsg) + raise self.failureException(msg) - def failIfAlmostEqual(self, first, second, *, places=7, msg=None): + def assertNotAlmostEqual(self, first, second, *, places=7, msg=None): """Fail if the two objects are equal as determined by their difference rounded to the given number of decimal places (default 7) and comparing to zero. @@ -484,25 +602,388 @@ as significant digits (measured from the most signficant digit). """ if round(abs(second-first), places) == 0: - raise self.failureException( - msg or '%r == %r within %r places' % (first, second, places)) + standardMsg = '%r == %r within %r places' % (first, second, places) + msg = self._formatMessage(msg, standardMsg) + raise self.failureException(msg) # Synonyms for assertion methods - assertEqual = assertEquals = failUnlessEqual + # The plurals are undocumented. Keep them that way to discourage use. + # Do not add more. Do not remove. + # Going through a deprecation cycle on these would annoy many people. + assertEquals = assertEqual + assertNotEquals = assertNotEqual + assertAlmostEquals = assertAlmostEqual + assertNotAlmostEquals = assertNotAlmostEqual + assert_ = assertTrue + + # These fail* assertion method names are pending deprecation and will + # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578 + def _deprecate(original_func): + def deprecated_func(*args, **kwargs): + warnings.warn( + 'Please use {0} instead.'.format(original_func.__name__), + PendingDeprecationWarning, 2) + return original_func(*args, **kwargs) + return deprecated_func + + failUnlessEqual = _deprecate(assertEqual) + failIfEqual = _deprecate(assertNotEqual) + failUnlessAlmostEqual = _deprecate(assertAlmostEqual) + failIfAlmostEqual = _deprecate(assertNotAlmostEqual) + failUnless = _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). + + For the purposes of this function, a valid orderd sequence type is one + which can be indexed, has a length, and has an equality operator. + + Args: + seq1: The first sequence to compare. + seq2: The second sequence to compare. + seq_type: The expected datatype of the sequences, or None if no + datatype should be enforced. + msg: Optional message to use on failure instead of a list of + differences. + """ + if seq_type != None: + seq_type_name = seq_type.__name__ + if not isinstance(seq1, seq_type): + raise self.failureException('First sequence is not a %s: %r' + % (seq_type_name, seq1)) + if not isinstance(seq2, seq_type): + raise self.failureException('Second sequence is not a %s: %r' + % (seq_type_name, seq2)) + else: + seq_type_name = "sequence" - assertNotEqual = assertNotEquals = failIfEqual + differing = None + try: + len1 = len(seq1) + except (TypeError, NotImplementedError): + differing = 'First %s has no length. Non-sequence?' % ( + seq_type_name) - assertAlmostEqual = assertAlmostEquals = failUnlessAlmostEqual + if differing is None: + try: + len2 = len(seq2) + except (TypeError, NotImplementedError): + differing = 'Second %s has no length. Non-sequence?' % ( + seq_type_name) + + if differing is None: + if seq1 == seq2: + return + + for i in range(min(len1, len2)): + try: + item1 = seq1[i] + except (TypeError, IndexError, NotImplementedError): + differing = ('Unable to index element %d of first %s\n' % + (i, seq_type_name)) + break + + try: + item2 = seq2[i] + except (TypeError, IndexError, NotImplementedError): + differing = ('Unable to index element %d of second %s\n' % + (i, seq_type_name)) + break + + if item1 != item2: + differing = ('First differing element %d:\n%s\n%s\n' % + (i, item1, item2)) + break + else: + if (len1 == len2 and seq_type is None and + type(seq1) != type(seq2)): + # The sequences are the same, but have differing types. + return + # A catch-all message for handling arbitrary user-defined + # sequences. + differing = '%ss differ:\n' % seq_type_name.capitalize() + if len1 > len2: + differing = ('First %s contains %d additional ' + 'elements.\n' % (seq_type_name, len1 - len2)) + try: + differing += ('First extra element %d:\n%s\n' % + (len2, seq1[len2])) + except (TypeError, IndexError, NotImplementedError): + differing += ('Unable to index element %d ' + 'of first %s\n' % (len2, seq_type_name)) + elif len1 < len2: + differing = ('Second %s contains %d additional ' + 'elements.\n' % (seq_type_name, len2 - len1)) + try: + differing += ('First extra element %d:\n%s\n' % + (len1, seq2[len1])) + except (TypeError, IndexError, NotImplementedError): + differing += ('Unable to index element %d ' + 'of second %s\n' % (len1, seq_type_name)) + standardMsg = differing + '\n'.join(difflib.ndiff(pprint.pformat(seq1).splitlines(), + pprint.pformat(seq2).splitlines())) + msg = self._formatMessage(msg, standardMsg) + self.fail(msg) + + def assertListEqual(self, list1, list2, msg=None): + """A list-specific equality assertion. + + Args: + list1: The first list to compare. + list2: The second list to compare. + msg: Optional message to use on failure instead of a list of + differences. + + """ + self.assertSequenceEqual(list1, list2, msg, seq_type=list) + + def assertTupleEqual(self, tuple1, tuple2, msg=None): + """A tuple-specific equality assertion. + + Args: + tuple1: The first tuple to compare. + tuple2: The second tuple to compare. + msg: Optional message to use on failure instead of a list of + differences. + """ + self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple) - assertNotAlmostEqual = assertNotAlmostEquals = failIfAlmostEqual + def assertSetEqual(self, set1, set2, msg=None): + """A set-specific equality assertion. - assertRaises = failUnlessRaises + Args: + set1: The first set to compare. + set2: The second set to compare. + msg: Optional message to use on failure instead of a list of + differences. + + For more general containership equality, assertSameElements will work + with things other than sets. This uses ducktyping to support + different types of sets, and is optimized for sets specifically + (parameters must support a difference method). + """ + try: + difference1 = set1.difference(set2) + except TypeError as e: + self.fail('invalid type when attempting set difference: %s' % e) + except AttributeError as e: + self.fail('first argument does not support set difference: %s' % e) - assert_ = assertTrue = failUnless + try: + difference2 = set2.difference(set1) + except TypeError as e: + self.fail('invalid type when attempting set difference: %s' % e) + except AttributeError as e: + self.fail('second argument does not support set difference: %s' % e) + + if not (difference1 or difference2): + return + + lines = [] + if difference1: + lines.append('Items in the first set but not the second:') + for item in difference1: + lines.append(repr(item)) + if difference2: + lines.append('Items in the second set but not the first:') + for item in difference2: + lines.append(repr(item)) + + standardMsg = '\n'.join(lines) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertIn(self, member, container, msg=None): + """Just like self.assertTrue(a in b), but with a nicer default message.""" + if member not in container: + standardMsg = '%r not found in %r' % (member, container) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertNotIn(self, member, container, msg=None): + """Just like self.assertTrue(a not in b), but with a nicer default message.""" + if member in container: + standardMsg = '%r unexpectedly found in %r' % (member, container) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertDictEqual(self, d1, d2, msg=None): + self.assert_(isinstance(d1, dict), 'First argument is not a dictionary') + self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary') + + if d1 != d2: + standardMsg = ('\n' + '\n'.join(difflib.ndiff( + pprint.pformat(d1).splitlines(), + pprint.pformat(d2).splitlines()))) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertDictContainsSubset(self, expected, actual, msg=None): + """Checks whether actual is a superset of expected.""" + missing = [] + mismatched = [] + for key, value in expected.items(): + if key not in actual: + missing.append(key) + elif value != actual[key]: + mismatched.append('%s, expected: %s, actual: %s' % (key, value, actual[key])) + + if not (missing or mismatched): + return + + standardMsg = '' + if missing: + standardMsg = 'Missing: %r' % ','.join(missing) + if mismatched: + if standardMsg: + standardMsg += '; ' + standardMsg += 'Mismatched values: %s' % ','.join(mismatched) - assertFalse = failIf + self.fail(self._formatMessage(msg, standardMsg)) + def assertSameElements(self, expected_seq, actual_seq, msg=None): + """An unordered sequence specific comparison. + + Raises with an error message listing which elements of expected_seq + are missing from actual_seq and vice versa if any. + """ + try: + expected = set(expected_seq) + actual = set(actual_seq) + missing = list(expected.difference(actual)) + unexpected = list(actual.difference(expected)) + missing.sort() + unexpected.sort() + except TypeError: + # Fall back to slower list-compare if any of the objects are + # not hashable. + expected = list(expected_seq) + actual = list(actual_seq) + expected.sort() + actual.sort() + missing, unexpected = _SortedListDifference(expected, actual) + errors = [] + if missing: + errors.append('Expected, but missing:\n %r' % missing) + if unexpected: + errors.append('Unexpected, but present:\n %r' % unexpected) + if errors: + standardMsg = '\n'.join(errors) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertMultiLineEqual(self, first, second, msg=None): + """Assert that two multi-line strings are equal.""" + self.assert_(isinstance(first, str), ( + 'First argument is not a string')) + self.assert_(isinstance(second, str), ( + 'Second argument is not a string')) + + if first != second: + standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True), second.splitlines(True))) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertLess(self, a, b, msg=None): + """Just like self.assertTrue(a < b), but with a nicer default message.""" + if not a < b: + standardMsg = '%r not less than %r' % (a, b) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertLessEqual(self, a, b, msg=None): + """Just like self.assertTrue(a <= b), but with a nicer default message.""" + if not a <= b: + standardMsg = '%r not less than or equal to %r' % (a, b) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertGreater(self, a, b, msg=None): + """Just like self.assertTrue(a > b), but with a nicer default message.""" + if not a > b: + standardMsg = '%r not greater than %r' % (a, b) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertGreaterEqual(self, a, b, msg=None): + """Just like self.assertTrue(a >= b), but with a nicer default message.""" + if not a >= b: + standardMsg = '%r not greater than or equal to %r' % (a, b) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertIsNone(self, obj, msg=None): + """Same as self.assertTrue(obj is None), with a nicer default message.""" + if obj is not None: + standardMsg = '%r is not None' % obj + self.fail(self._formatMessage(msg, standardMsg)) + + def assertIsNotNone(self, obj, msg=None): + """Included for symmetry with assertIsNone.""" + if obj is None: + standardMsg = 'unexpectedly None' + 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. + + Args: + expected_exception: Exception class expected to be raised. + expected_regexp: Regexp (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) + if callable_obj is None: + return context + with context: + callable_obj(*args, **kwargs) + + def assertRegexpMatches(self, text, expected_regex, msg=None): + if isinstance(expected_regex, (str, bytes)): + expected_regex = re.compile(expected_regex) + if not expected_regex.search(text): + msg = msg or "Regexp didn't match" + msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text) + raise self.failureException(msg) + + +def _SortedListDifference(expected, actual): + """Finds elements in only one or the other of two, sorted input lists. + + Returns a two-element tuple of lists. The first list contains those + elements in the "expected" list but not in the "actual" list, and the + second contains those elements in the "actual" list but not in the + "expected" list. Duplicate elements in either input list are ignored. + """ + i = j = 0 + missing = [] + unexpected = [] + while True: + try: + e = expected[i] + a = actual[j] + if e < a: + missing.append(e) + i += 1 + while expected[i] == e: + i += 1 + elif e > a: + unexpected.append(a) + j += 1 + while actual[j] == a: + j += 1 + else: + i += 1 + try: + while expected[i] == e: + i += 1 + finally: + j += 1 + while actual[j] == a: + j += 1 + except IndexError: + missing.extend(expected[i:]) + unexpected.extend(actual[j:]) + break + return missing, unexpected class TestSuite(object): @@ -611,52 +1092,52 @@ def __init__(self, testFunc, setUp=None, tearDown=None, description=None): super(FunctionTestCase, self).__init__() - self.__setUpFunc = setUp - self.__tearDownFunc = tearDown - self.__testFunc = testFunc - self.__description = description + self._setUpFunc = setUp + self._tearDownFunc = tearDown + self._testFunc = testFunc + self._description = description def setUp(self): - if self.__setUpFunc is not None: - self.__setUpFunc() + if self._setUpFunc is not None: + self._setUpFunc() def tearDown(self): - if self.__tearDownFunc is not None: - self.__tearDownFunc() + if self._tearDownFunc is not None: + self._tearDownFunc() def runTest(self): - self.__testFunc() + self._testFunc() def id(self): - return self.__testFunc.__name__ + return self._testFunc.__name__ def __eq__(self, other): if not isinstance(other, self.__class__): return NotImplemented - return self.__setUpFunc == other.__setUpFunc and \ - self.__tearDownFunc == other.__tearDownFunc and \ - self.__testFunc == other.__testFunc and \ - self.__description == other.__description + return self._setUpFunc == other._setUpFunc and \ + self._tearDownFunc == other._tearDownFunc and \ + self._testFunc == other._testFunc and \ + self._description == other._description def __ne__(self, other): return not self == other def __hash__(self): - return hash((type(self), self.__setUpFunc, self.__tearDownFunc, - self.__testFunc, self.__description)) + return hash((type(self), self._setUpFunc, self._tearDownFunc, + self._testFunc, self._description)) def __str__(self): return "%s (%s)" % (_strclass(self.__class__), self.__testFunc.__name__) def __repr__(self): - return "<%s testFunc=%s>" % (_strclass(self.__class__), - self.__testFunc) + return "<%s testFunc=%s>" % (_strclass(self.__class__), self._testFunc) def shortDescription(self): - if self.__description is not None: return self.__description - doc = self.__testFunc.__doc__ + if self._description is not None: + return self._description + doc = self._testFunc.__doc__ return doc and doc.split("\n")[0].strip() or None From python-checkins at python.org Sat Apr 4 18:38:09 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 18:38:09 +0200 (CEST) Subject: [Python-checkins] r71170 - in python/branches/py3k: Include/object.h Message-ID: <20090404163809.D8E101E4015@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 18:38:09 2009 New Revision: 71170 Log: Merged revisions 71163 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71163 | benjamin.peterson | 2009-04-04 11:05:51 -0500 (Sat, 04 Apr 2009) | 1 line revert r71159 since it broke the build ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Include/object.h Modified: python/branches/py3k/Include/object.h ============================================================================== --- python/branches/py3k/Include/object.h (original) +++ python/branches/py3k/Include/object.h Sat Apr 4 18:38:09 2009 @@ -651,13 +651,11 @@ ((PyObject*)(op))->ob_refcnt++) #define Py_DECREF(op) \ - do { \ - if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ - --((PyObject*)(op))->ob_refcnt != 0) \ - _Py_CHECK_REFCNT(op) \ - else \ - _Py_Dealloc((PyObject *)(op)) \ - } while (0) + if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ + --((PyObject*)(op))->ob_refcnt != 0) \ + _Py_CHECK_REFCNT(op) \ + else \ + _Py_Dealloc((PyObject *)(op)) /* Safely decref `op` and set `op` to NULL, especially useful in tp_clear * and tp_dealloc implementatons. From python-checkins at python.org Sat Apr 4 18:39:09 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 18:39:09 +0200 (CEST) Subject: [Python-checkins] r71171 - python/branches/py3k/Lib/test/test_unittest.py Message-ID: <20090404163909.3FA421E4015@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 18:39:09 2009 New Revision: 71171 Log: fix test_unittest 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 Sat Apr 4 18:39:09 2009 @@ -2608,11 +2608,11 @@ def testAssertNotRaisesRegexp(self): self.assertRaisesRegexp( - self.failureException, '^Exception not raised$', + self.failureException, '^Exception not raised by $', self.assertRaisesRegexp, Exception, re.compile('x'), lambda: None) self.assertRaisesRegexp( - self.failureException, '^Exception not raised$', + self.failureException, '^Exception not raised by $', self.assertRaisesRegexp, Exception, 'x', lambda: None) From buildbot at python.org Sat Apr 4 18:45:33 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 16:45:33 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 2.6 Message-ID: <20090404164533.63C191E4015@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%202.6/builds/214 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From python-checkins at python.org Sat Apr 4 18:46:24 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 18:46:24 +0200 (CEST) Subject: [Python-checkins] r71172 - python/branches/py3k/Lib/test/test_unittest.py Message-ID: <20090404164624.ECAEF1E4015@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 18:46:24 2009 New Revision: 71172 Log: mark dictionary assertElementsSame test as an expected failure 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 Sat Apr 4 18:46:24 2009 @@ -2392,6 +2392,8 @@ self.assertRaises(self.failureException, self.assertEqual, a, b, msg='foo') + # The fact that dictionaries are unorderable breaks this test for them. + @expectedFailure def testEquality(self): self.assertListEqual([], []) self.assertTupleEqual((), ()) @@ -2454,6 +2456,7 @@ # Test that sequences of unhashable objects can be tested for sameness: self.assertSameElements([[1, 2], [3, 4]], [[3, 4], [1, 2]]) + self.assertSameElements([{'a': 1}, {'b': 2}], [{'b': 2}, {'a': 1}]) self.assertRaises(self.failureException, self.assertSameElements, [[1]], [[2]]) From python-checkins at python.org Sat Apr 4 18:47:31 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 18:47:31 +0200 (CEST) Subject: [Python-checkins] r71173 - python/branches/py3k/Lib/test/test_unittest.py Message-ID: <20090404164731.D8CD41E4015@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 18:47:31 2009 New Revision: 71173 Log: fix name 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 Sat Apr 4 18:47:31 2009 @@ -2393,7 +2393,7 @@ msg='foo') # The fact that dictionaries are unorderable breaks this test for them. - @expectedFailure + @unittest.expectedFailure def testEquality(self): self.assertListEqual([], []) self.assertTupleEqual((), ()) From python-checkins at python.org Sat Apr 4 19:09:36 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 19:09:36 +0200 (CEST) Subject: [Python-checkins] r71174 - in python/branches/py3k: Doc/library/mmap.rst Lib/test/test_mmap.py Misc/NEWS Modules/mmapmodule.c Message-ID: <20090404170936.287FE1E4015@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 19:09:35 2009 New Revision: 71174 Log: #5391 make mmap work exclusively with bytes Modified: python/branches/py3k/Doc/library/mmap.rst python/branches/py3k/Lib/test/test_mmap.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/mmapmodule.c Modified: python/branches/py3k/Doc/library/mmap.rst ============================================================================== --- python/branches/py3k/Doc/library/mmap.rst (original) +++ python/branches/py3k/Doc/library/mmap.rst Sat Apr 4 19:09:35 2009 @@ -6,13 +6,13 @@ :synopsis: Interface to memory-mapped files for Unix and Windows. -Memory-mapped file objects behave like both strings and like file objects. -Unlike normal string objects, however, these are mutable. You can use mmap -objects in most places where strings are expected; for example, you can use -the :mod:`re` module to search through a memory-mapped file. Since they're -mutable, you can change a single character by doing ``obj[index] = 'a'``, or -change a substring by assigning to a slice: ``obj[i1:i2] = '...'``. You can -also read and write data starting at the current file position, and +Memory-mapped file objects behave like both :class:`bytes` and like file +objects. Unlike normal :class:`bytes` objects, however, these are mutable. +You can use mmap objects in most places where :class:`bytes` are expected; for +example, you can use the :mod:`re` module to search through a memory-mapped file. +Since they're mutable, you can change a single byte by doing ``obj[index] = 97``, +or change a subsequence by assigning to a slice: ``obj[i1:i2] = b'...'``. +You can also read and write data starting at the current file position, and :meth:`seek` through the file to different positions. A memory-mapped file is created by the :class:`mmap` constructor, which is @@ -94,21 +94,21 @@ # write a simple example file with open("hello.txt", "wb") as f: - f.write("Hello Python!\n") + f.write(b"Hello Python!\n") with open("hello.txt", "r+b") as f: # memory-map the file, size 0 means whole file map = mmap.mmap(f.fileno(), 0) # read content via standard file methods - print(map.readline()) # prints "Hello Python!" + print(map.readline()) # prints b"Hello Python!\n" # read content via slice notation - print(map[:5]) # prints "Hello" + print(map[:5]) # prints b"Hello" # update content using slice notation; # note that new content must have same size - map[6:] = " world!\n" + map[6:] = b" world!\n" # ... and read again using standard file methods map.seek(0) - print(map.readline()) # prints "Hello world!" + print(map.readline()) # prints b"Hello world!\n" # close the map map.close() @@ -120,7 +120,7 @@ import os map = mmap.mmap(-1, 13) - map.write("Hello world!") + map.write(b"Hello world!") pid = os.fork() @@ -140,10 +140,10 @@ result in an exception being raised. - .. method:: find(string[, start[, end]]) + .. method:: find(sub[, start[, end]]) - Returns the lowest index in the object where the substring *string* is - found, such that *string* is contained in the range [*start*, *end*]. + Returns the lowest index in the object where the subsequence *sub* is + found, such that *sub* is contained in the range [*start*, *end*]. Optional arguments *start* and *end* are interpreted as in slice notation. Returns ``-1`` on failure. @@ -172,15 +172,15 @@ .. method:: read(num) - Return a string containing up to *num* bytes starting from the current - file position; the file position is updated to point after the bytes that - were returned. + Return a :class:`bytes` containing up to *num* bytes starting from the + current file position; the file position is updated to point after the + bytes that were returned. .. method:: read_byte() - Returns a string of length 1 containing the character at the current file - position, and advances the file position by 1. + Returns a byte at the current file position as an integer, and advances + the file position by 1. .. method:: readline() @@ -196,10 +196,10 @@ throw a :exc:`TypeError` exception. - .. method:: rfind(string[, start[, end]]) + .. method:: rfind(sub[, start[, end]]) - Returns the highest index in the object where the substring *string* is - found, such that *string* is contained in the range [*start*, *end*]. + Returns the highest index in the object where the subsequence *sub* is + found, such that *sub* is contained in the range [*start*, *end*]. Optional arguments *start* and *end* are interpreted as in slice notation. Returns ``-1`` on failure. @@ -223,9 +223,9 @@ Returns the current position of the file pointer. - .. method:: write(string) + .. method:: write(bytes) - Write the bytes in *string* into memory at the current position of the + Write the bytes in *bytes* into memory at the current position of the file pointer; the file position is updated to point after the bytes that were written. If the mmap was created with :const:`ACCESS_READ`, then writing to it will throw a :exc:`TypeError` exception. @@ -233,7 +233,7 @@ .. method:: write_byte(byte) - Write the single-character string *byte* into memory at the current + Write the the integer *byte* into memory at the current position of the file pointer; the file position is advanced by ``1``. If the mmap was created with :const:`ACCESS_READ`, then writing to it will throw a :exc:`TypeError` exception. Modified: python/branches/py3k/Lib/test/test_mmap.py ============================================================================== --- python/branches/py3k/Lib/test/test_mmap.py (original) +++ python/branches/py3k/Lib/test/test_mmap.py Sat Apr 4 19:09:35 2009 @@ -37,7 +37,7 @@ # Simple sanity checks tp = str(type(m)) # SF bug 128713: segfaulted on Linux - self.assertEqual(m.find('foo'), PAGESIZE) + self.assertEqual(m.find(b'foo'), PAGESIZE) self.assertEqual(len(m), 2*PAGESIZE) @@ -262,38 +262,38 @@ def test_find_end(self): # test the new 'end' parameter works as expected - f = open(TESTFN, 'w+') - data = 'one two ones' + f = open(TESTFN, 'wb+') + data = b'one two ones' n = len(data) f.write(data) f.flush() m = mmap.mmap(f.fileno(), n) f.close() - self.assertEqual(m.find('one'), 0) - self.assertEqual(m.find('ones'), 8) - self.assertEqual(m.find('one', 0, -1), 0) - self.assertEqual(m.find('one', 1), 8) - self.assertEqual(m.find('one', 1, -1), 8) - self.assertEqual(m.find('one', 1, -2), -1) + self.assertEqual(m.find(b'one'), 0) + self.assertEqual(m.find(b'ones'), 8) + self.assertEqual(m.find(b'one', 0, -1), 0) + self.assertEqual(m.find(b'one', 1), 8) + self.assertEqual(m.find(b'one', 1, -1), 8) + self.assertEqual(m.find(b'one', 1, -2), -1) def test_rfind(self): # test the new 'end' parameter works as expected - f = open(TESTFN, 'w+') - data = 'one two ones' + f = open(TESTFN, 'wb+') + data = b'one two ones' n = len(data) f.write(data) f.flush() m = mmap.mmap(f.fileno(), n) f.close() - self.assertEqual(m.rfind('one'), 8) - self.assertEqual(m.rfind('one '), 0) - self.assertEqual(m.rfind('one', 0, -1), 8) - self.assertEqual(m.rfind('one', 0, -2), 0) - self.assertEqual(m.rfind('one', 1, -1), 8) - self.assertEqual(m.rfind('one', 1, -2), -1) + self.assertEqual(m.rfind(b'one'), 8) + self.assertEqual(m.rfind(b'one '), 0) + self.assertEqual(m.rfind(b'one', 0, -1), 8) + self.assertEqual(m.rfind(b'one', 0, -2), 0) + self.assertEqual(m.rfind(b'one', 1, -1), 8) + self.assertEqual(m.rfind(b'one', 1, -2), -1) def test_double_close(self): @@ -506,21 +506,15 @@ # Test write_byte() for i in range(len(data)): self.assertEquals(m.tell(), i) - m.write_byte(data[i:i+1]) + m.write_byte(data[i]) self.assertEquals(m.tell(), i+1) - self.assertRaises(ValueError, m.write_byte, b"x") + self.assertRaises(ValueError, m.write_byte, b"x"[0]) self.assertEquals(m[:], data) # Test read_byte() m.seek(0) for i in range(len(data)): self.assertEquals(m.tell(), i) - # XXX: Disable this test for now because it's not clear - # which type of object m.read_byte returns. Currently, it - # returns 1-length str (unicode). - if 0: - self.assertEquals(m.read_byte(), data[i:i+1]) - else: - m.read_byte() + self.assertEquals(m.read_byte(), data[i]) self.assertEquals(m.tell(), i+1) self.assertRaises(ValueError, m.read_byte) # Test read() Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Apr 4 19:09:35 2009 @@ -11,6 +11,7 @@ Core and Builtins ----------------- + - Implement PEP 378, Format Specifier for Thousands Separator, for integers. @@ -128,6 +129,8 @@ Extension Modules ----------------- +- Issue #5391: mmap now deals exclusively with bytes. + - Issue #5463: In struct module, remove deprecated overflow wrapping when packing an integer: struct.pack('=L', -1) now raises struct.error instead of returning b'\xff\xff\xff\xff'. The Modified: python/branches/py3k/Modules/mmapmodule.c ============================================================================== --- python/branches/py3k/Modules/mmapmodule.c (original) +++ python/branches/py3k/Modules/mmapmodule.c Sat Apr 4 19:09:35 2009 @@ -204,7 +204,7 @@ if (self->pos < self->size) { char value = self->data[self->pos]; self->pos += 1; - return Py_BuildValue("c", value); + return Py_BuildValue("b", value); } else { PyErr_SetString(PyExc_ValueError, "read byte out of range"); return NULL; @@ -264,7 +264,7 @@ Py_ssize_t len; CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, reverse ? "s#|nn:rfind" : "s#|nn:find", + if (!PyArg_ParseTuple(args, reverse ? "y#|nn:rfind" : "y#|nn:find", &needle, &len, &start, &end)) { return NULL; } else { @@ -348,7 +348,7 @@ char *data; CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "s#:write", &data, &length)) + if (!PyArg_ParseTuple(args, "y#:write", &data, &length)) return(NULL); if (!is_writable(self)) @@ -371,7 +371,7 @@ char value; CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "c:write_byte", &value)) + if (!PyArg_ParseTuple(args, "b:write_byte", &value)) return(NULL); if (!is_writable(self)) From python-checkins at python.org Sat Apr 4 19:20:05 2009 From: python-checkins at python.org (hirokazu.yamamoto) Date: Sat, 4 Apr 2009 19:20:05 +0200 (CEST) Subject: [Python-checkins] r71175 - python/trunk/Lib/test/test_mmap.py Message-ID: <20090404172005.C32441E4015@bag.python.org> Author: hirokazu.yamamoto Date: Sat Apr 4 19:20:05 2009 New Revision: 71175 Log: No behavior change. Modified: python/trunk/Lib/test/test_mmap.py Modified: python/trunk/Lib/test/test_mmap.py ============================================================================== --- python/trunk/Lib/test/test_mmap.py (original) +++ python/trunk/Lib/test/test_mmap.py Sat Apr 4 19:20:05 2009 @@ -513,7 +513,7 @@ # Test write_byte() for i in xrange(len(data)): self.assertEquals(m.tell(), i) - m.write_byte(data[i:i+1]) + m.write_byte(data[i]) self.assertEquals(m.tell(), i+1) self.assertRaises(ValueError, m.write_byte, "x") self.assertEquals(m[:], data) @@ -521,7 +521,7 @@ m.seek(0) for i in xrange(len(data)): self.assertEquals(m.tell(), i) - self.assertEquals(m.read_byte(), data[i:i+1]) + self.assertEquals(m.read_byte(), data[i]) self.assertEquals(m.tell(), i+1) self.assertRaises(ValueError, m.read_byte) # Test read() From python-checkins at python.org Sat Apr 4 19:26:32 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 19:26:32 +0200 (CEST) Subject: [Python-checkins] r71176 - python/branches/py3k/Lib/collections.py Message-ID: <20090404172632.C4E7A1E4015@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 19:26:32 2009 New Revision: 71176 Log: must provide this method Modified: python/branches/py3k/Lib/collections.py Modified: python/branches/py3k/Lib/collections.py ============================================================================== --- python/branches/py3k/Lib/collections.py (original) +++ python/branches/py3k/Lib/collections.py Sat Apr 4 19:26:32 2009 @@ -132,6 +132,9 @@ all(p==q for p, q in zip(self.items(), other.items())) return dict.__eq__(self, other) + def __ne__(self, other): + return not self == other + ################################################################################ From python-checkins at python.org Sat Apr 4 19:35:39 2009 From: python-checkins at python.org (hirokazu.yamamoto) Date: Sat, 4 Apr 2009 19:35:39 +0200 (CEST) Subject: [Python-checkins] r71177 - python/branches/py3k Message-ID: <20090404173539.15AC61E43C7@bag.python.org> Author: hirokazu.yamamoto Date: Sat Apr 4 19:35:38 2009 New Revision: 71177 Log: Blocked revisions 71175 via svnmerge ........ r71175 | hirokazu.yamamoto | 2009-04-05 02:20:05 +0900 | 1 line No behavior change. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Apr 4 19:36:05 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 4 Apr 2009 19:36:05 +0200 (CEST) Subject: [Python-checkins] r71178 - python/branches/py3k/Lib/test/test_sys.py Message-ID: <20090404173605.C6C2D1E43AF@bag.python.org> Author: antoine.pitrou Date: Sat Apr 4 19:36:05 2009 New Revision: 71178 Log: Skip test_recursionlimit_fatalerror under Windows because it generates an annoying and misleading crash dialog. Modified: python/branches/py3k/Lib/test/test_sys.py 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 Sat Apr 4 19:36:05 2009 @@ -177,6 +177,9 @@ def test_recursionlimit_fatalerror(self): # A fatal error occurs if a second recursion limit is hit when recovering # from a first one. + if os.name == "nt": + raise unittest.SkipTest( + "under Windows, test would generate a spurious crash dialog") code = textwrap.dedent(""" import sys From buildbot at python.org Sat Apr 4 20:27:27 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 18:27:27 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090404182727.D79D61E4044@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/478 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson,matthias.klose BUILD FAILED: failed test Excerpt from the test logfile: 3 tests failed: test_collections test_importlib test_posix ====================================================================== FAIL: test_equality (test.test_collections.TestOrderedDict) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_collections.py", line 714, in test_equality self.assertNotEqual(od1, od2) # different order implies inequality AssertionError: OrderedDict([('d', 4), ('f', 6), ('c', 1), ('a', 3), ('e', 5), ('b', 2)]) == OrderedDict([('c', 1), ('a', 3), ('e', 5), ('b', 2), ('d', 4), ('f', 6)]) Traceback (most recent call last): File "./Lib/test/regrtest.py", line 620, in runtest_inner File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_importlib.py", line 6, in test_main run_unittest(importlib.test.test_suite('importlib.test')) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/__init__.py", line 22, in test_suite package_tests = getattr(sys.modules[package_name], 'test_suite')() File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/source/__init__.py", line 8, in test_suite return importlib.test.test_suite('importlib.test.source', directory) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/__init__.py", line 16, in test_suite __import__(module_name, level=0) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/source/test_case_sensitivity.py", line 12, in class CaseSensitivityTest(unittest.TestCase): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/util.py", line 13, in case_insensitive_tests original_name = os.listdir('.')[0] IndexError: list index out of range ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 249, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 102, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Sat Apr 4 20:44:44 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 4 Apr 2009 20:44:44 +0200 (CEST) Subject: [Python-checkins] r71179 - python/trunk/Tools/msi/msi.py Message-ID: <20090404184444.61AB01E4019@bag.python.org> Author: martin.v.loewis Date: Sat Apr 4 20:44:44 2009 New Revision: 71179 Log: Issue #5470: Package zipdir.zip. Modified: python/trunk/Tools/msi/msi.py Modified: python/trunk/Tools/msi/msi.py ============================================================================== --- python/trunk/Tools/msi/msi.py (original) +++ python/trunk/Tools/msi/msi.py Sat Apr 4 20:44:44 2009 @@ -1012,6 +1012,7 @@ lib.glob("*.pem") lib.glob("*.pck") lib.add_file("readme.txt", src="README") + lib.add_file("zipdir.zip") if dir=='decimaltestdata': lib.glob("*.decTest") if dir=='output': From python-checkins at python.org Sat Apr 4 20:48:39 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 4 Apr 2009 20:48:39 +0200 (CEST) Subject: [Python-checkins] r71180 - in python/branches/py3k: Tools/msi/msi.py Message-ID: <20090404184839.7F4B11E4019@bag.python.org> Author: martin.v.loewis Date: Sat Apr 4 20:48:39 2009 New Revision: 71180 Log: Merged revisions 71179 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71179 | martin.v.loewis | 2009-04-04 20:44:44 +0200 (Sa, 04 Apr 2009) | 2 lines Issue #5470: Package zipdir.zip. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Tools/msi/msi.py Modified: python/branches/py3k/Tools/msi/msi.py ============================================================================== --- python/branches/py3k/Tools/msi/msi.py (original) +++ python/branches/py3k/Tools/msi/msi.py Sat Apr 4 20:48:39 2009 @@ -1013,6 +1013,7 @@ lib.glob("*.pem") lib.glob("*.pck") lib.add_file("readme.txt", src="README") + lib.add_file("zipdir.zip") if dir=='decimaltestdata': lib.glob("*.decTest") if dir=='output': From python-checkins at python.org Sat Apr 4 20:49:13 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 4 Apr 2009 20:49:13 +0200 (CEST) Subject: [Python-checkins] r71181 - in python/branches/release26-maint: Tools/msi/msi.py Message-ID: <20090404184913.600691E4019@bag.python.org> Author: martin.v.loewis Date: Sat Apr 4 20:49:13 2009 New Revision: 71181 Log: Merged revisions 71179 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71179 | martin.v.loewis | 2009-04-04 20:44:44 +0200 (Sa, 04 Apr 2009) | 2 lines Issue #5470: Package zipdir.zip. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Tools/msi/msi.py Modified: python/branches/release26-maint/Tools/msi/msi.py ============================================================================== --- python/branches/release26-maint/Tools/msi/msi.py (original) +++ python/branches/release26-maint/Tools/msi/msi.py Sat Apr 4 20:49:13 2009 @@ -1011,6 +1011,7 @@ lib.glob("*.pem") lib.glob("*.pck") lib.add_file("readme.txt", src="README") + lib.add_file("zipdir.zip") if dir=='decimaltestdata': lib.glob("*.decTest") if dir=='output': From python-checkins at python.org Sat Apr 4 20:53:09 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 4 Apr 2009 20:53:09 +0200 (CEST) Subject: [Python-checkins] r71182 - in python/branches/release30-maint: Tools/msi/msi.py Message-ID: <20090404185309.ADCA11E4019@bag.python.org> Author: martin.v.loewis Date: Sat Apr 4 20:53:09 2009 New Revision: 71182 Log: Merged revisions 71180 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71180 | martin.v.loewis | 2009-04-04 20:48:39 +0200 (Sa, 04 Apr 2009) | 9 lines Merged revisions 71179 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71179 | martin.v.loewis | 2009-04-04 20:44:44 +0200 (Sa, 04 Apr 2009) | 2 lines Issue #5470: Package zipdir.zip. ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Tools/msi/msi.py Modified: python/branches/release30-maint/Tools/msi/msi.py ============================================================================== --- python/branches/release30-maint/Tools/msi/msi.py (original) +++ python/branches/release30-maint/Tools/msi/msi.py Sat Apr 4 20:53:09 2009 @@ -1013,6 +1013,7 @@ lib.glob("*.pem") lib.glob("*.pck") lib.add_file("readme.txt", src="README") + lib.add_file("zipdir.zip") if dir=='decimaltestdata': lib.glob("*.decTest") if dir=='output': From python-checkins at python.org Sat Apr 4 20:55:10 2009 From: python-checkins at python.org (michael.foord) Date: Sat, 4 Apr 2009 20:55:10 +0200 (CEST) Subject: [Python-checkins] r71183 - in python/branches/py3k/Lib: test/test_unittest.py unittest.py Message-ID: <20090404185510.8210B1E4019@bag.python.org> Author: michael.foord Date: Sat Apr 4 20:55:09 2009 New Revision: 71183 Log: Patch for Py3k with fallback for comparing unsortable sequences in assertSameElements. Removed the expected failure and added another test case to confirm that this patch works for unsortable sequences that are the same (no fail) and different (fail). Issue #2578 Modified: python/branches/py3k/Lib/test/test_unittest.py python/branches/py3k/Lib/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 Sat Apr 4 20:55:09 2009 @@ -2392,8 +2392,6 @@ self.assertRaises(self.failureException, self.assertEqual, a, b, msg='foo') - # The fact that dictionaries are unorderable breaks this test for them. - @unittest.expectedFailure def testEquality(self): self.assertListEqual([], []) self.assertTupleEqual((), ()) @@ -2459,6 +2457,8 @@ self.assertSameElements([{'a': 1}, {'b': 2}], [{'b': 2}, {'a': 1}]) self.assertRaises(self.failureException, self.assertSameElements, [[1]], [[2]]) + self.assertRaises(self.failureException, self.assertSameElements, + [{'a': 1}, {'b': 2}], [{'b': 2}, {'a': 2}]) def testAssertSetEqual(self): set1 = set() Modified: python/branches/py3k/Lib/unittest.py ============================================================================== --- python/branches/py3k/Lib/unittest.py (original) +++ python/branches/py3k/Lib/unittest.py Sat Apr 4 20:55:09 2009 @@ -858,9 +858,13 @@ # not hashable. expected = list(expected_seq) actual = list(actual_seq) - expected.sort() - actual.sort() - missing, unexpected = _SortedListDifference(expected, actual) + try: + expected.sort() + actual.sort() + except TypeError: + missing, unexpected = _UnorderableListDifference(expected, actual) + else: + missing, unexpected = _SortedListDifference(expected, actual) errors = [] if missing: errors.append('Expected, but missing:\n %r' % missing) @@ -985,6 +989,22 @@ break return missing, unexpected +def _UnorderableListDifference(expected, actual): + """Same behavior as _SortedListDifference but + for lists of unorderable items (like dicts). + + As it does a linear search per item (remove) it + has O(n*n) performance.""" + missing = [] + while expected: + item = expected.pop() + try: + actual.remove(item) + except ValueError: + missing.append(item) + + # anything left in actual is unexpected + return missing, actual class TestSuite(object): """A test suite is a composite test consisting of a number of TestCases. From python-checkins at python.org Sat Apr 4 21:35:50 2009 From: python-checkins at python.org (eric.smith) Date: Sat, 4 Apr 2009 21:35:50 +0200 (CEST) Subject: [Python-checkins] r71184 - python/branches/py3k/Objects/stringlib/formatter.h Message-ID: <20090404193550.61EE71E4020@bag.python.org> Author: eric.smith Date: Sat Apr 4 21:35:49 2009 New Revision: 71184 Log: Resolves issue 5690: accidentally skipping code in non-debug build. Modified: python/branches/py3k/Objects/stringlib/formatter.h Modified: python/branches/py3k/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k/Objects/stringlib/formatter.h (original) +++ python/branches/py3k/Objects/stringlib/formatter.h Sat Apr 4 21:35:49 2009 @@ -692,7 +692,7 @@ #endif if (format->type == 'n') #ifndef NDEBUG - r = + r = #endif STRINGLIB_GROUPING_LOCALE(pstart, n_digits, n_digits, spec.n_total+n_grouping_chars-n_leading_chars, @@ -700,10 +700,10 @@ else #ifndef NDEBUG r = +#endif STRINGLIB_GROUPING(pstart, n_digits, n_digits, spec.n_total+n_grouping_chars-n_leading_chars, NULL, 0, "\3", ","); -#endif assert(r); } From python-checkins at python.org Sat Apr 4 21:58:42 2009 From: python-checkins at python.org (alexandre.vassalotti) Date: Sat, 4 Apr 2009 21:58:42 +0200 (CEST) Subject: [Python-checkins] r71185 - in python/branches/py3k: Makefile.pre.in Modules/Setup.dist Modules/_bufferedio.c Modules/_bytesio.c Modules/_fileio.c Modules/_io Modules/_io/_iomodule.c Modules/_io/_iomodule.h Modules/_io/bufferedio.c Modules/_io/bytesio.c Modules/_io/fileio.c Modules/_io/iobase.c Modules/_io/stringio.c Modules/_io/textio.c Modules/_iobase.c Modules/_iomodule.h Modules/_stringio.c Modules/_textio.c Modules/io.c PC/VC6/pythoncore.dsp PC/VS7.1/pythoncore.vcproj PC/VS8.0/pythoncore.vcproj PCbuild/pythoncore.vcproj Message-ID: <20090404195842.A8CF31E4020@bag.python.org> Author: alexandre.vassalotti Date: Sat Apr 4 21:58:40 2009 New Revision: 71185 Log: Issue 5682: Move _io module into its own subdirectory. Reviewed by: Antoine Pitrou Added: python/branches/py3k/Modules/_io/ python/branches/py3k/Modules/_io/_iomodule.c (props changed) - copied unchanged from r71106, /python/branches/py3k/Modules/io.c python/branches/py3k/Modules/_io/_iomodule.h (props changed) - copied unchanged from r71106, /python/branches/py3k/Modules/_iomodule.h python/branches/py3k/Modules/_io/bufferedio.c (props changed) - copied unchanged from r71106, /python/branches/py3k/Modules/_bufferedio.c python/branches/py3k/Modules/_io/bytesio.c (props changed) - copied unchanged from r71106, /python/branches/py3k/Modules/_bytesio.c python/branches/py3k/Modules/_io/fileio.c (props changed) - copied unchanged from r71106, /python/branches/py3k/Modules/_fileio.c python/branches/py3k/Modules/_io/iobase.c (props changed) - copied unchanged from r71106, /python/branches/py3k/Modules/_iobase.c python/branches/py3k/Modules/_io/stringio.c (props changed) - copied unchanged from r71106, /python/branches/py3k/Modules/_stringio.c python/branches/py3k/Modules/_io/textio.c (props changed) - copied unchanged from r71106, /python/branches/py3k/Modules/_textio.c Removed: python/branches/py3k/Modules/_bufferedio.c python/branches/py3k/Modules/_bytesio.c python/branches/py3k/Modules/_fileio.c python/branches/py3k/Modules/_iobase.c python/branches/py3k/Modules/_iomodule.h python/branches/py3k/Modules/_stringio.c python/branches/py3k/Modules/_textio.c python/branches/py3k/Modules/io.c Modified: python/branches/py3k/Makefile.pre.in python/branches/py3k/Modules/Setup.dist python/branches/py3k/PC/VC6/pythoncore.dsp python/branches/py3k/PC/VS7.1/pythoncore.vcproj python/branches/py3k/PC/VS8.0/pythoncore.vcproj python/branches/py3k/PCbuild/pythoncore.vcproj Modified: python/branches/py3k/Makefile.pre.in ============================================================================== --- python/branches/py3k/Makefile.pre.in (original) +++ python/branches/py3k/Makefile.pre.in Sat Apr 4 21:58:40 2009 @@ -193,15 +193,16 @@ # Used of signalmodule.o is not available SIGNAL_OBJS= @SIGNAL_OBJS@ -IO_H= Modules/_iomodule.h +IO_H= Modules/_io/_iomodule.h IO_OBJS= \ - Modules/io.o \ - Modules/_iobase.o \ - Modules/_fileio.o \ - Modules/_bufferedio.o \ - Modules/_textio.o \ - Modules/_bytesio.o + Modules/_io/_iomodule.o \ + Modules/_io/iobase.o \ + Modules/_io/fileio.o \ + Modules/_io/bufferedio.o \ + Modules/_io/textio.o \ + Modules/_io/bytesio.o \ + Modules/_io/stringio.o ########################################################################## # Grammar Modified: python/branches/py3k/Modules/Setup.dist ============================================================================== --- python/branches/py3k/Modules/Setup.dist (original) +++ python/branches/py3k/Modules/Setup.dist Sat Apr 4 21:58:40 2009 @@ -114,7 +114,7 @@ _weakref _weakref.c # weak references # Standard I/O baseline -_io io.c _iobase.c _fileio.c _bytesio.c _bufferedio.c _textio.c _stringio.c +_io -I$(srcdir)/Modules/_io _io/_iomodule.c _io/iobase.c _io/fileio.c _io/bytesio.c _io/bufferedio.c _io/textio.c _io/stringio.c # The zipimport module is always imported at startup. Having it as a # builtin module avoids some bootstrapping problems and reduces overhead. Deleted: python/branches/py3k/Modules/_bufferedio.c ============================================================================== --- python/branches/py3k/Modules/_bufferedio.c Sat Apr 4 21:58:40 2009 +++ (empty file) @@ -1,2139 +0,0 @@ -/* - An implementation of Buffered I/O as defined by PEP 3116 - "New I/O" - - Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter, - BufferedRandom. - - Written by Amaury Forgeot d'Arc and Antoine Pitrou -*/ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#include "structmember.h" -#include "pythread.h" -#include "_iomodule.h" - -/* - * BufferedIOBase class, inherits from IOBase. - */ -PyDoc_STRVAR(BufferedIOBase_doc, - "Base class for buffered IO objects.\n" - "\n" - "The main difference with RawIOBase is that the read() method\n" - "supports omitting the size argument, and does not have a default\n" - "implementation that defers to readinto().\n" - "\n" - "In addition, read(), readinto() and write() may raise\n" - "BlockingIOError if the underlying raw stream is in non-blocking\n" - "mode and not ready; unlike their raw counterparts, they will never\n" - "return None.\n" - "\n" - "A typical implementation should not inherit from a RawIOBase\n" - "implementation, but wrap one.\n" - ); - -static PyObject * -BufferedIOBase_readinto(PyObject *self, PyObject *args) -{ - Py_buffer buf; - Py_ssize_t len; - PyObject *data; - - if (!PyArg_ParseTuple(args, "w*:readinto", &buf)) { - return NULL; - } - - data = PyObject_CallMethod(self, "read", "n", buf.len); - if (data == NULL) - goto error; - - if (!PyBytes_Check(data)) { - Py_DECREF(data); - PyErr_SetString(PyExc_TypeError, "read() should return bytes"); - goto error; - } - - len = Py_SIZE(data); - memcpy(buf.buf, PyBytes_AS_STRING(data), len); - - PyBuffer_Release(&buf); - Py_DECREF(data); - - return PyLong_FromSsize_t(len); - - error: - PyBuffer_Release(&buf); - return NULL; -} - -static PyObject * -BufferedIOBase_unsupported(const char *message) -{ - PyErr_SetString(IO_STATE->unsupported_operation, message); - return NULL; -} - -PyDoc_STRVAR(BufferedIOBase_read_doc, - "Read and return up to n bytes.\n" - "\n" - "If the argument is omitted, None, or negative, reads and\n" - "returns all data until EOF.\n" - "\n" - "If the argument is positive, and the underlying raw stream is\n" - "not 'interactive', multiple raw reads may be issued to satisfy\n" - "the byte count (unless EOF is reached first). But for\n" - "interactive raw streams (as well as sockets and pipes), at most\n" - "one raw read will be issued, and a short result does not imply\n" - "that EOF is imminent.\n" - "\n" - "Returns an empty bytes object on EOF.\n" - "\n" - "Returns None if the underlying raw stream was open in non-blocking\n" - "mode and no data is available at the moment.\n"); - -static PyObject * -BufferedIOBase_read(PyObject *self, PyObject *args) -{ - return BufferedIOBase_unsupported("read"); -} - -PyDoc_STRVAR(BufferedIOBase_read1_doc, - "Read and return up to n bytes, with at most one read() call\n" - "to the underlying raw stream. A short result does not imply\n" - "that EOF is imminent.\n" - "\n" - "Returns an empty bytes object on EOF.\n"); - -static PyObject * -BufferedIOBase_read1(PyObject *self, PyObject *args) -{ - return BufferedIOBase_unsupported("read1"); -} - -PyDoc_STRVAR(BufferedIOBase_write_doc, - "Write the given buffer to the IO stream.\n" - "\n" - "Returns the number of bytes written, which is never less than\n" - "len(b).\n" - "\n" - "Raises BlockingIOError if the buffer is full and the\n" - "underlying raw stream cannot accept more data at the moment.\n"); - -static PyObject * -BufferedIOBase_write(PyObject *self, PyObject *args) -{ - return BufferedIOBase_unsupported("write"); -} - - -static PyMethodDef BufferedIOBase_methods[] = { - {"read", BufferedIOBase_read, METH_VARARGS, BufferedIOBase_read_doc}, - {"read1", BufferedIOBase_read1, METH_VARARGS, BufferedIOBase_read1_doc}, - {"readinto", BufferedIOBase_readinto, METH_VARARGS, NULL}, - {"write", BufferedIOBase_write, METH_VARARGS, BufferedIOBase_write_doc}, - {NULL, NULL} -}; - -PyTypeObject PyBufferedIOBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._BufferedIOBase", /*tp_name*/ - 0, /*tp_basicsize*/ - 0, /*tp_itemsize*/ - 0, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - BufferedIOBase_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - BufferedIOBase_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PyIOBase_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ -}; - - -typedef struct { - PyObject_HEAD - - PyObject *raw; - int ok; /* Initialized? */ - int readable; - int writable; - - /* Absolute position inside the raw stream (-1 if unknown). */ - Py_off_t abs_pos; - - /* A static buffer of size `buffer_size` */ - char *buffer; - /* Current logical position in the buffer. */ - Py_off_t pos; - /* Position of the raw stream in the buffer. */ - Py_off_t raw_pos; - - /* Just after the last buffered byte in the buffer, or -1 if the buffer - isn't ready for reading. */ - Py_off_t read_end; - - /* Just after the last byte actually written */ - Py_off_t write_pos; - /* Just after the last byte waiting to be written, or -1 if the buffer - isn't ready for writing. */ - Py_off_t write_end; - - PyThread_type_lock lock; - - Py_ssize_t buffer_size; - Py_ssize_t buffer_mask; - - PyObject *dict; - PyObject *weakreflist; -} BufferedObject; - -/* - Implementation notes: - - * BufferedReader, BufferedWriter and BufferedRandom try to share most - methods (this is helped by the members `readable` and `writable`, which - are initialized in the respective constructors) - * They also share a single buffer for reading and writing. This enables - interleaved reads and writes without flushing. It also makes the logic - a bit trickier to get right. - * The absolute position of the raw stream is cached, if possible, in the - `abs_pos` member. It must be updated every time an operation is done - on the raw stream. If not sure, it can be reinitialized by calling - _Buffered_raw_tell(), which queries the raw stream (_Buffered_raw_seek() - also does it). To read it, use RAW_TELL(). - * Three helpers, _BufferedReader_raw_read, _BufferedWriter_raw_write and - _BufferedWriter_flush_unlocked do a lot of useful housekeeping. - - NOTE: we should try to maintain block alignment of reads and writes to the - raw stream (according to the buffer size), but for now it is only done - in read() and friends. - - XXX: method naming is a bit messy. -*/ - -/* These macros protect the BufferedObject against concurrent operations. */ - -#define ENTER_BUFFERED(self) \ - Py_BEGIN_ALLOW_THREADS \ - PyThread_acquire_lock(self->lock, 1); \ - Py_END_ALLOW_THREADS - -#define LEAVE_BUFFERED(self) \ - PyThread_release_lock(self->lock); - -#define CHECK_INITIALIZED(self) \ - if (self->ok <= 0) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - return NULL; \ - } - -#define CHECK_INITIALIZED_INT(self) \ - if (self->ok <= 0) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - return -1; \ - } - -#define VALID_READ_BUFFER(self) \ - (self->readable && self->read_end != -1) - -#define VALID_WRITE_BUFFER(self) \ - (self->writable && self->write_end != -1) - -#define ADJUST_POSITION(self, _new_pos) \ - do { \ - self->pos = _new_pos; \ - if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \ - self->read_end = self->pos; \ - } while(0) - -#define READAHEAD(self) \ - ((self->readable && VALID_READ_BUFFER(self)) \ - ? (self->read_end - self->pos) : 0) - -#define RAW_OFFSET(self) \ - (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \ - && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0) - -#define RAW_TELL(self) \ - (self->abs_pos != -1 ? self->abs_pos : _Buffered_raw_tell(self)) - -#define MINUS_LAST_BLOCK(self, size) \ - (self->buffer_mask ? \ - (size & ~self->buffer_mask) : \ - (self->buffer_size * (size / self->buffer_size))) - - -static void -BufferedObject_dealloc(BufferedObject *self) -{ - if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0) - return; - _PyObject_GC_UNTRACK(self); - self->ok = 0; - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *)self); - Py_CLEAR(self->raw); - if (self->buffer) { - PyMem_Free(self->buffer); - self->buffer = NULL; - } - if (self->lock) { - PyThread_free_lock(self->lock); - self->lock = NULL; - } - Py_CLEAR(self->dict); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static int -Buffered_traverse(BufferedObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->raw); - Py_VISIT(self->dict); - return 0; -} - -static int -Buffered_clear(BufferedObject *self) -{ - if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0) - return -1; - self->ok = 0; - Py_CLEAR(self->raw); - Py_CLEAR(self->dict); - return 0; -} - -/* - * _BufferedIOMixin methods - * This is not a class, just a collection of methods that will be reused - * by BufferedReader and BufferedWriter - */ - -/* Flush and close */ - -static PyObject * -BufferedIOMixin_flush(BufferedObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self) - return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL); -} - -static int -BufferedIOMixin_closed(BufferedObject *self) -{ - int closed; - PyObject *res; - CHECK_INITIALIZED_INT(self) - res = PyObject_GetAttr(self->raw, _PyIO_str_closed); - if (res == NULL) - return -1; - closed = PyObject_IsTrue(res); - Py_DECREF(res); - return closed; -} - -static PyObject * -BufferedIOMixin_closed_get(BufferedObject *self, void *context) -{ - CHECK_INITIALIZED(self) - return PyObject_GetAttr(self->raw, _PyIO_str_closed); -} - -static PyObject * -BufferedIOMixin_close(BufferedObject *self, PyObject *args) -{ - PyObject *res = NULL; - int r; - - CHECK_INITIALIZED(self) - ENTER_BUFFERED(self) - - r = BufferedIOMixin_closed(self); - if (r < 0) - goto end; - if (r > 0) { - res = Py_None; - Py_INCREF(res); - goto end; - } - /* 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 (res == NULL) { - /* If flush() fails, just give up */ - if (PyErr_ExceptionMatches(PyExc_IOError)) - PyErr_Clear(); - else - goto end; - } - Py_XDECREF(res); - - res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL); - -end: - LEAVE_BUFFERED(self) - return res; -} - -/* Inquiries */ - -static PyObject * -BufferedIOMixin_seekable(BufferedObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self) - return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL); -} - -static PyObject * -BufferedIOMixin_readable(BufferedObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self) - return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL); -} - -static PyObject * -BufferedIOMixin_writable(BufferedObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self) - return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL); -} - -static PyObject * -BufferedIOMixin_name_get(BufferedObject *self, void *context) -{ - CHECK_INITIALIZED(self) - return PyObject_GetAttrString(self->raw, "name"); -} - -static PyObject * -BufferedIOMixin_mode_get(BufferedObject *self, void *context) -{ - CHECK_INITIALIZED(self) - return PyObject_GetAttrString(self->raw, "mode"); -} - -/* Lower-level APIs */ - -static PyObject * -BufferedIOMixin_fileno(BufferedObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self) - return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL); -} - -static PyObject * -BufferedIOMixin_isatty(BufferedObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self) - return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL); -} - - -/* Forward decls */ -static PyObject * -_BufferedWriter_flush_unlocked(BufferedObject *, int); -static Py_ssize_t -_BufferedReader_fill_buffer(BufferedObject *self); -static void -_BufferedReader_reset_buf(BufferedObject *self); -static void -_BufferedWriter_reset_buf(BufferedObject *self); -static PyObject * -_BufferedReader_peek_unlocked(BufferedObject *self, Py_ssize_t); -static PyObject * -_BufferedReader_read_unlocked(BufferedObject *self, Py_ssize_t); - - -/* - * Helpers - */ - -/* Returns the address of the `written` member if a BlockingIOError was - raised, NULL otherwise. The error is always re-raised. */ -static Py_ssize_t * -_Buffered_check_blocking_error(void) -{ - PyObject *t, *v, *tb; - PyBlockingIOErrorObject *err; - - PyErr_Fetch(&t, &v, &tb); - if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) { - PyErr_Restore(t, v, tb); - return NULL; - } - err = (PyBlockingIOErrorObject *) v; - /* TODO: sanity check (err->written >= 0) */ - PyErr_Restore(t, v, tb); - return &err->written; -} - -static Py_off_t -_Buffered_raw_tell(BufferedObject *self) -{ - PyObject *res; - Py_off_t n; - res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL); - if (res == NULL) - return -1; - n = PyNumber_AsOff_t(res, PyExc_ValueError); - Py_DECREF(res); - if (n < 0) { - if (!PyErr_Occurred()) - PyErr_Format(PyExc_IOError, - "Raw stream returned invalid position %zd", n); - return -1; - } - self->abs_pos = n; - return n; -} - -static Py_off_t -_Buffered_raw_seek(BufferedObject *self, Py_off_t target, int whence) -{ - PyObject *res, *posobj, *whenceobj; - Py_off_t n; - - posobj = PyLong_FromOff_t(target); - if (posobj == NULL) - return -1; - whenceobj = PyLong_FromLong(whence); - if (whenceobj == NULL) { - Py_DECREF(posobj); - return -1; - } - res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek, - posobj, whenceobj, NULL); - Py_DECREF(posobj); - Py_DECREF(whenceobj); - if (res == NULL) - return -1; - n = PyNumber_AsOff_t(res, PyExc_ValueError); - Py_DECREF(res); - if (n < 0) { - if (!PyErr_Occurred()) - PyErr_Format(PyExc_IOError, - "Raw stream returned invalid position %zd", n); - return -1; - } - self->abs_pos = n; - return n; -} - -static int -_Buffered_init(BufferedObject *self) -{ - Py_ssize_t n; - if (self->buffer_size <= 0) { - PyErr_SetString(PyExc_ValueError, - "buffer size must be strictly positive"); - return -1; - } - if (self->buffer) - PyMem_Free(self->buffer); - self->buffer = PyMem_Malloc(self->buffer_size); - if (self->buffer == NULL) { - PyErr_NoMemory(); - return -1; - } - self->lock = PyThread_allocate_lock(); - if (self->lock == NULL) { - PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock"); - return -1; - } - /* Find out whether buffer_size is a power of 2 */ - /* XXX is this optimization useful? */ - for (n = self->buffer_size - 1; n & 1; n >>= 1) - ; - if (n == 0) - self->buffer_mask = self->buffer_size - 1; - else - self->buffer_mask = 0; - if (_Buffered_raw_tell(self) == -1) - PyErr_Clear(); - return 0; -} - -/* - * Shared methods and wrappers - */ - -static PyObject * -Buffered_flush(BufferedObject *self, PyObject *args) -{ - PyObject *res; - - CHECK_INITIALIZED(self) - if (BufferedIOMixin_closed(self)) { - PyErr_SetString(PyExc_ValueError, "flush of closed file"); - return NULL; - } - - ENTER_BUFFERED(self) - res = _BufferedWriter_flush_unlocked(self, 0); - if (res != NULL && self->readable) { - /* Rewind the raw stream so that its position corresponds to - the current logical position. */ - Py_off_t n; - n = _Buffered_raw_seek(self, -RAW_OFFSET(self), 1); - if (n == -1) - Py_CLEAR(res); - _BufferedReader_reset_buf(self); - } - LEAVE_BUFFERED(self) - - return res; -} - -static PyObject * -Buffered_peek(BufferedObject *self, PyObject *args) -{ - Py_ssize_t n = 0; - PyObject *res = NULL; - - CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "|n:peek", &n)) { - return NULL; - } - - ENTER_BUFFERED(self) - - if (self->writable) { - res = _BufferedWriter_flush_unlocked(self, 1); - if (res == NULL) - goto end; - Py_CLEAR(res); - } - res = _BufferedReader_peek_unlocked(self, n); - -end: - LEAVE_BUFFERED(self) - return res; -} - -static PyObject * -Buffered_read(BufferedObject *self, PyObject *args) -{ - Py_ssize_t n = -1; - PyObject *res; - - CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "|n:read", &n)) { - return NULL; - } - if (n < -1) { - PyErr_SetString(PyExc_ValueError, - "read length must be positive or -1"); - return NULL; - } - - if (BufferedIOMixin_closed(self)) { - PyErr_SetString(PyExc_ValueError, "read of closed file"); - return NULL; - } - - ENTER_BUFFERED(self) - res = _BufferedReader_read_unlocked(self, n); - LEAVE_BUFFERED(self) - - return res; -} - -static PyObject * -Buffered_read1(BufferedObject *self, PyObject *args) -{ - Py_ssize_t n, have, r; - PyObject *res = NULL; - - CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "n:read1", &n)) { - return NULL; - } - - if (n < 0) { - PyErr_SetString(PyExc_ValueError, - "read length must be positive"); - return NULL; - } - if (n == 0) - return PyBytes_FromStringAndSize(NULL, 0); - - ENTER_BUFFERED(self) - - if (self->writable) { - res = _BufferedWriter_flush_unlocked(self, 1); - if (res == NULL) - goto end; - Py_CLEAR(res); - } - - /* Return up to n bytes. If at least one byte is buffered, we - only return buffered bytes. Otherwise, we do one raw read. */ - - /* XXX: this mimicks the io.py implementation but is probably wrong. - If we need to read from the raw stream, then we could actually read - all `n` bytes asked by the caller (and possibly more, so as to fill - our buffer for the next reads). */ - - have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); - if (have > 0) { - if (n > have) - n = have; - res = PyBytes_FromStringAndSize(self->buffer + self->pos, n); - if (res == NULL) - goto end; - self->pos += n; - goto end; - } - - /* Fill the buffer from the raw stream, and copy it to the result. */ - _BufferedReader_reset_buf(self); - r = _BufferedReader_fill_buffer(self); - if (r == -1) - goto end; - if (r == -2) - r = 0; - if (n > r) - n = r; - res = PyBytes_FromStringAndSize(self->buffer, n); - if (res == NULL) - goto end; - self->pos = n; - -end: - LEAVE_BUFFERED(self) - return res; -} - -static PyObject * -Buffered_readinto(BufferedObject *self, PyObject *args) -{ - PyObject *res = NULL; - - CHECK_INITIALIZED(self) - - /* TODO: use raw.readinto() instead! */ - if (self->writable) { - ENTER_BUFFERED(self) - res = _BufferedWriter_flush_unlocked(self, 0); - LEAVE_BUFFERED(self) - if (res == NULL) - goto end; - Py_DECREF(res); - } - res = BufferedIOBase_readinto((PyObject *)self, args); - -end: - return res; -} - -static PyObject * -_Buffered_readline(BufferedObject *self, Py_ssize_t limit) -{ - PyObject *res = NULL; - PyObject *chunks = NULL; - Py_ssize_t n, written = 0; - const char *start, *s, *end; - - if (BufferedIOMixin_closed(self)) { - PyErr_SetString(PyExc_ValueError, "readline of closed file"); - return NULL; - } - - ENTER_BUFFERED(self) - - /* First, try to find a line in the buffer */ - n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); - if (limit >= 0 && n > limit) - n = limit; - start = self->buffer + self->pos; - end = start + n; - s = start; - while (s < end) { - if (*s++ == '\n') { - res = PyBytes_FromStringAndSize(start, s - start); - if (res != NULL) - self->pos += s - start; - goto end; - } - } - if (n == limit) { - res = PyBytes_FromStringAndSize(start, n); - if (res != NULL) - self->pos += n; - goto end; - } - - /* Now we try to get some more from the raw stream */ - if (self->writable) { - res = _BufferedWriter_flush_unlocked(self, 1); - if (res == NULL) - goto end; - Py_CLEAR(res); - } - chunks = PyList_New(0); - if (chunks == NULL) - goto end; - if (n > 0) { - res = PyBytes_FromStringAndSize(start, n); - if (res == NULL) - goto end; - if (PyList_Append(chunks, res) < 0) { - Py_CLEAR(res); - goto end; - } - Py_CLEAR(res); - written += n; - if (limit >= 0) - limit -= n; - } - - for (;;) { - _BufferedReader_reset_buf(self); - n = _BufferedReader_fill_buffer(self); - if (n == -1) - goto end; - if (n <= 0) - break; - if (limit >= 0 && n > limit) - n = limit; - start = self->buffer; - end = start + n; - s = start; - while (s < end) { - if (*s++ == '\n') { - res = PyBytes_FromStringAndSize(start, s - start); - if (res == NULL) - goto end; - self->pos = s - start; - goto found; - } - } - res = PyBytes_FromStringAndSize(start, n); - if (res == NULL) - goto end; - if (n == limit) { - self->pos = n; - break; - } - if (PyList_Append(chunks, res) < 0) { - Py_CLEAR(res); - goto end; - } - Py_CLEAR(res); - written += n; - if (limit >= 0) - limit -= n; - } -found: - if (res != NULL && PyList_Append(chunks, res) < 0) { - Py_CLEAR(res); - goto end; - } - Py_CLEAR(res); - res = _PyBytes_Join(_PyIO_empty_bytes, chunks); - -end: - LEAVE_BUFFERED(self) - Py_XDECREF(chunks); - return res; -} - -static PyObject * -Buffered_readline(BufferedObject *self, PyObject *args) -{ - Py_ssize_t limit = -1; - - CHECK_INITIALIZED(self) - - if (!PyArg_ParseTuple(args, "|n:readline", &limit)) { - return NULL; - } - return _Buffered_readline(self, limit); -} - - -static PyObject * -Buffered_tell(BufferedObject *self, PyObject *args) -{ - Py_off_t pos; - - CHECK_INITIALIZED(self) - pos = _Buffered_raw_tell(self); - if (pos == -1) - return NULL; - pos -= RAW_OFFSET(self); - /* TODO: sanity check (pos >= 0) */ - return PyLong_FromOff_t(pos); -} - -static PyObject * -Buffered_seek(BufferedObject *self, PyObject *args) -{ - Py_off_t target, n; - int whence = 0; - PyObject *targetobj, *res = NULL; - - CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) { - return NULL; - } - - if (whence < 0 || whence > 2) { - PyErr_Format(PyExc_ValueError, - "whence must be between 0 and 2, not %d", whence); - return NULL; - } - target = PyNumber_AsOff_t(targetobj, PyExc_ValueError); - if (target == -1 && PyErr_Occurred()) - return NULL; - - ENTER_BUFFERED(self) - - if (whence != 2 && self->readable) { - Py_off_t current, avail; - /* Check if seeking leaves us inside the current buffer, - so as to return quickly if possible. - Don't know how to do that when whence == 2, though. */ - current = RAW_TELL(self); - avail = READAHEAD(self); - if (avail > 0) { - Py_off_t offset; - if (whence == 0) - offset = target - (current - RAW_OFFSET(self)); - else - offset = target; - if (offset >= -self->pos && offset <= avail) { - self->pos += offset; - res = PyLong_FromOff_t(current - avail + offset); - goto end; - } - } - } - - /* Fallback: invoke raw seek() method and clear buffer */ - if (self->writable) { - res = _BufferedWriter_flush_unlocked(self, 0); - if (res == NULL) - goto end; - Py_CLEAR(res); - _BufferedWriter_reset_buf(self); - } - - /* TODO: align on block boundary and read buffer if needed? */ - if (whence == 1) - target -= RAW_OFFSET(self); - n = _Buffered_raw_seek(self, target, whence); - if (n == -1) - goto end; - self->raw_pos = -1; - res = PyLong_FromOff_t(n); - if (res != NULL && self->readable) - _BufferedReader_reset_buf(self); - -end: - LEAVE_BUFFERED(self) - return res; -} - -static PyObject * -Buffered_truncate(BufferedObject *self, PyObject *args) -{ - PyObject *pos = Py_None; - PyObject *res = NULL; - - CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) { - return NULL; - } - - ENTER_BUFFERED(self) - - if (self->writable) { - res = _BufferedWriter_flush_unlocked(self, 0); - if (res == NULL) - goto end; - Py_CLEAR(res); - } - if (self->readable) { - if (pos == Py_None) { - /* Rewind the raw stream so that its position corresponds to - the current logical position. */ - if (_Buffered_raw_seek(self, -RAW_OFFSET(self), 1) == -1) - goto end; - } - _BufferedReader_reset_buf(self); - } - res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL); - if (res == NULL) - goto end; - /* Reset cached position */ - if (_Buffered_raw_tell(self) == -1) - PyErr_Clear(); - -end: - LEAVE_BUFFERED(self) - return res; -} - -static PyObject * -Buffered_iternext(BufferedObject *self) -{ - PyObject *line; - PyTypeObject *tp; - - CHECK_INITIALIZED(self); - - tp = Py_TYPE(self); - if (tp == &PyBufferedReader_Type || - tp == &PyBufferedRandom_Type) { - /* Skip method call overhead for speed */ - line = _Buffered_readline(self, -1); - } - else { - line = PyObject_CallMethodObjArgs((PyObject *)self, - _PyIO_str_readline, NULL); - if (line && !PyBytes_Check(line)) { - PyErr_Format(PyExc_IOError, - "readline() should have returned a bytes object, " - "not '%.200s'", Py_TYPE(line)->tp_name); - Py_DECREF(line); - return NULL; - } - } - - if (line == NULL) - return NULL; - - if (PyBytes_GET_SIZE(line) == 0) { - /* Reached EOF or would have blocked */ - Py_DECREF(line); - return NULL; - } - - return line; -} - -/* - * class BufferedReader - */ - -PyDoc_STRVAR(BufferedReader_doc, - "Create a new buffered reader using the given readable raw IO object."); - -static void _BufferedReader_reset_buf(BufferedObject *self) -{ - self->read_end = -1; -} - -static int -BufferedReader_init(BufferedObject *self, PyObject *args, PyObject *kwds) -{ - char *kwlist[] = {"raw", "buffer_size", NULL}; - Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; - PyObject *raw; - - self->ok = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist, - &raw, &buffer_size)) { - return -1; - } - - if (_PyIOBase_checkReadable(raw, Py_True) == NULL) - return -1; - - Py_CLEAR(self->raw); - Py_INCREF(raw); - self->raw = raw; - self->buffer_size = buffer_size; - self->readable = 1; - self->writable = 0; - - if (_Buffered_init(self) < 0) - return -1; - _BufferedReader_reset_buf(self); - - self->ok = 1; - return 0; -} - -static Py_ssize_t -_BufferedReader_raw_read(BufferedObject *self, char *start, Py_ssize_t len) -{ - Py_buffer buf; - PyObject *memobj, *res; - Py_ssize_t n; - /* NOTE: the buffer needn't be released as its object is NULL. */ - if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1) - return -1; - memobj = PyMemoryView_FromBuffer(&buf); - if (memobj == NULL) - return -1; - res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL); - Py_DECREF(memobj); - if (res == NULL) - return -1; - if (res == Py_None) { - /* Non-blocking stream would have blocked. Special return code! */ - Py_DECREF(res); - return -2; - } - n = PyNumber_AsSsize_t(res, PyExc_ValueError); - Py_DECREF(res); - if (n < 0 || n > len) { - PyErr_Format(PyExc_IOError, - "raw readinto() returned invalid length %zd " - "(should have been between 0 and %zd)", n, len); - return -1; - } - if (n > 0 && self->abs_pos != -1) - self->abs_pos += n; - return n; -} - -static Py_ssize_t -_BufferedReader_fill_buffer(BufferedObject *self) -{ - Py_ssize_t start, len, n; - if (VALID_READ_BUFFER(self)) - start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t); - else - start = 0; - len = self->buffer_size - start; - n = _BufferedReader_raw_read(self, self->buffer + start, len); - if (n <= 0) - return n; - self->read_end = start + n; - self->raw_pos = start + n; - return n; -} - -static PyObject * -_BufferedReader_read_unlocked(BufferedObject *self, Py_ssize_t n) -{ - PyObject *data, *res = NULL; - Py_ssize_t current_size, remaining, written; - char *out; - - /* Special case for when the number of bytes to read is unspecified. */ - if (n == -1) { - PyObject *chunks = PyList_New(0); - if (chunks == NULL) - return NULL; - - /* First copy what we have in the current buffer. */ - current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); - data = NULL; - if (current_size) { - data = PyBytes_FromStringAndSize( - self->buffer + self->pos, current_size); - if (data == NULL) { - Py_DECREF(chunks); - return NULL; - } - } - _BufferedReader_reset_buf(self); - /* We're going past the buffer's bounds, flush it */ - if (self->writable) { - res = _BufferedWriter_flush_unlocked(self, 1); - if (res == NULL) { - Py_DECREF(chunks); - return NULL; - } - Py_CLEAR(res); - } - while (1) { - if (data) { - if (PyList_Append(chunks, data) < 0) { - Py_DECREF(data); - Py_DECREF(chunks); - return NULL; - } - Py_DECREF(data); - } - - /* Read until EOF or until read() would block. */ - data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL); - if (data == NULL) { - Py_DECREF(chunks); - return NULL; - } - if (data != Py_None && !PyBytes_Check(data)) { - Py_DECREF(data); - Py_DECREF(chunks); - PyErr_SetString(PyExc_TypeError, "read() should return bytes"); - return NULL; - } - if (data == Py_None || PyBytes_GET_SIZE(data) == 0) { - if (current_size == 0) { - Py_DECREF(chunks); - return data; - } - else { - res = _PyBytes_Join(_PyIO_empty_bytes, chunks); - Py_DECREF(data); - Py_DECREF(chunks); - return res; - } - } - current_size += PyBytes_GET_SIZE(data); - if (self->abs_pos != -1) - self->abs_pos += PyBytes_GET_SIZE(data); - } - } - - /* The number of bytes to read is specified, return at most n bytes. */ - current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); - if (n <= current_size) { - /* Fast path: the data to read is fully buffered. */ - res = PyBytes_FromStringAndSize(self->buffer + self->pos, n); - if (res == NULL) - goto error; - self->pos += n; - return res; - } - - /* Slow path: read from the stream until enough bytes are read, - * or until an EOF occurs or until read() would block. - */ - res = PyBytes_FromStringAndSize(NULL, n); - if (res == NULL) - goto error; - out = PyBytes_AS_STRING(res); - remaining = n; - written = 0; - if (current_size > 0) { - memcpy(out, self->buffer + self->pos, current_size); - remaining -= current_size; - written += current_size; - } - _BufferedReader_reset_buf(self); - while (remaining > 0) { - /* We want to read a whole block at the end into buffer. - If we had readv() we could do this in one pass. */ - Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining); - if (r == 0) - break; - r = _BufferedReader_raw_read(self, out + written, r); - if (r == -1) - goto error; - if (r == 0 || r == -2) { - /* EOF occurred or read() would block. */ - if (r == 0 || written > 0) { - if (_PyBytes_Resize(&res, written)) - goto error; - return res; - } - Py_DECREF(res); - Py_INCREF(Py_None); - return Py_None; - } - remaining -= r; - written += r; - } - assert(remaining <= self->buffer_size); - self->pos = 0; - self->raw_pos = 0; - self->read_end = 0; - while (self->read_end < self->buffer_size) { - Py_ssize_t r = _BufferedReader_fill_buffer(self); - if (r == -1) - goto error; - if (r == 0 || r == -2) { - /* EOF occurred or read() would block. */ - if (r == 0 || written > 0) { - if (_PyBytes_Resize(&res, written)) - goto error; - return res; - } - Py_DECREF(res); - Py_INCREF(Py_None); - return Py_None; - } - if (remaining > r) { - memcpy(out + written, self->buffer + self->pos, r); - written += r; - self->pos += r; - remaining -= r; - } - else if (remaining > 0) { - memcpy(out + written, self->buffer + self->pos, remaining); - written += remaining; - self->pos += remaining; - remaining = 0; - } - if (remaining == 0) - break; - } - - return res; - -error: - Py_XDECREF(res); - return NULL; -} - -static PyObject * -_BufferedReader_peek_unlocked(BufferedObject *self, Py_ssize_t n) -{ - Py_ssize_t have, r; - - have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); - /* Constraints: - 1. we don't want to advance the file position. - 2. we don't want to lose block alignment, so we can't shift the buffer - to make some place. - Therefore, we either return `have` bytes (if > 0), or a full buffer. - */ - if (have > 0) { - return PyBytes_FromStringAndSize(self->buffer + self->pos, have); - } - - /* Fill the buffer from the raw stream, and copy it to the result. */ - _BufferedReader_reset_buf(self); - r = _BufferedReader_fill_buffer(self); - if (r == -1) - return NULL; - if (r == -2) - r = 0; - self->pos = 0; - return PyBytes_FromStringAndSize(self->buffer, r); -} - -static PyMethodDef BufferedReader_methods[] = { - /* BufferedIOMixin methods */ - {"flush", (PyCFunction)BufferedIOMixin_flush, METH_NOARGS}, - {"close", (PyCFunction)BufferedIOMixin_close, METH_NOARGS}, - {"seekable", (PyCFunction)BufferedIOMixin_seekable, METH_NOARGS}, - {"readable", (PyCFunction)BufferedIOMixin_readable, METH_NOARGS}, - {"writable", (PyCFunction)BufferedIOMixin_writable, METH_NOARGS}, - {"fileno", (PyCFunction)BufferedIOMixin_fileno, METH_NOARGS}, - {"isatty", (PyCFunction)BufferedIOMixin_isatty, METH_NOARGS}, - - {"read", (PyCFunction)Buffered_read, METH_VARARGS}, - {"peek", (PyCFunction)Buffered_peek, METH_VARARGS}, - {"read1", (PyCFunction)Buffered_read1, METH_VARARGS}, - {"readline", (PyCFunction)Buffered_readline, METH_VARARGS}, - {"seek", (PyCFunction)Buffered_seek, METH_VARARGS}, - {"tell", (PyCFunction)Buffered_tell, METH_NOARGS}, - {"truncate", (PyCFunction)Buffered_truncate, METH_VARARGS}, - {NULL, NULL} -}; - -static PyMemberDef BufferedReader_members[] = { - {"raw", T_OBJECT, offsetof(BufferedObject, raw), 0}, - {NULL} -}; - -static PyGetSetDef BufferedReader_getset[] = { - {"closed", (getter)BufferedIOMixin_closed_get, NULL, NULL}, - {"name", (getter)BufferedIOMixin_name_get, NULL, NULL}, - {"mode", (getter)BufferedIOMixin_mode_get, NULL, NULL}, - {0} -}; - - -PyTypeObject PyBufferedReader_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.BufferedReader", /*tp_name*/ - sizeof(BufferedObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)BufferedObject_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - BufferedReader_doc, /* tp_doc */ - (traverseproc)Buffered_traverse, /* tp_traverse */ - (inquiry)Buffered_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(BufferedObject, weakreflist), /*tp_weaklistoffset*/ - 0, /* tp_iter */ - (iternextfunc)Buffered_iternext, /* tp_iternext */ - BufferedReader_methods, /* tp_methods */ - BufferedReader_members, /* tp_members */ - BufferedReader_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(BufferedObject, dict), /* tp_dictoffset */ - (initproc)BufferedReader_init, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; - - - -static int -complain_about_max_buffer_size(void) -{ - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "max_buffer_size is deprecated", 1) < 0) - return 0; - return 1; -} - -/* - * class BufferedWriter - */ -PyDoc_STRVAR(BufferedWriter_doc, - "A buffer for a writeable sequential RawIO object.\n" - "\n" - "The constructor creates a BufferedWriter for the given writeable raw\n" - "stream. If the buffer_size is not given, it defaults to\n" - "DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n" - ); - -static void -_BufferedWriter_reset_buf(BufferedObject *self) -{ - self->write_pos = 0; - self->write_end = -1; -} - -static int -BufferedWriter_init(BufferedObject *self, PyObject *args, PyObject *kwds) -{ - /* TODO: properly deprecate max_buffer_size */ - char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL}; - Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; - Py_ssize_t max_buffer_size = -234; - PyObject *raw; - - self->ok = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedReader", kwlist, - &raw, &buffer_size, &max_buffer_size)) { - return -1; - } - - if (max_buffer_size != -234 && !complain_about_max_buffer_size()) - return -1; - - if (_PyIOBase_checkWritable(raw, Py_True) == NULL) - return -1; - - Py_CLEAR(self->raw); - Py_INCREF(raw); - self->raw = raw; - self->readable = 0; - self->writable = 1; - - self->buffer_size = buffer_size; - if (_Buffered_init(self) < 0) - return -1; - _BufferedWriter_reset_buf(self); - self->pos = 0; - - self->ok = 1; - return 0; -} - -static Py_ssize_t -_BufferedWriter_raw_write(BufferedObject *self, char *start, Py_ssize_t len) -{ - Py_buffer buf; - PyObject *memobj, *res; - Py_ssize_t n; - /* NOTE: the buffer needn't be released as its object is NULL. */ - if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1) - return -1; - memobj = PyMemoryView_FromBuffer(&buf); - if (memobj == NULL) - return -1; - res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL); - Py_DECREF(memobj); - if (res == NULL) - return -1; - n = PyNumber_AsSsize_t(res, PyExc_ValueError); - Py_DECREF(res); - if (n < 0 || n > len) { - PyErr_Format(PyExc_IOError, - "raw write() returned invalid length %zd " - "(should have been between 0 and %zd)", n, len); - return -1; - } - if (n > 0 && self->abs_pos != -1) - self->abs_pos += n; - return n; -} - -/* `restore_pos` is 1 if we need to restore the raw stream position at - the end, 0 otherwise. */ -static PyObject * -_BufferedWriter_flush_unlocked(BufferedObject *self, int restore_pos) -{ - Py_ssize_t written = 0; - Py_off_t n, rewind; - - if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end) - goto end; - /* First, rewind */ - rewind = RAW_OFFSET(self) + (self->pos - self->write_pos); - if (rewind != 0) { - n = _Buffered_raw_seek(self, -rewind, 1); - if (n < 0) { - goto error; - } - self->raw_pos -= rewind; - } - while (self->write_pos < self->write_end) { - n = _BufferedWriter_raw_write(self, - self->buffer + self->write_pos, - Py_SAFE_DOWNCAST(self->write_end - self->write_pos, - Py_off_t, Py_ssize_t)); - if (n == -1) { - Py_ssize_t *w = _Buffered_check_blocking_error(); - if (w == NULL) - goto error; - self->write_pos += *w; - self->raw_pos = self->write_pos; - written += *w; - *w = written; - /* Already re-raised */ - goto error; - } - self->write_pos += n; - self->raw_pos = self->write_pos; - written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t); - } - - if (restore_pos) { - Py_off_t forward = rewind - written; - if (forward != 0) { - n = _Buffered_raw_seek(self, forward, 1); - if (n < 0) { - goto error; - } - self->raw_pos += forward; - } - } - _BufferedWriter_reset_buf(self); - -end: - Py_RETURN_NONE; - -error: - return NULL; -} - -static PyObject * -BufferedWriter_write(BufferedObject *self, PyObject *args) -{ - PyObject *res = NULL; - Py_buffer buf; - Py_ssize_t written, avail, remaining, n; - - CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "y*:write", &buf)) { - return NULL; - } - - if (BufferedIOMixin_closed(self)) { - PyErr_SetString(PyExc_ValueError, "write to closed file"); - PyBuffer_Release(&buf); - return NULL; - } - - ENTER_BUFFERED(self) - - /* Fast path: the data to write can be fully buffered. */ - if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) { - self->pos = 0; - self->raw_pos = 0; - } - avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t); - if (buf.len <= avail) { - memcpy(self->buffer + self->pos, buf.buf, buf.len); - if (!VALID_WRITE_BUFFER(self)) { - self->write_pos = self->pos; - } - ADJUST_POSITION(self, self->pos + buf.len); - if (self->pos > self->write_end) - self->write_end = self->pos; - written = buf.len; - goto end; - } - - /* First write the current buffer */ - res = _BufferedWriter_flush_unlocked(self, 0); - if (res == NULL) { - Py_ssize_t *w = _Buffered_check_blocking_error(); - if (w == NULL) - goto error; - if (self->readable) - _BufferedReader_reset_buf(self); - /* Make some place by shifting the buffer. */ - assert(VALID_WRITE_BUFFER(self)); - memmove(self->buffer, self->buffer + self->write_pos, - Py_SAFE_DOWNCAST(self->write_end - self->write_pos, - Py_off_t, Py_ssize_t)); - self->write_end -= self->write_pos; - self->raw_pos -= self->write_pos; - self->pos -= self->write_pos; - self->write_pos = 0; - avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end, - Py_off_t, Py_ssize_t); - if (buf.len <= avail) { - /* Everything can be buffered */ - PyErr_Clear(); - memcpy(self->buffer + self->write_end, buf.buf, buf.len); - self->write_end += buf.len; - written = buf.len; - goto end; - } - /* Buffer as much as possible. */ - memcpy(self->buffer + self->write_end, buf.buf, avail); - self->write_end += avail; - /* Already re-raised */ - *w = avail; - goto error; - } - Py_CLEAR(res); - - /* Then write buf itself. At this point the buffer has been emptied. */ - remaining = buf.len; - written = 0; - while (remaining > self->buffer_size) { - n = _BufferedWriter_raw_write( - self, (char *) buf.buf + written, buf.len - written); - if (n == -1) { - Py_ssize_t *w = _Buffered_check_blocking_error(); - if (w == NULL) - goto error; - written += *w; - remaining -= *w; - if (remaining > self->buffer_size) { - /* Can't buffer everything, still buffer as much as possible */ - memcpy(self->buffer, - (char *) buf.buf + written, self->buffer_size); - self->raw_pos = 0; - ADJUST_POSITION(self, self->buffer_size); - self->write_end = self->buffer_size; - *w = written + self->buffer_size; - /* Already re-raised */ - goto error; - } - PyErr_Clear(); - break; - } - written += n; - remaining -= n; - } - if (self->readable) - _BufferedReader_reset_buf(self); - if (remaining > 0) { - memcpy(self->buffer, (char *) buf.buf + written, remaining); - written += remaining; - } - self->write_pos = 0; - /* TODO: sanity check (remaining >= 0) */ - self->write_end = remaining; - ADJUST_POSITION(self, remaining); - self->raw_pos = 0; - -end: - res = PyLong_FromSsize_t(written); - -error: - LEAVE_BUFFERED(self) - PyBuffer_Release(&buf); - return res; -} - -static PyMethodDef BufferedWriter_methods[] = { - /* BufferedIOMixin methods */ - {"close", (PyCFunction)BufferedIOMixin_close, METH_NOARGS}, - {"seekable", (PyCFunction)BufferedIOMixin_seekable, METH_NOARGS}, - {"readable", (PyCFunction)BufferedIOMixin_readable, METH_NOARGS}, - {"writable", (PyCFunction)BufferedIOMixin_writable, METH_NOARGS}, - {"fileno", (PyCFunction)BufferedIOMixin_fileno, METH_NOARGS}, - {"isatty", (PyCFunction)BufferedIOMixin_isatty, METH_NOARGS}, - - {"write", (PyCFunction)BufferedWriter_write, METH_VARARGS}, - {"truncate", (PyCFunction)Buffered_truncate, METH_VARARGS}, - {"flush", (PyCFunction)Buffered_flush, METH_NOARGS}, - {"seek", (PyCFunction)Buffered_seek, METH_VARARGS}, - {"tell", (PyCFunction)Buffered_tell, METH_NOARGS}, - {NULL, NULL} -}; - -static PyMemberDef BufferedWriter_members[] = { - {"raw", T_OBJECT, offsetof(BufferedObject, raw), 0}, - {NULL} -}; - -static PyGetSetDef BufferedWriter_getset[] = { - {"closed", (getter)BufferedIOMixin_closed_get, NULL, NULL}, - {"name", (getter)BufferedIOMixin_name_get, NULL, NULL}, - {"mode", (getter)BufferedIOMixin_mode_get, NULL, NULL}, - {0} -}; - - -PyTypeObject PyBufferedWriter_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.BufferedWriter", /*tp_name*/ - sizeof(BufferedObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)BufferedObject_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - BufferedWriter_doc, /* tp_doc */ - (traverseproc)Buffered_traverse, /* tp_traverse */ - (inquiry)Buffered_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(BufferedObject, weakreflist), /*tp_weaklistoffset*/ - 0, /* tp_iter */ - 0, /* tp_iternext */ - BufferedWriter_methods, /* tp_methods */ - BufferedWriter_members, /* tp_members */ - BufferedWriter_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(BufferedObject, dict), /* tp_dictoffset */ - (initproc)BufferedWriter_init, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; - - - -/* - * BufferedRWPair - */ - -PyDoc_STRVAR(BufferedRWPair_doc, - "A buffered reader and writer object together.\n" - "\n" - "A buffered reader object and buffered writer object put together to\n" - "form a sequential IO object that can read and write. This is typically\n" - "used with a socket or two-way pipe.\n" - "\n" - "reader and writer are RawIOBase objects that are readable and\n" - "writeable respectively. If the buffer_size is omitted it defaults to\n" - "DEFAULT_BUFFER_SIZE.\n" - ); - -/* XXX The usefulness of this (compared to having two separate IO objects) is - * questionable. - */ - -typedef struct { - PyObject_HEAD - BufferedObject *reader; - BufferedObject *writer; - PyObject *dict; - PyObject *weakreflist; -} BufferedRWPairObject; - -static int -BufferedRWPair_init(BufferedRWPairObject *self, PyObject *args, - PyObject *kwds) -{ - PyObject *reader, *writer; - Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; - Py_ssize_t max_buffer_size = -234; - - if (!PyArg_ParseTuple(args, "OO|nn:BufferedRWPair", &reader, &writer, - &buffer_size, &max_buffer_size)) { - return -1; - } - - if (max_buffer_size != -234 && !complain_about_max_buffer_size()) - return -1; - - if (_PyIOBase_checkReadable(reader, Py_True) == NULL) - return -1; - if (_PyIOBase_checkWritable(writer, Py_True) == NULL) - return -1; - - args = Py_BuildValue("(n)", buffer_size); - if (args == NULL) { - Py_CLEAR(self->reader); - return -1; - } - self->reader = (BufferedObject *)PyType_GenericNew( - &PyBufferedReader_Type, args, NULL); - Py_DECREF(args); - if (self->reader == NULL) - return -1; - - args = Py_BuildValue("(n)", buffer_size); - if (args == NULL) { - Py_CLEAR(self->reader); - return -1; - } - self->writer = (BufferedObject *)PyType_GenericNew( - &PyBufferedWriter_Type, args, NULL); - Py_DECREF(args); - if (self->writer == NULL) { - Py_CLEAR(self->reader); - return -1; - } - return 0; -} - -static int -BufferedRWPair_traverse(BufferedRWPairObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->dict); - return 0; -} - -static int -BufferedRWPair_clear(BufferedRWPairObject *self) -{ - Py_CLEAR(self->reader); - Py_CLEAR(self->writer); - Py_CLEAR(self->dict); - return 0; -} - -static void -BufferedRWPair_dealloc(BufferedRWPairObject *self) -{ - _PyObject_GC_UNTRACK(self); - Py_CLEAR(self->reader); - Py_CLEAR(self->writer); - Py_CLEAR(self->dict); - Py_TYPE(self)->tp_free((PyObject *) self); -} - -static PyObject * -_forward_call(BufferedObject *self, const char *name, PyObject *args) -{ - PyObject *func = PyObject_GetAttrString((PyObject *)self, name); - PyObject *ret; - - if (func == NULL) { - PyErr_SetString(PyExc_AttributeError, name); - return NULL; - } - - ret = PyObject_CallObject(func, args); - Py_DECREF(func); - return ret; -} - -static PyObject * -BufferedRWPair_read(BufferedRWPairObject *self, PyObject *args) -{ - return _forward_call(self->reader, "read", args); -} - -static PyObject * -BufferedRWPair_peek(BufferedRWPairObject *self, PyObject *args) -{ - return _forward_call(self->reader, "peek", args); -} - -static PyObject * -BufferedRWPair_read1(BufferedRWPairObject *self, PyObject *args) -{ - return _forward_call(self->reader, "read1", args); -} - -static PyObject * -BufferedRWPair_write(BufferedRWPairObject *self, PyObject *args) -{ - return _forward_call(self->writer, "write", args); -} - -static PyObject * -BufferedRWPair_flush(BufferedRWPairObject *self, PyObject *args) -{ - return _forward_call(self->writer, "flush", args); -} - -static PyObject * -BufferedRWPair_readable(BufferedRWPairObject *self, PyObject *args) -{ - return _forward_call(self->reader, "readable", args); -} - -static PyObject * -BufferedRWPair_writable(BufferedRWPairObject *self, PyObject *args) -{ - return _forward_call(self->writer, "writable", args); -} - -static PyObject * -BufferedRWPair_close(BufferedRWPairObject *self, PyObject *args) -{ - PyObject *ret = _forward_call(self->writer, "close", args); - if (ret == NULL) - return NULL; - Py_DECREF(ret); - - return _forward_call(self->reader, "close", args); -} - -static PyObject * -BufferedRWPair_isatty(BufferedRWPairObject *self, PyObject *args) -{ - PyObject *ret = _forward_call(self->writer, "isatty", args); - - if (ret != Py_False) { - /* either True or exception */ - return ret; - } - Py_DECREF(ret); - - return _forward_call(self->reader, "isatty", args); -} - - -static PyMethodDef BufferedRWPair_methods[] = { - {"read", (PyCFunction)BufferedRWPair_read, METH_VARARGS}, - {"peek", (PyCFunction)BufferedRWPair_peek, METH_VARARGS}, - {"read1", (PyCFunction)BufferedRWPair_read1, METH_VARARGS}, - {"readinto", (PyCFunction)Buffered_readinto, METH_VARARGS}, - - {"write", (PyCFunction)BufferedRWPair_write, METH_VARARGS}, - {"flush", (PyCFunction)BufferedRWPair_flush, METH_NOARGS}, - - {"readable", (PyCFunction)BufferedRWPair_readable, METH_NOARGS}, - {"writable", (PyCFunction)BufferedRWPair_writable, METH_NOARGS}, - - {"close", (PyCFunction)BufferedRWPair_close, METH_NOARGS}, - {"isatty", (PyCFunction)BufferedRWPair_isatty, METH_NOARGS}, - - {NULL, NULL} -}; - -PyTypeObject PyBufferedRWPair_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.BufferedRWPair", /*tp_name*/ - sizeof(BufferedRWPairObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)BufferedRWPair_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - BufferedRWPair_doc, /* tp_doc */ - (traverseproc)BufferedRWPair_traverse, /* tp_traverse */ - (inquiry)BufferedRWPair_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(BufferedRWPairObject, weakreflist), /*tp_weaklistoffset*/ - 0, /* tp_iter */ - 0, /* tp_iternext */ - BufferedRWPair_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(BufferedRWPairObject, dict), /* tp_dictoffset */ - (initproc)BufferedRWPair_init, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; - - - -/* - * BufferedRandom - */ - -PyDoc_STRVAR(BufferedRandom_doc, - "A buffered interface to random access streams.\n" - "\n" - "The constructor creates a reader and writer for a seekable stream,\n" - "raw, given in the first argument. If the buffer_size is omitted it\n" - "defaults to DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n" - ); - -static int -BufferedRandom_init(BufferedObject *self, PyObject *args, PyObject *kwds) -{ - char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL}; - Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; - Py_ssize_t max_buffer_size = -234; - PyObject *raw; - - self->ok = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedReader", kwlist, - &raw, &buffer_size, &max_buffer_size)) { - return -1; - } - - if (max_buffer_size != -234 && !complain_about_max_buffer_size()) - return -1; - - if (_PyIOBase_checkSeekable(raw, Py_True) == NULL) - return -1; - if (_PyIOBase_checkReadable(raw, Py_True) == NULL) - return -1; - if (_PyIOBase_checkWritable(raw, Py_True) == NULL) - return -1; - - Py_CLEAR(self->raw); - Py_INCREF(raw); - self->raw = raw; - self->buffer_size = buffer_size; - self->readable = 1; - self->writable = 1; - - if (_Buffered_init(self) < 0) - return -1; - _BufferedReader_reset_buf(self); - _BufferedWriter_reset_buf(self); - self->pos = 0; - - self->ok = 1; - return 0; -} - -static PyMethodDef BufferedRandom_methods[] = { - /* BufferedIOMixin methods */ - {"close", (PyCFunction)BufferedIOMixin_close, METH_NOARGS}, - {"seekable", (PyCFunction)BufferedIOMixin_seekable, METH_NOARGS}, - {"readable", (PyCFunction)BufferedIOMixin_readable, METH_NOARGS}, - {"writable", (PyCFunction)BufferedIOMixin_writable, METH_NOARGS}, - {"fileno", (PyCFunction)BufferedIOMixin_fileno, METH_NOARGS}, - {"isatty", (PyCFunction)BufferedIOMixin_isatty, METH_NOARGS}, - - {"flush", (PyCFunction)Buffered_flush, METH_NOARGS}, - - {"seek", (PyCFunction)Buffered_seek, METH_VARARGS}, - {"tell", (PyCFunction)Buffered_tell, METH_NOARGS}, - {"truncate", (PyCFunction)Buffered_truncate, METH_VARARGS}, - {"read", (PyCFunction)Buffered_read, METH_VARARGS}, - {"read1", (PyCFunction)Buffered_read1, METH_VARARGS}, - {"readinto", (PyCFunction)Buffered_readinto, METH_VARARGS}, - {"readline", (PyCFunction)Buffered_readline, METH_VARARGS}, - {"peek", (PyCFunction)Buffered_peek, METH_VARARGS}, - {"write", (PyCFunction)BufferedWriter_write, METH_VARARGS}, - {NULL, NULL} -}; - -static PyMemberDef BufferedRandom_members[] = { - {"raw", T_OBJECT, offsetof(BufferedObject, raw), 0}, - {NULL} -}; - -static PyGetSetDef BufferedRandom_getset[] = { - {"closed", (getter)BufferedIOMixin_closed_get, NULL, NULL}, - {"name", (getter)BufferedIOMixin_name_get, NULL, NULL}, - {"mode", (getter)BufferedIOMixin_mode_get, NULL, NULL}, - {0} -}; - - -PyTypeObject PyBufferedRandom_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.BufferedRandom", /*tp_name*/ - sizeof(BufferedObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)BufferedObject_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - BufferedRandom_doc, /* tp_doc */ - (traverseproc)Buffered_traverse, /* tp_traverse */ - (inquiry)Buffered_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(BufferedObject, weakreflist), /*tp_weaklistoffset*/ - 0, /* tp_iter */ - (iternextfunc)Buffered_iternext, /* tp_iternext */ - BufferedRandom_methods, /* tp_methods */ - BufferedRandom_members, /* tp_members */ - BufferedRandom_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /*tp_dict*/ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(BufferedObject, dict), /*tp_dictoffset*/ - (initproc)BufferedRandom_init, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; - Deleted: python/branches/py3k/Modules/_bytesio.c ============================================================================== --- python/branches/py3k/Modules/_bytesio.c Sat Apr 4 21:58:40 2009 +++ (empty file) @@ -1,757 +0,0 @@ -#include "Python.h" -#include "structmember.h" /* for offsetof() */ -#include "_iomodule.h" - -typedef struct { - PyObject_HEAD - char *buf; - Py_ssize_t pos; - Py_ssize_t string_size; - size_t buf_size; - PyObject *dict; - PyObject *weakreflist; -} BytesIOObject; - -#define CHECK_CLOSED(self) \ - if ((self)->buf == NULL) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on closed file."); \ - return NULL; \ - } - -/* Internal routine to get a line from the buffer of a BytesIO - object. Returns the length between the current position to the - next newline character. */ -static Py_ssize_t -get_line(BytesIOObject *self, char **output) -{ - char *n; - const char *str_end; - Py_ssize_t len; - - assert(self->buf != NULL); - - /* Move to the end of the line, up to the end of the string, s. */ - str_end = self->buf + self->string_size; - for (n = self->buf + self->pos; - n < str_end && *n != '\n'; - n++); - - /* Skip the newline character */ - if (n < str_end) - n++; - - /* Get the length from the current position to the end of the line. */ - len = n - (self->buf + self->pos); - *output = self->buf + self->pos; - - assert(len >= 0); - assert(self->pos < PY_SSIZE_T_MAX - len); - self->pos += len; - - return len; -} - -/* Internal routine for changing the size of the buffer of BytesIO objects. - The caller should ensure that the 'size' argument is non-negative. Returns - 0 on success, -1 otherwise. */ -static int -resize_buffer(BytesIOObject *self, size_t size) -{ - /* Here, unsigned types are used to avoid dealing with signed integer - overflow, which is undefined in C. */ - size_t alloc = self->buf_size; - char *new_buf = NULL; - - assert(self->buf != NULL); - - /* For simplicity, stay in the range of the signed type. Anyway, Python - doesn't allow strings to be longer than this. */ - if (size > PY_SSIZE_T_MAX) - goto overflow; - - if (size < alloc / 2) { - /* Major downsize; resize down to exact size. */ - alloc = size + 1; - } - else if (size < alloc) { - /* Within allocated size; quick exit */ - return 0; - } - else if (size <= alloc * 1.125) { - /* Moderate upsize; overallocate similar to list_resize() */ - alloc = size + (size >> 3) + (size < 9 ? 3 : 6); - } - else { - /* Major upsize; resize up to exact size */ - alloc = size + 1; - } - - if (alloc > ((size_t)-1) / sizeof(char)) - goto overflow; - new_buf = (char *)PyMem_Realloc(self->buf, alloc * sizeof(char)); - if (new_buf == NULL) { - PyErr_NoMemory(); - return -1; - } - self->buf_size = alloc; - self->buf = new_buf; - - return 0; - - overflow: - PyErr_SetString(PyExc_OverflowError, - "new buffer size too large"); - return -1; -} - -/* Internal routine for writing a string of bytes to the buffer of a BytesIO - object. Returns the number of bytes wrote, or -1 on error. */ -static Py_ssize_t -write_bytes(BytesIOObject *self, const char *bytes, Py_ssize_t len) -{ - assert(self->buf != NULL); - assert(self->pos >= 0); - assert(len >= 0); - - if ((size_t)self->pos + len > self->buf_size) { - if (resize_buffer(self, (size_t)self->pos + len) < 0) - return -1; - } - - if (self->pos > self->string_size) { - /* In case of overseek, pad with null bytes the buffer region between - the end of stream and the current position. - - 0 lo string_size hi - | |<---used--->|<----------available----------->| - | | <--to pad-->|<---to write---> | - 0 buf position - */ - memset(self->buf + self->string_size, '\0', - (self->pos - self->string_size) * sizeof(char)); - } - - /* Copy the data to the internal buffer, overwriting some of the existing - data if self->pos < self->string_size. */ - memcpy(self->buf + self->pos, bytes, len); - self->pos += len; - - /* Set the new length of the internal string if it has changed. */ - if (self->string_size < self->pos) { - self->string_size = self->pos; - } - - return len; -} - -static PyObject * -bytesio_get_closed(BytesIOObject *self) -{ - if (self->buf == NULL) { - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; - } -} - -/* Generic getter for the writable, readable and seekable properties */ -static PyObject * -return_true(BytesIOObject *self) -{ - Py_RETURN_TRUE; -} - -PyDoc_STRVAR(flush_doc, -"flush() -> None. Does nothing."); - -static PyObject * -bytesio_flush(BytesIOObject *self) -{ - Py_RETURN_NONE; -} - -PyDoc_STRVAR(getval_doc, -"getvalue() -> bytes.\n" -"\n" -"Retrieve the entire contents of the BytesIO object."); - -static PyObject * -bytesio_getvalue(BytesIOObject *self) -{ - CHECK_CLOSED(self); - return PyBytes_FromStringAndSize(self->buf, self->string_size); -} - -PyDoc_STRVAR(isatty_doc, -"isatty() -> False.\n" -"\n" -"Always returns False since BytesIO objects are not connected\n" -"to a tty-like device."); - -static PyObject * -bytesio_isatty(BytesIOObject *self) -{ - CHECK_CLOSED(self); - Py_RETURN_FALSE; -} - -PyDoc_STRVAR(tell_doc, -"tell() -> current file position, an integer\n"); - -static PyObject * -bytesio_tell(BytesIOObject *self) -{ - CHECK_CLOSED(self); - return PyLong_FromSsize_t(self->pos); -} - -PyDoc_STRVAR(read_doc, -"read([size]) -> read at most size bytes, returned as a string.\n" -"\n" -"If the size argument is negative, read until EOF is reached.\n" -"Return an empty string at EOF."); - -static PyObject * -bytesio_read(BytesIOObject *self, PyObject *args) -{ - Py_ssize_t size, n; - char *output; - PyObject *arg = Py_None; - - CHECK_CLOSED(self); - - if (!PyArg_ParseTuple(args, "|O:read", &arg)) - return NULL; - - if (PyLong_Check(arg)) { - size = PyLong_AsSsize_t(arg); - if (size == -1 && PyErr_Occurred()) - return NULL; - } - else if (arg == Py_None) { - /* Read until EOF is reached, by default. */ - size = -1; - } - else { - PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", - Py_TYPE(arg)->tp_name); - return NULL; - } - - /* adjust invalid sizes */ - n = self->string_size - self->pos; - if (size < 0 || size > n) { - size = n; - if (size < 0) - size = 0; - } - - assert(self->buf != NULL); - output = self->buf + self->pos; - self->pos += size; - - return PyBytes_FromStringAndSize(output, size); -} - - -PyDoc_STRVAR(read1_doc, -"read1(size) -> read at most size bytes, returned as a string.\n" -"\n" -"If the size argument is negative or omitted, read until EOF is reached.\n" -"Return an empty string at EOF."); - -static PyObject * -bytesio_read1(BytesIOObject *self, PyObject *n) -{ - PyObject *arg, *res; - - arg = PyTuple_Pack(1, n); - if (arg == NULL) - return NULL; - res = bytesio_read(self, arg); - Py_DECREF(arg); - return res; -} - -PyDoc_STRVAR(readline_doc, -"readline([size]) -> next line from the file, as a string.\n" -"\n" -"Retain newline. A non-negative size argument limits the maximum\n" -"number of bytes to return (an incomplete line may be returned then).\n" -"Return an empty string at EOF.\n"); - -static PyObject * -bytesio_readline(BytesIOObject *self, PyObject *args) -{ - Py_ssize_t size, n; - char *output; - PyObject *arg = Py_None; - - CHECK_CLOSED(self); - - if (!PyArg_ParseTuple(args, "|O:readline", &arg)) - return NULL; - - if (PyLong_Check(arg)) { - size = PyLong_AsSsize_t(arg); - if (size == -1 && PyErr_Occurred()) - return NULL; - } - else if (arg == Py_None) { - /* No size limit, by default. */ - size = -1; - } - else { - PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", - Py_TYPE(arg)->tp_name); - return NULL; - } - - n = get_line(self, &output); - - if (size >= 0 && size < n) { - size = n - size; - n -= size; - self->pos -= size; - } - - return PyBytes_FromStringAndSize(output, n); -} - -PyDoc_STRVAR(readlines_doc, -"readlines([size]) -> list of strings, each a line from the file.\n" -"\n" -"Call readline() repeatedly and return a list of the lines so read.\n" -"The optional size argument, if given, is an approximate bound on the\n" -"total number of bytes in the lines returned.\n"); - -static PyObject * -bytesio_readlines(BytesIOObject *self, PyObject *args) -{ - Py_ssize_t maxsize, size, n; - PyObject *result, *line; - char *output; - PyObject *arg = Py_None; - - CHECK_CLOSED(self); - - if (!PyArg_ParseTuple(args, "|O:readlines", &arg)) - return NULL; - - if (PyLong_Check(arg)) { - maxsize = PyLong_AsSsize_t(arg); - if (maxsize == -1 && PyErr_Occurred()) - return NULL; - } - else if (arg == Py_None) { - /* No size limit, by default. */ - maxsize = -1; - } - else { - PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", - Py_TYPE(arg)->tp_name); - return NULL; - } - - size = 0; - result = PyList_New(0); - if (!result) - return NULL; - - while ((n = get_line(self, &output)) != 0) { - line = PyBytes_FromStringAndSize(output, n); - if (!line) - goto on_error; - if (PyList_Append(result, line) == -1) { - Py_DECREF(line); - goto on_error; - } - Py_DECREF(line); - size += n; - if (maxsize > 0 && size >= maxsize) - break; - } - return result; - - on_error: - Py_DECREF(result); - return NULL; -} - -PyDoc_STRVAR(readinto_doc, -"readinto(bytearray) -> int. Read up to len(b) bytes into b.\n" -"\n" -"Returns number of bytes read (0 for EOF), or None if the object\n" -"is set not to block as has no data to read."); - -static PyObject * -bytesio_readinto(BytesIOObject *self, PyObject *buffer) -{ - void *raw_buffer; - Py_ssize_t len; - - CHECK_CLOSED(self); - - if (PyObject_AsWriteBuffer(buffer, &raw_buffer, &len) == -1) - return NULL; - - if (self->pos + len > self->string_size) - len = self->string_size - self->pos; - - memcpy(raw_buffer, self->buf + self->pos, len); - assert(self->pos + len < PY_SSIZE_T_MAX); - assert(len >= 0); - self->pos += len; - - return PyLong_FromSsize_t(len); -} - -PyDoc_STRVAR(truncate_doc, -"truncate([size]) -> int. Truncate the file to at most size bytes.\n" -"\n" -"Size defaults to the current file position, as returned by tell().\n" -"Returns the new size. Imply an absolute seek to the position size."); - -static PyObject * -bytesio_truncate(BytesIOObject *self, PyObject *args) -{ - Py_ssize_t size; - PyObject *arg = Py_None; - - CHECK_CLOSED(self); - - if (!PyArg_ParseTuple(args, "|O:truncate", &arg)) - return NULL; - - if (PyLong_Check(arg)) { - size = PyLong_AsSsize_t(arg); - if (size == -1 && PyErr_Occurred()) - return NULL; - } - else if (arg == Py_None) { - /* Truncate to current position if no argument is passed. */ - size = self->pos; - } - else { - PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", - Py_TYPE(arg)->tp_name); - return NULL; - } - - if (size < 0) { - PyErr_Format(PyExc_ValueError, - "negative size value %zd", size); - return NULL; - } - - if (size < self->string_size) { - self->string_size = size; - if (resize_buffer(self, size) < 0) - return NULL; - } - self->pos = size; - - return PyLong_FromSsize_t(size); -} - -static PyObject * -bytesio_iternext(BytesIOObject *self) -{ - char *next; - Py_ssize_t n; - - CHECK_CLOSED(self); - - n = get_line(self, &next); - - if (!next || n == 0) - return NULL; - - return PyBytes_FromStringAndSize(next, n); -} - -PyDoc_STRVAR(seek_doc, -"seek(pos, whence=0) -> int. Change stream position.\n" -"\n" -"Seek to byte offset pos relative to position indicated by whence:\n" -" 0 Start of stream (the default). pos should be >= 0;\n" -" 1 Current position - pos may be negative;\n" -" 2 End of stream - pos usually negative.\n" -"Returns the new absolute position."); - -static PyObject * -bytesio_seek(BytesIOObject *self, PyObject *args) -{ - Py_ssize_t pos; - int mode = 0; - - CHECK_CLOSED(self); - - if (!PyArg_ParseTuple(args, "n|i:seek", &pos, &mode)) - return NULL; - - if (pos < 0 && mode == 0) { - PyErr_Format(PyExc_ValueError, - "negative seek value %zd", pos); - return NULL; - } - - /* mode 0: offset relative to beginning of the string. - mode 1: offset relative to current position. - mode 2: offset relative the end of the string. */ - if (mode == 1) { - if (pos > PY_SSIZE_T_MAX - self->pos) { - PyErr_SetString(PyExc_OverflowError, - "new position too large"); - return NULL; - } - pos += self->pos; - } - else if (mode == 2) { - if (pos > PY_SSIZE_T_MAX - self->string_size) { - PyErr_SetString(PyExc_OverflowError, - "new position too large"); - return NULL; - } - pos += self->string_size; - } - else if (mode != 0) { - PyErr_Format(PyExc_ValueError, - "invalid whence (%i, should be 0, 1 or 2)", mode); - return NULL; - } - - if (pos < 0) - pos = 0; - self->pos = pos; - - return PyLong_FromSsize_t(self->pos); -} - -PyDoc_STRVAR(write_doc, -"write(bytes) -> int. Write bytes to file.\n" -"\n" -"Return the number of bytes written."); - -static PyObject * -bytesio_write(BytesIOObject *self, PyObject *obj) -{ - Py_ssize_t n = 0; - Py_buffer buf; - PyObject *result = NULL; - - CHECK_CLOSED(self); - - if (PyObject_GetBuffer(obj, &buf, PyBUF_CONTIG_RO) < 0) - return NULL; - - if (buf.len != 0) - n = write_bytes(self, buf.buf, buf.len); - if (n >= 0) - result = PyLong_FromSsize_t(n); - - PyBuffer_Release(&buf); - return result; -} - -PyDoc_STRVAR(writelines_doc, -"writelines(sequence_of_strings) -> None. Write strings to the file.\n" -"\n" -"Note that newlines are not added. The sequence can be any iterable\n" -"object producing strings. This is equivalent to calling write() for\n" -"each string."); - -static PyObject * -bytesio_writelines(BytesIOObject *self, PyObject *v) -{ - PyObject *it, *item; - PyObject *ret; - - CHECK_CLOSED(self); - - it = PyObject_GetIter(v); - if (it == NULL) - return NULL; - - while ((item = PyIter_Next(it)) != NULL) { - ret = bytesio_write(self, item); - Py_DECREF(item); - if (ret == NULL) { - Py_DECREF(it); - return NULL; - } - Py_DECREF(ret); - } - Py_DECREF(it); - - /* See if PyIter_Next failed */ - if (PyErr_Occurred()) - return NULL; - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(close_doc, -"close() -> None. Disable all I/O operations."); - -static PyObject * -bytesio_close(BytesIOObject *self) -{ - if (self->buf != NULL) { - PyMem_Free(self->buf); - self->buf = NULL; - } - Py_RETURN_NONE; -} - -static void -bytesio_dealloc(BytesIOObject *self) -{ - if (self->buf != NULL) { - PyMem_Free(self->buf); - self->buf = NULL; - } - Py_TYPE(self)->tp_clear((PyObject *)self); - Py_TYPE(self)->tp_free(self); -} - -static PyObject * -bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - BytesIOObject *self; - - assert(type != NULL && type->tp_alloc != NULL); - self = (BytesIOObject *)type->tp_alloc(type, 0); - if (self == NULL) - return NULL; - - self->string_size = 0; - self->pos = 0; - self->buf_size = 0; - self->buf = (char *)PyMem_Malloc(0); - if (self->buf == NULL) { - Py_DECREF(self); - return PyErr_NoMemory(); - } - - return (PyObject *)self; -} - -static int -bytesio_init(BytesIOObject *self, PyObject *args, PyObject *kwds) -{ - PyObject *initvalue = NULL; - - if (!PyArg_ParseTuple(args, "|O:BytesIO", &initvalue)) - return -1; - - /* In case, __init__ is called multiple times. */ - self->string_size = 0; - self->pos = 0; - - if (initvalue && initvalue != Py_None) { - PyObject *res; - res = bytesio_write(self, initvalue); - if (res == NULL) - return -1; - Py_DECREF(res); - self->pos = 0; - } - - return 0; -} - -static int -bytesio_traverse(BytesIOObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->dict); - Py_VISIT(self->weakreflist); - return 0; -} - -static int -bytesio_clear(BytesIOObject *self) -{ - Py_CLEAR(self->dict); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *)self); - return 0; -} - - -static PyGetSetDef bytesio_getsetlist[] = { - {"closed", (getter)bytesio_get_closed, NULL, - "True if the file is closed."}, - {0}, /* sentinel */ -}; - -static struct PyMethodDef bytesio_methods[] = { - {"readable", (PyCFunction)return_true, METH_NOARGS, NULL}, - {"seekable", (PyCFunction)return_true, METH_NOARGS, NULL}, - {"writable", (PyCFunction)return_true, METH_NOARGS, NULL}, - {"close", (PyCFunction)bytesio_close, METH_NOARGS, close_doc}, - {"flush", (PyCFunction)bytesio_flush, METH_NOARGS, flush_doc}, - {"isatty", (PyCFunction)bytesio_isatty, METH_NOARGS, isatty_doc}, - {"tell", (PyCFunction)bytesio_tell, METH_NOARGS, tell_doc}, - {"write", (PyCFunction)bytesio_write, METH_O, write_doc}, - {"writelines", (PyCFunction)bytesio_writelines, METH_O, writelines_doc}, - {"read1", (PyCFunction)bytesio_read1, METH_O, read1_doc}, - {"readinto", (PyCFunction)bytesio_readinto, METH_O, readinto_doc}, - {"readline", (PyCFunction)bytesio_readline, METH_VARARGS, readline_doc}, - {"readlines", (PyCFunction)bytesio_readlines, METH_VARARGS, readlines_doc}, - {"read", (PyCFunction)bytesio_read, METH_VARARGS, read_doc}, - {"getvalue", (PyCFunction)bytesio_getvalue, METH_VARARGS, getval_doc}, - {"seek", (PyCFunction)bytesio_seek, METH_VARARGS, seek_doc}, - {"truncate", (PyCFunction)bytesio_truncate, METH_VARARGS, truncate_doc}, - {NULL, NULL} /* sentinel */ -}; - -PyDoc_STRVAR(bytesio_doc, -"BytesIO([buffer]) -> object\n" -"\n" -"Create a buffered I/O implementation using an in-memory bytes\n" -"buffer, ready for reading and writing."); - -PyTypeObject PyBytesIO_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.BytesIO", /*tp_name*/ - sizeof(BytesIOObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)bytesio_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*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - bytesio_doc, /*tp_doc*/ - (traverseproc)bytesio_traverse, /*tp_traverse*/ - (inquiry)bytesio_clear, /*tp_clear*/ - 0, /*tp_richcompare*/ - offsetof(BytesIOObject, weakreflist), /*tp_weaklistoffset*/ - PyObject_SelfIter, /*tp_iter*/ - (iternextfunc)bytesio_iternext, /*tp_iternext*/ - bytesio_methods, /*tp_methods*/ - 0, /*tp_members*/ - bytesio_getsetlist, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - offsetof(BytesIOObject, dict), /*tp_dictoffset*/ - (initproc)bytesio_init, /*tp_init*/ - 0, /*tp_alloc*/ - bytesio_new, /*tp_new*/ -}; Deleted: python/branches/py3k/Modules/_fileio.c ============================================================================== --- python/branches/py3k/Modules/_fileio.c Sat Apr 4 21:58:40 2009 +++ (empty file) @@ -1,1034 +0,0 @@ -/* Author: Daniel Stutzbach */ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#include -#include -#include -#include /* For offsetof */ -#include "_iomodule.h" - -/* - * Known likely problems: - * - * - Files larger then 2**32-1 - * - Files with unicode filenames - * - Passing numbers greater than 2**32-1 when an integer is expected - * - Making it work on Windows and other oddball platforms - * - * To Do: - * - * - autoconfify header file inclusion - */ - -#ifdef MS_WINDOWS -/* can simulate truncate with Win32 API functions; see file_truncate */ -#define HAVE_FTRUNCATE -#define WIN32_LEAN_AND_MEAN -#include -#endif - -#if BUFSIZ < (8*1024) -#define SMALLCHUNK (8*1024) -#elif (BUFSIZ >= (2 << 25)) -#error "unreasonable BUFSIZ > 64MB defined" -#else -#define SMALLCHUNK BUFSIZ -#endif - -#if SIZEOF_INT < 4 -#define BIGCHUNK (512 * 32) -#else -#define BIGCHUNK (512 * 1024) -#endif - -typedef struct { - PyObject_HEAD - int fd; - unsigned readable : 1; - unsigned writable : 1; - int seekable : 2; /* -1 means unknown */ - int closefd : 1; - PyObject *weakreflist; - PyObject *dict; -} PyFileIOObject; - -PyTypeObject PyFileIO_Type; - -#define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type)) - -int -_PyFileIO_closed(PyObject *self) -{ - return ((PyFileIOObject *)self)->fd < 0; -} - -static PyObject * -portable_lseek(int fd, PyObject *posobj, int whence); - -static PyObject *portable_lseek(int fd, PyObject *posobj, int whence); - -/* Returns 0 on success, -1 with exception set on failure. */ -static int -internal_close(PyFileIOObject *self) -{ - int err = 0; - int save_errno = 0; - if (self->fd >= 0) { - int fd = self->fd; - self->fd = -1; - /* fd is accessible and someone else may have closed it */ - if (_PyVerify_fd(fd)) { - Py_BEGIN_ALLOW_THREADS - err = close(fd); - if (err < 0) - save_errno = errno; - Py_END_ALLOW_THREADS - } else { - save_errno = errno; - err = -1; - } - } - if (err < 0) { - errno = save_errno; - PyErr_SetFromErrno(PyExc_IOError); - return -1; - } - return 0; -} - -static PyObject * -fileio_close(PyFileIOObject *self) -{ - if (!self->closefd) { - self->fd = -1; - Py_RETURN_NONE; - } - errno = internal_close(self); - if (errno < 0) - return NULL; - - return PyObject_CallMethod((PyObject*)&PyRawIOBase_Type, - "close", "O", self); -} - -static PyObject * -fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyFileIOObject *self; - - assert(type != NULL && type->tp_alloc != NULL); - - self = (PyFileIOObject *) type->tp_alloc(type, 0); - if (self != NULL) { - self->fd = -1; - self->readable = 0; - self->writable = 0; - self->seekable = -1; - self->closefd = 1; - self->weakreflist = NULL; - } - - return (PyObject *) self; -} - -/* On Unix, open will succeed for directories. - In Python, there should be no file objects referring to - directories, so we need a check. */ - -static int -dircheck(PyFileIOObject* self, const char *name) -{ -#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR) - struct stat buf; - if (self->fd < 0) - return 0; - if (fstat(self->fd, &buf) == 0 && S_ISDIR(buf.st_mode)) { - char *msg = strerror(EISDIR); - PyObject *exc; - if (internal_close(self)) - return -1; - - exc = PyObject_CallFunction(PyExc_IOError, "(iss)", - EISDIR, msg, name); - PyErr_SetObject(PyExc_IOError, exc); - Py_XDECREF(exc); - return -1; - } -#endif - return 0; -} - -static int -check_fd(int fd) -{ -#if defined(HAVE_FSTAT) - struct stat buf; - if (!_PyVerify_fd(fd) || (fstat(fd, &buf) < 0 && errno == EBADF)) { - PyObject *exc; - char *msg = strerror(EBADF); - exc = PyObject_CallFunction(PyExc_OSError, "(is)", - EBADF, msg); - PyErr_SetObject(PyExc_OSError, exc); - Py_XDECREF(exc); - return -1; - } -#endif - return 0; -} - - -static int -fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) -{ - PyFileIOObject *self = (PyFileIOObject *) oself; - static char *kwlist[] = {"file", "mode", "closefd", NULL}; - const char *name = NULL; - PyObject *nameobj, *stringobj = NULL; - char *mode = "r"; - char *s; -#ifdef MS_WINDOWS - Py_UNICODE *widename = NULL; -#endif - int ret = 0; - int rwa = 0, plus = 0, append = 0; - int flags = 0; - int fd = -1; - int closefd = 1; - - assert(PyFileIO_Check(oself)); - if (self->fd >= 0) { - /* Have to close the existing file first. */ - if (internal_close(self) < 0) - return -1; - } - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|si:fileio", - kwlist, &nameobj, &mode, &closefd)) - return -1; - - if (PyFloat_Check(nameobj)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float"); - return -1; - } - - fd = PyLong_AsLong(nameobj); - if (fd < 0) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ValueError, - "Negative filedescriptor"); - return -1; - } - PyErr_Clear(); - } - -#ifdef Py_WIN_WIDE_FILENAMES - if (GetVersion() < 0x80000000) { - /* On NT, so wide API available */ - if (PyUnicode_Check(nameobj)) - widename = PyUnicode_AS_UNICODE(nameobj); - } - if (widename == NULL) -#endif - if (fd < 0) - { - if (PyBytes_Check(nameobj) || PyByteArray_Check(nameobj)) { - Py_ssize_t namelen; - if (PyObject_AsCharBuffer(nameobj, &name, &namelen) < 0) - return -1; - } - else { - PyObject *u = PyUnicode_FromObject(nameobj); - - if (u == NULL) - return -1; - - stringobj = PyUnicode_AsEncodedString( - u, Py_FileSystemDefaultEncoding, NULL); - Py_DECREF(u); - if (stringobj == NULL) - return -1; - if (!PyBytes_Check(stringobj)) { - PyErr_SetString(PyExc_TypeError, - "encoder failed to return bytes"); - goto error; - } - name = PyBytes_AS_STRING(stringobj); - } - } - - s = mode; - while (*s) { - switch (*s++) { - case 'r': - if (rwa) { - bad_mode: - PyErr_SetString(PyExc_ValueError, - "Must have exactly one of read/write/append mode"); - goto error; - } - rwa = 1; - self->readable = 1; - break; - case 'w': - if (rwa) - goto bad_mode; - rwa = 1; - self->writable = 1; - flags |= O_CREAT | O_TRUNC; - break; - case 'a': - if (rwa) - goto bad_mode; - rwa = 1; - self->writable = 1; - flags |= O_CREAT; - append = 1; - break; - case 'b': - break; - case '+': - if (plus) - goto bad_mode; - self->readable = self->writable = 1; - plus = 1; - break; - default: - PyErr_Format(PyExc_ValueError, - "invalid mode: %.200s", mode); - goto error; - } - } - - if (!rwa) - goto bad_mode; - - if (self->readable && self->writable) - flags |= O_RDWR; - else if (self->readable) - flags |= O_RDONLY; - else - flags |= O_WRONLY; - -#ifdef O_BINARY - flags |= O_BINARY; -#endif - -#ifdef O_APPEND - if (append) - flags |= O_APPEND; -#endif - - if (fd >= 0) { - if (check_fd(fd)) - goto error; - self->fd = fd; - self->closefd = closefd; - } - else { - self->closefd = 1; - if (!closefd) { - PyErr_SetString(PyExc_ValueError, - "Cannot use closefd=False with file name"); - goto error; - } - - Py_BEGIN_ALLOW_THREADS - errno = 0; -#ifdef MS_WINDOWS - if (widename != NULL) - self->fd = _wopen(widename, flags, 0666); - else -#endif - self->fd = open(name, flags, 0666); - Py_END_ALLOW_THREADS - if (self->fd < 0) { -#ifdef MS_WINDOWS - if (widename != NULL) - PyErr_SetFromErrnoWithUnicodeFilename(PyExc_IOError, widename); - else -#endif - PyErr_SetFromErrnoWithFilename(PyExc_IOError, name); - goto error; - } - if(dircheck(self, name) < 0) - goto error; - } - - if (PyObject_SetAttrString((PyObject *)self, "name", nameobj) < 0) - goto error; - - if (append) { - /* For consistent behaviour, we explicitly seek to the - end of file (otherwise, it might be done only on the - first write()). */ - PyObject *pos = portable_lseek(self->fd, NULL, 2); - if (pos == NULL) - goto error; - Py_DECREF(pos); - } - - goto done; - - error: - ret = -1; - - done: - Py_CLEAR(stringobj); - return ret; -} - -static int -fileio_traverse(PyFileIOObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->dict); - return 0; -} - -static int -fileio_clear(PyFileIOObject *self) -{ - Py_CLEAR(self->dict); - return 0; -} - -static void -fileio_dealloc(PyFileIOObject *self) -{ - if (_PyIOBase_finalize((PyObject *) self) < 0) - return; - _PyObject_GC_UNTRACK(self); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - Py_CLEAR(self->dict); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static PyObject * -err_closed(void) -{ - PyErr_SetString(PyExc_ValueError, "I/O operation on closed file"); - return NULL; -} - -static PyObject * -err_mode(char *action) -{ - PyErr_Format(PyExc_ValueError, "File not open for %s", action); - return NULL; -} - -static PyObject * -fileio_fileno(PyFileIOObject *self) -{ - if (self->fd < 0) - return err_closed(); - return PyLong_FromLong((long) self->fd); -} - -static PyObject * -fileio_readable(PyFileIOObject *self) -{ - if (self->fd < 0) - return err_closed(); - return PyBool_FromLong((long) self->readable); -} - -static PyObject * -fileio_writable(PyFileIOObject *self) -{ - if (self->fd < 0) - return err_closed(); - return PyBool_FromLong((long) self->writable); -} - -static PyObject * -fileio_seekable(PyFileIOObject *self) -{ - if (self->fd < 0) - return err_closed(); - if (self->seekable < 0) { - PyObject *pos = portable_lseek(self->fd, NULL, SEEK_CUR); - if (pos == NULL) { - PyErr_Clear(); - self->seekable = 0; - } else { - Py_DECREF(pos); - self->seekable = 1; - } - } - return PyBool_FromLong((long) self->seekable); -} - -static PyObject * -fileio_readinto(PyFileIOObject *self, PyObject *args) -{ - Py_buffer pbuf; - Py_ssize_t n; - - if (self->fd < 0) - return err_closed(); - if (!self->readable) - return err_mode("reading"); - - if (!PyArg_ParseTuple(args, "w*", &pbuf)) - return NULL; - - if (_PyVerify_fd(self->fd)) { - Py_BEGIN_ALLOW_THREADS - errno = 0; - n = read(self->fd, pbuf.buf, pbuf.len); - Py_END_ALLOW_THREADS - } else - n = -1; - PyBuffer_Release(&pbuf); - if (n < 0) { - if (errno == EAGAIN) - Py_RETURN_NONE; - PyErr_SetFromErrno(PyExc_IOError); - return NULL; - } - - return PyLong_FromSsize_t(n); -} - -static size_t -new_buffersize(PyFileIOObject *self, size_t currentsize) -{ -#ifdef HAVE_FSTAT - off_t pos, end; - struct stat st; - if (fstat(self->fd, &st) == 0) { - end = st.st_size; - pos = lseek(self->fd, 0L, SEEK_CUR); - /* Files claiming a size smaller than SMALLCHUNK may - actually be streaming pseudo-files. In this case, we - apply the more aggressive algorithm below. - */ - if (end >= SMALLCHUNK && end >= pos && pos >= 0) { - /* Add 1 so if the file were to grow we'd notice. */ - return currentsize + end - pos + 1; - } - } -#endif - if (currentsize > SMALLCHUNK) { - /* Keep doubling until we reach BIGCHUNK; - then keep adding BIGCHUNK. */ - if (currentsize <= BIGCHUNK) - return currentsize + currentsize; - else - return currentsize + BIGCHUNK; - } - return currentsize + SMALLCHUNK; -} - -static PyObject * -fileio_readall(PyFileIOObject *self) -{ - PyObject *result; - Py_ssize_t total = 0; - int n; - - if (!_PyVerify_fd(self->fd)) - return PyErr_SetFromErrno(PyExc_IOError); - - result = PyBytes_FromStringAndSize(NULL, SMALLCHUNK); - if (result == NULL) - return NULL; - - while (1) { - size_t newsize = new_buffersize(self, total); - if (newsize > PY_SSIZE_T_MAX || newsize <= 0) { - PyErr_SetString(PyExc_OverflowError, - "unbounded read returned more bytes " - "than a Python string can hold "); - Py_DECREF(result); - return NULL; - } - - if (PyBytes_GET_SIZE(result) < newsize) { - if (_PyBytes_Resize(&result, newsize) < 0) { - if (total == 0) { - Py_DECREF(result); - return NULL; - } - PyErr_Clear(); - break; - } - } - Py_BEGIN_ALLOW_THREADS - errno = 0; - n = read(self->fd, - PyBytes_AS_STRING(result) + total, - newsize - total); - Py_END_ALLOW_THREADS - if (n == 0) - break; - if (n < 0) { - if (total > 0) - break; - if (errno == EAGAIN) { - Py_DECREF(result); - Py_RETURN_NONE; - } - Py_DECREF(result); - PyErr_SetFromErrno(PyExc_IOError); - return NULL; - } - total += n; - } - - if (PyBytes_GET_SIZE(result) > total) { - if (_PyBytes_Resize(&result, total) < 0) { - /* This should never happen, but just in case */ - Py_DECREF(result); - return NULL; - } - } - return result; -} - -static PyObject * -fileio_read(PyFileIOObject *self, PyObject *args) -{ - char *ptr; - Py_ssize_t n; - Py_ssize_t size = -1; - PyObject *bytes; - - if (self->fd < 0) - return err_closed(); - if (!self->readable) - return err_mode("reading"); - - if (!PyArg_ParseTuple(args, "|n", &size)) - return NULL; - - if (size < 0) { - return fileio_readall(self); - } - - bytes = PyBytes_FromStringAndSize(NULL, size); - if (bytes == NULL) - return NULL; - ptr = PyBytes_AS_STRING(bytes); - - if (_PyVerify_fd(self->fd)) { - Py_BEGIN_ALLOW_THREADS - errno = 0; - n = read(self->fd, ptr, size); - Py_END_ALLOW_THREADS - } else - n = -1; - - if (n < 0) { - Py_DECREF(bytes); - if (errno == EAGAIN) - Py_RETURN_NONE; - PyErr_SetFromErrno(PyExc_IOError); - return NULL; - } - - if (n != size) { - if (_PyBytes_Resize(&bytes, n) < 0) { - Py_DECREF(bytes); - return NULL; - } - } - - return (PyObject *) bytes; -} - -static PyObject * -fileio_write(PyFileIOObject *self, PyObject *args) -{ - Py_buffer pbuf; - Py_ssize_t n; - - if (self->fd < 0) - return err_closed(); - if (!self->writable) - return err_mode("writing"); - - if (!PyArg_ParseTuple(args, "s*", &pbuf)) - return NULL; - - if (_PyVerify_fd(self->fd)) { - Py_BEGIN_ALLOW_THREADS - errno = 0; - n = write(self->fd, pbuf.buf, pbuf.len); - Py_END_ALLOW_THREADS - } else - n = -1; - - PyBuffer_Release(&pbuf); - - if (n < 0) { - if (errno == EAGAIN) - Py_RETURN_NONE; - PyErr_SetFromErrno(PyExc_IOError); - return NULL; - } - - return PyLong_FromSsize_t(n); -} - -/* XXX Windows support below is likely incomplete */ - -/* Cribbed from posix_lseek() */ -static PyObject * -portable_lseek(int fd, PyObject *posobj, int whence) -{ - Py_off_t pos, res; - -#ifdef SEEK_SET - /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ - switch (whence) { -#if SEEK_SET != 0 - case 0: whence = SEEK_SET; break; -#endif -#if SEEK_CUR != 1 - case 1: whence = SEEK_CUR; break; -#endif -#if SEEK_END != 2 - case 2: whence = SEEK_END; break; -#endif - } -#endif /* SEEK_SET */ - - if (posobj == NULL) - pos = 0; - else { - if(PyFloat_Check(posobj)) { - PyErr_SetString(PyExc_TypeError, "an integer is required"); - return NULL; - } -#if defined(HAVE_LARGEFILE_SUPPORT) - pos = PyLong_AsLongLong(posobj); -#else - pos = PyLong_AsLong(posobj); -#endif - if (PyErr_Occurred()) - return NULL; - } - - if (_PyVerify_fd(fd)) { - Py_BEGIN_ALLOW_THREADS -#if defined(MS_WIN64) || defined(MS_WINDOWS) - res = _lseeki64(fd, pos, whence); -#else - res = lseek(fd, pos, whence); -#endif - Py_END_ALLOW_THREADS - } else - res = -1; - if (res < 0) - return PyErr_SetFromErrno(PyExc_IOError); - -#if defined(HAVE_LARGEFILE_SUPPORT) - return PyLong_FromLongLong(res); -#else - return PyLong_FromLong(res); -#endif -} - -static PyObject * -fileio_seek(PyFileIOObject *self, PyObject *args) -{ - PyObject *posobj; - int whence = 0; - - if (self->fd < 0) - return err_closed(); - - if (!PyArg_ParseTuple(args, "O|i", &posobj, &whence)) - return NULL; - - return portable_lseek(self->fd, posobj, whence); -} - -static PyObject * -fileio_tell(PyFileIOObject *self, PyObject *args) -{ - if (self->fd < 0) - return err_closed(); - - return portable_lseek(self->fd, NULL, 1); -} - -#ifdef HAVE_FTRUNCATE -static PyObject * -fileio_truncate(PyFileIOObject *self, PyObject *args) -{ - PyObject *posobj = NULL; - Py_off_t pos; - int ret; - int fd; - - fd = self->fd; - if (fd < 0) - return err_closed(); - if (!self->writable) - return err_mode("writing"); - - if (!PyArg_ParseTuple(args, "|O", &posobj)) - return NULL; - - if (posobj == Py_None || posobj == NULL) { - /* Get the current position. */ - posobj = portable_lseek(fd, NULL, 1); - if (posobj == NULL) - return NULL; - } - else { - /* Move to the position to be truncated. */ - posobj = portable_lseek(fd, posobj, 0); - } - if (posobj == NULL) - return NULL; - -#if defined(HAVE_LARGEFILE_SUPPORT) - pos = PyLong_AsLongLong(posobj); -#else - pos = PyLong_AsLong(posobj); -#endif - if (pos == -1 && PyErr_Occurred()) - return NULL; - -#ifdef MS_WINDOWS - /* MS _chsize doesn't work if newsize doesn't fit in 32 bits, - so don't even try using it. */ - { - HANDLE hFile; - - /* Truncate. Note that this may grow the file! */ - Py_BEGIN_ALLOW_THREADS - errno = 0; - hFile = (HANDLE)_get_osfhandle(fd); - ret = hFile == (HANDLE)-1; - if (ret == 0) { - ret = SetEndOfFile(hFile) == 0; - if (ret) - errno = EACCES; - } - Py_END_ALLOW_THREADS - } -#else - Py_BEGIN_ALLOW_THREADS - errno = 0; - ret = ftruncate(fd, pos); - Py_END_ALLOW_THREADS -#endif /* !MS_WINDOWS */ - - if (ret != 0) { - PyErr_SetFromErrno(PyExc_IOError); - return NULL; - } - - return posobj; -} -#endif - -static char * -mode_string(PyFileIOObject *self) -{ - if (self->readable) { - if (self->writable) - return "rb+"; - else - return "rb"; - } - else - return "wb"; -} - -static PyObject * -fileio_repr(PyFileIOObject *self) -{ - if (self->fd < 0) - return PyUnicode_FromFormat("io.FileIO(-1)"); - - return PyUnicode_FromFormat("io.FileIO(%d, '%s')", - self->fd, mode_string(self)); -} - -static PyObject * -fileio_isatty(PyFileIOObject *self) -{ - long res; - - if (self->fd < 0) - return err_closed(); - Py_BEGIN_ALLOW_THREADS - res = isatty(self->fd); - Py_END_ALLOW_THREADS - return PyBool_FromLong(res); -} - - -PyDoc_STRVAR(fileio_doc, -"file(name: str[, mode: str]) -> file IO object\n" -"\n" -"Open a file. The mode can be 'r', 'w' or 'a' for reading (default),\n" -"writing or appending. The file will be created if it doesn't exist\n" -"when opened for writing or appending; it will be truncated when\n" -"opened for writing. Add a '+' to the mode to allow simultaneous\n" -"reading and writing."); - -PyDoc_STRVAR(read_doc, -"read(size: int) -> bytes. read at most size bytes, returned as bytes.\n" -"\n" -"Only makes one system call, so less data may be returned than requested\n" -"In non-blocking mode, returns None if no data is available.\n" -"On end-of-file, returns ''."); - -PyDoc_STRVAR(readall_doc, -"readall() -> bytes. read all data from the file, returned as bytes.\n" -"\n" -"In non-blocking mode, returns as much as is immediately available,\n" -"or None if no data is available. On end-of-file, returns ''."); - -PyDoc_STRVAR(write_doc, -"write(b: bytes) -> int. Write bytes b to file, return number written.\n" -"\n" -"Only makes one system call, so not all of the data may be written.\n" -"The number of bytes actually written is returned."); - -PyDoc_STRVAR(fileno_doc, -"fileno() -> int. \"file descriptor\".\n" -"\n" -"This is needed for lower-level file interfaces, such the fcntl module."); - -PyDoc_STRVAR(seek_doc, -"seek(offset: int[, whence: int]) -> None. Move to new file position.\n" -"\n" -"Argument offset is a byte count. Optional argument whence defaults to\n" -"0 (offset from start of file, offset should be >= 0); other values are 1\n" -"(move relative to current position, positive or negative), and 2 (move\n" -"relative to end of file, usually negative, although many platforms allow\n" -"seeking beyond the end of a file)." -"\n" -"Note that not all file objects are seekable."); - -#ifdef HAVE_FTRUNCATE -PyDoc_STRVAR(truncate_doc, -"truncate([size: int]) -> None. Truncate the file to at most size bytes.\n" -"\n" -"Size defaults to the current file position, as returned by tell()." -"The current file position is changed to the value of size."); -#endif - -PyDoc_STRVAR(tell_doc, -"tell() -> int. Current file position"); - -PyDoc_STRVAR(readinto_doc, -"readinto() -> Same as RawIOBase.readinto()."); - -PyDoc_STRVAR(close_doc, -"close() -> None. Close the file.\n" -"\n" -"A closed file cannot be used for further I/O operations. close() may be\n" -"called more than once without error. Changes the fileno to -1."); - -PyDoc_STRVAR(isatty_doc, -"isatty() -> bool. True if the file is connected to a tty device."); - -PyDoc_STRVAR(seekable_doc, -"seekable() -> bool. True if file supports random-access."); - -PyDoc_STRVAR(readable_doc, -"readable() -> bool. True if file was opened in a read mode."); - -PyDoc_STRVAR(writable_doc, -"writable() -> bool. True if file was opened in a write mode."); - -static PyMethodDef fileio_methods[] = { - {"read", (PyCFunction)fileio_read, METH_VARARGS, read_doc}, - {"readall", (PyCFunction)fileio_readall, METH_NOARGS, readall_doc}, - {"readinto", (PyCFunction)fileio_readinto, METH_VARARGS, readinto_doc}, - {"write", (PyCFunction)fileio_write, METH_VARARGS, write_doc}, - {"seek", (PyCFunction)fileio_seek, METH_VARARGS, seek_doc}, - {"tell", (PyCFunction)fileio_tell, METH_VARARGS, tell_doc}, -#ifdef HAVE_FTRUNCATE - {"truncate", (PyCFunction)fileio_truncate, METH_VARARGS, truncate_doc}, -#endif - {"close", (PyCFunction)fileio_close, METH_NOARGS, close_doc}, - {"seekable", (PyCFunction)fileio_seekable, METH_NOARGS, seekable_doc}, - {"readable", (PyCFunction)fileio_readable, METH_NOARGS, readable_doc}, - {"writable", (PyCFunction)fileio_writable, METH_NOARGS, writable_doc}, - {"fileno", (PyCFunction)fileio_fileno, METH_NOARGS, fileno_doc}, - {"isatty", (PyCFunction)fileio_isatty, METH_NOARGS, isatty_doc}, - {NULL, NULL} /* sentinel */ -}; - -/* 'closed' and 'mode' are attributes for backwards compatibility reasons. */ - -static PyObject * -get_closed(PyFileIOObject *self, void *closure) -{ - return PyBool_FromLong((long)(self->fd < 0)); -} - -static PyObject * -get_closefd(PyFileIOObject *self, void *closure) -{ - return PyBool_FromLong((long)(self->closefd)); -} - -static PyObject * -get_mode(PyFileIOObject *self, void *closure) -{ - return PyUnicode_FromString(mode_string(self)); -} - -static PyGetSetDef fileio_getsetlist[] = { - {"closed", (getter)get_closed, NULL, "True if the file is closed"}, - {"closefd", (getter)get_closefd, NULL, - "True if the file descriptor will be closed"}, - {"mode", (getter)get_mode, NULL, "String giving the file mode"}, - {0}, -}; - -PyTypeObject PyFileIO_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.FileIO", - sizeof(PyFileIOObject), - 0, - (destructor)fileio_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (reprfunc)fileio_repr, /* 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_BASETYPE - | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - fileio_doc, /* tp_doc */ - (traverseproc)fileio_traverse, /* tp_traverse */ - (inquiry)fileio_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(PyFileIOObject, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - fileio_methods, /* tp_methods */ - 0, /* tp_members */ - fileio_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(PyFileIOObject, dict), /* tp_dictoffset */ - fileio_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - fileio_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; Deleted: python/branches/py3k/Modules/_iobase.c ============================================================================== --- python/branches/py3k/Modules/_iobase.c Sat Apr 4 21:58:40 2009 +++ (empty file) @@ -1,894 +0,0 @@ -/* - An implementation of the I/O abstract base classes hierarchy - as defined by PEP 3116 - "New I/O" - - Classes defined here: IOBase, RawIOBase. - - Written by Amaury Forgeot d'Arc and Antoine Pitrou -*/ - - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#include "structmember.h" -#include "_iomodule.h" - -/* - * IOBase class, an abstract class - */ - -typedef struct { - PyObject_HEAD - - PyObject *dict; - PyObject *weakreflist; -} IOBaseObject; - -PyDoc_STRVAR(IOBase_doc, - "The abstract base class for all I/O classes, acting on streams of\n" - "bytes. There is no public constructor.\n" - "\n" - "This class provides dummy implementations for many methods that\n" - "derived classes can override selectively; the default implementations\n" - "represent a file that cannot be read, written or seeked.\n" - "\n" - "Even though IOBase does not declare read, readinto, or write because\n" - "their signatures will vary, implementations and clients should\n" - "consider those methods part of the interface. Also, implementations\n" - "may raise a IOError when operations they do not support are called.\n" - "\n" - "The basic type used for binary data read from or written to a file is\n" - "bytes. bytearrays are accepted too, and in some cases (such as\n" - "readinto) needed. Text I/O classes work with str data.\n" - "\n" - "Note that calling any method (even inquiries) on a closed stream is\n" - "undefined. Implementations may raise IOError in this case.\n" - "\n" - "IOBase (and its subclasses) support the iterator protocol, meaning\n" - "that an IOBase object can be iterated over yielding the lines in a\n" - "stream.\n" - "\n" - "IOBase also supports the :keyword:`with` statement. In this example,\n" - "fp is closed after the suite of the with statment is complete:\n" - "\n" - "with open('spam.txt', 'r') as fp:\n" - " fp.write('Spam and eggs!')\n"); - -/* Use this macro whenever you want to check the internal `closed` status - of the IOBase object rather than the virtual `closed` attribute as returned - by whatever subclass. */ - -#define IS_CLOSED(self) \ - PyObject_HasAttrString(self, "__IOBase_closed") - -/* Internal methods */ -static PyObject * -IOBase_unsupported(const char *message) -{ - PyErr_SetString(IO_STATE->unsupported_operation, message); - return NULL; -} - -/* Positionning */ - -PyDoc_STRVAR(IOBase_seek_doc, - "Change stream position.\n" - "\n" - "Change the stream position to byte offset offset. offset is\n" - "interpreted relative to the position indicated by whence. Values\n" - "for whence are:\n" - "\n" - "* 0 -- start of stream (the default); offset should be zero or positive\n" - "* 1 -- current stream position; offset may be negative\n" - "* 2 -- end of stream; offset is usually negative\n" - "\n" - "Return the new absolute position."); - -static PyObject * -IOBase_seek(PyObject *self, PyObject *args) -{ - return IOBase_unsupported("seek"); -} - -PyDoc_STRVAR(IOBase_tell_doc, - "Return current stream position."); - -static PyObject * -IOBase_tell(PyObject *self, PyObject *args) -{ - return PyObject_CallMethod(self, "seek", "ii", 0, 1); -} - -PyDoc_STRVAR(IOBase_truncate_doc, - "Truncate file to size bytes.\n" - "\n" - "Size defaults to the current IO position as reported by tell(). Return\n" - "the new size."); - -static PyObject * -IOBase_truncate(PyObject *self, PyObject *args) -{ - return IOBase_unsupported("truncate"); -} - -/* Flush and close methods */ - -PyDoc_STRVAR(IOBase_flush_doc, - "Flush write buffers, if applicable.\n" - "\n" - "This is not implemented for read-only and non-blocking streams.\n"); - -static PyObject * -IOBase_flush(PyObject *self, PyObject *args) -{ - /* XXX Should this return the number of bytes written??? */ - if (IS_CLOSED(self)) { - PyErr_SetString(PyExc_ValueError, "I/O operation on closed file."); - return NULL; - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(IOBase_close_doc, - "Flush and close the IO object.\n" - "\n" - "This method has no effect if the file is already closed.\n"); - -static int -IOBase_closed(PyObject *self) -{ - PyObject *res; - int closed; - /* This gets the derived attribute, which is *not* __IOBase_closed - in most cases! */ - res = PyObject_GetAttr(self, _PyIO_str_closed); - if (res == NULL) - return 0; - closed = PyObject_IsTrue(res); - Py_DECREF(res); - return closed; -} - -static PyObject * -IOBase_closed_get(PyObject *self, void *context) -{ - return PyBool_FromLong(IS_CLOSED(self)); -} - -PyObject * -_PyIOBase_checkClosed(PyObject *self, PyObject *args) -{ - if (IOBase_closed(self)) { - PyErr_SetString(PyExc_ValueError, "I/O operation on closed file."); - return NULL; - } - if (args == Py_True) - return Py_None; - else - Py_RETURN_NONE; -} - -/* XXX: IOBase thinks it has to maintain its own internal state in - `__IOBase_closed` and call flush() by itself, but it is redundant with - whatever behaviour a non-trivial derived class will implement. */ - -static PyObject * -IOBase_close(PyObject *self, PyObject *args) -{ - PyObject *res; - - if (IS_CLOSED(self)) - Py_RETURN_NONE; - - res = PyObject_CallMethodObjArgs(self, _PyIO_str_flush, NULL); - PyObject_SetAttrString(self, "__IOBase_closed", Py_True); - if (res == NULL) { - /* If flush() fails, just give up */ - if (PyErr_ExceptionMatches(PyExc_IOError)) - PyErr_Clear(); - else - return NULL; - } - Py_XDECREF(res); - Py_RETURN_NONE; -} - -/* Finalization and garbage collection support */ - -int -_PyIOBase_finalize(PyObject *self) -{ - PyObject *res; - PyObject *tp, *v, *tb; - int closed = 1; - int is_zombie; - - /* If _PyIOBase_finalize() is called from a destructor, we need to - resurrect the object as calling close() can invoke arbitrary code. */ - is_zombie = (Py_REFCNT(self) == 0); - if (is_zombie) { - ++Py_REFCNT(self); - } - PyErr_Fetch(&tp, &v, &tb); - /* If `closed` doesn't exist or can't be evaluated as bool, then the - object is probably in an unusable state, so ignore. */ - res = PyObject_GetAttr(self, _PyIO_str_closed); - if (res == NULL) - PyErr_Clear(); - else { - closed = PyObject_IsTrue(res); - Py_DECREF(res); - if (closed == -1) - PyErr_Clear(); - } - if (closed == 0) { - res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_close, - NULL); - /* Silencing I/O errors is bad, but printing spurious tracebacks is - equally as bad, and potentially more frequent (because of - shutdown issues). */ - if (res == NULL) - PyErr_Clear(); - else - Py_DECREF(res); - } - PyErr_Restore(tp, v, tb); - if (is_zombie) { - if (--Py_REFCNT(self) != 0) { - /* The object lives again. The following code is taken from - slot_tp_del in typeobject.c. */ - Py_ssize_t refcnt = Py_REFCNT(self); - _Py_NewReference(self); - Py_REFCNT(self) = refcnt; - /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so - * we need to undo that. */ - _Py_DEC_REFTOTAL; - /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object - * chain, so no more to do there. - * If COUNT_ALLOCS, the original decref bumped tp_frees, and - * _Py_NewReference bumped tp_allocs: both of those need to be - * undone. - */ -#ifdef COUNT_ALLOCS - --Py_TYPE(self)->tp_frees; - --Py_TYPE(self)->tp_allocs; -#endif - return -1; - } - } - return 0; -} - -static int -IOBase_traverse(IOBaseObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->dict); - return 0; -} - -static int -IOBase_clear(IOBaseObject *self) -{ - if (_PyIOBase_finalize((PyObject *) self) < 0) - return -1; - Py_CLEAR(self->dict); - return 0; -} - -/* Destructor */ - -static void -IOBase_dealloc(IOBaseObject *self) -{ - /* NOTE: since IOBaseObject has its own dict, Python-defined attributes - are still available here for close() to use. - However, if the derived class declares a __slots__, those slots are - already gone. - */ - if (_PyIOBase_finalize((PyObject *) self) < 0) { - /* When called from a heap type's dealloc, the type will be - decref'ed on return (see e.g. subtype_dealloc in typeobject.c). */ - if (PyType_HasFeature(Py_TYPE(self), Py_TPFLAGS_HEAPTYPE)) - Py_INCREF(Py_TYPE(self)); - return; - } - _PyObject_GC_UNTRACK(self); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - Py_CLEAR(self->dict); - Py_TYPE(self)->tp_free((PyObject *) self); -} - -/* Inquiry methods */ - -PyDoc_STRVAR(IOBase_seekable_doc, - "Return whether object supports random access.\n" - "\n" - "If False, seek(), tell() and truncate() will raise IOError.\n" - "This method may need to do a test seek()."); - -static PyObject * -IOBase_seekable(PyObject *self, PyObject *args) -{ - Py_RETURN_FALSE; -} - -PyObject * -_PyIOBase_checkSeekable(PyObject *self, PyObject *args) -{ - PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_seekable, NULL); - if (res == NULL) - return NULL; - if (res != Py_True) { - Py_CLEAR(res); - PyErr_SetString(PyExc_IOError, "File or stream is not seekable."); - return NULL; - } - if (args == Py_True) { - Py_DECREF(res); - } - return res; -} - -PyDoc_STRVAR(IOBase_readable_doc, - "Return whether object was opened for reading.\n" - "\n" - "If False, read() will raise IOError."); - -static PyObject * -IOBase_readable(PyObject *self, PyObject *args) -{ - Py_RETURN_FALSE; -} - -/* May be called with any object */ -PyObject * -_PyIOBase_checkReadable(PyObject *self, PyObject *args) -{ - PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_readable, NULL); - if (res == NULL) - return NULL; - if (res != Py_True) { - Py_CLEAR(res); - PyErr_SetString(PyExc_IOError, "File or stream is not readable."); - return NULL; - } - if (args == Py_True) { - Py_DECREF(res); - } - return res; -} - -PyDoc_STRVAR(IOBase_writable_doc, - "Return whether object was opened for writing.\n" - "\n" - "If False, read() will raise IOError."); - -static PyObject * -IOBase_writable(PyObject *self, PyObject *args) -{ - Py_RETURN_FALSE; -} - -/* May be called with any object */ -PyObject * -_PyIOBase_checkWritable(PyObject *self, PyObject *args) -{ - PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_writable, NULL); - if (res == NULL) - return NULL; - if (res != Py_True) { - Py_CLEAR(res); - PyErr_SetString(PyExc_IOError, "File or stream is not writable."); - return NULL; - } - if (args == Py_True) { - Py_DECREF(res); - } - return res; -} - -/* Context manager */ - -static PyObject * -IOBase_enter(PyObject *self, PyObject *args) -{ - if (_PyIOBase_checkClosed(self, Py_True) == NULL) - return NULL; - - Py_INCREF(self); - return self; -} - -static PyObject * -IOBase_exit(PyObject *self, PyObject *args) -{ - return PyObject_CallMethodObjArgs(self, _PyIO_str_close, NULL); -} - -/* Lower-level APIs */ - -/* XXX Should these be present even if unimplemented? */ - -PyDoc_STRVAR(IOBase_fileno_doc, - "Returns underlying file descriptor if one exists.\n" - "\n" - "An IOError is raised if the IO object does not use a file descriptor.\n"); - -static PyObject * -IOBase_fileno(PyObject *self, PyObject *args) -{ - return IOBase_unsupported("fileno"); -} - -PyDoc_STRVAR(IOBase_isatty_doc, - "Return whether this is an 'interactive' stream.\n" - "\n" - "Return False if it can't be determined.\n"); - -static PyObject * -IOBase_isatty(PyObject *self, PyObject *args) -{ - if (_PyIOBase_checkClosed(self, Py_True) == NULL) - return NULL; - Py_RETURN_FALSE; -} - -/* Readline(s) and writelines */ - -PyDoc_STRVAR(IOBase_readline_doc, - "Read and return a line from the stream.\n" - "\n" - "If limit is specified, at most limit bytes will be read.\n" - "\n" - "The line terminator is always b'\n' for binary files; for text\n" - "files, the newlines argument to open can be used to select the line\n" - "terminator(s) recognized.\n"); - -static PyObject * -IOBase_readline(PyObject *self, PyObject *args) -{ - /* For backwards compatibility, a (slowish) readline(). */ - - Py_ssize_t limit = -1; - int has_peek = 0; - PyObject *buffer, *result; - Py_ssize_t old_size = -1; - - if (!PyArg_ParseTuple(args, "|n:readline", &limit)) { - return NULL; - } - - if (PyObject_HasAttrString(self, "peek")) - has_peek = 1; - - buffer = PyByteArray_FromStringAndSize(NULL, 0); - if (buffer == NULL) - return NULL; - - while (limit < 0 || Py_SIZE(buffer) < limit) { - Py_ssize_t nreadahead = 1; - PyObject *b; - - if (has_peek) { - PyObject *readahead = PyObject_CallMethod(self, "peek", "i", 1); - if (readahead == NULL) - goto fail; - if (!PyBytes_Check(readahead)) { - PyErr_Format(PyExc_IOError, - "peek() should have returned a bytes object, " - "not '%.200s'", Py_TYPE(readahead)->tp_name); - Py_DECREF(readahead); - goto fail; - } - if (PyBytes_GET_SIZE(readahead) > 0) { - Py_ssize_t n = 0; - const char *buf = PyBytes_AS_STRING(readahead); - if (limit >= 0) { - do { - if (n >= PyBytes_GET_SIZE(readahead) || n >= limit) - break; - if (buf[n++] == '\n') - break; - } while (1); - } - else { - do { - if (n >= PyBytes_GET_SIZE(readahead)) - break; - if (buf[n++] == '\n') - break; - } while (1); - } - nreadahead = n; - } - Py_DECREF(readahead); - } - - b = PyObject_CallMethod(self, "read", "n", nreadahead); - if (b == NULL) - goto fail; - if (!PyBytes_Check(b)) { - PyErr_Format(PyExc_IOError, - "read() should have returned a bytes object, " - "not '%.200s'", Py_TYPE(b)->tp_name); - Py_DECREF(b); - goto fail; - } - if (PyBytes_GET_SIZE(b) == 0) { - Py_DECREF(b); - break; - } - - old_size = PyByteArray_GET_SIZE(buffer); - PyByteArray_Resize(buffer, old_size + PyBytes_GET_SIZE(b)); - memcpy(PyByteArray_AS_STRING(buffer) + old_size, - PyBytes_AS_STRING(b), PyBytes_GET_SIZE(b)); - - Py_DECREF(b); - - if (PyByteArray_AS_STRING(buffer)[PyByteArray_GET_SIZE(buffer) - 1] == '\n') - break; - } - - result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(buffer), - PyByteArray_GET_SIZE(buffer)); - Py_DECREF(buffer); - return result; - fail: - Py_DECREF(buffer); - return NULL; -} - -static PyObject * -IOBase_iter(PyObject *self) -{ - if (_PyIOBase_checkClosed(self, Py_True) == NULL) - return NULL; - - Py_INCREF(self); - return self; -} - -static PyObject * -IOBase_iternext(PyObject *self) -{ - PyObject *line = PyObject_CallMethodObjArgs(self, _PyIO_str_readline, NULL); - - if (line == NULL) - return NULL; - - if (PyObject_Size(line) == 0) { - Py_DECREF(line); - return NULL; - } - - return line; -} - -PyDoc_STRVAR(IOBase_readlines_doc, - "Return a list of lines from the stream.\n" - "\n" - "hint can be specified to control the number of lines read: no more\n" - "lines will be read if the total size (in bytes/characters) of all\n" - "lines so far exceeds hint."); - -static PyObject * -IOBase_readlines(PyObject *self, PyObject *args) -{ - Py_ssize_t hint = -1, length = 0; - PyObject *hintobj = Py_None, *result; - - if (!PyArg_ParseTuple(args, "|O:readlines", &hintobj)) { - return NULL; - } - if (hintobj != Py_None) { - hint = PyNumber_AsSsize_t(hintobj, PyExc_ValueError); - if (hint == -1 && PyErr_Occurred()) - return NULL; - } - - result = PyList_New(0); - if (result == NULL) - return NULL; - - if (hint <= 0) { - /* XXX special-casing this made sense in the Python version in order - to remove the bytecode interpretation overhead, but it could - probably be removed here. */ - PyObject *ret = PyObject_CallMethod(result, "extend", "O", self); - if (ret == NULL) { - Py_DECREF(result); - return NULL; - } - Py_DECREF(ret); - return result; - } - - while (1) { - PyObject *line = PyIter_Next(self); - if (line == NULL) { - if (PyErr_Occurred()) { - Py_DECREF(result); - return NULL; - } - else - break; /* StopIteration raised */ - } - - if (PyList_Append(result, line) < 0) { - Py_DECREF(line); - Py_DECREF(result); - return NULL; - } - length += PyObject_Size(line); - Py_DECREF(line); - - if (length > hint) - break; - } - return result; -} - -static PyObject * -IOBase_writelines(PyObject *self, PyObject *args) -{ - PyObject *lines, *iter, *res; - - if (!PyArg_ParseTuple(args, "O:writelines", &lines)) { - return NULL; - } - - if (_PyIOBase_checkClosed(self, Py_True) == NULL) - return NULL; - - iter = PyObject_GetIter(lines); - if (iter == NULL) - return NULL; - - while (1) { - PyObject *line = PyIter_Next(iter); - if (line == NULL) { - if (PyErr_Occurred()) { - Py_DECREF(iter); - return NULL; - } - else - break; /* Stop Iteration */ - } - - res = PyObject_CallMethodObjArgs(self, _PyIO_str_write, line, NULL); - Py_DECREF(line); - if (res == NULL) { - Py_DECREF(iter); - return NULL; - } - Py_DECREF(res); - } - Py_DECREF(iter); - Py_RETURN_NONE; -} - -static PyMethodDef IOBase_methods[] = { - {"seek", IOBase_seek, METH_VARARGS, IOBase_seek_doc}, - {"tell", IOBase_tell, METH_NOARGS, IOBase_tell_doc}, - {"truncate", IOBase_truncate, METH_VARARGS, IOBase_truncate_doc}, - {"flush", IOBase_flush, METH_NOARGS, IOBase_flush_doc}, - {"close", IOBase_close, METH_NOARGS, IOBase_close_doc}, - - {"seekable", IOBase_seekable, METH_NOARGS, IOBase_seekable_doc}, - {"readable", IOBase_readable, METH_NOARGS, IOBase_readable_doc}, - {"writable", IOBase_writable, METH_NOARGS, IOBase_writable_doc}, - - {"_checkClosed", _PyIOBase_checkClosed, METH_NOARGS}, - {"_checkSeekable", _PyIOBase_checkSeekable, METH_NOARGS}, - {"_checkReadable", _PyIOBase_checkReadable, METH_NOARGS}, - {"_checkWritable", _PyIOBase_checkWritable, METH_NOARGS}, - - {"fileno", IOBase_fileno, METH_NOARGS, IOBase_fileno_doc}, - {"isatty", IOBase_isatty, METH_NOARGS, IOBase_isatty_doc}, - - {"__enter__", IOBase_enter, METH_NOARGS}, - {"__exit__", IOBase_exit, METH_VARARGS}, - - {"readline", IOBase_readline, METH_VARARGS, IOBase_readline_doc}, - {"readlines", IOBase_readlines, METH_VARARGS, IOBase_readlines_doc}, - {"writelines", IOBase_writelines, METH_VARARGS}, - - {NULL, NULL} -}; - -static PyGetSetDef IOBase_getset[] = { - {"closed", (getter)IOBase_closed_get, NULL, NULL}, - {0} -}; - - -PyTypeObject PyIOBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._IOBase", /*tp_name*/ - sizeof(IOBaseObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)IOBase_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - IOBase_doc, /* tp_doc */ - (traverseproc)IOBase_traverse, /* tp_traverse */ - (inquiry)IOBase_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(IOBaseObject, weakreflist), /* tp_weaklistoffset */ - IOBase_iter, /* tp_iter */ - IOBase_iternext, /* tp_iternext */ - IOBase_methods, /* tp_methods */ - 0, /* tp_members */ - IOBase_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(IOBaseObject, dict), /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; - - -/* - * RawIOBase class, Inherits from IOBase. - */ -PyDoc_STRVAR(RawIOBase_doc, - "Base class for raw binary I/O."); - -/* - * The read() method is implemented by calling readinto(); derived classes - * that want to support read() only need to implement readinto() as a - * primitive operation. In general, readinto() can be more efficient than - * read(). - * - * (It would be tempting to also provide an implementation of readinto() in - * terms of read(), in case the latter is a more suitable primitive operation, - * but that would lead to nasty recursion in case a subclass doesn't implement - * either.) -*/ - -static PyObject * -RawIOBase_read(PyObject *self, PyObject *args) -{ - Py_ssize_t n = -1; - PyObject *b, *res; - - if (!PyArg_ParseTuple(args, "|n:read", &n)) { - return NULL; - } - - if (n < 0) - return PyObject_CallMethod(self, "readall", NULL); - - /* TODO: allocate a bytes object directly instead and manually construct - a writable memoryview pointing to it. */ - b = PyByteArray_FromStringAndSize(NULL, n); - if (b == NULL) - return NULL; - - res = PyObject_CallMethodObjArgs(self, _PyIO_str_readinto, b, NULL); - if (res == NULL) { - Py_DECREF(b); - return NULL; - } - - n = PyNumber_AsSsize_t(res, PyExc_ValueError); - Py_DECREF(res); - if (n == -1 && PyErr_Occurred()) { - Py_DECREF(b); - return NULL; - } - - res = PyBytes_FromStringAndSize(PyByteArray_AsString(b), n); - Py_DECREF(b); - return res; -} - - -PyDoc_STRVAR(RawIOBase_readall_doc, - "Read until EOF, using multiple read() call."); - -static PyObject * -RawIOBase_readall(PyObject *self, PyObject *args) -{ - int r; - PyObject *chunks = PyList_New(0); - PyObject *result; - - if (chunks == NULL) - return NULL; - - while (1) { - PyObject *data = PyObject_CallMethod(self, "read", - "i", DEFAULT_BUFFER_SIZE); - if (!data) { - Py_DECREF(chunks); - return NULL; - } - if (!PyBytes_Check(data)) { - Py_DECREF(chunks); - Py_DECREF(data); - PyErr_SetString(PyExc_TypeError, "read() should return bytes"); - return NULL; - } - if (PyBytes_GET_SIZE(data) == 0) { - /* EOF */ - Py_DECREF(data); - break; - } - r = PyList_Append(chunks, data); - Py_DECREF(data); - if (r < 0) { - Py_DECREF(chunks); - return NULL; - } - } - result = _PyBytes_Join(_PyIO_empty_bytes, chunks); - Py_DECREF(chunks); - return result; -} - -static PyMethodDef RawIOBase_methods[] = { - {"read", RawIOBase_read, METH_VARARGS}, - {"readall", RawIOBase_readall, METH_NOARGS, RawIOBase_readall_doc}, - {NULL, NULL} -}; - -PyTypeObject PyRawIOBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._RawIOBase", /*tp_name*/ - 0, /*tp_basicsize*/ - 0, /*tp_itemsize*/ - 0, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - RawIOBase_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - RawIOBase_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PyIOBase_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ -}; Deleted: python/branches/py3k/Modules/_iomodule.h ============================================================================== --- python/branches/py3k/Modules/_iomodule.h Sat Apr 4 21:58:40 2009 +++ (empty file) @@ -1,150 +0,0 @@ -/* - * Declarations shared between the different parts of the io module - */ - -/* ABCs */ -extern PyTypeObject PyIOBase_Type; -extern PyTypeObject PyRawIOBase_Type; -extern PyTypeObject PyBufferedIOBase_Type; -extern PyTypeObject PyTextIOBase_Type; - -/* Concrete classes */ -extern PyTypeObject PyFileIO_Type; -extern PyTypeObject PyBytesIO_Type; -extern PyTypeObject PyStringIO_Type; -extern PyTypeObject PyBufferedReader_Type; -extern PyTypeObject PyBufferedWriter_Type; -extern PyTypeObject PyBufferedRWPair_Type; -extern PyTypeObject PyBufferedRandom_Type; -extern PyTypeObject PyTextIOWrapper_Type; -extern PyTypeObject PyIncrementalNewlineDecoder_Type; - -/* These functions are used as METH_NOARGS methods, are normally called - * with args=NULL, and return a new reference. - * BUT when args=Py_True is passed, they return a borrowed reference. - */ -extern PyObject* _PyIOBase_checkReadable(PyObject *self, PyObject *args); -extern PyObject* _PyIOBase_checkWritable(PyObject *self, PyObject *args); -extern PyObject* _PyIOBase_checkSeekable(PyObject *self, PyObject *args); -extern PyObject* _PyIOBase_checkClosed(PyObject *self, PyObject *args); - -/* Helper for finalization. - This function will revive an object ready to be deallocated and try to - close() it. It returns 0 if the object can be destroyed, or -1 if it - is alive again. */ -extern int _PyIOBase_finalize(PyObject *self); - -/* Returns true if the given FileIO object is closed. - Doesn't check the argument type, so be careful! */ -extern int _PyFileIO_closed(PyObject *self); - -/* Shortcut to the core of the IncrementalNewlineDecoder.decode method */ -extern PyObject *_PyIncrementalNewlineDecoder_decode( - PyObject *self, PyObject *input, int final); - -/* Finds the first line ending between `start` and `end`. - If found, returns the index after the line ending and doesn't touch - `*consumed`. - If not found, returns -1 and sets `*consumed` to the number of characters - which can be safely put aside until another search. - - NOTE: for performance reasons, `end` must point to a NUL character ('\0'). - Otherwise, the function will scan further and return garbage. */ -extern Py_ssize_t _PyIO_find_line_ending( - int translated, int universal, PyObject *readnl, - Py_UNICODE *start, Py_UNICODE *end, Py_ssize_t *consumed); - - -#define DEFAULT_BUFFER_SIZE (8 * 1024) /* bytes */ - -typedef struct { - PyException_HEAD - PyObject *myerrno; - PyObject *strerror; - PyObject *filename; /* Not used, but part of the IOError object */ - Py_ssize_t written; -} PyBlockingIOErrorObject; -PyAPI_DATA(PyObject *) PyExc_BlockingIOError; - -/* - * Offset type for positioning. - */ - -#if defined(MS_WIN64) || defined(MS_WINDOWS) - -/* Windows uses long long for offsets */ -typedef PY_LONG_LONG Py_off_t; -# define PyLong_AsOff_t PyLong_AsLongLong -# define PyLong_FromOff_t PyLong_FromLongLong -# define PY_OFF_T_MAX PY_LLONG_MAX -# define PY_OFF_T_MIN PY_LLONG_MIN - -#else - -/* Other platforms use off_t */ -typedef off_t Py_off_t; -#if (SIZEOF_OFF_T == SIZEOF_SIZE_T) -# define PyLong_AsOff_t PyLong_AsSsize_t -# define PyLong_FromOff_t PyLong_FromSsize_t -# define PY_OFF_T_MAX PY_SSIZE_T_MAX -# define PY_OFF_T_MIN PY_SSIZE_T_MIN -#elif (SIZEOF_OFF_T == SIZEOF_LONG_LONG) -# define PyLong_AsOff_t PyLong_AsLongLong -# define PyLong_FromOff_t PyLong_FromLongLong -# define PY_OFF_T_MAX PY_LLONG_MAX -# define PY_OFF_T_MIN PY_LLONG_MIN -#elif (SIZEOF_OFF_T == SIZEOF_LONG) -# define PyLong_AsOff_t PyLong_AsLong -# define PyLong_FromOff_t PyLong_FromLong -# define PY_OFF_T_MAX LONG_MAX -# define PY_OFF_T_MIN LONG_MIN -#else -# error off_t does not match either size_t, long, or long long! -#endif - -#endif - -extern Py_off_t PyNumber_AsOff_t(PyObject *item, PyObject *err); - -/* Implementation details */ - -/* IO module structure */ - -extern PyModuleDef _PyIO_Module; - -typedef struct { - int initialized; - PyObject *os_module; - PyObject *locale_module; - - PyObject *unsupported_operation; -} _PyIO_State; - -#define IO_MOD_STATE(mod) ((_PyIO_State *)PyModule_GetState(mod)) -#define IO_STATE IO_MOD_STATE(PyState_FindModule(&_PyIO_Module)) - -extern PyObject *_PyIO_str_close; -extern PyObject *_PyIO_str_closed; -extern PyObject *_PyIO_str_decode; -extern PyObject *_PyIO_str_encode; -extern PyObject *_PyIO_str_fileno; -extern PyObject *_PyIO_str_flush; -extern PyObject *_PyIO_str_getstate; -extern PyObject *_PyIO_str_isatty; -extern PyObject *_PyIO_str_newlines; -extern PyObject *_PyIO_str_nl; -extern PyObject *_PyIO_str_read; -extern PyObject *_PyIO_str_read1; -extern PyObject *_PyIO_str_readable; -extern PyObject *_PyIO_str_readinto; -extern PyObject *_PyIO_str_readline; -extern PyObject *_PyIO_str_reset; -extern PyObject *_PyIO_str_seek; -extern PyObject *_PyIO_str_seekable; -extern PyObject *_PyIO_str_tell; -extern PyObject *_PyIO_str_truncate; -extern PyObject *_PyIO_str_writable; -extern PyObject *_PyIO_str_write; - -extern PyObject *_PyIO_empty_str; -extern PyObject *_PyIO_empty_bytes; Deleted: python/branches/py3k/Modules/_stringio.c ============================================================================== --- python/branches/py3k/Modules/_stringio.c Sat Apr 4 21:58:40 2009 +++ (empty file) @@ -1,769 +0,0 @@ -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#include "structmember.h" -#include "_iomodule.h" - -/* Implementation note: the buffer is always at least one character longer - than the enclosed string, for proper functioning of _PyIO_find_line_ending. -*/ - -typedef struct { - PyObject_HEAD - Py_UNICODE *buf; - Py_ssize_t pos; - Py_ssize_t string_size; - size_t buf_size; - - char ok; /* initialized? */ - char closed; - char readuniversal; - char readtranslate; - PyObject *decoder; - PyObject *readnl; - PyObject *writenl; - - PyObject *dict; - PyObject *weakreflist; -} StringIOObject; - -#define CHECK_INITIALIZED(self) \ - if (self->ok <= 0) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - return NULL; \ - } - -#define CHECK_CLOSED(self) \ - if (self->closed) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on closed file"); \ - return NULL; \ - } - -PyDoc_STRVAR(stringio_doc, - "Text I/O implementation using an in-memory buffer.\n" - "\n" - "The initial_value argument sets the value of object. The newline\n" - "argument is like the one of TextIOWrapper's constructor."); - - -/* Internal routine for changing the size, in terms of characters, of the - buffer of StringIO objects. The caller should ensure that the 'size' - argument is non-negative. Returns 0 on success, -1 otherwise. */ -static int -resize_buffer(StringIOObject *self, size_t size) -{ - /* Here, unsigned types are used to avoid dealing with signed integer - overflow, which is undefined in C. */ - size_t alloc = self->buf_size; - Py_UNICODE *new_buf = NULL; - - assert(self->buf != NULL); - - /* Reserve one more char for line ending detection. */ - size = size + 1; - /* For simplicity, stay in the range of the signed type. Anyway, Python - doesn't allow strings to be longer than this. */ - if (size > PY_SSIZE_T_MAX) - goto overflow; - - if (size < alloc / 2) { - /* Major downsize; resize down to exact size. */ - alloc = size + 1; - } - else if (size < alloc) { - /* Within allocated size; quick exit */ - return 0; - } - else if (size <= alloc * 1.125) { - /* Moderate upsize; overallocate similar to list_resize() */ - alloc = size + (size >> 3) + (size < 9 ? 3 : 6); - } - else { - /* Major upsize; resize up to exact size */ - alloc = size + 1; - } - - if (alloc > ((size_t)-1) / sizeof(Py_UNICODE)) - goto overflow; - new_buf = (Py_UNICODE *)PyMem_Realloc(self->buf, - alloc * sizeof(Py_UNICODE)); - if (new_buf == NULL) { - PyErr_NoMemory(); - return -1; - } - self->buf_size = alloc; - self->buf = new_buf; - - return 0; - - overflow: - PyErr_SetString(PyExc_OverflowError, - "new buffer size too large"); - return -1; -} - -/* Internal routine for writing a whole PyUnicode object to the buffer of a - StringIO object. Returns 0 on success, or -1 on error. */ -static Py_ssize_t -write_str(StringIOObject *self, PyObject *obj) -{ - Py_UNICODE *str; - Py_ssize_t len; - PyObject *decoded = NULL; - assert(self->buf != NULL); - assert(self->pos >= 0); - - if (self->decoder != NULL) { - decoded = _PyIncrementalNewlineDecoder_decode( - self->decoder, obj, 1 /* always final */); - } - else { - decoded = obj; - Py_INCREF(decoded); - } - if (self->writenl) { - PyObject *translated = PyUnicode_Replace( - decoded, _PyIO_str_nl, self->writenl, -1); - Py_DECREF(decoded); - decoded = translated; - } - if (decoded == NULL) - return -1; - - assert(PyUnicode_Check(decoded)); - str = PyUnicode_AS_UNICODE(decoded); - len = PyUnicode_GET_SIZE(decoded); - - assert(len >= 0); - - /* This overflow check is not strictly necessary. However, it avoids us to - deal with funky things like comparing an unsigned and a signed - integer. */ - if (self->pos > PY_SSIZE_T_MAX - len) { - PyErr_SetString(PyExc_OverflowError, - "new position too large"); - goto fail; - } - if (self->pos + len > self->string_size) { - if (resize_buffer(self, self->pos + len) < 0) - goto fail; - } - - if (self->pos > self->string_size) { - /* In case of overseek, pad with null bytes the buffer region between - the end of stream and the current position. - - 0 lo string_size hi - | |<---used--->|<----------available----------->| - | | <--to pad-->|<---to write---> | - 0 buf positon - - */ - memset(self->buf + self->string_size, '\0', - (self->pos - self->string_size) * sizeof(Py_UNICODE)); - } - - /* Copy the data to the internal buffer, overwriting some of the - existing data if self->pos < self->string_size. */ - memcpy(self->buf + self->pos, str, len * sizeof(Py_UNICODE)); - self->pos += len; - - /* Set the new length of the internal string if it has changed. */ - if (self->string_size < self->pos) { - self->string_size = self->pos; - } - - Py_DECREF(decoded); - return 0; - -fail: - Py_XDECREF(decoded); - return -1; -} - -PyDoc_STRVAR(stringio_getvalue_doc, - "Retrieve the entire contents of the object."); - -static PyObject * -stringio_getvalue(StringIOObject *self) -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - return PyUnicode_FromUnicode(self->buf, self->string_size); -} - -PyDoc_STRVAR(stringio_tell_doc, - "Tell the current file position."); - -static PyObject * -stringio_tell(StringIOObject *self) -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - return PyLong_FromSsize_t(self->pos); -} - -PyDoc_STRVAR(stringio_read_doc, - "Read at most n characters, returned as a string.\n" - "\n" - "If the argument is negative or omitted, read until EOF\n" - "is reached. Return an empty string at EOF.\n"); - -static PyObject * -stringio_read(StringIOObject *self, PyObject *args) -{ - Py_ssize_t size, n; - Py_UNICODE *output; - PyObject *arg = Py_None; - - CHECK_INITIALIZED(self); - if (!PyArg_ParseTuple(args, "|O:read", &arg)) - return NULL; - CHECK_CLOSED(self); - - if (PyNumber_Check(arg)) { - size = PyNumber_AsSsize_t(arg, PyExc_OverflowError); - if (size == -1 && PyErr_Occurred()) - return NULL; - } - else if (arg == Py_None) { - /* Read until EOF is reached, by default. */ - size = -1; - } - else { - PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", - Py_TYPE(arg)->tp_name); - return NULL; - } - - /* adjust invalid sizes */ - n = self->string_size - self->pos; - if (size < 0 || size > n) { - size = n; - if (size < 0) - size = 0; - } - - output = self->buf + self->pos; - self->pos += size; - return PyUnicode_FromUnicode(output, size); -} - -/* Internal helper, used by stringio_readline and stringio_iternext */ -static PyObject * -_stringio_readline(StringIOObject *self, Py_ssize_t limit) -{ - Py_UNICODE *start, *end, old_char; - Py_ssize_t len, consumed; - - /* In case of overseek, return the empty string */ - if (self->pos >= self->string_size) - return PyUnicode_FromString(""); - - start = self->buf + self->pos; - if (limit < 0 || limit > self->string_size - self->pos) - limit = self->string_size - self->pos; - - end = start + limit; - old_char = *end; - *end = '\0'; - len = _PyIO_find_line_ending( - self->readtranslate, self->readuniversal, self->readnl, - start, end, &consumed); - *end = old_char; - /* If we haven't found any line ending, we just return everything - (`consumed` is ignored). */ - if (len < 0) - len = limit; - self->pos += len; - return PyUnicode_FromUnicode(start, len); -} - -PyDoc_STRVAR(stringio_readline_doc, - "Read until newline or EOF.\n" - "\n" - "Returns an empty string if EOF is hit immediately.\n"); - -static PyObject * -stringio_readline(StringIOObject *self, PyObject *args) -{ - PyObject *arg = Py_None; - Py_ssize_t limit = -1; - - CHECK_INITIALIZED(self); - if (!PyArg_ParseTuple(args, "|O:readline", &arg)) - return NULL; - CHECK_CLOSED(self); - - if (PyNumber_Check(arg)) { - limit = PyNumber_AsSsize_t(arg, PyExc_OverflowError); - if (limit == -1 && PyErr_Occurred()) - return NULL; - } - else if (arg != Py_None) { - PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", - Py_TYPE(arg)->tp_name); - return NULL; - } - return _stringio_readline(self, limit); -} - -static PyObject * -stringio_iternext(StringIOObject *self) -{ - PyObject *line; - - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - - if (Py_TYPE(self) == &PyStringIO_Type) { - /* Skip method call overhead for speed */ - line = _stringio_readline(self, -1); - } - else { - /* XXX is subclassing StringIO really supported? */ - line = PyObject_CallMethodObjArgs((PyObject *)self, - _PyIO_str_readline, NULL); - if (line && !PyUnicode_Check(line)) { - PyErr_Format(PyExc_IOError, - "readline() should have returned an str object, " - "not '%.200s'", Py_TYPE(line)->tp_name); - Py_DECREF(line); - return NULL; - } - } - - if (line == NULL) - return NULL; - - if (PyUnicode_GET_SIZE(line) == 0) { - /* Reached EOF */ - Py_DECREF(line); - return NULL; - } - - return line; -} - -PyDoc_STRVAR(stringio_truncate_doc, - "Truncate size to pos.\n" - "\n" - "The pos argument defaults to the current file position, as\n" - "returned by tell(). Imply an absolute seek to pos.\n" - "Returns the new absolute position.\n"); - -static PyObject * -stringio_truncate(StringIOObject *self, PyObject *args) -{ - Py_ssize_t size; - PyObject *arg = Py_None; - - CHECK_INITIALIZED(self); - if (!PyArg_ParseTuple(args, "|O:truncate", &arg)) - return NULL; - CHECK_CLOSED(self); - - if (PyNumber_Check(arg)) { - size = PyNumber_AsSsize_t(arg, PyExc_OverflowError); - if (size == -1 && PyErr_Occurred()) - return NULL; - } - else if (arg == Py_None) { - /* Truncate to current position if no argument is passed. */ - size = self->pos; - } - else { - PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", - Py_TYPE(arg)->tp_name); - return NULL; - } - - if (size < 0) { - PyErr_Format(PyExc_ValueError, - "Negative size value %zd", size); - return NULL; - } - - if (size < self->string_size) { - if (resize_buffer(self, size) < 0) - return NULL; - self->string_size = size; - } - self->pos = size; - - return PyLong_FromSsize_t(size); -} - -PyDoc_STRVAR(stringio_seek_doc, - "Change stream position.\n" - "\n" - "Seek to character offset pos relative to position indicated by whence:\n" - " 0 Start of stream (the default). pos should be >= 0;\n" - " 1 Current position - pos must be 0;\n" - " 2 End of stream - pos must be 0.\n" - "Returns the new absolute position.\n"); - -static PyObject * -stringio_seek(StringIOObject *self, PyObject *args) -{ - Py_ssize_t pos; - int mode = 0; - - CHECK_INITIALIZED(self); - if (!PyArg_ParseTuple(args, "n|i:seek", &pos, &mode)) - return NULL; - CHECK_CLOSED(self); - - if (mode != 0 && mode != 1 && mode != 2) { - PyErr_Format(PyExc_ValueError, - "Invalid whence (%i, should be 0, 1 or 2)", mode); - return NULL; - } - else if (pos < 0 && mode == 0) { - PyErr_Format(PyExc_ValueError, - "Negative seek position %zd", pos); - return NULL; - } - else if (mode != 0 && pos != 0) { - PyErr_SetString(PyExc_IOError, - "Can't do nonzero cur-relative seeks"); - return NULL; - } - - /* mode 0: offset relative to beginning of the string. - mode 1: no change to current position. - mode 2: change position to end of file. */ - if (mode == 1) { - pos = self->pos; - } - else if (mode == 2) { - pos = self->string_size; - } - - self->pos = pos; - - return PyLong_FromSsize_t(self->pos); -} - -PyDoc_STRVAR(stringio_write_doc, - "Write string to file.\n" - "\n" - "Returns the number of characters written, which is always equal to\n" - "the length of the string.\n"); - -static PyObject * -stringio_write(StringIOObject *self, PyObject *obj) -{ - Py_ssize_t size; - - CHECK_INITIALIZED(self); - if (!PyUnicode_Check(obj)) { - PyErr_Format(PyExc_TypeError, "string argument expected, got '%s'", - Py_TYPE(obj)->tp_name); - return NULL; - } - CHECK_CLOSED(self); - size = PyUnicode_GET_SIZE(obj); - - if (size > 0 && write_str(self, obj) < 0) - return NULL; - - return PyLong_FromSsize_t(size); -} - -PyDoc_STRVAR(stringio_close_doc, - "Close the IO object. Attempting any further operation after the\n" - "object is closed will raise a ValueError.\n" - "\n" - "This method has no effect if the file is already closed.\n"); - -static PyObject * -stringio_close(StringIOObject *self) -{ - self->closed = 1; - /* Free up some memory */ - if (resize_buffer(self, 0) < 0) - return NULL; - Py_CLEAR(self->readnl); - Py_CLEAR(self->writenl); - Py_CLEAR(self->decoder); - Py_RETURN_NONE; -} - -static int -stringio_traverse(StringIOObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->dict); - return 0; -} - -static int -stringio_clear(StringIOObject *self) -{ - Py_CLEAR(self->dict); - return 0; -} - -static void -stringio_dealloc(StringIOObject *self) -{ - _PyObject_GC_UNTRACK(self); - Py_CLEAR(self->readnl); - Py_CLEAR(self->writenl); - Py_CLEAR(self->decoder); - if (self->buf) - PyMem_Free(self->buf); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - Py_TYPE(self)->tp_free(self); -} - -static PyObject * -stringio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - StringIOObject *self; - - assert(type != NULL && type->tp_alloc != NULL); - self = (StringIOObject *)type->tp_alloc(type, 0); - if (self == NULL) - return NULL; - - self->string_size = 0; - self->pos = 0; - self->buf_size = 0; - self->buf = (Py_UNICODE *)PyMem_Malloc(0); - if (self->buf == NULL) { - Py_DECREF(self); - return PyErr_NoMemory(); - } - - return (PyObject *)self; -} - -static int -stringio_init(StringIOObject *self, PyObject *args, PyObject *kwds) -{ - char *kwlist[] = {"initial_value", "newline", NULL}; - PyObject *value = NULL; - char *newline = "\n"; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oz:__init__", kwlist, - &value, &newline)) - return -1; - - if (newline && newline[0] != '\0' - && !(newline[0] == '\n' && newline[1] == '\0') - && !(newline[0] == '\r' && newline[1] == '\0') - && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) { - PyErr_Format(PyExc_ValueError, - "illegal newline value: %s", newline); - return -1; - } - if (value && value != Py_None && !PyUnicode_Check(value)) { - PyErr_Format(PyExc_ValueError, - "initial_value must be str or None, not %.200s", - Py_TYPE(value)->tp_name); - return -1; - } - - self->ok = 0; - - Py_CLEAR(self->readnl); - Py_CLEAR(self->writenl); - Py_CLEAR(self->decoder); - - if (newline) { - self->readnl = PyUnicode_FromString(newline); - if (self->readnl == NULL) - return -1; - } - self->readuniversal = (newline == NULL || newline[0] == '\0'); - self->readtranslate = (newline == NULL); - /* If newline == "", we don't translate anything. - If newline == "\n" or newline == None, we translate to "\n", which is - a no-op. - (for newline == None, TextIOWrapper translates to os.sepline, but it - is pointless for StringIO) - */ - if (newline != NULL && newline[0] == '\r') { - self->writenl = self->readnl; - Py_INCREF(self->writenl); - } - - if (self->readuniversal) { - self->decoder = PyObject_CallFunction( - (PyObject *)&PyIncrementalNewlineDecoder_Type, - "Oi", Py_None, (int) self->readtranslate); - if (self->decoder == NULL) - return -1; - } - - /* Now everything is set up, resize buffer to size of initial value, - and copy it */ - self->string_size = 0; - if (value && value != Py_None) { - Py_ssize_t len = PyUnicode_GetSize(value); - /* This is a heuristic, for newline translation might change - the string length. */ - if (resize_buffer(self, len) < 0) - return -1; - self->pos = 0; - if (write_str(self, value) < 0) - return -1; - } - else { - if (resize_buffer(self, 0) < 0) - return -1; - } - self->pos = 0; - - self->closed = 0; - self->ok = 1; - return 0; -} - -/* Properties and pseudo-properties */ -static PyObject * -stringio_seekable(StringIOObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self); - Py_RETURN_TRUE; -} - -static PyObject * -stringio_readable(StringIOObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self); - Py_RETURN_TRUE; -} - -static PyObject * -stringio_writable(StringIOObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self); - Py_RETURN_TRUE; -} - -static PyObject * -stringio_buffer(StringIOObject *self, void *context) -{ - PyErr_SetString(IO_STATE->unsupported_operation, - "buffer attribute is unsupported on type StringIO"); - return NULL; -} - -static PyObject * -stringio_closed(StringIOObject *self, void *context) -{ - CHECK_INITIALIZED(self); - return PyBool_FromLong(self->closed); -} - -static PyObject * -stringio_encoding(StringIOObject *self, void *context) -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - Py_RETURN_NONE; -} - -static PyObject * -stringio_errors(StringIOObject *self, void *context) -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - return PyUnicode_FromString("strict"); -} - -static PyObject * -stringio_line_buffering(StringIOObject *self, void *context) -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - Py_RETURN_FALSE; -} - -static PyObject * -stringio_newlines(StringIOObject *self, void *context) -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - if (self->decoder == NULL) - Py_RETURN_NONE; - return PyObject_GetAttr(self->decoder, _PyIO_str_newlines); -} - -static struct PyMethodDef stringio_methods[] = { - {"close", (PyCFunction)stringio_close, METH_NOARGS, stringio_close_doc}, - {"getvalue", (PyCFunction)stringio_getvalue, METH_VARARGS, stringio_getvalue_doc}, - {"read", (PyCFunction)stringio_read, METH_VARARGS, stringio_read_doc}, - {"readline", (PyCFunction)stringio_readline, METH_VARARGS, stringio_readline_doc}, - {"tell", (PyCFunction)stringio_tell, METH_NOARGS, stringio_tell_doc}, - {"truncate", (PyCFunction)stringio_truncate, METH_VARARGS, stringio_truncate_doc}, - {"seek", (PyCFunction)stringio_seek, METH_VARARGS, stringio_seek_doc}, - {"write", (PyCFunction)stringio_write, METH_O, stringio_write_doc}, - - {"seekable", (PyCFunction)stringio_seekable, METH_NOARGS}, - {"readable", (PyCFunction)stringio_readable, METH_NOARGS}, - {"writable", (PyCFunction)stringio_writable, METH_NOARGS}, - {NULL, NULL} /* sentinel */ -}; - -static PyGetSetDef stringio_getset[] = { - {"closed", (getter)stringio_closed, NULL, NULL}, - {"newlines", (getter)stringio_newlines, NULL, NULL}, - /* (following comments straight off of the original Python wrapper:) - XXX Cruft to support the TextIOWrapper API. This would only - be meaningful if StringIO supported the buffer attribute. - Hopefully, a better solution, than adding these pseudo-attributes, - will be found. - */ - {"buffer", (getter)stringio_buffer, NULL, NULL}, - {"encoding", (getter)stringio_encoding, NULL, NULL}, - {"errors", (getter)stringio_errors, NULL, NULL}, - {"line_buffering", (getter)stringio_line_buffering, NULL, NULL}, - {0} -}; - -PyTypeObject PyStringIO_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.StringIO", /*tp_name*/ - sizeof(StringIOObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)stringio_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*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - stringio_doc, /*tp_doc*/ - (traverseproc)stringio_traverse, /*tp_traverse*/ - (inquiry)stringio_clear, /*tp_clear*/ - 0, /*tp_richcompare*/ - offsetof(StringIOObject, weakreflist), /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - (iternextfunc)stringio_iternext, /*tp_iternext*/ - stringio_methods, /*tp_methods*/ - 0, /*tp_members*/ - stringio_getset, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - offsetof(StringIOObject, dict), /*tp_dictoffset*/ - (initproc)stringio_init, /*tp_init*/ - 0, /*tp_alloc*/ - stringio_new, /*tp_new*/ -}; Deleted: python/branches/py3k/Modules/_textio.c ============================================================================== --- python/branches/py3k/Modules/_textio.c Sat Apr 4 21:58:40 2009 +++ (empty file) @@ -1,2420 +0,0 @@ -/* - An implementation of Text I/O as defined by PEP 3116 - "New I/O" - - Classes defined here: TextIOBase, IncrementalNewlineDecoder, TextIOWrapper. - - Written by Amaury Forgeot d'Arc and Antoine Pitrou -*/ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#include "structmember.h" -#include "_iomodule.h" - -/* TextIOBase */ - -PyDoc_STRVAR(TextIOBase_doc, - "Base class for text I/O.\n" - "\n" - "This class provides a character and line based interface to stream\n" - "I/O. There is no readinto method because Python's character strings\n" - "are immutable. There is no public constructor.\n" - ); - -static PyObject * -_unsupported(const char *message) -{ - PyErr_SetString(IO_STATE->unsupported_operation, message); - return NULL; -} - -PyDoc_STRVAR(TextIOBase_read_doc, - "Read at most n characters from stream.\n" - "\n" - "Read from underlying buffer until we have n characters or we hit EOF.\n" - "If n is negative or omitted, read until EOF.\n" - ); - -static PyObject * -TextIOBase_read(PyObject *self, PyObject *args) -{ - return _unsupported("read"); -} - -PyDoc_STRVAR(TextIOBase_readline_doc, - "Read until newline or EOF.\n" - "\n" - "Returns an empty string if EOF is hit immediately.\n" - ); - -static PyObject * -TextIOBase_readline(PyObject *self, PyObject *args) -{ - return _unsupported("readline"); -} - -PyDoc_STRVAR(TextIOBase_write_doc, - "Write string to stream.\n" - "Returns the number of characters written (which is always equal to\n" - "the length of the string).\n" - ); - -static PyObject * -TextIOBase_write(PyObject *self, PyObject *args) -{ - return _unsupported("write"); -} - -PyDoc_STRVAR(TextIOBase_encoding_doc, - "Encoding of the text stream.\n" - "\n" - "Subclasses should override.\n" - ); - -static PyObject * -TextIOBase_encoding_get(PyObject *self, void *context) -{ - Py_RETURN_NONE; -} - -PyDoc_STRVAR(TextIOBase_newlines_doc, - "Line endings translated so far.\n" - "\n" - "Only line endings translated during reading are considered.\n" - "\n" - "Subclasses should override.\n" - ); - -static PyObject * -TextIOBase_newlines_get(PyObject *self, void *context) -{ - Py_RETURN_NONE; -} - - -static PyMethodDef TextIOBase_methods[] = { - {"read", TextIOBase_read, METH_VARARGS, TextIOBase_read_doc}, - {"readline", TextIOBase_readline, METH_VARARGS, TextIOBase_readline_doc}, - {"write", TextIOBase_write, METH_VARARGS, TextIOBase_write_doc}, - {NULL, NULL} -}; - -static PyGetSetDef TextIOBase_getset[] = { - {"encoding", (getter)TextIOBase_encoding_get, NULL, TextIOBase_encoding_doc}, - {"newlines", (getter)TextIOBase_newlines_get, NULL, TextIOBase_newlines_doc}, - {0} -}; - -PyTypeObject PyTextIOBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._TextIOBase", /*tp_name*/ - 0, /*tp_basicsize*/ - 0, /*tp_itemsize*/ - 0, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - TextIOBase_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - TextIOBase_methods, /* tp_methods */ - 0, /* tp_members */ - TextIOBase_getset, /* tp_getset */ - &PyIOBase_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ -}; - - -/* IncrementalNewlineDecoder */ - -PyDoc_STRVAR(IncrementalNewlineDecoder_doc, - "Codec used when reading a file in universal newlines mode. It wraps\n" - "another incremental decoder, translating \\r\\n and \\r into \\n. It also\n" - "records the types of newlines encountered. When used with\n" - "translate=False, it ensures that the newline sequence is returned in\n" - "one piece. When used with decoder=None, it expects unicode strings as\n" - "decode input and translates newlines without first invoking an external\n" - "decoder.\n" - ); - -typedef struct { - PyObject_HEAD - PyObject *decoder; - PyObject *errors; - int pendingcr:1; - int translate:1; - unsigned int seennl:3; -} PyNewLineDecoderObject; - -static int -IncrementalNewlineDecoder_init(PyNewLineDecoderObject *self, - PyObject *args, PyObject *kwds) -{ - PyObject *decoder; - int translate; - PyObject *errors = NULL; - char *kwlist[] = {"decoder", "translate", "errors", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi|O:IncrementalNewlineDecoder", - kwlist, &decoder, &translate, &errors)) - return -1; - - self->decoder = decoder; - Py_INCREF(decoder); - - if (errors == NULL) { - self->errors = PyUnicode_FromString("strict"); - if (self->errors == NULL) - return -1; - } - else { - Py_INCREF(errors); - self->errors = errors; - } - - self->translate = translate; - self->seennl = 0; - self->pendingcr = 0; - - return 0; -} - -static void -IncrementalNewlineDecoder_dealloc(PyNewLineDecoderObject *self) -{ - Py_CLEAR(self->decoder); - Py_CLEAR(self->errors); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -#define SEEN_CR 1 -#define SEEN_LF 2 -#define SEEN_CRLF 4 -#define SEEN_ALL (SEEN_CR | SEEN_LF | SEEN_CRLF) - -PyObject * -_PyIncrementalNewlineDecoder_decode(PyObject *_self, - PyObject *input, int final) -{ - PyObject *output; - Py_ssize_t output_len; - PyNewLineDecoderObject *self = (PyNewLineDecoderObject *) _self; - - if (self->decoder == NULL) { - PyErr_SetString(PyExc_ValueError, - "IncrementalNewlineDecoder.__init__ not called"); - return NULL; - } - - /* decode input (with the eventual \r from a previous pass) */ - if (self->decoder != Py_None) { - output = PyObject_CallMethodObjArgs(self->decoder, - _PyIO_str_decode, input, final ? Py_True : Py_False, NULL); - } - else { - output = input; - Py_INCREF(output); - } - - if (output == NULL) - return NULL; - - if (!PyUnicode_Check(output)) { - PyErr_SetString(PyExc_TypeError, - "decoder should return a string result"); - goto error; - } - - output_len = PyUnicode_GET_SIZE(output); - if (self->pendingcr && (final || output_len > 0)) { - Py_UNICODE *out; - PyObject *modified = PyUnicode_FromUnicode(NULL, output_len + 1); - if (modified == NULL) - goto error; - out = PyUnicode_AS_UNICODE(modified); - out[0] = '\r'; - memcpy(out + 1, PyUnicode_AS_UNICODE(output), - output_len * sizeof(Py_UNICODE)); - Py_DECREF(output); - output = modified; - self->pendingcr = 0; - output_len++; - } - - /* retain last \r even when not translating data: - * then readline() is sure to get \r\n in one pass - */ - if (!final) { - if (output_len > 0 - && PyUnicode_AS_UNICODE(output)[output_len - 1] == '\r') { - - if (Py_REFCNT(output) == 1) { - if (PyUnicode_Resize(&output, output_len - 1) < 0) - goto error; - } - else { - PyObject *modified = PyUnicode_FromUnicode( - PyUnicode_AS_UNICODE(output), - output_len - 1); - if (modified == NULL) - goto error; - Py_DECREF(output); - output = modified; - } - self->pendingcr = 1; - } - } - - /* Record which newlines are read and do newline translation if desired, - all in one pass. */ - { - Py_UNICODE *in_str; - Py_ssize_t len; - int seennl = self->seennl; - int only_lf = 0; - - in_str = PyUnicode_AS_UNICODE(output); - len = PyUnicode_GET_SIZE(output); - - if (len == 0) - return output; - - /* If, up to now, newlines are consistently \n, do a quick check - for the \r *byte* with the libc's optimized memchr. - */ - if (seennl == SEEN_LF || seennl == 0) { - only_lf = (memchr(in_str, '\r', len * sizeof(Py_UNICODE)) == NULL); - } - - if (only_lf) { - /* If not already seen, quick scan for a possible "\n" character. - (there's nothing else to be done, even when in translation mode) - */ - if (seennl == 0 && - memchr(in_str, '\n', len * sizeof(Py_UNICODE)) != NULL) { - Py_UNICODE *s, *end; - s = in_str; - end = in_str + len; - for (;;) { - Py_UNICODE c; - /* Fast loop for non-control characters */ - while (*s > '\n') - s++; - c = *s++; - if (c == '\n') { - seennl |= SEEN_LF; - break; - } - if (s > end) - break; - } - } - /* Finished: we have scanned for newlines, and none of them - need translating */ - } - else if (!self->translate) { - Py_UNICODE *s, *end; - /* We have already seen all newline types, no need to scan again */ - if (seennl == SEEN_ALL) - goto endscan; - s = in_str; - end = in_str + len; - for (;;) { - Py_UNICODE c; - /* Fast loop for non-control characters */ - while (*s > '\r') - s++; - c = *s++; - if (c == '\n') - seennl |= SEEN_LF; - else if (c == '\r') { - if (*s == '\n') { - seennl |= SEEN_CRLF; - s++; - } - else - seennl |= SEEN_CR; - } - if (s > end) - break; - if (seennl == SEEN_ALL) - break; - } - endscan: - ; - } - else { - PyObject *translated = NULL; - Py_UNICODE *out_str; - Py_UNICODE *in, *out, *end; - if (Py_REFCNT(output) != 1) { - /* We could try to optimize this so that we only do a copy - when there is something to translate. On the other hand, - most decoders should only output non-shared strings, i.e. - translation is done in place. */ - translated = PyUnicode_FromUnicode(NULL, len); - if (translated == NULL) - goto error; - assert(Py_REFCNT(translated) == 1); - memcpy(PyUnicode_AS_UNICODE(translated), - PyUnicode_AS_UNICODE(output), - len * sizeof(Py_UNICODE)); - } - else { - translated = output; - } - out_str = PyUnicode_AS_UNICODE(translated); - in = in_str; - out = out_str; - end = in_str + len; - for (;;) { - Py_UNICODE c; - /* Fast loop for non-control characters */ - while ((c = *in++) > '\r') - *out++ = c; - if (c == '\n') { - *out++ = c; - seennl |= SEEN_LF; - continue; - } - if (c == '\r') { - if (*in == '\n') { - in++; - seennl |= SEEN_CRLF; - } - else - seennl |= SEEN_CR; - *out++ = '\n'; - continue; - } - if (in > end) - break; - *out++ = c; - } - if (translated != output) { - Py_DECREF(output); - output = translated; - } - if (out - out_str != len) { - if (PyUnicode_Resize(&output, out - out_str) < 0) - goto error; - } - } - self->seennl |= seennl; - } - - return output; - - error: - Py_DECREF(output); - return NULL; -} - -static PyObject * -IncrementalNewlineDecoder_decode(PyNewLineDecoderObject *self, - PyObject *args, PyObject *kwds) -{ - char *kwlist[] = {"input", "final", NULL}; - PyObject *input; - int final = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:IncrementalNewlineDecoder", - kwlist, &input, &final)) - return NULL; - return _PyIncrementalNewlineDecoder_decode((PyObject *) self, input, final); -} - -static PyObject * -IncrementalNewlineDecoder_getstate(PyNewLineDecoderObject *self, PyObject *args) -{ - PyObject *buffer; - unsigned PY_LONG_LONG flag; - - if (self->decoder != Py_None) { - PyObject *state = PyObject_CallMethodObjArgs(self->decoder, - _PyIO_str_getstate, NULL); - if (state == NULL) - return NULL; - if (!PyArg_Parse(state, "(OK)", &buffer, &flag)) { - Py_DECREF(state); - return NULL; - } - Py_INCREF(buffer); - Py_DECREF(state); - } - else { - buffer = PyBytes_FromString(""); - flag = 0; - } - flag <<= 1; - if (self->pendingcr) - flag |= 1; - return Py_BuildValue("NK", buffer, flag); -} - -static PyObject * -IncrementalNewlineDecoder_setstate(PyNewLineDecoderObject *self, PyObject *state) -{ - PyObject *buffer; - unsigned PY_LONG_LONG flag; - - if (!PyArg_Parse(state, "(OK)", &buffer, &flag)) - return NULL; - - self->pendingcr = (int) flag & 1; - flag >>= 1; - - if (self->decoder != Py_None) - return PyObject_CallMethod(self->decoder, - "setstate", "((OK))", buffer, flag); - else - Py_RETURN_NONE; -} - -static PyObject * -IncrementalNewlineDecoder_reset(PyNewLineDecoderObject *self, PyObject *args) -{ - self->seennl = 0; - self->pendingcr = 0; - if (self->decoder != Py_None) - return PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL); - else - Py_RETURN_NONE; -} - -static PyObject * -IncrementalNewlineDecoder_newlines_get(PyNewLineDecoderObject *self, void *context) -{ - switch (self->seennl) { - case SEEN_CR: - return PyUnicode_FromString("\r"); - case SEEN_LF: - return PyUnicode_FromString("\n"); - case SEEN_CRLF: - return PyUnicode_FromString("\r\n"); - case SEEN_CR | SEEN_LF: - return Py_BuildValue("ss", "\r", "\n"); - case SEEN_CR | SEEN_CRLF: - return Py_BuildValue("ss", "\r", "\r\n"); - case SEEN_LF | SEEN_CRLF: - return Py_BuildValue("ss", "\n", "\r\n"); - case SEEN_CR | SEEN_LF | SEEN_CRLF: - return Py_BuildValue("sss", "\r", "\n", "\r\n"); - default: - Py_RETURN_NONE; - } - -} - - -static PyMethodDef IncrementalNewlineDecoder_methods[] = { - {"decode", (PyCFunction)IncrementalNewlineDecoder_decode, METH_VARARGS|METH_KEYWORDS}, - {"getstate", (PyCFunction)IncrementalNewlineDecoder_getstate, METH_NOARGS}, - {"setstate", (PyCFunction)IncrementalNewlineDecoder_setstate, METH_O}, - {"reset", (PyCFunction)IncrementalNewlineDecoder_reset, METH_NOARGS}, - {0} -}; - -static PyGetSetDef IncrementalNewlineDecoder_getset[] = { - {"newlines", (getter)IncrementalNewlineDecoder_newlines_get, NULL, NULL}, - {0} -}; - -PyTypeObject PyIncrementalNewlineDecoder_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.IncrementalNewlineDecoder", /*tp_name*/ - sizeof(PyNewLineDecoderObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)IncrementalNewlineDecoder_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - IncrementalNewlineDecoder_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /*tp_weaklistoffset*/ - 0, /* tp_iter */ - 0, /* tp_iternext */ - IncrementalNewlineDecoder_methods, /* tp_methods */ - 0, /* tp_members */ - IncrementalNewlineDecoder_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)IncrementalNewlineDecoder_init, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; - - -/* TextIOWrapper */ - -PyDoc_STRVAR(TextIOWrapper_doc, - "Character and line based layer over a BufferedIOBase object, buffer.\n" - "\n" - "encoding gives the name of the encoding that the stream will be\n" - "decoded or encoded with. It defaults to locale.getpreferredencoding.\n" - "\n" - "errors determines the strictness of encoding and decoding (see the\n" - "codecs.register) and defaults to \"strict\".\n" - "\n" - "newline can be None, '', '\\n', '\\r', or '\\r\\n'. It controls the\n" - "handling of line endings. If it is None, universal newlines is\n" - "enabled. With this enabled, on input, the lines endings '\\n', '\\r',\n" - "or '\\r\\n' are translated to '\\n' before being returned to the\n" - "caller. Conversely, on output, '\\n' is translated to the system\n" - "default line seperator, os.linesep. If newline is any other of its\n" - "legal values, that newline becomes the newline when the file is read\n" - "and it is returned untranslated. On output, '\\n' is converted to the\n" - "newline.\n" - "\n" - "If line_buffering is True, a call to flush is implied when a call to\n" - "write contains a newline character." - ); - -typedef PyObject * - (*encodefunc_t)(PyObject *, PyObject *); - -typedef struct -{ - PyObject_HEAD - int ok; /* initialized? */ - Py_ssize_t chunk_size; - PyObject *buffer; - PyObject *encoding; - PyObject *encoder; - PyObject *decoder; - PyObject *readnl; - PyObject *errors; - const char *writenl; /* utf-8 encoded, NULL stands for \n */ - char line_buffering; - char readuniversal; - char readtranslate; - char writetranslate; - char seekable; - char telling; - /* Specialized encoding func (see below) */ - encodefunc_t encodefunc; - - /* Reads and writes are internally buffered in order to speed things up. - However, any read will first flush the write buffer if itsn't empty. - - Please also note that text to be written is first encoded before being - buffered. This is necessary so that encoding errors are immediately - reported to the caller, but it unfortunately means that the - IncrementalEncoder (whose encode() method is always written in Python) - becomes a bottleneck for small writes. - */ - PyObject *decoded_chars; /* buffer for text returned from decoder */ - Py_ssize_t decoded_chars_used; /* offset into _decoded_chars for read() */ - PyObject *pending_bytes; /* list of bytes objects waiting to be - written, or NULL */ - Py_ssize_t pending_bytes_count; - PyObject *snapshot; - /* snapshot is either None, or a tuple (dec_flags, next_input) where - * dec_flags is the second (integer) item of the decoder state and - * next_input is the chunk of input bytes that comes next after the - * snapshot point. We use this to reconstruct decoder states in tell(). - */ - - /* Cache raw object if it's a FileIO object */ - PyObject *raw; - - PyObject *weakreflist; - PyObject *dict; -} PyTextIOWrapperObject; - - -/* A couple of specialized cases in order to bypass the slow incremental - encoding methods for the most popular encodings. */ - -static PyObject * -ascii_encode(PyTextIOWrapperObject *self, PyObject *text) -{ - return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(text), - PyUnicode_GET_SIZE(text), - PyBytes_AS_STRING(self->errors)); -} - -static PyObject * -utf16be_encode(PyTextIOWrapperObject *self, PyObject *text) -{ - return PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(text), - PyUnicode_GET_SIZE(text), - PyBytes_AS_STRING(self->errors), 1); -} - -static PyObject * -utf16le_encode(PyTextIOWrapperObject *self, PyObject *text) -{ - return PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(text), - PyUnicode_GET_SIZE(text), - PyBytes_AS_STRING(self->errors), -1); -} - -static PyObject * -utf16_encode(PyTextIOWrapperObject *self, PyObject *text) -{ - PyObject *res; - res = PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(text), - PyUnicode_GET_SIZE(text), - PyBytes_AS_STRING(self->errors), 0); - if (res == NULL) - return NULL; - /* Next writes will skip the BOM and use native byte ordering */ -#if defined(WORDS_BIGENDIAN) - self->encodefunc = (encodefunc_t) utf16be_encode; -#else - self->encodefunc = (encodefunc_t) utf16le_encode; -#endif - return res; -} - - -static PyObject * -utf8_encode(PyTextIOWrapperObject *self, PyObject *text) -{ - return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(text), - PyUnicode_GET_SIZE(text), - PyBytes_AS_STRING(self->errors)); -} - -static PyObject * -latin1_encode(PyTextIOWrapperObject *self, PyObject *text) -{ - return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(text), - PyUnicode_GET_SIZE(text), - PyBytes_AS_STRING(self->errors)); -} - -/* Map normalized encoding names onto the specialized encoding funcs */ - -typedef struct { - const char *name; - encodefunc_t encodefunc; -} encodefuncentry; - -static encodefuncentry encodefuncs[] = { - {"ascii", (encodefunc_t) ascii_encode}, - {"iso8859-1", (encodefunc_t) latin1_encode}, - {"utf-16-be", (encodefunc_t) utf16be_encode}, - {"utf-16-le", (encodefunc_t) utf16le_encode}, - {"utf-16", (encodefunc_t) utf16_encode}, - {"utf-8", (encodefunc_t) utf8_encode}, - {NULL, NULL} -}; - - -static int -TextIOWrapper_init(PyTextIOWrapperObject *self, PyObject *args, PyObject *kwds) -{ - char *kwlist[] = {"buffer", "encoding", "errors", - "newline", "line_buffering", - NULL}; - PyObject *buffer, *raw; - char *encoding = NULL; - char *errors = NULL; - char *newline = NULL; - int line_buffering = 0; - _PyIO_State *state = IO_STATE; - - PyObject *res; - int r; - - self->ok = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|zzzi:fileio", - kwlist, &buffer, &encoding, &errors, - &newline, &line_buffering)) - return -1; - - if (newline && newline[0] != '\0' - && !(newline[0] == '\n' && newline[1] == '\0') - && !(newline[0] == '\r' && newline[1] == '\0') - && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) { - PyErr_Format(PyExc_ValueError, - "illegal newline value: %s", newline); - return -1; - } - - Py_CLEAR(self->buffer); - Py_CLEAR(self->encoding); - Py_CLEAR(self->encoder); - Py_CLEAR(self->decoder); - Py_CLEAR(self->readnl); - Py_CLEAR(self->decoded_chars); - Py_CLEAR(self->pending_bytes); - Py_CLEAR(self->snapshot); - Py_CLEAR(self->errors); - Py_CLEAR(self->raw); - self->decoded_chars_used = 0; - self->pending_bytes_count = 0; - self->encodefunc = NULL; - - if (encoding == NULL) { - /* Try os.device_encoding(fileno) */ - PyObject *fileno; - fileno = PyObject_CallMethod(buffer, "fileno", NULL); - /* Ignore only AttributeError and UnsupportedOperation */ - if (fileno == NULL) { - if (PyErr_ExceptionMatches(PyExc_AttributeError) || - PyErr_ExceptionMatches(state->unsupported_operation)) { - PyErr_Clear(); - } - else { - goto error; - } - } - else { - self->encoding = PyObject_CallMethod(state->os_module, - "device_encoding", - "N", fileno); - if (self->encoding == NULL) - goto error; - else if (!PyUnicode_Check(self->encoding)) - Py_CLEAR(self->encoding); - } - } - if (encoding == NULL && self->encoding == NULL) { - if (state->locale_module == NULL) { - state->locale_module = PyImport_ImportModule("locale"); - if (state->locale_module == NULL) - goto catch_ImportError; - else - goto use_locale; - } - else { - use_locale: - self->encoding = PyObject_CallMethod( - state->locale_module, "getpreferredencoding", NULL); - if (self->encoding == NULL) { - catch_ImportError: - /* - Importing locale can raise a ImportError because of - _functools, and locale.getpreferredencoding can raise a - ImportError if _locale is not available. These will happen - during module building. - */ - if (PyErr_ExceptionMatches(PyExc_ImportError)) { - PyErr_Clear(); - self->encoding = PyUnicode_FromString("ascii"); - } - else - goto error; - } - else if (!PyUnicode_Check(self->encoding)) - Py_CLEAR(self->encoding); - } - } - if (self->encoding != NULL) - encoding = _PyUnicode_AsString(self->encoding); - else if (encoding != NULL) { - self->encoding = PyUnicode_FromString(encoding); - if (self->encoding == NULL) - goto error; - } - else { - PyErr_SetString(PyExc_IOError, - "could not determine default encoding"); - } - - if (errors == NULL) - errors = "strict"; - self->errors = PyBytes_FromString(errors); - if (self->errors == NULL) - goto error; - - self->chunk_size = 8192; - self->readuniversal = (newline == NULL || newline[0] == '\0'); - self->line_buffering = line_buffering; - self->readtranslate = (newline == NULL); - if (newline) { - self->readnl = PyUnicode_FromString(newline); - if (self->readnl == NULL) - return -1; - } - self->writetranslate = (newline == NULL || newline[0] != '\0'); - if (!self->readuniversal && self->readnl) { - self->writenl = _PyUnicode_AsString(self->readnl); - if (!strcmp(self->writenl, "\n")) - self->writenl = NULL; - } -#ifdef MS_WINDOWS - else - self->writenl = "\r\n"; -#endif - - /* Build the decoder object */ - res = PyObject_CallMethod(buffer, "readable", NULL); - if (res == NULL) - goto error; - r = PyObject_IsTrue(res); - Py_DECREF(res); - if (r == -1) - goto error; - if (r == 1) { - self->decoder = PyCodec_IncrementalDecoder( - encoding, errors); - if (self->decoder == NULL) - goto error; - - if (self->readuniversal) { - PyObject *incrementalDecoder = PyObject_CallFunction( - (PyObject *)&PyIncrementalNewlineDecoder_Type, - "Oi", self->decoder, (int)self->readtranslate); - if (incrementalDecoder == NULL) - goto error; - Py_CLEAR(self->decoder); - self->decoder = incrementalDecoder; - } - } - - /* Build the encoder object */ - res = PyObject_CallMethod(buffer, "writable", NULL); - if (res == NULL) - goto error; - r = PyObject_IsTrue(res); - Py_DECREF(res); - if (r == -1) - goto error; - if (r == 1) { - PyObject *ci; - self->encoder = PyCodec_IncrementalEncoder( - encoding, errors); - if (self->encoder == NULL) - goto error; - /* Get the normalized named of the codec */ - ci = _PyCodec_Lookup(encoding); - if (ci == NULL) - goto error; - res = PyObject_GetAttrString(ci, "name"); - Py_DECREF(ci); - if (res == NULL) - PyErr_Clear(); - else if (PyUnicode_Check(res)) { - encodefuncentry *e = encodefuncs; - while (e->name != NULL) { - if (!PyUnicode_CompareWithASCIIString(res, e->name)) { - self->encodefunc = e->encodefunc; - break; - } - e++; - } - } - Py_XDECREF(res); - } - - self->buffer = buffer; - Py_INCREF(buffer); - - if (Py_TYPE(buffer) == &PyBufferedReader_Type || - Py_TYPE(buffer) == &PyBufferedWriter_Type || - Py_TYPE(buffer) == &PyBufferedRandom_Type) { - raw = PyObject_GetAttrString(buffer, "raw"); - /* Cache the raw FileIO object to speed up 'closed' checks */ - if (raw == NULL) - PyErr_Clear(); - else if (Py_TYPE(raw) == &PyFileIO_Type) - self->raw = raw; - else - Py_DECREF(raw); - } - - res = PyObject_CallMethod(buffer, "seekable", NULL); - if (res == NULL) - goto error; - self->seekable = self->telling = PyObject_IsTrue(res); - Py_DECREF(res); - - self->ok = 1; - return 0; - - error: - return -1; -} - -static int -_TextIOWrapper_clear(PyTextIOWrapperObject *self) -{ - if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0) - return -1; - self->ok = 0; - Py_CLEAR(self->buffer); - Py_CLEAR(self->encoding); - Py_CLEAR(self->encoder); - Py_CLEAR(self->decoder); - Py_CLEAR(self->readnl); - Py_CLEAR(self->decoded_chars); - Py_CLEAR(self->pending_bytes); - Py_CLEAR(self->snapshot); - Py_CLEAR(self->errors); - Py_CLEAR(self->raw); - return 0; -} - -static void -TextIOWrapper_dealloc(PyTextIOWrapperObject *self) -{ - if (_TextIOWrapper_clear(self) < 0) - return; - _PyObject_GC_UNTRACK(self); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *)self); - Py_CLEAR(self->dict); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static int -TextIOWrapper_traverse(PyTextIOWrapperObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->buffer); - Py_VISIT(self->encoding); - Py_VISIT(self->encoder); - Py_VISIT(self->decoder); - Py_VISIT(self->readnl); - Py_VISIT(self->decoded_chars); - Py_VISIT(self->pending_bytes); - Py_VISIT(self->snapshot); - Py_VISIT(self->errors); - Py_VISIT(self->raw); - - Py_VISIT(self->dict); - return 0; -} - -static int -TextIOWrapper_clear(PyTextIOWrapperObject *self) -{ - if (_TextIOWrapper_clear(self) < 0) - return -1; - Py_CLEAR(self->dict); - return 0; -} - -static PyObject * -TextIOWrapper_closed_get(PyTextIOWrapperObject *self, void *context); - -/* This macro takes some shortcuts to make the common case faster. */ -#define CHECK_CLOSED(self) \ - do { \ - int r; \ - PyObject *_res; \ - if (Py_TYPE(self) == &PyTextIOWrapper_Type) { \ - if (self->raw != NULL) \ - r = _PyFileIO_closed(self->raw); \ - else { \ - _res = TextIOWrapper_closed_get(self, NULL); \ - if (_res == NULL) \ - return NULL; \ - r = PyObject_IsTrue(_res); \ - Py_DECREF(_res); \ - if (r < 0) \ - return NULL; \ - } \ - if (r > 0) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on closed file."); \ - return NULL; \ - } \ - } \ - else if (_PyIOBase_checkClosed((PyObject *)self, Py_True) == NULL) \ - return NULL; \ - } while (0) - -#define CHECK_INITIALIZED(self) \ - if (self->ok <= 0) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - return NULL; \ - } - -#define CHECK_INITIALIZED_INT(self) \ - if (self->ok <= 0) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - return -1; \ - } - - -Py_LOCAL_INLINE(const Py_UNICODE *) -findchar(const Py_UNICODE *s, Py_ssize_t size, Py_UNICODE ch) -{ - /* like wcschr, but doesn't stop at NULL characters */ - while (size-- > 0) { - if (*s == ch) - return s; - s++; - } - return NULL; -} - -/* Flush the internal write buffer. This doesn't explicitly flush the - underlying buffered object, though. */ -static int -_TextIOWrapper_writeflush(PyTextIOWrapperObject *self) -{ - PyObject *b, *ret; - - if (self->pending_bytes == NULL) - return 0; - b = _PyBytes_Join(_PyIO_empty_bytes, self->pending_bytes); - if (b == NULL) - return -1; - ret = PyObject_CallMethodObjArgs(self->buffer, - _PyIO_str_write, b, NULL); - Py_DECREF(b); - if (ret == NULL) - return -1; - Py_DECREF(ret); - Py_CLEAR(self->pending_bytes); - self->pending_bytes_count = 0; - return 0; -} - -static PyObject * -TextIOWrapper_write(PyTextIOWrapperObject *self, PyObject *args) -{ - PyObject *ret; - PyObject *text; /* owned reference */ - PyObject *b; - Py_ssize_t textlen; - int haslf = 0; - int needflush = 0; - - CHECK_INITIALIZED(self); - - if (!PyArg_ParseTuple(args, "U:write", &text)) { - return NULL; - } - - CHECK_CLOSED(self); - - Py_INCREF(text); - - textlen = PyUnicode_GetSize(text); - - if ((self->writetranslate && self->writenl != NULL) || self->line_buffering) - if (findchar(PyUnicode_AS_UNICODE(text), - PyUnicode_GET_SIZE(text), '\n')) - haslf = 1; - - if (haslf && self->writetranslate && self->writenl != NULL) { - PyObject *newtext = PyObject_CallMethod( - text, "replace", "ss", "\n", self->writenl); - Py_DECREF(text); - if (newtext == NULL) - return NULL; - text = newtext; - } - - if (self->line_buffering && - (haslf || - findchar(PyUnicode_AS_UNICODE(text), - PyUnicode_GET_SIZE(text), '\r'))) - needflush = 1; - - /* XXX What if we were just reading? */ - if (self->encodefunc != NULL) - b = (*self->encodefunc)((PyObject *) self, text); - else - b = PyObject_CallMethodObjArgs(self->encoder, - _PyIO_str_encode, text, NULL); - Py_DECREF(text); - if (b == NULL) - return NULL; - - if (self->pending_bytes == NULL) { - self->pending_bytes = PyList_New(0); - if (self->pending_bytes == NULL) { - Py_DECREF(b); - return NULL; - } - self->pending_bytes_count = 0; - } - if (PyList_Append(self->pending_bytes, b) < 0) { - Py_DECREF(b); - return NULL; - } - self->pending_bytes_count += PyBytes_GET_SIZE(b); - Py_DECREF(b); - if (self->pending_bytes_count > self->chunk_size || needflush) { - if (_TextIOWrapper_writeflush(self) < 0) - return NULL; - } - - if (needflush) { - ret = PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_flush, NULL); - if (ret == NULL) - return NULL; - Py_DECREF(ret); - } - - Py_CLEAR(self->snapshot); - - if (self->decoder) { - ret = PyObject_CallMethod(self->decoder, "reset", NULL); - if (ret == NULL) - return NULL; - Py_DECREF(ret); - } - - return PyLong_FromSsize_t(textlen); -} - -/* Steal a reference to chars and store it in the decoded_char buffer; - */ -static void -TextIOWrapper_set_decoded_chars(PyTextIOWrapperObject *self, PyObject *chars) -{ - Py_CLEAR(self->decoded_chars); - self->decoded_chars = chars; - self->decoded_chars_used = 0; -} - -static PyObject * -TextIOWrapper_get_decoded_chars(PyTextIOWrapperObject *self, Py_ssize_t n) -{ - PyObject *chars; - Py_ssize_t avail; - - if (self->decoded_chars == NULL) - return PyUnicode_FromStringAndSize(NULL, 0); - - avail = (PyUnicode_GET_SIZE(self->decoded_chars) - - self->decoded_chars_used); - - assert(avail >= 0); - - if (n < 0 || n > avail) - n = avail; - - if (self->decoded_chars_used > 0 || n < avail) { - chars = PyUnicode_FromUnicode( - PyUnicode_AS_UNICODE(self->decoded_chars) - + self->decoded_chars_used, n); - if (chars == NULL) - return NULL; - } - else { - chars = self->decoded_chars; - Py_INCREF(chars); - } - - self->decoded_chars_used += n; - return chars; -} - -/* Read and decode the next chunk of data from the BufferedReader. - */ -static int -TextIOWrapper_read_chunk(PyTextIOWrapperObject *self) -{ - PyObject *dec_buffer = NULL; - PyObject *dec_flags = NULL; - PyObject *input_chunk = NULL; - PyObject *decoded_chars, *chunk_size; - int eof; - - /* The return value is True unless EOF was reached. The decoded string is - * placed in self._decoded_chars (replacing its previous value). The - * entire input chunk is sent to the decoder, though some of it may remain - * buffered in the decoder, yet to be converted. - */ - - if (self->decoder == NULL) { - PyErr_SetString(PyExc_ValueError, "no decoder"); - return -1; - } - - if (self->telling) { - /* To prepare for tell(), we need to snapshot a point in the file - * where the decoder's input buffer is empty. - */ - - PyObject *state = PyObject_CallMethodObjArgs(self->decoder, - _PyIO_str_getstate, NULL); - if (state == NULL) - return -1; - /* Given this, we know there was a valid snapshot point - * len(dec_buffer) bytes ago with decoder state (b'', dec_flags). - */ - if (PyArg_Parse(state, "(OO)", &dec_buffer, &dec_flags) < 0) { - Py_DECREF(state); - return -1; - } - Py_INCREF(dec_buffer); - Py_INCREF(dec_flags); - Py_DECREF(state); - } - - /* Read a chunk, decode it, and put the result in self._decoded_chars. */ - chunk_size = PyLong_FromSsize_t(self->chunk_size); - if (chunk_size == NULL) - goto fail; - input_chunk = PyObject_CallMethodObjArgs(self->buffer, - _PyIO_str_read1, chunk_size, NULL); - Py_DECREF(chunk_size); - if (input_chunk == NULL) - goto fail; - assert(PyBytes_Check(input_chunk)); - - eof = (PyBytes_Size(input_chunk) == 0); - - if (Py_TYPE(self->decoder) == &PyIncrementalNewlineDecoder_Type) { - decoded_chars = _PyIncrementalNewlineDecoder_decode( - self->decoder, input_chunk, eof); - } - else { - decoded_chars = PyObject_CallMethodObjArgs(self->decoder, - _PyIO_str_decode, input_chunk, eof ? Py_True : Py_False, NULL); - } - - /* TODO sanity check: isinstance(decoded_chars, unicode) */ - if (decoded_chars == NULL) - goto fail; - TextIOWrapper_set_decoded_chars(self, decoded_chars); - if (PyUnicode_GET_SIZE(decoded_chars) > 0) - eof = 0; - - if (self->telling) { - /* At the snapshot point, len(dec_buffer) bytes before the read, the - * next input to be decoded is dec_buffer + input_chunk. - */ - PyObject *next_input = PyNumber_Add(dec_buffer, input_chunk); - if (next_input == NULL) - goto fail; - assert (PyBytes_Check(next_input)); - Py_DECREF(dec_buffer); - Py_CLEAR(self->snapshot); - self->snapshot = Py_BuildValue("NN", dec_flags, next_input); - } - Py_DECREF(input_chunk); - - return (eof == 0); - - fail: - Py_XDECREF(dec_buffer); - Py_XDECREF(dec_flags); - Py_XDECREF(input_chunk); - return -1; -} - -static PyObject * -TextIOWrapper_read(PyTextIOWrapperObject *self, PyObject *args) -{ - Py_ssize_t n = -1; - PyObject *result = NULL, *chunks = NULL; - - CHECK_INITIALIZED(self); - - if (!PyArg_ParseTuple(args, "|n:read", &n)) - return NULL; - - CHECK_CLOSED(self); - - if (self->decoder == NULL) { - PyErr_SetString(PyExc_IOError, "not readable"); - return NULL; - } - - if (_TextIOWrapper_writeflush(self) < 0) - return NULL; - - if (n < 0) { - /* Read everything */ - PyObject *bytes = PyObject_CallMethod(self->buffer, "read", NULL); - PyObject *decoded; - if (bytes == NULL) - goto fail; - decoded = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_decode, - bytes, Py_True, NULL); - Py_DECREF(bytes); - if (decoded == NULL) - goto fail; - - result = TextIOWrapper_get_decoded_chars(self, -1); - - if (result == NULL) { - Py_DECREF(decoded); - return NULL; - } - - PyUnicode_AppendAndDel(&result, decoded); - if (result == NULL) - goto fail; - - Py_CLEAR(self->snapshot); - return result; - } - else { - int res = 1; - Py_ssize_t remaining = n; - - result = TextIOWrapper_get_decoded_chars(self, n); - if (result == NULL) - goto fail; - remaining -= PyUnicode_GET_SIZE(result); - - /* Keep reading chunks until we have n characters to return */ - while (remaining > 0) { - res = TextIOWrapper_read_chunk(self); - if (res < 0) - goto fail; - if (res == 0) /* EOF */ - break; - if (chunks == NULL) { - chunks = PyList_New(0); - if (chunks == NULL) - goto fail; - } - if (PyList_Append(chunks, result) < 0) - goto fail; - Py_DECREF(result); - result = TextIOWrapper_get_decoded_chars(self, remaining); - if (result == NULL) - goto fail; - remaining -= PyUnicode_GET_SIZE(result); - } - if (chunks != NULL) { - if (result != NULL && PyList_Append(chunks, result) < 0) - goto fail; - Py_CLEAR(result); - result = PyUnicode_Join(_PyIO_empty_str, chunks); - if (result == NULL) - goto fail; - Py_CLEAR(chunks); - } - return result; - } - fail: - Py_XDECREF(result); - Py_XDECREF(chunks); - return NULL; -} - - -/* NOTE: `end` must point to the real end of the Py_UNICODE storage, - that is to the NUL character. Otherwise the function will produce - incorrect results. */ -static Py_UNICODE * -find_control_char(Py_UNICODE *start, Py_UNICODE *end, Py_UNICODE ch) -{ - Py_UNICODE *s = start; - for (;;) { - while (*s > ch) - s++; - if (*s == ch) - return s; - if (s == end) - return NULL; - s++; - } -} - -Py_ssize_t -_PyIO_find_line_ending( - int translated, int universal, PyObject *readnl, - Py_UNICODE *start, Py_UNICODE *end, Py_ssize_t *consumed) -{ - Py_ssize_t len = end - start; - - if (translated) { - /* Newlines are already translated, only search for \n */ - Py_UNICODE *pos = find_control_char(start, end, '\n'); - if (pos != NULL) - return pos - start + 1; - else { - *consumed = len; - return -1; - } - } - else if (universal) { - /* Universal newline search. Find any of \r, \r\n, \n - * The decoder ensures that \r\n are not split in two pieces - */ - Py_UNICODE *s = start; - for (;;) { - Py_UNICODE ch; - /* Fast path for non-control chars. The loop always ends - since the Py_UNICODE storage is NUL-terminated. */ - while (*s > '\r') - s++; - if (s >= end) { - *consumed = len; - return -1; - } - ch = *s++; - if (ch == '\n') - return s - start; - if (ch == '\r') { - if (*s == '\n') - return s - start + 1; - else - return s - start; - } - } - } - else { - /* Non-universal mode. */ - Py_ssize_t readnl_len = PyUnicode_GET_SIZE(readnl); - Py_UNICODE *nl = PyUnicode_AS_UNICODE(readnl); - if (readnl_len == 1) { - Py_UNICODE *pos = find_control_char(start, end, nl[0]); - if (pos != NULL) - return pos - start + 1; - *consumed = len; - return -1; - } - else { - Py_UNICODE *s = start; - Py_UNICODE *e = end - readnl_len + 1; - Py_UNICODE *pos; - if (e < s) - e = s; - while (s < e) { - Py_ssize_t i; - Py_UNICODE *pos = find_control_char(s, end, nl[0]); - if (pos == NULL || pos >= e) - break; - for (i = 1; i < readnl_len; i++) { - if (pos[i] != nl[i]) - break; - } - if (i == readnl_len) - return pos - start + readnl_len; - s = pos + 1; - } - pos = find_control_char(e, end, nl[0]); - if (pos == NULL) - *consumed = len; - else - *consumed = pos - start; - return -1; - } - } -} - -static PyObject * -_TextIOWrapper_readline(PyTextIOWrapperObject *self, Py_ssize_t limit) -{ - PyObject *line = NULL, *chunks = NULL, *remaining = NULL; - Py_ssize_t start, endpos, chunked, offset_to_buffer; - int res; - - CHECK_CLOSED(self); - - if (_TextIOWrapper_writeflush(self) < 0) - return NULL; - - chunked = 0; - - while (1) { - Py_UNICODE *ptr; - Py_ssize_t line_len; - Py_ssize_t consumed = 0; - - /* First, get some data if necessary */ - res = 1; - while (!self->decoded_chars || - !PyUnicode_GET_SIZE(self->decoded_chars)) { - res = TextIOWrapper_read_chunk(self); - if (res < 0) - goto error; - if (res == 0) - break; - } - if (res == 0) { - /* end of file */ - TextIOWrapper_set_decoded_chars(self, NULL); - Py_CLEAR(self->snapshot); - start = endpos = offset_to_buffer = 0; - break; - } - - if (remaining == NULL) { - line = self->decoded_chars; - start = self->decoded_chars_used; - offset_to_buffer = 0; - Py_INCREF(line); - } - else { - assert(self->decoded_chars_used == 0); - line = PyUnicode_Concat(remaining, self->decoded_chars); - start = 0; - offset_to_buffer = PyUnicode_GET_SIZE(remaining); - Py_CLEAR(remaining); - if (line == NULL) - goto error; - } - - ptr = PyUnicode_AS_UNICODE(line); - line_len = PyUnicode_GET_SIZE(line); - - endpos = _PyIO_find_line_ending( - self->readtranslate, self->readuniversal, self->readnl, - ptr + start, ptr + line_len, &consumed); - if (endpos >= 0) { - endpos += start; - if (limit >= 0 && (endpos - start) + chunked >= limit) - endpos = start + limit - chunked; - break; - } - - /* We can put aside up to `endpos` */ - endpos = consumed + start; - if (limit >= 0 && (endpos - start) + chunked >= limit) { - /* Didn't find line ending, but reached length limit */ - endpos = start + limit - chunked; - break; - } - - if (endpos > start) { - /* No line ending seen yet - put aside current data */ - PyObject *s; - if (chunks == NULL) { - chunks = PyList_New(0); - if (chunks == NULL) - goto error; - } - s = PyUnicode_FromUnicode(ptr + start, endpos - start); - if (s == NULL) - goto error; - if (PyList_Append(chunks, s) < 0) { - Py_DECREF(s); - goto error; - } - chunked += PyUnicode_GET_SIZE(s); - Py_DECREF(s); - } - /* There may be some remaining bytes we'll have to prepend to the - next chunk of data */ - if (endpos < line_len) { - remaining = PyUnicode_FromUnicode( - ptr + endpos, line_len - endpos); - if (remaining == NULL) - goto error; - } - Py_CLEAR(line); - /* We have consumed the buffer */ - TextIOWrapper_set_decoded_chars(self, NULL); - } - - if (line != NULL) { - /* Our line ends in the current buffer */ - self->decoded_chars_used = endpos - offset_to_buffer; - if (start > 0 || endpos < PyUnicode_GET_SIZE(line)) { - if (start == 0 && Py_REFCNT(line) == 1) { - if (PyUnicode_Resize(&line, endpos) < 0) - goto error; - } - else { - PyObject *s = PyUnicode_FromUnicode( - PyUnicode_AS_UNICODE(line) + start, endpos - start); - Py_CLEAR(line); - if (s == NULL) - goto error; - line = s; - } - } - } - if (remaining != NULL) { - if (chunks == NULL) { - chunks = PyList_New(0); - if (chunks == NULL) - goto error; - } - if (PyList_Append(chunks, remaining) < 0) - goto error; - Py_CLEAR(remaining); - } - if (chunks != NULL) { - if (line != NULL && PyList_Append(chunks, line) < 0) - goto error; - Py_CLEAR(line); - line = PyUnicode_Join(_PyIO_empty_str, chunks); - if (line == NULL) - goto error; - Py_DECREF(chunks); - } - if (line == NULL) - line = PyUnicode_FromStringAndSize(NULL, 0); - - return line; - - error: - Py_XDECREF(chunks); - Py_XDECREF(remaining); - Py_XDECREF(line); - return NULL; -} - -static PyObject * -TextIOWrapper_readline(PyTextIOWrapperObject *self, PyObject *args) -{ - Py_ssize_t limit = -1; - - CHECK_INITIALIZED(self); - if (!PyArg_ParseTuple(args, "|n:readline", &limit)) { - return NULL; - } - return _TextIOWrapper_readline(self, limit); -} - -/* Seek and Tell */ - -typedef struct { - Py_off_t start_pos; - int dec_flags; - int bytes_to_feed; - int chars_to_skip; - char need_eof; -} CookieStruct; - -/* - To speed up cookie packing/unpacking, we store the fields in a temporary - string and call _PyLong_FromByteArray() or _PyLong_AsByteArray (resp.). - The following macros define at which offsets in the intermediary byte - string the various CookieStruct fields will be stored. - */ - -#define COOKIE_BUF_LEN (sizeof(Py_off_t) + 3 * sizeof(int) + sizeof(char)) - -#if defined(WORDS_BIGENDIAN) - -# define IS_LITTLE_ENDIAN 0 - -/* We want the least significant byte of start_pos to also be the least - significant byte of the cookie, which means that in big-endian mode we - must copy the fields in reverse order. */ - -# define OFF_START_POS (sizeof(char) + 3 * sizeof(int)) -# define OFF_DEC_FLAGS (sizeof(char) + 2 * sizeof(int)) -# define OFF_BYTES_TO_FEED (sizeof(char) + sizeof(int)) -# define OFF_CHARS_TO_SKIP (sizeof(char)) -# define OFF_NEED_EOF 0 - -#else - -# define IS_LITTLE_ENDIAN 1 - -/* Little-endian mode: the least significant byte of start_pos will - naturally end up the least significant byte of the cookie. */ - -# define OFF_START_POS 0 -# define OFF_DEC_FLAGS (sizeof(Py_off_t)) -# define OFF_BYTES_TO_FEED (sizeof(Py_off_t) + sizeof(int)) -# define OFF_CHARS_TO_SKIP (sizeof(Py_off_t) + 2 * sizeof(int)) -# define OFF_NEED_EOF (sizeof(Py_off_t) + 3 * sizeof(int)) - -#endif - -static int -TextIOWrapper_parseCookie(CookieStruct *cookie, PyObject *cookieObj) -{ - unsigned char buffer[COOKIE_BUF_LEN]; - PyLongObject *cookieLong = (PyLongObject *)PyNumber_Long(cookieObj); - if (cookieLong == NULL) - return -1; - - if (_PyLong_AsByteArray(cookieLong, buffer, sizeof(buffer), - IS_LITTLE_ENDIAN, 0) < 0) { - Py_DECREF(cookieLong); - return -1; - } - Py_DECREF(cookieLong); - - memcpy(&cookie->start_pos, buffer + OFF_START_POS, sizeof(cookie->start_pos)); - memcpy(&cookie->dec_flags, buffer + OFF_DEC_FLAGS, sizeof(cookie->dec_flags)); - memcpy(&cookie->bytes_to_feed, buffer + OFF_BYTES_TO_FEED, sizeof(cookie->bytes_to_feed)); - memcpy(&cookie->chars_to_skip, buffer + OFF_CHARS_TO_SKIP, sizeof(cookie->chars_to_skip)); - memcpy(&cookie->need_eof, buffer + OFF_NEED_EOF, sizeof(cookie->need_eof)); - - return 0; -} - -static PyObject * -TextIOWrapper_buildCookie(CookieStruct *cookie) -{ - unsigned char buffer[COOKIE_BUF_LEN]; - - memcpy(buffer + OFF_START_POS, &cookie->start_pos, sizeof(cookie->start_pos)); - memcpy(buffer + OFF_DEC_FLAGS, &cookie->dec_flags, sizeof(cookie->dec_flags)); - memcpy(buffer + OFF_BYTES_TO_FEED, &cookie->bytes_to_feed, sizeof(cookie->bytes_to_feed)); - memcpy(buffer + OFF_CHARS_TO_SKIP, &cookie->chars_to_skip, sizeof(cookie->chars_to_skip)); - memcpy(buffer + OFF_NEED_EOF, &cookie->need_eof, sizeof(cookie->need_eof)); - - return _PyLong_FromByteArray(buffer, sizeof(buffer), IS_LITTLE_ENDIAN, 0); -} -#undef IS_LITTLE_ENDIAN - -static int -_TextIOWrapper_decoder_setstate(PyTextIOWrapperObject *self, - CookieStruct *cookie) -{ - PyObject *res; - /* When seeking to the start of the stream, we call decoder.reset() - rather than decoder.getstate(). - This is for a few decoders such as utf-16 for which the state value - at start is not (b"", 0) but e.g. (b"", 2) (meaning, in the case of - utf-16, that we are expecting a BOM). - */ - if (cookie->start_pos == 0 && cookie->dec_flags == 0) - res = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL); - else - res = PyObject_CallMethod(self->decoder, "setstate", - "((yi))", "", cookie->dec_flags); - if (res == NULL) - return -1; - Py_DECREF(res); - return 0; -} - -static PyObject * -TextIOWrapper_seek(PyTextIOWrapperObject *self, PyObject *args) -{ - PyObject *cookieObj, *posobj; - CookieStruct cookie; - int whence = 0; - static PyObject *zero = NULL; - PyObject *res; - int cmp; - - CHECK_INITIALIZED(self); - - if (zero == NULL) { - zero = PyLong_FromLong(0L); - if (zero == NULL) - return NULL; - } - - if (!PyArg_ParseTuple(args, "O|i:seek", &cookieObj, &whence)) - return NULL; - CHECK_CLOSED(self); - - Py_INCREF(cookieObj); - - if (!self->seekable) { - PyErr_SetString(PyExc_IOError, - "underlying stream is not seekable"); - goto fail; - } - - if (whence == 1) { - /* seek relative to current position */ - cmp = PyObject_RichCompareBool(cookieObj, zero, Py_EQ); - if (cmp < 0) - goto fail; - - if (cmp == 0) { - PyErr_SetString(PyExc_IOError, - "can't do nonzero cur-relative seeks"); - goto fail; - } - - /* Seeking to the current position should attempt to - * sync the underlying buffer with the current position. - */ - Py_DECREF(cookieObj); - cookieObj = PyObject_CallMethod((PyObject *)self, "tell", NULL); - if (cookieObj == NULL) - goto fail; - } - else if (whence == 2) { - /* seek relative to end of file */ - - cmp = PyObject_RichCompareBool(cookieObj, zero, Py_EQ); - if (cmp < 0) - goto fail; - - if (cmp == 0) { - PyErr_SetString(PyExc_IOError, - "can't do nonzero end-relative seeks"); - goto fail; - } - - res = PyObject_CallMethod((PyObject *)self, "flush", NULL); - if (res == NULL) - goto fail; - Py_DECREF(res); - - TextIOWrapper_set_decoded_chars(self, NULL); - Py_CLEAR(self->snapshot); - if (self->decoder) { - res = PyObject_CallMethod(self->decoder, "reset", NULL); - if (res == NULL) - goto fail; - Py_DECREF(res); - } - - res = PyObject_CallMethod(self->buffer, "seek", "ii", 0, 2); - Py_XDECREF(cookieObj); - return res; - } - else if (whence != 0) { - PyErr_Format(PyExc_ValueError, - "invalid whence (%d, should be 0, 1 or 2)", whence); - goto fail; - } - - cmp = PyObject_RichCompareBool(cookieObj, zero, Py_LT); - if (cmp < 0) - goto fail; - - if (cmp == 1) { - PyErr_Format(PyExc_ValueError, - "negative seek position %R", cookieObj); - goto fail; - } - - res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL); - if (res == NULL) - goto fail; - Py_DECREF(res); - - /* The strategy of seek() is to go back to the safe start point - * and replay the effect of read(chars_to_skip) from there. - */ - if (TextIOWrapper_parseCookie(&cookie, cookieObj) < 0) - goto fail; - - /* Seek back to the safe start point. */ - posobj = PyLong_FromOff_t(cookie.start_pos); - if (posobj == NULL) - goto fail; - res = PyObject_CallMethodObjArgs(self->buffer, - _PyIO_str_seek, posobj, NULL); - Py_DECREF(posobj); - if (res == NULL) - goto fail; - Py_DECREF(res); - - TextIOWrapper_set_decoded_chars(self, NULL); - Py_CLEAR(self->snapshot); - - /* Restore the decoder to its state from the safe start point. */ - if (self->decoder) { - if (_TextIOWrapper_decoder_setstate(self, &cookie) < 0) - goto fail; - } - - if (cookie.chars_to_skip) { - /* Just like _read_chunk, feed the decoder and save a snapshot. */ - PyObject *input_chunk = PyObject_CallMethod( - self->buffer, "read", "i", cookie.bytes_to_feed); - PyObject *decoded; - - if (input_chunk == NULL) - goto fail; - - assert (PyBytes_Check(input_chunk)); - - self->snapshot = Py_BuildValue("iN", cookie.dec_flags, input_chunk); - if (self->snapshot == NULL) { - Py_DECREF(input_chunk); - goto fail; - } - - decoded = PyObject_CallMethod(self->decoder, "decode", - "Oi", input_chunk, (int)cookie.need_eof); - - if (decoded == NULL) - goto fail; - - TextIOWrapper_set_decoded_chars(self, decoded); - - /* Skip chars_to_skip of the decoded characters. */ - if (PyUnicode_GetSize(self->decoded_chars) < cookie.chars_to_skip) { - PyErr_SetString(PyExc_IOError, "can't restore logical file position"); - goto fail; - } - self->decoded_chars_used = cookie.chars_to_skip; - } - else { - self->snapshot = Py_BuildValue("iy", cookie.dec_flags, ""); - if (self->snapshot == NULL) - goto fail; - } - - return cookieObj; - fail: - Py_XDECREF(cookieObj); - return NULL; - -} - -static PyObject * -TextIOWrapper_tell(PyTextIOWrapperObject *self, PyObject *args) -{ - PyObject *res; - PyObject *posobj = NULL; - CookieStruct cookie = {0,0,0,0,0}; - PyObject *next_input; - Py_ssize_t chars_to_skip, chars_decoded; - PyObject *saved_state = NULL; - char *input, *input_end; - - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - - if (!self->seekable) { - PyErr_SetString(PyExc_IOError, - "underlying stream is not seekable"); - goto fail; - } - if (!self->telling) { - PyErr_SetString(PyExc_IOError, - "telling position disabled by next() call"); - goto fail; - } - - if (_TextIOWrapper_writeflush(self) < 0) - return NULL; - res = PyObject_CallMethod((PyObject *)self, "flush", NULL); - if (res == NULL) - goto fail; - Py_DECREF(res); - - posobj = PyObject_CallMethod(self->buffer, "tell", NULL); - if (posobj == NULL) - goto fail; - - if (self->decoder == NULL || self->snapshot == NULL) { - assert (self->decoded_chars == NULL || PyUnicode_GetSize(self->decoded_chars) == 0); - return posobj; - } - -#if defined(HAVE_LARGEFILE_SUPPORT) - cookie.start_pos = PyLong_AsLongLong(posobj); -#else - cookie.start_pos = PyLong_AsLong(posobj); -#endif - if (PyErr_Occurred()) - goto fail; - - /* Skip backward to the snapshot point (see _read_chunk). */ - if (!PyArg_Parse(self->snapshot, "(iO)", &cookie.dec_flags, &next_input)) - goto fail; - - assert (PyBytes_Check(next_input)); - - cookie.start_pos -= PyBytes_GET_SIZE(next_input); - - /* How many decoded characters have been used up since the snapshot? */ - if (self->decoded_chars_used == 0) { - /* We haven't moved from the snapshot point. */ - Py_DECREF(posobj); - return TextIOWrapper_buildCookie(&cookie); - } - - chars_to_skip = self->decoded_chars_used; - - /* Starting from the snapshot position, we will walk the decoder - * forward until it gives us enough decoded characters. - */ - saved_state = PyObject_CallMethodObjArgs(self->decoder, - _PyIO_str_getstate, NULL); - if (saved_state == NULL) - goto fail; - - /* Note our initial start point. */ - if (_TextIOWrapper_decoder_setstate(self, &cookie) < 0) - goto fail; - - /* Feed the decoder one byte at a time. As we go, note the - * nearest "safe start point" before the current location - * (a point where the decoder has nothing buffered, so seek() - * can safely start from there and advance to this location). - */ - chars_decoded = 0; - input = PyBytes_AS_STRING(next_input); - input_end = input + PyBytes_GET_SIZE(next_input); - while (input < input_end) { - PyObject *state; - char *dec_buffer; - Py_ssize_t dec_buffer_len; - int dec_flags; - - PyObject *decoded = PyObject_CallMethod( - self->decoder, "decode", "y#", input, 1); - if (decoded == NULL) - goto fail; - assert (PyUnicode_Check(decoded)); - chars_decoded += PyUnicode_GET_SIZE(decoded); - Py_DECREF(decoded); - - cookie.bytes_to_feed += 1; - - state = PyObject_CallMethodObjArgs(self->decoder, - _PyIO_str_getstate, NULL); - if (state == NULL) - goto fail; - if (!PyArg_Parse(state, "(y#i)", &dec_buffer, &dec_buffer_len, &dec_flags)) { - Py_DECREF(state); - goto fail; - } - Py_DECREF(state); - - if (dec_buffer_len == 0 && chars_decoded <= chars_to_skip) { - /* Decoder buffer is empty, so this is a safe start point. */ - cookie.start_pos += cookie.bytes_to_feed; - chars_to_skip -= chars_decoded; - cookie.dec_flags = dec_flags; - cookie.bytes_to_feed = 0; - chars_decoded = 0; - } - if (chars_decoded >= chars_to_skip) - break; - input++; - } - if (input == input_end) { - /* We didn't get enough decoded data; signal EOF to get more. */ - PyObject *decoded = PyObject_CallMethod( - self->decoder, "decode", "yi", "", /* final = */ 1); - if (decoded == NULL) - goto fail; - assert (PyUnicode_Check(decoded)); - chars_decoded += PyUnicode_GET_SIZE(decoded); - Py_DECREF(decoded); - cookie.need_eof = 1; - - if (chars_decoded < chars_to_skip) { - PyErr_SetString(PyExc_IOError, - "can't reconstruct logical file position"); - goto fail; - } - } - - /* finally */ - Py_XDECREF(posobj); - res = PyObject_CallMethod(self->decoder, "setstate", "(O)", saved_state); - Py_DECREF(saved_state); - if (res == NULL) - return NULL; - Py_DECREF(res); - - /* The returned cookie corresponds to the last safe start point. */ - cookie.chars_to_skip = Py_SAFE_DOWNCAST(chars_to_skip, Py_ssize_t, int); - return TextIOWrapper_buildCookie(&cookie); - - fail: - Py_XDECREF(posobj); - if (saved_state) { - PyObject *type, *value, *traceback; - PyErr_Fetch(&type, &value, &traceback); - - res = PyObject_CallMethod(self->decoder, "setstate", "(O)", saved_state); - Py_DECREF(saved_state); - if (res == NULL) - return NULL; - Py_DECREF(res); - - PyErr_Restore(type, value, traceback); - } - return NULL; -} - -static PyObject * -TextIOWrapper_truncate(PyTextIOWrapperObject *self, PyObject *args) -{ - PyObject *pos = Py_None; - PyObject *res; - - CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) { - return NULL; - } - - res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_flush, NULL); - if (res == NULL) - return NULL; - Py_DECREF(res); - - if (pos != Py_None) { - res = PyObject_CallMethodObjArgs((PyObject *) self, - _PyIO_str_seek, pos, NULL); - if (res == NULL) - return NULL; - Py_DECREF(res); - } - - return PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_truncate, NULL); -} - -static PyObject * -TextIOWrapper_repr(PyTextIOWrapperObject *self) -{ - CHECK_INITIALIZED(self); - return PyUnicode_FromFormat("", self->encoding); -} - - -/* Inquiries */ - -static PyObject * -TextIOWrapper_fileno(PyTextIOWrapperObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self); - return PyObject_CallMethod(self->buffer, "fileno", NULL); -} - -static PyObject * -TextIOWrapper_seekable(PyTextIOWrapperObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self); - return PyObject_CallMethod(self->buffer, "seekable", NULL); -} - -static PyObject * -TextIOWrapper_readable(PyTextIOWrapperObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self); - return PyObject_CallMethod(self->buffer, "readable", NULL); -} - -static PyObject * -TextIOWrapper_writable(PyTextIOWrapperObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self); - return PyObject_CallMethod(self->buffer, "writable", NULL); -} - -static PyObject * -TextIOWrapper_isatty(PyTextIOWrapperObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self); - return PyObject_CallMethod(self->buffer, "isatty", NULL); -} - -static PyObject * -TextIOWrapper_flush(PyTextIOWrapperObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - self->telling = self->seekable; - if (_TextIOWrapper_writeflush(self) < 0) - return NULL; - return PyObject_CallMethod(self->buffer, "flush", NULL); -} - -static PyObject * -TextIOWrapper_close(PyTextIOWrapperObject *self, PyObject *args) -{ - PyObject *res; - CHECK_INITIALIZED(self); - res = PyObject_CallMethod((PyObject *)self, "flush", NULL); - if (res == NULL) { - /* If flush() fails, just give up */ - PyErr_Clear(); - } - else - Py_DECREF(res); - - return PyObject_CallMethod(self->buffer, "close", NULL); -} - -static PyObject * -TextIOWrapper_iternext(PyTextIOWrapperObject *self) -{ - PyObject *line; - - CHECK_INITIALIZED(self); - - self->telling = 0; - if (Py_TYPE(self) == &PyTextIOWrapper_Type) { - /* Skip method call overhead for speed */ - line = _TextIOWrapper_readline(self, -1); - } - else { - line = PyObject_CallMethodObjArgs((PyObject *)self, - _PyIO_str_readline, NULL); - if (line && !PyUnicode_Check(line)) { - PyErr_Format(PyExc_IOError, - "readline() should have returned an str object, " - "not '%.200s'", Py_TYPE(line)->tp_name); - Py_DECREF(line); - return NULL; - } - } - - if (line == NULL) - return NULL; - - if (PyUnicode_GET_SIZE(line) == 0) { - /* Reached EOF or would have blocked */ - Py_DECREF(line); - Py_CLEAR(self->snapshot); - self->telling = self->seekable; - return NULL; - } - - return line; -} - -static PyObject * -TextIOWrapper_name_get(PyTextIOWrapperObject *self, void *context) -{ - CHECK_INITIALIZED(self); - return PyObject_GetAttrString(self->buffer, "name"); -} - -static PyObject * -TextIOWrapper_closed_get(PyTextIOWrapperObject *self, void *context) -{ - CHECK_INITIALIZED(self); - return PyObject_GetAttr(self->buffer, _PyIO_str_closed); -} - -static PyObject * -TextIOWrapper_newlines_get(PyTextIOWrapperObject *self, void *context) -{ - PyObject *res; - CHECK_INITIALIZED(self); - if (self->decoder == NULL) - Py_RETURN_NONE; - res = PyObject_GetAttr(self->decoder, _PyIO_str_newlines); - if (res == NULL) { - PyErr_Clear(); - Py_RETURN_NONE; - } - return res; -} - -static PyObject * -TextIOWrapper_chunk_size_get(PyTextIOWrapperObject *self, void *context) -{ - CHECK_INITIALIZED(self); - return PyLong_FromSsize_t(self->chunk_size); -} - -static int -TextIOWrapper_chunk_size_set(PyTextIOWrapperObject *self, - PyObject *arg, void *context) -{ - Py_ssize_t n; - CHECK_INITIALIZED_INT(self); - n = PyNumber_AsSsize_t(arg, PyExc_TypeError); - if (n == -1 && PyErr_Occurred()) - return -1; - if (n <= 0) { - PyErr_SetString(PyExc_ValueError, - "a strictly positive integer is required"); - return -1; - } - self->chunk_size = n; - return 0; -} - -static PyMethodDef TextIOWrapper_methods[] = { - {"write", (PyCFunction)TextIOWrapper_write, METH_VARARGS}, - {"read", (PyCFunction)TextIOWrapper_read, METH_VARARGS}, - {"readline", (PyCFunction)TextIOWrapper_readline, METH_VARARGS}, - {"flush", (PyCFunction)TextIOWrapper_flush, METH_NOARGS}, - {"close", (PyCFunction)TextIOWrapper_close, METH_NOARGS}, - - {"fileno", (PyCFunction)TextIOWrapper_fileno, METH_NOARGS}, - {"seekable", (PyCFunction)TextIOWrapper_seekable, METH_NOARGS}, - {"readable", (PyCFunction)TextIOWrapper_readable, METH_NOARGS}, - {"writable", (PyCFunction)TextIOWrapper_writable, METH_NOARGS}, - {"isatty", (PyCFunction)TextIOWrapper_isatty, METH_NOARGS}, - - {"seek", (PyCFunction)TextIOWrapper_seek, METH_VARARGS}, - {"tell", (PyCFunction)TextIOWrapper_tell, METH_NOARGS}, - {"truncate", (PyCFunction)TextIOWrapper_truncate, METH_VARARGS}, - {NULL, NULL} -}; - -static PyMemberDef TextIOWrapper_members[] = { - {"encoding", T_OBJECT, offsetof(PyTextIOWrapperObject, encoding), READONLY}, - {"buffer", T_OBJECT, offsetof(PyTextIOWrapperObject, buffer), READONLY}, - {"line_buffering", T_BOOL, offsetof(PyTextIOWrapperObject, line_buffering), READONLY}, - {NULL} -}; - -static PyGetSetDef TextIOWrapper_getset[] = { - {"name", (getter)TextIOWrapper_name_get, NULL, NULL}, - {"closed", (getter)TextIOWrapper_closed_get, NULL, NULL}, -/* {"mode", (getter)TextIOWrapper_mode_get, NULL, NULL}, -*/ - {"newlines", (getter)TextIOWrapper_newlines_get, NULL, NULL}, - {"_CHUNK_SIZE", (getter)TextIOWrapper_chunk_size_get, - (setter)TextIOWrapper_chunk_size_set, NULL}, - {0} -}; - -PyTypeObject PyTextIOWrapper_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.TextIOWrapper", /*tp_name*/ - sizeof(PyTextIOWrapperObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)TextIOWrapper_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tps_etattr*/ - 0, /*tp_compare */ - (reprfunc)TextIOWrapper_repr,/*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - TextIOWrapper_doc, /* tp_doc */ - (traverseproc)TextIOWrapper_traverse, /* tp_traverse */ - (inquiry)TextIOWrapper_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(PyTextIOWrapperObject, weakreflist), /*tp_weaklistoffset*/ - 0, /* tp_iter */ - (iternextfunc)TextIOWrapper_iternext, /* tp_iternext */ - TextIOWrapper_methods, /* tp_methods */ - TextIOWrapper_members, /* tp_members */ - TextIOWrapper_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(PyTextIOWrapperObject, dict), /*tp_dictoffset*/ - (initproc)TextIOWrapper_init, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; Deleted: python/branches/py3k/Modules/io.c ============================================================================== --- python/branches/py3k/Modules/io.c Sat Apr 4 21:58:40 2009 +++ (empty file) @@ -1,760 +0,0 @@ -/* - An implementation of the new I/O lib as defined by PEP 3116 - "New I/O" - - Classes defined here: UnsupportedOperation, BlockingIOError. - Functions defined here: open(). - - Mostly written by Amaury Forgeot d'Arc -*/ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#include "structmember.h" -#include "_iomodule.h" - -#ifdef HAVE_SYS_TYPES_H -#include -#endif /* HAVE_SYS_TYPES_H */ - -#ifdef HAVE_SYS_STAT_H -#include -#endif /* HAVE_SYS_STAT_H */ - - -/* Various interned strings */ - -PyObject *_PyIO_str_close; -PyObject *_PyIO_str_closed; -PyObject *_PyIO_str_decode; -PyObject *_PyIO_str_encode; -PyObject *_PyIO_str_fileno; -PyObject *_PyIO_str_flush; -PyObject *_PyIO_str_getstate; -PyObject *_PyIO_str_isatty; -PyObject *_PyIO_str_newlines; -PyObject *_PyIO_str_nl; -PyObject *_PyIO_str_read; -PyObject *_PyIO_str_read1; -PyObject *_PyIO_str_readable; -PyObject *_PyIO_str_readinto; -PyObject *_PyIO_str_readline; -PyObject *_PyIO_str_reset; -PyObject *_PyIO_str_seek; -PyObject *_PyIO_str_seekable; -PyObject *_PyIO_str_tell; -PyObject *_PyIO_str_truncate; -PyObject *_PyIO_str_writable; -PyObject *_PyIO_str_write; - -PyObject *_PyIO_empty_str; -PyObject *_PyIO_empty_bytes; - - -PyDoc_STRVAR(module_doc, -"The io module provides the Python interfaces to stream handling. The\n" -"builtin open function is defined in this module.\n" -"\n" -"At the top of the I/O hierarchy is the abstract base class IOBase. It\n" -"defines the basic interface to a stream. Note, however, that there is no\n" -"seperation between reading and writing to streams; implementations are\n" -"allowed to throw an IOError if they do not support a given operation.\n" -"\n" -"Extending IOBase is RawIOBase which deals simply with the reading and\n" -"writing of raw bytes to a stream. FileIO subc lasses RawIOBase to provide\n" -"an interface to OS files.\n" -"\n" -"BufferedIOBase deals with buffering on a raw byte stream (RawIOBase). Its\n" -"subclasses, BufferedWriter, BufferedReader, and BufferedRWPair buffer\n" -"streams that are readable, writable, and both respectively.\n" -"BufferedRandom provides a buffered interface to random access\n" -"streams. BytesIO is a simple stream of in-memory bytes.\n" -"\n" -"Another IOBase subclass, TextIOBase, deals with the encoding and decoding\n" -"of streams into text. TextIOWrapper, which extends it, is a buffered text\n" -"interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO\n" -"is a in-memory stream for text.\n" -"\n" -"Argument names are not part of the specification, and only the arguments\n" -"of open() are intended to be used as keyword arguments.\n" -"\n" -"data:\n" -"\n" -"DEFAULT_BUFFER_SIZE\n" -"\n" -" An int containing the default buffer size used by the module's buffered\n" -" I/O classes. open() uses the file's blksize (as obtained by os.stat) if\n" -" possible.\n" - ); - - -/* - * BlockingIOError extends IOError - */ - -static int -BlockingIOError_init(PyBlockingIOErrorObject *self, PyObject *args, - PyObject *kwds) -{ - PyObject *myerrno = NULL, *strerror = NULL; - PyObject *baseargs = NULL; - Py_ssize_t written = 0; - - assert(PyTuple_Check(args)); - - self->written = 0; - if (!PyArg_ParseTuple(args, "OO|n:BlockingIOError", - &myerrno, &strerror, &written)) - return -1; - - baseargs = PyTuple_Pack(2, myerrno, strerror); - if (baseargs == NULL) - return -1; - /* This will take care of initializing of myerrno and strerror members */ - if (((PyTypeObject *)PyExc_IOError)->tp_init( - (PyObject *)self, baseargs, kwds) == -1) { - Py_DECREF(baseargs); - return -1; - } - Py_DECREF(baseargs); - - self->written = written; - return 0; -} - -static PyMemberDef BlockingIOError_members[] = { - {"characters_written", T_PYSSIZET, offsetof(PyBlockingIOErrorObject, written), 0}, - {NULL} /* Sentinel */ -}; - -static PyTypeObject _PyExc_BlockingIOError = { - PyVarObject_HEAD_INIT(NULL, 0) - "BlockingIOError", /*tp_name*/ - sizeof(PyBlockingIOErrorObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - 0, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - PyDoc_STR("Exception raised when I/O would block " - "on a non-blocking I/O stream"), /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - BlockingIOError_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)BlockingIOError_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ -}; -PyObject *PyExc_BlockingIOError = (PyObject *)&_PyExc_BlockingIOError; - - -/* - * The main open() function - */ -PyDoc_STRVAR(open_doc, -"Open file and return a stream. Raise IOError upon failure.\n" -"\n" -"file is either a text or byte string giving the name (and the path\n" -"if the file isn't in the current working directory) of the file to\n" -"be opened or an integer file descriptor of the file to be\n" -"wrapped. (If a file descriptor is given, it is closed when the\n" -"returned I/O object is closed, unless closefd is set to False.)\n" -"\n" -"mode is an optional string that specifies the mode in which the file\n" -"is opened. It defaults to 'r' which means open for reading in text\n" -"mode. Other common values are 'w' for writing (truncating the file if\n" -"it already exists), and 'a' for appending (which on some Unix systems,\n" -"means that all writes append to the end of the file regardless of the\n" -"current seek position). In text mode, if encoding is not specified the\n" -"encoding used is platform dependent. (For reading and writing raw\n" -"bytes use binary mode and leave encoding unspecified.) The available\n" -"modes are:\n" -"\n" -"========= ===============================================================\n" -"Character Meaning\n" -"--------- ---------------------------------------------------------------\n" -"'r' open for reading (default)\n" -"'w' open for writing, truncating the file first\n" -"'a' open for writing, appending to the end of the file if it exists\n" -"'b' binary mode\n" -"'t' text mode (default)\n" -"'+' open a disk file for updating (reading and writing)\n" -"'U' universal newline mode (for backwards compatibility; unneeded\n" -" for new code)\n" -"========= ===============================================================\n" -"\n" -"The default mode is 'rt' (open for reading text). For binary random\n" -"access, the mode 'w+b' opens and truncates the file to 0 bytes, while\n" -"'r+b' opens the file without truncation.\n" -"\n" -"Python distinguishes between files opened in binary and text modes,\n" -"even when the underlying operating system doesn't. Files opened in\n" -"binary mode (appending 'b' to the mode argument) return contents as\n" -"bytes objects without any decoding. In text mode (the default, or when\n" -"'t' is appended to the mode argument), the contents of the file are\n" -"returned as strings, the bytes having been first decoded using a\n" -"platform-dependent encoding or using the specified encoding if given.\n" -"\n" -"buffering is an optional integer used to set the buffering policy. By\n" -"default full buffering is on. Pass 0 to switch buffering off (only\n" -"allowed in binary mode), 1 to set line buffering, and an integer > 1\n" -"for full buffering.\n" -"\n" -"encoding is the name of the encoding used to decode or encode the\n" -"file. This should only be used in text mode. The default encoding is\n" -"platform dependent, but any encoding supported by Python can be\n" -"passed. See the codecs module for the list of supported encodings.\n" -"\n" -"errors is an optional string that specifies how encoding errors are to\n" -"be handled---this argument should not be used in binary mode. Pass\n" -"'strict' to raise a ValueError exception if there is an encoding error\n" -"(the default of None has the same effect), or pass 'ignore' to ignore\n" -"errors. (Note that ignoring encoding errors can lead to data loss.)\n" -"See the documentation for codecs.register for a list of the permitted\n" -"encoding error strings.\n" -"\n" -"newline controls how universal newlines works (it only applies to text\n" -"mode). It can be None, '', '\\n', '\\r', and '\\r\\n'. It works as\n" -"follows:\n" -"\n" -"* On input, if newline is None, universal newlines mode is\n" -" enabled. Lines in the input can end in '\\n', '\\r', or '\\r\\n', and\n" -" these are translated into '\\n' before being returned to the\n" -" caller. If it is '', universal newline mode is enabled, but line\n" -" endings are returned to the caller untranslated. If it has any of\n" -" the other legal values, input lines are only terminated by the given\n" -" string, and the line ending is returned to the caller untranslated.\n" -"\n" -"* On output, if newline is None, any '\\n' characters written are\n" -" translated to the system default line separator, os.linesep. If\n" -" newline is '', no translation takes place. If newline is any of the\n" -" other legal values, any '\\n' characters written are translated to\n" -" the given string.\n" -"\n" -"If closefd is False, the underlying file descriptor will be kept open\n" -"when the file is closed. This does not work when a file name is given\n" -"and must be True in that case.\n" -"\n" -"open() returns a file object whose type depends on the mode, and\n" -"through which the standard file operations such as reading and writing\n" -"are performed. When open() is used to open a file in a text mode ('w',\n" -"'r', 'wt', 'rt', etc.), it returns a TextIOWrapper. When used to open\n" -"a file in a binary mode, the returned class varies: in read binary\n" -"mode, it returns a BufferedReader; in write binary and append binary\n" -"modes, it returns a BufferedWriter, and in read/write mode, it returns\n" -"a BufferedRandom.\n" -"\n" -"It is also possible to use a string or bytearray as a file for both\n" -"reading and writing. For strings StringIO can be used like a file\n" -"opened in a text mode, and for bytes a BytesIO can be used like a file\n" -"opened in a binary mode.\n" - ); - -static PyObject * -io_open(PyObject *self, PyObject *args, PyObject *kwds) -{ - char *kwlist[] = {"file", "mode", "buffering", - "encoding", "errors", "newline", - "closefd", NULL}; - PyObject *file; - char *mode = "r"; - int buffering = -1, closefd = 1; - char *encoding = NULL, *errors = NULL, *newline = NULL; - unsigned i; - - int reading = 0, writing = 0, appending = 0, updating = 0; - int text = 0, binary = 0, universal = 0; - - char rawmode[5], *m; - int line_buffering, isatty; - - PyObject *raw, *modeobj = NULL, *buffer = NULL, *wrapper = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|sizzzi:open", kwlist, - &file, &mode, &buffering, - &encoding, &errors, &newline, - &closefd)) { - return NULL; - } - - if (!PyUnicode_Check(file) && - !PyBytes_Check(file) && - !PyNumber_Check(file)) { - PyErr_Format(PyExc_TypeError, "invalid file: %R", file); - return NULL; - } - - /* Decode mode */ - for (i = 0; i < strlen(mode); i++) { - char c = mode[i]; - - switch (c) { - case 'r': - reading = 1; - break; - case 'w': - writing = 1; - break; - case 'a': - appending = 1; - break; - case '+': - updating = 1; - break; - case 't': - text = 1; - break; - case 'b': - binary = 1; - break; - case 'U': - universal = 1; - reading = 1; - break; - default: - goto invalid_mode; - } - - /* c must not be duplicated */ - if (strchr(mode+i+1, c)) { - invalid_mode: - PyErr_Format(PyExc_ValueError, "invalid mode: '%s'", mode); - return NULL; - } - - } - - m = rawmode; - if (reading) *(m++) = 'r'; - if (writing) *(m++) = 'w'; - if (appending) *(m++) = 'a'; - if (updating) *(m++) = '+'; - *m = '\0'; - - /* Parameters validation */ - if (universal) { - if (writing || appending) { - PyErr_SetString(PyExc_ValueError, - "can't use U and writing mode at once"); - return NULL; - } - reading = 1; - } - - if (text && binary) { - PyErr_SetString(PyExc_ValueError, - "can't have text and binary mode at once"); - return NULL; - } - - if (reading + writing + appending > 1) { - PyErr_SetString(PyExc_ValueError, - "must have exactly one of read/write/append mode"); - return NULL; - } - - if (binary && encoding != NULL) { - PyErr_SetString(PyExc_ValueError, - "binary mode doesn't take an encoding argument"); - return NULL; - } - - if (binary && errors != NULL) { - PyErr_SetString(PyExc_ValueError, - "binary mode doesn't take an errors argument"); - return NULL; - } - - if (binary && newline != NULL) { - PyErr_SetString(PyExc_ValueError, - "binary mode doesn't take a newline argument"); - return NULL; - } - - /* Create the Raw file stream */ - raw = PyObject_CallFunction((PyObject *)&PyFileIO_Type, - "Osi", file, rawmode, closefd); - if (raw == NULL) - return NULL; - - modeobj = PyUnicode_FromString(mode); - if (modeobj == NULL) - goto error; - - /* buffering */ - { - PyObject *res = PyObject_CallMethod(raw, "isatty", NULL); - if (res == NULL) - goto error; - isatty = PyLong_AsLong(res); - Py_DECREF(res); - if (isatty == -1 && PyErr_Occurred()) - goto error; - } - - if (buffering == 1 || (buffering < 0 && isatty)) { - buffering = -1; - line_buffering = 1; - } - else - line_buffering = 0; - - if (buffering < 0) { - buffering = DEFAULT_BUFFER_SIZE; -#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE - { - struct stat st; - long fileno; - PyObject *res = PyObject_CallMethod(raw, "fileno", NULL); - if (res == NULL) - goto error; - - fileno = PyLong_AsLong(res); - Py_DECREF(res); - if (fileno == -1 && PyErr_Occurred()) - goto error; - - if (fstat(fileno, &st) >= 0) - buffering = st.st_blksize; - } -#endif - } - if (buffering < 0) { - PyErr_SetString(PyExc_ValueError, - "invalid buffering size"); - goto error; - } - - /* if not buffering, returns the raw file object */ - if (buffering == 0) { - if (!binary) { - PyErr_SetString(PyExc_ValueError, - "can't have unbuffered text I/O"); - goto error; - } - - Py_DECREF(modeobj); - return raw; - } - - /* wraps into a buffered file */ - { - PyObject *Buffered_class; - - if (updating) - Buffered_class = (PyObject *)&PyBufferedRandom_Type; - else if (writing || appending) - Buffered_class = (PyObject *)&PyBufferedWriter_Type; - else if (reading) - Buffered_class = (PyObject *)&PyBufferedReader_Type; - else { - PyErr_Format(PyExc_ValueError, - "unknown mode: '%s'", mode); - goto error; - } - - buffer = PyObject_CallFunction(Buffered_class, "Oi", raw, buffering); - } - Py_CLEAR(raw); - if (buffer == NULL) - goto error; - - - /* if binary, returns the buffered file */ - if (binary) { - Py_DECREF(modeobj); - return buffer; - } - - /* wraps into a TextIOWrapper */ - wrapper = PyObject_CallFunction((PyObject *)&PyTextIOWrapper_Type, - "Osssi", - buffer, - encoding, errors, newline, - line_buffering); - Py_CLEAR(buffer); - if (wrapper == NULL) - goto error; - - if (PyObject_SetAttrString(wrapper, "mode", modeobj) < 0) - goto error; - Py_DECREF(modeobj); - return wrapper; - - error: - Py_XDECREF(raw); - Py_XDECREF(modeobj); - Py_XDECREF(buffer); - Py_XDECREF(wrapper); - return NULL; -} - -/* - * Private helpers for the io module. - */ - -Py_off_t -PyNumber_AsOff_t(PyObject *item, PyObject *err) -{ - Py_off_t result; - PyObject *runerr; - PyObject *value = PyNumber_Index(item); - if (value == NULL) - return -1; - - /* We're done if PyLong_AsSsize_t() returns without error. */ - result = PyLong_AsOff_t(value); - if (result != -1 || !(runerr = PyErr_Occurred())) - goto finish; - - /* Error handling code -- only manage OverflowError differently */ - if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) - goto finish; - - PyErr_Clear(); - /* If no error-handling desired then the default clipping - is sufficient. - */ - if (!err) { - assert(PyLong_Check(value)); - /* Whether or not it is less than or equal to - zero is determined by the sign of ob_size - */ - if (_PyLong_Sign(value) < 0) - result = PY_OFF_T_MIN; - else - result = PY_OFF_T_MAX; - } - else { - /* Otherwise replace the error with caller's error object. */ - PyErr_Format(err, - "cannot fit '%.200s' into an offset-sized integer", - item->ob_type->tp_name); - } - - finish: - Py_DECREF(value); - return result; -} - -static int -iomodule_traverse(PyObject *mod, visitproc visit, void *arg) { - _PyIO_State *state = IO_MOD_STATE(mod); - if (!state->initialized) - return 0; - Py_VISIT(state->os_module); - if (state->locale_module != NULL) { - Py_VISIT(state->locale_module); - } - Py_VISIT(state->unsupported_operation); - return 0; -} - -static int -iomodule_clear(PyObject *mod) { - _PyIO_State *state = IO_MOD_STATE(mod); - if (!state->initialized) - return 0; - Py_CLEAR(state->os_module); - if (state->locale_module != NULL) - Py_CLEAR(state->locale_module); - Py_CLEAR(state->unsupported_operation); - return 0; -} - -static void -iomodule_free(PyObject *mod) { - iomodule_clear(mod); -} - -/* - * Module definition - */ - -static PyMethodDef module_methods[] = { - {"open", (PyCFunction)io_open, METH_VARARGS|METH_KEYWORDS, open_doc}, - {NULL, NULL} -}; - -struct PyModuleDef _PyIO_Module = { - PyModuleDef_HEAD_INIT, - "io", - module_doc, - sizeof(_PyIO_State), - module_methods, - NULL, - iomodule_traverse, - iomodule_clear, - (freefunc)iomodule_free, -}; - -PyMODINIT_FUNC -PyInit__io(void) -{ - PyObject *m = PyModule_Create(&_PyIO_Module); - _PyIO_State *state = NULL; - if (m == NULL) - return NULL; - state = IO_MOD_STATE(m); - state->initialized = 0; - - /* put os in the module state */ - state->os_module = PyImport_ImportModule("os"); - if (state->os_module == NULL) - goto fail; - -#define ADD_TYPE(type, name) \ - if (PyType_Ready(type) < 0) \ - goto fail; \ - Py_INCREF(type); \ - if (PyModule_AddObject(m, name, (PyObject *)type) < 0) { \ - Py_DECREF(type); \ - goto fail; \ - } - - /* DEFAULT_BUFFER_SIZE */ - if (PyModule_AddIntMacro(m, DEFAULT_BUFFER_SIZE) < 0) - goto fail; - - /* UnsupportedOperation inherits from ValueError and IOError */ - state->unsupported_operation = PyObject_CallFunction( - (PyObject *)&PyType_Type, "s(OO){}", - "UnsupportedOperation", PyExc_ValueError, PyExc_IOError); - if (state->unsupported_operation == NULL) - goto fail; - Py_INCREF(state->unsupported_operation); - if (PyModule_AddObject(m, "UnsupportedOperation", - state->unsupported_operation) < 0) - goto fail; - - /* BlockingIOError */ - _PyExc_BlockingIOError.tp_base = (PyTypeObject *) PyExc_IOError; - ADD_TYPE(&_PyExc_BlockingIOError, "BlockingIOError"); - - /* Concrete base types of the IO ABCs. - (the ABCs themselves are declared through inheritance in io.py) - */ - ADD_TYPE(&PyIOBase_Type, "_IOBase"); - ADD_TYPE(&PyRawIOBase_Type, "_RawIOBase"); - ADD_TYPE(&PyBufferedIOBase_Type, "_BufferedIOBase"); - ADD_TYPE(&PyTextIOBase_Type, "_TextIOBase"); - - /* Implementation of concrete IO objects. */ - /* FileIO */ - PyFileIO_Type.tp_base = &PyRawIOBase_Type; - ADD_TYPE(&PyFileIO_Type, "FileIO"); - - /* BytesIO */ - PyBytesIO_Type.tp_base = &PyBufferedIOBase_Type; - ADD_TYPE(&PyBytesIO_Type, "BytesIO"); - - /* StringIO */ - PyStringIO_Type.tp_base = &PyTextIOBase_Type; - ADD_TYPE(&PyStringIO_Type, "StringIO"); - - /* BufferedReader */ - PyBufferedReader_Type.tp_base = &PyBufferedIOBase_Type; - ADD_TYPE(&PyBufferedReader_Type, "BufferedReader"); - - /* BufferedWriter */ - PyBufferedWriter_Type.tp_base = &PyBufferedIOBase_Type; - ADD_TYPE(&PyBufferedWriter_Type, "BufferedWriter"); - - /* BufferedRWPair */ - PyBufferedRWPair_Type.tp_base = &PyBufferedIOBase_Type; - ADD_TYPE(&PyBufferedRWPair_Type, "BufferedRWPair"); - - /* BufferedRandom */ - PyBufferedRandom_Type.tp_base = &PyBufferedIOBase_Type; - ADD_TYPE(&PyBufferedRandom_Type, "BufferedRandom"); - - /* TextIOWrapper */ - PyTextIOWrapper_Type.tp_base = &PyTextIOBase_Type; - ADD_TYPE(&PyTextIOWrapper_Type, "TextIOWrapper"); - - /* IncrementalNewlineDecoder */ - ADD_TYPE(&PyIncrementalNewlineDecoder_Type, "IncrementalNewlineDecoder"); - - /* Interned strings */ - if (!(_PyIO_str_close = PyUnicode_InternFromString("close"))) - goto fail; - if (!(_PyIO_str_closed = PyUnicode_InternFromString("closed"))) - goto fail; - if (!(_PyIO_str_decode = PyUnicode_InternFromString("decode"))) - goto fail; - if (!(_PyIO_str_encode = PyUnicode_InternFromString("encode"))) - goto fail; - if (!(_PyIO_str_fileno = PyUnicode_InternFromString("fileno"))) - goto fail; - if (!(_PyIO_str_flush = PyUnicode_InternFromString("flush"))) - goto fail; - if (!(_PyIO_str_getstate = PyUnicode_InternFromString("getstate"))) - goto fail; - if (!(_PyIO_str_isatty = PyUnicode_InternFromString("isatty"))) - goto fail; - if (!(_PyIO_str_newlines = PyUnicode_InternFromString("newlines"))) - goto fail; - if (!(_PyIO_str_nl = PyUnicode_InternFromString("\n"))) - goto fail; - if (!(_PyIO_str_read = PyUnicode_InternFromString("read"))) - goto fail; - if (!(_PyIO_str_read1 = PyUnicode_InternFromString("read1"))) - goto fail; - if (!(_PyIO_str_readable = PyUnicode_InternFromString("readable"))) - goto fail; - if (!(_PyIO_str_readinto = PyUnicode_InternFromString("readinto"))) - goto fail; - if (!(_PyIO_str_readline = PyUnicode_InternFromString("readline"))) - goto fail; - if (!(_PyIO_str_reset = PyUnicode_InternFromString("reset"))) - goto fail; - if (!(_PyIO_str_seek = PyUnicode_InternFromString("seek"))) - goto fail; - if (!(_PyIO_str_seekable = PyUnicode_InternFromString("seekable"))) - goto fail; - if (!(_PyIO_str_tell = PyUnicode_InternFromString("tell"))) - goto fail; - if (!(_PyIO_str_truncate = PyUnicode_InternFromString("truncate"))) - goto fail; - if (!(_PyIO_str_write = PyUnicode_InternFromString("write"))) - goto fail; - if (!(_PyIO_str_writable = PyUnicode_InternFromString("writable"))) - goto fail; - - if (!(_PyIO_empty_str = PyUnicode_FromStringAndSize(NULL, 0))) - goto fail; - if (!(_PyIO_empty_bytes = PyBytes_FromStringAndSize(NULL, 0))) - goto fail; - - state->initialized = 1; - - return m; - - fail: - Py_XDECREF(state->os_module); - Py_XDECREF(state->unsupported_operation); - Py_DECREF(m); - return NULL; -} Modified: python/branches/py3k/PC/VC6/pythoncore.dsp ============================================================================== --- python/branches/py3k/PC/VC6/pythoncore.dsp (original) +++ python/branches/py3k/PC/VC6/pythoncore.dsp Sat Apr 4 21:58:40 2009 @@ -97,14 +97,6 @@ # End Source File # Begin Source File -SOURCE=..\..\Modules\_bufferedio.c -# End Source File -# Begin Source File - -SOURCE=..\..\Modules\_bytesio.c -# End Source File -# Begin Source File - SOURCE=..\..\Modules\cjkcodecs\_codecs_cn.c # End Source File # Begin Source File @@ -141,19 +133,39 @@ # End Source File # Begin Source File -SOURCE=..\..\Modules\_fileio.c +SOURCE=..\..\Modules\_functoolsmodule.c # End Source File # Begin Source File -SOURCE=..\..\Modules\_functoolsmodule.c +SOURCE=..\..\Modules\_heapqmodule.c # End Source File # Begin Source File -SOURCE=..\..\Modules\_heapqmodule.c +SOURCE=..\..\Modules\_io\bytesio.c +# End Source File +# Begin Source File + +SOURCE=..\..\Modules\_io\stringio.c +# End Source File +# Begin Source File + +SOURCE=..\..\Modules\_io\fileio.c +# End Source File +# Begin Source File + +SOURCE="..\..\Modules\_io\bufferedio.c" +# End Source File +# Begin Source File + +SOURCE=..\..\Modules\_io\iobase.c # End Source File # Begin Source File -SOURCE=..\..\Modules\_iobase.c +SOURCE=..\..\Modules\_io\textio.c +# End Source File +# Begin Source File + +SOURCE=..\..\Modules\_io\_iomodule.c # End Source File # Begin Source File @@ -181,10 +193,6 @@ # End Source File # Begin Source File -SOURCE=..\..\Modules\_stringio.c -# End Source File -# Begin Source File - SOURCE=..\..\Modules\_struct.c # End Source File # Begin Source File @@ -193,10 +201,6 @@ # End Source File # Begin Source File -SOURCE=..\..\Modules\_textio.c -# End Source File -# Begin Source File - SOURCE=..\..\Modules\_threadmodule.c # End Source File # Begin Source File @@ -475,10 +479,6 @@ # End Source File # Begin Source File -SOURCE=..\..\Modules\io.c -# End Source File -# Begin Source File - SOURCE=..\..\Objects\iterobject.c # End Source File # Begin Source File Modified: python/branches/py3k/PC/VS7.1/pythoncore.vcproj ============================================================================== --- python/branches/py3k/PC/VS7.1/pythoncore.vcproj (original) +++ python/branches/py3k/PC/VS7.1/pythoncore.vcproj Sat Apr 4 21:58:40 2009 @@ -274,6 +274,32 @@ + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + @@ -1043,10 +1051,6 @@ > - - Modified: python/branches/py3k/PCbuild/pythoncore.vcproj ============================================================================== --- python/branches/py3k/PCbuild/pythoncore.vcproj (original) +++ python/branches/py3k/PCbuild/pythoncore.vcproj Sat Apr 4 21:58:40 2009 @@ -975,10 +975,6 @@ > - - @@ -991,14 +987,6 @@ > - - - - @@ -1007,14 +995,6 @@ > - - - - @@ -1039,18 +1019,10 @@ > - - - - @@ -1091,10 +1063,6 @@ > - - @@ -1171,6 +1139,42 @@ > + + + + + + + + + + + + + + + + + + The Buildbot has detected a new failure of x86 osx.5 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%202.6/builds/225 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: martin.v.loewis BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Sat Apr 4 22:13:23 2009 From: python-checkins at python.org (kurt.kaiser) Date: Sat, 4 Apr 2009 22:13:23 +0200 (CEST) Subject: [Python-checkins] r71186 - in python/branches/py3k/Lib/idlelib: NEWS.txt run.py Message-ID: <20090404201323.E24C21E4020@bag.python.org> Author: kurt.kaiser Date: Sat Apr 4 22:13:23 2009 New Revision: 71186 Log: Merged revisions 71023 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71023 | kurt.kaiser | 2009-04-01 22:44:54 -0400 (Wed, 01 Apr 2009) | 3 lines Remove port spec from run.py and fix bug where subprocess fails to extract port from command line when warnings are present. ........ Modified: python/branches/py3k/Lib/idlelib/NEWS.txt python/branches/py3k/Lib/idlelib/run.py Modified: python/branches/py3k/Lib/idlelib/NEWS.txt ============================================================================== --- python/branches/py3k/Lib/idlelib/NEWS.txt (original) +++ python/branches/py3k/Lib/idlelib/NEWS.txt Sat Apr 4 22:13:23 2009 @@ -3,6 +3,9 @@ *Release date: XX-XXX-XXXX* +- Remove port spec from run.py and fix bug where subprocess fails to + extract port from command line when warnings are present. + - Issue #4815: Offer conversion to UTF-8 if source files have no encoding declaration and are not encoded in UTF-8. Modified: python/branches/py3k/Lib/idlelib/run.py ============================================================================== --- python/branches/py3k/Lib/idlelib/run.py (original) +++ python/branches/py3k/Lib/idlelib/run.py Sat Apr 4 22:13:23 2009 @@ -67,10 +67,13 @@ global quitting global no_exitfunc no_exitfunc = del_exitfunc - port = 8833 #time.sleep(15) # test subprocess not responding - if sys.argv[1:]: - port = int(sys.argv[1]) + try: + assert(len(sys.argv) > 1) + port = int(sys.argv[-1]) + except: + print>>sys.stderr, "IDLE Subprocess: no IP port passed in sys.argv." + return sys.argv[:] = [""] sockthread = threading.Thread(target=manage_socket, name='SockThread', From python-checkins at python.org Sat Apr 4 22:20:29 2009 From: python-checkins at python.org (kurt.kaiser) Date: Sat, 4 Apr 2009 22:20:29 +0200 (CEST) Subject: [Python-checkins] r71187 - python/branches/py3k/Lib/idlelib/run.py Message-ID: <20090404202029.BEE3D1E4037@bag.python.org> Author: kurt.kaiser Date: Sat Apr 4 22:20:29 2009 New Revision: 71187 Log: Convert print to Py3 Modified: python/branches/py3k/Lib/idlelib/run.py Modified: python/branches/py3k/Lib/idlelib/run.py ============================================================================== --- python/branches/py3k/Lib/idlelib/run.py (original) +++ python/branches/py3k/Lib/idlelib/run.py Sat Apr 4 22:20:29 2009 @@ -72,7 +72,8 @@ assert(len(sys.argv) > 1) port = int(sys.argv[-1]) except: - print>>sys.stderr, "IDLE Subprocess: no IP port passed in sys.argv." + print("IDLE Subprocess: no IP port passed in sys.argv.", + file=sys.__stderr__) return sys.argv[:] = [""] sockthread = threading.Thread(target=manage_socket, From python-checkins at python.org Sat Apr 4 22:34:17 2009 From: python-checkins at python.org (kurt.kaiser) Date: Sat, 4 Apr 2009 22:34:17 +0200 (CEST) Subject: [Python-checkins] r71188 - python/branches/py3k Message-ID: <20090404203417.1B9031E4020@bag.python.org> Author: kurt.kaiser Date: Sat Apr 4 22:34:16 2009 New Revision: 71188 Log: Merged revisions 71023 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71023 | kurt.kaiser | 2009-04-01 22:44:54 -0400 (Wed, 01 Apr 2009) | 3 lines Remove port spec from run.py and fix bug where subprocess fails to extract port from command line when warnings are present. ........ Modified: python/branches/py3k/ (props changed) From buildbot at python.org Sat Apr 4 22:34:35 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 20:34:35 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 2.6 Message-ID: <20090404203435.881FE1E4020@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%202.6/builds/216 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: martin.v.loewis BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_signal make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sat Apr 4 22:38:52 2009 From: python-checkins at python.org (kurt.kaiser) Date: Sat, 4 Apr 2009 22:38:52 +0200 (CEST) Subject: [Python-checkins] r71189 - in python/branches/py3k: Lib/idlelib/EditorWindow.py Lib/idlelib/NEWS.txt Message-ID: <20090404203852.946961E4037@bag.python.org> Author: kurt.kaiser Date: Sat Apr 4 22:38:52 2009 New Revision: 71189 Log: Merged revisions 70723 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70723 | kurt.kaiser | 2009-03-30 12:22:00 -0400 (Mon, 30 Mar 2009) | 1 line Tk 8.5 Text widget requires 'wordprocessor' tabstyle attr to handle mixed space/tab properly. Issue 5120, patch by Guilherme Polo. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/idlelib/EditorWindow.py python/branches/py3k/Lib/idlelib/NEWS.txt Modified: python/branches/py3k/Lib/idlelib/EditorWindow.py ============================================================================== --- python/branches/py3k/Lib/idlelib/EditorWindow.py (original) +++ python/branches/py3k/Lib/idlelib/EditorWindow.py Sat Apr 4 22:38:52 2009 @@ -107,10 +107,18 @@ self.text_frame = text_frame = Frame(top) self.vbar = vbar = Scrollbar(text_frame, name='vbar') self.width = idleConf.GetOption('main','EditorWindow','width') - self.text = text = MultiCallCreator(Text)( - text_frame, name='text', padx=5, wrap='none', - width=self.width, - height=idleConf.GetOption('main','EditorWindow','height') ) + text_options = { + 'name': 'text', + 'padx': 5, + 'wrap': 'none', + 'width': self.width, + 'height': idleConf.GetOption('main', 'EditorWindow', 'height')} + if TkVersion >= 8.5: + # Starting with tk 8.5 we have to set the new tabstyle option + # to 'wordprocessor' to achieve the same display of tabs as in + # older tk versions. + text_options['tabstyle'] = 'wordprocessor' + self.text = text = MultiCallCreator(Text)(text_frame, **text_options) self.top.focused_widget = self.text self.createmenubar() Modified: python/branches/py3k/Lib/idlelib/NEWS.txt ============================================================================== --- python/branches/py3k/Lib/idlelib/NEWS.txt (original) +++ python/branches/py3k/Lib/idlelib/NEWS.txt Sat Apr 4 22:38:52 2009 @@ -6,6 +6,9 @@ - Remove port spec from run.py and fix bug where subprocess fails to extract port from command line when warnings are present. +- Tk 8.5 Text widget requires 'wordprocessor' tabstyle attr to handle + mixed space/tab properly. Issue 5120, patch by Guilherme Polo. + - Issue #4815: Offer conversion to UTF-8 if source files have no encoding declaration and are not encoded in UTF-8. From python-checkins at python.org Sat Apr 4 22:47:27 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 4 Apr 2009 22:47:27 +0200 (CEST) Subject: [Python-checkins] r71190 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090404204727.7A3301E4020@bag.python.org> Author: mark.dickinson Date: Sat Apr 4 22:47:26 2009 New Revision: 71190 Log: Simplify some logic in format_float_short and PyOS_double_to_string: - min_digits keeps track of minimum number of digits needed - no need to add .0 explicitly at the end; it should be already there if we set min_digits appropriately. Remove is_integer logic. - n_wanted_digits_after_decimal is unused. Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Sat Apr 4 22:47:26 2009 @@ -519,22 +519,34 @@ }; -/* Convert a Python float to a minimal string that evaluates back to that - float. The output is minimal in the sense of having the fewest possible - number of significant digits. */ +/* Convert a double d to a string, and put the result into the buffer buf. + + Arguments: + buflen is the length of the provided buffer + d is the double to be converted + format_code is one of 'e', 'f', 'g', 'r' or 's'. 'e', 'f' and 'g' + correspond to '%e', '%f' and '%g'; 'r' and 's' correspond + to repr and str. + mode is one of '0', '2' or '3', and is completely determined by + format_code: 'e', 'g' and 's' use mode 2; 'f' mode 3, 'r' mode 0. + precision is the desired precision + always_add_sign is nonzero if a '+' sign should be included for positive + numbers + add_dot_0_if_integer is nonzero if integers in non-exponential form + should have ".0" added. Only applies to format codes 'r' and 's'. + use_alt_formatting is nonzero if alternative formatting should be + used. Only applies to format codes 'e', 'f' and 'g'. + */ static void format_float_short(char *buf, Py_ssize_t buflen, double d, char format_code, int mode, Py_ssize_t precision, - Py_ssize_t n_wanted_digits_after_decimal, int always_add_sign, int add_dot_0_if_integer, int use_alt_formatting, char **float_strings) { char *digits, *digits_end; - int decpt, sign, exp_len, dec_pos; - int use_exp = 0; - int is_integer; /* is the output produced so far just an integer? */ - Py_ssize_t n_digits, trailing_zeros; + int decpt, sign, exp_len, dec_pos, use_exp = 0; + Py_ssize_t n_digits, min_digits = 0; /* precision of 0 makes no sense for 'g' format; interpret as 1 */ if (precision == 0 && format_code == 'g') @@ -566,10 +578,7 @@ } else { /* shouldn't get here: Gay's code should always return - something starting with a digit, an 'I', or an - 'N' */ - /*printf("Help! dtoa returned: %.*s\n", - (int)n_digits, digits);*/ + something starting with a digit, an 'I', or 'N' */ strncpy(buf, "ERR", 3); buf += 3; assert(0); @@ -585,46 +594,42 @@ type = 'g'; over time, those tests should be deleted */ -/* if (decpt > 50 && format_code == 'f') - format_code = 'g'; */ - /* Detect if we're using exponents or not */ + /* Detect if we're using exponents or not, and figure out how many + additional digits we need beyond those provided by dtoa. */ switch (format_code) { case 'e': use_exp = 1; - trailing_zeros = precision - n_digits; + min_digits = precision; break; case 'f': - use_exp = 0; - trailing_zeros = decpt + precision - n_digits; + min_digits = decpt + precision; break; case 'g': - if ((mode != 0) && (decpt > precision || decpt <= -4)) + if (decpt <= -4 || decpt > precision) use_exp = 1; - else { - use_exp = 0; - } if (use_alt_formatting) - trailing_zeros = precision - n_digits; - else - trailing_zeros = 0; + min_digits = precision; break; case 'r': - /* use exponent for values >= 1e16 or < 1e-4 */ - if ((-4 < decpt) && (decpt <= 16)) - use_exp = 0; - else + if (decpt <= -4 || decpt > 16) use_exp = 1; - trailing_zeros = 0; + else if (add_dot_0_if_integer) + min_digits = decpt + 1; break; case 's': - /* str: use exponent for values >= 1e11 or < 1e-4 */ - if (-4 < decpt && decpt < precision) - use_exp = 0; - else + /* if we're forcing a digit after the point, convert to + exponential format at 1e11. If not, convert at 1e12. */ + if (decpt <= -4 || + decpt > precision - (add_dot_0_if_integer != 0)) use_exp = 1; - trailing_zeros = 0; + else if (add_dot_0_if_integer) + min_digits = decpt + 1; break; + default: + PyErr_BadInternalCall(); + *buf = '\0'; + return; } /* Always add a negative sign, and a plus sign if always_add_sign. */ @@ -659,42 +664,31 @@ strncpy(buf, digits, n_digits); buf += n_digits; } + min_digits -= n_digits; + /* and zeros on the right up to the decimal point */ if (n_digits < dec_pos) { memset(buf, '0', dec_pos-n_digits); buf += dec_pos-n_digits; *buf++ = '.'; - trailing_zeros -= dec_pos-n_digits; + min_digits -= dec_pos-n_digits; } - /* and more trailing zeros, when necessary */ - if (trailing_zeros > 0) { - memset(buf, '0', trailing_zeros); - buf += trailing_zeros; + + /* and more trailing zeros when necessary */ + if (min_digits > 0) { + memset(buf, '0', min_digits); + buf += min_digits; } - /* If we're at a trailing decimal, delete it. We are then just an - integer. */ - if (buf[-1] == '.' && !use_alt_formatting) { + /* delete a trailing decimal pt unless using alternative formatting. */ + if (buf[-1] == '.' && !use_alt_formatting) buf--; - is_integer = 1; - } - else - /* The decimal isn't at the end, so it's somewhere else in the - string. We are therefore not an integer. */ - is_integer = 0; /* Now that we've done zero padding, add an exponent if needed. */ if (use_exp) { *buf++ = float_strings[OFS_E][0]; exp_len = sprintf(buf, "%+.02d", decpt-1); buf += exp_len; - is_integer = 0; - } - - /* Add ".0" if we're an integer? */ - if (add_dot_0_if_integer && is_integer) { - *buf++ = '.'; - *buf++ = '0'; } *buf++ = '\0'; @@ -709,7 +703,6 @@ char* buf = (char *)PyMem_Malloc(512); char lc_format_code = format_code; char** float_strings = lc_float_strings; - Py_ssize_t n_wanted_digits_after_decimal = precision; int mode = 0; /* Validate format_code, and map upper and lower case */ @@ -749,8 +742,6 @@ break; case 'g': mode = 2; - if (flags & Py_DTSF_ALT) - n_wanted_digits_after_decimal--; break; case 'r': /* "repr" pseudo-mode */ @@ -767,7 +758,7 @@ /* XXX validate format_code */ format_float_short(buf, 512, val, lc_format_code, mode, precision, - n_wanted_digits_after_decimal, flags & Py_DTSF_SIGN, + flags & Py_DTSF_SIGN, flags & Py_DTSF_ADD_DOT_0, flags & Py_DTSF_ALT, float_strings); From python-checkins at python.org Sat Apr 4 22:52:47 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 4 Apr 2009 22:52:47 +0200 (CEST) Subject: [Python-checkins] r71191 - python/branches/py3k-short-float-repr/Objects/complexobject.c Message-ID: <20090404205247.658471E4020@bag.python.org> Author: mark.dickinson Date: Sat Apr 4 22:52:47 2009 New Revision: 71191 Log: str(complex) should use 's' format, not 'g' Modified: python/branches/py3k-short-float-repr/Objects/complexobject.c Modified: python/branches/py3k-short-float-repr/Objects/complexobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/complexobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/complexobject.c Sat Apr 4 22:52:47 2009 @@ -444,7 +444,7 @@ static PyObject * complex_str(PyComplexObject *v) { - return complex_format(v, 'g', PREC_STR); + return complex_format(v, 's', PREC_STR); } static long From python-checkins at python.org Sat Apr 4 23:06:54 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 23:06:54 +0200 (CEST) Subject: [Python-checkins] r71192 - in python/branches/py3k: Include/patchlevel.h Lib/distutils/__init__.py Lib/idlelib/idlever.py Misc/NEWS Misc/RPM/python-3.1.spec README Message-ID: <20090404210654.B76C21E4020@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 23:06:52 2009 New Revision: 71192 Log: bump version to 3.1a2 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.1.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 Apr 4 23:06:52 2009 @@ -20,10 +20,10 @@ #define PY_MINOR_VERSION 1 #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA -#define PY_RELEASE_SERIAL 1 +#define PY_RELEASE_SERIAL 2 /* Version as a string */ -#define PY_VERSION "3.1a1+" +#define PY_VERSION "3.1a2" /*--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 Apr 4 23:06:52 2009 @@ -15,5 +15,5 @@ # Updated automatically by the Python release process. # #--start constants-- -__version__ = "3.1a1" +__version__ = "3.1a2" #--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 Apr 4 23:06:52 2009 @@ -1 +1 @@ -IDLE_VERSION = "3.1a1" +IDLE_VERSION = "3.1a2" Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Apr 4 23:06:52 2009 @@ -7,7 +7,7 @@ What's New in Python 3.1 alpha 2? ================================= -*Release date: XXX* +*Release date: 2009-4-4* Core and Builtins ----------------- Modified: python/branches/py3k/Misc/RPM/python-3.1.spec ============================================================================== --- python/branches/py3k/Misc/RPM/python-3.1.spec (original) +++ python/branches/py3k/Misc/RPM/python-3.1.spec Sat Apr 4 23:06:52 2009 @@ -34,7 +34,7 @@ %define name python #--start constants-- -%define version 3.1a1 +%define version 3.1a2 %define libver 3.1 #--end constants-- %define release 1pydotorg Modified: python/branches/py3k/README ============================================================================== --- python/branches/py3k/README (original) +++ python/branches/py3k/README Sat Apr 4 23:06:52 2009 @@ -1,4 +1,4 @@ -This is Python version 3.1 alpha 1 +This is Python version 3.1 alpha 2 ================================== For notes specific to this release, see RELNOTES in this directory. @@ -12,10 +12,6 @@ changed considerably, and a lot of deprecated features have finally been removed. -This is an ongoing project; the cleanup isn't expected to be complete -until some time in 2008. In particular there are plans to reorganize -the standard library namespace. - Release Schedule ---------------- From python-checkins at python.org Sat Apr 4 23:07:40 2009 From: python-checkins at python.org (kurt.kaiser) Date: Sat, 4 Apr 2009 23:07:40 +0200 (CEST) Subject: [Python-checkins] r71193 - in python/branches/py3k: Lib/idlelib/NEWS.txt Lib/idlelib/PyShell.py Lib/idlelib/rpc.py Message-ID: <20090404210740.EF17F1E4020@bag.python.org> Author: kurt.kaiser Date: Sat Apr 4 23:07:39 2009 New Revision: 71193 Log: Merged revisions 71126 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71126 | kurt.kaiser | 2009-04-04 03:03:48 -0400 (Sat, 04 Apr 2009) | 5 lines Allow multiple IDLE GUI/subprocess pairs to exist simultaneously. Thanks to David Scherer for suggesting the use of an ephemeral port for the GUI. Patch 1529142 Weeble. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/idlelib/NEWS.txt python/branches/py3k/Lib/idlelib/PyShell.py python/branches/py3k/Lib/idlelib/rpc.py Modified: python/branches/py3k/Lib/idlelib/NEWS.txt ============================================================================== --- python/branches/py3k/Lib/idlelib/NEWS.txt (original) +++ python/branches/py3k/Lib/idlelib/NEWS.txt Sat Apr 4 23:07:39 2009 @@ -3,6 +3,10 @@ *Release date: XX-XXX-XXXX* +- Allow multiple IDLE GUI/subprocess pairs to exist simultaneously. Thanks to + David Scherer for suggesting the use of an ephemeral port for the GUI. + Patch 1529142 Weeble. + - Remove port spec from run.py and fix bug where subprocess fails to extract port from command line when warnings are present. Modified: python/branches/py3k/Lib/idlelib/PyShell.py ============================================================================== --- python/branches/py3k/Lib/idlelib/PyShell.py (original) +++ python/branches/py3k/Lib/idlelib/PyShell.py Sat Apr 4 23:07:39 2009 @@ -34,7 +34,8 @@ from idlelib import RemoteDebugger from idlelib import macosxSupport -LOCALHOST = '127.0.0.1' +HOST = '127.0.0.1' # python execution server on localhost loopback +PORT = 0 # someday pass in host, port for remote debug capability try: from signal import SIGTERM @@ -339,17 +340,21 @@ InteractiveInterpreter.__init__(self, locals=locals) self.save_warnings_filters = None self.restarting = False - self.subprocess_arglist = self.build_subprocess_arglist() + self.subprocess_arglist = None + self.port = PORT - port = 8833 rpcclt = None rpcpid = None def spawn_subprocess(self): + if self.subprocess_arglist == None: + self.subprocess_arglist = self.build_subprocess_arglist() args = self.subprocess_arglist self.rpcpid = os.spawnv(os.P_NOWAIT, sys.executable, args) def build_subprocess_arglist(self): + assert (self.port!=0), ( + "Socket should have been assigned a port number.") w = ['-W' + s for s in sys.warnoptions] # Maybe IDLE is installed and is being accessed via sys.path, # or maybe it's not installed and the idle.py script is being @@ -368,11 +373,8 @@ return [decorated_exec] + w + ["-c", command, str(self.port)] def start_subprocess(self): - # spawning first avoids passing a listening socket to the subprocess - self.spawn_subprocess() - #time.sleep(20) # test to simulate GUI not accepting connection - addr = (LOCALHOST, self.port) - # Idle starts listening for connection on localhost + addr = (HOST, self.port) + # GUI makes several attempts to acquire socket, listens for connection for i in range(3): time.sleep(i) try: @@ -383,6 +385,18 @@ else: self.display_port_binding_error() return None + # if PORT was 0, system will assign an 'ephemeral' port. Find it out: + self.port = self.rpcclt.listening_sock.getsockname()[1] + # if PORT was not 0, probably working with a remote execution server + if PORT != 0: + # To allow reconnection within the 2MSL wait (cf. Stevens TCP + # V1, 18.6), set SO_REUSEADDR. Note that this can be problematic + # on Windows since the implementation allows two active sockets on + # the same address! + self.rpcclt.listening_sock.setsockopt(socket.SOL_SOCKET, + socket.SO_REUSEADDR, 1) + self.spawn_subprocess() + #time.sleep(20) # test to simulate GUI not accepting connection # Accept the connection from the Python execution server self.rpcclt.listening_sock.settimeout(10) try: @@ -734,13 +748,12 @@ def display_port_binding_error(self): tkMessageBox.showerror( "Port Binding Error", - "IDLE can't bind TCP/IP port 8833, which is necessary to " - "communicate with its Python execution server. Either " - "no networking is installed on this computer or another " - "process (another IDLE?) is using the port. Run IDLE with the -n " - "command line switch to start without a subprocess and refer to " - "Help/IDLE Help 'Running without a subprocess' for further " - "details.", + "IDLE can't bind to a TCP/IP port, which is necessary to " + "communicate with its Python execution server. This might be " + "because no networking is installed on this computer. " + "Run IDLE with the -n command line switch to start without a " + "subprocess and refer to Help/IDLE Help 'Running without a " + "subprocess' for further details.", master=self.tkconsole.text) def display_no_subprocess_error(self): @@ -1285,7 +1298,7 @@ global flist, root, use_subprocess use_subprocess = True - enable_shell = False + enable_shell = True enable_edit = False debug = False cmd = None @@ -1306,6 +1319,7 @@ enable_shell = True if o == '-e': enable_edit = True + enable_shell = False if o == '-h': sys.stdout.write(usage_msg) sys.exit() @@ -1356,7 +1370,6 @@ edit_start = idleConf.GetOption('main', 'General', 'editor-on-startup', type='bool') enable_edit = enable_edit or edit_start - enable_shell = enable_shell or not edit_start # start editor and/or shell windows: root = Tk(className="Idle") Modified: python/branches/py3k/Lib/idlelib/rpc.py ============================================================================== --- python/branches/py3k/Lib/idlelib/rpc.py (original) +++ python/branches/py3k/Lib/idlelib/rpc.py Sat Apr 4 23:07:39 2009 @@ -518,8 +518,6 @@ def __init__(self, address, family=socket.AF_INET, type=socket.SOCK_STREAM): self.listening_sock = socket.socket(family, type) - self.listening_sock.setsockopt(socket.SOL_SOCKET, - socket.SO_REUSEADDR, 1) self.listening_sock.bind(address) self.listening_sock.listen(1) From python-checkins at python.org Sat Apr 4 23:08:04 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 23:08:04 +0200 (CEST) Subject: [Python-checkins] r71194 - in python/branches/py3k: README RELNOTES Message-ID: <20090404210804.D84911E4037@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 23:08:03 2009 New Revision: 71194 Log: I don't think RELNOTES is useful anymore Removed: python/branches/py3k/RELNOTES Modified: python/branches/py3k/README Modified: python/branches/py3k/README ============================================================================== --- python/branches/py3k/README (original) +++ python/branches/py3k/README Sat Apr 4 23:08:03 2009 @@ -1,7 +1,6 @@ This is Python version 3.1 alpha 2 ================================== -For notes specific to this release, see RELNOTES in this directory. Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Python Software Foundation. All rights reserved. Deleted: python/branches/py3k/RELNOTES ============================================================================== --- python/branches/py3k/RELNOTES Sat Apr 4 23:08:03 2009 +++ (empty file) @@ -1,29 +0,0 @@ -Python 3 Release Notes -====================== - -These release notes describe unfinished work, or important notes that Python 3 -adopters need to be aware of. This is not a complete list of changes for -Python 3 -- for that, see Misc/NEWS. - -Please report bugs to http://bugs.python.org/ - -The list of all known open issues for Python 3 can be found here: - -http://bugs.python.org/issue?%40search_text=&title=&%40columns=title&id=&%40columns=id&creation=&creator=&activity=&%40columns=activity&%40sort=activity&actor=&nosy=&type=&components=&versions=12&dependencies=&assignee=&keywords=&priority=&%40group=priority&status=1&%40columns=status&resolution=&%40pagesize=50&%40startwith=0&%40queryname=&%40old-queryname=&%40action=search - - -Additional notes for Python 3 ------------------------------ - -* The bsddb3 package has been removed from the standard library. It is - available as a separate distutils based package from the Python Cheeseshop. - If you need bsddb3 support in Python 3, you can find it here: - - http://pypi.python.org/pypi/bsddb3 - -* The email package needs quite a bit of work to make it consistent with - respect to bytes and strings. There have been discussions on - email-sig at python.org about where to go with the email package for Python 3, - but this was not resolved in time for 3.0 final. With enough care though, - the email package in Python 3 should be about as usable as it is with Python - 2. From python-checkins at python.org Sat Apr 4 23:11:32 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 4 Apr 2009 23:11:32 +0200 (CEST) Subject: [Python-checkins] r71195 - python/branches/py3k-short-float-repr/Modules/_pickle.c Message-ID: <20090404211132.1AAB61E4020@bag.python.org> Author: mark.dickinson Date: Sat Apr 4 23:11:31 2009 New Revision: 71195 Log: Use repr formatting in pickle (without extra .0) Modified: python/branches/py3k-short-float-repr/Modules/_pickle.c Modified: python/branches/py3k-short-float-repr/Modules/_pickle.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_pickle.c (original) +++ python/branches/py3k-short-float-repr/Modules/_pickle.c Sat Apr 4 23:11:31 2009 @@ -1025,7 +1025,7 @@ if (pickler_write(self, &op, 1) < 0) goto done; - buf = PyOS_double_to_string(x, 'g', 17, 0); + buf = PyOS_double_to_string(x, 'r', 0, 0); if (!buf) { PyErr_NoMemory(); goto done; From python-checkins at python.org Sat Apr 4 23:11:59 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 4 Apr 2009 23:11:59 +0200 (CEST) Subject: [Python-checkins] r71196 - in python/branches/py3k-short-float-repr: Objects/floatobject.c Python/marshal.c Message-ID: <20090404211159.4702A1E4020@bag.python.org> Author: mark.dickinson Date: Sat Apr 4 23:11:59 2009 New Revision: 71196 Log: No need for the .0 in marshal. Let's save some bytes! Modified: python/branches/py3k-short-float-repr/Objects/floatobject.c python/branches/py3k-short-float-repr/Python/marshal.c Modified: python/branches/py3k-short-float-repr/Objects/floatobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/floatobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/floatobject.c Sat Apr 4 23:11:59 2009 @@ -1917,8 +1917,8 @@ if (PyFloat_CheckExact(p) && Py_REFCNT(p) != 0) { char *buf = PyOS_double_to_string( - PyFloat_AS_DOUBLE(p), 'g', - 0, Py_DTSF_ADD_DOT_0); + PyFloat_AS_DOUBLE(p), 'r', + 0, 0); if (buf) { /* XXX(twouters) cast refcount to long Modified: python/branches/py3k-short-float-repr/Python/marshal.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/marshal.c (original) +++ python/branches/py3k-short-float-repr/Python/marshal.c Sat Apr 4 23:11:59 2009 @@ -237,7 +237,7 @@ } else { char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v), - 'r', 0, Py_DTSF_ADD_DOT_0); + 'r', 0, 0); if (!buf) return; n = strlen(buf); @@ -269,7 +269,7 @@ char *buf; w_byte(TYPE_COMPLEX, p); buf = PyOS_double_to_string(PyComplex_RealAsDouble(v), - 'r', 0, Py_DTSF_ADD_DOT_0); + 'r', 0, 0); if (!buf) return; n = strlen(buf); @@ -277,7 +277,7 @@ w_string(buf, (int)n, p); PyMem_Free(buf); buf = PyOS_double_to_string(PyComplex_ImagAsDouble(v), - 'r', 0, Py_DTSF_ADD_DOT_0); + 'r', 0, 0); if (!buf) return; n = strlen(buf); From python-checkins at python.org Sat Apr 4 23:16:52 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 4 Apr 2009 23:16:52 +0200 (CEST) Subject: [Python-checkins] r71197 - python/tags/r31a2 Message-ID: <20090404211652.2224B1E4020@bag.python.org> Author: benjamin.peterson Date: Sat Apr 4 23:16:51 2009 New Revision: 71197 Log: tag 3.1a2 Added: python/tags/r31a2/ - copied from r71196, /python/branches/py3k/ From python-checkins at python.org Sun Apr 5 00:19:12 2009 From: python-checkins at python.org (brett.cannon) Date: Sun, 5 Apr 2009 00:19:12 +0200 (CEST) Subject: [Python-checkins] r71198 - peps/trunk/pep-3143.txt Message-ID: <20090404221912.3AF7D1E4049@bag.python.org> Author: brett.cannon Date: Sun Apr 5 00:19:09 2009 New Revision: 71198 Log: Update to PEP 3143 as sent in by the PEP author. Modified: peps/trunk/pep-3143.txt Modified: peps/trunk/pep-3143.txt ============================================================================== --- peps/trunk/pep-3143.txt (original) +++ peps/trunk/pep-3143.txt Sun Apr 5 00:19:09 2009 @@ -54,7 +54,7 @@ from spam import do_main_program - with daemon.DaemonContext() as daemon_context: + with daemon.DaemonContext(): do_main_program() More complex example usage:: @@ -312,27 +312,27 @@ * If the `pidfile` attribute is not ``None``, enter its context manager. + * Register the `close` method to be called during Python's exit + processing. + When the function returns, the running program is a daemon process. `close()` :Return: ``None`` - Close the daemon context. This does nothing by default, but may be - overridden by a derived class. + Close the daemon context. This performs the following step: + + * If the `pidfile` attribute is not ``None``, exit its context + manager. `terminate(signal_number, stack_frame)` :Return: ``None`` Signal handler for the ``signal.SIGTERM`` signal. Performs the - following steps: - - * If the `pidfile` attribute is not ``None``, exit its context - manager. - - * Call the `close()` method. + following step: - * Raise a ``SystemExit`` exception. + * Raise a ``SystemExit`` exception explaining the signal. The class also implements the context manager protocol via ``__enter__`` and ``__exit__`` methods. @@ -577,8 +577,8 @@ Local variables: mode: rst coding: utf-8 - time-stamp-start: "^:Last-Modified:[ ]+" - time-stamp-end: "$" + time-stamp-start: "^Last-Modified:[ ]+\$Date: " + time-stamp-end: " \$$" time-stamp-line-limit: 20 time-stamp-format: "%:y-%02m-%02d %02H:%02M" End: From python-checkins at python.org Sun Apr 5 00:39:35 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 5 Apr 2009 00:39:35 +0200 (CEST) Subject: [Python-checkins] r71199 - in python/branches/py3k-short-float-repr: Objects/complexobject.c Objects/floatobject.c Python/pystrtod.c Message-ID: <20090404223935.0821E1E4066@bag.python.org> Author: eric.smith Date: Sun Apr 5 00:39:34 2009 New Revision: 71199 Log: Removed PREC_STR and hard-coded 's' precision inside PyOS_double_to_string(). Modified: python/branches/py3k-short-float-repr/Objects/complexobject.c python/branches/py3k-short-float-repr/Objects/floatobject.c python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Objects/complexobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/complexobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/complexobject.c Sun Apr 5 00:39:34 2009 @@ -14,15 +14,6 @@ #ifndef WITHOUT_COMPLEX -/* Precision used by str(). - - The str() precision is chosen so that in most cases, the rounding noise - created by various operations is suppressed, while giving plenty of - precision for practical use. -*/ - -#define PREC_STR 12 - /* elementary operations on complex numbers */ static Py_complex c_1 = {1., 0.}; @@ -339,7 +330,7 @@ static PyObject * -complex_format(PyComplexObject *v, char format_code, int precision) +complex_format(PyComplexObject *v, char format_code) { PyObject *result = NULL; Py_ssize_t len; @@ -368,8 +359,7 @@ im = "-inf*"; } else { - pim = PyOS_double_to_string(v->cval.imag, format_code, - precision, 0); + pim = PyOS_double_to_string(v->cval.imag, format_code, 0, 0); if (!pim) { PyErr_NoMemory(); goto done; @@ -388,8 +378,7 @@ re = "-inf"; } else { - pre = PyOS_double_to_string(v->cval.real, format_code, - precision, 0); + pre = PyOS_double_to_string(v->cval.real, format_code, 0, 0); if (!pre) { PyErr_NoMemory(); goto done; @@ -408,7 +397,7 @@ } else { pim = PyOS_double_to_string(v->cval.imag, format_code, - precision, Py_DTSF_SIGN); + 0, Py_DTSF_SIGN); if (!pim) { PyErr_NoMemory(); goto done; @@ -438,13 +427,13 @@ static PyObject * complex_repr(PyComplexObject *v) { - return complex_format(v, 'r', 0); + return complex_format(v, 'r'); } static PyObject * complex_str(PyComplexObject *v) { - return complex_format(v, 's', PREC_STR); + return complex_format(v, 's'); } static long Modified: python/branches/py3k-short-float-repr/Objects/floatobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/floatobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/floatobject.c Sun Apr 5 00:39:34 2009 @@ -354,23 +354,12 @@ return 0; } -/* Precision used by str(). - - The str() precision is chosen so that in most cases, the rounding noise - created by various operations is suppressed, while giving plenty of - precision for practical use. - -*/ - -#define PREC_STR 12 - static PyObject * -float_str_or_repr(PyFloatObject *v, char format_code, int precision) +float_str_or_repr(PyFloatObject *v, char format_code) { PyObject *result; char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v), - format_code, precision, - Py_DTSF_ADD_DOT_0); + format_code, 0, Py_DTSF_ADD_DOT_0); if (!buf) return PyErr_NoMemory(); result = PyUnicode_FromString(buf); @@ -381,13 +370,13 @@ static PyObject * float_repr(PyFloatObject *v) { - return float_str_or_repr(v, 'r', 0); + return float_str_or_repr(v, 'r'); } static PyObject * float_str(PyFloatObject *v) { - return float_str_or_repr(v, 's', PREC_STR); + return float_str_or_repr(v, 's'); } /* Comparison is pretty much a nightmare. When comparing float to float, Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Sun Apr 5 00:39:34 2009 @@ -746,9 +746,20 @@ case 'r': /* "repr" pseudo-mode */ mode = 0; + /* Supplied precision is unused, must be 0. */ + if (precision != 0) { + PyErr_BadInternalCall(); + return NULL; + } break; case 's': mode = 2; + /* Supplied precision is unused, must be 0. */ + if (precision != 0) { + PyErr_BadInternalCall(); + return NULL; + } + precision = 12; break; } From python-checkins at python.org Sun Apr 5 00:42:39 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 5 Apr 2009 00:42:39 +0200 (CEST) Subject: [Python-checkins] r71200 - python/branches/py3k-short-float-repr Message-ID: <20090404224239.71B6D1E4066@bag.python.org> Author: eric.smith Date: Sun Apr 5 00:42:38 2009 New Revision: 71200 Log: Initialized merge tracking via "svnmerge" with revisions "1-70732" from svn+ssh://pythondev at svn.python.org/python/branches/py3k Modified: python/branches/py3k-short-float-repr/ (props changed) From buildbot at python.org Sun Apr 5 00:57:00 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 22:57:00 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090404225700.843CA1E4066@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/480 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: eric.smith,martin.v.loewis,michael.foord BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 249, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 102, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Sun Apr 5 01:04:27 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 5 Apr 2009 01:04:27 +0200 (CEST) Subject: [Python-checkins] r71201 - in python/branches/py3k-short-float-repr: Demo/distutils/test2to3 Demo/distutils/test2to3/setup.py Demo/distutils/test2to3/test Doc/c-api/arg.rst Doc/c-api/exceptions.rst Doc/c-api/import.rst Doc/c-api/long.rst Doc/distutils/setupscript.rst Doc/extending/extending.rst Doc/extending/newtypes.rst Doc/howto/regex.rst Doc/library/abc.rst Doc/library/aifc.rst Doc/library/asynchat.rst Doc/library/atexit.rst Doc/library/base64.rst Doc/library/bdb.rst Doc/library/binascii.rst Doc/library/collections.rst Doc/library/csv.rst Doc/library/datetime.rst Doc/library/email.header.rst Doc/library/functions.rst Doc/library/http.client.rst Doc/library/importlib.rst Doc/library/io.rst Doc/library/mmap.rst Doc/library/os.path.rst Doc/library/pickle.rst Doc/library/pickletools.rst Doc/library/random.rst Doc/library/shelve.rst Doc/library/time.rst Doc/library/unittest.rst Doc/library/urllib.error.rst Doc/library/urllib.request.rst Doc/license.rst Doc/reference/datamodel.rst Doc/whatsnew/3.1.rst Grammar/Grammar Include/bytesobject.h Include/code.h Include/compile.h Include/import.h Include/parsetok.h Include/patchlevel.h Include/pythonrun.h Include/unicodeobject.h Lib/__future__.py Lib/_abcoll.py Lib/_pyio.py Lib/_strptime.py Lib/bisect.py Lib/cgitb.py Lib/collections.py Lib/distutils/__init__.py Lib/distutils/cmd.py Lib/distutils/command/build_ext.py Lib/distutils/command/install_data.py Lib/distutils/command/install_headers.py Lib/distutils/command/register.py Lib/distutils/command/upload.py Lib/distutils/extension.py Lib/distutils/tests/support.py Lib/distutils/tests/test_build_ext.py Lib/distutils/tests/test_clean.py Lib/distutils/tests/test_config.py Lib/distutils/tests/test_install_data.py Lib/distutils/tests/test_install_headers.py Lib/distutils/tests/test_msvc9compiler.py Lib/distutils/tests/test_register.py Lib/distutils/tests/test_sdist.py Lib/distutils/tests/test_upload.py Lib/distutils/util.py Lib/email/generator.py Lib/email/test/test_email.py Lib/email/test/test_email_codecs.py Lib/email/test/test_email_codecs_renamed.py Lib/http/client.py Lib/http/cookies.py Lib/http/server.py Lib/idlelib/EditorWindow.py Lib/idlelib/NEWS.txt Lib/idlelib/PyShell.py Lib/idlelib/idlever.py Lib/idlelib/rpc.py Lib/idlelib/run.py Lib/importlib/_bootstrap.py Lib/importlib/test/import_/test_path.py Lib/importlib/test/source/test_abc_loader.py Lib/importlib/test/util.py Lib/io.py Lib/locale.py Lib/mailbox.py Lib/multiprocessing/queues.py Lib/site.py Lib/symtable.py Lib/test/buffer_tests.py Lib/test/regrtest.py Lib/test/support.py Lib/test/test___all__.py Lib/test/test_asynchat.py Lib/test/test_bz2.py Lib/test/test_collections.py Lib/test/test_crypt.py Lib/test/test_csv.py Lib/test/test_ctypes.py Lib/test/test_curses.py Lib/test/test_dbm.py Lib/test/test_dbm_gnu.py Lib/test/test_dbm_ndbm.py Lib/test/test_exceptions.py Lib/test/test_fcntl.py Lib/test/test_flufl.py Lib/test/test_fork1.py Lib/test/test_functools.py Lib/test/test_gc.py Lib/test/test_grp.py Lib/test/test_http_cookiejar.py Lib/test/test_http_cookies.py Lib/test/test_imp.py Lib/test/test_io.py Lib Message-ID: <20090404230427.3F8E51E4073@bag.python.org> Author: eric.smith Date: Sun Apr 5 01:04:14 2009 New Revision: 71201 Log: Merged revisions 70733-71200 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r70736 | ronald.oussoren | 2009-03-30 15:25:21 -0400 (Mon, 30 Mar 2009) | 10 lines Merged revisions 70735 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70735 | ronald.oussoren | 2009-03-30 14:22:56 -0500 (Mon, 30 Mar 2009) | 3 lines Remove usage of the deprecated '-cString' and '+stringWithCString:' API's in PythonLauncher, replacing them with the correct counterparts. ........ ................ r70739 | ronald.oussoren | 2009-03-30 15:39:14 -0400 (Mon, 30 Mar 2009) | 13 lines Merged revisions 70737 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70737 | ronald.oussoren | 2009-03-30 14:34:51 -0500 (Mon, 30 Mar 2009) | 6 lines * Set a custom icon on the Python installer DMG * Remove last traces of "MacPython" * Add options to build different flavors of the installer (still defaulting to a 2-way universal build that runs on OSX 10.3) ........ ................ r70740 | ronald.oussoren | 2009-03-30 15:51:09 -0400 (Mon, 30 Mar 2009) | 3 lines Enable "--with-computed-gotos" for the binary installer on OSX. ................ r70742 | brett.cannon | 2009-03-30 15:57:15 -0400 (Mon, 30 Mar 2009) | 5 lines Fix importlib.machinery.PathFinder.find_module() to essentially skip over None entries in sys.path_importer_cache. While this differs from semantics in how __import__ works, it prevents any implicit semantics from taking hold with users. ................ r70745 | ronald.oussoren | 2009-03-30 16:00:00 -0400 (Mon, 30 Mar 2009) | 9 lines Merged revisions 70741 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70741 | ronald.oussoren | 2009-03-30 14:56:25 -0500 (Mon, 30 Mar 2009) | 2 lines Fixes issue 5270 ........ ................ r70749 | ronald.oussoren | 2009-03-30 16:05:35 -0400 (Mon, 30 Mar 2009) | 9 lines Merged revisions 70746 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70746 | ronald.oussoren | 2009-03-30 15:02:08 -0500 (Mon, 30 Mar 2009) | 2 lines Fix for issue 13095 ........ ................ r70750 | ronald.oussoren | 2009-03-30 16:10:18 -0400 (Mon, 30 Mar 2009) | 2 lines Fix for issue 5558 ................ r70751 | guido.van.rossum | 2009-03-30 16:34:57 -0400 (Mon, 30 Mar 2009) | 2 lines Thorough review of importlib docs. Reviewed by Brett himself. ................ r70753 | georg.brandl | 2009-03-30 17:21:05 -0400 (Mon, 30 Mar 2009) | 1 line Remove merging leftover. ................ r70755 | brett.cannon | 2009-03-30 17:30:26 -0400 (Mon, 30 Mar 2009) | 6 lines Make sure time.strptime only accepts strings (and document the fact like strftime). Already didn't accept bytes but make the check earlier. This also lifts the limitation of requiring ASCII. Closes issue #5236. Thanks Tennessee Leeuwenburg. ................ r70760 | senthil.kumaran | 2009-03-30 17:54:41 -0400 (Mon, 30 Mar 2009) | 3 lines Fix for Issue4962, issue4675. ................ r70762 | guido.van.rossum | 2009-03-30 18:01:35 -0400 (Mon, 30 Mar 2009) | 8 lines Issue #5604: non-ASCII characters in module name passed to imp.find_module() were converted to UTF-8 while the path is converted to the default filesystem encoding, causing nonsense. Thanks to Andrew Svetlov. (This time to the right branch. Will block duplicate merge to 3.0.2.) ................ r70774 | jesse.noller | 2009-03-30 18:59:27 -0400 (Mon, 30 Mar 2009) | 1 line finalize the queue to resolve test issue ................ r70780 | barry.warsaw | 2009-03-30 19:12:30 -0400 (Mon, 30 Mar 2009) | 4 lines "Port" the fix for issue 1974 from the trunk (2.7). Because Python 3.x does things much better, less changes are necessary. This also shoves test_email_codecs_rename.py onto test_email_codecs.py even though the test needs to be ported to Python 3. ................ r70782 | ronald.oussoren | 2009-03-30 19:16:10 -0400 (Mon, 30 Mar 2009) | 11 lines Merged revisions 70778 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70778 | ronald.oussoren | 2009-03-30 18:10:35 -0500 (Mon, 30 Mar 2009) | 4 lines Fix issue #4865: add /Library/Python/2.7/site-packages to sys.path on OSX, to make it easier to share (some) installed packages between the system install and a user install. ........ ................ r70786 | georg.brandl | 2009-03-30 20:33:15 -0400 (Mon, 30 Mar 2009) | 1 line Add example for new copydir_run_2to3(). ................ r70787 | georg.brandl | 2009-03-30 20:34:54 -0400 (Mon, 30 Mar 2009) | 1 line Add new copydir_run_2to3() function, for use e.g. in test runners to transparently convert and run tests written for Python 2. ................ r70791 | jesse.noller | 2009-03-30 23:25:07 -0400 (Mon, 30 Mar 2009) | 1 line merge 70783 to py3k ................ r70794 | jesse.noller | 2009-03-30 23:37:07 -0400 (Mon, 30 Mar 2009) | 1 line merge 70792 to py3k ................ r70796 | brett.cannon | 2009-03-30 23:58:04 -0400 (Mon, 30 Mar 2009) | 3 lines The message for the exception when time.strptime was passed something other than str did not output the type of the argument but the object itself. ................ r70797 | georg.brandl | 2009-03-31 00:16:10 -0400 (Tue, 31 Mar 2009) | 1 line Fix segfaults when running test_exceptions with coverage tracing, caused by wrongly defining Exception.__context__ as a T_OBJECT structmember which does not set the member to NULL on None assignment, and generally does not do type checks. This could be used to crash the interpreter by setting any object to __context__. The same applies to __cause__. Also document the PyException_* functions. ................ r70806 | ronald.oussoren | 2009-03-31 09:25:17 -0400 (Tue, 31 Mar 2009) | 11 lines Merged revisions 70802 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70802 | ronald.oussoren | 2009-03-31 08:20:45 -0500 (Tue, 31 Mar 2009) | 4 lines Minor update to OSX build-installer script, needed to ensure that the build will succeed in a clean checkout and with a non-default deployment target. ........ ................ r70808 | hirokazu.yamamoto | 2009-03-31 09:44:06 -0400 (Tue, 31 Mar 2009) | 9 lines Merged revisions 70800 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70800 | hirokazu.yamamoto | 2009-03-31 22:13:05 +0900 | 1 line Issue #5387: Fixed mmap.move crash by integer overflow. ........ ................ r70815 | jeremy.hylton | 2009-03-31 10:35:53 -0400 (Tue, 31 Mar 2009) | 12 lines Simplify the Request class. The basic components of the parsed Request are now available as public attributes, e.g. full_url and host. The accessor methods are deprecated. The implementation replace the complicated __getattr__ machinery with a _parse() method. The response from an HTTP request is now an HTTPResponse instance instead of an addinfourl() wrapper instance. The wrapper provided minimal extract functionality and was undocumented. The API of addinfourl() was preserved, except for close hooks, by adding a few methods and public attributes to the HTTPResponse class. ................ r70816 | jeremy.hylton | 2009-03-31 10:37:44 -0400 (Tue, 31 Mar 2009) | 2 lines Change email address. ................ r70817 | jeremy.hylton | 2009-03-31 10:38:13 -0400 (Tue, 31 Mar 2009) | 2 lines Document public attributes of urllib.request.Request. ................ r70818 | jeremy.hylton | 2009-03-31 10:40:19 -0400 (Tue, 31 Mar 2009) | 2 lines Update HTTPResponse documentation and add placeholder for HTTPMessage. ................ r70823 | jeremy.hylton | 2009-03-31 11:26:37 -0400 (Tue, 31 Mar 2009) | 29 lines Merged revisions 70801,70809 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk The merge ran into a lot of conflicts because dicts were replaced with sets in the Python 3 version of the symbol table. ........ r70801 | jeremy.hylton | 2009-03-31 09:17:03 -0400 (Tue, 31 Mar 2009) | 3 lines Add is_declared_global() which distinguishes between implicit and explicit global variables. ........ r70809 | jeremy.hylton | 2009-03-31 09:48:15 -0400 (Tue, 31 Mar 2009) | 14 lines Global statements from one function leaked into parallel functions. Re http://bugs.python.org/issue4315 The symbol table used the same name dictionaries to recursively analyze each of its child blocks, even though the dictionaries are modified during analysis. The fix is to create new temporary dictionaries via the analyze_child_block(). The only information that needs to propagate back up is the names of the free variables. Add more comments and break out a helper function. This code doesn't get any easier to understand when you only look at it once a year. ........ ................ r70826 | georg.brandl | 2009-03-31 11:48:12 -0400 (Tue, 31 Mar 2009) | 8 lines Blocked revisions 70825 via svnmerge ........ r70825 | georg.brandl | 2009-03-31 10:46:30 -0500 (Di, 31 M??r 2009) | 1 line #5566: fix versionadded from PyLong ssize_t functions. ........ ................ r70827 | georg.brandl | 2009-03-31 11:49:02 -0400 (Tue, 31 Mar 2009) | 1 line #5566: remove duplicate entry. ................ r70829 | georg.brandl | 2009-03-31 11:52:41 -0400 (Tue, 31 Mar 2009) | 1 line #5548: do return the new module from PyMODINIT_FUNC functions. ................ r70833 | jeremy.hylton | 2009-03-31 12:37:16 -0400 (Tue, 31 Mar 2009) | 3 lines Make urllib use HTTP/1.1. It seems to work now, but hasn't been carefully tested. ................ r70839 | georg.brandl | 2009-03-31 12:55:13 -0400 (Tue, 31 Mar 2009) | 8 lines Blocked revisions 70838 via svnmerge ........ r70838 | georg.brandl | 2009-03-31 11:54:38 -0500 (Di, 31 M??r 2009) | 1 line #992207: document that the parser only accepts \\n newlines. ........ ................ r70840 | georg.brandl | 2009-03-31 12:57:13 -0400 (Tue, 31 Mar 2009) | 1 line Forward-port of #992207 fix: document that the parser only accepts \\n newlines. (And remove a leftover footnote.) ................ r70843 | kristjan.jonsson | 2009-03-31 13:43:39 -0400 (Tue, 31 Mar 2009) | 2 lines get_file() no longer leaks a FILE structure. If given a file descriptor, it calls dup() to get a new handle. Then both the FILE object and the fd can be closed. This is important, because otherwise, the leaked FILE object will be closed on process exit, causing assertions on Windows, e.g. in the test_multiprocessing.py regression test. ................ r70845 | kristjan.jonsson | 2009-03-31 13:47:50 -0400 (Tue, 31 Mar 2009) | 1 line Fix a leaking "pathname" in import.c ................ r70846 | raymond.hettinger | 2009-03-31 13:51:51 -0400 (Tue, 31 Mar 2009) | 1 line Per the language summit, the optional fastpath imports should use from-import-star. ................ r70853 | r.david.murray | 2009-03-31 14:27:51 -0400 (Tue, 31 Mar 2009) | 10 lines Merged revisions 70779 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70779 | r.david.murray | 2009-03-30 19:10:37 -0400 (Mon, 30 Mar 2009) | 3 lines Actually suppress warnings in test_at_least_import_untested_modules inside the catch_warnings context manager. ........ ................ r70860 | georg.brandl | 2009-03-31 14:40:41 -0400 (Tue, 31 Mar 2009) | 8 lines Blocked revisions 70858 via svnmerge ........ r70858 | georg.brandl | 2009-03-31 13:38:56 -0500 (Di, 31 M??r 2009) | 1 line #5241: document missing U in regex howto. ........ ................ r70861 | georg.brandl | 2009-03-31 14:41:03 -0400 (Tue, 31 Mar 2009) | 1 line #5241: document missing A in regex howto. ................ r70862 | jesse.noller | 2009-03-31 14:48:42 -0400 (Tue, 31 Mar 2009) | 13 lines Merged revisions 70849,70852 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70849 | jesse.noller | 2009-03-31 13:12:35 -0500 (Tue, 31 Mar 2009) | 1 line Apply patch for netbsd multiprocessing support ........ r70852 | jesse.noller | 2009-03-31 13:27:14 -0500 (Tue, 31 Mar 2009) | 1 line missed the news/acks for netbsd patch ........ ................ r70863 | georg.brandl | 2009-03-31 14:56:38 -0400 (Tue, 31 Mar 2009) | 1 line #1717: fix-up docs for comparison in newtypes document. ................ r70865 | georg.brandl | 2009-03-31 15:06:37 -0400 (Tue, 31 Mar 2009) | 1 line Add missing label. ................ r70884 | hirokazu.yamamoto | 2009-03-31 16:43:56 -0400 (Tue, 31 Mar 2009) | 9 lines Merged revisions 70879 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70879 | hirokazu.yamamoto | 2009-04-01 05:14:04 +0900 | 1 line Issue #5387: Fixed mmap.move crash by integer overflow. (take2) ........ ................ r70898 | tarek.ziade | 2009-03-31 17:37:16 -0400 (Tue, 31 Mar 2009) | 29 lines Merged revisions 70886,70888-70892 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70886 | tarek.ziade | 2009-03-31 15:50:59 -0500 (Tue, 31 Mar 2009) | 1 line added tests for the clean command ........ r70888 | tarek.ziade | 2009-03-31 15:53:13 -0500 (Tue, 31 Mar 2009) | 1 line more tests for the register command ........ r70889 | tarek.ziade | 2009-03-31 15:53:55 -0500 (Tue, 31 Mar 2009) | 1 line more tests for the upload command ........ r70890 | tarek.ziade | 2009-03-31 15:54:38 -0500 (Tue, 31 Mar 2009) | 1 line added test to the install_data command ........ r70891 | tarek.ziade | 2009-03-31 15:55:21 -0500 (Tue, 31 Mar 2009) | 1 line added tests to the install_headers command ........ r70892 | tarek.ziade | 2009-03-31 15:56:11 -0500 (Tue, 31 Mar 2009) | 1 line making sdist and config test silents ........ ................ r70913 | jesse.noller | 2009-03-31 18:36:44 -0400 (Tue, 31 Mar 2009) | 9 lines Merged revisions 70908 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70908 | jesse.noller | 2009-03-31 17:20:35 -0500 (Tue, 31 Mar 2009) | 1 line Issue 5619: Pass MS CRT debug flags into subprocesses ........ ................ r70914 | tarek.ziade | 2009-03-31 18:37:55 -0400 (Tue, 31 Mar 2009) | 9 lines Merged revisions 70910 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70910 | tarek.ziade | 2009-03-31 17:27:23 -0500 (Tue, 31 Mar 2009) | 1 line #5583 Added optional Extensions in Distutils ........ ................ r70917 | martin.v.loewis | 2009-03-31 18:42:41 -0400 (Tue, 31 Mar 2009) | 2 lines Readd -n. ................ r70921 | georg.brandl | 2009-03-31 18:46:50 -0400 (Tue, 31 Mar 2009) | 1 line Run 2to3 over new script. ................ r70924 | tarek.ziade | 2009-03-31 18:50:54 -0400 (Tue, 31 Mar 2009) | 13 lines Merged revisions 70920,70922 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70920 | tarek.ziade | 2009-03-31 17:44:10 -0500 (Tue, 31 Mar 2009) | 1 line catching msvc9compiler error as well ........ r70922 | tarek.ziade | 2009-03-31 17:47:01 -0500 (Tue, 31 Mar 2009) | 1 line fixed the test for win32 CompileError ........ ................ r70925 | raymond.hettinger | 2009-03-31 18:52:48 -0400 (Tue, 31 Mar 2009) | 1 line Improve examples for collections.deque() ................ r70928 | benjamin.peterson | 2009-03-31 19:11:32 -0400 (Tue, 31 Mar 2009) | 1 line fix TextIOWrapper.read() when the buffer is not readable #5628 ................ r70929 | r.david.murray | 2009-03-31 19:16:50 -0400 (Tue, 31 Mar 2009) | 43 lines Merged revisions 70734,70775,70856,70874,70876-70877 via svnmerge ........ r70734 | r.david.murray | 2009-03-30 15:04:00 -0400 (Mon, 30 Mar 2009) | 7 lines Add import_function method to test.test_support, and modify a number of tests that expect to be skipped if imports fail or functions don't exist to use import_function and import_module. The ultimate goal is to change regrtest to not skip automatically on ImportError. Checking in now to make sure the buldbots don't show any errors on platforms I can't direct test on. ........ r70775 | r.david.murray | 2009-03-30 19:05:48 -0400 (Mon, 30 Mar 2009) | 4 lines Change more tests to use import_module for the modules that should cause tests to be skipped. Also rename import_function to the more descriptive get_attribute and add a docstring. ........ r70856 | r.david.murray | 2009-03-31 14:32:17 -0400 (Tue, 31 Mar 2009) | 7 lines A few more test skips via import_module, and change import_module to return the error message produced by importlib, so that if an import in the package whose import is being wrapped is what failed the skip message will contain the name of that module instead of the name of the wrapped module. Also fixed formatting of some previous comments. ........ r70874 | r.david.murray | 2009-03-31 15:33:15 -0400 (Tue, 31 Mar 2009) | 5 lines Improve test_support.import_module docstring, remove deprecated flag from get_attribute since it isn't likely to do anything useful. ........ r70876 | r.david.murray | 2009-03-31 15:49:15 -0400 (Tue, 31 Mar 2009) | 4 lines Remove the regrtest check that turns any ImportError into a skipped test. Hopefully all modules whose imports legitimately result in a skipped test have been properly wrapped by the previous commits. ........ r70877 | r.david.murray | 2009-03-31 15:57:24 -0400 (Tue, 31 Mar 2009) | 2 lines Add NEWS entry for regrtest change. ........ ................ r70932 | r.david.murray | 2009-03-31 19:50:31 -0400 (Tue, 31 Mar 2009) | 10 lines Merged revisions 70930 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70930 | r.david.murray | 2009-03-31 19:45:39 -0400 (Tue, 31 Mar 2009) | 3 lines Fix Windows test skip error revealed by buildbot. Also a comment spelling correction in a previously fixed test. ........ ................ r70935 | jeremy.hylton | 2009-03-31 22:35:56 -0400 (Tue, 31 Mar 2009) | 2 lines An HTTPResponse is, by its nature, readable. ................ r70937 | brett.cannon | 2009-03-31 23:35:20 -0400 (Tue, 31 Mar 2009) | 1 line Rip out a useless method that the superclass implements properly. ................ r70938 | r.david.murray | 2009-03-31 23:42:00 -0400 (Tue, 31 Mar 2009) | 11 lines Merged revisions 70936 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70936 | r.david.murray | 2009-03-31 23:21:43 -0400 (Tue, 31 Mar 2009) | 4 lines Fix issue 2522. locale.format now checks that it is passed exactly one pattern, which avoids mysterious errors where it had seemed to fail to do localization. ........ ................ r70941 | jack.diederich | 2009-04-01 00:27:09 -0400 (Wed, 01 Apr 2009) | 9 lines Merged revisions 70931 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70931 | jack.diederich | 2009-03-31 19:46:48 -0400 (Tue, 31 Mar 2009) | 1 line #5228: add pickle support to functools.partial ........ ................ r70942 | georg.brandl | 2009-04-01 00:27:47 -0400 (Wed, 01 Apr 2009) | 8 lines Merged revisions 70940 via svnmerge ........ r70940 | georg.brandl | 2009-03-31 23:21:14 -0500 (Di, 31 M??r 2009) | 2 lines The SimpleXMLRPCServer's CGI handler now runs like a pony. ........ ................ r70943 | georg.brandl | 2009-04-01 00:28:33 -0400 (Wed, 01 Apr 2009) | 8 lines Merged revisions 70940 via svnmerge ........ r70940 | georg.brandl | 2009-03-31 23:21:14 -0500 (Di, 31 M??r 2009) | 2 lines The SimpleXMLRPCServer's CGI handler now runs like a pony. ........ ................ r70945 | brett.cannon | 2009-04-01 01:08:41 -0400 (Wed, 01 Apr 2009) | 2 lines The BDFL has retired! Long live the FLUFL (Friendly Language Uncle For Life)! ................ r70948 | kristjan.jonsson | 2009-04-01 07:28:47 -0400 (Wed, 01 Apr 2009) | 1 line Allow skipping of regression tests not supported on windows. This reduces noise in the regression test suite for py3k on Windows. ................ r70952 | ronald.oussoren | 2009-04-01 10:59:59 -0400 (Wed, 01 Apr 2009) | 3 lines Fix typo in configure line that caused the build installer to not use the right LDFLAGS settings. ................ r70955 | georg.brandl | 2009-04-01 11:53:15 -0400 (Wed, 01 Apr 2009) | 1 line #5636: fix next -> __next__ in csv reader docs. ................ r70957 | brett.cannon | 2009-04-01 12:06:01 -0400 (Wed, 01 Apr 2009) | 12 lines Merged revisions 70956 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70956 | brett.cannon | 2009-04-01 09:00:34 -0700 (Wed, 01 Apr 2009) | 5 lines The cgitb module had imports in its functions. This can cause deadlock with the import lock if called from within a thread that was triggered by an import. Partially fixes issue #1665206. ........ ................ r70959 | r.david.murray | 2009-04-01 12:39:21 -0400 (Wed, 01 Apr 2009) | 2 lines Remove redundant import of tkinter. ................ r70966 | brett.cannon | 2009-04-01 14:13:07 -0400 (Wed, 01 Apr 2009) | 12 lines Merged revisions 70965 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70965 | brett.cannon | 2009-04-01 11:03:59 -0700 (Wed, 01 Apr 2009) | 5 lines _warnings was importing itself to get an attribute. That's bad if warnings gets called in a thread that was spawned by an import itself. Last part to close #1665206. ........ ................ r70974 | raymond.hettinger | 2009-04-01 15:05:50 -0400 (Wed, 01 Apr 2009) | 1 line Issue #5647: MutableSet.__iand__() no longer mutates self during iteration. ................ r70976 | brett.cannon | 2009-04-01 16:01:47 -0400 (Wed, 01 Apr 2009) | 11 lines Merged revisions 70975 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70975 | brett.cannon | 2009-04-01 12:57:10 -0700 (Wed, 01 Apr 2009) | 4 lines test_logging was blindly clearing the warnings filter. This caused PendingDeprecationWarnings to be spewed all over by unittest.failIf*(). Fix moves over to using warnings.catch_warning to protect the warnings filter. ........ ................ r70978 | senthil.kumaran | 2009-04-01 16:20:43 -0400 (Wed, 01 Apr 2009) | 3 lines Fix for issue5040. Adding support for unicode message passing and tests for unicode message and test for Content-Length. ................ r70982 | brett.cannon | 2009-04-01 16:27:29 -0400 (Wed, 01 Apr 2009) | 10 lines Merged revisions 70979 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70979 | brett.cannon | 2009-04-01 13:25:48 -0700 (Wed, 01 Apr 2009) | 3 lines test_warnings ironically had a single test that was not protecting the warnings filter and was resetting it. ........ ................ r70983 | benjamin.peterson | 2009-04-01 16:38:13 -0400 (Wed, 01 Apr 2009) | 1 line barry has already been causing test breakage ................ r70984 | brett.cannon | 2009-04-01 16:47:14 -0400 (Wed, 01 Apr 2009) | 1 line Add some clarification to the importlib docs. ................ r70987 | jesse.noller | 2009-04-01 16:51:28 -0400 (Wed, 01 Apr 2009) | 9 lines Merged revisions 70953 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70953 | hirokazu.yamamoto | 2009-04-01 10:13:52 -0500 (Wed, 01 Apr 2009) | 1 line Fixed compile error on windows. ........ ................ r70988 | raymond.hettinger | 2009-04-01 16:52:13 -0400 (Wed, 01 Apr 2009) | 1 line Add link to an alternative generator with a long-period. ................ r70996 | benjamin.peterson | 2009-04-01 17:22:20 -0400 (Wed, 01 Apr 2009) | 13 lines Merged revisions 70992,70995 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70992 | georg.brandl | 2009-04-01 16:00:55 -0500 (Wed, 01 Apr 2009) | 1 line #4572: add SEEK_* values as constants in io.py. ........ r70995 | benjamin.peterson | 2009-04-01 16:12:54 -0500 (Wed, 01 Apr 2009) | 1 line add seek constants to __all__ ........ ................ r71000 | r.david.murray | 2009-04-01 18:37:58 -0400 (Wed, 01 Apr 2009) | 10 lines Merged revisions 70997 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70997 | r.david.murray | 2009-04-01 17:26:18 -0400 (Wed, 01 Apr 2009) | 3 lines Add tests checking the CSV module's ability to handle embedded newlines in quoted field values. ........ ................ r71002 | georg.brandl | 2009-04-01 19:07:29 -0400 (Wed, 01 Apr 2009) | 1 line #5656: detect correct encoding of files when reporting coverage in trace.py, and ignore files in the temporary directory when reporting. ................ r71005 | brett.cannon | 2009-04-01 19:26:47 -0400 (Wed, 01 Apr 2009) | 1 line Add a meta path importer example. ................ r71007 | brett.cannon | 2009-04-01 19:36:48 -0400 (Wed, 01 Apr 2009) | 1 line Explain a little about the explanation. ................ r71012 | benjamin.peterson | 2009-04-01 20:24:00 -0400 (Wed, 01 Apr 2009) | 1 line fix markup ................ r71013 | benjamin.peterson | 2009-04-01 20:33:55 -0400 (Wed, 01 Apr 2009) | 1 line make 'c' only accept bytes and 'C' only unicode #5499 ................ r71015 | benjamin.peterson | 2009-04-01 21:03:26 -0400 (Wed, 01 Apr 2009) | 1 line add SEEK_ constants to _pyio ................ r71016 | benjamin.peterson | 2009-04-01 21:13:40 -0400 (Wed, 01 Apr 2009) | 9 lines Merged revisions 71014 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71014 | benjamin.peterson | 2009-04-01 20:03:17 -0500 (Wed, 01 Apr 2009) | 1 line handle SEEK_ constants in test_io ........ ................ r71017 | benjamin.peterson | 2009-04-01 21:14:45 -0400 (Wed, 01 Apr 2009) | 1 line add io and _pyio to test___all__ ................ r71018 | benjamin.peterson | 2009-04-01 21:50:37 -0400 (Wed, 01 Apr 2009) | 1 line fix ref leaks ................ r71020 | benjamin.peterson | 2009-04-01 22:27:20 -0400 (Wed, 01 Apr 2009) | 1 line rewrite error handling to make sense ................ r71021 | benjamin.peterson | 2009-04-01 22:27:56 -0400 (Wed, 01 Apr 2009) | 1 line remove unused variable ................ r71027 | georg.brandl | 2009-04-01 22:56:10 -0400 (Wed, 01 Apr 2009) | 2 lines First batch of signature documentation changes; using default argument syntax where applicable. ................ r71030 | senthil.kumaran | 2009-04-01 23:02:03 -0400 (Wed, 01 Apr 2009) | 3 lines Fixing the issue4860. Escaping the embedded '"' in the js_output method of Morsel class. ................ r71034 | brett.cannon | 2009-04-01 23:41:46 -0400 (Wed, 01 Apr 2009) | 13 lines Merged revisions 71031 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71031 | brett.cannon | 2009-04-01 20:17:39 -0700 (Wed, 01 Apr 2009) | 6 lines PyImport_AppendInittab() took a char * as a first argument even though that string was stored beyond the life of the call. Changed the signature to be const char * to help make this point. Closes issue #1419652. ........ ................ r71038 | r.david.murray | 2009-04-02 00:50:03 -0400 (Thu, 02 Apr 2009) | 9 lines Clarify that datetime strftime does not produce leap seconds and datetime strptime does not accept it in the strftime behavior section of the datetime docs. Closes issue 2568. Porting by hand since svnmerge disclaims all knowledge of the trunk commit. ................ r71042 | brett.cannon | 2009-04-02 01:17:54 -0400 (Thu, 02 Apr 2009) | 5 lines Check that on a platform that is expected to have a case-insensitive filesystem that is in fact the case. Closes issue #5442. ................ r71045 | hyeshik.chang | 2009-04-02 06:33:16 -0400 (Thu, 02 Apr 2009) | 4 lines Issue #5640: Fix _multibytecodec so that CJK codecs don't repeat error replacement returned by codec error callbacks twice in IncrementalEncoder and StreamWriter. ................ r71053 | brett.cannon | 2009-04-02 11:32:07 -0400 (Thu, 02 Apr 2009) | 1 line Give a more informative message on an importlib test upon failure. ................ r71054 | brett.cannon | 2009-04-02 11:35:09 -0400 (Thu, 02 Apr 2009) | 1 line Make a test in importlib have a more robust test value. ................ r71057 | brett.cannon | 2009-04-02 13:54:43 -0400 (Thu, 02 Apr 2009) | 5 lines importlib.test.source.test_abc_loader was making a bad assumption that all file paths used '/' as a path separator. Fixes issue #5646. ................ r71061 | mark.dickinson | 2009-04-02 14:41:40 -0400 (Thu, 02 Apr 2009) | 2 lines Rewrap some long lines. ................ r71063 | brett.cannon | 2009-04-02 14:57:15 -0400 (Thu, 02 Apr 2009) | 1 line r71034 somehow deleted all of the metadata for svnmerge. This is my attempt to fix my mistake. ................ r71064 | brett.cannon | 2009-04-02 15:02:06 -0400 (Thu, 02 Apr 2009) | 1 line A fix for the fix for the svnmerge metadata. ................ r71066 | r.david.murray | 2009-04-02 15:21:26 -0400 (Thu, 02 Apr 2009) | 2 lines A fix for Brett's fix for his fix. I think we got it right this time. ................ r71067 | r.david.murray | 2009-04-02 15:44:43 -0400 (Thu, 02 Apr 2009) | 13 lines In 3k this becomes an items() call. Merged revisions 71046 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71046 | r.david.murray | 2009-04-02 10:05:35 -0400 (Thu, 02 Apr 2009) | 4 lines Add missing iteritems() call to the for loop in mailbox.MH.get_message(). Fixes issue2625. ........ ................ r71071 | antoine.pitrou | 2009-04-02 17:42:24 -0400 (Thu, 02 Apr 2009) | 8 lines Blocked revisions 71070 via svnmerge ........ r71070 | antoine.pitrou | 2009-04-02 23:18:34 +0200 (jeu., 02 avril 2009) | 3 lines Issue #2396: backport the memoryview object. ........ ................ r71074 | raymond.hettinger | 2009-04-02 18:31:59 -0400 (Thu, 02 Apr 2009) | 4 lines Have namedtuple's field renamer assign names that are consistent with the corresponding tuple index. ................ r71076 | raymond.hettinger | 2009-04-02 18:37:59 -0400 (Thu, 02 Apr 2009) | 1 line Update docs for namedtuple's renaming change. ................ r71079 | raymond.hettinger | 2009-04-02 22:45:36 -0400 (Thu, 02 Apr 2009) | 3 lines Localize the function lookup in timeit. ................ r71084 | alexandre.vassalotti | 2009-04-03 00:17:41 -0400 (Fri, 03 Apr 2009) | 3 lines Update a comment about why the __module__ can sometime be NULL. Initialize last_string and arg member of Unpickler. ................ r71087 | raymond.hettinger | 2009-04-03 01:47:33 -0400 (Fri, 03 Apr 2009) | 1 line Fix typo. ................ r71088 | alexandre.vassalotti | 2009-04-03 02:07:29 -0400 (Fri, 03 Apr 2009) | 2 lines Remove old reference to cPickle. ................ r71089 | alexandre.vassalotti | 2009-04-03 02:13:29 -0400 (Fri, 03 Apr 2009) | 2 lines Add more examples in pickle documentation. ................ r71090 | alexandre.vassalotti | 2009-04-03 02:19:27 -0400 (Fri, 03 Apr 2009) | 2 lines Emphasize that Unpickler.memo is not necessarily a dict. ................ r71091 | alexandre.vassalotti | 2009-04-03 02:38:02 -0400 (Fri, 03 Apr 2009) | 4 lines Optimize slicing of bytes and bytearray by avoiding useless copying. This restores the behavior that was present in Python 2.x. ................ r71092 | alexandre.vassalotti | 2009-04-03 02:58:20 -0400 (Fri, 03 Apr 2009) | 8 lines Undocument the existence of the memo attribute and its main use-case. Apparently, Guido don't like this behavior. [1] I also agree that the memo should be left as an implementation detail. [1]: http://mail.python.org/pipermail/python-dev/2009-March/086809.html ................ r71093 | alexandre.vassalotti | 2009-04-03 03:16:55 -0400 (Fri, 03 Apr 2009) | 8 lines Make http.server main program nicer for interactive use. Remove unreachable calls to test(). This restores the behavior of SimpleHTTPServer, where a user could type "python -m SimpleHTTPServer" and get a simple server for sharing files. Now, you can do the same thing with "python3 -m http.server". ................ r71095 | eric.smith | 2009-04-03 07:19:31 -0400 (Fri, 03 Apr 2009) | 1 line Removed mixed tabs and whitespace. ................ r71096 | eric.smith | 2009-04-03 10:45:06 -0400 (Fri, 03 Apr 2009) | 9 lines Added ',' thousands grouping to int.__format__. See PEP 378. This is incomplete, but I want to get some version into the next alpha. I am still working on: Documentation. More tests. Implement for floats. In addition, there's an existing bug with 'n' formatting that carries forward to thousands grouping (issue 5515). ................ r71107 | benjamin.peterson | 2009-04-03 18:18:11 -0400 (Fri, 03 Apr 2009) | 1 line Py_BuildValue's 'c' code should use byte strings #5666 ................ r71108 | benjamin.peterson | 2009-04-03 18:22:42 -0400 (Fri, 03 Apr 2009) | 1 line update NEWS ................ r71109 | benjamin.peterson | 2009-04-03 18:23:43 -0400 (Fri, 03 Apr 2009) | 1 line os.path.listdir -> os.listdir ................ r71110 | eric.smith | 2009-04-03 18:25:33 -0400 (Fri, 03 Apr 2009) | 1 line Added Misc/NEWS entry for PEP 378. ................ r71112 | benjamin.peterson | 2009-04-03 19:47:26 -0400 (Fri, 03 Apr 2009) | 1 line fix naming ................ r71113 | benjamin.peterson | 2009-04-03 19:57:05 -0400 (Fri, 03 Apr 2009) | 1 line fix this test ................ r71114 | benjamin.peterson | 2009-04-03 20:46:15 -0400 (Fri, 03 Apr 2009) | 1 line fix name ................ r71115 | benjamin.peterson | 2009-04-03 21:21:56 -0400 (Fri, 03 Apr 2009) | 1 line fix name again ................ r71116 | r.david.murray | 2009-04-03 21:38:38 -0400 (Fri, 03 Apr 2009) | 10 lines Update documentation for csv module to reflect changes in code, specifically that it now expects unicode input (and therefore the paragraph about it not handling unicode is deleted, as well as the 'how to handle unicode' examples) and that files should be opened with "newline=''" instead of binary mode. Also removed unused BytesIO import from test_csv. This addresses issue 4847. ................ r71118 | benjamin.peterson | 2009-04-03 23:37:26 -0400 (Fri, 03 Apr 2009) | 733 lines Blocked revisions 70176,70178,70197,70261,70267,70271,70273,70286,70290,70292-70293,70295-70296,70298,70300,70305,70315,70319,70368,70443,70454,70463,70466,70470-70473,70475,70477,70479,70485,70531,70533,70538,70544,70552-70553,70564,70601,70651,70672,70702,70711-70714,70716,70719,70723,70734,70747,70757,70764-70765,70768-70773,70775-70777,70788-70789,70807,70821,70824-70825,70828,70830,70832,70836-70838,70842,70844,70851,70855-70858,70864,70866-70874,70876-70878,70883,70885,70893-70894,70896-70897,70901-70908,70912,70915,70918,70927,70933-70934,70939-70940,70944,70951,70958,70960,70962-70964,70968-70969,70980-70981,70986,70993-70994,70998,71001,71004,71006,71008-71011,71019,71022-71024,71026,71029,71031-71033,71036-71037,71041,71043,71056,71058-71059,71070,71073,71075,71078 via svnmerge ........ r70176 | ronald.oussoren | 2009-03-04 15:35:05 -0600 (Wed, 04 Mar 2009) | 2 lines Fixes issues 3883 and 5194 ........ r70178 | ronald.oussoren | 2009-03-04 16:49:36 -0600 (Wed, 04 Mar 2009) | 2 lines Fix for issue #1113328. ........ r70197 | jesus.cea | 2009-03-05 13:37:37 -0600 (Thu, 05 Mar 2009) | 1 line Minor bsddb documentation glitch ........ r70261 | raymond.hettinger | 2009-03-09 06:31:39 -0500 (Mon, 09 Mar 2009) | 1 line Issue 5443: Fix typo. ........ r70267 | raymond.hettinger | 2009-03-09 06:57:29 -0500 (Mon, 09 Mar 2009) | 1 line Add consume() recipe to itertools docs. ........ r70271 | raymond.hettinger | 2009-03-09 07:56:23 -0500 (Mon, 09 Mar 2009) | 1 line Add cross-reference to the collections docs. ........ r70273 | georg.brandl | 2009-03-09 09:25:07 -0500 (Mon, 09 Mar 2009) | 2 lines #5458: add a note when we started to raise RuntimeErrors. ........ r70286 | raymond.hettinger | 2009-03-09 19:06:05 -0500 (Mon, 09 Mar 2009) | 1 line Fix markup. ........ r70290 | raymond.hettinger | 2009-03-09 20:07:30 -0500 (Mon, 09 Mar 2009) | 1 line Update url for the spec. ........ r70292 | raymond.hettinger | 2009-03-09 23:40:24 -0500 (Mon, 09 Mar 2009) | 1 line Clarify the meaning of normal and subnormal. ........ r70293 | raymond.hettinger | 2009-03-09 23:49:21 -0500 (Mon, 09 Mar 2009) | 1 line Add a version tag to the decimal module. ........ r70295 | raymond.hettinger | 2009-03-10 03:16:05 -0500 (Tue, 10 Mar 2009) | 1 line Update the decimal FAQ for the from_float() classmethod and improve the recipe for remove_exponent() to make it cut and pasteable. ........ r70296 | raymond.hettinger | 2009-03-10 04:31:48 -0500 (Tue, 10 Mar 2009) | 1 line Small optimization for corner case where maxlen==0. ........ r70298 | raymond.hettinger | 2009-03-10 07:50:59 -0500 (Tue, 10 Mar 2009) | 1 line For collections.deque() objects, expose the maxlen parameter as a read-only attribute. ........ r70300 | raymond.hettinger | 2009-03-10 08:04:30 -0500 (Tue, 10 Mar 2009) | 1 line Fix typo. ........ r70305 | brett.cannon | 2009-03-10 23:51:06 -0500 (Tue, 10 Mar 2009) | 5 lines Require implementations for warnings.showwarning() support the 'line' argument. Was a DeprecationWarning for not supporting it since Python 2.6. Closes issue #3652. ........ r70315 | raymond.hettinger | 2009-03-11 19:25:03 -0500 (Wed, 11 Mar 2009) | 1 line Add reference to solution for a commonly asked question. ........ r70319 | raymond.hettinger | 2009-03-11 19:31:58 -0500 (Wed, 11 Mar 2009) | 1 line Issue 5477: Fix buglet in the itertools documentation. ........ r70368 | eric.smith | 2009-03-14 09:37:38 -0500 (Sat, 14 Mar 2009) | 1 line Unicode format tests weren't actually testing unicode. This was probably due to the original backport from py3k. ........ r70443 | bob.ippolito | 2009-03-17 18:19:00 -0500 (Tue, 17 Mar 2009) | 1 line merge json library with simplejson 2.0.9 (issue 4136) ........ r70454 | mark.dickinson | 2009-03-18 11:07:26 -0500 (Wed, 18 Mar 2009) | 9 lines Issue 4474: On platforms with sizeof(wchar_t) == 4 and sizeof(Py_UNICODE) == 2, PyUnicode_FromWideChar now converts each character outside the BMP to the appropriate surrogate pair. Thanks Victor Stinner for the patch. (backport of r70452 from py3k to trunk) ........ r70463 | benjamin.peterson | 2009-03-18 15:52:15 -0500 (Wed, 18 Mar 2009) | 1 line fix strange errors when setting attributes on tracebacks #4034 ........ r70466 | raymond.hettinger | 2009-03-18 17:13:20 -0500 (Wed, 18 Mar 2009) | 1 line Use mixin methods where possible. (2.7 only -- these don't all exist in 3.0) ........ r70470 | raymond.hettinger | 2009-03-19 10:21:10 -0500 (Thu, 19 Mar 2009) | 6 lines Improve implementation with better underlying data structure for O(1) deletions. Big-Oh performance now the same as regular dictionaries. Uses a doubly-linked list instead of a list/seq to track insertion order. ........ r70471 | raymond.hettinger | 2009-03-19 14:19:03 -0500 (Thu, 19 Mar 2009) | 3 lines Issue 5381: Add object_pairs_hook to the json module. ........ r70472 | raymond.hettinger | 2009-03-19 14:24:43 -0500 (Thu, 19 Mar 2009) | 1 line Silence a compiler warning. ........ r70473 | raymond.hettinger | 2009-03-19 14:59:58 -0500 (Thu, 19 Mar 2009) | 6 lines * Add clearer comment to initialization code. * Add optional argument to popitem() -- modeled after Anthon van der Neut's C version. * Fix method markup in docs. ........ r70475 | raymond.hettinger | 2009-03-19 18:12:41 -0500 (Thu, 19 Mar 2009) | 6 lines * Add implementation notes. * Re-order methods so that those touching the underlying data structure come first and the derived methods come last. ........ r70477 | raymond.hettinger | 2009-03-19 18:22:25 -0500 (Thu, 19 Mar 2009) | 1 line Fix typo ........ r70479 | mark.dickinson | 2009-03-20 10:51:55 -0500 (Fri, 20 Mar 2009) | 3 lines Issue #4258: Use 30-bit digits for Python longs, on 64-bit platforms. Backport of r70459. ........ r70485 | raymond.hettinger | 2009-03-20 13:25:49 -0500 (Fri, 20 Mar 2009) | 1 line Add MutableSet example. ........ r70531 | benjamin.peterson | 2009-03-22 17:24:58 -0500 (Sun, 22 Mar 2009) | 1 line AttributeError can be thrown during recursion errors ........ r70533 | raymond.hettinger | 2009-03-22 19:08:09 -0500 (Sun, 22 Mar 2009) | 6 lines Add more comments. Improve variable names. Make links clearer by using a Link object instead of a list. Use proxy links to avoid circular references. ........ r70538 | raymond.hettinger | 2009-03-22 23:42:18 -0500 (Sun, 22 Mar 2009) | 1 line Move initialization of root link to __init__. ........ r70544 | raymond.hettinger | 2009-03-23 13:26:59 -0500 (Mon, 23 Mar 2009) | 1 line Make imported name private and wrap long-line. ........ r70552 | benjamin.peterson | 2009-03-23 15:47:59 -0500 (Mon, 23 Mar 2009) | 1 line fix very old names for exception terms #5543 ........ r70553 | benjamin.peterson | 2009-03-23 16:23:30 -0500 (Mon, 23 Mar 2009) | 1 line revert r70552; wrong fix ........ r70564 | raymond.hettinger | 2009-03-23 19:17:11 -0500 (Mon, 23 Mar 2009) | 1 line Add links to related resources. ........ r70601 | raymond.hettinger | 2009-03-25 17:41:32 -0500 (Wed, 25 Mar 2009) | 1 line Separate initialization from clearing. ........ r70651 | guilherme.polo | 2009-03-28 14:17:16 -0500 (Sat, 28 Mar 2009) | 1 line Typo fix ........ r70672 | collin.winter | 2009-03-28 22:44:19 -0500 (Sat, 28 Mar 2009) | 4 lines Add the ability to control the random seed used by regrtest.py -r. This adds a --randseed option, and makes regrtest.py -r indicate what random seed it's using so that that value can later be fed back to --randseed. This option is useful for tracking down test order-related issues found by make buildbottest, for example. ........ r70702 | bob.ippolito | 2009-03-29 17:33:58 -0500 (Sun, 29 Mar 2009) | 1 line Issue 5381: fix regression in pure python code path, Issue 5584: fix a decoder bug for unicode float literals outside of a container ........ r70711 | r.david.murray | 2009-03-30 10:14:01 -0500 (Mon, 30 Mar 2009) | 2 lines Convert import try/except to use test_support.import_module(). ........ r70712 | benjamin.peterson | 2009-03-30 10:15:38 -0500 (Mon, 30 Mar 2009) | 1 line don't rely on the order dict repr #5605 ........ r70713 | ronald.oussoren | 2009-03-30 10:20:46 -0500 (Mon, 30 Mar 2009) | 2 lines This patch fixes issue 1254695 (wrong argument type conversion in Carbon.Qt) ........ r70714 | brett.cannon | 2009-03-30 10:20:53 -0500 (Mon, 30 Mar 2009) | 1 line Add an entry to developers.txt. ........ r70716 | r.david.murray | 2009-03-30 10:30:34 -0500 (Mon, 30 Mar 2009) | 2 lines Revert incorrect change. ........ r70719 | ronald.oussoren | 2009-03-30 11:01:51 -0500 (Mon, 30 Mar 2009) | 2 lines Fix for issue 896199 (some Carbon modules aren't present in the documentation) ........ r70723 | kurt.kaiser | 2009-03-30 11:22:00 -0500 (Mon, 30 Mar 2009) | 1 line Tk 8.5 Text widget requires 'wordprocessor' tabstyle attr to handle mixed space/tab properly. Issue 5120, patch by Guilherme Polo. ........ r70734 | r.david.murray | 2009-03-30 14:04:00 -0500 (Mon, 30 Mar 2009) | 7 lines Add import_function method to test.test_support, and modify a number of tests that expect to be skipped if imports fail or functions don't exist to use import_function and import_module. The ultimate goal is to change regrtest to not skip automatically on ImportError. Checking in now to make sure the buldbots don't show any errors on platforms I can't direct test on. ........ r70747 | r.david.murray | 2009-03-30 15:04:06 -0500 (Mon, 30 Mar 2009) | 3 lines Remove references to test_socket_ssl which was deleted in trunk in r64392 and py3k in r59038. ........ r70757 | senthil.kumaran | 2009-03-30 16:51:50 -0500 (Mon, 30 Mar 2009) | 3 lines Fix for bugs: Issue4675 and Issue4962. ........ r70764 | martin.v.loewis | 2009-03-30 17:06:33 -0500 (Mon, 30 Mar 2009) | 2 lines Add several VM developers. ........ r70765 | georg.brandl | 2009-03-30 17:09:34 -0500 (Mon, 30 Mar 2009) | 1 line #5199: make warning about vars() assignment more visible. ........ r70768 | andrew.kuchling | 2009-03-30 17:29:15 -0500 (Mon, 30 Mar 2009) | 1 line Typo fixes ........ r70769 | andrew.kuchling | 2009-03-30 17:29:53 -0500 (Mon, 30 Mar 2009) | 1 line Remove comment ........ r70770 | andrew.kuchling | 2009-03-30 17:30:20 -0500 (Mon, 30 Mar 2009) | 1 line Add several items and placeholders ........ r70771 | andrew.kuchling | 2009-03-30 17:31:11 -0500 (Mon, 30 Mar 2009) | 1 line Many edits ........ r70772 | barry.warsaw | 2009-03-30 17:42:17 -0500 (Mon, 30 Mar 2009) | 5 lines A fix for issue 1974, inspired by the patch from Andi Albrecht (aalbrecht), though with some changes by me. This patch should not be back ported or forward ported. It's a bit too risky for 2.6 and 3.x does things fairly differently. ........ r70773 | georg.brandl | 2009-03-30 17:43:00 -0500 (Mon, 30 Mar 2009) | 1 line #5039: make it clear that the impl. note refers to CPython. ........ r70775 | r.david.murray | 2009-03-30 18:05:48 -0500 (Mon, 30 Mar 2009) | 4 lines Change more tests to use import_module for the modules that should cause tests to be skipped. Also rename import_function to the more descriptive get_attribute and add a docstring. ........ r70776 | andrew.kuchling | 2009-03-30 18:08:24 -0500 (Mon, 30 Mar 2009) | 1 line typo fix ........ r70777 | andrew.kuchling | 2009-03-30 18:09:46 -0500 (Mon, 30 Mar 2009) | 1 line Add more items ........ r70788 | andrew.kuchling | 2009-03-30 20:21:01 -0500 (Mon, 30 Mar 2009) | 1 line Add various items ........ r70789 | georg.brandl | 2009-03-30 20:25:15 -0500 (Mon, 30 Mar 2009) | 1 line Fix a wrong struct field assignment (docstring as closure). ........ r70807 | jeremy.hylton | 2009-03-31 08:31:00 -0500 (Tue, 31 Mar 2009) | 2 lines Update quicktest to match Python 3 branch ........ r70821 | jeremy.hylton | 2009-03-31 10:04:15 -0500 (Tue, 31 Mar 2009) | 2 lines Add check for PyDict_Update() error. ........ r70824 | georg.brandl | 2009-03-31 10:43:20 -0500 (Tue, 31 Mar 2009) | 1 line #5519: remove reference to Kodos, which seems dead. ........ r70825 | georg.brandl | 2009-03-31 10:46:30 -0500 (Tue, 31 Mar 2009) | 1 line #5566: fix versionadded from PyLong ssize_t functions. ........ r70828 | georg.brandl | 2009-03-31 10:50:16 -0500 (Tue, 31 Mar 2009) | 1 line #5581: fget argument of abstractproperty is optional as well. ........ r70830 | georg.brandl | 2009-03-31 11:11:45 -0500 (Tue, 31 Mar 2009) | 1 line #5529: backport new docs of import semantics written by Brett to 2.x. ........ r70832 | georg.brandl | 2009-03-31 11:31:11 -0500 (Tue, 31 Mar 2009) | 1 line #1386675: specify WindowsError as the exception, because it has a winerror attribute that EnvironmentError doesnt have. ........ r70836 | georg.brandl | 2009-03-31 11:50:25 -0500 (Tue, 31 Mar 2009) | 1 line #5417: replace references to undocumented functions by ones to documented functions. ........ r70837 | gregory.p.smith | 2009-03-31 11:54:10 -0500 (Tue, 31 Mar 2009) | 9 lines The unittest.TestCase.assertEqual() now displays the differences in lists, tuples, dicts and sets on failure. Many new handy type and comparison specific assert* methods have been added that fail with error messages actually useful for debugging. Contributed in by Google and completed with help from mfoord and GvR at PyCon 2009 sprints. Discussion lives in http://bugs.python.org/issue2578. ........ r70838 | georg.brandl | 2009-03-31 11:54:38 -0500 (Tue, 31 Mar 2009) | 1 line #992207: document that the parser only accepts \\n newlines. ........ r70842 | georg.brandl | 2009-03-31 12:13:06 -0500 (Tue, 31 Mar 2009) | 1 line #970783: document PyObject_Generic[GS]etAttr. ........ r70844 | raymond.hettinger | 2009-03-31 12:47:06 -0500 (Tue, 31 Mar 2009) | 1 line Per the language summit, the optional fastpath imports should use from-import-star. ........ r70851 | georg.brandl | 2009-03-31 13:26:55 -0500 (Tue, 31 Mar 2009) | 1 line #837577: note cryptic return value of spawn*e on invalid env dicts. ........ r70855 | georg.brandl | 2009-03-31 13:30:37 -0500 (Tue, 31 Mar 2009) | 1 line #5245: note that PyRun_SimpleString doesnt return on SystemExit. ........ r70856 | r.david.murray | 2009-03-31 13:32:17 -0500 (Tue, 31 Mar 2009) | 7 lines A few more test skips via import_module, and change import_module to return the error message produced by importlib, so that if an import in the package whose import is being wrapped is what failed the skip message will contain the name of that module instead of the name of the wrapped module. Also fixed formatting of some previous comments. ........ r70857 | georg.brandl | 2009-03-31 13:33:10 -0500 (Tue, 31 Mar 2009) | 1 line #5227: note that Py_Main doesnt return on SystemExit. ........ r70858 | georg.brandl | 2009-03-31 13:38:56 -0500 (Tue, 31 Mar 2009) | 1 line #5241: document missing U in regex howto. ........ r70864 | gregory.p.smith | 2009-03-31 14:03:28 -0500 (Tue, 31 Mar 2009) | 10 lines Rename the actual method definitions to the official assertFoo names. Adds unittests to make sure the old fail* names continue to work now and adds a comment that they are pending deprecation. Also adds a test to confirm that the plural Equals method variants continue to exist even though we're unlikely to deprecate those. http://bugs.python.org/issue2578 ........ r70866 | georg.brandl | 2009-03-31 14:06:57 -0500 (Tue, 31 Mar 2009) | 1 line #4882: document named group behavior a bit better. ........ r70867 | georg.brandl | 2009-03-31 14:10:35 -0500 (Tue, 31 Mar 2009) | 1 line #1096310: document usage of sys.__std*__ a bit better. ........ r70868 | georg.brandl | 2009-03-31 14:12:17 -0500 (Tue, 31 Mar 2009) | 1 line #5190: export make_option in __all__. ........ r70869 | georg.brandl | 2009-03-31 14:14:42 -0500 (Tue, 31 Mar 2009) | 1 line Fix-up unwanted change. ........ r70870 | georg.brandl | 2009-03-31 14:26:24 -0500 (Tue, 31 Mar 2009) | 1 line #4411: document mro() and __mro__. (I hope I got it right.) ........ r70871 | georg.brandl | 2009-03-31 14:30:56 -0500 (Tue, 31 Mar 2009) | 1 line #5618: fix typo. ........ r70872 | r.david.murray | 2009-03-31 14:31:17 -0500 (Tue, 31 Mar 2009) | 3 lines Delete out-of-date and little-known README from the test directory by consensus of devs at pycon sprint. ........ r70873 | josiah.carlson | 2009-03-31 14:32:34 -0500 (Tue, 31 Mar 2009) | 2 lines This resolves issue 1161031. Tests pass. ........ r70874 | r.david.murray | 2009-03-31 14:33:15 -0500 (Tue, 31 Mar 2009) | 5 lines Improve test_support.import_module docstring, remove deprecated flag from get_attribute since it isn't likely to do anything useful. ........ r70876 | r.david.murray | 2009-03-31 14:49:15 -0500 (Tue, 31 Mar 2009) | 4 lines Remove the regrtest check that turns any ImportError into a skipped test. Hopefully all modules whose imports legitimately result in a skipped test have been properly wrapped by the previous commits. ........ r70877 | r.david.murray | 2009-03-31 14:57:24 -0500 (Tue, 31 Mar 2009) | 2 lines Add NEWS entry for regrtest change. ........ r70878 | gregory.p.smith | 2009-03-31 14:59:14 -0500 (Tue, 31 Mar 2009) | 3 lines Issue an actual PendingDeprecationWarning for the TestCase.fail* methods. Document the deprecation. ........ r70883 | georg.brandl | 2009-03-31 15:41:08 -0500 (Tue, 31 Mar 2009) | 1 line #1674032: return value of flag from Event.wait(). OKed by Guido. ........ r70885 | tarek.ziade | 2009-03-31 15:48:31 -0500 (Tue, 31 Mar 2009) | 1 line using log.warn for sys.stderr ........ r70893 | georg.brandl | 2009-03-31 15:56:32 -0500 (Tue, 31 Mar 2009) | 1 line #1530012: move TQS section before raw strings. ........ r70894 | benjamin.peterson | 2009-03-31 16:06:30 -0500 (Tue, 31 Mar 2009) | 1 line take the usual lock precautions around _active_limbo_lock ........ r70896 | georg.brandl | 2009-03-31 16:15:33 -0500 (Tue, 31 Mar 2009) | 1 line #5598: document DocFileSuite *args argument. ........ r70897 | benjamin.peterson | 2009-03-31 16:34:42 -0500 (Tue, 31 Mar 2009) | 1 line fix Thread.ident when it is the main thread or a dummy thread #5632 ........ r70901 | georg.brandl | 2009-03-31 16:40:24 -0500 (Tue, 31 Mar 2009) | 2 lines Remove warning about pending Win9x support removal. ........ r70902 | georg.brandl | 2009-03-31 16:43:03 -0500 (Tue, 31 Mar 2009) | 1 line #1675026: add a note about a strange Windows problem, and remove notes about AtheOS. ........ r70903 | georg.brandl | 2009-03-31 16:45:18 -0500 (Tue, 31 Mar 2009) | 1 line #1676135: remove trailing slashes from --prefix argument. ........ r70904 | josiah.carlson | 2009-03-31 16:49:36 -0500 (Tue, 31 Mar 2009) | 3 lines Made handle_expt_event() be called last, so that we don't accidentally read after closing the socket. ........ r70905 | georg.brandl | 2009-03-31 17:03:40 -0500 (Tue, 31 Mar 2009) | 1 line #5563: more documentation for bdist_msi. ........ r70906 | georg.brandl | 2009-03-31 17:11:53 -0500 (Tue, 31 Mar 2009) | 1 line #1651995: fix _convert_ref for non-ASCII characters. ........ r70907 | georg.brandl | 2009-03-31 17:18:19 -0500 (Tue, 31 Mar 2009) | 1 line #3427: document correct return type for urlopen().info(). ........ r70908 | jesse.noller | 2009-03-31 17:20:35 -0500 (Tue, 31 Mar 2009) | 1 line Issue 5619: Pass MS CRT debug flags into subprocesses ........ r70912 | georg.brandl | 2009-03-31 17:35:46 -0500 (Tue, 31 Mar 2009) | 1 line #5617: add a handy function to print a unicode string to gdbinit. ........ r70915 | georg.brandl | 2009-03-31 17:40:16 -0500 (Tue, 31 Mar 2009) | 1 line #5018: remove confusing paragraph. ........ r70918 | raymond.hettinger | 2009-03-31 17:43:03 -0500 (Tue, 31 Mar 2009) | 1 line Improve examples for collections.deque() ........ r70927 | georg.brandl | 2009-03-31 18:01:27 -0500 (Tue, 31 Mar 2009) | 1 line Dont shout to users. ........ r70933 | georg.brandl | 2009-03-31 19:04:33 -0500 (Tue, 31 Mar 2009) | 2 lines Issue #5635: Fix running test_sys with tracing enabled. ........ r70934 | josiah.carlson | 2009-03-31 20:28:11 -0500 (Tue, 31 Mar 2009) | 2 lines Fix for failing asyncore tests. ........ r70939 | jesse.noller | 2009-03-31 22:45:50 -0500 (Tue, 31 Mar 2009) | 1 line Fix multiprocessing.event to match the new threading.Event API ........ r70940 | georg.brandl | 2009-03-31 23:21:14 -0500 (Tue, 31 Mar 2009) | 2 lines The SimpleXMLRPCServer's CGI handler now runs like a pony. ........ r70944 | georg.brandl | 2009-03-31 23:32:39 -0500 (Tue, 31 Mar 2009) | 1 line #5631: add upload to list of possible commands, which is presented in --help-commands. ........ r70951 | georg.brandl | 2009-04-01 09:02:27 -0500 (Wed, 01 Apr 2009) | 1 line Add Maksim, who worked on several issues at the sprint. ........ r70958 | kristjan.jonsson | 2009-04-01 11:08:34 -0500 (Wed, 01 Apr 2009) | 3 lines http://bugs.python.org/issue5623 Dynamically discoverd the size of the ioinfo struct used by the crt for its file descriptors. This should work across all flavors of the CRT. Thanks to Amaury Forgeot d'Arc Needs porting to 3.1 ........ r70960 | jesse.noller | 2009-04-01 11:42:19 -0500 (Wed, 01 Apr 2009) | 1 line Issue 3270: document Listener address restrictions on windows ........ r70962 | brett.cannon | 2009-04-01 12:07:16 -0500 (Wed, 01 Apr 2009) | 2 lines Ron DuPlain was given commit privileges at PyCon 2009 to work on 3to2. ........ r70963 | georg.brandl | 2009-04-01 12:46:01 -0500 (Wed, 01 Apr 2009) | 1 line #5655: fix docstring oversight. ........ r70964 | brett.cannon | 2009-04-01 12:52:13 -0500 (Wed, 01 Apr 2009) | 2 lines Paul Kippes was given commit privileges to work on 3to2. ........ r70968 | michael.foord | 2009-04-01 13:25:38 -0500 (Wed, 01 Apr 2009) | 1 line Adding Wing project file ........ r70969 | raymond.hettinger | 2009-04-01 13:50:56 -0500 (Wed, 01 Apr 2009) | 1 line Issue #5647: MutableSet.__iand__() no longer mutates self during iteration. ........ r70980 | jack.diederich | 2009-04-01 15:26:13 -0500 (Wed, 01 Apr 2009) | 3 lines bounds check arguments to mmap.move(). All of them. Really. fixes crasher on OS X 10.5 ........ r70981 | senthil.kumaran | 2009-04-01 15:26:33 -0500 (Wed, 01 Apr 2009) | 3 lines Fix for issue5040. Adding test for Content-Length ........ r70986 | raymond.hettinger | 2009-04-01 15:50:58 -0500 (Wed, 01 Apr 2009) | 1 line Add link to an alternative generator with a long-period. ........ r70993 | georg.brandl | 2009-04-01 16:05:44 -0500 (Wed, 01 Apr 2009) | 1 line Add NEWS item. ........ r70994 | georg.brandl | 2009-04-01 16:06:30 -0500 (Wed, 01 Apr 2009) | 1 line Revert accidental checkin. ........ r70998 | georg.brandl | 2009-04-01 16:54:21 -0500 (Wed, 01 Apr 2009) | 1 line In Pdb, stop assigning values to __builtin__._ which interferes with the one commonly installed by gettext. ........ r71001 | brett.cannon | 2009-04-01 18:01:12 -0500 (Wed, 01 Apr 2009) | 3 lines Add my initials to Misc/developers.txt. Names are now sorted by number of characters in the person's name. ........ r71004 | benjamin.peterson | 2009-04-01 18:15:49 -0500 (Wed, 01 Apr 2009) | 1 line remove double underscores ........ r71006 | georg.brandl | 2009-04-01 18:32:17 -0500 (Wed, 01 Apr 2009) | 1 line Cache the f_locals dict of the current frame, since every access to frame.f_locals overrides its contents with the real locals which undoes modifications made by the debugging user. ........ r71008 | andrew.kuchling | 2009-04-01 19:02:14 -0500 (Wed, 01 Apr 2009) | 1 line Typo fix ........ r71009 | jesse.noller | 2009-04-01 19:03:28 -0500 (Wed, 01 Apr 2009) | 1 line issue5545: Switch to Autoconf for multiprocessing; special thanks to Martin Lowis for help ........ r71010 | benjamin.peterson | 2009-04-01 19:11:52 -0500 (Wed, 01 Apr 2009) | 1 line fix markup ........ r71011 | benjamin.peterson | 2009-04-01 19:12:47 -0500 (Wed, 01 Apr 2009) | 1 line this should be :noindex: ........ r71019 | georg.brandl | 2009-04-01 21:00:01 -0500 (Wed, 01 Apr 2009) | 1 line Fix test_doctest, missed two assignments to curframe. ........ r71022 | jesse.noller | 2009-04-01 21:32:55 -0500 (Wed, 01 Apr 2009) | 1 line Issue 3110: Additional protection for SEM_VALUE_MAX on platforms, thanks to Martin Loewis ........ r71023 | kurt.kaiser | 2009-04-01 21:44:54 -0500 (Wed, 01 Apr 2009) | 3 lines Remove port spec from run.py and fix bug where subprocess fails to extract port from command line when warnings are present. ........ r71024 | georg.brandl | 2009-04-01 21:47:44 -0500 (Wed, 01 Apr 2009) | 4 lines In PyErr_GivenExceptionMatches, temporarily bump the recursion limit, so that in the most common case PyObject_IsSubclass will not raise a recursion error we have to ignore anyway. ........ r71026 | benjamin.peterson | 2009-04-01 21:52:46 -0500 (Wed, 01 Apr 2009) | 1 line fix error handling ........ r71029 | senthil.kumaran | 2009-04-01 22:00:34 -0500 (Wed, 01 Apr 2009) | 3 lines Fixing the issue4860. Escaping embedded '"' character in js_output() method of Morsel. ........ r71031 | brett.cannon | 2009-04-01 22:17:39 -0500 (Wed, 01 Apr 2009) | 6 lines PyImport_AppendInittab() took a char * as a first argument even though that string was stored beyond the life of the call. Changed the signature to be const char * to help make this point. Closes issue #1419652. ........ r71032 | michael.foord | 2009-04-01 22:20:38 -0500 (Wed, 01 Apr 2009) | 13 lines Better exception messages for unittest assert methods. - unittest.assertNotEqual() now uses the inequality operator (!=) instead of the equality operator. - Default assertTrue and assertFalse messages are now useful. - TestCase has a longMessage attribute. This defaults to False, but if set to True useful error messages are shown in addition to explicit messages passed to assert methods. Issue #5663 ........ r71033 | brett.cannon | 2009-04-01 22:34:53 -0500 (Wed, 01 Apr 2009) | 3 lines Fix two issues introduced by issue #71031 by changing the signature of PyImport_AppendInittab() to take a const char *. ........ r71036 | jesse.noller | 2009-04-01 23:22:09 -0500 (Wed, 01 Apr 2009) | 1 line Issue 3551: Raise ValueError if the size causes ERROR_NO_SYSTEM_RESOURCES ........ r71037 | r.david.murray | 2009-04-01 23:34:04 -0500 (Wed, 01 Apr 2009) | 6 lines Clarify that datetime strftime does not produce leap seconds and datetime strptime does not accept it in the strftime behavior section of the datetime docs. Closes issue 2568. ........ r71041 | jesse.noller | 2009-04-02 00:17:26 -0500 (Thu, 02 Apr 2009) | 1 line Add custom initializer argument to multiprocess.Manager*, courtesy of lekma ........ r71043 | michael.foord | 2009-04-02 00:51:54 -0500 (Thu, 02 Apr 2009) | 7 lines Store the functions in the _type_equality_funcs as wrapped objects that are deep copyable. This allows for the deep copying of TestCase instances. Issue 5660 ........ r71056 | georg.brandl | 2009-04-02 12:43:07 -0500 (Thu, 02 Apr 2009) | 2 lines Actually the displayhook should print the repr. ........ r71058 | georg.brandl | 2009-04-02 13:09:04 -0500 (Thu, 02 Apr 2009) | 3 lines PyErr_NormalizeException may not set an error, so convert the PyErr_SetObject call on hitting the recursion limit into just assigning it to the arguments provided. ........ r71059 | mark.dickinson | 2009-04-02 13:39:37 -0500 (Thu, 02 Apr 2009) | 2 lines sys.long_info attributes should be ints, not longs ........ r71070 | antoine.pitrou | 2009-04-02 16:18:34 -0500 (Thu, 02 Apr 2009) | 3 lines Issue #2396: backport the memoryview object. ........ r71073 | raymond.hettinger | 2009-04-02 17:25:40 -0500 (Thu, 02 Apr 2009) | 4 lines Have namedtuple's field renamer assign names that are consistent with the corresponding tuple index. ........ r71075 | raymond.hettinger | 2009-04-02 17:34:17 -0500 (Thu, 02 Apr 2009) | 1 line Update docs for namedtuple's renaming change. ........ r71078 | raymond.hettinger | 2009-04-02 21:43:54 -0500 (Thu, 02 Apr 2009) | 4 lines Localize the function lookup in timeit. ........ ................ r71122 | raymond.hettinger | 2009-04-04 01:39:52 -0400 (Sat, 04 Apr 2009) | 1 line Add helpful link. ................ r71125 | r.david.murray | 2009-04-04 02:46:11 -0400 (Sat, 04 Apr 2009) | 8 lines Blocked revisions 71123 via svnmerge ........ r71123 | r.david.murray | 2009-04-04 02:39:56 -0400 (Sat, 04 Apr 2009) | 2 lines Fix error in description of 'oct' (issue 5678). ........ ................ r71128 | raymond.hettinger | 2009-04-04 04:48:03 -0400 (Sat, 04 Apr 2009) | 1 line Replace the localized min/max calls with normal if/else ................ r71137 | raymond.hettinger | 2009-04-04 06:47:35 -0400 (Sat, 04 Apr 2009) | 1 line Start building-up the whatsnew document for Py3.1 ................ r71138 | raymond.hettinger | 2009-04-04 07:08:48 -0400 (Sat, 04 Apr 2009) | 1 line More updates to whatsnew ................ r71139 | raymond.hettinger | 2009-04-04 07:59:00 -0400 (Sat, 04 Apr 2009) | 1 line More notes on 3.1 improvements. ................ r71140 | benjamin.peterson | 2009-04-04 08:33:52 -0400 (Sat, 04 Apr 2009) | 1 line revert r71118 because it blocked an excess of revisions ................ r71141 | raymond.hettinger | 2009-04-04 08:35:58 -0400 (Sat, 04 Apr 2009) | 1 line Complete the first-pass at whatsnew. ................ r71142 | benjamin.peterson | 2009-04-04 08:40:17 -0400 (Sat, 04 Apr 2009) | 94 lines Blocked revisions 70711,70713,70716,70719,70747,70772,70821,70830,70844,70873,70901-70902,70904,70918,70934,70969,70986,71026,71073,71075,71078 via svnmerge ........ r70711 | r.david.murray | 2009-03-30 10:14:01 -0500 (Mon, 30 Mar 2009) | 2 lines Convert import try/except to use test_support.import_module(). ........ r70713 | ronald.oussoren | 2009-03-30 10:20:46 -0500 (Mon, 30 Mar 2009) | 2 lines This patch fixes issue 1254695 (wrong argument type conversion in Carbon.Qt) ........ r70716 | r.david.murray | 2009-03-30 10:30:34 -0500 (Mon, 30 Mar 2009) | 2 lines Revert incorrect change. ........ r70719 | ronald.oussoren | 2009-03-30 11:01:51 -0500 (Mon, 30 Mar 2009) | 2 lines Fix for issue 896199 (some Carbon modules aren't present in the documentation) ........ r70747 | r.david.murray | 2009-03-30 15:04:06 -0500 (Mon, 30 Mar 2009) | 3 lines Remove references to test_socket_ssl which was deleted in trunk in r64392 and py3k in r59038. ........ r70772 | barry.warsaw | 2009-03-30 17:42:17 -0500 (Mon, 30 Mar 2009) | 5 lines A fix for issue 1974, inspired by the patch from Andi Albrecht (aalbrecht), though with some changes by me. This patch should not be back ported or forward ported. It's a bit too risky for 2.6 and 3.x does things fairly differently. ........ r70821 | jeremy.hylton | 2009-03-31 10:04:15 -0500 (Tue, 31 Mar 2009) | 2 lines Add check for PyDict_Update() error. ........ r70830 | georg.brandl | 2009-03-31 11:11:45 -0500 (Tue, 31 Mar 2009) | 1 line #5529: backport new docs of import semantics written by Brett to 2.x. ........ r70844 | raymond.hettinger | 2009-03-31 12:47:06 -0500 (Tue, 31 Mar 2009) | 1 line Per the language summit, the optional fastpath imports should use from-import-star. ........ r70873 | josiah.carlson | 2009-03-31 14:32:34 -0500 (Tue, 31 Mar 2009) | 2 lines This resolves issue 1161031. Tests pass. ........ r70901 | georg.brandl | 2009-03-31 16:40:24 -0500 (Tue, 31 Mar 2009) | 2 lines Remove warning about pending Win9x support removal. ........ r70902 | georg.brandl | 2009-03-31 16:43:03 -0500 (Tue, 31 Mar 2009) | 1 line #1675026: add a note about a strange Windows problem, and remove notes about AtheOS. ........ r70904 | josiah.carlson | 2009-03-31 16:49:36 -0500 (Tue, 31 Mar 2009) | 3 lines Made handle_expt_event() be called last, so that we don't accidentally read after closing the socket. ........ r70918 | raymond.hettinger | 2009-03-31 17:43:03 -0500 (Tue, 31 Mar 2009) | 1 line Improve examples for collections.deque() ........ r70934 | josiah.carlson | 2009-03-31 20:28:11 -0500 (Tue, 31 Mar 2009) | 2 lines Fix for failing asyncore tests. ........ r70969 | raymond.hettinger | 2009-04-01 13:50:56 -0500 (Wed, 01 Apr 2009) | 1 line Issue #5647: MutableSet.__iand__() no longer mutates self during iteration. ........ r70986 | raymond.hettinger | 2009-04-01 15:50:58 -0500 (Wed, 01 Apr 2009) | 1 line Add link to an alternative generator with a long-period. ........ r71026 | benjamin.peterson | 2009-04-01 21:52:46 -0500 (Wed, 01 Apr 2009) | 1 line fix error handling ........ r71073 | raymond.hettinger | 2009-04-02 17:25:40 -0500 (Thu, 02 Apr 2009) | 4 lines Have namedtuple's field renamer assign names that are consistent with the corresponding tuple index. ........ r71075 | raymond.hettinger | 2009-04-02 17:34:17 -0500 (Thu, 02 Apr 2009) | 1 line Update docs for namedtuple's renaming change. ........ r71078 | raymond.hettinger | 2009-04-02 21:43:54 -0500 (Thu, 02 Apr 2009) | 4 lines Localize the function lookup in timeit. ........ ................ r71143 | benjamin.peterson | 2009-04-04 08:42:53 -0400 (Sat, 04 Apr 2009) | 1 line typo ................ r71144 | raymond.hettinger | 2009-04-04 08:46:57 -0400 (Sat, 04 Apr 2009) | 1 line Eliminate a duplicate entry. ................ r71146 | raymond.hettinger | 2009-04-04 09:01:19 -0400 (Sat, 04 Apr 2009) | 1 line Fix nits. ................ r71147 | raymond.hettinger | 2009-04-04 09:13:56 -0400 (Sat, 04 Apr 2009) | 1 line Remove minor entry. Add the ttk module. ................ r71148 | raymond.hettinger | 2009-04-04 09:20:55 -0400 (Sat, 04 Apr 2009) | 1 line Note an improvement to pydoc. ................ r71151 | antoine.pitrou | 2009-04-04 10:09:30 -0400 (Sat, 04 Apr 2009) | 3 lines Fix test_memoryio under Windows ................ r71154 | matthias.klose | 2009-04-04 10:32:42 -0400 (Sat, 04 Apr 2009) | 10 lines Merged revisions 71152 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71152 | matthias.klose | 2009-04-04 16:18:13 +0200 (Sa, 04 Apr 2009) | 3 lines - Issue #3845: In PyRun_SimpleFileExFlags avoid invalid memory access with short file names. ........ ................ r71156 | benjamin.peterson | 2009-04-04 11:32:08 -0400 (Sat, 04 Apr 2009) | 1 line try to fix svnmerge-blocked property ................ r71157 | benjamin.peterson | 2009-04-04 11:38:19 -0400 (Sat, 04 Apr 2009) | 90 lines Blocked revisions 70711,70713,70716,70719,70747,70772,70821,70830,70844,70873,70901-70902,70904,70918,70934,70969,71026,71073,71075,71078 via svnmerge ........ r70711 | r.david.murray | 2009-03-30 10:14:01 -0500 (Mon, 30 Mar 2009) | 2 lines Convert import try/except to use test_support.import_module(). ........ r70713 | ronald.oussoren | 2009-03-30 10:20:46 -0500 (Mon, 30 Mar 2009) | 2 lines This patch fixes issue 1254695 (wrong argument type conversion in Carbon.Qt) ........ r70716 | r.david.murray | 2009-03-30 10:30:34 -0500 (Mon, 30 Mar 2009) | 2 lines Revert incorrect change. ........ r70719 | ronald.oussoren | 2009-03-30 11:01:51 -0500 (Mon, 30 Mar 2009) | 2 lines Fix for issue 896199 (some Carbon modules aren't present in the documentation) ........ r70747 | r.david.murray | 2009-03-30 15:04:06 -0500 (Mon, 30 Mar 2009) | 3 lines Remove references to test_socket_ssl which was deleted in trunk in r64392 and py3k in r59038. ........ r70772 | barry.warsaw | 2009-03-30 17:42:17 -0500 (Mon, 30 Mar 2009) | 5 lines A fix for issue 1974, inspired by the patch from Andi Albrecht (aalbrecht), though with some changes by me. This patch should not be back ported or forward ported. It's a bit too risky for 2.6 and 3.x does things fairly differently. ........ r70821 | jeremy.hylton | 2009-03-31 10:04:15 -0500 (Tue, 31 Mar 2009) | 2 lines Add check for PyDict_Update() error. ........ r70830 | georg.brandl | 2009-03-31 11:11:45 -0500 (Tue, 31 Mar 2009) | 1 line #5529: backport new docs of import semantics written by Brett to 2.x. ........ r70844 | raymond.hettinger | 2009-03-31 12:47:06 -0500 (Tue, 31 Mar 2009) | 1 line Per the language summit, the optional fastpath imports should use from-import-star. ........ r70873 | josiah.carlson | 2009-03-31 14:32:34 -0500 (Tue, 31 Mar 2009) | 2 lines This resolves issue 1161031. Tests pass. ........ r70901 | georg.brandl | 2009-03-31 16:40:24 -0500 (Tue, 31 Mar 2009) | 2 lines Remove warning about pending Win9x support removal. ........ r70902 | georg.brandl | 2009-03-31 16:43:03 -0500 (Tue, 31 Mar 2009) | 1 line #1675026: add a note about a strange Windows problem, and remove notes about AtheOS. ........ r70904 | josiah.carlson | 2009-03-31 16:49:36 -0500 (Tue, 31 Mar 2009) | 3 lines Made handle_expt_event() be called last, so that we don't accidentally read after closing the socket. ........ r70918 | raymond.hettinger | 2009-03-31 17:43:03 -0500 (Tue, 31 Mar 2009) | 1 line Improve examples for collections.deque() ........ r70934 | josiah.carlson | 2009-03-31 20:28:11 -0500 (Tue, 31 Mar 2009) | 2 lines Fix for failing asyncore tests. ........ r70969 | raymond.hettinger | 2009-04-01 13:50:56 -0500 (Wed, 01 Apr 2009) | 1 line Issue #5647: MutableSet.__iand__() no longer mutates self during iteration. ........ r71026 | benjamin.peterson | 2009-04-01 21:52:46 -0500 (Wed, 01 Apr 2009) | 1 line fix error handling ........ r71073 | raymond.hettinger | 2009-04-02 17:25:40 -0500 (Thu, 02 Apr 2009) | 4 lines Have namedtuple's field renamer assign names that are consistent with the corresponding tuple index. ........ r71075 | raymond.hettinger | 2009-04-02 17:34:17 -0500 (Thu, 02 Apr 2009) | 1 line Update docs for namedtuple's renaming change. ........ r71078 | raymond.hettinger | 2009-04-02 21:43:54 -0500 (Thu, 02 Apr 2009) | 4 lines Localize the function lookup in timeit. ........ ................ r71162 | matthias.klose | 2009-04-04 11:54:25 -0400 (Sat, 04 Apr 2009) | 9 lines Merged revisions 71159 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71159 | matthias.klose | 2009-04-04 17:51:23 +0200 (Sa, 04 Apr 2009) | 2 lines - Py_DECREF: Add `do { ... } while (0)' to avoid compiler warnings. ........ ................ r71169 | benjamin.peterson | 2009-04-04 12:35:46 -0400 (Sat, 04 Apr 2009) | 59 lines Merged revisions 70837,70864,70878,71004,71032,71043 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70837 | gregory.p.smith | 2009-03-31 11:54:10 -0500 (Tue, 31 Mar 2009) | 9 lines The unittest.TestCase.assertEqual() now displays the differences in lists, tuples, dicts and sets on failure. Many new handy type and comparison specific assert* methods have been added that fail with error messages actually useful for debugging. Contributed in by Google and completed with help from mfoord and GvR at PyCon 2009 sprints. Discussion lives in http://bugs.python.org/issue2578. ........ r70864 | gregory.p.smith | 2009-03-31 14:03:28 -0500 (Tue, 31 Mar 2009) | 10 lines Rename the actual method definitions to the official assertFoo names. Adds unittests to make sure the old fail* names continue to work now and adds a comment that they are pending deprecation. Also adds a test to confirm that the plural Equals method variants continue to exist even though we're unlikely to deprecate those. http://bugs.python.org/issue2578 ........ r70878 | gregory.p.smith | 2009-03-31 14:59:14 -0500 (Tue, 31 Mar 2009) | 3 lines Issue an actual PendingDeprecationWarning for the TestCase.fail* methods. Document the deprecation. ........ r71004 | benjamin.peterson | 2009-04-01 18:15:49 -0500 (Wed, 01 Apr 2009) | 1 line remove double underscores ........ r71032 | michael.foord | 2009-04-01 22:20:38 -0500 (Wed, 01 Apr 2009) | 13 lines Better exception messages for unittest assert methods. - unittest.assertNotEqual() now uses the inequality operator (!=) instead of the equality operator. - Default assertTrue and assertFalse messages are now useful. - TestCase has a longMessage attribute. This defaults to False, but if set to True useful error messages are shown in addition to explicit messages passed to assert methods. Issue #5663 ........ r71043 | michael.foord | 2009-04-02 00:51:54 -0500 (Thu, 02 Apr 2009) | 7 lines Store the functions in the _type_equality_funcs as wrapped objects that are deep copyable. This allows for the deep copying of TestCase instances. Issue 5660 ........ ................ r71170 | benjamin.peterson | 2009-04-04 12:38:09 -0400 (Sat, 04 Apr 2009) | 9 lines Merged revisions 71163 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71163 | benjamin.peterson | 2009-04-04 11:05:51 -0500 (Sat, 04 Apr 2009) | 1 line revert r71159 since it broke the build ........ ................ r71171 | benjamin.peterson | 2009-04-04 12:39:09 -0400 (Sat, 04 Apr 2009) | 1 line fix test_unittest ................ r71172 | benjamin.peterson | 2009-04-04 12:46:24 -0400 (Sat, 04 Apr 2009) | 1 line mark dictionary assertElementsSame test as an expected failure ................ r71173 | benjamin.peterson | 2009-04-04 12:47:31 -0400 (Sat, 04 Apr 2009) | 1 line fix name ................ r71174 | benjamin.peterson | 2009-04-04 13:09:35 -0400 (Sat, 04 Apr 2009) | 1 line #5391 make mmap work exclusively with bytes ................ r71176 | benjamin.peterson | 2009-04-04 13:26:32 -0400 (Sat, 04 Apr 2009) | 1 line must provide this method ................ r71177 | hirokazu.yamamoto | 2009-04-04 13:35:38 -0400 (Sat, 04 Apr 2009) | 8 lines Blocked revisions 71175 via svnmerge ........ r71175 | hirokazu.yamamoto | 2009-04-05 02:20:05 +0900 | 1 line No behavior change. ........ ................ r71178 | antoine.pitrou | 2009-04-04 13:36:05 -0400 (Sat, 04 Apr 2009) | 3 lines Skip test_recursionlimit_fatalerror under Windows because it generates an annoying and misleading crash dialog. ................ r71180 | martin.v.loewis | 2009-04-04 14:48:39 -0400 (Sat, 04 Apr 2009) | 9 lines Merged revisions 71179 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71179 | martin.v.loewis | 2009-04-04 20:44:44 +0200 (Sa, 04 Apr 2009) | 2 lines Issue #5470: Package zipdir.zip. ........ ................ r71183 | michael.foord | 2009-04-04 14:55:09 -0400 (Sat, 04 Apr 2009) | 9 lines Patch for Py3k with fallback for comparing unsortable sequences in assertSameElements. Removed the expected failure and added another test case to confirm that this patch works for unsortable sequences that are the same (no fail) and different (fail). Issue #2578 ................ r71184 | eric.smith | 2009-04-04 15:35:49 -0400 (Sat, 04 Apr 2009) | 1 line Resolves issue 5690: accidentally skipping code in non-debug build. ................ r71185 | alexandre.vassalotti | 2009-04-04 15:58:40 -0400 (Sat, 04 Apr 2009) | 4 lines Issue 5682: Move _io module into its own subdirectory. Reviewed by: Antoine Pitrou ................ r71186 | kurt.kaiser | 2009-04-04 16:13:23 -0400 (Sat, 04 Apr 2009) | 11 lines Merged revisions 71023 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71023 | kurt.kaiser | 2009-04-01 22:44:54 -0400 (Wed, 01 Apr 2009) | 3 lines Remove port spec from run.py and fix bug where subprocess fails to extract port from command line when warnings are present. ........ ................ r71187 | kurt.kaiser | 2009-04-04 16:20:29 -0400 (Sat, 04 Apr 2009) | 1 line Convert print to Py3 ................ r71188 | kurt.kaiser | 2009-04-04 16:34:16 -0400 (Sat, 04 Apr 2009) | 11 lines Merged revisions 71023 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71023 | kurt.kaiser | 2009-04-01 22:44:54 -0400 (Wed, 01 Apr 2009) | 3 lines Remove port spec from run.py and fix bug where subprocess fails to extract port from command line when warnings are present. ........ ................ r71189 | kurt.kaiser | 2009-04-04 16:38:52 -0400 (Sat, 04 Apr 2009) | 9 lines Merged revisions 70723 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70723 | kurt.kaiser | 2009-03-30 12:22:00 -0400 (Mon, 30 Mar 2009) | 1 line Tk 8.5 Text widget requires 'wordprocessor' tabstyle attr to handle mixed space/tab properly. Issue 5120, patch by Guilherme Polo. ........ ................ r71192 | benjamin.peterson | 2009-04-04 17:06:52 -0400 (Sat, 04 Apr 2009) | 1 line bump version to 3.1a2 ................ r71193 | kurt.kaiser | 2009-04-04 17:07:39 -0400 (Sat, 04 Apr 2009) | 12 lines Merged revisions 71126 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71126 | kurt.kaiser | 2009-04-04 03:03:48 -0400 (Sat, 04 Apr 2009) | 5 lines Allow multiple IDLE GUI/subprocess pairs to exist simultaneously. Thanks to David Scherer for suggesting the use of an ephemeral port for the GUI. Patch 1529142 Weeble. ........ ................ r71194 | benjamin.peterson | 2009-04-04 17:08:03 -0400 (Sat, 04 Apr 2009) | 1 line I don't think RELNOTES is useful anymore ................ Added: python/branches/py3k-short-float-repr/Demo/distutils/test2to3/test/ - copied from r71194, /python/branches/py3k/Demo/distutils/test2to3/test/ python/branches/py3k-short-float-repr/Lib/distutils/tests/test_clean.py - copied unchanged from r71194, /python/branches/py3k/Lib/distutils/tests/test_clean.py python/branches/py3k-short-float-repr/Lib/distutils/tests/test_install_data.py - copied unchanged from r71194, /python/branches/py3k/Lib/distutils/tests/test_install_data.py python/branches/py3k-short-float-repr/Lib/distutils/tests/test_install_headers.py - copied unchanged from r71194, /python/branches/py3k/Lib/distutils/tests/test_install_headers.py python/branches/py3k-short-float-repr/Lib/test/test_flufl.py - copied unchanged from r71194, /python/branches/py3k/Lib/test/test_flufl.py python/branches/py3k-short-float-repr/Modules/_io/ - copied from r71194, /python/branches/py3k/Modules/_io/ Removed: python/branches/py3k-short-float-repr/Lib/email/test/test_email_codecs_renamed.py python/branches/py3k-short-float-repr/Modules/_bufferedio.c python/branches/py3k-short-float-repr/Modules/_bytesio.c python/branches/py3k-short-float-repr/Modules/_fileio.c python/branches/py3k-short-float-repr/Modules/_iobase.c python/branches/py3k-short-float-repr/Modules/_iomodule.h python/branches/py3k-short-float-repr/Modules/_stringio.c python/branches/py3k-short-float-repr/Modules/_textio.c python/branches/py3k-short-float-repr/Modules/io.c python/branches/py3k-short-float-repr/RELNOTES Modified: python/branches/py3k-short-float-repr/ (props changed) python/branches/py3k-short-float-repr/Demo/distutils/test2to3/ (props changed) python/branches/py3k-short-float-repr/Demo/distutils/test2to3/setup.py python/branches/py3k-short-float-repr/Doc/c-api/arg.rst python/branches/py3k-short-float-repr/Doc/c-api/exceptions.rst python/branches/py3k-short-float-repr/Doc/c-api/import.rst python/branches/py3k-short-float-repr/Doc/c-api/long.rst python/branches/py3k-short-float-repr/Doc/distutils/setupscript.rst python/branches/py3k-short-float-repr/Doc/extending/extending.rst python/branches/py3k-short-float-repr/Doc/extending/newtypes.rst python/branches/py3k-short-float-repr/Doc/howto/regex.rst python/branches/py3k-short-float-repr/Doc/library/abc.rst python/branches/py3k-short-float-repr/Doc/library/aifc.rst python/branches/py3k-short-float-repr/Doc/library/asynchat.rst python/branches/py3k-short-float-repr/Doc/library/atexit.rst python/branches/py3k-short-float-repr/Doc/library/base64.rst python/branches/py3k-short-float-repr/Doc/library/bdb.rst python/branches/py3k-short-float-repr/Doc/library/binascii.rst python/branches/py3k-short-float-repr/Doc/library/collections.rst python/branches/py3k-short-float-repr/Doc/library/csv.rst python/branches/py3k-short-float-repr/Doc/library/datetime.rst python/branches/py3k-short-float-repr/Doc/library/email.header.rst python/branches/py3k-short-float-repr/Doc/library/functions.rst python/branches/py3k-short-float-repr/Doc/library/http.client.rst python/branches/py3k-short-float-repr/Doc/library/importlib.rst python/branches/py3k-short-float-repr/Doc/library/io.rst python/branches/py3k-short-float-repr/Doc/library/mmap.rst python/branches/py3k-short-float-repr/Doc/library/os.path.rst python/branches/py3k-short-float-repr/Doc/library/pickle.rst python/branches/py3k-short-float-repr/Doc/library/pickletools.rst python/branches/py3k-short-float-repr/Doc/library/random.rst python/branches/py3k-short-float-repr/Doc/library/shelve.rst python/branches/py3k-short-float-repr/Doc/library/time.rst python/branches/py3k-short-float-repr/Doc/library/unittest.rst python/branches/py3k-short-float-repr/Doc/library/urllib.error.rst python/branches/py3k-short-float-repr/Doc/library/urllib.request.rst python/branches/py3k-short-float-repr/Doc/license.rst python/branches/py3k-short-float-repr/Doc/reference/datamodel.rst python/branches/py3k-short-float-repr/Doc/whatsnew/3.1.rst python/branches/py3k-short-float-repr/Grammar/Grammar python/branches/py3k-short-float-repr/Include/bytesobject.h python/branches/py3k-short-float-repr/Include/code.h python/branches/py3k-short-float-repr/Include/compile.h python/branches/py3k-short-float-repr/Include/import.h python/branches/py3k-short-float-repr/Include/parsetok.h python/branches/py3k-short-float-repr/Include/patchlevel.h python/branches/py3k-short-float-repr/Include/pythonrun.h python/branches/py3k-short-float-repr/Include/unicodeobject.h python/branches/py3k-short-float-repr/Lib/__future__.py python/branches/py3k-short-float-repr/Lib/_abcoll.py python/branches/py3k-short-float-repr/Lib/_pyio.py python/branches/py3k-short-float-repr/Lib/_strptime.py python/branches/py3k-short-float-repr/Lib/bisect.py python/branches/py3k-short-float-repr/Lib/cgitb.py python/branches/py3k-short-float-repr/Lib/collections.py python/branches/py3k-short-float-repr/Lib/distutils/__init__.py python/branches/py3k-short-float-repr/Lib/distutils/cmd.py python/branches/py3k-short-float-repr/Lib/distutils/command/build_ext.py python/branches/py3k-short-float-repr/Lib/distutils/command/install_data.py python/branches/py3k-short-float-repr/Lib/distutils/command/install_headers.py python/branches/py3k-short-float-repr/Lib/distutils/command/register.py python/branches/py3k-short-float-repr/Lib/distutils/command/upload.py python/branches/py3k-short-float-repr/Lib/distutils/extension.py python/branches/py3k-short-float-repr/Lib/distutils/tests/support.py python/branches/py3k-short-float-repr/Lib/distutils/tests/test_build_ext.py python/branches/py3k-short-float-repr/Lib/distutils/tests/test_config.py python/branches/py3k-short-float-repr/Lib/distutils/tests/test_msvc9compiler.py python/branches/py3k-short-float-repr/Lib/distutils/tests/test_register.py python/branches/py3k-short-float-repr/Lib/distutils/tests/test_sdist.py python/branches/py3k-short-float-repr/Lib/distutils/tests/test_upload.py python/branches/py3k-short-float-repr/Lib/distutils/util.py python/branches/py3k-short-float-repr/Lib/email/generator.py python/branches/py3k-short-float-repr/Lib/email/test/test_email.py python/branches/py3k-short-float-repr/Lib/email/test/test_email_codecs.py (contents, props changed) python/branches/py3k-short-float-repr/Lib/http/client.py python/branches/py3k-short-float-repr/Lib/http/cookies.py python/branches/py3k-short-float-repr/Lib/http/server.py python/branches/py3k-short-float-repr/Lib/idlelib/EditorWindow.py python/branches/py3k-short-float-repr/Lib/idlelib/NEWS.txt python/branches/py3k-short-float-repr/Lib/idlelib/PyShell.py python/branches/py3k-short-float-repr/Lib/idlelib/idlever.py python/branches/py3k-short-float-repr/Lib/idlelib/rpc.py python/branches/py3k-short-float-repr/Lib/idlelib/run.py python/branches/py3k-short-float-repr/Lib/importlib/_bootstrap.py python/branches/py3k-short-float-repr/Lib/importlib/test/import_/test_path.py python/branches/py3k-short-float-repr/Lib/importlib/test/source/test_abc_loader.py python/branches/py3k-short-float-repr/Lib/importlib/test/util.py python/branches/py3k-short-float-repr/Lib/io.py python/branches/py3k-short-float-repr/Lib/locale.py python/branches/py3k-short-float-repr/Lib/mailbox.py python/branches/py3k-short-float-repr/Lib/multiprocessing/queues.py python/branches/py3k-short-float-repr/Lib/site.py python/branches/py3k-short-float-repr/Lib/symtable.py python/branches/py3k-short-float-repr/Lib/test/buffer_tests.py python/branches/py3k-short-float-repr/Lib/test/regrtest.py python/branches/py3k-short-float-repr/Lib/test/support.py python/branches/py3k-short-float-repr/Lib/test/test___all__.py python/branches/py3k-short-float-repr/Lib/test/test_asynchat.py python/branches/py3k-short-float-repr/Lib/test/test_bz2.py python/branches/py3k-short-float-repr/Lib/test/test_collections.py python/branches/py3k-short-float-repr/Lib/test/test_crypt.py python/branches/py3k-short-float-repr/Lib/test/test_csv.py python/branches/py3k-short-float-repr/Lib/test/test_ctypes.py python/branches/py3k-short-float-repr/Lib/test/test_curses.py python/branches/py3k-short-float-repr/Lib/test/test_dbm.py python/branches/py3k-short-float-repr/Lib/test/test_dbm_gnu.py python/branches/py3k-short-float-repr/Lib/test/test_dbm_ndbm.py python/branches/py3k-short-float-repr/Lib/test/test_exceptions.py python/branches/py3k-short-float-repr/Lib/test/test_fcntl.py python/branches/py3k-short-float-repr/Lib/test/test_fork1.py python/branches/py3k-short-float-repr/Lib/test/test_functools.py python/branches/py3k-short-float-repr/Lib/test/test_gc.py python/branches/py3k-short-float-repr/Lib/test/test_grp.py python/branches/py3k-short-float-repr/Lib/test/test_http_cookiejar.py python/branches/py3k-short-float-repr/Lib/test/test_http_cookies.py python/branches/py3k-short-float-repr/Lib/test/test_imp.py python/branches/py3k-short-float-repr/Lib/test/test_io.py python/branches/py3k-short-float-repr/Lib/test/test_ioctl.py python/branches/py3k-short-float-repr/Lib/test/test_locale.py python/branches/py3k-short-float-repr/Lib/test/test_logging.py python/branches/py3k-short-float-repr/Lib/test/test_mailbox.py python/branches/py3k-short-float-repr/Lib/test/test_mmap.py python/branches/py3k-short-float-repr/Lib/test/test_multibytecodec.py python/branches/py3k-short-float-repr/Lib/test/test_multiprocessing.py python/branches/py3k-short-float-repr/Lib/test/test_nis.py python/branches/py3k-short-float-repr/Lib/test/test_ossaudiodev.py python/branches/py3k-short-float-repr/Lib/test/test_posix.py python/branches/py3k-short-float-repr/Lib/test/test_pty.py python/branches/py3k-short-float-repr/Lib/test/test_pwd.py python/branches/py3k-short-float-repr/Lib/test/test_resource.py python/branches/py3k-short-float-repr/Lib/test/test_scope.py python/branches/py3k-short-float-repr/Lib/test/test_sqlite.py python/branches/py3k-short-float-repr/Lib/test/test_startfile.py python/branches/py3k-short-float-repr/Lib/test/test_struct.py python/branches/py3k-short-float-repr/Lib/test/test_sundry.py python/branches/py3k-short-float-repr/Lib/test/test_symtable.py python/branches/py3k-short-float-repr/Lib/test/test_sys.py python/branches/py3k-short-float-repr/Lib/test/test_syslog.py python/branches/py3k-short-float-repr/Lib/test/test_tcl.py python/branches/py3k-short-float-repr/Lib/test/test_time.py python/branches/py3k-short-float-repr/Lib/test/test_tk.py python/branches/py3k-short-float-repr/Lib/test/test_ttk_guionly.py python/branches/py3k-short-float-repr/Lib/test/test_ttk_textonly.py python/branches/py3k-short-float-repr/Lib/test/test_types.py python/branches/py3k-short-float-repr/Lib/test/test_unittest.py python/branches/py3k-short-float-repr/Lib/test/test_urllib.py python/branches/py3k-short-float-repr/Lib/test/test_urllib2.py python/branches/py3k-short-float-repr/Lib/test/test_urllib2net.py python/branches/py3k-short-float-repr/Lib/test/test_urlparse.py python/branches/py3k-short-float-repr/Lib/test/test_wait4.py python/branches/py3k-short-float-repr/Lib/test/test_warnings.py python/branches/py3k-short-float-repr/Lib/test/test_winreg.py python/branches/py3k-short-float-repr/Lib/test/test_winsound.py python/branches/py3k-short-float-repr/Lib/test/test_xml_etree_c.py python/branches/py3k-short-float-repr/Lib/test/test_xmlrpc.py python/branches/py3k-short-float-repr/Lib/test/test_zlib.py python/branches/py3k-short-float-repr/Lib/timeit.py python/branches/py3k-short-float-repr/Lib/trace.py python/branches/py3k-short-float-repr/Lib/unittest.py python/branches/py3k-short-float-repr/Lib/urllib/parse.py python/branches/py3k-short-float-repr/Lib/urllib/request.py python/branches/py3k-short-float-repr/Lib/xmlrpc/client.py python/branches/py3k-short-float-repr/Lib/xmlrpc/server.py python/branches/py3k-short-float-repr/Mac/BuildScript/README.txt python/branches/py3k-short-float-repr/Mac/BuildScript/build-installer.py python/branches/py3k-short-float-repr/Mac/BuildScript/resources/ReadMe.txt python/branches/py3k-short-float-repr/Mac/Makefile.in python/branches/py3k-short-float-repr/Mac/PythonLauncher/FileSettings.m python/branches/py3k-short-float-repr/Mac/Resources/app/Info.plist.in python/branches/py3k-short-float-repr/Makefile.pre.in python/branches/py3k-short-float-repr/Misc/ACKS python/branches/py3k-short-float-repr/Misc/NEWS python/branches/py3k-short-float-repr/Misc/RPM/python-3.1.spec python/branches/py3k-short-float-repr/Modules/Setup.dist python/branches/py3k-short-float-repr/Modules/_cursesmodule.c python/branches/py3k-short-float-repr/Modules/_functoolsmodule.c python/branches/py3k-short-float-repr/Modules/_multiprocessing/multiprocessing.h python/branches/py3k-short-float-repr/Modules/_multiprocessing/semaphore.c python/branches/py3k-short-float-repr/Modules/_multiprocessing/win32_functions.c python/branches/py3k-short-float-repr/Modules/_pickle.c python/branches/py3k-short-float-repr/Modules/arraymodule.c python/branches/py3k-short-float-repr/Modules/cjkcodecs/multibytecodec.c python/branches/py3k-short-float-repr/Modules/mmapmodule.c python/branches/py3k-short-float-repr/Modules/socketmodule.c python/branches/py3k-short-float-repr/Objects/bytearrayobject.c python/branches/py3k-short-float-repr/Objects/bytesobject.c python/branches/py3k-short-float-repr/Objects/exceptions.c python/branches/py3k-short-float-repr/Objects/longobject.c python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h python/branches/py3k-short-float-repr/Objects/stringlib/localeutil.h python/branches/py3k-short-float-repr/Objects/stringlib/stringdefs.h python/branches/py3k-short-float-repr/Objects/stringlib/unicodedefs.h python/branches/py3k-short-float-repr/Objects/unicodeobject.c python/branches/py3k-short-float-repr/PC/VC6/pythoncore.dsp python/branches/py3k-short-float-repr/PC/VS7.1/pythoncore.vcproj python/branches/py3k-short-float-repr/PC/VS8.0/pythoncore.vcproj python/branches/py3k-short-float-repr/PCbuild/pythoncore.vcproj python/branches/py3k-short-float-repr/Parser/parser.c python/branches/py3k-short-float-repr/Parser/parsetok.c python/branches/py3k-short-float-repr/Parser/tokenizer.c python/branches/py3k-short-float-repr/Python/_warnings.c python/branches/py3k-short-float-repr/Python/future.c python/branches/py3k-short-float-repr/Python/getargs.c python/branches/py3k-short-float-repr/Python/graminit.c python/branches/py3k-short-float-repr/Python/import.c python/branches/py3k-short-float-repr/Python/modsupport.c python/branches/py3k-short-float-repr/Python/pystrtod.c python/branches/py3k-short-float-repr/Python/pythonrun.c python/branches/py3k-short-float-repr/Python/symtable.c python/branches/py3k-short-float-repr/README python/branches/py3k-short-float-repr/Tools/buildbot/test.bat python/branches/py3k-short-float-repr/Tools/msi/msi.py python/branches/py3k-short-float-repr/Tools/msi/msilib.py python/branches/py3k-short-float-repr/Tools/scripts/reindent-rst.py python/branches/py3k-short-float-repr/setup.py Modified: python/branches/py3k-short-float-repr/Demo/distutils/test2to3/setup.py ============================================================================== --- python/branches/py3k-short-float-repr/Demo/distutils/test2to3/setup.py (original) +++ python/branches/py3k-short-float-repr/Demo/distutils/test2to3/setup.py Sun Apr 5 01:04:14 2009 @@ -20,7 +20,7 @@ license = "PSF license", packages = ["test2to3"], scripts = ["maintest.py"], - cmdclass = {'build_py':build_py, - 'build_scripts':build_scripts, + cmdclass = {'build_py': build_py, + 'build_scripts': build_scripts, } ) Modified: python/branches/py3k-short-float-repr/Doc/c-api/arg.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/c-api/arg.rst (original) +++ python/branches/py3k-short-float-repr/Doc/c-api/arg.rst Sun Apr 5 01:04:14 2009 @@ -208,9 +208,13 @@ Convert a Python integer to a C :ctype:`Py_ssize_t`. ``c`` (string of length 1) [char] - Convert a Python character, represented as a string of length 1, to a C + Convert a Python character, represented as a byte string of length 1, to a C :ctype:`char`. +``C`` (string of length 1) [int] + Convert a Python character, represented as a unicode string of length 1, to a + C :ctype:`int`. + ``f`` (float) [float] Convert a Python floating point number to a C :ctype:`float`. @@ -507,8 +511,12 @@ Convert a C :ctype:`Py_ssize_t` to a Python integer. ``c`` (string of length 1) [char] - Convert a C :ctype:`int` representing a character to a Python string of length - 1. + Convert a C :ctype:`int` representing a byte to a Python byte string of + length 1. + + ``C`` (string of length 1) [int] + Convert a C :ctype:`int` representing a character to Python unicode + string of length 1. ``d`` (float) [double] Convert a C :ctype:`double` to a Python floating point number. Modified: python/branches/py3k-short-float-repr/Doc/c-api/exceptions.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/c-api/exceptions.rst (original) +++ python/branches/py3k-short-float-repr/Doc/c-api/exceptions.rst Sun Apr 5 01:04:14 2009 @@ -400,6 +400,52 @@ the warning message. +Exception Objects +================= + +.. cfunction:: PyObject* PyException_GetTraceback(PyObject *ex) + + Return the traceback associated with the exception as a new reference, as + accessible from Python through :attr:`__traceback__`. If there is no + traceback associated, this returns *NULL*. + + +.. cfunction:: int PyException_SetTraceback(PyObject *ex, PyObject *tb) + + Set the traceback associated with the exception to *tb*. Use ``Py_None`` to + clear it. + + +.. cfunction:: PyObject* PyException_GetContext(PyObject *ex) + + Return the context (another exception instance during whose handling *ex* was + raised) associated with the exception as a new reference, as accessible from + Python through :attr:`__context__`. If there is no context associated, this + returns *NULL*. + + +.. cfunction:: void PyException_SetContext(PyObject *ex, PyObject *ctx) + + Set the context associated with the exception to *ctx*. Use *NULL* to clear + it. There is no type check to make sure that *ctx* is an exception instance. + This steals a reference to *ctx*. + + +.. cfunction:: PyObject* PyException_GetCause(PyObject *ex) + + Return the cause (another exception instance set by ``raise ... from ...``) + associated with the exception as a new reference, as accessible from Python + through :attr:`__cause__`. If there is no cause associated, this returns + *NULL*. + + +.. cfunction:: void PyException_SetCause(PyObject *ex, PyObject *ctx) + + Set the cause associated with the exception to *ctx*. Use *NULL* to clear + it. There is no type check to make sure that *ctx* is an exception instance. + This steals a reference to *ctx*. + + .. _standardexceptions: Standard Exceptions Modified: python/branches/py3k-short-float-repr/Doc/c-api/import.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/c-api/import.rst (original) +++ python/branches/py3k-short-float-repr/Doc/c-api/import.rst Sun Apr 5 01:04:14 2009 @@ -200,7 +200,7 @@ tricks with this to provide a dynamically created collection of frozen modules. -.. cfunction:: int PyImport_AppendInittab(char *name, PyObject* (*initfunc)(void)) +.. cfunction:: int PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void)) Add a single module to the existing table of built-in modules. This is a convenience wrapper around :cfunc:`PyImport_ExtendInittab`, returning ``-1`` if Modified: python/branches/py3k-short-float-repr/Doc/c-api/long.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/c-api/long.rst (original) +++ python/branches/py3k-short-float-repr/Doc/c-api/long.rst Sun Apr 5 01:04:14 2009 @@ -133,9 +133,9 @@ single: PY_SSIZE_T_MAX single: OverflowError (built-in exception) - Return a C :ctype:`Py_ssize_t` representation of the contents of *pylong*. If - *pylong* is greater than :const:`PY_SSIZE_T_MAX`, an :exc:`OverflowError` is raised - and ``-1`` will be returned. + Return a C :ctype:`Py_ssize_t` representation of the contents of *pylong*. + If *pylong* is greater than :const:`PY_SSIZE_T_MAX`, an :exc:`OverflowError` + is raised and ``-1`` will be returned. .. cfunction:: unsigned long PyLong_AsUnsignedLong(PyObject *pylong) @@ -149,16 +149,6 @@ raised. -.. cfunction:: Py_ssize_t PyLong_AsSsize_t(PyObject *pylong) - - .. index:: - single: PY_SSIZE_T_MAX - - Return a :ctype:`Py_ssize_t` representation of the contents of *pylong*. If - *pylong* is greater than :const:`PY_SSIZE_T_MAX`, an :exc:`OverflowError` is - raised. - - .. cfunction:: size_t PyLong_AsSize_t(PyObject *pylong) Return a :ctype:`size_t` representation of the contents of *pylong*. If Modified: python/branches/py3k-short-float-repr/Doc/distutils/setupscript.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/distutils/setupscript.rst (original) +++ python/branches/py3k-short-float-repr/Doc/distutils/setupscript.rst Sun Apr 5 01:04:14 2009 @@ -334,6 +334,10 @@ There are still some other options which can be used to handle special cases. +The :option:`optional` option is a boolean; if it is true, that specifies that +a build failure in the extension should not abort the build process, but simply +not install the failing extension. + The :option:`extra_objects` option is a list of object files to be passed to the linker. These files must not have extensions, as the default extension for the compiler is used. Modified: python/branches/py3k-short-float-repr/Doc/extending/extending.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/extending/extending.rst (original) +++ python/branches/py3k-short-float-repr/Doc/extending/extending.rst Sun Apr 5 01:04:14 2009 @@ -1266,12 +1266,13 @@ { PyObject *m; - m = Py_InitModule("client", ClientMethods); + m = PyModule_Create(&clientmodule); if (m == NULL) - return; + return NULL; if (import_spam() < 0) - return; + return NULL; /* additional initialization can happen here */ + return m; } The main disadvantage of this approach is that the file :file:`spammodule.h` is Modified: python/branches/py3k-short-float-repr/Doc/extending/newtypes.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/extending/newtypes.rst (original) +++ python/branches/py3k-short-float-repr/Doc/extending/newtypes.rst Sun Apr 5 01:04:14 2009 @@ -871,6 +871,7 @@ Py_INCREF(&ShoddyType); PyModule_AddObject(m, "Shoddy", (PyObject *) &ShoddyType); + return m; } Before calling :cfunc:`PyType_Ready`, the type structure must have the @@ -1230,50 +1231,53 @@ return -1; } -.. XXX tp_compare is dead; need to rewrite for tp_richcompare! +Object Comparison +----------------- - Object Comparison - ----------------- +:: + + richcmpfunc tp_richcompare; + +The :attr:`tp_richcompare` handler is called when comparisons are needed. It is +analogous to the :ref:`rich comparison methods `, like +:meth:`__lt__`, and also called by :cfunc:`PyObject_RichCompare` and +:cfunc:`PyObject_RichCompareBool`. + +This function is called with two Python objects and the operator as arguments, +where the operator is one of ``Py_EQ``, ``Py_NE``, ``Py_LE``, ``Py_GT``, +``Py_LT`` or ``Py_GT``. It should compare the two objects with respect to the +specified operator and return ``Py_True`` or ``Py_False`` if the comparison is +successfull, ``Py_NotImplemented`` to indicate that comparison is not +implemented and the other object's comparison method should be tried, or *NULL* +if an exception was set. + +Here is a sample implementation, for a datatype that is considered equal if the +size of an internal pointer is equal:: + + static int + newdatatype_richcmp(PyObject *obj1, PyObject *obj2, int op) + { + PyObject *result; + int c, size1, size2; - :: + /* code to make sure that both arguments are of type + newdatatype omitted */ - cmpfunc tp_compare; + size1 = obj1->obj_UnderlyingDatatypePtr->size; + size2 = obj2->obj_UnderlyingDatatypePtr->size; - The :attr:`tp_compare` handler is called when comparisons are needed and the - object does not implement the specific rich comparison method which matches the - requested comparison. (It is always used if defined and the - :cfunc:`PyObject_Compare` or :cfunc:`PyObject_Cmp` functions are used, or if - :func:`cmp` is used from Python.) It is analogous to the :meth:`__cmp__` method. - This function should return ``-1`` if *obj1* is less than *obj2*, ``0`` if they - are equal, and ``1`` if *obj1* is greater than *obj2*. (It was previously - allowed to return arbitrary negative or positive integers for less than and - greater than, respectively; as of Python 2.2, this is no longer allowed. In the - future, other return values may be assigned a different meaning.) - - A :attr:`tp_compare` handler may raise an exception. In this case it should - return a negative value. The caller has to test for the exception using - :cfunc:`PyErr_Occurred`. - - Here is a sample implementation:: - - static int - newdatatype_compare(newdatatypeobject * obj1, newdatatypeobject * obj2) - { - long result; - - if (obj1->obj_UnderlyingDatatypePtr->size < - obj2->obj_UnderlyingDatatypePtr->size) { - result = -1; - } - else if (obj1->obj_UnderlyingDatatypePtr->size > - obj2->obj_UnderlyingDatatypePtr->size) { - result = 1; - } - else { - result = 0; - } - return result; - } + switch (op) { + case Py_LT: c = size1 < size2; break; + case Py_LE: c = size1 <= size2; break; + case Py_EQ: c = size1 == size2; break; + case Py_NE: c = size1 != size2; break; + case Py_GT: c = size1 > size2; break; + case Py_GE: c = size1 >= size2; break; + } + result = c ? Py_True : Py_False; + Py_INCREF(result); + return result; + } Abstract Protocol Support Modified: python/branches/py3k-short-float-repr/Doc/howto/regex.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/howto/regex.rst (original) +++ python/branches/py3k-short-float-repr/Doc/howto/regex.rst Sun Apr 5 01:04:14 2009 @@ -540,6 +540,10 @@ | :const:`VERBOSE`, :const:`X` | Enable verbose REs, which can be organized | | | more cleanly and understandably. | +---------------------------------+--------------------------------------------+ +| :const:`ASCII`, :const:`A` | Makes several escapes like ``\w``, ``\b``, | +| | ``\s`` and ``\d`` match only on ASCII | +| | characters with the respective property. | ++---------------------------------+--------------------------------------------+ .. data:: I @@ -594,6 +598,15 @@ newline; without this flag, ``'.'`` will match anything *except* a newline. +.. data:: A + ASCII + :noindex: + + Make ``\w``, ``\W``, ``\b``, ``\B``, ``\s`` and ``\S`` perform ASCII-only + matching instead of full Unicode matching. This is only meaningful for + Unicode patterns, and is ignored for byte patterns. + + .. data:: X VERBOSE :noindex: Modified: python/branches/py3k-short-float-repr/Doc/library/abc.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/abc.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/abc.rst Sun Apr 5 01:04:14 2009 @@ -158,7 +158,7 @@ multiple-inheritance. -.. function:: abstractproperty(fget[, fset[, fdel[, doc]]]) +.. function:: abstractproperty(fget=None, fset=None, fdel=None, doc=None) A subclass of the built-in :func:`property`, indicating an abstract property. Modified: python/branches/py3k-short-float-repr/Doc/library/aifc.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/aifc.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/aifc.rst Sun Apr 5 01:04:14 2009 @@ -37,7 +37,7 @@ Module :mod:`aifc` defines the following function: -.. function:: open(file[, mode]) +.. function:: open(file, mode=None) Open an AIFF or AIFF-C file and return an object instance with methods that are described below. The argument *file* is either a string naming a file or a file Modified: python/branches/py3k-short-float-repr/Doc/library/asynchat.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/asynchat.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/asynchat.rst Sun Apr 5 01:04:14 2009 @@ -202,7 +202,7 @@ ------------------------------------------ -.. class:: simple_producer(data[, buffer_size=512]) +.. class:: simple_producer(data, buffer_size=512) A :class:`simple_producer` takes a chunk of data and an optional buffer size. Repeated calls to its :meth:`more` method yield successive chunks of @@ -215,7 +215,7 @@ empty string. -.. class:: fifo([list=None]) +.. class:: fifo(list=None) Each channel maintains a :class:`fifo` holding data which has been pushed by the application but not yet popped for writing to the channel. A Modified: python/branches/py3k-short-float-repr/Doc/library/atexit.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/atexit.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/atexit.rst Sun Apr 5 01:04:14 2009 @@ -17,7 +17,7 @@ :func:`os._exit` is called. -.. function:: register(func[, *args[, **kargs]]) +.. function:: register(func, *args, **kargs) Register *func* as a function to be executed at termination. Any optional arguments that are to be passed to *func* must be passed as arguments to @@ -48,7 +48,8 @@ .. seealso:: Module :mod:`readline` - Useful example of :mod:`atexit` to read and write :mod:`readline` history files. + Useful example of :mod:`atexit` to read and write :mod:`readline` history + files. .. _atexit-example: Modified: python/branches/py3k-short-float-repr/Doc/library/base64.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/base64.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/base64.rst Sun Apr 5 01:04:14 2009 @@ -23,7 +23,7 @@ The modern interface provides: -.. function:: b64encode(s[, altchars]) +.. function:: b64encode(s, altchars=None) Encode a string use Base64. @@ -36,7 +36,7 @@ The encoded string is returned. -.. function:: b64decode(s[, altchars]) +.. function:: b64decode(s, altchars=None) Decode a Base64 encoded string. @@ -78,7 +78,7 @@ is returned. -.. function:: b32decode(s[, casefold[, map01]]) +.. function:: b32decode(s, casefold=False, map01=None) Decode a Base32 encoded string. @@ -105,7 +105,7 @@ *s* is the string to encode. The encoded string is returned. -.. function:: b16decode(s[, casefold]) +.. function:: b16decode(s, casefold=False) Decode a Base16 encoded string. Modified: python/branches/py3k-short-float-repr/Doc/library/bdb.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/bdb.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/bdb.rst Sun Apr 5 01:04:14 2009 @@ -16,7 +16,7 @@ The :mod:`bdb` module also defines two classes: -.. class:: Breakpoint(self, file, line[, temporary=0[, cond=None [, funcname=None]]]) +.. class:: Breakpoint(self, file, line, temporary=0, cond=None, funcname=None) This class implements temporary breakpoints, ignore counts, disabling and (re-)enabling, and conditionals. @@ -50,7 +50,7 @@ Mark the breakpoint as disabled. - .. method:: pprint([out]) + .. method:: bpprint(out=None) Print all the information about the breakpoint: @@ -233,7 +233,7 @@ breakpoints. These methods return a string containing an error message if something went wrong, or ``None`` if all is well. - .. method:: set_break(filename, lineno[, temporary=0[, cond[, funcname]]]) + .. method:: set_break(filename, lineno, temporary=0, cond, funcname) Set a new breakpoint. If the *lineno* line doesn't exist for the *filename* passed as argument, return an error message. The *filename* @@ -285,7 +285,7 @@ Get a list of records for a frame and all higher (calling) and lower frames, and the size of the higher part. - .. method:: format_stack_entry(frame_lineno, [lprefix=': ']) + .. method:: format_stack_entry(frame_lineno, lprefix=': ') Return a string with information about a stack entry, identified by a ``(frame, lineno)`` tuple: @@ -300,12 +300,12 @@ The following two methods can be called by clients to use a debugger to debug a :term:`statement`, given as a string. - .. method:: run(cmd, [globals, [locals]]) + .. method:: run(cmd, globals=None, locals=None) Debug a statement executed via the :func:`exec` function. *globals* defaults to :attr:`__main__.__dict__`, *locals* defaults to *globals*. - .. method:: runeval(expr, [globals, [locals]]) + .. method:: runeval(expr, globals=None, locals=None) Debug an expression executed via the :func:`eval` function. *globals* and *locals* have the same meaning as in :meth:`run`. Modified: python/branches/py3k-short-float-repr/Doc/library/binascii.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/binascii.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/binascii.rst Sun Apr 5 01:04:14 2009 @@ -49,14 +49,14 @@ should be at most 57 to adhere to the base64 standard. -.. function:: a2b_qp(string[, header]) +.. function:: a2b_qp(string, header=False) Convert a block of quoted-printable data back to binary and return the binary data. More than one line may be passed at a time. If the optional argument *header* is present and true, underscores will be decoded as spaces. -.. function:: b2a_qp(data[, quotetabs, istext, header]) +.. function:: b2a_qp(data, quotetabs=False, istext=True, header=False) Convert binary data to a line(s) of ASCII characters in quoted-printable encoding. The return value is the converted line(s). If the optional argument Modified: python/branches/py3k-short-float-repr/Doc/library/collections.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/collections.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/collections.rst Sun Apr 5 01:04:14 2009 @@ -442,6 +442,29 @@ This section shows various approaches to working with deques. +Bounded length deques provide functionality similar to the ``tail`` filter +in Unix:: + + def tail(filename, n=10): + 'Return the last n lines of a file' + return deque(open(filename), n) + +Another approach to using deques is to maintain a sequence of recently +added elements by appending to the right and popping to the left:: + + def moving_average(iterable, n=3): + # moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0 + # http://en.wikipedia.org/wiki/Moving_average + it = iter(iterable) + d = deque(itertools.islice(it, n)) + s = sum(d) + if len(d) == n: + yield s / n + for elem in it: + s += elem - d.popleft() + d.append(elem) + yield s / n + The :meth:`rotate` method provides a way to implement :class:`deque` slicing and deletion. For example, a pure python implementation of ``del d[n]`` relies on the :meth:`rotate` method to position elements to be popped:: @@ -459,31 +482,6 @@ stack manipulations such as ``dup``, ``drop``, ``swap``, ``over``, ``pick``, ``rot``, and ``roll``. -Multi-pass data reduction algorithms can be succinctly expressed and efficiently -coded by extracting elements with multiple calls to :meth:`popleft`, applying -a reduction function, and calling :meth:`append` to add the result back to the -deque. - -For example, building a balanced binary tree of nested lists entails reducing -two adjacent nodes into one by grouping them in a list: - - >>> def maketree(iterable): - ... d = deque(iterable) - ... while len(d) > 1: - ... pair = [d.popleft(), d.popleft()] - ... d.append(pair) - ... return list(d) - ... - >>> print(maketree('abcdefgh')) - [[[['a', 'b'], ['c', 'd']], [['e', 'f'], ['g', 'h']]]] - -Bounded length deques provide functionality similar to the ``tail`` filter -in Unix:: - - def tail(filename, n=10): - 'Return the last n lines of a file' - return deque(open(filename), n) - :class:`defaultdict` objects ---------------------------- @@ -627,7 +625,7 @@ If *rename* is true, invalid fieldnames are automatically replaced with positional names. For example, ``['abc', 'def', 'ghi', 'abc']`` is - converted to ``['abc', '_2', 'ghi', '_4']``, eliminating the keyword + converted to ``['abc', '_1', 'ghi', '_3']``, eliminating the keyword ``def`` and the duplicate fieldname ``abc``. If *verbose* is true, the class definition is printed just before being built. Modified: python/branches/py3k-short-float-repr/Doc/library/csv.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/csv.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/csv.rst Sun Apr 5 01:04:14 2009 @@ -33,14 +33,6 @@ write sequences. Programmers can also read and write data in dictionary form using the :class:`DictReader` and :class:`DictWriter` classes. -.. note:: - - This version of the :mod:`csv` module doesn't support Unicode input. Also, - there are currently some issues regarding ASCII NUL characters. Accordingly, - all input should be UTF-8 or printable ASCII to be safe; see the examples in - section :ref:`csv-examples`. These restrictions will be removed in the future. - - .. seealso:: :pep:`305` - CSV File API @@ -60,8 +52,8 @@ Return a reader object which will iterate over lines in the given *csvfile*. *csvfile* can be any object which supports the :term:`iterator` protocol and returns a string each time its :meth:`next` method is called --- file objects and list - objects are both suitable. If *csvfile* is a file object, it must be opened - with the 'b' flag on platforms where that makes a difference. An optional + objects are both suitable. If *csvfile* is a file object, it should be opened + with ``newline=''``. [#]_ An optional *dialect* parameter can be given which is used to define a set of parameters specific to a particular CSV dialect. It may be an instance of a subclass of the :class:`Dialect` class or one of the strings returned by the @@ -71,20 +63,13 @@ section :ref:`csv-fmt-params`. Each row read from the csv file is returned as a list of strings. No - automatic data type conversion is performed. - - The parser is quite strict with respect to multi-line quoted fields. Previously, - if a line ended within a quoted field without a terminating newline character, a - newline would be inserted into the returned field. This behavior caused problems - when reading files which contained carriage return characters within fields. - The behavior was changed to return the field without inserting newlines. As a - consequence, if newlines embedded within fields are important, the input should - be split into lines in a manner which preserves the newline characters. + automatic data type conversion is performed unless the ``QUOTE_NONNUMERIC`` format + option is specified (in which case unquoted fields are transformed into floats). A short usage example:: >>> import csv - >>> spamReader = csv.reader(open('eggs.csv'), delimiter=' ', quotechar='|') + >>> spamReader = csv.reader(open('eggs.csv', newline=''), delimiter=' ', quotechar='|') >>> for row in spamReader: ... print(', '.join(row)) Spam, Spam, Spam, Spam, Spam, Baked Beans @@ -95,8 +80,7 @@ Return a writer object responsible for converting the user's data into delimited strings on the given file-like object. *csvfile* can be any object with a - :func:`write` method. If *csvfile* is a file object, it must be opened with the - 'b' flag on platforms where that makes a difference. An optional *dialect* + :func:`write` method. An optional *dialect* parameter can be given which is used to define a set of parameters specific to a particular CSV dialect. It may be an instance of a subclass of the :class:`Dialect` class or one of the strings returned by the @@ -270,7 +254,6 @@ Raised by any of the functions when an error is detected. - .. _csv-fmt-params: Dialects and Formatting Parameters @@ -351,14 +334,13 @@ Reader objects (:class:`DictReader` instances and objects returned by the :func:`reader` function) have the following public methods: - -.. method:: csvreader.next() +.. method:: csvreader.__next__() Return the next row of the reader's iterable object as a list, parsed according - to the current dialect. + to the current dialect. Usually you should call this as ``next(reader)``. -Reader objects have the following public attributes: +Reader objects have the following public attributes: .. attribute:: csvreader.dialect @@ -371,10 +353,8 @@ number of records returned, as records can span multiple lines. - DictReader objects have the following public attribute: - .. attribute:: csvreader.fieldnames If not passed as a parameter when creating the object, this attribute is @@ -422,41 +402,52 @@ The simplest example of reading a CSV file:: import csv - reader = csv.reader(open("some.csv", "rb")) + reader = csv.reader(open("some.csv", newline='')) for row in reader: print(row) Reading a file with an alternate format:: import csv - reader = csv.reader(open("passwd", "rb"), delimiter=':', quoting=csv.QUOTE_NONE) + reader = csv.reader(open("passwd"), delimiter=':', quoting=csv.QUOTE_NONE) for row in reader: print(row) The corresponding simplest possible writing example is:: import csv - writer = csv.writer(open("some.csv", "wb")) + writer = csv.writer(open("some.csv", "w")) writer.writerows(someiterable) +Since :func:`open` is used to open a CSV file for reading, the file +will by default be decoded into unicode using the system default +encoding (see :func:`locale.getpreferredencoding`). To decode a file +using a different encoding, use the ``encoding`` argument of open:: + + import csv + reader = csv.reader(open("some.csv", newline='', encoding='utf-8')) + for row in reader: + print(row) + +The same applies to writing in something other than the system default +encoding: specify the encoding argument when opening the output file. + Registering a new dialect:: import csv - csv.register_dialect('unixpwd', delimiter=':', quoting=csv.QUOTE_NONE) - - reader = csv.reader(open("passwd", "rb"), 'unixpwd') + reader = csv.reader(open("passwd"), 'unixpwd') A slightly more advanced use of the reader --- catching and reporting errors:: import csv, sys filename = "some.csv" - reader = csv.reader(open(filename, "rb")) + reader = csv.reader(open(filename, newline='')) try: for row in reader: print(row) except csv.Error as e: - sys.exit('file %s, line %d: %s' % (filename, reader.line_num, e)) + sys.exit('file {}, line {}: {}'.format(filename, reader.line_num, e)) And while the module doesn't directly support parsing strings, it can easily be done:: @@ -465,94 +456,10 @@ for row in csv.reader(['one,two,three']): print(row) -The :mod:`csv` module doesn't directly support reading and writing Unicode, but -it is 8-bit-clean save for some problems with ASCII NUL characters. So you can -write functions or classes that handle the encoding and decoding for you as long -as you avoid encodings like UTF-16 that use NULs. UTF-8 is recommended. - -:func:`unicode_csv_reader` below is a :term:`generator` that wraps :class:`csv.reader` -to handle Unicode CSV data (a list of Unicode strings). :func:`utf_8_encoder` -is a :term:`generator` that encodes the Unicode strings as UTF-8, one string (or row) at -a time. The encoded strings are parsed by the CSV reader, and -:func:`unicode_csv_reader` decodes the UTF-8-encoded cells back into Unicode:: - - import csv - def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs): - # csv.py doesn't do Unicode; encode temporarily as UTF-8: - csv_reader = csv.reader(utf_8_encoder(unicode_csv_data), - dialect=dialect, **kwargs) - for row in csv_reader: - # decode UTF-8 back to Unicode, cell by cell: - yield [unicode(cell, 'utf-8') for cell in row] - - def utf_8_encoder(unicode_csv_data): - for line in unicode_csv_data: - yield line.encode('utf-8') - -For all other encodings the following :class:`UnicodeReader` and -:class:`UnicodeWriter` classes can be used. They take an additional *encoding* -parameter in their constructor and make sure that the data passes the real -reader or writer encoded as UTF-8:: - - import csv, codecs, io - - class UTF8Recoder: - """ - Iterator that reads an encoded stream and reencodes the input to UTF-8 - """ - def __init__(self, f, encoding): - self.reader = codecs.getreader(encoding)(f) - - def __iter__(self): - return self - - def __next__(self): - return next(self.reader).encode("utf-8") - - class UnicodeReader: - """ - A CSV reader which will iterate over lines in the CSV file "f", - which is encoded in the given encoding. - """ - - def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds): - f = UTF8Recoder(f, encoding) - self.reader = csv.reader(f, dialect=dialect, **kwds) - - def __next__(self): - row = next(self.reader) - return [unicode(s, "utf-8") for s in row] - - def __iter__(self): - return self - - class UnicodeWriter: - """ - A CSV writer which will write rows to CSV file "f", - which is encoded in the given encoding. - """ - - def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds): - # Redirect output to a queue - self.queue = io.StringIO() - self.writer = csv.writer(self.queue, dialect=dialect, **kwds) - self.stream = f - self.encoder = codecs.getincrementalencoder(encoding)() - - def writerow(self, row): - self.writer.writerow([s.encode("utf-8") for s in row]) - # Fetch UTF-8 output from the queue ... - data = self.queue.getvalue() - data = data.decode("utf-8") - # ... and reencode it into the target encoding - data = self.encoder.encode(data) - # write to the target stream - self.stream.write(data) - # empty queue - self.queue.truncate(0) - - def writerows(self, rows): - for row in rows: - self.writerow(row) +.. rubric:: Footnotes +.. [#] If ``newline=''`` is not specified, newlines embedded inside quoted fields + will not be interpreted correctly. It should always be safe to specify + ``newline=''``, since the csv module does its own universal newline handling + on input. Modified: python/branches/py3k-short-float-repr/Doc/library/datetime.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/datetime.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/datetime.rst Sun Apr 5 01:04:14 2009 @@ -1621,8 +1621,12 @@ the output hour field if the ``%I`` directive is used to parse the hour. (3) - The range really is ``0`` to ``61``; this accounts for leap seconds and the - (very rare) double leap seconds. + The range really is ``0`` to ``61``; according to the Posix standard this + accounts for leap seconds and the (very rare) double leap seconds. + The :mod:`time` module may produce and does accept leap seconds since + it is based on the Posix standard, but the :mod:`datetime` module + does not accept leap seconds in :func:`strptime` input nor will it + produce them in :func:`strftime` output. (4) When used with the :func:`strptime` function, ``%U`` and ``%W`` are only used in Modified: python/branches/py3k-short-float-repr/Doc/library/email.header.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/email.header.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/email.header.rst Sun Apr 5 01:04:14 2009 @@ -72,7 +72,7 @@ Optional *continuation_ws* must be :rfc:`2822`\ -compliant folding whitespace, and is usually either a space or a hard tab character. This character will be - prepended to continuation lines. + prepended to continuation lines. *continuation_ws* defaults to a single space character (" "). Optional *errors* is passed straight through to the :meth:`append` method. Modified: python/branches/py3k-short-float-repr/Doc/library/functions.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/functions.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/functions.rst Sun Apr 5 01:04:14 2009 @@ -334,12 +334,12 @@ This function supports dynamic execution of Python code. *object* must be either a string or a code object. If it is a string, the string is parsed as a suite of Python statements which is then executed (unless a syntax error - occurs). If it is a code object, it is simply executed. In all cases, the - code that's executed is expected to be valid as file input (see the section - "File input" in the Reference Manual). Be aware that the :keyword:`return` - and :keyword:`yield` statements may not be used outside of function - definitions even within the context of code passed to the :func:`exec` - function. The return value is ``None``. + occurs). [#]_ If it is a code object, it is simply executed. In all cases, + the code that's executed is expected to be valid as file input (see the + section "File input" in the Reference Manual). Be aware that the + :keyword:`return` and :keyword:`yield` statements may not be used outside of + function definitions even within the context of code passed to the + :func:`exec` function. The return value is ``None``. In all cases, if the optional parts are omitted, the code is executed in the current scope. If only *globals* is provided, it must be a dictionary, which @@ -1275,13 +1275,10 @@ .. rubric:: Footnotes -.. [#] Specifying a buffer size currently has no effect on systems that don't have - :cfunc:`setvbuf`. The interface to specify the buffer size is not done using a - method that calls :cfunc:`setvbuf`, because that may dump core when called after - any I/O has been performed, and there's no reliable way to determine whether - this is the case. +.. [#] Note that the parser only accepts the Unix-style end of line convention. + If you are reading the code from a file, make sure to use newline conversion + mode to convert Windows or Mac-style newlines. .. [#] In the current implementation, local variable bindings cannot normally be affected this way, but variables retrieved from other scopes (such as modules) can be. This may change. - Modified: python/branches/py3k-short-float-repr/Doc/library/http.client.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/http.client.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/http.client.rst Sun Apr 5 01:04:14 2009 @@ -59,8 +59,8 @@ .. class:: HTTPResponse(sock[, debuglevel=0][, strict=0]) - Class whose instances are returned upon successful connection. Not instantiated - directly by user. + Class whose instances are returned upon successful connection. Not + instantiated directly by user. The following exceptions are raised as appropriate: @@ -433,7 +433,10 @@ HTTPResponse Objects -------------------- -:class:`HTTPResponse` instances have the following methods and attributes: +An :class:`HTTPResponse` instance wraps the HTTP response from the +server. It provides access to the request headers and the entity +body. The response is an iterable object and can be used in a with +statement. .. method:: HTTPResponse.read([amt]) @@ -454,7 +457,9 @@ .. attribute:: HTTPResponse.msg - An :class:`email.message.Message` instance containing the response headers. + A :class:`http.client.HTTPMessage` instance containing the response + headers. :class:`http.client.HTTPMessage` is a subclass of + :class:`email.message.Message`. .. attribute:: HTTPResponse.version @@ -472,6 +477,12 @@ Reason phrase returned by server. +.. attribute:: HTTPResponse.debuglevel + + A debugging hook. If `debuglevel` is greater than zero, messages + will be printed to stdout as the response is read and parsed. + + Examples -------- @@ -505,3 +516,13 @@ >>> data = response.read() >>> conn.close() + +.. _httpmessage-objects: + +HTTPMessage Objects +------------------- + +An :class:`http.client.HTTPMessage` instance holds the headers from an HTTP +response. It is implemented using the :class:`email.message.Message` class. + +.. XXX Define the methods that clients can depend upon between versions. Modified: python/branches/py3k-short-float-repr/Doc/library/importlib.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/importlib.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/importlib.rst Sun Apr 5 01:04:14 2009 @@ -37,7 +37,7 @@ The :func:`.__import__` function The built-in function for which the :keyword:`import` statement is - syntactic sugar for. + syntactic sugar. :pep:`235` Import on Case-Insensitive Platforms @@ -71,16 +71,20 @@ Import a module. The *name* argument specifies what module to import in absolute or relative terms (e.g. either ``pkg.mod`` or ``..mod``). If the name is - specified in relative terms, then the *package* argument must be - set to the package which is to act as the anchor for resolving the + specified in relative terms, then the *package* argument must be set to + the name of the package which is to act as the anchor for resolving the package name (e.g. ``import_module('..mod', 'pkg.subpkg')`` will import ``pkg.mod``). The :func:`import_module` function acts as a simplifying wrapper around - :func:`__import__`. This means all semantics of the function are derived - from :func:`__import__`, including requiring the package from which an - import is occurring to have been previously imported (i.e., *package* - must already be imported). + :func:`importlib.__import__`. This means all semantics of the function are + derived from :func:`importlib.__import__`, including requiring the package + from which an import is occurring to have been previously imported + (i.e., *package* must already be imported). The most important difference + is that :func:`import_module` returns the most nested package or module + that was imported (e.g. ``pkg.mod``), while :func:`__import__` returns the + top-level package or module (e.g. ``pkg``). + :mod:`importlib.abc` -- Abstract base classes related to import --------------------------------------------------------------- @@ -96,21 +100,21 @@ .. class:: Finder An abstract base class representing a :term:`finder`. + See :pep:`302` for the exact definition for a finder. .. method:: find_module(fullname, path=None) An abstract method for finding a :term:`loader` for the specified module. If the :term:`finder` is found on :data:`sys.meta_path` and the - module to be searched for is a subpackage or module then *path* is set - to the value of :attr:`__path__` from the parent package. If a loader + module to be searched for is a subpackage or module then *path* will + be the value of :attr:`__path__` from the parent package. If a loader cannot be found, :keyword:`None` is returned. - The exact definition of a :term:`finder` can be found in :pep:`302`. - .. class:: Loader An abstract base class for a :term:`loader`. + See :pep:`302` for the exact definition for a loader. .. method:: load_module(fullname) @@ -118,18 +122,19 @@ loaded, :exc:`ImportError` is raised, otherwise the loaded module is returned. - If the requested module is already exists in :data:`sys.modules`, that + If the requested module already exists in :data:`sys.modules`, that module should be used and reloaded. - Otherwise a new module is to be created by the loader and inserted into - :data:`sys.modules` before any loading begins to prevent recursion from - the import. If the loader inserted into a module and the load fails it + Otherwise the loader should create a new module and insert it into + :data:`sys.modules` before any loading begins, to prevent recursion + from the import. If the loader inserted a module and the load fails, it must be removed by the loader from :data:`sys.modules`; modules already in :data:`sys.modules` before the loader began execution should be left alone. The :func:`importlib.util.module_for_loader` decorator handles all of these details. - The loader is expected to set several attributes on the module when - adding a new module to :data:`sys.modules`. + The loader should set several attributes on the module. + (Note that some of these attributes can change when a module is + reloaded.) - :attr:`__name__` The name of the module. @@ -139,7 +144,7 @@ modules). - :attr:`__path__` - Set to a list of strings specifying the search path within a + A list of strings specifying the search path within a package. This attribute is not set on modules. - :attr:`__package__` @@ -149,9 +154,9 @@ for :attr:`__package__`. - :attr:`__loader__` - Set to the loader used to load the module. - - See :pep:`302` for the exact definition for a loader. + The loader used to load the module. + (This is not set by the built-in import machinery, + but it should be set whenever a :term:`loader` is used.) .. class:: ResourceLoader @@ -163,17 +168,18 @@ .. method:: get_data(path) An abstract method to return the bytes for the data located at *path*. - Loaders that have a file-like storage back-end can implement this - abstract method to give direct access + Loaders that have a file-like storage back-end + that allows storing arbitrary data + can implement this abstract method to give direct access to the data stored. :exc:`IOError` is to be raised if the *path* cannot be found. The *path* is expected to be constructed using a module's - :attr:`__path__` attribute or an item from :attr:`__path__`. + :attr:`__file__` attribute or an item from a package's :attr:`__path__`. .. class:: InspectLoader An abstract base class for a :term:`loader` which implements the optional - :pep:`302` protocol for loaders which inspect modules. + :pep:`302` protocol for loaders that inspect modules. .. method:: get_code(fullname) @@ -185,7 +191,7 @@ .. method:: get_source(fullname) An abstract method to return the source of a module. It is returned as - a string with universal newline support. Returns :keyword:`None` if no + a text string with universal newlines. Returns :keyword:`None` if no source is available (e.g. a built-in module). Raises :exc:`ImportError` if the loader cannot find the module specified. @@ -224,14 +230,17 @@ A concrete implementation of :meth:`importlib.abc.InspectLoader.get_code` that creates code objects - from Python source code. + from Python source code, by requesting the source code (using + :meth:`source_path` and :meth:`get_data`), converting it to standard + newlines, and compiling it with the built-in :func:`compile` function. .. method:: get_source(fullname) A concrete implementation of :meth:`importlib.abc.InspectLoader.get_source`. Uses :meth:`importlib.abc.InspectLoader.get_data` and :meth:`source_path` to - get the source code. + get the source code. It tries to guess the source encoding using + :func:`tokenize.detect_encoding`. .. class:: PyPycLoader @@ -250,8 +259,9 @@ .. method:: bytecode_path(fullname) An abstract method which returns the path to the bytecode for the - specified module. :keyword:`None` is returned if there is no bytecode. - :exc:`ImportError` is raised if the module is not found. + specified module, if it exists. It returns :keyword:`None` + if no bytecode exists (yet). + Raises :exc:`ImportError` if the module is not found. .. method:: write_bytecode(fullname, bytecode) @@ -259,6 +269,7 @@ use. If the bytecode is written, return :keyword:`True`. Return :keyword:`False` if the bytecode could not be written. This method should not be called if :data:`sys.dont_write_bytecode` is true. + The *bytecode* argument should be a bytes string or bytes array. :mod:`importlib.machinery` -- Importers and path hooks @@ -328,16 +339,18 @@ .. function:: module_for_loader(method) - A :term:`decorator` for a :term:`loader` which handles selecting the proper + A :term:`decorator` for a :term:`loader` method, + to handle selecting the proper module object to load with. The decorated method is expected to have a call signature taking two positional arguments (e.g. ``load_module(self, module)``) for which the second argument - will be the module object to be used by the loader. Note that the decorator + will be the module **object** to be used by the loader. + Note that the decorator will not work on static methods because of the assumption of two arguments. - The decorated method will take in the name of the module to be loaded as - expected for a :term:`loader`. If the module is not found in + The decorated method will take in the **name** of the module to be loaded + as expected for a :term:`loader`. If the module is not found in :data:`sys.modules` then a new one is constructed with its :attr:`__name__` attribute set. Otherwise the module found in :data:`sys.modules` will be passed into the method. If an @@ -346,18 +359,17 @@ module from being in left in :data:`sys.modules`. If the module was already in :data:`sys.modules` then it is left alone. - Use of this decorator handles all the details of what module object a + Use of this decorator handles all the details of which module object a loader should initialize as specified by :pep:`302`. - .. function:: set_loader(fxn) - A :term:`decorator` for a :term:`loader` to set the :attr:`__loader__` + A :term:`decorator` for a :term:`loader` method, + to set the :attr:`__loader__` attribute on loaded modules. If the attribute is already set the decorator does nothing. It is assumed that the first positional argument to the wrapped method is what :attr:`__loader__` should be set to. - .. function:: set_package(fxn) A :term:`decorator` for a :term:`loader` to set the :attr:`__package__` @@ -365,3 +377,107 @@ set and has a value other than :keyword:`None` it will not be changed. Note that the module returned by the loader is what has the attribute set on and not the module found in :data:`sys.modules`. + + Reliance on this decorator is discouraged when it is possible to set + :attr:`__package__` before the execution of the code is possible. By + setting it before the code for the module is executed it allows the + attribute to be used at the global level of the module during + initialization. + + +Example +------- + +Below is an example meta path importer that uses a dict for back-end storage +for source code. While not an optimal solution -- manipulations of +:attr:`__path__` on packages does not influence import -- it does illustrate +what little is required to implement an importer. + +.. testcode:: + + """An importer where source is stored in a dict.""" + from importlib import abc + + + class DictImporter(abc.Finder, abc.PyLoader): + + """A meta path importer that stores source code in a dict. + + The keys are the module names -- packages must end in ``.__init__``. + The values must be something that can be passed to 'bytes'. + + """ + + def __init__(self, memory): + """Store the dict.""" + self.memory = memory + + def contains(self, name): + """See if a module or package is in the dict.""" + if name in self.memory: + return name + package_name = '{}.__init__'.format(name) + if package_name in self.memory: + return package_name + return False + + __contains__ = contains # Convenience. + + def find_module(self, fullname, path=None): + """Find the module in the dict.""" + if fullname in self: + return self + return None + + def source_path(self, fullname): + """Return the module name if the module is in the dict.""" + if not fullname in self: + raise ImportError + return fullname + + def get_data(self, path): + """Return the bytes for the source. + + The value found in the dict is passed through 'bytes' before being + returned. + + """ + name = self.contains(path) + if not name: + raise IOError + return bytes(self.memory[name]) + + def is_package(self, fullname): + """Tell if module is a package based on whether the dict contains the + name with ``.__init__`` appended to it.""" + if fullname not in self: + raise ImportError + if fullname in self.memory: + return False + # If name is in this importer but not as it is then it must end in + # ``__init__``. + else: + return True + +.. testcode:: + :hide: + + import importlib + import sys + + + # Build the dict; keys of name, value of __package__. + names = {'_top_level': '', '_pkg.__init__': '_pkg', '_pkg.mod': '_pkg'} + source = {name: "name = {!r}".format(name).encode() for name in names} + + # Register the meta path importer. + importer = DictImporter(source) + sys.meta_path.append(importer) + + # Sanity check. + for name in names: + module = importlib.import_module(name) + assert module.__name__ == name + assert getattr(module, 'name') == name + assert module.__loader__ is importer + assert module.__package__ == names[name] Modified: python/branches/py3k-short-float-repr/Doc/library/io.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/io.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/io.rst Sun Apr 5 01:04:14 2009 @@ -270,12 +270,18 @@ interpreted relative to the position indicated by *whence*. Values for *whence* are: - * ``0`` -- start of the stream (the default); *offset* should be zero or positive - * ``1`` -- current stream position; *offset* may be negative - * ``2`` -- end of the stream; *offset* is usually negative + * :data:`SEEK_SET` or ``0`` -- start of the stream (the default); + *offset* should be zero or positive + * :data:`SEEK_CUR` or ``1`` -- current stream position; *offset* may + be negative + * :data:`SEEK_END` or ``2`` -- end of the stream; *offset* is usually + negative Return the new absolute position. + .. versionadded:: 2.7 + The ``SEEK_*`` constants + .. method:: seekable() Return ``True`` if the stream supports random access. If ``False``, Modified: python/branches/py3k-short-float-repr/Doc/library/mmap.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/mmap.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/mmap.rst Sun Apr 5 01:04:14 2009 @@ -6,13 +6,13 @@ :synopsis: Interface to memory-mapped files for Unix and Windows. -Memory-mapped file objects behave like both strings and like file objects. -Unlike normal string objects, however, these are mutable. You can use mmap -objects in most places where strings are expected; for example, you can use -the :mod:`re` module to search through a memory-mapped file. Since they're -mutable, you can change a single character by doing ``obj[index] = 'a'``, or -change a substring by assigning to a slice: ``obj[i1:i2] = '...'``. You can -also read and write data starting at the current file position, and +Memory-mapped file objects behave like both :class:`bytes` and like file +objects. Unlike normal :class:`bytes` objects, however, these are mutable. +You can use mmap objects in most places where :class:`bytes` are expected; for +example, you can use the :mod:`re` module to search through a memory-mapped file. +Since they're mutable, you can change a single byte by doing ``obj[index] = 97``, +or change a subsequence by assigning to a slice: ``obj[i1:i2] = b'...'``. +You can also read and write data starting at the current file position, and :meth:`seek` through the file to different positions. A memory-mapped file is created by the :class:`mmap` constructor, which is @@ -94,21 +94,21 @@ # write a simple example file with open("hello.txt", "wb") as f: - f.write("Hello Python!\n") + f.write(b"Hello Python!\n") with open("hello.txt", "r+b") as f: # memory-map the file, size 0 means whole file map = mmap.mmap(f.fileno(), 0) # read content via standard file methods - print(map.readline()) # prints "Hello Python!" + print(map.readline()) # prints b"Hello Python!\n" # read content via slice notation - print(map[:5]) # prints "Hello" + print(map[:5]) # prints b"Hello" # update content using slice notation; # note that new content must have same size - map[6:] = " world!\n" + map[6:] = b" world!\n" # ... and read again using standard file methods map.seek(0) - print(map.readline()) # prints "Hello world!" + print(map.readline()) # prints b"Hello world!\n" # close the map map.close() @@ -120,7 +120,7 @@ import os map = mmap.mmap(-1, 13) - map.write("Hello world!") + map.write(b"Hello world!") pid = os.fork() @@ -140,10 +140,10 @@ result in an exception being raised. - .. method:: find(string[, start[, end]]) + .. method:: find(sub[, start[, end]]) - Returns the lowest index in the object where the substring *string* is - found, such that *string* is contained in the range [*start*, *end*]. + Returns the lowest index in the object where the subsequence *sub* is + found, such that *sub* is contained in the range [*start*, *end*]. Optional arguments *start* and *end* are interpreted as in slice notation. Returns ``-1`` on failure. @@ -172,15 +172,15 @@ .. method:: read(num) - Return a string containing up to *num* bytes starting from the current - file position; the file position is updated to point after the bytes that - were returned. + Return a :class:`bytes` containing up to *num* bytes starting from the + current file position; the file position is updated to point after the + bytes that were returned. .. method:: read_byte() - Returns a string of length 1 containing the character at the current file - position, and advances the file position by 1. + Returns a byte at the current file position as an integer, and advances + the file position by 1. .. method:: readline() @@ -196,10 +196,10 @@ throw a :exc:`TypeError` exception. - .. method:: rfind(string[, start[, end]]) + .. method:: rfind(sub[, start[, end]]) - Returns the highest index in the object where the substring *string* is - found, such that *string* is contained in the range [*start*, *end*]. + Returns the highest index in the object where the subsequence *sub* is + found, such that *sub* is contained in the range [*start*, *end*]. Optional arguments *start* and *end* are interpreted as in slice notation. Returns ``-1`` on failure. @@ -223,9 +223,9 @@ Returns the current position of the file pointer. - .. method:: write(string) + .. method:: write(bytes) - Write the bytes in *string* into memory at the current position of the + Write the bytes in *bytes* into memory at the current position of the file pointer; the file position is updated to point after the bytes that were written. If the mmap was created with :const:`ACCESS_READ`, then writing to it will throw a :exc:`TypeError` exception. @@ -233,7 +233,7 @@ .. method:: write_byte(byte) - Write the single-character string *byte* into memory at the current + Write the the integer *byte* into memory at the current position of the file pointer; the file position is advanced by ``1``. If the mmap was created with :const:`ACCESS_READ`, then writing to it will throw a :exc:`TypeError` exception. Modified: python/branches/py3k-short-float-repr/Doc/library/os.path.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/os.path.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/os.path.rst Sun Apr 5 01:04:14 2009 @@ -189,7 +189,7 @@ .. function:: normcase(path) - Normalize the case of a pathname. On Unix, this returns the path unchanged; on + Normalize the case of a pathname. On Unix and MacOSX, this returns the path unchanged; on case-insensitive filesystems, it converts the path to lowercase. On Windows, it also converts forward slashes to backward slashes. Modified: python/branches/py3k-short-float-repr/Doc/library/pickle.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/pickle.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/pickle.rst Sun Apr 5 01:04:14 2009 @@ -14,6 +14,7 @@ .. sectionauthor:: Jim Kerr . .. sectionauthor:: Barry Warsaw + The :mod:`pickle` module implements a fundamental, but powerful algorithm for serializing and de-serializing a Python object structure. "Pickling" is the process whereby a Python object hierarchy is converted into a byte stream, and @@ -265,11 +266,6 @@ See :ref:`pickle-persistent` for details and examples of uses. - .. method:: clear_memo() - - Deprecated. Use the :meth:`clear` method on :attr:`memo`, instead. - Clear the pickler's memo, useful when reusing picklers. - .. attribute:: fast Deprecated. Enable fast mode if set to a true value. The fast mode @@ -280,26 +276,6 @@ Use :func:`pickletools.optimize` if you need more compact pickles. - .. attribute:: memo - - Dictionary holding previously pickled objects to allow shared or - recursive objects to pickled by reference as opposed to by value. - - -.. XXX Move these comments to somewhere more appropriate. - -It is possible to make multiple calls to the :meth:`dump` method of the same -:class:`Pickler` instance. These must then be matched to the same number of -calls to the :meth:`load` method of the corresponding :class:`Unpickler` -instance. If the same object is pickled by multiple :meth:`dump` calls, the -:meth:`load` will all yield references to the same object. - -Please note, this is intended for pickling multiple objects without intervening -modifications to the objects or their parts. If you modify an object and then -pickle it again using the same :class:`Pickler` instance, the object is not -pickled again --- a reference to it is pickled and the :class:`Unpickler` will -return the old value, not the modified one. - .. class:: Unpickler(file, [\*, encoding="ASCII", errors="strict"]) @@ -593,7 +569,7 @@ line = self.file.readline() if not line: return None - if line.endswith("\n"): + if line.endswith('\n'): line = line[:-1] return "%i: %s" % (self.lineno, line) @@ -707,25 +683,24 @@ As our examples shows, you have to be careful with what you allow to be unpickled. Therefore if security is a concern, you may want to consider -alternatives such as the marshalling API in :mod:`xmlrpc.client` or third-party -solutions. +alternatives such as the marshalling API in :mod:`xmlrpc.client` or +third-party solutions. .. _pickle-example: -Usage Examples --------------- +Examples +-------- -For the simplest code, use the :func:`dump` and :func:`load` functions. Note -that a self-referencing list is pickled and restored correctly. :: +For the simplest code, use the :func:`dump` and :func:`load` functions. :: import pickle # An arbitrary collection of objects supported by pickle. data = { - 'a': [1, 2.0, 3, 4+6j], - 'b': ("character string", b"byte string"), - 'c': set([None, True, False]) + 'a': [1, 2.0, 3, 4+6j], + 'b': ("character string", b"byte string"), + 'c': set([None, True, False]) } with open('data.pickle', 'wb') as f: @@ -743,11 +718,18 @@ data = pickle.load(f) +.. XXX: Add examples showing how to optimize pickles for size (like using +.. pickletools.optimize() or the gzip module). + + .. seealso:: Module :mod:`copyreg` Pickle interface constructor registration for extension types. + Module :mod:`pickletools` + Tools for working with and analyzing pickled data. + Module :mod:`shelve` Indexed databases of objects; uses :mod:`pickle`. Modified: python/branches/py3k-short-float-repr/Doc/library/pickletools.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/pickletools.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/pickletools.rst Sun Apr 5 01:04:14 2009 @@ -3,16 +3,14 @@ =================================================== .. module:: pickletools - :synopsis: Contains extensive comments about the pickle protocols and pickle-machine - opcodes, as well as some useful functions. - + :synopsis: Contains extensive comments about the pickle protocols and pickle-machine opcodes, as well as some useful functions. This module contains various constants relating to the intimate details of the -:mod:`pickle` module, some lengthy comments about the implementation, and a few -useful functions for analyzing pickled data. The contents of this module are -useful for Python core developers who are working on the :mod:`pickle` and -:mod:`cPickle` implementations; ordinary users of the :mod:`pickle` module -probably won't find the :mod:`pickletools` module relevant. +:mod:`pickle` module, some lengthy comments about the implementation, and a +few useful functions for analyzing pickled data. The contents of this module +are useful for Python core developers who are working on the :mod:`pickle`; +ordinary users of the :mod:`pickle` module probably won't find the +:mod:`pickletools` module relevant. .. function:: dis(pickle[, out=None, memo=None, indentlevel=4]) @@ -24,7 +22,6 @@ pickler. Successive levels, indicated by ``MARK`` opcodes in the stream, are indented by *indentlevel* spaces. - .. function:: genops(pickle) Provides an :term:`iterator` over all of the opcodes in a pickle, returning a Modified: python/branches/py3k-short-float-repr/Doc/library/random.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/random.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/random.rst Sun Apr 5 01:04:14 2009 @@ -253,3 +253,7 @@ Modeling and Computer Simulation Vol. 8, No. 1, January pp.3-30 1998. + `Complementary-Multiply-with-Carry recipe + `_ for a compatible alternative + random number generator with a long period and comparatively simple update + operations. Modified: python/branches/py3k-short-float-repr/Doc/library/shelve.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/shelve.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/shelve.rst Sun Apr 5 01:04:14 2009 @@ -48,6 +48,12 @@ disk, if feasible. This is called automatically when the shelf is closed with :meth:`close`. +.. seealso:: + + `Persistent dictionary recipe `_ + with widely supported storage formats and having the speed of native + dictionaries. + Restrictions ------------ Modified: python/branches/py3k-short-float-repr/Doc/library/time.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/time.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/time.rst Sun Apr 5 01:04:14 2009 @@ -358,15 +358,17 @@ .. function:: strptime(string[, format]) - Parse a string representing a time according to a format. The return value is - a :class:`struct_time` as returned by :func:`gmtime` or :func:`localtime`. + Parse a string representing a time according to a format. The return value + is a :class:`struct_time` as returned by :func:`gmtime` or + :func:`localtime`. The *format* parameter uses the same directives as those used by :func:`strftime`; it defaults to ``"%a %b %d %H:%M:%S %Y"`` which matches the - formatting returned by :func:`ctime`. If *string* cannot be parsed according to - *format*, or if it has excess data after parsing, :exc:`ValueError` is raised. - The default values used to fill in any missing data when more accurate values - cannot be inferred are ``(1900, 1, 1, 0, 0, 0, 0, 1, -1)``. + formatting returned by :func:`ctime`. If *string* cannot be parsed according + to *format*, or if it has excess data after parsing, :exc:`ValueError` is + raised. The default values used to fill in any missing data when more + accurate values cannot be inferred are ``(1900, 1, 1, 0, 0, 0, 0, 1, -1)``. + Both *string* and *format* must be strings. For example: Modified: python/branches/py3k-short-float-repr/Doc/library/unittest.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/unittest.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/unittest.rst Sun Apr 5 01:04:14 2009 @@ -1,4 +1,3 @@ - :mod:`unittest` --- Unit testing framework ========================================== @@ -207,8 +206,8 @@ widget = Widget('The widget') self.assertEqual(widget.size(), (50, 50), 'incorrect default size') -Note that in order to test something, we use the one of the :meth:`assert\*` or -:meth:`fail\*` methods provided by the :class:`TestCase` base class. If the +Note that in order to test something, we use the one of the :meth:`assert\*` +methods provided by the :class:`TestCase` base class. If the test fails, an exception will be raised, and :mod:`unittest` will identify the test case as a :dfn:`failure`. Any other exceptions will be treated as :dfn:`errors`. This helps you identify where the problem is: :dfn:`failures` are @@ -238,13 +237,13 @@ class DefaultWidgetSizeTestCase(SimpleWidgetTestCase): def runTest(self): - self.failUnless(self.widget.size() == (50,50), + self.assertTrue(self.widget.size() == (50,50), 'incorrect default size') class WidgetResizeTestCase(SimpleWidgetTestCase): def runTest(self): self.widget.resize(100,150) - self.failUnless(self.widget.size() == (100,150), + self.assertTrue(self.widget.size() == (100,150), 'wrong size after resize') If the :meth:`~TestCase.setUp` method raises an exception while the test is @@ -286,12 +285,12 @@ self.widget = None def testDefaultSize(self): - self.failUnless(self.widget.size() == (50,50), + self.assertTrue(self.widget.size() == (50,50), 'incorrect default size') def testResize(self): self.widget.resize(100,150) - self.failUnless(self.widget.size() == (100,150), + self.assertTrue(self.widget.size() == (100,150), 'wrong size after resize') Here we have not provided a :meth:`~TestCase.runTest` method, but have instead @@ -605,23 +604,37 @@ failures. - .. method:: assert_(expr[, msg]) + .. method:: assertTrue(expr[, msg]) + assert_(expr[, msg]) failUnless(expr[, msg]) - assertTrue(expr[, msg]) Signal a test failure if *expr* is false; the explanation for the error will be *msg* if given, otherwise it will be :const:`None`. + .. deprecated:: 2.7 + :meth:`failUnless`. + .. method:: assertEqual(first, second[, msg]) failUnlessEqual(first, second[, msg]) Test that *first* and *second* are equal. If the values do not compare equal, the test will fail with the explanation given by *msg*, or - :const:`None`. Note that using :meth:`failUnlessEqual` improves upon - doing the comparison as the first parameter to :meth:`failUnless`: the - default value for *msg* can be computed to include representations of both - *first* and *second*. + :const:`None`. Note that using :meth:`assertEqual` improves upon + doing the comparison as the first parameter to :meth:`assertTrue`: the + default value for *msg* include representations of both *first* and + *second*. + + In addition, if *first* and *second* are the exact same type and one of + list, tuple, dict, set, or frozenset or any type that a subclass + registers :meth:`addTypeEqualityFunc` the type specific equality function + will be called in order to generate a more useful default error message. + + .. versionchanged:: 2.7 + Added the automatic calling of type specific equality function. + + .. deprecated:: 2.7 + :meth:`failUnlessEqual`. .. method:: assertNotEqual(first, second[, msg]) @@ -629,11 +642,14 @@ Test that *first* and *second* are not equal. If the values do compare equal, the test will fail with the explanation given by *msg*, or - :const:`None`. Note that using :meth:`failIfEqual` improves upon doing - the comparison as the first parameter to :meth:`failUnless` is that the + :const:`None`. Note that using :meth:`assertNotEqual` improves upon doing + the comparison as the first parameter to :meth:`assertTrue` is that the default value for *msg* can be computed to include representations of both *first* and *second*. + .. deprecated:: 2.7 + :meth:`failIfEqual`. + .. method:: assertAlmostEqual(first, second[, places[, msg]]) failUnlessAlmostEqual(first, second[, places[, msg]]) @@ -647,6 +663,9 @@ compare equal, the test will fail with the explanation given by *msg*, or :const:`None`. + .. deprecated:: 2.7 + :meth:`failUnlessAlmostEqual`. + .. method:: assertNotAlmostEqual(first, second[, places[, msg]]) failIfAlmostEqual(first, second[, places[, msg]]) @@ -660,6 +679,128 @@ compare equal, the test will fail with the explanation given by *msg*, or :const:`None`. + .. deprecated:: 2.7 + :meth:`failIfAlmostEqual`. + + + .. method:: assertGreater(first, second, msg=None) + assertGreaterEqual(first, second, msg=None) + assertLess(first, second, msg=None) + assertLessEqual(first, second, msg=None) + + Test that *first* is respectively >, >=, < or <= than *second* depending + on the method name. If not, the test will fail with the nice explanation + or with the explanation given by *msg*:: + + >>> self.assertGreaterEqual(3, 4) + AssertionError: "3" unexpectedly not greater than or equal to "4" + + .. versionadded:: 2.7 + + + .. method:: assertMultiLineEqual(self, first, second, msg=None) + + Test that the multiline string *first* is equal to the string *second*. + When not equal a diff of the two strings highlighting the differences + will be included in the error message. + + If specified *msg* will be used as the error message on failure. + + .. versionadded:: 2.7 + + + .. method:: assertRegexpMatches(text, regexp[, msg=None]): + + Verifies that a *regexp* search matches *text*. Fails with an error + message including the pattern and the *text*. *regexp* may be + a regular expression object or a string containing a regular expression + suitable for use by :func:`re.search`. + + .. versionadded:: 2.7 + + + .. method:: assertIn(first, second, msg=None) + assertNotIn(first, second, msg=None) + + Tests that *first* is or is not in *second* with a nice explanitory error + message as appropriate. + + If specified *msg* will be used as the error message on failure. + + .. versionadded:: 2.7 + + + .. method:: assertSameElements(expected, actual, msg=None) + + Test that sequence *expected* contains the same elements as *actual*. + When they don't an error message listing the differences between the + sequences will be generated. + + If specified *msg* will be used as the error message on failure. + + .. versionadded:: 2.7 + + + .. method:: assertSetEqual(set1, set2, msg=None) + + Tests that two sets are equal. If not, an error message is constructed + that lists the differences between the sets. + + Fails if either of *set1* or *set2* does not have a :meth:`set.difference` + method. + + If specified *msg* will be used as the error message on failure. + + .. versionadded:: 2.7 + + + .. method:: assertDictEqual(expected, actual, msg=None) + + Test that two dictionaries are equal. If not, an error message is + constructed that shows the differences in the dictionaries. + + If specified *msg* will be used as the error message on failure. + + .. versionadded:: 2.7 + + + .. method:: assertDictContainsSubset(expected, actual, msg=None) + + Tests whether the key value pairs in dictionary *actual* are a + superset of those in *expected*. If not, an error message listing + the missing keys and mismatched values is generated. + + If specified *msg* will be used as the error message on failure. + + .. versionadded:: 2.7 + + + .. method:: assertListEqual(list1, list2, msg=None) + assertTupleEqual(tuple1, tuple2, msg=None) + + Tests that two lists or tuples are equal. If not an error message is + constructed that shows only the differences between the two. An error + is also raised if either of the parameters are of the wrong type. + + If specified *msg* will be used as the error message on failure. + + .. versionadded:: 2.7 + + + .. method:: assertSequenceEqual(seq1, seq2, msg=None, seq_type=None) + + Tests that two sequences are equal. If a *seq_type* is supplied, both + *seq1* and *seq2* must be instances of *seq_type* or a failure will + be raised. If the sequences are different an error message is + constructed that shows the difference between the two. + + If specified *msg* will be used as the error message on failure. + + This method is used to implement :meth:`assertListEqual` and + :meth:`assertTupleEqual`. + + .. versionadded:: 2.7 + .. method:: assertRaises(exception[, callable, ...]) failUnlessRaises(exception[, callable, ...]) @@ -680,14 +821,53 @@ .. versionchanged:: 3.1 Added the ability to use :meth:`assertRaises` as a context manager. + .. deprecated:: 2.7 + :meth:`failUnlessRaises`. + + + .. method:: assertRaisesRegexp(exception, regexp[, callable, ...]) + + Like :meth:`assertRaises` but also tests that *regexp* matches + on the string representation of the raised exception. *regexp* 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') + + or:: - .. method:: failIf(expr[, msg]) - assertFalse(expr[, msg]) + with self.assertRaisesRegexp(ValueError, 'literal'): + int('XYZ') - The inverse of the :meth:`failUnless` method is the :meth:`failIf` method. + .. versionadded:: 2.7 + + + .. method:: assertIsNone(expr[, msg]) + + This signals a test failure if *expr* is not None. + + .. versionadded:: 2.7 + + + .. method:: assertIsNotNone(expr[, msg]) + + The inverse of the :meth:`assertIsNone` method. + This signals a test failure if *expr* is None. + + .. versionadded:: 2.7 + + + .. method:: assertFalse(expr[, msg]) + failIf(expr[, msg]) + + The inverse of the :meth:`assertTrue` method is the :meth:`assertFalse` method. This signals a test failure if *expr* is true, with *msg* or :const:`None` for the error message. + .. deprecated:: 2.7 + :meth:`failIf`. + .. method:: fail([msg]) @@ -703,6 +883,25 @@ fair" with the framework. The initial value of this attribute is :exc:`AssertionError`. + + .. attribute:: longMessage + + If set to True then any explicit failure message you pass in to the + assert methods will be appended to the end of the normal failure message. + The normal messages contain useful information about the objects involved, + for example the message from assertEqual shows you the repr of the two + unequal objects. Setting this attribute 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. + + The class setting can be overridden in individual tests by assigning an + instance attribute to True or False before calling the assert methods. + + .. versionadded:: 2.7 + + Testing frameworks can use the following methods to collect information on the test: @@ -732,10 +931,34 @@ .. method:: shortDescription() - Returns a one-line description of the test, or :const:`None` if no - description has been provided. The default implementation of this method - returns the first line of the test method's docstring, if available, or - :const:`None`. + Returns a description of the test, or :const:`None` if no description + has been provided. The default implementation of this method + returns the first line of the test method's docstring, if available, + along with the method name. + + .. versionchanged:: 2.7 + + In earlier versions this only returned the first line of the test + method's docstring, if available or the :const:`None`. That led to + undesirable behavior of not printing the test name when someone was + thoughtful enough to write a docstring. + + + .. method:: addTypeEqualityFunc(typeobj, function) + + Registers a type specific :meth:`assertEqual` equality checking + function to be called by :meth:`assertEqual` when both objects it has + been asked to compare are exactly *typeobj* (not subclasses). + *function* must take two positional arguments and a third msg=None + keyword argument just as :meth:`assertEqual` does. It must raise + self.failureException when inequality between the first two + parameters is detected. + + One good use of custom equality checking functions for a type + is to raise self.failureException with an error message useful + for debugging the by explaining the inequalities in detail. + + .. versionadded:: 2.7 .. class:: FunctionTestCase(testFunc[, setUp[, tearDown[, description]]]) Modified: python/branches/py3k-short-float-repr/Doc/library/urllib.error.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/urllib.error.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/urllib.error.rst Sun Apr 5 01:04:14 2009 @@ -3,7 +3,7 @@ .. module:: urllib.error :synopsis: Exception classes raised by urllib.request. -.. moduleauthor:: Jeremy Hylton +.. moduleauthor:: Jeremy Hylton .. sectionauthor:: Senthil Kumaran Modified: python/branches/py3k-short-float-repr/Doc/library/urllib.request.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/urllib.request.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/urllib.request.rst Sun Apr 5 01:04:14 2009 @@ -3,7 +3,7 @@ .. module:: urllib.request :synopsis: Next generation URL opening library. -.. moduleauthor:: Jeremy Hylton +.. moduleauthor:: Jeremy Hylton .. sectionauthor:: Moshe Zadka @@ -16,26 +16,28 @@ .. function:: urlopen(url[, data][, timeout]) - Open the URL *url*, which can be either a string or a :class:`Request` object. + Open the URL *url*, which can be either a string or a + :class:`Request` object. - *data* may be a string specifying additional data to send to the server, or - ``None`` if no such data is needed. Currently HTTP requests are the only ones - that use *data*; the HTTP request will be a POST instead of a GET when the - *data* parameter is provided. *data* should be a buffer in the standard + *data* may be a string specifying additional data to send to the + server, or ``None`` if no such data is needed. Currently HTTP + requests are the only ones that use *data*; the HTTP request will + be a POST instead of a GET when the *data* parameter is provided. + *data* should be a buffer in the standard :mimetype:`application/x-www-form-urlencoded` format. The :func:`urllib.parse.urlencode` function takes a mapping or sequence of 2-tuples and returns a string in this format. - The optional *timeout* parameter specifies a timeout in seconds for blocking - operations like the connection attempt (if not specified, the global default - timeout setting will be used). This actually only works for HTTP, HTTPS, - FTP and FTPS connections. + The optional *timeout* parameter specifies a timeout in seconds for + blocking operations like the connection attempt (if not specified, + the global default timeout setting will be used). This actually + only works for HTTP, HTTPS, FTP and FTPS connections. This function returns a file-like object with two additional methods from the :mod:`urllib.response` module - * :meth:`geturl` --- return the URL of the resource retrieved, commonly used to - determine if a redirect was followed + * :meth:`geturl` --- return the URL of the resource retrieved, + commonly used to determine if a redirect was followed * :meth:`info` --- return the meta-information of the page, such as headers, in the form of an ``http.client.HTTPMessage`` instance (see `Quick @@ -52,7 +54,6 @@ Proxy handling, which was done by passing a dictionary parameter to ``urllib.urlopen``, can be obtained by using :class:`ProxyHandler` objects. - .. function:: install_opener(opener) Install an :class:`OpenerDirector` instance as the default global opener. @@ -167,37 +168,42 @@ *url* should be a string containing a valid URL. - *data* may be a string specifying additional data to send to the server, or - ``None`` if no such data is needed. Currently HTTP requests are the only ones - that use *data*; the HTTP request will be a POST instead of a GET when the - *data* parameter is provided. *data* should be a buffer in the standard + *data* may be a string specifying additional data to send to the + server, or ``None`` if no such data is needed. Currently HTTP + requests are the only ones that use *data*; the HTTP request will + be a POST instead of a GET when the *data* parameter is provided. + *data* should be a buffer in the standard :mimetype:`application/x-www-form-urlencoded` format. The :func:`urllib.parse.urlencode` function takes a mapping or sequence of 2-tuples and returns a string in this format. - *headers* should be a dictionary, and will be treated as if :meth:`add_header` - was called with each key and value as arguments. This is often used to "spoof" - the ``User-Agent`` header, which is used by a browser to identify itself -- - some HTTP servers only allow requests coming from common browsers as opposed - to scripts. For example, Mozilla Firefox may identify itself as ``"Mozilla/5.0 - (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11"``, while :mod:`urllib`'s - default user agent string is ``"Python-urllib/2.6"`` (on Python 2.6). - - The final two arguments are only of interest for correct handling of third-party - HTTP cookies: - - *origin_req_host* should be the request-host of the origin transaction, as - defined by :rfc:`2965`. It defaults to ``http.cookiejar.request_host(self)``. - This is the host name or IP address of the original request that was - initiated by the user. For example, if the request is for an image in an - HTML document, this should be the request-host of the request for the page + *headers* should be a dictionary, and will be treated as if + :meth:`add_header` was called with each key and value as arguments. + This is often used to "spoof" the ``User-Agent`` header, which is + used by a browser to identify itself -- some HTTP servers only + allow requests coming from common browsers as opposed to scripts. + For example, Mozilla Firefox may identify itself as ``"Mozilla/5.0 + (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11"``, while + :mod:`urllib`'s default user agent string is + ``"Python-urllib/2.6"`` (on Python 2.6). + + The final two arguments are only of interest for correct handling + of third-party HTTP cookies: + + *origin_req_host* should be the request-host of the origin + transaction, as defined by :rfc:`2965`. It defaults to + ``http.cookiejar.request_host(self)``. This is the host name or IP + address of the original request that was initiated by the user. + For example, if the request is for an image in an HTML document, + this should be the request-host of the request for the page containing the image. - *unverifiable* should indicate whether the request is unverifiable, as defined - by RFC 2965. It defaults to False. An unverifiable request is one whose URL - the user did not have the option to approve. For example, if the request is for - an image in an HTML document, and the user had no option to approve the - automatic fetching of the image, this should be true. + *unverifiable* should indicate whether the request is unverifiable, + as defined by RFC 2965. It defaults to False. An unverifiable + request is one whose URL the user did not have the option to + approve. For example, if the request is for an image in an HTML + document, and the user had no option to approve the automatic + fetching of the image, this should be true. .. class:: URLopener([proxies[, **x509]]) @@ -441,9 +447,41 @@ Request Objects --------------- -The following methods describe all of :class:`Request`'s public interface, and -so all must be overridden in subclasses. +The following methods describe :class:`Request`'s public interface, +and so all may be overridden in subclasses. It also defines several +public attributes that can be used by clients to inspect the parsed +request. + +.. attribute:: Request.full_url + + The original URL passed to the constructor. + +.. attribute:: Request.type + + The URI scheme. + +.. attribute:: Request.host + + The URI authority, typically a host, but may also contain a port + separated by a colon. + +.. attribute:: Request.origin_req_host + + The original host for the request, without port. + +.. attribute:: Request.selector + + The URI path. If the :class:`Request` uses a proxy, then selector + will be the full url that is passed to the proxy. + +.. attribute:: Request.data + + The entity body for the request, or None if not specified. + +.. attribute:: Request.unverifiable + boolean, indicates whether the request is unverifiable as defined + by RFC 2965. .. method:: Request.add_data(data) Modified: python/branches/py3k-short-float-repr/Doc/license.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/license.rst (original) +++ python/branches/py3k-short-float-repr/Doc/license.rst Sun Apr 5 01:04:14 2009 @@ -31,7 +31,6 @@ Source Definition). Historically, most, but not all, Python releases have also been GPL-compatible; the table below summarizes the various releases. -<<<<<<< .working +----------------+--------------+------------+------------+-----------------+ | Release | Derived from | Year | Owner | GPL compatible? | +================+==============+============+============+=================+ Modified: python/branches/py3k-short-float-repr/Doc/reference/datamodel.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/reference/datamodel.rst (original) +++ python/branches/py3k-short-float-repr/Doc/reference/datamodel.rst Sun Apr 5 01:04:14 2009 @@ -1160,6 +1160,7 @@ The return value must be a string object. +.. _richcmpfuncs: .. method:: object.__lt__(self, other) object.__le__(self, other) object.__eq__(self, other) Modified: python/branches/py3k-short-float-repr/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k-short-float-repr/Doc/whatsnew/3.1.rst Sun Apr 5 01:04:14 2009 @@ -4,7 +4,7 @@ .. XXX Add trademark info for Apple, Microsoft. -:Author: No one so far +:Author: Raymond Hettinger :Release: |release| :Date: |today| @@ -66,6 +66,61 @@ .. ====================================================================== +PEP 372: Ordered Dictionaries +============================= + +Regular Python dictionaries iterate over key/value pairs in arbitrary order. +Over the years, a number of authors have written alternative implementations +that remember the order that the keys were originally inserted. Based on +the experiences from those implementations, the :mod:`collections` module +now has an :class:`OrderedDict` class. + +The OrderedDict API is substantially the same as regular dictionaries +but will iterate over keys and values in a guaranteed order depending on +when a key was first inserted. If a new entry overwrites an existing entry, +the original insertion position is left unchanged. Deleting an entry and +reinserting it will move it to the end. + +The standard library now supports use of ordered dictionaries in several +modules. The :mod:`ConfigParser` module uses them by default. This lets +configuration files be read, modified, and then written back in their original +order. The :mod:`collections` module's :meth:`namedtuple._asdict` method now +returns an ordered dictionary with the values appearing in the same order as +the underlying tuple indicies. The :mod:`json` module is being built-out with +an *object_pairs_hook* to allow OrderedDicts to be built by the decoder. +Support was also added for third-party tools like PyYAML. + +.. seealso:: + + :pep:`372` - Ordered Dictionaries + PEP written by Armin Ronacher and Raymond Hettinger. Implementation + written by Raymond Hettinger. + +PEP 378: Format Specifier for Thousands Separator +================================================= + +The builtin :func:`format` function and the :meth:`str.format` method use +a mini-language that now includes a simple, non-locale aware way to format +a number with a thousands separator. That provides a way to humanize a +program's output, improving its professional appearance and readability:: + + >>> format(Decimal('1234567.89'), ',f') + '1,234,567.89' + +The currently supported types are :class:`int` and :class:`decimal.Decimal`. +Support for :class:`float` is expected before the beta release. +Discussions are underway about how to specify alternative separators +like dots, spaces, apostrophes, or underscores. Locale-aware applications +should use the existing *n* format specifier which already has some support +for thousands separators. + +.. seealso:: + + :pep:`378` - Format Specifier for Thousands Separator + PEP written by Raymond Hettinger; implemented by Eric Smith and + Mark Dickinson. + + Other Language Changes ====================== @@ -85,31 +140,117 @@ >>> (n+1).bit_length() 124 - (Contributed by Fredrik Johansson and Victor Stinner; :issue:`3439`.) + (Contributed by Fredrik Johansson, Victor Stinner, Raymond Hettinger, + and Mark Dickinson; :issue:`3439`.) -* Integers are now stored internally either in base 2**15 or in base - 2**30, the base being determined at build time. Previously, they - were always stored in base 2**15. Using base 2**30 gives - significant performance improvements on 64-bit machines, but - benchmark results on 32-bit machines have been mixed. Therefore, - the default is to use base 2**30 on 64-bit machines and base 2**15 - on 32-bit machines; on Unix, there's a new configure option - --enable-big-digits that can be used to override this default. +* Added a :class:`collections.Counter` class to support convenient + counting of unique items in a sequence or iterable:: - Apart from the performance improvements this change should be - invisible to end users, with one exception: for testing and - debugging purposes there's a new structseq ``sys.int_info`` that - provides information about the internal format, giving the number of - bits per digit and the size in bytes of the C type used to store - each digit:: + >>> Counter(['red', 'blue', 'red', 'green', 'blue', 'blue']) + Counter({'blue': 3, 'red': 2, 'green': 1}) - >>> import sys - >>> sys.int_info - sys.int_info(bits_per_digit=30, sizeof_digit=4) + (Contributed by Raymond Hettinger; :issue:`1696199`.) +* Add a new module, :mod:`ttk` for access to the Tk themed widget set. The + basic idea of ttk is to separate, to the extent possible, the code + implementing a widget's behavior from the code implementing its appearance. - (Contributed by Mark Dickinson; :issue:`4258`.) + (Contributed by Kevin Walzer and Guilherme Polo; :issue:`2618` and + :issue:`2983`.) + +* The :class:`gzip.GzipFile` and :class:`bz2.BZ2File` classs now support + the context manager protocol. + + (Contributed by Jacques Frechet; :issue:`4272`.) + +* The :mod:`Decimal` module now supports two new methods to create a + decimal object that from a binary :class:`float`. The conversion is + exact but can sometimes be surprising:: + + >>> Decimal.from_float(1.1) + Decimal('1.100000000000000088817841970012523233890533447265625') + + The long decimal result shows the actual binary fraction being + stored for *1.1*. The fraction has many digits because *1.1* cannot + be exactly represented in binary. + + (Contributed by Raymond Hettinger and Mark Dickinson.) + +* The fields in :func:`format` strings can now be automatically + numbered:: + + >>> 'Sir {} of {}'.format('Gallahad', 'Camelot') + 'Sir Gallahad of Camelot' + + Formerly, the string would have required numbered fields such as: + ``'Sir {0} of {1}'``. + + (Contributed by Eric Smith; :issue:`5237`.) + +* The :mod:`itertools` module grew two new functions. The + :func:`itertools.combinations_with_replacement` function is one of + four for generating combinatorics including permutations and Cartesian + products. The :func:`itertools.compress` function mimics its namesake + from APL. Also, the existing :func:`itertools.count` function now has + an optional *step* argument and can accept any type of counting + sequence including :class:`fractions.Fraction` and + :class:`decimal.Decimal`. + + (Contributed by Raymond Hettinger.) + +* :func:`collections.namedtuple` now supports a keyword argument + *rename* which lets invalid fieldnames be automatically converted to + positional names in the form _0, _1, etc. This is useful when + the field names are being created by an external source such as a + CSV header, SQL field list, or user input. + + (Contributed by Raymond Hettinger; :issue:`1818`.) + +* ``round`(x, n)`` now returns an integer if *x* is an integer. + Previously it returned a float. + + (Contributed by Mark Dickinson; :issue:`4707`.) + +* The :func:`re.sub`, :func:`re.subn` and :func:`re.split` functions now + accept a flags parameter. + + (Contributed by Gregory Smith.) +* The :mod:`runpy` module which supports the ``-m`` command line switch + now supports the execution of packages by looking for and executing + a ``__main__`` submodule when a package name is supplied. + + (Contributed by Andi Vajda; :issue:`4195`.) + +* The :mod:`pdb` module can now access and display source code loaded via + :mod:`zipimport` (or any other conformant :pep:`302` loader). + + (Contributed by Alexander Belopolsky; :issue:`4201`.) + +* :class:`functools.partial` objects can now be pickled. + + (Suggested by Antoine Pitrou and Jesse Noller. Implemented by + Jack Diedrich; :issue:`5228`.) + +* Add :mod:`pydoc` help topics for symbols so that ``help('@')`` + works as expected in the interactive environment. + + (Contributed by David Laban; :issue:`4739`.) + +* The :mod:`unittest` module now supports skipping individual tests or classes + of tests. And it supports marking a test as a expected failure, a test that + is known to be broken, but shouldn't be counted as a failure on a + TestResult. + + (Contributed by Benjamin Peterson.) + +* A new module, :mod:`importlib` was added. It provides a complete, portable, + pure Python reference implementation of the *import* statement and its + counterpart, the :func:`__import__` function. It represents a substantial + step forward in documenting and defining the actions that take place during + imports. + + (Contributed by Brett Cannon.) .. ====================================================================== @@ -128,11 +269,52 @@ (Contributed by Amaury Forgeot d'Arc and Antoine Pitrou.) -* A new configure flag, ``--with-computed-gotos``, enables a faster opcode - dispatch mechanism on compilers which support it. Speedups of up to 20% - have been observed, depending on the system and compiler. +* Added a heuristic so that tuples and dicts containing only untrackable objects + are not tracked by the garbage collector. This can reduce the size of + collections and therefore the garbage collection overhead on long-running + programs, depending on their particular use of datatypes. + + (Contributed by Antoine Pitrou, :issue:`4688`.) + +* Enabling a configure option named ``--with-computed-gotos`` + on compilers that support it (notably: gcc, SunPro, icc), the bytecode + evaluation loop is compiled with a new dispatch mechanism which gives + speedups of up to 20%, depending on the system, the compiler, and + the benchmark. + + (Contributed by Antoine Pitrou along with a number of other participants, + :issue:`4753`). + +* The decoding of UTF-8, UTF-16 and LATIN-1 is now two to four times + faster. + + (Contributed by Antoine Pitrou and Amaury Forgeot d'Arc, :issue:`4868`.) - (Contributed by Antoine Pitrou, :issue:`4753`.) +* The :mod:`json` module is getting a C extension to substantially improve + its performance. The code is expected to be added in-time for the beta + release. + (Contributed by Bob Ippolito.) + +* Integers are now stored internally either in base 2**15 or in base + 2**30, the base being determined at build time. Previously, they + were always stored in base 2**15. Using base 2**30 gives + significant performance improvements on 64-bit machines, but + benchmark results on 32-bit machines have been mixed. Therefore, + the default is to use base 2**30 on 64-bit machines and base 2**15 + on 32-bit machines; on Unix, there's a new configure option + ``--enable-big-digits`` that can be used to override this default. + + Apart from the performance improvements this change should be invisible to + end users, with one exception: for testing and debugging purposes there's a + new :class:`structseq` ``sys.int_info`` that provides information about the + internal format, giving the number of bits per digit and the size in bytes + of the C type used to store each digit:: + + >>> import sys + >>> sys.int_info + sys.int_info(bits_per_digit=30, sizeof_digit=4) + + (Contributed by Mark Dickinson; :issue:`4258`.) .. ====================================================================== Modified: python/branches/py3k-short-float-repr/Grammar/Grammar ============================================================================== --- python/branches/py3k-short-float-repr/Grammar/Grammar (original) +++ python/branches/py3k-short-float-repr/Grammar/Grammar Sun Apr 5 01:04:14 2009 @@ -87,7 +87,7 @@ and_test: not_test ('and' not_test)* not_test: 'not' not_test | comparison comparison: star_expr (comp_op star_expr)* -comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is'|'is' 'not' +comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' star_expr: ['*'] expr expr: xor_expr ('|' xor_expr)* xor_expr: and_expr ('^' and_expr)* Modified: python/branches/py3k-short-float-repr/Include/bytesobject.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/bytesobject.h (original) +++ python/branches/py3k-short-float-repr/Include/bytesobject.h Sun Apr 5 01:04:14 2009 @@ -91,13 +91,25 @@ into the string pointed to by buffer. For the argument descriptions, see Objects/stringlib/localeutil.h */ -PyAPI_FUNC(int) _PyBytes_InsertThousandsGrouping(char *buffer, +PyAPI_FUNC(int) _PyBytes_InsertThousandsGroupingLocale(char *buffer, Py_ssize_t n_buffer, Py_ssize_t n_digits, Py_ssize_t buf_size, Py_ssize_t *count, int append_zero_char); +/* 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 */ +PyAPI_FUNC(int) _PyBytes_InsertThousandsGrouping(char *buffer, + Py_ssize_t n_buffer, + Py_ssize_t n_digits, + Py_ssize_t buf_size, + Py_ssize_t *count, + int append_zero_char, + const char *grouping, + const char *thousands_sep); + /* Flags used by string formatting */ #define F_LJUST (1<<0) #define F_SIGN (1<<1) Modified: python/branches/py3k-short-float-repr/Include/code.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/code.h (original) +++ python/branches/py3k-short-float-repr/Include/code.h Sun Apr 5 01:04:14 2009 @@ -52,10 +52,12 @@ #define CO_FUTURE_UNICODE_LITERALS 0x20000 #endif +#define CO_FUTURE_BARRY_AS_BDFL 0x40000 + /* This should be defined if a future statement modifies the syntax. For example, when a keyword is added. */ -/* #define PY_PARSER_REQUIRES_FUTURE_KEYWORD */ +#define PY_PARSER_REQUIRES_FUTURE_KEYWORD #define CO_MAXBLOCKS 20 /* Max static block nesting within a function */ Modified: python/branches/py3k-short-float-repr/Include/compile.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/compile.h (original) +++ python/branches/py3k-short-float-repr/Include/compile.h Sun Apr 5 01:04:14 2009 @@ -26,6 +26,7 @@ #define FUTURE_WITH_STATEMENT "with_statement" #define FUTURE_PRINT_FUNCTION "print_function" #define FUTURE_UNICODE_LITERALS "unicode_literals" +#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 *, Modified: python/branches/py3k-short-float-repr/Include/import.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/import.h (original) +++ python/branches/py3k-short-float-repr/Include/import.h Sun Apr 5 01:04:14 2009 @@ -43,7 +43,7 @@ PyAPI_DATA(PyTypeObject) PyNullImporter_Type; PyAPI_DATA(struct _inittab *) PyImport_Inittab; -PyAPI_FUNC(int) PyImport_AppendInittab(char *name, PyObject* (*initfunc)(void)); +PyAPI_FUNC(int) PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void)); PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab); struct _frozen { Modified: python/branches/py3k-short-float-repr/Include/parsetok.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/parsetok.h (original) +++ python/branches/py3k-short-float-repr/Include/parsetok.h Sun Apr 5 01:04:14 2009 @@ -30,6 +30,7 @@ #endif #define PyPARSE_IGNORE_COOKIE 0x0010 +#define PyPARSE_BARRY_AS_BDFL 0x0020 PyAPI_FUNC(node *) PyParser_ParseString(const char *, grammar *, int, perrdetail *); Modified: python/branches/py3k-short-float-repr/Include/patchlevel.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/patchlevel.h (original) +++ python/branches/py3k-short-float-repr/Include/patchlevel.h Sun Apr 5 01:04:14 2009 @@ -20,10 +20,10 @@ #define PY_MINOR_VERSION 1 #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA -#define PY_RELEASE_SERIAL 1 +#define PY_RELEASE_SERIAL 2 /* Version as a string */ -#define PY_VERSION "3.1a1+" +#define PY_VERSION "3.1a2" /*--end constants--*/ /* Subversion Revision number of this file (not of the repository) */ Modified: python/branches/py3k-short-float-repr/Include/pythonrun.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/pythonrun.h (original) +++ python/branches/py3k-short-float-repr/Include/pythonrun.h Sun Apr 5 01:04:14 2009 @@ -7,7 +7,7 @@ extern "C" { #endif -#define PyCF_MASK 0 +#define PyCF_MASK CO_FUTURE_BARRY_AS_BDFL #define PyCF_MASK_OBSOLETE 0 #define PyCF_SOURCE_IS_UTF8 0x0100 #define PyCF_DONT_IMPLY_DEDENT 0x0200 Modified: python/branches/py3k-short-float-repr/Include/unicodeobject.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/unicodeobject.h (original) +++ python/branches/py3k-short-float-repr/Include/unicodeobject.h Sun Apr 5 01:04:14 2009 @@ -1482,13 +1482,24 @@ into the string pointed to by buffer. For the argument descriptions, see Objects/stringlib/localeutil.h */ -PyAPI_FUNC(int) _PyUnicode_InsertThousandsGrouping(Py_UNICODE *buffer, +PyAPI_FUNC(int) _PyUnicode_InsertThousandsGroupingLocale(Py_UNICODE *buffer, Py_ssize_t n_buffer, Py_ssize_t n_digits, Py_ssize_t buf_size, Py_ssize_t *count, int append_zero_char); +/* 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 */ +PyAPI_FUNC(int) _PyUnicode_InsertThousandsGrouping(Py_UNICODE *buffer, + Py_ssize_t n_buffer, + Py_ssize_t n_digits, + Py_ssize_t buf_size, + Py_ssize_t *count, + int append_zero_char, + const char *grouping, + const char *thousands_sep); /* === Characters Type APIs =============================================== */ /* Helper array used by Py_UNICODE_ISSPACE(). */ Modified: python/branches/py3k-short-float-repr/Lib/__future__.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/__future__.py (original) +++ python/branches/py3k-short-float-repr/Lib/__future__.py Sun Apr 5 01:04:14 2009 @@ -55,6 +55,7 @@ "with_statement", "print_function", "unicode_literals", + "barry_as_FLUFL", ] __all__ = ["all_feature_names"] + all_feature_names @@ -70,6 +71,7 @@ CO_FUTURE_WITH_STATEMENT = 0x8000 # with statement CO_FUTURE_PRINT_FUNCTION = 0x10000 # print function CO_FUTURE_UNICODE_LITERALS = 0x20000 # unicode string literals +CO_FUTURE_BARRY_AS_BDFL = 0x40000 class _Feature: def __init__(self, optionalRelease, mandatoryRelease, compiler_flag): @@ -126,3 +128,7 @@ unicode_literals = _Feature((2, 6, 0, "alpha", 2), (3, 0, 0, "alpha", 0), CO_FUTURE_UNICODE_LITERALS) + +barry_as_FLUFL = _Feature((3, 1, 0, "alpha", 2), + (3, 9, 0, "alpha", 0), + CO_FUTURE_BARRY_AS_BDFL) Modified: python/branches/py3k-short-float-repr/Lib/_abcoll.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/_abcoll.py (original) +++ python/branches/py3k-short-float-repr/Lib/_abcoll.py Sun Apr 5 01:04:14 2009 @@ -320,10 +320,9 @@ self.add(value) return self - def __iand__(self, c: Container): - for value in self: - if value not in c: - self.discard(value) + def __iand__(self, it: Iterable): + for value in (self - it): + self.discard(value) return self def __ixor__(self, it: Iterable): Modified: python/branches/py3k-short-float-repr/Lib/_pyio.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/_pyio.py (original) +++ python/branches/py3k-short-float-repr/Lib/_pyio.py Sun Apr 5 01:04:14 2009 @@ -14,6 +14,7 @@ import io from io import __all__ +from io import SEEK_SET, SEEK_CUR, SEEK_END # open() uses st_blksize whenever we can DEFAULT_BUFFER_SIZE = 8 * 1024 # bytes @@ -1696,6 +1697,7 @@ return cookie def read(self, n=None): + self._checkReadable() if n is None: n = -1 decoder = self._decoder or self._get_decoder() @@ -1827,6 +1829,10 @@ encoding="utf-8", errors="strict", newline=newline) + # Issue #5645: make universal newlines semantics the same as in the + # C version, even under Windows. + if newline is None: + self._writetranslate = False if initial_value: if not isinstance(initial_value, str): initial_value = str(initial_value) Modified: python/branches/py3k-short-float-repr/Lib/_strptime.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/_strptime.py (original) +++ python/branches/py3k-short-float-repr/Lib/_strptime.py Sun Apr 5 01:04:14 2009 @@ -262,7 +262,7 @@ def compile(self, format): """Return a compiled re object for the format string.""" - return re_compile(self.pattern(format), IGNORECASE | ASCII) + return re_compile(self.pattern(format), IGNORECASE) _cache_lock = _thread_allocate_lock() # DO NOT modify _TimeRE_cache or _regex_cache without acquiring the cache lock @@ -294,8 +294,15 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"): """Return a time struct based on the input string and the format string.""" + + for index, arg in enumerate([data_string, format]): + if not isinstance(arg, str): + msg = "strptime() argument {} must be str, not {}" + raise TypeError(msg.format(index, type(arg))) + global _TimeRE_cache, _regex_cache with _cache_lock: + if _getlang() != _TimeRE_cache.locale_time.lang: _TimeRE_cache = TimeRE() _regex_cache.clear() Modified: python/branches/py3k-short-float-repr/Lib/bisect.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/bisect.py (original) +++ python/branches/py3k-short-float-repr/Lib/bisect.py Sun Apr 5 01:04:14 2009 @@ -87,6 +87,6 @@ # Overwrite above definitions with a fast C implementation try: - from _bisect import bisect_right, bisect_left, insort_left, insort_right, insort, bisect + from _bisect import * except ImportError: pass Modified: python/branches/py3k-short-float-repr/Lib/cgitb.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/cgitb.py (original) +++ python/branches/py3k-short-float-repr/Lib/cgitb.py Sun Apr 5 01:04:14 2009 @@ -19,13 +19,19 @@ for you, call cgitb.handler(). The optional argument to handler() is a 3-item tuple (etype, evalue, etb) just like the value of sys.exc_info(). The default handler displays output as HTML. -""" - -__author__ = 'Ka-Ping Yee' - -__version__ = '$Revision$' +""" +import inspect +import keyword +import linecache +import os +import pydoc import sys +import tempfile +import time +import tokenize +import traceback +import types def reset(): """Return a string that resets the CGI and browser to a known state.""" @@ -74,7 +80,6 @@ def scanvars(reader, frame, locals): """Scan one logical line of Python and look up values of variables used.""" - import tokenize, keyword vars, lasttoken, parent, prefix, value = [], None, None, '', __UNDEF__ for ttype, token, start, end, line in tokenize.generate_tokens(reader): if ttype == tokenize.NEWLINE: break @@ -96,8 +101,6 @@ def html(einfo, context=5): """Return a nice HTML document describing a given traceback.""" - import os, time, traceback, linecache, inspect, pydoc - etype, evalue, etb = einfo if isinstance(etype, type): etype = etype.__name__ @@ -173,7 +176,6 @@ value = pydoc.html.repr(getattr(evalue, name)) exception.append('\n
%s%s =\n%s' % (indent, name, value)) - import traceback return head + ''.join(frames) + ''.join(exception) + ''' @@ -188,8 +190,6 @@ def text(einfo, context=5): """Return a plain text document describing a given traceback.""" - import os, time, traceback, linecache, inspect, pydoc - etype, evalue, etb = einfo if isinstance(etype, type): etype = etype.__name__ @@ -245,7 +245,6 @@ value = pydoc.text.repr(getattr(evalue, name)) exception.append('\n%s%s = %s' % (" "*4, name, value)) - import traceback return head + ''.join(frames) + ''.join(exception) + ''' The above is a description of an error in a Python program. Here is @@ -278,7 +277,6 @@ try: doc = formatter(info, self.context) except: # just in case something goes wrong - import traceback doc = ''.join(traceback.format_exception(*info)) plain = True @@ -292,7 +290,6 @@ self.file.write('

A problem occurred in a Python script.\n') if self.logdir is not None: - import os, tempfile suffix = ['.txt', '.html'][self.format=="html"] (fd, path) = tempfile.mkstemp(suffix=suffix, dir=self.logdir) try: Modified: python/branches/py3k-short-float-repr/Lib/collections.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/collections.py (original) +++ python/branches/py3k-short-float-repr/Lib/collections.py Sun Apr 5 01:04:14 2009 @@ -132,6 +132,9 @@ all(p==q for p, q in zip(self.items(), other.items())) return dict.__eq__(self, other) + def __ne__(self, other): + return not self == other + ################################################################################ @@ -174,7 +177,7 @@ if (not all(c.isalnum() or c=='_' for c in name) or _iskeyword(name) or not name or name[0].isdigit() or name.startswith('_') or name in seen): - names[i] = '_%d' % (i+1) + names[i] = '_%d' % i seen.add(name) field_names = tuple(names) for name in (typename,) + field_names: @@ -461,10 +464,10 @@ ''' if not isinstance(other, Counter): return NotImplemented - _max = max result = Counter() for elem in set(self) | set(other): - newcount = _max(self[elem], other[elem]) + p, q = self[elem], other[elem] + newcount = q if p < q else p if newcount > 0: result[elem] = newcount return result @@ -478,12 +481,12 @@ ''' if not isinstance(other, Counter): return NotImplemented - _min = min result = Counter() if len(self) < len(other): self, other = other, self for elem in filter(self.__contains__, other): - newcount = _min(self[elem], other[elem]) + p, q = self[elem], other[elem] + newcount = p if p < q else q if newcount > 0: result[elem] = newcount return result Modified: python/branches/py3k-short-float-repr/Lib/distutils/__init__.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/__init__.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/__init__.py Sun Apr 5 01:04:14 2009 @@ -15,5 +15,5 @@ # Updated automatically by the Python release process. # #--start constants-- -__version__ = "3.1a1" +__version__ = "3.1a2" #--end constants-- Modified: python/branches/py3k-short-float-repr/Lib/distutils/cmd.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/cmd.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/cmd.py Sun Apr 5 01:04:14 2009 @@ -333,7 +333,7 @@ # -- External world manipulation ----------------------------------- def warn(self, msg): - sys.stderr.write("warning: %s: %s\n" % (self.get_command_name(), msg)) + log.warn("warning: %s: %s\n" % (self.get_command_name(), msg)) def execute(self, func, args, msg=None, level=1): util.execute(func, args, msg, dry_run=self.dry_run) Modified: python/branches/py3k-short-float-repr/Lib/distutils/command/build_ext.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/command/build_ext.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/command/build_ext.py Sun Apr 5 01:04:14 2009 @@ -455,7 +455,13 @@ self.check_extensions_list(self.extensions) for ext in self.extensions: - self.build_extension(ext) + try: + self.build_extension(ext) + except (CCompilerError, DistutilsError, CompileError) as e: + if not ext.optional: + raise + self.warn('building extension "%s" failed: %s' % + (ext.name, e)) def build_extension(self, ext): sources = ext.sources Modified: python/branches/py3k-short-float-repr/Lib/distutils/command/install_data.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/command/install_data.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/command/install_data.py Sun Apr 5 01:04:14 2009 @@ -31,7 +31,6 @@ self.outfiles = [] self.root = None self.force = 0 - self.data_files = self.distribution.data_files self.warn_dir = 1 Modified: python/branches/py3k-short-float-repr/Lib/distutils/command/install_headers.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/command/install_headers.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/command/install_headers.py Sun Apr 5 01:04:14 2009 @@ -8,6 +8,7 @@ from distutils.core import Command +# XXX force is never used class install_headers(Command): description = "install C/C++ header files" Modified: python/branches/py3k-short-float-repr/Lib/distutils/command/register.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/command/register.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/command/register.py Sun Apr 5 01:04:14 2009 @@ -92,15 +92,14 @@ ''' url = self.repository+'?:action=list_classifiers' response = urllib.request.urlopen(url) - print(response.read()) + log.info(response.read()) def verify_metadata(self): ''' Send the metadata to the package index server to be checked. ''' # send the info to the server and report the result (code, result) = self.post_to_server(self.build_post_data('verify')) - print('Server response (%s): %s'%(code, result)) - + log.info('Server response (%s): %s' % (code, result)) def send_metadata(self): ''' Send the metadata to the package index server. @@ -211,17 +210,18 @@ data['email'] = input(' EMail: ') code, result = self.post_to_server(data) if code != 200: - print('Server response (%s): %s'%(code, result)) + log.info('Server response (%s): %s' % (code, result)) else: - print('You will receive an email shortly.') - print('Follow the instructions in it to complete registration.') + log.info('You will receive an email shortly.') + log.info(('Follow the instructions in it to ' + 'complete registration.')) elif choice == '3': data = {':action': 'password_reset'} data['email'] = '' while not data['email']: data['email'] = input('Your email address: ') code, result = self.post_to_server(data) - print('Server response (%s): %s'%(code, result)) + log.info('Server response (%s): %s' % (code, result)) def build_post_data(self, action): # figure the data to send - the metadata plus some additional @@ -254,8 +254,10 @@ def post_to_server(self, data, auth=None): ''' Post a query to the server, and return a string response. ''' - self.announce('Registering %s to %s' % (data['name'], - self.repository), log.INFO) + if 'name' in data: + self.announce('Registering %s to %s' % (data['name'], + self.repository), + log.INFO) # Build up the MIME payload for the urllib2 POST data boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' sep_boundary = '\n--' + boundary @@ -302,5 +304,6 @@ data = result.read() result = 200, 'OK' if self.show_response: - print('-'*75, data, '-'*75) + dashes = '-' * 75 + self.announce('%s%s%s' % (dashes, data, dashes)) return result Modified: python/branches/py3k-short-float-repr/Lib/distutils/command/upload.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/command/upload.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/command/upload.py Sun Apr 5 01:04:14 2009 @@ -194,4 +194,4 @@ self.announce('Upload failed (%s): %s' % (r.status, r.reason), log.ERROR) if self.show_response: - print('-'*75, r.read(), '-'*75) + self.announce('-'*75, r.read(), '-'*75) Modified: python/branches/py3k-short-float-repr/Lib/distutils/extension.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/extension.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/extension.py Sun Apr 5 01:04:14 2009 @@ -82,6 +82,9 @@ language : string extension language (i.e. "c", "c++", "objc"). Will be detected from the source extensions if not provided. + optional : boolean + specifies that a build failure in the extension should not abort the + build process, but simply not install the failing extension. """ # When adding arguments to this constructor, be sure to update @@ -100,6 +103,7 @@ swig_opts = None, depends=None, language=None, + optional=None, **kw # To catch unknown keywords ): assert isinstance(name, str), "'name' must be a string" @@ -122,6 +126,7 @@ self.swig_opts = swig_opts or [] self.depends = depends or [] self.language = language + self.optional = optional # If there are unknown keyword options, warn about them if len(kw): Modified: python/branches/py3k-short-float-repr/Lib/distutils/tests/support.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/tests/support.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/tests/support.py Sun Apr 5 01:04:14 2009 @@ -4,7 +4,7 @@ import tempfile from distutils import log - +from distutils.core import Distribution class LoggingSilencer(object): @@ -42,7 +42,7 @@ self.tempdirs.append(d) return d - def write_file(self, path, content): + def write_file(self, path, content='xxx'): """Writes a file in the given path. @@ -56,6 +56,23 @@ finally: f.close() + def create_dist(self, pkg_name='foo', **kw): + """Will generate a test environment. + + This function creates: + - a Distribution instance using keywords + - a temporary directory with a package structure + + It returns the package directory and the distribution + instance. + """ + tmp_dir = self.mkdtemp() + pkg_dir = os.path.join(tmp_dir, pkg_name) + os.mkdir(pkg_dir) + dist = Distribution(attrs=kw) + + return pkg_dir, dist + class DummyCommand: """Class to store options for retrieval via set_undefined_options().""" Modified: python/branches/py3k-short-float-repr/Lib/distutils/tests/test_build_ext.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/tests/test_build_ext.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/tests/test_build_ext.py Sun Apr 5 01:04:14 2009 @@ -8,6 +8,10 @@ from distutils.command.build_ext import build_ext from distutils import sysconfig from distutils.tests.support import TempdirManager +from distutils.tests.support import LoggingSilencer +from distutils.extension import Extension +from distutils.errors import UnknownFileError +from distutils.errors import CompileError import unittest from test import support @@ -20,7 +24,9 @@ srcdir = sysconfig.get_config_var('srcdir') return os.path.join(srcdir, 'Modules', 'xxmodule.c') -class BuildExtTestCase(TempdirManager, unittest.TestCase): +class BuildExtTestCase(TempdirManager, + LoggingSilencer, + unittest.TestCase): def setUp(self): # Create a simple test environment # Note that we're making changes to sys.path @@ -141,6 +147,23 @@ self.assert_(lib in cmd.library_dirs) self.assert_(incl in cmd.include_dirs) + def test_optional_extension(self): + + # this extension will fail, but let's ignore this failure + # with the optional argument. + modules = [Extension('foo', ['xxx'], optional=False)] + dist = Distribution({'name': 'xx', 'ext_modules': modules}) + cmd = build_ext(dist) + cmd.ensure_finalized() + self.assertRaises((UnknownFileError, CompileError), + cmd.run) # should raise an error + + modules = [Extension('foo', ['xxx'], optional=True)] + dist = Distribution({'name': 'xx', 'ext_modules': modules}) + cmd = build_ext(dist) + cmd.ensure_finalized() + cmd.run() # should pass + def test_suite(): src = _get_source_filename() if not os.path.exists(src): Modified: python/branches/py3k-short-float-repr/Lib/distutils/tests/test_config.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/tests/test_config.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/tests/test_config.py Sun Apr 5 01:04:14 2009 @@ -46,7 +46,9 @@ """ -class PyPIRCCommandTestCase(support.TempdirManager, unittest.TestCase): +class PyPIRCCommandTestCase(support.TempdirManager, + support.LoggingSilencer, + unittest.TestCase): def setUp(self): """Patches the environment.""" Modified: python/branches/py3k-short-float-repr/Lib/distutils/tests/test_msvc9compiler.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/tests/test_msvc9compiler.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/tests/test_msvc9compiler.py Sun Apr 5 01:04:14 2009 @@ -48,8 +48,8 @@ v = Reg.get_value(path, "lfitalic") self.assert_(v in (0, 1)) - import _winreg - HKCU = _winreg.HKEY_CURRENT_USER + import winreg + HKCU = winreg.HKEY_CURRENT_USER keys = Reg.read_keys(HKCU, 'xxxx') self.assertEquals(keys, None) Modified: python/branches/py3k-short-float-repr/Lib/distutils/tests/test_register.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/tests/test_register.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/tests/test_register.py Sun Apr 5 01:04:14 2009 @@ -3,7 +3,9 @@ import os import unittest import getpass +import urllib +from distutils.command import register as register_module from distutils.command.register import register from distutils.core import Distribution @@ -42,18 +44,20 @@ finally: self.index += 1 -class FakeServer(object): +class FakeOpener(object): """Fakes a PyPI server""" def __init__(self): - self.calls = [] + self.reqs = [] def __call__(self, *args): - # we want to compare them, so let's store - # something comparable - els = list(args[0].items()) - els.sort() - self.calls.append(tuple(els)) - return 200, 'OK' + return self + + def open(self, req): + self.reqs.append(req) + return self + + def read(self): + return 'xxx' class registerTestCase(PyPIRCCommandTestCase): @@ -64,24 +68,27 @@ def _getpass(prompt): return 'password' getpass.getpass = _getpass + self.old_opener = urllib.request.build_opener + self.conn = urllib.request.build_opener = FakeOpener() def tearDown(self): getpass.getpass = self._old_getpass + urllib.request.build_opener = self.old_opener PyPIRCCommandTestCase.tearDown(self) + def _get_cmd(self): + metadata = {'url': 'xxx', 'author': 'xxx', + 'author_email': 'xxx', + 'name': 'xxx', 'version': 'xxx'} + pkg_info, dist = self.create_dist(**metadata) + return register(dist) + def test_create_pypirc(self): # this test makes sure a .pypirc file # is created when requested. - # let's create a fake distribution - # and a register instance - dist = Distribution() - dist.metadata.url = 'xxx' - dist.metadata.author = 'xxx' - dist.metadata.author_email = 'xxx' - dist.metadata.name = 'xxx' - dist.metadata.version = 'xxx' - cmd = register(dist) + # let's create a register instance + cmd = self._get_cmd() # we shouldn't have a .pypirc file yet self.assert_(not os.path.exists(self.rc)) @@ -95,13 +102,12 @@ # Password : 'password' # Save your login (y/N)? : 'y' inputs = Inputs('1', 'tarek', 'y') - from distutils.command import register as register_module register_module.input = inputs.__call__ - - cmd.post_to_server = pypi_server = FakeServer() - # let's run the command - cmd.run() + try: + cmd.run() + finally: + del register_module.input # we should have a brand new .pypirc file self.assert_(os.path.exists(self.rc)) @@ -115,32 +121,68 @@ # if we run the command again def _no_way(prompt=''): raise AssertionError(prompt) - register_module.raw_input = _no_way + register_module.input = _no_way + cmd.show_response = 1 cmd.run() # let's see what the server received : we should # have 2 similar requests - self.assert_(len(pypi_server.calls), 2) - self.assert_(pypi_server.calls[0], pypi_server.calls[1]) + self.assert_(self.conn.reqs, 2) + req1 = dict(self.conn.reqs[0].headers) + req2 = dict(self.conn.reqs[1].headers) + + self.assertEquals(req1['Content-length'], '1374') + self.assertEquals(req2['Content-length'], '1374') + self.assert_((b'xxx') in self.conn.reqs[1].data) def test_password_not_in_file(self): - f = open(self.rc, 'w') - f.write(PYPIRC_NOPASSWORD) - f.close() - - dist = Distribution() - cmd = register(dist) - cmd.post_to_server = FakeServer() - + self.write_file(self.rc, PYPIRC_NOPASSWORD) + cmd = self._get_cmd() cmd._set_config() cmd.finalize_options() cmd.send_metadata() # dist.password should be set # therefore used afterwards by other commands - self.assertEquals(dist.password, 'password') + self.assertEquals(cmd.distribution.password, 'password') + + def test_registering(self): + # this test runs choice 2 + cmd = self._get_cmd() + inputs = Inputs('2', 'tarek', 'tarek at ziade.org') + register_module.input = inputs.__call__ + try: + # let's run the command + cmd.run() + finally: + del register_module.input + + # we should have send a request + self.assert_(self.conn.reqs, 1) + req = self.conn.reqs[0] + headers = dict(req.headers) + self.assertEquals(headers['Content-length'], '608') + self.assert_((b'tarek') in req.data) + + def test_password_reset(self): + # this test runs choice 3 + cmd = self._get_cmd() + inputs = Inputs('3', 'tarek at ziade.org') + register_module.input = inputs.__call__ + try: + # let's run the command + cmd.run() + finally: + del register_module.input + + # we should have send a request + self.assert_(self.conn.reqs, 1) + req = self.conn.reqs[0] + headers = dict(req.headers) + self.assertEquals(headers['Content-length'], '290') + self.assert_((b'tarek') in req.data) def test_suite(): return unittest.makeSuite(registerTestCase) Modified: python/branches/py3k-short-float-repr/Lib/distutils/tests/test_sdist.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/tests/test_sdist.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/tests/test_sdist.py Sun Apr 5 01:04:14 2009 @@ -34,7 +34,7 @@ somecode%(sep)sdoc.txt """ -class sdistTestCase(support.LoggingSilencer, PyPIRCCommandTestCase): +class sdistTestCase(PyPIRCCommandTestCase): def setUp(self): # PyPIRCCommandTestCase creates a temp dir already Modified: python/branches/py3k-short-float-repr/Lib/distutils/tests/test_upload.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/tests/test_upload.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/tests/test_upload.py Sun Apr 5 01:04:14 2009 @@ -2,6 +2,7 @@ import sys import os import unittest +import http.client as httpclient from distutils.command.upload import upload from distutils.core import Distribution @@ -18,17 +19,52 @@ [server1] username:me """ +class Response(object): + def __init__(self, status=200, reason='OK'): + self.status = status + self.reason = reason +class FakeConnection(object): + + def __init__(self): + self.requests = [] + self.headers = [] + self.body = '' + + def __call__(self, netloc): + return self + + def connect(self): + pass + endheaders = connect + + def putrequest(self, method, url): + self.requests.append((method, url)) + + def putheader(self, name, value): + self.headers.append((name, value)) + + def send(self, body): + self.body = body + + def getresponse(self): + return Response() class uploadTestCase(PyPIRCCommandTestCase): + def setUp(self): + super(uploadTestCase, self).setUp() + self.old_class = httpclient.HTTPConnection + self.conn = httpclient.HTTPConnection = FakeConnection() + + def tearDown(self): + httpclient.HTTPConnection = self.old_class + super(uploadTestCase, self).tearDown() + def test_finalize_options(self): # new format - f = open(self.rc, 'w') - f.write(PYPIRC) - f.close() - + self.write_file(self.rc, PYPIRC) dist = Distribution() cmd = upload(dist) cmd.finalize_options() @@ -39,9 +75,7 @@ def test_saved_password(self): # file with no password - f = open(self.rc, 'w') - f.write(PYPIRC_NOPASSWORD) - f.close() + self.write_file(self.rc, PYPIRC_NOPASSWORD) # make sure it passes dist = Distribution() @@ -56,6 +90,28 @@ cmd.finalize_options() self.assertEquals(cmd.password, 'xxx') + def test_upload(self): + tmp = self.mkdtemp() + path = os.path.join(tmp, 'xxx') + self.write_file(path) + command, pyversion, filename = 'xxx', '2.6', path + dist_files = [(command, pyversion, filename)] + self.write_file(self.rc, PYPIRC) + + # lets run it + pkg_dir, dist = self.create_dist(dist_files=dist_files) + cmd = upload(dist) + cmd.ensure_finalized() + cmd.run() + + # what did we send ? + headers = dict(self.conn.headers) + self.assertEquals(headers['Content-length'], '2087') + self.assert_(headers['Content-type'].startswith('multipart/form-data')) + + self.assertEquals(self.conn.requests, [('POST', '/pypi')]) + self.assert_((b'xxx') in self.conn.body) + def test_suite(): return unittest.makeSuite(uploadTestCase) Modified: python/branches/py3k-short-float-repr/Lib/distutils/util.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/util.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/util.py Sun Apr 5 01:04:14 2009 @@ -571,6 +571,39 @@ r = DistutilsRefactoringTool(fixer_names, options=options) r.refactor(files, write=True) +def copydir_run_2to3(src, dest, template=None, fixer_names=None, + options=None, explicit=None): + """Recursively copy a directory, only copying new and changed files, + running run_2to3 over all newly copied Python modules afterward. + + If you give a template string, it's parsed like a MANIFEST.in. + """ + from distutils.dir_util import mkpath + from distutils.file_util import copy_file + from distutils.filelist import FileList + filelist = FileList() + curdir = os.getcwd() + os.chdir(src) + try: + filelist.findall() + finally: + os.chdir(curdir) + filelist.files[:] = filelist.allfiles + if template: + for line in template.splitlines(): + line = line.strip() + if not line: continue + filelist.process_template_line(line) + copied = [] + for filename in filelist.files: + outname = os.path.join(dest, filename) + mkpath(os.path.dirname(outname)) + res = copy_file(os.path.join(src, filename), outname, update=1) + if res[1]: copied.append(outname) + run_2to3([fn for fn in copied if fn.lower().endswith('.py')], + fixer_names=fixer_names, options=options, explicit=explicit) + return copied + class Mixin2to3: '''Mixin class for commands that run 2to3. To configure 2to3, setup scripts may either change Modified: python/branches/py3k-short-float-repr/Lib/email/generator.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/email/generator.py (original) +++ python/branches/py3k-short-float-repr/Lib/email/generator.py Sun Apr 5 01:04:14 2009 @@ -138,7 +138,7 @@ else: # Header's got lots of smarts, so use it. header = Header(v, maxlinelen=self._maxheaderlen, - header_name=h, continuation_ws='\t') + header_name=h) print(header.encode(), file=self._fp) # A blank line always separates headers from body print(file=self._fp) Modified: python/branches/py3k-short-float-repr/Lib/email/test/test_email.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/email/test/test_email.py (original) +++ python/branches/py3k-short-float-repr/Lib/email/test/test_email.py Sun Apr 5 01:04:14 2009 @@ -769,7 +769,7 @@ msg['To'] = to eq(msg.as_string(maxheaderlen=78), '''\ To: "Someone Test #A" ,, -\t"Someone Test #B" , + "Someone Test #B" , "Someone Test #C" , "Someone Test #D" @@ -852,7 +852,7 @@ # snug against the field name. eq(msg.as_string(maxheaderlen=78), """\ Face-1:\x20 -\tiVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEUAAAAkHiJeRUIcGBi9 + iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEUAAAAkHiJeRUIcGBi9 locQDQ4zJykFBAXJfWDjAAACYUlEQVR4nF2TQY/jIAyFc6lydlG5x8Nyp1Y69wj1PN2I5gzp Face-2:\x20 iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEUAAAAkHiJeRUIcGBi9 Modified: python/branches/py3k-short-float-repr/Lib/email/test/test_email_codecs.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/email/test/test_email_codecs.py (original) +++ python/branches/py3k-short-float-repr/Lib/email/test/test_email_codecs.py Sun Apr 5 01:04:14 2009 @@ -6,9 +6,9 @@ from test.support import run_unittest from email.test.test_email import TestEmailBase -from email.Charset import Charset -from email.Header import Header, decode_header -from email.Message import Message +from email.charset import Charset +from email.header import Header, decode_header +from email.message import Message # We're compatible with Python 2.3, but it doesn't have the built-in Asian # codecs, so we have to skip all these tests. Deleted: python/branches/py3k-short-float-repr/Lib/email/test/test_email_codecs_renamed.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/email/test/test_email_codecs_renamed.py Sun Apr 5 01:04:14 2009 +++ (empty file) @@ -1,77 +0,0 @@ -# Copyright (C) 2002-2006 Python Software Foundation -# Contact: email-sig at python.org -# email package unit tests for (optional) Asian codecs - -import unittest -from test.support import run_unittest - -from email.test.test_email import TestEmailBase -from email.charset import Charset -from email.header import Header, decode_header -from email.message import Message - -# We're compatible with Python 2.3, but it doesn't have the built-in Asian -# codecs, so we have to skip all these tests. -try: - str('foo', 'euc-jp') -except LookupError: - raise unittest.SkipTest - - - -class TestEmailAsianCodecs(TestEmailBase): - def test_japanese_codecs(self): - eq = self.ndiffAssertEqual - j = Charset("euc-jp") - g = Charset("iso-8859-1") - h = Header("Hello World!") - jhello = '\xa5\xcf\xa5\xed\xa1\xbc\xa5\xef\xa1\xbc\xa5\xeb\xa5\xc9\xa1\xaa' - ghello = 'Gr\xfc\xdf Gott!' - h.append(jhello, j) - h.append(ghello, g) - # BAW: This used to -- and maybe should -- fold the two iso-8859-1 - # chunks into a single encoded word. However it doesn't violate the - # standard to have them as two encoded chunks and maybe it's - # reasonable for each .append() call to result in a separate - # encoded word. - eq(h.encode(), """\ -Hello World! =?iso-2022-jp?b?GyRCJU8lbSE8JW8hPCVrJUkhKhsoQg==?= - =?iso-8859-1?q?Gr=FC=DF?= =?iso-8859-1?q?_Gott!?=""") - eq(decode_header(h.encode()), - [('Hello World!', None), - ('\x1b$B%O%m!<%o!<%k%I!*\x1b(B', 'iso-2022-jp'), - ('Gr\xfc\xdf Gott!', 'iso-8859-1')]) - int = 'test-ja \xa4\xd8\xc5\xea\xb9\xc6\xa4\xb5\xa4\xec\xa4\xbf\xa5\xe1\xa1\xbc\xa5\xeb\xa4\xcf\xbb\xca\xb2\xf1\xbc\xd4\xa4\xce\xbe\xb5\xc7\xa7\xa4\xf2\xc2\xd4\xa4\xc3\xa4\xc6\xa4\xa4\xa4\xde\xa4\xb9' - h = Header(int, j, header_name="Subject") - # test a very long header - enc = h.encode() - # TK: splitting point may differ by codec design and/or Header encoding - eq(enc , """\ -=?iso-2022-jp?b?dGVzdC1qYSAbJEIkWEVqOUYkNSRsJD8lYSE8JWskTztKGyhC?= - =?iso-2022-jp?b?GyRCMnE8VCROPjVHJyRyQlQkQyRGJCQkXiQ5GyhC?=""") - # TK: full decode comparison - eq(h.__unicode__().encode('euc-jp'), int) - - def test_payload_encoding(self): - jhello = '\xa5\xcf\xa5\xed\xa1\xbc\xa5\xef\xa1\xbc\xa5\xeb\xa5\xc9\xa1\xaa' - jcode = 'euc-jp' - msg = Message() - msg.set_payload(jhello, jcode) - ustr = str(msg.get_payload(), msg.get_content_charset()) - self.assertEqual(jhello, ustr.encode(jcode)) - - - -def suite(): - suite = unittest.TestSuite() - suite.addTest(unittest.makeSuite(TestEmailAsianCodecs)) - return suite - - -def test_main(): - run_unittest(TestEmailAsianCodecs) - - - -if __name__ == '__main__': - unittest.main(defaultTest='suite') Modified: python/branches/py3k-short-float-repr/Lib/http/client.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/http/client.py (original) +++ python/branches/py3k-short-float-repr/Lib/http/client.py Sun Apr 5 01:04:14 2009 @@ -204,6 +204,12 @@ MAXAMOUNT = 1048576 class HTTPMessage(email.message.Message): + # XXX The only usage of this method is in + # http.server.CGIHTTPRequestHandler. Maybe move the code there so + # that it doesn't need to be part of the public API. The API has + # never been defined so this could cause backwards compatibility + # issues. + def getallmatchingheaders(self, name): """Find all header lines matching a given header name. @@ -261,20 +267,26 @@ # text following RFC 2047. The basic status line parsing only # accepts iso-8859-1. - def __init__(self, sock, debuglevel=0, strict=0, method=None): - # If the response includes a content-length header, we - # need to make sure that the client doesn't read more than the + def __init__(self, sock, debuglevel=0, strict=0, method=None, url=None): + # If the response includes a content-length header, we need to + # make sure that the client doesn't read more than the # specified number of bytes. If it does, it will block until - # the server times out and closes the connection. (The only - # applies to HTTP/1.1 connections.) This will happen if a self.fp.read() - # is done (without a size) whether self.fp is buffered or not. - # So, no self.fp.read() by clients unless they know what they are doing. + # the server times out and closes the connection. This will + # happen if a self.fp.read() is done (without a size) whether + # self.fp is buffered or not. So, no self.fp.read() by + # clients unless they know what they are doing. self.fp = sock.makefile("rb") self.debuglevel = debuglevel self.strict = strict self._method = method - self.msg = None + # The HTTPResponse object is returned via urllib. The clients + # of http and urllib expect different attributes for the + # headers. headers is used here and supports urllib. msg is + # provided as a backwards compatibility layer for http + # clients. + + self.headers = self.msg = None # from the Status-Line of the response self.version = _UNKNOWN # HTTP-Version @@ -326,7 +338,7 @@ return version, status, reason def begin(self): - if self.msg is not None: + if self.headers is not None: # we've already started reading the response return @@ -343,7 +355,7 @@ if self.debuglevel > 0: print("header:", skip) - self.status = status + self.code = self.status = status self.reason = reason.strip() if version == "HTTP/1.0": self.version = 10 @@ -358,17 +370,17 @@ self.length = None self.chunked = False self.will_close = True - self.msg = email.message_from_string('') + self.headers = self.msg = email.message_from_string('') return - self.msg = parse_headers(self.fp) + self.headers = self.msg = parse_headers(self.fp) if self.debuglevel > 0: - for hdr in self.msg: + for hdr in self.headers: print("header:", hdr, end=" ") # are we using the chunked-style of transfer encoding? - tr_enc = self.msg.get("transfer-encoding") + tr_enc = self.headers.get("transfer-encoding") if tr_enc and tr_enc.lower() == "chunked": self.chunked = True self.chunk_left = None @@ -381,10 +393,10 @@ # do we have a Content-Length? # NOTE: RFC 2616, S4.4, #3 says we ignore this if tr_enc is "chunked" self.length = None - length = self.msg.get("content-length") + length = self.headers.get("content-length") # are we using the chunked-style of transfer encoding? - tr_enc = self.msg.get("transfer-encoding") + tr_enc = self.headers.get("transfer-encoding") if length and not self.chunked: try: self.length = int(length) @@ -411,11 +423,11 @@ self.will_close = True def _check_close(self): - conn = self.msg.get("connection") + conn = self.headers.get("connection") if self.version == 11: # An HTTP/1.1 proxy is assumed to stay open unless # explicitly closed. - conn = self.msg.get("connection") + conn = self.headers.get("connection") if conn and "close" in conn.lower(): return True return False @@ -424,7 +436,7 @@ # connections, using rules different than HTTP/1.1. # For older HTTP, Keep-Alive indicates persistent connection. - if self.msg.get("keep-alive"): + if self.headers.get("keep-alive"): return False # At least Akamai returns a "Connection: Keep-Alive" header, @@ -433,7 +445,7 @@ return False # Proxy-Connection is a netscape hack. - pconn = self.msg.get("proxy-connection") + pconn = self.headers.get("proxy-connection") if pconn and "keep-alive" in pconn.lower(): return False @@ -457,6 +469,9 @@ def flush(self): self.fp.flush() + def readable(self): + return True + # End of "raw stream" methods def isclosed(self): @@ -584,21 +599,31 @@ return self.fp.fileno() def getheader(self, name, default=None): - if self.msg is None: + if self.headers is None: raise ResponseNotReady() - return ', '.join(self.msg.get_all(name, default)) + return ', '.join(self.headers.get_all(name, default)) def getheaders(self): """Return list of (header, value) tuples.""" - if self.msg is None: + if self.headers is None: raise ResponseNotReady() - return list(self.msg.items()) + return list(self.headers.items()) # We override IOBase.__iter__ so that it doesn't check for closed-ness def __iter__(self): return self + # For compatibility with old-style urllib responses. + + def info(self): + return self.headers + + def geturl(self): + return self.url + + def getcode(self): + return self.status class HTTPConnection: @@ -757,7 +782,7 @@ if self.__state == _CS_IDLE: self.__state = _CS_REQ_STARTED else: - raise CannotSendRequest() + raise CannotSendRequest(self.__state) # Save the method we use, we need it later in the response phase self._method = method @@ -906,13 +931,23 @@ self.endheaders(body) def getresponse(self): - """Get the response from the server.""" + """Get the response from the server. + + If the HTTPConnection is in the correct state, returns an + instance of HTTPResponse or of whatever object is returned by + class the response_class variable. + + If a request has not been sent or if a previous response has + not be handled, ResponseNotReady is raised. If the HTTP + response indicates that the connection should be closed, then + it will be closed before the response is returned. When the + connection is closed, the underlying socket is closed. + """ # if a prior response has been completed, then forget about it. if self.__response and self.__response.isclosed(): self.__response = None - # # if a prior response exists, then it must be completed (otherwise, we # cannot read this response's header to determine the connection-close # behavior) @@ -929,7 +964,7 @@ # isclosed() status to become true. # if self.__state != _CS_REQ_SENT or self.__response: - raise ResponseNotReady() + raise ResponseNotReady(self.__state) if self.debuglevel > 0: response = self.response_class(self.sock, self.debuglevel, Modified: python/branches/py3k-short-float-repr/Lib/http/cookies.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/http/cookies.py (original) +++ python/branches/py3k-short-float-repr/Lib/http/cookies.py Sun Apr 5 01:04:14 2009 @@ -392,7 +392,7 @@ document.cookie = \"%s\"; // end hiding --> - """ % ( self.OutputString(attrs), ) + """ % ( self.OutputString(attrs).replace('"',r'\"')) # end js_output() def OutputString(self, attrs=None): Modified: python/branches/py3k-short-float-repr/Lib/http/server.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/http/server.py (original) +++ python/branches/py3k-short-float-repr/Lib/http/server.py Sun Apr 5 01:04:14 2009 @@ -1082,10 +1082,12 @@ sa = httpd.socket.getsockname() print("Serving HTTP on", sa[0], "port", sa[1], "...") - httpd.serve_forever() - + try: + httpd.serve_forever() + except KeyboardInterrupt: + print("\nKeyboard interrupt received, exiting.") + httpd.server_close() + sys.exit(0) if __name__ == '__main__': - test(HandlerClass=BaseHTTPRequestHandler) test(HandlerClass=SimpleHTTPRequestHandler) - test(HandlerClass=CGIHTTPRequestHandler) Modified: python/branches/py3k-short-float-repr/Lib/idlelib/EditorWindow.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/idlelib/EditorWindow.py (original) +++ python/branches/py3k-short-float-repr/Lib/idlelib/EditorWindow.py Sun Apr 5 01:04:14 2009 @@ -107,10 +107,18 @@ self.text_frame = text_frame = Frame(top) self.vbar = vbar = Scrollbar(text_frame, name='vbar') self.width = idleConf.GetOption('main','EditorWindow','width') - self.text = text = MultiCallCreator(Text)( - text_frame, name='text', padx=5, wrap='none', - width=self.width, - height=idleConf.GetOption('main','EditorWindow','height') ) + text_options = { + 'name': 'text', + 'padx': 5, + 'wrap': 'none', + 'width': self.width, + 'height': idleConf.GetOption('main', 'EditorWindow', 'height')} + if TkVersion >= 8.5: + # Starting with tk 8.5 we have to set the new tabstyle option + # to 'wordprocessor' to achieve the same display of tabs as in + # older tk versions. + text_options['tabstyle'] = 'wordprocessor' + self.text = text = MultiCallCreator(Text)(text_frame, **text_options) self.top.focused_widget = self.text self.createmenubar() Modified: python/branches/py3k-short-float-repr/Lib/idlelib/NEWS.txt ============================================================================== --- python/branches/py3k-short-float-repr/Lib/idlelib/NEWS.txt (original) +++ python/branches/py3k-short-float-repr/Lib/idlelib/NEWS.txt Sun Apr 5 01:04:14 2009 @@ -3,6 +3,16 @@ *Release date: XX-XXX-XXXX* +- Allow multiple IDLE GUI/subprocess pairs to exist simultaneously. Thanks to + David Scherer for suggesting the use of an ephemeral port for the GUI. + Patch 1529142 Weeble. + +- Remove port spec from run.py and fix bug where subprocess fails to + extract port from command line when warnings are present. + +- Tk 8.5 Text widget requires 'wordprocessor' tabstyle attr to handle + mixed space/tab properly. Issue 5120, patch by Guilherme Polo. + - Issue #4815: Offer conversion to UTF-8 if source files have no encoding declaration and are not encoded in UTF-8. Modified: python/branches/py3k-short-float-repr/Lib/idlelib/PyShell.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/idlelib/PyShell.py (original) +++ python/branches/py3k-short-float-repr/Lib/idlelib/PyShell.py Sun Apr 5 01:04:14 2009 @@ -34,7 +34,8 @@ from idlelib import RemoteDebugger from idlelib import macosxSupport -LOCALHOST = '127.0.0.1' +HOST = '127.0.0.1' # python execution server on localhost loopback +PORT = 0 # someday pass in host, port for remote debug capability try: from signal import SIGTERM @@ -339,17 +340,21 @@ InteractiveInterpreter.__init__(self, locals=locals) self.save_warnings_filters = None self.restarting = False - self.subprocess_arglist = self.build_subprocess_arglist() + self.subprocess_arglist = None + self.port = PORT - port = 8833 rpcclt = None rpcpid = None def spawn_subprocess(self): + if self.subprocess_arglist == None: + self.subprocess_arglist = self.build_subprocess_arglist() args = self.subprocess_arglist self.rpcpid = os.spawnv(os.P_NOWAIT, sys.executable, args) def build_subprocess_arglist(self): + assert (self.port!=0), ( + "Socket should have been assigned a port number.") w = ['-W' + s for s in sys.warnoptions] # Maybe IDLE is installed and is being accessed via sys.path, # or maybe it's not installed and the idle.py script is being @@ -368,11 +373,8 @@ return [decorated_exec] + w + ["-c", command, str(self.port)] def start_subprocess(self): - # spawning first avoids passing a listening socket to the subprocess - self.spawn_subprocess() - #time.sleep(20) # test to simulate GUI not accepting connection - addr = (LOCALHOST, self.port) - # Idle starts listening for connection on localhost + addr = (HOST, self.port) + # GUI makes several attempts to acquire socket, listens for connection for i in range(3): time.sleep(i) try: @@ -383,6 +385,18 @@ else: self.display_port_binding_error() return None + # if PORT was 0, system will assign an 'ephemeral' port. Find it out: + self.port = self.rpcclt.listening_sock.getsockname()[1] + # if PORT was not 0, probably working with a remote execution server + if PORT != 0: + # To allow reconnection within the 2MSL wait (cf. Stevens TCP + # V1, 18.6), set SO_REUSEADDR. Note that this can be problematic + # on Windows since the implementation allows two active sockets on + # the same address! + self.rpcclt.listening_sock.setsockopt(socket.SOL_SOCKET, + socket.SO_REUSEADDR, 1) + self.spawn_subprocess() + #time.sleep(20) # test to simulate GUI not accepting connection # Accept the connection from the Python execution server self.rpcclt.listening_sock.settimeout(10) try: @@ -734,13 +748,12 @@ def display_port_binding_error(self): tkMessageBox.showerror( "Port Binding Error", - "IDLE can't bind TCP/IP port 8833, which is necessary to " - "communicate with its Python execution server. Either " - "no networking is installed on this computer or another " - "process (another IDLE?) is using the port. Run IDLE with the -n " - "command line switch to start without a subprocess and refer to " - "Help/IDLE Help 'Running without a subprocess' for further " - "details.", + "IDLE can't bind to a TCP/IP port, which is necessary to " + "communicate with its Python execution server. This might be " + "because no networking is installed on this computer. " + "Run IDLE with the -n command line switch to start without a " + "subprocess and refer to Help/IDLE Help 'Running without a " + "subprocess' for further details.", master=self.tkconsole.text) def display_no_subprocess_error(self): @@ -1285,7 +1298,7 @@ global flist, root, use_subprocess use_subprocess = True - enable_shell = False + enable_shell = True enable_edit = False debug = False cmd = None @@ -1306,6 +1319,7 @@ enable_shell = True if o == '-e': enable_edit = True + enable_shell = False if o == '-h': sys.stdout.write(usage_msg) sys.exit() @@ -1356,7 +1370,6 @@ edit_start = idleConf.GetOption('main', 'General', 'editor-on-startup', type='bool') enable_edit = enable_edit or edit_start - enable_shell = enable_shell or not edit_start # start editor and/or shell windows: root = Tk(className="Idle") Modified: python/branches/py3k-short-float-repr/Lib/idlelib/idlever.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/idlelib/idlever.py (original) +++ python/branches/py3k-short-float-repr/Lib/idlelib/idlever.py Sun Apr 5 01:04:14 2009 @@ -1 +1 @@ -IDLE_VERSION = "3.1a1" +IDLE_VERSION = "3.1a2" Modified: python/branches/py3k-short-float-repr/Lib/idlelib/rpc.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/idlelib/rpc.py (original) +++ python/branches/py3k-short-float-repr/Lib/idlelib/rpc.py Sun Apr 5 01:04:14 2009 @@ -518,8 +518,6 @@ def __init__(self, address, family=socket.AF_INET, type=socket.SOCK_STREAM): self.listening_sock = socket.socket(family, type) - self.listening_sock.setsockopt(socket.SOL_SOCKET, - socket.SO_REUSEADDR, 1) self.listening_sock.bind(address) self.listening_sock.listen(1) Modified: python/branches/py3k-short-float-repr/Lib/idlelib/run.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/idlelib/run.py (original) +++ python/branches/py3k-short-float-repr/Lib/idlelib/run.py Sun Apr 5 01:04:14 2009 @@ -67,10 +67,14 @@ global quitting global no_exitfunc no_exitfunc = del_exitfunc - port = 8833 #time.sleep(15) # test subprocess not responding - if sys.argv[1:]: - port = int(sys.argv[1]) + try: + assert(len(sys.argv) > 1) + port = int(sys.argv[-1]) + except: + print("IDLE Subprocess: no IP port passed in sys.argv.", + file=sys.__stderr__) + return sys.argv[:] = [""] sockthread = threading.Thread(target=manage_socket, name='SockThread', Modified: python/branches/py3k-short-float-repr/Lib/importlib/_bootstrap.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/importlib/_bootstrap.py (original) +++ python/branches/py3k-short-float-repr/Lib/importlib/_bootstrap.py Sun Apr 5 01:04:14 2009 @@ -475,25 +475,6 @@ # Not a property so that it is easy to override. return self._find_path(imp.PY_SOURCE) - @_check_name - def get_source(self, fullname): - """Return the source for the module as a string. - - Return None if the source is not available. Raise ImportError if the - laoder cannot handle the specified module. - - """ - source_path = self._source_path(name) - if source_path is None: - return None - import tokenize - with _closing(_io.FileIO(source_path, 'r')) as file: # Assuming bytes. - encoding, lines = tokenize.detect_encoding(file.readline) - # XXX Will fail when passed to compile() if the encoding is - # anything other than UTF-8. - return open(source_path, encoding=encoding).read() - - def get_data(self, path): """Return the data from path as raw bytes.""" return _io.FileIO(path, 'r').read() # Assuming bytes. @@ -661,9 +642,10 @@ finder = cls._path_importer_cache(entry) except ImportError: continue - loader = finder.find_module(fullname) - if loader: - return loader + if finder: + loader = finder.find_module(fullname) + if loader: + return loader else: return None Modified: python/branches/py3k-short-float-repr/Lib/importlib/test/import_/test_path.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/importlib/test/import_/test_path.py (original) +++ python/branches/py3k-short-float-repr/Lib/importlib/test/import_/test_path.py Sun Apr 5 01:04:14 2009 @@ -55,6 +55,25 @@ self.assert_(path in sys.path_importer_cache) self.assert_(sys.path_importer_cache[path] is importer) + def test_path_importer_cache_has_None(self): + # Test that if sys.path_importer_cache has None that None is returned. + clear_cache = {path: None for path in sys.path} + with util.import_state(path_importer_cache=clear_cache): + for name in ('asynchat', 'sys', ''): + self.assert_(machinery.PathFinder.find_module(name) is None) + + def test_path_importer_cache_has_None_continues(self): + # Test that having None in sys.path_importer_cache causes the search to + # continue. + path = '' + module = '' + importer = util.mock_modules(module) + with util.import_state(path=['1', '2'], + path_importer_cache={'1': None, '2': importer}): + loader = machinery.PathFinder.find_module(module) + self.assert_(loader is importer) + + class DefaultPathFinderTests(unittest.TestCase): Modified: python/branches/py3k-short-float-repr/Lib/importlib/test/source/test_abc_loader.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/importlib/test/source/test_abc_loader.py (original) +++ python/branches/py3k-short-float-repr/Lib/importlib/test/source/test_abc_loader.py Sun Apr 5 01:04:14 2009 @@ -123,11 +123,13 @@ def eq_attrs(self, ob, **kwargs): for attr, val in kwargs.items(): - self.assertEqual(getattr(ob, attr), val) + found = getattr(ob, attr) + self.assertEqual(found, val, + "{} attribute: {} != {}".format(attr, found, val)) def test_module(self): name = '' - path = 'path/to/module' + path = os.path.join('', 'path', 'to', 'module') mock = self.mocker({name: path}) with util.uncache(name): module = mock.load_module(name) @@ -139,7 +141,7 @@ def test_package(self): name = '' - path = '/path/to//__init__' + path = os.path.join('path', 'to', name, '__init__') mock = self.mocker({name: path}) with util.uncache(name): module = mock.load_module(name) @@ -151,7 +153,7 @@ def test_lacking_parent(self): name = 'pkg.mod' - path = 'path/to/pkg/mod' + path = os.path.join('path', 'to', 'pkg', 'mod') mock = self.mocker({name: path}) with util.uncache(name): module = mock.load_module(name) @@ -163,7 +165,7 @@ def test_module_reuse(self): name = 'mod' - path = 'path/to/mod' + path = os.path.join('path', 'to', 'mod') module = imp.new_module(name) mock = self.mocker({name: path}) with util.uncache(name): @@ -177,7 +179,7 @@ name = "mod" module = imp.new_module(name) module.blah = None - mock = self.mocker({name: 'path/to/mod'}) + mock = self.mocker({name: os.path.join('path', 'to', 'mod')}) mock.source = b"1/0" with util.uncache(name): sys.modules[name] = module @@ -188,7 +190,7 @@ def test_unloadable(self): name = "mod" - mock = self.mocker({name: 'path/to/mod'}) + mock = self.mocker({name: os.path.join('path', 'to', 'mod')}) mock.source = b"1/0" with util.uncache(name): self.assertRaises(ZeroDivisionError, mock.load_module, name) @@ -222,7 +224,7 @@ def test_default_encoding(self): # Should have no problems with UTF-8 text. name = 'mod' - mock = PyLoaderMock({name: 'path/to/mod'}) + mock = PyLoaderMock({name: os.path.join('path', 'to', 'mod')}) source = 'x = "??"' mock.source = source.encode('utf-8') returned_source = mock.get_source(name) @@ -231,7 +233,7 @@ def test_decoded_source(self): # Decoding should work. name = 'mod' - mock = PyLoaderMock({name: 'path/to/mod'}) + mock = PyLoaderMock({name: os.path.join('path', 'to', 'mod')}) source = "# coding: Latin-1\nx='??'" assert source.encode('latin-1') != source.encode('utf-8') mock.source = source.encode('latin-1') @@ -287,7 +289,7 @@ @source_util.writes_bytecode def run_test(self, dont_write_bytecode): name = 'mod' - mock = PyPycLoaderMock({name: 'path/to/mod'}) + mock = PyPycLoaderMock({name: os.path.join('path', 'to', 'mod')}) sys.dont_write_bytecode = dont_write_bytecode with util.uncache(name): mock.load_module(name) @@ -311,8 +313,9 @@ name = 'mod' bad_magic = b'\x00\x00\x00\x00' assert bad_magic != imp.get_magic() - mock = PyPycLoaderMock({name: 'path/to/mod'}, - {name: {'path': 'path/to/mod.bytecode', + mock = PyPycLoaderMock({name: os.path.join('path', 'to', 'mod')}, + {name: {'path': os.path.join('path', 'to', + 'mod.bytecode'), 'magic': bad_magic}}) with util.uncache(name): mock.load_module(name) @@ -325,7 +328,7 @@ # Bytecode with an older mtime should be regenerated. name = 'mod' old_mtime = PyPycLoaderMock.default_mtime - 1 - mock = PyPycLoaderMock({name: 'path/to/mod'}, + mock = PyPycLoaderMock({name: os.path.join('path', 'to', 'mod')}, {name: {'path': 'path/to/mod.bytecode', 'mtime': old_mtime}}) with util.uncache(name): mock.load_module(name) @@ -343,7 +346,8 @@ # A bad magic number should lead to an ImportError. name = 'mod' bad_magic = b'\x00\x00\x00\x00' - mock = PyPycLoaderMock({}, {name: {'path': 'path/to/mod', + mock = PyPycLoaderMock({}, {name: {'path': os.path.join('path', 'to', + 'mod'), 'magic': bad_magic}}) with util.uncache(name): self.assertRaises(ImportError, mock.load_module, name) @@ -351,7 +355,9 @@ def test_bad_bytecode(self): # Bad code object bytecode should elad to an ImportError. name = 'mod' - mock = PyPycLoaderMock({}, {name: {'path': '/path/to/mod', 'bc': b''}}) + mock = PyPycLoaderMock({}, {name: {'path': os.path.join('path', 'to', + 'mod'), + 'bc': b''}}) with util.uncache(name): self.assertRaises(ImportError, mock.load_module, name) @@ -387,14 +393,15 @@ def test_source_path_ImportError(self): # An ImportError from source_path should trigger an ImportError. name = 'mod' - mock = PyPycLoaderMock({}, {name: {'path': 'path/to/mod'}}) + mock = PyPycLoaderMock({}, {name: {'path': os.path.join('path', 'to', + 'mod')}}) with util.uncache(name): self.assertRaises(ImportError, mock.load_module, name) def test_bytecode_path_ImportError(self): # An ImportError from bytecode_path should trigger an ImportError. name = 'mod' - mock = PyPycLoaderMock({name: 'path/to/mod'}) + mock = PyPycLoaderMock({name: os.path.join('path', 'to', 'mod')}) bad_meth = types.MethodType(raise_ImportError, mock) mock.bytecode_path = bad_meth with util.uncache(name): Modified: python/branches/py3k-short-float-repr/Lib/importlib/test/util.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/importlib/test/util.py (original) +++ python/branches/py3k-short-float-repr/Lib/importlib/test/util.py Sun Apr 5 01:04:14 2009 @@ -1,7 +1,7 @@ from contextlib import contextmanager import imp import os.path -from test.support import unlink +from test import support import unittest import sys @@ -10,6 +10,13 @@ """Class decorator that nullifies tests that require a case-insensitive file system.""" if sys.platform not in ('win32', 'darwin', 'cygwin'): + original_name = os.listdir('.')[0] + if original_name.upper() != original_name: + changed_name = original_name.upper() + else: + changed_name = original_name.lower() + if os.path.exists(changed_name): + return class_ return unittest.TestCase else: return class_ Modified: python/branches/py3k-short-float-repr/Lib/io.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/io.py (original) +++ python/branches/py3k-short-float-repr/Lib/io.py Sun Apr 5 01:04:14 2009 @@ -52,7 +52,8 @@ __all__ = ["BlockingIOError", "open", "IOBase", "RawIOBase", "FileIO", "BytesIO", "StringIO", "BufferedIOBase", "BufferedReader", "BufferedWriter", "BufferedRWPair", - "BufferedRandom", "TextIOBase", "TextIOWrapper"] + "BufferedRandom", "TextIOBase", "TextIOWrapper", + "SEEK_SET", "SEEK_CUR", "SEEK_END"] import _io @@ -65,6 +66,11 @@ OpenWrapper = _io.open # for compatibility with _pyio +# for seek() +SEEK_SET = 0 +SEEK_CUR = 1 +SEEK_END = 2 + # Declaring ABCs in C is tricky so we do it here. # Method descriptions and default implementations are inherited from the C # version however. Modified: python/branches/py3k-short-float-repr/Lib/locale.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/locale.py (original) +++ python/branches/py3k-short-float-repr/Lib/locale.py Sun Apr 5 01:04:14 2009 @@ -11,7 +11,11 @@ """ -import sys, encodings, encodings.aliases +import sys +import encodings +import encodings.aliases +import re +import collections from builtins import str as _builtin_str import functools @@ -173,6 +177,9 @@ amount -= 1 return s[lpos:rpos+1] +_percent_re = re.compile(r'%(?:\((?P.*?)\))?' + r'(?P[-#0-9 +*.hlL]*?)[eEfFgGdiouxXcrs%]') + def format(percent, value, grouping=False, monetary=False, *additional): """Returns the locale-aware substitution of a %? specifier (percent). @@ -180,9 +187,13 @@ additional is for format strings which contain one or more '*' modifiers.""" # this is only for one-percent-specifier strings and this should be checked - if percent[0] != '%': - raise ValueError("format() must be given exactly one %char " - "format specifier") + match = _percent_re.match(percent) + if not match or len(match.group())!= len(percent): + raise ValueError(("format() must be given exactly one %%char " + "format specifier, %s not valid") % repr(percent)) + return _format(percent, value, grouping, monetary, *additional) + +def _format(percent, value, grouping=False, monetary=False, *additional): if additional: formatted = percent % ((value,) + additional) else: @@ -206,10 +217,6 @@ formatted = _strip_padding(formatted, seps) return formatted -import re, collections -_percent_re = re.compile(r'%(?:\((?P.*?)\))?' - r'(?P[-#0-9 +*.hlL]*?)[eEfFgGdiouxXcrs%]') - def format_string(f, val, grouping=False): """Formats a string in the same way that the % formatting would use, but takes the current locale into account. Modified: python/branches/py3k-short-float-repr/Lib/mailbox.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/mailbox.py (original) +++ python/branches/py3k-short-float-repr/Lib/mailbox.py Sun Apr 5 01:04:14 2009 @@ -907,7 +907,7 @@ _unlock_file(f) finally: f.close() - for name, key_list in self.get_sequences(): + for name, key_list in self.get_sequences().items(): if key in key_list: msg.add_sequence(name) return msg Modified: python/branches/py3k-short-float-repr/Lib/multiprocessing/queues.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/multiprocessing/queues.py (original) +++ python/branches/py3k-short-float-repr/Lib/multiprocessing/queues.py Sun Apr 5 01:04:14 2009 @@ -6,7 +6,7 @@ # Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt # -__all__ = ['Queue', 'SimpleQueue'] +__all__ = ['Queue', 'SimpleQueue', 'JoinableQueue'] import sys import os Modified: python/branches/py3k-short-float-repr/Lib/site.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/site.py (original) +++ python/branches/py3k-short-float-repr/Lib/site.py Sun Apr 5 01:04:14 2009 @@ -268,13 +268,15 @@ if sys.platform == "darwin": # for framework builds *only* we add the standard Apple - # locations. Currently only per-user, but /Library and - # /Network/Library could be added too + # locations. if 'Python.framework' in prefix: sitedirs.append( os.path.expanduser( os.path.join("~", "Library", "Python", sys.version[:3], "site-packages"))) + sitedirs.append( + os.path.join("/Library", "Python", + sys.version[:3], "site-packages")) for sitedir in sitedirs: if os.path.isdir(sitedir): Modified: python/branches/py3k-short-float-repr/Lib/symtable.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/symtable.py (original) +++ python/branches/py3k-short-float-repr/Lib/symtable.py Sun Apr 5 01:04:14 2009 @@ -191,6 +191,9 @@ def is_global(self): return bool(self.__scope in (GLOBAL_IMPLICIT, GLOBAL_EXPLICIT)) + def is_declared_global(self): + return bool(self.__scope == GLOBAL_EXPLICIT) + def is_local(self): return bool(self.__flags & DEF_BOUND) Modified: python/branches/py3k-short-float-repr/Lib/test/buffer_tests.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/buffer_tests.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/buffer_tests.py Sun Apr 5 01:04:14 2009 @@ -112,7 +112,7 @@ self.assertEqual(b'abc ', self.marshal(b'abc').ljust(6)) self.assertEqual(b'abc', self.marshal(b'abc').ljust(3)) self.assertEqual(b'abc', self.marshal(b'abc').ljust(2)) - self.assertEqual(b'abc*******', self.marshal(b'abc').ljust(10, '*')) + self.assertEqual(b'abc*******', self.marshal(b'abc').ljust(10, b'*')) self.assertRaises(TypeError, self.marshal(b'abc').ljust) def test_rjust(self): @@ -120,7 +120,7 @@ self.assertEqual(b' abc', self.marshal(b'abc').rjust(6)) self.assertEqual(b'abc', self.marshal(b'abc').rjust(3)) self.assertEqual(b'abc', self.marshal(b'abc').rjust(2)) - self.assertEqual(b'*******abc', self.marshal(b'abc').rjust(10, '*')) + self.assertEqual(b'*******abc', self.marshal(b'abc').rjust(10, b'*')) self.assertRaises(TypeError, self.marshal(b'abc').rjust) def test_center(self): @@ -128,7 +128,7 @@ self.assertEqual(b' abc ', self.marshal(b'abc').center(6)) self.assertEqual(b'abc', self.marshal(b'abc').center(3)) self.assertEqual(b'abc', self.marshal(b'abc').center(2)) - self.assertEqual(b'***abc****', self.marshal(b'abc').center(10, '*')) + self.assertEqual(b'***abc****', self.marshal(b'abc').center(10, b'*')) self.assertRaises(TypeError, self.marshal(b'abc').center) def test_swapcase(self): Modified: python/branches/py3k-short-float-repr/Lib/test/regrtest.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/regrtest.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/regrtest.py Sun Apr 5 01:04:14 2009 @@ -404,8 +404,9 @@ print("Using random seed", random_seed) random.shuffle(tests) if trace: - import trace - tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix], + import trace, tempfile + tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix, + tempfile.gettempdir()], trace=False, count=True) test_times = [] support.verbose = verbose # Tell tests to be moderately quiet @@ -628,7 +629,7 @@ print(test, "skipped --", msg) sys.stdout.flush() return -2 - except (ImportError, unittest.SkipTest) as msg: + except unittest.SkipTest as msg: if not quiet: print(test, "skipped --", msg) sys.stdout.flush() @@ -892,6 +893,7 @@ test_fork1 test_epoll test_dbm_gnu + test_dbm_ndbm test_grp test_ioctl test_largefile Modified: python/branches/py3k-short-float-repr/Lib/test/support.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/support.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/support.py Sun Apr 5 01:04:14 2009 @@ -12,6 +12,7 @@ import shutil import warnings import unittest +import importlib __all__ = ["Error", "TestFailed", "ResourceDenied", "import_module", "verbose", "use_resources", "max_memuse", "record_original_stdout", @@ -24,7 +25,7 @@ "TransientResource", "transient_internet", "run_with_locale", "set_memlimit", "bigmemtest", "bigaddrspacetest", "BasicTestRunner", "run_unittest", "run_doctest", "threading_setup", "threading_cleanup", - "reap_children", "cpython_only", "check_impl_detail"] + "reap_children", "cpython_only", "check_impl_detail", "get_attribute"] class Error(Exception): """Base class for regression test exceptions.""" @@ -41,19 +42,32 @@ """ def import_module(name, deprecated=False): - """Import the module to be tested, raising SkipTest if it is not - available.""" + """Import and return the module to be tested, raising SkipTest if + it is not available. + + If deprecated is True, any module or package deprecation messages + will be suppressed.""" with warnings.catch_warnings(): if deprecated: warnings.filterwarnings("ignore", ".+ (module|package)", DeprecationWarning) try: - module = __import__(name, level=0) - except ImportError: - raise unittest.SkipTest("No module named " + name) + module = importlib.import_module(name) + except ImportError as msg: + raise unittest.SkipTest(str(msg)) else: return module +def get_attribute(obj, name): + """Get an attribute, raising SkipTest if AttributeError is raised.""" + try: + attribute = getattr(obj, name) + except AttributeError: + raise unittest.SkipTest("module %s has no attribute %s" % ( + obj.__name__, name)) + else: + return attribute + verbose = 1 # Flag set to 0 by regrtest.py use_resources = None # Flag set to [] by regrtest.py max_memuse = 0 # Disable bigmem tests (they will still be run with Modified: python/branches/py3k-short-float-repr/Lib/test/test___all__.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test___all__.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test___all__.py Sun Apr 5 01:04:14 2009 @@ -75,6 +75,8 @@ self.check_all("heapq") self.check_all("http.client") self.check_all("ihooks") + self.check_all("io") + self.check_all("_pyio") self.check_all("imaplib") self.check_all("imghdr") self.check_all("keyword") Modified: python/branches/py3k-short-float-repr/Lib/test/test_asynchat.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_asynchat.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_asynchat.py Sun Apr 5 01:04:14 2009 @@ -1,10 +1,13 @@ -# test asynchat -- requires threading +# test asynchat + +from test import support + +# If this fails, the test will be skipped. +thread = support.import_module('_thread') -import _thread as thread # If this fails, we can't test this module import asyncore, asynchat, socket, threading, time import unittest import sys -from test import support HOST = support.HOST SERVER_QUIT = b'QUIT\n' Modified: python/branches/py3k-short-float-repr/Lib/test/test_bz2.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_bz2.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_bz2.py Sun Apr 5 01:04:14 2009 @@ -8,7 +8,9 @@ import subprocess import sys -import bz2 +# Skip tests if the bz2 module doesn't exist. +bz2 = support.import_module('bz2') + from bz2 import BZ2File, BZ2Compressor, BZ2Decompressor has_cmdline_bunzip2 = sys.platform not in ("win32", "os2emx") Modified: python/branches/py3k-short-float-repr/Lib/test/test_collections.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_collections.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_collections.py Sun Apr 5 01:04:14 2009 @@ -51,12 +51,12 @@ def test_name_fixer(self): for spec, renamed in [ - [('efg', 'g%hi'), ('efg', '_2')], # field with non-alpha char - [('abc', 'class'), ('abc', '_2')], # field has keyword - [('8efg', '9ghi'), ('_1', '_2')], # field starts with digit - [('abc', '_efg'), ('abc', '_2')], # field with leading underscore - [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_3', 'ghi')], # duplicate field - [('abc', '', 'x'), ('abc', '_2', 'x')], # fieldname is a space + [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char + [('abc', 'class'), ('abc', '_1')], # field has keyword + [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit + [('abc', '_efg'), ('abc', '_1')], # field with leading underscore + [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field + [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space ]: self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed) @@ -327,6 +327,25 @@ B.register(C) self.failUnless(issubclass(C, B)) +class WithSet(MutableSet): + + def __init__(self, it=()): + self.data = set(it) + + def __len__(self): + return len(self.data) + + def __iter__(self): + return iter(self.data) + + def __contains__(self, item): + return item in self.data + + def add(self, item): + self.data.add(item) + + def discard(self, item): + self.data.discard(item) class TestCollectionABCs(ABCTestCase): @@ -363,6 +382,12 @@ self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__', 'add', 'discard') + def test_issue_5647(self): + # MutableSet.__iand__ mutated the set during iteration + s = WithSet('abcd') + s &= WithSet('cdef') # This used to fail + self.assertEqual(set(s), set('cd')) + def test_issue_4920(self): # MutableSet.pop() method did not work class MySet(collections.MutableSet): Modified: python/branches/py3k-short-float-repr/Lib/test/test_crypt.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_crypt.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_crypt.py Sun Apr 5 01:04:14 2009 @@ -1,6 +1,7 @@ from test import support import unittest -import crypt + +crypt = support.import_module('crypt') class CryptTestCase(unittest.TestCase): Modified: python/branches/py3k-short-float-repr/Lib/test/test_csv.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_csv.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_csv.py Sun Apr 5 01:04:14 2009 @@ -6,7 +6,7 @@ import sys import os import unittest -from io import StringIO, BytesIO +from io import StringIO from tempfile import TemporaryFile import csv import gc @@ -162,6 +162,8 @@ quoting = csv.QUOTE_NONNUMERIC) self._write_test(['a',1,'p,q'], '"a","1","p,q"', quoting = csv.QUOTE_ALL) + self._write_test(['a\nb',1], '"a\nb","1"', + quoting = csv.QUOTE_ALL) def test_write_escape(self): self._write_test(['a',1,'p,q'], 'a,1,"p,q"', @@ -241,6 +243,7 @@ # will this fail where locale uses comma for decimals? self._read_test([',3,"5",7.3, 9'], [['', 3, '5', 7.3, 9]], quoting=csv.QUOTE_NONNUMERIC) + self._read_test(['"a\nb", 7'], [['a\nb', ' 7']]) self.assertRaises(ValueError, self._read_test, ['abc,3'], [[]], quoting=csv.QUOTE_NONNUMERIC) @@ -276,6 +279,16 @@ self.assertRaises(StopIteration, next, r) self.assertEqual(r.line_num, 3) + def test_roundtrip_quoteed_newlines(self): + with TemporaryFile("w+", newline='') as fileobj: + writer = csv.writer(fileobj) + self.assertRaises(TypeError, writer.writerows, None) + rows = [['a\nb','b'],['c','x\r\nd']] + writer.writerows(rows) + fileobj.seek(0) + for i, row in enumerate(csv.reader(fileobj)): + self.assertEqual(row, rows[i]) + class TestDialectRegistry(unittest.TestCase): def test_registry_badargs(self): self.assertRaises(TypeError, csv.list_dialects, None) Modified: python/branches/py3k-short-float-repr/Lib/test/test_ctypes.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_ctypes.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_ctypes.py Sun Apr 5 01:04:14 2009 @@ -1,6 +1,10 @@ import unittest -from test.support import run_unittest +from test.support import run_unittest, import_module + +# Skip tests if _ctypes module was not built. +import_module('_ctypes') + import ctypes.test def test_main(): Modified: python/branches/py3k-short-float-repr/Lib/test/test_curses.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_curses.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_curses.py Sun Apr 5 01:04:14 2009 @@ -9,16 +9,19 @@ # Only called, not tested: getmouse(), ungetmouse() # -import curses, sys, tempfile, os -import curses.panel +import sys, tempfile, os # Optionally test curses module. This currently requires that the # 'curses' resource be given on the regrtest command line using the -u # option. If not available, nothing after this line will be executed. -from test.support import requires +from test.support import requires, import_module requires('curses') +# If either of these don't exist, skip the tests. +curses = import_module('curses') +curses.panel = import_module('curses.panel') + # XXX: if newterm was supported we could use it instead of initscr and not exit term = os.environ.get('TERM') if not term or term == 'unknown': Modified: python/branches/py3k-short-float-repr/Lib/test/test_dbm.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_dbm.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_dbm.py Sun Apr 5 01:04:14 2009 @@ -3,10 +3,12 @@ import os import unittest -import dbm import glob import test.support +# Skip tests if dbm module doesn't exist. +dbm = test.support.import_module('dbm') + _fname = test.support.TESTFN # Modified: python/branches/py3k-short-float-repr/Lib/test/test_dbm_gnu.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_dbm_gnu.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_dbm_gnu.py Sun Apr 5 01:04:14 2009 @@ -1,4 +1,5 @@ -import dbm.gnu as gdbm +from test import support +gdbm = support.import_module("dbm.gnu") #skip if not supported import unittest import os from test.support import verbose, TESTFN, run_unittest, unlink Modified: python/branches/py3k-short-float-repr/Lib/test/test_dbm_ndbm.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_dbm_ndbm.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_dbm_ndbm.py Sun Apr 5 01:04:14 2009 @@ -1,4 +1,5 @@ from test import support +support.import_module("dbm.ndbm") #skip if not supported import unittest import os import random Modified: python/branches/py3k-short-float-repr/Lib/test/test_exceptions.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_exceptions.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_exceptions.py Sun Apr 5 01:04:14 2009 @@ -341,6 +341,12 @@ else: self.fail("No exception raised") + def testInvalidAttrs(self): + self.assertRaises(TypeError, setattr, Exception(), '__cause__', 1) + self.assertRaises(TypeError, delattr, Exception(), '__cause__') + self.assertRaises(TypeError, setattr, Exception(), '__context__', 1) + self.assertRaises(TypeError, delattr, Exception(), '__context__') + def testNoneClearsTracebackAttr(self): try: raise IndexError(4) Modified: python/branches/py3k-short-float-repr/Lib/test/test_fcntl.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_fcntl.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_fcntl.py Sun Apr 5 01:04:14 2009 @@ -3,12 +3,15 @@ OS/2+EMX doesn't support the file locking operations. """ -import fcntl import os import struct import sys import unittest -from test.support import verbose, TESTFN, unlink, run_unittest +from test.support import verbose, TESTFN, unlink, run_unittest, import_module + +# Skip test if no fnctl module. +fcntl = import_module('fcntl') + # TODO - Write tests for flock() and lockf(). Modified: python/branches/py3k-short-float-repr/Lib/test/test_fork1.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_fork1.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_fork1.py Sun Apr 5 01:04:14 2009 @@ -3,14 +3,12 @@ import os import time -import unittest from test.fork_wait import ForkWait -from test.support import run_unittest, reap_children +from test.support import run_unittest, reap_children, get_attribute + +# Skip test if fork does not exist. +get_attribute(os, 'fork') -try: - os.fork -except AttributeError: - raise unittest.SkipTest("os.fork not defined -- skipping test_fork1") class ForkTest(ForkWait): def wait_impl(self, cpid): Modified: python/branches/py3k-short-float-repr/Lib/test/test_functools.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_functools.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_functools.py Sun Apr 5 01:04:14 2009 @@ -2,6 +2,7 @@ import unittest from test import support from weakref import proxy +import pickle @staticmethod def PythonPartial(func, *args, **keywords): @@ -19,6 +20,9 @@ """capture all positional and keyword arguments""" return args, kw +def signature(part): + """ return the signature of a partial object """ + return (part.func, part.args, part.keywords, part.__dict__) class TestPartial(unittest.TestCase): @@ -141,6 +145,12 @@ join = self.thetype(''.join) self.assertEqual(join(data), '0123456789') + def test_pickle(self): + f = self.thetype(signature, 'asdf', bar=True) + f.add_something_to__dict__ = True + f_copy = pickle.loads(pickle.dumps(f)) + self.assertEqual(signature(f), signature(f_copy)) + class PartialSubclass(functools.partial): pass @@ -148,11 +158,13 @@ thetype = PartialSubclass - class TestPythonPartial(TestPartial): thetype = PythonPartial + # the python version isn't picklable + def test_pickle(self): pass + class TestUpdateWrapper(unittest.TestCase): def check_wrapper(self, wrapper, wrapped, Modified: python/branches/py3k-short-float-repr/Lib/test/test_gc.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_gc.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_gc.py Sun Apr 5 01:04:14 2009 @@ -244,7 +244,7 @@ # - the call to assertEqual somehow avoids building its args tuple def test_get_count(self): # Avoid future allocation of method object - assertEqual = self.assertEqual + assertEqual = self._baseAssertEqual gc.collect() assertEqual(gc.get_count(), (0, 0, 0)) a = dict() Modified: python/branches/py3k-short-float-repr/Lib/test/test_grp.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_grp.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_grp.py Sun Apr 5 01:04:14 2009 @@ -1,9 +1,10 @@ """Test script for the grp module.""" -import grp import unittest from test import support +grp = support.import_module('grp') + class GroupDatabaseTestCase(unittest.TestCase): def check_value(self, value): Modified: python/branches/py3k-short-float-repr/Lib/test/test_http_cookiejar.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_http_cookiejar.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_http_cookiejar.py Sun Apr 5 01:04:14 2009 @@ -583,11 +583,6 @@ req = urllib.request.Request("http://www.acme.com/", headers={"Host": "irrelevant.com"}) self.assertEquals(request_host(req), "www.acme.com") - # not actually sure this one is valid Request object, so maybe should - # remove test for no host in url in request_host function? - req = urllib.request.Request("/resource.html", - headers={"Host": "www.acme.com"}) - self.assertEquals(request_host(req), "www.acme.com") # port shouldn't be in request-host req = urllib.request.Request("http://www.acme.com:2345/resource.html", headers={"Host": "www.acme.com:5432"}) Modified: python/branches/py3k-short-float-repr/Lib/test/test_http_cookies.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_http_cookies.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_http_cookies.py Sun Apr 5 01:04:14 2009 @@ -50,17 +50,17 @@ self.assertEqual(C.output(['path']), 'Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme') - self.assertEqual(C.js_output(), """ + self.assertEqual(C.js_output(), r""" """) - self.assertEqual(C.js_output(['path']), """ + self.assertEqual(C.js_output(['path']), r""" """) Modified: python/branches/py3k-short-float-repr/Lib/test/test_imp.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_imp.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_imp.py Sun Apr 5 01:04:14 2009 @@ -1,4 +1,7 @@ import imp +import locale +import os +import os.path import sys import unittest from test import support @@ -75,6 +78,74 @@ support.unlink(temp_mod_name + '.pyc') support.unlink(temp_mod_name + '.pyo') + def test_issue5604(self): + # Test cannot cover imp.load_compiled function. + # Martin von Loewis note what shared library cannot have non-ascii + # character because init_xxx function cannot be compiled + # and issue never happens for dynamic modules. + # But sources modified to follow generic way for processing pathes. + + locale_encoding = locale.getpreferredencoding() + + # covers utf-8 and Windows ANSI code pages + # one non-space symbol from every page + # (http://en.wikipedia.org/wiki/Code_page) + known_locales = { + 'utf-8' : b'\xe4', + 'cp1250' : b'\x8C', + 'cp1251' : b'\xc0', + 'cp1252' : b'\xc0', + 'cp1253' : b'\xc1', + 'cp1254' : b'\xc0', + 'cp1255' : b'\xe0', + 'cp1256' : b'\xe0', + 'cp1257' : b'\xc0', + 'cp1258' : b'\xc0', + } + + special_char = known_locales.get(locale_encoding) + if special_char: + encoded_char = special_char.decode(locale_encoding) + temp_mod_name = 'test_imp_helper_' + encoded_char + test_package_name = 'test_imp_helper_package_' + encoded_char + init_file_name = os.path.join(test_package_name, '__init__.py') + try: + with open(temp_mod_name + '.py', 'w') as file: + file.write('a = 1\n') + file, filename, info = imp.find_module(temp_mod_name) + self.assertNotEquals(None, file) + self.assertTrue(filename[:-3].endswith(temp_mod_name)) + self.assertEquals('.py', info[0]) + self.assertEquals('U', info[1]) + self.assertEquals(imp.PY_SOURCE, info[2]) + + mod = imp.load_module(temp_mod_name, file, filename, info) + self.assertEquals(1, mod.a) + file.close() + + mod = imp.load_source(temp_mod_name, temp_mod_name + '.py') + self.assertEquals(1, mod.a) + + mod = imp.load_compiled(temp_mod_name, temp_mod_name + '.pyc') + self.assertEquals(1, mod.a) + + if not os.path.exists(test_package_name): + os.mkdir(test_package_name) + with open(init_file_name, 'w') as file: + file.write('b = 2\n') + package = imp.load_package(test_package_name, test_package_name) + self.assertEquals(2, package.b) + finally: + support.unlink(temp_mod_name + '.py') + support.unlink(temp_mod_name + '.pyc') + support.unlink(temp_mod_name + '.pyo') + + support.unlink(init_file_name + '.py') + support.unlink(init_file_name + '.pyc') + support.unlink(init_file_name + '.pyo') + support.rmtree(test_package_name) + + def test_reload(self): import marshal imp.reload(marshal) Modified: python/branches/py3k-short-float-repr/Lib/test/test_io.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_io.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_io.py Sun Apr 5 01:04:14 2009 @@ -1754,6 +1754,13 @@ self.assertEquals(f.read(), data * 2) self.assertEquals(buf.getvalue(), (data * 2).encode(encoding)) + def test_unreadable(self): + class UnReadable(self.BytesIO): + def readable(self): + return False + txt = self.TextIOWrapper(UnReadable()) + self.assertRaises(IOError, txt.read) + def test_read_one_by_one(self): txt = self.TextIOWrapper(self.BytesIO(b"AA\r\nBB")) reads = "" @@ -1989,13 +1996,13 @@ def test___all__(self): for name in self.io.__all__: obj = getattr(self.io, name, None) - self.assert_(obj is not None, name) + self.assertTrue(obj is not None, name) if name == "open": continue elif "error" in name.lower(): - self.assert_(issubclass(obj, Exception), name) - else: - self.assert_(issubclass(obj, self.IOBase), name) + self.assertTrue(issubclass(obj, Exception), name) + elif not name.startswith("SEEK_"): + self.assertTrue(issubclass(obj, self.IOBase)) def test_attributes(self): f = self.open(support.TESTFN, "wb", buffering=0) Modified: python/branches/py3k-short-float-repr/Lib/test/test_ioctl.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_ioctl.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_ioctl.py Sun Apr 5 01:04:14 2009 @@ -1,12 +1,9 @@ import unittest -from test.support import run_unittest +from test.support import run_unittest, import_module, get_attribute import os, struct -try: - import fcntl, termios -except ImportError: - raise unittest.SkipTest("No fcntl or termios module") -if not hasattr(termios,'TIOCGPGRP'): - raise unittest.SkipTest("termios module doesn't have TIOCGPGRP") +fcntl = import_module('fcntl') +termios = import_module('termios') +get_attribute(termios, 'TIOCGPGRP') #Can't run tests without this feature try: tty = open("/dev/tty", "r") Modified: python/branches/py3k-short-float-repr/Lib/test/test_locale.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_locale.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_locale.py Sun Apr 5 01:04:14 2009 @@ -219,6 +219,19 @@ (self.sep, self.sep)) +class TestFormatPatternArg(unittest.TestCase): + # Test handling of pattern argument of format + + def test_onlyOnePattern(self): + # Issue 2522: accept exactly one % pattern, and no extra chars. + self.assertRaises(ValueError, locale.format, "%f\n", 'foo') + self.assertRaises(ValueError, locale.format, "%f\r", 'foo') + self.assertRaises(ValueError, locale.format, "%f\r\n", 'foo') + self.assertRaises(ValueError, locale.format, " %f", 'foo') + self.assertRaises(ValueError, locale.format, "%fg", 'foo') + self.assertRaises(ValueError, locale.format, "%^g", 'foo') + + class TestNumberFormatting(BaseLocalizedTest, EnUSNumberFormatting): # Test number formatting with a real English locale. @@ -314,6 +327,7 @@ def test_main(): tests = [ TestMiscellaneous, + TestFormatPatternArg, TestEnUSNumberFormatting, TestCNumberFormatting, TestFrFRNumberFormatting, Modified: python/branches/py3k-short-float-repr/Lib/test/test_logging.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_logging.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_logging.py Sun Apr 5 01:04:14 2009 @@ -910,30 +910,32 @@ class WarningsTest(BaseTest): + def test_warnings(self): logging.captureWarnings(True) - warnings.filterwarnings("always", category=UserWarning) - try: - file = io.StringIO() - h = logging.StreamHandler(file) - logger = logging.getLogger("py.warnings") - logger.addHandler(h) - warnings.warn("I'm warning you...") - logger.removeHandler(h) - s = file.getvalue() - h.close() - self.assertTrue(s.find("UserWarning: I'm warning you...\n") > 0) - - #See if an explicit file uses the original implementation - file = io.StringIO() - warnings.showwarning("Explicit", UserWarning, "dummy.py", 42, file, - "Dummy line") - s = file.getvalue() - file.close() - self.assertEqual(s, "dummy.py:42: UserWarning: Explicit\n Dummy line\n") - finally: - warnings.resetwarnings() - logging.captureWarnings(False) + with warnings.catch_warnings(): + warnings.filterwarnings("always", category=UserWarning) + try: + file = io.StringIO() + h = logging.StreamHandler(file) + logger = logging.getLogger("py.warnings") + logger.addHandler(h) + warnings.warn("I'm warning you...") + logger.removeHandler(h) + s = file.getvalue() + h.close() + self.assertTrue(s.find("UserWarning: I'm warning you...\n") > 0) + + #See if an explicit file uses the original implementation + file = io.StringIO() + warnings.showwarning("Explicit", UserWarning, "dummy.py", 42, + file, "Dummy line") + s = file.getvalue() + file.close() + self.assertEqual(s, + "dummy.py:42: UserWarning: Explicit\n Dummy line\n") + finally: + logging.captureWarnings(False) # Set the locale to the platform-dependent default. I have no idea # why the test does this, but in any case we save the current locale Modified: python/branches/py3k-short-float-repr/Lib/test/test_mailbox.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_mailbox.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_mailbox.py Sun Apr 5 01:04:14 2009 @@ -931,6 +931,12 @@ self._box.remove(key1) self.assertEqual(self._box.get_sequences(), {'flagged':[key0]}) + def test_issue2625(self): + msg0 = mailbox.MHMessage(self._template % 0) + msg0.add_sequence('foo') + key0 = self._box.add(msg0) + refmsg0 = self._box.get_message(key0) + def test_pack(self): # Pack the contents of the mailbox msg0 = mailbox.MHMessage(self._template % 0) Modified: python/branches/py3k-short-float-repr/Lib/test/test_mmap.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_mmap.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_mmap.py Sun Apr 5 01:04:14 2009 @@ -1,7 +1,9 @@ -from test.support import TESTFN, run_unittest -import mmap +from test.support import TESTFN, run_unittest, import_module import unittest -import os, re +import os, re, itertools + +# Skip test if we can't import mmap. +mmap = import_module('mmap') PAGESIZE = mmap.PAGESIZE @@ -35,7 +37,7 @@ # Simple sanity checks tp = str(type(m)) # SF bug 128713: segfaulted on Linux - self.assertEqual(m.find('foo'), PAGESIZE) + self.assertEqual(m.find(b'foo'), PAGESIZE) self.assertEqual(len(m), 2*PAGESIZE) @@ -260,38 +262,38 @@ def test_find_end(self): # test the new 'end' parameter works as expected - f = open(TESTFN, 'w+') - data = 'one two ones' + f = open(TESTFN, 'wb+') + data = b'one two ones' n = len(data) f.write(data) f.flush() m = mmap.mmap(f.fileno(), n) f.close() - self.assertEqual(m.find('one'), 0) - self.assertEqual(m.find('ones'), 8) - self.assertEqual(m.find('one', 0, -1), 0) - self.assertEqual(m.find('one', 1), 8) - self.assertEqual(m.find('one', 1, -1), 8) - self.assertEqual(m.find('one', 1, -2), -1) + self.assertEqual(m.find(b'one'), 0) + self.assertEqual(m.find(b'ones'), 8) + self.assertEqual(m.find(b'one', 0, -1), 0) + self.assertEqual(m.find(b'one', 1), 8) + self.assertEqual(m.find(b'one', 1, -1), 8) + self.assertEqual(m.find(b'one', 1, -2), -1) def test_rfind(self): # test the new 'end' parameter works as expected - f = open(TESTFN, 'w+') - data = 'one two ones' + f = open(TESTFN, 'wb+') + data = b'one two ones' n = len(data) f.write(data) f.flush() m = mmap.mmap(f.fileno(), n) f.close() - self.assertEqual(m.rfind('one'), 8) - self.assertEqual(m.rfind('one '), 0) - self.assertEqual(m.rfind('one', 0, -1), 8) - self.assertEqual(m.rfind('one', 0, -2), 0) - self.assertEqual(m.rfind('one', 1, -1), 8) - self.assertEqual(m.rfind('one', 1, -2), -1) + self.assertEqual(m.rfind(b'one'), 8) + self.assertEqual(m.rfind(b'one '), 0) + self.assertEqual(m.rfind(b'one', 0, -1), 8) + self.assertEqual(m.rfind(b'one', 0, -2), 0) + self.assertEqual(m.rfind(b'one', 1, -1), 8) + self.assertEqual(m.rfind(b'one', 1, -2), -1) def test_double_close(self): @@ -335,6 +337,35 @@ mf.close() f.close() + # more excessive test + data = b"0123456789" + for dest in range(len(data)): + for src in range(len(data)): + for count in range(len(data) - max(dest, src)): + expected = data[:dest] + data[src:src+count] + data[dest+count:] + m = mmap.mmap(-1, len(data)) + m[:] = data + m.move(dest, src, count) + self.assertEqual(m[:], expected) + m.close() + + # segfault test (Issue 5387) + m = mmap.mmap(-1, 100) + offsets = [-100, -1, 0, 1, 100] + for source, dest, size in itertools.product(offsets, offsets, offsets): + try: + m.move(source, dest, size) + except ValueError: + pass + self.assertRaises(ValueError, m.move, -1, -1, -1) + self.assertRaises(ValueError, m.move, -1, -1, 0) + self.assertRaises(ValueError, m.move, -1, 0, -1) + self.assertRaises(ValueError, m.move, 0, -1, -1) + self.assertRaises(ValueError, m.move, -1, 0, 0) + self.assertRaises(ValueError, m.move, 0, -1, 0) + self.assertRaises(ValueError, m.move, 0, 0, -1) + m.close() + def test_anonymous(self): # anonymous mmap.mmap(-1, PAGE) m = mmap.mmap(-1, PAGESIZE) @@ -475,21 +506,15 @@ # Test write_byte() for i in range(len(data)): self.assertEquals(m.tell(), i) - m.write_byte(data[i:i+1]) + m.write_byte(data[i]) self.assertEquals(m.tell(), i+1) - self.assertRaises(ValueError, m.write_byte, b"x") + self.assertRaises(ValueError, m.write_byte, b"x"[0]) self.assertEquals(m[:], data) # Test read_byte() m.seek(0) for i in range(len(data)): self.assertEquals(m.tell(), i) - # XXX: Disable this test for now because it's not clear - # which type of object m.read_byte returns. Currently, it - # returns 1-length str (unicode). - if 0: - self.assertEquals(m.read_byte(), data[i:i+1]) - else: - m.read_byte() + self.assertEquals(m.read_byte(), data[i]) self.assertEquals(m.tell(), i+1) self.assertRaises(ValueError, m.read_byte) # Test read() Modified: python/branches/py3k-short-float-repr/Lib/test/test_multibytecodec.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_multibytecodec.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_multibytecodec.py Sun Apr 5 01:04:14 2009 @@ -112,6 +112,10 @@ self.assertRaises(UnicodeEncodeError, encoder.encode, '\u0123') self.assertEqual(encoder.encode('', True), b'\xa9\xdc') + def test_issue5640(self): + encoder = codecs.getincrementalencoder('shift-jis')('backslashreplace') + self.assertEqual(encoder.encode('\xff'), b'\\xff') + self.assertEqual(encoder.encode('\n'), b'\n') class Test_IncrementalDecoder(unittest.TestCase): Modified: python/branches/py3k-short-float-repr/Lib/test/test_multiprocessing.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_multiprocessing.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_multiprocessing.py Sun Apr 5 01:04:14 2009 @@ -17,20 +17,19 @@ import socket import random import logging +import test.support -# Work around broken sem_open implementations -try: - import multiprocessing.synchronize -except ImportError as e: - raise unittest.SkipTest(e) +# Skip tests if _multiprocessing wasn't built. +_multiprocessing = test.support.import_module('_multiprocessing') +# Skip tests if sem_open implementation is broken. +test.support.import_module('multiprocessing.synchronize') import multiprocessing.dummy import multiprocessing.connection import multiprocessing.managers import multiprocessing.heap import multiprocessing.pool -import _multiprocessing from multiprocessing import util @@ -548,6 +547,10 @@ self.assertEqual(lock.release(), None) self.assertRaises((AssertionError, RuntimeError), lock.release) + def test_lock_context(self): + with self.Lock(): + pass + class _TestSemaphore(BaseTestCase): @@ -1209,10 +1212,12 @@ p.start() queue = manager.get_queue() self.assertEqual(queue.get(), 'hello world') + del queue manager.shutdown() manager = QueueManager( address=('localhost', 9999), authkey=authkey, serializer=SERIALIZER) manager.start() + manager.shutdown() # # Modified: python/branches/py3k-short-float-repr/Lib/test/test_nis.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_nis.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_nis.py Sun Apr 5 01:04:14 2009 @@ -1,6 +1,8 @@ from test import support import unittest -import nis + +# Skip test if nis module does not exist. +nis = support.import_module('nis') raise unittest.SkipTest("test_nis hangs on Solaris") Modified: python/branches/py3k-short-float-repr/Lib/test/test_ossaudiodev.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_ossaudiodev.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_ossaudiodev.py Sun Apr 5 01:04:14 2009 @@ -3,8 +3,9 @@ from test.support import findfile +ossaudiodev = support.import_module('ossaudiodev') + import errno -import ossaudiodev import sys import sunau import time Modified: python/branches/py3k-short-float-repr/Lib/test/test_posix.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_posix.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_posix.py Sun Apr 5 01:04:14 2009 @@ -1,11 +1,7 @@ "Test posix functions" from test import support - -try: - import posix -except ImportError: - raise unittest.SkipTest("posix is not available") +posix = support.import_module('posix') #skip if not supported import time import os @@ -13,6 +9,7 @@ import shutil import unittest import warnings + warnings.filterwarnings('ignore', '.* potential security risk .*', RuntimeWarning) Modified: python/branches/py3k-short-float-repr/Lib/test/test_pty.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_pty.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_pty.py Sun Apr 5 01:04:14 2009 @@ -1,6 +1,7 @@ +from test import support +pty = support.import_module("pty") #skip if not supported import errno import fcntl -import pty import os import sys import signal Modified: python/branches/py3k-short-float-repr/Lib/test/test_pwd.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_pwd.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_pwd.py Sun Apr 5 01:04:14 2009 @@ -1,7 +1,7 @@ import unittest from test import support -import pwd +pwd = support.import_module('pwd') class PwdTest(unittest.TestCase): Modified: python/branches/py3k-short-float-repr/Lib/test/test_resource.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_resource.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_resource.py Sun Apr 5 01:04:14 2009 @@ -1,9 +1,9 @@ import unittest from test import support - -import resource import time +resource = support.import_module('resource') + # This test is checking a few specific problem spots with the resource module. class ResourceTest(unittest.TestCase): Modified: python/branches/py3k-short-float-repr/Lib/test/test_scope.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_scope.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_scope.py Sun Apr 5 01:04:14 2009 @@ -618,7 +618,6 @@ self.assertEqual(dec(), 0) def testNonLocalMethod(self): - def f(x): class c: def inc(self): @@ -630,13 +629,36 @@ x -= 1 return x return c() - c = f(0) self.assertEqual(c.inc(), 1) self.assertEqual(c.inc(), 2) self.assertEqual(c.dec(), 1) self.assertEqual(c.dec(), 0) + def testGlobalInParallelNestedFunctions(self): + # A symbol table bug leaked the global statement from one + # function to other nested functions in the same block. + # This test verifies that a global statement in the first + # function does not affect the second function. + CODE = """def f(): + y = 1 + def g(): + global y + return y + def h(): + return y + 1 + return g, h +y = 9 +g, h = f() +result9 = g() +result2 = h() +""" + local_ns = {} + global_ns = {} + exec(CODE, local_ns, global_ns) + self.assertEqual(2, global_ns["result2"]) + self.assertEqual(9, global_ns["result9"]) + def testNonLocalClass(self): def f(x): Modified: python/branches/py3k-short-float-repr/Lib/test/test_sqlite.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_sqlite.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_sqlite.py Sun Apr 5 01:04:14 2009 @@ -1,10 +1,9 @@ import unittest -from test.support import run_unittest +from test.support import run_unittest, import_module + +# Skip test if _sqlite3 module not installed +import_module('_sqlite3') -try: - import _sqlite3 -except ImportError: - raise unittest.SkipTest('no sqlite available') from sqlite3.test import (dbapi, types, userfunctions, factory, transactions, hooks, regression, dump) Modified: python/branches/py3k-short-float-repr/Lib/test/test_startfile.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_startfile.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_startfile.py Sun Apr 5 01:04:14 2009 @@ -9,9 +9,11 @@ import unittest from test import support +import os +from os import path + +startfile = support.get_attribute(os, 'startfile') -# use this form so that the test is skipped when startfile is not available: -from os import startfile, path class TestCase(unittest.TestCase): def test_nonexisting(self): Modified: python/branches/py3k-short-float-repr/Lib/test/test_struct.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_struct.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_struct.py Sun Apr 5 01:04:14 2009 @@ -207,6 +207,7 @@ class IntTester(unittest.TestCase): def __init__(self, formatpair, bytesize): + super(IntTester, self).__init__(methodName='test_one') self.assertEqual(len(formatpair), 2) self.formatpair = formatpair for direction in "<>!=": Modified: python/branches/py3k-short-float-repr/Lib/test/test_sundry.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_sundry.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_sundry.py Sun Apr 5 01:04:14 2009 @@ -8,6 +8,7 @@ class TestUntestedModules(unittest.TestCase): def test_at_least_import_untested_modules(self): with warnings.catch_warnings(): + warnings.simplefilter("ignore") import aifc import bdb import cgitb Modified: python/branches/py3k-short-float-repr/Lib/test/test_symtable.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_symtable.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_symtable.py Sun Apr 5 01:04:14 2009 @@ -88,7 +88,9 @@ def test_globals(self): self.assertTrue(self.spam.lookup("glob").is_global()) + self.assertFalse(self.spam.lookup("glob").is_declared_global()) self.assertTrue(self.spam.lookup("bar").is_global()) + self.assertTrue(self.spam.lookup("bar").is_declared_global()) self.assertFalse(self.internal.lookup("x").is_global()) self.assertFalse(self.Mine.lookup("instance_var").is_global()) Modified: python/branches/py3k-short-float-repr/Lib/test/test_sys.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_sys.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_sys.py Sun Apr 5 01:04:14 2009 @@ -177,6 +177,9 @@ def test_recursionlimit_fatalerror(self): # A fatal error occurs if a second recursion limit is hit when recovering # from a first one. + if os.name == "nt": + raise unittest.SkipTest( + "under Windows, test would generate a spurious crash dialog") code = textwrap.dedent(""" import sys Modified: python/branches/py3k-short-float-repr/Lib/test/test_syslog.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_syslog.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_syslog.py Sun Apr 5 01:04:14 2009 @@ -1,7 +1,7 @@ -import syslog -import unittest from test import support +syslog = support.import_module("syslog") #skip if not supported +import unittest # XXX(nnorwitz): This test sucks. I don't know of a platform independent way # to verify that the messages were really logged. Modified: python/branches/py3k-short-float-repr/Lib/test/test_tcl.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_tcl.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_tcl.py Sun Apr 5 01:04:14 2009 @@ -2,8 +2,11 @@ import unittest import os -import _tkinter from test import support + +# Skip this test if the _tkinter module wasn't built. +_tkinter = support.import_module('_tkinter') + from tkinter import Tcl from _tkinter import TclError Modified: python/branches/py3k-short-float-repr/Lib/test/test_time.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_time.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_time.py Sun Apr 5 01:04:14 2009 @@ -116,6 +116,11 @@ self.fail("conversion specifier %r failed with '%s' input." % (format, strf_output)) + def test_strptime_bytes(self): + # Make sure only strings are accepted as arguments to strptime. + self.assertRaises(TypeError, time.strptime, b'2009', "%Y") + self.assertRaises(TypeError, time.strptime, '2009', b'%Y') + def test_asctime(self): time.asctime(time.gmtime(self.t)) self.assertRaises(TypeError, time.asctime, 0) Modified: python/branches/py3k-short-float-repr/Lib/test/test_tk.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_tk.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_tk.py Sun Apr 5 01:04:14 2009 @@ -1,6 +1,9 @@ +from test import support +# Skip test if _tkinter wasn't built. +support.import_module('_tkinter') + import tkinter from tkinter.test import runtktests -from test import support import unittest try: Modified: python/branches/py3k-short-float-repr/Lib/test/test_ttk_guionly.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_ttk_guionly.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_ttk_guionly.py Sun Apr 5 01:04:14 2009 @@ -1,11 +1,15 @@ import os import sys -from tkinter import ttk -from tkinter.test import runtktests import unittest -from _tkinter import TclError from test import support +# Skip this test if _tkinter wasn't built. +support.import_module('_tkinter') + +from _tkinter import TclError +from tkinter import ttk +from tkinter.test import runtktests + try: ttk.Button() except TclError as msg: Modified: python/branches/py3k-short-float-repr/Lib/test/test_ttk_textonly.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_ttk_textonly.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_ttk_textonly.py Sun Apr 5 01:04:14 2009 @@ -1,6 +1,10 @@ import os import sys from test import support + +# Skip this test if _tkinter does not exist. +support.import_module('_tkinter') + from tkinter.test import runtktests def test_main(): Modified: python/branches/py3k-short-float-repr/Lib/test/test_types.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_types.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_types.py Sun Apr 5 01:04:14 2009 @@ -341,6 +341,15 @@ test(123456, "#012X", '0X000001E240') test(-123456, "#012X", '-0X00001E240') + test(123, ',', '123') + test(-123, ',', '-123') + test(1234, ',', '1,234') + test(-1234, ',', '-1,234') + test(123456, ',', '123,456') + test(-123456, ',', '-123,456') + test(1234567, ',', '1,234,567') + test(-1234567, ',', '-1,234,567') + # make sure these are errors # precision disallowed @@ -350,6 +359,8 @@ # format spec must be string self.assertRaises(TypeError, 3 .__format__, None) self.assertRaises(TypeError, 3 .__format__, 0) + # can't have ',' with 'n' + self.assertRaises(ValueError, 3 .__format__, ",n") # ensure that only int and float type specifiers work for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] + Modified: python/branches/py3k-short-float-repr/Lib/test/test_unittest.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_unittest.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_unittest.py Sun Apr 5 01:04:14 2009 @@ -6,10 +6,12 @@ TestCase.{assert,fail}* methods (some are tested implicitly) """ +import re from test import support import unittest from unittest import TestCase import types +from copy import deepcopy ### Support code ################################################################ @@ -53,6 +55,8 @@ class TestEquality(object): + """Used as a mixin for TestCase""" + # Check for a valid __eq__ implementation def test_eq(self): for obj_1, obj_2 in self.eq_pairs: @@ -66,25 +70,26 @@ self.failIfEqual(obj_2, obj_1) class TestHashing(object): + """Used as a mixin for TestCase""" + # Check for a valid __hash__ implementation def test_hash(self): for obj_1, obj_2 in self.eq_pairs: try: - assert hash(obj_1) == hash(obj_2) + if not hash(obj_1) == hash(obj_2): + self.fail("%r and %r do not hash equal" % (obj_1, obj_2)) except KeyboardInterrupt: raise - except AssertionError: - self.fail("%s and %s do not hash equal" % (obj_1, obj_2)) except Exception as e: - self.fail("Problem hashing %s and %s: %s" % (obj_1, obj_2, e)) + self.fail("Problem hashing %r and %r: %s" % (obj_1, obj_2, e)) for obj_1, obj_2 in self.ne_pairs: try: - assert hash(obj_1) != hash(obj_2) + if hash(obj_1) == hash(obj_2): + self.fail("%s and %s hash equal, but shouldn't" % + (obj_1, obj_2)) except KeyboardInterrupt: raise - except AssertionError: - self.fail("%s and %s hash equal, but shouldn't" % (obj_1, obj_2)) except Exception as e: self.fail("Problem hashing %s and %s: %s" % (obj_1, obj_2, e)) @@ -2247,39 +2252,6 @@ self.failUnless(isinstance(Foo().id(), str)) - # "Returns a one-line description of the test, or None if no description - # has been provided. The default implementation of this method returns - # the first line of the test method's docstring, if available, or None." - def test_shortDescription__no_docstring(self): - class Foo(unittest.TestCase): - def runTest(self): - pass - - self.assertEqual(Foo().shortDescription(), None) - - # "Returns a one-line description of the test, or None if no description - # has been provided. The default implementation of this method returns - # the first line of the test method's docstring, if available, or None." - def test_shortDescription__singleline_docstring(self): - class Foo(unittest.TestCase): - def runTest(self): - "this tests foo" - pass - - self.assertEqual(Foo().shortDescription(), "this tests foo") - - # "Returns a one-line description of the test, or None if no description - # has been provided. The default implementation of this method returns - # the first line of the test method's docstring, if available, or None." - def test_shortDescription__multiline_docstring(self): - class Foo(unittest.TestCase): - def runTest(self): - """this tests foo - blah, bar and baz are also tested""" - pass - - self.assertEqual(Foo().shortDescription(), "this tests foo") - # "If result is omitted or None, a temporary result object is created # and used, but is not made available to the caller" def test_run__uses_defaultTestResult(self): @@ -2298,6 +2270,408 @@ expected = ['startTest', 'test', 'addSuccess', 'stopTest'] self.assertEqual(events, expected) + def testShortDescriptionWithoutDocstring(self): + self.assertEqual( + self.shortDescription(), + 'testShortDescriptionWithoutDocstring (' + __name__ + + '.Test_TestCase)') + + def testShortDescriptionWithOneLineDocstring(self): + """Tests shortDescription() for a method with a docstring.""" + self.assertEqual( + self.shortDescription(), + ('testShortDescriptionWithOneLineDocstring ' + '(' + __name__ + '.Test_TestCase)\n' + 'Tests shortDescription() for a method with a docstring.')) + + def testShortDescriptionWithMultiLineDocstring(self): + """Tests shortDescription() for a method with a longer docstring. + + This method ensures that only the first line of a docstring is + returned used in the short description, no matter how long the + whole thing is. + """ + self.assertEqual( + self.shortDescription(), + ('testShortDescriptionWithMultiLineDocstring ' + '(' + __name__ + '.Test_TestCase)\n' + 'Tests shortDescription() for a method with a longer ' + 'docstring.')) + + def testAddTypeEqualityFunc(self): + class SadSnake(object): + """Dummy class for test_addTypeEqualityFunc.""" + s1, s2 = SadSnake(), SadSnake() + self.assertFalse(s1 == s2) + def AllSnakesCreatedEqual(a, b, msg=None): + return type(a) == type(b) == SadSnake + self.addTypeEqualityFunc(SadSnake, AllSnakesCreatedEqual) + self.assertEqual(s1, s2) + # No this doesn't clean up and remove the SadSnake equality func + # from this TestCase instance but since its a local nothing else + # will ever notice that. + + def testAssertIn(self): + animals = {'monkey': 'banana', 'cow': 'grass', 'seal': 'fish'} + + self.assertIn('a', 'abc') + self.assertIn(2, [1, 2, 3]) + self.assertIn('monkey', animals) + + self.assertNotIn('d', 'abc') + self.assertNotIn(0, [1, 2, 3]) + self.assertNotIn('otter', animals) + + self.assertRaises(self.failureException, self.assertIn, 'x', 'abc') + self.assertRaises(self.failureException, self.assertIn, 4, [1, 2, 3]) + self.assertRaises(self.failureException, self.assertIn, 'elephant', + animals) + + self.assertRaises(self.failureException, self.assertNotIn, 'c', 'abc') + self.assertRaises(self.failureException, self.assertNotIn, 1, [1, 2, 3]) + self.assertRaises(self.failureException, self.assertNotIn, 'cow', + animals) + + def testAssertDictContainsSubset(self): + self.assertDictContainsSubset({}, {}) + self.assertDictContainsSubset({}, {'a': 1}) + self.assertDictContainsSubset({'a': 1}, {'a': 1}) + self.assertDictContainsSubset({'a': 1}, {'a': 1, 'b': 2}) + self.assertDictContainsSubset({'a': 1, 'b': 2}, {'a': 1, 'b': 2}) + + self.assertRaises(unittest.TestCase.failureException, + self.assertDictContainsSubset, {'a': 2}, {'a': 1}, + '.*Mismatched values:.*') + + self.assertRaises(unittest.TestCase.failureException, + self.assertDictContainsSubset, {'c': 1}, {'a': 1}, + '.*Missing:.*') + + self.assertRaises(unittest.TestCase.failureException, + self.assertDictContainsSubset, {'a': 1, 'c': 1}, + {'a': 1}, '.*Missing:.*') + + self.assertRaises(unittest.TestCase.failureException, + self.assertDictContainsSubset, {'a': 1, 'c': 1}, + {'a': 1}, '.*Missing:.*Mismatched values:.*') + + def testAssertEqual(self): + equal_pairs = [ + ((), ()), + ({}, {}), + ([], []), + (set(), set()), + (frozenset(), frozenset())] + for a, b in equal_pairs: + # This mess of try excepts is to test the assertEqual behavior + # itself. + try: + self.assertEqual(a, b) + except self.failureException: + self.fail('assertEqual(%r, %r) failed' % (a, b)) + try: + self.assertEqual(a, b, msg='foo') + except self.failureException: + self.fail('assertEqual(%r, %r) with msg= failed' % (a, b)) + try: + self.assertEqual(a, b, 'foo') + except self.failureException: + self.fail('assertEqual(%r, %r) with third parameter failed' % + (a, b)) + + unequal_pairs = [ + ((), []), + ({}, set()), + (set([4,1]), frozenset([4,2])), + (frozenset([4,5]), set([2,3])), + (set([3,4]), set([5,4]))] + for a, b in unequal_pairs: + self.assertRaises(self.failureException, self.assertEqual, a, b) + self.assertRaises(self.failureException, self.assertEqual, a, b, + 'foo') + self.assertRaises(self.failureException, self.assertEqual, a, b, + msg='foo') + + def testEquality(self): + self.assertListEqual([], []) + self.assertTupleEqual((), ()) + self.assertSequenceEqual([], ()) + + a = [0, 'a', []] + b = [] + self.assertRaises(unittest.TestCase.failureException, + self.assertListEqual, a, b) + self.assertRaises(unittest.TestCase.failureException, + self.assertListEqual, tuple(a), tuple(b)) + self.assertRaises(unittest.TestCase.failureException, + self.assertSequenceEqual, a, tuple(b)) + + b.extend(a) + self.assertListEqual(a, b) + self.assertTupleEqual(tuple(a), tuple(b)) + self.assertSequenceEqual(a, tuple(b)) + self.assertSequenceEqual(tuple(a), b) + + self.assertRaises(self.failureException, self.assertListEqual, + a, tuple(b)) + self.assertRaises(self.failureException, self.assertTupleEqual, + tuple(a), b) + self.assertRaises(self.failureException, self.assertListEqual, None, b) + self.assertRaises(self.failureException, self.assertTupleEqual, None, + tuple(b)) + self.assertRaises(self.failureException, self.assertSequenceEqual, + None, tuple(b)) + self.assertRaises(self.failureException, self.assertListEqual, 1, 1) + self.assertRaises(self.failureException, self.assertTupleEqual, 1, 1) + self.assertRaises(self.failureException, self.assertSequenceEqual, + 1, 1) + + self.assertDictEqual({}, {}) + + c = { 'x': 1 } + d = {} + self.assertRaises(unittest.TestCase.failureException, + self.assertDictEqual, c, d) + + d.update(c) + self.assertDictEqual(c, d) + + d['x'] = 0 + self.assertRaises(unittest.TestCase.failureException, + self.assertDictEqual, c, d, 'These are unequal') + + self.assertRaises(self.failureException, self.assertDictEqual, None, d) + self.assertRaises(self.failureException, self.assertDictEqual, [], d) + self.assertRaises(self.failureException, self.assertDictEqual, 1, 1) + + self.assertSameElements([1, 2, 3], [3, 2, 1]) + self.assertSameElements([1, 2] + [3] * 100, [1] * 100 + [2, 3]) + self.assertSameElements(['foo', 'bar', 'baz'], ['bar', 'baz', 'foo']) + self.assertRaises(self.failureException, self.assertSameElements, + [10], [10, 11]) + self.assertRaises(self.failureException, self.assertSameElements, + [10, 11], [10]) + + # Test that sequences of unhashable objects can be tested for sameness: + self.assertSameElements([[1, 2], [3, 4]], [[3, 4], [1, 2]]) + self.assertSameElements([{'a': 1}, {'b': 2}], [{'b': 2}, {'a': 1}]) + self.assertRaises(self.failureException, self.assertSameElements, + [[1]], [[2]]) + self.assertRaises(self.failureException, self.assertSameElements, + [{'a': 1}, {'b': 2}], [{'b': 2}, {'a': 2}]) + + def testAssertSetEqual(self): + set1 = set() + set2 = set() + self.assertSetEqual(set1, set2) + + self.assertRaises(self.failureException, self.assertSetEqual, None, set2) + self.assertRaises(self.failureException, self.assertSetEqual, [], set2) + self.assertRaises(self.failureException, self.assertSetEqual, set1, None) + self.assertRaises(self.failureException, self.assertSetEqual, set1, []) + + set1 = set(['a']) + set2 = set() + self.assertRaises(self.failureException, self.assertSetEqual, set1, set2) + + set1 = set(['a']) + set2 = set(['a']) + self.assertSetEqual(set1, set2) + + set1 = set(['a']) + set2 = set(['a', 'b']) + self.assertRaises(self.failureException, self.assertSetEqual, set1, set2) + + set1 = set(['a']) + set2 = frozenset(['a', 'b']) + self.assertRaises(self.failureException, self.assertSetEqual, set1, set2) + + set1 = set(['a', 'b']) + set2 = frozenset(['a', 'b']) + self.assertSetEqual(set1, set2) + + set1 = set() + set2 = "foo" + self.assertRaises(self.failureException, self.assertSetEqual, set1, set2) + self.assertRaises(self.failureException, self.assertSetEqual, set2, set1) + + # make sure any string formatting is tuple-safe + set1 = set([(0, 1), (2, 3)]) + set2 = set([(4, 5)]) + self.assertRaises(self.failureException, self.assertSetEqual, set1, set2) + + def testInequality(self): + # Try ints + self.assertGreater(2, 1) + self.assertGreaterEqual(2, 1) + self.assertGreaterEqual(1, 1) + self.assertLess(1, 2) + self.assertLessEqual(1, 2) + self.assertLessEqual(1, 1) + self.assertRaises(self.failureException, self.assertGreater, 1, 2) + self.assertRaises(self.failureException, self.assertGreater, 1, 1) + self.assertRaises(self.failureException, self.assertGreaterEqual, 1, 2) + self.assertRaises(self.failureException, self.assertLess, 2, 1) + self.assertRaises(self.failureException, self.assertLess, 1, 1) + self.assertRaises(self.failureException, self.assertLessEqual, 2, 1) + + # Try Floats + self.assertGreater(1.1, 1.0) + self.assertGreaterEqual(1.1, 1.0) + self.assertGreaterEqual(1.0, 1.0) + self.assertLess(1.0, 1.1) + self.assertLessEqual(1.0, 1.1) + self.assertLessEqual(1.0, 1.0) + self.assertRaises(self.failureException, self.assertGreater, 1.0, 1.1) + self.assertRaises(self.failureException, self.assertGreater, 1.0, 1.0) + self.assertRaises(self.failureException, self.assertGreaterEqual, 1.0, 1.1) + self.assertRaises(self.failureException, self.assertLess, 1.1, 1.0) + self.assertRaises(self.failureException, self.assertLess, 1.0, 1.0) + self.assertRaises(self.failureException, self.assertLessEqual, 1.1, 1.0) + + # Try Strings + self.assertGreater('bug', 'ant') + self.assertGreaterEqual('bug', 'ant') + self.assertGreaterEqual('ant', 'ant') + self.assertLess('ant', 'bug') + self.assertLessEqual('ant', 'bug') + self.assertLessEqual('ant', 'ant') + self.assertRaises(self.failureException, self.assertGreater, 'ant', 'bug') + self.assertRaises(self.failureException, self.assertGreater, 'ant', 'ant') + self.assertRaises(self.failureException, self.assertGreaterEqual, 'ant', 'bug') + self.assertRaises(self.failureException, self.assertLess, 'bug', 'ant') + self.assertRaises(self.failureException, self.assertLess, 'ant', 'ant') + self.assertRaises(self.failureException, self.assertLessEqual, 'bug', 'ant') + + # Try bytes + self.assertGreater(b'bug', b'ant') + self.assertGreaterEqual(b'bug', b'ant') + self.assertGreaterEqual(b'ant', b'ant') + self.assertLess(b'ant', b'bug') + self.assertLessEqual(b'ant', b'bug') + self.assertLessEqual(b'ant', b'ant') + self.assertRaises(self.failureException, self.assertGreater, b'ant', b'bug') + self.assertRaises(self.failureException, self.assertGreater, b'ant', b'ant') + self.assertRaises(self.failureException, self.assertGreaterEqual, b'ant', + b'bug') + self.assertRaises(self.failureException, self.assertLess, b'bug', b'ant') + self.assertRaises(self.failureException, self.assertLess, b'ant', b'ant') + self.assertRaises(self.failureException, self.assertLessEqual, b'bug', b'ant') + + def testAssertMultiLineEqual(self): + sample_text = """\ +http://www.python.org/doc/2.3/lib/module-unittest.html +test case + A test case is the smallest unit of testing. [...] +""" + revised_sample_text = """\ +http://www.python.org/doc/2.4.1/lib/module-unittest.html +test case + A test case is the smallest unit of testing. [...] You may provide your + own implementation that does not subclass from TestCase, of course. +""" + sample_text_error = """ +- http://www.python.org/doc/2.3/lib/module-unittest.html +? ^ ++ http://www.python.org/doc/2.4.1/lib/module-unittest.html +? ^^^ + test case +- A test case is the smallest unit of testing. [...] ++ A test case is the smallest unit of testing. [...] You may provide your +? +++++++++++++++++++++ ++ own implementation that does not subclass from TestCase, of course. +""" + + try: + self.assertMultiLineEqual(sample_text, revised_sample_text) + except self.failureException as e: + # no fair testing ourself with ourself, use assertEqual.. + self.assertEqual(sample_text_error, str(e)) + + def testAssertIsNone(self): + self.assertIsNone(None) + self.assertRaises(self.failureException, self.assertIsNone, False) + 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, + 'saaas', r'aaaa') + + def testAssertRaisesRegexp(self): + class ExceptionMock(Exception): + pass + + def Stub(): + raise ExceptionMock('We expect') + + self.assertRaisesRegexp(ExceptionMock, re.compile('expect$'), Stub) + self.assertRaisesRegexp(ExceptionMock, 'expect$', Stub) + + def testAssertNotRaisesRegexp(self): + self.assertRaisesRegexp( + self.failureException, '^Exception not raised by $', + self.assertRaisesRegexp, Exception, re.compile('x'), + lambda: None) + self.assertRaisesRegexp( + self.failureException, '^Exception not raised by $', + self.assertRaisesRegexp, Exception, 'x', + lambda: None) + + def testAssertRaisesRegexpMismatch(self): + def Stub(): + raise Exception('Unexpected') + + self.assertRaisesRegexp( + self.failureException, + r'"\^Expected\$" does not match "Unexpected"', + self.assertRaisesRegexp, Exception, '^Expected$', + Stub) + self.assertRaisesRegexp( + self.failureException, + r'"\^Expected\$" does not match "Unexpected"', + self.assertRaisesRegexp, Exception, + re.compile('^Expected$'), Stub) + + def testSynonymAssertMethodNames(self): + """Test undocumented method name synonyms. + + Please do not use these methods names in your own code. + + This test confirms their continued existence and functionality + in order to avoid breaking existing code. + """ + self.assertNotEquals(3, 5) + self.assertEquals(3, 3) + self.assertAlmostEquals(2.0, 2.0) + self.assertNotAlmostEquals(3.0, 5.0) + self.assert_(True) + + def testPendingDeprecationMethodNames(self): + """Test fail* methods pending deprecation, they will warn in 3.2. + + Do not use these methods. They will go away in 3.3. + """ + self.failIfEqual(3, 5) + self.failUnlessEqual(3, 3) + self.failUnlessAlmostEqual(2.0, 2.0) + self.failIfAlmostEqual(3.0, 5.0) + self.failUnless(True) + self.failUnlessRaises(TypeError, lambda _: 3.14 + 'spam') + self.failIf(False) + + def testDeepcopy(self): + # Issue: 5660 + class TestableTest(TestCase): + def testNothing(self): + pass + + test = TestableTest('testNothing') + + # This shouldn't blow up + deepcopy(test) + class Test_TestSkipping(TestCase): @@ -2396,20 +2770,20 @@ def test_AlmostEqual(self): self.failUnlessAlmostEqual(1.00000001, 1.0) self.failIfAlmostEqual(1.0000001, 1.0) - self.assertRaises(AssertionError, + self.assertRaises(self.failureException, self.failUnlessAlmostEqual, 1.0000001, 1.0) - self.assertRaises(AssertionError, + self.assertRaises(self.failureException, self.failIfAlmostEqual, 1.00000001, 1.0) self.failUnlessAlmostEqual(1.1, 1.0, places=0) - self.assertRaises(AssertionError, + self.assertRaises(self.failureException, self.failUnlessAlmostEqual, 1.1, 1.0, places=1) self.failUnlessAlmostEqual(0, .1+.1j, places=0) self.failIfAlmostEqual(0, .1+.1j, places=1) - self.assertRaises(AssertionError, + self.assertRaises(self.failureException, self.failUnlessAlmostEqual, 0, .1+.1j, places=1) - self.assertRaises(AssertionError, + self.assertRaises(self.failureException, self.failIfAlmostEqual, 0, .1+.1j, places=0) def test_assertRaises(self): @@ -2419,7 +2793,7 @@ self.assertRaises(KeyError, _raise, KeyError("key")) try: self.assertRaises(KeyError, lambda: None) - except AssertionError as e: + except self.failureException as e: self.assert_("KeyError not raised" in str(e), str(e)) else: self.fail("assertRaises() didn't fail") @@ -2436,7 +2810,7 @@ try: with self.assertRaises(KeyError): pass - except AssertionError as e: + except self.failureException as e: self.assert_("KeyError not raised" in str(e), str(e)) else: self.fail("assertRaises() didn't fail") @@ -2449,6 +2823,172 @@ self.fail("assertRaises() didn't let exception pass through") +class TestLongMessage(TestCase): + """Test that the individual asserts honour longMessage. + This actually tests all the message behaviour for + asserts that use longMessage.""" + + def setUp(self): + class TestableTestFalse(TestCase): + longMessage = False + failureException = self.failureException + + def testTest(self): + pass + + class TestableTestTrue(TestCase): + longMessage = True + failureException = self.failureException + + def testTest(self): + pass + + self.testableTrue = TestableTestTrue('testTest') + self.testableFalse = TestableTestFalse('testTest') + + def testDefault(self): + self.assertFalse(TestCase.longMessage) + + def test_formatMsg(self): + self.assertEquals(self.testableFalse._formatMessage(None, "foo"), "foo") + self.assertEquals(self.testableFalse._formatMessage("foo", "bar"), "foo") + + self.assertEquals(self.testableTrue._formatMessage(None, "foo"), "foo") + self.assertEquals(self.testableTrue._formatMessage("foo", "bar"), "bar : foo") + + def assertMessages(self, methodName, args, errors): + def getMethod(i): + useTestableFalse = i < 2 + if useTestableFalse: + test = self.testableFalse + else: + test = self.testableTrue + return getattr(test, methodName) + + for i, expected_regexp in enumerate(errors): + testMethod = getMethod(i) + kwargs = {} + withMsg = i % 2 + if withMsg: + kwargs = {"msg": "oops"} + + with self.assertRaisesRegexp(self.failureException, + expected_regexp=expected_regexp): + testMethod(*args, **kwargs) + + def testAssertTrue(self): + self.assertMessages('assertTrue', (False,), + ["^False is not True$", "^oops$", "^False is not True$", + "^False is not True : oops$"]) + + def testAssertFalse(self): + self.assertMessages('assertFalse', (True,), + ["^True is not False$", "^oops$", "^True is not False$", + "^True is not False : oops$"]) + + def testNotEqual(self): + self.assertMessages('assertNotEqual', (1, 1), + ["^1 == 1$", "^oops$", "^1 == 1$", + "^1 == 1 : oops$"]) + + def testAlmostEqual(self): + self.assertMessages('assertAlmostEqual', (1, 2), + ["^1 != 2 within 7 places$", "^oops$", + "^1 != 2 within 7 places$", "^1 != 2 within 7 places : oops$"]) + + def testNotAlmostEqual(self): + self.assertMessages('assertNotAlmostEqual', (1, 1), + ["^1 == 1 within 7 places$", "^oops$", + "^1 == 1 within 7 places$", "^1 == 1 within 7 places : oops$"]) + + def test_baseAssertEqual(self): + self.assertMessages('_baseAssertEqual', (1, 2), + ["^1 != 2$", "^oops$", "^1 != 2$", "^1 != 2 : oops$"]) + + def testAssertSequenceEqual(self): + # Error messages are multiline so not testing on full message + # assertTupleEqual and assertListEqual delegate to this method + self.assertMessages('assertSequenceEqual', ([], [None]), + ["\+ \[None\]$", "^oops$", r"\+ \[None\]$", + r"\+ \[None\] : oops$"]) + + def testAssertSetEqual(self): + self.assertMessages('assertSetEqual', (set(), set([None])), + ["None$", "^oops$", "None$", + "None : oops$"]) + + def testAssertIn(self): + self.assertMessages('assertIn', (None, []), + ['^None not found in \[\]$', "^oops$", + '^None not found in \[\]$', + '^None not found in \[\] : oops$']) + + def testAssertNotIn(self): + self.assertMessages('assertNotIn', (None, [None]), + ['^None unexpectedly found in \[None\]$', "^oops$", + '^None unexpectedly found in \[None\]$', + '^None unexpectedly found in \[None\] : oops$']) + + def testAssertDictEqual(self): + self.assertMessages('assertDictEqual', ({}, {'key': 'value'}), + [r"\+ \{'key': 'value'\}$", "^oops$", + "\+ \{'key': 'value'\}$", + "\+ \{'key': 'value'\} : oops$"]) + + def testAssertDictContainsSubset(self): + self.assertMessages('assertDictContainsSubset', ({'key': 'value'}, {}), + ["^Missing: 'key'$", "^oops$", + "^Missing: 'key'$", + "^Missing: 'key' : oops$"]) + + def testAssertSameElements(self): + self.assertMessages('assertSameElements', ([], [None]), + [r"\[None\]$", "^oops$", + r"\[None\]$", + r"\[None\] : oops$"]) + + def testAssertMultiLineEqual(self): + self.assertMessages('assertMultiLineEqual', ("", "foo"), + [r"\+ foo$", "^oops$", + r"\+ foo$", + r"\+ foo : oops$"]) + + def testAssertLess(self): + self.assertMessages('assertLess', (2, 1), + ["^2 not less than 1$", "^oops$", + "^2 not less than 1$", "^2 not less than 1 : oops$"]) + + def testAssertLessEqual(self): + self.assertMessages('assertLessEqual', (2, 1), + ["^2 not less than or equal to 1$", "^oops$", + "^2 not less than or equal to 1$", + "^2 not less than or equal to 1 : oops$"]) + + def testAssertGreater(self): + self.assertMessages('assertGreater', (1, 2), + ["^1 not greater than 2$", "^oops$", + "^1 not greater than 2$", + "^1 not greater than 2 : oops$"]) + + def testAssertGreaterEqual(self): + self.assertMessages('assertGreaterEqual', (1, 2), + ["^1 not greater than or equal to 2$", "^oops$", + "^1 not greater than or equal to 2$", + "^1 not greater than or equal to 2 : oops$"]) + + def testAssertIsNone(self): + self.assertMessages('assertIsNone', ('not None',), + ["^'not None' is not None$", "^oops$", + "^'not None' is not None$", + "^'not None' is not None : oops$"]) + + def testAssertIsNotNone(self): + self.assertMessages('assertIsNotNone', (None,), + ["^unexpectedly None$", "^oops$", + "^unexpectedly None$", + "^unexpectedly None : oops$"]) + + ###################################################################### ## Main ###################################################################### @@ -2456,7 +2996,7 @@ def test_main(): support.run_unittest(Test_TestCase, Test_TestLoader, Test_TestSuite, Test_TestResult, Test_FunctionTestCase, - Test_TestSkipping, Test_Assertions) + Test_TestSkipping, Test_Assertions, TestLongMessage) if __name__ == "__main__": test_main() Modified: python/branches/py3k-short-float-repr/Lib/test/test_urllib.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_urllib.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_urllib.py Sun Apr 5 01:04:14 2009 @@ -830,6 +830,21 @@ "url2pathname() failed; %s != %s" % (expect, result)) +class Utility_Tests(unittest.TestCase): + """Testcase to test the various utility functions in the urllib.""" + + def test_splitpasswd(self): + """Some of password examples are not sensible, but it is added to + confirming to RFC2617 and addressing issue4675. + """ + self.assertEqual(('user', 'ab'),urllib.parse.splitpasswd('user:ab')) + self.assertEqual(('user', 'a\nb'),urllib.parse.splitpasswd('user:a\nb')) + self.assertEqual(('user', 'a\tb'),urllib.parse.splitpasswd('user:a\tb')) + self.assertEqual(('user', 'a\rb'),urllib.parse.splitpasswd('user:a\rb')) + self.assertEqual(('user', 'a\fb'),urllib.parse.splitpasswd('user:a\fb')) + self.assertEqual(('user', 'a\vb'),urllib.parse.splitpasswd('user:a\vb')) + self.assertEqual(('user', 'a:b'),urllib.parse.splitpasswd('user:a:b')) + # Just commented them out. # Can't really tell why keep failing in windows and sparc. # Everywhere else they work ok, but on those machines, someteimes @@ -920,6 +935,7 @@ UnquotingTests, urlencode_Tests, Pathname_Tests, + Utility_Tests, #FTPWrapperTests, ) Modified: python/branches/py3k-short-float-repr/Lib/test/test_urllib2.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_urllib2.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_urllib2.py Sun Apr 5 01:04:14 2009 @@ -683,8 +683,13 @@ self.msg = msg self.status = status self.reason = reason + self.code = 200 def read(self): return '' + def info(self): + return {} + def geturl(self): + return self.url class MockHTTPClass: def __init__(self): self.level = 0 Modified: python/branches/py3k-short-float-repr/Lib/test/test_urllib2net.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_urllib2net.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_urllib2net.py Sun Apr 5 01:04:14 2009 @@ -195,7 +195,7 @@ def test_http_basic(self): self.assertTrue(socket.getdefaulttimeout() is None) u = _urlopen_with_retry("http://www.python.org") - self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None) + self.assertTrue(u.fp.raw._sock.gettimeout() is None) def test_http_default_timeout(self): self.assertTrue(socket.getdefaulttimeout() is None) @@ -204,7 +204,7 @@ u = _urlopen_with_retry("http://www.python.org") finally: socket.setdefaulttimeout(None) - self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60) + self.assertEqual(u.fp.raw._sock.gettimeout(), 60) def test_http_no_timeout(self): self.assertTrue(socket.getdefaulttimeout() is None) @@ -213,11 +213,11 @@ u = _urlopen_with_retry("http://www.python.org", timeout=None) finally: socket.setdefaulttimeout(None) - self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None) + self.assertTrue(u.fp.raw._sock.gettimeout() is None) def test_http_timeout(self): u = _urlopen_with_retry("http://www.python.org", timeout=120) - self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 120) + self.assertEqual(u.fp.raw._sock.gettimeout(), 120) FTP_HOST = "ftp://ftp.mirror.nl/pub/mirror/gnu/" Modified: python/branches/py3k-short-float-repr/Lib/test/test_urlparse.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_urlparse.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_urlparse.py Sun Apr 5 01:04:14 2009 @@ -97,6 +97,9 @@ '', '', ''), ('mms', 'wms.sys.hinet.net', '/cts/Drama/09006251100.asf', '', '')), + ('nfs://server/path/to/file.txt', + ('nfs', 'server', '/path/to/file.txt', '', '', ''), + ('nfs', 'server', '/path/to/file.txt', '', '')), ('svn+ssh://svn.zope.org/repos/main/ZConfig/trunk/', ('svn+ssh', 'svn.zope.org', '/repos/main/ZConfig/trunk/', '', '', ''), Modified: python/branches/py3k-short-float-repr/Lib/test/test_wait4.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_wait4.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_wait4.py Sun Apr 5 01:04:14 2009 @@ -4,17 +4,12 @@ import os import time from test.fork_wait import ForkWait -from test.support import run_unittest, reap_children +from test.support import run_unittest, reap_children, get_attribute -try: - os.fork -except AttributeError: - raise unittest.SkipTest("os.fork not defined -- skipping test_wait4") +# If either of these do not exist, skip this test. +get_attribute(os, 'fork') +get_attribute(os, 'wait4') -try: - os.wait4 -except AttributeError: - raise unittest.SkipTest("os.wait4 not defined -- skipping test_wait4") class Wait4Test(ForkWait): def wait_impl(self, cpid): Modified: python/branches/py3k-short-float-repr/Lib/test/test_warnings.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_warnings.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_warnings.py Sun Apr 5 01:04:14 2009 @@ -423,6 +423,41 @@ finally: self.module.onceregistry = original_registry + def test_default_action(self): + # Replacing or removing defaultaction should be okay. + message = UserWarning("defaultaction test") + original = self.module.defaultaction + try: + with original_warnings.catch_warnings(record=True, + module=self.module) as w: + self.module.resetwarnings() + registry = {} + self.module.warn_explicit(message, UserWarning, "", 42, + registry=registry) + self.assertEqual(w[-1].message, message) + self.assertEqual(len(w), 1) + self.assertEqual(len(registry), 1) + del w[:] + # Test removal. + del self.module.defaultaction + __warningregistry__ = {} + registry = {} + self.module.warn_explicit(message, UserWarning, "", 43, + registry=registry) + self.assertEqual(w[-1].message, message) + self.assertEqual(len(w), 1) + self.assertEqual(len(registry), 1) + del w[:] + # Test setting. + self.module.defaultaction = "ignore" + __warningregistry__ = {} + registry = {} + self.module.warn_explicit(message, UserWarning, "", 44, + registry=registry) + self.assertEqual(len(w), 0) + finally: + self.module.defaultaction = original + def test_showwarning_missing(self): # Test that showwarning() missing is okay. text = 'del showwarning test' @@ -435,14 +470,14 @@ self.failUnless(text in result) def test_showwarning_not_callable(self): - self.module.filterwarnings("always", category=UserWarning) - old_showwarning = self.module.showwarning - self.module.showwarning = 23 - try: - self.assertRaises(TypeError, self.module.warn, "Warning!") - finally: - self.module.showwarning = old_showwarning - self.module.resetwarnings() + with original_warnings.catch_warnings(module=self.module): + self.module.filterwarnings("always", category=UserWarning) + old_showwarning = self.module.showwarning + self.module.showwarning = 23 + try: + self.assertRaises(TypeError, self.module.warn, "Warning!") + finally: + self.module.showwarning = old_showwarning def test_show_warning_output(self): # With showarning() missing, make sure that output is okay. Modified: python/branches/py3k-short-float-repr/Lib/test/test_winreg.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_winreg.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_winreg.py Sun Apr 5 01:04:14 2009 @@ -2,12 +2,15 @@ # Test the windows specific win32reg module. # Only win32reg functions not hit here: FlushKey, LoadKey and SaveKey -from winreg import * import os, sys import unittest - from test import support +# Do this first so test will be skipped if module doesn't exist +support.import_module('winreg') +# Now import everything +from winreg import * + test_key_name = "SOFTWARE\\Python Registry Test Key - Delete Me" test_data = [ Modified: python/branches/py3k-short-float-repr/Lib/test/test_winsound.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_winsound.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_winsound.py Sun Apr 5 01:04:14 2009 @@ -3,10 +3,12 @@ import unittest from test import support support.requires('audio') -import winsound, time +import time import os import subprocess +winsound = support.import_module('winsound') + class BeepTest(unittest.TestCase): # As with PlaySoundTest, incorporate the _have_soundcard() check Modified: python/branches/py3k-short-float-repr/Lib/test/test_xml_etree_c.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_xml_etree_c.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_xml_etree_c.py Sun Apr 5 01:04:14 2009 @@ -5,7 +5,7 @@ from test import support -from xml.etree import cElementTree as ET +ET = support.import_module('xml.etree.cElementTree') SAMPLE_XML = """ Modified: python/branches/py3k-short-float-repr/Lib/test/test_xmlrpc.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_xmlrpc.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_xmlrpc.py Sun Apr 5 01:04:14 2009 @@ -9,6 +9,7 @@ import http.client import socket import os +import re from test import support alist = [{'astring': 'foo at bar.baz.spam', @@ -352,6 +353,19 @@ # protocol error; provide additional information in test output self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) + def test_nonascii(self): + start_string = 'P\N{LATIN SMALL LETTER Y WITH CIRCUMFLEX}t' + end_string = 'h\N{LATIN SMALL LETTER O WITH HORN}n' + try: + p = xmlrpclib.ServerProxy(URL) + self.assertEqual(p.add(start_string, end_string), + start_string + end_string) + except (xmlrpclib.ProtocolError, socket.error) as e: + # ignore failures due to non-blocking socket 'unavailable' errors + if not is_unavailable_exception(e): + # protocol error; provide additional information in test output + self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) + # [ch] The test 404 is causing lots of false alarms. def XXXtest_404(self): # send POST with http.client, it should return 404 header and @@ -598,7 +612,11 @@ sys.stdin = open("xmldata.txt", "r") sys.stdout = open(support.TESTFN, "w") - self.cgi.handle_request() + os.environ['CONTENT_LENGTH'] = str(len(data)) + try: + self.cgi.handle_request() + finally: + del os.environ['CONTENT_LENGTH'] sys.stdin.close() sys.stdout.close() @@ -612,9 +630,21 @@ # need only xml self.assertRaises(xmlrpclib.Fault, xmlrpclib.loads, handle[44:]) + # Also test the content-length returned by handle_request + # Using the same test method inorder to avoid all the datapassing + # boilerplate code. + # Test for bug: http://bugs.python.org/issue5040 + + content = handle[handle.find("" or + filename.startswith("": - continue - if filename.startswith(" len2: + differing = ('First %s contains %d additional ' + 'elements.\n' % (seq_type_name, len1 - len2)) + try: + differing += ('First extra element %d:\n%s\n' % + (len2, seq1[len2])) + except (TypeError, IndexError, NotImplementedError): + differing += ('Unable to index element %d ' + 'of first %s\n' % (len2, seq_type_name)) + elif len1 < len2: + differing = ('Second %s contains %d additional ' + 'elements.\n' % (seq_type_name, len2 - len1)) + try: + differing += ('First extra element %d:\n%s\n' % + (len1, seq2[len1])) + except (TypeError, IndexError, NotImplementedError): + differing += ('Unable to index element %d ' + 'of second %s\n' % (len1, seq_type_name)) + standardMsg = differing + '\n'.join(difflib.ndiff(pprint.pformat(seq1).splitlines(), + pprint.pformat(seq2).splitlines())) + msg = self._formatMessage(msg, standardMsg) + self.fail(msg) + + def assertListEqual(self, list1, list2, msg=None): + """A list-specific equality assertion. + + Args: + list1: The first list to compare. + list2: The second list to compare. + msg: Optional message to use on failure instead of a list of + differences. + + """ + self.assertSequenceEqual(list1, list2, msg, seq_type=list) + + def assertTupleEqual(self, tuple1, tuple2, msg=None): + """A tuple-specific equality assertion. + + Args: + tuple1: The first tuple to compare. + tuple2: The second tuple to compare. + msg: Optional message to use on failure instead of a list of + differences. + """ + self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple) + + def assertSetEqual(self, set1, set2, msg=None): + """A set-specific equality assertion. + + Args: + set1: The first set to compare. + set2: The second set to compare. + msg: Optional message to use on failure instead of a list of + differences. + + For more general containership equality, assertSameElements will work + with things other than sets. This uses ducktyping to support + different types of sets, and is optimized for sets specifically + (parameters must support a difference method). + """ + try: + difference1 = set1.difference(set2) + except TypeError as e: + self.fail('invalid type when attempting set difference: %s' % e) + except AttributeError as e: + self.fail('first argument does not support set difference: %s' % e) + + try: + difference2 = set2.difference(set1) + except TypeError as e: + self.fail('invalid type when attempting set difference: %s' % e) + except AttributeError as e: + self.fail('second argument does not support set difference: %s' % e) + + if not (difference1 or difference2): + return + + lines = [] + if difference1: + lines.append('Items in the first set but not the second:') + for item in difference1: + lines.append(repr(item)) + if difference2: + lines.append('Items in the second set but not the first:') + for item in difference2: + lines.append(repr(item)) + + standardMsg = '\n'.join(lines) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertIn(self, member, container, msg=None): + """Just like self.assertTrue(a in b), but with a nicer default message.""" + if member not in container: + standardMsg = '%r not found in %r' % (member, container) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertNotIn(self, member, container, msg=None): + """Just like self.assertTrue(a not in b), but with a nicer default message.""" + if member in container: + standardMsg = '%r unexpectedly found in %r' % (member, container) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertDictEqual(self, d1, d2, msg=None): + self.assert_(isinstance(d1, dict), 'First argument is not a dictionary') + self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary') + + if d1 != d2: + standardMsg = ('\n' + '\n'.join(difflib.ndiff( + pprint.pformat(d1).splitlines(), + pprint.pformat(d2).splitlines()))) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertDictContainsSubset(self, expected, actual, msg=None): + """Checks whether actual is a superset of expected.""" + missing = [] + mismatched = [] + for key, value in expected.items(): + if key not in actual: + missing.append(key) + elif value != actual[key]: + mismatched.append('%s, expected: %s, actual: %s' % (key, value, actual[key])) + + if not (missing or mismatched): + return + + standardMsg = '' + if missing: + standardMsg = 'Missing: %r' % ','.join(missing) + if mismatched: + if standardMsg: + standardMsg += '; ' + standardMsg += 'Mismatched values: %s' % ','.join(mismatched) + + self.fail(self._formatMessage(msg, standardMsg)) + + def assertSameElements(self, expected_seq, actual_seq, msg=None): + """An unordered sequence specific comparison. + + Raises with an error message listing which elements of expected_seq + are missing from actual_seq and vice versa if any. + """ + try: + expected = set(expected_seq) + actual = set(actual_seq) + missing = list(expected.difference(actual)) + unexpected = list(actual.difference(expected)) + missing.sort() + unexpected.sort() + except TypeError: + # Fall back to slower list-compare if any of the objects are + # not hashable. + expected = list(expected_seq) + actual = list(actual_seq) + try: + expected.sort() + actual.sort() + except TypeError: + missing, unexpected = _UnorderableListDifference(expected, actual) + else: + missing, unexpected = _SortedListDifference(expected, actual) + errors = [] + if missing: + errors.append('Expected, but missing:\n %r' % missing) + if unexpected: + errors.append('Unexpected, but present:\n %r' % unexpected) + if errors: + standardMsg = '\n'.join(errors) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertMultiLineEqual(self, first, second, msg=None): + """Assert that two multi-line strings are equal.""" + self.assert_(isinstance(first, str), ( + 'First argument is not a string')) + self.assert_(isinstance(second, str), ( + 'Second argument is not a string')) + + if first != second: + standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True), second.splitlines(True))) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertLess(self, a, b, msg=None): + """Just like self.assertTrue(a < b), but with a nicer default message.""" + if not a < b: + standardMsg = '%r not less than %r' % (a, b) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertLessEqual(self, a, b, msg=None): + """Just like self.assertTrue(a <= b), but with a nicer default message.""" + if not a <= b: + standardMsg = '%r not less than or equal to %r' % (a, b) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertGreater(self, a, b, msg=None): + """Just like self.assertTrue(a > b), but with a nicer default message.""" + if not a > b: + standardMsg = '%r not greater than %r' % (a, b) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertGreaterEqual(self, a, b, msg=None): + """Just like self.assertTrue(a >= b), but with a nicer default message.""" + if not a >= b: + standardMsg = '%r not greater than or equal to %r' % (a, b) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertIsNone(self, obj, msg=None): + """Same as self.assertTrue(obj is None), with a nicer default message.""" + if obj is not None: + standardMsg = '%r is not None' % obj + self.fail(self._formatMessage(msg, standardMsg)) + + def assertIsNotNone(self, obj, msg=None): + """Included for symmetry with assertIsNone.""" + if obj is None: + standardMsg = 'unexpectedly None' + 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. + + Args: + expected_exception: Exception class expected to be raised. + expected_regexp: Regexp (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) + if callable_obj is None: + return context + with context: + callable_obj(*args, **kwargs) + + def assertRegexpMatches(self, text, expected_regex, msg=None): + if isinstance(expected_regex, (str, bytes)): + expected_regex = re.compile(expected_regex) + if not expected_regex.search(text): + msg = msg or "Regexp didn't match" + msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text) + raise self.failureException(msg) - assert_ = assertTrue = failUnless - assertFalse = failIf +def _SortedListDifference(expected, actual): + """Finds elements in only one or the other of two, sorted input lists. + Returns a two-element tuple of lists. The first list contains those + elements in the "expected" list but not in the "actual" list, and the + second contains those elements in the "actual" list but not in the + "expected" list. Duplicate elements in either input list are ignored. + """ + i = j = 0 + missing = [] + unexpected = [] + while True: + try: + e = expected[i] + a = actual[j] + if e < a: + missing.append(e) + i += 1 + while expected[i] == e: + i += 1 + elif e > a: + unexpected.append(a) + j += 1 + while actual[j] == a: + j += 1 + else: + i += 1 + try: + while expected[i] == e: + i += 1 + finally: + j += 1 + while actual[j] == a: + j += 1 + except IndexError: + missing.extend(expected[i:]) + unexpected.extend(actual[j:]) + break + return missing, unexpected + +def _UnorderableListDifference(expected, actual): + """Same behavior as _SortedListDifference but + for lists of unorderable items (like dicts). + + As it does a linear search per item (remove) it + has O(n*n) performance.""" + missing = [] + while expected: + item = expected.pop() + try: + actual.remove(item) + except ValueError: + missing.append(item) + # anything left in actual is unexpected + return missing, actual class TestSuite(object): """A test suite is a composite test consisting of a number of TestCases. @@ -611,52 +1112,52 @@ def __init__(self, testFunc, setUp=None, tearDown=None, description=None): super(FunctionTestCase, self).__init__() - self.__setUpFunc = setUp - self.__tearDownFunc = tearDown - self.__testFunc = testFunc - self.__description = description + self._setUpFunc = setUp + self._tearDownFunc = tearDown + self._testFunc = testFunc + self._description = description def setUp(self): - if self.__setUpFunc is not None: - self.__setUpFunc() + if self._setUpFunc is not None: + self._setUpFunc() def tearDown(self): - if self.__tearDownFunc is not None: - self.__tearDownFunc() + if self._tearDownFunc is not None: + self._tearDownFunc() def runTest(self): - self.__testFunc() + self._testFunc() def id(self): - return self.__testFunc.__name__ + return self._testFunc.__name__ def __eq__(self, other): if not isinstance(other, self.__class__): return NotImplemented - return self.__setUpFunc == other.__setUpFunc and \ - self.__tearDownFunc == other.__tearDownFunc and \ - self.__testFunc == other.__testFunc and \ - self.__description == other.__description + return self._setUpFunc == other._setUpFunc and \ + self._tearDownFunc == other._tearDownFunc and \ + self._testFunc == other._testFunc and \ + self._description == other._description def __ne__(self, other): return not self == other def __hash__(self): - return hash((type(self), self.__setUpFunc, self.__tearDownFunc, - self.__testFunc, self.__description)) + return hash((type(self), self._setUpFunc, self._tearDownFunc, + self._testFunc, self._description)) def __str__(self): return "%s (%s)" % (_strclass(self.__class__), self.__testFunc.__name__) def __repr__(self): - return "<%s testFunc=%s>" % (_strclass(self.__class__), - self.__testFunc) + return "<%s testFunc=%s>" % (_strclass(self.__class__), self._testFunc) def shortDescription(self): - if self.__description is not None: return self.__description - doc = self.__testFunc.__doc__ + if self._description is not None: + return self._description + doc = self._testFunc.__doc__ return doc and doc.split("\n")[0].strip() or None Modified: python/branches/py3k-short-float-repr/Lib/urllib/parse.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/urllib/parse.py (original) +++ python/branches/py3k-short-float-repr/Lib/urllib/parse.py Sun Apr 5 01:04:14 2009 @@ -19,7 +19,7 @@ uses_netloc = ['ftp', 'http', 'gopher', 'nntp', 'telnet', 'imap', 'wais', 'file', 'mms', 'https', 'shttp', 'snews', 'prospero', 'rtsp', 'rtspu', 'rsync', '', - 'svn', 'svn+ssh', 'sftp'] + 'svn', 'svn+ssh', 'sftp','nfs'] non_hierarchical = ['gopher', 'hdl', 'mailto', 'news', 'telnet', 'wais', 'imap', 'snews', 'sip', 'sips'] uses_params = ['ftp', 'hdl', 'prospero', 'http', 'imap', @@ -645,7 +645,7 @@ global _passwdprog if _passwdprog is None: import re - _passwdprog = re.compile('^([^:]*):(.*)$') + _passwdprog = re.compile('^([^:]*):(.*)$',re.S) match = _passwdprog.match(user) if match: return match.group(1, 2) Modified: python/branches/py3k-short-float-repr/Lib/urllib/request.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/urllib/request.py (original) +++ python/branches/py3k-short-float-repr/Lib/urllib/request.py Sun Apr 5 01:04:14 2009 @@ -1,6 +1,3 @@ -# Issues in merging urllib and urllib2: -# 1. They both define a function named urlopen() - """An extensible library for opening URLs using a variety of protocols The simplest way to use this module is to call the urlopen function, @@ -83,6 +80,7 @@ # abstract factory for opener import base64 +import bisect import email import hashlib import http.client @@ -94,7 +92,6 @@ import socket import sys import time -import bisect from urllib.error import URLError, HTTPError, ContentTooShortError from urllib.parse import ( @@ -149,7 +146,7 @@ comparison. """ - url = request.get_full_url() + url = request.full_url host = urlparse(url)[1] if host == "": host = request.get_header("Host", "") @@ -163,11 +160,7 @@ def __init__(self, url, data=None, headers={}, origin_req_host=None, unverifiable=False): # unwrap('') --> 'type://host/path' - self.__original = unwrap(url) - self.type = None - # self.__r_type is what's left after doing the splittype - self.host = None - self.port = None + self.full_url = unwrap(url) self.data = data self.headers = {} for key, value in headers.items(): @@ -177,26 +170,23 @@ origin_req_host = request_host(self) self.origin_req_host = origin_req_host self.unverifiable = unverifiable + self._parse() - def __getattr__(self, attr): - # XXX this is a fallback mechanism to guard against these - # methods getting called in a non-standard order. this may be - # too complicated and/or unnecessary. - # XXX should the __r_XXX attributes be public? - if attr[:12] == '_Request__r_': - name = attr[12:] - if hasattr(Request, 'get_' + name): - getattr(self, 'get_' + name)() - return getattr(self, attr) - raise AttributeError(attr) + def _parse(self): + self.type, rest = splittype(self.full_url) + if self.type is None: + raise ValueError("unknown url type: %s" % self.full_url) + self.host, self.selector = splithost(rest) + if self.host: + self.host = unquote(self.host) def get_method(self): - if self.has_data(): + if self.data is not None: return "POST" else: return "GET" - # XXX these helper methods are lame + # Begin deprecated methods def add_data(self, data): self.data = data @@ -208,37 +198,31 @@ return self.data def get_full_url(self): - return self.__original + return self.full_url def get_type(self): - if self.type is None: - self.type, self.__r_type = splittype(self.__original) - if self.type is None: - raise ValueError("unknown url type: %s" % self.__original) return self.type def get_host(self): - if self.host is None: - self.host, self.__r_host = splithost(self.__r_type) - if self.host: - self.host = unquote(self.host) return self.host def get_selector(self): - return self.__r_host + return self.selector - def set_proxy(self, host, type): - self.host, self.type = host, type - self.__r_host = self.__original - - def has_proxy(self): - return self.__r_host == self.__original + def is_unverifiable(self): + return self.unverifiable def get_origin_req_host(self): return self.origin_req_host - def is_unverifiable(self): - return self.unverifiable + # End deprecated methods + + def set_proxy(self, host, type): + self.host, self.type = host, type + self.selector = self.full_url + + def has_proxy(self): + return self.selector == self.full_url def add_header(self, key, val): # useful for something like authentication @@ -344,10 +328,10 @@ else: req = fullurl if data is not None: - req.add_data(data) + req.data = data req.timeout = timeout - protocol = req.get_type() + protocol = req.type # pre-process request meth_name = protocol+"_request" @@ -371,7 +355,7 @@ if result: return result - protocol = req.get_type() + protocol = req.type result = self._call_chain(self.handle_open, protocol, protocol + '_open', req) if result: @@ -481,7 +465,7 @@ class HTTPDefaultErrorHandler(BaseHandler): def http_error_default(self, req, fp, code, msg, hdrs): - raise HTTPError(req.get_full_url(), code, msg, hdrs, fp) + raise HTTPError(req.full_url, code, msg, hdrs, fp) class HTTPRedirectHandler(BaseHandler): # maximum number of redirections to any single URL @@ -504,7 +488,7 @@ m = req.get_method() if (not (code in (301, 302, 303, 307) and m in ("GET", "HEAD") or code in (301, 302, 303) and m == "POST")): - raise HTTPError(req.get_full_url(), code, msg, headers, fp) + raise HTTPError(req.full_url, code, msg, headers, fp) # Strictly (according to RFC 2616), 301 or 302 in response to # a POST MUST NOT cause a redirection without confirmation @@ -518,7 +502,7 @@ if k.lower() not in CONTENT_HEADERS) return Request(newurl, headers=newheaders, - origin_req_host=req.get_origin_req_host(), + origin_req_host=req.origin_req_host, unverifiable=True) # Implementation note: To avoid the server sending us into an @@ -542,7 +526,7 @@ urlparts[2] = "/" newurl = urlunparse(urlparts) - newurl = urljoin(req.get_full_url(), newurl) + newurl = urljoin(req.full_url, newurl) # XXX Probably want to forget about the state of the current # request, although that might interact poorly with other @@ -557,7 +541,7 @@ visited = new.redirect_dict = req.redirect_dict if (visited.get(newurl, 0) >= self.max_repeats or len(visited) >= self.max_redirections): - raise HTTPError(req.get_full_url(), code, + raise HTTPError(req.full_url, code, self.inf_msg + msg, headers, fp) else: visited = new.redirect_dict = req.redirect_dict = {} @@ -664,7 +648,7 @@ meth(r, proxy, type)) def proxy_open(self, req, proxy, type): - orig_type = req.get_type() + orig_type = req.type proxy_type, user, password, hostport = _parse_proxy(proxy) if proxy_type is None: proxy_type = orig_type @@ -811,7 +795,7 @@ auth_header = 'Authorization' def http_error_401(self, req, fp, code, msg, headers): - url = req.get_full_url() + url = req.full_url return self.http_error_auth_reqed('www-authenticate', url, req, headers) @@ -825,7 +809,7 @@ # authority. Assume there isn't one, since urllib.request does not (and # should not, RFC 3986 s. 3.2.1) support requests for URLs containing # userinfo. - authority = req.get_host() + authority = req.host return self.http_error_auth_reqed('proxy-authenticate', authority, req, headers) @@ -864,7 +848,7 @@ # prompting for the information. Crap. This isn't great # but it's better than the current 'repeat until recursion # depth exceeded' approach - raise HTTPError(req.get_full_url(), 401, "digest auth failed", + raise HTTPError(req.full_url, 401, "digest auth failed", headers, None) else: self.retried += 1 @@ -912,20 +896,20 @@ if H is None: return None - user, pw = self.passwd.find_user_password(realm, req.get_full_url()) + user, pw = self.passwd.find_user_password(realm, req.full_url) if user is None: return None # XXX not implemented yet - if req.has_data(): - entdig = self.get_entity_digest(req.get_data(), chal) + if req.data is not None: + entdig = self.get_entity_digest(req.data, chal) else: entdig = None A1 = "%s:%s:%s" % (user, realm, pw) A2 = "%s:%s" % (req.get_method(), # XXX selector: what about proxies and full urls - req.get_selector()) + req.selector) if qop == 'auth': self.nonce_count += 1 ncvalue = '%08x' % self.nonce_count @@ -941,7 +925,7 @@ # XXX should the partial digests be encoded too? base = 'username="%s", realm="%s", nonce="%s", uri="%s", ' \ - 'response="%s"' % (user, realm, nonce, req.get_selector(), + 'response="%s"' % (user, realm, nonce, req.selector, respdig) if opaque: base += ', opaque="%s"' % opaque @@ -978,7 +962,7 @@ handler_order = 490 # before Basic auth def http_error_401(self, req, fp, code, msg, headers): - host = urlparse(req.get_full_url())[1] + host = urlparse(req.full_url)[1] retry = self.http_error_auth_reqed('www-authenticate', host, req, headers) self.reset_retry_count() @@ -991,7 +975,7 @@ handler_order = 490 # before Basic auth def http_error_407(self, req, fp, code, msg, headers): - host = req.get_host() + host = req.host retry = self.http_error_auth_reqed('proxy-authenticate', host, req, headers) self.reset_retry_count() @@ -1006,12 +990,12 @@ self._debuglevel = level def do_request_(self, request): - host = request.get_host() + host = request.host if not host: raise URLError('no host given') - if request.has_data(): # POST - data = request.get_data() + if request.data is not None: # POST + data = request.data if not request.has_header('Content-type'): request.add_unredirected_header( 'Content-type', @@ -1022,7 +1006,7 @@ sel_host = host if request.has_proxy(): - scheme, sel = splittype(request.get_selector()) + scheme, sel = splittype(request.selector) sel_host, sel_path = splithost(sel) if not request.has_header('Host'): request.add_unredirected_header('Host', sel_host) @@ -1034,16 +1018,11 @@ return request def do_open(self, http_class, req): - """Return an addinfourl object for the request, using http_class. + """Return an HTTPResponse object for the request, using http_class. http_class must implement the HTTPConnection API from http.client. - The addinfourl return value is a file-like object. It also - has methods and attributes including: - - info(): return a email Message object for the headers - - geturl(): return the original request URL - - code: HTTP status code """ - host = req.get_host() + host = req.host if not host: raise URLError('no host given') @@ -1061,19 +1040,21 @@ # So make sure the connection gets closed after the (only) # request. headers["Connection"] = "close" - headers = dict( - (name.title(), val) for name, val in headers.items()) + headers = dict((name.title(), val) for name, val in headers.items()) try: - h.request(req.get_method(), req.get_selector(), req.data, headers) - r = h.getresponse() - except socket.error as err: # XXX what error? + h.request(req.get_method(), req.selector, req.data, headers) + r = h.getresponse() # an HTTPResponse instance + except socket.error as err: raise URLError(err) -## resp = addinfourl(r.fp, r.msg, req.get_full_url()) - resp = addinfourl(r, r.msg, req.get_full_url()) - resp.code = r.status - resp.msg = r.reason - return resp + r.url = req.full_url + # This line replaces the .msg attribute of the HTTPResponse + # with .headers, because urllib clients expect the response to + # have the reason in .msg. It would be good to mark this + # attribute is deprecated and get then to use info() or + # .headers. + r.msg = r.reason + return r class HTTPHandler(AbstractHTTPHandler): @@ -1111,7 +1092,7 @@ class UnknownHandler(BaseHandler): def unknown_open(self, req): - type = req.get_type() + type = req.type raise URLError('unknown url type: %s' % type) def parse_keqv_list(l): @@ -1170,7 +1151,7 @@ class FileHandler(BaseHandler): # Use local file or FTP depending on form of URL def file_open(self, req): - url = req.get_selector() + url = req.selector if url[:2] == '//' and url[2:3] != '/': req.type = 'ftp' return self.parent.open(req) @@ -1192,8 +1173,8 @@ def open_local_file(self, req): import email.utils import mimetypes - host = req.get_host() - file = req.get_selector() + host = req.host + file = req.selector localfile = url2pathname(file) try: stats = os.stat(localfile) @@ -1223,7 +1204,7 @@ def ftp_open(self, req): import ftplib import mimetypes - host = req.get_host() + host = req.host if not host: raise URLError('ftp error: no host given') host, port = splitport(host) @@ -1246,7 +1227,7 @@ host = socket.gethostbyname(host) except socket.error as msg: raise URLError(msg) - path, attrs = splitattr(req.get_selector()) + path, attrs = splitattr(req.selector) dirs = path.split('/') dirs = list(map(unquote, dirs)) dirs, file = dirs[:-1], dirs[-1] @@ -1262,13 +1243,13 @@ type = value.upper() fp, retrlen = fw.retrfile(file, type) headers = "" - mtype = mimetypes.guess_type(req.get_full_url())[0] + mtype = mimetypes.guess_type(req.full_url)[0] if mtype: headers += "Content-type: %s\n" % mtype if retrlen is not None and retrlen >= 0: headers += "Content-length: %d\n" % retrlen headers = email.message_from_string(headers) - return addinfourl(fp, headers, req.get_full_url()) + return addinfourl(fp, headers, req.full_url) except ftplib.all_errors as msg: exc = URLError('ftp error: %s' % msg) raise exc.with_traceback(sys.exc_info()[2]) @@ -1581,10 +1562,6 @@ else: auth = None http_conn = connection_factory(host) - # XXX We should fix urllib so that it works with HTTP/1.1. - http_conn._http_vsn = 10 - http_conn._http_vsn_str = "HTTP/1.0" - headers = {} if proxy_auth: headers["Proxy-Authorization"] = "Basic %s" % proxy_auth @@ -2183,18 +2160,18 @@ """ proxies = {} try: - import _winreg + import winreg except ImportError: # Std module, so should be around - but you never know! return proxies try: - internetSettings = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, + internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\Microsoft\Windows\CurrentVersion\Internet Settings') - proxyEnable = _winreg.QueryValueEx(internetSettings, + proxyEnable = winreg.QueryValueEx(internetSettings, 'ProxyEnable')[0] if proxyEnable: # Returned as Unicode but problems if not converted to ASCII - proxyServer = str(_winreg.QueryValueEx(internetSettings, + proxyServer = str(winreg.QueryValueEx(internetSettings, 'ProxyServer')[0]) if '=' in proxyServer: # Per-protocol settings @@ -2231,17 +2208,17 @@ def proxy_bypass_registry(host): try: - import _winreg + import winreg import re except ImportError: # Std modules, so should be around - but you never know! return 0 try: - internetSettings = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, + internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'Software\Microsoft\Windows\CurrentVersion\Internet Settings') - proxyEnable = _winreg.QueryValueEx(internetSettings, + proxyEnable = winreg.QueryValueEx(internetSettings, 'ProxyEnable')[0] - proxyOverride = str(_winreg.QueryValueEx(internetSettings, + proxyOverride = str(winreg.QueryValueEx(internetSettings, 'ProxyOverride')[0]) # ^^^^ Returned as Unicode but problems if not converted to ASCII except WindowsError: Modified: python/branches/py3k-short-float-repr/Lib/xmlrpc/client.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/xmlrpc/client.py (original) +++ python/branches/py3k-short-float-repr/Lib/xmlrpc/client.py Sun Apr 5 01:04:14 2009 @@ -1316,7 +1316,7 @@ transport = Transport(use_datetime=use_datetime) self.__transport = transport - self.__encoding = encoding + self.__encoding = encoding or 'utf-8' self.__verbose = verbose self.__allow_none = allow_none @@ -1324,7 +1324,7 @@ # call a method on the remote server request = dumps(params, methodname, encoding=self.__encoding, - allow_none=self.__allow_none) + allow_none=self.__allow_none).encode(self.__encoding) response = self.__transport.request( self.__host, Modified: python/branches/py3k-short-float-repr/Lib/xmlrpc/server.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/xmlrpc/server.py (original) +++ python/branches/py3k-short-float-repr/Lib/xmlrpc/server.py Sun Apr 5 01:04:14 2009 @@ -163,7 +163,7 @@ self.funcs = {} self.instance = None self.allow_none = allow_none - self.encoding = encoding + self.encoding = encoding or 'utf-8' def register_instance(self, instance, allow_dotted_names=False): """Registers an instance to respond to XML-RPC requests. @@ -266,7 +266,7 @@ encoding=self.encoding, allow_none=self.allow_none, ) - return response + return response.encode(self.encoding) def system_listMethods(self): """system.listMethods() => ['add', 'subtract', 'multiple'] @@ -473,8 +473,6 @@ self.end_headers() else: - # Got a valid XML RPC response; convert to bytes first - response = response.encode("utf-8") self.send_response(200) self.send_header("Content-type", "text/xml") self.send_header("Content-length", str(len(response))) @@ -551,7 +549,9 @@ print('Content-Type: text/xml') print('Content-Length: %d' % len(response)) print() - sys.stdout.write(response) + sys.stdout.flush() + sys.stdout.buffer.write(response) + sys.stdout.buffer.flush() def handle_get(self): """Handle a single HTTP GET request. @@ -569,11 +569,14 @@ 'message' : message, 'explain' : explain } + response = response.encode('utf-8') print('Status: %d %s' % (code, message)) - print('Content-Type: text/html') + print('Content-Type: %s' % http.server.DEFAULT_ERROR_CONTENT_TYPE) print('Content-Length: %d' % len(response)) print() - sys.stdout.write(response) + sys.stdout.flush() + sys.stdout.buffer.write(response) + sys.stdout.buffer.flush() def handle_request(self, request_text = None): """Handle a single XML-RPC request passed through a CGI post method. @@ -588,8 +591,12 @@ self.handle_get() else: # POST data is normally available through stdin + try: + length = int(os.environ.get('CONTENT_LENGTH', None)) + except (ValueError, TypeError): + length = -1 if request_text is None: - request_text = sys.stdin.read() + request_text = sys.stdin.read(length) self.handle_xmlrpc(request_text) @@ -810,12 +817,12 @@ self.report_404() return - response = self.server.generate_html_documentation() + response = self.server.generate_html_documentation().encode('utf-8') self.send_response(200) self.send_header("Content-type", "text/html") self.send_header("Content-length", str(len(response))) self.end_headers() - self.wfile.write(response.encode()) + self.wfile.write(response) # shut down the connection self.wfile.flush() @@ -848,12 +855,14 @@ documentation. """ - response = self.generate_html_documentation() + response = self.generate_html_documentation().encode('utf-8') print('Content-Type: text/html') print('Content-Length: %d' % len(response)) print() - sys.stdout.write(response) + sys.stdout.flush() + sys.stdout.buffer.write(response) + sys.stdout.buffer.flush() def __init__(self): CGIXMLRPCRequestHandler.__init__(self) Modified: python/branches/py3k-short-float-repr/Mac/BuildScript/README.txt ============================================================================== --- python/branches/py3k-short-float-repr/Mac/BuildScript/README.txt (original) +++ python/branches/py3k-short-float-repr/Mac/BuildScript/README.txt Sun Apr 5 01:04:14 2009 @@ -37,6 +37,17 @@ * When done the script will tell you where the DMG image is (by default somewhere in ``/tmp/_py``). +Building a 4-way universal installer +.................................... + +It is also possible to build a 4-way universal installer that runs on +OSX Leopard or later:: + + $ ./build-installer.py --dep-target=10.5 --universal-archs=all --sdk=/ + +This requires that the deployment target is 10.5 (or later), and hence +also that your building on at least OSX 10.5. + Testing ------- Modified: python/branches/py3k-short-float-repr/Mac/BuildScript/build-installer.py ============================================================================== --- python/branches/py3k-short-float-repr/Mac/BuildScript/build-installer.py (original) +++ python/branches/py3k-short-float-repr/Mac/BuildScript/build-installer.py Sun Apr 5 01:04:14 2009 @@ -2,7 +2,8 @@ """ This script is used to build the "official unofficial" universal build on Mac OS X. It requires Mac OS X 10.4, Xcode 2.2 and the 10.4u SDK to do its -work. +work. 64-bit or four-way universal builds require at least OS X 10.5 and +the 10.5 SDK. Please ensure that this script keeps working with Python 2.3, to avoid bootstrap issues (/usr/bin/python is Python 2.3 on OSX 10.4) @@ -63,7 +64,15 @@ SDKPATH = "/Developer/SDKs/MacOSX10.4u.sdk" #SDKPATH = "/" -ARCHLIST = ('i386', 'ppc',) +universal_opts_map = { '32-bit': ('i386', 'ppc',), + '64-bit': ('x86_64', 'ppc64',), + 'all': ('i386', 'ppc', 'x86_64', 'ppc64',) } + +UNIVERSALOPTS = tuple(universal_opts_map.keys()) + +UNIVERSALARCHS = '32-bit' + +ARCHLIST = universal_opts_map[UNIVERSALARCHS] # Source directory (asume we're in Mac/BuildScript) SRCDIR = os.path.dirname( @@ -72,6 +81,9 @@ os.path.abspath(__file__ )))) +# $MACOSX_DEPLOYMENT_TARGET -> minimum OS X level +DEPTARGET = '10.3' + USAGE = textwrap.dedent("""\ Usage: build_python [options] @@ -82,62 +94,67 @@ --third-party=DIR: Store third-party sources here (default: %(DEPSRC)r) --sdk-path=DIR: Location of the SDK (default: %(SDKPATH)r) --src-dir=DIR: Location of the Python sources (default: %(SRCDIR)r) + --dep-target=10.n OS X deployment target (default: %(DEPTARGET)r) + --universal-archs=x universal architectures (options: %(UNIVERSALOPTS)r, default: %(UNIVERSALARCHS)r) """)% globals() # Instructions for building libraries that are necessary for building a # batteries included python. -LIBRARY_RECIPES = [ - dict( - name="Bzip2 1.0.4", - url="http://www.bzip.org/1.0.4/bzip2-1.0.4.tar.gz", - checksum='fc310b254f6ba5fbb5da018f04533688', - configure=None, - install='make install PREFIX=%s/usr/local/ CFLAGS="-arch %s -isysroot %s"'%( - shellQuote(os.path.join(WORKDIR, 'libraries')), - ' -arch '.join(ARCHLIST), - SDKPATH, - ), - ), - dict( - name="ZLib 1.2.3", - url="http://www.gzip.org/zlib/zlib-1.2.3.tar.gz", - checksum='debc62758716a169df9f62e6ab2bc634', - configure=None, - install='make install prefix=%s/usr/local/ CFLAGS="-arch %s -isysroot %s"'%( - shellQuote(os.path.join(WORKDIR, 'libraries')), - ' -arch '.join(ARCHLIST), - SDKPATH, - ), - ), - dict( - # Note that GNU readline is GPL'd software - name="GNU Readline 5.1.4", - url="http://ftp.gnu.org/pub/gnu/readline/readline-5.1.tar.gz" , - checksum='7ee5a692db88b30ca48927a13fd60e46', - patchlevel='0', - patches=[ - # The readline maintainers don't do actual micro releases, but - # just ship a set of patches. - 'http://ftp.gnu.org/pub/gnu/readline/readline-5.1-patches/readline51-001', - 'http://ftp.gnu.org/pub/gnu/readline/readline-5.1-patches/readline51-002', - 'http://ftp.gnu.org/pub/gnu/readline/readline-5.1-patches/readline51-003', - 'http://ftp.gnu.org/pub/gnu/readline/readline-5.1-patches/readline51-004', - ] - ), - - dict( - name="SQLite 3.6.11", - url="http://www.sqlite.org/sqlite-3.6.11.tar.gz", - checksum='7ebb099696ab76cc6ff65dd496d17858', - configure_pre=[ - '--enable-threadsafe', - '--enable-tempstore', - '--enable-shared=no', - '--enable-static=yes', - '--disable-tcl', - ] - ), +# [The recipes are defined here for convenience but instantiated later after +# command line options have been processed.] +def library_recipes(): + return [ + dict( + name="Bzip2 1.0.4", + url="http://www.bzip.org/1.0.4/bzip2-1.0.4.tar.gz", + checksum='fc310b254f6ba5fbb5da018f04533688', + configure=None, + install='make install PREFIX=%s/usr/local/ CFLAGS="-arch %s -isysroot %s"'%( + shellQuote(os.path.join(WORKDIR, 'libraries')), + ' -arch '.join(ARCHLIST), + SDKPATH, + ), + ), + dict( + name="ZLib 1.2.3", + url="http://www.gzip.org/zlib/zlib-1.2.3.tar.gz", + checksum='debc62758716a169df9f62e6ab2bc634', + configure=None, + install='make install prefix=%s/usr/local/ CFLAGS="-arch %s -isysroot %s"'%( + shellQuote(os.path.join(WORKDIR, 'libraries')), + ' -arch '.join(ARCHLIST), + SDKPATH, + ), + ), + dict( + # Note that GNU readline is GPL'd software + name="GNU Readline 5.1.4", + url="http://ftp.gnu.org/pub/gnu/readline/readline-5.1.tar.gz" , + checksum='7ee5a692db88b30ca48927a13fd60e46', + patchlevel='0', + patches=[ + # The readline maintainers don't do actual micro releases, but + # just ship a set of patches. + 'http://ftp.gnu.org/pub/gnu/readline/readline-5.1-patches/readline51-001', + 'http://ftp.gnu.org/pub/gnu/readline/readline-5.1-patches/readline51-002', + 'http://ftp.gnu.org/pub/gnu/readline/readline-5.1-patches/readline51-003', + 'http://ftp.gnu.org/pub/gnu/readline/readline-5.1-patches/readline51-004', + ] + ), + + dict( + name="SQLite 3.6.11", + url="http://www.sqlite.org/sqlite-3.6.11.tar.gz", + checksum='7ebb099696ab76cc6ff65dd496d17858', + configure_pre=[ + '--enable-threadsafe', + '--enable-tempstore', + '--enable-shared=no', + '--enable-static=yes', + '--disable-tcl', + ] + ), dict( name="NCurses 5.5", @@ -170,7 +187,6 @@ ), ] - # Instructions for building packages inside the .mpkg. PKG_RECIPES = [ dict( @@ -205,8 +221,8 @@ source="/usr/local/bin", readme="""\ This package installs the unix tools in /usr/local/bin for - compatibility with older releases of MacPython. This package - is not necessary to use MacPython. + compatibility with older releases of Python. This package + is not necessary to use Python. """, required=False, selected='unselected', @@ -231,7 +247,7 @@ long_name="Shell profile updater", readme="""\ This packages updates your shell profile to make sure that - the MacPython tools are found by your shell in preference of + the Python tools are found by your shell in preference of the system provided Python tools. If you don't install this package you'll have to add @@ -321,14 +337,16 @@ """ Parse arguments and update global settings. """ - global WORKDIR, DEPSRC, SDKPATH, SRCDIR + global WORKDIR, DEPSRC, SDKPATH, SRCDIR, DEPTARGET + global UNIVERSALOPTS, UNIVERSALARCHS, ARCHLIST if args is None: args = sys.argv[1:] try: options, args = getopt.getopt(args, '?hb', - [ 'build-dir=', 'third-party=', 'sdk-path=' , 'src-dir=']) + [ 'build-dir=', 'third-party=', 'sdk-path=' , 'src-dir=', + 'dep-target=', 'universal-archs=', 'help' ]) except getopt.error, msg: print msg sys.exit(1) @@ -338,7 +356,7 @@ sys.exit(1) for k, v in options: - if k in ('-h', '-?'): + if k in ('-h', '-?', '--help'): print USAGE sys.exit(0) @@ -354,6 +372,16 @@ elif k in ('--src-dir',): SRCDIR=v + elif k in ('--dep-target', ): + DEPTARGET=v + + elif k in ('--universal-archs', ): + if v in UNIVERSALOPTS: + UNIVERSALARCHS = v + ARCHLIST = universal_opts_map[UNIVERSALARCHS] + else: + raise NotImplementedError, v + else: raise NotImplementedError, k @@ -366,7 +394,9 @@ print " * Source directory:", SRCDIR print " * Build directory: ", WORKDIR print " * SDK location: ", SDKPATH - print " * third-party source:", DEPSRC + print " * Third-party source:", DEPSRC + print " * Deployment target:", DEPTARGET + print " * Universal architectures:", ARCHLIST print "" @@ -476,6 +506,7 @@ print "Using local copy of %s"%(name,) else: + print "Did not find local copy of %s"%(name,) print "Downloading %s"%(name,) downloadURL(url, sourceArchive) print "Archive for %s stored as %s"%(name, sourceArchive) @@ -566,7 +597,7 @@ os.makedirs(os.path.join(universal, 'usr', 'local', 'lib')) os.makedirs(os.path.join(universal, 'usr', 'local', 'include')) - for recipe in LIBRARY_RECIPES: + for recipe in library_recipes(): buildRecipe(recipe, universal, ARCHLIST) @@ -590,7 +621,7 @@ def buildPython(): - print "Building a universal python" + print "Building a universal python for %s architectures" % UNIVERSALARCHS buildDir = os.path.join(WORKDIR, '_bld', 'python') rootDir = os.path.join(WORKDIR, '_root') @@ -613,10 +644,19 @@ # several paths. version = getVersion() + # Since the extra libs are not in their installed framework location + # during the build, augment the library path so that the interpreter + # will find them during its extension import sanity checks. + os.environ['DYLD_LIBRARY_PATH'] = os.path.join(WORKDIR, + 'libraries', 'usr', 'local', 'lib') print "Running configure..." - runCommand("%s -C --enable-framework --enable-universalsdk=%s LDFLAGS='-g -L%s/libraries/usr/local/lib' OPT='-g -O3 -I%s/libraries/usr/local/include' 2>&1"%( - shellQuote(os.path.join(SRCDIR, 'configure')), - shellQuote(SDKPATH), shellQuote(WORKDIR)[1:-1], + runCommand("%s -C --enable-framework --enable-universalsdk=%s " + "--with-universal-archs=%s --with-computed-gotos " + "LDFLAGS='-g -L%s/libraries/usr/local/lib' " + "OPT='-g -O3 -I%s/libraries/usr/local/include' 2>&1"%( + shellQuote(os.path.join(SRCDIR, 'configure')), shellQuote(SDKPATH), + UNIVERSALARCHS, + shellQuote(WORKDIR)[1:-1], shellQuote(WORKDIR)[1:-1])) print "Running make" @@ -630,6 +670,7 @@ runCommand("make frameworkinstallextras DESTDIR=%s"%( shellQuote(rootDir))) + del os.environ['DYLD_LIBRARY_PATH'] print "Copying required shared libraries" if os.path.exists(os.path.join(WORKDIR, 'libraries', 'Library')): runCommand("mv %s/* %s"%( @@ -704,7 +745,7 @@ data = fileContents(inPath) data = data.replace('$FULL_VERSION', getFullVersion()) data = data.replace('$VERSION', getVersion()) - data = data.replace('$MACOSX_DEPLOYMENT_TARGET', '10.3 or later') + data = data.replace('$MACOSX_DEPLOYMENT_TARGET', ''.join((DEPTARGET, ' or later'))) data = data.replace('$ARCHITECTURES', "i386, ppc") data = data.replace('$INSTALL_SIZE', installSize()) @@ -784,9 +825,9 @@ vers = getFullVersion() major, minor = map(int, getVersion().split('.', 2)) pl = Plist( - CFBundleGetInfoString="MacPython.%s %s"%(pkgname, vers,), - CFBundleIdentifier='org.python.MacPython.%s'%(pkgname,), - CFBundleName='MacPython.%s'%(pkgname,), + CFBundleGetInfoString="Python.%s %s"%(pkgname, vers,), + CFBundleIdentifier='org.python.Python.%s'%(pkgname,), + CFBundleName='Python.%s'%(pkgname,), CFBundleShortVersionString=vers, IFMajorVersion=major, IFMinorVersion=minor, @@ -807,7 +848,7 @@ pl = Plist( IFPkgDescriptionDescription=readme, - IFPkgDescriptionTitle=recipe.get('long_name', "MacPython.%s"%(pkgname,)), + IFPkgDescriptionTitle=recipe.get('long_name', "Python.%s"%(pkgname,)), IFPkgDescriptionVersion=vers, ) writePlist(pl, os.path.join(packageContents, 'Resources', 'Description.plist')) @@ -822,9 +863,9 @@ major, minor = map(int, getVersion().split('.', 2)) pl = Plist( - CFBundleGetInfoString="MacPython %s"%(vers,), - CFBundleIdentifier='org.python.MacPython', - CFBundleName='MacPython', + CFBundleGetInfoString="Python %s"%(vers,), + CFBundleIdentifier='org.python.Python', + CFBundleName='Python', CFBundleShortVersionString=vers, IFMajorVersion=major, IFMinorVersion=minor, @@ -858,7 +899,7 @@ shutil.rmtree(outdir) os.mkdir(outdir) - pkgroot = os.path.join(outdir, 'MacPython.mpkg', 'Contents') + pkgroot = os.path.join(outdir, 'Python.mpkg', 'Contents') pkgcontents = os.path.join(pkgroot, 'Packages') os.makedirs(pkgcontents) for recipe in PKG_RECIPES: @@ -875,7 +916,7 @@ makeMpkgPlist(os.path.join(pkgroot, 'Info.plist')) pl = Plist( - IFPkgDescriptionTitle="Universal MacPython", + IFPkgDescriptionTitle="Python", IFPkgDescriptionVersion=getVersion(), ) @@ -915,10 +956,32 @@ imagepath = imagepath + '.dmg' os.mkdir(outdir) - runCommand("hdiutil create -volname 'Universal MacPython %s' -srcfolder %s %s"%( - getFullVersion(), + volname='Python %s'%(getFullVersion()) + runCommand("hdiutil create -format UDRW -volname %s -srcfolder %s %s"%( + shellQuote(volname), shellQuote(os.path.join(WORKDIR, 'installer')), - shellQuote(imagepath))) + shellQuote(imagepath + ".tmp.dmg" ))) + + + if not os.path.exists(os.path.join(WORKDIR, "mnt")): + os.mkdir(os.path.join(WORKDIR, "mnt")) + runCommand("hdiutil attach %s -mountroot %s"%( + shellQuote(imagepath + ".tmp.dmg"), shellQuote(os.path.join(WORKDIR, "mnt")))) + + # Custom icon for the DMG, shown when the DMG is mounted. + shutil.copy("../Icons/Disk Image.icns", + os.path.join(WORKDIR, "mnt", volname, ".VolumeIcon.icns")) + runCommand("/Developer/Tools/SetFile -a C %s/"%( + shellQuote(os.path.join(WORKDIR, "mnt", volname)),)) + + runCommand("hdiutil detach %s"%(shellQuote(os.path.join(WORKDIR, "mnt", volname)))) + + setIcon(imagepath + ".tmp.dmg", "../Icons/Disk Image.icns") + runCommand("hdiutil convert %s -format UDZO -o %s"%( + shellQuote(imagepath + ".tmp.dmg"), shellQuote(imagepath))) + setIcon(imagepath, "../Icons/Disk Image.icns") + + os.unlink(imagepath + ".tmp.dmg") return imagepath @@ -946,7 +1009,7 @@ parseOptions() checkEnvironment() - os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.3' + os.environ['MACOSX_DEPLOYMENT_TARGET'] = DEPTARGET if os.path.exists(WORKDIR): shutil.rmtree(WORKDIR) @@ -957,7 +1020,18 @@ # Now build python itself buildPython() + + # And then build the documentation + # Remove the Deployment Target from the shell + # environment, it's no longer needed and + # an unexpected build target can cause problems + # when Sphinx and its dependencies need to + # be (re-)installed. + del os.environ['MACOSX_DEPLOYMENT_TARGET'] buildPythonDocs() + + + # Prepare the applications folder fn = os.path.join(WORKDIR, "_root", "Applications", "Python %s"%(getVersion(),), "Update Shell Profile.command") patchScript("scripts/postflight.patch-profile", fn) @@ -982,13 +1056,6 @@ print >> fp, "# By:", pwd.getpwuid(os.getuid()).pw_gecos fp.close() - # Custom icon for the DMG, shown when the DMG is mounted. - # XXX: Code is diabled because it doesn't actually work :-( -# shutil.copy("../Icons/Disk Image.icns", -# os.path.join(WORKDIR, "installer", ".VolumeIcon.icns")) -# os.system("/Developer/Tools/SetFile -a C %s"%( -# os.path.join(WORKDIR, "installer", ".VolumeIcon.icns"))) - setIcon(os.path.join(WORKDIR, "installer"), "../Icons/Disk Image.icns") # And copy it to a DMG Modified: python/branches/py3k-short-float-repr/Mac/BuildScript/resources/ReadMe.txt ============================================================================== --- python/branches/py3k-short-float-repr/Mac/BuildScript/resources/ReadMe.txt (original) +++ python/branches/py3k-short-float-repr/Mac/BuildScript/resources/ReadMe.txt Sun Apr 5 01:04:14 2009 @@ -19,9 +19,11 @@ that open up specific Macintosh technologies to Python programs. The installer puts the applications in "Python $VERSION" -in your Applications folder, command-line tools in -/usr/local/bin and the underlying machinery in -$PYTHONFRAMEWORKINSTALLDIR. +in your Applications folder, and the underlying machinery in +$PYTHONFRAMEWORKINSTALLDIR. It can optionally place +links to the command-line tools in /usr/local as well, +by default you have to add the "bin" directory inside +the framework to you shell's search path. More information on MacPython can be found at http://www.python.org/download/mac/. Modified: python/branches/py3k-short-float-repr/Mac/Makefile.in ============================================================================== --- python/branches/py3k-short-float-repr/Mac/Makefile.in (original) +++ python/branches/py3k-short-float-repr/Mac/Makefile.in Sun Apr 5 01:04:14 2009 @@ -14,6 +14,7 @@ LDFLAGS=@LDFLAGS@ FRAMEWORKUNIXTOOLSPREFIX=@FRAMEWORKUNIXTOOLSPREFIX@ PYTHONFRAMEWORK=@PYTHONFRAMEWORK@ +PYTHONFRAMEWORKIDENTIFIER=@PYTHONFRAMEWORKIDENTIFIER@ # These are normally glimpsed from the previous set @@ -206,6 +207,12 @@ done; \ done $(INSTALL_PROGRAM) $(STRIPFLAG) $(BUILDPYTHON) "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)" + sed -e "s!%bundleid%!$(PYTHONFRAMEWORKIDENTIFIER)!g" \ + -e "s!%version%!`$(RUNSHARED) $(BUILDPYTHON) \ + -c 'import platform; print(platform.python_version())'`!g" \ + < "$(DESTDIR)$(APPINSTALLDIR)/Contents/Info.plist.in" \ + > "$(DESTDIR)$(APPINSTALLDIR)/Contents/Info.plist" + rm "$(DESTDIR)$(APPINSTALLDIR)/Contents/Info.plist.in" install_Python4way: install_Python lipo -extract i386 -extract ppc7400 -output "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)-32" "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)" Modified: python/branches/py3k-short-float-repr/Mac/PythonLauncher/FileSettings.m ============================================================================== --- python/branches/py3k-short-float-repr/Mac/PythonLauncher/FileSettings.m (original) +++ python/branches/py3k-short-float-repr/Mac/PythonLauncher/FileSettings.m Sun Apr 5 01:04:14 2009 @@ -267,14 +267,14 @@ [script length]-[[script lastPathComponent] length]]; if (honourhashbang && - (fp=fopen([script cString], "r")) && + (fp=fopen([script fileSystemRepresentation], "r")) && fgets(hashbangbuf, sizeof(hashbangbuf), fp) && strncmp(hashbangbuf, "#!", 2) == 0 && (p=strchr(hashbangbuf, '\n'))) { *p = '\0'; p = hashbangbuf + 2; while (*p == ' ') p++; - cur_interp = [NSString stringWithCString: p]; + cur_interp = [NSString stringWithUTF8String: p]; } if (!cur_interp) cur_interp = interpreter; Modified: python/branches/py3k-short-float-repr/Mac/Resources/app/Info.plist.in ============================================================================== --- python/branches/py3k-short-float-repr/Mac/Resources/app/Info.plist.in (original) +++ python/branches/py3k-short-float-repr/Mac/Resources/app/Info.plist.in Sun Apr 5 01:04:14 2009 @@ -20,7 +20,7 @@ CFBundleExecutable Python CFBundleGetInfoString - @VERSION@, (c) 2004 Python Software Foundation. + %version%, (c) 2004-2009 Python Software Foundation. CFBundleHelpBookFolder Documentation @@ -33,21 +33,21 @@ CFBundleIconFile PythonInterpreter.icns CFBundleIdentifier - @PYTHONFRAMEWORKIDENTIFIER at .app + %bundleid% CFBundleInfoDictionaryVersion 6.0 CFBundleLongVersionString - @VERSION@, (c) 2004-2008 Python Software Foundation. + %version%, (c) 2004-2009 Python Software Foundation. CFBundleName Python CFBundlePackageType APPL CFBundleShortVersionString - @VERSION@ + %version% CFBundleSignature PytX CFBundleVersion - @VERSION@ + %version% CSResourcesFileMapped LSRequiresCarbon Modified: python/branches/py3k-short-float-repr/Makefile.pre.in ============================================================================== --- python/branches/py3k-short-float-repr/Makefile.pre.in (original) +++ python/branches/py3k-short-float-repr/Makefile.pre.in Sun Apr 5 01:04:14 2009 @@ -193,15 +193,16 @@ # Used of signalmodule.o is not available SIGNAL_OBJS= @SIGNAL_OBJS@ -IO_H= Modules/_iomodule.h +IO_H= Modules/_io/_iomodule.h IO_OBJS= \ - Modules/io.o \ - Modules/_iobase.o \ - Modules/_fileio.o \ - Modules/_bufferedio.o \ - Modules/_textio.o \ - Modules/_bytesio.o + Modules/_io/_iomodule.o \ + Modules/_io/iobase.o \ + Modules/_io/fileio.o \ + Modules/_io/bufferedio.o \ + Modules/_io/textio.o \ + Modules/_io/bytesio.o \ + Modules/_io/stringio.o ########################################################################## # Grammar Modified: python/branches/py3k-short-float-repr/Misc/ACKS ============================================================================== --- python/branches/py3k-short-float-repr/Misc/ACKS (original) +++ python/branches/py3k-short-float-repr/Misc/ACKS Sun Apr 5 01:04:14 2009 @@ -167,6 +167,7 @@ Raghuram Devarakonda Toby Dickenson Mark Dickinson +Jack Diederich Humberto Diogenes Yves Dionne Daniel Dittmar @@ -257,6 +258,7 @@ Jonathan Giddy Johannes Gijsbers Michael Gilfix +Tim Golden Chris Gonnerman David Goodger Hans de Graaff @@ -411,6 +413,7 @@ Inyeol Lee Thomas Lee Christopher Lee +Tennessee Leeuwenburg Luc Lefebvre Kip Lehman Joerg Lehmann @@ -480,6 +483,7 @@ Chad Miller Jay T. Miller Roman Milner +Andrii V. Mishkovskyi Dustin J. Mitchell Dom Mitchell Doug Moen @@ -490,6 +494,8 @@ Sjoerd Mullender Sape Mullender Michael Muller +R. David Murray +Piotr Meyer John Nagle Takahiro Nakayama Travers Naran @@ -686,7 +692,9 @@ Nathan Sullivan Mark Summerfield Hisao Suzuki +Andrew Svetlov Kalle Svensson +Andrew Svetlov Paul Swartz Thenault Sylvain Geoff Talvola @@ -792,4 +800,3 @@ Uwe Zessin Tarek Ziad? Peter ?strand -Jesse Noller Modified: python/branches/py3k-short-float-repr/Misc/NEWS ============================================================================== --- python/branches/py3k-short-float-repr/Misc/NEWS (original) +++ python/branches/py3k-short-float-repr/Misc/NEWS Sun Apr 5 01:04:14 2009 @@ -7,13 +7,33 @@ What's New in Python 3.1 alpha 2? ================================= -*Release date: XXX* +*Release date: 2009-4-4* Core and Builtins ----------------- +- Implement PEP 378, Format Specifier for Thousands Separator, for + integers. + +- Issue #5666: Py_BuildValue's 'c' code should create byte strings. + +- Issue #5499: The 'c' code for argument parsing functions now only accepts a + byte, and the 'C' code only accepts a unicode character. + +- Issue #1665206: Remove the last eager import in _warnings.c and make it lazy. + +- Fix a segfault when running test_exceptions with coverage, caused by + insufficient checks in accessors of Exception.__context__. + +- Issue #5604: non-ASCII characters in module name passed to + imp.find_module() were converted to UTF-8 while the path is + converted to the default filesystem encoding, causing nonsense. + - Issue #5126: str.isprintable() returned False for space characters. +- Issue #4865: On MacOSX /Library/Python/2.7/site-packages is added to + the end sys.path, for compatibility with the system install of Python. + - Issue #4688: Add a heuristic so that tuples and dicts containing only untrackable objects are not tracked by the garbage collector. This can reduce the size of collections and therefore the garbage collection overhead @@ -40,9 +60,43 @@ - Issue #5392: when a very low recursion limit was set, the interpreter would abort with a fatal error after the recursion limit was hit twice. +- Issue #3845: In PyRun_SimpleFileExFlags avoid invalid memory access with + short file names. + +- Py_DECREF: Add `do { ... } while (0)' to avoid compiler warnings. + Library ------- +- Issue 2625: added missing items() call to the for loop in + mailbox.MH.get_message(). + +- Issue #5640: Fix _multibytecodec so that CJK codecs don't repeat + error substitutions from non-strict codec error callbacks in + incrementalencoder and StreamWriter. + +- Issue #5656: Fix the coverage reporting when running the test suite with + the -T argument. + +- Issue #5647: MutableSet.__iand__() no longer mutates self during iteration. + +- Issue #5624: Fix the _winreg module name still used in several modules. + +- Issue #5628: Fix io.TextIOWrapper.read() with a unreadable buffer. + +- Issue #5619: Multiprocessing children disobey the debug flag and causes + popups on windows buildbots. Patch applied to work around this issue. + +- Issue #5400: Added patch for multiprocessing on netbsd compilation/support + +- Issue #5387: Fixed mmap.move crash by integer overflow. + +- Issue #5261: Patch multiprocessing's semaphore.c to support context + manager use: "with multiprocessing.Lock()" works now. + +- Issue #5236: Change time.strptime() to only take strings. Didn't work with + bytes already but the failure was non-obvious. + - Issue #5177: Multiprocessing's SocketListener class now uses socket.SO_REUSEADDR on all connections so that the user no longer needs to wait 120 seconds for the socket to expire. @@ -75,6 +129,8 @@ Extension Modules ----------------- +- Issue #5391: mmap now deals exclusively with bytes. + - Issue #5463: In struct module, remove deprecated overflow wrapping when packing an integer: struct.pack('=L', -1) now raises struct.error instead of returning b'\xff\xff\xff\xff'. The @@ -259,6 +315,17 @@ Library ------- +- Issue #1665206 (partially): Move imports in cgitb to the top of the module + instead of performing them in functions. Helps prevent import deadlocking in + threads. + +- Issue #2522: locale.format now checks its first argument to ensure it has + been passed only one pattern, avoiding mysterious errors where it appeared + that it was failing to do localization. + +- Issue #5583: Added optional Extensions in Distutils. Initial patch by Georg + Brandl. + - Issue #1222: locale.format() bug when the thousands separator is a space character. @@ -694,9 +761,15 @@ buffer. +- Issue #5228: Make functools.partial objects can now be pickled. + Tests ----- +- regrtest no longer treats ImportError as equivalent to SkipTest. Imports + that should cause a test to be skipped are now done using import_module + from test support, which does the conversion. + - Issue #5083: New 'gui' resource for regrtest. Modified: python/branches/py3k-short-float-repr/Misc/RPM/python-3.1.spec ============================================================================== --- python/branches/py3k-short-float-repr/Misc/RPM/python-3.1.spec (original) +++ python/branches/py3k-short-float-repr/Misc/RPM/python-3.1.spec Sun Apr 5 01:04:14 2009 @@ -34,7 +34,7 @@ %define name python #--start constants-- -%define version 3.1a1 +%define version 3.1a2 %define libver 3.1 #--end constants-- %define release 1pydotorg Modified: python/branches/py3k-short-float-repr/Modules/Setup.dist ============================================================================== --- python/branches/py3k-short-float-repr/Modules/Setup.dist (original) +++ python/branches/py3k-short-float-repr/Modules/Setup.dist Sun Apr 5 01:04:14 2009 @@ -114,7 +114,7 @@ _weakref _weakref.c # weak references # Standard I/O baseline -_io io.c _iobase.c _fileio.c _bytesio.c _bufferedio.c _textio.c _stringio.c +_io -I$(srcdir)/Modules/_io _io/_iomodule.c _io/iobase.c _io/fileio.c _io/bytesio.c _io/bufferedio.c _io/textio.c _io/stringio.c # The zipimport module is always imported at startup. Having it as a # builtin module avoids some bootstrapping problems and reduces overhead. Deleted: python/branches/py3k-short-float-repr/Modules/_bufferedio.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_bufferedio.c Sun Apr 5 01:04:14 2009 +++ (empty file) @@ -1,2139 +0,0 @@ -/* - An implementation of Buffered I/O as defined by PEP 3116 - "New I/O" - - Classes defined here: BufferedIOBase, BufferedReader, BufferedWriter, - BufferedRandom. - - Written by Amaury Forgeot d'Arc and Antoine Pitrou -*/ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#include "structmember.h" -#include "pythread.h" -#include "_iomodule.h" - -/* - * BufferedIOBase class, inherits from IOBase. - */ -PyDoc_STRVAR(BufferedIOBase_doc, - "Base class for buffered IO objects.\n" - "\n" - "The main difference with RawIOBase is that the read() method\n" - "supports omitting the size argument, and does not have a default\n" - "implementation that defers to readinto().\n" - "\n" - "In addition, read(), readinto() and write() may raise\n" - "BlockingIOError if the underlying raw stream is in non-blocking\n" - "mode and not ready; unlike their raw counterparts, they will never\n" - "return None.\n" - "\n" - "A typical implementation should not inherit from a RawIOBase\n" - "implementation, but wrap one.\n" - ); - -static PyObject * -BufferedIOBase_readinto(PyObject *self, PyObject *args) -{ - Py_buffer buf; - Py_ssize_t len; - PyObject *data; - - if (!PyArg_ParseTuple(args, "w*:readinto", &buf)) { - return NULL; - } - - data = PyObject_CallMethod(self, "read", "n", buf.len); - if (data == NULL) - goto error; - - if (!PyBytes_Check(data)) { - Py_DECREF(data); - PyErr_SetString(PyExc_TypeError, "read() should return bytes"); - goto error; - } - - len = Py_SIZE(data); - memcpy(buf.buf, PyBytes_AS_STRING(data), len); - - PyBuffer_Release(&buf); - Py_DECREF(data); - - return PyLong_FromSsize_t(len); - - error: - PyBuffer_Release(&buf); - return NULL; -} - -static PyObject * -BufferedIOBase_unsupported(const char *message) -{ - PyErr_SetString(IO_STATE->unsupported_operation, message); - return NULL; -} - -PyDoc_STRVAR(BufferedIOBase_read_doc, - "Read and return up to n bytes.\n" - "\n" - "If the argument is omitted, None, or negative, reads and\n" - "returns all data until EOF.\n" - "\n" - "If the argument is positive, and the underlying raw stream is\n" - "not 'interactive', multiple raw reads may be issued to satisfy\n" - "the byte count (unless EOF is reached first). But for\n" - "interactive raw streams (as well as sockets and pipes), at most\n" - "one raw read will be issued, and a short result does not imply\n" - "that EOF is imminent.\n" - "\n" - "Returns an empty bytes object on EOF.\n" - "\n" - "Returns None if the underlying raw stream was open in non-blocking\n" - "mode and no data is available at the moment.\n"); - -static PyObject * -BufferedIOBase_read(PyObject *self, PyObject *args) -{ - return BufferedIOBase_unsupported("read"); -} - -PyDoc_STRVAR(BufferedIOBase_read1_doc, - "Read and return up to n bytes, with at most one read() call\n" - "to the underlying raw stream. A short result does not imply\n" - "that EOF is imminent.\n" - "\n" - "Returns an empty bytes object on EOF.\n"); - -static PyObject * -BufferedIOBase_read1(PyObject *self, PyObject *args) -{ - return BufferedIOBase_unsupported("read1"); -} - -PyDoc_STRVAR(BufferedIOBase_write_doc, - "Write the given buffer to the IO stream.\n" - "\n" - "Returns the number of bytes written, which is never less than\n" - "len(b).\n" - "\n" - "Raises BlockingIOError if the buffer is full and the\n" - "underlying raw stream cannot accept more data at the moment.\n"); - -static PyObject * -BufferedIOBase_write(PyObject *self, PyObject *args) -{ - return BufferedIOBase_unsupported("write"); -} - - -static PyMethodDef BufferedIOBase_methods[] = { - {"read", BufferedIOBase_read, METH_VARARGS, BufferedIOBase_read_doc}, - {"read1", BufferedIOBase_read1, METH_VARARGS, BufferedIOBase_read1_doc}, - {"readinto", BufferedIOBase_readinto, METH_VARARGS, NULL}, - {"write", BufferedIOBase_write, METH_VARARGS, BufferedIOBase_write_doc}, - {NULL, NULL} -}; - -PyTypeObject PyBufferedIOBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._BufferedIOBase", /*tp_name*/ - 0, /*tp_basicsize*/ - 0, /*tp_itemsize*/ - 0, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - BufferedIOBase_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - BufferedIOBase_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PyIOBase_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ -}; - - -typedef struct { - PyObject_HEAD - - PyObject *raw; - int ok; /* Initialized? */ - int readable; - int writable; - - /* Absolute position inside the raw stream (-1 if unknown). */ - Py_off_t abs_pos; - - /* A static buffer of size `buffer_size` */ - char *buffer; - /* Current logical position in the buffer. */ - Py_off_t pos; - /* Position of the raw stream in the buffer. */ - Py_off_t raw_pos; - - /* Just after the last buffered byte in the buffer, or -1 if the buffer - isn't ready for reading. */ - Py_off_t read_end; - - /* Just after the last byte actually written */ - Py_off_t write_pos; - /* Just after the last byte waiting to be written, or -1 if the buffer - isn't ready for writing. */ - Py_off_t write_end; - - PyThread_type_lock lock; - - Py_ssize_t buffer_size; - Py_ssize_t buffer_mask; - - PyObject *dict; - PyObject *weakreflist; -} BufferedObject; - -/* - Implementation notes: - - * BufferedReader, BufferedWriter and BufferedRandom try to share most - methods (this is helped by the members `readable` and `writable`, which - are initialized in the respective constructors) - * They also share a single buffer for reading and writing. This enables - interleaved reads and writes without flushing. It also makes the logic - a bit trickier to get right. - * The absolute position of the raw stream is cached, if possible, in the - `abs_pos` member. It must be updated every time an operation is done - on the raw stream. If not sure, it can be reinitialized by calling - _Buffered_raw_tell(), which queries the raw stream (_Buffered_raw_seek() - also does it). To read it, use RAW_TELL(). - * Three helpers, _BufferedReader_raw_read, _BufferedWriter_raw_write and - _BufferedWriter_flush_unlocked do a lot of useful housekeeping. - - NOTE: we should try to maintain block alignment of reads and writes to the - raw stream (according to the buffer size), but for now it is only done - in read() and friends. - - XXX: method naming is a bit messy. -*/ - -/* These macros protect the BufferedObject against concurrent operations. */ - -#define ENTER_BUFFERED(self) \ - Py_BEGIN_ALLOW_THREADS \ - PyThread_acquire_lock(self->lock, 1); \ - Py_END_ALLOW_THREADS - -#define LEAVE_BUFFERED(self) \ - PyThread_release_lock(self->lock); - -#define CHECK_INITIALIZED(self) \ - if (self->ok <= 0) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - return NULL; \ - } - -#define CHECK_INITIALIZED_INT(self) \ - if (self->ok <= 0) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - return -1; \ - } - -#define VALID_READ_BUFFER(self) \ - (self->readable && self->read_end != -1) - -#define VALID_WRITE_BUFFER(self) \ - (self->writable && self->write_end != -1) - -#define ADJUST_POSITION(self, _new_pos) \ - do { \ - self->pos = _new_pos; \ - if (VALID_READ_BUFFER(self) && self->read_end < self->pos) \ - self->read_end = self->pos; \ - } while(0) - -#define READAHEAD(self) \ - ((self->readable && VALID_READ_BUFFER(self)) \ - ? (self->read_end - self->pos) : 0) - -#define RAW_OFFSET(self) \ - (((VALID_READ_BUFFER(self) || VALID_WRITE_BUFFER(self)) \ - && self->raw_pos >= 0) ? self->raw_pos - self->pos : 0) - -#define RAW_TELL(self) \ - (self->abs_pos != -1 ? self->abs_pos : _Buffered_raw_tell(self)) - -#define MINUS_LAST_BLOCK(self, size) \ - (self->buffer_mask ? \ - (size & ~self->buffer_mask) : \ - (self->buffer_size * (size / self->buffer_size))) - - -static void -BufferedObject_dealloc(BufferedObject *self) -{ - if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0) - return; - _PyObject_GC_UNTRACK(self); - self->ok = 0; - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *)self); - Py_CLEAR(self->raw); - if (self->buffer) { - PyMem_Free(self->buffer); - self->buffer = NULL; - } - if (self->lock) { - PyThread_free_lock(self->lock); - self->lock = NULL; - } - Py_CLEAR(self->dict); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static int -Buffered_traverse(BufferedObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->raw); - Py_VISIT(self->dict); - return 0; -} - -static int -Buffered_clear(BufferedObject *self) -{ - if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0) - return -1; - self->ok = 0; - Py_CLEAR(self->raw); - Py_CLEAR(self->dict); - return 0; -} - -/* - * _BufferedIOMixin methods - * This is not a class, just a collection of methods that will be reused - * by BufferedReader and BufferedWriter - */ - -/* Flush and close */ - -static PyObject * -BufferedIOMixin_flush(BufferedObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self) - return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL); -} - -static int -BufferedIOMixin_closed(BufferedObject *self) -{ - int closed; - PyObject *res; - CHECK_INITIALIZED_INT(self) - res = PyObject_GetAttr(self->raw, _PyIO_str_closed); - if (res == NULL) - return -1; - closed = PyObject_IsTrue(res); - Py_DECREF(res); - return closed; -} - -static PyObject * -BufferedIOMixin_closed_get(BufferedObject *self, void *context) -{ - CHECK_INITIALIZED(self) - return PyObject_GetAttr(self->raw, _PyIO_str_closed); -} - -static PyObject * -BufferedIOMixin_close(BufferedObject *self, PyObject *args) -{ - PyObject *res = NULL; - int r; - - CHECK_INITIALIZED(self) - ENTER_BUFFERED(self) - - r = BufferedIOMixin_closed(self); - if (r < 0) - goto end; - if (r > 0) { - res = Py_None; - Py_INCREF(res); - goto end; - } - /* 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 (res == NULL) { - /* If flush() fails, just give up */ - if (PyErr_ExceptionMatches(PyExc_IOError)) - PyErr_Clear(); - else - goto end; - } - Py_XDECREF(res); - - res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL); - -end: - LEAVE_BUFFERED(self) - return res; -} - -/* Inquiries */ - -static PyObject * -BufferedIOMixin_seekable(BufferedObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self) - return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL); -} - -static PyObject * -BufferedIOMixin_readable(BufferedObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self) - return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL); -} - -static PyObject * -BufferedIOMixin_writable(BufferedObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self) - return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL); -} - -static PyObject * -BufferedIOMixin_name_get(BufferedObject *self, void *context) -{ - CHECK_INITIALIZED(self) - return PyObject_GetAttrString(self->raw, "name"); -} - -static PyObject * -BufferedIOMixin_mode_get(BufferedObject *self, void *context) -{ - CHECK_INITIALIZED(self) - return PyObject_GetAttrString(self->raw, "mode"); -} - -/* Lower-level APIs */ - -static PyObject * -BufferedIOMixin_fileno(BufferedObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self) - return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL); -} - -static PyObject * -BufferedIOMixin_isatty(BufferedObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self) - return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL); -} - - -/* Forward decls */ -static PyObject * -_BufferedWriter_flush_unlocked(BufferedObject *, int); -static Py_ssize_t -_BufferedReader_fill_buffer(BufferedObject *self); -static void -_BufferedReader_reset_buf(BufferedObject *self); -static void -_BufferedWriter_reset_buf(BufferedObject *self); -static PyObject * -_BufferedReader_peek_unlocked(BufferedObject *self, Py_ssize_t); -static PyObject * -_BufferedReader_read_unlocked(BufferedObject *self, Py_ssize_t); - - -/* - * Helpers - */ - -/* Returns the address of the `written` member if a BlockingIOError was - raised, NULL otherwise. The error is always re-raised. */ -static Py_ssize_t * -_Buffered_check_blocking_error(void) -{ - PyObject *t, *v, *tb; - PyBlockingIOErrorObject *err; - - PyErr_Fetch(&t, &v, &tb); - if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) { - PyErr_Restore(t, v, tb); - return NULL; - } - err = (PyBlockingIOErrorObject *) v; - /* TODO: sanity check (err->written >= 0) */ - PyErr_Restore(t, v, tb); - return &err->written; -} - -static Py_off_t -_Buffered_raw_tell(BufferedObject *self) -{ - PyObject *res; - Py_off_t n; - res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL); - if (res == NULL) - return -1; - n = PyNumber_AsOff_t(res, PyExc_ValueError); - Py_DECREF(res); - if (n < 0) { - if (!PyErr_Occurred()) - PyErr_Format(PyExc_IOError, - "Raw stream returned invalid position %zd", n); - return -1; - } - self->abs_pos = n; - return n; -} - -static Py_off_t -_Buffered_raw_seek(BufferedObject *self, Py_off_t target, int whence) -{ - PyObject *res, *posobj, *whenceobj; - Py_off_t n; - - posobj = PyLong_FromOff_t(target); - if (posobj == NULL) - return -1; - whenceobj = PyLong_FromLong(whence); - if (whenceobj == NULL) { - Py_DECREF(posobj); - return -1; - } - res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seek, - posobj, whenceobj, NULL); - Py_DECREF(posobj); - Py_DECREF(whenceobj); - if (res == NULL) - return -1; - n = PyNumber_AsOff_t(res, PyExc_ValueError); - Py_DECREF(res); - if (n < 0) { - if (!PyErr_Occurred()) - PyErr_Format(PyExc_IOError, - "Raw stream returned invalid position %zd", n); - return -1; - } - self->abs_pos = n; - return n; -} - -static int -_Buffered_init(BufferedObject *self) -{ - Py_ssize_t n; - if (self->buffer_size <= 0) { - PyErr_SetString(PyExc_ValueError, - "buffer size must be strictly positive"); - return -1; - } - if (self->buffer) - PyMem_Free(self->buffer); - self->buffer = PyMem_Malloc(self->buffer_size); - if (self->buffer == NULL) { - PyErr_NoMemory(); - return -1; - } - self->lock = PyThread_allocate_lock(); - if (self->lock == NULL) { - PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock"); - return -1; - } - /* Find out whether buffer_size is a power of 2 */ - /* XXX is this optimization useful? */ - for (n = self->buffer_size - 1; n & 1; n >>= 1) - ; - if (n == 0) - self->buffer_mask = self->buffer_size - 1; - else - self->buffer_mask = 0; - if (_Buffered_raw_tell(self) == -1) - PyErr_Clear(); - return 0; -} - -/* - * Shared methods and wrappers - */ - -static PyObject * -Buffered_flush(BufferedObject *self, PyObject *args) -{ - PyObject *res; - - CHECK_INITIALIZED(self) - if (BufferedIOMixin_closed(self)) { - PyErr_SetString(PyExc_ValueError, "flush of closed file"); - return NULL; - } - - ENTER_BUFFERED(self) - res = _BufferedWriter_flush_unlocked(self, 0); - if (res != NULL && self->readable) { - /* Rewind the raw stream so that its position corresponds to - the current logical position. */ - Py_off_t n; - n = _Buffered_raw_seek(self, -RAW_OFFSET(self), 1); - if (n == -1) - Py_CLEAR(res); - _BufferedReader_reset_buf(self); - } - LEAVE_BUFFERED(self) - - return res; -} - -static PyObject * -Buffered_peek(BufferedObject *self, PyObject *args) -{ - Py_ssize_t n = 0; - PyObject *res = NULL; - - CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "|n:peek", &n)) { - return NULL; - } - - ENTER_BUFFERED(self) - - if (self->writable) { - res = _BufferedWriter_flush_unlocked(self, 1); - if (res == NULL) - goto end; - Py_CLEAR(res); - } - res = _BufferedReader_peek_unlocked(self, n); - -end: - LEAVE_BUFFERED(self) - return res; -} - -static PyObject * -Buffered_read(BufferedObject *self, PyObject *args) -{ - Py_ssize_t n = -1; - PyObject *res; - - CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "|n:read", &n)) { - return NULL; - } - if (n < -1) { - PyErr_SetString(PyExc_ValueError, - "read length must be positive or -1"); - return NULL; - } - - if (BufferedIOMixin_closed(self)) { - PyErr_SetString(PyExc_ValueError, "read of closed file"); - return NULL; - } - - ENTER_BUFFERED(self) - res = _BufferedReader_read_unlocked(self, n); - LEAVE_BUFFERED(self) - - return res; -} - -static PyObject * -Buffered_read1(BufferedObject *self, PyObject *args) -{ - Py_ssize_t n, have, r; - PyObject *res = NULL; - - CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "n:read1", &n)) { - return NULL; - } - - if (n < 0) { - PyErr_SetString(PyExc_ValueError, - "read length must be positive"); - return NULL; - } - if (n == 0) - return PyBytes_FromStringAndSize(NULL, 0); - - ENTER_BUFFERED(self) - - if (self->writable) { - res = _BufferedWriter_flush_unlocked(self, 1); - if (res == NULL) - goto end; - Py_CLEAR(res); - } - - /* Return up to n bytes. If at least one byte is buffered, we - only return buffered bytes. Otherwise, we do one raw read. */ - - /* XXX: this mimicks the io.py implementation but is probably wrong. - If we need to read from the raw stream, then we could actually read - all `n` bytes asked by the caller (and possibly more, so as to fill - our buffer for the next reads). */ - - have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); - if (have > 0) { - if (n > have) - n = have; - res = PyBytes_FromStringAndSize(self->buffer + self->pos, n); - if (res == NULL) - goto end; - self->pos += n; - goto end; - } - - /* Fill the buffer from the raw stream, and copy it to the result. */ - _BufferedReader_reset_buf(self); - r = _BufferedReader_fill_buffer(self); - if (r == -1) - goto end; - if (r == -2) - r = 0; - if (n > r) - n = r; - res = PyBytes_FromStringAndSize(self->buffer, n); - if (res == NULL) - goto end; - self->pos = n; - -end: - LEAVE_BUFFERED(self) - return res; -} - -static PyObject * -Buffered_readinto(BufferedObject *self, PyObject *args) -{ - PyObject *res = NULL; - - CHECK_INITIALIZED(self) - - /* TODO: use raw.readinto() instead! */ - if (self->writable) { - ENTER_BUFFERED(self) - res = _BufferedWriter_flush_unlocked(self, 0); - LEAVE_BUFFERED(self) - if (res == NULL) - goto end; - Py_DECREF(res); - } - res = BufferedIOBase_readinto((PyObject *)self, args); - -end: - return res; -} - -static PyObject * -_Buffered_readline(BufferedObject *self, Py_ssize_t limit) -{ - PyObject *res = NULL; - PyObject *chunks = NULL; - Py_ssize_t n, written = 0; - const char *start, *s, *end; - - if (BufferedIOMixin_closed(self)) { - PyErr_SetString(PyExc_ValueError, "readline of closed file"); - return NULL; - } - - ENTER_BUFFERED(self) - - /* First, try to find a line in the buffer */ - n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); - if (limit >= 0 && n > limit) - n = limit; - start = self->buffer + self->pos; - end = start + n; - s = start; - while (s < end) { - if (*s++ == '\n') { - res = PyBytes_FromStringAndSize(start, s - start); - if (res != NULL) - self->pos += s - start; - goto end; - } - } - if (n == limit) { - res = PyBytes_FromStringAndSize(start, n); - if (res != NULL) - self->pos += n; - goto end; - } - - /* Now we try to get some more from the raw stream */ - if (self->writable) { - res = _BufferedWriter_flush_unlocked(self, 1); - if (res == NULL) - goto end; - Py_CLEAR(res); - } - chunks = PyList_New(0); - if (chunks == NULL) - goto end; - if (n > 0) { - res = PyBytes_FromStringAndSize(start, n); - if (res == NULL) - goto end; - if (PyList_Append(chunks, res) < 0) { - Py_CLEAR(res); - goto end; - } - Py_CLEAR(res); - written += n; - if (limit >= 0) - limit -= n; - } - - for (;;) { - _BufferedReader_reset_buf(self); - n = _BufferedReader_fill_buffer(self); - if (n == -1) - goto end; - if (n <= 0) - break; - if (limit >= 0 && n > limit) - n = limit; - start = self->buffer; - end = start + n; - s = start; - while (s < end) { - if (*s++ == '\n') { - res = PyBytes_FromStringAndSize(start, s - start); - if (res == NULL) - goto end; - self->pos = s - start; - goto found; - } - } - res = PyBytes_FromStringAndSize(start, n); - if (res == NULL) - goto end; - if (n == limit) { - self->pos = n; - break; - } - if (PyList_Append(chunks, res) < 0) { - Py_CLEAR(res); - goto end; - } - Py_CLEAR(res); - written += n; - if (limit >= 0) - limit -= n; - } -found: - if (res != NULL && PyList_Append(chunks, res) < 0) { - Py_CLEAR(res); - goto end; - } - Py_CLEAR(res); - res = _PyBytes_Join(_PyIO_empty_bytes, chunks); - -end: - LEAVE_BUFFERED(self) - Py_XDECREF(chunks); - return res; -} - -static PyObject * -Buffered_readline(BufferedObject *self, PyObject *args) -{ - Py_ssize_t limit = -1; - - CHECK_INITIALIZED(self) - - if (!PyArg_ParseTuple(args, "|n:readline", &limit)) { - return NULL; - } - return _Buffered_readline(self, limit); -} - - -static PyObject * -Buffered_tell(BufferedObject *self, PyObject *args) -{ - Py_off_t pos; - - CHECK_INITIALIZED(self) - pos = _Buffered_raw_tell(self); - if (pos == -1) - return NULL; - pos -= RAW_OFFSET(self); - /* TODO: sanity check (pos >= 0) */ - return PyLong_FromOff_t(pos); -} - -static PyObject * -Buffered_seek(BufferedObject *self, PyObject *args) -{ - Py_off_t target, n; - int whence = 0; - PyObject *targetobj, *res = NULL; - - CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) { - return NULL; - } - - if (whence < 0 || whence > 2) { - PyErr_Format(PyExc_ValueError, - "whence must be between 0 and 2, not %d", whence); - return NULL; - } - target = PyNumber_AsOff_t(targetobj, PyExc_ValueError); - if (target == -1 && PyErr_Occurred()) - return NULL; - - ENTER_BUFFERED(self) - - if (whence != 2 && self->readable) { - Py_off_t current, avail; - /* Check if seeking leaves us inside the current buffer, - so as to return quickly if possible. - Don't know how to do that when whence == 2, though. */ - current = RAW_TELL(self); - avail = READAHEAD(self); - if (avail > 0) { - Py_off_t offset; - if (whence == 0) - offset = target - (current - RAW_OFFSET(self)); - else - offset = target; - if (offset >= -self->pos && offset <= avail) { - self->pos += offset; - res = PyLong_FromOff_t(current - avail + offset); - goto end; - } - } - } - - /* Fallback: invoke raw seek() method and clear buffer */ - if (self->writable) { - res = _BufferedWriter_flush_unlocked(self, 0); - if (res == NULL) - goto end; - Py_CLEAR(res); - _BufferedWriter_reset_buf(self); - } - - /* TODO: align on block boundary and read buffer if needed? */ - if (whence == 1) - target -= RAW_OFFSET(self); - n = _Buffered_raw_seek(self, target, whence); - if (n == -1) - goto end; - self->raw_pos = -1; - res = PyLong_FromOff_t(n); - if (res != NULL && self->readable) - _BufferedReader_reset_buf(self); - -end: - LEAVE_BUFFERED(self) - return res; -} - -static PyObject * -Buffered_truncate(BufferedObject *self, PyObject *args) -{ - PyObject *pos = Py_None; - PyObject *res = NULL; - - CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) { - return NULL; - } - - ENTER_BUFFERED(self) - - if (self->writable) { - res = _BufferedWriter_flush_unlocked(self, 0); - if (res == NULL) - goto end; - Py_CLEAR(res); - } - if (self->readable) { - if (pos == Py_None) { - /* Rewind the raw stream so that its position corresponds to - the current logical position. */ - if (_Buffered_raw_seek(self, -RAW_OFFSET(self), 1) == -1) - goto end; - } - _BufferedReader_reset_buf(self); - } - res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_truncate, pos, NULL); - if (res == NULL) - goto end; - /* Reset cached position */ - if (_Buffered_raw_tell(self) == -1) - PyErr_Clear(); - -end: - LEAVE_BUFFERED(self) - return res; -} - -static PyObject * -Buffered_iternext(BufferedObject *self) -{ - PyObject *line; - PyTypeObject *tp; - - CHECK_INITIALIZED(self); - - tp = Py_TYPE(self); - if (tp == &PyBufferedReader_Type || - tp == &PyBufferedRandom_Type) { - /* Skip method call overhead for speed */ - line = _Buffered_readline(self, -1); - } - else { - line = PyObject_CallMethodObjArgs((PyObject *)self, - _PyIO_str_readline, NULL); - if (line && !PyBytes_Check(line)) { - PyErr_Format(PyExc_IOError, - "readline() should have returned a bytes object, " - "not '%.200s'", Py_TYPE(line)->tp_name); - Py_DECREF(line); - return NULL; - } - } - - if (line == NULL) - return NULL; - - if (PyBytes_GET_SIZE(line) == 0) { - /* Reached EOF or would have blocked */ - Py_DECREF(line); - return NULL; - } - - return line; -} - -/* - * class BufferedReader - */ - -PyDoc_STRVAR(BufferedReader_doc, - "Create a new buffered reader using the given readable raw IO object."); - -static void _BufferedReader_reset_buf(BufferedObject *self) -{ - self->read_end = -1; -} - -static int -BufferedReader_init(BufferedObject *self, PyObject *args, PyObject *kwds) -{ - char *kwlist[] = {"raw", "buffer_size", NULL}; - Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; - PyObject *raw; - - self->ok = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist, - &raw, &buffer_size)) { - return -1; - } - - if (_PyIOBase_checkReadable(raw, Py_True) == NULL) - return -1; - - Py_CLEAR(self->raw); - Py_INCREF(raw); - self->raw = raw; - self->buffer_size = buffer_size; - self->readable = 1; - self->writable = 0; - - if (_Buffered_init(self) < 0) - return -1; - _BufferedReader_reset_buf(self); - - self->ok = 1; - return 0; -} - -static Py_ssize_t -_BufferedReader_raw_read(BufferedObject *self, char *start, Py_ssize_t len) -{ - Py_buffer buf; - PyObject *memobj, *res; - Py_ssize_t n; - /* NOTE: the buffer needn't be released as its object is NULL. */ - if (PyBuffer_FillInfo(&buf, NULL, start, len, 0, PyBUF_CONTIG) == -1) - return -1; - memobj = PyMemoryView_FromBuffer(&buf); - if (memobj == NULL) - return -1; - res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readinto, memobj, NULL); - Py_DECREF(memobj); - if (res == NULL) - return -1; - if (res == Py_None) { - /* Non-blocking stream would have blocked. Special return code! */ - Py_DECREF(res); - return -2; - } - n = PyNumber_AsSsize_t(res, PyExc_ValueError); - Py_DECREF(res); - if (n < 0 || n > len) { - PyErr_Format(PyExc_IOError, - "raw readinto() returned invalid length %zd " - "(should have been between 0 and %zd)", n, len); - return -1; - } - if (n > 0 && self->abs_pos != -1) - self->abs_pos += n; - return n; -} - -static Py_ssize_t -_BufferedReader_fill_buffer(BufferedObject *self) -{ - Py_ssize_t start, len, n; - if (VALID_READ_BUFFER(self)) - start = Py_SAFE_DOWNCAST(self->read_end, Py_off_t, Py_ssize_t); - else - start = 0; - len = self->buffer_size - start; - n = _BufferedReader_raw_read(self, self->buffer + start, len); - if (n <= 0) - return n; - self->read_end = start + n; - self->raw_pos = start + n; - return n; -} - -static PyObject * -_BufferedReader_read_unlocked(BufferedObject *self, Py_ssize_t n) -{ - PyObject *data, *res = NULL; - Py_ssize_t current_size, remaining, written; - char *out; - - /* Special case for when the number of bytes to read is unspecified. */ - if (n == -1) { - PyObject *chunks = PyList_New(0); - if (chunks == NULL) - return NULL; - - /* First copy what we have in the current buffer. */ - current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); - data = NULL; - if (current_size) { - data = PyBytes_FromStringAndSize( - self->buffer + self->pos, current_size); - if (data == NULL) { - Py_DECREF(chunks); - return NULL; - } - } - _BufferedReader_reset_buf(self); - /* We're going past the buffer's bounds, flush it */ - if (self->writable) { - res = _BufferedWriter_flush_unlocked(self, 1); - if (res == NULL) { - Py_DECREF(chunks); - return NULL; - } - Py_CLEAR(res); - } - while (1) { - if (data) { - if (PyList_Append(chunks, data) < 0) { - Py_DECREF(data); - Py_DECREF(chunks); - return NULL; - } - Py_DECREF(data); - } - - /* Read until EOF or until read() would block. */ - data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL); - if (data == NULL) { - Py_DECREF(chunks); - return NULL; - } - if (data != Py_None && !PyBytes_Check(data)) { - Py_DECREF(data); - Py_DECREF(chunks); - PyErr_SetString(PyExc_TypeError, "read() should return bytes"); - return NULL; - } - if (data == Py_None || PyBytes_GET_SIZE(data) == 0) { - if (current_size == 0) { - Py_DECREF(chunks); - return data; - } - else { - res = _PyBytes_Join(_PyIO_empty_bytes, chunks); - Py_DECREF(data); - Py_DECREF(chunks); - return res; - } - } - current_size += PyBytes_GET_SIZE(data); - if (self->abs_pos != -1) - self->abs_pos += PyBytes_GET_SIZE(data); - } - } - - /* The number of bytes to read is specified, return at most n bytes. */ - current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); - if (n <= current_size) { - /* Fast path: the data to read is fully buffered. */ - res = PyBytes_FromStringAndSize(self->buffer + self->pos, n); - if (res == NULL) - goto error; - self->pos += n; - return res; - } - - /* Slow path: read from the stream until enough bytes are read, - * or until an EOF occurs or until read() would block. - */ - res = PyBytes_FromStringAndSize(NULL, n); - if (res == NULL) - goto error; - out = PyBytes_AS_STRING(res); - remaining = n; - written = 0; - if (current_size > 0) { - memcpy(out, self->buffer + self->pos, current_size); - remaining -= current_size; - written += current_size; - } - _BufferedReader_reset_buf(self); - while (remaining > 0) { - /* We want to read a whole block at the end into buffer. - If we had readv() we could do this in one pass. */ - Py_ssize_t r = MINUS_LAST_BLOCK(self, remaining); - if (r == 0) - break; - r = _BufferedReader_raw_read(self, out + written, r); - if (r == -1) - goto error; - if (r == 0 || r == -2) { - /* EOF occurred or read() would block. */ - if (r == 0 || written > 0) { - if (_PyBytes_Resize(&res, written)) - goto error; - return res; - } - Py_DECREF(res); - Py_INCREF(Py_None); - return Py_None; - } - remaining -= r; - written += r; - } - assert(remaining <= self->buffer_size); - self->pos = 0; - self->raw_pos = 0; - self->read_end = 0; - while (self->read_end < self->buffer_size) { - Py_ssize_t r = _BufferedReader_fill_buffer(self); - if (r == -1) - goto error; - if (r == 0 || r == -2) { - /* EOF occurred or read() would block. */ - if (r == 0 || written > 0) { - if (_PyBytes_Resize(&res, written)) - goto error; - return res; - } - Py_DECREF(res); - Py_INCREF(Py_None); - return Py_None; - } - if (remaining > r) { - memcpy(out + written, self->buffer + self->pos, r); - written += r; - self->pos += r; - remaining -= r; - } - else if (remaining > 0) { - memcpy(out + written, self->buffer + self->pos, remaining); - written += remaining; - self->pos += remaining; - remaining = 0; - } - if (remaining == 0) - break; - } - - return res; - -error: - Py_XDECREF(res); - return NULL; -} - -static PyObject * -_BufferedReader_peek_unlocked(BufferedObject *self, Py_ssize_t n) -{ - Py_ssize_t have, r; - - have = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); - /* Constraints: - 1. we don't want to advance the file position. - 2. we don't want to lose block alignment, so we can't shift the buffer - to make some place. - Therefore, we either return `have` bytes (if > 0), or a full buffer. - */ - if (have > 0) { - return PyBytes_FromStringAndSize(self->buffer + self->pos, have); - } - - /* Fill the buffer from the raw stream, and copy it to the result. */ - _BufferedReader_reset_buf(self); - r = _BufferedReader_fill_buffer(self); - if (r == -1) - return NULL; - if (r == -2) - r = 0; - self->pos = 0; - return PyBytes_FromStringAndSize(self->buffer, r); -} - -static PyMethodDef BufferedReader_methods[] = { - /* BufferedIOMixin methods */ - {"flush", (PyCFunction)BufferedIOMixin_flush, METH_NOARGS}, - {"close", (PyCFunction)BufferedIOMixin_close, METH_NOARGS}, - {"seekable", (PyCFunction)BufferedIOMixin_seekable, METH_NOARGS}, - {"readable", (PyCFunction)BufferedIOMixin_readable, METH_NOARGS}, - {"writable", (PyCFunction)BufferedIOMixin_writable, METH_NOARGS}, - {"fileno", (PyCFunction)BufferedIOMixin_fileno, METH_NOARGS}, - {"isatty", (PyCFunction)BufferedIOMixin_isatty, METH_NOARGS}, - - {"read", (PyCFunction)Buffered_read, METH_VARARGS}, - {"peek", (PyCFunction)Buffered_peek, METH_VARARGS}, - {"read1", (PyCFunction)Buffered_read1, METH_VARARGS}, - {"readline", (PyCFunction)Buffered_readline, METH_VARARGS}, - {"seek", (PyCFunction)Buffered_seek, METH_VARARGS}, - {"tell", (PyCFunction)Buffered_tell, METH_NOARGS}, - {"truncate", (PyCFunction)Buffered_truncate, METH_VARARGS}, - {NULL, NULL} -}; - -static PyMemberDef BufferedReader_members[] = { - {"raw", T_OBJECT, offsetof(BufferedObject, raw), 0}, - {NULL} -}; - -static PyGetSetDef BufferedReader_getset[] = { - {"closed", (getter)BufferedIOMixin_closed_get, NULL, NULL}, - {"name", (getter)BufferedIOMixin_name_get, NULL, NULL}, - {"mode", (getter)BufferedIOMixin_mode_get, NULL, NULL}, - {0} -}; - - -PyTypeObject PyBufferedReader_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.BufferedReader", /*tp_name*/ - sizeof(BufferedObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)BufferedObject_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - BufferedReader_doc, /* tp_doc */ - (traverseproc)Buffered_traverse, /* tp_traverse */ - (inquiry)Buffered_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(BufferedObject, weakreflist), /*tp_weaklistoffset*/ - 0, /* tp_iter */ - (iternextfunc)Buffered_iternext, /* tp_iternext */ - BufferedReader_methods, /* tp_methods */ - BufferedReader_members, /* tp_members */ - BufferedReader_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(BufferedObject, dict), /* tp_dictoffset */ - (initproc)BufferedReader_init, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; - - - -static int -complain_about_max_buffer_size(void) -{ - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "max_buffer_size is deprecated", 1) < 0) - return 0; - return 1; -} - -/* - * class BufferedWriter - */ -PyDoc_STRVAR(BufferedWriter_doc, - "A buffer for a writeable sequential RawIO object.\n" - "\n" - "The constructor creates a BufferedWriter for the given writeable raw\n" - "stream. If the buffer_size is not given, it defaults to\n" - "DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n" - ); - -static void -_BufferedWriter_reset_buf(BufferedObject *self) -{ - self->write_pos = 0; - self->write_end = -1; -} - -static int -BufferedWriter_init(BufferedObject *self, PyObject *args, PyObject *kwds) -{ - /* TODO: properly deprecate max_buffer_size */ - char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL}; - Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; - Py_ssize_t max_buffer_size = -234; - PyObject *raw; - - self->ok = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedReader", kwlist, - &raw, &buffer_size, &max_buffer_size)) { - return -1; - } - - if (max_buffer_size != -234 && !complain_about_max_buffer_size()) - return -1; - - if (_PyIOBase_checkWritable(raw, Py_True) == NULL) - return -1; - - Py_CLEAR(self->raw); - Py_INCREF(raw); - self->raw = raw; - self->readable = 0; - self->writable = 1; - - self->buffer_size = buffer_size; - if (_Buffered_init(self) < 0) - return -1; - _BufferedWriter_reset_buf(self); - self->pos = 0; - - self->ok = 1; - return 0; -} - -static Py_ssize_t -_BufferedWriter_raw_write(BufferedObject *self, char *start, Py_ssize_t len) -{ - Py_buffer buf; - PyObject *memobj, *res; - Py_ssize_t n; - /* NOTE: the buffer needn't be released as its object is NULL. */ - if (PyBuffer_FillInfo(&buf, NULL, start, len, 1, PyBUF_CONTIG_RO) == -1) - return -1; - memobj = PyMemoryView_FromBuffer(&buf); - if (memobj == NULL) - return -1; - res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_write, memobj, NULL); - Py_DECREF(memobj); - if (res == NULL) - return -1; - n = PyNumber_AsSsize_t(res, PyExc_ValueError); - Py_DECREF(res); - if (n < 0 || n > len) { - PyErr_Format(PyExc_IOError, - "raw write() returned invalid length %zd " - "(should have been between 0 and %zd)", n, len); - return -1; - } - if (n > 0 && self->abs_pos != -1) - self->abs_pos += n; - return n; -} - -/* `restore_pos` is 1 if we need to restore the raw stream position at - the end, 0 otherwise. */ -static PyObject * -_BufferedWriter_flush_unlocked(BufferedObject *self, int restore_pos) -{ - Py_ssize_t written = 0; - Py_off_t n, rewind; - - if (!VALID_WRITE_BUFFER(self) || self->write_pos == self->write_end) - goto end; - /* First, rewind */ - rewind = RAW_OFFSET(self) + (self->pos - self->write_pos); - if (rewind != 0) { - n = _Buffered_raw_seek(self, -rewind, 1); - if (n < 0) { - goto error; - } - self->raw_pos -= rewind; - } - while (self->write_pos < self->write_end) { - n = _BufferedWriter_raw_write(self, - self->buffer + self->write_pos, - Py_SAFE_DOWNCAST(self->write_end - self->write_pos, - Py_off_t, Py_ssize_t)); - if (n == -1) { - Py_ssize_t *w = _Buffered_check_blocking_error(); - if (w == NULL) - goto error; - self->write_pos += *w; - self->raw_pos = self->write_pos; - written += *w; - *w = written; - /* Already re-raised */ - goto error; - } - self->write_pos += n; - self->raw_pos = self->write_pos; - written += Py_SAFE_DOWNCAST(n, Py_off_t, Py_ssize_t); - } - - if (restore_pos) { - Py_off_t forward = rewind - written; - if (forward != 0) { - n = _Buffered_raw_seek(self, forward, 1); - if (n < 0) { - goto error; - } - self->raw_pos += forward; - } - } - _BufferedWriter_reset_buf(self); - -end: - Py_RETURN_NONE; - -error: - return NULL; -} - -static PyObject * -BufferedWriter_write(BufferedObject *self, PyObject *args) -{ - PyObject *res = NULL; - Py_buffer buf; - Py_ssize_t written, avail, remaining, n; - - CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "y*:write", &buf)) { - return NULL; - } - - if (BufferedIOMixin_closed(self)) { - PyErr_SetString(PyExc_ValueError, "write to closed file"); - PyBuffer_Release(&buf); - return NULL; - } - - ENTER_BUFFERED(self) - - /* Fast path: the data to write can be fully buffered. */ - if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) { - self->pos = 0; - self->raw_pos = 0; - } - avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t); - if (buf.len <= avail) { - memcpy(self->buffer + self->pos, buf.buf, buf.len); - if (!VALID_WRITE_BUFFER(self)) { - self->write_pos = self->pos; - } - ADJUST_POSITION(self, self->pos + buf.len); - if (self->pos > self->write_end) - self->write_end = self->pos; - written = buf.len; - goto end; - } - - /* First write the current buffer */ - res = _BufferedWriter_flush_unlocked(self, 0); - if (res == NULL) { - Py_ssize_t *w = _Buffered_check_blocking_error(); - if (w == NULL) - goto error; - if (self->readable) - _BufferedReader_reset_buf(self); - /* Make some place by shifting the buffer. */ - assert(VALID_WRITE_BUFFER(self)); - memmove(self->buffer, self->buffer + self->write_pos, - Py_SAFE_DOWNCAST(self->write_end - self->write_pos, - Py_off_t, Py_ssize_t)); - self->write_end -= self->write_pos; - self->raw_pos -= self->write_pos; - self->pos -= self->write_pos; - self->write_pos = 0; - avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end, - Py_off_t, Py_ssize_t); - if (buf.len <= avail) { - /* Everything can be buffered */ - PyErr_Clear(); - memcpy(self->buffer + self->write_end, buf.buf, buf.len); - self->write_end += buf.len; - written = buf.len; - goto end; - } - /* Buffer as much as possible. */ - memcpy(self->buffer + self->write_end, buf.buf, avail); - self->write_end += avail; - /* Already re-raised */ - *w = avail; - goto error; - } - Py_CLEAR(res); - - /* Then write buf itself. At this point the buffer has been emptied. */ - remaining = buf.len; - written = 0; - while (remaining > self->buffer_size) { - n = _BufferedWriter_raw_write( - self, (char *) buf.buf + written, buf.len - written); - if (n == -1) { - Py_ssize_t *w = _Buffered_check_blocking_error(); - if (w == NULL) - goto error; - written += *w; - remaining -= *w; - if (remaining > self->buffer_size) { - /* Can't buffer everything, still buffer as much as possible */ - memcpy(self->buffer, - (char *) buf.buf + written, self->buffer_size); - self->raw_pos = 0; - ADJUST_POSITION(self, self->buffer_size); - self->write_end = self->buffer_size; - *w = written + self->buffer_size; - /* Already re-raised */ - goto error; - } - PyErr_Clear(); - break; - } - written += n; - remaining -= n; - } - if (self->readable) - _BufferedReader_reset_buf(self); - if (remaining > 0) { - memcpy(self->buffer, (char *) buf.buf + written, remaining); - written += remaining; - } - self->write_pos = 0; - /* TODO: sanity check (remaining >= 0) */ - self->write_end = remaining; - ADJUST_POSITION(self, remaining); - self->raw_pos = 0; - -end: - res = PyLong_FromSsize_t(written); - -error: - LEAVE_BUFFERED(self) - PyBuffer_Release(&buf); - return res; -} - -static PyMethodDef BufferedWriter_methods[] = { - /* BufferedIOMixin methods */ - {"close", (PyCFunction)BufferedIOMixin_close, METH_NOARGS}, - {"seekable", (PyCFunction)BufferedIOMixin_seekable, METH_NOARGS}, - {"readable", (PyCFunction)BufferedIOMixin_readable, METH_NOARGS}, - {"writable", (PyCFunction)BufferedIOMixin_writable, METH_NOARGS}, - {"fileno", (PyCFunction)BufferedIOMixin_fileno, METH_NOARGS}, - {"isatty", (PyCFunction)BufferedIOMixin_isatty, METH_NOARGS}, - - {"write", (PyCFunction)BufferedWriter_write, METH_VARARGS}, - {"truncate", (PyCFunction)Buffered_truncate, METH_VARARGS}, - {"flush", (PyCFunction)Buffered_flush, METH_NOARGS}, - {"seek", (PyCFunction)Buffered_seek, METH_VARARGS}, - {"tell", (PyCFunction)Buffered_tell, METH_NOARGS}, - {NULL, NULL} -}; - -static PyMemberDef BufferedWriter_members[] = { - {"raw", T_OBJECT, offsetof(BufferedObject, raw), 0}, - {NULL} -}; - -static PyGetSetDef BufferedWriter_getset[] = { - {"closed", (getter)BufferedIOMixin_closed_get, NULL, NULL}, - {"name", (getter)BufferedIOMixin_name_get, NULL, NULL}, - {"mode", (getter)BufferedIOMixin_mode_get, NULL, NULL}, - {0} -}; - - -PyTypeObject PyBufferedWriter_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.BufferedWriter", /*tp_name*/ - sizeof(BufferedObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)BufferedObject_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - BufferedWriter_doc, /* tp_doc */ - (traverseproc)Buffered_traverse, /* tp_traverse */ - (inquiry)Buffered_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(BufferedObject, weakreflist), /*tp_weaklistoffset*/ - 0, /* tp_iter */ - 0, /* tp_iternext */ - BufferedWriter_methods, /* tp_methods */ - BufferedWriter_members, /* tp_members */ - BufferedWriter_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(BufferedObject, dict), /* tp_dictoffset */ - (initproc)BufferedWriter_init, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; - - - -/* - * BufferedRWPair - */ - -PyDoc_STRVAR(BufferedRWPair_doc, - "A buffered reader and writer object together.\n" - "\n" - "A buffered reader object and buffered writer object put together to\n" - "form a sequential IO object that can read and write. This is typically\n" - "used with a socket or two-way pipe.\n" - "\n" - "reader and writer are RawIOBase objects that are readable and\n" - "writeable respectively. If the buffer_size is omitted it defaults to\n" - "DEFAULT_BUFFER_SIZE.\n" - ); - -/* XXX The usefulness of this (compared to having two separate IO objects) is - * questionable. - */ - -typedef struct { - PyObject_HEAD - BufferedObject *reader; - BufferedObject *writer; - PyObject *dict; - PyObject *weakreflist; -} BufferedRWPairObject; - -static int -BufferedRWPair_init(BufferedRWPairObject *self, PyObject *args, - PyObject *kwds) -{ - PyObject *reader, *writer; - Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; - Py_ssize_t max_buffer_size = -234; - - if (!PyArg_ParseTuple(args, "OO|nn:BufferedRWPair", &reader, &writer, - &buffer_size, &max_buffer_size)) { - return -1; - } - - if (max_buffer_size != -234 && !complain_about_max_buffer_size()) - return -1; - - if (_PyIOBase_checkReadable(reader, Py_True) == NULL) - return -1; - if (_PyIOBase_checkWritable(writer, Py_True) == NULL) - return -1; - - args = Py_BuildValue("(n)", buffer_size); - if (args == NULL) { - Py_CLEAR(self->reader); - return -1; - } - self->reader = (BufferedObject *)PyType_GenericNew( - &PyBufferedReader_Type, args, NULL); - Py_DECREF(args); - if (self->reader == NULL) - return -1; - - args = Py_BuildValue("(n)", buffer_size); - if (args == NULL) { - Py_CLEAR(self->reader); - return -1; - } - self->writer = (BufferedObject *)PyType_GenericNew( - &PyBufferedWriter_Type, args, NULL); - Py_DECREF(args); - if (self->writer == NULL) { - Py_CLEAR(self->reader); - return -1; - } - return 0; -} - -static int -BufferedRWPair_traverse(BufferedRWPairObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->dict); - return 0; -} - -static int -BufferedRWPair_clear(BufferedRWPairObject *self) -{ - Py_CLEAR(self->reader); - Py_CLEAR(self->writer); - Py_CLEAR(self->dict); - return 0; -} - -static void -BufferedRWPair_dealloc(BufferedRWPairObject *self) -{ - _PyObject_GC_UNTRACK(self); - Py_CLEAR(self->reader); - Py_CLEAR(self->writer); - Py_CLEAR(self->dict); - Py_TYPE(self)->tp_free((PyObject *) self); -} - -static PyObject * -_forward_call(BufferedObject *self, const char *name, PyObject *args) -{ - PyObject *func = PyObject_GetAttrString((PyObject *)self, name); - PyObject *ret; - - if (func == NULL) { - PyErr_SetString(PyExc_AttributeError, name); - return NULL; - } - - ret = PyObject_CallObject(func, args); - Py_DECREF(func); - return ret; -} - -static PyObject * -BufferedRWPair_read(BufferedRWPairObject *self, PyObject *args) -{ - return _forward_call(self->reader, "read", args); -} - -static PyObject * -BufferedRWPair_peek(BufferedRWPairObject *self, PyObject *args) -{ - return _forward_call(self->reader, "peek", args); -} - -static PyObject * -BufferedRWPair_read1(BufferedRWPairObject *self, PyObject *args) -{ - return _forward_call(self->reader, "read1", args); -} - -static PyObject * -BufferedRWPair_write(BufferedRWPairObject *self, PyObject *args) -{ - return _forward_call(self->writer, "write", args); -} - -static PyObject * -BufferedRWPair_flush(BufferedRWPairObject *self, PyObject *args) -{ - return _forward_call(self->writer, "flush", args); -} - -static PyObject * -BufferedRWPair_readable(BufferedRWPairObject *self, PyObject *args) -{ - return _forward_call(self->reader, "readable", args); -} - -static PyObject * -BufferedRWPair_writable(BufferedRWPairObject *self, PyObject *args) -{ - return _forward_call(self->writer, "writable", args); -} - -static PyObject * -BufferedRWPair_close(BufferedRWPairObject *self, PyObject *args) -{ - PyObject *ret = _forward_call(self->writer, "close", args); - if (ret == NULL) - return NULL; - Py_DECREF(ret); - - return _forward_call(self->reader, "close", args); -} - -static PyObject * -BufferedRWPair_isatty(BufferedRWPairObject *self, PyObject *args) -{ - PyObject *ret = _forward_call(self->writer, "isatty", args); - - if (ret != Py_False) { - /* either True or exception */ - return ret; - } - Py_DECREF(ret); - - return _forward_call(self->reader, "isatty", args); -} - - -static PyMethodDef BufferedRWPair_methods[] = { - {"read", (PyCFunction)BufferedRWPair_read, METH_VARARGS}, - {"peek", (PyCFunction)BufferedRWPair_peek, METH_VARARGS}, - {"read1", (PyCFunction)BufferedRWPair_read1, METH_VARARGS}, - {"readinto", (PyCFunction)Buffered_readinto, METH_VARARGS}, - - {"write", (PyCFunction)BufferedRWPair_write, METH_VARARGS}, - {"flush", (PyCFunction)BufferedRWPair_flush, METH_NOARGS}, - - {"readable", (PyCFunction)BufferedRWPair_readable, METH_NOARGS}, - {"writable", (PyCFunction)BufferedRWPair_writable, METH_NOARGS}, - - {"close", (PyCFunction)BufferedRWPair_close, METH_NOARGS}, - {"isatty", (PyCFunction)BufferedRWPair_isatty, METH_NOARGS}, - - {NULL, NULL} -}; - -PyTypeObject PyBufferedRWPair_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.BufferedRWPair", /*tp_name*/ - sizeof(BufferedRWPairObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)BufferedRWPair_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - BufferedRWPair_doc, /* tp_doc */ - (traverseproc)BufferedRWPair_traverse, /* tp_traverse */ - (inquiry)BufferedRWPair_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(BufferedRWPairObject, weakreflist), /*tp_weaklistoffset*/ - 0, /* tp_iter */ - 0, /* tp_iternext */ - BufferedRWPair_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(BufferedRWPairObject, dict), /* tp_dictoffset */ - (initproc)BufferedRWPair_init, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; - - - -/* - * BufferedRandom - */ - -PyDoc_STRVAR(BufferedRandom_doc, - "A buffered interface to random access streams.\n" - "\n" - "The constructor creates a reader and writer for a seekable stream,\n" - "raw, given in the first argument. If the buffer_size is omitted it\n" - "defaults to DEFAULT_BUFFER_SIZE. max_buffer_size isn't used anymore.\n" - ); - -static int -BufferedRandom_init(BufferedObject *self, PyObject *args, PyObject *kwds) -{ - char *kwlist[] = {"raw", "buffer_size", "max_buffer_size", NULL}; - Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; - Py_ssize_t max_buffer_size = -234; - PyObject *raw; - - self->ok = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|nn:BufferedReader", kwlist, - &raw, &buffer_size, &max_buffer_size)) { - return -1; - } - - if (max_buffer_size != -234 && !complain_about_max_buffer_size()) - return -1; - - if (_PyIOBase_checkSeekable(raw, Py_True) == NULL) - return -1; - if (_PyIOBase_checkReadable(raw, Py_True) == NULL) - return -1; - if (_PyIOBase_checkWritable(raw, Py_True) == NULL) - return -1; - - Py_CLEAR(self->raw); - Py_INCREF(raw); - self->raw = raw; - self->buffer_size = buffer_size; - self->readable = 1; - self->writable = 1; - - if (_Buffered_init(self) < 0) - return -1; - _BufferedReader_reset_buf(self); - _BufferedWriter_reset_buf(self); - self->pos = 0; - - self->ok = 1; - return 0; -} - -static PyMethodDef BufferedRandom_methods[] = { - /* BufferedIOMixin methods */ - {"close", (PyCFunction)BufferedIOMixin_close, METH_NOARGS}, - {"seekable", (PyCFunction)BufferedIOMixin_seekable, METH_NOARGS}, - {"readable", (PyCFunction)BufferedIOMixin_readable, METH_NOARGS}, - {"writable", (PyCFunction)BufferedIOMixin_writable, METH_NOARGS}, - {"fileno", (PyCFunction)BufferedIOMixin_fileno, METH_NOARGS}, - {"isatty", (PyCFunction)BufferedIOMixin_isatty, METH_NOARGS}, - - {"flush", (PyCFunction)Buffered_flush, METH_NOARGS}, - - {"seek", (PyCFunction)Buffered_seek, METH_VARARGS}, - {"tell", (PyCFunction)Buffered_tell, METH_NOARGS}, - {"truncate", (PyCFunction)Buffered_truncate, METH_VARARGS}, - {"read", (PyCFunction)Buffered_read, METH_VARARGS}, - {"read1", (PyCFunction)Buffered_read1, METH_VARARGS}, - {"readinto", (PyCFunction)Buffered_readinto, METH_VARARGS}, - {"readline", (PyCFunction)Buffered_readline, METH_VARARGS}, - {"peek", (PyCFunction)Buffered_peek, METH_VARARGS}, - {"write", (PyCFunction)BufferedWriter_write, METH_VARARGS}, - {NULL, NULL} -}; - -static PyMemberDef BufferedRandom_members[] = { - {"raw", T_OBJECT, offsetof(BufferedObject, raw), 0}, - {NULL} -}; - -static PyGetSetDef BufferedRandom_getset[] = { - {"closed", (getter)BufferedIOMixin_closed_get, NULL, NULL}, - {"name", (getter)BufferedIOMixin_name_get, NULL, NULL}, - {"mode", (getter)BufferedIOMixin_mode_get, NULL, NULL}, - {0} -}; - - -PyTypeObject PyBufferedRandom_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.BufferedRandom", /*tp_name*/ - sizeof(BufferedObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)BufferedObject_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - BufferedRandom_doc, /* tp_doc */ - (traverseproc)Buffered_traverse, /* tp_traverse */ - (inquiry)Buffered_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(BufferedObject, weakreflist), /*tp_weaklistoffset*/ - 0, /* tp_iter */ - (iternextfunc)Buffered_iternext, /* tp_iternext */ - BufferedRandom_methods, /* tp_methods */ - BufferedRandom_members, /* tp_members */ - BufferedRandom_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /*tp_dict*/ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(BufferedObject, dict), /*tp_dictoffset*/ - (initproc)BufferedRandom_init, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; - Deleted: python/branches/py3k-short-float-repr/Modules/_bytesio.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_bytesio.c Sun Apr 5 01:04:14 2009 +++ (empty file) @@ -1,757 +0,0 @@ -#include "Python.h" -#include "structmember.h" /* for offsetof() */ -#include "_iomodule.h" - -typedef struct { - PyObject_HEAD - char *buf; - Py_ssize_t pos; - Py_ssize_t string_size; - size_t buf_size; - PyObject *dict; - PyObject *weakreflist; -} BytesIOObject; - -#define CHECK_CLOSED(self) \ - if ((self)->buf == NULL) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on closed file."); \ - return NULL; \ - } - -/* Internal routine to get a line from the buffer of a BytesIO - object. Returns the length between the current position to the - next newline character. */ -static Py_ssize_t -get_line(BytesIOObject *self, char **output) -{ - char *n; - const char *str_end; - Py_ssize_t len; - - assert(self->buf != NULL); - - /* Move to the end of the line, up to the end of the string, s. */ - str_end = self->buf + self->string_size; - for (n = self->buf + self->pos; - n < str_end && *n != '\n'; - n++); - - /* Skip the newline character */ - if (n < str_end) - n++; - - /* Get the length from the current position to the end of the line. */ - len = n - (self->buf + self->pos); - *output = self->buf + self->pos; - - assert(len >= 0); - assert(self->pos < PY_SSIZE_T_MAX - len); - self->pos += len; - - return len; -} - -/* Internal routine for changing the size of the buffer of BytesIO objects. - The caller should ensure that the 'size' argument is non-negative. Returns - 0 on success, -1 otherwise. */ -static int -resize_buffer(BytesIOObject *self, size_t size) -{ - /* Here, unsigned types are used to avoid dealing with signed integer - overflow, which is undefined in C. */ - size_t alloc = self->buf_size; - char *new_buf = NULL; - - assert(self->buf != NULL); - - /* For simplicity, stay in the range of the signed type. Anyway, Python - doesn't allow strings to be longer than this. */ - if (size > PY_SSIZE_T_MAX) - goto overflow; - - if (size < alloc / 2) { - /* Major downsize; resize down to exact size. */ - alloc = size + 1; - } - else if (size < alloc) { - /* Within allocated size; quick exit */ - return 0; - } - else if (size <= alloc * 1.125) { - /* Moderate upsize; overallocate similar to list_resize() */ - alloc = size + (size >> 3) + (size < 9 ? 3 : 6); - } - else { - /* Major upsize; resize up to exact size */ - alloc = size + 1; - } - - if (alloc > ((size_t)-1) / sizeof(char)) - goto overflow; - new_buf = (char *)PyMem_Realloc(self->buf, alloc * sizeof(char)); - if (new_buf == NULL) { - PyErr_NoMemory(); - return -1; - } - self->buf_size = alloc; - self->buf = new_buf; - - return 0; - - overflow: - PyErr_SetString(PyExc_OverflowError, - "new buffer size too large"); - return -1; -} - -/* Internal routine for writing a string of bytes to the buffer of a BytesIO - object. Returns the number of bytes wrote, or -1 on error. */ -static Py_ssize_t -write_bytes(BytesIOObject *self, const char *bytes, Py_ssize_t len) -{ - assert(self->buf != NULL); - assert(self->pos >= 0); - assert(len >= 0); - - if ((size_t)self->pos + len > self->buf_size) { - if (resize_buffer(self, (size_t)self->pos + len) < 0) - return -1; - } - - if (self->pos > self->string_size) { - /* In case of overseek, pad with null bytes the buffer region between - the end of stream and the current position. - - 0 lo string_size hi - | |<---used--->|<----------available----------->| - | | <--to pad-->|<---to write---> | - 0 buf position - */ - memset(self->buf + self->string_size, '\0', - (self->pos - self->string_size) * sizeof(char)); - } - - /* Copy the data to the internal buffer, overwriting some of the existing - data if self->pos < self->string_size. */ - memcpy(self->buf + self->pos, bytes, len); - self->pos += len; - - /* Set the new length of the internal string if it has changed. */ - if (self->string_size < self->pos) { - self->string_size = self->pos; - } - - return len; -} - -static PyObject * -bytesio_get_closed(BytesIOObject *self) -{ - if (self->buf == NULL) { - Py_RETURN_TRUE; - } - else { - Py_RETURN_FALSE; - } -} - -/* Generic getter for the writable, readable and seekable properties */ -static PyObject * -return_true(BytesIOObject *self) -{ - Py_RETURN_TRUE; -} - -PyDoc_STRVAR(flush_doc, -"flush() -> None. Does nothing."); - -static PyObject * -bytesio_flush(BytesIOObject *self) -{ - Py_RETURN_NONE; -} - -PyDoc_STRVAR(getval_doc, -"getvalue() -> bytes.\n" -"\n" -"Retrieve the entire contents of the BytesIO object."); - -static PyObject * -bytesio_getvalue(BytesIOObject *self) -{ - CHECK_CLOSED(self); - return PyBytes_FromStringAndSize(self->buf, self->string_size); -} - -PyDoc_STRVAR(isatty_doc, -"isatty() -> False.\n" -"\n" -"Always returns False since BytesIO objects are not connected\n" -"to a tty-like device."); - -static PyObject * -bytesio_isatty(BytesIOObject *self) -{ - CHECK_CLOSED(self); - Py_RETURN_FALSE; -} - -PyDoc_STRVAR(tell_doc, -"tell() -> current file position, an integer\n"); - -static PyObject * -bytesio_tell(BytesIOObject *self) -{ - CHECK_CLOSED(self); - return PyLong_FromSsize_t(self->pos); -} - -PyDoc_STRVAR(read_doc, -"read([size]) -> read at most size bytes, returned as a string.\n" -"\n" -"If the size argument is negative, read until EOF is reached.\n" -"Return an empty string at EOF."); - -static PyObject * -bytesio_read(BytesIOObject *self, PyObject *args) -{ - Py_ssize_t size, n; - char *output; - PyObject *arg = Py_None; - - CHECK_CLOSED(self); - - if (!PyArg_ParseTuple(args, "|O:read", &arg)) - return NULL; - - if (PyLong_Check(arg)) { - size = PyLong_AsSsize_t(arg); - if (size == -1 && PyErr_Occurred()) - return NULL; - } - else if (arg == Py_None) { - /* Read until EOF is reached, by default. */ - size = -1; - } - else { - PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", - Py_TYPE(arg)->tp_name); - return NULL; - } - - /* adjust invalid sizes */ - n = self->string_size - self->pos; - if (size < 0 || size > n) { - size = n; - if (size < 0) - size = 0; - } - - assert(self->buf != NULL); - output = self->buf + self->pos; - self->pos += size; - - return PyBytes_FromStringAndSize(output, size); -} - - -PyDoc_STRVAR(read1_doc, -"read1(size) -> read at most size bytes, returned as a string.\n" -"\n" -"If the size argument is negative or omitted, read until EOF is reached.\n" -"Return an empty string at EOF."); - -static PyObject * -bytesio_read1(BytesIOObject *self, PyObject *n) -{ - PyObject *arg, *res; - - arg = PyTuple_Pack(1, n); - if (arg == NULL) - return NULL; - res = bytesio_read(self, arg); - Py_DECREF(arg); - return res; -} - -PyDoc_STRVAR(readline_doc, -"readline([size]) -> next line from the file, as a string.\n" -"\n" -"Retain newline. A non-negative size argument limits the maximum\n" -"number of bytes to return (an incomplete line may be returned then).\n" -"Return an empty string at EOF.\n"); - -static PyObject * -bytesio_readline(BytesIOObject *self, PyObject *args) -{ - Py_ssize_t size, n; - char *output; - PyObject *arg = Py_None; - - CHECK_CLOSED(self); - - if (!PyArg_ParseTuple(args, "|O:readline", &arg)) - return NULL; - - if (PyLong_Check(arg)) { - size = PyLong_AsSsize_t(arg); - if (size == -1 && PyErr_Occurred()) - return NULL; - } - else if (arg == Py_None) { - /* No size limit, by default. */ - size = -1; - } - else { - PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", - Py_TYPE(arg)->tp_name); - return NULL; - } - - n = get_line(self, &output); - - if (size >= 0 && size < n) { - size = n - size; - n -= size; - self->pos -= size; - } - - return PyBytes_FromStringAndSize(output, n); -} - -PyDoc_STRVAR(readlines_doc, -"readlines([size]) -> list of strings, each a line from the file.\n" -"\n" -"Call readline() repeatedly and return a list of the lines so read.\n" -"The optional size argument, if given, is an approximate bound on the\n" -"total number of bytes in the lines returned.\n"); - -static PyObject * -bytesio_readlines(BytesIOObject *self, PyObject *args) -{ - Py_ssize_t maxsize, size, n; - PyObject *result, *line; - char *output; - PyObject *arg = Py_None; - - CHECK_CLOSED(self); - - if (!PyArg_ParseTuple(args, "|O:readlines", &arg)) - return NULL; - - if (PyLong_Check(arg)) { - maxsize = PyLong_AsSsize_t(arg); - if (maxsize == -1 && PyErr_Occurred()) - return NULL; - } - else if (arg == Py_None) { - /* No size limit, by default. */ - maxsize = -1; - } - else { - PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", - Py_TYPE(arg)->tp_name); - return NULL; - } - - size = 0; - result = PyList_New(0); - if (!result) - return NULL; - - while ((n = get_line(self, &output)) != 0) { - line = PyBytes_FromStringAndSize(output, n); - if (!line) - goto on_error; - if (PyList_Append(result, line) == -1) { - Py_DECREF(line); - goto on_error; - } - Py_DECREF(line); - size += n; - if (maxsize > 0 && size >= maxsize) - break; - } - return result; - - on_error: - Py_DECREF(result); - return NULL; -} - -PyDoc_STRVAR(readinto_doc, -"readinto(bytearray) -> int. Read up to len(b) bytes into b.\n" -"\n" -"Returns number of bytes read (0 for EOF), or None if the object\n" -"is set not to block as has no data to read."); - -static PyObject * -bytesio_readinto(BytesIOObject *self, PyObject *buffer) -{ - void *raw_buffer; - Py_ssize_t len; - - CHECK_CLOSED(self); - - if (PyObject_AsWriteBuffer(buffer, &raw_buffer, &len) == -1) - return NULL; - - if (self->pos + len > self->string_size) - len = self->string_size - self->pos; - - memcpy(raw_buffer, self->buf + self->pos, len); - assert(self->pos + len < PY_SSIZE_T_MAX); - assert(len >= 0); - self->pos += len; - - return PyLong_FromSsize_t(len); -} - -PyDoc_STRVAR(truncate_doc, -"truncate([size]) -> int. Truncate the file to at most size bytes.\n" -"\n" -"Size defaults to the current file position, as returned by tell().\n" -"Returns the new size. Imply an absolute seek to the position size."); - -static PyObject * -bytesio_truncate(BytesIOObject *self, PyObject *args) -{ - Py_ssize_t size; - PyObject *arg = Py_None; - - CHECK_CLOSED(self); - - if (!PyArg_ParseTuple(args, "|O:truncate", &arg)) - return NULL; - - if (PyLong_Check(arg)) { - size = PyLong_AsSsize_t(arg); - if (size == -1 && PyErr_Occurred()) - return NULL; - } - else if (arg == Py_None) { - /* Truncate to current position if no argument is passed. */ - size = self->pos; - } - else { - PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", - Py_TYPE(arg)->tp_name); - return NULL; - } - - if (size < 0) { - PyErr_Format(PyExc_ValueError, - "negative size value %zd", size); - return NULL; - } - - if (size < self->string_size) { - self->string_size = size; - if (resize_buffer(self, size) < 0) - return NULL; - } - self->pos = size; - - return PyLong_FromSsize_t(size); -} - -static PyObject * -bytesio_iternext(BytesIOObject *self) -{ - char *next; - Py_ssize_t n; - - CHECK_CLOSED(self); - - n = get_line(self, &next); - - if (!next || n == 0) - return NULL; - - return PyBytes_FromStringAndSize(next, n); -} - -PyDoc_STRVAR(seek_doc, -"seek(pos, whence=0) -> int. Change stream position.\n" -"\n" -"Seek to byte offset pos relative to position indicated by whence:\n" -" 0 Start of stream (the default). pos should be >= 0;\n" -" 1 Current position - pos may be negative;\n" -" 2 End of stream - pos usually negative.\n" -"Returns the new absolute position."); - -static PyObject * -bytesio_seek(BytesIOObject *self, PyObject *args) -{ - Py_ssize_t pos; - int mode = 0; - - CHECK_CLOSED(self); - - if (!PyArg_ParseTuple(args, "n|i:seek", &pos, &mode)) - return NULL; - - if (pos < 0 && mode == 0) { - PyErr_Format(PyExc_ValueError, - "negative seek value %zd", pos); - return NULL; - } - - /* mode 0: offset relative to beginning of the string. - mode 1: offset relative to current position. - mode 2: offset relative the end of the string. */ - if (mode == 1) { - if (pos > PY_SSIZE_T_MAX - self->pos) { - PyErr_SetString(PyExc_OverflowError, - "new position too large"); - return NULL; - } - pos += self->pos; - } - else if (mode == 2) { - if (pos > PY_SSIZE_T_MAX - self->string_size) { - PyErr_SetString(PyExc_OverflowError, - "new position too large"); - return NULL; - } - pos += self->string_size; - } - else if (mode != 0) { - PyErr_Format(PyExc_ValueError, - "invalid whence (%i, should be 0, 1 or 2)", mode); - return NULL; - } - - if (pos < 0) - pos = 0; - self->pos = pos; - - return PyLong_FromSsize_t(self->pos); -} - -PyDoc_STRVAR(write_doc, -"write(bytes) -> int. Write bytes to file.\n" -"\n" -"Return the number of bytes written."); - -static PyObject * -bytesio_write(BytesIOObject *self, PyObject *obj) -{ - Py_ssize_t n = 0; - Py_buffer buf; - PyObject *result = NULL; - - CHECK_CLOSED(self); - - if (PyObject_GetBuffer(obj, &buf, PyBUF_CONTIG_RO) < 0) - return NULL; - - if (buf.len != 0) - n = write_bytes(self, buf.buf, buf.len); - if (n >= 0) - result = PyLong_FromSsize_t(n); - - PyBuffer_Release(&buf); - return result; -} - -PyDoc_STRVAR(writelines_doc, -"writelines(sequence_of_strings) -> None. Write strings to the file.\n" -"\n" -"Note that newlines are not added. The sequence can be any iterable\n" -"object producing strings. This is equivalent to calling write() for\n" -"each string."); - -static PyObject * -bytesio_writelines(BytesIOObject *self, PyObject *v) -{ - PyObject *it, *item; - PyObject *ret; - - CHECK_CLOSED(self); - - it = PyObject_GetIter(v); - if (it == NULL) - return NULL; - - while ((item = PyIter_Next(it)) != NULL) { - ret = bytesio_write(self, item); - Py_DECREF(item); - if (ret == NULL) { - Py_DECREF(it); - return NULL; - } - Py_DECREF(ret); - } - Py_DECREF(it); - - /* See if PyIter_Next failed */ - if (PyErr_Occurred()) - return NULL; - - Py_RETURN_NONE; -} - -PyDoc_STRVAR(close_doc, -"close() -> None. Disable all I/O operations."); - -static PyObject * -bytesio_close(BytesIOObject *self) -{ - if (self->buf != NULL) { - PyMem_Free(self->buf); - self->buf = NULL; - } - Py_RETURN_NONE; -} - -static void -bytesio_dealloc(BytesIOObject *self) -{ - if (self->buf != NULL) { - PyMem_Free(self->buf); - self->buf = NULL; - } - Py_TYPE(self)->tp_clear((PyObject *)self); - Py_TYPE(self)->tp_free(self); -} - -static PyObject * -bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - BytesIOObject *self; - - assert(type != NULL && type->tp_alloc != NULL); - self = (BytesIOObject *)type->tp_alloc(type, 0); - if (self == NULL) - return NULL; - - self->string_size = 0; - self->pos = 0; - self->buf_size = 0; - self->buf = (char *)PyMem_Malloc(0); - if (self->buf == NULL) { - Py_DECREF(self); - return PyErr_NoMemory(); - } - - return (PyObject *)self; -} - -static int -bytesio_init(BytesIOObject *self, PyObject *args, PyObject *kwds) -{ - PyObject *initvalue = NULL; - - if (!PyArg_ParseTuple(args, "|O:BytesIO", &initvalue)) - return -1; - - /* In case, __init__ is called multiple times. */ - self->string_size = 0; - self->pos = 0; - - if (initvalue && initvalue != Py_None) { - PyObject *res; - res = bytesio_write(self, initvalue); - if (res == NULL) - return -1; - Py_DECREF(res); - self->pos = 0; - } - - return 0; -} - -static int -bytesio_traverse(BytesIOObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->dict); - Py_VISIT(self->weakreflist); - return 0; -} - -static int -bytesio_clear(BytesIOObject *self) -{ - Py_CLEAR(self->dict); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *)self); - return 0; -} - - -static PyGetSetDef bytesio_getsetlist[] = { - {"closed", (getter)bytesio_get_closed, NULL, - "True if the file is closed."}, - {0}, /* sentinel */ -}; - -static struct PyMethodDef bytesio_methods[] = { - {"readable", (PyCFunction)return_true, METH_NOARGS, NULL}, - {"seekable", (PyCFunction)return_true, METH_NOARGS, NULL}, - {"writable", (PyCFunction)return_true, METH_NOARGS, NULL}, - {"close", (PyCFunction)bytesio_close, METH_NOARGS, close_doc}, - {"flush", (PyCFunction)bytesio_flush, METH_NOARGS, flush_doc}, - {"isatty", (PyCFunction)bytesio_isatty, METH_NOARGS, isatty_doc}, - {"tell", (PyCFunction)bytesio_tell, METH_NOARGS, tell_doc}, - {"write", (PyCFunction)bytesio_write, METH_O, write_doc}, - {"writelines", (PyCFunction)bytesio_writelines, METH_O, writelines_doc}, - {"read1", (PyCFunction)bytesio_read1, METH_O, read1_doc}, - {"readinto", (PyCFunction)bytesio_readinto, METH_O, readinto_doc}, - {"readline", (PyCFunction)bytesio_readline, METH_VARARGS, readline_doc}, - {"readlines", (PyCFunction)bytesio_readlines, METH_VARARGS, readlines_doc}, - {"read", (PyCFunction)bytesio_read, METH_VARARGS, read_doc}, - {"getvalue", (PyCFunction)bytesio_getvalue, METH_VARARGS, getval_doc}, - {"seek", (PyCFunction)bytesio_seek, METH_VARARGS, seek_doc}, - {"truncate", (PyCFunction)bytesio_truncate, METH_VARARGS, truncate_doc}, - {NULL, NULL} /* sentinel */ -}; - -PyDoc_STRVAR(bytesio_doc, -"BytesIO([buffer]) -> object\n" -"\n" -"Create a buffered I/O implementation using an in-memory bytes\n" -"buffer, ready for reading and writing."); - -PyTypeObject PyBytesIO_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.BytesIO", /*tp_name*/ - sizeof(BytesIOObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)bytesio_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*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - bytesio_doc, /*tp_doc*/ - (traverseproc)bytesio_traverse, /*tp_traverse*/ - (inquiry)bytesio_clear, /*tp_clear*/ - 0, /*tp_richcompare*/ - offsetof(BytesIOObject, weakreflist), /*tp_weaklistoffset*/ - PyObject_SelfIter, /*tp_iter*/ - (iternextfunc)bytesio_iternext, /*tp_iternext*/ - bytesio_methods, /*tp_methods*/ - 0, /*tp_members*/ - bytesio_getsetlist, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - offsetof(BytesIOObject, dict), /*tp_dictoffset*/ - (initproc)bytesio_init, /*tp_init*/ - 0, /*tp_alloc*/ - bytesio_new, /*tp_new*/ -}; Modified: python/branches/py3k-short-float-repr/Modules/_cursesmodule.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_cursesmodule.c (original) +++ python/branches/py3k-short-float-repr/Modules/_cursesmodule.c Sun Apr 5 01:04:14 2009 @@ -890,7 +890,7 @@ PyErr_SetString(PyCursesError, "no input"); return NULL; } else if (rtn<=255) - return Py_BuildValue("c", rtn); + return Py_BuildValue("C", rtn); else #if defined(__NetBSD__) return PyUnicode_FromString(unctrl(rtn)); Deleted: python/branches/py3k-short-float-repr/Modules/_fileio.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_fileio.c Sun Apr 5 01:04:14 2009 +++ (empty file) @@ -1,1034 +0,0 @@ -/* Author: Daniel Stutzbach */ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#include -#include -#include -#include /* For offsetof */ -#include "_iomodule.h" - -/* - * Known likely problems: - * - * - Files larger then 2**32-1 - * - Files with unicode filenames - * - Passing numbers greater than 2**32-1 when an integer is expected - * - Making it work on Windows and other oddball platforms - * - * To Do: - * - * - autoconfify header file inclusion - */ - -#ifdef MS_WINDOWS -/* can simulate truncate with Win32 API functions; see file_truncate */ -#define HAVE_FTRUNCATE -#define WIN32_LEAN_AND_MEAN -#include -#endif - -#if BUFSIZ < (8*1024) -#define SMALLCHUNK (8*1024) -#elif (BUFSIZ >= (2 << 25)) -#error "unreasonable BUFSIZ > 64MB defined" -#else -#define SMALLCHUNK BUFSIZ -#endif - -#if SIZEOF_INT < 4 -#define BIGCHUNK (512 * 32) -#else -#define BIGCHUNK (512 * 1024) -#endif - -typedef struct { - PyObject_HEAD - int fd; - unsigned readable : 1; - unsigned writable : 1; - int seekable : 2; /* -1 means unknown */ - int closefd : 1; - PyObject *weakreflist; - PyObject *dict; -} PyFileIOObject; - -PyTypeObject PyFileIO_Type; - -#define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type)) - -int -_PyFileIO_closed(PyObject *self) -{ - return ((PyFileIOObject *)self)->fd < 0; -} - -static PyObject * -portable_lseek(int fd, PyObject *posobj, int whence); - -static PyObject *portable_lseek(int fd, PyObject *posobj, int whence); - -/* Returns 0 on success, -1 with exception set on failure. */ -static int -internal_close(PyFileIOObject *self) -{ - int err = 0; - int save_errno = 0; - if (self->fd >= 0) { - int fd = self->fd; - self->fd = -1; - /* fd is accessible and someone else may have closed it */ - if (_PyVerify_fd(fd)) { - Py_BEGIN_ALLOW_THREADS - err = close(fd); - if (err < 0) - save_errno = errno; - Py_END_ALLOW_THREADS - } else { - save_errno = errno; - err = -1; - } - } - if (err < 0) { - errno = save_errno; - PyErr_SetFromErrno(PyExc_IOError); - return -1; - } - return 0; -} - -static PyObject * -fileio_close(PyFileIOObject *self) -{ - if (!self->closefd) { - self->fd = -1; - Py_RETURN_NONE; - } - errno = internal_close(self); - if (errno < 0) - return NULL; - - return PyObject_CallMethod((PyObject*)&PyRawIOBase_Type, - "close", "O", self); -} - -static PyObject * -fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyFileIOObject *self; - - assert(type != NULL && type->tp_alloc != NULL); - - self = (PyFileIOObject *) type->tp_alloc(type, 0); - if (self != NULL) { - self->fd = -1; - self->readable = 0; - self->writable = 0; - self->seekable = -1; - self->closefd = 1; - self->weakreflist = NULL; - } - - return (PyObject *) self; -} - -/* On Unix, open will succeed for directories. - In Python, there should be no file objects referring to - directories, so we need a check. */ - -static int -dircheck(PyFileIOObject* self, const char *name) -{ -#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR) - struct stat buf; - if (self->fd < 0) - return 0; - if (fstat(self->fd, &buf) == 0 && S_ISDIR(buf.st_mode)) { - char *msg = strerror(EISDIR); - PyObject *exc; - if (internal_close(self)) - return -1; - - exc = PyObject_CallFunction(PyExc_IOError, "(iss)", - EISDIR, msg, name); - PyErr_SetObject(PyExc_IOError, exc); - Py_XDECREF(exc); - return -1; - } -#endif - return 0; -} - -static int -check_fd(int fd) -{ -#if defined(HAVE_FSTAT) - struct stat buf; - if (!_PyVerify_fd(fd) || (fstat(fd, &buf) < 0 && errno == EBADF)) { - PyObject *exc; - char *msg = strerror(EBADF); - exc = PyObject_CallFunction(PyExc_OSError, "(is)", - EBADF, msg); - PyErr_SetObject(PyExc_OSError, exc); - Py_XDECREF(exc); - return -1; - } -#endif - return 0; -} - - -static int -fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) -{ - PyFileIOObject *self = (PyFileIOObject *) oself; - static char *kwlist[] = {"file", "mode", "closefd", NULL}; - const char *name = NULL; - PyObject *nameobj, *stringobj = NULL; - char *mode = "r"; - char *s; -#ifdef MS_WINDOWS - Py_UNICODE *widename = NULL; -#endif - int ret = 0; - int rwa = 0, plus = 0, append = 0; - int flags = 0; - int fd = -1; - int closefd = 1; - - assert(PyFileIO_Check(oself)); - if (self->fd >= 0) { - /* Have to close the existing file first. */ - if (internal_close(self) < 0) - return -1; - } - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|si:fileio", - kwlist, &nameobj, &mode, &closefd)) - return -1; - - if (PyFloat_Check(nameobj)) { - PyErr_SetString(PyExc_TypeError, - "integer argument expected, got float"); - return -1; - } - - fd = PyLong_AsLong(nameobj); - if (fd < 0) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_ValueError, - "Negative filedescriptor"); - return -1; - } - PyErr_Clear(); - } - -#ifdef Py_WIN_WIDE_FILENAMES - if (GetVersion() < 0x80000000) { - /* On NT, so wide API available */ - if (PyUnicode_Check(nameobj)) - widename = PyUnicode_AS_UNICODE(nameobj); - } - if (widename == NULL) -#endif - if (fd < 0) - { - if (PyBytes_Check(nameobj) || PyByteArray_Check(nameobj)) { - Py_ssize_t namelen; - if (PyObject_AsCharBuffer(nameobj, &name, &namelen) < 0) - return -1; - } - else { - PyObject *u = PyUnicode_FromObject(nameobj); - - if (u == NULL) - return -1; - - stringobj = PyUnicode_AsEncodedString( - u, Py_FileSystemDefaultEncoding, NULL); - Py_DECREF(u); - if (stringobj == NULL) - return -1; - if (!PyBytes_Check(stringobj)) { - PyErr_SetString(PyExc_TypeError, - "encoder failed to return bytes"); - goto error; - } - name = PyBytes_AS_STRING(stringobj); - } - } - - s = mode; - while (*s) { - switch (*s++) { - case 'r': - if (rwa) { - bad_mode: - PyErr_SetString(PyExc_ValueError, - "Must have exactly one of read/write/append mode"); - goto error; - } - rwa = 1; - self->readable = 1; - break; - case 'w': - if (rwa) - goto bad_mode; - rwa = 1; - self->writable = 1; - flags |= O_CREAT | O_TRUNC; - break; - case 'a': - if (rwa) - goto bad_mode; - rwa = 1; - self->writable = 1; - flags |= O_CREAT; - append = 1; - break; - case 'b': - break; - case '+': - if (plus) - goto bad_mode; - self->readable = self->writable = 1; - plus = 1; - break; - default: - PyErr_Format(PyExc_ValueError, - "invalid mode: %.200s", mode); - goto error; - } - } - - if (!rwa) - goto bad_mode; - - if (self->readable && self->writable) - flags |= O_RDWR; - else if (self->readable) - flags |= O_RDONLY; - else - flags |= O_WRONLY; - -#ifdef O_BINARY - flags |= O_BINARY; -#endif - -#ifdef O_APPEND - if (append) - flags |= O_APPEND; -#endif - - if (fd >= 0) { - if (check_fd(fd)) - goto error; - self->fd = fd; - self->closefd = closefd; - } - else { - self->closefd = 1; - if (!closefd) { - PyErr_SetString(PyExc_ValueError, - "Cannot use closefd=False with file name"); - goto error; - } - - Py_BEGIN_ALLOW_THREADS - errno = 0; -#ifdef MS_WINDOWS - if (widename != NULL) - self->fd = _wopen(widename, flags, 0666); - else -#endif - self->fd = open(name, flags, 0666); - Py_END_ALLOW_THREADS - if (self->fd < 0) { -#ifdef MS_WINDOWS - if (widename != NULL) - PyErr_SetFromErrnoWithUnicodeFilename(PyExc_IOError, widename); - else -#endif - PyErr_SetFromErrnoWithFilename(PyExc_IOError, name); - goto error; - } - if(dircheck(self, name) < 0) - goto error; - } - - if (PyObject_SetAttrString((PyObject *)self, "name", nameobj) < 0) - goto error; - - if (append) { - /* For consistent behaviour, we explicitly seek to the - end of file (otherwise, it might be done only on the - first write()). */ - PyObject *pos = portable_lseek(self->fd, NULL, 2); - if (pos == NULL) - goto error; - Py_DECREF(pos); - } - - goto done; - - error: - ret = -1; - - done: - Py_CLEAR(stringobj); - return ret; -} - -static int -fileio_traverse(PyFileIOObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->dict); - return 0; -} - -static int -fileio_clear(PyFileIOObject *self) -{ - Py_CLEAR(self->dict); - return 0; -} - -static void -fileio_dealloc(PyFileIOObject *self) -{ - if (_PyIOBase_finalize((PyObject *) self) < 0) - return; - _PyObject_GC_UNTRACK(self); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - Py_CLEAR(self->dict); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static PyObject * -err_closed(void) -{ - PyErr_SetString(PyExc_ValueError, "I/O operation on closed file"); - return NULL; -} - -static PyObject * -err_mode(char *action) -{ - PyErr_Format(PyExc_ValueError, "File not open for %s", action); - return NULL; -} - -static PyObject * -fileio_fileno(PyFileIOObject *self) -{ - if (self->fd < 0) - return err_closed(); - return PyLong_FromLong((long) self->fd); -} - -static PyObject * -fileio_readable(PyFileIOObject *self) -{ - if (self->fd < 0) - return err_closed(); - return PyBool_FromLong((long) self->readable); -} - -static PyObject * -fileio_writable(PyFileIOObject *self) -{ - if (self->fd < 0) - return err_closed(); - return PyBool_FromLong((long) self->writable); -} - -static PyObject * -fileio_seekable(PyFileIOObject *self) -{ - if (self->fd < 0) - return err_closed(); - if (self->seekable < 0) { - PyObject *pos = portable_lseek(self->fd, NULL, SEEK_CUR); - if (pos == NULL) { - PyErr_Clear(); - self->seekable = 0; - } else { - Py_DECREF(pos); - self->seekable = 1; - } - } - return PyBool_FromLong((long) self->seekable); -} - -static PyObject * -fileio_readinto(PyFileIOObject *self, PyObject *args) -{ - Py_buffer pbuf; - Py_ssize_t n; - - if (self->fd < 0) - return err_closed(); - if (!self->readable) - return err_mode("reading"); - - if (!PyArg_ParseTuple(args, "w*", &pbuf)) - return NULL; - - if (_PyVerify_fd(self->fd)) { - Py_BEGIN_ALLOW_THREADS - errno = 0; - n = read(self->fd, pbuf.buf, pbuf.len); - Py_END_ALLOW_THREADS - } else - n = -1; - PyBuffer_Release(&pbuf); - if (n < 0) { - if (errno == EAGAIN) - Py_RETURN_NONE; - PyErr_SetFromErrno(PyExc_IOError); - return NULL; - } - - return PyLong_FromSsize_t(n); -} - -static size_t -new_buffersize(PyFileIOObject *self, size_t currentsize) -{ -#ifdef HAVE_FSTAT - off_t pos, end; - struct stat st; - if (fstat(self->fd, &st) == 0) { - end = st.st_size; - pos = lseek(self->fd, 0L, SEEK_CUR); - /* Files claiming a size smaller than SMALLCHUNK may - actually be streaming pseudo-files. In this case, we - apply the more aggressive algorithm below. - */ - if (end >= SMALLCHUNK && end >= pos && pos >= 0) { - /* Add 1 so if the file were to grow we'd notice. */ - return currentsize + end - pos + 1; - } - } -#endif - if (currentsize > SMALLCHUNK) { - /* Keep doubling until we reach BIGCHUNK; - then keep adding BIGCHUNK. */ - if (currentsize <= BIGCHUNK) - return currentsize + currentsize; - else - return currentsize + BIGCHUNK; - } - return currentsize + SMALLCHUNK; -} - -static PyObject * -fileio_readall(PyFileIOObject *self) -{ - PyObject *result; - Py_ssize_t total = 0; - int n; - - if (!_PyVerify_fd(self->fd)) - return PyErr_SetFromErrno(PyExc_IOError); - - result = PyBytes_FromStringAndSize(NULL, SMALLCHUNK); - if (result == NULL) - return NULL; - - while (1) { - size_t newsize = new_buffersize(self, total); - if (newsize > PY_SSIZE_T_MAX || newsize <= 0) { - PyErr_SetString(PyExc_OverflowError, - "unbounded read returned more bytes " - "than a Python string can hold "); - Py_DECREF(result); - return NULL; - } - - if (PyBytes_GET_SIZE(result) < newsize) { - if (_PyBytes_Resize(&result, newsize) < 0) { - if (total == 0) { - Py_DECREF(result); - return NULL; - } - PyErr_Clear(); - break; - } - } - Py_BEGIN_ALLOW_THREADS - errno = 0; - n = read(self->fd, - PyBytes_AS_STRING(result) + total, - newsize - total); - Py_END_ALLOW_THREADS - if (n == 0) - break; - if (n < 0) { - if (total > 0) - break; - if (errno == EAGAIN) { - Py_DECREF(result); - Py_RETURN_NONE; - } - Py_DECREF(result); - PyErr_SetFromErrno(PyExc_IOError); - return NULL; - } - total += n; - } - - if (PyBytes_GET_SIZE(result) > total) { - if (_PyBytes_Resize(&result, total) < 0) { - /* This should never happen, but just in case */ - Py_DECREF(result); - return NULL; - } - } - return result; -} - -static PyObject * -fileio_read(PyFileIOObject *self, PyObject *args) -{ - char *ptr; - Py_ssize_t n; - Py_ssize_t size = -1; - PyObject *bytes; - - if (self->fd < 0) - return err_closed(); - if (!self->readable) - return err_mode("reading"); - - if (!PyArg_ParseTuple(args, "|n", &size)) - return NULL; - - if (size < 0) { - return fileio_readall(self); - } - - bytes = PyBytes_FromStringAndSize(NULL, size); - if (bytes == NULL) - return NULL; - ptr = PyBytes_AS_STRING(bytes); - - if (_PyVerify_fd(self->fd)) { - Py_BEGIN_ALLOW_THREADS - errno = 0; - n = read(self->fd, ptr, size); - Py_END_ALLOW_THREADS - } else - n = -1; - - if (n < 0) { - Py_DECREF(bytes); - if (errno == EAGAIN) - Py_RETURN_NONE; - PyErr_SetFromErrno(PyExc_IOError); - return NULL; - } - - if (n != size) { - if (_PyBytes_Resize(&bytes, n) < 0) { - Py_DECREF(bytes); - return NULL; - } - } - - return (PyObject *) bytes; -} - -static PyObject * -fileio_write(PyFileIOObject *self, PyObject *args) -{ - Py_buffer pbuf; - Py_ssize_t n; - - if (self->fd < 0) - return err_closed(); - if (!self->writable) - return err_mode("writing"); - - if (!PyArg_ParseTuple(args, "s*", &pbuf)) - return NULL; - - if (_PyVerify_fd(self->fd)) { - Py_BEGIN_ALLOW_THREADS - errno = 0; - n = write(self->fd, pbuf.buf, pbuf.len); - Py_END_ALLOW_THREADS - } else - n = -1; - - PyBuffer_Release(&pbuf); - - if (n < 0) { - if (errno == EAGAIN) - Py_RETURN_NONE; - PyErr_SetFromErrno(PyExc_IOError); - return NULL; - } - - return PyLong_FromSsize_t(n); -} - -/* XXX Windows support below is likely incomplete */ - -/* Cribbed from posix_lseek() */ -static PyObject * -portable_lseek(int fd, PyObject *posobj, int whence) -{ - Py_off_t pos, res; - -#ifdef SEEK_SET - /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ - switch (whence) { -#if SEEK_SET != 0 - case 0: whence = SEEK_SET; break; -#endif -#if SEEK_CUR != 1 - case 1: whence = SEEK_CUR; break; -#endif -#if SEEK_END != 2 - case 2: whence = SEEK_END; break; -#endif - } -#endif /* SEEK_SET */ - - if (posobj == NULL) - pos = 0; - else { - if(PyFloat_Check(posobj)) { - PyErr_SetString(PyExc_TypeError, "an integer is required"); - return NULL; - } -#if defined(HAVE_LARGEFILE_SUPPORT) - pos = PyLong_AsLongLong(posobj); -#else - pos = PyLong_AsLong(posobj); -#endif - if (PyErr_Occurred()) - return NULL; - } - - if (_PyVerify_fd(fd)) { - Py_BEGIN_ALLOW_THREADS -#if defined(MS_WIN64) || defined(MS_WINDOWS) - res = _lseeki64(fd, pos, whence); -#else - res = lseek(fd, pos, whence); -#endif - Py_END_ALLOW_THREADS - } else - res = -1; - if (res < 0) - return PyErr_SetFromErrno(PyExc_IOError); - -#if defined(HAVE_LARGEFILE_SUPPORT) - return PyLong_FromLongLong(res); -#else - return PyLong_FromLong(res); -#endif -} - -static PyObject * -fileio_seek(PyFileIOObject *self, PyObject *args) -{ - PyObject *posobj; - int whence = 0; - - if (self->fd < 0) - return err_closed(); - - if (!PyArg_ParseTuple(args, "O|i", &posobj, &whence)) - return NULL; - - return portable_lseek(self->fd, posobj, whence); -} - -static PyObject * -fileio_tell(PyFileIOObject *self, PyObject *args) -{ - if (self->fd < 0) - return err_closed(); - - return portable_lseek(self->fd, NULL, 1); -} - -#ifdef HAVE_FTRUNCATE -static PyObject * -fileio_truncate(PyFileIOObject *self, PyObject *args) -{ - PyObject *posobj = NULL; - Py_off_t pos; - int ret; - int fd; - - fd = self->fd; - if (fd < 0) - return err_closed(); - if (!self->writable) - return err_mode("writing"); - - if (!PyArg_ParseTuple(args, "|O", &posobj)) - return NULL; - - if (posobj == Py_None || posobj == NULL) { - /* Get the current position. */ - posobj = portable_lseek(fd, NULL, 1); - if (posobj == NULL) - return NULL; - } - else { - /* Move to the position to be truncated. */ - posobj = portable_lseek(fd, posobj, 0); - } - if (posobj == NULL) - return NULL; - -#if defined(HAVE_LARGEFILE_SUPPORT) - pos = PyLong_AsLongLong(posobj); -#else - pos = PyLong_AsLong(posobj); -#endif - if (pos == -1 && PyErr_Occurred()) - return NULL; - -#ifdef MS_WINDOWS - /* MS _chsize doesn't work if newsize doesn't fit in 32 bits, - so don't even try using it. */ - { - HANDLE hFile; - - /* Truncate. Note that this may grow the file! */ - Py_BEGIN_ALLOW_THREADS - errno = 0; - hFile = (HANDLE)_get_osfhandle(fd); - ret = hFile == (HANDLE)-1; - if (ret == 0) { - ret = SetEndOfFile(hFile) == 0; - if (ret) - errno = EACCES; - } - Py_END_ALLOW_THREADS - } -#else - Py_BEGIN_ALLOW_THREADS - errno = 0; - ret = ftruncate(fd, pos); - Py_END_ALLOW_THREADS -#endif /* !MS_WINDOWS */ - - if (ret != 0) { - PyErr_SetFromErrno(PyExc_IOError); - return NULL; - } - - return posobj; -} -#endif - -static char * -mode_string(PyFileIOObject *self) -{ - if (self->readable) { - if (self->writable) - return "rb+"; - else - return "rb"; - } - else - return "wb"; -} - -static PyObject * -fileio_repr(PyFileIOObject *self) -{ - if (self->fd < 0) - return PyUnicode_FromFormat("io.FileIO(-1)"); - - return PyUnicode_FromFormat("io.FileIO(%d, '%s')", - self->fd, mode_string(self)); -} - -static PyObject * -fileio_isatty(PyFileIOObject *self) -{ - long res; - - if (self->fd < 0) - return err_closed(); - Py_BEGIN_ALLOW_THREADS - res = isatty(self->fd); - Py_END_ALLOW_THREADS - return PyBool_FromLong(res); -} - - -PyDoc_STRVAR(fileio_doc, -"file(name: str[, mode: str]) -> file IO object\n" -"\n" -"Open a file. The mode can be 'r', 'w' or 'a' for reading (default),\n" -"writing or appending. The file will be created if it doesn't exist\n" -"when opened for writing or appending; it will be truncated when\n" -"opened for writing. Add a '+' to the mode to allow simultaneous\n" -"reading and writing."); - -PyDoc_STRVAR(read_doc, -"read(size: int) -> bytes. read at most size bytes, returned as bytes.\n" -"\n" -"Only makes one system call, so less data may be returned than requested\n" -"In non-blocking mode, returns None if no data is available.\n" -"On end-of-file, returns ''."); - -PyDoc_STRVAR(readall_doc, -"readall() -> bytes. read all data from the file, returned as bytes.\n" -"\n" -"In non-blocking mode, returns as much as is immediately available,\n" -"or None if no data is available. On end-of-file, returns ''."); - -PyDoc_STRVAR(write_doc, -"write(b: bytes) -> int. Write bytes b to file, return number written.\n" -"\n" -"Only makes one system call, so not all of the data may be written.\n" -"The number of bytes actually written is returned."); - -PyDoc_STRVAR(fileno_doc, -"fileno() -> int. \"file descriptor\".\n" -"\n" -"This is needed for lower-level file interfaces, such the fcntl module."); - -PyDoc_STRVAR(seek_doc, -"seek(offset: int[, whence: int]) -> None. Move to new file position.\n" -"\n" -"Argument offset is a byte count. Optional argument whence defaults to\n" -"0 (offset from start of file, offset should be >= 0); other values are 1\n" -"(move relative to current position, positive or negative), and 2 (move\n" -"relative to end of file, usually negative, although many platforms allow\n" -"seeking beyond the end of a file)." -"\n" -"Note that not all file objects are seekable."); - -#ifdef HAVE_FTRUNCATE -PyDoc_STRVAR(truncate_doc, -"truncate([size: int]) -> None. Truncate the file to at most size bytes.\n" -"\n" -"Size defaults to the current file position, as returned by tell()." -"The current file position is changed to the value of size."); -#endif - -PyDoc_STRVAR(tell_doc, -"tell() -> int. Current file position"); - -PyDoc_STRVAR(readinto_doc, -"readinto() -> Same as RawIOBase.readinto()."); - -PyDoc_STRVAR(close_doc, -"close() -> None. Close the file.\n" -"\n" -"A closed file cannot be used for further I/O operations. close() may be\n" -"called more than once without error. Changes the fileno to -1."); - -PyDoc_STRVAR(isatty_doc, -"isatty() -> bool. True if the file is connected to a tty device."); - -PyDoc_STRVAR(seekable_doc, -"seekable() -> bool. True if file supports random-access."); - -PyDoc_STRVAR(readable_doc, -"readable() -> bool. True if file was opened in a read mode."); - -PyDoc_STRVAR(writable_doc, -"writable() -> bool. True if file was opened in a write mode."); - -static PyMethodDef fileio_methods[] = { - {"read", (PyCFunction)fileio_read, METH_VARARGS, read_doc}, - {"readall", (PyCFunction)fileio_readall, METH_NOARGS, readall_doc}, - {"readinto", (PyCFunction)fileio_readinto, METH_VARARGS, readinto_doc}, - {"write", (PyCFunction)fileio_write, METH_VARARGS, write_doc}, - {"seek", (PyCFunction)fileio_seek, METH_VARARGS, seek_doc}, - {"tell", (PyCFunction)fileio_tell, METH_VARARGS, tell_doc}, -#ifdef HAVE_FTRUNCATE - {"truncate", (PyCFunction)fileio_truncate, METH_VARARGS, truncate_doc}, -#endif - {"close", (PyCFunction)fileio_close, METH_NOARGS, close_doc}, - {"seekable", (PyCFunction)fileio_seekable, METH_NOARGS, seekable_doc}, - {"readable", (PyCFunction)fileio_readable, METH_NOARGS, readable_doc}, - {"writable", (PyCFunction)fileio_writable, METH_NOARGS, writable_doc}, - {"fileno", (PyCFunction)fileio_fileno, METH_NOARGS, fileno_doc}, - {"isatty", (PyCFunction)fileio_isatty, METH_NOARGS, isatty_doc}, - {NULL, NULL} /* sentinel */ -}; - -/* 'closed' and 'mode' are attributes for backwards compatibility reasons. */ - -static PyObject * -get_closed(PyFileIOObject *self, void *closure) -{ - return PyBool_FromLong((long)(self->fd < 0)); -} - -static PyObject * -get_closefd(PyFileIOObject *self, void *closure) -{ - return PyBool_FromLong((long)(self->closefd)); -} - -static PyObject * -get_mode(PyFileIOObject *self, void *closure) -{ - return PyUnicode_FromString(mode_string(self)); -} - -static PyGetSetDef fileio_getsetlist[] = { - {"closed", (getter)get_closed, NULL, "True if the file is closed"}, - {"closefd", (getter)get_closefd, NULL, - "True if the file descriptor will be closed"}, - {"mode", (getter)get_mode, NULL, "String giving the file mode"}, - {0}, -}; - -PyTypeObject PyFileIO_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.FileIO", - sizeof(PyFileIOObject), - 0, - (destructor)fileio_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (reprfunc)fileio_repr, /* 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_BASETYPE - | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - fileio_doc, /* tp_doc */ - (traverseproc)fileio_traverse, /* tp_traverse */ - (inquiry)fileio_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(PyFileIOObject, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - fileio_methods, /* tp_methods */ - 0, /* tp_members */ - fileio_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(PyFileIOObject, dict), /* tp_dictoffset */ - fileio_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - fileio_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; Modified: python/branches/py3k-short-float-repr/Modules/_functoolsmodule.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_functoolsmodule.c (original) +++ python/branches/py3k-short-float-repr/Modules/_functoolsmodule.c Sun Apr 5 01:04:14 2009 @@ -196,6 +196,53 @@ {NULL} /* Sentinel */ }; +/* Pickle strategy: + __reduce__ by itself doesn't support getting kwargs in the unpickle + operation so we define a __setstate__ that replaces all the information + about the partial. If we only replaced part of it someone would use + it as a hook to do stange things. + */ + +PyObject * +partial_reduce(partialobject *pto, PyObject *unused) +{ + return Py_BuildValue("O(O)(OOOO)", Py_TYPE(pto), pto->fn, pto->fn, + pto->args, pto->kw, + pto->dict ? pto->dict : Py_None); +} + +PyObject * +partial_setstate(partialobject *pto, PyObject *args) +{ + PyObject *fn, *fnargs, *kw, *dict; + if (!PyArg_ParseTuple(args, "(OOOO):__setstate__", + &fn, &fnargs, &kw, &dict)) + return NULL; + Py_XDECREF(pto->fn); + Py_XDECREF(pto->args); + Py_XDECREF(pto->kw); + Py_XDECREF(pto->dict); + pto->fn = fn; + pto->args = fnargs; + pto->kw = kw; + if (dict != Py_None) { + pto->dict = dict; + Py_INCREF(dict); + } else { + pto->dict = NULL; + } + Py_INCREF(fn); + Py_INCREF(fnargs); + Py_INCREF(kw); + Py_RETURN_NONE; +} + +static PyMethodDef partial_methods[] = { + {"__reduce__", (PyCFunction)partial_reduce, METH_NOARGS}, + {"__setstate__", (PyCFunction)partial_setstate, METH_VARARGS}, + {NULL, NULL} /* sentinel */ +}; + static PyTypeObject partial_type = { PyVarObject_HEAD_INIT(NULL, 0) "functools.partial", /* tp_name */ @@ -226,7 +273,7 @@ offsetof(partialobject, weakreflist), /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - 0, /* tp_methods */ + partial_methods, /* tp_methods */ partial_memberlist, /* tp_members */ partial_getsetlist, /* tp_getset */ 0, /* tp_base */ Deleted: python/branches/py3k-short-float-repr/Modules/_iobase.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_iobase.c Sun Apr 5 01:04:14 2009 +++ (empty file) @@ -1,894 +0,0 @@ -/* - An implementation of the I/O abstract base classes hierarchy - as defined by PEP 3116 - "New I/O" - - Classes defined here: IOBase, RawIOBase. - - Written by Amaury Forgeot d'Arc and Antoine Pitrou -*/ - - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#include "structmember.h" -#include "_iomodule.h" - -/* - * IOBase class, an abstract class - */ - -typedef struct { - PyObject_HEAD - - PyObject *dict; - PyObject *weakreflist; -} IOBaseObject; - -PyDoc_STRVAR(IOBase_doc, - "The abstract base class for all I/O classes, acting on streams of\n" - "bytes. There is no public constructor.\n" - "\n" - "This class provides dummy implementations for many methods that\n" - "derived classes can override selectively; the default implementations\n" - "represent a file that cannot be read, written or seeked.\n" - "\n" - "Even though IOBase does not declare read, readinto, or write because\n" - "their signatures will vary, implementations and clients should\n" - "consider those methods part of the interface. Also, implementations\n" - "may raise a IOError when operations they do not support are called.\n" - "\n" - "The basic type used for binary data read from or written to a file is\n" - "bytes. bytearrays are accepted too, and in some cases (such as\n" - "readinto) needed. Text I/O classes work with str data.\n" - "\n" - "Note that calling any method (even inquiries) on a closed stream is\n" - "undefined. Implementations may raise IOError in this case.\n" - "\n" - "IOBase (and its subclasses) support the iterator protocol, meaning\n" - "that an IOBase object can be iterated over yielding the lines in a\n" - "stream.\n" - "\n" - "IOBase also supports the :keyword:`with` statement. In this example,\n" - "fp is closed after the suite of the with statment is complete:\n" - "\n" - "with open('spam.txt', 'r') as fp:\n" - " fp.write('Spam and eggs!')\n"); - -/* Use this macro whenever you want to check the internal `closed` status - of the IOBase object rather than the virtual `closed` attribute as returned - by whatever subclass. */ - -#define IS_CLOSED(self) \ - PyObject_HasAttrString(self, "__IOBase_closed") - -/* Internal methods */ -static PyObject * -IOBase_unsupported(const char *message) -{ - PyErr_SetString(IO_STATE->unsupported_operation, message); - return NULL; -} - -/* Positionning */ - -PyDoc_STRVAR(IOBase_seek_doc, - "Change stream position.\n" - "\n" - "Change the stream position to byte offset offset. offset is\n" - "interpreted relative to the position indicated by whence. Values\n" - "for whence are:\n" - "\n" - "* 0 -- start of stream (the default); offset should be zero or positive\n" - "* 1 -- current stream position; offset may be negative\n" - "* 2 -- end of stream; offset is usually negative\n" - "\n" - "Return the new absolute position."); - -static PyObject * -IOBase_seek(PyObject *self, PyObject *args) -{ - return IOBase_unsupported("seek"); -} - -PyDoc_STRVAR(IOBase_tell_doc, - "Return current stream position."); - -static PyObject * -IOBase_tell(PyObject *self, PyObject *args) -{ - return PyObject_CallMethod(self, "seek", "ii", 0, 1); -} - -PyDoc_STRVAR(IOBase_truncate_doc, - "Truncate file to size bytes.\n" - "\n" - "Size defaults to the current IO position as reported by tell(). Return\n" - "the new size."); - -static PyObject * -IOBase_truncate(PyObject *self, PyObject *args) -{ - return IOBase_unsupported("truncate"); -} - -/* Flush and close methods */ - -PyDoc_STRVAR(IOBase_flush_doc, - "Flush write buffers, if applicable.\n" - "\n" - "This is not implemented for read-only and non-blocking streams.\n"); - -static PyObject * -IOBase_flush(PyObject *self, PyObject *args) -{ - /* XXX Should this return the number of bytes written??? */ - if (IS_CLOSED(self)) { - PyErr_SetString(PyExc_ValueError, "I/O operation on closed file."); - return NULL; - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(IOBase_close_doc, - "Flush and close the IO object.\n" - "\n" - "This method has no effect if the file is already closed.\n"); - -static int -IOBase_closed(PyObject *self) -{ - PyObject *res; - int closed; - /* This gets the derived attribute, which is *not* __IOBase_closed - in most cases! */ - res = PyObject_GetAttr(self, _PyIO_str_closed); - if (res == NULL) - return 0; - closed = PyObject_IsTrue(res); - Py_DECREF(res); - return closed; -} - -static PyObject * -IOBase_closed_get(PyObject *self, void *context) -{ - return PyBool_FromLong(IS_CLOSED(self)); -} - -PyObject * -_PyIOBase_checkClosed(PyObject *self, PyObject *args) -{ - if (IOBase_closed(self)) { - PyErr_SetString(PyExc_ValueError, "I/O operation on closed file."); - return NULL; - } - if (args == Py_True) - return Py_None; - else - Py_RETURN_NONE; -} - -/* XXX: IOBase thinks it has to maintain its own internal state in - `__IOBase_closed` and call flush() by itself, but it is redundant with - whatever behaviour a non-trivial derived class will implement. */ - -static PyObject * -IOBase_close(PyObject *self, PyObject *args) -{ - PyObject *res; - - if (IS_CLOSED(self)) - Py_RETURN_NONE; - - res = PyObject_CallMethodObjArgs(self, _PyIO_str_flush, NULL); - PyObject_SetAttrString(self, "__IOBase_closed", Py_True); - if (res == NULL) { - /* If flush() fails, just give up */ - if (PyErr_ExceptionMatches(PyExc_IOError)) - PyErr_Clear(); - else - return NULL; - } - Py_XDECREF(res); - Py_RETURN_NONE; -} - -/* Finalization and garbage collection support */ - -int -_PyIOBase_finalize(PyObject *self) -{ - PyObject *res; - PyObject *tp, *v, *tb; - int closed = 1; - int is_zombie; - - /* If _PyIOBase_finalize() is called from a destructor, we need to - resurrect the object as calling close() can invoke arbitrary code. */ - is_zombie = (Py_REFCNT(self) == 0); - if (is_zombie) { - ++Py_REFCNT(self); - } - PyErr_Fetch(&tp, &v, &tb); - /* If `closed` doesn't exist or can't be evaluated as bool, then the - object is probably in an unusable state, so ignore. */ - res = PyObject_GetAttr(self, _PyIO_str_closed); - if (res == NULL) - PyErr_Clear(); - else { - closed = PyObject_IsTrue(res); - Py_DECREF(res); - if (closed == -1) - PyErr_Clear(); - } - if (closed == 0) { - res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_close, - NULL); - /* Silencing I/O errors is bad, but printing spurious tracebacks is - equally as bad, and potentially more frequent (because of - shutdown issues). */ - if (res == NULL) - PyErr_Clear(); - else - Py_DECREF(res); - } - PyErr_Restore(tp, v, tb); - if (is_zombie) { - if (--Py_REFCNT(self) != 0) { - /* The object lives again. The following code is taken from - slot_tp_del in typeobject.c. */ - Py_ssize_t refcnt = Py_REFCNT(self); - _Py_NewReference(self); - Py_REFCNT(self) = refcnt; - /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so - * we need to undo that. */ - _Py_DEC_REFTOTAL; - /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object - * chain, so no more to do there. - * If COUNT_ALLOCS, the original decref bumped tp_frees, and - * _Py_NewReference bumped tp_allocs: both of those need to be - * undone. - */ -#ifdef COUNT_ALLOCS - --Py_TYPE(self)->tp_frees; - --Py_TYPE(self)->tp_allocs; -#endif - return -1; - } - } - return 0; -} - -static int -IOBase_traverse(IOBaseObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->dict); - return 0; -} - -static int -IOBase_clear(IOBaseObject *self) -{ - if (_PyIOBase_finalize((PyObject *) self) < 0) - return -1; - Py_CLEAR(self->dict); - return 0; -} - -/* Destructor */ - -static void -IOBase_dealloc(IOBaseObject *self) -{ - /* NOTE: since IOBaseObject has its own dict, Python-defined attributes - are still available here for close() to use. - However, if the derived class declares a __slots__, those slots are - already gone. - */ - if (_PyIOBase_finalize((PyObject *) self) < 0) { - /* When called from a heap type's dealloc, the type will be - decref'ed on return (see e.g. subtype_dealloc in typeobject.c). */ - if (PyType_HasFeature(Py_TYPE(self), Py_TPFLAGS_HEAPTYPE)) - Py_INCREF(Py_TYPE(self)); - return; - } - _PyObject_GC_UNTRACK(self); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - Py_CLEAR(self->dict); - Py_TYPE(self)->tp_free((PyObject *) self); -} - -/* Inquiry methods */ - -PyDoc_STRVAR(IOBase_seekable_doc, - "Return whether object supports random access.\n" - "\n" - "If False, seek(), tell() and truncate() will raise IOError.\n" - "This method may need to do a test seek()."); - -static PyObject * -IOBase_seekable(PyObject *self, PyObject *args) -{ - Py_RETURN_FALSE; -} - -PyObject * -_PyIOBase_checkSeekable(PyObject *self, PyObject *args) -{ - PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_seekable, NULL); - if (res == NULL) - return NULL; - if (res != Py_True) { - Py_CLEAR(res); - PyErr_SetString(PyExc_IOError, "File or stream is not seekable."); - return NULL; - } - if (args == Py_True) { - Py_DECREF(res); - } - return res; -} - -PyDoc_STRVAR(IOBase_readable_doc, - "Return whether object was opened for reading.\n" - "\n" - "If False, read() will raise IOError."); - -static PyObject * -IOBase_readable(PyObject *self, PyObject *args) -{ - Py_RETURN_FALSE; -} - -/* May be called with any object */ -PyObject * -_PyIOBase_checkReadable(PyObject *self, PyObject *args) -{ - PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_readable, NULL); - if (res == NULL) - return NULL; - if (res != Py_True) { - Py_CLEAR(res); - PyErr_SetString(PyExc_IOError, "File or stream is not readable."); - return NULL; - } - if (args == Py_True) { - Py_DECREF(res); - } - return res; -} - -PyDoc_STRVAR(IOBase_writable_doc, - "Return whether object was opened for writing.\n" - "\n" - "If False, read() will raise IOError."); - -static PyObject * -IOBase_writable(PyObject *self, PyObject *args) -{ - Py_RETURN_FALSE; -} - -/* May be called with any object */ -PyObject * -_PyIOBase_checkWritable(PyObject *self, PyObject *args) -{ - PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_writable, NULL); - if (res == NULL) - return NULL; - if (res != Py_True) { - Py_CLEAR(res); - PyErr_SetString(PyExc_IOError, "File or stream is not writable."); - return NULL; - } - if (args == Py_True) { - Py_DECREF(res); - } - return res; -} - -/* Context manager */ - -static PyObject * -IOBase_enter(PyObject *self, PyObject *args) -{ - if (_PyIOBase_checkClosed(self, Py_True) == NULL) - return NULL; - - Py_INCREF(self); - return self; -} - -static PyObject * -IOBase_exit(PyObject *self, PyObject *args) -{ - return PyObject_CallMethodObjArgs(self, _PyIO_str_close, NULL); -} - -/* Lower-level APIs */ - -/* XXX Should these be present even if unimplemented? */ - -PyDoc_STRVAR(IOBase_fileno_doc, - "Returns underlying file descriptor if one exists.\n" - "\n" - "An IOError is raised if the IO object does not use a file descriptor.\n"); - -static PyObject * -IOBase_fileno(PyObject *self, PyObject *args) -{ - return IOBase_unsupported("fileno"); -} - -PyDoc_STRVAR(IOBase_isatty_doc, - "Return whether this is an 'interactive' stream.\n" - "\n" - "Return False if it can't be determined.\n"); - -static PyObject * -IOBase_isatty(PyObject *self, PyObject *args) -{ - if (_PyIOBase_checkClosed(self, Py_True) == NULL) - return NULL; - Py_RETURN_FALSE; -} - -/* Readline(s) and writelines */ - -PyDoc_STRVAR(IOBase_readline_doc, - "Read and return a line from the stream.\n" - "\n" - "If limit is specified, at most limit bytes will be read.\n" - "\n" - "The line terminator is always b'\n' for binary files; for text\n" - "files, the newlines argument to open can be used to select the line\n" - "terminator(s) recognized.\n"); - -static PyObject * -IOBase_readline(PyObject *self, PyObject *args) -{ - /* For backwards compatibility, a (slowish) readline(). */ - - Py_ssize_t limit = -1; - int has_peek = 0; - PyObject *buffer, *result; - Py_ssize_t old_size = -1; - - if (!PyArg_ParseTuple(args, "|n:readline", &limit)) { - return NULL; - } - - if (PyObject_HasAttrString(self, "peek")) - has_peek = 1; - - buffer = PyByteArray_FromStringAndSize(NULL, 0); - if (buffer == NULL) - return NULL; - - while (limit < 0 || Py_SIZE(buffer) < limit) { - Py_ssize_t nreadahead = 1; - PyObject *b; - - if (has_peek) { - PyObject *readahead = PyObject_CallMethod(self, "peek", "i", 1); - if (readahead == NULL) - goto fail; - if (!PyBytes_Check(readahead)) { - PyErr_Format(PyExc_IOError, - "peek() should have returned a bytes object, " - "not '%.200s'", Py_TYPE(readahead)->tp_name); - Py_DECREF(readahead); - goto fail; - } - if (PyBytes_GET_SIZE(readahead) > 0) { - Py_ssize_t n = 0; - const char *buf = PyBytes_AS_STRING(readahead); - if (limit >= 0) { - do { - if (n >= PyBytes_GET_SIZE(readahead) || n >= limit) - break; - if (buf[n++] == '\n') - break; - } while (1); - } - else { - do { - if (n >= PyBytes_GET_SIZE(readahead)) - break; - if (buf[n++] == '\n') - break; - } while (1); - } - nreadahead = n; - } - Py_DECREF(readahead); - } - - b = PyObject_CallMethod(self, "read", "n", nreadahead); - if (b == NULL) - goto fail; - if (!PyBytes_Check(b)) { - PyErr_Format(PyExc_IOError, - "read() should have returned a bytes object, " - "not '%.200s'", Py_TYPE(b)->tp_name); - Py_DECREF(b); - goto fail; - } - if (PyBytes_GET_SIZE(b) == 0) { - Py_DECREF(b); - break; - } - - old_size = PyByteArray_GET_SIZE(buffer); - PyByteArray_Resize(buffer, old_size + PyBytes_GET_SIZE(b)); - memcpy(PyByteArray_AS_STRING(buffer) + old_size, - PyBytes_AS_STRING(b), PyBytes_GET_SIZE(b)); - - Py_DECREF(b); - - if (PyByteArray_AS_STRING(buffer)[PyByteArray_GET_SIZE(buffer) - 1] == '\n') - break; - } - - result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(buffer), - PyByteArray_GET_SIZE(buffer)); - Py_DECREF(buffer); - return result; - fail: - Py_DECREF(buffer); - return NULL; -} - -static PyObject * -IOBase_iter(PyObject *self) -{ - if (_PyIOBase_checkClosed(self, Py_True) == NULL) - return NULL; - - Py_INCREF(self); - return self; -} - -static PyObject * -IOBase_iternext(PyObject *self) -{ - PyObject *line = PyObject_CallMethodObjArgs(self, _PyIO_str_readline, NULL); - - if (line == NULL) - return NULL; - - if (PyObject_Size(line) == 0) { - Py_DECREF(line); - return NULL; - } - - return line; -} - -PyDoc_STRVAR(IOBase_readlines_doc, - "Return a list of lines from the stream.\n" - "\n" - "hint can be specified to control the number of lines read: no more\n" - "lines will be read if the total size (in bytes/characters) of all\n" - "lines so far exceeds hint."); - -static PyObject * -IOBase_readlines(PyObject *self, PyObject *args) -{ - Py_ssize_t hint = -1, length = 0; - PyObject *hintobj = Py_None, *result; - - if (!PyArg_ParseTuple(args, "|O:readlines", &hintobj)) { - return NULL; - } - if (hintobj != Py_None) { - hint = PyNumber_AsSsize_t(hintobj, PyExc_ValueError); - if (hint == -1 && PyErr_Occurred()) - return NULL; - } - - result = PyList_New(0); - if (result == NULL) - return NULL; - - if (hint <= 0) { - /* XXX special-casing this made sense in the Python version in order - to remove the bytecode interpretation overhead, but it could - probably be removed here. */ - PyObject *ret = PyObject_CallMethod(result, "extend", "O", self); - if (ret == NULL) { - Py_DECREF(result); - return NULL; - } - Py_DECREF(ret); - return result; - } - - while (1) { - PyObject *line = PyIter_Next(self); - if (line == NULL) { - if (PyErr_Occurred()) { - Py_DECREF(result); - return NULL; - } - else - break; /* StopIteration raised */ - } - - if (PyList_Append(result, line) < 0) { - Py_DECREF(line); - Py_DECREF(result); - return NULL; - } - length += PyObject_Size(line); - Py_DECREF(line); - - if (length > hint) - break; - } - return result; -} - -static PyObject * -IOBase_writelines(PyObject *self, PyObject *args) -{ - PyObject *lines, *iter, *res; - - if (!PyArg_ParseTuple(args, "O:writelines", &lines)) { - return NULL; - } - - if (_PyIOBase_checkClosed(self, Py_True) == NULL) - return NULL; - - iter = PyObject_GetIter(lines); - if (iter == NULL) - return NULL; - - while (1) { - PyObject *line = PyIter_Next(iter); - if (line == NULL) { - if (PyErr_Occurred()) { - Py_DECREF(iter); - return NULL; - } - else - break; /* Stop Iteration */ - } - - res = PyObject_CallMethodObjArgs(self, _PyIO_str_write, line, NULL); - Py_DECREF(line); - if (res == NULL) { - Py_DECREF(iter); - return NULL; - } - Py_DECREF(res); - } - Py_DECREF(iter); - Py_RETURN_NONE; -} - -static PyMethodDef IOBase_methods[] = { - {"seek", IOBase_seek, METH_VARARGS, IOBase_seek_doc}, - {"tell", IOBase_tell, METH_NOARGS, IOBase_tell_doc}, - {"truncate", IOBase_truncate, METH_VARARGS, IOBase_truncate_doc}, - {"flush", IOBase_flush, METH_NOARGS, IOBase_flush_doc}, - {"close", IOBase_close, METH_NOARGS, IOBase_close_doc}, - - {"seekable", IOBase_seekable, METH_NOARGS, IOBase_seekable_doc}, - {"readable", IOBase_readable, METH_NOARGS, IOBase_readable_doc}, - {"writable", IOBase_writable, METH_NOARGS, IOBase_writable_doc}, - - {"_checkClosed", _PyIOBase_checkClosed, METH_NOARGS}, - {"_checkSeekable", _PyIOBase_checkSeekable, METH_NOARGS}, - {"_checkReadable", _PyIOBase_checkReadable, METH_NOARGS}, - {"_checkWritable", _PyIOBase_checkWritable, METH_NOARGS}, - - {"fileno", IOBase_fileno, METH_NOARGS, IOBase_fileno_doc}, - {"isatty", IOBase_isatty, METH_NOARGS, IOBase_isatty_doc}, - - {"__enter__", IOBase_enter, METH_NOARGS}, - {"__exit__", IOBase_exit, METH_VARARGS}, - - {"readline", IOBase_readline, METH_VARARGS, IOBase_readline_doc}, - {"readlines", IOBase_readlines, METH_VARARGS, IOBase_readlines_doc}, - {"writelines", IOBase_writelines, METH_VARARGS}, - - {NULL, NULL} -}; - -static PyGetSetDef IOBase_getset[] = { - {"closed", (getter)IOBase_closed_get, NULL, NULL}, - {0} -}; - - -PyTypeObject PyIOBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._IOBase", /*tp_name*/ - sizeof(IOBaseObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)IOBase_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - IOBase_doc, /* tp_doc */ - (traverseproc)IOBase_traverse, /* tp_traverse */ - (inquiry)IOBase_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(IOBaseObject, weakreflist), /* tp_weaklistoffset */ - IOBase_iter, /* tp_iter */ - IOBase_iternext, /* tp_iternext */ - IOBase_methods, /* tp_methods */ - 0, /* tp_members */ - IOBase_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(IOBaseObject, dict), /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; - - -/* - * RawIOBase class, Inherits from IOBase. - */ -PyDoc_STRVAR(RawIOBase_doc, - "Base class for raw binary I/O."); - -/* - * The read() method is implemented by calling readinto(); derived classes - * that want to support read() only need to implement readinto() as a - * primitive operation. In general, readinto() can be more efficient than - * read(). - * - * (It would be tempting to also provide an implementation of readinto() in - * terms of read(), in case the latter is a more suitable primitive operation, - * but that would lead to nasty recursion in case a subclass doesn't implement - * either.) -*/ - -static PyObject * -RawIOBase_read(PyObject *self, PyObject *args) -{ - Py_ssize_t n = -1; - PyObject *b, *res; - - if (!PyArg_ParseTuple(args, "|n:read", &n)) { - return NULL; - } - - if (n < 0) - return PyObject_CallMethod(self, "readall", NULL); - - /* TODO: allocate a bytes object directly instead and manually construct - a writable memoryview pointing to it. */ - b = PyByteArray_FromStringAndSize(NULL, n); - if (b == NULL) - return NULL; - - res = PyObject_CallMethodObjArgs(self, _PyIO_str_readinto, b, NULL); - if (res == NULL) { - Py_DECREF(b); - return NULL; - } - - n = PyNumber_AsSsize_t(res, PyExc_ValueError); - Py_DECREF(res); - if (n == -1 && PyErr_Occurred()) { - Py_DECREF(b); - return NULL; - } - - res = PyBytes_FromStringAndSize(PyByteArray_AsString(b), n); - Py_DECREF(b); - return res; -} - - -PyDoc_STRVAR(RawIOBase_readall_doc, - "Read until EOF, using multiple read() call."); - -static PyObject * -RawIOBase_readall(PyObject *self, PyObject *args) -{ - int r; - PyObject *chunks = PyList_New(0); - PyObject *result; - - if (chunks == NULL) - return NULL; - - while (1) { - PyObject *data = PyObject_CallMethod(self, "read", - "i", DEFAULT_BUFFER_SIZE); - if (!data) { - Py_DECREF(chunks); - return NULL; - } - if (!PyBytes_Check(data)) { - Py_DECREF(chunks); - Py_DECREF(data); - PyErr_SetString(PyExc_TypeError, "read() should return bytes"); - return NULL; - } - if (PyBytes_GET_SIZE(data) == 0) { - /* EOF */ - Py_DECREF(data); - break; - } - r = PyList_Append(chunks, data); - Py_DECREF(data); - if (r < 0) { - Py_DECREF(chunks); - return NULL; - } - } - result = _PyBytes_Join(_PyIO_empty_bytes, chunks); - Py_DECREF(chunks); - return result; -} - -static PyMethodDef RawIOBase_methods[] = { - {"read", RawIOBase_read, METH_VARARGS}, - {"readall", RawIOBase_readall, METH_NOARGS, RawIOBase_readall_doc}, - {NULL, NULL} -}; - -PyTypeObject PyRawIOBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._RawIOBase", /*tp_name*/ - 0, /*tp_basicsize*/ - 0, /*tp_itemsize*/ - 0, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - RawIOBase_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - RawIOBase_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PyIOBase_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ -}; Deleted: python/branches/py3k-short-float-repr/Modules/_iomodule.h ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_iomodule.h Sun Apr 5 01:04:14 2009 +++ (empty file) @@ -1,150 +0,0 @@ -/* - * Declarations shared between the different parts of the io module - */ - -/* ABCs */ -extern PyTypeObject PyIOBase_Type; -extern PyTypeObject PyRawIOBase_Type; -extern PyTypeObject PyBufferedIOBase_Type; -extern PyTypeObject PyTextIOBase_Type; - -/* Concrete classes */ -extern PyTypeObject PyFileIO_Type; -extern PyTypeObject PyBytesIO_Type; -extern PyTypeObject PyStringIO_Type; -extern PyTypeObject PyBufferedReader_Type; -extern PyTypeObject PyBufferedWriter_Type; -extern PyTypeObject PyBufferedRWPair_Type; -extern PyTypeObject PyBufferedRandom_Type; -extern PyTypeObject PyTextIOWrapper_Type; -extern PyTypeObject PyIncrementalNewlineDecoder_Type; - -/* These functions are used as METH_NOARGS methods, are normally called - * with args=NULL, and return a new reference. - * BUT when args=Py_True is passed, they return a borrowed reference. - */ -extern PyObject* _PyIOBase_checkReadable(PyObject *self, PyObject *args); -extern PyObject* _PyIOBase_checkWritable(PyObject *self, PyObject *args); -extern PyObject* _PyIOBase_checkSeekable(PyObject *self, PyObject *args); -extern PyObject* _PyIOBase_checkClosed(PyObject *self, PyObject *args); - -/* Helper for finalization. - This function will revive an object ready to be deallocated and try to - close() it. It returns 0 if the object can be destroyed, or -1 if it - is alive again. */ -extern int _PyIOBase_finalize(PyObject *self); - -/* Returns true if the given FileIO object is closed. - Doesn't check the argument type, so be careful! */ -extern int _PyFileIO_closed(PyObject *self); - -/* Shortcut to the core of the IncrementalNewlineDecoder.decode method */ -extern PyObject *_PyIncrementalNewlineDecoder_decode( - PyObject *self, PyObject *input, int final); - -/* Finds the first line ending between `start` and `end`. - If found, returns the index after the line ending and doesn't touch - `*consumed`. - If not found, returns -1 and sets `*consumed` to the number of characters - which can be safely put aside until another search. - - NOTE: for performance reasons, `end` must point to a NUL character ('\0'). - Otherwise, the function will scan further and return garbage. */ -extern Py_ssize_t _PyIO_find_line_ending( - int translated, int universal, PyObject *readnl, - Py_UNICODE *start, Py_UNICODE *end, Py_ssize_t *consumed); - - -#define DEFAULT_BUFFER_SIZE (8 * 1024) /* bytes */ - -typedef struct { - PyException_HEAD - PyObject *myerrno; - PyObject *strerror; - PyObject *filename; /* Not used, but part of the IOError object */ - Py_ssize_t written; -} PyBlockingIOErrorObject; -PyAPI_DATA(PyObject *) PyExc_BlockingIOError; - -/* - * Offset type for positioning. - */ - -#if defined(MS_WIN64) || defined(MS_WINDOWS) - -/* Windows uses long long for offsets */ -typedef PY_LONG_LONG Py_off_t; -# define PyLong_AsOff_t PyLong_AsLongLong -# define PyLong_FromOff_t PyLong_FromLongLong -# define PY_OFF_T_MAX PY_LLONG_MAX -# define PY_OFF_T_MIN PY_LLONG_MIN - -#else - -/* Other platforms use off_t */ -typedef off_t Py_off_t; -#if (SIZEOF_OFF_T == SIZEOF_SIZE_T) -# define PyLong_AsOff_t PyLong_AsSsize_t -# define PyLong_FromOff_t PyLong_FromSsize_t -# define PY_OFF_T_MAX PY_SSIZE_T_MAX -# define PY_OFF_T_MIN PY_SSIZE_T_MIN -#elif (SIZEOF_OFF_T == SIZEOF_LONG_LONG) -# define PyLong_AsOff_t PyLong_AsLongLong -# define PyLong_FromOff_t PyLong_FromLongLong -# define PY_OFF_T_MAX PY_LLONG_MAX -# define PY_OFF_T_MIN PY_LLONG_MIN -#elif (SIZEOF_OFF_T == SIZEOF_LONG) -# define PyLong_AsOff_t PyLong_AsLong -# define PyLong_FromOff_t PyLong_FromLong -# define PY_OFF_T_MAX LONG_MAX -# define PY_OFF_T_MIN LONG_MIN -#else -# error off_t does not match either size_t, long, or long long! -#endif - -#endif - -extern Py_off_t PyNumber_AsOff_t(PyObject *item, PyObject *err); - -/* Implementation details */ - -/* IO module structure */ - -extern PyModuleDef _PyIO_Module; - -typedef struct { - int initialized; - PyObject *os_module; - PyObject *locale_module; - - PyObject *unsupported_operation; -} _PyIO_State; - -#define IO_MOD_STATE(mod) ((_PyIO_State *)PyModule_GetState(mod)) -#define IO_STATE IO_MOD_STATE(PyState_FindModule(&_PyIO_Module)) - -extern PyObject *_PyIO_str_close; -extern PyObject *_PyIO_str_closed; -extern PyObject *_PyIO_str_decode; -extern PyObject *_PyIO_str_encode; -extern PyObject *_PyIO_str_fileno; -extern PyObject *_PyIO_str_flush; -extern PyObject *_PyIO_str_getstate; -extern PyObject *_PyIO_str_isatty; -extern PyObject *_PyIO_str_newlines; -extern PyObject *_PyIO_str_nl; -extern PyObject *_PyIO_str_read; -extern PyObject *_PyIO_str_read1; -extern PyObject *_PyIO_str_readable; -extern PyObject *_PyIO_str_readinto; -extern PyObject *_PyIO_str_readline; -extern PyObject *_PyIO_str_reset; -extern PyObject *_PyIO_str_seek; -extern PyObject *_PyIO_str_seekable; -extern PyObject *_PyIO_str_tell; -extern PyObject *_PyIO_str_truncate; -extern PyObject *_PyIO_str_writable; -extern PyObject *_PyIO_str_write; - -extern PyObject *_PyIO_empty_str; -extern PyObject *_PyIO_empty_bytes; Modified: python/branches/py3k-short-float-repr/Modules/_multiprocessing/multiprocessing.h ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_multiprocessing/multiprocessing.h (original) +++ python/branches/py3k-short-float-repr/Modules/_multiprocessing/multiprocessing.h Sun Apr 5 01:04:14 2009 @@ -16,6 +16,9 @@ # include # include # include /* getpid() */ +# ifdef Py_DEBUG +# include +# endif # define SEM_HANDLE HANDLE # define SEM_VALUE_MAX LONG_MAX #else Modified: python/branches/py3k-short-float-repr/Modules/_multiprocessing/semaphore.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_multiprocessing/semaphore.c (original) +++ python/branches/py3k-short-float-repr/Modules/_multiprocessing/semaphore.c Sun Apr 5 01:04:14 2009 @@ -546,7 +546,7 @@ "acquire the semaphore/lock"}, {"release", (PyCFunction)semlock_release, METH_NOARGS, "release the semaphore/lock"}, - {"__enter__", (PyCFunction)semlock_acquire, METH_VARARGS, + {"__enter__", (PyCFunction)semlock_acquire, METH_VARARGS | METH_KEYWORDS, "enter the semaphore/lock"}, {"__exit__", (PyCFunction)semlock_release, METH_VARARGS, "exit the semaphore/lock"}, Modified: python/branches/py3k-short-float-repr/Modules/_multiprocessing/win32_functions.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_multiprocessing/win32_functions.c (original) +++ python/branches/py3k-short-float-repr/Modules/_multiprocessing/win32_functions.c Sun Apr 5 01:04:14 2009 @@ -130,6 +130,12 @@ if (!PyArg_ParseTuple(args, "I", &uExitCode)) return NULL; + #if defined(Py_DEBUG) + SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOALIGNMENTFAULTEXCEPT|SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX); + _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); + #endif + + ExitProcess(uExitCode); return NULL; Modified: python/branches/py3k-short-float-repr/Modules/_pickle.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_pickle.c (original) +++ python/branches/py3k-short-float-repr/Modules/_pickle.c Sun Apr 5 01:04:14 2009 @@ -691,9 +691,9 @@ module_name = PyObject_GetAttr(global, module_str); - /* In some rare cases (e.g., random.getrandbits), __module__ can be - None. If it is so, then search sys.modules for the module of - global. */ + /* In some rare cases (e.g., bound methods of extension types), + __module__ can be None. If it is so, then search sys.modules + for the module of global. */ if (module_name == Py_None) { Py_DECREF(module_name); goto search; @@ -4462,6 +4462,9 @@ if (self->memo == NULL) return -1; + self->last_string = NULL; + self->arg = NULL; + return 0; } Deleted: python/branches/py3k-short-float-repr/Modules/_stringio.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_stringio.c Sun Apr 5 01:04:14 2009 +++ (empty file) @@ -1,769 +0,0 @@ -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#include "structmember.h" -#include "_iomodule.h" - -/* Implementation note: the buffer is always at least one character longer - than the enclosed string, for proper functioning of _PyIO_find_line_ending. -*/ - -typedef struct { - PyObject_HEAD - Py_UNICODE *buf; - Py_ssize_t pos; - Py_ssize_t string_size; - size_t buf_size; - - char ok; /* initialized? */ - char closed; - char readuniversal; - char readtranslate; - PyObject *decoder; - PyObject *readnl; - PyObject *writenl; - - PyObject *dict; - PyObject *weakreflist; -} StringIOObject; - -#define CHECK_INITIALIZED(self) \ - if (self->ok <= 0) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - return NULL; \ - } - -#define CHECK_CLOSED(self) \ - if (self->closed) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on closed file"); \ - return NULL; \ - } - -PyDoc_STRVAR(stringio_doc, - "Text I/O implementation using an in-memory buffer.\n" - "\n" - "The initial_value argument sets the value of object. The newline\n" - "argument is like the one of TextIOWrapper's constructor."); - - -/* Internal routine for changing the size, in terms of characters, of the - buffer of StringIO objects. The caller should ensure that the 'size' - argument is non-negative. Returns 0 on success, -1 otherwise. */ -static int -resize_buffer(StringIOObject *self, size_t size) -{ - /* Here, unsigned types are used to avoid dealing with signed integer - overflow, which is undefined in C. */ - size_t alloc = self->buf_size; - Py_UNICODE *new_buf = NULL; - - assert(self->buf != NULL); - - /* Reserve one more char for line ending detection. */ - size = size + 1; - /* For simplicity, stay in the range of the signed type. Anyway, Python - doesn't allow strings to be longer than this. */ - if (size > PY_SSIZE_T_MAX) - goto overflow; - - if (size < alloc / 2) { - /* Major downsize; resize down to exact size. */ - alloc = size + 1; - } - else if (size < alloc) { - /* Within allocated size; quick exit */ - return 0; - } - else if (size <= alloc * 1.125) { - /* Moderate upsize; overallocate similar to list_resize() */ - alloc = size + (size >> 3) + (size < 9 ? 3 : 6); - } - else { - /* Major upsize; resize up to exact size */ - alloc = size + 1; - } - - if (alloc > ((size_t)-1) / sizeof(Py_UNICODE)) - goto overflow; - new_buf = (Py_UNICODE *)PyMem_Realloc(self->buf, - alloc * sizeof(Py_UNICODE)); - if (new_buf == NULL) { - PyErr_NoMemory(); - return -1; - } - self->buf_size = alloc; - self->buf = new_buf; - - return 0; - - overflow: - PyErr_SetString(PyExc_OverflowError, - "new buffer size too large"); - return -1; -} - -/* Internal routine for writing a whole PyUnicode object to the buffer of a - StringIO object. Returns 0 on success, or -1 on error. */ -static Py_ssize_t -write_str(StringIOObject *self, PyObject *obj) -{ - Py_UNICODE *str; - Py_ssize_t len; - PyObject *decoded = NULL; - assert(self->buf != NULL); - assert(self->pos >= 0); - - if (self->decoder != NULL) { - decoded = _PyIncrementalNewlineDecoder_decode( - self->decoder, obj, 1 /* always final */); - } - else { - decoded = obj; - Py_INCREF(decoded); - } - if (self->writenl) { - PyObject *translated = PyUnicode_Replace( - decoded, _PyIO_str_nl, self->writenl, -1); - Py_DECREF(decoded); - decoded = translated; - } - if (decoded == NULL) - return -1; - - assert(PyUnicode_Check(decoded)); - str = PyUnicode_AS_UNICODE(decoded); - len = PyUnicode_GET_SIZE(decoded); - - assert(len >= 0); - - /* This overflow check is not strictly necessary. However, it avoids us to - deal with funky things like comparing an unsigned and a signed - integer. */ - if (self->pos > PY_SSIZE_T_MAX - len) { - PyErr_SetString(PyExc_OverflowError, - "new position too large"); - goto fail; - } - if (self->pos + len > self->string_size) { - if (resize_buffer(self, self->pos + len) < 0) - goto fail; - } - - if (self->pos > self->string_size) { - /* In case of overseek, pad with null bytes the buffer region between - the end of stream and the current position. - - 0 lo string_size hi - | |<---used--->|<----------available----------->| - | | <--to pad-->|<---to write---> | - 0 buf positon - - */ - memset(self->buf + self->string_size, '\0', - (self->pos - self->string_size) * sizeof(Py_UNICODE)); - } - - /* Copy the data to the internal buffer, overwriting some of the - existing data if self->pos < self->string_size. */ - memcpy(self->buf + self->pos, str, len * sizeof(Py_UNICODE)); - self->pos += len; - - /* Set the new length of the internal string if it has changed. */ - if (self->string_size < self->pos) { - self->string_size = self->pos; - } - - Py_DECREF(decoded); - return 0; - -fail: - Py_XDECREF(decoded); - return -1; -} - -PyDoc_STRVAR(stringio_getvalue_doc, - "Retrieve the entire contents of the object."); - -static PyObject * -stringio_getvalue(StringIOObject *self) -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - return PyUnicode_FromUnicode(self->buf, self->string_size); -} - -PyDoc_STRVAR(stringio_tell_doc, - "Tell the current file position."); - -static PyObject * -stringio_tell(StringIOObject *self) -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - return PyLong_FromSsize_t(self->pos); -} - -PyDoc_STRVAR(stringio_read_doc, - "Read at most n characters, returned as a string.\n" - "\n" - "If the argument is negative or omitted, read until EOF\n" - "is reached. Return an empty string at EOF.\n"); - -static PyObject * -stringio_read(StringIOObject *self, PyObject *args) -{ - Py_ssize_t size, n; - Py_UNICODE *output; - PyObject *arg = Py_None; - - CHECK_INITIALIZED(self); - if (!PyArg_ParseTuple(args, "|O:read", &arg)) - return NULL; - CHECK_CLOSED(self); - - if (PyNumber_Check(arg)) { - size = PyNumber_AsSsize_t(arg, PyExc_OverflowError); - if (size == -1 && PyErr_Occurred()) - return NULL; - } - else if (arg == Py_None) { - /* Read until EOF is reached, by default. */ - size = -1; - } - else { - PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", - Py_TYPE(arg)->tp_name); - return NULL; - } - - /* adjust invalid sizes */ - n = self->string_size - self->pos; - if (size < 0 || size > n) { - size = n; - if (size < 0) - size = 0; - } - - output = self->buf + self->pos; - self->pos += size; - return PyUnicode_FromUnicode(output, size); -} - -/* Internal helper, used by stringio_readline and stringio_iternext */ -static PyObject * -_stringio_readline(StringIOObject *self, Py_ssize_t limit) -{ - Py_UNICODE *start, *end, old_char; - Py_ssize_t len, consumed; - - /* In case of overseek, return the empty string */ - if (self->pos >= self->string_size) - return PyUnicode_FromString(""); - - start = self->buf + self->pos; - if (limit < 0 || limit > self->string_size - self->pos) - limit = self->string_size - self->pos; - - end = start + limit; - old_char = *end; - *end = '\0'; - len = _PyIO_find_line_ending( - self->readtranslate, self->readuniversal, self->readnl, - start, end, &consumed); - *end = old_char; - /* If we haven't found any line ending, we just return everything - (`consumed` is ignored). */ - if (len < 0) - len = limit; - self->pos += len; - return PyUnicode_FromUnicode(start, len); -} - -PyDoc_STRVAR(stringio_readline_doc, - "Read until newline or EOF.\n" - "\n" - "Returns an empty string if EOF is hit immediately.\n"); - -static PyObject * -stringio_readline(StringIOObject *self, PyObject *args) -{ - PyObject *arg = Py_None; - Py_ssize_t limit = -1; - - CHECK_INITIALIZED(self); - if (!PyArg_ParseTuple(args, "|O:readline", &arg)) - return NULL; - CHECK_CLOSED(self); - - if (PyNumber_Check(arg)) { - limit = PyNumber_AsSsize_t(arg, PyExc_OverflowError); - if (limit == -1 && PyErr_Occurred()) - return NULL; - } - else if (arg != Py_None) { - PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", - Py_TYPE(arg)->tp_name); - return NULL; - } - return _stringio_readline(self, limit); -} - -static PyObject * -stringio_iternext(StringIOObject *self) -{ - PyObject *line; - - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - - if (Py_TYPE(self) == &PyStringIO_Type) { - /* Skip method call overhead for speed */ - line = _stringio_readline(self, -1); - } - else { - /* XXX is subclassing StringIO really supported? */ - line = PyObject_CallMethodObjArgs((PyObject *)self, - _PyIO_str_readline, NULL); - if (line && !PyUnicode_Check(line)) { - PyErr_Format(PyExc_IOError, - "readline() should have returned an str object, " - "not '%.200s'", Py_TYPE(line)->tp_name); - Py_DECREF(line); - return NULL; - } - } - - if (line == NULL) - return NULL; - - if (PyUnicode_GET_SIZE(line) == 0) { - /* Reached EOF */ - Py_DECREF(line); - return NULL; - } - - return line; -} - -PyDoc_STRVAR(stringio_truncate_doc, - "Truncate size to pos.\n" - "\n" - "The pos argument defaults to the current file position, as\n" - "returned by tell(). Imply an absolute seek to pos.\n" - "Returns the new absolute position.\n"); - -static PyObject * -stringio_truncate(StringIOObject *self, PyObject *args) -{ - Py_ssize_t size; - PyObject *arg = Py_None; - - CHECK_INITIALIZED(self); - if (!PyArg_ParseTuple(args, "|O:truncate", &arg)) - return NULL; - CHECK_CLOSED(self); - - if (PyNumber_Check(arg)) { - size = PyNumber_AsSsize_t(arg, PyExc_OverflowError); - if (size == -1 && PyErr_Occurred()) - return NULL; - } - else if (arg == Py_None) { - /* Truncate to current position if no argument is passed. */ - size = self->pos; - } - else { - PyErr_Format(PyExc_TypeError, "integer argument expected, got '%s'", - Py_TYPE(arg)->tp_name); - return NULL; - } - - if (size < 0) { - PyErr_Format(PyExc_ValueError, - "Negative size value %zd", size); - return NULL; - } - - if (size < self->string_size) { - if (resize_buffer(self, size) < 0) - return NULL; - self->string_size = size; - } - self->pos = size; - - return PyLong_FromSsize_t(size); -} - -PyDoc_STRVAR(stringio_seek_doc, - "Change stream position.\n" - "\n" - "Seek to character offset pos relative to position indicated by whence:\n" - " 0 Start of stream (the default). pos should be >= 0;\n" - " 1 Current position - pos must be 0;\n" - " 2 End of stream - pos must be 0.\n" - "Returns the new absolute position.\n"); - -static PyObject * -stringio_seek(StringIOObject *self, PyObject *args) -{ - Py_ssize_t pos; - int mode = 0; - - CHECK_INITIALIZED(self); - if (!PyArg_ParseTuple(args, "n|i:seek", &pos, &mode)) - return NULL; - CHECK_CLOSED(self); - - if (mode != 0 && mode != 1 && mode != 2) { - PyErr_Format(PyExc_ValueError, - "Invalid whence (%i, should be 0, 1 or 2)", mode); - return NULL; - } - else if (pos < 0 && mode == 0) { - PyErr_Format(PyExc_ValueError, - "Negative seek position %zd", pos); - return NULL; - } - else if (mode != 0 && pos != 0) { - PyErr_SetString(PyExc_IOError, - "Can't do nonzero cur-relative seeks"); - return NULL; - } - - /* mode 0: offset relative to beginning of the string. - mode 1: no change to current position. - mode 2: change position to end of file. */ - if (mode == 1) { - pos = self->pos; - } - else if (mode == 2) { - pos = self->string_size; - } - - self->pos = pos; - - return PyLong_FromSsize_t(self->pos); -} - -PyDoc_STRVAR(stringio_write_doc, - "Write string to file.\n" - "\n" - "Returns the number of characters written, which is always equal to\n" - "the length of the string.\n"); - -static PyObject * -stringio_write(StringIOObject *self, PyObject *obj) -{ - Py_ssize_t size; - - CHECK_INITIALIZED(self); - if (!PyUnicode_Check(obj)) { - PyErr_Format(PyExc_TypeError, "string argument expected, got '%s'", - Py_TYPE(obj)->tp_name); - return NULL; - } - CHECK_CLOSED(self); - size = PyUnicode_GET_SIZE(obj); - - if (size > 0 && write_str(self, obj) < 0) - return NULL; - - return PyLong_FromSsize_t(size); -} - -PyDoc_STRVAR(stringio_close_doc, - "Close the IO object. Attempting any further operation after the\n" - "object is closed will raise a ValueError.\n" - "\n" - "This method has no effect if the file is already closed.\n"); - -static PyObject * -stringio_close(StringIOObject *self) -{ - self->closed = 1; - /* Free up some memory */ - if (resize_buffer(self, 0) < 0) - return NULL; - Py_CLEAR(self->readnl); - Py_CLEAR(self->writenl); - Py_CLEAR(self->decoder); - Py_RETURN_NONE; -} - -static int -stringio_traverse(StringIOObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->dict); - return 0; -} - -static int -stringio_clear(StringIOObject *self) -{ - Py_CLEAR(self->dict); - return 0; -} - -static void -stringio_dealloc(StringIOObject *self) -{ - _PyObject_GC_UNTRACK(self); - Py_CLEAR(self->readnl); - Py_CLEAR(self->writenl); - Py_CLEAR(self->decoder); - if (self->buf) - PyMem_Free(self->buf); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - Py_TYPE(self)->tp_free(self); -} - -static PyObject * -stringio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - StringIOObject *self; - - assert(type != NULL && type->tp_alloc != NULL); - self = (StringIOObject *)type->tp_alloc(type, 0); - if (self == NULL) - return NULL; - - self->string_size = 0; - self->pos = 0; - self->buf_size = 0; - self->buf = (Py_UNICODE *)PyMem_Malloc(0); - if (self->buf == NULL) { - Py_DECREF(self); - return PyErr_NoMemory(); - } - - return (PyObject *)self; -} - -static int -stringio_init(StringIOObject *self, PyObject *args, PyObject *kwds) -{ - char *kwlist[] = {"initial_value", "newline", NULL}; - PyObject *value = NULL; - char *newline = "\n"; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oz:__init__", kwlist, - &value, &newline)) - return -1; - - if (newline && newline[0] != '\0' - && !(newline[0] == '\n' && newline[1] == '\0') - && !(newline[0] == '\r' && newline[1] == '\0') - && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) { - PyErr_Format(PyExc_ValueError, - "illegal newline value: %s", newline); - return -1; - } - if (value && value != Py_None && !PyUnicode_Check(value)) { - PyErr_Format(PyExc_ValueError, - "initial_value must be str or None, not %.200s", - Py_TYPE(value)->tp_name); - return -1; - } - - self->ok = 0; - - Py_CLEAR(self->readnl); - Py_CLEAR(self->writenl); - Py_CLEAR(self->decoder); - - if (newline) { - self->readnl = PyUnicode_FromString(newline); - if (self->readnl == NULL) - return -1; - } - self->readuniversal = (newline == NULL || newline[0] == '\0'); - self->readtranslate = (newline == NULL); - /* If newline == "", we don't translate anything. - If newline == "\n" or newline == None, we translate to "\n", which is - a no-op. - (for newline == None, TextIOWrapper translates to os.sepline, but it - is pointless for StringIO) - */ - if (newline != NULL && newline[0] == '\r') { - self->writenl = self->readnl; - Py_INCREF(self->writenl); - } - - if (self->readuniversal) { - self->decoder = PyObject_CallFunction( - (PyObject *)&PyIncrementalNewlineDecoder_Type, - "Oi", Py_None, (int) self->readtranslate); - if (self->decoder == NULL) - return -1; - } - - /* Now everything is set up, resize buffer to size of initial value, - and copy it */ - self->string_size = 0; - if (value && value != Py_None) { - Py_ssize_t len = PyUnicode_GetSize(value); - /* This is a heuristic, for newline translation might change - the string length. */ - if (resize_buffer(self, len) < 0) - return -1; - self->pos = 0; - if (write_str(self, value) < 0) - return -1; - } - else { - if (resize_buffer(self, 0) < 0) - return -1; - } - self->pos = 0; - - self->closed = 0; - self->ok = 1; - return 0; -} - -/* Properties and pseudo-properties */ -static PyObject * -stringio_seekable(StringIOObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self); - Py_RETURN_TRUE; -} - -static PyObject * -stringio_readable(StringIOObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self); - Py_RETURN_TRUE; -} - -static PyObject * -stringio_writable(StringIOObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self); - Py_RETURN_TRUE; -} - -static PyObject * -stringio_buffer(StringIOObject *self, void *context) -{ - PyErr_SetString(IO_STATE->unsupported_operation, - "buffer attribute is unsupported on type StringIO"); - return NULL; -} - -static PyObject * -stringio_closed(StringIOObject *self, void *context) -{ - CHECK_INITIALIZED(self); - return PyBool_FromLong(self->closed); -} - -static PyObject * -stringio_encoding(StringIOObject *self, void *context) -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - Py_RETURN_NONE; -} - -static PyObject * -stringio_errors(StringIOObject *self, void *context) -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - return PyUnicode_FromString("strict"); -} - -static PyObject * -stringio_line_buffering(StringIOObject *self, void *context) -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - Py_RETURN_FALSE; -} - -static PyObject * -stringio_newlines(StringIOObject *self, void *context) -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - if (self->decoder == NULL) - Py_RETURN_NONE; - return PyObject_GetAttr(self->decoder, _PyIO_str_newlines); -} - -static struct PyMethodDef stringio_methods[] = { - {"close", (PyCFunction)stringio_close, METH_NOARGS, stringio_close_doc}, - {"getvalue", (PyCFunction)stringio_getvalue, METH_VARARGS, stringio_getvalue_doc}, - {"read", (PyCFunction)stringio_read, METH_VARARGS, stringio_read_doc}, - {"readline", (PyCFunction)stringio_readline, METH_VARARGS, stringio_readline_doc}, - {"tell", (PyCFunction)stringio_tell, METH_NOARGS, stringio_tell_doc}, - {"truncate", (PyCFunction)stringio_truncate, METH_VARARGS, stringio_truncate_doc}, - {"seek", (PyCFunction)stringio_seek, METH_VARARGS, stringio_seek_doc}, - {"write", (PyCFunction)stringio_write, METH_O, stringio_write_doc}, - - {"seekable", (PyCFunction)stringio_seekable, METH_NOARGS}, - {"readable", (PyCFunction)stringio_readable, METH_NOARGS}, - {"writable", (PyCFunction)stringio_writable, METH_NOARGS}, - {NULL, NULL} /* sentinel */ -}; - -static PyGetSetDef stringio_getset[] = { - {"closed", (getter)stringio_closed, NULL, NULL}, - {"newlines", (getter)stringio_newlines, NULL, NULL}, - /* (following comments straight off of the original Python wrapper:) - XXX Cruft to support the TextIOWrapper API. This would only - be meaningful if StringIO supported the buffer attribute. - Hopefully, a better solution, than adding these pseudo-attributes, - will be found. - */ - {"buffer", (getter)stringio_buffer, NULL, NULL}, - {"encoding", (getter)stringio_encoding, NULL, NULL}, - {"errors", (getter)stringio_errors, NULL, NULL}, - {"line_buffering", (getter)stringio_line_buffering, NULL, NULL}, - {0} -}; - -PyTypeObject PyStringIO_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.StringIO", /*tp_name*/ - sizeof(StringIOObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)stringio_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*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - stringio_doc, /*tp_doc*/ - (traverseproc)stringio_traverse, /*tp_traverse*/ - (inquiry)stringio_clear, /*tp_clear*/ - 0, /*tp_richcompare*/ - offsetof(StringIOObject, weakreflist), /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - (iternextfunc)stringio_iternext, /*tp_iternext*/ - stringio_methods, /*tp_methods*/ - 0, /*tp_members*/ - stringio_getset, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - offsetof(StringIOObject, dict), /*tp_dictoffset*/ - (initproc)stringio_init, /*tp_init*/ - 0, /*tp_alloc*/ - stringio_new, /*tp_new*/ -}; Deleted: python/branches/py3k-short-float-repr/Modules/_textio.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_textio.c Sun Apr 5 01:04:14 2009 +++ (empty file) @@ -1,2415 +0,0 @@ -/* - An implementation of Text I/O as defined by PEP 3116 - "New I/O" - - Classes defined here: TextIOBase, IncrementalNewlineDecoder, TextIOWrapper. - - Written by Amaury Forgeot d'Arc and Antoine Pitrou -*/ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#include "structmember.h" -#include "_iomodule.h" - -/* TextIOBase */ - -PyDoc_STRVAR(TextIOBase_doc, - "Base class for text I/O.\n" - "\n" - "This class provides a character and line based interface to stream\n" - "I/O. There is no readinto method because Python's character strings\n" - "are immutable. There is no public constructor.\n" - ); - -static PyObject * -_unsupported(const char *message) -{ - PyErr_SetString(IO_STATE->unsupported_operation, message); - return NULL; -} - -PyDoc_STRVAR(TextIOBase_read_doc, - "Read at most n characters from stream.\n" - "\n" - "Read from underlying buffer until we have n characters or we hit EOF.\n" - "If n is negative or omitted, read until EOF.\n" - ); - -static PyObject * -TextIOBase_read(PyObject *self, PyObject *args) -{ - return _unsupported("read"); -} - -PyDoc_STRVAR(TextIOBase_readline_doc, - "Read until newline or EOF.\n" - "\n" - "Returns an empty string if EOF is hit immediately.\n" - ); - -static PyObject * -TextIOBase_readline(PyObject *self, PyObject *args) -{ - return _unsupported("readline"); -} - -PyDoc_STRVAR(TextIOBase_write_doc, - "Write string to stream.\n" - "Returns the number of characters written (which is always equal to\n" - "the length of the string).\n" - ); - -static PyObject * -TextIOBase_write(PyObject *self, PyObject *args) -{ - return _unsupported("write"); -} - -PyDoc_STRVAR(TextIOBase_encoding_doc, - "Encoding of the text stream.\n" - "\n" - "Subclasses should override.\n" - ); - -static PyObject * -TextIOBase_encoding_get(PyObject *self, void *context) -{ - Py_RETURN_NONE; -} - -PyDoc_STRVAR(TextIOBase_newlines_doc, - "Line endings translated so far.\n" - "\n" - "Only line endings translated during reading are considered.\n" - "\n" - "Subclasses should override.\n" - ); - -static PyObject * -TextIOBase_newlines_get(PyObject *self, void *context) -{ - Py_RETURN_NONE; -} - - -static PyMethodDef TextIOBase_methods[] = { - {"read", TextIOBase_read, METH_VARARGS, TextIOBase_read_doc}, - {"readline", TextIOBase_readline, METH_VARARGS, TextIOBase_readline_doc}, - {"write", TextIOBase_write, METH_VARARGS, TextIOBase_write_doc}, - {NULL, NULL} -}; - -static PyGetSetDef TextIOBase_getset[] = { - {"encoding", (getter)TextIOBase_encoding_get, NULL, TextIOBase_encoding_doc}, - {"newlines", (getter)TextIOBase_newlines_get, NULL, TextIOBase_newlines_doc}, - {0} -}; - -PyTypeObject PyTextIOBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._TextIOBase", /*tp_name*/ - 0, /*tp_basicsize*/ - 0, /*tp_itemsize*/ - 0, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - TextIOBase_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - TextIOBase_methods, /* tp_methods */ - 0, /* tp_members */ - TextIOBase_getset, /* tp_getset */ - &PyIOBase_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ -}; - - -/* IncrementalNewlineDecoder */ - -PyDoc_STRVAR(IncrementalNewlineDecoder_doc, - "Codec used when reading a file in universal newlines mode. It wraps\n" - "another incremental decoder, translating \\r\\n and \\r into \\n. It also\n" - "records the types of newlines encountered. When used with\n" - "translate=False, it ensures that the newline sequence is returned in\n" - "one piece. When used with decoder=None, it expects unicode strings as\n" - "decode input and translates newlines without first invoking an external\n" - "decoder.\n" - ); - -typedef struct { - PyObject_HEAD - PyObject *decoder; - PyObject *errors; - int pendingcr:1; - int translate:1; - unsigned int seennl:3; -} PyNewLineDecoderObject; - -static int -IncrementalNewlineDecoder_init(PyNewLineDecoderObject *self, - PyObject *args, PyObject *kwds) -{ - PyObject *decoder; - int translate; - PyObject *errors = NULL; - char *kwlist[] = {"decoder", "translate", "errors", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi|O:IncrementalNewlineDecoder", - kwlist, &decoder, &translate, &errors)) - return -1; - - self->decoder = decoder; - Py_INCREF(decoder); - - if (errors == NULL) { - self->errors = PyUnicode_FromString("strict"); - if (self->errors == NULL) - return -1; - } - else { - Py_INCREF(errors); - self->errors = errors; - } - - self->translate = translate; - self->seennl = 0; - self->pendingcr = 0; - - return 0; -} - -static void -IncrementalNewlineDecoder_dealloc(PyNewLineDecoderObject *self) -{ - Py_CLEAR(self->decoder); - Py_CLEAR(self->errors); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -#define SEEN_CR 1 -#define SEEN_LF 2 -#define SEEN_CRLF 4 -#define SEEN_ALL (SEEN_CR | SEEN_LF | SEEN_CRLF) - -PyObject * -_PyIncrementalNewlineDecoder_decode(PyObject *_self, - PyObject *input, int final) -{ - PyObject *output; - Py_ssize_t output_len; - PyNewLineDecoderObject *self = (PyNewLineDecoderObject *) _self; - - if (self->decoder == NULL) { - PyErr_SetString(PyExc_ValueError, - "IncrementalNewlineDecoder.__init__ not called"); - return NULL; - } - - /* decode input (with the eventual \r from a previous pass) */ - if (self->decoder != Py_None) { - output = PyObject_CallMethodObjArgs(self->decoder, - _PyIO_str_decode, input, final ? Py_True : Py_False, NULL); - } - else { - output = input; - Py_INCREF(output); - } - - if (output == NULL) - return NULL; - - if (!PyUnicode_Check(output)) { - PyErr_SetString(PyExc_TypeError, - "decoder should return a string result"); - goto error; - } - - output_len = PyUnicode_GET_SIZE(output); - if (self->pendingcr && (final || output_len > 0)) { - Py_UNICODE *out; - PyObject *modified = PyUnicode_FromUnicode(NULL, output_len + 1); - if (modified == NULL) - goto error; - out = PyUnicode_AS_UNICODE(modified); - out[0] = '\r'; - memcpy(out + 1, PyUnicode_AS_UNICODE(output), - output_len * sizeof(Py_UNICODE)); - Py_DECREF(output); - output = modified; - self->pendingcr = 0; - output_len++; - } - - /* retain last \r even when not translating data: - * then readline() is sure to get \r\n in one pass - */ - if (!final) { - if (output_len > 0 - && PyUnicode_AS_UNICODE(output)[output_len - 1] == '\r') { - - if (Py_REFCNT(output) == 1) { - if (PyUnicode_Resize(&output, output_len - 1) < 0) - goto error; - } - else { - PyObject *modified = PyUnicode_FromUnicode( - PyUnicode_AS_UNICODE(output), - output_len - 1); - if (modified == NULL) - goto error; - Py_DECREF(output); - output = modified; - } - self->pendingcr = 1; - } - } - - /* Record which newlines are read and do newline translation if desired, - all in one pass. */ - { - Py_UNICODE *in_str; - Py_ssize_t len; - int seennl = self->seennl; - int only_lf = 0; - - in_str = PyUnicode_AS_UNICODE(output); - len = PyUnicode_GET_SIZE(output); - - if (len == 0) - return output; - - /* If, up to now, newlines are consistently \n, do a quick check - for the \r *byte* with the libc's optimized memchr. - */ - if (seennl == SEEN_LF || seennl == 0) { - only_lf = (memchr(in_str, '\r', len * sizeof(Py_UNICODE)) == NULL); - } - - if (only_lf) { - /* If not already seen, quick scan for a possible "\n" character. - (there's nothing else to be done, even when in translation mode) - */ - if (seennl == 0 && - memchr(in_str, '\n', len * sizeof(Py_UNICODE)) != NULL) { - Py_UNICODE *s, *end; - s = in_str; - end = in_str + len; - for (;;) { - Py_UNICODE c; - /* Fast loop for non-control characters */ - while (*s > '\n') - s++; - c = *s++; - if (c == '\n') { - seennl |= SEEN_LF; - break; - } - if (s > end) - break; - } - } - /* Finished: we have scanned for newlines, and none of them - need translating */ - } - else if (!self->translate) { - Py_UNICODE *s, *end; - /* We have already seen all newline types, no need to scan again */ - if (seennl == SEEN_ALL) - goto endscan; - s = in_str; - end = in_str + len; - for (;;) { - Py_UNICODE c; - /* Fast loop for non-control characters */ - while (*s > '\r') - s++; - c = *s++; - if (c == '\n') - seennl |= SEEN_LF; - else if (c == '\r') { - if (*s == '\n') { - seennl |= SEEN_CRLF; - s++; - } - else - seennl |= SEEN_CR; - } - if (s > end) - break; - if (seennl == SEEN_ALL) - break; - } - endscan: - ; - } - else { - PyObject *translated = NULL; - Py_UNICODE *out_str; - Py_UNICODE *in, *out, *end; - if (Py_REFCNT(output) != 1) { - /* We could try to optimize this so that we only do a copy - when there is something to translate. On the other hand, - most decoders should only output non-shared strings, i.e. - translation is done in place. */ - translated = PyUnicode_FromUnicode(NULL, len); - if (translated == NULL) - goto error; - assert(Py_REFCNT(translated) == 1); - memcpy(PyUnicode_AS_UNICODE(translated), - PyUnicode_AS_UNICODE(output), - len * sizeof(Py_UNICODE)); - } - else { - translated = output; - } - out_str = PyUnicode_AS_UNICODE(translated); - in = in_str; - out = out_str; - end = in_str + len; - for (;;) { - Py_UNICODE c; - /* Fast loop for non-control characters */ - while ((c = *in++) > '\r') - *out++ = c; - if (c == '\n') { - *out++ = c; - seennl |= SEEN_LF; - continue; - } - if (c == '\r') { - if (*in == '\n') { - in++; - seennl |= SEEN_CRLF; - } - else - seennl |= SEEN_CR; - *out++ = '\n'; - continue; - } - if (in > end) - break; - *out++ = c; - } - if (translated != output) { - Py_DECREF(output); - output = translated; - } - if (out - out_str != len) { - if (PyUnicode_Resize(&output, out - out_str) < 0) - goto error; - } - } - self->seennl |= seennl; - } - - return output; - - error: - Py_DECREF(output); - return NULL; -} - -static PyObject * -IncrementalNewlineDecoder_decode(PyNewLineDecoderObject *self, - PyObject *args, PyObject *kwds) -{ - char *kwlist[] = {"input", "final", NULL}; - PyObject *input; - int final = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:IncrementalNewlineDecoder", - kwlist, &input, &final)) - return NULL; - return _PyIncrementalNewlineDecoder_decode((PyObject *) self, input, final); -} - -static PyObject * -IncrementalNewlineDecoder_getstate(PyNewLineDecoderObject *self, PyObject *args) -{ - PyObject *buffer; - unsigned PY_LONG_LONG flag; - - if (self->decoder != Py_None) { - PyObject *state = PyObject_CallMethodObjArgs(self->decoder, - _PyIO_str_getstate, NULL); - if (state == NULL) - return NULL; - if (!PyArg_Parse(state, "(OK)", &buffer, &flag)) { - Py_DECREF(state); - return NULL; - } - Py_INCREF(buffer); - Py_DECREF(state); - } - else { - buffer = PyBytes_FromString(""); - flag = 0; - } - flag <<= 1; - if (self->pendingcr) - flag |= 1; - return Py_BuildValue("NK", buffer, flag); -} - -static PyObject * -IncrementalNewlineDecoder_setstate(PyNewLineDecoderObject *self, PyObject *state) -{ - PyObject *buffer; - unsigned PY_LONG_LONG flag; - - if (!PyArg_Parse(state, "(OK)", &buffer, &flag)) - return NULL; - - self->pendingcr = (int) flag & 1; - flag >>= 1; - - if (self->decoder != Py_None) - return PyObject_CallMethod(self->decoder, - "setstate", "((OK))", buffer, flag); - else - Py_RETURN_NONE; -} - -static PyObject * -IncrementalNewlineDecoder_reset(PyNewLineDecoderObject *self, PyObject *args) -{ - self->seennl = 0; - self->pendingcr = 0; - if (self->decoder != Py_None) - return PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL); - else - Py_RETURN_NONE; -} - -static PyObject * -IncrementalNewlineDecoder_newlines_get(PyNewLineDecoderObject *self, void *context) -{ - switch (self->seennl) { - case SEEN_CR: - return PyUnicode_FromString("\r"); - case SEEN_LF: - return PyUnicode_FromString("\n"); - case SEEN_CRLF: - return PyUnicode_FromString("\r\n"); - case SEEN_CR | SEEN_LF: - return Py_BuildValue("ss", "\r", "\n"); - case SEEN_CR | SEEN_CRLF: - return Py_BuildValue("ss", "\r", "\r\n"); - case SEEN_LF | SEEN_CRLF: - return Py_BuildValue("ss", "\n", "\r\n"); - case SEEN_CR | SEEN_LF | SEEN_CRLF: - return Py_BuildValue("sss", "\r", "\n", "\r\n"); - default: - Py_RETURN_NONE; - } - -} - - -static PyMethodDef IncrementalNewlineDecoder_methods[] = { - {"decode", (PyCFunction)IncrementalNewlineDecoder_decode, METH_VARARGS|METH_KEYWORDS}, - {"getstate", (PyCFunction)IncrementalNewlineDecoder_getstate, METH_NOARGS}, - {"setstate", (PyCFunction)IncrementalNewlineDecoder_setstate, METH_O}, - {"reset", (PyCFunction)IncrementalNewlineDecoder_reset, METH_NOARGS}, - {0} -}; - -static PyGetSetDef IncrementalNewlineDecoder_getset[] = { - {"newlines", (getter)IncrementalNewlineDecoder_newlines_get, NULL, NULL}, - {0} -}; - -PyTypeObject PyIncrementalNewlineDecoder_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.IncrementalNewlineDecoder", /*tp_name*/ - sizeof(PyNewLineDecoderObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)IncrementalNewlineDecoder_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - IncrementalNewlineDecoder_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /*tp_weaklistoffset*/ - 0, /* tp_iter */ - 0, /* tp_iternext */ - IncrementalNewlineDecoder_methods, /* tp_methods */ - 0, /* tp_members */ - IncrementalNewlineDecoder_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)IncrementalNewlineDecoder_init, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; - - -/* TextIOWrapper */ - -PyDoc_STRVAR(TextIOWrapper_doc, - "Character and line based layer over a BufferedIOBase object, buffer.\n" - "\n" - "encoding gives the name of the encoding that the stream will be\n" - "decoded or encoded with. It defaults to locale.getpreferredencoding.\n" - "\n" - "errors determines the strictness of encoding and decoding (see the\n" - "codecs.register) and defaults to \"strict\".\n" - "\n" - "newline can be None, '', '\\n', '\\r', or '\\r\\n'. It controls the\n" - "handling of line endings. If it is None, universal newlines is\n" - "enabled. With this enabled, on input, the lines endings '\\n', '\\r',\n" - "or '\\r\\n' are translated to '\\n' before being returned to the\n" - "caller. Conversely, on output, '\\n' is translated to the system\n" - "default line seperator, os.linesep. If newline is any other of its\n" - "legal values, that newline becomes the newline when the file is read\n" - "and it is returned untranslated. On output, '\\n' is converted to the\n" - "newline.\n" - "\n" - "If line_buffering is True, a call to flush is implied when a call to\n" - "write contains a newline character." - ); - -typedef PyObject * - (*encodefunc_t)(PyObject *, PyObject *); - -typedef struct -{ - PyObject_HEAD - int ok; /* initialized? */ - Py_ssize_t chunk_size; - PyObject *buffer; - PyObject *encoding; - PyObject *encoder; - PyObject *decoder; - PyObject *readnl; - PyObject *errors; - const char *writenl; /* utf-8 encoded, NULL stands for \n */ - char line_buffering; - char readuniversal; - char readtranslate; - char writetranslate; - char seekable; - char telling; - /* Specialized encoding func (see below) */ - encodefunc_t encodefunc; - - /* Reads and writes are internally buffered in order to speed things up. - However, any read will first flush the write buffer if itsn't empty. - - Please also note that text to be written is first encoded before being - buffered. This is necessary so that encoding errors are immediately - reported to the caller, but it unfortunately means that the - IncrementalEncoder (whose encode() method is always written in Python) - becomes a bottleneck for small writes. - */ - PyObject *decoded_chars; /* buffer for text returned from decoder */ - Py_ssize_t decoded_chars_used; /* offset into _decoded_chars for read() */ - PyObject *pending_bytes; /* list of bytes objects waiting to be - written, or NULL */ - Py_ssize_t pending_bytes_count; - PyObject *snapshot; - /* snapshot is either None, or a tuple (dec_flags, next_input) where - * dec_flags is the second (integer) item of the decoder state and - * next_input is the chunk of input bytes that comes next after the - * snapshot point. We use this to reconstruct decoder states in tell(). - */ - - /* Cache raw object if it's a FileIO object */ - PyObject *raw; - - PyObject *weakreflist; - PyObject *dict; -} PyTextIOWrapperObject; - - -/* A couple of specialized cases in order to bypass the slow incremental - encoding methods for the most popular encodings. */ - -static PyObject * -ascii_encode(PyTextIOWrapperObject *self, PyObject *text) -{ - return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(text), - PyUnicode_GET_SIZE(text), - PyBytes_AS_STRING(self->errors)); -} - -static PyObject * -utf16be_encode(PyTextIOWrapperObject *self, PyObject *text) -{ - return PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(text), - PyUnicode_GET_SIZE(text), - PyBytes_AS_STRING(self->errors), 1); -} - -static PyObject * -utf16le_encode(PyTextIOWrapperObject *self, PyObject *text) -{ - return PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(text), - PyUnicode_GET_SIZE(text), - PyBytes_AS_STRING(self->errors), -1); -} - -static PyObject * -utf16_encode(PyTextIOWrapperObject *self, PyObject *text) -{ - PyObject *res; - res = PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(text), - PyUnicode_GET_SIZE(text), - PyBytes_AS_STRING(self->errors), 0); - if (res == NULL) - return NULL; - /* Next writes will skip the BOM and use native byte ordering */ -#if defined(WORDS_BIGENDIAN) - self->encodefunc = (encodefunc_t) utf16be_encode; -#else - self->encodefunc = (encodefunc_t) utf16le_encode; -#endif - return res; -} - - -static PyObject * -utf8_encode(PyTextIOWrapperObject *self, PyObject *text) -{ - return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(text), - PyUnicode_GET_SIZE(text), - PyBytes_AS_STRING(self->errors)); -} - -static PyObject * -latin1_encode(PyTextIOWrapperObject *self, PyObject *text) -{ - return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(text), - PyUnicode_GET_SIZE(text), - PyBytes_AS_STRING(self->errors)); -} - -/* Map normalized encoding names onto the specialized encoding funcs */ - -typedef struct { - const char *name; - encodefunc_t encodefunc; -} encodefuncentry; - -static encodefuncentry encodefuncs[] = { - {"ascii", (encodefunc_t) ascii_encode}, - {"iso8859-1", (encodefunc_t) latin1_encode}, - {"utf-16-be", (encodefunc_t) utf16be_encode}, - {"utf-16-le", (encodefunc_t) utf16le_encode}, - {"utf-16", (encodefunc_t) utf16_encode}, - {"utf-8", (encodefunc_t) utf8_encode}, - {NULL, NULL} -}; - - -static int -TextIOWrapper_init(PyTextIOWrapperObject *self, PyObject *args, PyObject *kwds) -{ - char *kwlist[] = {"buffer", "encoding", "errors", - "newline", "line_buffering", - NULL}; - PyObject *buffer, *raw; - char *encoding = NULL; - char *errors = NULL; - char *newline = NULL; - int line_buffering = 0; - _PyIO_State *state = IO_STATE; - - PyObject *res; - int r; - - self->ok = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|zzzi:fileio", - kwlist, &buffer, &encoding, &errors, - &newline, &line_buffering)) - return -1; - - if (newline && newline[0] != '\0' - && !(newline[0] == '\n' && newline[1] == '\0') - && !(newline[0] == '\r' && newline[1] == '\0') - && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) { - PyErr_Format(PyExc_ValueError, - "illegal newline value: %s", newline); - return -1; - } - - Py_CLEAR(self->buffer); - Py_CLEAR(self->encoding); - Py_CLEAR(self->encoder); - Py_CLEAR(self->decoder); - Py_CLEAR(self->readnl); - Py_CLEAR(self->decoded_chars); - Py_CLEAR(self->pending_bytes); - Py_CLEAR(self->snapshot); - Py_CLEAR(self->errors); - Py_CLEAR(self->raw); - self->decoded_chars_used = 0; - self->pending_bytes_count = 0; - self->encodefunc = NULL; - - if (encoding == NULL) { - /* Try os.device_encoding(fileno) */ - PyObject *fileno; - fileno = PyObject_CallMethod(buffer, "fileno", NULL); - /* Ignore only AttributeError and UnsupportedOperation */ - if (fileno == NULL) { - if (PyErr_ExceptionMatches(PyExc_AttributeError) || - PyErr_ExceptionMatches(state->unsupported_operation)) { - PyErr_Clear(); - } - else { - goto error; - } - } - else { - self->encoding = PyObject_CallMethod(state->os_module, - "device_encoding", - "N", fileno); - if (self->encoding == NULL) - goto error; - else if (!PyUnicode_Check(self->encoding)) - Py_CLEAR(self->encoding); - } - } - if (encoding == NULL && self->encoding == NULL) { - if (state->locale_module == NULL) { - state->locale_module = PyImport_ImportModule("locale"); - if (state->locale_module == NULL) - goto catch_ImportError; - else - goto use_locale; - } - else { - use_locale: - self->encoding = PyObject_CallMethod( - state->locale_module, "getpreferredencoding", NULL); - if (self->encoding == NULL) { - catch_ImportError: - /* - Importing locale can raise a ImportError because of - _functools, and locale.getpreferredencoding can raise a - ImportError if _locale is not available. These will happen - during module building. - */ - if (PyErr_ExceptionMatches(PyExc_ImportError)) { - PyErr_Clear(); - self->encoding = PyUnicode_FromString("ascii"); - } - else - goto error; - } - else if (!PyUnicode_Check(self->encoding)) - Py_CLEAR(self->encoding); - } - } - if (self->encoding != NULL) - encoding = _PyUnicode_AsString(self->encoding); - else if (encoding != NULL) { - self->encoding = PyUnicode_FromString(encoding); - if (self->encoding == NULL) - goto error; - } - else { - PyErr_SetString(PyExc_IOError, - "could not determine default encoding"); - } - - if (errors == NULL) - errors = "strict"; - self->errors = PyBytes_FromString(errors); - if (self->errors == NULL) - goto error; - - self->chunk_size = 8192; - self->readuniversal = (newline == NULL || newline[0] == '\0'); - self->line_buffering = line_buffering; - self->readtranslate = (newline == NULL); - if (newline) { - self->readnl = PyUnicode_FromString(newline); - if (self->readnl == NULL) - return -1; - } - self->writetranslate = (newline == NULL || newline[0] != '\0'); - if (!self->readuniversal && self->readnl) { - self->writenl = _PyUnicode_AsString(self->readnl); - if (!strcmp(self->writenl, "\n")) - self->writenl = NULL; - } -#ifdef MS_WINDOWS - else - self->writenl = "\r\n"; -#endif - - /* Build the decoder object */ - res = PyObject_CallMethod(buffer, "readable", NULL); - if (res == NULL) - goto error; - r = PyObject_IsTrue(res); - Py_DECREF(res); - if (r == -1) - goto error; - if (r == 1) { - self->decoder = PyCodec_IncrementalDecoder( - encoding, errors); - if (self->decoder == NULL) - goto error; - - if (self->readuniversal) { - PyObject *incrementalDecoder = PyObject_CallFunction( - (PyObject *)&PyIncrementalNewlineDecoder_Type, - "Oi", self->decoder, (int)self->readtranslate); - if (incrementalDecoder == NULL) - goto error; - Py_CLEAR(self->decoder); - self->decoder = incrementalDecoder; - } - } - - /* Build the encoder object */ - res = PyObject_CallMethod(buffer, "writable", NULL); - if (res == NULL) - goto error; - r = PyObject_IsTrue(res); - Py_DECREF(res); - if (r == -1) - goto error; - if (r == 1) { - PyObject *ci; - self->encoder = PyCodec_IncrementalEncoder( - encoding, errors); - if (self->encoder == NULL) - goto error; - /* Get the normalized named of the codec */ - ci = _PyCodec_Lookup(encoding); - if (ci == NULL) - goto error; - res = PyObject_GetAttrString(ci, "name"); - Py_DECREF(ci); - if (res == NULL) - PyErr_Clear(); - else if (PyUnicode_Check(res)) { - encodefuncentry *e = encodefuncs; - while (e->name != NULL) { - if (!PyUnicode_CompareWithASCIIString(res, e->name)) { - self->encodefunc = e->encodefunc; - break; - } - e++; - } - } - Py_XDECREF(res); - } - - self->buffer = buffer; - Py_INCREF(buffer); - - if (Py_TYPE(buffer) == &PyBufferedReader_Type || - Py_TYPE(buffer) == &PyBufferedWriter_Type || - Py_TYPE(buffer) == &PyBufferedRandom_Type) { - raw = PyObject_GetAttrString(buffer, "raw"); - /* Cache the raw FileIO object to speed up 'closed' checks */ - if (raw == NULL) - PyErr_Clear(); - else if (Py_TYPE(raw) == &PyFileIO_Type) - self->raw = raw; - else - Py_DECREF(raw); - } - - res = PyObject_CallMethod(buffer, "seekable", NULL); - if (res == NULL) - goto error; - self->seekable = self->telling = PyObject_IsTrue(res); - Py_DECREF(res); - - self->ok = 1; - return 0; - - error: - return -1; -} - -static int -_TextIOWrapper_clear(PyTextIOWrapperObject *self) -{ - if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0) - return -1; - self->ok = 0; - Py_CLEAR(self->buffer); - Py_CLEAR(self->encoding); - Py_CLEAR(self->encoder); - Py_CLEAR(self->decoder); - Py_CLEAR(self->readnl); - Py_CLEAR(self->decoded_chars); - Py_CLEAR(self->pending_bytes); - Py_CLEAR(self->snapshot); - Py_CLEAR(self->errors); - Py_CLEAR(self->raw); - return 0; -} - -static void -TextIOWrapper_dealloc(PyTextIOWrapperObject *self) -{ - if (_TextIOWrapper_clear(self) < 0) - return; - _PyObject_GC_UNTRACK(self); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *)self); - Py_CLEAR(self->dict); - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static int -TextIOWrapper_traverse(PyTextIOWrapperObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->buffer); - Py_VISIT(self->encoding); - Py_VISIT(self->encoder); - Py_VISIT(self->decoder); - Py_VISIT(self->readnl); - Py_VISIT(self->decoded_chars); - Py_VISIT(self->pending_bytes); - Py_VISIT(self->snapshot); - Py_VISIT(self->errors); - Py_VISIT(self->raw); - - Py_VISIT(self->dict); - return 0; -} - -static int -TextIOWrapper_clear(PyTextIOWrapperObject *self) -{ - if (_TextIOWrapper_clear(self) < 0) - return -1; - Py_CLEAR(self->dict); - return 0; -} - -static PyObject * -TextIOWrapper_closed_get(PyTextIOWrapperObject *self, void *context); - -/* This macro takes some shortcuts to make the common case faster. */ -#define CHECK_CLOSED(self) \ - do { \ - int r; \ - PyObject *_res; \ - if (Py_TYPE(self) == &PyTextIOWrapper_Type) { \ - if (self->raw != NULL) \ - r = _PyFileIO_closed(self->raw); \ - else { \ - _res = TextIOWrapper_closed_get(self, NULL); \ - if (_res == NULL) \ - return NULL; \ - r = PyObject_IsTrue(_res); \ - Py_DECREF(_res); \ - if (r < 0) \ - return NULL; \ - } \ - if (r > 0) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on closed file."); \ - return NULL; \ - } \ - } \ - else if (_PyIOBase_checkClosed((PyObject *)self, Py_True) == NULL) \ - return NULL; \ - } while (0) - -#define CHECK_INITIALIZED(self) \ - if (self->ok <= 0) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - return NULL; \ - } - -#define CHECK_INITIALIZED_INT(self) \ - if (self->ok <= 0) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - return -1; \ - } - - -Py_LOCAL_INLINE(const Py_UNICODE *) -findchar(const Py_UNICODE *s, Py_ssize_t size, Py_UNICODE ch) -{ - /* like wcschr, but doesn't stop at NULL characters */ - while (size-- > 0) { - if (*s == ch) - return s; - s++; - } - return NULL; -} - -/* Flush the internal write buffer. This doesn't explicitly flush the - underlying buffered object, though. */ -static int -_TextIOWrapper_writeflush(PyTextIOWrapperObject *self) -{ - PyObject *b, *ret; - - if (self->pending_bytes == NULL) - return 0; - b = _PyBytes_Join(_PyIO_empty_bytes, self->pending_bytes); - if (b == NULL) - return -1; - ret = PyObject_CallMethodObjArgs(self->buffer, - _PyIO_str_write, b, NULL); - Py_DECREF(b); - if (ret == NULL) - return -1; - Py_DECREF(ret); - Py_CLEAR(self->pending_bytes); - self->pending_bytes_count = 0; - return 0; -} - -static PyObject * -TextIOWrapper_write(PyTextIOWrapperObject *self, PyObject *args) -{ - PyObject *ret; - PyObject *text; /* owned reference */ - PyObject *b; - Py_ssize_t textlen; - int haslf = 0; - int needflush = 0; - - CHECK_INITIALIZED(self); - - if (!PyArg_ParseTuple(args, "U:write", &text)) { - return NULL; - } - - CHECK_CLOSED(self); - - Py_INCREF(text); - - textlen = PyUnicode_GetSize(text); - - if ((self->writetranslate && self->writenl != NULL) || self->line_buffering) - if (findchar(PyUnicode_AS_UNICODE(text), - PyUnicode_GET_SIZE(text), '\n')) - haslf = 1; - - if (haslf && self->writetranslate && self->writenl != NULL) { - PyObject *newtext = PyObject_CallMethod( - text, "replace", "ss", "\n", self->writenl); - Py_DECREF(text); - if (newtext == NULL) - return NULL; - text = newtext; - } - - if (self->line_buffering && - (haslf || - findchar(PyUnicode_AS_UNICODE(text), - PyUnicode_GET_SIZE(text), '\r'))) - needflush = 1; - - /* XXX What if we were just reading? */ - if (self->encodefunc != NULL) - b = (*self->encodefunc)((PyObject *) self, text); - else - b = PyObject_CallMethodObjArgs(self->encoder, - _PyIO_str_encode, text, NULL); - Py_DECREF(text); - if (b == NULL) - return NULL; - - if (self->pending_bytes == NULL) { - self->pending_bytes = PyList_New(0); - if (self->pending_bytes == NULL) { - Py_DECREF(b); - return NULL; - } - self->pending_bytes_count = 0; - } - if (PyList_Append(self->pending_bytes, b) < 0) { - Py_DECREF(b); - return NULL; - } - self->pending_bytes_count += PyBytes_GET_SIZE(b); - Py_DECREF(b); - if (self->pending_bytes_count > self->chunk_size || needflush) { - if (_TextIOWrapper_writeflush(self) < 0) - return NULL; - } - - if (needflush) { - ret = PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_flush, NULL); - if (ret == NULL) - return NULL; - Py_DECREF(ret); - } - - Py_CLEAR(self->snapshot); - - if (self->decoder) { - ret = PyObject_CallMethod(self->decoder, "reset", NULL); - if (ret == NULL) - return NULL; - Py_DECREF(ret); - } - - return PyLong_FromSsize_t(textlen); -} - -/* Steal a reference to chars and store it in the decoded_char buffer; - */ -static void -TextIOWrapper_set_decoded_chars(PyTextIOWrapperObject *self, PyObject *chars) -{ - Py_CLEAR(self->decoded_chars); - self->decoded_chars = chars; - self->decoded_chars_used = 0; -} - -static PyObject * -TextIOWrapper_get_decoded_chars(PyTextIOWrapperObject *self, Py_ssize_t n) -{ - PyObject *chars; - Py_ssize_t avail; - - if (self->decoded_chars == NULL) - return PyUnicode_FromStringAndSize(NULL, 0); - - avail = (PyUnicode_GET_SIZE(self->decoded_chars) - - self->decoded_chars_used); - - assert(avail >= 0); - - if (n < 0 || n > avail) - n = avail; - - if (self->decoded_chars_used > 0 || n < avail) { - chars = PyUnicode_FromUnicode( - PyUnicode_AS_UNICODE(self->decoded_chars) - + self->decoded_chars_used, n); - if (chars == NULL) - return NULL; - } - else { - chars = self->decoded_chars; - Py_INCREF(chars); - } - - self->decoded_chars_used += n; - return chars; -} - -/* Read and decode the next chunk of data from the BufferedReader. - */ -static int -TextIOWrapper_read_chunk(PyTextIOWrapperObject *self) -{ - PyObject *dec_buffer = NULL; - PyObject *dec_flags = NULL; - PyObject *input_chunk = NULL; - PyObject *decoded_chars, *chunk_size; - int eof; - - /* The return value is True unless EOF was reached. The decoded string is - * placed in self._decoded_chars (replacing its previous value). The - * entire input chunk is sent to the decoder, though some of it may remain - * buffered in the decoder, yet to be converted. - */ - - if (self->decoder == NULL) { - PyErr_SetString(PyExc_ValueError, "no decoder"); - return -1; - } - - if (self->telling) { - /* To prepare for tell(), we need to snapshot a point in the file - * where the decoder's input buffer is empty. - */ - - PyObject *state = PyObject_CallMethodObjArgs(self->decoder, - _PyIO_str_getstate, NULL); - if (state == NULL) - return -1; - /* Given this, we know there was a valid snapshot point - * len(dec_buffer) bytes ago with decoder state (b'', dec_flags). - */ - if (PyArg_Parse(state, "(OO)", &dec_buffer, &dec_flags) < 0) { - Py_DECREF(state); - return -1; - } - Py_INCREF(dec_buffer); - Py_INCREF(dec_flags); - Py_DECREF(state); - } - - /* Read a chunk, decode it, and put the result in self._decoded_chars. */ - chunk_size = PyLong_FromSsize_t(self->chunk_size); - if (chunk_size == NULL) - goto fail; - input_chunk = PyObject_CallMethodObjArgs(self->buffer, - _PyIO_str_read1, chunk_size, NULL); - Py_DECREF(chunk_size); - if (input_chunk == NULL) - goto fail; - assert(PyBytes_Check(input_chunk)); - - eof = (PyBytes_Size(input_chunk) == 0); - - if (Py_TYPE(self->decoder) == &PyIncrementalNewlineDecoder_Type) { - decoded_chars = _PyIncrementalNewlineDecoder_decode( - self->decoder, input_chunk, eof); - } - else { - decoded_chars = PyObject_CallMethodObjArgs(self->decoder, - _PyIO_str_decode, input_chunk, eof ? Py_True : Py_False, NULL); - } - - /* TODO sanity check: isinstance(decoded_chars, unicode) */ - if (decoded_chars == NULL) - goto fail; - TextIOWrapper_set_decoded_chars(self, decoded_chars); - if (PyUnicode_GET_SIZE(decoded_chars) > 0) - eof = 0; - - if (self->telling) { - /* At the snapshot point, len(dec_buffer) bytes before the read, the - * next input to be decoded is dec_buffer + input_chunk. - */ - PyObject *next_input = PyNumber_Add(dec_buffer, input_chunk); - if (next_input == NULL) - goto fail; - assert (PyBytes_Check(next_input)); - Py_DECREF(dec_buffer); - Py_CLEAR(self->snapshot); - self->snapshot = Py_BuildValue("NN", dec_flags, next_input); - } - Py_DECREF(input_chunk); - - return (eof == 0); - - fail: - Py_XDECREF(dec_buffer); - Py_XDECREF(dec_flags); - Py_XDECREF(input_chunk); - return -1; -} - -static PyObject * -TextIOWrapper_read(PyTextIOWrapperObject *self, PyObject *args) -{ - Py_ssize_t n = -1; - PyObject *result = NULL, *chunks = NULL; - - CHECK_INITIALIZED(self); - - if (!PyArg_ParseTuple(args, "|n:read", &n)) - return NULL; - - CHECK_CLOSED(self); - - if (_TextIOWrapper_writeflush(self) < 0) - return NULL; - - if (n < 0) { - /* Read everything */ - PyObject *bytes = PyObject_CallMethod(self->buffer, "read", NULL); - PyObject *decoded; - if (bytes == NULL) - goto fail; - decoded = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_decode, - bytes, Py_True, NULL); - Py_DECREF(bytes); - if (decoded == NULL) - goto fail; - - result = TextIOWrapper_get_decoded_chars(self, -1); - - if (result == NULL) { - Py_DECREF(decoded); - return NULL; - } - - PyUnicode_AppendAndDel(&result, decoded); - if (result == NULL) - goto fail; - - Py_CLEAR(self->snapshot); - return result; - } - else { - int res = 1; - Py_ssize_t remaining = n; - - result = TextIOWrapper_get_decoded_chars(self, n); - if (result == NULL) - goto fail; - remaining -= PyUnicode_GET_SIZE(result); - - /* Keep reading chunks until we have n characters to return */ - while (remaining > 0) { - res = TextIOWrapper_read_chunk(self); - if (res < 0) - goto fail; - if (res == 0) /* EOF */ - break; - if (chunks == NULL) { - chunks = PyList_New(0); - if (chunks == NULL) - goto fail; - } - if (PyList_Append(chunks, result) < 0) - goto fail; - Py_DECREF(result); - result = TextIOWrapper_get_decoded_chars(self, remaining); - if (result == NULL) - goto fail; - remaining -= PyUnicode_GET_SIZE(result); - } - if (chunks != NULL) { - if (result != NULL && PyList_Append(chunks, result) < 0) - goto fail; - Py_CLEAR(result); - result = PyUnicode_Join(_PyIO_empty_str, chunks); - if (result == NULL) - goto fail; - Py_CLEAR(chunks); - } - return result; - } - fail: - Py_XDECREF(result); - Py_XDECREF(chunks); - return NULL; -} - - -/* NOTE: `end` must point to the real end of the Py_UNICODE storage, - that is to the NUL character. Otherwise the function will produce - incorrect results. */ -static Py_UNICODE * -find_control_char(Py_UNICODE *start, Py_UNICODE *end, Py_UNICODE ch) -{ - Py_UNICODE *s = start; - for (;;) { - while (*s > ch) - s++; - if (*s == ch) - return s; - if (s == end) - return NULL; - s++; - } -} - -Py_ssize_t -_PyIO_find_line_ending( - int translated, int universal, PyObject *readnl, - Py_UNICODE *start, Py_UNICODE *end, Py_ssize_t *consumed) -{ - Py_ssize_t len = end - start; - - if (translated) { - /* Newlines are already translated, only search for \n */ - Py_UNICODE *pos = find_control_char(start, end, '\n'); - if (pos != NULL) - return pos - start + 1; - else { - *consumed = len; - return -1; - } - } - else if (universal) { - /* Universal newline search. Find any of \r, \r\n, \n - * The decoder ensures that \r\n are not split in two pieces - */ - Py_UNICODE *s = start; - for (;;) { - Py_UNICODE ch; - /* Fast path for non-control chars. The loop always ends - since the Py_UNICODE storage is NUL-terminated. */ - while (*s > '\r') - s++; - if (s >= end) { - *consumed = len; - return -1; - } - ch = *s++; - if (ch == '\n') - return s - start; - if (ch == '\r') { - if (*s == '\n') - return s - start + 1; - else - return s - start; - } - } - } - else { - /* Non-universal mode. */ - Py_ssize_t readnl_len = PyUnicode_GET_SIZE(readnl); - Py_UNICODE *nl = PyUnicode_AS_UNICODE(readnl); - if (readnl_len == 1) { - Py_UNICODE *pos = find_control_char(start, end, nl[0]); - if (pos != NULL) - return pos - start + 1; - *consumed = len; - return -1; - } - else { - Py_UNICODE *s = start; - Py_UNICODE *e = end - readnl_len + 1; - Py_UNICODE *pos; - if (e < s) - e = s; - while (s < e) { - Py_ssize_t i; - Py_UNICODE *pos = find_control_char(s, end, nl[0]); - if (pos == NULL || pos >= e) - break; - for (i = 1; i < readnl_len; i++) { - if (pos[i] != nl[i]) - break; - } - if (i == readnl_len) - return pos - start + readnl_len; - s = pos + 1; - } - pos = find_control_char(e, end, nl[0]); - if (pos == NULL) - *consumed = len; - else - *consumed = pos - start; - return -1; - } - } -} - -static PyObject * -_TextIOWrapper_readline(PyTextIOWrapperObject *self, Py_ssize_t limit) -{ - PyObject *line = NULL, *chunks = NULL, *remaining = NULL; - Py_ssize_t start, endpos, chunked, offset_to_buffer; - int res; - - CHECK_CLOSED(self); - - if (_TextIOWrapper_writeflush(self) < 0) - return NULL; - - chunked = 0; - - while (1) { - Py_UNICODE *ptr; - Py_ssize_t line_len; - Py_ssize_t consumed = 0; - - /* First, get some data if necessary */ - res = 1; - while (!self->decoded_chars || - !PyUnicode_GET_SIZE(self->decoded_chars)) { - res = TextIOWrapper_read_chunk(self); - if (res < 0) - goto error; - if (res == 0) - break; - } - if (res == 0) { - /* end of file */ - TextIOWrapper_set_decoded_chars(self, NULL); - Py_CLEAR(self->snapshot); - start = endpos = offset_to_buffer = 0; - break; - } - - if (remaining == NULL) { - line = self->decoded_chars; - start = self->decoded_chars_used; - offset_to_buffer = 0; - Py_INCREF(line); - } - else { - assert(self->decoded_chars_used == 0); - line = PyUnicode_Concat(remaining, self->decoded_chars); - start = 0; - offset_to_buffer = PyUnicode_GET_SIZE(remaining); - Py_CLEAR(remaining); - if (line == NULL) - goto error; - } - - ptr = PyUnicode_AS_UNICODE(line); - line_len = PyUnicode_GET_SIZE(line); - - endpos = _PyIO_find_line_ending( - self->readtranslate, self->readuniversal, self->readnl, - ptr + start, ptr + line_len, &consumed); - if (endpos >= 0) { - endpos += start; - if (limit >= 0 && (endpos - start) + chunked >= limit) - endpos = start + limit - chunked; - break; - } - - /* We can put aside up to `endpos` */ - endpos = consumed + start; - if (limit >= 0 && (endpos - start) + chunked >= limit) { - /* Didn't find line ending, but reached length limit */ - endpos = start + limit - chunked; - break; - } - - if (endpos > start) { - /* No line ending seen yet - put aside current data */ - PyObject *s; - if (chunks == NULL) { - chunks = PyList_New(0); - if (chunks == NULL) - goto error; - } - s = PyUnicode_FromUnicode(ptr + start, endpos - start); - if (s == NULL) - goto error; - if (PyList_Append(chunks, s) < 0) { - Py_DECREF(s); - goto error; - } - chunked += PyUnicode_GET_SIZE(s); - Py_DECREF(s); - } - /* There may be some remaining bytes we'll have to prepend to the - next chunk of data */ - if (endpos < line_len) { - remaining = PyUnicode_FromUnicode( - ptr + endpos, line_len - endpos); - if (remaining == NULL) - goto error; - } - Py_CLEAR(line); - /* We have consumed the buffer */ - TextIOWrapper_set_decoded_chars(self, NULL); - } - - if (line != NULL) { - /* Our line ends in the current buffer */ - self->decoded_chars_used = endpos - offset_to_buffer; - if (start > 0 || endpos < PyUnicode_GET_SIZE(line)) { - if (start == 0 && Py_REFCNT(line) == 1) { - if (PyUnicode_Resize(&line, endpos) < 0) - goto error; - } - else { - PyObject *s = PyUnicode_FromUnicode( - PyUnicode_AS_UNICODE(line) + start, endpos - start); - Py_CLEAR(line); - if (s == NULL) - goto error; - line = s; - } - } - } - if (remaining != NULL) { - if (chunks == NULL) { - chunks = PyList_New(0); - if (chunks == NULL) - goto error; - } - if (PyList_Append(chunks, remaining) < 0) - goto error; - Py_CLEAR(remaining); - } - if (chunks != NULL) { - if (line != NULL && PyList_Append(chunks, line) < 0) - goto error; - Py_CLEAR(line); - line = PyUnicode_Join(_PyIO_empty_str, chunks); - if (line == NULL) - goto error; - Py_DECREF(chunks); - } - if (line == NULL) - line = PyUnicode_FromStringAndSize(NULL, 0); - - return line; - - error: - Py_XDECREF(chunks); - Py_XDECREF(remaining); - Py_XDECREF(line); - return NULL; -} - -static PyObject * -TextIOWrapper_readline(PyTextIOWrapperObject *self, PyObject *args) -{ - Py_ssize_t limit = -1; - - CHECK_INITIALIZED(self); - if (!PyArg_ParseTuple(args, "|n:readline", &limit)) { - return NULL; - } - return _TextIOWrapper_readline(self, limit); -} - -/* Seek and Tell */ - -typedef struct { - Py_off_t start_pos; - int dec_flags; - int bytes_to_feed; - int chars_to_skip; - char need_eof; -} CookieStruct; - -/* - To speed up cookie packing/unpacking, we store the fields in a temporary - string and call _PyLong_FromByteArray() or _PyLong_AsByteArray (resp.). - The following macros define at which offsets in the intermediary byte - string the various CookieStruct fields will be stored. - */ - -#define COOKIE_BUF_LEN (sizeof(Py_off_t) + 3 * sizeof(int) + sizeof(char)) - -#if defined(WORDS_BIGENDIAN) - -# define IS_LITTLE_ENDIAN 0 - -/* We want the least significant byte of start_pos to also be the least - significant byte of the cookie, which means that in big-endian mode we - must copy the fields in reverse order. */ - -# define OFF_START_POS (sizeof(char) + 3 * sizeof(int)) -# define OFF_DEC_FLAGS (sizeof(char) + 2 * sizeof(int)) -# define OFF_BYTES_TO_FEED (sizeof(char) + sizeof(int)) -# define OFF_CHARS_TO_SKIP (sizeof(char)) -# define OFF_NEED_EOF 0 - -#else - -# define IS_LITTLE_ENDIAN 1 - -/* Little-endian mode: the least significant byte of start_pos will - naturally end up the least significant byte of the cookie. */ - -# define OFF_START_POS 0 -# define OFF_DEC_FLAGS (sizeof(Py_off_t)) -# define OFF_BYTES_TO_FEED (sizeof(Py_off_t) + sizeof(int)) -# define OFF_CHARS_TO_SKIP (sizeof(Py_off_t) + 2 * sizeof(int)) -# define OFF_NEED_EOF (sizeof(Py_off_t) + 3 * sizeof(int)) - -#endif - -static int -TextIOWrapper_parseCookie(CookieStruct *cookie, PyObject *cookieObj) -{ - unsigned char buffer[COOKIE_BUF_LEN]; - PyLongObject *cookieLong = (PyLongObject *)PyNumber_Long(cookieObj); - if (cookieLong == NULL) - return -1; - - if (_PyLong_AsByteArray(cookieLong, buffer, sizeof(buffer), - IS_LITTLE_ENDIAN, 0) < 0) { - Py_DECREF(cookieLong); - return -1; - } - Py_DECREF(cookieLong); - - memcpy(&cookie->start_pos, buffer + OFF_START_POS, sizeof(cookie->start_pos)); - memcpy(&cookie->dec_flags, buffer + OFF_DEC_FLAGS, sizeof(cookie->dec_flags)); - memcpy(&cookie->bytes_to_feed, buffer + OFF_BYTES_TO_FEED, sizeof(cookie->bytes_to_feed)); - memcpy(&cookie->chars_to_skip, buffer + OFF_CHARS_TO_SKIP, sizeof(cookie->chars_to_skip)); - memcpy(&cookie->need_eof, buffer + OFF_NEED_EOF, sizeof(cookie->need_eof)); - - return 0; -} - -static PyObject * -TextIOWrapper_buildCookie(CookieStruct *cookie) -{ - unsigned char buffer[COOKIE_BUF_LEN]; - - memcpy(buffer + OFF_START_POS, &cookie->start_pos, sizeof(cookie->start_pos)); - memcpy(buffer + OFF_DEC_FLAGS, &cookie->dec_flags, sizeof(cookie->dec_flags)); - memcpy(buffer + OFF_BYTES_TO_FEED, &cookie->bytes_to_feed, sizeof(cookie->bytes_to_feed)); - memcpy(buffer + OFF_CHARS_TO_SKIP, &cookie->chars_to_skip, sizeof(cookie->chars_to_skip)); - memcpy(buffer + OFF_NEED_EOF, &cookie->need_eof, sizeof(cookie->need_eof)); - - return _PyLong_FromByteArray(buffer, sizeof(buffer), IS_LITTLE_ENDIAN, 0); -} -#undef IS_LITTLE_ENDIAN - -static int -_TextIOWrapper_decoder_setstate(PyTextIOWrapperObject *self, - CookieStruct *cookie) -{ - PyObject *res; - /* When seeking to the start of the stream, we call decoder.reset() - rather than decoder.getstate(). - This is for a few decoders such as utf-16 for which the state value - at start is not (b"", 0) but e.g. (b"", 2) (meaning, in the case of - utf-16, that we are expecting a BOM). - */ - if (cookie->start_pos == 0 && cookie->dec_flags == 0) - res = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL); - else - res = PyObject_CallMethod(self->decoder, "setstate", - "((yi))", "", cookie->dec_flags); - if (res == NULL) - return -1; - Py_DECREF(res); - return 0; -} - -static PyObject * -TextIOWrapper_seek(PyTextIOWrapperObject *self, PyObject *args) -{ - PyObject *cookieObj, *posobj; - CookieStruct cookie; - int whence = 0; - static PyObject *zero = NULL; - PyObject *res; - int cmp; - - CHECK_INITIALIZED(self); - - if (zero == NULL) { - zero = PyLong_FromLong(0L); - if (zero == NULL) - return NULL; - } - - if (!PyArg_ParseTuple(args, "O|i:seek", &cookieObj, &whence)) - return NULL; - CHECK_CLOSED(self); - - Py_INCREF(cookieObj); - - if (!self->seekable) { - PyErr_SetString(PyExc_IOError, - "underlying stream is not seekable"); - goto fail; - } - - if (whence == 1) { - /* seek relative to current position */ - cmp = PyObject_RichCompareBool(cookieObj, zero, Py_EQ); - if (cmp < 0) - goto fail; - - if (cmp == 0) { - PyErr_SetString(PyExc_IOError, - "can't do nonzero cur-relative seeks"); - goto fail; - } - - /* Seeking to the current position should attempt to - * sync the underlying buffer with the current position. - */ - Py_DECREF(cookieObj); - cookieObj = PyObject_CallMethod((PyObject *)self, "tell", NULL); - if (cookieObj == NULL) - goto fail; - } - else if (whence == 2) { - /* seek relative to end of file */ - - cmp = PyObject_RichCompareBool(cookieObj, zero, Py_EQ); - if (cmp < 0) - goto fail; - - if (cmp == 0) { - PyErr_SetString(PyExc_IOError, - "can't do nonzero end-relative seeks"); - goto fail; - } - - res = PyObject_CallMethod((PyObject *)self, "flush", NULL); - if (res == NULL) - goto fail; - Py_DECREF(res); - - TextIOWrapper_set_decoded_chars(self, NULL); - Py_CLEAR(self->snapshot); - if (self->decoder) { - res = PyObject_CallMethod(self->decoder, "reset", NULL); - if (res == NULL) - goto fail; - Py_DECREF(res); - } - - res = PyObject_CallMethod(self->buffer, "seek", "ii", 0, 2); - Py_XDECREF(cookieObj); - return res; - } - else if (whence != 0) { - PyErr_Format(PyExc_ValueError, - "invalid whence (%d, should be 0, 1 or 2)", whence); - goto fail; - } - - cmp = PyObject_RichCompareBool(cookieObj, zero, Py_LT); - if (cmp < 0) - goto fail; - - if (cmp == 1) { - PyErr_Format(PyExc_ValueError, - "negative seek position %R", cookieObj); - goto fail; - } - - res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL); - if (res == NULL) - goto fail; - Py_DECREF(res); - - /* The strategy of seek() is to go back to the safe start point - * and replay the effect of read(chars_to_skip) from there. - */ - if (TextIOWrapper_parseCookie(&cookie, cookieObj) < 0) - goto fail; - - /* Seek back to the safe start point. */ - posobj = PyLong_FromOff_t(cookie.start_pos); - if (posobj == NULL) - goto fail; - res = PyObject_CallMethodObjArgs(self->buffer, - _PyIO_str_seek, posobj, NULL); - Py_DECREF(posobj); - if (res == NULL) - goto fail; - Py_DECREF(res); - - TextIOWrapper_set_decoded_chars(self, NULL); - Py_CLEAR(self->snapshot); - - /* Restore the decoder to its state from the safe start point. */ - if (self->decoder) { - if (_TextIOWrapper_decoder_setstate(self, &cookie) < 0) - goto fail; - } - - if (cookie.chars_to_skip) { - /* Just like _read_chunk, feed the decoder and save a snapshot. */ - PyObject *input_chunk = PyObject_CallMethod( - self->buffer, "read", "i", cookie.bytes_to_feed); - PyObject *decoded; - - if (input_chunk == NULL) - goto fail; - - assert (PyBytes_Check(input_chunk)); - - self->snapshot = Py_BuildValue("iN", cookie.dec_flags, input_chunk); - if (self->snapshot == NULL) { - Py_DECREF(input_chunk); - goto fail; - } - - decoded = PyObject_CallMethod(self->decoder, "decode", - "Oi", input_chunk, (int)cookie.need_eof); - - if (decoded == NULL) - goto fail; - - TextIOWrapper_set_decoded_chars(self, decoded); - - /* Skip chars_to_skip of the decoded characters. */ - if (PyUnicode_GetSize(self->decoded_chars) < cookie.chars_to_skip) { - PyErr_SetString(PyExc_IOError, "can't restore logical file position"); - goto fail; - } - self->decoded_chars_used = cookie.chars_to_skip; - } - else { - self->snapshot = Py_BuildValue("iy", cookie.dec_flags, ""); - if (self->snapshot == NULL) - goto fail; - } - - return cookieObj; - fail: - Py_XDECREF(cookieObj); - return NULL; - -} - -static PyObject * -TextIOWrapper_tell(PyTextIOWrapperObject *self, PyObject *args) -{ - PyObject *res; - PyObject *posobj = NULL; - CookieStruct cookie = {0,0,0,0,0}; - PyObject *next_input; - Py_ssize_t chars_to_skip, chars_decoded; - PyObject *saved_state = NULL; - char *input, *input_end; - - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - - if (!self->seekable) { - PyErr_SetString(PyExc_IOError, - "underlying stream is not seekable"); - goto fail; - } - if (!self->telling) { - PyErr_SetString(PyExc_IOError, - "telling position disabled by next() call"); - goto fail; - } - - if (_TextIOWrapper_writeflush(self) < 0) - return NULL; - res = PyObject_CallMethod((PyObject *)self, "flush", NULL); - if (res == NULL) - goto fail; - Py_DECREF(res); - - posobj = PyObject_CallMethod(self->buffer, "tell", NULL); - if (posobj == NULL) - goto fail; - - if (self->decoder == NULL || self->snapshot == NULL) { - assert (self->decoded_chars == NULL || PyUnicode_GetSize(self->decoded_chars) == 0); - return posobj; - } - -#if defined(HAVE_LARGEFILE_SUPPORT) - cookie.start_pos = PyLong_AsLongLong(posobj); -#else - cookie.start_pos = PyLong_AsLong(posobj); -#endif - if (PyErr_Occurred()) - goto fail; - - /* Skip backward to the snapshot point (see _read_chunk). */ - if (!PyArg_Parse(self->snapshot, "(iO)", &cookie.dec_flags, &next_input)) - goto fail; - - assert (PyBytes_Check(next_input)); - - cookie.start_pos -= PyBytes_GET_SIZE(next_input); - - /* How many decoded characters have been used up since the snapshot? */ - if (self->decoded_chars_used == 0) { - /* We haven't moved from the snapshot point. */ - Py_DECREF(posobj); - return TextIOWrapper_buildCookie(&cookie); - } - - chars_to_skip = self->decoded_chars_used; - - /* Starting from the snapshot position, we will walk the decoder - * forward until it gives us enough decoded characters. - */ - saved_state = PyObject_CallMethodObjArgs(self->decoder, - _PyIO_str_getstate, NULL); - if (saved_state == NULL) - goto fail; - - /* Note our initial start point. */ - if (_TextIOWrapper_decoder_setstate(self, &cookie) < 0) - goto fail; - - /* Feed the decoder one byte at a time. As we go, note the - * nearest "safe start point" before the current location - * (a point where the decoder has nothing buffered, so seek() - * can safely start from there and advance to this location). - */ - chars_decoded = 0; - input = PyBytes_AS_STRING(next_input); - input_end = input + PyBytes_GET_SIZE(next_input); - while (input < input_end) { - PyObject *state; - char *dec_buffer; - Py_ssize_t dec_buffer_len; - int dec_flags; - - PyObject *decoded = PyObject_CallMethod( - self->decoder, "decode", "y#", input, 1); - if (decoded == NULL) - goto fail; - assert (PyUnicode_Check(decoded)); - chars_decoded += PyUnicode_GET_SIZE(decoded); - Py_DECREF(decoded); - - cookie.bytes_to_feed += 1; - - state = PyObject_CallMethodObjArgs(self->decoder, - _PyIO_str_getstate, NULL); - if (state == NULL) - goto fail; - if (!PyArg_Parse(state, "(y#i)", &dec_buffer, &dec_buffer_len, &dec_flags)) { - Py_DECREF(state); - goto fail; - } - Py_DECREF(state); - - if (dec_buffer_len == 0 && chars_decoded <= chars_to_skip) { - /* Decoder buffer is empty, so this is a safe start point. */ - cookie.start_pos += cookie.bytes_to_feed; - chars_to_skip -= chars_decoded; - cookie.dec_flags = dec_flags; - cookie.bytes_to_feed = 0; - chars_decoded = 0; - } - if (chars_decoded >= chars_to_skip) - break; - input++; - } - if (input == input_end) { - /* We didn't get enough decoded data; signal EOF to get more. */ - PyObject *decoded = PyObject_CallMethod( - self->decoder, "decode", "yi", "", /* final = */ 1); - if (decoded == NULL) - goto fail; - assert (PyUnicode_Check(decoded)); - chars_decoded += PyUnicode_GET_SIZE(decoded); - Py_DECREF(decoded); - cookie.need_eof = 1; - - if (chars_decoded < chars_to_skip) { - PyErr_SetString(PyExc_IOError, - "can't reconstruct logical file position"); - goto fail; - } - } - - /* finally */ - Py_XDECREF(posobj); - res = PyObject_CallMethod(self->decoder, "setstate", "(O)", saved_state); - Py_DECREF(saved_state); - if (res == NULL) - return NULL; - Py_DECREF(res); - - /* The returned cookie corresponds to the last safe start point. */ - cookie.chars_to_skip = Py_SAFE_DOWNCAST(chars_to_skip, Py_ssize_t, int); - return TextIOWrapper_buildCookie(&cookie); - - fail: - Py_XDECREF(posobj); - if (saved_state) { - PyObject *type, *value, *traceback; - PyErr_Fetch(&type, &value, &traceback); - - res = PyObject_CallMethod(self->decoder, "setstate", "(O)", saved_state); - Py_DECREF(saved_state); - if (res == NULL) - return NULL; - Py_DECREF(res); - - PyErr_Restore(type, value, traceback); - } - return NULL; -} - -static PyObject * -TextIOWrapper_truncate(PyTextIOWrapperObject *self, PyObject *args) -{ - PyObject *pos = Py_None; - PyObject *res; - - CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) { - return NULL; - } - - res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_flush, NULL); - if (res == NULL) - return NULL; - Py_DECREF(res); - - if (pos != Py_None) { - res = PyObject_CallMethodObjArgs((PyObject *) self, - _PyIO_str_seek, pos, NULL); - if (res == NULL) - return NULL; - Py_DECREF(res); - } - - return PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_truncate, NULL); -} - -static PyObject * -TextIOWrapper_repr(PyTextIOWrapperObject *self) -{ - CHECK_INITIALIZED(self); - return PyUnicode_FromFormat("", self->encoding); -} - - -/* Inquiries */ - -static PyObject * -TextIOWrapper_fileno(PyTextIOWrapperObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self); - return PyObject_CallMethod(self->buffer, "fileno", NULL); -} - -static PyObject * -TextIOWrapper_seekable(PyTextIOWrapperObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self); - return PyObject_CallMethod(self->buffer, "seekable", NULL); -} - -static PyObject * -TextIOWrapper_readable(PyTextIOWrapperObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self); - return PyObject_CallMethod(self->buffer, "readable", NULL); -} - -static PyObject * -TextIOWrapper_writable(PyTextIOWrapperObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self); - return PyObject_CallMethod(self->buffer, "writable", NULL); -} - -static PyObject * -TextIOWrapper_isatty(PyTextIOWrapperObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self); - return PyObject_CallMethod(self->buffer, "isatty", NULL); -} - -static PyObject * -TextIOWrapper_flush(PyTextIOWrapperObject *self, PyObject *args) -{ - CHECK_INITIALIZED(self); - CHECK_CLOSED(self); - self->telling = self->seekable; - if (_TextIOWrapper_writeflush(self) < 0) - return NULL; - return PyObject_CallMethod(self->buffer, "flush", NULL); -} - -static PyObject * -TextIOWrapper_close(PyTextIOWrapperObject *self, PyObject *args) -{ - PyObject *res; - CHECK_INITIALIZED(self); - res = PyObject_CallMethod((PyObject *)self, "flush", NULL); - if (res == NULL) { - /* If flush() fails, just give up */ - PyErr_Clear(); - } - else - Py_DECREF(res); - - return PyObject_CallMethod(self->buffer, "close", NULL); -} - -static PyObject * -TextIOWrapper_iternext(PyTextIOWrapperObject *self) -{ - PyObject *line; - - CHECK_INITIALIZED(self); - - self->telling = 0; - if (Py_TYPE(self) == &PyTextIOWrapper_Type) { - /* Skip method call overhead for speed */ - line = _TextIOWrapper_readline(self, -1); - } - else { - line = PyObject_CallMethodObjArgs((PyObject *)self, - _PyIO_str_readline, NULL); - if (line && !PyUnicode_Check(line)) { - PyErr_Format(PyExc_IOError, - "readline() should have returned an str object, " - "not '%.200s'", Py_TYPE(line)->tp_name); - Py_DECREF(line); - return NULL; - } - } - - if (line == NULL) - return NULL; - - if (PyUnicode_GET_SIZE(line) == 0) { - /* Reached EOF or would have blocked */ - Py_DECREF(line); - Py_CLEAR(self->snapshot); - self->telling = self->seekable; - return NULL; - } - - return line; -} - -static PyObject * -TextIOWrapper_name_get(PyTextIOWrapperObject *self, void *context) -{ - CHECK_INITIALIZED(self); - return PyObject_GetAttrString(self->buffer, "name"); -} - -static PyObject * -TextIOWrapper_closed_get(PyTextIOWrapperObject *self, void *context) -{ - CHECK_INITIALIZED(self); - return PyObject_GetAttr(self->buffer, _PyIO_str_closed); -} - -static PyObject * -TextIOWrapper_newlines_get(PyTextIOWrapperObject *self, void *context) -{ - PyObject *res; - CHECK_INITIALIZED(self); - if (self->decoder == NULL) - Py_RETURN_NONE; - res = PyObject_GetAttr(self->decoder, _PyIO_str_newlines); - if (res == NULL) { - PyErr_Clear(); - Py_RETURN_NONE; - } - return res; -} - -static PyObject * -TextIOWrapper_chunk_size_get(PyTextIOWrapperObject *self, void *context) -{ - CHECK_INITIALIZED(self); - return PyLong_FromSsize_t(self->chunk_size); -} - -static int -TextIOWrapper_chunk_size_set(PyTextIOWrapperObject *self, - PyObject *arg, void *context) -{ - Py_ssize_t n; - CHECK_INITIALIZED_INT(self); - n = PyNumber_AsSsize_t(arg, PyExc_TypeError); - if (n == -1 && PyErr_Occurred()) - return -1; - if (n <= 0) { - PyErr_SetString(PyExc_ValueError, - "a strictly positive integer is required"); - return -1; - } - self->chunk_size = n; - return 0; -} - -static PyMethodDef TextIOWrapper_methods[] = { - {"write", (PyCFunction)TextIOWrapper_write, METH_VARARGS}, - {"read", (PyCFunction)TextIOWrapper_read, METH_VARARGS}, - {"readline", (PyCFunction)TextIOWrapper_readline, METH_VARARGS}, - {"flush", (PyCFunction)TextIOWrapper_flush, METH_NOARGS}, - {"close", (PyCFunction)TextIOWrapper_close, METH_NOARGS}, - - {"fileno", (PyCFunction)TextIOWrapper_fileno, METH_NOARGS}, - {"seekable", (PyCFunction)TextIOWrapper_seekable, METH_NOARGS}, - {"readable", (PyCFunction)TextIOWrapper_readable, METH_NOARGS}, - {"writable", (PyCFunction)TextIOWrapper_writable, METH_NOARGS}, - {"isatty", (PyCFunction)TextIOWrapper_isatty, METH_NOARGS}, - - {"seek", (PyCFunction)TextIOWrapper_seek, METH_VARARGS}, - {"tell", (PyCFunction)TextIOWrapper_tell, METH_NOARGS}, - {"truncate", (PyCFunction)TextIOWrapper_truncate, METH_VARARGS}, - {NULL, NULL} -}; - -static PyMemberDef TextIOWrapper_members[] = { - {"encoding", T_OBJECT, offsetof(PyTextIOWrapperObject, encoding), READONLY}, - {"buffer", T_OBJECT, offsetof(PyTextIOWrapperObject, buffer), READONLY}, - {"line_buffering", T_BOOL, offsetof(PyTextIOWrapperObject, line_buffering), READONLY}, - {NULL} -}; - -static PyGetSetDef TextIOWrapper_getset[] = { - {"name", (getter)TextIOWrapper_name_get, NULL, NULL}, - {"closed", (getter)TextIOWrapper_closed_get, NULL, NULL}, -/* {"mode", (getter)TextIOWrapper_mode_get, NULL, NULL}, -*/ - {"newlines", (getter)TextIOWrapper_newlines_get, NULL, NULL}, - {"_CHUNK_SIZE", (getter)TextIOWrapper_chunk_size_get, - (setter)TextIOWrapper_chunk_size_set, NULL}, - {0} -}; - -PyTypeObject PyTextIOWrapper_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.TextIOWrapper", /*tp_name*/ - sizeof(PyTextIOWrapperObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)TextIOWrapper_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tps_etattr*/ - 0, /*tp_compare */ - (reprfunc)TextIOWrapper_repr,/*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - TextIOWrapper_doc, /* tp_doc */ - (traverseproc)TextIOWrapper_traverse, /* tp_traverse */ - (inquiry)TextIOWrapper_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(PyTextIOWrapperObject, weakreflist), /*tp_weaklistoffset*/ - 0, /* tp_iter */ - (iternextfunc)TextIOWrapper_iternext, /* tp_iternext */ - TextIOWrapper_methods, /* tp_methods */ - TextIOWrapper_members, /* tp_members */ - TextIOWrapper_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(PyTextIOWrapperObject, dict), /*tp_dictoffset*/ - (initproc)TextIOWrapper_init, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; Modified: python/branches/py3k-short-float-repr/Modules/arraymodule.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/arraymodule.c (original) +++ python/branches/py3k-short-float-repr/Modules/arraymodule.c Sun Apr 5 01:04:14 2009 @@ -1141,14 +1141,14 @@ > PY_SSIZE_T_MAX / Py_SIZE(array)) { return PyErr_NoMemory(); } - result = Py_BuildValue("O(cy#)O", + result = Py_BuildValue("O(Cy#)O", Py_TYPE(array), array->ob_descr->typecode, array->ob_item, Py_SIZE(array) * array->ob_descr->itemsize, dict); } else { - result = Py_BuildValue("O(c)O", + result = Py_BuildValue("O(C)O", Py_TYPE(array), array->ob_descr->typecode, dict); Modified: python/branches/py3k-short-float-repr/Modules/cjkcodecs/multibytecodec.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/cjkcodecs/multibytecodec.c (original) +++ python/branches/py3k-short-float-repr/Modules/cjkcodecs/multibytecodec.c Sun Apr 5 01:04:14 2009 @@ -506,7 +506,6 @@ outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf); r = codec->encode(state, codec->config, &buf.inbuf, inleft, &buf.outbuf, outleft, flags); - *data = buf.inbuf; if ((r == 0) || (r == MBERR_TOOFEW && !(flags & MBENC_FLUSH))) break; else if (multibytecodec_encerror(codec, state, &buf, errors,r)) @@ -536,6 +535,7 @@ if (_PyBytes_Resize(&buf.outobj, finalsize) == -1) goto errorexit; + *data = buf.inbuf; Py_XDECREF(buf.excobj); return buf.outobj; Deleted: python/branches/py3k-short-float-repr/Modules/io.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/io.c Sun Apr 5 01:04:14 2009 +++ (empty file) @@ -1,760 +0,0 @@ -/* - An implementation of the new I/O lib as defined by PEP 3116 - "New I/O" - - Classes defined here: UnsupportedOperation, BlockingIOError. - Functions defined here: open(). - - Mostly written by Amaury Forgeot d'Arc -*/ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#include "structmember.h" -#include "_iomodule.h" - -#ifdef HAVE_SYS_TYPES_H -#include -#endif /* HAVE_SYS_TYPES_H */ - -#ifdef HAVE_SYS_STAT_H -#include -#endif /* HAVE_SYS_STAT_H */ - - -/* Various interned strings */ - -PyObject *_PyIO_str_close; -PyObject *_PyIO_str_closed; -PyObject *_PyIO_str_decode; -PyObject *_PyIO_str_encode; -PyObject *_PyIO_str_fileno; -PyObject *_PyIO_str_flush; -PyObject *_PyIO_str_getstate; -PyObject *_PyIO_str_isatty; -PyObject *_PyIO_str_newlines; -PyObject *_PyIO_str_nl; -PyObject *_PyIO_str_read; -PyObject *_PyIO_str_read1; -PyObject *_PyIO_str_readable; -PyObject *_PyIO_str_readinto; -PyObject *_PyIO_str_readline; -PyObject *_PyIO_str_reset; -PyObject *_PyIO_str_seek; -PyObject *_PyIO_str_seekable; -PyObject *_PyIO_str_tell; -PyObject *_PyIO_str_truncate; -PyObject *_PyIO_str_writable; -PyObject *_PyIO_str_write; - -PyObject *_PyIO_empty_str; -PyObject *_PyIO_empty_bytes; - - -PyDoc_STRVAR(module_doc, -"The io module provides the Python interfaces to stream handling. The\n" -"builtin open function is defined in this module.\n" -"\n" -"At the top of the I/O hierarchy is the abstract base class IOBase. It\n" -"defines the basic interface to a stream. Note, however, that there is no\n" -"seperation between reading and writing to streams; implementations are\n" -"allowed to throw an IOError if they do not support a given operation.\n" -"\n" -"Extending IOBase is RawIOBase which deals simply with the reading and\n" -"writing of raw bytes to a stream. FileIO subc lasses RawIOBase to provide\n" -"an interface to OS files.\n" -"\n" -"BufferedIOBase deals with buffering on a raw byte stream (RawIOBase). Its\n" -"subclasses, BufferedWriter, BufferedReader, and BufferedRWPair buffer\n" -"streams that are readable, writable, and both respectively.\n" -"BufferedRandom provides a buffered interface to random access\n" -"streams. BytesIO is a simple stream of in-memory bytes.\n" -"\n" -"Another IOBase subclass, TextIOBase, deals with the encoding and decoding\n" -"of streams into text. TextIOWrapper, which extends it, is a buffered text\n" -"interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO\n" -"is a in-memory stream for text.\n" -"\n" -"Argument names are not part of the specification, and only the arguments\n" -"of open() are intended to be used as keyword arguments.\n" -"\n" -"data:\n" -"\n" -"DEFAULT_BUFFER_SIZE\n" -"\n" -" An int containing the default buffer size used by the module's buffered\n" -" I/O classes. open() uses the file's blksize (as obtained by os.stat) if\n" -" possible.\n" - ); - - -/* - * BlockingIOError extends IOError - */ - -static int -BlockingIOError_init(PyBlockingIOErrorObject *self, PyObject *args, - PyObject *kwds) -{ - PyObject *myerrno = NULL, *strerror = NULL; - PyObject *baseargs = NULL; - Py_ssize_t written = 0; - - assert(PyTuple_Check(args)); - - self->written = 0; - if (!PyArg_ParseTuple(args, "OO|n:BlockingIOError", - &myerrno, &strerror, &written)) - return -1; - - baseargs = PyTuple_Pack(2, myerrno, strerror); - if (baseargs == NULL) - return -1; - /* This will take care of initializing of myerrno and strerror members */ - if (((PyTypeObject *)PyExc_IOError)->tp_init( - (PyObject *)self, baseargs, kwds) == -1) { - Py_DECREF(baseargs); - return -1; - } - Py_DECREF(baseargs); - - self->written = written; - return 0; -} - -static PyMemberDef BlockingIOError_members[] = { - {"characters_written", T_PYSSIZET, offsetof(PyBlockingIOErrorObject, written), 0}, - {NULL} /* Sentinel */ -}; - -static PyTypeObject _PyExc_BlockingIOError = { - PyVarObject_HEAD_INIT(NULL, 0) - "BlockingIOError", /*tp_name*/ - sizeof(PyBlockingIOErrorObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - 0, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - PyDoc_STR("Exception raised when I/O would block " - "on a non-blocking I/O stream"), /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - BlockingIOError_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)BlockingIOError_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ -}; -PyObject *PyExc_BlockingIOError = (PyObject *)&_PyExc_BlockingIOError; - - -/* - * The main open() function - */ -PyDoc_STRVAR(open_doc, -"Open file and return a stream. Raise IOError upon failure.\n" -"\n" -"file is either a text or byte string giving the name (and the path\n" -"if the file isn't in the current working directory) of the file to\n" -"be opened or an integer file descriptor of the file to be\n" -"wrapped. (If a file descriptor is given, it is closed when the\n" -"returned I/O object is closed, unless closefd is set to False.)\n" -"\n" -"mode is an optional string that specifies the mode in which the file\n" -"is opened. It defaults to 'r' which means open for reading in text\n" -"mode. Other common values are 'w' for writing (truncating the file if\n" -"it already exists), and 'a' for appending (which on some Unix systems,\n" -"means that all writes append to the end of the file regardless of the\n" -"current seek position). In text mode, if encoding is not specified the\n" -"encoding used is platform dependent. (For reading and writing raw\n" -"bytes use binary mode and leave encoding unspecified.) The available\n" -"modes are:\n" -"\n" -"========= ===============================================================\n" -"Character Meaning\n" -"--------- ---------------------------------------------------------------\n" -"'r' open for reading (default)\n" -"'w' open for writing, truncating the file first\n" -"'a' open for writing, appending to the end of the file if it exists\n" -"'b' binary mode\n" -"'t' text mode (default)\n" -"'+' open a disk file for updating (reading and writing)\n" -"'U' universal newline mode (for backwards compatibility; unneeded\n" -" for new code)\n" -"========= ===============================================================\n" -"\n" -"The default mode is 'rt' (open for reading text). For binary random\n" -"access, the mode 'w+b' opens and truncates the file to 0 bytes, while\n" -"'r+b' opens the file without truncation.\n" -"\n" -"Python distinguishes between files opened in binary and text modes,\n" -"even when the underlying operating system doesn't. Files opened in\n" -"binary mode (appending 'b' to the mode argument) return contents as\n" -"bytes objects without any decoding. In text mode (the default, or when\n" -"'t' is appended to the mode argument), the contents of the file are\n" -"returned as strings, the bytes having been first decoded using a\n" -"platform-dependent encoding or using the specified encoding if given.\n" -"\n" -"buffering is an optional integer used to set the buffering policy. By\n" -"default full buffering is on. Pass 0 to switch buffering off (only\n" -"allowed in binary mode), 1 to set line buffering, and an integer > 1\n" -"for full buffering.\n" -"\n" -"encoding is the name of the encoding used to decode or encode the\n" -"file. This should only be used in text mode. The default encoding is\n" -"platform dependent, but any encoding supported by Python can be\n" -"passed. See the codecs module for the list of supported encodings.\n" -"\n" -"errors is an optional string that specifies how encoding errors are to\n" -"be handled---this argument should not be used in binary mode. Pass\n" -"'strict' to raise a ValueError exception if there is an encoding error\n" -"(the default of None has the same effect), or pass 'ignore' to ignore\n" -"errors. (Note that ignoring encoding errors can lead to data loss.)\n" -"See the documentation for codecs.register for a list of the permitted\n" -"encoding error strings.\n" -"\n" -"newline controls how universal newlines works (it only applies to text\n" -"mode). It can be None, '', '\\n', '\\r', and '\\r\\n'. It works as\n" -"follows:\n" -"\n" -"* On input, if newline is None, universal newlines mode is\n" -" enabled. Lines in the input can end in '\\n', '\\r', or '\\r\\n', and\n" -" these are translated into '\\n' before being returned to the\n" -" caller. If it is '', universal newline mode is enabled, but line\n" -" endings are returned to the caller untranslated. If it has any of\n" -" the other legal values, input lines are only terminated by the given\n" -" string, and the line ending is returned to the caller untranslated.\n" -"\n" -"* On output, if newline is None, any '\\n' characters written are\n" -" translated to the system default line separator, os.linesep. If\n" -" newline is '', no translation takes place. If newline is any of the\n" -" other legal values, any '\\n' characters written are translated to\n" -" the given string.\n" -"\n" -"If closefd is False, the underlying file descriptor will be kept open\n" -"when the file is closed. This does not work when a file name is given\n" -"and must be True in that case.\n" -"\n" -"open() returns a file object whose type depends on the mode, and\n" -"through which the standard file operations such as reading and writing\n" -"are performed. When open() is used to open a file in a text mode ('w',\n" -"'r', 'wt', 'rt', etc.), it returns a TextIOWrapper. When used to open\n" -"a file in a binary mode, the returned class varies: in read binary\n" -"mode, it returns a BufferedReader; in write binary and append binary\n" -"modes, it returns a BufferedWriter, and in read/write mode, it returns\n" -"a BufferedRandom.\n" -"\n" -"It is also possible to use a string or bytearray as a file for both\n" -"reading and writing. For strings StringIO can be used like a file\n" -"opened in a text mode, and for bytes a BytesIO can be used like a file\n" -"opened in a binary mode.\n" - ); - -static PyObject * -io_open(PyObject *self, PyObject *args, PyObject *kwds) -{ - char *kwlist[] = {"file", "mode", "buffering", - "encoding", "errors", "newline", - "closefd", NULL}; - PyObject *file; - char *mode = "r"; - int buffering = -1, closefd = 1; - char *encoding = NULL, *errors = NULL, *newline = NULL; - unsigned i; - - int reading = 0, writing = 0, appending = 0, updating = 0; - int text = 0, binary = 0, universal = 0; - - char rawmode[5], *m; - int line_buffering, isatty; - - PyObject *raw, *modeobj = NULL, *buffer = NULL, *wrapper = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|sizzzi:open", kwlist, - &file, &mode, &buffering, - &encoding, &errors, &newline, - &closefd)) { - return NULL; - } - - if (!PyUnicode_Check(file) && - !PyBytes_Check(file) && - !PyNumber_Check(file)) { - PyErr_Format(PyExc_TypeError, "invalid file: %R", file); - return NULL; - } - - /* Decode mode */ - for (i = 0; i < strlen(mode); i++) { - char c = mode[i]; - - switch (c) { - case 'r': - reading = 1; - break; - case 'w': - writing = 1; - break; - case 'a': - appending = 1; - break; - case '+': - updating = 1; - break; - case 't': - text = 1; - break; - case 'b': - binary = 1; - break; - case 'U': - universal = 1; - reading = 1; - break; - default: - goto invalid_mode; - } - - /* c must not be duplicated */ - if (strchr(mode+i+1, c)) { - invalid_mode: - PyErr_Format(PyExc_ValueError, "invalid mode: '%s'", mode); - return NULL; - } - - } - - m = rawmode; - if (reading) *(m++) = 'r'; - if (writing) *(m++) = 'w'; - if (appending) *(m++) = 'a'; - if (updating) *(m++) = '+'; - *m = '\0'; - - /* Parameters validation */ - if (universal) { - if (writing || appending) { - PyErr_SetString(PyExc_ValueError, - "can't use U and writing mode at once"); - return NULL; - } - reading = 1; - } - - if (text && binary) { - PyErr_SetString(PyExc_ValueError, - "can't have text and binary mode at once"); - return NULL; - } - - if (reading + writing + appending > 1) { - PyErr_SetString(PyExc_ValueError, - "must have exactly one of read/write/append mode"); - return NULL; - } - - if (binary && encoding != NULL) { - PyErr_SetString(PyExc_ValueError, - "binary mode doesn't take an encoding argument"); - return NULL; - } - - if (binary && errors != NULL) { - PyErr_SetString(PyExc_ValueError, - "binary mode doesn't take an errors argument"); - return NULL; - } - - if (binary && newline != NULL) { - PyErr_SetString(PyExc_ValueError, - "binary mode doesn't take a newline argument"); - return NULL; - } - - /* Create the Raw file stream */ - raw = PyObject_CallFunction((PyObject *)&PyFileIO_Type, - "Osi", file, rawmode, closefd); - if (raw == NULL) - return NULL; - - modeobj = PyUnicode_FromString(mode); - if (modeobj == NULL) - goto error; - - /* buffering */ - { - PyObject *res = PyObject_CallMethod(raw, "isatty", NULL); - if (res == NULL) - goto error; - isatty = PyLong_AsLong(res); - Py_DECREF(res); - if (isatty == -1 && PyErr_Occurred()) - goto error; - } - - if (buffering == 1 || (buffering < 0 && isatty)) { - buffering = -1; - line_buffering = 1; - } - else - line_buffering = 0; - - if (buffering < 0) { - buffering = DEFAULT_BUFFER_SIZE; -#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE - { - struct stat st; - long fileno; - PyObject *res = PyObject_CallMethod(raw, "fileno", NULL); - if (res == NULL) - goto error; - - fileno = PyLong_AsLong(res); - Py_DECREF(res); - if (fileno == -1 && PyErr_Occurred()) - goto error; - - if (fstat(fileno, &st) >= 0) - buffering = st.st_blksize; - } -#endif - } - if (buffering < 0) { - PyErr_SetString(PyExc_ValueError, - "invalid buffering size"); - goto error; - } - - /* if not buffering, returns the raw file object */ - if (buffering == 0) { - if (!binary) { - PyErr_SetString(PyExc_ValueError, - "can't have unbuffered text I/O"); - goto error; - } - - Py_DECREF(modeobj); - return raw; - } - - /* wraps into a buffered file */ - { - PyObject *Buffered_class; - - if (updating) - Buffered_class = (PyObject *)&PyBufferedRandom_Type; - else if (writing || appending) - Buffered_class = (PyObject *)&PyBufferedWriter_Type; - else if (reading) - Buffered_class = (PyObject *)&PyBufferedReader_Type; - else { - PyErr_Format(PyExc_ValueError, - "unknown mode: '%s'", mode); - goto error; - } - - buffer = PyObject_CallFunction(Buffered_class, "Oi", raw, buffering); - } - Py_CLEAR(raw); - if (buffer == NULL) - goto error; - - - /* if binary, returns the buffered file */ - if (binary) { - Py_DECREF(modeobj); - return buffer; - } - - /* wraps into a TextIOWrapper */ - wrapper = PyObject_CallFunction((PyObject *)&PyTextIOWrapper_Type, - "Osssi", - buffer, - encoding, errors, newline, - line_buffering); - Py_CLEAR(buffer); - if (wrapper == NULL) - goto error; - - if (PyObject_SetAttrString(wrapper, "mode", modeobj) < 0) - goto error; - Py_DECREF(modeobj); - return wrapper; - - error: - Py_XDECREF(raw); - Py_XDECREF(modeobj); - Py_XDECREF(buffer); - Py_XDECREF(wrapper); - return NULL; -} - -/* - * Private helpers for the io module. - */ - -Py_off_t -PyNumber_AsOff_t(PyObject *item, PyObject *err) -{ - Py_off_t result; - PyObject *runerr; - PyObject *value = PyNumber_Index(item); - if (value == NULL) - return -1; - - /* We're done if PyLong_AsSsize_t() returns without error. */ - result = PyLong_AsOff_t(value); - if (result != -1 || !(runerr = PyErr_Occurred())) - goto finish; - - /* Error handling code -- only manage OverflowError differently */ - if (!PyErr_GivenExceptionMatches(runerr, PyExc_OverflowError)) - goto finish; - - PyErr_Clear(); - /* If no error-handling desired then the default clipping - is sufficient. - */ - if (!err) { - assert(PyLong_Check(value)); - /* Whether or not it is less than or equal to - zero is determined by the sign of ob_size - */ - if (_PyLong_Sign(value) < 0) - result = PY_OFF_T_MIN; - else - result = PY_OFF_T_MAX; - } - else { - /* Otherwise replace the error with caller's error object. */ - PyErr_Format(err, - "cannot fit '%.200s' into an offset-sized integer", - item->ob_type->tp_name); - } - - finish: - Py_DECREF(value); - return result; -} - -static int -iomodule_traverse(PyObject *mod, visitproc visit, void *arg) { - _PyIO_State *state = IO_MOD_STATE(mod); - if (!state->initialized) - return 0; - Py_VISIT(state->os_module); - if (state->locale_module != NULL) { - Py_VISIT(state->locale_module); - } - Py_VISIT(state->unsupported_operation); - return 0; -} - -static int -iomodule_clear(PyObject *mod) { - _PyIO_State *state = IO_MOD_STATE(mod); - if (!state->initialized) - return 0; - Py_CLEAR(state->os_module); - if (state->locale_module != NULL) - Py_CLEAR(state->locale_module); - Py_CLEAR(state->unsupported_operation); - return 0; -} - -static void -iomodule_free(PyObject *mod) { - iomodule_clear(mod); -} - -/* - * Module definition - */ - -static PyMethodDef module_methods[] = { - {"open", (PyCFunction)io_open, METH_VARARGS|METH_KEYWORDS, open_doc}, - {NULL, NULL} -}; - -struct PyModuleDef _PyIO_Module = { - PyModuleDef_HEAD_INIT, - "io", - module_doc, - sizeof(_PyIO_State), - module_methods, - NULL, - iomodule_traverse, - iomodule_clear, - (freefunc)iomodule_free, -}; - -PyMODINIT_FUNC -PyInit__io(void) -{ - PyObject *m = PyModule_Create(&_PyIO_Module); - _PyIO_State *state = NULL; - if (m == NULL) - return NULL; - state = IO_MOD_STATE(m); - state->initialized = 0; - - /* put os in the module state */ - state->os_module = PyImport_ImportModule("os"); - if (state->os_module == NULL) - goto fail; - -#define ADD_TYPE(type, name) \ - if (PyType_Ready(type) < 0) \ - goto fail; \ - Py_INCREF(type); \ - if (PyModule_AddObject(m, name, (PyObject *)type) < 0) { \ - Py_DECREF(type); \ - goto fail; \ - } - - /* DEFAULT_BUFFER_SIZE */ - if (PyModule_AddIntMacro(m, DEFAULT_BUFFER_SIZE) < 0) - goto fail; - - /* UnsupportedOperation inherits from ValueError and IOError */ - state->unsupported_operation = PyObject_CallFunction( - (PyObject *)&PyType_Type, "s(OO){}", - "UnsupportedOperation", PyExc_ValueError, PyExc_IOError); - if (state->unsupported_operation == NULL) - goto fail; - Py_INCREF(state->unsupported_operation); - if (PyModule_AddObject(m, "UnsupportedOperation", - state->unsupported_operation) < 0) - goto fail; - - /* BlockingIOError */ - _PyExc_BlockingIOError.tp_base = (PyTypeObject *) PyExc_IOError; - ADD_TYPE(&_PyExc_BlockingIOError, "BlockingIOError"); - - /* Concrete base types of the IO ABCs. - (the ABCs themselves are declared through inheritance in io.py) - */ - ADD_TYPE(&PyIOBase_Type, "_IOBase"); - ADD_TYPE(&PyRawIOBase_Type, "_RawIOBase"); - ADD_TYPE(&PyBufferedIOBase_Type, "_BufferedIOBase"); - ADD_TYPE(&PyTextIOBase_Type, "_TextIOBase"); - - /* Implementation of concrete IO objects. */ - /* FileIO */ - PyFileIO_Type.tp_base = &PyRawIOBase_Type; - ADD_TYPE(&PyFileIO_Type, "FileIO"); - - /* BytesIO */ - PyBytesIO_Type.tp_base = &PyBufferedIOBase_Type; - ADD_TYPE(&PyBytesIO_Type, "BytesIO"); - - /* StringIO */ - PyStringIO_Type.tp_base = &PyTextIOBase_Type; - ADD_TYPE(&PyStringIO_Type, "StringIO"); - - /* BufferedReader */ - PyBufferedReader_Type.tp_base = &PyBufferedIOBase_Type; - ADD_TYPE(&PyBufferedReader_Type, "BufferedReader"); - - /* BufferedWriter */ - PyBufferedWriter_Type.tp_base = &PyBufferedIOBase_Type; - ADD_TYPE(&PyBufferedWriter_Type, "BufferedWriter"); - - /* BufferedRWPair */ - PyBufferedRWPair_Type.tp_base = &PyBufferedIOBase_Type; - ADD_TYPE(&PyBufferedRWPair_Type, "BufferedRWPair"); - - /* BufferedRandom */ - PyBufferedRandom_Type.tp_base = &PyBufferedIOBase_Type; - ADD_TYPE(&PyBufferedRandom_Type, "BufferedRandom"); - - /* TextIOWrapper */ - PyTextIOWrapper_Type.tp_base = &PyTextIOBase_Type; - ADD_TYPE(&PyTextIOWrapper_Type, "TextIOWrapper"); - - /* IncrementalNewlineDecoder */ - ADD_TYPE(&PyIncrementalNewlineDecoder_Type, "IncrementalNewlineDecoder"); - - /* Interned strings */ - if (!(_PyIO_str_close = PyUnicode_InternFromString("close"))) - goto fail; - if (!(_PyIO_str_closed = PyUnicode_InternFromString("closed"))) - goto fail; - if (!(_PyIO_str_decode = PyUnicode_InternFromString("decode"))) - goto fail; - if (!(_PyIO_str_encode = PyUnicode_InternFromString("encode"))) - goto fail; - if (!(_PyIO_str_fileno = PyUnicode_InternFromString("fileno"))) - goto fail; - if (!(_PyIO_str_flush = PyUnicode_InternFromString("flush"))) - goto fail; - if (!(_PyIO_str_getstate = PyUnicode_InternFromString("getstate"))) - goto fail; - if (!(_PyIO_str_isatty = PyUnicode_InternFromString("isatty"))) - goto fail; - if (!(_PyIO_str_newlines = PyUnicode_InternFromString("newlines"))) - goto fail; - if (!(_PyIO_str_nl = PyUnicode_InternFromString("\n"))) - goto fail; - if (!(_PyIO_str_read = PyUnicode_InternFromString("read"))) - goto fail; - if (!(_PyIO_str_read1 = PyUnicode_InternFromString("read1"))) - goto fail; - if (!(_PyIO_str_readable = PyUnicode_InternFromString("readable"))) - goto fail; - if (!(_PyIO_str_readinto = PyUnicode_InternFromString("readinto"))) - goto fail; - if (!(_PyIO_str_readline = PyUnicode_InternFromString("readline"))) - goto fail; - if (!(_PyIO_str_reset = PyUnicode_InternFromString("reset"))) - goto fail; - if (!(_PyIO_str_seek = PyUnicode_InternFromString("seek"))) - goto fail; - if (!(_PyIO_str_seekable = PyUnicode_InternFromString("seekable"))) - goto fail; - if (!(_PyIO_str_tell = PyUnicode_InternFromString("tell"))) - goto fail; - if (!(_PyIO_str_truncate = PyUnicode_InternFromString("truncate"))) - goto fail; - if (!(_PyIO_str_write = PyUnicode_InternFromString("write"))) - goto fail; - if (!(_PyIO_str_writable = PyUnicode_InternFromString("writable"))) - goto fail; - - if (!(_PyIO_empty_str = PyUnicode_FromStringAndSize(NULL, 0))) - goto fail; - if (!(_PyIO_empty_bytes = PyBytes_FromStringAndSize(NULL, 0))) - goto fail; - - state->initialized = 1; - - return m; - - fail: - Py_XDECREF(state->os_module); - Py_XDECREF(state->unsupported_operation); - Py_DECREF(m); - return NULL; -} Modified: python/branches/py3k-short-float-repr/Modules/mmapmodule.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/mmapmodule.c (original) +++ python/branches/py3k-short-float-repr/Modules/mmapmodule.c Sun Apr 5 01:04:14 2009 @@ -204,7 +204,7 @@ if (self->pos < self->size) { char value = self->data[self->pos]; self->pos += 1; - return Py_BuildValue("c", value); + return Py_BuildValue("b", value); } else { PyErr_SetString(PyExc_ValueError, "read byte out of range"); return NULL; @@ -264,7 +264,7 @@ Py_ssize_t len; CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, reverse ? "s#|nn:rfind" : "s#|nn:find", + if (!PyArg_ParseTuple(args, reverse ? "y#|nn:rfind" : "y#|nn:find", &needle, &len, &start, &end)) { return NULL; } else { @@ -348,7 +348,7 @@ char *data; CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "s#:write", &data, &length)) + if (!PyArg_ParseTuple(args, "y#:write", &data, &length)) return(NULL); if (!is_writable(self)) @@ -371,7 +371,7 @@ char value; CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "c:write_byte", &value)) + if (!PyArg_ParseTuple(args, "b:write_byte", &value)) return(NULL); if (!is_writable(self)) @@ -520,7 +520,11 @@ #ifdef MREMAP_MAYMOVE newmap = mremap(self->data, self->size, new_size, MREMAP_MAYMOVE); #else - newmap = mremap(self->data, self->size, new_size, 0); + #if defined(__NetBSD__) + newmap = mremap(self->data, self->size, self->data, new_size, 0); + #else + newmap = mremap(self->data, self->size, new_size, 0); + #endif /* __NetBSD__ */ #endif if (newmap == (void *)-1) { @@ -623,10 +627,8 @@ return NULL; } else { /* bounds check the values */ - if (/* end of source after end of data?? */ - ((src+count) > self->size) - /* dest will fit? */ - || (dest+count > self->size)) { + unsigned long pos = src > dest ? src : dest; + if (self->size < pos || count > self->size - pos) { PyErr_SetString(PyExc_ValueError, "source or destination out of range"); return NULL; Modified: python/branches/py3k-short-float-repr/Modules/socketmodule.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/socketmodule.c (original) +++ python/branches/py3k-short-float-repr/Modules/socketmodule.c Sun Apr 5 01:04:14 2009 @@ -382,7 +382,7 @@ #define SOCKETCLOSE close #endif -#if defined(HAVE_BLUETOOTH_H) || defined(HAVE_BLUETOOTH_BLUETOOTH_H) +#if defined(HAVE_BLUETOOTH_H) || defined(HAVE_BLUETOOTH_BLUETOOTH_H) && !defined(__NetBSD__) #define USE_BLUETOOTH 1 #if defined(__FreeBSD__) #define BTPROTO_L2CAP BLUETOOTH_PROTO_L2CAP Modified: python/branches/py3k-short-float-repr/Objects/bytearrayobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/bytearrayobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/bytearrayobject.c Sun Apr 5 01:04:14 2009 @@ -411,18 +411,18 @@ } else { char *source_buf = PyByteArray_AS_STRING(self); - char *result_buf = (char *)PyMem_Malloc(slicelength); + char *result_buf; PyObject *result; - if (result_buf == NULL) - return PyErr_NoMemory(); + result = PyByteArray_FromStringAndSize(NULL, slicelength); + if (result == NULL) + return NULL; + result_buf = PyByteArray_AS_STRING(result); for (cur = start, i = 0; i < slicelength; cur += step, i++) { result_buf[i] = source_buf[cur]; } - result = PyByteArray_FromStringAndSize(result_buf, slicelength); - PyMem_Free(result_buf); return result; } } Modified: python/branches/py3k-short-float-repr/Objects/bytesobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/bytesobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/bytesobject.c Sun Apr 5 01:04:14 2009 @@ -583,6 +583,7 @@ #include "stringlib/transmogrify.h" #define _Py_InsertThousandsGrouping _PyBytes_InsertThousandsGrouping +#define _Py_InsertThousandsGroupingLocale _PyBytes_InsertThousandsGroupingLocale #include "stringlib/localeutil.h" PyObject * @@ -951,19 +952,17 @@ slicelength); } else { - source_buf = PyBytes_AsString((PyObject*)self); - result_buf = (char *)PyMem_Malloc(slicelength); - if (result_buf == NULL) - return PyErr_NoMemory(); + source_buf = PyBytes_AS_STRING(self); + result = PyBytes_FromStringAndSize(NULL, slicelength); + if (result == NULL) + return NULL; + result_buf = PyBytes_AS_STRING(result); for (cur = start, i = 0; i < slicelength; cur += step, i++) { result_buf[i] = source_buf[cur]; } - result = PyBytes_FromStringAndSize(result_buf, - slicelength); - PyMem_Free(result_buf); return result; } } Modified: python/branches/py3k-short-float-repr/Objects/exceptions.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/exceptions.c (original) +++ python/branches/py3k-short-float-repr/Objects/exceptions.c Sun Apr 5 01:04:14 2009 @@ -250,11 +250,67 @@ return 0; } +static PyObject * +BaseException_get_context(PyObject *self) { + PyObject *res = PyException_GetContext(self); + if (res) return res; /* new reference already returned above */ + Py_RETURN_NONE; +} + +static int +BaseException_set_context(PyObject *self, PyObject *arg) { + if (arg == NULL) { + PyErr_SetString(PyExc_TypeError, "__context__ may not be deleted"); + return -1; + } else if (arg == Py_None) { + arg = NULL; + } else if (!PyExceptionInstance_Check(arg)) { + PyErr_SetString(PyExc_TypeError, "exception context must be None " + "or derive from BaseException"); + return -1; + } else { + /* PyException_SetContext steals this reference */ + Py_INCREF(arg); + } + PyException_SetContext(self, arg); + return 0; +} + +static PyObject * +BaseException_get_cause(PyObject *self) { + PyObject *res = PyException_GetCause(self); + if (res) return res; /* new reference already returned above */ + Py_RETURN_NONE; +} + +static int +BaseException_set_cause(PyObject *self, PyObject *arg) { + if (arg == NULL) { + PyErr_SetString(PyExc_TypeError, "__cause__ may not be deleted"); + return -1; + } else if (arg == Py_None) { + arg = NULL; + } else if (!PyExceptionInstance_Check(arg)) { + PyErr_SetString(PyExc_TypeError, "exception cause must be None " + "or derive from BaseException"); + return -1; + } else { + /* PyException_SetCause steals this reference */ + Py_INCREF(arg); + } + PyException_SetCause(self, arg); + return 0; +} + static PyGetSetDef BaseException_getset[] = { {"__dict__", (getter)BaseException_get_dict, (setter)BaseException_set_dict}, {"args", (getter)BaseException_get_args, (setter)BaseException_set_args}, {"__traceback__", (getter)BaseException_get_tb, (setter)BaseException_set_tb}, + {"__context__", (getter)BaseException_get_context, + (setter)BaseException_set_context, PyDoc_STR("exception context")}, + {"__cause__", (getter)BaseException_get_cause, + (setter)BaseException_set_cause, PyDoc_STR("exception cause")}, {NULL}, }; @@ -303,14 +359,6 @@ } -static PyMemberDef BaseException_members[] = { - {"__context__", T_OBJECT, offsetof(PyBaseExceptionObject, context), 0, - PyDoc_STR("exception context")}, - {"__cause__", T_OBJECT, offsetof(PyBaseExceptionObject, cause), 0, - PyDoc_STR("exception cause")}, - {NULL} /* Sentinel */ -}; - static PyTypeObject _PyExc_BaseException = { PyVarObject_HEAD_INIT(NULL, 0) "BaseException", /*tp_name*/ @@ -341,7 +389,7 @@ 0, /* tp_iter */ 0, /* tp_iternext */ BaseException_methods, /* tp_methods */ - BaseException_members, /* tp_members */ + 0, /* tp_members */ BaseException_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ Modified: python/branches/py3k-short-float-repr/Objects/longobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/longobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/longobject.c Sun Apr 5 01:04:14 2009 @@ -4092,8 +4092,10 @@ int_info = PyStructSequence_New(&Int_InfoType); if (int_info == NULL) return NULL; - PyStructSequence_SET_ITEM(int_info, field++, PyLong_FromLong(PyLong_SHIFT)); - PyStructSequence_SET_ITEM(int_info, field++, PyLong_FromLong(sizeof(digit))); + PyStructSequence_SET_ITEM(int_info, field++, + PyLong_FromLong(PyLong_SHIFT)); + PyStructSequence_SET_ITEM(int_info, field++, + PyLong_FromLong(sizeof(digit))); if (PyErr_Occurred()) { Py_CLEAR(int_info); return NULL; Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h (original) +++ python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Sun Apr 5 01:04:14 2009 @@ -120,6 +120,7 @@ int alternate; STRINGLIB_CHAR sign; Py_ssize_t width; + int thousands_separators; Py_ssize_t precision; STRINGLIB_CHAR type; } InternalFormatSpec; @@ -132,7 +133,7 @@ */ static int parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec, - Py_ssize_t format_spec_len, + Py_ssize_t format_spec_len, InternalFormatSpec *format, char default_type) { @@ -149,6 +150,7 @@ format->alternate = 0; format->sign = '\0'; format->width = -1; + format->thousands_separators = 0; format->precision = -1; format->type = default_type; @@ -178,8 +180,8 @@ /* If the next character is #, we're in alternate mode. This only applies to integers. */ if (end-ptr >= 1 && ptr[0] == '#') { - format->alternate = 1; - ++ptr; + format->alternate = 1; + ++ptr; } /* The special case for 0-padding (backwards compat) */ @@ -201,6 +203,12 @@ format->width = -1; } + /* Comma signifies add thousands separators */ + if (end-ptr && ptr[0] == ',') { + format->thousands_separators = 1; + ++ptr; + } + /* Parse field precision */ if (end-ptr && ptr[0] == '.') { ++ptr; @@ -230,6 +238,11 @@ ++ptr; } + if (format->type == 'n' && format->thousands_separators) { + PyErr_Format(PyExc_ValueError, "Cannot specify ',' with 'n'."); + return 0; + } + return 1; } @@ -259,8 +272,8 @@ and more efficient enough to justify a little obfuscation? */ static void calc_number_widths(NumberFieldWidths *spec, STRINGLIB_CHAR actual_sign, - Py_ssize_t n_prefix, Py_ssize_t n_digits, - const InternalFormatSpec *format) + Py_ssize_t n_prefix, Py_ssize_t n_digits, + const InternalFormatSpec *format) { spec->n_lpadding = 0; spec->n_prefix = 0; @@ -327,7 +340,7 @@ else { /* see if any padding is needed */ if (spec->n_lsign + n_digits + spec->n_rsign + - spec->n_prefix >= format->width) { + spec->n_prefix >= format->width) { /* no padding needed, we're already bigger than the requested width */ } @@ -335,8 +348,8 @@ /* determine which of left, space, or right padding is needed */ Py_ssize_t padding = format->width - - (spec->n_lsign + spec->n_prefix + - n_digits + spec->n_rsign); + (spec->n_lsign + spec->n_prefix + + n_digits + spec->n_rsign); if (format->align == '<') spec->n_rpadding = padding; else if (format->align == '>') @@ -352,7 +365,7 @@ } } spec->n_total = spec->n_lpadding + spec->n_lsign + spec->n_prefix + - spec->n_spadding + n_digits + spec->n_rsign + spec->n_rpadding; + spec->n_spadding + n_digits + spec->n_rsign + spec->n_rpadding; } /* fill in the non-digit parts of a numbers's string representation, @@ -360,8 +373,8 @@ where the digits go. */ static STRINGLIB_CHAR * fill_non_digits(STRINGLIB_CHAR *p_buf, const NumberFieldWidths *spec, - STRINGLIB_CHAR *prefix, Py_ssize_t n_digits, - STRINGLIB_CHAR fill_char) + STRINGLIB_CHAR *prefix, Py_ssize_t n_digits, + STRINGLIB_CHAR fill_char) { STRINGLIB_CHAR *p_digits; @@ -373,10 +386,10 @@ *p_buf++ = spec->lsign; } if (spec->n_prefix) { - memmove(p_buf, - prefix, - spec->n_prefix * sizeof(STRINGLIB_CHAR)); - p_buf += spec->n_prefix; + memmove(p_buf, + prefix, + spec->n_prefix * sizeof(STRINGLIB_CHAR)); + p_buf += spec->n_prefix; } if (spec->n_spadding) { STRINGLIB_FILL(p_buf, fill_char, spec->n_spadding); @@ -420,7 +433,7 @@ if (format->alternate) { PyErr_SetString(PyExc_ValueError, "Alternate form (#) not allowed in string format " - "specifier"); + "specifier"); goto done; } @@ -504,7 +517,7 @@ static PyObject * format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format, - IntOrLongToString tostring) + IntOrLongToString tostring) { PyObject *result = NULL; PyObject *tmp = NULL; @@ -516,8 +529,8 @@ string */ Py_ssize_t n_leading_chars; Py_ssize_t n_grouping_chars = 0; /* Count of additional chars to - allocate, used for 'n' - formatting. */ + allocate, used for 'n' + formatting. */ Py_ssize_t n_prefix = 0; /* Count of prefix chars, (e.g., '0x') */ STRINGLIB_CHAR *prefix = NULL; NumberFieldWidths spec; @@ -562,31 +575,31 @@ goto done; } #endif - numeric_char = (STRINGLIB_CHAR)x; - pnumeric_chars = &numeric_char; + numeric_char = (STRINGLIB_CHAR)x; + pnumeric_chars = &numeric_char; n_digits = 1; } else { int base; - int leading_chars_to_skip = 0; /* Number of characters added by - PyNumber_ToBase that we want to - skip over. */ + int leading_chars_to_skip = 0; /* Number of characters added by + PyNumber_ToBase that we want to + skip over. */ /* Compute the base and how many characters will be added by PyNumber_ToBase */ switch (format->type) { case 'b': base = 2; - leading_chars_to_skip = 2; /* 0b */ + leading_chars_to_skip = 2; /* 0b */ break; case 'o': base = 8; - leading_chars_to_skip = 2; /* 0o */ + leading_chars_to_skip = 2; /* 0o */ break; case 'x': case 'X': base = 16; - leading_chars_to_skip = 2; /* 0x */ + leading_chars_to_skip = 2; /* 0x */ break; default: /* shouldn't be needed, but stops a compiler warning */ case 'd': @@ -595,52 +608,57 @@ break; } - /* The number of prefix chars is the same as the leading - chars to skip */ - if (format->alternate) - n_prefix = leading_chars_to_skip; + /* The number of prefix chars is the same as the leading + chars to skip */ + if (format->alternate) + n_prefix = leading_chars_to_skip; /* Do the hard part, converting to a string in a given base */ - tmp = tostring(value, base); + tmp = tostring(value, base); if (tmp == NULL) goto done; - pnumeric_chars = STRINGLIB_STR(tmp); + pnumeric_chars = STRINGLIB_STR(tmp); n_digits = STRINGLIB_LEN(tmp); - prefix = pnumeric_chars; + prefix = pnumeric_chars; - /* Remember not to modify what pnumeric_chars points to. it - might be interned. Only modify it after we copy it into a - newly allocated output buffer. */ + /* Remember not to modify what pnumeric_chars points to. it + might be interned. Only modify it after we copy it into a + newly allocated output buffer. */ /* Is a sign character present in the output? If so, remember it and skip it */ sign = pnumeric_chars[0]; if (sign == '-') { - ++prefix; - ++leading_chars_to_skip; + ++prefix; + ++leading_chars_to_skip; } - /* Skip over the leading chars (0x, 0b, etc.) */ - n_digits -= leading_chars_to_skip; - pnumeric_chars += leading_chars_to_skip; + /* Skip over the leading chars (0x, 0b, etc.) */ + n_digits -= leading_chars_to_skip; + pnumeric_chars += leading_chars_to_skip; } if (format->type == 'n') - /* Compute how many additional chars we need to allocate - to hold the thousands grouping. */ - STRINGLIB_GROUPING(NULL, n_digits, n_digits, - 0, &n_grouping_chars, 0); + /* Compute how many additional chars we need to allocate + to hold the thousands grouping. */ + STRINGLIB_GROUPING_LOCALE(NULL, n_digits, n_digits, + 0, &n_grouping_chars, 0); + if (format->thousands_separators) + /* Compute how many additional chars we need to allocate + to hold the thousands grouping. */ + STRINGLIB_GROUPING(NULL, n_digits, n_digits, + 0, &n_grouping_chars, 0, "\3", ","); /* Calculate the widths of the various leading and trailing parts */ calc_number_widths(&spec, sign, n_prefix, n_digits + n_grouping_chars, - format); + format); /* Allocate a new string to hold the result */ result = STRINGLIB_NEW(NULL, spec.n_total); if (!result) - goto done; + goto done; p = STRINGLIB_STR(result); /* XXX There is too much magic here regarding the internals of @@ -651,44 +669,55 @@ /* Fill in the digit parts */ n_leading_chars = spec.n_lpadding + spec.n_lsign + - spec.n_prefix + spec.n_spadding; + spec.n_prefix + spec.n_spadding; memmove(p + n_leading_chars, - pnumeric_chars, - n_digits * sizeof(STRINGLIB_CHAR)); + pnumeric_chars, + n_digits * sizeof(STRINGLIB_CHAR)); /* If type is 'X', convert the filled in digits to uppercase */ if (format->type == 'X') { - Py_ssize_t t; - for (t = 0; t < n_digits; ++t) - p[t + n_leading_chars] = STRINGLIB_TOUPPER(p[t + n_leading_chars]); + Py_ssize_t t; + for (t = 0; t < n_digits; ++t) + p[t + n_leading_chars] = STRINGLIB_TOUPPER(p[t + n_leading_chars]); } /* Insert the grouping, if any, after the uppercasing of the digits, so we can ensure that grouping chars won't be affected. */ if (n_grouping_chars) { - /* We know this can't fail, since we've already - reserved enough space. */ - STRINGLIB_CHAR *pstart = p + n_leading_chars; + /* We know this can't fail, since we've already + reserved enough space. */ + STRINGLIB_CHAR *pstart = p + n_leading_chars; +#ifndef NDEBUG + int r; +#endif + if (format->type == 'n') +#ifndef NDEBUG + r = +#endif + STRINGLIB_GROUPING_LOCALE(pstart, n_digits, n_digits, + spec.n_total+n_grouping_chars-n_leading_chars, + NULL, 0); + else #ifndef NDEBUG - int r = + r = #endif - STRINGLIB_GROUPING(pstart, n_digits, n_digits, - spec.n_total+n_grouping_chars-n_leading_chars, - NULL, 0); - assert(r); + STRINGLIB_GROUPING(pstart, n_digits, n_digits, + spec.n_total+n_grouping_chars-n_leading_chars, + NULL, 0, "\3", ","); + assert(r); } /* Fill in the non-digit parts (padding, sign, etc.) */ fill_non_digits(p, &spec, prefix, n_digits + n_grouping_chars, - format->fill_char == '\0' ? ' ' : format->fill_char); + format->fill_char == '\0' ? ' ' : format->fill_char); /* If type is 'X', uppercase the prefix. This has to be done after the prefix is filled in by fill_non_digits */ if (format->type == 'X') { - Py_ssize_t t; - for (t = 0; t < n_prefix; ++t) - p[t + spec.n_lpadding + spec.n_lsign] = - STRINGLIB_TOUPPER(p[t + spec.n_lpadding + spec.n_lsign]); + Py_ssize_t t; + for (t = 0; t < n_prefix; ++t) + p[t + spec.n_lpadding + spec.n_lsign] = + STRINGLIB_TOUPPER(p[t + spec.n_lpadding + spec.n_lsign]); } @@ -723,7 +752,7 @@ /* much of this is taken from unicodeobject.c */ static PyObject * format_float_internal(PyObject *value, - const InternalFormatSpec *format) + const InternalFormatSpec *format) { /* fmt = '%.' + `prec` + `type` + '%%' worst case length = 2 + 10 (len of INT_MAX) + 1 + 2 = 15 (use 20)*/ @@ -765,7 +794,7 @@ if (format->alternate) { PyErr_SetString(PyExc_ValueError, "Alternate form (#) not allowed in float format " - "specifier"); + "specifier"); goto done; } @@ -796,7 +825,7 @@ 8-bit char. this is safe, because we've restricted what "type" can be */ PyOS_snprintf(fmt, sizeof(fmt), "%%.%" PY_FORMAT_SIZE_T "d%c", precision, - (char)type); + (char)type); /* do the actual formatting */ PyOS_ascii_formatd(charbuf, sizeof(charbuf), fmt, x); @@ -838,11 +867,11 @@ /* Fill in the non-digit parts (padding, sign, etc.) */ fill_non_digits(STRINGLIB_STR(result), &spec, NULL, n_digits, - format->fill_char == '\0' ? ' ' : format->fill_char); + format->fill_char == '\0' ? ' ' : format->fill_char); /* fill in the digit parts */ memmove(STRINGLIB_STR(result) + - (spec.n_lpadding + spec.n_lsign + spec.n_spadding), + (spec.n_lpadding + spec.n_lsign + spec.n_spadding), p, n_digits * sizeof(STRINGLIB_CHAR)); @@ -856,8 +885,8 @@ /************************************************************************/ PyObject * FORMAT_STRING(PyObject *obj, - STRINGLIB_CHAR *format_spec, - Py_ssize_t format_spec_len) + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len) { InternalFormatSpec format; PyObject *result = NULL; @@ -871,7 +900,7 @@ /* parse the format_spec */ if (!parse_internal_render_format_spec(format_spec, format_spec_len, - &format, 's')) + &format, 's')) goto done; /* type conversion? */ @@ -893,9 +922,9 @@ #if defined FORMAT_LONG || defined FORMAT_INT static PyObject* format_int_or_long(PyObject* obj, - STRINGLIB_CHAR *format_spec, - Py_ssize_t format_spec_len, - IntOrLongToString tostring) + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len, + IntOrLongToString tostring) { PyObject *result = NULL; PyObject *tmp = NULL; @@ -910,8 +939,8 @@ /* parse the format_spec */ if (!parse_internal_render_format_spec(format_spec, - format_spec_len, - &format, 'd')) + format_spec_len, + &format, 'd')) goto done; /* type conversion? */ @@ -924,8 +953,8 @@ case 'X': case 'n': /* no type conversion needed, already an int (or long). do - the formatting */ - result = format_int_or_long_internal(obj, &format, tostring); + the formatting */ + result = format_int_or_long_internal(obj, &format, tostring); break; case 'e': @@ -974,11 +1003,11 @@ PyObject * FORMAT_LONG(PyObject *obj, - STRINGLIB_CHAR *format_spec, - Py_ssize_t format_spec_len) + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len) { return format_int_or_long(obj, format_spec, format_spec_len, - long_format); + long_format); } #endif /* FORMAT_LONG */ @@ -995,19 +1024,19 @@ PyObject * FORMAT_INT(PyObject *obj, - STRINGLIB_CHAR *format_spec, - Py_ssize_t format_spec_len) + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len) { return format_int_or_long(obj, format_spec, format_spec_len, - int_format); + int_format); } #endif /* FORMAT_INT */ #ifdef FORMAT_FLOAT PyObject * FORMAT_FLOAT(PyObject *obj, - STRINGLIB_CHAR *format_spec, - Py_ssize_t format_spec_len) + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len) { PyObject *result = NULL; InternalFormatSpec format; @@ -1021,17 +1050,17 @@ /* parse the format_spec */ if (!parse_internal_render_format_spec(format_spec, - format_spec_len, - &format, '\0')) + format_spec_len, + &format, '\0')) goto done; /* type conversion? */ switch (format.type) { case '\0': - /* 'Z' means like 'g', but with at least one decimal. See - PyOS_ascii_formatd */ - format.type = 'Z'; - /* Deliberate fall through to the next case statement */ + /* 'Z' means like 'g', but with at least one decimal. See + PyOS_ascii_formatd */ + format.type = 'Z'; + /* Deliberate fall through to the next case statement */ case 'e': case 'E': case 'f': Modified: python/branches/py3k-short-float-repr/Objects/stringlib/localeutil.h ============================================================================== --- python/branches/py3k-short-float-repr/Objects/stringlib/localeutil.h (original) +++ python/branches/py3k-short-float-repr/Objects/stringlib/localeutil.h Sun Apr 5 01:04:14 2009 @@ -18,11 +18,13 @@ * @append_zero_char: If non-zero, put a trailing zero at the end of * of the resulting string, if and only if we modified the * string. + * @grouping: see definition in localeconv(). + * @thousands_sep: see definition in localeconv(). * - * Inserts thousand grouping characters (as defined in the current - * locale) into the string between buffer and buffer+n_digits. If - * count is non-NULL, don't do any formatting, just count the number - * of characters to insert. This is used by the caller to + * Inserts thousand grouping characters (as defined by grouping and + * thousands_sep) into the string between buffer and buffer+n_digits. + * If count is non-NULL, don't do any formatting, just count the + * number of characters to insert. This is used by the caller to * appropriately resize the buffer, if needed. If count is non-NULL, * buffer can be NULL (it is not dereferenced at all in that case). * @@ -34,97 +36,130 @@ **/ int _Py_InsertThousandsGrouping(STRINGLIB_CHAR *buffer, - Py_ssize_t n_buffer, - Py_ssize_t n_digits, - Py_ssize_t buf_size, - Py_ssize_t *count, - int append_zero_char) + Py_ssize_t n_buffer, + Py_ssize_t n_digits, + Py_ssize_t buf_size, + Py_ssize_t *count, + int append_zero_char, + const char *grouping, + const char *thousands_sep) { - struct lconv *locale_data = localeconv(); - const char *grouping = locale_data->grouping; - const char *thousands_sep = locale_data->thousands_sep; - Py_ssize_t thousands_sep_len = strlen(thousands_sep); - STRINGLIB_CHAR *pend = NULL; /* current end of buffer */ - STRINGLIB_CHAR *pmax = NULL; /* max of buffer */ - char current_grouping; - Py_ssize_t remaining = n_digits; /* Number of chars remaining to - be looked at */ - - /* Initialize the character count, if we're just counting. */ - if (count) - *count = 0; - else { - /* We're not just counting, we're modifying buffer */ - pend = buffer + n_buffer; - pmax = buffer + buf_size; - } - - /* Starting at the end and working right-to-left, keep track of - what grouping needs to be added and insert that. */ - current_grouping = *grouping++; - - /* If the first character is 0, perform no grouping at all. */ - if (current_grouping == 0) - return 1; - - while (remaining > current_grouping) { - /* Always leave buffer and pend valid at the end of this - loop, since we might leave with a return statement. */ - - remaining -= current_grouping; - if (count) { - /* We're only counting, not touching the memory. */ - *count += thousands_sep_len; - } - else { - /* Do the formatting. */ - - STRINGLIB_CHAR *plast = buffer + remaining; - - /* Is there room to insert thousands_sep_len chars? */ - if (pmax - pend < thousands_sep_len) - /* No room. */ - return 0; - - /* Move the rest of the string down. */ - memmove(plast + thousands_sep_len, - plast, - (pend - plast) * sizeof(STRINGLIB_CHAR)); - /* Copy the thousands_sep chars into the buffer. */ + Py_ssize_t thousands_sep_len = strlen(thousands_sep); + STRINGLIB_CHAR *pend = NULL; /* current end of buffer */ + STRINGLIB_CHAR *pmax = NULL; /* max of buffer */ + char current_grouping; + Py_ssize_t remaining = n_digits; /* Number of chars remaining to + be looked at */ + + /* Initialize the character count, if we're just counting. */ + if (count) + *count = 0; + else { + /* We're not just counting, we're modifying buffer */ + pend = buffer + n_buffer; + pmax = buffer + buf_size; + } + + /* Starting at the end and working right-to-left, keep track of + what grouping needs to be added and insert that. */ + current_grouping = *grouping++; + + /* If the first character is 0, perform no grouping at all. */ + if (current_grouping == 0) + return 1; + + while (remaining > current_grouping) { + /* Always leave buffer and pend valid at the end of this + loop, since we might leave with a return statement. */ + + remaining -= current_grouping; + if (count) { + /* We're only counting, not touching the memory. */ + *count += thousands_sep_len; + } + else { + /* Do the formatting. */ + + STRINGLIB_CHAR *plast = buffer + remaining; + + /* Is there room to insert thousands_sep_len chars? */ + if (pmax - pend < thousands_sep_len) + /* No room. */ + return 0; + + /* Move the rest of the string down. */ + memmove(plast + thousands_sep_len, + plast, + (pend - plast) * sizeof(STRINGLIB_CHAR)); + /* Copy the thousands_sep chars into the buffer. */ #if STRINGLIB_IS_UNICODE - /* Convert from the char's of the thousands_sep from - the locale into unicode. */ - { - Py_ssize_t i; - for (i = 0; i < thousands_sep_len; ++i) - plast[i] = thousands_sep[i]; - } + /* Convert from the char's of the thousands_sep from + the locale into unicode. */ + { + Py_ssize_t i; + for (i = 0; i < thousands_sep_len; ++i) + plast[i] = thousands_sep[i]; + } #else - /* No conversion, just memcpy the thousands_sep. */ - memcpy(plast, thousands_sep, thousands_sep_len); + /* No conversion, just memcpy the thousands_sep. */ + memcpy(plast, thousands_sep, thousands_sep_len); #endif - } + } - /* Adjust end pointer. */ - pend += thousands_sep_len; + /* Adjust end pointer. */ + pend += thousands_sep_len; - /* Move to the next grouping character, unless we're - repeating (which is designated by a grouping of 0). */ - if (*grouping != 0) { - current_grouping = *grouping++; - if (current_grouping == CHAR_MAX) - /* We're done. */ - break; - } - } - if (append_zero_char) { - /* Append a zero character to mark the end of the string, - if there's room. */ - if (pend - (buffer + remaining) < 1) - /* No room, error. */ - return 0; - *pend = 0; - } - return 1; + /* Move to the next grouping character, unless we're + repeating (which is designated by a grouping of 0). */ + if (*grouping != 0) { + current_grouping = *grouping++; + if (current_grouping == CHAR_MAX) + /* We're done. */ + break; + } + } + if (append_zero_char) { + /* Append a zero character to mark the end of the string, + if there's room. */ + if (pend - (buffer + remaining) < 1) + /* No room, error. */ + return 0; + *pend = 0; + } + return 1; +} + +/** + * _Py_InsertThousandsGroupingLocale: + * @buffer: A pointer to the start of a string. + * @n_buffer: The length of the string. + * @n_digits: The number of digits in the string, in which we want + * to put the grouping chars. + * @buf_size: The maximum size of the buffer pointed to by buffer. + * @count: If non-NULL, points to a variable that will receive the + * number of characters we need to insert (and no formatting + * will actually occur). + * @append_zero_char: If non-zero, put a trailing zero at the end of + * of the resulting string, if and only if we modified the + * string. + * + * Reads thee current locale and calls _Py_InsertThousandsGrouping(). + **/ +int +_Py_InsertThousandsGroupingLocale(STRINGLIB_CHAR *buffer, + Py_ssize_t n_buffer, + Py_ssize_t n_digits, + Py_ssize_t buf_size, + Py_ssize_t *count, + int append_zero_char) +{ + struct lconv *locale_data = localeconv(); + const char *grouping = locale_data->grouping; + const char *thousands_sep = locale_data->thousands_sep; + + return _Py_InsertThousandsGrouping(buffer, n_buffer, n_digits, + buf_size, count, + append_zero_char, grouping, + thousands_sep); } #endif /* STRINGLIB_LOCALEUTIL_H */ Modified: python/branches/py3k-short-float-repr/Objects/stringlib/stringdefs.h ============================================================================== --- python/branches/py3k-short-float-repr/Objects/stringlib/stringdefs.h (original) +++ python/branches/py3k-short-float-repr/Objects/stringlib/stringdefs.h Sun Apr 5 01:04:14 2009 @@ -24,5 +24,6 @@ #define STRINGLIB_CMP memcmp #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_GROUPING _PyBytes_InsertThousandsGrouping +#define STRINGLIB_GROUPING_LOCALE _PyBytes_InsertThousandsGroupingLocale #define STRINGLIB_TOASCII PyObject_Repr #endif /* !STRINGLIB_STRINGDEFS_H */ Modified: python/branches/py3k-short-float-repr/Objects/stringlib/unicodedefs.h ============================================================================== --- python/branches/py3k-short-float-repr/Objects/stringlib/unicodedefs.h (original) +++ python/branches/py3k-short-float-repr/Objects/stringlib/unicodedefs.h Sun Apr 5 01:04:14 2009 @@ -22,6 +22,7 @@ #define STRINGLIB_RESIZE PyUnicode_Resize #define STRINGLIB_CHECK PyUnicode_Check #define STRINGLIB_GROUPING _PyUnicode_InsertThousandsGrouping +#define STRINGLIB_GROUPING_LOCALE _PyUnicode_InsertThousandsGroupingLocale #if PY_VERSION_HEX < 0x03000000 #define STRINGLIB_TOSTR PyObject_Unicode Modified: python/branches/py3k-short-float-repr/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/unicodeobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/unicodeobject.c Sun Apr 5 01:04:14 2009 @@ -5635,6 +5635,7 @@ #include "stringlib/partition.h" #define _Py_InsertThousandsGrouping _PyUnicode_InsertThousandsGrouping +#define _Py_InsertThousandsGroupingLocale _PyUnicode_InsertThousandsGroupingLocale #include "stringlib/localeutil.h" /* helper macro to fixup start/end slice values */ Modified: python/branches/py3k-short-float-repr/PC/VC6/pythoncore.dsp ============================================================================== --- python/branches/py3k-short-float-repr/PC/VC6/pythoncore.dsp (original) +++ python/branches/py3k-short-float-repr/PC/VC6/pythoncore.dsp Sun Apr 5 01:04:14 2009 @@ -97,14 +97,6 @@ # End Source File # Begin Source File -SOURCE=..\..\Modules\_bufferedio.c -# End Source File -# Begin Source File - -SOURCE=..\..\Modules\_bytesio.c -# End Source File -# Begin Source File - SOURCE=..\..\Modules\cjkcodecs\_codecs_cn.c # End Source File # Begin Source File @@ -141,19 +133,39 @@ # End Source File # Begin Source File -SOURCE=..\..\Modules\_fileio.c +SOURCE=..\..\Modules\_functoolsmodule.c # End Source File # Begin Source File -SOURCE=..\..\Modules\_functoolsmodule.c +SOURCE=..\..\Modules\_heapqmodule.c # End Source File # Begin Source File -SOURCE=..\..\Modules\_heapqmodule.c +SOURCE=..\..\Modules\_io\bytesio.c +# End Source File +# Begin Source File + +SOURCE=..\..\Modules\_io\stringio.c +# End Source File +# Begin Source File + +SOURCE=..\..\Modules\_io\fileio.c +# End Source File +# Begin Source File + +SOURCE="..\..\Modules\_io\bufferedio.c" +# End Source File +# Begin Source File + +SOURCE=..\..\Modules\_io\iobase.c # End Source File # Begin Source File -SOURCE=..\..\Modules\_iobase.c +SOURCE=..\..\Modules\_io\textio.c +# End Source File +# Begin Source File + +SOURCE=..\..\Modules\_io\_iomodule.c # End Source File # Begin Source File @@ -181,10 +193,6 @@ # End Source File # Begin Source File -SOURCE=..\..\Modules\_stringio.c -# End Source File -# Begin Source File - SOURCE=..\..\Modules\_struct.c # End Source File # Begin Source File @@ -193,10 +201,6 @@ # End Source File # Begin Source File -SOURCE=..\..\Modules\_textio.c -# End Source File -# Begin Source File - SOURCE=..\..\Modules\_threadmodule.c # End Source File # Begin Source File @@ -475,10 +479,6 @@ # End Source File # Begin Source File -SOURCE=..\..\Modules\io.c -# End Source File -# Begin Source File - SOURCE=..\..\Objects\iterobject.c # End Source File # Begin Source File Modified: python/branches/py3k-short-float-repr/PC/VS7.1/pythoncore.vcproj ============================================================================== --- python/branches/py3k-short-float-repr/PC/VS7.1/pythoncore.vcproj (original) +++ python/branches/py3k-short-float-repr/PC/VS7.1/pythoncore.vcproj Sun Apr 5 01:04:14 2009 @@ -274,6 +274,32 @@ + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + @@ -1043,10 +1051,6 @@ > - - Modified: python/branches/py3k-short-float-repr/PCbuild/pythoncore.vcproj ============================================================================== --- python/branches/py3k-short-float-repr/PCbuild/pythoncore.vcproj (original) +++ python/branches/py3k-short-float-repr/PCbuild/pythoncore.vcproj Sun Apr 5 01:04:14 2009 @@ -979,10 +979,6 @@ > - - @@ -995,14 +991,6 @@ > - - - - @@ -1011,14 +999,6 @@ > - - - - @@ -1043,18 +1023,10 @@ > - - - - @@ -1095,10 +1067,6 @@ > - - @@ -1175,6 +1143,42 @@ > + + + + + + + + + + + + + + + + + + lb_str, s) != 0) continue; #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD +#if 0 /* Leaving this in as an example */ if (!(ps->p_flags & CO_FUTURE_WITH_STATEMENT)) { if (s[0] == 'w' && strcmp(s, "with") == 0) @@ -157,6 +158,7 @@ break; /* not a keyword yet */ } #endif +#endif D(printf("It's a keyword\n")); return n - i; } @@ -178,6 +180,7 @@ } #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD +#if 0 /* Leaving this in as an example */ static void future_hack(parser_state *ps) @@ -218,6 +221,7 @@ } } } +#endif #endif /* future keyword */ int @@ -278,11 +282,13 @@ d->d_name, ps->p_stack.s_top->s_state)); #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD +#if 0 if (d->d_name[0] == 'i' && strcmp(d->d_name, "import_stmt") == 0) future_hack(ps); #endif +#endif s_pop(&ps->p_stack); if (s_empty(&ps->p_stack)) { D(printf(" ACCEPT.\n")); @@ -296,10 +302,12 @@ if (s->s_accept) { #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD +#if 0 if (d->d_name[0] == 'i' && strcmp(d->d_name, "import_stmt") == 0) future_hack(ps); #endif +#endif /* Pop this dfa and try again */ s_pop(&ps->p_stack); D(printf(" Pop ...\n")); Modified: python/branches/py3k-short-float-repr/Parser/parsetok.c ============================================================================== --- python/branches/py3k-short-float-repr/Parser/parsetok.c (original) +++ python/branches/py3k-short-float-repr/Parser/parsetok.c Sun Apr 5 01:04:14 2009 @@ -100,6 +100,7 @@ } #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD +#if 0 static char with_msg[] = "%s:%d: Warning: 'with' will become a reserved keyword in Python 2.6\n"; @@ -114,6 +115,7 @@ PySys_WriteStderr(msg, filename, lineno); } #endif +#endif /* Parse input coming from the given tokenizer structure. Return error code. */ @@ -133,8 +135,8 @@ return NULL; } #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD - if (*flags & PyPARSE_WITH_IS_KEYWORD) - ps->p_flags |= CO_FUTURE_WITH_STATEMENT; + if (*flags & PyPARSE_BARRY_AS_BDFL) + ps->p_flags |= CO_FUTURE_BARRY_AS_BDFL; #endif for (;;) { @@ -177,26 +179,20 @@ str[len] = '\0'; #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD - /* This is only necessary to support the "as" warning, but - we don't want to warn about "as" in import statements. */ - if (type == NAME && - len == 6 && str[0] == 'i' && strcmp(str, "import") == 0) - handling_import = 1; - - /* Warn about with as NAME */ - if (type == NAME && - !(ps->p_flags & CO_FUTURE_WITH_STATEMENT)) { - if (len == 4 && str[0] == 'w' && strcmp(str, "with") == 0) - warn(with_msg, err_ret->filename, tok->lineno); - else if (!(handling_import || handling_with) && - len == 2 && str[0] == 'a' && - strcmp(str, "as") == 0) - warn(as_msg, err_ret->filename, tok->lineno); - } - else if (type == NAME && - (ps->p_flags & CO_FUTURE_WITH_STATEMENT) && - len == 4 && str[0] == 'w' && strcmp(str, "with") == 0) - handling_with = 1; + if (type == NOTEQUAL) { + if (!(ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) && + strcmp(str, "!=")) { + err_ret->error = E_SYNTAX; + break; + } + else if ((ps->p_flags & CO_FUTURE_BARRY_AS_BDFL) && + strcmp(str, "<>")) { + err_ret->text = "with Barry as BDFL, use '<>' " + "instead of '!='"; + err_ret->error = E_SYNTAX; + break; + } + } #endif if (a >= tok->line_start) col_offset = a - tok->line_start; Modified: python/branches/py3k-short-float-repr/Parser/tokenizer.c ============================================================================== --- python/branches/py3k-short-float-repr/Parser/tokenizer.c (original) +++ python/branches/py3k-short-float-repr/Parser/tokenizer.c Sun Apr 5 01:04:14 2009 @@ -1040,6 +1040,7 @@ break; case '<': switch (c2) { + case '>': return NOTEQUAL; case '=': return LESSEQUAL; case '<': return LEFTSHIFT; } Modified: python/branches/py3k-short-float-repr/Python/_warnings.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/_warnings.c (original) +++ python/branches/py3k-short-float-repr/Python/_warnings.c Sun Apr 5 01:04:14 2009 @@ -2,7 +2,6 @@ #include "frameobject.h" #define MODULE_NAME "_warnings" -#define DEFAULT_ACTION_NAME "default_action" PyDoc_STRVAR(warnings__doc__, MODULE_NAME " provides basic warning filtering support.\n" @@ -12,6 +11,7 @@ get_warnings_attr() will reset these variables accordingly. */ static PyObject *_filters; /* List */ static PyObject *_once_registry; /* Dict */ +static PyObject *_default_action; /* String */ static int @@ -78,12 +78,31 @@ } +static PyObject * +get_default_action(void) +{ + PyObject *default_action; + + default_action = get_warnings_attr("defaultaction"); + if (default_action == NULL) { + if (PyErr_Occurred()) { + return NULL; + } + return _default_action; + } + + Py_DECREF(_default_action); + _default_action = default_action; + return default_action; +} + + /* The item is a borrowed reference. */ static const char * get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, PyObject *module, PyObject **item) { - PyObject *action, *m, *d; + PyObject *action; Py_ssize_t i; PyObject *warnings_filters; @@ -135,22 +154,17 @@ return _PyUnicode_AsString(action); } - m = PyImport_ImportModule(MODULE_NAME); - if (m == NULL) - return NULL; - d = PyModule_GetDict(m); - Py_DECREF(m); - if (d == NULL) - return NULL; - action = PyDict_GetItemString(d, DEFAULT_ACTION_NAME); - if (action != NULL) + action = get_default_action(); + if (action != NULL) { return _PyUnicode_AsString(action); + } PyErr_SetString(PyExc_ValueError, - MODULE_NAME "." DEFAULT_ACTION_NAME " not found"); + MODULE_NAME ".defaultaction not found"); return NULL; } + static int already_warned(PyObject *registry, PyObject *key, int should_set) { @@ -874,7 +888,7 @@ PyMODINIT_FUNC _PyWarnings_Init(void) { - PyObject *m, *default_action; + PyObject *m; m = PyModule_Create(&warningsmodule); if (m == NULL) @@ -894,10 +908,10 @@ if (PyModule_AddObject(m, "once_registry", _once_registry) < 0) return NULL; - default_action = PyUnicode_InternFromString("default"); - if (default_action == NULL) + _default_action = PyUnicode_FromString("default"); + if (_default_action == NULL) return NULL; - if (PyModule_AddObject(m, DEFAULT_ACTION_NAME, default_action) < 0) + if (PyModule_AddObject(m, "default_action", _default_action) < 0) return NULL; return m; } Modified: python/branches/py3k-short-float-repr/Python/future.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/future.c (original) +++ python/branches/py3k-short-float-repr/Python/future.c Sun Apr 5 01:04:14 2009 @@ -39,6 +39,8 @@ continue; } else if (strcmp(feature, FUTURE_UNICODE_LITERALS) == 0) { continue; + } else if (strcmp(feature, FUTURE_BARRY_AS_BDFL) == 0) { + ff->ff_features |= CO_FUTURE_BARRY_AS_BDFL; } else if (strcmp(feature, "braces") == 0) { PyErr_SetString(PyExc_SyntaxError, "not a chance"); Modified: python/branches/py3k-short-float-repr/Python/getargs.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/getargs.c (original) +++ python/branches/py3k-short-float-repr/Python/getargs.c Sun Apr 5 01:04:14 2009 @@ -776,24 +776,18 @@ char *p = va_arg(*p_va, char *); if (PyBytes_Check(arg) && PyBytes_Size(arg) == 1) *p = PyBytes_AS_STRING(arg)[0]; - else if (PyUnicode_Check(arg) && - PyUnicode_GET_SIZE(arg) == 1 && - PyUnicode_AS_UNICODE(arg)[0] < 256) - *p = (char)PyUnicode_AS_UNICODE(arg)[0]; else - return converterr("char < 256", arg, msgbuf, bufsize); + return converterr("a byte string of length 1", arg, msgbuf, bufsize); break; } case 'C': {/* unicode char */ int *p = va_arg(*p_va, int *); - if (PyBytes_Check(arg) && PyBytes_Size(arg) == 1) - *p = PyBytes_AS_STRING(arg)[0]; - else if (PyUnicode_Check(arg) && - PyUnicode_GET_SIZE(arg) == 1) + if (PyUnicode_Check(arg) && + PyUnicode_GET_SIZE(arg) == 1) *p = PyUnicode_AS_UNICODE(arg)[0]; else - return converterr("char", arg, msgbuf, bufsize); + return converterr("a unicode character", arg, msgbuf, bufsize); break; } Modified: python/branches/py3k-short-float-repr/Python/graminit.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/graminit.c (original) +++ python/branches/py3k-short-float-repr/Python/graminit.c Sun Apr 5 01:04:14 2009 @@ -1129,16 +1129,17 @@ {1, arcs_52_0}, {2, arcs_52_1}, }; -static arc arcs_53_0[9] = { +static arc arcs_53_0[10] = { {118, 1}, {119, 1}, {120, 1}, {121, 1}, {122, 1}, {123, 1}, + {124, 1}, {95, 1}, {114, 2}, - {124, 3}, + {125, 3}, }; static arc arcs_53_1[1] = { {0, 1}, @@ -1151,7 +1152,7 @@ {0, 3}, }; static state states_53[4] = { - {9, arcs_53_0}, + {10, arcs_53_0}, {1, arcs_53_1}, {1, arcs_53_2}, {2, arcs_53_3}, @@ -1172,10 +1173,10 @@ {1, arcs_54_2}, }; static arc arcs_55_0[1] = { - {125, 1}, + {126, 1}, }; static arc arcs_55_1[2] = { - {126, 0}, + {127, 0}, {0, 1}, }; static state states_55[2] = { @@ -1183,10 +1184,10 @@ {2, arcs_55_1}, }; static arc arcs_56_0[1] = { - {127, 1}, + {128, 1}, }; static arc arcs_56_1[2] = { - {128, 0}, + {129, 0}, {0, 1}, }; static state states_56[2] = { @@ -1194,10 +1195,10 @@ {2, arcs_56_1}, }; static arc arcs_57_0[1] = { - {129, 1}, + {130, 1}, }; static arc arcs_57_1[2] = { - {130, 0}, + {131, 0}, {0, 1}, }; static state states_57[2] = { @@ -1205,11 +1206,11 @@ {2, arcs_57_1}, }; static arc arcs_58_0[1] = { - {131, 1}, + {132, 1}, }; static arc arcs_58_1[3] = { - {132, 0}, {133, 0}, + {134, 0}, {0, 1}, }; static state states_58[2] = { @@ -1217,11 +1218,11 @@ {3, arcs_58_1}, }; static arc arcs_59_0[1] = { - {134, 1}, + {135, 1}, }; static arc arcs_59_1[3] = { - {135, 0}, {136, 0}, + {137, 0}, {0, 1}, }; static state states_59[2] = { @@ -1229,13 +1230,13 @@ {3, arcs_59_1}, }; static arc arcs_60_0[1] = { - {137, 1}, + {138, 1}, }; static arc arcs_60_1[5] = { {31, 0}, - {138, 0}, {139, 0}, {140, 0}, + {141, 0}, {0, 1}, }; static state states_60[2] = { @@ -1243,13 +1244,13 @@ {5, arcs_60_1}, }; static arc arcs_61_0[4] = { - {135, 1}, {136, 1}, - {141, 1}, - {142, 2}, + {137, 1}, + {142, 1}, + {143, 2}, }; static arc arcs_61_1[1] = { - {137, 2}, + {138, 2}, }; static arc arcs_61_2[1] = { {0, 2}, @@ -1260,15 +1261,15 @@ {1, arcs_61_2}, }; static arc arcs_62_0[1] = { - {143, 1}, + {144, 1}, }; static arc arcs_62_1[3] = { - {144, 1}, + {145, 1}, {32, 2}, {0, 1}, }; static arc arcs_62_2[1] = { - {137, 3}, + {138, 3}, }; static arc arcs_62_3[1] = { {0, 3}, @@ -1281,44 +1282,44 @@ }; static arc arcs_63_0[10] = { {13, 1}, - {146, 2}, - {148, 3}, + {147, 2}, + {149, 3}, {21, 4}, - {151, 4}, - {152, 5}, + {152, 4}, + {153, 5}, {77, 4}, - {153, 4}, {154, 4}, {155, 4}, + {156, 4}, }; static arc arcs_63_1[3] = { {46, 6}, - {145, 6}, + {146, 6}, {15, 4}, }; static arc arcs_63_2[2] = { - {145, 7}, - {147, 4}, + {146, 7}, + {148, 4}, }; static arc arcs_63_3[2] = { - {149, 8}, - {150, 4}, + {150, 8}, + {151, 4}, }; static arc arcs_63_4[1] = { {0, 4}, }; static arc arcs_63_5[2] = { - {152, 5}, + {153, 5}, {0, 5}, }; static arc arcs_63_6[1] = { {15, 4}, }; static arc arcs_63_7[1] = { - {147, 4}, + {148, 4}, }; static arc arcs_63_8[1] = { - {150, 4}, + {151, 4}, }; static state states_63[9] = { {10, arcs_63_0}, @@ -1335,7 +1336,7 @@ {24, 1}, }; static arc arcs_64_1[3] = { - {156, 2}, + {157, 2}, {30, 3}, {0, 1}, }; @@ -1359,7 +1360,7 @@ }; static arc arcs_65_0[3] = { {13, 1}, - {146, 2}, + {147, 2}, {76, 3}, }; static arc arcs_65_1[2] = { @@ -1367,7 +1368,7 @@ {15, 5}, }; static arc arcs_65_2[1] = { - {157, 6}, + {158, 6}, }; static arc arcs_65_3[1] = { {21, 5}, @@ -1379,7 +1380,7 @@ {0, 5}, }; static arc arcs_65_6[1] = { - {147, 5}, + {148, 5}, }; static state states_65[7] = { {3, arcs_65_0}, @@ -1391,14 +1392,14 @@ {1, arcs_65_6}, }; static arc arcs_66_0[1] = { - {158, 1}, + {159, 1}, }; static arc arcs_66_1[2] = { {30, 2}, {0, 1}, }; static arc arcs_66_2[2] = { - {158, 1}, + {159, 1}, {0, 2}, }; static state states_66[3] = { @@ -1416,11 +1417,11 @@ }; static arc arcs_67_2[3] = { {24, 3}, - {159, 4}, + {160, 4}, {0, 2}, }; static arc arcs_67_3[2] = { - {159, 4}, + {160, 4}, {0, 3}, }; static arc arcs_67_4[1] = { @@ -1485,7 +1486,7 @@ }; static arc arcs_71_1[4] = { {25, 2}, - {156, 3}, + {157, 3}, {30, 4}, {0, 1}, }; @@ -1500,7 +1501,7 @@ {0, 4}, }; static arc arcs_71_5[3] = { - {156, 3}, + {157, 3}, {30, 7}, {0, 5}, }; @@ -1536,7 +1537,7 @@ {2, arcs_71_10}, }; static arc arcs_72_0[1] = { - {160, 1}, + {161, 1}, }; static arc arcs_72_1[1] = { {21, 2}, @@ -1572,7 +1573,7 @@ {1, arcs_72_7}, }; static arc arcs_73_0[3] = { - {161, 1}, + {162, 1}, {31, 2}, {32, 3}, }; @@ -1587,7 +1588,7 @@ {24, 6}, }; static arc arcs_73_4[4] = { - {161, 1}, + {162, 1}, {31, 2}, {32, 3}, {0, 4}, @@ -1600,7 +1601,7 @@ {0, 6}, }; static arc arcs_73_7[2] = { - {161, 5}, + {162, 5}, {32, 3}, }; static state states_73[8] = { @@ -1617,7 +1618,7 @@ {24, 1}, }; static arc arcs_74_1[3] = { - {156, 2}, + {157, 2}, {29, 3}, {0, 1}, }; @@ -1634,8 +1635,8 @@ {1, arcs_74_3}, }; static arc arcs_75_0[2] = { - {156, 1}, - {163, 1}, + {157, 1}, + {164, 1}, }; static arc arcs_75_1[1] = { {0, 1}, @@ -1657,7 +1658,7 @@ {105, 4}, }; static arc arcs_76_4[2] = { - {162, 5}, + {163, 5}, {0, 4}, }; static arc arcs_76_5[1] = { @@ -1678,7 +1679,7 @@ {107, 2}, }; static arc arcs_77_2[2] = { - {162, 3}, + {163, 3}, {0, 2}, }; static arc arcs_77_3[1] = { @@ -1712,7 +1713,7 @@ {1, arcs_79_1}, }; static arc arcs_80_0[1] = { - {166, 1}, + {167, 1}, }; static arc arcs_80_1[2] = { {9, 2}, @@ -1728,11 +1729,11 @@ }; static dfa dfas[81] = { {256, "single_input", 0, 3, states_0, - "\004\050\060\200\000\000\000\050\370\044\034\144\011\040\004\000\200\041\224\017\101"}, + "\004\050\060\200\000\000\000\050\370\044\034\144\011\040\004\000\000\103\050\037\202"}, {257, "file_input", 0, 2, states_1, - "\204\050\060\200\000\000\000\050\370\044\034\144\011\040\004\000\200\041\224\017\101"}, + "\204\050\060\200\000\000\000\050\370\044\034\144\011\040\004\000\000\103\050\037\202"}, {258, "eval_input", 0, 3, states_2, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {259, "decorator", 0, 7, states_3, "\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {260, "decorators", 0, 2, states_4, @@ -1752,13 +1753,13 @@ {267, "vfpdef", 0, 2, states_11, "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {268, "stmt", 0, 2, states_12, - "\000\050\060\200\000\000\000\050\370\044\034\144\011\040\004\000\200\041\224\017\101"}, + "\000\050\060\200\000\000\000\050\370\044\034\144\011\040\004\000\000\103\050\037\202"}, {269, "simple_stmt", 0, 4, states_13, - "\000\040\040\200\000\000\000\050\370\044\034\000\000\040\004\000\200\041\224\017\100"}, + "\000\040\040\200\000\000\000\050\370\044\034\000\000\040\004\000\000\103\050\037\200"}, {270, "small_stmt", 0, 2, states_14, - "\000\040\040\200\000\000\000\050\370\044\034\000\000\040\004\000\200\041\224\017\100"}, + "\000\040\040\200\000\000\000\050\370\044\034\000\000\040\004\000\000\103\050\037\200"}, {271, "expr_stmt", 0, 6, states_15, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {272, "augassign", 0, 2, states_16, "\000\000\000\000\000\200\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {273, "del_stmt", 0, 3, states_17, @@ -1766,7 +1767,7 @@ {274, "pass_stmt", 0, 2, states_18, "\000\000\000\000\000\000\000\040\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\170\000\000\000\000\000\000\000\000\000\000\000\100"}, + "\000\000\000\000\000\000\000\000\170\000\000\000\000\000\000\000\000\000\000\000\200"}, {276, "break_stmt", 0, 2, states_20, "\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000"}, {277, "continue_stmt", 0, 2, states_21, @@ -1774,7 +1775,7 @@ {278, "return_stmt", 0, 3, states_22, "\000\000\000\000\000\000\000\000\040\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\100"}, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200"}, {280, "raise_stmt", 0, 5, states_24, "\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000"}, {281, "import_stmt", 0, 2, states_25, @@ -1800,7 +1801,7 @@ {291, "assert_stmt", 0, 5, states_35, "\000\000\000\000\000\000\000\000\000\000\020\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\144\011\000\000\000\000\000\000\000\001"}, + "\000\010\020\000\000\000\000\000\000\000\000\144\011\000\000\000\000\000\000\000\002"}, {293, "if_stmt", 0, 8, states_37, "\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000"}, {294, "while_stmt", 0, 8, states_38, @@ -1816,67 +1817,67 @@ {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"}, {300, "suite", 0, 5, states_44, - "\004\040\040\200\000\000\000\050\370\044\034\000\000\040\004\000\200\041\224\017\100"}, + "\004\040\040\200\000\000\000\050\370\044\034\000\000\040\004\000\000\103\050\037\200"}, {301, "test", 0, 6, states_45, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {302, "test_nocond", 0, 2, states_46, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {303, "lambdef", 0, 5, states_47, "\000\000\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000"}, {304, "lambdef_nocond", 0, 5, states_48, "\000\000\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000"}, {305, "or_test", 0, 2, states_49, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\004\000\000\103\050\037\000"}, {306, "and_test", 0, 2, states_50, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\004\000\000\103\050\037\000"}, {307, "not_test", 0, 3, states_51, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\004\000\000\103\050\037\000"}, {308, "comparison", 0, 2, states_52, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\000\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\000\000\000\103\050\037\000"}, {309, "comp_op", 0, 4, states_53, - "\000\000\000\000\000\000\000\000\000\000\000\200\000\000\304\037\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\200\000\000\304\077\000\000\000\000\000"}, {310, "star_expr", 0, 3, states_54, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\000\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\000\000\000\103\050\037\000"}, {311, "expr", 0, 2, states_55, - "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\200\041\224\017\000"}, + "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\103\050\037\000"}, {312, "xor_expr", 0, 2, states_56, - "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\200\041\224\017\000"}, + "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\103\050\037\000"}, {313, "and_expr", 0, 2, states_57, - "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\200\041\224\017\000"}, + "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\103\050\037\000"}, {314, "shift_expr", 0, 2, states_58, - "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\200\041\224\017\000"}, + "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\103\050\037\000"}, {315, "arith_expr", 0, 2, states_59, - "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\200\041\224\017\000"}, + "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\103\050\037\000"}, {316, "term", 0, 2, states_60, - "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\200\041\224\017\000"}, + "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\103\050\037\000"}, {317, "factor", 0, 3, states_61, - "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\200\041\224\017\000"}, + "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\103\050\037\000"}, {318, "power", 0, 4, states_62, - "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\224\017\000"}, + "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\050\037\000"}, {319, "atom", 0, 9, states_63, - "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\224\017\000"}, + "\000\040\040\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\050\037\000"}, {320, "testlist_comp", 0, 5, states_64, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {321, "trailer", 0, 7, states_65, - "\000\040\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\004\000\000"}, + "\000\040\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\010\000\000"}, {322, "subscriptlist", 0, 3, states_66, - "\000\040\040\202\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\202\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {323, "subscript", 0, 5, states_67, - "\000\040\040\202\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\202\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {324, "sliceop", 0, 3, states_68, "\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {325, "exprlist", 0, 3, states_69, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\000\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\000\000\000\000\103\050\037\000"}, {326, "testlist", 0, 3, states_70, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {327, "dictorsetmaker", 0, 11, states_71, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {328, "classdef", 0, 8, states_72, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001"}, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002"}, {329, "arglist", 0, 8, states_73, - "\000\040\040\200\001\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\200\001\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {330, "argument", 0, 4, states_74, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {331, "comp_iter", 0, 2, states_75, "\000\000\000\000\000\000\000\000\000\000\000\104\000\000\000\000\000\000\000\000\000"}, {332, "comp_for", 0, 6, states_76, @@ -1884,13 +1885,13 @@ {333, "comp_if", 0, 4, states_77, "\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000"}, {334, "testlist1", 0, 2, states_78, - "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\200\041\224\017\000"}, + "\000\040\040\200\000\000\000\000\000\040\000\000\000\040\004\000\000\103\050\037\000"}, {335, "encoding_decl", 0, 2, states_79, "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {336, "yield_expr", 0, 3, states_80, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\100"}, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200"}, }; -static label labels[167] = { +static label labels[168] = { {0, "EMPTY"}, {256, 0}, {4, 0}, @@ -2015,6 +2016,7 @@ {31, 0}, {30, 0}, {29, 0}, + {29, 0}, {1, "is"}, {312, 0}, {18, 0}, @@ -2062,6 +2064,6 @@ grammar _PyParser_Grammar = { 81, dfas, - {167, labels}, + {168, labels}, 256 }; Modified: python/branches/py3k-short-float-repr/Python/import.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/import.c (original) +++ python/branches/py3k-short-float-repr/Python/import.c Sun Apr 5 01:04:14 2009 @@ -3023,13 +3023,21 @@ int fd = PyObject_AsFileDescriptor(fob); if (fd == -1) return NULL; - /* XXX This will leak a FILE struct. Fix this!!!! - (But it doesn't leak a file descrioptor!) */ + if (!_PyVerify_fd(fd)) + goto error; + /* the FILE struct gets a new fd, so that it can be closed + * independently of the file descriptor given + */ + fd = dup(fd); + if (fd == -1) + goto error; fp = fdopen(fd, mode); } - if (fp == NULL) - PyErr_SetFromErrno(PyExc_IOError); - return fp; + if (fp) + return fp; +error: + PyErr_SetFromErrno(PyExc_IOError); + return NULL; } static PyObject * @@ -3040,15 +3048,19 @@ PyObject *fob = NULL; PyObject *m; FILE *fp; - if (!PyArg_ParseTuple(args, "ss|O:load_compiled", - &name, &pathname, &fob)) + if (!PyArg_ParseTuple(args, "ses|O:load_compiled", + &name, + Py_FileSystemDefaultEncoding, &pathname, + &fob)) return NULL; fp = get_file(pathname, fob, "rb"); - if (fp == NULL) + if (fp == NULL) { + PyMem_Free(pathname); return NULL; + } m = load_compiled_module(name, pathname, fp); - if (fob == NULL) - fclose(fp); + fclose(fp); + PyMem_Free(pathname); return m; } @@ -3062,15 +3074,22 @@ PyObject *fob = NULL; PyObject *m; FILE *fp = NULL; - if (!PyArg_ParseTuple(args, "ss|O:load_dynamic", - &name, &pathname, &fob)) + if (!PyArg_ParseTuple(args, "ses|O:load_dynamic", + &name, + Py_FileSystemDefaultEncoding, &pathname, + &fob)) return NULL; if (fob) { fp = get_file(pathname, fob, "r"); - if (fp == NULL) + if (fp == NULL) { + PyMem_Free(pathname); return NULL; + } } m = _PyImport_LoadDynamicModule(name, pathname, fp); + PyMem_Free(pathname); + if (fp) + fclose(fp); return m; } @@ -3084,15 +3103,19 @@ PyObject *fob = NULL; PyObject *m; FILE *fp; - if (!PyArg_ParseTuple(args, "ss|O:load_source", - &name, &pathname, &fob)) + if (!PyArg_ParseTuple(args, "ses|O:load_source", + &name, + Py_FileSystemDefaultEncoding, &pathname, + &fob)) return NULL; fp = get_file(pathname, fob, "r"); - if (fp == NULL) + if (fp == NULL) { + PyMem_Free(pathname); return NULL; + } m = load_source_module(name, pathname, fp); - if (fob == NULL) - fclose(fp); + PyMem_Free(pathname); + fclose(fp); return m; } @@ -3102,13 +3125,15 @@ char *name; PyObject *fob; char *pathname; + PyObject * ret; char *suffix; /* Unused */ char *mode; int type; FILE *fp; - if (!PyArg_ParseTuple(args, "sOs(ssi):load_module", - &name, &fob, &pathname, + if (!PyArg_ParseTuple(args, "sOes(ssi):load_module", + &name, &fob, + Py_FileSystemDefaultEncoding, &pathname, &suffix, &mode, &type)) return NULL; if (*mode) { @@ -3119,6 +3144,7 @@ if (!(*mode == 'r' || *mode == 'U') || strchr(mode, '+')) { PyErr_Format(PyExc_ValueError, "invalid file open mode %.200s", mode); + PyMem_Free(pathname); return NULL; } } @@ -3126,10 +3152,16 @@ fp = NULL; else { fp = get_file(NULL, fob, mode); - if (fp == NULL) + if (fp == NULL) { + PyMem_Free(pathname); return NULL; - } - return load_module(name, fp, pathname, type, NULL); + } + } + ret = load_module(name, fp, pathname, type, NULL); + PyMem_Free(pathname); + if (fp) + fclose(fp); + return ret; } static PyObject * @@ -3137,9 +3169,13 @@ { char *name; char *pathname; - if (!PyArg_ParseTuple(args, "ss:load_package", &name, &pathname)) + PyObject * ret; + if (!PyArg_ParseTuple(args, "ses:load_package", + &name, Py_FileSystemDefaultEncoding, &pathname)) return NULL; - return load_package(name, pathname); + ret = load_package(name, pathname); + PyMem_Free(pathname); + return ret; } static PyObject * @@ -3452,13 +3488,13 @@ /* Shorthand to add a single entry given a name and a function */ int -PyImport_AppendInittab(char *name, PyObject* (*initfunc)(void)) +PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void)) { struct _inittab newtab[2]; memset(newtab, '\0', sizeof newtab); - newtab[0].name = name; + newtab[0].name = (char *)name; newtab[0].initfunc = initfunc; return PyImport_ExtendInittab(newtab); Modified: python/branches/py3k-short-float-repr/Python/modsupport.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/modsupport.c (original) +++ python/branches/py3k-short-float-repr/Python/modsupport.c Sun Apr 5 01:04:14 2009 @@ -289,7 +289,7 @@ { char p[1]; p[0] = (char)va_arg(*p_va, int); - return PyUnicode_FromStringAndSize(p, 1); + return PyBytes_FromStringAndSize(p, 1); } case 'C': { Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Sun Apr 5 01:04:14 2009 @@ -378,7 +378,7 @@ /* At this point, p points just past the right-most character we want to format. We need to add the grouping string for the characters between buffer and p. */ - return _PyBytes_InsertThousandsGrouping(buffer, len, p-buffer, + return _PyBytes_InsertThousandsGroupingLocale(buffer, len, p-buffer, buf_size, NULL, 1); } Modified: python/branches/py3k-short-float-repr/Python/pythonrun.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pythonrun.c (original) +++ python/branches/py3k-short-float-repr/Python/pythonrun.c Sun Apr 5 01:04:14 2009 @@ -1011,6 +1011,8 @@ parser_flags |= PyPARSE_DONT_IMPLY_DEDENT; if (flags->cf_flags & PyCF_IGNORE_COOKIE) parser_flags |= PyPARSE_IGNORE_COOKIE; + if (flags->cf_flags & CO_FUTURE_BARRY_AS_BDFL) + parser_flags |= PyPARSE_BARRY_AS_BDFL; return parser_flags; } @@ -1143,7 +1145,7 @@ { PyObject *m, *d, *v; const char *ext; - int set_file_name = 0, ret; + int set_file_name = 0, ret, len; m = PyImport_AddModule("__main__"); if (m == NULL) @@ -1161,7 +1163,8 @@ set_file_name = 1; Py_DECREF(f); } - ext = filename + strlen(filename) - 4; + len = strlen(filename); + ext = filename + len - (len > 4 ? 4 : 0); if (maybe_pyc_file(fp, filename, ext, closeit)) { /* Try to run a pyc file. First, re-open in binary */ if (closeit) @@ -2006,6 +2009,7 @@ Py_FatalError(const char *msg) { fprintf(stderr, "Fatal Python error: %s\n", msg); + fflush(stderr); /* it helps in Windows debug build */ if (PyErr_Occurred()) { PyErr_Print(); } Modified: python/branches/py3k-short-float-repr/Python/symtable.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/symtable.c (original) +++ python/branches/py3k-short-float-repr/Python/symtable.c Sun Apr 5 01:04:14 2009 @@ -377,8 +377,9 @@ /* Decide on scope of name, given flags. - The dicts passed in as arguments are modified as necessary. - ste is passed so that flags can be updated. + The namespace dictionaries may be modified to record information + about the new name. For example, a new global will add an entry to + global. A name that was global can be changed to local. */ static int @@ -454,7 +455,7 @@ explicit? It could also be global implicit. */ if (global && PySet_Contains(global, name)) { - SET_SCOPE(scopes, name, GLOBAL_EXPLICIT); + SET_SCOPE(scopes, name, GLOBAL_IMPLICIT); return 1; } if (ste->ste_nested) @@ -628,28 +629,56 @@ } /* Make final symbol table decisions for block of ste. + Arguments: ste -- current symtable entry (input/output) - bound -- set of variables bound in enclosing scopes (input) + bound -- set of variables bound in enclosing scopes (input). bound + is NULL for module blocks. free -- set of free variables in enclosed scopes (output) globals -- set of declared global variables in enclosing scopes (input) + + The implementation uses two mutually recursive functions, + analyze_block() and analyze_child_block(). analyze_block() is + responsible for analyzing the individual names defined in a block. + analyze_child_block() prepares temporary namespace dictionaries + used to evaluated nested blocks. + + The two functions exist because a child block should see the name + bindings of its enclosing blocks, but those bindings should not + propagate back to a parent block. */ static int +analyze_child_block(PySTEntryObject *entry, PyObject *bound, PyObject *free, + PyObject *global, PyObject* child_free); + +static int analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free, PyObject *global) { PyObject *name, *v, *local = NULL, *scopes = NULL, *newbound = NULL; - PyObject *newglobal = NULL, *newfree = NULL; + PyObject *newglobal = NULL, *newfree = NULL, *allfree = NULL; int i, success = 0; Py_ssize_t pos = 0; - scopes = PyDict_New(); - if (!scopes) - goto error; - local = PySet_New(NULL); + local = PySet_New(NULL); /* collect new names bound in block */ if (!local) goto error; + scopes = PyDict_New(); /* collect scopes defined for each name */ + if (!scopes) + goto error; + + /* Allocate new global and bound variable dictionaries. These + dictionaries hold the names visible in nested blocks. For + ClassBlocks, the bound and global names are initialized + before analyzing names, because class bindings aren't + visible in methods. For other blocks, they are initialized + after names are analyzed. + */ + + /* TODO(jhylton): Package these dicts in a struct so that we + can write reasonable helper functions? + */ newglobal = PySet_New(NULL); if (!newglobal) goto error; @@ -666,25 +695,22 @@ this one. */ if (ste->ste_type == ClassBlock) { + /* Pass down known globals */ + if (!PyNumber_InPlaceOr(newglobal, global)) + goto error; + Py_DECREF(newglobal); /* Pass down previously bound symbols */ if (bound) { if (!PyNumber_InPlaceOr(newbound, bound)) goto error; Py_DECREF(newbound); } - /* Pass down known globals */ - if (!PyNumber_InPlaceOr(newglobal, global)) - goto error; - Py_DECREF(newglobal); } - /* Analyze symbols in current scope */ - assert(PySTEntry_Check(ste)); - assert(PyDict_Check(ste->ste_symbols)); while (PyDict_Next(ste->ste_symbols, &pos, &name, &v)) { long flags = PyLong_AS_LONG(v); - if (!analyze_name(ste, scopes, name, flags, bound, local, free, - global)) + if (!analyze_name(ste, scopes, name, flags, + bound, local, free, global)) goto error; } @@ -716,19 +742,32 @@ goto error; } - /* Recursively call analyze_block() on each child block */ + /* Recursively call analyze_block() on each child block. + + newbound, newglobal now contain the names visible in + nested blocks. The free variables in the children will + be collected in allfree. + */ + allfree = PySet_New(NULL); + if (!allfree) + goto error; for (i = 0; i < PyList_GET_SIZE(ste->ste_children); ++i) { PyObject *c = PyList_GET_ITEM(ste->ste_children, i); PySTEntryObject* entry; assert(c && PySTEntry_Check(c)); entry = (PySTEntryObject*)c; - if (!analyze_block(entry, newbound, newfree, newglobal)) + if (!analyze_child_block(entry, newbound, newfree, newglobal, + allfree)) goto error; /* Check if any children have free variables */ if (entry->ste_free || entry->ste_child_free) ste->ste_child_free = 1; } + if (PyNumber_InPlaceOr(newfree, allfree) < 0) + goto error; + Py_DECREF(newfree); + /* Check if any local variables must be converted to cell variables */ if (ste->ste_type == FunctionBlock && !analyze_cells(scopes, newfree, NULL)) @@ -753,12 +792,52 @@ Py_XDECREF(newbound); Py_XDECREF(newglobal); Py_XDECREF(newfree); + Py_XDECREF(allfree); if (!success) assert(PyErr_Occurred()); return success; } static int +analyze_child_block(PySTEntryObject *entry, PyObject *bound, PyObject *free, + PyObject *global, PyObject* child_free) +{ + PyObject *temp_bound = NULL, *temp_global = NULL, *temp_free = NULL; + + /* Copy the bound and global dictionaries. + + These dictionary are used by all blocks enclosed by the + current block. The analyze_block() call modifies these + dictionaries. + + */ + temp_bound = PySet_New(bound); + if (!temp_bound) + goto error; + temp_free = PySet_New(free); + if (!temp_free) + goto error; + temp_global = PySet_New(global); + if (!temp_global) + goto error; + + if (!analyze_block(entry, temp_bound, temp_free, temp_global)) + goto error; + if (PyNumber_InPlaceOr(child_free, temp_free) < 0) + goto error; + Py_DECREF(child_free); + Py_DECREF(temp_bound); + Py_DECREF(temp_free); + Py_DECREF(temp_global); + return 1; + error: + Py_XDECREF(temp_bound); + Py_XDECREF(temp_free); + Py_XDECREF(temp_global); + return 0; +} + +static int symtable_analyze(struct symtable *st) { PyObject *free, *global; Modified: python/branches/py3k-short-float-repr/README ============================================================================== --- python/branches/py3k-short-float-repr/README (original) +++ python/branches/py3k-short-float-repr/README Sun Apr 5 01:04:14 2009 @@ -1,7 +1,6 @@ -This is Python version 3.1 alpha 1 +This is Python version 3.1 alpha 2 ================================== -For notes specific to this release, see RELNOTES in this directory. Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Python Software Foundation. All rights reserved. @@ -12,10 +11,6 @@ changed considerably, and a lot of deprecated features have finally been removed. -This is an ongoing project; the cleanup isn't expected to be complete -until some time in 2008. In particular there are plans to reorganize -the standard library namespace. - Release Schedule ---------------- Deleted: python/branches/py3k-short-float-repr/RELNOTES ============================================================================== --- python/branches/py3k-short-float-repr/RELNOTES Sun Apr 5 01:04:14 2009 +++ (empty file) @@ -1,29 +0,0 @@ -Python 3 Release Notes -====================== - -These release notes describe unfinished work, or important notes that Python 3 -adopters need to be aware of. This is not a complete list of changes for -Python 3 -- for that, see Misc/NEWS. - -Please report bugs to http://bugs.python.org/ - -The list of all known open issues for Python 3 can be found here: - -http://bugs.python.org/issue?%40search_text=&title=&%40columns=title&id=&%40columns=id&creation=&creator=&activity=&%40columns=activity&%40sort=activity&actor=&nosy=&type=&components=&versions=12&dependencies=&assignee=&keywords=&priority=&%40group=priority&status=1&%40columns=status&resolution=&%40pagesize=50&%40startwith=0&%40queryname=&%40old-queryname=&%40action=search - - -Additional notes for Python 3 ------------------------------ - -* The bsddb3 package has been removed from the standard library. It is - available as a separate distutils based package from the Python Cheeseshop. - If you need bsddb3 support in Python 3, you can find it here: - - http://pypi.python.org/pypi/bsddb3 - -* The email package needs quite a bit of work to make it consistent with - respect to bytes and strings. There have been discussions on - email-sig at python.org about where to go with the email package for Python 3, - but this was not resolved in time for 3.0 final. With enough care though, - the email package in Python 3 should be about as usable as it is with Python - 2. Modified: python/branches/py3k-short-float-repr/Tools/buildbot/test.bat ============================================================================== --- python/branches/py3k-short-float-repr/Tools/buildbot/test.bat (original) +++ python/branches/py3k-short-float-repr/Tools/buildbot/test.bat Sun Apr 5 01:04:14 2009 @@ -1,4 +1,4 @@ @rem Used by the buildbot "test" step. cd PCbuild -call rt.bat -d -q -uall -rw +call rt.bat -d -q -uall -rw -n Modified: python/branches/py3k-short-float-repr/Tools/msi/msi.py ============================================================================== --- python/branches/py3k-short-float-repr/Tools/msi/msi.py (original) +++ python/branches/py3k-short-float-repr/Tools/msi/msi.py Sun Apr 5 01:04:14 2009 @@ -1013,6 +1013,7 @@ lib.glob("*.pem") lib.glob("*.pck") lib.add_file("readme.txt", src="README") + lib.add_file("zipdir.zip") if dir=='decimaltestdata': lib.glob("*.decTest") if dir=='output': Modified: python/branches/py3k-short-float-repr/Tools/msi/msilib.py ============================================================================== --- python/branches/py3k-short-float-repr/Tools/msi/msilib.py (original) +++ python/branches/py3k-short-float-repr/Tools/msi/msilib.py Sun Apr 5 01:04:14 2009 @@ -5,7 +5,7 @@ import win32com.client import pythoncom, pywintypes from win32com.client import constants -import re, string, os, sets, glob, subprocess, sys, _winreg, struct +import re, string, os, sets, glob, subprocess, sys, winreg, struct try: basestring @@ -387,9 +387,9 @@ (r"Software\Microsoft\Win32SDK\Directories", "Install Dir"), ]: try: - key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, k) - dir = _winreg.QueryValueEx(key, v)[0] - _winreg.CloseKey(key) + key = winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, k) + dir = winreg.QueryValueEx(key, v)[0] + winreg.CloseKey(key) except (WindowsError, IndexError): continue cabarc = os.path.join(dir, r"Bin", "cabarc.exe") Modified: python/branches/py3k-short-float-repr/Tools/scripts/reindent-rst.py ============================================================================== --- python/branches/py3k-short-float-repr/Tools/scripts/reindent-rst.py (original) +++ python/branches/py3k-short-float-repr/Tools/scripts/reindent-rst.py Sun Apr 5 01:04:14 2009 @@ -3,7 +3,7 @@ # Make a reST file compliant to our pre-commit hook. # Currently just remove trailing whitespace. -from __future__ import with_statement + import sys, re, shutil ws_re = re.compile(r'\s+(\r?\n)$') @@ -16,12 +16,12 @@ lines = f.readlines() new_lines = [ws_re.sub(r'\1', line) for line in lines] if new_lines != lines: - print 'Fixing %s...' % filename + print('Fixing %s...' % filename) shutil.copyfile(filename, filename + '.bak') with open(filename, 'wb') as f: f.writelines(new_lines) - except Exception, err: - print 'Cannot fix %s: %s' % (filename, err) + except Exception as err: + print('Cannot fix %s: %s' % (filename, err)) rv = 1 return rv Modified: python/branches/py3k-short-float-repr/setup.py ============================================================================== --- python/branches/py3k-short-float-repr/setup.py (original) +++ python/branches/py3k-short-float-repr/setup.py Sun Apr 5 01:04:14 2009 @@ -1023,6 +1023,15 @@ ) libraries = [] + elif platform.startswith('netbsd'): + macros = dict( # at least NetBSD 5 + HAVE_SEM_OPEN=1, + HAVE_SEM_TIMEDWAIT=0, + HAVE_FD_TRANSFER=1, + HAVE_BROKEN_SEM_GETVALUE=1 + ) + libraries = [] + else: # Linux and other unices macros = dict( HAVE_SEM_OPEN=1, From python-checkins at python.org Sun Apr 5 01:16:41 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 5 Apr 2009 01:16:41 +0200 (CEST) Subject: [Python-checkins] r71202 - in python/branches/py3k: Include/patchlevel.h Misc/NEWS Message-ID: <20090404231641.AA4101E42CD@bag.python.org> Author: benjamin.peterson Date: Sun Apr 5 01:16:41 2009 New Revision: 71202 Log: bump version for 3.1a2+ Modified: python/branches/py3k/Include/patchlevel.h python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Include/patchlevel.h ============================================================================== --- python/branches/py3k/Include/patchlevel.h (original) +++ python/branches/py3k/Include/patchlevel.h Sun Apr 5 01:16:41 2009 @@ -23,7 +23,7 @@ #define PY_RELEASE_SERIAL 2 /* Version as a string */ -#define PY_VERSION "3.1a2" +#define PY_VERSION "3.1a2+" /*--end constants--*/ /* Subversion Revision number of this file (not of the repository) */ Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Apr 5 01:16:41 2009 @@ -4,6 +4,18 @@ (editors: check NEWS.help for information about editing NEWS using ReST.) +What's New in Python 3.1 beta 1? +================================ + +*Release date: XXXX-XX-XX* + +Core and Builtins +----------------- + +Library +------- + + What's New in Python 3.1 alpha 2? ================================= From buildbot at python.org Sun Apr 5 01:26:57 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 23:26:57 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 3.x Message-ID: <20090404232658.372321E4073@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%20gentoo%203.x/builds/577 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-amd64 Build Reason: The web-page 'force build' button was pressed by 'Eric Smith': Test repr change branch Build Source Stamp: [branch branches/py3k-short-float-repr] HEAD Blamelist: BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_unicode test_userstring ====================================================================== ERROR: test_floatformatting (test.test_unicode.UnicodeTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/string_tests.py", line 1115, in test_floatformatting self.checkcall(format, "__mod__", value) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/string_tests.py", line 86, in checkcall getattr(obj, methodname)(*args) MemoryError ====================================================================== ERROR: test_floatformatting (test.test_userstring.UserStringTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/string_tests.py", line 1115, in test_floatformatting self.checkcall(format, "__mod__", value) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_userstring.py", line 42, in checkcall getattr(object, methodname)(*args) File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/collections.py", line 684, in __mod__ return self.__class__(self.data % args) MemoryError make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sun Apr 5 01:46:34 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 5 Apr 2009 01:46:34 +0200 (CEST) Subject: [Python-checkins] r71203 - python/trunk/Doc/library/stdtypes.rst Message-ID: <20090404234634.C46FE1E4073@bag.python.org> Author: benjamin.peterson Date: Sun Apr 5 01:46:34 2009 New Revision: 71203 Log: note how using iter* are unsafe while mutating and document iter(dict) Modified: python/trunk/Doc/library/stdtypes.rst Modified: python/trunk/Doc/library/stdtypes.rst ============================================================================== --- python/trunk/Doc/library/stdtypes.rst (original) +++ python/trunk/Doc/library/stdtypes.rst Sun Apr 5 01:46:34 2009 @@ -1928,6 +1928,11 @@ .. versionadded:: 2.2 + .. describe:: iter(d) + + Return an iterator over the keys of the dictionary. This is a shortcut + for :meth:`iterkeys`. + .. method:: clear() Remove all items from the dictionary. @@ -1980,6 +1985,9 @@ Return an iterator over the dictionary's ``(key, value)`` pairs. See the note for :meth:`dict.items`. + Using :meth:`iteritems` while adding or deleting entries in the dictionary + will raise a :exc:`RuntimeError`. + .. versionadded:: 2.2 .. method:: iterkeys() @@ -1987,6 +1995,9 @@ Return an iterator over the dictionary's keys. See the note for :meth:`dict.items`. + Using :meth:`iterkeys` while adding or deleting entries in the dictionary + will raise a :exc:`RuntimeError`. + .. versionadded:: 2.2 .. method:: itervalues() @@ -1994,6 +2005,9 @@ Return an iterator over the dictionary's values. See the note for :meth:`dict.items`. + Using :meth:`itervalues` while adding or deleting entries in the + dictionary will raise a :exc:`RuntimeError`. + .. versionadded:: 2.2 .. method:: keys() From buildbot at python.org Sun Apr 5 01:52:36 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 04 Apr 2009 23:52:36 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 3.x Message-ID: <20090404235236.ADE611E4073@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%203.x/builds/572 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: The web-page 'force build' button was pressed by 'Eric Smith': Test repr change branch Build Source Stamp: [branch branches/py3k-short-float-repr] HEAD Blamelist: BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_unicode test_userstring ====================================================================== ERROR: test_floatformatting (test.test_unicode.UnicodeTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/test/string_tests.py", line 1115, in test_floatformatting self.checkcall(format, "__mod__", value) File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/test/string_tests.py", line 86, in checkcall getattr(obj, methodname)(*args) MemoryError ====================================================================== ERROR: test_floatformatting (test.test_userstring.UserStringTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/test/string_tests.py", line 1115, in test_floatformatting self.checkcall(format, "__mod__", value) File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/test/test_userstring.py", line 42, in checkcall getattr(object, methodname)(*args) File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/collections.py", line 684, in __mod__ return self.__class__(self.data % args) MemoryError make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sun Apr 5 01:58:20 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 5 Apr 2009 01:58:20 +0200 (CEST) Subject: [Python-checkins] r71204 - in python/branches/release26-maint: Doc/library/stdtypes.rst Message-ID: <20090404235820.1B4CB1E4462@bag.python.org> Author: benjamin.peterson Date: Sun Apr 5 01:58:19 2009 New Revision: 71204 Log: Merged revisions 71203 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71203 | benjamin.peterson | 2009-04-04 18:46:34 -0500 (Sat, 04 Apr 2009) | 1 line note how using iter* are unsafe while mutating and document iter(dict) ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/stdtypes.rst Modified: python/branches/release26-maint/Doc/library/stdtypes.rst ============================================================================== --- python/branches/release26-maint/Doc/library/stdtypes.rst (original) +++ python/branches/release26-maint/Doc/library/stdtypes.rst Sun Apr 5 01:58:19 2009 @@ -1897,6 +1897,11 @@ .. versionadded:: 2.2 + .. describe:: iter(d) + + Return an iterator over the keys of the dictionary. This is a shortcut + for :meth:`iterkeys`. + .. method:: clear() Remove all items from the dictionary. @@ -1949,6 +1954,9 @@ Return an iterator over the dictionary's ``(key, value)`` pairs. See the note for :meth:`dict.items`. + Using :meth:`iteritems` while adding or deleting entries in the dictionary + will raise a :exc:`RuntimeError`. + .. versionadded:: 2.2 .. method:: iterkeys() @@ -1956,6 +1964,9 @@ Return an iterator over the dictionary's keys. See the note for :meth:`dict.items`. + Using :meth:`iterkeys` while adding or deleting entries in the dictionary + will raise a :exc:`RuntimeError`. + .. versionadded:: 2.2 .. method:: itervalues() @@ -1963,6 +1974,9 @@ Return an iterator over the dictionary's values. See the note for :meth:`dict.items`. + Using :meth:`itervalues` while adding or deleting entries in the + dictionary will raise a :exc:`RuntimeError`. + .. versionadded:: 2.2 .. method:: keys() From buildbot at python.org Sun Apr 5 02:17:06 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 05 Apr 2009 00:17:06 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090405001707.35DBA1E4073@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/482 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson BUILD FAILED: failed test Excerpt from the test logfile: 3 tests failed: test_import test_posix test_smtplib ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 249, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 102, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Sun Apr 5 02:46:27 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 5 Apr 2009 02:46:27 +0200 (CEST) Subject: [Python-checkins] r71205 - python/branches/py3k/Modules/_io/_iomodule.c Message-ID: <20090405004627.5AE5A1E441A@bag.python.org> Author: benjamin.peterson Date: Sun Apr 5 02:46:27 2009 New Revision: 71205 Log: fix typo #5687 Modified: python/branches/py3k/Modules/_io/_iomodule.c Modified: python/branches/py3k/Modules/_io/_iomodule.c ============================================================================== --- python/branches/py3k/Modules/_io/_iomodule.c (original) +++ python/branches/py3k/Modules/_io/_iomodule.c Sun Apr 5 02:46:27 2009 @@ -60,7 +60,7 @@ "allowed to throw an IOError if they do not support a given operation.\n" "\n" "Extending IOBase is RawIOBase which deals simply with the reading and\n" -"writing of raw bytes to a stream. FileIO subc lasses RawIOBase to provide\n" +"writing of raw bytes to a stream. FileIO subclasses RawIOBase to provide\n" "an interface to OS files.\n" "\n" "BufferedIOBase deals with buffering on a raw byte stream (RawIOBase). Its\n" From python-checkins at python.org Sun Apr 5 03:04:38 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 5 Apr 2009 03:04:38 +0200 (CEST) Subject: [Python-checkins] r71206 - python/trunk/Lib/pickle.py Message-ID: <20090405010438.D6A621E4073@bag.python.org> Author: benjamin.peterson Date: Sun Apr 5 03:04:38 2009 New Revision: 71206 Log: compare types with is Modified: python/trunk/Lib/pickle.py Modified: python/trunk/Lib/pickle.py ============================================================================== --- python/trunk/Lib/pickle.py (original) +++ python/trunk/Lib/pickle.py Sun Apr 5 03:04:38 2009 @@ -501,7 +501,7 @@ self.memoize(obj) dispatch[UnicodeType] = save_unicode - if StringType == UnicodeType: + if StringType is UnicodeType: # This is true for Jython def save_string(self, obj, pack=struct.pack): unicode = obj.isunicode() From python-checkins at python.org Sun Apr 5 03:13:10 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 5 Apr 2009 03:13:10 +0200 (CEST) Subject: [Python-checkins] r71207 - python/branches/py3k Message-ID: <20090405011310.CE95C1E4073@bag.python.org> Author: benjamin.peterson Date: Sun Apr 5 03:13:10 2009 New Revision: 71207 Log: Blocked revisions 71206 via svnmerge ........ r71206 | benjamin.peterson | 2009-04-04 20:04:38 -0500 (Sat, 04 Apr 2009) | 1 line compare types with is ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sun Apr 5 03:15:02 2009 From: python-checkins at python.org (michael.foord) Date: Sun, 5 Apr 2009 03:15:02 +0200 (CEST) Subject: [Python-checkins] r71208 - python/trunk/Lib/unittest.py Message-ID: <20090405011502.29FBD1E4073@bag.python.org> Author: michael.foord Date: Sun Apr 5 03:15:01 2009 New Revision: 71208 Log: Change the way unittest.TestSuite use their tests to always access them through iteration. Non behavior changing, this allows you to create custom subclasses that override __iter__. Issue #5693 Modified: python/trunk/Lib/unittest.py Modified: python/trunk/Lib/unittest.py ============================================================================== --- python/trunk/Lib/unittest.py (original) +++ python/trunk/Lib/unittest.py Sun Apr 5 03:15:01 2009 @@ -998,7 +998,7 @@ self.addTests(tests) def __repr__(self): - return "<%s tests=%s>" % (_strclass(self.__class__), self._tests) + return "<%s tests=%s>" % (_strclass(self.__class__), list(self)) def __eq__(self, other): if not isinstance(other, self.__class__): @@ -1016,7 +1016,7 @@ def countTestCases(self): cases = 0 - for test in self._tests: + for test in self: cases += test.countTestCases() return cases @@ -1036,7 +1036,7 @@ self.addTest(test) def run(self, result): - for test in self._tests: + for test in self: if result.shouldStop: break test(result) @@ -1047,7 +1047,7 @@ def debug(self): """Run the tests without collecting errors in a TestResult""" - for test in self._tests: + for test in self: test.debug() From python-checkins at python.org Sun Apr 5 03:30:03 2009 From: python-checkins at python.org (alexandre.vassalotti) Date: Sun, 5 Apr 2009 03:30:03 +0200 (CEST) Subject: [Python-checkins] r71209 - python/branches/py3k/Modules/_tkinter.c Message-ID: <20090405013003.219E31E4049@bag.python.org> Author: alexandre.vassalotti Date: Sun Apr 5 03:30:02 2009 New Revision: 71209 Log: Initialize the tk_init_failed static variable to 0. Modified: python/branches/py3k/Modules/_tkinter.c Modified: python/branches/py3k/Modules/_tkinter.c ============================================================================== --- python/branches/py3k/Modules/_tkinter.c (original) +++ python/branches/py3k/Modules/_tkinter.c Sun Apr 5 03:30:02 2009 @@ -281,7 +281,7 @@ static PyObject *trbInCmd; #ifdef TKINTER_PROTECT_LOADTK -static int tk_load_failed; +static int tk_load_failed = 0; #endif From python-checkins at python.org Sun Apr 5 04:11:19 2009 From: python-checkins at python.org (guilherme.polo) Date: Sun, 5 Apr 2009 04:11:19 +0200 (CEST) Subject: [Python-checkins] r71210 - in python/trunk/Modules: _tkinter.c tkinter.h Message-ID: <20090405021119.D75431E44EE@bag.python.org> Author: guilherme.polo Date: Sun Apr 5 04:11:19 2009 New Revision: 71210 Log: Include tkinter.h only after including tk.h (or the equivalent for another platform). Modified: python/trunk/Modules/_tkinter.c python/trunk/Modules/tkinter.h Modified: python/trunk/Modules/_tkinter.c ============================================================================== --- python/trunk/Modules/_tkinter.c (original) +++ python/trunk/Modules/_tkinter.c Sun Apr 5 04:11:19 2009 @@ -33,8 +33,6 @@ #include #endif -#include "tkinter.h" - /* Allow using this code in Python 2.[12] */ #ifndef PyDoc_STRVAR #define PyDoc_STRVAR(name,str) static char name[] = str @@ -69,6 +67,8 @@ #include #endif +#include "tkinter.h" + /* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */ #ifndef CONST84_RETURN #define CONST84_RETURN Modified: python/trunk/Modules/tkinter.h ============================================================================== --- python/trunk/Modules/tkinter.h (original) +++ python/trunk/Modules/tkinter.h Sun Apr 5 04:11:19 2009 @@ -2,7 +2,9 @@ #define TKINTER_H /* This header is used to share some macros between _tkinter.c and - * tkappinit.c */ + * tkappinit.c. + * Be sure to include tk.h before including this header so + * TK_VERSION_HEX is properly defined. */ /* TK_RELEASE_LEVEL is always one of the following: * TCL_ALPHA_RELEASE 0 From buildbot at python.org Sun Apr 5 05:13:17 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 05 Apr 2009 03:13:17 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090405031318.01A251E40A4@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/484 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: alexandre.vassalotti,benjamin.peterson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 249, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 102, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Sun Apr 5 12:16:09 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 5 Apr 2009 12:16:09 +0200 (CEST) Subject: [Python-checkins] r71211 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090405101609.C43381E4012@bag.python.org> Author: mark.dickinson Date: Sun Apr 5 12:16:09 2009 New Revision: 71211 Log: Remove much of the #ifdef stuff in Gay's code. In detail --------- Assume: that we're using IEEE 754 floating-point with the usual round-half-to-even rounding, that divisions are accurate, that our float.h contains everything that C89 says it should. We don't want: K&R headers, Hex nans, Hex floats, correct setting of the inexact flag, rounding to respect FPU rounding mode. We *do* want: errno to be set appropriately, checks for infinities and nans. Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Sun Apr 5 12:16:09 2009 @@ -221,22 +221,10 @@ #include "stdlib.h" #include "string.h" -#ifdef USE_LOCALE -#include "locale.h" -#endif -#ifdef Honor_FLT_ROUNDS -#ifndef Trust_FLT_ROUNDS -#include -#endif -#endif #ifdef MALLOC -#ifdef KR_headers -extern char *MALLOC(); -#else extern void *MALLOC(size_t); -#endif #else #define MALLOC malloc #endif @@ -258,50 +246,12 @@ #define IEEE_Arith #endif -#ifdef IEEE_Arith -#ifndef NO_INFNAN_CHECK #undef INFNAN_CHECK #define INFNAN_CHECK -#endif -#else -#undef INFNAN_CHECK -#define NO_STRTOD_BIGCOMP -#endif #include "errno.h" -#ifdef Bad_float_h - -#ifdef IEEE_Arith -#define DBL_DIG 15 -#define DBL_MAX_10_EXP 308 -#define DBL_MAX_EXP 1024 -#define FLT_RADIX 2 -#endif /*IEEE_Arith*/ - -#ifdef IBM -#define DBL_DIG 16 -#define DBL_MAX_10_EXP 75 -#define DBL_MAX_EXP 63 -#define FLT_RADIX 16 -#define DBL_MAX 7.2370055773322621e+75 -#endif - -#ifdef VAX -#define DBL_DIG 16 -#define DBL_MAX_10_EXP 38 -#define DBL_MAX_EXP 127 -#define FLT_RADIX 2 -#define DBL_MAX 1.7014118346046923e+38 -#endif - -#ifndef LONG_MAX -#define LONG_MAX 2147483647 -#endif - -#else /* ifndef Bad_float_h */ #include "float.h" -#endif /* Bad_float_h */ #ifndef __MATH_H__ #include "math.h" @@ -312,12 +262,8 @@ #endif #ifndef CONST -#ifdef KR_headers -#define CONST /* blank */ -#else #define CONST const #endif -#endif #if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1 #error "Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined." @@ -362,7 +308,6 @@ /* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ /* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ -#ifdef IEEE_Arith #define Exp_shift 20 #define Exp_shift1 20 #define Exp_msk1 0x100000 @@ -389,12 +334,10 @@ #define Tiny1 1 #define Quick_max 14 #define Int_max 14 -#ifndef NO_IEEE_Scale #define Avoid_Underflow #ifdef Flush_Denorm /* debugging option */ #undef Sudden_Underflow #endif -#endif #ifndef Flt_Rounds #ifdef FLT_ROUNDS @@ -404,124 +347,25 @@ #endif #endif /*Flt_Rounds*/ -#ifdef Honor_FLT_ROUNDS -#undef Check_FLT_ROUNDS -#define Check_FLT_ROUNDS -#else #define Rounding Flt_Rounds -#endif -#else /* ifndef IEEE_Arith */ -#undef Check_FLT_ROUNDS -#undef Honor_FLT_ROUNDS -#undef SET_INEXACT -#undef Sudden_Underflow -#define Sudden_Underflow -#ifdef IBM -#undef Flt_Rounds -#define Flt_Rounds 0 -#define Exp_shift 24 -#define Exp_shift1 24 -#define Exp_msk1 0x1000000 -#define Exp_msk11 0x1000000 -#define Exp_mask 0x7f000000 -#define P 14 -#define Nbits 56 -#define Bias 65 -#define Emax 248 -#define Emin (-260) -#define Exp_1 0x41000000 -#define Exp_11 0x41000000 -#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ -#define Frac_mask 0xffffff -#define Frac_mask1 0xffffff -#define Bletch 4 -#define Ten_pmax 22 -#define Bndry_mask 0xefffff -#define Bndry_mask1 0xffffff -#define LSB 1 -#define Sign_bit 0x80000000 -#define Log2P 4 -#define Tiny0 0x100000 -#define Tiny1 0 -#define Quick_max 14 -#define Int_max 15 -#else /* VAX */ -#undef Flt_Rounds -#define Flt_Rounds 1 -#define Exp_shift 23 -#define Exp_shift1 7 -#define Exp_msk1 0x80 -#define Exp_msk11 0x800000 -#define Exp_mask 0x7f80 -#define P 56 -#define Nbits 56 -#define Bias 129 -#define Emax 126 -#define Emin (-129) -#define Exp_1 0x40800000 -#define Exp_11 0x4080 -#define Ebits 8 -#define Frac_mask 0x7fffff -#define Frac_mask1 0xffff007f -#define Ten_pmax 24 -#define Bletch 2 -#define Bndry_mask 0xffff007f -#define Bndry_mask1 0xffff007f -#define LSB 0x10000 -#define Sign_bit 0x8000 -#define Log2P 1 -#define Tiny0 0x80 -#define Tiny1 0 -#define Quick_max 15 -#define Int_max 15 -#endif /* IBM, VAX */ -#endif /* IEEE_Arith */ - -#ifndef IEEE_Arith -#define ROUND_BIASED -#endif - -#ifdef RND_PRODQUOT -#define rounded_product(a,b) a = rnd_prod(a, b) -#define rounded_quotient(a,b) a = rnd_quot(a, b) -#ifdef KR_headers -extern double rnd_prod(), rnd_quot(); -#else -extern double rnd_prod(double, double), rnd_quot(double, double); -#endif -#else + + #define rounded_product(a,b) a *= b #define rounded_quotient(a,b) a /= b -#endif #define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) #define Big1 0xffffffff -#ifndef Pack_32 -#define Pack_32 -#endif typedef struct BCinfo BCinfo; struct BCinfo { int dp0, dp1, dplen, dsign, e0, inexact, nd, nd0, rounding, scale, uflchk; }; -#ifdef KR_headers -#define FFFFFFFF ((((unsigned long)0xffff)<<16)|(unsigned long)0xffff) -#else #define FFFFFFFF 0xffffffffUL -#endif #ifdef NO_LONG_LONG #undef ULLong -#ifdef Just_16 -#undef Pack_32 -/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. - * This makes some inner loops simpler and sometimes saves work - * during multiplications, but it often seems to make things slightly - * slower. Hence the default is now to store 32 bits per Long. - */ -#endif #else /* long long available */ #ifndef Llong #define Llong long long @@ -551,11 +395,7 @@ static Bigint * Balloc -#ifdef KR_headers - (k) int k; -#else (int k) -#endif { int x; Bigint *rv; @@ -592,11 +432,7 @@ static void Bfree -#ifdef KR_headers - (v) Bigint *v; -#else (Bigint *v) -#endif { if (v) { if (v->k > Kmax) @@ -619,11 +455,7 @@ static Bigint * multadd -#ifdef KR_headers - (b, m, a) Bigint *b; int m, a; -#else (Bigint *b, int m, int a) /* multiply by m and add a */ -#endif { int i, wds; #ifdef ULLong @@ -631,10 +463,8 @@ ULLong carry, y; #else ULong carry, *x, y; -#ifdef Pack_32 ULong xi, z; #endif -#endif Bigint *b1; wds = b->wds; @@ -647,17 +477,11 @@ carry = y >> 32; *x++ = y & FFFFFFFF; #else -#ifdef Pack_32 xi = *x; y = (xi & 0xffff) * m + carry; z = (xi >> 16) * m + (y >> 16); carry = z >> 16; *x++ = (z << 16) + (y & 0xffff); -#else - y = *x * m + carry; - carry = y >> 16; - *x++ = y & 0xffff; -#endif #endif } while(++i < wds); @@ -676,11 +500,7 @@ static Bigint * s2b -#ifdef KR_headers - (s, nd0, nd, y9, dplen) CONST char *s; int nd0, nd, dplen; ULong y9; -#else (CONST char *s, int nd0, int nd, ULong y9, int dplen) -#endif { Bigint *b; int i, k; @@ -688,15 +508,9 @@ x = (nd + 8) / 9; for(k = 0, y = 1; x > y; y <<= 1, k++) ; -#ifdef Pack_32 b = Balloc(k); b->x[0] = y9; b->wds = 1; -#else - b = Balloc(k+1); - b->x[0] = y9 & 0xffff; - b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; -#endif i = 9; if (9 < nd0) { @@ -714,11 +528,7 @@ static int hi0bits -#ifdef KR_headers - (x) ULong x; -#else (ULong x) -#endif { int k = 0; @@ -748,11 +558,7 @@ static int lo0bits -#ifdef KR_headers - (y) ULong *y; -#else (ULong *y) -#endif { int k; ULong x = *y; @@ -796,11 +602,7 @@ static Bigint * i2b -#ifdef KR_headers - (i) int i; -#else (int i) -#endif { Bigint *b; @@ -812,11 +614,7 @@ static Bigint * mult -#ifdef KR_headers - (a, b) Bigint *a, *b; -#else (Bigint *a, Bigint *b) -#endif { Bigint *c; int k, wa, wb, wc; @@ -826,10 +624,8 @@ ULLong carry, z; #else ULong carry, z; -#ifdef Pack_32 ULong z2; #endif -#endif if (a->wds < b->wds) { c = a; @@ -866,7 +662,6 @@ } } #else -#ifdef Pack_32 for(; xb < xbe; xb++, xc0++) { if (y = *xb & 0xffff) { x = xa; @@ -898,22 +693,6 @@ *xc = z2; } } -#else - for(; xb < xbe; xc0++) { - if (y = *xb++) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * y + *xc + carry; - carry = z >> 16; - *xc++ = z & 0xffff; - } - while(x < xae); - *xc = carry; - } - } -#endif #endif for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; c->wds = wc; @@ -924,11 +703,7 @@ static Bigint * pow5mult -#ifdef KR_headers - (b, k) Bigint *b; int k; -#else (Bigint *b, int k) -#endif { Bigint *b1, *p5, *p51; int i; @@ -981,21 +756,13 @@ static Bigint * lshift -#ifdef KR_headers - (b, k) Bigint *b; int k; -#else (Bigint *b, int k) -#endif { int i, k1, n, n1; Bigint *b1; ULong *x, *x1, *xe, z; -#ifdef Pack_32 n = k >> 5; -#else - n = k >> 4; -#endif k1 = b->k; n1 = n + b->wds + 1; for(i = b->maxwds; n1 > i; i <<= 1) @@ -1006,7 +773,6 @@ *x1++ = 0; x = b->x; xe = x + b->wds; -#ifdef Pack_32 if (k &= 0x1f) { k1 = 32 - k; z = 0; @@ -1018,19 +784,6 @@ if ((*x1 = z)) ++n1; } -#else - if (k &= 0xf) { - k1 = 16 - k; - z = 0; - do { - *x1++ = *x << k & 0xffff | z; - z = *x++ >> k1; - } - while(x < xe); - if (*x1 = z) - ++n1; - } -#endif else do *x1++ = *x++; while(x < xe); @@ -1041,11 +794,7 @@ static int cmp -#ifdef KR_headers - (a, b) Bigint *a, *b; -#else (Bigint *a, Bigint *b) -#endif { ULong *xa, *xa0, *xb, *xb0; int i, j; @@ -1075,11 +824,7 @@ static Bigint * diff -#ifdef KR_headers - (a, b) Bigint *a, *b; -#else (Bigint *a, Bigint *b) -#endif { Bigint *c; int i, wa, wb; @@ -1088,10 +833,8 @@ ULLong borrow, y; #else ULong borrow, y; -#ifdef Pack_32 ULong z; #endif -#endif i = cmp(a,b); if (!i) { @@ -1131,7 +874,6 @@ *xc++ = y & FFFFFFFF; } #else -#ifdef Pack_32 do { y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; borrow = (y & 0x10000) >> 16; @@ -1147,19 +889,6 @@ borrow = (z & 0x10000) >> 16; Storeinc(xc, z, y); } -#else - do { - y = *xa++ - *xb++ - borrow; - borrow = (y & 0x10000) >> 16; - *xc++ = y & 0xffff; - } - while(xb < xbe); - while(xa < xae) { - y = *xa++ - borrow; - borrow = (y & 0x10000) >> 16; - *xc++ = y & 0xffff; - } -#endif #endif while(!*--xc) wa--; @@ -1169,11 +898,7 @@ static double ulp -#ifdef KR_headers - (x) U *x; -#else (U *x) -#endif { Long L; U u; @@ -1184,9 +909,6 @@ if (L > 0) { #endif #endif -#ifdef IBM - L |= Exp_msk1 >> 4; -#endif word0(&u) = L; word1(&u) = 0; #ifndef Avoid_Underflow @@ -1211,21 +933,13 @@ static double b2d -#ifdef KR_headers - (a, e) Bigint *a; int *e; -#else (Bigint *a, int *e) -#endif { ULong *xa, *xa0, w, y, z; int k; U d; -#ifdef VAX - ULong d0, d1; -#else #define d0 word0(&d) #define d1 word1(&d) -#endif xa0 = a->x; xa = xa0 + a->wds; @@ -1235,7 +949,6 @@ #endif k = hi0bits(y); *e = 32 - k; -#ifdef Pack_32 if (k < Ebits) { d0 = Exp_1 | y >> (Ebits - k); w = xa > xa0 ? *--xa : 0; @@ -1252,40 +965,15 @@ d0 = Exp_1 | y; d1 = z; } -#else - if (k < Ebits + 16) { - z = xa > xa0 ? *--xa : 0; - d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; - w = xa > xa0 ? *--xa : 0; - y = xa > xa0 ? *--xa : 0; - d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - w = xa > xa0 ? *--xa : 0; - k -= Ebits + 16; - d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; - y = xa > xa0 ? *--xa : 0; - d1 = w << k + 16 | y << k; -#endif ret_d: -#ifdef VAX - word0(&d) = d0 >> 16 | d0 << 16; - word1(&d) = d1 >> 16 | d1 << 16; -#else #undef d0 #undef d1 -#endif return dval(&d); } static Bigint * d2b -#ifdef KR_headers - (d, e, bits) U *d; int *e, *bits; -#else (U *d, int *e, int *bits) -#endif { Bigint *b; int de, k; @@ -1293,34 +981,21 @@ #ifndef Sudden_Underflow int i; #endif -#ifdef VAX - ULong d0, d1; - d0 = word0(d) >> 16 | word0(d) << 16; - d1 = word1(d) >> 16 | word1(d) << 16; -#else #define d0 word0(d) #define d1 word1(d) -#endif -#ifdef Pack_32 b = Balloc(1); -#else - b = Balloc(2); -#endif x = b->x; z = d0 & Frac_mask; d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ #ifdef Sudden_Underflow de = (int)(d0 >> Exp_shift); -#ifndef IBM z |= Exp_msk11; -#endif #else if ((de = (int)(d0 >> Exp_shift))) z |= Exp_msk1; #endif -#ifdef Pack_32 if ((y = d1)) { if ((k = lo0bits(&y))) { x[0] = y | z << (32 - k); @@ -1342,70 +1017,16 @@ b->wds = 1; k += 32; } -#else - if (y = d1) { - if (k = lo0bits(&y)) - if (k >= 16) { - x[0] = y | z << 32 - k & 0xffff; - x[1] = z >> k - 16 & 0xffff; - x[2] = z >> k; - i = 2; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16 | z << 16 - k & 0xffff; - x[2] = z >> k & 0xffff; - x[3] = z >> k+16; - i = 3; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16; - x[2] = z & 0xffff; - x[3] = z >> 16; - i = 3; - } - } - else { -#ifdef DEBUG - if (!z) - Bug("Zero passed to d2b"); -#endif - k = lo0bits(&z); - if (k >= 16) { - x[0] = z; - i = 0; - } - else { - x[0] = z & 0xffff; - x[1] = z >> 16; - i = 1; - } - k += 32; - } - while(!x[i]) - --i; - b->wds = i + 1; -#endif #ifndef Sudden_Underflow if (de) { #endif -#ifdef IBM - *e = (de - Bias - (P-1) << 2) + k; - *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); -#else *e = de - Bias - (P-1) + k; *bits = P - k; -#endif #ifndef Sudden_Underflow } else { *e = de - Bias - (P-1) + 1 + k; -#ifdef Pack_32 *bits = 32*i - hi0bits(x[i-1]); -#else - *bits = (i+2)*16 - hi0bits(x[i]); -#endif } #endif return b; @@ -1415,42 +1036,20 @@ static double ratio -#ifdef KR_headers - (a, b) Bigint *a, *b; -#else (Bigint *a, Bigint *b) -#endif { U da, db; int k, ka, kb; dval(&da) = b2d(a, &ka); dval(&db) = b2d(b, &kb); -#ifdef Pack_32 k = ka - kb + 32*(a->wds - b->wds); -#else - k = ka - kb + 16*(a->wds - b->wds); -#endif -#ifdef IBM - if (k > 0) { - word0(&da) += (k >> 2)*Exp_msk1; - if (k &= 3) - dval(&da) *= 1 << k; - } - else { - k = -k; - word0(&db) += (k >> 2)*Exp_msk1; - if (k &= 3) - dval(&db) *= 1 << k; - } -#else if (k > 0) word0(&da) += k*Exp_msk1; else { k = -k; word0(&db) += k*Exp_msk1; } -#endif return dval(&da) / dval(&db); } @@ -1459,13 +1058,9 @@ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22 -#ifdef VAX - , 1e23, 1e24 -#endif }; static CONST double -#ifdef IEEE_Arith bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, #ifdef Avoid_Underflow @@ -1479,40 +1074,19 @@ /* flag unnecessarily. It leads to a song and dance at the end of strtod. */ #define Scale_Bit 0x10 #define n_bigtens 5 -#else -#ifdef IBM -bigtens[] = { 1e16, 1e32, 1e64 }; -static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; -#define n_bigtens 3 -#else -bigtens[] = { 1e16, 1e32 }; -static CONST double tinytens[] = { 1e-16, 1e-32 }; -#define n_bigtens 2 -#endif -#endif #undef Need_Hexdig #ifdef INFNAN_CHECK -#ifndef No_Hex_NaN -#define Need_Hexdig -#endif #endif #ifndef Need_Hexdig -#ifndef NO_HEX_FP -#define Need_Hexdig -#endif #endif #ifdef Need_Hexdig /*{*/ static unsigned char hexdig[256]; static void -#ifdef KR_headers -htinit(h, s, inc) unsigned char *h; unsigned char *s; int inc; -#else htinit(unsigned char *h, unsigned char *s, int inc) -#endif { int i, j; for(i = 0; (j = s[i]) !=0; i++) @@ -1520,11 +1094,7 @@ } static void -#ifdef KR_headers -hexdig_init() -#else hexdig_init(void) -#endif { #define USC (unsigned char *) htinit(hexdig, USC "0123456789", 0x10); @@ -1545,11 +1115,7 @@ static int match -#ifdef KR_headers - (sp, t) char **sp, *t; -#else (CONST char **sp, char *t) -#endif { int c, d; CONST char *s = *sp; @@ -1564,556 +1130,15 @@ return 1; } -#ifndef No_Hex_NaN - static void -hexnan -#ifdef KR_headers - (rvp, sp) U *rvp; CONST char **sp; -#else - (U *rvp, CONST char **sp) -#endif -{ - ULong c, x[2]; - CONST char *s; - int c1, havedig, udx0, xshift; - - if (!hexdig['0']) - hexdig_init(); - x[0] = x[1] = 0; - havedig = xshift = 0; - udx0 = 1; - s = *sp; - /* allow optional initial 0x or 0X */ - while((c = *(CONST unsigned char*)(s+1)) && c <= ' ') - ++s; - if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X')) - s += 2; - while((c = *(CONST unsigned char*)++s)) { - if ((c1 = hexdig[c])) - c = c1 & 0xf; - else if (c <= ' ') { - if (udx0 && havedig) { - udx0 = 0; - xshift = 1; - } - continue; - } -#ifdef GDTOA_NON_PEDANTIC_NANCHECK - else if (/*(*/ c == ')' && havedig) { - *sp = s + 1; - break; - } - else - return; /* invalid form: don't change *sp */ -#else - else { - do { - if (/*(*/ c == ')') { - *sp = s + 1; - break; - } - } while((c = *++s)); - break; - } -#endif - havedig = 1; - if (xshift) { - xshift = 0; - x[0] = x[1]; - x[1] = 0; - } - if (udx0) - x[0] = (x[0] << 4) | (x[1] >> 28); - x[1] = (x[1] << 4) | c; - } - if ((x[0] &= 0xfffff) || x[1]) { - word0(rvp) = Exp_mask | x[0]; - word1(rvp) = x[1]; - } - } -#endif /*No_Hex_NaN*/ #endif /* INFNAN_CHECK */ -#ifdef Pack_32 #define ULbits 32 #define kshift 5 #define kmask 31 -#else -#define ULbits 16 -#define kshift 4 -#define kmask 15 -#endif - -#ifndef NO_HEX_FP /*{*/ - - static void -#ifdef KR_headers -rshift(b, k) Bigint *b; int k; -#else -rshift(Bigint *b, int k) -#endif -{ - ULong *x, *x1, *xe, y; - int n; - - x = x1 = b->x; - n = k >> kshift; - if (n < b->wds) { - xe = x + b->wds; - x += n; - if (k &= kmask) { - n = 32 - k; - y = *x++ >> k; - while(x < xe) { - *x1++ = (y | (*x << n)) & 0xffffffff; - y = *x++ >> k; - } - if ((*x1 = y) !=0) - x1++; - } - else - while(x < xe) - *x1++ = *x++; - } - if ((b->wds = x1 - b->x) == 0) - b->x[0] = 0; - } - - static ULong -#ifdef KR_headers -any_on(b, k) Bigint *b; int k; -#else -any_on(Bigint *b, int k) -#endif -{ - int n, nwds; - ULong *x, *x0, x1, x2; - - x = b->x; - nwds = b->wds; - n = k >> kshift; - if (n > nwds) - n = nwds; - else if (n < nwds && (k &= kmask)) { - x1 = x2 = x[n]; - x1 >>= k; - x1 <<= k; - if (x1 != x2) - return 1; - } - x0 = x; - x += n; - while(x > x0) - if (*--x) - return 1; - return 0; - } - -enum { /* rounding values: same as FLT_ROUNDS */ - Round_zero = 0, - Round_near = 1, - Round_up = 2, - Round_down = 3 - }; - - static Bigint * -#ifdef KR_headers -increment(b) Bigint *b; -#else -increment(Bigint *b) -#endif -{ - ULong *x, *xe; - Bigint *b1; - - x = b->x; - xe = x + b->wds; - do { - if (*x < (ULong)0xffffffffL) { - ++*x; - return b; - } - *x++ = 0; - } while(x < xe); - { - if (b->wds >= b->maxwds) { - b1 = Balloc(b->k+1); - Bcopy(b1,b); - Bfree(b); - b = b1; - } - b->x[b->wds++] = 1; - } - return b; - } - - void -#ifdef KR_headers -gethex(sp, rvp, rounding, sign) - CONST char **sp; U *rvp; int rounding, sign; -#else -gethex( CONST char **sp, U *rvp, int rounding, int sign) -#endif -{ - Bigint *b; - CONST unsigned char *decpt, *s0, *s, *s1; - Long e, e1; - ULong L, lostbits, *x; - int big, denorm, esign, havedig, k, n, nbits, up, zret; -#ifdef IBM - int j; -#endif - enum { -#ifdef IEEE_Arith /*{{*/ - emax = 0x7fe - Bias - P + 1, - emin = Emin - P + 1 -#else /*}{*/ - emin = Emin - P, -#ifdef VAX - emax = 0x7ff - Bias - P + 1 -#endif -#ifdef IBM - emax = 0x7f - Bias - P -#endif -#endif /*}}*/ - }; -#ifdef USE_LOCALE - int i; -#ifdef NO_LOCALE_CACHE - const unsigned char *decimalpoint = (unsigned char*) - localeconv()->decimal_point; -#else - const unsigned char *decimalpoint; - static unsigned char *decimalpoint_cache; - if (!(s0 = decimalpoint_cache)) { - s0 = (unsigned char*)localeconv()->decimal_point; - if ((decimalpoint_cache = (unsigned char*) - MALLOC(strlen((CONST char*)s0) + 1))) { - strcpy((char*)decimalpoint_cache, (CONST char*)s0); - s0 = decimalpoint_cache; - } - } - decimalpoint = s0; -#endif -#endif - if (!hexdig['0']) - hexdig_init(); - havedig = 0; - s0 = *(CONST unsigned char **)sp + 2; - while(s0[havedig] == '0') - havedig++; - s0 += havedig; - s = s0; - decpt = 0; - zret = 0; - e = 0; - if (hexdig[*s]) - havedig++; - else { - zret = 1; -#ifdef USE_LOCALE - for(i = 0; decimalpoint[i]; ++i) { - if (s[i] != decimalpoint[i]) - goto pcheck; - } - decpt = s += i; -#else - if (*s != '.') - goto pcheck; - decpt = ++s; -#endif - if (!hexdig[*s]) - goto pcheck; - while(*s == '0') - s++; - if (hexdig[*s]) - zret = 0; - havedig = 1; - s0 = s; - } - while(hexdig[*s]) - s++; -#ifdef USE_LOCALE - if (*s == *decimalpoint && !decpt) { - for(i = 1; decimalpoint[i]; ++i) { - if (s[i] != decimalpoint[i]) - goto pcheck; - } - decpt = s += i; -#else - if (*s == '.' && !decpt) { - decpt = ++s; -#endif - while(hexdig[*s]) - s++; - }/*}*/ - if (decpt) - e = -(((Long)(s-decpt)) << 2); - pcheck: - s1 = s; - big = esign = 0; - switch(*s) { - case 'p': - case 'P': - switch(*++s) { - case '-': - esign = 1; - /* no break */ - case '+': - s++; - } - if ((n = hexdig[*s]) == 0 || n > 0x19) { - s = s1; - break; - } - e1 = n - 0x10; - while((n = hexdig[*++s]) !=0 && n <= 0x19) { - if (e1 & 0xf8000000) - big = 1; - e1 = 10*e1 + n - 0x10; - } - if (esign) - e1 = -e1; - e += e1; - } - *sp = (char*)s; - if (!havedig) - *sp = (char*)s0 - 1; - if (zret) - goto retz1; - if (big) { - if (esign) { -#ifdef IEEE_Arith - switch(rounding) { - case Round_up: - if (sign) - break; - goto ret_tiny; - case Round_down: - if (!sign) - break; - goto ret_tiny; - } -#endif - goto retz; -#ifdef IEEE_Arith - ret_tiny: -#ifndef NO_ERRNO - errno = ERANGE; -#endif - word0(rvp) = 0; - word1(rvp) = 1; - return; -#endif /* IEEE_Arith */ - } - switch(rounding) { - case Round_near: - goto ovfl1; - case Round_up: - if (!sign) - goto ovfl1; - goto ret_big; - case Round_down: - if (sign) - goto ovfl1; - goto ret_big; - } - ret_big: - word0(rvp) = Big0; - word1(rvp) = Big1; - return; - } - n = s1 - s0 - 1; - for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1) - k++; - b = Balloc(k); - x = b->x; - n = 0; - L = 0; -#ifdef USE_LOCALE - for(i = 0; decimalpoint[i+1]; ++i); -#endif - while(s1 > s0) { -#ifdef USE_LOCALE - if (*--s1 == decimalpoint[i]) { - s1 -= i; - continue; - } -#else - if (*--s1 == '.') - continue; -#endif - if (n == ULbits) { - *x++ = L; - L = 0; - n = 0; - } - L |= (hexdig[*s1] & 0x0f) << n; - n += 4; - } - *x++ = L; - b->wds = n = x - b->x; - n = ULbits*n - hi0bits(L); - nbits = Nbits; - lostbits = 0; - x = b->x; - if (n > nbits) { - n -= nbits; - if (any_on(b,n)) { - lostbits = 1; - k = n - 1; - if (x[k>>kshift] & 1 << (k & kmask)) { - lostbits = 2; - if (k > 0 && any_on(b,k)) - lostbits = 3; - } - } - rshift(b, n); - e += n; - } - else if (n < nbits) { - n = nbits - n; - b = lshift(b, n); - e -= n; - x = b->x; - } - if (e > Emax) { - ovfl: - Bfree(b); - ovfl1: -#ifndef NO_ERRNO - errno = ERANGE; -#endif - word0(rvp) = Exp_mask; - word1(rvp) = 0; - return; - } - denorm = 0; - if (e < emin) { - denorm = 1; - n = emin - e; - if (n >= nbits) { -#ifdef IEEE_Arith /*{*/ - switch (rounding) { - case Round_near: - if (n == nbits && (n < 2 || any_on(b,n-1))) - goto ret_tiny; - break; - case Round_up: - if (!sign) - goto ret_tiny; - break; - case Round_down: - if (sign) - goto ret_tiny; - } -#endif /* } IEEE_Arith */ - Bfree(b); - retz: -#ifndef NO_ERRNO - errno = ERANGE; -#endif - retz1: - rvp->d = 0.; - return; - } - k = n - 1; - if (lostbits) - lostbits = 1; - else if (k > 0) - lostbits = any_on(b,k); - if (x[k>>kshift] & 1 << (k & kmask)) - lostbits |= 2; - nbits -= n; - rshift(b,n); - e = emin; - } - if (lostbits) { - up = 0; - switch(rounding) { - case Round_zero: - break; - case Round_near: - if (lostbits & 2 - && (lostbits & 1) | (x[0] & 1)) - up = 1; - break; - case Round_up: - up = 1 - sign; - break; - case Round_down: - up = sign; - } - if (up) { - k = b->wds; - b = increment(b); - x = b->x; - if (denorm) { -#if 0 - if (nbits == Nbits - 1 - && x[nbits >> kshift] & 1 << (nbits & kmask)) - denorm = 0; /* not currently used */ -#endif - } - else if (b->wds > k - || ((n = nbits & kmask) !=0 - && hi0bits(x[k-1]) < 32-n)) { - rshift(b,1); - if (++e > Emax) - goto ovfl; - } - } - } -#ifdef IEEE_Arith - if (denorm) - word0(rvp) = b->wds > 1 ? b->x[1] & ~0x100000 : 0; - else - word0(rvp) = (b->x[1] & ~0x100000) | ((e + 0x3ff + 52) << 20); - word1(rvp) = b->x[0]; -#endif -#ifdef IBM - if ((j = e & 3)) { - k = b->x[0] & ((1 << j) - 1); - rshift(b,j); - if (k) { - switch(rounding) { - case Round_up: - if (!sign) - increment(b); - break; - case Round_down: - if (sign) - increment(b); - break; - case Round_near: - j = 1 << (j-1); - if (k & j && ((k & (j-1)) | lostbits)) - increment(b); - } - } - } - e >>= 2; - word0(rvp) = b->x[1] | ((e + 65 + 13) << 24); - word1(rvp) = b->x[0]; -#endif -#ifdef VAX - /* The next two lines ignore swap of low- and high-order 2 bytes. */ - /* word0(rvp) = (b->x[1] & ~0x800000) | ((e + 129 + 55) << 23); */ - /* word1(rvp) = b->x[0]; */ - word0(rvp) = ((b->x[1] & ~0x800000) >> 16) | ((e + 129 + 55) << 7) | (b->x[1] << 16); - word1(rvp) = (b->x[0] >> 16) | (b->x[0] << 16); -#endif - Bfree(b); - } -#endif /*}!NO_HEX_FP*/ static int -#ifdef KR_headers -dshift(b, p2) Bigint *b; int p2; -#else dshift(Bigint *b, int p2) -#endif { int rv = hi0bits(b->x[b->wds-1]) - 4; if (p2 > 0) @@ -2123,11 +1148,7 @@ static int quorem -#ifdef KR_headers - (b, S) Bigint *b, *S; -#else (Bigint *b, Bigint *S) -#endif { int n; ULong *bx, *bxe, q, *sx, *sxe; @@ -2135,10 +1156,8 @@ ULLong borrow, carry, y, ys; #else ULong borrow, carry, y, ys; -#ifdef Pack_32 ULong si, z, zs; #endif -#endif n = S->wds; #ifdef DEBUG @@ -2167,7 +1186,6 @@ borrow = y >> 32 & (ULong)1; *bx++ = y & FFFFFFFF; #else -#ifdef Pack_32 si = *sx++; ys = (si & 0xffff) * q + carry; zs = (si >> 16) * q + (ys >> 16); @@ -2177,13 +1195,6 @@ z = (*bx >> 16) - (zs & 0xffff) - borrow; borrow = (z & 0x10000) >> 16; Storeinc(bx, z, y); -#else - ys = *sx++ * q + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - *bx++ = y & 0xffff; -#endif #endif } while(sx <= sxe); @@ -2208,7 +1219,6 @@ borrow = y >> 32 & (ULong)1; *bx++ = y & FFFFFFFF; #else -#ifdef Pack_32 si = *sx++; ys = (si & 0xffff) + carry; zs = (si >> 16) + (ys >> 16); @@ -2218,13 +1228,6 @@ z = (*bx >> 16) - (zs & 0xffff) - borrow; borrow = (z & 0x10000) >> 16; Storeinc(bx, z, y); -#else - ys = *sx++ + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - *bx++ = y & 0xffff; -#endif #endif } while(sx <= sxe); @@ -2239,16 +1242,10 @@ return q; } -#ifndef NO_STRTOD_BIGCOMP static void bigcomp -#ifdef KR_headers - (rv, s0, bc) - U *rv; CONST char *s0; BCinfo *bc; -#else (U *rv, CONST char *s0, BCinfo *bc) -#endif { Bigint *b, *d; int b2, bbits, d2, dd, dig, dsign, i, j, nd, nd0, p2, p5, speccase; @@ -2270,9 +1267,6 @@ word1(rv) = 1; #endif i = 0; -#ifdef Honor_FLT_ROUNDS - if (bc->rounding == 1) -#endif { speccase = 1; --p2; @@ -2305,15 +1299,6 @@ i = j; #endif } -#ifdef Honor_FLT_ROUNDS - if (bc->rounding != 1) { - if (i > 0) - b = lshift(b, i); - if (dsign) - b = increment(b); - } - else -#endif { b = lshift(b, ++i); b->x[0] |= 1; @@ -2381,34 +1366,6 @@ ret: Bfree(b); Bfree(d); -#ifdef Honor_FLT_ROUNDS - if (bc->rounding != 1) { - if (dd < 0) { - if (bc->rounding == 0) { - if (!dsign) - goto retlow1; - } - else if (dsign) - goto rethi1; - } - else if (dd > 0) { - if (bc->rounding == 0) { - if (dsign) - goto rethi1; - goto ret1; - } - if (!dsign) - goto rethi1; - dval(rv) += 2.*ulp(rv); - } - else { - bc->inexact = 0; - if (dsign) - goto rethi1; - } - } - else -#endif if (speccase) { if (dd <= 0) rv->d = 0.; @@ -2433,20 +1390,12 @@ } } -#ifdef Honor_FLT_ROUNDS - ret1: -#endif return; } -#endif /* NO_STRTOD_BIGCOMP */ double _Py_dg_strtod -#ifdef KR_headers - (s00, se) CONST char *s00; char **se; -#else (CONST char *s00, char **se) -#endif { int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1; int esign, i, j, k, nd, nd0, nf, nz, nz0, sign; @@ -2457,24 +1406,6 @@ ULong y, z; BCinfo bc; Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; -#ifdef SET_INEXACT - int oldinexact; -#endif -#ifdef Honor_FLT_ROUNDS /*{*/ -#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ - bc.rounding = Flt_Rounds; -#else /*}{*/ - bc.rounding = 1; - switch(fegetround()) { - case FE_TOWARDZERO: bc.rounding = 0; break; - case FE_UPWARD: bc.rounding = 2; break; - case FE_DOWNWARD: bc.rounding = 3; - } -#endif /*}}*/ -#endif /*}*/ -#ifdef USE_LOCALE - CONST char *s2; -#endif sign = nz0 = nz = bc.dplen = bc.uflchk = 0; dval(&rv) = 0.; @@ -2500,18 +1431,6 @@ } break2: if (*s == '0') { -#ifndef NO_HEX_FP /*{*/ - switch(s[1]) { - case 'x': - case 'X': -#ifdef Honor_FLT_ROUNDS - gethex(&s, &rv, bc.rounding, sign); -#else - gethex(&s, &rv, 1, sign); -#endif - goto ret; - } -#endif /*}*/ nz0 = 1; while(*++s == '0') ; if (!*s) @@ -2526,25 +1445,6 @@ z = 10*z + c - '0'; nd0 = nd; bc.dp0 = bc.dp1 = s - s0; -#ifdef USE_LOCALE - s1 = localeconv()->decimal_point; - if (c == *s1) { - c = '.'; - if (*++s1) { - s2 = s; - for(;;) { - if (*++s2 != *s1) { - c = 0; - break; - } - if (!*++s1) { - s = s2; - break; - } - } - } - } -#endif if (c == '.') { c = *++s; bc.dp1 = s - s0; @@ -2637,10 +1537,6 @@ if (match(&s, "an")) { word0(&rv) = NAN_WORD0; word1(&rv) = NAN_WORD1; -#ifndef No_Hex_NaN - if (*s == '(') /*)*/ - hexnan(&rv, &s); -#endif goto ret; } } @@ -2663,104 +1559,40 @@ k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; dval(&rv) = y; if (k > 9) { -#ifdef SET_INEXACT - if (k > DBL_DIG) - oldinexact = get_inexact(); -#endif dval(&rv) = tens[k - 9] * dval(&rv) + z; } bd0 = 0; if (nd <= DBL_DIG -#ifndef RND_PRODQUOT -#ifndef Honor_FLT_ROUNDS && Flt_Rounds == 1 -#endif -#endif ) { if (!e) goto ret; if (e > 0) { if (e <= Ten_pmax) { -#ifdef VAX - goto vax_ovfl_check; -#else -#ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - rv.d = -rv.d; - sign = 0; - } -#endif /* rv = */ rounded_product(dval(&rv), tens[e]); goto ret; -#endif } i = DBL_DIG - nd; if (e <= Ten_pmax + i) { /* A fancier test would sometimes let us do * this for larger i values. */ -#ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - rv.d = -rv.d; - sign = 0; - } -#endif e -= i; dval(&rv) *= tens[i]; -#ifdef VAX - /* VAX exponent range is so narrow we must - * worry about overflow here... - */ - vax_ovfl_check: - word0(&rv) -= P*Exp_msk1; /* rv = */ rounded_product(dval(&rv), tens[e]); - if ((word0(&rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) - goto ovfl; - word0(&rv) += P*Exp_msk1; -#else - /* rv = */ rounded_product(dval(&rv), tens[e]); -#endif goto ret; } } -#ifndef Inaccurate_Divide else if (e >= -Ten_pmax) { -#ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - rv.d = -rv.d; - sign = 0; - } -#endif /* rv = */ rounded_quotient(dval(&rv), tens[-e]); goto ret; } -#endif } e1 += nd - k; -#ifdef IEEE_Arith -#ifdef SET_INEXACT - bc.inexact = 1; - if (k <= DBL_DIG) - oldinexact = get_inexact(); -#endif #ifdef Avoid_Underflow bc.scale = 0; #endif -#ifdef Honor_FLT_ROUNDS - if (bc.rounding >= 2) { - if (sign) - bc.rounding = bc.rounding == 2 ? 0 : 2; - else - if (bc.rounding != 2) - bc.rounding = 0; - } -#endif -#endif /*IEEE_Arith*/ /* Get starting approximation = rv * 10**e1 */ @@ -2770,35 +1602,10 @@ if (e1 &= ~15) { if (e1 > DBL_MAX_10_EXP) { ovfl: -#ifndef NO_ERRNO errno = ERANGE; -#endif /* Can't trust HUGE_VAL */ -#ifdef IEEE_Arith -#ifdef Honor_FLT_ROUNDS - switch(bc.rounding) { - case 0: /* toward 0 */ - case 3: /* toward -infinity */ - word0(&rv) = Big0; - word1(&rv) = Big1; - break; - default: - word0(&rv) = Exp_mask; - word1(&rv) = 0; - } -#else /*Honor_FLT_ROUNDS*/ word0(&rv) = Exp_mask; word1(&rv) = 0; -#endif /*Honor_FLT_ROUNDS*/ -#ifdef SET_INEXACT - /* set overflow bit */ - dval(&rv0) = 1e300; - dval(&rv0) *= dval(&rv0); -#endif -#else /*IEEE_Arith*/ - word0(&rv) = Big0; - word1(&rv) = Big1; -#endif /*IEEE_Arith*/ goto ret; } e1 >>= 4; @@ -2861,9 +1668,7 @@ if (!dval(&rv)) { undfl: dval(&rv) = 0.; -#ifndef NO_ERRNO errno = ERANGE; -#endif goto ret; } #ifndef Avoid_Underflow @@ -2882,7 +1687,6 @@ /* Put digits into bd: true value = bd * 10^e */ bc.nd = nd; -#ifndef NO_STRTOD_BIGCOMP bc.nd0 = nd0; /* Only needed if nd > strtod_diglim, but done here */ /* to silence an erroneous warning about bc.nd0 */ /* possibly not being initialized. */ @@ -2912,7 +1716,6 @@ y = 10*y + s0[j++] - '0'; } } -#endif bd0 = s2b(s0, nd0, nd, y, bc.dplen); for(;;) { @@ -2934,10 +1737,6 @@ else bd2 -= bbe; bs2 = bb2; -#ifdef Honor_FLT_ROUNDS - if (bc.rounding != 1) - bs2++; -#endif #ifdef Avoid_Underflow j = bbe - bc.scale; i = j + bbbits - 1; /* logb(rv) */ @@ -2947,11 +1746,7 @@ j = P + 1 - bbbits; #else /*Avoid_Underflow*/ #ifdef Sudden_Underflow -#ifdef IBM - j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); -#else j = P + 1 - bbbits; -#endif #else /*Sudden_Underflow*/ j = bbe; i = j + bbbits - 1; /* logb(rv) */ @@ -2992,141 +1787,30 @@ bc.dsign = delta->sign; delta->sign = 0; i = cmp(delta, bs); -#ifndef NO_STRTOD_BIGCOMP if (bc.nd > nd && i <= 0) { if (bc.dsign) break; /* Must use bigcomp(). */ -#ifdef Honor_FLT_ROUNDS - if (bc.rounding != 1) { - if (i < 0) - break; - } - else -#endif { bc.nd = nd; i = -1; /* Discarded digits make delta smaller. */ } } -#endif -#ifdef Honor_FLT_ROUNDS - if (bc.rounding != 1) { - if (i < 0) { - /* Error is less than an ulp */ - if (!delta->x[0] && delta->wds <= 1) { - /* exact */ -#ifdef SET_INEXACT - bc.inexact = 0; -#endif - break; - } - if (bc.rounding) { - if (bc.dsign) { - adj.d = 1.; - goto apply_adj; - } - } - else if (!bc.dsign) { - adj.d = -1.; - if (!word1(&rv) - && !(word0(&rv) & Frac_mask)) { - y = word0(&rv) & Exp_mask; -#ifdef Avoid_Underflow - if (!bc.scale || y > 2*P*Exp_msk1) -#else - if (y) -#endif - { - delta = lshift(delta,Log2P); - if (cmp(delta, bs) <= 0) - adj.d = -0.5; - } - } - apply_adj: -#ifdef Avoid_Underflow - if (bc.scale && (y = word0(&rv) & Exp_mask) - <= 2*P*Exp_msk1) - word0(&adj) += (2*P+1)*Exp_msk1 - y; -#else -#ifdef Sudden_Underflow - if ((word0(&rv) & Exp_mask) <= - P*Exp_msk1) { - word0(&rv) += P*Exp_msk1; - dval(&rv) += adj.d*ulp(dval(&rv)); - word0(&rv) -= P*Exp_msk1; - } - else -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ - dval(&rv) += adj.d*ulp(&rv); - } - break; - } - adj.d = ratio(delta, bs); - if (adj.d < 1.) - adj.d = 1.; - if (adj.d <= 0x7ffffffe) { - /* adj = rounding ? ceil(adj) : floor(adj); */ - y = adj.d; - if (y != adj.d) { - if (!((bc.rounding>>1) ^ bc.dsign)) - y++; - adj.d = y; - } - } -#ifdef Avoid_Underflow - if (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) - word0(&adj) += (2*P+1)*Exp_msk1 - y; -#else -#ifdef Sudden_Underflow - if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { - word0(&rv) += P*Exp_msk1; - adj.d *= ulp(dval(&rv)); - if (bc.dsign) - dval(&rv) += adj.d; - else - dval(&rv) -= adj.d; - word0(&rv) -= P*Exp_msk1; - goto cont; - } -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ - adj.d *= ulp(&rv); - if (bc.dsign) { - if (word0(&rv) == Big0 && word1(&rv) == Big1) - goto ovfl; - dval(&rv) += adj.d; - } - else - dval(&rv) -= adj.d; - goto cont; - } -#endif /*Honor_FLT_ROUNDS*/ if (i < 0) { /* Error is less than half an ulp -- check for * special case of mantissa a power of two. */ if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask -#ifdef IEEE_Arith #ifdef Avoid_Underflow || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1 #else || (word0(&rv) & Exp_mask) <= Exp_msk1 #endif -#endif ) { -#ifdef SET_INEXACT - if (!delta->x[0] && delta->wds <= 1) - bc.inexact = 0; -#endif break; } if (!delta->x[0] && delta->wds <= 1) { /* exact result */ -#ifdef SET_INEXACT - bc.inexact = 0; -#endif break; } delta = lshift(delta,Log2P); @@ -3147,9 +1831,6 @@ /*boundary case -- increment exponent*/ word0(&rv) = (word0(&rv) & Exp_mask) + Exp_msk1 -#ifdef IBM - | Exp_msk1 >> 4 -#endif ; word1(&rv) = 0; #ifdef Avoid_Underflow @@ -3163,15 +1844,11 @@ /* boundary case -- decrement exponent */ #ifdef Sudden_Underflow /*{{*/ L = word0(&rv) & Exp_mask; -#ifdef IBM - if (L < Exp_msk1) -#else #ifdef Avoid_Underflow if (L <= (bc.scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) #else if (L <= Exp_msk1) #endif /*Avoid_Underflow*/ -#endif /*IBM*/ { if (bc.nd >nd) { bc.uflchk = 1; @@ -3202,19 +1879,12 @@ #endif /*Sudden_Underflow}}*/ word0(&rv) = L | Bndry_mask1; word1(&rv) = 0xffffffff; -#ifdef IBM - goto cont; -#else break; -#endif } -#ifndef ROUND_BIASED if (!(word1(&rv) & LSB)) break; -#endif if (bc.dsign) dval(&rv) += ulp(&rv); -#ifndef ROUND_BIASED else { dval(&rv) -= ulp(&rv); #ifndef Sudden_Underflow @@ -3230,7 +1900,6 @@ #ifdef Avoid_Underflow bc.dsign = 1 - bc.dsign; #endif -#endif break; } if ((aadj = ratio(delta, bs)) <= 2.) { @@ -3319,11 +1988,7 @@ word0(&rv) += P*Exp_msk1; adj.d = aadj1 * ulp(&rv); dval(&rv) += adj.d; -#ifdef IBM - if ((word0(&rv) & Exp_mask) < P*Exp_msk1) -#else if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) -#endif { if (word0(&rv0) == Tiny0 && word1(&rv0) == Tiny1) { @@ -3363,7 +2028,6 @@ #endif /*Avoid_Underflow*/ } z = word0(&rv) & Exp_mask; -#ifndef SET_INEXACT if (bc.nd == nd) { #ifdef Avoid_Underflow if (!bc.scale) @@ -3381,7 +2045,6 @@ break; } } -#endif cont: Bfree(bb); Bfree(bd); @@ -3393,44 +2056,18 @@ Bfree(bs); Bfree(bd0); Bfree(delta); -#ifndef NO_STRTOD_BIGCOMP if (bc.nd > nd) bigcomp(&rv, s0, &bc); -#endif -#ifdef SET_INEXACT - if (bc.inexact) { - if (!oldinexact) { - word0(&rv0) = Exp_1 + (70 << Exp_shift); - word1(&rv0) = 0; - dval(&rv0) += 1.; - } - } - else if (!oldinexact) - clear_inexact(); -#endif #ifdef Avoid_Underflow if (bc.scale) { word0(&rv0) = Exp_1 - 2*P*Exp_msk1; word1(&rv0) = 0; dval(&rv) *= dval(&rv0); -#ifndef NO_ERRNO /* try to avoid the bug of testing an 8087 register value */ -#ifdef IEEE_Arith if (!(word0(&rv) & Exp_mask)) -#else - if (word0(&rv) == 0 && word1(&rv) == 0) -#endif errno = ERANGE; -#endif } #endif /* Avoid_Underflow */ -#ifdef SET_INEXACT - if (bc.inexact && !(word0(&rv) & Exp_mask)) { - /* set underflow bit */ - dval(&rv0) = 1e-300; - dval(&rv0) *= dval(&rv0); - } -#endif ret: if (se) *se = (char *)s; @@ -3442,11 +2079,7 @@ #endif static char * -#ifdef KR_headers -rv_alloc(i) int i; -#else rv_alloc(int i) -#endif { int j, k, *r; @@ -3465,11 +2098,7 @@ } static char * -#ifdef KR_headers -nrv_alloc(s, rve, n) char *s, **rve; int n; -#else nrv_alloc(char *s, char **rve, int n) -#endif { char *rv, *t; @@ -3487,11 +2116,7 @@ */ void -#ifdef KR_headers -freedtoa(s) char *s; -#else freedtoa(char *s) -#endif { Bigint *b = (Bigint *)((int *)s - 1); b->maxwds = 1 << (b->k = *(int*)b); @@ -3538,12 +2163,7 @@ char * _Py_dg_dtoa -#ifdef KR_headers - (dd, mode, ndigits, decpt, sign, rve) - double dd; int mode, ndigits, *decpt, *sign; char **rve; -#else (double dd, int mode, int ndigits, int *decpt, int *sign, char **rve) -#endif { /* Arguments ndigits, decpt, sign are similar to those of ecvt and fcvt; trailing zeros are suppressed from @@ -3591,22 +2211,6 @@ U d2, eps, u; double ds; char *s, *s0; -#ifdef SET_INEXACT - int inexact, oldinexact; -#endif -#ifdef Honor_FLT_ROUNDS /*{*/ - int Rounding; -#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ - Rounding = Flt_Rounds; -#else /*}{*/ - Rounding = 1; - switch(fegetround()) { - case FE_TOWARDZERO: Rounding = 0; break; - case FE_UPWARD: Rounding = 2; break; - case FE_DOWNWARD: Rounding = 3; - } -#endif /*}}*/ -#endif /*}*/ #ifndef MULTIPLE_THREADS if (dtoa_result) { @@ -3625,42 +2229,20 @@ *sign = 0; #if defined(IEEE_Arith) + defined(VAX) -#ifdef IEEE_Arith if ((word0(&u) & Exp_mask) == Exp_mask) -#else - if (word0(&u) == 0x8000) -#endif { /* Infinity or NaN */ *decpt = 9999; -#ifdef IEEE_Arith if (!word1(&u) && !(word0(&u) & 0xfffff)) return nrv_alloc("Infinity", rve, 8); -#endif return nrv_alloc("NaN", rve, 3); } #endif -#ifdef IBM - dval(&u) += 0; /* normalize */ -#endif if (!dval(&u)) { *decpt = 1; return nrv_alloc("0", rve, 1); } -#ifdef SET_INEXACT - try_quick = oldinexact = get_inexact(); - inexact = 1; -#endif -#ifdef Honor_FLT_ROUNDS - if (Rounding >= 2) { - if (*sign) - Rounding = Rounding == 2 ? 0 : 2; - else - if (Rounding != 2) - Rounding = 0; - } -#endif b = d2b(&u, &be, &bbits); #ifdef Sudden_Underflow @@ -3671,10 +2253,6 @@ dval(&d2) = dval(&u); word0(&d2) &= Frac_mask1; word0(&d2) |= Exp_11; -#ifdef IBM - if (j = 11 - hi0bits(word0(&d2) & Frac_mask)) - dval(&d2) /= 1 << j; -#endif /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 * log10(x) = log(x) / log(10) @@ -3699,10 +2277,6 @@ */ i -= Bias; -#ifdef IBM - i <<= 2; - i += j; -#endif #ifndef Sudden_Underflow denorm = 0; } @@ -3750,13 +2324,11 @@ if (mode < 0 || mode > 9) mode = 0; -#ifndef SET_INEXACT #ifdef Check_FLT_ROUNDS try_quick = Rounding == 1; #else try_quick = 1; #endif -#endif /*SET_INEXACT*/ if (mode > 5) { mode -= 4; @@ -3791,10 +2363,6 @@ } s = s0 = rv_alloc(i); -#ifdef Honor_FLT_ROUNDS - if (mode > 1 && Rounding != 1) - leftright = 0; -#endif if (ilim >= 0 && ilim <= Quick_max && try_quick) { @@ -3848,7 +2416,6 @@ goto no_digits; goto fast_failed; } -#ifndef No_leftright if (leftright) { /* Use Steele & White method of only * generating digits needed. @@ -3869,7 +2436,6 @@ } } else { -#endif /* Generate ilim digits, then fix them up. */ dval(&eps) *= tens[ilim-1]; for(i = 1;; i++, dval(&u) *= 10.) { @@ -3888,9 +2454,7 @@ break; } } -#ifndef No_leftright } -#endif fast_failed: s = s0; dval(&u) = dval(&d2); @@ -3921,19 +2485,9 @@ #endif *s++ = '0' + (int)L; if (!dval(&u)) { -#ifdef SET_INEXACT - inexact = 0; -#endif break; } if (i == ilim) { -#ifdef Honor_FLT_ROUNDS - if (mode > 1) - switch(Rounding) { - case 0: goto ret1; - case 2: goto bump_up; - } -#endif dval(&u) += dval(&u); if (dval(&u) > ds || (dval(&u) == ds && L & 1)) { bump_up: @@ -3959,11 +2513,7 @@ #ifndef Sudden_Underflow denorm ? be + (Bias + (P-1) - 1 + 1) : #endif -#ifdef IBM - 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); -#else 1 + P - bbits; -#endif b2 += i; s2 += i; mhi = i2b(1); @@ -3996,9 +2546,6 @@ spec_case = 0; if ((mode < 2 || leftright) -#ifdef Honor_FLT_ROUNDS - && Rounding == 1 -#endif ) { if (!word1(&u) && !(word0(&u) & Bndry_mask) #ifndef Sudden_Underflow @@ -4019,15 +2566,9 @@ * and for all and pass them and a shift to quorem, so it * can do shifts and ors to compute the numerator for q. */ -#ifdef Pack_32 if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f)) i = 32 - i; #define iInc 28 -#else - if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) - i = 16 - i; -#define iInc 12 -#endif i = dshift(S, s2); b2 += i; m2 += i; @@ -4081,42 +2622,21 @@ delta = diff(S, mhi); j1 = delta->sign ? 1 : cmp(b, delta); Bfree(delta); -#ifndef ROUND_BIASED if (j1 == 0 && mode != 1 && !(word1(&u) & 1) -#ifdef Honor_FLT_ROUNDS - && Rounding >= 1 -#endif ) { if (dig == '9') goto round_9_up; if (j > 0) dig++; -#ifdef SET_INEXACT - else if (!b->x[0] && b->wds <= 1) - inexact = 0; -#endif *s++ = dig; goto ret; } -#endif if (j < 0 || (j == 0 && mode != 1 -#ifndef ROUND_BIASED && !(word1(&u) & 1) -#endif )) { if (!b->x[0] && b->wds <= 1) { -#ifdef SET_INEXACT - inexact = 0; -#endif goto accept_dig; } -#ifdef Honor_FLT_ROUNDS - if (mode > 1) - switch(Rounding) { - case 0: goto accept_dig; - case 2: goto keep_dig; - } -#endif /*Honor_FLT_ROUNDS*/ if (j1 > 0) { b = lshift(b, 1); j1 = cmp(b, S); @@ -4129,10 +2649,6 @@ goto ret; } if (j1 > 0) { -#ifdef Honor_FLT_ROUNDS - if (!Rounding) - goto accept_dig; -#endif if (dig == '9') { /* possible if i == 1 */ round_9_up: *s++ = '9'; @@ -4141,9 +2657,6 @@ *s++ = dig + 1; goto ret; } -#ifdef Honor_FLT_ROUNDS - keep_dig: -#endif *s++ = dig; if (i == ilim) break; @@ -4160,9 +2673,6 @@ for(i = 1;; i++) { *s++ = dig = quorem(b,S) + '0'; if (!b->x[0] && b->wds <= 1) { -#ifdef SET_INEXACT - inexact = 0; -#endif goto ret; } if (i >= ilim) @@ -4172,12 +2682,6 @@ /* Round off last digit */ -#ifdef Honor_FLT_ROUNDS - switch(Rounding) { - case 0: goto trimzeros; - case 2: goto roundoff; - } -#endif b = lshift(b, 1); j = cmp(b, S); if (j > 0 || (j == 0 && dig & 1)) { @@ -4191,9 +2695,6 @@ ++*s++; } else { -#ifdef Honor_FLT_ROUNDS - trimzeros: -#endif while(*--s == '0'); s++; } @@ -4205,17 +2706,6 @@ Bfree(mhi); } ret1: -#ifdef SET_INEXACT - if (inexact) { - if (!oldinexact) { - word0(&u) = Exp_1 + (70 << Exp_shift); - word1(&u) = 0; - dval(&u) += 1.; - } - } - else if (!oldinexact) - clear_inexact(); -#endif Bfree(b); *s = 0; *decpt = k + 1; From python-checkins at python.org Sun Apr 5 12:24:21 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 12:24:21 +0200 (CEST) Subject: [Python-checkins] r71212 - in python/trunk/Doc/library: basehttpserver.rst socketserver.rst Message-ID: <20090405102421.086E31E4012@bag.python.org> Author: georg.brandl Date: Sun Apr 5 12:24:20 2009 New Revision: 71212 Log: #1742837: expand HTTP server docs, and fix SocketServer ones to document methods as methods, not functions. Modified: python/trunk/Doc/library/basehttpserver.rst python/trunk/Doc/library/socketserver.rst Modified: python/trunk/Doc/library/basehttpserver.rst ============================================================================== --- python/trunk/Doc/library/basehttpserver.rst (original) +++ python/trunk/Doc/library/basehttpserver.rst Sun Apr 5 12:24:20 2009 @@ -15,8 +15,6 @@ pair: HTTP; protocol single: URL single: httpd - -.. index:: module: SimpleHTTPServer module: CGIHTTPServer @@ -26,7 +24,8 @@ :mod:`CGIHTTPServer` modules. The first class, :class:`HTTPServer`, is a :class:`SocketServer.TCPServer` -subclass. It creates and listens at the HTTP socket, dispatching the requests +subclass, and therefore implements the :class:`SocketServer.BaseServer` +interface. It creates and listens at the HTTP socket, dispatching the requests to a handler. Code to create and run the server looks like this:: def run(server_class=BaseHTTPServer.HTTPServer, @@ -269,12 +268,31 @@ performed on the client's IP address. +More examples +------------- + +To create a server that doesn't run forever, but until some condition is +fulfilled:: + + def run_while_true(server_class=BaseHTTPServer.HTTPServer, + handler_class=BaseHTTPServer.BaseHTTPRequestHandler): + """ + This assumes that keep_running() is a function of no arguments which + is tested initially and after each request. If its return value + is true, the server continues. + """ + server_address = ('', 8000) + httpd = server_class(server_address, handler_class) + while keep_running(): + httpd.handle_request() + + .. seealso:: Module :mod:`CGIHTTPServer` Extended request handler that supports CGI scripts. Module :mod:`SimpleHTTPServer` - Basic request handler that limits response to files actually under the document - root. + Basic request handler that limits response to files actually under the + document root. Modified: python/trunk/Doc/library/socketserver.rst ============================================================================== --- python/trunk/Doc/library/socketserver.rst (original) +++ python/trunk/Doc/library/socketserver.rst Sun Apr 5 12:24:20 2009 @@ -129,15 +129,21 @@ Server Objects -------------- +.. class:: BaseServer -.. function:: fileno() + This is the superclass of all Server objects in the module. It defines the + interface, given below, but does not implement most of the methods, which is + done in subclasses. + + +.. method:: BaseServer.fileno() Return an integer file descriptor for the socket on which the server is listening. This function is most commonly passed to :func:`select.select`, to allow monitoring multiple servers in the same process. -.. function:: handle_request() +.. method:: BaseServer.handle_request() Process a single request. This function calls the following methods in order: :meth:`get_request`, :meth:`verify_request`, and @@ -148,32 +154,32 @@ will return. -.. function:: serve_forever(poll_interval=0.5) +.. method:: BaseServer.serve_forever(poll_interval=0.5) Handle requests until an explicit :meth:`shutdown` request. Polls for shutdown every *poll_interval* seconds. -.. function:: shutdown() +.. method:: BaseServer.shutdown() Tells the :meth:`serve_forever` loop to stop and waits until it does. .. versionadded:: 2.6 -.. data:: address_family +.. attribute:: BaseServer.address_family The family of protocols to which the server's socket belongs. Common examples are :const:`socket.AF_INET` and :const:`socket.AF_UNIX`. -.. data:: RequestHandlerClass +.. attribute:: BaseServer.RequestHandlerClass The user-provided request handler class; an instance of this class is created for each request. -.. data:: server_address +.. attribute:: BaseServer.server_address The address on which the server is listening. The format of addresses varies depending on the protocol family; see the documentation for the socket module @@ -181,22 +187,22 @@ the address, and an integer port number: ``('127.0.0.1', 80)``, for example. -.. data:: socket +.. attribute:: BaseServer.socket The socket object on which the server will listen for incoming requests. + The server classes support the following class variables: .. XXX should class variables be covered before instance variables, or vice versa? - -.. data:: allow_reuse_address +.. attribute:: BaseServer.allow_reuse_address Whether the server will allow the reuse of an address. This defaults to :const:`False`, and can be set in subclasses to change the policy. -.. data:: request_queue_size +.. attribute:: BaseServer.request_queue_size The size of the request queue. If it takes a long time to process a single request, any requests that arrive while the server is busy are placed into a @@ -205,17 +211,19 @@ value is usually 5, but this can be overridden by subclasses. -.. data:: socket_type +.. attribute:: BaseServer.socket_type The type of socket used by the server; :const:`socket.SOCK_STREAM` and :const:`socket.SOCK_DGRAM` are two common values. -.. data:: timeout + +.. attribute:: BaseServer.timeout Timeout duration, measured in seconds, or :const:`None` if no timeout is desired. If :meth:`handle_request` receives no incoming requests within the timeout period, the :meth:`handle_timeout` method is called. + There are various server methods that can be overridden by subclasses of base server classes like :class:`TCPServer`; these methods aren't useful to external users of the server object. @@ -223,27 +231,27 @@ .. XXX should the default implementations of these be documented, or should it be assumed that the user will look at SocketServer.py? - -.. function:: finish_request() +.. method:: BaseServer.finish_request() Actually processes the request by instantiating :attr:`RequestHandlerClass` and calling its :meth:`handle` method. -.. function:: get_request() +.. method:: BaseServer.get_request() Must accept a request from the socket, and return a 2-tuple containing the *new* socket object to be used to communicate with the client, and the client's address. -.. function:: handle_error(request, client_address) +.. method:: BaseServer.handle_error(request, client_address) This function is called if the :attr:`RequestHandlerClass`'s :meth:`handle` method raises an exception. The default action is to print the traceback to standard output and continue handling further requests. -.. function:: handle_timeout() + +.. method:: BaseServer.handle_timeout() This function is called when the :attr:`timeout` attribute has been set to a value other than :const:`None` and the timeout period has passed with no @@ -251,31 +259,32 @@ to collect the status of any child processes that have exited, while in threading servers this method does nothing. -.. function:: process_request(request, client_address) + +.. method:: BaseServer.process_request(request, client_address) Calls :meth:`finish_request` to create an instance of the :attr:`RequestHandlerClass`. If desired, this function can create a new process or thread to handle the request; the :class:`ForkingMixIn` and :class:`ThreadingMixIn` classes do this. + .. Is there any point in documenting the following two functions? What would the purpose of overriding them be: initializing server instance variables, adding new network families? - -.. function:: server_activate() +.. method:: BaseServer.server_activate() Called by the server's constructor to activate the server. The default behavior just :meth:`listen`\ s to the server's socket. May be overridden. -.. function:: server_bind() +.. method:: BaseServer.server_bind() Called by the server's constructor to bind the socket to the desired address. May be overridden. -.. function:: verify_request(request, client_address) +.. method:: BaseServer.verify_request(request, client_address) Must return a Boolean value; if the value is :const:`True`, the request will be processed, and if it's :const:`False`, the request will be denied. This function @@ -291,14 +300,14 @@ request. -.. function:: finish() +.. method:: RequestHandler.finish() Called after the :meth:`handle` method to perform any clean-up actions required. The default implementation does nothing. If :meth:`setup` or :meth:`handle` raise an exception, this function will not be called. -.. function:: handle() +.. method:: RequestHandler.handle() This function must do all the work required to service a request. The default implementation does nothing. Several instance attributes are @@ -317,7 +326,7 @@ data or return data to the client. -.. function:: setup() +.. method:: RequestHandler.setup() Called before the :meth:`handle` method to perform any initialization actions required. The default implementation does nothing. From python-checkins at python.org Sun Apr 5 12:26:01 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 5 Apr 2009 12:26:01 +0200 (CEST) Subject: [Python-checkins] r71213 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090405102601.4117E1E4012@bag.python.org> Author: mark.dickinson Date: Sun Apr 5 12:26:01 2009 New Revision: 71213 Log: Remove #includes in dtoa.c that are already included by Python.h Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Sun Apr 5 12:26:01 2009 @@ -182,8 +182,7 @@ /* Linking of Python's #defines to Gay's #defines starts here. */ #include "Python.h" - -#define NO_HEX_FP +#include "float.h" /* use WORDS_BIGENDIAN to determine float endianness. This assumes that ints and floats share the same endianness on the target machine, which appears @@ -210,19 +209,17 @@ #define NO_LONG_LONG #endif -/* End Python #define linking */ +#undef DEBUG +#ifdef Py_DEBUG +#define DEBUG +#endif +/* End Python #define linking */ #ifdef DEBUG -#include "stdio.h" #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} #endif -#include "stdlib.h" -#include "string.h" - - - #ifdef MALLOC extern void *MALLOC(size_t); #else @@ -249,14 +246,6 @@ #undef INFNAN_CHECK #define INFNAN_CHECK -#include "errno.h" - -#include "float.h" - -#ifndef __MATH_H__ -#include "math.h" -#endif - #ifdef __cplusplus extern "C" { #endif From python-checkins at python.org Sun Apr 5 12:29:58 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 12:29:58 +0200 (CEST) Subject: [Python-checkins] r71214 - in python/trunk/Doc: distutils/apiref.rst library/os.path.rst library/ttk.rst Message-ID: <20090405102958.30FDA1E4012@bag.python.org> Author: georg.brandl Date: Sun Apr 5 12:29:57 2009 New Revision: 71214 Log: Normalize spelling of Mac OS X. Modified: python/trunk/Doc/distutils/apiref.rst python/trunk/Doc/library/os.path.rst python/trunk/Doc/library/ttk.rst Modified: python/trunk/Doc/distutils/apiref.rst ============================================================================== --- python/trunk/Doc/distutils/apiref.rst (original) +++ python/trunk/Doc/distutils/apiref.rst Sun Apr 5 12:29:57 2009 @@ -1091,17 +1091,17 @@ For non-POSIX platforms, currently just returns ``sys.platform``. - For MacOS X systems the OS version reflects the minimal version on which + For Mac OS X systems the OS version reflects the minimal version on which binaries will run (that is, the value of ``MACOSX_DEPLOYMENT_TARGET`` during the build of Python), not the OS version of the current system. - For universal binary builds on MacOS X the architecture value reflects + For universal binary builds on Mac OS X the architecture value reflects the univeral binary status instead of the architecture of the current processor. For 32-bit universal binaries the architecture is ``fat``, for 64-bit universal binaries the architecture is ``fat64``, and for 4-way universal binaries the architecture is ``universal``. - Examples of returned values on MacOS X: + Examples of returned values on Mac OS X: * ``macosx-10.3-ppc`` Modified: python/trunk/Doc/library/os.path.rst ============================================================================== --- python/trunk/Doc/library/os.path.rst (original) +++ python/trunk/Doc/library/os.path.rst Sun Apr 5 12:29:57 2009 @@ -190,9 +190,9 @@ .. function:: normcase(path) - Normalize the case of a pathname. On Unix and MacOSX, this returns the path unchanged; on - case-insensitive filesystems, it converts the path to lowercase. On Windows, it - also converts forward slashes to backward slashes. + Normalize the case of a pathname. On Unix and Mac OS X, this returns the + path unchanged; on case-insensitive filesystems, it converts the path to + lowercase. On Windows, it also converts forward slashes to backward slashes. .. function:: normpath(path) Modified: python/trunk/Doc/library/ttk.rst ============================================================================== --- python/trunk/Doc/library/ttk.rst (original) +++ python/trunk/Doc/library/ttk.rst Sun Apr 5 12:29:57 2009 @@ -656,7 +656,7 @@ Platform-specific notes ^^^^^^^^^^^^^^^^^^^^^^^ -* On MacOS X, toplevel windows automatically include a built-in size grip +* On Mac OS X, toplevel windows automatically include a built-in size grip by default. Adding a :class:`Sizegrip` is harmless, since the built-in grip will just mask the widget. From python-checkins at python.org Sun Apr 5 12:32:26 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 12:32:26 +0200 (CEST) Subject: [Python-checkins] r71215 - in python/trunk/Doc: distutils/apiref.rst library/_winreg.rst library/shelve.rst Message-ID: <20090405103226.A06241E4012@bag.python.org> Author: georg.brandl Date: Sun Apr 5 12:32:26 2009 New Revision: 71215 Log: Avoid sure signs of a diseased mind. Modified: python/trunk/Doc/distutils/apiref.rst python/trunk/Doc/library/_winreg.rst python/trunk/Doc/library/shelve.rst Modified: python/trunk/Doc/distutils/apiref.rst ============================================================================== --- python/trunk/Doc/distutils/apiref.rst (original) +++ python/trunk/Doc/distutils/apiref.rst Sun Apr 5 12:32:26 2009 @@ -1050,8 +1050,8 @@ .. warning:: - Handles cross-device moves on Unix using :func:`copy_file`. What about other - systems??? + Handles cross-device moves on Unix using :func:`copy_file`. What about + other systems? .. function:: write_file(filename, contents) Modified: python/trunk/Doc/library/_winreg.rst ============================================================================== --- python/trunk/Doc/library/_winreg.rst (original) +++ python/trunk/Doc/library/_winreg.rst Sun Apr 5 12:32:26 2009 @@ -252,9 +252,10 @@ associated. If this parameter is ``None`` or empty, the function retrieves the value set by the :func:`SetValue` method for the key identified by *key*. - Values in the registry have name, type, and data components. This method + Values in the registry have name, type, and data components. This method retrieves the data for a key's first value that has a NULL name. But the - underlying API call doesn't return the type, Lame Lame Lame, DO NOT USE THIS!!! + underlying API call doesn't return the type, so always use + :func:`QueryValueEx` if possible. .. function:: QueryValueEx(key, value_name) Modified: python/trunk/Doc/library/shelve.rst ============================================================================== --- python/trunk/Doc/library/shelve.rst (original) +++ python/trunk/Doc/library/shelve.rst Sun Apr 5 12:32:26 2009 @@ -148,7 +148,7 @@ # as d was opened WITHOUT writeback=True, beware: d['xx'] = range(4) # this works as expected, but... - d['xx'].append(5) # *this doesn't!* -- d['xx'] is STILL range(4)!!! + d['xx'].append(5) # *this doesn't!* -- d['xx'] is STILL range(4)! # having opened d without writeback=True, you need to code carefully: temp = d['xx'] # extracts the copy From python-checkins at python.org Sun Apr 5 12:41:04 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 12:41:04 +0200 (CEST) Subject: [Python-checkins] r71216 - in python/trunk/Doc/library: os.path.rst os.rst Message-ID: <20090405104104.181EE1E4012@bag.python.org> Author: georg.brandl Date: Sun Apr 5 12:41:02 2009 New Revision: 71216 Log: #1718017: document the relation of os.path and the posixpath, ntpath etc. modules better. Modified: python/trunk/Doc/library/os.path.rst python/trunk/Doc/library/os.rst Modified: python/trunk/Doc/library/os.path.rst ============================================================================== --- python/trunk/Doc/library/os.path.rst (original) +++ python/trunk/Doc/library/os.path.rst Sun Apr 5 12:41:02 2009 @@ -1,11 +1,9 @@ - :mod:`os.path` --- Common pathname manipulations ================================================ .. module:: os.path :synopsis: Operations on pathnames. - .. index:: single: path; operations This module implements some useful functions on pathnames. To read or @@ -18,6 +16,22 @@ :func:`splitunc` and :func:`ismount` do handle them correctly. +.. note:: + + Since different operating systems have different path name conventions, there + are several versions of this module in the standard library. The + :mod:`os.path` module is always the path module suitable for the operating + system Python is running on, and therefore usable for local paths. However, + you can also import and use the individual modules if you want to manipulate + a path that is *always* in one of the different formats. They all have the + same interface: + + * :mod:`posixpath` for UNIX-style paths + * :mod:`ntpath` for Windows paths + * :mod:`macpath` for old-style MacOS paths + * :mod:`os2emxpath` for OS/2 EMX paths + + .. function:: abspath(path) Return a normalized absolutized version of the pathname *path*. On most Modified: python/trunk/Doc/library/os.rst ============================================================================== --- python/trunk/Doc/library/os.rst (original) +++ python/trunk/Doc/library/os.rst Sun Apr 5 12:41:02 2009 @@ -46,15 +46,6 @@ ``'ce'``, ``'java'``, ``'riscos'``. -.. data:: path - - The corresponding operating system dependent standard module for pathname - operations, such as :mod:`posixpath` or :mod:`ntpath`. Thus, given the proper - imports, ``os.path.split(file)`` is equivalent to but more portable than - ``posixpath.split(file)``. Note that this is also an importable module: it may - be imported directly as :mod:`os.path`. - - .. _os-procinfo: Process Parameters From python-checkins at python.org Sun Apr 5 12:48:48 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 12:48:48 +0200 (CEST) Subject: [Python-checkins] r71217 - in python/trunk: Lib/ftplib.py Misc/NEWS Message-ID: <20090405104848.40FE21E4012@bag.python.org> Author: georg.brandl Date: Sun Apr 5 12:48:47 2009 New Revision: 71217 Log: #1726172: dont raise an unexpected IndexError if a voidresp() call has an empty response. Modified: python/trunk/Lib/ftplib.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/ftplib.py ============================================================================== --- python/trunk/Lib/ftplib.py (original) +++ python/trunk/Lib/ftplib.py Sun Apr 5 12:48:47 2009 @@ -221,7 +221,7 @@ def voidresp(self): """Expect a response beginning with '2'.""" resp = self.getresp() - if resp[0] != '2': + if resp[:1] != '2': raise error_reply, resp return resp @@ -520,8 +520,6 @@ resp = self.sendcmd('DELE ' + filename) if resp[:3] in ('250', '200'): return resp - elif resp[:1] == '5': - raise error_perm, resp else: raise error_reply, resp Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Apr 5 12:48:47 2009 @@ -210,6 +210,8 @@ Library ------- +- Issue 1726172: fix IndexError in the case of and empty response in ftplib. + - Issue 2625: added missing iteritems() call to the for loop in mailbox.MH.get_message(). From python-checkins at python.org Sun Apr 5 12:51:10 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 12:51:10 +0200 (CEST) Subject: [Python-checkins] r71218 - in python/branches/release26-maint: Lib/ftplib.py Misc/NEWS Message-ID: <20090405105110.3B31A1E4012@bag.python.org> Author: georg.brandl Date: Sun Apr 5 12:51:10 2009 New Revision: 71218 Log: Merged revisions 71217 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71217 | georg.brandl | 2009-04-05 12:48:47 +0200 (So, 05 Apr 2009) | 1 line #1726172: dont raise an unexpected IndexError if a voidresp() call has an empty response. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/ftplib.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/ftplib.py ============================================================================== --- python/branches/release26-maint/Lib/ftplib.py (original) +++ python/branches/release26-maint/Lib/ftplib.py Sun Apr 5 12:51:10 2009 @@ -221,7 +221,7 @@ def voidresp(self): """Expect a response beginning with '2'.""" resp = self.getresp() - if resp[0] != '2': + if resp[:1] != '2': raise error_reply, resp return resp @@ -520,8 +520,6 @@ resp = self.sendcmd('DELE ' + filename) if resp[:3] in ('250', '200'): return resp - elif resp[:1] == '5': - raise error_perm, resp else: raise error_reply, resp Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sun Apr 5 12:51:10 2009 @@ -95,6 +95,8 @@ Library ------- +- Issue 1726172: fix IndexError in the case of and empty response in ftplib. + - Issue 2625: added missing iteritems() call to the for loop in mailbox.MH.get_message(). From python-checkins at python.org Sun Apr 5 12:53:29 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 5 Apr 2009 12:53:29 +0200 (CEST) Subject: [Python-checkins] r71219 - python/branches/py3k-short-float-repr/Objects/unicodeobject.c Message-ID: <20090405105329.57B861E4012@bag.python.org> Author: mark.dickinson Date: Sun Apr 5 12:53:29 2009 New Revision: 71219 Log: Restore f->g switch for numbers >= 1e50 Modified: python/branches/py3k-short-float-repr/Objects/unicodeobject.c Modified: python/branches/py3k-short-float-repr/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/unicodeobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/unicodeobject.c Sun Apr 5 12:53:29 2009 @@ -8836,6 +8836,9 @@ goto done; } + if (type == 'f' && fabs(x) >= 1e50) + type = 'g'; + if (((type == 'g' || type == 'G') && buflen <= (size_t)10 + (size_t)prec) || ((type == 'f' || type == 'F') && From python-checkins at python.org Sun Apr 5 12:59:51 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 5 Apr 2009 12:59:51 +0200 (CEST) Subject: [Python-checkins] r71220 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090405105951.120041E4012@bag.python.org> Author: mark.dickinson Date: Sun Apr 5 12:59:50 2009 New Revision: 71220 Log: Hook up MALLOC and FREE in dtoa.c to PyMem_Malloc and PyMem_Free. Return properly from Balloc on failure. Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Sun Apr 5 12:59:50 2009 @@ -184,6 +184,9 @@ #include "Python.h" #include "float.h" +#define MALLOC PyMem_Malloc +#define FREE PyMem_Free + /* use WORDS_BIGENDIAN to determine float endianness. This assumes that ints and floats share the same endianness on the target machine, which appears to be true for every platform that Python currently cares about. We're @@ -220,12 +223,6 @@ #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} #endif -#ifdef MALLOC -extern void *MALLOC(size_t); -#else -#define MALLOC malloc -#endif - #ifndef Omit_Private_Memory #ifndef PRIVATE_MEM #define PRIVATE_MEM 2304 @@ -401,6 +398,8 @@ x = 1 << k; #ifdef Omit_Private_Memory rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); + if (rv == NULL) + goto error; #else len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) /sizeof(double); @@ -408,14 +407,18 @@ rv = (Bigint*)pmem_next; pmem_next += len; } - else + else { rv = (Bigint*)MALLOC(len*sizeof(double)); + if (rv == NULL) + goto error; + } #endif rv->k = k; rv->maxwds = x; } - FREE_DTOA_LOCK(0); rv->sign = rv->wds = 0; + error: + FREE_DTOA_LOCK(0); return rv; } @@ -425,11 +428,7 @@ { if (v) { if (v->k > Kmax) -#ifdef FREE FREE((void*)v); -#else - free((void*)v); -#endif else { ACQUIRE_DTOA_LOCK(0); v->next = freelist[v->k]; From python-checkins at python.org Sun Apr 5 13:06:25 2009 From: python-checkins at python.org (vinay.sajip) Date: Sun, 5 Apr 2009 13:06:25 +0200 (CEST) Subject: [Python-checkins] r71221 - python/trunk/Lib/test/test_logging.py Message-ID: <20090405110625.5280A1E4012@bag.python.org> Author: vinay.sajip Date: Sun Apr 5 13:06:24 2009 New Revision: 71221 Log: Issue #5695: Moved logging.captureWarnings() call inside with statement in WarningsTest.test_warnings. Modified: python/trunk/Lib/test/test_logging.py Modified: python/trunk/Lib/test/test_logging.py ============================================================================== --- python/trunk/Lib/test/test_logging.py (original) +++ python/trunk/Lib/test/test_logging.py Sun Apr 5 13:06:24 2009 @@ -912,8 +912,8 @@ class WarningsTest(BaseTest): def test_warnings(self): - logging.captureWarnings(True) with warnings.catch_warnings(): + logging.captureWarnings(True) warnings.filterwarnings("always", category=UserWarning) try: file = cStringIO.StringIO() From python-checkins at python.org Sun Apr 5 13:07:14 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 13:07:14 +0200 (CEST) Subject: [Python-checkins] r71222 - in python/trunk: Modules/_sqlite/connection.c Modules/_sqlite/module.c Objects/object.c Message-ID: <20090405110714.9C4B51E4012@bag.python.org> Author: georg.brandl Date: Sun Apr 5 13:07:14 2009 New Revision: 71222 Log: #5615: make it possible to configure --without-threads again. Modified: python/trunk/Modules/_sqlite/connection.c python/trunk/Modules/_sqlite/module.c python/trunk/Objects/object.c Modified: python/trunk/Modules/_sqlite/connection.c ============================================================================== --- python/trunk/Modules/_sqlite/connection.c (original) +++ python/trunk/Modules/_sqlite/connection.c Sun Apr 5 13:07:14 2009 @@ -168,8 +168,9 @@ self->detect_types = detect_types; self->timeout = timeout; (void)sqlite3_busy_timeout(self->db, (int)(timeout*1000)); - +#ifdef WITH_THREAD self->thread_ident = PyThread_get_thread_ident(); +#endif self->check_same_thread = check_same_thread; self->function_pinboard = PyDict_New(); @@ -585,9 +586,11 @@ PyObject* py_func; PyObject* py_retval = NULL; +#ifdef WITH_THREAD PyGILState_STATE threadstate; threadstate = PyGILState_Ensure(); +#endif py_func = (PyObject*)sqlite3_user_data(context); @@ -609,7 +612,9 @@ _sqlite3_result_error(context, "user-defined function raised exception", -1); } +#ifdef WITH_THREAD PyGILState_Release(threadstate); +#endif } static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_value** params) @@ -620,9 +625,11 @@ PyObject** aggregate_instance; PyObject* stepmethod = NULL; +#ifdef WITH_THREAD PyGILState_STATE threadstate; threadstate = PyGILState_Ensure(); +#endif aggregate_class = (PyObject*)sqlite3_user_data(context); @@ -669,7 +676,9 @@ Py_XDECREF(stepmethod); Py_XDECREF(function_result); +#ifdef WITH_THREAD PyGILState_Release(threadstate); +#endif } void _pysqlite_final_callback(sqlite3_context* context) @@ -678,9 +687,11 @@ PyObject** aggregate_instance; PyObject* aggregate_class; +#ifdef WITH_THREAD PyGILState_STATE threadstate; threadstate = PyGILState_Ensure(); +#endif aggregate_class = (PyObject*)sqlite3_user_data(context); @@ -708,7 +719,9 @@ Py_XDECREF(*aggregate_instance); Py_XDECREF(function_result); +#ifdef WITH_THREAD PyGILState_Release(threadstate); +#endif } void _pysqlite_drop_unused_statement_references(pysqlite_Connection* self) @@ -803,9 +816,11 @@ { PyObject *ret; int rc; +#ifdef WITH_THREAD PyGILState_STATE gilstate; gilstate = PyGILState_Ensure(); +#endif ret = PyObject_CallFunction((PyObject*)user_arg, "issss", action, arg1, arg2, dbname, access_attempt_source); if (!ret) { @@ -825,7 +840,9 @@ Py_DECREF(ret); } +#ifdef WITH_THREAD PyGILState_Release(gilstate); +#endif return rc; } @@ -833,9 +850,11 @@ { int rc; PyObject *ret; +#ifdef WITH_THREAD PyGILState_STATE gilstate; gilstate = PyGILState_Ensure(); +#endif ret = PyObject_CallFunction((PyObject*)user_arg, ""); if (!ret) { @@ -852,7 +871,9 @@ Py_DECREF(ret); } +#ifdef WITH_THREAD PyGILState_Release(gilstate); +#endif return rc; } @@ -907,6 +928,7 @@ int pysqlite_check_thread(pysqlite_Connection* self) { +#ifdef WITH_THREAD if (self->check_same_thread) { if (PyThread_get_thread_ident() != self->thread_ident) { PyErr_Format(pysqlite_ProgrammingError, @@ -917,7 +939,7 @@ } } - +#endif return 1; } @@ -1139,12 +1161,14 @@ PyObject* callback = (PyObject*)context; PyObject* string1 = 0; PyObject* string2 = 0; +#ifdef WITH_THREAD PyGILState_STATE gilstate; - +#endif PyObject* retval = NULL; int result = 0; - +#ifdef WITH_THREAD gilstate = PyGILState_Ensure(); +#endif if (PyErr_Occurred()) { goto finally; @@ -1173,9 +1197,9 @@ Py_XDECREF(string1); Py_XDECREF(string2); Py_XDECREF(retval); - +#ifdef WITH_THREAD PyGILState_Release(gilstate); - +#endif return result; } Modified: python/trunk/Modules/_sqlite/module.c ============================================================================== --- python/trunk/Modules/_sqlite/module.c (original) +++ python/trunk/Modules/_sqlite/module.c Sun Apr 5 13:07:14 2009 @@ -445,7 +445,9 @@ * threads have already been initialized. * (see pybsddb-users mailing list post on 2002-08-07) */ +#ifdef WITH_THREAD PyEval_InitThreads(); +#endif error: if (PyErr_Occurred()) Modified: python/trunk/Objects/object.c ============================================================================== --- python/trunk/Objects/object.c (original) +++ python/trunk/Objects/object.c Sun Apr 5 13:07:14 2009 @@ -336,11 +336,17 @@ if (op == NULL) fprintf(stderr, "NULL\n"); else { +#ifdef WITH_THREAD PyGILState_STATE gil; +#endif fprintf(stderr, "object : "); +#ifdef WITH_THREAD gil = PyGILState_Ensure(); +#endif (void)PyObject_Print(op, stderr, 0); +#ifdef WITH_THREAD PyGILState_Release(gil); +#endif /* XXX(twouters) cast refcount to long until %zd is universally available */ fprintf(stderr, "\n" From python-checkins at python.org Sun Apr 5 13:11:12 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 13:11:12 +0200 (CEST) Subject: [Python-checkins] r71223 - python/branches/py3k/Makefile.pre.in Message-ID: <20090405111112.AC8E21E401B@bag.python.org> Author: georg.brandl Date: Sun Apr 5 13:11:12 2009 New Revision: 71223 Log: #5606: fix formatter.h dependencies in the Makefile. 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 Sun Apr 5 13:11:12 2009 @@ -585,8 +585,7 @@ Objects/bytearrayobject.o: $(srcdir)/Objects/bytearrayobject.c $(BYTESTR_DEPS) Objects/unicodeobject.o: $(srcdir)/Objects/unicodeobject.c \ - $(BYTESTR_DEPS) \ - $(srcdir)/Objects/stringlib/formatter.h + $(BYTESTR_DEPS) $(OPCODETARGETS_H): $(OPCODETARGETGEN_FILES) $(OPCODETARGETGEN) $(OPCODETARGETS_H) @@ -594,7 +593,8 @@ Python/ceval.o: $(OPCODETARGETS_H) Python/formatter_unicode.o: $(srcdir)/Python/formatter_unicode.c \ - $(BYTESTR_DEPS) + $(BYTESTR_DEPS) \ + $(srcdir)/Objects/stringlib/formatter.h ############################################################################ From buildbot at python.org Sun Apr 5 13:40:56 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 05 Apr 2009 11:40:56 +0000 Subject: [Python-checkins] buildbot failure in OS X x86 2.6 Message-ID: <20090405114056.E3B551E4012@bag.python.org> The Buildbot has detected a new failure of OS X x86 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/OS%20X%20x86%202.6/builds/181 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: noller-osx86 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: Traceback (most recent call last): File "/Users/buildbot/buildarea/2.6.noller-osx86/build/Lib/SocketServer.py", line 281, in _handle_request_noblock self.process_request(request, client_address) File "/Users/buildbot/buildarea/2.6.noller-osx86/build/Lib/SocketServer.py", line 307, in process_request self.finish_request(request, client_address) File "/Users/buildbot/buildarea/2.6.noller-osx86/build/Lib/SocketServer.py", line 320, in finish_request self.RequestHandlerClass(request, client_address, self) File "/Users/buildbot/buildarea/2.6.noller-osx86/build/Lib/SocketServer.py", line 615, in __init__ self.handle() File "/Users/buildbot/buildarea/2.6.noller-osx86/build/Lib/BaseHTTPServer.py", line 329, in handle self.handle_one_request() File "/Users/buildbot/buildarea/2.6.noller-osx86/build/Lib/BaseHTTPServer.py", line 323, in handle_one_request method() File "/Users/buildbot/buildarea/2.6.noller-osx86/build/Lib/test/test_urllib2_localnet.py", line 209, in do_GET if self.digest_auth_handler.handle_request(self): File "/Users/buildbot/buildarea/2.6.noller-osx86/build/Lib/test/test_urllib2_localnet.py", line 158, in handle_request return self._return_auth_challenge(request_handler) File "/Users/buildbot/buildarea/2.6.noller-osx86/build/Lib/test/test_urllib2_localnet.py", line 141, in _return_auth_challenge request_handler.end_headers() File "/Users/buildbot/buildarea/2.6.noller-osx86/build/Lib/BaseHTTPServer.py", line 401, in end_headers self.wfile.write("\r\n") File "/Users/buildbot/buildarea/2.6.noller-osx86/build/Lib/socket.py", line 297, in write self.flush() File "/Users/buildbot/buildarea/2.6.noller-osx86/build/Lib/socket.py", line 284, in flush self._sock.sendall(buffer) error: [Errno 32] Broken pipe 1 test failed: test_urllib2_localnet make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sun Apr 5 13:47:36 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 13:47:36 +0200 (CEST) Subject: [Python-checkins] r71224 - in python/branches/py3k: Modules/_io/bufferedio.c Modules/_sqlite/connection.c Modules/_sqlite/module.c Objects/object.c Message-ID: <20090405114736.9AFD41E4012@bag.python.org> Author: georg.brandl Date: Sun Apr 5 13:47:34 2009 New Revision: 71224 Log: Merge revision 71222 from trunk: #5615: make it possible to configure --without-threads again. Modified: python/branches/py3k/ (props changed) python/branches/py3k/Modules/_io/bufferedio.c python/branches/py3k/Modules/_sqlite/connection.c python/branches/py3k/Modules/_sqlite/module.c python/branches/py3k/Objects/object.c Modified: python/branches/py3k/Modules/_io/bufferedio.c ============================================================================== --- python/branches/py3k/Modules/_io/bufferedio.c (original) +++ python/branches/py3k/Modules/_io/bufferedio.c Sun Apr 5 13:47:34 2009 @@ -204,7 +204,9 @@ isn't ready for writing. */ Py_off_t write_end; +#ifdef WITH_THREAD PyThread_type_lock lock; +#endif Py_ssize_t buffer_size; Py_ssize_t buffer_mask; @@ -239,6 +241,7 @@ /* These macros protect the BufferedObject against concurrent operations. */ +#ifdef WITH_THREAD #define ENTER_BUFFERED(self) \ Py_BEGIN_ALLOW_THREADS \ PyThread_acquire_lock(self->lock, 1); \ @@ -246,6 +249,10 @@ #define LEAVE_BUFFERED(self) \ PyThread_release_lock(self->lock); +#else +#define ENTER_BUFFERED(self) +#define LEAVE_BUFFERED(self) +#endif #define CHECK_INITIALIZED(self) \ if (self->ok <= 0) { \ @@ -305,10 +312,12 @@ PyMem_Free(self->buffer); self->buffer = NULL; } +#ifdef WITH_THREAD if (self->lock) { PyThread_free_lock(self->lock); self->lock = NULL; } +#endif Py_CLEAR(self->dict); Py_TYPE(self)->tp_free((PyObject *)self); } @@ -565,11 +574,13 @@ PyErr_NoMemory(); return -1; } +#ifdef WITH_THREAD self->lock = PyThread_allocate_lock(); if (self->lock == NULL) { PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock"); return -1; } +#endif /* Find out whether buffer_size is a power of 2 */ /* XXX is this optimization useful? */ for (n = self->buffer_size - 1; n & 1; n >>= 1) Modified: python/branches/py3k/Modules/_sqlite/connection.c ============================================================================== --- python/branches/py3k/Modules/_sqlite/connection.c (original) +++ python/branches/py3k/Modules/_sqlite/connection.c Sun Apr 5 13:47:34 2009 @@ -124,8 +124,9 @@ self->detect_types = detect_types; self->timeout = timeout; (void)sqlite3_busy_timeout(self->db, (int)(timeout*1000)); - +#ifdef WITH_THREAD self->thread_ident = PyThread_get_thread_ident(); +#endif self->check_same_thread = check_same_thread; self->function_pinboard = PyDict_New(); @@ -510,9 +511,11 @@ PyObject* py_func; PyObject* py_retval = NULL; +#ifdef WITH_THREAD PyGILState_STATE threadstate; threadstate = PyGILState_Ensure(); +#endif py_func = (PyObject*)sqlite3_user_data(context); @@ -534,7 +537,9 @@ _sqlite3_result_error(context, "user-defined function raised exception", -1); } +#ifdef WITH_THREAD PyGILState_Release(threadstate); +#endif } static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_value** params) @@ -545,9 +550,11 @@ PyObject** aggregate_instance; PyObject* stepmethod = NULL; +#ifdef WITH_THREAD PyGILState_STATE threadstate; threadstate = PyGILState_Ensure(); +#endif aggregate_class = (PyObject*)sqlite3_user_data(context); @@ -594,7 +601,9 @@ Py_XDECREF(stepmethod); Py_XDECREF(function_result); +#ifdef WITH_THREAD PyGILState_Release(threadstate); +#endif } void _pysqlite_final_callback(sqlite3_context* context) @@ -603,9 +612,11 @@ PyObject** aggregate_instance; PyObject* aggregate_class; +#ifdef WITH_THREAD PyGILState_STATE threadstate; threadstate = PyGILState_Ensure(); +#endif aggregate_class = (PyObject*)sqlite3_user_data(context); @@ -633,7 +644,9 @@ Py_XDECREF(*aggregate_instance); Py_XDECREF(function_result); +#ifdef WITH_THREAD PyGILState_Release(threadstate); +#endif } void _pysqlite_drop_unused_statement_references(pysqlite_Connection* self) @@ -728,9 +741,11 @@ { PyObject *ret; int rc; +#ifdef WITH_THREAD PyGILState_STATE gilstate; gilstate = PyGILState_Ensure(); +#endif ret = PyObject_CallFunction((PyObject*)user_arg, "issss", action, arg1, arg2, dbname, access_attempt_source); if (!ret) { @@ -750,7 +765,9 @@ Py_DECREF(ret); } +#ifdef WITH_THREAD PyGILState_Release(gilstate); +#endif return rc; } @@ -758,9 +775,11 @@ { int rc; PyObject *ret; +#ifdef WITH_THREAD PyGILState_STATE gilstate; gilstate = PyGILState_Ensure(); +#endif ret = PyObject_CallFunction((PyObject*)user_arg, ""); if (!ret) { @@ -777,7 +796,9 @@ Py_DECREF(ret); } +#ifdef WITH_THREAD PyGILState_Release(gilstate); +#endif return rc; } @@ -832,6 +853,7 @@ int pysqlite_check_thread(pysqlite_Connection* self) { +#ifdef WITH_THREAD if (self->check_same_thread) { if (PyThread_get_thread_ident() != self->thread_ident) { PyErr_Format(pysqlite_ProgrammingError, @@ -842,7 +864,7 @@ } } - +#endif return 1; } @@ -1067,12 +1089,14 @@ PyObject* callback = (PyObject*)context; PyObject* string1 = 0; PyObject* string2 = 0; +#ifdef WITH_THREAD PyGILState_STATE gilstate; - +#endif PyObject* retval = NULL; int result = 0; - +#ifdef WITH_THREAD gilstate = PyGILState_Ensure(); +#endif if (PyErr_Occurred()) { goto finally; @@ -1101,9 +1125,9 @@ Py_XDECREF(string1); Py_XDECREF(string2); Py_XDECREF(retval); - +#ifdef WITH_THREAD PyGILState_Release(gilstate); - +#endif return result; } Modified: python/branches/py3k/Modules/_sqlite/module.c ============================================================================== --- python/branches/py3k/Modules/_sqlite/module.c (original) +++ python/branches/py3k/Modules/_sqlite/module.c Sun Apr 5 13:47:34 2009 @@ -459,7 +459,9 @@ * threads have already been initialized. * (see pybsddb-users mailing list post on 2002-08-07) */ +#ifdef WITH_THREAD PyEval_InitThreads(); +#endif error: if (PyErr_Occurred()) Modified: python/branches/py3k/Objects/object.c ============================================================================== --- python/branches/py3k/Objects/object.c (original) +++ python/branches/py3k/Objects/object.c Sun Apr 5 13:47:34 2009 @@ -349,11 +349,17 @@ if (op == NULL) fprintf(stderr, "NULL\n"); else { +#ifdef WITH_THREAD PyGILState_STATE gil; +#endif fprintf(stderr, "object : "); +#ifdef WITH_THREAD gil = PyGILState_Ensure(); +#endif (void)PyObject_Print(op, stderr, 0); +#ifdef WITH_THREAD PyGILState_Release(gil); +#endif /* XXX(twouters) cast refcount to long until %zd is universally available */ fprintf(stderr, "\n" From python-checkins at python.org Sun Apr 5 13:54:07 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 13:54:07 +0200 (CEST) Subject: [Python-checkins] r71225 - python/trunk/Python/getargs.c Message-ID: <20090405115407.B2F9D1E4012@bag.python.org> Author: georg.brandl Date: Sun Apr 5 13:54:07 2009 New Revision: 71225 Log: #5580: no need to use parentheses when converterr() argument is actually a type description. Modified: python/trunk/Python/getargs.c Modified: python/trunk/Python/getargs.c ============================================================================== --- python/trunk/Python/getargs.c (original) +++ python/trunk/Python/getargs.c Sun Apr 5 13:54:07 2009 @@ -1108,7 +1108,7 @@ != size) { Py_DECREF(s); return converterr( - "(encoded string without NULL bytes)", + "encoded string without NULL bytes", arg, msgbuf, bufsize); } *buffer = PyMem_NEW(char, size + 1); From python-checkins at python.org Sun Apr 5 14:09:40 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 5 Apr 2009 14:09:40 +0200 (CEST) Subject: [Python-checkins] r71226 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090405120940.5F3EE1E4081@bag.python.org> Author: mark.dickinson Date: Sun Apr 5 14:09:39 2009 New Revision: 71226 Log: Don't use Gay's MULTIPLE_THREADS: we'll rely on the GIL instead. Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Sun Apr 5 14:09:39 2009 @@ -361,11 +361,6 @@ #endif #endif /* NO_LONG_LONG */ -#ifndef MULTIPLE_THREADS -#define ACQUIRE_DTOA_LOCK(n) /*nothing*/ -#define FREE_DTOA_LOCK(n) /*nothing*/ -#endif - #define Kmax 7 struct @@ -389,9 +384,6 @@ unsigned int len; #endif - ACQUIRE_DTOA_LOCK(0); - /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */ - /* but this case seems very unlikely. */ if (k <= Kmax && (rv = freelist[k])) freelist[k] = rv->next; else { @@ -418,7 +410,6 @@ } rv->sign = rv->wds = 0; error: - FREE_DTOA_LOCK(0); return rv; } @@ -430,10 +421,8 @@ if (v->k > Kmax) FREE((void*)v); else { - ACQUIRE_DTOA_LOCK(0); v->next = freelist[v->k]; freelist[v->k] = v; - FREE_DTOA_LOCK(0); } } } @@ -704,17 +693,8 @@ return b; if (!(p5 = p5s)) { /* first time */ -#ifdef MULTIPLE_THREADS - ACQUIRE_DTOA_LOCK(1); - if (!(p5 = p5s)) { - p5 = p5s = i2b(625); - p5->next = 0; - } - FREE_DTOA_LOCK(1); -#else p5 = p5s = i2b(625); p5->next = 0; -#endif } for(;;) { if (k & 1) { @@ -725,17 +705,8 @@ if (!(k >>= 1)) break; if (!(p51 = p5->next)) { -#ifdef MULTIPLE_THREADS - ACQUIRE_DTOA_LOCK(1); - if (!(p51 = p5->next)) { - p51 = p5->next = mult(p5,p5); - p51->next = 0; - } - FREE_DTOA_LOCK(1); -#else p51 = p5->next = mult(p5,p5); p51->next = 0; -#endif } p5 = p51; } @@ -2062,9 +2033,7 @@ return sign ? -dval(&rv) : dval(&rv); } -#ifndef MULTIPLE_THREADS static char *dtoa_result; -#endif static char * rv_alloc(int i) @@ -2079,9 +2048,7 @@ r = (int*)Balloc(k); *r = k; return -#ifndef MULTIPLE_THREADS dtoa_result = -#endif (char *)(r+1); } @@ -2109,10 +2076,8 @@ Bigint *b = (Bigint *)((int *)s - 1); b->maxwds = 1 << (b->k = *(int*)b); Bfree(b); -#ifndef MULTIPLE_THREADS if (s == dtoa_result) dtoa_result = 0; -#endif } /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. @@ -2200,12 +2165,10 @@ double ds; char *s, *s0; -#ifndef MULTIPLE_THREADS if (dtoa_result) { freedtoa(dtoa_result); dtoa_result = 0; } -#endif u.d = dd; if (word0(&u) & Sign_bit) { From python-checkins at python.org Sun Apr 5 14:28:49 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 5 Apr 2009 14:28:49 +0200 (CEST) Subject: [Python-checkins] r71227 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090405122849.0748C1E4012@bag.python.org> Author: mark.dickinson Date: Sun Apr 5 14:28:48 2009 New Revision: 71227 Log: Add return value checking to multadd, s2b, i2b, mult Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Sun Apr 5 14:28:48 2009 @@ -391,7 +391,7 @@ #ifdef Omit_Private_Memory rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); if (rv == NULL) - goto error; + return NULL; #else len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) /sizeof(double); @@ -402,14 +402,13 @@ else { rv = (Bigint*)MALLOC(len*sizeof(double)); if (rv == NULL) - goto error; + return NULL; } #endif rv->k = k; rv->maxwds = x; } rv->sign = rv->wds = 0; - error: return rv; } @@ -465,6 +464,10 @@ if (carry) { if (wds >= b->maxwds) { b1 = Balloc(b->k+1); + if (b1 == NULL){ + Bfree(b); + return NULL; + } Bcopy(b1, b); Bfree(b); b = b1; @@ -486,20 +489,28 @@ x = (nd + 8) / 9; for(k = 0, y = 1; x > y; y <<= 1, k++) ; b = Balloc(k); + if (b == NULL) + return NULL; b->x[0] = y9; b->wds = 1; i = 9; if (9 < nd0) { s += 9; - do b = multadd(b, 10, *s++ - '0'); - while(++i < nd0); + do { + b = multadd(b, 10, *s++ - '0'); + if (b == NULL) + return NULL; + } while(++i < nd0); s += dplen; } else s += dplen + 9; - for(; i < nd; i++) + for(; i < nd; i++) { b = multadd(b, 10, *s++ - '0'); + if (b == NULL) + return NULL; + } return b; } @@ -584,6 +595,8 @@ Bigint *b; b = Balloc(1); + if (b == NULL) + return NULL; b->x[0] = i; b->wds = 1; return b; @@ -616,6 +629,8 @@ if (wc > a->maxwds) k++; c = Balloc(k); + if (c == NULL) + return NULL; for(x = c->x, xa = x + wc; x < xa; x++) *x = 0; xa = a->x; From python-checkins at python.org Sun Apr 5 14:32:47 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 5 Apr 2009 14:32:47 +0200 (CEST) Subject: [Python-checkins] r71228 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090405123247.E17811E4012@bag.python.org> Author: mark.dickinson Date: Sun Apr 5 14:32:47 2009 New Revision: 71228 Log: add error checking to pow5mult Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Sun Apr 5 14:32:47 2009 @@ -701,27 +701,44 @@ int i; static int p05[3] = { 5, 25, 125 }; - if ((i = k & 3)) + if ((i = k & 3)) { b = multadd(b, p05[i-1], 0); + if (b == NULL) + return NULL; + } if (!(k >>= 2)) return b; - if (!(p5 = p5s)) { + p5 = p5s; + if (!p5) { /* first time */ - p5 = p5s = i2b(625); + p5 = i2b(625); + if (p5 == NULL) { + Bfree(b); + return NULL; + } + p5s = p5; p5->next = 0; } for(;;) { if (k & 1) { b1 = mult(b, p5); Bfree(b); + if (b1 == NULL) + return NULL; b = b1; } if (!(k >>= 1)) break; - if (!(p51 = p5->next)) { - p51 = p5->next = mult(p5,p5); + p51 = p5->next; + if (!p51) { + p51 = mult(p5,p5); + if (p51 == NULL) { + Bfree(b); + return NULL; + } p51->next = 0; + p5->next = p51; } p5 = p51; } From buildbot at python.org Sun Apr 5 14:42:27 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 05 Apr 2009 12:42:27 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 3.x Message-ID: <20090405124228.133AE1E4012@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%20gentoo%203.x/builds/583 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-amd64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_smtplib make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sun Apr 5 14:43:09 2009 From: python-checkins at python.org (matthias.klose) Date: Sun, 5 Apr 2009 14:43:09 +0200 (CEST) Subject: [Python-checkins] r71229 - in python/trunk: Include/object.h Misc/NEWS Message-ID: <20090405124309.3735B1E4012@bag.python.org> Author: matthias.klose Date: Sun Apr 5 14:43:08 2009 New Revision: 71229 Log: - Py_DECREF: Add `do { ... } while (0)' to avoid compiler warnings. (avoiding brown paper typo this time) Modified: python/trunk/Include/object.h python/trunk/Misc/NEWS Modified: python/trunk/Include/object.h ============================================================================== --- python/trunk/Include/object.h (original) +++ python/trunk/Include/object.h Sun Apr 5 14:43:08 2009 @@ -749,11 +749,13 @@ ((PyObject*)(op))->ob_refcnt++) #define Py_DECREF(op) \ - if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ - --((PyObject*)(op))->ob_refcnt != 0) \ - _Py_CHECK_REFCNT(op) \ - else \ - _Py_Dealloc((PyObject *)(op)) + do { \ + if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ + --((PyObject*)(op))->ob_refcnt != 0) \ + _Py_CHECK_REFCNT(op) \ + else \ + _Py_Dealloc((PyObject *)(op)); \ + } while (0) /* Safely decref `op` and set `op` to NULL, especially useful in tp_clear * and tp_dealloc implementatons. Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Apr 5 14:43:08 2009 @@ -207,6 +207,8 @@ - Issue #3845: In PyRun_SimpleFileExFlags avoid invalid memory access with short file names. +- Py_DECREF: Add `do { ... } while (0)' to avoid compiler warnings. + Library ------- From python-checkins at python.org Sun Apr 5 14:47:30 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 5 Apr 2009 14:47:30 +0200 (CEST) Subject: [Python-checkins] r71230 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090405124730.81DAA1E4012@bag.python.org> Author: mark.dickinson Date: Sun Apr 5 14:47:30 2009 New Revision: 71230 Log: More return value checks, in lshift, diff and d2b Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Sun Apr 5 14:47:30 2009 @@ -759,6 +759,10 @@ for(i = b->maxwds; n1 > i; i <<= 1) k1++; b1 = Balloc(k1); + if (b1 == NULL) { + Bfree(b); + return NULL; + } x1 = b1->x; for(i = 0; i < n; i++) *x1++ = 0; @@ -830,6 +834,8 @@ i = cmp(a,b); if (!i) { c = Balloc(0); + if (c == NULL) + return NULL; c->wds = 1; c->x[0] = 0; return c; @@ -843,6 +849,8 @@ else i = 0; c = Balloc(a->k); + if (c == NULL) + return NULL; c->sign = i; wa = a->wds; xa = a->x; @@ -976,6 +984,8 @@ #define d1 word1(d) b = Balloc(1); + if (b == NULL) + return NULL; x = b->x; z = d0 & Frac_mask; From python-checkins at python.org Sun Apr 5 15:05:45 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 5 Apr 2009 15:05:45 +0200 (CEST) Subject: [Python-checkins] r71231 - python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt Message-ID: <20090405130545.41E1E1E4012@bag.python.org> Author: mark.dickinson Date: Sun Apr 5 15:05:45 2009 New Revision: 71231 Log: Disable '%.f' % 1e50 test for now. Modified: python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt Modified: python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt (original) +++ python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt Sun Apr 5 15:05:45 2009 @@ -22,7 +22,7 @@ %.0f 123.456 -> 123 %.0f 1234.56 -> 1235 %.0f 1e49 -> 9999999999999999464902769475481793196872414789632 -%.0f 1e50 -> 100000000000000007629769841091887003294964970946560 +-- %.0f 1e50 -> 100000000000000007629769841091887003294964970946560 %.0f 9.9999999999999987e+49 -> 99999999999999986860582406952576489172979654066176 -- precision 1 From python-checkins at python.org Sun Apr 5 15:06:13 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 5 Apr 2009 15:06:13 +0200 (CEST) Subject: [Python-checkins] r71232 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090405130613.1B1A91E4012@bag.python.org> Author: mark.dickinson Date: Sun Apr 5 15:06:12 2009 New Revision: 71232 Log: Enable ADD_DOT_0 flag for 'g' mode. Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Sun Apr 5 15:06:12 2009 @@ -608,6 +608,10 @@ case 'g': if (decpt <= -4 || decpt > precision) use_exp = 1; + /* assumes that not both of add_dot_0_if_integer and + use_alt_formatting are set */ + else if (add_dot_0_if_integer) + min_digits = decpt + 1; if (use_alt_formatting) min_digits = precision; break; From python-checkins at python.org Sun Apr 5 15:07:00 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 5 Apr 2009 15:07:00 +0200 (CEST) Subject: [Python-checkins] r71233 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090405130700.A54951E4012@bag.python.org> Author: mark.dickinson Date: Sun Apr 5 15:07:00 2009 New Revision: 71233 Log: Remove Need_Hexdig define and associated code Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Sun Apr 5 15:07:00 2009 @@ -1076,34 +1076,6 @@ #define Scale_Bit 0x10 #define n_bigtens 5 -#undef Need_Hexdig -#ifdef INFNAN_CHECK -#endif - -#ifndef Need_Hexdig -#endif - -#ifdef Need_Hexdig /*{*/ -static unsigned char hexdig[256]; - - static void -htinit(unsigned char *h, unsigned char *s, int inc) -{ - int i, j; - for(i = 0; (j = s[i]) !=0; i++) - h[j] = i + inc; - } - - static void -hexdig_init(void) -{ -#define USC (unsigned char *) - htinit(hexdig, USC "0123456789", 0x10); - htinit(hexdig, USC "abcdef", 0x10 + 10); - htinit(hexdig, USC "ABCDEF", 0x10 + 10); - } -#endif /* } Need_Hexdig */ - #ifdef INFNAN_CHECK #ifndef NAN_WORD0 From python-checkins at python.org Sun Apr 5 15:16:36 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 15:16:36 +0200 (CEST) Subject: [Python-checkins] r71234 - python/trunk/Objects/bytearrayobject.c Message-ID: <20090405131636.22C8F1E4012@bag.python.org> Author: georg.brandl Date: Sun Apr 5 15:16:35 2009 New Revision: 71234 Log: Whitespace normalization. Modified: python/trunk/Objects/bytearrayobject.c Modified: python/trunk/Objects/bytearrayobject.c ============================================================================== --- python/trunk/Objects/bytearrayobject.c (original) +++ python/trunk/Objects/bytearrayobject.c Sun Apr 5 15:16:35 2009 @@ -1097,7 +1097,7 @@ { if (self->ob_exports > 0) { PyErr_SetString(PyExc_SystemError, - "deallocated bytearray object has exported buffers"); + "deallocated bytearray object has exported buffers"); PyErr_Print(); } if (self->ob_bytes != 0) { @@ -2691,10 +2691,10 @@ /* Try to determine the length of the argument. 32 is abitrary. */ buf_size = _PyObject_LengthHint(arg, 32); - if (buf_size == -1) { - Py_DECREF(it); - return NULL; - } + if (buf_size == -1) { + Py_DECREF(it); + return NULL; + } bytes_obj = PyByteArray_FromStringAndSize(NULL, buf_size); if (bytes_obj == NULL) @@ -3143,10 +3143,10 @@ static PyObject * bytes_sizeof(PyByteArrayObject *self) { - Py_ssize_t res; + Py_ssize_t res; - res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char); - return PyInt_FromSsize_t(res); + res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char); + return PyInt_FromSsize_t(res); } static PySequenceMethods bytes_as_sequence = { From python-checkins at python.org Sun Apr 5 15:40:01 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 5 Apr 2009 15:40:01 +0200 (CEST) Subject: [Python-checkins] r71235 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090405134001.7CCF01E4029@bag.python.org> Author: mark.dickinson Date: Sun Apr 5 15:40:01 2009 New Revision: 71235 Log: Give bigcomp a return value (-1 if an error occurred, else 0). Check return values within bigcomp. Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Sun Apr 5 15:40:01 2009 @@ -1216,7 +1216,9 @@ } - static void +/* return 0 on success, -1 on failure */ + + static int bigcomp (U *rv, CONST char *s0, BCinfo *bc) { @@ -1232,6 +1234,8 @@ if (rv->d == 0.) { /* special case: value near underflow-to-zero */ /* threshold was rounded to zero */ b = i2b(1); + if (b == NULL) + return -1; p2 = Emin - P + 1; bbits = 1; #ifdef Avoid_Underflow @@ -1249,7 +1253,11 @@ } else #endif + { b = d2b(rv, &p2, &bbits); + if (b == NULL) + return -1; + } #ifdef Avoid_Underflow p2 -= bc->scale; #endif @@ -1260,6 +1268,8 @@ #ifdef Sudden_Underflow Bfree(b); b = i2b(1); + if (b == NULL) + return -1; p2 = Emin; i = P - 1; #ifdef Avoid_Underflow @@ -1274,6 +1284,8 @@ } { b = lshift(b, ++i); + if (b == NULL) + return -1; b->x[0] |= 1; } #ifndef Sudden_Underflow @@ -1281,13 +1293,27 @@ #endif p2 -= p5 + i; d = i2b(1); + if (d == NULL) { + Bfree(b); + return -1; + } /* Arrange for convenient computation of quotients: * shift left if necessary so divisor has 4 leading 0 bits. */ - if (p5 > 0) + if (p5 > 0) { d = pow5mult(d, p5); - else if (p5 < 0) + if (d == NULL) { + Bfree(b); + return -1; + } + } + else if (p5 < 0) { b = pow5mult(b, -p5); + if (b == NULL) { + Bfree(d); + return -1; + } + } if (p2 > 0) { b2 = p2; d2 = 0; @@ -1297,16 +1323,30 @@ d2 = -p2; } i = dshift(d, d2); - if ((b2 += i) > 0) + if ((b2 += i) > 0) { b = lshift(b, b2); - if ((d2 += i) > 0) + if (b == NULL) { + Bfree(d); + return -1; + } + } + if ((d2 += i) > 0) { d = lshift(d, d2); + if (d == NULL) { + Bfree(b); + return -1; + } + } /* Now b/d = exactly half-way between the two floating-point values */ /* on either side of the input string. Compute first digit of b/d. */ if (!(dig = quorem(b,d))) { b = multadd(b, 10, 0); /* very unlikely */ + if (b == NULL) { + Bfree(d); + return -1; + } dig = quorem(b,d); } @@ -1321,6 +1361,10 @@ goto ret; } b = multadd(b, 10, 0); + if (b == NULL) { + Bfree(d); + return -1; + } dig = quorem(b,d); } for(j = bc->dp1; i++ < nd;) { @@ -1332,6 +1376,10 @@ goto ret; } b = multadd(b, 10, 0); + if (b == NULL) { + Bfree(d); + return -1; + } dig = quorem(b,d); } if (b->x[0] || b->wds > 1) @@ -1363,7 +1411,7 @@ } } - return; + return 0; } double From python-checkins at python.org Sun Apr 5 15:44:43 2009 From: python-checkins at python.org (matthias.klose) Date: Sun, 5 Apr 2009 15:44:43 +0200 (CEST) Subject: [Python-checkins] r71236 - python/branches/release30-maint/Doc/Makefile Message-ID: <20090405134443.F3A921E4029@bag.python.org> Author: matthias.klose Date: Sun Apr 5 15:44:43 2009 New Revision: 71236 Log: Merged revisions 70148 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r70148 | benjamin.peterson | 2009-03-03 23:55:55 +0100 (Di, 03 M?r 2009) | 1 line don't bother with version in doc builds ........ Modified: python/branches/release30-maint/Doc/Makefile Modified: python/branches/release30-maint/Doc/Makefile ============================================================================== --- python/branches/release30-maint/Doc/Makefile (original) +++ python/branches/release30-maint/Doc/Makefile Sun Apr 5 15:44:43 2009 @@ -4,7 +4,7 @@ # # You can set these variables from the command line. -PYTHON = python2.5 +PYTHON = python SVNROOT = http://svn.python.org/projects SPHINXOPTS = PAPER = From python-checkins at python.org Sun Apr 5 16:24:53 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 16:24:53 +0200 (CEST) Subject: [Python-checkins] r71237 - in python/trunk/Lib: test/test_traceback.py traceback.py Message-ID: <20090405142453.7AE541E4029@bag.python.org> Author: georg.brandl Date: Sun Apr 5 16:24:52 2009 New Revision: 71237 Log: #1326077: fix traceback formatting of SyntaxErrors. This fixes two differences with formatting coming from Python: a) the reproduction of location details in the error message if no line text is given, b) the prefixing of the last line by one space. Modified: python/trunk/Lib/test/test_traceback.py python/trunk/Lib/traceback.py Modified: python/trunk/Lib/test/test_traceback.py ============================================================================== --- python/trunk/Lib/test/test_traceback.py (original) +++ python/trunk/Lib/test/test_traceback.py Sun Apr 5 16:24:52 2009 @@ -8,16 +8,6 @@ import traceback -try: - raise KeyError -except KeyError: - type_, value, tb = sys.exc_info() - file_ = StringIO() - traceback_print(tb, file_) - example_traceback = file_.getvalue() -else: - raise Error("unable to create test traceback string") - class TracebackCases(unittest.TestCase): # For now, a very minimal set of tests. I want to be sure that @@ -162,9 +152,24 @@ class TracebackFormatTests(unittest.TestCase): - def test_traceback_indentation(self): + def test_traceback_format(self): + try: + raise KeyError('blah') + except KeyError: + type_, value, tb = sys.exc_info() + traceback_fmt = 'Traceback (most recent call last):\n' + \ + ''.join(traceback.format_tb(tb)) + file_ = StringIO() + traceback_print(tb, file_) + python_fmt = file_.getvalue() + else: + raise Error("unable to create test traceback string") + + # Make sure that Python and the traceback module format the same thing + self.assertEquals(traceback_fmt, python_fmt) + # Make sure that the traceback is properly indented. - tb_lines = example_traceback.splitlines() + tb_lines = python_fmt.splitlines() self.assertEquals(len(tb_lines), 3) banner, location, source_line = tb_lines self.assert_(banner.startswith('Traceback')) Modified: python/trunk/Lib/traceback.py ============================================================================== --- python/trunk/Lib/traceback.py (original) +++ python/trunk/Lib/traceback.py Sun Apr 5 16:24:52 2009 @@ -64,7 +64,7 @@ filename = co.co_filename name = co.co_name _print(file, - ' File "%s", line %d, in %s' % (filename,lineno,name)) + ' File "%s", line %d, in %s' % (filename, lineno, name)) linecache.checkcache(filename) line = linecache.getline(filename, lineno, f.f_globals) if line: _print(file, ' ' + line.strip()) @@ -124,9 +124,8 @@ _print(file, 'Traceback (most recent call last):') print_tb(tb, limit, file) lines = format_exception_only(etype, value) - for line in lines[:-1]: - _print(file, line, ' ') - _print(file, lines[-1], '') + for line in lines: + _print(file, line, '') def format_exception(etype, value, tb, limit = None): """Format a stack trace and the exception information. @@ -195,7 +194,7 @@ caretspace = ((c.isspace() and c or ' ') for c in caretspace) # only three spaces to account for offset1 == pos 0 lines.append(' %s^\n' % ''.join(caretspace)) - value = msg + value = msg lines.append(_format_final_exc_line(stype, value)) return lines From python-checkins at python.org Sun Apr 5 16:25:41 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 16:25:41 +0200 (CEST) Subject: [Python-checkins] r71238 - python/trunk/Misc/NEWS Message-ID: <20090405142541.F0DB91E4029@bag.python.org> Author: georg.brandl Date: Sun Apr 5 16:25:41 2009 New Revision: 71238 Log: Add NEWS entry for r71237. Modified: python/trunk/Misc/NEWS Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Apr 5 16:25:41 2009 @@ -212,6 +212,8 @@ Library ------- +- Issue 1326077: fix the formatting of SyntaxErrors by the traceback module. + - Issue 1726172: fix IndexError in the case of and empty response in ftplib. - Issue 2625: added missing iteritems() call to the for loop in From python-checkins at python.org Sun Apr 5 16:28:43 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 16:28:43 +0200 (CEST) Subject: [Python-checkins] r71239 - in python/branches/py3k: Lib/test/test_traceback.py Lib/traceback.py Misc/NEWS Message-ID: <20090405142843.409561E4767@bag.python.org> Author: georg.brandl Date: Sun Apr 5 16:28:42 2009 New Revision: 71239 Log: Merged revisions 71237-71238 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71237 | georg.brandl | 2009-04-05 16:24:52 +0200 (So, 05 Apr 2009) | 1 line #1326077: fix traceback formatting of SyntaxErrors. This fixes two differences with formatting coming from Python: a) the reproduction of location details in the error message if no line text is given, b) the prefixing of the last line by one space. ........ r71238 | georg.brandl | 2009-04-05 16:25:41 +0200 (So, 05 Apr 2009) | 1 line Add NEWS entry for r71237. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_traceback.py python/branches/py3k/Lib/traceback.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/test/test_traceback.py ============================================================================== --- python/branches/py3k/Lib/test/test_traceback.py (original) +++ python/branches/py3k/Lib/test/test_traceback.py Sun Apr 5 16:28:42 2009 @@ -10,16 +10,6 @@ import traceback -try: - raise KeyError -except KeyError: - type_, value, tb = sys.exc_info() - file_ = StringIO() - traceback_print(tb, file_) - example_traceback = file_.getvalue() -else: - raise Error("unable to create test traceback string") - class SyntaxTracebackCases(unittest.TestCase): # For now, a very minimal set of tests. I want to be sure that @@ -158,9 +148,24 @@ class TracebackFormatTests(unittest.TestCase): - def test_traceback_indentation(self): + def test_traceback_format(self): + try: + raise KeyError('blah') + except KeyError: + type_, value, tb = sys.exc_info() + traceback_fmt = 'Traceback (most recent call last):\n' + \ + ''.join(traceback.format_tb(tb)) + file_ = StringIO() + traceback_print(tb, file_) + python_fmt = file_.getvalue() + else: + raise Error("unable to create test traceback string") + + # Make sure that Python and the traceback module format the same thing + self.assertEquals(traceback_fmt, python_fmt) + # Make sure that the traceback is properly indented. - tb_lines = example_traceback.splitlines() + tb_lines = python_fmt.splitlines() self.assertEquals(len(tb_lines), 3) banner, location, source_line = tb_lines self.assert_(banner.startswith('Traceback')) Modified: python/branches/py3k/Lib/traceback.py ============================================================================== --- python/branches/py3k/Lib/traceback.py (original) +++ python/branches/py3k/Lib/traceback.py Sun Apr 5 16:28:42 2009 @@ -63,7 +63,7 @@ filename = co.co_filename name = co.co_name _print(file, - ' File "%s", line %d, in %s' % (filename,lineno,name)) + ' File "%s", line %d, in %s' % (filename, lineno, name)) linecache.checkcache(filename) line = linecache.getline(filename, lineno, f.f_globals) if line: _print(file, ' ' + line.strip()) @@ -159,9 +159,8 @@ _print(file, 'Traceback (most recent call last):') print_tb(tb, limit, file) lines = format_exception_only(type(value), value) - for line in lines[:-1]: - _print(file, line, ' ') - _print(file, lines[-1], '') + for line in lines: + _print(file, line, '') def format_exception(etype, value, tb, limit=None, chain=True): """Format a stack trace and the exception information. Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Apr 5 16:28:42 2009 @@ -327,6 +327,8 @@ Library ------- +- Issue 1326077: fix the formatting of SyntaxErrors by the traceback module. + - Issue #1665206 (partially): Move imports in cgitb to the top of the module instead of performing them in functions. Helps prevent import deadlocking in threads. From python-checkins at python.org Sun Apr 5 16:40:06 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 16:40:06 +0200 (CEST) Subject: [Python-checkins] r71240 - python/trunk/Doc/library/pickle.rst Message-ID: <20090405144006.D1D521E4792@bag.python.org> Author: georg.brandl Date: Sun Apr 5 16:40:06 2009 New Revision: 71240 Log: #5370: doc update about unpickling objects with custom __getattr__ etc. methods. Modified: python/trunk/Doc/library/pickle.rst Modified: python/trunk/Doc/library/pickle.rst ============================================================================== --- python/trunk/Doc/library/pickle.rst (original) +++ python/trunk/Doc/library/pickle.rst Sun Apr 5 16:40:06 2009 @@ -458,6 +458,15 @@ For :term:`new-style class`\es, if :meth:`__getstate__` returns a false value, the :meth:`__setstate__` method will not be called. +.. note:: + + At unpickling time, some methods like :meth:`__getattr__`, + :meth:`__getattribute__`, or :meth:`__setattr__` may be called upon the + instance. In case those methods rely on some internal invariant being + true, the type should implement either :meth:`__getinitargs__` or + :meth:`__getnewargs__` to establish such an invariant; otherwise, neither + :meth:`__new__` nor :meth:`__init__` will be called. + Pickling and unpickling extension types ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From buildbot at python.org Sun Apr 5 16:44:16 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 05 Apr 2009 14:44:16 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090405144416.8B1D81E4029@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/486 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 249, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 102, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Sun Apr 5 16:48:50 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 16:48:50 +0200 (CEST) Subject: [Python-checkins] r71241 - in python/trunk: Lib/posixpath.py Lib/test/test_posixpath.py Misc/NEWS Message-ID: <20090405144850.1F4E21E4029@bag.python.org> Author: georg.brandl Date: Sun Apr 5 16:48:49 2009 New Revision: 71241 Log: #5471: fix expanduser() for $HOME set to "/". Modified: python/trunk/Lib/posixpath.py python/trunk/Lib/test/test_posixpath.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/posixpath.py ============================================================================== --- python/trunk/Lib/posixpath.py (original) +++ python/trunk/Lib/posixpath.py Sun Apr 5 16:48:49 2009 @@ -262,7 +262,7 @@ except KeyError: return path userhome = pwent.pw_dir - userhome = userhome.rstrip('/') + userhome = userhome.rstrip('/') or userhome return userhome + path[i:] Modified: python/trunk/Lib/test/test_posixpath.py ============================================================================== --- python/trunk/Lib/test/test_posixpath.py (original) +++ python/trunk/Lib/test/test_posixpath.py Sun Apr 5 16:48:49 2009 @@ -345,6 +345,11 @@ self.assert_(isinstance(posixpath.expanduser("~root/"), basestring)) self.assert_(isinstance(posixpath.expanduser("~foo/"), basestring)) + orig_home = os.environ['HOME'] + os.environ['HOME'] = '/' + self.assertEqual(posixpath.expanduser("~"), "/") + os.environ['HOME'] = orig_home + self.assertRaises(TypeError, posixpath.expanduser) def test_expandvars(self): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Apr 5 16:48:49 2009 @@ -212,6 +212,8 @@ Library ------- +- Issue 5471: Fix os.path.expanduser() for $HOME set to '/'. + - Issue 1326077: fix the formatting of SyntaxErrors by the traceback module. - Issue 1726172: fix IndexError in the case of and empty response in ftplib. From python-checkins at python.org Sun Apr 5 17:05:49 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 17:05:49 +0200 (CEST) Subject: [Python-checkins] r71242 - python/branches/py3k/Lib/pydoc.py Message-ID: <20090405150549.3735D1E4029@bag.python.org> Author: georg.brandl Date: Sun Apr 5 17:05:48 2009 New Revision: 71242 Log: #5453: fix SyntaxErrors using pydoc -k, caused by intentionally bad files in Pythons test suite. Modified: python/branches/py3k/Lib/pydoc.py Modified: python/branches/py3k/Lib/pydoc.py ============================================================================== --- python/branches/py3k/Lib/pydoc.py (original) +++ python/branches/py3k/Lib/pydoc.py Sun Apr 5 17:05:48 2009 @@ -1922,8 +1922,12 @@ if key is None: callback(None, modname, '') else: - loader = importer.find_module(modname) - if hasattr(loader,'get_source'): + try: + loader = importer.find_module(modname) + except SyntaxError: + # raised by tests for bad coding cookies or BOM + continue + if hasattr(loader, 'get_source'): try: source = loader.get_source(modname) except UnicodeDecodeError: @@ -1932,7 +1936,7 @@ continue import io desc = source_synopsis(io.StringIO(source)) or '' - if hasattr(loader,'get_filename'): + if hasattr(loader, 'get_filename'): path = loader.get_filename(modname) else: path = None From python-checkins at python.org Sun Apr 5 17:14:29 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 17:14:29 +0200 (CEST) Subject: [Python-checkins] r71243 - python/trunk/Lib/plistlib.py Message-ID: <20090405151429.493B31E4029@bag.python.org> Author: georg.brandl Date: Sun Apr 5 17:14:29 2009 New Revision: 71243 Log: #5432: make plistlib docstring a raw string, since it contains examples with backslash escapes. Modified: python/trunk/Lib/plistlib.py Modified: python/trunk/Lib/plistlib.py ============================================================================== --- python/trunk/Lib/plistlib.py (original) +++ python/trunk/Lib/plistlib.py Sun Apr 5 17:14:29 2009 @@ -1,4 +1,4 @@ -"""plistlib.py -- a tool to generate and parse MacOSX .plist files. +r"""plistlib.py -- a tool to generate and parse MacOSX .plist files. The PropertyList (.plist) file format is a simple XML pickle supporting basic object types, like dictionaries, lists, numbers and strings. From python-checkins at python.org Sun Apr 5 18:01:20 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 5 Apr 2009 18:01:20 +0200 (CEST) Subject: [Python-checkins] r71244 - in python/branches/py3k-short-float-repr: Lib/test/test_float.py Python/dtoa.c Message-ID: <20090405160120.BB6A21E4029@bag.python.org> Author: mark.dickinson Date: Sun Apr 5 18:01:20 2009 New Revision: 71244 Log: Fix bug in strtod: '.nan' and '.inf' should be invalid. Modified: python/branches/py3k-short-float-repr/Lib/test/test_float.py python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Lib/test/test_float.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_float.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_float.py Sun Apr 5 18:01:20 2009 @@ -24,6 +24,8 @@ self.assertRaises(ValueError, float, "+-3.14") self.assertRaises(ValueError, float, "-+3.14") self.assertRaises(ValueError, float, "--3.14") + self.assertRaises(ValueError, float, ".nan") + self.assertRaises(ValueError, float, "+.inf") self.assertEqual(float(b" \u0663.\u0661\u0664 ".decode('raw-unicode-escape')), 3.14) @support.run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE') Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Sun Apr 5 18:01:20 2009 @@ -1418,7 +1418,7 @@ _Py_dg_strtod (CONST char *s00, char **se) { - int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1; + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dp, e, e1; int esign, i, j, k, nd, nd0, nf, nz, nz0, sign; CONST char *s, *s0, *s1; double aadj, aadj1; @@ -1428,7 +1428,7 @@ BCinfo bc; Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; - sign = nz0 = nz = bc.dplen = bc.uflchk = 0; + sign = nz0 = nz = dp = bc.dplen = bc.uflchk = 0; dval(&rv) = 0.; for(s = s00;;s++) switch(*s) { case '-': @@ -1467,6 +1467,7 @@ nd0 = nd; bc.dp0 = bc.dp1 = s - s0; if (c == '.') { + dp = 1; c = *++s; bc.dp1 = s - s0; bc.dplen = bc.dp1 - bc.dp0; @@ -1538,7 +1539,7 @@ s = s00; } if (!nd) { - if (!nz && !nz0) { + if (!nz && !nz0 && !dp) { #ifdef INFNAN_CHECK /* Check for Nan and Infinity */ switch(c) { From python-checkins at python.org Sun Apr 5 18:03:02 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 5 Apr 2009 18:03:02 +0200 (CEST) Subject: [Python-checkins] r71245 - python/branches/release30-maint/Doc/license.rst Message-ID: <20090405160302.C47771E4029@bag.python.org> Author: mark.dickinson Date: Sun Apr 5 18:03:02 2009 New Revision: 71245 Log: Remove leftover svn conflict marker Modified: python/branches/release30-maint/Doc/license.rst Modified: python/branches/release30-maint/Doc/license.rst ============================================================================== --- python/branches/release30-maint/Doc/license.rst (original) +++ python/branches/release30-maint/Doc/license.rst Sun Apr 5 18:03:02 2009 @@ -31,7 +31,6 @@ Source Definition). Historically, most, but not all, Python releases have also been GPL-compatible; the table below summarizes the various releases. -<<<<<<< .working +----------------+--------------+------------+------------+-----------------+ | Release | Derived from | Year | Owner | GPL compatible? | +================+==============+============+============+=================+ From python-checkins at python.org Sun Apr 5 18:04:57 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 5 Apr 2009 18:04:57 +0200 (CEST) Subject: [Python-checkins] r71246 - python/branches/release30-maint Message-ID: <20090405160457.C1A671E4029@bag.python.org> Author: mark.dickinson Date: Sun Apr 5 18:04:57 2009 New Revision: 71246 Log: Blocked revisions 70753 via svnmerge ........ r70753 | georg.brandl | 2009-03-30 22:21:05 +0100 (Mon, 30 Mar 2009) | 1 line Remove merging leftover. ........ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sun Apr 5 18:12:47 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 5 Apr 2009 18:12:47 +0200 (CEST) Subject: [Python-checkins] r71247 - python/branches/py3k-short-float-repr/Makefile.pre.in Message-ID: <20090405161247.0AE1C1E4029@bag.python.org> Author: eric.smith Date: Sun Apr 5 18:12:46 2009 New Revision: 71247 Log: Added dependency. Modified: python/branches/py3k-short-float-repr/Makefile.pre.in Modified: python/branches/py3k-short-float-repr/Makefile.pre.in ============================================================================== --- python/branches/py3k-short-float-repr/Makefile.pre.in (original) +++ python/branches/py3k-short-float-repr/Makefile.pre.in Sun Apr 5 18:12:46 2009 @@ -595,7 +595,8 @@ Python/ceval.o: $(OPCODETARGETS_H) Python/formatter_unicode.o: $(srcdir)/Python/formatter_unicode.c \ - $(BYTESTR_DEPS) + $(BYTESTR_DEPS) \ + $(srcdir)/Objects/stringlib/formatter.h ############################################################################ From python-checkins at python.org Sun Apr 5 18:24:33 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 5 Apr 2009 18:24:33 +0200 (CEST) Subject: [Python-checkins] r71248 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090405162433.488D71E4029@bag.python.org> Author: eric.smith Date: Sun Apr 5 18:24:33 2009 New Revision: 71248 Log: Fixed comment. Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Sun Apr 5 18:24:33 2009 @@ -533,7 +533,7 @@ always_add_sign is nonzero if a '+' sign should be included for positive numbers add_dot_0_if_integer is nonzero if integers in non-exponential form - should have ".0" added. Only applies to format codes 'r' and 's'. + should have ".0" added. Only applies to format codes 'r', 's', and 'g'. use_alt_formatting is nonzero if alternative formatting should be used. Only applies to format codes 'e', 'f' and 'g'. */ From python-checkins at python.org Sun Apr 5 18:30:43 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 18:30:43 +0200 (CEST) Subject: [Python-checkins] r71249 - python/trunk/Doc/make.bat Message-ID: <20090405163043.863D81E4029@bag.python.org> Author: georg.brandl Date: Sun Apr 5 18:30:43 2009 New Revision: 71249 Log: #5444: adapt make.bat to new htmlhelp output file name. Modified: python/trunk/Doc/make.bat Modified: python/trunk/Doc/make.bat ============================================================================== --- python/trunk/Doc/make.bat (original) +++ python/trunk/Doc/make.bat Sun Apr 5 18:30:43 2009 @@ -4,6 +4,7 @@ set SVNROOT=http://svn.python.org/projects if "%PYTHON%" EQU "" set PYTHON=..\pcbuild\python if "%HTMLHELP%" EQU "" set HTMLHELP=%ProgramFiles%\HTML Help Workshop\hhc.exe +if "%DISTVERSION%" EQU "" for /f "usebackq" %%v in (`%PYTHON% tools/sphinxext/patchlevel.py`) do set DISTVERSION=%%v if "%1" EQU "" goto help if "%1" EQU "html" goto build @@ -51,7 +52,7 @@ if not exist build\%1 mkdir build\%1 if not exist build\doctrees mkdir build\doctrees cmd /C %PYTHON% tools\sphinx-build.py -b%1 -dbuild\doctrees . build\%* -if "%1" EQU "htmlhelp" "%HTMLHELP%" build\htmlhelp\pydoc.hhp +if "%1" EQU "htmlhelp" "%HTMLHELP%" build\htmlhelp\python%DISTVERSION:.=%.hhp goto end :end From python-checkins at python.org Sun Apr 5 18:53:03 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 5 Apr 2009 18:53:03 +0200 (CEST) Subject: [Python-checkins] r71250 - in python/branches/py3k-short-float-repr: Lib/test/test_float.py Python/dtoa.c Message-ID: <20090405165303.52C0C1E4029@bag.python.org> Author: mark.dickinson Date: Sun Apr 5 18:53:02 2009 New Revision: 71250 Log: Revert previous 'fix', which caused float('.') to return 0.0. Modified: python/branches/py3k-short-float-repr/Lib/test/test_float.py python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Lib/test/test_float.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_float.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_float.py Sun Apr 5 18:53:02 2009 @@ -26,6 +26,7 @@ self.assertRaises(ValueError, float, "--3.14") self.assertRaises(ValueError, float, ".nan") self.assertRaises(ValueError, float, "+.inf") + self.assertRaises(ValueError, float, ".") self.assertEqual(float(b" \u0663.\u0661\u0664 ".decode('raw-unicode-escape')), 3.14) @support.run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE') Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Sun Apr 5 18:53:02 2009 @@ -1418,7 +1418,7 @@ _Py_dg_strtod (CONST char *s00, char **se) { - int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dp, e, e1; + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1; int esign, i, j, k, nd, nd0, nf, nz, nz0, sign; CONST char *s, *s0, *s1; double aadj, aadj1; @@ -1428,7 +1428,7 @@ BCinfo bc; Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; - sign = nz0 = nz = dp = bc.dplen = bc.uflchk = 0; + sign = nz0 = nz = bc.dplen = bc.uflchk = 0; dval(&rv) = 0.; for(s = s00;;s++) switch(*s) { case '-': @@ -1467,7 +1467,6 @@ nd0 = nd; bc.dp0 = bc.dp1 = s - s0; if (c == '.') { - dp = 1; c = *++s; bc.dp1 = s - s0; bc.dplen = bc.dp1 - bc.dp0; @@ -1539,7 +1538,7 @@ s = s00; } if (!nd) { - if (!nz && !nz0 && !dp) { + if (!nz && !nz0) { #ifdef INFNAN_CHECK /* Check for Nan and Infinity */ switch(c) { From python-checkins at python.org Sun Apr 5 19:17:43 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 19:17:43 +0200 (CEST) Subject: [Python-checkins] r71251 - python/trunk/Doc/c-api/init.rst Message-ID: <20090405171743.E542D1E4029@bag.python.org> Author: georg.brandl Date: Sun Apr 5 19:17:42 2009 New Revision: 71251 Log: #5298: clarify docs about GIL by using more consistent wording. Modified: python/trunk/Doc/c-api/init.rst Modified: python/trunk/Doc/c-api/init.rst ============================================================================== --- python/trunk/Doc/c-api/init.rst (original) +++ python/trunk/Doc/c-api/init.rst Sun Apr 5 19:17:42 2009 @@ -394,12 +394,12 @@ single: lock, interpreter The Python interpreter is not fully thread safe. In order to support -multi-threaded Python programs, there's a global lock that must be held by the -current thread before it can safely access Python objects. Without the lock, -even the simplest operations could cause problems in a multi-threaded program: -for example, when two threads simultaneously increment the reference count of -the same object, the reference count could end up being incremented only once -instead of twice. +multi-threaded Python programs, there's a global lock, called the :dfn:`global +interpreter lock` or :dfn:`GIL`, that must be held by the current thread before +it can safely access Python objects. Without the lock, even the simplest +operations could cause problems in a multi-threaded program: for example, when +two threads simultaneously increment the reference count of the same object, the +reference count could end up being incremented only once instead of twice. .. index:: single: setcheckinterval() (in module sys) @@ -428,9 +428,9 @@ interpreter lock has the following simple structure:: Save the thread state in a local variable. - Release the interpreter lock. + Release the global interpreter lock. ...Do some blocking I/O operation... - Reacquire the interpreter lock. + Reacquire the global interpreter lock. Restore the thread state from the local variable. This is so common that a pair of macros exists to simplify it:: @@ -447,7 +447,7 @@ hidden local variable; the :cmacro:`Py_END_ALLOW_THREADS` macro closes the block. Another advantage of using these two macros is that when Python is compiled without thread support, they are defined empty, thus saving the thread -state and lock manipulations. +state and GIL manipulations. When thread support is enabled, the block above expands to the following code:: @@ -479,7 +479,7 @@ saves and restores the value of the global variable :cdata:`errno`, since the lock manipulation does not guarantee that :cdata:`errno` is left alone. Also, when thread support is disabled, :cfunc:`PyEval_SaveThread` and -:cfunc:`PyEval_RestoreThread` don't manipulate the lock; in this case, +:cfunc:`PyEval_RestoreThread` don't manipulate the GIL; in this case, :cfunc:`PyEval_ReleaseLock` and :cfunc:`PyEval_AcquireLock` are not available. This is done so that dynamically loaded extensions compiled with thread support enabled can be loaded by an interpreter that was compiled with disabled thread @@ -562,16 +562,16 @@ .. index:: module: thread - When only the main thread exists, no lock operations are needed. This is a + When only the main thread exists, no GIL operations are needed. This is a common situation (most Python programs do not use threads), and the lock - operations slow the interpreter down a bit. Therefore, the lock is not created - initially. This situation is equivalent to having acquired the lock: when - there is only a single thread, all object accesses are safe. Therefore, when - this function initializes the lock, it also acquires it. Before the Python - :mod:`thread` module creates a new thread, knowing that either it has the lock - or the lock hasn't been created yet, it calls :cfunc:`PyEval_InitThreads`. When - this call returns, it is guaranteed that the lock has been created and that the - calling thread has acquired it. + operations slow the interpreter down a bit. Therefore, the lock is not + created initially. This situation is equivalent to having acquired the lock: + when there is only a single thread, all object accesses are safe. Therefore, + when this function initializes the global interpreter lock, it also acquires + it. Before the Python :mod:`thread` module creates a new thread, knowing + that either it has the lock or the lock hasn't been created yet, it calls + :cfunc:`PyEval_InitThreads`. When this call returns, it is guaranteed that + the lock has been created and that the calling thread has acquired it. It is **not** safe to call this function when it is unknown which thread (if any) currently has the global interpreter lock. @@ -582,7 +582,7 @@ .. cfunction:: int PyEval_ThreadsInitialized() Returns a non-zero value if :cfunc:`PyEval_InitThreads` has been called. This - function can be called without holding the lock, and therefore can be used to + function can be called without holding the GIL, and therefore can be used to avoid calls to the locking API when running single-threaded. This function is not available when thread support is disabled at compile time. @@ -622,20 +622,20 @@ .. cfunction:: PyThreadState* PyEval_SaveThread() - Release the interpreter lock (if it has been created and thread support is - enabled) and reset the thread state to *NULL*, returning the previous thread - state (which is not *NULL*). If the lock has been created, the current thread - must have acquired it. (This function is available even when thread support is - disabled at compile time.) + Release the global interpreter lock (if it has been created and thread + support is enabled) and reset the thread state to *NULL*, returning the + previous thread state (which is not *NULL*). If the lock has been created, + the current thread must have acquired it. (This function is available even + when thread support is disabled at compile time.) .. cfunction:: void PyEval_RestoreThread(PyThreadState *tstate) - Acquire the interpreter lock (if it has been created and thread support is - enabled) and set the thread state to *tstate*, which must not be *NULL*. If the - lock has been created, the current thread must not have acquired it, otherwise - deadlock ensues. (This function is available even when thread support is - disabled at compile time.) + Acquire the global interpreter lock (if it has been created and thread + support is enabled) and set the thread state to *tstate*, which must not be + *NULL*. If the lock has been created, the current thread must not have + acquired it, otherwise deadlock ensues. (This function is available even + when thread support is disabled at compile time.) .. cfunction:: void PyEval_ReInitThreads() @@ -679,60 +679,61 @@ declaration. It is a no-op when thread support is disabled at compile time. All of the following functions are only available when thread support is enabled -at compile time, and must be called only when the interpreter lock has been -created. +at compile time, and must be called only when the global interpreter lock has +been created. .. cfunction:: PyInterpreterState* PyInterpreterState_New() - Create a new interpreter state object. The interpreter lock need not be held, - but may be held if it is necessary to serialize calls to this function. + Create a new interpreter state object. The global interpreter lock need not + be held, but may be held if it is necessary to serialize calls to this + function. .. cfunction:: void PyInterpreterState_Clear(PyInterpreterState *interp) - Reset all information in an interpreter state object. The interpreter lock must - be held. + Reset all information in an interpreter state object. The global interpreter + lock must be held. .. cfunction:: void PyInterpreterState_Delete(PyInterpreterState *interp) - Destroy an interpreter state object. The interpreter lock need not be held. - The interpreter state must have been reset with a previous call to + Destroy an interpreter state object. The global interpreter lock need not be + held. The interpreter state must have been reset with a previous call to :cfunc:`PyInterpreterState_Clear`. .. cfunction:: PyThreadState* PyThreadState_New(PyInterpreterState *interp) - Create a new thread state object belonging to the given interpreter object. The - interpreter lock need not be held, but may be held if it is necessary to - serialize calls to this function. + Create a new thread state object belonging to the given interpreter object. + The global interpreter lock need not be held, but may be held if it is + necessary to serialize calls to this function. .. cfunction:: void PyThreadState_Clear(PyThreadState *tstate) - Reset all information in a thread state object. The interpreter lock must be - held. + Reset all information in a thread state object. The global interpreter lock + must be held. .. cfunction:: void PyThreadState_Delete(PyThreadState *tstate) - Destroy a thread state object. The interpreter lock need not be held. The - thread state must have been reset with a previous call to + Destroy a thread state object. The global interpreter lock need not be held. + The thread state must have been reset with a previous call to :cfunc:`PyThreadState_Clear`. .. cfunction:: PyThreadState* PyThreadState_Get() - Return the current thread state. The interpreter lock must be held. When the - current thread state is *NULL*, this issues a fatal error (so that the caller - needn't check for *NULL*). + Return the current thread state. The global interpreter lock must be held. + When the current thread state is *NULL*, this issues a fatal error (so that + the caller needn't check for *NULL*). .. cfunction:: PyThreadState* PyThreadState_Swap(PyThreadState *tstate) Swap the current thread state with the thread state given by the argument - *tstate*, which may be *NULL*. The interpreter lock must be held. + *tstate*, which may be *NULL*. The global interpreter lock must be held. .. cfunction:: PyObject* PyThreadState_GetDict() @@ -763,14 +764,15 @@ .. cfunction:: PyGILState_STATE PyGILState_Ensure() - Ensure that the current thread is ready to call the Python C API regardless of - the current state of Python, or of its thread lock. This may be called as many - times as desired by a thread as long as each call is matched with a call to - :cfunc:`PyGILState_Release`. In general, other thread-related APIs may be used - between :cfunc:`PyGILState_Ensure` and :cfunc:`PyGILState_Release` calls as long - as the thread state is restored to its previous state before the Release(). For - example, normal usage of the :cmacro:`Py_BEGIN_ALLOW_THREADS` and - :cmacro:`Py_END_ALLOW_THREADS` macros is acceptable. + Ensure that the current thread is ready to call the Python C API regardless + of the current state of Python, or of the global interpreter lock. This may + be called as many times as desired by a thread as long as each call is + matched with a call to :cfunc:`PyGILState_Release`. In general, other + thread-related APIs may be used between :cfunc:`PyGILState_Ensure` and + :cfunc:`PyGILState_Release` calls as long as the thread state is restored to + its previous state before the Release(). For example, normal usage of the + :cmacro:`Py_BEGIN_ALLOW_THREADS` and :cmacro:`Py_END_ALLOW_THREADS` macros is + acceptable. The return value is an opaque "handle" to the thread state when :cfunc:`PyGILState_Ensure` was called, and must be passed to @@ -808,35 +810,34 @@ .. index:: single: setcheckinterval() (in module sys) -Every check interval, when the interpreter lock is released and reacquired, -python will also call any such provided functions. This can be used for -example by asynchronous IO handlers. The notification can be scheduled -from a worker thread and the actual call than made at the earliest -convenience by the main thread where it has possession of the global -interpreter lock and can perform any Python API calls. +Every check interval, when the global interpreter lock is released and +reacquired, python will also call any such provided functions. This can be used +for example by asynchronous IO handlers. The notification can be scheduled from +a worker thread and the actual call than made at the earliest convenience by the +main thread where it has possession of the global interpreter lock and can +perform any Python API calls. .. cfunction:: void Py_AddPendingCall( int (*func)(void *, void *arg) ) .. index:: single: Py_AddPendingCall() - Post a notification to the Python main thread. If successful, - *func* will be called with the argument *arg* at the earliest - convenience. *func* will be called having the global interpreter - lock held and can thus use the full Python API and can take any - action such as setting object attributes to signal IO completion. - It must return 0 on success, or -1 signalling an exception. - The notification function won't be interrupted to perform another - asynchronous notification recursively, - but it can still be interrupted to switch threads if the interpreter - lock is released, for example, if it calls back into python code. + Post a notification to the Python main thread. If successful, *func* will be + called with the argument *arg* at the earliest convenience. *func* will be + called having the global interpreter lock held and can thus use the full + Python API and can take any action such as setting object attributes to + signal IO completion. It must return 0 on success, or -1 signalling an + exception. The notification function won't be interrupted to perform another + asynchronous notification recursively, but it can still be interrupted to + switch threads if the global interpreter lock is released, for example, if it + calls back into python code. This function returns 0 on success in which case the notification has been - scheduled. Otherwise, for example if the notification buffer is full, - it returns -1 without setting any exception. + scheduled. Otherwise, for example if the notification buffer is full, it + returns -1 without setting any exception. - This function can be called on any thread, be it a Python thread or - some other system thread. If it is a Python thread, it doesn't matter if - it holds the global interpreter lock or not. + This function can be called on any thread, be it a Python thread or some + other system thread. If it is a Python thread, it doesn't matter if it holds + the global interpreter lock or not. .. versionadded:: 2.7 From buildbot at python.org Sun Apr 5 19:51:20 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 05 Apr 2009 17:51:20 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090405175121.2E3011E472B@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/249 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: mark.dickinson,matthias.klose BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From buildbot at python.org Sun Apr 5 20:29:03 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 05 Apr 2009 18:29:03 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090405182903.47B701E4029@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/488 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 249, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 102, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Sun Apr 5 20:31:24 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 5 Apr 2009 20:31:24 +0200 (CEST) Subject: [Python-checkins] r71253 - in python/trunk: Lib/distutils/tests/test_clean.py Misc/NEWS Message-ID: <20090405183124.ADFF01E4029@bag.python.org> Author: tarek.ziade Date: Sun Apr 5 20:31:24 2009 New Revision: 71253 Log: Fixed 5694: removed spurious test output in Distutils Modified: python/trunk/Lib/distutils/tests/test_clean.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/distutils/tests/test_clean.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_clean.py (original) +++ python/trunk/Lib/distutils/tests/test_clean.py Sun Apr 5 20:31:24 2009 @@ -8,6 +8,7 @@ from distutils.tests import support class cleanTestCase(support.TempdirManager, + support.LoggingSilencer, unittest.TestCase): def test_simple_run(self): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Apr 5 20:31:24 2009 @@ -212,6 +212,8 @@ Library ------- +- Issue 5694: removed spurious test output in Distutils (test_clean). + - Issue 5471: Fix os.path.expanduser() for $HOME set to '/'. - Issue 1326077: fix the formatting of SyntaxErrors by the traceback module. From python-checkins at python.org Sun Apr 5 20:33:34 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 5 Apr 2009 20:33:34 +0200 (CEST) Subject: [Python-checkins] r71254 - in python/branches/py3k: Lib/distutils/tests/test_clean.py Misc/NEWS Message-ID: <20090405183334.62C221E4029@bag.python.org> Author: tarek.ziade Date: Sun Apr 5 20:33:34 2009 New Revision: 71254 Log: Merged revisions 71253 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71253 | tarek.ziade | 2009-04-05 20:31:24 +0200 (Sun, 05 Apr 2009) | 1 line Fixed 5694: removed spurious test output in Distutils ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/tests/test_clean.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/distutils/tests/test_clean.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_clean.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_clean.py Sun Apr 5 20:33:34 2009 @@ -8,6 +8,7 @@ from distutils.tests import support class cleanTestCase(support.TempdirManager, + support.LoggingSilencer, unittest.TestCase): def test_simple_run(self): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Apr 5 20:33:34 2009 @@ -327,6 +327,8 @@ Library ------- +- Issue 5694: removed spurious test output in Distutils (test_clean). + - Issue 1326077: fix the formatting of SyntaxErrors by the traceback module. - Issue #1665206 (partially): Move imports in cgitb to the top of the module From python-checkins at python.org Sun Apr 5 20:34:58 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 20:34:58 +0200 (CEST) Subject: [Python-checkins] r71255 - python/trunk/Lib/cgitb.py Message-ID: <20090405183458.841E11E4029@bag.python.org> Author: georg.brandl Date: Sun Apr 5 20:34:58 2009 New Revision: 71255 Log: #602893: add indicator for current line in cgitb that doesnt rely on styling alone. Modified: python/trunk/Lib/cgitb.py Modified: python/trunk/Lib/cgitb.py ============================================================================== --- python/trunk/Lib/cgitb.py (original) +++ python/trunk/Lib/cgitb.py Sun Apr 5 20:34:58 2009 @@ -141,10 +141,11 @@ i = lnum - index for line in lines: num = small(' ' * (5-len(str(i))) + str(i)) + ' ' - line = '%s%s' % (num, pydoc.html.preformat(line)) if i in highlight: + line = '=>%s%s' % (num, pydoc.html.preformat(line)) rows.append('%s' % line) else: + line = '  %s%s' % (num, pydoc.html.preformat(line)) rows.append('%s' % grey(line)) i += 1 From python-checkins at python.org Sun Apr 5 20:35:33 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 5 Apr 2009 20:35:33 +0200 (CEST) Subject: [Python-checkins] r71256 - python/branches/release26-maint Message-ID: <20090405183533.489061E4029@bag.python.org> Author: tarek.ziade Date: Sun Apr 5 20:35:33 2009 New Revision: 71256 Log: Blocked revisions 71253 via svnmerge ........ r71253 | tarek.ziade | 2009-04-05 20:31:24 +0200 (Sun, 05 Apr 2009) | 1 line Fixed 5694: removed spurious test output in Distutils ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Apr 5 20:37:01 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 5 Apr 2009 20:37:01 +0200 (CEST) Subject: [Python-checkins] r71257 - python/branches/release30-maint Message-ID: <20090405183701.E19951E44F5@bag.python.org> Author: tarek.ziade Date: Sun Apr 5 20:37:01 2009 New Revision: 71257 Log: Blocked revisions 71254 via svnmerge ................ r71254 | tarek.ziade | 2009-04-05 20:33:34 +0200 (Sun, 05 Apr 2009) | 9 lines Merged revisions 71253 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71253 | tarek.ziade | 2009-04-05 20:31:24 +0200 (Sun, 05 Apr 2009) | 1 line Fixed 5694: removed spurious test output in Distutils ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sun Apr 5 20:57:32 2009 From: python-checkins at python.org (brett.cannon) Date: Sun, 5 Apr 2009 20:57:32 +0200 (CEST) Subject: [Python-checkins] r71259 - in python/branches/py3k: Lib/test/test_logging.py Message-ID: <20090405185732.5A4941E4052@bag.python.org> Author: brett.cannon Date: Sun Apr 5 20:57:32 2009 New Revision: 71259 Log: Blocked revisions 71221 via svnmerge ........ r71221 | vinay.sajip | 2009-04-05 04:06:24 -0700 (Sun, 05 Apr 2009) | 1 line Issue #5695: Moved logging.captureWarnings() call inside with statement in WarningsTest.test_warnings. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_logging.py 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 Sun Apr 5 20:57:32 2009 @@ -912,10 +912,10 @@ class WarningsTest(BaseTest): def test_warnings(self): - logging.captureWarnings(True) with warnings.catch_warnings(): - warnings.filterwarnings("always", category=UserWarning) + logging.captureWarnings(True) try: + warnings.filterwarnings("always", category=UserWarning) file = io.StringIO() h = logging.StreamHandler(file) logger = logging.getLogger("py.warnings") From stackless-checkins-bounces at stackless.com Sun Apr 5 20:12:39 2009 From: stackless-checkins-bounces at stackless.com (stackless-checkins-bounces at stackless.com) Date: Sun, 05 Apr 2009 20:12:39 +0200 Subject: [Python-checkins] Your message to Stackless-checkins awaits moderator approval Message-ID: Your mail to 'Stackless-checkins' with the subject r71252 - in stackless/branches/py3k: Demo/classes/Complex.py Demo/classes/bitvec.py Demo/distutils/test2to3 Demo/distutils/test2to3/setup.py Demo/distutils/test2to3/test Demo/tix/grid.py Demo/tix/samples/Balloon.py Demo/tix/samples/BtnBox.py Demo/tix/samples/CmpImg.py Demo/tix/samples/ComboBox.py Demo/tix/samples/Control.py Demo/tix/samples/DirList.py Demo/tix/samples/DirTree.py Demo/tix/samples/NoteBook.py Demo/tix/samples/OptMenu.py Demo/tix/samples/PanedWin.py Demo/tix/samples/PopMenu.py Demo/tix/samples/SHList1.py Demo/tix/samples/SHList2.py Demo/tix/samples/Tree.py Demo/tix/tixwidgets.py Demo/tkinter/README Demo/tkinter/guido/AttrDialog.py Demo/tkinter/guido/ManPage.py Demo/tkinter/guido/MimeViewer.py Demo/tkinter/guido/ShellWindow.py Demo/tkinter/guido/brownian.py Demo/tkinter/guido/brownian2.py Demo/tkinter/guido/canvasevents.py Demo/tkinter/guido/dialog.py Demo/tkinter/guido/electrons.py Demo/tkinter/guido/hanoi.py Demo/tkinter/guido/hello.py Demo/tkinter/gu ido/imagedraw.py Demo/tkinter/guido/imageview.py Demo/tkinter/guido/kill.py Demo/tkinter/guido/listtree.py Demo/tkinter/guido/mbox.py Demo/tkinter/guido/newmenubardemo.py Demo/tkinter/guido/optionmenu.py Demo/tkinter/guido/paint.py Demo/tkinter/guido/rmt.py Demo/tkinter/guido/solitaire.py Demo/tkinter/guido/sortvisu.py Demo/tkinter/guido/ss1.py Demo/tkinter/guido/svkill.py Demo/tkinter/guido/switch.py Demo/tkinter/guido/tkman.py Demo/tkinter/matt/00-HELLO-WORLD.py Demo/tkinter/matt/animation-simple.py Demo/tkinter/matt/animation-w-velocity-ctrl.py Demo/tkinter/matt/bind-w-mult-calls-p-type.py Demo/tkinter/matt/canvas-demo-simple.py Demo/tkinter/matt/canvas-gridding.py Demo/tkinter/matt/canvas-moving-or-creating.py Demo/tkinter/matt/canvas-moving-w-mouse.py Demo/tkinter/matt/canvas-mult-item-sel.py Demo/tkinter/matt/canvas-reading-tag-info.py Demo/tkinter/matt/canvas-w-widget-draw-el.py Demo/tkinter/matt/canvas-with-scrollbars.py Demo/tkinter/matt/dialog-box.py Demo/tkinter/m att/entry-simple.py Demo/tkinter/matt/entry-with-shared-variable.py Demo/tkinter/matt/killing-window-w-wm.py Demo/tkinter/matt/menu-all-types-of-entries.py Demo/tkinter/matt/menu-simple.py Demo/tkinter/matt/not-what-you-might-think-1.py Demo/tkinter/matt/not-what-you-might-think-2.py Demo/tkinter/matt/packer-and-placer-together.py Demo/tkinter/matt/packer-simple.py Demo/tkinter/matt/placer-simple.py Demo/tkinter/matt/pong-demo-1.py Demo/tkinter/matt/printing-coords-of-items.py Demo/tkinter/matt/radiobutton-simple.py Demo/tkinter/matt/rubber-band-box-demo-1.py Demo/tkinter/matt/rubber-line-demo-1.py Demo/tkinter/matt/slider-demo-1.py Demo/tkinter/matt/subclass-existing-widgets.py Demo/tkinter/matt/two-radio-groups.py Demo/tkinter/matt/window-creation-more.py Demo/tkinter/matt/window-creation-simple.py Demo/tkinter/matt/window-creation-w-location.py Demo/tkinter/ttk Doc/ACKS.txt Doc/Makefile Doc/README.txt Doc/c-api/allocation.rst Doc/c-api/arg.rst Doc/c-api/bool.rst Doc/c-api /buffer.rst Doc/c-api/bytearray.rst Doc/c-api/bytes.rst Doc/c-api/cell.rst Doc/c-api/cobject.rst Doc/c-api/complex.rst Doc/c-api Is being held until the list moderator can review it for approval. The reason it is being held: Message body is too big: 4003370 bytes with a limit of 500 KB Either the message will get posted to the list, or you will receive notification of the moderator's decision. If you would like to cancel this posting, please visit the following URL: http://www.stackless.com/mailman/confirm/stackless-checkins/42ad792de89eec961e6db4c456e2f5a14e647d01 From python-checkins at python.org Sun Apr 5 21:13:19 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 5 Apr 2009 21:13:19 +0200 (CEST) Subject: [Python-checkins] r71261 - in python/branches/py3k: Doc/c-api/init.rst Doc/c-api/number.rst Doc/c-api/object.rst Doc/c-api/structures.rst Doc/c-api/veryhigh.rst Doc/distutils/apiref.rst Doc/extending/extending.rst Doc/howto/cporting.rst Doc/library/abc.rst Doc/library/doctest.rst Doc/library/functions.rst Doc/library/itertools.rst Doc/library/logging.rst Doc/library/multiprocessing.rst Doc/library/os.path.rst Doc/library/os.rst Doc/library/pdb.rst Doc/library/pickle.rst Doc/library/re.rst Doc/library/shelve.rst Doc/library/socketserver.rst Doc/library/ssl.rst Doc/library/stdtypes.rst Doc/library/sys.rst Doc/library/threading.rst Doc/library/tkinter.ttk.rst Doc/library/urllib.request.rst Doc/library/webbrowser.rst Doc/library/winreg.rst Doc/reference/datamodel.rst Doc/tutorial/datastructures.rst Doc/tutorial/introduction.rst Doc/whatsnew/2.6.rst Doc/whatsnew/2.7.rst Lib/distutils/cmd.py Lib/distutils/log.py Lib/ftplib.py Lib/glob.py Lib/optparse.py Lib/pdb.py Lib/test/README Lib/test/test_pprint.py Lib/test/test_sys.py Lib/test/test_threading.py Lib/threading.py Misc/ACKS Misc/developers.txt Objects/genobject.c configure configure.in Message-ID: <20090405191319.D0D841E424C@bag.python.org> Author: benjamin.peterson Date: Sun Apr 5 21:13:16 2009 New Revision: 71261 Log: Merged revisions 70712,70714,70764-70765,70769-70771,70773,70776-70777,70788-70789,70824,70828,70832,70836,70842,70851,70855,70857,70866-70872,70883,70885,70893-70894,70896-70897,70903,70905-70907,70915,70927,70933,70951,70960,70962-70964,70998,71001,71006,71008,71010-71011,71019,71037,71056,71094,71101-71103,71106,71119,71123,71149-71150,71203,71212,71214-71217,71221,71240 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70712 | benjamin.peterson | 2009-03-30 10:15:38 -0500 (Mon, 30 Mar 2009) | 1 line don't rely on the order dict repr #5605 ........ r70714 | brett.cannon | 2009-03-30 10:20:53 -0500 (Mon, 30 Mar 2009) | 1 line Add an entry to developers.txt. ........ r70764 | martin.v.loewis | 2009-03-30 17:06:33 -0500 (Mon, 30 Mar 2009) | 2 lines Add several VM developers. ........ r70765 | georg.brandl | 2009-03-30 17:09:34 -0500 (Mon, 30 Mar 2009) | 1 line #5199: make warning about vars() assignment more visible. ........ r70769 | andrew.kuchling | 2009-03-30 17:29:53 -0500 (Mon, 30 Mar 2009) | 1 line Remove comment ........ r70770 | andrew.kuchling | 2009-03-30 17:30:20 -0500 (Mon, 30 Mar 2009) | 1 line Add several items and placeholders ........ r70771 | andrew.kuchling | 2009-03-30 17:31:11 -0500 (Mon, 30 Mar 2009) | 1 line Many edits ........ r70773 | georg.brandl | 2009-03-30 17:43:00 -0500 (Mon, 30 Mar 2009) | 1 line #5039: make it clear that the impl. note refers to CPython. ........ r70776 | andrew.kuchling | 2009-03-30 18:08:24 -0500 (Mon, 30 Mar 2009) | 1 line typo fix ........ r70777 | andrew.kuchling | 2009-03-30 18:09:46 -0500 (Mon, 30 Mar 2009) | 1 line Add more items ........ r70788 | andrew.kuchling | 2009-03-30 20:21:01 -0500 (Mon, 30 Mar 2009) | 1 line Add various items ........ r70789 | georg.brandl | 2009-03-30 20:25:15 -0500 (Mon, 30 Mar 2009) | 1 line Fix a wrong struct field assignment (docstring as closure). ........ r70824 | georg.brandl | 2009-03-31 10:43:20 -0500 (Tue, 31 Mar 2009) | 1 line #5519: remove reference to Kodos, which seems dead. ........ r70828 | georg.brandl | 2009-03-31 10:50:16 -0500 (Tue, 31 Mar 2009) | 1 line #5581: fget argument of abstractproperty is optional as well. ........ r70832 | georg.brandl | 2009-03-31 11:31:11 -0500 (Tue, 31 Mar 2009) | 1 line #1386675: specify WindowsError as the exception, because it has a winerror attribute that EnvironmentError doesnt have. ........ r70836 | georg.brandl | 2009-03-31 11:50:25 -0500 (Tue, 31 Mar 2009) | 1 line #5417: replace references to undocumented functions by ones to documented functions. ........ r70842 | georg.brandl | 2009-03-31 12:13:06 -0500 (Tue, 31 Mar 2009) | 1 line #970783: document PyObject_Generic[GS]etAttr. ........ r70851 | georg.brandl | 2009-03-31 13:26:55 -0500 (Tue, 31 Mar 2009) | 1 line #837577: note cryptic return value of spawn*e on invalid env dicts. ........ r70855 | georg.brandl | 2009-03-31 13:30:37 -0500 (Tue, 31 Mar 2009) | 1 line #5245: note that PyRun_SimpleString doesnt return on SystemExit. ........ r70857 | georg.brandl | 2009-03-31 13:33:10 -0500 (Tue, 31 Mar 2009) | 1 line #5227: note that Py_Main doesnt return on SystemExit. ........ r70866 | georg.brandl | 2009-03-31 14:06:57 -0500 (Tue, 31 Mar 2009) | 1 line #4882: document named group behavior a bit better. ........ r70867 | georg.brandl | 2009-03-31 14:10:35 -0500 (Tue, 31 Mar 2009) | 1 line #1096310: document usage of sys.__std*__ a bit better. ........ r70868 | georg.brandl | 2009-03-31 14:12:17 -0500 (Tue, 31 Mar 2009) | 1 line #5190: export make_option in __all__. ........ r70869 | georg.brandl | 2009-03-31 14:14:42 -0500 (Tue, 31 Mar 2009) | 1 line Fix-up unwanted change. ........ r70870 | georg.brandl | 2009-03-31 14:26:24 -0500 (Tue, 31 Mar 2009) | 1 line #4411: document mro() and __mro__. (I hope I got it right.) ........ r70871 | georg.brandl | 2009-03-31 14:30:56 -0500 (Tue, 31 Mar 2009) | 1 line #5618: fix typo. ........ r70872 | r.david.murray | 2009-03-31 14:31:17 -0500 (Tue, 31 Mar 2009) | 3 lines Delete out-of-date and little-known README from the test directory by consensus of devs at pycon sprint. ........ r70883 | georg.brandl | 2009-03-31 15:41:08 -0500 (Tue, 31 Mar 2009) | 1 line #1674032: return value of flag from Event.wait(). OKed by Guido. ........ r70885 | tarek.ziade | 2009-03-31 15:48:31 -0500 (Tue, 31 Mar 2009) | 1 line using log.warn for sys.stderr ........ r70893 | georg.brandl | 2009-03-31 15:56:32 -0500 (Tue, 31 Mar 2009) | 1 line #1530012: move TQS section before raw strings. ........ r70894 | benjamin.peterson | 2009-03-31 16:06:30 -0500 (Tue, 31 Mar 2009) | 1 line take the usual lock precautions around _active_limbo_lock ........ r70896 | georg.brandl | 2009-03-31 16:15:33 -0500 (Tue, 31 Mar 2009) | 1 line #5598: document DocFileSuite *args argument. ........ r70897 | benjamin.peterson | 2009-03-31 16:34:42 -0500 (Tue, 31 Mar 2009) | 1 line fix Thread.ident when it is the main thread or a dummy thread #5632 ........ r70903 | georg.brandl | 2009-03-31 16:45:18 -0500 (Tue, 31 Mar 2009) | 1 line #1676135: remove trailing slashes from --prefix argument. ........ r70905 | georg.brandl | 2009-03-31 17:03:40 -0500 (Tue, 31 Mar 2009) | 1 line #5563: more documentation for bdist_msi. ........ r70906 | georg.brandl | 2009-03-31 17:11:53 -0500 (Tue, 31 Mar 2009) | 1 line #1651995: fix _convert_ref for non-ASCII characters. ........ r70907 | georg.brandl | 2009-03-31 17:18:19 -0500 (Tue, 31 Mar 2009) | 1 line #3427: document correct return type for urlopen().info(). ........ r70915 | georg.brandl | 2009-03-31 17:40:16 -0500 (Tue, 31 Mar 2009) | 1 line #5018: remove confusing paragraph. ........ r70927 | georg.brandl | 2009-03-31 18:01:27 -0500 (Tue, 31 Mar 2009) | 1 line Dont shout to users. ........ r70933 | georg.brandl | 2009-03-31 19:04:33 -0500 (Tue, 31 Mar 2009) | 2 lines Issue #5635: Fix running test_sys with tracing enabled. ........ r70951 | georg.brandl | 2009-04-01 09:02:27 -0500 (Wed, 01 Apr 2009) | 1 line Add Maksim, who worked on several issues at the sprint. ........ r70960 | jesse.noller | 2009-04-01 11:42:19 -0500 (Wed, 01 Apr 2009) | 1 line Issue 3270: document Listener address restrictions on windows ........ r70962 | brett.cannon | 2009-04-01 12:07:16 -0500 (Wed, 01 Apr 2009) | 2 lines Ron DuPlain was given commit privileges at PyCon 2009 to work on 3to2. ........ r70963 | georg.brandl | 2009-04-01 12:46:01 -0500 (Wed, 01 Apr 2009) | 1 line #5655: fix docstring oversight. ........ r70964 | brett.cannon | 2009-04-01 12:52:13 -0500 (Wed, 01 Apr 2009) | 2 lines Paul Kippes was given commit privileges to work on 3to2. ........ r70998 | georg.brandl | 2009-04-01 16:54:21 -0500 (Wed, 01 Apr 2009) | 1 line In Pdb, stop assigning values to __builtin__._ which interferes with the one commonly installed by gettext. ........ r71001 | brett.cannon | 2009-04-01 18:01:12 -0500 (Wed, 01 Apr 2009) | 3 lines Add my initials to Misc/developers.txt. Names are now sorted by number of characters in the person's name. ........ r71006 | georg.brandl | 2009-04-01 18:32:17 -0500 (Wed, 01 Apr 2009) | 1 line Cache the f_locals dict of the current frame, since every access to frame.f_locals overrides its contents with the real locals which undoes modifications made by the debugging user. ........ r71008 | andrew.kuchling | 2009-04-01 19:02:14 -0500 (Wed, 01 Apr 2009) | 1 line Typo fix ........ r71010 | benjamin.peterson | 2009-04-01 19:11:52 -0500 (Wed, 01 Apr 2009) | 1 line fix markup ........ r71011 | benjamin.peterson | 2009-04-01 19:12:47 -0500 (Wed, 01 Apr 2009) | 1 line this should be :noindex: ........ r71019 | georg.brandl | 2009-04-01 21:00:01 -0500 (Wed, 01 Apr 2009) | 1 line Fix test_doctest, missed two assignments to curframe. ........ r71037 | r.david.murray | 2009-04-01 23:34:04 -0500 (Wed, 01 Apr 2009) | 6 lines Clarify that datetime strftime does not produce leap seconds and datetime strptime does not accept it in the strftime behavior section of the datetime docs. Closes issue 2568. ........ r71056 | georg.brandl | 2009-04-02 12:43:07 -0500 (Thu, 02 Apr 2009) | 2 lines Actually the displayhook should print the repr. ........ r71094 | vinay.sajip | 2009-04-03 05:23:18 -0500 (Fri, 03 Apr 2009) | 1 line Added warning about logging use from asynchronous signal handlers. ........ r71101 | andrew.kuchling | 2009-04-03 16:43:00 -0500 (Fri, 03 Apr 2009) | 1 line Add some items ........ r71102 | andrew.kuchling | 2009-04-03 16:44:49 -0500 (Fri, 03 Apr 2009) | 1 line Fix 'the the'; grammar fix ........ r71103 | andrew.kuchling | 2009-04-03 16:45:29 -0500 (Fri, 03 Apr 2009) | 1 line Fix 'the the' duplication ........ r71106 | vinay.sajip | 2009-04-03 16:58:16 -0500 (Fri, 03 Apr 2009) | 1 line Clarified warning about logging use from asynchronous signal handlers. ........ r71119 | raymond.hettinger | 2009-04-04 00:37:47 -0500 (Sat, 04 Apr 2009) | 1 line Add helpful link. ........ r71123 | r.david.murray | 2009-04-04 01:39:56 -0500 (Sat, 04 Apr 2009) | 2 lines Fix error in description of 'oct' (issue 5678). ........ r71149 | georg.brandl | 2009-04-04 08:42:39 -0500 (Sat, 04 Apr 2009) | 1 line #5642: clarify map() compatibility to the builtin. ........ r71150 | georg.brandl | 2009-04-04 08:45:49 -0500 (Sat, 04 Apr 2009) | 1 line #5601: clarify that webbrowser is not meant for file names. ........ r71203 | benjamin.peterson | 2009-04-04 18:46:34 -0500 (Sat, 04 Apr 2009) | 1 line note how using iter* are unsafe while mutating and document iter(dict) ........ r71212 | georg.brandl | 2009-04-05 05:24:20 -0500 (Sun, 05 Apr 2009) | 1 line #1742837: expand HTTP server docs, and fix SocketServer ones to document methods as methods, not functions. ........ r71214 | georg.brandl | 2009-04-05 05:29:57 -0500 (Sun, 05 Apr 2009) | 1 line Normalize spelling of Mac OS X. ........ r71215 | georg.brandl | 2009-04-05 05:32:26 -0500 (Sun, 05 Apr 2009) | 1 line Avoid sure signs of a diseased mind. ........ r71216 | georg.brandl | 2009-04-05 05:41:02 -0500 (Sun, 05 Apr 2009) | 1 line #1718017: document the relation of os.path and the posixpath, ntpath etc. modules better. ........ r71217 | georg.brandl | 2009-04-05 05:48:47 -0500 (Sun, 05 Apr 2009) | 1 line #1726172: dont raise an unexpected IndexError if a voidresp() call has an empty response. ........ r71221 | vinay.sajip | 2009-04-05 06:06:24 -0500 (Sun, 05 Apr 2009) | 1 line Issue #5695: Moved logging.captureWarnings() call inside with statement in WarningsTest.test_warnings. ........ r71240 | georg.brandl | 2009-04-05 09:40:06 -0500 (Sun, 05 Apr 2009) | 1 line #5370: doc update about unpickling objects with custom __getattr__ etc. methods. ........ Removed: python/branches/py3k/Lib/test/README Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/init.rst python/branches/py3k/Doc/c-api/number.rst python/branches/py3k/Doc/c-api/object.rst python/branches/py3k/Doc/c-api/structures.rst python/branches/py3k/Doc/c-api/veryhigh.rst python/branches/py3k/Doc/distutils/apiref.rst python/branches/py3k/Doc/extending/extending.rst python/branches/py3k/Doc/howto/cporting.rst python/branches/py3k/Doc/library/abc.rst python/branches/py3k/Doc/library/doctest.rst python/branches/py3k/Doc/library/functions.rst python/branches/py3k/Doc/library/itertools.rst python/branches/py3k/Doc/library/logging.rst python/branches/py3k/Doc/library/multiprocessing.rst python/branches/py3k/Doc/library/os.path.rst python/branches/py3k/Doc/library/os.rst python/branches/py3k/Doc/library/pdb.rst python/branches/py3k/Doc/library/pickle.rst python/branches/py3k/Doc/library/re.rst python/branches/py3k/Doc/library/shelve.rst python/branches/py3k/Doc/library/socketserver.rst python/branches/py3k/Doc/library/ssl.rst python/branches/py3k/Doc/library/stdtypes.rst python/branches/py3k/Doc/library/sys.rst python/branches/py3k/Doc/library/threading.rst python/branches/py3k/Doc/library/tkinter.ttk.rst python/branches/py3k/Doc/library/urllib.request.rst python/branches/py3k/Doc/library/webbrowser.rst python/branches/py3k/Doc/library/winreg.rst python/branches/py3k/Doc/reference/datamodel.rst python/branches/py3k/Doc/tutorial/datastructures.rst python/branches/py3k/Doc/tutorial/introduction.rst python/branches/py3k/Doc/whatsnew/2.6.rst python/branches/py3k/Doc/whatsnew/2.7.rst python/branches/py3k/Lib/distutils/cmd.py python/branches/py3k/Lib/distutils/log.py python/branches/py3k/Lib/ftplib.py python/branches/py3k/Lib/glob.py python/branches/py3k/Lib/optparse.py python/branches/py3k/Lib/pdb.py python/branches/py3k/Lib/test/test_pprint.py python/branches/py3k/Lib/test/test_sys.py python/branches/py3k/Lib/test/test_threading.py python/branches/py3k/Lib/threading.py python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/developers.txt python/branches/py3k/Objects/genobject.c python/branches/py3k/configure python/branches/py3k/configure.in 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 Sun Apr 5 21:13:16 2009 @@ -787,7 +787,7 @@ Asynchronous Notifications ========================== -A mechanism is provided to make asynchronous notifications to the the main +A mechanism is provided to make asynchronous notifications to the main interpreter thread. These notifications take the form of a function pointer and a void argument. Modified: python/branches/py3k/Doc/c-api/number.rst ============================================================================== --- python/branches/py3k/Doc/c-api/number.rst (original) +++ python/branches/py3k/Doc/c-api/number.rst Sun Apr 5 21:13:16 2009 @@ -264,8 +264,8 @@ .. cfunction:: PyObject* PyNumber_ToBase(PyObject *n, int base) - Returns the the integer *n* converted to *base* as a string with a base - marker of ``'0b'``, ``'0o'``, or ``'0x'`` if appended applicable. When + Returns the integer *n* converted to *base* as a string with a base + marker of ``'0b'``, ``'0o'``, or ``'0x'`` if applicable. When *base* is not 2, 8, 10, or 16, the format is ``'x#num'`` where x is the base. If *n* is not an int object, it is converted with :cfunc:`PyNumber_Index` first. Modified: python/branches/py3k/Doc/c-api/object.rst ============================================================================== --- python/branches/py3k/Doc/c-api/object.rst (original) +++ python/branches/py3k/Doc/c-api/object.rst Sun Apr 5 21:13:16 2009 @@ -42,6 +42,16 @@ expression ``o.attr_name``. +.. cfunction:: PyObject* PyObject_GenericGetAttr(PyObject *o, PyObject *name) + + Generic attribute getter function that is meant to be put into a type + object's ``tp_getattro`` slot. It looks for a descriptor in the dictionary + of classes in the object's MRO as well as an attribute in the object's + :attr:`__dict__` (if present). As outlined in :ref:`descriptors`, data + descriptors take preference over instance attributes, while non-data + descriptors don't. Otherwise, an :exc:`AttributeError` is raised. + + .. cfunction:: int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v) Set the value of the attribute named *attr_name*, for object *o*, to the value @@ -56,6 +66,16 @@ ``o.attr_name = v``. +.. cfunction:: int PyObject_GenericSetAttr(PyObject *o, PyObject *name, PyObject *value) + + Generic attribute setter function that is meant to be put into a type + object's ``tp_setattro`` slot. It looks for a data descriptor in the + dictionary of classes in the object's MRO, and if found it takes preference + over setting the attribute in the instance dictionary. Otherwise, the + attribute is set in the object's :attr:`__dict__` (if present). Otherwise, + an :exc:`AttributeError` is raised and ``-1`` is returned. + + .. cfunction:: int PyObject_DelAttr(PyObject *o, PyObject *attr_name) Delete attribute named *attr_name*, for object *o*. Returns ``-1`` on failure. Modified: python/branches/py3k/Doc/c-api/structures.rst ============================================================================== --- python/branches/py3k/Doc/c-api/structures.rst (original) +++ python/branches/py3k/Doc/c-api/structures.rst Sun Apr 5 21:13:16 2009 @@ -241,7 +241,7 @@ T_OBJECT_EX PyObject \* T_CHAR char T_BYTE char - T_UNBYTE unsigned char + T_UBYTE unsigned char T_UINT unsigned int T_USHORT unsigned short T_ULONG unsigned long 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 Sun Apr 5 21:13:16 2009 @@ -38,6 +38,10 @@ interpreter exits due to an exception, or ``2`` if the parameter list does not represent a valid Python command line. + Note that if an otherwise unhandled :exc:`SystemError` is raised, this + function will not return ``1``, but exit the process, as long as + ``Py_InspectFlag`` is not set. + .. cfunction:: int PyRun_AnyFile(FILE *fp, const char *filename) @@ -80,6 +84,10 @@ there was an error, there is no way to get the exception information. For the meaning of *flags*, see below. + Note that if an otherwise unhandled :exc:`SystemError` is raised, this + function will not return ``-1``, but exit the process, as long as + ``Py_InspectFlag`` is not set. + .. cfunction:: int PyRun_SimpleFile(FILE *fp, const char *filename) Modified: python/branches/py3k/Doc/distutils/apiref.rst ============================================================================== --- python/branches/py3k/Doc/distutils/apiref.rst (original) +++ python/branches/py3k/Doc/distutils/apiref.rst Sun Apr 5 21:13:16 2009 @@ -1050,8 +1050,8 @@ .. warning:: - Handles cross-device moves on Unix using :func:`copy_file`. What about other - systems??? + Handles cross-device moves on Unix using :func:`copy_file`. What about + other systems? .. function:: write_file(filename, contents) @@ -1091,17 +1091,17 @@ For non-POSIX platforms, currently just returns ``sys.platform``. - For MacOS X systems the OS version reflects the minimal version on which + For Mac OS X systems the OS version reflects the minimal version on which binaries will run (that is, the value of ``MACOSX_DEPLOYMENT_TARGET`` during the build of Python), not the OS version of the current system. - For universal binary builds on MacOS X the architecture value reflects + For universal binary builds on Mac OS X the architecture value reflects the univeral binary status instead of the architecture of the current processor. For 32-bit universal binaries the architecture is ``fat``, for 64-bit universal binaries the architecture is ``fat64``, and for 4-way universal binaries the architecture is ``universal``. - Examples of returned values on MacOS X: + Examples of returned values on Mac OS X: * ``macosx-10.3-ppc`` @@ -1758,8 +1758,16 @@ .. module:: distutils.command.bdist_msi :synopsis: Build a binary distribution as a Windows MSI file +.. class:: bdist_msi(Command) -.. % todo + Builds a `Windows Installer`_ (.msi) binary package. + + .. _Windows Installer: http://msdn.microsoft.com/en-us/library/cc185688(VS.85).aspx + + In most cases, the ``bdist_msi`` installer is a better choice than the + ``bdist_wininst`` installer, because it provides better support for + Win64 platforms, allows administrators to perform non-interactive + installations, and allows installation through group policies. :mod:`distutils.command.bdist_rpm` --- Build a binary distribution as a Redhat RPM and SRPM Modified: python/branches/py3k/Doc/extending/extending.rst ============================================================================== --- python/branches/py3k/Doc/extending/extending.rst (original) +++ python/branches/py3k/Doc/extending/extending.rst Sun Apr 5 21:13:16 2009 @@ -476,10 +476,10 @@ (but note that *temp* will not be *NULL* in this context). More info on them in section :ref:`refcounts`. -.. index:: single: PyEval_CallObject() +.. index:: single: PyObject_CallObject() Later, when it is time to call the function, you call the C function -:cfunc:`PyEval_CallObject`. This function has two arguments, both pointers to +:cfunc:`PyObject_CallObject`. This function has two arguments, both pointers to arbitrary Python objects: the Python function, and the argument list. The argument list must always be a tuple object, whose length is the number of arguments. To call the Python function with no arguments, pass in NULL, or @@ -495,16 +495,16 @@ ... /* Time to call the callback */ arglist = Py_BuildValue("(i)", arg); - result = PyEval_CallObject(my_callback, arglist); + result = PyObject_CallObject(my_callback, arglist); Py_DECREF(arglist); -:cfunc:`PyEval_CallObject` returns a Python object pointer: this is the return -value of the Python function. :cfunc:`PyEval_CallObject` is +:cfunc:`PyObject_CallObject` returns a Python object pointer: this is the return +value of the Python function. :cfunc:`PyObject_CallObject` is "reference-count-neutral" with respect to its arguments. In the example a new tuple was created to serve as the argument list, which is :cfunc:`Py_DECREF`\ -ed immediately after the call. -The return value of :cfunc:`PyEval_CallObject` is "new": either it is a brand +The return value of :cfunc:`PyObject_CallObject` is "new": either it is a brand new object, or it is an existing object whose reference count has been incremented. So, unless you want to save it in a global variable, you should somehow :cfunc:`Py_DECREF` the result, even (especially!) if you are not @@ -512,7 +512,7 @@ Before you do this, however, it is important to check that the return value isn't *NULL*. If it is, the Python function terminated by raising an exception. -If the C code that called :cfunc:`PyEval_CallObject` is called from Python, it +If the C code that called :cfunc:`PyObject_CallObject` is called from Python, it should now return an error indication to its Python caller, so the interpreter can print a stack trace, or the calling Python code can handle the exception. If this is not possible or desirable, the exception should be cleared by calling @@ -524,7 +524,7 @@ Py_DECREF(result); Depending on the desired interface to the Python callback function, you may also -have to provide an argument list to :cfunc:`PyEval_CallObject`. In some cases +have to provide an argument list to :cfunc:`PyObject_CallObject`. In some cases the argument list is also provided by the Python program, through the same interface that specified the callback function. It can then be saved and used in the same manner as the function object. In other cases, you may have to @@ -535,7 +535,7 @@ PyObject *arglist; ... arglist = Py_BuildValue("(l)", eventcode); - result = PyEval_CallObject(my_callback, arglist); + result = PyObject_CallObject(my_callback, arglist); Py_DECREF(arglist); if (result == NULL) return NULL; /* Pass error back */ @@ -547,19 +547,20 @@ :cfunc:`Py_BuildValue` may run out of memory, and this should be checked. You may also call a function with keyword arguments by using -:cfunc:`PyEval_CallObjectWithKeywords`. As in the above example, we use -:cfunc:`Py_BuildValue` to construct the dictionary. :: +:cfunc:`PyObject_Call`, which supports arguments and keyword arguments. As in +the above example, we use :cfunc:`Py_BuildValue` to construct the dictionary. :: PyObject *dict; ... dict = Py_BuildValue("{s:i}", "name", val); - result = PyEval_CallObjectWithKeywords(my_callback, NULL, dict); + result = PyObject_Call(my_callback, NULL, dict); Py_DECREF(dict); if (result == NULL) return NULL; /* Pass error back */ /* Here maybe use the result */ Py_DECREF(result); + .. _parsetuple: Extracting Parameters in Extension Functions Modified: python/branches/py3k/Doc/howto/cporting.rst ============================================================================== --- python/branches/py3k/Doc/howto/cporting.rst (original) +++ python/branches/py3k/Doc/howto/cporting.rst Sun Apr 5 21:13:16 2009 @@ -98,7 +98,7 @@ Python level, but actually corresponds to 2.x's :func:`long` type. In the C-API, ``PyInt_*`` functions are replaced by their ``PyLong_*`` neighbors. The best course of action here is using the ``PyInt_*`` functions aliased to -``PyLong_*`` found in :file:`intobject.h`. The the abstract ``PyNumber_*`` APIs +``PyLong_*`` found in :file:`intobject.h`. The abstract ``PyNumber_*`` APIs can also be used in some cases. :: #include "Python.h" Modified: python/branches/py3k/Doc/library/abc.rst ============================================================================== --- python/branches/py3k/Doc/library/abc.rst (original) +++ python/branches/py3k/Doc/library/abc.rst Sun Apr 5 21:13:16 2009 @@ -132,7 +132,7 @@ A class that has a metaclass derived from :class:`ABCMeta` cannot be instantiated unless all of its abstract methods and properties are overridden. - The abstract methods can be called using any of the the normal 'super' call + The abstract methods can be called using any of the normal 'super' call mechanisms. Dynamically adding abstract methods to a class, or attempting to modify the @@ -184,6 +184,7 @@ def setx(self, value): ... x = abstractproperty(getx, setx) + .. rubric:: Footnotes .. [#] C++ programmers should note that Python's virtual base class Modified: python/branches/py3k/Doc/library/doctest.rst ============================================================================== --- python/branches/py3k/Doc/library/doctest.rst (original) +++ python/branches/py3k/Doc/library/doctest.rst Sun Apr 5 21:13:16 2009 @@ -905,7 +905,7 @@ from text files and modules with doctests: -.. function:: DocFileSuite([module_relative][, package][, setUp][, tearDown][, globs][, optionflags][, parser][, encoding]) +.. function:: DocFileSuite(*paths, [module_relative][, package][, setUp][, tearDown][, globs][, optionflags][, parser][, encoding]) Convert doctest tests from one or more text files to a :class:`unittest.TestSuite`. @@ -923,45 +923,47 @@ Optional argument *module_relative* specifies how the filenames in *paths* should be interpreted: - * If *module_relative* is ``True`` (the default), then each filename specifies - an OS-independent module-relative path. By default, this path is relative to - the calling module's directory; but if the *package* argument is specified, then - it is relative to that package. To ensure OS-independence, each filename should - use ``/`` characters to separate path segments, and may not be an absolute path - (i.e., it may not begin with ``/``). - - * If *module_relative* is ``False``, then each filename specifies an OS-specific - path. The path may be absolute or relative; relative paths are resolved with - respect to the current working directory. - - Optional argument *package* is a Python package or the name of a Python package - whose directory should be used as the base directory for module-relative - filenames. If no package is specified, then the calling module's directory is - used as the base directory for module-relative filenames. It is an error to - specify *package* if *module_relative* is ``False``. - - Optional argument *setUp* specifies a set-up function for the test suite. This - is called before running the tests in each file. The *setUp* function will be - passed a :class:`DocTest` object. The setUp function can access the test - globals as the *globs* attribute of the test passed. + * If *module_relative* is ``True`` (the default), then each filename in + *paths* specifies an OS-independent module-relative path. By default, this + path is relative to the calling module's directory; but if the *package* + argument is specified, then it is relative to that package. To ensure + OS-independence, each filename should use ``/`` characters to separate path + segments, and may not be an absolute path (i.e., it may not begin with + ``/``). + + * If *module_relative* is ``False``, then each filename in *paths* specifies + an OS-specific path. The path may be absolute or relative; relative paths + are resolved with respect to the current working directory. + + Optional argument *package* is a Python package or the name of a Python + package whose directory should be used as the base directory for + module-relative filenames in *paths*. If no package is specified, then the + calling module's directory is used as the base directory for module-relative + filenames. It is an error to specify *package* if *module_relative* is + ``False``. - Optional argument *tearDown* specifies a tear-down function for the test suite. - This is called after running the tests in each file. The *tearDown* function + Optional argument *setUp* specifies a set-up function for the test suite. + This is called before running the tests in each file. The *setUp* function will be passed a :class:`DocTest` object. The setUp function can access the test globals as the *globs* attribute of the test passed. + Optional argument *tearDown* specifies a tear-down function for the test + suite. This is called after running the tests in each file. The *tearDown* + function will be passed a :class:`DocTest` object. The setUp function can + access the test globals as the *globs* attribute of the test passed. + Optional argument *globs* is a dictionary containing the initial global variables for the tests. A new copy of this dictionary is created for each test. By default, *globs* is a new empty dictionary. Optional argument *optionflags* specifies the default doctest options for the tests, created by or-ing together individual option flags. See section - :ref:`doctest-options`. See function :func:`set_unittest_reportflags` below for - a better way to set reporting options. + :ref:`doctest-options`. See function :func:`set_unittest_reportflags` below + for a better way to set reporting options. - Optional argument *parser* specifies a :class:`DocTestParser` (or subclass) that - should be used to extract tests from the files. It defaults to a normal parser - (i.e., ``DocTestParser()``). + Optional argument *parser* specifies a :class:`DocTestParser` (or subclass) + that should be used to extract tests from the files. It defaults to a normal + parser (i.e., ``DocTestParser()``). Optional argument *encoding* specifies an encoding that should be used to convert the file to unicode. Modified: python/branches/py3k/Doc/library/functions.rst ============================================================================== --- python/branches/py3k/Doc/library/functions.rst (original) +++ python/branches/py3k/Doc/library/functions.rst Sun Apr 5 21:13:16 2009 @@ -1163,9 +1163,11 @@ Without arguments, return a dictionary corresponding to the current local symbol table. With a module, class or class instance object as argument (or anything else that has a :attr:`__dict__` attribute), returns a dictionary corresponding - to the object's symbol table. The returned dictionary should not be modified: - the effects on the corresponding symbol table are undefined. [#]_ + to the object's symbol table. + .. warning:: + The returned dictionary should not be modified: + the effects on the corresponding symbol table are undefined. [#]_ .. function:: zip(*iterables) Modified: python/branches/py3k/Doc/library/itertools.rst ============================================================================== --- python/branches/py3k/Doc/library/itertools.rst (original) +++ python/branches/py3k/Doc/library/itertools.rst Sun Apr 5 21:13:16 2009 @@ -207,7 +207,7 @@ 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 have been exhausted. + Stops when either the *data* or *selectors* iterables has been exhausted. Equivalent to:: def compress(data, selectors): Modified: python/branches/py3k/Doc/library/logging.rst ============================================================================== --- python/branches/py3k/Doc/library/logging.rst (original) +++ python/branches/py3k/Doc/library/logging.rst Sun Apr 5 21:13:16 2009 @@ -2290,6 +2290,10 @@ locks; there is one lock to serialize access to the module's shared data, and each handler also creates a lock to serialize access to its underlying I/O. +If you are implementing asynchronous signal handlers using the :mod:`signal` +module, you may not be able to use logging from within such handlers. This is +because lock implementations in the :mod:`threading` module are not always +re-entrant, and so cannot be invoked from such signal handlers. Configuration ------------- Modified: python/branches/py3k/Doc/library/multiprocessing.rst ============================================================================== --- python/branches/py3k/Doc/library/multiprocessing.rst (original) +++ python/branches/py3k/Doc/library/multiprocessing.rst Sun Apr 5 21:13:16 2009 @@ -1537,8 +1537,8 @@ .. method:: map(func, iterable[, chunksize]) - A parallel equivalent of the :func:`map` builtin function, collecting the - result in a list. It blocks till the whole result is ready. + A parallel equivalent of the :func:`map` builtin function (it supports only + one *iterable* argument though). It blocks till the result is ready. This method chops the iterable into a number of chunks which it submits to the process pool as separate tasks. The (approximate) size of these @@ -1697,6 +1697,12 @@ *address* is the address to be used by the bound socket or named pipe of the listener object. + .. note:: + + If an address of '0.0.0.0' is used, the address will not be a connectable + end point on Windows. If you require a connectable end-point, + you should use '127.0.0.1'. + *family* is the type of socket (or named pipe) to use. This can be one of the strings ``'AF_INET'`` (for a TCP socket), ``'AF_UNIX'`` (for a Unix domain socket) or ``'AF_PIPE'`` (for a Windows named pipe). Of these only @@ -1839,7 +1845,7 @@ any :class:`~multiprocessing.Process` object that the current process creates. This means that (by default) all processes of a multi-process program will share a single authentication key which can be used when setting up connections -between the themselves. +between themselves. Suitable authentication keys can also be generated by using :func:`os.urandom`. 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 Apr 5 21:13:16 2009 @@ -1,11 +1,9 @@ - :mod:`os.path` --- Common pathname manipulations ================================================ .. module:: os.path :synopsis: Operations on pathnames. - .. index:: single: path; operations This module implements some useful functions on pathnames. To read or @@ -31,6 +29,22 @@ :func:`splitunc` and :func:`ismount` do handle them correctly. +.. note:: + + Since different operating systems have different path name conventions, there + are several versions of this module in the standard library. The + :mod:`os.path` module is always the path module suitable for the operating + system Python is running on, and therefore usable for local paths. However, + you can also import and use the individual modules if you want to manipulate + a path that is *always* in one of the different formats. They all have the + same interface: + + * :mod:`posixpath` for UNIX-style paths + * :mod:`ntpath` for Windows paths + * :mod:`macpath` for old-style MacOS paths + * :mod:`os2emxpath` for OS/2 EMX paths + + .. function:: abspath(path) Return a normalized absolutized version of the pathname *path*. On most @@ -189,9 +203,9 @@ .. function:: normcase(path) - Normalize the case of a pathname. On Unix and MacOSX, this returns the path unchanged; on - case-insensitive filesystems, it converts the path to lowercase. On Windows, it - also converts forward slashes to backward slashes. + Normalize the case of a pathname. On Unix and Mac OS X, this returns the + path unchanged; on case-insensitive filesystems, it converts the path to + lowercase. On Windows, it also converts forward slashes to backward slashes. .. function:: normpath(path) Modified: python/branches/py3k/Doc/library/os.rst ============================================================================== --- python/branches/py3k/Doc/library/os.rst (original) +++ python/branches/py3k/Doc/library/os.rst Sun Apr 5 21:13:16 2009 @@ -51,15 +51,6 @@ ``'ce'``, ``'java'``. -.. data:: path - - The corresponding operating system dependent standard module for pathname - operations, such as :mod:`posixpath` or :mod:`ntpath`. Thus, given the proper - imports, ``os.path.split(file)`` is equivalent to but more portable than - ``posixpath.split(file)``. Note that this is also an importable module: it may - be imported directly as :mod:`os.path`. - - .. _os-procinfo: Process Parameters @@ -1491,7 +1482,9 @@ which is used to define the environment variables for the new process (they are used instead of the current process' environment); the functions :func:`spawnl`, :func:`spawnlp`, :func:`spawnv`, and :func:`spawnvp` all cause - the new process to inherit the environment of the current process. + the new process to inherit the environment of the current process. Note that + keys and values in the *env* dictionary must be strings; invalid keys or + values will cause the function to fail, with a return value of ``127``. As an example, the following calls to :func:`spawnlp` and :func:`spawnvpe` are equivalent:: Modified: python/branches/py3k/Doc/library/pdb.rst ============================================================================== --- python/branches/py3k/Doc/library/pdb.rst (original) +++ python/branches/py3k/Doc/library/pdb.rst Sun Apr 5 21:13:16 2009 @@ -262,7 +262,7 @@ full speed, only stopping at the next line in the current function.) unt(il) - Continue execution until the line with the the line number greater than the + Continue execution until the line with the line number greater than the current one is reached or when returning from current frame. r(eturn) Modified: python/branches/py3k/Doc/library/pickle.rst ============================================================================== --- python/branches/py3k/Doc/library/pickle.rst (original) +++ python/branches/py3k/Doc/library/pickle.rst Sun Apr 5 21:13:16 2009 @@ -436,6 +436,14 @@ Refer to the section :ref:`pickle-state` for more information about how to use the methods :meth:`__getstate__` and :meth:`__setstate__`. +.. note:: + At unpickling time, some methods like :meth:`__getattr__`, + :meth:`__getattribute__`, or :meth:`__setattr__` may be called upon the + instance. In case those methods rely on some internal invariant being + true, the type should implement either :meth:`__getinitargs__` or + :meth:`__getnewargs__` to establish such an invariant; otherwise, neither + :meth:`__new__` nor :meth:`__init__` will be called. + .. index:: pair: copy; protocol single: __reduce__() (copy protocol) Modified: python/branches/py3k/Doc/library/re.rst ============================================================================== --- python/branches/py3k/Doc/library/re.rst (original) +++ python/branches/py3k/Doc/library/re.rst Sun Apr 5 21:13:16 2009 @@ -8,10 +8,9 @@ .. sectionauthor:: Andrew M. Kuchling - - This module provides regular expression matching operations similar to -those found in Perl. The :mod:`re` module is always available. +those found in Perl. Both patterns and strings to be searched can be +Unicode strings as well as 8-bit strings. Both patterns and strings to be searched can be Unicode strings as well as 8-bit strings. However, Unicode strings and 8-bit strings cannot be mixed: @@ -47,9 +46,6 @@ second edition of the book no longer covers Python at all, but the first edition covered writing good regular expression patterns in great detail. - `Kodos `_ - is a graphical regular expression debugger written in Python. - .. _re-syntax: @@ -241,16 +237,18 @@ ``(?P...)`` Similar to regular parentheses, but the substring matched by the group is - accessible via the symbolic group name *name*. Group names must be valid Python - identifiers, and each group name must be defined only once within a regular - expression. A symbolic group is also a numbered group, just as if the group - were not named. So the group named 'id' in the example below can also be - referenced as the numbered group 1. + accessible within the rest of the regular expression via the symbolic group + name *name*. Group names must be valid Python identifiers, and each group + name must be defined only once within a regular expression. A symbolic group + is also a numbered group, just as if the group were not named. So the group + named ``id`` in the example below can also be referenced as the numbered group + ``1``. For example, if the pattern is ``(?P[a-zA-Z_]\w*)``, the group can be referenced by its name in arguments to methods of match objects, such as - ``m.group('id')`` or ``m.end('id')``, and also by name in pattern text (for - example, ``(?P=id)``) and replacement text (such as ``\g``). + ``m.group('id')`` or ``m.end('id')``, and also by name in the regular + expression itself (using ``(?P=id)``) and replacement text given to + ``.sub()`` (using ``\g``). ``(?P=name)`` Matches whatever text was matched by the earlier group named *name*. Modified: python/branches/py3k/Doc/library/shelve.rst ============================================================================== --- python/branches/py3k/Doc/library/shelve.rst (original) +++ python/branches/py3k/Doc/library/shelve.rst Sun Apr 5 21:13:16 2009 @@ -141,7 +141,7 @@ # as d was opened WITHOUT writeback=True, beware: d['xx'] = range(4) # this works as expected, but... - d['xx'].append(5) # *this doesn't!* -- d['xx'] is STILL range(4)!!! + d['xx'].append(5) # *this doesn't!* -- d['xx'] is STILL range(4)! # having opened d without writeback=True, you need to code carefully: temp = d['xx'] # extracts the copy Modified: python/branches/py3k/Doc/library/socketserver.rst ============================================================================== --- python/branches/py3k/Doc/library/socketserver.rst (original) +++ python/branches/py3k/Doc/library/socketserver.rst Sun Apr 5 21:13:16 2009 @@ -122,15 +122,21 @@ Server Objects -------------- +.. class:: BaseServer -.. function:: fileno() + This is the superclass of all Server objects in the module. It defines the + interface, given below, but does not implement most of the methods, which is + done in subclasses. + + +.. method:: BaseServer.fileno() Return an integer file descriptor for the socket on which the server is listening. This function is most commonly passed to :func:`select.select`, to allow monitoring multiple servers in the same process. -.. function:: handle_request() +.. method:: BaseServer.handle_request() Process a single request. This function calls the following methods in order: :meth:`get_request`, :meth:`verify_request`, and @@ -141,30 +147,30 @@ will return. -.. function:: serve_forever(poll_interval=0.5) +.. method:: BaseServer.serve_forever(poll_interval=0.5) Handle requests until an explicit :meth:`shutdown` request. Polls for shutdown every *poll_interval* seconds. -.. function:: shutdown() +.. method:: BaseServer.shutdown() Tells the :meth:`serve_forever` loop to stop and waits until it does. -.. data:: address_family +.. attribute:: BaseServer.address_family The family of protocols to which the server's socket belongs. Common examples are :const:`socket.AF_INET` and :const:`socket.AF_UNIX`. -.. data:: RequestHandlerClass +.. attribute:: BaseServer.RequestHandlerClass The user-provided request handler class; an instance of this class is created for each request. -.. data:: server_address +.. attribute:: BaseServer.server_address The address on which the server is listening. The format of addresses varies depending on the protocol family; see the documentation for the socket module @@ -172,22 +178,22 @@ the address, and an integer port number: ``('127.0.0.1', 80)``, for example. -.. data:: socket +.. attribute:: BaseServer.socket The socket object on which the server will listen for incoming requests. + The server classes support the following class variables: .. XXX should class variables be covered before instance variables, or vice versa? - -.. data:: allow_reuse_address +.. attribute:: BaseServer.allow_reuse_address Whether the server will allow the reuse of an address. This defaults to :const:`False`, and can be set in subclasses to change the policy. -.. data:: request_queue_size +.. attribute:: BaseServer.request_queue_size The size of the request queue. If it takes a long time to process a single request, any requests that arrive while the server is busy are placed into a @@ -196,17 +202,19 @@ value is usually 5, but this can be overridden by subclasses. -.. data:: socket_type +.. attribute:: BaseServer.socket_type The type of socket used by the server; :const:`socket.SOCK_STREAM` and :const:`socket.SOCK_DGRAM` are two common values. -.. data:: timeout + +.. attribute:: BaseServer.timeout Timeout duration, measured in seconds, or :const:`None` if no timeout is desired. If :meth:`handle_request` receives no incoming requests within the timeout period, the :meth:`handle_timeout` method is called. + There are various server methods that can be overridden by subclasses of base server classes like :class:`TCPServer`; these methods aren't useful to external users of the server object. @@ -214,27 +222,27 @@ .. XXX should the default implementations of these be documented, or should it be assumed that the user will look at socketserver.py? - -.. function:: finish_request() +.. method:: BaseServer.finish_request() Actually processes the request by instantiating :attr:`RequestHandlerClass` and calling its :meth:`handle` method. -.. function:: get_request() +.. method:: BaseServer.get_request() Must accept a request from the socket, and return a 2-tuple containing the *new* socket object to be used to communicate with the client, and the client's address. -.. function:: handle_error(request, client_address) +.. method:: BaseServer.handle_error(request, client_address) This function is called if the :attr:`RequestHandlerClass`'s :meth:`handle` method raises an exception. The default action is to print the traceback to standard output and continue handling further requests. -.. function:: handle_timeout() + +.. method:: BaseServer.handle_timeout() This function is called when the :attr:`timeout` attribute has been set to a value other than :const:`None` and the timeout period has passed with no @@ -242,31 +250,32 @@ to collect the status of any child processes that have exited, while in threading servers this method does nothing. -.. function:: process_request(request, client_address) + +.. method:: BaseServer.process_request(request, client_address) Calls :meth:`finish_request` to create an instance of the :attr:`RequestHandlerClass`. If desired, this function can create a new process or thread to handle the request; the :class:`ForkingMixIn` and :class:`ThreadingMixIn` classes do this. + .. Is there any point in documenting the following two functions? What would the purpose of overriding them be: initializing server instance variables, adding new network families? - -.. function:: server_activate() +.. method:: BaseServer.server_activate() Called by the server's constructor to activate the server. The default behavior just :meth:`listen`\ s to the server's socket. May be overridden. -.. function:: server_bind() +.. method:: BaseServer.server_bind() Called by the server's constructor to bind the socket to the desired address. May be overridden. -.. function:: verify_request(request, client_address) +.. method:: BaseServer.verify_request(request, client_address) Must return a Boolean value; if the value is :const:`True`, the request will be processed, and if it's :const:`False`, the request will be denied. This function @@ -282,14 +291,14 @@ request. -.. function:: finish() +.. method:: RequestHandler.finish() Called after the :meth:`handle` method to perform any clean-up actions required. The default implementation does nothing. If :meth:`setup` or :meth:`handle` raise an exception, this function will not be called. -.. function:: handle() +.. method:: RequestHandler.handle() This function must do all the work required to service a request. The default implementation does nothing. Several instance attributes are @@ -308,7 +317,7 @@ data or return data to the client. -.. function:: setup() +.. method:: RequestHandler.setup() Called before the :meth:`handle` method to perform any initialization actions required. The default implementation does nothing. Modified: python/branches/py3k/Doc/library/ssl.rst ============================================================================== --- python/branches/py3k/Doc/library/ssl.rst (original) +++ python/branches/py3k/Doc/library/ssl.rst Sun Apr 5 21:13:16 2009 @@ -293,7 +293,7 @@ If there is no certificate for the peer on the other end of the connection, returns ``None``. - If the the parameter ``binary_form`` is :const:`False`, and a + If the parameter ``binary_form`` is :const:`False`, and a certificate was received from the peer, this method returns a :class:`dict` instance. If the certificate was not validated, the dict is empty. If the certificate was validated, it returns a dict Modified: python/branches/py3k/Doc/library/stdtypes.rst ============================================================================== --- python/branches/py3k/Doc/library/stdtypes.rst (original) +++ python/branches/py3k/Doc/library/stdtypes.rst Sun Apr 5 21:13:16 2009 @@ -1834,6 +1834,11 @@ Equivalent to ``not key in d``. + .. describe:: iter(d) + + Return an iterator over the keys of the dictionary. This is a shortcut + for :meth:`iterkeys`. + .. method:: clear() Remove all items from the dictionary. @@ -1931,6 +1936,9 @@ using :func:`zip`: ``pairs = zip(d.values(), d.keys())``. Another way to create the same list is ``pairs = [(v, k) for (k, v) in d.items()]``. + Iterating views while adding or deleting entries in the dictionary will raise + a :exc:`RuntimeError`. + .. describe:: x in dictview Return ``True`` if *x* is in the underlying dictionary's keys, values or @@ -2666,10 +2674,26 @@ The name of the class or type. +The following attributes are only supported by :term:`new-style class`\ es. + +.. attribute:: class.__mro__ + + This attribute is a tuple of classes that are considered when looking for + base classes during method resolution. + + +.. method:: class.mro() + + This method can be overridden by a metaclass to customize the method + resolution order for its instances. It is called at class instantiation, and + its result is stored in :attr:`__mro__`. + + .. method:: class.__subclasses__ - All classes keep a list of weak references to their immediate subclasses. - This method returns a list of all those references still alive. Example:: + Each new-style class keeps a list of weak references to its immediate + subclasses. This method returns a list of all those references still alive. + Example:: >>> int.__subclasses__() [] Modified: python/branches/py3k/Doc/library/sys.rst ============================================================================== --- python/branches/py3k/Doc/library/sys.rst (original) +++ python/branches/py3k/Doc/library/sys.rst Sun Apr 5 21:13:16 2009 @@ -780,16 +780,20 @@ __stderr__ These objects contain the original values of ``stdin``, ``stderr`` and - ``stdout`` at the start of the program. They are used during finalization, and - could be useful to restore the actual files to known working file objects in - case they have been overwritten with a broken object. - - .. note:: - - Under some conditions ``stdin``, ``stdout`` and ``stderr`` as well as the - original values ``__stdin__``, ``__stdout__`` and ``__stderr__`` can be - None. It is usually the case for Windows GUI apps that aren't connected to - a console and Python apps started with :program:`pythonw`. + ``stdout`` at the start of the program. They are used during finalization, + and could be useful to print to the actual standard stream no matter if the + ``sys.std*`` object has been redirected. + + It can also be used to restore the actual files to known working file objects + in case they have been overwritten with a broken object. However, the + preferred way to do this is to explicitly save the previous stream before + replacing it, and restore the saved object. + + .. note:: + Under some conditions ``stdin``, ``stdout`` and ``stderr`` as well as the + original values ``__stdin__``, ``__stdout__`` and ``__stderr__`` can be + None. It is usually the case for Windows GUI apps that aren't connected + to a console and Python apps started with :program:`pythonw`. .. data:: tracebacklimit Modified: python/branches/py3k/Doc/library/threading.rst ============================================================================== --- python/branches/py3k/Doc/library/threading.rst (original) +++ python/branches/py3k/Doc/library/threading.rst Sun Apr 5 21:13:16 2009 @@ -676,14 +676,20 @@ .. method:: Event.wait([timeout]) - Block until the internal flag is true. If the internal flag is true on entry, - return immediately. Otherwise, block until another thread calls :meth:`set` to - set the flag to true, or until the optional timeout occurs. + Block until the internal flag is true. If the internal flag is true on entry, + return immediately. Otherwise, block until another thread calls :meth:`set` + to set the flag to true, or until the optional timeout occurs. When the timeout argument is present and not ``None``, it should be a floating point number specifying a timeout for the operation in seconds (or fractions thereof). + This method returns the internal flag on exit, so it will always return + ``True`` except if a timeout is given and the operation times out. + + .. versionchanged:: 2.7 + Previously, the method always returned ``None``. + .. _timer-objects: Modified: python/branches/py3k/Doc/library/tkinter.ttk.rst ============================================================================== --- python/branches/py3k/Doc/library/tkinter.ttk.rst (original) +++ python/branches/py3k/Doc/library/tkinter.ttk.rst Sun Apr 5 21:13:16 2009 @@ -249,7 +249,7 @@ ttk.Widget ^^^^^^^^^^ -Besides the methods described below, the class :class:`ttk.Widget` supports the +Besides the methods described below, the :class:`ttk.Widget` supports the methods :meth:`tkinter.Widget.cget` and :meth:`tkinter.Widget.configure`. .. class:: Widget @@ -484,7 +484,7 @@ The tab will not be displayed, but the associated window remains managed by the notebook and its configuration remembered. Hidden tabs - may be restored with the add command. + may be restored with the :meth:`add` command. .. method:: identify(x, y) @@ -503,7 +503,7 @@ Inserts a pane at the specified position. - *pos* is either the string end, an integer index, or the name of a + *pos* is either the string "end", an integer index, or the name of a managed child. If *child* is already managed by the notebook, moves it to the specified position. @@ -523,7 +523,7 @@ Query or modify the options of the specific *tab_id*. - If *kw* is not given, returns a dict of the tab option values. If + If *kw* is not given, returns a dictionary of the tab option values. If *option* is specified, returns the value of that *option*. Otherwise, sets the options to the corresponding values. @@ -540,14 +540,14 @@ This will extend the bindings for the toplevel window containing the notebook as follows: - * Control-Tab: selects the tab following the currently selected one - * Shift-Control-Tab: selects the tab preceding the currently selected one + * Control-Tab: selects the tab following the currently selected one. + * Shift-Control-Tab: selects the tab preceding the currently selected one. * Alt-K: where K is the mnemonic (underlined) character of any tab, will select that tab. Multiple notebooks in a single toplevel may be enabled for traversal, including nested notebooks. However, notebook traversal only works - properly if all panes have as master the notebook they are in. + properly if all panes have the notebook they are in as master. Progressbar @@ -580,12 +580,12 @@ +----------+---------------------------------------------------------------+ | value | The current value of the progress bar. In "determinate" mode, | | | this represents the amount of work completed. In | - | | "indeterminate" mode, it is interpreted as modulo maximum; | + | | "indeterminate" mode, it is interpreted as modulo *maximum*; | | | that is, the progress bar completes one "cycle" when its value| - | | increases by maximum. | + | | increases by *maximum*. | +----------+---------------------------------------------------------------+ | variable | A name which is linked to the option value. If specified, the | - | | value of the progressbar is automatically set to the value of | + | | value of the progress bar is automatically set to the value of| | | this name whenever the latter is modified. | +----------+---------------------------------------------------------------+ | phase | Read-only option. The widget periodically increments the value| @@ -602,14 +602,14 @@ .. method:: start([interval]) - Begin autoincrement mode: schedules a recurring timer even that calls + Begin autoincrement mode: schedules a recurring timer event that calls :meth:`Progressbar.step` every *interval* milliseconds. If omitted, *interval* defaults to 50 milliseconds. .. method:: step([amount]) - Increments progressbar's value by *amount*. + Increments the progress bar's value by *amount*. *amount* defaults to 1.0 if omitted. @@ -617,7 +617,7 @@ .. method:: stop() Stop autoincrement mode: cancels any recurring timer event initiated by - :meth:`Progressbar.start` for this progressbar. + :meth:`Progressbar.start` for this progress bar. Separator @@ -626,7 +626,7 @@ The :class:`ttk.Separator` widget displays a horizontal or vertical separator bar. -It has no other method besides the ones inherited from :class:`ttk.Widget`. +It has no other methods besides the ones inherited from :class:`ttk.Widget`. Options @@ -645,18 +645,18 @@ Sizegrip -------- -The :class:`ttk.Sizegrip` widget (also known as grow box) allows the user to +The :class:`ttk.Sizegrip` widget (also known as a grow box) allows the user to resize the containing toplevel window by pressing and dragging the grip. -This widget has no specific options neither specific methods, besides the +This widget has neither specific options nor specific methods, besides the ones inherited from :class:`ttk.Widget`. Platform-specific notes ^^^^^^^^^^^^^^^^^^^^^^^ -* On Mac OSX, toplevel windows automatically include a built-in size grip - by default. Adding a Sizegrip there is harmless, since the built-in +* On MacOS X, toplevel windows automatically include a built-in size grip + by default. Adding a :class:`Sizegrip` is harmless, since the built-in grip will just mask the widget. @@ -664,8 +664,8 @@ ^^^^ * If the containing toplevel's position was specified relative to the right - or bottom of the screen (e.g. ....), the Sizegrip widget will not resize - the window. + or bottom of the screen (e.g. ....), the :class:`Sizegrip` widget will + not resize the window. * This widget supports only "southeast" resizing. @@ -678,16 +678,16 @@ label. The order in which data values are displayed may be controlled by setting -the widget option displaycolumns. The tree widget can also display column +the widget option ``displaycolumns``. The tree widget can also display column headings. Columns may be accessed by number or symbolic names listed in the widget option columns. See `Column Identifiers`_. Each item is identified by an unique name. The widget will generate item IDs if they are not supplied by the caller. There is a distinguished root item, -named {}. The root item itself is not displayed; its children appear at the +named ``{}``. The root item itself is not displayed; its children appear at the top level of the hierarchy. -Each item also has a list of tags, which can be used to associate even bindings +Each item also has a list of tags, which can be used to associate event bindings with individual items and control the appearance of the item. The Treeview widget supports horizontal and vertical scrolling, according to @@ -698,7 +698,7 @@ Options ^^^^^^^ -This widget accepts the following specific option: +This widget accepts the following specific options: +----------------+--------------------------------------------------------+ | option | description | @@ -726,8 +726,8 @@ | | be changed. | | | | | | Note that the application code and tag bindings can set| - | | the selection however they wish, regardless the value | - | | of this option. | + | | the selection however they wish, regardless of the | + | | value of this option. | +----------------+--------------------------------------------------------+ | show | A list containing zero or more of the following values,| | | specifying which elements of the tree to display. | @@ -738,7 +738,7 @@ | | The default is "tree headings", i.e., show all | | | elements. | | | | - | | **Note**: Column #0 always refer to the tree column, | + | | **Note**: Column #0 always refers to the tree column, | | | even if show="tree" is not specified. | +----------------+--------------------------------------------------------+ @@ -858,11 +858,11 @@ .. method:: set_children(item, *newchildren) - Replaces item's child with *newchildren*. + Replaces *item*'s child with *newchildren*. - Children present in item that are not present in *newchildren* are - detached from tree. No items in *newchildren* may be an ancestor of - item. Note that not specifying *newchildren* results in detaching + Children present in *item* that are not present in *newchildren* are + detached from the tree. No items in *newchildren* may be an ancestor of + *item*. Note that not specifying *newchildren* results in detaching *item*'s children. @@ -877,16 +877,16 @@ The valid options/values are: * id - Returns the column name, this is a read-only option. + Returns the column name. This is a read-only option. * anchor: One of the standard Tk anchor values. Specifies how the text in this column should be aligned with respect to the cell. * minwidth: width The minimum width of the column in pixels. The treeview widget will - not make the column any smaller than the specified by this option when + not make the column any smaller than specified by this option when the widget is resized or the user drags a column. * stretch: True/False - Specifies wheter or not the column's width should be adjusted when + Specifies whether the column's width should be adjusted when the widget is resized. * width: width The width of the column in pixels. @@ -912,8 +912,7 @@ .. method:: exists(item) - Returns True if the specified *item* is present in the three, - False otherwise. + Returns True if the specified *item* is present in the tree. .. method:: focus([item=None]) @@ -942,7 +941,7 @@ * command: callback A callback to be invoked when the heading label is pressed. - To configure the tree column heading, call this with column = "#0" + To configure the tree column heading, call this with column = "#0". .. method:: identify(component, x, y) @@ -985,7 +984,7 @@ .. method:: identify_element(x, y) - Returns the element at position x, y. + Returns the element at position *x*, *y*. Availability: Tk 8.6. @@ -997,16 +996,16 @@ .. method:: insert(parent, index[, iid=None[, **kw]]) - Creates a new item and return the item identifier of the newly created + Creates a new item and returns the item identifier of the newly created item. *parent* is the item ID of the parent item, or the empty string to create a new top-level item. *index* is an integer, or the value "end", specifying where in the list of parent's children to insert the new item. If *index* is less than or equal to zero, the new node is inserted at - the beginning, if *index* is greater than or equal to the current number + the beginning; if *index* is greater than or equal to the current number of children, it is inserted at the end. If *iid* is specified, it is used - as the item identifier, *iid* must not already exist in the tree. + as the item identifier; *iid* must not already exist in the tree. Otherwise, a new unique identifier is generated. See `Item Options`_ for the list of available points. @@ -1026,9 +1025,9 @@ Moves *item* to position *index* in *parent*'s list of children. - It is illegal to move an item under one of its descendants. If index is - less than or equal to zero, item is moved to the beginning, if greater - than or equal to the number of children, it is moved to the end. If item + It is illegal to move an item under one of its descendants. If *index* is + less than or equal to zero, *item* is moved to the beginning; if greater + than or equal to the number of children, it is moved to the end. If *item* was detached it is reattached. @@ -1101,7 +1100,7 @@ .. method:: tag_bind(tagname[, sequence=None[, callback=None]]) Bind a callback for the given event *sequence* to the tag *tagname*. - When an event is delivered to an item, the *callbacks* for each of the + When an event is delivered to an item, the callbacks for each of the item's tags option are called. @@ -1119,7 +1118,7 @@ If *item* is specified, returns 1 or 0 depending on whether the specified *item* has the given *tagname*. Otherwise, returns a list of all items - which have the specified tag. + that have the specified tag. Availability: Tk 8.6 @@ -1159,7 +1158,7 @@ .. method:: configure(style, query_opt=None, **kw) - Query or sets the default value of the specified option(s) in *style*. + Query or set the default value of the specified option(s) in *style*. Each key in *kw* is an option and each value is a string identifying the value for that option. @@ -1185,10 +1184,10 @@ Query or sets dynamic values of the specified option(s) in *style*. - Each key in kw is an option and each value should be a list or a - tuple (usually) containing statespecs grouped in tuples, or list, or - something else of your preference. A statespec is compound of one or more - states and then a value. + Each key in *kw* is an option and each value should be a list or a + tuple (usually) containing statespecs grouped in tuples, lists, or + something else of your preference. A statespec is a compound of one + or more states and then a value. An example may make it more understandable:: @@ -1208,12 +1207,10 @@ root.mainloop() - There is a thing to note in this previous short example: - - * The order of the (states, value) sequences for an option does matter, - if you changed the order to [('active', 'blue'), ('pressed', 'red')] - in the foreground option, for example, you would get a blue foreground - when the widget were in active or pressed states. + Note that the order of the (states, value) sequences for an option does + matter, if you changed the order to ``[('active', 'blue'), ('pressed', + 'red')]`` in the foreground option, for example, you would get a blue + foreground when the widget were in active or pressed states. .. method:: lookup(style, option[, state=None[, default=None]]) @@ -1236,13 +1233,13 @@ Define the widget layout for given *style*. If *layoutspec* is omitted, return the layout specification for given style. - *layoutspec*, if specified, is expected to be a list, or some other - sequence type (excluding string), where each item should be a tuple and + *layoutspec*, if specified, is expected to be a list or some other + sequence type (excluding strings), where each item should be a tuple and the first item is the layout name and the second item should have the format described described in `Layouts`_. - To understand the format, check this example below (it is not intended - to do anything useful):: + To understand the format, see the following example (it is not + intended to do anything useful):: from tkinter import ttk import tkinter @@ -1268,12 +1265,12 @@ .. method:: element_create(elementname, etype, *args, **kw) - Create a new element in the current theme of given *etype* which is + Create a new element in the current theme, of the given *etype* which is expected to be either "image", "from" or "vsapi". The latter is only available in Tk 8.6a for Windows XP and Vista and is not described here. If "image" is used, *args* should contain the default image name followed - by statespec/value pairs (this is the imagespec), *kw* may have the + by statespec/value pairs (this is the imagespec), and *kw* may have the following options: * border=padding @@ -1296,11 +1293,12 @@ Specifies a minimum width for the element. If less than zero, the base image's width is used as a default. - But if "from" is used, then :meth:`element_create` will clone an existing - element. *args* is expected to contain a themename, which is from where + If "from" is used as the value of *etype*, + :meth:`element_create` will clone an existing + element. *args* is expected to contain a themename, from which the element will be cloned, and optionally an element to clone from. If this element to clone from is not specified, an empty element will - be used. *kw* is discarded here. + be used. *kw* is discarded. .. method:: element_names() @@ -1334,7 +1332,7 @@ :meth:`Style.configure`, :meth:`Style.map`, :meth:`Style.layout` and :meth:`Style.element_create` respectively. - As an example, lets change the Combobox for the default theme a bit:: + As an example, let's change the Combobox for the default theme a bit:: from tkinter import ttk import tkinter @@ -1367,7 +1365,7 @@ .. method:: theme_use([themename]) - If *themename* is not given, returns the theme in use, otherwise, set + If *themename* is not given, returns the theme in use. Otherwise, sets the current theme to *themename*, refreshes all widgets and emits a <> event. @@ -1375,13 +1373,14 @@ Layouts ^^^^^^^ -A layout can be just None, if takes no options, or a dict of options specifying -how to arrange the element. The layout mechanism uses a simplified -version of the pack geometry manager: given an initial cavity, each element is -allocated a parcel. Valid options/values are: +A layout can be just None, if it takes no options, or a dict of +options specifying how to arrange the element. The layout mechanism +uses a simplified version of the pack geometry manager: given an +initial cavity, each element is allocated a parcel. Valid +options/values are: * side: whichside - Specifies which side of the cavity to place the the element; one of + Specifies which side of the cavity to place the element; one of top, right, bottom or left. If omitted, the element occupies the entire cavity. Modified: python/branches/py3k/Doc/library/urllib.request.rst ============================================================================== --- python/branches/py3k/Doc/library/urllib.request.rst (original) +++ python/branches/py3k/Doc/library/urllib.request.rst Sun Apr 5 21:13:16 2009 @@ -40,7 +40,7 @@ commonly used to determine if a redirect was followed * :meth:`info` --- return the meta-information of the page, such as headers, - in the form of an ``http.client.HTTPMessage`` instance (see `Quick + in the form of an :class:`http.client.HTTPMessage` instance (see `Quick Reference to HTTP Headers `_) Raises :exc:`URLError` on errors. Modified: python/branches/py3k/Doc/library/webbrowser.rst ============================================================================== --- python/branches/py3k/Doc/library/webbrowser.rst (original) +++ python/branches/py3k/Doc/library/webbrowser.rst Sun Apr 5 21:13:16 2009 @@ -55,6 +55,10 @@ under many window managers this will occur regardless of the setting of this variable). + Note that on some platforms, trying to open a filename using this function, + may work and start the operating system's associated program. However, this + is neither supported nor portable. + .. function:: open_new(url) Modified: python/branches/py3k/Doc/library/winreg.rst ============================================================================== --- python/branches/py3k/Doc/library/winreg.rst (original) +++ python/branches/py3k/Doc/library/winreg.rst Sun Apr 5 21:13:16 2009 @@ -39,8 +39,8 @@ *key* is the predefined handle to connect to. - The return value is the handle of the opened key. If the function fails, an - :exc:`EnvironmentError` exception is raised. + The return value is the handle of the opened key. If the function fails, a + :exc:`WindowsError` exception is raised. .. function:: CreateKey(key, sub_key) @@ -57,8 +57,8 @@ If the key already exists, this function opens the existing key. - The return value is the handle of the opened key. If the function fails, an - :exc:`EnvironmentError` exception is raised. + The return value is the handle of the opened key. If the function fails, a + :exc:`WindowsError` exception is raised. .. function:: DeleteKey(key, sub_key) @@ -74,7 +74,7 @@ *This method can not delete keys with subkeys.* If the method succeeds, the entire key, including all of its values, is removed. - If the method fails, an :exc:`EnvironmentError` exception is raised. + If the method fails, a :exc:`WindowsError` exception is raised. .. function:: DeleteValue(key, value) @@ -97,7 +97,7 @@ *index* is an integer that identifies the index of the key to retrieve. The function retrieves the name of one subkey each time it is called. It is - typically called repeatedly until an :exc:`EnvironmentError` exception is + typically called repeatedly until a :exc:`WindowsError` exception is raised, indicating, no more values are available. @@ -111,7 +111,7 @@ *index* is an integer that identifies the index of the value to retrieve. The function retrieves the name of one subkey each time it is called. It is - typically called repeatedly, until an :exc:`EnvironmentError` exception is + typically called repeatedly, until a :exc:`WindowsError` exception is raised, indicating no more values. The result is a tuple of 3 items: @@ -199,7 +199,7 @@ The result is a new handle to the specified key. - If the function fails, :exc:`EnvironmentError` is raised. + If the function fails, :exc:`WindowsError` is raised. .. function:: OpenKeyEx() @@ -243,9 +243,10 @@ associated. If this parameter is ``None`` or empty, the function retrieves the value set by the :func:`SetValue` method for the key identified by *key*. - Values in the registry have name, type, and data components. This method + Values in the registry have name, type, and data components. This method retrieves the data for a key's first value that has a NULL name. But the - underlying API call doesn't return the type, Lame Lame Lame, DO NOT USE THIS!!! + underlying API call doesn't return the type, so always use + :func:`QueryValueEx` if possible. .. function:: QueryValueEx(key, value_name) Modified: python/branches/py3k/Doc/reference/datamodel.rst ============================================================================== --- python/branches/py3k/Doc/reference/datamodel.rst (original) +++ python/branches/py3k/Doc/reference/datamodel.rst Sun Apr 5 21:13:16 2009 @@ -59,12 +59,13 @@ they may be garbage-collected. An implementation is allowed to postpone garbage collection or omit it altogether --- it is a matter of implementation quality how garbage collection is implemented, as long as no objects are collected that -are still reachable. (Implementation note: the current implementation uses a +are still reachable. (Implementation note: CPython currently uses a reference-counting scheme with (optional) delayed detection of cyclically linked garbage, which collects most objects as soon as they become unreachable, but is not guaranteed to collect garbage containing circular references. See the documentation of the :mod:`gc` module for information on controlling the -collection of cyclic garbage.) +collection of cyclic garbage. Other implementations act differently and CPython +may change.) Note that the use of the implementation's tracing or debugging facilities may keep objects alive that would normally be collectable. Also note that catching Modified: python/branches/py3k/Doc/tutorial/datastructures.rst ============================================================================== --- python/branches/py3k/Doc/tutorial/datastructures.rst (original) +++ python/branches/py3k/Doc/tutorial/datastructures.rst Sun Apr 5 21:13:16 2009 @@ -347,13 +347,11 @@ >>> x, y, z = t -This is called, appropriately enough, *sequence unpacking*. Sequence unpacking -requires the list of variables on the left to have the same number of elements -as the length of the sequence. Note that multiple assignment is really just a -combination of tuple packing and sequence unpacking! - -There is a small bit of asymmetry here: packing multiple values always creates -a tuple, and unpacking works for any sequence. +This is called, appropriately enough, *sequence unpacking* and works for any +sequence on the right-hand side. Sequence unpacking requires the list of +variables on the left to have the same number of elements as the length of the +sequence. Note that multiple assignment is really just a combination of tuple +packing and sequence unpacking. .. XXX Add a bit on the difference between tuples and lists. Modified: python/branches/py3k/Doc/tutorial/introduction.rst ============================================================================== --- python/branches/py3k/Doc/tutorial/introduction.rst (original) +++ python/branches/py3k/Doc/tutorial/introduction.rst Sun Apr 5 21:13:16 2009 @@ -225,10 +225,9 @@ several lines of text just as you would do in C. Note that whitespace at the beginning of the line is significant. -If we make the string literal a "raw" string, however, the ``\n`` sequences are -not converted to newlines, but the backslash at the end of the line, and the -newline character in the source, are both included in the string as data. Thus, -the example:: +If we make the string literal a "raw" string, ``\n`` sequences are not converted +to newlines, but the backslash at the end of the line, and the newline character +in the source, are both included in the string as data. Thus, the example:: hello = r"This is a rather long string containing\n\ several lines of text much as you would do in C." @@ -240,22 +239,12 @@ This is a rather long string containing\n\ several lines of text much as you would do in C. -Or, strings can be surrounded in a pair of matching triple-quotes: ``"""`` or -``'''``. End of lines do not need to be escaped when using triple-quotes, but -they will be included in the string. :: - - print(""" - Usage: thingy [OPTIONS] - -h Display this usage message - -H hostname Hostname to connect to - """) - -produces the following output:: - - Usage: thingy [OPTIONS] - -h Display this usage message - -H hostname Hostname to connect to - +The interpreter prints the result of string operations in the same way as they +are typed for input: inside quotes, and with quotes and other funny characters +escaped by backslashes, to show the precise value. The string is enclosed in +double quotes if the string contains a single quote and no double quotes, else +it's enclosed in single quotes. (The :func:`print` function, described later, +can be used to write strings without quotes or escapes.) Strings can be concatenated (glued together) with the ``+`` operator, and repeated with ``*``:: Modified: python/branches/py3k/Doc/whatsnew/2.6.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/2.6.rst (original) +++ python/branches/py3k/Doc/whatsnew/2.6.rst Sun Apr 5 21:13:16 2009 @@ -86,8 +86,6 @@ .. ======================================================================== .. Large, PEP-level features and changes should be described here. -.. Should there be a new section here for 3k migration? -.. Or perhaps a more general section describing module changes/deprecation? .. ======================================================================== Python 3.0 @@ -1678,7 +1676,7 @@ :attr:`__self__`, and :attr:`im_func` is also available as :attr:`__func__`. The old names are still supported in Python 2.6, but are gone in 3.0. -* An obscure change: when you use the the :func:`locals` function inside a +* An obscure change: when you use the :func:`locals` function inside a :keyword:`class` statement, the resulting dictionary no longer returns free variables. (Free variables, in this case, are variables referenced in the :keyword:`class` statement that aren't attributes of the class.) Modified: python/branches/py3k/Doc/whatsnew/2.7.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/2.7.rst (original) +++ python/branches/py3k/Doc/whatsnew/2.7.rst Sun Apr 5 21:13:16 2009 @@ -6,7 +6,7 @@ :Release: |release| :Date: |today| -.. Fix accents on Kristjan Valur Jonsson, Fuerstenau. +.. Fix accents on Kristjan Valur Jonsson, Fuerstenau, Tarek Ziade. .. $Id$ Rules for maintenance: @@ -55,12 +55,32 @@ .. Compare with previous release in 2 - 3 sentences here. add hyperlink when the documentation becomes available online. +Python 3.1 +================ + +Much as Python 2.6 incorporated features from Python 3.0, +version 2.7 is influenced by features from 3.1. + +XXX mention importlib; anything else? + +One porting change: the :option:`-3` switch now automatically +enables the :option:`-Qwarn` switch that causes warnings +about using classic division with integers and long integers. + .. ======================================================================== .. Large, PEP-level features and changes should be described here. -.. Should there be a new section here for 3k migration? -.. Or perhaps a more general section describing module changes/deprecation? .. ======================================================================== +PEP 372: Adding an ordered dictionary to collections +==================================================== + +XXX write this + +Several modules will now use :class:`OrderedDict` by default. The +:mod:`ConfigParser` module uses :class:`OrderedDict` for the list +of sections and the options within a section. +The :meth:`namedtuple._asdict` method returns an :class:`OrderedDict` +as well. Other Language Changes @@ -85,6 +105,43 @@ (Contributed by Fredrik Johansson and Victor Stinner; :issue:`3439`.) +* The :class:`bytearray` type's :meth:`translate` method will + now accept None as its first argument. (Fixed by Georg Brandl; + :issue:`4759`.) + +.. ====================================================================== + + +Optimizations +------------- + +Several performance enhancements have been added: + +.. * A new :program:`configure` option, :option:`--with-computed-gotos`, + compiles the main bytecode interpreter loop using a new dispatch + mechanism that gives speedups of up to 20%, depending on the system + and benchmark. The new mechanism is only supported on certain + compilers, such as gcc, SunPro, and icc. + +* The garbage collector now performs better when many objects are + being allocated without deallocating any. A full garbage collection + pass is only performed when the middle generation has been collected + 10 times and when the number of survivor objects from the middle + generation exceeds 10% of the number of objects in the oldest + generation. The second condition was added to reduce the number + of full garbage collections as the number of objects on the heap grows, + avoiding quadratic performance when allocating very many objects. + (Suggested by Martin von Loewis and implemented by Antoine Pitrou; + :issue:`4074`.) + +* The garbage collector tries to avoid tracking simple containers + which can't be part of a cycle. In Python 2.7, this is now true for + tuples and dicts containing atomic types (such as ints, strings, + etc.). Transitively, a dict containing tuples of atomic types won't + be tracked either. This helps reduce the cost of each + garbage collection by decreasing the number of objects to be + considered and traversed by the collector. + (Contributed by Antoine Pitrou; :issue:`4688`.) * Integers are now stored internally either in base 2**15 or in base 2**30, the base being determined at build time. Previously, they @@ -93,7 +150,7 @@ benchmark results on 32-bit machines have been mixed. Therefore, the default is to use base 2**30 on 64-bit machines and base 2**15 on 32-bit machines; on Unix, there's a new configure option - --enable-big-digits that can be used to override this default. + :option:`--enable-big-digits` that can be used to override this default. Apart from the performance improvements this change should be invisible to end users, with one exception: for testing and @@ -106,41 +163,28 @@ >>> sys.long_info sys.long_info(bits_per_digit=30, sizeof_digit=4) - (Contributed by Mark Dickinson; :issue:`4258`.) - -.. ====================================================================== - - -Optimizations -------------- - -A few performance enhancements have been added: - -* The garbage collector now performs better when many objects are - being allocated without deallocating any. A full garbage collection - pass is only performed when the middle generation has been collected - 10 times and when the number of survivor objects from the middle - generation exceeds 10% of the number of objects in the oldest - generation. The second condition was added to reduce the number - of full garbage collections as the number of objects on the heap grows, - avoiding quadratic performance when allocating very many objects. - (Suggested by Martin von Loewis and implemented by Antoine Pitrou; - :issue:`4074`.) - -* The garbage collector tries to avoid tracking simple containers which - can't be part of a cycle. As of now, this is true for tuples and dicts - containing atomic types (such as ints, strings, etc.). Transitively, a dict - containing tuples of atomic types won't be tracked either. This helps bring - down the individual cost of each garbage collection, since it decreases the - number of objects to be considered and traversed by the collector. - - To help diagnosing this optimization, a new function in the :mod:`gc` - module, :func:`is_tracked`, returns True if a given instance is tracked - by the garbage collector, False otherwise. - (Contributed by Antoine Pitrou; :issue:`4688`.) - + Another set of changes made long objects a few bytes smaller: 2 bytes + smaller on 32-bit systems and 6 bytes on 64-bit. + (Contributed by Mark Dickinson; :issue:`5260`.) + +* The division algorithm for long integers has been made faster + by tightening the inner loop, doing shifts instead of multiplications, + and fixing an unnecessary extra iteration. + Various benchmarks show speedups of between 50% and 150% for long + integer divisions and modulo operations. + (Contributed by Mark Dickinson; :issue:`5512`.) + +* The implementation of ``%`` checks for the left-side operand being + a Python string and special-cases it; this results in a 1-3% + performance increase for applications that frequently use ``%`` + with strings, such as templating libraries. + (Implemented by Collin Winter; :issue:`5176`.) + +* List comprehensions with an ``if`` condition are compiled into + faster bytecode. (Patch by Antoine Pitrou, back-ported to 2.7 + by Jeffrey Yasskin; :issue:`4715`.) .. ====================================================================== @@ -153,15 +197,6 @@ :file:`Misc/NEWS` file in the source tree for a more complete list of changes, or look through the Subversion logs for all the details. -* In Distutils, distutils.sdist.add_defaults now uses package_dir and data_files - to feed MANIFEST. - -* It is not mandatory anymore to store clear text passwords in the - :file:`.pypirc` file when registering and uploading packages to PyPI. As long - as the username is present in that file, the :mod:`distutils` package will - prompt for the password if not present. (Added by tarek, with the initial - contribution of Nathan Van Gheem; :issue:`4394`.) - * The :mod:`bz2` module's :class:`BZ2File` now supports the context management protocol, so you can write ``with bz2.BZ2File(...) as f: ...``. (Contributed by Hagen Fuerstenau; :issue:`3860`.) @@ -200,21 +235,100 @@ Contributed by Raymond Hettinger; :issue:`1696199`. + The :class:`namedtuple` class now has an optional *rename* parameter. + If *rename* is True, field names that are invalid because they've + been repeated or that aren't legal Python identifiers will be + renamed to legal names that are derived from the field's + position within the list of fields: + + >>> T=namedtuple('T', ['field1', '$illegal', 'for', 'field2'], rename=True) + >>> T._fields + ('field1', '_1', '_2', 'field2') + + (Added by Raymond Hettinger; :issue:`1818`.) + +* In Distutils, :func:`distutils.sdist.add_defaults` now uses + *package_dir* and *data_files* to create the MANIFEST file. + + It is no longer mandatory to store clear-text passwords in the + :file:`.pypirc` file when registering and uploading packages to PyPI. As long + as the username is present in that file, the :mod:`distutils` package will + prompt for the password if not present. (Added by Tarek Ziade, + based on an initial contribution by Nathan Van Gheem; :issue:`4394`.) + +* New method: the :class:`Decimal` class gained a + :meth:`from_float` class method that performs an exact conversion + of a floating-point number to a :class:`Decimal`. + Note that this is an **exact** conversion that strives for the + closest decimal approximation to the floating-point representation's value; + the resulting decimal value will therefore still include the inaccuracy, + if any. + For example, ``Decimal.from_float(0.1)`` returns + ``Decimal('0.1000000000000000055511151231257827021181583404541015625')``. + (Implemented by Raymond Hettinger; :issue:`4796`.) + +* A new function in the :mod:`gc` module, :func:`is_tracked`, returns + True if a given instance is tracked by the garbage collector, False + otherwise. (Contributed by Antoine Pitrou; :issue:`4688`.) + * The :mod:`gzip` module's :class:`GzipFile` now supports the context management protocol, so you can write ``with gzip.GzipFile(...) as f: ...``. (Contributed by Hagen Fuerstenau; :issue:`3860`.) + It's now possible to override the modification time + recorded in a gzipped file by providing an optional timestamp to + the constructor. (Contributed by Jacques Frechet; :issue:`4272`.) * The :class:`io.FileIO` class now raises an :exc:`OSError` when passed an invalid file descriptor. (Implemented by Benjamin Peterson; :issue:`4991`.) +* New function: ``itertools.compress(*data*, *selectors*)`` takes two + iterators. Elements of *data* are returned if the corresponding + value in *selectors* is True:: + + itertools.compress('ABCDEF', [1,0,1,0,1,1]) => + A, C, E, F + + New function: ``itertools.combinations_with_replacement(*iter*, *r*)`` + returns all the possible *r*-length combinations of elements from the + iterable *iter*. Unlike :func:`combinations`, individual elements + can be repeated in the generated combinations:: + + itertools.combinations_with_replacement('abc', 2) => + ('a', 'a'), ('a', 'b'), ('a', 'c'), + ('b', 'b'), ('b', 'c'), ('c', 'c') + + Note that elements are treated as unique depending on their position + in the input, not their actual values. + + The :class:`itertools.count` function now has a *step* argument that + allows incrementing by values other than 1. :func:`count` also + now allows keyword arguments, and using non-integer values such as + floats or :class:`Decimal` instances. (Implemented by Raymond + Hettinger; :issue:`5032`.) + + :func:`itertools.combinations` and :func:`itertools.product` were + previously raising :exc:`ValueError` for values of *r* larger than + the input iterable. This was deemed a specification error, so they + now return an empty iterator. (Fixed by Raymond Hettinger; :issue:`4816`.) + +* The :mod:`json` module was upgraded to version 2.0.9 of the + simplejson package, which includes a C extension that makes + encoding and decoding faster. + (Contributed by Bob Ippolito; :issue:`4136`.) + + To support the new :class:`OrderedDict` type, :func:`json.load` + now has an optional *object_pairs_hook* parameter that will be called + with any object literal that decodes to a list of pairs. + (Contributed by Raymond Hettinger; :issue:`5381`.) + * The :mod:`pydoc` module now has help for the various symbols that Python uses. You can now do ``help('<<')`` or ``help('@')``, for example. (Contributed by David Laban; :issue:`4739`.) * A new function in the :mod:`subprocess` module, :func:`check_output`, runs a command with a specified set of arguments - and returns the command's output as a string if the command runs without + and returns the command's output as a string when the command runs without error, or raises a :exc:`CalledProcessError` exception otherwise. :: @@ -229,13 +343,41 @@ (Contributed by Gregory P. Smith.) +* The ``sys.version_info`` value is now a named tuple, with attributes + named ``major``, ``minor``, ``micro``, ``releaselevel``, and ``serial``. + (Contributed by Ross Light; :issue:`4285`.) + +* The :mod:`unittest` module was enhanced in several ways. + Test cases can raise the :exc:`SkipTest` exception to skip a test. + (:issue:`1034053`.) + It will now use 'x' for expected failures + and 'u' for unexpected successes when run in its verbose mode. + (Contributed by Benjamin Peterson.) + + The :meth:`assertRaises` and :meth:`failUnlessRaises` methods now + return a context handler when called without providing a callable + object to run. For example, you can write this:: + + with self.assertRaises(KeyError): + raise ValueError + + (Implemented by Antoine Pitrou; :issue:`4444`.) + * The :func:`is_zipfile` function in the :mod:`zipfile` module will now accept a file object, in addition to the path names accepted in earlier versions. (Contributed by Gabriel Genellina; :issue:`4756`.) + :mod:`zipfile` now supports archiving empty directories and + extracts them correctly. (Fixed by Kuba Wieczorek; :issue:`4710`.) + .. ====================================================================== .. whole new modules get described in subsections here +importlib: Importing Modules +------------------------------ + +XXX write this + ttk: Themed Widgets for Tk -------------------------- @@ -266,11 +408,16 @@ debugged doesn't hold the GIL; the macro will now acquire it before printing. (Contributed by Victor Stinner; :issue:`3632`.) -* :cfunc:`Py_AddPendingCall` is now thread safe, letting any +* :cfunc:`Py_AddPendingCall` is now thread-safe, letting any worker thread submit notifications to the main Python thread. This is particularly useful for asynchronous IO operations. (Contributed by Kristjan Valur Jonsson; :issue:`4293`.) +* The :program:`configure` script now checks for floating-point rounding bugs + on certain 32-bit Intel chips and defines a :cmacro:`X87_DOUBLE_ROUNDING` + preprocessor definition. No code currently uses this definition, + but it's available if anyone wishes to use it. + (Added by Mark Dickinson; :issue:`2937`.) .. ====================================================================== @@ -293,6 +440,28 @@ Port-Specific Changes: Mac OS X ----------------------------------- +* The ``/Library/Python/2.7/site-packages`` is now appended to + ``sys.path``, in order to share added packages between the system + installation and a user-installed copy of the same version. + (Changed by Ronald Oussoren; :issue:`4865`.) + + +Other Changes and Fixes +======================= + +* When importing a module from a :file:`.pyc` or :file:`.pyo` file + with an existing :file:`.py` counterpart, the :attr:`co_filename` + attributes of all code objects if the original filename is obsolete, + which can happen if the file has been renamed, moved, or is accessed + through different paths. (Patch by Ziga Seilnacht and Jean-Paul + Calderone; :issue:`1180193`.) + +* The :file:`regrtest.py` script now takes a :option:`--randseed=` + switch that takes an integer that will be used as the random seed + for the :option:`-r` option that executes tests in random order. + The :option:`-r` option also now reports the seed that was used + (Added by Collin Winter.) + .. ====================================================================== Modified: python/branches/py3k/Lib/distutils/cmd.py ============================================================================== --- python/branches/py3k/Lib/distutils/cmd.py (original) +++ python/branches/py3k/Lib/distutils/cmd.py Sun Apr 5 21:13:16 2009 @@ -333,7 +333,8 @@ # -- External world manipulation ----------------------------------- def warn(self, msg): - log.warn("warning: %s: %s\n" % (self.get_command_name(), msg)) + log.warn("warning: %s: %s\n" % + (self.get_command_name(), msg)) def execute(self, func, args, msg=None, level=1): util.execute(func, args, msg, dry_run=self.dry_run) Modified: python/branches/py3k/Lib/distutils/log.py ============================================================================== --- python/branches/py3k/Lib/distutils/log.py (original) +++ python/branches/py3k/Lib/distutils/log.py Sun Apr 5 21:13:16 2009 @@ -18,13 +18,14 @@ def _log(self, level, msg, args): if level >= self.threshold: - if not args: - # msg may contain a '%'. If args is empty, - # don't even try to string-format - print(msg) + if args: + msg = msg % args + if level in (WARN, ERROR, FATAL): + stream = sys.stderr else: - print(msg % args) - sys.stdout.flush() + stream = sys.stdout + stream.write('%s\n' % msg) + stream.flush() def log(self, level, msg, *args): self._log(level, msg, args) Modified: python/branches/py3k/Lib/ftplib.py ============================================================================== --- python/branches/py3k/Lib/ftplib.py (original) +++ python/branches/py3k/Lib/ftplib.py Sun Apr 5 21:13:16 2009 @@ -223,7 +223,7 @@ def voidresp(self): """Expect a response beginning with '2'.""" resp = self.getresp() - if resp[0] != '2': + if resp[:1] != '2': raise error_reply(resp) return resp @@ -522,8 +522,6 @@ resp = self.sendcmd('DELE ' + filename) if resp[:3] in ('250', '200'): return resp - elif resp[:1] == '5': - raise error_perm(resp) else: raise error_reply(resp) Modified: python/branches/py3k/Lib/glob.py ============================================================================== --- python/branches/py3k/Lib/glob.py (original) +++ python/branches/py3k/Lib/glob.py Sun Apr 5 21:13:16 2009 @@ -16,7 +16,7 @@ return list(iglob(pathname)) def iglob(pathname): - """Return a list of paths matching a pathname pattern. + """Return an iterator which yields the paths matching a pathname pattern. The pattern may contain simple shell-style wildcards a la fnmatch. Modified: python/branches/py3k/Lib/optparse.py ============================================================================== --- python/branches/py3k/Lib/optparse.py (original) +++ python/branches/py3k/Lib/optparse.py Sun Apr 5 21:13:16 2009 @@ -11,6 +11,7 @@ __version__ = "1.5.3" __all__ = ['Option', + 'make_option', 'SUPPRESS_HELP', 'SUPPRESS_USAGE', 'Values', Modified: python/branches/py3k/Lib/pdb.py ============================================================================== --- python/branches/py3k/Lib/pdb.py (original) +++ python/branches/py3k/Lib/pdb.py Sun Apr 5 21:13:16 2009 @@ -95,10 +95,14 @@ rcFile.close() self.commands = {} # associates a command list to breakpoint numbers - self.commands_doprompt = {} # for each bp num, tells if the prompt must be disp. after execing the cmd list - self.commands_silent = {} # for each bp num, tells if the stack trace must be disp. after execing the cmd list - self.commands_defining = False # True while in the process of defining a command list - self.commands_bnum = None # The breakpoint number for which we are defining a list + self.commands_doprompt = {} # for each bp num, tells if the prompt + # must be disp. after execing the cmd list + self.commands_silent = {} # for each bp num, tells if the stack trace + # must be disp. after execing the cmd list + self.commands_defining = False # True while in the process of defining + # a command list + self.commands_bnum = None # The breakpoint number for which we are + # defining a list def reset(self): bdb.Bdb.reset(self) @@ -114,6 +118,10 @@ self.forget() self.stack, self.curindex = self.get_stack(f, t) self.curframe = self.stack[self.curindex][0] + # The f_locals dictionary is updated from the actual frame + # locals whenever the .f_locals accessor is called, so we + # cache it here to ensure that modifications are not overwritten. + self.curframe_locals = self.curframe.f_locals self.execRcLines() # Can be executed earlier than 'setup' if desired @@ -192,21 +200,30 @@ self.cmdloop() self.forget() + def displayhook(self, obj): + """Custom displayhook for the exec in default(), which prevents + assignment of the _ variable in the builtins. + """ + print(repr(obj)) + def default(self, line): if line[:1] == '!': line = line[1:] - locals = self.curframe.f_locals + locals = self.curframe_locals globals = self.curframe.f_globals try: code = compile(line + '\n', '', 'single') save_stdout = sys.stdout save_stdin = sys.stdin + save_displayhook = sys.displayhook try: sys.stdin = self.stdin sys.stdout = self.stdout + sys.displayhook = self.displayhook exec(code, globals, locals) finally: sys.stdout = save_stdout sys.stdin = save_stdin + sys.displayhook = save_displayhook except: t, v = sys.exc_info()[:2] if type(t) == type(''): @@ -349,7 +366,7 @@ try: func = eval(arg, self.curframe.f_globals, - self.curframe.f_locals) + self.curframe_locals) except: func = arg try: @@ -597,6 +614,7 @@ else: self.curindex = self.curindex - 1 self.curframe = self.stack[self.curindex][0] + self.curframe_locals = self.curframe.f_locals self.print_stack_entry(self.stack[self.curindex]) self.lineno = None do_u = do_up @@ -607,6 +625,7 @@ else: self.curindex = self.curindex + 1 self.curframe = self.stack[self.curindex][0] + self.curframe_locals = self.curframe.f_locals self.print_stack_entry(self.stack[self.curindex]) self.lineno = None do_d = do_down @@ -670,7 +689,7 @@ def do_debug(self, arg): sys.settrace(None) globals = self.curframe.f_globals - locals = self.curframe.f_locals + locals = self.curframe_locals p = Pdb(self.completekey, self.stdin, self.stdout) p.prompt = "(%s) " % self.prompt.strip() print("ENTERING RECURSIVE DEBUGGER", file=self.stdout) @@ -694,9 +713,8 @@ return 1 def do_args(self, arg): - f = self.curframe - co = f.f_code - dict = f.f_locals + co = self.curframe.f_code + dict = self.curframe_locals n = co.co_argcount if co.co_flags & 4: n = n+1 if co.co_flags & 8: n = n+1 @@ -708,16 +726,15 @@ do_a = do_args def do_retval(self, arg): - if '__return__' in self.curframe.f_locals: - print(self.curframe.f_locals['__return__'], file=self.stdout) + if '__return__' in self.curframe_locals: + print(self.curframe_locals['__return__'], file=self.stdout) else: print('*** Not yet returned!', file=self.stdout) do_rv = do_retval def _getval(self, arg): try: - return eval(arg, self.curframe.f_globals, - self.curframe.f_locals) + return eval(arg, self.curframe.f_globals, self.curframe_locals) except: t, v = sys.exc_info()[:2] if isinstance(t, str): @@ -788,7 +805,7 @@ def do_whatis(self, arg): try: value = eval(arg, self.curframe.f_globals, - self.curframe.f_locals) + self.curframe_locals) except: t, v = sys.exc_info()[:2] if type(t) == type(''): Deleted: python/branches/py3k/Lib/test/README ============================================================================== --- python/branches/py3k/Lib/test/README Sun Apr 5 21:13:16 2009 +++ (empty file) @@ -1,411 +0,0 @@ -+++++++++++++++++++++++++++++++ -Writing Python Regression Tests -+++++++++++++++++++++++++++++++ - -:Author: Skip Montanaro -:Contact: skip at pobox.com - -Introduction -============ - -If you add a new module to Python or modify the functionality of an existing -module, you should write one or more test cases to exercise that new -functionality. There are different ways to do this within the regression -testing facility provided with Python; any particular test should use only -one of these options. Each option requires writing a test module using the -conventions of the selected option: - - - unittest_ based tests - - doctest_ based tests - - "traditional" Python test modules - -Regardless of the mechanics of the testing approach you choose, -you will be writing unit tests (isolated tests of functions and objects -defined by the module) using white box techniques. Unlike black box -testing, where you only have the external interfaces to guide your test case -writing, in white box testing you can see the code being tested and tailor -your test cases to exercise it more completely. In particular, you will be -able to refer to the C and Python code in the CVS repository when writing -your regression test cases. - -.. _unittest: http://www.python.org/doc/current/lib/module-unittest.html -.. _doctest: http://www.python.org/doc/current/lib/module-doctest.html - -unittest-based tests ------------------- -The unittest_ framework is based on the ideas of unit testing as espoused -by Kent Beck and the `Extreme Programming`_ (XP) movement. The specific -interface provided by the framework is tightly based on the JUnit_ -Java implementation of Beck's original SmallTalk test framework. Please -see the documentation of the unittest_ module for detailed information on -the interface and general guidelines on writing unittest-based tests. - -The test_support helper module provides a function for use by -unittest-based tests in the Python regression testing framework, -``run_unittest()``. This is the primary way of running tests in the -standard library. You can pass it any number of the following: - -- classes derived from or instances of ``unittest.TestCase`` or - ``unittest.TestSuite``. These will be handed off to unittest for - converting into a proper TestSuite instance. - -- a string; this must be a key in sys.modules. The module associated with - that string will be scanned by ``unittest.TestLoader.loadTestsFromModule``. - This is usually seen as ``test_support.run_unittest(__name__)`` in a test - module's ``test_main()`` function. This has the advantage of picking up - new tests automatically, without you having to add each new test case - manually. - -All test methods in the Python regression framework have names that -start with "``test_``" and use lower-case names with words separated with -underscores. - -Test methods should *not* have docstrings! The unittest module prints -the docstring if there is one, but otherwise prints the function name -and the full class name. When there's a problem with a test, the -latter information makes it easier to find the source for the test -than the docstring. - -All unittest-based tests in the Python test suite use boilerplate that -looks like this (with minor variations):: - - import unittest - from test import test_support - - class MyTestCase1(unittest.TestCase): - - # Define setUp and tearDown only if needed - - def setUp(self): - unittest.TestCase.setUp(self) - ... additional initialization... - - def tearDown(self): - ... additional finalization... - unittest.TestCase.tearDown(self) - - def test_feature_one(self): - # Testing feature one - ...unit test for feature one... - - def test_feature_two(self): - # Testing feature two - ...unit test for feature two... - - ...etc... - - class MyTestCase2(unittest.TestCase): - ...same structure as MyTestCase1... - - ...etc... - - def test_main(): - test_support.run_unittest(__name__) - - if __name__ == "__main__": - test_main() - -This has the advantage that it allows the unittest module to be used -as a script to run individual tests as well as working well with the -regrtest framework. - -.. _Extreme Programming: http://www.extremeprogramming.org/ -.. _JUnit: http://www.junit.org/ - -doctest based tests -------------------- -Tests written to use doctest_ are actually part of the docstrings for -the module being tested. Each test is written as a display of an -interactive session, including the Python prompts, statements that would -be typed by the user, and the output of those statements (including -tracebacks, although only the exception msg needs to be retained then). -The module in the test package is simply a wrapper that causes doctest -to run over the tests in the module. The test for the difflib module -provides a convenient example:: - - import difflib - from test import test_support - test_support.run_doctest(difflib) - -If the test is successful, nothing is written to stdout (so you should not -create a corresponding output/test_difflib file), but running regrtest -with -v will give a detailed report, the same as if passing -v to doctest. - -A second argument can be passed to run_doctest to tell doctest to search -``sys.argv`` for -v instead of using test_support's idea of verbosity. This -is useful for writing doctest-based tests that aren't simply running a -doctest'ed Lib module, but contain the doctests themselves. Then at -times you may want to run such a test directly as a doctest, independent -of the regrtest framework. The tail end of test_descrtut.py is a good -example:: - - def test_main(verbose=None): - from test import test_support, test_descrtut - test_support.run_doctest(test_descrtut, verbose) - - if __name__ == "__main__": - test_main(1) - -If run via regrtest, ``test_main()`` is called (by regrtest) without -specifying verbose, and then test_support's idea of verbosity is used. But -when run directly, ``test_main(1)`` is called, and then doctest's idea of -verbosity is used. - -See the documentation for the doctest module for information on -writing tests using the doctest framework. - -"traditional" Python test modules ---------------------------------- -The mechanics of how the "traditional" test system operates are fairly -straightforward. When a test case is run, the output is compared with the -expected output that is stored in .../Lib/test/output. If the test runs to -completion and the actual and expected outputs match, the test succeeds, if -not, it fails. If an ``ImportError`` or ``test_support.TestSkipped`` error -is raised, the test is not run. - -Executing Test Cases -==================== -If you are writing test cases for module spam, you need to create a file -in .../Lib/test named test_spam.py. In addition, if the tests are expected -to write to stdout during a successful run, you also need to create an -expected output file in .../Lib/test/output named test_spam ("..." -represents the top-level directory in the Python source tree, the directory -containing the configure script). If needed, generate the initial version -of the test output file by executing:: - - ./python Lib/test/regrtest.py -g test_spam.py - -from the top-level directory. - -Any time you modify test_spam.py you need to generate a new expected -output file. Don't forget to desk check the generated output to make sure -it's really what you expected to find! All in all it's usually better -not to have an expected-out file (note that doctest- and unittest-based -tests do not). - -To run a single test after modifying a module, simply run regrtest.py -without the -g flag:: - - ./python Lib/test/regrtest.py test_spam.py - -While debugging a regression test, you can of course execute it -independently of the regression testing framework and see what it prints:: - - ./python Lib/test/test_spam.py - -To run the entire test suite: - -- [UNIX, + other platforms where "make" works] Make the "test" target at the - top level:: - - make test - -- [WINDOWS] Run rt.bat from your PCBuild directory. Read the comments at - the top of rt.bat for the use of special -d, -O and -q options processed - by rt.bat. - -- [OTHER] You can simply execute the two runs of regrtest (optimized and - non-optimized) directly:: - - ./python Lib/test/regrtest.py - ./python -O Lib/test/regrtest.py - -But note that this way picks up whatever .pyc and .pyo files happen to be -around. The makefile and rt.bat ways run the tests twice, the first time -removing all .pyc and .pyo files from the subtree rooted at Lib/. - -Test cases generate output based upon values computed by the test code. -When executed, regrtest.py compares the actual output generated by executing -the test case with the expected output and reports success or failure. It -stands to reason that if the actual and expected outputs are to match, they -must not contain any machine dependencies. This means your test cases -should not print out absolute machine addresses (e.g. the return value of -the id() builtin function) or floating point numbers with large numbers of -significant digits (unless you understand what you are doing!). - - -Test Case Writing Tips -====================== -Writing good test cases is a skilled task and is too complex to discuss in -detail in this short document. Many books have been written on the subject. -I'll show my age by suggesting that Glenford Myers' `"The Art of Software -Testing"`_, published in 1979, is still the best introduction to the subject -available. It is short (177 pages), easy to read, and discusses the major -elements of software testing, though its publication predates the -object-oriented software revolution, so doesn't cover that subject at all. -Unfortunately, it is very expensive (about $100 new). If you can borrow it -or find it used (around $20), I strongly urge you to pick up a copy. - -The most important goal when writing test cases is to break things. A test -case that doesn't uncover a bug is much less valuable than one that does. -In designing test cases you should pay attention to the following: - - * Your test cases should exercise all the functions and objects defined - in the module, not just the ones meant to be called by users of your - module. This may require you to write test code that uses the module - in ways you don't expect (explicitly calling internal functions, for - example - see test_atexit.py). - - * You should consider any boundary values that may tickle exceptional - conditions (e.g. if you were writing regression tests for division, - you might well want to generate tests with numerators and denominators - at the limits of floating point and integer numbers on the machine - performing the tests as well as a denominator of zero). - - * You should exercise as many paths through the code as possible. This - may not always be possible, but is a goal to strive for. In - particular, when considering if statements (or their equivalent), you - want to create test cases that exercise both the true and false - branches. For loops, you should create test cases that exercise the - loop zero, one and multiple times. - - * You should test with obviously invalid input. If you know that a - function requires an integer input, try calling it with other types of - objects to see how it responds. - - * You should test with obviously out-of-range input. If the domain of a - function is only defined for positive integers, try calling it with a - negative integer. - - * If you are going to fix a bug that wasn't uncovered by an existing - test, try to write a test case that exposes the bug (preferably before - fixing it). - - * If you need to create a temporary file, you can use the filename in - ``test_support.TESTFN`` to do so. It is important to remove the file - when done; other tests should be able to use the name without cleaning - up after your test. - -.. _"The Art of Software Testing": - http://www.amazon.com/exec/obidos/ISBN=0471043281 - -Regression Test Writing Rules -============================= -Each test case is different. There is no "standard" form for a Python -regression test case, though there are some general rules (note that -these mostly apply only to the "classic" tests; unittest_- and doctest_- -based tests should follow the conventions natural to those frameworks):: - - * If your test case detects a failure, raise ``TestFailed`` (found in - ``test.test_support``). - - * Import everything you'll need as early as possible. - - * If you'll be importing objects from a module that is at least - partially platform-dependent, only import those objects you need for - the current test case to avoid spurious ``ImportError`` exceptions - that prevent the test from running to completion. - - * Print all your test case results using the ``print`` statement. For - non-fatal errors, print an error message (or omit a successful - completion print) to indicate the failure, but proceed instead of - raising ``TestFailed``. - - * Use ``assert`` sparingly, if at all. It's usually better to just print - what you got, and rely on regrtest's got-vs-expected comparison to - catch deviations from what you expect. ``assert`` statements aren't - executed at all when regrtest is run in -O mode; and, because they - cause the test to stop immediately, can lead to a long & tedious - test-fix, test-fix, test-fix, ... cycle when things are badly broken - (and note that "badly broken" often includes running the test suite - for the first time on new platforms or under new implementations of - the language). - -Miscellaneous -============= -There is a test_support module in the test package you can import for -your test case. Import this module using either:: - - import test.test_support - -or:: - - from test import test_support - -test_support provides the following useful objects: - - * ``TestFailed`` - raise this exception when your regression test detects - a failure. - - * ``TestSkipped`` - raise this if the test could not be run because the - platform doesn't offer all the required facilities (like large - file support), even if all the required modules are available. - - * ``ResourceDenied`` - this is raised when a test requires a resource that - is not available. Primarily used by 'requires'. - - * ``verbose`` - you can use this variable to control print output. Many - modules use it. Search for "verbose" in the test_*.py files to see - lots of examples. - - * ``forget(module_name)`` - attempts to cause Python to "forget" that it - loaded a module and erase any PYC files. - - * ``is_resource_enabled(resource)`` - Returns a boolean based on whether - the resource is enabled or not. - - * ``requires(resource [, msg])`` - if the required resource is not - available the ResourceDenied exception is raised. - - * ``verify(condition, reason='test failed')``. Use this instead of:: - - assert condition[, reason] - - ``verify()`` has two advantages over ``assert``: it works even in -O - mode, and it raises ``TestFailed`` on failure instead of - ``AssertionError``. - - * ``is_jython`` - true if the interpreter is Jython, false otherwise. - - * ``TESTFN`` - a string that should always be used as the filename when - you need to create a temp file. Also use ``try``/``finally`` to - ensure that your temp files are deleted before your test completes. - Note that you cannot unlink an open file on all operating systems, so - also be sure to close temp files before trying to unlink them. - - * ``sortdict(dict)`` - acts like ``repr(dict.items())``, but sorts the - items first. This is important when printing a dict value, because - the order of items produced by ``dict.items()`` is not defined by the - language. - - * ``findfile(file)`` - you can call this function to locate a file - somewhere along sys.path or in the Lib/test tree - see - test_ossaudiodev.py for an example of its use. - - * ``fcmp(x,y)`` - you can call this function to compare two floating - point numbers when you expect them to only be approximately equal - withing a fuzz factor (``test_support.FUZZ``, which defaults to 1e-6). - - * ``check_syntax_error(testcase, statement)`` - make sure that the - statement is *not* correct Python syntax. - - -Some Non-Obvious regrtest Features -================================== - * Automagic test detection: When you create a new test file - test_spam.py, you do not need to modify regrtest (or anything else) - to advertise its existence. regrtest searches for and runs all - modules in the test directory with names of the form test_xxx.py. - - * Miranda output: If, when running test_spam.py, regrtest does not - find an expected-output file test/output/test_spam, regrtest - pretends that it did find one, containing the single line - - test_spam - - This allows new tests that don't expect to print anything to stdout - to not bother creating expected-output files. - - * Two-stage testing: To run test_spam.py, regrtest imports test_spam - as a module. Most tests run to completion as a side-effect of - getting imported. After importing test_spam, regrtest also executes - ``test_spam.test_main()``, if test_spam has a ``test_main`` attribute. - This is rarely required with the "traditional" Python tests, and - you shouldn't create a module global with name test_main unless - you're specifically exploiting this gimmick. This usage does - prove useful with unittest-based tests as well, however; defining - a ``test_main()`` which is run by regrtest and a script-stub in the - test module ("``if __name__ == '__main__': test_main()``") allows - the test to be used like any other Python test and also work - with the unittest.py-as-a-script approach, allowing a developer - to run specific tests from the command line. Modified: python/branches/py3k/Lib/test/test_pprint.py ============================================================================== --- python/branches/py3k/Lib/test/test_pprint.py (original) +++ python/branches/py3k/Lib/test/test_pprint.py Sun Apr 5 21:13:16 2009 @@ -115,10 +115,10 @@ {}, dict2(), dict3(), verify, pprint, -6, -6, -6-6j, -1.5, "x", b"x", (3,), [3], {3: 6}, - (1,2), [3,4], {5: 6, 7: 8}, + (1,2), [3,4], {5: 6}, tuple2((1,2)), tuple3((1,2)), tuple3(range(100)), [3,4], list2([3,4]), list3([3,4]), list3(range(100)), - {5: 6, 7: 8}, dict2({5: 6}), dict3({5: 6}), + dict2({5: 6}), dict3({5: 6}), range(10, -11, -1) ): native = repr(simple) 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 Sun Apr 5 21:13:16 2009 @@ -225,6 +225,11 @@ sys.setdlopenflags(oldflags) def test_refcount(self): + # n here must be a global in order for this test to pass while + # tracing with a python function. Tracing calls PyFrame_FastToLocals + # which will add a copy of any locals to the frame object, causing + # the reference count to increase by 2 instead of 1. + global n self.assertRaises(TypeError, sys.getrefcount) c = sys.getrefcount(None) n = None Modified: python/branches/py3k/Lib/test/test_threading.py ============================================================================== --- python/branches/py3k/Lib/test/test_threading.py (original) +++ python/branches/py3k/Lib/test/test_threading.py Sun Apr 5 21:13:16 2009 @@ -84,11 +84,24 @@ t.join(NUMTASKS) self.assert_(not t.is_alive()) self.failIfEqual(t.ident, 0) + self.assertFalse(t.ident is None) self.assert_(re.match('', repr(t))) if verbose: print('all tasks done') self.assertEqual(numrunning.get(), 0) + def test_ident_of_no_threading_threads(self): + # The ident still must work for the main thread and dummy threads. + self.assertFalse(threading.currentThread().ident is None) + def f(): + ident.append(threading.currentThread().ident) + done.set() + done = threading.Event() + ident = [] + _thread.start_new_thread(f, ()) + done.wait() + self.assertFalse(ident[0] is None) + # run with a small(ish) thread stack size (256kB) def test_various_ops_small_stack(self): if verbose: @@ -187,7 +200,8 @@ # Now raise an exception in the worker thread. if verbose: print(" waiting for worker thread to get started") - worker_started.wait() + ret = worker_started.wait() + self.assertTrue(ret) if verbose: print(" verifying worker hasn't exited") self.assert_(not t.finished) Modified: python/branches/py3k/Lib/threading.py ============================================================================== --- python/branches/py3k/Lib/threading.py (original) +++ python/branches/py3k/Lib/threading.py Sun Apr 5 21:13:16 2009 @@ -375,6 +375,7 @@ try: if not self._flag: self._cond.wait(timeout) + return self._flag finally: self._cond.release() @@ -450,9 +451,8 @@ raise RuntimeError("thread already started") if __debug__: self._note("%s.start(): starting thread", self) - _active_limbo_lock.acquire() - _limbo[self] = self - _active_limbo_lock.release() + with _active_limbo_lock: + _limbo[self] = self _start_new_thread(self._bootstrap, ()) self._started.wait() @@ -485,14 +485,16 @@ return raise + def _set_ident(self): + self._ident = _get_ident() + def _bootstrap_inner(self): try: - self._ident = _get_ident() + self._set_ident() self._started.set() - _active_limbo_lock.acquire() - _active[self._ident] = self - del _limbo[self] - _active_limbo_lock.release() + with _active_limbo_lock: + _active[self._ident] = self + del _limbo[self] if __debug__: self._note("%s._bootstrap(): thread started", self) @@ -721,9 +723,9 @@ def __init__(self): Thread.__init__(self, name="MainThread") self._started.set() - _active_limbo_lock.acquire() - _active[_get_ident()] = self - _active_limbo_lock.release() + self._set_ident() + with _active_limbo_lock: + _active[self._ident] = self def _set_daemon(self): return False @@ -768,9 +770,9 @@ self._started.set() - _active_limbo_lock.acquire() - _active[_get_ident()] = self - _active_limbo_lock.release() + self._set_ident() + with _active_limbo_lock: + _active[self._ident] = self def _set_daemon(self): return True @@ -791,18 +793,14 @@ currentThread = current_thread def active_count(): - _active_limbo_lock.acquire() - count = len(_active) + len(_limbo) - _active_limbo_lock.release() - return count + with _active_limbo_lock: + return len(_active) + len(_limbo) activeCount = active_count def enumerate(): - _active_limbo_lock.acquire() - active = list(_active.values()) + list(_limbo.values()) - _active_limbo_lock.release() - return active + with _active_limbo_lock: + return list(_active.values()) + list(_limbo.values()) from _thread import stack_size Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Sun Apr 5 21:13:16 2009 @@ -392,6 +392,7 @@ Greg Kochanski Damon Kohler Joseph Koshy +Maksim Kozyarchuk Bob Kras Holger Krekel Michael Kremer Modified: python/branches/py3k/Misc/developers.txt ============================================================================== --- python/branches/py3k/Misc/developers.txt (original) +++ python/branches/py3k/Misc/developers.txt Sun Apr 5 21:13:16 2009 @@ -17,6 +17,18 @@ Permissions History ------------------- +- Paul Kippes was given commit privileges at PyCon 2009 by BAC to work on 3to2. + +- Ron DuPlain was given commit privileges at PyCon 2009 by BAC to work on 3to2. + +- Several developers of alternative Python implementations where + given access for test suite and library adaptions by MvL: + Allison Randal (Parrot), Michael Foord (IronPython), + Jim Baker, Philip Jenvey, and Frank Wierzbicki (all Jython). + +- R. David Murray was given SVN access on March 30 2009 by MvL, after + recommendation by BAC. + - Chris Withers was given SVN access on March 8 2009 by MvL, after recommendation by GvR. @@ -244,10 +256,11 @@ Initials of Project Admins -------------------------- -GvR: Guido van Rossum -NCN: Neal Norwitz -RDH: Raymond Hettinger TGP: Tim Peters +GFB: Georg Brandl +BAC: Brett Cannon +NCN: Neal Norwitz DJG: David Goodger MvL: Martin v. Loewis -GFB: Georg Brandl +GvR: Guido van Rossum +RDH: Raymond Hettinger Modified: python/branches/py3k/Objects/genobject.c ============================================================================== --- python/branches/py3k/Objects/genobject.c (original) +++ python/branches/py3k/Objects/genobject.c Sun Apr 5 21:13:16 2009 @@ -304,7 +304,7 @@ "Return the name of the generator's associated code object."); static PyGetSetDef gen_getsetlist[] = { - {"__name__", (getter)gen_get_name, NULL, NULL, gen__name__doc__}, + {"__name__", (getter)gen_get_name, NULL, gen__name__doc__}, {NULL} }; Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Sun Apr 5 21:13:16 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 70459 . +# From configure.in Revision: 70732 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.1. # @@ -1804,6 +1804,11 @@ +if test "$prefix" != "/"; then + prefix=`echo "$prefix" | sed -e 's/\/$//g'` +fi + + Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Sun Apr 5 21:13:16 2009 @@ -12,6 +12,15 @@ AC_CONFIG_SRCDIR([Include/object.h]) AC_CONFIG_HEADER(pyconfig.h) +dnl Ensure that if prefix is specified, it does not end in a slash. If +dnl it does, we get path names containing '//' which is both ugly and +dnl can cause trouble. + +dnl Last slash shouldn't be stripped if prefix=/ +if test "$prefix" != "/"; then + prefix=`echo "$prefix" | sed -e 's/\/$//g'` +fi + dnl This is for stuff that absolutely must end up in pyconfig.h. dnl Please use pyport.h instead, if possible. AH_TOP([ From python-checkins at python.org Sun Apr 5 21:15:51 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 5 Apr 2009 21:15:51 +0200 (CEST) Subject: [Python-checkins] r71262 - python/branches/py3k Message-ID: <20090405191551.8878E1E4052@bag.python.org> Author: benjamin.peterson Date: Sun Apr 5 21:15:51 2009 New Revision: 71262 Log: Blocked revisions 71253 via svnmerge ........ r71253 | tarek.ziade | 2009-04-05 13:31:24 -0500 (Sun, 05 Apr 2009) | 1 line Fixed 5694: removed spurious test output in Distutils ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sun Apr 5 21:19:32 2009 From: python-checkins at python.org (michael.foord) Date: Sun, 5 Apr 2009 21:19:32 +0200 (CEST) Subject: [Python-checkins] r71263 - in python/trunk: Doc/library/unittest.rst Lib/test/test_unittest.py Lib/unittest.py Misc/NEWS Message-ID: <20090405191932.4A7131E4052@bag.python.org> Author: michael.foord Date: Sun Apr 5 21:19:28 2009 New Revision: 71263 Log: Adding assertIs and assertIsNot methods to unittest.TestCase Issue #2578 Modified: python/trunk/Doc/library/unittest.rst python/trunk/Lib/test/test_unittest.py python/trunk/Lib/unittest.py python/trunk/Misc/NEWS Modified: python/trunk/Doc/library/unittest.rst ============================================================================== --- python/trunk/Doc/library/unittest.rst (original) +++ python/trunk/Doc/library/unittest.rst Sun Apr 5 21:19:28 2009 @@ -859,6 +859,23 @@ .. versionadded:: 2.7 + .. method:: assertIs(expr1, expr2[, msg]) + + This signals a test failure if *expr1* and *expr2* don't evaluate to the same + object. + + .. versionadded:: 2.7 + + + .. method:: assertIsNot(expr1, expr2[, msg]) + + The inverse of the :meth:`assertIs` method. + This signals a test failure if *expr1* and *expr2* evaluate to the same + object. + + .. versionadded:: 2.7 + + .. method:: assertFalse(expr[, msg]) failIf(expr[, msg]) Modified: python/trunk/Lib/test/test_unittest.py ============================================================================== --- python/trunk/Lib/test/test_unittest.py (original) +++ python/trunk/Lib/test/test_unittest.py Sun Apr 5 21:19:28 2009 @@ -2301,6 +2301,16 @@ # from this TestCase instance but since its a local nothing else # will ever notice that. + def testAssertIs(self): + thing = object() + self.assertIs(thing, thing) + self.assertRaises(self.failureException, self.assertIs, thing, object()) + + def testAssertIsNot(self): + thing = object() + self.assertIsNot(thing, object()) + self.assertRaises(self.failureException, self.assertIsNot, thing, thing) + def testAssertIn(self): animals = {'monkey': 'banana', 'cow': 'grass', 'seal': 'fish'} @@ -2444,6 +2454,7 @@ # Test that sequences of unhashable objects can be tested for sameness: self.assertSameElements([[1, 2], [3, 4]], [[3, 4], [1, 2]]) + self.assertSameElements([{'a': 1}, {'b': 2}], [{'b': 2}, {'a': 1}]) self.assertRaises(self.failureException, self.assertSameElements, [[1]], [[2]]) @@ -3016,6 +3027,18 @@ "^unexpectedly None$", "^unexpectedly None : oops$"]) + def testAssertIs(self): + self.assertMessages('assertIs', (None, 'foo'), + ["^None is not 'foo'$", "^oops$", + "^None is not 'foo'$", + "^None is not 'foo' : oops$"]) + + def testAssertIsNot(self): + self.assertMessages('assertIsNot', (None, None), + ["^unexpectedly identical: None$", "^oops$", + "^unexpectedly identical: None$", + "^unexpectedly identical: None : oops$"]) + ###################################################################### ## Main Modified: python/trunk/Lib/unittest.py ============================================================================== --- python/trunk/Lib/unittest.py (original) +++ python/trunk/Lib/unittest.py Sun Apr 5 21:19:28 2009 @@ -806,6 +806,18 @@ standardMsg = '%r unexpectedly found in %r' % (member, container) self.fail(self._formatMessage(msg, standardMsg)) + def assertIs(self, expr1, expr2, msg=None): + """Just like self.assertTrue(a is b), but with a nicer default message.""" + if expr1 is not expr2: + standardMsg = '%r is not %r' % (expr1, expr2) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertIsNot(self, expr1, expr2, msg=None): + """Just like self.assertTrue(a is not b), but with a nicer default message.""" + if expr1 is expr2: + standardMsg = 'unexpectedly identical: %r' % (expr1,) + self.fail(self._formatMessage(msg, standardMsg)) + def assertDictEqual(self, d1, d2, msg=None): self.assert_(isinstance(d1, dict), 'First argument is not a dictionary') self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary') Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Apr 5 21:19:28 2009 @@ -212,6 +212,8 @@ Library ------- +- Issue 5693: TestSuite.__iter__ can now be consistently overridden in subclasses. + - Issue 5694: removed spurious test output in Distutils (test_clean). - Issue 5471: Fix os.path.expanduser() for $HOME set to '/'. From python-checkins at python.org Sun Apr 5 21:44:44 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 5 Apr 2009 21:44:44 +0200 (CEST) Subject: [Python-checkins] r71264 - in python/branches/py3k-short-float-repr: Lib/test/test_float.py Python/dtoa.c Message-ID: <20090405194444.5549F1E4078@bag.python.org> Author: mark.dickinson Date: Sun Apr 5 21:44:44 2009 New Revision: 71264 Log: Second attempted fix for float('.nan'), float('.inf'). Modified: python/branches/py3k-short-float-repr/Lib/test/test_float.py python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Lib/test/test_float.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_float.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_float.py Sun Apr 5 21:44:44 2009 @@ -27,6 +27,7 @@ self.assertRaises(ValueError, float, ".nan") self.assertRaises(ValueError, float, "+.inf") self.assertRaises(ValueError, float, ".") + self.assertRaises(ValueError, float, "-.") self.assertEqual(float(b" \u0663.\u0661\u0664 ".decode('raw-unicode-escape')), 3.14) @support.run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE') Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Sun Apr 5 21:44:44 2009 @@ -1500,6 +1500,10 @@ } } dig_done: + if (!nd && !nz && !nz0 && (s != s0)) { + /* no digits, just a '.'. Fail. */ + goto ret0; + } e = 0; if (c == 'e' || c == 'E') { if (!nd && !nz && !nz0) { From python-checkins at python.org Sun Apr 5 22:07:08 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 5 Apr 2009 22:07:08 +0200 (CEST) Subject: [Python-checkins] r71265 - python/branches/py3k-short-float-repr/Objects/floatobject.c Message-ID: <20090405200708.AFB961E4078@bag.python.org> Author: mark.dickinson Date: Sun Apr 5 22:07:08 2009 New Revision: 71265 Log: Remove useless duplicate call to PyOS_ascii_strtod. Modified: python/branches/py3k-short-float-repr/Objects/floatobject.c Modified: python/branches/py3k-short-float-repr/Objects/floatobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/floatobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/floatobject.c Sun Apr 5 22:07:08 2009 @@ -197,8 +197,7 @@ sp = s; /* We don't care about overflow or underflow. If the platform supports * them, infinities and signed zeroes (on underflow) are fine. - * However, strtod can return 0 for denormalized numbers, where atof - * does not. So (alas!) we special-case a zero result. Note that + * However, strtod can return 0 for denormalized numbers. Note that * whether strtod sets errno on underflow is not defined, so we can't * key off errno. */ @@ -259,14 +258,6 @@ "null byte in argument for float()"); goto error; } - if (x == 0.0) { - /* See above -- may have been strtod being anal - about denorms. */ - PyFPE_START_PROTECT("strtod", goto error) - x = PyOS_ascii_strtod(s, NULL); - PyFPE_END_PROTECT(x) - errno = 0; /* whether atof ever set errno is undefined */ - } result = PyFloat_FromDouble(x); error: if (s_buffer) From python-checkins at python.org Sun Apr 5 22:23:13 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 22:23:13 +0200 (CEST) Subject: [Python-checkins] r71266 - python/trunk/Misc/NEWS Message-ID: <20090405202313.4F5881E4078@bag.python.org> Author: georg.brandl Date: Sun Apr 5 22:23:13 2009 New Revision: 71266 Log: Normalize issue referencing style. Modified: python/trunk/Misc/NEWS Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Apr 5 22:23:13 2009 @@ -70,7 +70,7 @@ - Issue #4978: Passing keyword arguments as unicode strings is now allowed. -- Issue 1242657: the __len__() and __length_hint__() calls in several tools +- Issue #1242657: the __len__() and __length_hint__() calls in several tools were suppressing all exceptions. These include list(), filter(), map(), zip(), and bytearray(). @@ -212,23 +212,23 @@ Library ------- -- Issue 5693: TestSuite.__iter__ can now be consistently overridden in subclasses. +- Issue #5693: TestSuite.__iter__ can now be consistently overridden in subclasses. -- Issue 5694: removed spurious test output in Distutils (test_clean). +- Issue #5694: removed spurious test output in Distutils (test_clean). -- Issue 5471: Fix os.path.expanduser() for $HOME set to '/'. +- Issue #5471: Fix os.path.expanduser() for $HOME set to '/'. -- Issue 1326077: fix the formatting of SyntaxErrors by the traceback module. +- Issue #1326077: fix the formatting of SyntaxErrors by the traceback module. -- Issue 1726172: fix IndexError in the case of and empty response in ftplib. +- Issue #1726172: fix IndexError in the case of and empty response in ftplib. -- Issue 2625: added missing iteritems() call to the for loop in +- Issue #2625: added missing iteritems() call to the for loop in mailbox.MH.get_message(). -- Issue 5585: Add the ability to call an initializer to mulitiprocessing.manager +- Issue #5585: Add the ability to call an initializer to mulitiprocessing.manager so that users can install custonm handlers/etc. -- Issue 3551: Patch multiprocessing to raise a proper exception if the size of the +- Issue #3551: Patch multiprocessing to raise a proper exception if the size of the object when writefile is called causes a ERROR_NO_SYSTEM_RESOURCES. Added docs to note the limitation @@ -445,12 +445,12 @@ inside its source path if it began with the same letters (e.g. "src" vs. "src.new"). -- Issue 4920: Fixed .next() vs .__next__() issues in the ABCs for +- Issue #4920: Fixed .next() vs .__next__() issues in the ABCs for Iterator and MutableSet. - Added the ttk module. See issue #2983: Ttk support for Tkinter. -- Issue 5021: doctest.testfile() did not create __name__ and +- Issue #5021: doctest.testfile() did not create __name__ and collections.namedtuple() relied on __name__ being defined. - Backport importlib from Python 3.1. Only the import_module() function has @@ -464,7 +464,7 @@ - Added a new itertools functions: combinations_with_replacement() and compress(). -- Issue 5032: added a step argument to itertools.count() and +- Issue #5032: added a step argument to itertools.count() and allowed non-integer arguments. - Fix and properly document the multiprocessing module's logging @@ -549,7 +549,7 @@ - Fractions.from_float() no longer loses precision for integers too big to cast as floats. -- Issue 4790: The nsmallest() and nlargest() functions in the heapq module +- Issue #4790: The nsmallest() and nlargest() functions in the heapq module did unnecessary work in the common case where no key function was specified. - Issue #3767: Convert Tk object to string in tkColorChooser. From python-checkins at python.org Sun Apr 5 22:24:31 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 22:24:31 +0200 (CEST) Subject: [Python-checkins] r71267 - python/branches/py3k/Misc/NEWS Message-ID: <20090405202431.5C9EC1E4078@bag.python.org> Author: georg.brandl Date: Sun Apr 5 22:24:29 2009 New Revision: 71267 Log: Normalize issue referencing style. Modified: python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Apr 5 22:24:29 2009 @@ -80,7 +80,7 @@ Library ------- -- Issue 2625: added missing items() call to the for loop in +- Issue #2625: added missing items() call to the for loop in mailbox.MH.get_message(). - Issue #5640: Fix _multibytecodec so that CJK codecs don't repeat @@ -187,7 +187,7 @@ the type definition cmpfunc. The tp_compare slot has been renamed to tp_reserved, and is reserved for future usage. -- Issue 1242657: the __len__() and __length_hint__() calls in several tools +- Issue #1242657: the __len__() and __length_hint__() calls in several tools were suppressing all exceptions. These include list() and bytearray(). - Issue #4707: round(x, n) now returns an integer if x is an integer. @@ -327,9 +327,9 @@ Library ------- -- Issue 5694: removed spurious test output in Distutils (test_clean). +- Issue #5694: removed spurious test output in Distutils (test_clean). -- Issue 1326077: fix the formatting of SyntaxErrors by the traceback module. +- Issue #1326077: fix the formatting of SyntaxErrors by the traceback module. - Issue #1665206 (partially): Move imports in cgitb to the top of the module instead of performing them in functions. Helps prevent import deadlocking in @@ -481,7 +481,7 @@ operator module; use the abstract base classes instead. Also removed the repeat() function; use mul() instead. -- Issue 5021: doctest.testfile() did not create __name__ and +- Issue #5021: doctest.testfile() did not create __name__ and collections.namedtuple() relied on __name__ being defined. - Backport importlib from Python 3.1. Only the import_module() function has @@ -495,7 +495,7 @@ - Added a new itertools functions: combinations_with_replacement() and compress(). -- Issue 5032: added a step argument to itertools.count() and +- Issue #5032: added a step argument to itertools.count() and allowed non-integer arguments. - Fix and properly document the multiprocessing module's logging @@ -582,7 +582,7 @@ - Issue #4812: add missing underscore prefix to some internal-use-only constants in the decimal module. (Dec_0 becomes _Dec_0, etc.) -- Issue 4790: The nsmallest() and nlargest() functions in the heapq module +- Issue #4790: The nsmallest() and nlargest() functions in the heapq module did unnecessary work in the common case where no key function was specified. - Issue #4795: inspect.isgeneratorfunction() returns False instead of None when From buildbot at python.org Sun Apr 5 22:57:11 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 05 Apr 2009 20:57:11 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 3.x Message-ID: <20090405205711.453FF1E4078@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%203.x/builds/685 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From nnorwitz at gmail.com Sun Apr 5 22:00:43 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 5 Apr 2009 16:00:43 -0400 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090405200043.GA15307@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Sun Apr 5 10:00:47 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 5 Apr 2009 04:00:47 -0400 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090405080047.GA12839@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Sun Apr 5 18:30:45 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 5 Apr 2009 12:30:45 -0400 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090405163045.GA14568@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Sun Apr 5 08:20:46 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 5 Apr 2009 01:20:46 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090405062046.GA11994@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Sun Apr 5 14:40:45 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 5 Apr 2009 08:40:45 -0400 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090405124045.GA13761@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Sat Apr 4 19:30:45 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sat, 4 Apr 2009 12:30:45 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090404173045.GA9362@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Sat Apr 4 11:00:47 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sat, 4 Apr 2009 04:00:47 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090404090047.GA1584@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Fri Apr 3 23:00:43 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 3 Apr 2009 16:00:43 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090403210043.GA31157@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Sat Apr 4 15:40:45 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sat, 4 Apr 2009 08:40:45 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090404134045.GA8555@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Sat Apr 4 23:00:43 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sat, 4 Apr 2009 16:00:43 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090404210043.GA10100@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Thu Apr 2 19:30:45 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 2 Apr 2009 12:30:45 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090402173045.GA25277@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Fri Apr 3 19:30:45 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 3 Apr 2009 12:30:45 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090403173045.GA30419@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Sun Apr 5 03:40:43 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sat, 4 Apr 2009 20:40:43 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090405014043.GA11018@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Fri Apr 3 11:00:47 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 3 Apr 2009 04:00:47 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090403090047.GA28725@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Sat Apr 4 08:20:46 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sat, 4 Apr 2009 01:20:46 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090404062046.GA574@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Fri Apr 3 15:40:45 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 3 Apr 2009 08:40:45 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090403134045.GA29612@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Thu Apr 2 08:20:46 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 2 Apr 2009 01:20:46 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090402062046.GA22691@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Thu Apr 2 15:40:45 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 2 Apr 2009 08:40:45 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090402134045.GA24517@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Thu Apr 2 23:00:43 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 2 Apr 2009 16:00:43 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090402210043.GA25975@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Fri Apr 3 03:40:43 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 2 Apr 2009 20:40:43 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090403014043.GA26841@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Sat Apr 4 03:40:43 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 3 Apr 2009 20:40:43 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090404014043.GA32074@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Fri Apr 3 08:20:46 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 3 Apr 2009 01:20:46 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090403062046.GA27760@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Wed Apr 1 11:00:47 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 1 Apr 2009 04:00:47 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090401090047.GA18581@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Thu Apr 2 11:00:48 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 2 Apr 2009 04:00:48 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090402090048.GA23650@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Thu Apr 2 03:40:43 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 1 Apr 2009 20:40:43 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090402014043.GA21774@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Wed Apr 1 08:20:46 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 1 Apr 2009 01:20:46 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090401062046.GA17617@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Wed Apr 1 19:30:45 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 1 Apr 2009 12:30:45 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090401173045.GA20210@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Wed Apr 1 23:00:43 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 1 Apr 2009 16:00:43 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090401210043.GA20908@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Wed Apr 1 03:40:43 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 31 Mar 2009 20:40:43 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090401014043.GA16700@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From nnorwitz at gmail.com Wed Apr 1 15:40:45 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 1 Apr 2009 08:40:45 -0500 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090401134045.GA19450@python.psfb.org> svn update tools/sphinx svn: PROPFIND request failed on '/projects/doctools/trunk/sphinx' svn: PROPFIND of '/projects/doctools/trunk/sphinx': Could not resolve hostname `svn.python.org': Host not found (http://svn.python.org) make: *** [update] Error 1 From python-checkins at python.org Sun Apr 5 23:00:49 2009 From: python-checkins at python.org (matthias.klose) Date: Sun, 5 Apr 2009 23:00:49 +0200 (CEST) Subject: [Python-checkins] r71268 - in python/trunk: Lib/SimpleXMLRPCServer.py Misc/NEWS Message-ID: <20090405210049.11BFF1E42DB@bag.python.org> Author: matthias.klose Date: Sun Apr 5 23:00:48 2009 New Revision: 71268 Log: - Issue #2703: SimpleXMLRPCDispatcher.__init__: Provide default values for new arguments introduced in 2.5. Modified: python/trunk/Lib/SimpleXMLRPCServer.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/SimpleXMLRPCServer.py ============================================================================== --- python/trunk/Lib/SimpleXMLRPCServer.py (original) +++ python/trunk/Lib/SimpleXMLRPCServer.py Sun Apr 5 23:00:48 2009 @@ -164,7 +164,7 @@ reason to instantiate this class directly. """ - def __init__(self, allow_none, encoding): + def __init__(self, allow_none=False, encoding=None): self.funcs = {} self.instance = None self.allow_none = allow_none Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Apr 5 23:00:48 2009 @@ -689,6 +689,9 @@ - Issue #999042: The Python compiler now handles explict global statements correctly (should be assigned using STORE_GLOBAL opcode). +- Issue #2703: SimpleXMLRPCDispatcher.__init__: Provide default values for + new arguments introduced in 2.5. + Tools/Demos ----------- From python-checkins at python.org Sun Apr 5 23:06:02 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 5 Apr 2009 23:06:02 +0200 (CEST) Subject: [Python-checkins] r71269 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090405210602.796B11E4078@bag.python.org> Author: mark.dickinson Date: Sun Apr 5 23:06:02 2009 New Revision: 71269 Log: Treat Avoid_Underflow as always #defined Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Sun Apr 5 23:06:02 2009 @@ -903,30 +903,8 @@ U u; L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; -#ifndef Avoid_Underflow -#ifndef Sudden_Underflow - if (L > 0) { -#endif -#endif word0(&u) = L; word1(&u) = 0; -#ifndef Avoid_Underflow -#ifndef Sudden_Underflow - } - else { - L = -L >> Exp_shift; - if (L < Exp_shift) { - word0(&u) = 0x80000 >> L; - word1(&u) = 0; - } - else { - word0(&u) = 0; - L -= Exp_shift; - word1(&u) = L >= 31 ? 1 : 1 << 31 - L; - } - } -#endif -#endif return dval(&u); } @@ -1064,12 +1042,8 @@ static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, -#ifdef Avoid_Underflow 9007199254740992.*9007199254740992.e-256 /* = 2^106 * 1e-256 */ -#else - 1e-256 -#endif }; /* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ /* flag unnecessarily. It leads to a song and dance at the end of strtod. */ @@ -1238,11 +1212,7 @@ return -1; p2 = Emin - P + 1; bbits = 1; -#ifdef Avoid_Underflow word0(rv) = (P+2) << Exp_shift; -#else - word1(rv) = 1; -#endif i = 0; { speccase = 1; @@ -1258,9 +1228,7 @@ if (b == NULL) return -1; } -#ifdef Avoid_Underflow p2 -= bc->scale; -#endif /* floor(log2(rv)) == bbits - 1 + p2 */ /* Check for denormal case. */ i = P - bbits; @@ -1272,11 +1240,7 @@ return -1; p2 = Emin; i = P - 1; -#ifdef Avoid_Underflow word0(rv) = (1 + bc->scale) << Exp_shift; -#else - word0(rv) = Exp_msk1; -#endif word1(rv) = 0; #else i = j; @@ -1615,9 +1579,7 @@ } e1 += nd - k; -#ifdef Avoid_Underflow bc.scale = 0; -#endif /* Get starting approximation = rv * 10**e1 */ @@ -1660,7 +1622,6 @@ if (e1 >>= 4) { if (e1 >= 1 << n_bigtens) goto undfl; -#ifdef Avoid_Underflow if (e1 & Scale_Bit) bc.scale = 2*P; for(j = 0; e1 > 0; j++, e1 >>= 1) @@ -1679,31 +1640,12 @@ else word1(&rv) &= 0xffffffff << j; } -#else - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - dval(&rv) *= tinytens[j]; - /* The last multiplication could underflow. */ - dval(&rv0) = dval(&rv); - dval(&rv) *= tinytens[j]; - if (!dval(&rv)) { - dval(&rv) = 2.*dval(&rv0); - dval(&rv) *= tinytens[j]; -#endif if (!dval(&rv)) { undfl: dval(&rv) = 0.; errno = ERANGE; goto ret; } -#ifndef Avoid_Underflow - word0(&rv) = Tiny0; - word1(&rv) = Tiny1; - /* The refinement below will clean - * this approximation up. - */ - } -#endif } } @@ -1762,30 +1704,15 @@ else bd2 -= bbe; bs2 = bb2; -#ifdef Avoid_Underflow j = bbe - bc.scale; i = j + bbbits - 1; /* logb(rv) */ if (i < Emin) /* denormal */ j += P - Emin; else j = P + 1 - bbbits; -#else /*Avoid_Underflow*/ -#ifdef Sudden_Underflow - j = P + 1 - bbbits; -#else /*Sudden_Underflow*/ - j = bbe; - i = j + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j += P - Emin; - else - j = P + 1 - bbbits; -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ bb2 += j; bd2 += j; -#ifdef Avoid_Underflow bd2 += bc.scale; -#endif i = bb2 < bd2 ? bb2 : bd2; if (i > bs2) i = bs2; @@ -1826,11 +1753,7 @@ * special case of mantissa a power of two. */ if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask -#ifdef Avoid_Underflow || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1 -#else - || (word0(&rv) & Exp_mask) <= Exp_msk1 -#endif ) { break; } @@ -1848,19 +1771,15 @@ if (bc.dsign) { if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 && word1(&rv) == ( -#ifdef Avoid_Underflow (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : -#endif 0xffffffff)) { /*boundary case -- increment exponent*/ word0(&rv) = (word0(&rv) & Exp_mask) + Exp_msk1 ; word1(&rv) = 0; -#ifdef Avoid_Underflow bc.dsign = 0; -#endif break; } } @@ -1869,11 +1788,7 @@ /* boundary case -- decrement exponent */ #ifdef Sudden_Underflow /*{{*/ L = word0(&rv) & Exp_mask; -#ifdef Avoid_Underflow if (L <= (bc.scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) -#else - if (L <= Exp_msk1) -#endif /*Avoid_Underflow*/ { if (bc.nd >nd) { bc.uflchk = 1; @@ -1883,7 +1798,6 @@ } L -= Exp_msk1; #else /*Sudden_Underflow}{*/ -#ifdef Avoid_Underflow if (bc.scale) { L = word0(&rv) & Exp_mask; if (L <= (2*P+1)*Exp_msk1) { @@ -1899,7 +1813,6 @@ goto undfl; } } -#endif /*Avoid_Underflow*/ L = (word0(&rv) & Exp_mask) - Exp_msk1; #endif /*Sudden_Underflow}}*/ word0(&rv) = L | Bndry_mask1; @@ -1922,9 +1835,7 @@ } #endif } -#ifdef Avoid_Underflow bc.dsign = 1 - bc.dsign; -#endif break; } if ((aadj = ratio(delta, bs)) <= 2.) { @@ -1992,7 +1903,6 @@ word0(&rv) += P*Exp_msk1; } else { -#ifdef Avoid_Underflow if (bc.scale && y <= 2*P*Exp_msk1) { if (aadj <= 0x7fffffff) { if ((z = aadj) <= 0) @@ -2006,57 +1916,10 @@ } adj.d = aadj1 * ulp(&rv); dval(&rv) += adj.d; -#else -#ifdef Sudden_Underflow - if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { - dval(&rv0) = dval(&rv); - word0(&rv) += P*Exp_msk1; - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; - if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) - { - if (word0(&rv0) == Tiny0 - && word1(&rv0) == Tiny1) { - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } - goto undfl; - } - word0(&rv) = Tiny0; - word1(&rv) = Tiny1; - goto cont; - } - else - word0(&rv) -= P*Exp_msk1; - } - else { - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; - } -#else /*Sudden_Underflow*/ - /* Compute adj so that the IEEE rounding rules will - * correctly round rv + adj in some half-way cases. - * If rv * ulp(rv) is denormalized (i.e., - * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid - * trouble from bits lost to denormalization; - * example: 1.2e-307 . - */ - if (y <= (P-1)*Exp_msk1 && aadj > 1.) { - aadj1 = (double)(int)(aadj + 0.5); - if (!bc.dsign) - aadj1 = -aadj1; - } - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ } z = word0(&rv) & Exp_mask; if (bc.nd == nd) { -#ifdef Avoid_Underflow if (!bc.scale) -#endif if (y == z) { /* Can we stop now? */ L = (Long)aadj; @@ -2083,7 +1946,6 @@ Bfree(delta); if (bc.nd > nd) bigcomp(&rv, s0, &bc); -#ifdef Avoid_Underflow if (bc.scale) { word0(&rv0) = Exp_1 - 2*P*Exp_msk1; word1(&rv0) = 0; @@ -2092,7 +1954,6 @@ if (!(word0(&rv) & Exp_mask)) errno = ERANGE; } -#endif /* Avoid_Underflow */ ret: if (se) *se = (char *)s; From buildbot at python.org Sun Apr 5 23:11:00 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 05 Apr 2009 21:11:00 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 3.x Message-ID: <20090405211100.7C5A81E4078@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%20gentoo%203.x/builds/588 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-amd64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_multiprocessing ====================================================================== FAIL: test_event (test.test_multiprocessing.WithThreadsTestEvent) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_multiprocessing.py", line 755, in test_event self.assertEqual(wait(0.0), None) AssertionError: False != None ====================================================================== FAIL: test_event (test.test_multiprocessing.WithManagerTestEvent) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/3.x.norwitz-amd64/build/Lib/test/test_multiprocessing.py", line 755, in test_event self.assertEqual(wait(0.0), None) AssertionError: False != None make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sun Apr 5 23:11:46 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 23:11:46 +0200 (CEST) Subject: [Python-checkins] r71270 - in python/branches/release26-maint: Doc/c-api/long.rst Doc/c-api/object.rst Doc/c-api/veryhigh.rst Doc/distutils/index.rst Doc/documenting/index.rst Doc/extending/extending.rst Doc/extending/index.rst Doc/glossary.rst Doc/howto/regex.rst Doc/library/_winreg.rst Doc/library/abc.rst Doc/library/functions.rst Doc/library/index.rst Doc/library/os.rst Doc/library/re.rst Doc/library/stdtypes.rst Doc/library/sys.rst Doc/reference/datamodel.rst Doc/reference/index.rst Doc/reference/simple_stmts.rst Doc/tutorial/index.rst Doc/using/index.rst Lib/distutils/version.py Objects/genobject.c Tools/scripts/reindent-rst.py Message-ID: <20090405211146.8BB9E1E4078@bag.python.org> Author: georg.brandl Date: Sun Apr 5 23:11:43 2009 New Revision: 71270 Log: Merged revisions 70642,70648,70656,70661,70765,70773,70789,70824-70825,70828,70830,70832,70836,70838,70842,70851,70855,70857-70858 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70642 | georg.brandl | 2009-03-28 01:48:48 +0100 (Sa, 28 M?r 2009) | 1 line Fix typo. ........ r70648 | georg.brandl | 2009-03-28 20:10:37 +0100 (Sa, 28 M?r 2009) | 1 line #5324: document __subclasses__(). ........ r70656 | georg.brandl | 2009-03-28 20:33:33 +0100 (Sa, 28 M?r 2009) | 2 lines Add a script to fixup rst files if the pre-commit hook rejects them. ........ r70661 | georg.brandl | 2009-03-28 20:57:36 +0100 (Sa, 28 M?r 2009) | 2 lines Add section numbering to some of the larger subdocuments. ........ r70765 | georg.brandl | 2009-03-31 00:09:34 +0200 (Di, 31 M?r 2009) | 1 line #5199: make warning about vars() assignment more visible. ........ r70773 | georg.brandl | 2009-03-31 00:43:00 +0200 (Di, 31 M?r 2009) | 1 line #5039: make it clear that the impl. note refers to CPython. ........ r70789 | georg.brandl | 2009-03-31 03:25:15 +0200 (Di, 31 M?r 2009) | 1 line Fix a wrong struct field assignment (docstring as closure). ........ r70824 | georg.brandl | 2009-03-31 17:43:20 +0200 (Di, 31 M?r 2009) | 1 line #5519: remove reference to Kodos, which seems dead. ........ r70825 | georg.brandl | 2009-03-31 17:46:30 +0200 (Di, 31 M?r 2009) | 1 line #5566: fix versionadded from PyLong ssize_t functions. ........ r70828 | georg.brandl | 2009-03-31 17:50:16 +0200 (Di, 31 M?r 2009) | 1 line #5581: fget argument of abstractproperty is optional as well. ........ r70830 | georg.brandl | 2009-03-31 18:11:45 +0200 (Di, 31 M?r 2009) | 1 line #5529: backport new docs of import semantics written by Brett to 2.x. ........ r70832 | georg.brandl | 2009-03-31 18:31:11 +0200 (Di, 31 M?r 2009) | 1 line #1386675: specify WindowsError as the exception, because it has a winerror attribute that EnvironmentError doesnt have. ........ r70836 | georg.brandl | 2009-03-31 18:50:25 +0200 (Di, 31 M?r 2009) | 1 line #5417: replace references to undocumented functions by ones to documented functions. ........ r70838 | georg.brandl | 2009-03-31 18:54:38 +0200 (Di, 31 M?r 2009) | 1 line #992207: document that the parser only accepts \\n newlines. ........ r70842 | georg.brandl | 2009-03-31 19:13:06 +0200 (Di, 31 M?r 2009) | 1 line #970783: document PyObject_Generic[GS]etAttr. ........ r70851 | georg.brandl | 2009-03-31 20:26:55 +0200 (Di, 31 M?r 2009) | 1 line #837577: note cryptic return value of spawn*e on invalid env dicts. ........ r70855 | georg.brandl | 2009-03-31 20:30:37 +0200 (Di, 31 M?r 2009) | 1 line #5245: note that PyRun_SimpleString doesnt return on SystemExit. ........ r70857 | georg.brandl | 2009-03-31 20:33:10 +0200 (Di, 31 M?r 2009) | 1 line #5227: note that Py_Main doesnt return on SystemExit. ........ r70858 | georg.brandl | 2009-03-31 20:38:56 +0200 (Di, 31 M?r 2009) | 1 line #5241: document missing U in regex howto. ........ Added: python/branches/release26-maint/Tools/scripts/reindent-rst.py - copied unchanged from r70656, /python/trunk/Tools/scripts/reindent-rst.py Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/c-api/long.rst python/branches/release26-maint/Doc/c-api/object.rst python/branches/release26-maint/Doc/c-api/veryhigh.rst python/branches/release26-maint/Doc/distutils/index.rst python/branches/release26-maint/Doc/documenting/index.rst python/branches/release26-maint/Doc/extending/extending.rst python/branches/release26-maint/Doc/extending/index.rst python/branches/release26-maint/Doc/glossary.rst python/branches/release26-maint/Doc/howto/regex.rst python/branches/release26-maint/Doc/library/_winreg.rst python/branches/release26-maint/Doc/library/abc.rst python/branches/release26-maint/Doc/library/functions.rst python/branches/release26-maint/Doc/library/index.rst python/branches/release26-maint/Doc/library/os.rst python/branches/release26-maint/Doc/library/re.rst python/branches/release26-maint/Doc/library/stdtypes.rst python/branches/release26-maint/Doc/library/sys.rst python/branches/release26-maint/Doc/reference/datamodel.rst python/branches/release26-maint/Doc/reference/index.rst python/branches/release26-maint/Doc/reference/simple_stmts.rst python/branches/release26-maint/Doc/tutorial/index.rst python/branches/release26-maint/Doc/using/index.rst python/branches/release26-maint/Lib/distutils/version.py python/branches/release26-maint/Objects/genobject.c Modified: python/branches/release26-maint/Doc/c-api/long.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/long.rst (original) +++ python/branches/release26-maint/Doc/c-api/long.rst Sun Apr 5 23:11:43 2009 @@ -54,7 +54,7 @@ Return a new :ctype:`PyLongObject` object from a C :ctype:`Py_ssize_t`, or *NULL* on failure. - .. versionadded:: 2.5 + .. versionadded:: 2.6 .. cfunction:: PyObject* PyLong_FromSize_t(size_t v) @@ -62,7 +62,7 @@ Return a new :ctype:`PyLongObject` object from a C :ctype:`size_t`, or *NULL* on failure. - .. versionadded:: 2.5 + .. versionadded:: 2.6 .. cfunction:: PyObject* PyLong_FromLongLong(PY_LONG_LONG v) @@ -139,7 +139,7 @@ *pylong* is greater than :const:`PY_SSIZE_T_MAX`, an :exc:`OverflowError` is raised and ``-1`` will be returned. - .. versionadded:: 2.5 + .. versionadded:: 2.6 .. cfunction:: unsigned long PyLong_AsUnsignedLong(PyObject *pylong) Modified: python/branches/release26-maint/Doc/c-api/object.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/object.rst (original) +++ python/branches/release26-maint/Doc/c-api/object.rst Sun Apr 5 23:11:43 2009 @@ -42,6 +42,16 @@ expression ``o.attr_name``. +.. cfunction:: PyObject* PyObject_GenericGetAttr(PyObject *o, PyObject *name) + + Generic attribute getter function that is meant to be put into a type + object's ``tp_getattro`` slot. It looks for a descriptor in the dictionary + of classes in the object's MRO as well as an attribute in the object's + :attr:`__dict__` (if present). As outlined in :ref:`descriptors`, data + descriptors take preference over instance attributes, while non-data + descriptors don't. Otherwise, an :exc:`AttributeError` is raised. + + .. cfunction:: int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v) Set the value of the attribute named *attr_name*, for object *o*, to the value @@ -56,6 +66,17 @@ ``o.attr_name = v``. +.. cfunction:: int PyObject_GenericSetAttr(PyObject *o, PyObject *name, PyObject +*value) + + Generic attribute setter function that is meant to be put into a type + object's ``tp_setattro`` slot. It looks for a data descriptor in the + dictionary of classes in the object's MRO, and if found it takes preference + over setting the attribute in the instance dictionary. Otherwise, the + attribute is set in the object's :attr:`__dict__` (if present). Otherwise, + an :exc:`AttributeError` is raised and ``-1`` is returned. + + .. cfunction:: int PyObject_DelAttr(PyObject *o, PyObject *attr_name) Delete attribute named *attr_name*, for object *o*. Returns ``-1`` on failure. Modified: python/branches/release26-maint/Doc/c-api/veryhigh.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/veryhigh.rst (original) +++ python/branches/release26-maint/Doc/c-api/veryhigh.rst Sun Apr 5 23:11:43 2009 @@ -36,6 +36,10 @@ interpreter exits due to an exception, or ``2`` if the parameter list does not represent a valid Python command line. + Note that if an otherwise unhandled :exc:`SystemError` is raised, this + function will not return ``1``, but exit the process, as long as + ``Py_InspectFlag`` is not set. + .. cfunction:: int PyRun_AnyFile(FILE *fp, const char *filename) @@ -78,6 +82,10 @@ there was an error, there is no way to get the exception information. For the meaning of *flags*, see below. + Note that if an otherwise unhandled :exc:`SystemError` is raised, this + function will not return ``-1``, but exit the process, as long as + ``Py_InspectFlag`` is not set. + .. cfunction:: int PyRun_SimpleFile(FILE *fp, const char *filename) Modified: python/branches/release26-maint/Doc/distutils/index.rst ============================================================================== --- python/branches/release26-maint/Doc/distutils/index.rst (original) +++ python/branches/release26-maint/Doc/distutils/index.rst Sun Apr 5 23:11:43 2009 @@ -16,6 +16,7 @@ .. toctree:: :maxdepth: 2 + :numbered: introduction.rst setupscript.rst Modified: python/branches/release26-maint/Doc/documenting/index.rst ============================================================================== --- python/branches/release26-maint/Doc/documenting/index.rst (original) +++ python/branches/release26-maint/Doc/documenting/index.rst Sun Apr 5 23:11:43 2009 @@ -23,6 +23,7 @@ are more than welcome as well. .. toctree:: + :numbered: intro.rst style.rst Modified: python/branches/release26-maint/Doc/extending/extending.rst ============================================================================== --- python/branches/release26-maint/Doc/extending/extending.rst (original) +++ python/branches/release26-maint/Doc/extending/extending.rst Sun Apr 5 23:11:43 2009 @@ -465,10 +465,10 @@ (but note that *temp* will not be *NULL* in this context). More info on them in section :ref:`refcounts`. -.. index:: single: PyEval_CallObject() +.. index:: single: PyObject_CallObject() Later, when it is time to call the function, you call the C function -:cfunc:`PyEval_CallObject`. This function has two arguments, both pointers to +:cfunc:`PyObject_CallObject`. This function has two arguments, both pointers to arbitrary Python objects: the Python function, and the argument list. The argument list must always be a tuple object, whose length is the number of arguments. To call the Python function with no arguments, pass in NULL, or @@ -484,16 +484,16 @@ ... /* Time to call the callback */ arglist = Py_BuildValue("(i)", arg); - result = PyEval_CallObject(my_callback, arglist); + result = PyObject_CallObject(my_callback, arglist); Py_DECREF(arglist); -:cfunc:`PyEval_CallObject` returns a Python object pointer: this is the return -value of the Python function. :cfunc:`PyEval_CallObject` is +:cfunc:`PyObject_CallObject` returns a Python object pointer: this is the return +value of the Python function. :cfunc:`PyObject_CallObject` is "reference-count-neutral" with respect to its arguments. In the example a new tuple was created to serve as the argument list, which is :cfunc:`Py_DECREF`\ -ed immediately after the call. -The return value of :cfunc:`PyEval_CallObject` is "new": either it is a brand +The return value of :cfunc:`PyObject_CallObject` is "new": either it is a brand new object, or it is an existing object whose reference count has been incremented. So, unless you want to save it in a global variable, you should somehow :cfunc:`Py_DECREF` the result, even (especially!) if you are not @@ -501,7 +501,7 @@ Before you do this, however, it is important to check that the return value isn't *NULL*. If it is, the Python function terminated by raising an exception. -If the C code that called :cfunc:`PyEval_CallObject` is called from Python, it +If the C code that called :cfunc:`PyObject_CallObject` is called from Python, it should now return an error indication to its Python caller, so the interpreter can print a stack trace, or the calling Python code can handle the exception. If this is not possible or desirable, the exception should be cleared by calling @@ -513,7 +513,7 @@ Py_DECREF(result); Depending on the desired interface to the Python callback function, you may also -have to provide an argument list to :cfunc:`PyEval_CallObject`. In some cases +have to provide an argument list to :cfunc:`PyObject_CallObject`. In some cases the argument list is also provided by the Python program, through the same interface that specified the callback function. It can then be saved and used in the same manner as the function object. In other cases, you may have to @@ -524,7 +524,7 @@ PyObject *arglist; ... arglist = Py_BuildValue("(l)", eventcode); - result = PyEval_CallObject(my_callback, arglist); + result = PyObject_CallObject(my_callback, arglist); Py_DECREF(arglist); if (result == NULL) return NULL; /* Pass error back */ @@ -536,19 +536,20 @@ :cfunc:`Py_BuildValue` may run out of memory, and this should be checked. You may also call a function with keyword arguments by using -:cfunc:`PyEval_CallObjectWithKeywords`. As in the above example, we use -:cfunc:`Py_BuildValue` to construct the dictionary. :: +:cfunc:`PyObject_Call`, which supports arguments and keyword arguments. As in +the above example, we use :cfunc:`Py_BuildValue` to construct the dictionary. :: PyObject *dict; ... dict = Py_BuildValue("{s:i}", "name", val); - result = PyEval_CallObjectWithKeywords(my_callback, NULL, dict); + result = PyObject_Call(my_callback, NULL, dict); Py_DECREF(dict); if (result == NULL) return NULL; /* Pass error back */ /* Here maybe use the result */ Py_DECREF(result); + .. _parsetuple: Extracting Parameters in Extension Functions Modified: python/branches/release26-maint/Doc/extending/index.rst ============================================================================== --- python/branches/release26-maint/Doc/extending/index.rst (original) +++ python/branches/release26-maint/Doc/extending/index.rst Sun Apr 5 23:11:43 2009 @@ -26,6 +26,7 @@ .. toctree:: :maxdepth: 2 + :numbered: extending.rst newtypes.rst Modified: python/branches/release26-maint/Doc/glossary.rst ============================================================================== --- python/branches/release26-maint/Doc/glossary.rst (original) +++ python/branches/release26-maint/Doc/glossary.rst Sun Apr 5 23:11:43 2009 @@ -185,6 +185,11 @@ A module written in C or C++, using Python's C API to interact with the core and with user code. + finder + An object that tries to find the :term:`loader` for a module. It must + implement a method named :meth:`find_module`. See :pep:`302` for + details. + function A series of statements which returns some value to a caller. It can also be passed zero or more arguments which may be used in the execution of @@ -288,6 +293,10 @@ fraction. Integer division can be forced by using the ``//`` operator instead of the ``/`` operator. See also :term:`__future__`. + importer + An object that both finds and loads a module; both a + :term:`finder` and :term:`loader` object. + interactive Python has an interactive interpreter which means you can enter statements and expressions at the interpreter prompt, immediately @@ -368,6 +377,11 @@ clause is optional. If omitted, all elements in ``range(256)`` are processed. + loader + An object that loads a module. It must define a method named + :meth:`load_module`. A loader is typically returned by a + :term:`finder`. See :pep:`302` for details. + mapping A container object (such as :class:`dict`) which supports arbitrary key lookups using the special method :meth:`__getitem__`. Modified: python/branches/release26-maint/Doc/howto/regex.rst ============================================================================== --- python/branches/release26-maint/Doc/howto/regex.rst (original) +++ python/branches/release26-maint/Doc/howto/regex.rst Sun Apr 5 23:11:43 2009 @@ -540,6 +540,10 @@ | :const:`VERBOSE`, :const:`X` | Enable verbose REs, which can be organized | | | more cleanly and understandably. | +---------------------------------+--------------------------------------------+ +| :const:`UNICODE`, :const:`U` | Makes several escapes like ``\w``, ``\b``, | +| | ``\s`` and ``\d`` dependent on the Unicode | +| | character database. | ++---------------------------------+--------------------------------------------+ .. data:: I @@ -594,6 +598,14 @@ newline; without this flag, ``'.'`` will match anything *except* a newline. +.. data:: U + UNICODE + :index: + + Make ``\w``, ``\W``, ``\b``, ``\B``, ``\d``, ``\D``, ``\s`` and ``\S`` + dependent on the Unicode character properties database. + + .. data:: X VERBOSE :noindex: Modified: python/branches/release26-maint/Doc/library/_winreg.rst ============================================================================== --- python/branches/release26-maint/Doc/library/_winreg.rst (original) +++ python/branches/release26-maint/Doc/library/_winreg.rst Sun Apr 5 23:11:43 2009 @@ -1,4 +1,3 @@ - :mod:`_winreg` -- Windows registry access ========================================= @@ -47,8 +46,8 @@ *key* is the predefined handle to connect to. - The return value is the handle of the opened key. If the function fails, an - :exc:`EnvironmentError` exception is raised. + The return value is the handle of the opened key. If the function fails, a + :exc:`WindowsError` exception is raised. .. function:: CreateKey(key, sub_key) @@ -65,8 +64,8 @@ If the key already exists, this function opens the existing key. - The return value is the handle of the opened key. If the function fails, an - :exc:`EnvironmentError` exception is raised. + The return value is the handle of the opened key. If the function fails, a + :exc:`WindowsError` exception is raised. .. function:: DeleteKey(key, sub_key) @@ -82,7 +81,7 @@ *This method can not delete keys with subkeys.* If the method succeeds, the entire key, including all of its values, is removed. - If the method fails, an :exc:`EnvironmentError` exception is raised. + If the method fails, a :exc:`WindowsError` exception is raised. .. function:: DeleteValue(key, value) @@ -105,7 +104,7 @@ *index* is an integer that identifies the index of the key to retrieve. The function retrieves the name of one subkey each time it is called. It is - typically called repeatedly until an :exc:`EnvironmentError` exception is + typically called repeatedly until a :exc:`WindowsError` exception is raised, indicating, no more values are available. @@ -119,7 +118,7 @@ *index* is an integer that identifies the index of the value to retrieve. The function retrieves the name of one subkey each time it is called. It is - typically called repeatedly, until an :exc:`EnvironmentError` exception is + typically called repeatedly, until a :exc:`WindowsError` exception is raised, indicating no more values. The result is a tuple of 3 items: @@ -209,7 +208,7 @@ The result is a new handle to the specified key. - If the function fails, :exc:`EnvironmentError` is raised. + If the function fails, :exc:`WindowsError` is raised. .. function:: OpenKeyEx() Modified: python/branches/release26-maint/Doc/library/abc.rst ============================================================================== --- python/branches/release26-maint/Doc/library/abc.rst (original) +++ python/branches/release26-maint/Doc/library/abc.rst Sun Apr 5 23:11:43 2009 @@ -161,7 +161,7 @@ multiple-inheritance. -.. function:: abstractproperty(fget[, fset[, fdel[, doc]]]) +.. function:: abstractproperty([fget[, fset[, fdel[, doc]]]]) A subclass of the built-in :func:`property`, indicating an abstract property. @@ -189,6 +189,7 @@ def setx(self, value): ... x = abstractproperty(getx, setx) + .. rubric:: Footnotes .. [#] C++ programmers should note that Python's virtual base class Modified: python/branches/release26-maint/Doc/library/functions.rst ============================================================================== --- python/branches/release26-maint/Doc/library/functions.rst (original) +++ python/branches/release26-maint/Doc/library/functions.rst Sun Apr 5 23:11:43 2009 @@ -1344,8 +1344,12 @@ Without arguments, return a dictionary corresponding to the current local symbol table. With a module, class or class instance object as argument (or anything else that has a :attr:`__dict__` attribute), returns a dictionary corresponding - to the object's symbol table. The returned dictionary should not be modified: - the effects on the corresponding symbol table are undefined. [#]_ + to the object's symbol table. + + .. warning:: + + The returned dictionary should not be modified: + the effects on the corresponding symbol table are undefined. [#]_ .. function:: xrange([start,] stop[, step]) Modified: python/branches/release26-maint/Doc/library/index.rst ============================================================================== --- python/branches/release26-maint/Doc/library/index.rst (original) +++ python/branches/release26-maint/Doc/library/index.rst Sun Apr 5 23:11:43 2009 @@ -38,6 +38,7 @@ .. toctree:: :maxdepth: 2 + :numbered: intro.rst functions.rst Modified: python/branches/release26-maint/Doc/library/os.rst ============================================================================== --- python/branches/release26-maint/Doc/library/os.rst (original) +++ python/branches/release26-maint/Doc/library/os.rst Sun Apr 5 23:11:43 2009 @@ -1751,7 +1751,9 @@ which is used to define the environment variables for the new process (they are used instead of the current process' environment); the functions :func:`spawnl`, :func:`spawnlp`, :func:`spawnv`, and :func:`spawnvp` all cause - the new process to inherit the environment of the current process. + the new process to inherit the environment of the current process. Note that + keys and values in the *env* dictionary must be strings; invalid keys or + values will cause the function to fail, with a return value of ``127``. As an example, the following calls to :func:`spawnlp` and :func:`spawnvpe` are equivalent:: Modified: python/branches/release26-maint/Doc/library/re.rst ============================================================================== --- python/branches/release26-maint/Doc/library/re.rst (original) +++ python/branches/release26-maint/Doc/library/re.rst Sun Apr 5 23:11:43 2009 @@ -8,12 +8,9 @@ .. sectionauthor:: Andrew M. Kuchling - - This module provides regular expression matching operations similar to those found in Perl. Both patterns and strings to be searched can be -Unicode strings as well as 8-bit strings. The :mod:`re` module is -always available. +Unicode strings as well as 8-bit strings. Regular expressions use the backslash character (``'\'``) to indicate special forms or to allow special characters to be used without invoking @@ -43,9 +40,6 @@ second edition of the book no longer covers Python at all, but the first edition covered writing good regular expression patterns in great detail. - `Kodos `_ - is a graphical regular expression debugger written in Python. - .. _re-syntax: Modified: python/branches/release26-maint/Doc/library/stdtypes.rst ============================================================================== --- python/branches/release26-maint/Doc/library/stdtypes.rst (original) +++ python/branches/release26-maint/Doc/library/stdtypes.rst Sun Apr 5 23:11:43 2009 @@ -2652,6 +2652,17 @@ The name of the class or type. + +.. method:: class.__subclasses__ + + :term:`New-style class`\ es keep a list of weak references to their immediate + subclasses. This method returns a list of all those references still alive. + Example:: + + >>> int.__subclasses__() + [] + + .. rubric:: Footnotes .. [#] Additional information on these special methods may be found in the Python Modified: python/branches/release26-maint/Doc/library/sys.rst ============================================================================== --- python/branches/release26-maint/Doc/library/sys.rst (original) +++ python/branches/release26-maint/Doc/library/sys.rst Sun Apr 5 23:11:43 2009 @@ -535,6 +535,22 @@ characters are stored as UCS-2 or UCS-4. +.. data:: meta_path + + A list of :term:`finder` objects that have their :meth:`find_module` + methods called to see if one of the objects can find the module to be + imported. The :meth:`find_module` method is called at least with the + absolute name of the module being imported. If the module to be imported is + contained in package then the parent package's :attr:`__path__` attribute + is passed in as a second argument. The method returns :keyword:`None` if + the module cannot be found, else returns a :term:`loader`. + + :data:`sys.meta_path` is searched before any implicit default finders or + :data:`sys.path`. + + See :pep:`302` for the original specification. + + .. data:: modules .. index:: builtin: reload @@ -571,6 +587,27 @@ :data:`sys.path`. +.. data:: path_hooks + + A list of callables that take a path argument to try to create a + :term:`finder` for the path. If a finder can be created, it is to be + returned by the callable, else raise :exc:`ImportError`. + + Originally specified in :pep:`302`. + + +.. data:: path_importer_cache + + A dictionary acting as a cache for :term:`finder` objects. The keys are + paths that have been passed to :data:`sys.path_hooks` and the values are + the finders that are found. If a path is a valid file system path but no + explicit finder is found on :data:`sys.path_hooks` then :keyword:`None` is + stored to represent the implicit default finder should be used. If the path + is not an existing path then :class:`imp.NullImporter` is set. + + Originally specified in :pep:`302`. + + .. data:: platform This string contains a platform identifier that can be used to append Modified: python/branches/release26-maint/Doc/reference/datamodel.rst ============================================================================== --- python/branches/release26-maint/Doc/reference/datamodel.rst (original) +++ python/branches/release26-maint/Doc/reference/datamodel.rst Sun Apr 5 23:11:43 2009 @@ -56,12 +56,13 @@ they may be garbage-collected. An implementation is allowed to postpone garbage collection or omit it altogether --- it is a matter of implementation quality how garbage collection is implemented, as long as no objects are collected that -are still reachable. (Implementation note: the current implementation uses a +are still reachable. (Implementation note: CPython currently uses a reference-counting scheme with (optional) delayed detection of cyclically linked garbage, which collects most objects as soon as they become unreachable, but is not guaranteed to collect garbage containing circular references. See the documentation of the :mod:`gc` module for information on controlling the -collection of cyclic garbage.) +collection of cyclic garbage. Other implementations act differently and CPython +may change.) Note that the use of the implementation's tracing or debugging facilities may keep objects alive that would normally be collectable. Also note that catching Modified: python/branches/release26-maint/Doc/reference/index.rst ============================================================================== --- python/branches/release26-maint/Doc/reference/index.rst (original) +++ python/branches/release26-maint/Doc/reference/index.rst Sun Apr 5 23:11:43 2009 @@ -18,6 +18,7 @@ .. toctree:: :maxdepth: 2 + :numbered: introduction.rst lexical_analysis.rst Modified: python/branches/release26-maint/Doc/reference/simple_stmts.rst ============================================================================== --- python/branches/release26-maint/Doc/reference/simple_stmts.rst (original) +++ python/branches/release26-maint/Doc/reference/simple_stmts.rst Sun Apr 5 23:11:43 2009 @@ -653,48 +653,124 @@ Import statements are executed in two steps: (1) find a module, and initialize it if necessary; (2) define a name or names in the local namespace (of the scope -where the :keyword:`import` statement occurs). The first form (without -:keyword:`from`) repeats these steps for each identifier in the list. The form -with :keyword:`from` performs step (1) once, and then performs step (2) -repeatedly. - -In this context, to "initialize" a built-in or extension module means to call an -initialization function that the module must provide for the purpose (in the -reference implementation, the function's name is obtained by prepending string -"init" to the module's name); to "initialize" a Python-coded module means to -execute the module's body. - -.. index:: - single: modules (in module sys) - single: sys.modules - pair: module; name - pair: built-in; module - pair: user-defined; module - module: sys - pair: filename; extension - triple: module; search; path - -The system maintains a table of modules that have been or are being initialized, -indexed by module name. This table is accessible as ``sys.modules``. When a -module name is found in this table, step (1) is finished. If not, a search for -a module definition is started. When a module is found, it is loaded. Details -of the module searching and loading process are implementation and platform -specific. It generally involves searching for a "built-in" module with the -given name and then searching a list of locations given as ``sys.path``. +where the :keyword:`import` statement occurs). The statement comes in two +forms differing on whether it uses the :keyword:`from` keyword. The first form +(without :keyword:`from`) repeats these steps for each identifier in the list. +The form with :keyword:`from` performs step (1) once, and then performs step +(2) repeatedly. .. index:: - pair: module; initialization - exception: ImportError - single: code block - exception: SyntaxError + single: package + +To understand how step (1) occurs, one must first understand how Python handles +hierarchical naming of modules. To help organize modules and provide a +hierarchy in naming, Python has a concept of packages. A package can contain +other packages and modules while modules cannot contain other modules or +packages. From a file system perspective, packages are directories and modules +are files. The original `specification for packages +`_ is still available to read, +although minor details have changed since the writing of that document. + +.. index:: + single: sys.modules + +Once the name of the module is known (unless otherwise specified, the term +"module" will refer to both packages and modules), searching +for the module or package can begin. The first place checked is +:data:`sys.modules`, the cache of all modules that have been imported +previously. If the module is found there then it is used in step (2) of import. + +.. index:: + single: sys.meta_path + single: finder + pair: finder; find_module + single: __path__ + +If the module is not found in the cache, then :data:`sys.meta_path` is searched +(the specification for :data:`sys.meta_path` can be found in :pep:`302`). +The object is a list of :term:`finder` objects which are queried in order as to +whether they know how to load the module by calling their :meth:`find_module` +method with the name of the module. If the module happens to be contained +within a package (as denoted by the existence of a dot in the name), then a +second argument to :meth:`find_module` is given as the value of the +:attr:`__path__` attribute from the parent package (everything up to the last +dot in the name of the module being imported). If a finder can find the module +it returns a :term:`loader` (discussed later) or returns :keyword:`None`. + +.. index:: + single: sys.path_hooks + single: sys.path_importer_cache + single: sys.path + +If none of the finders on :data:`sys.meta_path` are able to find the module +then some implicitly defined finders are queried. Implementations of Python +vary in what implicit meta path finders are defined. The one they all do +define, though, is one that handles :data:`sys.path_hooks`, +:data:`sys.path_importer_cache`, and :data:`sys.path`. + +The implicit finder searches for the requested module in the "paths" specified +in one of two places ("paths" do not have to be file system paths). If the +module being imported is supposed to be contained within a package then the +second argument passed to :meth:`find_module`, :attr:`__path__` on the parent +package, is used as the source of paths. If the module is not contained in a +package then :data:`sys.path` is used as the source of paths. + +Once the source of paths is chosen it is iterated over to find a finder that +can handle that path. The dict at :data:`sys.path_importer_cache` caches +finders for paths and is checked for a finder. If the path does not have a +finder cached then :data:`sys.path_hooks` is searched by calling each object in +the list with a single argument of the path, returning a finder or raises +:exc:`ImportError`. If a finder is returned then it is cached in +:data:`sys.path_importer_cache` and then used for that path entry. If no finder +can be found but the path exists then a value of :keyword:`None` is +stored in :data:`sys.path_importer_cache` to signify that an implicit, +file-based finder that handles modules stored as individual files should be +used for that path. If the path does not exist then a finder which always +returns :keyword:`None` is placed in the cache for the path. -If a built-in module is found, its built-in initialization code is executed and -step (1) is finished. If no matching file is found, :exc:`ImportError` is -raised. If a file is found, it is parsed, yielding an executable code block. If -a syntax error occurs, :exc:`SyntaxError` is raised. Otherwise, an empty module -of the given name is created and inserted in the module table, and then the code -block is executed in the context of this module. Exceptions during this -execution terminate step (1). +.. index:: + single: loader + pair: loader; load_module + exception: ImportError + +If no finder can find the module then :exc:`ImportError` is raised. Otherwise +some finder returned a loader whose :meth:`load_module` method is called with +the name of the module to load (see :pep:`302` for the original definition of +loaders). A loader has several responsibilities to perform on a module it +loads. First, if the module already exists in :data:`sys.modules` (a +possibility if the loader is called outside of the import machinery) then it +is to use that module for initialization and not a new module. But if the +module does not exist in :data:`sys.modules` then it is to be added to that +dict before initialization begins. If an error occurs during loading of the +module and it was added to :data:`sys.modules` it is to be removed from the +dict. If an error occurs but the module was already in :data:`sys.modules` it +is left in the dict. + +.. index:: + single: __name__ + single: __file__ + single: __path__ + single: __package__ + single: __loader__ + +The loader must set several attributes on the module. :data:`__name__` is to be +set to the name of the module. :data:`__file__` is to be the "path" to the file +unless the module is built-in (and thus listed in +:data:`sys.builtin_module_names`) in which case the attribute is not set. +If what is being imported is a package then :data:`__path__` is to be set to a +list of paths to be searched when looking for modules and packages contained +within the package being imported. :data:`__package__` is optional but should +be set to the name of package that contains the module or package (the empty +string is used for module not contained in a package). :data:`__loader__` is +also optional but should be set to the loader object that is loading the +module. + +.. index:: + exception: ImportError + +If an error occurs during loading then the loader raises :exc:`ImportError` if +some other exception is not already being propagated. Otherwise the loader +returns the module that was loaded and initialized. When step (1) finishes without raising an exception, step (2) can begin. @@ -734,23 +810,21 @@ raise a :exc:`SyntaxError`. .. index:: - keyword: from - statement: from - triple: hierarchical; module; names - single: packages - single: __init__.py - -**Hierarchical module names:** when the module names contains one or more dots, -the module search path is carried out differently. The sequence of identifiers -up to the last dot is used to find a "package"; the final identifier is then -searched inside the package. A package is generally a subdirectory of a -directory on ``sys.path`` that has a file :file:`__init__.py`. - -.. - [XXX Can't be - bothered to spell this out right now; see the URL - http://www.python.org/doc/essays/packages.html for more details, also about how - the module search works from inside a package.] + single: relative; import + +When specifying what module to import you do not have to specify the absolute +name of the module. When a module or package is contained within another +package it is possible to make a relative import within the same top package +without having to mention the package name. By using leading dots in the +specified module or package after :keyword:`from` you can specify how high to +traverse up the current package hierarchy without specifying exact names. One +leading dot means the current package where the module making the import +exists. Two dots means up one package level. Three dots is up two levels, etc. +So if you execute ``from . import mod`` from a module in the ``pkg`` package +then you will end up importing ``pkg.mod``. If you execute ``from ..subpkg2 +imprt mod`` from within ``pkg.subpkg1`` you will import ``pkg.subpkg2.mod``. +The specification for relative imports is contained within :pep:`328`. + .. index:: builtin: __import__ @@ -892,7 +966,7 @@ This statement supports dynamic execution of Python code. The first expression should evaluate to either a string, an open file object, or a code object. If it is a string, the string is parsed as a suite of Python statements which is -then executed (unless a syntax error occurs). If it is an open file, the file +then executed (unless a syntax error occurs). [#]_ If it is an open file, the file is parsed until EOF and executed. If it is a code object, it is simply executed. In all cases, the code that's executed is expected to be valid as file input (see section :ref:`file-input`). Be aware that the @@ -930,3 +1004,8 @@ which may be useful to pass around for use by :keyword:`exec`. +.. rubric:: Footnotes + +.. [#] Note that the parser only accepts the Unix-style end of line convention. + If you are reading the code from a file, make sure to use universal + newline mode to convert Windows or Mac-style newlines. Modified: python/branches/release26-maint/Doc/tutorial/index.rst ============================================================================== --- python/branches/release26-maint/Doc/tutorial/index.rst (original) +++ python/branches/release26-maint/Doc/tutorial/index.rst Sun Apr 5 23:11:43 2009 @@ -44,6 +44,7 @@ The :ref:`glossary` is also worth going through. .. toctree:: + :numbered: appetite.rst interpreter.rst Modified: python/branches/release26-maint/Doc/using/index.rst ============================================================================== --- python/branches/release26-maint/Doc/using/index.rst (original) +++ python/branches/release26-maint/Doc/using/index.rst Sun Apr 5 23:11:43 2009 @@ -11,6 +11,7 @@ .. toctree:: + :numbered: cmdline.rst unix.rst Modified: python/branches/release26-maint/Lib/distutils/version.py ============================================================================== --- python/branches/release26-maint/Lib/distutils/version.py (original) +++ python/branches/release26-maint/Lib/distutils/version.py Sun Apr 5 23:11:43 2009 @@ -162,7 +162,7 @@ # The rules according to Greg Stein: -# 1) a version number has 1 or more numbers separate by a period or by +# 1) a version number has 1 or more numbers separated by a period or by # sequences of letters. If only periods, then these are compared # left-to-right to determine an ordering. # 2) sequences of letters are part of the tuple for comparison and are Modified: python/branches/release26-maint/Objects/genobject.c ============================================================================== --- python/branches/release26-maint/Objects/genobject.c (original) +++ python/branches/release26-maint/Objects/genobject.c Sun Apr 5 23:11:43 2009 @@ -306,7 +306,7 @@ "Return the name of the generator's associated code object."); static PyGetSetDef gen_getsetlist[] = { - {"__name__", (getter)gen_get_name, NULL, NULL, gen__name__doc__}, + {"__name__", (getter)gen_get_name, NULL, gen__name__doc__}, {NULL} }; From python-checkins at python.org Sun Apr 5 23:19:14 2009 From: python-checkins at python.org (matthias.klose) Date: Sun, 5 Apr 2009 23:19:14 +0200 (CEST) Subject: [Python-checkins] r71271 - in python/trunk: Include/object.h Misc/NEWS Modules/readline.c Message-ID: <20090405211914.4DFCE1E408E@bag.python.org> Author: matthias.klose Date: Sun Apr 5 23:19:13 2009 New Revision: 71271 Log: Issue #1113244: Py_XINCREF, Py_DECREF, Py_XDECREF: Add `do { ... } while (0)' to avoid compiler warnings. Modified: python/trunk/Include/object.h python/trunk/Misc/NEWS python/trunk/Modules/readline.c Modified: python/trunk/Include/object.h ============================================================================== --- python/trunk/Include/object.h (original) +++ python/trunk/Include/object.h Sun Apr 5 23:19:13 2009 @@ -801,8 +801,8 @@ } while (0) /* Macros to use in case the object pointer may be NULL: */ -#define Py_XINCREF(op) if ((op) == NULL) ; else Py_INCREF(op) -#define Py_XDECREF(op) if ((op) == NULL) ; else Py_DECREF(op) +#define Py_XINCREF(op) do { if ((op) == NULL) ; else Py_INCREF(op); } while (0) +#define Py_XDECREF(op) do { if ((op) == NULL) ; else Py_DECREF(op); } while (0) /* These are provided as conveniences to Python runtime embedders, so that Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Apr 5 23:19:13 2009 @@ -207,7 +207,8 @@ - Issue #3845: In PyRun_SimpleFileExFlags avoid invalid memory access with short file names. -- Py_DECREF: Add `do { ... } while (0)' to avoid compiler warnings. +- Issue #1113244: Py_XINCREF, Py_DECREF, Py_XDECREF: Add `do { ... } while (0)' + to avoid compiler warnings. Library ------- Modified: python/trunk/Modules/readline.c ============================================================================== --- python/trunk/Modules/readline.c (original) +++ python/trunk/Modules/readline.c Sun Apr 5 23:19:13 2009 @@ -694,13 +694,13 @@ r = PyObject_CallFunction(completion_display_matches_hook, "sOi", matches[0], m, max_length); - Py_DECREF(m), m=NULL; + Py_DECREF(m); m=NULL; if (r == NULL || (r != Py_None && PyInt_AsLong(r) == -1 && PyErr_Occurred())) { goto error; } - Py_XDECREF(r), r=NULL; + Py_XDECREF(r); r=NULL; if (0) { error: From python-checkins at python.org Sun Apr 5 23:21:05 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 23:21:05 +0200 (CEST) Subject: [Python-checkins] r71272 - in python/branches/release26-maint: Doc/c-api/structures.rst Doc/distutils/apiref.rst Doc/library/doctest.rst Doc/library/re.rst Doc/library/stdtypes.rst Doc/library/sys.rst Doc/library/urllib.rst Doc/tutorial/datastructures.rst Doc/tutorial/introduction.rst Lib/SimpleXMLRPCServer.py Lib/distutils/command/__init__.py Lib/glob.py Lib/optparse.py Lib/pdb.py Lib/test/test_sys.py Lib/test/test_xmlrpc.py Misc/NEWS Misc/gdbinit README Message-ID: <20090405212105.9F1851E408E@bag.python.org> Author: georg.brandl Date: Sun Apr 5 23:21:05 2009 New Revision: 71272 Log: Merged revisions 70866-70868,70870-70871,70893,70896,70902,70905,70907,70912,70915,70927,70933,70940,70944,70954,70963,70998,71056 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70866 | georg.brandl | 2009-03-31 21:06:57 +0200 (Di, 31 M?r 2009) | 1 line #4882: document named group behavior a bit better. ........ r70867 | georg.brandl | 2009-03-31 21:10:35 +0200 (Di, 31 M?r 2009) | 1 line #1096310: document usage of sys.__std*__ a bit better. ........ r70868 | georg.brandl | 2009-03-31 21:12:17 +0200 (Di, 31 M?r 2009) | 1 line #5190: export make_option in __all__. ........ r70870 | georg.brandl | 2009-03-31 21:26:24 +0200 (Di, 31 M?r 2009) | 1 line #4411: document mro() and __mro__. (I hope I got it right.) ........ r70871 | georg.brandl | 2009-03-31 21:30:56 +0200 (Di, 31 M?r 2009) | 1 line #5618: fix typo. ........ r70893 | georg.brandl | 2009-03-31 22:56:32 +0200 (Di, 31 M?r 2009) | 1 line #1530012: move TQS section before raw strings. ........ r70896 | georg.brandl | 2009-03-31 23:15:33 +0200 (Di, 31 M?r 2009) | 1 line #5598: document DocFileSuite *args argument. ........ r70902 | georg.brandl | 2009-03-31 23:43:03 +0200 (Di, 31 M?r 2009) | 1 line #1675026: add a note about a strange Windows problem, and remove notes about AtheOS. ........ r70905 | georg.brandl | 2009-04-01 00:03:40 +0200 (Mi, 01 Apr 2009) | 1 line #5563: more documentation for bdist_msi. ........ r70907 | georg.brandl | 2009-04-01 00:18:19 +0200 (Mi, 01 Apr 2009) | 1 line #3427: document correct return type for urlopen().info(). ........ r70912 | georg.brandl | 2009-04-01 00:35:46 +0200 (Mi, 01 Apr 2009) | 1 line #5617: add a handy function to print a unicode string to gdbinit. ........ r70915 | georg.brandl | 2009-04-01 00:40:16 +0200 (Mi, 01 Apr 2009) | 1 line #5018: remove confusing paragraph. ........ r70927 | georg.brandl | 2009-04-01 01:01:27 +0200 (Mi, 01 Apr 2009) | 1 line Dont shout to users. ........ r70933 | georg.brandl | 2009-04-01 02:04:33 +0200 (Mi, 01 Apr 2009) | 2 lines Issue #5635: Fix running test_sys with tracing enabled. ........ r70940 | georg.brandl | 2009-04-01 06:21:14 +0200 (Mi, 01 Apr 2009) | 2 lines The SimpleXMLRPCServer's CGI handler now runs like a pony. ........ r70944 | georg.brandl | 2009-04-01 06:32:39 +0200 (Mi, 01 Apr 2009) | 1 line #5631: add upload to list of possible commands, which is presented in --help-commands. ........ r70954 | georg.brandl | 2009-04-01 17:23:43 +0200 (Mi, 01 Apr 2009) | 1 line Fix test_xmlrpc and make the CGI handler work with no CONTENT_LENGTH. ........ r70963 | georg.brandl | 2009-04-01 19:46:01 +0200 (Mi, 01 Apr 2009) | 1 line #5655: fix docstring oversight. ........ r70998 | georg.brandl | 2009-04-01 23:54:21 +0200 (Mi, 01 Apr 2009) | 1 line In Pdb, stop assigning values to __builtin__._ which interferes with the one commonly installed by gettext. ........ r71056 | georg.brandl | 2009-04-02 19:43:07 +0200 (Do, 02 Apr 2009) | 2 lines Actually the displayhook should print the repr. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/c-api/structures.rst python/branches/release26-maint/Doc/distutils/apiref.rst python/branches/release26-maint/Doc/library/doctest.rst python/branches/release26-maint/Doc/library/re.rst python/branches/release26-maint/Doc/library/stdtypes.rst python/branches/release26-maint/Doc/library/sys.rst python/branches/release26-maint/Doc/library/urllib.rst python/branches/release26-maint/Doc/tutorial/datastructures.rst python/branches/release26-maint/Doc/tutorial/introduction.rst python/branches/release26-maint/Lib/SimpleXMLRPCServer.py python/branches/release26-maint/Lib/distutils/command/__init__.py python/branches/release26-maint/Lib/glob.py python/branches/release26-maint/Lib/optparse.py python/branches/release26-maint/Lib/pdb.py python/branches/release26-maint/Lib/test/test_sys.py python/branches/release26-maint/Lib/test/test_xmlrpc.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Misc/gdbinit python/branches/release26-maint/README Modified: python/branches/release26-maint/Doc/c-api/structures.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/structures.rst (original) +++ python/branches/release26-maint/Doc/c-api/structures.rst Sun Apr 5 23:21:05 2009 @@ -247,7 +247,7 @@ T_OBJECT_EX PyObject \* T_CHAR char T_BYTE char - T_UNBYTE unsigned char + T_UBYTE unsigned char T_UINT unsigned int T_USHORT unsigned short T_ULONG unsigned long Modified: python/branches/release26-maint/Doc/distutils/apiref.rst ============================================================================== --- python/branches/release26-maint/Doc/distutils/apiref.rst (original) +++ python/branches/release26-maint/Doc/distutils/apiref.rst Sun Apr 5 23:21:05 2009 @@ -1775,8 +1775,16 @@ .. module:: distutils.command.bdist_msi :synopsis: Build a binary distribution as a Windows MSI file +.. class:: bdist_msi(Command) -.. % todo + Builds a `Windows Installer`_ (.msi) binary package. + + .. _Windows Installer: http://msdn.microsoft.com/en-us/library/cc185688(VS.85).aspx + + In most cases, the ``bdist_msi`` installer is a better choice than the + ``bdist_wininst`` installer, because it provides better support for + Win64 platforms, allows administrators to perform non-interactive + installations, and allows installation through group policies. :mod:`distutils.command.bdist_rpm` --- Build a binary distribution as a Redhat RPM and SRPM Modified: python/branches/release26-maint/Doc/library/doctest.rst ============================================================================== --- python/branches/release26-maint/Doc/library/doctest.rst (original) +++ python/branches/release26-maint/Doc/library/doctest.rst Sun Apr 5 23:21:05 2009 @@ -965,7 +965,7 @@ from text files and modules with doctests: -.. function:: DocFileSuite([module_relative][, package][, setUp][, tearDown][, globs][, optionflags][, parser][, encoding]) +.. function:: DocFileSuite(*paths, [module_relative][, package][, setUp][, tearDown][, globs][, optionflags][, parser][, encoding]) Convert doctest tests from one or more text files to a :class:`unittest.TestSuite`. @@ -983,45 +983,47 @@ Optional argument *module_relative* specifies how the filenames in *paths* should be interpreted: - * If *module_relative* is ``True`` (the default), then each filename specifies - an OS-independent module-relative path. By default, this path is relative to - the calling module's directory; but if the *package* argument is specified, then - it is relative to that package. To ensure OS-independence, each filename should - use ``/`` characters to separate path segments, and may not be an absolute path - (i.e., it may not begin with ``/``). - - * If *module_relative* is ``False``, then each filename specifies an OS-specific - path. The path may be absolute or relative; relative paths are resolved with - respect to the current working directory. - - Optional argument *package* is a Python package or the name of a Python package - whose directory should be used as the base directory for module-relative - filenames. If no package is specified, then the calling module's directory is - used as the base directory for module-relative filenames. It is an error to - specify *package* if *module_relative* is ``False``. - - Optional argument *setUp* specifies a set-up function for the test suite. This - is called before running the tests in each file. The *setUp* function will be - passed a :class:`DocTest` object. The setUp function can access the test - globals as the *globs* attribute of the test passed. + * If *module_relative* is ``True`` (the default), then each filename in + *paths* specifies an OS-independent module-relative path. By default, this + path is relative to the calling module's directory; but if the *package* + argument is specified, then it is relative to that package. To ensure + OS-independence, each filename should use ``/`` characters to separate path + segments, and may not be an absolute path (i.e., it may not begin with + ``/``). + + * If *module_relative* is ``False``, then each filename in *paths* specifies + an OS-specific path. The path may be absolute or relative; relative paths + are resolved with respect to the current working directory. + + Optional argument *package* is a Python package or the name of a Python + package whose directory should be used as the base directory for + module-relative filenames in *paths*. If no package is specified, then the + calling module's directory is used as the base directory for module-relative + filenames. It is an error to specify *package* if *module_relative* is + ``False``. - Optional argument *tearDown* specifies a tear-down function for the test suite. - This is called after running the tests in each file. The *tearDown* function + Optional argument *setUp* specifies a set-up function for the test suite. + This is called before running the tests in each file. The *setUp* function will be passed a :class:`DocTest` object. The setUp function can access the test globals as the *globs* attribute of the test passed. + Optional argument *tearDown* specifies a tear-down function for the test + suite. This is called after running the tests in each file. The *tearDown* + function will be passed a :class:`DocTest` object. The setUp function can + access the test globals as the *globs* attribute of the test passed. + Optional argument *globs* is a dictionary containing the initial global variables for the tests. A new copy of this dictionary is created for each test. By default, *globs* is a new empty dictionary. Optional argument *optionflags* specifies the default doctest options for the tests, created by or-ing together individual option flags. See section - :ref:`doctest-options`. See function :func:`set_unittest_reportflags` below for - a better way to set reporting options. + :ref:`doctest-options`. See function :func:`set_unittest_reportflags` below + for a better way to set reporting options. - Optional argument *parser* specifies a :class:`DocTestParser` (or subclass) that - should be used to extract tests from the files. It defaults to a normal parser - (i.e., ``DocTestParser()``). + Optional argument *parser* specifies a :class:`DocTestParser` (or subclass) + that should be used to extract tests from the files. It defaults to a normal + parser (i.e., ``DocTestParser()``). Optional argument *encoding* specifies an encoding that should be used to convert the file to unicode. @@ -1029,8 +1031,8 @@ .. versionadded:: 2.4 .. versionchanged:: 2.5 - The global ``__file__`` was added to the globals provided to doctests loaded - from a text file using :func:`DocFileSuite`. + The global ``__file__`` was added to the globals provided to doctests + loaded from a text file using :func:`DocFileSuite`. .. versionchanged:: 2.5 The parameter *encoding* was added. Modified: python/branches/release26-maint/Doc/library/re.rst ============================================================================== --- python/branches/release26-maint/Doc/library/re.rst (original) +++ python/branches/release26-maint/Doc/library/re.rst Sun Apr 5 23:21:05 2009 @@ -231,16 +231,18 @@ ``(?P...)`` Similar to regular parentheses, but the substring matched by the group is - accessible via the symbolic group name *name*. Group names must be valid Python - identifiers, and each group name must be defined only once within a regular - expression. A symbolic group is also a numbered group, just as if the group - were not named. So the group named 'id' in the example below can also be - referenced as the numbered group 1. + accessible within the rest of the regular expression via the symbolic group + name *name*. Group names must be valid Python identifiers, and each group + name must be defined only once within a regular expression. A symbolic group + is also a numbered group, just as if the group were not named. So the group + named ``id`` in the example below can also be referenced as the numbered group + ``1``. For example, if the pattern is ``(?P[a-zA-Z_]\w*)``, the group can be referenced by its name in arguments to methods of match objects, such as - ``m.group('id')`` or ``m.end('id')``, and also by name in pattern text (for - example, ``(?P=id)``) and replacement text (such as ``\g``). + ``m.group('id')`` or ``m.end('id')``, and also by name in the regular + expression itself (using ``(?P=id)``) and replacement text given to + ``.sub()`` (using ``\g``). ``(?P=name)`` Matches whatever text was matched by the earlier group named *name*. Modified: python/branches/release26-maint/Doc/library/stdtypes.rst ============================================================================== --- python/branches/release26-maint/Doc/library/stdtypes.rst (original) +++ python/branches/release26-maint/Doc/library/stdtypes.rst Sun Apr 5 23:21:05 2009 @@ -2653,9 +2653,24 @@ The name of the class or type. +The following attributes are only supported by :term:`new-style class`\ es. + +.. attribute:: class.__mro__ + + This attribute is a tuple of classes that are considered when looking for + base classes during method resolution. + + +.. method:: class.mro() + + This method can be overridden by a metaclass to customize the method + resolution order for its instances. It is called at class instantiation, and + its result is stored in :attr:`__mro__`. + + .. method:: class.__subclasses__ - :term:`New-style class`\ es keep a list of weak references to their immediate + Each new-style class keeps a list of weak references to its immediate subclasses. This method returns a list of all those references still alive. Example:: Modified: python/branches/release26-maint/Doc/library/sys.rst ============================================================================== --- python/branches/release26-maint/Doc/library/sys.rst (original) +++ python/branches/release26-maint/Doc/library/sys.rst Sun Apr 5 23:21:05 2009 @@ -850,9 +850,14 @@ __stderr__ These objects contain the original values of ``stdin``, ``stderr`` and - ``stdout`` at the start of the program. They are used during finalization, and - could be useful to restore the actual files to known working file objects in - case they have been overwritten with a broken object. + ``stdout`` at the start of the program. They are used during finalization, + and could be useful to print to the actual standard stream no matter if the + ``sys.std*`` object has been redirected. + + It can also be used to restore the actual files to known working file objects + in case they have been overwritten with a broken object. However, the + preferred way to do this is to explicitly save the previous stream before + replacing it, and restore the saved object. .. data:: tracebacklimit Modified: python/branches/release26-maint/Doc/library/urllib.rst ============================================================================== --- python/branches/release26-maint/Doc/library/urllib.rst (original) +++ python/branches/release26-maint/Doc/library/urllib.rst Sun Apr 5 23:21:05 2009 @@ -49,7 +49,7 @@ .. index:: module: mimetools The :meth:`info` method returns an instance of the class - :class:`mimetools.Message` containing meta-information associated with the + :class:`httplib.HTTPMessage` containing meta-information associated with the URL. When the method is HTTP, these headers are those returned by the server at the head of the retrieved HTML page (including Content-Length and Content-Type). When the method is FTP, a Content-Length header will be Modified: python/branches/release26-maint/Doc/tutorial/datastructures.rst ============================================================================== --- python/branches/release26-maint/Doc/tutorial/datastructures.rst (original) +++ python/branches/release26-maint/Doc/tutorial/datastructures.rst Sun Apr 5 23:21:05 2009 @@ -401,13 +401,11 @@ >>> x, y, z = t -This is called, appropriately enough, *sequence unpacking*. Sequence unpacking -requires the list of variables on the left to have the same number of elements -as the length of the sequence. Note that multiple assignment is really just a -combination of tuple packing and sequence unpacking! - -There is a small bit of asymmetry here: packing multiple values always creates -a tuple, and unpacking works for any sequence. +This is called, appropriately enough, *sequence unpacking* and works for any +sequence on the right-hand side. Sequence unpacking requires the list of +variables on the left to have the same number of elements as the length of the +sequence. Note that multiple assignment is really just a combination of tuple +packing and sequence unpacking. .. XXX Add a bit on the difference between tuples and lists. Modified: python/branches/release26-maint/Doc/tutorial/introduction.rst ============================================================================== --- python/branches/release26-maint/Doc/tutorial/introduction.rst (original) +++ python/branches/release26-maint/Doc/tutorial/introduction.rst Sun Apr 5 23:21:05 2009 @@ -199,21 +199,6 @@ several lines of text just as you would do in C. Note that whitespace at the beginning of the line is significant. -If we make the string literal a "raw" string, however, the ``\n`` sequences are -not converted to newlines, but the backslash at the end of the line, and the -newline character in the source, are both included in the string as data. Thus, -the example:: - - hello = r"This is a rather long string containing\n\ - several lines of text much as you would do in C." - - print hello - -would print:: - - This is a rather long string containing\n\ - several lines of text much as you would do in C. - Or, strings can be surrounded in a pair of matching triple-quotes: ``"""`` or ``'''``. End of lines do not need to be escaped when using triple-quotes, but they will be included in the string. :: @@ -230,6 +215,20 @@ -h Display this usage message -H hostname Hostname to connect to +If we make the string literal a "raw" string, ``\n`` sequences are not converted +to newlines, but the backslash at the end of the line, and the newline character +in the source, are both included in the string as data. Thus, the example:: + + hello = r"This is a rather long string containing\n\ + several lines of text much as you would do in C." + + print hello + +would print:: + + This is a rather long string containing\n\ + several lines of text much as you would do in C. + The interpreter prints the result of string operations in the same way as they are typed for input: inside quotes, and with quotes and other funny characters escaped by backslashes, to show the precise value. The string is enclosed in Modified: python/branches/release26-maint/Lib/SimpleXMLRPCServer.py ============================================================================== --- python/branches/release26-maint/Lib/SimpleXMLRPCServer.py (original) +++ python/branches/release26-maint/Lib/SimpleXMLRPCServer.py Sun Apr 5 23:21:05 2009 @@ -598,8 +598,12 @@ self.handle_get() else: # POST data is normally available through stdin + try: + length = int(os.environ.get('CONTENT_LENGTH', None)) + except (TypeError, ValueError): + length = -1 if request_text is None: - request_text = sys.stdin.read() + request_text = sys.stdin.read(length) self.handle_xmlrpc(request_text) Modified: python/branches/release26-maint/Lib/distutils/command/__init__.py ============================================================================== --- python/branches/release26-maint/Lib/distutils/command/__init__.py (original) +++ python/branches/release26-maint/Lib/distutils/command/__init__.py Sun Apr 5 23:21:05 2009 @@ -24,6 +24,8 @@ 'bdist_dumb', 'bdist_rpm', 'bdist_wininst', + 'upload', + # These two are reserved for future use: #'bdist_sdux', #'bdist_pkgtool', Modified: python/branches/release26-maint/Lib/glob.py ============================================================================== --- python/branches/release26-maint/Lib/glob.py (original) +++ python/branches/release26-maint/Lib/glob.py Sun Apr 5 23:21:05 2009 @@ -16,7 +16,7 @@ return list(iglob(pathname)) def iglob(pathname): - """Return a list of paths matching a pathname pattern. + """Return an iterator which yields the paths matching a pathname pattern. The pattern may contain simple shell-style wildcards a la fnmatch. Modified: python/branches/release26-maint/Lib/optparse.py ============================================================================== --- python/branches/release26-maint/Lib/optparse.py (original) +++ python/branches/release26-maint/Lib/optparse.py Sun Apr 5 23:21:05 2009 @@ -11,6 +11,7 @@ __version__ = "1.5.3" __all__ = ['Option', + 'make_option', 'SUPPRESS_HELP', 'SUPPRESS_USAGE', 'Values', Modified: python/branches/release26-maint/Lib/pdb.py ============================================================================== --- python/branches/release26-maint/Lib/pdb.py (original) +++ python/branches/release26-maint/Lib/pdb.py Sun Apr 5 23:21:05 2009 @@ -194,6 +194,12 @@ self.cmdloop() self.forget() + def displayhook(self, obj): + """Custom displayhook for the exec in default(), which prevents + assignment of the _ variable in the builtins. + """ + print repr(obj) + def default(self, line): if line[:1] == '!': line = line[1:] locals = self.curframe.f_locals @@ -202,13 +208,16 @@ code = compile(line + '\n', '', 'single') save_stdout = sys.stdout save_stdin = sys.stdin + save_displayhook = sys.displayhook try: sys.stdin = self.stdin sys.stdout = self.stdout + sys.displayhook = self.displayhook exec code in globals, locals finally: sys.stdout = save_stdout sys.stdin = save_stdin + sys.displayhook = save_displayhook except: t, v = sys.exc_info()[:2] if type(t) == type(''): Modified: python/branches/release26-maint/Lib/test/test_sys.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_sys.py (original) +++ python/branches/release26-maint/Lib/test/test_sys.py Sun Apr 5 23:21:05 2009 @@ -221,6 +221,11 @@ sys.setdlopenflags(oldflags) def test_refcount(self): + # n here must be a global in order for this test to pass while + # tracing with a python function. Tracing calls PyFrame_FastToLocals + # which will add a copy of any locals to the frame object, causing + # the reference count to increase by 2 instead of 1. + global n self.assertRaises(TypeError, sys.getrefcount) c = sys.getrefcount(None) n = None Modified: python/branches/release26-maint/Lib/test/test_xmlrpc.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_xmlrpc.py (original) +++ python/branches/release26-maint/Lib/test/test_xmlrpc.py Sun Apr 5 23:21:05 2009 @@ -624,7 +624,11 @@ sys.stdin = open("xmldata.txt", "r") sys.stdout = open(test_support.TESTFN, "w") - self.cgi.handle_request() + os.environ['CONTENT_LENGTH'] = str(len(data)) + try: + self.cgi.handle_request() + finally: + del os.environ['CONTENT_LENGTH'] sys.stdin.close() sys.stdout.close() Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sun Apr 5 23:21:05 2009 @@ -97,6 +97,23 @@ - Issue 1726172: fix IndexError in the case of and empty response in ftplib. +- In Pdb, prevent the reassignment of __builtin__._ by sys.displayhook on + printing out values. + +- Issue #4572: added SEEK_* symbolic constants to io module. + +- Issue #1665206 (partially): Move imports in cgitb to the top of the module + instead of performing them in functions. Helps prevent import deadlocking in + threads. + +- Issue #5647: MutableSet.__iand__() no longer mutates self during iteration. + +- Actually make the SimpleXMLRPCServer CGI handler work. + +- Issue #2522: locale.format now checks its first argument to ensure it has + been passed only one pattern, avoiding mysterious errors where it appeared + that it was failing to do localization. + - Issue 2625: added missing iteritems() call to the for loop in mailbox.MH.get_message(). @@ -508,6 +525,18 @@ - Issue #4396: The parser module now correctly validates the with statement. +Tests +----- + +- Issue #5635: Fix running test_sys with tracing enabled. + +- regrtest no longer treats ImportError as equivalent to SkipTest. Imports + that should cause a test to be skipped are now done using import_module + from test support, which does the conversion. + +- Issue #5083: New 'gui' resource for regrtest. + + What's New in Python 2.6 final ============================== Modified: python/branches/release26-maint/Misc/gdbinit ============================================================================== --- python/branches/release26-maint/Misc/gdbinit (original) +++ python/branches/release26-maint/Misc/gdbinit Sun Apr 5 23:21:05 2009 @@ -138,3 +138,16 @@ end select-frame 0 end + +# generally useful macro to print a Unicode string +def pu + set $uni = $arg0 + set $i = 0 + while (*$uni && $i++<100) + if (*$uni < 0x80) + print *(char*)$uni++ + else + print /x *(short*)$uni++ + end + end +end Modified: python/branches/release26-maint/README ============================================================================== --- python/branches/release26-maint/README (original) +++ python/branches/release26-maint/README Sun Apr 5 23:21:05 2009 @@ -665,75 +665,10 @@ News regarding these platforms with more recent Cygwin versions would be appreciated! -AtheOS: Official support has been stopped as of Python 2.6. All code will be - removed in Python 2.7 unless a maintainer steps forward for this - platform. - - From Octavian Cerna : - - Before building: - - Make sure you have shared versions of the libraries you - want to use with Python. You will have to compile them - yourself, or download precompiled packages. - - Recommended libraries: - - ncurses-4.2 - readline-4.2a - zlib-1.1.4 - - Build: - - $ ./configure --prefix=/usr/python - $ make - - Python is always built as a shared library, otherwise - dynamic loading would not work. - - Testing: - - $ make test - - Install: - - # make install - # pkgmanager -a /usr/python - - - AtheOS issues: - - - large file support: due to a stdio bug in glibc/libio, - access to large files may not work correctly. fseeko() - tries to seek to a negative offset. ftello() returns a - negative offset, it looks like a 32->64bit - sign-extension issue. The lowlevel functions (open, - lseek, etc) are OK. - - sockets: AF_UNIX is defined in the C library and in - Python, but not implemented in the system. - - select: poll is available in the C library, but does not - work (It does not return POLLNVAL for bad fds and - hangs). - - posix: statvfs and fstatvfs always return ENOSYS. - - disabled modules: - - mmap: not yet implemented in AtheOS - - nis: broken (on an unconfigured system - yp_get_default_domain() returns junk instead of - error) - - dl: dynamic loading doesn't work via dlopen() - - resource: getrimit and setrlimit are not yet - implemented - - - if you are getting segmentation faults, you probably are - low on memory. AtheOS doesn't handle very well an - out-of-memory condition and simply SEGVs the process. - - Tested on: - - AtheOS-0.3.7 - gcc-2.95 - binutils-2.10 - make-3.78 +Windows: When executing Python scripts on the command line using file type + associations (i.e. starting "script.py" instead of "python script.py"), + redirects may not work unless you set a specific registry key. See + the Knowledge Base article . Configuring the bsddb and dbm modules From python-checkins at python.org Sun Apr 5 23:23:27 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 23:23:27 +0200 (CEST) Subject: [Python-checkins] r71273 - python/branches/release26-maint Message-ID: <20090405212327.2BA931E4078@bag.python.org> Author: georg.brandl Date: Sun Apr 5 23:23:27 2009 New Revision: 71273 Log: Blocked revisions 70869,70883,70901,70903,70951,70992-70994,71006,71019,71024 via svnmerge ........ r70869 | georg.brandl | 2009-03-31 21:14:42 +0200 (Di, 31 M?r 2009) | 1 line Fix-up unwanted change. ........ r70883 | georg.brandl | 2009-03-31 22:41:08 +0200 (Di, 31 M?r 2009) | 1 line #1674032: return value of flag from Event.wait(). OKed by Guido. ........ r70901 | georg.brandl | 2009-03-31 23:40:24 +0200 (Di, 31 M?r 2009) | 2 lines Remove warning about pending Win9x support removal. ........ r70903 | georg.brandl | 2009-03-31 23:45:18 +0200 (Di, 31 M?r 2009) | 1 line #1676135: remove trailing slashes from --prefix argument. ........ r70951 | georg.brandl | 2009-04-01 16:02:27 +0200 (Mi, 01 Apr 2009) | 1 line Add Maksim, who worked on several issues at the sprint. ........ r70992 | georg.brandl | 2009-04-01 23:00:55 +0200 (Mi, 01 Apr 2009) | 1 line #4572: add SEEK_* values as constants in io.py. ........ r70993 | georg.brandl | 2009-04-01 23:05:44 +0200 (Mi, 01 Apr 2009) | 1 line Add NEWS item. ........ r70994 | georg.brandl | 2009-04-01 23:06:30 +0200 (Mi, 01 Apr 2009) | 1 line Revert accidental checkin. ........ r71006 | georg.brandl | 2009-04-02 01:32:17 +0200 (Do, 02 Apr 2009) | 1 line Cache the f_locals dict of the current frame, since every access to frame.f_locals overrides its contents with the real locals which undoes modifications made by the debugging user. ........ r71019 | georg.brandl | 2009-04-02 04:00:01 +0200 (Do, 02 Apr 2009) | 1 line Fix test_doctest, missed two assignments to curframe. ........ r71024 | georg.brandl | 2009-04-02 04:47:44 +0200 (Do, 02 Apr 2009) | 4 lines In PyErr_GivenExceptionMatches, temporarily bump the recursion limit, so that in the most common case PyObject_IsSubclass will not raise a recursion error we have to ignore anyway. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Apr 5 23:24:58 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 5 Apr 2009 23:24:58 +0200 (CEST) Subject: [Python-checkins] r71274 - in python/branches/py3k: Doc/library/multiprocessing.rst Lib/multiprocessing/synchronize.py Lib/test/test_multiprocessing.py Modules/_multiprocessing/connection.h Modules/_multiprocessing/multiprocessing.c Modules/_multiprocessing/multiprocessing.h Modules/_multiprocessing/pipe_connection.c Modules/_multiprocessing/semaphore.c configure configure.in pyconfig.h.in setup.py Message-ID: <20090405212458.B56DE1E4078@bag.python.org> Author: benjamin.peterson Date: Sun Apr 5 23:24:58 2009 New Revision: 71274 Log: Merged revisions 70908,70939,71009,71022,71036 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70908 | jesse.noller | 2009-03-31 17:20:35 -0500 (Tue, 31 Mar 2009) | 1 line Issue 5619: Pass MS CRT debug flags into subprocesses ........ r70939 | jesse.noller | 2009-03-31 22:45:50 -0500 (Tue, 31 Mar 2009) | 1 line Fix multiprocessing.event to match the new threading.Event API ........ r71009 | jesse.noller | 2009-04-01 19:03:28 -0500 (Wed, 01 Apr 2009) | 1 line issue5545: Switch to Autoconf for multiprocessing; special thanks to Martin Lowis for help ........ r71022 | jesse.noller | 2009-04-01 21:32:55 -0500 (Wed, 01 Apr 2009) | 1 line Issue 3110: Additional protection for SEM_VALUE_MAX on platforms, thanks to Martin Loewis ........ r71036 | jesse.noller | 2009-04-01 23:22:09 -0500 (Wed, 01 Apr 2009) | 1 line Issue 3551: Raise ValueError if the size causes ERROR_NO_SYSTEM_RESOURCES ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/multiprocessing.rst python/branches/py3k/Lib/multiprocessing/synchronize.py python/branches/py3k/Lib/test/test_multiprocessing.py python/branches/py3k/Modules/_multiprocessing/connection.h python/branches/py3k/Modules/_multiprocessing/multiprocessing.c python/branches/py3k/Modules/_multiprocessing/multiprocessing.h python/branches/py3k/Modules/_multiprocessing/pipe_connection.c python/branches/py3k/Modules/_multiprocessing/semaphore.c python/branches/py3k/configure python/branches/py3k/configure.in python/branches/py3k/pyconfig.h.in python/branches/py3k/setup.py Modified: python/branches/py3k/Doc/library/multiprocessing.rst ============================================================================== --- python/branches/py3k/Doc/library/multiprocessing.rst (original) +++ python/branches/py3k/Doc/library/multiprocessing.rst Sun Apr 5 23:24:58 2009 @@ -708,7 +708,8 @@ Send an object to the other end of the connection which should be read using :meth:`recv`. - The object must be picklable. + The object must be picklable. Very large pickles (approximately 32 MB+, + though it depends on the OS) may raise a ValueError exception. .. method:: recv() @@ -740,7 +741,9 @@ complete message. If *offset* is given then data is read from that position in *buffer*. If - *size* is given then that many bytes will be read from buffer. + *size* is given then that many bytes will be read from buffer. Very large + buffers (approximately 32 MB+, though it depends on the OS) may raise a + ValueError exception .. method:: recv_bytes([maxlength]) @@ -834,6 +837,12 @@ .. class:: Event() A clone of :class:`threading.Event`. + This method returns the state of the internal semaphore on exit, so it + will always return ``True`` except if a timeout is given and the operation + times out. + + .. versionchanged:: 2.7 + Previously, the method always returned ``None``. .. class:: Lock() Modified: python/branches/py3k/Lib/multiprocessing/synchronize.py ============================================================================== --- python/branches/py3k/Lib/multiprocessing/synchronize.py (original) +++ python/branches/py3k/Lib/multiprocessing/synchronize.py Sun Apr 5 23:24:58 2009 @@ -301,5 +301,10 @@ self._flag.release() else: self._cond.wait(timeout) + + if self._flag.acquire(False): + self._flag.release() + return True + return False finally: self._cond.release() Modified: python/branches/py3k/Lib/test/test_multiprocessing.py ============================================================================== --- python/branches/py3k/Lib/test/test_multiprocessing.py (original) +++ python/branches/py3k/Lib/test/test_multiprocessing.py Sun Apr 5 23:24:58 2009 @@ -750,20 +750,22 @@ # Removed temporaily, due to API shear, this does not # work with threading._Event objects. is_set == isSet - #self.assertEqual(event.is_set(), False) + self.assertEqual(event.is_set(), False) - self.assertEqual(wait(0.0), None) + # Removed, threading.Event.wait() will return the value of the __flag + # instead of None. API Shear with the semaphore backed mp.Event + self.assertEqual(wait(0.0), False) self.assertTimingAlmostEqual(wait.elapsed, 0.0) - self.assertEqual(wait(TIMEOUT1), None) + self.assertEqual(wait(TIMEOUT1), False) self.assertTimingAlmostEqual(wait.elapsed, TIMEOUT1) event.set() # See note above on the API differences - # self.assertEqual(event.is_set(), True) - self.assertEqual(wait(), None) + self.assertEqual(event.is_set(), True) + self.assertEqual(wait(), True) self.assertTimingAlmostEqual(wait.elapsed, 0.0) - self.assertEqual(wait(TIMEOUT1), None) + self.assertEqual(wait(TIMEOUT1), True) self.assertTimingAlmostEqual(wait.elapsed, 0.0) # self.assertEqual(event.is_set(), True) @@ -772,7 +774,7 @@ #self.assertEqual(event.is_set(), False) self.Process(target=self._test_event, args=(event,)).start() - self.assertEqual(wait(), None) + self.assertEqual(wait(), True) # # Modified: python/branches/py3k/Modules/_multiprocessing/connection.h ============================================================================== --- python/branches/py3k/Modules/_multiprocessing/connection.h (original) +++ python/branches/py3k/Modules/_multiprocessing/connection.h Sun Apr 5 23:24:58 2009 @@ -139,8 +139,12 @@ res = conn_send_string(self, buffer + offset, size); PyBuffer_Release(&pbuffer); - if (res < 0) - return mp_SetError(PyExc_IOError, res); + if (res < 0) { + if (PyErr_Occurred()) + return NULL; + else + return mp_SetError(PyExc_IOError, res); + } Py_RETURN_NONE; } Modified: python/branches/py3k/Modules/_multiprocessing/multiprocessing.c ============================================================================== --- python/branches/py3k/Modules/_multiprocessing/multiprocessing.c (original) +++ python/branches/py3k/Modules/_multiprocessing/multiprocessing.c Sun Apr 5 23:24:58 2009 @@ -8,6 +8,12 @@ #include "multiprocessing.h" +#ifdef SCM_RIGHTS + #define HAVE_FD_TRANSFER 1 +#else + #define HAVE_FD_TRANSFER 0 +#endif + PyObject *create_win32_namespace(void); PyObject *pickle_dumps, *pickle_loads, *pickle_protocol; @@ -257,7 +263,7 @@ Py_INCREF(&ConnectionType); PyModule_AddObject(module, "Connection", (PyObject*)&ConnectionType); -#if defined(MS_WINDOWS) || HAVE_SEM_OPEN +#if defined(MS_WINDOWS) || defined(HAVE_SEM_OPEN) /* Add SemLock type to module */ if (PyType_Ready(&SemLockType) < 0) return NULL; Modified: python/branches/py3k/Modules/_multiprocessing/multiprocessing.h ============================================================================== --- python/branches/py3k/Modules/_multiprocessing/multiprocessing.h (original) +++ python/branches/py3k/Modules/_multiprocessing/multiprocessing.h Sun Apr 5 23:24:58 2009 @@ -27,7 +27,7 @@ # include # include # include /* htonl() and ntohl() */ -# if HAVE_SEM_OPEN +# ifdef HAVE_SEM_OPEN # include typedef sem_t *SEM_HANDLE; # endif @@ -45,13 +45,18 @@ * Issue 3110 - Solaris does not define SEM_VALUE_MAX */ #ifndef SEM_VALUE_MAX -# ifdef _SEM_VALUE_MAX -# define SEM_VALUE_MAX _SEM_VALUE_MAX -# else -# define SEM_VALUE_MAX INT_MAX -# endif + #if defined(HAVE_SYSCONF) && defined(_SC_SEM_VALUE_MAX) + # define SEM_VALUE_MAX sysconf(_SC_SEM_VALUE_MAX) + #elif defined(_SEM_VALUE_MAX) + # define SEM_VALUE_MAX _SEM_VALUE_MAX + #elif definef(_POSIX_SEM_VALUE_MAX) + # define SEM_VALUE_MAX _POSIX_SEM_VALUE_MAX + #else + # define SEM_VALUE_MAX INT_MAX + #endif #endif + /* * Make sure Py_ssize_t available */ Modified: python/branches/py3k/Modules/_multiprocessing/pipe_connection.c ============================================================================== --- python/branches/py3k/Modules/_multiprocessing/pipe_connection.c (original) +++ python/branches/py3k/Modules/_multiprocessing/pipe_connection.c Sun Apr 5 23:24:58 2009 @@ -23,6 +23,12 @@ Py_BEGIN_ALLOW_THREADS ret = WriteFile(conn->handle, string, length, &amount_written, NULL); Py_END_ALLOW_THREADS + + if (ret == 0 && GetLastError() == ERROR_NO_SYSTEM_RESOURCES) { + PyErr_Format(PyExc_ValueError, "Cannnot send %" PY_FORMAT_SIZE_T "d bytes over connection", length); + return MP_STANDARD_ERROR; + } + return ret ? MP_SUCCESS : MP_STANDARD_ERROR; } Modified: python/branches/py3k/Modules/_multiprocessing/semaphore.c ============================================================================== --- python/branches/py3k/Modules/_multiprocessing/semaphore.c (original) +++ python/branches/py3k/Modules/_multiprocessing/semaphore.c Sun Apr 5 23:24:58 2009 @@ -197,11 +197,11 @@ #define SEM_GETVALUE(sem, pval) sem_getvalue(sem, pval) #define SEM_UNLINK(name) sem_unlink(name) -#if HAVE_BROKEN_SEM_UNLINK +#ifndef HAVE_SEM_UNLINK # define sem_unlink(name) 0 #endif -#if !HAVE_SEM_TIMEDWAIT +#ifndef HAVE_SEM_TIMEDWAIT # define sem_timedwait(sem,deadline) sem_timedwait_save(sem,deadline,_save) int @@ -348,7 +348,7 @@ } assert(self->count == 1); } else { -#if HAVE_BROKEN_SEM_GETVALUE +#ifdef HAVE_BROKEN_SEM_GETVALUE /* We will only check properly the maxvalue == 1 case */ if (self->maxvalue == 1) { /* make sure that already locked */ @@ -494,7 +494,7 @@ static PyObject * semlock_getvalue(SemLockObject *self) { -#if HAVE_BROKEN_SEM_GETVALUE +#ifdef HAVE_BROKEN_SEM_GETVALUE PyErr_SetNone(PyExc_NotImplementedError); return NULL; #else @@ -512,7 +512,7 @@ static PyObject * semlock_iszero(SemLockObject *self) { -#if HAVE_BROKEN_SEM_GETVALUE +#ifdef HAVE_BROKEN_SEM_GETVALUE if (sem_trywait(self->handle) < 0) { if (errno == EAGAIN) Py_RETURN_TRUE; Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Sun Apr 5 23:24:58 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 70732 . +# From configure.in Revision: 71261 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.1. # @@ -16264,6 +16264,10 @@ + + + + for ac_func in alarm setitimer getitimer bind_textdomain_codeset chown \ clock confstr ctermid execv fchmod fchown fork fpathconf ftime ftruncate \ gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \ @@ -16271,7 +16275,8 @@ kill killpg lchmod lchown lstat mkfifo mknod mktime \ mremap nice pathconf pause plock poll pthread_init \ putenv readlink realpath \ - select setegid seteuid setgid \ + select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ + setgid \ setlocale setregid setreuid setsid setpgid setpgrp setuid setvbuf snprintf \ sigaction siginterrupt sigrelse strftime strlcpy \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ @@ -21692,6 +21697,86 @@ fi +# Multiprocessing check for broken sem_getvalue +{ echo "$as_me:$LINENO: checking for broken sem_getvalue" >&5 +echo $ECHO_N "checking for broken sem_getvalue... $ECHO_C" >&6; } +if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +#include +#include +#include + +int main(void){ + sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + int count; + int res; + if(a==SEM_FAILED){ + perror("sem_open"); + return 1; + + } + res = sem_getvalue(a, &count); + sem_close(a); + return res==-1 ? 1 : 0; +} + + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_BROKEN_SEM_GETVALUE 1 +_ACEOF + + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + # On FreeBSD 6.2, it appears that tanh(-0.) returns 0. instead of # -0. on some architectures. Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Sun Apr 5 23:24:58 2009 @@ -2388,7 +2388,8 @@ kill killpg lchmod lchown lstat mkfifo mknod mktime \ mremap nice pathconf pause plock poll pthread_init \ putenv readlink realpath \ - select setegid seteuid setgid \ + select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ + setgid \ setlocale setregid setreuid setsid setpgid setpgrp setuid setvbuf snprintf \ sigaction siginterrupt sigrelse strftime strlcpy \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ @@ -3108,6 +3109,33 @@ [Define if arithmetic is subject to x87-style double rounding issue]) fi +# Multiprocessing check for broken sem_getvalue +AC_MSG_CHECKING(for broken sem_getvalue) +AC_TRY_RUN([ +#include +#include +#include +#include +#include + +int main(void){ + sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + int count; + int res; + if(a==SEM_FAILED){ + perror("sem_open"); + return 1; + + } + res = sem_getvalue(a, &count); + sem_close(a); + return res==-1 ? 1 : 0; +} +] +,AC_MSG_RESULT(no), + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BROKEN_SEM_GETVALUE, 1, define to 1 if your sem_getvalue is broken.) +) # On FreeBSD 6.2, it appears that tanh(-0.) returns 0. instead of # -0. on some architectures. Modified: python/branches/py3k/pyconfig.h.in ============================================================================== --- python/branches/py3k/pyconfig.h.in (original) +++ python/branches/py3k/pyconfig.h.in Sun Apr 5 23:24:58 2009 @@ -74,6 +74,9 @@ /* Define if pthread_sigmask() does not work on your system. */ #undef HAVE_BROKEN_PTHREAD_SIGMASK +/* define to 1 if your sem_getvalue is broken. */ +#undef HAVE_BROKEN_SEM_GETVALUE + /* Define this if you have the type _Bool. */ #undef HAVE_C99_BOOL @@ -505,6 +508,18 @@ /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT +/* Define to 1 if you have the `sem_getvalue' function. */ +#undef HAVE_SEM_GETVALUE + +/* Define to 1 if you have the `sem_open' function. */ +#undef HAVE_SEM_OPEN + +/* Define to 1 if you have the `sem_timedwait' function. */ +#undef HAVE_SEM_TIMEDWAIT + +/* Define to 1 if you have the `sem_unlink' function. */ +#undef HAVE_SEM_UNLINK + /* Define to 1 if you have the `setegid' function. */ #undef HAVE_SETEGID Modified: python/branches/py3k/setup.py ============================================================================== --- python/branches/py3k/setup.py (original) +++ python/branches/py3k/setup.py Sun Apr 5 23:24:58 2009 @@ -988,56 +988,29 @@ libraries = ['ws2_32'] elif platform == 'darwin': # Mac OSX - macros = dict( - HAVE_SEM_OPEN=1, - HAVE_SEM_TIMEDWAIT=0, - HAVE_FD_TRANSFER=1, - HAVE_BROKEN_SEM_GETVALUE=1 - ) + macros = dict() libraries = [] elif platform == 'cygwin': # Cygwin - macros = dict( - HAVE_SEM_OPEN=1, - HAVE_SEM_TIMEDWAIT=1, - HAVE_FD_TRANSFER=0, - HAVE_BROKEN_SEM_UNLINK=1 - ) + macros = dict() libraries = [] elif platform in ('freebsd4', 'freebsd5', 'freebsd6', 'freebsd7', 'freebsd8'): # FreeBSD's P1003.1b semaphore support is very experimental # and has many known problems. (as of June 2008) - macros = dict( # FreeBSD - HAVE_SEM_OPEN=0, - HAVE_SEM_TIMEDWAIT=0, - HAVE_FD_TRANSFER=1, - ) + macros = dict() libraries = [] elif platform.startswith('openbsd'): - macros = dict( # OpenBSD - HAVE_SEM_OPEN=0, # Not implemented - HAVE_SEM_TIMEDWAIT=0, - HAVE_FD_TRANSFER=1, - ) + macros = dict() libraries = [] elif platform.startswith('netbsd'): - macros = dict( # at least NetBSD 5 - HAVE_SEM_OPEN=1, - HAVE_SEM_TIMEDWAIT=0, - HAVE_FD_TRANSFER=1, - HAVE_BROKEN_SEM_GETVALUE=1 - ) + macros = dict() libraries = [] else: # Linux and other unices - macros = dict( - HAVE_SEM_OPEN=1, - HAVE_SEM_TIMEDWAIT=1, - HAVE_FD_TRANSFER=1 - ) + macros = dict() libraries = ['rt'] if platform == 'win32': @@ -1052,8 +1025,7 @@ multiprocessing_srcs = [ '_multiprocessing/multiprocessing.c', '_multiprocessing/socket_connection.c' ] - - if macros.get('HAVE_SEM_OPEN', False): + if sysconfig.get_config_var('HAVE_SEM_OPEN'): multiprocessing_srcs.append('_multiprocessing/semaphore.c') if sysconfig.get_config_var('WITH_THREAD'): From python-checkins at python.org Sun Apr 5 23:26:32 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 23:26:32 +0200 (CEST) Subject: [Python-checkins] r71275 - in python/branches/release26-maint: Doc/c-api/init.rst Doc/distutils/apiref.rst Doc/library/_winreg.rst Doc/library/basehttpserver.rst Doc/library/multiprocessing.rst Doc/library/os.path.rst Doc/library/os.rst Doc/library/pickle.rst Doc/library/shelve.rst Doc/library/socketserver.rst Doc/library/webbrowser.rst Doc/make.bat Lib/plistlib.py Lib/posixpath.py Lib/test/test_posixpath.py Lib/test/test_traceback.py Lib/traceback.py Misc/NEWS Modules/_sqlite/connection.c Modules/_sqlite/module.c Objects/bytearrayobject.c Objects/object.c Python/errors.c Python/getargs.c Message-ID: <20090405212632.8A3641E4078@bag.python.org> Author: georg.brandl Date: Sun Apr 5 23:26:31 2009 New Revision: 71275 Log: Merged revisions 71058,71149-71150,71212,71214-71216,71222,71225,71234,71237-71238,71240-71241,71243,71249,71251 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71058 | georg.brandl | 2009-04-02 20:09:04 +0200 (Do, 02 Apr 2009) | 3 lines PyErr_NormalizeException may not set an error, so convert the PyErr_SetObject call on hitting the recursion limit into just assigning it to the arguments provided. ........ r71149 | georg.brandl | 2009-04-04 15:42:39 +0200 (Sa, 04 Apr 2009) | 1 line #5642: clarify map() compatibility to the builtin. ........ r71150 | georg.brandl | 2009-04-04 15:45:49 +0200 (Sa, 04 Apr 2009) | 1 line #5601: clarify that webbrowser is not meant for file names. ........ r71212 | georg.brandl | 2009-04-05 12:24:20 +0200 (So, 05 Apr 2009) | 1 line #1742837: expand HTTP server docs, and fix SocketServer ones to document methods as methods, not functions. ........ r71214 | georg.brandl | 2009-04-05 12:29:57 +0200 (So, 05 Apr 2009) | 1 line Normalize spelling of Mac OS X. ........ r71215 | georg.brandl | 2009-04-05 12:32:26 +0200 (So, 05 Apr 2009) | 1 line Avoid sure signs of a diseased mind. ........ r71216 | georg.brandl | 2009-04-05 12:41:02 +0200 (So, 05 Apr 2009) | 1 line #1718017: document the relation of os.path and the posixpath, ntpath etc. modules better. ........ r71222 | georg.brandl | 2009-04-05 13:07:14 +0200 (So, 05 Apr 2009) | 1 line #5615: make it possible to configure --without-threads again. ........ r71225 | georg.brandl | 2009-04-05 13:54:07 +0200 (So, 05 Apr 2009) | 1 line #5580: no need to use parentheses when converterr() argument is actually a type description. ........ r71234 | georg.brandl | 2009-04-05 15:16:35 +0200 (So, 05 Apr 2009) | 1 line Whitespace normalization. ........ r71237 | georg.brandl | 2009-04-05 16:24:52 +0200 (So, 05 Apr 2009) | 1 line #1326077: fix traceback formatting of SyntaxErrors. This fixes two differences with formatting coming from Python: a) the reproduction of location details in the error message if no line text is given, b) the prefixing of the last line by one space. ........ r71238 | georg.brandl | 2009-04-05 16:25:41 +0200 (So, 05 Apr 2009) | 1 line Add NEWS entry for r71237. ........ r71240 | georg.brandl | 2009-04-05 16:40:06 +0200 (So, 05 Apr 2009) | 1 line #5370: doc update about unpickling objects with custom __getattr__ etc. methods. ........ r71241 | georg.brandl | 2009-04-05 16:48:49 +0200 (So, 05 Apr 2009) | 1 line #5471: fix expanduser() for $HOME set to "/". ........ r71243 | georg.brandl | 2009-04-05 17:14:29 +0200 (So, 05 Apr 2009) | 1 line #5432: make plistlib docstring a raw string, since it contains examples with backslash escapes. ........ r71249 | georg.brandl | 2009-04-05 18:30:43 +0200 (So, 05 Apr 2009) | 1 line #5444: adapt make.bat to new htmlhelp output file name. ........ r71251 | georg.brandl | 2009-04-05 19:17:42 +0200 (So, 05 Apr 2009) | 1 line #5298: clarify docs about GIL by using more consistent wording. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/c-api/init.rst python/branches/release26-maint/Doc/distutils/apiref.rst python/branches/release26-maint/Doc/library/_winreg.rst python/branches/release26-maint/Doc/library/basehttpserver.rst python/branches/release26-maint/Doc/library/multiprocessing.rst python/branches/release26-maint/Doc/library/os.path.rst python/branches/release26-maint/Doc/library/os.rst python/branches/release26-maint/Doc/library/pickle.rst python/branches/release26-maint/Doc/library/shelve.rst python/branches/release26-maint/Doc/library/socketserver.rst python/branches/release26-maint/Doc/library/webbrowser.rst python/branches/release26-maint/Doc/make.bat python/branches/release26-maint/Lib/plistlib.py python/branches/release26-maint/Lib/posixpath.py python/branches/release26-maint/Lib/test/test_posixpath.py python/branches/release26-maint/Lib/test/test_traceback.py python/branches/release26-maint/Lib/traceback.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Modules/_sqlite/connection.c python/branches/release26-maint/Modules/_sqlite/module.c python/branches/release26-maint/Objects/bytearrayobject.c python/branches/release26-maint/Objects/object.c python/branches/release26-maint/Python/errors.c python/branches/release26-maint/Python/getargs.c Modified: python/branches/release26-maint/Doc/c-api/init.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/init.rst (original) +++ python/branches/release26-maint/Doc/c-api/init.rst Sun Apr 5 23:26:31 2009 @@ -394,12 +394,12 @@ single: lock, interpreter The Python interpreter is not fully thread safe. In order to support -multi-threaded Python programs, there's a global lock that must be held by the -current thread before it can safely access Python objects. Without the lock, -even the simplest operations could cause problems in a multi-threaded program: -for example, when two threads simultaneously increment the reference count of -the same object, the reference count could end up being incremented only once -instead of twice. +multi-threaded Python programs, there's a global lock, called the :dfn:`global +interpreter lock` or :dfn:`GIL`, that must be held by the current thread before +it can safely access Python objects. Without the lock, even the simplest +operations could cause problems in a multi-threaded program: for example, when +two threads simultaneously increment the reference count of the same object, the +reference count could end up being incremented only once instead of twice. .. index:: single: setcheckinterval() (in module sys) @@ -428,9 +428,9 @@ interpreter lock has the following simple structure:: Save the thread state in a local variable. - Release the interpreter lock. + Release the global interpreter lock. ...Do some blocking I/O operation... - Reacquire the interpreter lock. + Reacquire the global interpreter lock. Restore the thread state from the local variable. This is so common that a pair of macros exists to simplify it:: @@ -447,7 +447,7 @@ hidden local variable; the :cmacro:`Py_END_ALLOW_THREADS` macro closes the block. Another advantage of using these two macros is that when Python is compiled without thread support, they are defined empty, thus saving the thread -state and lock manipulations. +state and GIL manipulations. When thread support is enabled, the block above expands to the following code:: @@ -479,7 +479,7 @@ saves and restores the value of the global variable :cdata:`errno`, since the lock manipulation does not guarantee that :cdata:`errno` is left alone. Also, when thread support is disabled, :cfunc:`PyEval_SaveThread` and -:cfunc:`PyEval_RestoreThread` don't manipulate the lock; in this case, +:cfunc:`PyEval_RestoreThread` don't manipulate the GIL; in this case, :cfunc:`PyEval_ReleaseLock` and :cfunc:`PyEval_AcquireLock` are not available. This is done so that dynamically loaded extensions compiled with thread support enabled can be loaded by an interpreter that was compiled with disabled thread @@ -562,16 +562,16 @@ .. index:: module: thread - When only the main thread exists, no lock operations are needed. This is a + When only the main thread exists, no GIL operations are needed. This is a common situation (most Python programs do not use threads), and the lock - operations slow the interpreter down a bit. Therefore, the lock is not created - initially. This situation is equivalent to having acquired the lock: when - there is only a single thread, all object accesses are safe. Therefore, when - this function initializes the lock, it also acquires it. Before the Python - :mod:`thread` module creates a new thread, knowing that either it has the lock - or the lock hasn't been created yet, it calls :cfunc:`PyEval_InitThreads`. When - this call returns, it is guaranteed that the lock has been created and that the - calling thread has acquired it. + operations slow the interpreter down a bit. Therefore, the lock is not + created initially. This situation is equivalent to having acquired the lock: + when there is only a single thread, all object accesses are safe. Therefore, + when this function initializes the global interpreter lock, it also acquires + it. Before the Python :mod:`thread` module creates a new thread, knowing + that either it has the lock or the lock hasn't been created yet, it calls + :cfunc:`PyEval_InitThreads`. When this call returns, it is guaranteed that + the lock has been created and that the calling thread has acquired it. It is **not** safe to call this function when it is unknown which thread (if any) currently has the global interpreter lock. @@ -582,7 +582,7 @@ .. cfunction:: int PyEval_ThreadsInitialized() Returns a non-zero value if :cfunc:`PyEval_InitThreads` has been called. This - function can be called without holding the lock, and therefore can be used to + function can be called without holding the GIL, and therefore can be used to avoid calls to the locking API when running single-threaded. This function is not available when thread support is disabled at compile time. @@ -622,20 +622,20 @@ .. cfunction:: PyThreadState* PyEval_SaveThread() - Release the interpreter lock (if it has been created and thread support is - enabled) and reset the thread state to *NULL*, returning the previous thread - state (which is not *NULL*). If the lock has been created, the current thread - must have acquired it. (This function is available even when thread support is - disabled at compile time.) + Release the global interpreter lock (if it has been created and thread + support is enabled) and reset the thread state to *NULL*, returning the + previous thread state (which is not *NULL*). If the lock has been created, + the current thread must have acquired it. (This function is available even + when thread support is disabled at compile time.) .. cfunction:: void PyEval_RestoreThread(PyThreadState *tstate) - Acquire the interpreter lock (if it has been created and thread support is - enabled) and set the thread state to *tstate*, which must not be *NULL*. If the - lock has been created, the current thread must not have acquired it, otherwise - deadlock ensues. (This function is available even when thread support is - disabled at compile time.) + Acquire the global interpreter lock (if it has been created and thread + support is enabled) and set the thread state to *tstate*, which must not be + *NULL*. If the lock has been created, the current thread must not have + acquired it, otherwise deadlock ensues. (This function is available even + when thread support is disabled at compile time.) .. cfunction:: void PyEval_ReInitThreads() @@ -679,60 +679,61 @@ declaration. It is a no-op when thread support is disabled at compile time. All of the following functions are only available when thread support is enabled -at compile time, and must be called only when the interpreter lock has been -created. +at compile time, and must be called only when the global interpreter lock has +been created. .. cfunction:: PyInterpreterState* PyInterpreterState_New() - Create a new interpreter state object. The interpreter lock need not be held, - but may be held if it is necessary to serialize calls to this function. + Create a new interpreter state object. The global interpreter lock need not + be held, but may be held if it is necessary to serialize calls to this + function. .. cfunction:: void PyInterpreterState_Clear(PyInterpreterState *interp) - Reset all information in an interpreter state object. The interpreter lock must - be held. + Reset all information in an interpreter state object. The global interpreter + lock must be held. .. cfunction:: void PyInterpreterState_Delete(PyInterpreterState *interp) - Destroy an interpreter state object. The interpreter lock need not be held. - The interpreter state must have been reset with a previous call to + Destroy an interpreter state object. The global interpreter lock need not be + held. The interpreter state must have been reset with a previous call to :cfunc:`PyInterpreterState_Clear`. .. cfunction:: PyThreadState* PyThreadState_New(PyInterpreterState *interp) - Create a new thread state object belonging to the given interpreter object. The - interpreter lock need not be held, but may be held if it is necessary to - serialize calls to this function. + Create a new thread state object belonging to the given interpreter object. + The global interpreter lock need not be held, but may be held if it is + necessary to serialize calls to this function. .. cfunction:: void PyThreadState_Clear(PyThreadState *tstate) - Reset all information in a thread state object. The interpreter lock must be - held. + Reset all information in a thread state object. The global interpreter lock + must be held. .. cfunction:: void PyThreadState_Delete(PyThreadState *tstate) - Destroy a thread state object. The interpreter lock need not be held. The - thread state must have been reset with a previous call to + Destroy a thread state object. The global interpreter lock need not be held. + The thread state must have been reset with a previous call to :cfunc:`PyThreadState_Clear`. .. cfunction:: PyThreadState* PyThreadState_Get() - Return the current thread state. The interpreter lock must be held. When the - current thread state is *NULL*, this issues a fatal error (so that the caller - needn't check for *NULL*). + Return the current thread state. The global interpreter lock must be held. + When the current thread state is *NULL*, this issues a fatal error (so that + the caller needn't check for *NULL*). .. cfunction:: PyThreadState* PyThreadState_Swap(PyThreadState *tstate) Swap the current thread state with the thread state given by the argument - *tstate*, which may be *NULL*. The interpreter lock must be held. + *tstate*, which may be *NULL*. The global interpreter lock must be held. .. cfunction:: PyObject* PyThreadState_GetDict() @@ -763,14 +764,15 @@ .. cfunction:: PyGILState_STATE PyGILState_Ensure() - Ensure that the current thread is ready to call the Python C API regardless of - the current state of Python, or of its thread lock. This may be called as many - times as desired by a thread as long as each call is matched with a call to - :cfunc:`PyGILState_Release`. In general, other thread-related APIs may be used - between :cfunc:`PyGILState_Ensure` and :cfunc:`PyGILState_Release` calls as long - as the thread state is restored to its previous state before the Release(). For - example, normal usage of the :cmacro:`Py_BEGIN_ALLOW_THREADS` and - :cmacro:`Py_END_ALLOW_THREADS` macros is acceptable. + Ensure that the current thread is ready to call the Python C API regardless + of the current state of Python, or of the global interpreter lock. This may + be called as many times as desired by a thread as long as each call is + matched with a call to :cfunc:`PyGILState_Release`. In general, other + thread-related APIs may be used between :cfunc:`PyGILState_Ensure` and + :cfunc:`PyGILState_Release` calls as long as the thread state is restored to + its previous state before the Release(). For example, normal usage of the + :cmacro:`Py_BEGIN_ALLOW_THREADS` and :cmacro:`Py_END_ALLOW_THREADS` macros is + acceptable. The return value is an opaque "handle" to the thread state when :cfunc:`PyGILState_Ensure` was called, and must be passed to Modified: python/branches/release26-maint/Doc/distutils/apiref.rst ============================================================================== --- python/branches/release26-maint/Doc/distutils/apiref.rst (original) +++ python/branches/release26-maint/Doc/distutils/apiref.rst Sun Apr 5 23:26:31 2009 @@ -1067,8 +1067,8 @@ .. warning:: - Handles cross-device moves on Unix using :func:`copy_file`. What about other - systems??? + Handles cross-device moves on Unix using :func:`copy_file`. What about + other systems? .. function:: write_file(filename, contents) @@ -1108,17 +1108,17 @@ For non-POSIX platforms, currently just returns ``sys.platform``. - For MacOS X systems the OS version reflects the minimal version on which + For Mac OS X systems the OS version reflects the minimal version on which binaries will run (that is, the value of ``MACOSX_DEPLOYMENT_TARGET`` during the build of Python), not the OS version of the current system. - For universal binary builds on MacOS X the architecture value reflects + For universal binary builds on Mac OS X the architecture value reflects the univeral binary status instead of the architecture of the current processor. For 32-bit universal binaries the architecture is ``fat``, for 64-bit universal binaries the architecture is ``fat64``, and for 4-way universal binaries the architecture is ``universal``. - Examples of returned values on MacOS X: + Examples of returned values on Mac OS X: * ``macosx-10.3-ppc`` Modified: python/branches/release26-maint/Doc/library/_winreg.rst ============================================================================== --- python/branches/release26-maint/Doc/library/_winreg.rst (original) +++ python/branches/release26-maint/Doc/library/_winreg.rst Sun Apr 5 23:26:31 2009 @@ -252,9 +252,10 @@ associated. If this parameter is ``None`` or empty, the function retrieves the value set by the :func:`SetValue` method for the key identified by *key*. - Values in the registry have name, type, and data components. This method + Values in the registry have name, type, and data components. This method retrieves the data for a key's first value that has a NULL name. But the - underlying API call doesn't return the type, Lame Lame Lame, DO NOT USE THIS!!! + underlying API call doesn't return the type, so always use + :func:`QueryValueEx` if possible. .. function:: QueryValueEx(key, value_name) Modified: python/branches/release26-maint/Doc/library/basehttpserver.rst ============================================================================== --- python/branches/release26-maint/Doc/library/basehttpserver.rst (original) +++ python/branches/release26-maint/Doc/library/basehttpserver.rst Sun Apr 5 23:26:31 2009 @@ -15,8 +15,6 @@ pair: HTTP; protocol single: URL single: httpd - -.. index:: module: SimpleHTTPServer module: CGIHTTPServer @@ -26,7 +24,8 @@ :mod:`CGIHTTPServer` modules. The first class, :class:`HTTPServer`, is a :class:`SocketServer.TCPServer` -subclass. It creates and listens at the HTTP socket, dispatching the requests +subclass, and therefore implements the :class:`SocketServer.BaseServer` +interface. It creates and listens at the HTTP socket, dispatching the requests to a handler. Code to create and run the server looks like this:: def run(server_class=BaseHTTPServer.HTTPServer, @@ -269,12 +268,31 @@ performed on the client's IP address. +More examples +------------- + +To create a server that doesn't run forever, but until some condition is +fulfilled:: + + def run_while_true(server_class=BaseHTTPServer.HTTPServer, + handler_class=BaseHTTPServer.BaseHTTPRequestHandler): + """ + This assumes that keep_running() is a function of no arguments which + is tested initially and after each request. If its return value + is true, the server continues. + """ + server_address = ('', 8000) + httpd = server_class(server_address, handler_class) + while keep_running(): + httpd.handle_request() + + .. seealso:: Module :mod:`CGIHTTPServer` Extended request handler that supports CGI scripts. Module :mod:`SimpleHTTPServer` - Basic request handler that limits response to files actually under the document - root. + Basic request handler that limits response to files actually under the + document root. Modified: python/branches/release26-maint/Doc/library/multiprocessing.rst ============================================================================== --- python/branches/release26-maint/Doc/library/multiprocessing.rst (original) +++ python/branches/release26-maint/Doc/library/multiprocessing.rst Sun Apr 5 23:26:31 2009 @@ -1537,8 +1537,8 @@ .. method:: map(func, iterable[, chunksize]) - A parallel equivalent of the :func:`map` builtin function. It blocks till - the result is ready. + A parallel equivalent of the :func:`map` builtin function (it supports only + one *iterable* argument though). It blocks till the result is ready. This method chops the iterable into a number of chunks which it submits to the process pool as separate tasks. The (approximate) size of these Modified: python/branches/release26-maint/Doc/library/os.path.rst ============================================================================== --- python/branches/release26-maint/Doc/library/os.path.rst (original) +++ python/branches/release26-maint/Doc/library/os.path.rst Sun Apr 5 23:26:31 2009 @@ -1,11 +1,9 @@ - :mod:`os.path` --- Common pathname manipulations ================================================ .. module:: os.path :synopsis: Operations on pathnames. - .. index:: single: path; operations This module implements some useful functions on pathnames. To read or @@ -18,6 +16,22 @@ :func:`splitunc` and :func:`ismount` do handle them correctly. +.. note:: + + Since different operating systems have different path name conventions, there + are several versions of this module in the standard library. The + :mod:`os.path` module is always the path module suitable for the operating + system Python is running on, and therefore usable for local paths. However, + you can also import and use the individual modules if you want to manipulate + a path that is *always* in one of the different formats. They all have the + same interface: + + * :mod:`posixpath` for UNIX-style paths + * :mod:`ntpath` for Windows paths + * :mod:`macpath` for old-style MacOS paths + * :mod:`os2emxpath` for OS/2 EMX paths + + .. function:: abspath(path) Return a normalized absolutized version of the pathname *path*. On most @@ -190,9 +204,9 @@ .. function:: normcase(path) - Normalize the case of a pathname. On Unix and MacOSX, this returns the path unchanged; on - case-insensitive filesystems, it converts the path to lowercase. On Windows, it - also converts forward slashes to backward slashes. + Normalize the case of a pathname. On Unix and Mac OS X, this returns the + path unchanged; on case-insensitive filesystems, it converts the path to + lowercase. On Windows, it also converts forward slashes to backward slashes. .. function:: normpath(path) Modified: python/branches/release26-maint/Doc/library/os.rst ============================================================================== --- python/branches/release26-maint/Doc/library/os.rst (original) +++ python/branches/release26-maint/Doc/library/os.rst Sun Apr 5 23:26:31 2009 @@ -46,15 +46,6 @@ ``'ce'``, ``'java'``, ``'riscos'``. -.. data:: path - - The corresponding operating system dependent standard module for pathname - operations, such as :mod:`posixpath` or :mod:`ntpath`. Thus, given the proper - imports, ``os.path.split(file)`` is equivalent to but more portable than - ``posixpath.split(file)``. Note that this is also an importable module: it may - be imported directly as :mod:`os.path`. - - .. _os-procinfo: Process Parameters Modified: python/branches/release26-maint/Doc/library/pickle.rst ============================================================================== --- python/branches/release26-maint/Doc/library/pickle.rst (original) +++ python/branches/release26-maint/Doc/library/pickle.rst Sun Apr 5 23:26:31 2009 @@ -458,6 +458,15 @@ For :term:`new-style class`\es, if :meth:`__getstate__` returns a false value, the :meth:`__setstate__` method will not be called. +.. note:: + + At unpickling time, some methods like :meth:`__getattr__`, + :meth:`__getattribute__`, or :meth:`__setattr__` may be called upon the + instance. In case those methods rely on some internal invariant being + true, the type should implement either :meth:`__getinitargs__` or + :meth:`__getnewargs__` to establish such an invariant; otherwise, neither + :meth:`__new__` nor :meth:`__init__` will be called. + Pickling and unpickling extension types ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Modified: python/branches/release26-maint/Doc/library/shelve.rst ============================================================================== --- python/branches/release26-maint/Doc/library/shelve.rst (original) +++ python/branches/release26-maint/Doc/library/shelve.rst Sun Apr 5 23:26:31 2009 @@ -148,7 +148,7 @@ # as d was opened WITHOUT writeback=True, beware: d['xx'] = range(4) # this works as expected, but... - d['xx'].append(5) # *this doesn't!* -- d['xx'] is STILL range(4)!!! + d['xx'].append(5) # *this doesn't!* -- d['xx'] is STILL range(4)! # having opened d without writeback=True, you need to code carefully: temp = d['xx'] # extracts the copy Modified: python/branches/release26-maint/Doc/library/socketserver.rst ============================================================================== --- python/branches/release26-maint/Doc/library/socketserver.rst (original) +++ python/branches/release26-maint/Doc/library/socketserver.rst Sun Apr 5 23:26:31 2009 @@ -129,15 +129,21 @@ Server Objects -------------- +.. class:: BaseServer -.. function:: fileno() + This is the superclass of all Server objects in the module. It defines the + interface, given below, but does not implement most of the methods, which is + done in subclasses. + + +.. method:: BaseServer.fileno() Return an integer file descriptor for the socket on which the server is listening. This function is most commonly passed to :func:`select.select`, to allow monitoring multiple servers in the same process. -.. function:: handle_request() +.. method:: BaseServer.handle_request() Process a single request. This function calls the following methods in order: :meth:`get_request`, :meth:`verify_request`, and @@ -148,32 +154,32 @@ will return. -.. function:: serve_forever(poll_interval=0.5) +.. method:: BaseServer.serve_forever(poll_interval=0.5) Handle requests until an explicit :meth:`shutdown` request. Polls for shutdown every *poll_interval* seconds. -.. function:: shutdown() +.. method:: BaseServer.shutdown() Tells the :meth:`serve_forever` loop to stop and waits until it does. .. versionadded:: 2.6 -.. data:: address_family +.. attribute:: BaseServer.address_family The family of protocols to which the server's socket belongs. Common examples are :const:`socket.AF_INET` and :const:`socket.AF_UNIX`. -.. data:: RequestHandlerClass +.. attribute:: BaseServer.RequestHandlerClass The user-provided request handler class; an instance of this class is created for each request. -.. data:: server_address +.. attribute:: BaseServer.server_address The address on which the server is listening. The format of addresses varies depending on the protocol family; see the documentation for the socket module @@ -181,22 +187,22 @@ the address, and an integer port number: ``('127.0.0.1', 80)``, for example. -.. data:: socket +.. attribute:: BaseServer.socket The socket object on which the server will listen for incoming requests. + The server classes support the following class variables: .. XXX should class variables be covered before instance variables, or vice versa? - -.. data:: allow_reuse_address +.. attribute:: BaseServer.allow_reuse_address Whether the server will allow the reuse of an address. This defaults to :const:`False`, and can be set in subclasses to change the policy. -.. data:: request_queue_size +.. attribute:: BaseServer.request_queue_size The size of the request queue. If it takes a long time to process a single request, any requests that arrive while the server is busy are placed into a @@ -205,17 +211,19 @@ value is usually 5, but this can be overridden by subclasses. -.. data:: socket_type +.. attribute:: BaseServer.socket_type The type of socket used by the server; :const:`socket.SOCK_STREAM` and :const:`socket.SOCK_DGRAM` are two common values. -.. data:: timeout + +.. attribute:: BaseServer.timeout Timeout duration, measured in seconds, or :const:`None` if no timeout is desired. If :meth:`handle_request` receives no incoming requests within the timeout period, the :meth:`handle_timeout` method is called. + There are various server methods that can be overridden by subclasses of base server classes like :class:`TCPServer`; these methods aren't useful to external users of the server object. @@ -223,27 +231,27 @@ .. XXX should the default implementations of these be documented, or should it be assumed that the user will look at SocketServer.py? - -.. function:: finish_request() +.. method:: BaseServer.finish_request() Actually processes the request by instantiating :attr:`RequestHandlerClass` and calling its :meth:`handle` method. -.. function:: get_request() +.. method:: BaseServer.get_request() Must accept a request from the socket, and return a 2-tuple containing the *new* socket object to be used to communicate with the client, and the client's address. -.. function:: handle_error(request, client_address) +.. method:: BaseServer.handle_error(request, client_address) This function is called if the :attr:`RequestHandlerClass`'s :meth:`handle` method raises an exception. The default action is to print the traceback to standard output and continue handling further requests. -.. function:: handle_timeout() + +.. method:: BaseServer.handle_timeout() This function is called when the :attr:`timeout` attribute has been set to a value other than :const:`None` and the timeout period has passed with no @@ -251,31 +259,32 @@ to collect the status of any child processes that have exited, while in threading servers this method does nothing. -.. function:: process_request(request, client_address) + +.. method:: BaseServer.process_request(request, client_address) Calls :meth:`finish_request` to create an instance of the :attr:`RequestHandlerClass`. If desired, this function can create a new process or thread to handle the request; the :class:`ForkingMixIn` and :class:`ThreadingMixIn` classes do this. + .. Is there any point in documenting the following two functions? What would the purpose of overriding them be: initializing server instance variables, adding new network families? - -.. function:: server_activate() +.. method:: BaseServer.server_activate() Called by the server's constructor to activate the server. The default behavior just :meth:`listen`\ s to the server's socket. May be overridden. -.. function:: server_bind() +.. method:: BaseServer.server_bind() Called by the server's constructor to bind the socket to the desired address. May be overridden. -.. function:: verify_request(request, client_address) +.. method:: BaseServer.verify_request(request, client_address) Must return a Boolean value; if the value is :const:`True`, the request will be processed, and if it's :const:`False`, the request will be denied. This function @@ -291,14 +300,14 @@ request. -.. function:: finish() +.. method:: RequestHandler.finish() Called after the :meth:`handle` method to perform any clean-up actions required. The default implementation does nothing. If :meth:`setup` or :meth:`handle` raise an exception, this function will not be called. -.. function:: handle() +.. method:: RequestHandler.handle() This function must do all the work required to service a request. The default implementation does nothing. Several instance attributes are @@ -317,7 +326,7 @@ data or return data to the client. -.. function:: setup() +.. method:: RequestHandler.setup() Called before the :meth:`handle` method to perform any initialization actions required. The default implementation does nothing. Modified: python/branches/release26-maint/Doc/library/webbrowser.rst ============================================================================== --- python/branches/release26-maint/Doc/library/webbrowser.rst (original) +++ python/branches/release26-maint/Doc/library/webbrowser.rst Sun Apr 5 23:26:31 2009 @@ -55,6 +55,10 @@ under many window managers this will occur regardless of the setting of this variable). + Note that on some platforms, trying to open a filename using this function, + may work and start the operating system's associated program. However, this + is neither supported nor portable. + .. versionchanged:: 2.5 *new* can now be 2. Modified: python/branches/release26-maint/Doc/make.bat ============================================================================== --- python/branches/release26-maint/Doc/make.bat (original) +++ python/branches/release26-maint/Doc/make.bat Sun Apr 5 23:26:31 2009 @@ -4,6 +4,7 @@ set SVNROOT=http://svn.python.org/projects if "%PYTHON%" EQU "" set PYTHON=..\pcbuild\python if "%HTMLHELP%" EQU "" set HTMLHELP=%ProgramFiles%\HTML Help Workshop\hhc.exe +if "%DISTVERSION%" EQU "" for /f "usebackq" %%v in (`%PYTHON% tools/sphinxext/patchlevel.py`) do set DISTVERSION=%%v if "%1" EQU "" goto help if "%1" EQU "html" goto build @@ -51,7 +52,7 @@ if not exist build\%1 mkdir build\%1 if not exist build\doctrees mkdir build\doctrees cmd /C %PYTHON% tools\sphinx-build.py -b%1 -dbuild\doctrees . build\%* -if "%1" EQU "htmlhelp" "%HTMLHELP%" build\htmlhelp\pydoc.hhp +if "%1" EQU "htmlhelp" "%HTMLHELP%" build\htmlhelp\python%DISTVERSION:.=%.hhp goto end :end Modified: python/branches/release26-maint/Lib/plistlib.py ============================================================================== --- python/branches/release26-maint/Lib/plistlib.py (original) +++ python/branches/release26-maint/Lib/plistlib.py Sun Apr 5 23:26:31 2009 @@ -1,4 +1,4 @@ -"""plistlib.py -- a tool to generate and parse MacOSX .plist files. +r"""plistlib.py -- a tool to generate and parse MacOSX .plist files. The PropertyList (.plist) file format is a simple XML pickle supporting basic object types, like dictionaries, lists, numbers and strings. Modified: python/branches/release26-maint/Lib/posixpath.py ============================================================================== --- python/branches/release26-maint/Lib/posixpath.py (original) +++ python/branches/release26-maint/Lib/posixpath.py Sun Apr 5 23:26:31 2009 @@ -262,7 +262,7 @@ except KeyError: return path userhome = pwent.pw_dir - userhome = userhome.rstrip('/') + userhome = userhome.rstrip('/') or userhome return userhome + path[i:] Modified: python/branches/release26-maint/Lib/test/test_posixpath.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_posixpath.py (original) +++ python/branches/release26-maint/Lib/test/test_posixpath.py Sun Apr 5 23:26:31 2009 @@ -345,6 +345,11 @@ self.assert_(isinstance(posixpath.expanduser("~root/"), basestring)) self.assert_(isinstance(posixpath.expanduser("~foo/"), basestring)) + orig_home = os.environ['HOME'] + os.environ['HOME'] = '/' + self.assertEqual(posixpath.expanduser("~"), "/") + os.environ['HOME'] = orig_home + self.assertRaises(TypeError, posixpath.expanduser) def test_expandvars(self): Modified: python/branches/release26-maint/Lib/test/test_traceback.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_traceback.py (original) +++ python/branches/release26-maint/Lib/test/test_traceback.py Sun Apr 5 23:26:31 2009 @@ -8,16 +8,6 @@ import traceback -try: - raise KeyError -except KeyError: - type_, value, tb = sys.exc_info() - file_ = StringIO() - traceback_print(tb, file_) - example_traceback = file_.getvalue() -else: - raise Error("unable to create test traceback string") - class TracebackCases(unittest.TestCase): # For now, a very minimal set of tests. I want to be sure that @@ -162,9 +152,24 @@ class TracebackFormatTests(unittest.TestCase): - def test_traceback_indentation(self): + def test_traceback_format(self): + try: + raise KeyError('blah') + except KeyError: + type_, value, tb = sys.exc_info() + traceback_fmt = 'Traceback (most recent call last):\n' + \ + ''.join(traceback.format_tb(tb)) + file_ = StringIO() + traceback_print(tb, file_) + python_fmt = file_.getvalue() + else: + raise Error("unable to create test traceback string") + + # Make sure that Python and the traceback module format the same thing + self.assertEquals(traceback_fmt, python_fmt) + # Make sure that the traceback is properly indented. - tb_lines = example_traceback.splitlines() + tb_lines = python_fmt.splitlines() self.assertEquals(len(tb_lines), 3) banner, location, source_line = tb_lines self.assert_(banner.startswith('Traceback')) Modified: python/branches/release26-maint/Lib/traceback.py ============================================================================== --- python/branches/release26-maint/Lib/traceback.py (original) +++ python/branches/release26-maint/Lib/traceback.py Sun Apr 5 23:26:31 2009 @@ -64,7 +64,7 @@ filename = co.co_filename name = co.co_name _print(file, - ' File "%s", line %d, in %s' % (filename,lineno,name)) + ' File "%s", line %d, in %s' % (filename, lineno, name)) linecache.checkcache(filename) line = linecache.getline(filename, lineno, f.f_globals) if line: _print(file, ' ' + line.strip()) @@ -124,9 +124,8 @@ _print(file, 'Traceback (most recent call last):') print_tb(tb, limit, file) lines = format_exception_only(etype, value) - for line in lines[:-1]: - _print(file, line, ' ') - _print(file, lines[-1], '') + for line in lines: + _print(file, line, '') def format_exception(etype, value, tb, limit = None): """Format a stack trace and the exception information. @@ -195,7 +194,7 @@ caretspace = ((c.isspace() and c or ' ') for c in caretspace) # only three spaces to account for offset1 == pos 0 lines.append(' %s^\n' % ''.join(caretspace)) - value = msg + value = msg lines.append(_format_final_exc_line(stype, value)) return lines Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sun Apr 5 23:26:31 2009 @@ -14,6 +14,11 @@ - xrange() is now registered as a Sequence. +- Fix a problem in PyErr_NormalizeException that leads to "undetected errors" + when hitting the recursion limit under certain circumstances. + +- Issue #1665206: Remove the last eager import in _warnings.c and make it lazy. + - Issue #4034: Fix weird attribute error messages of the traceback object. (As a result traceback.__members__ no longer exists.) @@ -95,6 +100,10 @@ Library ------- +- Issue 5471: Fix os.path.expanduser() for $HOME set to '/'. + +- Issue 1326077: fix the formatting of SyntaxErrors by the traceback module. + - Issue 1726172: fix IndexError in the case of and empty response in ftplib. - In Pdb, prevent the reassignment of __builtin__._ by sys.displayhook on Modified: python/branches/release26-maint/Modules/_sqlite/connection.c ============================================================================== --- python/branches/release26-maint/Modules/_sqlite/connection.c (original) +++ python/branches/release26-maint/Modules/_sqlite/connection.c Sun Apr 5 23:26:31 2009 @@ -168,8 +168,9 @@ self->detect_types = detect_types; self->timeout = timeout; (void)sqlite3_busy_timeout(self->db, (int)(timeout*1000)); - +#ifdef WITH_THREAD self->thread_ident = PyThread_get_thread_ident(); +#endif self->check_same_thread = check_same_thread; self->function_pinboard = PyDict_New(); @@ -585,9 +586,11 @@ PyObject* py_func; PyObject* py_retval = NULL; +#ifdef WITH_THREAD PyGILState_STATE threadstate; threadstate = PyGILState_Ensure(); +#endif py_func = (PyObject*)sqlite3_user_data(context); @@ -609,7 +612,9 @@ _sqlite3_result_error(context, "user-defined function raised exception", -1); } +#ifdef WITH_THREAD PyGILState_Release(threadstate); +#endif } static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_value** params) @@ -620,9 +625,11 @@ PyObject** aggregate_instance; PyObject* stepmethod = NULL; +#ifdef WITH_THREAD PyGILState_STATE threadstate; threadstate = PyGILState_Ensure(); +#endif aggregate_class = (PyObject*)sqlite3_user_data(context); @@ -669,7 +676,9 @@ Py_XDECREF(stepmethod); Py_XDECREF(function_result); +#ifdef WITH_THREAD PyGILState_Release(threadstate); +#endif } void _pysqlite_final_callback(sqlite3_context* context) @@ -678,9 +687,11 @@ PyObject** aggregate_instance; PyObject* aggregate_class; +#ifdef WITH_THREAD PyGILState_STATE threadstate; threadstate = PyGILState_Ensure(); +#endif aggregate_class = (PyObject*)sqlite3_user_data(context); @@ -708,7 +719,9 @@ Py_XDECREF(*aggregate_instance); Py_XDECREF(function_result); +#ifdef WITH_THREAD PyGILState_Release(threadstate); +#endif } void _pysqlite_drop_unused_statement_references(pysqlite_Connection* self) @@ -803,9 +816,11 @@ { PyObject *ret; int rc; +#ifdef WITH_THREAD PyGILState_STATE gilstate; gilstate = PyGILState_Ensure(); +#endif ret = PyObject_CallFunction((PyObject*)user_arg, "issss", action, arg1, arg2, dbname, access_attempt_source); if (!ret) { @@ -825,7 +840,9 @@ Py_DECREF(ret); } +#ifdef WITH_THREAD PyGILState_Release(gilstate); +#endif return rc; } @@ -833,9 +850,11 @@ { int rc; PyObject *ret; +#ifdef WITH_THREAD PyGILState_STATE gilstate; gilstate = PyGILState_Ensure(); +#endif ret = PyObject_CallFunction((PyObject*)user_arg, ""); if (!ret) { @@ -852,7 +871,9 @@ Py_DECREF(ret); } +#ifdef WITH_THREAD PyGILState_Release(gilstate); +#endif return rc; } @@ -907,6 +928,7 @@ int pysqlite_check_thread(pysqlite_Connection* self) { +#ifdef WITH_THREAD if (self->check_same_thread) { if (PyThread_get_thread_ident() != self->thread_ident) { PyErr_Format(pysqlite_ProgrammingError, @@ -917,7 +939,7 @@ } } - +#endif return 1; } @@ -1139,12 +1161,14 @@ PyObject* callback = (PyObject*)context; PyObject* string1 = 0; PyObject* string2 = 0; +#ifdef WITH_THREAD PyGILState_STATE gilstate; - +#endif PyObject* retval = NULL; int result = 0; - +#ifdef WITH_THREAD gilstate = PyGILState_Ensure(); +#endif if (PyErr_Occurred()) { goto finally; @@ -1173,9 +1197,9 @@ Py_XDECREF(string1); Py_XDECREF(string2); Py_XDECREF(retval); - +#ifdef WITH_THREAD PyGILState_Release(gilstate); - +#endif return result; } Modified: python/branches/release26-maint/Modules/_sqlite/module.c ============================================================================== --- python/branches/release26-maint/Modules/_sqlite/module.c (original) +++ python/branches/release26-maint/Modules/_sqlite/module.c Sun Apr 5 23:26:31 2009 @@ -445,7 +445,9 @@ * threads have already been initialized. * (see pybsddb-users mailing list post on 2002-08-07) */ +#ifdef WITH_THREAD PyEval_InitThreads(); +#endif error: if (PyErr_Occurred()) Modified: python/branches/release26-maint/Objects/bytearrayobject.c ============================================================================== --- python/branches/release26-maint/Objects/bytearrayobject.c (original) +++ python/branches/release26-maint/Objects/bytearrayobject.c Sun Apr 5 23:26:31 2009 @@ -1093,7 +1093,7 @@ { if (self->ob_exports > 0) { PyErr_SetString(PyExc_SystemError, - "deallocated bytearray object has exported buffers"); + "deallocated bytearray object has exported buffers"); PyErr_Print(); } if (self->ob_bytes != 0) { @@ -2679,10 +2679,10 @@ /* Try to determine the length of the argument. 32 is abitrary. */ buf_size = _PyObject_LengthHint(arg, 32); - if (buf_size == -1) { - Py_DECREF(it); - return NULL; - } + if (buf_size == -1) { + Py_DECREF(it); + return NULL; + } bytes_obj = PyByteArray_FromStringAndSize(NULL, buf_size); if (bytes_obj == NULL) @@ -3122,10 +3122,10 @@ static PyObject * bytes_sizeof(PyByteArrayObject *self) { - Py_ssize_t res; + Py_ssize_t res; - res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char); - return PyInt_FromSsize_t(res); + res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char); + return PyInt_FromSsize_t(res); } static PySequenceMethods bytes_as_sequence = { Modified: python/branches/release26-maint/Objects/object.c ============================================================================== --- python/branches/release26-maint/Objects/object.c (original) +++ python/branches/release26-maint/Objects/object.c Sun Apr 5 23:26:31 2009 @@ -331,11 +331,17 @@ if (op == NULL) fprintf(stderr, "NULL\n"); else { +#ifdef WITH_THREAD PyGILState_STATE gil; +#endif fprintf(stderr, "object : "); +#ifdef WITH_THREAD gil = PyGILState_Ensure(); +#endif (void)PyObject_Print(op, stderr, 0); +#ifdef WITH_THREAD PyGILState_Release(gil); +#endif /* XXX(twouters) cast refcount to long until %zd is universally available */ fprintf(stderr, "\n" Modified: python/branches/release26-maint/Python/errors.c ============================================================================== --- python/branches/release26-maint/Python/errors.c (original) +++ python/branches/release26-maint/Python/errors.c Sun Apr 5 23:26:31 2009 @@ -219,7 +219,15 @@ tstate = PyThreadState_GET(); if (++tstate->recursion_depth > Py_GetRecursionLimit()) { --tstate->recursion_depth; - PyErr_SetObject(PyExc_RuntimeError, PyExc_RecursionErrorInst); + /* throw away the old exception... */ + Py_DECREF(*exc); + Py_DECREF(*val); + /* ... and use the recursion error instead */ + *exc = PyExc_RuntimeError; + *val = PyExc_RecursionErrorInst; + Py_INCREF(*exc); + Py_INCREF(*val); + /* just keeping the old traceback */ return; } PyErr_NormalizeException(exc, val, tb); Modified: python/branches/release26-maint/Python/getargs.c ============================================================================== --- python/branches/release26-maint/Python/getargs.c (original) +++ python/branches/release26-maint/Python/getargs.c Sun Apr 5 23:26:31 2009 @@ -1108,7 +1108,7 @@ != size) { Py_DECREF(s); return converterr( - "(encoded string without NULL bytes)", + "encoded string without NULL bytes", arg, msgbuf, bufsize); } *buffer = PyMem_NEW(char, size + 1); From buildbot at python.org Sun Apr 5 23:26:36 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 05 Apr 2009 21:26:36 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 3.x Message-ID: <20090405212636.E2AE81E4696@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%203.x/builds/627 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_multiprocessing ====================================================================== FAIL: test_event (test.test_multiprocessing.WithThreadsTestEvent) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/buildbot/buildarea/3.x.heller-x86-osx5/build/Lib/test/test_multiprocessing.py", line 755, in test_event self.assertEqual(wait(0.0), None) AssertionError: False != None ====================================================================== FAIL: test_event (test.test_multiprocessing.WithManagerTestEvent) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/buildbot/buildarea/3.x.heller-x86-osx5/build/Lib/test/test_multiprocessing.py", line 755, in test_event self.assertEqual(wait(0.0), None) AssertionError: False != None make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sun Apr 5 23:26:58 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 23:26:58 +0200 (CEST) Subject: [Python-checkins] r71276 - python/branches/release26-maint Message-ID: <20090405212658.C13431E4078@bag.python.org> Author: georg.brandl Date: Sun Apr 5 23:26:58 2009 New Revision: 71276 Log: Blocked revisions 71255,71266 via svnmerge ........ r71255 | georg.brandl | 2009-04-05 20:34:58 +0200 (So, 05 Apr 2009) | 1 line #602893: add indicator for current line in cgitb that doesnt rely on styling alone. ........ r71266 | georg.brandl | 2009-04-05 22:23:13 +0200 (So, 05 Apr 2009) | 1 line Normalize issue referencing style. ........ Modified: python/branches/release26-maint/ (props changed) From jnoller at gmail.com Sun Apr 5 23:29:12 2009 From: jnoller at gmail.com (Jesse Noller) Date: Sun, 5 Apr 2009 17:29:12 -0400 Subject: [Python-checkins] buildbot failure in x86 osx.5 3.x In-Reply-To: <20090405212636.E2AE81E4696@bag.python.org> References: <20090405212636.E2AE81E4696@bag.python.org> Message-ID: Ben, you need georg's threading.event changes too On Apr 5, 2009, at 5:26 PM, buildbot at python.org wrote: > The Buildbot has detected a new failure of x86 osx.5 3.x. > Full details are available at: > http://www.python.org/dev/buildbot/all/x86%20osx.5%203.x/builds/627 > > Buildbot URL: http://www.python.org/dev/buildbot/all/ > > Buildslave for this Build: heller-x86-osx5 > > Build Reason: > Build Source Stamp: [branch branches/py3k] HEAD > Blamelist: benjamin.peterson > > BUILD FAILED: failed test > > Excerpt from the test logfile: > 1 test failed: > test_multiprocessing > > ====================================================================== > FAIL: test_event (test.test_multiprocessing.WithThreadsTestEvent) > ---------------------------------------------------------------------- > > Traceback (most recent call last): > File "/Users/buildbot/buildarea/3.x.heller-x86-osx5/build/Lib/test/ > test_multiprocessing.py", line 755, in test_event > self.assertEqual(wait(0.0), None) > AssertionError: False != None > > ====================================================================== > FAIL: test_event (test.test_multiprocessing.WithManagerTestEvent) > ---------------------------------------------------------------------- > > Traceback (most recent call last): > File "/Users/buildbot/buildarea/3.x.heller-x86-osx5/build/Lib/test/ > test_multiprocessing.py", line 755, in test_event > self.assertEqual(wait(0.0), None) > AssertionError: False != None > > make: *** [buildbottest] Error 1 > > sincerely, > -The Buildbot > > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > http://mail.python.org/mailman/listinfo/python-checkins From benjamin at python.org Sun Apr 5 23:30:52 2009 From: benjamin at python.org (Benjamin Peterson) Date: Sun, 5 Apr 2009 16:30:52 -0500 Subject: [Python-checkins] buildbot failure in x86 osx.5 3.x In-Reply-To: References: <20090405212636.E2AE81E4696@bag.python.org> Message-ID: <1afaf6160904051430i2700a8a7n825d69021042bb39@mail.gmail.com> 2009/4/5 Jesse Noller : > Ben, you need georg's threading.event changes too Time machine! Just merged them 5 minutes ago. :) -- Regards, Benjamin From python-checkins at python.org Sun Apr 5 23:31:16 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 5 Apr 2009 23:31:16 +0200 (CEST) Subject: [Python-checkins] r71277 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090405213116.6AD771E4078@bag.python.org> Author: mark.dickinson Date: Sun Apr 5 23:31:16 2009 New Revision: 71277 Log: Treat Sudden_Underflow as not defined. Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Sun Apr 5 23:31:16 2009 @@ -955,9 +955,7 @@ Bigint *b; int de, k; ULong *x, y, z; -#ifndef Sudden_Underflow int i; -#endif #define d0 word0(d) #define d1 word1(d) @@ -968,13 +966,8 @@ z = d0 & Frac_mask; d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ -#ifdef Sudden_Underflow - de = (int)(d0 >> Exp_shift); - z |= Exp_msk11; -#else if ((de = (int)(d0 >> Exp_shift))) z |= Exp_msk1; -#endif if ((y = d1)) { if ((k = lo0bits(&y))) { x[0] = y | z << (32 - k); @@ -982,32 +975,24 @@ } else x[0] = y; -#ifndef Sudden_Underflow i = -#endif b->wds = (x[1] = z) ? 2 : 1; } else { k = lo0bits(&z); x[0] = z; -#ifndef Sudden_Underflow i = -#endif b->wds = 1; k += 32; } -#ifndef Sudden_Underflow if (de) { -#endif *e = de - Bias - (P-1) + k; *bits = P - k; -#ifndef Sudden_Underflow } else { *e = de - Bias - (P-1) + 1 + k; *bits = 32*i - hi0bits(x[i-1]); } -#endif return b; } #undef d0 @@ -1204,7 +1189,6 @@ nd0 = bc->nd0; p5 = nd + bc->e0 - 1; speccase = 0; -#ifndef Sudden_Underflow if (rv->d == 0.) { /* special case: value near underflow-to-zero */ /* threshold was rounded to zero */ b = i2b(1); @@ -1222,7 +1206,6 @@ } } else -#endif { b = d2b(rv, &p2, &bbits); if (b == NULL) @@ -1233,18 +1216,7 @@ /* Check for denormal case. */ i = P - bbits; if (i > (j = P - Emin - 1 + p2)) { -#ifdef Sudden_Underflow - Bfree(b); - b = i2b(1); - if (b == NULL) - return -1; - p2 = Emin; - i = P - 1; - word0(rv) = (1 + bc->scale) << Exp_shift; - word1(rv) = 0; -#else i = j; -#endif } { b = lshift(b, ++i); @@ -1252,9 +1224,7 @@ return -1; b->x[0] |= 1; } -#ifndef Sudden_Underflow have_i: -#endif p2 -= p5 + i; d = i2b(1); if (d == NULL) { @@ -1786,18 +1756,6 @@ else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { drop_down: /* boundary case -- decrement exponent */ -#ifdef Sudden_Underflow /*{{*/ - L = word0(&rv) & Exp_mask; - if (L <= (bc.scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) - { - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } - goto undfl; - } - L -= Exp_msk1; -#else /*Sudden_Underflow}{*/ if (bc.scale) { L = word0(&rv) & Exp_mask; if (L <= (2*P+1)*Exp_msk1) { @@ -1814,7 +1772,6 @@ } } L = (word0(&rv) & Exp_mask) - Exp_msk1; -#endif /*Sudden_Underflow}}*/ word0(&rv) = L | Bndry_mask1; word1(&rv) = 0xffffffff; break; @@ -1825,7 +1782,6 @@ dval(&rv) += ulp(&rv); else { dval(&rv) -= ulp(&rv); -#ifndef Sudden_Underflow if (!dval(&rv)) { if (bc.nd >nd) { bc.uflchk = 1; @@ -1833,7 +1789,6 @@ } goto undfl; } -#endif } bc.dsign = 1 - bc.dsign; break; @@ -1842,7 +1797,6 @@ if (bc.dsign) aadj = aadj1 = 1.; else if (word1(&rv) || word0(&rv) & Bndry_mask) { -#ifndef Sudden_Underflow if (word1(&rv) == Tiny1 && !word0(&rv)) { if (bc.nd >nd) { bc.uflchk = 1; @@ -1850,7 +1804,6 @@ } goto undfl; } -#endif aadj = 1.; aadj1 = -1.; } @@ -2083,10 +2036,8 @@ j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, spec_case, try_quick; Long L; -#ifndef Sudden_Underflow int denorm; ULong x; -#endif Bigint *b, *b1, *delta, *mlo, *mhi, *S; U d2, eps, u; double ds; @@ -2123,11 +2074,7 @@ b = d2b(&u, &be, &bbits); -#ifdef Sudden_Underflow - i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); -#else if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) { -#endif dval(&d2) = dval(&u); word0(&d2) &= Frac_mask1; word0(&d2) |= Exp_11; @@ -2155,7 +2102,6 @@ */ i -= Bias; -#ifndef Sudden_Underflow denorm = 0; } else { @@ -2169,7 +2115,6 @@ i -= (Bias + (P-1) - 1) + 1; denorm = 1; } -#endif ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; k = (int)ds; if (ds < 0. && ds != k) @@ -2388,9 +2333,7 @@ mhi = mlo = 0; if (leftright) { i = -#ifndef Sudden_Underflow denorm ? be + (Bias + (P-1) - 1 + 1) : -#endif 1 + P - bbits; b2 += i; s2 += i; @@ -2426,9 +2369,7 @@ if ((mode < 2 || leftright) ) { if (!word1(&u) && !(word0(&u) & Bndry_mask) -#ifndef Sudden_Underflow && word0(&u) & (Exp_mask & ~Exp_msk1) -#endif ) { /* The special case */ b2 += Log2P; From jnoller at gmail.com Sun Apr 5 23:33:26 2009 From: jnoller at gmail.com (Jesse Noller) Date: Sun, 5 Apr 2009 17:33:26 -0400 Subject: [Python-checkins] buildbot failure in x86 osx.5 3.x In-Reply-To: <1afaf6160904051430i2700a8a7n825d69021042bb39@mail.gmail.com> References: <20090405212636.E2AE81E4696@bag.python.org> <1afaf6160904051430i2700a8a7n825d69021042bb39@mail.gmail.com> Message-ID: <4F044223-E91D-4F79-B95A-4E02EEA253C9@gmail.com> Foiled again! On Apr 5, 2009, at 5:30 PM, Benjamin Peterson wrote: > 2009/4/5 Jesse Noller : >> Ben, you need georg's threading.event changes too > > Time machine! Just merged them 5 minutes ago. :) > > > > -- > Regards, > Benjamin From python-checkins at python.org Sun Apr 5 23:34:16 2009 From: python-checkins at python.org (matthias.klose) Date: Sun, 5 Apr 2009 23:34:16 +0200 (CEST) Subject: [Python-checkins] r71278 - in python/branches/release26-maint: Lib/SimpleXMLRPCServer.py Misc/NEWS Message-ID: <20090405213416.07D601E4078@bag.python.org> Author: matthias.klose Date: Sun Apr 5 23:34:15 2009 New Revision: 71278 Log: Merged revisions 71268 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71268 | matthias.klose | 2009-04-05 23:00:48 +0200 (So, 05 Apr 2009) | 3 lines - Issue #2703: SimpleXMLRPCDispatcher.__init__: Provide default values for new arguments introduced in 2.5. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/SimpleXMLRPCServer.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/SimpleXMLRPCServer.py ============================================================================== --- python/branches/release26-maint/Lib/SimpleXMLRPCServer.py (original) +++ python/branches/release26-maint/Lib/SimpleXMLRPCServer.py Sun Apr 5 23:34:15 2009 @@ -164,7 +164,7 @@ reason to instantiate this class directly. """ - def __init__(self, allow_none, encoding): + def __init__(self, allow_none=False, encoding=None): self.funcs = {} self.instance = None self.allow_none = allow_none Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sun Apr 5 23:34:15 2009 @@ -468,6 +468,9 @@ - Issue #1149804: macostools.mkdirs now even works when another process creates one of the needed subdirectories. +- Issue #2703: SimpleXMLRPCDispatcher.__init__: Provide default values for + new arguments introduced in 2.5. + Tools/Demos ----------- From python-checkins at python.org Sun Apr 5 23:35:06 2009 From: python-checkins at python.org (matthias.klose) Date: Sun, 5 Apr 2009 23:35:06 +0200 (CEST) Subject: [Python-checkins] r71279 - python/branches/release26-maint/Misc/NEWS Message-ID: <20090405213506.9AE6F1E401E@bag.python.org> Author: matthias.klose Date: Sun Apr 5 23:35:06 2009 New Revision: 71279 Log: Move news item from 2.6.1 to 2.6.2. Modified: python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sun Apr 5 23:35:06 2009 @@ -308,6 +308,9 @@ - Issue #4861: ctypes.util.find_library(): Robustify. Fix library detection on biarch systems. Try to rely on ldconfig only, without using objdump and gcc. +- Issue #2703: SimpleXMLRPCDispatcher.__init__: Provide default values for + new arguments introduced in 2.5. + Extension Modules ----------------- @@ -468,9 +471,6 @@ - Issue #1149804: macostools.mkdirs now even works when another process creates one of the needed subdirectories. -- Issue #2703: SimpleXMLRPCDispatcher.__init__: Provide default values for - new arguments introduced in 2.5. - Tools/Demos ----------- From python-checkins at python.org Sun Apr 5 23:44:09 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 5 Apr 2009 23:44:09 +0200 (CEST) Subject: [Python-checkins] r71280 - in python/trunk: Lib/distutils/filelist.py Lib/distutils/tests/test_filelist.py Misc/NEWS Message-ID: <20090405214409.C5DAF1E401A@bag.python.org> Author: tarek.ziade Date: Sun Apr 5 23:44:08 2009 New Revision: 71280 Log: Fixed #1491431: distutils.filelist.glob_to_re was broken for some edge cases (detailed in the test Added: python/trunk/Lib/distutils/tests/test_filelist.py (contents, props changed) Modified: python/trunk/Lib/distutils/filelist.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/distutils/filelist.py ============================================================================== --- python/trunk/Lib/distutils/filelist.py (original) +++ python/trunk/Lib/distutils/filelist.py Sun Apr 5 23:44:08 2009 @@ -302,7 +302,7 @@ return list -def glob_to_re (pattern): +def glob_to_re(pattern): """Translate a shell-like glob pattern to a regular expression; return a string containing the regex. Differs from 'fnmatch.translate()' in that '*' does not match "special characters" (which are @@ -317,7 +317,8 @@ # character except the special characters. # XXX currently the "special characters" are just slash -- i.e. this is # Unix-only. - pattern_re = re.sub(r'(^|[^\\])\.', r'\1[^/]', pattern_re) + pattern_re = re.sub(r'((? Author: tarek.ziade Date: Sun Apr 5 23:47:02 2009 New Revision: 71281 Log: Merged revisions 71280 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71280 | tarek.ziade | 2009-04-05 23:44:08 +0200 (Sun, 05 Apr 2009) | 1 line Fixed #1491431: distutils.filelist.glob_to_re was broken for some edge cases (detailed in the test ........ Added: python/branches/release26-maint/Lib/distutils/tests/test_filelist.py - copied unchanged from r71280, /python/trunk/Lib/distutils/tests/test_filelist.py Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/distutils/filelist.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/distutils/filelist.py ============================================================================== --- python/branches/release26-maint/Lib/distutils/filelist.py (original) +++ python/branches/release26-maint/Lib/distutils/filelist.py Sun Apr 5 23:47:02 2009 @@ -304,7 +304,7 @@ return list -def glob_to_re (pattern): +def glob_to_re(pattern): """Translate a shell-like glob pattern to a regular expression; return a string containing the regex. Differs from 'fnmatch.translate()' in that '*' does not match "special characters" (which are @@ -319,7 +319,8 @@ # character except the special characters. # XXX currently the "special characters" are just slash -- i.e. this is # Unix-only. - pattern_re = re.sub(r'(^|[^\\])\.', r'\1[^/]', pattern_re) + pattern_re = re.sub(r'((? Author: georg.brandl Date: Sun Apr 5 23:48:06 2009 New Revision: 71282 Log: Merged revisions 69578-69580,69901,69907,69994,70022-70023,70025-70026,70166,70273,70275,70342,70386-70387,70389-70390,70392-70393,70395,70397,70400,70418 via svnmerge ........ r69578 | georg.brandl | 2009-02-13 12:03:59 +0100 (Fr, 13 Feb 2009) | 1 line #3694: add test for fix committed in r66693. ........ r69579 | georg.brandl | 2009-02-13 12:06:59 +0100 (Fr, 13 Feb 2009) | 2 lines Fix warnings GCC emits where the argument of PyErr_Format is a single variable. ........ r69580 | georg.brandl | 2009-02-13 12:10:04 +0100 (Fr, 13 Feb 2009) | 2 lines Fix warnings GCC emits where the argument of PyErr_Format is a single variable. ........ r69901 | georg.brandl | 2009-02-23 12:24:46 +0100 (Mo, 23 Feb 2009) | 2 lines #5349: C++ pure virtuals can also have an implementation. ........ r69907 | georg.brandl | 2009-02-23 19:33:48 +0100 (Mo, 23 Feb 2009) | 1 line Fix grammar. ........ r69994 | georg.brandl | 2009-02-26 18:36:26 +0100 (Do, 26 Feb 2009) | 1 line Document that setting sys.py3kwarning wont do anything. ........ r70022 | georg.brandl | 2009-02-27 17:23:18 +0100 (Fr, 27 Feb 2009) | 1 line #5361: fix typo. ........ r70023 | georg.brandl | 2009-02-27 17:39:26 +0100 (Fr, 27 Feb 2009) | 1 line #5363: fix cmpfiles() docs. Another instance where a prose description is twice as long as the code. ........ r70025 | georg.brandl | 2009-02-27 17:52:55 +0100 (Fr, 27 Feb 2009) | 1 line #5344: fix punctuation. ........ r70026 | georg.brandl | 2009-02-27 17:59:03 +0100 (Fr, 27 Feb 2009) | 1 line #5365: add quick look conversion table for different time representations. ........ r70166 | georg.brandl | 2009-03-04 19:24:41 +0100 (Mi, 04 M?r 2009) | 2 lines Remove obsolete stuff from string module docs. ........ r70273 | georg.brandl | 2009-03-09 15:25:07 +0100 (Mo, 09 M?r 2009) | 2 lines #5458: add a note when we started to raise RuntimeErrors. ........ r70275 | georg.brandl | 2009-03-09 17:35:48 +0100 (Mo, 09 M?r 2009) | 2 lines Add missing space. ........ r70342 | georg.brandl | 2009-03-13 20:03:58 +0100 (Fr, 13 M?r 2009) | 1 line #5486: typos. ........ r70386 | georg.brandl | 2009-03-15 22:32:06 +0100 (So, 15 M?r 2009) | 1 line #5496: fix docstring of lookup(). ........ r70387 | georg.brandl | 2009-03-15 22:37:16 +0100 (So, 15 M?r 2009) | 1 line #5493: clarify __nonzero__ docs. ........ r70389 | georg.brandl | 2009-03-15 22:43:38 +0100 (So, 15 M?r 2009) | 1 line Fix a small nit in the error message if bool() falls back on __len__ and it returns the wrong type: it would tell the user that __nonzero__ should return bool or int. ........ r70390 | georg.brandl | 2009-03-15 22:44:43 +0100 (So, 15 M?r 2009) | 1 line #5491: clarify nested() semantics. ........ r70392 | georg.brandl | 2009-03-15 22:46:00 +0100 (So, 15 M?r 2009) | 1 line #5488: add missing struct member. ........ r70393 | georg.brandl | 2009-03-15 22:47:42 +0100 (So, 15 M?r 2009) | 1 line #5478: fix copy-paste oversight in function signature. ........ r70395 | georg.brandl | 2009-03-15 22:51:48 +0100 (So, 15 M?r 2009) | 1 line #5276: document IDLESTARTUP and .Idle.py. ........ r70397 | georg.brandl | 2009-03-15 22:53:56 +0100 (So, 15 M?r 2009) | 1 line #5469: add with statement to list of name-binding constructs. ........ r70400 | georg.brandl | 2009-03-15 22:59:37 +0100 (So, 15 M?r 2009) | 3 lines Fix markup in re docs and give a mail address in regex howto, so that the recommendation to send suggestions to the author can be followed. ........ r70418 | georg.brandl | 2009-03-16 20:42:03 +0100 (Mo, 16 M?r 2009) | 1 line Add token markup. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/c-api/typeobj.rst python/branches/release26-maint/Doc/distutils/packageindex.rst python/branches/release26-maint/Doc/howto/regex.rst python/branches/release26-maint/Doc/library/2to3.rst python/branches/release26-maint/Doc/library/abc.rst python/branches/release26-maint/Doc/library/contextlib.rst python/branches/release26-maint/Doc/library/exceptions.rst python/branches/release26-maint/Doc/library/filecmp.rst python/branches/release26-maint/Doc/library/idle.rst python/branches/release26-maint/Doc/library/re.rst python/branches/release26-maint/Doc/library/stdtypes.rst python/branches/release26-maint/Doc/library/string.rst python/branches/release26-maint/Doc/library/sys.rst python/branches/release26-maint/Doc/library/threading.rst python/branches/release26-maint/Doc/library/time.rst python/branches/release26-maint/Doc/library/turtle.rst python/branches/release26-maint/Doc/library/xml.dom.rst python/branches/release26-maint/Doc/reference/datamodel.rst python/branches/release26-maint/Doc/reference/executionmodel.rst python/branches/release26-maint/Doc/whatsnew/2.6.rst python/branches/release26-maint/Lib/test/test_struct.py python/branches/release26-maint/Modules/_codecsmodule.c python/branches/release26-maint/Modules/_ctypes/_ctypes.c python/branches/release26-maint/Objects/typeobject.c python/branches/release26-maint/Objects/unicodeobject.c Modified: python/branches/release26-maint/Doc/c-api/typeobj.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/typeobj.rst (original) +++ python/branches/release26-maint/Doc/c-api/typeobj.rst Sun Apr 5 23:48:06 2009 @@ -1180,6 +1180,7 @@ binaryfunc nb_inplace_add; binaryfunc nb_inplace_subtract; binaryfunc nb_inplace_multiply; + binaryfunc nb_inplace_divide; binaryfunc nb_inplace_remainder; ternaryfunc nb_inplace_power; binaryfunc nb_inplace_lshift; Modified: python/branches/release26-maint/Doc/distutils/packageindex.rst ============================================================================== --- python/branches/release26-maint/Doc/distutils/packageindex.rst (original) +++ python/branches/release26-maint/Doc/distutils/packageindex.rst Sun Apr 5 23:48:06 2009 @@ -91,4 +91,3 @@ python setup.py register -r other - Modified: python/branches/release26-maint/Doc/howto/regex.rst ============================================================================== --- python/branches/release26-maint/Doc/howto/regex.rst (original) +++ python/branches/release26-maint/Doc/howto/regex.rst Sun Apr 5 23:48:06 2009 @@ -4,7 +4,7 @@ Regular Expression HOWTO **************************** -:Author: A.M. Kuchling +:Author: A.M. Kuchling :Release: 0.05 .. TODO: Modified: python/branches/release26-maint/Doc/library/2to3.rst ============================================================================== --- python/branches/release26-maint/Doc/library/2to3.rst (original) +++ python/branches/release26-maint/Doc/library/2to3.rst Sun Apr 5 23:48:06 2009 @@ -36,9 +36,9 @@ $ 2to3 example.py A diff against the original source file is printed. 2to3 can also write the -needed modifications right back to the source file. (Of course, a backup of the -original is also be made unless :option:`-n` is also given.) Writing the -changes back is enabled with the :option:`-w` flag:: +needed modifications right back to the source file. (A backup of the original +file is made unless :option:`-n` is also given.) Writing the changes back is +enabled with the :option:`-w` flag:: $ 2to3 -w example.py Modified: python/branches/release26-maint/Doc/library/abc.rst ============================================================================== --- python/branches/release26-maint/Doc/library/abc.rst (original) +++ python/branches/release26-maint/Doc/library/abc.rst Sun Apr 5 23:48:06 2009 @@ -153,7 +153,7 @@ .. note:: - Unlike C++'s pure virtual functions, or Java abstract methods, these abstract + Unlike Java abstract methods, these abstract methods may have an implementation. This implementation can be called via the :func:`super` mechanism from the class that overrides it. This could be useful as an end-point for a Modified: python/branches/release26-maint/Doc/library/contextlib.rst ============================================================================== --- python/branches/release26-maint/Doc/library/contextlib.rst (original) +++ python/branches/release26-maint/Doc/library/contextlib.rst Sun Apr 5 23:48:06 2009 @@ -63,14 +63,15 @@ from contextlib import nested - with nested(A, B, C) as (X, Y, Z): + with nested(A(), B(), C()) as (X, Y, Z): do_something() is equivalent to this:: - with A as X: - with B as Y: - with C as Z: + m1, m2, m3 = A(), B(), C() + with m1 as X: + with m2 as Y: + with m3 as Z: do_something() Note that if the :meth:`__exit__` method of one of the nested context managers Modified: python/branches/release26-maint/Doc/library/exceptions.rst ============================================================================== --- python/branches/release26-maint/Doc/library/exceptions.rst (original) +++ python/branches/release26-maint/Doc/library/exceptions.rst Sun Apr 5 23:48:06 2009 @@ -52,7 +52,7 @@ The base class for all built-in exceptions. It is not meant to be directly inherited by user-defined classes (for that use :exc:`Exception`). If :func:`str` or :func:`unicode` is called on an instance of this class, the - representation of the argument(s) to the instance are returned or the emptry + representation of the argument(s) to the instance are returned or the empty string when there were no arguments. All arguments are stored in :attr:`args` as a tuple. Modified: python/branches/release26-maint/Doc/library/filecmp.rst ============================================================================== --- python/branches/release26-maint/Doc/library/filecmp.rst (original) +++ python/branches/release26-maint/Doc/library/filecmp.rst Sun Apr 5 23:48:06 2009 @@ -31,17 +31,24 @@ .. function:: cmpfiles(dir1, dir2, common[, shallow]) - Returns three lists of file names: *match*, *mismatch*, *errors*. *match* - contains the list of files match in both directories, *mismatch* includes the - names of those that don't, and *errros* lists the names of files which could not - be compared. Files may be listed in *errors* because the user may lack - permission to read them or many other reasons, but always that the comparison - could not be done for some reason. + Compare the files in the two directories *dir1* and *dir2* whose names are + given by *common*. - The *common* parameter is a list of file names found in both directories. The - *shallow* parameter has the same meaning and default value as for + Returns three lists of file names: *match*, *mismatch*, + *errors*. *match* contains the list of files that match, *mismatch* contains + the names of those that don't, and *errors* lists the names of files which + could not be compared. Files are listed in *errors* if they don't exist in + one of the directories, the user lacks permission to read them or if the + comparison could not be done for some other reason. + + The *shallow* parameter has the same meaning and default value as for :func:`filecmp.cmp`. + For example, ``cmpfiles('a', 'b', ['c', 'd/e'])`` will compare ``a/c`` with + ``b/c`` and ``a/d/e`` with ``b/d/e``. ``'c'`` and ``'d/e'`` will each be in + one of the three returned lists. + + Example:: >>> import filecmp Modified: python/branches/release26-maint/Doc/library/idle.rst ============================================================================== --- python/branches/release26-maint/Doc/library/idle.rst (original) +++ python/branches/release26-maint/Doc/library/idle.rst Sun Apr 5 23:48:06 2009 @@ -253,6 +253,24 @@ black +Startup +------- + +Upon startup with the ``-s`` option, IDLE will execute the file referenced by +the environment variables :envvar:`IDLESTARTUP` or :envvar:`PYTHONSTARTUP`. +Idle first checks for ``IDLESTARTUP``; if ``IDLESTARTUP`` is present the file +referenced is run. If ``IDLESTARTUP`` is not present, Idle checks for +``PYTHONSTARTUP``. Files referenced by these environment variables are +convenient places to store functions that are used frequently from the Idle +shell, or for executing import statements to import common modules. + +In addition, ``Tk`` also loads a startup file if it is present. Note that the +Tk file is loaded unconditionally. This additional file is ``.Idle.py`` and is +looked for in the user's home directory. Statements in this file will be +executed in the Tk namespace, so this file is not useful for importing functions +to be used from Idle's Python shell. + + Command line usage ^^^^^^^^^^^^^^^^^^ Modified: python/branches/release26-maint/Doc/library/re.rst ============================================================================== --- python/branches/release26-maint/Doc/library/re.rst (original) +++ python/branches/release26-maint/Doc/library/re.rst Sun Apr 5 23:48:06 2009 @@ -1093,7 +1093,7 @@ string)`` or ``re.search(pattern, string)``. :func:`match` has an optional second parameter that gives an index in the string -where the search is to start: +where the search is to start:: >>> pattern = re.compile("o") >>> pattern.match("dog") # No match as "o" is not at the start of "dog." Modified: python/branches/release26-maint/Doc/library/stdtypes.rst ============================================================================== --- python/branches/release26-maint/Doc/library/stdtypes.rst (original) +++ python/branches/release26-maint/Doc/library/stdtypes.rst Sun Apr 5 23:48:06 2009 @@ -1296,7 +1296,7 @@ +------------+-----------------------------------------------------+-------+ | ``'o'`` | Signed octal value. | \(1) | +------------+-----------------------------------------------------+-------+ -| ``'u'`` | Obselete type -- it is identical to ``'d'``. | \(7) | +| ``'u'`` | Obsolete type -- it is identical to ``'d'``. | \(7) | +------------+-----------------------------------------------------+-------+ | ``'x'`` | Signed hexadecimal (lowercase). | \(2) | +------------+-----------------------------------------------------+-------+ Modified: python/branches/release26-maint/Doc/library/string.rst ============================================================================== --- python/branches/release26-maint/Doc/library/string.rst (original) +++ python/branches/release26-maint/Doc/library/string.rst Sun Apr 5 23:48:06 2009 @@ -62,10 +62,9 @@ .. data:: lowercase A string containing all the characters that are considered lowercase letters. - On most systems this is the string ``'abcdefghijklmnopqrstuvwxyz'``. Do not - change its definition --- the effect on the routines :func:`upper` and - :func:`swapcase` is undefined. The specific value is locale-dependent, and will - be updated when :func:`locale.setlocale` is called. + On most systems this is the string ``'abcdefghijklmnopqrstuvwxyz'``. The + specific value is locale-dependent, and will be updated when + :func:`locale.setlocale` is called. .. data:: octdigits @@ -89,18 +88,16 @@ .. data:: uppercase A string containing all the characters that are considered uppercase letters. - On most systems this is the string ``'ABCDEFGHIJKLMNOPQRSTUVWXYZ'``. Do not - change its definition --- the effect on the routines :func:`lower` and - :func:`swapcase` is undefined. The specific value is locale-dependent, and will - be updated when :func:`locale.setlocale` is called. + On most systems this is the string ``'ABCDEFGHIJKLMNOPQRSTUVWXYZ'``. The + specific value is locale-dependent, and will be updated when + :func:`locale.setlocale` is called. .. data:: whitespace A string containing all characters that are considered whitespace. On most systems this includes the characters space, tab, linefeed, return, formfeed, and - vertical tab. Do not change its definition --- the effect on the routines - :func:`strip` and :func:`split` is undefined. + vertical tab. .. _new-string-formatting: @@ -224,7 +221,7 @@ .. productionlist:: sf replacement_field: "{" `field_name` ["!" `conversion`] [":" `format_spec`] "}" - field_name: (`identifier` | `integer`) ("." `attribute_name` | "[" element_index "]")* + field_name: (`identifier` | `integer`) ("." `attribute_name` | "[" `element_index` "]")* attribute_name: `identifier` element_index: `integer` conversion: "r" | "s" @@ -599,7 +596,7 @@ Don't use strings derived from :const:`lowercase` and :const:`uppercase` as arguments; in some locales, these don't have the same length. For case - conversions, always use :func:`lower` and :func:`upper`. + conversions, always use :meth:`str.lower` and :meth:`str.upper`. Deprecated string functions Modified: python/branches/release26-maint/Doc/library/sys.rst ============================================================================== --- python/branches/release26-maint/Doc/library/sys.rst (original) +++ python/branches/release26-maint/Doc/library/sys.rst Sun Apr 5 23:48:06 2009 @@ -661,7 +661,9 @@ .. data:: py3kwarning Bool containing the status of the Python 3.0 warning flag. It's ``True`` - when Python is started with the -3 option. + when Python is started with the -3 option. (This should be considered + read-only; setting it to a different value doesn't have an effect on + Python 3.0 warnings.) .. versionadded:: 2.6 Modified: python/branches/release26-maint/Doc/library/threading.rst ============================================================================== --- python/branches/release26-maint/Doc/library/threading.rst (original) +++ python/branches/release26-maint/Doc/library/threading.rst Sun Apr 5 23:48:06 2009 @@ -21,9 +21,14 @@ deprecation of the ``camelCase`` names and they remain fully supported in both Python 2.x and 3.x. -This module defines the following functions and objects: +.. note:: + + Starting with Python 2.5, several Thread methods raise :exc:`RuntimeError` + instead of :exc:`AssertionError` if called erroneously. +This module defines the following functions and objects: + .. function:: active_count() activeCount() Modified: python/branches/release26-maint/Doc/library/time.rst ============================================================================== --- python/branches/release26-maint/Doc/library/time.rst (original) +++ python/branches/release26-maint/Doc/library/time.rst Sun Apr 5 23:48:06 2009 @@ -118,6 +118,24 @@ The time value sequence was changed from a tuple to a :class:`struct_time`, with the addition of attribute names for the fields. +* Use the following functions to convert between time representations: + + +-------------------------+-------------------------+-------------------------+ + | From | To | Use | + +=========================+=========================+=========================+ + | seconds since the epoch | :class:`struct_time` in | :func:`gmtime` | + | | UTC | | + +-------------------------+-------------------------+-------------------------+ + | seconds since the epoch | :class:`struct_time` in | :func:`localtime` | + | | local time | | + +-------------------------+-------------------------+-------------------------+ + | :class:`struct_time` in | seconds since the epoch | :func:`calendar.timegm` | + | UTC | | | + +-------------------------+-------------------------+-------------------------+ + | :class:`struct_time` in | seconds since the epoch | :func:`mktime` | + | local time | | | + +-------------------------+-------------------------+-------------------------+ + The module defines the following functions and data items: Modified: python/branches/release26-maint/Doc/library/turtle.rst ============================================================================== --- python/branches/release26-maint/Doc/library/turtle.rst (original) +++ python/branches/release26-maint/Doc/library/turtle.rst Sun Apr 5 23:48:06 2009 @@ -61,7 +61,7 @@ The procedural interface provides functions which are derived from the methods of the classes :class:`Screen` and :class:`Turtle`. They have the same names as -the corresponding methods. A screen object is automativally created whenever a +the corresponding methods. A screen object is automatically created whenever a function derived from a Screen method is called. An (unnamed) turtle object is automatically created whenever any of the functions derived from a Turtle method is called. @@ -1608,7 +1608,7 @@ =========== =========== "polygon" a polygon-tuple, i.e. a tuple of pairs of coordinates "image" an image (in this form only used internally!) - "compound" ``None`` (a compund shape has to be constructed using the + "compound" ``None`` (a compound shape has to be constructed using the :meth:`addcomponent` method) =========== =========== @@ -1830,7 +1830,7 @@ It contains: -- a set of 15 demo scripts demonstrating differet features of the new module +- a set of 15 demo scripts demonstrating different features of the new module :mod:`turtle` - a demo viewer :file:`turtleDemo.py` which can be used to view the sourcecode of the scripts and run them at the same time. 14 of the examples can be Modified: python/branches/release26-maint/Doc/library/xml.dom.rst ============================================================================== --- python/branches/release26-maint/Doc/library/xml.dom.rst (original) +++ python/branches/release26-maint/Doc/library/xml.dom.rst Sun Apr 5 23:48:06 2009 @@ -611,7 +611,7 @@ Same as equivalent method in the :class:`Document` class. -.. method:: Element.getElementsByTagNameNS(tagName) +.. method:: Element.getElementsByTagNameNS(namespaceURI, localName) Same as equivalent method in the :class:`Document` class. Modified: python/branches/release26-maint/Doc/reference/datamodel.rst ============================================================================== --- python/branches/release26-maint/Doc/reference/datamodel.rst (original) +++ python/branches/release26-maint/Doc/reference/datamodel.rst Sun Apr 5 23:48:06 2009 @@ -1414,11 +1414,12 @@ .. index:: single: __len__() (mapping object method) - Called to implement truth value testing, and the built-in operation ``bool()``; + Called to implement truth value testing and the built-in operation ``bool()``; should return ``False`` or ``True``, or their integer equivalents ``0`` or - ``1``. When this method is not defined, :meth:`__len__` is called, if it is - defined (see below). If a class defines neither :meth:`__len__` nor - :meth:`__nonzero__`, all its instances are considered true. + ``1``. When this method is not defined, :meth:`__len__` is called, if it is + defined, and the object is considered true if its result is nonzero. + If a class defines neither :meth:`__len__` nor :meth:`__nonzero__`, all its + instances are considered true. .. method:: object.__unicode__(self) Modified: python/branches/release26-maint/Doc/reference/executionmodel.rst ============================================================================== --- python/branches/release26-maint/Doc/reference/executionmodel.rst (original) +++ python/branches/release26-maint/Doc/reference/executionmodel.rst Sun Apr 5 23:48:06 2009 @@ -87,9 +87,10 @@ The following constructs bind names: formal parameters to functions, :keyword:`import` statements, class and function definitions (these bind the class or function name in the defining block), and targets that are identifiers -if occurring in an assignment, :keyword:`for` loop header, or in the second -position of an :keyword:`except` clause header. The :keyword:`import` statement -of the form "``from ...import *``" binds all names defined in the imported +if occurring in an assignment, :keyword:`for` loop header, in the second +position of an :keyword:`except` clause header or after :keyword:`as` in a +:keyword:`with` statement. The :keyword:`import` statement +of the form ``from ... import *`` binds all names defined in the imported module, except those beginning with an underscore. This form may only be used at the module level. Modified: python/branches/release26-maint/Doc/whatsnew/2.6.rst ============================================================================== --- python/branches/release26-maint/Doc/whatsnew/2.6.rst (original) +++ python/branches/release26-maint/Doc/whatsnew/2.6.rst Sun Apr 5 23:48:06 2009 @@ -270,7 +270,7 @@ The expression is evaluated, and it should result in an object that supports the context management protocol (that is, has :meth:`__enter__` and :meth:`__exit__` -methods. +methods). The object's :meth:`__enter__` is called before *with-block* is executed and therefore can run set-up code. It also may return a value that is bound to the Modified: python/branches/release26-maint/Lib/test/test_struct.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_struct.py (original) +++ python/branches/release26-maint/Lib/test/test_struct.py Sun Apr 5 23:48:06 2009 @@ -512,6 +512,10 @@ self.assertRaises(struct.error, s.pack_into, small_buf, 0, test_string) self.assertRaises(struct.error, s.pack_into, small_buf, 2, test_string) + # Test bogus offset (issue 3694) + sb = small_buf + self.assertRaises(TypeError, struct.pack_into, b'1', sb, None) + def test_pack_into_fn(self): test_string = 'Reykjavik rocks, eow!' writable_buf = array.array('c', ' '*100) Modified: python/branches/release26-maint/Modules/_codecsmodule.c ============================================================================== --- python/branches/release26-maint/Modules/_codecsmodule.c (original) +++ python/branches/release26-maint/Modules/_codecsmodule.c Sun Apr 5 23:48:06 2009 @@ -61,7 +61,7 @@ "lookup(encoding) -> CodecInfo\n\ \n\ Looks up a codec tuple in the Python codec registry and returns\n\ -a tuple of function (or a CodecInfo object)."); +a CodecInfo object."); static PyObject *codec_lookup(PyObject *self, PyObject *args) Modified: python/branches/release26-maint/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/release26-maint/Modules/_ctypes/_ctypes.c (original) +++ python/branches/release26-maint/Modules/_ctypes/_ctypes.c Sun Apr 5 23:48:06 2009 @@ -599,13 +599,14 @@ #else address = (void *)ctypes_dlsym(handle, name); if (!address) { - PyErr_Format(PyExc_ValueError, #ifdef __CYGWIN__ /* dlerror() isn't very helpful on cygwin */ + PyErr_Format(PyExc_ValueError, "symbol '%s' not found (%s) ", - name, + name); +#else + PyErr_SetString(PyExc_ValueError, ctypes_dlerror()); #endif - ctypes_dlerror()); return NULL; } #endif @@ -3283,13 +3284,14 @@ #else address = (PPROC)ctypes_dlsym(handle, name); if (!address) { - PyErr_Format(PyExc_AttributeError, #ifdef __CYGWIN__ /* dlerror() isn't very helpful on cygwin */ + PyErr_Format(PyExc_AttributeError, "function '%s' not found (%s) ", - name, + name); +#else + PyErr_SetString(PyExc_AttributeError, ctypes_dlerror()); #endif - ctypes_dlerror()); return NULL; } #endif Modified: python/branches/release26-maint/Objects/typeobject.c ============================================================================== --- python/branches/release26-maint/Objects/typeobject.c (original) +++ python/branches/release26-maint/Objects/typeobject.c Sun Apr 5 23:48:06 2009 @@ -5092,6 +5092,7 @@ PyObject *func, *args; static PyObject *nonzero_str, *len_str; int result = -1; + int using_len = 0; func = lookup_maybe(self, "__nonzero__", &nonzero_str); if (func == NULL) { @@ -5100,6 +5101,7 @@ func = lookup_maybe(self, "__len__", &len_str); if (func == NULL) return PyErr_Occurred() ? -1 : 1; + using_len = 1; } args = PyTuple_New(0); if (args != NULL) { @@ -5110,8 +5112,10 @@ result = PyObject_IsTrue(temp); else { PyErr_Format(PyExc_TypeError, - "__nonzero__ should return " + "%s should return " "bool or int, returned %s", + (using_len ? "__len__" + : "__nonzero__"), temp->ob_type->tp_name); result = -1; } Modified: python/branches/release26-maint/Objects/unicodeobject.c ============================================================================== --- python/branches/release26-maint/Objects/unicodeobject.c (original) +++ python/branches/release26-maint/Objects/unicodeobject.c Sun Apr 5 23:48:06 2009 @@ -1385,7 +1385,7 @@ if (restuple == NULL) goto onError; if (!PyTuple_Check(restuple)) { - PyErr_Format(PyExc_TypeError, &argparse[4]); + PyErr_SetString(PyExc_TypeError, &argparse[4]); goto onError; } if (!PyArg_ParseTuple(restuple, argparse, &PyUnicode_Type, &repunicode, &newpos)) @@ -3440,7 +3440,7 @@ if (restuple == NULL) return NULL; if (!PyTuple_Check(restuple)) { - PyErr_Format(PyExc_TypeError, &argparse[4]); + PyErr_SetString(PyExc_TypeError, &argparse[4]); Py_DECREF(restuple); return NULL; } @@ -4712,7 +4712,7 @@ if (restuple == NULL) return NULL; if (!PyTuple_Check(restuple)) { - PyErr_Format(PyExc_TypeError, &argparse[4]); + PyErr_SetString(PyExc_TypeError, &argparse[4]); Py_DECREF(restuple); return NULL; } From python-checkins at python.org Sun Apr 5 23:48:32 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 5 Apr 2009 23:48:32 +0200 (CEST) Subject: [Python-checkins] r71283 - python/branches/release26-maint Message-ID: <20090405214832.EBB3B1E401A@bag.python.org> Author: georg.brandl Date: Sun Apr 5 23:48:32 2009 New Revision: 71283 Log: Blocked revisions 70405 via svnmerge ........ r70405 | georg.brandl | 2009-03-15 23:11:07 +0100 (So, 15 M?r 2009) | 7 lines Move the previously local import of threading to module level. This is cleaner and avoids lockups in obscure cases where a Queue is instantiated while the import lock is already held by another thread. OKed by Tim Peters. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Apr 5 23:49:36 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 5 Apr 2009 23:49:36 +0200 (CEST) Subject: [Python-checkins] r71284 - in python/branches/py3k: Lib/distutils/filelist.py Lib/distutils/tests/test_filelist.py Misc/NEWS Message-ID: <20090405214936.CE1A41E401A@bag.python.org> Author: tarek.ziade Date: Sun Apr 5 23:49:36 2009 New Revision: 71284 Log: Merged revisions 71280 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71280 | tarek.ziade | 2009-04-05 23:44:08 +0200 (Sun, 05 Apr 2009) | 1 line Fixed #1491431: distutils.filelist.glob_to_re was broken for some edge cases (detailed in the test ........ Added: python/branches/py3k/Lib/distutils/tests/test_filelist.py - copied unchanged from r71280, /python/trunk/Lib/distutils/tests/test_filelist.py Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/filelist.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/distutils/filelist.py ============================================================================== --- python/branches/py3k/Lib/distutils/filelist.py (original) +++ python/branches/py3k/Lib/distutils/filelist.py Sun Apr 5 23:49:36 2009 @@ -289,7 +289,8 @@ # character except the special characters. # XXX currently the "special characters" are just slash -- i.e. this is # Unix-only. - pattern_re = re.sub(r'(^|[^\\])\.', r'\1[^/]', pattern_re) + pattern_re = re.sub(r'((? Author: tarek.ziade Date: Sun Apr 5 23:52:04 2009 New Revision: 71285 Log: Merged revisions 71284 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71284 | tarek.ziade | 2009-04-05 23:49:36 +0200 (Sun, 05 Apr 2009) | 9 lines Merged revisions 71280 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71280 | tarek.ziade | 2009-04-05 23:44:08 +0200 (Sun, 05 Apr 2009) | 1 line Fixed #1491431: distutils.filelist.glob_to_re was broken for some edge cases (detailed in the test ........ ................ Added: python/branches/release30-maint/Lib/distutils/tests/test_filelist.py - copied unchanged from r71284, /python/branches/py3k/Lib/distutils/tests/test_filelist.py Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Lib/distutils/filelist.py python/branches/release30-maint/Misc/NEWS Modified: python/branches/release30-maint/Lib/distutils/filelist.py ============================================================================== --- python/branches/release30-maint/Lib/distutils/filelist.py (original) +++ python/branches/release30-maint/Lib/distutils/filelist.py Sun Apr 5 23:52:04 2009 @@ -289,7 +289,8 @@ # character except the special characters. # XXX currently the "special characters" are just slash -- i.e. this is # Unix-only. - pattern_re = re.sub(r'(^|[^\\])\.', r'\1[^/]', pattern_re) + pattern_re = re.sub(r'((? The Buildbot has detected a new failure of OS X x86 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/OS%20X%20x86%202.6/builds/183 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: noller-osx86 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_string make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 6 00:04:38 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 6 Apr 2009 00:04:38 +0200 (CEST) Subject: [Python-checkins] r71286 - python/trunk/Lib/distutils/tests/test_spawn.py Message-ID: <20090405220438.E39EB1E401A@bag.python.org> Author: tarek.ziade Date: Mon Apr 6 00:04:38 2009 New Revision: 71286 Log: added a simplest test to distutils.spawn._nt_quote_args Added: python/trunk/Lib/distutils/tests/test_spawn.py (contents, props changed) Added: python/trunk/Lib/distutils/tests/test_spawn.py ============================================================================== --- (empty file) +++ python/trunk/Lib/distutils/tests/test_spawn.py Mon Apr 6 00:04:38 2009 @@ -0,0 +1,20 @@ +"""Tests for distutils.spawn.""" +import unittest +from distutils.spawn import _nt_quote_args + +class SpawnTestCase(unittest.TestCase): + + def test_nt_quote_args(self): + + for (args, wanted) in ((['with space', 'nospace'], + ['"with space"', 'nospace']), + (['nochange', 'nospace'], + ['nochange', 'nospace'])): + res = _nt_quote_args(args) + self.assertEquals(res, wanted) + +def test_suite(): + return unittest.makeSuite(SpawnTestCase) + +if __name__ == "__main__": + unittest.main(defaultTest="test_suite") From python-checkins at python.org Mon Apr 6 00:11:44 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 6 Apr 2009 00:11:44 +0200 (CEST) Subject: [Python-checkins] r71287 - in python/branches/py3k-short-float-repr: Doc/c-api/init.rst Doc/c-api/number.rst Doc/c-api/object.rst Doc/c-api/structures.rst Doc/c-api/veryhigh.rst Doc/distutils/apiref.rst Doc/extending/extending.rst Doc/howto/cporting.rst Doc/library/abc.rst Doc/library/doctest.rst Doc/library/functions.rst Doc/library/itertools.rst Doc/library/logging.rst Doc/library/multiprocessing.rst Doc/library/os.path.rst Doc/library/os.rst Doc/library/pdb.rst Doc/library/pickle.rst Doc/library/re.rst Doc/library/shelve.rst Doc/library/socketserver.rst Doc/library/ssl.rst Doc/library/stdtypes.rst Doc/library/sys.rst Doc/library/threading.rst Doc/library/tkinter.ttk.rst Doc/library/urllib.request.rst Doc/library/webbrowser.rst Doc/library/winreg.rst Doc/reference/datamodel.rst Doc/tutorial/datastructures.rst Doc/tutorial/introduction.rst Doc/whatsnew/2.6.rst Doc/whatsnew/2.7.rst Include/patchlevel.h Lib/distutils/cmd.py Lib/distutils/log.py Lib/distutils/tests/test_clean.py Lib/ftplib.py Lib/glob.py Lib/multiprocessing/synchronize.py Lib/optparse.py Lib/pdb.py Lib/pydoc.py Lib/test/README Lib/test/test_logging.py Lib/test/test_multiprocessing.py Lib/test/test_pprint.py Lib/test/test_sys.py Lib/test/test_threading.py Lib/test/test_traceback.py Lib/threading.py Lib/traceback.py Makefile.pre.in Misc/ACKS Misc/NEWS Misc/developers.txt Modules/_io/_iomodule.c Modules/_io/bufferedio.c Modules/_multiprocessing/connection.h Modules/_multiprocessing/multiprocessing.c Modules/_multiprocessing/multiprocessing.h Modules/_multiprocessing/pipe_connection.c Modules/_multiprocessing/semaphore.c Modules/_sqlite/connection.c Modules/_sqlite/module.c Modules/_tkinter.c Objects/genobject.c Objects/object.c configure configure.in pyconfig.h.in setup.py Message-ID: <20090405221144.3FB0E1E401A@bag.python.org> Author: eric.smith Date: Mon Apr 6 00:11:42 2009 New Revision: 71287 Log: Merged revisions 71202,71205,71207,71209,71223-71224,71239,71242,71254,71259,71261-71262,71267,71274 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71202 | benjamin.peterson | 2009-04-04 19:16:41 -0400 (Sat, 04 Apr 2009) | 1 line bump version for 3.1a2+ ................ r71205 | benjamin.peterson | 2009-04-04 20:46:27 -0400 (Sat, 04 Apr 2009) | 1 line fix typo #5687 ................ r71207 | benjamin.peterson | 2009-04-04 21:13:10 -0400 (Sat, 04 Apr 2009) | 8 lines Blocked revisions 71206 via svnmerge ........ r71206 | benjamin.peterson | 2009-04-04 20:04:38 -0500 (Sat, 04 Apr 2009) | 1 line compare types with is ........ ................ r71209 | alexandre.vassalotti | 2009-04-04 21:30:02 -0400 (Sat, 04 Apr 2009) | 2 lines Initialize the tk_init_failed static variable to 0. ................ r71223 | georg.brandl | 2009-04-05 07:11:12 -0400 (Sun, 05 Apr 2009) | 1 line #5606: fix formatter.h dependencies in the Makefile. ................ r71224 | georg.brandl | 2009-04-05 07:47:34 -0400 (Sun, 05 Apr 2009) | 1 line Merge revision 71222 from trunk: #5615: make it possible to configure --without-threads again. ................ r71239 | georg.brandl | 2009-04-05 10:28:42 -0400 (Sun, 05 Apr 2009) | 13 lines Merged revisions 71237-71238 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71237 | georg.brandl | 2009-04-05 16:24:52 +0200 (So, 05 Apr 2009) | 1 line #1326077: fix traceback formatting of SyntaxErrors. This fixes two differences with formatting coming from Python: a) the reproduction of location details in the error message if no line text is given, b) the prefixing of the last line by one space. ........ r71238 | georg.brandl | 2009-04-05 16:25:41 +0200 (So, 05 Apr 2009) | 1 line Add NEWS entry for r71237. ........ ................ r71242 | georg.brandl | 2009-04-05 11:05:48 -0400 (Sun, 05 Apr 2009) | 1 line #5453: fix SyntaxErrors using pydoc -k, caused by intentionally bad files in Pythons test suite. ................ r71254 | tarek.ziade | 2009-04-05 14:33:34 -0400 (Sun, 05 Apr 2009) | 9 lines Merged revisions 71253 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71253 | tarek.ziade | 2009-04-05 20:31:24 +0200 (Sun, 05 Apr 2009) | 1 line Fixed 5694: removed spurious test output in Distutils ........ ................ r71259 | brett.cannon | 2009-04-05 14:57:32 -0400 (Sun, 05 Apr 2009) | 8 lines Blocked revisions 71221 via svnmerge ........ r71221 | vinay.sajip | 2009-04-05 04:06:24 -0700 (Sun, 05 Apr 2009) | 1 line Issue #5695: Moved logging.captureWarnings() call inside with statement in WarningsTest.test_warnings. ........ ................ r71261 | benjamin.peterson | 2009-04-05 15:13:16 -0400 (Sun, 05 Apr 2009) | 295 lines Merged revisions 70712,70714,70764-70765,70769-70771,70773,70776-70777,70788-70789,70824,70828,70832,70836,70842,70851,70855,70857,70866-70872,70883,70885,70893-70894,70896-70897,70903,70905-70907,70915,70927,70933,70951,70960,70962-70964,70998,71001,71006,71008,71010-71011,71019,71037,71056,71094,71101-71103,71106,71119,71123,71149-71150,71203,71212,71214-71217,71221,71240 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70712 | benjamin.peterson | 2009-03-30 10:15:38 -0500 (Mon, 30 Mar 2009) | 1 line don't rely on the order dict repr #5605 ........ r70714 | brett.cannon | 2009-03-30 10:20:53 -0500 (Mon, 30 Mar 2009) | 1 line Add an entry to developers.txt. ........ r70764 | martin.v.loewis | 2009-03-30 17:06:33 -0500 (Mon, 30 Mar 2009) | 2 lines Add several VM developers. ........ r70765 | georg.brandl | 2009-03-30 17:09:34 -0500 (Mon, 30 Mar 2009) | 1 line #5199: make warning about vars() assignment more visible. ........ r70769 | andrew.kuchling | 2009-03-30 17:29:53 -0500 (Mon, 30 Mar 2009) | 1 line Remove comment ........ r70770 | andrew.kuchling | 2009-03-30 17:30:20 -0500 (Mon, 30 Mar 2009) | 1 line Add several items and placeholders ........ r70771 | andrew.kuchling | 2009-03-30 17:31:11 -0500 (Mon, 30 Mar 2009) | 1 line Many edits ........ r70773 | georg.brandl | 2009-03-30 17:43:00 -0500 (Mon, 30 Mar 2009) | 1 line #5039: make it clear that the impl. note refers to CPython. ........ r70776 | andrew.kuchling | 2009-03-30 18:08:24 -0500 (Mon, 30 Mar 2009) | 1 line typo fix ........ r70777 | andrew.kuchling | 2009-03-30 18:09:46 -0500 (Mon, 30 Mar 2009) | 1 line Add more items ........ r70788 | andrew.kuchling | 2009-03-30 20:21:01 -0500 (Mon, 30 Mar 2009) | 1 line Add various items ........ r70789 | georg.brandl | 2009-03-30 20:25:15 -0500 (Mon, 30 Mar 2009) | 1 line Fix a wrong struct field assignment (docstring as closure). ........ r70824 | georg.brandl | 2009-03-31 10:43:20 -0500 (Tue, 31 Mar 2009) | 1 line #5519: remove reference to Kodos, which seems dead. ........ r70828 | georg.brandl | 2009-03-31 10:50:16 -0500 (Tue, 31 Mar 2009) | 1 line #5581: fget argument of abstractproperty is optional as well. ........ r70832 | georg.brandl | 2009-03-31 11:31:11 -0500 (Tue, 31 Mar 2009) | 1 line #1386675: specify WindowsError as the exception, because it has a winerror attribute that EnvironmentError doesnt have. ........ r70836 | georg.brandl | 2009-03-31 11:50:25 -0500 (Tue, 31 Mar 2009) | 1 line #5417: replace references to undocumented functions by ones to documented functions. ........ r70842 | georg.brandl | 2009-03-31 12:13:06 -0500 (Tue, 31 Mar 2009) | 1 line #970783: document PyObject_Generic[GS]etAttr. ........ r70851 | georg.brandl | 2009-03-31 13:26:55 -0500 (Tue, 31 Mar 2009) | 1 line #837577: note cryptic return value of spawn*e on invalid env dicts. ........ r70855 | georg.brandl | 2009-03-31 13:30:37 -0500 (Tue, 31 Mar 2009) | 1 line #5245: note that PyRun_SimpleString doesnt return on SystemExit. ........ r70857 | georg.brandl | 2009-03-31 13:33:10 -0500 (Tue, 31 Mar 2009) | 1 line #5227: note that Py_Main doesnt return on SystemExit. ........ r70866 | georg.brandl | 2009-03-31 14:06:57 -0500 (Tue, 31 Mar 2009) | 1 line #4882: document named group behavior a bit better. ........ r70867 | georg.brandl | 2009-03-31 14:10:35 -0500 (Tue, 31 Mar 2009) | 1 line #1096310: document usage of sys.__std*__ a bit better. ........ r70868 | georg.brandl | 2009-03-31 14:12:17 -0500 (Tue, 31 Mar 2009) | 1 line #5190: export make_option in __all__. ........ r70869 | georg.brandl | 2009-03-31 14:14:42 -0500 (Tue, 31 Mar 2009) | 1 line Fix-up unwanted change. ........ r70870 | georg.brandl | 2009-03-31 14:26:24 -0500 (Tue, 31 Mar 2009) | 1 line #4411: document mro() and __mro__. (I hope I got it right.) ........ r70871 | georg.brandl | 2009-03-31 14:30:56 -0500 (Tue, 31 Mar 2009) | 1 line #5618: fix typo. ........ r70872 | r.david.murray | 2009-03-31 14:31:17 -0500 (Tue, 31 Mar 2009) | 3 lines Delete out-of-date and little-known README from the test directory by consensus of devs at pycon sprint. ........ r70883 | georg.brandl | 2009-03-31 15:41:08 -0500 (Tue, 31 Mar 2009) | 1 line #1674032: return value of flag from Event.wait(). OKed by Guido. ........ r70885 | tarek.ziade | 2009-03-31 15:48:31 -0500 (Tue, 31 Mar 2009) | 1 line using log.warn for sys.stderr ........ r70893 | georg.brandl | 2009-03-31 15:56:32 -0500 (Tue, 31 Mar 2009) | 1 line #1530012: move TQS section before raw strings. ........ r70894 | benjamin.peterson | 2009-03-31 16:06:30 -0500 (Tue, 31 Mar 2009) | 1 line take the usual lock precautions around _active_limbo_lock ........ r70896 | georg.brandl | 2009-03-31 16:15:33 -0500 (Tue, 31 Mar 2009) | 1 line #5598: document DocFileSuite *args argument. ........ r70897 | benjamin.peterson | 2009-03-31 16:34:42 -0500 (Tue, 31 Mar 2009) | 1 line fix Thread.ident when it is the main thread or a dummy thread #5632 ........ r70903 | georg.brandl | 2009-03-31 16:45:18 -0500 (Tue, 31 Mar 2009) | 1 line #1676135: remove trailing slashes from --prefix argument. ........ r70905 | georg.brandl | 2009-03-31 17:03:40 -0500 (Tue, 31 Mar 2009) | 1 line #5563: more documentation for bdist_msi. ........ r70906 | georg.brandl | 2009-03-31 17:11:53 -0500 (Tue, 31 Mar 2009) | 1 line #1651995: fix _convert_ref for non-ASCII characters. ........ r70907 | georg.brandl | 2009-03-31 17:18:19 -0500 (Tue, 31 Mar 2009) | 1 line #3427: document correct return type for urlopen().info(). ........ r70915 | georg.brandl | 2009-03-31 17:40:16 -0500 (Tue, 31 Mar 2009) | 1 line #5018: remove confusing paragraph. ........ r70927 | georg.brandl | 2009-03-31 18:01:27 -0500 (Tue, 31 Mar 2009) | 1 line Dont shout to users. ........ r70933 | georg.brandl | 2009-03-31 19:04:33 -0500 (Tue, 31 Mar 2009) | 2 lines Issue #5635: Fix running test_sys with tracing enabled. ........ r70951 | georg.brandl | 2009-04-01 09:02:27 -0500 (Wed, 01 Apr 2009) | 1 line Add Maksim, who worked on several issues at the sprint. ........ r70960 | jesse.noller | 2009-04-01 11:42:19 -0500 (Wed, 01 Apr 2009) | 1 line Issue 3270: document Listener address restrictions on windows ........ r70962 | brett.cannon | 2009-04-01 12:07:16 -0500 (Wed, 01 Apr 2009) | 2 lines Ron DuPlain was given commit privileges at PyCon 2009 to work on 3to2. ........ r70963 | georg.brandl | 2009-04-01 12:46:01 -0500 (Wed, 01 Apr 2009) | 1 line #5655: fix docstring oversight. ........ r70964 | brett.cannon | 2009-04-01 12:52:13 -0500 (Wed, 01 Apr 2009) | 2 lines Paul Kippes was given commit privileges to work on 3to2. ........ r70998 | georg.brandl | 2009-04-01 16:54:21 -0500 (Wed, 01 Apr 2009) | 1 line In Pdb, stop assigning values to __builtin__._ which interferes with the one commonly installed by gettext. ........ r71001 | brett.cannon | 2009-04-01 18:01:12 -0500 (Wed, 01 Apr 2009) | 3 lines Add my initials to Misc/developers.txt. Names are now sorted by number of characters in the person's name. ........ r71006 | georg.brandl | 2009-04-01 18:32:17 -0500 (Wed, 01 Apr 2009) | 1 line Cache the f_locals dict of the current frame, since every access to frame.f_locals overrides its contents with the real locals which undoes modifications made by the debugging user. ........ r71008 | andrew.kuchling | 2009-04-01 19:02:14 -0500 (Wed, 01 Apr 2009) | 1 line Typo fix ........ r71010 | benjamin.peterson | 2009-04-01 19:11:52 -0500 (Wed, 01 Apr 2009) | 1 line fix markup ........ r71011 | benjamin.peterson | 2009-04-01 19:12:47 -0500 (Wed, 01 Apr 2009) | 1 line this should be :noindex: ........ r71019 | georg.brandl | 2009-04-01 21:00:01 -0500 (Wed, 01 Apr 2009) | 1 line Fix test_doctest, missed two assignments to curframe. ........ r71037 | r.david.murray | 2009-04-01 23:34:04 -0500 (Wed, 01 Apr 2009) | 6 lines Clarify that datetime strftime does not produce leap seconds and datetime strptime does not accept it in the strftime behavior section of the datetime docs. Closes issue 2568. ........ r71056 | georg.brandl | 2009-04-02 12:43:07 -0500 (Thu, 02 Apr 2009) | 2 lines Actually the displayhook should print the repr. ........ r71094 | vinay.sajip | 2009-04-03 05:23:18 -0500 (Fri, 03 Apr 2009) | 1 line Added warning about logging use from asynchronous signal handlers. ........ r71101 | andrew.kuchling | 2009-04-03 16:43:00 -0500 (Fri, 03 Apr 2009) | 1 line Add some items ........ r71102 | andrew.kuchling | 2009-04-03 16:44:49 -0500 (Fri, 03 Apr 2009) | 1 line Fix 'the the'; grammar fix ........ r71103 | andrew.kuchling | 2009-04-03 16:45:29 -0500 (Fri, 03 Apr 2009) | 1 line Fix 'the the' duplication ........ r71106 | vinay.sajip | 2009-04-03 16:58:16 -0500 (Fri, 03 Apr 2009) | 1 line Clarified warning about logging use from asynchronous signal handlers. ........ r71119 | raymond.hettinger | 2009-04-04 00:37:47 -0500 (Sat, 04 Apr 2009) | 1 line Add helpful link. ........ r71123 | r.david.murray | 2009-04-04 01:39:56 -0500 (Sat, 04 Apr 2009) | 2 lines Fix error in description of 'oct' (issue 5678). ........ r71149 | georg.brandl | 2009-04-04 08:42:39 -0500 (Sat, 04 Apr 2009) | 1 line #5642: clarify map() compatibility to the builtin. ........ r71150 | georg.brandl | 2009-04-04 08:45:49 -0500 (Sat, 04 Apr 2009) | 1 line #5601: clarify that webbrowser is not meant for file names. ........ r71203 | benjamin.peterson | 2009-04-04 18:46:34 -0500 (Sat, 04 Apr 2009) | 1 line note how using iter* are unsafe while mutating and document iter(dict) ........ r71212 | georg.brandl | 2009-04-05 05:24:20 -0500 (Sun, 05 Apr 2009) | 1 line #1742837: expand HTTP server docs, and fix SocketServer ones to document methods as methods, not functions. ........ r71214 | georg.brandl | 2009-04-05 05:29:57 -0500 (Sun, 05 Apr 2009) | 1 line Normalize spelling of Mac OS X. ........ r71215 | georg.brandl | 2009-04-05 05:32:26 -0500 (Sun, 05 Apr 2009) | 1 line Avoid sure signs of a diseased mind. ........ r71216 | georg.brandl | 2009-04-05 05:41:02 -0500 (Sun, 05 Apr 2009) | 1 line #1718017: document the relation of os.path and the posixpath, ntpath etc. modules better. ........ r71217 | georg.brandl | 2009-04-05 05:48:47 -0500 (Sun, 05 Apr 2009) | 1 line #1726172: dont raise an unexpected IndexError if a voidresp() call has an empty response. ........ r71221 | vinay.sajip | 2009-04-05 06:06:24 -0500 (Sun, 05 Apr 2009) | 1 line Issue #5695: Moved logging.captureWarnings() call inside with statement in WarningsTest.test_warnings. ........ r71240 | georg.brandl | 2009-04-05 09:40:06 -0500 (Sun, 05 Apr 2009) | 1 line #5370: doc update about unpickling objects with custom __getattr__ etc. methods. ........ ................ r71262 | benjamin.peterson | 2009-04-05 15:15:51 -0400 (Sun, 05 Apr 2009) | 8 lines Blocked revisions 71253 via svnmerge ........ r71253 | tarek.ziade | 2009-04-05 13:31:24 -0500 (Sun, 05 Apr 2009) | 1 line Fixed 5694: removed spurious test output in Distutils ........ ................ r71267 | georg.brandl | 2009-04-05 16:24:29 -0400 (Sun, 05 Apr 2009) | 1 line Normalize issue referencing style. ................ r71274 | benjamin.peterson | 2009-04-05 17:24:58 -0400 (Sun, 05 Apr 2009) | 25 lines Merged revisions 70908,70939,71009,71022,71036 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70908 | jesse.noller | 2009-03-31 17:20:35 -0500 (Tue, 31 Mar 2009) | 1 line Issue 5619: Pass MS CRT debug flags into subprocesses ........ r70939 | jesse.noller | 2009-03-31 22:45:50 -0500 (Tue, 31 Mar 2009) | 1 line Fix multiprocessing.event to match the new threading.Event API ........ r71009 | jesse.noller | 2009-04-01 19:03:28 -0500 (Wed, 01 Apr 2009) | 1 line issue5545: Switch to Autoconf for multiprocessing; special thanks to Martin Lowis for help ........ r71022 | jesse.noller | 2009-04-01 21:32:55 -0500 (Wed, 01 Apr 2009) | 1 line Issue 3110: Additional protection for SEM_VALUE_MAX on platforms, thanks to Martin Loewis ........ r71036 | jesse.noller | 2009-04-01 23:22:09 -0500 (Wed, 01 Apr 2009) | 1 line Issue 3551: Raise ValueError if the size causes ERROR_NO_SYSTEM_RESOURCES ........ ................ Removed: python/branches/py3k-short-float-repr/Lib/test/README Modified: python/branches/py3k-short-float-repr/ (props changed) python/branches/py3k-short-float-repr/Doc/c-api/init.rst python/branches/py3k-short-float-repr/Doc/c-api/number.rst python/branches/py3k-short-float-repr/Doc/c-api/object.rst python/branches/py3k-short-float-repr/Doc/c-api/structures.rst python/branches/py3k-short-float-repr/Doc/c-api/veryhigh.rst python/branches/py3k-short-float-repr/Doc/distutils/apiref.rst python/branches/py3k-short-float-repr/Doc/extending/extending.rst python/branches/py3k-short-float-repr/Doc/howto/cporting.rst python/branches/py3k-short-float-repr/Doc/library/abc.rst python/branches/py3k-short-float-repr/Doc/library/doctest.rst python/branches/py3k-short-float-repr/Doc/library/functions.rst python/branches/py3k-short-float-repr/Doc/library/itertools.rst python/branches/py3k-short-float-repr/Doc/library/logging.rst python/branches/py3k-short-float-repr/Doc/library/multiprocessing.rst python/branches/py3k-short-float-repr/Doc/library/os.path.rst python/branches/py3k-short-float-repr/Doc/library/os.rst python/branches/py3k-short-float-repr/Doc/library/pdb.rst python/branches/py3k-short-float-repr/Doc/library/pickle.rst python/branches/py3k-short-float-repr/Doc/library/re.rst python/branches/py3k-short-float-repr/Doc/library/shelve.rst python/branches/py3k-short-float-repr/Doc/library/socketserver.rst python/branches/py3k-short-float-repr/Doc/library/ssl.rst python/branches/py3k-short-float-repr/Doc/library/stdtypes.rst python/branches/py3k-short-float-repr/Doc/library/sys.rst python/branches/py3k-short-float-repr/Doc/library/threading.rst python/branches/py3k-short-float-repr/Doc/library/tkinter.ttk.rst python/branches/py3k-short-float-repr/Doc/library/urllib.request.rst python/branches/py3k-short-float-repr/Doc/library/webbrowser.rst python/branches/py3k-short-float-repr/Doc/library/winreg.rst python/branches/py3k-short-float-repr/Doc/reference/datamodel.rst python/branches/py3k-short-float-repr/Doc/tutorial/datastructures.rst python/branches/py3k-short-float-repr/Doc/tutorial/introduction.rst python/branches/py3k-short-float-repr/Doc/whatsnew/2.6.rst python/branches/py3k-short-float-repr/Doc/whatsnew/2.7.rst python/branches/py3k-short-float-repr/Include/patchlevel.h python/branches/py3k-short-float-repr/Lib/distutils/cmd.py python/branches/py3k-short-float-repr/Lib/distutils/log.py python/branches/py3k-short-float-repr/Lib/distutils/tests/test_clean.py python/branches/py3k-short-float-repr/Lib/ftplib.py python/branches/py3k-short-float-repr/Lib/glob.py python/branches/py3k-short-float-repr/Lib/multiprocessing/synchronize.py python/branches/py3k-short-float-repr/Lib/optparse.py python/branches/py3k-short-float-repr/Lib/pdb.py python/branches/py3k-short-float-repr/Lib/pydoc.py python/branches/py3k-short-float-repr/Lib/test/test_logging.py python/branches/py3k-short-float-repr/Lib/test/test_multiprocessing.py python/branches/py3k-short-float-repr/Lib/test/test_pprint.py python/branches/py3k-short-float-repr/Lib/test/test_sys.py python/branches/py3k-short-float-repr/Lib/test/test_threading.py python/branches/py3k-short-float-repr/Lib/test/test_traceback.py python/branches/py3k-short-float-repr/Lib/threading.py python/branches/py3k-short-float-repr/Lib/traceback.py python/branches/py3k-short-float-repr/Makefile.pre.in python/branches/py3k-short-float-repr/Misc/ACKS python/branches/py3k-short-float-repr/Misc/NEWS python/branches/py3k-short-float-repr/Misc/developers.txt python/branches/py3k-short-float-repr/Modules/_io/_iomodule.c python/branches/py3k-short-float-repr/Modules/_io/bufferedio.c python/branches/py3k-short-float-repr/Modules/_multiprocessing/connection.h python/branches/py3k-short-float-repr/Modules/_multiprocessing/multiprocessing.c python/branches/py3k-short-float-repr/Modules/_multiprocessing/multiprocessing.h python/branches/py3k-short-float-repr/Modules/_multiprocessing/pipe_connection.c python/branches/py3k-short-float-repr/Modules/_multiprocessing/semaphore.c python/branches/py3k-short-float-repr/Modules/_sqlite/connection.c python/branches/py3k-short-float-repr/Modules/_sqlite/module.c python/branches/py3k-short-float-repr/Modules/_tkinter.c python/branches/py3k-short-float-repr/Objects/genobject.c python/branches/py3k-short-float-repr/Objects/object.c python/branches/py3k-short-float-repr/configure python/branches/py3k-short-float-repr/configure.in python/branches/py3k-short-float-repr/pyconfig.h.in python/branches/py3k-short-float-repr/setup.py Modified: python/branches/py3k-short-float-repr/Doc/c-api/init.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/c-api/init.rst (original) +++ python/branches/py3k-short-float-repr/Doc/c-api/init.rst Mon Apr 6 00:11:42 2009 @@ -787,7 +787,7 @@ Asynchronous Notifications ========================== -A mechanism is provided to make asynchronous notifications to the the main +A mechanism is provided to make asynchronous notifications to the main interpreter thread. These notifications take the form of a function pointer and a void argument. Modified: python/branches/py3k-short-float-repr/Doc/c-api/number.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/c-api/number.rst (original) +++ python/branches/py3k-short-float-repr/Doc/c-api/number.rst Mon Apr 6 00:11:42 2009 @@ -264,8 +264,8 @@ .. cfunction:: PyObject* PyNumber_ToBase(PyObject *n, int base) - Returns the the integer *n* converted to *base* as a string with a base - marker of ``'0b'``, ``'0o'``, or ``'0x'`` if appended applicable. When + Returns the integer *n* converted to *base* as a string with a base + marker of ``'0b'``, ``'0o'``, or ``'0x'`` if applicable. When *base* is not 2, 8, 10, or 16, the format is ``'x#num'`` where x is the base. If *n* is not an int object, it is converted with :cfunc:`PyNumber_Index` first. Modified: python/branches/py3k-short-float-repr/Doc/c-api/object.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/c-api/object.rst (original) +++ python/branches/py3k-short-float-repr/Doc/c-api/object.rst Mon Apr 6 00:11:42 2009 @@ -42,6 +42,16 @@ expression ``o.attr_name``. +.. cfunction:: PyObject* PyObject_GenericGetAttr(PyObject *o, PyObject *name) + + Generic attribute getter function that is meant to be put into a type + object's ``tp_getattro`` slot. It looks for a descriptor in the dictionary + of classes in the object's MRO as well as an attribute in the object's + :attr:`__dict__` (if present). As outlined in :ref:`descriptors`, data + descriptors take preference over instance attributes, while non-data + descriptors don't. Otherwise, an :exc:`AttributeError` is raised. + + .. cfunction:: int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v) Set the value of the attribute named *attr_name*, for object *o*, to the value @@ -56,6 +66,16 @@ ``o.attr_name = v``. +.. cfunction:: int PyObject_GenericSetAttr(PyObject *o, PyObject *name, PyObject *value) + + Generic attribute setter function that is meant to be put into a type + object's ``tp_setattro`` slot. It looks for a data descriptor in the + dictionary of classes in the object's MRO, and if found it takes preference + over setting the attribute in the instance dictionary. Otherwise, the + attribute is set in the object's :attr:`__dict__` (if present). Otherwise, + an :exc:`AttributeError` is raised and ``-1`` is returned. + + .. cfunction:: int PyObject_DelAttr(PyObject *o, PyObject *attr_name) Delete attribute named *attr_name*, for object *o*. Returns ``-1`` on failure. Modified: python/branches/py3k-short-float-repr/Doc/c-api/structures.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/c-api/structures.rst (original) +++ python/branches/py3k-short-float-repr/Doc/c-api/structures.rst Mon Apr 6 00:11:42 2009 @@ -241,7 +241,7 @@ T_OBJECT_EX PyObject \* T_CHAR char T_BYTE char - T_UNBYTE unsigned char + T_UBYTE unsigned char T_UINT unsigned int T_USHORT unsigned short T_ULONG unsigned long Modified: python/branches/py3k-short-float-repr/Doc/c-api/veryhigh.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/c-api/veryhigh.rst (original) +++ python/branches/py3k-short-float-repr/Doc/c-api/veryhigh.rst Mon Apr 6 00:11:42 2009 @@ -38,6 +38,10 @@ interpreter exits due to an exception, or ``2`` if the parameter list does not represent a valid Python command line. + Note that if an otherwise unhandled :exc:`SystemError` is raised, this + function will not return ``1``, but exit the process, as long as + ``Py_InspectFlag`` is not set. + .. cfunction:: int PyRun_AnyFile(FILE *fp, const char *filename) @@ -80,6 +84,10 @@ there was an error, there is no way to get the exception information. For the meaning of *flags*, see below. + Note that if an otherwise unhandled :exc:`SystemError` is raised, this + function will not return ``-1``, but exit the process, as long as + ``Py_InspectFlag`` is not set. + .. cfunction:: int PyRun_SimpleFile(FILE *fp, const char *filename) Modified: python/branches/py3k-short-float-repr/Doc/distutils/apiref.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/distutils/apiref.rst (original) +++ python/branches/py3k-short-float-repr/Doc/distutils/apiref.rst Mon Apr 6 00:11:42 2009 @@ -1050,8 +1050,8 @@ .. warning:: - Handles cross-device moves on Unix using :func:`copy_file`. What about other - systems??? + Handles cross-device moves on Unix using :func:`copy_file`. What about + other systems? .. function:: write_file(filename, contents) @@ -1091,17 +1091,17 @@ For non-POSIX platforms, currently just returns ``sys.platform``. - For MacOS X systems the OS version reflects the minimal version on which + For Mac OS X systems the OS version reflects the minimal version on which binaries will run (that is, the value of ``MACOSX_DEPLOYMENT_TARGET`` during the build of Python), not the OS version of the current system. - For universal binary builds on MacOS X the architecture value reflects + For universal binary builds on Mac OS X the architecture value reflects the univeral binary status instead of the architecture of the current processor. For 32-bit universal binaries the architecture is ``fat``, for 64-bit universal binaries the architecture is ``fat64``, and for 4-way universal binaries the architecture is ``universal``. - Examples of returned values on MacOS X: + Examples of returned values on Mac OS X: * ``macosx-10.3-ppc`` @@ -1758,8 +1758,16 @@ .. module:: distutils.command.bdist_msi :synopsis: Build a binary distribution as a Windows MSI file +.. class:: bdist_msi(Command) -.. % todo + Builds a `Windows Installer`_ (.msi) binary package. + + .. _Windows Installer: http://msdn.microsoft.com/en-us/library/cc185688(VS.85).aspx + + In most cases, the ``bdist_msi`` installer is a better choice than the + ``bdist_wininst`` installer, because it provides better support for + Win64 platforms, allows administrators to perform non-interactive + installations, and allows installation through group policies. :mod:`distutils.command.bdist_rpm` --- Build a binary distribution as a Redhat RPM and SRPM Modified: python/branches/py3k-short-float-repr/Doc/extending/extending.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/extending/extending.rst (original) +++ python/branches/py3k-short-float-repr/Doc/extending/extending.rst Mon Apr 6 00:11:42 2009 @@ -476,10 +476,10 @@ (but note that *temp* will not be *NULL* in this context). More info on them in section :ref:`refcounts`. -.. index:: single: PyEval_CallObject() +.. index:: single: PyObject_CallObject() Later, when it is time to call the function, you call the C function -:cfunc:`PyEval_CallObject`. This function has two arguments, both pointers to +:cfunc:`PyObject_CallObject`. This function has two arguments, both pointers to arbitrary Python objects: the Python function, and the argument list. The argument list must always be a tuple object, whose length is the number of arguments. To call the Python function with no arguments, pass in NULL, or @@ -495,16 +495,16 @@ ... /* Time to call the callback */ arglist = Py_BuildValue("(i)", arg); - result = PyEval_CallObject(my_callback, arglist); + result = PyObject_CallObject(my_callback, arglist); Py_DECREF(arglist); -:cfunc:`PyEval_CallObject` returns a Python object pointer: this is the return -value of the Python function. :cfunc:`PyEval_CallObject` is +:cfunc:`PyObject_CallObject` returns a Python object pointer: this is the return +value of the Python function. :cfunc:`PyObject_CallObject` is "reference-count-neutral" with respect to its arguments. In the example a new tuple was created to serve as the argument list, which is :cfunc:`Py_DECREF`\ -ed immediately after the call. -The return value of :cfunc:`PyEval_CallObject` is "new": either it is a brand +The return value of :cfunc:`PyObject_CallObject` is "new": either it is a brand new object, or it is an existing object whose reference count has been incremented. So, unless you want to save it in a global variable, you should somehow :cfunc:`Py_DECREF` the result, even (especially!) if you are not @@ -512,7 +512,7 @@ Before you do this, however, it is important to check that the return value isn't *NULL*. If it is, the Python function terminated by raising an exception. -If the C code that called :cfunc:`PyEval_CallObject` is called from Python, it +If the C code that called :cfunc:`PyObject_CallObject` is called from Python, it should now return an error indication to its Python caller, so the interpreter can print a stack trace, or the calling Python code can handle the exception. If this is not possible or desirable, the exception should be cleared by calling @@ -524,7 +524,7 @@ Py_DECREF(result); Depending on the desired interface to the Python callback function, you may also -have to provide an argument list to :cfunc:`PyEval_CallObject`. In some cases +have to provide an argument list to :cfunc:`PyObject_CallObject`. In some cases the argument list is also provided by the Python program, through the same interface that specified the callback function. It can then be saved and used in the same manner as the function object. In other cases, you may have to @@ -535,7 +535,7 @@ PyObject *arglist; ... arglist = Py_BuildValue("(l)", eventcode); - result = PyEval_CallObject(my_callback, arglist); + result = PyObject_CallObject(my_callback, arglist); Py_DECREF(arglist); if (result == NULL) return NULL; /* Pass error back */ @@ -547,19 +547,20 @@ :cfunc:`Py_BuildValue` may run out of memory, and this should be checked. You may also call a function with keyword arguments by using -:cfunc:`PyEval_CallObjectWithKeywords`. As in the above example, we use -:cfunc:`Py_BuildValue` to construct the dictionary. :: +:cfunc:`PyObject_Call`, which supports arguments and keyword arguments. As in +the above example, we use :cfunc:`Py_BuildValue` to construct the dictionary. :: PyObject *dict; ... dict = Py_BuildValue("{s:i}", "name", val); - result = PyEval_CallObjectWithKeywords(my_callback, NULL, dict); + result = PyObject_Call(my_callback, NULL, dict); Py_DECREF(dict); if (result == NULL) return NULL; /* Pass error back */ /* Here maybe use the result */ Py_DECREF(result); + .. _parsetuple: Extracting Parameters in Extension Functions Modified: python/branches/py3k-short-float-repr/Doc/howto/cporting.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/howto/cporting.rst (original) +++ python/branches/py3k-short-float-repr/Doc/howto/cporting.rst Mon Apr 6 00:11:42 2009 @@ -98,7 +98,7 @@ Python level, but actually corresponds to 2.x's :func:`long` type. In the C-API, ``PyInt_*`` functions are replaced by their ``PyLong_*`` neighbors. The best course of action here is using the ``PyInt_*`` functions aliased to -``PyLong_*`` found in :file:`intobject.h`. The the abstract ``PyNumber_*`` APIs +``PyLong_*`` found in :file:`intobject.h`. The abstract ``PyNumber_*`` APIs can also be used in some cases. :: #include "Python.h" Modified: python/branches/py3k-short-float-repr/Doc/library/abc.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/abc.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/abc.rst Mon Apr 6 00:11:42 2009 @@ -132,7 +132,7 @@ A class that has a metaclass derived from :class:`ABCMeta` cannot be instantiated unless all of its abstract methods and properties are overridden. - The abstract methods can be called using any of the the normal 'super' call + The abstract methods can be called using any of the normal 'super' call mechanisms. Dynamically adding abstract methods to a class, or attempting to modify the @@ -184,6 +184,7 @@ def setx(self, value): ... x = abstractproperty(getx, setx) + .. rubric:: Footnotes .. [#] C++ programmers should note that Python's virtual base class Modified: python/branches/py3k-short-float-repr/Doc/library/doctest.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/doctest.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/doctest.rst Mon Apr 6 00:11:42 2009 @@ -905,7 +905,7 @@ from text files and modules with doctests: -.. function:: DocFileSuite([module_relative][, package][, setUp][, tearDown][, globs][, optionflags][, parser][, encoding]) +.. function:: DocFileSuite(*paths, [module_relative][, package][, setUp][, tearDown][, globs][, optionflags][, parser][, encoding]) Convert doctest tests from one or more text files to a :class:`unittest.TestSuite`. @@ -923,45 +923,47 @@ Optional argument *module_relative* specifies how the filenames in *paths* should be interpreted: - * If *module_relative* is ``True`` (the default), then each filename specifies - an OS-independent module-relative path. By default, this path is relative to - the calling module's directory; but if the *package* argument is specified, then - it is relative to that package. To ensure OS-independence, each filename should - use ``/`` characters to separate path segments, and may not be an absolute path - (i.e., it may not begin with ``/``). - - * If *module_relative* is ``False``, then each filename specifies an OS-specific - path. The path may be absolute or relative; relative paths are resolved with - respect to the current working directory. - - Optional argument *package* is a Python package or the name of a Python package - whose directory should be used as the base directory for module-relative - filenames. If no package is specified, then the calling module's directory is - used as the base directory for module-relative filenames. It is an error to - specify *package* if *module_relative* is ``False``. - - Optional argument *setUp* specifies a set-up function for the test suite. This - is called before running the tests in each file. The *setUp* function will be - passed a :class:`DocTest` object. The setUp function can access the test - globals as the *globs* attribute of the test passed. + * If *module_relative* is ``True`` (the default), then each filename in + *paths* specifies an OS-independent module-relative path. By default, this + path is relative to the calling module's directory; but if the *package* + argument is specified, then it is relative to that package. To ensure + OS-independence, each filename should use ``/`` characters to separate path + segments, and may not be an absolute path (i.e., it may not begin with + ``/``). + + * If *module_relative* is ``False``, then each filename in *paths* specifies + an OS-specific path. The path may be absolute or relative; relative paths + are resolved with respect to the current working directory. + + Optional argument *package* is a Python package or the name of a Python + package whose directory should be used as the base directory for + module-relative filenames in *paths*. If no package is specified, then the + calling module's directory is used as the base directory for module-relative + filenames. It is an error to specify *package* if *module_relative* is + ``False``. - Optional argument *tearDown* specifies a tear-down function for the test suite. - This is called after running the tests in each file. The *tearDown* function + Optional argument *setUp* specifies a set-up function for the test suite. + This is called before running the tests in each file. The *setUp* function will be passed a :class:`DocTest` object. The setUp function can access the test globals as the *globs* attribute of the test passed. + Optional argument *tearDown* specifies a tear-down function for the test + suite. This is called after running the tests in each file. The *tearDown* + function will be passed a :class:`DocTest` object. The setUp function can + access the test globals as the *globs* attribute of the test passed. + Optional argument *globs* is a dictionary containing the initial global variables for the tests. A new copy of this dictionary is created for each test. By default, *globs* is a new empty dictionary. Optional argument *optionflags* specifies the default doctest options for the tests, created by or-ing together individual option flags. See section - :ref:`doctest-options`. See function :func:`set_unittest_reportflags` below for - a better way to set reporting options. + :ref:`doctest-options`. See function :func:`set_unittest_reportflags` below + for a better way to set reporting options. - Optional argument *parser* specifies a :class:`DocTestParser` (or subclass) that - should be used to extract tests from the files. It defaults to a normal parser - (i.e., ``DocTestParser()``). + Optional argument *parser* specifies a :class:`DocTestParser` (or subclass) + that should be used to extract tests from the files. It defaults to a normal + parser (i.e., ``DocTestParser()``). Optional argument *encoding* specifies an encoding that should be used to convert the file to unicode. Modified: python/branches/py3k-short-float-repr/Doc/library/functions.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/functions.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/functions.rst Mon Apr 6 00:11:42 2009 @@ -1163,9 +1163,11 @@ Without arguments, return a dictionary corresponding to the current local symbol table. With a module, class or class instance object as argument (or anything else that has a :attr:`__dict__` attribute), returns a dictionary corresponding - to the object's symbol table. The returned dictionary should not be modified: - the effects on the corresponding symbol table are undefined. [#]_ + to the object's symbol table. + .. warning:: + The returned dictionary should not be modified: + the effects on the corresponding symbol table are undefined. [#]_ .. function:: zip(*iterables) Modified: python/branches/py3k-short-float-repr/Doc/library/itertools.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/itertools.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/itertools.rst Mon Apr 6 00:11:42 2009 @@ -207,7 +207,7 @@ 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 have been exhausted. + Stops when either the *data* or *selectors* iterables has been exhausted. Equivalent to:: def compress(data, selectors): Modified: python/branches/py3k-short-float-repr/Doc/library/logging.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/logging.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/logging.rst Mon Apr 6 00:11:42 2009 @@ -2290,6 +2290,10 @@ locks; there is one lock to serialize access to the module's shared data, and each handler also creates a lock to serialize access to its underlying I/O. +If you are implementing asynchronous signal handlers using the :mod:`signal` +module, you may not be able to use logging from within such handlers. This is +because lock implementations in the :mod:`threading` module are not always +re-entrant, and so cannot be invoked from such signal handlers. Configuration ------------- Modified: python/branches/py3k-short-float-repr/Doc/library/multiprocessing.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/multiprocessing.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/multiprocessing.rst Mon Apr 6 00:11:42 2009 @@ -708,7 +708,8 @@ Send an object to the other end of the connection which should be read using :meth:`recv`. - The object must be picklable. + The object must be picklable. Very large pickles (approximately 32 MB+, + though it depends on the OS) may raise a ValueError exception. .. method:: recv() @@ -740,7 +741,9 @@ complete message. If *offset* is given then data is read from that position in *buffer*. If - *size* is given then that many bytes will be read from buffer. + *size* is given then that many bytes will be read from buffer. Very large + buffers (approximately 32 MB+, though it depends on the OS) may raise a + ValueError exception .. method:: recv_bytes([maxlength]) @@ -834,6 +837,12 @@ .. class:: Event() A clone of :class:`threading.Event`. + This method returns the state of the internal semaphore on exit, so it + will always return ``True`` except if a timeout is given and the operation + times out. + + .. versionchanged:: 2.7 + Previously, the method always returned ``None``. .. class:: Lock() @@ -1537,8 +1546,8 @@ .. method:: map(func, iterable[, chunksize]) - A parallel equivalent of the :func:`map` builtin function, collecting the - result in a list. It blocks till the whole result is ready. + A parallel equivalent of the :func:`map` builtin function (it supports only + one *iterable* argument though). It blocks till the result is ready. This method chops the iterable into a number of chunks which it submits to the process pool as separate tasks. The (approximate) size of these @@ -1697,6 +1706,12 @@ *address* is the address to be used by the bound socket or named pipe of the listener object. + .. note:: + + If an address of '0.0.0.0' is used, the address will not be a connectable + end point on Windows. If you require a connectable end-point, + you should use '127.0.0.1'. + *family* is the type of socket (or named pipe) to use. This can be one of the strings ``'AF_INET'`` (for a TCP socket), ``'AF_UNIX'`` (for a Unix domain socket) or ``'AF_PIPE'`` (for a Windows named pipe). Of these only @@ -1839,7 +1854,7 @@ any :class:`~multiprocessing.Process` object that the current process creates. This means that (by default) all processes of a multi-process program will share a single authentication key which can be used when setting up connections -between the themselves. +between themselves. Suitable authentication keys can also be generated by using :func:`os.urandom`. Modified: python/branches/py3k-short-float-repr/Doc/library/os.path.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/os.path.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/os.path.rst Mon Apr 6 00:11:42 2009 @@ -1,11 +1,9 @@ - :mod:`os.path` --- Common pathname manipulations ================================================ .. module:: os.path :synopsis: Operations on pathnames. - .. index:: single: path; operations This module implements some useful functions on pathnames. To read or @@ -31,6 +29,22 @@ :func:`splitunc` and :func:`ismount` do handle them correctly. +.. note:: + + Since different operating systems have different path name conventions, there + are several versions of this module in the standard library. The + :mod:`os.path` module is always the path module suitable for the operating + system Python is running on, and therefore usable for local paths. However, + you can also import and use the individual modules if you want to manipulate + a path that is *always* in one of the different formats. They all have the + same interface: + + * :mod:`posixpath` for UNIX-style paths + * :mod:`ntpath` for Windows paths + * :mod:`macpath` for old-style MacOS paths + * :mod:`os2emxpath` for OS/2 EMX paths + + .. function:: abspath(path) Return a normalized absolutized version of the pathname *path*. On most @@ -189,9 +203,9 @@ .. function:: normcase(path) - Normalize the case of a pathname. On Unix and MacOSX, this returns the path unchanged; on - case-insensitive filesystems, it converts the path to lowercase. On Windows, it - also converts forward slashes to backward slashes. + Normalize the case of a pathname. On Unix and Mac OS X, this returns the + path unchanged; on case-insensitive filesystems, it converts the path to + lowercase. On Windows, it also converts forward slashes to backward slashes. .. function:: normpath(path) Modified: python/branches/py3k-short-float-repr/Doc/library/os.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/os.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/os.rst Mon Apr 6 00:11:42 2009 @@ -51,15 +51,6 @@ ``'ce'``, ``'java'``. -.. data:: path - - The corresponding operating system dependent standard module for pathname - operations, such as :mod:`posixpath` or :mod:`ntpath`. Thus, given the proper - imports, ``os.path.split(file)`` is equivalent to but more portable than - ``posixpath.split(file)``. Note that this is also an importable module: it may - be imported directly as :mod:`os.path`. - - .. _os-procinfo: Process Parameters @@ -1491,7 +1482,9 @@ which is used to define the environment variables for the new process (they are used instead of the current process' environment); the functions :func:`spawnl`, :func:`spawnlp`, :func:`spawnv`, and :func:`spawnvp` all cause - the new process to inherit the environment of the current process. + the new process to inherit the environment of the current process. Note that + keys and values in the *env* dictionary must be strings; invalid keys or + values will cause the function to fail, with a return value of ``127``. As an example, the following calls to :func:`spawnlp` and :func:`spawnvpe` are equivalent:: Modified: python/branches/py3k-short-float-repr/Doc/library/pdb.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/pdb.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/pdb.rst Mon Apr 6 00:11:42 2009 @@ -262,7 +262,7 @@ full speed, only stopping at the next line in the current function.) unt(il) - Continue execution until the line with the the line number greater than the + Continue execution until the line with the line number greater than the current one is reached or when returning from current frame. r(eturn) Modified: python/branches/py3k-short-float-repr/Doc/library/pickle.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/pickle.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/pickle.rst Mon Apr 6 00:11:42 2009 @@ -436,6 +436,14 @@ Refer to the section :ref:`pickle-state` for more information about how to use the methods :meth:`__getstate__` and :meth:`__setstate__`. +.. note:: + At unpickling time, some methods like :meth:`__getattr__`, + :meth:`__getattribute__`, or :meth:`__setattr__` may be called upon the + instance. In case those methods rely on some internal invariant being + true, the type should implement either :meth:`__getinitargs__` or + :meth:`__getnewargs__` to establish such an invariant; otherwise, neither + :meth:`__new__` nor :meth:`__init__` will be called. + .. index:: pair: copy; protocol single: __reduce__() (copy protocol) Modified: python/branches/py3k-short-float-repr/Doc/library/re.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/re.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/re.rst Mon Apr 6 00:11:42 2009 @@ -8,10 +8,9 @@ .. sectionauthor:: Andrew M. Kuchling - - This module provides regular expression matching operations similar to -those found in Perl. The :mod:`re` module is always available. +those found in Perl. Both patterns and strings to be searched can be +Unicode strings as well as 8-bit strings. Both patterns and strings to be searched can be Unicode strings as well as 8-bit strings. However, Unicode strings and 8-bit strings cannot be mixed: @@ -47,9 +46,6 @@ second edition of the book no longer covers Python at all, but the first edition covered writing good regular expression patterns in great detail. - `Kodos `_ - is a graphical regular expression debugger written in Python. - .. _re-syntax: @@ -241,16 +237,18 @@ ``(?P...)`` Similar to regular parentheses, but the substring matched by the group is - accessible via the symbolic group name *name*. Group names must be valid Python - identifiers, and each group name must be defined only once within a regular - expression. A symbolic group is also a numbered group, just as if the group - were not named. So the group named 'id' in the example below can also be - referenced as the numbered group 1. + accessible within the rest of the regular expression via the symbolic group + name *name*. Group names must be valid Python identifiers, and each group + name must be defined only once within a regular expression. A symbolic group + is also a numbered group, just as if the group were not named. So the group + named ``id`` in the example below can also be referenced as the numbered group + ``1``. For example, if the pattern is ``(?P[a-zA-Z_]\w*)``, the group can be referenced by its name in arguments to methods of match objects, such as - ``m.group('id')`` or ``m.end('id')``, and also by name in pattern text (for - example, ``(?P=id)``) and replacement text (such as ``\g``). + ``m.group('id')`` or ``m.end('id')``, and also by name in the regular + expression itself (using ``(?P=id)``) and replacement text given to + ``.sub()`` (using ``\g``). ``(?P=name)`` Matches whatever text was matched by the earlier group named *name*. Modified: python/branches/py3k-short-float-repr/Doc/library/shelve.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/shelve.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/shelve.rst Mon Apr 6 00:11:42 2009 @@ -141,7 +141,7 @@ # as d was opened WITHOUT writeback=True, beware: d['xx'] = range(4) # this works as expected, but... - d['xx'].append(5) # *this doesn't!* -- d['xx'] is STILL range(4)!!! + d['xx'].append(5) # *this doesn't!* -- d['xx'] is STILL range(4)! # having opened d without writeback=True, you need to code carefully: temp = d['xx'] # extracts the copy Modified: python/branches/py3k-short-float-repr/Doc/library/socketserver.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/socketserver.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/socketserver.rst Mon Apr 6 00:11:42 2009 @@ -122,15 +122,21 @@ Server Objects -------------- +.. class:: BaseServer -.. function:: fileno() + This is the superclass of all Server objects in the module. It defines the + interface, given below, but does not implement most of the methods, which is + done in subclasses. + + +.. method:: BaseServer.fileno() Return an integer file descriptor for the socket on which the server is listening. This function is most commonly passed to :func:`select.select`, to allow monitoring multiple servers in the same process. -.. function:: handle_request() +.. method:: BaseServer.handle_request() Process a single request. This function calls the following methods in order: :meth:`get_request`, :meth:`verify_request`, and @@ -141,30 +147,30 @@ will return. -.. function:: serve_forever(poll_interval=0.5) +.. method:: BaseServer.serve_forever(poll_interval=0.5) Handle requests until an explicit :meth:`shutdown` request. Polls for shutdown every *poll_interval* seconds. -.. function:: shutdown() +.. method:: BaseServer.shutdown() Tells the :meth:`serve_forever` loop to stop and waits until it does. -.. data:: address_family +.. attribute:: BaseServer.address_family The family of protocols to which the server's socket belongs. Common examples are :const:`socket.AF_INET` and :const:`socket.AF_UNIX`. -.. data:: RequestHandlerClass +.. attribute:: BaseServer.RequestHandlerClass The user-provided request handler class; an instance of this class is created for each request. -.. data:: server_address +.. attribute:: BaseServer.server_address The address on which the server is listening. The format of addresses varies depending on the protocol family; see the documentation for the socket module @@ -172,22 +178,22 @@ the address, and an integer port number: ``('127.0.0.1', 80)``, for example. -.. data:: socket +.. attribute:: BaseServer.socket The socket object on which the server will listen for incoming requests. + The server classes support the following class variables: .. XXX should class variables be covered before instance variables, or vice versa? - -.. data:: allow_reuse_address +.. attribute:: BaseServer.allow_reuse_address Whether the server will allow the reuse of an address. This defaults to :const:`False`, and can be set in subclasses to change the policy. -.. data:: request_queue_size +.. attribute:: BaseServer.request_queue_size The size of the request queue. If it takes a long time to process a single request, any requests that arrive while the server is busy are placed into a @@ -196,17 +202,19 @@ value is usually 5, but this can be overridden by subclasses. -.. data:: socket_type +.. attribute:: BaseServer.socket_type The type of socket used by the server; :const:`socket.SOCK_STREAM` and :const:`socket.SOCK_DGRAM` are two common values. -.. data:: timeout + +.. attribute:: BaseServer.timeout Timeout duration, measured in seconds, or :const:`None` if no timeout is desired. If :meth:`handle_request` receives no incoming requests within the timeout period, the :meth:`handle_timeout` method is called. + There are various server methods that can be overridden by subclasses of base server classes like :class:`TCPServer`; these methods aren't useful to external users of the server object. @@ -214,27 +222,27 @@ .. XXX should the default implementations of these be documented, or should it be assumed that the user will look at socketserver.py? - -.. function:: finish_request() +.. method:: BaseServer.finish_request() Actually processes the request by instantiating :attr:`RequestHandlerClass` and calling its :meth:`handle` method. -.. function:: get_request() +.. method:: BaseServer.get_request() Must accept a request from the socket, and return a 2-tuple containing the *new* socket object to be used to communicate with the client, and the client's address. -.. function:: handle_error(request, client_address) +.. method:: BaseServer.handle_error(request, client_address) This function is called if the :attr:`RequestHandlerClass`'s :meth:`handle` method raises an exception. The default action is to print the traceback to standard output and continue handling further requests. -.. function:: handle_timeout() + +.. method:: BaseServer.handle_timeout() This function is called when the :attr:`timeout` attribute has been set to a value other than :const:`None` and the timeout period has passed with no @@ -242,31 +250,32 @@ to collect the status of any child processes that have exited, while in threading servers this method does nothing. -.. function:: process_request(request, client_address) + +.. method:: BaseServer.process_request(request, client_address) Calls :meth:`finish_request` to create an instance of the :attr:`RequestHandlerClass`. If desired, this function can create a new process or thread to handle the request; the :class:`ForkingMixIn` and :class:`ThreadingMixIn` classes do this. + .. Is there any point in documenting the following two functions? What would the purpose of overriding them be: initializing server instance variables, adding new network families? - -.. function:: server_activate() +.. method:: BaseServer.server_activate() Called by the server's constructor to activate the server. The default behavior just :meth:`listen`\ s to the server's socket. May be overridden. -.. function:: server_bind() +.. method:: BaseServer.server_bind() Called by the server's constructor to bind the socket to the desired address. May be overridden. -.. function:: verify_request(request, client_address) +.. method:: BaseServer.verify_request(request, client_address) Must return a Boolean value; if the value is :const:`True`, the request will be processed, and if it's :const:`False`, the request will be denied. This function @@ -282,14 +291,14 @@ request. -.. function:: finish() +.. method:: RequestHandler.finish() Called after the :meth:`handle` method to perform any clean-up actions required. The default implementation does nothing. If :meth:`setup` or :meth:`handle` raise an exception, this function will not be called. -.. function:: handle() +.. method:: RequestHandler.handle() This function must do all the work required to service a request. The default implementation does nothing. Several instance attributes are @@ -308,7 +317,7 @@ data or return data to the client. -.. function:: setup() +.. method:: RequestHandler.setup() Called before the :meth:`handle` method to perform any initialization actions required. The default implementation does nothing. Modified: python/branches/py3k-short-float-repr/Doc/library/ssl.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/ssl.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/ssl.rst Mon Apr 6 00:11:42 2009 @@ -293,7 +293,7 @@ If there is no certificate for the peer on the other end of the connection, returns ``None``. - If the the parameter ``binary_form`` is :const:`False`, and a + If the parameter ``binary_form`` is :const:`False`, and a certificate was received from the peer, this method returns a :class:`dict` instance. If the certificate was not validated, the dict is empty. If the certificate was validated, it returns a dict Modified: python/branches/py3k-short-float-repr/Doc/library/stdtypes.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/stdtypes.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/stdtypes.rst Mon Apr 6 00:11:42 2009 @@ -1834,6 +1834,11 @@ Equivalent to ``not key in d``. + .. describe:: iter(d) + + Return an iterator over the keys of the dictionary. This is a shortcut + for :meth:`iterkeys`. + .. method:: clear() Remove all items from the dictionary. @@ -1931,6 +1936,9 @@ using :func:`zip`: ``pairs = zip(d.values(), d.keys())``. Another way to create the same list is ``pairs = [(v, k) for (k, v) in d.items()]``. + Iterating views while adding or deleting entries in the dictionary will raise + a :exc:`RuntimeError`. + .. describe:: x in dictview Return ``True`` if *x* is in the underlying dictionary's keys, values or @@ -2666,10 +2674,26 @@ The name of the class or type. +The following attributes are only supported by :term:`new-style class`\ es. + +.. attribute:: class.__mro__ + + This attribute is a tuple of classes that are considered when looking for + base classes during method resolution. + + +.. method:: class.mro() + + This method can be overridden by a metaclass to customize the method + resolution order for its instances. It is called at class instantiation, and + its result is stored in :attr:`__mro__`. + + .. method:: class.__subclasses__ - All classes keep a list of weak references to their immediate subclasses. - This method returns a list of all those references still alive. Example:: + Each new-style class keeps a list of weak references to its immediate + subclasses. This method returns a list of all those references still alive. + Example:: >>> int.__subclasses__() [] Modified: python/branches/py3k-short-float-repr/Doc/library/sys.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/sys.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/sys.rst Mon Apr 6 00:11:42 2009 @@ -780,16 +780,20 @@ __stderr__ These objects contain the original values of ``stdin``, ``stderr`` and - ``stdout`` at the start of the program. They are used during finalization, and - could be useful to restore the actual files to known working file objects in - case they have been overwritten with a broken object. - - .. note:: - - Under some conditions ``stdin``, ``stdout`` and ``stderr`` as well as the - original values ``__stdin__``, ``__stdout__`` and ``__stderr__`` can be - None. It is usually the case for Windows GUI apps that aren't connected to - a console and Python apps started with :program:`pythonw`. + ``stdout`` at the start of the program. They are used during finalization, + and could be useful to print to the actual standard stream no matter if the + ``sys.std*`` object has been redirected. + + It can also be used to restore the actual files to known working file objects + in case they have been overwritten with a broken object. However, the + preferred way to do this is to explicitly save the previous stream before + replacing it, and restore the saved object. + + .. note:: + Under some conditions ``stdin``, ``stdout`` and ``stderr`` as well as the + original values ``__stdin__``, ``__stdout__`` and ``__stderr__`` can be + None. It is usually the case for Windows GUI apps that aren't connected + to a console and Python apps started with :program:`pythonw`. .. data:: tracebacklimit Modified: python/branches/py3k-short-float-repr/Doc/library/threading.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/threading.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/threading.rst Mon Apr 6 00:11:42 2009 @@ -676,14 +676,20 @@ .. method:: Event.wait([timeout]) - Block until the internal flag is true. If the internal flag is true on entry, - return immediately. Otherwise, block until another thread calls :meth:`set` to - set the flag to true, or until the optional timeout occurs. + Block until the internal flag is true. If the internal flag is true on entry, + return immediately. Otherwise, block until another thread calls :meth:`set` + to set the flag to true, or until the optional timeout occurs. When the timeout argument is present and not ``None``, it should be a floating point number specifying a timeout for the operation in seconds (or fractions thereof). + This method returns the internal flag on exit, so it will always return + ``True`` except if a timeout is given and the operation times out. + + .. versionchanged:: 2.7 + Previously, the method always returned ``None``. + .. _timer-objects: Modified: python/branches/py3k-short-float-repr/Doc/library/tkinter.ttk.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/tkinter.ttk.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/tkinter.ttk.rst Mon Apr 6 00:11:42 2009 @@ -249,7 +249,7 @@ ttk.Widget ^^^^^^^^^^ -Besides the methods described below, the class :class:`ttk.Widget` supports the +Besides the methods described below, the :class:`ttk.Widget` supports the methods :meth:`tkinter.Widget.cget` and :meth:`tkinter.Widget.configure`. .. class:: Widget @@ -484,7 +484,7 @@ The tab will not be displayed, but the associated window remains managed by the notebook and its configuration remembered. Hidden tabs - may be restored with the add command. + may be restored with the :meth:`add` command. .. method:: identify(x, y) @@ -503,7 +503,7 @@ Inserts a pane at the specified position. - *pos* is either the string end, an integer index, or the name of a + *pos* is either the string "end", an integer index, or the name of a managed child. If *child* is already managed by the notebook, moves it to the specified position. @@ -523,7 +523,7 @@ Query or modify the options of the specific *tab_id*. - If *kw* is not given, returns a dict of the tab option values. If + If *kw* is not given, returns a dictionary of the tab option values. If *option* is specified, returns the value of that *option*. Otherwise, sets the options to the corresponding values. @@ -540,14 +540,14 @@ This will extend the bindings for the toplevel window containing the notebook as follows: - * Control-Tab: selects the tab following the currently selected one - * Shift-Control-Tab: selects the tab preceding the currently selected one + * Control-Tab: selects the tab following the currently selected one. + * Shift-Control-Tab: selects the tab preceding the currently selected one. * Alt-K: where K is the mnemonic (underlined) character of any tab, will select that tab. Multiple notebooks in a single toplevel may be enabled for traversal, including nested notebooks. However, notebook traversal only works - properly if all panes have as master the notebook they are in. + properly if all panes have the notebook they are in as master. Progressbar @@ -580,12 +580,12 @@ +----------+---------------------------------------------------------------+ | value | The current value of the progress bar. In "determinate" mode, | | | this represents the amount of work completed. In | - | | "indeterminate" mode, it is interpreted as modulo maximum; | + | | "indeterminate" mode, it is interpreted as modulo *maximum*; | | | that is, the progress bar completes one "cycle" when its value| - | | increases by maximum. | + | | increases by *maximum*. | +----------+---------------------------------------------------------------+ | variable | A name which is linked to the option value. If specified, the | - | | value of the progressbar is automatically set to the value of | + | | value of the progress bar is automatically set to the value of| | | this name whenever the latter is modified. | +----------+---------------------------------------------------------------+ | phase | Read-only option. The widget periodically increments the value| @@ -602,14 +602,14 @@ .. method:: start([interval]) - Begin autoincrement mode: schedules a recurring timer even that calls + Begin autoincrement mode: schedules a recurring timer event that calls :meth:`Progressbar.step` every *interval* milliseconds. If omitted, *interval* defaults to 50 milliseconds. .. method:: step([amount]) - Increments progressbar's value by *amount*. + Increments the progress bar's value by *amount*. *amount* defaults to 1.0 if omitted. @@ -617,7 +617,7 @@ .. method:: stop() Stop autoincrement mode: cancels any recurring timer event initiated by - :meth:`Progressbar.start` for this progressbar. + :meth:`Progressbar.start` for this progress bar. Separator @@ -626,7 +626,7 @@ The :class:`ttk.Separator` widget displays a horizontal or vertical separator bar. -It has no other method besides the ones inherited from :class:`ttk.Widget`. +It has no other methods besides the ones inherited from :class:`ttk.Widget`. Options @@ -645,18 +645,18 @@ Sizegrip -------- -The :class:`ttk.Sizegrip` widget (also known as grow box) allows the user to +The :class:`ttk.Sizegrip` widget (also known as a grow box) allows the user to resize the containing toplevel window by pressing and dragging the grip. -This widget has no specific options neither specific methods, besides the +This widget has neither specific options nor specific methods, besides the ones inherited from :class:`ttk.Widget`. Platform-specific notes ^^^^^^^^^^^^^^^^^^^^^^^ -* On Mac OSX, toplevel windows automatically include a built-in size grip - by default. Adding a Sizegrip there is harmless, since the built-in +* On MacOS X, toplevel windows automatically include a built-in size grip + by default. Adding a :class:`Sizegrip` is harmless, since the built-in grip will just mask the widget. @@ -664,8 +664,8 @@ ^^^^ * If the containing toplevel's position was specified relative to the right - or bottom of the screen (e.g. ....), the Sizegrip widget will not resize - the window. + or bottom of the screen (e.g. ....), the :class:`Sizegrip` widget will + not resize the window. * This widget supports only "southeast" resizing. @@ -678,16 +678,16 @@ label. The order in which data values are displayed may be controlled by setting -the widget option displaycolumns. The tree widget can also display column +the widget option ``displaycolumns``. The tree widget can also display column headings. Columns may be accessed by number or symbolic names listed in the widget option columns. See `Column Identifiers`_. Each item is identified by an unique name. The widget will generate item IDs if they are not supplied by the caller. There is a distinguished root item, -named {}. The root item itself is not displayed; its children appear at the +named ``{}``. The root item itself is not displayed; its children appear at the top level of the hierarchy. -Each item also has a list of tags, which can be used to associate even bindings +Each item also has a list of tags, which can be used to associate event bindings with individual items and control the appearance of the item. The Treeview widget supports horizontal and vertical scrolling, according to @@ -698,7 +698,7 @@ Options ^^^^^^^ -This widget accepts the following specific option: +This widget accepts the following specific options: +----------------+--------------------------------------------------------+ | option | description | @@ -726,8 +726,8 @@ | | be changed. | | | | | | Note that the application code and tag bindings can set| - | | the selection however they wish, regardless the value | - | | of this option. | + | | the selection however they wish, regardless of the | + | | value of this option. | +----------------+--------------------------------------------------------+ | show | A list containing zero or more of the following values,| | | specifying which elements of the tree to display. | @@ -738,7 +738,7 @@ | | The default is "tree headings", i.e., show all | | | elements. | | | | - | | **Note**: Column #0 always refer to the tree column, | + | | **Note**: Column #0 always refers to the tree column, | | | even if show="tree" is not specified. | +----------------+--------------------------------------------------------+ @@ -858,11 +858,11 @@ .. method:: set_children(item, *newchildren) - Replaces item's child with *newchildren*. + Replaces *item*'s child with *newchildren*. - Children present in item that are not present in *newchildren* are - detached from tree. No items in *newchildren* may be an ancestor of - item. Note that not specifying *newchildren* results in detaching + Children present in *item* that are not present in *newchildren* are + detached from the tree. No items in *newchildren* may be an ancestor of + *item*. Note that not specifying *newchildren* results in detaching *item*'s children. @@ -877,16 +877,16 @@ The valid options/values are: * id - Returns the column name, this is a read-only option. + Returns the column name. This is a read-only option. * anchor: One of the standard Tk anchor values. Specifies how the text in this column should be aligned with respect to the cell. * minwidth: width The minimum width of the column in pixels. The treeview widget will - not make the column any smaller than the specified by this option when + not make the column any smaller than specified by this option when the widget is resized or the user drags a column. * stretch: True/False - Specifies wheter or not the column's width should be adjusted when + Specifies whether the column's width should be adjusted when the widget is resized. * width: width The width of the column in pixels. @@ -912,8 +912,7 @@ .. method:: exists(item) - Returns True if the specified *item* is present in the three, - False otherwise. + Returns True if the specified *item* is present in the tree. .. method:: focus([item=None]) @@ -942,7 +941,7 @@ * command: callback A callback to be invoked when the heading label is pressed. - To configure the tree column heading, call this with column = "#0" + To configure the tree column heading, call this with column = "#0". .. method:: identify(component, x, y) @@ -985,7 +984,7 @@ .. method:: identify_element(x, y) - Returns the element at position x, y. + Returns the element at position *x*, *y*. Availability: Tk 8.6. @@ -997,16 +996,16 @@ .. method:: insert(parent, index[, iid=None[, **kw]]) - Creates a new item and return the item identifier of the newly created + Creates a new item and returns the item identifier of the newly created item. *parent* is the item ID of the parent item, or the empty string to create a new top-level item. *index* is an integer, or the value "end", specifying where in the list of parent's children to insert the new item. If *index* is less than or equal to zero, the new node is inserted at - the beginning, if *index* is greater than or equal to the current number + the beginning; if *index* is greater than or equal to the current number of children, it is inserted at the end. If *iid* is specified, it is used - as the item identifier, *iid* must not already exist in the tree. + as the item identifier; *iid* must not already exist in the tree. Otherwise, a new unique identifier is generated. See `Item Options`_ for the list of available points. @@ -1026,9 +1025,9 @@ Moves *item* to position *index* in *parent*'s list of children. - It is illegal to move an item under one of its descendants. If index is - less than or equal to zero, item is moved to the beginning, if greater - than or equal to the number of children, it is moved to the end. If item + It is illegal to move an item under one of its descendants. If *index* is + less than or equal to zero, *item* is moved to the beginning; if greater + than or equal to the number of children, it is moved to the end. If *item* was detached it is reattached. @@ -1101,7 +1100,7 @@ .. method:: tag_bind(tagname[, sequence=None[, callback=None]]) Bind a callback for the given event *sequence* to the tag *tagname*. - When an event is delivered to an item, the *callbacks* for each of the + When an event is delivered to an item, the callbacks for each of the item's tags option are called. @@ -1119,7 +1118,7 @@ If *item* is specified, returns 1 or 0 depending on whether the specified *item* has the given *tagname*. Otherwise, returns a list of all items - which have the specified tag. + that have the specified tag. Availability: Tk 8.6 @@ -1159,7 +1158,7 @@ .. method:: configure(style, query_opt=None, **kw) - Query or sets the default value of the specified option(s) in *style*. + Query or set the default value of the specified option(s) in *style*. Each key in *kw* is an option and each value is a string identifying the value for that option. @@ -1185,10 +1184,10 @@ Query or sets dynamic values of the specified option(s) in *style*. - Each key in kw is an option and each value should be a list or a - tuple (usually) containing statespecs grouped in tuples, or list, or - something else of your preference. A statespec is compound of one or more - states and then a value. + Each key in *kw* is an option and each value should be a list or a + tuple (usually) containing statespecs grouped in tuples, lists, or + something else of your preference. A statespec is a compound of one + or more states and then a value. An example may make it more understandable:: @@ -1208,12 +1207,10 @@ root.mainloop() - There is a thing to note in this previous short example: - - * The order of the (states, value) sequences for an option does matter, - if you changed the order to [('active', 'blue'), ('pressed', 'red')] - in the foreground option, for example, you would get a blue foreground - when the widget were in active or pressed states. + Note that the order of the (states, value) sequences for an option does + matter, if you changed the order to ``[('active', 'blue'), ('pressed', + 'red')]`` in the foreground option, for example, you would get a blue + foreground when the widget were in active or pressed states. .. method:: lookup(style, option[, state=None[, default=None]]) @@ -1236,13 +1233,13 @@ Define the widget layout for given *style*. If *layoutspec* is omitted, return the layout specification for given style. - *layoutspec*, if specified, is expected to be a list, or some other - sequence type (excluding string), where each item should be a tuple and + *layoutspec*, if specified, is expected to be a list or some other + sequence type (excluding strings), where each item should be a tuple and the first item is the layout name and the second item should have the format described described in `Layouts`_. - To understand the format, check this example below (it is not intended - to do anything useful):: + To understand the format, see the following example (it is not + intended to do anything useful):: from tkinter import ttk import tkinter @@ -1268,12 +1265,12 @@ .. method:: element_create(elementname, etype, *args, **kw) - Create a new element in the current theme of given *etype* which is + Create a new element in the current theme, of the given *etype* which is expected to be either "image", "from" or "vsapi". The latter is only available in Tk 8.6a for Windows XP and Vista and is not described here. If "image" is used, *args* should contain the default image name followed - by statespec/value pairs (this is the imagespec), *kw* may have the + by statespec/value pairs (this is the imagespec), and *kw* may have the following options: * border=padding @@ -1296,11 +1293,12 @@ Specifies a minimum width for the element. If less than zero, the base image's width is used as a default. - But if "from" is used, then :meth:`element_create` will clone an existing - element. *args* is expected to contain a themename, which is from where + If "from" is used as the value of *etype*, + :meth:`element_create` will clone an existing + element. *args* is expected to contain a themename, from which the element will be cloned, and optionally an element to clone from. If this element to clone from is not specified, an empty element will - be used. *kw* is discarded here. + be used. *kw* is discarded. .. method:: element_names() @@ -1334,7 +1332,7 @@ :meth:`Style.configure`, :meth:`Style.map`, :meth:`Style.layout` and :meth:`Style.element_create` respectively. - As an example, lets change the Combobox for the default theme a bit:: + As an example, let's change the Combobox for the default theme a bit:: from tkinter import ttk import tkinter @@ -1367,7 +1365,7 @@ .. method:: theme_use([themename]) - If *themename* is not given, returns the theme in use, otherwise, set + If *themename* is not given, returns the theme in use. Otherwise, sets the current theme to *themename*, refreshes all widgets and emits a <> event. @@ -1375,13 +1373,14 @@ Layouts ^^^^^^^ -A layout can be just None, if takes no options, or a dict of options specifying -how to arrange the element. The layout mechanism uses a simplified -version of the pack geometry manager: given an initial cavity, each element is -allocated a parcel. Valid options/values are: +A layout can be just None, if it takes no options, or a dict of +options specifying how to arrange the element. The layout mechanism +uses a simplified version of the pack geometry manager: given an +initial cavity, each element is allocated a parcel. Valid +options/values are: * side: whichside - Specifies which side of the cavity to place the the element; one of + Specifies which side of the cavity to place the element; one of top, right, bottom or left. If omitted, the element occupies the entire cavity. Modified: python/branches/py3k-short-float-repr/Doc/library/urllib.request.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/urllib.request.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/urllib.request.rst Mon Apr 6 00:11:42 2009 @@ -40,7 +40,7 @@ commonly used to determine if a redirect was followed * :meth:`info` --- return the meta-information of the page, such as headers, - in the form of an ``http.client.HTTPMessage`` instance (see `Quick + in the form of an :class:`http.client.HTTPMessage` instance (see `Quick Reference to HTTP Headers `_) Raises :exc:`URLError` on errors. Modified: python/branches/py3k-short-float-repr/Doc/library/webbrowser.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/webbrowser.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/webbrowser.rst Mon Apr 6 00:11:42 2009 @@ -55,6 +55,10 @@ under many window managers this will occur regardless of the setting of this variable). + Note that on some platforms, trying to open a filename using this function, + may work and start the operating system's associated program. However, this + is neither supported nor portable. + .. function:: open_new(url) Modified: python/branches/py3k-short-float-repr/Doc/library/winreg.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/winreg.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/winreg.rst Mon Apr 6 00:11:42 2009 @@ -39,8 +39,8 @@ *key* is the predefined handle to connect to. - The return value is the handle of the opened key. If the function fails, an - :exc:`EnvironmentError` exception is raised. + The return value is the handle of the opened key. If the function fails, a + :exc:`WindowsError` exception is raised. .. function:: CreateKey(key, sub_key) @@ -57,8 +57,8 @@ If the key already exists, this function opens the existing key. - The return value is the handle of the opened key. If the function fails, an - :exc:`EnvironmentError` exception is raised. + The return value is the handle of the opened key. If the function fails, a + :exc:`WindowsError` exception is raised. .. function:: DeleteKey(key, sub_key) @@ -74,7 +74,7 @@ *This method can not delete keys with subkeys.* If the method succeeds, the entire key, including all of its values, is removed. - If the method fails, an :exc:`EnvironmentError` exception is raised. + If the method fails, a :exc:`WindowsError` exception is raised. .. function:: DeleteValue(key, value) @@ -97,7 +97,7 @@ *index* is an integer that identifies the index of the key to retrieve. The function retrieves the name of one subkey each time it is called. It is - typically called repeatedly until an :exc:`EnvironmentError` exception is + typically called repeatedly until a :exc:`WindowsError` exception is raised, indicating, no more values are available. @@ -111,7 +111,7 @@ *index* is an integer that identifies the index of the value to retrieve. The function retrieves the name of one subkey each time it is called. It is - typically called repeatedly, until an :exc:`EnvironmentError` exception is + typically called repeatedly, until a :exc:`WindowsError` exception is raised, indicating no more values. The result is a tuple of 3 items: @@ -199,7 +199,7 @@ The result is a new handle to the specified key. - If the function fails, :exc:`EnvironmentError` is raised. + If the function fails, :exc:`WindowsError` is raised. .. function:: OpenKeyEx() @@ -243,9 +243,10 @@ associated. If this parameter is ``None`` or empty, the function retrieves the value set by the :func:`SetValue` method for the key identified by *key*. - Values in the registry have name, type, and data components. This method + Values in the registry have name, type, and data components. This method retrieves the data for a key's first value that has a NULL name. But the - underlying API call doesn't return the type, Lame Lame Lame, DO NOT USE THIS!!! + underlying API call doesn't return the type, so always use + :func:`QueryValueEx` if possible. .. function:: QueryValueEx(key, value_name) Modified: python/branches/py3k-short-float-repr/Doc/reference/datamodel.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/reference/datamodel.rst (original) +++ python/branches/py3k-short-float-repr/Doc/reference/datamodel.rst Mon Apr 6 00:11:42 2009 @@ -59,12 +59,13 @@ they may be garbage-collected. An implementation is allowed to postpone garbage collection or omit it altogether --- it is a matter of implementation quality how garbage collection is implemented, as long as no objects are collected that -are still reachable. (Implementation note: the current implementation uses a +are still reachable. (Implementation note: CPython currently uses a reference-counting scheme with (optional) delayed detection of cyclically linked garbage, which collects most objects as soon as they become unreachable, but is not guaranteed to collect garbage containing circular references. See the documentation of the :mod:`gc` module for information on controlling the -collection of cyclic garbage.) +collection of cyclic garbage. Other implementations act differently and CPython +may change.) Note that the use of the implementation's tracing or debugging facilities may keep objects alive that would normally be collectable. Also note that catching Modified: python/branches/py3k-short-float-repr/Doc/tutorial/datastructures.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/tutorial/datastructures.rst (original) +++ python/branches/py3k-short-float-repr/Doc/tutorial/datastructures.rst Mon Apr 6 00:11:42 2009 @@ -347,13 +347,11 @@ >>> x, y, z = t -This is called, appropriately enough, *sequence unpacking*. Sequence unpacking -requires the list of variables on the left to have the same number of elements -as the length of the sequence. Note that multiple assignment is really just a -combination of tuple packing and sequence unpacking! - -There is a small bit of asymmetry here: packing multiple values always creates -a tuple, and unpacking works for any sequence. +This is called, appropriately enough, *sequence unpacking* and works for any +sequence on the right-hand side. Sequence unpacking requires the list of +variables on the left to have the same number of elements as the length of the +sequence. Note that multiple assignment is really just a combination of tuple +packing and sequence unpacking. .. XXX Add a bit on the difference between tuples and lists. Modified: python/branches/py3k-short-float-repr/Doc/tutorial/introduction.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/tutorial/introduction.rst (original) +++ python/branches/py3k-short-float-repr/Doc/tutorial/introduction.rst Mon Apr 6 00:11:42 2009 @@ -225,10 +225,9 @@ several lines of text just as you would do in C. Note that whitespace at the beginning of the line is significant. -If we make the string literal a "raw" string, however, the ``\n`` sequences are -not converted to newlines, but the backslash at the end of the line, and the -newline character in the source, are both included in the string as data. Thus, -the example:: +If we make the string literal a "raw" string, ``\n`` sequences are not converted +to newlines, but the backslash at the end of the line, and the newline character +in the source, are both included in the string as data. Thus, the example:: hello = r"This is a rather long string containing\n\ several lines of text much as you would do in C." @@ -240,22 +239,12 @@ This is a rather long string containing\n\ several lines of text much as you would do in C. -Or, strings can be surrounded in a pair of matching triple-quotes: ``"""`` or -``'''``. End of lines do not need to be escaped when using triple-quotes, but -they will be included in the string. :: - - print(""" - Usage: thingy [OPTIONS] - -h Display this usage message - -H hostname Hostname to connect to - """) - -produces the following output:: - - Usage: thingy [OPTIONS] - -h Display this usage message - -H hostname Hostname to connect to - +The interpreter prints the result of string operations in the same way as they +are typed for input: inside quotes, and with quotes and other funny characters +escaped by backslashes, to show the precise value. The string is enclosed in +double quotes if the string contains a single quote and no double quotes, else +it's enclosed in single quotes. (The :func:`print` function, described later, +can be used to write strings without quotes or escapes.) Strings can be concatenated (glued together) with the ``+`` operator, and repeated with ``*``:: Modified: python/branches/py3k-short-float-repr/Doc/whatsnew/2.6.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/whatsnew/2.6.rst (original) +++ python/branches/py3k-short-float-repr/Doc/whatsnew/2.6.rst Mon Apr 6 00:11:42 2009 @@ -86,8 +86,6 @@ .. ======================================================================== .. Large, PEP-level features and changes should be described here. -.. Should there be a new section here for 3k migration? -.. Or perhaps a more general section describing module changes/deprecation? .. ======================================================================== Python 3.0 @@ -1678,7 +1676,7 @@ :attr:`__self__`, and :attr:`im_func` is also available as :attr:`__func__`. The old names are still supported in Python 2.6, but are gone in 3.0. -* An obscure change: when you use the the :func:`locals` function inside a +* An obscure change: when you use the :func:`locals` function inside a :keyword:`class` statement, the resulting dictionary no longer returns free variables. (Free variables, in this case, are variables referenced in the :keyword:`class` statement that aren't attributes of the class.) Modified: python/branches/py3k-short-float-repr/Doc/whatsnew/2.7.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/whatsnew/2.7.rst (original) +++ python/branches/py3k-short-float-repr/Doc/whatsnew/2.7.rst Mon Apr 6 00:11:42 2009 @@ -6,7 +6,7 @@ :Release: |release| :Date: |today| -.. Fix accents on Kristjan Valur Jonsson, Fuerstenau. +.. Fix accents on Kristjan Valur Jonsson, Fuerstenau, Tarek Ziade. .. $Id$ Rules for maintenance: @@ -55,12 +55,32 @@ .. Compare with previous release in 2 - 3 sentences here. add hyperlink when the documentation becomes available online. +Python 3.1 +================ + +Much as Python 2.6 incorporated features from Python 3.0, +version 2.7 is influenced by features from 3.1. + +XXX mention importlib; anything else? + +One porting change: the :option:`-3` switch now automatically +enables the :option:`-Qwarn` switch that causes warnings +about using classic division with integers and long integers. + .. ======================================================================== .. Large, PEP-level features and changes should be described here. -.. Should there be a new section here for 3k migration? -.. Or perhaps a more general section describing module changes/deprecation? .. ======================================================================== +PEP 372: Adding an ordered dictionary to collections +==================================================== + +XXX write this + +Several modules will now use :class:`OrderedDict` by default. The +:mod:`ConfigParser` module uses :class:`OrderedDict` for the list +of sections and the options within a section. +The :meth:`namedtuple._asdict` method returns an :class:`OrderedDict` +as well. Other Language Changes @@ -85,6 +105,43 @@ (Contributed by Fredrik Johansson and Victor Stinner; :issue:`3439`.) +* The :class:`bytearray` type's :meth:`translate` method will + now accept None as its first argument. (Fixed by Georg Brandl; + :issue:`4759`.) + +.. ====================================================================== + + +Optimizations +------------- + +Several performance enhancements have been added: + +.. * A new :program:`configure` option, :option:`--with-computed-gotos`, + compiles the main bytecode interpreter loop using a new dispatch + mechanism that gives speedups of up to 20%, depending on the system + and benchmark. The new mechanism is only supported on certain + compilers, such as gcc, SunPro, and icc. + +* The garbage collector now performs better when many objects are + being allocated without deallocating any. A full garbage collection + pass is only performed when the middle generation has been collected + 10 times and when the number of survivor objects from the middle + generation exceeds 10% of the number of objects in the oldest + generation. The second condition was added to reduce the number + of full garbage collections as the number of objects on the heap grows, + avoiding quadratic performance when allocating very many objects. + (Suggested by Martin von Loewis and implemented by Antoine Pitrou; + :issue:`4074`.) + +* The garbage collector tries to avoid tracking simple containers + which can't be part of a cycle. In Python 2.7, this is now true for + tuples and dicts containing atomic types (such as ints, strings, + etc.). Transitively, a dict containing tuples of atomic types won't + be tracked either. This helps reduce the cost of each + garbage collection by decreasing the number of objects to be + considered and traversed by the collector. + (Contributed by Antoine Pitrou; :issue:`4688`.) * Integers are now stored internally either in base 2**15 or in base 2**30, the base being determined at build time. Previously, they @@ -93,7 +150,7 @@ benchmark results on 32-bit machines have been mixed. Therefore, the default is to use base 2**30 on 64-bit machines and base 2**15 on 32-bit machines; on Unix, there's a new configure option - --enable-big-digits that can be used to override this default. + :option:`--enable-big-digits` that can be used to override this default. Apart from the performance improvements this change should be invisible to end users, with one exception: for testing and @@ -106,41 +163,28 @@ >>> sys.long_info sys.long_info(bits_per_digit=30, sizeof_digit=4) - (Contributed by Mark Dickinson; :issue:`4258`.) - -.. ====================================================================== - - -Optimizations -------------- - -A few performance enhancements have been added: - -* The garbage collector now performs better when many objects are - being allocated without deallocating any. A full garbage collection - pass is only performed when the middle generation has been collected - 10 times and when the number of survivor objects from the middle - generation exceeds 10% of the number of objects in the oldest - generation. The second condition was added to reduce the number - of full garbage collections as the number of objects on the heap grows, - avoiding quadratic performance when allocating very many objects. - (Suggested by Martin von Loewis and implemented by Antoine Pitrou; - :issue:`4074`.) - -* The garbage collector tries to avoid tracking simple containers which - can't be part of a cycle. As of now, this is true for tuples and dicts - containing atomic types (such as ints, strings, etc.). Transitively, a dict - containing tuples of atomic types won't be tracked either. This helps bring - down the individual cost of each garbage collection, since it decreases the - number of objects to be considered and traversed by the collector. - - To help diagnosing this optimization, a new function in the :mod:`gc` - module, :func:`is_tracked`, returns True if a given instance is tracked - by the garbage collector, False otherwise. - (Contributed by Antoine Pitrou; :issue:`4688`.) - + Another set of changes made long objects a few bytes smaller: 2 bytes + smaller on 32-bit systems and 6 bytes on 64-bit. + (Contributed by Mark Dickinson; :issue:`5260`.) + +* The division algorithm for long integers has been made faster + by tightening the inner loop, doing shifts instead of multiplications, + and fixing an unnecessary extra iteration. + Various benchmarks show speedups of between 50% and 150% for long + integer divisions and modulo operations. + (Contributed by Mark Dickinson; :issue:`5512`.) + +* The implementation of ``%`` checks for the left-side operand being + a Python string and special-cases it; this results in a 1-3% + performance increase for applications that frequently use ``%`` + with strings, such as templating libraries. + (Implemented by Collin Winter; :issue:`5176`.) + +* List comprehensions with an ``if`` condition are compiled into + faster bytecode. (Patch by Antoine Pitrou, back-ported to 2.7 + by Jeffrey Yasskin; :issue:`4715`.) .. ====================================================================== @@ -153,15 +197,6 @@ :file:`Misc/NEWS` file in the source tree for a more complete list of changes, or look through the Subversion logs for all the details. -* In Distutils, distutils.sdist.add_defaults now uses package_dir and data_files - to feed MANIFEST. - -* It is not mandatory anymore to store clear text passwords in the - :file:`.pypirc` file when registering and uploading packages to PyPI. As long - as the username is present in that file, the :mod:`distutils` package will - prompt for the password if not present. (Added by tarek, with the initial - contribution of Nathan Van Gheem; :issue:`4394`.) - * The :mod:`bz2` module's :class:`BZ2File` now supports the context management protocol, so you can write ``with bz2.BZ2File(...) as f: ...``. (Contributed by Hagen Fuerstenau; :issue:`3860`.) @@ -200,21 +235,100 @@ Contributed by Raymond Hettinger; :issue:`1696199`. + The :class:`namedtuple` class now has an optional *rename* parameter. + If *rename* is True, field names that are invalid because they've + been repeated or that aren't legal Python identifiers will be + renamed to legal names that are derived from the field's + position within the list of fields: + + >>> T=namedtuple('T', ['field1', '$illegal', 'for', 'field2'], rename=True) + >>> T._fields + ('field1', '_1', '_2', 'field2') + + (Added by Raymond Hettinger; :issue:`1818`.) + +* In Distutils, :func:`distutils.sdist.add_defaults` now uses + *package_dir* and *data_files* to create the MANIFEST file. + + It is no longer mandatory to store clear-text passwords in the + :file:`.pypirc` file when registering and uploading packages to PyPI. As long + as the username is present in that file, the :mod:`distutils` package will + prompt for the password if not present. (Added by Tarek Ziade, + based on an initial contribution by Nathan Van Gheem; :issue:`4394`.) + +* New method: the :class:`Decimal` class gained a + :meth:`from_float` class method that performs an exact conversion + of a floating-point number to a :class:`Decimal`. + Note that this is an **exact** conversion that strives for the + closest decimal approximation to the floating-point representation's value; + the resulting decimal value will therefore still include the inaccuracy, + if any. + For example, ``Decimal.from_float(0.1)`` returns + ``Decimal('0.1000000000000000055511151231257827021181583404541015625')``. + (Implemented by Raymond Hettinger; :issue:`4796`.) + +* A new function in the :mod:`gc` module, :func:`is_tracked`, returns + True if a given instance is tracked by the garbage collector, False + otherwise. (Contributed by Antoine Pitrou; :issue:`4688`.) + * The :mod:`gzip` module's :class:`GzipFile` now supports the context management protocol, so you can write ``with gzip.GzipFile(...) as f: ...``. (Contributed by Hagen Fuerstenau; :issue:`3860`.) + It's now possible to override the modification time + recorded in a gzipped file by providing an optional timestamp to + the constructor. (Contributed by Jacques Frechet; :issue:`4272`.) * The :class:`io.FileIO` class now raises an :exc:`OSError` when passed an invalid file descriptor. (Implemented by Benjamin Peterson; :issue:`4991`.) +* New function: ``itertools.compress(*data*, *selectors*)`` takes two + iterators. Elements of *data* are returned if the corresponding + value in *selectors* is True:: + + itertools.compress('ABCDEF', [1,0,1,0,1,1]) => + A, C, E, F + + New function: ``itertools.combinations_with_replacement(*iter*, *r*)`` + returns all the possible *r*-length combinations of elements from the + iterable *iter*. Unlike :func:`combinations`, individual elements + can be repeated in the generated combinations:: + + itertools.combinations_with_replacement('abc', 2) => + ('a', 'a'), ('a', 'b'), ('a', 'c'), + ('b', 'b'), ('b', 'c'), ('c', 'c') + + Note that elements are treated as unique depending on their position + in the input, not their actual values. + + The :class:`itertools.count` function now has a *step* argument that + allows incrementing by values other than 1. :func:`count` also + now allows keyword arguments, and using non-integer values such as + floats or :class:`Decimal` instances. (Implemented by Raymond + Hettinger; :issue:`5032`.) + + :func:`itertools.combinations` and :func:`itertools.product` were + previously raising :exc:`ValueError` for values of *r* larger than + the input iterable. This was deemed a specification error, so they + now return an empty iterator. (Fixed by Raymond Hettinger; :issue:`4816`.) + +* The :mod:`json` module was upgraded to version 2.0.9 of the + simplejson package, which includes a C extension that makes + encoding and decoding faster. + (Contributed by Bob Ippolito; :issue:`4136`.) + + To support the new :class:`OrderedDict` type, :func:`json.load` + now has an optional *object_pairs_hook* parameter that will be called + with any object literal that decodes to a list of pairs. + (Contributed by Raymond Hettinger; :issue:`5381`.) + * The :mod:`pydoc` module now has help for the various symbols that Python uses. You can now do ``help('<<')`` or ``help('@')``, for example. (Contributed by David Laban; :issue:`4739`.) * A new function in the :mod:`subprocess` module, :func:`check_output`, runs a command with a specified set of arguments - and returns the command's output as a string if the command runs without + and returns the command's output as a string when the command runs without error, or raises a :exc:`CalledProcessError` exception otherwise. :: @@ -229,13 +343,41 @@ (Contributed by Gregory P. Smith.) +* The ``sys.version_info`` value is now a named tuple, with attributes + named ``major``, ``minor``, ``micro``, ``releaselevel``, and ``serial``. + (Contributed by Ross Light; :issue:`4285`.) + +* The :mod:`unittest` module was enhanced in several ways. + Test cases can raise the :exc:`SkipTest` exception to skip a test. + (:issue:`1034053`.) + It will now use 'x' for expected failures + and 'u' for unexpected successes when run in its verbose mode. + (Contributed by Benjamin Peterson.) + + The :meth:`assertRaises` and :meth:`failUnlessRaises` methods now + return a context handler when called without providing a callable + object to run. For example, you can write this:: + + with self.assertRaises(KeyError): + raise ValueError + + (Implemented by Antoine Pitrou; :issue:`4444`.) + * The :func:`is_zipfile` function in the :mod:`zipfile` module will now accept a file object, in addition to the path names accepted in earlier versions. (Contributed by Gabriel Genellina; :issue:`4756`.) + :mod:`zipfile` now supports archiving empty directories and + extracts them correctly. (Fixed by Kuba Wieczorek; :issue:`4710`.) + .. ====================================================================== .. whole new modules get described in subsections here +importlib: Importing Modules +------------------------------ + +XXX write this + ttk: Themed Widgets for Tk -------------------------- @@ -266,11 +408,16 @@ debugged doesn't hold the GIL; the macro will now acquire it before printing. (Contributed by Victor Stinner; :issue:`3632`.) -* :cfunc:`Py_AddPendingCall` is now thread safe, letting any +* :cfunc:`Py_AddPendingCall` is now thread-safe, letting any worker thread submit notifications to the main Python thread. This is particularly useful for asynchronous IO operations. (Contributed by Kristjan Valur Jonsson; :issue:`4293`.) +* The :program:`configure` script now checks for floating-point rounding bugs + on certain 32-bit Intel chips and defines a :cmacro:`X87_DOUBLE_ROUNDING` + preprocessor definition. No code currently uses this definition, + but it's available if anyone wishes to use it. + (Added by Mark Dickinson; :issue:`2937`.) .. ====================================================================== @@ -293,6 +440,28 @@ Port-Specific Changes: Mac OS X ----------------------------------- +* The ``/Library/Python/2.7/site-packages`` is now appended to + ``sys.path``, in order to share added packages between the system + installation and a user-installed copy of the same version. + (Changed by Ronald Oussoren; :issue:`4865`.) + + +Other Changes and Fixes +======================= + +* When importing a module from a :file:`.pyc` or :file:`.pyo` file + with an existing :file:`.py` counterpart, the :attr:`co_filename` + attributes of all code objects if the original filename is obsolete, + which can happen if the file has been renamed, moved, or is accessed + through different paths. (Patch by Ziga Seilnacht and Jean-Paul + Calderone; :issue:`1180193`.) + +* The :file:`regrtest.py` script now takes a :option:`--randseed=` + switch that takes an integer that will be used as the random seed + for the :option:`-r` option that executes tests in random order. + The :option:`-r` option also now reports the seed that was used + (Added by Collin Winter.) + .. ====================================================================== Modified: python/branches/py3k-short-float-repr/Include/patchlevel.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/patchlevel.h (original) +++ python/branches/py3k-short-float-repr/Include/patchlevel.h Mon Apr 6 00:11:42 2009 @@ -23,7 +23,7 @@ #define PY_RELEASE_SERIAL 2 /* Version as a string */ -#define PY_VERSION "3.1a2" +#define PY_VERSION "3.1a2+" /*--end constants--*/ /* Subversion Revision number of this file (not of the repository) */ Modified: python/branches/py3k-short-float-repr/Lib/distutils/cmd.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/cmd.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/cmd.py Mon Apr 6 00:11:42 2009 @@ -333,7 +333,8 @@ # -- External world manipulation ----------------------------------- def warn(self, msg): - log.warn("warning: %s: %s\n" % (self.get_command_name(), msg)) + log.warn("warning: %s: %s\n" % + (self.get_command_name(), msg)) def execute(self, func, args, msg=None, level=1): util.execute(func, args, msg, dry_run=self.dry_run) Modified: python/branches/py3k-short-float-repr/Lib/distutils/log.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/log.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/log.py Mon Apr 6 00:11:42 2009 @@ -18,13 +18,14 @@ def _log(self, level, msg, args): if level >= self.threshold: - if not args: - # msg may contain a '%'. If args is empty, - # don't even try to string-format - print(msg) + if args: + msg = msg % args + if level in (WARN, ERROR, FATAL): + stream = sys.stderr else: - print(msg % args) - sys.stdout.flush() + stream = sys.stdout + stream.write('%s\n' % msg) + stream.flush() def log(self, level, msg, *args): self._log(level, msg, args) Modified: python/branches/py3k-short-float-repr/Lib/distutils/tests/test_clean.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/tests/test_clean.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/tests/test_clean.py Mon Apr 6 00:11:42 2009 @@ -8,6 +8,7 @@ from distutils.tests import support class cleanTestCase(support.TempdirManager, + support.LoggingSilencer, unittest.TestCase): def test_simple_run(self): Modified: python/branches/py3k-short-float-repr/Lib/ftplib.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/ftplib.py (original) +++ python/branches/py3k-short-float-repr/Lib/ftplib.py Mon Apr 6 00:11:42 2009 @@ -223,7 +223,7 @@ def voidresp(self): """Expect a response beginning with '2'.""" resp = self.getresp() - if resp[0] != '2': + if resp[:1] != '2': raise error_reply(resp) return resp @@ -522,8 +522,6 @@ resp = self.sendcmd('DELE ' + filename) if resp[:3] in ('250', '200'): return resp - elif resp[:1] == '5': - raise error_perm(resp) else: raise error_reply(resp) Modified: python/branches/py3k-short-float-repr/Lib/glob.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/glob.py (original) +++ python/branches/py3k-short-float-repr/Lib/glob.py Mon Apr 6 00:11:42 2009 @@ -16,7 +16,7 @@ return list(iglob(pathname)) def iglob(pathname): - """Return a list of paths matching a pathname pattern. + """Return an iterator which yields the paths matching a pathname pattern. The pattern may contain simple shell-style wildcards a la fnmatch. Modified: python/branches/py3k-short-float-repr/Lib/multiprocessing/synchronize.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/multiprocessing/synchronize.py (original) +++ python/branches/py3k-short-float-repr/Lib/multiprocessing/synchronize.py Mon Apr 6 00:11:42 2009 @@ -301,5 +301,10 @@ self._flag.release() else: self._cond.wait(timeout) + + if self._flag.acquire(False): + self._flag.release() + return True + return False finally: self._cond.release() Modified: python/branches/py3k-short-float-repr/Lib/optparse.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/optparse.py (original) +++ python/branches/py3k-short-float-repr/Lib/optparse.py Mon Apr 6 00:11:42 2009 @@ -11,6 +11,7 @@ __version__ = "1.5.3" __all__ = ['Option', + 'make_option', 'SUPPRESS_HELP', 'SUPPRESS_USAGE', 'Values', Modified: python/branches/py3k-short-float-repr/Lib/pdb.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/pdb.py (original) +++ python/branches/py3k-short-float-repr/Lib/pdb.py Mon Apr 6 00:11:42 2009 @@ -95,10 +95,14 @@ rcFile.close() self.commands = {} # associates a command list to breakpoint numbers - self.commands_doprompt = {} # for each bp num, tells if the prompt must be disp. after execing the cmd list - self.commands_silent = {} # for each bp num, tells if the stack trace must be disp. after execing the cmd list - self.commands_defining = False # True while in the process of defining a command list - self.commands_bnum = None # The breakpoint number for which we are defining a list + self.commands_doprompt = {} # for each bp num, tells if the prompt + # must be disp. after execing the cmd list + self.commands_silent = {} # for each bp num, tells if the stack trace + # must be disp. after execing the cmd list + self.commands_defining = False # True while in the process of defining + # a command list + self.commands_bnum = None # The breakpoint number for which we are + # defining a list def reset(self): bdb.Bdb.reset(self) @@ -114,6 +118,10 @@ self.forget() self.stack, self.curindex = self.get_stack(f, t) self.curframe = self.stack[self.curindex][0] + # The f_locals dictionary is updated from the actual frame + # locals whenever the .f_locals accessor is called, so we + # cache it here to ensure that modifications are not overwritten. + self.curframe_locals = self.curframe.f_locals self.execRcLines() # Can be executed earlier than 'setup' if desired @@ -192,21 +200,30 @@ self.cmdloop() self.forget() + def displayhook(self, obj): + """Custom displayhook for the exec in default(), which prevents + assignment of the _ variable in the builtins. + """ + print(repr(obj)) + def default(self, line): if line[:1] == '!': line = line[1:] - locals = self.curframe.f_locals + locals = self.curframe_locals globals = self.curframe.f_globals try: code = compile(line + '\n', '', 'single') save_stdout = sys.stdout save_stdin = sys.stdin + save_displayhook = sys.displayhook try: sys.stdin = self.stdin sys.stdout = self.stdout + sys.displayhook = self.displayhook exec(code, globals, locals) finally: sys.stdout = save_stdout sys.stdin = save_stdin + sys.displayhook = save_displayhook except: t, v = sys.exc_info()[:2] if type(t) == type(''): @@ -349,7 +366,7 @@ try: func = eval(arg, self.curframe.f_globals, - self.curframe.f_locals) + self.curframe_locals) except: func = arg try: @@ -597,6 +614,7 @@ else: self.curindex = self.curindex - 1 self.curframe = self.stack[self.curindex][0] + self.curframe_locals = self.curframe.f_locals self.print_stack_entry(self.stack[self.curindex]) self.lineno = None do_u = do_up @@ -607,6 +625,7 @@ else: self.curindex = self.curindex + 1 self.curframe = self.stack[self.curindex][0] + self.curframe_locals = self.curframe.f_locals self.print_stack_entry(self.stack[self.curindex]) self.lineno = None do_d = do_down @@ -670,7 +689,7 @@ def do_debug(self, arg): sys.settrace(None) globals = self.curframe.f_globals - locals = self.curframe.f_locals + locals = self.curframe_locals p = Pdb(self.completekey, self.stdin, self.stdout) p.prompt = "(%s) " % self.prompt.strip() print("ENTERING RECURSIVE DEBUGGER", file=self.stdout) @@ -694,9 +713,8 @@ return 1 def do_args(self, arg): - f = self.curframe - co = f.f_code - dict = f.f_locals + co = self.curframe.f_code + dict = self.curframe_locals n = co.co_argcount if co.co_flags & 4: n = n+1 if co.co_flags & 8: n = n+1 @@ -708,16 +726,15 @@ do_a = do_args def do_retval(self, arg): - if '__return__' in self.curframe.f_locals: - print(self.curframe.f_locals['__return__'], file=self.stdout) + if '__return__' in self.curframe_locals: + print(self.curframe_locals['__return__'], file=self.stdout) else: print('*** Not yet returned!', file=self.stdout) do_rv = do_retval def _getval(self, arg): try: - return eval(arg, self.curframe.f_globals, - self.curframe.f_locals) + return eval(arg, self.curframe.f_globals, self.curframe_locals) except: t, v = sys.exc_info()[:2] if isinstance(t, str): @@ -788,7 +805,7 @@ def do_whatis(self, arg): try: value = eval(arg, self.curframe.f_globals, - self.curframe.f_locals) + self.curframe_locals) except: t, v = sys.exc_info()[:2] if type(t) == type(''): Modified: python/branches/py3k-short-float-repr/Lib/pydoc.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/pydoc.py (original) +++ python/branches/py3k-short-float-repr/Lib/pydoc.py Mon Apr 6 00:11:42 2009 @@ -1922,8 +1922,12 @@ if key is None: callback(None, modname, '') else: - loader = importer.find_module(modname) - if hasattr(loader,'get_source'): + try: + loader = importer.find_module(modname) + except SyntaxError: + # raised by tests for bad coding cookies or BOM + continue + if hasattr(loader, 'get_source'): try: source = loader.get_source(modname) except UnicodeDecodeError: @@ -1932,7 +1936,7 @@ continue import io desc = source_synopsis(io.StringIO(source)) or '' - if hasattr(loader,'get_filename'): + if hasattr(loader, 'get_filename'): path = loader.get_filename(modname) else: path = None Deleted: python/branches/py3k-short-float-repr/Lib/test/README ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/README Mon Apr 6 00:11:42 2009 +++ (empty file) @@ -1,411 +0,0 @@ -+++++++++++++++++++++++++++++++ -Writing Python Regression Tests -+++++++++++++++++++++++++++++++ - -:Author: Skip Montanaro -:Contact: skip at pobox.com - -Introduction -============ - -If you add a new module to Python or modify the functionality of an existing -module, you should write one or more test cases to exercise that new -functionality. There are different ways to do this within the regression -testing facility provided with Python; any particular test should use only -one of these options. Each option requires writing a test module using the -conventions of the selected option: - - - unittest_ based tests - - doctest_ based tests - - "traditional" Python test modules - -Regardless of the mechanics of the testing approach you choose, -you will be writing unit tests (isolated tests of functions and objects -defined by the module) using white box techniques. Unlike black box -testing, where you only have the external interfaces to guide your test case -writing, in white box testing you can see the code being tested and tailor -your test cases to exercise it more completely. In particular, you will be -able to refer to the C and Python code in the CVS repository when writing -your regression test cases. - -.. _unittest: http://www.python.org/doc/current/lib/module-unittest.html -.. _doctest: http://www.python.org/doc/current/lib/module-doctest.html - -unittest-based tests ------------------- -The unittest_ framework is based on the ideas of unit testing as espoused -by Kent Beck and the `Extreme Programming`_ (XP) movement. The specific -interface provided by the framework is tightly based on the JUnit_ -Java implementation of Beck's original SmallTalk test framework. Please -see the documentation of the unittest_ module for detailed information on -the interface and general guidelines on writing unittest-based tests. - -The test_support helper module provides a function for use by -unittest-based tests in the Python regression testing framework, -``run_unittest()``. This is the primary way of running tests in the -standard library. You can pass it any number of the following: - -- classes derived from or instances of ``unittest.TestCase`` or - ``unittest.TestSuite``. These will be handed off to unittest for - converting into a proper TestSuite instance. - -- a string; this must be a key in sys.modules. The module associated with - that string will be scanned by ``unittest.TestLoader.loadTestsFromModule``. - This is usually seen as ``test_support.run_unittest(__name__)`` in a test - module's ``test_main()`` function. This has the advantage of picking up - new tests automatically, without you having to add each new test case - manually. - -All test methods in the Python regression framework have names that -start with "``test_``" and use lower-case names with words separated with -underscores. - -Test methods should *not* have docstrings! The unittest module prints -the docstring if there is one, but otherwise prints the function name -and the full class name. When there's a problem with a test, the -latter information makes it easier to find the source for the test -than the docstring. - -All unittest-based tests in the Python test suite use boilerplate that -looks like this (with minor variations):: - - import unittest - from test import test_support - - class MyTestCase1(unittest.TestCase): - - # Define setUp and tearDown only if needed - - def setUp(self): - unittest.TestCase.setUp(self) - ... additional initialization... - - def tearDown(self): - ... additional finalization... - unittest.TestCase.tearDown(self) - - def test_feature_one(self): - # Testing feature one - ...unit test for feature one... - - def test_feature_two(self): - # Testing feature two - ...unit test for feature two... - - ...etc... - - class MyTestCase2(unittest.TestCase): - ...same structure as MyTestCase1... - - ...etc... - - def test_main(): - test_support.run_unittest(__name__) - - if __name__ == "__main__": - test_main() - -This has the advantage that it allows the unittest module to be used -as a script to run individual tests as well as working well with the -regrtest framework. - -.. _Extreme Programming: http://www.extremeprogramming.org/ -.. _JUnit: http://www.junit.org/ - -doctest based tests -------------------- -Tests written to use doctest_ are actually part of the docstrings for -the module being tested. Each test is written as a display of an -interactive session, including the Python prompts, statements that would -be typed by the user, and the output of those statements (including -tracebacks, although only the exception msg needs to be retained then). -The module in the test package is simply a wrapper that causes doctest -to run over the tests in the module. The test for the difflib module -provides a convenient example:: - - import difflib - from test import test_support - test_support.run_doctest(difflib) - -If the test is successful, nothing is written to stdout (so you should not -create a corresponding output/test_difflib file), but running regrtest -with -v will give a detailed report, the same as if passing -v to doctest. - -A second argument can be passed to run_doctest to tell doctest to search -``sys.argv`` for -v instead of using test_support's idea of verbosity. This -is useful for writing doctest-based tests that aren't simply running a -doctest'ed Lib module, but contain the doctests themselves. Then at -times you may want to run such a test directly as a doctest, independent -of the regrtest framework. The tail end of test_descrtut.py is a good -example:: - - def test_main(verbose=None): - from test import test_support, test_descrtut - test_support.run_doctest(test_descrtut, verbose) - - if __name__ == "__main__": - test_main(1) - -If run via regrtest, ``test_main()`` is called (by regrtest) without -specifying verbose, and then test_support's idea of verbosity is used. But -when run directly, ``test_main(1)`` is called, and then doctest's idea of -verbosity is used. - -See the documentation for the doctest module for information on -writing tests using the doctest framework. - -"traditional" Python test modules ---------------------------------- -The mechanics of how the "traditional" test system operates are fairly -straightforward. When a test case is run, the output is compared with the -expected output that is stored in .../Lib/test/output. If the test runs to -completion and the actual and expected outputs match, the test succeeds, if -not, it fails. If an ``ImportError`` or ``test_support.TestSkipped`` error -is raised, the test is not run. - -Executing Test Cases -==================== -If you are writing test cases for module spam, you need to create a file -in .../Lib/test named test_spam.py. In addition, if the tests are expected -to write to stdout during a successful run, you also need to create an -expected output file in .../Lib/test/output named test_spam ("..." -represents the top-level directory in the Python source tree, the directory -containing the configure script). If needed, generate the initial version -of the test output file by executing:: - - ./python Lib/test/regrtest.py -g test_spam.py - -from the top-level directory. - -Any time you modify test_spam.py you need to generate a new expected -output file. Don't forget to desk check the generated output to make sure -it's really what you expected to find! All in all it's usually better -not to have an expected-out file (note that doctest- and unittest-based -tests do not). - -To run a single test after modifying a module, simply run regrtest.py -without the -g flag:: - - ./python Lib/test/regrtest.py test_spam.py - -While debugging a regression test, you can of course execute it -independently of the regression testing framework and see what it prints:: - - ./python Lib/test/test_spam.py - -To run the entire test suite: - -- [UNIX, + other platforms where "make" works] Make the "test" target at the - top level:: - - make test - -- [WINDOWS] Run rt.bat from your PCBuild directory. Read the comments at - the top of rt.bat for the use of special -d, -O and -q options processed - by rt.bat. - -- [OTHER] You can simply execute the two runs of regrtest (optimized and - non-optimized) directly:: - - ./python Lib/test/regrtest.py - ./python -O Lib/test/regrtest.py - -But note that this way picks up whatever .pyc and .pyo files happen to be -around. The makefile and rt.bat ways run the tests twice, the first time -removing all .pyc and .pyo files from the subtree rooted at Lib/. - -Test cases generate output based upon values computed by the test code. -When executed, regrtest.py compares the actual output generated by executing -the test case with the expected output and reports success or failure. It -stands to reason that if the actual and expected outputs are to match, they -must not contain any machine dependencies. This means your test cases -should not print out absolute machine addresses (e.g. the return value of -the id() builtin function) or floating point numbers with large numbers of -significant digits (unless you understand what you are doing!). - - -Test Case Writing Tips -====================== -Writing good test cases is a skilled task and is too complex to discuss in -detail in this short document. Many books have been written on the subject. -I'll show my age by suggesting that Glenford Myers' `"The Art of Software -Testing"`_, published in 1979, is still the best introduction to the subject -available. It is short (177 pages), easy to read, and discusses the major -elements of software testing, though its publication predates the -object-oriented software revolution, so doesn't cover that subject at all. -Unfortunately, it is very expensive (about $100 new). If you can borrow it -or find it used (around $20), I strongly urge you to pick up a copy. - -The most important goal when writing test cases is to break things. A test -case that doesn't uncover a bug is much less valuable than one that does. -In designing test cases you should pay attention to the following: - - * Your test cases should exercise all the functions and objects defined - in the module, not just the ones meant to be called by users of your - module. This may require you to write test code that uses the module - in ways you don't expect (explicitly calling internal functions, for - example - see test_atexit.py). - - * You should consider any boundary values that may tickle exceptional - conditions (e.g. if you were writing regression tests for division, - you might well want to generate tests with numerators and denominators - at the limits of floating point and integer numbers on the machine - performing the tests as well as a denominator of zero). - - * You should exercise as many paths through the code as possible. This - may not always be possible, but is a goal to strive for. In - particular, when considering if statements (or their equivalent), you - want to create test cases that exercise both the true and false - branches. For loops, you should create test cases that exercise the - loop zero, one and multiple times. - - * You should test with obviously invalid input. If you know that a - function requires an integer input, try calling it with other types of - objects to see how it responds. - - * You should test with obviously out-of-range input. If the domain of a - function is only defined for positive integers, try calling it with a - negative integer. - - * If you are going to fix a bug that wasn't uncovered by an existing - test, try to write a test case that exposes the bug (preferably before - fixing it). - - * If you need to create a temporary file, you can use the filename in - ``test_support.TESTFN`` to do so. It is important to remove the file - when done; other tests should be able to use the name without cleaning - up after your test. - -.. _"The Art of Software Testing": - http://www.amazon.com/exec/obidos/ISBN=0471043281 - -Regression Test Writing Rules -============================= -Each test case is different. There is no "standard" form for a Python -regression test case, though there are some general rules (note that -these mostly apply only to the "classic" tests; unittest_- and doctest_- -based tests should follow the conventions natural to those frameworks):: - - * If your test case detects a failure, raise ``TestFailed`` (found in - ``test.test_support``). - - * Import everything you'll need as early as possible. - - * If you'll be importing objects from a module that is at least - partially platform-dependent, only import those objects you need for - the current test case to avoid spurious ``ImportError`` exceptions - that prevent the test from running to completion. - - * Print all your test case results using the ``print`` statement. For - non-fatal errors, print an error message (or omit a successful - completion print) to indicate the failure, but proceed instead of - raising ``TestFailed``. - - * Use ``assert`` sparingly, if at all. It's usually better to just print - what you got, and rely on regrtest's got-vs-expected comparison to - catch deviations from what you expect. ``assert`` statements aren't - executed at all when regrtest is run in -O mode; and, because they - cause the test to stop immediately, can lead to a long & tedious - test-fix, test-fix, test-fix, ... cycle when things are badly broken - (and note that "badly broken" often includes running the test suite - for the first time on new platforms or under new implementations of - the language). - -Miscellaneous -============= -There is a test_support module in the test package you can import for -your test case. Import this module using either:: - - import test.test_support - -or:: - - from test import test_support - -test_support provides the following useful objects: - - * ``TestFailed`` - raise this exception when your regression test detects - a failure. - - * ``TestSkipped`` - raise this if the test could not be run because the - platform doesn't offer all the required facilities (like large - file support), even if all the required modules are available. - - * ``ResourceDenied`` - this is raised when a test requires a resource that - is not available. Primarily used by 'requires'. - - * ``verbose`` - you can use this variable to control print output. Many - modules use it. Search for "verbose" in the test_*.py files to see - lots of examples. - - * ``forget(module_name)`` - attempts to cause Python to "forget" that it - loaded a module and erase any PYC files. - - * ``is_resource_enabled(resource)`` - Returns a boolean based on whether - the resource is enabled or not. - - * ``requires(resource [, msg])`` - if the required resource is not - available the ResourceDenied exception is raised. - - * ``verify(condition, reason='test failed')``. Use this instead of:: - - assert condition[, reason] - - ``verify()`` has two advantages over ``assert``: it works even in -O - mode, and it raises ``TestFailed`` on failure instead of - ``AssertionError``. - - * ``is_jython`` - true if the interpreter is Jython, false otherwise. - - * ``TESTFN`` - a string that should always be used as the filename when - you need to create a temp file. Also use ``try``/``finally`` to - ensure that your temp files are deleted before your test completes. - Note that you cannot unlink an open file on all operating systems, so - also be sure to close temp files before trying to unlink them. - - * ``sortdict(dict)`` - acts like ``repr(dict.items())``, but sorts the - items first. This is important when printing a dict value, because - the order of items produced by ``dict.items()`` is not defined by the - language. - - * ``findfile(file)`` - you can call this function to locate a file - somewhere along sys.path or in the Lib/test tree - see - test_ossaudiodev.py for an example of its use. - - * ``fcmp(x,y)`` - you can call this function to compare two floating - point numbers when you expect them to only be approximately equal - withing a fuzz factor (``test_support.FUZZ``, which defaults to 1e-6). - - * ``check_syntax_error(testcase, statement)`` - make sure that the - statement is *not* correct Python syntax. - - -Some Non-Obvious regrtest Features -================================== - * Automagic test detection: When you create a new test file - test_spam.py, you do not need to modify regrtest (or anything else) - to advertise its existence. regrtest searches for and runs all - modules in the test directory with names of the form test_xxx.py. - - * Miranda output: If, when running test_spam.py, regrtest does not - find an expected-output file test/output/test_spam, regrtest - pretends that it did find one, containing the single line - - test_spam - - This allows new tests that don't expect to print anything to stdout - to not bother creating expected-output files. - - * Two-stage testing: To run test_spam.py, regrtest imports test_spam - as a module. Most tests run to completion as a side-effect of - getting imported. After importing test_spam, regrtest also executes - ``test_spam.test_main()``, if test_spam has a ``test_main`` attribute. - This is rarely required with the "traditional" Python tests, and - you shouldn't create a module global with name test_main unless - you're specifically exploiting this gimmick. This usage does - prove useful with unittest-based tests as well, however; defining - a ``test_main()`` which is run by regrtest and a script-stub in the - test module ("``if __name__ == '__main__': test_main()``") allows - the test to be used like any other Python test and also work - with the unittest.py-as-a-script approach, allowing a developer - to run specific tests from the command line. Modified: python/branches/py3k-short-float-repr/Lib/test/test_logging.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_logging.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_logging.py Mon Apr 6 00:11:42 2009 @@ -912,10 +912,10 @@ class WarningsTest(BaseTest): def test_warnings(self): - logging.captureWarnings(True) with warnings.catch_warnings(): - warnings.filterwarnings("always", category=UserWarning) + logging.captureWarnings(True) try: + warnings.filterwarnings("always", category=UserWarning) file = io.StringIO() h = logging.StreamHandler(file) logger = logging.getLogger("py.warnings") Modified: python/branches/py3k-short-float-repr/Lib/test/test_multiprocessing.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_multiprocessing.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_multiprocessing.py Mon Apr 6 00:11:42 2009 @@ -750,20 +750,22 @@ # Removed temporaily, due to API shear, this does not # work with threading._Event objects. is_set == isSet - #self.assertEqual(event.is_set(), False) + self.assertEqual(event.is_set(), False) - self.assertEqual(wait(0.0), None) + # Removed, threading.Event.wait() will return the value of the __flag + # instead of None. API Shear with the semaphore backed mp.Event + self.assertEqual(wait(0.0), False) self.assertTimingAlmostEqual(wait.elapsed, 0.0) - self.assertEqual(wait(TIMEOUT1), None) + self.assertEqual(wait(TIMEOUT1), False) self.assertTimingAlmostEqual(wait.elapsed, TIMEOUT1) event.set() # See note above on the API differences - # self.assertEqual(event.is_set(), True) - self.assertEqual(wait(), None) + self.assertEqual(event.is_set(), True) + self.assertEqual(wait(), True) self.assertTimingAlmostEqual(wait.elapsed, 0.0) - self.assertEqual(wait(TIMEOUT1), None) + self.assertEqual(wait(TIMEOUT1), True) self.assertTimingAlmostEqual(wait.elapsed, 0.0) # self.assertEqual(event.is_set(), True) @@ -772,7 +774,7 @@ #self.assertEqual(event.is_set(), False) self.Process(target=self._test_event, args=(event,)).start() - self.assertEqual(wait(), None) + self.assertEqual(wait(), True) # # Modified: python/branches/py3k-short-float-repr/Lib/test/test_pprint.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_pprint.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_pprint.py Mon Apr 6 00:11:42 2009 @@ -115,10 +115,10 @@ {}, dict2(), dict3(), verify, pprint, -6, -6, -6-6j, -1.5, "x", b"x", (3,), [3], {3: 6}, - (1,2), [3,4], {5: 6, 7: 8}, + (1,2), [3,4], {5: 6}, tuple2((1,2)), tuple3((1,2)), tuple3(range(100)), [3,4], list2([3,4]), list3([3,4]), list3(range(100)), - {5: 6, 7: 8}, dict2({5: 6}), dict3({5: 6}), + dict2({5: 6}), dict3({5: 6}), range(10, -11, -1) ): native = repr(simple) Modified: python/branches/py3k-short-float-repr/Lib/test/test_sys.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_sys.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_sys.py Mon Apr 6 00:11:42 2009 @@ -225,6 +225,11 @@ sys.setdlopenflags(oldflags) def test_refcount(self): + # n here must be a global in order for this test to pass while + # tracing with a python function. Tracing calls PyFrame_FastToLocals + # which will add a copy of any locals to the frame object, causing + # the reference count to increase by 2 instead of 1. + global n self.assertRaises(TypeError, sys.getrefcount) c = sys.getrefcount(None) n = None Modified: python/branches/py3k-short-float-repr/Lib/test/test_threading.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_threading.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_threading.py Mon Apr 6 00:11:42 2009 @@ -84,11 +84,24 @@ t.join(NUMTASKS) self.assert_(not t.is_alive()) self.failIfEqual(t.ident, 0) + self.assertFalse(t.ident is None) self.assert_(re.match('', repr(t))) if verbose: print('all tasks done') self.assertEqual(numrunning.get(), 0) + def test_ident_of_no_threading_threads(self): + # The ident still must work for the main thread and dummy threads. + self.assertFalse(threading.currentThread().ident is None) + def f(): + ident.append(threading.currentThread().ident) + done.set() + done = threading.Event() + ident = [] + _thread.start_new_thread(f, ()) + done.wait() + self.assertFalse(ident[0] is None) + # run with a small(ish) thread stack size (256kB) def test_various_ops_small_stack(self): if verbose: @@ -187,7 +200,8 @@ # Now raise an exception in the worker thread. if verbose: print(" waiting for worker thread to get started") - worker_started.wait() + ret = worker_started.wait() + self.assertTrue(ret) if verbose: print(" verifying worker hasn't exited") self.assert_(not t.finished) Modified: python/branches/py3k-short-float-repr/Lib/test/test_traceback.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_traceback.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_traceback.py Mon Apr 6 00:11:42 2009 @@ -10,16 +10,6 @@ import traceback -try: - raise KeyError -except KeyError: - type_, value, tb = sys.exc_info() - file_ = StringIO() - traceback_print(tb, file_) - example_traceback = file_.getvalue() -else: - raise Error("unable to create test traceback string") - class SyntaxTracebackCases(unittest.TestCase): # For now, a very minimal set of tests. I want to be sure that @@ -158,9 +148,24 @@ class TracebackFormatTests(unittest.TestCase): - def test_traceback_indentation(self): + def test_traceback_format(self): + try: + raise KeyError('blah') + except KeyError: + type_, value, tb = sys.exc_info() + traceback_fmt = 'Traceback (most recent call last):\n' + \ + ''.join(traceback.format_tb(tb)) + file_ = StringIO() + traceback_print(tb, file_) + python_fmt = file_.getvalue() + else: + raise Error("unable to create test traceback string") + + # Make sure that Python and the traceback module format the same thing + self.assertEquals(traceback_fmt, python_fmt) + # Make sure that the traceback is properly indented. - tb_lines = example_traceback.splitlines() + tb_lines = python_fmt.splitlines() self.assertEquals(len(tb_lines), 3) banner, location, source_line = tb_lines self.assert_(banner.startswith('Traceback')) Modified: python/branches/py3k-short-float-repr/Lib/threading.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/threading.py (original) +++ python/branches/py3k-short-float-repr/Lib/threading.py Mon Apr 6 00:11:42 2009 @@ -375,6 +375,7 @@ try: if not self._flag: self._cond.wait(timeout) + return self._flag finally: self._cond.release() @@ -450,9 +451,8 @@ raise RuntimeError("thread already started") if __debug__: self._note("%s.start(): starting thread", self) - _active_limbo_lock.acquire() - _limbo[self] = self - _active_limbo_lock.release() + with _active_limbo_lock: + _limbo[self] = self _start_new_thread(self._bootstrap, ()) self._started.wait() @@ -485,14 +485,16 @@ return raise + def _set_ident(self): + self._ident = _get_ident() + def _bootstrap_inner(self): try: - self._ident = _get_ident() + self._set_ident() self._started.set() - _active_limbo_lock.acquire() - _active[self._ident] = self - del _limbo[self] - _active_limbo_lock.release() + with _active_limbo_lock: + _active[self._ident] = self + del _limbo[self] if __debug__: self._note("%s._bootstrap(): thread started", self) @@ -721,9 +723,9 @@ def __init__(self): Thread.__init__(self, name="MainThread") self._started.set() - _active_limbo_lock.acquire() - _active[_get_ident()] = self - _active_limbo_lock.release() + self._set_ident() + with _active_limbo_lock: + _active[self._ident] = self def _set_daemon(self): return False @@ -768,9 +770,9 @@ self._started.set() - _active_limbo_lock.acquire() - _active[_get_ident()] = self - _active_limbo_lock.release() + self._set_ident() + with _active_limbo_lock: + _active[self._ident] = self def _set_daemon(self): return True @@ -791,18 +793,14 @@ currentThread = current_thread def active_count(): - _active_limbo_lock.acquire() - count = len(_active) + len(_limbo) - _active_limbo_lock.release() - return count + with _active_limbo_lock: + return len(_active) + len(_limbo) activeCount = active_count def enumerate(): - _active_limbo_lock.acquire() - active = list(_active.values()) + list(_limbo.values()) - _active_limbo_lock.release() - return active + with _active_limbo_lock: + return list(_active.values()) + list(_limbo.values()) from _thread import stack_size Modified: python/branches/py3k-short-float-repr/Lib/traceback.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/traceback.py (original) +++ python/branches/py3k-short-float-repr/Lib/traceback.py Mon Apr 6 00:11:42 2009 @@ -63,7 +63,7 @@ filename = co.co_filename name = co.co_name _print(file, - ' File "%s", line %d, in %s' % (filename,lineno,name)) + ' File "%s", line %d, in %s' % (filename, lineno, name)) linecache.checkcache(filename) line = linecache.getline(filename, lineno, f.f_globals) if line: _print(file, ' ' + line.strip()) @@ -159,9 +159,8 @@ _print(file, 'Traceback (most recent call last):') print_tb(tb, limit, file) lines = format_exception_only(type(value), value) - for line in lines[:-1]: - _print(file, line, ' ') - _print(file, lines[-1], '') + for line in lines: + _print(file, line, '') def format_exception(etype, value, tb, limit=None, chain=True): """Format a stack trace and the exception information. Modified: python/branches/py3k-short-float-repr/Makefile.pre.in ============================================================================== --- python/branches/py3k-short-float-repr/Makefile.pre.in (original) +++ python/branches/py3k-short-float-repr/Makefile.pre.in Mon Apr 6 00:11:42 2009 @@ -586,8 +586,7 @@ Objects/bytearrayobject.o: $(srcdir)/Objects/bytearrayobject.c $(BYTESTR_DEPS) Objects/unicodeobject.o: $(srcdir)/Objects/unicodeobject.c \ - $(BYTESTR_DEPS) \ - $(srcdir)/Objects/stringlib/formatter.h + $(BYTESTR_DEPS) $(OPCODETARGETS_H): $(OPCODETARGETGEN_FILES) $(OPCODETARGETGEN) $(OPCODETARGETS_H) Modified: python/branches/py3k-short-float-repr/Misc/ACKS ============================================================================== --- python/branches/py3k-short-float-repr/Misc/ACKS (original) +++ python/branches/py3k-short-float-repr/Misc/ACKS Mon Apr 6 00:11:42 2009 @@ -392,6 +392,7 @@ Greg Kochanski Damon Kohler Joseph Koshy +Maksim Kozyarchuk Bob Kras Holger Krekel Michael Kremer Modified: python/branches/py3k-short-float-repr/Misc/NEWS ============================================================================== --- python/branches/py3k-short-float-repr/Misc/NEWS (original) +++ python/branches/py3k-short-float-repr/Misc/NEWS Mon Apr 6 00:11:42 2009 @@ -4,6 +4,18 @@ (editors: check NEWS.help for information about editing NEWS using ReST.) +What's New in Python 3.1 beta 1? +================================ + +*Release date: XXXX-XX-XX* + +Core and Builtins +----------------- + +Library +------- + + What's New in Python 3.1 alpha 2? ================================= @@ -68,7 +80,7 @@ Library ------- -- Issue 2625: added missing items() call to the for loop in +- Issue #2625: added missing items() call to the for loop in mailbox.MH.get_message(). - Issue #5640: Fix _multibytecodec so that CJK codecs don't repeat @@ -175,7 +187,7 @@ the type definition cmpfunc. The tp_compare slot has been renamed to tp_reserved, and is reserved for future usage. -- Issue 1242657: the __len__() and __length_hint__() calls in several tools +- Issue #1242657: the __len__() and __length_hint__() calls in several tools were suppressing all exceptions. These include list() and bytearray(). - Issue #4707: round(x, n) now returns an integer if x is an integer. @@ -315,6 +327,10 @@ Library ------- +- Issue #5694: removed spurious test output in Distutils (test_clean). + +- Issue #1326077: fix the formatting of SyntaxErrors by the traceback module. + - Issue #1665206 (partially): Move imports in cgitb to the top of the module instead of performing them in functions. Helps prevent import deadlocking in threads. @@ -465,7 +481,7 @@ operator module; use the abstract base classes instead. Also removed the repeat() function; use mul() instead. -- Issue 5021: doctest.testfile() did not create __name__ and +- Issue #5021: doctest.testfile() did not create __name__ and collections.namedtuple() relied on __name__ being defined. - Backport importlib from Python 3.1. Only the import_module() function has @@ -479,7 +495,7 @@ - Added a new itertools functions: combinations_with_replacement() and compress(). -- Issue 5032: added a step argument to itertools.count() and +- Issue #5032: added a step argument to itertools.count() and allowed non-integer arguments. - Fix and properly document the multiprocessing module's logging @@ -566,7 +582,7 @@ - Issue #4812: add missing underscore prefix to some internal-use-only constants in the decimal module. (Dec_0 becomes _Dec_0, etc.) -- Issue 4790: The nsmallest() and nlargest() functions in the heapq module +- Issue #4790: The nsmallest() and nlargest() functions in the heapq module did unnecessary work in the common case where no key function was specified. - Issue #4795: inspect.isgeneratorfunction() returns False instead of None when Modified: python/branches/py3k-short-float-repr/Misc/developers.txt ============================================================================== --- python/branches/py3k-short-float-repr/Misc/developers.txt (original) +++ python/branches/py3k-short-float-repr/Misc/developers.txt Mon Apr 6 00:11:42 2009 @@ -17,6 +17,18 @@ Permissions History ------------------- +- Paul Kippes was given commit privileges at PyCon 2009 by BAC to work on 3to2. + +- Ron DuPlain was given commit privileges at PyCon 2009 by BAC to work on 3to2. + +- Several developers of alternative Python implementations where + given access for test suite and library adaptions by MvL: + Allison Randal (Parrot), Michael Foord (IronPython), + Jim Baker, Philip Jenvey, and Frank Wierzbicki (all Jython). + +- R. David Murray was given SVN access on March 30 2009 by MvL, after + recommendation by BAC. + - Chris Withers was given SVN access on March 8 2009 by MvL, after recommendation by GvR. @@ -244,10 +256,11 @@ Initials of Project Admins -------------------------- -GvR: Guido van Rossum -NCN: Neal Norwitz -RDH: Raymond Hettinger TGP: Tim Peters +GFB: Georg Brandl +BAC: Brett Cannon +NCN: Neal Norwitz DJG: David Goodger MvL: Martin v. Loewis -GFB: Georg Brandl +GvR: Guido van Rossum +RDH: Raymond Hettinger Modified: python/branches/py3k-short-float-repr/Modules/_io/_iomodule.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_io/_iomodule.c (original) +++ python/branches/py3k-short-float-repr/Modules/_io/_iomodule.c Mon Apr 6 00:11:42 2009 @@ -60,7 +60,7 @@ "allowed to throw an IOError if they do not support a given operation.\n" "\n" "Extending IOBase is RawIOBase which deals simply with the reading and\n" -"writing of raw bytes to a stream. FileIO subc lasses RawIOBase to provide\n" +"writing of raw bytes to a stream. FileIO subclasses RawIOBase to provide\n" "an interface to OS files.\n" "\n" "BufferedIOBase deals with buffering on a raw byte stream (RawIOBase). Its\n" Modified: python/branches/py3k-short-float-repr/Modules/_io/bufferedio.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_io/bufferedio.c (original) +++ python/branches/py3k-short-float-repr/Modules/_io/bufferedio.c Mon Apr 6 00:11:42 2009 @@ -204,7 +204,9 @@ isn't ready for writing. */ Py_off_t write_end; +#ifdef WITH_THREAD PyThread_type_lock lock; +#endif Py_ssize_t buffer_size; Py_ssize_t buffer_mask; @@ -239,6 +241,7 @@ /* These macros protect the BufferedObject against concurrent operations. */ +#ifdef WITH_THREAD #define ENTER_BUFFERED(self) \ Py_BEGIN_ALLOW_THREADS \ PyThread_acquire_lock(self->lock, 1); \ @@ -246,6 +249,10 @@ #define LEAVE_BUFFERED(self) \ PyThread_release_lock(self->lock); +#else +#define ENTER_BUFFERED(self) +#define LEAVE_BUFFERED(self) +#endif #define CHECK_INITIALIZED(self) \ if (self->ok <= 0) { \ @@ -305,10 +312,12 @@ PyMem_Free(self->buffer); self->buffer = NULL; } +#ifdef WITH_THREAD if (self->lock) { PyThread_free_lock(self->lock); self->lock = NULL; } +#endif Py_CLEAR(self->dict); Py_TYPE(self)->tp_free((PyObject *)self); } @@ -565,11 +574,13 @@ PyErr_NoMemory(); return -1; } +#ifdef WITH_THREAD self->lock = PyThread_allocate_lock(); if (self->lock == NULL) { PyErr_SetString(PyExc_RuntimeError, "can't allocate read lock"); return -1; } +#endif /* Find out whether buffer_size is a power of 2 */ /* XXX is this optimization useful? */ for (n = self->buffer_size - 1; n & 1; n >>= 1) Modified: python/branches/py3k-short-float-repr/Modules/_multiprocessing/connection.h ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_multiprocessing/connection.h (original) +++ python/branches/py3k-short-float-repr/Modules/_multiprocessing/connection.h Mon Apr 6 00:11:42 2009 @@ -139,8 +139,12 @@ res = conn_send_string(self, buffer + offset, size); PyBuffer_Release(&pbuffer); - if (res < 0) - return mp_SetError(PyExc_IOError, res); + if (res < 0) { + if (PyErr_Occurred()) + return NULL; + else + return mp_SetError(PyExc_IOError, res); + } Py_RETURN_NONE; } Modified: python/branches/py3k-short-float-repr/Modules/_multiprocessing/multiprocessing.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_multiprocessing/multiprocessing.c (original) +++ python/branches/py3k-short-float-repr/Modules/_multiprocessing/multiprocessing.c Mon Apr 6 00:11:42 2009 @@ -8,6 +8,12 @@ #include "multiprocessing.h" +#ifdef SCM_RIGHTS + #define HAVE_FD_TRANSFER 1 +#else + #define HAVE_FD_TRANSFER 0 +#endif + PyObject *create_win32_namespace(void); PyObject *pickle_dumps, *pickle_loads, *pickle_protocol; @@ -257,7 +263,7 @@ Py_INCREF(&ConnectionType); PyModule_AddObject(module, "Connection", (PyObject*)&ConnectionType); -#if defined(MS_WINDOWS) || HAVE_SEM_OPEN +#if defined(MS_WINDOWS) || defined(HAVE_SEM_OPEN) /* Add SemLock type to module */ if (PyType_Ready(&SemLockType) < 0) return NULL; Modified: python/branches/py3k-short-float-repr/Modules/_multiprocessing/multiprocessing.h ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_multiprocessing/multiprocessing.h (original) +++ python/branches/py3k-short-float-repr/Modules/_multiprocessing/multiprocessing.h Mon Apr 6 00:11:42 2009 @@ -27,7 +27,7 @@ # include # include # include /* htonl() and ntohl() */ -# if HAVE_SEM_OPEN +# ifdef HAVE_SEM_OPEN # include typedef sem_t *SEM_HANDLE; # endif @@ -45,13 +45,18 @@ * Issue 3110 - Solaris does not define SEM_VALUE_MAX */ #ifndef SEM_VALUE_MAX -# ifdef _SEM_VALUE_MAX -# define SEM_VALUE_MAX _SEM_VALUE_MAX -# else -# define SEM_VALUE_MAX INT_MAX -# endif + #if defined(HAVE_SYSCONF) && defined(_SC_SEM_VALUE_MAX) + # define SEM_VALUE_MAX sysconf(_SC_SEM_VALUE_MAX) + #elif defined(_SEM_VALUE_MAX) + # define SEM_VALUE_MAX _SEM_VALUE_MAX + #elif definef(_POSIX_SEM_VALUE_MAX) + # define SEM_VALUE_MAX _POSIX_SEM_VALUE_MAX + #else + # define SEM_VALUE_MAX INT_MAX + #endif #endif + /* * Make sure Py_ssize_t available */ Modified: python/branches/py3k-short-float-repr/Modules/_multiprocessing/pipe_connection.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_multiprocessing/pipe_connection.c (original) +++ python/branches/py3k-short-float-repr/Modules/_multiprocessing/pipe_connection.c Mon Apr 6 00:11:42 2009 @@ -23,6 +23,12 @@ Py_BEGIN_ALLOW_THREADS ret = WriteFile(conn->handle, string, length, &amount_written, NULL); Py_END_ALLOW_THREADS + + if (ret == 0 && GetLastError() == ERROR_NO_SYSTEM_RESOURCES) { + PyErr_Format(PyExc_ValueError, "Cannnot send %" PY_FORMAT_SIZE_T "d bytes over connection", length); + return MP_STANDARD_ERROR; + } + return ret ? MP_SUCCESS : MP_STANDARD_ERROR; } Modified: python/branches/py3k-short-float-repr/Modules/_multiprocessing/semaphore.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_multiprocessing/semaphore.c (original) +++ python/branches/py3k-short-float-repr/Modules/_multiprocessing/semaphore.c Mon Apr 6 00:11:42 2009 @@ -197,11 +197,11 @@ #define SEM_GETVALUE(sem, pval) sem_getvalue(sem, pval) #define SEM_UNLINK(name) sem_unlink(name) -#if HAVE_BROKEN_SEM_UNLINK +#ifndef HAVE_SEM_UNLINK # define sem_unlink(name) 0 #endif -#if !HAVE_SEM_TIMEDWAIT +#ifndef HAVE_SEM_TIMEDWAIT # define sem_timedwait(sem,deadline) sem_timedwait_save(sem,deadline,_save) int @@ -348,7 +348,7 @@ } assert(self->count == 1); } else { -#if HAVE_BROKEN_SEM_GETVALUE +#ifdef HAVE_BROKEN_SEM_GETVALUE /* We will only check properly the maxvalue == 1 case */ if (self->maxvalue == 1) { /* make sure that already locked */ @@ -494,7 +494,7 @@ static PyObject * semlock_getvalue(SemLockObject *self) { -#if HAVE_BROKEN_SEM_GETVALUE +#ifdef HAVE_BROKEN_SEM_GETVALUE PyErr_SetNone(PyExc_NotImplementedError); return NULL; #else @@ -512,7 +512,7 @@ static PyObject * semlock_iszero(SemLockObject *self) { -#if HAVE_BROKEN_SEM_GETVALUE +#ifdef HAVE_BROKEN_SEM_GETVALUE if (sem_trywait(self->handle) < 0) { if (errno == EAGAIN) Py_RETURN_TRUE; Modified: python/branches/py3k-short-float-repr/Modules/_sqlite/connection.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_sqlite/connection.c (original) +++ python/branches/py3k-short-float-repr/Modules/_sqlite/connection.c Mon Apr 6 00:11:42 2009 @@ -124,8 +124,9 @@ self->detect_types = detect_types; self->timeout = timeout; (void)sqlite3_busy_timeout(self->db, (int)(timeout*1000)); - +#ifdef WITH_THREAD self->thread_ident = PyThread_get_thread_ident(); +#endif self->check_same_thread = check_same_thread; self->function_pinboard = PyDict_New(); @@ -510,9 +511,11 @@ PyObject* py_func; PyObject* py_retval = NULL; +#ifdef WITH_THREAD PyGILState_STATE threadstate; threadstate = PyGILState_Ensure(); +#endif py_func = (PyObject*)sqlite3_user_data(context); @@ -534,7 +537,9 @@ _sqlite3_result_error(context, "user-defined function raised exception", -1); } +#ifdef WITH_THREAD PyGILState_Release(threadstate); +#endif } static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_value** params) @@ -545,9 +550,11 @@ PyObject** aggregate_instance; PyObject* stepmethod = NULL; +#ifdef WITH_THREAD PyGILState_STATE threadstate; threadstate = PyGILState_Ensure(); +#endif aggregate_class = (PyObject*)sqlite3_user_data(context); @@ -594,7 +601,9 @@ Py_XDECREF(stepmethod); Py_XDECREF(function_result); +#ifdef WITH_THREAD PyGILState_Release(threadstate); +#endif } void _pysqlite_final_callback(sqlite3_context* context) @@ -603,9 +612,11 @@ PyObject** aggregate_instance; PyObject* aggregate_class; +#ifdef WITH_THREAD PyGILState_STATE threadstate; threadstate = PyGILState_Ensure(); +#endif aggregate_class = (PyObject*)sqlite3_user_data(context); @@ -633,7 +644,9 @@ Py_XDECREF(*aggregate_instance); Py_XDECREF(function_result); +#ifdef WITH_THREAD PyGILState_Release(threadstate); +#endif } void _pysqlite_drop_unused_statement_references(pysqlite_Connection* self) @@ -728,9 +741,11 @@ { PyObject *ret; int rc; +#ifdef WITH_THREAD PyGILState_STATE gilstate; gilstate = PyGILState_Ensure(); +#endif ret = PyObject_CallFunction((PyObject*)user_arg, "issss", action, arg1, arg2, dbname, access_attempt_source); if (!ret) { @@ -750,7 +765,9 @@ Py_DECREF(ret); } +#ifdef WITH_THREAD PyGILState_Release(gilstate); +#endif return rc; } @@ -758,9 +775,11 @@ { int rc; PyObject *ret; +#ifdef WITH_THREAD PyGILState_STATE gilstate; gilstate = PyGILState_Ensure(); +#endif ret = PyObject_CallFunction((PyObject*)user_arg, ""); if (!ret) { @@ -777,7 +796,9 @@ Py_DECREF(ret); } +#ifdef WITH_THREAD PyGILState_Release(gilstate); +#endif return rc; } @@ -832,6 +853,7 @@ int pysqlite_check_thread(pysqlite_Connection* self) { +#ifdef WITH_THREAD if (self->check_same_thread) { if (PyThread_get_thread_ident() != self->thread_ident) { PyErr_Format(pysqlite_ProgrammingError, @@ -842,7 +864,7 @@ } } - +#endif return 1; } @@ -1067,12 +1089,14 @@ PyObject* callback = (PyObject*)context; PyObject* string1 = 0; PyObject* string2 = 0; +#ifdef WITH_THREAD PyGILState_STATE gilstate; - +#endif PyObject* retval = NULL; int result = 0; - +#ifdef WITH_THREAD gilstate = PyGILState_Ensure(); +#endif if (PyErr_Occurred()) { goto finally; @@ -1101,9 +1125,9 @@ Py_XDECREF(string1); Py_XDECREF(string2); Py_XDECREF(retval); - +#ifdef WITH_THREAD PyGILState_Release(gilstate); - +#endif return result; } Modified: python/branches/py3k-short-float-repr/Modules/_sqlite/module.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_sqlite/module.c (original) +++ python/branches/py3k-short-float-repr/Modules/_sqlite/module.c Mon Apr 6 00:11:42 2009 @@ -459,7 +459,9 @@ * threads have already been initialized. * (see pybsddb-users mailing list post on 2002-08-07) */ +#ifdef WITH_THREAD PyEval_InitThreads(); +#endif error: if (PyErr_Occurred()) Modified: python/branches/py3k-short-float-repr/Modules/_tkinter.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_tkinter.c (original) +++ python/branches/py3k-short-float-repr/Modules/_tkinter.c Mon Apr 6 00:11:42 2009 @@ -281,7 +281,7 @@ static PyObject *trbInCmd; #ifdef TKINTER_PROTECT_LOADTK -static int tk_load_failed; +static int tk_load_failed = 0; #endif Modified: python/branches/py3k-short-float-repr/Objects/genobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/genobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/genobject.c Mon Apr 6 00:11:42 2009 @@ -304,7 +304,7 @@ "Return the name of the generator's associated code object."); static PyGetSetDef gen_getsetlist[] = { - {"__name__", (getter)gen_get_name, NULL, NULL, gen__name__doc__}, + {"__name__", (getter)gen_get_name, NULL, gen__name__doc__}, {NULL} }; Modified: python/branches/py3k-short-float-repr/Objects/object.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/object.c (original) +++ python/branches/py3k-short-float-repr/Objects/object.c Mon Apr 6 00:11:42 2009 @@ -349,11 +349,17 @@ if (op == NULL) fprintf(stderr, "NULL\n"); else { +#ifdef WITH_THREAD PyGILState_STATE gil; +#endif fprintf(stderr, "object : "); +#ifdef WITH_THREAD gil = PyGILState_Ensure(); +#endif (void)PyObject_Print(op, stderr, 0); +#ifdef WITH_THREAD PyGILState_Release(gil); +#endif /* XXX(twouters) cast refcount to long until %zd is universally available */ fprintf(stderr, "\n" Modified: python/branches/py3k-short-float-repr/configure ============================================================================== --- python/branches/py3k-short-float-repr/configure (original) +++ python/branches/py3k-short-float-repr/configure Mon Apr 6 00:11:42 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 70732 . +# From configure.in Revision: 71261 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.1. # @@ -1804,6 +1804,11 @@ +if test "$prefix" != "/"; then + prefix=`echo "$prefix" | sed -e 's/\/$//g'` +fi + + @@ -16329,6 +16334,10 @@ + + + + for ac_func in alarm setitimer getitimer bind_textdomain_codeset chown \ clock confstr ctermid execv fchmod fchown fork fpathconf ftime ftruncate \ gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \ @@ -16336,7 +16345,8 @@ kill killpg lchmod lchown lstat mkfifo mknod mktime \ mremap nice pathconf pause plock poll pthread_init \ putenv readlink realpath \ - select setegid seteuid setgid \ + select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ + setgid \ setlocale setregid setreuid setsid setpgid setpgrp setuid setvbuf snprintf \ sigaction siginterrupt sigrelse strftime strlcpy \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ @@ -21757,6 +21767,86 @@ fi +# Multiprocessing check for broken sem_getvalue +{ echo "$as_me:$LINENO: checking for broken sem_getvalue" >&5 +echo $ECHO_N "checking for broken sem_getvalue... $ECHO_C" >&6; } +if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +#include +#include +#include + +int main(void){ + sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + int count; + int res; + if(a==SEM_FAILED){ + perror("sem_open"); + return 1; + + } + res = sem_getvalue(a, &count); + sem_close(a); + return res==-1 ? 1 : 0; +} + + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_BROKEN_SEM_GETVALUE 1 +_ACEOF + + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + # On FreeBSD 6.2, it appears that tanh(-0.) returns 0. instead of # -0. on some architectures. Modified: python/branches/py3k-short-float-repr/configure.in ============================================================================== --- python/branches/py3k-short-float-repr/configure.in (original) +++ python/branches/py3k-short-float-repr/configure.in Mon Apr 6 00:11:42 2009 @@ -12,6 +12,15 @@ AC_CONFIG_SRCDIR([Include/object.h]) AC_CONFIG_HEADER(pyconfig.h) +dnl Ensure that if prefix is specified, it does not end in a slash. If +dnl it does, we get path names containing '//' which is both ugly and +dnl can cause trouble. + +dnl Last slash shouldn't be stripped if prefix=/ +if test "$prefix" != "/"; then + prefix=`echo "$prefix" | sed -e 's/\/$//g'` +fi + dnl This is for stuff that absolutely must end up in pyconfig.h. dnl Please use pyport.h instead, if possible. AH_TOP([ @@ -2405,7 +2414,8 @@ kill killpg lchmod lchown lstat mkfifo mknod mktime \ mremap nice pathconf pause plock poll pthread_init \ putenv readlink realpath \ - select setegid seteuid setgid \ + select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ + setgid \ setlocale setregid setreuid setsid setpgid setpgrp setuid setvbuf snprintf \ sigaction siginterrupt sigrelse strftime strlcpy \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ @@ -3125,6 +3135,33 @@ [Define if arithmetic is subject to x87-style double rounding issue]) fi +# Multiprocessing check for broken sem_getvalue +AC_MSG_CHECKING(for broken sem_getvalue) +AC_TRY_RUN([ +#include +#include +#include +#include +#include + +int main(void){ + sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + int count; + int res; + if(a==SEM_FAILED){ + perror("sem_open"); + return 1; + + } + res = sem_getvalue(a, &count); + sem_close(a); + return res==-1 ? 1 : 0; +} +] +,AC_MSG_RESULT(no), + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BROKEN_SEM_GETVALUE, 1, define to 1 if your sem_getvalue is broken.) +) # On FreeBSD 6.2, it appears that tanh(-0.) returns 0. instead of # -0. on some architectures. Modified: python/branches/py3k-short-float-repr/pyconfig.h.in ============================================================================== --- python/branches/py3k-short-float-repr/pyconfig.h.in (original) +++ python/branches/py3k-short-float-repr/pyconfig.h.in Mon Apr 6 00:11:42 2009 @@ -74,6 +74,9 @@ /* Define if pthread_sigmask() does not work on your system. */ #undef HAVE_BROKEN_PTHREAD_SIGMASK +/* define to 1 if your sem_getvalue is broken. */ +#undef HAVE_BROKEN_SEM_GETVALUE + /* Define this if you have the type _Bool. */ #undef HAVE_C99_BOOL @@ -505,6 +508,18 @@ /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT +/* Define to 1 if you have the `sem_getvalue' function. */ +#undef HAVE_SEM_GETVALUE + +/* Define to 1 if you have the `sem_open' function. */ +#undef HAVE_SEM_OPEN + +/* Define to 1 if you have the `sem_timedwait' function. */ +#undef HAVE_SEM_TIMEDWAIT + +/* Define to 1 if you have the `sem_unlink' function. */ +#undef HAVE_SEM_UNLINK + /* Define to 1 if you have the `setegid' function. */ #undef HAVE_SETEGID Modified: python/branches/py3k-short-float-repr/setup.py ============================================================================== --- python/branches/py3k-short-float-repr/setup.py (original) +++ python/branches/py3k-short-float-repr/setup.py Mon Apr 6 00:11:42 2009 @@ -988,56 +988,29 @@ libraries = ['ws2_32'] elif platform == 'darwin': # Mac OSX - macros = dict( - HAVE_SEM_OPEN=1, - HAVE_SEM_TIMEDWAIT=0, - HAVE_FD_TRANSFER=1, - HAVE_BROKEN_SEM_GETVALUE=1 - ) + macros = dict() libraries = [] elif platform == 'cygwin': # Cygwin - macros = dict( - HAVE_SEM_OPEN=1, - HAVE_SEM_TIMEDWAIT=1, - HAVE_FD_TRANSFER=0, - HAVE_BROKEN_SEM_UNLINK=1 - ) + macros = dict() libraries = [] elif platform in ('freebsd4', 'freebsd5', 'freebsd6', 'freebsd7', 'freebsd8'): # FreeBSD's P1003.1b semaphore support is very experimental # and has many known problems. (as of June 2008) - macros = dict( # FreeBSD - HAVE_SEM_OPEN=0, - HAVE_SEM_TIMEDWAIT=0, - HAVE_FD_TRANSFER=1, - ) + macros = dict() libraries = [] elif platform.startswith('openbsd'): - macros = dict( # OpenBSD - HAVE_SEM_OPEN=0, # Not implemented - HAVE_SEM_TIMEDWAIT=0, - HAVE_FD_TRANSFER=1, - ) + macros = dict() libraries = [] elif platform.startswith('netbsd'): - macros = dict( # at least NetBSD 5 - HAVE_SEM_OPEN=1, - HAVE_SEM_TIMEDWAIT=0, - HAVE_FD_TRANSFER=1, - HAVE_BROKEN_SEM_GETVALUE=1 - ) + macros = dict() libraries = [] else: # Linux and other unices - macros = dict( - HAVE_SEM_OPEN=1, - HAVE_SEM_TIMEDWAIT=1, - HAVE_FD_TRANSFER=1 - ) + macros = dict() libraries = ['rt'] if platform == 'win32': @@ -1052,8 +1025,7 @@ multiprocessing_srcs = [ '_multiprocessing/multiprocessing.c', '_multiprocessing/socket_connection.c' ] - - if macros.get('HAVE_SEM_OPEN', False): + if sysconfig.get_config_var('HAVE_SEM_OPEN'): multiprocessing_srcs.append('_multiprocessing/semaphore.c') if sysconfig.get_config_var('WITH_THREAD'): From python-checkins at python.org Mon Apr 6 00:12:56 2009 From: python-checkins at python.org (matthias.klose) Date: Mon, 6 Apr 2009 00:12:56 +0200 (CEST) Subject: [Python-checkins] r71288 - python/branches/release26-maint/Misc/NEWS Message-ID: <20090405221256.754B41E401A@bag.python.org> Author: matthias.klose Date: Mon Apr 6 00:12:56 2009 New Revision: 71288 Log: Misc/NEWS: Move all news items checked in after the 2.6.1 release to the 2.6.2 section. Modified: python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Mon Apr 6 00:12:56 2009 @@ -314,65 +314,6 @@ - Issue #2703: SimpleXMLRPCDispatcher.__init__: Provide default values for new arguments introduced in 2.5. -Extension Modules ------------------ - -- Issue #1040026: Fix os.times result on systems where HZ is incorrect. - -Build ------ - -- Link the shared python library with $(MODLIBS). - - -What's New in Python 2.6.1 -========================== - -*Release date: 04-Dec-2008* - -Core and Builtins ------------------ - -- Issue #3996: On Windows, the PyOS_CheckStack function would cause the - interpreter to abort ("Fatal Python error: Could not reset the stack!") - instead of throwing a MemoryError. - -- Issue #4367: Python would segfault during compiling when the unicodedata - module couldn't be imported and \N escapes were present. - -- Issue #4348: Some bytearray methods returned that didn't cause any change to - the bytearray, returned the same bytearray instead of a copy. - -- Issue #4317: Fixed a crash in the imageop.rgb2rgb8() function. - -- Issue #4230: If ``__getattr__`` is a descriptor, it now functions correctly. - -- Issue #4048: The parser module now correctly validates relative imports. - -- Issue #4225: ``from __future__ import unicode_literals`` didn't work in an - exec statement. - -- Issue #4176: Fixed a crash when pickling an object which ``__reduce__`` - method does not return iterators for the 4th and 5th items. - -- Issue #4209: Enabling unicode_literals and the print_function in the same - __future__ import didn't work. - -- On windows, os.chdir given unicode was not working if GetCurrentDirectoryW - returned a path longer than MAX_PATH. (But It's doubtful this code path is - really executed because I cannot move to such directory on win2k) - -- Issue #4069: When set.remove(element) is used with a set element, the element - is temporarily replaced with an equivalent frozenset. But the eventual - KeyError would always report the empty frozenset([]) as the missing key. Now - it correctly refers to the initial element. - -- Fixed C99 style comments in several files. Python is now C89 compatible - again. - -Library -------- - - Issue #1885: distutils. When running sdist with --formats=tar,gztar the tar file was overriden by the gztar one. @@ -439,30 +380,6 @@ support unusual filenames (such as those containing semi-colons) in Content-Disposition headers. -- Issue #3741: DISTUTILS_USE_SDK set causes msvc9compiler.py to raise an - exception. - -- Issue #4363: The uuid.uuid1() and uuid.uuid4() functions now work even if - the ctypes module is not present. - -- Issue #4116: Resolve member name conflict in ScrolledCanvas.__init__. - -- Issue #3774: Fixed an error when create a Tkinter menu item without command - and then remove it. - -- Fixed a modulefinder crash on certain relative imports. - -- Issue #4150: Pdb's "up" command now works for generator frames in post-mortem - debugging. - -- Issue #4092: Return ArgInfo as promised in the documentation from - inspect.getargvalues. - -- Issue #3935: Properly support list subclasses in bisect's C implementation. - -- Issue #4014: Don't claim that Python has an Alpha release status, in addition - to claiming it is Mature. - - Issue #4730: Fixed the cPickle module to handle correctly astral characters when protocol 0 is used. @@ -479,9 +396,32 @@ - Issue #4677: add two list comprehension tests to pybench. +Extension Modules +----------------- + +- Issue #4301: Patch the logging module to add processName support, remove + _check_logger_class from multiprocessing. + +- Issue #1040026: Fix os.times result on systems where HZ is incorrect. + +- Issue #4397: Fix occasional test_socket failure on OS X. + +- Issue #4279: Fix build of parsermodule under Cygwin. + +- Issue #4051: Prevent conflict of UNICODE macros in cPickle. + +- Issue #4228: Pack negative values the same way as 2.4 in struct's L format. + +- Issue #1040026: Fix os.times result on systems where HZ is incorrect. + +- Issues #3167, #3682: Fix test_math failures for log, log10 on Solaris, + OpenBSD. + Build ----- +- Link the shared python library with $(MODLIBS). + - Issue #5134: Silence compiler warnings when compiling sqlite with VC++. - Issue #4494: Fix build with Py_NO_ENABLE_SHARED on Windows. @@ -496,17 +436,6 @@ - Issue #4289: Remove Cancel button from AdvancedDlg. -- Issue #1656675: Register a drop handler for .py* files on Windows. - -- Issue #4120: Exclude manifest from extension modules in VS2008. - -- Issue #4091: Install pythonxy.dll in system32 again. - -- Issue #4018: Disable "for me" installations on Vista. - -- Issue #3758: Add ``patchcheck`` build target to .PHONY. - -- Issue #4204: Fixed module build errors on FreeBSD 4. C-API ----- @@ -516,40 +445,117 @@ - Issue #3632: from the gdb debugger, the 'pyo' macro can now be called when the GIL is released, or owned by another thread. -- Issue #4122: On Windows, fix a compilation error when using the - Py_UNICODE_ISSPACE macro in an extension module. +Tests +----- -Extension Modules +- Issue #5635: Fix running test_sys with tracing enabled. + +- regrtest no longer treats ImportError as equivalent to SkipTest. Imports + that should cause a test to be skipped are now done using import_module + from test support, which does the conversion. + +- Issue #5083: New 'gui' resource for regrtest. + + +What's New in Python 2.6.1 +========================== + +*Release date: 04-Dec-2008* + +Core and Builtins ----------------- -- Issue #4397: Fix occasional test_socket failure on OS X. +- Issue #3996: On Windows, the PyOS_CheckStack function would cause the + interpreter to abort ("Fatal Python error: Could not reset the stack!") + instead of throwing a MemoryError. -- Issue #4279: Fix build of parsermodule under Cygwin. +- Issue #4367: Python would segfault during compiling when the unicodedata + module couldn't be imported and \N escapes were present. -- Issue #4051: Prevent conflict of UNICODE macros in cPickle. +- Issue #4348: Some bytearray methods returned that didn't cause any change to + the bytearray, returned the same bytearray instead of a copy. -- Issue #4228: Pack negative values the same way as 2.4 in struct's L format. +- Issue #4317: Fixed a crash in the imageop.rgb2rgb8() function. -- Issue #1040026: Fix os.times result on systems where HZ is incorrect. +- Issue #4230: If ``__getattr__`` is a descriptor, it now functions correctly. -- Issues #3167, #3682: Fix test_math failures for log, log10 on Solaris, - OpenBSD. +- Issue #4048: The parser module now correctly validates relative imports. -- Issue #4365: Add crtassem.h constants to the msvcrt module. +- Issue #4225: ``from __future__ import unicode_literals`` didn't work in an + exec statement. -- Issue #4396: The parser module now correctly validates the with statement. +- Issue #4176: Fixed a crash when pickling an object which ``__reduce__`` + method does not return iterators for the 4th and 5th items. +- Issue #4209: Enabling unicode_literals and the print_function in the same + __future__ import didn't work. -Tests +- On windows, os.chdir given unicode was not working if GetCurrentDirectoryW + returned a path longer than MAX_PATH. (But It's doubtful this code path is + really executed because I cannot move to such directory on win2k) + +- Issue #4069: When set.remove(element) is used with a set element, the element + is temporarily replaced with an equivalent frozenset. But the eventual + KeyError would always report the empty frozenset([]) as the missing key. Now + it correctly refers to the initial element. + +- Fixed C99 style comments in several files. Python is now C89 compatible + again. + +Library +------- + +- Issue #3741: DISTUTILS_USE_SDK set causes msvc9compiler.py to raise an + exception. + +- Issue #4363: The uuid.uuid1() and uuid.uuid4() functions now work even if + the ctypes module is not present. + +- Issue #4116: Resolve member name conflict in ScrolledCanvas.__init__. + +- Issue #3774: Fixed an error when create a Tkinter menu item without command + and then remove it. + +- Fixed a modulefinder crash on certain relative imports. + +- Issue #4150: Pdb's "up" command now works for generator frames in post-mortem + debugging. + +- Issue #4092: Return ArgInfo as promised in the documentation from + inspect.getargvalues. + +- Issue #3935: Properly support list subclasses in bisect's C implementation. + +- Issue #4014: Don't claim that Python has an Alpha release status, in addition + to claiming it is Mature. + +Build ----- -- Issue #5635: Fix running test_sys with tracing enabled. +- Issue #1656675: Register a drop handler for .py* files on Windows. -- regrtest no longer treats ImportError as equivalent to SkipTest. Imports - that should cause a test to be skipped are now done using import_module - from test support, which does the conversion. +- Issue #4120: Exclude manifest from extension modules in VS2008. -- Issue #5083: New 'gui' resource for regrtest. +- Issue #4091: Install pythonxy.dll in system32 again. + +- Issue #4018: Disable "for me" installations on Vista. + +- Issue #3758: Add ``patchcheck`` build target to .PHONY. + +- Issue #4204: Fixed module build errors on FreeBSD 4. + +C-API +----- + +- Issue #4122: On Windows, fix a compilation error when using the + Py_UNICODE_ISSPACE macro in an extension module. + +Extension Modules +----------------- + +- Issue #4365: Add crtassem.h constants to the msvcrt module. + +- Issue #4396: The parser module now correctly validates the with statement. What's New in Python 2.6 final @@ -764,9 +770,6 @@ Extension Modules ----------------- -- Issue #4301: Patch the logging module to add processName support, remove - _check_logger_class from multiprocessing. - - Issue #2975: When compiling several extension modules with Visual Studio 2008 from the same python interpreter, some environment variables would grow without limit. From python-checkins at python.org Mon Apr 6 00:20:44 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 6 Apr 2009 00:20:44 +0200 (CEST) Subject: [Python-checkins] r71289 - in python/branches/py3k/Doc/library: binhex.rst bisect.rst builtins.rst bz2.rst calendar.rst cgi.rst cgitb.rst chunk.rst cmath.rst cmd.rst code.rst codecs.rst Message-ID: <20090405222044.708EA1E401A@bag.python.org> Author: georg.brandl Date: Mon Apr 6 00:20:44 2009 New Revision: 71289 Log: Update signature style of optional arguments, part two. Modified: python/branches/py3k/Doc/library/binhex.rst python/branches/py3k/Doc/library/bisect.rst python/branches/py3k/Doc/library/builtins.rst python/branches/py3k/Doc/library/bz2.rst python/branches/py3k/Doc/library/calendar.rst python/branches/py3k/Doc/library/cgi.rst python/branches/py3k/Doc/library/cgitb.rst python/branches/py3k/Doc/library/chunk.rst python/branches/py3k/Doc/library/cmath.rst python/branches/py3k/Doc/library/cmd.rst python/branches/py3k/Doc/library/code.rst python/branches/py3k/Doc/library/codecs.rst Modified: python/branches/py3k/Doc/library/binhex.rst ============================================================================== --- python/branches/py3k/Doc/library/binhex.rst (original) +++ python/branches/py3k/Doc/library/binhex.rst Mon Apr 6 00:20:44 2009 @@ -1,4 +1,3 @@ - :mod:`binhex` --- Encode and decode binhex4 files ================================================= @@ -19,11 +18,11 @@ supporting a :meth:`write` and :meth:`close` method). -.. function:: hexbin(input[, output]) +.. function:: hexbin(input, output) Decode a binhex file *input*. *input* may be a filename or a file-like object supporting :meth:`read` and :meth:`close` methods. The resulting file is written - to a file named *output*, unless the argument is omitted in which case the + to a file named *output*, unless the argument is ``None`` in which case the output filename is read from the binhex file. The following exception is also defined: Modified: python/branches/py3k/Doc/library/bisect.rst ============================================================================== --- python/branches/py3k/Doc/library/bisect.rst (original) +++ python/branches/py3k/Doc/library/bisect.rst Mon Apr 6 00:20:44 2009 @@ -1,4 +1,3 @@ - :mod:`bisect` --- Array bisection algorithm =========================================== @@ -17,43 +16,35 @@ The following functions are provided: -.. function:: bisect_left(list, item[, lo[, hi]]) - - Locate the proper insertion point for *item* in *list* to maintain sorted order. - The parameters *lo* and *hi* may be used to specify a subset of the list which - should be considered; by default the entire list is used. If *item* is already - present in *list*, the insertion point will be before (to the left of) any - existing entries. The return value is suitable for use as the first parameter - to ``list.insert()``. This assumes that *list* is already sorted. - - -.. function:: bisect_right(list, item[, lo[, hi]]) - - Similar to :func:`bisect_left`, but returns an insertion point which comes after - (to the right of) any existing entries of *item* in *list*. - - -.. function:: bisect(...) +.. function:: bisect_left(a, x, lo=0, hi=len(a)) - Alias for :func:`bisect_right`. + Locate the proper insertion point for *x* in *a* to maintain sorted order. + The parameters *lo* and *hi* may be used to specify a subset of the list + which should be considered; by default the entire list is used. If *x* is + already present in *a*, the insertion point will be before (to the left of) + any existing entries. The return value is suitable for use as the first + parameter to ``list.insert()``. This assumes that *a* is already sorted. -.. function:: insort_left(list, item[, lo[, hi]]) +.. function:: bisect_right(a, x, lo=0, hi=len(a)) + bisect(a, x, lo=0, hi=len(a)) - Insert *item* in *list* in sorted order. This is equivalent to - ``list.insert(bisect.bisect_left(list, item, lo, hi), item)``. This assumes - that *list* is already sorted. + Similar to :func:`bisect_left`, but returns an insertion point which comes + after (to the right of) any existing entries of *x* in *a*. -.. function:: insort_right(list, item[, lo[, hi]]) +.. function:: insort_left(a, x, lo=0, hi=len(a)) - Similar to :func:`insort_left`, but inserting *item* in *list* after any - existing entries of *item*. + Insert *x* in *a* in sorted order. This is equivalent to + ``a.insert(bisect.bisect_left(a, x, lo, hi), x)``. This assumes that *a* is + already sorted. -.. function:: insort(...) +.. function:: insort_right(a, x, lo=0, hi=len(a)) + insort(a, x, lo=0, hi=len(a)) - Alias for :func:`insort_right`. + Similar to :func:`insort_left`, but inserting *x* in *a* after any existing + entries of *x*. Examples Modified: python/branches/py3k/Doc/library/builtins.rst ============================================================================== --- python/branches/py3k/Doc/library/builtins.rst (original) +++ python/branches/py3k/Doc/library/builtins.rst Mon Apr 6 00:20:44 2009 @@ -1,4 +1,3 @@ - :mod:`builtins` --- Built-in objects ==================================== Modified: python/branches/py3k/Doc/library/bz2.rst ============================================================================== --- python/branches/py3k/Doc/library/bz2.rst (original) +++ python/branches/py3k/Doc/library/bz2.rst Mon Apr 6 00:20:44 2009 @@ -1,9 +1,9 @@ - :mod:`bz2` --- Compression compatible with :program:`bzip2` =========================================================== .. module:: bz2 - :synopsis: Interface to compression and decompression routines compatible with bzip2. + :synopsis: Interface to compression and decompression routines + compatible with bzip2. .. moduleauthor:: Gustavo Niemeyer .. sectionauthor:: Gustavo Niemeyer @@ -42,7 +42,7 @@ Handling of compressed files is offered by the :class:`BZ2File` class. -.. class:: BZ2File(filename[, mode[, buffering[, compresslevel]]]) +.. class:: BZ2File(filename, mode='r', buffering=0, compresslevel=9) Open a bz2 file. Mode can be either ``'r'`` or ``'w'``, for reading (default) or writing. When opened for writing, the file will be created if it doesn't @@ -129,14 +129,13 @@ :class:`BZ2Compressor` and :class:`BZ2Decompressor`. -.. class:: BZ2Compressor([compresslevel]) +.. class:: BZ2Compressor(compresslevel=9) Create a new compressor object. This object may be used to compress data sequentially. If you want to compress data in one shot, use the :func:`compress` function instead. The *compresslevel* parameter, if given, must be a number between ``1`` and ``9``; the default is ``9``. - .. method:: compress(data) Provide more data to the compressor object. It will return chunks of @@ -157,7 +156,6 @@ sequentially. If you want to decompress data in one shot, use the :func:`decompress` function instead. - .. method:: decompress(data) Provide more data to the decompressor object. It will return chunks of @@ -174,7 +172,7 @@ and :func:`decompress` functions. -.. function:: compress(data[, compresslevel]) +.. function:: compress(data, compresslevel=9) Compress *data* in one shot. If you want to compress data sequentially, use an instance of :class:`BZ2Compressor` instead. The *compresslevel* parameter, Modified: python/branches/py3k/Doc/library/calendar.rst ============================================================================== --- python/branches/py3k/Doc/library/calendar.rst (original) +++ python/branches/py3k/Doc/library/calendar.rst Mon Apr 6 00:20:44 2009 @@ -1,10 +1,9 @@ - :mod:`calendar` --- General calendar-related functions ====================================================== .. module:: calendar - :synopsis: Functions for working with calendars, including some emulation of the Unix cal - program. + :synopsis: Functions for working with calendars, including some emulation + of the Unix cal program. .. sectionauthor:: Drew Csillag @@ -23,7 +22,7 @@ it's the base calendar for all computations. -.. class:: Calendar([firstweekday]) +.. class:: Calendar(firstweekday=0) Creates a :class:`Calendar` object. *firstweekday* is an integer specifying the first day of the week. ``0`` is Monday (the default), ``6`` is Sunday. @@ -82,7 +81,7 @@ weeks. Weeks are lists of seven day numbers. - .. method:: yeardatescalendar(year[, width]) + .. method:: yeardatescalendar(year, width=3) Return the data for the specified year ready for formatting. The return value is a list of month rows. Each month row contains up to *width* @@ -90,28 +89,27 @@ each week contains 1--7 days. Days are :class:`datetime.date` objects. - .. method:: yeardays2calendar(year[, width]) + .. method:: yeardays2calendar(year, width=3) Return the data for the specified year ready for formatting (similar to :meth:`yeardatescalendar`). Entries in the week lists are tuples of day numbers and weekday numbers. Day numbers outside this month are zero. - .. method:: yeardayscalendar(year[, width]) + .. method:: yeardayscalendar(year, width=3) Return the data for the specified year ready for formatting (similar to :meth:`yeardatescalendar`). Entries in the week lists are day numbers. Day numbers outside this month are zero. -.. class:: TextCalendar([firstweekday]) +.. class:: TextCalendar(firstweekday=0) This class can be used to generate plain text calendars. - :class:`TextCalendar` instances have the following methods: - .. method:: formatmonth(theyear, themonth[, w[, l]]) + .. method:: formatmonth(theyear, themonth, w=0, l=0) Return a month's calendar in a multi-line string. If *w* is provided, it specifies the width of the date columns, which are centered. If *l* is @@ -120,12 +118,12 @@ :meth:`setfirstweekday` method. - .. method:: prmonth(theyear, themonth[, w[, l]]) + .. method:: prmonth(theyear, themonth, w=0, l=0) Print a month's calendar as returned by :meth:`formatmonth`. - .. method:: formatyear(theyear, themonth[, w[, l[, c[, m]]]]) + .. method:: formatyear(theyear, themonth, w=2, l=1, c=6, m=3) Return a *m*-column calendar for an entire year as a multi-line string. Optional parameters *w*, *l*, and *c* are for date column width, lines per @@ -135,32 +133,32 @@ can be generated is platform-dependent. - .. method:: pryear(theyear[, w[, l[, c[, m]]]]) + .. method:: pryear(theyear, w=2, l=1, c=6, m=3) Print the calendar for an entire year as returned by :meth:`formatyear`. -.. class:: HTMLCalendar([firstweekday]) +.. class:: HTMLCalendar(firstweekday=0) This class can be used to generate HTML calendars. :class:`HTMLCalendar` instances have the following methods: - .. method:: formatmonth(theyear, themonth[, withyear]) + .. method:: formatmonth(theyear, themonth, withyear=True) Return a month's calendar as an HTML table. If *withyear* is true the year will be included in the header, otherwise just the month name will be used. - .. method:: formatyear(theyear, themonth[, width]) + .. method:: formatyear(theyear, themonth, width=3) Return a year's calendar as an HTML table. *width* (defaulting to 3) specifies the number of months per row. - .. method:: formatyearpage(theyear[, width[, css[, encoding]]]) + .. method:: formatyearpage(theyear, width=3, css='calendar.css', encoding=None) Return a year's calendar as a complete HTML page. *width* (defaulting to 3) specifies the number of months per row. *css* is the name for the @@ -169,7 +167,7 @@ output (defaulting to the system default encoding). -.. class:: LocaleTextCalendar([firstweekday[, locale]]) +.. class:: LocaleTextCalendar(firstweekday=0, locale=None) This subclass of :class:`TextCalendar` can be passed a locale name in the constructor and will return month and weekday names in the specified @@ -177,7 +175,7 @@ weekday names will be returned as unicode. -.. class:: LocaleHTMLCalendar([firstweekday[, locale]]) +.. class:: LocaleHTMLCalendar(firstweekday=0, locale=None) This subclass of :class:`HTMLCalendar` can be passed a locale name in the constructor and will return month and weekday names in the specified @@ -241,26 +239,26 @@ unless set by :func:`setfirstweekday`. -.. function:: prmonth(theyear, themonth[, w[, l]]) +.. function:: prmonth(theyear, themonth, w=0, l=0) Prints a month's calendar as returned by :func:`month`. -.. function:: month(theyear, themonth[, w[, l]]) +.. function:: month(theyear, themonth, w=0, l=0) Returns a month's calendar in a multi-line string using the :meth:`formatmonth` of the :class:`TextCalendar` class. -.. function:: prcal(year[, w[, l[c]]]) +.. function:: prcal(year, w=0, l=0, c=6, m=3) Prints the calendar for an entire year as returned by :func:`calendar`. -.. function:: calendar(year[, w[, l[c]]]) +.. function:: calendar(year, w=2, l=1, c=6, m=3) - Returns a 3-column calendar for an entire year as a multi-line string using the - :meth:`formatyear` of the :class:`TextCalendar` class. + Returns a 3-column calendar for an entire year as a multi-line string using + the :meth:`formatyear` of the :class:`TextCalendar` class. .. function:: timegm(tuple) Modified: python/branches/py3k/Doc/library/cgi.rst ============================================================================== --- python/branches/py3k/Doc/library/cgi.rst (original) +++ python/branches/py3k/Doc/library/cgi.rst Mon Apr 6 00:20:44 2009 @@ -1,6 +1,5 @@ - -:mod:`cgi` --- Common Gateway Interface support. -================================================ +:mod:`cgi` --- Common Gateway Interface support +=============================================== .. module:: cgi :synopsis: Helpers for running Python scripts via the Common Gateway Interface. @@ -220,7 +219,7 @@ :meth:`getlist` provided by this higher level interface. -.. method:: FieldStorage.getfirst(name[, default]) +.. method:: FieldStorage.getfirst(name, default=None) This method always returns only one value associated with form field *name*. The method returns only the first value in case that more values were posted @@ -255,19 +254,19 @@ algorithms implemented in this module in other circumstances. -.. function:: parse(fp[, keep_blank_values[, strict_parsing]]) +.. function:: parse(fp=None, environ=os.environ, keep_blank_values=False, strict_parsing=False) Parse a query in the environment or from a file (the file defaults to ``sys.stdin``). The *keep_blank_values* and *strict_parsing* parameters are passed to :func:`urllib.parse.parse_qs` unchanged. -.. function:: parse_qs(qs[, keep_blank_values[, strict_parsing]]) +.. function:: parse_qs(qs, keep_blank_values=False, strict_parsing=False) This function is deprecated in this module. Use :func:`urllib.parse.parse_qs` instead. It is maintained here only for backward compatibility. -.. function:: parse_qsl(qs[, keep_blank_values[, strict_parsing]]) +.. function:: parse_qsl(qs, keep_blank_values=False, strict_parsing=False) This function is deprecated in this module. Use :func:`urllib.parse.parse_qs` instead. It is maintained here only for backward compatibility. @@ -319,7 +318,7 @@ Print a list of useful (used by CGI) environment variables in HTML. -.. function:: escape(s[, quote]) +.. function:: escape(s, quote=False) Convert the characters ``'&'``, ``'<'`` and ``'>'`` in string *s* to HTML-safe sequences. Use this if you need to display text that might contain such Modified: python/branches/py3k/Doc/library/cgitb.rst ============================================================================== --- python/branches/py3k/Doc/library/cgitb.rst (original) +++ python/branches/py3k/Doc/library/cgitb.rst Mon Apr 6 00:20:44 2009 @@ -1,4 +1,3 @@ - :mod:`cgitb` --- Traceback manager for CGI scripts ================================================== @@ -34,7 +33,7 @@ analysis. -.. function:: enable([display[, logdir[, context[, format]]]]) +.. function:: enable(display=1, logdir=None, context=5, format="html") .. index:: single: excepthook() (in module sys) @@ -51,7 +50,7 @@ value forces plain text output. The default value is ``"html"``. -.. function:: handler([info]) +.. function:: handler(info=None) This function handles an exception using the default settings (that is, show a report in the browser, but don't log to a file). This can be used when you've Modified: python/branches/py3k/Doc/library/chunk.rst ============================================================================== --- python/branches/py3k/Doc/library/chunk.rst (original) +++ python/branches/py3k/Doc/library/chunk.rst Mon Apr 6 00:20:44 2009 @@ -1,4 +1,3 @@ - :mod:`chunk` --- Read IFF chunked data ====================================== @@ -51,7 +50,7 @@ instance will fail with a :exc:`EOFError` exception. -.. class:: Chunk(file[, align, bigendian, inclheader]) +.. class:: Chunk(file, align=True, bigendian=True, inclheader=False) Class which represents a chunk. The *file* argument is expected to be a file-like object. An instance of this class is specifically allowed. The @@ -94,7 +93,7 @@ Returns ``False``. - .. method:: seek(pos[, whence]) + .. method:: seek(pos, whence=0) Set the chunk's current position. The *whence* argument is optional and defaults to ``0`` (absolute file positioning); other values are ``1`` @@ -108,7 +107,7 @@ Return the current position into the chunk. - .. method:: read([size]) + .. method:: read(size=-1) Read at most *size* bytes from the chunk (less if the read hits the end of the chunk before obtaining *size* bytes). If the *size* argument is Modified: python/branches/py3k/Doc/library/cmath.rst ============================================================================== --- python/branches/py3k/Doc/library/cmath.rst (original) +++ python/branches/py3k/Doc/library/cmath.rst Mon Apr 6 00:20:44 2009 @@ -1,4 +1,3 @@ - :mod:`cmath` --- Mathematical functions for complex numbers =========================================================== Modified: python/branches/py3k/Doc/library/cmd.rst ============================================================================== --- python/branches/py3k/Doc/library/cmd.rst (original) +++ python/branches/py3k/Doc/library/cmd.rst Mon Apr 6 00:20:44 2009 @@ -1,4 +1,3 @@ - :mod:`cmd` --- Support for line-oriented command interpreters ============================================================= @@ -13,7 +12,7 @@ interface. -.. class:: Cmd([completekey[, stdin[, stdout]]]) +.. class:: Cmd(completekey='tab', stdin=None, stdout=None) A :class:`Cmd` instance or subclass instance is a line-oriented interpreter framework. There is no good reason to instantiate :class:`Cmd` itself; rather, @@ -42,7 +41,7 @@ A :class:`Cmd` instance has the following methods: -.. method:: Cmd.cmdloop([intro]) +.. method:: Cmd.cmdloop(intro=None) Repeatedly issue a prompt, accept input, parse an initial prefix off the received input, and dispatch to action methods, passing them the remainder of Modified: python/branches/py3k/Doc/library/code.rst ============================================================================== --- python/branches/py3k/Doc/library/code.rst (original) +++ python/branches/py3k/Doc/library/code.rst Mon Apr 6 00:20:44 2009 @@ -12,7 +12,7 @@ build applications which provide an interactive interpreter prompt. -.. class:: InteractiveInterpreter([locals]) +.. class:: InteractiveInterpreter(locals=None) This class deals with parsing and interpreter state (the user's namespace); it does not deal with input buffering or prompting or input file naming (the @@ -22,14 +22,14 @@ ``'__doc__'`` set to ``None``. -.. class:: InteractiveConsole([locals[, filename]]) +.. class:: InteractiveConsole(locals=None, filename="") Closely emulate the behavior of the interactive Python interpreter. This class builds on :class:`InteractiveInterpreter` and adds prompting using the familiar ``sys.ps1`` and ``sys.ps2``, and input buffering. -.. function:: interact([banner[, readfunc[, local]]]) +.. function:: interact(banner=None, readfunc=None, local=None) Convenience function to run a read-eval-print loop. This creates a new instance of :class:`InteractiveConsole` and sets *readfunc* to be used as the @@ -40,7 +40,7 @@ discarded after use. -.. function:: compile_command(source[, filename[, symbol]]) +.. function:: compile_command(source, filename="", symbol="single") This function is useful for programs that want to emulate Python's interpreter main loop (a.k.a. the read-eval-print loop). The tricky part is to determine @@ -67,7 +67,7 @@ ------------------------------- -.. method:: InteractiveInterpreter.runsource(source[, filename[, symbol]]) +.. method:: InteractiveInterpreter.runsource(source, filename="", symbol="single") Compile and run some source in the interpreter. Arguments are the same as for :func:`compile_command`; the default for *filename* is ``''``, and for @@ -100,7 +100,7 @@ with it. -.. method:: InteractiveInterpreter.showsyntaxerror([filename]) +.. method:: InteractiveInterpreter.showsyntaxerror(filename=None) Display the syntax error that just occurred. This does not display a stack trace because there isn't one for syntax errors. If *filename* is given, it is @@ -132,7 +132,7 @@ interpreter objects as well as the following additions. -.. method:: InteractiveConsole.interact([banner]) +.. method:: InteractiveConsole.interact(banner=None) Closely emulate the interactive Python console. The optional banner argument specify the banner to print before the first interaction; by default it prints a @@ -158,7 +158,7 @@ Remove any unhandled source text from the input buffer. -.. method:: InteractiveConsole.raw_input([prompt]) +.. method:: InteractiveConsole.raw_input(prompt="") Write a prompt and read a line. The returned line does not include the trailing newline. When the user enters the EOF key sequence, :exc:`EOFError` is raised. Modified: python/branches/py3k/Doc/library/codecs.rst ============================================================================== --- python/branches/py3k/Doc/library/codecs.rst (original) +++ python/branches/py3k/Doc/library/codecs.rst Mon Apr 6 00:20:44 2009 @@ -1,4 +1,3 @@ - :mod:`codecs` --- Codec registry and base classes ================================================= @@ -226,34 +225,36 @@ defaults to line buffered. -.. function:: EncodedFile(file, input[, output[, errors]]) +.. function:: EncodedFile(file, data_encoding, file_encoding=None, errors='strict') Return a wrapped version of file which provides transparent encoding translation. Bytes written to the wrapped file are interpreted according to the given - *input* encoding and then written to the original file as bytes using the - *output* encoding. + *data_encoding* and then written to the original file as bytes using the + *file_encoding*. - If *output* is not given, it defaults to *input*. + If *file_encoding* is not given, it defaults to *data_encoding*. - *errors* may be given to define the error handling. It defaults to ``'strict'``, - which causes :exc:`ValueError` to be raised in case an encoding error occurs. + *errors* may be given to define the error handling. It defaults to + ``'strict'``, which causes :exc:`ValueError` to be raised in case an encoding + error occurs. -.. function:: iterencode(iterable, encoding[, errors]) +.. function:: iterencode(iterator, encoding, errors='strict', **kwargs) Uses an incremental encoder to iteratively encode the input provided by - *iterable*. This function is a :term:`generator`. *errors* (as well as any + *iterator*. This function is a :term:`generator`. *errors* (as well as any other keyword argument) is passed through to the incremental encoder. -.. function:: iterdecode(iterable, encoding[, errors]) +.. function:: iterdecode(iterator, encoding, errors='strict', **kwargs) Uses an incremental decoder to iteratively decode the input provided by - *iterable*. This function is a :term:`generator`. *errors* (as well as any + *iterator*. This function is a :term:`generator`. *errors* (as well as any other keyword argument) is passed through to the incremental decoder. + The module also provides the following constants which are useful for reading and writing to platform dependent files: From python-checkins at python.org Mon Apr 6 00:20:45 2009 From: python-checkins at python.org (matthias.klose) Date: Mon, 6 Apr 2009 00:20:45 +0200 (CEST) Subject: [Python-checkins] r71290 - python/branches/release26-maint/Misc/NEWS Message-ID: <20090405222045.E60C51E401A@bag.python.org> Author: matthias.klose Date: Mon Apr 6 00:20:45 2009 New Revision: 71290 Log: Misc/NEWS: Move back two items to 2.6.1. Modified: python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Mon Apr 6 00:20:45 2009 @@ -432,11 +432,6 @@ - Issues #4728 and #4060: WORDS_BIGEDIAN is now correct in Universal builds. -- Issue #4389: Add icon to the uninstall entry in "add-and-remove-programs". - -- Issue #4289: Remove Cancel button from AdvancedDlg. - - C-API ----- @@ -532,6 +527,10 @@ Build ----- +- Issue #4389: Add icon to the uninstall entry in "add-and-remove-programs". + +- Issue #4289: Remove Cancel button from AdvancedDlg. + - Issue #1656675: Register a drop handler for .py* files on Windows. - Issue #4120: Exclude manifest from extension modules in VS2008. From buildbot at python.org Mon Apr 6 00:21:56 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 05 Apr 2009 22:21:56 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 2.6 Message-ID: <20090405222157.14E0B1E401A@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%202.6/builds/238 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: 3 tests failed: test_generators test_genexps test_syntax make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Mon Apr 6 00:44:44 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 05 Apr 2009 22:44:44 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 2.6 Message-ID: <20090405224444.B719E1E4002@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%202.6/builds/229 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Mon Apr 6 00:51:09 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 6 Apr 2009 00:51:09 +0200 (CEST) Subject: [Python-checkins] r71291 - in python/trunk: Doc/distutils/builtdist.rst Lib/distutils/command/bdist.py Lib/distutils/tests/test_bdist.py Misc/NEWS Message-ID: <20090405225109.EADB51E4002@bag.python.org> Author: tarek.ziade Date: Mon Apr 6 00:51:09 2009 New Revision: 71291 Log: Fixed #5095: msi missing from Distutils bdist formats Added: python/trunk/Lib/distutils/tests/test_bdist.py (contents, props changed) Modified: python/trunk/Doc/distutils/builtdist.rst python/trunk/Lib/distutils/command/bdist.py python/trunk/Misc/NEWS Modified: python/trunk/Doc/distutils/builtdist.rst ============================================================================== --- python/trunk/Doc/distutils/builtdist.rst (original) +++ python/trunk/Doc/distutils/builtdist.rst Mon Apr 6 00:51:09 2009 @@ -80,7 +80,7 @@ +-------------+------------------------------+---------+ | ``tar`` | tar file (:file:`.tar`) | \(3) | +-------------+------------------------------+---------+ -| ``zip`` | zip file (:file:`.zip`) | \(4) | +| ``zip`` | zip file (:file:`.zip`) | (2),(4) | +-------------+------------------------------+---------+ | ``rpm`` | RPM | \(5) | +-------------+------------------------------+---------+ @@ -90,9 +90,12 @@ +-------------+------------------------------+---------+ | ``rpm`` | RPM | \(5) | +-------------+------------------------------+---------+ -| ``wininst`` | self-extracting ZIP file for | (2),(4) | +| ``wininst`` | self-extracting ZIP file for | \(4) | | | Windows | | +-------------+------------------------------+---------+ +| ``msi`` | Microsoft Installer. | | ++-------------+------------------------------+---------+ + Notes: @@ -102,8 +105,6 @@ (2) default on Windows - **\*\*** to-do! **\*\*** - (3) requires external utilities: :program:`tar` and possibly one of :program:`gzip`, :program:`bzip2`, or :program:`compress` @@ -133,6 +134,8 @@ +--------------------------+-----------------------+ | :command:`bdist_wininst` | wininst | +--------------------------+-----------------------+ +| :command:`bdist_msi` | msi | ++--------------------------+-----------------------+ The following sections give details on the individual :command:`bdist_\*` commands. Modified: python/trunk/Lib/distutils/command/bdist.py ============================================================================== --- python/trunk/Lib/distutils/command/bdist.py (original) +++ python/trunk/Lib/distutils/command/bdist.py Mon Apr 6 00:51:09 2009 @@ -12,7 +12,7 @@ from distutils.util import get_platform -def show_formats (): +def show_formats(): """Print list of available formats (arguments to "--format" option). """ from distutils.fancy_getopt import FancyGetopt @@ -24,7 +24,7 @@ pretty_printer.print_help("List of available distribution formats:") -class bdist (Command): +class bdist(Command): description = "create a built (binary) distribution" @@ -50,35 +50,28 @@ ] # The following commands do not take a format option from bdist - no_format_option = ('bdist_rpm', - #'bdist_sdux', 'bdist_pkgtool' - ) + no_format_option = ('bdist_rpm',) # This won't do in reality: will need to distinguish RPM-ish Linux, # Debian-ish Linux, Solaris, FreeBSD, ..., Windows, Mac OS. - default_format = { 'posix': 'gztar', - 'nt': 'zip', - 'os2': 'zip', } + default_format = {'posix': 'gztar', + 'nt': 'zip', + 'os2': 'zip'} # Establish the preferred order (for the --help-formats option). format_commands = ['rpm', 'gztar', 'bztar', 'ztar', 'tar', - 'wininst', 'zip', - #'pkgtool', 'sdux' - ] + 'wininst', 'zip', 'msi'] # And the real information. - format_command = { 'rpm': ('bdist_rpm', "RPM distribution"), - 'zip': ('bdist_dumb', "ZIP file"), - 'gztar': ('bdist_dumb', "gzip'ed tar file"), - 'bztar': ('bdist_dumb', "bzip2'ed tar file"), - 'ztar': ('bdist_dumb', "compressed tar file"), - 'tar': ('bdist_dumb', "tar file"), - 'wininst': ('bdist_wininst', - "Windows executable installer"), - 'zip': ('bdist_dumb', "ZIP file"), - #'pkgtool': ('bdist_pkgtool', - # "Solaris pkgtool distribution"), - #'sdux': ('bdist_sdux', "HP-UX swinstall depot"), + format_command = {'rpm': ('bdist_rpm', "RPM distribution"), + 'gztar': ('bdist_dumb', "gzip'ed tar file"), + 'bztar': ('bdist_dumb', "bzip2'ed tar file"), + 'ztar': ('bdist_dumb', "compressed tar file"), + 'tar': ('bdist_dumb', "tar file"), + 'wininst': ('bdist_wininst', + "Windows executable installer"), + 'zip': ('bdist_dumb', "ZIP file"), + 'msi': ('bdist_msi', "Microsoft Installer") } @@ -89,9 +82,6 @@ self.dist_dir = None self.skip_build = 0 - # initialize_options() - - def finalize_options (self): # have to finalize 'plat_name' before 'bdist_base' if self.plat_name is None: @@ -120,10 +110,7 @@ if self.dist_dir is None: self.dist_dir = "dist" - # finalize_options() - def run (self): - # Figure out which sub-commands we need to run. commands = [] for format in self.formats: @@ -144,7 +131,3 @@ if cmd_name in commands[i+1:]: sub_cmd.keep_temp = 1 self.run_command(cmd_name) - - # run() - -# class bdist Added: python/trunk/Lib/distutils/tests/test_bdist.py ============================================================================== --- (empty file) +++ python/trunk/Lib/distutils/tests/test_bdist.py Mon Apr 6 00:51:09 2009 @@ -0,0 +1,43 @@ +"""Tests for distutils.command.bdist.""" +import unittest +import sys +import os +import tempfile +import shutil + +from distutils.core import Distribution +from distutils.command.bdist import bdist +from distutils.tests import support +from distutils.spawn import find_executable +from distutils import spawn +from distutils.errors import DistutilsExecError + +class BuildTestCase(support.TempdirManager, + unittest.TestCase): + + def test_formats(self): + + # let's create a command and make sure + # we can fix the format + pkg_pth, dist = self.create_dist() + cmd = bdist(dist) + cmd.formats = ['msi'] + cmd.ensure_finalized() + self.assertEquals(cmd.formats, ['msi']) + + # what format bdist offers ? + # XXX an explicit list in bdist is + # not the best way to bdist_* commands + # we should add a registry + formats = ['rpm', 'zip', 'gztar', 'bztar', 'ztar', + 'tar', 'wininst', 'msi'] + formats.sort() + founded = cmd.format_command.keys() + founded.sort() + self.assertEquals(founded, formats) + +def test_suite(): + return unittest.makeSuite(BuildTestCase) + +if __name__ == '__main__': + test_support.run_unittest(test_suite()) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Apr 6 00:51:09 2009 @@ -213,6 +213,9 @@ Library ------- +- Issue #5095: Added bdist_msi to the list of bdist supported formats. + Initial fix by Steven Bethard. + - Issue #1491431: Fixed distutils.filelist.glob_to_re for edge cases. Initial fix by Wayne Davison. From python-checkins at python.org Mon Apr 6 00:52:46 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 6 Apr 2009 00:52:46 +0200 (CEST) Subject: [Python-checkins] r71292 - python/branches/release26-maint Message-ID: <20090405225246.EA7B81E4002@bag.python.org> Author: tarek.ziade Date: Mon Apr 6 00:52:46 2009 New Revision: 71292 Log: Blocked revisions 71291 via svnmerge ........ r71291 | tarek.ziade | 2009-04-06 00:51:09 +0200 (Mon, 06 Apr 2009) | 1 line Fixed #5095: msi missing from Distutils bdist formats ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Apr 6 00:57:22 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 6 Apr 2009 00:57:22 +0200 (CEST) Subject: [Python-checkins] r71293 - in python/branches/py3k: Doc/distutils/builtdist.rst Lib/distutils/command/bdist.py Lib/distutils/tests/test_bdist.py Misc/NEWS Message-ID: <20090405225722.132A01E4002@bag.python.org> Author: tarek.ziade Date: Mon Apr 6 00:57:21 2009 New Revision: 71293 Log: Merged revisions 71291 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71291 | tarek.ziade | 2009-04-06 00:51:09 +0200 (Mon, 06 Apr 2009) | 1 line Fixed #5095: msi missing from Distutils bdist formats ........ Added: python/branches/py3k/Lib/distutils/tests/test_bdist.py - copied, changed from r71291, /python/trunk/Lib/distutils/tests/test_bdist.py Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/distutils/builtdist.rst python/branches/py3k/Lib/distutils/command/bdist.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/distutils/builtdist.rst ============================================================================== --- python/branches/py3k/Doc/distutils/builtdist.rst (original) +++ python/branches/py3k/Doc/distutils/builtdist.rst Mon Apr 6 00:57:21 2009 @@ -80,7 +80,7 @@ +-------------+------------------------------+---------+ | ``tar`` | tar file (:file:`.tar`) | \(3) | +-------------+------------------------------+---------+ -| ``zip`` | zip file (:file:`.zip`) | \(4) | +| ``zip`` | zip file (:file:`.zip`) | (2),(4) | +-------------+------------------------------+---------+ | ``rpm`` | RPM | \(5) | +-------------+------------------------------+---------+ @@ -90,9 +90,12 @@ +-------------+------------------------------+---------+ | ``rpm`` | RPM | \(5) | +-------------+------------------------------+---------+ -| ``wininst`` | self-extracting ZIP file for | (2),(4) | +| ``wininst`` | self-extracting ZIP file for | \(4) | | | Windows | | +-------------+------------------------------+---------+ +| ``msi`` | Microsoft Installer. | | ++-------------+------------------------------+---------+ + Notes: @@ -102,8 +105,6 @@ (2) default on Windows - **\*\*** to-do! **\*\*** - (3) requires external utilities: :program:`tar` and possibly one of :program:`gzip`, :program:`bzip2`, or :program:`compress` @@ -133,6 +134,8 @@ +--------------------------+-----------------------+ | :command:`bdist_wininst` | wininst | +--------------------------+-----------------------+ +| :command:`bdist_msi` | msi | ++--------------------------+-----------------------+ The following sections give details on the individual :command:`bdist_\*` commands. Modified: python/branches/py3k/Lib/distutils/command/bdist.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/bdist.py (original) +++ python/branches/py3k/Lib/distutils/command/bdist.py Mon Apr 6 00:57:21 2009 @@ -49,35 +49,28 @@ ] # The following commands do not take a format option from bdist - no_format_option = ('bdist_rpm', - #'bdist_sdux', 'bdist_pkgtool' - ) + no_format_option = ('bdist_rpm',) # This won't do in reality: will need to distinguish RPM-ish Linux, # Debian-ish Linux, Solaris, FreeBSD, ..., Windows, Mac OS. - default_format = { 'posix': 'gztar', - 'nt': 'zip', - 'os2': 'zip', } + default_format = {'posix': 'gztar', + 'nt': 'zip', + 'os2': 'zip'} # Establish the preferred order (for the --help-formats option). format_commands = ['rpm', 'gztar', 'bztar', 'ztar', 'tar', - 'wininst', 'zip', - #'pkgtool', 'sdux' - ] + 'wininst', 'zip', 'msi'] # And the real information. - format_command = { 'rpm': ('bdist_rpm', "RPM distribution"), - 'zip': ('bdist_dumb', "ZIP file"), - 'gztar': ('bdist_dumb', "gzip'ed tar file"), - 'bztar': ('bdist_dumb', "bzip2'ed tar file"), - 'ztar': ('bdist_dumb', "compressed tar file"), - 'tar': ('bdist_dumb', "tar file"), - 'wininst': ('bdist_wininst', - "Windows executable installer"), - 'zip': ('bdist_dumb', "ZIP file"), - #'pkgtool': ('bdist_pkgtool', - # "Solaris pkgtool distribution"), - #'sdux': ('bdist_sdux', "HP-UX swinstall depot"), + format_command = {'rpm': ('bdist_rpm', "RPM distribution"), + 'gztar': ('bdist_dumb', "gzip'ed tar file"), + 'bztar': ('bdist_dumb', "bzip2'ed tar file"), + 'ztar': ('bdist_dumb', "compressed tar file"), + 'tar': ('bdist_dumb', "tar file"), + 'wininst': ('bdist_wininst', + "Windows executable installer"), + 'zip': ('bdist_dumb', "ZIP file"), + 'msi': ('bdist_msi', "Microsoft Installer") } Copied: python/branches/py3k/Lib/distutils/tests/test_bdist.py (from r71291, /python/trunk/Lib/distutils/tests/test_bdist.py) ============================================================================== --- /python/trunk/Lib/distutils/tests/test_bdist.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_bdist.py Mon Apr 6 00:57:21 2009 @@ -32,7 +32,7 @@ formats = ['rpm', 'zip', 'gztar', 'bztar', 'ztar', 'tar', 'wininst', 'msi'] formats.sort() - founded = cmd.format_command.keys() + founded = list(cmd.format_command.keys()) founded.sort() self.assertEquals(founded, formats) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Apr 6 00:57:21 2009 @@ -327,6 +327,9 @@ Library ------- +- Issue #5095: Added bdist_msi to the list of bdist supported formats. + Initial fix by Steven Bethard. + - Issue #1491431: Fixed distutils.filelist.glob_to_re for edge cases. Initial fix by Wayne Davison. From python-checkins at python.org Mon Apr 6 00:58:18 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 6 Apr 2009 00:58:18 +0200 (CEST) Subject: [Python-checkins] r71294 - python/branches/release30-maint Message-ID: <20090405225818.A79EE1E4002@bag.python.org> Author: tarek.ziade Date: Mon Apr 6 00:58:18 2009 New Revision: 71294 Log: Blocked revisions 71293 via svnmerge ................ r71293 | tarek.ziade | 2009-04-06 00:57:21 +0200 (Mon, 06 Apr 2009) | 9 lines Merged revisions 71291 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71291 | tarek.ziade | 2009-04-06 00:51:09 +0200 (Mon, 06 Apr 2009) | 1 line Fixed #5095: msi missing from Distutils bdist formats ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Mon Apr 6 01:03:10 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 6 Apr 2009 01:03:10 +0200 (CEST) Subject: [Python-checkins] r71295 - python/trunk/Lib/distutils/command/bdist.py Message-ID: <20090405230310.AFF6E1E4002@bag.python.org> Author: tarek.ziade Date: Mon Apr 6 01:03:10 2009 New Revision: 71295 Log: pep8-fied method names Modified: python/trunk/Lib/distutils/command/bdist.py Modified: python/trunk/Lib/distutils/command/bdist.py ============================================================================== --- python/trunk/Lib/distutils/command/bdist.py (original) +++ python/trunk/Lib/distutils/command/bdist.py Mon Apr 6 01:03:10 2009 @@ -75,14 +75,14 @@ } - def initialize_options (self): + def initialize_options(self): self.bdist_base = None self.plat_name = None self.formats = None self.dist_dir = None self.skip_build = 0 - def finalize_options (self): + def finalize_options(self): # have to finalize 'plat_name' before 'bdist_base' if self.plat_name is None: if self.skip_build: @@ -110,7 +110,7 @@ if self.dist_dir is None: self.dist_dir = "dist" - def run (self): + def run(self): # Figure out which sub-commands we need to run. commands = [] for format in self.formats: From python-checkins at python.org Mon Apr 6 01:04:17 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 6 Apr 2009 01:04:17 +0200 (CEST) Subject: [Python-checkins] r71296 - python/branches/release26-maint Message-ID: <20090405230417.6DFE21E4002@bag.python.org> Author: tarek.ziade Date: Mon Apr 6 01:04:17 2009 New Revision: 71296 Log: Blocked revisions 71295 via svnmerge ........ r71295 | tarek.ziade | 2009-04-06 01:03:10 +0200 (Mon, 06 Apr 2009) | 1 line pep8-fied method names ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Apr 6 01:05:31 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 6 Apr 2009 01:05:31 +0200 (CEST) Subject: [Python-checkins] r71297 - python/branches/py3k Message-ID: <20090405230531.9C2A61E4002@bag.python.org> Author: tarek.ziade Date: Mon Apr 6 01:05:31 2009 New Revision: 71297 Log: Merged revisions 71295 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71295 | tarek.ziade | 2009-04-06 01:03:10 +0200 (Mon, 06 Apr 2009) | 1 line pep8-fied method names ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Mon Apr 6 01:06:21 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 6 Apr 2009 01:06:21 +0200 (CEST) Subject: [Python-checkins] r71298 - python/branches/release30-maint Message-ID: <20090405230621.C789F1E4095@bag.python.org> Author: tarek.ziade Date: Mon Apr 6 01:06:21 2009 New Revision: 71298 Log: Blocked revisions 71297 via svnmerge ................ r71297 | tarek.ziade | 2009-04-06 01:05:31 +0200 (Mon, 06 Apr 2009) | 9 lines Merged revisions 71295 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71295 | tarek.ziade | 2009-04-06 01:03:10 +0200 (Mon, 06 Apr 2009) | 1 line pep8-fied method names ........ ................ Modified: python/branches/release30-maint/ (props changed) From buildbot at python.org Mon Apr 6 01:29:40 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 05 Apr 2009 23:29:40 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 2.6 Message-ID: <20090405232941.1FE371E4002@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%20gentoo%202.6/builds/207 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-amd64 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: georg.brandl,matthias.klose,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 3 tests failed: test_generators test_genexps test_syntax make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 6 01:43:58 2009 From: python-checkins at python.org (gregory.p.smith) Date: Mon, 6 Apr 2009 01:43:58 +0200 (CEST) Subject: [Python-checkins] r71299 - in python/trunk: Lib/test/test_os.py Modules/posixmodule.c Message-ID: <20090405234358.B47C21E401E@bag.python.org> Author: gregory.p.smith Date: Mon Apr 6 01:43:58 2009 New Revision: 71299 Log: Fixes issue5705: os.setuid() and friends did not accept the same range of values that pwd.getpwnam() returns. Modified: python/trunk/Lib/test/test_os.py python/trunk/Modules/posixmodule.c Modified: python/trunk/Lib/test/test_os.py ============================================================================== --- python/trunk/Lib/test/test_os.py (original) +++ python/trunk/Lib/test/test_os.py Mon Apr 6 01:43:58 2009 @@ -608,6 +608,48 @@ class Win32ErrorTests(unittest.TestCase): pass + class PosixUidGidTests(unittest.TestCase): + if hasattr(os, 'setuid'): + def test_setuid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setuid, 0) + self.assertRaises(OverflowError, os.setuid, 1<<32) + + if hasattr(os, 'setgid'): + def test_setgid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setgid, 0) + self.assertRaises(OverflowError, os.setgid, 1<<32) + + if hasattr(os, 'seteuid'): + def test_seteuid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.seteuid, 0) + self.assertRaises(OverflowError, os.seteuid, 1<<32) + + if hasattr(os, 'setegid'): + def test_setegid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setegid, 0) + self.assertRaises(OverflowError, os.setegid, 1<<32) + + if hasattr(os, 'setreuid'): + def test_setreuid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setreuid, 0, 0) + self.assertRaises(OverflowError, os.setreuid, 1<<32, 0) + self.assertRaises(OverflowError, os.setreuid, 0, 1<<32) + + if hasattr(os, 'setregid'): + def test_setregid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setregid, 0, 0) + self.assertRaises(OverflowError, os.setregid, 1<<32, 0) + self.assertRaises(OverflowError, os.setregid, 0, 1<<32) +else: + class PosixUidGidTests(unittest.TestCase): + pass + def test_main(): test_support.run_unittest( FileTests, @@ -619,7 +661,8 @@ DevNullTests, URandomTests, Win32ErrorTests, - TestInvalidFD + TestInvalidFD, + PosixUidGidTests ) if __name__ == "__main__": Modified: python/trunk/Modules/posixmodule.c ============================================================================== --- python/trunk/Modules/posixmodule.c (original) +++ python/trunk/Modules/posixmodule.c Mon Apr 6 01:43:58 2009 @@ -5597,9 +5597,15 @@ static PyObject * posix_setuid(PyObject *self, PyObject *args) { - int uid; - if (!PyArg_ParseTuple(args, "i:setuid", &uid)) + long uid_arg; + uid_t uid; + if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg)) + return NULL; + uid = uid_arg; + if (uid != uid_arg) { + PyErr_SetString(PyExc_OverflowError, "user id too big"); return NULL; + } if (setuid(uid) < 0) return posix_error(); Py_INCREF(Py_None); @@ -5616,10 +5622,16 @@ static PyObject * posix_seteuid (PyObject *self, PyObject *args) { - int euid; - if (!PyArg_ParseTuple(args, "i", &euid)) { + long euid_arg; + uid_t euid; + if (!PyArg_ParseTuple(args, "l", &euid_arg)) + return NULL; + euid = euid_arg; + if (euid != euid_arg) { + PyErr_SetString(PyExc_OverflowError, "user id too big"); return NULL; - } else if (seteuid(euid) < 0) { + } + if (seteuid(euid) < 0) { return posix_error(); } else { Py_INCREF(Py_None); @@ -5636,10 +5648,16 @@ static PyObject * posix_setegid (PyObject *self, PyObject *args) { - int egid; - if (!PyArg_ParseTuple(args, "i", &egid)) { + long egid_arg; + gid_t egid; + if (!PyArg_ParseTuple(args, "l", &egid_arg)) return NULL; - } else if (setegid(egid) < 0) { + egid = egid_arg; + if (egid != egid_arg) { + PyErr_SetString(PyExc_OverflowError, "group id too big"); + return NULL; + } + if (setegid(egid) < 0) { return posix_error(); } else { Py_INCREF(Py_None); @@ -5656,10 +5674,17 @@ static PyObject * posix_setreuid (PyObject *self, PyObject *args) { - int ruid, euid; - if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) { + long ruid_arg, euid_arg; + uid_t ruid, euid; + if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg)) return NULL; - } else if (setreuid(ruid, euid) < 0) { + ruid = ruid_arg; + euid = euid_arg; + if (euid != euid_arg || ruid != ruid_arg) { + PyErr_SetString(PyExc_OverflowError, "user id too big"); + return NULL; + } + if (setreuid(ruid, euid) < 0) { return posix_error(); } else { Py_INCREF(Py_None); @@ -5676,10 +5701,17 @@ static PyObject * posix_setregid (PyObject *self, PyObject *args) { - int rgid, egid; - if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) { + long rgid_arg, egid_arg; + gid_t rgid, egid; + if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg)) + return NULL; + rgid = rgid_arg; + egid = egid_arg; + if (egid != egid_arg || rgid != rgid_arg) { + PyErr_SetString(PyExc_OverflowError, "group id too big"); return NULL; - } else if (setregid(rgid, egid) < 0) { + } + if (setregid(rgid, egid) < 0) { return posix_error(); } else { Py_INCREF(Py_None); @@ -5696,9 +5728,15 @@ static PyObject * posix_setgid(PyObject *self, PyObject *args) { - int gid; - if (!PyArg_ParseTuple(args, "i:setgid", &gid)) + long gid_arg; + gid_t gid; + if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg)) + return NULL; + gid = gid_arg; + if (gid != gid_arg) { + PyErr_SetString(PyExc_OverflowError, "group id too big"); return NULL; + } if (setgid(gid) < 0) return posix_error(); Py_INCREF(Py_None); @@ -5746,7 +5784,7 @@ return NULL; } grouplist[i] = x; - /* read back the value to see if it fitted in gid_t */ + /* read back to see if it fits in gid_t */ if (grouplist[i] != x) { PyErr_SetString(PyExc_TypeError, "group id too big"); From buildbot at python.org Mon Apr 6 01:44:31 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 05 Apr 2009 23:44:31 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 3.x Message-ID: <20090405234431.89A781E401E@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%20gentoo%203.x/builds/590 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-amd64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: tarek.ziade BUILD FAILED: failed failed slave lost sincerely, -The Buildbot From python-checkins at python.org Mon Apr 6 01:48:26 2009 From: python-checkins at python.org (gregory.p.smith) Date: Mon, 6 Apr 2009 01:48:26 +0200 (CEST) Subject: [Python-checkins] r71300 - python/trunk/Misc/NEWS Message-ID: <20090405234826.90C931E4002@bag.python.org> Author: gregory.p.smith Date: Mon Apr 6 01:48:26 2009 New Revision: 71300 Log: news entry for r71299. Modified: python/trunk/Misc/NEWS Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Apr 6 01:48:26 2009 @@ -210,6 +210,9 @@ - Issue #1113244: Py_XINCREF, Py_DECREF, Py_XDECREF: Add `do { ... } while (0)' to avoid compiler warnings. +- Issue #5705: os.setuid() would not accept values > 2**31-1 but pwd.getpwnam() + returned them on 64bit platforms. + Library ------- From buildbot at python.org Mon Apr 6 02:08:49 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 06 Apr 2009 00:08:49 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo trunk Message-ID: <20090406000849.853051E4002@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo trunk. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%20gentoo%20trunk/builds/2103 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-amd64 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: Traceback (most recent call last): File "/home/buildbot/slave/py-build/trunk.norwitz-amd64/build/Lib/threading.py", line 524, in __bootstrap_inner self.run() File "/home/buildbot/slave/py-build/trunk.norwitz-amd64/build/Lib/threading.py", line 477, in run self.__target(*self.__args, **self.__kwargs) File "/home/buildbot/slave/py-build/trunk.norwitz-amd64/build/Lib/bsddb/test/test_thread.py", line 306, in readerThread rec = dbutils.DeadlockWrap(c.next, max_retries=10) File "/home/buildbot/slave/py-build/trunk.norwitz-amd64/build/Lib/bsddb/dbutils.py", line 68, in DeadlockWrap return function(*_args, **_kwargs) DBLockDeadlockError: (-30995, 'DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock') 4 tests failed: test_asyncore test_generators test_genexps test_syntax ====================================================================== FAIL: test_readwrite (test.test_asyncore.HelperFunctionTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildbot/slave/py-build/trunk.norwitz-amd64/build/Lib/test/test_asyncore.py", line 144, in test_readwrite self.assertEqual(tobj.read, True) AssertionError: False != True make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 6 02:24:29 2009 From: python-checkins at python.org (hirokazu.yamamoto) Date: Mon, 6 Apr 2009 02:24:29 +0200 (CEST) Subject: [Python-checkins] r71301 - in python/branches/release26-maint/Doc: c-api/object.rst howto/regex.rst Message-ID: <20090406002429.EDDDF1E4002@bag.python.org> Author: hirokazu.yamamoto Date: Mon Apr 6 02:24:29 2009 New Revision: 71301 Log: Fixed typo. Modified: python/branches/release26-maint/Doc/c-api/object.rst python/branches/release26-maint/Doc/howto/regex.rst Modified: python/branches/release26-maint/Doc/c-api/object.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/object.rst (original) +++ python/branches/release26-maint/Doc/c-api/object.rst Mon Apr 6 02:24:29 2009 @@ -66,8 +66,7 @@ ``o.attr_name = v``. -.. cfunction:: int PyObject_GenericSetAttr(PyObject *o, PyObject *name, PyObject -*value) +.. cfunction:: int PyObject_GenericSetAttr(PyObject *o, PyObject *name, PyObject *value) Generic attribute setter function that is meant to be put into a type object's ``tp_setattro`` slot. It looks for a data descriptor in the Modified: python/branches/release26-maint/Doc/howto/regex.rst ============================================================================== --- python/branches/release26-maint/Doc/howto/regex.rst (original) +++ python/branches/release26-maint/Doc/howto/regex.rst Mon Apr 6 02:24:29 2009 @@ -600,7 +600,7 @@ .. data:: U UNICODE - :index: + :noindex: Make ``\w``, ``\W``, ``\b``, ``\B``, ``\d``, ``\D``, ``\s`` and ``\S`` dependent on the Unicode character properties database. From buildbot at python.org Mon Apr 6 02:34:09 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 06 Apr 2009 00:34:09 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 2.6 Message-ID: <20090406003409.CE9A51E4002@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%202.6/builds/220 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_ssl ====================================================================== ERROR: testConnect (test.test_ssl.NetworkedTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/test/test_ssl.py", line 121, in testConnect s.connect(("svn.python.org", 443)) File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/ssl.py", line 309, in connect self.do_handshake() File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/ssl.py", line 293, in do_handshake self._sslobj.do_handshake() error: [Errno 110] Connection timed out make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Mon Apr 6 03:05:45 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 06 Apr 2009 01:05:45 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090406010546.40B6C1E4002@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/251 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_posix test_subprocess ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From buildbot at python.org Mon Apr 6 03:16:28 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 06 Apr 2009 01:16:28 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 2.6 Message-ID: <20090406011628.320DA1E4002@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%202.6/builds/223 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: georg.brandl,matthias.klose,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: Traceback (most recent call last): File "/home/pybot/buildarea/2.6.klose-debian-ppc/build/Lib/threading.py", line 525, in __bootstrap_inner self.run() File "/home/pybot/buildarea/2.6.klose-debian-ppc/build/Lib/threading.py", line 477, in run self.__target(*self.__args, **self.__kwargs) File "/home/pybot/buildarea/2.6.klose-debian-ppc/build/Lib/bsddb/test/test_thread.py", line 306, in readerThread rec = dbutils.DeadlockWrap(c.next, max_retries=10) File "/home/pybot/buildarea/2.6.klose-debian-ppc/build/Lib/bsddb/dbutils.py", line 68, in DeadlockWrap return function(*_args, **_kwargs) DBLockDeadlockError: (-30994, 'DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock') 3 tests failed: test_generators test_genexps test_syntax make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 6 04:08:45 2009 From: python-checkins at python.org (jack.diederich) Date: Mon, 6 Apr 2009 04:08:45 +0200 (CEST) Subject: [Python-checkins] r71302 - python/trunk/Lib/test/test_telnetlib.py Message-ID: <20090406020845.3583C1E4002@bag.python.org> Author: jack.diederich Date: Mon Apr 6 04:08:44 2009 New Revision: 71302 Log: test the telnetlib.Telnet interface more thoroughly Modified: python/trunk/Lib/test/test_telnetlib.py Modified: python/trunk/Lib/test/test_telnetlib.py ============================================================================== --- python/trunk/Lib/test/test_telnetlib.py (original) +++ python/trunk/Lib/test/test_telnetlib.py Mon Apr 6 04:08:44 2009 @@ -2,23 +2,46 @@ import threading import telnetlib import time +import Queue from unittest import TestCase from test import test_support HOST = test_support.HOST +EOF_sigil = object() -def server(evt, serv): +def server(evt, serv, dataq=None): + """ Open a tcp server in three steps + 1) set evt to true to let the parent know we are ready + 2) [optional] write all the data in dataq to the socket + terminate when dataq.get() returns EOF_sigil + 3) set evt to true to let the parent know we're done + """ serv.listen(5) evt.set() try: conn, addr = serv.accept() + if dataq: + data = '' + new_data = dataq.get(True, 0.5) + while new_data is not EOF_sigil: + if type(new_data) == str: + data += new_data + elif type(new_data) in [int, float]: + time.sleep(new_data) + written = conn.send(data) + data = data[written:] + new_data = dataq.get(True, 0.5) except socket.timeout: pass finally: serv.close() evt.set() +def wibble_float(num): + ''' return a (low, high) tuple that are 1% more and 1% less of num ''' + return num * 0.99, num * 1.01 + class GeneralTests(TestCase): def setUp(self): @@ -26,13 +49,15 @@ self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.settimeout(3) self.port = test_support.bind_port(self.sock) - threading.Thread(target=server, args=(self.evt,self.sock)).start() + self.thread = threading.Thread(target=server, args=(self.evt,self.sock)) + self.thread.start() self.evt.wait() self.evt.clear() time.sleep(.1) def tearDown(self): self.evt.wait() + self.thread.join() def testBasic(self): # connects @@ -71,9 +96,257 @@ self.assertEqual(telnet.sock.gettimeout(), 30) telnet.sock.close() +def _read_setUp(self): + # the blocking constant should be tuned! + self.blocking_timeout = 0.0 + self.evt = threading.Event() + self.dataq = Queue.Queue() + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.sock.settimeout(3) + self.port = test_support.bind_port(self.sock) + self.thread = threading.Thread(target=server, args=(self.evt,self.sock, self.dataq)) + self.thread.start() + self.evt.wait() + self.evt.clear() + time.sleep(.1) + +def _read_tearDown(self): + self.evt.wait() + self.thread.join() + + +class ReadTests(TestCase): + setUp = _read_setUp + tearDown = _read_tearDown + + def _test_blocking(self, func): + start = time.time() + self.dataq.put(self.blocking_timeout) + self.dataq.put(EOF_sigil) + data = func() + low, high = wibble_float(self.blocking_timeout) + self.assertTrue(time.time() - start >= low) + + def test_read_until_A(self): + """ + read_until(expected, [timeout]) + Read until the expected string has been seen, or a timeout is + hit (default is no timeout); may block. + """ + want = ['x' * 10, 'match', 'y' * 10, EOF_sigil] + for item in want: + self.dataq.put(item) + telnet = telnetlib.Telnet(HOST, self.port) + data = telnet.read_until('match') + self.assertEqual(data, ''.join(want[:-2])) + + def test_read_until_B(self): + # test the timeout - it does NOT raise socket.timeout + want = ['hello', self.blocking_timeout, EOF_sigil] + for item in want: + self.dataq.put(item) + telnet = telnetlib.Telnet(HOST, self.port) + start = time.time() + timeout = self.blocking_timeout / 2 + data = telnet.read_until('not seen', timeout) + low, high = wibble_float(timeout) + self.assertTrue(low <= time.time() - high) + self.assertEqual(data, want[0]) + + def test_read_all_A(self): + """ + read_all() + Read all data until EOF; may block. + """ + want = ['x' * 500, 'y' * 500, 'z' * 500, EOF_sigil] + for item in want: + self.dataq.put(item) + telnet = telnetlib.Telnet(HOST, self.port) + data = telnet.read_all() + self.assertEqual(data, ''.join(want[:-1])) + return + + def test_read_all_B(self): + self._test_blocking(telnetlib.Telnet(HOST, self.port).read_all) + + def test_read_some_A(self): + """ + read_some() + Read at least one byte or EOF; may block. + """ + # test 'at least one byte' + want = ['x' * 500, EOF_sigil] + for item in want: + self.dataq.put(item) + telnet = telnetlib.Telnet(HOST, self.port) + data = telnet.read_all() + self.assertTrue(len(data) >= 1) + + def test_read_some_B(self): + # test EOF + self.dataq.put(EOF_sigil) + telnet = telnetlib.Telnet(HOST, self.port) + self.assertEqual('', telnet.read_some()) + + def test_read_all_C(self): + self._test_blocking(telnetlib.Telnet(HOST, self.port).read_some) + + def _test_read_any_eager_A(self, func_name): + """ + read_very_eager() + Read all data available already queued or on the socket, + without blocking. + """ + # this never blocks so it should return eat part in turn + want = ['x' * 100, self.blocking_timeout/2, 'y' * 100, EOF_sigil] + expects = want[0] + want[2] + for item in want: + self.dataq.put(item) + telnet = telnetlib.Telnet(HOST, self.port) + func = getattr(telnet, func_name) + time.sleep(self.blocking_timeout/10) + data = '' + while True: + try: + data += func() + self.assertTrue(expects.startswith(data)) + time.sleep(self.blocking_timeout) + except EOFError: + break + self.assertEqual(expects, data) + + def _test_read_any_eager_B(self, func_name): + # test EOF + self.dataq.put(EOF_sigil) + time.sleep(self.blocking_timeout / 10) + telnet = telnetlib.Telnet(HOST, self.port) + func = getattr(telnet, func_name) + self.assertRaises(EOFError, func) + + # read_eager and read_very_eager make the same gaurantees + # (they behave differently but we only test the gaurantees) + def test_read_very_eager_A(self): + self._test_read_any_eager_A('read_very_eager') + def test_read_very_eager_B(self): + self._test_read_any_eager_B('read_very_eager') + def test_read_eager_A(self): + self._test_read_any_eager_A('read_eager') + def test_read_eager_B(self): + self._test_read_any_eager_B('read_eager') + # NB -- we need to test the IAC block which is mentioned in the docstring + # but not in the module docs + + def _test_read_any_lazy_A(self, func_name): + want = [self.blocking_timeout/2, 'x' * 100, EOF_sigil] + for item in want: + self.dataq.put(item) + telnet = telnetlib.Telnet(HOST, self.port) + func = getattr(telnet, func_name) + self.assertEqual('', func()) + data = '' + while True: + time.sleep(self.blocking_timeout) + try: + telnet.fill_rawq() + data += func() + if not data: + break + except EOFError: + break + self.assertTrue(want[1].startswith(data)) + return data, want[1] + + def _test_read_any_lazy_B(self, func_name): + self.dataq.put(EOF_sigil) + telnet = telnetlib.Telnet(HOST, self.port) + func = getattr(telnet, func_name) + time.sleep(self.blocking_timeout/10) + telnet.fill_rawq() + self.assertRaises(EOFError, func) + + # read_lazy and read_very_lazy make the samish gaurantees + def test_read_very_lazy_A(self): + data, want = self._test_read_any_lazy_A('read_very_lazy') + self.assertEqual(data, '') + def test_read_lazy(self): + data, want = self._test_read_any_lazy_A('read_lazy') + self.assertEqual(data, want) + def test_read_very_lazy_B(self): + self._test_read_any_lazy_B('read_very_lazy') + def test_read_lazy_B(self): + self._test_read_any_lazy_B('read_lazy') + +class nego_collector(object): + def __init__(self, sb_getter=None): + self.seen = '' + self.sb_getter = sb_getter + self.sb_seen = '' + + def do_nego(self, sock, cmd, opt): + self.seen += cmd + opt + if cmd == tl.SE and self.sb_getter: + sb_data = self.sb_getter() + self.sb_seen += sb_data + +tl = telnetlib +class OptionTests(TestCase): + setUp = _read_setUp + tearDown = _read_tearDown + # RFC 854 commands + cmds = [tl.AO, tl.AYT, tl.BRK, tl.EC, tl.EL, tl.GA, tl.IP, tl.NOP] + + def _test_command(self, data): + """ helper for testing IAC + cmd """ + self.setUp() + for item in data: + self.dataq.put(item) + telnet = telnetlib.Telnet(HOST, self.port) + nego = nego_collector() + telnet.set_option_negotiation_callback(nego.do_nego) + time.sleep(self.blocking_timeout/10) + txt = telnet.read_all() + cmd = nego.seen + self.assertTrue(len(cmd) > 0) # we expect at least one command + self.assertTrue(cmd[0] in self.cmds) + self.assertEqual(cmd[1], tl.NOOPT) + self.assertEqual(len(''.join(data[:-1])), len(txt + cmd)) + self.tearDown() + + def test_IAC_commands(self): + # reset our setup + self.dataq.put(EOF_sigil) + telnet = telnetlib.Telnet(HOST, self.port) + self.tearDown() + + for cmd in self.cmds: + self._test_command(['x' * 100, tl.IAC + cmd, 'y'*100, EOF_sigil]) + self._test_command(['x' * 10, tl.IAC + cmd, 'y'*10, EOF_sigil]) + self._test_command([tl.IAC + cmd, EOF_sigil]) + # all at once + self._test_command([tl.IAC + cmd for (cmd) in self.cmds] + [EOF_sigil]) + + def test_SB_commands(self): + # RFC 855, subnegotiations portion + send = [tl.IAC + tl.SB + tl.IAC + tl.SE, + tl.IAC + tl.SB + tl.IAC + tl.IAC + tl.IAC + tl.SE, + tl.IAC + tl.SB + tl.IAC + tl.IAC + 'aa' + tl.IAC + tl.SE, + tl.IAC + tl.SB + 'bb' + tl.IAC + tl.IAC + tl.IAC + tl.SE, + tl.IAC + tl.SB + 'cc' + tl.IAC + tl.IAC + 'dd' + tl.IAC + tl.SE, + EOF_sigil, + ] + for item in send: + self.dataq.put(item) + telnet = telnetlib.Telnet(HOST, self.port) + nego = nego_collector(telnet.read_sb_data) + telnet.set_option_negotiation_callback(nego.do_nego) + time.sleep(self.blocking_timeout/10) + txt = telnet.read_all() + self.assertEqual(txt, '') + want_sb_data = tl.IAC + tl.IAC + 'aabb' + tl.IAC + 'cc' + tl.IAC + 'dd' + self.assertEqual(nego.sb_seen, want_sb_data) def test_main(verbose=None): - test_support.run_unittest(GeneralTests) + test_support.run_unittest(GeneralTests, ReadTests, OptionTests) if __name__ == '__main__': test_main() From buildbot at python.org Mon Apr 6 04:12:55 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 06 Apr 2009 02:12:55 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 3.x Message-ID: <20090406021256.0E3C51E4002@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%203.x/builds/630 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_list make: *** [buildbottest] Error 1 sincerely, -The Buildbot From jackdied at gmail.com Mon Apr 6 04:19:54 2009 From: jackdied at gmail.com (Jack diederich) Date: Sun, 5 Apr 2009 22:19:54 -0400 Subject: [Python-checkins] r71302 - python/trunk/Lib/test/test_telnetlib.py In-Reply-To: <20090406020845.3583C1E4002@bag.python.org> References: <20090406020845.3583C1E4002@bag.python.org> Message-ID: I haven't tried this patch on 3.x yet. I expect it will explode badly due to bytes/str confusion. I'll figure that stuff out once I have telnetlib in slightly less sorry shape. On Sun, Apr 5, 2009 at 10:08 PM, jack.diederich wrote: > Author: jack.diederich > Date: Mon Apr ?6 04:08:44 2009 > New Revision: 71302 > > Log: > test the telnetlib.Telnet interface more thoroughly > > Modified: > ? python/trunk/Lib/test/test_telnetlib.py > > Modified: python/trunk/Lib/test/test_telnetlib.py > ============================================================================== > --- python/trunk/Lib/test/test_telnetlib.py ? ? (original) > +++ python/trunk/Lib/test/test_telnetlib.py ? ? Mon Apr ?6 04:08:44 2009 > @@ -2,23 +2,46 @@ > ?import threading > ?import telnetlib > ?import time > +import Queue > > ?from unittest import TestCase > ?from test import test_support > > ?HOST = test_support.HOST > +EOF_sigil = object() > > -def server(evt, serv): > +def server(evt, serv, dataq=None): > + ? ?""" Open a tcp server in three steps > + ? ? ? ?1) set evt to true to let the parent know we are ready > + ? ? ? ?2) [optional] write all the data in dataq to the socket > + ? ? ? ? ? terminate when dataq.get() returns EOF_sigil > + ? ? ? ?3) set evt to true to let the parent know we're done > + ? ?""" > ? ? serv.listen(5) > ? ? evt.set() > ? ? try: > ? ? ? ? conn, addr = serv.accept() > + ? ? ? ?if dataq: > + ? ? ? ? ? ?data = '' > + ? ? ? ? ? ?new_data = dataq.get(True, 0.5) > + ? ? ? ? ? ?while new_data is not EOF_sigil: > + ? ? ? ? ? ? ? ?if type(new_data) == str: > + ? ? ? ? ? ? ? ? ? ?data += new_data > + ? ? ? ? ? ? ? ?elif type(new_data) in [int, float]: > + ? ? ? ? ? ? ? ? ? ?time.sleep(new_data) > + ? ? ? ? ? ? ? ?written = conn.send(data) > + ? ? ? ? ? ? ? ?data = data[written:] > + ? ? ? ? ? ? ? ?new_data = dataq.get(True, 0.5) > ? ? except socket.timeout: > ? ? ? ? pass > ? ? finally: > ? ? ? ? serv.close() > ? ? ? ? evt.set() > > +def wibble_float(num): > + ? ?''' return a (low, high) tuple that are 1% more and 1% less of num ''' > + ? ?return num * 0.99, num * 1.01 > + > ?class GeneralTests(TestCase): > > ? ? def setUp(self): > @@ -26,13 +49,15 @@ > ? ? ? ? self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) > ? ? ? ? self.sock.settimeout(3) > ? ? ? ? self.port = test_support.bind_port(self.sock) > - ? ? ? ?threading.Thread(target=server, args=(self.evt,self.sock)).start() > + ? ? ? ?self.thread = threading.Thread(target=server, args=(self.evt,self.sock)) > + ? ? ? ?self.thread.start() > ? ? ? ? self.evt.wait() > ? ? ? ? self.evt.clear() > ? ? ? ? time.sleep(.1) > > ? ? def tearDown(self): > ? ? ? ? self.evt.wait() > + ? ? ? ?self.thread.join() > > ? ? def testBasic(self): > ? ? ? ? # connects > @@ -71,9 +96,257 @@ > ? ? ? ? self.assertEqual(telnet.sock.gettimeout(), 30) > ? ? ? ? telnet.sock.close() > > +def _read_setUp(self): > + ? ?# the blocking constant should be tuned! > + ? ?self.blocking_timeout = 0.0 > + ? ?self.evt = threading.Event() > + ? ?self.dataq = Queue.Queue() > + ? ?self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) > + ? ?self.sock.settimeout(3) > + ? ?self.port = test_support.bind_port(self.sock) > + ? ?self.thread = threading.Thread(target=server, args=(self.evt,self.sock, self.dataq)) > + ? ?self.thread.start() > + ? ?self.evt.wait() > + ? ?self.evt.clear() > + ? ?time.sleep(.1) > + > +def _read_tearDown(self): > + ? ?self.evt.wait() > + ? ?self.thread.join() > + > + > +class ReadTests(TestCase): > + ? ?setUp = _read_setUp > + ? ?tearDown = _read_tearDown > + > + ? ?def _test_blocking(self, func): > + ? ? ? ?start = time.time() > + ? ? ? ?self.dataq.put(self.blocking_timeout) > + ? ? ? ?self.dataq.put(EOF_sigil) > + ? ? ? ?data = func() > + ? ? ? ?low, high = wibble_float(self.blocking_timeout) > + ? ? ? ?self.assertTrue(time.time() - start >= low) > + > + ? ?def test_read_until_A(self): > + ? ? ? ?""" > + ? ? ? ?read_until(expected, [timeout]) > + ? ? ? ? ?Read until the expected string has been seen, or a timeout is > + ? ? ? ? ?hit (default is no timeout); may block. > + ? ? ? ?""" > + ? ? ? ?want = ['x' * 10, 'match', 'y' * 10, EOF_sigil] > + ? ? ? ?for item in want: > + ? ? ? ? ? ?self.dataq.put(item) > + ? ? ? ?telnet = telnetlib.Telnet(HOST, self.port) > + ? ? ? ?data = telnet.read_until('match') > + ? ? ? ?self.assertEqual(data, ''.join(want[:-2])) > + > + ? ?def test_read_until_B(self): > + ? ? ? ?# test the timeout - it does NOT raise socket.timeout > + ? ? ? ?want = ['hello', self.blocking_timeout, EOF_sigil] > + ? ? ? ?for item in want: > + ? ? ? ? ? ?self.dataq.put(item) > + ? ? ? ?telnet = telnetlib.Telnet(HOST, self.port) > + ? ? ? ?start = time.time() > + ? ? ? ?timeout = self.blocking_timeout / 2 > + ? ? ? ?data = telnet.read_until('not seen', timeout) > + ? ? ? ?low, high = wibble_float(timeout) > + ? ? ? ?self.assertTrue(low <= time.time() - high) > + ? ? ? ?self.assertEqual(data, want[0]) > + > + ? ?def test_read_all_A(self): > + ? ? ? ?""" > + ? ? ? ?read_all() > + ? ? ? ? ?Read all data until EOF; may block. > + ? ? ? ?""" > + ? ? ? ?want = ['x' * 500, 'y' * 500, 'z' * 500, EOF_sigil] > + ? ? ? ?for item in want: > + ? ? ? ? ? ?self.dataq.put(item) > + ? ? ? ?telnet = telnetlib.Telnet(HOST, self.port) > + ? ? ? ?data = telnet.read_all() > + ? ? ? ?self.assertEqual(data, ''.join(want[:-1])) > + ? ? ? ?return > + > + ? ?def test_read_all_B(self): > + ? ? ? ?self._test_blocking(telnetlib.Telnet(HOST, self.port).read_all) > + > + ? ?def test_read_some_A(self): > + ? ? ? ?""" > + ? ? ? ?read_some() > + ? ? ? ? ?Read at least one byte or EOF; may block. > + ? ? ? ?""" > + ? ? ? ?# test 'at least one byte' > + ? ? ? ?want = ['x' * 500, EOF_sigil] > + ? ? ? ?for item in want: > + ? ? ? ? ? ?self.dataq.put(item) > + ? ? ? ?telnet = telnetlib.Telnet(HOST, self.port) > + ? ? ? ?data = telnet.read_all() > + ? ? ? ?self.assertTrue(len(data) >= 1) > + > + ? ?def test_read_some_B(self): > + ? ? ? ?# test EOF > + ? ? ? ?self.dataq.put(EOF_sigil) > + ? ? ? ?telnet = telnetlib.Telnet(HOST, self.port) > + ? ? ? ?self.assertEqual('', telnet.read_some()) > + > + ? ?def test_read_all_C(self): > + ? ? ? ?self._test_blocking(telnetlib.Telnet(HOST, self.port).read_some) > + > + ? ?def _test_read_any_eager_A(self, func_name): > + ? ? ? ?""" > + ? ? ? ?read_very_eager() > + ? ? ? ? ?Read all data available already queued or on the socket, > + ? ? ? ? ?without blocking. > + ? ? ? ?""" > + ? ? ? ?# this never blocks so it should return eat part in turn > + ? ? ? ?want = ['x' * 100, self.blocking_timeout/2, 'y' * 100, EOF_sigil] > + ? ? ? ?expects = want[0] + want[2] > + ? ? ? ?for item in want: > + ? ? ? ? ? ?self.dataq.put(item) > + ? ? ? ?telnet = telnetlib.Telnet(HOST, self.port) > + ? ? ? ?func = getattr(telnet, func_name) > + ? ? ? ?time.sleep(self.blocking_timeout/10) > + ? ? ? ?data = '' > + ? ? ? ?while True: > + ? ? ? ? ? ?try: > + ? ? ? ? ? ? ? ?data += func() > + ? ? ? ? ? ? ? ?self.assertTrue(expects.startswith(data)) > + ? ? ? ? ? ? ? ?time.sleep(self.blocking_timeout) > + ? ? ? ? ? ?except EOFError: > + ? ? ? ? ? ? ? ?break > + ? ? ? ?self.assertEqual(expects, data) > + > + ? ?def _test_read_any_eager_B(self, func_name): > + ? ? ? ?# test EOF > + ? ? ? ?self.dataq.put(EOF_sigil) > + ? ? ? ?time.sleep(self.blocking_timeout / 10) > + ? ? ? ?telnet = telnetlib.Telnet(HOST, self.port) > + ? ? ? ?func = getattr(telnet, func_name) > + ? ? ? ?self.assertRaises(EOFError, func) > + > + ? ?# read_eager and read_very_eager make the same gaurantees > + ? ?# (they behave differently but we only test the gaurantees) > + ? ?def test_read_very_eager_A(self): > + ? ? ? ?self._test_read_any_eager_A('read_very_eager') > + ? ?def test_read_very_eager_B(self): > + ? ? ? ?self._test_read_any_eager_B('read_very_eager') > + ? ?def test_read_eager_A(self): > + ? ? ? ?self._test_read_any_eager_A('read_eager') > + ? ?def test_read_eager_B(self): > + ? ? ? ?self._test_read_any_eager_B('read_eager') > + ? ?# NB -- we need to test the IAC block which is mentioned in the docstring > + ? ?# but not in the module docs > + > + ? ?def _test_read_any_lazy_A(self, func_name): > + ? ? ? ?want = [self.blocking_timeout/2, 'x' * 100, EOF_sigil] > + ? ? ? ?for item in want: > + ? ? ? ? ? ?self.dataq.put(item) > + ? ? ? ?telnet = telnetlib.Telnet(HOST, self.port) > + ? ? ? ?func = getattr(telnet, func_name) > + ? ? ? ?self.assertEqual('', func()) > + ? ? ? ?data = '' > + ? ? ? ?while True: > + ? ? ? ? ? ?time.sleep(self.blocking_timeout) > + ? ? ? ? ? ?try: > + ? ? ? ? ? ? ? ?telnet.fill_rawq() > + ? ? ? ? ? ? ? ?data += func() > + ? ? ? ? ? ? ? ?if not data: > + ? ? ? ? ? ? ? ? ? ?break > + ? ? ? ? ? ?except EOFError: > + ? ? ? ? ? ? ? ?break > + ? ? ? ? ? ?self.assertTrue(want[1].startswith(data)) > + ? ? ? ?return data, want[1] > + > + ? ?def _test_read_any_lazy_B(self, func_name): > + ? ? ? ?self.dataq.put(EOF_sigil) > + ? ? ? ?telnet = telnetlib.Telnet(HOST, self.port) > + ? ? ? ?func = getattr(telnet, func_name) > + ? ? ? ?time.sleep(self.blocking_timeout/10) > + ? ? ? ?telnet.fill_rawq() > + ? ? ? ?self.assertRaises(EOFError, func) > + > + ? ?# read_lazy and read_very_lazy make the samish gaurantees > + ? ?def test_read_very_lazy_A(self): > + ? ? ? ?data, want = self._test_read_any_lazy_A('read_very_lazy') > + ? ? ? ?self.assertEqual(data, '') > + ? ?def test_read_lazy(self): > + ? ? ? ?data, want = self._test_read_any_lazy_A('read_lazy') > + ? ? ? ?self.assertEqual(data, want) > + ? ?def test_read_very_lazy_B(self): > + ? ? ? ?self._test_read_any_lazy_B('read_very_lazy') > + ? ?def test_read_lazy_B(self): > + ? ? ? ?self._test_read_any_lazy_B('read_lazy') > + > +class nego_collector(object): > + ? ?def __init__(self, sb_getter=None): > + ? ? ? ?self.seen = '' > + ? ? ? ?self.sb_getter = sb_getter > + ? ? ? ?self.sb_seen = '' > + > + ? ?def do_nego(self, sock, cmd, opt): > + ? ? ? ?self.seen += cmd + opt > + ? ? ? ?if cmd == tl.SE and self.sb_getter: > + ? ? ? ? ? ?sb_data = self.sb_getter() > + ? ? ? ? ? ?self.sb_seen += sb_data > + > +tl = telnetlib > +class OptionTests(TestCase): > + ? ?setUp = _read_setUp > + ? ?tearDown = _read_tearDown > + ? ?# RFC 854 commands > + ? ?cmds = [tl.AO, tl.AYT, tl.BRK, tl.EC, tl.EL, tl.GA, tl.IP, tl.NOP] > + > + ? ?def _test_command(self, data): > + ? ? ? ?""" helper for testing IAC + cmd """ > + ? ? ? ?self.setUp() > + ? ? ? ?for item in data: > + ? ? ? ? ? ?self.dataq.put(item) > + ? ? ? ?telnet = telnetlib.Telnet(HOST, self.port) > + ? ? ? ?nego = nego_collector() > + ? ? ? ?telnet.set_option_negotiation_callback(nego.do_nego) > + ? ? ? ?time.sleep(self.blocking_timeout/10) > + ? ? ? ?txt = telnet.read_all() > + ? ? ? ?cmd = nego.seen > + ? ? ? ?self.assertTrue(len(cmd) > 0) # we expect at least one command > + ? ? ? ?self.assertTrue(cmd[0] in self.cmds) > + ? ? ? ?self.assertEqual(cmd[1], tl.NOOPT) > + ? ? ? ?self.assertEqual(len(''.join(data[:-1])), len(txt + cmd)) > + ? ? ? ?self.tearDown() > + > + ? ?def test_IAC_commands(self): > + ? ? ? ?# reset our setup > + ? ? ? ?self.dataq.put(EOF_sigil) > + ? ? ? ?telnet = telnetlib.Telnet(HOST, self.port) > + ? ? ? ?self.tearDown() > + > + ? ? ? ?for cmd in self.cmds: > + ? ? ? ? ? ?self._test_command(['x' * 100, tl.IAC + cmd, 'y'*100, EOF_sigil]) > + ? ? ? ? ? ?self._test_command(['x' * 10, tl.IAC + cmd, 'y'*10, EOF_sigil]) > + ? ? ? ? ? ?self._test_command([tl.IAC + cmd, EOF_sigil]) > + ? ? ? ?# all at once > + ? ? ? ?self._test_command([tl.IAC + cmd for (cmd) in self.cmds] + [EOF_sigil]) > + > + ? ?def test_SB_commands(self): > + ? ? ? ?# RFC 855, subnegotiations portion > + ? ? ? ?send = [tl.IAC + tl.SB + tl.IAC + tl.SE, > + ? ? ? ? ? ? ? ?tl.IAC + tl.SB + tl.IAC + tl.IAC + tl.IAC + tl.SE, > + ? ? ? ? ? ? ? ?tl.IAC + tl.SB + tl.IAC + tl.IAC + 'aa' + tl.IAC + tl.SE, > + ? ? ? ? ? ? ? ?tl.IAC + tl.SB + 'bb' + tl.IAC + tl.IAC + tl.IAC + tl.SE, > + ? ? ? ? ? ? ? ?tl.IAC + tl.SB + 'cc' + tl.IAC + tl.IAC + 'dd' + tl.IAC + tl.SE, > + ? ? ? ? ? ? ? ?EOF_sigil, > + ? ? ? ? ? ? ? ] > + ? ? ? ?for item in send: > + ? ? ? ? ? ?self.dataq.put(item) > + ? ? ? ?telnet = telnetlib.Telnet(HOST, self.port) > + ? ? ? ?nego = nego_collector(telnet.read_sb_data) > + ? ? ? ?telnet.set_option_negotiation_callback(nego.do_nego) > + ? ? ? ?time.sleep(self.blocking_timeout/10) > + ? ? ? ?txt = telnet.read_all() > + ? ? ? ?self.assertEqual(txt, '') > + ? ? ? ?want_sb_data = tl.IAC + tl.IAC + 'aabb' + tl.IAC + 'cc' + tl.IAC + 'dd' > + ? ? ? ?self.assertEqual(nego.sb_seen, want_sb_data) > > ?def test_main(verbose=None): > - ? ?test_support.run_unittest(GeneralTests) > + ? ?test_support.run_unittest(GeneralTests, ReadTests, OptionTests) > > ?if __name__ == '__main__': > ? ? test_main() > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > http://mail.python.org/mailman/listinfo/python-checkins > From benjamin at python.org Mon Apr 6 05:02:28 2009 From: benjamin at python.org (Benjamin Peterson) Date: Sun, 5 Apr 2009 22:02:28 -0500 Subject: [Python-checkins] r71302 - python/trunk/Lib/test/test_telnetlib.py In-Reply-To: References: <20090406020845.3583C1E4002@bag.python.org> Message-ID: <1afaf6160904052002q1ce0b951l8cea65583a37fff0@mail.gmail.com> 2009/4/5 Jack diederich : > I haven't tried this patch on 3.x yet. ?I expect it will explode badly > due to bytes/str confusion. ? I'll figure that stuff out once I have > telnetlib in slightly less sorry shape. I'll just let you figure out how to merge it then. :) -- Regards, Benjamin From buildbot at python.org Mon Apr 6 06:15:55 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 06 Apr 2009 04:15:55 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090406041555.EF88E1E401C@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/541 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: The web-page 'force build' button was pressed by 'Eric Smith': Test repr change branch Build Source Stamp: [branch branches/py3k-short-float-repr] HEAD Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Mon Apr 6 06:57:42 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 06 Apr 2009 04:57:42 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090406045742.6D12E1E401C@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/492 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 249, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 102, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Mon Apr 6 08:33:26 2009 From: python-checkins at python.org (gregory.p.smith) Date: Mon, 6 Apr 2009 08:33:26 +0200 (CEST) Subject: [Python-checkins] r71303 - in python/trunk: Lib/CGIHTTPServer.py Lib/test/test_httpservers.py Misc/NEWS Message-ID: <20090406063326.9572F1E40CC@bag.python.org> Author: gregory.p.smith Date: Mon Apr 6 08:33:26 2009 New Revision: 71303 Log: - Issue #2254: Fix CGIHTTPServer information disclosure. Relative paths are now collapsed within the url properly before looking in cgi_directories. Modified: python/trunk/Lib/CGIHTTPServer.py python/trunk/Lib/test/test_httpservers.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/CGIHTTPServer.py ============================================================================== --- python/trunk/Lib/CGIHTTPServer.py (original) +++ python/trunk/Lib/CGIHTTPServer.py Mon Apr 6 08:33:26 2009 @@ -70,27 +70,20 @@ return SimpleHTTPServer.SimpleHTTPRequestHandler.send_head(self) def is_cgi(self): - """Test whether self.path corresponds to a CGI script, - and return a boolean. + """Test whether self.path corresponds to a CGI script. - This function sets self.cgi_info to a tuple (dir, rest) - when it returns True, where dir is the directory part before - the CGI script name. Note that rest begins with a - slash if it is not empty. - - The default implementation tests whether the path - begins with one of the strings in the list - self.cgi_directories (and the next character is a '/' - or the end of the string). + Returns True and updates the cgi_info attribute to the tuple + (dir, rest) if self.path requires running a CGI script. + Returns False otherwise. + + The default implementation tests whether the normalized url + path begins with one of the strings in self.cgi_directories + (and the next character is a '/' or the end of the string). """ - - path = self.path - - for x in self.cgi_directories: - i = len(x) - if path[:i] == x and (not path[i:] or path[i] == '/'): - self.cgi_info = path[:i], path[i+1:] - return True + splitpath = _url_collapse_path_split(self.path) + if splitpath[0] in self.cgi_directories: + self.cgi_info = splitpath + return True return False cgi_directories = ['/cgi-bin', '/htbin'] @@ -330,6 +323,46 @@ self.log_message("CGI script exited OK") +# TODO(gregory.p.smith): Move this into an appropriate library. +def _url_collapse_path_split(path): + """ + Given a URL path, remove extra '/'s and '.' path elements and collapse + any '..' references. + + Implements something akin to RFC-2396 5.2 step 6 to parse relative paths. + + Returns: A tuple of (head, tail) where tail is everything after the final / + and head is everything before it. Head will always start with a '/' and, + if it contains anything else, never have a trailing '/'. + + Raises: IndexError if too many '..' occur within the path. + """ + # Similar to os.path.split(os.path.normpath(path)) but specific to URL + # path semantics rather than local operating system semantics. + path_parts = [] + for part in path.split('/'): + if part == '.': + path_parts.append('') + else: + path_parts.append(part) + # Filter out blank non trailing parts before consuming the '..'. + path_parts = [part for part in path_parts[:-1] if part] + path_parts[-1:] + if path_parts: + tail_part = path_parts.pop() + else: + tail_part = '' + head_parts = [] + for part in path_parts: + if part == '..': + head_parts.pop() + else: + head_parts.append(part) + if tail_part and tail_part == '..': + head_parts.pop() + tail_part = '' + return ('/' + '/'.join(head_parts), tail_part) + + nobody = None def nobody_uid(): Modified: python/trunk/Lib/test/test_httpservers.py ============================================================================== --- python/trunk/Lib/test/test_httpservers.py (original) +++ python/trunk/Lib/test/test_httpservers.py Mon Apr 6 08:33:26 2009 @@ -7,6 +7,7 @@ from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer from SimpleHTTPServer import SimpleHTTPRequestHandler from CGIHTTPServer import CGIHTTPRequestHandler +import CGIHTTPServer import os import sys @@ -315,6 +316,45 @@ finally: BaseTestCase.tearDown(self) + def test_url_collapse_path_split(self): + test_vectors = { + '': ('/', ''), + '..': IndexError, + '/.//..': IndexError, + '/': ('/', ''), + '//': ('/', ''), + '/\\': ('/', '\\'), + '/.//': ('/', ''), + 'cgi-bin/file1.py': ('/cgi-bin', 'file1.py'), + '/cgi-bin/file1.py': ('/cgi-bin', 'file1.py'), + 'a': ('/', 'a'), + '/a': ('/', 'a'), + '//a': ('/', 'a'), + './a': ('/', 'a'), + './C:/': ('/C:', ''), + '/a/b': ('/a', 'b'), + '/a/b/': ('/a/b', ''), + '/a/b/c/..': ('/a/b', ''), + '/a/b/c/../d': ('/a/b', 'd'), + '/a/b/c/../d/e/../f': ('/a/b/d', 'f'), + '/a/b/c/../d/e/../../f': ('/a/b', 'f'), + '/a/b/c/../d/e/.././././..//f': ('/a/b', 'f'), + '../a/b/c/../d/e/.././././..//f': IndexError, + '/a/b/c/../d/e/../../../f': ('/a', 'f'), + '/a/b/c/../d/e/../../../../f': ('/', 'f'), + '/a/b/c/../d/e/../../../../../f': IndexError, + '/a/b/c/../d/e/../../../../f/..': ('/', ''), + } + for path, expected in test_vectors.iteritems(): + if isinstance(expected, type) and issubclass(expected, Exception): + self.assertRaises(expected, + CGIHTTPServer._url_collapse_path_split, path) + else: + actual = CGIHTTPServer._url_collapse_path_split(path) + self.assertEquals(expected, actual, + msg='path = %r\nGot: %r\nWanted: %r' % ( + path, actual, expected)) + def test_headers_and_content(self): res = self.request('/cgi-bin/file1.py') self.assertEquals(('Hello World\n', 'text/html', 200), \ @@ -339,6 +379,12 @@ self.assertEquals(('Hello World\n', 'text/html', 200), \ (res.read(), res.getheader('Content-type'), res.status)) + def test_no_leading_slash(self): + # http://bugs.python.org/issue2254 + res = self.request('cgi-bin/file1.py') + self.assertEquals(('Hello World\n', 'text/html', 200), + (res.read(), res.getheader('Content-type'), res.status)) + def test_main(verbose=None): try: Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Apr 6 08:33:26 2009 @@ -216,6 +216,9 @@ Library ------- +- Issue #2254: Fix CGIHTTPServer information disclosure. Relative paths are + now collapsed within the url properly before looking in cgi_directories. + - Issue #5095: Added bdist_msi to the list of bdist supported formats. Initial fix by Steven Bethard. From python-checkins at python.org Mon Apr 6 08:47:37 2009 From: python-checkins at python.org (gregory.p.smith) Date: Mon, 6 Apr 2009 08:47:37 +0200 (CEST) Subject: [Python-checkins] r71304 - in python/branches/release26-maint: Lib/test/test_os.py Misc/NEWS Modules/posixmodule.c Message-ID: <20090406064737.C6D081E4016@bag.python.org> Author: gregory.p.smith Date: Mon Apr 6 08:47:37 2009 New Revision: 71304 Log: Merged revisions 71299 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71299 | gregory.p.smith | 2009-04-05 16:43:58 -0700 (Sun, 05 Apr 2009) | 3 lines Fixes issue5705: os.setuid() and friends did not accept the same range of values that pwd.getpwnam() returns. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_os.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Modules/posixmodule.c Modified: python/branches/release26-maint/Lib/test/test_os.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_os.py (original) +++ python/branches/release26-maint/Lib/test/test_os.py Mon Apr 6 08:47:37 2009 @@ -600,6 +600,48 @@ class Win32ErrorTests(unittest.TestCase): pass + class PosixUidGidTests(unittest.TestCase): + if hasattr(os, 'setuid'): + def test_setuid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setuid, 0) + self.assertRaises(OverflowError, os.setuid, 1<<32) + + if hasattr(os, 'setgid'): + def test_setgid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setgid, 0) + self.assertRaises(OverflowError, os.setgid, 1<<32) + + if hasattr(os, 'seteuid'): + def test_seteuid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.seteuid, 0) + self.assertRaises(OverflowError, os.seteuid, 1<<32) + + if hasattr(os, 'setegid'): + def test_setegid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setegid, 0) + self.assertRaises(OverflowError, os.setegid, 1<<32) + + if hasattr(os, 'setreuid'): + def test_setreuid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setreuid, 0, 0) + self.assertRaises(OverflowError, os.setreuid, 1<<32, 0) + self.assertRaises(OverflowError, os.setreuid, 0, 1<<32) + + if hasattr(os, 'setregid'): + def test_setregid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setregid, 0, 0) + self.assertRaises(OverflowError, os.setregid, 1<<32, 0) + self.assertRaises(OverflowError, os.setregid, 0, 1<<32) +else: + class PosixUidGidTests(unittest.TestCase): + pass + def test_main(): test_support.run_unittest( FileTests, @@ -611,7 +653,8 @@ DevNullTests, URandomTests, Win32ErrorTests, - TestInvalidFD + TestInvalidFD, + PosixUidGidTests ) if __name__ == "__main__": Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Mon Apr 6 08:47:37 2009 @@ -97,6 +97,9 @@ - Issue #3845: In PyRun_SimpleFileExFlags avoid invalid memory access with short file names. +- Issue #5705: os.setuid() would not accept values > 2**31-1 but pwd.getpwnam() + returned them on 64bit platforms. + Library ------- Modified: python/branches/release26-maint/Modules/posixmodule.c ============================================================================== --- python/branches/release26-maint/Modules/posixmodule.c (original) +++ python/branches/release26-maint/Modules/posixmodule.c Mon Apr 6 08:47:37 2009 @@ -5505,9 +5505,15 @@ static PyObject * posix_setuid(PyObject *self, PyObject *args) { - int uid; - if (!PyArg_ParseTuple(args, "i:setuid", &uid)) + long uid_arg; + uid_t uid; + if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg)) + return NULL; + uid = uid_arg; + if (uid != uid_arg) { + PyErr_SetString(PyExc_OverflowError, "user id too big"); return NULL; + } if (setuid(uid) < 0) return posix_error(); Py_INCREF(Py_None); @@ -5524,10 +5530,16 @@ static PyObject * posix_seteuid (PyObject *self, PyObject *args) { - int euid; - if (!PyArg_ParseTuple(args, "i", &euid)) { + long euid_arg; + uid_t euid; + if (!PyArg_ParseTuple(args, "l", &euid_arg)) + return NULL; + euid = euid_arg; + if (euid != euid_arg) { + PyErr_SetString(PyExc_OverflowError, "user id too big"); return NULL; - } else if (seteuid(euid) < 0) { + } + if (seteuid(euid) < 0) { return posix_error(); } else { Py_INCREF(Py_None); @@ -5544,10 +5556,16 @@ static PyObject * posix_setegid (PyObject *self, PyObject *args) { - int egid; - if (!PyArg_ParseTuple(args, "i", &egid)) { + long egid_arg; + gid_t egid; + if (!PyArg_ParseTuple(args, "l", &egid_arg)) return NULL; - } else if (setegid(egid) < 0) { + egid = egid_arg; + if (egid != egid_arg) { + PyErr_SetString(PyExc_OverflowError, "group id too big"); + return NULL; + } + if (setegid(egid) < 0) { return posix_error(); } else { Py_INCREF(Py_None); @@ -5564,10 +5582,17 @@ static PyObject * posix_setreuid (PyObject *self, PyObject *args) { - int ruid, euid; - if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) { + long ruid_arg, euid_arg; + uid_t ruid, euid; + if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg)) return NULL; - } else if (setreuid(ruid, euid) < 0) { + ruid = ruid_arg; + euid = euid_arg; + if (euid != euid_arg || ruid != ruid_arg) { + PyErr_SetString(PyExc_OverflowError, "user id too big"); + return NULL; + } + if (setreuid(ruid, euid) < 0) { return posix_error(); } else { Py_INCREF(Py_None); @@ -5584,10 +5609,17 @@ static PyObject * posix_setregid (PyObject *self, PyObject *args) { - int rgid, egid; - if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) { + long rgid_arg, egid_arg; + gid_t rgid, egid; + if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg)) + return NULL; + rgid = rgid_arg; + egid = egid_arg; + if (egid != egid_arg || rgid != rgid_arg) { + PyErr_SetString(PyExc_OverflowError, "group id too big"); return NULL; - } else if (setregid(rgid, egid) < 0) { + } + if (setregid(rgid, egid) < 0) { return posix_error(); } else { Py_INCREF(Py_None); @@ -5604,9 +5636,15 @@ static PyObject * posix_setgid(PyObject *self, PyObject *args) { - int gid; - if (!PyArg_ParseTuple(args, "i:setgid", &gid)) + long gid_arg; + gid_t gid; + if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg)) + return NULL; + gid = gid_arg; + if (gid != gid_arg) { + PyErr_SetString(PyExc_OverflowError, "group id too big"); return NULL; + } if (setgid(gid) < 0) return posix_error(); Py_INCREF(Py_None); @@ -5654,7 +5692,7 @@ return NULL; } grouplist[i] = x; - /* read back the value to see if it fitted in gid_t */ + /* read back to see if it fits in gid_t */ if (grouplist[i] != x) { PyErr_SetString(PyExc_TypeError, "group id too big"); From buildbot at python.org Mon Apr 6 09:31:06 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 06 Apr 2009 07:31:06 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 2.6 Message-ID: <20090406073107.308431E43FA@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%20gentoo%202.6/builds/209 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-amd64 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: gregory.p.smith,hirokazu.yamamoto BUILD FAILED: failed test Excerpt from the test logfile: 3 tests failed: test_generators test_genexps test_syntax make: *** [buildbottest] Error 1 sincerely, -The Buildbot From nnorwitz at gmail.com Mon Apr 6 10:10:57 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 6 Apr 2009 04:10:57 -0400 Subject: [Python-checkins] Python Regression Test Failures basics (7) Message-ID: <20090406081057.GA22466@python.psfb.org> 327 tests OK. 7 tests failed: test_asyncore test_generators test_genexps test_lib2to3 test_multiprocessing test_syntax test_telnetlib 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ast test_asynchat test_asyncore test test_asyncore failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_asyncore.py", line 144, in test_readwrite self.assertEqual(tobj.read, True) AssertionError: False != True 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils 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_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_gdbm test_generators ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: f=lambda: (yield 1),(yield 2) Expected: Traceback (most recent call last): ... SyntaxError: 'yield' outside function (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: 'yield' outside function ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): x = yield = y Expected: Traceback (most recent call last): ... SyntaxError: assignment to yield expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: assignment to yield expression not possible ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): (yield bar) = y Expected: Traceback (most recent call last): ... SyntaxError: can't assign to yield expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to yield expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): (yield bar) += y Expected: Traceback (most recent call last): ... SyntaxError: augmented assignment to yield expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to yield expression not possible ********************************************************************** 1 items had failures: 4 of 99 in test.test_generators.__test__.coroutine ***Test Failed*** 4 failures. test test_generators failed -- 4 of 284 doctests failed test_genericpath test_genexps ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_genexps.py", line ?, in test.test_genexps.__test__.doctests Failed example: (y for y in (1,2)) = 10 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to generator expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to generator expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_genexps.py", line ?, in test.test_genexps.__test__.doctests Failed example: (y for y in (1,2)) += 10 Expected: Traceback (most recent call last): ... SyntaxError: augmented assignment to generator expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to generator expression not possible ********************************************************************** 1 items had failures: 2 of 75 in test.test_genexps.__test__.doctests ***Test Failed*** 2 failures. test test_genexps failed -- 2 of 75 doctests failed 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 [13183 refs] [13183 refs] [13183 refs] [23375 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 test_lib2to3 crashed -- : No module named myfixes 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 test_multiprocessing crashed -- : cannot import name SkipTest test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18903 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 30, in test.test_syntax Failed example: obj.None = 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 34, in test.test_syntax Failed example: None = 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 42, in test.test_syntax Failed example: () = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to () (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to () ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 46, in test.test_syntax Failed example: f() = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to function call (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 50, in test.test_syntax Failed example: del f() Expected: Traceback (most recent call last): SyntaxError: can't delete function call (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't delete function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 54, in test.test_syntax Failed example: a + 1 = 2 Expected: Traceback (most recent call last): SyntaxError: can't assign to operator (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to operator ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 58, in test.test_syntax Failed example: (x for x in x) = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to generator expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to generator expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 62, in test.test_syntax Failed example: 1 = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 66, in test.test_syntax Failed example: "abc" = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 70, in test.test_syntax Failed example: `1` = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to repr (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to repr ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 79, in test.test_syntax Failed example: (a, "b", c) = (1, 2, 3) Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 83, in test.test_syntax Failed example: [a, b, c + 1] = [1, 2, 3] Expected: Traceback (most recent call last): SyntaxError: can't assign to operator (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to operator ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 87, in test.test_syntax Failed example: a if 1 else b = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to conditional expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to conditional expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 93, in test.test_syntax Failed example: def f(None=1): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 101, in test.test_syntax Failed example: def f(x, y=1, z): pass Expected: Traceback (most recent call last): SyntaxError: non-default argument follows default argument (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: non-default argument follows default argument ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 106, in test.test_syntax Failed example: def f(x, None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 111, in test.test_syntax Failed example: def f(*None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 116, in test.test_syntax Failed example: def f(**None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 124, in test.test_syntax Failed example: def None(x): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 137, in test.test_syntax Failed example: f(x for x in L, 1) Expected: Traceback (most recent call last): SyntaxError: Generator expression must be parenthesized if not sole argument (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: Generator expression must be parenthesized if not sole argument ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 143, in test.test_syntax Failed example: f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, i121, i122, i123, i124, i125, i126, i127, i128, i129, i130, i131, i132, i133, i134, i135, i136, i137, i138, i139, i140, i141, i142, i143, i144, i145, i146, i147, i148, i149, i150, i151, i152, i153, i154, i155, i156, i157, i158, i159, i160, i161, i162, i163, i164, i165, i166, i167, i168, i169, i170, i171, i172, i173, i174, i175, i176, i177, i178, i179, i180, i181, i182, i183, i184, i185, i186, i187, i188, i189, i190, i191, i192, i193, i194, i195, i196, i197, i198, i199, i200, i201, i202, i203, i204, i205, i206, i207, i208, i209, i210, i211, i212, i213, i214, i215, i216, i217, i218, i219, i220, i221, i222, i223, i224, i225, i226, i227, i228, i229, i230, i231, i232, i233, i234, i235, i236, i237, i238, i239, i240, i241, i242, i243, i244, i245, i246, i247, i248, i249, i250, i251, i252, i253, i254, i255) Expected: Traceback (most recent call last): SyntaxError: more than 255 arguments (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: more than 255 arguments ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 177, in test.test_syntax Failed example: f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, i121, i122, i123, i124, i125, i126, i127, i128, i129, i130, i131, i132, i133, i134, i135, i136, i137, i138, i139, i140, i141, i142, i143, i144, i145, i146, i147, i148, i149, i150, i151, i152, i153, i154, i155, i156, i157, i158, i159, i160, i161, i162, i163, i164, i165, i166, i167, i168, i169, i170, i171, i172, i173, i174, i175, i176, i177, i178, i179, i180, i181, i182, i183, i184, i185, i186, i187, i188, i189, i190, i191, i192, i193, i194, i195, i196, i197, i198, i199, i200, i201, i202, i203, i204, i205, i206, i207, i208, i209, i210, i211, i212, i213, i214, i215, i216, i217, i218, i219, i220, i221, i222, i223, i224, i225, i226, i227, i228, i229, i230, i231, i232, i233, i234, i235, i236, i237, i238, i239, i240, i241, i242, i243, (x for x in i244), i245, i246, i247, i248, i249, i250, i251, i252=1, i253=1, i254=1, i255=1) Expected: Traceback (most recent call last): SyntaxError: more than 255 arguments (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: more than 255 arguments ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 207, in test.test_syntax Failed example: f(lambda x: x[0] = 3) Expected: Traceback (most recent call last): SyntaxError: lambda cannot contain assignment (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: lambda cannot contain assignment ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 214, in test.test_syntax Failed example: f(x()=2) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 217, in test.test_syntax Failed example: f(a or b=1) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 220, in test.test_syntax Failed example: f(x.y=1) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 227, in test.test_syntax Failed example: (x for x in x) += 1 Expected: Traceback (most recent call last): SyntaxError: augmented assignment to generator expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to generator expression not possible ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 230, in test.test_syntax Failed example: None += 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 233, in test.test_syntax Failed example: f() += 1 Expected: Traceback (most recent call last): SyntaxError: illegal expression for augmented assignment (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: illegal expression for augmented assignment ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 254, in test.test_syntax Failed example: def test(): for abc in range(10): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 266, in test.test_syntax Failed example: def test(): for abc in range(10): try: pass finally: try: continue except: pass Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 7) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 7 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 279, in test.test_syntax Failed example: def foo(): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 5) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 5 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 288, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 298, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: try: continue finally: pass Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 7) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 7 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 311, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: try: pass except: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 8) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 8 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 328, in test.test_syntax Failed example: try: print 1 break print 2 finally: print 3 Expected: Traceback (most recent call last): ... SyntaxError: 'break' outside loop (, line 3) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 3 SyntaxError: 'break' outside loop ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 372, in test.test_syntax Failed example: if 1: x() = 1 elif 1: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 2) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 2 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 380, in test.test_syntax Failed example: if 1: pass elif 1: x() = 1 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 4) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 4 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 388, in test.test_syntax Failed example: if 1: x() = 1 elif 1: pass else: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 2) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 2 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 398, in test.test_syntax Failed example: if 1: pass elif 1: x() = 1 else: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 4) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 4 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 408, in test.test_syntax Failed example: if 1: pass elif 1: pass else: x() = 1 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 418, in test.test_syntax Failed example: f(a=23, a=234) Expected: Traceback (most recent call last): ... SyntaxError: keyword argument repeated (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword argument repeated ********************************************************************** 1 items had failures: 42 of 50 in test.test_syntax ***Test Failed*** 42 failures. test test_syntax failed -- 42 of 50 doctests failed test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test test_telnetlib failed -- errors occurred; run in verbose mode for details test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18896 refs] [17873 refs] [17873 refs] [17873 refs] [17873 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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_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 327 tests OK. 7 tests failed: test_asyncore test_generators test_genexps test_lib2to3 test_multiprocessing test_syntax test_telnetlib 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl [701506 refs] From nnorwitz at gmail.com Mon Apr 6 10:18:22 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 6 Apr 2009 04:18:22 -0400 Subject: [Python-checkins] Python Regression Test Failures opt (7) Message-ID: <20090406081822.GA24896@python.psfb.org> 327 tests OK. 7 tests failed: test_asyncore test_generators test_genexps test_lib2to3 test_multiprocessing test_syntax test_telnetlib 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ast test_asynchat test_asyncore test test_asyncore failed -- errors occurred; run in verbose mode for details 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils [17363 refs] [17363 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_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_gdbm test_generators ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: f=lambda: (yield 1),(yield 2) Expected: Traceback (most recent call last): ... SyntaxError: 'yield' outside function (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: 'yield' outside function ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): x = yield = y Expected: Traceback (most recent call last): ... SyntaxError: assignment to yield expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: assignment to yield expression not possible ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): (yield bar) = y Expected: Traceback (most recent call last): ... SyntaxError: can't assign to yield expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to yield expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): (yield bar) += y Expected: Traceback (most recent call last): ... SyntaxError: augmented assignment to yield expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to yield expression not possible ********************************************************************** 1 items had failures: 4 of 99 in test.test_generators.__test__.coroutine ***Test Failed*** 4 failures. test test_generators failed -- 4 of 284 doctests failed test_genericpath test_genexps ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_genexps.py", line ?, in test.test_genexps.__test__.doctests Failed example: (y for y in (1,2)) = 10 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to generator expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to generator expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_genexps.py", line ?, in test.test_genexps.__test__.doctests Failed example: (y for y in (1,2)) += 10 Expected: Traceback (most recent call last): ... SyntaxError: augmented assignment to generator expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to generator expression not possible ********************************************************************** 1 items had failures: 2 of 75 in test.test_genexps.__test__.doctests ***Test Failed*** 2 failures. test test_genexps failed -- 2 of 75 doctests failed 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 [13183 refs] [13183 refs] [13183 refs] [23375 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 test_lib2to3 crashed -- : No module named myfixes 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 test_multiprocessing crashed -- : cannot import name SkipTest test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18903 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 30, in test.test_syntax Failed example: obj.None = 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 34, in test.test_syntax Failed example: None = 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 42, in test.test_syntax Failed example: () = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to () (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to () ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 46, in test.test_syntax Failed example: f() = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to function call (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 50, in test.test_syntax Failed example: del f() Expected: Traceback (most recent call last): SyntaxError: can't delete function call (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't delete function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 54, in test.test_syntax Failed example: a + 1 = 2 Expected: Traceback (most recent call last): SyntaxError: can't assign to operator (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to operator ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 58, in test.test_syntax Failed example: (x for x in x) = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to generator expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to generator expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 62, in test.test_syntax Failed example: 1 = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 66, in test.test_syntax Failed example: "abc" = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 70, in test.test_syntax Failed example: `1` = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to repr (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to repr ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 79, in test.test_syntax Failed example: (a, "b", c) = (1, 2, 3) Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 83, in test.test_syntax Failed example: [a, b, c + 1] = [1, 2, 3] Expected: Traceback (most recent call last): SyntaxError: can't assign to operator (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to operator ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 87, in test.test_syntax Failed example: a if 1 else b = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to conditional expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to conditional expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 93, in test.test_syntax Failed example: def f(None=1): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 101, in test.test_syntax Failed example: def f(x, y=1, z): pass Expected: Traceback (most recent call last): SyntaxError: non-default argument follows default argument (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: non-default argument follows default argument ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 106, in test.test_syntax Failed example: def f(x, None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 111, in test.test_syntax Failed example: def f(*None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 116, in test.test_syntax Failed example: def f(**None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 124, in test.test_syntax Failed example: def None(x): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 137, in test.test_syntax Failed example: f(x for x in L, 1) Expected: Traceback (most recent call last): SyntaxError: Generator expression must be parenthesized if not sole argument (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: Generator expression must be parenthesized if not sole argument ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 143, in test.test_syntax Failed example: f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, i121, i122, i123, i124, i125, i126, i127, i128, i129, i130, i131, i132, i133, i134, i135, i136, i137, i138, i139, i140, i141, i142, i143, i144, i145, i146, i147, i148, i149, i150, i151, i152, i153, i154, i155, i156, i157, i158, i159, i160, i161, i162, i163, i164, i165, i166, i167, i168, i169, i170, i171, i172, i173, i174, i175, i176, i177, i178, i179, i180, i181, i182, i183, i184, i185, i186, i187, i188, i189, i190, i191, i192, i193, i194, i195, i196, i197, i198, i199, i200, i201, i202, i203, i204, i205, i206, i207, i208, i209, i210, i211, i212, i213, i214, i215, i216, i217, i218, i219, i220, i221, i222, i223, i224, i225, i226, i227, i228, i229, i230, i231, i232, i233, i234, i235, i236, i237, i238, i239, i240, i241, i242, i243, i244, i245, i246, i247, i248, i249, i250, i251, i252, i253, i254, i255) Expected: Traceback (most recent call last): SyntaxError: more than 255 arguments (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: more than 255 arguments ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 177, in test.test_syntax Failed example: f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, i121, i122, i123, i124, i125, i126, i127, i128, i129, i130, i131, i132, i133, i134, i135, i136, i137, i138, i139, i140, i141, i142, i143, i144, i145, i146, i147, i148, i149, i150, i151, i152, i153, i154, i155, i156, i157, i158, i159, i160, i161, i162, i163, i164, i165, i166, i167, i168, i169, i170, i171, i172, i173, i174, i175, i176, i177, i178, i179, i180, i181, i182, i183, i184, i185, i186, i187, i188, i189, i190, i191, i192, i193, i194, i195, i196, i197, i198, i199, i200, i201, i202, i203, i204, i205, i206, i207, i208, i209, i210, i211, i212, i213, i214, i215, i216, i217, i218, i219, i220, i221, i222, i223, i224, i225, i226, i227, i228, i229, i230, i231, i232, i233, i234, i235, i236, i237, i238, i239, i240, i241, i242, i243, (x for x in i244), i245, i246, i247, i248, i249, i250, i251, i252=1, i253=1, i254=1, i255=1) Expected: Traceback (most recent call last): SyntaxError: more than 255 arguments (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: more than 255 arguments ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 207, in test.test_syntax Failed example: f(lambda x: x[0] = 3) Expected: Traceback (most recent call last): SyntaxError: lambda cannot contain assignment (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: lambda cannot contain assignment ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 214, in test.test_syntax Failed example: f(x()=2) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 217, in test.test_syntax Failed example: f(a or b=1) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 220, in test.test_syntax Failed example: f(x.y=1) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 227, in test.test_syntax Failed example: (x for x in x) += 1 Expected: Traceback (most recent call last): SyntaxError: augmented assignment to generator expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to generator expression not possible ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 230, in test.test_syntax Failed example: None += 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 233, in test.test_syntax Failed example: f() += 1 Expected: Traceback (most recent call last): SyntaxError: illegal expression for augmented assignment (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: illegal expression for augmented assignment ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 254, in test.test_syntax Failed example: def test(): for abc in range(10): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 266, in test.test_syntax Failed example: def test(): for abc in range(10): try: pass finally: try: continue except: pass Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 7) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 7 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 279, in test.test_syntax Failed example: def foo(): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 5) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 5 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 288, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 298, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: try: continue finally: pass Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 7) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 7 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 311, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: try: pass except: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 8) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 8 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 328, in test.test_syntax Failed example: try: print 1 break print 2 finally: print 3 Expected: Traceback (most recent call last): ... SyntaxError: 'break' outside loop (, line 3) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 3 SyntaxError: 'break' outside loop ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 372, in test.test_syntax Failed example: if 1: x() = 1 elif 1: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 2) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 2 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 380, in test.test_syntax Failed example: if 1: pass elif 1: x() = 1 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 4) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 4 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 388, in test.test_syntax Failed example: if 1: x() = 1 elif 1: pass else: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 2) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 2 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 398, in test.test_syntax Failed example: if 1: pass elif 1: x() = 1 else: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 4) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 4 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 408, in test.test_syntax Failed example: if 1: pass elif 1: pass else: x() = 1 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 418, in test.test_syntax Failed example: f(a=23, a=234) Expected: Traceback (most recent call last): ... SyntaxError: keyword argument repeated (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword argument repeated ********************************************************************** 1 items had failures: 42 of 50 in test.test_syntax ***Test Failed*** 42 failures. test test_syntax failed -- 42 of 50 doctests failed test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test test_telnetlib failed -- errors occurred; run in verbose mode for details test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18059 refs] [17873 refs] [17873 refs] [17873 refs] [17873 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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_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 327 tests OK. 7 tests failed: test_asyncore test_generators test_genexps test_lib2to3 test_multiprocessing test_syntax test_telnetlib 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl [700775 refs] From nnorwitz at gmail.com Mon Apr 6 11:18:31 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 6 Apr 2009 05:18:31 -0400 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20090406091831.GA11019@python.psfb.org> More important issues: ---------------------- test_ssl leaked [403, 0, -20] references, sum=383 Less important issues: ---------------------- test_cmd_line leaked [-25, 50, -25] references, sum=0 test_httpservers leaked [-25, 0, 11] references, sum=-14 test_smtplib leaked [-1, 1, 109] references, sum=109 test_sys leaked [21, -42, 21] references, sum=0 test_threading leaked [48, 44, 52] references, sum=144 test_urllib2_localnet leaked [3, 3, 3] references, sum=9 From nnorwitz at gmail.com Mon Apr 6 11:35:00 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 6 Apr 2009 05:35:00 -0400 Subject: [Python-checkins] Python Regression Test Failures all (7) Message-ID: <20090406093500.GA14698@python.psfb.org> 332 tests OK. 7 tests failed: test_asyncore test_generators test_genexps test_lib2to3 test_multiprocessing test_syntax test_telnetlib 26 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_cd test_cl test_epoll test_gl test_imgfile test_ioctl test_kqueue test_macos test_macostools 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ast test_asynchat test_asyncore test test_asyncore failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_asyncore.py", line 144, in test_readwrite self.assertEqual(tobj.read, True) AssertionError: False != True 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-11027 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils 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_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_gdbm test_generators ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: f=lambda: (yield 1),(yield 2) Expected: Traceback (most recent call last): ... SyntaxError: 'yield' outside function (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: 'yield' outside function ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): x = yield = y Expected: Traceback (most recent call last): ... SyntaxError: assignment to yield expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: assignment to yield expression not possible ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): (yield bar) = y Expected: Traceback (most recent call last): ... SyntaxError: can't assign to yield expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to yield expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): (yield bar) += y Expected: Traceback (most recent call last): ... SyntaxError: augmented assignment to yield expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to yield expression not possible ********************************************************************** 1 items had failures: 4 of 99 in test.test_generators.__test__.coroutine ***Test Failed*** 4 failures. test test_generators failed -- 4 of 284 doctests failed test_genericpath test_genexps ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_genexps.py", line ?, in test.test_genexps.__test__.doctests Failed example: (y for y in (1,2)) = 10 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to generator expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to generator expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_genexps.py", line ?, in test.test_genexps.__test__.doctests Failed example: (y for y in (1,2)) += 10 Expected: Traceback (most recent call last): ... SyntaxError: augmented assignment to generator expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to generator expression not possible ********************************************************************** 1 items had failures: 2 of 75 in test.test_genexps.__test__.doctests ***Test Failed*** 2 failures. test test_genexps failed -- 2 of 75 doctests failed 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 [13183 refs] [13183 refs] [13183 refs] [23375 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 test_lib2to3 crashed -- : No module named myfixes 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 test_multiprocessing crashed -- : cannot import name SkipTest test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18903 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib test_socket test_socketserver 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 30, in test.test_syntax Failed example: obj.None = 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 34, in test.test_syntax Failed example: None = 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 42, in test.test_syntax Failed example: () = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to () (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to () ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 46, in test.test_syntax Failed example: f() = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to function call (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 50, in test.test_syntax Failed example: del f() Expected: Traceback (most recent call last): SyntaxError: can't delete function call (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't delete function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 54, in test.test_syntax Failed example: a + 1 = 2 Expected: Traceback (most recent call last): SyntaxError: can't assign to operator (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to operator ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 58, in test.test_syntax Failed example: (x for x in x) = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to generator expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to generator expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 62, in test.test_syntax Failed example: 1 = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 66, in test.test_syntax Failed example: "abc" = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 70, in test.test_syntax Failed example: `1` = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to repr (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to repr ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 79, in test.test_syntax Failed example: (a, "b", c) = (1, 2, 3) Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 83, in test.test_syntax Failed example: [a, b, c + 1] = [1, 2, 3] Expected: Traceback (most recent call last): SyntaxError: can't assign to operator (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to operator ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 87, in test.test_syntax Failed example: a if 1 else b = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to conditional expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to conditional expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 93, in test.test_syntax Failed example: def f(None=1): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 101, in test.test_syntax Failed example: def f(x, y=1, z): pass Expected: Traceback (most recent call last): SyntaxError: non-default argument follows default argument (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: non-default argument follows default argument ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 106, in test.test_syntax Failed example: def f(x, None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 111, in test.test_syntax Failed example: def f(*None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 116, in test.test_syntax Failed example: def f(**None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 124, in test.test_syntax Failed example: def None(x): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 137, in test.test_syntax Failed example: f(x for x in L, 1) Expected: Traceback (most recent call last): SyntaxError: Generator expression must be parenthesized if not sole argument (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: Generator expression must be parenthesized if not sole argument ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 143, in test.test_syntax Failed example: f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, i121, i122, i123, i124, i125, i126, i127, i128, i129, i130, i131, i132, i133, i134, i135, i136, i137, i138, i139, i140, i141, i142, i143, i144, i145, i146, i147, i148, i149, i150, i151, i152, i153, i154, i155, i156, i157, i158, i159, i160, i161, i162, i163, i164, i165, i166, i167, i168, i169, i170, i171, i172, i173, i174, i175, i176, i177, i178, i179, i180, i181, i182, i183, i184, i185, i186, i187, i188, i189, i190, i191, i192, i193, i194, i195, i196, i197, i198, i199, i200, i201, i202, i203, i204, i205, i206, i207, i208, i209, i210, i211, i212, i213, i214, i215, i216, i217, i218, i219, i220, i221, i222, i223, i224, i225, i226, i227, i228, i229, i230, i231, i232, i233, i234, i235, i236, i237, i238, i239, i240, i241, i242, i243, i244, i245, i246, i247, i248, i249, i250, i251, i252, i253, i254, i255) Expected: Traceback (most recent call last): SyntaxError: more than 255 arguments (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: more than 255 arguments ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 177, in test.test_syntax Failed example: f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, i121, i122, i123, i124, i125, i126, i127, i128, i129, i130, i131, i132, i133, i134, i135, i136, i137, i138, i139, i140, i141, i142, i143, i144, i145, i146, i147, i148, i149, i150, i151, i152, i153, i154, i155, i156, i157, i158, i159, i160, i161, i162, i163, i164, i165, i166, i167, i168, i169, i170, i171, i172, i173, i174, i175, i176, i177, i178, i179, i180, i181, i182, i183, i184, i185, i186, i187, i188, i189, i190, i191, i192, i193, i194, i195, i196, i197, i198, i199, i200, i201, i202, i203, i204, i205, i206, i207, i208, i209, i210, i211, i212, i213, i214, i215, i216, i217, i218, i219, i220, i221, i222, i223, i224, i225, i226, i227, i228, i229, i230, i231, i232, i233, i234, i235, i236, i237, i238, i239, i240, i241, i242, i243, (x for x in i244), i245, i246, i247, i248, i249, i250, i251, i252=1, i253=1, i254=1, i255=1) Expected: Traceback (most recent call last): SyntaxError: more than 255 arguments (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: more than 255 arguments ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 207, in test.test_syntax Failed example: f(lambda x: x[0] = 3) Expected: Traceback (most recent call last): SyntaxError: lambda cannot contain assignment (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: lambda cannot contain assignment ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 214, in test.test_syntax Failed example: f(x()=2) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 217, in test.test_syntax Failed example: f(a or b=1) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 220, in test.test_syntax Failed example: f(x.y=1) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 227, in test.test_syntax Failed example: (x for x in x) += 1 Expected: Traceback (most recent call last): SyntaxError: augmented assignment to generator expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to generator expression not possible ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 230, in test.test_syntax Failed example: None += 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 233, in test.test_syntax Failed example: f() += 1 Expected: Traceback (most recent call last): SyntaxError: illegal expression for augmented assignment (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: illegal expression for augmented assignment ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 254, in test.test_syntax Failed example: def test(): for abc in range(10): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 266, in test.test_syntax Failed example: def test(): for abc in range(10): try: pass finally: try: continue except: pass Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 7) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 7 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 279, in test.test_syntax Failed example: def foo(): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 5) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 5 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 288, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 298, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: try: continue finally: pass Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 7) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 7 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 311, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: try: pass except: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 8) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 8 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 328, in test.test_syntax Failed example: try: print 1 break print 2 finally: print 3 Expected: Traceback (most recent call last): ... SyntaxError: 'break' outside loop (, line 3) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 3 SyntaxError: 'break' outside loop ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 372, in test.test_syntax Failed example: if 1: x() = 1 elif 1: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 2) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 2 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 380, in test.test_syntax Failed example: if 1: pass elif 1: x() = 1 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 4) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 4 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 388, in test.test_syntax Failed example: if 1: x() = 1 elif 1: pass else: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 2) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 2 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 398, in test.test_syntax Failed example: if 1: pass elif 1: x() = 1 else: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 4) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 4 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 408, in test.test_syntax Failed example: if 1: pass elif 1: pass else: x() = 1 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 418, in test.test_syntax Failed example: f(a=23, a=234) Expected: Traceback (most recent call last): ... SyntaxError: keyword argument repeated (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword argument repeated ********************************************************************** 1 items had failures: 42 of 50 in test.test_syntax ***Test Failed*** 42 failures. test test_syntax failed -- 42 of 50 doctests failed test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test test_telnetlib failed -- errors occurred; run in verbose mode for details test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18896 refs] [17873 refs] [17873 refs] [17873 refs] [17873 refs] test_threading_local test_threadsignals test_time test_timeout 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_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllibnet test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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_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 332 tests OK. 7 tests failed: test_asyncore test_generators test_genexps test_lib2to3 test_multiprocessing test_syntax test_telnetlib 26 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_cd test_cl test_epoll test_gl test_imgfile test_ioctl test_kqueue test_macos test_macostools 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl [716538 refs] From python-checkins at python.org Mon Apr 6 14:21:24 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 6 Apr 2009 14:21:24 +0200 (CEST) Subject: [Python-checkins] r71305 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090406122124.668611E4064@bag.python.org> Author: mark.dickinson Date: Mon Apr 6 14:21:24 2009 New Revision: 71305 Log: Add error checking to _Py_dg_strtod. If _Py_dg_strtod fails due to a failed malloc, it returns 0.0, sets the contents of its second argument to point to the start of the input string, and sets errno = ENOMEM. Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Mon Apr 6 14:21:24 2009 @@ -1352,7 +1352,7 @@ _Py_dg_strtod (CONST char *s00, char **se) { - int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1; + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1, error; int esign, i, j, k, nd, nd0, nf, nz, nz0, sign; CONST char *s, *s0, *s1; double aadj, aadj1; @@ -1654,12 +1654,29 @@ } } bd0 = s2b(s0, nd0, nd, y, bc.dplen); + if (bd0 == NULL) + goto failed_malloc; for(;;) { bd = Balloc(bd0->k); + if (bd == NULL) { + Bfree(bd0); + goto failed_malloc; + } Bcopy(bd, bd0); bb = d2b(&rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ + if (bb == NULL) { + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } bs = i2b(1); + if (bs == NULL) { + Bfree(bb); + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } if (e >= 0) { bb2 = bb5 = 0; @@ -1693,19 +1710,66 @@ } if (bb5 > 0) { bs = pow5mult(bs, bb5); + if (bs == NULL) { + Bfree(bb); + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } bb1 = mult(bs, bb); Bfree(bb); + if (bb1 == NULL) { + Bfree(bs); + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } bb = bb1; } - if (bb2 > 0) + if (bb2 > 0) { bb = lshift(bb, bb2); - if (bd5 > 0) + if (bb == NULL) { + Bfree(bs); + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } + } + if (bd5 > 0) { bd = pow5mult(bd, bd5); - if (bd2 > 0) + if (bd == NULL) { + Bfree(bb); + Bfree(bs); + Bfree(bd0); + goto failed_malloc; + } + } + if (bd2 > 0) { bd = lshift(bd, bd2); - if (bs2 > 0) + if (bd == NULL) { + Bfree(bb); + Bfree(bs); + Bfree(bd0); + goto failed_malloc; + } + } + if (bs2 > 0) { bs = lshift(bs, bs2); + if (bs == NULL) { + Bfree(bb); + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } + } delta = diff(bb, bd); + if (delta == NULL) { + Bfree(bb); + Bfree(bs); + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } bc.dsign = delta->sign; delta->sign = 0; i = cmp(delta, bs); @@ -1732,6 +1796,13 @@ break; } delta = lshift(delta,Log2P); + if (delta == NULL) { + Bfree(bb); + Bfree(bs); + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } if (cmp(delta, bs) > 0) goto drop_down; break; @@ -1897,8 +1968,12 @@ Bfree(bs); Bfree(bd0); Bfree(delta); - if (bc.nd > nd) - bigcomp(&rv, s0, &bc); + if (bc.nd > nd) { + error = bigcomp(&rv, s0, &bc); + if (error) + goto failed_malloc; + } + if (bc.scale) { word0(&rv0) = Exp_1 - 2*P*Exp_msk1; word1(&rv0) = 0; @@ -1911,6 +1986,12 @@ if (se) *se = (char *)s; return sign ? -dval(&rv) : dval(&rv); + + failed_malloc: + if (se) + *se = (char *)s00; + errno = ENOMEM; + return 0.0; } static char *dtoa_result; From python-checkins at python.org Mon Apr 6 14:28:57 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 6 Apr 2009 14:28:57 +0200 (CEST) Subject: [Python-checkins] r71306 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090406122857.D911E1E4064@bag.python.org> Author: mark.dickinson Date: Mon Apr 6 14:28:57 2009 New Revision: 71306 Log: Return -1.0, not 0.0, on strtod failure due to a failed malloc. Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Mon Apr 6 14:28:57 2009 @@ -1991,7 +1991,7 @@ if (se) *se = (char *)s00; errno = ENOMEM; - return 0.0; + return -1.0; } static char *dtoa_result; From python-checkins at python.org Mon Apr 6 15:17:26 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 6 Apr 2009 15:17:26 +0200 (CEST) Subject: [Python-checkins] r71307 - in python/branches/py3k-short-float-repr: Include/dtoa.h Python/dtoa.c Message-ID: <20090406131726.2151F1E4064@bag.python.org> Author: mark.dickinson Date: Mon Apr 6 15:17:24 2009 New Revision: 71307 Log: Make freedtoa publicly available, and rename it to _Py_dg_freedtoa Modified: python/branches/py3k-short-float-repr/Include/dtoa.h python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Include/dtoa.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/dtoa.h (original) +++ python/branches/py3k-short-float-repr/Include/dtoa.h Mon Apr 6 15:17:24 2009 @@ -5,6 +5,8 @@ PyAPI_FUNC(double) _Py_dg_strtod(const char *str, char **ptr); PyAPI_FUNC(char *) _Py_dg_dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve); +PyAPI_FUNC(void) _Py_dg_freedtoa(char *s); + #ifdef __cplusplus } Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Mon Apr 6 15:17:24 2009 @@ -2032,7 +2032,7 @@ */ void -freedtoa(char *s) +_Py_dg_freedtoa(char *s) { Bigint *b = (Bigint *)((int *)s - 1); b->maxwds = 1 << (b->k = *(int*)b); @@ -2125,7 +2125,7 @@ char *s, *s0; if (dtoa_result) { - freedtoa(dtoa_result); + _Py_dg_freedtoa(dtoa_result); dtoa_result = 0; } From python-checkins at python.org Mon Apr 6 15:39:51 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 6 Apr 2009 15:39:51 +0200 (CEST) Subject: [Python-checkins] r71308 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090406133951.135811E4064@bag.python.org> Author: mark.dickinson Date: Mon Apr 6 15:39:50 2009 New Revision: 71308 Log: Remove some redundant references to VAX Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Mon Apr 6 15:39:50 2009 @@ -251,8 +251,8 @@ #define CONST const #endif -#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1 -#error "Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined." +#if defined(IEEE_8087) + defined(IEEE_MC68k) != 1 +#error "Exactly one of IEEE_8087 or IEEE_MC68k should be defined." #endif typedef union { double d; ULong L[2]; } U; @@ -280,7 +280,7 @@ * An alternative that might be better on some machines is * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) */ -#if defined(IEEE_8087) + defined(VAX) +#if defined(IEEE_8087) #define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ ((unsigned short *)a)[0] = (unsigned short)c, a++) #else @@ -2138,7 +2138,6 @@ else *sign = 0; -#if defined(IEEE_Arith) + defined(VAX) if ((word0(&u) & Exp_mask) == Exp_mask) { /* Infinity or NaN */ @@ -2147,7 +2146,6 @@ return nrv_alloc("Infinity", rve, 8); return nrv_alloc("NaN", rve, 3); } -#endif if (!dval(&u)) { *decpt = 1; return nrv_alloc("0", rve, 1); From python-checkins at python.org Mon Apr 6 15:54:08 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 6 Apr 2009 15:54:08 +0200 (CEST) Subject: [Python-checkins] r71309 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090406135408.575831E4076@bag.python.org> Author: mark.dickinson Date: Mon Apr 6 15:54:08 2009 New Revision: 71309 Log: Always call _Py_dg_freedtoa on the result of a (successful) _Py_dg_dtoa call. Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Mon Apr 6 15:54:08 2009 @@ -553,7 +553,7 @@ precision = 1; /* _Py_dg_dtoa returns a digit string (no decimal point or - exponent) */ + exponent). Must be matched by a call to _Py_dg_freedtoa. */ digits = _Py_dg_dtoa(d, mode, precision, &decpt, &sign, &digits_end); assert(digits_end != NULL && digits_end >= digits); n_digits = digits_end - digits; @@ -583,8 +583,7 @@ buf += 3; assert(0); } - *buf = '\0'; - return; + goto exit; } /* We got digits back, format them. */ @@ -632,8 +631,7 @@ break; default: PyErr_BadInternalCall(); - *buf = '\0'; - return; + goto exit; } /* Always add a negative sign, and a plus sign if always_add_sign. */ @@ -694,8 +692,9 @@ exp_len = sprintf(buf, "%+.02d", decpt-1); buf += exp_len; } - - *buf++ = '\0'; + exit: + *buf = '\0'; + _Py_dg_freedtoa(digits); } From python-checkins at python.org Mon Apr 6 16:11:15 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 6 Apr 2009 16:11:15 +0200 (CEST) Subject: [Python-checkins] r71310 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090406141115.343541E4064@bag.python.org> Author: mark.dickinson Date: Mon Apr 6 16:11:14 2009 New Revision: 71310 Log: Remove static dtoa_result variable. The penalty for doing this is that calls to _Py_dg_dtoa must always be matched by a corresponding call to _Py_dg_freedtoa, to avoid memory leakage. Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Mon Apr 6 16:11:14 2009 @@ -1994,8 +1994,6 @@ return -1.0; } - static char *dtoa_result; - static char * rv_alloc(int i) { @@ -2008,9 +2006,7 @@ k++; r = (int*)Balloc(k); *r = k; - return - dtoa_result = - (char *)(r+1); + return (char *)(r+1); } static char * @@ -2037,8 +2033,6 @@ Bigint *b = (Bigint *)((int *)s - 1); b->maxwds = 1 << (b->k = *(int*)b); Bfree(b); - if (s == dtoa_result) - dtoa_result = 0; } /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. @@ -2075,6 +2069,9 @@ * calculation. */ +/* Note: to avoid memory leakage, a successful call to _Py_dg_dtoa should + always be matched by a call to _Py_dg_freedtoa. */ + char * _Py_dg_dtoa (double dd, int mode, int ndigits, int *decpt, int *sign, char **rve) @@ -2124,11 +2121,6 @@ double ds; char *s, *s0; - if (dtoa_result) { - _Py_dg_freedtoa(dtoa_result); - dtoa_result = 0; - } - u.d = dd; if (word0(&u) & Sign_bit) { /* set sign for everything, including 0's and NaNs */ From python-checkins at python.org Mon Apr 6 16:22:34 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 6 Apr 2009 16:22:34 +0200 (CEST) Subject: [Python-checkins] r71311 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090406142234.A190D1E4076@bag.python.org> Author: mark.dickinson Date: Mon Apr 6 16:22:34 2009 New Revision: 71311 Log: rv_alloc and nrv_alloc should return NULL on failure Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Mon Apr 6 16:22:34 2009 @@ -2005,6 +2005,8 @@ j <<= 1) k++; r = (int*)Balloc(k); + if (r == NULL) + return NULL; *r = k; return (char *)(r+1); } @@ -2014,7 +2016,10 @@ { char *rv, *t; - t = rv = rv_alloc(n); + rv = rv_alloc(n); + if (rv == NULL) + return NULL; + t = rv; while((*t = *s++)) t++; if (rve) *rve = t; From python-checkins at python.org Mon Apr 6 18:34:41 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 6 Apr 2009 18:34:41 +0200 (CEST) Subject: [Python-checkins] r71312 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090406163441.40C971E44F1@bag.python.org> Author: mark.dickinson Date: Mon Apr 6 18:34:40 2009 New Revision: 71312 Log: Add failure checks throughout _Py_dg_dtoa Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Mon Apr 6 18:34:40 2009 @@ -416,6 +416,7 @@ Bfree (Bigint *v) { + assert(v != NULL); if (v) { if (v->k > Kmax) FREE((void*)v); @@ -2074,8 +2075,9 @@ * calculation. */ -/* Note: to avoid memory leakage, a successful call to _Py_dg_dtoa should - always be matched by a call to _Py_dg_freedtoa. */ +/* Additional notes (METD): (1) returns NULL on failure. (2) to avoid memory + leakage, a successful call to _Py_dg_dtoa should always be matched by a + call to _Py_dg_freedtoa. */ char * _Py_dg_dtoa @@ -2126,6 +2128,11 @@ double ds; char *s, *s0; + /* set pointers to NULL, to silence gcc compiler warnings and make + cleanup easier on error */ + mlo = mhi = b = S = 0; + s0 = 0; + u.d = dd; if (word0(&u) & Sign_bit) { /* set sign for everything, including 0's and NaNs */ @@ -2150,6 +2157,8 @@ b = d2b(&u, &be, &bbits); + if (b == NULL) + goto failed_malloc; if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) { dval(&d2) = dval(&u); word0(&d2) &= Frac_mask1; @@ -2260,7 +2269,10 @@ if (i <= 0) i = 1; } - s = s0 = rv_alloc(i); + s0 = rv_alloc(i); + if (s0 == NULL) + goto failed_malloc; + s = s0; if (ilim >= 0 && ilim <= Quick_max && try_quick) { @@ -2406,7 +2418,6 @@ m2 = b2; m5 = b5; - mhi = mlo = 0; if (leftright) { i = denorm ? be + (Bias + (P-1) - 1 + 1) : @@ -2414,6 +2425,8 @@ b2 += i; s2 += i; mhi = i2b(1); + if (mhi == NULL) + goto failed_malloc; } if (m2 > 0 && s2 > 0) { i = m2 < s2 ? m2 : s2; @@ -2425,19 +2438,34 @@ if (leftright) { if (m5 > 0) { mhi = pow5mult(mhi, m5); + if (mhi == NULL) + goto failed_malloc; b1 = mult(mhi, b); Bfree(b); b = b1; + if (b == NULL) + goto failed_malloc; } - if ((j = b5 - m5)) + if ((j = b5 - m5)) { b = pow5mult(b, j); + if (b == NULL) + goto failed_malloc; + } } - else + else { b = pow5mult(b, b5); + if (b == NULL) + goto failed_malloc; + } } S = i2b(1); - if (s5 > 0) + if (S == NULL) + goto failed_malloc; + if (s5 > 0) { S = pow5mult(S, s5); + if (S == NULL) + goto failed_malloc; + } /* Check for special case that d is a normalized power of 2. */ @@ -2468,34 +2496,55 @@ b2 += i; m2 += i; s2 += i; - if (b2 > 0) + if (b2 > 0) { b = lshift(b, b2); - if (s2 > 0) + if (b == NULL) + goto failed_malloc; + } + if (s2 > 0) { S = lshift(S, s2); + if (S == NULL) + goto failed_malloc; + } if (k_check) { if (cmp(b,S) < 0) { k--; b = multadd(b, 10, 0); /* we botched the k estimate */ - if (leftright) + if (b == NULL) + goto failed_malloc; + if (leftright) { mhi = multadd(mhi, 10, 0); + if (mhi == NULL) + goto failed_malloc; + } ilim = ilim1; } } if (ilim <= 0 && (mode == 3 || mode == 5)) { - if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { + if (ilim < 0) { /* no digits, fcvt style */ no_digits: k = -1 - ndigits; goto ret; } + else { + S = multadd(S, 5, 0); + if (S == NULL) + goto failed_malloc; + if (cmp(b, S) <= 0) + goto no_digits; + } one_digit: *s++ = '1'; k++; goto ret; } if (leftright) { - if (m2 > 0) + if (m2 > 0) { mhi = lshift(mhi, m2); + if (mhi == NULL) + goto failed_malloc; + } /* Compute mlo -- check for special case * that d is a normalized power of 2. @@ -2504,8 +2553,12 @@ mlo = mhi; if (spec_case) { mhi = Balloc(mhi->k); + if (mhi == NULL) + goto failed_malloc; Bcopy(mhi, mlo); mhi = lshift(mhi, Log2P); + if (mhi == NULL) + goto failed_malloc; } for(i = 1;;i++) { @@ -2515,6 +2568,8 @@ */ j = cmp(b, mlo); delta = diff(S, mhi); + if (delta == NULL) + goto failed_malloc; j1 = delta->sign ? 1 : cmp(b, delta); Bfree(delta); if (j1 == 0 && mode != 1 && !(word1(&u) & 1) @@ -2534,6 +2589,8 @@ } if (j1 > 0) { b = lshift(b, 1); + if (b == NULL) + goto failed_malloc; j1 = cmp(b, S); if ((j1 > 0 || (j1 == 0 && dig & 1)) && dig++ == '9') @@ -2556,11 +2613,20 @@ if (i == ilim) break; b = multadd(b, 10, 0); - if (mlo == mhi) + if (b == NULL) + goto failed_malloc; + if (mlo == mhi) { mlo = mhi = multadd(mhi, 10, 0); + if (mlo == NULL) + goto failed_malloc; + } else { mlo = multadd(mlo, 10, 0); + if (mlo == NULL) + goto failed_malloc; mhi = multadd(mhi, 10, 0); + if (mhi == NULL) + goto failed_malloc; } } } @@ -2573,11 +2639,15 @@ if (i >= ilim) break; b = multadd(b, 10, 0); + if (b == NULL) + goto failed_malloc; } /* Round off last digit */ b = lshift(b, 1); + if (b == NULL) + goto failed_malloc; j = cmp(b, S); if (j > 0 || (j == 0 && dig & 1)) { roundoff: @@ -2607,6 +2677,18 @@ if (rve) *rve = s; return s0; + failed_malloc: + if (S) + Bfree(S); + if (mlo && mlo != mhi) + Bfree(mlo); + if (mhi) + Bfree(mhi); + if (b) + Bfree(b); + if (s0) + _Py_dg_freedtoa(s0); + return NULL; } #ifdef __cplusplus } From python-checkins at python.org Mon Apr 6 18:45:24 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 6 Apr 2009 18:45:24 +0200 (CEST) Subject: [Python-checkins] r71313 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090406164524.B9B901E403E@bag.python.org> Author: mark.dickinson Date: Mon Apr 6 18:45:24 2009 New Revision: 71313 Log: Minor consistency tweaks Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Mon Apr 6 18:45:24 2009 @@ -725,9 +725,9 @@ if (k & 1) { b1 = mult(b, p5); Bfree(b); - if (b1 == NULL) - return NULL; b = b1; + if (b == NULL) + return NULL; } if (!(k >>= 1)) break; @@ -1719,13 +1719,13 @@ } bb1 = mult(bs, bb); Bfree(bb); - if (bb1 == NULL) { + bb = bb1; + if (bb == NULL) { Bfree(bs); Bfree(bd); Bfree(bd0); goto failed_malloc; } - bb = bb1; } if (bb2 > 0) { bb = lshift(bb, bb2); From python-checkins at python.org Mon Apr 6 19:11:59 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 6 Apr 2009 19:11:59 +0200 (CEST) Subject: [Python-checkins] r71314 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090406171159.293381E4032@bag.python.org> Author: mark.dickinson Date: Mon Apr 6 19:11:58 2009 New Revision: 71314 Log: Add comments about the modifications to the top of dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Mon Apr 6 19:11:58 2009 @@ -17,8 +17,47 @@ * ***************************************************************/ -/* Please send bug reports to David M. Gay (dmg at acm dot org, - * with " at " changed at "@" and " dot " changed to "."). */ +/**************************************************************** + * This is dtoa.c by David Gay, obtained from http://www.netlib.org/fp/dtoa.c + * on March 17, 2009 and modified for inclusion into the Python core by Mark + * Dickinson and Eric Smith. The major modifications are as follows: + * + * 0. The original code has been specialized to Python's needs by removing + * many of the #ifdef'd sections. In particular, code to support VAX and + * IBM floating-point formats, hex NaNs, hex floats, locale-aware + * treatment of the decimal point, and setting of the inexact flag have + * been removed. + * + * 1. We use PyMem_Malloc and PyMem_Free in place of malloc and free. + * + * 2. The public functions strtod, dtoa and freedtoa all now have + * a _Py_dg_ prefix. + * + * 3. Instead of assuming that PyMem_Malloc always succeeds, we thread + * PyMem_Malloc failures through the code. The functions + * + * Balloc, multadd, s2b, i2b, mult, pow5mult, lshift, diff, d2b + * + * of return type *Bigint all return NULL to indicate a malloc failure. + * Similarly, rv_alloc and nrv_alloc (return type char *) return NULL on + * failure. bigcomp now has return type int (it used to be void) and + * returns -1 on failure and 0 otherwise. _Py_dg_dtoa returns NULL + * on failure. _Py_dg_strtod indicates failure due to malloc failure + * by returning -1.0, setting errno=ENOMEM and *se to s00. + * + * 4. The static variable dtoa_result has been removed. Callers of + * _Py_dg_dtoa are expected to call _Py_dg_freedtoa to free + * the memory allocated by _Py_dg_dtoa. + * + * 5. A bug in the original dtoa.c code, in which '.nan' and '.inf' + * were accepted as valid inputs to strtod, has been fixed. + * + ***************************************************************/ + +/* Please send bug reports for the original dtoa.c code to David M. Gay (dmg + * at acm dot org, with " at " changed at "@" and " dot " changed to "."). + * Send bug reports for this modified version to Mark Dickinson + * (dickinsm at gmail.com). */ /* On a machine with IEEE extended-precision registers, it is * necessary to specify double-precision (53-bit) rounding precision From python-checkins at python.org Mon Apr 6 19:43:21 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 6 Apr 2009 19:43:21 +0200 (CEST) Subject: [Python-checkins] r71315 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090406174321.C78ED1E457B@bag.python.org> Author: mark.dickinson Date: Mon Apr 6 19:43:21 2009 New Revision: 71315 Log: Bug reports should go to the issue tracker, *not* to me! Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Mon Apr 6 19:43:21 2009 @@ -56,8 +56,8 @@ /* Please send bug reports for the original dtoa.c code to David M. Gay (dmg * at acm dot org, with " at " changed at "@" and " dot " changed to "."). - * Send bug reports for this modified version to Mark Dickinson - * (dickinsm at gmail.com). */ + * Please report bugs for this modified version using the Python issue tracker + * (http://bugs.python.org). */ /* On a machine with IEEE extended-precision registers, it is * necessary to specify double-precision (53-bit) rounding precision From python-checkins at python.org Mon Apr 6 19:55:06 2009 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 6 Apr 2009 19:55:06 +0200 (CEST) Subject: [Python-checkins] r71316 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090406175506.1FE8E1E400C@bag.python.org> Author: raymond.hettinger Date: Mon Apr 6 19:55:05 2009 New Revision: 71316 Log: Add more examples. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Mon Apr 6 19:55:05 2009 @@ -194,7 +194,17 @@ from APL. Also, the existing :func:`itertools.count` function now has an optional *step* argument and can accept any type of counting sequence including :class:`fractions.Fraction` and - :class:`decimal.Decimal`. + :class:`decimal.Decimal`:: + + >>> [p+q for p,q in combinations_with_replacement('LOVE', 2)] + ['LL', 'LO', 'LV', 'LE', 'OO', 'OV', 'OE', 'VV', 'VE', 'EE'] + + >>> list(compress(data=range(10), selectors=[0,0,1,1,0,1,0,1,0,0])) + [2, 3, 5, 7] + + >>> c = count(start=Fraction(1,2), step=Fraction(1,6)) + >>> next(c), next(c), next(c), next(c) + (Fraction(1, 2), Fraction(2, 3), Fraction(5, 6), Fraction(1, 1)) (Contributed by Raymond Hettinger.) @@ -206,8 +216,11 @@ (Contributed by Raymond Hettinger; :issue:`1818`.) -* ``round`(x, n)`` now returns an integer if *x* is an integer. - Previously it returned a float. +* ``round(x, n)`` now returns an integer if *x* is an integer. + Previously it returned a float:: + + >>> round(1123, -2) + 1100 (Contributed by Mark Dickinson; :issue:`4707`.) @@ -240,7 +253,17 @@ * The :mod:`unittest` module now supports skipping individual tests or classes of tests. And it supports marking a test as a expected failure, a test that is known to be broken, but shouldn't be counted as a failure on a - TestResult. + TestResult:: + + class TestGizmo(unittest.TestCase): + + @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows") + def test_gizmo_on_windows(self): + ... + + @unittest.expectedFailure + def test_gimzo_without_required_library(self): + ... (Contributed by Benjamin Peterson.) From python-checkins at python.org Mon Apr 6 20:42:54 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 6 Apr 2009 20:42:54 +0200 (CEST) Subject: [Python-checkins] r71317 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090406184254.637291E40D1@bag.python.org> Author: mark.dickinson Date: Mon Apr 6 20:42:54 2009 New Revision: 71317 Log: Remove bogus assert. Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Mon Apr 6 20:42:54 2009 @@ -455,7 +455,6 @@ Bfree (Bigint *v) { - assert(v != NULL); if (v) { if (v->k > Kmax) FREE((void*)v); From python-checkins at python.org Mon Apr 6 21:11:07 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 6 Apr 2009 21:11:07 +0200 (CEST) Subject: [Python-checkins] r71318 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090406191107.06F711E4538@bag.python.org> Author: eric.smith Date: Mon Apr 6 21:11:06 2009 New Revision: 71318 Log: Moved 'g' precision test back into PyOS_double_to_string; started cleaning up memory management in format_float_short. Work still remains to calculate the longest string we'll need to allocate. Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Mon Apr 6 21:11:06 2009 @@ -536,22 +536,23 @@ should have ".0" added. Only applies to format codes 'r', 's', and 'g'. use_alt_formatting is nonzero if alternative formatting should be used. Only applies to format codes 'e', 'f' and 'g'. + + Returns a PyMem_Malloc'd block of memory containing the resulting string, + or NULL on error. If NULL is returned, the Python error has been set. */ -static void -format_float_short(char *buf, Py_ssize_t buflen, double d, char format_code, +static char * +format_float_short(double d, char format_code, int mode, Py_ssize_t precision, int always_add_sign, int add_dot_0_if_integer, int use_alt_formatting, char **float_strings) { + char* p = (char *)PyMem_Malloc(512); + char* buf = p; char *digits, *digits_end; int decpt, sign, exp_len, dec_pos, use_exp = 0; Py_ssize_t n_digits, min_digits = 0; - /* precision of 0 makes no sense for 'g' format; interpret as 1 */ - if (precision == 0 && format_code == 'g') - precision = 1; - /* _Py_dg_dtoa returns a digit string (no decimal point or exponent). Must be matched by a call to _Py_dg_freedtoa. */ digits = _Py_dg_dtoa(d, mode, precision, &decpt, &sign, &digits_end); @@ -695,6 +696,8 @@ exit: *buf = '\0'; _Py_dg_freedtoa(digits); + + return p; } @@ -703,7 +706,6 @@ int precision, int flags) { - char* buf = (char *)PyMem_Malloc(512); char lc_format_code = format_code; char** float_strings = lc_float_strings; int mode = 0; @@ -745,6 +747,9 @@ break; case 'g': mode = 2; + /* precision of 0 makes no sense for 'g' format; interpret as 1 */ + if (precision == 0) + precision = 1; break; case 'r': /* "repr" pseudo-mode */ @@ -766,15 +771,8 @@ break; } - if (!buf) - return NULL; - - /* XXX validate format_code */ - - format_float_short(buf, 512, val, lc_format_code, mode, precision, - flags & Py_DTSF_SIGN, - flags & Py_DTSF_ADD_DOT_0, flags & Py_DTSF_ALT, - float_strings); - - return buf; + return format_float_short(val, lc_format_code, mode, precision, + flags & Py_DTSF_SIGN, + flags & Py_DTSF_ADD_DOT_0, flags & Py_DTSF_ALT, + float_strings); } From python-checkins at python.org Mon Apr 6 21:34:10 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 6 Apr 2009 21:34:10 +0200 (CEST) Subject: [Python-checkins] r71319 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090406193410.2D1D81E403F@bag.python.org> Author: mark.dickinson Date: Mon Apr 6 21:34:08 2009 New Revision: 71319 Log: Remove some no-longer-applicable comments Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Mon Apr 6 21:34:08 2009 @@ -106,10 +106,6 @@ * #define IEEE_MC68k for IEEE-arithmetic machines where the most * significant byte has the lowest address. * #define Long int on machines with 32-bit ints and 64-bit longs. - * #define IBM for IBM mainframe-style floating-point arithmetic. - * #define VAX for VAX-style floating-point arithmetic (D_floating). - * #define No_leftright to omit left-right logic in fast floating-point - * computation of dtoa. * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 * and strtod and dtoa should round accordingly. Unless Trust_FLT_ROUNDS * is also #defined, fegetround() will be queried for the rounding mode. @@ -120,34 +116,6 @@ * portable than using FLT_FOUNDS directly. * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 * and Honor_FLT_ROUNDS is not #defined. - * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines - * that use extended-precision instructions to compute rounded - * products and quotients) with IBM. - * #define ROUND_BIASED for IEEE-format with biased rounding. - * #define Inaccurate_Divide for IEEE-format with correctly rounded - * products but inaccurate quotients, e.g., for Intel i860. - * #define NO_LONG_LONG on machines that do not have a "long long" - * integer type (of >= 64 bits). On such machines, you can - * #define Just_16 to store 16 bits per 32-bit Long when doing - * high-precision integer arithmetic. Whether this speeds things - * up or slows things down depends on the machine and the number - * being converted. If long long is available and the name is - * something other than "long long", #define Llong to be the name, - * and if "unsigned Llong" does not work as an unsigned version of - * Llong, #define #ULLong to be the corresponding unsigned type. - * #define KR_headers for old-style C function headers. - * #define Bad_float_h if your system lacks a float.h or if it does not - * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, - * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. - * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) - * if memory is available and otherwise does something you deem - * appropriate. If MALLOC is undefined, malloc will be invoked - * directly -- and assumed always to succeed. Similarly, if you - * want something other than the system's free() to be called to - * recycle memory acquired from MALLOC, #define FREE to be the - * name of the alternate routine. (FREE or free is only called in - * pathological cases, e.g., in a dtoa call after a dtoa return in - * mode 3 with thousands of digits requested.) * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making * memory allocations from a private pool of memory when possible. * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, @@ -159,63 +127,6 @@ * all dtoa conversions in single-threaded executions with 8-byte * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte * pointers, PRIVATE_MEM >= 7112 appears adequate. - * #define NO_INFNAN_CHECK if you do not wish to have INFNAN_CHECK - * #defined automatically on IEEE systems. On such systems, - * when INFNAN_CHECK is #defined, strtod checks - * for Infinity and NaN (case insensitively). On some systems - * (e.g., some HP systems), it may be necessary to #define NAN_WORD0 - * appropriately -- to the most significant word of a quiet NaN. - * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) - * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, - * strtod also accepts (case insensitively) strings of the form - * NaN(x), where x is a string of hexadecimal digits and spaces; - * if there is only one string of hexadecimal digits, it is taken - * for the 52 fraction bits of the resulting NaN; if there are two - * or more strings of hex digits, the first is for the high 20 bits, - * the second and subsequent for the low 32 bits, with intervening - * white space ignored; but if this results in none of the 52 - * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0 - * and NAN_WORD1 are used instead. - * #define MULTIPLE_THREADS if the system offers preemptively scheduled - * multiple threads. In this case, you must provide (or suitably - * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed - * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed - * in pow5mult, ensures lazy evaluation of only one copy of high - * powers of 5; omitting this lock would introduce a small - * probability of wasting memory, but would otherwise be harmless.) - * You must also invoke freedtoa(s) to free the value s returned by - * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. - * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that - * avoids underflows on inputs whose result does not underflow. - * If you #define NO_IEEE_Scale on a machine that uses IEEE-format - * floating-point numbers and flushes underflows to zero rather - * than implementing gradual underflow, then you must also #define - * Sudden_Underflow. - * #define USE_LOCALE to use the current locale's decimal_point value. - * #define SET_INEXACT if IEEE arithmetic is being used and extra - * computation should be done to set the inexact flag when the - * result is inexact and avoid setting inexact when the result - * is exact. In this case, dtoa.c must be compiled in - * an environment, perhaps provided by #include "dtoa.c" in a - * suitable wrapper, that defines two functions, - * int get_inexact(void); - * void clear_inexact(void); - * such that get_inexact() returns a nonzero value if the - * inexact bit is already set, and clear_inexact() sets the - * inexact bit to 0. When SET_INEXACT is #defined, strtod - * also does extra computations to set the underflow and overflow - * flags when appropriate (i.e., when the result is tiny and - * inexact or when it is a numeric value rounded to +-infinity). - * #define NO_ERRNO if strtod should not assign errno = ERANGE when - * the result overflows to +-Infinity or underflows to 0. - * #define NO_HEX_FP to omit recognition of hexadecimal floating-point - * values by strtod. - * #define NO_STRTOD_BIGCOMP (on IEEE-arithmetic systems only for now) - * to disable logic for "fast" testing of very long input strings - * to strtod. This testing proceeds by initially truncating the - * input string, then if necessary comparing the whole string with - * a decimal expansion to decide close cases. This logic is only - * used for input more than STRTOD_DIGLIM digits long (default 40). */ /* Linking of Python's #defines to Gay's #defines starts here. */ From python-checkins at python.org Mon Apr 6 21:45:53 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 6 Apr 2009 21:45:53 +0200 (CEST) Subject: [Python-checkins] r71320 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090406194553.658251E4014@bag.python.org> Author: mark.dickinson Date: Mon Apr 6 21:45:53 2009 New Revision: 71320 Log: More preprocessor cleanup Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Mon Apr 6 21:45:53 2009 @@ -116,17 +116,6 @@ * portable than using FLT_FOUNDS directly. * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 * and Honor_FLT_ROUNDS is not #defined. - * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making - * memory allocations from a private pool of memory when possible. - * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, - * unless #defined to be a different length. This default length - * suffices to get rid of MALLOC calls except for unusual cases, - * such as decimal-to-binary conversion of a very long string of - * digits. The longest string dtoa can return is about 751 bytes - * long. For conversions by strtod of strings of 800 digits and - * all dtoa conversions in single-threaded executions with 8-byte - * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte - * pointers, PRIVATE_MEM >= 7112 appears adequate. */ /* Linking of Python's #defines to Gay's #defines starts here. */ @@ -173,16 +162,13 @@ #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} #endif -#ifndef Omit_Private_Memory #ifndef PRIVATE_MEM #define PRIVATE_MEM 2304 #endif #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) static double private_mem[PRIVATE_mem], *pmem_next = private_mem; -#endif #undef IEEE_Arith -#undef Avoid_Underflow #ifdef IEEE_MC68k #define IEEE_Arith #endif @@ -190,17 +176,10 @@ #define IEEE_Arith #endif -#undef INFNAN_CHECK -#define INFNAN_CHECK - #ifdef __cplusplus extern "C" { #endif -#ifndef CONST -#define CONST const -#endif - #if defined(IEEE_8087) + defined(IEEE_MC68k) != 1 #error "Exactly one of IEEE_8087 or IEEE_MC68k should be defined." #endif @@ -270,10 +249,6 @@ #define Tiny1 1 #define Quick_max 14 #define Int_max 14 -#define Avoid_Underflow -#ifdef Flush_Denorm /* debugging option */ -#undef Sudden_Underflow -#endif #ifndef Flt_Rounds #ifdef FLT_ROUNDS @@ -285,14 +260,17 @@ #define Rounding Flt_Rounds - - -#define rounded_product(a,b) a *= b -#define rounded_quotient(a,b) a /= b - #define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) #define Big1 0xffffffff +#ifndef NAN_WORD0 +#define NAN_WORD0 0x7ff80000 +#endif + +#ifndef NAN_WORD1 +#define NAN_WORD1 0 +#endif + typedef struct BCinfo BCinfo; struct @@ -330,19 +308,12 @@ { int x; Bigint *rv; -#ifndef Omit_Private_Memory unsigned int len; -#endif if (k <= Kmax && (rv = freelist[k])) freelist[k] = rv->next; else { x = 1 << k; -#ifdef Omit_Private_Memory - rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); - if (rv == NULL) - return NULL; -#else len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) /sizeof(double); if (pmem_next - private_mem + len <= PRIVATE_mem) { @@ -354,7 +325,6 @@ if (rv == NULL) return NULL; } -#endif rv->k = k; rv->maxwds = x; } @@ -430,7 +400,7 @@ static Bigint * s2b - (CONST char *s, int nd0, int nd, ULong y9, int dplen) + (const char *s, int nd0, int nd, ULong y9, int dplen) { Bigint *b; int i, k; @@ -967,16 +937,16 @@ return dval(&da) / dval(&db); } - static CONST double + static const double tens[] = { 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22 }; - static CONST double + static const double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; -static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, +static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 9007199254740992.*9007199254740992.e-256 /* = 2^106 * 1e-256 */ }; @@ -985,22 +955,12 @@ #define Scale_Bit 0x10 #define n_bigtens 5 -#ifdef INFNAN_CHECK - -#ifndef NAN_WORD0 -#define NAN_WORD0 0x7ff80000 -#endif - -#ifndef NAN_WORD1 -#define NAN_WORD1 0 -#endif - static int match - (CONST char **sp, char *t) + (const char **sp, char *t) { int c, d; - CONST char *s = *sp; + const char *s = *sp; while((d = *t++)) { if ((c = *++s) >= 'A' && c <= 'Z') @@ -1012,8 +972,6 @@ return 1; } -#endif /* INFNAN_CHECK */ - #define ULbits 32 #define kshift 5 #define kmask 31 @@ -1129,7 +1087,7 @@ static int bigcomp - (U *rv, CONST char *s0, BCinfo *bc) + (U *rv, const char *s0, BCinfo *bc) { Bigint *b, *d; int b2, bbits, d2, dd, dig, dsign, i, j, nd, nd0, p2, p5, speccase; @@ -1300,11 +1258,11 @@ double _Py_dg_strtod - (CONST char *s00, char **se) + (const char *s00, char **se) { int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1, error; int esign, i, j, k, nd, nd0, nf, nz, nz0, sign; - CONST char *s, *s0, *s1; + const char *s, *s0, *s1; double aadj, aadj1; Long L; U aadj2, adj, rv, rv0; @@ -1427,7 +1385,6 @@ } if (!nd) { if (!nz && !nz0) { -#ifdef INFNAN_CHECK /* Check for Nan and Infinity */ switch(c) { case 'i': @@ -1449,7 +1406,6 @@ goto ret; } } -#endif /* INFNAN_CHECK */ ret0: s = s00; sign = 0; @@ -1478,7 +1434,7 @@ goto ret; if (e > 0) { if (e <= Ten_pmax) { - /* rv = */ rounded_product(dval(&rv), tens[e]); + dval(&rv) *= tens[e]; goto ret; } i = DBL_DIG - nd; @@ -1488,12 +1444,12 @@ */ e -= i; dval(&rv) *= tens[i]; - /* rv = */ rounded_product(dval(&rv), tens[e]); + dval(&rv) *= tens[e]; goto ret; } } else if (e >= -Ten_pmax) { - /* rv = */ rounded_quotient(dval(&rv), tens[-e]); + dval(&rv) /= tens[-e]; goto ret; } } From nnorwitz at gmail.com Mon Apr 6 22:09:08 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 6 Apr 2009 16:09:08 -0400 Subject: [Python-checkins] Python Regression Test Failures basics (7) Message-ID: <20090406200908.GA29213@python.psfb.org> 327 tests OK. 7 tests failed: test_asyncore test_generators test_genexps test_lib2to3 test_multiprocessing test_syntax test_telnetlib 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ast test_asynchat test_asyncore test test_asyncore failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_asyncore.py", line 144, in test_readwrite self.assertEqual(tobj.read, True) AssertionError: False != True 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils 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_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_gdbm test_generators ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: f=lambda: (yield 1),(yield 2) Expected: Traceback (most recent call last): ... SyntaxError: 'yield' outside function (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: 'yield' outside function ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): x = yield = y Expected: Traceback (most recent call last): ... SyntaxError: assignment to yield expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: assignment to yield expression not possible ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): (yield bar) = y Expected: Traceback (most recent call last): ... SyntaxError: can't assign to yield expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to yield expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): (yield bar) += y Expected: Traceback (most recent call last): ... SyntaxError: augmented assignment to yield expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to yield expression not possible ********************************************************************** 1 items had failures: 4 of 99 in test.test_generators.__test__.coroutine ***Test Failed*** 4 failures. test test_generators failed -- 4 of 284 doctests failed test_genericpath test_genexps ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_genexps.py", line ?, in test.test_genexps.__test__.doctests Failed example: (y for y in (1,2)) = 10 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to generator expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to generator expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_genexps.py", line ?, in test.test_genexps.__test__.doctests Failed example: (y for y in (1,2)) += 10 Expected: Traceback (most recent call last): ... SyntaxError: augmented assignment to generator expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to generator expression not possible ********************************************************************** 1 items had failures: 2 of 75 in test.test_genexps.__test__.doctests ***Test Failed*** 2 failures. test test_genexps failed -- 2 of 75 doctests failed 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 [13183 refs] [13183 refs] [13183 refs] [23375 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 test_lib2to3 crashed -- : No module named myfixes 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 test_multiprocessing crashed -- : cannot import name SkipTest test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18903 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 30, in test.test_syntax Failed example: obj.None = 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 34, in test.test_syntax Failed example: None = 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 42, in test.test_syntax Failed example: () = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to () (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to () ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 46, in test.test_syntax Failed example: f() = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to function call (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 50, in test.test_syntax Failed example: del f() Expected: Traceback (most recent call last): SyntaxError: can't delete function call (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't delete function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 54, in test.test_syntax Failed example: a + 1 = 2 Expected: Traceback (most recent call last): SyntaxError: can't assign to operator (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to operator ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 58, in test.test_syntax Failed example: (x for x in x) = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to generator expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to generator expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 62, in test.test_syntax Failed example: 1 = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 66, in test.test_syntax Failed example: "abc" = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 70, in test.test_syntax Failed example: `1` = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to repr (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to repr ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 79, in test.test_syntax Failed example: (a, "b", c) = (1, 2, 3) Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 83, in test.test_syntax Failed example: [a, b, c + 1] = [1, 2, 3] Expected: Traceback (most recent call last): SyntaxError: can't assign to operator (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to operator ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 87, in test.test_syntax Failed example: a if 1 else b = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to conditional expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to conditional expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 93, in test.test_syntax Failed example: def f(None=1): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 101, in test.test_syntax Failed example: def f(x, y=1, z): pass Expected: Traceback (most recent call last): SyntaxError: non-default argument follows default argument (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: non-default argument follows default argument ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 106, in test.test_syntax Failed example: def f(x, None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 111, in test.test_syntax Failed example: def f(*None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 116, in test.test_syntax Failed example: def f(**None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 124, in test.test_syntax Failed example: def None(x): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 137, in test.test_syntax Failed example: f(x for x in L, 1) Expected: Traceback (most recent call last): SyntaxError: Generator expression must be parenthesized if not sole argument (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: Generator expression must be parenthesized if not sole argument ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 143, in test.test_syntax Failed example: f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, i121, i122, i123, i124, i125, i126, i127, i128, i129, i130, i131, i132, i133, i134, i135, i136, i137, i138, i139, i140, i141, i142, i143, i144, i145, i146, i147, i148, i149, i150, i151, i152, i153, i154, i155, i156, i157, i158, i159, i160, i161, i162, i163, i164, i165, i166, i167, i168, i169, i170, i171, i172, i173, i174, i175, i176, i177, i178, i179, i180, i181, i182, i183, i184, i185, i186, i187, i188, i189, i190, i191, i192, i193, i194, i195, i196, i197, i198, i199, i200, i201, i202, i203, i204, i205, i206, i207, i208, i209, i210, i211, i212, i213, i214, i215, i216, i217, i218, i219, i220, i221, i222, i223, i224, i225, i226, i227, i228, i229, i230, i231, i232, i233, i234, i235, i236, i237, i238, i239, i240, i241, i242, i243, i244, i245, i246, i247, i248, i249, i250, i251, i252, i253, i254, i255) Expected: Traceback (most recent call last): SyntaxError: more than 255 arguments (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: more than 255 arguments ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 177, in test.test_syntax Failed example: f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, i121, i122, i123, i124, i125, i126, i127, i128, i129, i130, i131, i132, i133, i134, i135, i136, i137, i138, i139, i140, i141, i142, i143, i144, i145, i146, i147, i148, i149, i150, i151, i152, i153, i154, i155, i156, i157, i158, i159, i160, i161, i162, i163, i164, i165, i166, i167, i168, i169, i170, i171, i172, i173, i174, i175, i176, i177, i178, i179, i180, i181, i182, i183, i184, i185, i186, i187, i188, i189, i190, i191, i192, i193, i194, i195, i196, i197, i198, i199, i200, i201, i202, i203, i204, i205, i206, i207, i208, i209, i210, i211, i212, i213, i214, i215, i216, i217, i218, i219, i220, i221, i222, i223, i224, i225, i226, i227, i228, i229, i230, i231, i232, i233, i234, i235, i236, i237, i238, i239, i240, i241, i242, i243, (x for x in i244), i245, i246, i247, i248, i249, i250, i251, i252=1, i253=1, i254=1, i255=1) Expected: Traceback (most recent call last): SyntaxError: more than 255 arguments (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: more than 255 arguments ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 207, in test.test_syntax Failed example: f(lambda x: x[0] = 3) Expected: Traceback (most recent call last): SyntaxError: lambda cannot contain assignment (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: lambda cannot contain assignment ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 214, in test.test_syntax Failed example: f(x()=2) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 217, in test.test_syntax Failed example: f(a or b=1) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 220, in test.test_syntax Failed example: f(x.y=1) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 227, in test.test_syntax Failed example: (x for x in x) += 1 Expected: Traceback (most recent call last): SyntaxError: augmented assignment to generator expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to generator expression not possible ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 230, in test.test_syntax Failed example: None += 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 233, in test.test_syntax Failed example: f() += 1 Expected: Traceback (most recent call last): SyntaxError: illegal expression for augmented assignment (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: illegal expression for augmented assignment ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 254, in test.test_syntax Failed example: def test(): for abc in range(10): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 266, in test.test_syntax Failed example: def test(): for abc in range(10): try: pass finally: try: continue except: pass Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 7) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 7 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 279, in test.test_syntax Failed example: def foo(): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 5) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 5 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 288, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 298, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: try: continue finally: pass Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 7) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 7 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 311, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: try: pass except: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 8) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 8 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 328, in test.test_syntax Failed example: try: print 1 break print 2 finally: print 3 Expected: Traceback (most recent call last): ... SyntaxError: 'break' outside loop (, line 3) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 3 SyntaxError: 'break' outside loop ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 372, in test.test_syntax Failed example: if 1: x() = 1 elif 1: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 2) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 2 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 380, in test.test_syntax Failed example: if 1: pass elif 1: x() = 1 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 4) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 4 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 388, in test.test_syntax Failed example: if 1: x() = 1 elif 1: pass else: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 2) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 2 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 398, in test.test_syntax Failed example: if 1: pass elif 1: x() = 1 else: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 4) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 4 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 408, in test.test_syntax Failed example: if 1: pass elif 1: pass else: x() = 1 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 418, in test.test_syntax Failed example: f(a=23, a=234) Expected: Traceback (most recent call last): ... SyntaxError: keyword argument repeated (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword argument repeated ********************************************************************** 1 items had failures: 42 of 50 in test.test_syntax ***Test Failed*** 42 failures. test test_syntax failed -- 42 of 50 doctests failed test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test test_telnetlib failed -- errors occurred; run in verbose mode for details test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18059 refs] [17873 refs] [17873 refs] [17873 refs] [17873 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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_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 327 tests OK. 7 tests failed: test_asyncore test_generators test_genexps test_lib2to3 test_multiprocessing test_syntax test_telnetlib 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl [701505 refs] From python-checkins at python.org Mon Apr 6 22:10:24 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 6 Apr 2009 22:10:24 +0200 (CEST) Subject: [Python-checkins] r71321 - in python/branches/py3k-short-float-repr: PC/pyconfig.h configure configure.in pyconfig.h.in Message-ID: <20090406201024.893B11E4265@bag.python.org> Author: mark.dickinson Date: Mon Apr 6 22:10:23 2009 New Revision: 71321 Log: Add autoconf tests to detect IEEE 754 doubles and their endianness Modified: python/branches/py3k-short-float-repr/PC/pyconfig.h python/branches/py3k-short-float-repr/configure python/branches/py3k-short-float-repr/configure.in python/branches/py3k-short-float-repr/pyconfig.h.in Modified: python/branches/py3k-short-float-repr/PC/pyconfig.h ============================================================================== --- python/branches/py3k-short-float-repr/PC/pyconfig.h (original) +++ python/branches/py3k-short-float-repr/PC/pyconfig.h Mon Apr 6 22:10:23 2009 @@ -752,4 +752,8 @@ socket handles greater than FD_SETSIZE */ #define Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE +/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the + least significant byte first */ +#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1 + #endif /* !Py_CONFIG_H */ Modified: python/branches/py3k-short-float-repr/configure ============================================================================== --- python/branches/py3k-short-float-repr/configure (original) +++ python/branches/py3k-short-float-repr/configure Mon Apr 6 22:10:23 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 71261 . +# From configure.in Revision: 71287 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.1. # @@ -21680,6 +21680,152 @@ LIBS_SAVE=$LIBS LIBS="$LIBS $LIBM" +{ echo "$as_me:$LINENO: checking whether C doubles are little-endian IEEE 754 binary64" >&5 +echo $ECHO_N "checking whether C doubles are little-endian IEEE 754 binary64... $ECHO_C" >&6; } +if test "${ac_cv_little_endian_double+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +if test "$cross_compiling" = yes; then + ac_cv_little_endian_double=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +int main() { + double x = 9006104071832581.0; + if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0) + return 0; + else + return 1; +} + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_little_endian_double=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_little_endian_double=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi + +{ echo "$as_me:$LINENO: result: $ac_cv_little_endian_double" >&5 +echo "${ECHO_T}$ac_cv_little_endian_double" >&6; } +if test "$ac_cv_little_endian_double" = yes +then + +cat >>confdefs.h <<\_ACEOF +#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1 +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking whether C doubles are big-endian IEEE 754 binary64" >&5 +echo $ECHO_N "checking whether C doubles are big-endian IEEE 754 binary64... $ECHO_C" >&6; } +if test "${ac_cv_big_endian_double+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +if test "$cross_compiling" = yes; then + ac_cv_big_endian_double=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +int main() { + double x = 9006104071832581.0; + if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0) + return 0; + else + return 1; +} + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_big_endian_double=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_big_endian_double=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi + +{ echo "$as_me:$LINENO: result: $ac_cv_big_endian_double" >&5 +echo "${ECHO_T}$ac_cv_big_endian_double" >&6; } +if test "$ac_cv_big_endian_double" = yes +then + +cat >>confdefs.h <<\_ACEOF +#define DOUBLE_IS_BIG_ENDIAN_IEEE754 1 +_ACEOF + +fi + # Detect whether system arithmetic is subject to x87-style double # rounding issues. The result of this test has little meaning on non # IEEE 754 platforms. On IEEE 754, test should return 1 if rounding Modified: python/branches/py3k-short-float-repr/configure.in ============================================================================== --- python/branches/py3k-short-float-repr/configure.in (original) +++ python/branches/py3k-short-float-repr/configure.in Mon Apr 6 22:10:23 2009 @@ -3098,6 +3098,54 @@ LIBS_SAVE=$LIBS LIBS="$LIBS $LIBM" +AC_MSG_CHECKING(whether C doubles are little-endian IEEE 754 binary64) +AC_CACHE_VAL(ac_cv_little_endian_double, [ +AC_TRY_RUN([ +#include +#include +int main() { + double x = 9006104071832581.0; + if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0) + return 0; + else + return 1; +} +], +ac_cv_little_endian_double=yes, +ac_cv_little_endian_double=no, +ac_cv_little_endian_double=no)]) +AC_MSG_RESULT($ac_cv_little_endian_double) +if test "$ac_cv_little_endian_double" = yes +then + AC_DEFINE(DOUBLE_IS_LITTLE_ENDIAN_IEEE754, 1, + [Define if C doubles are 64-bit IEEE 754 binary format, stored + with the least significant byte first]) +fi + +AC_MSG_CHECKING(whether C doubles are big-endian IEEE 754 binary64) +AC_CACHE_VAL(ac_cv_big_endian_double, [ +AC_TRY_RUN([ +#include +#include +int main() { + double x = 9006104071832581.0; + if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0) + return 0; + else + return 1; +} +], +ac_cv_big_endian_double=yes, +ac_cv_big_endian_double=no, +ac_cv_big_endian_double=no)]) +AC_MSG_RESULT($ac_cv_big_endian_double) +if test "$ac_cv_big_endian_double" = yes +then + AC_DEFINE(DOUBLE_IS_BIG_ENDIAN_IEEE754, 1, + [Define if C doubles are 64-bit IEEE 754 binary format, stored + with the most significant byte first]) +fi + # Detect whether system arithmetic is subject to x87-style double # rounding issues. The result of this test has little meaning on non # IEEE 754 platforms. On IEEE 754, test should return 1 if rounding Modified: python/branches/py3k-short-float-repr/pyconfig.h.in ============================================================================== --- python/branches/py3k-short-float-repr/pyconfig.h.in (original) +++ python/branches/py3k-short-float-repr/pyconfig.h.in Mon Apr 6 22:10:23 2009 @@ -15,6 +15,14 @@ /* Define if you have the Mach cthreads package */ #undef C_THREADS +/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the most + significant byte first */ +#undef DOUBLE_IS_BIG_ENDIAN_IEEE754 + +/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the + least significant byte first */ +#undef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 + /* Define if --enable-ipv6 is specified */ #undef ENABLE_IPV6 From nnorwitz at gmail.com Mon Apr 6 22:16:28 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 6 Apr 2009 16:16:28 -0400 Subject: [Python-checkins] Python Regression Test Failures opt (7) Message-ID: <20090406201628.GA31655@python.psfb.org> 327 tests OK. 7 tests failed: test_asyncore test_generators test_genexps test_lib2to3 test_multiprocessing test_syntax test_telnetlib 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ast test_asynchat test_asyncore test test_asyncore failed -- errors occurred; run in verbose mode for details 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils [17363 refs] [17363 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_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_gdbm test_generators ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: f=lambda: (yield 1),(yield 2) Expected: Traceback (most recent call last): ... SyntaxError: 'yield' outside function (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: 'yield' outside function ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): x = yield = y Expected: Traceback (most recent call last): ... SyntaxError: assignment to yield expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: assignment to yield expression not possible ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): (yield bar) = y Expected: Traceback (most recent call last): ... SyntaxError: can't assign to yield expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to yield expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): (yield bar) += y Expected: Traceback (most recent call last): ... SyntaxError: augmented assignment to yield expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to yield expression not possible ********************************************************************** 1 items had failures: 4 of 99 in test.test_generators.__test__.coroutine ***Test Failed*** 4 failures. test test_generators failed -- 4 of 284 doctests failed test_genericpath test_genexps ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_genexps.py", line ?, in test.test_genexps.__test__.doctests Failed example: (y for y in (1,2)) = 10 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to generator expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to generator expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_genexps.py", line ?, in test.test_genexps.__test__.doctests Failed example: (y for y in (1,2)) += 10 Expected: Traceback (most recent call last): ... SyntaxError: augmented assignment to generator expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to generator expression not possible ********************************************************************** 1 items had failures: 2 of 75 in test.test_genexps.__test__.doctests ***Test Failed*** 2 failures. test test_genexps failed -- 2 of 75 doctests failed 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 [13183 refs] [13183 refs] [13183 refs] [23375 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 test_lib2to3 crashed -- : No module named myfixes 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 test_multiprocessing crashed -- : cannot import name SkipTest test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18903 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 30, in test.test_syntax Failed example: obj.None = 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 34, in test.test_syntax Failed example: None = 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 42, in test.test_syntax Failed example: () = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to () (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to () ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 46, in test.test_syntax Failed example: f() = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to function call (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 50, in test.test_syntax Failed example: del f() Expected: Traceback (most recent call last): SyntaxError: can't delete function call (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't delete function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 54, in test.test_syntax Failed example: a + 1 = 2 Expected: Traceback (most recent call last): SyntaxError: can't assign to operator (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to operator ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 58, in test.test_syntax Failed example: (x for x in x) = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to generator expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to generator expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 62, in test.test_syntax Failed example: 1 = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 66, in test.test_syntax Failed example: "abc" = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 70, in test.test_syntax Failed example: `1` = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to repr (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to repr ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 79, in test.test_syntax Failed example: (a, "b", c) = (1, 2, 3) Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 83, in test.test_syntax Failed example: [a, b, c + 1] = [1, 2, 3] Expected: Traceback (most recent call last): SyntaxError: can't assign to operator (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to operator ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 87, in test.test_syntax Failed example: a if 1 else b = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to conditional expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to conditional expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 93, in test.test_syntax Failed example: def f(None=1): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 101, in test.test_syntax Failed example: def f(x, y=1, z): pass Expected: Traceback (most recent call last): SyntaxError: non-default argument follows default argument (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: non-default argument follows default argument ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 106, in test.test_syntax Failed example: def f(x, None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 111, in test.test_syntax Failed example: def f(*None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 116, in test.test_syntax Failed example: def f(**None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 124, in test.test_syntax Failed example: def None(x): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 137, in test.test_syntax Failed example: f(x for x in L, 1) Expected: Traceback (most recent call last): SyntaxError: Generator expression must be parenthesized if not sole argument (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: Generator expression must be parenthesized if not sole argument ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 143, in test.test_syntax Failed example: f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, i121, i122, i123, i124, i125, i126, i127, i128, i129, i130, i131, i132, i133, i134, i135, i136, i137, i138, i139, i140, i141, i142, i143, i144, i145, i146, i147, i148, i149, i150, i151, i152, i153, i154, i155, i156, i157, i158, i159, i160, i161, i162, i163, i164, i165, i166, i167, i168, i169, i170, i171, i172, i173, i174, i175, i176, i177, i178, i179, i180, i181, i182, i183, i184, i185, i186, i187, i188, i189, i190, i191, i192, i193, i194, i195, i196, i197, i198, i199, i200, i201, i202, i203, i204, i205, i206, i207, i208, i209, i210, i211, i212, i213, i214, i215, i216, i217, i218, i219, i220, i221, i222, i223, i224, i225, i226, i227, i228, i229, i230, i231, i232, i233, i234, i235, i236, i237, i238, i239, i240, i241, i242, i243, i244, i245, i246, i247, i248, i249, i250, i251, i252, i253, i254, i255) Expected: Traceback (most recent call last): SyntaxError: more than 255 arguments (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: more than 255 arguments ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 177, in test.test_syntax Failed example: f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, i121, i122, i123, i124, i125, i126, i127, i128, i129, i130, i131, i132, i133, i134, i135, i136, i137, i138, i139, i140, i141, i142, i143, i144, i145, i146, i147, i148, i149, i150, i151, i152, i153, i154, i155, i156, i157, i158, i159, i160, i161, i162, i163, i164, i165, i166, i167, i168, i169, i170, i171, i172, i173, i174, i175, i176, i177, i178, i179, i180, i181, i182, i183, i184, i185, i186, i187, i188, i189, i190, i191, i192, i193, i194, i195, i196, i197, i198, i199, i200, i201, i202, i203, i204, i205, i206, i207, i208, i209, i210, i211, i212, i213, i214, i215, i216, i217, i218, i219, i220, i221, i222, i223, i224, i225, i226, i227, i228, i229, i230, i231, i232, i233, i234, i235, i236, i237, i238, i239, i240, i241, i242, i243, (x for x in i244), i245, i246, i247, i248, i249, i250, i251, i252=1, i253=1, i254=1, i255=1) Expected: Traceback (most recent call last): SyntaxError: more than 255 arguments (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: more than 255 arguments ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 207, in test.test_syntax Failed example: f(lambda x: x[0] = 3) Expected: Traceback (most recent call last): SyntaxError: lambda cannot contain assignment (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: lambda cannot contain assignment ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 214, in test.test_syntax Failed example: f(x()=2) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 217, in test.test_syntax Failed example: f(a or b=1) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 220, in test.test_syntax Failed example: f(x.y=1) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 227, in test.test_syntax Failed example: (x for x in x) += 1 Expected: Traceback (most recent call last): SyntaxError: augmented assignment to generator expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to generator expression not possible ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 230, in test.test_syntax Failed example: None += 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 233, in test.test_syntax Failed example: f() += 1 Expected: Traceback (most recent call last): SyntaxError: illegal expression for augmented assignment (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: illegal expression for augmented assignment ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 254, in test.test_syntax Failed example: def test(): for abc in range(10): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 266, in test.test_syntax Failed example: def test(): for abc in range(10): try: pass finally: try: continue except: pass Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 7) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 7 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 279, in test.test_syntax Failed example: def foo(): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 5) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 5 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 288, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 298, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: try: continue finally: pass Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 7) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 7 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 311, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: try: pass except: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 8) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 8 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 328, in test.test_syntax Failed example: try: print 1 break print 2 finally: print 3 Expected: Traceback (most recent call last): ... SyntaxError: 'break' outside loop (, line 3) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 3 SyntaxError: 'break' outside loop ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 372, in test.test_syntax Failed example: if 1: x() = 1 elif 1: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 2) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 2 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 380, in test.test_syntax Failed example: if 1: pass elif 1: x() = 1 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 4) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 4 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 388, in test.test_syntax Failed example: if 1: x() = 1 elif 1: pass else: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 2) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 2 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 398, in test.test_syntax Failed example: if 1: pass elif 1: x() = 1 else: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 4) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 4 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 408, in test.test_syntax Failed example: if 1: pass elif 1: pass else: x() = 1 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 418, in test.test_syntax Failed example: f(a=23, a=234) Expected: Traceback (most recent call last): ... SyntaxError: keyword argument repeated (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword argument repeated ********************************************************************** 1 items had failures: 42 of 50 in test.test_syntax ***Test Failed*** 42 failures. test test_syntax failed -- 42 of 50 doctests failed test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test test_telnetlib failed -- errors occurred; run in verbose mode for details test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18896 refs] [17873 refs] [17873 refs] [17873 refs] [17873 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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_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 327 tests OK. 7 tests failed: test_asyncore test_generators test_genexps test_lib2to3 test_multiprocessing test_syntax test_telnetlib 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl [700777 refs] From python-checkins at python.org Mon Apr 6 22:39:11 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 6 Apr 2009 22:39:11 +0200 (CEST) Subject: [Python-checkins] r71322 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090406203911.9EC831E400C@bag.python.org> Author: mark.dickinson Date: Mon Apr 6 22:39:10 2009 New Revision: 71322 Log: Link autoconf double format detection to dtoa.c defines Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Mon Apr 6 22:39:10 2009 @@ -101,10 +101,6 @@ */ /* - * #define IEEE_8087 for IEEE-arithmetic machines where the least - * significant byte has the lowest address. - * #define IEEE_MC68k for IEEE-arithmetic machines where the most - * significant byte has the lowest address. * #define Long int on machines with 32-bit ints and 64-bit longs. * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 * and strtod and dtoa should round accordingly. Unless Trust_FLT_ROUNDS @@ -126,16 +122,15 @@ #define MALLOC PyMem_Malloc #define FREE PyMem_Free -/* use WORDS_BIGENDIAN to determine float endianness. This assumes that ints - and floats share the same endianness on the target machine, which appears - to be true for every platform that Python currently cares about. We're - also assuming IEEE 754 float format for now. */ - -#ifdef WORDS_BIGENDIAN -#define IEEE_MC68k -#else +#ifdef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 #define IEEE_8087 #endif +#ifdef DOUBLE_IS_BIG_ENDIAN_IEEE754 +#define IEEE_MC68k +#endif +#if defined(IEEE_8087) + defined(IEEE_MC68k) != 1 +#error "Exactly one of IEEE_8087 or IEEE_MC68k should be defined." +#endif #if SIZEOF_LONG==8 && SIZEOF_INT==4 typedef int Long; @@ -168,22 +163,10 @@ #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) static double private_mem[PRIVATE_mem], *pmem_next = private_mem; -#undef IEEE_Arith -#ifdef IEEE_MC68k -#define IEEE_Arith -#endif -#ifdef IEEE_8087 -#define IEEE_Arith -#endif - #ifdef __cplusplus extern "C" { #endif -#if defined(IEEE_8087) + defined(IEEE_MC68k) != 1 -#error "Exactly one of IEEE_8087 or IEEE_MC68k should be defined." -#endif - typedef union { double d; ULong L[2]; } U; #ifdef IEEE_8087 From python-checkins at python.org Mon Apr 6 22:57:16 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 6 Apr 2009 22:57:16 +0200 (CEST) Subject: [Python-checkins] r71323 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090406205716.948041E400C@bag.python.org> Author: eric.smith Date: Mon Apr 6 22:57:16 2009 New Revision: 71323 Log: Removed bogus comment. Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Mon Apr 6 22:57:16 2009 @@ -589,12 +589,6 @@ /* We got digits back, format them. */ - /* this replaces the various tests in other places like: - if (type == 'f' && fabs(x) >= 1e50) - type = 'g'; - over time, those tests should be deleted - */ - /* Detect if we're using exponents or not, and figure out how many additional digits we need beyond those provided by dtoa. */ switch (format_code) { From python-checkins at python.org Mon Apr 6 22:59:24 2009 From: python-checkins at python.org (matthias.klose) Date: Mon, 6 Apr 2009 22:59:24 +0200 (CEST) Subject: [Python-checkins] r71324 - python/branches/release30-maint/Misc/NEWS Message-ID: <20090406205924.781561E400C@bag.python.org> Author: matthias.klose Date: Mon Apr 6 22:59:24 2009 New Revision: 71324 Log: Misc/NEWS: Move all news items checked in after the 3.0.1 release to the 3.0.2 section. Modified: python/branches/release30-maint/Misc/NEWS Modified: python/branches/release30-maint/Misc/NEWS ============================================================================== --- python/branches/release30-maint/Misc/NEWS (original) +++ python/branches/release30-maint/Misc/NEWS Mon Apr 6 22:59:24 2009 @@ -30,6 +30,29 @@ Library ------- +- Issue #1491431: Fixed distutils.filelist.glob_to_re for edge cases. + Initial fix by Wayne Davison. + +- Issue #4792: Prevent a segfault in _tkinter by using the + guaranteed to be safe interp argument given to the PythonCmd in place of + the Tcl interpreter taken from a PythonCmd_ClientData. + +- Issue #5193: Guarantee that tkinter.Text.search returns a string. + +- Issue #5334: array.fromfile() failed to insert values when EOFError was + raised. + +- Issue #5385: Fixed mmap crash after resize failure on windows. + +- Issue #5401: Fixed a performance problem in mimetypes when ``from mimetypes + import guess_extension`` was used. + +- Issue #1733986: Fixed mmap crash in accessing elements of second map object + with same tagname but larger size than first map. (Windows) + +- Issue #5386: mmap.write_byte didn't check map size, so it could cause buffer + overrun. + - Issue 2625: added missing items() call to the for loop in mailbox.MH.get_message(). @@ -187,28 +210,6 @@ Library ------- -- Issue #1491431: Fixed distutils.filelist.glob_to_re for edge cases. - Initial fix by Wayne Davison. - -- Issue #4792: Prevent a segfault in _tkinter by using the - guaranteed to be safe interp argument given to the PythonCmd in place of - the Tcl interpreter taken from a PythonCmd_ClientData. - -- Issue #5193: Guarantee that tkinter.Text.search returns a string. - -- Issue #5334: array.fromfile() failed to insert values when EOFError was raised. - -- Issue #5385: Fixed mmap crash after resize failure on windows. - -- Issue #5401: Fixed a performance problem in mimetypes when ``from mimetypes - import guess_extension`` was used. - -- Issue #1733986: Fixed mmap crash in accessing elements of second map object - with same tagname but larger size than first map. (Windows) - -- Issue #5386: mmap.write_byte didn't check map size, so it could cause buffer - overrun. - - Issue #4998: The memory saving effect of __slots__ had been lost on Fractions which inherited from numbers.py which did not have __slots__ defined. The numbers hierarchy now has its own __slots__ declarations. From python-checkins at python.org Mon Apr 6 23:05:19 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 6 Apr 2009 23:05:19 +0200 (CEST) Subject: [Python-checkins] r71325 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090406210519.364851E40D9@bag.python.org> Author: mark.dickinson Date: Mon Apr 6 23:05:18 2009 New Revision: 71325 Log: Fix up integer defines Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Mon Apr 6 23:05:18 2009 @@ -101,7 +101,6 @@ */ /* - * #define Long int on machines with 32-bit ints and 64-bit longs. * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 * and strtod and dtoa should round accordingly. Unless Trust_FLT_ROUNDS * is also #defined, fegetround() will be queried for the rounding mode. @@ -132,18 +131,17 @@ #error "Exactly one of IEEE_8087 or IEEE_MC68k should be defined." #endif -#if SIZEOF_LONG==8 && SIZEOF_INT==4 -typedef int Long; -typedef unsigned int ULong; -#elif SIZEOF_LONG==4 -typedef long Long; -typedef unsigned long ULong; +#if defined(HAVE_UINT32_T) && defined(HAVE_INT32_T) +typedef PY_UINT32_T ULong; +typedef PY_INT32_T Long; #else #error "Failed to find an exact-width 32-bit integer type" #endif -#ifndef HAVE_LONG_LONG -#define NO_LONG_LONG +#if defined(HAVE_UINT64_T) +#define ULLong PY_UINT64_T +#else +#undef ULLong #endif #undef DEBUG @@ -261,17 +259,6 @@ #define FFFFFFFF 0xffffffffUL -#ifdef NO_LONG_LONG -#undef ULLong -#else /* long long available */ -#ifndef Llong -#define Llong long long -#endif -#ifndef ULLong -#define ULLong unsigned Llong -#endif -#endif /* NO_LONG_LONG */ - #define Kmax 7 struct From python-checkins at python.org Mon Apr 6 23:16:46 2009 From: python-checkins at python.org (martin.v.loewis) Date: Mon, 6 Apr 2009 23:16:46 +0200 (CEST) Subject: [Python-checkins] r71326 - python/branches/py3k/Tools/msi/uuids.py Message-ID: <20090406211646.E4D0C1E403F@bag.python.org> Author: martin.v.loewis Date: Mon Apr 6 23:16:46 2009 New Revision: 71326 Log: Add uuids for 3.1 Modified: python/branches/py3k/Tools/msi/uuids.py Modified: python/branches/py3k/Tools/msi/uuids.py ============================================================================== --- python/branches/py3k/Tools/msi/uuids.py (original) +++ python/branches/py3k/Tools/msi/uuids.py Mon Apr 6 23:16:46 2009 @@ -67,4 +67,10 @@ '3.0.1150':'{de2f2d9c-53e2-40ee-8209-74da63cb060e}', # 3.0.1 '3.0.2121':'{cef79e7f-9809-49e2-afd2-e24148d7c855}', # 3.0.2c1 '3.0.2150':'{0cf3b95a-8382-4607-9779-c36407ff362c}', # 3.0.2 + '3.1.101': '{c423eada-c498-4d51-9eb4-bfeae647e0a0}', # 3.1a1 + '3.1.102': '{f6e199bf-dc64-42f3-87d4-1525991a013e}', # 3.1a2 + '3.1.111': '{c3c82893-69b2-4676-8554-1b6ee6c191e9}', # 3.1b1 + '3.1.121': '{da2b5170-12f3-4d99-8a1f-54926cca7acd}', # 3.1c1 + '3.1.122': '{bceb5133-e2ee-4109-951f-ac7e941a1692}', # 3.1c1 + '3.1.150': '{3ad61ee5-81d2-4d7e-adef-da1dd37277d1}', # 3.1.0 } From nnorwitz at gmail.com Mon Apr 6 23:16:48 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 6 Apr 2009 17:16:48 -0400 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20090406211648.GA17765@python.psfb.org> More important issues: ---------------------- test_softspace leaked [0, -80, 0] references, sum=-80 Less important issues: ---------------------- test_cmd_line leaked [-25, 0, 25] references, sum=0 test_httpservers leaked [5, -7, -24] references, sum=-26 test_smtplib leaked [-1, 1, 109] references, sum=109 test_socketserver leaked [0, 0, 80] references, sum=80 test_sys leaked [-42, 21, 21] references, sum=0 test_threading leaked [48, 48, 48] references, sum=144 test_urllib2_localnet leaked [3, 3, 3] references, sum=9 From python-checkins at python.org Mon Apr 6 23:21:20 2009 From: python-checkins at python.org (hirokazu.yamamoto) Date: Mon, 6 Apr 2009 23:21:20 +0200 (CEST) Subject: [Python-checkins] r71327 - in python/branches/release30-maint: Modules/_multiprocessing/multiprocessing.h Message-ID: <20090406212120.B4D171E403F@bag.python.org> Author: hirokazu.yamamoto Date: Mon Apr 6 23:21:20 2009 New Revision: 71327 Log: Merged revisions 70987 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r70987 | jesse.noller | 2009-04-02 05:51:28 +0900 | 9 lines Merged revisions 70953 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70953 | hirokazu.yamamoto | 2009-04-01 10:13:52 -0500 (Wed, 01 Apr 2009) | 1 line Fixed compile error on windows. ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Modules/_multiprocessing/multiprocessing.h Modified: python/branches/release30-maint/Modules/_multiprocessing/multiprocessing.h ============================================================================== --- python/branches/release30-maint/Modules/_multiprocessing/multiprocessing.h (original) +++ python/branches/release30-maint/Modules/_multiprocessing/multiprocessing.h Mon Apr 6 23:21:20 2009 @@ -16,6 +16,9 @@ # include # include # include /* getpid() */ +# ifdef Py_DEBUG +# include +# endif # define SEM_HANDLE HANDLE # define SEM_VALUE_MAX LONG_MAX #else From nnorwitz at gmail.com Mon Apr 6 23:32:51 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 6 Apr 2009 17:32:51 -0400 Subject: [Python-checkins] Python Regression Test Failures all (7) Message-ID: <20090406213251.GA21444@python.psfb.org> 332 tests OK. 7 tests failed: test_asyncore test_generators test_genexps test_lib2to3 test_multiprocessing test_syntax test_telnetlib 26 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_cd test_cl test_epoll test_gl test_imgfile test_ioctl test_kqueue test_macos test_macostools 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ast test_asynchat test_asyncore test test_asyncore failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_asyncore.py", line 144, in test_readwrite self.assertEqual(tobj.read, True) AssertionError: False != True 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-17773 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils 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_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_gdbm test_generators ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: f=lambda: (yield 1),(yield 2) Expected: Traceback (most recent call last): ... SyntaxError: 'yield' outside function (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: 'yield' outside function ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): x = yield = y Expected: Traceback (most recent call last): ... SyntaxError: assignment to yield expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: assignment to yield expression not possible ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): (yield bar) = y Expected: Traceback (most recent call last): ... SyntaxError: can't assign to yield expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to yield expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): (yield bar) += y Expected: Traceback (most recent call last): ... SyntaxError: augmented assignment to yield expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to yield expression not possible ********************************************************************** 1 items had failures: 4 of 99 in test.test_generators.__test__.coroutine ***Test Failed*** 4 failures. test test_generators failed -- 4 of 284 doctests failed test_genericpath test_genexps ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_genexps.py", line ?, in test.test_genexps.__test__.doctests Failed example: (y for y in (1,2)) = 10 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to generator expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to generator expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_genexps.py", line ?, in test.test_genexps.__test__.doctests Failed example: (y for y in (1,2)) += 10 Expected: Traceback (most recent call last): ... SyntaxError: augmented assignment to generator expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to generator expression not possible ********************************************************************** 1 items had failures: 2 of 75 in test.test_genexps.__test__.doctests ***Test Failed*** 2 failures. test test_genexps failed -- 2 of 75 doctests failed 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 [13183 refs] [13183 refs] [13183 refs] [23375 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 test_lib2to3 crashed -- : No module named myfixes 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 test_multiprocessing crashed -- : cannot import name SkipTest test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18903 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib test_socket test_socketserver 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 30, in test.test_syntax Failed example: obj.None = 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 34, in test.test_syntax Failed example: None = 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 42, in test.test_syntax Failed example: () = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to () (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to () ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 46, in test.test_syntax Failed example: f() = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to function call (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 50, in test.test_syntax Failed example: del f() Expected: Traceback (most recent call last): SyntaxError: can't delete function call (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't delete function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 54, in test.test_syntax Failed example: a + 1 = 2 Expected: Traceback (most recent call last): SyntaxError: can't assign to operator (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to operator ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 58, in test.test_syntax Failed example: (x for x in x) = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to generator expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to generator expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 62, in test.test_syntax Failed example: 1 = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 66, in test.test_syntax Failed example: "abc" = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 70, in test.test_syntax Failed example: `1` = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to repr (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to repr ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 79, in test.test_syntax Failed example: (a, "b", c) = (1, 2, 3) Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 83, in test.test_syntax Failed example: [a, b, c + 1] = [1, 2, 3] Expected: Traceback (most recent call last): SyntaxError: can't assign to operator (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to operator ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 87, in test.test_syntax Failed example: a if 1 else b = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to conditional expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to conditional expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 93, in test.test_syntax Failed example: def f(None=1): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 101, in test.test_syntax Failed example: def f(x, y=1, z): pass Expected: Traceback (most recent call last): SyntaxError: non-default argument follows default argument (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: non-default argument follows default argument ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 106, in test.test_syntax Failed example: def f(x, None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 111, in test.test_syntax Failed example: def f(*None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 116, in test.test_syntax Failed example: def f(**None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 124, in test.test_syntax Failed example: def None(x): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 137, in test.test_syntax Failed example: f(x for x in L, 1) Expected: Traceback (most recent call last): SyntaxError: Generator expression must be parenthesized if not sole argument (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: Generator expression must be parenthesized if not sole argument ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 143, in test.test_syntax Failed example: f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, i121, i122, i123, i124, i125, i126, i127, i128, i129, i130, i131, i132, i133, i134, i135, i136, i137, i138, i139, i140, i141, i142, i143, i144, i145, i146, i147, i148, i149, i150, i151, i152, i153, i154, i155, i156, i157, i158, i159, i160, i161, i162, i163, i164, i165, i166, i167, i168, i169, i170, i171, i172, i173, i174, i175, i176, i177, i178, i179, i180, i181, i182, i183, i184, i185, i186, i187, i188, i189, i190, i191, i192, i193, i194, i195, i196, i197, i198, i199, i200, i201, i202, i203, i204, i205, i206, i207, i208, i209, i210, i211, i212, i213, i214, i215, i216, i217, i218, i219, i220, i221, i222, i223, i224, i225, i226, i227, i228, i229, i230, i231, i232, i233, i234, i235, i236, i237, i238, i239, i240, i241, i242, i243, i244, i245, i246, i247, i248, i249, i250, i251, i252, i253, i254, i255) Expected: Traceback (most recent call last): SyntaxError: more than 255 arguments (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: more than 255 arguments ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 177, in test.test_syntax Failed example: f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, i121, i122, i123, i124, i125, i126, i127, i128, i129, i130, i131, i132, i133, i134, i135, i136, i137, i138, i139, i140, i141, i142, i143, i144, i145, i146, i147, i148, i149, i150, i151, i152, i153, i154, i155, i156, i157, i158, i159, i160, i161, i162, i163, i164, i165, i166, i167, i168, i169, i170, i171, i172, i173, i174, i175, i176, i177, i178, i179, i180, i181, i182, i183, i184, i185, i186, i187, i188, i189, i190, i191, i192, i193, i194, i195, i196, i197, i198, i199, i200, i201, i202, i203, i204, i205, i206, i207, i208, i209, i210, i211, i212, i213, i214, i215, i216, i217, i218, i219, i220, i221, i222, i223, i224, i225, i226, i227, i228, i229, i230, i231, i232, i233, i234, i235, i236, i237, i238, i239, i240, i241, i242, i243, (x for x in i244), i245, i246, i247, i248, i249, i250, i251, i252=1, i253=1, i254=1, i255=1) Expected: Traceback (most recent call last): SyntaxError: more than 255 arguments (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: more than 255 arguments ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 207, in test.test_syntax Failed example: f(lambda x: x[0] = 3) Expected: Traceback (most recent call last): SyntaxError: lambda cannot contain assignment (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: lambda cannot contain assignment ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 214, in test.test_syntax Failed example: f(x()=2) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 217, in test.test_syntax Failed example: f(a or b=1) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 220, in test.test_syntax Failed example: f(x.y=1) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 227, in test.test_syntax Failed example: (x for x in x) += 1 Expected: Traceback (most recent call last): SyntaxError: augmented assignment to generator expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to generator expression not possible ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 230, in test.test_syntax Failed example: None += 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 233, in test.test_syntax Failed example: f() += 1 Expected: Traceback (most recent call last): SyntaxError: illegal expression for augmented assignment (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: illegal expression for augmented assignment ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 254, in test.test_syntax Failed example: def test(): for abc in range(10): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 266, in test.test_syntax Failed example: def test(): for abc in range(10): try: pass finally: try: continue except: pass Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 7) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 7 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 279, in test.test_syntax Failed example: def foo(): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 5) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 5 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 288, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 298, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: try: continue finally: pass Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 7) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 7 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 311, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: try: pass except: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 8) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 8 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 328, in test.test_syntax Failed example: try: print 1 break print 2 finally: print 3 Expected: Traceback (most recent call last): ... SyntaxError: 'break' outside loop (, line 3) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 3 SyntaxError: 'break' outside loop ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 372, in test.test_syntax Failed example: if 1: x() = 1 elif 1: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 2) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 2 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 380, in test.test_syntax Failed example: if 1: pass elif 1: x() = 1 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 4) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 4 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 388, in test.test_syntax Failed example: if 1: x() = 1 elif 1: pass else: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 2) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 2 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 398, in test.test_syntax Failed example: if 1: pass elif 1: x() = 1 else: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 4) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 4 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 408, in test.test_syntax Failed example: if 1: pass elif 1: pass else: x() = 1 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 418, in test.test_syntax Failed example: f(a=23, a=234) Expected: Traceback (most recent call last): ... SyntaxError: keyword argument repeated (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword argument repeated ********************************************************************** 1 items had failures: 42 of 50 in test.test_syntax ***Test Failed*** 42 failures. test test_syntax failed -- 42 of 50 doctests failed test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test test_telnetlib failed -- errors occurred; run in verbose mode for details test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18896 refs] [17873 refs] [17873 refs] [17873 refs] [17873 refs] test_threading_local test_threadsignals test_time test_timeout 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_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllibnet test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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_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 332 tests OK. 7 tests failed: test_asyncore test_generators test_genexps test_lib2to3 test_multiprocessing test_syntax test_telnetlib 26 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_cd test_cl test_epoll test_gl test_imgfile test_ioctl test_kqueue test_macos test_macostools 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl [716537 refs] From python-checkins at python.org Mon Apr 6 23:52:21 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 6 Apr 2009 23:52:21 +0200 (CEST) Subject: [Python-checkins] r71328 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090406215221.2E7D61E4011@bag.python.org> Author: mark.dickinson Date: Mon Apr 6 23:52:20 2009 New Revision: 71328 Log: Silence a compiler warning from gcc Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Mon Apr 6 23:52:20 2009 @@ -1164,6 +1164,8 @@ /* Compare b/d with s0 */ + assert(nd > 0); + dd = 9999; /* silence gcc compiler warning */ for(i = 0; i < nd0; ) { if ((dd = s0[i++] - '0' - dig)) goto ret; From python-checkins at python.org Mon Apr 6 23:53:33 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 6 Apr 2009 23:53:33 +0200 (CEST) Subject: [Python-checkins] r71329 - python/trunk/Lib/socket.py Message-ID: <20090406215333.49A271E4011@bag.python.org> Author: benjamin.peterson Date: Mon Apr 6 23:53:33 2009 New Revision: 71329 Log: add create_connection to __all__ #5711 Modified: python/trunk/Lib/socket.py Modified: python/trunk/Lib/socket.py ============================================================================== --- python/trunk/Lib/socket.py (original) +++ python/trunk/Lib/socket.py Mon Apr 6 23:53:33 2009 @@ -88,7 +88,7 @@ except ImportError: EBADF = 9 -__all__ = ["getfqdn"] +__all__ = ["getfqdn", "create_connection"] __all__.extend(os._get_exports_list(_socket)) From buildbot at python.org Mon Apr 6 23:54:30 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 06 Apr 2009 21:54:30 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 3.x Message-ID: <20090406215431.1BFFD1E4011@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%203.x/builds/690 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: martin.v.loewis,raymond.hettinger BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Tue Apr 7 00:02:08 2009 From: python-checkins at python.org (eric.smith) Date: Tue, 7 Apr 2009 00:02:08 +0200 (CEST) Subject: [Python-checkins] r71330 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090406220208.5ED061E4011@bag.python.org> Author: eric.smith Date: Tue Apr 7 00:02:07 2009 New Revision: 71330 Log: Modify format_float_short() to compute how much memory to allocate. This removes the last hard-coded buffer in this file. Mark: Please review this, I'm sure it could be simplified. In particular, min_digits1 feels hackish. Also, I'm assuming max 3 digits for the exponent, which might not be correct. Maybe we should enforce that the abs(exponent) < 1000? Still need to detect errors in return value from_Py_dg_dtoa and handle that correctly. Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Tue Apr 7 00:02:07 2009 @@ -547,11 +547,13 @@ int always_add_sign, int add_dot_0_if_integer, int use_alt_formatting, char **float_strings) { - char* p = (char *)PyMem_Malloc(512); - char* buf = p; + char *buf = NULL; + char *p; + Py_ssize_t bufsize = 0; char *digits, *digits_end; int decpt, sign, exp_len, dec_pos, use_exp = 0; Py_ssize_t n_digits, min_digits = 0; + Py_ssize_t min_digits1; /* _Py_dg_dtoa returns a digit string (no decimal point or exponent). Must be matched by a call to _Py_dg_freedtoa. */ @@ -563,25 +565,35 @@ /* Infinities and nans here; adapt Gay's output, so convert Infinity to inf and NaN to nan, and ignore sign of nan. Then return. */ + + /* We only need 5 bytes to hold the result "+inf\0" . */ + bufsize = 5; /* Used later in an assert. */ + buf = (char *)PyMem_Malloc(bufsize); + if (buf == NULL) { + PyErr_NoMemory(); + goto exit; + } + p = buf; + if (digits[0] == 'i' || digits[0] == 'I') { if (sign == 1) { - *buf++ = '-'; + *p++ = '-'; } else if (always_add_sign) { - *buf++ = '+'; + *p++ = '+'; } - strncpy(buf, float_strings[OFS_INF], 3); - buf += 3; + strncpy(p, float_strings[OFS_INF], 3); + p += 3; } else if (digits[0] == 'n' || digits[0] == 'N') { - strncpy(buf, float_strings[OFS_NAN], 3); - buf += 3; + strncpy(p, float_strings[OFS_NAN], 3); + p += 3; } else { /* shouldn't get here: Gay's code should always return something starting with a digit, an 'I', or 'N' */ - strncpy(buf, "ERR", 3); - buf += 3; + strncpy(p, "ERR", 3); + p += 3; assert(0); } goto exit; @@ -629,69 +641,111 @@ goto exit; } - /* Always add a negative sign, and a plus sign if always_add_sign. */ - if (sign == 1) - *buf++ = '-'; - else if (always_add_sign) - *buf++ = '+'; - /* dec_pos = position of decimal point in buffer */ if (use_exp) dec_pos = 1; else dec_pos = decpt; - /* zero padding on left of digit string */ + min_digits -= n_digits; + min_digits1 = (n_digits < dec_pos) ? + (min_digits - (dec_pos-n_digits)) : min_digits; + + /* Compute an upper bound how much memory we need. This might be a few + chars too long, but no big deal. */ + bufsize = + /* 1: Sign */ + 1 + + + /* 2: Zero padding on left of digit string */ + (dec_pos <= 0 ? -dec_pos + 2 : 0) + + + /* 3: Digits, with included decimal point */ + (1 + n_digits) + + + /* 4: And zeros on the right up to the decimal point */ + ((n_digits < dec_pos) ? dec_pos-n_digits + 1 : 0) + + + /* 5: And more trailing zeros when necessary */ + (min_digits1 > 0 ? min_digits1 : 0) + + + /* 6: Exponent "e+100", max 3 numerical digits */ + (use_exp ? 5 : 0) + + + /* Trailing 0 byte */ + 1; + + /* Now allocate the memory and initialize p to point to the start of + it. */ + buf = (char *)PyMem_Malloc(bufsize); + if (buf == NULL) { + PyErr_NoMemory(); + goto exit; + } + p = buf; + + /* 1: Add a negative sign if negative, and a plus sign if non-negative + and always_add_sign is true. */ + if (sign == 1) + *p++ = '-'; + else if (always_add_sign) + *p++ = '+'; + + /* 2: Zero padding on left of digit string */ if (dec_pos <= 0) { - *buf++ = '0'; - *buf++ = '.'; - memset(buf, '0', -dec_pos); - buf -= dec_pos; + *p++ = '0'; + *p++ = '.'; + memset(p, '0', -dec_pos); + p -= dec_pos; } - /* digits, with included decimal point */ + /* 3: Digits, with included decimal point */ if (0 < dec_pos && dec_pos <= n_digits) { - strncpy(buf, digits, dec_pos); - buf += dec_pos; - *buf++ = '.'; - strncpy(buf, digits+dec_pos, n_digits-dec_pos); - buf += n_digits-dec_pos; + strncpy(p, digits, dec_pos); + p += dec_pos; + *p++ = '.'; + strncpy(p, digits+dec_pos, n_digits-dec_pos); + p += n_digits-dec_pos; } else { - strncpy(buf, digits, n_digits); - buf += n_digits; + strncpy(p, digits, n_digits); + p += n_digits; } - min_digits -= n_digits; - /* and zeros on the right up to the decimal point */ + /* 4: And zeros on the right up to the decimal point */ if (n_digits < dec_pos) { - memset(buf, '0', dec_pos-n_digits); - buf += dec_pos-n_digits; - *buf++ = '.'; + memset(p, '0', dec_pos-n_digits); + p += dec_pos-n_digits; + *p++ = '.'; min_digits -= dec_pos-n_digits; } - /* and more trailing zeros when necessary */ + /* 5: And more trailing zeros when necessary */ if (min_digits > 0) { - memset(buf, '0', min_digits); - buf += min_digits; + memset(p, '0', min_digits); + p += min_digits; } - /* delete a trailing decimal pt unless using alternative formatting. */ - if (buf[-1] == '.' && !use_alt_formatting) - buf--; + /* Delete a trailing decimal pt unless using alternative formatting. */ + if (p[-1] == '.' && !use_alt_formatting) + p--; - /* Now that we've done zero padding, add an exponent if needed. */ + /* 6: Now that we've done zero padding, add an exponent if needed. */ if (use_exp) { - *buf++ = float_strings[OFS_E][0]; - exp_len = sprintf(buf, "%+.02d", decpt-1); - buf += exp_len; + *p++ = float_strings[OFS_E][0]; + exp_len = sprintf(p, "%+.02d", decpt-1); + p += exp_len; } exit: - *buf = '\0'; + if (buf) { + *p = '\0'; + /* It's too late if this fails, we've already stepped on + memory that isn't ours. But it's an okay debugging test. */ + assert(p-buf < bufsize); + } _Py_dg_freedtoa(digits); - return p; + return buf; } From python-checkins at python.org Tue Apr 7 00:11:57 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 7 Apr 2009 00:11:57 +0200 (CEST) Subject: [Python-checkins] r71331 - in python/branches/release26-maint: Lib/socket.py Message-ID: <20090406221157.A54D81E403F@bag.python.org> Author: benjamin.peterson Date: Tue Apr 7 00:11:57 2009 New Revision: 71331 Log: Merged revisions 71329 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71329 | benjamin.peterson | 2009-04-06 16:53:33 -0500 (Mon, 06 Apr 2009) | 1 line add create_connection to __all__ #5711 ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/socket.py Modified: python/branches/release26-maint/Lib/socket.py ============================================================================== --- python/branches/release26-maint/Lib/socket.py (original) +++ python/branches/release26-maint/Lib/socket.py Tue Apr 7 00:11:57 2009 @@ -88,7 +88,7 @@ except ImportError: EBADF = 9 -__all__ = ["getfqdn"] +__all__ = ["getfqdn", "create_connection"] __all__.extend(os._get_exports_list(_socket)) From python-checkins at python.org Tue Apr 7 00:39:03 2009 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 7 Apr 2009 00:39:03 +0200 (CEST) Subject: [Python-checkins] r71332 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090406223903.6718C1E42DA@bag.python.org> Author: raymond.hettinger Date: Tue Apr 7 00:39:03 2009 New Revision: 71332 Log: Add example. Fix spelling. Fix patch attribution. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Tue Apr 7 00:39:03 2009 @@ -158,10 +158,14 @@ (Contributed by Kevin Walzer and Guilherme Polo; :issue:`2618` and :issue:`2983`.) -* The :class:`gzip.GzipFile` and :class:`bz2.BZ2File` classs now support - the context manager protocol. +* The :class:`gzip.GzipFile` and :class:`bz2.BZ2File` classes now support + the context manager protocol:: - (Contributed by Jacques Frechet; :issue:`4272`.) + >>> # Automatically close file after writing + >>> with gzip.GzipFile(filename, "wb") as f: + ... f.write(b"xxx") + + (Contributed by Antoine Pitrou.) * The :mod:`Decimal` module now supports two new methods to create a decimal object that from a binary :class:`float`. The conversion is From python-checkins at python.org Tue Apr 7 00:45:52 2009 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 7 Apr 2009 00:45:52 +0200 (CEST) Subject: [Python-checkins] r71333 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090406224552.D03EA1E41AC@bag.python.org> Author: raymond.hettinger Date: Tue Apr 7 00:45:52 2009 New Revision: 71333 Log: Fix links to Decimal and ttk. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Tue Apr 7 00:45:52 2009 @@ -151,8 +151,8 @@ (Contributed by Raymond Hettinger; :issue:`1696199`.) -* Add a new module, :mod:`ttk` for access to the Tk themed widget set. The - basic idea of ttk is to separate, to the extent possible, the code +* Add a new module, :mod:`tkinter.ttk` for access to the Tk themed widget set. + The basic idea of ttk is to separate, to the extent possible, the code implementing a widget's behavior from the code implementing its appearance. (Contributed by Kevin Walzer and Guilherme Polo; :issue:`2618` and @@ -167,7 +167,7 @@ (Contributed by Antoine Pitrou.) -* The :mod:`Decimal` module now supports two new methods to create a +* The :mod:`decimal.Decimal` module now supports two new methods to create a decimal object that from a binary :class:`float`. The conversion is exact but can sometimes be surprising:: From python-checkins at python.org Tue Apr 7 00:49:20 2009 From: python-checkins at python.org (eric.smith) Date: Tue, 7 Apr 2009 00:49:20 +0200 (CEST) Subject: [Python-checkins] r71334 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090406224920.CA6C41E4017@bag.python.org> Author: eric.smith Date: Tue Apr 7 00:49:20 2009 New Revision: 71334 Log: Handle out of memory errors from _Py_dg_dtoa. Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Tue Apr 7 00:49:20 2009 @@ -558,6 +558,11 @@ /* _Py_dg_dtoa returns a digit string (no decimal point or exponent). Must be matched by a call to _Py_dg_freedtoa. */ digits = _Py_dg_dtoa(d, mode, precision, &decpt, &sign, &digits_end); + if (digits == NULL) { + /* The only failure mode is no memory. */ + PyErr_NoMemory(); + goto exit; + } assert(digits_end != NULL && digits_end >= digits); n_digits = digits_end - digits; @@ -743,7 +748,8 @@ memory that isn't ours. But it's an okay debugging test. */ assert(p-buf < bufsize); } - _Py_dg_freedtoa(digits); + if (digits) + _Py_dg_freedtoa(digits); return buf; } From buildbot at python.org Tue Apr 7 00:52:19 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 06 Apr 2009 22:52:19 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090406225219.9F89D1E4017@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/253 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: hirokazu.yamamoto,matthias.klose BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_distutils test_posix ====================================================================== FAIL: test_get_python_inc (distutils.tests.test_sysconfig.SysconfigTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/distutils/tests/test_sysconfig.py", line 45, in test_get_python_inc self.assert_(os.path.isdir(inc_dir), inc_dir) AssertionError: /home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/Include ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Tue Apr 7 00:53:29 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 7 Apr 2009 00:53:29 +0200 (CEST) Subject: [Python-checkins] r71335 - python/trunk/Misc/build.sh Message-ID: <20090406225329.6F5471E4017@bag.python.org> Author: benjamin.peterson Date: Tue Apr 7 00:53:29 2009 New Revision: 71335 Log: see if this helps the doc builds Modified: python/trunk/Misc/build.sh Modified: python/trunk/Misc/build.sh ============================================================================== --- python/trunk/Misc/build.sh (original) +++ python/trunk/Misc/build.sh Tue Apr 7 00:53:29 2009 @@ -257,6 +257,7 @@ # which will definitely fail with a conflict. #CONFLICTED_FILE=commontex/boilerplate.tex #conflict_count=`grep -c "<<<" $CONFLICTED_FILE` +make clean conflict_count=0 if [ $conflict_count != 0 ]; then echo "Conflict detected in $CONFLICTED_FILE. Doc build skipped." > ../build/$F From python-checkins at python.org Tue Apr 7 01:11:08 2009 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 7 Apr 2009 01:11:08 +0200 (CEST) Subject: [Python-checkins] r71336 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090406231108.5CE9B1E4017@bag.python.org> Author: raymond.hettinger Date: Tue Apr 7 01:11:08 2009 New Revision: 71336 Log: Improve the prose just a bit. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Tue Apr 7 01:11:08 2009 @@ -151,7 +151,7 @@ (Contributed by Raymond Hettinger; :issue:`1696199`.) -* Add a new module, :mod:`tkinter.ttk` for access to the Tk themed widget set. +* Added a new module, :mod:`tkinter.ttk` for access to the Tk themed widget set. The basic idea of ttk is to separate, to the extent possible, the code implementing a widget's behavior from the code implementing its appearance. @@ -167,7 +167,7 @@ (Contributed by Antoine Pitrou.) -* The :mod:`decimal.Decimal` module now supports two new methods to create a +* The :mod:`decimal.Decimal` module now supports methods to creating a decimal object that from a binary :class:`float`. The conversion is exact but can sometimes be surprising:: From python-checkins at python.org Tue Apr 7 01:11:47 2009 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 7 Apr 2009 01:11:47 +0200 (CEST) Subject: [Python-checkins] r71337 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090406231147.451C41E4017@bag.python.org> Author: raymond.hettinger Date: Tue Apr 7 01:11:47 2009 New Revision: 71337 Log: Fix nit. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Tue Apr 7 01:11:47 2009 @@ -167,8 +167,8 @@ (Contributed by Antoine Pitrou.) -* The :mod:`decimal.Decimal` module now supports methods to creating a - decimal object that from a binary :class:`float`. The conversion is +* The :mod:`decimal.Decimal` module now supports methods for creating a + decimal object from a binary :class:`float`. The conversion is exact but can sometimes be surprising:: >>> Decimal.from_float(1.1) From python-checkins at python.org Tue Apr 7 01:22:37 2009 From: python-checkins at python.org (guido.van.rossum) Date: Tue, 7 Apr 2009 01:22:37 +0200 (CEST) Subject: [Python-checkins] r71338 - peps/trunk/pep-0401.txt Message-ID: <20090406232237.32D7F1E4017@bag.python.org> Author: guido.van.rossum Date: Tue Apr 7 01:22:36 2009 New Revision: 71338 Log: Clarify the status of this PEP. Modified: peps/trunk/pep-0401.txt Modified: peps/trunk/pep-0401.txt ============================================================================== --- peps/trunk/pep-0401.txt (original) +++ peps/trunk/pep-0401.txt Tue Apr 7 01:22:36 2009 @@ -3,7 +3,7 @@ Version: $Revision$ Last-Modified: $Date: 2009-04-01 00:00:00 -0400 (Wed, 1 Apr 2009)$ Author: Barry Warsaw, Brett Cannon -Status: Accepted +Status: April Fool! Type: Process Content-Type: text/x-rst Created: 01-Apr-2009 From python-checkins at python.org Tue Apr 7 01:43:46 2009 From: python-checkins at python.org (eric.smith) Date: Tue, 7 Apr 2009 01:43:46 +0200 (CEST) Subject: [Python-checkins] r71339 - in python/branches/py3k-short-float-repr: Doc/distutils/builtdist.rst Doc/library/binhex.rst Doc/library/bisect.rst Doc/library/builtins.rst Doc/library/bz2.rst Doc/library/calendar.rst Doc/library/cgi.rst Doc/library/cgitb.rst Doc/library/chunk.rst Doc/library/cmath.rst Doc/library/cmd.rst Doc/library/code.rst Doc/library/codecs.rst Doc/whatsnew/3.1.rst Lib/distutils/command/bdist.py Lib/distutils/filelist.py Lib/distutils/tests/test_bdist.py Lib/distutils/tests/test_filelist.py Misc/NEWS Tools/msi/uuids.py Message-ID: <20090406234346.55C531E4017@bag.python.org> Author: eric.smith Date: Tue Apr 7 01:43:45 2009 New Revision: 71339 Log: Merged revisions 71281-71338 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71284 | tarek.ziade | 2009-04-05 17:49:36 -0400 (Sun, 05 Apr 2009) | 9 lines Merged revisions 71280 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71280 | tarek.ziade | 2009-04-05 23:44:08 +0200 (Sun, 05 Apr 2009) | 1 line Fixed #1491431: distutils.filelist.glob_to_re was broken for some edge cases (detailed in the test ........ ................ r71289 | georg.brandl | 2009-04-05 18:20:44 -0400 (Sun, 05 Apr 2009) | 1 line Update signature style of optional arguments, part two. ................ r71293 | tarek.ziade | 2009-04-05 18:57:21 -0400 (Sun, 05 Apr 2009) | 9 lines Merged revisions 71291 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71291 | tarek.ziade | 2009-04-06 00:51:09 +0200 (Mon, 06 Apr 2009) | 1 line Fixed #5095: msi missing from Distutils bdist formats ........ ................ r71297 | tarek.ziade | 2009-04-05 19:05:31 -0400 (Sun, 05 Apr 2009) | 9 lines Merged revisions 71295 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71295 | tarek.ziade | 2009-04-06 01:03:10 +0200 (Mon, 06 Apr 2009) | 1 line pep8-fied method names ........ ................ r71316 | raymond.hettinger | 2009-04-06 13:55:05 -0400 (Mon, 06 Apr 2009) | 1 line Add more examples. ................ r71326 | martin.v.loewis | 2009-04-06 17:16:46 -0400 (Mon, 06 Apr 2009) | 1 line Add uuids for 3.1 ................ r71332 | raymond.hettinger | 2009-04-06 18:39:03 -0400 (Mon, 06 Apr 2009) | 1 line Add example. Fix spelling. Fix patch attribution. ................ r71333 | raymond.hettinger | 2009-04-06 18:45:52 -0400 (Mon, 06 Apr 2009) | 1 line Fix links to Decimal and ttk. ................ r71336 | raymond.hettinger | 2009-04-06 19:11:08 -0400 (Mon, 06 Apr 2009) | 1 line Improve the prose just a bit. ................ r71337 | raymond.hettinger | 2009-04-06 19:11:47 -0400 (Mon, 06 Apr 2009) | 1 line Fix nit. ................ Added: python/branches/py3k-short-float-repr/Lib/distutils/tests/test_bdist.py - copied unchanged from r71337, /python/branches/py3k/Lib/distutils/tests/test_bdist.py python/branches/py3k-short-float-repr/Lib/distutils/tests/test_filelist.py - copied unchanged from r71337, /python/branches/py3k/Lib/distutils/tests/test_filelist.py Modified: python/branches/py3k-short-float-repr/ (props changed) python/branches/py3k-short-float-repr/Doc/distutils/builtdist.rst python/branches/py3k-short-float-repr/Doc/library/binhex.rst python/branches/py3k-short-float-repr/Doc/library/bisect.rst python/branches/py3k-short-float-repr/Doc/library/builtins.rst python/branches/py3k-short-float-repr/Doc/library/bz2.rst python/branches/py3k-short-float-repr/Doc/library/calendar.rst python/branches/py3k-short-float-repr/Doc/library/cgi.rst python/branches/py3k-short-float-repr/Doc/library/cgitb.rst python/branches/py3k-short-float-repr/Doc/library/chunk.rst python/branches/py3k-short-float-repr/Doc/library/cmath.rst python/branches/py3k-short-float-repr/Doc/library/cmd.rst python/branches/py3k-short-float-repr/Doc/library/code.rst python/branches/py3k-short-float-repr/Doc/library/codecs.rst python/branches/py3k-short-float-repr/Doc/whatsnew/3.1.rst python/branches/py3k-short-float-repr/Lib/distutils/command/bdist.py python/branches/py3k-short-float-repr/Lib/distutils/filelist.py python/branches/py3k-short-float-repr/Misc/NEWS python/branches/py3k-short-float-repr/Tools/msi/uuids.py Modified: python/branches/py3k-short-float-repr/Doc/distutils/builtdist.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/distutils/builtdist.rst (original) +++ python/branches/py3k-short-float-repr/Doc/distutils/builtdist.rst Tue Apr 7 01:43:45 2009 @@ -80,7 +80,7 @@ +-------------+------------------------------+---------+ | ``tar`` | tar file (:file:`.tar`) | \(3) | +-------------+------------------------------+---------+ -| ``zip`` | zip file (:file:`.zip`) | \(4) | +| ``zip`` | zip file (:file:`.zip`) | (2),(4) | +-------------+------------------------------+---------+ | ``rpm`` | RPM | \(5) | +-------------+------------------------------+---------+ @@ -90,9 +90,12 @@ +-------------+------------------------------+---------+ | ``rpm`` | RPM | \(5) | +-------------+------------------------------+---------+ -| ``wininst`` | self-extracting ZIP file for | (2),(4) | +| ``wininst`` | self-extracting ZIP file for | \(4) | | | Windows | | +-------------+------------------------------+---------+ +| ``msi`` | Microsoft Installer. | | ++-------------+------------------------------+---------+ + Notes: @@ -102,8 +105,6 @@ (2) default on Windows - **\*\*** to-do! **\*\*** - (3) requires external utilities: :program:`tar` and possibly one of :program:`gzip`, :program:`bzip2`, or :program:`compress` @@ -133,6 +134,8 @@ +--------------------------+-----------------------+ | :command:`bdist_wininst` | wininst | +--------------------------+-----------------------+ +| :command:`bdist_msi` | msi | ++--------------------------+-----------------------+ The following sections give details on the individual :command:`bdist_\*` commands. Modified: python/branches/py3k-short-float-repr/Doc/library/binhex.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/binhex.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/binhex.rst Tue Apr 7 01:43:45 2009 @@ -1,4 +1,3 @@ - :mod:`binhex` --- Encode and decode binhex4 files ================================================= @@ -19,11 +18,11 @@ supporting a :meth:`write` and :meth:`close` method). -.. function:: hexbin(input[, output]) +.. function:: hexbin(input, output) Decode a binhex file *input*. *input* may be a filename or a file-like object supporting :meth:`read` and :meth:`close` methods. The resulting file is written - to a file named *output*, unless the argument is omitted in which case the + to a file named *output*, unless the argument is ``None`` in which case the output filename is read from the binhex file. The following exception is also defined: Modified: python/branches/py3k-short-float-repr/Doc/library/bisect.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/bisect.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/bisect.rst Tue Apr 7 01:43:45 2009 @@ -1,4 +1,3 @@ - :mod:`bisect` --- Array bisection algorithm =========================================== @@ -17,43 +16,35 @@ The following functions are provided: -.. function:: bisect_left(list, item[, lo[, hi]]) - - Locate the proper insertion point for *item* in *list* to maintain sorted order. - The parameters *lo* and *hi* may be used to specify a subset of the list which - should be considered; by default the entire list is used. If *item* is already - present in *list*, the insertion point will be before (to the left of) any - existing entries. The return value is suitable for use as the first parameter - to ``list.insert()``. This assumes that *list* is already sorted. - - -.. function:: bisect_right(list, item[, lo[, hi]]) - - Similar to :func:`bisect_left`, but returns an insertion point which comes after - (to the right of) any existing entries of *item* in *list*. - - -.. function:: bisect(...) +.. function:: bisect_left(a, x, lo=0, hi=len(a)) - Alias for :func:`bisect_right`. + Locate the proper insertion point for *x* in *a* to maintain sorted order. + The parameters *lo* and *hi* may be used to specify a subset of the list + which should be considered; by default the entire list is used. If *x* is + already present in *a*, the insertion point will be before (to the left of) + any existing entries. The return value is suitable for use as the first + parameter to ``list.insert()``. This assumes that *a* is already sorted. -.. function:: insort_left(list, item[, lo[, hi]]) +.. function:: bisect_right(a, x, lo=0, hi=len(a)) + bisect(a, x, lo=0, hi=len(a)) - Insert *item* in *list* in sorted order. This is equivalent to - ``list.insert(bisect.bisect_left(list, item, lo, hi), item)``. This assumes - that *list* is already sorted. + Similar to :func:`bisect_left`, but returns an insertion point which comes + after (to the right of) any existing entries of *x* in *a*. -.. function:: insort_right(list, item[, lo[, hi]]) +.. function:: insort_left(a, x, lo=0, hi=len(a)) - Similar to :func:`insort_left`, but inserting *item* in *list* after any - existing entries of *item*. + Insert *x* in *a* in sorted order. This is equivalent to + ``a.insert(bisect.bisect_left(a, x, lo, hi), x)``. This assumes that *a* is + already sorted. -.. function:: insort(...) +.. function:: insort_right(a, x, lo=0, hi=len(a)) + insort(a, x, lo=0, hi=len(a)) - Alias for :func:`insort_right`. + Similar to :func:`insort_left`, but inserting *x* in *a* after any existing + entries of *x*. Examples Modified: python/branches/py3k-short-float-repr/Doc/library/builtins.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/builtins.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/builtins.rst Tue Apr 7 01:43:45 2009 @@ -1,4 +1,3 @@ - :mod:`builtins` --- Built-in objects ==================================== Modified: python/branches/py3k-short-float-repr/Doc/library/bz2.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/bz2.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/bz2.rst Tue Apr 7 01:43:45 2009 @@ -1,9 +1,9 @@ - :mod:`bz2` --- Compression compatible with :program:`bzip2` =========================================================== .. module:: bz2 - :synopsis: Interface to compression and decompression routines compatible with bzip2. + :synopsis: Interface to compression and decompression routines + compatible with bzip2. .. moduleauthor:: Gustavo Niemeyer .. sectionauthor:: Gustavo Niemeyer @@ -42,7 +42,7 @@ Handling of compressed files is offered by the :class:`BZ2File` class. -.. class:: BZ2File(filename[, mode[, buffering[, compresslevel]]]) +.. class:: BZ2File(filename, mode='r', buffering=0, compresslevel=9) Open a bz2 file. Mode can be either ``'r'`` or ``'w'``, for reading (default) or writing. When opened for writing, the file will be created if it doesn't @@ -129,14 +129,13 @@ :class:`BZ2Compressor` and :class:`BZ2Decompressor`. -.. class:: BZ2Compressor([compresslevel]) +.. class:: BZ2Compressor(compresslevel=9) Create a new compressor object. This object may be used to compress data sequentially. If you want to compress data in one shot, use the :func:`compress` function instead. The *compresslevel* parameter, if given, must be a number between ``1`` and ``9``; the default is ``9``. - .. method:: compress(data) Provide more data to the compressor object. It will return chunks of @@ -157,7 +156,6 @@ sequentially. If you want to decompress data in one shot, use the :func:`decompress` function instead. - .. method:: decompress(data) Provide more data to the decompressor object. It will return chunks of @@ -174,7 +172,7 @@ and :func:`decompress` functions. -.. function:: compress(data[, compresslevel]) +.. function:: compress(data, compresslevel=9) Compress *data* in one shot. If you want to compress data sequentially, use an instance of :class:`BZ2Compressor` instead. The *compresslevel* parameter, Modified: python/branches/py3k-short-float-repr/Doc/library/calendar.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/calendar.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/calendar.rst Tue Apr 7 01:43:45 2009 @@ -1,10 +1,9 @@ - :mod:`calendar` --- General calendar-related functions ====================================================== .. module:: calendar - :synopsis: Functions for working with calendars, including some emulation of the Unix cal - program. + :synopsis: Functions for working with calendars, including some emulation + of the Unix cal program. .. sectionauthor:: Drew Csillag @@ -23,7 +22,7 @@ it's the base calendar for all computations. -.. class:: Calendar([firstweekday]) +.. class:: Calendar(firstweekday=0) Creates a :class:`Calendar` object. *firstweekday* is an integer specifying the first day of the week. ``0`` is Monday (the default), ``6`` is Sunday. @@ -82,7 +81,7 @@ weeks. Weeks are lists of seven day numbers. - .. method:: yeardatescalendar(year[, width]) + .. method:: yeardatescalendar(year, width=3) Return the data for the specified year ready for formatting. The return value is a list of month rows. Each month row contains up to *width* @@ -90,28 +89,27 @@ each week contains 1--7 days. Days are :class:`datetime.date` objects. - .. method:: yeardays2calendar(year[, width]) + .. method:: yeardays2calendar(year, width=3) Return the data for the specified year ready for formatting (similar to :meth:`yeardatescalendar`). Entries in the week lists are tuples of day numbers and weekday numbers. Day numbers outside this month are zero. - .. method:: yeardayscalendar(year[, width]) + .. method:: yeardayscalendar(year, width=3) Return the data for the specified year ready for formatting (similar to :meth:`yeardatescalendar`). Entries in the week lists are day numbers. Day numbers outside this month are zero. -.. class:: TextCalendar([firstweekday]) +.. class:: TextCalendar(firstweekday=0) This class can be used to generate plain text calendars. - :class:`TextCalendar` instances have the following methods: - .. method:: formatmonth(theyear, themonth[, w[, l]]) + .. method:: formatmonth(theyear, themonth, w=0, l=0) Return a month's calendar in a multi-line string. If *w* is provided, it specifies the width of the date columns, which are centered. If *l* is @@ -120,12 +118,12 @@ :meth:`setfirstweekday` method. - .. method:: prmonth(theyear, themonth[, w[, l]]) + .. method:: prmonth(theyear, themonth, w=0, l=0) Print a month's calendar as returned by :meth:`formatmonth`. - .. method:: formatyear(theyear, themonth[, w[, l[, c[, m]]]]) + .. method:: formatyear(theyear, themonth, w=2, l=1, c=6, m=3) Return a *m*-column calendar for an entire year as a multi-line string. Optional parameters *w*, *l*, and *c* are for date column width, lines per @@ -135,32 +133,32 @@ can be generated is platform-dependent. - .. method:: pryear(theyear[, w[, l[, c[, m]]]]) + .. method:: pryear(theyear, w=2, l=1, c=6, m=3) Print the calendar for an entire year as returned by :meth:`formatyear`. -.. class:: HTMLCalendar([firstweekday]) +.. class:: HTMLCalendar(firstweekday=0) This class can be used to generate HTML calendars. :class:`HTMLCalendar` instances have the following methods: - .. method:: formatmonth(theyear, themonth[, withyear]) + .. method:: formatmonth(theyear, themonth, withyear=True) Return a month's calendar as an HTML table. If *withyear* is true the year will be included in the header, otherwise just the month name will be used. - .. method:: formatyear(theyear, themonth[, width]) + .. method:: formatyear(theyear, themonth, width=3) Return a year's calendar as an HTML table. *width* (defaulting to 3) specifies the number of months per row. - .. method:: formatyearpage(theyear[, width[, css[, encoding]]]) + .. method:: formatyearpage(theyear, width=3, css='calendar.css', encoding=None) Return a year's calendar as a complete HTML page. *width* (defaulting to 3) specifies the number of months per row. *css* is the name for the @@ -169,7 +167,7 @@ output (defaulting to the system default encoding). -.. class:: LocaleTextCalendar([firstweekday[, locale]]) +.. class:: LocaleTextCalendar(firstweekday=0, locale=None) This subclass of :class:`TextCalendar` can be passed a locale name in the constructor and will return month and weekday names in the specified @@ -177,7 +175,7 @@ weekday names will be returned as unicode. -.. class:: LocaleHTMLCalendar([firstweekday[, locale]]) +.. class:: LocaleHTMLCalendar(firstweekday=0, locale=None) This subclass of :class:`HTMLCalendar` can be passed a locale name in the constructor and will return month and weekday names in the specified @@ -241,26 +239,26 @@ unless set by :func:`setfirstweekday`. -.. function:: prmonth(theyear, themonth[, w[, l]]) +.. function:: prmonth(theyear, themonth, w=0, l=0) Prints a month's calendar as returned by :func:`month`. -.. function:: month(theyear, themonth[, w[, l]]) +.. function:: month(theyear, themonth, w=0, l=0) Returns a month's calendar in a multi-line string using the :meth:`formatmonth` of the :class:`TextCalendar` class. -.. function:: prcal(year[, w[, l[c]]]) +.. function:: prcal(year, w=0, l=0, c=6, m=3) Prints the calendar for an entire year as returned by :func:`calendar`. -.. function:: calendar(year[, w[, l[c]]]) +.. function:: calendar(year, w=2, l=1, c=6, m=3) - Returns a 3-column calendar for an entire year as a multi-line string using the - :meth:`formatyear` of the :class:`TextCalendar` class. + Returns a 3-column calendar for an entire year as a multi-line string using + the :meth:`formatyear` of the :class:`TextCalendar` class. .. function:: timegm(tuple) Modified: python/branches/py3k-short-float-repr/Doc/library/cgi.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/cgi.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/cgi.rst Tue Apr 7 01:43:45 2009 @@ -1,6 +1,5 @@ - -:mod:`cgi` --- Common Gateway Interface support. -================================================ +:mod:`cgi` --- Common Gateway Interface support +=============================================== .. module:: cgi :synopsis: Helpers for running Python scripts via the Common Gateway Interface. @@ -220,7 +219,7 @@ :meth:`getlist` provided by this higher level interface. -.. method:: FieldStorage.getfirst(name[, default]) +.. method:: FieldStorage.getfirst(name, default=None) This method always returns only one value associated with form field *name*. The method returns only the first value in case that more values were posted @@ -255,19 +254,19 @@ algorithms implemented in this module in other circumstances. -.. function:: parse(fp[, keep_blank_values[, strict_parsing]]) +.. function:: parse(fp=None, environ=os.environ, keep_blank_values=False, strict_parsing=False) Parse a query in the environment or from a file (the file defaults to ``sys.stdin``). The *keep_blank_values* and *strict_parsing* parameters are passed to :func:`urllib.parse.parse_qs` unchanged. -.. function:: parse_qs(qs[, keep_blank_values[, strict_parsing]]) +.. function:: parse_qs(qs, keep_blank_values=False, strict_parsing=False) This function is deprecated in this module. Use :func:`urllib.parse.parse_qs` instead. It is maintained here only for backward compatibility. -.. function:: parse_qsl(qs[, keep_blank_values[, strict_parsing]]) +.. function:: parse_qsl(qs, keep_blank_values=False, strict_parsing=False) This function is deprecated in this module. Use :func:`urllib.parse.parse_qs` instead. It is maintained here only for backward compatibility. @@ -319,7 +318,7 @@ Print a list of useful (used by CGI) environment variables in HTML. -.. function:: escape(s[, quote]) +.. function:: escape(s, quote=False) Convert the characters ``'&'``, ``'<'`` and ``'>'`` in string *s* to HTML-safe sequences. Use this if you need to display text that might contain such Modified: python/branches/py3k-short-float-repr/Doc/library/cgitb.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/cgitb.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/cgitb.rst Tue Apr 7 01:43:45 2009 @@ -1,4 +1,3 @@ - :mod:`cgitb` --- Traceback manager for CGI scripts ================================================== @@ -34,7 +33,7 @@ analysis. -.. function:: enable([display[, logdir[, context[, format]]]]) +.. function:: enable(display=1, logdir=None, context=5, format="html") .. index:: single: excepthook() (in module sys) @@ -51,7 +50,7 @@ value forces plain text output. The default value is ``"html"``. -.. function:: handler([info]) +.. function:: handler(info=None) This function handles an exception using the default settings (that is, show a report in the browser, but don't log to a file). This can be used when you've Modified: python/branches/py3k-short-float-repr/Doc/library/chunk.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/chunk.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/chunk.rst Tue Apr 7 01:43:45 2009 @@ -1,4 +1,3 @@ - :mod:`chunk` --- Read IFF chunked data ====================================== @@ -51,7 +50,7 @@ instance will fail with a :exc:`EOFError` exception. -.. class:: Chunk(file[, align, bigendian, inclheader]) +.. class:: Chunk(file, align=True, bigendian=True, inclheader=False) Class which represents a chunk. The *file* argument is expected to be a file-like object. An instance of this class is specifically allowed. The @@ -94,7 +93,7 @@ Returns ``False``. - .. method:: seek(pos[, whence]) + .. method:: seek(pos, whence=0) Set the chunk's current position. The *whence* argument is optional and defaults to ``0`` (absolute file positioning); other values are ``1`` @@ -108,7 +107,7 @@ Return the current position into the chunk. - .. method:: read([size]) + .. method:: read(size=-1) Read at most *size* bytes from the chunk (less if the read hits the end of the chunk before obtaining *size* bytes). If the *size* argument is Modified: python/branches/py3k-short-float-repr/Doc/library/cmath.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/cmath.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/cmath.rst Tue Apr 7 01:43:45 2009 @@ -1,4 +1,3 @@ - :mod:`cmath` --- Mathematical functions for complex numbers =========================================================== Modified: python/branches/py3k-short-float-repr/Doc/library/cmd.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/cmd.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/cmd.rst Tue Apr 7 01:43:45 2009 @@ -1,4 +1,3 @@ - :mod:`cmd` --- Support for line-oriented command interpreters ============================================================= @@ -13,7 +12,7 @@ interface. -.. class:: Cmd([completekey[, stdin[, stdout]]]) +.. class:: Cmd(completekey='tab', stdin=None, stdout=None) A :class:`Cmd` instance or subclass instance is a line-oriented interpreter framework. There is no good reason to instantiate :class:`Cmd` itself; rather, @@ -42,7 +41,7 @@ A :class:`Cmd` instance has the following methods: -.. method:: Cmd.cmdloop([intro]) +.. method:: Cmd.cmdloop(intro=None) Repeatedly issue a prompt, accept input, parse an initial prefix off the received input, and dispatch to action methods, passing them the remainder of Modified: python/branches/py3k-short-float-repr/Doc/library/code.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/code.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/code.rst Tue Apr 7 01:43:45 2009 @@ -12,7 +12,7 @@ build applications which provide an interactive interpreter prompt. -.. class:: InteractiveInterpreter([locals]) +.. class:: InteractiveInterpreter(locals=None) This class deals with parsing and interpreter state (the user's namespace); it does not deal with input buffering or prompting or input file naming (the @@ -22,14 +22,14 @@ ``'__doc__'`` set to ``None``. -.. class:: InteractiveConsole([locals[, filename]]) +.. class:: InteractiveConsole(locals=None, filename="") Closely emulate the behavior of the interactive Python interpreter. This class builds on :class:`InteractiveInterpreter` and adds prompting using the familiar ``sys.ps1`` and ``sys.ps2``, and input buffering. -.. function:: interact([banner[, readfunc[, local]]]) +.. function:: interact(banner=None, readfunc=None, local=None) Convenience function to run a read-eval-print loop. This creates a new instance of :class:`InteractiveConsole` and sets *readfunc* to be used as the @@ -40,7 +40,7 @@ discarded after use. -.. function:: compile_command(source[, filename[, symbol]]) +.. function:: compile_command(source, filename="", symbol="single") This function is useful for programs that want to emulate Python's interpreter main loop (a.k.a. the read-eval-print loop). The tricky part is to determine @@ -67,7 +67,7 @@ ------------------------------- -.. method:: InteractiveInterpreter.runsource(source[, filename[, symbol]]) +.. method:: InteractiveInterpreter.runsource(source, filename="", symbol="single") Compile and run some source in the interpreter. Arguments are the same as for :func:`compile_command`; the default for *filename* is ``''``, and for @@ -100,7 +100,7 @@ with it. -.. method:: InteractiveInterpreter.showsyntaxerror([filename]) +.. method:: InteractiveInterpreter.showsyntaxerror(filename=None) Display the syntax error that just occurred. This does not display a stack trace because there isn't one for syntax errors. If *filename* is given, it is @@ -132,7 +132,7 @@ interpreter objects as well as the following additions. -.. method:: InteractiveConsole.interact([banner]) +.. method:: InteractiveConsole.interact(banner=None) Closely emulate the interactive Python console. The optional banner argument specify the banner to print before the first interaction; by default it prints a @@ -158,7 +158,7 @@ Remove any unhandled source text from the input buffer. -.. method:: InteractiveConsole.raw_input([prompt]) +.. method:: InteractiveConsole.raw_input(prompt="") Write a prompt and read a line. The returned line does not include the trailing newline. When the user enters the EOF key sequence, :exc:`EOFError` is raised. Modified: python/branches/py3k-short-float-repr/Doc/library/codecs.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/codecs.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/codecs.rst Tue Apr 7 01:43:45 2009 @@ -1,4 +1,3 @@ - :mod:`codecs` --- Codec registry and base classes ================================================= @@ -226,34 +225,36 @@ defaults to line buffered. -.. function:: EncodedFile(file, input[, output[, errors]]) +.. function:: EncodedFile(file, data_encoding, file_encoding=None, errors='strict') Return a wrapped version of file which provides transparent encoding translation. Bytes written to the wrapped file are interpreted according to the given - *input* encoding and then written to the original file as bytes using the - *output* encoding. + *data_encoding* and then written to the original file as bytes using the + *file_encoding*. - If *output* is not given, it defaults to *input*. + If *file_encoding* is not given, it defaults to *data_encoding*. - *errors* may be given to define the error handling. It defaults to ``'strict'``, - which causes :exc:`ValueError` to be raised in case an encoding error occurs. + *errors* may be given to define the error handling. It defaults to + ``'strict'``, which causes :exc:`ValueError` to be raised in case an encoding + error occurs. -.. function:: iterencode(iterable, encoding[, errors]) +.. function:: iterencode(iterator, encoding, errors='strict', **kwargs) Uses an incremental encoder to iteratively encode the input provided by - *iterable*. This function is a :term:`generator`. *errors* (as well as any + *iterator*. This function is a :term:`generator`. *errors* (as well as any other keyword argument) is passed through to the incremental encoder. -.. function:: iterdecode(iterable, encoding[, errors]) +.. function:: iterdecode(iterator, encoding, errors='strict', **kwargs) Uses an incremental decoder to iteratively decode the input provided by - *iterable*. This function is a :term:`generator`. *errors* (as well as any + *iterator*. This function is a :term:`generator`. *errors* (as well as any other keyword argument) is passed through to the incremental decoder. + The module also provides the following constants which are useful for reading and writing to platform dependent files: Modified: python/branches/py3k-short-float-repr/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k-short-float-repr/Doc/whatsnew/3.1.rst Tue Apr 7 01:43:45 2009 @@ -151,20 +151,24 @@ (Contributed by Raymond Hettinger; :issue:`1696199`.) -* Add a new module, :mod:`ttk` for access to the Tk themed widget set. The - basic idea of ttk is to separate, to the extent possible, the code +* Added a new module, :mod:`tkinter.ttk` for access to the Tk themed widget set. + The basic idea of ttk is to separate, to the extent possible, the code implementing a widget's behavior from the code implementing its appearance. (Contributed by Kevin Walzer and Guilherme Polo; :issue:`2618` and :issue:`2983`.) -* The :class:`gzip.GzipFile` and :class:`bz2.BZ2File` classs now support - the context manager protocol. +* The :class:`gzip.GzipFile` and :class:`bz2.BZ2File` classes now support + the context manager protocol:: - (Contributed by Jacques Frechet; :issue:`4272`.) + >>> # Automatically close file after writing + >>> with gzip.GzipFile(filename, "wb") as f: + ... f.write(b"xxx") -* The :mod:`Decimal` module now supports two new methods to create a - decimal object that from a binary :class:`float`. The conversion is + (Contributed by Antoine Pitrou.) + +* The :mod:`decimal.Decimal` module now supports methods for creating a + decimal object from a binary :class:`float`. The conversion is exact but can sometimes be surprising:: >>> Decimal.from_float(1.1) @@ -194,7 +198,17 @@ from APL. Also, the existing :func:`itertools.count` function now has an optional *step* argument and can accept any type of counting sequence including :class:`fractions.Fraction` and - :class:`decimal.Decimal`. + :class:`decimal.Decimal`:: + + >>> [p+q for p,q in combinations_with_replacement('LOVE', 2)] + ['LL', 'LO', 'LV', 'LE', 'OO', 'OV', 'OE', 'VV', 'VE', 'EE'] + + >>> list(compress(data=range(10), selectors=[0,0,1,1,0,1,0,1,0,0])) + [2, 3, 5, 7] + + >>> c = count(start=Fraction(1,2), step=Fraction(1,6)) + >>> next(c), next(c), next(c), next(c) + (Fraction(1, 2), Fraction(2, 3), Fraction(5, 6), Fraction(1, 1)) (Contributed by Raymond Hettinger.) @@ -206,8 +220,11 @@ (Contributed by Raymond Hettinger; :issue:`1818`.) -* ``round`(x, n)`` now returns an integer if *x* is an integer. - Previously it returned a float. +* ``round(x, n)`` now returns an integer if *x* is an integer. + Previously it returned a float:: + + >>> round(1123, -2) + 1100 (Contributed by Mark Dickinson; :issue:`4707`.) @@ -240,7 +257,17 @@ * The :mod:`unittest` module now supports skipping individual tests or classes of tests. And it supports marking a test as a expected failure, a test that is known to be broken, but shouldn't be counted as a failure on a - TestResult. + TestResult:: + + class TestGizmo(unittest.TestCase): + + @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows") + def test_gizmo_on_windows(self): + ... + + @unittest.expectedFailure + def test_gimzo_without_required_library(self): + ... (Contributed by Benjamin Peterson.) Modified: python/branches/py3k-short-float-repr/Lib/distutils/command/bdist.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/command/bdist.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/command/bdist.py Tue Apr 7 01:43:45 2009 @@ -49,35 +49,28 @@ ] # The following commands do not take a format option from bdist - no_format_option = ('bdist_rpm', - #'bdist_sdux', 'bdist_pkgtool' - ) + no_format_option = ('bdist_rpm',) # This won't do in reality: will need to distinguish RPM-ish Linux, # Debian-ish Linux, Solaris, FreeBSD, ..., Windows, Mac OS. - default_format = { 'posix': 'gztar', - 'nt': 'zip', - 'os2': 'zip', } + default_format = {'posix': 'gztar', + 'nt': 'zip', + 'os2': 'zip'} # Establish the preferred order (for the --help-formats option). format_commands = ['rpm', 'gztar', 'bztar', 'ztar', 'tar', - 'wininst', 'zip', - #'pkgtool', 'sdux' - ] + 'wininst', 'zip', 'msi'] # And the real information. - format_command = { 'rpm': ('bdist_rpm', "RPM distribution"), - 'zip': ('bdist_dumb', "ZIP file"), - 'gztar': ('bdist_dumb', "gzip'ed tar file"), - 'bztar': ('bdist_dumb', "bzip2'ed tar file"), - 'ztar': ('bdist_dumb', "compressed tar file"), - 'tar': ('bdist_dumb', "tar file"), - 'wininst': ('bdist_wininst', - "Windows executable installer"), - 'zip': ('bdist_dumb', "ZIP file"), - #'pkgtool': ('bdist_pkgtool', - # "Solaris pkgtool distribution"), - #'sdux': ('bdist_sdux', "HP-UX swinstall depot"), + format_command = {'rpm': ('bdist_rpm', "RPM distribution"), + 'gztar': ('bdist_dumb', "gzip'ed tar file"), + 'bztar': ('bdist_dumb', "bzip2'ed tar file"), + 'ztar': ('bdist_dumb', "compressed tar file"), + 'tar': ('bdist_dumb', "tar file"), + 'wininst': ('bdist_wininst', + "Windows executable installer"), + 'zip': ('bdist_dumb', "ZIP file"), + 'msi': ('bdist_msi', "Microsoft Installer") } Modified: python/branches/py3k-short-float-repr/Lib/distutils/filelist.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/filelist.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/filelist.py Tue Apr 7 01:43:45 2009 @@ -289,7 +289,8 @@ # character except the special characters. # XXX currently the "special characters" are just slash -- i.e. this is # Unix-only. - pattern_re = re.sub(r'(^|[^\\])\.', r'\1[^/]', pattern_re) + pattern_re = re.sub(r'((? Author: benjamin.peterson Date: Tue Apr 7 01:52:08 2009 New Revision: 71340 Log: don't let fun break the index Modified: peps/trunk/pep0/pep.py Modified: peps/trunk/pep0/pep.py ============================================================================== --- peps/trunk/pep0/pep.py (original) +++ peps/trunk/pep0/pep.py Tue Apr 7 01:52:08 2009 @@ -207,8 +207,12 @@ # 'Status'. status = metadata['Status'] if status not in self.status_values: - raise PEPError("%r is not a valid Status value" % - (status,), pep_file.name, self.number) + if status == "April Fool!": + # See PEP 401 :) + status = "Rejected" + else: + raise PEPError("%r is not a valid Status value" % + (status,), pep_file.name, self.number) # Special case for Active PEPs. if (status == u"Active" and self.type_ not in ("Process", "Informational")): From python-checkins at python.org Tue Apr 7 02:07:34 2009 From: python-checkins at python.org (eric.smith) Date: Tue, 7 Apr 2009 02:07:34 +0200 (CEST) Subject: [Python-checkins] r71341 - in python/branches/py3k/Python: atof.c strtod.c Message-ID: <20090407000734.B3D6D1E4017@bag.python.org> Author: eric.smith Date: Tue Apr 7 02:07:34 2009 New Revision: 71341 Log: Removed unused files in preparation for merging py3k-short-float-repr. Removed: python/branches/py3k/Python/atof.c python/branches/py3k/Python/strtod.c Deleted: python/branches/py3k/Python/atof.c ============================================================================== --- python/branches/py3k/Python/atof.c Tue Apr 7 02:07:34 2009 +++ (empty file) @@ -1,50 +0,0 @@ - -/* Just in case you haven't got an atof() around... - This one doesn't check for bad syntax or overflow, - and is slow and inaccurate. - But it's good enough for the occasional string literal... */ - -#include "pyconfig.h" - -#include - -double atof(char *s) -{ - double a = 0.0; - int e = 0; - int c; - while ((c = *s++) != '\0' && isdigit(c)) { - a = a*10.0 + (c - '0'); - } - if (c == '.') { - while ((c = *s++) != '\0' && isdigit(c)) { - a = a*10.0 + (c - '0'); - e = e-1; - } - } - if (c == 'e' || c == 'E') { - int sign = 1; - int i = 0; - c = *s++; - if (c == '+') - c = *s++; - else if (c == '-') { - c = *s++; - sign = -1; - } - while (isdigit(c)) { - i = i*10 + (c - '0'); - c = *s++; - } - e += i*sign; - } - while (e > 0) { - a *= 10.0; - e--; - } - while (e < 0) { - a *= 0.1; - e++; - } - return a; -} Deleted: python/branches/py3k/Python/strtod.c ============================================================================== --- python/branches/py3k/Python/strtod.c Tue Apr 7 02:07:34 2009 +++ (empty file) @@ -1,156 +0,0 @@ -#include "pyconfig.h" - -/* comp.sources.misc strtod(), as posted in comp.lang.tcl, - with bugfix for "123000.0" and acceptance of space after 'e' sign nuked. - - ************************************************************ - * YOU MUST EDIT THE MACHINE-DEPENDENT DEFINITIONS BELOW!!! * - ************************************************************ -*/ - -/* File : stdtod.c (Modified version of str2dbl.c) - Author : Richard A. O'Keefe @ Quintus Computer Systems, Inc. - Updated: Tuesday August 2nd, 1988 - Defines: double strtod (char *str, char**ptr) -*/ - -/* This is an implementation of the strtod() function described in the - System V manuals, with a different name to avoid linker problems. - All that str2dbl() does itself is check that the argument is well-formed - and is in range. It leaves the work of conversion to atof(), which is - assumed to exist and deliver correct results (if they can be represented). - - There are two reasons why this should be provided to the net: - (a) some UNIX systems do not yet have strtod(), or do not have it - available in the BSD "universe" (but they do have atof()). - (b) some of the UNIX systems that *do* have it get it wrong. - (some crash with large arguments, some assign the wrong *ptr value). - There is a reason why *we* are providing it: we need a correct version - of strtod(), and if we give this one away maybe someone will look for - mistakes in it and fix them for us (:-). -*/ - -/* The following constants are machine-specific. MD{MIN,MAX}EXPT are - integers and MD{MIN,MAX}FRAC are strings such that - 0.${MDMAXFRAC}e${MDMAXEXPT} is the largest representable double, - 0.${MDMINFRAC}e${MDMINEXPT} is the smallest representable +ve double - MD{MIN,MAX}FRAC must not have any trailing zeros. - The values here are for IEEE-754 64-bit floats. - It is not perfectly clear to me whether an IEEE infinity should be - returned for overflow, nor what a portable way of writing one is, - so HUGE is just 0.MAXFRAC*10**MAXEXPT (this seems still to be the - UNIX convention). - - I do know about , but the whole point of this file is that - we can't always trust that stuff to be there or to be correct. -*/ -static int MDMINEXPT = -323; -static char MDMINFRAC[] = "494065645841246544"; -static double ZERO = 0.0; - -static int MDMAXEXPT = 309; -static char MDMAXFRAC[] = "17976931348623157"; -static double HUGE = 1.7976931348623157e308; - -extern double atof(const char *); /* Only called when result known to be ok */ - -#ifdef HAVE_ERRNO_H -#include -#endif -extern int errno; - -double strtod(char *str, char **ptr) -{ - int sign, scale, dotseen; - int esign, expt; - char *save; - register char *sp, *dp; - register int c; - char *buforg, *buflim; - char buffer[64]; /* 45-digit significant + */ - /* 13-digit exponent */ - sp = str; - while (*sp == ' ') sp++; - sign = 1; - if (*sp == '-') sign -= 2, sp++; - dotseen = 0, scale = 0; - dp = buffer; - *dp++ = '0'; *dp++ = '.'; - buforg = dp, buflim = buffer+48; - for (save = sp; c = *sp; sp++) - if (c == '.') { - if (dotseen) break; - dotseen++; - } else - if ((unsigned)(c-'0') > (unsigned)('9'-'0')) { - break; - } else - if (c == '0') { - if (dp != buforg) { - /* This is not the first digit, so we want to keep it */ - if (dp < buflim) *dp++ = c; - if (!dotseen) scale++; - } else { - /* No non-zero digits seen yet */ - /* If a . has been seen, scale must be adjusted */ - if (dotseen) scale--; - } - } else { - /* This is a nonzero digit, so we want to keep it */ - if (dp < buflim) *dp++ = c; - /* If it precedes a ., scale must be adjusted */ - if (!dotseen) scale++; - } - if (sp == save) { - if (ptr) *ptr = str; - errno = EDOM; /* what should this be? */ - return ZERO; - } - - while (dp > buforg && dp[-1] == '0') --dp; - if (dp == buforg) *dp++ = '0'; - *dp = '\0'; - /* Now the contents of buffer are - +--+--------+-+--------+ - |0.|fraction|\|leftover| - +--+--------+-+--------+ - ^dp points here - where fraction begins with 0 iff it is "0", and has at most - 45 digits in it, and leftover is at least 16 characters. - */ - save = sp, expt = 0, esign = 1; - do { - c = *sp++; - if (c != 'e' && c != 'E') break; - c = *sp++; - if (c == '-') esign -= 2, c = *sp++; else - if (c == '+' /* || c == ' ' */ ) c = *sp++; - if ((unsigned)(c-'0') > (unsigned)('9'-'0')) break; - while (c == '0') c = *sp++; - for (; (unsigned)(c-'0') <= (unsigned)('9'-'0'); c = *sp++) - expt = expt*10 + c-'0'; - if (esign < 0) expt = -expt; - save = sp-1; - } while (0); - if (ptr) *ptr = save; - expt += scale; - /* Now the number is sign*0.fraction*10**expt */ - errno = ERANGE; - if (expt > MDMAXEXPT) { - return HUGE*sign; - } else - if (expt == MDMAXEXPT) { - if (strcmp(buforg, MDMAXFRAC) > 0) return HUGE*sign; - } else - if (expt < MDMINEXPT) { - return ZERO*sign; - } else - if (expt == MDMINEXPT) { - if (strcmp(buforg, MDMINFRAC) < 0) return ZERO*sign; - } - /* We have now established that the number can be */ - /* represented without overflow or underflow */ - (void) sprintf(dp, "E%d", expt); - errno = 0; - return atof(buffer)*sign; -} From buildbot at python.org Tue Apr 7 02:45:36 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 00:45:36 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 3.x Message-ID: <20090407004539.084461E4017@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%203.x/builds/586 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: eric.smith,raymond.hettinger BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_multiprocessing Traceback (most recent call last): File "./Lib/test/regrtest.py", line 620, in runtest_inner indirect_test() File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/test/test_multiprocessing.py", line 1856, in test_main ProcessesMixin.pool = multiprocessing.Pool(4) File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/multiprocessing/__init__.py", line 226, in Pool return Pool(processes, initializer, initargs) File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/multiprocessing/pool.py", line 104, in __init__ w.start() File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/multiprocessing/process.py", line 99, in start _cleanup() File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/multiprocessing/process.py", line 53, in _cleanup if p._popen.poll() is not None: File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/multiprocessing/forking.py", line 107, in poll pid, sts = os.waitpid(self.pid, flag) OSError: [Errno 10] No child processes make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Tue Apr 7 02:59:30 2009 From: python-checkins at python.org (eric.smith) Date: Tue, 7 Apr 2009 02:59:30 +0200 (CEST) Subject: [Python-checkins] r71342 - in python/branches/py3k-short-float-repr: Lib/test/test_types.py Objects/stringlib/formatter.h Message-ID: <20090407005930.A17E01E4017@bag.python.org> Author: eric.smith Date: Tue Apr 7 02:59:30 2009 New Revision: 71342 Log: Moved float.__format__ over to PyOS_double_to_string. This removes the last (internal) use of PyOS_ascii_formatd, which I'd like to deprecate or just remove. The only thing that doesn't work is 'n' (locale-aware) formatting, which I'm still working on. Modified: python/branches/py3k-short-float-repr/Lib/test/test_types.py python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Modified: python/branches/py3k-short-float-repr/Lib/test/test_types.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_types.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_types.py Tue Apr 7 02:59:30 2009 @@ -467,14 +467,16 @@ self.assertEqual(value.__format__(format_spec), float(value).__format__(format_spec)) - @run_with_locale('LC_NUMERIC', 'en_US.UTF8') - def test_float__format__locale(self): - # test locale support for __format__ code 'n' - - for i in range(-10, 10): - x = 1234567890.0 * (10.0 ** i) - self.assertEqual(locale.format('%g', x, grouping=True), format(x, 'n')) - self.assertEqual(locale.format('%.10g', x, grouping=True), format(x, '.10n')) + # XXX: needs to be put back in when 'n' formatting is complete + # after the py3k-short-float-repr merge +# @run_with_locale('LC_NUMERIC', 'en_US.UTF8') +# def test_float__format__locale(self): +# # test locale support for __format__ code 'n' +# +# for i in range(-10, 10): +# x = 1234567890.0 * (10.0 ** i) +# self.assertEqual(locale.format('%g', x, grouping=True), format(x, 'n')) +# self.assertEqual(locale.format('%.10g', x, grouping=True), format(x, '.10n')) @run_with_locale('LC_NUMERIC', 'en_US.UTF8') def test_int__format__locale(self): @@ -550,7 +552,10 @@ # a totaly empty format specifier means something else. # So, just use a sign flag test(1e200, '+g', '+1e+200') - test(1e200, '+', '+1.0e+200') + + # XXX this is a change from 3.0. Needs to be vetted. +# test(1e200, '+', '+1.0e+200') + test(1.1e200, '+g', '+1.1e+200') test(1.1e200, '+', '+1.1e+200') Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h (original) +++ python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Tue Apr 7 02:59:30 2009 @@ -1,6 +1,8 @@ /* implements the string, long, and float formatters. that is, string.__format__, etc. */ +#include + /* Before including this, you must include either: stringlib/unicodedefs.h stringlib/stringdefs.h @@ -13,8 +15,6 @@ be. These are the only non-static functions defined here. */ -#define ALLOW_PARENS_FOR_SIGN 0 - /* Raises an exception about an unknown presentation type for this * type. */ @@ -104,9 +104,6 @@ { switch (c) { case ' ': case '+': case '-': -#if ALLOW_PARENS_FOR_SIGN - case '(': -#endif return 1; default: return 0; @@ -170,11 +167,6 @@ if (end-ptr >= 1 && is_sign_element(ptr[0])) { format->sign = ptr[0]; ++ptr; -#if ALLOW_PARENS_FOR_SIGN - if (end-ptr >= 1 && ptr[0] == ')') { - ++ptr; - } -#endif } /* If the next character is #, we're in alternate mode. This only @@ -258,10 +250,8 @@ Py_ssize_t n_prefix; Py_ssize_t n_spadding; Py_ssize_t n_rpadding; - char lsign; - Py_ssize_t n_lsign; - char rsign; - Py_ssize_t n_rsign; + char sign; + Py_ssize_t n_sign; Py_ssize_t n_total; /* just a convenience, it's derivable from the other fields */ } NumberFieldWidths; @@ -272,24 +262,22 @@ and more efficient enough to justify a little obfuscation? */ static void calc_number_widths(NumberFieldWidths *spec, STRINGLIB_CHAR actual_sign, - Py_ssize_t n_prefix, Py_ssize_t n_digits, - const InternalFormatSpec *format) + Py_ssize_t n_prefix, Py_ssize_t n_digits, int has_decimal, + Py_ssize_t n_rest, const InternalFormatSpec *format) { spec->n_lpadding = 0; spec->n_prefix = 0; spec->n_spadding = 0; spec->n_rpadding = 0; - spec->lsign = '\0'; - spec->n_lsign = 0; - spec->rsign = '\0'; - spec->n_rsign = 0; + spec->sign = '\0'; + spec->n_sign = 0; /* the output will look like: - | | - | | - | | + | | + | | + | | - lsign and rsign are computed from format->sign and the actual + sign is computed from format->sign and the actual sign of the number prefix is given (it's for the '0x' prefix) @@ -306,28 +294,18 @@ /* compute the various parts we're going to write */ if (format->sign == '+') { /* always put a + or - */ - spec->n_lsign = 1; - spec->lsign = (actual_sign == '-' ? '-' : '+'); + spec->n_sign = 1; + spec->sign = (actual_sign == '-' ? '-' : '+'); } -#if ALLOW_PARENS_FOR_SIGN - else if (format->sign == '(') { - if (actual_sign == '-') { - spec->n_lsign = 1; - spec->lsign = '('; - spec->n_rsign = 1; - spec->rsign = ')'; - } - } -#endif else if (format->sign == ' ') { - spec->n_lsign = 1; - spec->lsign = (actual_sign == '-' ? '-' : ' '); + spec->n_sign = 1; + spec->sign = (actual_sign == '-' ? '-' : ' '); } else { /* non specified, or the default (-) */ if (actual_sign == '-') { - spec->n_lsign = 1; - spec->lsign = '-'; + spec->n_sign = 1; + spec->sign = '-'; } } @@ -339,7 +317,7 @@ } else { /* see if any padding is needed */ - if (spec->n_lsign + n_digits + spec->n_rsign + + if (spec->n_sign + n_digits + spec->n_prefix >= format->width) { /* no padding needed, we're already bigger than the requested width */ @@ -348,8 +326,8 @@ /* determine which of left, space, or right padding is needed */ Py_ssize_t padding = format->width - - (spec->n_lsign + spec->n_prefix + - n_digits + spec->n_rsign); + (spec->n_sign + spec->n_prefix + + n_digits); if (format->align == '<') spec->n_rpadding = padding; else if (format->align == '>') @@ -364,8 +342,8 @@ spec->n_lpadding = padding; } } - spec->n_total = spec->n_lpadding + spec->n_lsign + spec->n_prefix + - spec->n_spadding + n_digits + spec->n_rsign + spec->n_rpadding; + spec->n_total = spec->n_lpadding + spec->n_sign + spec->n_prefix + + spec->n_spadding + n_digits + spec->n_rpadding; } /* fill in the non-digit parts of a numbers's string representation, @@ -382,8 +360,8 @@ STRINGLIB_FILL(p_buf, fill_char, spec->n_lpadding); p_buf += spec->n_lpadding; } - if (spec->n_lsign == 1) { - *p_buf++ = spec->lsign; + if (spec->n_sign == 1) { + *p_buf++ = spec->sign; } if (spec->n_prefix) { memmove(p_buf, @@ -397,15 +375,72 @@ } p_digits = p_buf; p_buf += n_digits; - if (spec->n_rsign == 1) { - *p_buf++ = spec->rsign; - } if (spec->n_rpadding) { STRINGLIB_FILL(p_buf, fill_char, spec->n_rpadding); p_buf += spec->n_rpadding; } return p_digits; } + +/* Find the decimal point character(s?), thousands_separator(s?), and + grouping description, either for the current locale if use_locale + is GFI_USE_LOCALE, a hard-coded locale if GFI_DEFAULT, or none if + GFI_NONE */ +#define GFI_USE_LOCALE 0 +#define GFI_DEFAULT_LOCALE 1 +#define GFI_NO_LOCALE 2 +static void +get_formatting_info(int locale, char **decimal_point, char **thousands_sep, + char **grouping) +{ + if (locale == GFI_USE_LOCALE) { + struct lconv *locale_data = localeconv(); + *decimal_point = locale_data->decimal_point; + *thousands_sep = locale_data->thousands_sep; + *grouping = locale_data->grouping; + } else if (locale == GFI_DEFAULT_LOCALE) { + *decimal_point = "."; + *thousands_sep = ","; + *grouping = "\3"; /* every 3 characters, trailing 0 means repeat */ + } else { + *decimal_point = "."; + *thousands_sep = ""; + *grouping = ""; + } +} + +/* Given a number of the form: + [+-]digits[rest] + where ptr points to the start and end points to the end, parse + the number into its integer part and then everything else (which + could be a decimal, an exponent, or both. + This is the format returned from PyOS_double_to_string(). + Results are undefined (but shouldn't crash) for improperly + formatted strings. + Consider moving this to pystrtod.c +*/ +static void +find_number_parts(STRINGLIB_CHAR *ptr, Py_ssize_t len, + STRINGLIB_CHAR **sign, + STRINGLIB_CHAR **integer_start, + STRINGLIB_CHAR **rest_start, + int *has_decimal) +{ + STRINGLIB_CHAR *end = ptr + len; + + if (ptrtype == 'X') { Py_ssize_t t; for (t = 0; t < n_prefix; ++t) - p[t + spec.n_lpadding + spec.n_lsign] = - STRINGLIB_TOUPPER(p[t + spec.n_lpadding + spec.n_lsign]); + p[t + spec.n_lpadding + spec.n_sign] = + STRINGLIB_TOUPPER(p[t + spec.n_lpadding + spec.n_sign]); } @@ -733,61 +768,47 @@ #ifdef FORMAT_FLOAT #if STRINGLIB_IS_UNICODE -/* taken from unicodeobject.c */ -static Py_ssize_t -strtounicode(Py_UNICODE *buffer, const char *charbuffer) +static void +strtounicode(Py_UNICODE *buffer, const char *charbuffer, Py_ssize_t len) { - register Py_ssize_t i; - Py_ssize_t len = strlen(charbuffer); - for (i = len - 1; i >= 0; --i) - buffer[i] = (Py_UNICODE) charbuffer[i]; - - return len; + Py_ssize_t i; + for (i = 0; i < len; ++i) + buffer[i] = (Py_UNICODE)charbuffer[i]; } #endif -/* see FORMATBUFLEN in unicodeobject.c */ -#define FLOAT_FORMATBUFLEN 120 - /* much of this is taken from unicodeobject.c */ static PyObject * format_float_internal(PyObject *value, const InternalFormatSpec *format) { - /* fmt = '%.' + `prec` + `type` + '%%' - worst case length = 2 + 10 (len of INT_MAX) + 1 + 2 = 15 (use 20)*/ - char fmt[20]; - - /* taken from unicodeobject.c */ - /* Worst case length calc to ensure no buffer overrun: - - 'g' formats: - fmt = %#.g - buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp - for any double rep.) - len = 1 + prec + 1 + 2 + 5 = 9 + prec - - 'f' formats: - buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50) - len = 1 + 50 + 1 + prec = 52 + prec - - If prec=0 the effective precision is 1 (the leading digit is - always given), therefore increase the length by one. - - */ - char charbuf[FLOAT_FORMATBUFLEN]; + char *buf = NULL; /* buffer returned from PyOS_double_to_string */ Py_ssize_t n_digits; - double x; + double val; Py_ssize_t precision = format->precision; - PyObject *result = NULL; - STRINGLIB_CHAR sign; - char* trailing = ""; + STRINGLIB_CHAR type = format->type; + STRINGLIB_CHAR sign_char = '\0'; + int add_pct = 0; + int use_locale; STRINGLIB_CHAR *p; NumberFieldWidths spec; - STRINGLIB_CHAR type = format->type; + int flags = 0; + PyObject *result = NULL; + + /* the various parts of the raw formatted number */ + STRINGLIB_CHAR *sign; + STRINGLIB_CHAR *integer_start; + STRINGLIB_CHAR *rest_start; + int has_decimal = 0; + + /* locale settings, either from the actual locale or + from a hard-code pseudo-locale */ + char *l_decimal_point; + char *l_thousands_sep; + char *l_grouping; #if STRINGLIB_IS_UNICODE - Py_UNICODE unicodebuf[FLOAT_FORMATBUFLEN]; + Py_UNICODE *unicode_tmp = NULL; #endif /* alternate is not allowed on floats. */ @@ -798,67 +819,91 @@ goto done; } - /* first, do the conversion as 8-bit chars, using the platform's - snprintf. then, if needed, convert to unicode. */ + if (type == '\0') { + /* Omitted type specifier, this is like 'g' but with at least + one digit after the decimal point. */ + type = 'g'; + flags |= Py_DTSF_ADD_DOT_0; + } + if (type == 'n') { + type = 'g'; + use_locale = GFI_USE_LOCALE; + } else if (format->thousands_separators) + use_locale = GFI_DEFAULT_LOCALE; + else + use_locale = GFI_NO_LOCALE; /* 'F' is the same as 'f', per the PEP */ if (type == 'F') type = 'f'; - x = PyFloat_AsDouble(value); + val = PyFloat_AsDouble(value); - if (x == -1.0 && PyErr_Occurred()) + if (val == -1.0 && PyErr_Occurred()) goto done; if (type == '%') { type = 'f'; - x *= 100; - trailing = "%"; + val *= 100; + add_pct = 1; } if (precision < 0) precision = 6; - if (type == 'f' && fabs(x) >= 1e50) + if (type == 'f' && fabs(val) >= 1e50) type = 'g'; /* cast "type", because if we're in unicode we need to pass a 8-bit char. this is safe, because we've restricted what "type" can be */ - PyOS_snprintf(fmt, sizeof(fmt), "%%.%" PY_FORMAT_SIZE_T "d%c", precision, - (char)type); + buf = PyOS_double_to_string(val, (char)type, precision, flags); + if (buf == NULL) + goto done; + n_digits = strlen(buf); - /* do the actual formatting */ - PyOS_ascii_formatd(charbuf, sizeof(charbuf), fmt, x); + if (add_pct) { + /* We know that buf has a trailing zero (since we just called + strlen() on it), and we don't use that fact any more. So we + can just write over the trailing zero. */ + buf[n_digits] = '%'; + n_digits += 1; + } - /* adding trailing to fmt with PyOS_snprintf doesn't work, not - sure why. we'll just concatentate it here, no harm done. we - know we can't have a buffer overflow from the fmt size - analysis */ - strcat(charbuf, trailing); - - /* rather than duplicate the code for snprintf for both unicode - and 8 bit strings, we just use the 8 bit version and then - convert to unicode in a separate code path. that's probably - the lesser of 2 evils. */ + /* Since there is no unicode version of PyOS_double_to_string, + just use the 8 bit version and then convert to unicode in a + separate code path. */ #if STRINGLIB_IS_UNICODE - n_digits = strtounicode(unicodebuf, charbuf); - p = unicodebuf; + /* This could probably be optimized away by converting into the + memory returned by STRINGLIB_NEW, but that's a project for + another day. */ + unicode_tmp = (Py_UNICODE*)PyMem_Malloc((n_digits)*sizeof(Py_UNICODE)); + if (unicode_tmp == NULL) { + PyErr_NoMemory(); + goto done; + } + strtounicode(unicode_tmp, buf, n_digits); + p = unicode_tmp; #else - /* compute the length. I believe this is done because the return - value from snprintf above is unreliable */ - n_digits = strlen(charbuf); - p = charbuf; + p = buf; #endif + find_number_parts(p, n_digits, + &sign, + &integer_start, + &rest_start, + &has_decimal); + /* is a sign character present in the output? if so, remember it and skip it */ - sign = p[0]; - if (sign == '-') { + if (sign) { + sign_char = *sign; ++p; --n_digits; } - calc_number_widths(&spec, sign, 0, n_digits, format); + get_formatting_info(use_locale, &l_decimal_point, &l_thousands_sep, &l_grouping); + + calc_number_widths(&spec, sign_char, 0, n_digits, has_decimal, 0, format); /* allocate a string with enough space */ result = STRINGLIB_NEW(NULL, spec.n_total); @@ -871,11 +916,15 @@ /* fill in the digit parts */ memmove(STRINGLIB_STR(result) + - (spec.n_lpadding + spec.n_lsign + spec.n_spadding), + (spec.n_lpadding + spec.n_sign + spec.n_spadding), p, n_digits * sizeof(STRINGLIB_CHAR)); done: + PyMem_Free(buf); +#if STRINGLIB_IS_UNICODE + PyMem_Free(unicode_tmp); +#endif return result; } #endif /* FORMAT_FLOAT */ @@ -1056,11 +1105,7 @@ /* type conversion? */ switch (format.type) { - case '\0': - /* 'Z' means like 'g', but with at least one decimal. See - PyOS_ascii_formatd */ - format.type = 'Z'; - /* Deliberate fall through to the next case statement */ + case '\0': /* No format code: like 'g', but with at least one decimal. */ case 'e': case 'E': case 'f': From python-checkins at python.org Tue Apr 7 03:02:27 2009 From: python-checkins at python.org (eric.smith) Date: Tue, 7 Apr 2009 03:02:27 +0200 (CEST) Subject: [Python-checkins] r71343 - python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Message-ID: <20090407010227.49DA11E4021@bag.python.org> Author: eric.smith Date: Tue Apr 7 03:02:27 2009 New Revision: 71343 Log: Comments for find_number_parts. Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h (original) +++ python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Tue Apr 7 03:02:27 2009 @@ -412,11 +412,12 @@ /* Given a number of the form: [+-]digits[rest] where ptr points to the start and end points to the end, parse - the number into its integer part and then everything else (which - could be a decimal, an exponent, or both. - This is the format returned from PyOS_double_to_string(). + the number into its integer part and then everything else (which + could be a decimal, an exponent, both, or neither. + This is compatible with the format returned from + PyOS_double_to_string(). Results are undefined (but shouldn't crash) for improperly - formatted strings. + formatted strings. Consider moving this to pystrtod.c */ static void From buildbot at python.org Tue Apr 7 03:03:55 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 01:03:55 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 3.x Message-ID: <20090407010355.6FB7F1E4021@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%203.x/builds/632 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: eric.smith,raymond.hettinger BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Tue Apr 7 03:54:03 2009 From: python-checkins at python.org (barry.warsaw) Date: Tue, 7 Apr 2009 03:54:03 +0200 (CEST) Subject: [Python-checkins] r71345 - in python/branches/release26-maint: Include/patchlevel.h Lib/distutils/__init__.py Lib/idlelib/idlever.py Lib/optparse.py Misc/NEWS Misc/RPM/python-2.6.spec README Message-ID: <20090407015403.851FD1E401D@bag.python.org> Author: barry.warsaw Date: Tue Apr 7 03:54:02 2009 New Revision: 71345 Log: Bump to 2.6.2c1. Modified: python/branches/release26-maint/Include/patchlevel.h python/branches/release26-maint/Lib/distutils/__init__.py python/branches/release26-maint/Lib/idlelib/idlever.py python/branches/release26-maint/Lib/optparse.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Misc/RPM/python-2.6.spec python/branches/release26-maint/README Modified: python/branches/release26-maint/Include/patchlevel.h ============================================================================== --- python/branches/release26-maint/Include/patchlevel.h (original) +++ python/branches/release26-maint/Include/patchlevel.h Tue Apr 7 03:54:02 2009 @@ -22,12 +22,12 @@ /*--start constants--*/ #define PY_MAJOR_VERSION 2 #define PY_MINOR_VERSION 6 -#define PY_MICRO_VERSION 1 +#define PY_MICRO_VERSION 2 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "2.6.1+" +#define PY_VERSION "2.6.2c1" /*--end constants--*/ /* Subversion Revision number of this file (not of the repository) */ Modified: python/branches/release26-maint/Lib/distutils/__init__.py ============================================================================== --- python/branches/release26-maint/Lib/distutils/__init__.py (original) +++ python/branches/release26-maint/Lib/distutils/__init__.py Tue Apr 7 03:54:02 2009 @@ -22,5 +22,5 @@ # #--start constants-- -__version__ = "2.6.1" +__version__ = "2.6.2c1" #--end constants-- Modified: python/branches/release26-maint/Lib/idlelib/idlever.py ============================================================================== --- python/branches/release26-maint/Lib/idlelib/idlever.py (original) +++ python/branches/release26-maint/Lib/idlelib/idlever.py Tue Apr 7 03:54:02 2009 @@ -1 +1 @@ -IDLE_VERSION = "2.6.1" +IDLE_VERSION = "2.6.2c1" Modified: python/branches/release26-maint/Lib/optparse.py ============================================================================== --- python/branches/release26-maint/Lib/optparse.py (original) +++ python/branches/release26-maint/Lib/optparse.py Tue Apr 7 03:54:02 2009 @@ -995,7 +995,7 @@ """add_option(Option) add_option(opt_str, ..., kwarg=val, ...) """ - if type(args[0]) is types.StringType: + if type(args[0]) in types.StringTypes: option = self.option_class(*args, **kwargs) elif len(args) == 1 and not kwargs: option = args[0] Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Tue Apr 7 03:54:02 2009 @@ -4,10 +4,10 @@ (editors: check NEWS.help for information about editing NEWS using ReST.) -What's New in Python 2.6.2 -========================== +What's New in Python 2.6.2 rc 1 +=============================== -*Release date: XX-XXX-200X* +*Release date: 06-Apr-2009* Core and Builtins ----------------- @@ -19,8 +19,8 @@ - Issue #1665206: Remove the last eager import in _warnings.c and make it lazy. -- Issue #4034: Fix weird attribute error messages of the traceback object. (As a - result traceback.__members__ no longer exists.) +- Issue #4034: Fix weird attribute error messages of the traceback object. (As + a result traceback.__members__ no longer exists.) - Issue #5247: Improve error message when unknown format codes are used when using str.format() with str, unicode, long, int, and @@ -137,8 +137,8 @@ - Issue #5619: Multiprocessing children disobey the debug flag and causes popups on windows buildbots. Patch applied to work around this issue. -- Issue #5632: Thread.ident was None for the main thread and threads not created - with the threading module. +- Issue #5632: Thread.ident was None for the main thread and threads not + created with the threading module. - Issue #5400: Added patch for multiprocessing on netbsd compilation/support @@ -186,8 +186,8 @@ - Issue #5179: Fixed subprocess handle leak on failure on windows. -- Issue #4308: httplib.IncompleteRead's repr doesn't include all of the data all - ready received. +- Issue #4308: httplib.IncompleteRead's repr doesn't include all of the data + all ready received. - Issue #5401: Fixed a performance problem in mimetypes when ``from mimetypes import guess_extension`` was used. @@ -217,11 +217,11 @@ function without argtypes (only occurs if HAVE_USABLE_WCHAR_T is false). - Issue #3321: _multiprocessing.Connection() doesn't check handle; added checks - for *nix machines for negative handles and large int handles. Without this check - it is possible to segfault the interpreter. + for *nix machines for negative handles and large int handles. Without this + check it is possible to segfault the interpreter. -- Issue #4449: AssertionError in mp_benchmarks.py, caused by an underlying issue - in sharedctypes.py. +- Issue #4449: AssertionError in mp_benchmarks.py, caused by an underlying + issue in sharedctypes.py. - Issue #3386: distutils.sysconfig.get_python_lib prefix argument was ignored under NT and OS2. Patch by Philip Jenvey. Modified: python/branches/release26-maint/Misc/RPM/python-2.6.spec ============================================================================== --- python/branches/release26-maint/Misc/RPM/python-2.6.spec (original) +++ python/branches/release26-maint/Misc/RPM/python-2.6.spec Tue Apr 7 03:54:02 2009 @@ -34,7 +34,7 @@ %define name python #--start constants-- -%define version 2.6.1 +%define version 2.6.2c1 %define libver 2.6 #--end constants-- %define release 1pydotorg Modified: python/branches/release26-maint/README ============================================================================== --- python/branches/release26-maint/README (original) +++ python/branches/release26-maint/README Tue Apr 7 03:54:02 2009 @@ -1,4 +1,4 @@ -This is Python version 2.6.1 +This is Python version 2.6.2 ============================ Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 From python-checkins at python.org Tue Apr 7 03:54:35 2009 From: python-checkins at python.org (barry.warsaw) Date: Tue, 7 Apr 2009 03:54:35 +0200 (CEST) Subject: [Python-checkins] r71346 - python/tags/r262c1 Message-ID: <20090407015435.BE3EA1E4021@bag.python.org> Author: barry.warsaw Date: Tue Apr 7 03:54:35 2009 New Revision: 71346 Log: Tag for 2.6.2 candidate 1 Added: python/tags/r262c1/ - copied from r71345, /python/branches/release26-maint/ From python-checkins at python.org Tue Apr 7 04:08:23 2009 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 7 Apr 2009 04:08:23 +0200 (CEST) Subject: [Python-checkins] r71347 - python/branches/py3k/Doc/reference/datamodel.rst Message-ID: <20090407020823.734C11E401D@bag.python.org> Author: raymond.hettinger Date: Tue Apr 7 04:08:23 2009 New Revision: 71347 Log: Add an example metaclass showing a use of __prepare__() as outlined in PEP 3115. Modified: python/branches/py3k/Doc/reference/datamodel.rst Modified: python/branches/py3k/Doc/reference/datamodel.rst ============================================================================== --- python/branches/py3k/Doc/reference/datamodel.rst (original) +++ python/branches/py3k/Doc/reference/datamodel.rst Tue Apr 7 04:08:23 2009 @@ -1541,6 +1541,38 @@ property creation, proxies, frameworks, and automatic resource locking/synchronization. +Here is an example of a metaclass that uses an :class:`OrderedDict` to +remember the order that class members were defined:: + + class OrderedClass(type): + + @classmethod + def __prepare__(metacls, name, bases, **kwds): + return collections.OrderedDict() + + def __new__(cls, name, bases, classdict): + result = type.__new__(cls, name, bases, dict(classdict)) + result.members = tuple(classdict) + return result + + class A(metaclass=OrderedClass): + def one(self): pass + def two(self): pass + def three(self): pass + def four(self): pass + + >>> A.members + ('__module__', 'one', 'two', 'three', 'four') + +When the class definition for *A* get executed, the first step is calling the +metaclass's :meth:`__prepare__` method which returns an empty +:class:`collections.OrderedDict`. That mapping records the methods and +attributes of *A* as they are defined within the body of the class statement. +Once those definitions are executed, the ordered dict is fully populated, and +then the metaclass's :meth:`__new__ ` method gets invoked. That method builds +the new type and saves the keys for the ordered dictionary in an attribute +called *members*. + .. _callable-types: From python-checkins at python.org Tue Apr 7 04:09:15 2009 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 7 Apr 2009 04:09:15 +0200 (CEST) Subject: [Python-checkins] r71348 - python/branches/py3k/Doc/reference/datamodel.rst Message-ID: <20090407020915.8DA1E1E401D@bag.python.org> Author: raymond.hettinger Date: Tue Apr 7 04:09:15 2009 New Revision: 71348 Log: Fix internal link. Modified: python/branches/py3k/Doc/reference/datamodel.rst Modified: python/branches/py3k/Doc/reference/datamodel.rst ============================================================================== --- python/branches/py3k/Doc/reference/datamodel.rst (original) +++ python/branches/py3k/Doc/reference/datamodel.rst Tue Apr 7 04:09:15 2009 @@ -1541,8 +1541,8 @@ property creation, proxies, frameworks, and automatic resource locking/synchronization. -Here is an example of a metaclass that uses an :class:`OrderedDict` to -remember the order that class members were defined:: +Here is an example of a metaclass that uses an :class:`collections.OrderedDict` +to remember the order that class members were defined:: class OrderedClass(type): From python-checkins at python.org Tue Apr 7 04:31:14 2009 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 7 Apr 2009 04:31:14 +0200 (CEST) Subject: [Python-checkins] r71349 - python/branches/py3k/Doc/reference/datamodel.rst Message-ID: <20090407023114.E39F81E401D@bag.python.org> Author: raymond.hettinger Date: Tue Apr 7 04:31:14 2009 New Revision: 71349 Log: Fix nits Modified: python/branches/py3k/Doc/reference/datamodel.rst Modified: python/branches/py3k/Doc/reference/datamodel.rst ============================================================================== --- python/branches/py3k/Doc/reference/datamodel.rst (original) +++ python/branches/py3k/Doc/reference/datamodel.rst Tue Apr 7 04:31:14 2009 @@ -1564,13 +1564,13 @@ >>> A.members ('__module__', 'one', 'two', 'three', 'four') -When the class definition for *A* get executed, the first step is calling the -metaclass's :meth:`__prepare__` method which returns an empty +When the class definition for *A* gets executed, the process begins with +calling the metaclass's :meth:`__prepare__` method which returns an empty :class:`collections.OrderedDict`. That mapping records the methods and attributes of *A* as they are defined within the body of the class statement. -Once those definitions are executed, the ordered dict is fully populated, and -then the metaclass's :meth:`__new__ ` method gets invoked. That method builds -the new type and saves the keys for the ordered dictionary in an attribute +Once those definitions are executed, the ordered dictionary is fully populated +and the metaclass's :meth:`__new__ ` method gets invoked. That method builds +the new type and it saves the ordered dictionary keys in an attribute called *members*. From buildbot at python.org Tue Apr 7 05:13:12 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 03:13:12 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 3.0 Message-ID: <20090407031312.C9F841E401D@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%203.0/builds/259 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: benjamin.peterson,eric.smith,guido.van.rossum,hirokazu.yamamoto,jeremy.hylton,jesse.noller,mark.dickinson,martin.v.loewis,matthias.klose,r.david.murray,raymond.hettinger,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Tue Apr 7 09:11:00 2009 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 7 Apr 2009 09:11:00 +0200 (CEST) Subject: [Python-checkins] r71350 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090407071100.F03B41E401C@bag.python.org> Author: raymond.hettinger Date: Tue Apr 7 09:11:00 2009 New Revision: 71350 Log: Put core language changes in a separate section from module changes. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Tue Apr 7 09:11:00 2009 @@ -143,6 +143,30 @@ (Contributed by Fredrik Johansson, Victor Stinner, Raymond Hettinger, and Mark Dickinson; :issue:`3439`.) +* The fields in :func:`format` strings can now be automatically + numbered:: + + >>> 'Sir {} of {}'.format('Gallahad', 'Camelot') + 'Sir Gallahad of Camelot' + + Formerly, the string would have required numbered fields such as: + ``'Sir {0} of {1}'``. + + (Contributed by Eric Smith; :issue:`5237`.) + +* ``round(x, n)`` now returns an integer if *x* is an integer. + Previously it returned a float:: + + >>> round(1123, -2) + 1100 + + (Contributed by Mark Dickinson; :issue:`4707`.) + +.. ====================================================================== + +New, Improved, and Deprecated Modules +===================================== + * Added a :class:`collections.Counter` class to support convenient counting of unique items in a sequence or iterable:: @@ -180,17 +204,6 @@ (Contributed by Raymond Hettinger and Mark Dickinson.) -* The fields in :func:`format` strings can now be automatically - numbered:: - - >>> 'Sir {} of {}'.format('Gallahad', 'Camelot') - 'Sir Gallahad of Camelot' - - Formerly, the string would have required numbered fields such as: - ``'Sir {0} of {1}'``. - - (Contributed by Eric Smith; :issue:`5237`.) - * The :mod:`itertools` module grew two new functions. The :func:`itertools.combinations_with_replacement` function is one of four for generating combinatorics including permutations and Cartesian @@ -220,14 +233,6 @@ (Contributed by Raymond Hettinger; :issue:`1818`.) -* ``round(x, n)`` now returns an integer if *x* is an integer. - Previously it returned a float:: - - >>> round(1123, -2) - 1100 - - (Contributed by Mark Dickinson; :issue:`4707`.) - * The :func:`re.sub`, :func:`re.subn` and :func:`re.split` functions now accept a flags parameter. @@ -283,7 +288,7 @@ Optimizations -------------- +============= Major performance enhancements have been added: @@ -334,7 +339,7 @@ Apart from the performance improvements this change should be invisible to end users, with one exception: for testing and debugging purposes there's a - new :class:`structseq` ``sys.int_info`` that provides information about the + new :attr:`sys.int_info` that provides information about the internal format, giving the number of bits per digit and the size in bytes of the C type used to store each digit:: From nnorwitz at gmail.com Tue Apr 7 10:09:09 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 7 Apr 2009 04:09:09 -0400 Subject: [Python-checkins] Python Regression Test Failures basics (7) Message-ID: <20090407080909.GA25789@python.psfb.org> 327 tests OK. 7 tests failed: test_asyncore test_generators test_genexps test_lib2to3 test_multiprocessing test_syntax test_telnetlib 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ast test_asynchat test_asyncore test test_asyncore failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_asyncore.py", line 144, in test_readwrite self.assertEqual(tobj.read, True) AssertionError: False != True 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils 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_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_gdbm test_generators ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: f=lambda: (yield 1),(yield 2) Expected: Traceback (most recent call last): ... SyntaxError: 'yield' outside function (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: 'yield' outside function ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): x = yield = y Expected: Traceback (most recent call last): ... SyntaxError: assignment to yield expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: assignment to yield expression not possible ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): (yield bar) = y Expected: Traceback (most recent call last): ... SyntaxError: can't assign to yield expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to yield expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): (yield bar) += y Expected: Traceback (most recent call last): ... SyntaxError: augmented assignment to yield expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to yield expression not possible ********************************************************************** 1 items had failures: 4 of 99 in test.test_generators.__test__.coroutine ***Test Failed*** 4 failures. test test_generators failed -- 4 of 284 doctests failed test_genericpath test_genexps ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_genexps.py", line ?, in test.test_genexps.__test__.doctests Failed example: (y for y in (1,2)) = 10 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to generator expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to generator expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_genexps.py", line ?, in test.test_genexps.__test__.doctests Failed example: (y for y in (1,2)) += 10 Expected: Traceback (most recent call last): ... SyntaxError: augmented assignment to generator expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to generator expression not possible ********************************************************************** 1 items had failures: 2 of 75 in test.test_genexps.__test__.doctests ***Test Failed*** 2 failures. test test_genexps failed -- 2 of 75 doctests failed 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 [13183 refs] [13183 refs] [13183 refs] [23375 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 test_lib2to3 crashed -- : No module named myfixes 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 test_multiprocessing crashed -- : cannot import name SkipTest test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18903 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 30, in test.test_syntax Failed example: obj.None = 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 34, in test.test_syntax Failed example: None = 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 42, in test.test_syntax Failed example: () = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to () (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to () ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 46, in test.test_syntax Failed example: f() = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to function call (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 50, in test.test_syntax Failed example: del f() Expected: Traceback (most recent call last): SyntaxError: can't delete function call (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't delete function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 54, in test.test_syntax Failed example: a + 1 = 2 Expected: Traceback (most recent call last): SyntaxError: can't assign to operator (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to operator ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 58, in test.test_syntax Failed example: (x for x in x) = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to generator expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to generator expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 62, in test.test_syntax Failed example: 1 = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 66, in test.test_syntax Failed example: "abc" = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 70, in test.test_syntax Failed example: `1` = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to repr (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to repr ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 79, in test.test_syntax Failed example: (a, "b", c) = (1, 2, 3) Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 83, in test.test_syntax Failed example: [a, b, c + 1] = [1, 2, 3] Expected: Traceback (most recent call last): SyntaxError: can't assign to operator (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to operator ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 87, in test.test_syntax Failed example: a if 1 else b = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to conditional expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to conditional expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 93, in test.test_syntax Failed example: def f(None=1): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 101, in test.test_syntax Failed example: def f(x, y=1, z): pass Expected: Traceback (most recent call last): SyntaxError: non-default argument follows default argument (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: non-default argument follows default argument ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 106, in test.test_syntax Failed example: def f(x, None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 111, in test.test_syntax Failed example: def f(*None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 116, in test.test_syntax Failed example: def f(**None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 124, in test.test_syntax Failed example: def None(x): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 137, in test.test_syntax Failed example: f(x for x in L, 1) Expected: Traceback (most recent call last): SyntaxError: Generator expression must be parenthesized if not sole argument (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: Generator expression must be parenthesized if not sole argument ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 143, in test.test_syntax Failed example: f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, i121, i122, i123, i124, i125, i126, i127, i128, i129, i130, i131, i132, i133, i134, i135, i136, i137, i138, i139, i140, i141, i142, i143, i144, i145, i146, i147, i148, i149, i150, i151, i152, i153, i154, i155, i156, i157, i158, i159, i160, i161, i162, i163, i164, i165, i166, i167, i168, i169, i170, i171, i172, i173, i174, i175, i176, i177, i178, i179, i180, i181, i182, i183, i184, i185, i186, i187, i188, i189, i190, i191, i192, i193, i194, i195, i196, i197, i198, i199, i200, i201, i202, i203, i204, i205, i206, i207, i208, i209, i210, i211, i212, i213, i214, i215, i216, i217, i218, i219, i220, i221, i222, i223, i224, i225, i226, i227, i228, i229, i230, i231, i232, i233, i234, i235, i236, i237, i238, i239, i240, i241, i242, i243, i244, i245, i246, i247, i248, i249, i250, i251, i252, i253, i254, i255) Expected: Traceback (most recent call last): SyntaxError: more than 255 arguments (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: more than 255 arguments ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 177, in test.test_syntax Failed example: f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, i121, i122, i123, i124, i125, i126, i127, i128, i129, i130, i131, i132, i133, i134, i135, i136, i137, i138, i139, i140, i141, i142, i143, i144, i145, i146, i147, i148, i149, i150, i151, i152, i153, i154, i155, i156, i157, i158, i159, i160, i161, i162, i163, i164, i165, i166, i167, i168, i169, i170, i171, i172, i173, i174, i175, i176, i177, i178, i179, i180, i181, i182, i183, i184, i185, i186, i187, i188, i189, i190, i191, i192, i193, i194, i195, i196, i197, i198, i199, i200, i201, i202, i203, i204, i205, i206, i207, i208, i209, i210, i211, i212, i213, i214, i215, i216, i217, i218, i219, i220, i221, i222, i223, i224, i225, i226, i227, i228, i229, i230, i231, i232, i233, i234, i235, i236, i237, i238, i239, i240, i241, i242, i243, (x for x in i244), i245, i246, i247, i248, i249, i250, i251, i252=1, i253=1, i254=1, i255=1) Expected: Traceback (most recent call last): SyntaxError: more than 255 arguments (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: more than 255 arguments ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 207, in test.test_syntax Failed example: f(lambda x: x[0] = 3) Expected: Traceback (most recent call last): SyntaxError: lambda cannot contain assignment (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: lambda cannot contain assignment ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 214, in test.test_syntax Failed example: f(x()=2) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 217, in test.test_syntax Failed example: f(a or b=1) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 220, in test.test_syntax Failed example: f(x.y=1) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 227, in test.test_syntax Failed example: (x for x in x) += 1 Expected: Traceback (most recent call last): SyntaxError: augmented assignment to generator expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to generator expression not possible ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 230, in test.test_syntax Failed example: None += 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 233, in test.test_syntax Failed example: f() += 1 Expected: Traceback (most recent call last): SyntaxError: illegal expression for augmented assignment (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: illegal expression for augmented assignment ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 254, in test.test_syntax Failed example: def test(): for abc in range(10): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 266, in test.test_syntax Failed example: def test(): for abc in range(10): try: pass finally: try: continue except: pass Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 7) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 7 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 279, in test.test_syntax Failed example: def foo(): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 5) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 5 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 288, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 298, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: try: continue finally: pass Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 7) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 7 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 311, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: try: pass except: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 8) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 8 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 328, in test.test_syntax Failed example: try: print 1 break print 2 finally: print 3 Expected: Traceback (most recent call last): ... SyntaxError: 'break' outside loop (, line 3) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 3 SyntaxError: 'break' outside loop ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 372, in test.test_syntax Failed example: if 1: x() = 1 elif 1: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 2) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 2 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 380, in test.test_syntax Failed example: if 1: pass elif 1: x() = 1 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 4) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 4 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 388, in test.test_syntax Failed example: if 1: x() = 1 elif 1: pass else: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 2) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 2 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 398, in test.test_syntax Failed example: if 1: pass elif 1: x() = 1 else: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 4) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 4 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 408, in test.test_syntax Failed example: if 1: pass elif 1: pass else: x() = 1 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 418, in test.test_syntax Failed example: f(a=23, a=234) Expected: Traceback (most recent call last): ... SyntaxError: keyword argument repeated (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword argument repeated ********************************************************************** 1 items had failures: 42 of 50 in test.test_syntax ***Test Failed*** 42 failures. test test_syntax failed -- 42 of 50 doctests failed test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test test_telnetlib failed -- errors occurred; run in verbose mode for details test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18059 refs] [17873 refs] [17873 refs] [17873 refs] [17873 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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_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 327 tests OK. 7 tests failed: test_asyncore test_generators test_genexps test_lib2to3 test_multiprocessing test_syntax test_telnetlib 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl [701504 refs] From nnorwitz at gmail.com Tue Apr 7 10:16:34 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 7 Apr 2009 04:16:34 -0400 Subject: [Python-checkins] Python Regression Test Failures opt (7) Message-ID: <20090407081634.GA28231@python.psfb.org> 327 tests OK. 7 tests failed: test_asyncore test_generators test_genexps test_lib2to3 test_multiprocessing test_syntax test_telnetlib 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ast test_asynchat test_asyncore test test_asyncore failed -- errors occurred; run in verbose mode for details 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils [17363 refs] [17363 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_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_gdbm test_generators ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: f=lambda: (yield 1),(yield 2) Expected: Traceback (most recent call last): ... SyntaxError: 'yield' outside function (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: 'yield' outside function ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): x = yield = y Expected: Traceback (most recent call last): ... SyntaxError: assignment to yield expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: assignment to yield expression not possible ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): (yield bar) = y Expected: Traceback (most recent call last): ... SyntaxError: can't assign to yield expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to yield expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): (yield bar) += y Expected: Traceback (most recent call last): ... SyntaxError: augmented assignment to yield expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to yield expression not possible ********************************************************************** 1 items had failures: 4 of 99 in test.test_generators.__test__.coroutine ***Test Failed*** 4 failures. test test_generators failed -- 4 of 284 doctests failed test_genericpath test_genexps ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_genexps.py", line ?, in test.test_genexps.__test__.doctests Failed example: (y for y in (1,2)) = 10 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to generator expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to generator expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_genexps.py", line ?, in test.test_genexps.__test__.doctests Failed example: (y for y in (1,2)) += 10 Expected: Traceback (most recent call last): ... SyntaxError: augmented assignment to generator expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to generator expression not possible ********************************************************************** 1 items had failures: 2 of 75 in test.test_genexps.__test__.doctests ***Test Failed*** 2 failures. test test_genexps failed -- 2 of 75 doctests failed 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 [13183 refs] [13183 refs] [13183 refs] [23375 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 test_lib2to3 crashed -- : No module named myfixes 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 test_multiprocessing crashed -- : cannot import name SkipTest test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18903 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 30, in test.test_syntax Failed example: obj.None = 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 34, in test.test_syntax Failed example: None = 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 42, in test.test_syntax Failed example: () = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to () (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to () ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 46, in test.test_syntax Failed example: f() = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to function call (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 50, in test.test_syntax Failed example: del f() Expected: Traceback (most recent call last): SyntaxError: can't delete function call (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't delete function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 54, in test.test_syntax Failed example: a + 1 = 2 Expected: Traceback (most recent call last): SyntaxError: can't assign to operator (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to operator ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 58, in test.test_syntax Failed example: (x for x in x) = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to generator expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to generator expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 62, in test.test_syntax Failed example: 1 = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 66, in test.test_syntax Failed example: "abc" = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 70, in test.test_syntax Failed example: `1` = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to repr (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to repr ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 79, in test.test_syntax Failed example: (a, "b", c) = (1, 2, 3) Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 83, in test.test_syntax Failed example: [a, b, c + 1] = [1, 2, 3] Expected: Traceback (most recent call last): SyntaxError: can't assign to operator (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to operator ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 87, in test.test_syntax Failed example: a if 1 else b = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to conditional expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to conditional expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 93, in test.test_syntax Failed example: def f(None=1): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 101, in test.test_syntax Failed example: def f(x, y=1, z): pass Expected: Traceback (most recent call last): SyntaxError: non-default argument follows default argument (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: non-default argument follows default argument ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 106, in test.test_syntax Failed example: def f(x, None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 111, in test.test_syntax Failed example: def f(*None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 116, in test.test_syntax Failed example: def f(**None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 124, in test.test_syntax Failed example: def None(x): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 137, in test.test_syntax Failed example: f(x for x in L, 1) Expected: Traceback (most recent call last): SyntaxError: Generator expression must be parenthesized if not sole argument (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: Generator expression must be parenthesized if not sole argument ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 143, in test.test_syntax Failed example: f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, i121, i122, i123, i124, i125, i126, i127, i128, i129, i130, i131, i132, i133, i134, i135, i136, i137, i138, i139, i140, i141, i142, i143, i144, i145, i146, i147, i148, i149, i150, i151, i152, i153, i154, i155, i156, i157, i158, i159, i160, i161, i162, i163, i164, i165, i166, i167, i168, i169, i170, i171, i172, i173, i174, i175, i176, i177, i178, i179, i180, i181, i182, i183, i184, i185, i186, i187, i188, i189, i190, i191, i192, i193, i194, i195, i196, i197, i198, i199, i200, i201, i202, i203, i204, i205, i206, i207, i208, i209, i210, i211, i212, i213, i214, i215, i216, i217, i218, i219, i220, i221, i222, i223, i224, i225, i226, i227, i228, i229, i230, i231, i232, i233, i234, i235, i236, i237, i238, i239, i240, i241, i242, i243, i244, i245, i246, i247, i248, i249, i250, i251, i252, i253, i254, i255) Expected: Traceback (most recent call last): SyntaxError: more than 255 arguments (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: more than 255 arguments ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 177, in test.test_syntax Failed example: f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, i121, i122, i123, i124, i125, i126, i127, i128, i129, i130, i131, i132, i133, i134, i135, i136, i137, i138, i139, i140, i141, i142, i143, i144, i145, i146, i147, i148, i149, i150, i151, i152, i153, i154, i155, i156, i157, i158, i159, i160, i161, i162, i163, i164, i165, i166, i167, i168, i169, i170, i171, i172, i173, i174, i175, i176, i177, i178, i179, i180, i181, i182, i183, i184, i185, i186, i187, i188, i189, i190, i191, i192, i193, i194, i195, i196, i197, i198, i199, i200, i201, i202, i203, i204, i205, i206, i207, i208, i209, i210, i211, i212, i213, i214, i215, i216, i217, i218, i219, i220, i221, i222, i223, i224, i225, i226, i227, i228, i229, i230, i231, i232, i233, i234, i235, i236, i237, i238, i239, i240, i241, i242, i243, (x for x in i244), i245, i246, i247, i248, i249, i250, i251, i252=1, i253=1, i254=1, i255=1) Expected: Traceback (most recent call last): SyntaxError: more than 255 arguments (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: more than 255 arguments ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 207, in test.test_syntax Failed example: f(lambda x: x[0] = 3) Expected: Traceback (most recent call last): SyntaxError: lambda cannot contain assignment (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: lambda cannot contain assignment ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 214, in test.test_syntax Failed example: f(x()=2) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 217, in test.test_syntax Failed example: f(a or b=1) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 220, in test.test_syntax Failed example: f(x.y=1) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 227, in test.test_syntax Failed example: (x for x in x) += 1 Expected: Traceback (most recent call last): SyntaxError: augmented assignment to generator expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to generator expression not possible ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 230, in test.test_syntax Failed example: None += 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 233, in test.test_syntax Failed example: f() += 1 Expected: Traceback (most recent call last): SyntaxError: illegal expression for augmented assignment (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: illegal expression for augmented assignment ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 254, in test.test_syntax Failed example: def test(): for abc in range(10): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 266, in test.test_syntax Failed example: def test(): for abc in range(10): try: pass finally: try: continue except: pass Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 7) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 7 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 279, in test.test_syntax Failed example: def foo(): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 5) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 5 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 288, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 298, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: try: continue finally: pass Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 7) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 7 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 311, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: try: pass except: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 8) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 8 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 328, in test.test_syntax Failed example: try: print 1 break print 2 finally: print 3 Expected: Traceback (most recent call last): ... SyntaxError: 'break' outside loop (, line 3) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 3 SyntaxError: 'break' outside loop ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 372, in test.test_syntax Failed example: if 1: x() = 1 elif 1: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 2) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 2 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 380, in test.test_syntax Failed example: if 1: pass elif 1: x() = 1 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 4) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 4 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 388, in test.test_syntax Failed example: if 1: x() = 1 elif 1: pass else: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 2) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 2 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 398, in test.test_syntax Failed example: if 1: pass elif 1: x() = 1 else: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 4) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 4 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 408, in test.test_syntax Failed example: if 1: pass elif 1: pass else: x() = 1 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 418, in test.test_syntax Failed example: f(a=23, a=234) Expected: Traceback (most recent call last): ... SyntaxError: keyword argument repeated (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword argument repeated ********************************************************************** 1 items had failures: 42 of 50 in test.test_syntax ***Test Failed*** 42 failures. test test_syntax failed -- 42 of 50 doctests failed test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test test_telnetlib failed -- errors occurred; run in verbose mode for details test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18896 refs] [17873 refs] [17873 refs] [17873 refs] [17873 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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_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 327 tests OK. 7 tests failed: test_asyncore test_generators test_genexps test_lib2to3 test_multiprocessing test_syntax test_telnetlib 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl [700777 refs] From python-checkins at python.org Tue Apr 7 11:16:26 2009 From: python-checkins at python.org (eric.smith) Date: Tue, 7 Apr 2009 11:16:26 +0200 (CEST) Subject: [Python-checkins] r71351 - in python/branches/py3k-short-float-repr: Doc/reference/datamodel.rst Doc/whatsnew/3.1.rst Message-ID: <20090407091626.C38DF1E407B@bag.python.org> Author: eric.smith Date: Tue Apr 7 11:16:26 2009 New Revision: 71351 Log: Merged revisions 71339-71350 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r71341 | eric.smith | 2009-04-06 20:07:34 -0400 (Mon, 06 Apr 2009) | 1 line Removed unused files in preparation for merging py3k-short-float-repr. ........ r71347 | raymond.hettinger | 2009-04-06 22:08:23 -0400 (Mon, 06 Apr 2009) | 1 line Add an example metaclass showing a use of __prepare__() as outlined in PEP 3115. ........ r71348 | raymond.hettinger | 2009-04-06 22:09:15 -0400 (Mon, 06 Apr 2009) | 1 line Fix internal link. ........ r71349 | raymond.hettinger | 2009-04-06 22:31:14 -0400 (Mon, 06 Apr 2009) | 1 line Fix nits ........ r71350 | raymond.hettinger | 2009-04-07 03:11:00 -0400 (Tue, 07 Apr 2009) | 1 line Put core language changes in a separate section from module changes. ........ Modified: python/branches/py3k-short-float-repr/ (props changed) python/branches/py3k-short-float-repr/Doc/reference/datamodel.rst python/branches/py3k-short-float-repr/Doc/whatsnew/3.1.rst Modified: python/branches/py3k-short-float-repr/Doc/reference/datamodel.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/reference/datamodel.rst (original) +++ python/branches/py3k-short-float-repr/Doc/reference/datamodel.rst Tue Apr 7 11:16:26 2009 @@ -1541,6 +1541,38 @@ property creation, proxies, frameworks, and automatic resource locking/synchronization. +Here is an example of a metaclass that uses an :class:`collections.OrderedDict` +to remember the order that class members were defined:: + + class OrderedClass(type): + + @classmethod + def __prepare__(metacls, name, bases, **kwds): + return collections.OrderedDict() + + def __new__(cls, name, bases, classdict): + result = type.__new__(cls, name, bases, dict(classdict)) + result.members = tuple(classdict) + return result + + class A(metaclass=OrderedClass): + def one(self): pass + def two(self): pass + def three(self): pass + def four(self): pass + + >>> A.members + ('__module__', 'one', 'two', 'three', 'four') + +When the class definition for *A* gets executed, the process begins with +calling the metaclass's :meth:`__prepare__` method which returns an empty +:class:`collections.OrderedDict`. That mapping records the methods and +attributes of *A* as they are defined within the body of the class statement. +Once those definitions are executed, the ordered dictionary is fully populated +and the metaclass's :meth:`__new__ ` method gets invoked. That method builds +the new type and it saves the ordered dictionary keys in an attribute +called *members*. + .. _callable-types: Modified: python/branches/py3k-short-float-repr/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k-short-float-repr/Doc/whatsnew/3.1.rst Tue Apr 7 11:16:26 2009 @@ -143,6 +143,30 @@ (Contributed by Fredrik Johansson, Victor Stinner, Raymond Hettinger, and Mark Dickinson; :issue:`3439`.) +* The fields in :func:`format` strings can now be automatically + numbered:: + + >>> 'Sir {} of {}'.format('Gallahad', 'Camelot') + 'Sir Gallahad of Camelot' + + Formerly, the string would have required numbered fields such as: + ``'Sir {0} of {1}'``. + + (Contributed by Eric Smith; :issue:`5237`.) + +* ``round(x, n)`` now returns an integer if *x* is an integer. + Previously it returned a float:: + + >>> round(1123, -2) + 1100 + + (Contributed by Mark Dickinson; :issue:`4707`.) + +.. ====================================================================== + +New, Improved, and Deprecated Modules +===================================== + * Added a :class:`collections.Counter` class to support convenient counting of unique items in a sequence or iterable:: @@ -180,17 +204,6 @@ (Contributed by Raymond Hettinger and Mark Dickinson.) -* The fields in :func:`format` strings can now be automatically - numbered:: - - >>> 'Sir {} of {}'.format('Gallahad', 'Camelot') - 'Sir Gallahad of Camelot' - - Formerly, the string would have required numbered fields such as: - ``'Sir {0} of {1}'``. - - (Contributed by Eric Smith; :issue:`5237`.) - * The :mod:`itertools` module grew two new functions. The :func:`itertools.combinations_with_replacement` function is one of four for generating combinatorics including permutations and Cartesian @@ -220,14 +233,6 @@ (Contributed by Raymond Hettinger; :issue:`1818`.) -* ``round(x, n)`` now returns an integer if *x* is an integer. - Previously it returned a float:: - - >>> round(1123, -2) - 1100 - - (Contributed by Mark Dickinson; :issue:`4707`.) - * The :func:`re.sub`, :func:`re.subn` and :func:`re.split` functions now accept a flags parameter. @@ -283,7 +288,7 @@ Optimizations -------------- +============= Major performance enhancements have been added: @@ -334,7 +339,7 @@ Apart from the performance improvements this change should be invisible to end users, with one exception: for testing and debugging purposes there's a - new :class:`structseq` ``sys.int_info`` that provides information about the + new :attr:`sys.int_info` that provides information about the internal format, giving the number of bits per digit and the size in bytes of the C type used to store each digit:: From nnorwitz at gmail.com Tue Apr 7 11:33:25 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 7 Apr 2009 05:33:25 -0400 Subject: [Python-checkins] Python Regression Test Failures all (7) Message-ID: <20090407093325.GA18020@python.psfb.org> 332 tests OK. 7 tests failed: test_asyncore test_generators test_genexps test_lib2to3 test_multiprocessing test_syntax test_telnetlib 26 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_cd test_cl test_epoll test_gl test_imgfile test_ioctl test_kqueue test_macos test_macostools 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ast test_asynchat test_asyncore test test_asyncore failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_asyncore.py", line 144, in test_readwrite self.assertEqual(tobj.read, True) AssertionError: False != True 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-14349 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils 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_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_gdbm test_generators ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: f=lambda: (yield 1),(yield 2) Expected: Traceback (most recent call last): ... SyntaxError: 'yield' outside function (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: 'yield' outside function ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): x = yield = y Expected: Traceback (most recent call last): ... SyntaxError: assignment to yield expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: assignment to yield expression not possible ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): (yield bar) = y Expected: Traceback (most recent call last): ... SyntaxError: can't assign to yield expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to yield expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine Failed example: def f(): (yield bar) += y Expected: Traceback (most recent call last): ... SyntaxError: augmented assignment to yield expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to yield expression not possible ********************************************************************** 1 items had failures: 4 of 99 in test.test_generators.__test__.coroutine ***Test Failed*** 4 failures. test test_generators failed -- 4 of 284 doctests failed test_genericpath test_genexps ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_genexps.py", line ?, in test.test_genexps.__test__.doctests Failed example: (y for y in (1,2)) = 10 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to generator expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to generator expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_genexps.py", line ?, in test.test_genexps.__test__.doctests Failed example: (y for y in (1,2)) += 10 Expected: Traceback (most recent call last): ... SyntaxError: augmented assignment to generator expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to generator expression not possible ********************************************************************** 1 items had failures: 2 of 75 in test.test_genexps.__test__.doctests ***Test Failed*** 2 failures. test test_genexps failed -- 2 of 75 doctests failed 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 [13183 refs] [13183 refs] [13183 refs] [23375 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 test_lib2to3 crashed -- : No module named myfixes 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 test_multiprocessing crashed -- : cannot import name SkipTest test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18903 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib test_socket test_socketserver 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 30, in test.test_syntax Failed example: obj.None = 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 34, in test.test_syntax Failed example: None = 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 42, in test.test_syntax Failed example: () = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to () (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to () ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 46, in test.test_syntax Failed example: f() = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to function call (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 50, in test.test_syntax Failed example: del f() Expected: Traceback (most recent call last): SyntaxError: can't delete function call (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't delete function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 54, in test.test_syntax Failed example: a + 1 = 2 Expected: Traceback (most recent call last): SyntaxError: can't assign to operator (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to operator ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 58, in test.test_syntax Failed example: (x for x in x) = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to generator expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to generator expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 62, in test.test_syntax Failed example: 1 = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 66, in test.test_syntax Failed example: "abc" = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 70, in test.test_syntax Failed example: `1` = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to repr (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to repr ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 79, in test.test_syntax Failed example: (a, "b", c) = (1, 2, 3) Expected: Traceback (most recent call last): SyntaxError: can't assign to literal (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to literal ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 83, in test.test_syntax Failed example: [a, b, c + 1] = [1, 2, 3] Expected: Traceback (most recent call last): SyntaxError: can't assign to operator (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to operator ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 87, in test.test_syntax Failed example: a if 1 else b = 1 Expected: Traceback (most recent call last): SyntaxError: can't assign to conditional expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: can't assign to conditional expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 93, in test.test_syntax Failed example: def f(None=1): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 101, in test.test_syntax Failed example: def f(x, y=1, z): pass Expected: Traceback (most recent call last): SyntaxError: non-default argument follows default argument (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: non-default argument follows default argument ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 106, in test.test_syntax Failed example: def f(x, None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 111, in test.test_syntax Failed example: def f(*None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 116, in test.test_syntax Failed example: def f(**None): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 124, in test.test_syntax Failed example: def None(x): pass Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 137, in test.test_syntax Failed example: f(x for x in L, 1) Expected: Traceback (most recent call last): SyntaxError: Generator expression must be parenthesized if not sole argument (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: Generator expression must be parenthesized if not sole argument ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 143, in test.test_syntax Failed example: f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, i121, i122, i123, i124, i125, i126, i127, i128, i129, i130, i131, i132, i133, i134, i135, i136, i137, i138, i139, i140, i141, i142, i143, i144, i145, i146, i147, i148, i149, i150, i151, i152, i153, i154, i155, i156, i157, i158, i159, i160, i161, i162, i163, i164, i165, i166, i167, i168, i169, i170, i171, i172, i173, i174, i175, i176, i177, i178, i179, i180, i181, i182, i183, i184, i185, i186, i187, i188, i189, i190, i191, i192, i193, i194, i195, i196, i197, i198, i199, i200, i201, i202, i203, i204, i205, i206, i207, i208, i209, i210, i211, i212, i213, i214, i215, i216, i217, i218, i219, i220, i221, i222, i223, i224, i225, i226, i227, i228, i229, i230, i231, i232, i233, i234, i235, i236, i237, i238, i239, i240, i241, i242, i243, i244, i245, i246, i247, i248, i249, i250, i251, i252, i253, i254, i255) Expected: Traceback (most recent call last): SyntaxError: more than 255 arguments (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: more than 255 arguments ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 177, in test.test_syntax Failed example: f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101, i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115, i116, i117, i118, i119, i120, i121, i122, i123, i124, i125, i126, i127, i128, i129, i130, i131, i132, i133, i134, i135, i136, i137, i138, i139, i140, i141, i142, i143, i144, i145, i146, i147, i148, i149, i150, i151, i152, i153, i154, i155, i156, i157, i158, i159, i160, i161, i162, i163, i164, i165, i166, i167, i168, i169, i170, i171, i172, i173, i174, i175, i176, i177, i178, i179, i180, i181, i182, i183, i184, i185, i186, i187, i188, i189, i190, i191, i192, i193, i194, i195, i196, i197, i198, i199, i200, i201, i202, i203, i204, i205, i206, i207, i208, i209, i210, i211, i212, i213, i214, i215, i216, i217, i218, i219, i220, i221, i222, i223, i224, i225, i226, i227, i228, i229, i230, i231, i232, i233, i234, i235, i236, i237, i238, i239, i240, i241, i242, i243, (x for x in i244), i245, i246, i247, i248, i249, i250, i251, i252=1, i253=1, i254=1, i255=1) Expected: Traceback (most recent call last): SyntaxError: more than 255 arguments (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: more than 255 arguments ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 207, in test.test_syntax Failed example: f(lambda x: x[0] = 3) Expected: Traceback (most recent call last): SyntaxError: lambda cannot contain assignment (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: lambda cannot contain assignment ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 214, in test.test_syntax Failed example: f(x()=2) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 217, in test.test_syntax Failed example: f(a or b=1) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 220, in test.test_syntax Failed example: f(x.y=1) Expected: Traceback (most recent call last): SyntaxError: keyword can't be an expression (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword can't be an expression ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 227, in test.test_syntax Failed example: (x for x in x) += 1 Expected: Traceback (most recent call last): SyntaxError: augmented assignment to generator expression not possible (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: augmented assignment to generator expression not possible ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 230, in test.test_syntax Failed example: None += 1 Expected: Traceback (most recent call last): SyntaxError: cannot assign to None (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: cannot assign to None ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 233, in test.test_syntax Failed example: f() += 1 Expected: Traceback (most recent call last): SyntaxError: illegal expression for augmented assignment (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: illegal expression for augmented assignment ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 254, in test.test_syntax Failed example: def test(): for abc in range(10): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 266, in test.test_syntax Failed example: def test(): for abc in range(10): try: pass finally: try: continue except: pass Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 7) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 7 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 279, in test.test_syntax Failed example: def foo(): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 5) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 5 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 288, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 298, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: try: continue finally: pass Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 7) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 7 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 311, in test.test_syntax Failed example: def foo(): for a in (): try: pass finally: try: pass except: continue Expected: Traceback (most recent call last): ... SyntaxError: 'continue' not supported inside 'finally' clause (, line 8) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 8 SyntaxError: 'continue' not supported inside 'finally' clause ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 328, in test.test_syntax Failed example: try: print 1 break print 2 finally: print 3 Expected: Traceback (most recent call last): ... SyntaxError: 'break' outside loop (, line 3) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 3 SyntaxError: 'break' outside loop ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 372, in test.test_syntax Failed example: if 1: x() = 1 elif 1: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 2) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 2 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 380, in test.test_syntax Failed example: if 1: pass elif 1: x() = 1 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 4) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 4 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 388, in test.test_syntax Failed example: if 1: x() = 1 elif 1: pass else: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 2) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 2 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 398, in test.test_syntax Failed example: if 1: pass elif 1: x() = 1 else: pass Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 4) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 4 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 408, in test.test_syntax Failed example: if 1: pass elif 1: pass else: x() = 1 Expected: Traceback (most recent call last): ... SyntaxError: can't assign to function call (, line 6) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 6 SyntaxError: can't assign to function call ********************************************************************** File "/tmp/python-test/local/lib/python2.7/test/test_syntax.py", line 418, in test.test_syntax Failed example: f(a=23, a=234) Expected: Traceback (most recent call last): ... SyntaxError: keyword argument repeated (, line 1) Got: Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/doctest.py", line 1241, in __run compileflags, 1) in test.globs File "", line 1 SyntaxError: keyword argument repeated ********************************************************************** 1 items had failures: 42 of 50 in test.test_syntax ***Test Failed*** 42 failures. test test_syntax failed -- 42 of 50 doctests failed test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test test_telnetlib failed -- errors occurred; run in verbose mode for details test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18059 refs] [17873 refs] [17873 refs] [17873 refs] [17873 refs] test_threading_local test_threadsignals test_time test_timeout 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_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllibnet test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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_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 332 tests OK. 7 tests failed: test_asyncore test_generators test_genexps test_lib2to3 test_multiprocessing test_syntax test_telnetlib 26 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_cd test_cl test_epoll test_gl test_imgfile test_ioctl test_kqueue test_macos test_macostools 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl [716537 refs] From python-checkins at python.org Tue Apr 7 12:59:29 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 7 Apr 2009 12:59:29 +0200 (CEST) Subject: [Python-checkins] r71352 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090407105929.919B71E4031@bag.python.org> Author: mark.dickinson Date: Tue Apr 7 12:59:28 2009 New Revision: 71352 Log: Reformat dtoa.c to follow PEP 7 more closely Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Tue Apr 7 12:59:28 2009 @@ -18,9 +18,10 @@ ***************************************************************/ /**************************************************************** - * This is dtoa.c by David Gay, obtained from http://www.netlib.org/fp/dtoa.c - * on March 17, 2009 and modified for inclusion into the Python core by Mark - * Dickinson and Eric Smith. The major modifications are as follows: + * This is dtoa.c by David M. Gay, downloaded from + * http://www.netlib.org/fp/dtoa.c on March 17, 2009 and modified for + * inclusion into the Python core by Mark E. T. Dickinson and Eric V. Smith. + * The major modifications are as follows: * * 0. The original code has been specialized to Python's needs by removing * many of the #ifdef'd sections. In particular, code to support VAX and @@ -52,6 +53,9 @@ * 5. A bug in the original dtoa.c code, in which '.nan' and '.inf' * were accepted as valid inputs to strtod, has been fixed. * + * 6. The code has been reformatted to better fit with Python's + * C style guide (PEP 7). + * ***************************************************************/ /* Please send bug reports for the original dtoa.c code to David M. Gay (dmg @@ -63,7 +67,7 @@ * necessary to specify double-precision (53-bit) rounding precision * before invoking strtod or dtoa. If the machine uses (the equivalent * of) Intel 80x87 arithmetic, the call - * _control87(PC_53, MCW_PC); + * _control87(PC_53, MCW_PC); * does this with many compilers. Whether this or another call is * appropriate depends on the compiler; for this to work, it may be * necessary to #include "float.h" or another system-dependent header @@ -82,35 +86,35 @@ * * Modifications: * - * 1. We only require IEEE, IBM, or VAX double-precision - * arithmetic (not IEEE double-extended). - * 2. We get by with floating-point arithmetic in a case that - * Clinger missed -- when we're computing d * 10^n - * for a small integer d and the integer n is not too - * much larger than 22 (the maximum integer k for which - * we can represent 10^k exactly), we may be able to - * compute (d*10^k) * 10^(e-k) with just one roundoff. - * 3. Rather than a bit-at-a-time adjustment of the binary - * result in the hard case, we use floating-point - * arithmetic to determine the adjustment to within - * one bit; only in really hard cases do we need to - * compute a second residual. - * 4. Because of 3., we don't need a large table of powers of 10 - * for ten-to-e (just some small tables, e.g. of 10^k - * for 0 <= k <= 22). + * 1. We only require IEEE, IBM, or VAX double-precision + * arithmetic (not IEEE double-extended). + * 2. We get by with floating-point arithmetic in a case that + * Clinger missed -- when we're computing d * 10^n + * for a small integer d and the integer n is not too + * much larger than 22 (the maximum integer k for which + * we can represent 10^k exactly), we may be able to + * compute (d*10^k) * 10^(e-k) with just one roundoff. + * 3. Rather than a bit-at-a-time adjustment of the binary + * result in the hard case, we use floating-point + * arithmetic to determine the adjustment to within + * one bit; only in really hard cases do we need to + * compute a second residual. + * 4. Because of 3., we don't need a large table of powers of 10 + * for ten-to-e (just some small tables, e.g. of 10^k + * for 0 <= k <= 22). */ /* * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 - * and strtod and dtoa should round accordingly. Unless Trust_FLT_ROUNDS - * is also #defined, fegetround() will be queried for the rounding mode. - * Note that both FLT_ROUNDS and fegetround() are specified by the C99 - * standard (and are specified to be consistent, with fesetround() - * affecting the value of FLT_ROUNDS), but that some (Linux) systems - * do not work correctly in this regard, so using fegetround() is more - * portable than using FLT_FOUNDS directly. + * and strtod and dtoa should round accordingly. Unless Trust_FLT_ROUNDS + * is also #defined, fegetround() will be queried for the rounding mode. + * Note that both FLT_ROUNDS and fegetround() are specified by the C99 + * standard (and are specified to be consistent, with fesetround() + * affecting the value of FLT_ROUNDS), but that some (Linux) systems + * do not work correctly in this regard, so using fegetround() is more + * portable than using FLT_FOUNDS directly. * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 - * and Honor_FLT_ROUNDS is not #defined. + * and Honor_FLT_ROUNDS is not #defined. */ /* Linking of Python's #defines to Gay's #defines starts here. */ @@ -191,11 +195,11 @@ * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) */ #if defined(IEEE_8087) -#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ -((unsigned short *)a)[0] = (unsigned short)c, a++) +#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ + ((unsigned short *)a)[0] = (unsigned short)c, a++) #else -#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ -((unsigned short *)a)[1] = (unsigned short)c, a++) +#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ + ((unsigned short *)a)[1] = (unsigned short)c, a++) #endif /* #define P DBL_MANT_DIG */ @@ -254,1655 +258,1659 @@ typedef struct BCinfo BCinfo; - struct -BCinfo { int dp0, dp1, dplen, dsign, e0, inexact, nd, nd0, rounding, scale, uflchk; }; +struct +BCinfo { + int dp0, dp1, dplen, dsign, e0, inexact; + int nd, nd0, rounding, scale, uflchk; +}; #define FFFFFFFF 0xffffffffUL #define Kmax 7 - struct +struct Bigint { - struct Bigint *next; - int k, maxwds, sign, wds; - ULong x[1]; - }; + struct Bigint *next; + int k, maxwds, sign, wds; + ULong x[1]; +}; - typedef struct Bigint Bigint; +typedef struct Bigint Bigint; - static Bigint *freelist[Kmax+1]; +static Bigint *freelist[Kmax+1]; - static Bigint * +static Bigint * Balloc - (int k) +(int k) { - int x; - Bigint *rv; - unsigned int len; - - if (k <= Kmax && (rv = freelist[k])) - freelist[k] = rv->next; - else { - x = 1 << k; - len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) - /sizeof(double); - if (pmem_next - private_mem + len <= PRIVATE_mem) { - rv = (Bigint*)pmem_next; - pmem_next += len; - } - else { - rv = (Bigint*)MALLOC(len*sizeof(double)); - if (rv == NULL) - return NULL; - } - rv->k = k; - rv->maxwds = x; - } - rv->sign = rv->wds = 0; - return rv; - } + int x; + Bigint *rv; + unsigned int len; + + if (k <= Kmax && (rv = freelist[k])) + freelist[k] = rv->next; + else { + x = 1 << k; + len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) + /sizeof(double); + if (pmem_next - private_mem + len <= PRIVATE_mem) { + rv = (Bigint*)pmem_next; + pmem_next += len; + } + else { + rv = (Bigint*)MALLOC(len*sizeof(double)); + if (rv == NULL) + return NULL; + } + rv->k = k; + rv->maxwds = x; + } + rv->sign = rv->wds = 0; + return rv; +} - static void +static void Bfree - (Bigint *v) +(Bigint *v) { - if (v) { - if (v->k > Kmax) - FREE((void*)v); - else { - v->next = freelist[v->k]; - freelist[v->k] = v; - } - } - } + if (v) { + if (v->k > Kmax) + FREE((void*)v); + else { + v->next = freelist[v->k]; + freelist[v->k] = v; + } + } +} -#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ -y->wds*sizeof(Long) + 2*sizeof(int)) +#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ + y->wds*sizeof(Long) + 2*sizeof(int)) - static Bigint * +static Bigint * multadd - (Bigint *b, int m, int a) /* multiply by m and add a */ +(Bigint *b, int m, int a) /* multiply by m and add a */ { - int i, wds; + int i, wds; #ifdef ULLong - ULong *x; - ULLong carry, y; + ULong *x; + ULLong carry, y; #else - ULong carry, *x, y; - ULong xi, z; + ULong carry, *x, y; + ULong xi, z; #endif - Bigint *b1; + Bigint *b1; - wds = b->wds; - x = b->x; - i = 0; - carry = a; - do { + wds = b->wds; + x = b->x; + i = 0; + carry = a; + do { #ifdef ULLong - y = *x * (ULLong)m + carry; - carry = y >> 32; - *x++ = y & FFFFFFFF; + y = *x * (ULLong)m + carry; + carry = y >> 32; + *x++ = y & FFFFFFFF; #else - xi = *x; - y = (xi & 0xffff) * m + carry; - z = (xi >> 16) * m + (y >> 16); - carry = z >> 16; - *x++ = (z << 16) + (y & 0xffff); -#endif - } - while(++i < wds); - if (carry) { - if (wds >= b->maxwds) { - b1 = Balloc(b->k+1); - if (b1 == NULL){ - Bfree(b); - return NULL; - } - Bcopy(b1, b); - Bfree(b); - b = b1; - } - b->x[wds++] = carry; - b->wds = wds; - } - return b; - } + xi = *x; + y = (xi & 0xffff) * m + carry; + z = (xi >> 16) * m + (y >> 16); + carry = z >> 16; + *x++ = (z << 16) + (y & 0xffff); +#endif + } + while(++i < wds); + if (carry) { + if (wds >= b->maxwds) { + b1 = Balloc(b->k+1); + if (b1 == NULL){ + Bfree(b); + return NULL; + } + Bcopy(b1, b); + Bfree(b); + b = b1; + } + b->x[wds++] = carry; + b->wds = wds; + } + return b; +} - static Bigint * +static Bigint * s2b - (const char *s, int nd0, int nd, ULong y9, int dplen) +(const char *s, int nd0, int nd, ULong y9, int dplen) { - Bigint *b; - int i, k; - Long x, y; - - x = (nd + 8) / 9; - for(k = 0, y = 1; x > y; y <<= 1, k++) ; - b = Balloc(k); - if (b == NULL) - return NULL; - b->x[0] = y9; - b->wds = 1; - - i = 9; - if (9 < nd0) { - s += 9; - do { - b = multadd(b, 10, *s++ - '0'); - if (b == NULL) - return NULL; - } while(++i < nd0); - s += dplen; - } - else - s += dplen + 9; - for(; i < nd; i++) { - b = multadd(b, 10, *s++ - '0'); - if (b == NULL) - return NULL; - } - return b; - } + Bigint *b; + int i, k; + Long x, y; + + x = (nd + 8) / 9; + for(k = 0, y = 1; x > y; y <<= 1, k++) ; + b = Balloc(k); + if (b == NULL) + return NULL; + b->x[0] = y9; + b->wds = 1; + + i = 9; + if (9 < nd0) { + s += 9; + do { + b = multadd(b, 10, *s++ - '0'); + if (b == NULL) + return NULL; + } while(++i < nd0); + s += dplen; + } + else + s += dplen + 9; + for(; i < nd; i++) { + b = multadd(b, 10, *s++ - '0'); + if (b == NULL) + return NULL; + } + return b; +} - static int +static int hi0bits - (ULong x) +(ULong x) { - int k = 0; + int k = 0; - if (!(x & 0xffff0000)) { - k = 16; - x <<= 16; - } - if (!(x & 0xff000000)) { - k += 8; - x <<= 8; - } - if (!(x & 0xf0000000)) { - k += 4; - x <<= 4; - } - if (!(x & 0xc0000000)) { - k += 2; - x <<= 2; - } - if (!(x & 0x80000000)) { - k++; - if (!(x & 0x40000000)) - return 32; - } - return k; - } + if (!(x & 0xffff0000)) { + k = 16; + x <<= 16; + } + if (!(x & 0xff000000)) { + k += 8; + x <<= 8; + } + if (!(x & 0xf0000000)) { + k += 4; + x <<= 4; + } + if (!(x & 0xc0000000)) { + k += 2; + x <<= 2; + } + if (!(x & 0x80000000)) { + k++; + if (!(x & 0x40000000)) + return 32; + } + return k; +} - static int +static int lo0bits - (ULong *y) +(ULong *y) { - int k; - ULong x = *y; + int k; + ULong x = *y; - if (x & 7) { - if (x & 1) - return 0; - if (x & 2) { - *y = x >> 1; - return 1; - } - *y = x >> 2; - return 2; - } - k = 0; - if (!(x & 0xffff)) { - k = 16; - x >>= 16; - } - if (!(x & 0xff)) { - k += 8; - x >>= 8; - } - if (!(x & 0xf)) { - k += 4; - x >>= 4; - } - if (!(x & 0x3)) { - k += 2; - x >>= 2; - } - if (!(x & 1)) { - k++; - x >>= 1; - if (!x) - return 32; - } - *y = x; - return k; - } + if (x & 7) { + if (x & 1) + return 0; + if (x & 2) { + *y = x >> 1; + return 1; + } + *y = x >> 2; + return 2; + } + k = 0; + if (!(x & 0xffff)) { + k = 16; + x >>= 16; + } + if (!(x & 0xff)) { + k += 8; + x >>= 8; + } + if (!(x & 0xf)) { + k += 4; + x >>= 4; + } + if (!(x & 0x3)) { + k += 2; + x >>= 2; + } + if (!(x & 1)) { + k++; + x >>= 1; + if (!x) + return 32; + } + *y = x; + return k; +} - static Bigint * +static Bigint * i2b - (int i) +(int i) { - Bigint *b; + Bigint *b; - b = Balloc(1); - if (b == NULL) - return NULL; - b->x[0] = i; - b->wds = 1; - return b; - } + b = Balloc(1); + if (b == NULL) + return NULL; + b->x[0] = i; + b->wds = 1; + return b; +} - static Bigint * +static Bigint * mult - (Bigint *a, Bigint *b) +(Bigint *a, Bigint *b) { - Bigint *c; - int k, wa, wb, wc; - ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; - ULong y; + Bigint *c; + int k, wa, wb, wc; + ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; + ULong y; #ifdef ULLong - ULLong carry, z; + ULLong carry, z; #else - ULong carry, z; - ULong z2; + ULong carry, z; + ULong z2; #endif - if (a->wds < b->wds) { - c = a; - a = b; - b = c; - } - k = a->k; - wa = a->wds; - wb = b->wds; - wc = wa + wb; - if (wc > a->maxwds) - k++; - c = Balloc(k); - if (c == NULL) - return NULL; - for(x = c->x, xa = x + wc; x < xa; x++) - *x = 0; - xa = a->x; - xae = xa + wa; - xb = b->x; - xbe = xb + wb; - xc0 = c->x; + if (a->wds < b->wds) { + c = a; + a = b; + b = c; + } + k = a->k; + wa = a->wds; + wb = b->wds; + wc = wa + wb; + if (wc > a->maxwds) + k++; + c = Balloc(k); + if (c == NULL) + return NULL; + for(x = c->x, xa = x + wc; x < xa; x++) + *x = 0; + xa = a->x; + xae = xa + wa; + xb = b->x; + xbe = xb + wb; + xc0 = c->x; #ifdef ULLong - for(; xb < xbe; xc0++) { - if ((y = *xb++)) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * (ULLong)y + *xc + carry; - carry = z >> 32; - *xc++ = z & FFFFFFFF; - } - while(x < xae); - *xc = carry; - } - } + for(; xb < xbe; xc0++) { + if ((y = *xb++)) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * (ULLong)y + *xc + carry; + carry = z >> 32; + *xc++ = z & FFFFFFFF; + } + while(x < xae); + *xc = carry; + } + } #else - for(; xb < xbe; xb++, xc0++) { - if (y = *xb & 0xffff) { - x = xa; - xc = xc0; - carry = 0; - do { - z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; - carry = z >> 16; - z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; - carry = z2 >> 16; - Storeinc(xc, z2, z); - } - while(x < xae); - *xc = carry; - } - if (y = *xb >> 16) { - x = xa; - xc = xc0; - carry = 0; - z2 = *xc; - do { - z = (*x & 0xffff) * y + (*xc >> 16) + carry; - carry = z >> 16; - Storeinc(xc, z, z2); - z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; - carry = z2 >> 16; - } - while(x < xae); - *xc = z2; - } - } -#endif - for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; - c->wds = wc; - return c; - } + for(; xb < xbe; xb++, xc0++) { + if (y = *xb & 0xffff) { + x = xa; + xc = xc0; + carry = 0; + do { + z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; + carry = z >> 16; + z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; + carry = z2 >> 16; + Storeinc(xc, z2, z); + } + while(x < xae); + *xc = carry; + } + if (y = *xb >> 16) { + x = xa; + xc = xc0; + carry = 0; + z2 = *xc; + do { + z = (*x & 0xffff) * y + (*xc >> 16) + carry; + carry = z >> 16; + Storeinc(xc, z, z2); + z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; + carry = z2 >> 16; + } + while(x < xae); + *xc = z2; + } + } +#endif + for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; + c->wds = wc; + return c; +} - static Bigint *p5s; +static Bigint *p5s; - static Bigint * +static Bigint * pow5mult - (Bigint *b, int k) +(Bigint *b, int k) { - Bigint *b1, *p5, *p51; - int i; - static int p05[3] = { 5, 25, 125 }; - - if ((i = k & 3)) { - b = multadd(b, p05[i-1], 0); - if (b == NULL) - return NULL; - } - - if (!(k >>= 2)) - return b; - p5 = p5s; - if (!p5) { - /* first time */ - p5 = i2b(625); - if (p5 == NULL) { - Bfree(b); - return NULL; - } - p5s = p5; - p5->next = 0; - } - for(;;) { - if (k & 1) { - b1 = mult(b, p5); - Bfree(b); - b = b1; - if (b == NULL) - return NULL; - } - if (!(k >>= 1)) - break; - p51 = p5->next; - if (!p51) { - p51 = mult(p5,p5); - if (p51 == NULL) { - Bfree(b); - return NULL; - } - p51->next = 0; - p5->next = p51; - } - p5 = p51; - } - return b; - } + Bigint *b1, *p5, *p51; + int i; + static int p05[3] = { 5, 25, 125 }; + + if ((i = k & 3)) { + b = multadd(b, p05[i-1], 0); + if (b == NULL) + return NULL; + } + + if (!(k >>= 2)) + return b; + p5 = p5s; + if (!p5) { + /* first time */ + p5 = i2b(625); + if (p5 == NULL) { + Bfree(b); + return NULL; + } + p5s = p5; + p5->next = 0; + } + for(;;) { + if (k & 1) { + b1 = mult(b, p5); + Bfree(b); + b = b1; + if (b == NULL) + return NULL; + } + if (!(k >>= 1)) + break; + p51 = p5->next; + if (!p51) { + p51 = mult(p5,p5); + if (p51 == NULL) { + Bfree(b); + return NULL; + } + p51->next = 0; + p5->next = p51; + } + p5 = p51; + } + return b; +} - static Bigint * +static Bigint * lshift - (Bigint *b, int k) +(Bigint *b, int k) { - int i, k1, n, n1; - Bigint *b1; - ULong *x, *x1, *xe, z; - - n = k >> 5; - k1 = b->k; - n1 = n + b->wds + 1; - for(i = b->maxwds; n1 > i; i <<= 1) - k1++; - b1 = Balloc(k1); - if (b1 == NULL) { - Bfree(b); - return NULL; - } - x1 = b1->x; - for(i = 0; i < n; i++) - *x1++ = 0; - x = b->x; - xe = x + b->wds; - if (k &= 0x1f) { - k1 = 32 - k; - z = 0; - do { - *x1++ = *x << k | z; - z = *x++ >> k1; - } - while(x < xe); - if ((*x1 = z)) - ++n1; - } - else do - *x1++ = *x++; - while(x < xe); - b1->wds = n1 - 1; - Bfree(b); - return b1; - } + int i, k1, n, n1; + Bigint *b1; + ULong *x, *x1, *xe, z; + + n = k >> 5; + k1 = b->k; + n1 = n + b->wds + 1; + for(i = b->maxwds; n1 > i; i <<= 1) + k1++; + b1 = Balloc(k1); + if (b1 == NULL) { + Bfree(b); + return NULL; + } + x1 = b1->x; + for(i = 0; i < n; i++) + *x1++ = 0; + x = b->x; + xe = x + b->wds; + if (k &= 0x1f) { + k1 = 32 - k; + z = 0; + do { + *x1++ = *x << k | z; + z = *x++ >> k1; + } + while(x < xe); + if ((*x1 = z)) + ++n1; + } + else do + *x1++ = *x++; + while(x < xe); + b1->wds = n1 - 1; + Bfree(b); + return b1; +} - static int +static int cmp - (Bigint *a, Bigint *b) +(Bigint *a, Bigint *b) { - ULong *xa, *xa0, *xb, *xb0; - int i, j; + ULong *xa, *xa0, *xb, *xb0; + int i, j; - i = a->wds; - j = b->wds; + i = a->wds; + j = b->wds; #ifdef DEBUG - if (i > 1 && !a->x[i-1]) - Bug("cmp called with a->x[a->wds-1] == 0"); - if (j > 1 && !b->x[j-1]) - Bug("cmp called with b->x[b->wds-1] == 0"); -#endif - if (i -= j) - return i; - xa0 = a->x; - xa = xa0 + j; - xb0 = b->x; - xb = xb0 + j; - for(;;) { - if (*--xa != *--xb) - return *xa < *xb ? -1 : 1; - if (xa <= xa0) - break; - } - return 0; - } + if (i > 1 && !a->x[i-1]) + Bug("cmp called with a->x[a->wds-1] == 0"); + if (j > 1 && !b->x[j-1]) + Bug("cmp called with b->x[b->wds-1] == 0"); +#endif + if (i -= j) + return i; + xa0 = a->x; + xa = xa0 + j; + xb0 = b->x; + xb = xb0 + j; + for(;;) { + if (*--xa != *--xb) + return *xa < *xb ? -1 : 1; + if (xa <= xa0) + break; + } + return 0; +} - static Bigint * +static Bigint * diff - (Bigint *a, Bigint *b) +(Bigint *a, Bigint *b) { - Bigint *c; - int i, wa, wb; - ULong *xa, *xae, *xb, *xbe, *xc; + Bigint *c; + int i, wa, wb; + ULong *xa, *xae, *xb, *xbe, *xc; #ifdef ULLong - ULLong borrow, y; + ULLong borrow, y; #else - ULong borrow, y; - ULong z; + ULong borrow, y; + ULong z; #endif - i = cmp(a,b); - if (!i) { - c = Balloc(0); - if (c == NULL) - return NULL; - c->wds = 1; - c->x[0] = 0; - return c; - } - if (i < 0) { - c = a; - a = b; - b = c; - i = 1; - } - else - i = 0; - c = Balloc(a->k); - if (c == NULL) - return NULL; - c->sign = i; - wa = a->wds; - xa = a->x; - xae = xa + wa; - wb = b->wds; - xb = b->x; - xbe = xb + wb; - xc = c->x; - borrow = 0; + i = cmp(a,b); + if (!i) { + c = Balloc(0); + if (c == NULL) + return NULL; + c->wds = 1; + c->x[0] = 0; + return c; + } + if (i < 0) { + c = a; + a = b; + b = c; + i = 1; + } + else + i = 0; + c = Balloc(a->k); + if (c == NULL) + return NULL; + c->sign = i; + wa = a->wds; + xa = a->x; + xae = xa + wa; + wb = b->wds; + xb = b->x; + xbe = xb + wb; + xc = c->x; + borrow = 0; #ifdef ULLong - do { - y = (ULLong)*xa++ - *xb++ - borrow; - borrow = y >> 32 & (ULong)1; - *xc++ = y & FFFFFFFF; - } - while(xb < xbe); - while(xa < xae) { - y = *xa++ - borrow; - borrow = y >> 32 & (ULong)1; - *xc++ = y & FFFFFFFF; - } + do { + y = (ULLong)*xa++ - *xb++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = y & FFFFFFFF; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = y & FFFFFFFF; + } #else - do { - y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(xc, z, y); - } - while(xb < xbe); - while(xa < xae) { - y = (*xa & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*xa++ >> 16) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(xc, z, y); - } -#endif - while(!*--xc) - wa--; - c->wds = wa; - return c; - } + do { + y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } + while(xb < xbe); + while(xa < xae) { + y = (*xa & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } +#endif + while(!*--xc) + wa--; + c->wds = wa; + return c; +} - static double +static double ulp - (U *x) +(U *x) { - Long L; - U u; + Long L; + U u; - L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; - word0(&u) = L; - word1(&u) = 0; - return dval(&u); - } + L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; + word0(&u) = L; + word1(&u) = 0; + return dval(&u); +} - static double +static double b2d - (Bigint *a, int *e) +(Bigint *a, int *e) { - ULong *xa, *xa0, w, y, z; - int k; - U d; + ULong *xa, *xa0, w, y, z; + int k; + U d; #define d0 word0(&d) #define d1 word1(&d) - xa0 = a->x; - xa = xa0 + a->wds; - y = *--xa; + xa0 = a->x; + xa = xa0 + a->wds; + y = *--xa; #ifdef DEBUG - if (!y) Bug("zero y in b2d"); + if (!y) Bug("zero y in b2d"); #endif - k = hi0bits(y); - *e = 32 - k; - if (k < Ebits) { - d0 = Exp_1 | y >> (Ebits - k); - w = xa > xa0 ? *--xa : 0; - d1 = y << ((32-Ebits) + k) | w >> (Ebits - k); - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - if (k -= Ebits) { - d0 = Exp_1 | y << k | z >> (32 - k); - y = xa > xa0 ? *--xa : 0; - d1 = z << k | y >> (32 - k); - } - else { - d0 = Exp_1 | y; - d1 = z; - } - ret_d: + k = hi0bits(y); + *e = 32 - k; + if (k < Ebits) { + d0 = Exp_1 | y >> (Ebits - k); + w = xa > xa0 ? *--xa : 0; + d1 = y << ((32-Ebits) + k) | w >> (Ebits - k); + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + if (k -= Ebits) { + d0 = Exp_1 | y << k | z >> (32 - k); + y = xa > xa0 ? *--xa : 0; + d1 = z << k | y >> (32 - k); + } + else { + d0 = Exp_1 | y; + d1 = z; + } + ret_d: #undef d0 #undef d1 - return dval(&d); - } + return dval(&d); +} - static Bigint * +static Bigint * d2b - (U *d, int *e, int *bits) +(U *d, int *e, int *bits) { - Bigint *b; - int de, k; - ULong *x, y, z; - int i; + Bigint *b; + int de, k; + ULong *x, y, z; + int i; #define d0 word0(d) #define d1 word1(d) - b = Balloc(1); - if (b == NULL) - return NULL; - x = b->x; - - z = d0 & Frac_mask; - d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ - if ((de = (int)(d0 >> Exp_shift))) - z |= Exp_msk1; - if ((y = d1)) { - if ((k = lo0bits(&y))) { - x[0] = y | z << (32 - k); - z >>= k; - } - else - x[0] = y; - i = - b->wds = (x[1] = z) ? 2 : 1; - } - else { - k = lo0bits(&z); - x[0] = z; - i = - b->wds = 1; - k += 32; - } - if (de) { - *e = de - Bias - (P-1) + k; - *bits = P - k; - } - else { - *e = de - Bias - (P-1) + 1 + k; - *bits = 32*i - hi0bits(x[i-1]); - } - return b; - } + b = Balloc(1); + if (b == NULL) + return NULL; + x = b->x; + + z = d0 & Frac_mask; + d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ + if ((de = (int)(d0 >> Exp_shift))) + z |= Exp_msk1; + if ((y = d1)) { + if ((k = lo0bits(&y))) { + x[0] = y | z << (32 - k); + z >>= k; + } + else + x[0] = y; + i = + b->wds = (x[1] = z) ? 2 : 1; + } + else { + k = lo0bits(&z); + x[0] = z; + i = + b->wds = 1; + k += 32; + } + if (de) { + *e = de - Bias - (P-1) + k; + *bits = P - k; + } + else { + *e = de - Bias - (P-1) + 1 + k; + *bits = 32*i - hi0bits(x[i-1]); + } + return b; +} #undef d0 #undef d1 - static double +static double ratio - (Bigint *a, Bigint *b) +(Bigint *a, Bigint *b) { - U da, db; - int k, ka, kb; + U da, db; + int k, ka, kb; - dval(&da) = b2d(a, &ka); - dval(&db) = b2d(b, &kb); - k = ka - kb + 32*(a->wds - b->wds); - if (k > 0) - word0(&da) += k*Exp_msk1; - else { - k = -k; - word0(&db) += k*Exp_msk1; - } - return dval(&da) / dval(&db); - } + dval(&da) = b2d(a, &ka); + dval(&db) = b2d(b, &kb); + k = ka - kb + 32*(a->wds - b->wds); + if (k > 0) + word0(&da) += k*Exp_msk1; + else { + k = -k; + word0(&db) += k*Exp_msk1; + } + return dval(&da) / dval(&db); +} - static const double +static const double tens[] = { - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - 1e20, 1e21, 1e22 - }; + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22 +}; - static const double +static const double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, - 9007199254740992.*9007199254740992.e-256 - /* = 2^106 * 1e-256 */ - }; + 9007199254740992.*9007199254740992.e-256 + /* = 2^106 * 1e-256 */ +}; /* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ /* flag unnecessarily. It leads to a song and dance at the end of strtod. */ #define Scale_Bit 0x10 #define n_bigtens 5 - static int +static int match - (const char **sp, char *t) +(const char **sp, char *t) { - int c, d; - const char *s = *sp; + int c, d; + const char *s = *sp; - while((d = *t++)) { - if ((c = *++s) >= 'A' && c <= 'Z') - c += 'a' - 'A'; - if (c != d) - return 0; - } - *sp = s + 1; - return 1; - } + while((d = *t++)) { + if ((c = *++s) >= 'A' && c <= 'Z') + c += 'a' - 'A'; + if (c != d) + return 0; + } + *sp = s + 1; + return 1; +} #define ULbits 32 #define kshift 5 #define kmask 31 - static int +static int dshift(Bigint *b, int p2) { - int rv = hi0bits(b->x[b->wds-1]) - 4; - if (p2 > 0) - rv -= p2; - return rv & kmask; - } + int rv = hi0bits(b->x[b->wds-1]) - 4; + if (p2 > 0) + rv -= p2; + return rv & kmask; +} - static int +static int quorem - (Bigint *b, Bigint *S) +(Bigint *b, Bigint *S) { - int n; - ULong *bx, *bxe, q, *sx, *sxe; + int n; + ULong *bx, *bxe, q, *sx, *sxe; #ifdef ULLong - ULLong borrow, carry, y, ys; + ULLong borrow, carry, y, ys; #else - ULong borrow, carry, y, ys; - ULong si, z, zs; + ULong borrow, carry, y, ys; + ULong si, z, zs; #endif - n = S->wds; + n = S->wds; #ifdef DEBUG - /*debug*/ if (b->wds > n) - /*debug*/ Bug("oversize b in quorem"); + /*debug*/ if (b->wds > n) + /*debug*/ Bug("oversize b in quorem"); #endif - if (b->wds < n) - return 0; - sx = S->x; - sxe = sx + --n; - bx = b->x; - bxe = bx + n; - q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ + if (b->wds < n) + return 0; + sx = S->x; + sxe = sx + --n; + bx = b->x; + bxe = bx + n; + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ #ifdef DEBUG - /*debug*/ if (q > 9) - /*debug*/ Bug("oversized quotient in quorem"); + /*debug*/ if (q > 9) + /*debug*/ Bug("oversized quotient in quorem"); #endif - if (q) { - borrow = 0; - carry = 0; - do { + if (q) { + borrow = 0; + carry = 0; + do { #ifdef ULLong - ys = *sx++ * (ULLong)q + carry; - carry = ys >> 32; - y = *bx - (ys & FFFFFFFF) - borrow; - borrow = y >> 32 & (ULong)1; - *bx++ = y & FFFFFFFF; + ys = *sx++ * (ULLong)q + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = y & FFFFFFFF; #else - si = *sx++; - ys = (si & 0xffff) * q + carry; - zs = (si >> 16) * q + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*bx >> 16) - (zs & 0xffff) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(bx, z, y); -#endif - } - while(sx <= sxe); - if (!*bxe) { - bx = b->x; - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - if (cmp(b, S) >= 0) { - q++; - borrow = 0; - carry = 0; - bx = b->x; - sx = S->x; - do { + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#endif + } + while(sx <= sxe); + if (!*bxe) { + bx = b->x; + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + if (cmp(b, S) >= 0) { + q++; + borrow = 0; + carry = 0; + bx = b->x; + sx = S->x; + do { #ifdef ULLong - ys = *sx++ + carry; - carry = ys >> 32; - y = *bx - (ys & FFFFFFFF) - borrow; - borrow = y >> 32 & (ULong)1; - *bx++ = y & FFFFFFFF; + ys = *sx++ + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = y & FFFFFFFF; #else - si = *sx++; - ys = (si & 0xffff) + carry; - zs = (si >> 16) + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*bx >> 16) - (zs & 0xffff) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(bx, z, y); -#endif - } - while(sx <= sxe); - bx = b->x; - bxe = bx + n; - if (!*bxe) { - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - return q; - } + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#endif + } + while(sx <= sxe); + bx = b->x; + bxe = bx + n; + if (!*bxe) { + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + return q; +} /* return 0 on success, -1 on failure */ - static int +static int bigcomp - (U *rv, const char *s0, BCinfo *bc) +(U *rv, const char *s0, BCinfo *bc) { - Bigint *b, *d; - int b2, bbits, d2, dd, dig, dsign, i, j, nd, nd0, p2, p5, speccase; + Bigint *b, *d; + int b2, bbits, d2, dd, dig, dsign, i, j, nd, nd0, p2, p5, speccase; - dsign = bc->dsign; - nd = bc->nd; - nd0 = bc->nd0; - p5 = nd + bc->e0 - 1; - speccase = 0; - if (rv->d == 0.) { /* special case: value near underflow-to-zero */ - /* threshold was rounded to zero */ - b = i2b(1); - if (b == NULL) - return -1; - p2 = Emin - P + 1; - bbits = 1; - word0(rv) = (P+2) << Exp_shift; - i = 0; - { - speccase = 1; - --p2; - dsign = 0; - goto have_i; - } - } - else - { - b = d2b(rv, &p2, &bbits); - if (b == NULL) - return -1; - } - p2 -= bc->scale; - /* floor(log2(rv)) == bbits - 1 + p2 */ - /* Check for denormal case. */ - i = P - bbits; - if (i > (j = P - Emin - 1 + p2)) { - i = j; - } - { - b = lshift(b, ++i); - if (b == NULL) - return -1; - b->x[0] |= 1; - } - have_i: - p2 -= p5 + i; - d = i2b(1); - if (d == NULL) { - Bfree(b); - return -1; - } - /* Arrange for convenient computation of quotients: - * shift left if necessary so divisor has 4 leading 0 bits. - */ - if (p5 > 0) { - d = pow5mult(d, p5); - if (d == NULL) { - Bfree(b); - return -1; - } - } - else if (p5 < 0) { - b = pow5mult(b, -p5); - if (b == NULL) { - Bfree(d); - return -1; - } - } - if (p2 > 0) { - b2 = p2; - d2 = 0; - } - else { - b2 = 0; - d2 = -p2; - } - i = dshift(d, d2); - if ((b2 += i) > 0) { - b = lshift(b, b2); - if (b == NULL) { - Bfree(d); - return -1; - } - } - if ((d2 += i) > 0) { - d = lshift(d, d2); - if (d == NULL) { - Bfree(b); - return -1; - } - } - - /* Now b/d = exactly half-way between the two floating-point values */ - /* on either side of the input string. Compute first digit of b/d. */ - - if (!(dig = quorem(b,d))) { - b = multadd(b, 10, 0); /* very unlikely */ - if (b == NULL) { - Bfree(d); - return -1; - } - dig = quorem(b,d); - } - - /* Compare b/d with s0 */ - - assert(nd > 0); - dd = 9999; /* silence gcc compiler warning */ - for(i = 0; i < nd0; ) { - if ((dd = s0[i++] - '0' - dig)) - goto ret; - if (!b->x[0] && b->wds == 1) { - if (i < nd) - dd = 1; - goto ret; - } - b = multadd(b, 10, 0); - if (b == NULL) { - Bfree(d); - return -1; - } - dig = quorem(b,d); - } - for(j = bc->dp1; i++ < nd;) { - if ((dd = s0[j++] - '0' - dig)) - goto ret; - if (!b->x[0] && b->wds == 1) { - if (i < nd) - dd = 1; - goto ret; - } - b = multadd(b, 10, 0); - if (b == NULL) { - Bfree(d); - return -1; - } - dig = quorem(b,d); - } - if (b->x[0] || b->wds > 1) - dd = -1; - ret: - Bfree(b); - Bfree(d); - if (speccase) { - if (dd <= 0) - rv->d = 0.; - } - else if (dd < 0) { - if (!dsign) /* does not happen for round-near */ -retlow1: - dval(rv) -= ulp(rv); - } - else if (dd > 0) { - if (dsign) { - rethi1: - dval(rv) += ulp(rv); - } - } - else { - /* Exact half-way case: apply round-even rule. */ - if (word1(rv) & 1) { - if (dsign) - goto rethi1; - goto retlow1; - } - } + dsign = bc->dsign; + nd = bc->nd; + nd0 = bc->nd0; + p5 = nd + bc->e0 - 1; + speccase = 0; + if (rv->d == 0.) { /* special case: value near underflow-to-zero */ + /* threshold was rounded to zero */ + b = i2b(1); + if (b == NULL) + return -1; + p2 = Emin - P + 1; + bbits = 1; + word0(rv) = (P+2) << Exp_shift; + i = 0; + { + speccase = 1; + --p2; + dsign = 0; + goto have_i; + } + } + else + { + b = d2b(rv, &p2, &bbits); + if (b == NULL) + return -1; + } + p2 -= bc->scale; + /* floor(log2(rv)) == bbits - 1 + p2 */ + /* Check for denormal case. */ + i = P - bbits; + if (i > (j = P - Emin - 1 + p2)) { + i = j; + } + { + b = lshift(b, ++i); + if (b == NULL) + return -1; + b->x[0] |= 1; + } + have_i: + p2 -= p5 + i; + d = i2b(1); + if (d == NULL) { + Bfree(b); + return -1; + } + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + */ + if (p5 > 0) { + d = pow5mult(d, p5); + if (d == NULL) { + Bfree(b); + return -1; + } + } + else if (p5 < 0) { + b = pow5mult(b, -p5); + if (b == NULL) { + Bfree(d); + return -1; + } + } + if (p2 > 0) { + b2 = p2; + d2 = 0; + } + else { + b2 = 0; + d2 = -p2; + } + i = dshift(d, d2); + if ((b2 += i) > 0) { + b = lshift(b, b2); + if (b == NULL) { + Bfree(d); + return -1; + } + } + if ((d2 += i) > 0) { + d = lshift(d, d2); + if (d == NULL) { + Bfree(b); + return -1; + } + } + + /* Now b/d = exactly half-way between the two floating-point values */ + /* on either side of the input string. Compute first digit of b/d. */ + + if (!(dig = quorem(b,d))) { + b = multadd(b, 10, 0); /* very unlikely */ + if (b == NULL) { + Bfree(d); + return -1; + } + dig = quorem(b,d); + } + + /* Compare b/d with s0 */ + + assert(nd > 0); + dd = 9999; /* silence gcc compiler warning */ + for(i = 0; i < nd0; ) { + if ((dd = s0[i++] - '0' - dig)) + goto ret; + if (!b->x[0] && b->wds == 1) { + if (i < nd) + dd = 1; + goto ret; + } + b = multadd(b, 10, 0); + if (b == NULL) { + Bfree(d); + return -1; + } + dig = quorem(b,d); + } + for(j = bc->dp1; i++ < nd;) { + if ((dd = s0[j++] - '0' - dig)) + goto ret; + if (!b->x[0] && b->wds == 1) { + if (i < nd) + dd = 1; + goto ret; + } + b = multadd(b, 10, 0); + if (b == NULL) { + Bfree(d); + return -1; + } + dig = quorem(b,d); + } + if (b->x[0] || b->wds > 1) + dd = -1; + ret: + Bfree(b); + Bfree(d); + if (speccase) { + if (dd <= 0) + rv->d = 0.; + } + else if (dd < 0) { + if (!dsign) /* does not happen for round-near */ + retlow1: + dval(rv) -= ulp(rv); + } + else if (dd > 0) { + if (dsign) { + rethi1: + dval(rv) += ulp(rv); + } + } + else { + /* Exact half-way case: apply round-even rule. */ + if (word1(rv) & 1) { + if (dsign) + goto rethi1; + goto retlow1; + } + } - return 0; - } + return 0; +} - double +double _Py_dg_strtod - (const char *s00, char **se) +(const char *s00, char **se) { - int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1, error; - int esign, i, j, k, nd, nd0, nf, nz, nz0, sign; - const char *s, *s0, *s1; - double aadj, aadj1; - Long L; - U aadj2, adj, rv, rv0; - ULong y, z; - BCinfo bc; - Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; - - sign = nz0 = nz = bc.dplen = bc.uflchk = 0; - dval(&rv) = 0.; - for(s = s00;;s++) switch(*s) { - case '-': - sign = 1; - /* no break */ - case '+': - if (*++s) - goto break2; - /* no break */ - case 0: - goto ret0; - case '\t': - case '\n': - case '\v': - case '\f': - case '\r': - case ' ': - continue; - default: - goto break2; - } - break2: - if (*s == '0') { - nz0 = 1; - while(*++s == '0') ; - if (!*s) - goto ret; - } - s0 = s; - y = z = 0; - for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) - if (nd < 9) - y = 10*y + c - '0'; - else if (nd < 16) - z = 10*z + c - '0'; - nd0 = nd; - bc.dp0 = bc.dp1 = s - s0; - if (c == '.') { - c = *++s; - bc.dp1 = s - s0; - bc.dplen = bc.dp1 - bc.dp0; - if (!nd) { - for(; c == '0'; c = *++s) - nz++; - if (c > '0' && c <= '9') { - s0 = s; - nf += nz; - nz = 0; - goto have_dig; - } - goto dig_done; - } - for(; c >= '0' && c <= '9'; c = *++s) { - have_dig: - nz++; - if (c -= '0') { - nf += nz; - for(i = 1; i < nz; i++) - if (nd++ < 9) - y *= 10; - else if (nd <= DBL_DIG + 1) - z *= 10; - if (nd++ < 9) - y = 10*y + c; - else if (nd <= DBL_DIG + 1) - z = 10*z + c; - nz = 0; - } - } - } - dig_done: - if (!nd && !nz && !nz0 && (s != s0)) { - /* no digits, just a '.'. Fail. */ - goto ret0; - } - e = 0; - if (c == 'e' || c == 'E') { - if (!nd && !nz && !nz0) { - goto ret0; - } - s00 = s; - esign = 0; - switch(c = *++s) { - case '-': - esign = 1; - case '+': - c = *++s; - } - if (c >= '0' && c <= '9') { - while(c == '0') - c = *++s; - if (c > '0' && c <= '9') { - L = c - '0'; - s1 = s; - while((c = *++s) >= '0' && c <= '9') - L = 10*L + c - '0'; - if (s - s1 > 8 || L > 19999) - /* Avoid confusion from exponents - * so large that e might overflow. - */ - e = 19999; /* safe for 16 bit ints */ - else - e = (int)L; - if (esign) - e = -e; - } - else - e = 0; - } - else - s = s00; - } - if (!nd) { - if (!nz && !nz0) { - /* Check for Nan and Infinity */ - switch(c) { - case 'i': - case 'I': - if (match(&s,"nf")) { - --s; - if (!match(&s,"inity")) - ++s; - word0(&rv) = 0x7ff00000; - word1(&rv) = 0; - goto ret; - } - break; - case 'n': - case 'N': - if (match(&s, "an")) { - word0(&rv) = NAN_WORD0; - word1(&rv) = NAN_WORD1; - goto ret; - } - } - ret0: - s = s00; - sign = 0; - } - goto ret; - } - bc.e0 = e1 = e -= nf; - - /* Now we have nd0 digits, starting at s0, followed by a - * decimal point, followed by nd-nd0 digits. The number we're - * after is the integer represented by those digits times - * 10**e */ - - if (!nd0) - nd0 = nd; - k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - dval(&rv) = y; - if (k > 9) { - dval(&rv) = tens[k - 9] * dval(&rv) + z; - } - bd0 = 0; - if (nd <= DBL_DIG - && Flt_Rounds == 1 - ) { - if (!e) - goto ret; - if (e > 0) { - if (e <= Ten_pmax) { - dval(&rv) *= tens[e]; - goto ret; - } - i = DBL_DIG - nd; - if (e <= Ten_pmax + i) { - /* A fancier test would sometimes let us do - * this for larger i values. - */ - e -= i; - dval(&rv) *= tens[i]; - dval(&rv) *= tens[e]; - goto ret; - } - } - else if (e >= -Ten_pmax) { - dval(&rv) /= tens[-e]; - goto ret; - } - } - e1 += nd - k; - - bc.scale = 0; - - /* Get starting approximation = rv * 10**e1 */ - - if (e1 > 0) { - if ((i = e1 & 15)) - dval(&rv) *= tens[i]; - if (e1 &= ~15) { - if (e1 > DBL_MAX_10_EXP) { - ovfl: - errno = ERANGE; - /* Can't trust HUGE_VAL */ - word0(&rv) = Exp_mask; - word1(&rv) = 0; - goto ret; - } - e1 >>= 4; - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - dval(&rv) *= bigtens[j]; - /* The last multiplication could overflow. */ - word0(&rv) -= P*Exp_msk1; - dval(&rv) *= bigtens[j]; - if ((z = word0(&rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-P)) - goto ovfl; - if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { - /* set to largest number */ - /* (Can't trust DBL_MAX) */ - word0(&rv) = Big0; - word1(&rv) = Big1; - } - else - word0(&rv) += P*Exp_msk1; - } - } - else if (e1 < 0) { - e1 = -e1; - if ((i = e1 & 15)) - dval(&rv) /= tens[i]; - if (e1 >>= 4) { - if (e1 >= 1 << n_bigtens) - goto undfl; - if (e1 & Scale_Bit) - bc.scale = 2*P; - for(j = 0; e1 > 0; j++, e1 >>= 1) - if (e1 & 1) - dval(&rv) *= tinytens[j]; - if (bc.scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask) - >> Exp_shift)) > 0) { - /* scaled rv is denormal; clear j low bits */ - if (j >= 32) { - word1(&rv) = 0; - if (j >= 53) - word0(&rv) = (P+2)*Exp_msk1; - else - word0(&rv) &= 0xffffffff << (j-32); - } - else - word1(&rv) &= 0xffffffff << j; - } - if (!dval(&rv)) { - undfl: - dval(&rv) = 0.; - errno = ERANGE; - goto ret; - } - } - } - - /* Now the hard part -- adjusting rv to the correct value.*/ - - /* Put digits into bd: true value = bd * 10^e */ - - bc.nd = nd; - bc.nd0 = nd0; /* Only needed if nd > strtod_diglim, but done here */ - /* to silence an erroneous warning about bc.nd0 */ - /* possibly not being initialized. */ - if (nd > strtod_diglim) { - /* ASSERT(strtod_diglim >= 18); 18 == one more than the */ - /* minimum number of decimal digits to distinguish double values */ - /* in IEEE arithmetic. */ - i = j = 18; - if (i > nd0) - j += bc.dplen; - for(;;) { - if (--j <= bc.dp1 && j >= bc.dp0) - j = bc.dp0 - 1; - if (s0[j] != '0') - break; - --i; - } - e += nd - i; - nd = i; - if (nd0 > nd) - nd0 = nd; - if (nd < 9) { /* must recompute y */ - y = 0; - for(i = 0; i < nd0; ++i) - y = 10*y + s0[i] - '0'; - for(j = bc.dp1; i < nd; ++i) - y = 10*y + s0[j++] - '0'; - } - } - bd0 = s2b(s0, nd0, nd, y, bc.dplen); - if (bd0 == NULL) - goto failed_malloc; - - for(;;) { - bd = Balloc(bd0->k); - if (bd == NULL) { - Bfree(bd0); - goto failed_malloc; - } - Bcopy(bd, bd0); - bb = d2b(&rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ - if (bb == NULL) { - Bfree(bd); - Bfree(bd0); - goto failed_malloc; - } - bs = i2b(1); - if (bs == NULL) { - Bfree(bb); - Bfree(bd); - Bfree(bd0); - goto failed_malloc; - } - - if (e >= 0) { - bb2 = bb5 = 0; - bd2 = bd5 = e; - } - else { - bb2 = bb5 = -e; - bd2 = bd5 = 0; - } - if (bbe >= 0) - bb2 += bbe; - else - bd2 -= bbe; - bs2 = bb2; - j = bbe - bc.scale; - i = j + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j += P - Emin; - else - j = P + 1 - bbbits; - bb2 += j; - bd2 += j; - bd2 += bc.scale; - i = bb2 < bd2 ? bb2 : bd2; - if (i > bs2) - i = bs2; - if (i > 0) { - bb2 -= i; - bd2 -= i; - bs2 -= i; - } - if (bb5 > 0) { - bs = pow5mult(bs, bb5); - if (bs == NULL) { - Bfree(bb); - Bfree(bd); - Bfree(bd0); - goto failed_malloc; - } - bb1 = mult(bs, bb); - Bfree(bb); - bb = bb1; - if (bb == NULL) { - Bfree(bs); - Bfree(bd); - Bfree(bd0); - goto failed_malloc; - } - } - if (bb2 > 0) { - bb = lshift(bb, bb2); - if (bb == NULL) { - Bfree(bs); - Bfree(bd); - Bfree(bd0); - goto failed_malloc; - } - } - if (bd5 > 0) { - bd = pow5mult(bd, bd5); - if (bd == NULL) { - Bfree(bb); - Bfree(bs); - Bfree(bd0); - goto failed_malloc; - } - } - if (bd2 > 0) { - bd = lshift(bd, bd2); - if (bd == NULL) { - Bfree(bb); - Bfree(bs); - Bfree(bd0); - goto failed_malloc; - } - } - if (bs2 > 0) { - bs = lshift(bs, bs2); - if (bs == NULL) { - Bfree(bb); - Bfree(bd); - Bfree(bd0); - goto failed_malloc; - } - } - delta = diff(bb, bd); - if (delta == NULL) { - Bfree(bb); - Bfree(bs); - Bfree(bd); - Bfree(bd0); - goto failed_malloc; - } - bc.dsign = delta->sign; - delta->sign = 0; - i = cmp(delta, bs); - if (bc.nd > nd && i <= 0) { - if (bc.dsign) - break; /* Must use bigcomp(). */ - { - bc.nd = nd; - i = -1; /* Discarded digits make delta smaller. */ - } - } - - if (i < 0) { - /* Error is less than half an ulp -- check for - * special case of mantissa a power of two. - */ - if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask - || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1 - ) { - break; - } - if (!delta->x[0] && delta->wds <= 1) { - /* exact result */ - break; - } - delta = lshift(delta,Log2P); - if (delta == NULL) { - Bfree(bb); - Bfree(bs); - Bfree(bd); - Bfree(bd0); - goto failed_malloc; - } - if (cmp(delta, bs) > 0) - goto drop_down; - break; - } - if (i == 0) { - /* exactly half-way between */ - if (bc.dsign) { - if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 - && word1(&rv) == ( - (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) - ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : - 0xffffffff)) { - /*boundary case -- increment exponent*/ - word0(&rv) = (word0(&rv) & Exp_mask) - + Exp_msk1 - ; - word1(&rv) = 0; - bc.dsign = 0; - break; - } - } - else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { - drop_down: - /* boundary case -- decrement exponent */ - if (bc.scale) { - L = word0(&rv) & Exp_mask; - if (L <= (2*P+1)*Exp_msk1) { - if (L > (P+2)*Exp_msk1) - /* round even ==> */ - /* accept rv */ - break; - /* rv = smallest denormal */ - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } - goto undfl; - } - } - L = (word0(&rv) & Exp_mask) - Exp_msk1; - word0(&rv) = L | Bndry_mask1; - word1(&rv) = 0xffffffff; - break; - } - if (!(word1(&rv) & LSB)) - break; - if (bc.dsign) - dval(&rv) += ulp(&rv); - else { - dval(&rv) -= ulp(&rv); - if (!dval(&rv)) { - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } - goto undfl; - } - } - bc.dsign = 1 - bc.dsign; - break; - } - if ((aadj = ratio(delta, bs)) <= 2.) { - if (bc.dsign) - aadj = aadj1 = 1.; - else if (word1(&rv) || word0(&rv) & Bndry_mask) { - if (word1(&rv) == Tiny1 && !word0(&rv)) { - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } - goto undfl; - } - aadj = 1.; - aadj1 = -1.; - } - else { - /* special case -- power of FLT_RADIX to be */ - /* rounded down... */ - - if (aadj < 2./FLT_RADIX) - aadj = 1./FLT_RADIX; - else - aadj *= 0.5; - aadj1 = -aadj; - } - } - else { - aadj *= 0.5; - aadj1 = bc.dsign ? aadj : -aadj; + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1, error; + int esign, i, j, k, nd, nd0, nf, nz, nz0, sign; + const char *s, *s0, *s1; + double aadj, aadj1; + Long L; + U aadj2, adj, rv, rv0; + ULong y, z; + BCinfo bc; + Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; + + sign = nz0 = nz = bc.dplen = bc.uflchk = 0; + dval(&rv) = 0.; + for(s = s00;;s++) switch(*s) { + case '-': + sign = 1; + /* no break */ + case '+': + if (*++s) + goto break2; + /* no break */ + case 0: + goto ret0; + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + continue; + default: + goto break2; + } + break2: + if (*s == '0') { + nz0 = 1; + while(*++s == '0') ; + if (!*s) + goto ret; + } + s0 = s; + y = z = 0; + for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) + y = 10*y + c - '0'; + else if (nd < 16) + z = 10*z + c - '0'; + nd0 = nd; + bc.dp0 = bc.dp1 = s - s0; + if (c == '.') { + c = *++s; + bc.dp1 = s - s0; + bc.dplen = bc.dp1 - bc.dp0; + if (!nd) { + for(; c == '0'; c = *++s) + nz++; + if (c > '0' && c <= '9') { + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for(; c >= '0' && c <= '9'; c = *++s) { + have_dig: + nz++; + if (c -= '0') { + nf += nz; + for(i = 1; i < nz; i++) + if (nd++ < 9) + y *= 10; + else if (nd <= DBL_DIG + 1) + z *= 10; + if (nd++ < 9) + y = 10*y + c; + else if (nd <= DBL_DIG + 1) + z = 10*z + c; + nz = 0; + } + } + } + dig_done: + if (!nd && !nz && !nz0 && (s != s0)) { + /* no digits, just a '.'. Fail. */ + goto ret0; + } + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + goto ret0; + } + s00 = s; + esign = 0; + switch(c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while(c == '0') + c = *++s; + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while((c = *++s) >= '0' && c <= '9') + L = 10*L + c - '0'; + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + e = 19999; /* safe for 16 bit ints */ + else + e = (int)L; + if (esign) + e = -e; + } + else + e = 0; + } + else + s = s00; + } + if (!nd) { + if (!nz && !nz0) { + /* Check for Nan and Infinity */ + switch(c) { + case 'i': + case 'I': + if (match(&s,"nf")) { + --s; + if (!match(&s,"inity")) + ++s; + word0(&rv) = 0x7ff00000; + word1(&rv) = 0; + goto ret; + } + break; + case 'n': + case 'N': + if (match(&s, "an")) { + word0(&rv) = NAN_WORD0; + word1(&rv) = NAN_WORD1; + goto ret; + } + } + ret0: + s = s00; + sign = 0; + } + goto ret; + } + bc.e0 = e1 = e -= nf; + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) + nd0 = nd; + k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; + dval(&rv) = y; + if (k > 9) { + dval(&rv) = tens[k - 9] * dval(&rv) + z; + } + bd0 = 0; + if (nd <= DBL_DIG + && Flt_Rounds == 1 + ) { + if (!e) + goto ret; + if (e > 0) { + if (e <= Ten_pmax) { + dval(&rv) *= tens[e]; + goto ret; + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ + e -= i; + dval(&rv) *= tens[i]; + dval(&rv) *= tens[e]; + goto ret; + } + } + else if (e >= -Ten_pmax) { + dval(&rv) /= tens[-e]; + goto ret; + } + } + e1 += nd - k; + + bc.scale = 0; + + /* Get starting approximation = rv * 10**e1 */ + + if (e1 > 0) { + if ((i = e1 & 15)) + dval(&rv) *= tens[i]; + if (e1 &= ~15) { + if (e1 > DBL_MAX_10_EXP) { + ovfl: + errno = ERANGE; + /* Can't trust HUGE_VAL */ + word0(&rv) = Exp_mask; + word1(&rv) = 0; + goto ret; + } + e1 >>= 4; + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(&rv) *= bigtens[j]; + /* The last multiplication could overflow. */ + word0(&rv) -= P*Exp_msk1; + dval(&rv) *= bigtens[j]; + if ((z = word0(&rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-P)) + goto ovfl; + if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { + /* set to largest number */ + /* (Can't trust DBL_MAX) */ + word0(&rv) = Big0; + word1(&rv) = Big1; + } + else + word0(&rv) += P*Exp_msk1; + } + } + else if (e1 < 0) { + e1 = -e1; + if ((i = e1 & 15)) + dval(&rv) /= tens[i]; + if (e1 >>= 4) { + if (e1 >= 1 << n_bigtens) + goto undfl; + if (e1 & Scale_Bit) + bc.scale = 2*P; + for(j = 0; e1 > 0; j++, e1 >>= 1) + if (e1 & 1) + dval(&rv) *= tinytens[j]; + if (bc.scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask) + >> Exp_shift)) > 0) { + /* scaled rv is denormal; clear j low bits */ + if (j >= 32) { + word1(&rv) = 0; + if (j >= 53) + word0(&rv) = (P+2)*Exp_msk1; + else + word0(&rv) &= 0xffffffff << (j-32); + } + else + word1(&rv) &= 0xffffffff << j; + } + if (!dval(&rv)) { + undfl: + dval(&rv) = 0.; + errno = ERANGE; + goto ret; + } + } + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + + bc.nd = nd; + bc.nd0 = nd0; /* Only needed if nd > strtod_diglim, but done here */ + /* to silence an erroneous warning about bc.nd0 */ + /* possibly not being initialized. */ + if (nd > strtod_diglim) { + /* ASSERT(strtod_diglim >= 18); 18 == one more than the */ + /* minimum number of decimal digits to distinguish double values */ + /* in IEEE arithmetic. */ + i = j = 18; + if (i > nd0) + j += bc.dplen; + for(;;) { + if (--j <= bc.dp1 && j >= bc.dp0) + j = bc.dp0 - 1; + if (s0[j] != '0') + break; + --i; + } + e += nd - i; + nd = i; + if (nd0 > nd) + nd0 = nd; + if (nd < 9) { /* must recompute y */ + y = 0; + for(i = 0; i < nd0; ++i) + y = 10*y + s0[i] - '0'; + for(j = bc.dp1; i < nd; ++i) + y = 10*y + s0[j++] - '0'; + } + } + bd0 = s2b(s0, nd0, nd, y, bc.dplen); + if (bd0 == NULL) + goto failed_malloc; + + for(;;) { + bd = Balloc(bd0->k); + if (bd == NULL) { + Bfree(bd0); + goto failed_malloc; + } + Bcopy(bd, bd0); + bb = d2b(&rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ + if (bb == NULL) { + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } + bs = i2b(1); + if (bs == NULL) { + Bfree(bb); + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; + j = bbe - bc.scale; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j += P - Emin; + else + j = P + 1 - bbbits; + bb2 += j; + bd2 += j; + bd2 += bc.scale; + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + if (bs == NULL) { + Bfree(bb); + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } + bb1 = mult(bs, bb); + Bfree(bb); + bb = bb1; + if (bb == NULL) { + Bfree(bs); + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } + } + if (bb2 > 0) { + bb = lshift(bb, bb2); + if (bb == NULL) { + Bfree(bs); + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } + } + if (bd5 > 0) { + bd = pow5mult(bd, bd5); + if (bd == NULL) { + Bfree(bb); + Bfree(bs); + Bfree(bd0); + goto failed_malloc; + } + } + if (bd2 > 0) { + bd = lshift(bd, bd2); + if (bd == NULL) { + Bfree(bb); + Bfree(bs); + Bfree(bd0); + goto failed_malloc; + } + } + if (bs2 > 0) { + bs = lshift(bs, bs2); + if (bs == NULL) { + Bfree(bb); + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } + } + delta = diff(bb, bd); + if (delta == NULL) { + Bfree(bb); + Bfree(bs); + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } + bc.dsign = delta->sign; + delta->sign = 0; + i = cmp(delta, bs); + if (bc.nd > nd && i <= 0) { + if (bc.dsign) + break; /* Must use bigcomp(). */ + { + bc.nd = nd; + i = -1; /* Discarded digits make delta smaller. */ + } + } + + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask + || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1 + ) { + break; + } + if (!delta->x[0] && delta->wds <= 1) { + /* exact result */ + break; + } + delta = lshift(delta,Log2P); + if (delta == NULL) { + Bfree(bb); + Bfree(bs); + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } + if (cmp(delta, bs) > 0) + goto drop_down; + break; + } + if (i == 0) { + /* exactly half-way between */ + if (bc.dsign) { + if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 + && word1(&rv) == ( + (bc.scale && + (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) ? + (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : + 0xffffffff)) { + /*boundary case -- increment exponent*/ + word0(&rv) = (word0(&rv) & Exp_mask) + + Exp_msk1 + ; + word1(&rv) = 0; + bc.dsign = 0; + break; + } + } + else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { + drop_down: + /* boundary case -- decrement exponent */ + if (bc.scale) { + L = word0(&rv) & Exp_mask; + if (L <= (2*P+1)*Exp_msk1) { + if (L > (P+2)*Exp_msk1) + /* round even ==> */ + /* accept rv */ + break; + /* rv = smallest denormal */ + if (bc.nd >nd) { + bc.uflchk = 1; + break; + } + goto undfl; + } + } + L = (word0(&rv) & Exp_mask) - Exp_msk1; + word0(&rv) = L | Bndry_mask1; + word1(&rv) = 0xffffffff; + break; + } + if (!(word1(&rv) & LSB)) + break; + if (bc.dsign) + dval(&rv) += ulp(&rv); + else { + dval(&rv) -= ulp(&rv); + if (!dval(&rv)) { + if (bc.nd >nd) { + bc.uflchk = 1; + break; + } + goto undfl; + } + } + bc.dsign = 1 - bc.dsign; + break; + } + if ((aadj = ratio(delta, bs)) <= 2.) { + if (bc.dsign) + aadj = aadj1 = 1.; + else if (word1(&rv) || word0(&rv) & Bndry_mask) { + if (word1(&rv) == Tiny1 && !word0(&rv)) { + if (bc.nd >nd) { + bc.uflchk = 1; + break; + } + goto undfl; + } + aadj = 1.; + aadj1 = -1.; + } + else { + /* special case -- power of FLT_RADIX to be */ + /* rounded down... */ + + if (aadj < 2./FLT_RADIX) + aadj = 1./FLT_RADIX; + else + aadj *= 0.5; + aadj1 = -aadj; + } + } + else { + aadj *= 0.5; + aadj1 = bc.dsign ? aadj : -aadj; #ifdef Check_FLT_ROUNDS - switch(bc.rounding) { - case 2: /* towards +infinity */ - aadj1 -= 0.5; - break; - case 0: /* towards 0 */ - case 3: /* towards -infinity */ - aadj1 += 0.5; - } + switch(bc.rounding) { + case 2: /* towards +infinity */ + aadj1 -= 0.5; + break; + case 0: /* towards 0 */ + case 3: /* towards -infinity */ + aadj1 += 0.5; + } #else - if (Flt_Rounds == 0) - aadj1 += 0.5; + if (Flt_Rounds == 0) + aadj1 += 0.5; #endif /*Check_FLT_ROUNDS*/ - } - y = word0(&rv) & Exp_mask; + } + y = word0(&rv) & Exp_mask; - /* Check for overflow */ + /* Check for overflow */ - if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { - dval(&rv0) = dval(&rv); - word0(&rv) -= P*Exp_msk1; - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; - if ((word0(&rv) & Exp_mask) >= - Exp_msk1*(DBL_MAX_EXP+Bias-P)) { - if (word0(&rv0) == Big0 && word1(&rv0) == Big1) - goto ovfl; - word0(&rv) = Big0; - word1(&rv) = Big1; - goto cont; - } - else - word0(&rv) += P*Exp_msk1; - } - else { - if (bc.scale && y <= 2*P*Exp_msk1) { - if (aadj <= 0x7fffffff) { - if ((z = aadj) <= 0) - z = 1; - aadj = z; - aadj1 = bc.dsign ? aadj : -aadj; - } - dval(&aadj2) = aadj1; - word0(&aadj2) += (2*P+1)*Exp_msk1 - y; - aadj1 = dval(&aadj2); - } - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; - } - z = word0(&rv) & Exp_mask; - if (bc.nd == nd) { - if (!bc.scale) - if (y == z) { - /* Can we stop now? */ - L = (Long)aadj; - aadj -= L; - /* The tolerances below are conservative. */ - if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask) { - if (aadj < .4999999 || aadj > .5000001) - break; - } - else if (aadj < .4999999/FLT_RADIX) - break; - } - } - cont: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(delta); - } - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(bd0); - Bfree(delta); - if (bc.nd > nd) { - error = bigcomp(&rv, s0, &bc); - if (error) - goto failed_malloc; - } - - if (bc.scale) { - word0(&rv0) = Exp_1 - 2*P*Exp_msk1; - word1(&rv0) = 0; - dval(&rv) *= dval(&rv0); - /* try to avoid the bug of testing an 8087 register value */ - if (!(word0(&rv) & Exp_mask)) - errno = ERANGE; - } - ret: - if (se) - *se = (char *)s; - return sign ? -dval(&rv) : dval(&rv); - - failed_malloc: - if (se) - *se = (char *)s00; - errno = ENOMEM; - return -1.0; - } + if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { + dval(&rv0) = dval(&rv); + word0(&rv) -= P*Exp_msk1; + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; + if ((word0(&rv) & Exp_mask) >= + Exp_msk1*(DBL_MAX_EXP+Bias-P)) { + if (word0(&rv0) == Big0 && word1(&rv0) == Big1) + goto ovfl; + word0(&rv) = Big0; + word1(&rv) = Big1; + goto cont; + } + else + word0(&rv) += P*Exp_msk1; + } + else { + if (bc.scale && y <= 2*P*Exp_msk1) { + if (aadj <= 0x7fffffff) { + if ((z = aadj) <= 0) + z = 1; + aadj = z; + aadj1 = bc.dsign ? aadj : -aadj; + } + dval(&aadj2) = aadj1; + word0(&aadj2) += (2*P+1)*Exp_msk1 - y; + aadj1 = dval(&aadj2); + } + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; + } + z = word0(&rv) & Exp_mask; + if (bc.nd == nd) { + if (!bc.scale) + if (y == z) { + /* Can we stop now? */ + L = (Long)aadj; + aadj -= L; + /* The tolerances below are conservative. */ + if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask) { + if (aadj < .4999999 || aadj > .5000001) + break; + } + else if (aadj < .4999999/FLT_RADIX) + break; + } + } + cont: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(delta); + } + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); + if (bc.nd > nd) { + error = bigcomp(&rv, s0, &bc); + if (error) + goto failed_malloc; + } + + if (bc.scale) { + word0(&rv0) = Exp_1 - 2*P*Exp_msk1; + word1(&rv0) = 0; + dval(&rv) *= dval(&rv0); + /* try to avoid the bug of testing an 8087 register value */ + if (!(word0(&rv) & Exp_mask)) + errno = ERANGE; + } + ret: + if (se) + *se = (char *)s; + return sign ? -dval(&rv) : dval(&rv); + + failed_malloc: + if (se) + *se = (char *)s00; + errno = ENOMEM; + return -1.0; +} - static char * +static char * rv_alloc(int i) { - int j, k, *r; + int j, k, *r; - j = sizeof(ULong); - for(k = 0; - sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i; - j <<= 1) - k++; - r = (int*)Balloc(k); - if (r == NULL) - return NULL; - *r = k; - return (char *)(r+1); - } + j = sizeof(ULong); + for(k = 0; + sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i; + j <<= 1) + k++; + r = (int*)Balloc(k); + if (r == NULL) + return NULL; + *r = k; + return (char *)(r+1); +} - static char * +static char * nrv_alloc(char *s, char **rve, int n) { - char *rv, *t; + char *rv, *t; - rv = rv_alloc(n); - if (rv == NULL) - return NULL; - t = rv; - while((*t = *s++)) t++; - if (rve) - *rve = t; - return rv; - } + rv = rv_alloc(n); + if (rv == NULL) + return NULL; + t = rv; + while((*t = *s++)) t++; + if (rve) + *rve = t; + return rv; +} /* freedtoa(s) must be used to free values s returned by dtoa * when MULTIPLE_THREADS is #defined. It should be used in all cases, @@ -1910,13 +1918,13 @@ * when MULTIPLE_THREADS is not defined. */ - void +void _Py_dg_freedtoa(char *s) { - Bigint *b = (Bigint *)((int *)s - 1); - b->maxwds = 1 << (b->k = *(int*)b); - Bfree(b); - } + Bigint *b = (Bigint *)((int *)s - 1); + b->maxwds = 1 << (b->k = *(int*)b); + Bfree(b); +} /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. * @@ -1924,649 +1932,650 @@ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. * * Modifications: - * 1. Rather than iterating, we use a simple numeric overestimate - * to determine k = floor(log10(d)). We scale relevant - * quantities using O(log2(k)) rather than O(k) multiplications. - * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't - * try to generate digits strictly left to right. Instead, we - * compute with fewer bits and propagate the carry if necessary - * when rounding the final digit up. This is often faster. - * 3. Under the assumption that input will be rounded nearest, - * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. - * That is, we allow equality in stopping tests when the - * round-nearest rule will give the same floating-point value - * as would satisfaction of the stopping test with strict - * inequality. - * 4. We remove common factors of powers of 2 from relevant - * quantities. - * 5. When converting floating-point integers less than 1e16, - * we use floating-point arithmetic rather than resorting - * to multiple-precision integers. - * 6. When asked to produce fewer than 15 digits, we first try - * to get by with floating-point arithmetic; we resort to - * multiple-precision integer arithmetic only if we cannot - * guarantee that the floating-point calculation has given - * the correctly rounded result. For k requested digits and - * "uniformly" distributed input, the probability is - * something like 10^(k-15) that we must resort to the Long - * calculation. + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. */ /* Additional notes (METD): (1) returns NULL on failure. (2) to avoid memory leakage, a successful call to _Py_dg_dtoa should always be matched by a call to _Py_dg_freedtoa. */ - char * +char * _Py_dg_dtoa - (double dd, int mode, int ndigits, int *decpt, int *sign, char **rve) +(double dd, int mode, int ndigits, int *decpt, int *sign, char **rve) { - /* Arguments ndigits, decpt, sign are similar to those - of ecvt and fcvt; trailing zeros are suppressed from - the returned string. If not null, *rve is set to point - to the end of the return value. If d is +-Infinity or NaN, - then *decpt is set to 9999. - - mode: - 0 ==> shortest string that yields d when read in - and rounded to nearest. - 1 ==> like 0, but with Steele & White stopping rule; - e.g. with IEEE P754 arithmetic , mode 0 gives - 1e23 whereas mode 1 gives 9.999999999999999e22. - 2 ==> max(1,ndigits) significant digits. This gives a - return value similar to that of ecvt, except - that trailing zeros are suppressed. - 3 ==> through ndigits past the decimal point. This - gives a return value similar to that from fcvt, - except that trailing zeros are suppressed, and - ndigits can be negative. - 4,5 ==> similar to 2 and 3, respectively, but (in - round-nearest mode) with the tests of mode 0 to - possibly return a shorter string that rounds to d. - With IEEE arithmetic and compilation with - -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same - as modes 2 and 3 when FLT_ROUNDS != 1. - 6-9 ==> Debugging modes similar to mode - 4: don't try - fast floating-point estimate (if applicable). - - Values of mode other than 0-9 are treated as mode 0. - - Sufficient space is allocated to the return value - to hold the suppressed trailing zeros. - */ - - int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, - j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, - spec_case, try_quick; - Long L; - int denorm; - ULong x; - Bigint *b, *b1, *delta, *mlo, *mhi, *S; - U d2, eps, u; - double ds; - char *s, *s0; - - /* set pointers to NULL, to silence gcc compiler warnings and make - cleanup easier on error */ - mlo = mhi = b = S = 0; - s0 = 0; - - u.d = dd; - if (word0(&u) & Sign_bit) { - /* set sign for everything, including 0's and NaNs */ - *sign = 1; - word0(&u) &= ~Sign_bit; /* clear sign bit */ - } - else - *sign = 0; - - if ((word0(&u) & Exp_mask) == Exp_mask) - { - /* Infinity or NaN */ - *decpt = 9999; - if (!word1(&u) && !(word0(&u) & 0xfffff)) - return nrv_alloc("Infinity", rve, 8); - return nrv_alloc("NaN", rve, 3); - } - if (!dval(&u)) { - *decpt = 1; - return nrv_alloc("0", rve, 1); - } - - - b = d2b(&u, &be, &bbits); - if (b == NULL) - goto failed_malloc; - if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) { - dval(&d2) = dval(&u); - word0(&d2) &= Frac_mask1; - word0(&d2) |= Exp_11; - - /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 - * log10(x) = log(x) / log(10) - * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) - * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) - * - * This suggests computing an approximation k to log10(d) by - * - * k = (i - Bias)*0.301029995663981 - * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); - * - * We want k to be too large rather than too small. - * The error in the first-order Taylor series approximation - * is in our favor, so we just round up the constant enough - * to compensate for any error in the multiplication of - * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, - * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, - * adding 1e-13 to the constant term more than suffices. - * Hence we adjust the constant term to 0.1760912590558. - * (We could get a more accurate k by invoking log10, - * but this is probably not worthwhile.) - */ - - i -= Bias; - denorm = 0; - } - else { - /* d is denormalized */ - - i = bbits + be + (Bias + (P-1) - 1); - x = i > 32 ? word0(&u) << (64 - i) | word1(&u) >> (i - 32) - : word1(&u) << (32 - i); - dval(&d2) = x; - word0(&d2) -= 31*Exp_msk1; /* adjust exponent */ - i -= (Bias + (P-1) - 1) + 1; - denorm = 1; - } - ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; - k = (int)ds; - if (ds < 0. && ds != k) - k--; /* want k = floor(ds) */ - k_check = 1; - if (k >= 0 && k <= Ten_pmax) { - if (dval(&u) < tens[k]) - k--; - k_check = 0; - } - j = bbits - i - 1; - if (j >= 0) { - b2 = 0; - s2 = j; - } - else { - b2 = -j; - s2 = 0; - } - if (k >= 0) { - b5 = 0; - s5 = k; - s2 += k; - } - else { - b2 -= k; - b5 = -k; - s5 = 0; - } - if (mode < 0 || mode > 9) - mode = 0; + /* Arguments ndigits, decpt, sign are similar to those + of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to 9999. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4,5 ==> similar to 2 and 3, respectively, but (in + round-nearest mode) with the tests of mode 0 to + possibly return a shorter string that rounds to d. + With IEEE arithmetic and compilation with + -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same + as modes 2 and 3 when FLT_ROUNDS != 1. + 6-9 ==> Debugging modes similar to mode - 4: don't try + fast floating-point estimate (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, + j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, + spec_case, try_quick; + Long L; + int denorm; + ULong x; + Bigint *b, *b1, *delta, *mlo, *mhi, *S; + U d2, eps, u; + double ds; + char *s, *s0; + + /* set pointers to NULL, to silence gcc compiler warnings and make + cleanup easier on error */ + mlo = mhi = b = S = 0; + s0 = 0; + + u.d = dd; + if (word0(&u) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + word0(&u) &= ~Sign_bit; /* clear sign bit */ + } + else + *sign = 0; + + if ((word0(&u) & Exp_mask) == Exp_mask) + { + /* Infinity or NaN */ + *decpt = 9999; + if (!word1(&u) && !(word0(&u) & 0xfffff)) + return nrv_alloc("Infinity", rve, 8); + return nrv_alloc("NaN", rve, 3); + } + if (!dval(&u)) { + *decpt = 1; + return nrv_alloc("0", rve, 1); + } + + + b = d2b(&u, &be, &bbits); + if (b == NULL) + goto failed_malloc; + if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) { + dval(&d2) = dval(&u); + word0(&d2) &= Frac_mask1; + word0(&d2) |= Exp_11; + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ + + i -= Bias; + denorm = 0; + } + else { + /* d is denormalized */ + + i = bbits + be + (Bias + (P-1) - 1); + x = i > 32 ? word0(&u) << (64 - i) | word1(&u) >> (i - 32) + : word1(&u) << (32 - i); + dval(&d2) = x; + word0(&d2) -= 31*Exp_msk1; /* adjust exponent */ + i -= (Bias + (P-1) - 1) + 1; + denorm = 1; + } + ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + + i*0.301029995663981; + k = (int)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; + if (k >= 0 && k <= Ten_pmax) { + if (dval(&u) < tens[k]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } + if (mode < 0 || mode > 9) + mode = 0; #ifdef Check_FLT_ROUNDS - try_quick = Rounding == 1; + try_quick = Rounding == 1; #else - try_quick = 1; + try_quick = 1; #endif - if (mode > 5) { - mode -= 4; - try_quick = 0; - } - leftright = 1; - ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ - /* silence erroneous "gcc -Wall" warning. */ - switch(mode) { - case 0: - case 1: - i = 18; - ndigits = 0; - break; - case 2: - leftright = 0; - /* no break */ - case 4: - if (ndigits <= 0) - ndigits = 1; - ilim = ilim1 = i = ndigits; - break; - case 3: - leftright = 0; - /* no break */ - case 5: - i = ndigits + k + 1; - ilim = i; - ilim1 = i - 1; - if (i <= 0) - i = 1; - } - s0 = rv_alloc(i); - if (s0 == NULL) - goto failed_malloc; - s = s0; - - - if (ilim >= 0 && ilim <= Quick_max && try_quick) { - - /* Try to get by with floating-point arithmetic. */ - - i = 0; - dval(&d2) = dval(&u); - k0 = k; - ilim0 = ilim; - ieps = 2; /* conservative */ - if (k > 0) { - ds = tens[k&0xf]; - j = k >> 4; - if (j & Bletch) { - /* prevent overflows */ - j &= Bletch - 1; - dval(&u) /= bigtens[n_bigtens-1]; - ieps++; - } - for(; j; j >>= 1, i++) - if (j & 1) { - ieps++; - ds *= bigtens[i]; - } - dval(&u) /= ds; - } - else if ((j1 = -k)) { - dval(&u) *= tens[j1 & 0xf]; - for(j = j1 >> 4; j; j >>= 1, i++) - if (j & 1) { - ieps++; - dval(&u) *= bigtens[i]; - } - } - if (k_check && dval(&u) < 1. && ilim > 0) { - if (ilim1 <= 0) - goto fast_failed; - ilim = ilim1; - k--; - dval(&u) *= 10.; - ieps++; - } - dval(&eps) = ieps*dval(&u) + 7.; - word0(&eps) -= (P-1)*Exp_msk1; - if (ilim == 0) { - S = mhi = 0; - dval(&u) -= 5.; - if (dval(&u) > dval(&eps)) - goto one_digit; - if (dval(&u) < -dval(&eps)) - goto no_digits; - goto fast_failed; - } - if (leftright) { - /* Use Steele & White method of only - * generating digits needed. - */ - dval(&eps) = 0.5/tens[ilim-1] - dval(&eps); - for(i = 0;;) { - L = dval(&u); - dval(&u) -= L; - *s++ = '0' + (int)L; - if (dval(&u) < dval(&eps)) - goto ret1; - if (1. - dval(&u) < dval(&eps)) - goto bump_up; - if (++i >= ilim) - break; - dval(&eps) *= 10.; - dval(&u) *= 10.; - } - } - else { - /* Generate ilim digits, then fix them up. */ - dval(&eps) *= tens[ilim-1]; - for(i = 1;; i++, dval(&u) *= 10.) { - L = (Long)(dval(&u)); - if (!(dval(&u) -= L)) - ilim = i; - *s++ = '0' + (int)L; - if (i == ilim) { - if (dval(&u) > 0.5 + dval(&eps)) - goto bump_up; - else if (dval(&u) < 0.5 - dval(&eps)) { - while(*--s == '0'); - s++; - goto ret1; - } - break; - } - } - } - fast_failed: - s = s0; - dval(&u) = dval(&d2); - k = k0; - ilim = ilim0; - } - - /* Do we have a "small" integer? */ - - if (be >= 0 && k <= Int_max) { - /* Yes. */ - ds = tens[k]; - if (ndigits < 0 && ilim <= 0) { - S = mhi = 0; - if (ilim < 0 || dval(&u) <= 5*ds) - goto no_digits; - goto one_digit; - } - for(i = 1;; i++, dval(&u) *= 10.) { - L = (Long)(dval(&u) / ds); - dval(&u) -= L*ds; + if (mode > 5) { + mode -= 4; + try_quick = 0; + } + leftright = 1; + ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ + /* silence erroneous "gcc -Wall" warning. */ + switch(mode) { + case 0: + case 1: + i = 18; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + s0 = rv_alloc(i); + if (s0 == NULL) + goto failed_malloc; + s = s0; + + + if (ilim >= 0 && ilim <= Quick_max && try_quick) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + dval(&d2) = dval(&u); + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + dval(&u) /= bigtens[n_bigtens-1]; + ieps++; + } + for(; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + dval(&u) /= ds; + } + else if ((j1 = -k)) { + dval(&u) *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + dval(&u) *= bigtens[i]; + } + } + if (k_check && dval(&u) < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + dval(&u) *= 10.; + ieps++; + } + dval(&eps) = ieps*dval(&u) + 7.; + word0(&eps) -= (P-1)*Exp_msk1; + if (ilim == 0) { + S = mhi = 0; + dval(&u) -= 5.; + if (dval(&u) > dval(&eps)) + goto one_digit; + if (dval(&u) < -dval(&eps)) + goto no_digits; + goto fast_failed; + } + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + dval(&eps) = 0.5/tens[ilim-1] - dval(&eps); + for(i = 0;;) { + L = dval(&u); + dval(&u) -= L; + *s++ = '0' + (int)L; + if (dval(&u) < dval(&eps)) + goto ret1; + if (1. - dval(&u) < dval(&eps)) + goto bump_up; + if (++i >= ilim) + break; + dval(&eps) *= 10.; + dval(&u) *= 10.; + } + } + else { + /* Generate ilim digits, then fix them up. */ + dval(&eps) *= tens[ilim-1]; + for(i = 1;; i++, dval(&u) *= 10.) { + L = (Long)(dval(&u)); + if (!(dval(&u) -= L)) + ilim = i; + *s++ = '0' + (int)L; + if (i == ilim) { + if (dval(&u) > 0.5 + dval(&eps)) + goto bump_up; + else if (dval(&u) < 0.5 - dval(&eps)) { + while(*--s == '0'); + s++; + goto ret1; + } + break; + } + } + } + fast_failed: + s = s0; + dval(&u) = dval(&d2); + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || dval(&u) <= 5*ds) + goto no_digits; + goto one_digit; + } + for(i = 1;; i++, dval(&u) *= 10.) { + L = (Long)(dval(&u) / ds); + dval(&u) -= L*ds; #ifdef Check_FLT_ROUNDS - /* If FLT_ROUNDS == 2, L will usually be high by 1 */ - if (dval(&u) < 0) { - L--; - dval(&u) += ds; - } -#endif - *s++ = '0' + (int)L; - if (!dval(&u)) { - break; - } - if (i == ilim) { - dval(&u) += dval(&u); - if (dval(&u) > ds || (dval(&u) == ds && L & 1)) { - bump_up: - while(*--s == '9') - if (s == s0) { - k++; - *s = '0'; - break; - } - ++*s++; - } - break; - } - } - goto ret1; - } - - m2 = b2; - m5 = b5; - if (leftright) { - i = - denorm ? be + (Bias + (P-1) - 1 + 1) : - 1 + P - bbits; - b2 += i; - s2 += i; - mhi = i2b(1); - if (mhi == NULL) - goto failed_malloc; - } - if (m2 > 0 && s2 > 0) { - i = m2 < s2 ? m2 : s2; - b2 -= i; - m2 -= i; - s2 -= i; - } - if (b5 > 0) { - if (leftright) { - if (m5 > 0) { - mhi = pow5mult(mhi, m5); - if (mhi == NULL) - goto failed_malloc; - b1 = mult(mhi, b); - Bfree(b); - b = b1; - if (b == NULL) - goto failed_malloc; - } - if ((j = b5 - m5)) { - b = pow5mult(b, j); - if (b == NULL) - goto failed_malloc; - } - } - else { - b = pow5mult(b, b5); - if (b == NULL) - goto failed_malloc; - } - } - S = i2b(1); - if (S == NULL) - goto failed_malloc; - if (s5 > 0) { - S = pow5mult(S, s5); - if (S == NULL) - goto failed_malloc; - } - - /* Check for special case that d is a normalized power of 2. */ - - spec_case = 0; - if ((mode < 2 || leftright) - ) { - if (!word1(&u) && !(word0(&u) & Bndry_mask) - && word0(&u) & (Exp_mask & ~Exp_msk1) - ) { - /* The special case */ - b2 += Log2P; - s2 += Log2P; - spec_case = 1; - } - } - - /* Arrange for convenient computation of quotients: - * shift left if necessary so divisor has 4 leading 0 bits. - * - * Perhaps we should just compute leading 28 bits of S once - * and for all and pass them and a shift to quorem, so it - * can do shifts and ors to compute the numerator for q. - */ - if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f)) - i = 32 - i; + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (dval(&u) < 0) { + L--; + dval(&u) += ds; + } +#endif + *s++ = '0' + (int)L; + if (!dval(&u)) { + break; + } + if (i == ilim) { + dval(&u) += dval(&u); + if (dval(&u) > ds || (dval(&u) == ds && L & 1)) { + bump_up: + while(*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + break; + } + } + goto ret1; + } + + m2 = b2; + m5 = b5; + if (leftright) { + i = + denorm ? be + (Bias + (P-1) - 1 + 1) : + 1 + P - bbits; + b2 += i; + s2 += i; + mhi = i2b(1); + if (mhi == NULL) + goto failed_malloc; + } + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + if (mhi == NULL) + goto failed_malloc; + b1 = mult(mhi, b); + Bfree(b); + b = b1; + if (b == NULL) + goto failed_malloc; + } + if ((j = b5 - m5)) { + b = pow5mult(b, j); + if (b == NULL) + goto failed_malloc; + } + } + else { + b = pow5mult(b, b5); + if (b == NULL) + goto failed_malloc; + } + } + S = i2b(1); + if (S == NULL) + goto failed_malloc; + if (s5 > 0) { + S = pow5mult(S, s5); + if (S == NULL) + goto failed_malloc; + } + + /* Check for special case that d is a normalized power of 2. */ + + spec_case = 0; + if ((mode < 2 || leftright) + ) { + if (!word1(&u) && !(word0(&u) & Bndry_mask) + && word0(&u) & (Exp_mask & ~Exp_msk1) + ) { + /* The special case */ + b2 += Log2P; + s2 += Log2P; + spec_case = 1; + } + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ + if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f)) + i = 32 - i; #define iInc 28 - i = dshift(S, s2); - b2 += i; - m2 += i; - s2 += i; - if (b2 > 0) { - b = lshift(b, b2); - if (b == NULL) - goto failed_malloc; - } - if (s2 > 0) { - S = lshift(S, s2); - if (S == NULL) - goto failed_malloc; - } - if (k_check) { - if (cmp(b,S) < 0) { - k--; - b = multadd(b, 10, 0); /* we botched the k estimate */ - if (b == NULL) - goto failed_malloc; - if (leftright) { - mhi = multadd(mhi, 10, 0); - if (mhi == NULL) - goto failed_malloc; - } - ilim = ilim1; - } - } - if (ilim <= 0 && (mode == 3 || mode == 5)) { - if (ilim < 0) { - /* no digits, fcvt style */ - no_digits: - k = -1 - ndigits; - goto ret; - } - else { - S = multadd(S, 5, 0); - if (S == NULL) - goto failed_malloc; - if (cmp(b, S) <= 0) - goto no_digits; - } - one_digit: - *s++ = '1'; - k++; - goto ret; - } - if (leftright) { - if (m2 > 0) { - mhi = lshift(mhi, m2); - if (mhi == NULL) - goto failed_malloc; - } - - /* Compute mlo -- check for special case - * that d is a normalized power of 2. - */ - - mlo = mhi; - if (spec_case) { - mhi = Balloc(mhi->k); - if (mhi == NULL) - goto failed_malloc; - Bcopy(mhi, mlo); - mhi = lshift(mhi, Log2P); - if (mhi == NULL) - goto failed_malloc; - } - - for(i = 1;;i++) { - dig = quorem(b,S) + '0'; - /* Do we yet have the shortest decimal string - * that will round to d? - */ - j = cmp(b, mlo); - delta = diff(S, mhi); - if (delta == NULL) - goto failed_malloc; - j1 = delta->sign ? 1 : cmp(b, delta); - Bfree(delta); - if (j1 == 0 && mode != 1 && !(word1(&u) & 1) - ) { - if (dig == '9') - goto round_9_up; - if (j > 0) - dig++; - *s++ = dig; - goto ret; - } - if (j < 0 || (j == 0 && mode != 1 - && !(word1(&u) & 1) - )) { - if (!b->x[0] && b->wds <= 1) { - goto accept_dig; - } - if (j1 > 0) { - b = lshift(b, 1); - if (b == NULL) - goto failed_malloc; - j1 = cmp(b, S); - if ((j1 > 0 || (j1 == 0 && dig & 1)) - && dig++ == '9') - goto round_9_up; - } - accept_dig: - *s++ = dig; - goto ret; - } - if (j1 > 0) { - if (dig == '9') { /* possible if i == 1 */ - round_9_up: - *s++ = '9'; - goto roundoff; - } - *s++ = dig + 1; - goto ret; - } - *s++ = dig; - if (i == ilim) - break; - b = multadd(b, 10, 0); - if (b == NULL) - goto failed_malloc; - if (mlo == mhi) { - mlo = mhi = multadd(mhi, 10, 0); - if (mlo == NULL) - goto failed_malloc; - } - else { - mlo = multadd(mlo, 10, 0); - if (mlo == NULL) - goto failed_malloc; - mhi = multadd(mhi, 10, 0); - if (mhi == NULL) - goto failed_malloc; - } - } - } - else - for(i = 1;; i++) { - *s++ = dig = quorem(b,S) + '0'; - if (!b->x[0] && b->wds <= 1) { - goto ret; - } - if (i >= ilim) - break; - b = multadd(b, 10, 0); - if (b == NULL) - goto failed_malloc; - } - - /* Round off last digit */ - - b = lshift(b, 1); - if (b == NULL) - goto failed_malloc; - j = cmp(b, S); - if (j > 0 || (j == 0 && dig & 1)) { - roundoff: - while(*--s == '9') - if (s == s0) { - k++; - *s++ = '1'; - goto ret; - } - ++*s++; - } - else { - while(*--s == '0'); - s++; - } - ret: - Bfree(S); - if (mhi) { - if (mlo && mlo != mhi) - Bfree(mlo); - Bfree(mhi); - } - ret1: - Bfree(b); - *s = 0; - *decpt = k + 1; - if (rve) - *rve = s; - return s0; - failed_malloc: - if (S) - Bfree(S); - if (mlo && mlo != mhi) - Bfree(mlo); - if (mhi) - Bfree(mhi); - if (b) - Bfree(b); - if (s0) - _Py_dg_freedtoa(s0); - return NULL; - } + i = dshift(S, s2); + b2 += i; + m2 += i; + s2 += i; + if (b2 > 0) { + b = lshift(b, b2); + if (b == NULL) + goto failed_malloc; + } + if (s2 > 0) { + S = lshift(S, s2); + if (S == NULL) + goto failed_malloc; + } + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (b == NULL) + goto failed_malloc; + if (leftright) { + mhi = multadd(mhi, 10, 0); + if (mhi == NULL) + goto failed_malloc; + } + ilim = ilim1; + } + } + if (ilim <= 0 && (mode == 3 || mode == 5)) { + if (ilim < 0) { + /* no digits, fcvt style */ + no_digits: + k = -1 - ndigits; + goto ret; + } + else { + S = multadd(S, 5, 0); + if (S == NULL) + goto failed_malloc; + if (cmp(b, S) <= 0) + goto no_digits; + } + one_digit: + *s++ = '1'; + k++; + goto ret; + } + if (leftright) { + if (m2 > 0) { + mhi = lshift(mhi, m2); + if (mhi == NULL) + goto failed_malloc; + } + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + if (mhi == NULL) + goto failed_malloc; + Bcopy(mhi, mlo); + mhi = lshift(mhi, Log2P); + if (mhi == NULL) + goto failed_malloc; + } + + for(i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi); + if (delta == NULL) + goto failed_malloc; + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); + if (j1 == 0 && mode != 1 && !(word1(&u) & 1) + ) { + if (dig == '9') + goto round_9_up; + if (j > 0) + dig++; + *s++ = dig; + goto ret; + } + if (j < 0 || (j == 0 && mode != 1 + && !(word1(&u) & 1) + )) { + if (!b->x[0] && b->wds <= 1) { + goto accept_dig; + } + if (j1 > 0) { + b = lshift(b, 1); + if (b == NULL) + goto failed_malloc; + j1 = cmp(b, S); + if ((j1 > 0 || (j1 == 0 && dig & 1)) + && dig++ == '9') + goto round_9_up; + } + accept_dig: + *s++ = dig; + goto ret; + } + if (j1 > 0) { + if (dig == '9') { /* possible if i == 1 */ + round_9_up: + *s++ = '9'; + goto roundoff; + } + *s++ = dig + 1; + goto ret; + } + *s++ = dig; + if (i == ilim) + break; + b = multadd(b, 10, 0); + if (b == NULL) + goto failed_malloc; + if (mlo == mhi) { + mlo = mhi = multadd(mhi, 10, 0); + if (mlo == NULL) + goto failed_malloc; + } + else { + mlo = multadd(mlo, 10, 0); + if (mlo == NULL) + goto failed_malloc; + mhi = multadd(mhi, 10, 0); + if (mhi == NULL) + goto failed_malloc; + } + } + } + else + for(i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (!b->x[0] && b->wds <= 1) { + goto ret; + } + if (i >= ilim) + break; + b = multadd(b, 10, 0); + if (b == NULL) + goto failed_malloc; + } + + /* Round off last digit */ + + b = lshift(b, 1); + if (b == NULL) + goto failed_malloc; + j = cmp(b, S); + if (j > 0 || (j == 0 && dig & 1)) { + roundoff: + while(*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; + } + else { + while(*--s == '0'); + s++; + } + ret: + Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } + ret1: + Bfree(b); + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; + return s0; + failed_malloc: + if (S) + Bfree(S); + if (mlo && mlo != mhi) + Bfree(mlo); + if (mhi) + Bfree(mhi); + if (b) + Bfree(b); + if (s0) + _Py_dg_freedtoa(s0); + return NULL; +} #ifdef __cplusplus } #endif From python-checkins at python.org Tue Apr 7 13:27:18 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 7 Apr 2009 13:27:18 +0200 (CEST) Subject: [Python-checkins] r71353 - in python/branches/py3k-short-float-repr: Lib/test/test_float.py test_float_format.py Message-ID: <20090407112718.C0D321E40B0@bag.python.org> Author: mark.dickinson Date: Tue Apr 7 13:27:18 2009 New Revision: 71353 Log: Remove top-level test_floatformat file, and incorporate into Lib/test/test_float.py. Tests are skipped on non IEEE 754 platforms. Removed: python/branches/py3k-short-float-repr/test_float_format.py Modified: python/branches/py3k-short-float-repr/Lib/test/test_float.py Modified: python/branches/py3k-short-float-repr/Lib/test/test_float.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_float.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_float.py Tue Apr 7 13:27:18 2009 @@ -1,6 +1,7 @@ import unittest, struct import os +import sys from test import support import math from math import isinf, isnan, copysign, ldexp @@ -10,6 +11,14 @@ INF = float("inf") NAN = float("nan") +#locate file with float format test values +if __name__ == '__main__': + file = sys.argv[0] +else: + file = __file__ +test_dir = os.path.dirname(file) or os.curdir +format_testfile = os.path.join(test_dir, 'formatfloat_testcases.txt') + class GeneralFloatCases(unittest.TestCase): def test_float(self): @@ -313,6 +322,23 @@ self.assertEqual(v, eval(repr(v))) floats_file.close() +class FormatTestCase(unittest.TestCase): + @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + def test_format_testfile(self): + for line in open(format_testfile): + if line.startswith('--'): + continue + line = line.strip() + if not line: + continue + + lhs, rhs = map(str.strip, line.split('->')) + fmt, arg = lhs.split() + self.assertEqual(fmt % float(arg), rhs) + self.assertEqual(fmt % -float(arg), '-' + rhs) + + # Beginning with Python 2.6 float has cross platform compatible # ways to create and represent inf and nan class InfNanTest(unittest.TestCase): Deleted: python/branches/py3k-short-float-repr/test_float_format.py ============================================================================== --- python/branches/py3k-short-float-repr/test_float_format.py Tue Apr 7 13:27:18 2009 +++ (empty file) @@ -1,14 +0,0 @@ -f = open('Lib/test/formatfloat_testcases.txt') - -for line in f: - if line.startswith('--'): - continue - line = line.strip() - if not line: - continue - - lhs, rhs = map(str.strip, line.split('->')) - fmt, arg = lhs.split() - print(line) - assert fmt % float(arg) == rhs - assert fmt % -float(arg) == '-'+rhs From kayan.almeida at lig022.del.ufrj.br Fri Apr 3 18:51:29 2009 From: kayan.almeida at lig022.del.ufrj.br (Kayan Turazzi Almeida) Date: Fri, 3 Apr 2009 13:51:29 -0300 Subject: [Python-checkins] Python Regression Test Failures doc dist (1) Message-ID: <20090403165129.GA11720@lig022.del.ufrj.br> rm -rf dist mkdir -p dist # archive the HTML make html make[1]: Entering directory `/net/users/kayan.almeida/Desktop/Python-2.6.1/Doc' mkdir -p build/html build/doctrees python tools/sphinx-build.py -b html -d build/doctrees -D latex_paper_size= . build/html Exception occurred: File "/net/users/kayan.almeida/Desktop/Python-2.6.1/Doc/conf.py", line 33, in ? import patchlevel ImportError: No module named patchlevel The full traceback has been saved in /tmp/sphinx-err-ZarMIe.log, if you want to report the issue to the author. Please also report this if it was a user error, so that a better error message can be provided next time. Send reports to sphinx-dev at googlegroups.com. Thanks! make[1]: *** [build] Error 1 make[1]: Leaving directory `/net/users/kayan.almeida/Desktop/Python-2.6.1/Doc' make: *** [dist] Error 2 From kayan.almeida at lig022.del.ufrj.br Fri Apr 3 18:51:28 2009 From: kayan.almeida at lig022.del.ufrj.br (Kayan Turazzi Almeida) Date: Fri, 3 Apr 2009 13:51:28 -0300 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090403165128.GA11693@lig022.del.ufrj.br> Checking out Sphinx... A tools/sphinx/quickstart.py A tools/sphinx/jinja2glue.py A tools/sphinx/linkcheck.py A tools/sphinx/pycode A tools/sphinx/pycode/nodes.py A tools/sphinx/pycode/Grammar.txt A tools/sphinx/pycode/__init__.py A tools/sphinx/pycode/pgen2 A tools/sphinx/pycode/pgen2/tokenize.py A tools/sphinx/pycode/pgen2/pgen.py A tools/sphinx/pycode/pgen2/parse.py A tools/sphinx/pycode/pgen2/driver.py A tools/sphinx/pycode/pgen2/__init__.py A tools/sphinx/pycode/pgen2/literals.py A tools/sphinx/pycode/pgen2/token.py A tools/sphinx/pycode/pgen2/parse.pyx A tools/sphinx/pycode/pgen2/parse.c A tools/sphinx/pycode/pgen2/grammar.py A tools/sphinx/setup_command.py A tools/sphinx/__init__.py A tools/sphinx/static A tools/sphinx/static/contents.png A tools/sphinx/static/doctools.js A tools/sphinx/static/searchtools.js A tools/sphinx/static/traditional.css A tools/sphinx/static/file.png A tools/sphinx/static/navigation.png A tools/sphinx/static/plus.png A tools/sphinx/static/sphinxdoc.css A tools/sphinx/static/stickysidebar.css A tools/sphinx/static/jquery.js A tools/sphinx/static/default.css A tools/sphinx/static/minus.png A tools/sphinx/static/rightsidebar.css A tools/sphinx/htmlwriter.py A tools/sphinx/application.py A tools/sphinx/environment.py A tools/sphinx/search.py A tools/sphinx/config.py A tools/sphinx/highlighting.py A tools/sphinx/templates A tools/sphinx/templates/page.html A tools/sphinx/templates/layout.html A tools/sphinx/templates/genindex-single.html A tools/sphinx/templates/genindex.html A tools/sphinx/templates/opensearch.xml A tools/sphinx/templates/changes A tools/sphinx/templates/changes/versionchanges.html A tools/sphinx/templates/changes/frameset.html A tools/sphinx/templates/changes/rstsource.html A tools/sphinx/templates/search.html A tools/sphinx/templates/defindex.html A tools/sphinx/templates/modindex.html A tools/sphinx/templates/genindex-split.html A tools/sphinx/writers A tools/sphinx/writers/latex.py A tools/sphinx/writers/__init__.py A tools/sphinx/writers/html.py A tools/sphinx/writers/text.py A tools/sphinx/locale A tools/sphinx/locale/cs A tools/sphinx/locale/cs/LC_MESSAGES A tools/sphinx/locale/cs/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/cs/LC_MESSAGES/sphinx.js A tools/sphinx/locale/cs/LC_MESSAGES/sphinx.po A tools/sphinx/locale/__init__.py A tools/sphinx/locale/pt_BR A tools/sphinx/locale/pt_BR/LC_MESSAGES A tools/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.js A tools/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po A tools/sphinx/locale/es A tools/sphinx/locale/es/LC_MESSAGES A tools/sphinx/locale/es/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/es/LC_MESSAGES/sphinx.js A tools/sphinx/locale/es/LC_MESSAGES/sphinx.po A tools/sphinx/locale/fr A tools/sphinx/locale/fr/LC_MESSAGES A tools/sphinx/locale/fr/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/fr/LC_MESSAGES/sphinx.js A tools/sphinx/locale/fr/LC_MESSAGES/sphinx.po A tools/sphinx/locale/de A tools/sphinx/locale/de/LC_MESSAGES A tools/sphinx/locale/de/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/de/LC_MESSAGES/sphinx.js A tools/sphinx/locale/de/LC_MESSAGES/sphinx.po A tools/sphinx/locale/nl A tools/sphinx/locale/nl/LC_MESSAGES A tools/sphinx/locale/nl/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/nl/LC_MESSAGES/sphinx.js A tools/sphinx/locale/nl/LC_MESSAGES/sphinx.po A tools/sphinx/locale/ja A tools/sphinx/locale/ja/LC_MESSAGES A tools/sphinx/locale/ja/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/ja/LC_MESSAGES/sphinx.js A tools/sphinx/locale/ja/LC_MESSAGES/sphinx.po A tools/sphinx/locale/sphinx.pot A tools/sphinx/locale/pl A tools/sphinx/locale/pl/LC_MESSAGES A tools/sphinx/locale/pl/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/pl/LC_MESSAGES/sphinx.js A tools/sphinx/locale/pl/LC_MESSAGES/sphinx.po A tools/sphinx/locale/zh_TW A tools/sphinx/locale/zh_TW/LC_MESSAGES A tools/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.js A tools/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po A tools/sphinx/locale/it A tools/sphinx/locale/it/LC_MESSAGES A tools/sphinx/locale/it/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/it/LC_MESSAGES/sphinx.js A tools/sphinx/locale/it/LC_MESSAGES/sphinx.po A tools/sphinx/locale/sl A tools/sphinx/locale/sl/LC_MESSAGES A tools/sphinx/locale/sl/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/sl/LC_MESSAGES/sphinx.js A tools/sphinx/locale/sl/LC_MESSAGES/sphinx.po A tools/sphinx/ext A tools/sphinx/ext/coverage.py A tools/sphinx/ext/intersphinx.py A tools/sphinx/ext/autodoc.py A tools/sphinx/ext/pngmath.py A tools/sphinx/ext/__init__.py A tools/sphinx/ext/refcounting.py A tools/sphinx/ext/ifconfig.py A tools/sphinx/ext/mathbase.py A tools/sphinx/ext/doctest.py A tools/sphinx/ext/todo.py A tools/sphinx/ext/jsmath.py A tools/sphinx/latexwriter.py A tools/sphinx/directives A tools/sphinx/directives/code.py A tools/sphinx/directives/desc.py A tools/sphinx/directives/__init__.py A tools/sphinx/directives/other.py A tools/sphinx/cmdline.py A tools/sphinx/texinputs A tools/sphinx/texinputs/python.ist A tools/sphinx/texinputs/howto.cls A tools/sphinx/texinputs/tabulary.sty A tools/sphinx/texinputs/sphinx.sty A tools/sphinx/texinputs/fncychap.sty A tools/sphinx/texinputs/Makefile A tools/sphinx/texinputs/manual.cls A tools/sphinx/htmlhelp.py A tools/sphinx/addnodes.py A tools/sphinx/textwriter.py A tools/sphinx/builders A tools/sphinx/builders/changes.py A tools/sphinx/builders/linkcheck.py A tools/sphinx/builders/htmlhelp.py A tools/sphinx/builders/latex.py A tools/sphinx/builders/qthelp.py A tools/sphinx/builders/__init__.py A tools/sphinx/builders/html.py A tools/sphinx/builders/text.py A tools/sphinx/roles.py A tools/sphinx/builder.py A tools/sphinx/util A tools/sphinx/util/stemmer.py A tools/sphinx/util/__init__.py A tools/sphinx/util/docstrings.py A tools/sphinx/util/texescape.py A tools/sphinx/util/console.py A tools/sphinx/util/jsdump.py A tools/sphinx/util/compat.py A tools/sphinx/util/png.py A tools/sphinx/util/smartypants.py U tools/sphinx Checked out revision 71097. Checking out Docutils... A tools/docutils/core.py A tools/docutils/nodes.py A tools/docutils/parsers A tools/docutils/parsers/null.py A tools/docutils/parsers/__init__.py A tools/docutils/parsers/rst A tools/docutils/parsers/rst/directives A tools/docutils/parsers/rst/directives/parts.py A tools/docutils/parsers/rst/directives/tables.py A tools/docutils/parsers/rst/directives/misc.py A tools/docutils/parsers/rst/directives/body.py A tools/docutils/parsers/rst/directives/__init__.py A tools/docutils/parsers/rst/directives/references.py A tools/docutils/parsers/rst/directives/admonitions.py A tools/docutils/parsers/rst/directives/html.py A tools/docutils/parsers/rst/directives/images.py A tools/docutils/parsers/rst/include A tools/docutils/parsers/rst/include/isopub.txt A tools/docutils/parsers/rst/include/isobox.txt A tools/docutils/parsers/rst/include/isogrk4-wide.txt A tools/docutils/parsers/rst/include/isonum.txt A tools/docutils/parsers/rst/include/isomfrk.txt A tools/docutils/parsers/rst/include/xhtml1-lat1.txt A tools/docutils/parsers/rst/include/isomopf.txt A tools/docutils/parsers/rst/include/mmlextra-wide.txt A tools/docutils/parsers/rst/include/xhtml1-symbol.txt A tools/docutils/parsers/rst/include/mmlextra.txt A tools/docutils/parsers/rst/include/isocyr1.txt A tools/docutils/parsers/rst/include/isocyr2.txt A tools/docutils/parsers/rst/include/xhtml1-special.txt A tools/docutils/parsers/rst/include/isoamsa.txt A tools/docutils/parsers/rst/include/isoamsb.txt A tools/docutils/parsers/rst/include/isoamsc.txt A tools/docutils/parsers/rst/include/mmlalias.txt A tools/docutils/parsers/rst/include/isomfrk-wide.txt A tools/docutils/parsers/rst/include/isomopf-wide.txt A tools/docutils/parsers/rst/include/isomscr-wide.txt A tools/docutils/parsers/rst/include/isodia.txt A tools/docutils/parsers/rst/include/isoamsn.txt A tools/docutils/parsers/rst/include/isoamso.txt A tools/docutils/parsers/rst/include/isolat1.txt A tools/docutils/parsers/rst/include/isoamsr.txt A tools/docutils/parsers/rst/include/isolat2.txt A tools/docutils/parsers/rst/include/isogrk1.txt A tools/docutils/parsers/rst/include/isomscr.txt A tools/docutils/parsers/rst/include/isogrk2.txt A tools/docutils/parsers/rst/include/isogrk3.txt A tools/docutils/parsers/rst/include/isogrk4.txt A tools/docutils/parsers/rst/include/s5defs.txt A tools/docutils/parsers/rst/include/README.txt A tools/docutils/parsers/rst/include/isotech.txt A tools/docutils/parsers/rst/__init__.py A tools/docutils/parsers/rst/languages A tools/docutils/parsers/rst/languages/sv.py A tools/docutils/parsers/rst/languages/de.py A tools/docutils/parsers/rst/languages/ja.py A tools/docutils/parsers/rst/languages/zh_tw.py A tools/docutils/parsers/rst/languages/he.py A tools/docutils/parsers/rst/languages/fi.py A tools/docutils/parsers/rst/languages/__init__.py A tools/docutils/parsers/rst/languages/zh_cn.py A tools/docutils/parsers/rst/languages/en.py A tools/docutils/parsers/rst/languages/eo.py A tools/docutils/parsers/rst/languages/cs.py A tools/docutils/parsers/rst/languages/pt_br.py A tools/docutils/parsers/rst/languages/es.py A tools/docutils/parsers/rst/languages/fr.py A tools/docutils/parsers/rst/languages/nl.py A tools/docutils/parsers/rst/languages/it.py A tools/docutils/parsers/rst/languages/sk.py A tools/docutils/parsers/rst/languages/ca.py A tools/docutils/parsers/rst/languages/ru.py A tools/docutils/parsers/rst/languages/af.py A tools/docutils/parsers/rst/states.py A tools/docutils/parsers/rst/roles.py A tools/docutils/parsers/rst/tableparser.py A tools/docutils/writers A tools/docutils/writers/null.py A tools/docutils/writers/html4css1 A tools/docutils/writers/html4css1/__init__.py A tools/docutils/writers/html4css1/html4css1.css A tools/docutils/writers/html4css1/template.txt A tools/docutils/writers/latex2e A tools/docutils/writers/latex2e/latex2e.tex A tools/docutils/writers/latex2e/__init__.py A tools/docutils/writers/__init__.py A tools/docutils/writers/pseudoxml.py A tools/docutils/writers/pep_html A tools/docutils/writers/pep_html/__init__.py A tools/docutils/writers/pep_html/template.txt A tools/docutils/writers/pep_html/pep.css A tools/docutils/writers/s5_html A tools/docutils/writers/s5_html/themes A tools/docutils/writers/s5_html/themes/big-white A tools/docutils/writers/s5_html/themes/big-white/framing.css A tools/docutils/writers/s5_html/themes/big-white/pretty.css A tools/docutils/writers/s5_html/themes/small-black A tools/docutils/writers/s5_html/themes/small-black/__base__ A tools/docutils/writers/s5_html/themes/small-black/pretty.css A tools/docutils/writers/s5_html/themes/default A tools/docutils/writers/s5_html/themes/default/print.css A tools/docutils/writers/s5_html/themes/default/s5-core.css A tools/docutils/writers/s5_html/themes/default/iepngfix.htc A tools/docutils/writers/s5_html/themes/default/outline.css A tools/docutils/writers/s5_html/themes/default/framing.css A tools/docutils/writers/s5_html/themes/default/slides.css A tools/docutils/writers/s5_html/themes/default/blank.gif A tools/docutils/writers/s5_html/themes/default/opera.css A tools/docutils/writers/s5_html/themes/default/pretty.css A tools/docutils/writers/s5_html/themes/default/slides.js A tools/docutils/writers/s5_html/themes/small-white A tools/docutils/writers/s5_html/themes/small-white/framing.css A tools/docutils/writers/s5_html/themes/small-white/pretty.css A tools/docutils/writers/s5_html/themes/medium-black A tools/docutils/writers/s5_html/themes/medium-black/__base__ A tools/docutils/writers/s5_html/themes/medium-black/pretty.css A tools/docutils/writers/s5_html/themes/README.txt A tools/docutils/writers/s5_html/themes/big-black A tools/docutils/writers/s5_html/themes/big-black/__base__ A tools/docutils/writers/s5_html/themes/big-black/framing.css A tools/docutils/writers/s5_html/themes/big-black/pretty.css A tools/docutils/writers/s5_html/themes/medium-white A tools/docutils/writers/s5_html/themes/medium-white/framing.css A tools/docutils/writers/s5_html/themes/medium-white/pretty.css A tools/docutils/writers/s5_html/__init__.py A tools/docutils/writers/docutils_xml.py A tools/docutils/writers/newlatex2e A tools/docutils/writers/newlatex2e/tests.txt A tools/docutils/writers/newlatex2e/__init__.py A tools/docutils/writers/newlatex2e/notes.txt A tools/docutils/writers/newlatex2e/base.tex A tools/docutils/writers/newlatex2e/unicode_map.py A tools/docutils/examples.py A tools/docutils/readers A tools/docutils/readers/standalone.py A tools/docutils/readers/python A tools/docutils/readers/python/__init__.py A tools/docutils/readers/python/pynodes.py A tools/docutils/readers/python/moduleparser.py A tools/docutils/readers/__init__.py A tools/docutils/readers/pep.py A tools/docutils/readers/doctree.py A tools/docutils/__init__.py A tools/docutils/frontend.py A tools/docutils/languages A tools/docutils/languages/sv.py A tools/docutils/languages/de.py A tools/docutils/languages/ja.py A tools/docutils/languages/zh_tw.py A tools/docutils/languages/he.py A tools/docutils/languages/fi.py A tools/docutils/languages/__init__.py A tools/docutils/languages/zh_cn.py A tools/docutils/languages/en.py A tools/docutils/languages/eo.py A tools/docutils/languages/cs.py A tools/docutils/languages/pt_br.py A tools/docutils/languages/es.py A tools/docutils/languages/fr.py A tools/docutils/languages/nl.py A tools/docutils/languages/it.py A tools/docutils/languages/sk.py A tools/docutils/languages/ca.py A tools/docutils/languages/ru.py A tools/docutils/languages/af.py A tools/docutils/utils.py A tools/docutils/docutils.conf A tools/docutils/statemachine.py A tools/docutils/io.py A tools/docutils/transforms A tools/docutils/transforms/universal.py A tools/docutils/transforms/parts.py A tools/docutils/transforms/writer_aux.py A tools/docutils/transforms/misc.py A tools/docutils/transforms/__init__.py A tools/docutils/transforms/references.py A tools/docutils/transforms/components.py A tools/docutils/transforms/frontmatter.py A tools/docutils/transforms/peps.py A tools/docutils/urischemes.py Checked out revision 71097. Checking out Jinja... A tools/jinja/loaders.py A tools/jinja/datastructure.py A tools/jinja/parser.py A tools/jinja/plugin.py A tools/jinja/__init__.py A tools/jinja/utils.py A tools/jinja/tests.py A tools/jinja/environment.py A tools/jinja/defaults.py A tools/jinja/filters.py A tools/jinja/nodes.py A tools/jinja/constants.py A tools/jinja/_debugger.c A tools/jinja/lexer.py A tools/jinja/_speedups.c A tools/jinja/exceptions.py A tools/jinja/debugger.py A tools/jinja/_native.py A tools/jinja/translators A tools/jinja/translators/__init__.py A tools/jinja/translators/python.py Checked out revision 71097. Checking out Pygments... A tools/pygments/scanner.py A tools/pygments/styles A tools/pygments/styles/vs.py A tools/pygments/styles/emacs.py A tools/pygments/styles/perldoc.py A tools/pygments/styles/trac.py A tools/pygments/styles/vim.py A tools/pygments/styles/__init__.py A tools/pygments/styles/manni.py A tools/pygments/styles/bw.py A tools/pygments/styles/autumn.py A tools/pygments/styles/friendly.py A tools/pygments/styles/borland.py A tools/pygments/styles/fruity.py A tools/pygments/styles/default.py A tools/pygments/styles/murphy.py A tools/pygments/styles/colorful.py A tools/pygments/styles/pastie.py A tools/pygments/styles/native.py A tools/pygments/plugin.py A tools/pygments/__init__.py A tools/pygments/formatters A tools/pygments/formatters/terminal256.py A tools/pygments/formatters/_mapping.py A tools/pygments/formatters/rtf.py A tools/pygments/formatters/terminal.py A tools/pygments/formatters/img.py A tools/pygments/formatters/latex.py A tools/pygments/formatters/bbcode.py A tools/pygments/formatters/__init__.py A tools/pygments/formatters/svg.py A tools/pygments/formatters/other.py A tools/pygments/formatters/html.py A tools/pygments/style.py A tools/pygments/console.py A tools/pygments/formatter.py A tools/pygments/cmdline.py A tools/pygments/lexers A tools/pygments/lexers/math.py A tools/pygments/lexers/_luabuiltins.py A tools/pygments/lexers/_mapping.py A tools/pygments/lexers/compiled.py A tools/pygments/lexers/dotnet.py A tools/pygments/lexers/templates.py A tools/pygments/lexers/__init__.py A tools/pygments/lexers/_phpbuiltins.py A tools/pygments/lexers/functional.py A tools/pygments/lexers/_vimbuiltins.py A tools/pygments/lexers/_clbuiltins.py A tools/pygments/lexers/web.py A tools/pygments/lexers/asm.py A tools/pygments/lexers/special.py A tools/pygments/lexers/agile.py A tools/pygments/lexers/other.py A tools/pygments/lexers/text.py A tools/pygments/util.py A tools/pygments/lexer.py A tools/pygments/token.py A tools/pygments/filters A tools/pygments/filters/__init__.py A tools/pygments/unistring.py A tools/pygments/filter.py Checked out revision 71097. svn update tools/sphinx At revision 71097. svn update tools/docutils At revision 71097. svn update tools/jinja At revision 71097. svn update tools/pygments At revision 71097. mkdir -p build/html build/doctrees python tools/sphinx-build.py -b html -d build/doctrees -D latex_paper_size= . build/html Exception occurred: File "/net/users/kayan.almeida/Desktop/Python-2.6.1/Doc/conf.py", line 33, in ? import patchlevel ImportError: No module named patchlevel The full traceback has been saved in /tmp/sphinx-err-aoPB-o.log, if you want to report the issue to the author. Please also report this if it was a user error, so that a better error message can be provided next time. Send reports to sphinx-dev at googlegroups.com. Thanks! make: *** [build] Error 1 From python-checkins at python.org Tue Apr 7 13:53:52 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 7 Apr 2009 13:53:52 +0200 (CEST) Subject: [Python-checkins] r71354 - in python/branches/py3k/Python: atof.c strtod.c Message-ID: <20090407115352.3C31E1E406D@bag.python.org> Author: mark.dickinson Date: Tue Apr 7 13:53:52 2009 New Revision: 71354 Log: Revert removal of atof.c and strtod.c in r71341. We're not quite ready for this yet---this removal should happen as part of the py3k-short-float-repr merge. Added: python/branches/py3k/Python/atof.c - copied unchanged from r71340, /python/branches/py3k/Python/atof.c python/branches/py3k/Python/strtod.c - copied unchanged from r71340, /python/branches/py3k/Python/strtod.c From buildbot at python.org Tue Apr 7 14:38:39 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 12:38:39 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090407123839.3DF211E42DF@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/496 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: mark.dickinson,raymond.hettinger BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 249, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 102, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Tue Apr 7 15:13:10 2009 From: python-checkins at python.org (matthias.klose) Date: Tue, 7 Apr 2009 15:13:10 +0200 (CEST) Subject: [Python-checkins] r71355 - in python/branches/py3k: Lib/xmlrpc/server.py Misc/NEWS Message-ID: <20090407131310.EAF201E403E@bag.python.org> Author: matthias.klose Date: Tue Apr 7 15:13:10 2009 New Revision: 71355 Log: Merged revisions 71268 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71268 | matthias.klose | 2009-04-05 23:00:48 +0200 (So, 05 Apr 2009) | 3 lines - Issue #2703: SimpleXMLRPCDispatcher.__init__: Provide default values for new arguments introduced in 2.5. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/xmlrpc/server.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/xmlrpc/server.py ============================================================================== --- python/branches/py3k/Lib/xmlrpc/server.py (original) +++ python/branches/py3k/Lib/xmlrpc/server.py Tue Apr 7 15:13:10 2009 @@ -159,7 +159,7 @@ reason to instantiate this class directly. """ - def __init__(self, allow_none, encoding): + def __init__(self, allow_none=False, encoding=None): self.funcs = {} self.instance = None self.allow_none = allow_none Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Tue Apr 7 15:13:10 2009 @@ -15,6 +15,9 @@ Library ------- +- Issue #2703: SimpleXMLRPCDispatcher.__init__: Provide default values for + new arguments introduced in 2.5. + What's New in Python 3.1 alpha 2? ================================= From python-checkins at python.org Tue Apr 7 15:24:29 2009 From: python-checkins at python.org (matthias.klose) Date: Tue, 7 Apr 2009 15:24:29 +0200 (CEST) Subject: [Python-checkins] r71356 - in python/branches/py3k: Include/object.h Misc/NEWS Modules/readline.c Message-ID: <20090407132429.40EE61E403E@bag.python.org> Author: matthias.klose Date: Tue Apr 7 15:24:27 2009 New Revision: 71356 Log: Merged revisions 71229,71271 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71229 | matthias.klose | 2009-04-05 14:43:08 +0200 (So, 05 Apr 2009) | 3 lines - Py_DECREF: Add `do { ... } while (0)' to avoid compiler warnings. (avoiding brown paper typo this time) ........ r71271 | matthias.klose | 2009-04-05 23:19:13 +0200 (So, 05 Apr 2009) | 3 lines Issue #1113244: Py_XINCREF, Py_DECREF, Py_XDECREF: Add `do { ... } while (0)' to avoid compiler warnings. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Include/object.h python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/readline.c Modified: python/branches/py3k/Include/object.h ============================================================================== --- python/branches/py3k/Include/object.h (original) +++ python/branches/py3k/Include/object.h Tue Apr 7 15:24:27 2009 @@ -651,11 +651,13 @@ ((PyObject*)(op))->ob_refcnt++) #define Py_DECREF(op) \ - if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ - --((PyObject*)(op))->ob_refcnt != 0) \ - _Py_CHECK_REFCNT(op) \ - else \ - _Py_Dealloc((PyObject *)(op)) + do { \ + if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ + --((PyObject*)(op))->ob_refcnt != 0) \ + _Py_CHECK_REFCNT(op) \ + else \ + _Py_Dealloc((PyObject *)(op)); \ + } while (0) /* Safely decref `op` and set `op` to NULL, especially useful in tp_clear * and tp_dealloc implementatons. @@ -701,8 +703,8 @@ } while (0) /* Macros to use in case the object pointer may be NULL: */ -#define Py_XINCREF(op) if ((op) == NULL) ; else Py_INCREF(op) -#define Py_XDECREF(op) if ((op) == NULL) ; else Py_DECREF(op) +#define Py_XINCREF(op) do { if ((op) == NULL) ; else Py_INCREF(op); } while (0) +#define Py_XDECREF(op) do { if ((op) == NULL) ; else Py_DECREF(op); } while (0) /* These are provided as conveniences to Python runtime embedders, so that Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Tue Apr 7 15:24:27 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #1113244: Py_XINCREF, Py_DECREF, Py_XDECREF: Add `do { ... } while (0)' + to avoid compiler warnings. + Library ------- @@ -78,8 +81,6 @@ - Issue #3845: In PyRun_SimpleFileExFlags avoid invalid memory access with short file names. -- Py_DECREF: Add `do { ... } while (0)' to avoid compiler warnings. - Library ------- Modified: python/branches/py3k/Modules/readline.c ============================================================================== --- python/branches/py3k/Modules/readline.c (original) +++ python/branches/py3k/Modules/readline.c Tue Apr 7 15:24:27 2009 @@ -693,13 +693,13 @@ r = PyObject_CallFunction(completion_display_matches_hook, "sOi", matches[0], m, max_length); - Py_DECREF(m), m=NULL; + Py_DECREF(m); m=NULL; if (r == NULL || (r != Py_None && PyLong_AsLong(r) == -1 && PyErr_Occurred())) { goto error; } - Py_XDECREF(r), r=NULL; + Py_XDECREF(r); r=NULL; if (0) { error: From python-checkins at python.org Tue Apr 7 15:49:46 2009 From: python-checkins at python.org (matthias.klose) Date: Tue, 7 Apr 2009 15:49:46 +0200 (CEST) Subject: [Python-checkins] r71357 - in python/branches/py3k: Misc/NEWS setup.py Message-ID: <20090407134946.507B61E4450@bag.python.org> Author: matthias.klose Date: Tue Apr 7 15:49:45 2009 New Revision: 71357 Log: - Issue #5359: Readd the Berkley-DB detection code to allow _dbm be built using Berkley-DB. Modified: python/branches/py3k/Misc/NEWS python/branches/py3k/setup.py Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Tue Apr 7 15:49:45 2009 @@ -21,6 +21,12 @@ - Issue #2703: SimpleXMLRPCDispatcher.__init__: Provide default values for new arguments introduced in 2.5. +Extension Modules +----------------- + +- Issue #5359: Readd the Berkley-DB detection code to allow _dbm be built + using Berkley-DB. + What's New in Python 3.1 alpha 2? ================================= Modified: python/branches/py3k/setup.py ============================================================================== --- python/branches/py3k/setup.py (original) +++ python/branches/py3k/setup.py Tue Apr 7 15:49:45 2009 @@ -5,6 +5,7 @@ import sys, os, imp, re, optparse from glob import glob +from platform import machine as platform_machine from distutils import log from distutils import sysconfig @@ -650,6 +651,49 @@ # implementation independent wrapper for these; dbm/dumb.py provides # similar functionality (but slower of course) implemented in Python. + # Sleepycat^WOracle Berkeley DB interface. + # http://www.oracle.com/database/berkeley-db/db/index.html + # + # This requires the Sleepycat^WOracle DB code. The supported versions + # are set below. Visit the URL above to download + # a release. Most open source OSes come with one or more + # versions of BerkeleyDB already installed. + + max_db_ver = (4, 7) + min_db_ver = (3, 3) + db_setup_debug = False # verbose debug prints from this script? + + def allow_db_ver(db_ver): + """Returns a boolean if the given BerkeleyDB version is acceptable. + + Args: + db_ver: A tuple of the version to verify. + """ + if not (min_db_ver <= db_ver <= max_db_ver): + return False + # Use this function to filter out known bad configurations. + if (4, 6) == db_ver[:2]: + # BerkeleyDB 4.6.x is not stable on many architectures. + arch = platform_machine() + if arch not in ('i386', 'i486', 'i586', 'i686', + 'x86_64', 'ia64'): + return False + return True + + def gen_db_minor_ver_nums(major): + if major == 4: + for x in range(max_db_ver[1]+1): + if allow_db_ver((4, x)): + yield x + elif major == 3: + for x in (3,): + if allow_db_ver((3, x)): + yield x + else: + raise ValueError("unknown major BerkeleyDB version", major) + + # construct a list of paths to look for the header file in on + # top of the normal inc_dirs. db_inc_paths = [ '/usr/include/db4', '/usr/local/include/db4', @@ -661,8 +705,124 @@ '/sw/include/db4', '/sw/include/db3', ] + # 4.x minor number specific paths + for x in gen_db_minor_ver_nums(4): + db_inc_paths.append('/usr/include/db4%d' % x) + db_inc_paths.append('/usr/include/db4.%d' % x) + db_inc_paths.append('/usr/local/BerkeleyDB.4.%d/include' % x) + db_inc_paths.append('/usr/local/include/db4%d' % x) + db_inc_paths.append('/pkg/db-4.%d/include' % x) + db_inc_paths.append('/opt/db-4.%d/include' % x) + # MacPorts default (http://www.macports.org/) + db_inc_paths.append('/opt/local/include/db4%d' % x) + # 3.x minor number specific paths + for x in gen_db_minor_ver_nums(3): + db_inc_paths.append('/usr/include/db3%d' % x) + db_inc_paths.append('/usr/local/BerkeleyDB.3.%d/include' % x) + db_inc_paths.append('/usr/local/include/db3%d' % x) + db_inc_paths.append('/pkg/db-3.%d/include' % x) + db_inc_paths.append('/opt/db-3.%d/include' % x) + + # Add some common subdirectories for Sleepycat DB to the list, + # based on the standard include directories. This way DB3/4 gets + # picked up when it is installed in a non-standard prefix and + # the user has added that prefix into inc_dirs. + std_variants = [] + for dn in inc_dirs: + std_variants.append(os.path.join(dn, 'db3')) + std_variants.append(os.path.join(dn, 'db4')) + for x in gen_db_minor_ver_nums(4): + std_variants.append(os.path.join(dn, "db4%d"%x)) + std_variants.append(os.path.join(dn, "db4.%d"%x)) + for x in gen_db_minor_ver_nums(3): + std_variants.append(os.path.join(dn, "db3%d"%x)) + std_variants.append(os.path.join(dn, "db3.%d"%x)) + + db_inc_paths = std_variants + db_inc_paths + db_inc_paths = [p for p in db_inc_paths if os.path.exists(p)] + + db_ver_inc_map = {} + + class db_found(Exception): pass + try: + # See whether there is a Sleepycat header in the standard + # search path. + for d in inc_dirs + db_inc_paths: + f = os.path.join(d, "db.h") + if db_setup_debug: print("db: looking for db.h in", f) + if os.path.exists(f): + f = open(f).read() + m = re.search(r"#define\WDB_VERSION_MAJOR\W(\d+)", f) + if m: + db_major = int(m.group(1)) + m = re.search(r"#define\WDB_VERSION_MINOR\W(\d+)", f) + db_minor = int(m.group(1)) + db_ver = (db_major, db_minor) + + # Avoid 4.6 prior to 4.6.21 due to a BerkeleyDB bug + if db_ver == (4, 6): + m = re.search(r"#define\WDB_VERSION_PATCH\W(\d+)", f) + db_patch = int(m.group(1)) + if db_patch < 21: + print("db.h:", db_ver, "patch", db_patch, + "being ignored (4.6.x must be >= 4.6.21)") + continue + + if ( (db_ver not in db_ver_inc_map) and + allow_db_ver(db_ver) ): + # save the include directory with the db.h version + # (first occurrence only) + db_ver_inc_map[db_ver] = d + if db_setup_debug: + print("db.h: found", db_ver, "in", d) + else: + # we already found a header for this library version + if db_setup_debug: print("db.h: ignoring", d) + else: + # ignore this header, it didn't contain a version number + if db_setup_debug: + print("db.h: no version number version in", d) + + db_found_vers = list(db_ver_inc_map.keys()) + db_found_vers.sort() + + while db_found_vers: + db_ver = db_found_vers.pop() + db_incdir = db_ver_inc_map[db_ver] + + # check lib directories parallel to the location of the header + db_dirs_to_check = [ + db_incdir.replace("include", 'lib64'), + db_incdir.replace("include", 'lib'), + ] + db_dirs_to_check = list(filter(os.path.isdir, db_dirs_to_check)) + + # Look for a version specific db-X.Y before an ambiguoius dbX + # XXX should we -ever- look for a dbX name? Do any + # systems really not name their library by version and + # symlink to more general names? + for dblib in (('db-%d.%d' % db_ver), + ('db%d%d' % db_ver), + ('db%d' % db_ver[0])): + dblib_file = self.compiler.find_library_file( + db_dirs_to_check + lib_dirs, dblib ) + if dblib_file: + dblib_dir = [ os.path.abspath(os.path.dirname(dblib_file)) ] + raise db_found + else: + if db_setup_debug: print("db lib: ", dblib, "not found") - db_incs = None + except db_found: + if db_setup_debug: + print("bsddb using BerkeleyDB lib:", db_ver, dblib) + print("bsddb lib dir:", dblib_dir, " inc dir:", db_incdir) + db_incs = [db_incdir] + dblibs = [dblib] + else: + if db_setup_debug: print("db: no appropriate library found") + db_incs = None + dblibs = [] + dblib_dir = None # The sqlite interface sqlite_setup_debug = False # verbose debug prints from this script? From buildbot at python.org Tue Apr 7 15:54:44 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 13:54:44 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 3.x Message-ID: <20090407135444.D41391E403E@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%20gentoo%203.x/builds/597 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-amd64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: matthias.klose BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_smtplib make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Tue Apr 7 15:55:34 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 13:55:34 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 3.x Message-ID: <20090407135535.4B5AD1E403E@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%203.x/builds/695 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From buildbot at python.org Tue Apr 7 16:00:43 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 14:00:43 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090407140043.8CC381E4494@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/498 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From buildbot at python.org Tue Apr 7 16:00:45 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 14:00:45 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090407140045.CB4B81E43BF@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/548 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From buildbot at python.org Tue Apr 7 16:06:02 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 14:06:02 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 3.x Message-ID: <20090407140602.B0B6E1E4046@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%203.x/builds/636 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From buildbot at python.org Tue Apr 7 16:18:51 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 14:18:51 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 3.x Message-ID: <20090407141851.3C20A1E43FF@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%203.x/builds/590 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From python-checkins at python.org Tue Apr 7 16:33:53 2009 From: python-checkins at python.org (hirokazu.yamamoto) Date: Tue, 7 Apr 2009 16:33:53 +0200 (CEST) Subject: [Python-checkins] r71358 - in python/branches/release26-maint: Lib/test/test_traceback.py Lib/traceback.py Message-ID: <20090407143353.617CC1E403E@bag.python.org> Author: hirokazu.yamamoto Date: Tue Apr 7 16:33:53 2009 New Revision: 71358 Log: Rolled back revisions 71237 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_traceback.py python/branches/release26-maint/Lib/traceback.py Modified: python/branches/release26-maint/Lib/test/test_traceback.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_traceback.py (original) +++ python/branches/release26-maint/Lib/test/test_traceback.py Tue Apr 7 16:33:53 2009 @@ -8,6 +8,16 @@ import traceback +try: + raise KeyError +except KeyError: + type_, value, tb = sys.exc_info() + file_ = StringIO() + traceback_print(tb, file_) + example_traceback = file_.getvalue() +else: + raise Error("unable to create test traceback string") + class TracebackCases(unittest.TestCase): # For now, a very minimal set of tests. I want to be sure that @@ -152,24 +162,9 @@ class TracebackFormatTests(unittest.TestCase): - def test_traceback_format(self): - try: - raise KeyError('blah') - except KeyError: - type_, value, tb = sys.exc_info() - traceback_fmt = 'Traceback (most recent call last):\n' + \ - ''.join(traceback.format_tb(tb)) - file_ = StringIO() - traceback_print(tb, file_) - python_fmt = file_.getvalue() - else: - raise Error("unable to create test traceback string") - - # Make sure that Python and the traceback module format the same thing - self.assertEquals(traceback_fmt, python_fmt) - + def test_traceback_indentation(self): # Make sure that the traceback is properly indented. - tb_lines = python_fmt.splitlines() + tb_lines = example_traceback.splitlines() self.assertEquals(len(tb_lines), 3) banner, location, source_line = tb_lines self.assert_(banner.startswith('Traceback')) Modified: python/branches/release26-maint/Lib/traceback.py ============================================================================== --- python/branches/release26-maint/Lib/traceback.py (original) +++ python/branches/release26-maint/Lib/traceback.py Tue Apr 7 16:33:53 2009 @@ -64,7 +64,7 @@ filename = co.co_filename name = co.co_name _print(file, - ' File "%s", line %d, in %s' % (filename, lineno, name)) + ' File "%s", line %d, in %s' % (filename,lineno,name)) linecache.checkcache(filename) line = linecache.getline(filename, lineno, f.f_globals) if line: _print(file, ' ' + line.strip()) @@ -124,8 +124,9 @@ _print(file, 'Traceback (most recent call last):') print_tb(tb, limit, file) lines = format_exception_only(etype, value) - for line in lines: - _print(file, line, '') + for line in lines[:-1]: + _print(file, line, ' ') + _print(file, lines[-1], '') def format_exception(etype, value, tb, limit = None): """Format a stack trace and the exception information. @@ -194,7 +195,7 @@ caretspace = ((c.isspace() and c or ' ') for c in caretspace) # only three spaces to account for offset1 == pos 0 lines.append(' %s^\n' % ''.join(caretspace)) - value = msg + value = msg lines.append(_format_final_exc_line(stype, value)) return lines From python-checkins at python.org Tue Apr 7 16:48:10 2009 From: python-checkins at python.org (matthias.klose) Date: Tue, 7 Apr 2009 16:48:10 +0200 (CEST) Subject: [Python-checkins] r71359 - in python/branches/release30-maint: Lib/xmlrpc/server.py Misc/NEWS Message-ID: <20090407144810.B85731E403E@bag.python.org> Author: matthias.klose Date: Tue Apr 7 16:48:10 2009 New Revision: 71359 Log: Merged revisions 71355 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71355 | matthias.klose | 2009-04-07 15:13:10 +0200 (Di, 07 Apr 2009) | 10 lines Merged revisions 71268 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71268 | matthias.klose | 2009-04-05 23:00:48 +0200 (So, 05 Apr 2009) | 3 lines - Issue #2703: SimpleXMLRPCDispatcher.__init__: Provide default values for new arguments introduced in 2.5. ........ ................ Modified: python/branches/release30-maint/Lib/xmlrpc/server.py python/branches/release30-maint/Misc/NEWS Modified: python/branches/release30-maint/Lib/xmlrpc/server.py ============================================================================== --- python/branches/release30-maint/Lib/xmlrpc/server.py (original) +++ python/branches/release30-maint/Lib/xmlrpc/server.py Tue Apr 7 16:48:10 2009 @@ -159,7 +159,7 @@ reason to instantiate this class directly. """ - def __init__(self, allow_none, encoding): + def __init__(self, allow_none=False, encoding=None): self.funcs = {} self.instance = None self.allow_none = allow_none Modified: python/branches/release30-maint/Misc/NEWS ============================================================================== --- python/branches/release30-maint/Misc/NEWS (original) +++ python/branches/release30-maint/Misc/NEWS Tue Apr 7 16:48:10 2009 @@ -92,6 +92,9 @@ - Issue #4524: distutils build_script command failed with --with-suffix=3. Initial patch by Amaury Forgeot d'Arc. +- Issue #2703: SimpleXMLRPCDispatcher.__init__: Provide default values for + new arguments introduced in 2.5. + Build ----- From python-checkins at python.org Tue Apr 7 16:50:24 2009 From: python-checkins at python.org (matthias.klose) Date: Tue, 7 Apr 2009 16:50:24 +0200 (CEST) Subject: [Python-checkins] r71360 - in python/branches/release30-maint: Misc/NEWS setup.py Message-ID: <20090407145024.79F381E446C@bag.python.org> Author: matthias.klose Date: Tue Apr 7 16:50:24 2009 New Revision: 71360 Log: Merged revisions 71357 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r71357 | matthias.klose | 2009-04-07 15:49:45 +0200 (Di, 07 Apr 2009) | 3 lines - Issue #5359: Readd the Berkley-DB detection code to allow _dbm be built using Berkley-DB. ........ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Misc/NEWS python/branches/release30-maint/setup.py Modified: python/branches/release30-maint/Misc/NEWS ============================================================================== --- python/branches/release30-maint/Misc/NEWS (original) +++ python/branches/release30-maint/Misc/NEWS Tue Apr 7 16:50:24 2009 @@ -100,6 +100,9 @@ - Link the shared python library with $(MODLIBS). +- Issue #5359: Readd the Berkley-DB detection code to allow _dbm be built + using Berkley-DB. + What's New in Python 3.0.1? =========================== Modified: python/branches/release30-maint/setup.py ============================================================================== --- python/branches/release30-maint/setup.py (original) +++ python/branches/release30-maint/setup.py Tue Apr 7 16:50:24 2009 @@ -5,6 +5,7 @@ import sys, os, imp, re, optparse from glob import glob +from platform import machine as platform_machine from distutils import log from distutils import sysconfig @@ -665,6 +666,49 @@ # implementation independent wrapper for these; dbm/dumb.py provides # similar functionality (but slower of course) implemented in Python. + # Sleepycat^WOracle Berkeley DB interface. + # http://www.oracle.com/database/berkeley-db/db/index.html + # + # This requires the Sleepycat^WOracle DB code. The supported versions + # are set below. Visit the URL above to download + # a release. Most open source OSes come with one or more + # versions of BerkeleyDB already installed. + + max_db_ver = (4, 7) + min_db_ver = (3, 3) + db_setup_debug = False # verbose debug prints from this script? + + def allow_db_ver(db_ver): + """Returns a boolean if the given BerkeleyDB version is acceptable. + + Args: + db_ver: A tuple of the version to verify. + """ + if not (min_db_ver <= db_ver <= max_db_ver): + return False + # Use this function to filter out known bad configurations. + if (4, 6) == db_ver[:2]: + # BerkeleyDB 4.6.x is not stable on many architectures. + arch = platform_machine() + if arch not in ('i386', 'i486', 'i586', 'i686', + 'x86_64', 'ia64'): + return False + return True + + def gen_db_minor_ver_nums(major): + if major == 4: + for x in range(max_db_ver[1]+1): + if allow_db_ver((4, x)): + yield x + elif major == 3: + for x in (3,): + if allow_db_ver((3, x)): + yield x + else: + raise ValueError("unknown major BerkeleyDB version", major) + + # construct a list of paths to look for the header file in on + # top of the normal inc_dirs. db_inc_paths = [ '/usr/include/db4', '/usr/local/include/db4', @@ -676,8 +720,124 @@ '/sw/include/db4', '/sw/include/db3', ] + # 4.x minor number specific paths + for x in gen_db_minor_ver_nums(4): + db_inc_paths.append('/usr/include/db4%d' % x) + db_inc_paths.append('/usr/include/db4.%d' % x) + db_inc_paths.append('/usr/local/BerkeleyDB.4.%d/include' % x) + db_inc_paths.append('/usr/local/include/db4%d' % x) + db_inc_paths.append('/pkg/db-4.%d/include' % x) + db_inc_paths.append('/opt/db-4.%d/include' % x) + # MacPorts default (http://www.macports.org/) + db_inc_paths.append('/opt/local/include/db4%d' % x) + # 3.x minor number specific paths + for x in gen_db_minor_ver_nums(3): + db_inc_paths.append('/usr/include/db3%d' % x) + db_inc_paths.append('/usr/local/BerkeleyDB.3.%d/include' % x) + db_inc_paths.append('/usr/local/include/db3%d' % x) + db_inc_paths.append('/pkg/db-3.%d/include' % x) + db_inc_paths.append('/opt/db-3.%d/include' % x) + + # Add some common subdirectories for Sleepycat DB to the list, + # based on the standard include directories. This way DB3/4 gets + # picked up when it is installed in a non-standard prefix and + # the user has added that prefix into inc_dirs. + std_variants = [] + for dn in inc_dirs: + std_variants.append(os.path.join(dn, 'db3')) + std_variants.append(os.path.join(dn, 'db4')) + for x in gen_db_minor_ver_nums(4): + std_variants.append(os.path.join(dn, "db4%d"%x)) + std_variants.append(os.path.join(dn, "db4.%d"%x)) + for x in gen_db_minor_ver_nums(3): + std_variants.append(os.path.join(dn, "db3%d"%x)) + std_variants.append(os.path.join(dn, "db3.%d"%x)) + + db_inc_paths = std_variants + db_inc_paths + db_inc_paths = [p for p in db_inc_paths if os.path.exists(p)] + + db_ver_inc_map = {} + + class db_found(Exception): pass + try: + # See whether there is a Sleepycat header in the standard + # search path. + for d in inc_dirs + db_inc_paths: + f = os.path.join(d, "db.h") + if db_setup_debug: print("db: looking for db.h in", f) + if os.path.exists(f): + f = open(f).read() + m = re.search(r"#define\WDB_VERSION_MAJOR\W(\d+)", f) + if m: + db_major = int(m.group(1)) + m = re.search(r"#define\WDB_VERSION_MINOR\W(\d+)", f) + db_minor = int(m.group(1)) + db_ver = (db_major, db_minor) + + # Avoid 4.6 prior to 4.6.21 due to a BerkeleyDB bug + if db_ver == (4, 6): + m = re.search(r"#define\WDB_VERSION_PATCH\W(\d+)", f) + db_patch = int(m.group(1)) + if db_patch < 21: + print("db.h:", db_ver, "patch", db_patch, + "being ignored (4.6.x must be >= 4.6.21)") + continue + + if ( (db_ver not in db_ver_inc_map) and + allow_db_ver(db_ver) ): + # save the include directory with the db.h version + # (first occurrence only) + db_ver_inc_map[db_ver] = d + if db_setup_debug: + print("db.h: found", db_ver, "in", d) + else: + # we already found a header for this library version + if db_setup_debug: print("db.h: ignoring", d) + else: + # ignore this header, it didn't contain a version number + if db_setup_debug: + print("db.h: no version number version in", d) + + db_found_vers = list(db_ver_inc_map.keys()) + db_found_vers.sort() + + while db_found_vers: + db_ver = db_found_vers.pop() + db_incdir = db_ver_inc_map[db_ver] + + # check lib directories parallel to the location of the header + db_dirs_to_check = [ + db_incdir.replace("include", 'lib64'), + db_incdir.replace("include", 'lib'), + ] + db_dirs_to_check = list(filter(os.path.isdir, db_dirs_to_check)) + + # Look for a version specific db-X.Y before an ambiguoius dbX + # XXX should we -ever- look for a dbX name? Do any + # systems really not name their library by version and + # symlink to more general names? + for dblib in (('db-%d.%d' % db_ver), + ('db%d%d' % db_ver), + ('db%d' % db_ver[0])): + dblib_file = self.compiler.find_library_file( + db_dirs_to_check + lib_dirs, dblib ) + if dblib_file: + dblib_dir = [ os.path.abspath(os.path.dirname(dblib_file)) ] + raise db_found + else: + if db_setup_debug: print("db lib: ", dblib, "not found") - db_incs = None + except db_found: + if db_setup_debug: + print("bsddb using BerkeleyDB lib:", db_ver, dblib) + print("bsddb lib dir:", dblib_dir, " inc dir:", db_incdir) + db_incs = [db_incdir] + dblibs = [dblib] + else: + if db_setup_debug: print("db: no appropriate library found") + db_incs = None + dblibs = [] + dblib_dir = None # The sqlite interface sqlite_setup_debug = False # verbose debug prints from this script? From buildbot at python.org Tue Apr 7 16:58:34 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 14:58:34 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 3.0 Message-ID: <20090407145834.B42191E4103@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%203.0/builds/282 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From buildbot at python.org Tue Apr 7 17:04:18 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 15:04:18 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 3.0 Message-ID: <20090407150418.BDA481E44FE@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%20gentoo%203.0/builds/232 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-amd64 Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From buildbot at python.org Tue Apr 7 17:04:25 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 15:04:25 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 3.0 Message-ID: <20090407150425.477861E43F7@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%203.0/builds/252 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From python-checkins at python.org Tue Apr 7 17:15:05 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 7 Apr 2009 17:15:05 +0200 (CEST) Subject: [Python-checkins] r71361 - in python/trunk/Lib/test: test_genexps.py test_syntax.py Message-ID: <20090407151505.85EAF1E4074@bag.python.org> Author: benjamin.peterson Date: Tue Apr 7 17:15:04 2009 New Revision: 71361 Log: fix syntax tests after formatting change Modified: python/trunk/Lib/test/test_genexps.py python/trunk/Lib/test/test_syntax.py Modified: python/trunk/Lib/test/test_genexps.py ============================================================================== --- python/trunk/Lib/test/test_genexps.py (original) +++ python/trunk/Lib/test/test_genexps.py Tue Apr 7 17:15:04 2009 @@ -137,12 +137,14 @@ >>> (y for y in (1,2)) = 10 Traceback (most recent call last): ... - SyntaxError: can't assign to generator expression (, line 1) + File "", line 1 + SyntaxError: can't assign to generator expression >>> (y for y in (1,2)) += 10 Traceback (most recent call last): ... - SyntaxError: augmented assignment to generator expression not possible (, line 1) + File "", line 1 + SyntaxError: augmented assignment to generator expression not possible ########### Tests borrowed from or inspired by test_generators.py ############ Modified: python/trunk/Lib/test/test_syntax.py ============================================================================== --- python/trunk/Lib/test/test_syntax.py (original) +++ python/trunk/Lib/test/test_syntax.py Tue Apr 7 17:15:04 2009 @@ -29,11 +29,13 @@ >>> obj.None = 1 Traceback (most recent call last): -SyntaxError: cannot assign to None (, line 1) + File "", line 1 +SyntaxError: cannot assign to None >>> None = 1 Traceback (most recent call last): -SyntaxError: cannot assign to None (, line 1) + File "", line 1 +SyntaxError: cannot assign to None It's a syntax error to assign to the empty tuple. Why isn't it an error to assign to the empty list? It will always raise some error at @@ -41,35 +43,43 @@ >>> () = 1 Traceback (most recent call last): -SyntaxError: can't assign to () (, line 1) + File "", line 1 +SyntaxError: can't assign to () >>> f() = 1 Traceback (most recent call last): -SyntaxError: can't assign to function call (, line 1) + File "", line 1 +SyntaxError: can't assign to function call >>> del f() Traceback (most recent call last): -SyntaxError: can't delete function call (, line 1) + File "", line 1 +SyntaxError: can't delete function call >>> a + 1 = 2 Traceback (most recent call last): -SyntaxError: can't assign to operator (, line 1) + File "", line 1 +SyntaxError: can't assign to operator >>> (x for x in x) = 1 Traceback (most recent call last): -SyntaxError: can't assign to generator expression (, line 1) + File "", line 1 +SyntaxError: can't assign to generator expression >>> 1 = 1 Traceback (most recent call last): -SyntaxError: can't assign to literal (, line 1) + File "", line 1 +SyntaxError: can't assign to literal >>> "abc" = 1 Traceback (most recent call last): -SyntaxError: can't assign to literal (, line 1) + File "", line 1 +SyntaxError: can't assign to literal >>> `1` = 1 Traceback (most recent call last): -SyntaxError: can't assign to repr (, line 1) + File "", line 1 +SyntaxError: can't assign to repr If the left-hand side of an assignment is a list or tuple, an illegal expression inside that contain should still cause a syntax error. @@ -78,22 +88,26 @@ >>> (a, "b", c) = (1, 2, 3) Traceback (most recent call last): -SyntaxError: can't assign to literal (, line 1) + File "", line 1 +SyntaxError: can't assign to literal >>> [a, b, c + 1] = [1, 2, 3] Traceback (most recent call last): -SyntaxError: can't assign to operator (, line 1) + File "", line 1 +SyntaxError: can't assign to operator >>> a if 1 else b = 1 Traceback (most recent call last): -SyntaxError: can't assign to conditional expression (, line 1) + File "", line 1 +SyntaxError: can't assign to conditional expression From compiler_complex_args(): >>> def f(None=1): ... pass Traceback (most recent call last): -SyntaxError: cannot assign to None (, line 1) + File "", line 1 +SyntaxError: cannot assign to None From ast_for_arguments(): @@ -101,22 +115,26 @@ >>> def f(x, y=1, z): ... pass Traceback (most recent call last): -SyntaxError: non-default argument follows default argument (, line 1) + File "", line 1 +SyntaxError: non-default argument follows default argument >>> def f(x, None): ... pass Traceback (most recent call last): -SyntaxError: cannot assign to None (, line 1) + File "", line 1 +SyntaxError: cannot assign to None >>> def f(*None): ... pass Traceback (most recent call last): -SyntaxError: cannot assign to None (, line 1) + File "", line 1 +SyntaxError: cannot assign to None >>> def f(**None): ... pass Traceback (most recent call last): -SyntaxError: cannot assign to None (, line 1) + File "", line 1 +SyntaxError: cannot assign to None From ast_for_funcdef(): @@ -124,7 +142,8 @@ >>> def None(x): ... pass Traceback (most recent call last): -SyntaxError: cannot assign to None (, line 1) + File "", line 1 +SyntaxError: cannot assign to None From ast_for_call(): @@ -136,7 +155,8 @@ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> f(x for x in L, 1) Traceback (most recent call last): -SyntaxError: Generator expression must be parenthesized if not sole argument (, line 1) + File "", line 1 +SyntaxError: Generator expression must be parenthesized if not sole argument >>> f((x for x in L), 1) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] @@ -168,7 +188,8 @@ ... i244, i245, i246, i247, i248, i249, i250, i251, i252, ... i253, i254, i255) Traceback (most recent call last): -SyntaxError: more than 255 arguments (, line 1) + File "", line 1 +SyntaxError: more than 255 arguments The actual error cases counts positional arguments, keyword arguments, and generator expression arguments separately. This test combines the @@ -202,37 +223,45 @@ ... (x for x in i244), i245, i246, i247, i248, i249, i250, i251, ... i252=1, i253=1, i254=1, i255=1) Traceback (most recent call last): -SyntaxError: more than 255 arguments (, line 1) + File "", line 1 +SyntaxError: more than 255 arguments >>> f(lambda x: x[0] = 3) Traceback (most recent call last): -SyntaxError: lambda cannot contain assignment (, line 1) + File "", line 1 +SyntaxError: lambda cannot contain assignment The grammar accepts any test (basically, any expression) in the keyword slot of a call site. Test a few different options. >>> f(x()=2) Traceback (most recent call last): -SyntaxError: keyword can't be an expression (, line 1) + File "", line 1 +SyntaxError: keyword can't be an expression >>> f(a or b=1) Traceback (most recent call last): -SyntaxError: keyword can't be an expression (, line 1) + File "", line 1 +SyntaxError: keyword can't be an expression >>> f(x.y=1) Traceback (most recent call last): -SyntaxError: keyword can't be an expression (, line 1) + File "", line 1 +SyntaxError: keyword can't be an expression From ast_for_expr_stmt(): >>> (x for x in x) += 1 Traceback (most recent call last): -SyntaxError: augmented assignment to generator expression not possible (, line 1) + File "", line 1 +SyntaxError: augmented assignment to generator expression not possible >>> None += 1 Traceback (most recent call last): -SyntaxError: cannot assign to None (, line 1) + File "", line 1 +SyntaxError: cannot assign to None >>> f() += 1 Traceback (most recent call last): -SyntaxError: illegal expression for augmented assignment (, line 1) + File "", line 1 +SyntaxError: illegal expression for augmented assignment Test continue in finally in weird combinations. @@ -259,7 +288,8 @@ ... continue Traceback (most recent call last): ... - SyntaxError: 'continue' not supported inside 'finally' clause (, line 6) + File "", line 6 + SyntaxError: 'continue' not supported inside 'finally' clause This is essentially a continue in a finally which should not be allowed. @@ -274,7 +304,8 @@ ... pass Traceback (most recent call last): ... - SyntaxError: 'continue' not supported inside 'finally' clause (, line 7) + File "", line 6 + SyntaxError: 'continue' not supported inside 'finally' clause >>> def foo(): ... try: @@ -283,7 +314,8 @@ ... continue Traceback (most recent call last): ... - SyntaxError: 'continue' not supported inside 'finally' clause (, line 5) + File "", line 5 + SyntaxError: 'continue' not supported inside 'finally' clause >>> def foo(): ... for a in (): @@ -293,7 +325,8 @@ ... continue Traceback (most recent call last): ... - SyntaxError: 'continue' not supported inside 'finally' clause (, line 6) + File "", line 6 + SyntaxError: 'continue' not supported inside 'finally' clause >>> def foo(): ... for a in (): @@ -306,7 +339,8 @@ ... pass Traceback (most recent call last): ... - SyntaxError: 'continue' not supported inside 'finally' clause (, line 7) + File "", line 7 + SyntaxError: 'continue' not supported inside 'finally' clause >>> def foo(): ... for a in (): @@ -318,7 +352,8 @@ ... continue Traceback (most recent call last): ... - SyntaxError: 'continue' not supported inside 'finally' clause (, line 8) + File "", line 8 + SyntaxError: 'continue' not supported inside 'finally' clause There is one test for a break that is not in a loop. The compiler uses a single data structure to keep track of try-finally and loops, @@ -333,7 +368,8 @@ ... print 3 Traceback (most recent call last): ... - SyntaxError: 'break' outside loop (, line 3) + File "", line 3 + SyntaxError: 'break' outside loop This should probably raise a better error than a SystemError (or none at all). In 2.5 there was a missing exception and an assert was triggered in a debug @@ -375,7 +411,8 @@ ... pass Traceback (most recent call last): ... - SyntaxError: can't assign to function call (, line 2) + File "", line 2 + SyntaxError: can't assign to function call >>> if 1: ... pass @@ -383,7 +420,8 @@ ... x() = 1 Traceback (most recent call last): ... - SyntaxError: can't assign to function call (, line 4) + File "", line 4 + SyntaxError: can't assign to function call >>> if 1: ... x() = 1 @@ -393,7 +431,8 @@ ... pass Traceback (most recent call last): ... - SyntaxError: can't assign to function call (, line 2) + File "", line 2 + SyntaxError: can't assign to function call >>> if 1: ... pass @@ -403,7 +442,8 @@ ... pass Traceback (most recent call last): ... - SyntaxError: can't assign to function call (, line 4) + File "", line 4 + SyntaxError: can't assign to function call >>> if 1: ... pass @@ -413,12 +453,14 @@ ... x() = 1 Traceback (most recent call last): ... - SyntaxError: can't assign to function call (, line 6) + File "", line 6 + SyntaxError: can't assign to function call >>> f(a=23, a=234) Traceback (most recent call last): ... -SyntaxError: keyword argument repeated (, line 1) + File "", line 1 +SyntaxError: keyword argument repeated """ From python-checkins at python.org Tue Apr 7 17:15:47 2009 From: python-checkins at python.org (barry.warsaw) Date: Tue, 7 Apr 2009 17:15:47 +0200 (CEST) Subject: [Python-checkins] r71362 - python/branches/release26-maint/Misc/NEWS Message-ID: <20090407151547.BE81A1E4497@bag.python.org> Author: barry.warsaw Date: Tue Apr 7 17:15:47 2009 New Revision: 71362 Log: The back ported fix for 1326077 caused a regression and is removed from 2.6.2rc1. Modified: python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Tue Apr 7 17:15:47 2009 @@ -108,8 +108,6 @@ - Issue 5471: Fix os.path.expanduser() for $HOME set to '/'. -- Issue 1326077: fix the formatting of SyntaxErrors by the traceback module. - - Issue 1726172: fix IndexError in the case of and empty response in ftplib. - In Pdb, prevent the reassignment of __builtin__._ by sys.displayhook on From python-checkins at python.org Tue Apr 7 17:17:20 2009 From: python-checkins at python.org (barry.warsaw) Date: Tue, 7 Apr 2009 17:17:20 +0200 (CEST) Subject: [Python-checkins] r71363 - python/tags/r262c1 Message-ID: <20090407151720.81F6B1E4074@bag.python.org> Author: barry.warsaw Date: Tue Apr 7 17:17:20 2009 New Revision: 71363 Log: Retagging. Removed: python/tags/r262c1/ From buildbot at python.org Tue Apr 7 17:17:44 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 15:17:44 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 3.0 Message-ID: <20090407151744.DC0A61E4074@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%203.0/builds/204 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From python-checkins at python.org Tue Apr 7 17:17:50 2009 From: python-checkins at python.org (barry.warsaw) Date: Tue, 7 Apr 2009 17:17:50 +0200 (CEST) Subject: [Python-checkins] r71364 - python/tags/r262c1 Message-ID: <20090407151750.4DF1E1E4103@bag.python.org> Author: barry.warsaw Date: Tue Apr 7 17:17:50 2009 New Revision: 71364 Log: Retagging. Added: python/tags/r262c1/ - copied from r71363, /python/branches/release26-maint/ From buildbot at python.org Tue Apr 7 17:31:43 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 15:31:43 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.0 Message-ID: <20090407153143.85E451E4074@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.0/builds/253 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From python-checkins at python.org Tue Apr 7 17:52:05 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 7 Apr 2009 17:52:05 +0200 (CEST) Subject: [Python-checkins] r71365 - in python/trunk/Lib/test: test_generators.py test_telnetlib.py Message-ID: <20090407155205.E4BDA1E43A7@bag.python.org> Author: benjamin.peterson Date: Tue Apr 7 17:52:05 2009 New Revision: 71365 Log: fix since difference formating of SyntaxErrors Modified: python/trunk/Lib/test/test_generators.py python/trunk/Lib/test/test_telnetlib.py Modified: python/trunk/Lib/test/test_generators.py ============================================================================== --- python/trunk/Lib/test/test_generators.py (original) +++ python/trunk/Lib/test/test_generators.py Tue Apr 7 17:52:05 2009 @@ -1564,7 +1564,8 @@ >>> f=lambda: (yield 1),(yield 2) Traceback (most recent call last): ... -SyntaxError: 'yield' outside function (, line 1) + File "", line 1 +SyntaxError: 'yield' outside function >>> def f(): return lambda x=(yield): 1 Traceback (most recent call last): @@ -1574,17 +1575,20 @@ >>> def f(): x = yield = y Traceback (most recent call last): ... -SyntaxError: assignment to yield expression not possible (, line 1) + File "", line 1 +SyntaxError: assignment to yield expression not possible >>> def f(): (yield bar) = y Traceback (most recent call last): ... -SyntaxError: can't assign to yield expression (, line 1) + File "", line 1 +SyntaxError: can't assign to yield expression >>> def f(): (yield bar) += y Traceback (most recent call last): ... -SyntaxError: augmented assignment to yield expression not possible (, line 1) + File "", line 1 +SyntaxError: augmented assignment to yield expression not possible Now check some throw() conditions: Modified: python/trunk/Lib/test/test_telnetlib.py ============================================================================== --- python/trunk/Lib/test/test_telnetlib.py (original) +++ python/trunk/Lib/test/test_telnetlib.py Tue Apr 7 17:52:05 2009 @@ -98,7 +98,7 @@ def _read_setUp(self): # the blocking constant should be tuned! - self.blocking_timeout = 0.0 + self.blocking_timeout = 0.1 self.evt = threading.Event() self.dataq = Queue.Queue() self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) From python-checkins at python.org Tue Apr 7 18:00:52 2009 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 7 Apr 2009 18:00:52 +0200 (CEST) Subject: [Python-checkins] r71366 - in python/branches/release26-maint: PCbuild/sqlite3.vcproj Message-ID: <20090407160052.18FBC1E4074@bag.python.org> Author: martin.v.loewis Date: Tue Apr 7 18:00:51 2009 New Revision: 71366 Log: Merged revisions 69589 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r69589 | martin.v.loewis | 2009-02-13 21:11:34 +0100 (Fr, 13 Feb 2009) | 2 lines Move amd64 properties further to the top, so that they override the linker options correctly. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/PCbuild/sqlite3.vcproj Modified: python/branches/release26-maint/PCbuild/sqlite3.vcproj ============================================================================== --- python/branches/release26-maint/PCbuild/sqlite3.vcproj (original) +++ python/branches/release26-maint/PCbuild/sqlite3.vcproj Tue Apr 7 18:00:51 2009 @@ -82,7 +82,7 @@ @@ -327,7 +327,7 @@ @@ -449,7 +449,7 @@ From python-checkins at python.org Tue Apr 7 18:03:04 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 7 Apr 2009 18:03:04 +0200 (CEST) Subject: [Python-checkins] r71367 - python/trunk/Lib/test/test_telnetlib.py Message-ID: <20090407160304.9C0761E4074@bag.python.org> Author: benjamin.peterson Date: Tue Apr 7 18:03:04 2009 New Revision: 71367 Log: revert unrelated change to test_telnetlib Modified: python/trunk/Lib/test/test_telnetlib.py Modified: python/trunk/Lib/test/test_telnetlib.py ============================================================================== --- python/trunk/Lib/test/test_telnetlib.py (original) +++ python/trunk/Lib/test/test_telnetlib.py Tue Apr 7 18:03:04 2009 @@ -98,7 +98,7 @@ def _read_setUp(self): # the blocking constant should be tuned! - self.blocking_timeout = 0.1 + self.blocking_timeout = 0.0 self.evt = threading.Event() self.dataq = Queue.Queue() self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) From python-checkins at python.org Tue Apr 7 18:08:29 2009 From: python-checkins at python.org (matthias.klose) Date: Tue, 7 Apr 2009 18:08:29 +0200 (CEST) Subject: [Python-checkins] r71368 - python/branches/py3k/setup.py Message-ID: <20090407160829.799DD1E406E@bag.python.org> Author: matthias.klose Date: Tue Apr 7 18:08:29 2009 New Revision: 71368 Log: Don't check for broken Berkley-DB versions on some platforms; the test was required for the _bsddb3 extension, not necessary for the _dbm extension. Modified: python/branches/py3k/setup.py Modified: python/branches/py3k/setup.py ============================================================================== --- python/branches/py3k/setup.py (original) +++ python/branches/py3k/setup.py Tue Apr 7 18:08:29 2009 @@ -5,7 +5,6 @@ import sys, os, imp, re, optparse from glob import glob -from platform import machine as platform_machine from distutils import log from distutils import sysconfig @@ -671,13 +670,6 @@ """ if not (min_db_ver <= db_ver <= max_db_ver): return False - # Use this function to filter out known bad configurations. - if (4, 6) == db_ver[:2]: - # BerkeleyDB 4.6.x is not stable on many architectures. - arch = platform_machine() - if arch not in ('i386', 'i486', 'i586', 'i686', - 'x86_64', 'ia64'): - return False return True def gen_db_minor_ver_nums(major): From python-checkins at python.org Tue Apr 7 18:11:56 2009 From: python-checkins at python.org (matthias.klose) Date: Tue, 7 Apr 2009 18:11:56 +0200 (CEST) Subject: [Python-checkins] r71369 - python/branches/release30-maint/setup.py Message-ID: <20090407161156.3F0161E406E@bag.python.org> Author: matthias.klose Date: Tue Apr 7 18:11:56 2009 New Revision: 71369 Log: Merged revisions 71368 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r71368 | matthias.klose | 2009-04-07 18:08:29 +0200 (Di, 07 Apr 2009) | 4 lines Don't check for broken Berkley-DB versions on some platforms; the test was required for the _bsddb3 extension, not necessary for the _dbm extension. ........ Modified: python/branches/release30-maint/setup.py Modified: python/branches/release30-maint/setup.py ============================================================================== --- python/branches/release30-maint/setup.py (original) +++ python/branches/release30-maint/setup.py Tue Apr 7 18:11:56 2009 @@ -5,7 +5,6 @@ import sys, os, imp, re, optparse from glob import glob -from platform import machine as platform_machine from distutils import log from distutils import sysconfig @@ -686,13 +685,6 @@ """ if not (min_db_ver <= db_ver <= max_db_ver): return False - # Use this function to filter out known bad configurations. - if (4, 6) == db_ver[:2]: - # BerkeleyDB 4.6.x is not stable on many architectures. - arch = platform_machine() - if arch not in ('i386', 'i486', 'i586', 'i686', - 'x86_64', 'ia64'): - return False return True def gen_db_minor_ver_nums(major): From buildbot at python.org Tue Apr 7 19:13:29 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 17:13:29 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 2.6 Message-ID: <20090407171329.973571E406E@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%202.6/builds/236 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: barry.warsaw,martin.v.loewis BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Tue Apr 7 19:18:25 2009 From: python-checkins at python.org (vinay.sajip) Date: Tue, 7 Apr 2009 19:18:25 +0200 (CEST) Subject: [Python-checkins] r71370 - python/trunk/Lib/test/test_logging.py Message-ID: <20090407171825.1E20B1E406E@bag.python.org> Author: vinay.sajip Date: Tue Apr 7 19:18:24 2009 New Revision: 71370 Log: Issue #5695: Minor tweak to improve the code as suggested by Brett Cannon and as implemented in the Py3K branch. Modified: python/trunk/Lib/test/test_logging.py Modified: python/trunk/Lib/test/test_logging.py ============================================================================== --- python/trunk/Lib/test/test_logging.py (original) +++ python/trunk/Lib/test/test_logging.py Tue Apr 7 19:18:24 2009 @@ -914,8 +914,8 @@ def test_warnings(self): with warnings.catch_warnings(): logging.captureWarnings(True) - warnings.filterwarnings("always", category=UserWarning) try: + warnings.filterwarnings("always", category=UserWarning) file = cStringIO.StringIO() h = logging.StreamHandler(file) logger = logging.getLogger("py.warnings") From python-checkins at python.org Tue Apr 7 19:20:44 2009 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 7 Apr 2009 19:20:44 +0200 (CEST) Subject: [Python-checkins] r71371 - in python/branches/release26-maint: Tools/msi/merge.py Message-ID: <20090407172044.2C1EE1E406E@bag.python.org> Author: martin.v.loewis Date: Tue Apr 7 19:20:43 2009 New Revision: 71371 Log: Merged revisions 69593 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r69593 | martin.v.loewis | 2009-02-13 21:51:48 +0100 (Fr, 13 Feb 2009) | 1 line Add optional code signing after merging. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Tools/msi/merge.py Modified: python/branches/release26-maint/Tools/msi/merge.py ============================================================================== --- python/branches/release26-maint/Tools/msi/merge.py (original) +++ python/branches/release26-maint/Tools/msi/merge.py Tue Apr 7 19:20:43 2009 @@ -1,5 +1,6 @@ import msilib,os,win32com,tempfile,sys PCBUILD="PCBuild" +certname = None from config import * Win64 = "amd64" in PCBUILD @@ -76,3 +77,8 @@ db.Commit() merge(msi, "SharedCRT", "TARGETDIR", modules) + +# certname (from config.py) should be (a substring of) +# the certificate subject, e.g. "Python Software Foundation" +if certname: + os.system('signtool sign /n "%s" /t http://timestamp.verisign.com/scripts/timestamp.dll %s' % (certname, msi)) From python-checkins at python.org Tue Apr 7 21:27:32 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 7 Apr 2009 21:27:32 +0200 (CEST) Subject: [Python-checkins] r71372 - python/branches/py3k/Makefile.pre.in Message-ID: <20090407192732.D4A811E4082@bag.python.org> Author: benjamin.peterson Date: Tue Apr 7 21:27:32 2009 New Revision: 71372 Log: don't install extras like pydoc and idle in altinstall, possibly overwriting the 2.x ones #1590 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 Tue Apr 7 21:27:32 2009 @@ -757,7 +757,7 @@ # Install almost everything without disturbing previous versions altinstall: @FRAMEWORKALTINSTALLFIRST@ altbininstall libinstall inclinstall libainstall \ - sharedinstall oldsharedinstall @FRAMEWORKALTINSTALLLAST@ + oldsharedinstall @FRAMEWORKALTINSTALLLAST@ # Install shared libraries enabled by Setup DESTDIRS= $(exec_prefix) $(LIBDIR) $(BINLIBDEST) $(DESTSHARED) From python-checkins at python.org Tue Apr 7 21:27:36 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 7 Apr 2009 21:27:36 +0200 (CEST) Subject: [Python-checkins] r71373 - in python/branches/release26-maint: Misc/build.sh Message-ID: <20090407192736.CB72D1E410C@bag.python.org> Author: benjamin.peterson Date: Tue Apr 7 21:27:36 2009 New Revision: 71373 Log: Merged revisions 71335 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71335 | benjamin.peterson | 2009-04-06 17:53:29 -0500 (Mon, 06 Apr 2009) | 1 line see if this helps the doc builds ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Misc/build.sh Modified: python/branches/release26-maint/Misc/build.sh ============================================================================== --- python/branches/release26-maint/Misc/build.sh (original) +++ python/branches/release26-maint/Misc/build.sh Tue Apr 7 21:27:36 2009 @@ -258,6 +258,7 @@ # which will definitely fail with a conflict. #CONFLICTED_FILE=commontex/boilerplate.tex #conflict_count=`grep -c "<<<" $CONFLICTED_FILE` +make clean conflict_count=0 if [ $conflict_count != 0 ]; then echo "Conflict detected in $CONFLICTED_FILE. Doc build skipped." > ../build/$F From python-checkins at python.org Tue Apr 7 21:34:09 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 7 Apr 2009 21:34:09 +0200 (CEST) Subject: [Python-checkins] r71374 - in python/branches/py3k: Misc/build.sh Message-ID: <20090407193409.3C69A1E4082@bag.python.org> Author: benjamin.peterson Date: Tue Apr 7 21:34:08 2009 New Revision: 71374 Log: Merged revisions 71335 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71335 | benjamin.peterson | 2009-04-06 17:53:29 -0500 (Mon, 06 Apr 2009) | 1 line see if this helps the doc builds ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Misc/build.sh Modified: python/branches/py3k/Misc/build.sh ============================================================================== --- python/branches/py3k/Misc/build.sh (original) +++ python/branches/py3k/Misc/build.sh Tue Apr 7 21:34:08 2009 @@ -259,6 +259,7 @@ # which will definitely fail with a conflict. #CONFLICTED_FILE=commontex/boilerplate.tex #conflict_count=`grep -c "<<<" $CONFLICTED_FILE` +make clean conflict_count=0 if [ $conflict_count != 0 ]; then echo "Conflict detected in $CONFLICTED_FILE. Doc build skipped." > ../build/$F From buildbot at python.org Tue Apr 7 21:40:15 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 19:40:15 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 2.6 Message-ID: <20090407194016.D67921E4082@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%202.6/builds/230 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: martin.v.loewis BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_bsddb3 make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Tue Apr 7 21:42:10 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 7 Apr 2009 21:42:10 +0200 (CEST) Subject: [Python-checkins] r71375 - in python/branches/release30-maint: Misc/build.sh Message-ID: <20090407194210.943631E45D9@bag.python.org> Author: benjamin.peterson Date: Tue Apr 7 21:42:10 2009 New Revision: 71375 Log: Merged revisions 71374 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71374 | benjamin.peterson | 2009-04-07 14:34:08 -0500 (Tue, 07 Apr 2009) | 9 lines Merged revisions 71335 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71335 | benjamin.peterson | 2009-04-06 17:53:29 -0500 (Mon, 06 Apr 2009) | 1 line see if this helps the doc builds ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Misc/build.sh Modified: python/branches/release30-maint/Misc/build.sh ============================================================================== --- python/branches/release30-maint/Misc/build.sh (original) +++ python/branches/release30-maint/Misc/build.sh Tue Apr 7 21:42:10 2009 @@ -259,6 +259,7 @@ # which will definitely fail with a conflict. #CONFLICTED_FILE=commontex/boilerplate.tex #conflict_count=`grep -c "<<<" $CONFLICTED_FILE` +make clean conflict_count=0 if [ $conflict_count != 0 ]; then echo "Conflict detected in $CONFLICTED_FILE. Doc build skipped." > ../build/$F From python-checkins at python.org Tue Apr 7 21:43:57 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 7 Apr 2009 21:43:57 +0200 (CEST) Subject: [Python-checkins] r71376 - python/branches/py3k/Makefile.pre.in Message-ID: <20090407194357.A20291E4082@bag.python.org> Author: benjamin.peterson Date: Tue Apr 7 21:43:57 2009 New Revision: 71376 Log: install as python3 #5461 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 Tue Apr 7 21:43:57 2009 @@ -787,7 +787,7 @@ then rm -f $(DESTDIR)$(BINDIR)/$(PYTHON); \ else true; \ fi - (cd $(DESTDIR)$(BINDIR); $(LN) python$(VERSION)$(EXE) $(PYTHON)) + (cd $(DESTDIR)$(BINDIR); $(LN) python$(VERSION)$(EXE) $(PYTHON)3) -rm -f $(DESTDIR)$(BINDIR)/python-config (cd $(DESTDIR)$(BINDIR); $(LN) -s python$(VERSION)-config python-config) From buildbot at python.org Tue Apr 7 21:57:29 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 19:57:29 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 3.x Message-ID: <20090407195730.293EC1E4019@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%203.x/builds/638 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_asynchat make: *** [buildbottest] Error 1 sincerely, -The Buildbot From nnorwitz at gmail.com Tue Apr 7 22:14:30 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 7 Apr 2009 16:14:30 -0400 Subject: [Python-checkins] Python Regression Test Failures basics (4) Message-ID: <20090407201430.GA18606@python.psfb.org> 330 tests OK. 4 tests failed: test_asyncore test_lib2to3 test_multiprocessing test_telnetlib 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ast test_asynchat test_asyncore test test_asyncore failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_asyncore.py", line 144, in test_readwrite self.assertEqual(tobj.read, True) AssertionError: False != True 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23375 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 test_lib2to3 crashed -- : No module named myfixes 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 test_multiprocessing crashed -- : cannot import name SkipTest test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18903 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test test_telnetlib failed -- errors occurred; run in verbose mode for details test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18059 refs] [17873 refs] [17873 refs] [17873 refs] [17873 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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_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 330 tests OK. 4 tests failed: test_asyncore test_lib2to3 test_multiprocessing test_telnetlib 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl [701514 refs] From python-checkins at python.org Tue Apr 7 22:22:59 2009 From: python-checkins at python.org (jack.diederich) Date: Tue, 7 Apr 2009 22:22:59 +0200 (CEST) Subject: [Python-checkins] r71377 - python/trunk/Lib/test/test_telnetlib.py Message-ID: <20090407202259.C2D5A1E4019@bag.python.org> Author: jack.diederich Date: Tue Apr 7 22:22:59 2009 New Revision: 71377 Log: eliminate more race conditions in telnetlib tests Modified: python/trunk/Lib/test/test_telnetlib.py Modified: python/trunk/Lib/test/test_telnetlib.py ============================================================================== --- python/trunk/Lib/test/test_telnetlib.py (original) +++ python/trunk/Lib/test/test_telnetlib.py Tue Apr 7 22:22:59 2009 @@ -13,8 +13,8 @@ def server(evt, serv, dataq=None): """ Open a tcp server in three steps 1) set evt to true to let the parent know we are ready - 2) [optional] write all the data in dataq to the socket - terminate when dataq.get() returns EOF_sigil + 2) [optional] if is not False, write the list of data from dataq.get() + to the socket. 3) set evt to true to let the parent know we're done """ serv.listen(5) @@ -23,15 +23,19 @@ conn, addr = serv.accept() if dataq: data = '' - new_data = dataq.get(True, 0.5) - while new_data is not EOF_sigil: - if type(new_data) == str: - data += new_data - elif type(new_data) in [int, float]: + done = False + for new_data in dataq.get(True, 0.5): + if not done: + dataq.task_done() + done = True + if new_data == EOF_sigil: + break + if type(new_data) in [int, float]: time.sleep(new_data) + else: + data += new_data written = conn.send(data) data = data[written:] - new_data = dataq.get(True, 0.5) except socket.timeout: pass finally: @@ -98,7 +102,7 @@ def _read_setUp(self): # the blocking constant should be tuned! - self.blocking_timeout = 0.0 + self.blocking_timeout = 0.3 self.evt = threading.Event() self.dataq = Queue.Queue() self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -114,19 +118,10 @@ self.evt.wait() self.thread.join() - class ReadTests(TestCase): setUp = _read_setUp tearDown = _read_tearDown - def _test_blocking(self, func): - start = time.time() - self.dataq.put(self.blocking_timeout) - self.dataq.put(EOF_sigil) - data = func() - low, high = wibble_float(self.blocking_timeout) - self.assertTrue(time.time() - start >= low) - def test_read_until_A(self): """ read_until(expected, [timeout]) @@ -134,23 +129,19 @@ hit (default is no timeout); may block. """ want = ['x' * 10, 'match', 'y' * 10, EOF_sigil] - for item in want: - self.dataq.put(item) + self.dataq.put(want) telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() data = telnet.read_until('match') self.assertEqual(data, ''.join(want[:-2])) def test_read_until_B(self): # test the timeout - it does NOT raise socket.timeout want = ['hello', self.blocking_timeout, EOF_sigil] - for item in want: - self.dataq.put(item) + self.dataq.put(want) telnet = telnetlib.Telnet(HOST, self.port) - start = time.time() - timeout = self.blocking_timeout / 2 - data = telnet.read_until('not seen', timeout) - low, high = wibble_float(timeout) - self.assertTrue(low <= time.time() - high) + self.dataq.join() + data = telnet.read_until('not seen') self.assertEqual(data, want[0]) def test_read_all_A(self): @@ -159,16 +150,31 @@ Read all data until EOF; may block. """ want = ['x' * 500, 'y' * 500, 'z' * 500, EOF_sigil] - for item in want: - self.dataq.put(item) + self.dataq.put(want) telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() data = telnet.read_all() self.assertEqual(data, ''.join(want[:-1])) return + def _test_blocking(self, func): + self.dataq.put([self.blocking_timeout, EOF_sigil]) + self.dataq.join() + start = time.time() + data = func() + low, high = wibble_float(self.blocking_timeout) + self.assertTrue(low <= time.time() - start) + def test_read_all_B(self): self._test_blocking(telnetlib.Telnet(HOST, self.port).read_all) + def test_read_all_C(self): + self.dataq.put([EOF_sigil]) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + telnet.read_all() + telnet.read_all() # shouldn't raise + def test_read_some_A(self): """ read_some() @@ -176,19 +182,20 @@ """ # test 'at least one byte' want = ['x' * 500, EOF_sigil] - for item in want: - self.dataq.put(item) + self.dataq.put(want) telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() data = telnet.read_all() self.assertTrue(len(data) >= 1) def test_read_some_B(self): # test EOF - self.dataq.put(EOF_sigil) + self.dataq.put([EOF_sigil]) telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() self.assertEqual('', telnet.read_some()) - def test_read_all_C(self): + def test_read_some_C(self): self._test_blocking(telnetlib.Telnet(HOST, self.port).read_some) def _test_read_any_eager_A(self, func_name): @@ -200,26 +207,24 @@ # this never blocks so it should return eat part in turn want = ['x' * 100, self.blocking_timeout/2, 'y' * 100, EOF_sigil] expects = want[0] + want[2] - for item in want: - self.dataq.put(item) + self.dataq.put(want) telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() func = getattr(telnet, func_name) - time.sleep(self.blocking_timeout/10) data = '' while True: try: data += func() self.assertTrue(expects.startswith(data)) - time.sleep(self.blocking_timeout) except EOFError: break self.assertEqual(expects, data) def _test_read_any_eager_B(self, func_name): # test EOF - self.dataq.put(EOF_sigil) - time.sleep(self.blocking_timeout / 10) + self.dataq.put([EOF_sigil]) telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() func = getattr(telnet, func_name) self.assertRaises(EOFError, func) @@ -238,14 +243,14 @@ def _test_read_any_lazy_A(self, func_name): want = [self.blocking_timeout/2, 'x' * 100, EOF_sigil] - for item in want: - self.dataq.put(item) + self.dataq.put(want) telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() func = getattr(telnet, func_name) self.assertEqual('', func()) data = '' while True: - time.sleep(self.blocking_timeout) + time.sleep(0.0) try: telnet.fill_rawq() data += func() @@ -257,10 +262,11 @@ return data, want[1] def _test_read_any_lazy_B(self, func_name): - self.dataq.put(EOF_sigil) + self.dataq.put([EOF_sigil]) telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() func = getattr(telnet, func_name) - time.sleep(self.blocking_timeout/10) + time.sleep(0.0) telnet.fill_rawq() self.assertRaises(EOFError, func) @@ -298,12 +304,11 @@ def _test_command(self, data): """ helper for testing IAC + cmd """ self.setUp() - for item in data: - self.dataq.put(item) + self.dataq.put(data) telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() nego = nego_collector() telnet.set_option_negotiation_callback(nego.do_nego) - time.sleep(self.blocking_timeout/10) txt = telnet.read_all() cmd = nego.seen self.assertTrue(len(cmd) > 0) # we expect at least one command @@ -314,8 +319,9 @@ def test_IAC_commands(self): # reset our setup - self.dataq.put(EOF_sigil) + self.dataq.put([EOF_sigil]) telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() self.tearDown() for cmd in self.cmds: @@ -324,6 +330,7 @@ self._test_command([tl.IAC + cmd, EOF_sigil]) # all at once self._test_command([tl.IAC + cmd for (cmd) in self.cmds] + [EOF_sigil]) + self.assertEqual('', telnet.read_sb_data()) def test_SB_commands(self): # RFC 855, subnegotiations portion @@ -334,16 +341,16 @@ tl.IAC + tl.SB + 'cc' + tl.IAC + tl.IAC + 'dd' + tl.IAC + tl.SE, EOF_sigil, ] - for item in send: - self.dataq.put(item) + self.dataq.put(send) telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() nego = nego_collector(telnet.read_sb_data) telnet.set_option_negotiation_callback(nego.do_nego) - time.sleep(self.blocking_timeout/10) txt = telnet.read_all() self.assertEqual(txt, '') want_sb_data = tl.IAC + tl.IAC + 'aabb' + tl.IAC + 'cc' + tl.IAC + 'dd' self.assertEqual(nego.sb_seen, want_sb_data) + self.assertEqual('', telnet.read_sb_data()) def test_main(verbose=None): test_support.run_unittest(GeneralTests, ReadTests, OptionTests) From buildbot at python.org Tue Apr 7 22:24:53 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 20:24:53 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 2.6 Message-ID: <20090407202453.B9F851E4019@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%202.6/builds/238 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: benjamin.peterson BUILD FAILED: failed test Excerpt from the test logfile: Traceback (most recent call last): File "/Users/buildbot/buildarea/2.6.heller-x86-osx5/build/Lib/threading.py", line 525, in __bootstrap_inner self.run() File "/Users/buildbot/buildarea/2.6.heller-x86-osx5/build/Lib/test/test_ftplib.py", line 203, in run asyncore.loop(timeout=0.1, count=1) File "/Users/buildbot/buildarea/2.6.heller-x86-osx5/build/Lib/asyncore.py", line 204, in loop poll_fun(timeout, map) File "/Users/buildbot/buildarea/2.6.heller-x86-osx5/build/Lib/asyncore.py", line 141, in poll read(obj) File "/Users/buildbot/buildarea/2.6.heller-x86-osx5/build/Lib/asyncore.py", line 78, in read obj.handle_error() File "/Users/buildbot/buildarea/2.6.heller-x86-osx5/build/Lib/asyncore.py", line 74, in read obj.handle_read_event() File "/Users/buildbot/buildarea/2.6.heller-x86-osx5/build/Lib/asyncore.py", line 413, in handle_read_event self.handle_read() File "/Users/buildbot/buildarea/2.6.heller-x86-osx5/build/Lib/test/test_ssl.py", line 408, in handle_read self.send(data.lower()) File "/Users/buildbot/buildarea/2.6.heller-x86-osx5/build/Lib/asyncore.py", line 519, in send self.initiate_send() File "/Users/buildbot/buildarea/2.6.heller-x86-osx5/build/Lib/asyncore.py", line 506, in initiate_send num_sent = dispatcher.send(self, self.out_buffer[:512]) File "/Users/buildbot/buildarea/2.6.heller-x86-osx5/build/Lib/asyncore.py", line 349, in send result = self.socket.send(data) File "/Users/buildbot/buildarea/2.6.heller-x86-osx5/build/Lib/socket.py", line 165, in _dummy raise error(EBADF, 'Bad file descriptor') error: [Errno 9] Bad file descriptor 1 test failed: test_ftplib make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Tue Apr 7 22:57:09 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 20:57:09 +0000 Subject: [Python-checkins] buildbot failure in amd64 gentoo 3.x Message-ID: <20090407205709.763791E4019@bag.python.org> The Buildbot has detected a new failure of amd64 gentoo 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/amd64%20gentoo%203.x/builds/601 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-amd64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_smtplib make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Tue Apr 7 23:02:09 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 21:02:09 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 3.x Message-ID: <20090407210209.3F95F1E4019@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%203.x/builds/699 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Tue Apr 7 23:19:16 2009 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 7 Apr 2009 23:19:16 +0200 (CEST) Subject: [Python-checkins] r71378 - python/branches/py3k/Doc/make.bat Message-ID: <20090407211916.4EDCB1E406E@bag.python.org> Author: raymond.hettinger Date: Tue Apr 7 23:19:16 2009 New Revision: 71378 Log: Fix make.bat to match makefile changes Modified: python/branches/py3k/Doc/make.bat Modified: python/branches/py3k/Doc/make.bat ============================================================================== --- python/branches/py3k/Doc/make.bat (original) +++ python/branches/py3k/Doc/make.bat Tue Apr 7 23:19:16 2009 @@ -33,7 +33,7 @@ goto end :checkout -svn co %SVNROOT%/doctools/trunk/sphinx tools/sphinx +svn co %SVNROOT%/external/Sphinx-0.6.1/sphinx tools/sphinx svn co %SVNROOT%/external/docutils-0.5/docutils tools/docutils svn co %SVNROOT%/external/Jinja-2.1.1/jinja2 tools/jinja2 svn co %SVNROOT%/external/Pygments-0.11.1/pygments tools/pygments @@ -50,6 +50,7 @@ if not exist build mkdir build if not exist build\%1 mkdir build\%1 if not exist build\doctrees mkdir build\doctrees +cmd /C %PYTHON% --version cmd /C %PYTHON% tools\sphinx-build.py -b%1 -dbuild\doctrees . build\%* if "%1" EQU "htmlhelp" "%HTMLHELP%" build\htmlhelp\pydoc.hhp goto end From python-checkins at python.org Tue Apr 7 23:27:30 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 7 Apr 2009 23:27:30 +0200 (CEST) Subject: [Python-checkins] r71379 - python/branches/py3k/Tools/msi/msilib.py Message-ID: <20090407212730.47E041E406E@bag.python.org> Author: georg.brandl Date: Tue Apr 7 23:27:29 2009 New Revision: 71379 Log: Revert 3k change to msilib, which is executed with Python 2.x. Modified: python/branches/py3k/Tools/msi/msilib.py Modified: python/branches/py3k/Tools/msi/msilib.py ============================================================================== --- python/branches/py3k/Tools/msi/msilib.py (original) +++ python/branches/py3k/Tools/msi/msilib.py Tue Apr 7 23:27:29 2009 @@ -5,7 +5,7 @@ import win32com.client import pythoncom, pywintypes from win32com.client import constants -import re, string, os, sets, glob, subprocess, sys, winreg, struct +import re, string, os, sets, glob, subprocess, sys, _winreg, struct try: basestring @@ -387,9 +387,9 @@ (r"Software\Microsoft\Win32SDK\Directories", "Install Dir"), ]: try: - key = winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, k) - dir = winreg.QueryValueEx(key, v)[0] - winreg.CloseKey(key) + key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, k) + dir = _winreg.QueryValueEx(key, v)[0] + _winreg.CloseKey(key) except (WindowsError, IndexError): continue cabarc = os.path.join(dir, r"Bin", "cabarc.exe") From python-checkins at python.org Tue Apr 7 23:28:34 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 7 Apr 2009 23:28:34 +0200 (CEST) Subject: [Python-checkins] r70943 - svn:log Message-ID: <20090407212834.A51871E4430@bag.python.org> Author: georg.brandl Revision: 70943 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -1,7 +1 @@ -Merged revisions 70940 via svnmerge - -........ - r70940 | georg.brandl | 2009-03-31 23:21:14 -0500 (Di, 31 M?r 2009) | 2 lines - - The SimpleXMLRPCServer's CGI handler now runs like a pony. -........ +#5624: _winreg is winreg in Python 3. From python-checkins at python.org Tue Apr 7 23:43:51 2009 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 7 Apr 2009 23:43:51 +0200 (CEST) Subject: [Python-checkins] r71380 - python/trunk/Doc/make.bat Message-ID: <20090407214351.761411E406E@bag.python.org> Author: raymond.hettinger Date: Tue Apr 7 23:43:51 2009 New Revision: 71380 Log: Fix make.bat to match makefile changes Modified: python/trunk/Doc/make.bat Modified: python/trunk/Doc/make.bat ============================================================================== --- python/trunk/Doc/make.bat (original) +++ python/trunk/Doc/make.bat Tue Apr 7 23:43:51 2009 @@ -34,7 +34,7 @@ goto end :checkout -svn co %SVNROOT%/doctools/trunk/sphinx tools/sphinx +svn co %SVNROOT%/external/Sphinx-0.6.1/sphinx tools/sphinx svn co %SVNROOT%/external/docutils-0.5/docutils tools/docutils svn co %SVNROOT%/external/Jinja-2.1.1/jinja2 tools/jinja2 svn co %SVNROOT%/external/Pygments-0.11.1/pygments tools/pygments From python-checkins at python.org Tue Apr 7 23:44:28 2009 From: python-checkins at python.org (eric.smith) Date: Tue, 7 Apr 2009 23:44:28 +0200 (CEST) Subject: [Python-checkins] r71381 - python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Message-ID: <20090407214428.7732F1E406E@bag.python.org> Author: eric.smith Date: Tue Apr 7 23:44:28 2009 New Revision: 71381 Log: Slowly refactoring in order to support locales and commas. Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h (original) +++ python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Tue Apr 7 23:44:28 2009 @@ -346,6 +346,18 @@ spec->n_spadding + n_digits + spec->n_rpadding; } +/* Fill in the digit parts of a numbers's string representation, + as determined in calc_number_widths(). */ +static void +fill_digits(STRINGLIB_CHAR *p_buf, const NumberFieldWidths *spec, + STRINGLIB_CHAR *p_digits, Py_ssize_t n_digits) +{ + memmove(p_buf + + (spec->n_lpadding + spec->n_sign + spec->n_spadding), + p_digits, + n_digits * sizeof(STRINGLIB_CHAR)); +} + /* fill in the non-digit parts of a numbers's string representation, as determined in calc_number_widths(). returns the pointer to where the digits go. */ @@ -902,11 +914,13 @@ --n_digits; } + /* Determine the grouping, separator, and decimal point, if any. */ get_formatting_info(use_locale, &l_decimal_point, &l_thousands_sep, &l_grouping); + /* Calculate how much space we'll need. */ calc_number_widths(&spec, sign_char, 0, n_digits, has_decimal, 0, format); - /* allocate a string with enough space */ + /* Allocate that space. */ result = STRINGLIB_NEW(NULL, spec.n_total); if (result == NULL) goto done; @@ -915,11 +929,8 @@ fill_non_digits(STRINGLIB_STR(result), &spec, NULL, n_digits, format->fill_char == '\0' ? ' ' : format->fill_char); - /* fill in the digit parts */ - memmove(STRINGLIB_STR(result) + - (spec.n_lpadding + spec.n_sign + spec.n_spadding), - p, - n_digits * sizeof(STRINGLIB_CHAR)); + /* Fill in the digit parts. */ + fill_digits(STRINGLIB_STR(result), &spec, p, n_digits); done: PyMem_Free(buf); From python-checkins at python.org Tue Apr 7 23:46:05 2009 From: python-checkins at python.org (eric.smith) Date: Tue, 7 Apr 2009 23:46:05 +0200 (CEST) Subject: [Python-checkins] r71382 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090407214605.8962C1E406E@bag.python.org> Author: eric.smith Date: Tue Apr 7 23:46:05 2009 New Revision: 71382 Log: Fixed comment. Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Tue Apr 7 23:46:05 2009 @@ -519,10 +519,10 @@ }; -/* Convert a double d to a string, and put the result into the buffer buf. +/* Convert a double d to a string, and return a PyMem_Malloc'd block of + memory contain the resulting string. Arguments: - buflen is the length of the provided buffer d is the double to be converted format_code is one of 'e', 'f', 'g', 'r' or 's'. 'e', 'f' and 'g' correspond to '%e', '%f' and '%g'; 'r' and 's' correspond From buildbot at python.org Wed Apr 8 00:40:08 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 07 Apr 2009 22:40:08 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090407224008.474601E45DE@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/256 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: benjamin.peterson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Wed Apr 8 00:55:31 2009 From: python-checkins at python.org (eric.smith) Date: Wed, 8 Apr 2009 00:55:31 +0200 (CEST) Subject: [Python-checkins] r71383 - python/branches/py3k/Python/mysnprintf.c Message-ID: <20090407225531.894EC1E4124@bag.python.org> Author: eric.smith Date: Wed Apr 8 00:55:31 2009 New Revision: 71383 Log: Removed unused #include. Modified: python/branches/py3k/Python/mysnprintf.c Modified: python/branches/py3k/Python/mysnprintf.c ============================================================================== --- python/branches/py3k/Python/mysnprintf.c (original) +++ python/branches/py3k/Python/mysnprintf.c Wed Apr 8 00:55:31 2009 @@ -1,5 +1,4 @@ #include "Python.h" -#include /* snprintf() wrappers. If the platform has vsnprintf, we use it, else we emulate it in a half-hearted way. Even if the platform has it, we wrap From python-checkins at python.org Wed Apr 8 01:10:59 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 8 Apr 2009 01:10:59 +0200 (CEST) Subject: [Python-checkins] r71384 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090407231059.693FE1E4002@bag.python.org> Author: raymond.hettinger Date: Wed Apr 8 01:10:59 2009 New Revision: 71384 Log: Add link. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Wed Apr 8 01:10:59 2009 @@ -88,7 +88,7 @@ returns an ordered dictionary with the values appearing in the same order as the underlying tuple indicies. The :mod:`json` module is being built-out with an *object_pairs_hook* to allow OrderedDicts to be built by the decoder. -Support was also added for third-party tools like PyYAML. +Support was also added for third-party tools like `PyYAML `_. .. seealso:: From python-checkins at python.org Wed Apr 8 01:56:57 2009 From: python-checkins at python.org (jack.diederich) Date: Wed, 8 Apr 2009 01:56:57 +0200 (CEST) Subject: [Python-checkins] r71385 - python/trunk/Lib/test/test_telnetlib.py Message-ID: <20090407235657.5F9471E4002@bag.python.org> Author: jack.diederich Date: Wed Apr 8 01:56:57 2009 New Revision: 71385 Log: - Make timing assertions very generous (a la test_timeout.py) - Break the gc cycle in negotiation tests - test the different guarantees of read_lazy and read_very_lazy Modified: python/trunk/Lib/test/test_telnetlib.py Modified: python/trunk/Lib/test/test_telnetlib.py ============================================================================== --- python/trunk/Lib/test/test_telnetlib.py (original) +++ python/trunk/Lib/test/test_telnetlib.py Wed Apr 8 01:56:57 2009 @@ -23,17 +23,15 @@ conn, addr = serv.accept() if dataq: data = '' - done = False - for new_data in dataq.get(True, 0.5): - if not done: - dataq.task_done() - done = True - if new_data == EOF_sigil: + new_data = dataq.get(True, 0.5) + dataq.task_done() + for item in new_data: + if item == EOF_sigil: break - if type(new_data) in [int, float]: - time.sleep(new_data) + if type(item) in [int, float]: + time.sleep(item) else: - data += new_data + data += item written = conn.send(data) data = data[written:] except socket.timeout: @@ -42,10 +40,6 @@ serv.close() evt.set() -def wibble_float(num): - ''' return a (low, high) tuple that are 1% more and 1% less of num ''' - return num * 0.99, num * 1.01 - class GeneralTests(TestCase): def setUp(self): @@ -101,8 +95,6 @@ telnet.sock.close() def _read_setUp(self): - # the blocking constant should be tuned! - self.blocking_timeout = 0.3 self.evt = threading.Event() self.dataq = Queue.Queue() self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -122,6 +114,10 @@ setUp = _read_setUp tearDown = _read_tearDown + # use a similar approach to testing timeouts as test_timeout.py + # these will never pass 100% but make the fuzz big enough that it is rare + block_long = 0.6 + block_short = 0.3 def test_read_until_A(self): """ read_until(expected, [timeout]) @@ -137,12 +133,13 @@ def test_read_until_B(self): # test the timeout - it does NOT raise socket.timeout - want = ['hello', self.blocking_timeout, EOF_sigil] + want = ['hello', self.block_long, 'not seen', EOF_sigil] self.dataq.put(want) telnet = telnetlib.Telnet(HOST, self.port) self.dataq.join() - data = telnet.read_until('not seen') + data = telnet.read_until('not seen', self.block_short) self.assertEqual(data, want[0]) + self.assertEqual(telnet.read_all(), 'not seen') def test_read_all_A(self): """ @@ -158,12 +155,11 @@ return def _test_blocking(self, func): - self.dataq.put([self.blocking_timeout, EOF_sigil]) + self.dataq.put([self.block_long, EOF_sigil]) self.dataq.join() start = time.time() data = func() - low, high = wibble_float(self.blocking_timeout) - self.assertTrue(low <= time.time() - start) + self.assertTrue(self.block_short <= time.time() - start) def test_read_all_B(self): self._test_blocking(telnetlib.Telnet(HOST, self.port).read_all) @@ -204,9 +200,8 @@ Read all data available already queued or on the socket, without blocking. """ - # this never blocks so it should return eat part in turn - want = ['x' * 100, self.blocking_timeout/2, 'y' * 100, EOF_sigil] - expects = want[0] + want[2] + want = [self.block_long, 'x' * 100, 'y' * 100, EOF_sigil] + expects = want[1] + want[2] self.dataq.put(want) telnet = telnetlib.Telnet(HOST, self.port) self.dataq.join() @@ -225,6 +220,7 @@ self.dataq.put([EOF_sigil]) telnet = telnetlib.Telnet(HOST, self.port) self.dataq.join() + time.sleep(self.block_short) func = getattr(telnet, func_name) self.assertRaises(EOFError, func) @@ -241,46 +237,59 @@ # NB -- we need to test the IAC block which is mentioned in the docstring # but not in the module docs - def _test_read_any_lazy_A(self, func_name): - want = [self.blocking_timeout/2, 'x' * 100, EOF_sigil] - self.dataq.put(want) + def _test_read_any_lazy_B(self, func_name): + self.dataq.put([EOF_sigil]) telnet = telnetlib.Telnet(HOST, self.port) self.dataq.join() func = getattr(telnet, func_name) - self.assertEqual('', func()) + telnet.fill_rawq() + self.assertRaises(EOFError, func) + + def test_read_lazy_A(self): + want = ['x' * 100, EOF_sigil] + self.dataq.put(want) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + time.sleep(self.block_short) + self.assertEqual('', telnet.read_lazy()) data = '' while True: - time.sleep(0.0) try: - telnet.fill_rawq() - data += func() - if not data: - break + read_data = telnet.read_lazy() + data += read_data + if not read_data: + telnet.fill_rawq() except EOFError: break - self.assertTrue(want[1].startswith(data)) - return data, want[1] + self.assertTrue(want[0].startswith(data)) + self.assertEqual(data, want[0]) - def _test_read_any_lazy_B(self, func_name): - self.dataq.put([EOF_sigil]) + def test_read_lazy_B(self): + self._test_read_any_lazy_B('read_lazy') + + def test_read_very_lazy_A(self): + want = ['x' * 100, EOF_sigil] + self.dataq.put(want) telnet = telnetlib.Telnet(HOST, self.port) self.dataq.join() - func = getattr(telnet, func_name) - time.sleep(0.0) - telnet.fill_rawq() - self.assertRaises(EOFError, func) + time.sleep(self.block_short) + self.assertEqual('', telnet.read_very_lazy()) + data = '' + while True: + try: + read_data = telnet.read_very_lazy() + except EOFError: + break + data += read_data + if not read_data: + telnet.fill_rawq() + self.assertEqual('', telnet.cookedq) + telnet.process_rawq() + self.assertTrue(want[0].startswith(data)) + self.assertEqual(data, want[0]) - # read_lazy and read_very_lazy make the samish gaurantees - def test_read_very_lazy_A(self): - data, want = self._test_read_any_lazy_A('read_very_lazy') - self.assertEqual(data, '') - def test_read_lazy(self): - data, want = self._test_read_any_lazy_A('read_lazy') - self.assertEqual(data, want) def test_read_very_lazy_B(self): self._test_read_any_lazy_B('read_very_lazy') - def test_read_lazy_B(self): - self._test_read_any_lazy_B('read_lazy') class nego_collector(object): def __init__(self, sb_getter=None): @@ -315,6 +324,7 @@ self.assertTrue(cmd[0] in self.cmds) self.assertEqual(cmd[1], tl.NOOPT) self.assertEqual(len(''.join(data[:-1])), len(txt + cmd)) + nego.sb_getter = None # break the nego => telnet cycle self.tearDown() def test_IAC_commands(self): @@ -351,6 +361,7 @@ want_sb_data = tl.IAC + tl.IAC + 'aabb' + tl.IAC + 'cc' + tl.IAC + 'dd' self.assertEqual(nego.sb_seen, want_sb_data) self.assertEqual('', telnet.read_sb_data()) + nego.sb_getter = None # break the nego => telnet cycle def test_main(verbose=None): test_support.run_unittest(GeneralTests, ReadTests, OptionTests) From python-checkins at python.org Wed Apr 8 02:09:26 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 8 Apr 2009 02:09:26 +0200 (CEST) Subject: [Python-checkins] r71386 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090408000926.C34761E4002@bag.python.org> Author: raymond.hettinger Date: Wed Apr 8 02:09:26 2009 New Revision: 71386 Log: Fix-up attribution per IRC discussion with GPolo. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Wed Apr 8 02:09:26 2009 @@ -179,8 +179,7 @@ The basic idea of ttk is to separate, to the extent possible, the code implementing a widget's behavior from the code implementing its appearance. - (Contributed by Kevin Walzer and Guilherme Polo; :issue:`2618` and - :issue:`2983`.) + (Contributed by Guilherme Polo; :issue:`2983`.) * The :class:`gzip.GzipFile` and :class:`bz2.BZ2File` classes now support the context manager protocol:: From buildbot at python.org Wed Apr 8 02:56:06 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 08 Apr 2009 00:56:06 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090408005606.B16991E4026@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/501 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson,georg.brandl,raymond.hettinger BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_importlib test_posix Traceback (most recent call last): File "./Lib/test/regrtest.py", line 620, in runtest_inner File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_importlib.py", line 6, in test_main run_unittest(importlib.test.test_suite('importlib.test')) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/__init__.py", line 22, in test_suite package_tests = getattr(sys.modules[package_name], 'test_suite')() File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/source/__init__.py", line 8, in test_suite return importlib.test.test_suite('importlib.test.source', directory) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/__init__.py", line 16, in test_suite __import__(module_name, level=0) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/source/test_case_sensitivity.py", line 12, in class CaseSensitivityTest(unittest.TestCase): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/util.py", line 13, in case_insensitive_tests original_name = os.listdir('.')[0] IndexError: list index out of range ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 249, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 102, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Wed Apr 8 03:15:03 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 8 Apr 2009 03:15:03 +0200 (CEST) Subject: [Python-checkins] r71387 - python/branches/py3k/Lib/collections.py Message-ID: <20090408011503.4561E1E4002@bag.python.org> Author: raymond.hettinger Date: Wed Apr 8 03:15:02 2009 New Revision: 71387 Log: Add docstrings. Modified: python/branches/py3k/Lib/collections.py Modified: python/branches/py3k/Lib/collections.py ============================================================================== --- python/branches/py3k/Lib/collections.py (original) +++ python/branches/py3k/Lib/collections.py Wed Apr 8 03:15:02 2009 @@ -36,6 +36,11 @@ # Those hard references disappear when a key is deleted from an OrderedDict. def __init__(self, *args, **kwds): + '''Initialize an ordered dictionary. Signature is the same as for + regular dictionaries, but keyword arguments are not recommended + because their insertion order is arbitrary. + + ''' if len(args) > 1: raise TypeError('expected at most 1 arguments, got %d' % len(args)) try: @@ -47,12 +52,14 @@ self.update(*args, **kwds) def clear(self): + 'od.clear() -> None. Remove all items from od.' root = self.__root root.prev = root.next = root self.__map.clear() dict.clear(self) def __setitem__(self, key, value): + 'od.__setitem__(i, y) <==> od[i]=y' # Setting a new item creates a new link which goes at the end of the linked # list, and the inherited dictionary is updated with the new key/value pair. if key not in self: @@ -64,6 +71,7 @@ dict.__setitem__(self, key, value) def __delitem__(self, key): + 'od.__delitem__(y) <==> del od[y]' # Deleting an existing item uses self.__map to find the link which is # then removed by updating the links in the predecessor and successor nodes. dict.__delitem__(self, key) @@ -72,6 +80,7 @@ link.next.prev = link.prev def __iter__(self): + 'od.__iter__() <==> iter(od)' # Traverse the linked list in order. root = self.__root curr = root.next @@ -80,6 +89,7 @@ curr = curr.next def __reversed__(self): + 'od.__iter__() <==> reversed(od)' # Traverse the linked list in reverse order. root = self.__root curr = root.prev @@ -88,6 +98,7 @@ curr = curr.prev def __reduce__(self): + 'Return state information for pickling' items = [[k, self[k]] for k in self] tmp = self.__map, self.__root del self.__map, self.__root @@ -105,6 +116,10 @@ items = MutableMapping.items def popitem(self, last=True): + '''od.popitem() -> (k, v), return and remove a (key, value) pair. + Pairs are returned in LIFO order if last is true or FIFO order if false. + + ''' if not self: raise KeyError('dictionary is empty') key = next(reversed(self)) if last else next(iter(self)) @@ -112,27 +127,41 @@ return key, value def __repr__(self): + 'od.__repr__() <==> repr(od)' if not self: return '%s()' % (self.__class__.__name__,) return '%s(%r)' % (self.__class__.__name__, list(self.items())) def copy(self): + 'od.copy() -> a shallow copy of od' return self.__class__(self) @classmethod def fromkeys(cls, iterable, value=None): + '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S + and values equal to v (which defaults to None). + + ''' d = cls() for key in iterable: d[key] = value return d def __eq__(self, other): + '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' if isinstance(other, OrderedDict): return len(self)==len(other) and \ all(p==q for p, q in zip(self.items(), other.items())) return dict.__eq__(self, other) def __ne__(self, other): + '''od.__ne__(y) <==> od!=y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' return not self == other From python-checkins at python.org Wed Apr 8 03:16:27 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 8 Apr 2009 03:16:27 +0200 (CEST) Subject: [Python-checkins] r71388 - python/branches/py3k/Lib/collections.py Message-ID: <20090408011627.4159C1E4002@bag.python.org> Author: raymond.hettinger Date: Wed Apr 8 03:16:27 2009 New Revision: 71388 Log: Typo. Modified: python/branches/py3k/Lib/collections.py Modified: python/branches/py3k/Lib/collections.py ============================================================================== --- python/branches/py3k/Lib/collections.py (original) +++ python/branches/py3k/Lib/collections.py Wed Apr 8 03:16:27 2009 @@ -89,7 +89,7 @@ curr = curr.next def __reversed__(self): - 'od.__iter__() <==> reversed(od)' + 'od.__reversed__() <==> reversed(od)' # Traverse the linked list in reverse order. root = self.__root curr = root.prev From buildbot at python.org Wed Apr 8 04:39:50 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 08 Apr 2009 02:39:50 +0000 Subject: [Python-checkins] buildbot failure in x86 XP-4 trunk Message-ID: <20090408023951.06A9C1E4010@bag.python.org> The Buildbot has detected a new failure of x86 XP-4 trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20XP-4%20trunk/builds/2022 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: bolen-windows Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: benjamin.peterson,georg.brandl,gregory.p.smith,guilherme.polo,hirokazu.yamamoto,jack.diederich,martin.v.loewis,matthias.klose,michael.foord,raymond.hettinger,tarek.ziade,vinay.sajip BUILD FAILED: failed test Excerpt from the test logfile: 3 tests failed: test__locale test_posix test_pty Traceback (most recent call last): File "../lib/test/regrtest.py", line 564, in runtest_inner the_package = __import__(abstest, globals(), locals(), []) File "E:\cygwin\home\db3l\buildarea\trunk.bolen-windows\build\lib\test\test__locale.py", line 2, in from _locale import (setlocale, LC_NUMERIC, RADIXCHAR, THOUSEP, nl_langinfo, ImportError: cannot import name RADIXCHAR Traceback (most recent call last): File "../lib/test/regrtest.py", line 564, in runtest_inner the_package = __import__(abstest, globals(), locals(), []) File "E:\cygwin\home\db3l\buildarea\trunk.bolen-windows\build\lib\test\test_posix.py", line 8, in import pwd ImportError: No module named pwd Traceback (most recent call last): File "../lib/test/regrtest.py", line 564, in runtest_inner the_package = __import__(abstest, globals(), locals(), []) File "E:\cygwin\home\db3l\buildarea\trunk.bolen-windows\build\lib\test\test_pty.py", line 2, in import fcntl ImportError: No module named fcntl sincerely, -The Buildbot From buildbot at python.org Wed Apr 8 05:06:17 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 08 Apr 2009 03:06:17 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090408030617.CBD751E400C@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/503 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: raymond.hettinger BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 249, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 102, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From buildbot at python.org Wed Apr 8 06:07:20 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 08 Apr 2009 04:07:20 +0000 Subject: [Python-checkins] buildbot failure in x86 XP-4 2.6 Message-ID: <20090408040720.4445E1E400C@bag.python.org> The Buildbot has detected a new failure of x86 XP-4 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20XP-4%202.6/builds/178 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: bolen-windows Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: barry.warsaw,benjamin.peterson,georg.brandl,gregory.p.smith,hirokazu.yamamoto,martin.v.loewis,matthias.klose,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_bsddb3 ====================================================================== ERROR: test01_badpointer (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 21, in test01_badpointer dbs = dbshelve.open(self.filename) File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\dbshelve.py", line 106, in open d.open(filename, dbname, filetype, flags, mode) File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\dbshelve.py", line 171, in open self.db.open(*args, **kwargs) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test03_repr_closed_db (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 37, in test03_repr_closed_db db = hashopen(self.filename) File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\__init__.py", line 361, in hashopen d.open(file, db.DB_HASH, flags, mode) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test04_repr_db (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 43, in test04_repr_db db = hashopen(self.filename) File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\__init__.py", line 361, in hashopen d.open(file, db.DB_HASH, flags, mode) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test05_double_free_make_key_dbt (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 65, in test05_double_free_make_key_dbt db.DB_CREATE | db.DB_THREAD) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test06_key_with_null_bytes (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 77, in test06_key_with_null_bytes db1.open(self.filename, None, db.DB_HASH, db.DB_CREATE) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test07_DB_set_flags_persists (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 101, in test07_DB_set_flags_persists db1.open(self.filename, db.DB_HASH, db.DB_CREATE) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') sincerely, -The Buildbot From python-checkins at python.org Wed Apr 8 07:39:38 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 8 Apr 2009 07:39:38 +0200 (CEST) Subject: [Python-checkins] r71389 - python/trunk/Lib/collections.py Message-ID: <20090408053938.E5CEB1E400C@bag.python.org> Author: raymond.hettinger Date: Wed Apr 8 07:39:38 2009 New Revision: 71389 Log: Add docstrings. Modified: python/trunk/Lib/collections.py Modified: python/trunk/Lib/collections.py ============================================================================== --- python/trunk/Lib/collections.py (original) +++ python/trunk/Lib/collections.py Wed Apr 8 07:39:38 2009 @@ -36,6 +36,11 @@ # Those hard references disappear when a key is deleted from an OrderedDict. def __init__(self, *args, **kwds): + '''Initialize an ordered dictionary. Signature is the same as for + regular dictionaries, but keyword arguments are not recommended + because their insertion order is arbitrary. + + ''' if len(args) > 1: raise TypeError('expected at most 1 arguments, got %d' % len(args)) try: @@ -47,12 +52,14 @@ self.update(*args, **kwds) def clear(self): + 'od.clear() -> None. Remove all items from od.' root = self.__root root.prev = root.next = root self.__map.clear() dict.clear(self) def __setitem__(self, key, value): + 'od.__setitem__(i, y) <==> od[i]=y' # Setting a new item creates a new link which goes at the end of the linked # list, and the inherited dictionary is updated with the new key/value pair. if key not in self: @@ -64,6 +71,7 @@ dict.__setitem__(self, key, value) def __delitem__(self, key): + 'od.__delitem__(y) <==> del od[y]' # Deleting an existing item uses self.__map to find the link which is # then removed by updating the links in the predecessor and successor nodes. dict.__delitem__(self, key) @@ -72,6 +80,7 @@ link.next.prev = link.prev def __iter__(self): + 'od.__iter__() <==> iter(od)' # Traverse the linked list in order. root = self.__root curr = root.next @@ -80,6 +89,7 @@ curr = curr.next def __reversed__(self): + 'od.__reversed__() <==> reversed(od)' # Traverse the linked list in reverse order. root = self.__root curr = root.prev @@ -88,6 +98,7 @@ curr = curr.prev def __reduce__(self): + 'Return state information for pickling' items = [[k, self[k]] for k in self] tmp = self.__map, self.__root del self.__map, self.__root @@ -109,6 +120,10 @@ __ne__ = MutableMapping.__ne__ def popitem(self, last=True): + '''od.popitem() -> (k, v), return and remove a (key, value) pair. + Pairs are returned in LIFO order if last is true or FIFO order if false. + + ''' if not self: raise KeyError('dictionary is empty') key = next(reversed(self)) if last else next(iter(self)) @@ -116,21 +131,31 @@ return key, value def __repr__(self): + 'od.__repr__() <==> repr(od)' if not self: return '%s()' % (self.__class__.__name__,) return '%s(%r)' % (self.__class__.__name__, self.items()) def copy(self): + 'od.copy() -> a shallow copy of od' return self.__class__(self) @classmethod def fromkeys(cls, iterable, value=None): + '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S + and values equal to v (which defaults to None). + + ''' d = cls() for key in iterable: d[key] = value return d def __eq__(self, other): + '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' if isinstance(other, OrderedDict): return len(self)==len(other) and \ all(_imap(_eq, self.iteritems(), other.iteritems())) From python-checkins at python.org Wed Apr 8 09:49:04 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 8 Apr 2009 09:49:04 +0200 (CEST) Subject: [Python-checkins] r71390 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090408074904.8CAC51E4039@bag.python.org> Author: raymond.hettinger Date: Wed Apr 8 09:49:03 2009 New Revision: 71390 Log: Add example for auto-renaming. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Wed Apr 8 09:49:03 2009 @@ -228,7 +228,18 @@ *rename* which lets invalid fieldnames be automatically converted to positional names in the form _0, _1, etc. This is useful when the field names are being created by an external source such as a - CSV header, SQL field list, or user input. + CSV header, SQL field list, or user input:: + + >>> query = input('Enter a query: ') + Enter a query: SELECT region, dept, count(*) FROM main GROUPBY region, dept + + >>> cursor.execute(query) + >>> query_fields = [desc[0] for desc in cursor.description] + >>> UserQuery = namedtuple('UserQuery', query_fields, rename=True) + >>> pprint.pprint([UserQuery(*row) for row in cursor]) + [UserQuery(region='South', dept='Shipping', _2=185), + UserQuery(region='North', dept='Accounting', _2=37), + UserQuery(region='West', dept='Sales', _2=419)] (Contributed by Raymond Hettinger; :issue:`1818`.) From nnorwitz at gmail.com Wed Apr 8 10:09:13 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 8 Apr 2009 04:09:13 -0400 Subject: [Python-checkins] Python Regression Test Failures basics (3) Message-ID: <20090408080913.GA8006@python.psfb.org> 331 tests OK. 3 tests failed: test_asyncore test_lib2to3 test_multiprocessing 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ast test_asynchat test_asyncore test test_asyncore failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_asyncore.py", line 144, in test_readwrite self.assertEqual(tobj.read, True) AssertionError: False != True 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23381 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 test_lib2to3 crashed -- : No module named myfixes 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 test_multiprocessing crashed -- : cannot import name SkipTest test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18065 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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_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 331 tests OK. 3 tests failed: test_asyncore test_lib2to3 test_multiprocessing 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl [700383 refs] From nnorwitz at gmail.com Wed Apr 8 10:16:34 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 8 Apr 2009 04:16:34 -0400 Subject: [Python-checkins] Python Regression Test Failures opt (3) Message-ID: <20090408081634.GA10449@python.psfb.org> 331 tests OK. 3 tests failed: test_asyncore test_lib2to3 test_multiprocessing 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ast test_asynchat test_asyncore test test_asyncore failed -- errors occurred; run in verbose mode for details 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils [17363 refs] [17363 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23381 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 test_lib2to3 crashed -- : No module named myfixes 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 test_multiprocessing crashed -- : cannot import name SkipTest test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18065 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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_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 331 tests OK. 3 tests failed: test_asyncore test_lib2to3 test_multiprocessing 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl [699652 refs] From python-checkins at python.org Wed Apr 8 10:23:44 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 8 Apr 2009 10:23:44 +0200 (CEST) Subject: [Python-checkins] r71391 - python/branches/py3k/Doc/library/tkinter.ttk.rst Message-ID: <20090408082344.E21DB1E4039@bag.python.org> Author: raymond.hettinger Date: Wed Apr 8 10:23:44 2009 New Revision: 71391 Log: Perform minor copy edits Modified: python/branches/py3k/Doc/library/tkinter.ttk.rst Modified: python/branches/py3k/Doc/library/tkinter.ttk.rst ============================================================================== --- python/branches/py3k/Doc/library/tkinter.ttk.rst (original) +++ python/branches/py3k/Doc/library/tkinter.ttk.rst Wed Apr 8 10:23:44 2009 @@ -9,13 +9,13 @@ .. index:: single: ttk The :mod:`tkinter.ttk` module provides access to the Tk themed widget set, -which has been introduced in Tk 8.5. If you do not have Python compiled against -Tk 8.5 you may still use this module as long as you have Tile installed, but -then you will miss some features provided by the new Tk, like anti-aliased font -rendering under X11, window transparency (on X11 you will need a composition -window manager) and others. +introduced in Tk 8.5. If Python has not been compiled against Tk 8.5, this +module can still be accessed if *Tile* has been installed. The former +method using Tk 8.5 provides additional benefits including anti-aliased font +rendering under X11 and window transparency (requiring a composition +window manager on X11). -The basic idea of :mod:`tkinter.ttk` is to separate, to the extent possible, +The basic idea for :mod:`tkinter.ttk` is to separate, to the extent possible, the code implementing a widget's behavior from the code implementing its appearance. @@ -23,58 +23,55 @@ .. seealso:: `Tk Widget Styling Support `_ - The document which brought up theming support for Tk + A document introducing theming support for Tk Using Ttk --------- -Basically, to start using Ttk, you have to import its module:: +To start using Ttk, import its module:: from tkinter import ttk -But if you already have some code that does:: - - from tkinter import * - -You may optionally want to use:: +To override the basic Tk widgets, the import should follow the Tk import:: from tkinter import * from tkinter.ttk import * -And then several :mod:`tkinter.ttk` widgets (:class:`Button`, +That code causes several :mod:`tkinter.ttk` widgets (:class:`Button`, :class:`Checkbutton`, :class:`Entry`, :class:`Frame`, :class:`Label`, :class:`LabelFrame`, :class:`Menubutton`, :class:`PanedWindow`, -:class:`Radiobutton`, :class:`Scale` and :class:`Scrollbar`) will -automatically substitute the Tk widgets. +:class:`Radiobutton`, :class:`Scale` and :class:`Scrollbar`) to +automatically replace the Tk widgets. + +This has the direct benefit of using the new widgets which gives a better +look and feel across platforms; however, the replacement widgets are not +completely compatible. The main difference is that widget options such as +"fg", "bg" and others related to widget styling are no +longer present in Ttk widgets. Instead, use the :class:`ttk.Style` class +for improved styling effects. -This has the direct benefit of using the new widgets which gives better -look & feel across platforms, but you should be aware that they are not -totally compatible. The main difference you will find out is that widget -options such as "fg", "bg" and others related to widget styling are no -longer present in Ttk widgets, instead you will have to use :class:`ttk.Style` -to achieve the same (or better) styling. .. seealso:: - `Converting existing applications to use the Tile widgets `_ - A text which talks in Tcl terms about differences typically found when - moving applications to use the new widgets. + `Converting existing applications to use Tile widgets `_ + A monograph (using Tcl terminology) about differences typically + encountered when moving applications to use the new widgets. Ttk Widgets ----------- -Ttk comes with 17 widgets, where 11 of these already existed in tkinter: +Ttk comes with 17 widgets, eleven of which already existed in tkinter: :class:`Button`, :class:`Checkbutton`, :class:`Entry`, :class:`Frame`, :class:`Label`, :class:`LabelFrame`, :class:`Menubutton`, :class:`PanedWindow`, -:class:`Radiobutton`, :class:`Scale` and :class:`Scrollbar`. The others 6 are +:class:`Radiobutton`, :class:`Scale` and :class:`Scrollbar`. The other six are new: :class:`Combobox`, :class:`Notebook`, :class:`Progressbar`, :class:`Separator`, :class:`Sizegrip` and :class:`Treeview`. And all them are subclasses of :class:`Widget`. -Like it was told before, you will notice changes in look & feel as well in the -styling code. To demonstrate the latter, a very simple example is shown below. +Using the Ttk widgets gives the application an improved look and feel. +As discussed above, there are differences in how the styling is coded. Tk code:: @@ -90,7 +87,7 @@ l1 = ttk.Label(text="Test", style="BW.TLabel") l2 = ttk.Label(text="Test", style="BW.TLabel") -For more information about TtkStyling_ read the :class:`Style` class +For more information about TtkStyling_, see the :class:`Style` class documentation. Widget @@ -554,10 +551,10 @@ ----------- The :class:`ttk.Progressbar` widget shows the status of a long-running -operation. It can operate in two modes: determinate mode shows the amount -completed relative to the total amount of work to be done, and indeterminate -mode provides an animated display to let the user know that something is -happening. +operation. It can operate in two modes: 1) the determinate mode which shows the +amount completed relative to the total amount of work to be done and 2) the +indeterminate mode which provides an animated display to let the user know that +work is progressing. Options @@ -1164,7 +1161,7 @@ the value for that option. For example, to change every default button to be a flat button with - some padding and a different background color you could do:: + some padding and a different background color:: from tkinter import ttk import tkinter @@ -1186,7 +1183,7 @@ Each key in *kw* is an option and each value should be a list or a tuple (usually) containing statespecs grouped in tuples, lists, or - something else of your preference. A statespec is a compound of one + some other preference. A statespec is a compound of one or more states and then a value. An example may make it more understandable:: @@ -1208,9 +1205,9 @@ Note that the order of the (states, value) sequences for an option does - matter, if you changed the order to ``[('active', 'blue'), ('pressed', - 'red')]`` in the foreground option, for example, you would get a blue - foreground when the widget were in active or pressed states. + matter, if the order is changed to ``[('active', 'blue'), ('pressed', + 'red')]`` in the foreground option, for example, the result would be a + blue foreground when the widget were in active or pressed states. .. method:: lookup(style, option[, state=None[, default=None]]) @@ -1221,7 +1218,7 @@ states. If the *default* argument is set, it is used as a fallback value in case no specification for option is found. - To check what font a Button uses by default, you would do:: + To check what font a Button uses by default:: from tkinter import ttk From python-checkins at python.org Wed Apr 8 10:26:55 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 8 Apr 2009 10:26:55 +0200 (CEST) Subject: [Python-checkins] r71392 - python/trunk/Lib/collections.py Message-ID: <20090408082655.7C9CC1E4039@bag.python.org> Author: raymond.hettinger Date: Wed Apr 8 10:26:55 2009 New Revision: 71392 Log: Minor factoring. Modified: python/trunk/Lib/collections.py Modified: python/trunk/Lib/collections.py ============================================================================== --- python/trunk/Lib/collections.py (original) +++ python/trunk/Lib/collections.py Wed Apr 8 10:26:55 2009 @@ -126,7 +126,7 @@ ''' if not self: raise KeyError('dictionary is empty') - key = next(reversed(self)) if last else next(iter(self)) + key = next(reversed(self) if last else iter(self)) value = self.pop(key) return key, value From python-checkins at python.org Wed Apr 8 10:28:28 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 8 Apr 2009 10:28:28 +0200 (CEST) Subject: [Python-checkins] r71393 - python/branches/py3k/Lib/collections.py Message-ID: <20090408082828.C19DA1E4039@bag.python.org> Author: raymond.hettinger Date: Wed Apr 8 10:28:28 2009 New Revision: 71393 Log: Minor factoring. Modified: python/branches/py3k/Lib/collections.py Modified: python/branches/py3k/Lib/collections.py ============================================================================== --- python/branches/py3k/Lib/collections.py (original) +++ python/branches/py3k/Lib/collections.py Wed Apr 8 10:28:28 2009 @@ -122,7 +122,7 @@ ''' if not self: raise KeyError('dictionary is empty') - key = next(reversed(self)) if last else next(iter(self)) + key = next(reversed(self) if last else iter(self)) value = self.pop(key) return key, value From nnorwitz at gmail.com Wed Apr 8 11:26:33 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 8 Apr 2009 05:26:33 -0400 Subject: [Python-checkins] Python Regression Test Failures refleak (3) Message-ID: <20090408092633.GA23588@python.psfb.org> More important issues: ---------------------- test_pydoc leaked [-42, 0, 0] references, sum=-42 test_softspace leaked [0, -84, 0] references, sum=-84 test_ssl leaked [0, 322, 0] references, sum=322 Less important issues: ---------------------- test_cmd_line leaked [0, -25, 0] references, sum=-25 test_httpservers leaked [-25, 0, 11] references, sum=-14 test_smtplib leaked [-1, -87, 180] references, sum=92 test_socketserver leaked [0, 0, 84] references, sum=84 test_sys leaked [21, 21, -42] references, sum=0 test_threading leaked [48, 48, 48] references, sum=144 test_threadsignals leaked [0, 0, -8] references, sum=-8 test_urllib2_localnet leaked [-276, 282, -276] references, sum=-270 From python-checkins at python.org Wed Apr 8 11:38:36 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 8 Apr 2009 11:38:36 +0200 (CEST) Subject: [Python-checkins] r71394 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090408093836.94A4D1E4039@bag.python.org> Author: raymond.hettinger Date: Wed Apr 8 11:38:32 2009 New Revision: 71394 Log: Remove bits that pertained to earlier releases. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Wed Apr 8 11:38:32 2009 @@ -2,8 +2,6 @@ What's New In Python 3.1 **************************** -.. XXX Add trademark info for Apple, Microsoft. - :Author: Raymond Hettinger :Release: |release| :Date: |today| @@ -17,8 +15,7 @@ * The maintainer will go through Misc/NEWS periodically and add changes; it's therefore more important to add your changes to - Misc/NEWS than to this file. (Note: I didn't get to this for 3.0. - GvR.) + Misc/NEWS than to this file. * This is not a complete list of every single change; completeness is the purpose of Misc/NEWS. Some changes I consider too small @@ -39,8 +36,7 @@ necessary (especially when a final release is some months away). * Credit the author of a patch or bugfix. Just the name is - sufficient; the e-mail address isn't necessary. (Due to time - constraints I haven't managed to do this for 3.0. GvR.) + sufficient; the e-mail address isn't necessary. * It's helpful to add the bug/patch number as a comment: @@ -50,21 +46,10 @@ (Contributed by P.Y. Developer.) This saves the maintainer the effort of going through the SVN log - when researching a change. (Again, I didn't get to this for 3.0. - GvR.) + when researching a change. This article explains the new features in Python 3.1, compared to 3.0. -.. Compare with previous release in 2 - 3 sentences here. -.. add hyperlink when the documentation becomes available online. - -.. ====================================================================== -.. Large, PEP-level features and changes should be described here. -.. Should there be a new section here for 3k migration? -.. Or perhaps a more general section describing module changes/deprecation? -.. sets module deprecated -.. ====================================================================== - PEP 372: Ordered Dictionaries ============================= @@ -96,6 +81,7 @@ PEP written by Armin Ronacher and Raymond Hettinger. Implementation written by Raymond Hettinger. + PEP 378: Format Specifier for Thousands Separator ================================================= @@ -162,7 +148,6 @@ (Contributed by Mark Dickinson; :issue:`4707`.) -.. ====================================================================== New, Improved, and Deprecated Modules ===================================== @@ -294,8 +279,6 @@ (Contributed by Brett Cannon.) -.. ====================================================================== - Optimizations ============= @@ -359,4 +342,3 @@ (Contributed by Mark Dickinson; :issue:`4258`.) -.. ====================================================================== From nnorwitz at gmail.com Wed Apr 8 11:43:11 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 8 Apr 2009 05:43:11 -0400 Subject: [Python-checkins] Python Regression Test Failures all (3) Message-ID: <20090408094311.GA27270@python.psfb.org> 336 tests OK. 3 tests failed: test_asyncore test_lib2to3 test_multiprocessing 26 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_cd test_cl test_epoll test_gl test_imgfile test_ioctl test_kqueue test_macos test_macostools 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ast test_asynchat test_asyncore test test_asyncore failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_asyncore.py", line 144, in test_readwrite self.assertEqual(tobj.read, True) AssertionError: False != True 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-23596 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23381 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 test_lib2to3 crashed -- : No module named myfixes 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 test_multiprocessing crashed -- : cannot import name SkipTest test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib test_socket test_socketserver 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18065 refs] [17879 refs] [17879 refs] [17879 refs] [17879 refs] test_threading_local test_threadsignals test_time test_timeout 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_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllibnet test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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_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 336 tests OK. 3 tests failed: test_asyncore test_lib2to3 test_multiprocessing 26 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_cd test_cl test_epoll test_gl test_imgfile test_ioctl test_kqueue test_macos test_macostools 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl [715437 refs] From python-checkins at python.org Wed Apr 8 15:27:29 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 8 Apr 2009 15:27:29 +0200 (CEST) Subject: [Python-checkins] r71395 - python/trunk/Makefile.pre.in Message-ID: <20090408132729.499841E404A@bag.python.org> Author: benjamin.peterson Date: Wed Apr 8 15:27:29 2009 New Revision: 71395 Log: these must be installed to correctly run tests Modified: python/trunk/Makefile.pre.in Modified: python/trunk/Makefile.pre.in ============================================================================== --- python/trunk/Makefile.pre.in (original) +++ python/trunk/Makefile.pre.in Wed Apr 8 15:27:29 2009 @@ -826,7 +826,8 @@ json json/tests \ sqlite3 sqlite3/test \ logging bsddb bsddb/test csv importlib wsgiref \ - lib2to3 lib2to3/fixes lib2to3/pgen2 lib2to3/tests \ + lib2to3 lib2to3/fixes lib2to3/pgen2 lib2to3/tests + lib2to3/tests/data lib2to3/tests/data/fixes lib2to3/tests/data/fixers/myfixes \ ctypes ctypes/test ctypes/macholib idlelib idlelib/Icons \ distutils distutils/command distutils/tests $(XMLLIBSUBDIRS) \ multiprocessing multiprocessing/dummy \ From python-checkins at python.org Wed Apr 8 15:29:41 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 8 Apr 2009 15:29:41 +0200 (CEST) Subject: [Python-checkins] r71396 - python/trunk/Makefile.pre.in Message-ID: <20090408132941.47D0E1E404A@bag.python.org> Author: benjamin.peterson Date: Wed Apr 8 15:29:41 2009 New Revision: 71396 Log: fix syntax Modified: python/trunk/Makefile.pre.in Modified: python/trunk/Makefile.pre.in ============================================================================== --- python/trunk/Makefile.pre.in (original) +++ python/trunk/Makefile.pre.in Wed Apr 8 15:29:41 2009 @@ -826,7 +826,7 @@ json json/tests \ sqlite3 sqlite3/test \ logging bsddb bsddb/test csv importlib wsgiref \ - lib2to3 lib2to3/fixes lib2to3/pgen2 lib2to3/tests + lib2to3 lib2to3/fixes lib2to3/pgen2 lib2to3/tests \ lib2to3/tests/data lib2to3/tests/data/fixes lib2to3/tests/data/fixers/myfixes \ ctypes ctypes/test ctypes/macholib idlelib idlelib/Icons \ distutils distutils/command distutils/tests $(XMLLIBSUBDIRS) \ From python-checkins at python.org Wed Apr 8 18:36:40 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 8 Apr 2009 18:36:40 +0200 (CEST) Subject: [Python-checkins] r71397 - python/trunk/Doc/c-api/buffer.rst Message-ID: <20090408163640.1B5E41E4048@bag.python.org> Author: georg.brandl Date: Wed Apr 8 18:36:39 2009 New Revision: 71397 Log: Remove redundant backtick. Modified: python/trunk/Doc/c-api/buffer.rst Modified: python/trunk/Doc/c-api/buffer.rst ============================================================================== --- python/trunk/Doc/c-api/buffer.rst (original) +++ python/trunk/Doc/c-api/buffer.rst Wed Apr 8 18:36:39 2009 @@ -242,7 +242,7 @@ | :cmacro:`PyBUF_FULL` | This is equivalent to ``(PyBUF_INDIRECT | | | | PyBUF_FORMAT | PyBUF_WRITABLE)``. | +------------------------------+---------------------------------------------------+ - | :cmacro:`PyBUF_FULL_RO`` | This is equivalent to ``(PyBUF_INDIRECT | | + | :cmacro:`PyBUF_FULL_RO` | This is equivalent to ``(PyBUF_INDIRECT | | | | PyBUF_FORMAT)``. | +------------------------------+---------------------------------------------------+ | :cmacro:`PyBUF_CONTIG` | This is equivalent to ``(PyBUF_ND | | From python-checkins at python.org Wed Apr 8 18:39:04 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 8 Apr 2009 18:39:04 +0200 (CEST) Subject: [Python-checkins] r71398 - python/trunk/Doc/tools/sphinxext/susp-ignored.csv Message-ID: <20090408163904.85D451E4048@bag.python.org> Author: georg.brandl Date: Wed Apr 8 18:39:04 2009 New Revision: 71398 Log: Update ignore file for suspicious builder. Modified: python/trunk/Doc/tools/sphinxext/susp-ignored.csv Modified: python/trunk/Doc/tools/sphinxext/susp-ignored.csv ============================================================================== --- python/trunk/Doc/tools/sphinxext/susp-ignored.csv (original) +++ python/trunk/Doc/tools/sphinxext/susp-ignored.csv Wed Apr 8 18:39:04 2009 @@ -48,6 +48,8 @@ library/httplib,,:port,host:port library/imaplib,,:MM,"""DD-Mmm-YYYY HH:MM:SS +HHMM""" library/imaplib,,:SS,"""DD-Mmm-YYYY HH:MM:SS +HHMM""" +library/itertools,,:stop,elements from seq[start:stop:step] +library/itertools,,:step,elements from seq[start:stop:step] library/linecache,,:sys,"sys:x:3:3:sys:/dev:/bin/sh" library/logging,,:And, library/logging,,:package1, From python-checkins at python.org Wed Apr 8 23:35:53 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 8 Apr 2009 23:35:53 +0200 (CEST) Subject: [Python-checkins] r71399 - python/branches/py3k/Makefile.pre.in Message-ID: <20090408213553.179B81E40BD@bag.python.org> Author: benjamin.peterson Date: Wed Apr 8 23:35:52 2009 New Revision: 71399 Log: fix installing of extension modules 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 Wed Apr 8 23:35:52 2009 @@ -757,7 +757,7 @@ # Install almost everything without disturbing previous versions altinstall: @FRAMEWORKALTINSTALLFIRST@ altbininstall libinstall inclinstall libainstall \ - oldsharedinstall @FRAMEWORKALTINSTALLLAST@ + sharedinstall oldsharedinstall @FRAMEWORKALTINSTALLLAST@ # Install shared libraries enabled by Setup DESTDIRS= $(exec_prefix) $(LIBDIR) $(BINLIBDEST) $(DESTSHARED) From python-checkins at python.org Wed Apr 8 23:40:02 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 8 Apr 2009 23:40:02 +0200 (CEST) Subject: [Python-checkins] r71400 - python/branches/py3k/setup.py Message-ID: <20090408214002.0F6FE1E40D1@bag.python.org> Author: benjamin.peterson Date: Wed Apr 8 23:40:01 2009 New Revision: 71400 Log: don't install scripts which will overwrite 2.x ones #1590 Modified: python/branches/py3k/setup.py Modified: python/branches/py3k/setup.py ============================================================================== --- python/branches/py3k/setup.py (original) +++ python/branches/py3k/setup.py Wed Apr 8 23:40:01 2009 @@ -1653,9 +1653,11 @@ ext_modules=[Extension('_struct', ['_struct.c'])], # Scripts to install - scripts = ['Tools/scripts/pydoc', 'Tools/scripts/idle', - 'Tools/scripts/2to3', - 'Lib/smtpd.py'] + # Commented out because we don't want them to override the 2.x + # ones. See #1590. + #scripts = ['Tools/scripts/pydoc', 'Tools/scripts/idle', + # 'Tools/scripts/2to3', + # 'Lib/smtpd.py'] ) # --install-platlib From python-checkins at python.org Wed Apr 8 23:41:45 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 8 Apr 2009 23:41:45 +0200 (CEST) Subject: [Python-checkins] r71401 - python/branches/py3k/setup.py Message-ID: <20090408214145.46E8D1E4376@bag.python.org> Author: benjamin.peterson Date: Wed Apr 8 23:41:45 2009 New Revision: 71401 Log: fix building Modified: python/branches/py3k/setup.py Modified: python/branches/py3k/setup.py ============================================================================== --- python/branches/py3k/setup.py (original) +++ python/branches/py3k/setup.py Wed Apr 8 23:41:45 2009 @@ -1655,6 +1655,7 @@ # Scripts to install # Commented out because we don't want them to override the 2.x # ones. See #1590. + scripts = [] #scripts = ['Tools/scripts/pydoc', 'Tools/scripts/idle', # 'Tools/scripts/2to3', # 'Lib/smtpd.py'] From buildbot at python.org Thu Apr 9 00:26:53 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 08 Apr 2009 22:26:53 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090408222654.2D3551E40BD@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/505 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson,raymond.hettinger BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_importlib test_posix Traceback (most recent call last): File "./Lib/test/regrtest.py", line 620, in runtest_inner File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_importlib.py", line 6, in test_main run_unittest(importlib.test.test_suite('importlib.test')) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/__init__.py", line 22, in test_suite package_tests = getattr(sys.modules[package_name], 'test_suite')() File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/source/__init__.py", line 8, in test_suite return importlib.test.test_suite('importlib.test.source', directory) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/__init__.py", line 16, in test_suite __import__(module_name, level=0) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/source/test_case_sensitivity.py", line 12, in class CaseSensitivityTest(unittest.TestCase): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/util.py", line 13, in case_insensitive_tests original_name = os.listdir('.')[0] IndexError: list index out of range ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 249, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 102, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Thu Apr 9 00:50:09 2009 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 9 Apr 2009 00:50:09 +0200 (CEST) Subject: [Python-checkins] r71402 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090408225009.70A971E40BD@bag.python.org> Author: raymond.hettinger Date: Thu Apr 9 00:50:09 2009 New Revision: 71402 Log: Clean-up an example. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Thu Apr 9 00:50:09 2009 @@ -215,8 +215,8 @@ the field names are being created by an external source such as a CSV header, SQL field list, or user input:: - >>> query = input('Enter a query: ') - Enter a query: SELECT region, dept, count(*) FROM main GROUPBY region, dept + >>> query = input() + SELECT region, dept, count(*) FROM main GROUPBY region, dept >>> cursor.execute(query) >>> query_fields = [desc[0] for desc in cursor.description] From python-checkins at python.org Thu Apr 9 02:08:24 2009 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 9 Apr 2009 02:08:24 +0200 (CEST) Subject: [Python-checkins] r71403 - in python/branches/py3k/Doc: library/io.rst library/multiprocessing.rst library/sys.rst library/threading.rst library/unittest.rst whatsnew/3.1.rst Message-ID: <20090409000824.692721E4018@bag.python.org> Author: raymond.hettinger Date: Thu Apr 9 02:08:24 2009 New Revision: 71403 Log: Update whatsnew based on doc search. Modified: python/branches/py3k/Doc/library/io.rst python/branches/py3k/Doc/library/multiprocessing.rst python/branches/py3k/Doc/library/sys.rst python/branches/py3k/Doc/library/threading.rst python/branches/py3k/Doc/library/unittest.rst python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/library/io.rst ============================================================================== --- python/branches/py3k/Doc/library/io.rst (original) +++ python/branches/py3k/Doc/library/io.rst Thu Apr 9 02:08:24 2009 @@ -279,7 +279,7 @@ Return the new absolute position. - .. versionadded:: 2.7 + .. versionadded:: 3.1 The ``SEEK_*`` constants .. method:: seekable() Modified: python/branches/py3k/Doc/library/multiprocessing.rst ============================================================================== --- python/branches/py3k/Doc/library/multiprocessing.rst (original) +++ python/branches/py3k/Doc/library/multiprocessing.rst Thu Apr 9 02:08:24 2009 @@ -841,7 +841,7 @@ will always return ``True`` except if a timeout is given and the operation times out. - .. versionchanged:: 2.7 + .. versionchanged:: 3.1 Previously, the method always returned ``None``. .. class:: Lock() Modified: python/branches/py3k/Doc/library/sys.rst ============================================================================== --- python/branches/py3k/Doc/library/sys.rst (original) +++ python/branches/py3k/Doc/library/sys.rst Thu Apr 9 02:08:24 2009 @@ -833,7 +833,7 @@ so ``sys.version_info[0]`` is equivalent to ``sys.version_info.major`` and so on. - .. versionchanged:: 2.7 + .. versionchanged:: 3.1 Added named component attributes .. data:: warnoptions Modified: python/branches/py3k/Doc/library/threading.rst ============================================================================== --- python/branches/py3k/Doc/library/threading.rst (original) +++ python/branches/py3k/Doc/library/threading.rst Thu Apr 9 02:08:24 2009 @@ -687,7 +687,7 @@ This method returns the internal flag on exit, so it will always return ``True`` except if a timeout is given and the operation times out. - .. versionchanged:: 2.7 + .. versionchanged:: 3.1 Previously, the method always returned ``None``. Modified: python/branches/py3k/Doc/library/unittest.rst ============================================================================== --- python/branches/py3k/Doc/library/unittest.rst (original) +++ python/branches/py3k/Doc/library/unittest.rst Thu Apr 9 02:08:24 2009 @@ -611,7 +611,7 @@ Signal a test failure if *expr* is false; the explanation for the error will be *msg* if given, otherwise it will be :const:`None`. - .. deprecated:: 2.7 + .. deprecated:: 3.1 :meth:`failUnless`. @@ -630,10 +630,10 @@ registers :meth:`addTypeEqualityFunc` the type specific equality function will be called in order to generate a more useful default error message. - .. versionchanged:: 2.7 + .. versionchanged:: 3.1 Added the automatic calling of type specific equality function. - .. deprecated:: 2.7 + .. deprecated:: 3.1 :meth:`failUnlessEqual`. @@ -647,7 +647,7 @@ default value for *msg* can be computed to include representations of both *first* and *second*. - .. deprecated:: 2.7 + .. deprecated:: 3.1 :meth:`failIfEqual`. @@ -663,7 +663,7 @@ compare equal, the test will fail with the explanation given by *msg*, or :const:`None`. - .. deprecated:: 2.7 + .. deprecated:: 3.1 :meth:`failUnlessAlmostEqual`. @@ -679,7 +679,7 @@ compare equal, the test will fail with the explanation given by *msg*, or :const:`None`. - .. deprecated:: 2.7 + .. deprecated:: 3.1 :meth:`failIfAlmostEqual`. @@ -695,7 +695,7 @@ >>> self.assertGreaterEqual(3, 4) AssertionError: "3" unexpectedly not greater than or equal to "4" - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertMultiLineEqual(self, first, second, msg=None) @@ -706,7 +706,7 @@ If specified *msg* will be used as the error message on failure. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertRegexpMatches(text, regexp[, msg=None]): @@ -716,7 +716,7 @@ a regular expression object or a string containing a regular expression suitable for use by :func:`re.search`. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertIn(first, second, msg=None) @@ -727,7 +727,7 @@ If specified *msg* will be used as the error message on failure. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertSameElements(expected, actual, msg=None) @@ -738,7 +738,7 @@ If specified *msg* will be used as the error message on failure. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertSetEqual(set1, set2, msg=None) @@ -751,7 +751,7 @@ If specified *msg* will be used as the error message on failure. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertDictEqual(expected, actual, msg=None) @@ -761,7 +761,7 @@ If specified *msg* will be used as the error message on failure. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertDictContainsSubset(expected, actual, msg=None) @@ -772,7 +772,7 @@ If specified *msg* will be used as the error message on failure. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertListEqual(list1, list2, msg=None) @@ -784,7 +784,7 @@ If specified *msg* will be used as the error message on failure. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertSequenceEqual(seq1, seq2, msg=None, seq_type=None) @@ -799,7 +799,7 @@ This method is used to implement :meth:`assertListEqual` and :meth:`assertTupleEqual`. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertRaises(exception[, callable, ...]) @@ -821,7 +821,7 @@ .. versionchanged:: 3.1 Added the ability to use :meth:`assertRaises` as a context manager. - .. deprecated:: 2.7 + .. deprecated:: 3.1 :meth:`failUnlessRaises`. @@ -840,14 +840,14 @@ with self.assertRaisesRegexp(ValueError, 'literal'): int('XYZ') - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertIsNone(expr[, msg]) This signals a test failure if *expr* is not None. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertIsNotNone(expr[, msg]) @@ -855,7 +855,7 @@ The inverse of the :meth:`assertIsNone` method. This signals a test failure if *expr* is None. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertFalse(expr[, msg]) @@ -865,7 +865,7 @@ This signals a test failure if *expr* is true, with *msg* or :const:`None` for the error message. - .. deprecated:: 2.7 + .. deprecated:: 3.1 :meth:`failIf`. @@ -899,7 +899,7 @@ The class setting can be overridden in individual tests by assigning an instance attribute to True or False before calling the assert methods. - .. versionadded:: 2.7 + .. versionadded:: 3.1 Testing frameworks can use the following methods to collect information on @@ -936,7 +936,7 @@ returns the first line of the test method's docstring, if available, along with the method name. - .. versionchanged:: 2.7 + .. versionchanged:: 3.1 In earlier versions this only returned the first line of the test method's docstring, if available or the :const:`None`. That led to @@ -958,7 +958,7 @@ is to raise self.failureException with an error message useful for debugging the by explaining the inequalities in detail. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. class:: FunctionTestCase(testFunc[, setUp[, tearDown[, description]]]) Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Thu Apr 9 02:08:24 2009 @@ -233,6 +233,16 @@ (Contributed by Gregory Smith.) +* The :mod:`logging` module now implements a simple :class:`NullHandler` + class for applications that are not using logging but are calling + library code that does. Setting-up a null handler will suppress + spurious warnings like "No handlers could be found for logger X.Y.Z":: + + >>> h = logging.NullHandler() + >>> logging.getLogger("foo").addHandler(h) + + (Contributed by Vinay Sajip; issue:`4384`). + * The :mod:`runpy` module which supports the ``-m`` command line switch now supports the execution of packages by looking for and executing a ``__main__`` submodule when a package name is supplied. @@ -269,7 +279,30 @@ def test_gimzo_without_required_library(self): ... - (Contributed by Benjamin Peterson.) + Also, tests for exceptions have been builtout to work with context managers:: + + def test_division_by_zero(self): + with self.assertRaises(ZeroDivisionError): + x / 0 + + In addition, several new assertion methods were added including + :func:`assertSetEqual`, :func:`assertDictEqual`, + :func:`assertDictContainsSubset`, :func:`assertListEqual`, + :func:`assertTupleEqual`, :func:`assertSequenceEqual`, + :func:`assertRaisesRegexp`, :func:`assertIsNone`, + and :func:`assertIsNotNot`. + + (Contributed by Benjamin Peterson and Antoine Pitrou.) + +* The :mod:`io` module has three new constants for :meth:`seek`: + method :data:`SEEK_SET`, :data:`SEEK_CUR`, and :data:`SEEK_END`. + +* The :attr:`sys.version_info` tuple is now a named tuple:: + + >>> sys.version_info + sys.version_info(major=3, minor=1, micro=0, releaselevel='alpha', serial=2) + + (Contributed by Ross Light; :issue:`4285`.) * A new module, :mod:`importlib` was added. It provides a complete, portable, pure Python reference implementation of the *import* statement and its @@ -319,7 +352,13 @@ its performance. The code is expected to be added in-time for the beta release. - (Contributed by Bob Ippolito.) + (Contributed by Bob Ippolito and converted to Py3.1 by Antoine Pitrou; + :issue:`4136`.) + +Build and C API Changes +======================= + +Changes to Python's build process and to the C API include: * Integers are now stored internally either in base 2**15 or in base 2**30, the base being determined at build time. Previously, they @@ -342,3 +381,11 @@ (Contributed by Mark Dickinson; :issue:`4258`.) +* The :cfunc:`PyLong_AsUnsignedLongLong()` function now handles a negative + *pylong* by raising :exc:`OverflowError` instead of :exc:`TypeError`. + + (Contributed by Mark Dickinson and Lisandro Dalcrin; :issue:`5175`.) + +* Deprecated :cfunc:`PyNumber_Int`. Use :cfunc:`PyNumber_Long` instead. + + (Contributed by Mark Dickinson; :issue;`4910`.) From python-checkins at python.org Thu Apr 9 02:18:29 2009 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 9 Apr 2009 02:18:29 +0200 (CEST) Subject: [Python-checkins] r71404 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090409001829.BCFA61E4018@bag.python.org> Author: raymond.hettinger Date: Thu Apr 9 02:18:29 2009 New Revision: 71404 Log: Fix markup Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Thu Apr 9 02:18:29 2009 @@ -294,7 +294,7 @@ (Contributed by Benjamin Peterson and Antoine Pitrou.) -* The :mod:`io` module has three new constants for :meth:`seek`: +* The :mod:`io` module has three new constants for the :meth:`seek` method :data:`SEEK_SET`, :data:`SEEK_CUR`, and :data:`SEEK_END`. * The :attr:`sys.version_info` tuple is now a named tuple:: @@ -388,4 +388,4 @@ * Deprecated :cfunc:`PyNumber_Int`. Use :cfunc:`PyNumber_Long` instead. - (Contributed by Mark Dickinson; :issue;`4910`.) + (Contributed by Mark Dickinson; :issue:`4910`.) From python-checkins at python.org Thu Apr 9 13:22:47 2009 From: python-checkins at python.org (andrew.kuchling) Date: Thu, 9 Apr 2009 13:22:47 +0200 (CEST) Subject: [Python-checkins] r71405 - python/trunk/Doc/whatsnew/2.7.rst Message-ID: <20090409112247.B7A881E4012@bag.python.org> Author: andrew.kuchling Date: Thu Apr 9 13:22:47 2009 New Revision: 71405 Log: Add items Modified: python/trunk/Doc/whatsnew/2.7.rst Modified: python/trunk/Doc/whatsnew/2.7.rst ============================================================================== --- python/trunk/Doc/whatsnew/2.7.rst (original) +++ python/trunk/Doc/whatsnew/2.7.rst Thu Apr 9 13:22:47 2009 @@ -322,6 +322,12 @@ with any object literal that decodes to a list of pairs. (Contributed by Raymond Hettinger; :issue:`5381`.) +* The :mod:`multiprocessing` module's :class:`Manager*` classes + can now be passed a callable that will be called whenever + a subprocess is started, along with a set of arguments that will be + passed to the callable. + (Contributed by lekma; :issue:`5585`.) + * The :mod:`pydoc` module now has help for the various symbols that Python uses. You can now do ``help('<<')`` or ``help('@')``, for example. (Contributed by David Laban; :issue:`4739`.) @@ -348,21 +354,82 @@ (Contributed by Ross Light; :issue:`4285`.) * The :mod:`unittest` module was enhanced in several ways. - Test cases can raise the :exc:`SkipTest` exception to skip a test. - (:issue:`1034053`.) - It will now use 'x' for expected failures + The progress messages will now print 'x' for expected failures and 'u' for unexpected successes when run in its verbose mode. (Contributed by Benjamin Peterson.) + Test cases can raise the :exc:`SkipTest` exception to skip a test. + (:issue:`1034053`.) + + The error messages for :meth:`assertEqual`, + :meth:`assertTrue`, and :meth:`assertFalse` + failures now provide more information. If you set the + :attr:`longMessage` attribute of your :class:`TestCase` classes to + true, both the standard error message and any additional message you + provide will be printed for failures. (Added by Michael Foord; :issue:`5663`.) The :meth:`assertRaises` and :meth:`failUnlessRaises` methods now return a context handler when called without providing a callable object to run. For example, you can write this:: - with self.assertRaises(KeyError): - raise ValueError + with self.assertRaises(KeyError): + raise ValueError (Implemented by Antoine Pitrou; :issue:`4444`.) + A number of new methods were added that provide more specialized + tests. Many of these methods were written by Google engineers + for use in their test suites; Gregory P. Smith, Michael Foord, and + GvR worked on merging them into Python's version of :mod:`unittest`. + + * :meth:`assertIsNone` and :meth:`assertIsNotNone` take one + expression and verify that the result is or is not ``None``. + + * :meth:`assertIs` and :meth:`assertIsNot` take two values and check + whether the two values evaluate to the same object or not. + (Added by Michael Foord; :issue:`2578`.) + + * :meth:`assertGreater`, :meth:`assertGreaterEqual`, + :meth:`assertLess`, and :meth:`assertLessEqual` compare + two quantities. + + * :meth:`assertMultiLineEqual` compares two strings, and if they're + not equal, displays a helpful comparison that highlights the + differences in the two strings. + + * :meth:`assertRegexpMatches` checks whether its first argument is a + string matching a regular expression provided as its second argument. + + * :meth:`assertRaisesRegexp` checks whether a particular exception + is raised, and then also checks that the string representation of + the exception matches the provided regular expression. + + * :meth:`assertIn` and :meth:`assertNotIn` tests whether + *first* is or is not in *second*. + + * :meth:`assertSameElements` tests whether two provided sequences + contain the same elements. + + * :meth:`assertSetEqual` compares whether two sets are equal, and + only reports the differences between the sets in case of error. + + * Similarly, :meth:`assertListEqual` and :meth:`assertTupleEqual` + compare the specified types and explain the differences. + More generally, :meth:`assertSequenceEqual` compares two sequences + and can optionally check whether both sequences are of a + particular type. + + * :meth:`assertDictEqual` compares two dictionaries and reports the + differences. :meth:`assertDictContainsSubset` checks whether + all of the key/value pairs in *first* are found in *second*. + + * A new hook, :meth:`addTypeEqualityFunc` takes a type object and a + function. The :meth:`assertEqual` method will use the function + when both of the objects being compared are of the specified type. + This function should compare the two objects and raise an + exception if they don't match; it's a good idea for the function + to provide additional information about why the two objects are + matching, much as the new sequence comparison methods do. + * The :func:`is_zipfile` function in the :mod:`zipfile` module will now accept a file object, in addition to the path names accepted in earlier versions. (Contributed by Gabriel Genellina; :issue:`4756`.) From python-checkins at python.org Thu Apr 9 13:23:36 2009 From: python-checkins at python.org (andrew.kuchling) Date: Thu, 9 Apr 2009 13:23:36 +0200 (CEST) Subject: [Python-checkins] r71406 - in python/trunk: Doc/library/unittest.rst Misc/NEWS Message-ID: <20090409112336.B77701E4012@bag.python.org> Author: andrew.kuchling Date: Thu Apr 9 13:23:36 2009 New Revision: 71406 Log: Typo fixes Modified: python/trunk/Doc/library/unittest.rst python/trunk/Misc/NEWS Modified: python/trunk/Doc/library/unittest.rst ============================================================================== --- python/trunk/Doc/library/unittest.rst (original) +++ python/trunk/Doc/library/unittest.rst Thu Apr 9 13:23:36 2009 @@ -690,7 +690,7 @@ assertLessEqual(first, second, msg=None) Test that *first* is respectively >, >=, < or <= than *second* depending - on the method name. If not, the test will fail with the nice explanation + on the method name. If not, the test will fail with an explanation or with the explanation given by *msg*:: >>> self.assertGreaterEqual(3, 4) @@ -723,7 +723,7 @@ .. method:: assertIn(first, second, msg=None) assertNotIn(first, second, msg=None) - Tests that *first* is or is not in *second* with a nice explanitory error + Tests that *first* is or is not in *second* with an explanatory error message as appropriate. If specified *msg* will be used as the error message on failure. @@ -767,7 +767,7 @@ .. method:: assertDictContainsSubset(expected, actual, msg=None) - Tests whether the key value pairs in dictionary *actual* are a + Tests whether the key/value pairs in dictionary *actual* are a superset of those in *expected*. If not, an error message listing the missing keys and mismatched values is generated. @@ -969,12 +969,12 @@ been asked to compare are exactly *typeobj* (not subclasses). *function* must take two positional arguments and a third msg=None keyword argument just as :meth:`assertEqual` does. It must raise - self.failureException when inequality between the first two + ``self.failureException`` when inequality between the first two parameters is detected. One good use of custom equality checking functions for a type - is to raise self.failureException with an error message useful - for debugging the by explaining the inequalities in detail. + is to raise ``self.failureException`` with an error message useful + for debugging the problem by explaining the inequalities in detail. .. versionadded:: 2.7 Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Apr 9 13:23:36 2009 @@ -239,7 +239,7 @@ mailbox.MH.get_message(). - Issue #5585: Add the ability to call an initializer to mulitiprocessing.manager - so that users can install custonm handlers/etc. + so that users can install custom handlers/etc. - Issue #3551: Patch multiprocessing to raise a proper exception if the size of the object when writefile is called causes a ERROR_NO_SYSTEM_RESOURCES. Added docs From python-checkins at python.org Thu Apr 9 13:57:59 2009 From: python-checkins at python.org (eric.smith) Date: Thu, 9 Apr 2009 13:57:59 +0200 (CEST) Subject: [Python-checkins] r71407 - in python/branches/py3k-short-float-repr: Include/pystrtod.h Objects/complexobject.c Message-ID: <20090409115759.9E5541E4012@bag.python.org> Author: eric.smith Date: Thu Apr 9 13:57:59 2009 New Revision: 71407 Log: Added a comment about freeing memory returned from PyOS_double_to_string. Fixed a memory leak in complex_format. Both thanks to Nick Coghlan's review on Rietveld. Modified: python/branches/py3k-short-float-repr/Include/pystrtod.h python/branches/py3k-short-float-repr/Objects/complexobject.c Modified: python/branches/py3k-short-float-repr/Include/pystrtod.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/pystrtod.h (original) +++ python/branches/py3k-short-float-repr/Include/pystrtod.h Thu Apr 9 13:57:59 2009 @@ -9,6 +9,9 @@ PyAPI_FUNC(double) PyOS_ascii_strtod(const char *str, char **ptr); PyAPI_FUNC(double) PyOS_ascii_atof(const char *str); PyAPI_FUNC(char *) PyOS_ascii_formatd(char *buffer, size_t buf_len, const char *format, double d); + +/* The caller is responsible for calling PyMem_Free to free the buffer + that's is returned. */ PyAPI_FUNC(char *) PyOS_double_to_string(double val, char format_code, int precision, Modified: python/branches/py3k-short-float-repr/Objects/complexobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/complexobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/complexobject.c Thu Apr 9 13:57:59 2009 @@ -334,11 +334,11 @@ { PyObject *result = NULL; Py_ssize_t len; - char *buf; /* If these are non-NULL, they'll need to be freed. */ char *pre = NULL; char *pim = NULL; + char *buf = NULL; /* These do not need to be freed. They're either aliases for pim and pre, or pointers to constants. */ @@ -420,6 +420,7 @@ done: PyMem_Free(pim); PyMem_Free(pre); + PyMem_Free(buf); return result; } From python-checkins at python.org Thu Apr 9 18:46:47 2009 From: python-checkins at python.org (collin.winter) Date: Thu, 9 Apr 2009 18:46:47 +0200 (CEST) Subject: [Python-checkins] r71408 - in python/trunk/Lib/test: pickletester.py regrtest.py test_cpickle.py test_pickle.py test_xpickle.py Message-ID: <20090409164647.049311E4013@bag.python.org> Author: collin.winter Date: Thu Apr 9 18:46:46 2009 New Revision: 71408 Log: Issue 5665: add more pickling tests. - Add tests for the module-level load() and dump() functions. - Add tests for cPickle's internal data structures, stressing workloads with many gets/puts. - Add tests for the Pickler and Unpickler classes, in particular the memo attribute. - test_xpickle is extended to test backwards compatibility with Python 2.4, 2.5 and 2.6 by round-tripping pickled objects through a worker process. This is guarded with a regrtest -u xpickle resource. Modified: python/trunk/Lib/test/pickletester.py python/trunk/Lib/test/regrtest.py python/trunk/Lib/test/test_cpickle.py python/trunk/Lib/test/test_pickle.py python/trunk/Lib/test/test_xpickle.py Modified: python/trunk/Lib/test/pickletester.py ============================================================================== --- python/trunk/Lib/test/pickletester.py (original) +++ python/trunk/Lib/test/pickletester.py Thu Apr 9 18:46:46 2009 @@ -1,11 +1,11 @@ import unittest import pickle import cPickle +import cStringIO import pickletools import copy_reg -from test.test_support import TestFailed, have_unicode, TESTFN, \ - run_with_locale +from test.test_support import TestFailed, have_unicode, TESTFN # Tests that try a number of pickle protocols should have a # for proto in protocols: @@ -13,6 +13,42 @@ assert pickle.HIGHEST_PROTOCOL == cPickle.HIGHEST_PROTOCOL == 2 protocols = range(pickle.HIGHEST_PROTOCOL + 1) +# Copy of test.test_support.run_with_locale. This is needed to support Python +# 2.4, which didn't include it. This is all to support test_xpickle, which +# bounces pickled objects through older Python versions to test backwards +# compatibility. +def run_with_locale(catstr, *locales): + def decorator(func): + def inner(*args, **kwds): + try: + import locale + category = getattr(locale, catstr) + orig_locale = locale.setlocale(category) + except AttributeError: + # if the test author gives us an invalid category string + raise + except: + # cannot retrieve original locale, so do nothing + locale = orig_locale = None + else: + for loc in locales: + try: + locale.setlocale(category, loc) + break + except: + pass + + # now run the function, resetting the locale on exceptions + try: + return func(*args, **kwds) + finally: + if locale and orig_locale: + locale.setlocale(category, orig_locale) + inner.func_name = func.func_name + inner.__doc__ = func.__doc__ + return inner + return decorator + # Return True if opcode code appears in the pickle, else False. def opcode_in_pickle(code, pickle): @@ -409,12 +445,11 @@ # is a mystery. cPickle also suppresses PUT for objects with a refcount # of 1. def dont_test_disassembly(self): - from cStringIO import StringIO from pickletools import dis for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS): s = self.dumps(self._testdata, proto) - filelike = StringIO() + filelike = cStringIO.StringIO() dis(s, out=filelike) got = filelike.getvalue() self.assertEqual(expected, got) @@ -822,7 +857,7 @@ self.assertEqual(x.bar, y.bar) def test_reduce_overrides_default_reduce_ex(self): - for proto in 0, 1, 2: + for proto in protocols: x = REX_one() self.assertEqual(x._reduce_called, 0) s = self.dumps(x, proto) @@ -831,7 +866,7 @@ self.assertEqual(y._reduce_called, 0) def test_reduce_ex_called(self): - for proto in 0, 1, 2: + for proto in protocols: x = REX_two() self.assertEqual(x._proto, None) s = self.dumps(x, proto) @@ -840,7 +875,7 @@ self.assertEqual(y._proto, None) def test_reduce_ex_overrides_reduce(self): - for proto in 0, 1, 2: + for proto in protocols: x = REX_three() self.assertEqual(x._proto, None) s = self.dumps(x, proto) @@ -849,7 +884,7 @@ self.assertEqual(y._proto, None) def test_reduce_ex_calls_base(self): - for proto in 0, 1, 2: + for proto in protocols: x = REX_four() self.assertEqual(x._proto, None) s = self.dumps(x, proto) @@ -858,7 +893,7 @@ self.assertEqual(y._proto, proto) def test_reduce_calls_base(self): - for proto in 0, 1, 2: + for proto in protocols: x = REX_five() self.assertEqual(x._reduce_called, 0) s = self.dumps(x, proto) @@ -879,7 +914,7 @@ return dict, (), None, None, [] # Protocol 0 is less strict and also accept iterables. - for proto in 0, 1, 2: + for proto in protocols: try: self.dumps(C(), proto) except (AttributeError, pickle.PickleError, cPickle.PickleError): @@ -889,6 +924,21 @@ except (AttributeError, pickle.PickleError, cPickle.PickleError): pass + def test_many_puts_and_gets(self): + # Test that internal data structures correctly deal with lots of + # puts/gets. + keys = ("aaa" + str(i) for i in xrange(100)) + large_dict = dict((k, [4, 5, 6]) for k in keys) + obj = [dict(large_dict), dict(large_dict), dict(large_dict)] + + for proto in protocols: + dumped = self.dumps(obj, proto) + loaded = self.loads(dumped) + self.assertEqual(loaded, obj, + "Failed protocol %d: %r != %r" + % (proto, obj, loaded)) + + # Test classes for reduce_ex class REX_one(object): @@ -990,13 +1040,20 @@ finally: os.remove(TESTFN) + def test_load_from_and_dump_to_file(self): + stream = cStringIO.StringIO() + data = [123, {}, 124] + self.module.dump(data, stream) + stream.seek(0) + unpickled = self.module.load(stream) + self.assertEqual(unpickled, data) + def test_highest_protocol(self): # Of course this needs to be changed when HIGHEST_PROTOCOL changes. self.assertEqual(self.module.HIGHEST_PROTOCOL, 2) def test_callapi(self): - from cStringIO import StringIO - f = StringIO() + f = cStringIO.StringIO() # With and without keyword arguments self.module.dump(123, f, -1) self.module.dump(123, file=f, protocol=-1) @@ -1039,3 +1096,116 @@ self.assertEqual(self.loads(self.dumps(L, 1)), L) self.assertEqual(self.id_count, 5) self.assertEqual(self.load_count, 5) + +class AbstractPicklerUnpicklerObjectTests(unittest.TestCase): + + pickler_class = None + unpickler_class = None + + def setUp(self): + assert self.pickler_class + assert self.unpickler_class + + def test_clear_pickler_memo(self): + # To test whether clear_memo() has any effect, we pickle an object, + # then pickle it again without clearing the memo; the two serialized + # forms should be different. If we clear_memo() and then pickle the + # object again, the third serialized form should be identical to the + # first one we obtained. + data = ["abcdefg", "abcdefg", 44] + f = cStringIO.StringIO() + pickler = self.pickler_class(f) + + pickler.dump(data) + first_pickled = f.getvalue() + + # Reset StringIO object. + f.seek(0) + f.truncate() + + pickler.dump(data) + second_pickled = f.getvalue() + + # Reset the Pickler and StringIO objects. + pickler.clear_memo() + f.seek(0) + f.truncate() + + pickler.dump(data) + third_pickled = f.getvalue() + + self.assertNotEqual(first_pickled, second_pickled) + self.assertEqual(first_pickled, third_pickled) + + def test_priming_pickler_memo(self): + # Verify that we can set the Pickler's memo attribute. + data = ["abcdefg", "abcdefg", 44] + f = cStringIO.StringIO() + pickler = self.pickler_class(f) + + pickler.dump(data) + first_pickled = f.getvalue() + + f = cStringIO.StringIO() + primed = self.pickler_class(f) + primed.memo = pickler.memo + + primed.dump(data) + primed_pickled = f.getvalue() + + self.assertNotEqual(first_pickled, primed_pickled) + + def test_priming_unpickler_memo(self): + # Verify that we can set the Unpickler's memo attribute. + data = ["abcdefg", "abcdefg", 44] + f = cStringIO.StringIO() + pickler = self.pickler_class(f) + + pickler.dump(data) + first_pickled = f.getvalue() + + f = cStringIO.StringIO() + primed = self.pickler_class(f) + primed.memo = pickler.memo + + primed.dump(data) + primed_pickled = f.getvalue() + + unpickler = self.unpickler_class(cStringIO.StringIO(first_pickled)) + unpickled_data1 = unpickler.load() + + self.assertEqual(unpickled_data1, data) + + primed = self.unpickler_class(cStringIO.StringIO(primed_pickled)) + primed.memo = unpickler.memo + unpickled_data2 = primed.load() + + primed.memo.clear() + + self.assertEqual(unpickled_data2, data) + self.assertTrue(unpickled_data2 is unpickled_data1) + + def test_reusing_unpickler_objects(self): + data1 = ["abcdefg", "abcdefg", 44] + f = cStringIO.StringIO() + pickler = self.pickler_class(f) + pickler.dump(data1) + pickled1 = f.getvalue() + + data2 = ["abcdefg", 44, 44] + f = cStringIO.StringIO() + pickler = self.pickler_class(f) + pickler.dump(data2) + pickled2 = f.getvalue() + + f = cStringIO.StringIO() + f.write(pickled1) + f.seek(0) + unpickler = self.unpickler_class(f) + self.assertEqual(unpickler.load(), data1) + + f.seek(0) + f.truncate() + f.write(pickled2) + f.seek(0) + self.assertEqual(unpickler.load(), data2) Modified: python/trunk/Lib/test/regrtest.py ============================================================================== --- python/trunk/Lib/test/regrtest.py (original) +++ python/trunk/Lib/test/regrtest.py Thu Apr 9 18:46:46 2009 @@ -122,6 +122,10 @@ gui - Run tests that require a running GUI. + xpickle - Test pickle and cPickle against Python 2.4, 2.5 and 2.6 to + test backwards compatibility. These tests take a long time + to run. + To enable all resources except one, use '-uall,-'. For example, to run all the tests except for the bsddb tests, give the option '-uall,-bsddb'. @@ -175,7 +179,8 @@ from test import test_support RESOURCE_NAMES = ('audio', 'curses', 'largefile', 'network', 'bsddb', - 'decimal', 'compiler', 'subprocess', 'urlfetch', 'gui') + 'decimal', 'compiler', 'subprocess', 'urlfetch', 'gui', + 'xpickle') def usage(code, msg=''): Modified: python/trunk/Lib/test/test_cpickle.py ============================================================================== --- python/trunk/Lib/test/test_cpickle.py (original) +++ python/trunk/Lib/test/test_cpickle.py Thu Apr 9 18:46:46 2009 @@ -1,6 +1,7 @@ import cPickle, unittest from cStringIO import StringIO from test.pickletester import AbstractPickleTests, AbstractPickleModuleTests +from test.pickletester import AbstractPicklerUnpicklerObjectTests from test import test_support class cPickleTests(AbstractPickleTests, AbstractPickleModuleTests): @@ -90,6 +91,12 @@ b = self.loads(self.dumps(a)) self.assertEqual(a, b) +class cPicklePicklerUnpicklerObjectTests(AbstractPicklerUnpicklerObjectTests): + + pickler_class = cPickle.Pickler + unpickler_class = cPickle.Unpickler + + class Node(object): pass @@ -120,6 +127,7 @@ cPickleListPicklerTests, cPickleFastPicklerTests, cPickleDeepRecursive, + cPicklePicklerUnpicklerObjectTests, ) if __name__ == "__main__": Modified: python/trunk/Lib/test/test_pickle.py ============================================================================== --- python/trunk/Lib/test/test_pickle.py (original) +++ python/trunk/Lib/test/test_pickle.py Thu Apr 9 18:46:46 2009 @@ -6,6 +6,7 @@ from test.pickletester import AbstractPickleTests from test.pickletester import AbstractPickleModuleTests from test.pickletester import AbstractPersistentPicklerTests +from test.pickletester import AbstractPicklerUnpicklerObjectTests class PickleTests(AbstractPickleTests, AbstractPickleModuleTests): @@ -60,11 +61,18 @@ u = PersUnpickler(f) return u.load() +class PicklerUnpicklerObjectTests(AbstractPicklerUnpicklerObjectTests): + + pickler_class = pickle.Pickler + unpickler_class = pickle.Unpickler + + def test_main(): test_support.run_unittest( PickleTests, PicklerTests, - PersPicklerTests + PersPicklerTests, + PicklerUnpicklerObjectTests, ) test_support.run_doctest(pickle) Modified: python/trunk/Lib/test/test_xpickle.py ============================================================================== --- python/trunk/Lib/test/test_xpickle.py (original) +++ python/trunk/Lib/test/test_xpickle.py Thu Apr 9 18:46:46 2009 @@ -1,19 +1,42 @@ # test_pickle dumps and loads pickles via pickle.py. # test_cpickle does the same, but via the cPickle module. # This test covers the other two cases, making pickles with one module and -# loading them via the other. +# loading them via the other. It also tests backwards compatibility with +# previous version of Python by bouncing pickled objects through Python 2.4 +# and Python 2.5 running this file. -import pickle import cPickle +import os +import os.path +import pickle +import subprocess +import sys +import types +import unittest from test import test_support -from test.pickletester import AbstractPickleTests + +# Most distro-supplied Pythons don't include the tests +# or test support files, and some don't include a way to get these back even if +# you're will to install extra packages (like Ubuntu). Doing things like this +# "provides" a pickletester module for older versions of Python that may be +# installed without it. Note that one other design for this involves messing +# with sys.path, which is less precise. +mod_path = os.path.abspath(os.path.join(os.path.dirname(__file__), + "pickletester.py")) +pickletester = types.ModuleType("test.pickletester") +execfile(mod_path, pickletester.__dict__, pickletester.__dict__) +AbstractPickleTests = pickletester.AbstractPickleTests +if pickletester.__name__ in sys.modules: + raise RuntimeError("Did not expect to find test.pickletester loaded") +sys.modules[pickletester.__name__] = pickletester + class DumpCPickle_LoadPickle(AbstractPickleTests): error = KeyError - def dumps(self, arg, proto=0, fast=0): + def dumps(self, arg, proto=0, fast=False): # Ignore fast return cPickle.dumps(arg, proto) @@ -25,7 +48,7 @@ error = cPickle.BadPickleGet - def dumps(self, arg, proto=0, fast=0): + def dumps(self, arg, proto=0, fast=False): # Ignore fast return pickle.dumps(arg, proto) @@ -33,11 +56,204 @@ # Ignore fast return cPickle.loads(buf) +def have_python_version(name): + """Check whether the given name is a valid Python binary. + + This respects your PATH. + + Args: + name: short string name of a Python binary such as "python2.4". + + Returns: + True if the name is valid, False otherwise. + """ + return os.system(name + " -c 'import sys; sys.exit()'") == 0 + + +class AbstractCompatTests(AbstractPickleTests): + + module = None + python = None + error = None + + def setUp(self): + self.assertTrue(self.python) + self.assertTrue(self.module) + self.assertTrue(self.error) + + def send_to_worker(self, python, obj, proto): + """Bounce a pickled object through another version of Python. + + This will pickle the object, send it to a child process where it will be + unpickled, then repickled and sent back to the parent process. + + Args: + python: the name of the Python binary to start. + obj: object to pickle. + proto: pickle protocol number to use. + + Returns: + The pickled data received from the child process. + """ + # Prevent the subprocess from picking up invalid .pyc files. + target = __file__ + if target[-1] in ("c", "o"): + target = target[:-1] + + data = self.module.dumps((proto, obj), proto) + worker = subprocess.Popen([python, target, "worker"], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + stdout, stderr = worker.communicate(data) + if worker.returncode != 0: + raise RuntimeError(stderr) + return stdout + + def dumps(self, arg, proto=0, fast=False): + return self.send_to_worker(self.python, arg, proto) + + def loads(self, input): + return self.module.loads(input) + + # These tests are disabled because they require some special setup + # on the worker that's hard to keep in sync. + def test_global_ext1(self): + pass + + def test_global_ext2(self): + pass + + def test_global_ext4(self): + pass + + # This is a cut-down version of pickletester's test_float. Backwards + # compatibility for the values in for_bin_protos was explicitly broken in + # r68903 to fix a bug. + def test_float(self): + for_bin_protos = [4.94e-324, 1e-310] + neg_for_bin_protos = [-x for x in for_bin_protos] + test_values = [0.0, 7e-308, 6.626e-34, 0.1, 0.5, + 3.14, 263.44582062374053, 6.022e23, 1e30] + test_proto0_values = test_values + [-x for x in test_values] + test_values = test_proto0_values + for_bin_protos + neg_for_bin_protos + + for value in test_proto0_values: + pickle = self.dumps(value, 0) + got = self.loads(pickle) + self.assertEqual(value, got) + + for proto in pickletester.protocols[1:]: + for value in test_values: + pickle = self.dumps(value, proto) + got = self.loads(pickle) + self.assertEqual(value, got) + + # Backwards compatibility was explicitly broken in r67934 to fix a bug. + def test_unicode_high_plane(self): + pass + + if test_support.have_unicode: + # This is a cut-down version of pickletester's test_unicode. Backwards + # compatibility was explicitly broken in r67934 to fix a bug. + def test_unicode(self): + endcases = [u'', u'<\\u>', u'<\\\u1234>', u'<\n>', u'<\\>'] + for proto in pickletester.protocols: + for u in endcases: + p = self.dumps(u, proto) + u2 = self.loads(p) + self.assertEqual(u2, u) + + +def run_compat_test(python_name): + return (test_support.is_resource_enabled("xpickle") and + have_python_version(python_name)) + + +# Test backwards compatibility with Python 2.4. +if not run_compat_test("python2.4"): + class CPicklePython24Compat(unittest.TestCase): + pass +else: + class CPicklePython24Compat(AbstractCompatTests): + + module = cPickle + python = "python2.4" + error = cPickle.BadPickleGet + + # Disable these tests for Python 2.4. Making them pass would require + # nontrivially monkeypatching the pickletester module in the worker. + def test_reduce_calls_base(self): + pass + + def test_reduce_ex_calls_base(self): + pass + +class PicklePython24Compat(CPicklePython24Compat): + + module = pickle + error = KeyError + + +# Test backwards compatibility with Python 2.5. +if not run_compat_test("python2.5"): + class CPicklePython25Compat(unittest.TestCase): + pass +else: + class CPicklePython25Compat(AbstractCompatTests): + + module = cPickle + python = "python2.5" + error = cPickle.BadPickleGet + +class PicklePython25Compat(CPicklePython25Compat): + + module = pickle + error = KeyError + + +# Test backwards compatibility with Python 2.6. +if not run_compat_test("python2.6"): + class CPicklePython26Compat(unittest.TestCase): + pass +else: + class CPicklePython26Compat(AbstractCompatTests): + + module = cPickle + python = "python2.6" + error = cPickle.BadPickleGet + +class PicklePython26Compat(CPicklePython26Compat): + + module = pickle + error = KeyError + + +def worker_main(in_stream, out_stream): + message = cPickle.load(in_stream) + protocol, obj = message + cPickle.dump(obj, out_stream, protocol) + + def test_main(): + if not test_support.is_resource_enabled("xpickle"): + print >>sys.stderr, "test_xpickle -- skipping backwards compat tests." + print >>sys.stderr, "Use 'regrtest.py -u xpickle' to run them." + sys.stderr.flush() + test_support.run_unittest( DumpCPickle_LoadPickle, - DumpPickle_LoadCPickle + DumpPickle_LoadCPickle, + CPicklePython24Compat, + CPicklePython25Compat, + CPicklePython26Compat, + PicklePython24Compat, + PicklePython25Compat, + PicklePython26Compat, ) if __name__ == "__main__": - test_main() + if "worker" in sys.argv: + worker_main(sys.stdin, sys.stdout) + else: + test_main() From python-checkins at python.org Thu Apr 9 21:01:05 2009 From: python-checkins at python.org (georg.brandl) Date: Thu, 9 Apr 2009 21:01:05 +0200 (CEST) Subject: [Python-checkins] r71409 - python/trunk/Doc/tools/sphinxext/static/basic.css Message-ID: <20090409190105.081441E401D@bag.python.org> Author: georg.brandl Date: Thu Apr 9 21:01:04 2009 New Revision: 71409 Log: Add a custom stylesheet with better table formatting. Added: python/trunk/Doc/tools/sphinxext/static/basic.css Added: python/trunk/Doc/tools/sphinxext/static/basic.css ============================================================================== --- (empty file) +++ python/trunk/Doc/tools/sphinxext/static/basic.css Thu Apr 9 21:01:04 2009 @@ -0,0 +1,415 @@ +/** + * Sphinx stylesheet -- basic theme + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 230px; +} + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +img { + border: 0; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable dl, table.indextable dd { + margin-top: 0; + margin-bottom: 0; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +/* -- general body styles --------------------------------------------------- */ + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.field-list ul { + padding-left: 1em; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.field-list td, table.field-list th { + border: 0 !important; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; + background-color: #ede; +} + +/* -- other body styles ----------------------------------------------------- */ + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, .highlight { + background-color: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.refcount { + color: #060; +} + +.optional { + font-size: 1.3em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +tt.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +tt.descclassname { + background-color: transparent; +} + +tt.xref, a tt { + background-color: transparent; + font-weight: bold; +} + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + background-color: transparent; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +/* -- printout stylesheet --------------------------------------------------- */ + + at media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} From python-checkins at python.org Thu Apr 9 21:37:49 2009 From: python-checkins at python.org (tarek.ziade) Date: Thu, 9 Apr 2009 21:37:49 +0200 (CEST) Subject: [Python-checkins] r71410 - peps/branches/jim-update-345/pep-0345.txt Message-ID: <20090409193749.0B0151E401B@bag.python.org> Author: tarek.ziade Date: Thu Apr 9 21:37:48 2009 New Revision: 71410 Log: Tres Seaver's changes (Pycon) Modified: peps/branches/jim-update-345/pep-0345.txt Modified: peps/branches/jim-update-345/pep-0345.txt ============================================================================== --- peps/branches/jim-update-345/pep-0345.txt (original) +++ peps/branches/jim-update-345/pep-0345.txt Thu Apr 9 21:37:48 2009 @@ -26,8 +26,10 @@ Version 1.2 of the metadata format adds a number of optional fields designed to make third-party packaging of Python Software easier. -These fields are "Requires-Python" and "Requires-External". Also, the -"Metadata-Version" field is updated. +These fields are "Requires-Python", "Requires-External", "Requires-Dist", +"Provides-Dist", and "Obsoletes-Dist". This version also updates the +"Metadata-Version" field, and adds new fields, "Maintainer" and +Maintainer-email". Fields @@ -159,6 +161,32 @@ Author-email: "C. Schultz" +Maintainer (optional) + A string containing the maintainer's name at a minimum; additional + contact information may be provided. + + Note that this field is intended for use when a package is being + maintained by someone other than the original author: it should be + omitted if it is identical to 'Author'. + + Example:: + + Maintainer: C. Schultz, Universal Features Syndicate, + Los Angeles, CA + +Maintainer-email (optional) + A string containing the maintainer's e-mail address. It can contain + a name and e-mail address in the legal forms for a RFC-822 + 'From:' header. + + Note that this field is intended for use when a package is being + maintained by someone other than the original author: it should be + omitted if it is identical to 'Author'. + + Example:: + + Maintainer-email: "C. Schultz" + License Text indicating the license covering the package where the license is not a selection from the "License" Trove classifiers. See @@ -213,6 +241,8 @@ Requires: xml.parsers.expat (>1.0) Requires: psycopg + Note: this field is now deprecated in favor of 'Requires-Dist'. + Provides (multiple use) Each entry contains a string describing a package or module that will be provided by this package once it is installed. These @@ -229,6 +259,8 @@ Provides: xml.dom Provides: xmltools (1.3) + Note: this field is now deprecated in favor of 'Provides-Dist'. + Obsoletes (multiple use) Each entry contains a string describing a package or module that this package renders obsolete, meaning that the two packages @@ -244,6 +276,71 @@ Obsoletes: Gorgon + Note: this field is now deprecated in favor of 'Obsoletes-Dist'. + +Requires-Dist (multiple use) + Each entry contains a string naming some other distutils + project required by this package. + + The format of a requirement string is identical to that of a + distutils project name (e.g., as found in the 'Name:' field. + optionally followed by a version declaration within parentheses. + + A version declaration is a series of conditional operators and + version numbers, separated by commas. Conditional operators + must be one of "<", ">", "<=", ">=", "==", and "!=". Version + numbers must be in the format accepted by the + 'verlib.py' module (see PEP ###). + + Any number of conditional operators can be specified, e.g. + the string ">1.0, !=1.3.4, <2.0" is a legal version declaration. + + The distutils project names should correspond to names as found + on the Python Package Index (PyPI, see PEP ###). + + Example:: + + Requires-Dist: pkginfo + Requires-Dist: PasteDeploy + Requires-Dist: zope.interface (>3.5.0) + +Provides-Dist (multiple use) + Each entry contains a string naming a distutlis project which + is contained within this distribution. This field *must* include + the project identified in the 'Name' field. + + A distribution may provide additional names, e.g. to indicate that + multiple projects have been bundled together. + + A distribution may also provide a "virtual" project name, which does + not correspond to any separately-distributed project: such a name + might be used to indicate an abstract capability which could be supplied + by one of multiple projects. + + A version declaration may be supplied (without a comparison + operator); the package's version number will be implied if none + is specified. + + Example:: + + Provides-Dist: OtherPackage + Provides-Dist: virtual_package + +Obsoletes-Dist (multiple use) + Each entry contains a string describing a distutils project which + this package renders obsolete, meaning that the two packages + should not be installed at the same time. Version declarations + can be supplied. + + The most common use of this field will be in case a project name + changes, e.g. Gorgon 2.3 gets subsumed into Torqued Python 1.0. + When you install Torqued Python, the Gorgon distribution should be + removed. + + Example:: + + Obsoletes-Dist: Gorgon + Requires-Python This field specifies the Python version(s) that the package is guaranteed to be compatible with. The format of the field is a @@ -335,6 +432,27 @@ XXX command-line interface needs work, obviously +Summary of Differences From PEP 314 +----------------------------------- + +* Metadata-Version is now 1.2. + +* Added fields: + + - Maintainer + - Maintainer-email + - Requires-Python + - Requires-External + - Requires-Dist + - Provides-Dist + - Obsoletes-Dist + +* Deprecated fields: + + - Requires (in favor of Requires-Dist) + - Provides (in favor of Provides-Dist) + - Obsoletes (in favor of Obsoletes-Dist) + References ========== From python-checkins at python.org Thu Apr 9 21:39:41 2009 From: python-checkins at python.org (tarek.ziade) Date: Thu, 9 Apr 2009 21:39:41 +0200 (CEST) Subject: [Python-checkins] r71411 - peps/branches/jim-update-345/pep-0345.txt Message-ID: <20090409193941.A1E2A1E401B@bag.python.org> Author: tarek.ziade Date: Thu Apr 9 21:39:41 2009 New Revision: 71411 Log: typo Modified: peps/branches/jim-update-345/pep-0345.txt Modified: peps/branches/jim-update-345/pep-0345.txt ============================================================================== --- peps/branches/jim-update-345/pep-0345.txt (original) +++ peps/branches/jim-update-345/pep-0345.txt Thu Apr 9 21:39:41 2009 @@ -167,7 +167,7 @@ Note that this field is intended for use when a package is being maintained by someone other than the original author: it should be - omitted if it is identical to 'Author'. + omitted if it is identical to 'Author-email'. Example:: From python-checkins at python.org Thu Apr 9 21:42:18 2009 From: python-checkins at python.org (tarek.ziade) Date: Thu, 9 Apr 2009 21:42:18 +0200 (CEST) Subject: [Python-checkins] r71412 - peps/branches/jim-update-345/pep-0345.txt Message-ID: <20090409194218.32A961E401B@bag.python.org> Author: tarek.ziade Date: Thu Apr 9 21:42:17 2009 New Revision: 71412 Log: wrong place Modified: peps/branches/jim-update-345/pep-0345.txt Modified: peps/branches/jim-update-345/pep-0345.txt ============================================================================== --- peps/branches/jim-update-345/pep-0345.txt (original) +++ peps/branches/jim-update-345/pep-0345.txt Thu Apr 9 21:42:17 2009 @@ -167,7 +167,7 @@ Note that this field is intended for use when a package is being maintained by someone other than the original author: it should be - omitted if it is identical to 'Author-email'. + omitted if it is identical to 'Author'. Example:: @@ -181,7 +181,7 @@ Note that this field is intended for use when a package is being maintained by someone other than the original author: it should be - omitted if it is identical to 'Author'. + omitted if it is identical to 'Author-email'. Example:: From python-checkins at python.org Thu Apr 9 23:36:45 2009 From: python-checkins at python.org (tarek.ziade) Date: Thu, 9 Apr 2009 23:36:45 +0200 (CEST) Subject: [Python-checkins] r71413 - in python/trunk: Lib/distutils/command/bdist_wininst.py Lib/distutils/tests/test_bdist_wininst.py Misc/NEWS Message-ID: <20090409213645.1722F1E4029@bag.python.org> Author: tarek.ziade Date: Thu Apr 9 23:36:44 2009 New Revision: 71413 Log: Fixed #5731: Distutils bdist_wininst no longer worked on non-Windows platforms Added: python/trunk/Lib/distutils/tests/test_bdist_wininst.py (contents, props changed) Modified: python/trunk/Lib/distutils/command/bdist_wininst.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/distutils/command/bdist_wininst.py ============================================================================== --- python/trunk/Lib/distutils/command/bdist_wininst.py (original) +++ python/trunk/Lib/distutils/command/bdist_wininst.py Thu Apr 9 23:36:44 2009 @@ -342,10 +342,15 @@ directory = os.path.dirname(__file__) # we must use a wininst-x.y.exe built with the same C compiler # used for python. XXX What about mingw, borland, and so on? - if self.plat_name == 'win32': - sfix = '' + + # if plat_name starts with "win" but is not "win32" + # we want to strip "win" and leave the rest (e.g. -amd64) + # for all other cases, we don't want any suffix + if self.plat_name != 'win32' and self.plat_name[:3] == 'win': + sfix = self.plat_name[3:] else: - sfix = self.plat_name[3:] # strip 'win' - leaves eg '-amd64' + sfix = '' + filename = os.path.join(directory, "wininst-%.1f%s.exe" % (bv, sfix)) return open(filename, "rb").read() # class bdist_wininst Added: python/trunk/Lib/distutils/tests/test_bdist_wininst.py ============================================================================== --- (empty file) +++ python/trunk/Lib/distutils/tests/test_bdist_wininst.py Thu Apr 9 23:36:44 2009 @@ -0,0 +1,29 @@ +"""Tests for distutils.command.bdist_wininst.""" +import unittest + +from distutils.command.bdist_wininst import bdist_wininst +from distutils.tests import support + +class BuildWinInstTestCase(support.TempdirManager, + unittest.TestCase): + + def test_get_exe_bytes(self): + + # issue5731: command was broken on non-windows platforms + # this test makes sure it works now for every platform + # let's create a command + pkg_pth, dist = self.create_dist() + cmd = bdist_wininst(dist) + cmd.ensure_finalized() + + # let's run the code that finds the right wininst*.exe file + # and make sure it finds it and returns its content + # no matter what platform we have + exe_file = cmd.get_exe_bytes() + self.assert_(len(exe_file) > 10) + +def test_suite(): + return unittest.makeSuite(BuildWinInstTestCase) + +if __name__ == '__main__': + test_support.run_unittest(test_suite()) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Apr 9 23:36:44 2009 @@ -216,6 +216,9 @@ Library ------- +- Issue #5731: Distutils bdist_wininst no longer worked on non-Windows + platforms. Initial patch by Paul Moore. + - Issue #2254: Fix CGIHTTPServer information disclosure. Relative paths are now collapsed within the url properly before looking in cgi_directories. From python-checkins at python.org Thu Apr 9 23:54:50 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 9 Apr 2009 23:54:50 +0200 (CEST) Subject: [Python-checkins] r71414 - in python/trunk: Lib/test/test_minidom.py Lib/xml/dom/minidom.py Misc/NEWS Message-ID: <20090409215450.51F801E40F0@bag.python.org> Author: r.david.murray Date: Thu Apr 9 23:54:50 2009 New Revision: 71414 Log: Issue #2170: refactored xml.dom.minidom.normalize, increasing both its clarity and its speed. Modified: python/trunk/Lib/test/test_minidom.py python/trunk/Lib/xml/dom/minidom.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/test/test_minidom.py ============================================================================== --- python/trunk/Lib/test/test_minidom.py (original) +++ python/trunk/Lib/test/test_minidom.py Thu Apr 9 23:54:50 2009 @@ -790,6 +790,167 @@ "testNormalize -- single empty node removed") doc.unlink() + def testNormalizeCombineAndNextSibling(self): + doc = parseString("") + root = doc.documentElement + root.appendChild(doc.createTextNode("first")) + root.appendChild(doc.createTextNode("second")) + root.appendChild(doc.createElement("i")) + self.confirm(len(root.childNodes) == 3 + and root.childNodes.length == 3, + "testNormalizeCombineAndNextSibling -- preparation") + doc.normalize() + self.confirm(len(root.childNodes) == 2 + and root.childNodes.length == 2 + and root.firstChild.data == "firstsecond" + and root.firstChild is not root.lastChild + and root.firstChild.nextSibling is root.lastChild + and root.firstChild.previousSibling is None + and root.lastChild.previousSibling is root.firstChild + and root.lastChild.nextSibling is None + , "testNormalizeCombinedAndNextSibling -- result") + doc.unlink() + + def testNormalizeDeleteWithPrevSibling(self): + doc = parseString("") + root = doc.documentElement + root.appendChild(doc.createTextNode("first")) + root.appendChild(doc.createTextNode("")) + self.confirm(len(root.childNodes) == 2 + and root.childNodes.length == 2, + "testNormalizeDeleteWithPrevSibling -- preparation") + doc.normalize() + self.confirm(len(root.childNodes) == 1 + and root.childNodes.length == 1 + and root.firstChild.data == "first" + and root.firstChild is root.lastChild + and root.firstChild.nextSibling is None + and root.firstChild.previousSibling is None + , "testNormalizeDeleteWithPrevSibling -- result") + doc.unlink() + + def testNormalizeDeleteWithNextSibling(self): + doc = parseString("") + root = doc.documentElement + root.appendChild(doc.createTextNode("")) + root.appendChild(doc.createTextNode("second")) + self.confirm(len(root.childNodes) == 2 + and root.childNodes.length == 2, + "testNormalizeDeleteWithNextSibling -- preparation") + doc.normalize() + self.confirm(len(root.childNodes) == 1 + and root.childNodes.length == 1 + and root.firstChild.data == "second" + and root.firstChild is root.lastChild + and root.firstChild.nextSibling is None + and root.firstChild.previousSibling is None + , "testNormalizeDeleteWithNextSibling -- result") + doc.unlink() + + def testNormalizeDeleteWithTwoNonTextSiblings(self): + doc = parseString("") + root = doc.documentElement + root.appendChild(doc.createElement("i")) + root.appendChild(doc.createTextNode("")) + root.appendChild(doc.createElement("i")) + self.confirm(len(root.childNodes) == 3 + and root.childNodes.length == 3, + "testNormalizeDeleteWithTwoSiblings -- preparation") + doc.normalize() + self.confirm(len(root.childNodes) == 2 + and root.childNodes.length == 2 + and root.firstChild is not root.lastChild + and root.firstChild.nextSibling is root.lastChild + and root.firstChild.previousSibling is None + and root.lastChild.previousSibling is root.firstChild + and root.lastChild.nextSibling is None + , "testNormalizeDeleteWithTwoSiblings -- result") + doc.unlink() + + def testNormalizeDeleteAndCombine(self): + doc = parseString("") + root = doc.documentElement + root.appendChild(doc.createTextNode("")) + root.appendChild(doc.createTextNode("second")) + root.appendChild(doc.createTextNode("")) + root.appendChild(doc.createTextNode("fourth")) + root.appendChild(doc.createTextNode("")) + self.confirm(len(root.childNodes) == 5 + and root.childNodes.length == 5, + "testNormalizeDeleteAndCombine -- preparation") + doc.normalize() + self.confirm(len(root.childNodes) == 1 + and root.childNodes.length == 1 + and root.firstChild is root.lastChild + and root.firstChild.data == "secondfourth" + and root.firstChild.previousSibling is None + and root.firstChild.nextSibling is None + , "testNormalizeDeleteAndCombine -- result") + doc.unlink() + + def testNormalizeRecursion(self): + doc = parseString("" + "" + "" + "t" + # + #x + "" + "" + "" + "t2" + #x2 + "" + "t3" + #x3 + "" + # + "") + root = doc.documentElement + root.childNodes[0].appendChild(doc.createTextNode("")) + root.childNodes[0].appendChild(doc.createTextNode("x")) + root.childNodes[1].childNodes[0].appendChild(doc.createTextNode("x2")) + root.childNodes[1].appendChild(doc.createTextNode("x3")) + root.appendChild(doc.createTextNode("")) + self.confirm(len(root.childNodes) == 3 + and root.childNodes.length == 3 + and len(root.childNodes[0].childNodes) == 4 + and root.childNodes[0].childNodes.length == 4 + and len(root.childNodes[1].childNodes) == 3 + and root.childNodes[1].childNodes.length == 3 + and len(root.childNodes[1].childNodes[0].childNodes) == 2 + and root.childNodes[1].childNodes[0].childNodes.length == 2 + , "testNormalize2 -- preparation") + doc.normalize() + self.confirm(len(root.childNodes) == 2 + and root.childNodes.length == 2 + and len(root.childNodes[0].childNodes) == 2 + and root.childNodes[0].childNodes.length == 2 + and len(root.childNodes[1].childNodes) == 2 + and root.childNodes[1].childNodes.length == 2 + and len(root.childNodes[1].childNodes[0].childNodes) == 1 + and root.childNodes[1].childNodes[0].childNodes.length == 1 + , "testNormalize2 -- childNodes lengths") + self.confirm(root.childNodes[0].childNodes[1].data == "tx" + and root.childNodes[1].childNodes[0].childNodes[0].data == "t2x2" + and root.childNodes[1].childNodes[1].data == "t3x3" + , "testNormalize2 -- joined text fields") + self.confirm(root.childNodes[0].childNodes[1].nextSibling is None + and root.childNodes[0].childNodes[1].previousSibling + is root.childNodes[0].childNodes[0] + and root.childNodes[0].childNodes[0].previousSibling is None + and root.childNodes[0].childNodes[0].nextSibling + is root.childNodes[0].childNodes[1] + and root.childNodes[1].childNodes[1].nextSibling is None + and root.childNodes[1].childNodes[1].previousSibling + is root.childNodes[1].childNodes[0] + and root.childNodes[1].childNodes[0].previousSibling is None + and root.childNodes[1].childNodes[0].nextSibling + is root.childNodes[1].childNodes[1] + , "testNormalize2 -- sibling pointers") + doc.unlink() + + def testBug1433694(self): doc = parseString("t") node = doc.documentElement Modified: python/trunk/Lib/xml/dom/minidom.py ============================================================================== --- python/trunk/Lib/xml/dom/minidom.py (original) +++ python/trunk/Lib/xml/dom/minidom.py Thu Apr 9 23:54:50 2009 @@ -177,34 +177,27 @@ L = [] for child in self.childNodes: if child.nodeType == Node.TEXT_NODE: - data = child.data - if data and L and L[-1].nodeType == child.nodeType: + if not child.data: + # empty text node; discard + if L: + L[-1].nextSibling = child.nextSibling + if child.nextSibling: + child.nextSibling.previousSibling = child.previousSibling + child.unlink() + elif L and L[-1].nodeType == child.nodeType: # collapse text node node = L[-1] node.data = node.data + child.data node.nextSibling = child.nextSibling + if child.nextSibling: + child.nextSibling.previousSibling = node child.unlink() - elif data: - if L: - L[-1].nextSibling = child - child.previousSibling = L[-1] - else: - child.previousSibling = None - L.append(child) else: - # empty text node; discard - child.unlink() + L.append(child) else: - if L: - L[-1].nextSibling = child - child.previousSibling = L[-1] - else: - child.previousSibling = None L.append(child) if child.nodeType == Node.ELEMENT_NODE: child.normalize() - if L: - L[-1].nextSibling = None self.childNodes[:] = L def cloneNode(self, deep): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Apr 9 23:54:50 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #2170: refactored xml.dom.minidom.normalize, increasing both + its clarity and its speed. + - Issue #2396: the memoryview object was backported from Python 3.1. - Fix a problem in PyErr_NormalizeException that leads to "undetected errors" From python-checkins at python.org Fri Apr 10 00:02:42 2009 From: python-checkins at python.org (tarek.ziade) Date: Fri, 10 Apr 2009 00:02:42 +0200 (CEST) Subject: [Python-checkins] r71415 - in python/branches/py3k: Lib/distutils/command/bdist_wininst.py Lib/distutils/tests/test_bdist_wininst.py Misc/NEWS Message-ID: <20090409220242.478C41E4018@bag.python.org> Author: tarek.ziade Date: Fri Apr 10 00:02:39 2009 New Revision: 71415 Log: Merged revisions 71413 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71413 | tarek.ziade | 2009-04-09 23:36:44 +0200 (Thu, 09 Apr 2009) | 1 line Fixed #5731: Distutils bdist_wininst no longer worked on non-Windows platforms ........ Added: python/branches/py3k/Lib/distutils/tests/test_bdist_wininst.py - copied unchanged from r71413, /python/trunk/Lib/distutils/tests/test_bdist_wininst.py Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/command/bdist_wininst.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/distutils/command/bdist_wininst.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/bdist_wininst.py (original) +++ python/branches/py3k/Lib/distutils/command/bdist_wininst.py Fri Apr 10 00:02:39 2009 @@ -330,9 +330,14 @@ directory = os.path.dirname(__file__) # we must use a wininst-x.y.exe built with the same C compiler # used for python. XXX What about mingw, borland, and so on? - if self.plat_name == 'win32': - sfix = '' + + # if plat_name starts with "win" but is not "win32" + # we want to strip "win" and leave the rest (e.g. -amd64) + # for all other cases, we don't want any suffix + if self.plat_name != 'win32' and self.plat_name[:3] == 'win': + sfix = self.plat_name[3:] else: - sfix = self.plat_name[3:] # strip 'win' - leaves eg '-amd64' + sfix = '' + filename = os.path.join(directory, "wininst-%.1f%s.exe" % (bv, sfix)) return open(filename, "rb").read() Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Apr 10 00:02:39 2009 @@ -337,6 +337,9 @@ Library ------- +- Issue #5731: Distutils bdist_wininst no longer worked on non-Windows + platforms. Initial patch by Paul Moore. + - Issue #5095: Added bdist_msi to the list of bdist supported formats. Initial fix by Steven Bethard. From python-checkins at python.org Fri Apr 10 00:16:44 2009 From: python-checkins at python.org (r.david.murray) Date: Fri, 10 Apr 2009 00:16:44 +0200 (CEST) Subject: [Python-checkins] r71416 - in python/branches/py3k: Lib/test/test_minidom.py Lib/xml/dom/minidom.py Misc/NEWS Message-ID: <20090409221644.3B7921E401B@bag.python.org> Author: r.david.murray Date: Fri Apr 10 00:16:43 2009 New Revision: 71416 Log: Merged revisions 71414 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71414 | r.david.murray | 2009-04-09 17:54:50 -0400 (Thu, 09 Apr 2009) | 3 lines Issue #2170: refactored xml.dom.minidom.normalize, increasing both its clarity and its speed. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_minidom.py python/branches/py3k/Lib/xml/dom/minidom.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/test/test_minidom.py ============================================================================== --- python/branches/py3k/Lib/test/test_minidom.py (original) +++ python/branches/py3k/Lib/test/test_minidom.py Fri Apr 10 00:16:43 2009 @@ -789,6 +789,167 @@ "testNormalize -- single empty node removed") doc.unlink() + def testNormalizeCombineAndNextSibling(self): + doc = parseString("") + root = doc.documentElement + root.appendChild(doc.createTextNode("first")) + root.appendChild(doc.createTextNode("second")) + root.appendChild(doc.createElement("i")) + self.confirm(len(root.childNodes) == 3 + and root.childNodes.length == 3, + "testNormalizeCombineAndNextSibling -- preparation") + doc.normalize() + self.confirm(len(root.childNodes) == 2 + and root.childNodes.length == 2 + and root.firstChild.data == "firstsecond" + and root.firstChild is not root.lastChild + and root.firstChild.nextSibling is root.lastChild + and root.firstChild.previousSibling is None + and root.lastChild.previousSibling is root.firstChild + and root.lastChild.nextSibling is None + , "testNormalizeCombinedAndNextSibling -- result") + doc.unlink() + + def testNormalizeDeleteWithPrevSibling(self): + doc = parseString("") + root = doc.documentElement + root.appendChild(doc.createTextNode("first")) + root.appendChild(doc.createTextNode("")) + self.confirm(len(root.childNodes) == 2 + and root.childNodes.length == 2, + "testNormalizeDeleteWithPrevSibling -- preparation") + doc.normalize() + self.confirm(len(root.childNodes) == 1 + and root.childNodes.length == 1 + and root.firstChild.data == "first" + and root.firstChild is root.lastChild + and root.firstChild.nextSibling is None + and root.firstChild.previousSibling is None + , "testNormalizeDeleteWithPrevSibling -- result") + doc.unlink() + + def testNormalizeDeleteWithNextSibling(self): + doc = parseString("") + root = doc.documentElement + root.appendChild(doc.createTextNode("")) + root.appendChild(doc.createTextNode("second")) + self.confirm(len(root.childNodes) == 2 + and root.childNodes.length == 2, + "testNormalizeDeleteWithNextSibling -- preparation") + doc.normalize() + self.confirm(len(root.childNodes) == 1 + and root.childNodes.length == 1 + and root.firstChild.data == "second" + and root.firstChild is root.lastChild + and root.firstChild.nextSibling is None + and root.firstChild.previousSibling is None + , "testNormalizeDeleteWithNextSibling -- result") + doc.unlink() + + def testNormalizeDeleteWithTwoNonTextSiblings(self): + doc = parseString("") + root = doc.documentElement + root.appendChild(doc.createElement("i")) + root.appendChild(doc.createTextNode("")) + root.appendChild(doc.createElement("i")) + self.confirm(len(root.childNodes) == 3 + and root.childNodes.length == 3, + "testNormalizeDeleteWithTwoSiblings -- preparation") + doc.normalize() + self.confirm(len(root.childNodes) == 2 + and root.childNodes.length == 2 + and root.firstChild is not root.lastChild + and root.firstChild.nextSibling is root.lastChild + and root.firstChild.previousSibling is None + and root.lastChild.previousSibling is root.firstChild + and root.lastChild.nextSibling is None + , "testNormalizeDeleteWithTwoSiblings -- result") + doc.unlink() + + def testNormalizeDeleteAndCombine(self): + doc = parseString("") + root = doc.documentElement + root.appendChild(doc.createTextNode("")) + root.appendChild(doc.createTextNode("second")) + root.appendChild(doc.createTextNode("")) + root.appendChild(doc.createTextNode("fourth")) + root.appendChild(doc.createTextNode("")) + self.confirm(len(root.childNodes) == 5 + and root.childNodes.length == 5, + "testNormalizeDeleteAndCombine -- preparation") + doc.normalize() + self.confirm(len(root.childNodes) == 1 + and root.childNodes.length == 1 + and root.firstChild is root.lastChild + and root.firstChild.data == "secondfourth" + and root.firstChild.previousSibling is None + and root.firstChild.nextSibling is None + , "testNormalizeDeleteAndCombine -- result") + doc.unlink() + + def testNormalizeRecursion(self): + doc = parseString("" + "" + "" + "t" + # + #x + "" + "" + "" + "t2" + #x2 + "" + "t3" + #x3 + "" + # + "") + root = doc.documentElement + root.childNodes[0].appendChild(doc.createTextNode("")) + root.childNodes[0].appendChild(doc.createTextNode("x")) + root.childNodes[1].childNodes[0].appendChild(doc.createTextNode("x2")) + root.childNodes[1].appendChild(doc.createTextNode("x3")) + root.appendChild(doc.createTextNode("")) + self.confirm(len(root.childNodes) == 3 + and root.childNodes.length == 3 + and len(root.childNodes[0].childNodes) == 4 + and root.childNodes[0].childNodes.length == 4 + and len(root.childNodes[1].childNodes) == 3 + and root.childNodes[1].childNodes.length == 3 + and len(root.childNodes[1].childNodes[0].childNodes) == 2 + and root.childNodes[1].childNodes[0].childNodes.length == 2 + , "testNormalize2 -- preparation") + doc.normalize() + self.confirm(len(root.childNodes) == 2 + and root.childNodes.length == 2 + and len(root.childNodes[0].childNodes) == 2 + and root.childNodes[0].childNodes.length == 2 + and len(root.childNodes[1].childNodes) == 2 + and root.childNodes[1].childNodes.length == 2 + and len(root.childNodes[1].childNodes[0].childNodes) == 1 + and root.childNodes[1].childNodes[0].childNodes.length == 1 + , "testNormalize2 -- childNodes lengths") + self.confirm(root.childNodes[0].childNodes[1].data == "tx" + and root.childNodes[1].childNodes[0].childNodes[0].data == "t2x2" + and root.childNodes[1].childNodes[1].data == "t3x3" + , "testNormalize2 -- joined text fields") + self.confirm(root.childNodes[0].childNodes[1].nextSibling is None + and root.childNodes[0].childNodes[1].previousSibling + is root.childNodes[0].childNodes[0] + and root.childNodes[0].childNodes[0].previousSibling is None + and root.childNodes[0].childNodes[0].nextSibling + is root.childNodes[0].childNodes[1] + and root.childNodes[1].childNodes[1].nextSibling is None + and root.childNodes[1].childNodes[1].previousSibling + is root.childNodes[1].childNodes[0] + and root.childNodes[1].childNodes[0].previousSibling is None + and root.childNodes[1].childNodes[0].nextSibling + is root.childNodes[1].childNodes[1] + , "testNormalize2 -- sibling pointers") + doc.unlink() + + def testBug1433694(self): doc = parseString("t") node = doc.documentElement Modified: python/branches/py3k/Lib/xml/dom/minidom.py ============================================================================== --- python/branches/py3k/Lib/xml/dom/minidom.py (original) +++ python/branches/py3k/Lib/xml/dom/minidom.py Fri Apr 10 00:16:43 2009 @@ -179,34 +179,27 @@ L = [] for child in self.childNodes: if child.nodeType == Node.TEXT_NODE: - data = child.data - if data and L and L[-1].nodeType == child.nodeType: + if not child.data: + # empty text node; discard + if L: + L[-1].nextSibling = child.nextSibling + if child.nextSibling: + child.nextSibling.previousSibling = child.previousSibling + child.unlink() + elif L and L[-1].nodeType == child.nodeType: # collapse text node node = L[-1] node.data = node.data + child.data node.nextSibling = child.nextSibling + if child.nextSibling: + child.nextSibling.previousSibling = node child.unlink() - elif data: - if L: - L[-1].nextSibling = child - child.previousSibling = L[-1] - else: - child.previousSibling = None - L.append(child) else: - # empty text node; discard - child.unlink() + L.append(child) else: - if L: - L[-1].nextSibling = child - child.previousSibling = L[-1] - else: - child.previousSibling = None L.append(child) if child.nodeType == Node.ELEMENT_NODE: child.normalize() - if L: - L[-1].nextSibling = None self.childNodes[:] = L def cloneNode(self, deep): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Apr 10 00:16:43 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #2170: refactored xml.dom.minidom.normalize, increasing both + its clarity and its speed. + - Issue #1113244: Py_XINCREF, Py_DECREF, Py_XDECREF: Add `do { ... } while (0)' to avoid compiler warnings. From python-checkins at python.org Fri Apr 10 00:18:30 2009 From: python-checkins at python.org (r.david.murray) Date: Fri, 10 Apr 2009 00:18:30 +0200 (CEST) Subject: [Python-checkins] r71417 - python/branches/release30-maint Message-ID: <20090409221830.A65401E4018@bag.python.org> Author: r.david.murray Date: Fri Apr 10 00:18:30 2009 New Revision: 71417 Log: Blocked revisions 71416 via svnmerge ................ r71416 | r.david.murray | 2009-04-09 18:16:43 -0400 (Thu, 09 Apr 2009) | 10 lines Merged revisions 71414 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71414 | r.david.murray | 2009-04-09 17:54:50 -0400 (Thu, 09 Apr 2009) | 3 lines Issue #2170: refactored xml.dom.minidom.normalize, increasing both its clarity and its speed. ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Fri Apr 10 00:22:06 2009 From: python-checkins at python.org (r.david.murray) Date: Fri, 10 Apr 2009 00:22:06 +0200 (CEST) Subject: [Python-checkins] r71418 - python/branches/release26-maint Message-ID: <20090409222206.5C63B1E401B@bag.python.org> Author: r.david.murray Date: Fri Apr 10 00:22:06 2009 New Revision: 71418 Log: Blocked revisions 71414 via svnmerge ........ r71414 | r.david.murray | 2009-04-09 17:54:50 -0400 (Thu, 09 Apr 2009) | 3 lines Issue #2170: refactored xml.dom.minidom.normalize, increasing both its clarity and its speed. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Fri Apr 10 00:31:52 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 10 Apr 2009 00:31:52 +0200 (CEST) Subject: [Python-checkins] r71419 - python/trunk/Doc/library/collections.rst Message-ID: <20090409223152.0653E1E401D@bag.python.org> Author: raymond.hettinger Date: Fri Apr 10 00:31:51 2009 New Revision: 71419 Log: Add note on using keyword arguments with OrderedDict. Modified: python/trunk/Doc/library/collections.rst Modified: python/trunk/Doc/library/collections.rst ============================================================================== --- python/trunk/Doc/library/collections.rst (original) +++ python/trunk/Doc/library/collections.rst Fri Apr 10 00:31:51 2009 @@ -875,6 +875,10 @@ This allows :class:`OrderedDict` objects to be substituted anywhere a regular dictionary is used. +The :class:`OrderedDict` constructor and :meth:`update` method both accept +keyword arguments, but their order is lost because Python's function call +semantics pass-in keyword arguments using a regular unordered dictionary. + .. seealso:: `Equivalent OrderedDict recipe `_ From python-checkins at python.org Fri Apr 10 00:34:23 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 10 Apr 2009 00:34:23 +0200 (CEST) Subject: [Python-checkins] r71420 - python/branches/py3k/Doc/library/collections.rst Message-ID: <20090409223423.8DB6F1E401B@bag.python.org> Author: raymond.hettinger Date: Fri Apr 10 00:34:23 2009 New Revision: 71420 Log: Add note on using keyword arguments with OrderedDict. Modified: python/branches/py3k/Doc/library/collections.rst Modified: python/branches/py3k/Doc/library/collections.rst ============================================================================== --- python/branches/py3k/Doc/library/collections.rst (original) +++ python/branches/py3k/Doc/library/collections.rst Fri Apr 10 00:34:23 2009 @@ -852,6 +852,10 @@ This allows :class:`OrderedDict` objects to be substituted anywhere a regular dictionary is used. +The :class:`OrderedDict` constructor and :meth:`update` method both accept +keyword arguments, but their order is lost because Python's function call +semantics pass-in keyword arguments using a regular unordered dictionary. + .. seealso:: `Equivalent OrderedDict recipe `_ From python-checkins at python.org Fri Apr 10 00:34:46 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 10 Apr 2009 00:34:46 +0200 (CEST) Subject: [Python-checkins] r71421 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090409223446.40D321E401B@bag.python.org> Author: raymond.hettinger Date: Fri Apr 10 00:34:46 2009 New Revision: 71421 Log: Fix link Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Fri Apr 10 00:34:46 2009 @@ -175,7 +175,7 @@ (Contributed by Antoine Pitrou.) -* The :mod:`decimal.Decimal` module now supports methods for creating a +* The :mod:`decimal` module now supports methods for creating a decimal object from a binary :class:`float`. The conversion is exact but can sometimes be surprising:: From python-checkins at python.org Fri Apr 10 00:48:19 2009 From: python-checkins at python.org (tarek.ziade) Date: Fri, 10 Apr 2009 00:48:19 +0200 (CEST) Subject: [Python-checkins] r71422 - in python/branches/release26-maint: Lib/distutils/command/bdist_wininst.py Lib/distutils/tests/test_bdist_wininst.py Misc/NEWS Message-ID: <20090409224820.008801E4013@bag.python.org> Author: tarek.ziade Date: Fri Apr 10 00:48:19 2009 New Revision: 71422 Log: Merged revisions 71413 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71413 | tarek.ziade | 2009-04-09 23:36:44 +0200 (Thu, 09 Apr 2009) | 1 line Fixed #5731: Distutils bdist_wininst no longer worked on non-Windows platforms ........ Added: python/branches/release26-maint/Lib/distutils/tests/test_bdist_wininst.py - copied, changed from r71413, /python/trunk/Lib/distutils/tests/test_bdist_wininst.py Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/distutils/command/bdist_wininst.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/distutils/command/bdist_wininst.py ============================================================================== --- python/branches/release26-maint/Lib/distutils/command/bdist_wininst.py (original) +++ python/branches/release26-maint/Lib/distutils/command/bdist_wininst.py Fri Apr 10 00:48:19 2009 @@ -344,10 +344,15 @@ directory = os.path.dirname(__file__) # we must use a wininst-x.y.exe built with the same C compiler # used for python. XXX What about mingw, borland, and so on? - if self.plat_name == 'win32': - sfix = '' + + # if plat_name starts with "win" but is not "win32" + # we want to strip "win" and leave the rest (e.g. -amd64) + # for all other cases, we don't want any suffix + if self.plat_name != 'win32' and self.plat_name[:3] == 'win': + sfix = self.plat_name[3:] else: - sfix = self.plat_name[3:] # strip 'win' - leaves eg '-amd64' + sfix = '' + filename = os.path.join(directory, "wininst-%.1f%s.exe" % (bv, sfix)) return open(filename, "rb").read() # class bdist_wininst Copied: python/branches/release26-maint/Lib/distutils/tests/test_bdist_wininst.py (from r71413, /python/trunk/Lib/distutils/tests/test_bdist_wininst.py) ============================================================================== --- /python/trunk/Lib/distutils/tests/test_bdist_wininst.py (original) +++ python/branches/release26-maint/Lib/distutils/tests/test_bdist_wininst.py Fri Apr 10 00:48:19 2009 @@ -1,6 +1,8 @@ """Tests for distutils.command.bdist_wininst.""" import unittest +import os +from distutils.dist import Distribution from distutils.command.bdist_wininst import bdist_wininst from distutils.tests import support @@ -12,7 +14,10 @@ # issue5731: command was broken on non-windows platforms # this test makes sure it works now for every platform # let's create a command - pkg_pth, dist = self.create_dist() + tmp_dir = self.mkdtemp() + pkg_dir = os.path.join(tmp_dir, 'foo') + os.mkdir(pkg_dir) + dist = Distribution() cmd = bdist_wininst(dist) cmd.ensure_finalized() Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Fri Apr 10 00:48:19 2009 @@ -103,6 +103,9 @@ Library ------- +- Issue #5731: Distutils bdist_wininst no longer worked on non-Windows + platforms. Initial patch by Paul Moore. + - Issue #1491431: Fixed distutils.filelist.glob_to_re for edge cases. Initial fix by Wayne Davison. From python-checkins at python.org Fri Apr 10 00:51:41 2009 From: python-checkins at python.org (tarek.ziade) Date: Fri, 10 Apr 2009 00:51:41 +0200 (CEST) Subject: [Python-checkins] r71423 - in python/branches/release30-maint: Lib/distutils/command/bdist_wininst.py Lib/distutils/tests/test_bdist_wininst.py Misc/NEWS Message-ID: <20090409225141.5BC9B1E4013@bag.python.org> Author: tarek.ziade Date: Fri Apr 10 00:51:41 2009 New Revision: 71423 Log: Merged revisions 71415 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71415 | tarek.ziade | 2009-04-10 00:02:39 +0200 (Fri, 10 Apr 2009) | 9 lines Merged revisions 71413 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71413 | tarek.ziade | 2009-04-09 23:36:44 +0200 (Thu, 09 Apr 2009) | 1 line Fixed #5731: Distutils bdist_wininst no longer worked on non-Windows platforms ........ ................ Added: python/branches/release30-maint/Lib/distutils/tests/test_bdist_wininst.py - copied, changed from r71415, /python/branches/py3k/Lib/distutils/tests/test_bdist_wininst.py Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Lib/distutils/command/bdist_wininst.py python/branches/release30-maint/Misc/NEWS Modified: python/branches/release30-maint/Lib/distutils/command/bdist_wininst.py ============================================================================== --- python/branches/release30-maint/Lib/distutils/command/bdist_wininst.py (original) +++ python/branches/release30-maint/Lib/distutils/command/bdist_wininst.py Fri Apr 10 00:51:41 2009 @@ -330,9 +330,14 @@ directory = os.path.dirname(__file__) # we must use a wininst-x.y.exe built with the same C compiler # used for python. XXX What about mingw, borland, and so on? - if self.plat_name == 'win32': - sfix = '' + + # if plat_name starts with "win" but is not "win32" + # we want to strip "win" and leave the rest (e.g. -amd64) + # for all other cases, we don't want any suffix + if self.plat_name != 'win32' and self.plat_name[:3] == 'win': + sfix = self.plat_name[3:] else: - sfix = self.plat_name[3:] # strip 'win' - leaves eg '-amd64' + sfix = '' + filename = os.path.join(directory, "wininst-%.1f%s.exe" % (bv, sfix)) return open(filename, "rb").read() Copied: python/branches/release30-maint/Lib/distutils/tests/test_bdist_wininst.py (from r71415, /python/branches/py3k/Lib/distutils/tests/test_bdist_wininst.py) ============================================================================== --- /python/branches/py3k/Lib/distutils/tests/test_bdist_wininst.py (original) +++ python/branches/release30-maint/Lib/distutils/tests/test_bdist_wininst.py Fri Apr 10 00:51:41 2009 @@ -1,6 +1,8 @@ """Tests for distutils.command.bdist_wininst.""" import unittest +import os +from distutils.dist import Distribution from distutils.command.bdist_wininst import bdist_wininst from distutils.tests import support @@ -12,7 +14,10 @@ # issue5731: command was broken on non-windows platforms # this test makes sure it works now for every platform # let's create a command - pkg_pth, dist = self.create_dist() + tmp_dir = self.mkdtemp() + pkg_dir = os.path.join(tmp_dir, 'foo') + os.mkdir(pkg_dir) + dist = Distribution() cmd = bdist_wininst(dist) cmd.ensure_finalized() Modified: python/branches/release30-maint/Misc/NEWS ============================================================================== --- python/branches/release30-maint/Misc/NEWS (original) +++ python/branches/release30-maint/Misc/NEWS Fri Apr 10 00:51:41 2009 @@ -216,6 +216,9 @@ Library ------- +- Issue #5731: Distutils bdist_wininst no longer worked on non-Windows + platforms. Initial patch by Paul Moore. + - Issue #4998: The memory saving effect of __slots__ had been lost on Fractions which inherited from numbers.py which did not have __slots__ defined. The numbers hierarchy now has its own __slots__ declarations. From python-checkins at python.org Fri Apr 10 01:25:30 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 10 Apr 2009 01:25:30 +0200 (CEST) Subject: [Python-checkins] r71424 - python/trunk/Doc/tools/sphinxext/static/basic.css Message-ID: <20090409232530.6ADFC1E4013@bag.python.org> Author: raymond.hettinger Date: Fri Apr 10 01:25:30 2009 New Revision: 71424 Log: More table formatting. Modified: python/trunk/Doc/tools/sphinxext/static/basic.css Modified: python/trunk/Doc/tools/sphinxext/static/basic.css ============================================================================== --- python/trunk/Doc/tools/sphinxext/static/basic.css (original) +++ python/trunk/Doc/tools/sphinxext/static/basic.css Fri Apr 10 01:25:30 2009 @@ -262,10 +262,11 @@ table.docutils td, table.docutils th { padding: 1px 8px 1px 5px; - border-top: 0; + border-top: 1px solid #b9b; border-left: 0; border-right: 0; border-bottom: 1px solid #aaa; + background-color: #eef; } table.field-list td, table.field-list th { @@ -276,6 +277,10 @@ border: 0 !important; } +table.docutils th { + background-color: #ede; +} + th { text-align: left; padding-right: 5px; From python-checkins at python.org Fri Apr 10 01:34:15 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 10 Apr 2009 01:34:15 +0200 (CEST) Subject: [Python-checkins] r71425 - python/trunk/Doc/tools/sphinxext/static/basic.css Message-ID: <20090409233415.081CF1E4002@bag.python.org> Author: raymond.hettinger Date: Fri Apr 10 01:34:14 2009 New Revision: 71425 Log: Center table headings. Modified: python/trunk/Doc/tools/sphinxext/static/basic.css Modified: python/trunk/Doc/tools/sphinxext/static/basic.css ============================================================================== --- python/trunk/Doc/tools/sphinxext/static/basic.css (original) +++ python/trunk/Doc/tools/sphinxext/static/basic.css Fri Apr 10 01:34:14 2009 @@ -287,6 +287,10 @@ background-color: #ede; } +th.head { + text-align: center; +} + /* -- other body styles ----------------------------------------------------- */ dl { From buildbot at python.org Fri Apr 10 02:13:02 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 10 Apr 2009 00:13:02 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 3.x Message-ID: <20090410001302.98C531E4002@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%203.x/builds/646 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: Traceback (most recent call last): File "/Users/buildbot/buildarea/3.x.heller-x86-osx5/build/Lib/test/test_xmlrpc.py", line 479, in test_dotted_attribute self.test_simple1() File "/Users/buildbot/buildarea/3.x.heller-x86-osx5/build/Lib/test/test_xmlrpc.py", line 354, in test_simple1 self.fail("%s\n%s" % (e, getattr(e, "headers", ""))) AssertionError: [Errno 9] Bad file descriptor 1 test failed: test_xmlrpc make: *** [buildbottest] Error 1 sincerely, -The Buildbot From stackless-checkins-bounces at stackless.com Fri Apr 10 02:34:49 2009 From: stackless-checkins-bounces at stackless.com (stackless-checkins-bounces at stackless.com) Date: Fri, 10 Apr 2009 02:34:49 +0200 Subject: [Python-checkins] Your message to Stackless-checkins awaits moderator approval Message-ID: Your mail to 'Stackless-checkins' with the subject r71426 - in stackless/branches/release26-maint: Doc/ACKS.txt Doc/Makefile Doc/README.txt Doc/c-api/allocation.rst Doc/c-api/arg.rst Doc/c-api/bool.rst Doc/c-api/buffer.rst Doc/c-api/bytearray.rst Doc/c-api/cell.rst Doc/c-api/class.rst Doc/c-api/cobject.rst Doc/c-api/complex.rst Doc/c-api/conversion.rst Doc/c-api/datetime.rst Doc/c-api/descriptor.rst Doc/c-api/dict.rst Doc/c-api/exceptions.rst Doc/c-api/file.rst Doc/c-api/float.rst Doc/c-api/function.rst Doc/c-api/gcsupport.rst Doc/c-api/gen.rst Doc/c-api/import.rst Doc/c-api/init.rst Doc/c-api/int.rst Doc/c-api/intro.rst Doc/c-api/iter.rst Doc/c-api/iterator.rst Doc/c-api/list.rst Doc/c-api/long.rst Doc/c-api/mapping.rst Doc/c-api/marshal.rst Doc/c-api/method.rst Doc/c-api/module.rst Doc/c-api/none.rst Doc/c-api/number.rst Doc/c-api/objbuffer.rst Doc/c-api/object.rst Doc/c-api/reflection.rst Doc/c-api/sequence.rst Doc/c-api/set.rst Doc/c-api/slice.rst Doc/c-api/string.rst Doc/c-api/structures.rst Doc/c-api/sys.rst D oc/c-api/tuple.rst Doc/c-api/type.rst Doc/c-api/typeobj.rst Doc/c-api/unicode.rst Doc/c-api/veryhigh.rst Doc/c-api/weakref.rst Doc/conf.py Doc/distutils/apiref.rst Doc/distutils/builtdist.rst Doc/distutils/configfile.rst Doc/distutils/index.rst Doc/distutils/packageindex.rst Doc/distutils/setupscript.rst Doc/distutils/uploading.rst Doc/documenting/index.rst Doc/documenting/markup.rst Doc/documenting/rest.rst Doc/documenting/sphinx.rst Doc/documenting/style.rst Doc/extending/building.rst Doc/extending/extending.rst Doc/extending/index.rst Doc/extending/newtypes.rst Doc/extending/windows.rst Doc/glossary.rst Doc/howto/cporting.rst Doc/howto/curses.rst Doc/howto/doanddont.rst Doc/howto/functional.rst Doc/howto/regex.rst Doc/howto/sockets.rst Doc/howto/unicode.rst Doc/howto/urllib2.rst Doc/howto/webservers.rst Doc/includes/mp_benchmarks.py Doc/includes/mp_distributing.py Doc/includes/mp_newtype.py Doc/includes/mp_pool.py Doc/includes/mp_synchronize.py Doc/includes/mp_webserver.p y Doc/includes/mp_workers.py Doc/install/index.rst Doc/library/2to3.rst Doc/library/_winreg.rst Doc/library/abc.rst Doc/library/aifc.rst Doc/library/al.rst Doc/library/ast.rst Doc/library/audioop.rst Doc/library/base64.rst Doc/library/basehttpserver.rst Doc/library/bastion.rst Doc/library/bdb.rst Doc/library/binascii.rst Doc/library/bsddb.rst Doc/library/bz2.rst Doc/library/carbon.rst Doc/library/cd.rst Doc/library/cgi.rst Doc/library/cgitb.rst Doc/library/cmath.rst Doc/library/codeop.rst Doc/library/collections.rst Doc/library/compiler.rst Doc/library/configparser.rst Doc/library/contextlib.rst Doc/library/cookielib.rst Doc/library/crypt.rst Doc/library/csv.rst Doc/library/ctypes.rst Doc/library/datetime.rst Doc/library/decimal.rst Doc/library/difflib.rst Doc/library/dircache.rst Doc/library/dis.rst Doc/library/dl.rst Doc/library/doctest.rst Doc/library/email.mime.rst Doc/library/exceptions.rst Doc/library/filecmp.rst Doc/library/fileinput.rst Doc/library/fl.rst Doc/library /fm.rst Doc/library/fpformat.rst Doc/library/fractions.rst Doc/library/ftplib.rst Doc/library/functions.rst Doc/library/future_b Is being held until the list moderator can review it for approval. The reason it is being held: Message body is too big: 1866353 bytes with a limit of 500 KB Either the message will get posted to the list, or you will receive notification of the moderator's decision. If you would like to cancel this posting, please visit the following URL: http://www.stackless.com/mailman/confirm/stackless-checkins/e368ce8e6ba170fed804d1d8dddf85098386c28d From python-checkins at python.org Fri Apr 10 02:49:41 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 10 Apr 2009 02:49:41 +0200 (CEST) Subject: [Python-checkins] r71428 - python/trunk/Doc/tools/sphinxext/static/basic.css Message-ID: <20090410004941.4D38C1E4002@bag.python.org> Author: raymond.hettinger Date: Fri Apr 10 02:49:41 2009 New Revision: 71428 Log: More table clean-up Modified: python/trunk/Doc/tools/sphinxext/static/basic.css Modified: python/trunk/Doc/tools/sphinxext/static/basic.css ============================================================================== --- python/trunk/Doc/tools/sphinxext/static/basic.css (original) +++ python/trunk/Doc/tools/sphinxext/static/basic.css Fri Apr 10 02:49:41 2009 @@ -256,16 +256,12 @@ /* -- tables ---------------------------------------------------------------- */ table.docutils { - border: 0; + border: 0 solid #dce; border-collapse: collapse; } table.docutils td, table.docutils th { padding: 1px 8px 1px 5px; - border-top: 1px solid #b9b; - border-left: 0; - border-right: 0; - border-bottom: 1px solid #aaa; background-color: #eef; } @@ -278,13 +274,13 @@ } table.docutils th { + border-top: 1px solid #cac; background-color: #ede; } th { text-align: left; padding-right: 5px; - background-color: #ede; } th.head { From buildbot at python.org Fri Apr 10 03:01:11 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 10 Apr 2009 01:01:11 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 2.6 Message-ID: <20090410010111.B97CB1E4002@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%202.6/builds/229 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From nnorwitz at gmail.com Fri Apr 10 03:21:26 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 9 Apr 2009 21:21:26 -0400 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090410012126.GA23183@python.psfb.org> From nnorwitz at gmail.com Fri Apr 10 03:47:26 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 9 Apr 2009 21:47:26 -0400 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090410014726.GA23333@python.psfb.org> From nnorwitz at gmail.com Fri Apr 10 03:50:10 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 9 Apr 2009 21:50:10 -0400 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090410015010.GA23442@python.psfb.org> From python-checkins at python.org Fri Apr 10 04:01:21 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 10 Apr 2009 04:01:21 +0200 (CEST) Subject: [Python-checkins] r71429 - python/trunk/Doc/tools/sphinxext/static/basic.css Message-ID: <20090410020121.885D81E4002@bag.python.org> Author: raymond.hettinger Date: Fri Apr 10 04:01:21 2009 New Revision: 71429 Log: IE needs the border-left:0 for some reason. Modified: python/trunk/Doc/tools/sphinxext/static/basic.css Modified: python/trunk/Doc/tools/sphinxext/static/basic.css ============================================================================== --- python/trunk/Doc/tools/sphinxext/static/basic.css (original) +++ python/trunk/Doc/tools/sphinxext/static/basic.css Fri Apr 10 04:01:21 2009 @@ -261,7 +261,8 @@ } table.docutils td, table.docutils th { - padding: 1px 8px 1px 5px; + padding: 2px 5px 2px 5px; + border-left: 0; background-color: #eef; } From buildbot at python.org Fri Apr 10 04:35:00 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 10 Apr 2009 02:35:00 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090410023506.953B71E402D@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/507 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 249, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 102, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From buildbot at python.org Fri Apr 10 05:25:27 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 10 Apr 2009 03:25:27 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090410032528.AC4291E4017@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/258 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_distutils test_posix ====================================================================== FAIL: test_get_python_inc (distutils.tests.test_sysconfig.SysconfigTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/distutils/tests/test_sysconfig.py", line 45, in test_get_python_inc self.assert_(os.path.isdir(inc_dir), inc_dir) AssertionError: /home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/Include ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Fri Apr 10 06:25:45 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 10 Apr 2009 06:25:45 +0200 (CEST) Subject: [Python-checkins] r71430 - python/trunk/Doc/library/itertools.rst Message-ID: <20090410042545.F2D451E4017@bag.python.org> Author: raymond.hettinger Date: Fri Apr 10 06:25:45 2009 New Revision: 71430 Log: Clarify the table entries for combinatorics. Modified: python/trunk/Doc/library/itertools.rst Modified: python/trunk/Doc/library/itertools.rst ============================================================================== --- python/trunk/Doc/library/itertools.rst (original) +++ python/trunk/Doc/library/itertools.rst Fri Apr 10 06:25:45 2009 @@ -66,14 +66,19 @@ **Combinatoric generators:** - ===================================== ==================== ================================================= - Iterator Arguments Results - ===================================== ==================== ================================================= - :func:`product` p, q, ... [repeat=1] cartesian product - :func:`permutations` p[, r] r-length permutations (without repeated elements) - :func:`combinations` p[, r] r-length combinations (sorted and no repeats) - :func:`combinations_with_replacement` p[, r] r-length combinations (sorted but with repeats) - ===================================== ==================== ================================================= + ============================================== ==================== ============================================================= + Iterator Arguments Results + ============================================== ==================== ============================================================= + :func:`product` p, q, ... [repeat=1] cartesian product, equivalent to a nested for-loop + :func:`permutations` p[, r] r-length tuples, all possible orderings, no repeated elements + :func:`combinations` p[, r] r-length tuples, in sorted order, no repeated elements + :func:`combinations_with_replacement` p[, r] r-length tuples, in sorted order, with repeated elements + | + ``product('ABCD', repeat=2)`` ``AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD`` + ``permutations('ABCD', 2)`` ``AB AC AD BA BC BD CA CB CD DA DB DC`` + ``combinations('ABCD', 2)`` ``AB AC AD BC BD CD`` + ``combinations_with_replacement('ABCD', 2)`` ``AA AB AC AD BB BC BD CC CD DD`` + ============================================== ==================== ============================================================= .. _itertools-functions: From python-checkins at python.org Fri Apr 10 06:27:37 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 10 Apr 2009 06:27:37 +0200 (CEST) Subject: [Python-checkins] r71431 - python/branches/py3k/Doc/library/itertools.rst Message-ID: <20090410042737.EB1631E40DF@bag.python.org> Author: raymond.hettinger Date: Fri Apr 10 06:27:37 2009 New Revision: 71431 Log: Clarify the table entries for combinatorics. 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 Fri Apr 10 06:27:37 2009 @@ -61,14 +61,19 @@ **Combinatoric generators:** - ===================================== ==================== ================================================= - Iterator Arguments Results - ===================================== ==================== ================================================= - :func:`product` p, q, ... [repeat=1] cartesian product - :func:`permutations` p[, r] r-length permutations (without repeated elements) - :func:`combinations` p[, r] r-length combinations (sorted and no repeats) - :func:`combinations_with_replacement` p[, r] r-length combinations (sorted but with repeats) - ===================================== ==================== ================================================= + ============================================== ==================== ============================================================= + Iterator Arguments Results + ============================================== ==================== ============================================================= + :func:`product` p, q, ... [repeat=1] cartesian product, equivalent to a nested for-loop + :func:`permutations` p[, r] r-length tuples, all possible orderings, no repeated elements + :func:`combinations` p[, r] r-length tuples, in sorted order, no repeated elements + :func:`combinations_with_replacement` p[, r] r-length tuples, in sorted order, with repeated elements + | + ``product('ABCD', repeat=2)`` ``AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD`` + ``permutations('ABCD', 2)`` ``AB AC AD BA BC BD CA CB CD DA DB DC`` + ``combinations('ABCD', 2)`` ``AB AC AD BC BD CD`` + ``combinations_with_replacement('ABCD', 2)`` ``AA AB AC AD BB BC BD CC CD DD`` + ============================================== ==================== ============================================================= .. _itertools-functions: From python-checkins at python.org Fri Apr 10 06:29:24 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 10 Apr 2009 06:29:24 +0200 (CEST) Subject: [Python-checkins] r71432 - python/branches/release26-maint/Doc/library/itertools.rst Message-ID: <20090410042924.E74681E4017@bag.python.org> Author: raymond.hettinger Date: Fri Apr 10 06:29:23 2009 New Revision: 71432 Log: Clarify the table entries for combinatorics. Modified: python/branches/release26-maint/Doc/library/itertools.rst Modified: python/branches/release26-maint/Doc/library/itertools.rst ============================================================================== --- python/branches/release26-maint/Doc/library/itertools.rst (original) +++ python/branches/release26-maint/Doc/library/itertools.rst Fri Apr 10 06:29:23 2009 @@ -65,13 +65,17 @@ **Combinatoric generators:** - ===================================== ==================== ================================================= - Iterator Arguments Results - ===================================== ==================== ================================================= - :func:`product` p, q, ... [repeat=1] cartesian product - :func:`permutations` p[, r] r-length permutations (without repeated elements) - :func:`combinations` p[, r] r-length combinations (sorted and no repeats) - ===================================== ==================== ================================================= + ============================================== ==================== ============================================================= + Iterator Arguments Results + ============================================== ==================== ============================================================= + :func:`product` p, q, ... [repeat=1] cartesian product, equivalent to a nested for-loop + :func:`permutations` p[, r] r-length tuples, all possible orderings, no repeated elements + :func:`combinations` p[, r] r-length tuples, in sorted order, no repeated elements + | + ``product('ABCD', repeat=2)`` ``AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD`` + ``permutations('ABCD', 2)`` ``AB AC AD BA BC BD CA CB CD DA DB DC`` + ``combinations('ABCD', 2)`` ``AB AC AD BC BD CD`` + ============================================== ==================== ============================================================= .. _itertools-functions: From python-checkins at python.org Fri Apr 10 06:30:08 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 10 Apr 2009 06:30:08 +0200 (CEST) Subject: [Python-checkins] r71433 - python/branches/release30-maint/Doc/library/itertools.rst Message-ID: <20090410043008.C8FC21E4017@bag.python.org> Author: raymond.hettinger Date: Fri Apr 10 06:30:08 2009 New Revision: 71433 Log: Clarify the table entries for combinatorics. Modified: python/branches/release30-maint/Doc/library/itertools.rst Modified: python/branches/release30-maint/Doc/library/itertools.rst ============================================================================== --- python/branches/release30-maint/Doc/library/itertools.rst (original) +++ python/branches/release30-maint/Doc/library/itertools.rst Fri Apr 10 06:30:08 2009 @@ -60,13 +60,17 @@ **Combinatoric generators:** - ===================================== ==================== ================================================= - Iterator Arguments Results - ===================================== ==================== ================================================= - :func:`product` p, q, ... [repeat=1] cartesian product - :func:`permutations` p[, r] r-length permutations (without repeated elements) - :func:`combinations` p[, r] r-length combinations (sorted and no repeats) - ===================================== ==================== ================================================= + ============================================== ==================== ============================================================= + Iterator Arguments Results + ============================================== ==================== ============================================================= + :func:`product` p, q, ... [repeat=1] cartesian product, equivalent to a nested for-loop + :func:`permutations` p[, r] r-length tuples, all possible orderings, no repeated elements + :func:`combinations` p[, r] r-length tuples, in sorted order, no repeated elements + | + ``product('ABCD', repeat=2)`` ``AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD`` + ``permutations('ABCD', 2)`` ``AB AC AD BA BC BD CA CB CD DA DB DC`` + ``combinations('ABCD', 2)`` ``AB AC AD BC BD CD`` + ============================================== ==================== ============================================================= .. _itertools-functions: From python-checkins at python.org Fri Apr 10 07:33:27 2009 From: python-checkins at python.org (jack.diederich) Date: Fri, 10 Apr 2009 07:33:27 +0200 (CEST) Subject: [Python-checkins] r71434 - in python/branches/py3k/Lib: telnetlib.py test/test_telnetlib.py Message-ID: <20090410053327.431D41E4017@bag.python.org> Author: jack.diederich Date: Fri Apr 10 07:33:26 2009 New Revision: 71434 Log: -fixes telnetlib constants to be one-length byte arrays instead of ints -this fixes telnet negotiation (broken in 3.0) -merged/ported telnetlib tests from trunk (below) Merged revisions 71302,71377,71385 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71302 | jack.diederich | 2009-04-05 22:08:44 -0400 (Sun, 05 Apr 2009) | 1 line test the telnetlib.Telnet interface more thoroughly ........ r71377 | jack.diederich | 2009-04-07 16:22:59 -0400 (Tue, 07 Apr 2009) | 1 line eliminate more race conditions in telnetlib tests ........ r71385 | jack.diederich | 2009-04-07 19:56:57 -0400 (Tue, 07 Apr 2009) | 4 lines - Make timing assertions very generous (a la test_timeout.py) - Break the gc cycle in negotiation tests - test the different guarantees of read_lazy and read_very_lazy ........ Modified: python/branches/py3k/Lib/telnetlib.py python/branches/py3k/Lib/test/test_telnetlib.py Modified: python/branches/py3k/Lib/telnetlib.py ============================================================================== --- python/branches/py3k/Lib/telnetlib.py (original) +++ python/branches/py3k/Lib/telnetlib.py Fri Apr 10 07:33:26 2009 @@ -47,87 +47,87 @@ TELNET_PORT = 23 # Telnet protocol characters (don't change) -IAC = 255 # "Interpret As Command" -DONT = 254 -DO = 253 -WONT = 252 -WILL = 251 -theNULL = 0 - -SE = 240 # Subnegotiation End -NOP = 241 # No Operation -DM = 242 # Data Mark -BRK = 243 # Break -IP = 244 # Interrupt process -AO = 245 # Abort output -AYT = 246 # Are You There -EC = 247 # Erase Character -EL = 248 # Erase Line -GA = 249 # Go Ahead -SB = 250 # Subnegotiation Begin +IAC = bytes([255]) # "Interpret As Command" +DONT = bytes([254]) +DO = bytes([253]) +WONT = bytes([252]) +WILL = bytes([251]) +theNULL = bytes([0]) + +SE = bytes([240]) # Subnegotiation End +NOP = bytes([241]) # No Operation +DM = bytes([242]) # Data Mark +BRK = bytes([243]) # Break +IP = bytes([244]) # Interrupt process +AO = bytes([245]) # Abort output +AYT = bytes([246]) # Are You There +EC = bytes([247]) # Erase Character +EL = bytes([248]) # Erase Line +GA = bytes([249]) # Go Ahead +SB = bytes([250]) # Subnegotiation Begin # Telnet protocol options code (don't change) # These ones all come from arpa/telnet.h -BINARY = 0 # 8-bit data path -ECHO = 1 # echo -RCP = 2 # prepare to reconnect -SGA = 3 # suppress go ahead -NAMS = 4 # approximate message size -STATUS = 5 # give status -TM = 6 # timing mark -RCTE = 7 # remote controlled transmission and echo -NAOL = 8 # negotiate about output line width -NAOP = 9 # negotiate about output page size -NAOCRD = 10 # negotiate about CR disposition -NAOHTS = 11 # negotiate about horizontal tabstops -NAOHTD = 12 # negotiate about horizontal tab disposition -NAOFFD = 13 # negotiate about formfeed disposition -NAOVTS = 14 # negotiate about vertical tab stops -NAOVTD = 15 # negotiate about vertical tab disposition -NAOLFD = 16 # negotiate about output LF disposition -XASCII = 17 # extended ascii character set -LOGOUT = 18 # force logout -BM = 19 # byte macro -DET = 20 # data entry terminal -SUPDUP = 21 # supdup protocol -SUPDUPOUTPUT = 22 # supdup output -SNDLOC = 23 # send location -TTYPE = 24 # terminal type -EOR = 25 # end or record -TUID = 26 # TACACS user identification -OUTMRK = 27 # output marking -TTYLOC = 28 # terminal location number -VT3270REGIME = 29 # 3270 regime -X3PAD = 30 # X.3 PAD -NAWS = 31 # window size -TSPEED = 32 # terminal speed -LFLOW = 33 # remote flow control -LINEMODE = 34 # Linemode option -XDISPLOC = 35 # X Display Location -OLD_ENVIRON = 36 # Old - Environment variables -AUTHENTICATION = 37 # Authenticate -ENCRYPT = 38 # Encryption option -NEW_ENVIRON = 39 # New - Environment variables +BINARY = bytes([0]) # 8-bit data path +ECHO = bytes([1]) # echo +RCP = bytes([2]) # prepare to reconnect +SGA = bytes([3]) # suppress go ahead +NAMS = bytes([4]) # approximate message size +STATUS = bytes([5]) # give status +TM = bytes([6]) # timing mark +RCTE = bytes([7]) # remote controlled transmission and echo +NAOL = bytes([8]) # negotiate about output line width +NAOP = bytes([9]) # negotiate about output page size +NAOCRD = bytes([10]) # negotiate about CR disposition +NAOHTS = bytes([11]) # negotiate about horizontal tabstops +NAOHTD = bytes([12]) # negotiate about horizontal tab disposition +NAOFFD = bytes([13]) # negotiate about formfeed disposition +NAOVTS = bytes([14]) # negotiate about vertical tab stops +NAOVTD = bytes([15]) # negotiate about vertical tab disposition +NAOLFD = bytes([16]) # negotiate about output LF disposition +XASCII = bytes([17]) # extended ascii character set +LOGOUT = bytes([18]) # force logout +BM = bytes([19]) # byte macro +DET = bytes([20]) # data entry terminal +SUPDUP = bytes([21]) # supdup protocol +SUPDUPOUTPUT = bytes([22]) # supdup output +SNDLOC = bytes([23]) # send location +TTYPE = bytes([24]) # terminal type +EOR = bytes([25]) # end or record +TUID = bytes([26]) # TACACS user identification +OUTMRK = bytes([27]) # output marking +TTYLOC = bytes([28]) # terminal location number +VT3270REGIME = bytes([29]) # 3270 regime +X3PAD = bytes([30]) # X.3 PAD +NAWS = bytes([31]) # window size +TSPEED = bytes([32]) # terminal speed +LFLOW = bytes([33]) # remote flow control +LINEMODE = bytes([34]) # Linemode option +XDISPLOC = bytes([35]) # X Display Location +OLD_ENVIRON = bytes([36]) # Old - Environment variables +AUTHENTICATION = bytes([37]) # Authenticate +ENCRYPT = bytes([38]) # Encryption option +NEW_ENVIRON = bytes([39]) # New - Environment variables # the following ones come from # http://www.iana.org/assignments/telnet-options # Unfortunately, that document does not assign identifiers # to all of them, so we are making them up -TN3270E = 40 # TN3270E -XAUTH = 41 # XAUTH -CHARSET = 42 # CHARSET -RSP = 43 # Telnet Remote Serial Port -COM_PORT_OPTION = 44 # Com Port Control Option -SUPPRESS_LOCAL_ECHO = 45 # Telnet Suppress Local Echo -TLS = 46 # Telnet Start TLS -KERMIT = 47 # KERMIT -SEND_URL = 48 # SEND-URL -FORWARD_X = 49 # FORWARD_X -PRAGMA_LOGON = 138 # TELOPT PRAGMA LOGON -SSPI_LOGON = 139 # TELOPT SSPI LOGON -PRAGMA_HEARTBEAT = 140 # TELOPT PRAGMA HEARTBEAT -EXOPL = 255 # Extended-Options-List -NOOPT = 0 +TN3270E = bytes([40]) # TN3270E +XAUTH = bytes([41]) # XAUTH +CHARSET = bytes([42]) # CHARSET +RSP = bytes([43]) # Telnet Remote Serial Port +COM_PORT_OPTION = bytes([44]) # Com Port Control Option +SUPPRESS_LOCAL_ECHO = bytes([45]) # Telnet Suppress Local Echo +TLS = bytes([46]) # Telnet Start TLS +KERMIT = bytes([47]) # KERMIT +SEND_URL = bytes([48]) # SEND-URL +FORWARD_X = bytes([49]) # FORWARD_X +PRAGMA_LOGON = bytes([138]) # TELOPT PRAGMA LOGON +SSPI_LOGON = bytes([139]) # TELOPT SSPI LOGON +PRAGMA_HEARTBEAT = bytes([140]) # TELOPT PRAGMA HEARTBEAT +EXOPL = bytes([255]) # Extended-Options-List +NOOPT = bytes([0]) class Telnet: 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 Fri Apr 10 07:33:26 2009 @@ -2,17 +2,38 @@ import threading import telnetlib import time +import queue from unittest import TestCase from test import support HOST = support.HOST +EOF_sigil = object() -def server(evt, serv): +def server(evt, serv, dataq=None): + """ Open a tcp server in three steps + 1) set evt to true to let the parent know we are ready + 2) [optional] if is not False, write the list of data from dataq.get() + to the socket. + 3) set evt to true to let the parent know we're done + """ serv.listen(5) evt.set() try: conn, addr = serv.accept() + if dataq: + data = b'' + new_data = dataq.get(True, 0.5) + dataq.task_done() + for item in new_data: + if item == EOF_sigil: + break + if type(item) in [int, float]: + time.sleep(item) + else: + data += item + written = conn.send(data) + data = data[written:] except socket.timeout: pass finally: @@ -26,13 +47,15 @@ self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.settimeout(3) self.port = support.bind_port(self.sock) - threading.Thread(target=server, args=(self.evt,self.sock)).start() + self.thread = threading.Thread(target=server, args=(self.evt,self.sock)) + self.thread.start() self.evt.wait() self.evt.clear() time.sleep(.1) def tearDown(self): self.evt.wait() + self.thread.join() def testBasic(self): # connects @@ -71,9 +94,277 @@ self.assertEqual(telnet.sock.gettimeout(), 30) telnet.sock.close() +def _read_setUp(self): + self.evt = threading.Event() + self.dataq = queue.Queue() + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.sock.settimeout(3) + self.port = support.bind_port(self.sock) + self.thread = threading.Thread(target=server, args=(self.evt,self.sock, self.dataq)) + self.thread.start() + self.evt.wait() + self.evt.clear() + time.sleep(.1) + +def _read_tearDown(self): + self.evt.wait() + self.thread.join() + +class ReadTests(TestCase): + setUp = _read_setUp + tearDown = _read_tearDown + + # use a similar approach to testing timeouts as test_timeout.py + # these will never pass 100% but make the fuzz big enough that it is rare + block_long = 0.6 + block_short = 0.3 + def test_read_until_A(self): + """ + read_until(expected, [timeout]) + Read until the expected string has been seen, or a timeout is + hit (default is no timeout); may block. + """ + want = [b'x' * 10, b'match', b'y' * 10, EOF_sigil] + self.dataq.put(want) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + data = telnet.read_until(b'match') + self.assertEqual(data, b''.join(want[:-2])) + + def test_read_until_B(self): + # test the timeout - it does NOT raise socket.timeout + want = [b'hello', self.block_long, b'not seen', EOF_sigil] + self.dataq.put(want) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + data = telnet.read_until(b'not seen', self.block_short) + self.assertEqual(data, want[0]) + self.assertEqual(telnet.read_all(), b'not seen') + + def test_read_all_A(self): + """ + read_all() + Read all data until EOF; may block. + """ + want = [b'x' * 500, b'y' * 500, b'z' * 500, EOF_sigil] + self.dataq.put(want) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + data = telnet.read_all() + self.assertEqual(data, b''.join(want[:-1])) + return + + def _test_blocking(self, func): + self.dataq.put([self.block_long, EOF_sigil]) + self.dataq.join() + start = time.time() + data = func() + self.assertTrue(self.block_short <= time.time() - start) + + def test_read_all_B(self): + self._test_blocking(telnetlib.Telnet(HOST, self.port).read_all) + + def test_read_all_C(self): + self.dataq.put([EOF_sigil]) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + telnet.read_all() + telnet.read_all() # shouldn't raise + + def test_read_some_A(self): + """ + read_some() + Read at least one byte or EOF; may block. + """ + # test 'at least one byte' + want = [b'x' * 500, EOF_sigil] + self.dataq.put(want) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + data = telnet.read_all() + self.assertTrue(len(data) >= 1) + + def test_read_some_B(self): + # test EOF + self.dataq.put([EOF_sigil]) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + self.assertEqual(b'', telnet.read_some()) + + def test_read_some_C(self): + self._test_blocking(telnetlib.Telnet(HOST, self.port).read_some) + + def _test_read_any_eager_A(self, func_name): + """ + read_very_eager() + Read all data available already queued or on the socket, + without blocking. + """ + want = [self.block_long, b'x' * 100, b'y' * 100, EOF_sigil] + expects = want[1] + want[2] + self.dataq.put(want) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + func = getattr(telnet, func_name) + data = b'' + while True: + try: + data += func() + self.assertTrue(expects.startswith(data)) + except EOFError: + break + self.assertEqual(expects, data) + + def _test_read_any_eager_B(self, func_name): + # test EOF + self.dataq.put([EOF_sigil]) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + time.sleep(self.block_short) + func = getattr(telnet, func_name) + self.assertRaises(EOFError, func) + + # read_eager and read_very_eager make the same gaurantees + # (they behave differently but we only test the gaurantees) + def test_read_very_eager_A(self): + self._test_read_any_eager_A('read_very_eager') + def test_read_very_eager_B(self): + self._test_read_any_eager_B('read_very_eager') + def test_read_eager_A(self): + self._test_read_any_eager_A('read_eager') + def test_read_eager_B(self): + self._test_read_any_eager_B('read_eager') + # NB -- we need to test the IAC block which is mentioned in the docstring + # but not in the module docs + + def _test_read_any_lazy_B(self, func_name): + self.dataq.put([EOF_sigil]) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + func = getattr(telnet, func_name) + telnet.fill_rawq() + self.assertRaises(EOFError, func) + + def test_read_lazy_A(self): + want = [b'x' * 100, EOF_sigil] + self.dataq.put(want) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + time.sleep(self.block_short) + self.assertEqual(b'', telnet.read_lazy()) + data = b'' + while True: + try: + read_data = telnet.read_lazy() + data += read_data + if not read_data: + telnet.fill_rawq() + except EOFError: + break + self.assertTrue(want[0].startswith(data)) + self.assertEqual(data, want[0]) + + def test_read_lazy_B(self): + self._test_read_any_lazy_B('read_lazy') + + def test_read_very_lazy_A(self): + want = [b'x' * 100, EOF_sigil] + self.dataq.put(want) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + time.sleep(self.block_short) + self.assertEqual(b'', telnet.read_very_lazy()) + data = b'' + while True: + try: + read_data = telnet.read_very_lazy() + except EOFError: + break + data += read_data + if not read_data: + telnet.fill_rawq() + self.assertEqual(b'', telnet.cookedq) + telnet.process_rawq() + self.assertTrue(want[0].startswith(data)) + self.assertEqual(data, want[0]) + + def test_read_very_lazy_B(self): + self._test_read_any_lazy_B('read_very_lazy') + +class nego_collector(object): + def __init__(self, sb_getter=None): + self.seen = b'' + self.sb_getter = sb_getter + self.sb_seen = b'' + + def do_nego(self, sock, cmd, opt): + self.seen += cmd + opt + if cmd == tl.SE and self.sb_getter: + sb_data = self.sb_getter() + self.sb_seen += sb_data + +tl = telnetlib +class OptionTests(TestCase): + setUp = _read_setUp + tearDown = _read_tearDown + # RFC 854 commands + cmds = [tl.AO, tl.AYT, tl.BRK, tl.EC, tl.EL, tl.GA, tl.IP, tl.NOP] + + def _test_command(self, data): + """ helper for testing IAC + cmd """ + self.setUp() + self.dataq.put(data) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + nego = nego_collector() + telnet.set_option_negotiation_callback(nego.do_nego) + txt = telnet.read_all() + cmd = nego.seen + self.assertTrue(len(cmd) > 0) # we expect at least one command + self.assertTrue(cmd[:1] in self.cmds) + self.assertEqual(cmd[1:2], tl.NOOPT) + self.assertEqual(len(b''.join(data[:-1])), len(txt + cmd)) + nego.sb_getter = None # break the nego => telnet cycle + self.tearDown() + + def test_IAC_commands(self): + # reset our setup + self.dataq.put([EOF_sigil]) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + self.tearDown() + + for cmd in self.cmds: + self._test_command([tl.IAC, cmd, EOF_sigil]) + self._test_command([b'x' * 100, tl.IAC, cmd, b'y'*100, EOF_sigil]) + self._test_command([b'x' * 10, tl.IAC, cmd, b'y'*10, EOF_sigil]) + # all at once + self._test_command([tl.IAC + cmd for (cmd) in self.cmds] + [EOF_sigil]) + self.assertEqual(b'', telnet.read_sb_data()) + + def test_SB_commands(self): + # RFC 855, subnegotiations portion + send = [tl.IAC + tl.SB + tl.IAC + tl.SE, + tl.IAC + tl.SB + tl.IAC + tl.IAC + tl.IAC + tl.SE, + tl.IAC + tl.SB + tl.IAC + tl.IAC + b'aa' + tl.IAC + tl.SE, + tl.IAC + tl.SB + b'bb' + tl.IAC + tl.IAC + tl.IAC + tl.SE, + tl.IAC + tl.SB + b'cc' + tl.IAC + tl.IAC + b'dd' + tl.IAC + tl.SE, + EOF_sigil, + ] + self.dataq.put(send) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + nego = nego_collector(telnet.read_sb_data) + telnet.set_option_negotiation_callback(nego.do_nego) + txt = telnet.read_all() + self.assertEqual(txt, b'') + want_sb_data = tl.IAC + tl.IAC + b'aabb' + tl.IAC + b'cc' + tl.IAC + b'dd' + self.assertEqual(nego.sb_seen, want_sb_data) + self.assertEqual(b'', telnet.read_sb_data()) + nego.sb_getter = None # break the nego => telnet cycle def test_main(verbose=None): - support.run_unittest(GeneralTests) + support.run_unittest(GeneralTests, ReadTests, OptionTests) if __name__ == '__main__': test_main() From python-checkins at python.org Fri Apr 10 08:38:39 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 10 Apr 2009 08:38:39 +0200 (CEST) Subject: [Python-checkins] r71435 - python/trunk/Doc/library/collections.rst Message-ID: <20090410063839.5F3D41E4017@bag.python.org> Author: raymond.hettinger Date: Fri Apr 10 08:38:39 2009 New Revision: 71435 Log: Fix the count of datatypes. Modified: python/trunk/Doc/library/collections.rst Modified: python/trunk/Doc/library/collections.rst ============================================================================== --- python/trunk/Doc/library/collections.rst (original) +++ python/trunk/Doc/library/collections.rst Fri Apr 10 08:38:39 2009 @@ -16,7 +16,7 @@ __name__ = '' This module implements high-performance container datatypes. Currently, -there are three datatypes, :class:`Counter`, :class:`deque`, :class:`OrderedDict` and +there are four datatypes, :class:`Counter`, :class:`deque`, :class:`OrderedDict` and :class:`defaultdict`, and one datatype factory function, :func:`namedtuple`. The specialized containers provided in this module provide alternatives From python-checkins at python.org Fri Apr 10 09:01:53 2009 From: python-checkins at python.org (georg.brandl) Date: Fri, 10 Apr 2009 09:01:53 +0200 (CEST) Subject: [Python-checkins] r71436 - in python/branches/py3k: Doc/tools/sphinxext/static/basic.css Message-ID: <20090410070153.288381E4053@bag.python.org> Author: georg.brandl Date: Fri Apr 10 09:01:52 2009 New Revision: 71436 Log: Merged revisions 71409 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71409 | georg.brandl | 2009-04-09 21:01:04 +0200 (Do, 09 Apr 2009) | 1 line Add a custom stylesheet with better table formatting. ........ Added: python/branches/py3k/Doc/tools/sphinxext/static/basic.css - copied unchanged from r71409, /python/trunk/Doc/tools/sphinxext/static/basic.css Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Fri Apr 10 09:02:57 2009 From: python-checkins at python.org (georg.brandl) Date: Fri, 10 Apr 2009 09:02:57 +0200 (CEST) Subject: [Python-checkins] r71437 - in python/branches/py3k: Doc/tools/sphinxext/static/basic.css Message-ID: <20090410070257.BD0181E4017@bag.python.org> Author: georg.brandl Date: Fri Apr 10 09:02:56 2009 New Revision: 71437 Log: Merged revisions 71424-71425,71428-71429 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71424 | raymond.hettinger | 2009-04-10 01:25:30 +0200 (Fr, 10 Apr 2009) | 1 line More table formatting. ........ r71425 | raymond.hettinger | 2009-04-10 01:34:14 +0200 (Fr, 10 Apr 2009) | 1 line Center table headings. ........ r71428 | raymond.hettinger | 2009-04-10 02:49:41 +0200 (Fr, 10 Apr 2009) | 1 line More table clean-up ........ r71429 | raymond.hettinger | 2009-04-10 04:01:21 +0200 (Fr, 10 Apr 2009) | 1 line IE needs the border-left:0 for some reason. ........ Modified: python/branches/py3k/ (props changed) 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 Fri Apr 10 09:02:56 2009 @@ -256,16 +256,14 @@ /* -- tables ---------------------------------------------------------------- */ table.docutils { - border: 0; + border: 0 solid #dce; border-collapse: collapse; } table.docutils td, table.docutils th { - padding: 1px 8px 1px 5px; - border-top: 0; - border-left: 0; - border-right: 0; - border-bottom: 1px solid #aaa; + padding: 2px 5px 2px 5px; + border-left: 0; + background-color: #eef; } table.field-list td, table.field-list th { @@ -276,10 +274,18 @@ border: 0 !important; } +table.docutils th { + border-top: 1px solid #cac; + background-color: #ede; +} + th { text-align: left; padding-right: 5px; - background-color: #ede; +} + +th.head { + text-align: center; } /* -- other body styles ----------------------------------------------------- */ From python-checkins at python.org Fri Apr 10 09:07:22 2009 From: python-checkins at python.org (georg.brandl) Date: Fri, 10 Apr 2009 09:07:22 +0200 (CEST) Subject: [Python-checkins] r71438 - in python/branches/release30-maint: Doc/tools/sphinxext/static/basic.css Message-ID: <20090410070722.936411E4017@bag.python.org> Author: georg.brandl Date: Fri Apr 10 09:07:22 2009 New Revision: 71438 Log: Merged revisions 71436-71437 via svnmerge from svn+ssh://svn.python.org/python/branches/py3k ................ r71436 | georg.brandl | 2009-04-10 09:01:52 +0200 (Fr, 10 Apr 2009) | 9 lines Merged revisions 71409 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71409 | georg.brandl | 2009-04-09 21:01:04 +0200 (Do, 09 Apr 2009) | 1 line Add a custom stylesheet with better table formatting. ........ ................ r71437 | georg.brandl | 2009-04-10 09:02:56 +0200 (Fr, 10 Apr 2009) | 21 lines Merged revisions 71424-71425,71428-71429 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71424 | raymond.hettinger | 2009-04-10 01:25:30 +0200 (Fr, 10 Apr 2009) | 1 line More table formatting. ........ r71425 | raymond.hettinger | 2009-04-10 01:34:14 +0200 (Fr, 10 Apr 2009) | 1 line Center table headings. ........ r71428 | raymond.hettinger | 2009-04-10 02:49:41 +0200 (Fr, 10 Apr 2009) | 1 line More table clean-up ........ r71429 | raymond.hettinger | 2009-04-10 04:01:21 +0200 (Fr, 10 Apr 2009) | 1 line IE needs the border-left:0 for some reason. ........ ................ Added: python/branches/release30-maint/Doc/tools/sphinxext/static/basic.css - copied unchanged from r71437, /python/branches/py3k/Doc/tools/sphinxext/static/basic.css Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Fri Apr 10 09:09:05 2009 From: python-checkins at python.org (georg.brandl) Date: Fri, 10 Apr 2009 09:09:05 +0200 (CEST) Subject: [Python-checkins] r71439 - in python/branches/release26-maint: Doc/tools/sphinxext/static/basic.css Message-ID: <20090410070905.356471E4017@bag.python.org> Author: georg.brandl Date: Fri Apr 10 09:09:05 2009 New Revision: 71439 Log: Merged revisions 71409 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71409 | georg.brandl | 2009-04-09 21:01:04 +0200 (Do, 09 Apr 2009) | 1 line Add a custom stylesheet with better table formatting. ........ Added: python/branches/release26-maint/Doc/tools/sphinxext/static/basic.css - copied unchanged from r71409, /python/trunk/Doc/tools/sphinxext/static/basic.css Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Fri Apr 10 09:09:49 2009 From: python-checkins at python.org (georg.brandl) Date: Fri, 10 Apr 2009 09:09:49 +0200 (CEST) Subject: [Python-checkins] r71440 - in python/branches/release26-maint: Doc/tools/sphinxext/static/basic.css Message-ID: <20090410070949.79A361E4017@bag.python.org> Author: georg.brandl Date: Fri Apr 10 09:09:49 2009 New Revision: 71440 Log: Merged revisions 71424-71425,71428-71429 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71424 | raymond.hettinger | 2009-04-10 01:25:30 +0200 (Fr, 10 Apr 2009) | 1 line More table formatting. ........ r71425 | raymond.hettinger | 2009-04-10 01:34:14 +0200 (Fr, 10 Apr 2009) | 1 line Center table headings. ........ r71428 | raymond.hettinger | 2009-04-10 02:49:41 +0200 (Fr, 10 Apr 2009) | 1 line More table clean-up ........ r71429 | raymond.hettinger | 2009-04-10 04:01:21 +0200 (Fr, 10 Apr 2009) | 1 line IE needs the border-left:0 for some reason. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/tools/sphinxext/static/basic.css Modified: python/branches/release26-maint/Doc/tools/sphinxext/static/basic.css ============================================================================== --- python/branches/release26-maint/Doc/tools/sphinxext/static/basic.css (original) +++ python/branches/release26-maint/Doc/tools/sphinxext/static/basic.css Fri Apr 10 09:09:49 2009 @@ -256,16 +256,14 @@ /* -- tables ---------------------------------------------------------------- */ table.docutils { - border: 0; + border: 0 solid #dce; border-collapse: collapse; } table.docutils td, table.docutils th { - padding: 1px 8px 1px 5px; - border-top: 0; - border-left: 0; - border-right: 0; - border-bottom: 1px solid #aaa; + padding: 2px 5px 2px 5px; + border-left: 0; + background-color: #eef; } table.field-list td, table.field-list th { @@ -276,10 +274,18 @@ border: 0 !important; } +table.docutils th { + border-top: 1px solid #cac; + background-color: #ede; +} + th { text-align: left; padding-right: 5px; - background-color: #ede; +} + +th.head { + text-align: center; } /* -- other body styles ----------------------------------------------------- */ From buildbot at python.org Fri Apr 10 09:49:20 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 10 Apr 2009 07:49:20 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090410074920.A37B41E4017@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/509 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_posix test_smtplib ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 249, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 102, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From buildbot at python.org Fri Apr 10 10:04:02 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 10 Apr 2009 08:04:02 +0000 Subject: [Python-checkins] buildbot failure in OS X x86 2.6 Message-ID: <20090410080403.1BEEB1E401B@bag.python.org> The Buildbot has detected a new failure of OS X x86 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/OS%20X%20x86%202.6/builds/196 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: noller-osx86 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: georg.brandl,raymond.hettinger BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_bz2 make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Fri Apr 10 10:16:48 2009 From: python-checkins at python.org (georg.brandl) Date: Fri, 10 Apr 2009 10:16:48 +0200 (CEST) Subject: [Python-checkins] r71441 - python/trunk/Doc/reference/expressions.rst Message-ID: <20090410081648.8F0B91E4017@bag.python.org> Author: georg.brandl Date: Fri Apr 10 10:16:47 2009 New Revision: 71441 Log: Let "lambda" point to the correct heading. Modified: python/trunk/Doc/reference/expressions.rst Modified: python/trunk/Doc/reference/expressions.rst ============================================================================== --- python/trunk/Doc/reference/expressions.rst (original) +++ python/trunk/Doc/reference/expressions.rst Fri Apr 10 10:16:47 2009 @@ -1177,6 +1177,7 @@ .. _lambdas: +.. _lambda: Lambdas ======= @@ -1201,8 +1202,6 @@ See section :ref:`function` for the syntax of parameter lists. Note that functions created with lambda forms cannot contain statements. -.. _lambda: - .. _exprlists: From python-checkins at python.org Fri Apr 10 10:17:22 2009 From: python-checkins at python.org (georg.brandl) Date: Fri, 10 Apr 2009 10:17:22 +0200 (CEST) Subject: [Python-checkins] r71442 - in python/branches/py3k: Doc/reference/expressions.rst Message-ID: <20090410081722.0D5E21E4017@bag.python.org> Author: georg.brandl Date: Fri Apr 10 10:17:21 2009 New Revision: 71442 Log: Merged revisions 71441 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71441 | georg.brandl | 2009-04-10 10:16:47 +0200 (Fr, 10 Apr 2009) | 1 line Let "lambda" point to the correct heading. ........ Modified: python/branches/py3k/ (props changed) 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 Fri Apr 10 10:17:21 2009 @@ -1152,6 +1152,7 @@ .. _lambdas: +.. _lambda: Lambdas ======= @@ -1176,8 +1177,6 @@ See section :ref:`function` for the syntax of parameter lists. Note that functions created with lambda forms cannot contain statements or annotations. -.. _lambda: - .. _exprlists: From python-checkins at python.org Fri Apr 10 10:20:23 2009 From: python-checkins at python.org (georg.brandl) Date: Fri, 10 Apr 2009 10:20:23 +0200 (CEST) Subject: [Python-checkins] r71443 - python/trunk/Lib/pydoc.py Message-ID: <20090410082023.4F8681E4017@bag.python.org> Author: georg.brandl Date: Fri Apr 10 10:20:23 2009 New Revision: 71443 Log: #5698: Fix casing of !DOCTYPE to conform to W3C specs. Modified: python/trunk/Lib/pydoc.py Modified: python/trunk/Lib/pydoc.py ============================================================================== --- python/trunk/Lib/pydoc.py (original) +++ python/trunk/Lib/pydoc.py Fri Apr 10 10:20:23 2009 @@ -422,7 +422,7 @@ def page(self, title, contents): """Format an HTML page.""" return ''' - + Python: %s %s From buildbot at python.org Fri Apr 10 10:21:39 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 10 Apr 2009 08:21:39 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 2.6 Message-ID: <20090410082139.E58111E4017@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%202.6/builds/241 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: georg.brandl,raymond.hettinger BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_asynchat make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Fri Apr 10 10:28:28 2009 From: python-checkins at python.org (georg.brandl) Date: Fri, 10 Apr 2009 10:28:28 +0200 (CEST) Subject: [Python-checkins] r71444 - in python/branches/py3k: Lib/pydoc.py Message-ID: <20090410082828.EB6B51E401B@bag.python.org> Author: georg.brandl Date: Fri Apr 10 10:28:28 2009 New Revision: 71444 Log: Merged revisions 71443 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71443 | georg.brandl | 2009-04-10 10:20:23 +0200 (Fr, 10 Apr 2009) | 1 line #5698: Fix casing of !DOCTYPE to conform to W3C specs. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/pydoc.py Modified: python/branches/py3k/Lib/pydoc.py ============================================================================== --- python/branches/py3k/Lib/pydoc.py (original) +++ python/branches/py3k/Lib/pydoc.py Fri Apr 10 10:28:28 2009 @@ -415,7 +415,7 @@ def page(self, title, contents): """Format an HTML page.""" return ''' - + Python: %s %s From python-checkins at python.org Fri Apr 10 10:31:48 2009 From: python-checkins at python.org (georg.brandl) Date: Fri, 10 Apr 2009 10:31:48 +0200 (CEST) Subject: [Python-checkins] r71445 - python/branches/py3k/Lib/pydoc.py Message-ID: <20090410083148.624C21E401B@bag.python.org> Author: georg.brandl Date: Fri Apr 10 10:31:48 2009 New Revision: 71445 Log: #5698, part 2: generate a meta info in pydoc HTML pages indicating the encoding, and fix the -w option to use the correct encoding. Modified: python/branches/py3k/Lib/pydoc.py Modified: python/branches/py3k/Lib/pydoc.py ============================================================================== --- python/branches/py3k/Lib/pydoc.py (original) +++ python/branches/py3k/Lib/pydoc.py Fri Apr 10 10:31:48 2009 @@ -414,9 +414,10 @@ def page(self, title, contents): """Format an HTML page.""" - return ''' + return '''\ Python: %s + %s ''' % (title, contents) @@ -1510,7 +1511,7 @@ try: object, name = resolve(thing, forceload) page = html.page(describe(object), html.document(object, name)) - file = open(name + '.html', 'w') + file = open(name + '.html', 'w', encoding='utf-8') file.write(page) file.close() print('wrote', name + '.html') From buildbot at python.org Fri Apr 10 10:46:35 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 10 Apr 2009 08:46:35 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 3.x Message-ID: <20090410084636.23F5A1E4021@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%203.x/builds/649 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_cmd_line_script make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Fri Apr 10 11:03:43 2009 From: python-checkins at python.org (georg.brandl) Date: Fri, 10 Apr 2009 11:03:43 +0200 (CEST) Subject: [Python-checkins] r71446 - in python/branches/py3k/Doc/library: codeop.rst collections.rst compileall.rst configparser.rst constants.rst copyreg.rst csv.rst curses.rst datetime.rst dbm.rst decimal.rst difflib.rst dis.rst doctest.rst Message-ID: <20090410090343.C2AC41E401D@bag.python.org> Author: georg.brandl Date: Fri Apr 10 11:03:43 2009 New Revision: 71446 Log: Update signature style for optional arguments, part 3. Modified: python/branches/py3k/Doc/library/codeop.rst python/branches/py3k/Doc/library/collections.rst python/branches/py3k/Doc/library/compileall.rst python/branches/py3k/Doc/library/configparser.rst python/branches/py3k/Doc/library/constants.rst python/branches/py3k/Doc/library/copyreg.rst python/branches/py3k/Doc/library/csv.rst python/branches/py3k/Doc/library/curses.rst python/branches/py3k/Doc/library/datetime.rst python/branches/py3k/Doc/library/dbm.rst python/branches/py3k/Doc/library/decimal.rst python/branches/py3k/Doc/library/difflib.rst python/branches/py3k/Doc/library/dis.rst python/branches/py3k/Doc/library/doctest.rst Modified: python/branches/py3k/Doc/library/codeop.rst ============================================================================== --- python/branches/py3k/Doc/library/codeop.rst (original) +++ python/branches/py3k/Doc/library/codeop.rst Fri Apr 10 11:03:43 2009 @@ -26,7 +26,7 @@ To do just the former: -.. function:: compile_command(source[, filename[, symbol]]) +.. function:: compile_command(source, filename="", symbol="single") Tries to compile *source*, which should be a string of Python code and return a code object if *source* is valid Python code. In that case, the filename Modified: python/branches/py3k/Doc/library/collections.rst ============================================================================== --- python/branches/py3k/Doc/library/collections.rst (original) +++ python/branches/py3k/Doc/library/collections.rst Fri Apr 10 11:03:43 2009 @@ -286,7 +286,7 @@ :class:`deque` objects ---------------------- -.. class:: deque([iterable[, maxlen]]) +.. class:: deque([iterable, [maxlen]]) Returns a new deque object initialized left-to-right (using :meth:`append`) with data from *iterable*. If *iterable* is not specified, the new deque is empty. @@ -605,7 +605,7 @@ self-documenting code. They can be used wherever regular tuples are used, and they add the ability to access fields by name instead of position index. -.. function:: namedtuple(typename, field_names, [verbose], [rename]) +.. function:: namedtuple(typename, field_names, verbose=False, rename=False) Returns a new tuple subclass named *typename*. The new subclass is used to create tuple-like objects that have fields accessible by attribute lookup as Modified: python/branches/py3k/Doc/library/compileall.rst ============================================================================== --- python/branches/py3k/Doc/library/compileall.rst (original) +++ python/branches/py3k/Doc/library/compileall.rst Fri Apr 10 11:03:43 2009 @@ -20,7 +20,7 @@ expression argument. All files that match the expression will be skipped. -.. function:: compile_dir(dir[, maxlevels[, ddir[, force[, rx[, quiet]]]]]) +.. function:: compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, quiet=False) 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 @@ -36,7 +36,7 @@ operation. -.. function:: compile_path([skip_curdir[, maxlevels[, force]]]) +.. function:: compile_path(skip_curdir=True, maxlevels=0, force=False) 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 Modified: python/branches/py3k/Doc/library/configparser.rst ============================================================================== --- python/branches/py3k/Doc/library/configparser.rst (original) +++ python/branches/py3k/Doc/library/configparser.rst Fri Apr 10 11:03:43 2009 @@ -56,7 +56,7 @@ write-back, as will be the keys within each section. -.. class:: RawConfigParser([defaults[, dict_type]]) +.. class:: RawConfigParser(defaults=None, dict_type=collections.OrderedDict) The basic configuration object. When *defaults* is given, it is initialized into the dictionary of intrinsic defaults. When *dict_type* is given, it will @@ -68,7 +68,7 @@ The default *dict_type* is :class:`collections.OrderedDict`. -.. class:: ConfigParser([defaults[, dict_type]]) +.. class:: ConfigParser(defaults=None, dict_type=collections.OrderedDict) Derived class of :class:`RawConfigParser` that implements the magical interpolation feature and adds optional arguments to the :meth:`get` and @@ -87,7 +87,7 @@ The default *dict_type* is :class:`collections.OrderedDict`. -.. class:: SafeConfigParser([defaults[, dict_type]]) +.. class:: SafeConfigParser(defaults=None, dict_type=collections.OrderedDict) Derived class of :class:`ConfigParser` that implements a more-sane variant of the magical interpolation feature. This implementation is more predictable as @@ -228,7 +228,7 @@ config.read(['site.cfg', os.path.expanduser('~/.myapp.cfg')]) -.. method:: RawConfigParser.readfp(fp[, filename]) +.. method:: RawConfigParser.readfp(fp, filename=None) Read and parse configuration data from the file or file-like object in *fp* (only the :meth:`readline` method is used). If *filename* is omitted and *fp* @@ -315,7 +315,7 @@ :class:`RawConfigParser` interface, adding some optional arguments. -.. method:: ConfigParser.get(section, option[, raw[, vars]]) +.. method:: ConfigParser.get(section, option, raw=False, vars=None) Get an *option* value for the named *section*. All the ``'%'`` interpolations are expanded in the return values, based on the defaults passed into the @@ -323,7 +323,7 @@ is true. -.. method:: ConfigParser.items(section[, raw[, vars]]) +.. method:: ConfigParser.items(section, raw=False, vars=None) Return a list of ``(name, value)`` pairs for each option in the given *section*. Optional arguments have the same meaning as for the :meth:`get` method. Modified: python/branches/py3k/Doc/library/constants.rst ============================================================================== --- python/branches/py3k/Doc/library/constants.rst (original) +++ python/branches/py3k/Doc/library/constants.rst Fri Apr 10 11:03:43 2009 @@ -61,8 +61,8 @@ built-in namespace. They are useful for the interactive interpreter shell and should not be used in programs. -.. data:: quit([code=None]) - exit([code=None]) +.. data:: quit(code=None) + exit(code=None) Objects that when printed, print a message like "Use quit() or Ctrl-D (i.e. EOF) to exit", and when called, raise :exc:`SystemExit` with the Modified: python/branches/py3k/Doc/library/copyreg.rst ============================================================================== --- python/branches/py3k/Doc/library/copyreg.rst (original) +++ python/branches/py3k/Doc/library/copyreg.rst Fri Apr 10 11:03:43 2009 @@ -24,7 +24,7 @@ hence not valid as a constructor), raises :exc:`TypeError`. -.. function:: pickle(type, function[, constructor]) +.. function:: pickle(type, function, constructor=None) Declares that *function* should be used as a "reduction" function for objects of type *type*. *function* should return either a string or a tuple Modified: python/branches/py3k/Doc/library/csv.rst ============================================================================== --- python/branches/py3k/Doc/library/csv.rst (original) +++ python/branches/py3k/Doc/library/csv.rst Fri Apr 10 11:03:43 2009 @@ -47,7 +47,7 @@ The :mod:`csv` module defines the following functions: -.. function:: reader(csvfile[, dialect='excel'][, fmtparam]) +.. function:: reader(csvfile, dialect='excel', **fmtparams) Return a reader object which will iterate over lines in the given *csvfile*. *csvfile* can be any object which supports the :term:`iterator` protocol and returns a @@ -57,7 +57,7 @@ *dialect* parameter can be given which is used to define a set of parameters specific to a particular CSV dialect. It may be an instance of a subclass of the :class:`Dialect` class or one of the strings returned by the - :func:`list_dialects` function. The other optional *fmtparam* keyword arguments + :func:`list_dialects` function. The other optional *fmtparams* keyword arguments can be given to override individual formatting parameters in the current dialect. For full details about the dialect and formatting parameters, see section :ref:`csv-fmt-params`. @@ -76,7 +76,7 @@ Spam, Lovely Spam, Wonderful Spam -.. function:: writer(csvfile[, dialect='excel'][, fmtparam]) +.. function:: writer(csvfile, dialect='excel', **fmtparams) Return a writer object responsible for converting the user's data into delimited strings on the given file-like object. *csvfile* can be any object with a @@ -84,7 +84,7 @@ parameter can be given which is used to define a set of parameters specific to a particular CSV dialect. It may be an instance of a subclass of the :class:`Dialect` class or one of the strings returned by the - :func:`list_dialects` function. The other optional *fmtparam* keyword arguments + :func:`list_dialects` function. The other optional *fmtparams* keyword arguments can be given to override individual formatting parameters in the current dialect. For full details about the dialect and formatting parameters, see section :ref:`csv-fmt-params`. To make it @@ -103,11 +103,11 @@ >>> spamWriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam']) -.. function:: register_dialect(name[, dialect][, fmtparam]) +.. function:: register_dialect(name[, dialect], **fmtparams) Associate *dialect* with *name*. *name* must be a string. The dialect can be specified either by passing a sub-class of :class:`Dialect`, or - by *fmtparam* keyword arguments, or both, with keyword arguments overriding + by *fmtparams* keyword arguments, or both, with keyword arguments overriding parameters of the dialect. For full details about the dialect and formatting parameters, see section :ref:`csv-fmt-params`. @@ -137,7 +137,7 @@ The :mod:`csv` module defines the following classes: -.. class:: DictReader(csvfile[, fieldnames=None[, restkey=None[, restval=None[, dialect='excel'[, *args, **kwds]]]]]) +.. class:: DictReader(csvfile, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds) Create an object which operates like a regular reader but maps the information read into a dict whose keys are given by the optional *fieldnames* parameter. @@ -151,7 +151,7 @@ arguments are passed to the underlying :class:`reader` instance. -.. class:: DictWriter(csvfile, fieldnames[, restval=''[, extrasaction='raise'[, dialect='excel'[, *args, **kwds]]]]) +.. class:: DictWriter(csvfile, fieldnames, restval='', extrasaction='raise', dialect='excel', *args, **kwds) Create an object which operates like a regular writer but maps dictionaries onto output rows. The *fieldnames* parameter identifies the order in which values in @@ -195,7 +195,7 @@ The :class:`Sniffer` class provides two methods: - .. method:: sniff(sample[, delimiters=None]) + .. method:: sniff(sample, delimiters=None) Analyze the given *sample* and return a :class:`Dialect` subclass reflecting the parameters found. If the optional *delimiters* parameter Modified: python/branches/py3k/Doc/library/curses.rst ============================================================================== --- python/branches/py3k/Doc/library/curses.rst (original) +++ python/branches/py3k/Doc/library/curses.rst Fri Apr 10 11:03:43 2009 @@ -531,7 +531,7 @@ capability, or is canceled or absent from the terminal description. -.. function:: tparm(str[,...]) +.. function:: tparm(str[, ...]) Instantiates the string *str* with the supplied parameters, where *str* should be a parameterized string obtained from the terminfo database. E.g. Modified: python/branches/py3k/Doc/library/datetime.rst ============================================================================== --- python/branches/py3k/Doc/library/datetime.rst (original) +++ python/branches/py3k/Doc/library/datetime.rst Fri Apr 10 11:03:43 2009 @@ -128,7 +128,7 @@ dates or times. -.. class:: timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]]) +.. class:: timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0) All arguments are optional and default to ``0``. Arguments may be integers or floats, and may be positive or negative. @@ -570,7 +570,7 @@ Constructor: -.. class:: datetime(year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]) +.. class:: datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None) The year, month and day arguments are required. *tzinfo* may be ``None``, or an instance of a :class:`tzinfo` subclass. The remaining arguments may be integers, @@ -596,7 +596,7 @@ :meth:`fromtimestamp`. -.. method:: datetime.now([tz]) +.. method:: datetime.now(tz=None) Return the current local date and time. If optional argument *tz* is ``None`` or not specified, this is like :meth:`today`, but, if possible, supplies more @@ -617,7 +617,7 @@ :class:`datetime` object. See also :meth:`now`. -.. method:: datetime.fromtimestamp(timestamp[, tz]) +.. method:: datetime.fromtimestamp(timestamp, tz=None) Return the local date and time corresponding to the POSIX timestamp, such as is returned by :func:`time.time`. If optional argument *tz* is ``None`` or not @@ -947,7 +947,7 @@ ``self.date().isocalendar()``. -.. method:: datetime.isoformat([sep]) +.. method:: datetime.isoformat(sep='T') Return a string representing the date and time in ISO 8601 format, YYYY-MM-DDTHH:MM:SS.mmmmmm or, if :attr:`microsecond` is 0, @@ -1101,7 +1101,7 @@ day, and subject to adjustment via a :class:`tzinfo` object. -.. class:: time(hour[, minute[, second[, microsecond[, tzinfo]]]]) +.. class:: time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None) All arguments are optional. *tzinfo* may be ``None``, or an instance of a :class:`tzinfo` subclass. The remaining arguments may be integers, in the Modified: python/branches/py3k/Doc/library/dbm.rst ============================================================================== --- python/branches/py3k/Doc/library/dbm.rst (original) +++ python/branches/py3k/Doc/library/dbm.rst Fri Apr 10 11:03:43 2009 @@ -30,7 +30,7 @@ name, such as ``'dbm.ndbm'`` or ``'dbm.gnu'``. -.. function:: open(filename[, flag[, mode]]) +.. function:: open(filename, flag='r', mode=0o666) Open the database file *filename* and return a corresponding object. @@ -121,7 +121,7 @@ raised for general mapping errors like specifying an incorrect key. -.. function:: open(filename, [flag, [mode]]) +.. function:: open(filename[, flag[, mode]]) Open a ``gdbm`` database and return a :class:`gdbm` object. The *filename* argument is the name of the database file. Modified: python/branches/py3k/Doc/library/decimal.rst ============================================================================== --- python/branches/py3k/Doc/library/decimal.rst (original) +++ python/branches/py3k/Doc/library/decimal.rst Fri Apr 10 11:03:43 2009 @@ -305,7 +305,7 @@ --------------- -.. class:: Decimal([value [, context]]) +.. class:: Decimal(value="0", context=None) Construct a new :class:`Decimal` object based from *value*. Modified: python/branches/py3k/Doc/library/difflib.rst ============================================================================== --- python/branches/py3k/Doc/library/difflib.rst (original) +++ python/branches/py3k/Doc/library/difflib.rst Fri Apr 10 11:03:43 2009 @@ -72,7 +72,7 @@ The constructor for this class is: - .. function:: __init__([tabsize][, wrapcolumn][, linejunk][, charjunk]) + .. method:: __init__(tabsize=8, wrapcolumn=None, linejunk=None, charjunk=IS_CHARACTER_JUNK) Initializes instance of :class:`HtmlDiff`. @@ -88,8 +88,7 @@ The following methods are public: - - .. function:: make_file(fromlines, tolines [, fromdesc][, todesc][, context][, numlines]) + .. method:: make_file(fromlines, tolines, fromdesc='', todesc='', context=False, numlines=5) Compares *fromlines* and *tolines* (lists of strings) and returns a string which is a complete HTML file containing a table showing line by line differences with @@ -108,8 +107,7 @@ the next difference highlight at the top of the browser without any leading context). - - .. function:: make_table(fromlines, tolines [, fromdesc][, todesc][, context][, numlines]) + .. method:: make_table(fromlines, tolines, fromdesc='', todesc='', context=False, numlines=5) Compares *fromlines* and *tolines* (lists of strings) and returns a string which is a complete HTML table showing line by line differences with inter-line and @@ -122,7 +120,7 @@ contains a good example of its use. -.. function:: context_diff(a, b[, fromfile][, tofile][, fromfiledate][, tofiledate][, n][, lineterm]) +.. function:: context_diff(a, b, fromfile='', tofile='', fromfiledate='', tofiledate='', n=3, lineterm='\\n') Compare *a* and *b* (lists of strings); return a delta (a :term:`generator` generating the delta lines) in context diff format. @@ -167,7 +165,7 @@ See :ref:`difflib-interface` for a more detailed example. -.. function:: get_close_matches(word, possibilities[, n][, cutoff]) +.. function:: get_close_matches(word, possibilities, n=3, cutoff=0.6) Return a list of the best "good enough" matches. *word* is a sequence for which close matches are desired (typically a string), and *possibilities* is a list of @@ -193,7 +191,7 @@ ['except'] -.. function:: ndiff(a, b[, linejunk][, charjunk]) +.. function:: ndiff(a, b, linejunk=None, charjunk=IS_CHARACTER_JUNK) Compare *a* and *b* (lists of strings); return a :class:`Differ`\ -style delta (a :term:`generator` generating the delta lines). @@ -253,7 +251,7 @@ emu -.. function:: unified_diff(a, b[, fromfile][, tofile][, fromfiledate][, tofiledate][, n][, lineterm]) +.. function:: unified_diff(a, b, fromfile='', tofile='', fromfiledate='', tofiledate='', n=3, lineterm='\\n') Compare *a* and *b* (lists of strings); return a delta (a :term:`generator` generating the delta lines) in unified diff format. @@ -326,7 +324,7 @@ The :class:`SequenceMatcher` class has this constructor: -.. class:: SequenceMatcher([isjunk[, a[, b]]]) +.. class:: SequenceMatcher(isjunk=None, a='', b='') Optional argument *isjunk* must be ``None`` (the default) or a one-argument function that takes a sequence element and returns true if and only if the @@ -467,7 +465,7 @@ insert a[6:6] () b[5:6] (f) - .. method:: get_grouped_opcodes([n]) + .. method:: get_grouped_opcodes(n=3) Return a :term:`generator` of groups with up to *n* lines of context. @@ -580,7 +578,7 @@ The :class:`Differ` class has this constructor: -.. class:: Differ([linejunk[, charjunk]]) +.. class:: Differ(linejunk=None, charjunk=None) Optional keyword parameters *linejunk* and *charjunk* are for filter functions (or ``None``): Modified: python/branches/py3k/Doc/library/dis.rst ============================================================================== --- python/branches/py3k/Doc/library/dis.rst (original) +++ python/branches/py3k/Doc/library/dis.rst Fri Apr 10 11:03:43 2009 @@ -30,22 +30,23 @@ The :mod:`dis` module defines the following functions and constants: -.. function:: dis([bytesource]) +.. function:: dis(x=None) - Disassemble the *bytesource* object. *bytesource* can denote either a module, a + Disassemble the *x* object. *x* can denote either a module, a class, a method, a function, or a code object. For a module, it disassembles all functions. For a class, it disassembles all methods. For a single code sequence, it prints one line per bytecode instruction. If no object is provided, it disassembles the last traceback. -.. function:: distb([tb]) +.. function:: distb(tb=None) Disassembles the top-of-stack function of a traceback, using the last traceback if none was passed. The instruction causing the exception is indicated. -.. function:: disassemble(code[, lasti]) +.. function:: disassemble(code, lasti=-1) + disco(code, lasti=-1) Disassembles a code object, indicating the last instruction if *lasti* was provided. The output is divided in the following columns: @@ -62,12 +63,6 @@ constant values, branch targets, and compare operators. -.. function:: disco(code[, lasti]) - - A synonym for :func:`disassemble`. It is more convenient to type, and kept - for compatibility with earlier Python releases. - - .. function:: findlinestarts(code) This generator function uses the ``co_firstlineno`` and ``co_lnotab`` Modified: python/branches/py3k/Doc/library/doctest.rst ============================================================================== --- python/branches/py3k/Doc/library/doctest.rst (original) +++ python/branches/py3k/Doc/library/doctest.rst Fri Apr 10 11:03:43 2009 @@ -753,7 +753,7 @@ and :ref:`doctest-simple-testfile`. -.. function:: testfile(filename[, module_relative][, name][, package][, globs][, verbose][, report][, optionflags][, extraglobs][, raise_on_error][, parser][, encoding]) +.. function:: testfile(filename, module_relative=True, name=None, package=None, globs=None, verbose=None, report=True, optionflags=0, extraglobs=None, raise_on_error=False, parser=DocTestParser(), encoding=None) All arguments except *filename* are optional, and should be specified in keyword form. @@ -822,7 +822,7 @@ convert the file to unicode. -.. function:: testmod([m][, name][, globs][, verbose][, report][, optionflags][, extraglobs][, raise_on_error][, exclude_empty]) +.. function:: testmod(m=None, name=None, globs=None, verbose=None, report=True, optionflags=0, extraglobs=None, raise_on_error=False, exclude_empty=False) All arguments are optional, and all except for *m* should be specified in keyword form. @@ -860,7 +860,7 @@ deprecate it, but it's rarely useful: -.. function:: run_docstring_examples(f, globs[, verbose][, name][, compileflags][, optionflags]) +.. function:: run_docstring_examples(f, globs, verbose=False, name="NoName", compileflags=None, optionflags=0) Test examples associated with object *f*; for example, *f* may be a module, function, or class object. @@ -905,7 +905,7 @@ from text files and modules with doctests: -.. function:: DocFileSuite(*paths, [module_relative][, package][, setUp][, tearDown][, globs][, optionflags][, parser][, encoding]) +.. function:: DocFileSuite(*paths, module_relative=True, package=None, setUp=None, tearDown=None, globs=None, optionflags=0, parser=DocTestParser(), encoding=None) Convert doctest tests from one or more text files to a :class:`unittest.TestSuite`. @@ -972,7 +972,7 @@ from a text file using :func:`DocFileSuite`. -.. function:: DocTestSuite([module][, globs][, extraglobs][, test_finder][, setUp][, tearDown][, checker]) +.. function:: DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None, setUp=None, tearDown=None, checker=None) Convert doctest tests for a module to a :class:`unittest.TestSuite`. @@ -1158,7 +1158,7 @@ ^^^^^^^^^^^^^^^ -.. class:: Example(source, want[, exc_msg][, lineno][, indent][, options]) +.. class:: Example(source, want, exc_msg=None, lineno=0, indent=0, options=None) A single interactive example, consisting of a Python statement and its expected output. The constructor arguments are used to initialize the member variables @@ -1220,7 +1220,7 @@ ^^^^^^^^^^^^^^^^^^^^^ -.. class:: DocTestFinder([verbose][, parser][, recurse][, exclude_empty]) +.. class:: DocTestFinder(verbose=False, parser=DocTestParser(), recurse=True, exclude_empty=True) A processing class used to extract the :class:`DocTest`\ s that are relevant to a given object, from its docstring and the docstrings of its contained objects. @@ -1306,14 +1306,14 @@ information. - .. method:: get_examples(string[, name]) + .. method:: get_examples(string, name='') Extract all doctest examples from the given string, and return them as a list of :class:`Example` objects. Line numbers are 0-based. The optional argument *name* is a name identifying this string, and is only used for error messages. - .. method:: parse(string[, name]) + .. method:: parse(string, name='') Divide the given string into examples and intervening text, and return them as a list of alternating :class:`Example`\ s and strings. Line numbers for the @@ -1327,7 +1327,7 @@ ^^^^^^^^^^^^^^^^^^^^^ -.. class:: DocTestRunner([checker][, verbose][, optionflags]) +.. class:: DocTestRunner(checker=None, verbose=None, optionflags=0) A processing class used to execute and verify the interactive examples in a :class:`DocTest`. @@ -1409,7 +1409,7 @@ output function that was passed to :meth:`DocTestRunner.run`. - .. method:: run(test[, compileflags][, out][, clear_globs]) + .. method:: run(test, compileflags=None, out=None, clear_globs=True) Run the examples in *test* (a :class:`DocTest` object), and display the results using the writer function *out*. @@ -1428,7 +1428,7 @@ :meth:`DocTestRunner.report_\*` methods. - .. method:: summarize([verbose]) + .. method:: summarize(verbose=None) Print a summary of all the test cases that have been run by this DocTestRunner, and return a :term:`named tuple` ``TestResults(failed, attempted)``. @@ -1592,7 +1592,7 @@ converted to code, and the rest placed in comments. -.. function:: debug(module, name[, pm]) +.. function:: debug(module, name, pm=False) Debug the doctests for an object. @@ -1613,7 +1613,7 @@ passing an appropriate :func:`exec` call to :func:`pdb.run`. -.. function:: debug_src(src[, pm][, globs]) +.. function:: debug_src(src, pm=False, globs=None) Debug the doctests in a string. @@ -1633,7 +1633,7 @@ doctest!) for more details: -.. class:: DebugRunner([checker][, verbose][, optionflags]) +.. class:: DebugRunner(checker=None, verbose=None, optionflags=0) A subclass of :class:`DocTestRunner` that raises an exception as soon as a failure is encountered. If an unexpected exception occurs, an From buildbot at python.org Fri Apr 10 13:51:28 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 10 Apr 2009 11:51:28 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090410115128.985081E401B@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/511 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 249, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 102, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Fri Apr 10 14:38:09 2009 From: python-checkins at python.org (matthias.klose) Date: Fri, 10 Apr 2009 14:38:09 +0200 (CEST) Subject: [Python-checkins] r71447 - in python/branches/release26-maint: Lib/pydoc.py Message-ID: <20090410123809.E93941E4193@bag.python.org> Author: matthias.klose Date: Fri Apr 10 14:38:09 2009 New Revision: 71447 Log: Merged revisions 71443 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71443 | georg.brandl | 2009-04-10 10:20:23 +0200 (Fr, 10 Apr 2009) | 1 line #5698: Fix casing of !DOCTYPE to conform to W3C specs. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/pydoc.py Modified: python/branches/release26-maint/Lib/pydoc.py ============================================================================== --- python/branches/release26-maint/Lib/pydoc.py (original) +++ python/branches/release26-maint/Lib/pydoc.py Fri Apr 10 14:38:09 2009 @@ -422,7 +422,7 @@ def page(self, title, contents): """Format an HTML page.""" return ''' - + Python: %s %s From python-checkins at python.org Fri Apr 10 15:16:50 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 10 Apr 2009 15:16:50 +0200 (CEST) Subject: [Python-checkins] r71448 - python/trunk/Doc/library/itertools.rst Message-ID: <20090410131650.967471E401B@bag.python.org> Author: raymond.hettinger Date: Fri Apr 10 15:16:50 2009 New Revision: 71448 Log: Add examples. Modified: python/trunk/Doc/library/itertools.rst Modified: python/trunk/Doc/library/itertools.rst ============================================================================== --- python/trunk/Doc/library/itertools.rst (original) +++ python/trunk/Doc/library/itertools.rst Fri Apr 10 15:16:50 2009 @@ -36,49 +36,49 @@ **Infinite Iterators:** - ================== ================= ================================================= - Iterator Arguments Results - ================== ================= ================================================= - :func:`count` start, [step] start, start+step, start+2*step, ... - :func:`cycle` p p0, p1, ... plast, p0, p1, ... - :func:`repeat` elem [,n] elem, elem, elem, ... endlessly or up to n times - ================== ================= ================================================= +================== ================= ================================================= ========================================= +Iterator Arguments Results Example +================== ================= ================================================= ========================================= +:func:`count` start, [step] start, start+step, start+2*step, ... ``count(10) --> 10 11 12 13 14 ...`` +:func:`cycle` p p0, p1, ... plast, p0, p1, ... ``cycle('ABCD') --> A B C D A B C D ...`` +:func:`repeat` elem [,n] elem, elem, elem, ... endlessly or up to n times ``repeat(10, 3) --> 10 10 10`` +================== ================= ================================================= ========================================= **Iterators terminating on the shortest input sequence:** - ==================== ============================ ================================================= - Iterator Arguments Results - ==================== ============================ ================================================= - :func:`chain` p, q, ... p0, p1, ... plast, q0, q1, ... - :func:`compress` data, selectors (d[0] if s[0]), (d[1] if s[1]), ... - :func:`dropwhile` pred, seq seq[n], seq[n+1], starting when pred fails - :func:`groupby` iterable[, keyfunc] sub-iterators grouped by value of keyfunc(v) - :func:`ifilter` pred, seq elements of seq where pred(elem) is True - :func:`ifilterfalse` pred, seq elements of seq where pred(elem) is False - :func:`islice` seq, [start,] stop [, step] elements from seq[start:stop:step] - :func:`imap` func, p, q, ... func(p0, q0), func(p1, q1), ... - :func:`starmap` func, seq func(\*seq[0]), func(\*seq[1]), ... - :func:`tee` it, n it1, it2 , ... itn splits one iterator into n - :func:`takewhile` pred, seq seq[0], seq[1], until pred fails - :func:`izip` p, q, ... (p[0], q[0]), (p[1], q[1]), ... - :func:`izip_longest` p, q, ... (p[0], q[0]), (p[1], q[1]), ... - ==================== ============================ ================================================= +==================== ============================ ================================================= ============================================================= +Iterator Arguments Results Example +==================== ============================ ================================================= ============================================================= +: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`` +:func:`groupby` iterable[, keyfunc] sub-iterators grouped by value of keyfunc(v) +:func:`ifilter` pred, seq elements of seq where pred(elem) is True ``ifilter(lambda x: x%2, range(10)) --> 1 3 5 7 9`` +:func:`ifilterfalse` pred, seq elements of seq where pred(elem) is False ``ifilterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8`` +:func:`islice` seq, [start,] stop [, step] elements from seq[start:stop:step] ``islice('ABCDEFG', 2, None) --> C D E F G`` +:func:`imap` func, p, q, ... func(p0, q0), func(p1, q1), ... ``imap(pow, (2,3,10), (5,2,3)) --> 32 9 1000`` +:func:`starmap` func, seq func(\*seq[0]), func(\*seq[1]), ... ``starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000`` +:func:`tee` it, n it1, it2 , ... itn splits one iterator into n +:func:`takewhile` pred, seq seq[0], seq[1], until pred fails ``takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4`` +:func:`izip` p, q, ... (p[0], q[0]), (p[1], q[1]), ... ``izip('ABCD', 'xy') --> Ax By`` +:func:`izip_longest` p, q, ... (p[0], q[0]), (p[1], q[1]), ... ``izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-`` +==================== ============================ ================================================= ============================================================= **Combinatoric generators:** - ============================================== ==================== ============================================================= - Iterator Arguments Results - ============================================== ==================== ============================================================= - :func:`product` p, q, ... [repeat=1] cartesian product, equivalent to a nested for-loop - :func:`permutations` p[, r] r-length tuples, all possible orderings, no repeated elements - :func:`combinations` p[, r] r-length tuples, in sorted order, no repeated elements - :func:`combinations_with_replacement` p[, r] r-length tuples, in sorted order, with repeated elements - | - ``product('ABCD', repeat=2)`` ``AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD`` - ``permutations('ABCD', 2)`` ``AB AC AD BA BC BD CA CB CD DA DB DC`` - ``combinations('ABCD', 2)`` ``AB AC AD BC BD CD`` - ``combinations_with_replacement('ABCD', 2)`` ``AA AB AC AD BB BC BD CC CD DD`` - ============================================== ==================== ============================================================= +============================================== ==================== ============================================================= +Iterator Arguments Results +============================================== ==================== ============================================================= +:func:`product` p, q, ... [repeat=1] cartesian product, equivalent to a nested for-loop +:func:`permutations` p[, r] r-length tuples, all possible orderings, no repeated elements +:func:`combinations` p[, r] r-length tuples, in sorted order, no repeated elements +:func:`combinations_with_replacement` p[, r] r-length tuples, in sorted order, with repeated elements +| +``product('ABCD', repeat=2)`` ``AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD`` +``permutations('ABCD', 2)`` ``AB AC AD BA BC BD CA CB CD DA DB DC`` +``combinations('ABCD', 2)`` ``AB AC AD BC BD CD`` +``combinations_with_replacement('ABCD', 2)`` ``AA AB AC AD BB BC BD CC CD DD`` +============================================== ==================== ============================================================= .. _itertools-functions: @@ -641,43 +641,6 @@ .. versionadded:: 2.4 -.. _itertools-example: - -Examples --------- - -The following examples show common uses for each tool and demonstrate ways they -can be combined. - -.. doctest:: - - >>> # Show a dictionary sorted and grouped by value - >>> from operator import itemgetter - >>> d = dict(a=1, b=2, c=1, d=2, e=1, f=2, g=3) - >>> di = sorted(d.iteritems(), key=itemgetter(1)) - >>> for k, g in groupby(di, key=itemgetter(1)): - ... print k, map(itemgetter(0), g) - ... - 1 ['a', 'c', 'e'] - 2 ['b', 'd', 'f'] - 3 ['g'] - - >>> # Find runs of consecutive numbers using groupby. The key to the solution - >>> # is differencing with a range so that consecutive numbers all appear in - >>> # same group. - >>> data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28] - >>> for k, g in groupby(enumerate(data), lambda (i,x):i-x): - ... print map(itemgetter(1), g) - ... - [1] - [4, 5, 6] - [10] - [15, 16, 17, 18] - [22] - [25, 26, 27, 28] - - - .. _itertools-recipes: Recipes From python-checkins at python.org Fri Apr 10 20:52:25 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 10 Apr 2009 20:52:25 +0200 (CEST) Subject: [Python-checkins] r71449 - python/branches/release26-maint/Doc/library/itertools.rst Message-ID: <20090410185225.2CE011E4021@bag.python.org> Author: raymond.hettinger Date: Fri Apr 10 20:52:23 2009 New Revision: 71449 Log: Add examples. Modified: python/branches/release26-maint/Doc/library/itertools.rst Modified: python/branches/release26-maint/Doc/library/itertools.rst ============================================================================== --- python/branches/release26-maint/Doc/library/itertools.rst (original) +++ python/branches/release26-maint/Doc/library/itertools.rst Fri Apr 10 20:52:23 2009 @@ -36,32 +36,32 @@ **Infinite Iterators:** - ================== ================= ================================================= - Iterator Arguments Results - ================== ================= ================================================= - :func:`count` start start, start+1, start+2, ... - :func:`cycle` p p0, p1, ... plast, p0, p1, ... - :func:`repeat` elem [,n] elem, elem, elem, ... endlessly or up to n times - ================== ================= ================================================= +================== ================= ================================================= ========================================= +Iterator Arguments Results Example +================== ================= ================================================= ========================================= +:func:`count` start, [step] start, start+step, start+2*step, ... ``count(10) --> 10 11 12 13 14 ...`` +:func:`cycle` p p0, p1, ... plast, p0, p1, ... ``cycle('ABCD') --> A B C D A B C D ...`` +:func:`repeat` elem [,n] elem, elem, elem, ... endlessly or up to n times ``repeat(10, 3) --> 10 10 10`` +================== ================= ================================================= ========================================= **Iterators terminating on the shortest input sequence:** - ==================== ============================ ================================================= - Iterator Arguments Results - ==================== ============================ ================================================= - :func:`chain` p, q, ... p0, p1, ... plast, q0, q1, ... - :func:`dropwhile` pred, seq seq[n], seq[n+1], starting when pred fails - :func:`groupby` iterable[, keyfunc] sub-iterators grouped by value of keyfunc(v) - :func:`ifilter` pred, seq elements of seq where pred(elem) is True - :func:`ifilterfalse` pred, seq elements of seq where pred(elem) is False - :func:`islice` seq, [start,] stop [, step] elements from seq[start:stop:step] - :func:`imap` func, p, q, ... func(p0, q0), func(p1, q1), ... - :func:`starmap` func, seq func(\*seq[0]), func(\*seq[1]), ... - :func:`tee` it, n it1, it2 , ... itn splits one iterator into n - :func:`takewhile` pred, seq seq[0], seq[1], until pred fails - :func:`izip` p, q, ... (p[0], q[0]), (p[1], q[1]), ... - :func:`izip_longest` p, q, ... (p[0], q[0]), (p[1], q[1]), ... - ==================== ============================ ================================================= +==================== ============================ ================================================= ============================================================= +Iterator Arguments Results Example +==================== ============================ ================================================= ============================================================= +:func:`chain` p, q, ... p0, p1, ... plast, q0, q1, ... ``chain('ABC', 'DEF') --> A B C D 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`` +:func:`groupby` iterable[, keyfunc] sub-iterators grouped by value of keyfunc(v) +:func:`ifilter` pred, seq elements of seq where pred(elem) is True ``ifilter(lambda x: x%2, range(10)) --> 1 3 5 7 9`` +:func:`ifilterfalse` pred, seq elements of seq where pred(elem) is False ``ifilterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8`` +:func:`islice` seq, [start,] stop [, step] elements from seq[start:stop:step] ``islice('ABCDEFG', 2, None) --> C D E F G`` +:func:`imap` func, p, q, ... func(p0, q0), func(p1, q1), ... ``imap(pow, (2,3,10), (5,2,3)) --> 32 9 1000`` +:func:`starmap` func, seq func(\*seq[0]), func(\*seq[1]), ... ``starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000`` +:func:`tee` it, n it1, it2 , ... itn splits one iterator into n +:func:`takewhile` pred, seq seq[0], seq[1], until pred fails ``takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4`` +:func:`izip` p, q, ... (p[0], q[0]), (p[1], q[1]), ... ``izip('ABCD', 'xy') --> Ax By`` +:func:`izip_longest` p, q, ... (p[0], q[0]), (p[1], q[1]), ... ``izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-`` +==================== ============================ ================================================= ============================================================= **Combinatoric generators:** From python-checkins at python.org Fri Apr 10 20:58:59 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 10 Apr 2009 20:58:59 +0200 (CEST) Subject: [Python-checkins] r71450 - python/branches/release26-maint/Doc/library/itertools.rst Message-ID: <20090410185859.394401E4002@bag.python.org> Author: raymond.hettinger Date: Fri Apr 10 20:58:58 2009 New Revision: 71450 Log: No start argument Modified: python/branches/release26-maint/Doc/library/itertools.rst Modified: python/branches/release26-maint/Doc/library/itertools.rst ============================================================================== --- python/branches/release26-maint/Doc/library/itertools.rst (original) +++ python/branches/release26-maint/Doc/library/itertools.rst Fri Apr 10 20:58:58 2009 @@ -39,7 +39,7 @@ ================== ================= ================================================= ========================================= Iterator Arguments Results Example ================== ================= ================================================= ========================================= -:func:`count` start, [step] start, start+step, start+2*step, ... ``count(10) --> 10 11 12 13 14 ...`` +:func:`count` start start, start+1, start+2, ... ``count(10) --> 10 11 12 13 14 ...`` :func:`cycle` p p0, p1, ... plast, p0, p1, ... ``cycle('ABCD') --> A B C D A B C D ...`` :func:`repeat` elem [,n] elem, elem, elem, ... endlessly or up to n times ``repeat(10, 3) --> 10 10 10`` ================== ================= ================================================= ========================================= From python-checkins at python.org Fri Apr 10 21:02:41 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 10 Apr 2009 21:02:41 +0200 (CEST) Subject: [Python-checkins] r71451 - python/branches/py3k/Doc/library/itertools.rst Message-ID: <20090410190241.E11A71E4021@bag.python.org> Author: raymond.hettinger Date: Fri Apr 10 21:02:36 2009 New Revision: 71451 Log: Add examples. 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 Fri Apr 10 21:02:36 2009 @@ -34,30 +34,30 @@ **Infinite Iterators:** - ================== ================= ================================================= - Iterator Arguments Results - ================== ================= ================================================= - :func:`count` start, [step] start, start+step, start+2*step, ... - :func:`cycle` p p0, p1, ... plast, p0, p1, ... - :func:`repeat` elem [,n] elem, elem, elem, ... endlessly or up to n times - ================== ================= ================================================= +================== ================= ================================================= ========================================= +Iterator Arguments Results Example +================== ================= ================================================= ========================================= +:func:`count` start, [step] start, start+step, start+2*step, ... ``count(10) --> 10 11 12 13 14 ...`` +:func:`cycle` p p0, p1, ... plast, p0, p1, ... ``cycle('ABCD') --> A B C D A B C D ...`` +:func:`repeat` elem [,n] elem, elem, elem, ... endlessly or up to n times ``repeat(10, 3) --> 10 10 10`` +================== ================= ================================================= ========================================= **Iterators terminating on the shortest input sequence:** - ==================== ============================ ================================================= - Iterator Arguments Results - ==================== ============================ ================================================= - :func:`chain` p, q, ... p0, p1, ... plast, q0, q1, ... - :func:`compress` data, selectors (d[0] if s[0]), (d[1] if s[1]), ... - :func:`dropwhile` pred, seq seq[n], seq[n+1], starting when pred fails - :func:`filterfalse` pred, seq elements of seq where pred(elem) is False - :func:`groupby` iterable[, keyfunc] sub-iterators grouped by value of keyfunc(v) - :func:`islice` seq, [start,] stop [, step] elements from seq[start:stop:step] - :func:`starmap` func, seq func(\*seq[0]), func(\*seq[1]), ... - :func:`tee` it, n it1, it2 , ... itn splits one iterator into n - :func:`takewhile` pred, seq seq[0], seq[1], until pred fails - :func:`zip_longest` p, q, ... (p[0], q[0]), (p[1], q[1]), ... - ==================== ============================ ================================================= +==================== ============================ ================================================= ============================================================= +Iterator Arguments Results Example +==================== ============================ ================================================= ============================================================= +: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`` +:func:`filterfalse` pred, seq elements of seq where pred(elem) is False ``ifilterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8`` +:func:`groupby` iterable[, keyfunc] sub-iterators grouped by value of keyfunc(v) +:func:`islice` seq, [start,] stop [, step] elements from seq[start:stop:step] ``islice('ABCDEFG', 2, None) --> C D E F G`` +:func:`starmap` func, seq func(\*seq[0]), func(\*seq[1]), ... ``starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000`` +:func:`takewhile` pred, seq seq[0], seq[1], until pred fails ``takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4`` +:func:`tee` it, n it1, it2 , ... itn splits one iterator into n +:func:`zip_longest` p, q, ... (p[0], q[0]), (p[1], q[1]), ... ``izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-`` +==================== ============================ ================================================= ============================================================= **Combinatoric generators:** @@ -555,43 +555,6 @@ *fillvalue* defaults to ``None``. -.. _itertools-example: - -Examples --------- - -The following examples show common uses for each tool and demonstrate ways they -can be combined. - -.. doctest:: - - >>> # Show a dictionary sorted and grouped by value - >>> from operator import itemgetter - >>> d = dict(a=1, b=2, c=1, d=2, e=1, f=2, g=3) - >>> di = sorted(d.items(), key=itemgetter(1)) - >>> for k, g in groupby(di, key=itemgetter(1)): - ... print(k, map(itemgetter(0), g)) - ... - 1 ['a', 'c', 'e'] - 2 ['b', 'd', 'f'] - 3 ['g'] - - >>> # Find runs of consecutive numbers using groupby. The key to the solution - >>> # is differencing with a range so that consecutive numbers all appear in - >>> # same group. - >>> data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28] - >>> for k, g in groupby(enumerate(data), lambda t:t[0]-t[1]): - ... print(map(operator.itemgetter(1), g)) - ... - [1] - [4, 5, 6] - [10] - [15, 16, 17, 18] - [22] - [25, 26, 27, 28] - - - .. _itertools-recipes: Recipes From python-checkins at python.org Fri Apr 10 21:08:08 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 10 Apr 2009 21:08:08 +0200 (CEST) Subject: [Python-checkins] r71452 - python/branches/release30-maint/Doc/library/itertools.rst Message-ID: <20090410190808.43D801E4002@bag.python.org> Author: raymond.hettinger Date: Fri Apr 10 21:08:06 2009 New Revision: 71452 Log: Add examples. Modified: python/branches/release30-maint/Doc/library/itertools.rst Modified: python/branches/release30-maint/Doc/library/itertools.rst ============================================================================== --- python/branches/release30-maint/Doc/library/itertools.rst (original) +++ python/branches/release30-maint/Doc/library/itertools.rst Fri Apr 10 21:08:06 2009 @@ -34,29 +34,29 @@ **Infinite Iterators:** - ================== ================= ================================================= - Iterator Arguments Results - ================== ================= ================================================= - :func:`count` start start, start+1, start+2*1, ... - :func:`cycle` p p0, p1, ... plast, p0, p1, ... - :func:`repeat` elem [,n] elem, elem, elem, ... endlessly or up to n times - ================== ================= ================================================= +================== ================= ================================================= ========================================= +Iterator Arguments Results Example +================== ================= ================================================= ========================================= +:func:`count` start start, start+1, start+2, .... ``count(10) --> 10 11 12 13 14 ...`` +:func:`cycle` p p0, p1, ... plast, p0, p1, ... ``cycle('ABCD') --> A B C D A B C D ...`` +:func:`repeat` elem [,n] elem, elem, elem, ... endlessly or up to n times ``repeat(10, 3) --> 10 10 10`` +================== ================= ================================================= ========================================= **Iterators terminating on the shortest input sequence:** - ==================== ============================ ================================================= - Iterator Arguments Results - ==================== ============================ ================================================= - :func:`chain` p, q, ... p0, p1, ... plast, q0, q1, ... - :func:`dropwhile` pred, seq seq[n], seq[n+1], starting when pred fails - :func:`filterfalse` pred, seq elements of seq where pred(elem) is False - :func:`groupby` iterable[, keyfunc] sub-iterators grouped by value of keyfunc(v) - :func:`islice` seq, [start,] stop [, step] elements from seq[start:stop:step] - :func:`starmap` func, seq func(\*seq[0]), func(\*seq[1]), ... - :func:`tee` it, n it1, it2 , ... itn splits one iterator into n - :func:`takewhile` pred, seq seq[0], seq[1], until pred fails - :func:`zip_longest` p, q, ... (p[0], q[0]), (p[1], q[1]), ... - ==================== ============================ ================================================= +==================== ============================ ================================================= ============================================================= +Iterator Arguments Results Example +==================== ============================ ================================================= ============================================================= +:func:`chain` p, q, ... p0, p1, ... plast, q0, q1, ... ``chain('ABC', 'DEF') --> A B C D 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`` +:func:`filterfalse` pred, seq elements of seq where pred(elem) is False ``ifilterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8`` +:func:`groupby` iterable[, keyfunc] sub-iterators grouped by value of keyfunc(v) +:func:`islice` seq, [start,] stop [, step] elements from seq[start:stop:step] ``islice('ABCDEFG', 2, None) --> C D E F G`` +:func:`starmap` func, seq func(\*seq[0]), func(\*seq[1]), ... ``starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000`` +:func:`takewhile` pred, seq seq[0], seq[1], until pred fails ``takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4`` +:func:`tee` it, n it1, it2 , ... itn splits one iterator into n +:func:`zip_longest` p, q, ... (p[0], q[0]), (p[1], q[1]), ... ``izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-`` +==================== ============================ ================================================= ============================================================= **Combinatoric generators:** @@ -488,43 +488,6 @@ *fillvalue* defaults to ``None``. -.. _itertools-example: - -Examples --------- - -The following examples show common uses for each tool and demonstrate ways they -can be combined. - -.. doctest:: - - >>> # Show a dictionary sorted and grouped by value - >>> from operator import itemgetter - >>> d = dict(a=1, b=2, c=1, d=2, e=1, f=2, g=3) - >>> di = sorted(d.items(), key=itemgetter(1)) - >>> for k, g in groupby(di, key=itemgetter(1)): - ... print(k, map(itemgetter(0), g)) - ... - 1 ['a', 'c', 'e'] - 2 ['b', 'd', 'f'] - 3 ['g'] - - >>> # Find runs of consecutive numbers using groupby. The key to the solution - >>> # is differencing with a range so that consecutive numbers all appear in - >>> # same group. - >>> data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28] - >>> for k, g in groupby(enumerate(data), lambda t:t[0]-t[1]): - ... print(map(operator.itemgetter(1), g)) - ... - [1] - [4, 5, 6] - [10] - [15, 16, 17, 18] - [22] - [25, 26, 27, 28] - - - .. _itertools-recipes: Recipes From python-checkins at python.org Fri Apr 10 21:13:25 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 10 Apr 2009 21:13:25 +0200 (CEST) Subject: [Python-checkins] r71453 - python/branches/release30-maint/Doc/make.bat Message-ID: <20090410191325.17AC41E4034@bag.python.org> Author: raymond.hettinger Date: Fri Apr 10 21:13:23 2009 New Revision: 71453 Log: Sync-up make.bat with Makefile. Modified: python/branches/release30-maint/Doc/make.bat Modified: python/branches/release30-maint/Doc/make.bat ============================================================================== --- python/branches/release30-maint/Doc/make.bat (original) +++ python/branches/release30-maint/Doc/make.bat Fri Apr 10 21:13:23 2009 @@ -33,7 +33,7 @@ goto end :checkout -svn co %SVNROOT%/doctools/trunk/sphinx tools/sphinx +svn co %SVNROOT%/external/Sphinx-0.6.1/sphinx tools/sphinx svn co %SVNROOT%/external/docutils-0.5/docutils tools/docutils svn co %SVNROOT%/external/Jinja-2.1.1/jinja2 tools/jinja2 svn co %SVNROOT%/external/Pygments-0.11.1/pygments tools/pygments From python-checkins at python.org Fri Apr 10 21:43:53 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 10 Apr 2009 21:43:53 +0200 (CEST) Subject: [Python-checkins] r71454 - python/branches/py3k/Doc/library/itertools.rst Message-ID: <20090410194353.75EB71E4015@bag.python.org> Author: raymond.hettinger Date: Fri Apr 10 21:43:50 2009 New Revision: 71454 Log: Fix alignment 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 Fri Apr 10 21:43:50 2009 @@ -61,19 +61,19 @@ **Combinatoric generators:** - ============================================== ==================== ============================================================= - Iterator Arguments Results - ============================================== ==================== ============================================================= - :func:`product` p, q, ... [repeat=1] cartesian product, equivalent to a nested for-loop - :func:`permutations` p[, r] r-length tuples, all possible orderings, no repeated elements - :func:`combinations` p[, r] r-length tuples, in sorted order, no repeated elements - :func:`combinations_with_replacement` p[, r] r-length tuples, in sorted order, with repeated elements - | - ``product('ABCD', repeat=2)`` ``AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD`` - ``permutations('ABCD', 2)`` ``AB AC AD BA BC BD CA CB CD DA DB DC`` - ``combinations('ABCD', 2)`` ``AB AC AD BC BD CD`` - ``combinations_with_replacement('ABCD', 2)`` ``AA AB AC AD BB BC BD CC CD DD`` - ============================================== ==================== ============================================================= +============================================== ==================== ============================================================= +Iterator Arguments Results +============================================== ==================== ============================================================= +:func:`product` p, q, ... [repeat=1] cartesian product, equivalent to a nested for-loop +:func:`permutations` p[, r] r-length tuples, all possible orderings, no repeated elements +:func:`combinations` p[, r] r-length tuples, in sorted order, no repeated elements +:func:`combinations_with_replacement` p[, r] r-length tuples, in sorted order, with repeated elements +| +``product('ABCD', repeat=2)`` ``AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD`` +``permutations('ABCD', 2)`` ``AB AC AD BA BC BD CA CB CD DA DB DC`` +``combinations('ABCD', 2)`` ``AB AC AD BC BD CD`` +``combinations_with_replacement('ABCD', 2)`` ``AA AB AC AD BB BC BD CC CD DD`` +============================================== ==================== ============================================================= .. _itertools-functions: From python-checkins at python.org Fri Apr 10 21:45:01 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 10 Apr 2009 21:45:01 +0200 (CEST) Subject: [Python-checkins] r71455 - python/branches/release30-maint/Doc/library/itertools.rst Message-ID: <20090410194501.9ACA51E4015@bag.python.org> Author: raymond.hettinger Date: Fri Apr 10 21:44:58 2009 New Revision: 71455 Log: Fix alignment Modified: python/branches/release30-maint/Doc/library/itertools.rst Modified: python/branches/release30-maint/Doc/library/itertools.rst ============================================================================== --- python/branches/release30-maint/Doc/library/itertools.rst (original) +++ python/branches/release30-maint/Doc/library/itertools.rst Fri Apr 10 21:44:58 2009 @@ -60,17 +60,17 @@ **Combinatoric generators:** - ============================================== ==================== ============================================================= - Iterator Arguments Results - ============================================== ==================== ============================================================= - :func:`product` p, q, ... [repeat=1] cartesian product, equivalent to a nested for-loop - :func:`permutations` p[, r] r-length tuples, all possible orderings, no repeated elements - :func:`combinations` p[, r] r-length tuples, in sorted order, no repeated elements - | - ``product('ABCD', repeat=2)`` ``AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD`` - ``permutations('ABCD', 2)`` ``AB AC AD BA BC BD CA CB CD DA DB DC`` - ``combinations('ABCD', 2)`` ``AB AC AD BC BD CD`` - ============================================== ==================== ============================================================= +============================================== ==================== ============================================================= +Iterator Arguments Results +============================================== ==================== ============================================================= +:func:`product` p, q, ... [repeat=1] cartesian product, equivalent to a nested for-loop +:func:`permutations` p[, r] r-length tuples, all possible orderings, no repeated elements +:func:`combinations` p[, r] r-length tuples, in sorted order, no repeated elements +| +``product('ABCD', repeat=2)`` ``AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD`` +``permutations('ABCD', 2)`` ``AB AC AD BA BC BD CA CB CD DA DB DC`` +``combinations('ABCD', 2)`` ``AB AC AD BC BD CD`` +============================================== ==================== ============================================================= .. _itertools-functions: From python-checkins at python.org Fri Apr 10 21:46:52 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 10 Apr 2009 21:46:52 +0200 (CEST) Subject: [Python-checkins] r71456 - python/branches/release26-maint/Doc/library/itertools.rst Message-ID: <20090410194652.D30CC1E4015@bag.python.org> Author: raymond.hettinger Date: Fri Apr 10 21:46:51 2009 New Revision: 71456 Log: Fix alignment Modified: python/branches/release26-maint/Doc/library/itertools.rst Modified: python/branches/release26-maint/Doc/library/itertools.rst ============================================================================== --- python/branches/release26-maint/Doc/library/itertools.rst (original) +++ python/branches/release26-maint/Doc/library/itertools.rst Fri Apr 10 21:46:51 2009 @@ -65,17 +65,17 @@ **Combinatoric generators:** - ============================================== ==================== ============================================================= - Iterator Arguments Results - ============================================== ==================== ============================================================= - :func:`product` p, q, ... [repeat=1] cartesian product, equivalent to a nested for-loop - :func:`permutations` p[, r] r-length tuples, all possible orderings, no repeated elements - :func:`combinations` p[, r] r-length tuples, in sorted order, no repeated elements - | - ``product('ABCD', repeat=2)`` ``AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD`` - ``permutations('ABCD', 2)`` ``AB AC AD BA BC BD CA CB CD DA DB DC`` - ``combinations('ABCD', 2)`` ``AB AC AD BC BD CD`` - ============================================== ==================== ============================================================= +============================================== ==================== ============================================================= +Iterator Arguments Results +============================================== ==================== ============================================================= +:func:`product` p, q, ... [repeat=1] cartesian product, equivalent to a nested for-loop +:func:`permutations` p[, r] r-length tuples, all possible orderings, no repeated elements +:func:`combinations` p[, r] r-length tuples, in sorted order, no repeated elements +| +``product('ABCD', repeat=2)`` ``AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD`` +``permutations('ABCD', 2)`` ``AB AC AD BA BC BD CA CB CD DA DB DC`` +``combinations('ABCD', 2)`` ``AB AC AD BC BD CD`` +============================================== ==================== ============================================================= .. _itertools-functions: From python-checkins at python.org Sat Apr 11 00:19:09 2009 From: python-checkins at python.org (guilherme.polo) Date: Sat, 11 Apr 2009 00:19:09 +0200 (CEST) Subject: [Python-checkins] r71457 - in python/branches/py3k: Modules/_tkinter.c Modules/tkinter.h Message-ID: <20090410221909.63C6A1E4015@bag.python.org> Author: guilherme.polo Date: Sat Apr 11 00:19:09 2009 New Revision: 71457 Log: Merged revisions 71210 via svnmerge from svn+ssh://pythondev/python/trunk ........ r71210 | guilherme.polo | 2009-04-04 23:11:19 -0300 (Sat, 04 Apr 2009) | 1 line Include tkinter.h only after including tk.h (or the equivalent for another platform). ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Modules/_tkinter.c python/branches/py3k/Modules/tkinter.h Modified: python/branches/py3k/Modules/_tkinter.c ============================================================================== --- python/branches/py3k/Modules/_tkinter.c (original) +++ python/branches/py3k/Modules/_tkinter.c Sat Apr 11 00:19:09 2009 @@ -33,8 +33,6 @@ #include #endif -#include "tkinter.h" - /* Allow using this code in Python 2.[12] */ #ifndef PyDoc_STRVAR #define PyDoc_STRVAR(name,str) static char name[] = str @@ -69,6 +67,8 @@ #include #endif +#include "tkinter.h" + /* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */ #ifndef CONST84_RETURN #define CONST84_RETURN Modified: python/branches/py3k/Modules/tkinter.h ============================================================================== --- python/branches/py3k/Modules/tkinter.h (original) +++ python/branches/py3k/Modules/tkinter.h Sat Apr 11 00:19:09 2009 @@ -2,7 +2,9 @@ #define TKINTER_H /* This header is used to share some macros between _tkinter.c and - * tkappinit.c */ + * tkappinit.c. + * Be sure to include tk.h before including this header so + * TK_VERSION_HEX is properly defined. */ /* TK_RELEASE_LEVEL is always one of the following: * TCL_ALPHA_RELEASE 0 From python-checkins at python.org Sat Apr 11 00:20:27 2009 From: python-checkins at python.org (guilherme.polo) Date: Sat, 11 Apr 2009 00:20:27 +0200 (CEST) Subject: [Python-checkins] r71458 - python/branches/release30-maint Message-ID: <20090410222027.452B81E4015@bag.python.org> Author: guilherme.polo Date: Sat Apr 11 00:20:27 2009 New Revision: 71458 Log: Blocked revisions 71457 via svnmerge ................ r71457 | guilherme.polo | 2009-04-10 19:19:09 -0300 (Fri, 10 Apr 2009) | 9 lines Merged revisions 71210 via svnmerge from svn+ssh://pythondev/python/trunk ........ r71210 | guilherme.polo | 2009-04-04 23:11:19 -0300 (Sat, 04 Apr 2009) | 1 line Include tkinter.h only after including tk.h (or the equivalent for another platform). ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sat Apr 11 00:21:35 2009 From: python-checkins at python.org (guilherme.polo) Date: Sat, 11 Apr 2009 00:21:35 +0200 (CEST) Subject: [Python-checkins] r71459 - python/branches/release26-maint Message-ID: <20090410222135.8B6401E4015@bag.python.org> Author: guilherme.polo Date: Sat Apr 11 00:21:35 2009 New Revision: 71459 Log: Blocked revisions 71210 via svnmerge ........ r71210 | guilherme.polo | 2009-04-04 23:11:19 -0300 (Sat, 04 Apr 2009) | 1 line Include tkinter.h only after including tk.h (or the equivalent for another platform). ........ Modified: python/branches/release26-maint/ (props changed) From buildbot at python.org Sat Apr 11 00:52:09 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 10 Apr 2009 22:52:09 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 2.6 Message-ID: <20090410225209.26F321E4015@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%202.6/builds/205 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: guilherme.polo,raymond.hettinger BUILD FAILED: failed test Excerpt from the test logfile: make: *** [buildbottest] Killed sincerely, -The Buildbot From buildbot at python.org Sat Apr 11 02:12:30 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 11 Apr 2009 00:12:30 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090411001230.66AF91E4014@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/260 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: guilherme.polo,raymond.hettinger BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_posix test_subprocess ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From python-checkins at python.org Sat Apr 11 07:44:20 2009 From: python-checkins at python.org (eric.smith) Date: Sat, 11 Apr 2009 07:44:20 +0200 (CEST) Subject: [Python-checkins] r71460 - in python/branches/py3k-short-float-repr: Include/bytesobject.h Include/unicodeobject.h Lib/test/test_types.py Objects/bytesobject.c Objects/stringlib/formatter.h Objects/stringlib/localeutil.h Python/pystrtod.c Message-ID: <20090411054420.2E9891E4010@bag.python.org> Author: eric.smith Date: Sat Apr 11 07:44:19 2009 New Revision: 71460 Log: Added locale-aware formatting back in, and added ',' formatting for ints and floats. Some bugs remain, but all existing tests pass. Once we're done with the merge to py3k (and the bug tracker is back up) I'll add test cases and fix bugs. Modified: python/branches/py3k-short-float-repr/Include/bytesobject.h python/branches/py3k-short-float-repr/Include/unicodeobject.h python/branches/py3k-short-float-repr/Lib/test/test_types.py python/branches/py3k-short-float-repr/Objects/bytesobject.c python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h python/branches/py3k-short-float-repr/Objects/stringlib/localeutil.h python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Include/bytesobject.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/bytesobject.h (original) +++ python/branches/py3k-short-float-repr/Include/bytesobject.h Sat Apr 11 07:44:19 2009 @@ -91,24 +91,22 @@ into the string pointed to by buffer. For the argument descriptions, see Objects/stringlib/localeutil.h */ -PyAPI_FUNC(int) _PyBytes_InsertThousandsGroupingLocale(char *buffer, - Py_ssize_t n_buffer, - Py_ssize_t n_digits, - Py_ssize_t buf_size, - Py_ssize_t *count, - int append_zero_char); +PyAPI_FUNC(Py_ssize_t) _PyBytes_InsertThousandsGroupingLocale(char *buffer, + Py_ssize_t n_buffer, + char *digits, + Py_ssize_t n_digits, + Py_ssize_t min_width); /* 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 */ -PyAPI_FUNC(int) _PyBytes_InsertThousandsGrouping(char *buffer, - Py_ssize_t n_buffer, - Py_ssize_t n_digits, - Py_ssize_t buf_size, - Py_ssize_t *count, - int append_zero_char, - const char *grouping, - const char *thousands_sep); +PyAPI_FUNC(Py_ssize_t) _PyBytes_InsertThousandsGrouping(char *buffer, + Py_ssize_t n_buffer, + char *digits, + Py_ssize_t n_digits, + Py_ssize_t min_width, + const char *grouping, + const char *thousands_sep); /* Flags used by string formatting */ #define F_LJUST (1<<0) Modified: python/branches/py3k-short-float-repr/Include/unicodeobject.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/unicodeobject.h (original) +++ python/branches/py3k-short-float-repr/Include/unicodeobject.h Sat Apr 11 07:44:19 2009 @@ -1482,24 +1482,22 @@ into the string pointed to by buffer. For the argument descriptions, see Objects/stringlib/localeutil.h */ -PyAPI_FUNC(int) _PyUnicode_InsertThousandsGroupingLocale(Py_UNICODE *buffer, - Py_ssize_t n_buffer, - Py_ssize_t n_digits, - Py_ssize_t buf_size, - Py_ssize_t *count, - int append_zero_char); +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); /* 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 */ -PyAPI_FUNC(int) _PyUnicode_InsertThousandsGrouping(Py_UNICODE *buffer, - Py_ssize_t n_buffer, - Py_ssize_t n_digits, - Py_ssize_t buf_size, - Py_ssize_t *count, - int append_zero_char, - const char *grouping, - const char *thousands_sep); +PyAPI_FUNC(Py_ssize_t) _PyUnicode_InsertThousandsGrouping(Py_UNICODE *buffer, + Py_ssize_t n_buffer, + Py_UNICODE *digits, + Py_ssize_t n_digits, + Py_ssize_t min_width, + const char *grouping, + const char *thousands_sep); /* === Characters Type APIs =============================================== */ /* Helper array used by Py_UNICODE_ISSPACE(). */ Modified: python/branches/py3k-short-float-repr/Lib/test/test_types.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_types.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_types.py Sat Apr 11 07:44:19 2009 @@ -361,6 +361,8 @@ self.assertRaises(TypeError, 3 .__format__, 0) # can't have ',' with 'n' self.assertRaises(ValueError, 3 .__format__, ",n") + # can't have ',' with 'c' + self.assertRaises(ValueError, 3 .__format__, ",c") # ensure that only int and float type specifiers work for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] + @@ -467,16 +469,14 @@ self.assertEqual(value.__format__(format_spec), float(value).__format__(format_spec)) - # XXX: needs to be put back in when 'n' formatting is complete - # after the py3k-short-float-repr merge -# @run_with_locale('LC_NUMERIC', 'en_US.UTF8') -# def test_float__format__locale(self): -# # test locale support for __format__ code 'n' -# -# for i in range(-10, 10): -# x = 1234567890.0 * (10.0 ** i) -# self.assertEqual(locale.format('%g', x, grouping=True), format(x, 'n')) -# self.assertEqual(locale.format('%.10g', x, grouping=True), format(x, '.10n')) + @run_with_locale('LC_NUMERIC', 'en_US.UTF8') + def test_float__format__locale(self): + # test locale support for __format__ code 'n' + + for i in range(-10, 10): + x = 1234567890.0 * (10.0 ** i) + self.assertEqual(locale.format('%g', x, grouping=True), format(x, 'n')) + self.assertEqual(locale.format('%.10g', x, grouping=True), format(x, '.10n')) @run_with_locale('LC_NUMERIC', 'en_US.UTF8') def test_int__format__locale(self): @@ -552,9 +552,7 @@ # a totaly empty format specifier means something else. # So, just use a sign flag test(1e200, '+g', '+1e+200') - - # XXX this is a change from 3.0. Needs to be vetted. -# test(1e200, '+', '+1.0e+200') + test(1e200, '+', '+1e+200') test(1.1e200, '+g', '+1.1e+200') test(1.1e200, '+', '+1.1e+200') Modified: python/branches/py3k-short-float-repr/Objects/bytesobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/bytesobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/bytesobject.c Sat Apr 11 07:44:19 2009 @@ -562,6 +562,7 @@ /* -------------------------------------------------------------------- */ /* Methods */ +#include "stringlib/stringdefs.h" #define STRINGLIB_CHAR char #define STRINGLIB_CMP memcmp Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h (original) +++ python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Sat Apr 11 07:44:19 2009 @@ -230,6 +230,7 @@ ++ptr; } + /* XXX other types like xobXOB also invalid */ if (format->type == 'n' && format->thousands_separators) { PyErr_Format(PyExc_ValueError, "Cannot specify ',' with 'n'."); return 0; @@ -243,6 +244,25 @@ /*********** common routines for numeric formatting *********************/ /************************************************************************/ +/* Locale type codes. */ +#define LT_USE_LOCALE 0 +#define LT_DEFAULT_LOCALE 1 +#define LT_NO_LOCALE 2 + +/* Locale info needed for formatting integers and the part of floats + before and including the decimal. Note that locales only support + 8-bit chars, not unicode. */ +typedef struct { + int type; /* One of the LT_* codes. Having this here is just + an optimization for the common case of not + using any locale info (LT_NO_LOCALE). It could + really be inferred just by looking at the + following fields.*/ + char *decimal_point; + char *thousands_sep; + char *grouping; +} LocaleInfo; + /* describes the layout for an integer, see the comment in calc_number_widths() for details */ typedef struct { @@ -251,31 +271,79 @@ Py_ssize_t n_spadding; Py_ssize_t n_rpadding; char sign; - Py_ssize_t n_sign; + Py_ssize_t n_sign; /* number of digits needed for sign (0/1) */ + Py_ssize_t n_grouped_digits; /* Space taken up by the digits, including + any grouping chars. */ + Py_ssize_t n_decimal; /* 0 if only an integer */ + Py_ssize_t n_remainder; /* digits in decimal and/or exponent part, + excluding the decimal itself, if present */ Py_ssize_t n_total; /* just a convenience, it's derivable from the other fields */ + + Py_ssize_t n_digits; /* The number of digits before a decimal or + exponent. */ + Py_ssize_t n_min_width; /* The min_width we used when we computed + the n_grouped_digits width. */ } NumberFieldWidths; +/* Given a number of the form: + digits[remainder] + where ptr points to the start and end points to the end, find where + the integer part ends. This could be a decimal, an exponent, both, + or neither. + If a decimal point is present, set *has_decimal and increment + remainder beyond it. + Results are undefined (but shouldn't crash) for improperly + formatted strings. +*/ +static void +parse_number(STRINGLIB_CHAR *ptr, Py_ssize_t len, + Py_ssize_t *n_remainder, int *has_decimal) +{ + STRINGLIB_CHAR *end = ptr + len; + STRINGLIB_CHAR *remainder; + + while (ptrn_digits = n_number - n_remainder - (has_decimal?1:0); spec->n_lpadding = 0; - spec->n_prefix = 0; + spec->n_prefix = n_prefix; + spec->n_decimal = has_decimal ? strlen(locale->decimal_point) : 0; + spec->n_remainder = n_remainder; spec->n_spadding = 0; spec->n_rpadding = 0; spec->sign = '\0'; spec->n_sign = 0; /* the output will look like: - | | - | | - | | + | | + | | + | | sign is computed from format->sign and the actual sign of the number @@ -295,29 +363,49 @@ if (format->sign == '+') { /* always put a + or - */ spec->n_sign = 1; - spec->sign = (actual_sign == '-' ? '-' : '+'); + spec->sign = (sign_char == '-' ? '-' : '+'); } else if (format->sign == ' ') { spec->n_sign = 1; - spec->sign = (actual_sign == '-' ? '-' : ' '); + spec->sign = (sign_char == '-' ? '-' : ' '); } else { /* non specified, or the default (-) */ - if (actual_sign == '-') { + if (sign_char == '-') { spec->n_sign = 1; spec->sign = '-'; } } - spec->n_prefix = n_prefix; + /* The number of chars used for non-digit and non-padding. */ + n_non_digit_non_padding = spec->n_sign + spec->n_prefix + spec->n_decimal + + spec->n_remainder; + + /* min_width can go negative, that's okay. format->width == -1 means + we don't care. */ + if (format->fill_char == '0') + spec->n_min_width = format->width - n_non_digit_non_padding; + else + spec->n_min_width = 0; + + if (spec->n_digits == 0) + /* This case only occurs when using 'c' formatting, we need + to special case it because the grouping code always wants + to have at least one character. */ + spec->n_grouped_digits = 0; + else + spec->n_grouped_digits = STRINGLIB_GROUPING(NULL, 0, NULL, + spec->n_digits, + spec->n_min_width, + locale->grouping, + locale->thousands_sep); - /* now the number of padding characters */ if (format->width == -1) { /* no padding at all, nothing to do */ } else { /* see if any padding is needed */ - if (spec->n_sign + n_digits + + if (spec->n_sign + spec->n_grouped_digits + spec->n_prefix >= format->width) { /* no padding needed, we're already bigger than the requested width */ @@ -326,8 +414,7 @@ /* determine which of left, space, or right padding is needed */ Py_ssize_t padding = format->width - - (spec->n_sign + spec->n_prefix + - n_digits); + (spec->n_sign + spec->n_grouped_digits + n_prefix); if (format->align == '<') spec->n_rpadding = padding; else if (format->align == '>') @@ -343,117 +430,123 @@ } } spec->n_total = spec->n_lpadding + spec->n_sign + spec->n_prefix + - spec->n_spadding + n_digits + spec->n_rpadding; + spec->n_spadding + spec->n_grouped_digits + spec->n_decimal + + spec->n_remainder + spec->n_rpadding; } /* Fill in the digit parts of a numbers's string representation, - as determined in calc_number_widths(). */ + as determined in calc_number_widths(). + No error checking, since we know the buffer is the correct size. */ static void -fill_digits(STRINGLIB_CHAR *p_buf, const NumberFieldWidths *spec, - STRINGLIB_CHAR *p_digits, Py_ssize_t n_digits) -{ - memmove(p_buf + - (spec->n_lpadding + spec->n_sign + spec->n_spadding), - p_digits, - n_digits * sizeof(STRINGLIB_CHAR)); -} - -/* fill in the non-digit parts of a numbers's string representation, - as determined in calc_number_widths(). returns the pointer to - where the digits go. */ -static STRINGLIB_CHAR * -fill_non_digits(STRINGLIB_CHAR *p_buf, const NumberFieldWidths *spec, - STRINGLIB_CHAR *prefix, Py_ssize_t n_digits, - STRINGLIB_CHAR fill_char) +fill_number(STRINGLIB_CHAR *buf, const NumberFieldWidths *spec, + STRINGLIB_CHAR *digits, Py_ssize_t n_digits, + STRINGLIB_CHAR *prefix, STRINGLIB_CHAR fill_char, + LocaleInfo *locale, int toupper) { - STRINGLIB_CHAR *p_digits; + /* Used to keep track of digits, decimal, and remainder. */ + STRINGLIB_CHAR *p = digits; + +#ifndef NDEBUG + Py_ssize_t r; +#endif if (spec->n_lpadding) { - STRINGLIB_FILL(p_buf, fill_char, spec->n_lpadding); - p_buf += spec->n_lpadding; + STRINGLIB_FILL(buf, fill_char, spec->n_lpadding); + buf += spec->n_lpadding; } if (spec->n_sign == 1) { - *p_buf++ = spec->sign; + *buf++ = spec->sign; } if (spec->n_prefix) { - memmove(p_buf, + memmove(buf, prefix, spec->n_prefix * sizeof(STRINGLIB_CHAR)); - p_buf += spec->n_prefix; + if (toupper) { + Py_ssize_t t; + for (t = 0; t < spec->n_prefix; ++t) + buf[t] = STRINGLIB_TOUPPER(buf[t]); + } + buf += spec->n_prefix; } if (spec->n_spadding) { - STRINGLIB_FILL(p_buf, fill_char, spec->n_spadding); - p_buf += spec->n_spadding; + STRINGLIB_FILL(buf, fill_char, spec->n_spadding); + buf += spec->n_spadding; } - p_digits = p_buf; - p_buf += n_digits; + + /* Only for type 'c' special case, it has no digits. */ + if (spec->n_digits != 0) { + /* Fill the digits with InsertThousandsGrouping. */ +#ifndef NDEBUG + r = +#endif + STRINGLIB_GROUPING(buf, spec->n_grouped_digits, digits, + spec->n_digits, spec->n_min_width, + locale->grouping, locale->thousands_sep); +#ifndef NDEBUG + assert(r == spec->n_grouped_digits); +#endif + p += spec->n_digits; + } + if (toupper) { + Py_ssize_t t; + for (t = 0; t < spec->n_grouped_digits; ++t) + buf[t] = STRINGLIB_TOUPPER(buf[t]); + } + buf += spec->n_grouped_digits; + + if (spec->n_decimal) { + Py_ssize_t t; + for (t = 0; t < spec->n_decimal; ++t) + buf[t] = locale->decimal_point[t]; + buf += spec->n_decimal; + p += 1; + } + + if (spec->n_remainder) { + memcpy(buf, p, spec->n_remainder * sizeof(STRINGLIB_CHAR)); + buf += spec->n_remainder; + p += spec->n_remainder; + } + if (spec->n_rpadding) { - STRINGLIB_FILL(p_buf, fill_char, spec->n_rpadding); - p_buf += spec->n_rpadding; + STRINGLIB_FILL(buf, fill_char, spec->n_rpadding); + buf += spec->n_rpadding; } - return p_digits; } +static char no_grouping[1] = {CHAR_MAX}; + /* Find the decimal point character(s?), thousands_separator(s?), and - grouping description, either for the current locale if use_locale - is GFI_USE_LOCALE, a hard-coded locale if GFI_DEFAULT, or none if - GFI_NONE */ -#define GFI_USE_LOCALE 0 -#define GFI_DEFAULT_LOCALE 1 -#define GFI_NO_LOCALE 2 + grouping description, either for the current locale if type is + LT_USE_LOCALE, a hard-coded locale if LT_DEFAULT_LOCALE, or none if + LT_NO_LOCALE. */ static void -get_formatting_info(int locale, char **decimal_point, char **thousands_sep, - char **grouping) +get_locale_info(int type, LocaleInfo *locale_info) { - if (locale == GFI_USE_LOCALE) { + locale_info->type = type; + switch (type) { + case LT_USE_LOCALE: { struct lconv *locale_data = localeconv(); - *decimal_point = locale_data->decimal_point; - *thousands_sep = locale_data->thousands_sep; - *grouping = locale_data->grouping; - } else if (locale == GFI_DEFAULT_LOCALE) { - *decimal_point = "."; - *thousands_sep = ","; - *grouping = "\3"; /* every 3 characters, trailing 0 means repeat */ - } else { - *decimal_point = "."; - *thousands_sep = ""; - *grouping = ""; + locale_info->decimal_point = locale_data->decimal_point; + locale_info->thousands_sep = locale_data->thousands_sep; + locale_info->grouping = locale_data->grouping; + break; + } + case LT_DEFAULT_LOCALE: + locale_info->decimal_point = "."; + locale_info->thousands_sep = ","; + locale_info->grouping = "\3"; /* every 3 characters, trailing 0 means repeat */ + break; + case LT_NO_LOCALE: + locale_info->decimal_point = "."; + locale_info->thousands_sep = ""; + locale_info->grouping = no_grouping; + break; + default: + assert(0); } } -/* Given a number of the form: - [+-]digits[rest] - where ptr points to the start and end points to the end, parse - the number into its integer part and then everything else (which - could be a decimal, an exponent, both, or neither. - This is compatible with the format returned from - PyOS_double_to_string(). - Results are undefined (but shouldn't crash) for improperly - formatted strings. - Consider moving this to pystrtod.c -*/ -static void -find_number_parts(STRINGLIB_CHAR *ptr, Py_ssize_t len, - STRINGLIB_CHAR **sign, - STRINGLIB_CHAR **integer_start, - STRINGLIB_CHAR **rest_start, - int *has_decimal) -{ - STRINGLIB_CHAR *end = ptr + len; - - if (ptrprecision != -1) { PyErr_SetString(PyExc_ValueError, @@ -602,6 +697,14 @@ goto done; } + /* Error to specify a comma. */ + if (format->thousands_separators) { + PyErr_SetString(PyExc_ValueError, + "Thousands separators not allowed with integer" + " format specifier 'c'"); + goto done; + } + /* taken from unicodeobject.c formatchar() */ /* Integer input truncated to a character */ /* XXX: won't work for int */ @@ -626,6 +729,13 @@ numeric_char = (STRINGLIB_CHAR)x; pnumeric_chars = &numeric_char; n_digits = 1; + + /* As a sort-of hack, we tell calc_number_widths that we only + have "remainder" characters. calc_number_widths thinks + these are characters that don't get formatted, only copied + into the output string. We do this for 'c' formatting, + because the characters are likely to be non-digits. */ + n_remainder = 1; } else { int base; @@ -677,8 +787,8 @@ /* Is a sign character present in the output? If so, remember it and skip it */ - sign = pnumeric_chars[0]; - if (sign == '-') { + if (pnumeric_chars[0] == '-') { + sign_char = pnumeric_chars[0]; ++prefix; ++leading_chars_to_skip; } @@ -688,20 +798,15 @@ pnumeric_chars += leading_chars_to_skip; } - if (format->type == 'n') - /* Compute how many additional chars we need to allocate - to hold the thousands grouping. */ - STRINGLIB_GROUPING_LOCALE(NULL, n_digits, n_digits, - 0, &n_grouping_chars, 0); - if (format->thousands_separators) - /* Compute how many additional chars we need to allocate - to hold the thousands grouping. */ - STRINGLIB_GROUPING(NULL, n_digits, n_digits, - 0, &n_grouping_chars, 0, "\3", ","); + /* Determine the grouping, separator, and decimal point, if any. */ + get_locale_info(format->type == 'n' ? LT_USE_LOCALE : + (format->thousands_separators ? LT_DEFAULT_LOCALE : + LT_NO_LOCALE), + &locale); /* Calculate the widths of the various leading and trailing parts */ - calc_number_widths(&spec, sign, n_prefix, n_digits + n_grouping_chars, - 0, 0, format); + calc_number_widths(&spec, n_prefix, sign_char, pnumeric_chars, + n_digits, n_remainder, 0, &locale, format); /* Allocate a new string to hold the result */ result = STRINGLIB_NEW(NULL, spec.n_total); @@ -709,65 +814,9 @@ goto done; p = STRINGLIB_STR(result); - /* XXX There is too much magic here regarding the internals of - spec and the location of the prefix and digits. It would be - better if calc_number_widths returned a number of logical - offsets into the buffer, and those were used. Maybe in a - future code cleanup. */ - - /* Fill in the digit parts */ - n_leading_chars = spec.n_lpadding + spec.n_sign + - spec.n_prefix + spec.n_spadding; - memmove(p + n_leading_chars, - pnumeric_chars, - n_digits * sizeof(STRINGLIB_CHAR)); - - /* If type is 'X', convert the filled in digits to uppercase */ - if (format->type == 'X') { - Py_ssize_t t; - for (t = 0; t < n_digits; ++t) - p[t + n_leading_chars] = STRINGLIB_TOUPPER(p[t + n_leading_chars]); - } - - /* Insert the grouping, if any, after the uppercasing of the digits, so - we can ensure that grouping chars won't be affected. */ - if (n_grouping_chars) { - /* We know this can't fail, since we've already - reserved enough space. */ - STRINGLIB_CHAR *pstart = p + n_leading_chars; -#ifndef NDEBUG - int r; -#endif - if (format->type == 'n') -#ifndef NDEBUG - r = -#endif - STRINGLIB_GROUPING_LOCALE(pstart, n_digits, n_digits, - spec.n_total+n_grouping_chars-n_leading_chars, - NULL, 0); - else -#ifndef NDEBUG - r = -#endif - STRINGLIB_GROUPING(pstart, n_digits, n_digits, - spec.n_total+n_grouping_chars-n_leading_chars, - NULL, 0, "\3", ","); - assert(r); - } - - /* Fill in the non-digit parts (padding, sign, etc.) */ - fill_non_digits(p, &spec, prefix, n_digits + n_grouping_chars, - format->fill_char == '\0' ? ' ' : format->fill_char); - - /* If type is 'X', uppercase the prefix. This has to be done after the - prefix is filled in by fill_non_digits */ - if (format->type == 'X') { - Py_ssize_t t; - for (t = 0; t < n_prefix; ++t) - p[t + spec.n_lpadding + spec.n_sign] = - STRINGLIB_TOUPPER(p[t + spec.n_lpadding + spec.n_sign]); - } - + fill_number(p, &spec, pnumeric_chars, n_digits, prefix, + format->fill_char == '\0' ? ' ' : format->fill_char, &locale, + format->type == 'X'); done: Py_XDECREF(tmp); @@ -797,33 +846,26 @@ { char *buf = NULL; /* buffer returned from PyOS_double_to_string */ Py_ssize_t n_digits; + Py_ssize_t n_remainder; + int has_decimal; double val; Py_ssize_t precision = format->precision; STRINGLIB_CHAR type = format->type; - STRINGLIB_CHAR sign_char = '\0'; int add_pct = 0; - int use_locale; STRINGLIB_CHAR *p; NumberFieldWidths spec; int flags = 0; PyObject *result = NULL; - - /* the various parts of the raw formatted number */ - STRINGLIB_CHAR *sign; - STRINGLIB_CHAR *integer_start; - STRINGLIB_CHAR *rest_start; - int has_decimal = 0; - - /* locale settings, either from the actual locale or - from a hard-code pseudo-locale */ - char *l_decimal_point; - char *l_thousands_sep; - char *l_grouping; + STRINGLIB_CHAR sign_char = '\0'; #if STRINGLIB_IS_UNICODE Py_UNICODE *unicode_tmp = NULL; #endif + /* Locale settings, either from the actual locale or + from a hard-code pseudo-locale */ + LocaleInfo locale; + /* alternate is not allowed on floats. */ if (format->alternate) { PyErr_SetString(PyExc_ValueError, @@ -838,20 +880,14 @@ type = 'g'; flags |= Py_DTSF_ADD_DOT_0; } - if (type == 'n') { + if (type == 'n') type = 'g'; - use_locale = GFI_USE_LOCALE; - } else if (format->thousands_separators) - use_locale = GFI_DEFAULT_LOCALE; - else - use_locale = GFI_NO_LOCALE; /* 'F' is the same as 'f', per the PEP */ if (type == 'F') type = 'f'; val = PyFloat_AsDouble(value); - if (val == -1.0 && PyErr_Occurred()) goto done; @@ -900,37 +936,37 @@ p = buf; #endif - find_number_parts(p, n_digits, - &sign, - &integer_start, - &rest_start, - &has_decimal); - - /* is a sign character present in the output? if so, remember it + /* Is a sign character present in the output? If so, remember it and skip it */ - if (sign) { - sign_char = *sign; + if (*p == '-') { + sign_char = *p; ++p; --n_digits; } /* Determine the grouping, separator, and decimal point, if any. */ - get_formatting_info(use_locale, &l_decimal_point, &l_thousands_sep, &l_grouping); + get_locale_info(type == 'n' ? LT_USE_LOCALE : + (format->thousands_separators ? LT_DEFAULT_LOCALE : + LT_NO_LOCALE), + &locale); + + /* Determine if we have any "remainder" (after the digits, might include + decimal or exponent or both (or neither)) */ + parse_number(p, n_digits, &n_remainder, &has_decimal); /* Calculate how much space we'll need. */ - calc_number_widths(&spec, sign_char, 0, n_digits, has_decimal, 0, format); + calc_number_widths(&spec, 0, sign_char, p, n_digits, n_remainder, + has_decimal, &locale, format); /* Allocate that space. */ result = STRINGLIB_NEW(NULL, spec.n_total); if (result == NULL) goto done; - /* Fill in the non-digit parts (padding, sign, etc.) */ - fill_non_digits(STRINGLIB_STR(result), &spec, NULL, n_digits, - format->fill_char == '\0' ? ' ' : format->fill_char); - - /* Fill in the digit parts. */ - fill_digits(STRINGLIB_STR(result), &spec, p, n_digits); + /* Populate the space. */ + fill_number(STRINGLIB_STR(result), &spec, p, n_digits, NULL, + format->fill_char == '\0' ? ' ' : format->fill_char, &locale, + 0); done: PyMem_Free(buf); Modified: python/branches/py3k-short-float-repr/Objects/stringlib/localeutil.h ============================================================================== --- python/branches/py3k-short-float-repr/Objects/stringlib/localeutil.h (original) +++ python/branches/py3k-short-float-repr/Objects/stringlib/localeutil.h Sat Apr 11 07:44:19 2009 @@ -5,161 +5,208 @@ #include +#define MAX(x, y) ((x) < (y) ? (y) : (x)) +#define MIN(x, y) ((x) < (y) ? (x) : (y)) + +typedef struct { + const char *grouping; + char previous; + Py_ssize_t i; /* Where we're currently pointing in grouping. */ +} GroupGenerator; + +static void +_GroupGenerator_init(GroupGenerator *self, const char *grouping) +{ + self->grouping = grouping; + self->i = 0; + self->previous = 0; +} + +/* Returns the next grouping, or 0 to signify end. */ +static Py_ssize_t +_GroupGenerator_next(GroupGenerator *self) +{ + /* Note that we don't really do much error checking here. If a + grouping string contains just CHAR_MAX, for example, then just + terminate the generator. That shouldn't happen, but at least we + fail gracefully. */ + switch (self->grouping[self->i]) { + case 0: + return self->previous; + case CHAR_MAX: + /* Stop the generator. */ + return 0; + default: { + char ch = self->grouping[self->i]; + self->previous = ch; + self->i++; + return (Py_ssize_t)ch; + } + } +} + +/* Fill in some digits, leading zeros, and thousands separator. All + are optional, depending on when we're called. */ +static void +fill(STRINGLIB_CHAR **digits_end, STRINGLIB_CHAR **buffer_end, + Py_ssize_t n_chars, Py_ssize_t n_zeros, const char* thousands_sep, + Py_ssize_t thousands_sep_len) +{ +#if STRINGLIB_IS_UNICODE + Py_ssize_t i; +#endif + + if (thousands_sep) { + *buffer_end -= thousands_sep_len; + + /* Copy the thousands_sep chars into the buffer. */ +#if STRINGLIB_IS_UNICODE + /* Convert from the char's of the thousands_sep from + the locale into unicode. */ + for (i = 0; i < thousands_sep_len; ++i) + (*buffer_end)[i] = thousands_sep[i]; +#else + /* No conversion, just memcpy the thousands_sep. */ + memcpy(*buffer_end, thousands_sep, thousands_sep_len); +#endif + } + + *buffer_end -= n_chars; + *digits_end -= n_chars; + memcpy(*buffer_end, *digits_end, n_chars * sizeof(STRINGLIB_CHAR)); + + *buffer_end -= n_zeros; + STRINGLIB_FILL(*buffer_end, '0', n_zeros); +} + /** * _Py_InsertThousandsGrouping: * @buffer: A pointer to the start of a string. - * @n_buffer: The length of the string. + * @n_buffer: Number of characters in @buffer. + * @digits: A pointer to the digits we're reading from. If count + * is non-NULL, this is unused. * @n_digits: The number of digits in the string, in which we want * to put the grouping chars. - * @buf_size: The maximum size of the buffer pointed to by buffer. - * @count: If non-NULL, points to a variable that will receive the - * number of characters we need to insert (and no formatting - * will actually occur). - * @append_zero_char: If non-zero, put a trailing zero at the end of - * of the resulting string, if and only if we modified the - * string. + * @min_width: The minimum width of the digits in the output string. + * Output will be zero-padded on the left to fill. * @grouping: see definition in localeconv(). * @thousands_sep: see definition in localeconv(). * + * There are 2 modes: counting and filling. If @buffer is NULL, + * we are in counting mode, else filling mode. + * If counting, the required buffer size is returned. + * If filling, we know the buffer will be large enough, so we don't + * need to pass in the buffer size. * Inserts thousand grouping characters (as defined by grouping and * thousands_sep) into the string between buffer and buffer+n_digits. - * If count is non-NULL, don't do any formatting, just count the - * number of characters to insert. This is used by the caller to - * appropriately resize the buffer, if needed. If count is non-NULL, - * buffer can be NULL (it is not dereferenced at all in that case). * * Return value: 0 on error, else 1. Note that no error can occur if * count is non-NULL. * * This name won't be used, the includer of this file should define * it to be the actual function name, based on unicode or string. + * + * As closely as possible, this code mimics the logic in decimal.py's + _insert_thousands_sep(). **/ -int +Py_ssize_t _Py_InsertThousandsGrouping(STRINGLIB_CHAR *buffer, Py_ssize_t n_buffer, + STRINGLIB_CHAR *digits, Py_ssize_t n_digits, - Py_ssize_t buf_size, - Py_ssize_t *count, - int append_zero_char, + Py_ssize_t min_width, const char *grouping, const char *thousands_sep) { - Py_ssize_t thousands_sep_len = strlen(thousands_sep); - STRINGLIB_CHAR *pend = NULL; /* current end of buffer */ - STRINGLIB_CHAR *pmax = NULL; /* max of buffer */ - char current_grouping; - Py_ssize_t remaining = n_digits; /* Number of chars remaining to - be looked at */ - - /* Initialize the character count, if we're just counting. */ - if (count) - *count = 0; - else { - /* We're not just counting, we're modifying buffer */ - pend = buffer + n_buffer; - pmax = buffer + buf_size; + Py_ssize_t count = 0; + Py_ssize_t n_zeros; + int loop_broken = 0; + int use_separator = 0; /* First time through, don't append the + separator. They only go between + groups. */ + STRINGLIB_CHAR *buffer_end = NULL; + STRINGLIB_CHAR *digits_end; + Py_ssize_t l; + Py_ssize_t n_chars; + Py_ssize_t thousands_sep_len = strlen(thousands_sep); + Py_ssize_t remaining = n_digits; /* Number of chars remaining to + be looked at */ + /* A generator that returns all of the grouping widths, until it + returns 0. */ + GroupGenerator groupgen; + _GroupGenerator_init(&groupgen, grouping); + + if (buffer) { + buffer_end = buffer + n_buffer; + digits_end = digits + n_digits; + } + + while ((l = _GroupGenerator_next(&groupgen)) > 0) { + l = MIN(l, MAX(MAX(remaining, min_width), 1)); + n_zeros = MAX(0, l - remaining); + n_chars = MAX(0, MIN(remaining, l)); + + /* Use n_zero zero's and n_chars chars */ + + /* Count only, don't do anything. */ + count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars; + + if (buffer) { + /* Copy into the output buffer. */ + fill(&digits_end, &buffer_end, n_chars, n_zeros, + use_separator ? thousands_sep : NULL, thousands_sep_len); } - /* Starting at the end and working right-to-left, keep track of - what grouping needs to be added and insert that. */ - current_grouping = *grouping++; - - /* If the first character is 0, perform no grouping at all. */ - if (current_grouping == 0) - return 1; - - while (remaining > current_grouping) { - /* Always leave buffer and pend valid at the end of this - loop, since we might leave with a return statement. */ - - remaining -= current_grouping; - if (count) { - /* We're only counting, not touching the memory. */ - *count += thousands_sep_len; - } - else { - /* Do the formatting. */ - - STRINGLIB_CHAR *plast = buffer + remaining; - - /* Is there room to insert thousands_sep_len chars? */ - if (pmax - pend < thousands_sep_len) - /* No room. */ - return 0; - - /* Move the rest of the string down. */ - memmove(plast + thousands_sep_len, - plast, - (pend - plast) * sizeof(STRINGLIB_CHAR)); - /* Copy the thousands_sep chars into the buffer. */ -#if STRINGLIB_IS_UNICODE - /* Convert from the char's of the thousands_sep from - the locale into unicode. */ - { - Py_ssize_t i; - for (i = 0; i < thousands_sep_len; ++i) - plast[i] = thousands_sep[i]; - } -#else - /* No conversion, just memcpy the thousands_sep. */ - memcpy(plast, thousands_sep, thousands_sep_len); -#endif - } + /* Use a separator next time. */ + use_separator = 1; - /* Adjust end pointer. */ - pend += thousands_sep_len; + remaining -= n_chars; + min_width -= l; - /* Move to the next grouping character, unless we're - repeating (which is designated by a grouping of 0). */ - if (*grouping != 0) { - current_grouping = *grouping++; - if (current_grouping == CHAR_MAX) - /* We're done. */ - break; - } + if (remaining <= 0 && min_width <= 0) { + loop_broken = 1; + break; } - if (append_zero_char) { - /* Append a zero character to mark the end of the string, - if there's room. */ - if (pend - (buffer + remaining) < 1) - /* No room, error. */ - return 0; - *pend = 0; + min_width -= thousands_sep_len; + } + if (!loop_broken) { + /* We left the loop without using a break statement. */ + + l = MAX(MAX(remaining, min_width), 1); + n_zeros = MAX(0, l - remaining); + n_chars = MAX(0, MIN(remaining, l)); + + /* Use n_zero zero's and n_chars chars */ + count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars; + if (buffer) { + /* Copy into the output buffer. */ + fill(&digits_end, &buffer_end, n_chars, n_zeros, + use_separator ? thousands_sep : NULL, thousands_sep_len); } - return 1; + } + return count; } /** * _Py_InsertThousandsGroupingLocale: * @buffer: A pointer to the start of a string. - * @n_buffer: The length of the string. * @n_digits: The number of digits in the string, in which we want * to put the grouping chars. - * @buf_size: The maximum size of the buffer pointed to by buffer. - * @count: If non-NULL, points to a variable that will receive the - * number of characters we need to insert (and no formatting - * will actually occur). - * @append_zero_char: If non-zero, put a trailing zero at the end of - * of the resulting string, if and only if we modified the - * string. * * Reads thee current locale and calls _Py_InsertThousandsGrouping(). **/ -int +Py_ssize_t _Py_InsertThousandsGroupingLocale(STRINGLIB_CHAR *buffer, Py_ssize_t n_buffer, + STRINGLIB_CHAR *digits, Py_ssize_t n_digits, - Py_ssize_t buf_size, - Py_ssize_t *count, - int append_zero_char) + Py_ssize_t min_width) { struct lconv *locale_data = localeconv(); const char *grouping = locale_data->grouping; const char *thousands_sep = locale_data->thousands_sep; - return _Py_InsertThousandsGrouping(buffer, n_buffer, n_digits, - buf_size, count, - append_zero_char, grouping, - thousands_sep); + return _Py_InsertThousandsGrouping(buffer, n_buffer, digits, n_digits, + min_width, grouping, thousands_sep); } #endif /* STRINGLIB_LOCALEUTIL_H */ Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Sat Apr 11 07:44:19 2009 @@ -357,6 +357,7 @@ Py_LOCAL_INLINE(int) add_thousands_grouping(char* buffer, size_t buf_size) { +#if 0 Py_ssize_t len = strlen(buffer); struct lconv *locale_data = localeconv(); const char *decimal_point = locale_data->decimal_point; @@ -379,7 +380,9 @@ want to format. We need to add the grouping string for the characters between buffer and p. */ return _PyBytes_InsertThousandsGroupingLocale(buffer, len, p-buffer, - buf_size, NULL, 1); + buf_size, NULL, 1, 1); +#endif + return 1; } /* see FORMATBUFLEN in unicodeobject.c */ From python-checkins at python.org Sat Apr 11 07:50:13 2009 From: python-checkins at python.org (eric.smith) Date: Sat, 11 Apr 2009 07:50:13 +0200 (CEST) Subject: [Python-checkins] r71461 - python/branches/py3k-short-float-repr/Lib/test/test_types.py Message-ID: <20090411055013.2BBD11E41E6@bag.python.org> Author: eric.smith Date: Sat Apr 11 07:50:12 2009 New Revision: 71461 Log: Some tests fail on Linux. Temporarily comment them out so as not to affect Mark. Modified: python/branches/py3k-short-float-repr/Lib/test/test_types.py Modified: python/branches/py3k-short-float-repr/Lib/test/test_types.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_types.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_types.py Sat Apr 11 07:50:12 2009 @@ -475,8 +475,8 @@ for i in range(-10, 10): x = 1234567890.0 * (10.0 ** i) - self.assertEqual(locale.format('%g', x, grouping=True), format(x, 'n')) - self.assertEqual(locale.format('%.10g', x, grouping=True), format(x, '.10n')) +# self.assertEqual(locale.format('%g', x, grouping=True), format(x, 'n')) +# self.assertEqual(locale.format('%.10g', x, grouping=True), format(x, '.10n')) @run_with_locale('LC_NUMERIC', 'en_US.UTF8') def test_int__format__locale(self): From python-checkins at python.org Sat Apr 11 13:22:19 2009 From: python-checkins at python.org (chris.withers) Date: Sat, 11 Apr 2009 13:22:19 +0200 (CEST) Subject: [Python-checkins] r71462 - python/trunk/Lib/socket.py Message-ID: <20090411112219.EA5111E401D@bag.python.org> Author: chris.withers Date: Sat Apr 11 13:22:19 2009 New Revision: 71462 Log: remove unpleasant exec Modified: python/trunk/Lib/socket.py Modified: python/trunk/Lib/socket.py ============================================================================== --- python/trunk/Lib/socket.py (original) +++ python/trunk/Lib/socket.py Sat Apr 11 13:22:19 2009 @@ -45,6 +45,8 @@ import _socket from _socket import * +from functools import partial +from new import instancemethod try: import _ssl @@ -213,11 +215,15 @@ type = property(lambda self: self._sock.type, doc="the socket type") proto = property(lambda self: self._sock.proto, doc="the socket protocol") - _s = ("def %s(self, *args): return self._sock.%s(*args)\n\n" - "%s.__doc__ = _realsocket.%s.__doc__\n") - for _m in _socketmethods: - exec _s % (_m, _m, _m, _m) - del _m, _s +def meth(name,self,*args): + return getattr(self._sock,name)(*args) + +for _m in _socketmethods: + p = partial(meth,_m) + p.__name__ = _m + p.__doc__ = getattr(_realsocket,_m).__doc__ + m = instancemethod(p,None,_socketobject) + setattr(_socketobject,_m,m) socket = SocketType = _socketobject From python-checkins at python.org Sat Apr 11 13:37:38 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 11 Apr 2009 13:37:38 +0200 (CEST) Subject: [Python-checkins] r71463 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090411113738.16A6A1E4169@bag.python.org> Author: mark.dickinson Date: Sat Apr 11 13:37:37 2009 New Revision: 71463 Log: line-length fixes Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Sat Apr 11 13:37:37 2009 @@ -804,7 +804,7 @@ break; case 'g': mode = 2; - /* precision of 0 makes no sense for 'g' format; interpret as 1 */ + /* precision 0 makes no sense for 'g' format; interpret as 1 */ if (precision == 0) precision = 1; break; @@ -830,6 +830,7 @@ return format_float_short(val, lc_format_code, mode, precision, flags & Py_DTSF_SIGN, - flags & Py_DTSF_ADD_DOT_0, flags & Py_DTSF_ALT, + flags & Py_DTSF_ADD_DOT_0, + flags & Py_DTSF_ALT, float_strings); } From python-checkins at python.org Sat Apr 11 13:40:02 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 11 Apr 2009 13:40:02 +0200 (CEST) Subject: [Python-checkins] r71464 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090411114002.DBF0F1E401D@bag.python.org> Author: mark.dickinson Date: Sat Apr 11 13:40:01 2009 New Revision: 71464 Log: We never add a sign for a NaN. Add comment to make it clear that this was a deliberate decision. Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Sat Apr 11 13:40:01 2009 @@ -594,6 +594,8 @@ p += 3; } else if (digits[0] == 'n' || digits[0] == 'N') { + /* note that we *never* add a sign for a nan, + even if one has explicitly been requested */ strncpy(p, float_strings[OFS_NAN], 3); p += 3; } From python-checkins at python.org Sat Apr 11 15:31:32 2009 From: python-checkins at python.org (nick.coghlan) Date: Sat, 11 Apr 2009 15:31:32 +0200 (CEST) Subject: [Python-checkins] r71465 - in python/trunk: Doc/library/test.rst Lib/test/test_heapq.py Lib/test/test_support.py Lib/test/test_warnings.py Message-ID: <20090411133132.143311E415B@bag.python.org> Author: nick.coghlan Date: Sat Apr 11 15:31:31 2009 New Revision: 71465 Log: Issue 5251: Provide a standardised testing mechanism for doing fresh imports of modules, including the ability to block extension modules in order to test the pure Python fallbacks Modified: python/trunk/Doc/library/test.rst python/trunk/Lib/test/test_heapq.py python/trunk/Lib/test/test_support.py python/trunk/Lib/test/test_warnings.py Modified: python/trunk/Doc/library/test.rst ============================================================================== --- python/trunk/Doc/library/test.rst (original) +++ python/trunk/Doc/library/test.rst Sat Apr 11 15:31:31 2009 @@ -339,6 +339,30 @@ .. versionadded:: 2.6 +.. function:: import_module(name, deprecated=False) + + This function imports and returns the named module. Unlike a normal + import, this function raises :exc:`unittest.SkipTest` if the module + cannot be imported. + + Module and package deprecation messages are suppressed during this import + if *deprecated* is :const:`True`. + + .. versionadded:: 2.7 + + +.. function:: import_fresh_module(name, blocked_names=None, deprecated=False) + + This function imports and returns a fresh copy of the named Python module. The + ``sys.modules`` cache is bypassed temporarily, and the ability to import the + modules named in *blocked_names* is suppressed for the duration of the import. + + Module and package deprecation messages are suppressed during this import + if *deprecated* is :const:`True`. + + .. versionadded:: 2.7 + + The :mod:`test.test_support` module defines the following classes: .. class:: TransientResource(exc[, **kwargs]) Modified: python/trunk/Lib/test/test_heapq.py ============================================================================== --- python/trunk/Lib/test/test_heapq.py (original) +++ python/trunk/Lib/test/test_heapq.py Sat Apr 11 15:31:31 2009 @@ -7,23 +7,8 @@ # We do a bit of trickery here to be able to test both the C implementation # and the Python implementation of the module. - -# Make it impossible to import the C implementation anymore. -sys.modules['_heapq'] = 0 -# We must also handle the case that heapq was imported before. -if 'heapq' in sys.modules: - del sys.modules['heapq'] - -# Now we can import the module and get the pure Python implementation. -import heapq as py_heapq - -# Restore everything to normal. -del sys.modules['_heapq'] -del sys.modules['heapq'] - -# This is now the module with the C implementation. import heapq as c_heapq - +py_heapq = test_support.import_fresh_module('heapq', ['_heapq']) class TestHeap(unittest.TestCase): module = None @@ -193,6 +178,13 @@ class TestHeapPython(TestHeap): module = py_heapq + # As an early adopter, we sanity check the + # test_support.import_fresh_module utility function + def test_pure_python(self): + self.assertFalse(sys.modules['heapq'] is self.module) + self.assertTrue(hasattr(self.module.heapify, 'func_code')) + + class TestHeapC(TestHeap): module = c_heapq @@ -217,6 +209,12 @@ self.assertEqual(hsort(data, LT), target) self.assertEqual(hsort(data, LE), target) + # As an early adopter, we sanity check the + # test_support.import_fresh_module utility function + def test_accelerated(self): + self.assertTrue(sys.modules['heapq'] is self.module) + self.assertFalse(hasattr(self.module.heapify, 'func_code')) + #============================================================================== Modified: python/trunk/Lib/test/test_support.py ============================================================================== --- python/trunk/Lib/test/test_support.py (original) +++ python/trunk/Lib/test/test_support.py Sat Apr 11 15:31:31 2009 @@ -42,22 +42,63 @@ and unexpected skips. """ + at contextlib.contextmanager +def _ignore_deprecated_imports(ignore=True): + """Context manager to suppress package and module deprecation + warnings when importing them. + + If ignore is False, this context manager has no effect.""" + if ignore: + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", ".+ (module|package)", + DeprecationWarning) + yield + else: + yield + + def import_module(name, deprecated=False): """Import and return the module to be tested, raising SkipTest if it is not available. If deprecated is True, any module or package deprecation messages will be suppressed.""" - with warnings.catch_warnings(): - if deprecated: - warnings.filterwarnings("ignore", ".+ (module|package)", - DeprecationWarning) + with _ignore_deprecated_imports(deprecated): try: - module = importlib.import_module(name) + return importlib.import_module(name) except ImportError, msg: raise unittest.SkipTest(str(msg)) - else: - return module + + +def import_fresh_module(name, blocked_names=None, deprecated=False): + """Imports and returns a module, deliberately bypassing the sys.modules cache + and importing a fresh copy of the module. Once the import is complete, + the sys.modules cache is restored to its original state. + + Importing of modules named in blocked_names is prevented while the fresh import + takes place. + + If deprecated is True, any module or package deprecation messages + will be suppressed.""" + # NOTE: test_heapq and test_warnings include extra sanity checks to make + # sure that this utility function is working as expected + with _ignore_deprecated_imports(deprecated): + if blocked_names is None: + blocked_names = () + orig_modules = {} + if name in sys.modules: + orig_modules[name] = sys.modules[name] + del sys.modules[name] + try: + for blocked in blocked_names: + orig_modules[blocked] = sys.modules[blocked] + sys.modules[blocked] = 0 + py_module = importlib.import_module(name) + finally: + for blocked, module in orig_modules.items(): + sys.modules[blocked] = module + return py_module + def get_attribute(obj, name): """Get an attribute, raising SkipTest if AttributeError is raised.""" Modified: python/trunk/Lib/test/test_warnings.py ============================================================================== --- python/trunk/Lib/test/test_warnings.py (original) +++ python/trunk/Lib/test/test_warnings.py Sat Apr 11 15:31:31 2009 @@ -10,18 +10,8 @@ import warnings as original_warnings -sys.modules['_warnings'] = 0 -del sys.modules['warnings'] - -import warnings as py_warnings - -del sys.modules['_warnings'] -del sys.modules['warnings'] - -import warnings as c_warnings - -sys.modules['warnings'] = original_warnings - +py_warnings = test_support.import_fresh_module('warnings', ['_warnings']) +c_warnings = test_support.import_fresh_module('warnings') @contextmanager def warnings_state(module): @@ -341,9 +331,21 @@ class CWarnTests(BaseTest, WarnTests): module = c_warnings + # As an early adopter, we sanity check the + # test_support.import_fresh_module utility function + def test_accelerated(self): + self.assertFalse(original_warnings is self.module) + self.assertFalse(hasattr(self.module.warn, 'func_code')) + class PyWarnTests(BaseTest, WarnTests): module = py_warnings + # As an early adopter, we sanity check the + # test_support.import_fresh_module utility function + def test_pure_python(self): + self.assertFalse(original_warnings is self.module) + self.assertTrue(hasattr(self.module.warn, 'func_code')) + class WCmdLineTests(unittest.TestCase): From python-checkins at python.org Sat Apr 11 15:35:04 2009 From: python-checkins at python.org (nick.coghlan) Date: Sat, 11 Apr 2009 15:35:04 +0200 (CEST) Subject: [Python-checkins] r71465 - svn:log Message-ID: <20090411133504.1D4841E4039@bag.python.org> Author: nick.coghlan Revision: 71465 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -1 +1 @@ -Issue 5251: Provide a standardised testing mechanism for doing fresh imports of modules, including the ability to block extension modules in order to test the pure Python fallbacks \ No newline at end of file +Issue 5354: Provide a standardised testing mechanism for doing fresh imports of modules, including the ability to block extension modules in order to test the pure Python fallbacks \ No newline at end of file From python-checkins at python.org Sat Apr 11 15:39:18 2009 From: python-checkins at python.org (nick.coghlan) Date: Sat, 11 Apr 2009 15:39:18 +0200 (CEST) Subject: [Python-checkins] r71466 - python/branches/release26-maint Message-ID: <20090411133918.8BA411E405C@bag.python.org> Author: nick.coghlan Date: Sat Apr 11 15:39:18 2009 New Revision: 71466 Log: Blocked revisions 71465 via svnmerge ........ r71465 | nick.coghlan | 2009-04-11 23:31:31 +1000 (Sat, 11 Apr 2009) | 1 line Issue 5354: Provide a standardised testing mechanism for doing fresh imports of modules, including the ability to block extension modules in order to test the pure Python fallbacks ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sat Apr 11 15:59:05 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 11 Apr 2009 15:59:05 +0200 (CEST) Subject: [Python-checkins] r71467 - python/trunk/Doc/distutils/examples.rst Message-ID: <20090411135905.7482C1E41A5@bag.python.org> Author: tarek.ziade Date: Sat Apr 11 15:59:05 2009 New Revision: 71467 Log: fixed link Modified: python/trunk/Doc/distutils/examples.rst Modified: python/trunk/Doc/distutils/examples.rst ============================================================================== --- python/trunk/Doc/distutils/examples.rst (original) +++ python/trunk/Doc/distutils/examples.rst Sat Apr 11 15:59:05 2009 @@ -11,7 +11,7 @@ .. seealso:: - `Distutils Cookbook `_ + `Distutils Cookbook `_ Collection of recipes showing how to achieve more control over distutils. From python-checkins at python.org Sat Apr 11 16:17:15 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 11 Apr 2009 16:17:15 +0200 (CEST) Subject: [Python-checkins] r71468 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090411141715.5FF2C1E425C@bag.python.org> Author: mark.dickinson Date: Sat Apr 11 16:17:15 2009 New Revision: 71468 Log: Refactor format_float_short, and add some more comments and checks. Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Sat Apr 11 16:17:15 2009 @@ -554,22 +554,23 @@ char *p; Py_ssize_t bufsize = 0; char *digits, *digits_end; - int decpt, sign, exp_len, dec_pos, use_exp = 0; - Py_ssize_t n_digits, min_digits = 0; - Py_ssize_t min_digits1; - - /* _Py_dg_dtoa returns a digit string (no decimal point or - exponent). Must be matched by a call to _Py_dg_freedtoa. */ - digits = _Py_dg_dtoa(d, mode, precision, &decpt, &sign, &digits_end); + int decpt_as_int, sign, exp_len, exp = 0, use_exp = 0; + Py_ssize_t decpt, digits_len, vdigits_start, vdigits_end; + + /* _Py_dg_dtoa returns a digit string (no decimal point or exponent). + Must be matched by a call to _Py_dg_freedtoa. */ + digits = _Py_dg_dtoa(d, mode, precision, &decpt_as_int, &sign, + &digits_end); + decpt = (Py_ssize_t)decpt_as_int; if (digits == NULL) { /* The only failure mode is no memory. */ PyErr_NoMemory(); goto exit; } assert(digits_end != NULL && digits_end >= digits); - n_digits = digits_end - digits; + digits_len = digits_end - digits; - if (n_digits && !isdigit(digits[0])) { + if (digits_len && !isdigit(digits[0])) { /* Infinities and nans here; adapt Gay's output, so convert Infinity to inf and NaN to nan, and ignore sign of nan. Then return. */ @@ -609,81 +610,96 @@ goto exit; } - /* We got digits back, format them. */ - - /* Detect if we're using exponents or not, and figure out how many - additional digits we need beyond those provided by dtoa. */ + /* We got digits back, format them. We may need to pad 'digits' + either on the left or right (or both) with extra zeros, so in + general the resulting string has the form + + [][] + + where either of the pieces could be empty, and there's a + decimal point that could appear either in or in the + leading or trailing . + + Imagine an infinite 'virtual' string vdigits, consisting of the + string 'digits' (starting at index 0) padded on both the left and + right with infinite strings of zeros. We want to output a slice + + vdigits[vdigits_start : vdigits_end] + + of this virtual string. Thus if vdigits_start < 0 then we'll end + up producing some leading zeros; if vdigits_end > digits_len there + will be trailing zeros in the output. The next section of code + determines whether to use an exponent or not, figures out the + position 'decpt' of the decimal point, and computes 'vdigits_start' + and 'vdigits_end'. */ + vdigits_end = digits_len; switch (format_code) { case 'e': use_exp = 1; - min_digits = precision; + vdigits_end = precision; break; case 'f': - min_digits = decpt + precision; + vdigits_end = decpt + precision; break; case 'g': if (decpt <= -4 || decpt > precision) use_exp = 1; - /* assumes that not both of add_dot_0_if_integer and - use_alt_formatting are set */ - else if (add_dot_0_if_integer) - min_digits = decpt + 1; if (use_alt_formatting) - min_digits = precision; + vdigits_end = precision; break; case 'r': + /* convert to exponential format at 1e16. We used to convert + at 1e17, but that gives odd-looking results for some values + when a 16-digit 'shortest' repr is padded with bogus zeros. + For example, repr(2e16+8) would give 20000000000000010.0; + the true value is 20000000000000008.0. */ if (decpt <= -4 || decpt > 16) use_exp = 1; - else if (add_dot_0_if_integer) - min_digits = decpt + 1; break; case 's': /* if we're forcing a digit after the point, convert to exponential format at 1e11. If not, convert at 1e12. */ - if (decpt <= -4 || - decpt > precision - (add_dot_0_if_integer != 0)) + if (decpt <= -4 || decpt > + (add_dot_0_if_integer ? precision-1 : precision)) use_exp = 1; - else if (add_dot_0_if_integer) - min_digits = decpt + 1; break; default: PyErr_BadInternalCall(); goto exit; } - /* dec_pos = position of decimal point in buffer */ - if (use_exp) - dec_pos = 1; + /* if using an exponent, reset decimal point position to 1 and adjust + exponent accordingly.*/ + if (use_exp) { + exp = decpt - 1; + decpt = 1; + } + /* ensure vdigits_start < decpt <= vdigits_end, or vdigits_start < + decpt < vdigits_end if add_dot_0_if_integer and no exponent */ + vdigits_start = decpt <= 0 ? decpt-1 : 0; + if (!use_exp && add_dot_0_if_integer) + vdigits_end = vdigits_end > decpt ? vdigits_end : decpt + 1; else - dec_pos = decpt; + vdigits_end = vdigits_end > decpt ? vdigits_end : decpt; - min_digits -= n_digits; - min_digits1 = (n_digits < dec_pos) ? - (min_digits - (dec_pos-n_digits)) : min_digits; + /* double check inequalities */ + assert(vdigits_start <= 0 && + 0 <= digits_len && + digits_len <= vdigits_end); + /* decimal point should be in (vdigits_start, vdigits_end] */ + assert(vdigits_start < decpt && decpt <= vdigits_end); /* Compute an upper bound how much memory we need. This might be a few chars too long, but no big deal. */ bufsize = - /* 1: Sign */ - 1 + - - /* 2: Zero padding on left of digit string */ - (dec_pos <= 0 ? -dec_pos + 2 : 0) + - - /* 3: Digits, with included decimal point */ - (1 + n_digits) + + /* sign, decimal point and trailing 0 byte */ + 3 + - /* 4: And zeros on the right up to the decimal point */ - ((n_digits < dec_pos) ? dec_pos-n_digits + 1 : 0) + + /* total digit count (including zero padding on both sides) */ + (vdigits_end - vdigits_start) + - /* 5: And more trailing zeros when necessary */ - (min_digits1 > 0 ? min_digits1 : 0) + - - /* 6: Exponent "e+100", max 3 numerical digits */ - (use_exp ? 5 : 0) + - - /* Trailing 0 byte */ - 1; + /* exponent "e+100", max 3 numerical digits */ + (use_exp ? 5 : 0); /* Now allocate the memory and initialize p to point to the start of it. */ @@ -701,39 +717,45 @@ else if (always_add_sign) *p++ = '+'; + /* note that exactly one of the three 'if' conditions is true, + so we include exactly one decimal point */ /* 2: Zero padding on left of digit string */ - if (dec_pos <= 0) { - *p++ = '0'; + if (decpt <= 0) { + memset(p, '0', decpt-vdigits_start); + p += decpt - vdigits_start; *p++ = '.'; - memset(p, '0', -dec_pos); - p -= dec_pos; + memset(p, '0', 0-decpt); + p += 0-decpt; + } + else { + memset(p, '0', 0-vdigits_start); + p += 0 - vdigits_start; } /* 3: Digits, with included decimal point */ - if (0 < dec_pos && dec_pos <= n_digits) { - strncpy(p, digits, dec_pos); - p += dec_pos; + if (0 < decpt && decpt <= digits_len) { + strncpy(p, digits, decpt-0); + p += decpt-0; *p++ = '.'; - strncpy(p, digits+dec_pos, n_digits-dec_pos); - p += n_digits-dec_pos; + strncpy(p, digits+decpt, digits_len-decpt); + p += digits_len-decpt; } else { - strncpy(p, digits, n_digits); - p += n_digits; + strncpy(p, digits, digits_len); + p += digits_len; } - /* 4: And zeros on the right up to the decimal point */ - if (n_digits < dec_pos) { - memset(p, '0', dec_pos-n_digits); - p += dec_pos-n_digits; + /* 4: And zeros on the right */ + if (digits_len < decpt) { + memset(p, '0', decpt-digits_len); + p += decpt-digits_len; *p++ = '.'; - min_digits -= dec_pos-n_digits; + memset(p, '0', vdigits_end-decpt); + p += vdigits_end-decpt; } - - /* 5: And more trailing zeros when necessary */ - if (min_digits > 0) { - memset(p, '0', min_digits); - p += min_digits; + else { + memset(p, '0', vdigits_end-digits_len); + p += vdigits_end-digits_len; } /* Delete a trailing decimal pt unless using alternative formatting. */ @@ -743,7 +765,7 @@ /* 6: Now that we've done zero padding, add an exponent if needed. */ if (use_exp) { *p++ = float_strings[OFS_E][0]; - exp_len = sprintf(p, "%+.02d", decpt-1); + exp_len = sprintf(p, "%+.02d", exp); p += exp_len; } exit: From python-checkins at python.org Sat Apr 11 16:30:59 2009 From: python-checkins at python.org (nick.coghlan) Date: Sat, 11 Apr 2009 16:30:59 +0200 (CEST) Subject: [Python-checkins] r71469 - in python/branches/py3k: Doc/library/test.rst Lib/test/support.py Lib/test/test_heapq.py Lib/test/test_warnings.py Message-ID: <20090411143059.983F21E4052@bag.python.org> Author: nick.coghlan Date: Sat Apr 11 16:30:59 2009 New Revision: 71469 Log: Merged revisions 71465 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71465 | nick.coghlan | 2009-04-11 23:31:31 +1000 (Sat, 11 Apr 2009) | 1 line Issue 5354: Provide a standardised testing mechanism for doing fresh imports of modules, including the ability to block extension modules in order to test the pure Python fallbacks ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/test.rst python/branches/py3k/Lib/test/support.py python/branches/py3k/Lib/test/test_heapq.py python/branches/py3k/Lib/test/test_warnings.py Modified: python/branches/py3k/Doc/library/test.rst ============================================================================== --- python/branches/py3k/Doc/library/test.rst (original) +++ python/branches/py3k/Doc/library/test.rst Sat Apr 11 16:30:59 2009 @@ -322,6 +322,30 @@ assert s.getvalue() == "hello" +.. function:: import_module(name, deprecated=False) + + This function imports and returns the named module. Unlike a normal + import, this function raises :exc:`unittest.SkipTest` if the module + cannot be imported. + + Module and package deprecation messages are suppressed during this import + if *deprecated* is :const:`True`. + + .. versionadded:: 3.1 + + +.. function:: import_fresh_module(name, blocked_names=None, deprecated=False) + + This function imports and returns a fresh copy of the named Python module. The + ``sys.modules`` cache is bypassed temporarily, and the ability to import the + modules named in *blocked_names* is suppressed for the duration of the import. + + Module and package deprecation messages are suppressed during this import + if *deprecated* is :const:`True`. + + .. versionadded:: 3.1 + + The :mod:`test.support` module defines the following classes: .. class:: TransientResource(exc[, **kwargs]) Modified: python/branches/py3k/Lib/test/support.py ============================================================================== --- python/branches/py3k/Lib/test/support.py (original) +++ python/branches/py3k/Lib/test/support.py Sat Apr 11 16:30:59 2009 @@ -41,22 +41,63 @@ and unexpected skips. """ + at contextlib.contextmanager +def _ignore_deprecated_imports(ignore=True): + """Context manager to suppress package and module deprecation + warnings when importing them. + + If ignore is False, this context manager has no effect.""" + if ignore: + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", ".+ (module|package)", + DeprecationWarning) + yield + else: + yield + + def import_module(name, deprecated=False): """Import and return the module to be tested, raising SkipTest if it is not available. If deprecated is True, any module or package deprecation messages will be suppressed.""" - with warnings.catch_warnings(): - if deprecated: - warnings.filterwarnings("ignore", ".+ (module|package)", - DeprecationWarning) + with _ignore_deprecated_imports(deprecated): try: - module = importlib.import_module(name) + return importlib.import_module(name) except ImportError as msg: raise unittest.SkipTest(str(msg)) - else: - return module + + +def import_fresh_module(name, blocked_names=None, deprecated=False): + """Imports and returns a module, deliberately bypassing the sys.modules cache + and importing a fresh copy of the module. Once the import is complete, + the sys.modules cache is restored to its original state. + + Importing of modules named in blocked_names is prevented while the fresh import + takes place. + + If deprecated is True, any module or package deprecation messages + will be suppressed.""" + # NOTE: test_heapq and test_warnings include extra sanity checks to make + # sure that this utility function is working as expected + with _ignore_deprecated_imports(deprecated): + if blocked_names is None: + blocked_names = () + orig_modules = {} + if name in sys.modules: + orig_modules[name] = sys.modules[name] + del sys.modules[name] + try: + for blocked in blocked_names: + orig_modules[blocked] = sys.modules[blocked] + sys.modules[blocked] = 0 + py_module = importlib.import_module(name) + finally: + for blocked, module in orig_modules.items(): + sys.modules[blocked] = module + return py_module + def get_attribute(obj, name): """Get an attribute, raising SkipTest if AttributeError is raised.""" Modified: python/branches/py3k/Lib/test/test_heapq.py ============================================================================== --- python/branches/py3k/Lib/test/test_heapq.py (original) +++ python/branches/py3k/Lib/test/test_heapq.py Sat Apr 11 16:30:59 2009 @@ -7,23 +7,8 @@ # We do a bit of trickery here to be able to test both the C implementation # and the Python implementation of the module. - -# Make it impossible to import the C implementation anymore. -sys.modules['_heapq'] = 0 -# We must also handle the case that heapq was imported before. -if 'heapq' in sys.modules: - del sys.modules['heapq'] - -# Now we can import the module and get the pure Python implementation. -import heapq as py_heapq - -# Restore everything to normal. -del sys.modules['_heapq'] -del sys.modules['heapq'] - -# This is now the module with the C implementation. import heapq as c_heapq - +py_heapq = support.import_fresh_module('heapq', ['_heapq']) class TestHeap(unittest.TestCase): module = None @@ -194,6 +179,13 @@ class TestHeapPython(TestHeap): module = py_heapq + # As an early adopter, we sanity check the + # test.support.import_fresh_module utility function + def test_pure_python(self): + self.assertFalse(sys.modules['heapq'] is self.module) + self.assertTrue(hasattr(self.module.heapify, '__code__')) + + class TestHeapC(TestHeap): module = c_heapq @@ -219,6 +211,12 @@ self.assertEqual(hsort(data, LT), target) self.assertRaises(TypeError, data, LE) + # As an early adopter, we sanity check the + # test.support.import_fresh_module utility function + def test_accelerated(self): + self.assertTrue(sys.modules['heapq'] is self.module) + self.assertFalse(hasattr(self.module.heapify, '__code__')) + #============================================================================== Modified: python/branches/py3k/Lib/test/test_warnings.py ============================================================================== --- python/branches/py3k/Lib/test/test_warnings.py (original) +++ python/branches/py3k/Lib/test/test_warnings.py Sat Apr 11 16:30:59 2009 @@ -10,18 +10,14 @@ import warnings as original_warnings -sys.modules['_warnings'] = 0 -del sys.modules['warnings'] - -import warnings as py_warnings - +py_warnings = support.import_fresh_module('warnings', ['_warnings']) +# XXX (ncoghlan 20090412): +# Something in Py3k doesn't like sharing the same instance of +# _warnings between original_warnings and c_warnings +# Will leave issue 5354 open until I understand why 3.x breaks +# without the next line, while 2.x doesn't care del sys.modules['_warnings'] -del sys.modules['warnings'] - -import warnings as c_warnings - -sys.modules['warnings'] = original_warnings - +c_warnings = support.import_fresh_module('warnings') @contextmanager def warnings_state(module): @@ -351,9 +347,21 @@ class CWarnTests(BaseTest, WarnTests): module = c_warnings + # As an early adopter, we sanity check the + # test.support.import_fresh_module utility function + def test_accelerated(self): + self.assertFalse(original_warnings is self.module) + self.assertFalse(hasattr(self.module.warn, '__code__')) + class PyWarnTests(BaseTest, WarnTests): module = py_warnings + # As an early adopter, we sanity check the + # test.support.import_fresh_module utility function + def test_pure_python(self): + self.assertFalse(original_warnings is self.module) + self.assertTrue(hasattr(self.module.warn, '__code__')) + class WCmdLineTests(unittest.TestCase): From python-checkins at python.org Sat Apr 11 16:31:25 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 11 Apr 2009 16:31:25 +0200 (CEST) Subject: [Python-checkins] r71470 - in python/branches/release26-maint: Doc/distutils/examples.rst Message-ID: <20090411143125.18C5B1E404A@bag.python.org> Author: tarek.ziade Date: Sat Apr 11 16:31:24 2009 New Revision: 71470 Log: Merged revisions 71467 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71467 | tarek.ziade | 2009-04-11 15:59:05 +0200 (Sat, 11 Apr 2009) | 1 line fixed link ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/distutils/examples.rst Modified: python/branches/release26-maint/Doc/distutils/examples.rst ============================================================================== --- python/branches/release26-maint/Doc/distutils/examples.rst (original) +++ python/branches/release26-maint/Doc/distutils/examples.rst Sat Apr 11 16:31:24 2009 @@ -11,7 +11,7 @@ .. seealso:: - `Distutils Cookbook `_ + `Distutils Cookbook `_ Collection of recipes showing how to achieve more control over distutils. From python-checkins at python.org Sat Apr 11 16:32:37 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 11 Apr 2009 16:32:37 +0200 (CEST) Subject: [Python-checkins] r71471 - in python/branches/py3k: Doc/distutils/examples.rst Message-ID: <20090411143237.9E2271E4039@bag.python.org> Author: tarek.ziade Date: Sat Apr 11 16:32:37 2009 New Revision: 71471 Log: Merged revisions 71467 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71467 | tarek.ziade | 2009-04-11 15:59:05 +0200 (Sat, 11 Apr 2009) | 1 line fixed link ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/distutils/examples.rst Modified: python/branches/py3k/Doc/distutils/examples.rst ============================================================================== --- python/branches/py3k/Doc/distutils/examples.rst (original) +++ python/branches/py3k/Doc/distutils/examples.rst Sat Apr 11 16:32:37 2009 @@ -11,7 +11,7 @@ .. seealso:: - `Distutils Cookbook `_ + `Distutils Cookbook `_ Collection of recipes showing how to achieve more control over distutils. From python-checkins at python.org Sat Apr 11 16:33:04 2009 From: python-checkins at python.org (nick.coghlan) Date: Sat, 11 Apr 2009 16:33:04 +0200 (CEST) Subject: [Python-checkins] r71472 - python/branches/release30-maint Message-ID: <20090411143304.35D4F1E4205@bag.python.org> Author: nick.coghlan Date: Sat Apr 11 16:33:04 2009 New Revision: 71472 Log: Blocked revisions 71469 via svnmerge ................ r71469 | nick.coghlan | 2009-04-12 00:30:59 +1000 (Sun, 12 Apr 2009) | 9 lines Merged revisions 71465 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71465 | nick.coghlan | 2009-04-11 23:31:31 +1000 (Sat, 11 Apr 2009) | 1 line Issue 5354: Provide a standardised testing mechanism for doing fresh imports of modules, including the ability to block extension modules in order to test the pure Python fallbacks ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sat Apr 11 16:55:12 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 11 Apr 2009 16:55:12 +0200 (CEST) Subject: [Python-checkins] r71473 - in python/trunk: Doc/distutils/apiref.rst Doc/distutils/examples.rst Lib/distutils/command/__init__.py Lib/distutils/command/check.py Lib/distutils/tests/test_check.py Misc/NEWS Message-ID: <20090411145512.3C65F1E406A@bag.python.org> Author: tarek.ziade Date: Sat Apr 11 16:55:07 2009 New Revision: 71473 Log: #5732: added the check command into Distutils Added: python/trunk/Lib/distutils/command/check.py (contents, props changed) python/trunk/Lib/distutils/tests/test_check.py (contents, props changed) Modified: python/trunk/Doc/distutils/apiref.rst python/trunk/Doc/distutils/examples.rst python/trunk/Lib/distutils/command/__init__.py python/trunk/Misc/NEWS Modified: python/trunk/Doc/distutils/apiref.rst ============================================================================== --- python/trunk/Doc/distutils/apiref.rst (original) +++ python/trunk/Doc/distutils/apiref.rst Sat Apr 11 16:55:07 2009 @@ -1932,6 +1932,19 @@ .. % todo +:mod:`distutils.command.check` --- Check the meta-data of a package +=================================================================== + +.. module:: distutils.command.check + :synopsis: Check the metadata of a package + + +The ``check`` command performs some tests on the meta-data of a package. +It makes sure for example that all required meta-data are provided through +the arguments passed to the :func:`setup` function. + +.. % todo + Creating a new Distutils command ================================ Modified: python/trunk/Doc/distutils/examples.rst ============================================================================== --- python/trunk/Doc/distutils/examples.rst (original) +++ python/trunk/Doc/distutils/examples.rst Sat Apr 11 16:55:07 2009 @@ -233,6 +233,58 @@ ext_modules=[Extension('foopkg.foo', ['foo.c'])], ) +Checking a package +================== + +The ``check`` command allows you to verify if your package meta-data are +meeting the minimum requirements to build a distribution. + +To run it, just call it over your :file:`setup.py` script. If something is +missing, ``check`` will display a warning. + +Let's take an example with a simple script:: + + from distutils.core import setup + + setup(name='foobar') + +Running the ``check`` command will display some warnings:: + + $ python setup.py check + running check + warning: check: missing required meta-data: version ,url + warning: check: missing meta-data: either (author and author_email) or + (maintainer and maintainer_email) must be supplied + + +If you use the reStructuredText syntax in the `long_description` field and +`docutils `_ is installed you can check if +the syntax is fine with the ``check`` command, using the `restructuredtext` +option. + +For example, if the :file:`setup.py` script is changed like this:: + + from distutils.core import setup + + desc = """\ + My description + ============= + + This is the description of the ``foobar`` package. + """ + + setup(name='foobar', version='1', author='tarek', + author_email='tarek at ziade.org', + url='http://example.com', long_description=desc) + +Where the long description is broken, ``check`` will be able to detect it +by using the `docutils` parser:: + + $ pythontrunk setup.py check --restructuredtext + running check + warning: check: Title underline too short. (line 2) + warning: check: Could not finish the parsing. + .. % \section{Multiple extension modules} .. % \label{multiple-ext} Modified: python/trunk/Lib/distutils/command/__init__.py ============================================================================== --- python/trunk/Lib/distutils/command/__init__.py (original) +++ python/trunk/Lib/distutils/command/__init__.py Sat Apr 11 16:55:07 2009 @@ -23,7 +23,7 @@ 'bdist_rpm', 'bdist_wininst', 'upload', - + 'check', # These two are reserved for future use: #'bdist_sdux', #'bdist_pkgtool', Added: python/trunk/Lib/distutils/command/check.py ============================================================================== --- (empty file) +++ python/trunk/Lib/distutils/command/check.py Sat Apr 11 16:55:07 2009 @@ -0,0 +1,143 @@ +"""distutils.command.check + +Implements the Distutils 'check' command. +""" +__revision__ = "$Id$" + +from distutils.core import Command +from distutils.errors import DistutilsSetupError + +try: + # docutils is installed + from docutils.utils import Reporter + from docutils.parsers.rst import Parser + from docutils import frontend + from docutils import nodes + from StringIO import StringIO + + class SilentReporter(Reporter): + + def __init__(self, source, report_level, halt_level, stream=None, + debug=0, encoding='ascii', error_handler='replace'): + self.messages = [] + Reporter.__init__(self, source, report_level, halt_level, stream, + debug, encoding, error_handler) + + def system_message(self, level, message, *children, **kwargs): + self.messages.append((level, message, children, kwargs)) + + HAS_DOCUTILS = True +except ImportError: + # docutils is not installed + HAS_DOCUTILS = False + +class check(Command): + """This command checks the meta-data of the package. + """ + description = ("perform some checks on the package") + user_options = [('metadata', 'm', 'Verify meta-data'), + ('restructuredtext', 'r', + ('Checks if long string meta-data syntax ' + 'are reStructuredText-compliant')), + ('strict', 's', + 'Will exit with an error if a check fails')] + + boolean_options = ['metadata', 'restructuredtext', 'strict'] + + def initialize_options(self): + """Sets default values for options.""" + self.restructuredtext = 0 + self.metadata = 1 + self.strict = 0 + self._warnings = 0 + + def finalize_options(self): + pass + + def warn(self, msg): + """Counts the number of warnings that occurs.""" + self._warnings += 1 + return Command.warn(self, msg) + + def run(self): + """Runs the command.""" + # perform the various tests + if self.metadata: + self.check_metadata() + if self.restructuredtext: + if docutils: + self.check_restructuredtext() + elif self.strict: + raise DistutilsSetupError('The docutils package is needed.') + + # let's raise an error in strict mode, if we have at least + # one warning + if self.strict and self._warnings > 1: + raise DistutilsSetupError('Please correct your package.') + + def check_metadata(self): + """Ensures that all required elements of meta-data are supplied. + + name, version, URL, (author and author_email) or + (maintainer and maintainer_email)). + + Warns if any are missing. + """ + metadata = self.distribution.metadata + + missing = [] + for attr in ('name', 'version', 'url'): + if not (hasattr(metadata, attr) and getattr(metadata, attr)): + missing.append(attr) + + if missing: + self.warn("missing required meta-data: %s" % ' ,'.join(missing)) + if metadata.author: + if not metadata.author_email: + self.warn("missing meta-data: if 'author' supplied, " + + "'author_email' must be supplied too") + elif metadata.maintainer: + if not metadata.maintainer_email: + self.warn("missing meta-data: if 'maintainer' supplied, " + + "'maintainer_email' must be supplied too") + else: + self.warn("missing meta-data: either (author and author_email) " + + "or (maintainer and maintainer_email) " + + "must be supplied") + + def check_restructuredtext(self): + """Checks if the long string fields are reST-compliant.""" + data = self.distribution.get_long_description() + for warning in self._check_rst_data(data): + line = warning[-1].get('line') + if line is None: + warning = warning[1] + else: + warning = '%s (line %s)' % (warning[1], line) + self.warn(warning) + + def _check_rst_data(self, data): + """Returns warnings when the provided data doesn't compile.""" + source_path = StringIO() + parser = Parser() + settings = frontend.OptionParser().get_default_values() + settings.tab_width = 4 + settings.pep_references = None + settings.rfc_references = None + reporter = SilentReporter(source_path, + settings.report_level, + settings.halt_level, + stream=settings.warning_stream, + debug=settings.debug, + encoding=settings.error_encoding, + error_handler=settings.error_encoding_error_handler) + + document = nodes.document(settings, reporter, source=source_path) + document.note_source(source_path, -1) + try: + parser.parse(data, document) + except AttributeError: + reporter.messages.append((-1, 'Could not finish the parsing.', + '', {})) + + return reporter.messages Added: python/trunk/Lib/distutils/tests/test_check.py ============================================================================== --- (empty file) +++ python/trunk/Lib/distutils/tests/test_check.py Sat Apr 11 16:55:07 2009 @@ -0,0 +1,92 @@ +"""Tests for distutils.command.check.""" +import unittest + +from distutils.command.check import check, HAS_DOCUTILS +from distutils.tests import support +from distutils.errors import DistutilsSetupError + +class CheckTestCase(support.LoggingSilencer, + support.TempdirManager, + unittest.TestCase): + + def _run(self, metadata=None, **options): + if metadata is None: + metadata = {} + pkg_info, dist = self.create_dist(**metadata) + cmd = check(dist) + cmd.initialize_options() + for name, value in options.items(): + setattr(cmd, name, value) + cmd.ensure_finalized() + cmd.run() + return cmd + + def test_check_metadata(self): + # let's run the command with no metadata at all + # by default, check is checking the metadata + # should have some warnings + cmd = self._run() + self.assertEquals(cmd._warnings, 2) + + # now let's add the required fields + # and run it again, to make sure we don't get + # any warning anymore + metadata = {'url': 'xxx', 'author': 'xxx', + 'author_email': 'xxx', + 'name': 'xxx', 'version': 'xxx'} + cmd = self._run(metadata) + self.assertEquals(cmd._warnings, 0) + + # now with the strict mode, we should + # get an error if there are missing metadata + self.assertRaises(DistutilsSetupError, self._run, {}, **{'strict': 1}) + + # and of course, no error when all metadata are present + cmd = self._run(metadata, strict=1) + self.assertEquals(cmd._warnings, 0) + + def test_check_document(self): + if not HAS_DOCUTILS: # won't test without docutils + return + pkg_info, dist = self.create_dist() + cmd = check(dist) + + # let's see if it detects broken rest + broken_rest = 'title\n===\n\ntest' + msgs = cmd._check_rst_data(broken_rest) + self.assertEquals(len(msgs), 1) + + # and non-broken rest + rest = 'title\n=====\n\ntest' + msgs = cmd._check_rst_data(rest) + self.assertEquals(len(msgs), 0) + + def test_check_restructuredtext(self): + if not HAS_DOCUTILS: # won't test without docutils + return + # let's see if it detects broken rest in long_description + broken_rest = 'title\n===\n\ntest' + pkg_info, dist = self.create_dist(long_description=broken_rest) + cmd = check(dist) + cmd.check_restructuredtext() + self.assertEquals(cmd._warnings, 1) + + # let's see if we have an error with strict=1 + cmd = check(dist) + cmd.initialize_options() + cmd.strict = 1 + cmd.ensure_finalized() + self.assertRaises(DistutilsSetupError, cmd.run) + + # and non-broken rest + rest = 'title\n=====\n\ntest' + pkg_info, dist = self.create_dist(long_description=rest) + cmd = check(dist) + cmd.check_restructuredtext() + self.assertEquals(cmd._warnings, 0) + +def test_suite(): + return unittest.makeSuite(CheckTestCase) + +if __name__ == "__main__": + unittest.main(defaultTest="test_suite") Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Apr 11 16:55:07 2009 @@ -219,6 +219,8 @@ Library ------- +- Issue #5732: added a new command in Distutils: check. + - Issue #5731: Distutils bdist_wininst no longer worked on non-Windows platforms. Initial patch by Paul Moore. From python-checkins at python.org Sat Apr 11 16:56:13 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 11 Apr 2009 16:56:13 +0200 (CEST) Subject: [Python-checkins] r71474 - python/branches/release26-maint Message-ID: <20090411145613.0E99E1E401A@bag.python.org> Author: tarek.ziade Date: Sat Apr 11 16:56:12 2009 New Revision: 71474 Log: Blocked revisions 71473 via svnmerge ........ r71473 | tarek.ziade | 2009-04-11 16:55:07 +0200 (Sat, 11 Apr 2009) | 1 line #5732: added the check command into Distutils ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sat Apr 11 17:00:44 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 11 Apr 2009 17:00:44 +0200 (CEST) Subject: [Python-checkins] r71475 - in python/branches/py3k: Doc/distutils/apiref.rst Doc/distutils/examples.rst Lib/distutils/command/__init__.py Lib/distutils/command/check.py Lib/distutils/tests/test_check.py Misc/NEWS Message-ID: <20090411150044.5A17A1E401A@bag.python.org> Author: tarek.ziade Date: Sat Apr 11 17:00:43 2009 New Revision: 71475 Log: Merged revisions 71473 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71473 | tarek.ziade | 2009-04-11 16:55:07 +0200 (Sat, 11 Apr 2009) | 1 line #5732: added the check command into Distutils ........ Added: python/branches/py3k/Lib/distutils/command/check.py - copied unchanged from r71473, /python/trunk/Lib/distutils/command/check.py python/branches/py3k/Lib/distutils/tests/test_check.py - copied unchanged from r71473, /python/trunk/Lib/distutils/tests/test_check.py Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/distutils/apiref.rst python/branches/py3k/Doc/distutils/examples.rst python/branches/py3k/Lib/distutils/command/__init__.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/distutils/apiref.rst ============================================================================== --- python/branches/py3k/Doc/distutils/apiref.rst (original) +++ python/branches/py3k/Doc/distutils/apiref.rst Sat Apr 11 17:00:43 2009 @@ -1950,6 +1950,19 @@ .. % todo +:mod:`distutils.command.check` --- Check the meta-data of a package +=================================================================== + +.. module:: distutils.command.check + :synopsis: Check the metadata of a package + + +The ``check`` command performs some tests on the meta-data of a package. +It makes sure for example that all required meta-data are provided through +the arguments passed to the :func:`setup` function. + +.. % todo + Creating a new Distutils command ================================ Modified: python/branches/py3k/Doc/distutils/examples.rst ============================================================================== --- python/branches/py3k/Doc/distutils/examples.rst (original) +++ python/branches/py3k/Doc/distutils/examples.rst Sat Apr 11 17:00:43 2009 @@ -233,6 +233,58 @@ ext_modules=[Extension('foopkg.foo', ['foo.c'])], ) +Checking a package +================== + +The ``check`` command allows you to verify if your package meta-data are +meeting the minimum requirements to build a distribution. + +To run it, just call it over your :file:`setup.py` script. If something is +missing, ``check`` will display a warning. + +Let's take an example with a simple script:: + + from distutils.core import setup + + setup(name='foobar') + +Running the ``check`` command will display some warnings:: + + $ python setup.py check + running check + warning: check: missing required meta-data: version ,url + warning: check: missing meta-data: either (author and author_email) or + (maintainer and maintainer_email) must be supplied + + +If you use the reStructuredText syntax in the `long_description` field and +`docutils `_ is installed you can check if +the syntax is fine with the ``check`` command, using the `restructuredtext` +option. + +For example, if the :file:`setup.py` script is changed like this:: + + from distutils.core import setup + + desc = """\ + My description + ============= + + This is the description of the ``foobar`` package. + """ + + setup(name='foobar', version='1', author='tarek', + author_email='tarek at ziade.org', + url='http://example.com', long_description=desc) + +Where the long description is broken, ``check`` will be able to detect it +by using the `docutils` parser:: + + $ pythontrunk setup.py check --restructuredtext + running check + warning: check: Title underline too short. (line 2) + warning: check: Could not finish the parsing. + .. % \section{Multiple extension modules} .. % \label{multiple-ext} Modified: python/branches/py3k/Lib/distutils/command/__init__.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/__init__.py (original) +++ python/branches/py3k/Lib/distutils/command/__init__.py Sat Apr 11 17:00:43 2009 @@ -22,6 +22,7 @@ 'bdist_dumb', 'bdist_rpm', 'bdist_wininst', + 'check', # These two are reserved for future use: #'bdist_sdux', #'bdist_pkgtool', Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Apr 11 17:00:43 2009 @@ -340,6 +340,8 @@ Library ------- +- Issue #5732: added a new command in Distutils: check. + - Issue #5731: Distutils bdist_wininst no longer worked on non-Windows platforms. Initial patch by Paul Moore. From python-checkins at python.org Sat Apr 11 17:03:18 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 11 Apr 2009 17:03:18 +0200 (CEST) Subject: [Python-checkins] r71476 - in python/branches/release30-maint: Doc/distutils/examples.rst Message-ID: <20090411150318.F40E21E4039@bag.python.org> Author: tarek.ziade Date: Sat Apr 11 17:03:18 2009 New Revision: 71476 Log: Merged revisions 71471 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71471 | tarek.ziade | 2009-04-11 16:32:37 +0200 (Sat, 11 Apr 2009) | 9 lines Merged revisions 71467 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71467 | tarek.ziade | 2009-04-11 15:59:05 +0200 (Sat, 11 Apr 2009) | 1 line fixed link ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Doc/distutils/examples.rst Modified: python/branches/release30-maint/Doc/distutils/examples.rst ============================================================================== --- python/branches/release30-maint/Doc/distutils/examples.rst (original) +++ python/branches/release30-maint/Doc/distutils/examples.rst Sat Apr 11 17:03:18 2009 @@ -11,7 +11,7 @@ .. seealso:: - `Distutils Cookbook `_ + `Distutils Cookbook `_ Collection of recipes showing how to achieve more control over distutils. From python-checkins at python.org Sat Apr 11 17:03:47 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 11 Apr 2009 17:03:47 +0200 (CEST) Subject: [Python-checkins] r71477 - python/branches/release30-maint Message-ID: <20090411150347.47DA71E4039@bag.python.org> Author: tarek.ziade Date: Sat Apr 11 17:03:47 2009 New Revision: 71477 Log: Blocked revisions 71475 via svnmerge ................ r71475 | tarek.ziade | 2009-04-11 17:00:43 +0200 (Sat, 11 Apr 2009) | 9 lines Merged revisions 71473 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71473 | tarek.ziade | 2009-04-11 16:55:07 +0200 (Sat, 11 Apr 2009) | 1 line #5732: added the check command into Distutils ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sat Apr 11 17:14:17 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 11 Apr 2009 17:14:17 +0200 (CEST) Subject: [Python-checkins] r71478 - in python/trunk/Lib/distutils: command/check.py tests/test_check.py Message-ID: <20090411151417.DE0711E4039@bag.python.org> Author: tarek.ziade Date: Sat Apr 11 17:14:17 2009 New Revision: 71478 Log: testing a full check case Modified: python/trunk/Lib/distutils/command/check.py python/trunk/Lib/distutils/tests/test_check.py Modified: python/trunk/Lib/distutils/command/check.py ============================================================================== --- python/trunk/Lib/distutils/command/check.py (original) +++ python/trunk/Lib/distutils/command/check.py Sat Apr 11 17:14:17 2009 @@ -65,7 +65,7 @@ if self.metadata: self.check_metadata() if self.restructuredtext: - if docutils: + if HAS_DOCUTILS: self.check_restructuredtext() elif self.strict: raise DistutilsSetupError('The docutils package is needed.') Modified: python/trunk/Lib/distutils/tests/test_check.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_check.py (original) +++ python/trunk/Lib/distutils/tests/test_check.py Sat Apr 11 17:14:17 2009 @@ -85,6 +85,13 @@ cmd.check_restructuredtext() self.assertEquals(cmd._warnings, 0) + def test_check_all(self): + + metadata = {'url': 'xxx', 'author': 'xxx'} + self.assertRaises(DistutilsSetupError, self._run, + {}, **{'strict': 1, + 'restructuredtext': 1}) + def test_suite(): return unittest.makeSuite(CheckTestCase) From python-checkins at python.org Sat Apr 11 17:15:32 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 11 Apr 2009 17:15:32 +0200 (CEST) Subject: [Python-checkins] r71479 - python/branches/release26-maint Message-ID: <20090411151532.BD2421E416C@bag.python.org> Author: tarek.ziade Date: Sat Apr 11 17:15:32 2009 New Revision: 71479 Log: Blocked revisions 71478 via svnmerge ........ r71478 | tarek.ziade | 2009-04-11 17:14:17 +0200 (Sat, 11 Apr 2009) | 1 line testing a full check case ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sat Apr 11 17:17:05 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 11 Apr 2009 17:17:05 +0200 (CEST) Subject: [Python-checkins] r71480 - in python/branches/py3k: Lib/distutils/command/check.py Lib/distutils/tests/test_check.py Message-ID: <20090411151705.3E58A1E4039@bag.python.org> Author: tarek.ziade Date: Sat Apr 11 17:17:04 2009 New Revision: 71480 Log: Merged revisions 71478 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71478 | tarek.ziade | 2009-04-11 17:14:17 +0200 (Sat, 11 Apr 2009) | 1 line testing a full check case ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/command/check.py python/branches/py3k/Lib/distutils/tests/test_check.py Modified: python/branches/py3k/Lib/distutils/command/check.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/check.py (original) +++ python/branches/py3k/Lib/distutils/command/check.py Sat Apr 11 17:17:04 2009 @@ -65,7 +65,7 @@ if self.metadata: self.check_metadata() if self.restructuredtext: - if docutils: + if HAS_DOCUTILS: self.check_restructuredtext() elif self.strict: raise DistutilsSetupError('The docutils package is needed.') Modified: python/branches/py3k/Lib/distutils/tests/test_check.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_check.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_check.py Sat Apr 11 17:17:04 2009 @@ -85,6 +85,13 @@ cmd.check_restructuredtext() self.assertEquals(cmd._warnings, 0) + def test_check_all(self): + + metadata = {'url': 'xxx', 'author': 'xxx'} + self.assertRaises(DistutilsSetupError, self._run, + {}, **{'strict': 1, + 'restructuredtext': 1}) + def test_suite(): return unittest.makeSuite(CheckTestCase) From python-checkins at python.org Sat Apr 11 17:18:16 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 11 Apr 2009 17:18:16 +0200 (CEST) Subject: [Python-checkins] r71481 - python/branches/release30-maint Message-ID: <20090411151816.9BA171E4012@bag.python.org> Author: tarek.ziade Date: Sat Apr 11 17:18:16 2009 New Revision: 71481 Log: Blocked revisions 71480 via svnmerge ................ r71480 | tarek.ziade | 2009-04-11 17:17:04 +0200 (Sat, 11 Apr 2009) | 9 lines Merged revisions 71478 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71478 | tarek.ziade | 2009-04-11 17:14:17 +0200 (Sat, 11 Apr 2009) | 1 line testing a full check case ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sat Apr 11 17:18:47 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 11 Apr 2009 17:18:47 +0200 (CEST) Subject: [Python-checkins] r71482 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090411151847.841B81E4012@bag.python.org> Author: mark.dickinson Date: Sat Apr 11 17:18:47 2009 New Revision: 71482 Log: Add some explanatory comments to dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Sat Apr 11 17:18:47 2009 @@ -257,6 +257,8 @@ #endif +/* struct BCinfo is used to pass information from _Py_dg_strtod to bigcomp */ + typedef struct BCinfo BCinfo; struct BCinfo { @@ -268,6 +270,28 @@ #define Kmax 7 +/* struct Bigint is used to represent arbitrary-precision integers. These + integers are stored in sign-magnitude format, with the magnitude stored as + an array of base 2**32 digits. Bigints are always normalized: if x is a + Bigint then x->wds >= 1, and either x->wds == 1 or x[wds-1] is nonzero. + + The Bigint fields are as follows: + + - next is a header used by Balloc and Bfree to keep track of lists + of freed Bigints; it's also used for the linked list of + powers of 5 of the form 5**2**i used by pow5mult. + - k indicates which pool this Bigint was allocated from + - maxwds is the maximum number of words space was allocated for + (usually maxwds == 2**k) + - sign is 1 for negative Bigints, 0 for positive. The sign is unused + (ignored on inputs, set to 0 on outputs) in almost all operations + involving Bigints: a notable exception is the diff function, which + ignores signs on inputs but sets the sign of the output correctly. + - wds is the actual number of significant words + - x contains the vector of words (digits) for this Bigint, from least + significant (x[0]) to most significant (x[wds-1]). +*/ + struct Bigint { struct Bigint *next; @@ -277,8 +301,29 @@ typedef struct Bigint Bigint; +/* Memory management: memory is allocated from, and returned to, Kmax+1 pools + of memory, where pool k (0 <= k <= Kmax) is for Bigints b with b->maxwds == + 1 << k. These pools are maintained as linked lists, with freelist[k] + pointing to the head of the list for pool k. + + On allocation, if there's no free slot in the appropriate pool, MALLOC is + called to get more memory. This memory is not returned to the system until + Python quits. There's also a private memory pool that's allocated from + in preference to using MALLOC. + + For Bigints with more than (1 << Kmax) digits (which implies at least 1233 + decimal digits), memory is directly allocated using MALLOC, and freed using + FREE. + + XXX: it would be easy to bypass this memory-management system and + translate each call to Balloc into a call to PyMem_Malloc, and each + Bfree to PyMem_Free. Investigate whether this has any significant + performance on impact. */ + static Bigint *freelist[Kmax+1]; +/* Allocate space for a Bigint with up to 1<sign, (char *)&y->sign, \ y->wds*sizeof(Long) + 2*sizeof(int)) +/* Multiply a Bigint b by m and add a. Either modifies b in place and returns + a pointer to the modified b, or Bfrees b and returns a pointer to a copy. + On failure, return NULL. In this case, b will have been already freed. */ + static Bigint * multadd (Bigint *b, int m, int a) /* multiply by m and add a */ @@ -375,6 +426,12 @@ return b; } +/* convert a string s containing nd decimal digits (possibly containing a + decimal separator at position nd0, which is ignored) to a Bigint. This + function carries on where the parsing code in _Py_dg_strtod leaves off: on + entry, y9 contains the result of converting the first 9 digits. Returns + NULL on failure. */ + static Bigint * s2b (const char *s, int nd0, int nd, ULong y9, int dplen) @@ -411,6 +468,8 @@ return b; } +/* count leading 0 bits in the 32-bit integer x. */ + static int hi0bits (ULong x) @@ -441,6 +500,9 @@ return k; } +/* count trailing 0 bits in the 32-bit integer y, and shift y right by that + number of bits. */ + static int lo0bits (ULong *y) @@ -485,6 +547,8 @@ return k; } +/* convert a small nonnegative integer to a Bigint */ + static Bigint * i2b (int i) @@ -499,6 +563,9 @@ return b; } +/* multiply two Bigints. Returns a new Bigint, or NULL on failure. Ignores + the signs of a and b. */ + static Bigint * mult (Bigint *a, Bigint *b) @@ -588,8 +655,14 @@ return c; } +/* p5s is a linked list of powers of 5 of the form 5**(2**i), i >= 2 */ + static Bigint *p5s; +/* multiply the Bigint b by 5**k. Returns a pointer to the result, or NULL on + failure; if the returned pointer is distinct from b then the original + Bigint b will have been Bfree'd. Ignores the sign of b. */ + static Bigint * pow5mult (Bigint *b, int k) @@ -642,6 +715,10 @@ return b; } +/* shift a Bigint b left by k bits. Return a pointer to the shifted result, + or NULL on failure. If the returned pointer is distinct from b then the + original b will have been Bfree'd. Ignores the sign of b. */ + static Bigint * lshift (Bigint *b, int k) @@ -684,6 +761,9 @@ return b1; } +/* Do a three-way compare of a and b, returning -1 if a < b, 0 if a == b and + 1 if a > b. Ignores signs of a and b. */ + static int cmp (Bigint *a, Bigint *b) @@ -714,6 +794,10 @@ return 0; } +/* Take the difference of Bigints a and b, returning a new Bigint. Returns + NULL on failure. The signs of a and b are ignored, but the sign of the + result is set appropriately. */ + static Bigint * diff (Bigint *a, Bigint *b) @@ -792,6 +876,9 @@ return c; } +/* Given a positive normal double x, return the difference between x and the next + double up. Doesn't give correct results for subnormals. */ + static double ulp (U *x) @@ -805,6 +892,8 @@ return dval(&u); } +/* Convert a Bigint to a double plus an exponent */ + static double b2d (Bigint *a, int *e) @@ -845,6 +934,8 @@ return dval(&d); } +/* Convert a double to a Bigint plus an exponent. Return NULL on failure. */ + static Bigint * d2b (U *d, int *e, int *bits) @@ -895,6 +986,9 @@ #undef d0 #undef d1 +/* Compute the ratio of two Bigints, as a double. The result may have an + error of up to 2.5 ulps. */ + static double ratio (Bigint *a, Bigint *b) @@ -932,6 +1026,9 @@ #define Scale_Bit 0x10 #define n_bigtens 5 +/* case insensitive string match, for recognising 'inf[inity]' and + 'nan' strings. */ + static int match (const char **sp, char *t) @@ -963,6 +1060,10 @@ return rv & kmask; } +/* special case of Bigint division. The quotient is always in the range 0 <= + quotient < 10, and on entry the divisor S is normalized so that its top 4 + bits (28--31) are zero and bit 27 is set. */ + static int quorem (Bigint *b, Bigint *S) From python-checkins at python.org Sat Apr 11 17:39:25 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sat, 11 Apr 2009 17:39:25 +0200 (CEST) Subject: [Python-checkins] r71483 - python/branches/py3k/Modules/_io/bufferedio.c Message-ID: <20090411153925.657AD1E422C@bag.python.org> Author: antoine.pitrou Date: Sat Apr 11 17:39:24 2009 New Revision: 71483 Log: #5502: accelerate binary buffered IO (especially small operations). On a suggestion by Victor Stinner. Modified: python/branches/py3k/Modules/_io/bufferedio.c Modified: python/branches/py3k/Modules/_io/bufferedio.c ============================================================================== --- python/branches/py3k/Modules/_io/bufferedio.c (original) +++ python/branches/py3k/Modules/_io/bufferedio.c Sat Apr 11 17:39:24 2009 @@ -174,7 +174,7 @@ 0, /* tp_alloc */ 0, /* tp_new */ }; - + typedef struct { PyObject_HEAD @@ -183,6 +183,10 @@ int ok; /* Initialized? */ int readable; int writable; + + /* True if this is a vanilla Buffered object (rather than a user derived + class) *and* the raw stream is a vanilla FileIO object. */ + int fast_closed_checks; /* Absolute position inside the raw stream (-1 if unknown). */ Py_off_t abs_pos; @@ -268,6 +272,18 @@ return -1; \ } +#define IS_CLOSED(self) \ + (self->fast_closed_checks \ + ? _PyFileIO_closed(self->raw) \ + : BufferedIOMixin_closed(self)) + +#define CHECK_CLOSED(self, error_msg) \ + if (IS_CLOSED(self)) { \ + PyErr_SetString(PyExc_ValueError, error_msg); \ + return NULL; \ + } + + #define VALID_READ_BUFFER(self) \ (self->readable && self->read_end != -1) @@ -466,8 +482,8 @@ CHECK_INITIALIZED(self) return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL); } - - + + /* Forward decls */ static PyObject * _BufferedWriter_flush_unlocked(BufferedObject *, int); @@ -480,7 +496,11 @@ static PyObject * _BufferedReader_peek_unlocked(BufferedObject *self, Py_ssize_t); static PyObject * -_BufferedReader_read_unlocked(BufferedObject *self, Py_ssize_t); +_BufferedReader_read_all(BufferedObject *self); +static PyObject * +_BufferedReader_read_fast(BufferedObject *self, Py_ssize_t); +static PyObject * +_BufferedReader_read_generic(BufferedObject *self, Py_ssize_t); /* @@ -509,8 +529,8 @@ static Py_off_t _Buffered_raw_tell(BufferedObject *self) { - PyObject *res; Py_off_t n; + PyObject *res; res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL); if (res == NULL) return -1; @@ -604,10 +624,7 @@ PyObject *res; CHECK_INITIALIZED(self) - if (BufferedIOMixin_closed(self)) { - PyErr_SetString(PyExc_ValueError, "flush of closed file"); - return NULL; - } + CHECK_CLOSED(self, "flush of closed file") ENTER_BUFFERED(self) res = _BufferedWriter_flush_unlocked(self, 0); @@ -667,14 +684,23 @@ return NULL; } - if (BufferedIOMixin_closed(self)) { - PyErr_SetString(PyExc_ValueError, "read of closed file"); - return NULL; - } + CHECK_CLOSED(self, "read of closed file") - ENTER_BUFFERED(self) - res = _BufferedReader_read_unlocked(self, n); - LEAVE_BUFFERED(self) + if (n == -1) { + /* The number of bytes is unspecified, read until the end of stream */ + ENTER_BUFFERED(self) + res = _BufferedReader_read_all(self); + LEAVE_BUFFERED(self) + } + else { + res = _BufferedReader_read_fast(self, n); + if (res == Py_None) { + Py_DECREF(res); + ENTER_BUFFERED(self) + res = _BufferedReader_read_generic(self, n); + LEAVE_BUFFERED(self) + } + } return res; } @@ -775,35 +801,31 @@ Py_ssize_t n, written = 0; const char *start, *s, *end; - if (BufferedIOMixin_closed(self)) { - PyErr_SetString(PyExc_ValueError, "readline of closed file"); - return NULL; - } - - ENTER_BUFFERED(self) + CHECK_CLOSED(self, "readline of closed file") - /* First, try to find a line in the buffer */ + /* First, try to find a line in the buffer. This can run unlocked because + the calls to the C API are simple enough that they can't trigger + any thread switch. */ n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); if (limit >= 0 && n > limit) n = limit; start = self->buffer + self->pos; - end = start + n; - s = start; - while (s < end) { - if (*s++ == '\n') { - res = PyBytes_FromStringAndSize(start, s - start); - if (res != NULL) - self->pos += s - start; - goto end; - } + s = memchr(start, '\n', n); + if (s != NULL) { + res = PyBytes_FromStringAndSize(start, s - start + 1); + if (res != NULL) + self->pos += s - start + 1; + goto end_unlocked; } if (n == limit) { res = PyBytes_FromStringAndSize(start, n); if (res != NULL) self->pos += n; - goto end; + goto end_unlocked; } + ENTER_BUFFERED(self) + /* Now we try to get some more from the raw stream */ if (self->writable) { res = _BufferedWriter_flush_unlocked(self, 1); @@ -875,6 +897,7 @@ end: LEAVE_BUFFERED(self) +end_unlocked: Py_XDECREF(chunks); return res; } @@ -918,23 +941,26 @@ if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) { return NULL; } - if (whence < 0 || whence > 2) { PyErr_Format(PyExc_ValueError, "whence must be between 0 and 2, not %d", whence); return NULL; } + + CHECK_CLOSED(self, "seek of closed file") + target = PyNumber_AsOff_t(targetobj, PyExc_ValueError); if (target == -1 && PyErr_Occurred()) return NULL; - ENTER_BUFFERED(self) - if (whence != 2 && self->readable) { Py_off_t current, avail; /* Check if seeking leaves us inside the current buffer, - so as to return quickly if possible. + so as to return quickly if possible. Also, we needn't take the + lock in this fast path. Don't know how to do that when whence == 2, though. */ + /* NOTE: RAW_TELL() can release the GIL but the object is in a stable + state at this point. */ current = RAW_TELL(self); avail = READAHEAD(self); if (avail > 0) { @@ -945,12 +971,13 @@ offset = target; if (offset >= -self->pos && offset <= avail) { self->pos += offset; - res = PyLong_FromOff_t(current - avail + offset); - goto end; + return PyLong_FromOff_t(current - avail + offset); } } } + ENTER_BUFFERED(self) + /* Fallback: invoke raw seek() method and clear buffer */ if (self->writable) { res = _BufferedWriter_flush_unlocked(self, 0); @@ -1094,6 +1121,9 @@ return -1; _BufferedReader_reset_buf(self); + self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type && + Py_TYPE(raw) == &PyFileIO_Type); + self->ok = 1; return 0; } @@ -1150,93 +1180,107 @@ } static PyObject * -_BufferedReader_read_unlocked(BufferedObject *self, Py_ssize_t n) +_BufferedReader_read_all(BufferedObject *self) { - PyObject *data, *res = NULL; - Py_ssize_t current_size, remaining, written; - char *out; + Py_ssize_t current_size; + PyObject *res, *data = NULL; + PyObject *chunks = PyList_New(0); - /* Special case for when the number of bytes to read is unspecified. */ - if (n == -1) { - PyObject *chunks = PyList_New(0); - if (chunks == NULL) - return NULL; + if (chunks == NULL) + return NULL; - /* First copy what we have in the current buffer. */ - current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); - data = NULL; - if (current_size) { - data = PyBytes_FromStringAndSize( - self->buffer + self->pos, current_size); - if (data == NULL) { - Py_DECREF(chunks); - return NULL; - } + /* First copy what we have in the current buffer. */ + current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); + if (current_size) { + data = PyBytes_FromStringAndSize( + self->buffer + self->pos, current_size); + if (data == NULL) { + Py_DECREF(chunks); + return NULL; } - _BufferedReader_reset_buf(self); - /* We're going past the buffer's bounds, flush it */ - if (self->writable) { - res = _BufferedWriter_flush_unlocked(self, 1); - if (res == NULL) { + } + _BufferedReader_reset_buf(self); + /* We're going past the buffer's bounds, flush it */ + if (self->writable) { + res = _BufferedWriter_flush_unlocked(self, 1); + if (res == NULL) { + Py_DECREF(chunks); + return NULL; + } + Py_CLEAR(res); + } + while (1) { + if (data) { + if (PyList_Append(chunks, data) < 0) { + Py_DECREF(data); Py_DECREF(chunks); return NULL; } - Py_CLEAR(res); + Py_DECREF(data); } - while (1) { - if (data) { - if (PyList_Append(chunks, data) < 0) { - Py_DECREF(data); - Py_DECREF(chunks); - return NULL; - } - Py_DECREF(data); - } - /* Read until EOF or until read() would block. */ - data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL); - if (data == NULL) { + /* Read until EOF or until read() would block. */ + data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL); + if (data == NULL) { + Py_DECREF(chunks); + return NULL; + } + if (data != Py_None && !PyBytes_Check(data)) { + Py_DECREF(data); + Py_DECREF(chunks); + PyErr_SetString(PyExc_TypeError, "read() should return bytes"); + return NULL; + } + if (data == Py_None || PyBytes_GET_SIZE(data) == 0) { + if (current_size == 0) { Py_DECREF(chunks); - return NULL; + return data; } - if (data != Py_None && !PyBytes_Check(data)) { + else { + res = _PyBytes_Join(_PyIO_empty_bytes, chunks); Py_DECREF(data); Py_DECREF(chunks); - PyErr_SetString(PyExc_TypeError, "read() should return bytes"); - return NULL; - } - if (data == Py_None || PyBytes_GET_SIZE(data) == 0) { - if (current_size == 0) { - Py_DECREF(chunks); - return data; - } - else { - res = _PyBytes_Join(_PyIO_empty_bytes, chunks); - Py_DECREF(data); - Py_DECREF(chunks); - return res; - } + return res; } - current_size += PyBytes_GET_SIZE(data); - if (self->abs_pos != -1) - self->abs_pos += PyBytes_GET_SIZE(data); } + current_size += PyBytes_GET_SIZE(data); + if (self->abs_pos != -1) + self->abs_pos += PyBytes_GET_SIZE(data); } +} + +/* Read n bytes from the buffer if it can, otherwise return None. + This function is simple enough that it can run unlocked. */ +static PyObject * +_BufferedReader_read_fast(BufferedObject *self, Py_ssize_t n) +{ + Py_ssize_t current_size; - /* The number of bytes to read is specified, return at most n bytes. */ current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); if (n <= current_size) { /* Fast path: the data to read is fully buffered. */ - res = PyBytes_FromStringAndSize(self->buffer + self->pos, n); - if (res == NULL) - goto error; - self->pos += n; + PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n); + if (res != NULL) + self->pos += n; return res; } + Py_RETURN_NONE; +} + +/* Generic read function: read from the stream until enough bytes are read, + * or until an EOF occurs or until read() would block. + */ +static PyObject * +_BufferedReader_read_generic(BufferedObject *self, Py_ssize_t n) +{ + PyObject *res = NULL; + Py_ssize_t current_size, remaining, written; + char *out; + + current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); + if (n <= current_size) + return _BufferedReader_read_fast(self, n); - /* Slow path: read from the stream until enough bytes are read, - * or until an EOF occurs or until read() would block. - */ res = PyBytes_FromStringAndSize(NULL, n); if (res == NULL) goto error; @@ -1479,6 +1523,9 @@ _BufferedWriter_reset_buf(self); self->pos = 0; + self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type && + Py_TYPE(raw) == &PyFileIO_Type); + self->ok = 1; return 0; } @@ -1583,7 +1630,7 @@ return NULL; } - if (BufferedIOMixin_closed(self)) { + if (IS_CLOSED(self)) { PyErr_SetString(PyExc_ValueError, "write to closed file"); PyBuffer_Release(&buf); return NULL; @@ -2066,6 +2113,9 @@ _BufferedWriter_reset_buf(self); self->pos = 0; + self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type && + Py_TYPE(raw) == &PyFileIO_Type); + self->ok = 1; return 0; } From python-checkins at python.org Sat Apr 11 17:57:34 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 11 Apr 2009 17:57:34 +0200 (CEST) Subject: [Python-checkins] r71484 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090411155734.650891E41F5@bag.python.org> Author: mark.dickinson Date: Sat Apr 11 17:57:34 2009 New Revision: 71484 Log: Treat Check_FLT_ROUNDS as undefined. It looks as though it's not used consistently throughout dtoa.c anyway. Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Sat Apr 11 17:57:34 2009 @@ -104,19 +104,6 @@ * for 0 <= k <= 22). */ -/* - * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 - * and strtod and dtoa should round accordingly. Unless Trust_FLT_ROUNDS - * is also #defined, fegetround() will be queried for the rounding mode. - * Note that both FLT_ROUNDS and fegetround() are specified by the C99 - * standard (and are specified to be consistent, with fesetround() - * affecting the value of FLT_ROUNDS), but that some (Linux) systems - * do not work correctly in this regard, so using fegetround() is more - * portable than using FLT_FOUNDS directly. - * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 - * and Honor_FLT_ROUNDS is not #defined. - */ - /* Linking of Python's #defines to Gay's #defines starts here. */ #include "Python.h" @@ -1879,19 +1866,8 @@ else { aadj *= 0.5; aadj1 = bc.dsign ? aadj : -aadj; -#ifdef Check_FLT_ROUNDS - switch(bc.rounding) { - case 2: /* towards +infinity */ - aadj1 -= 0.5; - break; - case 0: /* towards 0 */ - case 3: /* towards -infinity */ - aadj1 += 0.5; - } -#else if (Flt_Rounds == 0) aadj1 += 0.5; -#endif /*Check_FLT_ROUNDS*/ } y = word0(&rv) & Exp_mask; @@ -2219,11 +2195,7 @@ if (mode < 0 || mode > 9) mode = 0; -#ifdef Check_FLT_ROUNDS - try_quick = Rounding == 1; -#else try_quick = 1; -#endif if (mode > 5) { mode -= 4; @@ -2374,13 +2346,6 @@ for(i = 1;; i++, dval(&u) *= 10.) { L = (Long)(dval(&u) / ds); dval(&u) -= L*ds; -#ifdef Check_FLT_ROUNDS - /* If FLT_ROUNDS == 2, L will usually be high by 1 */ - if (dval(&u) < 0) { - L--; - dval(&u) += ds; - } -#endif *s++ = '0' + (int)L; if (!dval(&u)) { break; From buildbot at python.org Sat Apr 11 18:02:42 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 11 Apr 2009 16:02:42 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090411160242.F212B1E4039@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/513 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: nick.coghlan,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_importlib test_posix Traceback (most recent call last): File "./Lib/test/regrtest.py", line 620, in runtest_inner File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_importlib.py", line 6, in test_main run_unittest(importlib.test.test_suite('importlib.test')) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/__init__.py", line 22, in test_suite package_tests = getattr(sys.modules[package_name], 'test_suite')() File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/source/__init__.py", line 8, in test_suite return importlib.test.test_suite('importlib.test.source', directory) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/__init__.py", line 16, in test_suite __import__(module_name, level=0) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/source/test_case_sensitivity.py", line 12, in class CaseSensitivityTest(unittest.TestCase): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/util.py", line 13, in case_insensitive_tests original_name = os.listdir('.')[0] IndexError: list index out of range ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 249, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 143, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From buildbot at python.org Sat Apr 11 18:09:26 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 11 Apr 2009 16:09:26 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 3.0 Message-ID: <20090411160926.A252D1E405A@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%203.0/builds/259 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: nick.coghlan BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Sat Apr 11 18:12:23 2009 From: python-checkins at python.org (andrew.kuchling) Date: Sat, 11 Apr 2009 18:12:23 +0200 (CEST) Subject: [Python-checkins] r71485 - python/trunk/Doc/whatsnew/2.7.rst Message-ID: <20090411161223.BF22C1E4012@bag.python.org> Author: andrew.kuchling Date: Sat Apr 11 18:12:23 2009 New Revision: 71485 Log: Add various items Modified: python/trunk/Doc/whatsnew/2.7.rst Modified: python/trunk/Doc/whatsnew/2.7.rst ============================================================================== --- python/trunk/Doc/whatsnew/2.7.rst (original) +++ python/trunk/Doc/whatsnew/2.7.rst Sat Apr 11 18:12:23 2009 @@ -88,8 +88,25 @@ Some smaller changes made to the core Python language are: +* The string :method:`format` method now supports automatic numbering + of the replacement fields. This makes using :meth:`format` + more closely resemble using ``%s`` formatting:: + + >>> '{}:{}:{}'.format(2009, 04, 'Sunday') + '2009:4:Sunday' + >>> '{}:{}:{day}'.format(2009, 4, day='Sunday') + '2009:4:Sunday' + + The auto-numbering takes the fields from left to right, so the first + ``{...}`` specifier will use the first argument to :meth:`format`, + the next specifier will use the next argument, and so on. You can't + mix auto-numbering and explicit numbering -- either number all of + your specifier fields or none of them -- but you can mix + auto-numbering and named fields, as in the second example above. + (Contributed by XXX; :issue`5237`.) + * The :func:`int` and :func:`long` types gained a ``bit_length`` - method that returns the number of bits necessary to represent +'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' method that returns the number of bits necessary to represent its argument in binary:: >>> n = 37 @@ -106,7 +123,7 @@ (Contributed by Fredrik Johansson and Victor Stinner; :issue:`3439`.) * The :class:`bytearray` type's :meth:`translate` method will - now accept None as its first argument. (Fixed by Georg Brandl; + now accept ``None`` as its first argument. (Fixed by Georg Brandl; :issue:`4759`.) .. ====================================================================== @@ -201,7 +218,7 @@ management protocol, so you can write ``with bz2.BZ2File(...) as f: ...``. (Contributed by Hagen Fuerstenau; :issue:`3860`.) -* A new :class:`Counter` class in the :mod:`collections` module is +* New class: the :class:`Counter` class in the :mod:`collections` module is useful for tallying data. :class:`Counter` instances behave mostly like dictionaries but return zero for missing keys instead of raising a :exc:`KeyError`:: @@ -236,7 +253,7 @@ Contributed by Raymond Hettinger; :issue:`1696199`. The :class:`namedtuple` class now has an optional *rename* parameter. - If *rename* is True, field names that are invalid because they've + If *rename* is true, field names that are invalid because they've been repeated or that aren't legal Python identifiers will be renamed to legal names that are derived from the field's position within the list of fields: @@ -247,8 +264,13 @@ (Added by Raymond Hettinger; :issue:`1818`.) + The :class:`deque` data type now exposes its maximum length as the + read-only :attr:`maxlen` attribute. (Added by Raymond Hettinger.) + * In Distutils, :func:`distutils.sdist.add_defaults` now uses *package_dir* and *data_files* to create the MANIFEST file. + :mod:`distutils.sysconfig` will now read the :envvar:`AR` + environment variable. It is no longer mandatory to store clear-text passwords in the :file:`.pypirc` file when registering and uploading packages to PyPI. As long @@ -256,6 +278,12 @@ prompt for the password if not present. (Added by Tarek Ziade, based on an initial contribution by Nathan Van Gheem; :issue:`4394`.) + A Distutils setup can now specify that a C extension is optional by + setting the *optional* option setting to true. If this optional is + supplied, failure to build the extension will not abort the build + process, but instead simply not install the failing extension. + (Contributed by XXX; :issue:`5583`.) + * New method: the :class:`Decimal` class gained a :meth:`from_float` class method that performs an exact conversion of a floating-point number to a :class:`Decimal`. @@ -267,8 +295,8 @@ ``Decimal('0.1000000000000000055511151231257827021181583404541015625')``. (Implemented by Raymond Hettinger; :issue:`4796`.) -* A new function in the :mod:`gc` module, :func:`is_tracked`, returns - True if a given instance is tracked by the garbage collector, False +* New function: the :mod:`gc` module's :func:`is_tracked` returns + true if a given instance is tracked by the garbage collector, false otherwise. (Contributed by Antoine Pitrou; :issue:`4688`.) * The :mod:`gzip` module's :class:`GzipFile` now supports the context @@ -284,7 +312,7 @@ * New function: ``itertools.compress(*data*, *selectors*)`` takes two iterators. Elements of *data* are returned if the corresponding - value in *selectors* is True:: + value in *selectors* is true:: itertools.compress('ABCDEF', [1,0,1,0,1,1]) => A, C, E, F @@ -332,8 +360,12 @@ uses. You can now do ``help('<<')`` or ``help('@')``, for example. (Contributed by David Laban; :issue:`4739`.) -* A new function in the :mod:`subprocess` module, - :func:`check_output`, runs a command with a specified set of arguments +* The :mod:`re` module's :func:`split`, :func:`sub`, and :func:`subn` + now accept an optional *flags* argument, for consistency with the + other functions in the module. (Added by Gregory P. Smith.) + +* New function: the :mod:`subprocess` module's + :func:`check_output` runs a command with a specified set of arguments and returns the command's output as a string when the command runs without error, or raises a :exc:`CalledProcessError` exception otherwise. @@ -349,13 +381,25 @@ (Contributed by Gregory P. Smith.) +* New function: :func:`is_declared_global` in the :mod:`symtable` module + returns true for variables that are explicitly declared to be global, + false for ones that are implicitly global. + (Contributed by Jeremy Hylton.) + * The ``sys.version_info`` value is now a named tuple, with attributes named ``major``, ``minor``, ``micro``, ``releaselevel``, and ``serial``. (Contributed by Ross Light; :issue:`4285`.) +* The :mod:`threading` module's :meth:`Event.wait` method now returns + the internal flag on exit. This means the method will usually + return true because :meth:`wait` is supposed to block until the + internal flag becomes true. The return value will only be false if + a timeout was provided and the operation timed out. + (Contributed by XXX; :issue:`1674032`.) + * The :mod:`unittest` module was enhanced in several ways. - The progress messages will now print 'x' for expected failures - and 'u' for unexpected successes when run in its verbose mode. + The progress messages will now show 'x' for expected failures + and 'u' for unexpected successes when run in verbose mode. (Contributed by Benjamin Peterson.) Test cases can raise the :exc:`SkipTest` exception to skip a test. (:issue:`1034053`.) @@ -443,7 +487,37 @@ importlib: Importing Modules ------------------------------ -XXX write this +Python 3.1 includes the :mod:`importlib` package, a re-implementation +of the logic underlying Python's :keyword:`import` statement. +:mod:`importlib` is useful for implementors of Python interpreters and +to user who wish to write new importers that can participate in the +import process. Python 2.7 doesn't contain the complete +:mod:`importlib` package, but instead has a tiny subset that contains +a single function, :func:`import_module`. + +``import_module(*name*, *package*=None)`` imports a module. *name* is +a string containing the module or package's name. It's possible to do +relative imports by providing a string that begins with a ``.`` +character, such as ``..utils.errors``. For relative imports, the +*package* argument must be provided and is the name of the package that +will be used as the anchor for +the relative import. :func:`import_module` both inserts the imported +module into ``sys.modules`` and returns the module object. + +Here are some examples:: + + >>> from importlib import import_module + >>> anydbm = import_module('anydbm') # Standard absolute import + >>> anydbm + + >>> # Relative import + >>> sysconfig = import_module('..sysconfig', 'distutils.command') + >>> sysconfig + + +:mod:`importlib` was implemented by Brett Cannon and introduced in +Python 3.1. + ttk: Themed Widgets for Tk -------------------------- From python-checkins at python.org Sat Apr 11 18:18:14 2009 From: python-checkins at python.org (andrew.kuchling) Date: Sat, 11 Apr 2009 18:18:14 +0200 (CEST) Subject: [Python-checkins] r71486 - python/trunk/Doc/distutils/setupscript.rst Message-ID: <20090411161814.D07931E4012@bag.python.org> Author: andrew.kuchling Date: Sat Apr 11 18:18:14 2009 New Revision: 71486 Log: Re-word Modified: python/trunk/Doc/distutils/setupscript.rst Modified: python/trunk/Doc/distutils/setupscript.rst ============================================================================== --- python/trunk/Doc/distutils/setupscript.rst (original) +++ python/trunk/Doc/distutils/setupscript.rst Sat Apr 11 18:18:14 2009 @@ -334,9 +334,9 @@ There are still some other options which can be used to handle special cases. -The :option:`optional` option is a boolean; if it is true, that specifies that -a build failure in the extension should not abort the build process, but simply -not install the failing extension. +The :option:`optional` option is a boolean; if it is true, +a build failure in the extension will not abort the build process, but +instead simply not install the failing extension. The :option:`extra_objects` option is a list of object files to be passed to the linker. These files must not have extensions, as the default extension for the From python-checkins at python.org Sat Apr 11 18:47:22 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 11 Apr 2009 18:47:22 +0200 (CEST) Subject: [Python-checkins] r71487 - python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt Message-ID: <20090411164722.DAE191E4012@bag.python.org> Author: mark.dickinson Date: Sat Apr 11 18:47:22 2009 New Revision: 71487 Log: Some additional testcases for repr, chosen to provoke failure on systems where the FPU is set to 64-bit rounding precision. Modified: python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt Modified: python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt (original) +++ python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt Sat Apr 11 18:47:22 2009 @@ -347,6 +347,15 @@ %r 0.999e-4 -> 9.99e-05 %r 1e-5 -> 1e-05 +-- some values that are designed to fail if the FPU rounding +-- precision is 64-bits. +%r 8.72293771110361e+25 -> 8.72293771110361e+25 +%r 7.47005307342313e+26 -> 7.47005307342313e+26 +%r 2.86438000439698e+28 -> 2.86438000439698e+28 +%r 8.89142905246179e+28 -> 8.89142905246179e+28 +%r 3.08578087079232e+35 -> 3.08578087079232e+35 + + -- str formatting. Result always includes decimal point and at -- least one digit after the point, or an exponent. %s 0 -> 0.0 From python-checkins at python.org Sat Apr 11 18:55:09 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 11 Apr 2009 18:55:09 +0200 (CEST) Subject: [Python-checkins] r71488 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090411165509.023001E404A@bag.python.org> Author: mark.dickinson Date: Sat Apr 11 18:55:08 2009 New Revision: 71488 Log: Fix declaration style Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Sat Apr 11 18:55:08 2009 @@ -312,8 +312,7 @@ /* Allocate space for a Bigint with up to 1<k > Kmax) @@ -365,8 +363,7 @@ On failure, return NULL. In this case, b will have been already freed. */ static Bigint * -multadd -(Bigint *b, int m, int a) /* multiply by m and add a */ +multadd(Bigint *b, int m, int a) /* multiply by m and add a */ { int i, wds; #ifdef ULLong @@ -420,8 +417,7 @@ NULL on failure. */ static Bigint * -s2b -(const char *s, int nd0, int nd, ULong y9, int dplen) +s2b(const char *s, int nd0, int nd, ULong y9, int dplen) { Bigint *b; int i, k; @@ -458,8 +454,7 @@ /* count leading 0 bits in the 32-bit integer x. */ static int -hi0bits -(ULong x) +hi0bits(ULong x) { int k = 0; @@ -491,8 +486,7 @@ number of bits. */ static int -lo0bits -(ULong *y) +lo0bits(ULong *y) { int k; ULong x = *y; @@ -537,8 +531,7 @@ /* convert a small nonnegative integer to a Bigint */ static Bigint * -i2b -(int i) +i2b(int i) { Bigint *b; @@ -554,8 +547,7 @@ the signs of a and b. */ static Bigint * -mult -(Bigint *a, Bigint *b) +mult(Bigint *a, Bigint *b) { Bigint *c; int k, wa, wb, wc; @@ -651,8 +643,7 @@ Bigint b will have been Bfree'd. Ignores the sign of b. */ static Bigint * -pow5mult -(Bigint *b, int k) +pow5mult(Bigint *b, int k) { Bigint *b1, *p5, *p51; int i; @@ -707,8 +698,7 @@ original b will have been Bfree'd. Ignores the sign of b. */ static Bigint * -lshift -(Bigint *b, int k) +lshift(Bigint *b, int k) { int i, k1, n, n1; Bigint *b1; @@ -752,8 +742,7 @@ 1 if a > b. Ignores signs of a and b. */ static int -cmp -(Bigint *a, Bigint *b) +cmp(Bigint *a, Bigint *b) { ULong *xa, *xa0, *xb, *xb0; int i, j; @@ -786,8 +775,7 @@ result is set appropriately. */ static Bigint * -diff -(Bigint *a, Bigint *b) +diff(Bigint *a, Bigint *b) { Bigint *c; int i, wa, wb; @@ -867,8 +855,7 @@ double up. Doesn't give correct results for subnormals. */ static double -ulp -(U *x) +ulp(U *x) { Long L; U u; @@ -882,8 +869,7 @@ /* Convert a Bigint to a double plus an exponent */ static double -b2d -(Bigint *a, int *e) +b2d(Bigint *a, int *e) { ULong *xa, *xa0, w, y, z; int k; @@ -924,8 +910,7 @@ /* Convert a double to a Bigint plus an exponent. Return NULL on failure. */ static Bigint * -d2b -(U *d, int *e, int *bits) +d2b(U *d, int *e, int *bits) { Bigint *b; int de, k; @@ -977,8 +962,7 @@ error of up to 2.5 ulps. */ static double -ratio -(Bigint *a, Bigint *b) +ratio(Bigint *a, Bigint *b) { U da, db; int k, ka, kb; @@ -1017,8 +1001,7 @@ 'nan' strings. */ static int -match -(const char **sp, char *t) +match(const char **sp, char *t) { int c, d; const char *s = *sp; @@ -1052,8 +1035,7 @@ bits (28--31) are zero and bit 27 is set. */ static int -quorem -(Bigint *b, Bigint *S) +quorem(Bigint *b, Bigint *S) { int n; ULong *bx, *bxe, q, *sx, *sxe; @@ -1151,8 +1133,7 @@ /* return 0 on success, -1 on failure */ static int -bigcomp -(U *rv, const char *s0, BCinfo *bc) +bigcomp(U *rv, const char *s0, BCinfo *bc) { Bigint *b, *d; int b2, bbits, d2, dd, dig, dsign, i, j, nd, nd0, p2, p5, speccase; From python-checkins at python.org Sat Apr 11 18:56:56 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 11 Apr 2009 18:56:56 +0200 (CEST) Subject: [Python-checkins] r71489 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090411165656.9BABE1E4012@bag.python.org> Author: mark.dickinson Date: Sat Apr 11 18:56:56 2009 New Revision: 71489 Log: Fix a couple more declarations Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Sat Apr 11 18:56:56 2009 @@ -1305,8 +1305,7 @@ } double -_Py_dg_strtod -(const char *s00, char **se) +_Py_dg_strtod(const char *s00, char **se) { int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1, error; int esign, i, j, k, nd, nd0, nf, nz, nz0, sign; @@ -2023,8 +2022,8 @@ call to _Py_dg_freedtoa. */ char * -_Py_dg_dtoa -(double dd, int mode, int ndigits, int *decpt, int *sign, char **rve) +_Py_dg_dtoa(double dd, int mode, int ndigits, + int *decpt, int *sign, char **rve) { /* Arguments ndigits, decpt, sign are similar to those of ecvt and fcvt; trailing zeros are suppressed from From buildbot at python.org Sat Apr 11 19:27:08 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 11 Apr 2009 17:27:08 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 2.6 Message-ID: <20090411172709.47A0E1E4039@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%202.6/builds/246 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Sat Apr 11 19:52:56 2009 From: python-checkins at python.org (r.david.murray) Date: Sat, 11 Apr 2009 19:52:56 +0200 (CEST) Subject: [Python-checkins] r71490 - python/trunk/Lib/test/test_asyncore.py Message-ID: <20090411175256.9D03D1E4039@bag.python.org> Author: r.david.murray Date: Sat Apr 11 19:52:56 2009 New Revision: 71490 Log: Make test_asyncore tests match code changes introduced by the fix to Issue1161031, refactoring the test to simplify it in the process. Modified: python/trunk/Lib/test/test_asyncore.py Modified: python/trunk/Lib/test/test_asyncore.py ============================================================================== --- python/trunk/Lib/test/test_asyncore.py (original) +++ python/trunk/Lib/test/test_asyncore.py Sat Apr 11 19:52:56 2009 @@ -115,12 +115,24 @@ def test_readwrite(self): # Check that correct methods are called by readwrite() + attributes = ('read', 'expt', 'write', 'closed', 'error_handled') + + expected = ( + (select.POLLIN, 'read'), + (select.POLLPRI, 'expt'), + (select.POLLOUT, 'write'), + (select.POLLERR, 'closed'), + (select.POLLHUP, 'closed'), + (select.POLLNVAL, 'closed'), + ) + class testobj: def __init__(self): self.read = False self.write = False self.closed = False self.expt = False + self.error_handled = False def handle_read_event(self): self.read = True @@ -137,54 +149,25 @@ def handle_error(self): self.error_handled = True - for flag in (select.POLLIN, select.POLLPRI): + for flag, expectedattr in expected: tobj = testobj() - self.assertEqual(tobj.read, False) + self.assertEqual(getattr(tobj, expectedattr), False) asyncore.readwrite(tobj, flag) - self.assertEqual(tobj.read, True) - # check that ExitNow exceptions in the object handler method - # bubbles all the way up through asyncore readwrite call - tr1 = exitingdummy() - self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, flag) - - # check that an exception other than ExitNow in the object handler - # method causes the handle_error method to get called - tr2 = crashingdummy() - asyncore.readwrite(tr2, flag) - self.assertEqual(tr2.error_handled, True) - - tobj = testobj() - self.assertEqual(tobj.write, False) - asyncore.readwrite(tobj, select.POLLOUT) - self.assertEqual(tobj.write, True) - - # check that ExitNow exceptions in the object handler method - # bubbles all the way up through asyncore readwrite call - tr1 = exitingdummy() - self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, - select.POLLOUT) - - # check that an exception other than ExitNow in the object handler - # method causes the handle_error method to get called - tr2 = crashingdummy() - asyncore.readwrite(tr2, select.POLLOUT) - self.assertEqual(tr2.error_handled, True) - - for flag in (select.POLLERR, select.POLLHUP, select.POLLNVAL): - tobj = testobj() - self.assertEqual((tobj.expt, tobj.closed)[flag == select.POLLHUP], False) - asyncore.readwrite(tobj, flag) - self.assertEqual((tobj.expt, tobj.closed)[flag == select.POLLHUP], True) + # Only the attribute modified by the routine we expect to be + # called should be True. + for attr in attributes: + self.assertEqual(getattr(tobj, attr), attr==expectedattr) # check that ExitNow exceptions in the object handler method - # bubbles all the way up through asyncore readwrite calls + # bubbles all the way up through asyncore readwrite call tr1 = exitingdummy() self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, flag) # check that an exception other than ExitNow in the object handler # method causes the handle_error method to get called tr2 = crashingdummy() + self.assertEqual(tr2.error_handled, False) asyncore.readwrite(tr2, flag) self.assertEqual(tr2.error_handled, True) From python-checkins at python.org Sat Apr 11 20:18:17 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 11 Apr 2009 20:18:17 +0200 (CEST) Subject: [Python-checkins] r71491 - python/branches/py3k/Doc/library/json.rst Message-ID: <20090411181817.3762A1E40D9@bag.python.org> Author: georg.brandl Date: Sat Apr 11 20:18:16 2009 New Revision: 71491 Log: Remove mentions of "long". Modified: python/branches/py3k/Doc/library/json.rst Modified: python/branches/py3k/Doc/library/json.rst ============================================================================== --- python/branches/py3k/Doc/library/json.rst (original) +++ python/branches/py3k/Doc/library/json.rst Sat Apr 11 20:18:16 2009 @@ -118,7 +118,7 @@ file-like object). If *skipkeys* is ``True`` (default: ``False``), then dict keys that are not - of a basic type (:class:`str`, :class:`unicode`, :class:`int`, :class:`long`, + of a basic type (:class:`str`, :class:`unicode`, :class:`int`, :class:`float`, :class:`bool`, ``None``) will be skipped instead of raising a :exc:`TypeError`. @@ -232,7 +232,7 @@ +---------------+-------------------+ | string | unicode | +---------------+-------------------+ - | number (int) | int, long | + | number (int) | int | +---------------+-------------------+ | number (real) | float | +---------------+-------------------+ @@ -304,7 +304,7 @@ +-------------------+---------------+ | str, unicode | string | +-------------------+---------------+ - | int, long, float | number | + | int, float | number | +-------------------+---------------+ | True | true | +-------------------+---------------+ @@ -319,7 +319,7 @@ (to raise :exc:`TypeError`). If *skipkeys* is ``False`` (the default), then it is a :exc:`TypeError` to - attempt encoding of keys that are not str, int, long, float or None. If + attempt encoding of keys that are not str, int, float or None. If *skipkeys* is ``True``, such items are simply skipped. If *ensure_ascii* is ``True`` (the default), the output is guaranteed to be From python-checkins at python.org Sat Apr 11 20:19:27 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 11 Apr 2009 20:19:27 +0200 (CEST) Subject: [Python-checkins] r71492 - python/trunk/Doc/whatsnew/2.7.rst Message-ID: <20090411181927.665211E401B@bag.python.org> Author: georg.brandl Date: Sat Apr 11 20:19:27 2009 New Revision: 71492 Log: Take credit for a patch of mine. Modified: python/trunk/Doc/whatsnew/2.7.rst Modified: python/trunk/Doc/whatsnew/2.7.rst ============================================================================== --- python/trunk/Doc/whatsnew/2.7.rst (original) +++ python/trunk/Doc/whatsnew/2.7.rst Sat Apr 11 20:19:27 2009 @@ -106,7 +106,7 @@ (Contributed by XXX; :issue`5237`.) * The :func:`int` and :func:`long` types gained a ``bit_length`` -'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' method that returns the number of bits necessary to represent + method that returns the number of bits necessary to represent its argument in binary:: >>> n = 37 @@ -282,7 +282,7 @@ setting the *optional* option setting to true. If this optional is supplied, failure to build the extension will not abort the build process, but instead simply not install the failing extension. - (Contributed by XXX; :issue:`5583`.) + (Contributed by Georg Brandl; :issue:`5583`.) * New method: the :class:`Decimal` class gained a :meth:`from_float` class method that performs an exact conversion From python-checkins at python.org Sat Apr 11 21:16:28 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Apr 2009 21:16:28 +0200 (CEST) Subject: [Python-checkins] r71493 - python/branches/py3k Message-ID: <20090411191628.17F2B1E4039@bag.python.org> Author: benjamin.peterson Date: Sat Apr 11 21:16:27 2009 New Revision: 71493 Log: Blocked revisions 70807,70986,70993-70994,71127,71300,71302,71361,71365,71367,71370,71377,71380,71385,71389,71392,71419,71430,71435,71448,71462,71490 via svnmerge ........ r70807 | jeremy.hylton | 2009-03-31 08:31:00 -0500 (Tue, 31 Mar 2009) | 2 lines Update quicktest to match Python 3 branch ........ r70986 | raymond.hettinger | 2009-04-01 15:50:58 -0500 (Wed, 01 Apr 2009) | 1 line Add link to an alternative generator with a long-period. ........ r70993 | georg.brandl | 2009-04-01 16:05:44 -0500 (Wed, 01 Apr 2009) | 1 line Add NEWS item. ........ r70994 | georg.brandl | 2009-04-01 16:06:30 -0500 (Wed, 01 Apr 2009) | 1 line Revert accidental checkin. ........ r71127 | raymond.hettinger | 2009-04-04 03:46:58 -0500 (Sat, 04 Apr 2009) | 1 line Replace the localized min/max calls with normal if/else ........ r71300 | gregory.p.smith | 2009-04-05 18:48:26 -0500 (Sun, 05 Apr 2009) | 2 lines news entry for r71299. ........ r71302 | jack.diederich | 2009-04-05 21:08:44 -0500 (Sun, 05 Apr 2009) | 1 line test the telnetlib.Telnet interface more thoroughly ........ r71361 | benjamin.peterson | 2009-04-07 10:15:04 -0500 (Tue, 07 Apr 2009) | 1 line fix syntax tests after formatting change ........ r71365 | benjamin.peterson | 2009-04-07 10:52:05 -0500 (Tue, 07 Apr 2009) | 1 line fix since difference formating of SyntaxErrors ........ r71367 | benjamin.peterson | 2009-04-07 11:03:04 -0500 (Tue, 07 Apr 2009) | 1 line revert unrelated change to test_telnetlib ........ r71370 | vinay.sajip | 2009-04-07 12:18:24 -0500 (Tue, 07 Apr 2009) | 1 line Issue #5695: Minor tweak to improve the code as suggested by Brett Cannon and as implemented in the Py3K branch. ........ r71377 | jack.diederich | 2009-04-07 15:22:59 -0500 (Tue, 07 Apr 2009) | 1 line eliminate more race conditions in telnetlib tests ........ r71380 | raymond.hettinger | 2009-04-07 16:43:51 -0500 (Tue, 07 Apr 2009) | 1 line Fix make.bat to match makefile changes ........ r71385 | jack.diederich | 2009-04-07 18:56:57 -0500 (Tue, 07 Apr 2009) | 4 lines - Make timing assertions very generous (a la test_timeout.py) - Break the gc cycle in negotiation tests - test the different guarantees of read_lazy and read_very_lazy ........ r71389 | raymond.hettinger | 2009-04-08 00:39:38 -0500 (Wed, 08 Apr 2009) | 1 line Add docstrings. ........ r71392 | raymond.hettinger | 2009-04-08 03:26:55 -0500 (Wed, 08 Apr 2009) | 1 line Minor factoring. ........ r71419 | raymond.hettinger | 2009-04-09 17:31:51 -0500 (Thu, 09 Apr 2009) | 1 line Add note on using keyword arguments with OrderedDict. ........ r71430 | raymond.hettinger | 2009-04-09 23:25:45 -0500 (Thu, 09 Apr 2009) | 1 line Clarify the table entries for combinatorics. ........ r71435 | raymond.hettinger | 2009-04-10 01:38:39 -0500 (Fri, 10 Apr 2009) | 1 line Fix the count of datatypes. ........ r71448 | raymond.hettinger | 2009-04-10 08:16:50 -0500 (Fri, 10 Apr 2009) | 1 line Add examples. ........ r71462 | chris.withers | 2009-04-11 06:22:19 -0500 (Sat, 11 Apr 2009) | 2 lines remove unpleasant exec ........ r71490 | r.david.murray | 2009-04-11 12:52:56 -0500 (Sat, 11 Apr 2009) | 4 lines Make test_asyncore tests match code changes introduced by the fix to Issue1161031, refactoring the test to simplify it in the process. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Apr 11 21:31:01 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Apr 2009 21:31:01 +0200 (CEST) Subject: [Python-checkins] r71494 - python/trunk/Makefile.pre.in Message-ID: <20090411193101.E5E861E4039@bag.python.org> Author: benjamin.peterson Date: Sat Apr 11 21:31:00 2009 New Revision: 71494 Log: ignore py3_test_grammar when compiling the library Modified: python/trunk/Makefile.pre.in Modified: python/trunk/Makefile.pre.in ============================================================================== --- python/trunk/Makefile.pre.in (original) +++ python/trunk/Makefile.pre.in Sat Apr 11 21:31:00 2009 @@ -892,11 +892,13 @@ PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ ./$(BUILDPYTHON) -Wi -tt $(DESTDIR)$(LIBDEST)/compileall.py \ -d $(LIBDEST) -f \ - -x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST) + -x 'bad_coding|badsyntax|site-packages|py3_test_grammar' \ + $(DESTDIR)$(LIBDEST) PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ ./$(BUILDPYTHON) -Wi -tt -O $(DESTDIR)$(LIBDEST)/compileall.py \ -d $(LIBDEST) -f \ - -x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST) + -x 'bad_coding|badsyntax|site-packages|py3_test_grammar' \ + $(DESTDIR)$(LIBDEST) -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ ./$(BUILDPYTHON) -Wi -t $(DESTDIR)$(LIBDEST)/compileall.py \ -d $(LIBDEST)/site-packages -f \ From python-checkins at python.org Sat Apr 11 21:48:16 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Apr 2009 21:48:16 +0200 (CEST) Subject: [Python-checkins] r71495 - in python/branches/py3k: Doc/c-api/buffer.rst Doc/c-api/init.rst Doc/distutils/setupscript.rst Doc/make.bat Doc/tools/sphinxext/susp-ignored.csv Lib/cgitb.py Lib/plistlib.py Lib/posixpath.py Lib/socket.py Lib/test/test_mmap.py Lib/test/test_os.py Lib/test/test_posixpath.py Lib/test/test_sys.py Modules/mmapmodule.c Modules/posixmodule.c Objects/bytearrayobject.c Python/getargs.c Message-ID: <20090411194816.15C2D1E4039@bag.python.org> Author: benjamin.peterson Date: Sat Apr 11 21:48:14 2009 New Revision: 71495 Log: Merged revisions 70980,71059,71225,71234,71241,71243,71249,71251,71255,71266,71299,71329,71397-71398,71486 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70980 | jack.diederich | 2009-04-01 15:26:13 -0500 (Wed, 01 Apr 2009) | 3 lines bounds check arguments to mmap.move(). All of them. Really. fixes crasher on OS X 10.5 ........ r71059 | mark.dickinson | 2009-04-02 13:39:37 -0500 (Thu, 02 Apr 2009) | 2 lines sys.long_info attributes should be ints, not longs ........ r71225 | georg.brandl | 2009-04-05 06:54:07 -0500 (Sun, 05 Apr 2009) | 1 line #5580: no need to use parentheses when converterr() argument is actually a type description. ........ r71234 | georg.brandl | 2009-04-05 08:16:35 -0500 (Sun, 05 Apr 2009) | 1 line Whitespace normalization. ........ r71241 | georg.brandl | 2009-04-05 09:48:49 -0500 (Sun, 05 Apr 2009) | 1 line #5471: fix expanduser() for $HOME set to "/". ........ r71243 | georg.brandl | 2009-04-05 10:14:29 -0500 (Sun, 05 Apr 2009) | 1 line #5432: make plistlib docstring a raw string, since it contains examples with backslash escapes. ........ r71249 | georg.brandl | 2009-04-05 11:30:43 -0500 (Sun, 05 Apr 2009) | 1 line #5444: adapt make.bat to new htmlhelp output file name. ........ r71251 | georg.brandl | 2009-04-05 12:17:42 -0500 (Sun, 05 Apr 2009) | 1 line #5298: clarify docs about GIL by using more consistent wording. ........ r71255 | georg.brandl | 2009-04-05 13:34:58 -0500 (Sun, 05 Apr 2009) | 1 line #602893: add indicator for current line in cgitb that doesnt rely on styling alone. ........ r71266 | georg.brandl | 2009-04-05 15:23:13 -0500 (Sun, 05 Apr 2009) | 1 line Normalize issue referencing style. ........ r71299 | gregory.p.smith | 2009-04-05 18:43:58 -0500 (Sun, 05 Apr 2009) | 3 lines Fixes issue5705: os.setuid() and friends did not accept the same range of values that pwd.getpwnam() returns. ........ r71329 | benjamin.peterson | 2009-04-06 16:53:33 -0500 (Mon, 06 Apr 2009) | 1 line add create_connection to __all__ #5711 ........ r71397 | georg.brandl | 2009-04-08 11:36:39 -0500 (Wed, 08 Apr 2009) | 1 line Remove redundant backtick. ........ r71398 | georg.brandl | 2009-04-08 11:39:04 -0500 (Wed, 08 Apr 2009) | 1 line Update ignore file for suspicious builder. ........ r71486 | andrew.kuchling | 2009-04-11 11:18:14 -0500 (Sat, 11 Apr 2009) | 1 line Re-word ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/buffer.rst python/branches/py3k/Doc/c-api/init.rst python/branches/py3k/Doc/distutils/setupscript.rst python/branches/py3k/Doc/make.bat python/branches/py3k/Doc/tools/sphinxext/susp-ignored.csv python/branches/py3k/Lib/cgitb.py python/branches/py3k/Lib/plistlib.py python/branches/py3k/Lib/posixpath.py python/branches/py3k/Lib/socket.py python/branches/py3k/Lib/test/test_mmap.py python/branches/py3k/Lib/test/test_os.py python/branches/py3k/Lib/test/test_posixpath.py python/branches/py3k/Lib/test/test_sys.py python/branches/py3k/Modules/mmapmodule.c python/branches/py3k/Modules/posixmodule.c python/branches/py3k/Objects/bytearrayobject.c python/branches/py3k/Python/getargs.c 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 Sat Apr 11 21:48:14 2009 @@ -239,7 +239,7 @@ | :cmacro:`PyBUF_FULL` | This is equivalent to ``(PyBUF_INDIRECT | | | | PyBUF_FORMAT | PyBUF_WRITABLE)``. | +------------------------------+---------------------------------------------------+ - | :cmacro:`PyBUF_FULL_RO`` | This is equivalent to ``(PyBUF_INDIRECT | | + | :cmacro:`PyBUF_FULL_RO` | This is equivalent to ``(PyBUF_INDIRECT | | | | PyBUF_FORMAT)``. | +------------------------------+---------------------------------------------------+ | :cmacro:`PyBUF_CONTIG` | This is equivalent to ``(PyBUF_ND | | 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 Sat Apr 11 21:48:14 2009 @@ -391,12 +391,12 @@ single: lock, interpreter The Python interpreter is not fully thread safe. In order to support -multi-threaded Python programs, there's a global lock that must be held by the -current thread before it can safely access Python objects. Without the lock, -even the simplest operations could cause problems in a multi-threaded program: -for example, when two threads simultaneously increment the reference count of -the same object, the reference count could end up being incremented only once -instead of twice. +multi-threaded Python programs, there's a global lock, called the :dfn:`global +interpreter lock` or :dfn:`GIL`, that must be held by the current thread before +it can safely access Python objects. Without the lock, even the simplest +operations could cause problems in a multi-threaded program: for example, when +two threads simultaneously increment the reference count of the same object, the +reference count could end up being incremented only once instead of twice. .. index:: single: setcheckinterval() (in module sys) @@ -425,9 +425,9 @@ interpreter lock has the following simple structure:: Save the thread state in a local variable. - Release the interpreter lock. + Release the global interpreter lock. ...Do some blocking I/O operation... - Reacquire the interpreter lock. + Reacquire the global interpreter lock. Restore the thread state from the local variable. This is so common that a pair of macros exists to simplify it:: @@ -444,7 +444,7 @@ hidden local variable; the :cmacro:`Py_END_ALLOW_THREADS` macro closes the block. Another advantage of using these two macros is that when Python is compiled without thread support, they are defined empty, thus saving the thread -state and lock manipulations. +state and GIL manipulations. When thread support is enabled, the block above expands to the following code:: @@ -476,7 +476,7 @@ saves and restores the value of the global variable :cdata:`errno`, since the lock manipulation does not guarantee that :cdata:`errno` is left alone. Also, when thread support is disabled, :cfunc:`PyEval_SaveThread` and -:cfunc:`PyEval_RestoreThread` don't manipulate the lock; in this case, +:cfunc:`PyEval_RestoreThread` don't manipulate the GIL; in this case, :cfunc:`PyEval_ReleaseLock` and :cfunc:`PyEval_AcquireLock` are not available. This is done so that dynamically loaded extensions compiled with thread support enabled can be loaded by an interpreter that was compiled with disabled thread @@ -559,16 +559,16 @@ .. index:: module: _thread - When only the main thread exists, no lock operations are needed. This is a + When only the main thread exists, no GIL operations are needed. This is a common situation (most Python programs do not use threads), and the lock - operations slow the interpreter down a bit. Therefore, the lock is not created - initially. This situation is equivalent to having acquired the lock: when - there is only a single thread, all object accesses are safe. Therefore, when - this function initializes the lock, it also acquires it. Before the Python - :mod:`_thread` module creates a new thread, knowing that either it has the lock - or the lock hasn't been created yet, it calls :cfunc:`PyEval_InitThreads`. When - this call returns, it is guaranteed that the lock has been created and that the - calling thread has acquired it. + operations slow the interpreter down a bit. Therefore, the lock is not + created initially. This situation is equivalent to having acquired the lock: + when there is only a single thread, all object accesses are safe. Therefore, + when this function initializes the global interpreter lock, it also acquires + it. Before the Python :mod:`_thread` module creates a new thread, knowing + that either it has the lock or the lock hasn't been created yet, it calls + :cfunc:`PyEval_InitThreads`. When this call returns, it is guaranteed that + the lock has been created and that the calling thread has acquired it. It is **not** safe to call this function when it is unknown which thread (if any) currently has the global interpreter lock. @@ -579,7 +579,7 @@ .. cfunction:: int PyEval_ThreadsInitialized() Returns a non-zero value if :cfunc:`PyEval_InitThreads` has been called. This - function can be called without holding the lock, and therefore can be used to + function can be called without holding the GIL, and therefore can be used to avoid calls to the locking API when running single-threaded. This function is not available when thread support is disabled at compile time. @@ -617,20 +617,20 @@ .. cfunction:: PyThreadState* PyEval_SaveThread() - Release the interpreter lock (if it has been created and thread support is - enabled) and reset the thread state to *NULL*, returning the previous thread - state (which is not *NULL*). If the lock has been created, the current thread - must have acquired it. (This function is available even when thread support is - disabled at compile time.) + Release the global interpreter lock (if it has been created and thread + support is enabled) and reset the thread state to *NULL*, returning the + previous thread state (which is not *NULL*). If the lock has been created, + the current thread must have acquired it. (This function is available even + when thread support is disabled at compile time.) .. cfunction:: void PyEval_RestoreThread(PyThreadState *tstate) - Acquire the interpreter lock (if it has been created and thread support is - enabled) and set the thread state to *tstate*, which must not be *NULL*. If the - lock has been created, the current thread must not have acquired it, otherwise - deadlock ensues. (This function is available even when thread support is - disabled at compile time.) + Acquire the global interpreter lock (if it has been created and thread + support is enabled) and set the thread state to *tstate*, which must not be + *NULL*. If the lock has been created, the current thread must not have + acquired it, otherwise deadlock ensues. (This function is available even + when thread support is disabled at compile time.) .. cfunction:: void PyEval_ReInitThreads() @@ -674,60 +674,61 @@ declaration. It is a no-op when thread support is disabled at compile time. All of the following functions are only available when thread support is enabled -at compile time, and must be called only when the interpreter lock has been -created. +at compile time, and must be called only when the global interpreter lock has +been created. .. cfunction:: PyInterpreterState* PyInterpreterState_New() - Create a new interpreter state object. The interpreter lock need not be held, - but may be held if it is necessary to serialize calls to this function. + Create a new interpreter state object. The global interpreter lock need not + be held, but may be held if it is necessary to serialize calls to this + function. .. cfunction:: void PyInterpreterState_Clear(PyInterpreterState *interp) - Reset all information in an interpreter state object. The interpreter lock must - be held. + Reset all information in an interpreter state object. The global interpreter + lock must be held. .. cfunction:: void PyInterpreterState_Delete(PyInterpreterState *interp) - Destroy an interpreter state object. The interpreter lock need not be held. - The interpreter state must have been reset with a previous call to + Destroy an interpreter state object. The global interpreter lock need not be + held. The interpreter state must have been reset with a previous call to :cfunc:`PyInterpreterState_Clear`. .. cfunction:: PyThreadState* PyThreadState_New(PyInterpreterState *interp) - Create a new thread state object belonging to the given interpreter object. The - interpreter lock need not be held, but may be held if it is necessary to - serialize calls to this function. + Create a new thread state object belonging to the given interpreter object. + The global interpreter lock need not be held, but may be held if it is + necessary to serialize calls to this function. .. cfunction:: void PyThreadState_Clear(PyThreadState *tstate) - Reset all information in a thread state object. The interpreter lock must be - held. + Reset all information in a thread state object. The global interpreter lock + must be held. .. cfunction:: void PyThreadState_Delete(PyThreadState *tstate) - Destroy a thread state object. The interpreter lock need not be held. The - thread state must have been reset with a previous call to + Destroy a thread state object. The global interpreter lock need not be held. + The thread state must have been reset with a previous call to :cfunc:`PyThreadState_Clear`. .. cfunction:: PyThreadState* PyThreadState_Get() - Return the current thread state. The interpreter lock must be held. When the - current thread state is *NULL*, this issues a fatal error (so that the caller - needn't check for *NULL*). + Return the current thread state. The global interpreter lock must be held. + When the current thread state is *NULL*, this issues a fatal error (so that + the caller needn't check for *NULL*). .. cfunction:: PyThreadState* PyThreadState_Swap(PyThreadState *tstate) Swap the current thread state with the thread state given by the argument - *tstate*, which may be *NULL*. The interpreter lock must be held. + *tstate*, which may be *NULL*. The global interpreter lock must be held. .. cfunction:: PyObject* PyThreadState_GetDict() @@ -752,14 +753,15 @@ .. cfunction:: PyGILState_STATE PyGILState_Ensure() - Ensure that the current thread is ready to call the Python C API regardless of - the current state of Python, or of its thread lock. This may be called as many - times as desired by a thread as long as each call is matched with a call to - :cfunc:`PyGILState_Release`. In general, other thread-related APIs may be used - between :cfunc:`PyGILState_Ensure` and :cfunc:`PyGILState_Release` calls as long - as the thread state is restored to its previous state before the Release(). For - example, normal usage of the :cmacro:`Py_BEGIN_ALLOW_THREADS` and - :cmacro:`Py_END_ALLOW_THREADS` macros is acceptable. + Ensure that the current thread is ready to call the Python C API regardless + of the current state of Python, or of the global interpreter lock. This may + be called as many times as desired by a thread as long as each call is + matched with a call to :cfunc:`PyGILState_Release`. In general, other + thread-related APIs may be used between :cfunc:`PyGILState_Ensure` and + :cfunc:`PyGILState_Release` calls as long as the thread state is restored to + its previous state before the Release(). For example, normal usage of the + :cmacro:`Py_BEGIN_ALLOW_THREADS` and :cmacro:`Py_END_ALLOW_THREADS` macros is + acceptable. The return value is an opaque "handle" to the thread state when :cfunc:`PyGILState_Ensure` was called, and must be passed to @@ -793,35 +795,34 @@ .. index:: single: setcheckinterval() (in module sys) -Every check interval, when the interpreter lock is released and reacquired, -python will also call any such provided functions. This can be used for -example by asynchronous IO handlers. The notification can be scheduled -from a worker thread and the actual call than made at the earliest -convenience by the main thread where it has possession of the global -interpreter lock and can perform any Python API calls. +Every check interval, when the global interpreter lock is released and +reacquired, python will also call any such provided functions. This can be used +for example by asynchronous IO handlers. The notification can be scheduled from +a worker thread and the actual call than made at the earliest convenience by the +main thread where it has possession of the global interpreter lock and can +perform any Python API calls. .. cfunction:: void Py_AddPendingCall( int (*func)(void *, void *arg) ) .. index:: single: Py_AddPendingCall() - Post a notification to the Python main thread. If successful, - *func* will be called with the argument *arg* at the earliest - convenience. *func* will be called having the global interpreter - lock held and can thus use the full Python API and can take any - action such as setting object attributes to signal IO completion. - It must return 0 on success, or -1 signalling an exception. - The notification function won't be interrupted to perform another - asynchronous notification recursively, - but it can still be interrupted to switch threads if the interpreter - lock is released, for example, if it calls back into python code. + Post a notification to the Python main thread. If successful, *func* will be + called with the argument *arg* at the earliest convenience. *func* will be + called having the global interpreter lock held and can thus use the full + Python API and can take any action such as setting object attributes to + signal IO completion. It must return 0 on success, or -1 signalling an + exception. The notification function won't be interrupted to perform another + asynchronous notification recursively, but it can still be interrupted to + switch threads if the global interpreter lock is released, for example, if it + calls back into python code. This function returns 0 on success in which case the notification has been - scheduled. Otherwise, for example if the notification buffer is full, - it returns -1 without setting any exception. + scheduled. Otherwise, for example if the notification buffer is full, it + returns -1 without setting any exception. - This function can be called on any thread, be it a Python thread or - some other system thread. If it is a Python thread, it doesn't matter if - it holds the global interpreter lock or not. + This function can be called on any thread, be it a Python thread or some + other system thread. If it is a Python thread, it doesn't matter if it holds + the global interpreter lock or not. .. versionadded:: 2.7 Modified: python/branches/py3k/Doc/distutils/setupscript.rst ============================================================================== --- python/branches/py3k/Doc/distutils/setupscript.rst (original) +++ python/branches/py3k/Doc/distutils/setupscript.rst Sat Apr 11 21:48:14 2009 @@ -334,9 +334,9 @@ There are still some other options which can be used to handle special cases. -The :option:`optional` option is a boolean; if it is true, that specifies that -a build failure in the extension should not abort the build process, but simply -not install the failing extension. +The :option:`optional` option is a boolean; if it is true, +a build failure in the extension will not abort the build process, but +instead simply not install the failing extension. The :option:`extra_objects` option is a list of object files to be passed to the linker. These files must not have extensions, as the default extension for the Modified: python/branches/py3k/Doc/make.bat ============================================================================== --- python/branches/py3k/Doc/make.bat (original) +++ python/branches/py3k/Doc/make.bat Sat Apr 11 21:48:14 2009 @@ -4,6 +4,7 @@ set SVNROOT=http://svn.python.org/projects if "%PYTHON%" EQU "" set PYTHON=..\pcbuild\python if "%HTMLHELP%" EQU "" set HTMLHELP=%ProgramFiles%\HTML Help Workshop\hhc.exe +if "%DISTVERSION%" EQU "" for /f "usebackq" %%v in (`%PYTHON% tools/sphinxext/patchlevel.py`) do set DISTVERSION=%%v if "%1" EQU "" goto help if "%1" EQU "html" goto build @@ -52,7 +53,7 @@ if not exist build\doctrees mkdir build\doctrees cmd /C %PYTHON% --version cmd /C %PYTHON% tools\sphinx-build.py -b%1 -dbuild\doctrees . build\%* -if "%1" EQU "htmlhelp" "%HTMLHELP%" build\htmlhelp\pydoc.hhp +if "%1" EQU "htmlhelp" "%HTMLHELP%" build\htmlhelp\python%DISTVERSION:.=%.hhp goto end :end 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 Apr 11 21:48:14 2009 @@ -48,6 +48,8 @@ library/httplib,,:port,host:port library/imaplib,,:MM,"""DD-Mmm-YYYY HH:MM:SS +HHMM""" library/imaplib,,:SS,"""DD-Mmm-YYYY HH:MM:SS +HHMM""" +library/itertools,,:stop,elements from seq[start:stop:step] +library/itertools,,:step,elements from seq[start:stop:step] library/linecache,,:sys,"sys:x:3:3:sys:/dev:/bin/sh" library/logging,,:And, library/logging,,:package1, Modified: python/branches/py3k/Lib/cgitb.py ============================================================================== --- python/branches/py3k/Lib/cgitb.py (original) +++ python/branches/py3k/Lib/cgitb.py Sat Apr 11 21:48:14 2009 @@ -142,10 +142,11 @@ i = lnum - index for line in lines: num = small(' ' * (5-len(str(i))) + str(i)) + ' ' - line = '%s%s' % (num, pydoc.html.preformat(line)) if i in highlight: + line = '=>%s%s' % (num, pydoc.html.preformat(line)) rows.append('%s' % line) else: + line = '  %s%s' % (num, pydoc.html.preformat(line)) rows.append('%s' % grey(line)) i += 1 Modified: python/branches/py3k/Lib/plistlib.py ============================================================================== --- python/branches/py3k/Lib/plistlib.py (original) +++ python/branches/py3k/Lib/plistlib.py Sat Apr 11 21:48:14 2009 @@ -1,4 +1,4 @@ -"""plistlib.py -- a tool to generate and parse MacOSX .plist files. +r"""plistlib.py -- a tool to generate and parse MacOSX .plist files. The PropertList (.plist) file format is a simple XML pickle supporting basic object types, like dictionaries, lists, numbers and strings. Modified: python/branches/py3k/Lib/posixpath.py ============================================================================== --- python/branches/py3k/Lib/posixpath.py (original) +++ python/branches/py3k/Lib/posixpath.py Sat Apr 11 21:48:14 2009 @@ -257,7 +257,10 @@ userhome = pwent.pw_dir if isinstance(path, bytes): userhome = userhome.encode(sys.getfilesystemencoding()) - userhome = userhome.rstrip(sep) + root = b'/' + else: + root = '/' + userhome = userhome.rstrip(root) or userhome return userhome + path[i:] Modified: python/branches/py3k/Lib/socket.py ============================================================================== --- python/branches/py3k/Lib/socket.py (original) +++ python/branches/py3k/Lib/socket.py Sat Apr 11 21:48:14 2009 @@ -52,7 +52,7 @@ except ImportError: EBADF = 9 -__all__ = ["getfqdn"] +__all__ = ["getfqdn", "create_connection"] __all__.extend(os._get_exports_list(_socket)) Modified: python/branches/py3k/Lib/test/test_mmap.py ============================================================================== --- python/branches/py3k/Lib/test/test_mmap.py (original) +++ python/branches/py3k/Lib/test/test_mmap.py Sat Apr 11 21:48:14 2009 @@ -357,15 +357,22 @@ m.move(source, dest, size) except ValueError: pass - self.assertRaises(ValueError, m.move, -1, -1, -1) - self.assertRaises(ValueError, m.move, -1, -1, 0) - self.assertRaises(ValueError, m.move, -1, 0, -1) - self.assertRaises(ValueError, m.move, 0, -1, -1) - self.assertRaises(ValueError, m.move, -1, 0, 0) - self.assertRaises(ValueError, m.move, 0, -1, 0) - self.assertRaises(ValueError, m.move, 0, 0, -1) + + offsets = [(-1, -1, -1), (-1, -1, 0), (-1, 0, -1), (0, -1, -1), + (-1, 0, 0), (0, -1, 0), (0, 0, -1)] + for source, dest, size in offsets: + self.assertRaises(ValueError, m.move, source, dest, size) + m.close() + m = mmap.mmap(-1, 1) # single byte + self.assertRaises(ValueError, m.move, 0, 0, 2) + self.assertRaises(ValueError, m.move, 1, 0, 1) + self.assertRaises(ValueError, m.move, 0, 1, 1) + m.move(0, 0, 1) + m.move(0, 0, 0) + + def test_anonymous(self): # anonymous mmap.mmap(-1, PAGE) m = mmap.mmap(-1, PAGESIZE) 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 Sat Apr 11 21:48:14 2009 @@ -660,6 +660,48 @@ class Win32ErrorTests(unittest.TestCase): pass + class PosixUidGidTests(unittest.TestCase): + if hasattr(os, 'setuid'): + def test_setuid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setuid, 0) + self.assertRaises(OverflowError, os.setuid, 1<<32) + + if hasattr(os, 'setgid'): + def test_setgid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setgid, 0) + self.assertRaises(OverflowError, os.setgid, 1<<32) + + if hasattr(os, 'seteuid'): + def test_seteuid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.seteuid, 0) + self.assertRaises(OverflowError, os.seteuid, 1<<32) + + if hasattr(os, 'setegid'): + def test_setegid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setegid, 0) + self.assertRaises(OverflowError, os.setegid, 1<<32) + + if hasattr(os, 'setreuid'): + def test_setreuid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setreuid, 0, 0) + self.assertRaises(OverflowError, os.setreuid, 1<<32, 0) + self.assertRaises(OverflowError, os.setreuid, 0, 1<<32) + + if hasattr(os, 'setregid'): + def test_setregid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setregid, 0, 0) + self.assertRaises(OverflowError, os.setregid, 1<<32, 0) + self.assertRaises(OverflowError, os.setregid, 0, 1<<32) +else: + class PosixUidGidTests(unittest.TestCase): + pass + def test_main(): support.run_unittest( FileTests, @@ -671,7 +713,8 @@ URandomTests, ExecTests, Win32ErrorTests, - TestInvalidFD + TestInvalidFD, + PosixUidGidTests ) if __name__ == "__main__": 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 Sat Apr 11 21:48:14 2009 @@ -419,6 +419,11 @@ self.assert_(isinstance(posixpath.expanduser(b"~root/"), bytes)) self.assert_(isinstance(posixpath.expanduser(b"~foo/"), bytes)) + orig_home = os.environ['HOME'] + os.environ['HOME'] = '/' + self.assertEqual(posixpath.expanduser("~"), "/") + os.environ['HOME'] = orig_home + self.assertRaises(TypeError, posixpath.expanduser) def test_expandvars(self): 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 Sat Apr 11 21:48:14 2009 @@ -344,6 +344,8 @@ self.assertEqual(len(sys.int_info), 2) self.assert_(sys.int_info.bits_per_digit % 5 == 0) self.assert_(sys.int_info.sizeof_digit >= 1) + self.assertEqual(type(sys.int_info.bits_per_digit), int) + self.assertEqual(type(sys.int_info.sizeof_digit), int) self.assert_(isinstance(sys.hexversion, int)) self.assert_(isinstance(sys.maxsize, int)) self.assert_(isinstance(sys.maxunicode, int)) @@ -622,9 +624,9 @@ check(1, size(vh) + self.longdigit) check(-1, size(vh) + self.longdigit) PyLong_BASE = 2**sys.int_info.bits_per_digit - check(PyLong_BASE, size(vh) + 2*self.longdigit) - check(PyLong_BASE**2-1, size(vh) + 2*self.longdigit) - check(PyLong_BASE**2, size(vh) + 3*self.longdigit) + check(int(PyLong_BASE), size(vh) + 2*self.longdigit) + check(int(PyLong_BASE**2-1), size(vh) + 2*self.longdigit) + check(int(PyLong_BASE**2), size(vh) + 3*self.longdigit) # memory check(memoryview(b''), size(h + 'P PP2P2i7P')) # module Modified: python/branches/py3k/Modules/mmapmodule.c ============================================================================== --- python/branches/py3k/Modules/mmapmodule.c (original) +++ python/branches/py3k/Modules/mmapmodule.c Sat Apr 11 21:48:14 2009 @@ -620,23 +620,23 @@ static PyObject * mmap_move_method(mmap_object *self, PyObject *args) { - unsigned long dest, src, count; + unsigned long dest, src, cnt; CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "kkk:move", &dest, &src, &count) || + if (!PyArg_ParseTuple(args, "kkk:move", &dest, &src, &cnt) || !is_writable(self)) { return NULL; } else { /* bounds check the values */ - unsigned long pos = src > dest ? src : dest; - if (self->size < pos || count > self->size - pos) { + if (cnt < 0 || (cnt + dest) < cnt || (cnt + src) < cnt || + src < 0 || src > self->size || (src + cnt) > self->size || + dest < 0 || dest > self->size || (dest + cnt) > self->size) { PyErr_SetString(PyExc_ValueError, - "source or destination out of range"); + "source, destination, or count out of range"); return NULL; - } else { - memmove(self->data+dest, self->data+src, count); - Py_INCREF(Py_None); - return Py_None; } + memmove(self->data+dest, self->data+src, cnt); + Py_INCREF(Py_None); + return Py_None; } } Modified: python/branches/py3k/Modules/posixmodule.c ============================================================================== --- python/branches/py3k/Modules/posixmodule.c (original) +++ python/branches/py3k/Modules/posixmodule.c Sat Apr 11 21:48:14 2009 @@ -4168,9 +4168,15 @@ static PyObject * posix_setuid(PyObject *self, PyObject *args) { - int uid; - if (!PyArg_ParseTuple(args, "i:setuid", &uid)) + long uid_arg; + uid_t uid; + if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg)) + return NULL; + uid = uid_arg; + if (uid != uid_arg) { + PyErr_SetString(PyExc_OverflowError, "user id too big"); return NULL; + } if (setuid(uid) < 0) return posix_error(); Py_INCREF(Py_None); @@ -4187,10 +4193,16 @@ static PyObject * posix_seteuid (PyObject *self, PyObject *args) { - int euid; - if (!PyArg_ParseTuple(args, "i", &euid)) { + long euid_arg; + uid_t euid; + if (!PyArg_ParseTuple(args, "l", &euid_arg)) + return NULL; + euid = euid_arg; + if (euid != euid_arg) { + PyErr_SetString(PyExc_OverflowError, "user id too big"); return NULL; - } else if (seteuid(euid) < 0) { + } + if (seteuid(euid) < 0) { return posix_error(); } else { Py_INCREF(Py_None); @@ -4207,10 +4219,16 @@ static PyObject * posix_setegid (PyObject *self, PyObject *args) { - int egid; - if (!PyArg_ParseTuple(args, "i", &egid)) { + long egid_arg; + gid_t egid; + if (!PyArg_ParseTuple(args, "l", &egid_arg)) return NULL; - } else if (setegid(egid) < 0) { + egid = egid_arg; + if (egid != egid_arg) { + PyErr_SetString(PyExc_OverflowError, "group id too big"); + return NULL; + } + if (setegid(egid) < 0) { return posix_error(); } else { Py_INCREF(Py_None); @@ -4227,10 +4245,17 @@ static PyObject * posix_setreuid (PyObject *self, PyObject *args) { - int ruid, euid; - if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) { + long ruid_arg, euid_arg; + uid_t ruid, euid; + if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg)) return NULL; - } else if (setreuid(ruid, euid) < 0) { + ruid = ruid_arg; + euid = euid_arg; + if (euid != euid_arg || ruid != ruid_arg) { + PyErr_SetString(PyExc_OverflowError, "user id too big"); + return NULL; + } + if (setreuid(ruid, euid) < 0) { return posix_error(); } else { Py_INCREF(Py_None); @@ -4247,10 +4272,17 @@ static PyObject * posix_setregid (PyObject *self, PyObject *args) { - int rgid, egid; - if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) { + long rgid_arg, egid_arg; + gid_t rgid, egid; + if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg)) + return NULL; + rgid = rgid_arg; + egid = egid_arg; + if (egid != egid_arg || rgid != rgid_arg) { + PyErr_SetString(PyExc_OverflowError, "group id too big"); return NULL; - } else if (setregid(rgid, egid) < 0) { + } + if (setregid(rgid, egid) < 0) { return posix_error(); } else { Py_INCREF(Py_None); @@ -4267,9 +4299,15 @@ static PyObject * posix_setgid(PyObject *self, PyObject *args) { - int gid; - if (!PyArg_ParseTuple(args, "i:setgid", &gid)) + long gid_arg; + gid_t gid; + if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg)) + return NULL; + gid = gid_arg; + if (gid != gid_arg) { + PyErr_SetString(PyExc_OverflowError, "group id too big"); return NULL; + } if (setgid(gid) < 0) return posix_error(); Py_INCREF(Py_None); Modified: python/branches/py3k/Objects/bytearrayobject.c ============================================================================== --- python/branches/py3k/Objects/bytearrayobject.c (original) +++ python/branches/py3k/Objects/bytearrayobject.c Sat Apr 11 21:48:14 2009 @@ -1021,7 +1021,7 @@ { if (self->ob_exports > 0) { PyErr_SetString(PyExc_SystemError, - "deallocated bytearray object has exported buffers"); + "deallocated bytearray object has exported buffers"); PyErr_Print(); } if (self->ob_bytes != 0) { @@ -2616,10 +2616,10 @@ /* Try to determine the length of the argument. 32 is abitrary. */ buf_size = _PyObject_LengthHint(arg, 32); - if (buf_size == -1) { - Py_DECREF(it); - return NULL; - } + if (buf_size == -1) { + Py_DECREF(it); + return NULL; + } bytes_obj = PyByteArray_FromStringAndSize(NULL, buf_size); if (bytes_obj == NULL) @@ -3063,10 +3063,10 @@ static PyObject * bytes_sizeof(PyByteArrayObject *self) { - Py_ssize_t res; + Py_ssize_t res; - res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char); - return PyLong_FromSsize_t(res); + res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char); + return PyLong_FromSsize_t(res); } static PySequenceMethods bytes_as_sequence = { Modified: python/branches/py3k/Python/getargs.c ============================================================================== --- python/branches/py3k/Python/getargs.c (original) +++ python/branches/py3k/Python/getargs.c Sat Apr 11 21:48:14 2009 @@ -1147,7 +1147,7 @@ if ((Py_ssize_t)strlen(ptr) != size) { Py_DECREF(s); return converterr( - "(encoded string without NULL bytes)", + "encoded string without NULL bytes", arg, msgbuf, bufsize); } *buffer = PyMem_NEW(char, size + 1); From buildbot at python.org Sat Apr 11 22:10:49 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 11 Apr 2009 20:10:49 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090411201049.908BB1E4141@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/262 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Sat Apr 11 22:12:10 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Apr 2009 22:12:10 +0200 (CEST) Subject: [Python-checkins] r71496 - in python/branches/py3k: Lib/http/server.py Lib/test/test_httpservers.py Message-ID: <20090411201210.701C21E4071@bag.python.org> Author: benjamin.peterson Date: Sat Apr 11 22:12:10 2009 New Revision: 71496 Log: Merged revisions 71303 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71303 | gregory.p.smith | 2009-04-06 01:33:26 -0500 (Mon, 06 Apr 2009) | 3 lines - Issue #2254: Fix CGIHTTPServer information disclosure. Relative paths are now collapsed within the url properly before looking in cgi_directories. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/http/server.py python/branches/py3k/Lib/test/test_httpservers.py Modified: python/branches/py3k/Lib/http/server.py ============================================================================== --- python/branches/py3k/Lib/http/server.py (original) +++ python/branches/py3k/Lib/http/server.py Sat Apr 11 22:12:10 2009 @@ -773,6 +773,46 @@ # Utilities for CGIHTTPRequestHandler +# TODO(gregory.p.smith): Move this into an appropriate library. +def _url_collapse_path_split(path): + """ + Given a URL path, remove extra '/'s and '.' path elements and collapse + any '..' references. + + Implements something akin to RFC-2396 5.2 step 6 to parse relative paths. + + Returns: A tuple of (head, tail) where tail is everything after the final / + and head is everything before it. Head will always start with a '/' and, + if it contains anything else, never have a trailing '/'. + + Raises: IndexError if too many '..' occur within the path. + """ + # Similar to os.path.split(os.path.normpath(path)) but specific to URL + # path semantics rather than local operating system semantics. + path_parts = [] + for part in path.split('/'): + if part == '.': + path_parts.append('') + else: + path_parts.append(part) + # Filter out blank non trailing parts before consuming the '..'. + path_parts = [part for part in path_parts[:-1] if part] + path_parts[-1:] + if path_parts: + tail_part = path_parts.pop() + else: + tail_part = '' + head_parts = [] + for part in path_parts: + if part == '..': + head_parts.pop() + else: + head_parts.append(part) + if tail_part and tail_part == '..': + head_parts.pop() + tail_part = '' + return ('/' + '/'.join(head_parts), tail_part) + + nobody = None def nobody_uid(): @@ -839,24 +879,20 @@ def is_cgi(self): """Test whether self.path corresponds to a CGI script. - Return a tuple (dir, rest) if self.path requires running a - CGI script, None if not. Note that rest begins with a - slash if it is not empty. - - The default implementation tests whether the path - begins with one of the strings in the list - self.cgi_directories (and the next character is a '/' - or the end of the string). + Returns True and updates the cgi_info attribute to the tuple + (dir, rest) if self.path requires running a CGI script. + Returns False otherwise. + + The default implementation tests whether the normalized url + path begins with one of the strings in self.cgi_directories + (and the next character is a '/' or the end of the string). """ - path = self.path - - for x in self.cgi_directories: - i = len(x) - if path[:i] == x and (not path[i:] or path[i] == '/'): - self.cgi_info = path[:i], path[i+1:] - return True + splitpath = _url_collapse_path_split(self.path) + if splitpath[0] in self.cgi_directories: + self.cgi_info = splitpath + return True return False cgi_directories = ['/cgi-bin', '/htbin'] 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 Sat Apr 11 22:12:10 2009 @@ -6,6 +6,7 @@ from http.server import BaseHTTPRequestHandler, HTTPServer, \ SimpleHTTPRequestHandler, CGIHTTPRequestHandler +from http import server import os import sys @@ -316,6 +317,45 @@ finally: BaseTestCase.tearDown(self) + def test_url_collapse_path_split(self): + test_vectors = { + '': ('/', ''), + '..': IndexError, + '/.//..': IndexError, + '/': ('/', ''), + '//': ('/', ''), + '/\\': ('/', '\\'), + '/.//': ('/', ''), + 'cgi-bin/file1.py': ('/cgi-bin', 'file1.py'), + '/cgi-bin/file1.py': ('/cgi-bin', 'file1.py'), + 'a': ('/', 'a'), + '/a': ('/', 'a'), + '//a': ('/', 'a'), + './a': ('/', 'a'), + './C:/': ('/C:', ''), + '/a/b': ('/a', 'b'), + '/a/b/': ('/a/b', ''), + '/a/b/c/..': ('/a/b', ''), + '/a/b/c/../d': ('/a/b', 'd'), + '/a/b/c/../d/e/../f': ('/a/b/d', 'f'), + '/a/b/c/../d/e/../../f': ('/a/b', 'f'), + '/a/b/c/../d/e/.././././..//f': ('/a/b', 'f'), + '../a/b/c/../d/e/.././././..//f': IndexError, + '/a/b/c/../d/e/../../../f': ('/a', 'f'), + '/a/b/c/../d/e/../../../../f': ('/', 'f'), + '/a/b/c/../d/e/../../../../../f': IndexError, + '/a/b/c/../d/e/../../../../f/..': ('/', ''), + } + for path, expected in test_vectors.items(): + if isinstance(expected, type) and issubclass(expected, Exception): + self.assertRaises(expected, + server._url_collapse_path_split, path) + else: + actual = server._url_collapse_path_split(path) + self.assertEquals(expected, actual, + msg='path = %r\nGot: %r\nWanted: %r' % ( + path, actual, expected)) + def test_headers_and_content(self): res = self.request('/cgi-bin/file1.py') self.assertEquals((b'Hello World\n', 'text/html', 200), \ @@ -341,6 +381,12 @@ self.assertEquals((b'Hello World\n', 'text/html', 200), \ (res.read(), res.getheader('Content-type'), res.status)) + def test_no_leading_slash(self): + # http://bugs.python.org/issue2254 + res = self.request('cgi-bin/file1.py') + self.assertEquals((b'Hello World\n', 'text/html', 200), + (res.read(), res.getheader('Content-type'), res.status)) + def test_main(verbose=None): try: From python-checkins at python.org Sat Apr 11 22:14:54 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Apr 2009 22:14:54 +0200 (CEST) Subject: [Python-checkins] r71497 - python/branches/py3k Message-ID: <20090411201454.8A7091E4039@bag.python.org> Author: benjamin.peterson Date: Sat Apr 11 22:14:54 2009 New Revision: 71497 Log: Blocked revisions 70757,70981,71029,71031,71082 via svnmerge ........ r70757 | senthil.kumaran | 2009-03-30 16:51:50 -0500 (Mon, 30 Mar 2009) | 3 lines Fix for bugs: Issue4675 and Issue4962. ........ r70981 | senthil.kumaran | 2009-04-01 15:26:33 -0500 (Wed, 01 Apr 2009) | 3 lines Fix for issue5040. Adding test for Content-Length ........ r71029 | senthil.kumaran | 2009-04-01 22:00:34 -0500 (Wed, 01 Apr 2009) | 3 lines Fixing the issue4860. Escaping embedded '"' character in js_output() method of Morsel. ........ r71031 | brett.cannon | 2009-04-01 22:17:39 -0500 (Wed, 01 Apr 2009) | 6 lines PyImport_AppendInittab() took a char * as a first argument even though that string was stored beyond the life of the call. Changed the signature to be const char * to help make this point. Closes issue #1419652. ........ r71082 | hirokazu.yamamoto | 2009-04-02 22:54:08 -0500 (Thu, 02 Apr 2009) | 1 line Fixed compile error on windows. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Apr 11 22:27:16 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Apr 2009 22:27:16 +0200 (CEST) Subject: [Python-checkins] r71498 - python/trunk/Doc/whatsnew/2.7.rst Message-ID: <20090411202716.68A661E4167@bag.python.org> Author: benjamin.peterson Date: Sat Apr 11 22:27:15 2009 New Revision: 71498 Log: fix markup Modified: python/trunk/Doc/whatsnew/2.7.rst Modified: python/trunk/Doc/whatsnew/2.7.rst ============================================================================== --- python/trunk/Doc/whatsnew/2.7.rst (original) +++ python/trunk/Doc/whatsnew/2.7.rst Sat Apr 11 22:27:15 2009 @@ -88,22 +88,21 @@ Some smaller changes made to the core Python language are: -* The string :method:`format` method now supports automatic numbering - of the replacement fields. This makes using :meth:`format` - more closely resemble using ``%s`` formatting:: +* :meth:`str.format` method now supports automatic numbering of the replacement + fields. This makes using :meth:`str.format` more closely resemble using + ``%s`` formatting:: >>> '{}:{}:{}'.format(2009, 04, 'Sunday') '2009:4:Sunday' >>> '{}:{}:{day}'.format(2009, 4, day='Sunday') '2009:4:Sunday' - The auto-numbering takes the fields from left to right, so the first - ``{...}`` specifier will use the first argument to :meth:`format`, - the next specifier will use the next argument, and so on. You can't - mix auto-numbering and explicit numbering -- either number all of - your specifier fields or none of them -- but you can mix - auto-numbering and named fields, as in the second example above. - (Contributed by XXX; :issue`5237`.) + The auto-numbering takes the fields from left to right, so the first ``{...}`` + specifier will use the first argument to :meth:`str.format`, the next + specifier will use the next argument, and so on. You can't mix auto-numbering + and explicit numbering -- either number all of your specifier fields or none + of them -- but you can mix auto-numbering and named fields, as in the second + example above. (Contributed by XXX; :issue`5237`.) * The :func:`int` and :func:`long` types gained a ``bit_length`` method that returns the number of bits necessary to represent From python-checkins at python.org Sat Apr 11 22:34:18 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 11 Apr 2009 22:34:18 +0200 (CEST) Subject: [Python-checkins] r71499 - python/branches/release26-maint/Doc/tools/sphinxext/pyspecific.py Message-ID: <20090411203418.06D441E41ED@bag.python.org> Author: georg.brandl Date: Sat Apr 11 22:34:17 2009 New Revision: 71499 Log: Add a monkeypatching hack so that the docs can still be built with Sphinx 0.5. Modified: python/branches/release26-maint/Doc/tools/sphinxext/pyspecific.py Modified: python/branches/release26-maint/Doc/tools/sphinxext/pyspecific.py ============================================================================== --- python/branches/release26-maint/Doc/tools/sphinxext/pyspecific.py (original) +++ python/branches/release26-maint/Doc/tools/sphinxext/pyspecific.py Sat Apr 11 22:34:17 2009 @@ -5,7 +5,7 @@ Sphinx extension with Python doc-specific markup. - :copyright: 2008 by Georg Brandl. + :copyright: 2008, 2009 by Georg Brandl. :license: Python license. """ @@ -59,7 +59,11 @@ try: from sphinx.builders import Builder except ImportError: + # using Sphinx < 0.6, which has a different package layout from sphinx.builder import Builder + # monkey-patch toctree directive to accept (and ignore) the :numbered: flag + from sphinx.directives.other import toctree_directive + toctree_directive.options['numbered'] = toctree_directive.options['glob'] try: from sphinx.writers.text import TextWriter From python-checkins at python.org Sat Apr 11 22:45:41 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Apr 2009 22:45:41 +0200 (CEST) Subject: [Python-checkins] r71500 - in python/branches/py3k: Doc/library/multiprocessing.rst Doc/library/unittest.rst Doc/whatsnew/2.7.rst Lib/distutils/command/__init__.py Lib/distutils/command/check.py Lib/distutils/tests/test_spawn.py Lib/multiprocessing/managers.py Lib/multiprocessing/pool.py Lib/test/test_multiprocessing.py Lib/test/test_unittest.py Lib/unittest.py Makefile.pre.in Misc Misc/README Misc/gdbinit Misc/python-wing.wpr Message-ID: <20090411204541.9EBCF1E4043@bag.python.org> Author: benjamin.peterson Date: Sat Apr 11 22:45:40 2009 New Revision: 71500 Log: Merged revisions 70912,70944,70968,71033,71041,71208,71263,71286,71395-71396,71405-71406,71485,71492,71494 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70912 | georg.brandl | 2009-03-31 17:35:46 -0500 (Tue, 31 Mar 2009) | 1 line #5617: add a handy function to print a unicode string to gdbinit. ........ r70944 | georg.brandl | 2009-03-31 23:32:39 -0500 (Tue, 31 Mar 2009) | 1 line #5631: add upload to list of possible commands, which is presented in --help-commands. ........ r70968 | michael.foord | 2009-04-01 13:25:38 -0500 (Wed, 01 Apr 2009) | 1 line Adding Wing project file ........ r71033 | brett.cannon | 2009-04-01 22:34:53 -0500 (Wed, 01 Apr 2009) | 3 lines Fix two issues introduced by issue #71031 by changing the signature of PyImport_AppendInittab() to take a const char *. ........ r71041 | jesse.noller | 2009-04-02 00:17:26 -0500 (Thu, 02 Apr 2009) | 1 line Add custom initializer argument to multiprocess.Manager*, courtesy of lekma ........ r71208 | michael.foord | 2009-04-04 20:15:01 -0500 (Sat, 04 Apr 2009) | 4 lines Change the way unittest.TestSuite use their tests to always access them through iteration. Non behavior changing, this allows you to create custom subclasses that override __iter__. Issue #5693 ........ r71263 | michael.foord | 2009-04-05 14:19:28 -0500 (Sun, 05 Apr 2009) | 4 lines Adding assertIs and assertIsNot methods to unittest.TestCase Issue #2578 ........ r71286 | tarek.ziade | 2009-04-05 17:04:38 -0500 (Sun, 05 Apr 2009) | 1 line added a simplest test to distutils.spawn._nt_quote_args ........ r71395 | benjamin.peterson | 2009-04-08 08:27:29 -0500 (Wed, 08 Apr 2009) | 1 line these must be installed to correctly run tests ........ r71396 | benjamin.peterson | 2009-04-08 08:29:41 -0500 (Wed, 08 Apr 2009) | 1 line fix syntax ........ r71405 | andrew.kuchling | 2009-04-09 06:22:47 -0500 (Thu, 09 Apr 2009) | 1 line Add items ........ r71406 | andrew.kuchling | 2009-04-09 06:23:36 -0500 (Thu, 09 Apr 2009) | 1 line Typo fixes ........ r71485 | andrew.kuchling | 2009-04-11 11:12:23 -0500 (Sat, 11 Apr 2009) | 1 line Add various items ........ r71492 | georg.brandl | 2009-04-11 13:19:27 -0500 (Sat, 11 Apr 2009) | 1 line Take credit for a patch of mine. ........ r71494 | benjamin.peterson | 2009-04-11 14:31:00 -0500 (Sat, 11 Apr 2009) | 1 line ignore py3_test_grammar when compiling the library ........ Added: python/branches/py3k/Lib/distutils/tests/test_spawn.py - copied unchanged from r71286, /python/trunk/Lib/distutils/tests/test_spawn.py python/branches/py3k/Misc/python-wing.wpr - copied unchanged from r70968, /python/trunk/Misc/python-wing.wpr Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/multiprocessing.rst python/branches/py3k/Doc/library/unittest.rst python/branches/py3k/Doc/whatsnew/2.7.rst python/branches/py3k/Lib/distutils/command/__init__.py python/branches/py3k/Lib/distutils/command/check.py python/branches/py3k/Lib/multiprocessing/managers.py python/branches/py3k/Lib/multiprocessing/pool.py python/branches/py3k/Lib/test/test_multiprocessing.py python/branches/py3k/Lib/test/test_unittest.py python/branches/py3k/Lib/unittest.py python/branches/py3k/Makefile.pre.in python/branches/py3k/Misc/ (props changed) python/branches/py3k/Misc/README python/branches/py3k/Misc/gdbinit Modified: python/branches/py3k/Doc/library/multiprocessing.rst ============================================================================== --- python/branches/py3k/Doc/library/multiprocessing.rst (original) +++ python/branches/py3k/Doc/library/multiprocessing.rst Sat Apr 11 22:45:40 2009 @@ -1128,9 +1128,10 @@ ``current_process().authkey``. Otherwise *authkey* is used and it must be a string. - .. method:: start() + .. method:: start([initializer[, initargs]]) - Start a subprocess to start the manager. + Start a subprocess to start the manager. If *initializer* is not ``None`` + then the subprocess will call ``initializer(*initargs)`` when it starts. .. method:: serve_forever() Modified: python/branches/py3k/Doc/library/unittest.rst ============================================================================== --- python/branches/py3k/Doc/library/unittest.rst (original) +++ python/branches/py3k/Doc/library/unittest.rst Sat Apr 11 22:45:40 2009 @@ -689,7 +689,7 @@ assertLessEqual(first, second, msg=None) Test that *first* is respectively >, >=, < or <= than *second* depending - on the method name. If not, the test will fail with the nice explanation + on the method name. If not, the test will fail with an explanation or with the explanation given by *msg*:: >>> self.assertGreaterEqual(3, 4) @@ -722,7 +722,7 @@ .. method:: assertIn(first, second, msg=None) assertNotIn(first, second, msg=None) - Tests that *first* is or is not in *second* with a nice explanitory error + Tests that *first* is or is not in *second* with an explanatory error message as appropriate. If specified *msg* will be used as the error message on failure. @@ -766,7 +766,7 @@ .. method:: assertDictContainsSubset(expected, actual, msg=None) - Tests whether the key value pairs in dictionary *actual* are a + Tests whether the key/value pairs in dictionary *actual* are a superset of those in *expected*. If not, an error message listing the missing keys and mismatched values is generated. @@ -858,6 +858,23 @@ .. versionadded:: 3.1 + .. method:: assertIs(expr1, expr2[, msg]) + + This signals a test failure if *expr1* and *expr2* don't evaluate to the same + object. + + .. versionadded:: 2.7 + + + .. method:: assertIsNot(expr1, expr2[, msg]) + + The inverse of the :meth:`assertIs` method. + This signals a test failure if *expr1* and *expr2* evaluate to the same + object. + + .. versionadded:: 2.7 + + .. method:: assertFalse(expr[, msg]) failIf(expr[, msg]) @@ -951,12 +968,12 @@ been asked to compare are exactly *typeobj* (not subclasses). *function* must take two positional arguments and a third msg=None keyword argument just as :meth:`assertEqual` does. It must raise - self.failureException when inequality between the first two + ``self.failureException`` when inequality between the first two parameters is detected. One good use of custom equality checking functions for a type - is to raise self.failureException with an error message useful - for debugging the by explaining the inequalities in detail. + is to raise ``self.failureException`` with an error message useful + for debugging the problem by explaining the inequalities in detail. .. versionadded:: 3.1 Modified: python/branches/py3k/Doc/whatsnew/2.7.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/2.7.rst (original) +++ python/branches/py3k/Doc/whatsnew/2.7.rst Sat Apr 11 22:45:40 2009 @@ -88,6 +88,23 @@ Some smaller changes made to the core Python language are: +* The string :method:`format` method now supports automatic numbering + of the replacement fields. This makes using :meth:`format` + more closely resemble using ``%s`` formatting:: + + >>> '{}:{}:{}'.format(2009, 04, 'Sunday') + '2009:4:Sunday' + >>> '{}:{}:{day}'.format(2009, 4, day='Sunday') + '2009:4:Sunday' + + The auto-numbering takes the fields from left to right, so the first + ``{...}`` specifier will use the first argument to :meth:`format`, + the next specifier will use the next argument, and so on. You can't + mix auto-numbering and explicit numbering -- either number all of + your specifier fields or none of them -- but you can mix + auto-numbering and named fields, as in the second example above. + (Contributed by XXX; :issue`5237`.) + * The :func:`int` and :func:`long` types gained a ``bit_length`` method that returns the number of bits necessary to represent its argument in binary:: @@ -106,7 +123,7 @@ (Contributed by Fredrik Johansson and Victor Stinner; :issue:`3439`.) * The :class:`bytearray` type's :meth:`translate` method will - now accept None as its first argument. (Fixed by Georg Brandl; + now accept ``None`` as its first argument. (Fixed by Georg Brandl; :issue:`4759`.) .. ====================================================================== @@ -201,7 +218,7 @@ management protocol, so you can write ``with bz2.BZ2File(...) as f: ...``. (Contributed by Hagen Fuerstenau; :issue:`3860`.) -* A new :class:`Counter` class in the :mod:`collections` module is +* New class: the :class:`Counter` class in the :mod:`collections` module is useful for tallying data. :class:`Counter` instances behave mostly like dictionaries but return zero for missing keys instead of raising a :exc:`KeyError`:: @@ -236,7 +253,7 @@ Contributed by Raymond Hettinger; :issue:`1696199`. The :class:`namedtuple` class now has an optional *rename* parameter. - If *rename* is True, field names that are invalid because they've + If *rename* is true, field names that are invalid because they've been repeated or that aren't legal Python identifiers will be renamed to legal names that are derived from the field's position within the list of fields: @@ -247,8 +264,13 @@ (Added by Raymond Hettinger; :issue:`1818`.) + The :class:`deque` data type now exposes its maximum length as the + read-only :attr:`maxlen` attribute. (Added by Raymond Hettinger.) + * In Distutils, :func:`distutils.sdist.add_defaults` now uses *package_dir* and *data_files* to create the MANIFEST file. + :mod:`distutils.sysconfig` will now read the :envvar:`AR` + environment variable. It is no longer mandatory to store clear-text passwords in the :file:`.pypirc` file when registering and uploading packages to PyPI. As long @@ -256,6 +278,12 @@ prompt for the password if not present. (Added by Tarek Ziade, based on an initial contribution by Nathan Van Gheem; :issue:`4394`.) + A Distutils setup can now specify that a C extension is optional by + setting the *optional* option setting to true. If this optional is + supplied, failure to build the extension will not abort the build + process, but instead simply not install the failing extension. + (Contributed by Georg Brandl; :issue:`5583`.) + * New method: the :class:`Decimal` class gained a :meth:`from_float` class method that performs an exact conversion of a floating-point number to a :class:`Decimal`. @@ -267,8 +295,8 @@ ``Decimal('0.1000000000000000055511151231257827021181583404541015625')``. (Implemented by Raymond Hettinger; :issue:`4796`.) -* A new function in the :mod:`gc` module, :func:`is_tracked`, returns - True if a given instance is tracked by the garbage collector, False +* New function: the :mod:`gc` module's :func:`is_tracked` returns + true if a given instance is tracked by the garbage collector, false otherwise. (Contributed by Antoine Pitrou; :issue:`4688`.) * The :mod:`gzip` module's :class:`GzipFile` now supports the context @@ -284,7 +312,7 @@ * New function: ``itertools.compress(*data*, *selectors*)`` takes two iterators. Elements of *data* are returned if the corresponding - value in *selectors* is True:: + value in *selectors* is true:: itertools.compress('ABCDEF', [1,0,1,0,1,1]) => A, C, E, F @@ -322,12 +350,22 @@ with any object literal that decodes to a list of pairs. (Contributed by Raymond Hettinger; :issue:`5381`.) +* The :mod:`multiprocessing` module's :class:`Manager*` classes + can now be passed a callable that will be called whenever + a subprocess is started, along with a set of arguments that will be + passed to the callable. + (Contributed by lekma; :issue:`5585`.) + * The :mod:`pydoc` module now has help for the various symbols that Python uses. You can now do ``help('<<')`` or ``help('@')``, for example. (Contributed by David Laban; :issue:`4739`.) -* A new function in the :mod:`subprocess` module, - :func:`check_output`, runs a command with a specified set of arguments +* The :mod:`re` module's :func:`split`, :func:`sub`, and :func:`subn` + now accept an optional *flags* argument, for consistency with the + other functions in the module. (Added by Gregory P. Smith.) + +* New function: the :mod:`subprocess` module's + :func:`check_output` runs a command with a specified set of arguments and returns the command's output as a string when the command runs without error, or raises a :exc:`CalledProcessError` exception otherwise. @@ -343,26 +381,99 @@ (Contributed by Gregory P. Smith.) +* New function: :func:`is_declared_global` in the :mod:`symtable` module + returns true for variables that are explicitly declared to be global, + false for ones that are implicitly global. + (Contributed by Jeremy Hylton.) + * The ``sys.version_info`` value is now a named tuple, with attributes named ``major``, ``minor``, ``micro``, ``releaselevel``, and ``serial``. (Contributed by Ross Light; :issue:`4285`.) +* The :mod:`threading` module's :meth:`Event.wait` method now returns + the internal flag on exit. This means the method will usually + return true because :meth:`wait` is supposed to block until the + internal flag becomes true. The return value will only be false if + a timeout was provided and the operation timed out. + (Contributed by XXX; :issue:`1674032`.) + * The :mod:`unittest` module was enhanced in several ways. + The progress messages will now show 'x' for expected failures + and 'u' for unexpected successes when run in verbose mode. + (Contributed by Benjamin Peterson.) Test cases can raise the :exc:`SkipTest` exception to skip a test. (:issue:`1034053`.) - It will now use 'x' for expected failures - and 'u' for unexpected successes when run in its verbose mode. - (Contributed by Benjamin Peterson.) + + The error messages for :meth:`assertEqual`, + :meth:`assertTrue`, and :meth:`assertFalse` + failures now provide more information. If you set the + :attr:`longMessage` attribute of your :class:`TestCase` classes to + true, both the standard error message and any additional message you + provide will be printed for failures. (Added by Michael Foord; :issue:`5663`.) The :meth:`assertRaises` and :meth:`failUnlessRaises` methods now return a context handler when called without providing a callable object to run. For example, you can write this:: - with self.assertRaises(KeyError): - raise ValueError + with self.assertRaises(KeyError): + raise ValueError (Implemented by Antoine Pitrou; :issue:`4444`.) + A number of new methods were added that provide more specialized + tests. Many of these methods were written by Google engineers + for use in their test suites; Gregory P. Smith, Michael Foord, and + GvR worked on merging them into Python's version of :mod:`unittest`. + + * :meth:`assertIsNone` and :meth:`assertIsNotNone` take one + expression and verify that the result is or is not ``None``. + + * :meth:`assertIs` and :meth:`assertIsNot` take two values and check + whether the two values evaluate to the same object or not. + (Added by Michael Foord; :issue:`2578`.) + + * :meth:`assertGreater`, :meth:`assertGreaterEqual`, + :meth:`assertLess`, and :meth:`assertLessEqual` compare + two quantities. + + * :meth:`assertMultiLineEqual` compares two strings, and if they're + not equal, displays a helpful comparison that highlights the + differences in the two strings. + + * :meth:`assertRegexpMatches` checks whether its first argument is a + string matching a regular expression provided as its second argument. + + * :meth:`assertRaisesRegexp` checks whether a particular exception + is raised, and then also checks that the string representation of + the exception matches the provided regular expression. + + * :meth:`assertIn` and :meth:`assertNotIn` tests whether + *first* is or is not in *second*. + + * :meth:`assertSameElements` tests whether two provided sequences + contain the same elements. + + * :meth:`assertSetEqual` compares whether two sets are equal, and + only reports the differences between the sets in case of error. + + * Similarly, :meth:`assertListEqual` and :meth:`assertTupleEqual` + compare the specified types and explain the differences. + More generally, :meth:`assertSequenceEqual` compares two sequences + and can optionally check whether both sequences are of a + particular type. + + * :meth:`assertDictEqual` compares two dictionaries and reports the + differences. :meth:`assertDictContainsSubset` checks whether + all of the key/value pairs in *first* are found in *second*. + + * A new hook, :meth:`addTypeEqualityFunc` takes a type object and a + function. The :meth:`assertEqual` method will use the function + when both of the objects being compared are of the specified type. + This function should compare the two objects and raise an + exception if they don't match; it's a good idea for the function + to provide additional information about why the two objects are + matching, much as the new sequence comparison methods do. + * The :func:`is_zipfile` function in the :mod:`zipfile` module will now accept a file object, in addition to the path names accepted in earlier versions. (Contributed by Gabriel Genellina; :issue:`4756`.) @@ -376,7 +487,37 @@ importlib: Importing Modules ------------------------------ -XXX write this +Python 3.1 includes the :mod:`importlib` package, a re-implementation +of the logic underlying Python's :keyword:`import` statement. +:mod:`importlib` is useful for implementors of Python interpreters and +to user who wish to write new importers that can participate in the +import process. Python 2.7 doesn't contain the complete +:mod:`importlib` package, but instead has a tiny subset that contains +a single function, :func:`import_module`. + +``import_module(*name*, *package*=None)`` imports a module. *name* is +a string containing the module or package's name. It's possible to do +relative imports by providing a string that begins with a ``.`` +character, such as ``..utils.errors``. For relative imports, the +*package* argument must be provided and is the name of the package that +will be used as the anchor for +the relative import. :func:`import_module` both inserts the imported +module into ``sys.modules`` and returns the module object. + +Here are some examples:: + + >>> from importlib import import_module + >>> anydbm = import_module('anydbm') # Standard absolute import + >>> anydbm + + >>> # Relative import + >>> sysconfig = import_module('..sysconfig', 'distutils.command') + >>> sysconfig + + +:mod:`importlib` was implemented by Brett Cannon and introduced in +Python 3.1. + ttk: Themed Widgets for Tk -------------------------- Modified: python/branches/py3k/Lib/distutils/command/__init__.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/__init__.py (original) +++ python/branches/py3k/Lib/distutils/command/__init__.py Sat Apr 11 22:45:40 2009 @@ -23,6 +23,7 @@ 'bdist_rpm', 'bdist_wininst', 'check', + 'upload', # These two are reserved for future use: #'bdist_sdux', #'bdist_pkgtool', Modified: python/branches/py3k/Lib/distutils/command/check.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/check.py (original) +++ python/branches/py3k/Lib/distutils/command/check.py Sat Apr 11 22:45:40 2009 @@ -27,8 +27,9 @@ self.messages.append((level, message, children, kwargs)) HAS_DOCUTILS = True -except ImportError: - # docutils is not installed +except Exception: + # Catch all exceptions because exceptions besides ImportError probably + # indicate that docutils is not ported to Py3k. HAS_DOCUTILS = False class check(Command): Modified: python/branches/py3k/Lib/multiprocessing/managers.py ============================================================================== --- python/branches/py3k/Lib/multiprocessing/managers.py (original) +++ python/branches/py3k/Lib/multiprocessing/managers.py Sat Apr 11 22:45:40 2009 @@ -478,12 +478,15 @@ dispatch(conn, None, 'dummy') self._state.value = State.STARTED - def start(self): + def start(self, initializer=None, initargs=()): ''' Spawn a server process for this manager object ''' assert self._state.value == State.INITIAL + if initializer is not None and not hasattr(initializer, '__call__'): + raise TypeError('initializer must be a callable') + # pipe over which we will retrieve address of server reader, writer = connection.Pipe(duplex=False) @@ -491,7 +494,7 @@ self._process = Process( target=type(self)._run_server, args=(self._registry, self._address, self._authkey, - self._serializer, writer), + self._serializer, writer, initializer, initargs), ) ident = ':'.join(str(i) for i in self._process._identity) self._process.name = type(self).__name__ + '-' + ident @@ -512,10 +515,14 @@ ) @classmethod - def _run_server(cls, registry, address, authkey, serializer, writer): + def _run_server(cls, registry, address, authkey, serializer, writer, + initializer=None, initargs=()): ''' Create a server, report its address and run it ''' + if initializer is not None: + initializer(*initargs) + # create server server = cls._Server(registry, address, authkey, serializer) Modified: python/branches/py3k/Lib/multiprocessing/pool.py ============================================================================== --- python/branches/py3k/Lib/multiprocessing/pool.py (original) +++ python/branches/py3k/Lib/multiprocessing/pool.py Sat Apr 11 22:45:40 2009 @@ -92,6 +92,9 @@ except NotImplementedError: processes = 1 + if initializer is not None and not hasattr(initializer, '__call__'): + raise TypeError('initializer must be a callable') + self._pool = [] for i in range(processes): w = self.Process( Modified: python/branches/py3k/Lib/test/test_multiprocessing.py ============================================================================== --- python/branches/py3k/Lib/test/test_multiprocessing.py (original) +++ python/branches/py3k/Lib/test/test_multiprocessing.py Sat Apr 11 22:45:40 2009 @@ -1832,7 +1832,37 @@ multiprocessing.connection.answer_challenge, _FakeConnection(), b'abc') -testcases_other = [OtherTest, TestInvalidHandle] +# +# Test Manager.start()/Pool.__init__() initializer feature - see issue 5585 +# + +def initializer(ns): + ns.test += 1 + +class TestInitializers(unittest.TestCase): + def setUp(self): + self.mgr = multiprocessing.Manager() + self.ns = self.mgr.Namespace() + self.ns.test = 0 + + def tearDown(self): + self.mgr.shutdown() + + def test_manager_initializer(self): + m = multiprocessing.managers.SyncManager() + self.assertRaises(TypeError, m.start, 1) + m.start(initializer, (self.ns,)) + self.assertEqual(self.ns.test, 1) + m.shutdown() + + def test_pool_initializer(self): + self.assertRaises(TypeError, multiprocessing.Pool, initializer=1) + p = multiprocessing.Pool(1, initializer, (self.ns,)) + p.close() + p.join() + self.assertEqual(self.ns.test, 1) + +testcases_other = [OtherTest, TestInvalidHandle, TestInitializers] # # 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 Sat Apr 11 22:45:40 2009 @@ -2311,6 +2311,16 @@ # from this TestCase instance but since its a local nothing else # will ever notice that. + def testAssertIs(self): + thing = object() + self.assertIs(thing, thing) + self.assertRaises(self.failureException, self.assertIs, thing, object()) + + def testAssertIsNot(self): + thing = object() + self.assertIsNot(thing, object()) + self.assertRaises(self.failureException, self.assertIsNot, thing, thing) + def testAssertIn(self): animals = {'monkey': 'banana', 'cow': 'grass', 'seal': 'fish'} @@ -2454,6 +2464,7 @@ # Test that sequences of unhashable objects can be tested for sameness: self.assertSameElements([[1, 2], [3, 4]], [[3, 4], [1, 2]]) + self.assertSameElements([{'a': 1}, {'b': 2}], [{'b': 2}, {'a': 1}]) self.assertRaises(self.failureException, self.assertSameElements, [[1]], [[2]]) @@ -2988,6 +2999,18 @@ "^unexpectedly None$", "^unexpectedly None : oops$"]) + def testAssertIs(self): + self.assertMessages('assertIs', (None, 'foo'), + ["^None is not 'foo'$", "^oops$", + "^None is not 'foo'$", + "^None is not 'foo' : oops$"]) + + def testAssertIsNot(self): + self.assertMessages('assertIsNot', (None, None), + ["^unexpectedly identical: None$", "^oops$", + "^unexpectedly identical: None$", + "^unexpectedly identical: None : oops$"]) + ###################################################################### ## Main Modified: python/branches/py3k/Lib/unittest.py ============================================================================== --- python/branches/py3k/Lib/unittest.py (original) +++ python/branches/py3k/Lib/unittest.py Sat Apr 11 22:45:40 2009 @@ -807,6 +807,18 @@ standardMsg = '%r unexpectedly found in %r' % (member, container) self.fail(self._formatMessage(msg, standardMsg)) + def assertIs(self, expr1, expr2, msg=None): + """Just like self.assertTrue(a is b), but with a nicer default message.""" + if expr1 is not expr2: + standardMsg = '%r is not %r' % (expr1, expr2) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertIsNot(self, expr1, expr2, msg=None): + """Just like self.assertTrue(a is not b), but with a nicer default message.""" + if expr1 is expr2: + standardMsg = 'unexpectedly identical: %r' % (expr1,) + self.fail(self._formatMessage(msg, standardMsg)) + def assertDictEqual(self, d1, d2, msg=None): self.assert_(isinstance(d1, dict), 'First argument is not a dictionary') self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary') @@ -1020,7 +1032,7 @@ self.addTests(tests) def __repr__(self): - return "<%s tests=%s>" % (_strclass(self.__class__), self._tests) + return "<%s tests=%s>" % (_strclass(self.__class__), list(self)) def __eq__(self, other): if not isinstance(other, self.__class__): @@ -1035,7 +1047,7 @@ def countTestCases(self): cases = 0 - for test in self._tests: + for test in self: cases += test.countTestCases() return cases @@ -1055,7 +1067,7 @@ self.addTest(test) def run(self, result): - for test in self._tests: + for test in self: if result.shouldStop: break test(result) @@ -1066,7 +1078,7 @@ def debug(self): """Run the tests without collecting errors in a TestResult""" - for test in self._tests: + for test in self: test.debug() Modified: python/branches/py3k/Makefile.pre.in ============================================================================== --- python/branches/py3k/Makefile.pre.in (original) +++ python/branches/py3k/Makefile.pre.in Sat Apr 11 22:45:40 2009 @@ -841,6 +841,7 @@ sqlite3 sqlite3/test \ logging bsddb bsddb/test csv wsgiref urllib \ lib2to3 lib2to3/fixes lib2to3/pgen2 lib2to3/tests \ + lib2to3/tests/data lib2to3/tests/data/fixes lib2to3/tests/data/fixers/myfixes \ ctypes ctypes/test ctypes/macholib idlelib idlelib/Icons \ distutils distutils/command distutils/tests $(XMLLIBSUBDIRS) \ importlib importlib/test importlib/test/builtin \ @@ -908,11 +909,13 @@ -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ ./$(BUILDPYTHON) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \ -d $(LIBDEST) -f \ - -x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST) + -x 'bad_coding|badsyntax|site-packages|py2_test_grammar' \ + $(DESTDIR)$(LIBDEST) -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ ./$(BUILDPYTHON) -Wi -O $(DESTDIR)$(LIBDEST)/compileall.py \ -d $(LIBDEST) -f \ - -x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST) + -x 'bad_coding|badsyntax|site-packages|py2_test_grammar' \ + $(DESTDIR)$(LIBDEST) -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ ./$(BUILDPYTHON) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \ -d $(LIBDEST)/site-packages -f \ Modified: python/branches/py3k/Misc/README ============================================================================== --- python/branches/py3k/Misc/README (original) +++ python/branches/py3k/Misc/README Sat Apr 11 22:45:40 2009 @@ -21,6 +21,7 @@ pymemcompat.h Memory interface compatibility file. python.man UNIX man page for the python interpreter python-mode.el Emacs mode for editing Python programs +python-wing.wpr Wing IDE project file README The file you're reading now README.valgrind Information for Valgrind users, see valgrind-python.supp RFD Request For Discussion about a Python newsgroup Modified: python/branches/py3k/Misc/gdbinit ============================================================================== --- python/branches/py3k/Misc/gdbinit (original) +++ python/branches/py3k/Misc/gdbinit Sat Apr 11 22:45:40 2009 @@ -138,3 +138,16 @@ end select-frame 0 end + +# generally useful macro to print a Unicode string +def pu + set $uni = $arg0 + set $i = 0 + while (*$uni && $i++<100) + if (*$uni < 0x80) + print *(char*)$uni++ + else + print /x *(short*)$uni++ + end + end +end From python-checkins at python.org Sat Apr 11 22:58:12 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Apr 2009 22:58:12 +0200 (CEST) Subject: [Python-checkins] r71501 - in python/branches/py3k: Doc/whatsnew/2.7.rst Message-ID: <20090411205812.D37551E4043@bag.python.org> Author: benjamin.peterson Date: Sat Apr 11 22:58:12 2009 New Revision: 71501 Log: Merged revisions 71498 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71498 | benjamin.peterson | 2009-04-11 15:27:15 -0500 (Sat, 11 Apr 2009) | 1 line fix markup ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/whatsnew/2.7.rst Modified: python/branches/py3k/Doc/whatsnew/2.7.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/2.7.rst (original) +++ python/branches/py3k/Doc/whatsnew/2.7.rst Sat Apr 11 22:58:12 2009 @@ -88,22 +88,21 @@ Some smaller changes made to the core Python language are: -* The string :method:`format` method now supports automatic numbering - of the replacement fields. This makes using :meth:`format` - more closely resemble using ``%s`` formatting:: +* :meth:`str.format` method now supports automatic numbering of the replacement + fields. This makes using :meth:`str.format` more closely resemble using + ``%s`` formatting:: >>> '{}:{}:{}'.format(2009, 04, 'Sunday') '2009:4:Sunday' >>> '{}:{}:{day}'.format(2009, 4, day='Sunday') '2009:4:Sunday' - The auto-numbering takes the fields from left to right, so the first - ``{...}`` specifier will use the first argument to :meth:`format`, - the next specifier will use the next argument, and so on. You can't - mix auto-numbering and explicit numbering -- either number all of - your specifier fields or none of them -- but you can mix - auto-numbering and named fields, as in the second example above. - (Contributed by XXX; :issue`5237`.) + The auto-numbering takes the fields from left to right, so the first ``{...}`` + specifier will use the first argument to :meth:`str.format`, the next + specifier will use the next argument, and so on. You can't mix auto-numbering + and explicit numbering -- either number all of your specifier fields or none + of them -- but you can mix auto-numbering and named fields, as in the second + example above. (Contributed by XXX; :issue`5237`.) * The :func:`int` and :func:`long` types gained a ``bit_length`` method that returns the number of bits necessary to represent From python-checkins at python.org Sat Apr 11 23:24:37 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 11 Apr 2009 23:24:37 +0200 (CEST) Subject: [Python-checkins] r71502 - in python/branches/py3k: Misc/NEWS Python/errors.c Message-ID: <20090411212437.9BAC31E4043@bag.python.org> Author: georg.brandl Date: Sat Apr 11 23:24:37 2009 New Revision: 71502 Log: Merged revisions 71024,71058 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71024 | georg.brandl | 2009-04-02 04:47:44 +0200 (Do, 02 Apr 2009) | 4 lines In PyErr_GivenExceptionMatches, temporarily bump the recursion limit, so that in the most common case PyObject_IsSubclass will not raise a recursion error we have to ignore anyway. ........ r71058 | georg.brandl | 2009-04-02 20:09:04 +0200 (Do, 02 Apr 2009) | 3 lines PyErr_NormalizeException may not set an error, so convert the PyErr_SetObject call on hitting the recursion limit into just assigning it to the arguments provided. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Misc/NEWS python/branches/py3k/Python/errors.c Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Apr 11 23:24:37 2009 @@ -47,6 +47,9 @@ - Issue #5499: The 'c' code for argument parsing functions now only accepts a byte, and the 'C' code only accepts a unicode character. +- Fix a problem in PyErr_NormalizeException that leads to "undetected errors" + when hitting the recursion limit under certain circumstances. + - Issue #1665206: Remove the last eager import in _warnings.c and make it lazy. - Fix a segfault when running test_exceptions with coverage, caused by Modified: python/branches/py3k/Python/errors.c ============================================================================== --- python/branches/py3k/Python/errors.c (original) +++ python/branches/py3k/Python/errors.c Sat Apr 11 23:24:37 2009 @@ -279,7 +279,15 @@ tstate = PyThreadState_GET(); if (++tstate->recursion_depth > Py_GetRecursionLimit()) { --tstate->recursion_depth; - PyErr_SetObject(PyExc_RuntimeError, PyExc_RecursionErrorInst); + /* throw away the old exception... */ + Py_DECREF(*exc); + Py_DECREF(*val); + /* ... and use the recursion error instead */ + *exc = PyExc_RuntimeError; + *val = PyExc_RecursionErrorInst; + Py_INCREF(*exc); + Py_INCREF(*val); + /* just keeping the old traceback */ return; } PyErr_NormalizeException(exc, val, tb); From buildbot at python.org Sat Apr 11 23:46:51 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 11 Apr 2009 21:46:51 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090411214651.BB39E1E4043@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/515 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson,georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 249, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 143, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From buildbot at python.org Sat Apr 11 23:55:46 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 11 Apr 2009 21:55:46 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 3.x Message-ID: <20090411215546.71ED11E4043@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%203.x/builds/658 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: make: *** [buildbottest] Abort trap sincerely, -The Buildbot From python-checkins at python.org Sun Apr 12 04:57:29 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 12 Apr 2009 04:57:29 +0200 (CEST) Subject: [Python-checkins] r71503 - python/trunk/Doc/whatsnew/2.7.rst Message-ID: <20090412025729.9307D1E401C@bag.python.org> Author: eric.smith Date: Sun Apr 12 04:57:29 2009 New Revision: 71503 Log: Take credit for my patch for issue 5237. Modified: python/trunk/Doc/whatsnew/2.7.rst Modified: python/trunk/Doc/whatsnew/2.7.rst ============================================================================== --- python/trunk/Doc/whatsnew/2.7.rst (original) +++ python/trunk/Doc/whatsnew/2.7.rst Sun Apr 12 04:57:29 2009 @@ -102,7 +102,7 @@ specifier will use the next argument, and so on. You can't mix auto-numbering and explicit numbering -- either number all of your specifier fields or none of them -- but you can mix auto-numbering and named fields, as in the second - example above. (Contributed by XXX; :issue`5237`.) + example above. (Contributed by Eric Smith; :issue`5237`.) * The :func:`int` and :func:`long` types gained a ``bit_length`` method that returns the number of bits necessary to represent From nnorwitz at gmail.com Sun Apr 12 10:11:08 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 12 Apr 2009 04:11:08 -0400 Subject: [Python-checkins] Python Regression Test Failures basics (2) Message-ID: <20090412081108.GA27399@python.psfb.org> 332 tests OK. 2 tests failed: test_lib2to3 test_multiprocessing 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23366 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 test_lib2to3 failed -- errors occurred; run in verbose mode for details 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 test_multiprocessing crashed -- : cannot import name SkipTest test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18902 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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 332 tests OK. 2 tests failed: test_lib2to3 test_multiprocessing 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl [741627 refs] From nnorwitz at gmail.com Sun Apr 12 10:18:50 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 12 Apr 2009 04:18:50 -0400 Subject: [Python-checkins] Python Regression Test Failures opt (3) Message-ID: <20090412081850.GA29830@python.psfb.org> 331 tests OK. 3 tests failed: test_asyncore test_lib2to3 test_multiprocessing 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ast test_asynchat test_asyncore test test_asyncore failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_asyncore.py", line 280, in test_log_info self.assertEquals(lines, expected) AssertionError: First differing element 1: info: Why can't she have egg bacon spam and sausage? SPAM: THAT'S got spam in it! + ['EGGS: Have you got anything without spam?', "SPAM: THAT'S got spam in it!"] - ['EGGS: Have you got anything without spam?', - "info: Why can't she have egg bacon spam and sausage?", - "SPAM: THAT'S got spam in it!"] 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils [17363 refs] [17363 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23366 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 test_lib2to3 failed -- errors occurred; run in verbose mode for details 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 test_multiprocessing crashed -- : cannot import name SkipTest test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18902 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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 331 tests OK. 3 tests failed: test_asyncore test_lib2to3 test_multiprocessing 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl [740863 refs] From python-checkins at python.org Sun Apr 12 11:50:49 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 12 Apr 2009 11:50:49 +0200 (CEST) Subject: [Python-checkins] r71504 - in python/branches/py3k-short-float-repr: Lib/test/test_float.py Python/dtoa.c Message-ID: <20090412095049.E18701E4014@bag.python.org> Author: mark.dickinson Date: Sun Apr 12 11:50:49 2009 New Revision: 71504 Log: Fix redundant if test Modified: python/branches/py3k-short-float-repr/Lib/test/test_float.py python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Lib/test/test_float.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_float.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_float.py Sun Apr 12 11:50:49 2009 @@ -1,7 +1,6 @@ import unittest, struct import os -import sys from test import support import math from math import isinf, isnan, copysign, ldexp @@ -12,11 +11,7 @@ NAN = float("nan") #locate file with float format test values -if __name__ == '__main__': - file = sys.argv[0] -else: - file = __file__ -test_dir = os.path.dirname(file) or os.curdir +test_dir = os.path.dirname(__file__) or os.curdir format_testfile = os.path.join(test_dir, 'formatfloat_testcases.txt') class GeneralFloatCases(unittest.TestCase): Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Sun Apr 12 11:50:49 2009 @@ -874,8 +874,6 @@ ULong *xa, *xa0, w, y, z; int k; U d; -#define d0 word0(&d) -#define d1 word1(&d) xa0 = a->x; xa = xa0 + a->wds; @@ -886,28 +884,34 @@ k = hi0bits(y); *e = 32 - k; if (k < Ebits) { - d0 = Exp_1 | y >> (Ebits - k); + word0(&d) = Exp_1 | y >> (Ebits - k); w = xa > xa0 ? *--xa : 0; - d1 = y << ((32-Ebits) + k) | w >> (Ebits - k); + word1(&d) = y << ((32-Ebits) + k) | w >> (Ebits - k); goto ret_d; } z = xa > xa0 ? *--xa : 0; if (k -= Ebits) { - d0 = Exp_1 | y << k | z >> (32 - k); + word0(&d) = Exp_1 | y << k | z >> (32 - k); y = xa > xa0 ? *--xa : 0; - d1 = z << k | y >> (32 - k); + word1(&d) = z << k | y >> (32 - k); } else { - d0 = Exp_1 | y; - d1 = z; + word0(&d) = Exp_1 | y; + word1(&d) = z; } ret_d: -#undef d0 -#undef d1 return dval(&d); } -/* Convert a double to a Bigint plus an exponent. Return NULL on failure. */ +/* Convert a double to a Bigint plus an exponent. Return NULL on failure. + + Given a finite nonzero double d, return an odd Bigint b and exponent *e + such that fabs(d) = b * 2**e. On return, *bbits gives the number of + significant bits of e; that is, 2**(*bbits-1) <= b < 2**(*bbits). + + If d is zero, then b == 0, *e == -1010, *bbits = 0. + */ + static Bigint * d2b(U *d, int *e, int *bits) @@ -916,19 +920,17 @@ int de, k; ULong *x, y, z; int i; -#define d0 word0(d) -#define d1 word1(d) b = Balloc(1); if (b == NULL) return NULL; x = b->x; - z = d0 & Frac_mask; - d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ - if ((de = (int)(d0 >> Exp_shift))) + z = word0(d) & Frac_mask; + word0(d) &= 0x7fffffff; /* clear sign bit, which we ignore */ + if ((de = (int)(word0(d) >> Exp_shift))) z |= Exp_msk1; - if ((y = d1)) { + if ((y = word1(d))) { if ((k = lo0bits(&y))) { x[0] = y | z << (32 - k); z >>= k; @@ -955,8 +957,6 @@ } return b; } -#undef d0 -#undef d1 /* Compute the ratio of two Bigints, as a double. The result may have an error of up to 2.5 ulps. */ @@ -2084,6 +2084,7 @@ else *sign = 0; + /* quick return for Infinities, NaNs and zeros */ if ((word0(&u) & Exp_mask) == Exp_mask) { /* Infinity or NaN */ @@ -2097,7 +2098,8 @@ return nrv_alloc("0", rve, 1); } - + /* compute k = floor(log10(d)). The computation may leave k + one too large, but should never leave k too small. */ b = d2b(&u, &be, &bbits); if (b == NULL) goto failed_malloc; From python-checkins at python.org Sun Apr 12 13:34:16 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 12 Apr 2009 13:34:16 +0200 (CEST) Subject: [Python-checkins] r71505 - python/branches/py3k/Parser/asdl.py Message-ID: <20090412113416.5BA851E4014@bag.python.org> Author: georg.brandl Date: Sun Apr 12 13:34:13 2009 New Revision: 71505 Log: #2725: Fix missing local, and handle errors without tracebacks. Modified: python/branches/py3k/Parser/asdl.py Modified: python/branches/py3k/Parser/asdl.py ============================================================================== --- python/branches/py3k/Parser/asdl.py (original) +++ python/branches/py3k/Parser/asdl.py Sun Apr 12 13:34:13 2009 @@ -405,7 +405,8 @@ try: return parser.parse(tokens) except ASDLSyntaxError: - output(sys.exc_info()[1]) + err = sys.exc_info()[1] + output(str(err)) lines = buf.split("\n") output(lines[err.lineno - 1]) # lines starts at 0, files at 1 @@ -422,6 +423,8 @@ for file in files: output(file) mod = parse(file) + if not mod: + break output("module", mod.name) output(len(mod.dfns), "definitions") if not check(mod): From python-checkins at python.org Sun Apr 12 14:01:51 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 12 Apr 2009 14:01:51 +0200 (CEST) Subject: [Python-checkins] r71506 - python/branches/py3k/Objects/unicodeobject.c Message-ID: <20090412120151.311EF1E402B@bag.python.org> Author: georg.brandl Date: Sun Apr 12 14:01:50 2009 New Revision: 71506 Log: #5708: a bit of streamlining in unicode_repeat(). 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 Sun Apr 12 14:01:50 2009 @@ -7738,8 +7738,10 @@ Py_ssize_t nchars; size_t nbytes; - if (len < 0) - len = 0; + if (len < 1) { + Py_INCREF(unicode_empty); + return (PyObject *)unicode_empty; + } if (len == 1 && PyUnicode_CheckExact(str)) { /* no repeat, return original string */ @@ -7751,7 +7753,7 @@ * needed doesn't overflow size_t */ nchars = len * str->length; - if (len && nchars / len != str->length) { + if (nchars / len != str->length) { PyErr_SetString(PyExc_OverflowError, "repeated string is too long"); return NULL; @@ -7768,14 +7770,11 @@ p = u->str; - if (str->length == 1 && len > 0) { + if (str->length == 1) { Py_UNICODE_FILL(p, str->str[0], len); } else { - Py_ssize_t done = 0; /* number of characters copied this far */ - if (done < nchars) { - Py_UNICODE_COPY(p, str->str, str->length); - done = str->length; - } + Py_ssize_t done = str->length; /* number of characters copied this far */ + Py_UNICODE_COPY(p, str->str, str->length); while (done < nchars) { Py_ssize_t n = (done <= nchars-done) ? done : nchars-done; Py_UNICODE_COPY(p+done, p, n); From python-checkins at python.org Sun Apr 12 14:08:13 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 12 Apr 2009 14:08:13 +0200 (CEST) Subject: [Python-checkins] r71507 - in python/trunk: Misc/NEWS Modules/main.c Message-ID: <20090412120813.BE2601E402B@bag.python.org> Author: georg.brandl Date: Sun Apr 12 14:08:12 2009 New Revision: 71507 Log: #5704: let python -3 imply -t as well. Modified: python/trunk/Misc/NEWS python/trunk/Modules/main.c Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Apr 12 14:08:12 2009 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #5704: the "-3" command-line option now implies "-t". + - Issue #2170: refactored xml.dom.minidom.normalize, increasing both its clarity and its speed. Modified: python/trunk/Modules/main.c ============================================================================== --- python/trunk/Modules/main.c (original) +++ python/trunk/Modules/main.c Sun Apr 12 14:08:12 2009 @@ -432,6 +432,10 @@ return 0; } + if (Py_Py3kWarningFlag && !Py_TabcheckFlag) + /* -3 implies -t (but not -tt) */ + Py_TabcheckFlag = 1; + if (!Py_InspectFlag && (p = Py_GETENV("PYTHONINSPECT")) && *p != '\0') Py_InspectFlag = 1; From python-checkins at python.org Sun Apr 12 14:54:32 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 12 Apr 2009 14:54:32 +0200 (CEST) Subject: [Python-checkins] r71508 - python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Message-ID: <20090412125432.2BF921E402B@bag.python.org> Author: eric.smith Date: Sun Apr 12 14:54:31 2009 New Revision: 71508 Log: Cleaned up some comments. Made float and int/long routines more similar. I might combine their 'back ends', where they actually build up the resulting strings. Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h (original) +++ python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Sun Apr 12 14:54:31 2009 @@ -665,7 +665,6 @@ STRINGLIB_CHAR *pnumeric_chars; STRINGLIB_CHAR numeric_char; STRINGLIB_CHAR sign_char = '\0'; - STRINGLIB_CHAR *p; Py_ssize_t n_digits; /* count of digits need from the computed string */ Py_ssize_t n_remainder = 0; /* Used only for 'c' formatting, which @@ -804,19 +803,19 @@ LT_NO_LOCALE), &locale); - /* Calculate the widths of the various leading and trailing parts */ + /* Calculate how much memory we'll need. */ calc_number_widths(&spec, n_prefix, sign_char, pnumeric_chars, n_digits, n_remainder, 0, &locale, format); - /* Allocate a new string to hold the result */ + /* Allocate the memory. */ result = STRINGLIB_NEW(NULL, spec.n_total); if (!result) goto done; - p = STRINGLIB_STR(result); - fill_number(p, &spec, pnumeric_chars, n_digits, prefix, - format->fill_char == '\0' ? ' ' : format->fill_char, &locale, - format->type == 'X'); + /* Populate the memory. */ + fill_number(STRINGLIB_STR(result), &spec, pnumeric_chars, n_digits, + prefix, format->fill_char == '\0' ? ' ' : format->fill_char, + &locale, format->type == 'X'); done: Py_XDECREF(tmp); @@ -919,12 +918,8 @@ } /* Since there is no unicode version of PyOS_double_to_string, - just use the 8 bit version and then convert to unicode in a - separate code path. */ + just use the 8 bit version and then convert to unicode. */ #if STRINGLIB_IS_UNICODE - /* This could probably be optimized away by converting into the - memory returned by STRINGLIB_NEW, but that's a project for - another day. */ unicode_tmp = (Py_UNICODE*)PyMem_Malloc((n_digits)*sizeof(Py_UNICODE)); if (unicode_tmp == NULL) { PyErr_NoMemory(); @@ -944,26 +939,26 @@ --n_digits; } + /* Determine if we have any "remainder" (after the digits, might include + decimal or exponent or both (or neither)) */ + parse_number(p, n_digits, &n_remainder, &has_decimal); + /* Determine the grouping, separator, and decimal point, if any. */ get_locale_info(type == 'n' ? LT_USE_LOCALE : (format->thousands_separators ? LT_DEFAULT_LOCALE : LT_NO_LOCALE), &locale); - /* Determine if we have any "remainder" (after the digits, might include - decimal or exponent or both (or neither)) */ - parse_number(p, n_digits, &n_remainder, &has_decimal); - - /* Calculate how much space we'll need. */ + /* Calculate how much memory we'll need. */ calc_number_widths(&spec, 0, sign_char, p, n_digits, n_remainder, has_decimal, &locale, format); - /* Allocate that space. */ + /* Allocate the memory. */ result = STRINGLIB_NEW(NULL, spec.n_total); if (result == NULL) goto done; - /* Populate the space. */ + /* Populate the memory. */ fill_number(STRINGLIB_STR(result), &spec, p, n_digits, NULL, format->fill_char == '\0' ? ' ' : format->fill_char, &locale, 0); From python-checkins at python.org Sun Apr 12 16:53:52 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 12 Apr 2009 16:53:52 +0200 (CEST) Subject: [Python-checkins] r71509 - in python/trunk/Lib/distutils: command/config.py tests/test_config_cmd.py Message-ID: <20090412145352.4BC771E402B@bag.python.org> Author: tarek.ziade Date: Sun Apr 12 16:53:51 2009 New Revision: 71509 Log: removed the print statements and added a test Added: python/trunk/Lib/distutils/tests/test_config_cmd.py (contents, props changed) Modified: python/trunk/Lib/distutils/command/config.py Modified: python/trunk/Lib/distutils/command/config.py ============================================================================== --- python/trunk/Lib/distutils/command/config.py (original) +++ python/trunk/Lib/distutils/command/config.py Sun Apr 12 16:53:51 2009 @@ -354,13 +354,17 @@ # class config +def dump_file(filename, head=None): + """Dumps a file content into log.info. -def dump_file (filename, head=None): + If head is not None, will be dumped before the file content. + """ if head is None: - print filename + ":" + log.info('%s' % filename) else: - print head - + log.info(head) file = open(filename) - sys.stdout.write(file.read()) - file.close() + try: + log.info(file.read()) + finally: + file.close() Added: python/trunk/Lib/distutils/tests/test_config_cmd.py ============================================================================== --- (empty file) +++ python/trunk/Lib/distutils/tests/test_config_cmd.py Sun Apr 12 16:53:51 2009 @@ -0,0 +1,42 @@ +"""Tests for distutils.command.config.""" +import unittest +import os + +from distutils.command.config import dump_file +from distutils.tests import support +from distutils import log + +class ConfigTestCase(support.LoggingSilencer, + support.TempdirManager, + unittest.TestCase): + + def _info(self, msg): + for line in msg.splitlines(): + self._logs.append(line) + + def setUp(self): + super(ConfigTestCase, self).setUp() + self._logs = [] + self.old_log = log.info + log.info = self._info + + def tearDown(self): + log.info = self.old_log + super(ConfigTestCase, self).tearDown() + + def test_dump_file(self): + this_file = os.path.splitext(__file__)[0] + '.py' + f = open(this_file) + try: + numlines = len(f.readlines()) + finally: + f.close() + + dump_file(this_file, 'I am the header') + self.assertEquals(len(self._logs), numlines+1) + +def test_suite(): + return unittest.makeSuite(ConfigTestCase) + +if __name__ == "__main__": + unittest.main(defaultTest="test_suite") From python-checkins at python.org Sun Apr 12 16:54:50 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 12 Apr 2009 16:54:50 +0200 (CEST) Subject: [Python-checkins] r71510 - python/branches/release26-maint Message-ID: <20090412145450.BECF11E402B@bag.python.org> Author: tarek.ziade Date: Sun Apr 12 16:54:50 2009 New Revision: 71510 Log: Blocked revisions 71509 via svnmerge ........ r71509 | tarek.ziade | 2009-04-12 16:53:51 +0200 (Sun, 12 Apr 2009) | 1 line removed the print statements and added a test ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Apr 12 16:57:47 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 12 Apr 2009 16:57:47 +0200 (CEST) Subject: [Python-checkins] r71511 - in python/branches/py3k: Lib/distutils/command/config.py Lib/distutils/tests/test_config_cmd.py Message-ID: <20090412145747.9CE011E402B@bag.python.org> Author: tarek.ziade Date: Sun Apr 12 16:57:46 2009 New Revision: 71511 Log: Merged revisions 71509 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71509 | tarek.ziade | 2009-04-12 16:53:51 +0200 (Sun, 12 Apr 2009) | 1 line removed the print statements and added a test ........ Added: python/branches/py3k/Lib/distutils/tests/test_config_cmd.py - copied unchanged from r71509, /python/trunk/Lib/distutils/tests/test_config_cmd.py Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/command/config.py Modified: python/branches/py3k/Lib/distutils/command/config.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/config.py (original) +++ python/branches/py3k/Lib/distutils/command/config.py Sun Apr 12 16:57:46 2009 @@ -336,11 +336,16 @@ def dump_file(filename, head=None): + """Dumps a file content into log.info. + + If head is not None, will be dumped before the file content. + """ if head is None: - print(filename + ":") + log.info('%s' % filename) else: - print(head) - + log.info(head) file = open(filename) - sys.stdout.write(file.read()) - file.close() + try: + log.info(file.read()) + finally: + file.close() From python-checkins at python.org Sun Apr 12 16:58:41 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 12 Apr 2009 16:58:41 +0200 (CEST) Subject: [Python-checkins] r71512 - python/branches/release30-maint Message-ID: <20090412145841.2DA951E402B@bag.python.org> Author: tarek.ziade Date: Sun Apr 12 16:58:39 2009 New Revision: 71512 Log: Blocked revisions 71511 via svnmerge ................ r71511 | tarek.ziade | 2009-04-12 16:57:46 +0200 (Sun, 12 Apr 2009) | 9 lines Merged revisions 71509 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71509 | tarek.ziade | 2009-04-12 16:53:51 +0200 (Sun, 12 Apr 2009) | 1 line removed the print statements and added a test ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sun Apr 12 17:03:51 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 12 Apr 2009 17:03:51 +0200 (CEST) Subject: [Python-checkins] r71513 - python/trunk/Lib/distutils/command/config.py Message-ID: <20090412150351.427431E4037@bag.python.org> Author: tarek.ziade Date: Sun Apr 12 17:03:50 2009 New Revision: 71513 Log: pep8-fied the module before adding tests Modified: python/trunk/Lib/distutils/command/config.py Modified: python/trunk/Lib/distutils/command/config.py ============================================================================== --- python/trunk/Lib/distutils/command/config.py (original) +++ python/trunk/Lib/distutils/command/config.py Sun Apr 12 17:03:50 2009 @@ -18,10 +18,9 @@ from distutils.sysconfig import customize_compiler from distutils import log -LANG_EXT = {'c': '.c', - 'c++': '.cxx'} +LANG_EXT = {'c': '.c', 'c++': '.cxx'} -class config (Command): +class config(Command): description = "prepare to build" @@ -51,12 +50,10 @@ # The three standard command methods: since the "config" command # does nothing by default, these are empty. - def initialize_options (self): + def initialize_options(self): self.compiler = None self.cc = None self.include_dirs = None - #self.define = None - #self.undef = None self.libraries = None self.library_dirs = None @@ -68,7 +65,7 @@ # to clean at some point self.temp_files = [] - def finalize_options (self): + def finalize_options(self): if self.include_dirs is None: self.include_dirs = self.distribution.include_dirs or [] elif type(self.include_dirs) is StringType: @@ -93,7 +90,7 @@ # loosely based on Autoconf macros of similar names. Sub-classes # may use these freely. - def _check_compiler (self): + def _check_compiler(self): """Check that 'self.compiler' really is a CCompiler object; if not, make it one. """ @@ -112,7 +109,7 @@ self.compiler.set_library_dirs(self.library_dirs) - def _gen_temp_sourcefile (self, body, headers, lang): + def _gen_temp_sourcefile(self, body, headers, lang): filename = "_configtest" + LANG_EXT[lang] file = open(filename, "w") if headers: @@ -125,14 +122,14 @@ file.close() return filename - def _preprocess (self, body, headers, include_dirs, lang): + def _preprocess(self, body, headers, include_dirs, lang): src = self._gen_temp_sourcefile(body, headers, lang) out = "_configtest.i" self.temp_files.extend([src, out]) self.compiler.preprocess(src, out, include_dirs=include_dirs) return (src, out) - def _compile (self, body, headers, include_dirs, lang): + def _compile(self, body, headers, include_dirs, lang): src = self._gen_temp_sourcefile(body, headers, lang) if self.dump_source: dump_file(src, "compiling '%s':" % src) @@ -141,9 +138,8 @@ self.compiler.compile([src], include_dirs=include_dirs) return (src, obj) - def _link (self, body, - headers, include_dirs, - libraries, library_dirs, lang): + def _link(self, body, headers, include_dirs, libraries, library_dirs, + lang): (src, obj) = self._compile(body, headers, include_dirs, lang) prog = os.path.splitext(os.path.basename(src))[0] self.compiler.link_executable([obj], prog, @@ -157,7 +153,7 @@ return (src, obj, prog) - def _clean (self, *filenames): + def _clean(self, *filenames): if not filenames: filenames = self.temp_files self.temp_files = [] @@ -179,7 +175,7 @@ # XXX need access to the header search path and maybe default macros. - def try_cpp (self, body=None, headers=None, include_dirs=None, lang="c"): + def try_cpp(self, body=None, headers=None, include_dirs=None, lang="c"): """Construct a source file from 'body' (a string containing lines of C/C++ code) and 'headers' (a list of header files to include) and run it through the preprocessor. Return true if the @@ -197,8 +193,8 @@ self._clean() return ok - def search_cpp (self, pattern, body=None, - headers=None, include_dirs=None, lang="c"): + def search_cpp(self, pattern, body=None, headers=None, include_dirs=None, + lang="c"): """Construct a source file (just like 'try_cpp()'), run it through the preprocessor, and return true if any line of the output matches 'pattern'. 'pattern' should either be a compiled regex object or a @@ -227,7 +223,7 @@ self._clean() return match - def try_compile (self, body, headers=None, include_dirs=None, lang="c"): + def try_compile(self, body, headers=None, include_dirs=None, lang="c"): """Try to compile a source file built from 'body' and 'headers'. Return true on success, false otherwise. """ @@ -243,10 +239,8 @@ self._clean() return ok - def try_link (self, body, - headers=None, include_dirs=None, - libraries=None, library_dirs=None, - lang="c"): + def try_link(self, body, headers=None, include_dirs=None, libraries=None, + library_dirs=None, lang="c"): """Try to compile and link a source file, built from 'body' and 'headers', to executable form. Return true on success, false otherwise. @@ -264,10 +258,8 @@ self._clean() return ok - def try_run (self, body, - headers=None, include_dirs=None, - libraries=None, library_dirs=None, - lang="c"): + def try_run(self, body, headers=None, include_dirs=None, libraries=None, + library_dirs=None, lang="c"): """Try to compile, link to an executable, and run a program built from 'body' and 'headers'. Return true on success, false otherwise. @@ -291,10 +283,8 @@ # (these are the ones that are actually likely to be useful # when implementing a real-world config command!) - def check_func (self, func, - headers=None, include_dirs=None, - libraries=None, library_dirs=None, - decl=0, call=0): + def check_func(self, func, headers=None, include_dirs=None, + libraries=None, library_dirs=None, decl=0, call=0): """Determine if function 'func' is available by constructing a source file that refers to 'func', and compiles and links it. @@ -327,8 +317,8 @@ # check_func () - def check_lib (self, library, library_dirs=None, - headers=None, include_dirs=None, other_libraries=[]): + def check_lib(self, library, library_dirs=None, headers=None, + include_dirs=None, other_libraries=[]): """Determine if 'library' is available to be linked against, without actually checking that any particular symbols are provided by it. 'headers' will be used in constructing the source file to @@ -342,8 +332,8 @@ headers, include_dirs, [library]+other_libraries, library_dirs) - def check_header (self, header, include_dirs=None, - library_dirs=None, lang="c"): + def check_header(self, header, include_dirs=None, library_dirs=None, + lang="c"): """Determine if the system header file named by 'header_file' exists and can be found by the preprocessor; return true if so, false otherwise. @@ -352,8 +342,6 @@ include_dirs=include_dirs) -# class config - def dump_file(filename, head=None): """Dumps a file content into log.info. From python-checkins at python.org Sun Apr 12 17:04:56 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 12 Apr 2009 17:04:56 +0200 (CEST) Subject: [Python-checkins] r71514 - python/branches/release26-maint Message-ID: <20090412150456.A4ACB1E4037@bag.python.org> Author: tarek.ziade Date: Sun Apr 12 17:04:56 2009 New Revision: 71514 Log: Blocked revisions 71513 via svnmerge ........ r71513 | tarek.ziade | 2009-04-12 17:03:50 +0200 (Sun, 12 Apr 2009) | 1 line pep8-fied the module before adding tests ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Apr 12 17:07:31 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 12 Apr 2009 17:07:31 +0200 (CEST) Subject: [Python-checkins] r71515 - in python/branches/py3k: Lib/distutils/command/config.py Message-ID: <20090412150731.ABD9B1E4037@bag.python.org> Author: tarek.ziade Date: Sun Apr 12 17:07:31 2009 New Revision: 71515 Log: Merged revisions 71513 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71513 | tarek.ziade | 2009-04-12 17:03:50 +0200 (Sun, 12 Apr 2009) | 1 line pep8-fied the module before adding tests ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/command/config.py Modified: python/branches/py3k/Lib/distutils/command/config.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/config.py (original) +++ python/branches/py3k/Lib/distutils/command/config.py Sun Apr 12 17:07:31 2009 @@ -53,8 +53,6 @@ self.compiler = None self.cc = None self.include_dirs = None - #self.define = None - #self.undef = None self.libraries = None self.library_dirs = None @@ -136,8 +134,8 @@ self.compiler.compile([src], include_dirs=include_dirs) return (src, obj) - def _link(self, body, headers, include_dirs, libraries, - library_dirs, lang): + def _link(self, body, headers, include_dirs, libraries, library_dirs, + lang): (src, obj) = self._compile(body, headers, include_dirs, lang) prog = os.path.splitext(os.path.basename(src))[0] self.compiler.link_executable([obj], prog, @@ -191,8 +189,8 @@ self._clean() return ok - def search_cpp(self, pattern, body=None, headers=None, - include_dirs=None, lang="c"): + def search_cpp(self, pattern, body=None, headers=None, include_dirs=None, + lang="c"): """Construct a source file (just like 'try_cpp()'), run it through the preprocessor, and return true if any line of the output matches 'pattern'. 'pattern' should either be a compiled regex object or a @@ -237,8 +235,8 @@ self._clean() return ok - def try_link(self, body, headers=None, include_dirs=None, - libraries=None, library_dirs=None, lang="c"): + def try_link(self, body, headers=None, include_dirs=None, libraries=None, + library_dirs=None, lang="c"): """Try to compile and link a source file, built from 'body' and 'headers', to executable form. Return true on success, false otherwise. @@ -256,8 +254,8 @@ self._clean() return ok - def try_run(self, body, headers=None, include_dirs=None, - libraries=None, library_dirs=None, lang="c"): + def try_run(self, body, headers=None, include_dirs=None, libraries=None, + library_dirs=None, lang="c"): """Try to compile, link to an executable, and run a program built from 'body' and 'headers'. Return true on success, false otherwise. From python-checkins at python.org Sun Apr 12 17:08:24 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 12 Apr 2009 17:08:24 +0200 (CEST) Subject: [Python-checkins] r71516 - python/branches/release30-maint Message-ID: <20090412150824.342011E4037@bag.python.org> Author: tarek.ziade Date: Sun Apr 12 17:08:24 2009 New Revision: 71516 Log: Blocked revisions 71515 via svnmerge ................ r71515 | tarek.ziade | 2009-04-12 17:07:31 +0200 (Sun, 12 Apr 2009) | 9 lines Merged revisions 71513 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71513 | tarek.ziade | 2009-04-12 17:03:50 +0200 (Sun, 12 Apr 2009) | 1 line pep8-fied the module before adding tests ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sun Apr 12 17:10:08 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 12 Apr 2009 17:10:08 +0200 (CEST) Subject: [Python-checkins] r71517 - in python/branches/py3k-short-float-repr: Lib/test/test_types.py Objects/stringlib/formatter.h Message-ID: <20090412151008.D95B31E4037@bag.python.org> Author: eric.smith Date: Sun Apr 12 17:10:08 2009 New Revision: 71517 Log: Significant cleanup, simplification, and correction of padding code. Added tests that previously failed. Modified: python/branches/py3k-short-float-repr/Lib/test/test_types.py python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Modified: python/branches/py3k-short-float-repr/Lib/test/test_types.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_types.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_types.py Sun Apr 12 17:10:08 2009 @@ -557,6 +557,29 @@ test(1.1e200, '+g', '+1.1e+200') test(1.1e200, '+', '+1.1e+200') + # 0 padding + test(1234., '010f', '1234.000000') + test(1234., '011f', '1234.000000') + test(1234., '012f', '01234.000000') + test(-1234., '011f', '-1234.000000') + test(-1234., '012f', '-1234.000000') + test(-1234., '013f', '-01234.000000') + test(-1234.12341234, '013f', '-01234.123412') + test(-123456.12341234, '011.2f', '-0123456.12') + + # 0 padding with commas + test(1234., '011,f', '1,234.000000') + test(1234., '012,f', '1,234.000000') + test(1234., '013,f', '01,234.000000') + test(-1234., '012,f', '-1,234.000000') + test(-1234., '013,f', '-1,234.000000') + test(-1234., '014,f', '-01,234.000000') + test(-12345., '015,f', '-012,345.000000') + test(-123456., '016,f', '-0,123,456.000000') + test(-123456., '017,f', '-0,123,456.000000') + test(-123456.12341234, '017,f', '-0,123,456.123412') + test(-123456.12341234, '013,.2f', '-0,123,456.12') + # % formatting test(-1.0, '%', '-100.000000%') Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h (original) +++ python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Sun Apr 12 17:10:08 2009 @@ -277,9 +277,10 @@ Py_ssize_t n_decimal; /* 0 if only an integer */ Py_ssize_t n_remainder; /* digits in decimal and/or exponent part, excluding the decimal itself, if present */ - Py_ssize_t n_total; /* just a convenience, it's derivable from the - other fields */ + /* These 2 are calculatable from parameters, but needed between + calls to calc_number_widths and fill_number in order to not + have to pass all of the parameters to fill_number. */ Py_ssize_t n_digits; /* The number of digits before a decimal or exponent. */ Py_ssize_t n_min_width; /* The min_width we used when we computed @@ -321,7 +322,7 @@ unused. should this take discrete params in order to be more clear about what it does? or is passing a single format parameter easier and more efficient enough to justify a little obfuscation? */ -static void +static Py_ssize_t calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix, STRINGLIB_CHAR sign_char, STRINGLIB_CHAR *number, Py_ssize_t n_number, Py_ssize_t n_remainder, @@ -329,6 +330,7 @@ const InternalFormatSpec *format) { Py_ssize_t n_non_digit_non_padding; + Py_ssize_t n_padding; spec->n_digits = n_number - n_remainder - (has_decimal?1:0); spec->n_lpadding = 0; @@ -377,7 +379,7 @@ } } - /* The number of chars used for non-digit and non-padding. */ + /* The number of chars used for non-digits and non-padding. */ n_non_digit_non_padding = spec->n_sign + spec->n_prefix + spec->n_decimal + spec->n_remainder; @@ -400,36 +402,32 @@ locale->grouping, locale->thousands_sep); - if (format->width == -1) { - /* no padding at all, nothing to do */ - } - else { - /* see if any padding is needed */ - if (spec->n_sign + spec->n_grouped_digits + - spec->n_prefix >= format->width) { - /* no padding needed, we're already bigger than the - requested width */ - } - else { - /* determine which of left, space, or right padding is - needed */ - Py_ssize_t padding = format->width - - (spec->n_sign + spec->n_grouped_digits + n_prefix); - if (format->align == '<') - spec->n_rpadding = padding; - else if (format->align == '>') - spec->n_lpadding = padding; - else if (format->align == '^') { - spec->n_lpadding = padding / 2; - spec->n_rpadding = padding - spec->n_lpadding; - } - else if (format->align == '=') - spec->n_spadding = padding; - else - spec->n_lpadding = padding; + /* Given the desired width and the total of digit and non-digit + space we consume, see if we need any padding. format->width can + be negative (meaning no padding), but this code still works in + that case. */ + n_padding = format->width - + (n_non_digit_non_padding + spec->n_grouped_digits); + if (n_padding > 0) { + /* Some padding is needed. Determine if it's left, space, or right. */ + switch (format->align) { + case '<': + spec->n_rpadding = n_padding; + break; + case '^': + spec->n_lpadding = n_padding / 2; + spec->n_rpadding = n_padding - spec->n_lpadding; + break; + case '=': + spec->n_spadding = n_padding; + break; + default: + /* Handles '>', plus catch-all just in case. */ + spec->n_lpadding = n_padding; + break; } } - spec->n_total = spec->n_lpadding + spec->n_sign + spec->n_prefix + + return spec->n_lpadding + spec->n_sign + spec->n_prefix + spec->n_spadding + spec->n_grouped_digits + spec->n_decimal + spec->n_remainder + spec->n_rpadding; } @@ -670,6 +668,7 @@ Py_ssize_t n_remainder = 0; /* Used only for 'c' formatting, which produces non-digits */ Py_ssize_t n_prefix = 0; /* Count of prefix chars, (e.g., '0x') */ + Py_ssize_t n_total; STRINGLIB_CHAR *prefix = NULL; NumberFieldWidths spec; long x; @@ -804,11 +803,11 @@ &locale); /* Calculate how much memory we'll need. */ - calc_number_widths(&spec, n_prefix, sign_char, pnumeric_chars, + n_total = calc_number_widths(&spec, n_prefix, sign_char, pnumeric_chars, n_digits, n_remainder, 0, &locale, format); /* Allocate the memory. */ - result = STRINGLIB_NEW(NULL, spec.n_total); + result = STRINGLIB_NEW(NULL, n_total); if (!result) goto done; @@ -846,6 +845,7 @@ char *buf = NULL; /* buffer returned from PyOS_double_to_string */ Py_ssize_t n_digits; Py_ssize_t n_remainder; + Py_ssize_t n_total; int has_decimal; double val; Py_ssize_t precision = format->precision; @@ -950,11 +950,11 @@ &locale); /* Calculate how much memory we'll need. */ - calc_number_widths(&spec, 0, sign_char, p, n_digits, n_remainder, - has_decimal, &locale, format); + n_total = calc_number_widths(&spec, 0, sign_char, p, n_digits, + n_remainder, has_decimal, &locale, format); /* Allocate the memory. */ - result = STRINGLIB_NEW(NULL, spec.n_total); + result = STRINGLIB_NEW(NULL, n_total); if (result == NULL) goto done; From python-checkins at python.org Sun Apr 12 17:21:36 2009 From: python-checkins at python.org (r.david.murray) Date: Sun, 12 Apr 2009 17:21:36 +0200 (CEST) Subject: [Python-checkins] r71518 - python/branches/py3k Message-ID: <20090412152136.4DC941E400C@bag.python.org> Author: r.david.murray Date: Sun Apr 12 17:21:36 2009 New Revision: 71518 Log: Unblock most recent asyncore commits in preparation for py3k integration. Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sun Apr 12 17:31:57 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 12 Apr 2009 17:31:57 +0200 (CEST) Subject: [Python-checkins] r71519 - in python/branches/py3k-short-float-repr: Lib/test/test_types.py Objects/stringlib/formatter.h Message-ID: <20090412153157.09E0E1E400C@bag.python.org> Author: eric.smith Date: Sun Apr 12 17:31:56 2009 New Revision: 71519 Log: Fixed localized output with floats. Changed name of constant to LT_CURRENT_LOCALE if using the current locale. Re-enabled tests. Modified: python/branches/py3k-short-float-repr/Lib/test/test_types.py python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Modified: python/branches/py3k-short-float-repr/Lib/test/test_types.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_types.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_types.py Sun Apr 12 17:31:56 2009 @@ -475,8 +475,8 @@ for i in range(-10, 10): x = 1234567890.0 * (10.0 ** i) -# self.assertEqual(locale.format('%g', x, grouping=True), format(x, 'n')) -# self.assertEqual(locale.format('%.10g', x, grouping=True), format(x, '.10n')) + self.assertEqual(locale.format('%g', x, grouping=True), format(x, 'n')) + self.assertEqual(locale.format('%.10g', x, grouping=True), format(x, '.10n')) @run_with_locale('LC_NUMERIC', 'en_US.UTF8') def test_int__format__locale(self): Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h (original) +++ python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Sun Apr 12 17:31:56 2009 @@ -245,7 +245,7 @@ /************************************************************************/ /* Locale type codes. */ -#define LT_USE_LOCALE 0 +#define LT_CURRENT_LOCALE 0 #define LT_DEFAULT_LOCALE 1 #define LT_NO_LOCALE 2 @@ -516,14 +516,14 @@ /* Find the decimal point character(s?), thousands_separator(s?), and grouping description, either for the current locale if type is - LT_USE_LOCALE, a hard-coded locale if LT_DEFAULT_LOCALE, or none if - LT_NO_LOCALE. */ + LT_CURRENT_LOCALE, a hard-coded locale if LT_DEFAULT_LOCALE, or + none if LT_NO_LOCALE. */ static void get_locale_info(int type, LocaleInfo *locale_info) { locale_info->type = type; switch (type) { - case LT_USE_LOCALE: { + case LT_CURRENT_LOCALE: { struct lconv *locale_data = localeconv(); locale_info->decimal_point = locale_data->decimal_point; locale_info->thousands_sep = locale_data->thousands_sep; @@ -684,7 +684,6 @@ goto done; } - /* special case for character formatting */ if (format->type == 'c') { /* error to specify a sign */ @@ -797,8 +796,9 @@ } /* Determine the grouping, separator, and decimal point, if any. */ - get_locale_info(format->type == 'n' ? LT_USE_LOCALE : - (format->thousands_separators ? LT_DEFAULT_LOCALE : + get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE : + (format->thousands_separators ? + LT_DEFAULT_LOCALE : LT_NO_LOCALE), &locale); @@ -944,8 +944,9 @@ parse_number(p, n_digits, &n_remainder, &has_decimal); /* Determine the grouping, separator, and decimal point, if any. */ - get_locale_info(type == 'n' ? LT_USE_LOCALE : - (format->thousands_separators ? LT_DEFAULT_LOCALE : + get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE : + (format->thousands_separators ? + LT_DEFAULT_LOCALE : LT_NO_LOCALE), &locale); From python-checkins at python.org Sun Apr 12 17:35:00 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 12 Apr 2009 17:35:00 +0200 (CEST) Subject: [Python-checkins] r71519 - svn:log Message-ID: <20090412153500.5E71D1E400C@bag.python.org> Author: eric.smith Revision: 71519 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -1 +1,2 @@ -Fixed localized output with floats. Changed name of constant to LT_CURRENT_LOCALE if using the current locale. Re-enabled tests. \ No newline at end of file +Fixed locale-aware float formatting; re-enabled tests. +Changed name of constant to LT_CURRENT_LOCALE if using the current locale. \ No newline at end of file From python-checkins at python.org Sun Apr 12 17:35:45 2009 From: python-checkins at python.org (r.david.murray) Date: Sun, 12 Apr 2009 17:35:45 +0200 (CEST) Subject: [Python-checkins] r71520 - in python/branches/py3k: Doc/library/asyncore.rst Lib/asyncore.py Lib/test/test_asyncore.py Message-ID: <20090412153545.156A11E400C@bag.python.org> Author: r.david.murray Date: Sun Apr 12 17:35:44 2009 New Revision: 71520 Log: Merged revisions 70873,70904,70934,71490 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70873 | josiah.carlson | 2009-03-31 15:32:34 -0400 (Tue, 31 Mar 2009) | 2 lines This resolves issue 1161031. Tests pass. ........ r70904 | josiah.carlson | 2009-03-31 17:49:36 -0400 (Tue, 31 Mar 2009) | 3 lines Made handle_expt_event() be called last, so that we don't accidentally read after closing the socket. ........ r70934 | josiah.carlson | 2009-03-31 21:28:11 -0400 (Tue, 31 Mar 2009) | 2 lines Fix for failing asyncore tests. ........ r71490 | r.david.murray | 2009-04-11 13:52:56 -0400 (Sat, 11 Apr 2009) | 4 lines Make test_asyncore tests match code changes introduced by the fix to Issue1161031, refactoring the test to simplify it in the process. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/asyncore.rst python/branches/py3k/Lib/asyncore.py python/branches/py3k/Lib/test/test_asyncore.py Modified: python/branches/py3k/Doc/library/asyncore.rst ============================================================================== --- python/branches/py3k/Doc/library/asyncore.rst (original) +++ python/branches/py3k/Doc/library/asyncore.rst Sun Apr 12 17:35:44 2009 @@ -81,7 +81,8 @@ +----------------------+----------------------------------------+ | Event | Description | +======================+========================================+ - | ``handle_connect()`` | Implied by the first write event | + | ``handle_connect()`` | Implied by the first read or write | + | | event | +----------------------+----------------------------------------+ | ``handle_close()`` | Implied by a read event with no data | | | available | Modified: python/branches/py3k/Lib/asyncore.py ============================================================================== --- python/branches/py3k/Lib/asyncore.py (original) +++ python/branches/py3k/Lib/asyncore.py Sun Apr 12 17:35:44 2009 @@ -68,10 +68,12 @@ class ExitNow(Exception): pass +_reraised_exceptions = (ExitNow, KeyboardInterrupt, SystemExit) + def read(obj): try: obj.handle_read_event() - except (ExitNow, KeyboardInterrupt, SystemExit): + except _reraised_exceptions: raise except: obj.handle_error() @@ -79,7 +81,7 @@ def write(obj): try: obj.handle_write_event() - except (ExitNow, KeyboardInterrupt, SystemExit): + except _reraised_exceptions: raise except: obj.handle_error() @@ -87,22 +89,22 @@ def _exception(obj): try: obj.handle_expt_event() - except (ExitNow, KeyboardInterrupt, SystemExit): + except _reraised_exceptions: raise except: obj.handle_error() def readwrite(obj, flags): try: - if flags & (select.POLLIN | select.POLLPRI): + if flags & select.POLLIN: obj.handle_read_event() if flags & select.POLLOUT: obj.handle_write_event() - if flags & (select.POLLERR | select.POLLNVAL): - obj.handle_expt_event() - if flags & select.POLLHUP: + if flags & (select.POLLHUP | select.POLLERR | select.POLLNVAL): obj.handle_close() - except (ExitNow, KeyboardInterrupt, SystemExit): + if flags & select.POLLPRI: + obj.handle_expt_event() + except _reraised_exceptions: raise except: obj.handle_error() @@ -210,6 +212,7 @@ accepting = False closing = False addr = None + ignore_log_types = frozenset(['warning']) def __init__(self, sock=None, map=None): if map is None: @@ -397,7 +400,7 @@ sys.stderr.write('log: %s\n' % str(message)) def log_info(self, message, type='info'): - if __debug__ or type != 'info': + if type not in self.ignore_log_types: print('%s: %s' % (type, message)) def handle_read_event(self): @@ -431,22 +434,17 @@ self.handle_write() def handle_expt_event(self): - # if the handle_expt is the same default worthless method, - # we'll not even bother calling it, we'll instead generate - # a useful error - x = True - try: - y1 = self.handle_expt.__func__ - y2 = dispatcher.handle_expt - x = y1 is y2 - except AttributeError: - pass - - if x: - err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) - msg = _strerror(err) - - raise socket.error(err, msg) + # handle_expt_event() is called if there might be an error on the + # socket, or if there is OOB data + # check for the error condition first + err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) + if err != 0: + # we can get here when select.select() says that there is an + # exceptional condition on the socket + # since there is an error, we'll go ahead and close the socket + # like we would in a subclassed handle_read() that received no + # data + self.handle_close() else: self.handle_expt() @@ -471,7 +469,7 @@ self.handle_close() def handle_expt(self): - self.log_info('unhandled exception', 'warning') + self.log_info('unhandled incoming priority event', 'warning') def handle_read(self): self.log_info('unhandled read event', 'warning') @@ -552,7 +550,7 @@ pass elif not ignore_all: raise - except (ExitNow, KeyboardInterrupt, SystemExit): + except _reraised_exceptions: raise except: if not ignore_all: 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 Sun Apr 12 17:35:44 2009 @@ -116,12 +116,24 @@ def test_readwrite(self): # Check that correct methods are called by readwrite() + attributes = ('read', 'expt', 'write', 'closed', 'error_handled') + + expected = ( + (select.POLLIN, 'read'), + (select.POLLPRI, 'expt'), + (select.POLLOUT, 'write'), + (select.POLLERR, 'closed'), + (select.POLLHUP, 'closed'), + (select.POLLNVAL, 'closed'), + ) + class testobj: def __init__(self): self.read = False self.write = False self.closed = False self.expt = False + self.error_handled = False def handle_read_event(self): self.read = True @@ -138,54 +150,25 @@ def handle_error(self): self.error_handled = True - for flag in (select.POLLIN, select.POLLPRI): + for flag, expectedattr in expected: tobj = testobj() - self.assertEqual(tobj.read, False) + self.assertEqual(getattr(tobj, expectedattr), False) asyncore.readwrite(tobj, flag) - self.assertEqual(tobj.read, True) - # check that ExitNow exceptions in the object handler method - # bubbles all the way up through asyncore readwrite call - tr1 = exitingdummy() - self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, flag) - - # check that an exception other than ExitNow in the object handler - # method causes the handle_error method to get called - tr2 = crashingdummy() - asyncore.readwrite(tr2, flag) - self.assertEqual(tr2.error_handled, True) - - tobj = testobj() - self.assertEqual(tobj.write, False) - asyncore.readwrite(tobj, select.POLLOUT) - self.assertEqual(tobj.write, True) - - # check that ExitNow exceptions in the object handler method - # bubbles all the way up through asyncore readwrite call - tr1 = exitingdummy() - self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, - select.POLLOUT) - - # check that an exception other than ExitNow in the object handler - # method causes the handle_error method to get called - tr2 = crashingdummy() - asyncore.readwrite(tr2, select.POLLOUT) - self.assertEqual(tr2.error_handled, True) - - for flag in (select.POLLERR, select.POLLHUP, select.POLLNVAL): - tobj = testobj() - self.assertEqual((tobj.expt, tobj.closed)[flag == select.POLLHUP], False) - asyncore.readwrite(tobj, flag) - self.assertEqual((tobj.expt, tobj.closed)[flag == select.POLLHUP], True) + # Only the attribute modified by the routine we expect to be + # called should be True. + for attr in attributes: + self.assertEqual(getattr(tobj, attr), attr==expectedattr) # check that ExitNow exceptions in the object handler method - # bubbles all the way up through asyncore readwrite calls + # bubbles all the way up through asyncore readwrite call tr1 = exitingdummy() self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, flag) # check that an exception other than ExitNow in the object handler # method causes the handle_error method to get called tr2 = crashingdummy() + self.assertEqual(tr2.error_handled, False) asyncore.readwrite(tr2, flag) self.assertEqual(tr2.error_handled, True) @@ -299,6 +282,7 @@ def test_unhandled(self): d = asyncore.dispatcher() + d.ignore_log_types = () # capture output of dispatcher.log_info() (to stdout via print) fp = StringIO() @@ -314,7 +298,7 @@ sys.stdout = stdout lines = fp.getvalue().splitlines() - expected = ['warning: unhandled exception', + expected = ['warning: unhandled incoming priority event', 'warning: unhandled read event', 'warning: unhandled write event', 'warning: unhandled connect event', From buildbot at python.org Sun Apr 12 17:50:09 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 12 Apr 2009 15:50:09 +0000 Subject: [Python-checkins] buildbot failure in OS X x86 2.6 Message-ID: <20090412155010.1580D1E400C@bag.python.org> The Buildbot has detected a new failure of OS X x86 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/OS%20X%20x86%202.6/builds/203 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: noller-osx86 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: georg.brandl,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_sys make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sun Apr 12 17:51:51 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 12 Apr 2009 17:51:51 +0200 (CEST) Subject: [Python-checkins] r71521 - in python/branches/py3k: Doc/library/stdtypes.rst Doc/library/string.rst Include/bytes_methods.h Lib/string.py Lib/test/test_bigmem.py Lib/test/test_bytes.py Lib/test/test_string.py Misc/NEWS Objects/bytearrayobject.c Objects/bytes_methods.c Objects/bytesobject.c Message-ID: <20090412155151.D911C1E400C@bag.python.org> Author: georg.brandl Date: Sun Apr 12 17:51:51 2009 New Revision: 71521 Log: Add bytes/bytearray.maketrans() to mirror str.maketrans(), and deprecate string.maketrans() which actually works on bytes. (Also closes #5675.) Modified: python/branches/py3k/Doc/library/stdtypes.rst python/branches/py3k/Doc/library/string.rst python/branches/py3k/Include/bytes_methods.h python/branches/py3k/Lib/string.py python/branches/py3k/Lib/test/test_bigmem.py python/branches/py3k/Lib/test/test_bytes.py python/branches/py3k/Lib/test/test_string.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/bytearrayobject.c python/branches/py3k/Objects/bytes_methods.c python/branches/py3k/Objects/bytesobject.c Modified: python/branches/py3k/Doc/library/stdtypes.rst ============================================================================== --- python/branches/py3k/Doc/library/stdtypes.rst (original) +++ python/branches/py3k/Doc/library/stdtypes.rst Sun Apr 12 17:51:51 2009 @@ -479,7 +479,7 @@ exponent. -.. method:: float.fromhex(s) +.. classmethod:: float.fromhex(s) Class method to return the float represented by a hexadecimal string *s*. The string *s* may have leading and trailing @@ -967,7 +967,7 @@ 'example.com' -.. method:: str.maketrans(x[, y[, z]]) +.. staticmethod:: str.maketrans(x[, y[, z]]) This static method returns a translation table usable for :meth:`str.translate`. @@ -1514,8 +1514,8 @@ The bytes and bytearray types have an additional class method: -.. method:: bytes.fromhex(string) - bytearray.fromhex(string) +.. classmethod:: bytes.fromhex(string) + bytearray.fromhex(string) This :class:`bytes` class method returns a bytes or bytearray object, decoding the given string object. The string must contain two hexadecimal @@ -1524,7 +1524,9 @@ >>> bytes.fromhex('f0 f1f2 ') b'\xf0\xf1\xf2' -The translate method differs in semantics from the version available on strings: + +The maketrans and translate methods differ in semantics from the versions +available on strings: .. method:: bytes.translate(table[, delete]) @@ -1533,8 +1535,7 @@ mapped through the given translation table, which must be a bytes object of length 256. - You can use the :func:`string.maketrans` helper function to create a - translation table. + You can use the :func:`bytes.maketrans` method to create a translation table. Set the *table* argument to ``None`` for translations that only delete characters:: @@ -1543,6 +1544,16 @@ b'rd ths shrt txt' +.. staticmethod:: bytes.maketrans(from, to) + + This static method returns a translation table usable for + :meth:`bytes.translate` that will map each character in *from* into the + character at the same position in *to*; *from* and *to* must be bytes objects + and have the same length. + + .. versionadded:: 3.1 + + .. _types-set: Set Types --- :class:`set`, :class:`frozenset` @@ -1847,7 +1858,7 @@ Return a shallow copy of the dictionary. - .. method:: fromkeys(seq[, value]) + .. classmethod:: fromkeys(seq[, value]) Create a new dictionary with keys from *seq* and values set to *value*. Modified: python/branches/py3k/Doc/library/string.rst ============================================================================== --- python/branches/py3k/Doc/library/string.rst (original) +++ python/branches/py3k/Doc/library/string.rst Sun Apr 12 17:51:51 2009 @@ -548,13 +548,9 @@ delimiter), and it should appear last in the regular expression. -String functions +Helper functions ---------------- -The following functions are available to operate on string objects. -They are not available as string methods. - - .. function:: capwords(s) Split the argument into words using :func:`split`, capitalize each word using @@ -568,3 +564,6 @@ Return a translation table suitable for passing to :meth:`bytes.translate`, that will map each character in *from* into the character at the same position in *to*; *from* and *to* must have the same length. + + .. deprecated:: 3.1 + Use the :meth:`bytes.maketrans` static method instead. Modified: python/branches/py3k/Include/bytes_methods.h ============================================================================== --- python/branches/py3k/Include/bytes_methods.h (original) +++ python/branches/py3k/Include/bytes_methods.h Sun Apr 12 17:51:51 2009 @@ -20,6 +20,9 @@ extern void _Py_bytes_capitalize(char *result, char *s, Py_ssize_t len); extern void _Py_bytes_swapcase(char *result, char *s, Py_ssize_t len); +/* This one gets the raw argument list. */ +extern PyObject* _Py_bytes_maketrans(PyObject *args); + /* Shared __doc__ strings. */ extern const char _Py_isspace__doc__[]; extern const char _Py_isalpha__doc__[]; @@ -33,6 +36,7 @@ extern const char _Py_title__doc__[]; extern const char _Py_capitalize__doc__[]; extern const char _Py_swapcase__doc__[]; +extern const char _Py_maketrans__doc__[]; #define FLAG_LOWER 0x01 #define FLAG_UPPER 0x02 Modified: python/branches/py3k/Lib/string.py ============================================================================== --- python/branches/py3k/Lib/string.py (original) +++ python/branches/py3k/Lib/string.py Sun Apr 12 17:51:51 2009 @@ -49,6 +49,9 @@ mapped to the byte at the same position in to. The strings frm and to must be of the same length. """ + import warnings + warnings.warn("string.maketrans is deprecated, use bytes.maketrans instead", + DeprecationWarning) if len(frm) != len(to): raise ValueError("maketrans arguments must have same length") if not (isinstance(frm, bytes) and isinstance(to, bytes)): Modified: python/branches/py3k/Lib/test/test_bigmem.py ============================================================================== --- python/branches/py3k/Lib/test/test_bigmem.py (original) +++ python/branches/py3k/Lib/test/test_bigmem.py Sun Apr 12 17:51:51 2009 @@ -418,18 +418,15 @@ @bigmemtest(minsize=_2G, memuse=2) def test_translate(self, size): _ = self.from_latin1 - trans = { - ord(_('.')): _('-'), - ord(_('a')): _('!'), - ord(_('Z')): _('$'), - } SUBSTR = _('aZz.z.Aaz.') - if not isinstance(SUBSTR, str): - # Workaround the inexistence of bytes.maketrans() - chars = bytearray(range(256)) - for k, v in trans.items(): - chars[k] = ord(v) - trans = chars + if isinstance(SUBSTR, str): + trans = { + ord(_('.')): _('-'), + ord(_('a')): _('!'), + ord(_('Z')): _('$'), + } + else: + trans = bytes.maketrans(b'.aZ', b'-!$') sublen = len(SUBSTR) repeats = size // sublen + 2 s = SUBSTR * repeats 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 Apr 12 17:51:51 2009 @@ -450,6 +450,13 @@ self.assertEqual([ord(b[i:i+1]) for i in range(len(b))], [0, 65, 127, 128, 255]) + def test_maketrans(self): + transtable = b'\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`xyzdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377' + + self.assertEqual(self.type2test.maketrans(b'abc', b'xyz'), transtable) + self.assertRaises(ValueError, self.type2test.maketrans, b'abc', b'xyzq') + self.assertRaises(TypeError, self.type2test.maketrans, 'abc', 'def') + class BytesTest(BaseBytesTest): type2test = bytes Modified: python/branches/py3k/Lib/test/test_string.py ============================================================================== --- python/branches/py3k/Lib/test/test_string.py (original) +++ python/branches/py3k/Lib/test/test_string.py Sun Apr 12 17:51:51 2009 @@ -101,14 +101,6 @@ self.assertRaises(ValueError, fmt.format, "{0}", 10, 20, i=100) self.assertRaises(ValueError, fmt.format, "{i}", 10, 20, i=100) - - def test_maketrans(self): - transtable = b'\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`xyzdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377' - - self.assertEqual(string.maketrans(b'abc', b'xyz'), transtable) - self.assertRaises(ValueError, string.maketrans, b'abc', b'xyzq') - self.assertRaises(TypeError, string.maketrans, 'abc', 'def') - def test_main(): support.run_unittest(ModuleTest) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Apr 12 17:51:51 2009 @@ -12,6 +12,11 @@ Core and Builtins ----------------- +- The string.maketrans() function is deprecated; there is a new static method + maketrans() on the bytes and bytearray classes. This removes confusion about + the types string.maketrans() is supposed to work with, and mirrors the + methods available on the str class. + - Issue #2170: refactored xml.dom.minidom.normalize, increasing both its clarity and its speed. Modified: python/branches/py3k/Objects/bytearrayobject.c ============================================================================== --- python/branches/py3k/Objects/bytearrayobject.c (original) +++ python/branches/py3k/Objects/bytearrayobject.c Sun Apr 12 17:51:51 2009 @@ -1451,6 +1451,13 @@ } +static PyObject * +bytes_maketrans(PyObject *null, PyObject *args) +{ + return _Py_bytes_maketrans(args); +} + + #define FORWARD 1 #define REVERSE -1 @@ -3131,6 +3138,8 @@ {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__}, {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__}, {"lstrip", (PyCFunction)bytes_lstrip, METH_VARARGS, lstrip__doc__}, + {"maketrans", (PyCFunction)bytes_maketrans, METH_VARARGS|METH_STATIC, + _Py_maketrans__doc__}, {"partition", (PyCFunction)bytes_partition, METH_O, partition__doc__}, {"pop", (PyCFunction)bytes_pop, METH_VARARGS, pop__doc__}, {"remove", (PyCFunction)bytes_remove, METH_O, remove__doc__}, Modified: python/branches/py3k/Objects/bytes_methods.c ============================================================================== --- python/branches/py3k/Objects/bytes_methods.c (original) +++ python/branches/py3k/Objects/bytes_methods.c Sun Apr 12 17:51:51 2009 @@ -608,3 +608,70 @@ } } + +PyDoc_STRVAR_shared(_Py_maketrans__doc__, +"B.maketrans(frm, to) -> translation table\n\ +\n\ +Return a translation table (a bytes object of length 256)\n\ +suitable for use in bytes.translate where each byte in frm is\n\ +mapped to the byte at the same position in to.\n\ +The strings frm and to must be of the same length."); + +static Py_ssize_t +_getbuffer(PyObject *obj, Py_buffer *view) +{ + PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer; + + if (buffer == NULL || buffer->bf_getbuffer == NULL) + { + PyErr_Format(PyExc_TypeError, + "Type %.100s doesn't support the buffer API", + Py_TYPE(obj)->tp_name); + return -1; + } + + if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0) + return -1; + return view->len; +} + +PyObject * +_Py_bytes_maketrans(PyObject *args) +{ + PyObject *frm, *to, *res = NULL; + Py_buffer bfrm, bto; + int i; + char *p; + + bfrm.len = -1; + bto.len = -1; + + if (!PyArg_ParseTuple(args, "OO:maketrans", &frm, &to)) + return NULL; + if (_getbuffer(frm, &bfrm) < 0) + return NULL; + if (_getbuffer(to, &bto) < 0) + goto done; + if (bfrm.len != bto.len) { + PyErr_Format(PyExc_ValueError, + "maketrans arguments must have same length"); + goto done; + } + res = PyBytes_FromStringAndSize(NULL, 256); + if (!res) { + goto done; + } + p = PyBytes_AS_STRING(res); + for (i = 0; i < 256; i++) + p[i] = i; + for (i = 0; i < bfrm.len; i++) { + p[(int)((char *)bfrm.buf)[i]] = ((char *)bto.buf)[i]; + } + + done: + if (bfrm.len != -1) + PyBuffer_Release(&bfrm); + if (bto.len != -1) + PyBuffer_Release(&bto); + return res; +} Modified: python/branches/py3k/Objects/bytesobject.c ============================================================================== --- python/branches/py3k/Objects/bytesobject.c (original) +++ python/branches/py3k/Objects/bytesobject.c Sun Apr 12 17:51:51 2009 @@ -1950,6 +1950,12 @@ } +static PyObject * +string_maketrans(PyObject *null, PyObject *args) +{ + return _Py_bytes_maketrans(args); +} + #define FORWARD 1 #define REVERSE -1 @@ -2851,6 +2857,8 @@ {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__}, {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__}, {"lstrip", (PyCFunction)string_lstrip, METH_VARARGS, lstrip__doc__}, + {"maketrans", (PyCFunction)string_maketrans, METH_VARARGS|METH_STATIC, + _Py_maketrans__doc__}, {"partition", (PyCFunction)string_partition, METH_O, partition__doc__}, {"replace", (PyCFunction)string_replace, METH_VARARGS, replace__doc__}, {"rfind", (PyCFunction)string_rfind, METH_VARARGS, rfind__doc__}, From buildbot at python.org Sun Apr 12 17:56:26 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 12 Apr 2009 15:56:26 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc trunk Message-ID: <20090412155626.B57E51E400C@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc trunk. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%20trunk/builds/287 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posixpath sincerely, -The Buildbot From python-checkins at python.org Sun Apr 12 18:16:22 2009 From: python-checkins at python.org (r.david.murray) Date: Sun, 12 Apr 2009 18:16:22 +0200 (CEST) Subject: [Python-checkins] r71522 - in python/branches/release30-maint: Doc/library/asyncore.rst Lib/asyncore.py Lib/test/test_asyncore.py Message-ID: <20090412161622.16F071E400C@bag.python.org> Author: r.david.murray Date: Sun Apr 12 18:16:21 2009 New Revision: 71522 Log: Merged revisions 71520 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71520 | r.david.murray | 2009-04-12 11:35:44 -0400 (Sun, 12 Apr 2009) | 24 lines Merged revisions 70873,70904,70934,71490 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70873 | josiah.carlson | 2009-03-31 15:32:34 -0400 (Tue, 31 Mar 2009) | 2 lines This resolves issue 1161031. Tests pass. ........ r70904 | josiah.carlson | 2009-03-31 17:49:36 -0400 (Tue, 31 Mar 2009) | 3 lines Made handle_expt_event() be called last, so that we don't accidentally read after closing the socket. ........ r70934 | josiah.carlson | 2009-03-31 21:28:11 -0400 (Tue, 31 Mar 2009) | 2 lines Fix for failing asyncore tests. ........ r71490 | r.david.murray | 2009-04-11 13:52:56 -0400 (Sat, 11 Apr 2009) | 4 lines Make test_asyncore tests match code changes introduced by the fix to Issue1161031, refactoring the test to simplify it in the process. ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Doc/library/asyncore.rst python/branches/release30-maint/Lib/asyncore.py python/branches/release30-maint/Lib/test/test_asyncore.py Modified: python/branches/release30-maint/Doc/library/asyncore.rst ============================================================================== --- python/branches/release30-maint/Doc/library/asyncore.rst (original) +++ python/branches/release30-maint/Doc/library/asyncore.rst Sun Apr 12 18:16:21 2009 @@ -81,7 +81,8 @@ +----------------------+----------------------------------------+ | Event | Description | +======================+========================================+ - | ``handle_connect()`` | Implied by the first write event | + | ``handle_connect()`` | Implied by the first read or write | + | | event | +----------------------+----------------------------------------+ | ``handle_close()`` | Implied by a read event with no data | | | available | Modified: python/branches/release30-maint/Lib/asyncore.py ============================================================================== --- python/branches/release30-maint/Lib/asyncore.py (original) +++ python/branches/release30-maint/Lib/asyncore.py Sun Apr 12 18:16:21 2009 @@ -68,10 +68,12 @@ class ExitNow(Exception): pass +_reraised_exceptions = (ExitNow, KeyboardInterrupt, SystemExit) + def read(obj): try: obj.handle_read_event() - except (ExitNow, KeyboardInterrupt, SystemExit): + except _reraised_exceptions: raise except: obj.handle_error() @@ -79,7 +81,7 @@ def write(obj): try: obj.handle_write_event() - except (ExitNow, KeyboardInterrupt, SystemExit): + except _reraised_exceptions: raise except: obj.handle_error() @@ -87,22 +89,22 @@ def _exception(obj): try: obj.handle_expt_event() - except (ExitNow, KeyboardInterrupt, SystemExit): + except _reraised_exceptions: raise except: obj.handle_error() def readwrite(obj, flags): try: - if flags & (select.POLLIN | select.POLLPRI): + if flags & select.POLLIN: obj.handle_read_event() if flags & select.POLLOUT: obj.handle_write_event() - if flags & (select.POLLERR | select.POLLNVAL): - obj.handle_expt_event() - if flags & select.POLLHUP: + if flags & (select.POLLHUP | select.POLLERR | select.POLLNVAL): obj.handle_close() - except (ExitNow, KeyboardInterrupt, SystemExit): + if flags & select.POLLPRI: + obj.handle_expt_event() + except _reraised_exceptions: raise except: obj.handle_error() @@ -210,6 +212,7 @@ accepting = False closing = False addr = None + ignore_log_types = frozenset(['warning']) def __init__(self, sock=None, map=None): if map is None: @@ -397,7 +400,7 @@ sys.stderr.write('log: %s\n' % str(message)) def log_info(self, message, type='info'): - if __debug__ or type != 'info': + if type not in self.ignore_log_types: print('%s: %s' % (type, message)) def handle_read_event(self): @@ -431,22 +434,17 @@ self.handle_write() def handle_expt_event(self): - # if the handle_expt is the same default worthless method, - # we'll not even bother calling it, we'll instead generate - # a useful error - x = True - try: - y1 = self.handle_expt.__func__ - y2 = dispatcher.handle_expt - x = y1 is y2 - except AttributeError: - pass - - if x: - err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) - msg = _strerror(err) - - raise socket.error(err, msg) + # handle_expt_event() is called if there might be an error on the + # socket, or if there is OOB data + # check for the error condition first + err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) + if err != 0: + # we can get here when select.select() says that there is an + # exceptional condition on the socket + # since there is an error, we'll go ahead and close the socket + # like we would in a subclassed handle_read() that received no + # data + self.handle_close() else: self.handle_expt() @@ -471,7 +469,7 @@ self.handle_close() def handle_expt(self): - self.log_info('unhandled exception', 'warning') + self.log_info('unhandled incoming priority event', 'warning') def handle_read(self): self.log_info('unhandled read event', 'warning') @@ -552,7 +550,7 @@ pass elif not ignore_all: raise - except (ExitNow, KeyboardInterrupt, SystemExit): + except _reraised_exceptions: raise except: if not ignore_all: Modified: python/branches/release30-maint/Lib/test/test_asyncore.py ============================================================================== --- python/branches/release30-maint/Lib/test/test_asyncore.py (original) +++ python/branches/release30-maint/Lib/test/test_asyncore.py Sun Apr 12 18:16:21 2009 @@ -116,12 +116,24 @@ def test_readwrite(self): # Check that correct methods are called by readwrite() + attributes = ('read', 'expt', 'write', 'closed', 'error_handled') + + expected = ( + (select.POLLIN, 'read'), + (select.POLLPRI, 'expt'), + (select.POLLOUT, 'write'), + (select.POLLERR, 'closed'), + (select.POLLHUP, 'closed'), + (select.POLLNVAL, 'closed'), + ) + class testobj: def __init__(self): self.read = False self.write = False self.closed = False self.expt = False + self.error_handled = False def handle_read_event(self): self.read = True @@ -138,54 +150,25 @@ def handle_error(self): self.error_handled = True - for flag in (select.POLLIN, select.POLLPRI): + for flag, expectedattr in expected: tobj = testobj() - self.assertEqual(tobj.read, False) + self.assertEqual(getattr(tobj, expectedattr), False) asyncore.readwrite(tobj, flag) - self.assertEqual(tobj.read, True) - # check that ExitNow exceptions in the object handler method - # bubbles all the way up through asyncore readwrite call - tr1 = exitingdummy() - self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, flag) - - # check that an exception other than ExitNow in the object handler - # method causes the handle_error method to get called - tr2 = crashingdummy() - asyncore.readwrite(tr2, flag) - self.assertEqual(tr2.error_handled, True) - - tobj = testobj() - self.assertEqual(tobj.write, False) - asyncore.readwrite(tobj, select.POLLOUT) - self.assertEqual(tobj.write, True) - - # check that ExitNow exceptions in the object handler method - # bubbles all the way up through asyncore readwrite call - tr1 = exitingdummy() - self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, - select.POLLOUT) - - # check that an exception other than ExitNow in the object handler - # method causes the handle_error method to get called - tr2 = crashingdummy() - asyncore.readwrite(tr2, select.POLLOUT) - self.assertEqual(tr2.error_handled, True) - - for flag in (select.POLLERR, select.POLLHUP, select.POLLNVAL): - tobj = testobj() - self.assertEqual((tobj.expt, tobj.closed)[flag == select.POLLHUP], False) - asyncore.readwrite(tobj, flag) - self.assertEqual((tobj.expt, tobj.closed)[flag == select.POLLHUP], True) + # Only the attribute modified by the routine we expect to be + # called should be True. + for attr in attributes: + self.assertEqual(getattr(tobj, attr), attr==expectedattr) # check that ExitNow exceptions in the object handler method - # bubbles all the way up through asyncore readwrite calls + # bubbles all the way up through asyncore readwrite call tr1 = exitingdummy() self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, flag) # check that an exception other than ExitNow in the object handler # method causes the handle_error method to get called tr2 = crashingdummy() + self.assertEqual(tr2.error_handled, False) asyncore.readwrite(tr2, flag) self.assertEqual(tr2.error_handled, True) @@ -299,6 +282,7 @@ def test_unhandled(self): d = asyncore.dispatcher() + d.ignore_log_types = () # capture output of dispatcher.log_info() (to stdout via print) fp = StringIO() @@ -314,7 +298,7 @@ sys.stdout = stdout lines = fp.getvalue().splitlines() - expected = ['warning: unhandled exception', + expected = ['warning: unhandled incoming priority event', 'warning: unhandled read event', 'warning: unhandled write event', 'warning: unhandled connect event', From python-checkins at python.org Sun Apr 12 18:31:24 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 12 Apr 2009 18:31:24 +0200 (CEST) Subject: [Python-checkins] r71523 - in python/trunk/Lib/distutils: command/config.py tests/test_config_cmd.py Message-ID: <20090412163124.9C8F01E400C@bag.python.org> Author: tarek.ziade Date: Sun Apr 12 18:31:24 2009 New Revision: 71523 Log: added a simple test for search_cpp Modified: python/trunk/Lib/distutils/command/config.py python/trunk/Lib/distutils/tests/test_config_cmd.py Modified: python/trunk/Lib/distutils/command/config.py ============================================================================== --- python/trunk/Lib/distutils/command/config.py (original) +++ python/trunk/Lib/distutils/command/config.py Sun Apr 12 18:31:24 2009 @@ -202,11 +202,10 @@ preprocesses an empty file -- which can be useful to determine the symbols the preprocessor and compiler set by default. """ - self._check_compiler() - (src, out) = self._preprocess(body, headers, include_dirs, lang) + src, out = self._preprocess(body, headers, include_dirs, lang) - if type(pattern) is StringType: + if isinstance(pattern, str): pattern = re.compile(pattern) file = open(out) Modified: python/trunk/Lib/distutils/tests/test_config_cmd.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_config_cmd.py (original) +++ python/trunk/Lib/distutils/tests/test_config_cmd.py Sun Apr 12 18:31:24 2009 @@ -2,7 +2,7 @@ import unittest import os -from distutils.command.config import dump_file +from distutils.command.config import dump_file, config from distutils.tests import support from distutils import log @@ -10,7 +10,7 @@ support.TempdirManager, unittest.TestCase): - def _info(self, msg): + def _info(self, msg, *args): for line in msg.splitlines(): self._logs.append(line) @@ -35,6 +35,17 @@ dump_file(this_file, 'I am the header') self.assertEquals(len(self._logs), numlines+1) + def test_search_cpp(self): + pkg_dir, dist = self.create_dist() + cmd = config(dist) + + # simple pattern searches + match = cmd.search_cpp(pattern='xxx', body='// xxx') + self.assertEquals(match, 0) + + match = cmd.search_cpp(pattern='command', body='// xxx') + self.assertEquals(match, 1) + def test_suite(): return unittest.makeSuite(ConfigTestCase) From python-checkins at python.org Sun Apr 12 18:32:21 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 12 Apr 2009 18:32:21 +0200 (CEST) Subject: [Python-checkins] r71524 - python/branches/release26-maint Message-ID: <20090412163221.0D1F31E400C@bag.python.org> Author: tarek.ziade Date: Sun Apr 12 18:32:20 2009 New Revision: 71524 Log: Blocked revisions 71523 via svnmerge ........ r71523 | tarek.ziade | 2009-04-12 18:31:24 +0200 (Sun, 12 Apr 2009) | 1 line added a simple test for search_cpp ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Apr 12 18:34:34 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 12 Apr 2009 18:34:34 +0200 (CEST) Subject: [Python-checkins] r71525 - in python/branches/py3k: Lib/distutils/command/config.py Lib/distutils/tests/test_config_cmd.py Message-ID: <20090412163434.6060A1E400C@bag.python.org> Author: tarek.ziade Date: Sun Apr 12 18:34:34 2009 New Revision: 71525 Log: Merged revisions 71523 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71523 | tarek.ziade | 2009-04-12 18:31:24 +0200 (Sun, 12 Apr 2009) | 1 line added a simple test for search_cpp ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/command/config.py python/branches/py3k/Lib/distutils/tests/test_config_cmd.py Modified: python/branches/py3k/Lib/distutils/command/config.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/config.py (original) +++ python/branches/py3k/Lib/distutils/command/config.py Sun Apr 12 18:34:34 2009 @@ -198,9 +198,8 @@ preprocesses an empty file -- which can be useful to determine the symbols the preprocessor and compiler set by default. """ - self._check_compiler() - (src, out) = self._preprocess(body, headers, include_dirs, lang) + src, out = self._preprocess(body, headers, include_dirs, lang) if isinstance(pattern, str): pattern = re.compile(pattern) Modified: python/branches/py3k/Lib/distutils/tests/test_config_cmd.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_config_cmd.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_config_cmd.py Sun Apr 12 18:34:34 2009 @@ -2,7 +2,7 @@ import unittest import os -from distutils.command.config import dump_file +from distutils.command.config import dump_file, config from distutils.tests import support from distutils import log @@ -10,7 +10,7 @@ support.TempdirManager, unittest.TestCase): - def _info(self, msg): + def _info(self, msg, *args): for line in msg.splitlines(): self._logs.append(line) @@ -35,6 +35,17 @@ dump_file(this_file, 'I am the header') self.assertEquals(len(self._logs), numlines+1) + def test_search_cpp(self): + pkg_dir, dist = self.create_dist() + cmd = config(dist) + + # simple pattern searches + match = cmd.search_cpp(pattern='xxx', body='// xxx') + self.assertEquals(match, 0) + + match = cmd.search_cpp(pattern='command', body='// xxx') + self.assertEquals(match, 1) + def test_suite(): return unittest.makeSuite(ConfigTestCase) From python-checkins at python.org Sun Apr 12 18:39:19 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 12 Apr 2009 18:39:19 +0200 (CEST) Subject: [Python-checkins] r71526 - in python/branches/py3k-short-float-repr: Include/pystrtod.h Modules/_pickle.c Objects/complexobject.c Objects/floatobject.c Objects/stringlib/formatter.h Objects/unicodeobject.c Python/marshal.c Python/pystrtod.c Message-ID: <20090412163919.86F951E4050@bag.python.org> Author: eric.smith Date: Sun Apr 12 18:39:18 2009 New Revision: 71526 Log: Added output parameter 'type' to PyOS_double_to_string, so the caller can tell if the resulting string represents a normal number, a nan, or an inf. Added corresponding constants to pystrtod.h. Modified: python/branches/py3k-short-float-repr/Include/pystrtod.h python/branches/py3k-short-float-repr/Modules/_pickle.c python/branches/py3k-short-float-repr/Objects/complexobject.c python/branches/py3k-short-float-repr/Objects/floatobject.c python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h python/branches/py3k-short-float-repr/Objects/unicodeobject.c python/branches/py3k-short-float-repr/Python/marshal.c python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Include/pystrtod.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/pystrtod.h (original) +++ python/branches/py3k-short-float-repr/Include/pystrtod.h Sun Apr 12 18:39:18 2009 @@ -15,14 +15,21 @@ PyAPI_FUNC(char *) PyOS_double_to_string(double val, char format_code, int precision, - int flags); + int flags, + int *type); +/* PyOS_double_to_string's "flags" parameter can be set to 0 or more of: */ #define Py_DTSF_SIGN 0x01 /* always add the sign */ #define Py_DTSF_ADD_DOT_0 0x02 /* if the result is an integer add ".0" */ #define Py_DTSF_ALT 0x04 /* "alternate" formatting. it's format_code specific */ +/* PyOS_double_to_string's "type", if non-NULL, will be set to one of: */ +#define Py_DTST_FINITE 0 +#define Py_DTST_INFINITE 1 +#define Py_DTST_NAN 2 + #ifdef __cplusplus } #endif Modified: python/branches/py3k-short-float-repr/Modules/_pickle.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_pickle.c (original) +++ python/branches/py3k-short-float-repr/Modules/_pickle.c Sun Apr 12 18:39:18 2009 @@ -1025,7 +1025,7 @@ if (pickler_write(self, &op, 1) < 0) goto done; - buf = PyOS_double_to_string(x, 'r', 0, 0); + buf = PyOS_double_to_string(x, 'r', 0, 0, NULL); if (!buf) { PyErr_NoMemory(); goto done; Modified: python/branches/py3k-short-float-repr/Objects/complexobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/complexobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/complexobject.c Sun Apr 12 18:39:18 2009 @@ -359,7 +359,8 @@ im = "-inf*"; } else { - pim = PyOS_double_to_string(v->cval.imag, format_code, 0, 0); + pim = PyOS_double_to_string(v->cval.imag, format_code, + 0, 0, NULL); if (!pim) { PyErr_NoMemory(); goto done; @@ -378,7 +379,8 @@ re = "-inf"; } else { - pre = PyOS_double_to_string(v->cval.real, format_code, 0, 0); + pre = PyOS_double_to_string(v->cval.real, format_code, + 0, 0, NULL); if (!pre) { PyErr_NoMemory(); goto done; @@ -397,7 +399,7 @@ } else { pim = PyOS_double_to_string(v->cval.imag, format_code, - 0, Py_DTSF_SIGN); + 0, Py_DTSF_SIGN, NULL); if (!pim) { PyErr_NoMemory(); goto done; Modified: python/branches/py3k-short-float-repr/Objects/floatobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/floatobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/floatobject.c Sun Apr 12 18:39:18 2009 @@ -350,7 +350,8 @@ { PyObject *result; char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v), - format_code, 0, Py_DTSF_ADD_DOT_0); + format_code, 0, Py_DTSF_ADD_DOT_0, + NULL); if (!buf) return PyErr_NoMemory(); result = PyUnicode_FromString(buf); @@ -1898,7 +1899,7 @@ Py_REFCNT(p) != 0) { char *buf = PyOS_double_to_string( PyFloat_AS_DOUBLE(p), 'r', - 0, 0); + 0, 0, NULL); if (buf) { /* XXX(twouters) cast refcount to long Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h (original) +++ python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Sun Apr 12 18:39:18 2009 @@ -856,6 +856,7 @@ int flags = 0; PyObject *result = NULL; STRINGLIB_CHAR sign_char = '\0'; + int float_type; /* Used to see if we have a nan, inf, or regular float. */ #if STRINGLIB_IS_UNICODE Py_UNICODE *unicode_tmp = NULL; @@ -904,7 +905,8 @@ /* cast "type", because if we're in unicode we need to pass a 8-bit char. this is safe, because we've restricted what "type" can be */ - buf = PyOS_double_to_string(val, (char)type, precision, flags); + buf = PyOS_double_to_string(val, (char)type, precision, flags, + &float_type); if (buf == NULL) goto done; n_digits = strlen(buf); Modified: python/branches/py3k-short-float-repr/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/unicodeobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/unicodeobject.c Sun Apr 12 18:39:18 2009 @@ -8849,7 +8849,7 @@ } p = PyOS_double_to_string(x, type, prec, - (flags & F_ALT) ? Py_DTSF_ALT : 0); + (flags & F_ALT) ? Py_DTSF_ALT : 0, NULL); len = strlen(p); if (len+1 >= buflen) { /* Caller supplied buffer is not large enough. */ Modified: python/branches/py3k-short-float-repr/Python/marshal.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/marshal.c (original) +++ python/branches/py3k-short-float-repr/Python/marshal.c Sun Apr 12 18:39:18 2009 @@ -237,7 +237,7 @@ } else { char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v), - 'r', 0, 0); + 'r', 0, 0, NULL); if (!buf) return; n = strlen(buf); @@ -269,7 +269,7 @@ char *buf; w_byte(TYPE_COMPLEX, p); buf = PyOS_double_to_string(PyComplex_RealAsDouble(v), - 'r', 0, 0); + 'r', 0, 0, NULL); if (!buf) return; n = strlen(buf); @@ -277,7 +277,7 @@ w_string(buf, (int)n, p); PyMem_Free(buf); buf = PyOS_double_to_string(PyComplex_ImagAsDouble(v), - 'r', 0, 0); + 'r', 0, 0, NULL); if (!buf) return; n = strlen(buf); Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Sun Apr 12 18:39:18 2009 @@ -539,6 +539,11 @@ should have ".0" added. Only applies to format codes 'r', 's', and 'g'. use_alt_formatting is nonzero if alternative formatting should be used. Only applies to format codes 'e', 'f' and 'g'. + type, if non-NULL, will be set to one of these constants to identify + the type of the 'd' argument: + Py_DTST_FINITE + Py_DTST_INFINITE + Py_DTST_NAN Returns a PyMem_Malloc'd block of memory containing the resulting string, or NULL on error. If NULL is returned, the Python error has been set. @@ -548,7 +553,7 @@ format_float_short(double d, char format_code, int mode, Py_ssize_t precision, int always_add_sign, int add_dot_0_if_integer, - int use_alt_formatting, char **float_strings) + int use_alt_formatting, char **float_strings, int *type) { char *buf = NULL; char *p; @@ -593,12 +598,18 @@ } strncpy(p, float_strings[OFS_INF], 3); p += 3; + + if (type) + *type = Py_DTST_INFINITE; } else if (digits[0] == 'n' || digits[0] == 'N') { /* note that we *never* add a sign for a nan, even if one has explicitly been requested */ strncpy(p, float_strings[OFS_NAN], 3); p += 3; + + if (type) + *type = Py_DTST_NAN; } else { /* shouldn't get here: Gay's code should always return @@ -610,6 +621,11 @@ goto exit; } + /* The result must be finite (not inf or nan). */ + if (type) + *type = Py_DTST_FINITE; + + /* We got digits back, format them. We may need to pad 'digits' either on the left or right (or both) with extra zeros, so in general the resulting string has the form @@ -785,7 +801,8 @@ PyAPI_FUNC(char *) PyOS_double_to_string(double val, char format_code, int precision, - int flags) + int flags, + int *type) { char lc_format_code = format_code; char** float_strings = lc_float_strings; @@ -856,5 +873,5 @@ flags & Py_DTSF_SIGN, flags & Py_DTSF_ADD_DOT_0, flags & Py_DTSF_ALT, - float_strings); + float_strings, type); } From python-checkins at python.org Sun Apr 12 18:42:10 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 12 Apr 2009 18:42:10 +0200 (CEST) Subject: [Python-checkins] r71527 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090412164210.75EDE1E400C@bag.python.org> Author: eric.smith Date: Sun Apr 12 18:42:10 2009 New Revision: 71527 Log: Cleaned up comments by removing reference numbers that no longer apply. Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Sun Apr 12 18:42:10 2009 @@ -726,7 +726,7 @@ } p = buf; - /* 1: Add a negative sign if negative, and a plus sign if non-negative + /* Add a negative sign if negative, and a plus sign if non-negative and always_add_sign is true. */ if (sign == 1) *p++ = '-'; @@ -735,7 +735,7 @@ /* note that exactly one of the three 'if' conditions is true, so we include exactly one decimal point */ - /* 2: Zero padding on left of digit string */ + /* Zero padding on left of digit string */ if (decpt <= 0) { memset(p, '0', decpt-vdigits_start); p += decpt - vdigits_start; @@ -748,7 +748,7 @@ p += 0 - vdigits_start; } - /* 3: Digits, with included decimal point */ + /* Digits, with included decimal point */ if (0 < decpt && decpt <= digits_len) { strncpy(p, digits, decpt-0); p += decpt-0; @@ -761,7 +761,7 @@ p += digits_len; } - /* 4: And zeros on the right */ + /* And zeros on the right */ if (digits_len < decpt) { memset(p, '0', decpt-digits_len); p += decpt-digits_len; @@ -778,7 +778,7 @@ if (p[-1] == '.' && !use_alt_formatting) p--; - /* 6: Now that we've done zero padding, add an exponent if needed. */ + /* Now that we've done zero padding, add an exponent if needed. */ if (use_exp) { *p++ = float_strings[OFS_E][0]; exp_len = sprintf(p, "%+.02d", exp); @@ -787,7 +787,7 @@ exit: if (buf) { *p = '\0'; - /* It's too late if this fails, we've already stepped on + /* It's too late if this fails, as we've already stepped on memory that isn't ours. But it's an okay debugging test. */ assert(p-buf < bufsize); } From python-checkins at python.org Sun Apr 12 18:45:32 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 12 Apr 2009 18:45:32 +0200 (CEST) Subject: [Python-checkins] r71528 - in python/trunk/Lib/distutils: command/config.py tests/test_config_cmd.py Message-ID: <20090412164532.E80B31E400C@bag.python.org> Author: tarek.ziade Date: Sun Apr 12 18:45:32 2009 New Revision: 71528 Log: added a test for finalize_options Modified: python/trunk/Lib/distutils/command/config.py python/trunk/Lib/distutils/tests/test_config_cmd.py Modified: python/trunk/Lib/distutils/command/config.py ============================================================================== --- python/trunk/Lib/distutils/command/config.py (original) +++ python/trunk/Lib/distutils/command/config.py Sun Apr 12 18:45:32 2009 @@ -12,7 +12,7 @@ __revision__ = "$Id$" import sys, os, string, re -from types import * + from distutils.core import Command from distutils.errors import DistutilsExecError from distutils.sysconfig import customize_compiler @@ -68,19 +68,18 @@ def finalize_options(self): if self.include_dirs is None: self.include_dirs = self.distribution.include_dirs or [] - elif type(self.include_dirs) is StringType: - self.include_dirs = string.split(self.include_dirs, os.pathsep) + elif isinstance(self.include_dirs, str): + self.include_dirs = self.include_dirs.split(os.pathsep) if self.libraries is None: self.libraries = [] - elif type(self.libraries) is StringType: + elif isinstance(self.libraries, str): self.libraries = [self.libraries] if self.library_dirs is None: self.library_dirs = [] - elif type(self.library_dirs) is StringType: - self.library_dirs = string.split(self.library_dirs, os.pathsep) - + elif isinstance(self.library_dirs, str): + self.library_dirs = self.library_dirs.split(os.pathsep) def run (self): pass Modified: python/trunk/Lib/distutils/tests/test_config_cmd.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_config_cmd.py (original) +++ python/trunk/Lib/distutils/tests/test_config_cmd.py Sun Apr 12 18:45:32 2009 @@ -46,6 +46,21 @@ match = cmd.search_cpp(pattern='command', body='// xxx') self.assertEquals(match, 1) + def test_finalize_options(self): + # finalize_options does a bit of transformation + # on options + pkg_dir, dist = self.create_dist() + cmd = config(dist) + cmd.include_dirs = 'one%stwo' % os.pathsep + cmd.libraries = 'one' + cmd.library_dirs = 'three%sfour' % os.pathsep + cmd.ensure_finalized() + + self.assertEquals(cmd.include_dirs, ['one', 'two']) + self.assertEquals(cmd.libraries, ['one']) + self.assertEquals(cmd.library_dirs, ['three', 'four']) + + def test_suite(): return unittest.makeSuite(ConfigTestCase) From python-checkins at python.org Sun Apr 12 18:46:41 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 12 Apr 2009 18:46:41 +0200 (CEST) Subject: [Python-checkins] r71529 - python/branches/release26-maint Message-ID: <20090412164641.A864C1E400C@bag.python.org> Author: tarek.ziade Date: Sun Apr 12 18:46:41 2009 New Revision: 71529 Log: Blocked revisions 71528 via svnmerge ........ r71528 | tarek.ziade | 2009-04-12 18:45:32 +0200 (Sun, 12 Apr 2009) | 1 line added a test for finalize_options ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Apr 12 18:49:21 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 12 Apr 2009 18:49:21 +0200 (CEST) Subject: [Python-checkins] r71530 - in python/branches/py3k: Lib/distutils/command/config.py Lib/distutils/tests/test_config_cmd.py Message-ID: <20090412164921.2CE5A1E400C@bag.python.org> Author: tarek.ziade Date: Sun Apr 12 18:49:20 2009 New Revision: 71530 Log: Merged revisions 71528 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71528 | tarek.ziade | 2009-04-12 18:45:32 +0200 (Sun, 12 Apr 2009) | 1 line added a test for finalize_options ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/command/config.py python/branches/py3k/Lib/distutils/tests/test_config_cmd.py Modified: python/branches/py3k/Lib/distutils/command/config.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/config.py (original) +++ python/branches/py3k/Lib/distutils/command/config.py Sun Apr 12 18:49:20 2009 @@ -12,6 +12,7 @@ __revision__ = "$Id$" import sys, os, re + from distutils.core import Command from distutils.errors import DistutilsExecError from distutils.sysconfig import customize_compiler Modified: python/branches/py3k/Lib/distutils/tests/test_config_cmd.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_config_cmd.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_config_cmd.py Sun Apr 12 18:49:20 2009 @@ -46,6 +46,21 @@ match = cmd.search_cpp(pattern='command', body='// xxx') self.assertEquals(match, 1) + def test_finalize_options(self): + # finalize_options does a bit of transformation + # on options + pkg_dir, dist = self.create_dist() + cmd = config(dist) + cmd.include_dirs = 'one%stwo' % os.pathsep + cmd.libraries = 'one' + cmd.library_dirs = 'three%sfour' % os.pathsep + cmd.ensure_finalized() + + self.assertEquals(cmd.include_dirs, ['one', 'two']) + self.assertEquals(cmd.libraries, ['one']) + self.assertEquals(cmd.library_dirs, ['three', 'four']) + + def test_suite(): return unittest.makeSuite(ConfigTestCase) From python-checkins at python.org Sun Apr 12 18:50:03 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 12 Apr 2009 18:50:03 +0200 (CEST) Subject: [Python-checkins] r71531 - python/branches/release30-maint Message-ID: <20090412165003.768191E4047@bag.python.org> Author: tarek.ziade Date: Sun Apr 12 18:50:03 2009 New Revision: 71531 Log: Blocked revisions 71525 via svnmerge ................ r71525 | tarek.ziade | 2009-04-12 18:34:34 +0200 (Sun, 12 Apr 2009) | 9 lines Merged revisions 71523 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71523 | tarek.ziade | 2009-04-12 18:31:24 +0200 (Sun, 12 Apr 2009) | 1 line added a simple test for search_cpp ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sun Apr 12 18:50:37 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 12 Apr 2009 18:50:37 +0200 (CEST) Subject: [Python-checkins] r71532 - python/branches/release30-maint Message-ID: <20090412165037.C48411E4047@bag.python.org> Author: tarek.ziade Date: Sun Apr 12 18:50:37 2009 New Revision: 71532 Log: Blocked revisions 71530 via svnmerge ................ r71530 | tarek.ziade | 2009-04-12 18:49:20 +0200 (Sun, 12 Apr 2009) | 9 lines Merged revisions 71528 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71528 | tarek.ziade | 2009-04-12 18:45:32 +0200 (Sun, 12 Apr 2009) | 1 line added a test for finalize_options ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sun Apr 12 19:02:09 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 12 Apr 2009 19:02:09 +0200 (CEST) Subject: [Python-checkins] r71533 - in python/trunk/Lib/distutils: command/config.py tests/test_config_cmd.py Message-ID: <20090412170209.0B4151E4047@bag.python.org> Author: tarek.ziade Date: Sun Apr 12 19:02:08 2009 New Revision: 71533 Log: removed string usage and added a test for _clean Modified: python/trunk/Lib/distutils/command/config.py python/trunk/Lib/distutils/tests/test_config_cmd.py Modified: python/trunk/Lib/distutils/command/config.py ============================================================================== --- python/trunk/Lib/distutils/command/config.py (original) +++ python/trunk/Lib/distutils/command/config.py Sun Apr 12 19:02:08 2009 @@ -11,7 +11,7 @@ __revision__ = "$Id$" -import sys, os, string, re +import sys, os, re from distutils.core import Command from distutils.errors import DistutilsExecError @@ -81,7 +81,7 @@ elif isinstance(self.library_dirs, str): self.library_dirs = self.library_dirs.split(os.pathsep) - def run (self): + def run(self): pass @@ -156,7 +156,7 @@ if not filenames: filenames = self.temp_files self.temp_files = [] - log.info("removing: %s", string.join(filenames)) + log.info("removing: %s", ' '.join(filenames)) for filename in filenames: try: os.remove(filename) @@ -308,7 +308,7 @@ else: body.append(" %s;" % func) body.append("}") - body = string.join(body, "\n") + "\n" + body = "\n".join(body) + "\n" return self.try_link(body, headers, include_dirs, libraries, library_dirs) Modified: python/trunk/Lib/distutils/tests/test_config_cmd.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_config_cmd.py (original) +++ python/trunk/Lib/distutils/tests/test_config_cmd.py Sun Apr 12 19:02:08 2009 @@ -60,6 +60,24 @@ self.assertEquals(cmd.libraries, ['one']) self.assertEquals(cmd.library_dirs, ['three', 'four']) + def test_clean(self): + # _clean removes files + tmp_dir = self.mkdtemp() + f1 = os.path.join(tmp_dir, 'one') + f2 = os.path.join(tmp_dir, 'two') + + self.write_file(f1, 'xxx') + self.write_file(f2, 'xxx') + + for f in (f1, f2): + self.assert_(os.path.exists(f)) + + pkg_dir, dist = self.create_dist() + cmd = config(dist) + cmd._clean(f1, f2) + + for f in (f1, f2): + self.assert_(not os.path.exists(f)) def test_suite(): return unittest.makeSuite(ConfigTestCase) From python-checkins at python.org Sun Apr 12 19:02:55 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 12 Apr 2009 19:02:55 +0200 (CEST) Subject: [Python-checkins] r71534 - python/branches/release26-maint Message-ID: <20090412170255.EF1061E4050@bag.python.org> Author: tarek.ziade Date: Sun Apr 12 19:02:55 2009 New Revision: 71534 Log: Blocked revisions 71533 via svnmerge ........ r71533 | tarek.ziade | 2009-04-12 19:02:08 +0200 (Sun, 12 Apr 2009) | 1 line removed string usage and added a test for _clean ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Apr 12 19:04:40 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 12 Apr 2009 19:04:40 +0200 (CEST) Subject: [Python-checkins] r71535 - in python/branches/py3k: Lib/distutils/tests/test_config_cmd.py Message-ID: <20090412170440.1C9081E404F@bag.python.org> Author: tarek.ziade Date: Sun Apr 12 19:04:39 2009 New Revision: 71535 Log: Merged revisions 71533 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71533 | tarek.ziade | 2009-04-12 19:02:08 +0200 (Sun, 12 Apr 2009) | 1 line removed string usage and added a test for _clean ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/tests/test_config_cmd.py Modified: python/branches/py3k/Lib/distutils/tests/test_config_cmd.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_config_cmd.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_config_cmd.py Sun Apr 12 19:04:39 2009 @@ -60,6 +60,24 @@ self.assertEquals(cmd.libraries, ['one']) self.assertEquals(cmd.library_dirs, ['three', 'four']) + def test_clean(self): + # _clean removes files + tmp_dir = self.mkdtemp() + f1 = os.path.join(tmp_dir, 'one') + f2 = os.path.join(tmp_dir, 'two') + + self.write_file(f1, 'xxx') + self.write_file(f2, 'xxx') + + for f in (f1, f2): + self.assert_(os.path.exists(f)) + + pkg_dir, dist = self.create_dist() + cmd = config(dist) + cmd._clean(f1, f2) + + for f in (f1, f2): + self.assert_(not os.path.exists(f)) def test_suite(): return unittest.makeSuite(ConfigTestCase) From python-checkins at python.org Sun Apr 12 19:05:27 2009 From: python-checkins at python.org (tarek.ziade) Date: Sun, 12 Apr 2009 19:05:27 +0200 (CEST) Subject: [Python-checkins] r71536 - python/branches/release30-maint Message-ID: <20090412170527.A262C1E41D8@bag.python.org> Author: tarek.ziade Date: Sun Apr 12 19:05:27 2009 New Revision: 71536 Log: Blocked revisions 71535 via svnmerge ................ r71535 | tarek.ziade | 2009-04-12 19:04:39 +0200 (Sun, 12 Apr 2009) | 9 lines Merged revisions 71533 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71533 | tarek.ziade | 2009-04-12 19:02:08 +0200 (Sun, 12 Apr 2009) | 1 line removed string usage and added a test for _clean ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sun Apr 12 19:24:12 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 12 Apr 2009 19:24:12 +0200 (CEST) Subject: [Python-checkins] r71537 - in python/trunk: Lib/ConfigParser.py Lib/test/test_cfgparser.py Misc/NEWS Message-ID: <20090412172412.051E11E404F@bag.python.org> Author: georg.brandl Date: Sun Apr 12 19:24:11 2009 New Revision: 71537 Log: #5741: dont disallow double percent signs in SafeConfigParser.set() keys. Modified: python/trunk/Lib/ConfigParser.py python/trunk/Lib/test/test_cfgparser.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/ConfigParser.py ============================================================================== --- python/trunk/Lib/ConfigParser.py (original) +++ python/trunk/Lib/ConfigParser.py Sun Apr 12 19:24:11 2009 @@ -620,7 +620,6 @@ return ''.join(L) _interpvar_re = re.compile(r"%\(([^)]+)\)s") - _badpercent_re = re.compile(r"%[^%]|%$") def _interpolate_some(self, option, accum, rest, section, map, depth): if depth > MAX_INTERPOLATION_DEPTH: @@ -667,9 +666,10 @@ # check for bad percent signs: # first, replace all "good" interpolations tmp_value = self._interpvar_re.sub('', value) + tmp_value = tmp_value.replace('%%', '') # then, check if there's a lone percent sign left - m = self._badpercent_re.search(tmp_value) - if m: + percent_index = tmp_value.find('%') + if percent_index != -1: raise ValueError("invalid interpolation syntax in %r at " - "position %d" % (value, m.start())) + "position %d" % (value, percent_index)) ConfigParser.set(self, section, option, value) Modified: python/trunk/Lib/test/test_cfgparser.py ============================================================================== --- python/trunk/Lib/test/test_cfgparser.py (original) +++ python/trunk/Lib/test/test_cfgparser.py Sun Apr 12 19:24:11 2009 @@ -434,6 +434,10 @@ self.assertEqual(cf.get('sect', "option1"), "foo") + # bug #5741: double percents are *not* malformed + cf.set("sect", "option2", "foo%%bar") + self.assertEqual(cf.get("sect", "option2"), "foo%bar") + def test_set_nonstring_types(self): cf = self.fromstring("[sect]\n" "option1=foo\n") Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Apr 12 19:24:11 2009 @@ -221,6 +221,9 @@ Library ------- +- Issue #5741: don't disallow "%%" (which is an escape for "%") when setting + a value in SafeConfigParser. + - Issue #5732: added a new command in Distutils: check. - Issue #5731: Distutils bdist_wininst no longer worked on non-Windows From python-checkins at python.org Sun Apr 12 19:26:19 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 12 Apr 2009 19:26:19 +0200 (CEST) Subject: [Python-checkins] r71538 - in python/branches/release26-maint: Lib/ConfigParser.py Lib/test/test_cfgparser.py Misc/NEWS Message-ID: <20090412172619.369C21E404F@bag.python.org> Author: georg.brandl Date: Sun Apr 12 19:26:19 2009 New Revision: 71538 Log: Merged revisions 71537 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71537 | georg.brandl | 2009-04-12 19:24:11 +0200 (So, 12 Apr 2009) | 1 line #5741: dont disallow double percent signs in SafeConfigParser.set() keys. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/ConfigParser.py python/branches/release26-maint/Lib/test/test_cfgparser.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/ConfigParser.py ============================================================================== --- python/branches/release26-maint/Lib/ConfigParser.py (original) +++ python/branches/release26-maint/Lib/ConfigParser.py Sun Apr 12 19:26:19 2009 @@ -614,7 +614,6 @@ return ''.join(L) _interpvar_re = re.compile(r"%\(([^)]+)\)s") - _badpercent_re = re.compile(r"%[^%]|%$") def _interpolate_some(self, option, accum, rest, section, map, depth): if depth > MAX_INTERPOLATION_DEPTH: @@ -661,9 +660,10 @@ # check for bad percent signs: # first, replace all "good" interpolations tmp_value = self._interpvar_re.sub('', value) + tmp_value = tmp_value.replace('%%', '') # then, check if there's a lone percent sign left - m = self._badpercent_re.search(tmp_value) - if m: + percent_index = tmp_value.find('%') + if percent_index != -1: raise ValueError("invalid interpolation syntax in %r at " - "position %d" % (value, m.start())) + "position %d" % (value, percent_index)) ConfigParser.set(self, section, option, value) Modified: python/branches/release26-maint/Lib/test/test_cfgparser.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_cfgparser.py (original) +++ python/branches/release26-maint/Lib/test/test_cfgparser.py Sun Apr 12 19:26:19 2009 @@ -434,6 +434,10 @@ self.assertEqual(cf.get('sect', "option1"), "foo") + # bug #5741: double percents are *not* malformed + cf.set("sect", "option2", "foo%%bar") + self.assertEqual(cf.get("sect", "option2"), "foo%bar") + def test_set_nonstring_types(self): cf = self.fromstring("[sect]\n" "option1=foo\n") Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sun Apr 12 19:26:19 2009 @@ -103,6 +103,9 @@ Library ------- +- Issue #5741: don't disallow "%%" (which is an escape for "%") when setting + a value in SafeConfigParser. + - Issue #5731: Distutils bdist_wininst no longer worked on non-Windows platforms. Initial patch by Paul Moore. From buildbot at python.org Sun Apr 12 20:06:56 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 12 Apr 2009 18:06:56 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 2.6 Message-ID: <20090412180656.8926C1E4016@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%202.6/builds/249 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From buildbot at python.org Sun Apr 12 20:14:43 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 12 Apr 2009 18:14:43 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 2.6 Message-ID: <20090412181443.563921E4016@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%202.6/builds/238 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: Traceback (most recent call last): File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/threading.py", line 525, in __bootstrap_inner self.run() File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/threading.py", line 477, in run self.__target(*self.__args, **self.__kwargs) File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/bsddb/test/test_thread.py", line 306, in readerThread rec = dbutils.DeadlockWrap(c.next, max_retries=10) File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/bsddb/dbutils.py", line 68, in DeadlockWrap return function(*_args, **_kwargs) DBLockDeadlockError: (-30994, 'DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock') sincerely, -The Buildbot From buildbot at python.org Sun Apr 12 20:32:10 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 12 Apr 2009 18:32:10 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 3.x Message-ID: <20090412183210.9F62F1E4016@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%203.x/builds/662 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl,r.david.murray,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_asynchat make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Sun Apr 12 20:40:59 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 12 Apr 2009 18:40:59 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 2.6 Message-ID: <20090412184059.6D6631E4016@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%202.6/builds/241 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: Traceback (most recent call last): File "/home/pybot/buildarea/2.6.klose-debian-ppc/build/Lib/test/test_signal.py", line 165, in test_main pickle.dump(None, done_w) File "/home/pybot/buildarea/2.6.klose-debian-ppc/build/Lib/contextlib.py", line 153, in __exit__ self.thing.close() IOError: [Errno 9] Bad file descriptor 1 test failed: test_signal make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Sun Apr 12 20:50:20 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 12 Apr 2009 18:50:20 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090412185020.A13E51E4016@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/571 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl,r.david.murray,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/test/test_urllib2_localnet.py", line 251, in test_proxy_with_bad_password_raises_httperror self.URL) File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/unittest.py", line 535, in assertRaises callableObj(*args, **kwargs) File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/urllib/request.py", line 348, in open response = meth(req, response) File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/urllib/request.py", line 460, in http_response 'http', request, response, code, msg, hdrs) File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/urllib/request.py", line 380, in error result = self._call_chain(*args) File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/urllib/request.py", line 320, in _call_chain result = func(*args) File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/urllib/request.py", line 980, in http_error_407 host, req, headers) File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/urllib/request.py", line 858, in http_error_auth_reqed return self.retry_http_digest_auth(req, authreq) File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/urllib/request.py", line 869, in retry_http_digest_auth resp = self.parent.open(req) File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/urllib/request.py", line 342, in open response = self._open(req, data) File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/urllib/request.py", line 360, in _open '_open', req) File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/urllib/request.py", line 320, in _call_chain result = func(*args) File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/urllib/request.py", line 1063, in http_open return self.do_open(http.client.HTTPConnection, req) File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/urllib/request.py", line 1048, in do_open raise URLError(err) urllib.error.URLError: 1 test failed: test_urllib2_localnet make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Sun Apr 12 20:56:30 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 12 Apr 2009 18:56:30 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 3.0 Message-ID: <20090412185631.0374B1E4073@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%203.0/builds/262 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: r.david.murray,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_asynchat make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Sun Apr 12 21:45:31 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 12 Apr 2009 19:45:31 +0000 Subject: [Python-checkins] buildbot failure in OS X x86 2.6 Message-ID: <20090412194531.827FD1E4016@bag.python.org> The Buildbot has detected a new failure of OS X x86 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/OS%20X%20x86%202.6/builds/206 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: noller-osx86 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: Traceback (most recent call last): File "/Users/buildbot/buildarea/2.6.noller-osx86/build/Lib/test/test_signal.py", line 165, in test_main pickle.dump(None, done_w) File "/Users/buildbot/buildarea/2.6.noller-osx86/build/Lib/contextlib.py", line 153, in __exit__ self.thing.close() IOError: [Errno 9] Bad file descriptor 1 test failed: test_signal make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Sun Apr 12 21:57:19 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 12 Apr 2009 19:57:19 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.0 Message-ID: <20090412195720.35C411E4016@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.0/builds/263 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: r.david.murray,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_doctest test_ssl make: *** [buildbottest] Error 1 sincerely, -The Buildbot From nnorwitz at gmail.com Sun Apr 12 22:11:11 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 12 Apr 2009 16:11:11 -0400 Subject: [Python-checkins] Python Regression Test Failures basics (2) Message-ID: <20090412201111.GA29863@python.psfb.org> 332 tests OK. 2 tests failed: test_lib2to3 test_multiprocessing 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23366 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 test_lib2to3 failed -- errors occurred; run in verbose mode for details 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 test_multiprocessing crashed -- : cannot import name SkipTest test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18065 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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 332 tests OK. 2 tests failed: test_lib2to3 test_multiprocessing 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl [741905 refs] From nnorwitz at gmail.com Sun Apr 12 22:18:58 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 12 Apr 2009 16:18:58 -0400 Subject: [Python-checkins] Python Regression Test Failures opt (3) Message-ID: <20090412201858.GA32299@python.psfb.org> 331 tests OK. 3 tests failed: test_asyncore test_lib2to3 test_multiprocessing 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array test_ast test_asynchat test_asyncore test test_asyncore failed -- Traceback (most recent call last): File "/tmp/python-test/local/lib/python2.7/test/test_asyncore.py", line 280, in test_log_info self.assertEquals(lines, expected) AssertionError: First differing element 1: info: Why can't she have egg bacon spam and sausage? SPAM: THAT'S got spam in it! + ['EGGS: Have you got anything without spam?', "SPAM: THAT'S got spam in it!"] - ['EGGS: Have you got anything without spam?', - "info: Why can't she have egg bacon spam and sausage?", - "SPAM: THAT'S got spam in it!"] 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils [17363 refs] [17363 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23366 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 test_lib2to3 failed -- errors occurred; run in verbose mode for details 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 test_multiprocessing crashed -- : cannot import name SkipTest test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18902 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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 331 tests OK. 3 tests failed: test_asyncore test_lib2to3 test_multiprocessing 34 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll test_gl test_imgfile test_ioctl test_kqueue test_linuxaudiodev test_macos test_macostools test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages 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 5 skips unexpected on linux2: test_ttk_guionly test_epoll test_ttk_textonly test_tk test_ioctl [741142 refs] From python-checkins at python.org Sun Apr 12 22:24:56 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 12 Apr 2009 22:24:56 +0200 (CEST) Subject: [Python-checkins] r71539 - python/trunk/Lib/test/test_multiprocessing.py Message-ID: <20090412202456.6D6C81E4016@bag.python.org> Author: benjamin.peterson Date: Sun Apr 12 22:24:56 2009 New Revision: 71539 Log: remove useless import Modified: python/trunk/Lib/test/test_multiprocessing.py Modified: python/trunk/Lib/test/test_multiprocessing.py ============================================================================== --- python/trunk/Lib/test/test_multiprocessing.py (original) +++ python/trunk/Lib/test/test_multiprocessing.py Sun Apr 12 22:24:56 2009 @@ -1872,7 +1872,6 @@ try: lock = multiprocessing.RLock() except OSError: - from test.test_support import SkipTest raise unittest.SkipTest("OSError raises on RLock creation, see issue 3111!") if run is None: From python-checkins at python.org Sun Apr 12 22:30:53 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 12 Apr 2009 22:30:53 +0200 (CEST) Subject: [Python-checkins] r71540 - python/trunk/Lib/optparse.py Message-ID: <20090412203053.6175D1E41F8@bag.python.org> Author: georg.brandl Date: Sun Apr 12 22:30:53 2009 New Revision: 71540 Log: #5719: add short usage example to optparse docstring. Modified: python/trunk/Lib/optparse.py Modified: python/trunk/Lib/optparse.py ============================================================================== --- python/trunk/Lib/optparse.py (original) +++ python/trunk/Lib/optparse.py Sun Apr 12 22:30:53 2009 @@ -6,6 +6,19 @@ For support, use the optik-users at lists.sourceforge.net mailing list (http://lists.sourceforge.net/lists/listinfo/optik-users). + +Simple usage example: + + from optparse import OptionParser + + parser = OptionParser() + parser.add_option("-f", "--file", dest="filename", + help="write report to FILE", metavar="FILE") + parser.add_option("-q", "--quiet", + action="store_false", dest="verbose", default=True, + help="don't print status messages to stdout") + + (options, args) = parser.parse_args() """ __version__ = "1.5.3" From python-checkins at python.org Sun Apr 12 22:32:11 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 12 Apr 2009 22:32:11 +0200 (CEST) Subject: [Python-checkins] r71541 - in python/branches/py3k: Lib/test/test_multiprocessing.py Message-ID: <20090412203211.6DD991E4016@bag.python.org> Author: benjamin.peterson Date: Sun Apr 12 22:32:11 2009 New Revision: 71541 Log: Merged revisions 71539 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71539 | benjamin.peterson | 2009-04-12 15:24:56 -0500 (Sun, 12 Apr 2009) | 1 line remove useless import ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_multiprocessing.py Modified: python/branches/py3k/Lib/test/test_multiprocessing.py ============================================================================== --- python/branches/py3k/Lib/test/test_multiprocessing.py (original) +++ python/branches/py3k/Lib/test/test_multiprocessing.py Sun Apr 12 22:32:11 2009 @@ -1873,7 +1873,6 @@ try: lock = multiprocessing.RLock() except OSError: - from test.support import TestSkipped raise unittest.SkipTest("OSError raises on RLock creation, see issue 3111!") if run is None: From buildbot at python.org Sun Apr 12 23:32:37 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 12 Apr 2009 21:32:37 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090412213237.2602C1E4016@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/264 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: r.david.murray,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_distutils test_posix ====================================================================== FAIL: test_get_python_inc (distutils.tests.test_sysconfig.SysconfigTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/distutils/tests/test_sysconfig.py", line 45, in test_get_python_inc self.assert_(os.path.isdir(inc_dir), inc_dir) AssertionError: /home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/Include ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From buildbot at python.org Mon Apr 13 00:29:56 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 12 Apr 2009 22:29:56 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc trunk Message-ID: <20090412222956.28A6D1E4016@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc trunk. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%20trunk/builds/289 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: georg.brandl,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posixpath sincerely, -The Buildbot From python-checkins at python.org Mon Apr 13 00:57:40 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 13 Apr 2009 00:57:40 +0200 (CEST) Subject: [Python-checkins] r71542 - python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Message-ID: <20090412225740.75E001E4016@bag.python.org> Author: eric.smith Date: Mon Apr 13 00:57:40 2009 New Revision: 71542 Log: Replaced nested if's with a switch statement. Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h (original) +++ python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Mon Apr 13 00:57:40 2009 @@ -362,17 +362,18 @@ */ /* compute the various parts we're going to write */ - if (format->sign == '+') { + switch (format->sign) { + case '+': /* always put a + or - */ spec->n_sign = 1; spec->sign = (sign_char == '-' ? '-' : '+'); - } - else if (format->sign == ' ') { + break; + case ' ': spec->n_sign = 1; spec->sign = (sign_char == '-' ? '-' : ' '); - } - else { - /* non specified, or the default (-) */ + break; + default: + /* Not specified, or the default (-) */ if (sign_char == '-') { spec->n_sign = 1; spec->sign = '-'; From python-checkins at python.org Mon Apr 13 01:16:43 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 13 Apr 2009 01:16:43 +0200 (CEST) Subject: [Python-checkins] r71543 - python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Message-ID: <20090412231643.1AC1B1E4016@bag.python.org> Author: eric.smith Date: Mon Apr 13 01:16:42 2009 New Revision: 71543 Log: Removed unused member of LocaleInfo. Improved comments. Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h (original) +++ python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Mon Apr 13 01:16:42 2009 @@ -253,11 +253,6 @@ before and including the decimal. Note that locales only support 8-bit chars, not unicode. */ typedef struct { - int type; /* One of the LT_* codes. Having this here is just - an optimization for the common case of not - using any locale info (LT_NO_LOCALE). It could - really be inferred just by looking at the - following fields.*/ char *decimal_point; char *thousands_sep; char *grouping; @@ -522,7 +517,6 @@ static void get_locale_info(int type, LocaleInfo *locale_info) { - locale_info->type = type; switch (type) { case LT_CURRENT_LOCALE: { struct lconv *locale_data = localeconv(); @@ -534,7 +528,9 @@ case LT_DEFAULT_LOCALE: locale_info->decimal_point = "."; locale_info->thousands_sep = ","; - locale_info->grouping = "\3"; /* every 3 characters, trailing 0 means repeat */ + locale_info->grouping = "\3"; /* Group every 3 characters, + trailing 0 means repeat + infinitely. */ break; case LT_NO_LOCALE: locale_info->decimal_point = "."; From python-checkins at python.org Mon Apr 13 01:19:56 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 13 Apr 2009 01:19:56 +0200 (CEST) Subject: [Python-checkins] r71544 - python/trunk/Doc/library/multiprocessing.rst Message-ID: <20090412231956.8EF681E4016@bag.python.org> Author: benjamin.peterson Date: Mon Apr 13 01:19:56 2009 New Revision: 71544 Log: fix extra parenthesis #5774 Modified: python/trunk/Doc/library/multiprocessing.rst Modified: python/trunk/Doc/library/multiprocessing.rst ============================================================================== --- python/trunk/Doc/library/multiprocessing.rst (original) +++ python/trunk/Doc/library/multiprocessing.rst Mon Apr 13 01:19:56 2009 @@ -1162,7 +1162,7 @@ Connect a local manager object to a remote manager process: >>> from multiprocessing.managers import BaseManager - >>> m = BaseManager(address='127.0.0.1', authkey='abc)) + >>> m = BaseManager(address='127.0.0.1', authkey='abc) >>> m.connect() .. method:: shutdown() From python-checkins at python.org Mon Apr 13 01:33:18 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 13 Apr 2009 01:33:18 +0200 (CEST) Subject: [Python-checkins] r71545 - python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Message-ID: <20090412233318.CFDCC1E4016@bag.python.org> Author: eric.smith Date: Mon Apr 13 01:33:18 2009 New Revision: 71545 Log: Improved error detecttion with ',' modifier. Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h (original) +++ python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Mon Apr 13 01:33:18 2009 @@ -230,10 +230,27 @@ ++ptr; } - /* XXX other types like xobXOB also invalid */ - if (format->type == 'n' && format->thousands_separators) { - PyErr_Format(PyExc_ValueError, "Cannot specify ',' with 'n'."); - return 0; + /* Do as much validating as we can, just by looking at the format + specifier. Do not take into account what type of formatting + we're doing (int, float, string). */ + + if (format->thousands_separators) { + switch (format->type) { + case 'd': + case 'e': + case 'f': + case 'g': + case 'E': + case 'G': + case '%': + case 'F': + /* These are allowed. See PEP 378.*/ + break; + default: + PyErr_Format(PyExc_ValueError, + "Cannot specify ',' with '%c'.", format->type); + return 0; + } } return 1; From python-checkins at python.org Mon Apr 13 01:44:15 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 13 Apr 2009 01:44:15 +0200 (CEST) Subject: [Python-checkins] r71546 - python/trunk/Doc/library/multiprocessing.rst Message-ID: <20090412234415.600271E4016@bag.python.org> Author: benjamin.peterson Date: Mon Apr 13 01:44:15 2009 New Revision: 71546 Log: fix missing quote Modified: python/trunk/Doc/library/multiprocessing.rst Modified: python/trunk/Doc/library/multiprocessing.rst ============================================================================== --- python/trunk/Doc/library/multiprocessing.rst (original) +++ python/trunk/Doc/library/multiprocessing.rst Mon Apr 13 01:44:15 2009 @@ -1162,7 +1162,7 @@ Connect a local manager object to a remote manager process: >>> from multiprocessing.managers import BaseManager - >>> m = BaseManager(address='127.0.0.1', authkey='abc) + >>> m = BaseManager(address='127.0.0.1', authkey='abc') >>> m.connect() .. method:: shutdown() From python-checkins at python.org Mon Apr 13 01:57:39 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 13 Apr 2009 01:57:39 +0200 (CEST) Subject: [Python-checkins] r71547 - python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Message-ID: <20090412235739.7B9B11E4016@bag.python.org> Author: eric.smith Date: Mon Apr 13 01:57:39 2009 New Revision: 71547 Log: Cleaned up comments. Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h (original) +++ python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Mon Apr 13 01:57:39 2009 @@ -188,8 +188,8 @@ /* XXX add error checking */ specified_width = get_integer(&ptr, end, &format->width); - /* if specified_width is 0, we didn't consume any characters for - the width. in that case, reset the width to -1, because + /* If specified_width is 0, we didn't consume any characters for + the width. In that case, reset the width to -1, because get_integer() will have set it to zero */ if (specified_width == 0) { format->width = -1; @@ -208,7 +208,7 @@ /* XXX add error checking */ specified_width = get_integer(&ptr, end, &format->precision); - /* not having a precision after a dot is an error */ + /* Not having a precision after a dot is an error. */ if (specified_width == 0) { PyErr_Format(PyExc_ValueError, "Format specifier missing precision"); @@ -217,10 +217,10 @@ } - /* Finally, parse the type field */ + /* Finally, parse the type field. */ if (end-ptr > 1) { - /* invalid conversion spec */ + /* More than one char remain, invalid conversion spec. */ PyErr_Format(PyExc_ValueError, "Invalid conversion specification"); return 0; } @@ -287,14 +287,14 @@ Py_ssize_t n_grouped_digits; /* Space taken up by the digits, including any grouping chars. */ Py_ssize_t n_decimal; /* 0 if only an integer */ - Py_ssize_t n_remainder; /* digits in decimal and/or exponent part, - excluding the decimal itself, if present */ - - /* These 2 are calculatable from parameters, but needed between - calls to calc_number_widths and fill_number in order to not - have to pass all of the parameters to fill_number. */ - Py_ssize_t n_digits; /* The number of digits before a decimal or - exponent. */ + Py_ssize_t n_remainder; /* Digits in decimal and/or exponent part, + excluding the decimal itself, if + present. */ + + /* These 2 are not the widths of fields, but are needed by + STRINGLIB_GROUPING. */ + Py_ssize_t n_digits; /* The number of digits before a decimal + or exponent. */ Py_ssize_t n_min_width; /* The min_width we used when we computed the n_grouped_digits width. */ } NumberFieldWidths; @@ -880,7 +880,7 @@ from a hard-code pseudo-locale */ LocaleInfo locale; - /* alternate is not allowed on floats. */ + /* Alternate is not allowed on floats. */ if (format->alternate) { PyErr_SetString(PyExc_ValueError, "Alternate form (#) not allowed in float format " @@ -889,12 +889,15 @@ } if (type == '\0') { - /* Omitted type specifier, this is like 'g' but with at least + /* Omitted type specifier. This is like 'g' but with at least one digit after the decimal point. */ type = 'g'; flags |= Py_DTSF_ADD_DOT_0; } + if (type == 'n') + /* 'n' is the same as 'g', except for the locale used to + format the result. We take care of that later. */ type = 'g'; /* 'F' is the same as 'f', per the PEP */ @@ -913,12 +916,12 @@ if (precision < 0) precision = 6; - if (type == 'f' && fabs(val) >= 1e50) + if ((type == 'f' || type == 'F') && fabs(val) >= 1e50) type = 'g'; - /* cast "type", because if we're in unicode we need to pass a - 8-bit char. this is safe, because we've restricted what "type" - can be */ + /* Cast "type", because if we're in unicode we need to pass a + 8-bit char. This is safe, because we've restricted what "type" + can be. */ buf = PyOS_double_to_string(val, (char)type, precision, flags, &float_type); if (buf == NULL) From python-checkins at python.org Mon Apr 13 02:29:50 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 13 Apr 2009 02:29:50 +0200 (CEST) Subject: [Python-checkins] r71548 - python/trunk/Objects/stringlib/formatter.h Message-ID: <20090413002950.C9FB31E4016@bag.python.org> Author: eric.smith Date: Mon Apr 13 02:29:50 2009 New Revision: 71548 Log: Fixed incorrect object passed into format_float_internal(). This was resulting in a conversion being done twice. Modified: python/trunk/Objects/stringlib/formatter.h Modified: python/trunk/Objects/stringlib/formatter.h ============================================================================== --- python/trunk/Objects/stringlib/formatter.h (original) +++ python/trunk/Objects/stringlib/formatter.h Mon Apr 13 02:29:50 2009 @@ -939,7 +939,7 @@ tmp = PyNumber_Float(obj); if (tmp == NULL) goto done; - result = format_float_internal(obj, &format); + result = format_float_internal(tmp, &format); break; default: From python-checkins at python.org Mon Apr 13 02:32:17 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 13 Apr 2009 02:32:17 +0200 (CEST) Subject: [Python-checkins] r71549 - in python/branches/release26-maint: Objects/stringlib/formatter.h Message-ID: <20090413003217.428751E4016@bag.python.org> Author: eric.smith Date: Mon Apr 13 02:32:15 2009 New Revision: 71549 Log: Merged revisions 71548 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71548 | eric.smith | 2009-04-12 20:29:50 -0400 (Sun, 12 Apr 2009) | 1 line Fixed incorrect object passed into format_float_internal(). This was resulting in a conversion being done twice. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Objects/stringlib/formatter.h Modified: python/branches/release26-maint/Objects/stringlib/formatter.h ============================================================================== --- python/branches/release26-maint/Objects/stringlib/formatter.h (original) +++ python/branches/release26-maint/Objects/stringlib/formatter.h Mon Apr 13 02:32:15 2009 @@ -939,7 +939,7 @@ tmp = PyNumber_Float(obj); if (tmp == NULL) goto done; - result = format_float_internal(obj, &format); + result = format_float_internal(tmp, &format); break; default: From python-checkins at python.org Mon Apr 13 02:50:24 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 13 Apr 2009 02:50:24 +0200 (CEST) Subject: [Python-checkins] r71550 - in python/branches/py3k: Objects/stringlib/formatter.h Message-ID: <20090413005024.2D9271E4016@bag.python.org> Author: eric.smith Date: Mon Apr 13 02:50:23 2009 New Revision: 71550 Log: Merged revisions 71548 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71548 | eric.smith | 2009-04-12 20:29:50 -0400 (Sun, 12 Apr 2009) | 1 line Fixed incorrect object passed into format_float_internal(). This was resulting in a conversion being done twice. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Objects/stringlib/formatter.h Modified: python/branches/py3k/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k/Objects/stringlib/formatter.h (original) +++ python/branches/py3k/Objects/stringlib/formatter.h Mon Apr 13 02:50:23 2009 @@ -968,7 +968,7 @@ tmp = PyNumber_Float(obj); if (tmp == NULL) goto done; - result = format_float_internal(obj, &format); + result = format_float_internal(tmp, &format); break; default: From python-checkins at python.org Mon Apr 13 02:55:10 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 13 Apr 2009 02:55:10 +0200 (CEST) Subject: [Python-checkins] r71551 - in python/branches/py3k-short-float-repr: Objects/stringlib/formatter.h Message-ID: <20090413005510.91CCB1E4016@bag.python.org> Author: eric.smith Date: Mon Apr 13 02:55:10 2009 New Revision: 71551 Log: Merged revisions 71550 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71550 | eric.smith | 2009-04-12 20:50:23 -0400 (Sun, 12 Apr 2009) | 9 lines Merged revisions 71548 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71548 | eric.smith | 2009-04-12 20:29:50 -0400 (Sun, 12 Apr 2009) | 1 line Fixed incorrect object passed into format_float_internal(). This was resulting in a conversion being done twice. ........ ................ Modified: python/branches/py3k-short-float-repr/ (props changed) python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h (original) +++ python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Mon Apr 13 02:55:10 2009 @@ -1080,7 +1080,7 @@ tmp = PyNumber_Float(obj); if (tmp == NULL) goto done; - result = format_float_internal(obj, &format); + result = format_float_internal(tmp, &format); break; default: From python-checkins at python.org Mon Apr 13 02:58:35 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 13 Apr 2009 02:58:35 +0200 (CEST) Subject: [Python-checkins] r71552 - in python/branches/release30-maint: Objects/stringlib/formatter.h Message-ID: <20090413005835.6901C1E421A@bag.python.org> Author: eric.smith Date: Mon Apr 13 02:58:35 2009 New Revision: 71552 Log: Merged revisions 71550 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71550 | eric.smith | 2009-04-12 20:50:23 -0400 (Sun, 12 Apr 2009) | 9 lines Merged revisions 71548 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71548 | eric.smith | 2009-04-12 20:29:50 -0400 (Sun, 12 Apr 2009) | 1 line Fixed incorrect object passed into format_float_internal(). This was resulting in a conversion being done twice. ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Objects/stringlib/formatter.h Modified: python/branches/release30-maint/Objects/stringlib/formatter.h ============================================================================== --- python/branches/release30-maint/Objects/stringlib/formatter.h (original) +++ python/branches/release30-maint/Objects/stringlib/formatter.h Mon Apr 13 02:58:35 2009 @@ -939,7 +939,7 @@ tmp = PyNumber_Float(obj); if (tmp == NULL) goto done; - result = format_float_internal(obj, &format); + result = format_float_internal(tmp, &format); break; default: From python-checkins at python.org Mon Apr 13 03:06:46 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 13 Apr 2009 03:06:46 +0200 (CEST) Subject: [Python-checkins] r71553 - python/trunk/Lib/test/test_asyncore.py Message-ID: <20090413010646.B109F1E4062@bag.python.org> Author: r.david.murray Date: Mon Apr 13 03:06:46 2009 New Revision: 71553 Log: Adjust test_asyncore to account for intentional asyncore behavior change introduced by r70934 that was causing a test failure when run under -O. Modified: python/trunk/Lib/test/test_asyncore.py Modified: python/trunk/Lib/test/test_asyncore.py ============================================================================== --- python/trunk/Lib/test/test_asyncore.py (original) +++ python/trunk/Lib/test/test_asyncore.py Mon Apr 13 03:06:46 2009 @@ -272,10 +272,7 @@ sys.stdout = stdout lines = fp.getvalue().splitlines() - if __debug__: - expected = ['EGGS: %s' % l1, 'info: %s' % l2, 'SPAM: %s' % l3] - else: - expected = ['EGGS: %s' % l1, 'SPAM: %s' % l3] + expected = ['EGGS: %s' % l1, 'info: %s' % l2, 'SPAM: %s' % l3] self.assertEquals(lines, expected) From python-checkins at python.org Mon Apr 13 03:07:06 2009 From: python-checkins at python.org (hirokazu.yamamoto) Date: Mon, 13 Apr 2009 03:07:06 +0200 (CEST) Subject: [Python-checkins] r71554 - python/trunk/Doc/library/email.message.rst Message-ID: <20090413010706.74E801E4016@bag.python.org> Author: hirokazu.yamamoto Date: Mon Apr 13 03:07:06 2009 New Revision: 71554 Log: Fixed typo. (email.Utils => email.utils) Modified: python/trunk/Doc/library/email.message.rst Modified: python/trunk/Doc/library/email.message.rst ============================================================================== --- python/trunk/Doc/library/email.message.rst (original) +++ python/trunk/Doc/library/email.message.rst Mon Apr 13 03:07:06 2009 @@ -373,13 +373,13 @@ If your application doesn't care whether the parameter was encoded as in :rfc:`2231`, you can collapse the parameter value by calling - :func:`email.Utils.collapse_rfc2231_value`, passing in the return value + :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 isn't. For example:: rawparam = msg.get_param('foo') - param = email.Utils.collapse_rfc2231_value(rawparam) + param = email.utils.collapse_rfc2231_value(rawparam) In any case, the parameter value (either the returned string, or the ``VALUE`` item in the 3-tuple) is always unquoted, unless *unquote* is set From python-checkins at python.org Mon Apr 13 03:21:56 2009 From: python-checkins at python.org (hirokazu.yamamoto) Date: Mon, 13 Apr 2009 03:21:56 +0200 (CEST) Subject: [Python-checkins] r71555 - python/trunk/Doc/library/email.message.rst Message-ID: <20090413012156.A0BB81E4016@bag.python.org> Author: hirokazu.yamamoto Date: Mon Apr 13 03:21:56 2009 New Revision: 71555 Log: Fixed another typos. (email.Utils => email.utils) Modified: python/trunk/Doc/library/email.message.rst Modified: python/trunk/Doc/library/email.message.rst ============================================================================== --- python/trunk/Doc/library/email.message.rst (original) +++ python/trunk/Doc/library/email.message.rst Mon Apr 13 03:21:56 2009 @@ -445,7 +445,7 @@ does not have a ``filename`` parameter, this method falls back to looking for the ``name`` parameter. If neither is found, or the header is missing, then *failobj* is returned. The returned string will always be - unquoted as per :meth:`Utils.unquote`. + unquoted as per :func:`email.utils.unquote`. .. method:: get_boundary([failobj]) @@ -453,7 +453,7 @@ Return the value of the ``boundary`` parameter of the :mailheader:`Content-Type` header of the message, or *failobj* if either the header is missing, or has no ``boundary`` parameter. The returned - string will always be unquoted as per :meth:`Utils.unquote`. + string will always be unquoted as per :func:`email.utils.unquote`. .. method:: set_boundary(boundary) From python-checkins at python.org Mon Apr 13 03:22:04 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 13 Apr 2009 03:22:04 +0200 (CEST) Subject: [Python-checkins] r71556 - in python/branches/py3k: Lib/test/test_asyncore.py Message-ID: <20090413012204.449E71E4016@bag.python.org> Author: r.david.murray Date: Mon Apr 13 03:22:04 2009 New Revision: 71556 Log: Merged revisions 71553 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71553 | r.david.murray | 2009-04-12 21:06:46 -0400 (Sun, 12 Apr 2009) | 3 lines Adjust test_asyncore to account for intentional asyncore behavior change introduced by r70934 that was causing a test failure when run under -O. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_asyncore.py 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 Mon Apr 13 03:22:04 2009 @@ -273,10 +273,7 @@ sys.stdout = stdout lines = fp.getvalue().splitlines() - if __debug__: - expected = ['EGGS: %s' % l1, 'info: %s' % l2, 'SPAM: %s' % l3] - else: - expected = ['EGGS: %s' % l1, 'SPAM: %s' % l3] + expected = ['EGGS: %s' % l1, 'info: %s' % l2, 'SPAM: %s' % l3] self.assertEquals(lines, expected) From python-checkins at python.org Mon Apr 13 03:27:49 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 13 Apr 2009 03:27:49 +0200 (CEST) Subject: [Python-checkins] r71557 - in python/branches/release30-maint: Lib/test/test_asyncore.py Message-ID: <20090413012749.CA8751E4016@bag.python.org> Author: r.david.murray Date: Mon Apr 13 03:27:49 2009 New Revision: 71557 Log: Merged revisions 71556 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71556 | r.david.murray | 2009-04-12 21:22:04 -0400 (Sun, 12 Apr 2009) | 10 lines Merged revisions 71553 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71553 | r.david.murray | 2009-04-12 21:06:46 -0400 (Sun, 12 Apr 2009) | 3 lines Adjust test_asyncore to account for intentional asyncore behavior change introduced by r70934 that was causing a test failure when run under -O. ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Lib/test/test_asyncore.py Modified: python/branches/release30-maint/Lib/test/test_asyncore.py ============================================================================== --- python/branches/release30-maint/Lib/test/test_asyncore.py (original) +++ python/branches/release30-maint/Lib/test/test_asyncore.py Mon Apr 13 03:27:49 2009 @@ -273,10 +273,7 @@ sys.stdout = stdout lines = fp.getvalue().splitlines() - if __debug__: - expected = ['EGGS: %s' % l1, 'info: %s' % l2, 'SPAM: %s' % l3] - else: - expected = ['EGGS: %s' % l1, 'SPAM: %s' % l3] + expected = ['EGGS: %s' % l1, 'info: %s' % l2, 'SPAM: %s' % l3] self.assertEquals(lines, expected) From buildbot at python.org Mon Apr 13 05:18:11 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 13 Apr 2009 03:18:11 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090413031812.44A6A1E4057@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/575 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_email Traceback (most recent call last): File "./Lib/test/regrtest.py", line 613, in runtest_inner the_package = __import__(abstest, globals(), locals(), []) File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/test/test_email.py", line 5, in from email.test.test_email import suite ImportError: cannot import name suite make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 13 05:51:12 2009 From: python-checkins at python.org (hirokazu.yamamoto) Date: Mon, 13 Apr 2009 05:51:12 +0200 (CEST) Subject: [Python-checkins] r71558 - in python/branches/release26-maint: Doc/library/email.message.rst Message-ID: <20090413035112.2CBD51E4057@bag.python.org> Author: hirokazu.yamamoto Date: Mon Apr 13 05:51:11 2009 New Revision: 71558 Log: Merged revisions 71554-71555 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71554 | hirokazu.yamamoto | 2009-04-13 10:07:06 +0900 | 1 line Fixed typo. (email.Utils => email.utils) ........ r71555 | hirokazu.yamamoto | 2009-04-13 10:21:56 +0900 | 1 line Fixed another typos. (email.Utils => email.utils) ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/email.message.rst Modified: python/branches/release26-maint/Doc/library/email.message.rst ============================================================================== --- python/branches/release26-maint/Doc/library/email.message.rst (original) +++ python/branches/release26-maint/Doc/library/email.message.rst Mon Apr 13 05:51:11 2009 @@ -373,13 +373,13 @@ If your application doesn't care whether the parameter was encoded as in :rfc:`2231`, you can collapse the parameter value by calling - :func:`email.Utils.collapse_rfc2231_value`, passing in the return value + :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 isn't. For example:: rawparam = msg.get_param('foo') - param = email.Utils.collapse_rfc2231_value(rawparam) + param = email.utils.collapse_rfc2231_value(rawparam) In any case, the parameter value (either the returned string, or the ``VALUE`` item in the 3-tuple) is always unquoted, unless *unquote* is set @@ -445,7 +445,7 @@ does not have a ``filename`` parameter, this method falls back to looking for the ``name`` parameter. If neither is found, or the header is missing, then *failobj* is returned. The returned string will always be - unquoted as per :meth:`Utils.unquote`. + unquoted as per :func:`email.utils.unquote`. .. method:: get_boundary([failobj]) @@ -453,7 +453,7 @@ Return the value of the ``boundary`` parameter of the :mailheader:`Content-Type` header of the message, or *failobj* if either the header is missing, or has no ``boundary`` parameter. The returned - string will always be unquoted as per :meth:`Utils.unquote`. + string will always be unquoted as per :func:`email.utils.unquote`. .. method:: set_boundary(boundary) From buildbot at python.org Mon Apr 13 07:07:28 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 13 Apr 2009 05:07:28 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc trunk Message-ID: <20090413050729.352151E4057@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc trunk. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%20trunk/builds/292 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: hirokazu.yamamoto,r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posixpath sincerely, -The Buildbot From buildbot at python.org Mon Apr 13 07:48:01 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 13 Apr 2009 05:48:01 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090413054802.2EBC31E4070@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/523 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_posix test_posixpath ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 249, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 143, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== ERROR: test_realpath_basic (test.test_posixpath.PosixPathTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posixpath.py", line 504, in test_realpath_basic os.symlink(ABSTFN+"1", ABSTFN) OSError: [Errno 17] File exists sincerely, -The Buildbot From buildbot at python.org Mon Apr 13 09:27:08 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 13 Apr 2009 07:27:08 +0000 Subject: [Python-checkins] buildbot failure in x86 XP-4 2.6 Message-ID: <20090413072708.DEC751E4011@bag.python.org> The Buildbot has detected a new failure of x86 XP-4 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20XP-4%202.6/builds/189 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: bolen-windows Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: hirokazu.yamamoto BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_bsddb3 ====================================================================== ERROR: test01_badpointer (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 21, in test01_badpointer dbs = dbshelve.open(self.filename) File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\dbshelve.py", line 106, in open d.open(filename, dbname, filetype, flags, mode) File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\dbshelve.py", line 171, in open self.db.open(*args, **kwargs) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test03_repr_closed_db (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 37, in test03_repr_closed_db db = hashopen(self.filename) File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\__init__.py", line 361, in hashopen d.open(file, db.DB_HASH, flags, mode) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test04_repr_db (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 43, in test04_repr_db db = hashopen(self.filename) File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\__init__.py", line 361, in hashopen d.open(file, db.DB_HASH, flags, mode) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test05_double_free_make_key_dbt (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 65, in test05_double_free_make_key_dbt db.DB_CREATE | db.DB_THREAD) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test06_key_with_null_bytes (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 77, in test06_key_with_null_bytes db1.open(self.filename, None, db.DB_HASH, db.DB_CREATE) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test07_DB_set_flags_persists (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 101, in test07_DB_set_flags_persists db1.open(self.filename, db.DB_HASH, db.DB_CREATE) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') sincerely, -The Buildbot From buildbot at python.org Mon Apr 13 09:43:08 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 13 Apr 2009 07:43:08 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090413074308.8983F1E4011@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/266 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_posix test_subprocess ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From nnorwitz at gmail.com Mon Apr 13 10:11:26 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 13 Apr 2009 04:11:26 -0400 Subject: [Python-checkins] Python Regression Test Failures basics (1) Message-ID: <20090413081126.GA19147@python.psfb.org> 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23366 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 test_lib2to3 failed -- errors occurred; run in verbose mode for details 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 -- OSError raises on RLock creation, see issue 3111! test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18065 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [741906 refs] From nnorwitz at gmail.com Mon Apr 13 10:19:16 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 13 Apr 2009 04:19:16 -0400 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20090413081916.GA21583@python.psfb.org> 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils [17363 refs] [17363 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23366 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 test_lib2to3 failed -- errors occurred; run in verbose mode for details 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 -- OSError raises on RLock creation, see issue 3111! test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18902 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [741146 refs] From python-checkins at python.org Mon Apr 13 12:16:14 2009 From: python-checkins at python.org (kristjan.jonsson) Date: Mon, 13 Apr 2009 12:16:14 +0200 (CEST) Subject: [Python-checkins] r71559 - python/branches/py3k/Modules/posixmodule.c Message-ID: <20090413101614.807821E4018@bag.python.org> Author: kristjan.jonsson Date: Mon Apr 13 12:16:14 2009 New Revision: 71559 Log: Merging r70968 from the trunk, regarding http://bugs.python.org/issue5623 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 Mon Apr 13 12:16:14 2009 @@ -263,6 +263,7 @@ #include #endif #include "osdefs.h" +#include #include #include /* for ShellExecute() */ #endif /* _MSC_VER */ @@ -352,47 +353,15 @@ * (all of this is to avoid globally modifying the CRT behaviour using * _set_invalid_parameter_handler() and _CrtSetReportMode()) */ -#if _MSC_VER >= 1500 /* VS 2008 */ -typedef struct { - intptr_t osfhnd; - char osfile; - char pipech; - int lockinitflag; - CRITICAL_SECTION lock; -#ifndef _SAFECRT_IMPL - char textmode : 7; - char unicode : 1; - char pipech2[2]; - __int64 startpos; - BOOL utf8translations; - char dbcsBuffer; - BOOL dbcsBufferUsed; -#endif /* _SAFECRT_IMPL */ - } ioinfo; -#elif _MSC_VER >= 1400 /* VS 2005 */ +/* The actual size of the structure is determined at runtime. + * Only the first items must be present. + */ typedef struct { intptr_t osfhnd; char osfile; - char pipech; - int lockinitflag; - CRITICAL_SECTION lock; -#ifndef _SAFECRT_IMPL - char textmode : 7; - char unicode : 1; - char pipech2[2]; - __int64 startpos; - BOOL utf8translations; -#ifndef _DEBUG - /* padding hack. 8 byte extra length observed at - * runtime, for 32 and 64 bits when not in _DEBUG - */ - __int32 _padding[2]; -#endif -#endif /* _SAFECRT_IMPL */ - } ioinfo; -#endif +} my_ioinfo; -extern __declspec(dllimport) ioinfo * __pioinfo[]; +extern __declspec(dllimport) char * __pioinfo[]; #define IOINFO_L2E 5 #define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) #define IOINFO_ARRAYS 64 @@ -406,6 +375,19 @@ { const int i1 = fd >> IOINFO_L2E; const int i2 = fd & ((1 << IOINFO_L2E) - 1); + + static int sizeof_ioinfo = 0; + + /* Determine the actual size of the ioinfo structure, + * as used by the CRT loaded in memory + */ + if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) { + sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS; + } + if (sizeof_ioinfo == 0) { + /* This should not happen... */ + goto fail; + } /* See that it isn't a special CLEAR fileno */ if (fd != _NO_CONSOLE_FILENO) { @@ -414,10 +396,13 @@ */ if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) { /* finally, check that the file is open */ - if (__pioinfo[i1][i2].osfile & FOPEN) + my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo); + if (info->osfile & FOPEN) { return 1; + } } } + fail: errno = EBADF; return 0; } From python-checkins at python.org Mon Apr 13 14:34:01 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 13 Apr 2009 14:34:01 +0200 (CEST) Subject: [Python-checkins] r71560 - in python/trunk: Lib/distutils/tests/test_util.py Misc/NEWS Message-ID: <20090413123401.763791E401E@bag.python.org> Author: tarek.ziade Date: Mon Apr 13 14:34:01 2009 New Revision: 71560 Log: Fixed #5607: Distutils test_get_platform was failing fo Mac OS X fat binaries. Modified: python/trunk/Lib/distutils/tests/test_util.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/distutils/tests/test_util.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_util.py (original) +++ python/trunk/Lib/distutils/tests/test_util.py Mon Apr 13 14:34:01 2009 @@ -5,6 +5,7 @@ import os import sys import unittest +from copy import copy from distutils.errors import DistutilsPlatformError @@ -17,6 +18,7 @@ from distutils.util import rfc822_escape from distutils import util # used to patch _environ_checked +from distutils.sysconfig import get_config_vars, _config_vars class utilTestCase(unittest.TestCase): @@ -30,6 +32,7 @@ self.join = os.path.join self.isabs = os.path.isabs self.splitdrive = os.path.splitdrive + self._config_vars = copy(_config_vars) # patching os.uname if hasattr(os, 'uname'): @@ -42,7 +45,7 @@ os.uname = self._get_uname def tearDown(self): - # getting back tne environment + # getting back the environment os.name = self.name sys.platform = self.platform sys.version = self.version @@ -55,6 +58,7 @@ os.uname = self.uname else: del os.uname + _config_vars = copy(self._config_vars) def _set_uname(self, uname): self._uname = uname @@ -96,8 +100,34 @@ 'root:xnu-792.25.20~1/RELEASE_I386'), 'i386')) os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.3' + get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g ' + '-fwrapv -O3 -Wall -Wstrict-prototypes') + self.assertEquals(get_platform(), 'macosx-10.3-i386') + # macbook with fat binaries (fat, universal or fat64) + os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.4' + get_config_vars()['CFLAGS'] = ('-arch ppc -arch i386 -isysroot ' + '/Developer/SDKs/MacOSX10.4u.sdk ' + '-fno-strict-aliasing -fno-common ' + '-dynamic -DNDEBUG -g -O3') + + self.assertEquals(get_platform(), 'macosx-10.4-fat') + + get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch i386 -isysroot ' + '/Developer/SDKs/MacOSX10.4u.sdk ' + '-fno-strict-aliasing -fno-common ' + '-dynamic -DNDEBUG -g -O3') + + self.assertEquals(get_platform(), 'macosx-10.4-universal') + + get_config_vars()['CFLAGS'] = ('-arch x86_64 -isysroot ' + '/Developer/SDKs/MacOSX10.4u.sdk ' + '-fno-strict-aliasing -fno-common ' + '-dynamic -DNDEBUG -g -O3') + + self.assertEquals(get_platform(), 'macosx-10.4-fat64') + # linux debian sarge os.name = 'posix' sys.version = ('2.3.5 (#1, Jul 4 2007, 17:28:59) ' Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Apr 13 14:34:01 2009 @@ -221,6 +221,8 @@ Library ------- +- Issue #5607: fixed Distutils test_get_platform for Mac OS X fat binaries. + - Issue #5741: don't disallow "%%" (which is an escape for "%") when setting a value in SafeConfigParser. From python-checkins at python.org Mon Apr 13 14:35:01 2009 From: python-checkins at python.org (martin.v.loewis) Date: Mon, 13 Apr 2009 14:35:01 +0200 (CEST) Subject: [Python-checkins] r71561 - tracker/instances/python-dev/html/file.index.html Message-ID: <20090413123501.DDE811E401E@bag.python.org> Author: martin.v.loewis Date: Mon Apr 13 14:35:01 2009 New Revision: 71561 Log: Issue 270: Fix typo. Modified: tracker/instances/python-dev/html/file.index.html Modified: tracker/instances/python-dev/html/file.index.html ============================================================================== --- tracker/instances/python-dev/html/file.index.html (original) +++ tracker/instances/python-dev/html/file.index.html Mon Apr 13 14:35:01 2009 @@ -7,7 +7,7 @@ - + From python-checkins at python.org Mon Apr 13 14:35:52 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 13 Apr 2009 14:35:52 +0200 (CEST) Subject: [Python-checkins] r71562 - python/branches/release26-maint Message-ID: <20090413123552.106161E4162@bag.python.org> Author: tarek.ziade Date: Mon Apr 13 14:35:51 2009 New Revision: 71562 Log: Blocked revisions 71560 via svnmerge ........ r71560 | tarek.ziade | 2009-04-13 14:34:01 +0200 (Mon, 13 Apr 2009) | 1 line Fixed #5607: Distutils test_get_platform was failing fo Mac OS X fat binaries. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Apr 13 14:36:19 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 13 Apr 2009 14:36:19 +0200 (CEST) Subject: [Python-checkins] r71563 - python/trunk/Doc/reference/compound_stmts.rst Message-ID: <20090413123619.0E9461E4221@bag.python.org> Author: georg.brandl Date: Mon Apr 13 14:36:18 2009 New Revision: 71563 Log: Simplify markup. Modified: python/trunk/Doc/reference/compound_stmts.rst Modified: python/trunk/Doc/reference/compound_stmts.rst ============================================================================== --- python/trunk/Doc/reference/compound_stmts.rst (original) +++ python/trunk/Doc/reference/compound_stmts.rst Mon Apr 13 14:36:18 2009 @@ -1,4 +1,3 @@ - .. _compound: ******************* @@ -195,12 +194,10 @@ inserts an item in the sequence before the current item, the current item will be treated again the next time through the loop. This can lead to nasty bugs that can be avoided by making a temporary copy using a slice of the whole - sequence, e.g., - -:: + sequence, e.g., :: - for x in a[:]: - if x < 0: a.remove(x) + for x in a[:]: + if x < 0: a.remove(x) .. _try: From python-checkins at python.org Mon Apr 13 14:36:24 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 13 Apr 2009 14:36:24 +0200 (CEST) Subject: [Python-checkins] r71564 - python/trunk/Lib/ConfigParser.py Message-ID: <20090413123624.743BB1E4101@bag.python.org> Author: georg.brandl Date: Mon Apr 13 14:36:24 2009 New Revision: 71564 Log: #5741 followup: should also allow %%(blah)s. Modified: python/trunk/Lib/ConfigParser.py Modified: python/trunk/Lib/ConfigParser.py ============================================================================== --- python/trunk/Lib/ConfigParser.py (original) +++ python/trunk/Lib/ConfigParser.py Mon Apr 13 14:36:24 2009 @@ -665,8 +665,8 @@ raise TypeError("option values must be strings") # check for bad percent signs: # first, replace all "good" interpolations - tmp_value = self._interpvar_re.sub('', value) - tmp_value = tmp_value.replace('%%', '') + tmp_value = value.replace('%%', '') + tmp_value = self._interpvar_re.sub('', tmp_value) # then, check if there's a lone percent sign left percent_index = tmp_value.find('%') if percent_index != -1: From python-checkins at python.org Mon Apr 13 14:37:57 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 13 Apr 2009 14:37:57 +0200 (CEST) Subject: [Python-checkins] r71565 - in python/branches/py3k: Lib/distutils/tests/test_util.py Misc/NEWS Message-ID: <20090413123757.52E781E4045@bag.python.org> Author: tarek.ziade Date: Mon Apr 13 14:37:57 2009 New Revision: 71565 Log: Merged revisions 71560 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71560 | tarek.ziade | 2009-04-13 14:34:01 +0200 (Mon, 13 Apr 2009) | 1 line Fixed #5607: Distutils test_get_platform was failing fo Mac OS X fat binaries. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/tests/test_util.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/distutils/tests/test_util.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_util.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_util.py Mon Apr 13 14:37:57 2009 @@ -5,6 +5,7 @@ import os import sys import unittest +from copy import copy from distutils.errors import DistutilsPlatformError @@ -17,6 +18,7 @@ from distutils.util import rfc822_escape from distutils import util # used to patch _environ_checked +from distutils.sysconfig import get_config_vars, _config_vars class utilTestCase(unittest.TestCase): @@ -30,6 +32,7 @@ self.join = os.path.join self.isabs = os.path.isabs self.splitdrive = os.path.splitdrive + self._config_vars = copy(_config_vars) # patching os.uname if hasattr(os, 'uname'): @@ -42,7 +45,7 @@ os.uname = self._get_uname def tearDown(self): - # getting back tne environment + # getting back the environment os.name = self.name sys.platform = self.platform sys.version = self.version @@ -55,6 +58,7 @@ os.uname = self.uname else: del os.uname + _config_vars = copy(self._config_vars) def _set_uname(self, uname): self._uname = uname @@ -96,8 +100,34 @@ 'root:xnu-792.25.20~1/RELEASE_I386'), 'i386')) os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.3' + get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g ' + '-fwrapv -O3 -Wall -Wstrict-prototypes') + self.assertEquals(get_platform(), 'macosx-10.3-i386') + # macbook with fat binaries (fat, universal or fat64) + os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.4' + get_config_vars()['CFLAGS'] = ('-arch ppc -arch i386 -isysroot ' + '/Developer/SDKs/MacOSX10.4u.sdk ' + '-fno-strict-aliasing -fno-common ' + '-dynamic -DNDEBUG -g -O3') + + self.assertEquals(get_platform(), 'macosx-10.4-fat') + + get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch i386 -isysroot ' + '/Developer/SDKs/MacOSX10.4u.sdk ' + '-fno-strict-aliasing -fno-common ' + '-dynamic -DNDEBUG -g -O3') + + self.assertEquals(get_platform(), 'macosx-10.4-universal') + + get_config_vars()['CFLAGS'] = ('-arch x86_64 -isysroot ' + '/Developer/SDKs/MacOSX10.4u.sdk ' + '-fno-strict-aliasing -fno-common ' + '-dynamic -DNDEBUG -g -O3') + + self.assertEquals(get_platform(), 'macosx-10.4-fat64') + # linux debian sarge os.name = 'posix' sys.version = ('2.3.5 (#1, Jul 4 2007, 17:28:59) ' Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Apr 13 14:37:57 2009 @@ -348,6 +348,8 @@ Library ------- +- Issue #5607: fixed Distutils test_get_platform for Mac OS X fat binaries. + - Issue #5732: added a new command in Distutils: check. - Issue #5731: Distutils bdist_wininst no longer worked on non-Windows From python-checkins at python.org Mon Apr 13 14:37:59 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 13 Apr 2009 14:37:59 +0200 (CEST) Subject: [Python-checkins] r71566 - in python/branches/release26-maint: Lib/ConfigParser.py Message-ID: <20090413123759.D01211E4170@bag.python.org> Author: georg.brandl Date: Mon Apr 13 14:37:59 2009 New Revision: 71566 Log: Merged revisions 71564 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71564 | georg.brandl | 2009-04-13 12:36:24 +0000 (Mo, 13 Apr 2009) | 1 line #5741 followup: should also allow %%(blah)s. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/ConfigParser.py Modified: python/branches/release26-maint/Lib/ConfigParser.py ============================================================================== --- python/branches/release26-maint/Lib/ConfigParser.py (original) +++ python/branches/release26-maint/Lib/ConfigParser.py Mon Apr 13 14:37:59 2009 @@ -659,8 +659,8 @@ raise TypeError("option values must be strings") # check for bad percent signs: # first, replace all "good" interpolations - tmp_value = self._interpvar_re.sub('', value) - tmp_value = tmp_value.replace('%%', '') + tmp_value = value.replace('%%', '') + tmp_value = self._interpvar_re.sub('', tmp_value) # then, check if there's a lone percent sign left percent_index = tmp_value.find('%') if percent_index != -1: From python-checkins at python.org Mon Apr 13 14:39:11 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 13 Apr 2009 14:39:11 +0200 (CEST) Subject: [Python-checkins] r71567 - python/branches/release30-maint Message-ID: <20090413123911.675D31E4045@bag.python.org> Author: tarek.ziade Date: Mon Apr 13 14:39:11 2009 New Revision: 71567 Log: Blocked revisions 71565 via svnmerge ................ r71565 | tarek.ziade | 2009-04-13 14:37:57 +0200 (Mon, 13 Apr 2009) | 9 lines Merged revisions 71560 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71560 | tarek.ziade | 2009-04-13 14:34:01 +0200 (Mon, 13 Apr 2009) | 1 line Fixed #5607: Distutils test_get_platform was failing fo Mac OS X fat binaries. ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Mon Apr 13 14:40:42 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 13 Apr 2009 14:40:42 +0200 (CEST) Subject: [Python-checkins] r71568 - python/branches/py3k Message-ID: <20090413124042.6E7691E4045@bag.python.org> Author: georg.brandl Date: Mon Apr 13 14:40:42 2009 New Revision: 71568 Log: Blocked revisions 70958 via svnmerge (merged manually) ........ r70958 | kristjan.jonsson | 2009-04-01 16:08:34 +0000 (Mi, 01 Apr 2009) | 3 lines http://bugs.python.org/issue5623 Dynamically discoverd the size of the ioinfo struct used by the crt for its file descriptors. This should work across all flavors of the CRT. Thanks to Amaury Forgeot d'Arc Needs porting to 3.1 ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Mon Apr 13 14:41:12 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 13 Apr 2009 14:41:12 +0200 (CEST) Subject: [Python-checkins] r71559 - svn:log Message-ID: <20090413124112.E57461E4045@bag.python.org> Author: georg.brandl Revision: 71559 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -1 +1 @@ -Merging r70968 from the trunk, regarding http://bugs.python.org/issue5623 \ No newline at end of file +Merging r70958 from the trunk, regarding http://bugs.python.org/issue5623 From python-checkins at python.org Mon Apr 13 14:42:26 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 13 Apr 2009 14:42:26 +0200 (CEST) Subject: [Python-checkins] r71569 - python/trunk/Lib/distutils/tests/test_config_cmd.py Message-ID: <20090413124226.585C71E4229@bag.python.org> Author: tarek.ziade Date: Mon Apr 13 14:42:26 2009 New Revision: 71569 Log: deactivate test_search_cpp under win32 Modified: python/trunk/Lib/distutils/tests/test_config_cmd.py Modified: python/trunk/Lib/distutils/tests/test_config_cmd.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_config_cmd.py (original) +++ python/trunk/Lib/distutils/tests/test_config_cmd.py Mon Apr 13 14:42:26 2009 @@ -1,6 +1,7 @@ """Tests for distutils.command.config.""" import unittest import os +import sys from distutils.command.config import dump_file, config from distutils.tests import support @@ -36,6 +37,8 @@ self.assertEquals(len(self._logs), numlines+1) def test_search_cpp(self): + if sys.platform == 'win32': + return pkg_dir, dist = self.create_dist() cmd = config(dist) From python-checkins at python.org Mon Apr 13 14:57:11 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 13 Apr 2009 14:57:11 +0200 (CEST) Subject: [Python-checkins] r71570 - python/branches/release26-maint Message-ID: <20090413125711.022A41E4035@bag.python.org> Author: tarek.ziade Date: Mon Apr 13 14:57:10 2009 New Revision: 71570 Log: Blocked revisions 71569 via svnmerge ........ r71569 | tarek.ziade | 2009-04-13 14:42:26 +0200 (Mon, 13 Apr 2009) | 1 line deactivate test_search_cpp under win32 ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Apr 13 14:59:04 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 13 Apr 2009 14:59:04 +0200 (CEST) Subject: [Python-checkins] r71571 - in python/branches/py3k: Lib/distutils/tests/test_config_cmd.py Message-ID: <20090413125904.0CB091E4035@bag.python.org> Author: tarek.ziade Date: Mon Apr 13 14:59:03 2009 New Revision: 71571 Log: Merged revisions 71569 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71569 | tarek.ziade | 2009-04-13 14:42:26 +0200 (Mon, 13 Apr 2009) | 1 line deactivate test_search_cpp under win32 ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/tests/test_config_cmd.py Modified: python/branches/py3k/Lib/distutils/tests/test_config_cmd.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_config_cmd.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_config_cmd.py Mon Apr 13 14:59:03 2009 @@ -1,6 +1,7 @@ """Tests for distutils.command.config.""" import unittest import os +import sys from distutils.command.config import dump_file, config from distutils.tests import support @@ -36,6 +37,8 @@ self.assertEquals(len(self._logs), numlines+1) def test_search_cpp(self): + if sys.platform == 'win32': + return pkg_dir, dist = self.create_dist() cmd = config(dist) From buildbot at python.org Mon Apr 13 15:00:18 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 13 Apr 2009 13:00:18 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu trunk Message-ID: <20090413130018.66E261E4035@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%20trunk/builds/1134 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: georg.brandl,hirokazu.yamamoto,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_distutils ====================================================================== ERROR: test_build_ext (distutils.tests.test_build_ext.BuildExtTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-ubuntu-i386/build/Lib/distutils/tests/test_build_ext.py", line 64, in test_build_ext cmd.run() File "/home/pybot/buildarea/trunk.klose-ubuntu-i386/build/Lib/distutils/command/build_ext.py", line 353, in run self.build_extensions() File "/home/pybot/buildarea/trunk.klose-ubuntu-i386/build/Lib/distutils/command/build_ext.py", line 480, in build_extensions self.build_extension(ext) File "/home/pybot/buildarea/trunk.klose-ubuntu-i386/build/Lib/distutils/command/build_ext.py", line 550, in build_extension depends=ext.depends) File "/home/pybot/buildarea/trunk.klose-ubuntu-i386/build/Lib/distutils/ccompiler.py", line 695, in compile self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts) File "/home/pybot/buildarea/trunk.klose-ubuntu-i386/build/Lib/distutils/unixccompiler.py", line 180, in _compile raise CompileError, msg CompileError: command 'gcc' failed with exit status 1 make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 13 15:13:26 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 13 Apr 2009 15:13:26 +0200 (CEST) Subject: [Python-checkins] r71572 - in python/trunk/Doc/library: email.charset.rst email.encoders.rst email.errors.rst email.generator.rst email.header.rst email.message.rst email.mime.rst email.parser.rst Message-ID: <20090413131326.13C431E4030@bag.python.org> Author: georg.brandl Date: Mon Apr 13 15:13:25 2009 New Revision: 71572 Log: #5745: more linking for identifiers in email docs. Modified: python/trunk/Doc/library/email.charset.rst python/trunk/Doc/library/email.encoders.rst python/trunk/Doc/library/email.errors.rst python/trunk/Doc/library/email.generator.rst python/trunk/Doc/library/email.header.rst python/trunk/Doc/library/email.message.rst python/trunk/Doc/library/email.mime.rst python/trunk/Doc/library/email.parser.rst Modified: python/trunk/Doc/library/email.charset.rst ============================================================================== --- python/trunk/Doc/library/email.charset.rst (original) +++ python/trunk/Doc/library/email.charset.rst Mon Apr 13 15:13:25 2009 @@ -163,8 +163,8 @@ charset to the output charset automatically. This is not useful for multibyte character sets, which have line length issues (multibyte characters must be split on a character, not a byte boundary); use the - higher-level :class:`Header` class to deal with these issues (see - :mod:`email.header`). *convert* defaults to ``False``. + higher-level :class:`~email.header.Header` class to deal with these issues + (see :mod:`email.header`). *convert* defaults to ``False``. The type of encoding (base64 or quoted-printable) will be based on the *header_encoding* attribute. Modified: python/trunk/Doc/library/email.encoders.rst ============================================================================== --- python/trunk/Doc/library/email.encoders.rst (original) +++ python/trunk/Doc/library/email.encoders.rst Mon Apr 13 15:13:25 2009 @@ -5,18 +5,18 @@ :synopsis: Encoders for email message payloads. -When creating :class:`Message` objects from scratch, you often need to encode -the payloads for transport through compliant mail servers. This is especially -true for :mimetype:`image/\*` and :mimetype:`text/\*` type messages containing -binary data. +When creating :class:`~email.message.Message` objects from scratch, you often +need to encode the payloads for transport through compliant mail servers. This +is especially true for :mimetype:`image/\*` and :mimetype:`text/\*` type messages +containing binary data. The :mod:`email` package provides some convenient encodings in its :mod:`encoders` module. These encoders are actually used by the -:class:`MIMEAudio` and :class:`MIMEImage` class constructors to provide default -encodings. All encoder functions take exactly one argument, the message object -to encode. They usually extract the payload, encode it, and reset the payload -to this newly encoded value. They should also set the -:mailheader:`Content-Transfer-Encoding` header as appropriate. +:class:`~email.mime.audio.MIMEAudio` and :class:`~email.mime.image.MIMEImage` +class constructors to provide default encodings. All encoder functions take +exactly one argument, the message object to encode. They usually extract the +payload, encode it, and reset the payload to this newly encoded value. They +should also set the :mailheader:`Content-Transfer-Encoding` header as appropriate. Here are the encoding functions provided: Modified: python/trunk/Doc/library/email.errors.rst ============================================================================== --- python/trunk/Doc/library/email.errors.rst (original) +++ python/trunk/Doc/library/email.errors.rst Mon Apr 13 15:13:25 2009 @@ -17,8 +17,8 @@ .. exception:: MessageParseError() - This is the base class for exceptions thrown by the :class:`Parser` class. It - is derived from :exc:`MessageError`. + This is the base class for exceptions thrown by the :class:`~email.parser.Parser` + class. It is derived from :exc:`MessageError`. .. exception:: HeaderParseError() @@ -55,11 +55,12 @@ Since :meth:`Message.add_payload` is deprecated, this exception is rarely raised in practice. However the exception may also be raised if the :meth:`attach` method is called on an instance of a class derived from - :class:`MIMENonMultipart` (e.g. :class:`MIMEImage`). + :class:`~email.mime.nonmultipart.MIMENonMultipart` (e.g. + :class:`~email.mime.image.MIMEImage`). -Here's the list of the defects that the :class:`FeedParser` can find while -parsing messages. Note that the defects are added to the message where the -problem was found, so for example, if a message nested inside a +Here's the list of the defects that the :class:`~email.mime.parser.FeedParser` +can find while parsing messages. Note that the defects are added to the message +where the problem was found, so for example, if a message nested inside a :mimetype:`multipart/alternative` had a malformed header, that nested message object would have a defect, but the containing messages would not. Modified: python/trunk/Doc/library/email.generator.rst ============================================================================== --- python/trunk/Doc/library/email.generator.rst (original) +++ python/trunk/Doc/library/email.generator.rst Mon Apr 13 15:13:25 2009 @@ -16,8 +16,8 @@ yourself. However the bundled generator knows how to generate most email in a standards-compliant way, should handle MIME and non-MIME email messages just fine, and is designed so that the transformation from flat text, to a message -structure via the :class:`Parser` class, and back to flat text, is idempotent -(the input is identical to the output). +structure via the :class:`~email.parser.Parser` class, and back to flat text, +is idempotent (the input is identical to the output). Here are the public methods of the :class:`Generator` class, imported from the :mod:`email.generator` module: @@ -41,8 +41,8 @@ Optional *maxheaderlen* specifies the longest length for a non-continued header. When a header line is longer than *maxheaderlen* (in characters, with tabs expanded to 8 spaces), the header will be split as defined in the - :mod:`email.header.Header` class. Set to zero to disable header wrapping. The - default is 78, as recommended (but not required) by :rfc:`2822`. + :class:`~email.header.Header` class. Set to zero to disable header wrapping. + The default is 78, as recommended (but not required) by :rfc:`2822`. The other public :class:`Generator` methods are: Modified: python/trunk/Doc/library/email.header.rst ============================================================================== --- python/trunk/Doc/library/email.header.rst (original) +++ python/trunk/Doc/library/email.header.rst Mon Apr 13 15:13:25 2009 @@ -21,10 +21,10 @@ If you want to include non-ASCII characters in your email headers, say in the :mailheader:`Subject` or :mailheader:`To` fields, you should use the -:class:`Header` class and assign the field in the :class:`Message` object to an -instance of :class:`Header` instead of using a string for the header value. -Import the :class:`Header` class from the :mod:`email.header` module. For -example:: +:class:`Header` class and assign the field in the :class:`~email.message.Message` +object to an instance of :class:`Header` instead of using a string for the header +value. Import the :class:`Header` class from the :mod:`email.header` module. +For example:: >>> from email.message import Message >>> from email.header import Header @@ -39,9 +39,9 @@ Notice here how we wanted the :mailheader:`Subject` field to contain a non-ASCII character? We did this by creating a :class:`Header` instance and passing in the character set that the byte string was encoded in. When the subsequent -:class:`Message` instance was flattened, the :mailheader:`Subject` field was -properly :rfc:`2047` encoded. MIME-aware mail readers would show this header -using the embedded ISO-8859-1 character. +:class:`~email.message.Message` instance was flattened, the :mailheader:`Subject` +field was properly :rfc:`2047` encoded. MIME-aware mail readers would show this +header using the embedded ISO-8859-1 character. .. versionadded:: 2.2.2 @@ -84,10 +84,11 @@ Append the string *s* to the MIME header. - Optional *charset*, if given, should be a :class:`Charset` instance (see - :mod:`email.charset`) or the name of a character set, which will be - converted to a :class:`Charset` instance. A value of ``None`` (the - default) means that the *charset* given in the constructor is used. + Optional *charset*, if given, should be a :class:`~email.charset.Charset` + instance (see :mod:`email.charset`) or the name of a character set, which + will be converted to a :class:`~email.charset.Charset` instance. A value + of ``None`` (the default) means that the *charset* given in the constructor + is used. *s* may be a byte string or a Unicode string. If it is a byte string (i.e. ``isinstance(s, str)`` is true), then *charset* is the encoding of Modified: python/trunk/Doc/library/email.message.rst ============================================================================== --- python/trunk/Doc/library/email.message.rst (original) +++ python/trunk/Doc/library/email.message.rst Mon Apr 13 15:13:25 2009 @@ -45,8 +45,8 @@ Note that this method is provided as a convenience and may not always format the message the way you want. For example, by default it mangles lines that begin with ``From``. For more flexibility, instantiate a - :class:`Generator` instance and use its :meth:`flatten` method directly. - For example:: + :class:`~email.generator.Generator` instance and use its :meth:`flatten` + method directly. For example:: from cStringIO import StringIO from email.generator import Generator @@ -126,11 +126,12 @@ .. method:: set_charset(charset) Set the character set of the payload to *charset*, which can either be a - :class:`Charset` instance (see :mod:`email.charset`), a string naming a - character set, or ``None``. If it is a string, it will be converted to a - :class:`Charset` instance. If *charset* is ``None``, the ``charset`` - parameter will be removed from the :mailheader:`Content-Type` - header. Anything else will generate a :exc:`TypeError`. + :class:`~email.charset.Charset` instance (see :mod:`email.charset`), a + string naming a character set, or ``None``. If it is a string, it will + be converted to a :class:`~email.charset.Charset` instance. If *charset* + is ``None``, the ``charset`` parameter will be removed from the + :mailheader:`Content-Type` header. Anything else will generate a + :exc:`TypeError`. The message will be assumed to be of type :mimetype:`text/\*` encoded with *charset.input_charset*. It will be converted to *charset.output_charset* @@ -144,8 +145,8 @@ .. method:: get_charset() - Return the :class:`Charset` instance associated with the message's - payload. + Return the :class:`~email.charset.Charset` instance associated with the + message's payload. .. versionadded:: 2.2.2 @@ -478,7 +479,7 @@ that header has no ``charset`` parameter, *failobj* is returned. Note that this method differs from :meth:`get_charset` which returns the - :class:`Charset` instance for the default encoding of the message body. + :class:`~email.charset.Charset` instance for the default encoding of the message body. .. versionadded:: 2.2.2 @@ -534,10 +535,11 @@ text can become visible. The *preamble* attribute contains this leading extra-armor text for MIME - documents. When the :class:`Parser` discovers some text after the headers - but before the first boundary string, it assigns this text to the - message's *preamble* attribute. When the :class:`Generator` is writing - out the plain text representation of a MIME message, and it finds the + documents. When the :class:`~email.parser.Parser` discovers some text + after the headers but before the first boundary string, it assigns this + text to the message's *preamble* attribute. When the + :class:`~email.generator.Generator` is writing out the plain text + representation of a MIME message, and it finds the message has a *preamble* attribute, it will write this text in the area between the headers and the first boundary. See :mod:`email.parser` and :mod:`email.generator` for details. Modified: python/trunk/Doc/library/email.mime.rst ============================================================================== --- python/trunk/Doc/library/email.mime.rst (original) +++ python/trunk/Doc/library/email.mime.rst Mon Apr 13 15:13:25 2009 @@ -8,14 +8,15 @@ Ordinarily, you get a message object structure by passing a file or some text to a parser, which parses the text and returns the root message object. However you can also build a complete message structure from scratch, or even individual -:class:`Message` objects by hand. In fact, you can also take an existing -structure and add new :class:`Message` objects, move them around, etc. This -makes a very convenient interface for slicing-and-dicing MIME messages. - -You can create a new object structure by creating :class:`Message` instances, -adding attachments and all the appropriate headers manually. For MIME messages -though, the :mod:`email` package provides some convenient subclasses to make -things easier. +:class:`~email.message.Message` objects by hand. In fact, you can also take an +existing structure and add new :class:`~email.message.Message` objects, move them +around, etc. This makes a very convenient interface for slicing-and-dicing MIME +messages. + +You can create a new object structure by creating :class:`~email.message.Message` +instances, adding attachments and all the appropriate headers manually. For MIME +messages though, the :mod:`email` package provides some convenient subclasses to +make things easier. Here are the classes: @@ -25,10 +26,11 @@ Module: :mod:`email.mime.base` - This is the base class for all the MIME-specific subclasses of :class:`Message`. - Ordinarily you won't create instances specifically of :class:`MIMEBase`, - although you could. :class:`MIMEBase` is provided primarily as a convenient - base class for more specific MIME-aware subclasses. + This is the base class for all the MIME-specific subclasses of + :class:`~email.message.Message`. Ordinarily you won't create instances + specifically of :class:`MIMEBase`, although you could. :class:`MIMEBase` + is provided primarily as a convenient base class for more specific + MIME-aware subclasses. *_maintype* is the :mailheader:`Content-Type` major type (e.g. :mimetype:`text` or :mimetype:`image`), and *_subtype* is the :mailheader:`Content-Type` minor @@ -46,11 +48,11 @@ Module: :mod:`email.mime.nonmultipart` - A subclass of :class:`MIMEBase`, this is an intermediate base class for MIME - messages that are not :mimetype:`multipart`. The primary purpose of this class - is to prevent the use of the :meth:`attach` method, which only makes sense for - :mimetype:`multipart` messages. If :meth:`attach` is called, a - :exc:`MultipartConversionError` exception is raised. + A subclass of :class:`~email.mime.base.MIMEBase`, this is an intermediate base + class for MIME messages that are not :mimetype:`multipart`. The primary + purpose of this class is to prevent the use of the :meth:`attach` method, + which only makes sense for :mimetype:`multipart` messages. If :meth:`attach` + is called, a :exc:`~email.errors.MultipartConversionError` exception is raised. .. versionadded:: 2.2.2 @@ -61,12 +63,12 @@ Module: :mod:`email.mime.multipart` - A subclass of :class:`MIMEBase`, this is an intermediate base class for MIME - messages that are :mimetype:`multipart`. Optional *_subtype* defaults to - :mimetype:`mixed`, but can be used to specify the subtype of the message. A - :mailheader:`Content-Type` header of :mimetype:`multipart/_subtype` will be - added to the message object. A :mailheader:`MIME-Version` header will also be - added. + A subclass of :class:`~email.mime.base.MIMEBase`, this is an intermediate base + class for MIME messages that are :mimetype:`multipart`. Optional *_subtype* + defaults to :mimetype:`mixed`, but can be used to specify the subtype of the + message. A :mailheader:`Content-Type` header of :mimetype:`multipart/_subtype` + will be added to the message object. A :mailheader:`MIME-Version` header will + also be added. Optional *boundary* is the multipart boundary string. When ``None`` (the default), the boundary is calculated when needed. @@ -88,10 +90,11 @@ Module: :mod:`email.mime.application` - A subclass of :class:`MIMENonMultipart`, the :class:`MIMEApplication` class is - used to represent MIME message objects of major type :mimetype:`application`. - *_data* is a string containing the raw byte data. Optional *_subtype* specifies - the MIME subtype and defaults to :mimetype:`octet-stream`. + A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the + :class:`MIMEApplication` class is used to represent MIME message objects of + major type :mimetype:`application`. *_data* is a string containing the raw + byte data. Optional *_subtype* specifies the MIME subtype and defaults to + :mimetype:`octet-stream`. Optional *_encoder* is a callable (i.e. function) which will perform the actual encoding of the data for transport. This callable takes one argument, which is @@ -112,13 +115,14 @@ Module: :mod:`email.mime.audio` - A subclass of :class:`MIMENonMultipart`, the :class:`MIMEAudio` class is used to - create MIME message objects of major type :mimetype:`audio`. *_audiodata* is a - string containing the raw audio data. If this data can be decoded by the - standard Python module :mod:`sndhdr`, then the subtype will be automatically - included in the :mailheader:`Content-Type` header. Otherwise you can explicitly - specify the audio subtype via the *_subtype* parameter. If the minor type could - not be guessed and *_subtype* was not given, then :exc:`TypeError` is raised. + A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the + :class:`MIMEAudio` class is used to create MIME message objects of major type + :mimetype:`audio`. *_audiodata* is a string containing the raw audio data. If + this data can be decoded by the standard Python module :mod:`sndhdr`, then the + subtype will be automatically included in the :mailheader:`Content-Type` header. + Otherwise you can explicitly specify the audio subtype via the *_subtype* + parameter. If the minor type could not be guessed and *_subtype* was not given, + then :exc:`TypeError` is raised. Optional *_encoder* is a callable (i.e. function) which will perform the actual encoding of the audio data for transport. This callable takes one argument, @@ -137,13 +141,14 @@ Module: :mod:`email.mime.image` - A subclass of :class:`MIMENonMultipart`, the :class:`MIMEImage` class is used to - create MIME message objects of major type :mimetype:`image`. *_imagedata* is a - string containing the raw image data. If this data can be decoded by the - standard Python module :mod:`imghdr`, then the subtype will be automatically - included in the :mailheader:`Content-Type` header. Otherwise you can explicitly - specify the image subtype via the *_subtype* parameter. If the minor type could - not be guessed and *_subtype* was not given, then :exc:`TypeError` is raised. + A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the + :class:`MIMEImage` class is used to create MIME message objects of major type + :mimetype:`image`. *_imagedata* is a string containing the raw image data. If + this data can be decoded by the standard Python module :mod:`imghdr`, then the + subtype will be automatically included in the :mailheader:`Content-Type` header. + Otherwise you can explicitly specify the image subtype via the *_subtype* + parameter. If the minor type could not be guessed and *_subtype* was not given, + then :exc:`TypeError` is raised. Optional *_encoder* is a callable (i.e. function) which will perform the actual encoding of the image data for transport. This callable takes one argument, @@ -153,7 +158,8 @@ object as necessary. The default encoding is base64. See the :mod:`email.encoders` module for a list of the built-in encoders. - *_params* are passed straight through to the :class:`MIMEBase` constructor. + *_params* are passed straight through to the :class:`~email.mime.base.MIMEBase` + constructor. .. currentmodule:: email.mime.message @@ -162,10 +168,11 @@ Module: :mod:`email.mime.message` - A subclass of :class:`MIMENonMultipart`, the :class:`MIMEMessage` class is used - to create MIME objects of main type :mimetype:`message`. *_msg* is used as the - payload, and must be an instance of class :class:`Message` (or a subclass - thereof), otherwise a :exc:`TypeError` is raised. + A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the + :class:`MIMEMessage` class is used to create MIME objects of main type + :mimetype:`message`. *_msg* is used as the payload, and must be an instance + of class :class:`~email.message.Message` (or a subclass thereof), otherwise + a :exc:`TypeError` is raised. Optional *_subtype* sets the subtype of the message; it defaults to :mimetype:`rfc822`. @@ -177,12 +184,13 @@ Module: :mod:`email.mime.text` - A subclass of :class:`MIMENonMultipart`, the :class:`MIMEText` class is used to - create MIME objects of major type :mimetype:`text`. *_text* is the string for - the payload. *_subtype* is the minor type and defaults to :mimetype:`plain`. - *_charset* is the character set of the text and is passed as a parameter to the - :class:`MIMENonMultipart` constructor; it defaults to ``us-ascii``. No guessing - or encoding is performed on the text data. + A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the + :class:`MIMEText` class is used to create MIME objects of major type + :mimetype:`text`. *_text* is the string for the payload. *_subtype* is the + minor type and defaults to :mimetype:`plain`. *_charset* is the character + set of the text and is passed as a parameter to the + :class:`~email.mime.nonmultipart.MIMENonMultipart` constructor; it defaults + to ``us-ascii``. No guessing or encoding is performed on the text data. .. versionchanged:: 2.4 The previously deprecated *_encoding* argument has been removed. Encoding Modified: python/trunk/Doc/library/email.parser.rst ============================================================================== --- python/trunk/Doc/library/email.parser.rst (original) +++ python/trunk/Doc/library/email.parser.rst Mon Apr 13 15:13:25 2009 @@ -6,18 +6,18 @@ Message object structures can be created in one of two ways: they can be created -from whole cloth by instantiating :class:`Message` objects and stringing them -together via :meth:`attach` and :meth:`set_payload` calls, or they can be -created by parsing a flat text representation of the email message. +from whole cloth by instantiating :class:`~email.message.Message` objects and +stringing them together via :meth:`attach` and :meth:`set_payload` calls, or they +can be created by parsing a flat text representation of the email message. The :mod:`email` package provides a standard parser that understands most email document structures, including MIME documents. You can pass the parser a string -or a file object, and the parser will return to you the root :class:`Message` -instance of the object structure. For simple, non-MIME messages the payload of -this root object will likely be a string containing the text of the message. -For MIME messages, the root object will return ``True`` from its -:meth:`is_multipart` method, and the subparts can be accessed via the -:meth:`get_payload` and :meth:`walk` methods. +or a file object, and the parser will return to you the root +:class:`~email.message.Message` instance of the object structure. For simple, +non-MIME messages the payload of this root object will likely be a string +containing the text of the message. For MIME messages, the root object will +return ``True`` from its :meth:`is_multipart` method, and the subparts can be +accessed via the :meth:`get_payload` and :meth:`walk` methods. There are actually two parser interfaces available for use, the classic :class:`Parser` API and the incremental :class:`FeedParser` API. The classic @@ -31,8 +31,8 @@ Note that the parser can be extended in limited ways, and of course you can implement your own parser completely from scratch. There is no magical connection between the :mod:`email` package's bundled parser and the -:class:`Message` class, so your custom parser can create message object trees -any way it finds necessary. +:class:`~email.message.Message` class, so your custom parser can create message +object trees any way it finds necessary. FeedParser API @@ -103,8 +103,8 @@ The constructor for the :class:`Parser` class takes an optional argument *_class*. This must be a callable factory (such as a function or a class), and it is used whenever a sub-message object needs to be created. It defaults to - :class:`Message` (see :mod:`email.message`). The factory will be called without - arguments. + :class:`~email.message.Message` (see :mod:`email.message`). The factory will + be called without arguments. The optional *strict* flag is ignored. @@ -199,7 +199,8 @@ * All :mimetype:`multipart` type messages will be parsed as a container message object with a list of sub-message objects for their payload. The outer container message will return ``True`` for :meth:`is_multipart` and their - :meth:`get_payload` method will return the list of :class:`Message` subparts. + :meth:`get_payload` method will return the list of :class:`~email.message.Message` + subparts. * Most messages with a content type of :mimetype:`message/\*` (e.g. :mimetype:`message/delivery-status` and :mimetype:`message/rfc822`) will also be From buildbot at python.org Mon Apr 13 15:22:30 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 13 Apr 2009 13:22:30 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 3.x Message-ID: <20090413132230.78E441E4030@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%203.x/builds/733 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/tests/test_build_ext.py", line 65, in test_build_ext cmd.run() File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/command/build_ext.py", line 347, in run self.build_extensions() File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/command/build_ext.py", line 459, in build_extensions self.build_extension(ext) File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/command/build_ext.py", line 529, in build_extension depends=ext.depends) File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/ccompiler.py", line 649, in compile self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts) File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/unixccompiler.py", line 178, in _compile raise CompileError(msg) distutils.errors.CompileError: command 'gcc' failed with exit status 1 1 test failed: test_distutils ====================================================================== ERROR: test_build_ext (distutils.tests.test_build_ext.BuildExtTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/unixccompiler.py", line 176, in _compile extra_postargs) File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/ccompiler.py", line 982, in spawn spawn(cmd, dry_run=self.dry_run) File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/spawn.py", line 31, in spawn _spawn_posix(cmd, search_path, dry_run=dry_run) File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/spawn.py", line 139, in _spawn_posix % (cmd[0], exit_status)) distutils.errors.DistutilsExecError: command 'gcc' failed with exit status 1 Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/tests/test_build_ext.py", line 65, in test_build_ext cmd.run() File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/command/build_ext.py", line 347, in run self.build_extensions() File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/command/build_ext.py", line 459, in build_extensions self.build_extension(ext) File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/command/build_ext.py", line 529, in build_extension depends=ext.depends) File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/ccompiler.py", line 649, in compile self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts) File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/unixccompiler.py", line 178, in _compile raise CompileError(msg) distutils.errors.CompileError: command 'gcc' failed with exit status 1 Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/tests/test_build_ext.py", line 65, in test_build_ext cmd.run() File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/command/build_ext.py", line 347, in run self.build_extensions() File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/command/build_ext.py", line 459, in build_extensions self.build_extension(ext) File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/command/build_ext.py", line 529, in build_extension depends=ext.depends) File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/ccompiler.py", line 649, in compile self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts) File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/distutils/unixccompiler.py", line 178, in _compile raise CompileError(msg) distutils.errors.CompileError: command 'gcc' failed with exit status 1 make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 13 15:26:20 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 13 Apr 2009 15:26:20 +0200 (CEST) Subject: [Python-checkins] r71573 - in python/branches/py3k-short-float-repr: Lib/test/test_types.py Objects/stringlib/formatter.h Message-ID: <20090413132620.0F6351E4030@bag.python.org> Author: eric.smith Date: Mon Apr 13 15:26:19 2009 New Revision: 71573 Log: Enabled error checking with better messages, added tests. Modified: python/branches/py3k-short-float-repr/Lib/test/test_types.py python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Modified: python/branches/py3k-short-float-repr/Lib/test/test_types.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_types.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_types.py Mon Apr 13 15:26:19 2009 @@ -604,6 +604,20 @@ self.assertRaises(ValueError, format, 0.0, '#') self.assertRaises(ValueError, format, 0.0, '#20f') + def test_format_spec_errors(self): + # int, float, and string all share the same format spec + # mini-language parser. + + # Check that we can't ask for too many digits. This is + # probably a CPython specific test. It tries to put the width + # into a C long. + self.assertRaises(ValueError, format, 0, '1'*10000 + 'd') + + # Similar with the precision. + self.assertRaises(ValueError, format, 0, '.' + '1'*10000 + 'd') + + # And may as well test both. + self.assertRaises(ValueError, format, 0, '1'*1000 + '.' + '1'*10000 + 'd') def test_main(): run_unittest(TypesTests) Modified: python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h (original) +++ python/branches/py3k-short-float-repr/Objects/stringlib/formatter.h Mon Apr 13 15:26:19 2009 @@ -140,7 +140,7 @@ /* end-ptr is used throughout this code to specify the length of the input string */ - Py_ssize_t specified_width; + Py_ssize_t consumed; format->fill_char = '\0'; format->align = '\0'; @@ -185,15 +185,17 @@ ++ptr; } - /* XXX add error checking */ - specified_width = get_integer(&ptr, end, &format->width); + consumed = get_integer(&ptr, end, &format->width); + if (consumed == -1) + /* Overflow error. Exception already set. */ + return 0; - /* If specified_width is 0, we didn't consume any characters for - the width. In that case, reset the width to -1, because - get_integer() will have set it to zero */ - if (specified_width == 0) { + /* If consumed is 0, we didn't consume any characters for the + width. In that case, reset the width to -1, because + get_integer() will have set it to zero. -1 is how we record + that the width wasn't specified. */ + if (consumed == 0) format->width = -1; - } /* Comma signifies add thousands separators */ if (end-ptr && ptr[0] == ',') { @@ -205,11 +207,13 @@ if (end-ptr && ptr[0] == '.') { ++ptr; - /* XXX add error checking */ - specified_width = get_integer(&ptr, end, &format->precision); + consumed = get_integer(&ptr, end, &format->precision); + if (consumed == -1) + /* Overflow error. Exception already set. */ + return 0; /* Not having a precision after a dot is an error. */ - if (specified_width == 0) { + if (consumed == 0) { PyErr_Format(PyExc_ValueError, "Format specifier missing precision"); return 0; From buildbot at python.org Mon Apr 13 15:31:25 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 13 Apr 2009 13:31:25 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 2.6 Message-ID: <20090413133125.ADA501E404D@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%202.6/builds/242 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: georg.brandl,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_tarfile make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 13 15:55:51 2009 From: python-checkins at python.org (martin.v.loewis) Date: Mon, 13 Apr 2009 15:55:51 +0200 (CEST) Subject: [Python-checkins] r71574 - peps/trunk/pep-0382.txt Message-ID: <20090413135551.9D1D71E404D@bag.python.org> Author: martin.v.loewis Date: Mon Apr 13 15:55:51 2009 New Revision: 71574 Log: Fix typo, reported by Tom Wright. Modified: peps/trunk/pep-0382.txt Modified: peps/trunk/pep-0382.txt ============================================================================== --- peps/trunk/pep-0382.txt (original) +++ peps/trunk/pep-0382.txt Mon Apr 13 15:55:51 2009 @@ -43,7 +43,7 @@ from pkgutil import extend_path __path__ = extend_path(__path__, __name__) -int the package's ``__init__.py``. Every distribution needs to provide +in the package's ``__init__.py``. Every distribution needs to provide the same contents in its ``__init__.py``, so that extend_path is invoked independent of which portion of the package gets imported first. As a consequence, the package's ``__init__.py`` cannot From buildbot at python.org Mon Apr 13 16:51:03 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 13 Apr 2009 14:51:03 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090413145104.0BFFF1E4030@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/577 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_codecmaps_tw test_epoll make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 13 17:05:52 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 13 Apr 2009 17:05:52 +0200 (CEST) Subject: [Python-checkins] r71575 - python/branches/py3k-short-float-repr/Lib/test/test_types.py Message-ID: <20090413150552.161211E4298@bag.python.org> Author: eric.smith Date: Mon Apr 13 17:05:51 2009 New Revision: 71575 Log: Another test for an existing error checks. Modified: python/branches/py3k-short-float-repr/Lib/test/test_types.py Modified: python/branches/py3k-short-float-repr/Lib/test/test_types.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_types.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_types.py Mon Apr 13 17:05:51 2009 @@ -619,6 +619,10 @@ # And may as well test both. self.assertRaises(ValueError, format, 0, '1'*1000 + '.' + '1'*10000 + 'd') + # Make sure commas aren't allowed with various type codes + for code in 'xXobns': + self.assertRaises(ValueError, format, 0, ',' + code) + def test_main(): run_unittest(TypesTests) From buildbot at python.org Mon Apr 13 17:06:32 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 13 Apr 2009 15:06:32 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 3.x Message-ID: <20090413150632.A9C7A1E41B0@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%203.x/builds/619 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/tests/test_build_ext.py", line 65, in test_build_ext cmd.run() File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/command/build_ext.py", line 347, in run self.build_extensions() File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/command/build_ext.py", line 459, in build_extensions self.build_extension(ext) File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/command/build_ext.py", line 529, in build_extension depends=ext.depends) File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/ccompiler.py", line 649, in compile self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts) File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/unixccompiler.py", line 178, in _compile raise CompileError(msg) distutils.errors.CompileError: command 'gcc' failed with exit status 1 1 test failed: test_distutils ====================================================================== ERROR: test_build_ext (distutils.tests.test_build_ext.BuildExtTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/unixccompiler.py", line 176, in _compile extra_postargs) File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/ccompiler.py", line 982, in spawn spawn(cmd, dry_run=self.dry_run) File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/spawn.py", line 31, in spawn _spawn_posix(cmd, search_path, dry_run=dry_run) File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/spawn.py", line 139, in _spawn_posix % (cmd[0], exit_status)) distutils.errors.DistutilsExecError: command 'gcc' failed with exit status 1 Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/tests/test_build_ext.py", line 65, in test_build_ext cmd.run() File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/command/build_ext.py", line 347, in run self.build_extensions() File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/command/build_ext.py", line 459, in build_extensions self.build_extension(ext) File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/command/build_ext.py", line 529, in build_extension depends=ext.depends) File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/ccompiler.py", line 649, in compile self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts) File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/unixccompiler.py", line 178, in _compile raise CompileError(msg) distutils.errors.CompileError: command 'gcc' failed with exit status 1 Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/tests/test_build_ext.py", line 65, in test_build_ext cmd.run() File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/command/build_ext.py", line 347, in run self.build_extensions() File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/command/build_ext.py", line 459, in build_extensions self.build_extension(ext) File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/command/build_ext.py", line 529, in build_extension depends=ext.depends) File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/ccompiler.py", line 649, in compile self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts) File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/distutils/unixccompiler.py", line 178, in _compile raise CompileError(msg) distutils.errors.CompileError: command 'gcc' failed with exit status 1 make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Mon Apr 13 17:47:18 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 13 Apr 2009 15:47:18 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 2.6 Message-ID: <20090413154718.849271E4064@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%202.6/builds/254 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From buildbot at python.org Mon Apr 13 17:49:03 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 13 Apr 2009 15:49:03 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 2.6 Message-ID: <20090413154903.704461E4064@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%202.6/builds/216 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: georg.brandl,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 6 tests failed: test_gzip test_marshal test_pipes test_subprocess test_urllib2 test_wait3 4 tests failed: test_mailbox test_pipes test_subprocess test_wait3 3 tests failed: test_pipes test_subprocess test_wait3 3 tests failed: test_pipes test_subprocess test_wait3 3 tests failed: test_pipes test_subprocess test_wait3 3 tests failed: test_pipes test_subprocess test_wait3 3 tests failed: test_pipes test_subprocess test_wait3 3 tests failed: test_pipes test_subprocess test_wait3 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 13 18:08:49 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 13 Apr 2009 18:08:49 +0200 (CEST) Subject: [Python-checkins] r71576 - in python/branches/py3k-short-float-repr: configure configure.in pyconfig.h.in Message-ID: <20090413160849.633C31E404D@bag.python.org> Author: mark.dickinson Date: Mon Apr 13 18:08:48 2009 New Revision: 71576 Log: Some configure script fixes: - on gcc/x86, if SSE2 instruction set doesn't appear to be available then check that we can use inline assembler to get and set the x87 control word - the double rounding check should use BASECFLAGS, since that might affect the result - don't cache result of double rounding check - move all the floating-point stuff into one place in configure.in Modified: python/branches/py3k-short-float-repr/configure python/branches/py3k-short-float-repr/configure.in python/branches/py3k-short-float-repr/pyconfig.h.in Modified: python/branches/py3k-short-float-repr/configure ============================================================================== --- python/branches/py3k-short-float-repr/configure (original) +++ python/branches/py3k-short-float-repr/configure Mon Apr 13 18:08:48 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 71287 . +# From configure.in Revision: 71321 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.1. # @@ -4588,76 +4588,6 @@ BASECFLAGS="$BASECFLAGS -fno-strict-aliasing" fi - # On x86/x86-64, use the SSE2 instruction set when available. - { echo "$as_me:$LINENO: checking whether $CC accepts -msse2 -mfpmath=sse" >&5 -echo $ECHO_N "checking whether $CC accepts -msse2 -mfpmath=sse... $ECHO_C" >&6; } - ac_save_cc="$CC" - CC="$CC -msse2 -mfpmath=sse" - if test "$cross_compiling" = yes; then - ac_cv_msse2_ok=no -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -int main() { return 0; } -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_msse2_ok=yes -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_msse2_ok=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - - CC="$ac_save_cc" - { echo "$as_me:$LINENO: result: $ac_cv_msse2_ok" >&5 -echo "${ECHO_T}$ac_cv_msse2_ok" >&6; } - { echo "$as_me:$LINENO: checking whether SSE2 instructions are already enabled for math" >&5 -echo $ECHO_N "checking whether SSE2 instructions are already enabled for math... $ECHO_C" >&6; } - if [ "`$CC -dM -E - &5 -echo "${ECHO_T}$ac_sse2_enabled" >&6; } - if test $ac_sse2_enabled = no - then - if test $ac_cv_msse2_ok = yes - then - BASECFLAGS="$BASECFLAGS -msse2 -mfpmath=sse" - fi - fi - # if using gcc on alpha, use -mieee to get (near) full IEEE 754 # support. Without this, treatment of subnormals doesn't follow # the standard. @@ -21673,12 +21603,9 @@ fi -# ************************************ -# * Check for mathematical functions * -# ************************************ - -LIBS_SAVE=$LIBS -LIBS="$LIBS $LIBM" +# ************************************************** +# * Check for various properties of floating point * +# ************************************************** { echo "$as_me:$LINENO: checking whether C doubles are little-endian IEEE 754 binary64" >&5 echo $ECHO_N "checking whether C doubles are little-endian IEEE 754 binary64... $ECHO_C" >&6; } @@ -21696,7 +21623,6 @@ cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -#include #include int main() { double x = 9006104071832581.0; @@ -21769,7 +21695,6 @@ cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -#include #include int main() { double x = 9006104071832581.0; @@ -21826,6 +21751,157 @@ fi +# David Gay's code in Python/dtoa.c requires that the FPU uses 53-bit +# rounding; this is a particular problem on x86, where the x87 FPU has +# a default rounding precision of 64 bits. For gcc/x86, we try to fix +# this by: +# +# (1) using the SSE2 instruction set when available (it usually is +# on modern machines) +# (2) using inline assembler to get and set the x87 FPU control word +# otherwise. + +if test "$GCC" = yes && test -n "`$CC -dM -E - &5 +echo $ECHO_N "checking whether SSE2 instructions are already enabled for math... $ECHO_C" >&6; } + if [ "`$CC -dM -E - &5 +echo "${ECHO_T}$ac_sse2_enabled" >&6; } + + # if not, try using gcc options to enable it + if test $ac_sse2_enabled = no + then + { echo "$as_me:$LINENO: checking whether $CC accepts -msse2 -mfpmath=sse" >&5 +echo $ECHO_N "checking whether $CC accepts -msse2 -mfpmath=sse... $ECHO_C" >&6; } + ac_save_cc="$CC" + CC="$CC -msse2 -mfpmath=sse" + if test "$cross_compiling" = yes; then + ac_cv_msse2_ok=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +int main() { return 0; } +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_msse2_ok=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_msse2_ok=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + CC="$ac_save_cc" + { echo "$as_me:$LINENO: result: $ac_cv_msse2_ok" >&5 +echo "${ECHO_T}$ac_cv_msse2_ok" >&6; } + + if test $ac_cv_msse2_ok = yes + then + BASECFLAGS="$BASECFLAGS -msse2 -mfpmath=sse" + else + +cat >>confdefs.h <<\_ACEOF +#define USING_X87_FPU 1 +_ACEOF + + # SSE2 doesn't appear to be available. Check that it's okay + # to use gcc inline assembler to get and set x87 control word + { echo "$as_me:$LINENO: checking whether we can use gcc inline assembler to get and set x87 control word" >&5 +echo $ECHO_N "checking whether we can use gcc inline assembler to get and set x87 control word... $ECHO_C" >&6; } + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + unsigned short cw; + __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); + __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + have_gcc_asm_for_x87=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + have_gcc_asm_for_x87=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { echo "$as_me:$LINENO: result: $have_gcc_asm_for_x87" >&5 +echo "${ECHO_T}$have_gcc_asm_for_x87" >&6; } + if test "$have_gcc_asm_for_x87" = yes + then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_GCC_ASM_FOR_X87 1 +_ACEOF + + fi + fi + fi +fi + # Detect whether system arithmetic is subject to x87-style double # rounding issues. The result of this test has little meaning on non # IEEE 754 platforms. On IEEE 754, test should return 1 if rounding @@ -21833,10 +21909,9 @@ # 0 otherwise. See http://bugs.python.org/issue2937 for more info. { echo "$as_me:$LINENO: checking for x87-style double rounding" >&5 echo $ECHO_N "checking for x87-style double rounding... $ECHO_C" >&6; } -if test "${ac_cv_x87_double_rounding+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - +# $BASECFLAGS may affect the result +ac_save_cc="$CC" +CC="$CC $BASECFLAGS" if test "$cross_compiling" = yes; then ac_cv_x87_double_rounding=no else @@ -21900,8 +21975,7 @@ fi -fi - +CC="$ac_save_cc" { echo "$as_me:$LINENO: result: $ac_cv_x87_double_rounding" >&5 echo "${ECHO_T}$ac_cv_x87_double_rounding" >&6; } if test "$ac_cv_x87_double_rounding" = yes @@ -21913,6 +21987,13 @@ fi +# ************************************ +# * Check for mathematical functions * +# ************************************ + +LIBS_SAVE=$LIBS +LIBS="$LIBS $LIBM" + # Multiprocessing check for broken sem_getvalue { echo "$as_me:$LINENO: checking for broken sem_getvalue" >&5 echo $ECHO_N "checking for broken sem_getvalue... $ECHO_C" >&6; } Modified: python/branches/py3k-short-float-repr/configure.in ============================================================================== --- python/branches/py3k-short-float-repr/configure.in (original) +++ python/branches/py3k-short-float-repr/configure.in Mon Apr 13 18:08:48 2009 @@ -858,32 +858,6 @@ BASECFLAGS="$BASECFLAGS -fno-strict-aliasing" fi - # On x86/x86-64, use the SSE2 instruction set when available. - AC_MSG_CHECKING(whether $CC accepts -msse2 -mfpmath=sse) - ac_save_cc="$CC" - CC="$CC -msse2 -mfpmath=sse" - AC_TRY_RUN([int main() { return 0; }], - ac_cv_msse2_ok=yes, - ac_cv_msse2_ok=no, - ac_cv_msse2_ok=no) - CC="$ac_save_cc" - AC_MSG_RESULT($ac_cv_msse2_ok) - AC_MSG_CHECKING(whether SSE2 instructions are already enabled for math) - if [[ "`$CC -dM -E - #include int main() { double x = 9006104071832581.0; @@ -3125,7 +3095,6 @@ AC_MSG_CHECKING(whether C doubles are big-endian IEEE 754 binary64) AC_CACHE_VAL(ac_cv_big_endian_double, [ AC_TRY_RUN([ -#include #include int main() { double x = 9006104071832581.0; @@ -3146,13 +3115,76 @@ with the most significant byte first]) fi +# David Gay's code in Python/dtoa.c requires that the FPU uses 53-bit +# rounding; this is a particular problem on x86, where the x87 FPU has +# a default rounding precision of 64 bits. For gcc/x86, we try to fix +# this by: +# +# (1) using the SSE2 instruction set when available (it usually is +# on modern machines) +# (2) using inline assembler to get and set the x87 FPU control word +# otherwise. + +if test "$GCC" = yes && test -n "`$CC -dM -E - #include @@ -3175,7 +3207,8 @@ ], ac_cv_x87_double_rounding=no, ac_cv_x87_double_rounding=yes, -ac_cv_x87_double_rounding=no)]) +ac_cv_x87_double_rounding=no) +CC="$ac_save_cc" AC_MSG_RESULT($ac_cv_x87_double_rounding) if test "$ac_cv_x87_double_rounding" = yes then @@ -3183,6 +3216,13 @@ [Define if arithmetic is subject to x87-style double rounding issue]) fi +# ************************************ +# * Check for mathematical functions * +# ************************************ + +LIBS_SAVE=$LIBS +LIBS="$LIBS $LIBM" + # Multiprocessing check for broken sem_getvalue AC_MSG_CHECKING(for broken sem_getvalue) AC_TRY_RUN([ Modified: python/branches/py3k-short-float-repr/pyconfig.h.in ============================================================================== --- python/branches/py3k-short-float-repr/pyconfig.h.in (original) +++ python/branches/py3k-short-float-repr/pyconfig.h.in Mon Apr 13 18:08:48 2009 @@ -240,6 +240,10 @@ /* Define to 1 if you have the `gai_strerror' function. */ #undef HAVE_GAI_STRERROR +/* Define if we can use gcc inline assembler to get and set x87 control word + */ +#undef HAVE_GCC_ASM_FOR_X87 + /* Define if you have the getaddrinfo function. */ #undef HAVE_GETADDRINFO @@ -978,6 +982,10 @@ /* Define if you want to use computed gotos in ceval.c. */ #undef USE_COMPUTED_GOTOS +/* Define on x86 hardware if the x87 FPU is being used for floating-point + arithmetic */ +#undef USING_X87_FPU + /* Define if a va_list is an array of some kind */ #undef VA_LIST_IS_ARRAY From python-checkins at python.org Mon Apr 13 18:25:29 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 13 Apr 2009 18:25:29 +0200 (CEST) Subject: [Python-checkins] r71577 - in python/branches/py3k-short-float-repr: Include/pymath.h Python/pymath.c Message-ID: <20090413162529.EB5821E4064@bag.python.org> Author: mark.dickinson Date: Mon Apr 13 18:25:29 2009 New Revision: 71577 Log: Add functions to get and set the x87 FPU control word, where applicable Modified: python/branches/py3k-short-float-repr/Include/pymath.h python/branches/py3k-short-float-repr/Python/pymath.c Modified: python/branches/py3k-short-float-repr/Include/pymath.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/pymath.h (original) +++ python/branches/py3k-short-float-repr/Include/pymath.h Mon Apr 13 18:25:29 2009 @@ -92,6 +92,11 @@ # endif #endif +#ifdef HAVE_GCC_ASM_FOR_X87 +PyAPI_FUNC(unsigned short) _Py_get_387controlword(void); +PyAPI_FUNC(void) _Py_set_387controlword(unsigned short); +#endif + /* Py_IS_NAN(X) * Return 1 if float or double arg is a NaN, else 0. * Caution: Modified: python/branches/py3k-short-float-repr/Python/pymath.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pymath.c (original) +++ python/branches/py3k-short-float-repr/Python/pymath.c Mon Apr 13 18:25:29 2009 @@ -13,6 +13,28 @@ } #endif +#ifdef USING_X87_FPU +# ifdef HAVE_GCC_ASM_FOR_X87 + +/* inline assembly for getting and setting the 387 FPU control word on + gcc/x86 */ + +unsigned short _Py_get_387controlword(void) { + unsigned short cw; + __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); + return cw; +} + +void _Py_set_387controlword(unsigned short cw) { + __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); +} + +# else +# error "Unable to get and set x87 control word" +# endif +#endif + + #ifndef HAVE_HYPOT double hypot(double x, double y) { From python-checkins at python.org Mon Apr 13 18:30:56 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 13 Apr 2009 18:30:56 +0200 (CEST) Subject: [Python-checkins] r71578 - in python/branches/py3k-short-float-repr: Doc/c-api/buffer.rst Doc/c-api/init.rst Doc/distutils/apiref.rst Doc/distutils/examples.rst Doc/distutils/setupscript.rst Doc/library/asyncore.rst Doc/library/codeop.rst Doc/library/collections.rst Doc/library/compileall.rst Doc/library/configparser.rst Doc/library/constants.rst Doc/library/copyreg.rst Doc/library/csv.rst Doc/library/curses.rst Doc/library/datetime.rst Doc/library/dbm.rst Doc/library/decimal.rst Doc/library/difflib.rst Doc/library/dis.rst Doc/library/doctest.rst Doc/library/io.rst Doc/library/itertools.rst Doc/library/json.rst Doc/library/multiprocessing.rst Doc/library/stdtypes.rst Doc/library/string.rst Doc/library/sys.rst Doc/library/test.rst Doc/library/threading.rst Doc/library/tkinter.ttk.rst Doc/library/unittest.rst Doc/make.bat Doc/reference/expressions.rst Doc/tools/sphinxext/static/basic.css Doc/tools/sphinxext/susp-ignored.csv Doc/whatsnew/2.7.rst Doc/whatsnew/3.1.rst Include/bytes_methods.h Include/object.h Lib/asyncore.py Lib/cgitb.py Lib/collections.py Lib/distutils/command/__init__.py Lib/distutils/command/bdist_wininst.py Lib/distutils/command/check.py Lib/distutils/command/config.py Lib/distutils/tests/test_bdist_wininst.py Lib/distutils/tests/test_check.py Lib/distutils/tests/test_config_cmd.py Lib/distutils/tests/test_spawn.py Lib/distutils/tests/test_util.py Lib/http/server.py Lib/multiprocessing/managers.py Lib/multiprocessing/pool.py Lib/plistlib.py Lib/posixpath.py Lib/pydoc.py Lib/socket.py Lib/string.py Lib/telnetlib.py Lib/test/support.py Lib/test/test_asyncore.py Lib/test/test_bigmem.py Lib/test/test_bytes.py Lib/test/test_heapq.py Lib/test/test_httpservers.py Lib/test/test_minidom.py Lib/test/test_mmap.py Lib/test/test_multiprocessing.py Lib/test/test_os.py Lib/test/test_posixpath.py Lib/test/test_string.py Lib/test/test_sys.py Lib/test/test_telnetlib.py Lib/test/test_unittest.py Lib/test/test_warnings.py Lib/unittest.py Lib/xml/dom/minidom.py Lib/xmlrpc/server.py Makefile.pre.in Misc Misc/NEWS Misc/README Misc/build.sh Misc/gdbinit Misc/python-wing.wpr Modules/_io/bufferedio.c Modules/_tkinter.c Modules/mmapmodule.c Modules/posixmodule.c Modules/readline.c Modules/tkinter.h Objects/bytearrayobject.c Objects/bytes_methods.c Objects/bytesobject.c Objects/unicodeobject.c Parser/asdl.py Python/atof.c Python/errors.c Python/getargs.c Python/mysnprintf.c Python/strtod.c Tools/msi/msilib.py setup.py Message-ID: <20090413163056.CAF181E42FE@bag.python.org> Author: mark.dickinson Date: Mon Apr 13 18:30:54 2009 New Revision: 71578 Log: Merged revisions 71354-71357,71368,71372,71374,71376,71378-71379,71383-71384,71386-71388,71390-71391,71393-71394,71399-71404,71415-71416,71420-71421,71431,71434,71436-71437,71442,71444-71446,71451,71454,71457,71469,71471,71475,71480,71483,71491,71493,71495-71497,71500-71502,71505-71506,71511,71515,71518,71520-71521,71525,71530,71535,71541,71556,71559,71565,71568,71571 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71354 | mark.dickinson | 2009-04-07 12:53:52 +0100 (Tue, 07 Apr 2009) | 4 lines Revert removal of atof.c and strtod.c in r71341. We're not quite ready for this yet---this removal should happen as part of the py3k-short-float-repr merge. ................ r71355 | matthias.klose | 2009-04-07 14:13:10 +0100 (Tue, 07 Apr 2009) | 10 lines Merged revisions 71268 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71268 | matthias.klose | 2009-04-05 23:00:48 +0200 (So, 05 Apr 2009) | 3 lines - Issue #2703: SimpleXMLRPCDispatcher.__init__: Provide default values for new arguments introduced in 2.5. ........ ................ r71356 | matthias.klose | 2009-04-07 14:24:27 +0100 (Tue, 07 Apr 2009) | 15 lines Merged revisions 71229,71271 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71229 | matthias.klose | 2009-04-05 14:43:08 +0200 (So, 05 Apr 2009) | 3 lines - Py_DECREF: Add `do { ... } while (0)' to avoid compiler warnings. (avoiding brown paper typo this time) ........ r71271 | matthias.klose | 2009-04-05 23:19:13 +0200 (So, 05 Apr 2009) | 3 lines Issue #1113244: Py_XINCREF, Py_DECREF, Py_XDECREF: Add `do { ... } while (0)' to avoid compiler warnings. ........ ................ r71357 | matthias.klose | 2009-04-07 14:49:45 +0100 (Tue, 07 Apr 2009) | 3 lines - Issue #5359: Readd the Berkley-DB detection code to allow _dbm be built using Berkley-DB. ................ r71368 | matthias.klose | 2009-04-07 17:08:29 +0100 (Tue, 07 Apr 2009) | 4 lines Don't check for broken Berkley-DB versions on some platforms; the test was required for the _bsddb3 extension, not necessary for the _dbm extension. ................ r71372 | benjamin.peterson | 2009-04-07 20:27:32 +0100 (Tue, 07 Apr 2009) | 1 line don't install extras like pydoc and idle in altinstall, possibly overwriting the 2.x ones #1590 ................ r71374 | benjamin.peterson | 2009-04-07 20:34:08 +0100 (Tue, 07 Apr 2009) | 9 lines Merged revisions 71335 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71335 | benjamin.peterson | 2009-04-06 17:53:29 -0500 (Mon, 06 Apr 2009) | 1 line see if this helps the doc builds ........ ................ r71376 | benjamin.peterson | 2009-04-07 20:43:57 +0100 (Tue, 07 Apr 2009) | 1 line install as python3 #5461 ................ r71378 | raymond.hettinger | 2009-04-07 22:19:16 +0100 (Tue, 07 Apr 2009) | 1 line Fix make.bat to match makefile changes ................ r71379 | georg.brandl | 2009-04-07 22:27:29 +0100 (Tue, 07 Apr 2009) | 1 line Revert 3k change to msilib, which is executed with Python 2.x. ................ r71383 | eric.smith | 2009-04-07 23:55:31 +0100 (Tue, 07 Apr 2009) | 1 line Removed unused #include. ................ r71384 | raymond.hettinger | 2009-04-08 00:10:59 +0100 (Wed, 08 Apr 2009) | 1 line Add link. ................ r71386 | raymond.hettinger | 2009-04-08 01:09:26 +0100 (Wed, 08 Apr 2009) | 1 line Fix-up attribution per IRC discussion with GPolo. ................ r71387 | raymond.hettinger | 2009-04-08 02:15:02 +0100 (Wed, 08 Apr 2009) | 1 line Add docstrings. ................ r71388 | raymond.hettinger | 2009-04-08 02:16:27 +0100 (Wed, 08 Apr 2009) | 1 line Typo. ................ r71390 | raymond.hettinger | 2009-04-08 08:49:03 +0100 (Wed, 08 Apr 2009) | 1 line Add example for auto-renaming. ................ r71391 | raymond.hettinger | 2009-04-08 09:23:44 +0100 (Wed, 08 Apr 2009) | 1 line Perform minor copy edits ................ r71393 | raymond.hettinger | 2009-04-08 09:28:28 +0100 (Wed, 08 Apr 2009) | 1 line Minor factoring. ................ r71394 | raymond.hettinger | 2009-04-08 10:38:32 +0100 (Wed, 08 Apr 2009) | 1 line Remove bits that pertained to earlier releases. ................ r71399 | benjamin.peterson | 2009-04-08 22:35:52 +0100 (Wed, 08 Apr 2009) | 1 line fix installing of extension modules ................ r71400 | benjamin.peterson | 2009-04-08 22:40:01 +0100 (Wed, 08 Apr 2009) | 1 line don't install scripts which will overwrite 2.x ones #1590 ................ r71401 | benjamin.peterson | 2009-04-08 22:41:45 +0100 (Wed, 08 Apr 2009) | 1 line fix building ................ r71402 | raymond.hettinger | 2009-04-08 23:50:09 +0100 (Wed, 08 Apr 2009) | 1 line Clean-up an example. ................ r71403 | raymond.hettinger | 2009-04-09 01:08:24 +0100 (Thu, 09 Apr 2009) | 1 line Update whatsnew based on doc search. ................ r71404 | raymond.hettinger | 2009-04-09 01:18:29 +0100 (Thu, 09 Apr 2009) | 1 line Fix markup ................ r71415 | tarek.ziade | 2009-04-09 23:02:39 +0100 (Thu, 09 Apr 2009) | 9 lines Merged revisions 71413 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71413 | tarek.ziade | 2009-04-09 23:36:44 +0200 (Thu, 09 Apr 2009) | 1 line Fixed #5731: Distutils bdist_wininst no longer worked on non-Windows platforms ........ ................ r71416 | r.david.murray | 2009-04-09 23:16:43 +0100 (Thu, 09 Apr 2009) | 10 lines Merged revisions 71414 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71414 | r.david.murray | 2009-04-09 17:54:50 -0400 (Thu, 09 Apr 2009) | 3 lines Issue #2170: refactored xml.dom.minidom.normalize, increasing both its clarity and its speed. ........ ................ r71420 | raymond.hettinger | 2009-04-09 23:34:23 +0100 (Thu, 09 Apr 2009) | 1 line Add note on using keyword arguments with OrderedDict. ................ r71421 | raymond.hettinger | 2009-04-09 23:34:46 +0100 (Thu, 09 Apr 2009) | 1 line Fix link ................ r71431 | raymond.hettinger | 2009-04-10 05:27:37 +0100 (Fri, 10 Apr 2009) | 1 line Clarify the table entries for combinatorics. ................ r71434 | jack.diederich | 2009-04-10 06:33:26 +0100 (Fri, 10 Apr 2009) | 23 lines -fixes telnetlib constants to be one-length byte arrays instead of ints -this fixes telnet negotiation (broken in 3.0) -merged/ported telnetlib tests from trunk (below) Merged revisions 71302,71377,71385 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71302 | jack.diederich | 2009-04-05 22:08:44 -0400 (Sun, 05 Apr 2009) | 1 line test the telnetlib.Telnet interface more thoroughly ........ r71377 | jack.diederich | 2009-04-07 16:22:59 -0400 (Tue, 07 Apr 2009) | 1 line eliminate more race conditions in telnetlib tests ........ r71385 | jack.diederich | 2009-04-07 19:56:57 -0400 (Tue, 07 Apr 2009) | 4 lines - Make timing assertions very generous (a la test_timeout.py) - Break the gc cycle in negotiation tests - test the different guarantees of read_lazy and read_very_lazy ........ ................ r71436 | georg.brandl | 2009-04-10 08:01:52 +0100 (Fri, 10 Apr 2009) | 9 lines Merged revisions 71409 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71409 | georg.brandl | 2009-04-09 21:01:04 +0200 (Do, 09 Apr 2009) | 1 line Add a custom stylesheet with better table formatting. ........ ................ r71437 | georg.brandl | 2009-04-10 08:02:56 +0100 (Fri, 10 Apr 2009) | 21 lines Merged revisions 71424-71425,71428-71429 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71424 | raymond.hettinger | 2009-04-10 01:25:30 +0200 (Fr, 10 Apr 2009) | 1 line More table formatting. ........ r71425 | raymond.hettinger | 2009-04-10 01:34:14 +0200 (Fr, 10 Apr 2009) | 1 line Center table headings. ........ r71428 | raymond.hettinger | 2009-04-10 02:49:41 +0200 (Fr, 10 Apr 2009) | 1 line More table clean-up ........ r71429 | raymond.hettinger | 2009-04-10 04:01:21 +0200 (Fr, 10 Apr 2009) | 1 line IE needs the border-left:0 for some reason. ........ ................ r71442 | georg.brandl | 2009-04-10 09:17:21 +0100 (Fri, 10 Apr 2009) | 9 lines Merged revisions 71441 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71441 | georg.brandl | 2009-04-10 10:16:47 +0200 (Fr, 10 Apr 2009) | 1 line Let "lambda" point to the correct heading. ........ ................ r71444 | georg.brandl | 2009-04-10 09:28:28 +0100 (Fri, 10 Apr 2009) | 9 lines Merged revisions 71443 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71443 | georg.brandl | 2009-04-10 10:20:23 +0200 (Fr, 10 Apr 2009) | 1 line #5698: Fix casing of !DOCTYPE to conform to W3C specs. ........ ................ r71445 | georg.brandl | 2009-04-10 09:31:48 +0100 (Fri, 10 Apr 2009) | 1 line #5698, part 2: generate a meta info in pydoc HTML pages indicating the encoding, and fix the -w option to use the correct encoding. ................ r71446 | georg.brandl | 2009-04-10 10:03:43 +0100 (Fri, 10 Apr 2009) | 1 line Update signature style for optional arguments, part 3. ................ r71451 | raymond.hettinger | 2009-04-10 20:02:36 +0100 (Fri, 10 Apr 2009) | 1 line Add examples. ................ r71454 | raymond.hettinger | 2009-04-10 20:43:50 +0100 (Fri, 10 Apr 2009) | 1 line Fix alignment ................ r71457 | guilherme.polo | 2009-04-10 23:19:09 +0100 (Fri, 10 Apr 2009) | 9 lines Merged revisions 71210 via svnmerge from svn+ssh://pythondev/python/trunk ........ r71210 | guilherme.polo | 2009-04-04 23:11:19 -0300 (Sat, 04 Apr 2009) | 1 line Include tkinter.h only after including tk.h (or the equivalent for another platform). ........ ................ r71469 | nick.coghlan | 2009-04-11 15:30:59 +0100 (Sat, 11 Apr 2009) | 9 lines Merged revisions 71465 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71465 | nick.coghlan | 2009-04-11 23:31:31 +1000 (Sat, 11 Apr 2009) | 1 line Issue 5354: Provide a standardised testing mechanism for doing fresh imports of modules, including the ability to block extension modules in order to test the pure Python fallbacks ........ ................ r71471 | tarek.ziade | 2009-04-11 15:32:37 +0100 (Sat, 11 Apr 2009) | 9 lines Merged revisions 71467 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71467 | tarek.ziade | 2009-04-11 15:59:05 +0200 (Sat, 11 Apr 2009) | 1 line fixed link ........ ................ r71475 | tarek.ziade | 2009-04-11 16:00:43 +0100 (Sat, 11 Apr 2009) | 9 lines Merged revisions 71473 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71473 | tarek.ziade | 2009-04-11 16:55:07 +0200 (Sat, 11 Apr 2009) | 1 line #5732: added the check command into Distutils ........ ................ r71480 | tarek.ziade | 2009-04-11 16:17:04 +0100 (Sat, 11 Apr 2009) | 9 lines Merged revisions 71478 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71478 | tarek.ziade | 2009-04-11 17:14:17 +0200 (Sat, 11 Apr 2009) | 1 line testing a full check case ........ ................ r71483 | antoine.pitrou | 2009-04-11 16:39:24 +0100 (Sat, 11 Apr 2009) | 4 lines #5502: accelerate binary buffered IO (especially small operations). On a suggestion by Victor Stinner. ................ r71491 | georg.brandl | 2009-04-11 19:18:16 +0100 (Sat, 11 Apr 2009) | 1 line Remove mentions of "long". ................ r71493 | benjamin.peterson | 2009-04-11 20:16:27 +0100 (Sat, 11 Apr 2009) | 96 lines Blocked revisions 70807,70986,70993-70994,71127,71300,71302,71361,71365,71367,71370,71377,71380,71385,71389,71392,71419,71430,71435,71448,71462,71490 via svnmerge ........ r70807 | jeremy.hylton | 2009-03-31 08:31:00 -0500 (Tue, 31 Mar 2009) | 2 lines Update quicktest to match Python 3 branch ........ r70986 | raymond.hettinger | 2009-04-01 15:50:58 -0500 (Wed, 01 Apr 2009) | 1 line Add link to an alternative generator with a long-period. ........ r70993 | georg.brandl | 2009-04-01 16:05:44 -0500 (Wed, 01 Apr 2009) | 1 line Add NEWS item. ........ r70994 | georg.brandl | 2009-04-01 16:06:30 -0500 (Wed, 01 Apr 2009) | 1 line Revert accidental checkin. ........ r71127 | raymond.hettinger | 2009-04-04 03:46:58 -0500 (Sat, 04 Apr 2009) | 1 line Replace the localized min/max calls with normal if/else ........ r71300 | gregory.p.smith | 2009-04-05 18:48:26 -0500 (Sun, 05 Apr 2009) | 2 lines news entry for r71299. ........ r71302 | jack.diederich | 2009-04-05 21:08:44 -0500 (Sun, 05 Apr 2009) | 1 line test the telnetlib.Telnet interface more thoroughly ........ r71361 | benjamin.peterson | 2009-04-07 10:15:04 -0500 (Tue, 07 Apr 2009) | 1 line fix syntax tests after formatting change ........ r71365 | benjamin.peterson | 2009-04-07 10:52:05 -0500 (Tue, 07 Apr 2009) | 1 line fix since difference formating of SyntaxErrors ........ r71367 | benjamin.peterson | 2009-04-07 11:03:04 -0500 (Tue, 07 Apr 2009) | 1 line revert unrelated change to test_telnetlib ........ r71370 | vinay.sajip | 2009-04-07 12:18:24 -0500 (Tue, 07 Apr 2009) | 1 line Issue #5695: Minor tweak to improve the code as suggested by Brett Cannon and as implemented in the Py3K branch. ........ r71377 | jack.diederich | 2009-04-07 15:22:59 -0500 (Tue, 07 Apr 2009) | 1 line eliminate more race conditions in telnetlib tests ........ r71380 | raymond.hettinger | 2009-04-07 16:43:51 -0500 (Tue, 07 Apr 2009) | 1 line Fix make.bat to match makefile changes ........ r71385 | jack.diederich | 2009-04-07 18:56:57 -0500 (Tue, 07 Apr 2009) | 4 lines - Make timing assertions very generous (a la test_timeout.py) - Break the gc cycle in negotiation tests - test the different guarantees of read_lazy and read_very_lazy ........ r71389 | raymond.hettinger | 2009-04-08 00:39:38 -0500 (Wed, 08 Apr 2009) | 1 line Add docstrings. ........ r71392 | raymond.hettinger | 2009-04-08 03:26:55 -0500 (Wed, 08 Apr 2009) | 1 line Minor factoring. ........ r71419 | raymond.hettinger | 2009-04-09 17:31:51 -0500 (Thu, 09 Apr 2009) | 1 line Add note on using keyword arguments with OrderedDict. ........ r71430 | raymond.hettinger | 2009-04-09 23:25:45 -0500 (Thu, 09 Apr 2009) | 1 line Clarify the table entries for combinatorics. ........ r71435 | raymond.hettinger | 2009-04-10 01:38:39 -0500 (Fri, 10 Apr 2009) | 1 line Fix the count of datatypes. ........ r71448 | raymond.hettinger | 2009-04-10 08:16:50 -0500 (Fri, 10 Apr 2009) | 1 line Add examples. ........ r71462 | chris.withers | 2009-04-11 06:22:19 -0500 (Sat, 11 Apr 2009) | 2 lines remove unpleasant exec ........ r71490 | r.david.murray | 2009-04-11 12:52:56 -0500 (Sat, 11 Apr 2009) | 4 lines Make test_asyncore tests match code changes introduced by the fix to Issue1161031, refactoring the test to simplify it in the process. ........ ................ r71495 | benjamin.peterson | 2009-04-11 20:48:14 +0100 (Sat, 11 Apr 2009) | 67 lines Merged revisions 70980,71059,71225,71234,71241,71243,71249,71251,71255,71266,71299,71329,71397-71398,71486 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70980 | jack.diederich | 2009-04-01 15:26:13 -0500 (Wed, 01 Apr 2009) | 3 lines bounds check arguments to mmap.move(). All of them. Really. fixes crasher on OS X 10.5 ........ r71059 | mark.dickinson | 2009-04-02 13:39:37 -0500 (Thu, 02 Apr 2009) | 2 lines sys.long_info attributes should be ints, not longs ........ r71225 | georg.brandl | 2009-04-05 06:54:07 -0500 (Sun, 05 Apr 2009) | 1 line #5580: no need to use parentheses when converterr() argument is actually a type description. ........ r71234 | georg.brandl | 2009-04-05 08:16:35 -0500 (Sun, 05 Apr 2009) | 1 line Whitespace normalization. ........ r71241 | georg.brandl | 2009-04-05 09:48:49 -0500 (Sun, 05 Apr 2009) | 1 line #5471: fix expanduser() for $HOME set to "/". ........ r71243 | georg.brandl | 2009-04-05 10:14:29 -0500 (Sun, 05 Apr 2009) | 1 line #5432: make plistlib docstring a raw string, since it contains examples with backslash escapes. ........ r71249 | georg.brandl | 2009-04-05 11:30:43 -0500 (Sun, 05 Apr 2009) | 1 line #5444: adapt make.bat to new htmlhelp output file name. ........ r71251 | georg.brandl | 2009-04-05 12:17:42 -0500 (Sun, 05 Apr 2009) | 1 line #5298: clarify docs about GIL by using more consistent wording. ........ r71255 | georg.brandl | 2009-04-05 13:34:58 -0500 (Sun, 05 Apr 2009) | 1 line #602893: add indicator for current line in cgitb that doesnt rely on styling alone. ........ r71266 | georg.brandl | 2009-04-05 15:23:13 -0500 (Sun, 05 Apr 2009) | 1 line Normalize issue referencing style. ........ r71299 | gregory.p.smith | 2009-04-05 18:43:58 -0500 (Sun, 05 Apr 2009) | 3 lines Fixes issue5705: os.setuid() and friends did not accept the same range of values that pwd.getpwnam() returns. ........ r71329 | benjamin.peterson | 2009-04-06 16:53:33 -0500 (Mon, 06 Apr 2009) | 1 line add create_connection to __all__ #5711 ........ r71397 | georg.brandl | 2009-04-08 11:36:39 -0500 (Wed, 08 Apr 2009) | 1 line Remove redundant backtick. ........ r71398 | georg.brandl | 2009-04-08 11:39:04 -0500 (Wed, 08 Apr 2009) | 1 line Update ignore file for suspicious builder. ........ r71486 | andrew.kuchling | 2009-04-11 11:18:14 -0500 (Sat, 11 Apr 2009) | 1 line Re-word ........ ................ r71496 | benjamin.peterson | 2009-04-11 21:12:10 +0100 (Sat, 11 Apr 2009) | 10 lines Merged revisions 71303 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71303 | gregory.p.smith | 2009-04-06 01:33:26 -0500 (Mon, 06 Apr 2009) | 3 lines - Issue #2254: Fix CGIHTTPServer information disclosure. Relative paths are now collapsed within the url properly before looking in cgi_directories. ........ ................ r71497 | benjamin.peterson | 2009-04-11 21:14:54 +0100 (Sat, 11 Apr 2009) | 28 lines Blocked revisions 70757,70981,71029,71031,71082 via svnmerge ........ r70757 | senthil.kumaran | 2009-03-30 16:51:50 -0500 (Mon, 30 Mar 2009) | 3 lines Fix for bugs: Issue4675 and Issue4962. ........ r70981 | senthil.kumaran | 2009-04-01 15:26:33 -0500 (Wed, 01 Apr 2009) | 3 lines Fix for issue5040. Adding test for Content-Length ........ r71029 | senthil.kumaran | 2009-04-01 22:00:34 -0500 (Wed, 01 Apr 2009) | 3 lines Fixing the issue4860. Escaping embedded '"' character in js_output() method of Morsel. ........ r71031 | brett.cannon | 2009-04-01 22:17:39 -0500 (Wed, 01 Apr 2009) | 6 lines PyImport_AppendInittab() took a char * as a first argument even though that string was stored beyond the life of the call. Changed the signature to be const char * to help make this point. Closes issue #1419652. ........ r71082 | hirokazu.yamamoto | 2009-04-02 22:54:08 -0500 (Thu, 02 Apr 2009) | 1 line Fixed compile error on windows. ........ ................ r71500 | benjamin.peterson | 2009-04-11 21:45:40 +0100 (Sat, 11 Apr 2009) | 70 lines Merged revisions 70912,70944,70968,71033,71041,71208,71263,71286,71395-71396,71405-71406,71485,71492,71494 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70912 | georg.brandl | 2009-03-31 17:35:46 -0500 (Tue, 31 Mar 2009) | 1 line #5617: add a handy function to print a unicode string to gdbinit. ........ r70944 | georg.brandl | 2009-03-31 23:32:39 -0500 (Tue, 31 Mar 2009) | 1 line #5631: add upload to list of possible commands, which is presented in --help-commands. ........ r70968 | michael.foord | 2009-04-01 13:25:38 -0500 (Wed, 01 Apr 2009) | 1 line Adding Wing project file ........ r71033 | brett.cannon | 2009-04-01 22:34:53 -0500 (Wed, 01 Apr 2009) | 3 lines Fix two issues introduced by issue #71031 by changing the signature of PyImport_AppendInittab() to take a const char *. ........ r71041 | jesse.noller | 2009-04-02 00:17:26 -0500 (Thu, 02 Apr 2009) | 1 line Add custom initializer argument to multiprocess.Manager*, courtesy of lekma ........ r71208 | michael.foord | 2009-04-04 20:15:01 -0500 (Sat, 04 Apr 2009) | 4 lines Change the way unittest.TestSuite use their tests to always access them through iteration. Non behavior changing, this allows you to create custom subclasses that override __iter__. Issue #5693 ........ r71263 | michael.foord | 2009-04-05 14:19:28 -0500 (Sun, 05 Apr 2009) | 4 lines Adding assertIs and assertIsNot methods to unittest.TestCase Issue #2578 ........ r71286 | tarek.ziade | 2009-04-05 17:04:38 -0500 (Sun, 05 Apr 2009) | 1 line added a simplest test to distutils.spawn._nt_quote_args ........ r71395 | benjamin.peterson | 2009-04-08 08:27:29 -0500 (Wed, 08 Apr 2009) | 1 line these must be installed to correctly run tests ........ r71396 | benjamin.peterson | 2009-04-08 08:29:41 -0500 (Wed, 08 Apr 2009) | 1 line fix syntax ........ r71405 | andrew.kuchling | 2009-04-09 06:22:47 -0500 (Thu, 09 Apr 2009) | 1 line Add items ........ r71406 | andrew.kuchling | 2009-04-09 06:23:36 -0500 (Thu, 09 Apr 2009) | 1 line Typo fixes ........ r71485 | andrew.kuchling | 2009-04-11 11:12:23 -0500 (Sat, 11 Apr 2009) | 1 line Add various items ........ r71492 | georg.brandl | 2009-04-11 13:19:27 -0500 (Sat, 11 Apr 2009) | 1 line Take credit for a patch of mine. ........ r71494 | benjamin.peterson | 2009-04-11 14:31:00 -0500 (Sat, 11 Apr 2009) | 1 line ignore py3_test_grammar when compiling the library ........ ................ r71501 | benjamin.peterson | 2009-04-11 21:58:12 +0100 (Sat, 11 Apr 2009) | 9 lines Merged revisions 71498 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71498 | benjamin.peterson | 2009-04-11 15:27:15 -0500 (Sat, 11 Apr 2009) | 1 line fix markup ........ ................ r71502 | georg.brandl | 2009-04-11 22:24:37 +0100 (Sat, 11 Apr 2009) | 16 lines Merged revisions 71024,71058 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71024 | georg.brandl | 2009-04-02 04:47:44 +0200 (Do, 02 Apr 2009) | 4 lines In PyErr_GivenExceptionMatches, temporarily bump the recursion limit, so that in the most common case PyObject_IsSubclass will not raise a recursion error we have to ignore anyway. ........ r71058 | georg.brandl | 2009-04-02 20:09:04 +0200 (Do, 02 Apr 2009) | 3 lines PyErr_NormalizeException may not set an error, so convert the PyErr_SetObject call on hitting the recursion limit into just assigning it to the arguments provided. ........ ................ r71505 | georg.brandl | 2009-04-12 12:34:13 +0100 (Sun, 12 Apr 2009) | 1 line #2725: Fix missing local, and handle errors without tracebacks. ................ r71506 | georg.brandl | 2009-04-12 13:01:50 +0100 (Sun, 12 Apr 2009) | 1 line #5708: a bit of streamlining in unicode_repeat(). ................ r71511 | tarek.ziade | 2009-04-12 15:57:46 +0100 (Sun, 12 Apr 2009) | 9 lines Merged revisions 71509 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71509 | tarek.ziade | 2009-04-12 16:53:51 +0200 (Sun, 12 Apr 2009) | 1 line removed the print statements and added a test ........ ................ r71515 | tarek.ziade | 2009-04-12 16:07:31 +0100 (Sun, 12 Apr 2009) | 9 lines Merged revisions 71513 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71513 | tarek.ziade | 2009-04-12 17:03:50 +0200 (Sun, 12 Apr 2009) | 1 line pep8-fied the module before adding tests ........ ................ r71518 | r.david.murray | 2009-04-12 16:21:36 +0100 (Sun, 12 Apr 2009) | 2 lines Unblock most recent asyncore commits in preparation for py3k integration. ................ r71520 | r.david.murray | 2009-04-12 16:35:44 +0100 (Sun, 12 Apr 2009) | 24 lines Merged revisions 70873,70904,70934,71490 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70873 | josiah.carlson | 2009-03-31 15:32:34 -0400 (Tue, 31 Mar 2009) | 2 lines This resolves issue 1161031. Tests pass. ........ r70904 | josiah.carlson | 2009-03-31 17:49:36 -0400 (Tue, 31 Mar 2009) | 3 lines Made handle_expt_event() be called last, so that we don't accidentally read after closing the socket. ........ r70934 | josiah.carlson | 2009-03-31 21:28:11 -0400 (Tue, 31 Mar 2009) | 2 lines Fix for failing asyncore tests. ........ r71490 | r.david.murray | 2009-04-11 13:52:56 -0400 (Sat, 11 Apr 2009) | 4 lines Make test_asyncore tests match code changes introduced by the fix to Issue1161031, refactoring the test to simplify it in the process. ........ ................ r71521 | georg.brandl | 2009-04-12 16:51:51 +0100 (Sun, 12 Apr 2009) | 4 lines Add bytes/bytearray.maketrans() to mirror str.maketrans(), and deprecate string.maketrans() which actually works on bytes. (Also closes #5675.) ................ r71525 | tarek.ziade | 2009-04-12 17:34:34 +0100 (Sun, 12 Apr 2009) | 9 lines Merged revisions 71523 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71523 | tarek.ziade | 2009-04-12 18:31:24 +0200 (Sun, 12 Apr 2009) | 1 line added a simple test for search_cpp ........ ................ r71530 | tarek.ziade | 2009-04-12 17:49:20 +0100 (Sun, 12 Apr 2009) | 9 lines Merged revisions 71528 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71528 | tarek.ziade | 2009-04-12 18:45:32 +0200 (Sun, 12 Apr 2009) | 1 line added a test for finalize_options ........ ................ r71535 | tarek.ziade | 2009-04-12 18:04:39 +0100 (Sun, 12 Apr 2009) | 9 lines Merged revisions 71533 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71533 | tarek.ziade | 2009-04-12 19:02:08 +0200 (Sun, 12 Apr 2009) | 1 line removed string usage and added a test for _clean ........ ................ r71541 | benjamin.peterson | 2009-04-12 21:32:11 +0100 (Sun, 12 Apr 2009) | 9 lines Merged revisions 71539 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71539 | benjamin.peterson | 2009-04-12 15:24:56 -0500 (Sun, 12 Apr 2009) | 1 line remove useless import ........ ................ r71556 | r.david.murray | 2009-04-13 02:22:04 +0100 (Mon, 13 Apr 2009) | 10 lines Merged revisions 71553 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71553 | r.david.murray | 2009-04-12 21:06:46 -0400 (Sun, 12 Apr 2009) | 3 lines Adjust test_asyncore to account for intentional asyncore behavior change introduced by r70934 that was causing a test failure when run under -O. ........ ................ r71559 | kristjan.jonsson | 2009-04-13 11:16:14 +0100 (Mon, 13 Apr 2009) | 2 lines Merging r70958 from the trunk, regarding http://bugs.python.org/issue5623 ................ r71565 | tarek.ziade | 2009-04-13 13:37:57 +0100 (Mon, 13 Apr 2009) | 9 lines Merged revisions 71560 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71560 | tarek.ziade | 2009-04-13 14:34:01 +0200 (Mon, 13 Apr 2009) | 1 line Fixed #5607: Distutils test_get_platform was failing fo Mac OS X fat binaries. ........ ................ r71568 | georg.brandl | 2009-04-13 13:40:42 +0100 (Mon, 13 Apr 2009) | 10 lines Blocked revisions 70958 via svnmerge (merged manually) ........ r70958 | kristjan.jonsson | 2009-04-01 16:08:34 +0000 (Mi, 01 Apr 2009) | 3 lines http://bugs.python.org/issue5623 Dynamically discoverd the size of the ioinfo struct used by the crt for its file descriptors. This should work across all flavors of the CRT. Thanks to Amaury Forgeot d'Arc Needs porting to 3.1 ........ ................ r71571 | tarek.ziade | 2009-04-13 13:59:03 +0100 (Mon, 13 Apr 2009) | 9 lines Merged revisions 71569 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71569 | tarek.ziade | 2009-04-13 14:42:26 +0200 (Mon, 13 Apr 2009) | 1 line deactivate test_search_cpp under win32 ........ ................ Added: python/branches/py3k-short-float-repr/Doc/tools/sphinxext/static/basic.css - copied unchanged from r71541, /python/branches/py3k/Doc/tools/sphinxext/static/basic.css python/branches/py3k-short-float-repr/Lib/distutils/command/check.py - copied unchanged from r71541, /python/branches/py3k/Lib/distutils/command/check.py python/branches/py3k-short-float-repr/Lib/distutils/tests/test_bdist_wininst.py - copied unchanged from r71541, /python/branches/py3k/Lib/distutils/tests/test_bdist_wininst.py python/branches/py3k-short-float-repr/Lib/distutils/tests/test_check.py - copied unchanged from r71541, /python/branches/py3k/Lib/distutils/tests/test_check.py python/branches/py3k-short-float-repr/Lib/distutils/tests/test_config_cmd.py - copied, changed from r71541, /python/branches/py3k/Lib/distutils/tests/test_config_cmd.py python/branches/py3k-short-float-repr/Lib/distutils/tests/test_spawn.py - copied unchanged from r71541, /python/branches/py3k/Lib/distutils/tests/test_spawn.py python/branches/py3k-short-float-repr/Misc/python-wing.wpr - copied unchanged from r71541, /python/branches/py3k/Misc/python-wing.wpr python/branches/py3k-short-float-repr/Python/atof.c - copied unchanged from r71541, /python/branches/py3k/Python/atof.c python/branches/py3k-short-float-repr/Python/strtod.c - copied unchanged from r71541, /python/branches/py3k/Python/strtod.c Modified: python/branches/py3k-short-float-repr/ (props changed) python/branches/py3k-short-float-repr/Doc/c-api/buffer.rst python/branches/py3k-short-float-repr/Doc/c-api/init.rst python/branches/py3k-short-float-repr/Doc/distutils/apiref.rst python/branches/py3k-short-float-repr/Doc/distutils/examples.rst python/branches/py3k-short-float-repr/Doc/distutils/setupscript.rst python/branches/py3k-short-float-repr/Doc/library/asyncore.rst python/branches/py3k-short-float-repr/Doc/library/codeop.rst python/branches/py3k-short-float-repr/Doc/library/collections.rst python/branches/py3k-short-float-repr/Doc/library/compileall.rst python/branches/py3k-short-float-repr/Doc/library/configparser.rst python/branches/py3k-short-float-repr/Doc/library/constants.rst python/branches/py3k-short-float-repr/Doc/library/copyreg.rst python/branches/py3k-short-float-repr/Doc/library/csv.rst python/branches/py3k-short-float-repr/Doc/library/curses.rst python/branches/py3k-short-float-repr/Doc/library/datetime.rst python/branches/py3k-short-float-repr/Doc/library/dbm.rst python/branches/py3k-short-float-repr/Doc/library/decimal.rst python/branches/py3k-short-float-repr/Doc/library/difflib.rst python/branches/py3k-short-float-repr/Doc/library/dis.rst python/branches/py3k-short-float-repr/Doc/library/doctest.rst python/branches/py3k-short-float-repr/Doc/library/io.rst python/branches/py3k-short-float-repr/Doc/library/itertools.rst python/branches/py3k-short-float-repr/Doc/library/json.rst python/branches/py3k-short-float-repr/Doc/library/multiprocessing.rst python/branches/py3k-short-float-repr/Doc/library/stdtypes.rst python/branches/py3k-short-float-repr/Doc/library/string.rst python/branches/py3k-short-float-repr/Doc/library/sys.rst python/branches/py3k-short-float-repr/Doc/library/test.rst python/branches/py3k-short-float-repr/Doc/library/threading.rst python/branches/py3k-short-float-repr/Doc/library/tkinter.ttk.rst python/branches/py3k-short-float-repr/Doc/library/unittest.rst python/branches/py3k-short-float-repr/Doc/make.bat python/branches/py3k-short-float-repr/Doc/reference/expressions.rst python/branches/py3k-short-float-repr/Doc/tools/sphinxext/susp-ignored.csv python/branches/py3k-short-float-repr/Doc/whatsnew/2.7.rst python/branches/py3k-short-float-repr/Doc/whatsnew/3.1.rst python/branches/py3k-short-float-repr/Include/bytes_methods.h python/branches/py3k-short-float-repr/Include/object.h python/branches/py3k-short-float-repr/Lib/asyncore.py python/branches/py3k-short-float-repr/Lib/cgitb.py python/branches/py3k-short-float-repr/Lib/collections.py python/branches/py3k-short-float-repr/Lib/distutils/command/__init__.py python/branches/py3k-short-float-repr/Lib/distutils/command/bdist_wininst.py python/branches/py3k-short-float-repr/Lib/distutils/command/config.py python/branches/py3k-short-float-repr/Lib/distutils/tests/test_util.py python/branches/py3k-short-float-repr/Lib/http/server.py python/branches/py3k-short-float-repr/Lib/multiprocessing/managers.py python/branches/py3k-short-float-repr/Lib/multiprocessing/pool.py python/branches/py3k-short-float-repr/Lib/plistlib.py python/branches/py3k-short-float-repr/Lib/posixpath.py python/branches/py3k-short-float-repr/Lib/pydoc.py python/branches/py3k-short-float-repr/Lib/socket.py python/branches/py3k-short-float-repr/Lib/string.py python/branches/py3k-short-float-repr/Lib/telnetlib.py python/branches/py3k-short-float-repr/Lib/test/support.py python/branches/py3k-short-float-repr/Lib/test/test_asyncore.py python/branches/py3k-short-float-repr/Lib/test/test_bigmem.py python/branches/py3k-short-float-repr/Lib/test/test_bytes.py python/branches/py3k-short-float-repr/Lib/test/test_heapq.py python/branches/py3k-short-float-repr/Lib/test/test_httpservers.py python/branches/py3k-short-float-repr/Lib/test/test_minidom.py python/branches/py3k-short-float-repr/Lib/test/test_mmap.py python/branches/py3k-short-float-repr/Lib/test/test_multiprocessing.py python/branches/py3k-short-float-repr/Lib/test/test_os.py python/branches/py3k-short-float-repr/Lib/test/test_posixpath.py python/branches/py3k-short-float-repr/Lib/test/test_string.py python/branches/py3k-short-float-repr/Lib/test/test_sys.py python/branches/py3k-short-float-repr/Lib/test/test_telnetlib.py python/branches/py3k-short-float-repr/Lib/test/test_unittest.py python/branches/py3k-short-float-repr/Lib/test/test_warnings.py python/branches/py3k-short-float-repr/Lib/unittest.py python/branches/py3k-short-float-repr/Lib/xml/dom/minidom.py python/branches/py3k-short-float-repr/Lib/xmlrpc/server.py python/branches/py3k-short-float-repr/Makefile.pre.in python/branches/py3k-short-float-repr/Misc/ (props changed) python/branches/py3k-short-float-repr/Misc/NEWS python/branches/py3k-short-float-repr/Misc/README python/branches/py3k-short-float-repr/Misc/build.sh python/branches/py3k-short-float-repr/Misc/gdbinit python/branches/py3k-short-float-repr/Modules/_io/bufferedio.c python/branches/py3k-short-float-repr/Modules/_tkinter.c python/branches/py3k-short-float-repr/Modules/mmapmodule.c python/branches/py3k-short-float-repr/Modules/posixmodule.c python/branches/py3k-short-float-repr/Modules/readline.c python/branches/py3k-short-float-repr/Modules/tkinter.h python/branches/py3k-short-float-repr/Objects/bytearrayobject.c python/branches/py3k-short-float-repr/Objects/bytes_methods.c python/branches/py3k-short-float-repr/Objects/bytesobject.c python/branches/py3k-short-float-repr/Objects/unicodeobject.c python/branches/py3k-short-float-repr/Parser/asdl.py python/branches/py3k-short-float-repr/Python/errors.c python/branches/py3k-short-float-repr/Python/getargs.c python/branches/py3k-short-float-repr/Python/mysnprintf.c python/branches/py3k-short-float-repr/Tools/msi/msilib.py python/branches/py3k-short-float-repr/setup.py Modified: python/branches/py3k-short-float-repr/Doc/c-api/buffer.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/c-api/buffer.rst (original) +++ python/branches/py3k-short-float-repr/Doc/c-api/buffer.rst Mon Apr 13 18:30:54 2009 @@ -239,7 +239,7 @@ | :cmacro:`PyBUF_FULL` | This is equivalent to ``(PyBUF_INDIRECT | | | | PyBUF_FORMAT | PyBUF_WRITABLE)``. | +------------------------------+---------------------------------------------------+ - | :cmacro:`PyBUF_FULL_RO`` | This is equivalent to ``(PyBUF_INDIRECT | | + | :cmacro:`PyBUF_FULL_RO` | This is equivalent to ``(PyBUF_INDIRECT | | | | PyBUF_FORMAT)``. | +------------------------------+---------------------------------------------------+ | :cmacro:`PyBUF_CONTIG` | This is equivalent to ``(PyBUF_ND | | Modified: python/branches/py3k-short-float-repr/Doc/c-api/init.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/c-api/init.rst (original) +++ python/branches/py3k-short-float-repr/Doc/c-api/init.rst Mon Apr 13 18:30:54 2009 @@ -391,12 +391,12 @@ single: lock, interpreter The Python interpreter is not fully thread safe. In order to support -multi-threaded Python programs, there's a global lock that must be held by the -current thread before it can safely access Python objects. Without the lock, -even the simplest operations could cause problems in a multi-threaded program: -for example, when two threads simultaneously increment the reference count of -the same object, the reference count could end up being incremented only once -instead of twice. +multi-threaded Python programs, there's a global lock, called the :dfn:`global +interpreter lock` or :dfn:`GIL`, that must be held by the current thread before +it can safely access Python objects. Without the lock, even the simplest +operations could cause problems in a multi-threaded program: for example, when +two threads simultaneously increment the reference count of the same object, the +reference count could end up being incremented only once instead of twice. .. index:: single: setcheckinterval() (in module sys) @@ -425,9 +425,9 @@ interpreter lock has the following simple structure:: Save the thread state in a local variable. - Release the interpreter lock. + Release the global interpreter lock. ...Do some blocking I/O operation... - Reacquire the interpreter lock. + Reacquire the global interpreter lock. Restore the thread state from the local variable. This is so common that a pair of macros exists to simplify it:: @@ -444,7 +444,7 @@ hidden local variable; the :cmacro:`Py_END_ALLOW_THREADS` macro closes the block. Another advantage of using these two macros is that when Python is compiled without thread support, they are defined empty, thus saving the thread -state and lock manipulations. +state and GIL manipulations. When thread support is enabled, the block above expands to the following code:: @@ -476,7 +476,7 @@ saves and restores the value of the global variable :cdata:`errno`, since the lock manipulation does not guarantee that :cdata:`errno` is left alone. Also, when thread support is disabled, :cfunc:`PyEval_SaveThread` and -:cfunc:`PyEval_RestoreThread` don't manipulate the lock; in this case, +:cfunc:`PyEval_RestoreThread` don't manipulate the GIL; in this case, :cfunc:`PyEval_ReleaseLock` and :cfunc:`PyEval_AcquireLock` are not available. This is done so that dynamically loaded extensions compiled with thread support enabled can be loaded by an interpreter that was compiled with disabled thread @@ -559,16 +559,16 @@ .. index:: module: _thread - When only the main thread exists, no lock operations are needed. This is a + When only the main thread exists, no GIL operations are needed. This is a common situation (most Python programs do not use threads), and the lock - operations slow the interpreter down a bit. Therefore, the lock is not created - initially. This situation is equivalent to having acquired the lock: when - there is only a single thread, all object accesses are safe. Therefore, when - this function initializes the lock, it also acquires it. Before the Python - :mod:`_thread` module creates a new thread, knowing that either it has the lock - or the lock hasn't been created yet, it calls :cfunc:`PyEval_InitThreads`. When - this call returns, it is guaranteed that the lock has been created and that the - calling thread has acquired it. + operations slow the interpreter down a bit. Therefore, the lock is not + created initially. This situation is equivalent to having acquired the lock: + when there is only a single thread, all object accesses are safe. Therefore, + when this function initializes the global interpreter lock, it also acquires + it. Before the Python :mod:`_thread` module creates a new thread, knowing + that either it has the lock or the lock hasn't been created yet, it calls + :cfunc:`PyEval_InitThreads`. When this call returns, it is guaranteed that + the lock has been created and that the calling thread has acquired it. It is **not** safe to call this function when it is unknown which thread (if any) currently has the global interpreter lock. @@ -579,7 +579,7 @@ .. cfunction:: int PyEval_ThreadsInitialized() Returns a non-zero value if :cfunc:`PyEval_InitThreads` has been called. This - function can be called without holding the lock, and therefore can be used to + function can be called without holding the GIL, and therefore can be used to avoid calls to the locking API when running single-threaded. This function is not available when thread support is disabled at compile time. @@ -617,20 +617,20 @@ .. cfunction:: PyThreadState* PyEval_SaveThread() - Release the interpreter lock (if it has been created and thread support is - enabled) and reset the thread state to *NULL*, returning the previous thread - state (which is not *NULL*). If the lock has been created, the current thread - must have acquired it. (This function is available even when thread support is - disabled at compile time.) + Release the global interpreter lock (if it has been created and thread + support is enabled) and reset the thread state to *NULL*, returning the + previous thread state (which is not *NULL*). If the lock has been created, + the current thread must have acquired it. (This function is available even + when thread support is disabled at compile time.) .. cfunction:: void PyEval_RestoreThread(PyThreadState *tstate) - Acquire the interpreter lock (if it has been created and thread support is - enabled) and set the thread state to *tstate*, which must not be *NULL*. If the - lock has been created, the current thread must not have acquired it, otherwise - deadlock ensues. (This function is available even when thread support is - disabled at compile time.) + Acquire the global interpreter lock (if it has been created and thread + support is enabled) and set the thread state to *tstate*, which must not be + *NULL*. If the lock has been created, the current thread must not have + acquired it, otherwise deadlock ensues. (This function is available even + when thread support is disabled at compile time.) .. cfunction:: void PyEval_ReInitThreads() @@ -674,60 +674,61 @@ declaration. It is a no-op when thread support is disabled at compile time. All of the following functions are only available when thread support is enabled -at compile time, and must be called only when the interpreter lock has been -created. +at compile time, and must be called only when the global interpreter lock has +been created. .. cfunction:: PyInterpreterState* PyInterpreterState_New() - Create a new interpreter state object. The interpreter lock need not be held, - but may be held if it is necessary to serialize calls to this function. + Create a new interpreter state object. The global interpreter lock need not + be held, but may be held if it is necessary to serialize calls to this + function. .. cfunction:: void PyInterpreterState_Clear(PyInterpreterState *interp) - Reset all information in an interpreter state object. The interpreter lock must - be held. + Reset all information in an interpreter state object. The global interpreter + lock must be held. .. cfunction:: void PyInterpreterState_Delete(PyInterpreterState *interp) - Destroy an interpreter state object. The interpreter lock need not be held. - The interpreter state must have been reset with a previous call to + Destroy an interpreter state object. The global interpreter lock need not be + held. The interpreter state must have been reset with a previous call to :cfunc:`PyInterpreterState_Clear`. .. cfunction:: PyThreadState* PyThreadState_New(PyInterpreterState *interp) - Create a new thread state object belonging to the given interpreter object. The - interpreter lock need not be held, but may be held if it is necessary to - serialize calls to this function. + Create a new thread state object belonging to the given interpreter object. + The global interpreter lock need not be held, but may be held if it is + necessary to serialize calls to this function. .. cfunction:: void PyThreadState_Clear(PyThreadState *tstate) - Reset all information in a thread state object. The interpreter lock must be - held. + Reset all information in a thread state object. The global interpreter lock + must be held. .. cfunction:: void PyThreadState_Delete(PyThreadState *tstate) - Destroy a thread state object. The interpreter lock need not be held. The - thread state must have been reset with a previous call to + Destroy a thread state object. The global interpreter lock need not be held. + The thread state must have been reset with a previous call to :cfunc:`PyThreadState_Clear`. .. cfunction:: PyThreadState* PyThreadState_Get() - Return the current thread state. The interpreter lock must be held. When the - current thread state is *NULL*, this issues a fatal error (so that the caller - needn't check for *NULL*). + Return the current thread state. The global interpreter lock must be held. + When the current thread state is *NULL*, this issues a fatal error (so that + the caller needn't check for *NULL*). .. cfunction:: PyThreadState* PyThreadState_Swap(PyThreadState *tstate) Swap the current thread state with the thread state given by the argument - *tstate*, which may be *NULL*. The interpreter lock must be held. + *tstate*, which may be *NULL*. The global interpreter lock must be held. .. cfunction:: PyObject* PyThreadState_GetDict() @@ -752,14 +753,15 @@ .. cfunction:: PyGILState_STATE PyGILState_Ensure() - Ensure that the current thread is ready to call the Python C API regardless of - the current state of Python, or of its thread lock. This may be called as many - times as desired by a thread as long as each call is matched with a call to - :cfunc:`PyGILState_Release`. In general, other thread-related APIs may be used - between :cfunc:`PyGILState_Ensure` and :cfunc:`PyGILState_Release` calls as long - as the thread state is restored to its previous state before the Release(). For - example, normal usage of the :cmacro:`Py_BEGIN_ALLOW_THREADS` and - :cmacro:`Py_END_ALLOW_THREADS` macros is acceptable. + Ensure that the current thread is ready to call the Python C API regardless + of the current state of Python, or of the global interpreter lock. This may + be called as many times as desired by a thread as long as each call is + matched with a call to :cfunc:`PyGILState_Release`. In general, other + thread-related APIs may be used between :cfunc:`PyGILState_Ensure` and + :cfunc:`PyGILState_Release` calls as long as the thread state is restored to + its previous state before the Release(). For example, normal usage of the + :cmacro:`Py_BEGIN_ALLOW_THREADS` and :cmacro:`Py_END_ALLOW_THREADS` macros is + acceptable. The return value is an opaque "handle" to the thread state when :cfunc:`PyGILState_Ensure` was called, and must be passed to @@ -793,35 +795,34 @@ .. index:: single: setcheckinterval() (in module sys) -Every check interval, when the interpreter lock is released and reacquired, -python will also call any such provided functions. This can be used for -example by asynchronous IO handlers. The notification can be scheduled -from a worker thread and the actual call than made at the earliest -convenience by the main thread where it has possession of the global -interpreter lock and can perform any Python API calls. +Every check interval, when the global interpreter lock is released and +reacquired, python will also call any such provided functions. This can be used +for example by asynchronous IO handlers. The notification can be scheduled from +a worker thread and the actual call than made at the earliest convenience by the +main thread where it has possession of the global interpreter lock and can +perform any Python API calls. .. cfunction:: void Py_AddPendingCall( int (*func)(void *, void *arg) ) .. index:: single: Py_AddPendingCall() - Post a notification to the Python main thread. If successful, - *func* will be called with the argument *arg* at the earliest - convenience. *func* will be called having the global interpreter - lock held and can thus use the full Python API and can take any - action such as setting object attributes to signal IO completion. - It must return 0 on success, or -1 signalling an exception. - The notification function won't be interrupted to perform another - asynchronous notification recursively, - but it can still be interrupted to switch threads if the interpreter - lock is released, for example, if it calls back into python code. + Post a notification to the Python main thread. If successful, *func* will be + called with the argument *arg* at the earliest convenience. *func* will be + called having the global interpreter lock held and can thus use the full + Python API and can take any action such as setting object attributes to + signal IO completion. It must return 0 on success, or -1 signalling an + exception. The notification function won't be interrupted to perform another + asynchronous notification recursively, but it can still be interrupted to + switch threads if the global interpreter lock is released, for example, if it + calls back into python code. This function returns 0 on success in which case the notification has been - scheduled. Otherwise, for example if the notification buffer is full, - it returns -1 without setting any exception. + scheduled. Otherwise, for example if the notification buffer is full, it + returns -1 without setting any exception. - This function can be called on any thread, be it a Python thread or - some other system thread. If it is a Python thread, it doesn't matter if - it holds the global interpreter lock or not. + This function can be called on any thread, be it a Python thread or some + other system thread. If it is a Python thread, it doesn't matter if it holds + the global interpreter lock or not. .. versionadded:: 2.7 Modified: python/branches/py3k-short-float-repr/Doc/distutils/apiref.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/distutils/apiref.rst (original) +++ python/branches/py3k-short-float-repr/Doc/distutils/apiref.rst Mon Apr 13 18:30:54 2009 @@ -1950,6 +1950,19 @@ .. % todo +:mod:`distutils.command.check` --- Check the meta-data of a package +=================================================================== + +.. module:: distutils.command.check + :synopsis: Check the metadata of a package + + +The ``check`` command performs some tests on the meta-data of a package. +It makes sure for example that all required meta-data are provided through +the arguments passed to the :func:`setup` function. + +.. % todo + Creating a new Distutils command ================================ Modified: python/branches/py3k-short-float-repr/Doc/distutils/examples.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/distutils/examples.rst (original) +++ python/branches/py3k-short-float-repr/Doc/distutils/examples.rst Mon Apr 13 18:30:54 2009 @@ -11,7 +11,7 @@ .. seealso:: - `Distutils Cookbook `_ + `Distutils Cookbook `_ Collection of recipes showing how to achieve more control over distutils. @@ -233,6 +233,58 @@ ext_modules=[Extension('foopkg.foo', ['foo.c'])], ) +Checking a package +================== + +The ``check`` command allows you to verify if your package meta-data are +meeting the minimum requirements to build a distribution. + +To run it, just call it over your :file:`setup.py` script. If something is +missing, ``check`` will display a warning. + +Let's take an example with a simple script:: + + from distutils.core import setup + + setup(name='foobar') + +Running the ``check`` command will display some warnings:: + + $ python setup.py check + running check + warning: check: missing required meta-data: version ,url + warning: check: missing meta-data: either (author and author_email) or + (maintainer and maintainer_email) must be supplied + + +If you use the reStructuredText syntax in the `long_description` field and +`docutils `_ is installed you can check if +the syntax is fine with the ``check`` command, using the `restructuredtext` +option. + +For example, if the :file:`setup.py` script is changed like this:: + + from distutils.core import setup + + desc = """\ + My description + ============= + + This is the description of the ``foobar`` package. + """ + + setup(name='foobar', version='1', author='tarek', + author_email='tarek at ziade.org', + url='http://example.com', long_description=desc) + +Where the long description is broken, ``check`` will be able to detect it +by using the `docutils` parser:: + + $ pythontrunk setup.py check --restructuredtext + running check + warning: check: Title underline too short. (line 2) + warning: check: Could not finish the parsing. + .. % \section{Multiple extension modules} .. % \label{multiple-ext} Modified: python/branches/py3k-short-float-repr/Doc/distutils/setupscript.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/distutils/setupscript.rst (original) +++ python/branches/py3k-short-float-repr/Doc/distutils/setupscript.rst Mon Apr 13 18:30:54 2009 @@ -334,9 +334,9 @@ There are still some other options which can be used to handle special cases. -The :option:`optional` option is a boolean; if it is true, that specifies that -a build failure in the extension should not abort the build process, but simply -not install the failing extension. +The :option:`optional` option is a boolean; if it is true, +a build failure in the extension will not abort the build process, but +instead simply not install the failing extension. The :option:`extra_objects` option is a list of object files to be passed to the linker. These files must not have extensions, as the default extension for the Modified: python/branches/py3k-short-float-repr/Doc/library/asyncore.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/asyncore.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/asyncore.rst Mon Apr 13 18:30:54 2009 @@ -81,7 +81,8 @@ +----------------------+----------------------------------------+ | Event | Description | +======================+========================================+ - | ``handle_connect()`` | Implied by the first write event | + | ``handle_connect()`` | Implied by the first read or write | + | | event | +----------------------+----------------------------------------+ | ``handle_close()`` | Implied by a read event with no data | | | available | Modified: python/branches/py3k-short-float-repr/Doc/library/codeop.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/codeop.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/codeop.rst Mon Apr 13 18:30:54 2009 @@ -26,7 +26,7 @@ To do just the former: -.. function:: compile_command(source[, filename[, symbol]]) +.. function:: compile_command(source, filename="", symbol="single") Tries to compile *source*, which should be a string of Python code and return a code object if *source* is valid Python code. In that case, the filename Modified: python/branches/py3k-short-float-repr/Doc/library/collections.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/collections.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/collections.rst Mon Apr 13 18:30:54 2009 @@ -286,7 +286,7 @@ :class:`deque` objects ---------------------- -.. class:: deque([iterable[, maxlen]]) +.. class:: deque([iterable, [maxlen]]) Returns a new deque object initialized left-to-right (using :meth:`append`) with data from *iterable*. If *iterable* is not specified, the new deque is empty. @@ -605,7 +605,7 @@ self-documenting code. They can be used wherever regular tuples are used, and they add the ability to access fields by name instead of position index. -.. function:: namedtuple(typename, field_names, [verbose], [rename]) +.. function:: namedtuple(typename, field_names, verbose=False, rename=False) Returns a new tuple subclass named *typename*. The new subclass is used to create tuple-like objects that have fields accessible by attribute lookup as @@ -852,6 +852,10 @@ This allows :class:`OrderedDict` objects to be substituted anywhere a regular dictionary is used. +The :class:`OrderedDict` constructor and :meth:`update` method both accept +keyword arguments, but their order is lost because Python's function call +semantics pass-in keyword arguments using a regular unordered dictionary. + .. seealso:: `Equivalent OrderedDict recipe `_ Modified: python/branches/py3k-short-float-repr/Doc/library/compileall.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/compileall.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/compileall.rst Mon Apr 13 18:30:54 2009 @@ -20,7 +20,7 @@ expression argument. All files that match the expression will be skipped. -.. function:: compile_dir(dir[, maxlevels[, ddir[, force[, rx[, quiet]]]]]) +.. function:: compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, quiet=False) 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 @@ -36,7 +36,7 @@ operation. -.. function:: compile_path([skip_curdir[, maxlevels[, force]]]) +.. function:: compile_path(skip_curdir=True, maxlevels=0, force=False) 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 Modified: python/branches/py3k-short-float-repr/Doc/library/configparser.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/configparser.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/configparser.rst Mon Apr 13 18:30:54 2009 @@ -56,7 +56,7 @@ write-back, as will be the keys within each section. -.. class:: RawConfigParser([defaults[, dict_type]]) +.. class:: RawConfigParser(defaults=None, dict_type=collections.OrderedDict) The basic configuration object. When *defaults* is given, it is initialized into the dictionary of intrinsic defaults. When *dict_type* is given, it will @@ -68,7 +68,7 @@ The default *dict_type* is :class:`collections.OrderedDict`. -.. class:: ConfigParser([defaults[, dict_type]]) +.. class:: ConfigParser(defaults=None, dict_type=collections.OrderedDict) Derived class of :class:`RawConfigParser` that implements the magical interpolation feature and adds optional arguments to the :meth:`get` and @@ -87,7 +87,7 @@ The default *dict_type* is :class:`collections.OrderedDict`. -.. class:: SafeConfigParser([defaults[, dict_type]]) +.. class:: SafeConfigParser(defaults=None, dict_type=collections.OrderedDict) Derived class of :class:`ConfigParser` that implements a more-sane variant of the magical interpolation feature. This implementation is more predictable as @@ -228,7 +228,7 @@ config.read(['site.cfg', os.path.expanduser('~/.myapp.cfg')]) -.. method:: RawConfigParser.readfp(fp[, filename]) +.. method:: RawConfigParser.readfp(fp, filename=None) Read and parse configuration data from the file or file-like object in *fp* (only the :meth:`readline` method is used). If *filename* is omitted and *fp* @@ -315,7 +315,7 @@ :class:`RawConfigParser` interface, adding some optional arguments. -.. method:: ConfigParser.get(section, option[, raw[, vars]]) +.. method:: ConfigParser.get(section, option, raw=False, vars=None) Get an *option* value for the named *section*. All the ``'%'`` interpolations are expanded in the return values, based on the defaults passed into the @@ -323,7 +323,7 @@ is true. -.. method:: ConfigParser.items(section[, raw[, vars]]) +.. method:: ConfigParser.items(section, raw=False, vars=None) Return a list of ``(name, value)`` pairs for each option in the given *section*. Optional arguments have the same meaning as for the :meth:`get` method. Modified: python/branches/py3k-short-float-repr/Doc/library/constants.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/constants.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/constants.rst Mon Apr 13 18:30:54 2009 @@ -61,8 +61,8 @@ built-in namespace. They are useful for the interactive interpreter shell and should not be used in programs. -.. data:: quit([code=None]) - exit([code=None]) +.. data:: quit(code=None) + exit(code=None) Objects that when printed, print a message like "Use quit() or Ctrl-D (i.e. EOF) to exit", and when called, raise :exc:`SystemExit` with the Modified: python/branches/py3k-short-float-repr/Doc/library/copyreg.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/copyreg.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/copyreg.rst Mon Apr 13 18:30:54 2009 @@ -24,7 +24,7 @@ hence not valid as a constructor), raises :exc:`TypeError`. -.. function:: pickle(type, function[, constructor]) +.. function:: pickle(type, function, constructor=None) Declares that *function* should be used as a "reduction" function for objects of type *type*. *function* should return either a string or a tuple Modified: python/branches/py3k-short-float-repr/Doc/library/csv.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/csv.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/csv.rst Mon Apr 13 18:30:54 2009 @@ -47,7 +47,7 @@ The :mod:`csv` module defines the following functions: -.. function:: reader(csvfile[, dialect='excel'][, fmtparam]) +.. function:: reader(csvfile, dialect='excel', **fmtparams) Return a reader object which will iterate over lines in the given *csvfile*. *csvfile* can be any object which supports the :term:`iterator` protocol and returns a @@ -57,7 +57,7 @@ *dialect* parameter can be given which is used to define a set of parameters specific to a particular CSV dialect. It may be an instance of a subclass of the :class:`Dialect` class or one of the strings returned by the - :func:`list_dialects` function. The other optional *fmtparam* keyword arguments + :func:`list_dialects` function. The other optional *fmtparams* keyword arguments can be given to override individual formatting parameters in the current dialect. For full details about the dialect and formatting parameters, see section :ref:`csv-fmt-params`. @@ -76,7 +76,7 @@ Spam, Lovely Spam, Wonderful Spam -.. function:: writer(csvfile[, dialect='excel'][, fmtparam]) +.. function:: writer(csvfile, dialect='excel', **fmtparams) Return a writer object responsible for converting the user's data into delimited strings on the given file-like object. *csvfile* can be any object with a @@ -84,7 +84,7 @@ parameter can be given which is used to define a set of parameters specific to a particular CSV dialect. It may be an instance of a subclass of the :class:`Dialect` class or one of the strings returned by the - :func:`list_dialects` function. The other optional *fmtparam* keyword arguments + :func:`list_dialects` function. The other optional *fmtparams* keyword arguments can be given to override individual formatting parameters in the current dialect. For full details about the dialect and formatting parameters, see section :ref:`csv-fmt-params`. To make it @@ -103,11 +103,11 @@ >>> spamWriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam']) -.. function:: register_dialect(name[, dialect][, fmtparam]) +.. function:: register_dialect(name[, dialect], **fmtparams) Associate *dialect* with *name*. *name* must be a string. The dialect can be specified either by passing a sub-class of :class:`Dialect`, or - by *fmtparam* keyword arguments, or both, with keyword arguments overriding + by *fmtparams* keyword arguments, or both, with keyword arguments overriding parameters of the dialect. For full details about the dialect and formatting parameters, see section :ref:`csv-fmt-params`. @@ -137,7 +137,7 @@ The :mod:`csv` module defines the following classes: -.. class:: DictReader(csvfile[, fieldnames=None[, restkey=None[, restval=None[, dialect='excel'[, *args, **kwds]]]]]) +.. class:: DictReader(csvfile, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds) Create an object which operates like a regular reader but maps the information read into a dict whose keys are given by the optional *fieldnames* parameter. @@ -151,7 +151,7 @@ arguments are passed to the underlying :class:`reader` instance. -.. class:: DictWriter(csvfile, fieldnames[, restval=''[, extrasaction='raise'[, dialect='excel'[, *args, **kwds]]]]) +.. class:: DictWriter(csvfile, fieldnames, restval='', extrasaction='raise', dialect='excel', *args, **kwds) Create an object which operates like a regular writer but maps dictionaries onto output rows. The *fieldnames* parameter identifies the order in which values in @@ -195,7 +195,7 @@ The :class:`Sniffer` class provides two methods: - .. method:: sniff(sample[, delimiters=None]) + .. method:: sniff(sample, delimiters=None) Analyze the given *sample* and return a :class:`Dialect` subclass reflecting the parameters found. If the optional *delimiters* parameter Modified: python/branches/py3k-short-float-repr/Doc/library/curses.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/curses.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/curses.rst Mon Apr 13 18:30:54 2009 @@ -531,7 +531,7 @@ capability, or is canceled or absent from the terminal description. -.. function:: tparm(str[,...]) +.. function:: tparm(str[, ...]) Instantiates the string *str* with the supplied parameters, where *str* should be a parameterized string obtained from the terminfo database. E.g. Modified: python/branches/py3k-short-float-repr/Doc/library/datetime.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/datetime.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/datetime.rst Mon Apr 13 18:30:54 2009 @@ -128,7 +128,7 @@ dates or times. -.. class:: timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]]) +.. class:: timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0) All arguments are optional and default to ``0``. Arguments may be integers or floats, and may be positive or negative. @@ -570,7 +570,7 @@ Constructor: -.. class:: datetime(year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]) +.. class:: datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None) The year, month and day arguments are required. *tzinfo* may be ``None``, or an instance of a :class:`tzinfo` subclass. The remaining arguments may be integers, @@ -596,7 +596,7 @@ :meth:`fromtimestamp`. -.. method:: datetime.now([tz]) +.. method:: datetime.now(tz=None) Return the current local date and time. If optional argument *tz* is ``None`` or not specified, this is like :meth:`today`, but, if possible, supplies more @@ -617,7 +617,7 @@ :class:`datetime` object. See also :meth:`now`. -.. method:: datetime.fromtimestamp(timestamp[, tz]) +.. method:: datetime.fromtimestamp(timestamp, tz=None) Return the local date and time corresponding to the POSIX timestamp, such as is returned by :func:`time.time`. If optional argument *tz* is ``None`` or not @@ -947,7 +947,7 @@ ``self.date().isocalendar()``. -.. method:: datetime.isoformat([sep]) +.. method:: datetime.isoformat(sep='T') Return a string representing the date and time in ISO 8601 format, YYYY-MM-DDTHH:MM:SS.mmmmmm or, if :attr:`microsecond` is 0, @@ -1101,7 +1101,7 @@ day, and subject to adjustment via a :class:`tzinfo` object. -.. class:: time(hour[, minute[, second[, microsecond[, tzinfo]]]]) +.. class:: time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None) All arguments are optional. *tzinfo* may be ``None``, or an instance of a :class:`tzinfo` subclass. The remaining arguments may be integers, in the Modified: python/branches/py3k-short-float-repr/Doc/library/dbm.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/dbm.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/dbm.rst Mon Apr 13 18:30:54 2009 @@ -30,7 +30,7 @@ name, such as ``'dbm.ndbm'`` or ``'dbm.gnu'``. -.. function:: open(filename[, flag[, mode]]) +.. function:: open(filename, flag='r', mode=0o666) Open the database file *filename* and return a corresponding object. @@ -121,7 +121,7 @@ raised for general mapping errors like specifying an incorrect key. -.. function:: open(filename, [flag, [mode]]) +.. function:: open(filename[, flag[, mode]]) Open a ``gdbm`` database and return a :class:`gdbm` object. The *filename* argument is the name of the database file. Modified: python/branches/py3k-short-float-repr/Doc/library/decimal.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/decimal.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/decimal.rst Mon Apr 13 18:30:54 2009 @@ -305,7 +305,7 @@ --------------- -.. class:: Decimal([value [, context]]) +.. class:: Decimal(value="0", context=None) Construct a new :class:`Decimal` object based from *value*. Modified: python/branches/py3k-short-float-repr/Doc/library/difflib.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/difflib.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/difflib.rst Mon Apr 13 18:30:54 2009 @@ -72,7 +72,7 @@ The constructor for this class is: - .. function:: __init__([tabsize][, wrapcolumn][, linejunk][, charjunk]) + .. method:: __init__(tabsize=8, wrapcolumn=None, linejunk=None, charjunk=IS_CHARACTER_JUNK) Initializes instance of :class:`HtmlDiff`. @@ -88,8 +88,7 @@ The following methods are public: - - .. function:: make_file(fromlines, tolines [, fromdesc][, todesc][, context][, numlines]) + .. method:: make_file(fromlines, tolines, fromdesc='', todesc='', context=False, numlines=5) Compares *fromlines* and *tolines* (lists of strings) and returns a string which is a complete HTML file containing a table showing line by line differences with @@ -108,8 +107,7 @@ the next difference highlight at the top of the browser without any leading context). - - .. function:: make_table(fromlines, tolines [, fromdesc][, todesc][, context][, numlines]) + .. method:: make_table(fromlines, tolines, fromdesc='', todesc='', context=False, numlines=5) Compares *fromlines* and *tolines* (lists of strings) and returns a string which is a complete HTML table showing line by line differences with inter-line and @@ -122,7 +120,7 @@ contains a good example of its use. -.. function:: context_diff(a, b[, fromfile][, tofile][, fromfiledate][, tofiledate][, n][, lineterm]) +.. function:: context_diff(a, b, fromfile='', tofile='', fromfiledate='', tofiledate='', n=3, lineterm='\\n') Compare *a* and *b* (lists of strings); return a delta (a :term:`generator` generating the delta lines) in context diff format. @@ -167,7 +165,7 @@ See :ref:`difflib-interface` for a more detailed example. -.. function:: get_close_matches(word, possibilities[, n][, cutoff]) +.. function:: get_close_matches(word, possibilities, n=3, cutoff=0.6) Return a list of the best "good enough" matches. *word* is a sequence for which close matches are desired (typically a string), and *possibilities* is a list of @@ -193,7 +191,7 @@ ['except'] -.. function:: ndiff(a, b[, linejunk][, charjunk]) +.. function:: ndiff(a, b, linejunk=None, charjunk=IS_CHARACTER_JUNK) Compare *a* and *b* (lists of strings); return a :class:`Differ`\ -style delta (a :term:`generator` generating the delta lines). @@ -253,7 +251,7 @@ emu -.. function:: unified_diff(a, b[, fromfile][, tofile][, fromfiledate][, tofiledate][, n][, lineterm]) +.. function:: unified_diff(a, b, fromfile='', tofile='', fromfiledate='', tofiledate='', n=3, lineterm='\\n') Compare *a* and *b* (lists of strings); return a delta (a :term:`generator` generating the delta lines) in unified diff format. @@ -326,7 +324,7 @@ The :class:`SequenceMatcher` class has this constructor: -.. class:: SequenceMatcher([isjunk[, a[, b]]]) +.. class:: SequenceMatcher(isjunk=None, a='', b='') Optional argument *isjunk* must be ``None`` (the default) or a one-argument function that takes a sequence element and returns true if and only if the @@ -467,7 +465,7 @@ insert a[6:6] () b[5:6] (f) - .. method:: get_grouped_opcodes([n]) + .. method:: get_grouped_opcodes(n=3) Return a :term:`generator` of groups with up to *n* lines of context. @@ -580,7 +578,7 @@ The :class:`Differ` class has this constructor: -.. class:: Differ([linejunk[, charjunk]]) +.. class:: Differ(linejunk=None, charjunk=None) Optional keyword parameters *linejunk* and *charjunk* are for filter functions (or ``None``): Modified: python/branches/py3k-short-float-repr/Doc/library/dis.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/dis.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/dis.rst Mon Apr 13 18:30:54 2009 @@ -30,22 +30,23 @@ The :mod:`dis` module defines the following functions and constants: -.. function:: dis([bytesource]) +.. function:: dis(x=None) - Disassemble the *bytesource* object. *bytesource* can denote either a module, a + Disassemble the *x* object. *x* can denote either a module, a class, a method, a function, or a code object. For a module, it disassembles all functions. For a class, it disassembles all methods. For a single code sequence, it prints one line per bytecode instruction. If no object is provided, it disassembles the last traceback. -.. function:: distb([tb]) +.. function:: distb(tb=None) Disassembles the top-of-stack function of a traceback, using the last traceback if none was passed. The instruction causing the exception is indicated. -.. function:: disassemble(code[, lasti]) +.. function:: disassemble(code, lasti=-1) + disco(code, lasti=-1) Disassembles a code object, indicating the last instruction if *lasti* was provided. The output is divided in the following columns: @@ -62,12 +63,6 @@ constant values, branch targets, and compare operators. -.. function:: disco(code[, lasti]) - - A synonym for :func:`disassemble`. It is more convenient to type, and kept - for compatibility with earlier Python releases. - - .. function:: findlinestarts(code) This generator function uses the ``co_firstlineno`` and ``co_lnotab`` Modified: python/branches/py3k-short-float-repr/Doc/library/doctest.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/doctest.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/doctest.rst Mon Apr 13 18:30:54 2009 @@ -753,7 +753,7 @@ and :ref:`doctest-simple-testfile`. -.. function:: testfile(filename[, module_relative][, name][, package][, globs][, verbose][, report][, optionflags][, extraglobs][, raise_on_error][, parser][, encoding]) +.. function:: testfile(filename, module_relative=True, name=None, package=None, globs=None, verbose=None, report=True, optionflags=0, extraglobs=None, raise_on_error=False, parser=DocTestParser(), encoding=None) All arguments except *filename* are optional, and should be specified in keyword form. @@ -822,7 +822,7 @@ convert the file to unicode. -.. function:: testmod([m][, name][, globs][, verbose][, report][, optionflags][, extraglobs][, raise_on_error][, exclude_empty]) +.. function:: testmod(m=None, name=None, globs=None, verbose=None, report=True, optionflags=0, extraglobs=None, raise_on_error=False, exclude_empty=False) All arguments are optional, and all except for *m* should be specified in keyword form. @@ -860,7 +860,7 @@ deprecate it, but it's rarely useful: -.. function:: run_docstring_examples(f, globs[, verbose][, name][, compileflags][, optionflags]) +.. function:: run_docstring_examples(f, globs, verbose=False, name="NoName", compileflags=None, optionflags=0) Test examples associated with object *f*; for example, *f* may be a module, function, or class object. @@ -905,7 +905,7 @@ from text files and modules with doctests: -.. function:: DocFileSuite(*paths, [module_relative][, package][, setUp][, tearDown][, globs][, optionflags][, parser][, encoding]) +.. function:: DocFileSuite(*paths, module_relative=True, package=None, setUp=None, tearDown=None, globs=None, optionflags=0, parser=DocTestParser(), encoding=None) Convert doctest tests from one or more text files to a :class:`unittest.TestSuite`. @@ -972,7 +972,7 @@ from a text file using :func:`DocFileSuite`. -.. function:: DocTestSuite([module][, globs][, extraglobs][, test_finder][, setUp][, tearDown][, checker]) +.. function:: DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None, setUp=None, tearDown=None, checker=None) Convert doctest tests for a module to a :class:`unittest.TestSuite`. @@ -1158,7 +1158,7 @@ ^^^^^^^^^^^^^^^ -.. class:: Example(source, want[, exc_msg][, lineno][, indent][, options]) +.. class:: Example(source, want, exc_msg=None, lineno=0, indent=0, options=None) A single interactive example, consisting of a Python statement and its expected output. The constructor arguments are used to initialize the member variables @@ -1220,7 +1220,7 @@ ^^^^^^^^^^^^^^^^^^^^^ -.. class:: DocTestFinder([verbose][, parser][, recurse][, exclude_empty]) +.. class:: DocTestFinder(verbose=False, parser=DocTestParser(), recurse=True, exclude_empty=True) A processing class used to extract the :class:`DocTest`\ s that are relevant to a given object, from its docstring and the docstrings of its contained objects. @@ -1306,14 +1306,14 @@ information. - .. method:: get_examples(string[, name]) + .. method:: get_examples(string, name='') Extract all doctest examples from the given string, and return them as a list of :class:`Example` objects. Line numbers are 0-based. The optional argument *name* is a name identifying this string, and is only used for error messages. - .. method:: parse(string[, name]) + .. method:: parse(string, name='') Divide the given string into examples and intervening text, and return them as a list of alternating :class:`Example`\ s and strings. Line numbers for the @@ -1327,7 +1327,7 @@ ^^^^^^^^^^^^^^^^^^^^^ -.. class:: DocTestRunner([checker][, verbose][, optionflags]) +.. class:: DocTestRunner(checker=None, verbose=None, optionflags=0) A processing class used to execute and verify the interactive examples in a :class:`DocTest`. @@ -1409,7 +1409,7 @@ output function that was passed to :meth:`DocTestRunner.run`. - .. method:: run(test[, compileflags][, out][, clear_globs]) + .. method:: run(test, compileflags=None, out=None, clear_globs=True) Run the examples in *test* (a :class:`DocTest` object), and display the results using the writer function *out*. @@ -1428,7 +1428,7 @@ :meth:`DocTestRunner.report_\*` methods. - .. method:: summarize([verbose]) + .. method:: summarize(verbose=None) Print a summary of all the test cases that have been run by this DocTestRunner, and return a :term:`named tuple` ``TestResults(failed, attempted)``. @@ -1592,7 +1592,7 @@ converted to code, and the rest placed in comments. -.. function:: debug(module, name[, pm]) +.. function:: debug(module, name, pm=False) Debug the doctests for an object. @@ -1613,7 +1613,7 @@ passing an appropriate :func:`exec` call to :func:`pdb.run`. -.. function:: debug_src(src[, pm][, globs]) +.. function:: debug_src(src, pm=False, globs=None) Debug the doctests in a string. @@ -1633,7 +1633,7 @@ doctest!) for more details: -.. class:: DebugRunner([checker][, verbose][, optionflags]) +.. class:: DebugRunner(checker=None, verbose=None, optionflags=0) A subclass of :class:`DocTestRunner` that raises an exception as soon as a failure is encountered. If an unexpected exception occurs, an Modified: python/branches/py3k-short-float-repr/Doc/library/io.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/io.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/io.rst Mon Apr 13 18:30:54 2009 @@ -279,7 +279,7 @@ Return the new absolute position. - .. versionadded:: 2.7 + .. versionadded:: 3.1 The ``SEEK_*`` constants .. method:: seekable() Modified: python/branches/py3k-short-float-repr/Doc/library/itertools.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/itertools.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/itertools.rst Mon Apr 13 18:30:54 2009 @@ -34,41 +34,46 @@ **Infinite Iterators:** - ================== ================= ================================================= - Iterator Arguments Results - ================== ================= ================================================= - :func:`count` start, [step] start, start+step, start+2*step, ... - :func:`cycle` p p0, p1, ... plast, p0, p1, ... - :func:`repeat` elem [,n] elem, elem, elem, ... endlessly or up to n times - ================== ================= ================================================= +================== ================= ================================================= ========================================= +Iterator Arguments Results Example +================== ================= ================================================= ========================================= +:func:`count` start, [step] start, start+step, start+2*step, ... ``count(10) --> 10 11 12 13 14 ...`` +:func:`cycle` p p0, p1, ... plast, p0, p1, ... ``cycle('ABCD') --> A B C D A B C D ...`` +:func:`repeat` elem [,n] elem, elem, elem, ... endlessly or up to n times ``repeat(10, 3) --> 10 10 10`` +================== ================= ================================================= ========================================= **Iterators terminating on the shortest input sequence:** - ==================== ============================ ================================================= - Iterator Arguments Results - ==================== ============================ ================================================= - :func:`chain` p, q, ... p0, p1, ... plast, q0, q1, ... - :func:`compress` data, selectors (d[0] if s[0]), (d[1] if s[1]), ... - :func:`dropwhile` pred, seq seq[n], seq[n+1], starting when pred fails - :func:`filterfalse` pred, seq elements of seq where pred(elem) is False - :func:`groupby` iterable[, keyfunc] sub-iterators grouped by value of keyfunc(v) - :func:`islice` seq, [start,] stop [, step] elements from seq[start:stop:step] - :func:`starmap` func, seq func(\*seq[0]), func(\*seq[1]), ... - :func:`tee` it, n it1, it2 , ... itn splits one iterator into n - :func:`takewhile` pred, seq seq[0], seq[1], until pred fails - :func:`zip_longest` p, q, ... (p[0], q[0]), (p[1], q[1]), ... - ==================== ============================ ================================================= +==================== ============================ ================================================= ============================================================= +Iterator Arguments Results Example +==================== ============================ ================================================= ============================================================= +: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`` +:func:`filterfalse` pred, seq elements of seq where pred(elem) is False ``ifilterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8`` +:func:`groupby` iterable[, keyfunc] sub-iterators grouped by value of keyfunc(v) +:func:`islice` seq, [start,] stop [, step] elements from seq[start:stop:step] ``islice('ABCDEFG', 2, None) --> C D E F G`` +:func:`starmap` func, seq func(\*seq[0]), func(\*seq[1]), ... ``starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000`` +:func:`takewhile` pred, seq seq[0], seq[1], until pred fails ``takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4`` +:func:`tee` it, n it1, it2 , ... itn splits one iterator into n +:func:`zip_longest` p, q, ... (p[0], q[0]), (p[1], q[1]), ... ``izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-`` +==================== ============================ ================================================= ============================================================= **Combinatoric generators:** - ===================================== ==================== ================================================= - Iterator Arguments Results - ===================================== ==================== ================================================= - :func:`product` p, q, ... [repeat=1] cartesian product - :func:`permutations` p[, r] r-length permutations (without repeated elements) - :func:`combinations` p[, r] r-length combinations (sorted and no repeats) - :func:`combinations_with_replacement` p[, r] r-length combinations (sorted but with repeats) - ===================================== ==================== ================================================= +============================================== ==================== ============================================================= +Iterator Arguments Results +============================================== ==================== ============================================================= +:func:`product` p, q, ... [repeat=1] cartesian product, equivalent to a nested for-loop +:func:`permutations` p[, r] r-length tuples, all possible orderings, no repeated elements +:func:`combinations` p[, r] r-length tuples, in sorted order, no repeated elements +:func:`combinations_with_replacement` p[, r] r-length tuples, in sorted order, with repeated elements +| +``product('ABCD', repeat=2)`` ``AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD`` +``permutations('ABCD', 2)`` ``AB AC AD BA BC BD CA CB CD DA DB DC`` +``combinations('ABCD', 2)`` ``AB AC AD BC BD CD`` +``combinations_with_replacement('ABCD', 2)`` ``AA AB AC AD BB BC BD CC CD DD`` +============================================== ==================== ============================================================= .. _itertools-functions: @@ -550,43 +555,6 @@ *fillvalue* defaults to ``None``. -.. _itertools-example: - -Examples --------- - -The following examples show common uses for each tool and demonstrate ways they -can be combined. - -.. doctest:: - - >>> # Show a dictionary sorted and grouped by value - >>> from operator import itemgetter - >>> d = dict(a=1, b=2, c=1, d=2, e=1, f=2, g=3) - >>> di = sorted(d.items(), key=itemgetter(1)) - >>> for k, g in groupby(di, key=itemgetter(1)): - ... print(k, map(itemgetter(0), g)) - ... - 1 ['a', 'c', 'e'] - 2 ['b', 'd', 'f'] - 3 ['g'] - - >>> # Find runs of consecutive numbers using groupby. The key to the solution - >>> # is differencing with a range so that consecutive numbers all appear in - >>> # same group. - >>> data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28] - >>> for k, g in groupby(enumerate(data), lambda t:t[0]-t[1]): - ... print(map(operator.itemgetter(1), g)) - ... - [1] - [4, 5, 6] - [10] - [15, 16, 17, 18] - [22] - [25, 26, 27, 28] - - - .. _itertools-recipes: Recipes Modified: python/branches/py3k-short-float-repr/Doc/library/json.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/json.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/json.rst Mon Apr 13 18:30:54 2009 @@ -118,7 +118,7 @@ file-like object). If *skipkeys* is ``True`` (default: ``False``), then dict keys that are not - of a basic type (:class:`str`, :class:`unicode`, :class:`int`, :class:`long`, + of a basic type (:class:`str`, :class:`unicode`, :class:`int`, :class:`float`, :class:`bool`, ``None``) will be skipped instead of raising a :exc:`TypeError`. @@ -232,7 +232,7 @@ +---------------+-------------------+ | string | unicode | +---------------+-------------------+ - | number (int) | int, long | + | number (int) | int | +---------------+-------------------+ | number (real) | float | +---------------+-------------------+ @@ -304,7 +304,7 @@ +-------------------+---------------+ | str, unicode | string | +-------------------+---------------+ - | int, long, float | number | + | int, float | number | +-------------------+---------------+ | True | true | +-------------------+---------------+ @@ -319,7 +319,7 @@ (to raise :exc:`TypeError`). If *skipkeys* is ``False`` (the default), then it is a :exc:`TypeError` to - attempt encoding of keys that are not str, int, long, float or None. If + attempt encoding of keys that are not str, int, float or None. If *skipkeys* is ``True``, such items are simply skipped. If *ensure_ascii* is ``True`` (the default), the output is guaranteed to be Modified: python/branches/py3k-short-float-repr/Doc/library/multiprocessing.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/multiprocessing.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/multiprocessing.rst Mon Apr 13 18:30:54 2009 @@ -841,7 +841,7 @@ will always return ``True`` except if a timeout is given and the operation times out. - .. versionchanged:: 2.7 + .. versionchanged:: 3.1 Previously, the method always returned ``None``. .. class:: Lock() @@ -1128,9 +1128,10 @@ ``current_process().authkey``. Otherwise *authkey* is used and it must be a string. - .. method:: start() + .. method:: start([initializer[, initargs]]) - Start a subprocess to start the manager. + Start a subprocess to start the manager. If *initializer* is not ``None`` + then the subprocess will call ``initializer(*initargs)`` when it starts. .. method:: serve_forever() Modified: python/branches/py3k-short-float-repr/Doc/library/stdtypes.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/stdtypes.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/stdtypes.rst Mon Apr 13 18:30:54 2009 @@ -479,7 +479,7 @@ exponent. -.. method:: float.fromhex(s) +.. classmethod:: float.fromhex(s) Class method to return the float represented by a hexadecimal string *s*. The string *s* may have leading and trailing @@ -967,7 +967,7 @@ 'example.com' -.. method:: str.maketrans(x[, y[, z]]) +.. staticmethod:: str.maketrans(x[, y[, z]]) This static method returns a translation table usable for :meth:`str.translate`. @@ -1514,8 +1514,8 @@ The bytes and bytearray types have an additional class method: -.. method:: bytes.fromhex(string) - bytearray.fromhex(string) +.. classmethod:: bytes.fromhex(string) + bytearray.fromhex(string) This :class:`bytes` class method returns a bytes or bytearray object, decoding the given string object. The string must contain two hexadecimal @@ -1524,7 +1524,9 @@ >>> bytes.fromhex('f0 f1f2 ') b'\xf0\xf1\xf2' -The translate method differs in semantics from the version available on strings: + +The maketrans and translate methods differ in semantics from the versions +available on strings: .. method:: bytes.translate(table[, delete]) @@ -1533,8 +1535,7 @@ mapped through the given translation table, which must be a bytes object of length 256. - You can use the :func:`string.maketrans` helper function to create a - translation table. + You can use the :func:`bytes.maketrans` method to create a translation table. Set the *table* argument to ``None`` for translations that only delete characters:: @@ -1543,6 +1544,16 @@ b'rd ths shrt txt' +.. staticmethod:: bytes.maketrans(from, to) + + This static method returns a translation table usable for + :meth:`bytes.translate` that will map each character in *from* into the + character at the same position in *to*; *from* and *to* must be bytes objects + and have the same length. + + .. versionadded:: 3.1 + + .. _types-set: Set Types --- :class:`set`, :class:`frozenset` @@ -1847,7 +1858,7 @@ Return a shallow copy of the dictionary. - .. method:: fromkeys(seq[, value]) + .. classmethod:: fromkeys(seq[, value]) Create a new dictionary with keys from *seq* and values set to *value*. Modified: python/branches/py3k-short-float-repr/Doc/library/string.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/string.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/string.rst Mon Apr 13 18:30:54 2009 @@ -548,13 +548,9 @@ delimiter), and it should appear last in the regular expression. -String functions +Helper functions ---------------- -The following functions are available to operate on string objects. -They are not available as string methods. - - .. function:: capwords(s) Split the argument into words using :func:`split`, capitalize each word using @@ -568,3 +564,6 @@ Return a translation table suitable for passing to :meth:`bytes.translate`, that will map each character in *from* into the character at the same position in *to*; *from* and *to* must have the same length. + + .. deprecated:: 3.1 + Use the :meth:`bytes.maketrans` static method instead. Modified: python/branches/py3k-short-float-repr/Doc/library/sys.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/sys.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/sys.rst Mon Apr 13 18:30:54 2009 @@ -833,7 +833,7 @@ so ``sys.version_info[0]`` is equivalent to ``sys.version_info.major`` and so on. - .. versionchanged:: 2.7 + .. versionchanged:: 3.1 Added named component attributes .. data:: warnoptions Modified: python/branches/py3k-short-float-repr/Doc/library/test.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/test.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/test.rst Mon Apr 13 18:30:54 2009 @@ -322,6 +322,30 @@ assert s.getvalue() == "hello" +.. function:: import_module(name, deprecated=False) + + This function imports and returns the named module. Unlike a normal + import, this function raises :exc:`unittest.SkipTest` if the module + cannot be imported. + + Module and package deprecation messages are suppressed during this import + if *deprecated* is :const:`True`. + + .. versionadded:: 3.1 + + +.. function:: import_fresh_module(name, blocked_names=None, deprecated=False) + + This function imports and returns a fresh copy of the named Python module. The + ``sys.modules`` cache is bypassed temporarily, and the ability to import the + modules named in *blocked_names* is suppressed for the duration of the import. + + Module and package deprecation messages are suppressed during this import + if *deprecated* is :const:`True`. + + .. versionadded:: 3.1 + + The :mod:`test.support` module defines the following classes: .. class:: TransientResource(exc[, **kwargs]) Modified: python/branches/py3k-short-float-repr/Doc/library/threading.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/threading.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/threading.rst Mon Apr 13 18:30:54 2009 @@ -687,7 +687,7 @@ This method returns the internal flag on exit, so it will always return ``True`` except if a timeout is given and the operation times out. - .. versionchanged:: 2.7 + .. versionchanged:: 3.1 Previously, the method always returned ``None``. Modified: python/branches/py3k-short-float-repr/Doc/library/tkinter.ttk.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/tkinter.ttk.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/tkinter.ttk.rst Mon Apr 13 18:30:54 2009 @@ -9,13 +9,13 @@ .. index:: single: ttk The :mod:`tkinter.ttk` module provides access to the Tk themed widget set, -which has been introduced in Tk 8.5. If you do not have Python compiled against -Tk 8.5 you may still use this module as long as you have Tile installed, but -then you will miss some features provided by the new Tk, like anti-aliased font -rendering under X11, window transparency (on X11 you will need a composition -window manager) and others. +introduced in Tk 8.5. If Python has not been compiled against Tk 8.5, this +module can still be accessed if *Tile* has been installed. The former +method using Tk 8.5 provides additional benefits including anti-aliased font +rendering under X11 and window transparency (requiring a composition +window manager on X11). -The basic idea of :mod:`tkinter.ttk` is to separate, to the extent possible, +The basic idea for :mod:`tkinter.ttk` is to separate, to the extent possible, the code implementing a widget's behavior from the code implementing its appearance. @@ -23,58 +23,55 @@ .. seealso:: `Tk Widget Styling Support `_ - The document which brought up theming support for Tk + A document introducing theming support for Tk Using Ttk --------- -Basically, to start using Ttk, you have to import its module:: +To start using Ttk, import its module:: from tkinter import ttk -But if you already have some code that does:: - - from tkinter import * - -You may optionally want to use:: +To override the basic Tk widgets, the import should follow the Tk import:: from tkinter import * from tkinter.ttk import * -And then several :mod:`tkinter.ttk` widgets (:class:`Button`, +That code causes several :mod:`tkinter.ttk` widgets (:class:`Button`, :class:`Checkbutton`, :class:`Entry`, :class:`Frame`, :class:`Label`, :class:`LabelFrame`, :class:`Menubutton`, :class:`PanedWindow`, -:class:`Radiobutton`, :class:`Scale` and :class:`Scrollbar`) will -automatically substitute the Tk widgets. +:class:`Radiobutton`, :class:`Scale` and :class:`Scrollbar`) to +automatically replace the Tk widgets. + +This has the direct benefit of using the new widgets which gives a better +look and feel across platforms; however, the replacement widgets are not +completely compatible. The main difference is that widget options such as +"fg", "bg" and others related to widget styling are no +longer present in Ttk widgets. Instead, use the :class:`ttk.Style` class +for improved styling effects. -This has the direct benefit of using the new widgets which gives better -look & feel across platforms, but you should be aware that they are not -totally compatible. The main difference you will find out is that widget -options such as "fg", "bg" and others related to widget styling are no -longer present in Ttk widgets, instead you will have to use :class:`ttk.Style` -to achieve the same (or better) styling. .. seealso:: - `Converting existing applications to use the Tile widgets `_ - A text which talks in Tcl terms about differences typically found when - moving applications to use the new widgets. + `Converting existing applications to use Tile widgets `_ + A monograph (using Tcl terminology) about differences typically + encountered when moving applications to use the new widgets. Ttk Widgets ----------- -Ttk comes with 17 widgets, where 11 of these already existed in tkinter: +Ttk comes with 17 widgets, eleven of which already existed in tkinter: :class:`Button`, :class:`Checkbutton`, :class:`Entry`, :class:`Frame`, :class:`Label`, :class:`LabelFrame`, :class:`Menubutton`, :class:`PanedWindow`, -:class:`Radiobutton`, :class:`Scale` and :class:`Scrollbar`. The others 6 are +:class:`Radiobutton`, :class:`Scale` and :class:`Scrollbar`. The other six are new: :class:`Combobox`, :class:`Notebook`, :class:`Progressbar`, :class:`Separator`, :class:`Sizegrip` and :class:`Treeview`. And all them are subclasses of :class:`Widget`. -Like it was told before, you will notice changes in look & feel as well in the -styling code. To demonstrate the latter, a very simple example is shown below. +Using the Ttk widgets gives the application an improved look and feel. +As discussed above, there are differences in how the styling is coded. Tk code:: @@ -90,7 +87,7 @@ l1 = ttk.Label(text="Test", style="BW.TLabel") l2 = ttk.Label(text="Test", style="BW.TLabel") -For more information about TtkStyling_ read the :class:`Style` class +For more information about TtkStyling_, see the :class:`Style` class documentation. Widget @@ -554,10 +551,10 @@ ----------- The :class:`ttk.Progressbar` widget shows the status of a long-running -operation. It can operate in two modes: determinate mode shows the amount -completed relative to the total amount of work to be done, and indeterminate -mode provides an animated display to let the user know that something is -happening. +operation. It can operate in two modes: 1) the determinate mode which shows the +amount completed relative to the total amount of work to be done and 2) the +indeterminate mode which provides an animated display to let the user know that +work is progressing. Options @@ -1164,7 +1161,7 @@ the value for that option. For example, to change every default button to be a flat button with - some padding and a different background color you could do:: + some padding and a different background color:: from tkinter import ttk import tkinter @@ -1186,7 +1183,7 @@ Each key in *kw* is an option and each value should be a list or a tuple (usually) containing statespecs grouped in tuples, lists, or - something else of your preference. A statespec is a compound of one + some other preference. A statespec is a compound of one or more states and then a value. An example may make it more understandable:: @@ -1208,9 +1205,9 @@ Note that the order of the (states, value) sequences for an option does - matter, if you changed the order to ``[('active', 'blue'), ('pressed', - 'red')]`` in the foreground option, for example, you would get a blue - foreground when the widget were in active or pressed states. + matter, if the order is changed to ``[('active', 'blue'), ('pressed', + 'red')]`` in the foreground option, for example, the result would be a + blue foreground when the widget were in active or pressed states. .. method:: lookup(style, option[, state=None[, default=None]]) @@ -1221,7 +1218,7 @@ states. If the *default* argument is set, it is used as a fallback value in case no specification for option is found. - To check what font a Button uses by default, you would do:: + To check what font a Button uses by default:: from tkinter import ttk Modified: python/branches/py3k-short-float-repr/Doc/library/unittest.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/unittest.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/unittest.rst Mon Apr 13 18:30:54 2009 @@ -611,7 +611,7 @@ Signal a test failure if *expr* is false; the explanation for the error will be *msg* if given, otherwise it will be :const:`None`. - .. deprecated:: 2.7 + .. deprecated:: 3.1 :meth:`failUnless`. @@ -630,10 +630,10 @@ registers :meth:`addTypeEqualityFunc` the type specific equality function will be called in order to generate a more useful default error message. - .. versionchanged:: 2.7 + .. versionchanged:: 3.1 Added the automatic calling of type specific equality function. - .. deprecated:: 2.7 + .. deprecated:: 3.1 :meth:`failUnlessEqual`. @@ -647,7 +647,7 @@ default value for *msg* can be computed to include representations of both *first* and *second*. - .. deprecated:: 2.7 + .. deprecated:: 3.1 :meth:`failIfEqual`. @@ -663,7 +663,7 @@ compare equal, the test will fail with the explanation given by *msg*, or :const:`None`. - .. deprecated:: 2.7 + .. deprecated:: 3.1 :meth:`failUnlessAlmostEqual`. @@ -679,7 +679,7 @@ compare equal, the test will fail with the explanation given by *msg*, or :const:`None`. - .. deprecated:: 2.7 + .. deprecated:: 3.1 :meth:`failIfAlmostEqual`. @@ -689,13 +689,13 @@ assertLessEqual(first, second, msg=None) Test that *first* is respectively >, >=, < or <= than *second* depending - on the method name. If not, the test will fail with the nice explanation + on the method name. If not, the test will fail with an explanation or with the explanation given by *msg*:: >>> self.assertGreaterEqual(3, 4) AssertionError: "3" unexpectedly not greater than or equal to "4" - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertMultiLineEqual(self, first, second, msg=None) @@ -706,7 +706,7 @@ If specified *msg* will be used as the error message on failure. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertRegexpMatches(text, regexp[, msg=None]): @@ -716,18 +716,18 @@ a regular expression object or a string containing a regular expression suitable for use by :func:`re.search`. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertIn(first, second, msg=None) assertNotIn(first, second, msg=None) - Tests that *first* is or is not in *second* with a nice explanitory error + Tests that *first* is or is not in *second* with an explanatory error message as appropriate. If specified *msg* will be used as the error message on failure. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertSameElements(expected, actual, msg=None) @@ -738,7 +738,7 @@ If specified *msg* will be used as the error message on failure. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertSetEqual(set1, set2, msg=None) @@ -751,7 +751,7 @@ If specified *msg* will be used as the error message on failure. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertDictEqual(expected, actual, msg=None) @@ -761,18 +761,18 @@ If specified *msg* will be used as the error message on failure. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertDictContainsSubset(expected, actual, msg=None) - Tests whether the key value pairs in dictionary *actual* are a + Tests whether the key/value pairs in dictionary *actual* are a superset of those in *expected*. If not, an error message listing the missing keys and mismatched values is generated. If specified *msg* will be used as the error message on failure. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertListEqual(list1, list2, msg=None) @@ -784,7 +784,7 @@ If specified *msg* will be used as the error message on failure. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertSequenceEqual(seq1, seq2, msg=None, seq_type=None) @@ -799,7 +799,7 @@ This method is used to implement :meth:`assertListEqual` and :meth:`assertTupleEqual`. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertRaises(exception[, callable, ...]) @@ -821,7 +821,7 @@ .. versionchanged:: 3.1 Added the ability to use :meth:`assertRaises` as a context manager. - .. deprecated:: 2.7 + .. deprecated:: 3.1 :meth:`failUnlessRaises`. @@ -840,14 +840,14 @@ with self.assertRaisesRegexp(ValueError, 'literal'): int('XYZ') - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertIsNone(expr[, msg]) This signals a test failure if *expr* is not None. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. method:: assertIsNotNone(expr[, msg]) @@ -855,6 +855,23 @@ The inverse of the :meth:`assertIsNone` method. This signals a test failure if *expr* is None. + .. versionadded:: 3.1 + + + .. method:: assertIs(expr1, expr2[, msg]) + + This signals a test failure if *expr1* and *expr2* don't evaluate to the same + object. + + .. versionadded:: 2.7 + + + .. method:: assertIsNot(expr1, expr2[, msg]) + + The inverse of the :meth:`assertIs` method. + This signals a test failure if *expr1* and *expr2* evaluate to the same + object. + .. versionadded:: 2.7 @@ -865,7 +882,7 @@ This signals a test failure if *expr* is true, with *msg* or :const:`None` for the error message. - .. deprecated:: 2.7 + .. deprecated:: 3.1 :meth:`failIf`. @@ -899,7 +916,7 @@ The class setting can be overridden in individual tests by assigning an instance attribute to True or False before calling the assert methods. - .. versionadded:: 2.7 + .. versionadded:: 3.1 Testing frameworks can use the following methods to collect information on @@ -936,7 +953,7 @@ returns the first line of the test method's docstring, if available, along with the method name. - .. versionchanged:: 2.7 + .. versionchanged:: 3.1 In earlier versions this only returned the first line of the test method's docstring, if available or the :const:`None`. That led to @@ -951,14 +968,14 @@ been asked to compare are exactly *typeobj* (not subclasses). *function* must take two positional arguments and a third msg=None keyword argument just as :meth:`assertEqual` does. It must raise - self.failureException when inequality between the first two + ``self.failureException`` when inequality between the first two parameters is detected. One good use of custom equality checking functions for a type - is to raise self.failureException with an error message useful - for debugging the by explaining the inequalities in detail. + is to raise ``self.failureException`` with an error message useful + for debugging the problem by explaining the inequalities in detail. - .. versionadded:: 2.7 + .. versionadded:: 3.1 .. class:: FunctionTestCase(testFunc[, setUp[, tearDown[, description]]]) Modified: python/branches/py3k-short-float-repr/Doc/make.bat ============================================================================== --- python/branches/py3k-short-float-repr/Doc/make.bat (original) +++ python/branches/py3k-short-float-repr/Doc/make.bat Mon Apr 13 18:30:54 2009 @@ -4,6 +4,7 @@ set SVNROOT=http://svn.python.org/projects if "%PYTHON%" EQU "" set PYTHON=..\pcbuild\python if "%HTMLHELP%" EQU "" set HTMLHELP=%ProgramFiles%\HTML Help Workshop\hhc.exe +if "%DISTVERSION%" EQU "" for /f "usebackq" %%v in (`%PYTHON% tools/sphinxext/patchlevel.py`) do set DISTVERSION=%%v if "%1" EQU "" goto help if "%1" EQU "html" goto build @@ -33,7 +34,7 @@ goto end :checkout -svn co %SVNROOT%/doctools/trunk/sphinx tools/sphinx +svn co %SVNROOT%/external/Sphinx-0.6.1/sphinx tools/sphinx svn co %SVNROOT%/external/docutils-0.5/docutils tools/docutils svn co %SVNROOT%/external/Jinja-2.1.1/jinja2 tools/jinja2 svn co %SVNROOT%/external/Pygments-0.11.1/pygments tools/pygments @@ -50,8 +51,9 @@ if not exist build mkdir build if not exist build\%1 mkdir build\%1 if not exist build\doctrees mkdir build\doctrees +cmd /C %PYTHON% --version cmd /C %PYTHON% tools\sphinx-build.py -b%1 -dbuild\doctrees . build\%* -if "%1" EQU "htmlhelp" "%HTMLHELP%" build\htmlhelp\pydoc.hhp +if "%1" EQU "htmlhelp" "%HTMLHELP%" build\htmlhelp\python%DISTVERSION:.=%.hhp goto end :end Modified: python/branches/py3k-short-float-repr/Doc/reference/expressions.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/reference/expressions.rst (original) +++ python/branches/py3k-short-float-repr/Doc/reference/expressions.rst Mon Apr 13 18:30:54 2009 @@ -1152,6 +1152,7 @@ .. _lambdas: +.. _lambda: Lambdas ======= @@ -1176,8 +1177,6 @@ See section :ref:`function` for the syntax of parameter lists. Note that functions created with lambda forms cannot contain statements or annotations. -.. _lambda: - .. _exprlists: Modified: python/branches/py3k-short-float-repr/Doc/tools/sphinxext/susp-ignored.csv ============================================================================== --- python/branches/py3k-short-float-repr/Doc/tools/sphinxext/susp-ignored.csv (original) +++ python/branches/py3k-short-float-repr/Doc/tools/sphinxext/susp-ignored.csv Mon Apr 13 18:30:54 2009 @@ -48,6 +48,8 @@ library/httplib,,:port,host:port library/imaplib,,:MM,"""DD-Mmm-YYYY HH:MM:SS +HHMM""" library/imaplib,,:SS,"""DD-Mmm-YYYY HH:MM:SS +HHMM""" +library/itertools,,:stop,elements from seq[start:stop:step] +library/itertools,,:step,elements from seq[start:stop:step] library/linecache,,:sys,"sys:x:3:3:sys:/dev:/bin/sh" library/logging,,:And, library/logging,,:package1, Modified: python/branches/py3k-short-float-repr/Doc/whatsnew/2.7.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/whatsnew/2.7.rst (original) +++ python/branches/py3k-short-float-repr/Doc/whatsnew/2.7.rst Mon Apr 13 18:30:54 2009 @@ -88,6 +88,22 @@ Some smaller changes made to the core Python language are: +* :meth:`str.format` method now supports automatic numbering of the replacement + fields. This makes using :meth:`str.format` more closely resemble using + ``%s`` formatting:: + + >>> '{}:{}:{}'.format(2009, 04, 'Sunday') + '2009:4:Sunday' + >>> '{}:{}:{day}'.format(2009, 4, day='Sunday') + '2009:4:Sunday' + + The auto-numbering takes the fields from left to right, so the first ``{...}`` + specifier will use the first argument to :meth:`str.format`, the next + specifier will use the next argument, and so on. You can't mix auto-numbering + and explicit numbering -- either number all of your specifier fields or none + of them -- but you can mix auto-numbering and named fields, as in the second + example above. (Contributed by XXX; :issue`5237`.) + * The :func:`int` and :func:`long` types gained a ``bit_length`` method that returns the number of bits necessary to represent its argument in binary:: @@ -106,7 +122,7 @@ (Contributed by Fredrik Johansson and Victor Stinner; :issue:`3439`.) * The :class:`bytearray` type's :meth:`translate` method will - now accept None as its first argument. (Fixed by Georg Brandl; + now accept ``None`` as its first argument. (Fixed by Georg Brandl; :issue:`4759`.) .. ====================================================================== @@ -201,7 +217,7 @@ management protocol, so you can write ``with bz2.BZ2File(...) as f: ...``. (Contributed by Hagen Fuerstenau; :issue:`3860`.) -* A new :class:`Counter` class in the :mod:`collections` module is +* New class: the :class:`Counter` class in the :mod:`collections` module is useful for tallying data. :class:`Counter` instances behave mostly like dictionaries but return zero for missing keys instead of raising a :exc:`KeyError`:: @@ -236,7 +252,7 @@ Contributed by Raymond Hettinger; :issue:`1696199`. The :class:`namedtuple` class now has an optional *rename* parameter. - If *rename* is True, field names that are invalid because they've + If *rename* is true, field names that are invalid because they've been repeated or that aren't legal Python identifiers will be renamed to legal names that are derived from the field's position within the list of fields: @@ -247,8 +263,13 @@ (Added by Raymond Hettinger; :issue:`1818`.) + The :class:`deque` data type now exposes its maximum length as the + read-only :attr:`maxlen` attribute. (Added by Raymond Hettinger.) + * In Distutils, :func:`distutils.sdist.add_defaults` now uses *package_dir* and *data_files* to create the MANIFEST file. + :mod:`distutils.sysconfig` will now read the :envvar:`AR` + environment variable. It is no longer mandatory to store clear-text passwords in the :file:`.pypirc` file when registering and uploading packages to PyPI. As long @@ -256,6 +277,12 @@ prompt for the password if not present. (Added by Tarek Ziade, based on an initial contribution by Nathan Van Gheem; :issue:`4394`.) + A Distutils setup can now specify that a C extension is optional by + setting the *optional* option setting to true. If this optional is + supplied, failure to build the extension will not abort the build + process, but instead simply not install the failing extension. + (Contributed by Georg Brandl; :issue:`5583`.) + * New method: the :class:`Decimal` class gained a :meth:`from_float` class method that performs an exact conversion of a floating-point number to a :class:`Decimal`. @@ -267,8 +294,8 @@ ``Decimal('0.1000000000000000055511151231257827021181583404541015625')``. (Implemented by Raymond Hettinger; :issue:`4796`.) -* A new function in the :mod:`gc` module, :func:`is_tracked`, returns - True if a given instance is tracked by the garbage collector, False +* New function: the :mod:`gc` module's :func:`is_tracked` returns + true if a given instance is tracked by the garbage collector, false otherwise. (Contributed by Antoine Pitrou; :issue:`4688`.) * The :mod:`gzip` module's :class:`GzipFile` now supports the context @@ -284,7 +311,7 @@ * New function: ``itertools.compress(*data*, *selectors*)`` takes two iterators. Elements of *data* are returned if the corresponding - value in *selectors* is True:: + value in *selectors* is true:: itertools.compress('ABCDEF', [1,0,1,0,1,1]) => A, C, E, F @@ -322,12 +349,22 @@ with any object literal that decodes to a list of pairs. (Contributed by Raymond Hettinger; :issue:`5381`.) +* The :mod:`multiprocessing` module's :class:`Manager*` classes + can now be passed a callable that will be called whenever + a subprocess is started, along with a set of arguments that will be + passed to the callable. + (Contributed by lekma; :issue:`5585`.) + * The :mod:`pydoc` module now has help for the various symbols that Python uses. You can now do ``help('<<')`` or ``help('@')``, for example. (Contributed by David Laban; :issue:`4739`.) -* A new function in the :mod:`subprocess` module, - :func:`check_output`, runs a command with a specified set of arguments +* The :mod:`re` module's :func:`split`, :func:`sub`, and :func:`subn` + now accept an optional *flags* argument, for consistency with the + other functions in the module. (Added by Gregory P. Smith.) + +* New function: the :mod:`subprocess` module's + :func:`check_output` runs a command with a specified set of arguments and returns the command's output as a string when the command runs without error, or raises a :exc:`CalledProcessError` exception otherwise. @@ -343,26 +380,99 @@ (Contributed by Gregory P. Smith.) +* New function: :func:`is_declared_global` in the :mod:`symtable` module + returns true for variables that are explicitly declared to be global, + false for ones that are implicitly global. + (Contributed by Jeremy Hylton.) + * The ``sys.version_info`` value is now a named tuple, with attributes named ``major``, ``minor``, ``micro``, ``releaselevel``, and ``serial``. (Contributed by Ross Light; :issue:`4285`.) +* The :mod:`threading` module's :meth:`Event.wait` method now returns + the internal flag on exit. This means the method will usually + return true because :meth:`wait` is supposed to block until the + internal flag becomes true. The return value will only be false if + a timeout was provided and the operation timed out. + (Contributed by XXX; :issue:`1674032`.) + * The :mod:`unittest` module was enhanced in several ways. + The progress messages will now show 'x' for expected failures + and 'u' for unexpected successes when run in verbose mode. + (Contributed by Benjamin Peterson.) Test cases can raise the :exc:`SkipTest` exception to skip a test. (:issue:`1034053`.) - It will now use 'x' for expected failures - and 'u' for unexpected successes when run in its verbose mode. - (Contributed by Benjamin Peterson.) + + The error messages for :meth:`assertEqual`, + :meth:`assertTrue`, and :meth:`assertFalse` + failures now provide more information. If you set the + :attr:`longMessage` attribute of your :class:`TestCase` classes to + true, both the standard error message and any additional message you + provide will be printed for failures. (Added by Michael Foord; :issue:`5663`.) The :meth:`assertRaises` and :meth:`failUnlessRaises` methods now return a context handler when called without providing a callable object to run. For example, you can write this:: - with self.assertRaises(KeyError): - raise ValueError + with self.assertRaises(KeyError): + raise ValueError (Implemented by Antoine Pitrou; :issue:`4444`.) + A number of new methods were added that provide more specialized + tests. Many of these methods were written by Google engineers + for use in their test suites; Gregory P. Smith, Michael Foord, and + GvR worked on merging them into Python's version of :mod:`unittest`. + + * :meth:`assertIsNone` and :meth:`assertIsNotNone` take one + expression and verify that the result is or is not ``None``. + + * :meth:`assertIs` and :meth:`assertIsNot` take two values and check + whether the two values evaluate to the same object or not. + (Added by Michael Foord; :issue:`2578`.) + + * :meth:`assertGreater`, :meth:`assertGreaterEqual`, + :meth:`assertLess`, and :meth:`assertLessEqual` compare + two quantities. + + * :meth:`assertMultiLineEqual` compares two strings, and if they're + not equal, displays a helpful comparison that highlights the + differences in the two strings. + + * :meth:`assertRegexpMatches` checks whether its first argument is a + string matching a regular expression provided as its second argument. + + * :meth:`assertRaisesRegexp` checks whether a particular exception + is raised, and then also checks that the string representation of + the exception matches the provided regular expression. + + * :meth:`assertIn` and :meth:`assertNotIn` tests whether + *first* is or is not in *second*. + + * :meth:`assertSameElements` tests whether two provided sequences + contain the same elements. + + * :meth:`assertSetEqual` compares whether two sets are equal, and + only reports the differences between the sets in case of error. + + * Similarly, :meth:`assertListEqual` and :meth:`assertTupleEqual` + compare the specified types and explain the differences. + More generally, :meth:`assertSequenceEqual` compares two sequences + and can optionally check whether both sequences are of a + particular type. + + * :meth:`assertDictEqual` compares two dictionaries and reports the + differences. :meth:`assertDictContainsSubset` checks whether + all of the key/value pairs in *first* are found in *second*. + + * A new hook, :meth:`addTypeEqualityFunc` takes a type object and a + function. The :meth:`assertEqual` method will use the function + when both of the objects being compared are of the specified type. + This function should compare the two objects and raise an + exception if they don't match; it's a good idea for the function + to provide additional information about why the two objects are + matching, much as the new sequence comparison methods do. + * The :func:`is_zipfile` function in the :mod:`zipfile` module will now accept a file object, in addition to the path names accepted in earlier versions. (Contributed by Gabriel Genellina; :issue:`4756`.) @@ -376,7 +486,37 @@ importlib: Importing Modules ------------------------------ -XXX write this +Python 3.1 includes the :mod:`importlib` package, a re-implementation +of the logic underlying Python's :keyword:`import` statement. +:mod:`importlib` is useful for implementors of Python interpreters and +to user who wish to write new importers that can participate in the +import process. Python 2.7 doesn't contain the complete +:mod:`importlib` package, but instead has a tiny subset that contains +a single function, :func:`import_module`. + +``import_module(*name*, *package*=None)`` imports a module. *name* is +a string containing the module or package's name. It's possible to do +relative imports by providing a string that begins with a ``.`` +character, such as ``..utils.errors``. For relative imports, the +*package* argument must be provided and is the name of the package that +will be used as the anchor for +the relative import. :func:`import_module` both inserts the imported +module into ``sys.modules`` and returns the module object. + +Here are some examples:: + + >>> from importlib import import_module + >>> anydbm = import_module('anydbm') # Standard absolute import + >>> anydbm + + >>> # Relative import + >>> sysconfig = import_module('..sysconfig', 'distutils.command') + >>> sysconfig + + +:mod:`importlib` was implemented by Brett Cannon and introduced in +Python 3.1. + ttk: Themed Widgets for Tk -------------------------- Modified: python/branches/py3k-short-float-repr/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k-short-float-repr/Doc/whatsnew/3.1.rst Mon Apr 13 18:30:54 2009 @@ -2,8 +2,6 @@ What's New In Python 3.1 **************************** -.. XXX Add trademark info for Apple, Microsoft. - :Author: Raymond Hettinger :Release: |release| :Date: |today| @@ -17,8 +15,7 @@ * The maintainer will go through Misc/NEWS periodically and add changes; it's therefore more important to add your changes to - Misc/NEWS than to this file. (Note: I didn't get to this for 3.0. - GvR.) + Misc/NEWS than to this file. * This is not a complete list of every single change; completeness is the purpose of Misc/NEWS. Some changes I consider too small @@ -39,8 +36,7 @@ necessary (especially when a final release is some months away). * Credit the author of a patch or bugfix. Just the name is - sufficient; the e-mail address isn't necessary. (Due to time - constraints I haven't managed to do this for 3.0. GvR.) + sufficient; the e-mail address isn't necessary. * It's helpful to add the bug/patch number as a comment: @@ -50,21 +46,10 @@ (Contributed by P.Y. Developer.) This saves the maintainer the effort of going through the SVN log - when researching a change. (Again, I didn't get to this for 3.0. - GvR.) + when researching a change. This article explains the new features in Python 3.1, compared to 3.0. -.. Compare with previous release in 2 - 3 sentences here. -.. add hyperlink when the documentation becomes available online. - -.. ====================================================================== -.. Large, PEP-level features and changes should be described here. -.. Should there be a new section here for 3k migration? -.. Or perhaps a more general section describing module changes/deprecation? -.. sets module deprecated -.. ====================================================================== - PEP 372: Ordered Dictionaries ============================= @@ -88,7 +73,7 @@ returns an ordered dictionary with the values appearing in the same order as the underlying tuple indicies. The :mod:`json` module is being built-out with an *object_pairs_hook* to allow OrderedDicts to be built by the decoder. -Support was also added for third-party tools like PyYAML. +Support was also added for third-party tools like `PyYAML `_. .. seealso:: @@ -96,6 +81,7 @@ PEP written by Armin Ronacher and Raymond Hettinger. Implementation written by Raymond Hettinger. + PEP 378: Format Specifier for Thousands Separator ================================================= @@ -162,7 +148,6 @@ (Contributed by Mark Dickinson; :issue:`4707`.) -.. ====================================================================== New, Improved, and Deprecated Modules ===================================== @@ -179,8 +164,7 @@ The basic idea of ttk is to separate, to the extent possible, the code implementing a widget's behavior from the code implementing its appearance. - (Contributed by Kevin Walzer and Guilherme Polo; :issue:`2618` and - :issue:`2983`.) + (Contributed by Guilherme Polo; :issue:`2983`.) * The :class:`gzip.GzipFile` and :class:`bz2.BZ2File` classes now support the context manager protocol:: @@ -191,7 +175,7 @@ (Contributed by Antoine Pitrou.) -* The :mod:`decimal.Decimal` module now supports methods for creating a +* The :mod:`decimal` module now supports methods for creating a decimal object from a binary :class:`float`. The conversion is exact but can sometimes be surprising:: @@ -229,7 +213,18 @@ *rename* which lets invalid fieldnames be automatically converted to positional names in the form _0, _1, etc. This is useful when the field names are being created by an external source such as a - CSV header, SQL field list, or user input. + CSV header, SQL field list, or user input:: + + >>> query = input() + SELECT region, dept, count(*) FROM main GROUPBY region, dept + + >>> cursor.execute(query) + >>> query_fields = [desc[0] for desc in cursor.description] + >>> UserQuery = namedtuple('UserQuery', query_fields, rename=True) + >>> pprint.pprint([UserQuery(*row) for row in cursor]) + [UserQuery(region='South', dept='Shipping', _2=185), + UserQuery(region='North', dept='Accounting', _2=37), + UserQuery(region='West', dept='Sales', _2=419)] (Contributed by Raymond Hettinger; :issue:`1818`.) @@ -238,6 +233,16 @@ (Contributed by Gregory Smith.) +* The :mod:`logging` module now implements a simple :class:`NullHandler` + class for applications that are not using logging but are calling + library code that does. Setting-up a null handler will suppress + spurious warnings like "No handlers could be found for logger X.Y.Z":: + + >>> h = logging.NullHandler() + >>> logging.getLogger("foo").addHandler(h) + + (Contributed by Vinay Sajip; issue:`4384`). + * The :mod:`runpy` module which supports the ``-m`` command line switch now supports the execution of packages by looking for and executing a ``__main__`` submodule when a package name is supplied. @@ -274,7 +279,30 @@ def test_gimzo_without_required_library(self): ... - (Contributed by Benjamin Peterson.) + Also, tests for exceptions have been builtout to work with context managers:: + + def test_division_by_zero(self): + with self.assertRaises(ZeroDivisionError): + x / 0 + + In addition, several new assertion methods were added including + :func:`assertSetEqual`, :func:`assertDictEqual`, + :func:`assertDictContainsSubset`, :func:`assertListEqual`, + :func:`assertTupleEqual`, :func:`assertSequenceEqual`, + :func:`assertRaisesRegexp`, :func:`assertIsNone`, + and :func:`assertIsNotNot`. + + (Contributed by Benjamin Peterson and Antoine Pitrou.) + +* The :mod:`io` module has three new constants for the :meth:`seek` + method :data:`SEEK_SET`, :data:`SEEK_CUR`, and :data:`SEEK_END`. + +* The :attr:`sys.version_info` tuple is now a named tuple:: + + >>> sys.version_info + sys.version_info(major=3, minor=1, micro=0, releaselevel='alpha', serial=2) + + (Contributed by Ross Light; :issue:`4285`.) * A new module, :mod:`importlib` was added. It provides a complete, portable, pure Python reference implementation of the *import* statement and its @@ -284,8 +312,6 @@ (Contributed by Brett Cannon.) -.. ====================================================================== - Optimizations ============= @@ -326,7 +352,13 @@ its performance. The code is expected to be added in-time for the beta release. - (Contributed by Bob Ippolito.) + (Contributed by Bob Ippolito and converted to Py3.1 by Antoine Pitrou; + :issue:`4136`.) + +Build and C API Changes +======================= + +Changes to Python's build process and to the C API include: * Integers are now stored internally either in base 2**15 or in base 2**30, the base being determined at build time. Previously, they @@ -349,4 +381,11 @@ (Contributed by Mark Dickinson; :issue:`4258`.) -.. ====================================================================== +* The :cfunc:`PyLong_AsUnsignedLongLong()` function now handles a negative + *pylong* by raising :exc:`OverflowError` instead of :exc:`TypeError`. + + (Contributed by Mark Dickinson and Lisandro Dalcrin; :issue:`5175`.) + +* Deprecated :cfunc:`PyNumber_Int`. Use :cfunc:`PyNumber_Long` instead. + + (Contributed by Mark Dickinson; :issue:`4910`.) Modified: python/branches/py3k-short-float-repr/Include/bytes_methods.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/bytes_methods.h (original) +++ python/branches/py3k-short-float-repr/Include/bytes_methods.h Mon Apr 13 18:30:54 2009 @@ -20,6 +20,9 @@ extern void _Py_bytes_capitalize(char *result, char *s, Py_ssize_t len); extern void _Py_bytes_swapcase(char *result, char *s, Py_ssize_t len); +/* This one gets the raw argument list. */ +extern PyObject* _Py_bytes_maketrans(PyObject *args); + /* Shared __doc__ strings. */ extern const char _Py_isspace__doc__[]; extern const char _Py_isalpha__doc__[]; @@ -33,6 +36,7 @@ extern const char _Py_title__doc__[]; extern const char _Py_capitalize__doc__[]; extern const char _Py_swapcase__doc__[]; +extern const char _Py_maketrans__doc__[]; #define FLAG_LOWER 0x01 #define FLAG_UPPER 0x02 Modified: python/branches/py3k-short-float-repr/Include/object.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/object.h (original) +++ python/branches/py3k-short-float-repr/Include/object.h Mon Apr 13 18:30:54 2009 @@ -651,11 +651,13 @@ ((PyObject*)(op))->ob_refcnt++) #define Py_DECREF(op) \ - if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ - --((PyObject*)(op))->ob_refcnt != 0) \ - _Py_CHECK_REFCNT(op) \ - else \ - _Py_Dealloc((PyObject *)(op)) + do { \ + if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ + --((PyObject*)(op))->ob_refcnt != 0) \ + _Py_CHECK_REFCNT(op) \ + else \ + _Py_Dealloc((PyObject *)(op)); \ + } while (0) /* Safely decref `op` and set `op` to NULL, especially useful in tp_clear * and tp_dealloc implementatons. @@ -701,8 +703,8 @@ } while (0) /* Macros to use in case the object pointer may be NULL: */ -#define Py_XINCREF(op) if ((op) == NULL) ; else Py_INCREF(op) -#define Py_XDECREF(op) if ((op) == NULL) ; else Py_DECREF(op) +#define Py_XINCREF(op) do { if ((op) == NULL) ; else Py_INCREF(op); } while (0) +#define Py_XDECREF(op) do { if ((op) == NULL) ; else Py_DECREF(op); } while (0) /* These are provided as conveniences to Python runtime embedders, so that Modified: python/branches/py3k-short-float-repr/Lib/asyncore.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/asyncore.py (original) +++ python/branches/py3k-short-float-repr/Lib/asyncore.py Mon Apr 13 18:30:54 2009 @@ -68,10 +68,12 @@ class ExitNow(Exception): pass +_reraised_exceptions = (ExitNow, KeyboardInterrupt, SystemExit) + def read(obj): try: obj.handle_read_event() - except (ExitNow, KeyboardInterrupt, SystemExit): + except _reraised_exceptions: raise except: obj.handle_error() @@ -79,7 +81,7 @@ def write(obj): try: obj.handle_write_event() - except (ExitNow, KeyboardInterrupt, SystemExit): + except _reraised_exceptions: raise except: obj.handle_error() @@ -87,22 +89,22 @@ def _exception(obj): try: obj.handle_expt_event() - except (ExitNow, KeyboardInterrupt, SystemExit): + except _reraised_exceptions: raise except: obj.handle_error() def readwrite(obj, flags): try: - if flags & (select.POLLIN | select.POLLPRI): + if flags & select.POLLIN: obj.handle_read_event() if flags & select.POLLOUT: obj.handle_write_event() - if flags & (select.POLLERR | select.POLLNVAL): - obj.handle_expt_event() - if flags & select.POLLHUP: + if flags & (select.POLLHUP | select.POLLERR | select.POLLNVAL): obj.handle_close() - except (ExitNow, KeyboardInterrupt, SystemExit): + if flags & select.POLLPRI: + obj.handle_expt_event() + except _reraised_exceptions: raise except: obj.handle_error() @@ -210,6 +212,7 @@ accepting = False closing = False addr = None + ignore_log_types = frozenset(['warning']) def __init__(self, sock=None, map=None): if map is None: @@ -397,7 +400,7 @@ sys.stderr.write('log: %s\n' % str(message)) def log_info(self, message, type='info'): - if __debug__ or type != 'info': + if type not in self.ignore_log_types: print('%s: %s' % (type, message)) def handle_read_event(self): @@ -431,22 +434,17 @@ self.handle_write() def handle_expt_event(self): - # if the handle_expt is the same default worthless method, - # we'll not even bother calling it, we'll instead generate - # a useful error - x = True - try: - y1 = self.handle_expt.__func__ - y2 = dispatcher.handle_expt - x = y1 is y2 - except AttributeError: - pass - - if x: - err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) - msg = _strerror(err) - - raise socket.error(err, msg) + # handle_expt_event() is called if there might be an error on the + # socket, or if there is OOB data + # check for the error condition first + err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) + if err != 0: + # we can get here when select.select() says that there is an + # exceptional condition on the socket + # since there is an error, we'll go ahead and close the socket + # like we would in a subclassed handle_read() that received no + # data + self.handle_close() else: self.handle_expt() @@ -471,7 +469,7 @@ self.handle_close() def handle_expt(self): - self.log_info('unhandled exception', 'warning') + self.log_info('unhandled incoming priority event', 'warning') def handle_read(self): self.log_info('unhandled read event', 'warning') @@ -552,7 +550,7 @@ pass elif not ignore_all: raise - except (ExitNow, KeyboardInterrupt, SystemExit): + except _reraised_exceptions: raise except: if not ignore_all: Modified: python/branches/py3k-short-float-repr/Lib/cgitb.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/cgitb.py (original) +++ python/branches/py3k-short-float-repr/Lib/cgitb.py Mon Apr 13 18:30:54 2009 @@ -142,10 +142,11 @@ i = lnum - index for line in lines: num = small(' ' * (5-len(str(i))) + str(i)) + ' ' - line = '%s%s' % (num, pydoc.html.preformat(line)) if i in highlight: + line = '=>%s%s' % (num, pydoc.html.preformat(line)) rows.append('' % line) else: + line = '  %s%s' % (num, pydoc.html.preformat(line)) rows.append('' % grey(line)) i += 1 Modified: python/branches/py3k-short-float-repr/Lib/collections.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/collections.py (original) +++ python/branches/py3k-short-float-repr/Lib/collections.py Mon Apr 13 18:30:54 2009 @@ -36,6 +36,11 @@ # Those hard references disappear when a key is deleted from an OrderedDict. def __init__(self, *args, **kwds): + '''Initialize an ordered dictionary. Signature is the same as for + regular dictionaries, but keyword arguments are not recommended + because their insertion order is arbitrary. + + ''' if len(args) > 1: raise TypeError('expected at most 1 arguments, got %d' % len(args)) try: @@ -47,12 +52,14 @@ self.update(*args, **kwds) def clear(self): + 'od.clear() -> None. Remove all items from od.' root = self.__root root.prev = root.next = root self.__map.clear() dict.clear(self) def __setitem__(self, key, value): + 'od.__setitem__(i, y) <==> od[i]=y' # Setting a new item creates a new link which goes at the end of the linked # list, and the inherited dictionary is updated with the new key/value pair. if key not in self: @@ -64,6 +71,7 @@ dict.__setitem__(self, key, value) def __delitem__(self, key): + 'od.__delitem__(y) <==> del od[y]' # Deleting an existing item uses self.__map to find the link which is # then removed by updating the links in the predecessor and successor nodes. dict.__delitem__(self, key) @@ -72,6 +80,7 @@ link.next.prev = link.prev def __iter__(self): + 'od.__iter__() <==> iter(od)' # Traverse the linked list in order. root = self.__root curr = root.next @@ -80,6 +89,7 @@ curr = curr.next def __reversed__(self): + 'od.__reversed__() <==> reversed(od)' # Traverse the linked list in reverse order. root = self.__root curr = root.prev @@ -88,6 +98,7 @@ curr = curr.prev def __reduce__(self): + 'Return state information for pickling' items = [[k, self[k]] for k in self] tmp = self.__map, self.__root del self.__map, self.__root @@ -105,34 +116,52 @@ items = MutableMapping.items def popitem(self, last=True): + '''od.popitem() -> (k, v), return and remove a (key, value) pair. + Pairs are returned in LIFO order if last is true or FIFO order if false. + + ''' if not self: raise KeyError('dictionary is empty') - key = next(reversed(self)) if last else next(iter(self)) + key = next(reversed(self) if last else iter(self)) value = self.pop(key) return key, value def __repr__(self): + 'od.__repr__() <==> repr(od)' if not self: return '%s()' % (self.__class__.__name__,) return '%s(%r)' % (self.__class__.__name__, list(self.items())) def copy(self): + 'od.copy() -> a shallow copy of od' return self.__class__(self) @classmethod def fromkeys(cls, iterable, value=None): + '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S + and values equal to v (which defaults to None). + + ''' d = cls() for key in iterable: d[key] = value return d def __eq__(self, other): + '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' if isinstance(other, OrderedDict): return len(self)==len(other) and \ all(p==q for p, q in zip(self.items(), other.items())) return dict.__eq__(self, other) def __ne__(self, other): + '''od.__ne__(y) <==> od!=y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' return not self == other Modified: python/branches/py3k-short-float-repr/Lib/distutils/command/__init__.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/command/__init__.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/command/__init__.py Mon Apr 13 18:30:54 2009 @@ -22,6 +22,8 @@ 'bdist_dumb', 'bdist_rpm', 'bdist_wininst', + 'check', + 'upload', # These two are reserved for future use: #'bdist_sdux', #'bdist_pkgtool', Modified: python/branches/py3k-short-float-repr/Lib/distutils/command/bdist_wininst.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/command/bdist_wininst.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/command/bdist_wininst.py Mon Apr 13 18:30:54 2009 @@ -330,9 +330,14 @@ directory = os.path.dirname(__file__) # we must use a wininst-x.y.exe built with the same C compiler # used for python. XXX What about mingw, borland, and so on? - if self.plat_name == 'win32': - sfix = '' + + # if plat_name starts with "win" but is not "win32" + # we want to strip "win" and leave the rest (e.g. -amd64) + # for all other cases, we don't want any suffix + if self.plat_name != 'win32' and self.plat_name[:3] == 'win': + sfix = self.plat_name[3:] else: - sfix = self.plat_name[3:] # strip 'win' - leaves eg '-amd64' + sfix = '' + filename = os.path.join(directory, "wininst-%.1f%s.exe" % (bv, sfix)) return open(filename, "rb").read() Modified: python/branches/py3k-short-float-repr/Lib/distutils/command/config.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/command/config.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/command/config.py Mon Apr 13 18:30:54 2009 @@ -12,6 +12,7 @@ __revision__ = "$Id$" import sys, os, re + from distutils.core import Command from distutils.errors import DistutilsExecError from distutils.sysconfig import customize_compiler @@ -53,8 +54,6 @@ self.compiler = None self.cc = None self.include_dirs = None - #self.define = None - #self.undef = None self.libraries = None self.library_dirs = None @@ -136,8 +135,8 @@ self.compiler.compile([src], include_dirs=include_dirs) return (src, obj) - def _link(self, body, headers, include_dirs, libraries, - library_dirs, lang): + def _link(self, body, headers, include_dirs, libraries, library_dirs, + lang): (src, obj) = self._compile(body, headers, include_dirs, lang) prog = os.path.splitext(os.path.basename(src))[0] self.compiler.link_executable([obj], prog, @@ -191,8 +190,8 @@ self._clean() return ok - def search_cpp(self, pattern, body=None, headers=None, - include_dirs=None, lang="c"): + def search_cpp(self, pattern, body=None, headers=None, include_dirs=None, + lang="c"): """Construct a source file (just like 'try_cpp()'), run it through the preprocessor, and return true if any line of the output matches 'pattern'. 'pattern' should either be a compiled regex object or a @@ -200,9 +199,8 @@ preprocesses an empty file -- which can be useful to determine the symbols the preprocessor and compiler set by default. """ - self._check_compiler() - (src, out) = self._preprocess(body, headers, include_dirs, lang) + src, out = self._preprocess(body, headers, include_dirs, lang) if isinstance(pattern, str): pattern = re.compile(pattern) @@ -237,8 +235,8 @@ self._clean() return ok - def try_link(self, body, headers=None, include_dirs=None, - libraries=None, library_dirs=None, lang="c"): + def try_link(self, body, headers=None, include_dirs=None, libraries=None, + library_dirs=None, lang="c"): """Try to compile and link a source file, built from 'body' and 'headers', to executable form. Return true on success, false otherwise. @@ -256,8 +254,8 @@ self._clean() return ok - def try_run(self, body, headers=None, include_dirs=None, - libraries=None, library_dirs=None, lang="c"): + def try_run(self, body, headers=None, include_dirs=None, libraries=None, + library_dirs=None, lang="c"): """Try to compile, link to an executable, and run a program built from 'body' and 'headers'. Return true on success, false otherwise. @@ -336,11 +334,16 @@ def dump_file(filename, head=None): + """Dumps a file content into log.info. + + If head is not None, will be dumped before the file content. + """ if head is None: - print(filename + ":") + log.info('%s' % filename) else: - print(head) - + log.info(head) file = open(filename) - sys.stdout.write(file.read()) - file.close() + try: + log.info(file.read()) + finally: + file.close() Copied: python/branches/py3k-short-float-repr/Lib/distutils/tests/test_config_cmd.py (from r71541, /python/branches/py3k/Lib/distutils/tests/test_config_cmd.py) ============================================================================== --- /python/branches/py3k/Lib/distutils/tests/test_config_cmd.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/tests/test_config_cmd.py Mon Apr 13 18:30:54 2009 @@ -1,6 +1,7 @@ """Tests for distutils.command.config.""" import unittest import os +import sys from distutils.command.config import dump_file, config from distutils.tests import support @@ -36,6 +37,8 @@ self.assertEquals(len(self._logs), numlines+1) def test_search_cpp(self): + if sys.platform == 'win32': + return pkg_dir, dist = self.create_dist() cmd = config(dist) Modified: python/branches/py3k-short-float-repr/Lib/distutils/tests/test_util.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/tests/test_util.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/tests/test_util.py Mon Apr 13 18:30:54 2009 @@ -5,6 +5,7 @@ import os import sys import unittest +from copy import copy from distutils.errors import DistutilsPlatformError @@ -17,6 +18,7 @@ from distutils.util import rfc822_escape from distutils import util # used to patch _environ_checked +from distutils.sysconfig import get_config_vars, _config_vars class utilTestCase(unittest.TestCase): @@ -30,6 +32,7 @@ self.join = os.path.join self.isabs = os.path.isabs self.splitdrive = os.path.splitdrive + self._config_vars = copy(_config_vars) # patching os.uname if hasattr(os, 'uname'): @@ -42,7 +45,7 @@ os.uname = self._get_uname def tearDown(self): - # getting back tne environment + # getting back the environment os.name = self.name sys.platform = self.platform sys.version = self.version @@ -55,6 +58,7 @@ os.uname = self.uname else: del os.uname + _config_vars = copy(self._config_vars) def _set_uname(self, uname): self._uname = uname @@ -96,8 +100,34 @@ 'root:xnu-792.25.20~1/RELEASE_I386'), 'i386')) os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.3' + get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g ' + '-fwrapv -O3 -Wall -Wstrict-prototypes') + self.assertEquals(get_platform(), 'macosx-10.3-i386') + # macbook with fat binaries (fat, universal or fat64) + os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.4' + get_config_vars()['CFLAGS'] = ('-arch ppc -arch i386 -isysroot ' + '/Developer/SDKs/MacOSX10.4u.sdk ' + '-fno-strict-aliasing -fno-common ' + '-dynamic -DNDEBUG -g -O3') + + self.assertEquals(get_platform(), 'macosx-10.4-fat') + + get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch i386 -isysroot ' + '/Developer/SDKs/MacOSX10.4u.sdk ' + '-fno-strict-aliasing -fno-common ' + '-dynamic -DNDEBUG -g -O3') + + self.assertEquals(get_platform(), 'macosx-10.4-universal') + + get_config_vars()['CFLAGS'] = ('-arch x86_64 -isysroot ' + '/Developer/SDKs/MacOSX10.4u.sdk ' + '-fno-strict-aliasing -fno-common ' + '-dynamic -DNDEBUG -g -O3') + + self.assertEquals(get_platform(), 'macosx-10.4-fat64') + # linux debian sarge os.name = 'posix' sys.version = ('2.3.5 (#1, Jul 4 2007, 17:28:59) ' Modified: python/branches/py3k-short-float-repr/Lib/http/server.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/http/server.py (original) +++ python/branches/py3k-short-float-repr/Lib/http/server.py Mon Apr 13 18:30:54 2009 @@ -773,6 +773,46 @@ # Utilities for CGIHTTPRequestHandler +# TODO(gregory.p.smith): Move this into an appropriate library. +def _url_collapse_path_split(path): + """ + Given a URL path, remove extra '/'s and '.' path elements and collapse + any '..' references. + + Implements something akin to RFC-2396 5.2 step 6 to parse relative paths. + + Returns: A tuple of (head, tail) where tail is everything after the final / + and head is everything before it. Head will always start with a '/' and, + if it contains anything else, never have a trailing '/'. + + Raises: IndexError if too many '..' occur within the path. + """ + # Similar to os.path.split(os.path.normpath(path)) but specific to URL + # path semantics rather than local operating system semantics. + path_parts = [] + for part in path.split('/'): + if part == '.': + path_parts.append('') + else: + path_parts.append(part) + # Filter out blank non trailing parts before consuming the '..'. + path_parts = [part for part in path_parts[:-1] if part] + path_parts[-1:] + if path_parts: + tail_part = path_parts.pop() + else: + tail_part = '' + head_parts = [] + for part in path_parts: + if part == '..': + head_parts.pop() + else: + head_parts.append(part) + if tail_part and tail_part == '..': + head_parts.pop() + tail_part = '' + return ('/' + '/'.join(head_parts), tail_part) + + nobody = None def nobody_uid(): @@ -839,24 +879,20 @@ def is_cgi(self): """Test whether self.path corresponds to a CGI script. - Return a tuple (dir, rest) if self.path requires running a - CGI script, None if not. Note that rest begins with a - slash if it is not empty. - - The default implementation tests whether the path - begins with one of the strings in the list - self.cgi_directories (and the next character is a '/' - or the end of the string). + Returns True and updates the cgi_info attribute to the tuple + (dir, rest) if self.path requires running a CGI script. + Returns False otherwise. + + The default implementation tests whether the normalized url + path begins with one of the strings in self.cgi_directories + (and the next character is a '/' or the end of the string). """ - path = self.path - - for x in self.cgi_directories: - i = len(x) - if path[:i] == x and (not path[i:] or path[i] == '/'): - self.cgi_info = path[:i], path[i+1:] - return True + splitpath = _url_collapse_path_split(self.path) + if splitpath[0] in self.cgi_directories: + self.cgi_info = splitpath + return True return False cgi_directories = ['/cgi-bin', '/htbin'] Modified: python/branches/py3k-short-float-repr/Lib/multiprocessing/managers.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/multiprocessing/managers.py (original) +++ python/branches/py3k-short-float-repr/Lib/multiprocessing/managers.py Mon Apr 13 18:30:54 2009 @@ -478,12 +478,15 @@ dispatch(conn, None, 'dummy') self._state.value = State.STARTED - def start(self): + def start(self, initializer=None, initargs=()): ''' Spawn a server process for this manager object ''' assert self._state.value == State.INITIAL + if initializer is not None and not hasattr(initializer, '__call__'): + raise TypeError('initializer must be a callable') + # pipe over which we will retrieve address of server reader, writer = connection.Pipe(duplex=False) @@ -491,7 +494,7 @@ self._process = Process( target=type(self)._run_server, args=(self._registry, self._address, self._authkey, - self._serializer, writer), + self._serializer, writer, initializer, initargs), ) ident = ':'.join(str(i) for i in self._process._identity) self._process.name = type(self).__name__ + '-' + ident @@ -512,10 +515,14 @@ ) @classmethod - def _run_server(cls, registry, address, authkey, serializer, writer): + def _run_server(cls, registry, address, authkey, serializer, writer, + initializer=None, initargs=()): ''' Create a server, report its address and run it ''' + if initializer is not None: + initializer(*initargs) + # create server server = cls._Server(registry, address, authkey, serializer) Modified: python/branches/py3k-short-float-repr/Lib/multiprocessing/pool.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/multiprocessing/pool.py (original) +++ python/branches/py3k-short-float-repr/Lib/multiprocessing/pool.py Mon Apr 13 18:30:54 2009 @@ -92,6 +92,9 @@ except NotImplementedError: processes = 1 + if initializer is not None and not hasattr(initializer, '__call__'): + raise TypeError('initializer must be a callable') + self._pool = [] for i in range(processes): w = self.Process( Modified: python/branches/py3k-short-float-repr/Lib/plistlib.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/plistlib.py (original) +++ python/branches/py3k-short-float-repr/Lib/plistlib.py Mon Apr 13 18:30:54 2009 @@ -1,4 +1,4 @@ -"""plistlib.py -- a tool to generate and parse MacOSX .plist files. +r"""plistlib.py -- a tool to generate and parse MacOSX .plist files. The PropertList (.plist) file format is a simple XML pickle supporting basic object types, like dictionaries, lists, numbers and strings. Modified: python/branches/py3k-short-float-repr/Lib/posixpath.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/posixpath.py (original) +++ python/branches/py3k-short-float-repr/Lib/posixpath.py Mon Apr 13 18:30:54 2009 @@ -257,7 +257,10 @@ userhome = pwent.pw_dir if isinstance(path, bytes): userhome = userhome.encode(sys.getfilesystemencoding()) - userhome = userhome.rstrip(sep) + root = b'/' + else: + root = '/' + userhome = userhome.rstrip(root) or userhome return userhome + path[i:] Modified: python/branches/py3k-short-float-repr/Lib/pydoc.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/pydoc.py (original) +++ python/branches/py3k-short-float-repr/Lib/pydoc.py Mon Apr 13 18:30:54 2009 @@ -414,9 +414,10 @@ def page(self, title, contents): """Format an HTML page.""" - return ''' - + return '''\ +Python: %s + %s ''' % (title, contents) @@ -1510,7 +1511,7 @@ try: object, name = resolve(thing, forceload) page = html.page(describe(object), html.document(object, name)) - file = open(name + '.html', 'w') + file = open(name + '.html', 'w', encoding='utf-8') file.write(page) file.close() print('wrote', name + '.html') Modified: python/branches/py3k-short-float-repr/Lib/socket.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/socket.py (original) +++ python/branches/py3k-short-float-repr/Lib/socket.py Mon Apr 13 18:30:54 2009 @@ -52,7 +52,7 @@ except ImportError: EBADF = 9 -__all__ = ["getfqdn"] +__all__ = ["getfqdn", "create_connection"] __all__.extend(os._get_exports_list(_socket)) Modified: python/branches/py3k-short-float-repr/Lib/string.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/string.py (original) +++ python/branches/py3k-short-float-repr/Lib/string.py Mon Apr 13 18:30:54 2009 @@ -49,6 +49,9 @@ mapped to the byte at the same position in to. The strings frm and to must be of the same length. """ + import warnings + warnings.warn("string.maketrans is deprecated, use bytes.maketrans instead", + DeprecationWarning) if len(frm) != len(to): raise ValueError("maketrans arguments must have same length") if not (isinstance(frm, bytes) and isinstance(to, bytes)): Modified: python/branches/py3k-short-float-repr/Lib/telnetlib.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/telnetlib.py (original) +++ python/branches/py3k-short-float-repr/Lib/telnetlib.py Mon Apr 13 18:30:54 2009 @@ -47,87 +47,87 @@ TELNET_PORT = 23 # Telnet protocol characters (don't change) -IAC = 255 # "Interpret As Command" -DONT = 254 -DO = 253 -WONT = 252 -WILL = 251 -theNULL = 0 - -SE = 240 # Subnegotiation End -NOP = 241 # No Operation -DM = 242 # Data Mark -BRK = 243 # Break -IP = 244 # Interrupt process -AO = 245 # Abort output -AYT = 246 # Are You There -EC = 247 # Erase Character -EL = 248 # Erase Line -GA = 249 # Go Ahead -SB = 250 # Subnegotiation Begin +IAC = bytes([255]) # "Interpret As Command" +DONT = bytes([254]) +DO = bytes([253]) +WONT = bytes([252]) +WILL = bytes([251]) +theNULL = bytes([0]) + +SE = bytes([240]) # Subnegotiation End +NOP = bytes([241]) # No Operation +DM = bytes([242]) # Data Mark +BRK = bytes([243]) # Break +IP = bytes([244]) # Interrupt process +AO = bytes([245]) # Abort output +AYT = bytes([246]) # Are You There +EC = bytes([247]) # Erase Character +EL = bytes([248]) # Erase Line +GA = bytes([249]) # Go Ahead +SB = bytes([250]) # Subnegotiation Begin # Telnet protocol options code (don't change) # These ones all come from arpa/telnet.h -BINARY = 0 # 8-bit data path -ECHO = 1 # echo -RCP = 2 # prepare to reconnect -SGA = 3 # suppress go ahead -NAMS = 4 # approximate message size -STATUS = 5 # give status -TM = 6 # timing mark -RCTE = 7 # remote controlled transmission and echo -NAOL = 8 # negotiate about output line width -NAOP = 9 # negotiate about output page size -NAOCRD = 10 # negotiate about CR disposition -NAOHTS = 11 # negotiate about horizontal tabstops -NAOHTD = 12 # negotiate about horizontal tab disposition -NAOFFD = 13 # negotiate about formfeed disposition -NAOVTS = 14 # negotiate about vertical tab stops -NAOVTD = 15 # negotiate about vertical tab disposition -NAOLFD = 16 # negotiate about output LF disposition -XASCII = 17 # extended ascii character set -LOGOUT = 18 # force logout -BM = 19 # byte macro -DET = 20 # data entry terminal -SUPDUP = 21 # supdup protocol -SUPDUPOUTPUT = 22 # supdup output -SNDLOC = 23 # send location -TTYPE = 24 # terminal type -EOR = 25 # end or record -TUID = 26 # TACACS user identification -OUTMRK = 27 # output marking -TTYLOC = 28 # terminal location number -VT3270REGIME = 29 # 3270 regime -X3PAD = 30 # X.3 PAD -NAWS = 31 # window size -TSPEED = 32 # terminal speed -LFLOW = 33 # remote flow control -LINEMODE = 34 # Linemode option -XDISPLOC = 35 # X Display Location -OLD_ENVIRON = 36 # Old - Environment variables -AUTHENTICATION = 37 # Authenticate -ENCRYPT = 38 # Encryption option -NEW_ENVIRON = 39 # New - Environment variables +BINARY = bytes([0]) # 8-bit data path +ECHO = bytes([1]) # echo +RCP = bytes([2]) # prepare to reconnect +SGA = bytes([3]) # suppress go ahead +NAMS = bytes([4]) # approximate message size +STATUS = bytes([5]) # give status +TM = bytes([6]) # timing mark +RCTE = bytes([7]) # remote controlled transmission and echo +NAOL = bytes([8]) # negotiate about output line width +NAOP = bytes([9]) # negotiate about output page size +NAOCRD = bytes([10]) # negotiate about CR disposition +NAOHTS = bytes([11]) # negotiate about horizontal tabstops +NAOHTD = bytes([12]) # negotiate about horizontal tab disposition +NAOFFD = bytes([13]) # negotiate about formfeed disposition +NAOVTS = bytes([14]) # negotiate about vertical tab stops +NAOVTD = bytes([15]) # negotiate about vertical tab disposition +NAOLFD = bytes([16]) # negotiate about output LF disposition +XASCII = bytes([17]) # extended ascii character set +LOGOUT = bytes([18]) # force logout +BM = bytes([19]) # byte macro +DET = bytes([20]) # data entry terminal +SUPDUP = bytes([21]) # supdup protocol +SUPDUPOUTPUT = bytes([22]) # supdup output +SNDLOC = bytes([23]) # send location +TTYPE = bytes([24]) # terminal type +EOR = bytes([25]) # end or record +TUID = bytes([26]) # TACACS user identification +OUTMRK = bytes([27]) # output marking +TTYLOC = bytes([28]) # terminal location number +VT3270REGIME = bytes([29]) # 3270 regime +X3PAD = bytes([30]) # X.3 PAD +NAWS = bytes([31]) # window size +TSPEED = bytes([32]) # terminal speed +LFLOW = bytes([33]) # remote flow control +LINEMODE = bytes([34]) # Linemode option +XDISPLOC = bytes([35]) # X Display Location +OLD_ENVIRON = bytes([36]) # Old - Environment variables +AUTHENTICATION = bytes([37]) # Authenticate +ENCRYPT = bytes([38]) # Encryption option +NEW_ENVIRON = bytes([39]) # New - Environment variables # the following ones come from # http://www.iana.org/assignments/telnet-options # Unfortunately, that document does not assign identifiers # to all of them, so we are making them up -TN3270E = 40 # TN3270E -XAUTH = 41 # XAUTH -CHARSET = 42 # CHARSET -RSP = 43 # Telnet Remote Serial Port -COM_PORT_OPTION = 44 # Com Port Control Option -SUPPRESS_LOCAL_ECHO = 45 # Telnet Suppress Local Echo -TLS = 46 # Telnet Start TLS -KERMIT = 47 # KERMIT -SEND_URL = 48 # SEND-URL -FORWARD_X = 49 # FORWARD_X -PRAGMA_LOGON = 138 # TELOPT PRAGMA LOGON -SSPI_LOGON = 139 # TELOPT SSPI LOGON -PRAGMA_HEARTBEAT = 140 # TELOPT PRAGMA HEARTBEAT -EXOPL = 255 # Extended-Options-List -NOOPT = 0 +TN3270E = bytes([40]) # TN3270E +XAUTH = bytes([41]) # XAUTH +CHARSET = bytes([42]) # CHARSET +RSP = bytes([43]) # Telnet Remote Serial Port +COM_PORT_OPTION = bytes([44]) # Com Port Control Option +SUPPRESS_LOCAL_ECHO = bytes([45]) # Telnet Suppress Local Echo +TLS = bytes([46]) # Telnet Start TLS +KERMIT = bytes([47]) # KERMIT +SEND_URL = bytes([48]) # SEND-URL +FORWARD_X = bytes([49]) # FORWARD_X +PRAGMA_LOGON = bytes([138]) # TELOPT PRAGMA LOGON +SSPI_LOGON = bytes([139]) # TELOPT SSPI LOGON +PRAGMA_HEARTBEAT = bytes([140]) # TELOPT PRAGMA HEARTBEAT +EXOPL = bytes([255]) # Extended-Options-List +NOOPT = bytes([0]) class Telnet: Modified: python/branches/py3k-short-float-repr/Lib/test/support.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/support.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/support.py Mon Apr 13 18:30:54 2009 @@ -41,22 +41,63 @@ and unexpected skips. """ + at contextlib.contextmanager +def _ignore_deprecated_imports(ignore=True): + """Context manager to suppress package and module deprecation + warnings when importing them. + + If ignore is False, this context manager has no effect.""" + if ignore: + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", ".+ (module|package)", + DeprecationWarning) + yield + else: + yield + + def import_module(name, deprecated=False): """Import and return the module to be tested, raising SkipTest if it is not available. If deprecated is True, any module or package deprecation messages will be suppressed.""" - with warnings.catch_warnings(): - if deprecated: - warnings.filterwarnings("ignore", ".+ (module|package)", - DeprecationWarning) + with _ignore_deprecated_imports(deprecated): try: - module = importlib.import_module(name) + return importlib.import_module(name) except ImportError as msg: raise unittest.SkipTest(str(msg)) - else: - return module + + +def import_fresh_module(name, blocked_names=None, deprecated=False): + """Imports and returns a module, deliberately bypassing the sys.modules cache + and importing a fresh copy of the module. Once the import is complete, + the sys.modules cache is restored to its original state. + + Importing of modules named in blocked_names is prevented while the fresh import + takes place. + + If deprecated is True, any module or package deprecation messages + will be suppressed.""" + # NOTE: test_heapq and test_warnings include extra sanity checks to make + # sure that this utility function is working as expected + with _ignore_deprecated_imports(deprecated): + if blocked_names is None: + blocked_names = () + orig_modules = {} + if name in sys.modules: + orig_modules[name] = sys.modules[name] + del sys.modules[name] + try: + for blocked in blocked_names: + orig_modules[blocked] = sys.modules[blocked] + sys.modules[blocked] = 0 + py_module = importlib.import_module(name) + finally: + for blocked, module in orig_modules.items(): + sys.modules[blocked] = module + return py_module + def get_attribute(obj, name): """Get an attribute, raising SkipTest if AttributeError is raised.""" Modified: python/branches/py3k-short-float-repr/Lib/test/test_asyncore.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_asyncore.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_asyncore.py Mon Apr 13 18:30:54 2009 @@ -116,12 +116,24 @@ def test_readwrite(self): # Check that correct methods are called by readwrite() + attributes = ('read', 'expt', 'write', 'closed', 'error_handled') + + expected = ( + (select.POLLIN, 'read'), + (select.POLLPRI, 'expt'), + (select.POLLOUT, 'write'), + (select.POLLERR, 'closed'), + (select.POLLHUP, 'closed'), + (select.POLLNVAL, 'closed'), + ) + class testobj: def __init__(self): self.read = False self.write = False self.closed = False self.expt = False + self.error_handled = False def handle_read_event(self): self.read = True @@ -138,54 +150,25 @@ def handle_error(self): self.error_handled = True - for flag in (select.POLLIN, select.POLLPRI): + for flag, expectedattr in expected: tobj = testobj() - self.assertEqual(tobj.read, False) + self.assertEqual(getattr(tobj, expectedattr), False) asyncore.readwrite(tobj, flag) - self.assertEqual(tobj.read, True) - - # check that ExitNow exceptions in the object handler method - # bubbles all the way up through asyncore readwrite call - tr1 = exitingdummy() - self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, flag) - - # check that an exception other than ExitNow in the object handler - # method causes the handle_error method to get called - tr2 = crashingdummy() - asyncore.readwrite(tr2, flag) - self.assertEqual(tr2.error_handled, True) - tobj = testobj() - self.assertEqual(tobj.write, False) - asyncore.readwrite(tobj, select.POLLOUT) - self.assertEqual(tobj.write, True) - - # check that ExitNow exceptions in the object handler method - # bubbles all the way up through asyncore readwrite call - tr1 = exitingdummy() - self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, - select.POLLOUT) - - # check that an exception other than ExitNow in the object handler - # method causes the handle_error method to get called - tr2 = crashingdummy() - asyncore.readwrite(tr2, select.POLLOUT) - self.assertEqual(tr2.error_handled, True) - - for flag in (select.POLLERR, select.POLLHUP, select.POLLNVAL): - tobj = testobj() - self.assertEqual((tobj.expt, tobj.closed)[flag == select.POLLHUP], False) - asyncore.readwrite(tobj, flag) - self.assertEqual((tobj.expt, tobj.closed)[flag == select.POLLHUP], True) + # Only the attribute modified by the routine we expect to be + # called should be True. + for attr in attributes: + self.assertEqual(getattr(tobj, attr), attr==expectedattr) # check that ExitNow exceptions in the object handler method - # bubbles all the way up through asyncore readwrite calls + # bubbles all the way up through asyncore readwrite call tr1 = exitingdummy() self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, flag) # check that an exception other than ExitNow in the object handler # method causes the handle_error method to get called tr2 = crashingdummy() + self.assertEqual(tr2.error_handled, False) asyncore.readwrite(tr2, flag) self.assertEqual(tr2.error_handled, True) @@ -290,15 +273,13 @@ sys.stdout = stdout lines = fp.getvalue().splitlines() - if __debug__: - expected = ['EGGS: %s' % l1, 'info: %s' % l2, 'SPAM: %s' % l3] - else: - expected = ['EGGS: %s' % l1, 'SPAM: %s' % l3] + expected = ['EGGS: %s' % l1, 'info: %s' % l2, 'SPAM: %s' % l3] self.assertEquals(lines, expected) def test_unhandled(self): d = asyncore.dispatcher() + d.ignore_log_types = () # capture output of dispatcher.log_info() (to stdout via print) fp = StringIO() @@ -314,7 +295,7 @@ sys.stdout = stdout lines = fp.getvalue().splitlines() - expected = ['warning: unhandled exception', + expected = ['warning: unhandled incoming priority event', 'warning: unhandled read event', 'warning: unhandled write event', 'warning: unhandled connect event', Modified: python/branches/py3k-short-float-repr/Lib/test/test_bigmem.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_bigmem.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_bigmem.py Mon Apr 13 18:30:54 2009 @@ -418,18 +418,15 @@ @bigmemtest(minsize=_2G, memuse=2) def test_translate(self, size): _ = self.from_latin1 - trans = { - ord(_('.')): _('-'), - ord(_('a')): _('!'), - ord(_('Z')): _('$'), - } SUBSTR = _('aZz.z.Aaz.') - if not isinstance(SUBSTR, str): - # Workaround the inexistence of bytes.maketrans() - chars = bytearray(range(256)) - for k, v in trans.items(): - chars[k] = ord(v) - trans = chars + if isinstance(SUBSTR, str): + trans = { + ord(_('.')): _('-'), + ord(_('a')): _('!'), + ord(_('Z')): _('$'), + } + else: + trans = bytes.maketrans(b'.aZ', b'-!$') sublen = len(SUBSTR) repeats = size // sublen + 2 s = SUBSTR * repeats Modified: python/branches/py3k-short-float-repr/Lib/test/test_bytes.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_bytes.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_bytes.py Mon Apr 13 18:30:54 2009 @@ -450,6 +450,13 @@ self.assertEqual([ord(b[i:i+1]) for i in range(len(b))], [0, 65, 127, 128, 255]) + def test_maketrans(self): + transtable = b'\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`xyzdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377' + + self.assertEqual(self.type2test.maketrans(b'abc', b'xyz'), transtable) + self.assertRaises(ValueError, self.type2test.maketrans, b'abc', b'xyzq') + self.assertRaises(TypeError, self.type2test.maketrans, 'abc', 'def') + class BytesTest(BaseBytesTest): type2test = bytes Modified: python/branches/py3k-short-float-repr/Lib/test/test_heapq.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_heapq.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_heapq.py Mon Apr 13 18:30:54 2009 @@ -7,23 +7,8 @@ # We do a bit of trickery here to be able to test both the C implementation # and the Python implementation of the module. - -# Make it impossible to import the C implementation anymore. -sys.modules['_heapq'] = 0 -# We must also handle the case that heapq was imported before. -if 'heapq' in sys.modules: - del sys.modules['heapq'] - -# Now we can import the module and get the pure Python implementation. -import heapq as py_heapq - -# Restore everything to normal. -del sys.modules['_heapq'] -del sys.modules['heapq'] - -# This is now the module with the C implementation. import heapq as c_heapq - +py_heapq = support.import_fresh_module('heapq', ['_heapq']) class TestHeap(unittest.TestCase): module = None @@ -194,6 +179,13 @@ class TestHeapPython(TestHeap): module = py_heapq + # As an early adopter, we sanity check the + # test.support.import_fresh_module utility function + def test_pure_python(self): + self.assertFalse(sys.modules['heapq'] is self.module) + self.assertTrue(hasattr(self.module.heapify, '__code__')) + + class TestHeapC(TestHeap): module = c_heapq @@ -219,6 +211,12 @@ self.assertEqual(hsort(data, LT), target) self.assertRaises(TypeError, data, LE) + # As an early adopter, we sanity check the + # test.support.import_fresh_module utility function + def test_accelerated(self): + self.assertTrue(sys.modules['heapq'] is self.module) + self.assertFalse(hasattr(self.module.heapify, '__code__')) + #============================================================================== Modified: python/branches/py3k-short-float-repr/Lib/test/test_httpservers.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_httpservers.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_httpservers.py Mon Apr 13 18:30:54 2009 @@ -6,6 +6,7 @@ from http.server import BaseHTTPRequestHandler, HTTPServer, \ SimpleHTTPRequestHandler, CGIHTTPRequestHandler +from http import server import os import sys @@ -316,6 +317,45 @@ finally: BaseTestCase.tearDown(self) + def test_url_collapse_path_split(self): + test_vectors = { + '': ('/', ''), + '..': IndexError, + '/.//..': IndexError, + '/': ('/', ''), + '//': ('/', ''), + '/\\': ('/', '\\'), + '/.//': ('/', ''), + 'cgi-bin/file1.py': ('/cgi-bin', 'file1.py'), + '/cgi-bin/file1.py': ('/cgi-bin', 'file1.py'), + 'a': ('/', 'a'), + '/a': ('/', 'a'), + '//a': ('/', 'a'), + './a': ('/', 'a'), + './C:/': ('/C:', ''), + '/a/b': ('/a', 'b'), + '/a/b/': ('/a/b', ''), + '/a/b/c/..': ('/a/b', ''), + '/a/b/c/../d': ('/a/b', 'd'), + '/a/b/c/../d/e/../f': ('/a/b/d', 'f'), + '/a/b/c/../d/e/../../f': ('/a/b', 'f'), + '/a/b/c/../d/e/.././././..//f': ('/a/b', 'f'), + '../a/b/c/../d/e/.././././..//f': IndexError, + '/a/b/c/../d/e/../../../f': ('/a', 'f'), + '/a/b/c/../d/e/../../../../f': ('/', 'f'), + '/a/b/c/../d/e/../../../../../f': IndexError, + '/a/b/c/../d/e/../../../../f/..': ('/', ''), + } + for path, expected in test_vectors.items(): + if isinstance(expected, type) and issubclass(expected, Exception): + self.assertRaises(expected, + server._url_collapse_path_split, path) + else: + actual = server._url_collapse_path_split(path) + self.assertEquals(expected, actual, + msg='path = %r\nGot: %r\nWanted: %r' % ( + path, actual, expected)) + def test_headers_and_content(self): res = self.request('/cgi-bin/file1.py') self.assertEquals((b'Hello World\n', 'text/html', 200), \ @@ -341,6 +381,12 @@ self.assertEquals((b'Hello World\n', 'text/html', 200), \ (res.read(), res.getheader('Content-type'), res.status)) + def test_no_leading_slash(self): + # http://bugs.python.org/issue2254 + res = self.request('cgi-bin/file1.py') + self.assertEquals((b'Hello World\n', 'text/html', 200), + (res.read(), res.getheader('Content-type'), res.status)) + def test_main(verbose=None): try: Modified: python/branches/py3k-short-float-repr/Lib/test/test_minidom.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_minidom.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_minidom.py Mon Apr 13 18:30:54 2009 @@ -789,6 +789,167 @@ "testNormalize -- single empty node removed") doc.unlink() + def testNormalizeCombineAndNextSibling(self): + doc = parseString("") + root = doc.documentElement + root.appendChild(doc.createTextNode("first")) + root.appendChild(doc.createTextNode("second")) + root.appendChild(doc.createElement("i")) + self.confirm(len(root.childNodes) == 3 + and root.childNodes.length == 3, + "testNormalizeCombineAndNextSibling -- preparation") + doc.normalize() + self.confirm(len(root.childNodes) == 2 + and root.childNodes.length == 2 + and root.firstChild.data == "firstsecond" + and root.firstChild is not root.lastChild + and root.firstChild.nextSibling is root.lastChild + and root.firstChild.previousSibling is None + and root.lastChild.previousSibling is root.firstChild + and root.lastChild.nextSibling is None + , "testNormalizeCombinedAndNextSibling -- result") + doc.unlink() + + def testNormalizeDeleteWithPrevSibling(self): + doc = parseString("") + root = doc.documentElement + root.appendChild(doc.createTextNode("first")) + root.appendChild(doc.createTextNode("")) + self.confirm(len(root.childNodes) == 2 + and root.childNodes.length == 2, + "testNormalizeDeleteWithPrevSibling -- preparation") + doc.normalize() + self.confirm(len(root.childNodes) == 1 + and root.childNodes.length == 1 + and root.firstChild.data == "first" + and root.firstChild is root.lastChild + and root.firstChild.nextSibling is None + and root.firstChild.previousSibling is None + , "testNormalizeDeleteWithPrevSibling -- result") + doc.unlink() + + def testNormalizeDeleteWithNextSibling(self): + doc = parseString("") + root = doc.documentElement + root.appendChild(doc.createTextNode("")) + root.appendChild(doc.createTextNode("second")) + self.confirm(len(root.childNodes) == 2 + and root.childNodes.length == 2, + "testNormalizeDeleteWithNextSibling -- preparation") + doc.normalize() + self.confirm(len(root.childNodes) == 1 + and root.childNodes.length == 1 + and root.firstChild.data == "second" + and root.firstChild is root.lastChild + and root.firstChild.nextSibling is None + and root.firstChild.previousSibling is None + , "testNormalizeDeleteWithNextSibling -- result") + doc.unlink() + + def testNormalizeDeleteWithTwoNonTextSiblings(self): + doc = parseString("") + root = doc.documentElement + root.appendChild(doc.createElement("i")) + root.appendChild(doc.createTextNode("")) + root.appendChild(doc.createElement("i")) + self.confirm(len(root.childNodes) == 3 + and root.childNodes.length == 3, + "testNormalizeDeleteWithTwoSiblings -- preparation") + doc.normalize() + self.confirm(len(root.childNodes) == 2 + and root.childNodes.length == 2 + and root.firstChild is not root.lastChild + and root.firstChild.nextSibling is root.lastChild + and root.firstChild.previousSibling is None + and root.lastChild.previousSibling is root.firstChild + and root.lastChild.nextSibling is None + , "testNormalizeDeleteWithTwoSiblings -- result") + doc.unlink() + + def testNormalizeDeleteAndCombine(self): + doc = parseString("") + root = doc.documentElement + root.appendChild(doc.createTextNode("")) + root.appendChild(doc.createTextNode("second")) + root.appendChild(doc.createTextNode("")) + root.appendChild(doc.createTextNode("fourth")) + root.appendChild(doc.createTextNode("")) + self.confirm(len(root.childNodes) == 5 + and root.childNodes.length == 5, + "testNormalizeDeleteAndCombine -- preparation") + doc.normalize() + self.confirm(len(root.childNodes) == 1 + and root.childNodes.length == 1 + and root.firstChild is root.lastChild + and root.firstChild.data == "secondfourth" + and root.firstChild.previousSibling is None + and root.firstChild.nextSibling is None + , "testNormalizeDeleteAndCombine -- result") + doc.unlink() + + def testNormalizeRecursion(self): + doc = parseString("" + "" + "" + "t" + # + #x + "" + "" + "" + "t2" + #x2 + "" + "t3" + #x3 + "" + # + "") + root = doc.documentElement + root.childNodes[0].appendChild(doc.createTextNode("")) + root.childNodes[0].appendChild(doc.createTextNode("x")) + root.childNodes[1].childNodes[0].appendChild(doc.createTextNode("x2")) + root.childNodes[1].appendChild(doc.createTextNode("x3")) + root.appendChild(doc.createTextNode("")) + self.confirm(len(root.childNodes) == 3 + and root.childNodes.length == 3 + and len(root.childNodes[0].childNodes) == 4 + and root.childNodes[0].childNodes.length == 4 + and len(root.childNodes[1].childNodes) == 3 + and root.childNodes[1].childNodes.length == 3 + and len(root.childNodes[1].childNodes[0].childNodes) == 2 + and root.childNodes[1].childNodes[0].childNodes.length == 2 + , "testNormalize2 -- preparation") + doc.normalize() + self.confirm(len(root.childNodes) == 2 + and root.childNodes.length == 2 + and len(root.childNodes[0].childNodes) == 2 + and root.childNodes[0].childNodes.length == 2 + and len(root.childNodes[1].childNodes) == 2 + and root.childNodes[1].childNodes.length == 2 + and len(root.childNodes[1].childNodes[0].childNodes) == 1 + and root.childNodes[1].childNodes[0].childNodes.length == 1 + , "testNormalize2 -- childNodes lengths") + self.confirm(root.childNodes[0].childNodes[1].data == "tx" + and root.childNodes[1].childNodes[0].childNodes[0].data == "t2x2" + and root.childNodes[1].childNodes[1].data == "t3x3" + , "testNormalize2 -- joined text fields") + self.confirm(root.childNodes[0].childNodes[1].nextSibling is None + and root.childNodes[0].childNodes[1].previousSibling + is root.childNodes[0].childNodes[0] + and root.childNodes[0].childNodes[0].previousSibling is None + and root.childNodes[0].childNodes[0].nextSibling + is root.childNodes[0].childNodes[1] + and root.childNodes[1].childNodes[1].nextSibling is None + and root.childNodes[1].childNodes[1].previousSibling + is root.childNodes[1].childNodes[0] + and root.childNodes[1].childNodes[0].previousSibling is None + and root.childNodes[1].childNodes[0].nextSibling + is root.childNodes[1].childNodes[1] + , "testNormalize2 -- sibling pointers") + doc.unlink() + + def testBug1433694(self): doc = parseString("t") node = doc.documentElement Modified: python/branches/py3k-short-float-repr/Lib/test/test_mmap.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_mmap.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_mmap.py Mon Apr 13 18:30:54 2009 @@ -357,15 +357,22 @@ m.move(source, dest, size) except ValueError: pass - self.assertRaises(ValueError, m.move, -1, -1, -1) - self.assertRaises(ValueError, m.move, -1, -1, 0) - self.assertRaises(ValueError, m.move, -1, 0, -1) - self.assertRaises(ValueError, m.move, 0, -1, -1) - self.assertRaises(ValueError, m.move, -1, 0, 0) - self.assertRaises(ValueError, m.move, 0, -1, 0) - self.assertRaises(ValueError, m.move, 0, 0, -1) + + offsets = [(-1, -1, -1), (-1, -1, 0), (-1, 0, -1), (0, -1, -1), + (-1, 0, 0), (0, -1, 0), (0, 0, -1)] + for source, dest, size in offsets: + self.assertRaises(ValueError, m.move, source, dest, size) + m.close() + m = mmap.mmap(-1, 1) # single byte + self.assertRaises(ValueError, m.move, 0, 0, 2) + self.assertRaises(ValueError, m.move, 1, 0, 1) + self.assertRaises(ValueError, m.move, 0, 1, 1) + m.move(0, 0, 1) + m.move(0, 0, 0) + + def test_anonymous(self): # anonymous mmap.mmap(-1, PAGE) m = mmap.mmap(-1, PAGESIZE) Modified: python/branches/py3k-short-float-repr/Lib/test/test_multiprocessing.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_multiprocessing.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_multiprocessing.py Mon Apr 13 18:30:54 2009 @@ -1832,7 +1832,37 @@ multiprocessing.connection.answer_challenge, _FakeConnection(), b'abc') -testcases_other = [OtherTest, TestInvalidHandle] +# +# Test Manager.start()/Pool.__init__() initializer feature - see issue 5585 +# + +def initializer(ns): + ns.test += 1 + +class TestInitializers(unittest.TestCase): + def setUp(self): + self.mgr = multiprocessing.Manager() + self.ns = self.mgr.Namespace() + self.ns.test = 0 + + def tearDown(self): + self.mgr.shutdown() + + def test_manager_initializer(self): + m = multiprocessing.managers.SyncManager() + self.assertRaises(TypeError, m.start, 1) + m.start(initializer, (self.ns,)) + self.assertEqual(self.ns.test, 1) + m.shutdown() + + def test_pool_initializer(self): + self.assertRaises(TypeError, multiprocessing.Pool, initializer=1) + p = multiprocessing.Pool(1, initializer, (self.ns,)) + p.close() + p.join() + self.assertEqual(self.ns.test, 1) + +testcases_other = [OtherTest, TestInvalidHandle, TestInitializers] # # @@ -1843,7 +1873,6 @@ try: lock = multiprocessing.RLock() except OSError: - from test.support import TestSkipped raise unittest.SkipTest("OSError raises on RLock creation, see issue 3111!") if run is None: Modified: python/branches/py3k-short-float-repr/Lib/test/test_os.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_os.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_os.py Mon Apr 13 18:30:54 2009 @@ -660,6 +660,48 @@ class Win32ErrorTests(unittest.TestCase): pass + class PosixUidGidTests(unittest.TestCase): + if hasattr(os, 'setuid'): + def test_setuid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setuid, 0) + self.assertRaises(OverflowError, os.setuid, 1<<32) + + if hasattr(os, 'setgid'): + def test_setgid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setgid, 0) + self.assertRaises(OverflowError, os.setgid, 1<<32) + + if hasattr(os, 'seteuid'): + def test_seteuid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.seteuid, 0) + self.assertRaises(OverflowError, os.seteuid, 1<<32) + + if hasattr(os, 'setegid'): + def test_setegid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setegid, 0) + self.assertRaises(OverflowError, os.setegid, 1<<32) + + if hasattr(os, 'setreuid'): + def test_setreuid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setreuid, 0, 0) + self.assertRaises(OverflowError, os.setreuid, 1<<32, 0) + self.assertRaises(OverflowError, os.setreuid, 0, 1<<32) + + if hasattr(os, 'setregid'): + def test_setregid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setregid, 0, 0) + self.assertRaises(OverflowError, os.setregid, 1<<32, 0) + self.assertRaises(OverflowError, os.setregid, 0, 1<<32) +else: + class PosixUidGidTests(unittest.TestCase): + pass + def test_main(): support.run_unittest( FileTests, @@ -671,7 +713,8 @@ URandomTests, ExecTests, Win32ErrorTests, - TestInvalidFD + TestInvalidFD, + PosixUidGidTests ) if __name__ == "__main__": Modified: python/branches/py3k-short-float-repr/Lib/test/test_posixpath.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_posixpath.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_posixpath.py Mon Apr 13 18:30:54 2009 @@ -419,6 +419,11 @@ self.assert_(isinstance(posixpath.expanduser(b"~root/"), bytes)) self.assert_(isinstance(posixpath.expanduser(b"~foo/"), bytes)) + orig_home = os.environ['HOME'] + os.environ['HOME'] = '/' + self.assertEqual(posixpath.expanduser("~"), "/") + os.environ['HOME'] = orig_home + self.assertRaises(TypeError, posixpath.expanduser) def test_expandvars(self): Modified: python/branches/py3k-short-float-repr/Lib/test/test_string.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_string.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_string.py Mon Apr 13 18:30:54 2009 @@ -101,14 +101,6 @@ self.assertRaises(ValueError, fmt.format, "{0}", 10, 20, i=100) self.assertRaises(ValueError, fmt.format, "{i}", 10, 20, i=100) - - def test_maketrans(self): - transtable = b'\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`xyzdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377' - - self.assertEqual(string.maketrans(b'abc', b'xyz'), transtable) - self.assertRaises(ValueError, string.maketrans, b'abc', b'xyzq') - self.assertRaises(TypeError, string.maketrans, 'abc', 'def') - def test_main(): support.run_unittest(ModuleTest) Modified: python/branches/py3k-short-float-repr/Lib/test/test_sys.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_sys.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_sys.py Mon Apr 13 18:30:54 2009 @@ -344,6 +344,8 @@ self.assertEqual(len(sys.int_info), 2) self.assert_(sys.int_info.bits_per_digit % 5 == 0) self.assert_(sys.int_info.sizeof_digit >= 1) + self.assertEqual(type(sys.int_info.bits_per_digit), int) + self.assertEqual(type(sys.int_info.sizeof_digit), int) self.assert_(isinstance(sys.hexversion, int)) self.assert_(isinstance(sys.maxsize, int)) self.assert_(isinstance(sys.maxunicode, int)) @@ -622,9 +624,9 @@ check(1, size(vh) + self.longdigit) check(-1, size(vh) + self.longdigit) PyLong_BASE = 2**sys.int_info.bits_per_digit - check(PyLong_BASE, size(vh) + 2*self.longdigit) - check(PyLong_BASE**2-1, size(vh) + 2*self.longdigit) - check(PyLong_BASE**2, size(vh) + 3*self.longdigit) + check(int(PyLong_BASE), size(vh) + 2*self.longdigit) + check(int(PyLong_BASE**2-1), size(vh) + 2*self.longdigit) + check(int(PyLong_BASE**2), size(vh) + 3*self.longdigit) # memory check(memoryview(b''), size(h + 'P PP2P2i7P')) # module Modified: python/branches/py3k-short-float-repr/Lib/test/test_telnetlib.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_telnetlib.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_telnetlib.py Mon Apr 13 18:30:54 2009 @@ -2,17 +2,38 @@ import threading import telnetlib import time +import queue from unittest import TestCase from test import support HOST = support.HOST +EOF_sigil = object() -def server(evt, serv): +def server(evt, serv, dataq=None): + """ Open a tcp server in three steps + 1) set evt to true to let the parent know we are ready + 2) [optional] if is not False, write the list of data from dataq.get() + to the socket. + 3) set evt to true to let the parent know we're done + """ serv.listen(5) evt.set() try: conn, addr = serv.accept() + if dataq: + data = b'' + new_data = dataq.get(True, 0.5) + dataq.task_done() + for item in new_data: + if item == EOF_sigil: + break + if type(item) in [int, float]: + time.sleep(item) + else: + data += item + written = conn.send(data) + data = data[written:] except socket.timeout: pass finally: @@ -26,13 +47,15 @@ self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.settimeout(3) self.port = support.bind_port(self.sock) - threading.Thread(target=server, args=(self.evt,self.sock)).start() + self.thread = threading.Thread(target=server, args=(self.evt,self.sock)) + self.thread.start() self.evt.wait() self.evt.clear() time.sleep(.1) def tearDown(self): self.evt.wait() + self.thread.join() def testBasic(self): # connects @@ -71,9 +94,277 @@ self.assertEqual(telnet.sock.gettimeout(), 30) telnet.sock.close() +def _read_setUp(self): + self.evt = threading.Event() + self.dataq = queue.Queue() + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.sock.settimeout(3) + self.port = support.bind_port(self.sock) + self.thread = threading.Thread(target=server, args=(self.evt,self.sock, self.dataq)) + self.thread.start() + self.evt.wait() + self.evt.clear() + time.sleep(.1) + +def _read_tearDown(self): + self.evt.wait() + self.thread.join() + +class ReadTests(TestCase): + setUp = _read_setUp + tearDown = _read_tearDown + + # use a similar approach to testing timeouts as test_timeout.py + # these will never pass 100% but make the fuzz big enough that it is rare + block_long = 0.6 + block_short = 0.3 + def test_read_until_A(self): + """ + read_until(expected, [timeout]) + Read until the expected string has been seen, or a timeout is + hit (default is no timeout); may block. + """ + want = [b'x' * 10, b'match', b'y' * 10, EOF_sigil] + self.dataq.put(want) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + data = telnet.read_until(b'match') + self.assertEqual(data, b''.join(want[:-2])) + + def test_read_until_B(self): + # test the timeout - it does NOT raise socket.timeout + want = [b'hello', self.block_long, b'not seen', EOF_sigil] + self.dataq.put(want) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + data = telnet.read_until(b'not seen', self.block_short) + self.assertEqual(data, want[0]) + self.assertEqual(telnet.read_all(), b'not seen') + + def test_read_all_A(self): + """ + read_all() + Read all data until EOF; may block. + """ + want = [b'x' * 500, b'y' * 500, b'z' * 500, EOF_sigil] + self.dataq.put(want) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + data = telnet.read_all() + self.assertEqual(data, b''.join(want[:-1])) + return + + def _test_blocking(self, func): + self.dataq.put([self.block_long, EOF_sigil]) + self.dataq.join() + start = time.time() + data = func() + self.assertTrue(self.block_short <= time.time() - start) + + def test_read_all_B(self): + self._test_blocking(telnetlib.Telnet(HOST, self.port).read_all) + + def test_read_all_C(self): + self.dataq.put([EOF_sigil]) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + telnet.read_all() + telnet.read_all() # shouldn't raise + + def test_read_some_A(self): + """ + read_some() + Read at least one byte or EOF; may block. + """ + # test 'at least one byte' + want = [b'x' * 500, EOF_sigil] + self.dataq.put(want) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + data = telnet.read_all() + self.assertTrue(len(data) >= 1) + + def test_read_some_B(self): + # test EOF + self.dataq.put([EOF_sigil]) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + self.assertEqual(b'', telnet.read_some()) + + def test_read_some_C(self): + self._test_blocking(telnetlib.Telnet(HOST, self.port).read_some) + + def _test_read_any_eager_A(self, func_name): + """ + read_very_eager() + Read all data available already queued or on the socket, + without blocking. + """ + want = [self.block_long, b'x' * 100, b'y' * 100, EOF_sigil] + expects = want[1] + want[2] + self.dataq.put(want) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + func = getattr(telnet, func_name) + data = b'' + while True: + try: + data += func() + self.assertTrue(expects.startswith(data)) + except EOFError: + break + self.assertEqual(expects, data) + + def _test_read_any_eager_B(self, func_name): + # test EOF + self.dataq.put([EOF_sigil]) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + time.sleep(self.block_short) + func = getattr(telnet, func_name) + self.assertRaises(EOFError, func) + + # read_eager and read_very_eager make the same gaurantees + # (they behave differently but we only test the gaurantees) + def test_read_very_eager_A(self): + self._test_read_any_eager_A('read_very_eager') + def test_read_very_eager_B(self): + self._test_read_any_eager_B('read_very_eager') + def test_read_eager_A(self): + self._test_read_any_eager_A('read_eager') + def test_read_eager_B(self): + self._test_read_any_eager_B('read_eager') + # NB -- we need to test the IAC block which is mentioned in the docstring + # but not in the module docs + + def _test_read_any_lazy_B(self, func_name): + self.dataq.put([EOF_sigil]) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + func = getattr(telnet, func_name) + telnet.fill_rawq() + self.assertRaises(EOFError, func) + + def test_read_lazy_A(self): + want = [b'x' * 100, EOF_sigil] + self.dataq.put(want) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + time.sleep(self.block_short) + self.assertEqual(b'', telnet.read_lazy()) + data = b'' + while True: + try: + read_data = telnet.read_lazy() + data += read_data + if not read_data: + telnet.fill_rawq() + except EOFError: + break + self.assertTrue(want[0].startswith(data)) + self.assertEqual(data, want[0]) + + def test_read_lazy_B(self): + self._test_read_any_lazy_B('read_lazy') + + def test_read_very_lazy_A(self): + want = [b'x' * 100, EOF_sigil] + self.dataq.put(want) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + time.sleep(self.block_short) + self.assertEqual(b'', telnet.read_very_lazy()) + data = b'' + while True: + try: + read_data = telnet.read_very_lazy() + except EOFError: + break + data += read_data + if not read_data: + telnet.fill_rawq() + self.assertEqual(b'', telnet.cookedq) + telnet.process_rawq() + self.assertTrue(want[0].startswith(data)) + self.assertEqual(data, want[0]) + + def test_read_very_lazy_B(self): + self._test_read_any_lazy_B('read_very_lazy') + +class nego_collector(object): + def __init__(self, sb_getter=None): + self.seen = b'' + self.sb_getter = sb_getter + self.sb_seen = b'' + + def do_nego(self, sock, cmd, opt): + self.seen += cmd + opt + if cmd == tl.SE and self.sb_getter: + sb_data = self.sb_getter() + self.sb_seen += sb_data + +tl = telnetlib +class OptionTests(TestCase): + setUp = _read_setUp + tearDown = _read_tearDown + # RFC 854 commands + cmds = [tl.AO, tl.AYT, tl.BRK, tl.EC, tl.EL, tl.GA, tl.IP, tl.NOP] + + def _test_command(self, data): + """ helper for testing IAC + cmd """ + self.setUp() + self.dataq.put(data) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + nego = nego_collector() + telnet.set_option_negotiation_callback(nego.do_nego) + txt = telnet.read_all() + cmd = nego.seen + self.assertTrue(len(cmd) > 0) # we expect at least one command + self.assertTrue(cmd[:1] in self.cmds) + self.assertEqual(cmd[1:2], tl.NOOPT) + self.assertEqual(len(b''.join(data[:-1])), len(txt + cmd)) + nego.sb_getter = None # break the nego => telnet cycle + self.tearDown() + + def test_IAC_commands(self): + # reset our setup + self.dataq.put([EOF_sigil]) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + self.tearDown() + + for cmd in self.cmds: + self._test_command([tl.IAC, cmd, EOF_sigil]) + self._test_command([b'x' * 100, tl.IAC, cmd, b'y'*100, EOF_sigil]) + self._test_command([b'x' * 10, tl.IAC, cmd, b'y'*10, EOF_sigil]) + # all at once + self._test_command([tl.IAC + cmd for (cmd) in self.cmds] + [EOF_sigil]) + self.assertEqual(b'', telnet.read_sb_data()) + + def test_SB_commands(self): + # RFC 855, subnegotiations portion + send = [tl.IAC + tl.SB + tl.IAC + tl.SE, + tl.IAC + tl.SB + tl.IAC + tl.IAC + tl.IAC + tl.SE, + tl.IAC + tl.SB + tl.IAC + tl.IAC + b'aa' + tl.IAC + tl.SE, + tl.IAC + tl.SB + b'bb' + tl.IAC + tl.IAC + tl.IAC + tl.SE, + tl.IAC + tl.SB + b'cc' + tl.IAC + tl.IAC + b'dd' + tl.IAC + tl.SE, + EOF_sigil, + ] + self.dataq.put(send) + telnet = telnetlib.Telnet(HOST, self.port) + self.dataq.join() + nego = nego_collector(telnet.read_sb_data) + telnet.set_option_negotiation_callback(nego.do_nego) + txt = telnet.read_all() + self.assertEqual(txt, b'') + want_sb_data = tl.IAC + tl.IAC + b'aabb' + tl.IAC + b'cc' + tl.IAC + b'dd' + self.assertEqual(nego.sb_seen, want_sb_data) + self.assertEqual(b'', telnet.read_sb_data()) + nego.sb_getter = None # break the nego => telnet cycle def test_main(verbose=None): - support.run_unittest(GeneralTests) + support.run_unittest(GeneralTests, ReadTests, OptionTests) if __name__ == '__main__': test_main() Modified: python/branches/py3k-short-float-repr/Lib/test/test_unittest.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_unittest.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_unittest.py Mon Apr 13 18:30:54 2009 @@ -2311,6 +2311,16 @@ # from this TestCase instance but since its a local nothing else # will ever notice that. + def testAssertIs(self): + thing = object() + self.assertIs(thing, thing) + self.assertRaises(self.failureException, self.assertIs, thing, object()) + + def testAssertIsNot(self): + thing = object() + self.assertIsNot(thing, object()) + self.assertRaises(self.failureException, self.assertIsNot, thing, thing) + def testAssertIn(self): animals = {'monkey': 'banana', 'cow': 'grass', 'seal': 'fish'} @@ -2454,6 +2464,7 @@ # Test that sequences of unhashable objects can be tested for sameness: self.assertSameElements([[1, 2], [3, 4]], [[3, 4], [1, 2]]) + self.assertSameElements([{'a': 1}, {'b': 2}], [{'b': 2}, {'a': 1}]) self.assertRaises(self.failureException, self.assertSameElements, [[1]], [[2]]) @@ -2988,6 +2999,18 @@ "^unexpectedly None$", "^unexpectedly None : oops$"]) + def testAssertIs(self): + self.assertMessages('assertIs', (None, 'foo'), + ["^None is not 'foo'$", "^oops$", + "^None is not 'foo'$", + "^None is not 'foo' : oops$"]) + + def testAssertIsNot(self): + self.assertMessages('assertIsNot', (None, None), + ["^unexpectedly identical: None$", "^oops$", + "^unexpectedly identical: None$", + "^unexpectedly identical: None : oops$"]) + ###################################################################### ## Main Modified: python/branches/py3k-short-float-repr/Lib/test/test_warnings.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_warnings.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_warnings.py Mon Apr 13 18:30:54 2009 @@ -10,18 +10,14 @@ import warnings as original_warnings -sys.modules['_warnings'] = 0 -del sys.modules['warnings'] - -import warnings as py_warnings - +py_warnings = support.import_fresh_module('warnings', ['_warnings']) +# XXX (ncoghlan 20090412): +# Something in Py3k doesn't like sharing the same instance of +# _warnings between original_warnings and c_warnings +# Will leave issue 5354 open until I understand why 3.x breaks +# without the next line, while 2.x doesn't care del sys.modules['_warnings'] -del sys.modules['warnings'] - -import warnings as c_warnings - -sys.modules['warnings'] = original_warnings - +c_warnings = support.import_fresh_module('warnings') @contextmanager def warnings_state(module): @@ -351,9 +347,21 @@ class CWarnTests(BaseTest, WarnTests): module = c_warnings + # As an early adopter, we sanity check the + # test.support.import_fresh_module utility function + def test_accelerated(self): + self.assertFalse(original_warnings is self.module) + self.assertFalse(hasattr(self.module.warn, '__code__')) + class PyWarnTests(BaseTest, WarnTests): module = py_warnings + # As an early adopter, we sanity check the + # test.support.import_fresh_module utility function + def test_pure_python(self): + self.assertFalse(original_warnings is self.module) + self.assertTrue(hasattr(self.module.warn, '__code__')) + class WCmdLineTests(unittest.TestCase): Modified: python/branches/py3k-short-float-repr/Lib/unittest.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/unittest.py (original) +++ python/branches/py3k-short-float-repr/Lib/unittest.py Mon Apr 13 18:30:54 2009 @@ -807,6 +807,18 @@ standardMsg = '%r unexpectedly found in %r' % (member, container) self.fail(self._formatMessage(msg, standardMsg)) + def assertIs(self, expr1, expr2, msg=None): + """Just like self.assertTrue(a is b), but with a nicer default message.""" + if expr1 is not expr2: + standardMsg = '%r is not %r' % (expr1, expr2) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertIsNot(self, expr1, expr2, msg=None): + """Just like self.assertTrue(a is not b), but with a nicer default message.""" + if expr1 is expr2: + standardMsg = 'unexpectedly identical: %r' % (expr1,) + self.fail(self._formatMessage(msg, standardMsg)) + def assertDictEqual(self, d1, d2, msg=None): self.assert_(isinstance(d1, dict), 'First argument is not a dictionary') self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary') @@ -1020,7 +1032,7 @@ self.addTests(tests) def __repr__(self): - return "<%s tests=%s>" % (_strclass(self.__class__), self._tests) + return "<%s tests=%s>" % (_strclass(self.__class__), list(self)) def __eq__(self, other): if not isinstance(other, self.__class__): @@ -1035,7 +1047,7 @@ def countTestCases(self): cases = 0 - for test in self._tests: + for test in self: cases += test.countTestCases() return cases @@ -1055,7 +1067,7 @@ self.addTest(test) def run(self, result): - for test in self._tests: + for test in self: if result.shouldStop: break test(result) @@ -1066,7 +1078,7 @@ def debug(self): """Run the tests without collecting errors in a TestResult""" - for test in self._tests: + for test in self: test.debug() Modified: python/branches/py3k-short-float-repr/Lib/xml/dom/minidom.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/xml/dom/minidom.py (original) +++ python/branches/py3k-short-float-repr/Lib/xml/dom/minidom.py Mon Apr 13 18:30:54 2009 @@ -179,34 +179,27 @@ L = [] for child in self.childNodes: if child.nodeType == Node.TEXT_NODE: - data = child.data - if data and L and L[-1].nodeType == child.nodeType: + if not child.data: + # empty text node; discard + if L: + L[-1].nextSibling = child.nextSibling + if child.nextSibling: + child.nextSibling.previousSibling = child.previousSibling + child.unlink() + elif L and L[-1].nodeType == child.nodeType: # collapse text node node = L[-1] node.data = node.data + child.data node.nextSibling = child.nextSibling + if child.nextSibling: + child.nextSibling.previousSibling = node child.unlink() - elif data: - if L: - L[-1].nextSibling = child - child.previousSibling = L[-1] - else: - child.previousSibling = None - L.append(child) else: - # empty text node; discard - child.unlink() + L.append(child) else: - if L: - L[-1].nextSibling = child - child.previousSibling = L[-1] - else: - child.previousSibling = None L.append(child) if child.nodeType == Node.ELEMENT_NODE: child.normalize() - if L: - L[-1].nextSibling = None self.childNodes[:] = L def cloneNode(self, deep): Modified: python/branches/py3k-short-float-repr/Lib/xmlrpc/server.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/xmlrpc/server.py (original) +++ python/branches/py3k-short-float-repr/Lib/xmlrpc/server.py Mon Apr 13 18:30:54 2009 @@ -159,7 +159,7 @@ reason to instantiate this class directly. """ - def __init__(self, allow_none, encoding): + def __init__(self, allow_none=False, encoding=None): self.funcs = {} self.instance = None self.allow_none = allow_none Modified: python/branches/py3k-short-float-repr/Makefile.pre.in ============================================================================== --- python/branches/py3k-short-float-repr/Makefile.pre.in (original) +++ python/branches/py3k-short-float-repr/Makefile.pre.in Mon Apr 13 18:30:54 2009 @@ -788,7 +788,7 @@ then rm -f $(DESTDIR)$(BINDIR)/$(PYTHON); \ else true; \ fi - (cd $(DESTDIR)$(BINDIR); $(LN) python$(VERSION)$(EXE) $(PYTHON)) + (cd $(DESTDIR)$(BINDIR); $(LN) python$(VERSION)$(EXE) $(PYTHON)3) -rm -f $(DESTDIR)$(BINDIR)/python-config (cd $(DESTDIR)$(BINDIR); $(LN) -s python$(VERSION)-config python-config) @@ -842,6 +842,7 @@ sqlite3 sqlite3/test \ logging bsddb bsddb/test csv wsgiref urllib \ lib2to3 lib2to3/fixes lib2to3/pgen2 lib2to3/tests \ + lib2to3/tests/data lib2to3/tests/data/fixes lib2to3/tests/data/fixers/myfixes \ ctypes ctypes/test ctypes/macholib idlelib idlelib/Icons \ distutils distutils/command distutils/tests $(XMLLIBSUBDIRS) \ importlib importlib/test importlib/test/builtin \ @@ -909,11 +910,13 @@ -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ ./$(BUILDPYTHON) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \ -d $(LIBDEST) -f \ - -x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST) + -x 'bad_coding|badsyntax|site-packages|py2_test_grammar' \ + $(DESTDIR)$(LIBDEST) -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ ./$(BUILDPYTHON) -Wi -O $(DESTDIR)$(LIBDEST)/compileall.py \ -d $(LIBDEST) -f \ - -x 'bad_coding|badsyntax|site-packages' $(DESTDIR)$(LIBDEST) + -x 'bad_coding|badsyntax|site-packages|py2_test_grammar' \ + $(DESTDIR)$(LIBDEST) -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ ./$(BUILDPYTHON) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \ -d $(LIBDEST)/site-packages -f \ Modified: python/branches/py3k-short-float-repr/Misc/NEWS ============================================================================== --- python/branches/py3k-short-float-repr/Misc/NEWS (original) +++ python/branches/py3k-short-float-repr/Misc/NEWS Mon Apr 13 18:30:54 2009 @@ -12,9 +12,29 @@ Core and Builtins ----------------- +- The string.maketrans() function is deprecated; there is a new static method + maketrans() on the bytes and bytearray classes. This removes confusion about + the types string.maketrans() is supposed to work with, and mirrors the + methods available on the str class. + +- Issue #2170: refactored xml.dom.minidom.normalize, increasing both + its clarity and its speed. + +- Issue #1113244: Py_XINCREF, Py_DECREF, Py_XDECREF: Add `do { ... } while (0)' + to avoid compiler warnings. + Library ------- +- Issue #2703: SimpleXMLRPCDispatcher.__init__: Provide default values for + new arguments introduced in 2.5. + +Extension Modules +----------------- + +- Issue #5359: Readd the Berkley-DB detection code to allow _dbm be built + using Berkley-DB. + What's New in Python 3.1 alpha 2? ================================= @@ -32,6 +52,9 @@ - Issue #5499: The 'c' code for argument parsing functions now only accepts a byte, and the 'C' code only accepts a unicode character. +- Fix a problem in PyErr_NormalizeException that leads to "undetected errors" + when hitting the recursion limit under certain circumstances. + - Issue #1665206: Remove the last eager import in _warnings.c and make it lazy. - Fix a segfault when running test_exceptions with coverage, caused by @@ -75,8 +98,6 @@ - Issue #3845: In PyRun_SimpleFileExFlags avoid invalid memory access with short file names. -- Py_DECREF: Add `do { ... } while (0)' to avoid compiler warnings. - Library ------- @@ -327,6 +348,13 @@ Library ------- +- Issue #5607: fixed Distutils test_get_platform for Mac OS X fat binaries. + +- Issue #5732: added a new command in Distutils: check. + +- Issue #5731: Distutils bdist_wininst no longer worked on non-Windows + platforms. Initial patch by Paul Moore. + - Issue #5095: Added bdist_msi to the list of bdist supported formats. Initial fix by Steven Bethard. Modified: python/branches/py3k-short-float-repr/Misc/README ============================================================================== --- python/branches/py3k-short-float-repr/Misc/README (original) +++ python/branches/py3k-short-float-repr/Misc/README Mon Apr 13 18:30:54 2009 @@ -21,6 +21,7 @@ pymemcompat.h Memory interface compatibility file. python.man UNIX man page for the python interpreter python-mode.el Emacs mode for editing Python programs +python-wing.wpr Wing IDE project file README The file you're reading now README.valgrind Information for Valgrind users, see valgrind-python.supp RFD Request For Discussion about a Python newsgroup Modified: python/branches/py3k-short-float-repr/Misc/build.sh ============================================================================== --- python/branches/py3k-short-float-repr/Misc/build.sh (original) +++ python/branches/py3k-short-float-repr/Misc/build.sh Mon Apr 13 18:30:54 2009 @@ -259,6 +259,7 @@ # which will definitely fail with a conflict. #CONFLICTED_FILE=commontex/boilerplate.tex #conflict_count=`grep -c "<<<" $CONFLICTED_FILE` +make clean conflict_count=0 if [ $conflict_count != 0 ]; then echo "Conflict detected in $CONFLICTED_FILE. Doc build skipped." > ../build/$F Modified: python/branches/py3k-short-float-repr/Misc/gdbinit ============================================================================== --- python/branches/py3k-short-float-repr/Misc/gdbinit (original) +++ python/branches/py3k-short-float-repr/Misc/gdbinit Mon Apr 13 18:30:54 2009 @@ -138,3 +138,16 @@ end select-frame 0 end + +# generally useful macro to print a Unicode string +def pu + set $uni = $arg0 + set $i = 0 + while (*$uni && $i++<100) + if (*$uni < 0x80) + print *(char*)$uni++ + else + print /x *(short*)$uni++ + end + end +end Modified: python/branches/py3k-short-float-repr/Modules/_io/bufferedio.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_io/bufferedio.c (original) +++ python/branches/py3k-short-float-repr/Modules/_io/bufferedio.c Mon Apr 13 18:30:54 2009 @@ -174,7 +174,7 @@ 0, /* tp_alloc */ 0, /* tp_new */ }; - + typedef struct { PyObject_HEAD @@ -183,6 +183,10 @@ int ok; /* Initialized? */ int readable; int writable; + + /* True if this is a vanilla Buffered object (rather than a user derived + class) *and* the raw stream is a vanilla FileIO object. */ + int fast_closed_checks; /* Absolute position inside the raw stream (-1 if unknown). */ Py_off_t abs_pos; @@ -268,6 +272,18 @@ return -1; \ } +#define IS_CLOSED(self) \ + (self->fast_closed_checks \ + ? _PyFileIO_closed(self->raw) \ + : BufferedIOMixin_closed(self)) + +#define CHECK_CLOSED(self, error_msg) \ + if (IS_CLOSED(self)) { \ + PyErr_SetString(PyExc_ValueError, error_msg); \ + return NULL; \ + } + + #define VALID_READ_BUFFER(self) \ (self->readable && self->read_end != -1) @@ -466,8 +482,8 @@ CHECK_INITIALIZED(self) return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL); } - - + + /* Forward decls */ static PyObject * _BufferedWriter_flush_unlocked(BufferedObject *, int); @@ -480,7 +496,11 @@ static PyObject * _BufferedReader_peek_unlocked(BufferedObject *self, Py_ssize_t); static PyObject * -_BufferedReader_read_unlocked(BufferedObject *self, Py_ssize_t); +_BufferedReader_read_all(BufferedObject *self); +static PyObject * +_BufferedReader_read_fast(BufferedObject *self, Py_ssize_t); +static PyObject * +_BufferedReader_read_generic(BufferedObject *self, Py_ssize_t); /* @@ -509,8 +529,8 @@ static Py_off_t _Buffered_raw_tell(BufferedObject *self) { - PyObject *res; Py_off_t n; + PyObject *res; res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL); if (res == NULL) return -1; @@ -604,10 +624,7 @@ PyObject *res; CHECK_INITIALIZED(self) - if (BufferedIOMixin_closed(self)) { - PyErr_SetString(PyExc_ValueError, "flush of closed file"); - return NULL; - } + CHECK_CLOSED(self, "flush of closed file") ENTER_BUFFERED(self) res = _BufferedWriter_flush_unlocked(self, 0); @@ -667,14 +684,23 @@ return NULL; } - if (BufferedIOMixin_closed(self)) { - PyErr_SetString(PyExc_ValueError, "read of closed file"); - return NULL; - } + CHECK_CLOSED(self, "read of closed file") - ENTER_BUFFERED(self) - res = _BufferedReader_read_unlocked(self, n); - LEAVE_BUFFERED(self) + if (n == -1) { + /* The number of bytes is unspecified, read until the end of stream */ + ENTER_BUFFERED(self) + res = _BufferedReader_read_all(self); + LEAVE_BUFFERED(self) + } + else { + res = _BufferedReader_read_fast(self, n); + if (res == Py_None) { + Py_DECREF(res); + ENTER_BUFFERED(self) + res = _BufferedReader_read_generic(self, n); + LEAVE_BUFFERED(self) + } + } return res; } @@ -775,35 +801,31 @@ Py_ssize_t n, written = 0; const char *start, *s, *end; - if (BufferedIOMixin_closed(self)) { - PyErr_SetString(PyExc_ValueError, "readline of closed file"); - return NULL; - } - - ENTER_BUFFERED(self) + CHECK_CLOSED(self, "readline of closed file") - /* First, try to find a line in the buffer */ + /* First, try to find a line in the buffer. This can run unlocked because + the calls to the C API are simple enough that they can't trigger + any thread switch. */ n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); if (limit >= 0 && n > limit) n = limit; start = self->buffer + self->pos; - end = start + n; - s = start; - while (s < end) { - if (*s++ == '\n') { - res = PyBytes_FromStringAndSize(start, s - start); - if (res != NULL) - self->pos += s - start; - goto end; - } + s = memchr(start, '\n', n); + if (s != NULL) { + res = PyBytes_FromStringAndSize(start, s - start + 1); + if (res != NULL) + self->pos += s - start + 1; + goto end_unlocked; } if (n == limit) { res = PyBytes_FromStringAndSize(start, n); if (res != NULL) self->pos += n; - goto end; + goto end_unlocked; } + ENTER_BUFFERED(self) + /* Now we try to get some more from the raw stream */ if (self->writable) { res = _BufferedWriter_flush_unlocked(self, 1); @@ -875,6 +897,7 @@ end: LEAVE_BUFFERED(self) +end_unlocked: Py_XDECREF(chunks); return res; } @@ -918,23 +941,26 @@ if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) { return NULL; } - if (whence < 0 || whence > 2) { PyErr_Format(PyExc_ValueError, "whence must be between 0 and 2, not %d", whence); return NULL; } + + CHECK_CLOSED(self, "seek of closed file") + target = PyNumber_AsOff_t(targetobj, PyExc_ValueError); if (target == -1 && PyErr_Occurred()) return NULL; - ENTER_BUFFERED(self) - if (whence != 2 && self->readable) { Py_off_t current, avail; /* Check if seeking leaves us inside the current buffer, - so as to return quickly if possible. + so as to return quickly if possible. Also, we needn't take the + lock in this fast path. Don't know how to do that when whence == 2, though. */ + /* NOTE: RAW_TELL() can release the GIL but the object is in a stable + state at this point. */ current = RAW_TELL(self); avail = READAHEAD(self); if (avail > 0) { @@ -945,12 +971,13 @@ offset = target; if (offset >= -self->pos && offset <= avail) { self->pos += offset; - res = PyLong_FromOff_t(current - avail + offset); - goto end; + return PyLong_FromOff_t(current - avail + offset); } } } + ENTER_BUFFERED(self) + /* Fallback: invoke raw seek() method and clear buffer */ if (self->writable) { res = _BufferedWriter_flush_unlocked(self, 0); @@ -1094,6 +1121,9 @@ return -1; _BufferedReader_reset_buf(self); + self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedReader_Type && + Py_TYPE(raw) == &PyFileIO_Type); + self->ok = 1; return 0; } @@ -1150,93 +1180,107 @@ } static PyObject * -_BufferedReader_read_unlocked(BufferedObject *self, Py_ssize_t n) +_BufferedReader_read_all(BufferedObject *self) { - PyObject *data, *res = NULL; - Py_ssize_t current_size, remaining, written; - char *out; + Py_ssize_t current_size; + PyObject *res, *data = NULL; + PyObject *chunks = PyList_New(0); - /* Special case for when the number of bytes to read is unspecified. */ - if (n == -1) { - PyObject *chunks = PyList_New(0); - if (chunks == NULL) - return NULL; + if (chunks == NULL) + return NULL; - /* First copy what we have in the current buffer. */ - current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); - data = NULL; - if (current_size) { - data = PyBytes_FromStringAndSize( - self->buffer + self->pos, current_size); - if (data == NULL) { - Py_DECREF(chunks); - return NULL; - } + /* First copy what we have in the current buffer. */ + current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); + if (current_size) { + data = PyBytes_FromStringAndSize( + self->buffer + self->pos, current_size); + if (data == NULL) { + Py_DECREF(chunks); + return NULL; } - _BufferedReader_reset_buf(self); - /* We're going past the buffer's bounds, flush it */ - if (self->writable) { - res = _BufferedWriter_flush_unlocked(self, 1); - if (res == NULL) { + } + _BufferedReader_reset_buf(self); + /* We're going past the buffer's bounds, flush it */ + if (self->writable) { + res = _BufferedWriter_flush_unlocked(self, 1); + if (res == NULL) { + Py_DECREF(chunks); + return NULL; + } + Py_CLEAR(res); + } + while (1) { + if (data) { + if (PyList_Append(chunks, data) < 0) { + Py_DECREF(data); Py_DECREF(chunks); return NULL; } - Py_CLEAR(res); + Py_DECREF(data); } - while (1) { - if (data) { - if (PyList_Append(chunks, data) < 0) { - Py_DECREF(data); - Py_DECREF(chunks); - return NULL; - } - Py_DECREF(data); - } - /* Read until EOF or until read() would block. */ - data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL); - if (data == NULL) { + /* Read until EOF or until read() would block. */ + data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL); + if (data == NULL) { + Py_DECREF(chunks); + return NULL; + } + if (data != Py_None && !PyBytes_Check(data)) { + Py_DECREF(data); + Py_DECREF(chunks); + PyErr_SetString(PyExc_TypeError, "read() should return bytes"); + return NULL; + } + if (data == Py_None || PyBytes_GET_SIZE(data) == 0) { + if (current_size == 0) { Py_DECREF(chunks); - return NULL; + return data; } - if (data != Py_None && !PyBytes_Check(data)) { + else { + res = _PyBytes_Join(_PyIO_empty_bytes, chunks); Py_DECREF(data); Py_DECREF(chunks); - PyErr_SetString(PyExc_TypeError, "read() should return bytes"); - return NULL; - } - if (data == Py_None || PyBytes_GET_SIZE(data) == 0) { - if (current_size == 0) { - Py_DECREF(chunks); - return data; - } - else { - res = _PyBytes_Join(_PyIO_empty_bytes, chunks); - Py_DECREF(data); - Py_DECREF(chunks); - return res; - } + return res; } - current_size += PyBytes_GET_SIZE(data); - if (self->abs_pos != -1) - self->abs_pos += PyBytes_GET_SIZE(data); } + current_size += PyBytes_GET_SIZE(data); + if (self->abs_pos != -1) + self->abs_pos += PyBytes_GET_SIZE(data); } +} + +/* Read n bytes from the buffer if it can, otherwise return None. + This function is simple enough that it can run unlocked. */ +static PyObject * +_BufferedReader_read_fast(BufferedObject *self, Py_ssize_t n) +{ + Py_ssize_t current_size; - /* The number of bytes to read is specified, return at most n bytes. */ current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); if (n <= current_size) { /* Fast path: the data to read is fully buffered. */ - res = PyBytes_FromStringAndSize(self->buffer + self->pos, n); - if (res == NULL) - goto error; - self->pos += n; + PyObject *res = PyBytes_FromStringAndSize(self->buffer + self->pos, n); + if (res != NULL) + self->pos += n; return res; } + Py_RETURN_NONE; +} + +/* Generic read function: read from the stream until enough bytes are read, + * or until an EOF occurs or until read() would block. + */ +static PyObject * +_BufferedReader_read_generic(BufferedObject *self, Py_ssize_t n) +{ + PyObject *res = NULL; + Py_ssize_t current_size, remaining, written; + char *out; + + current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); + if (n <= current_size) + return _BufferedReader_read_fast(self, n); - /* Slow path: read from the stream until enough bytes are read, - * or until an EOF occurs or until read() would block. - */ res = PyBytes_FromStringAndSize(NULL, n); if (res == NULL) goto error; @@ -1479,6 +1523,9 @@ _BufferedWriter_reset_buf(self); self->pos = 0; + self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedWriter_Type && + Py_TYPE(raw) == &PyFileIO_Type); + self->ok = 1; return 0; } @@ -1583,7 +1630,7 @@ return NULL; } - if (BufferedIOMixin_closed(self)) { + if (IS_CLOSED(self)) { PyErr_SetString(PyExc_ValueError, "write to closed file"); PyBuffer_Release(&buf); return NULL; @@ -2066,6 +2113,9 @@ _BufferedWriter_reset_buf(self); self->pos = 0; + self->fast_closed_checks = (Py_TYPE(self) == &PyBufferedRandom_Type && + Py_TYPE(raw) == &PyFileIO_Type); + self->ok = 1; return 0; } Modified: python/branches/py3k-short-float-repr/Modules/_tkinter.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/_tkinter.c (original) +++ python/branches/py3k-short-float-repr/Modules/_tkinter.c Mon Apr 13 18:30:54 2009 @@ -33,8 +33,6 @@ #include #endif -#include "tkinter.h" - /* Allow using this code in Python 2.[12] */ #ifndef PyDoc_STRVAR #define PyDoc_STRVAR(name,str) static char name[] = str @@ -69,6 +67,8 @@ #include #endif +#include "tkinter.h" + /* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */ #ifndef CONST84_RETURN #define CONST84_RETURN Modified: python/branches/py3k-short-float-repr/Modules/mmapmodule.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/mmapmodule.c (original) +++ python/branches/py3k-short-float-repr/Modules/mmapmodule.c Mon Apr 13 18:30:54 2009 @@ -620,23 +620,23 @@ static PyObject * mmap_move_method(mmap_object *self, PyObject *args) { - unsigned long dest, src, count; + unsigned long dest, src, cnt; CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "kkk:move", &dest, &src, &count) || + if (!PyArg_ParseTuple(args, "kkk:move", &dest, &src, &cnt) || !is_writable(self)) { return NULL; } else { /* bounds check the values */ - unsigned long pos = src > dest ? src : dest; - if (self->size < pos || count > self->size - pos) { + if (cnt < 0 || (cnt + dest) < cnt || (cnt + src) < cnt || + src < 0 || src > self->size || (src + cnt) > self->size || + dest < 0 || dest > self->size || (dest + cnt) > self->size) { PyErr_SetString(PyExc_ValueError, - "source or destination out of range"); + "source, destination, or count out of range"); return NULL; - } else { - memmove(self->data+dest, self->data+src, count); - Py_INCREF(Py_None); - return Py_None; } + memmove(self->data+dest, self->data+src, cnt); + Py_INCREF(Py_None); + return Py_None; } } Modified: python/branches/py3k-short-float-repr/Modules/posixmodule.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/posixmodule.c (original) +++ python/branches/py3k-short-float-repr/Modules/posixmodule.c Mon Apr 13 18:30:54 2009 @@ -263,6 +263,7 @@ #include #endif #include "osdefs.h" +#include #include #include /* for ShellExecute() */ #endif /* _MSC_VER */ @@ -352,47 +353,15 @@ * (all of this is to avoid globally modifying the CRT behaviour using * _set_invalid_parameter_handler() and _CrtSetReportMode()) */ -#if _MSC_VER >= 1500 /* VS 2008 */ -typedef struct { - intptr_t osfhnd; - char osfile; - char pipech; - int lockinitflag; - CRITICAL_SECTION lock; -#ifndef _SAFECRT_IMPL - char textmode : 7; - char unicode : 1; - char pipech2[2]; - __int64 startpos; - BOOL utf8translations; - char dbcsBuffer; - BOOL dbcsBufferUsed; -#endif /* _SAFECRT_IMPL */ - } ioinfo; -#elif _MSC_VER >= 1400 /* VS 2005 */ +/* The actual size of the structure is determined at runtime. + * Only the first items must be present. + */ typedef struct { intptr_t osfhnd; char osfile; - char pipech; - int lockinitflag; - CRITICAL_SECTION lock; -#ifndef _SAFECRT_IMPL - char textmode : 7; - char unicode : 1; - char pipech2[2]; - __int64 startpos; - BOOL utf8translations; -#ifndef _DEBUG - /* padding hack. 8 byte extra length observed at - * runtime, for 32 and 64 bits when not in _DEBUG - */ - __int32 _padding[2]; -#endif -#endif /* _SAFECRT_IMPL */ - } ioinfo; -#endif +} my_ioinfo; -extern __declspec(dllimport) ioinfo * __pioinfo[]; +extern __declspec(dllimport) char * __pioinfo[]; #define IOINFO_L2E 5 #define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) #define IOINFO_ARRAYS 64 @@ -406,6 +375,19 @@ { const int i1 = fd >> IOINFO_L2E; const int i2 = fd & ((1 << IOINFO_L2E) - 1); + + static int sizeof_ioinfo = 0; + + /* Determine the actual size of the ioinfo structure, + * as used by the CRT loaded in memory + */ + if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) { + sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS; + } + if (sizeof_ioinfo == 0) { + /* This should not happen... */ + goto fail; + } /* See that it isn't a special CLEAR fileno */ if (fd != _NO_CONSOLE_FILENO) { @@ -414,10 +396,13 @@ */ if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) { /* finally, check that the file is open */ - if (__pioinfo[i1][i2].osfile & FOPEN) + my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo); + if (info->osfile & FOPEN) { return 1; + } } } + fail: errno = EBADF; return 0; } @@ -4168,9 +4153,15 @@ static PyObject * posix_setuid(PyObject *self, PyObject *args) { - int uid; - if (!PyArg_ParseTuple(args, "i:setuid", &uid)) + long uid_arg; + uid_t uid; + if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg)) + return NULL; + uid = uid_arg; + if (uid != uid_arg) { + PyErr_SetString(PyExc_OverflowError, "user id too big"); return NULL; + } if (setuid(uid) < 0) return posix_error(); Py_INCREF(Py_None); @@ -4187,10 +4178,16 @@ static PyObject * posix_seteuid (PyObject *self, PyObject *args) { - int euid; - if (!PyArg_ParseTuple(args, "i", &euid)) { + long euid_arg; + uid_t euid; + if (!PyArg_ParseTuple(args, "l", &euid_arg)) + return NULL; + euid = euid_arg; + if (euid != euid_arg) { + PyErr_SetString(PyExc_OverflowError, "user id too big"); return NULL; - } else if (seteuid(euid) < 0) { + } + if (seteuid(euid) < 0) { return posix_error(); } else { Py_INCREF(Py_None); @@ -4207,10 +4204,16 @@ static PyObject * posix_setegid (PyObject *self, PyObject *args) { - int egid; - if (!PyArg_ParseTuple(args, "i", &egid)) { + long egid_arg; + gid_t egid; + if (!PyArg_ParseTuple(args, "l", &egid_arg)) + return NULL; + egid = egid_arg; + if (egid != egid_arg) { + PyErr_SetString(PyExc_OverflowError, "group id too big"); return NULL; - } else if (setegid(egid) < 0) { + } + if (setegid(egid) < 0) { return posix_error(); } else { Py_INCREF(Py_None); @@ -4227,10 +4230,17 @@ static PyObject * posix_setreuid (PyObject *self, PyObject *args) { - int ruid, euid; - if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) { + long ruid_arg, euid_arg; + uid_t ruid, euid; + if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg)) return NULL; - } else if (setreuid(ruid, euid) < 0) { + ruid = ruid_arg; + euid = euid_arg; + if (euid != euid_arg || ruid != ruid_arg) { + PyErr_SetString(PyExc_OverflowError, "user id too big"); + return NULL; + } + if (setreuid(ruid, euid) < 0) { return posix_error(); } else { Py_INCREF(Py_None); @@ -4247,10 +4257,17 @@ static PyObject * posix_setregid (PyObject *self, PyObject *args) { - int rgid, egid; - if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) { + long rgid_arg, egid_arg; + gid_t rgid, egid; + if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg)) + return NULL; + rgid = rgid_arg; + egid = egid_arg; + if (egid != egid_arg || rgid != rgid_arg) { + PyErr_SetString(PyExc_OverflowError, "group id too big"); return NULL; - } else if (setregid(rgid, egid) < 0) { + } + if (setregid(rgid, egid) < 0) { return posix_error(); } else { Py_INCREF(Py_None); @@ -4267,9 +4284,15 @@ static PyObject * posix_setgid(PyObject *self, PyObject *args) { - int gid; - if (!PyArg_ParseTuple(args, "i:setgid", &gid)) + long gid_arg; + gid_t gid; + if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg)) + return NULL; + gid = gid_arg; + if (gid != gid_arg) { + PyErr_SetString(PyExc_OverflowError, "group id too big"); return NULL; + } if (setgid(gid) < 0) return posix_error(); Py_INCREF(Py_None); Modified: python/branches/py3k-short-float-repr/Modules/readline.c ============================================================================== --- python/branches/py3k-short-float-repr/Modules/readline.c (original) +++ python/branches/py3k-short-float-repr/Modules/readline.c Mon Apr 13 18:30:54 2009 @@ -693,13 +693,13 @@ r = PyObject_CallFunction(completion_display_matches_hook, "sOi", matches[0], m, max_length); - Py_DECREF(m), m=NULL; + Py_DECREF(m); m=NULL; if (r == NULL || (r != Py_None && PyLong_AsLong(r) == -1 && PyErr_Occurred())) { goto error; } - Py_XDECREF(r), r=NULL; + Py_XDECREF(r); r=NULL; if (0) { error: Modified: python/branches/py3k-short-float-repr/Modules/tkinter.h ============================================================================== --- python/branches/py3k-short-float-repr/Modules/tkinter.h (original) +++ python/branches/py3k-short-float-repr/Modules/tkinter.h Mon Apr 13 18:30:54 2009 @@ -2,7 +2,9 @@ #define TKINTER_H /* This header is used to share some macros between _tkinter.c and - * tkappinit.c */ + * tkappinit.c. + * Be sure to include tk.h before including this header so + * TK_VERSION_HEX is properly defined. */ /* TK_RELEASE_LEVEL is always one of the following: * TCL_ALPHA_RELEASE 0 Modified: python/branches/py3k-short-float-repr/Objects/bytearrayobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/bytearrayobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/bytearrayobject.c Mon Apr 13 18:30:54 2009 @@ -1021,7 +1021,7 @@ { if (self->ob_exports > 0) { PyErr_SetString(PyExc_SystemError, - "deallocated bytearray object has exported buffers"); + "deallocated bytearray object has exported buffers"); PyErr_Print(); } if (self->ob_bytes != 0) { @@ -1451,6 +1451,13 @@ } +static PyObject * +bytes_maketrans(PyObject *null, PyObject *args) +{ + return _Py_bytes_maketrans(args); +} + + #define FORWARD 1 #define REVERSE -1 @@ -2616,10 +2623,10 @@ /* Try to determine the length of the argument. 32 is abitrary. */ buf_size = _PyObject_LengthHint(arg, 32); - if (buf_size == -1) { - Py_DECREF(it); - return NULL; - } + if (buf_size == -1) { + Py_DECREF(it); + return NULL; + } bytes_obj = PyByteArray_FromStringAndSize(NULL, buf_size); if (bytes_obj == NULL) @@ -3063,10 +3070,10 @@ static PyObject * bytes_sizeof(PyByteArrayObject *self) { - Py_ssize_t res; + Py_ssize_t res; - res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char); - return PyLong_FromSsize_t(res); + res = sizeof(PyByteArrayObject) + self->ob_alloc * sizeof(char); + return PyLong_FromSsize_t(res); } static PySequenceMethods bytes_as_sequence = { @@ -3131,6 +3138,8 @@ {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__}, {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__}, {"lstrip", (PyCFunction)bytes_lstrip, METH_VARARGS, lstrip__doc__}, + {"maketrans", (PyCFunction)bytes_maketrans, METH_VARARGS|METH_STATIC, + _Py_maketrans__doc__}, {"partition", (PyCFunction)bytes_partition, METH_O, partition__doc__}, {"pop", (PyCFunction)bytes_pop, METH_VARARGS, pop__doc__}, {"remove", (PyCFunction)bytes_remove, METH_O, remove__doc__}, Modified: python/branches/py3k-short-float-repr/Objects/bytes_methods.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/bytes_methods.c (original) +++ python/branches/py3k-short-float-repr/Objects/bytes_methods.c Mon Apr 13 18:30:54 2009 @@ -608,3 +608,70 @@ } } + +PyDoc_STRVAR_shared(_Py_maketrans__doc__, +"B.maketrans(frm, to) -> translation table\n\ +\n\ +Return a translation table (a bytes object of length 256)\n\ +suitable for use in bytes.translate where each byte in frm is\n\ +mapped to the byte at the same position in to.\n\ +The strings frm and to must be of the same length."); + +static Py_ssize_t +_getbuffer(PyObject *obj, Py_buffer *view) +{ + PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer; + + if (buffer == NULL || buffer->bf_getbuffer == NULL) + { + PyErr_Format(PyExc_TypeError, + "Type %.100s doesn't support the buffer API", + Py_TYPE(obj)->tp_name); + return -1; + } + + if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0) + return -1; + return view->len; +} + +PyObject * +_Py_bytes_maketrans(PyObject *args) +{ + PyObject *frm, *to, *res = NULL; + Py_buffer bfrm, bto; + int i; + char *p; + + bfrm.len = -1; + bto.len = -1; + + if (!PyArg_ParseTuple(args, "OO:maketrans", &frm, &to)) + return NULL; + if (_getbuffer(frm, &bfrm) < 0) + return NULL; + if (_getbuffer(to, &bto) < 0) + goto done; + if (bfrm.len != bto.len) { + PyErr_Format(PyExc_ValueError, + "maketrans arguments must have same length"); + goto done; + } + res = PyBytes_FromStringAndSize(NULL, 256); + if (!res) { + goto done; + } + p = PyBytes_AS_STRING(res); + for (i = 0; i < 256; i++) + p[i] = i; + for (i = 0; i < bfrm.len; i++) { + p[(int)((char *)bfrm.buf)[i]] = ((char *)bto.buf)[i]; + } + + done: + if (bfrm.len != -1) + PyBuffer_Release(&bfrm); + if (bto.len != -1) + PyBuffer_Release(&bto); + return res; +} Modified: python/branches/py3k-short-float-repr/Objects/bytesobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/bytesobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/bytesobject.c Mon Apr 13 18:30:54 2009 @@ -1951,6 +1951,12 @@ } +static PyObject * +string_maketrans(PyObject *null, PyObject *args) +{ + return _Py_bytes_maketrans(args); +} + #define FORWARD 1 #define REVERSE -1 @@ -2852,6 +2858,8 @@ {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__}, {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__}, {"lstrip", (PyCFunction)string_lstrip, METH_VARARGS, lstrip__doc__}, + {"maketrans", (PyCFunction)string_maketrans, METH_VARARGS|METH_STATIC, + _Py_maketrans__doc__}, {"partition", (PyCFunction)string_partition, METH_O, partition__doc__}, {"replace", (PyCFunction)string_replace, METH_VARARGS, replace__doc__}, {"rfind", (PyCFunction)string_rfind, METH_VARARGS, rfind__doc__}, Modified: python/branches/py3k-short-float-repr/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/unicodeobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/unicodeobject.c Mon Apr 13 18:30:54 2009 @@ -7738,8 +7738,10 @@ Py_ssize_t nchars; size_t nbytes; - if (len < 0) - len = 0; + if (len < 1) { + Py_INCREF(unicode_empty); + return (PyObject *)unicode_empty; + } if (len == 1 && PyUnicode_CheckExact(str)) { /* no repeat, return original string */ @@ -7751,7 +7753,7 @@ * needed doesn't overflow size_t */ nchars = len * str->length; - if (len && nchars / len != str->length) { + if (nchars / len != str->length) { PyErr_SetString(PyExc_OverflowError, "repeated string is too long"); return NULL; @@ -7768,14 +7770,11 @@ p = u->str; - if (str->length == 1 && len > 0) { + if (str->length == 1) { Py_UNICODE_FILL(p, str->str[0], len); } else { - Py_ssize_t done = 0; /* number of characters copied this far */ - if (done < nchars) { - Py_UNICODE_COPY(p, str->str, str->length); - done = str->length; - } + Py_ssize_t done = str->length; /* number of characters copied this far */ + Py_UNICODE_COPY(p, str->str, str->length); while (done < nchars) { Py_ssize_t n = (done <= nchars-done) ? done : nchars-done; Py_UNICODE_COPY(p+done, p, n); Modified: python/branches/py3k-short-float-repr/Parser/asdl.py ============================================================================== --- python/branches/py3k-short-float-repr/Parser/asdl.py (original) +++ python/branches/py3k-short-float-repr/Parser/asdl.py Mon Apr 13 18:30:54 2009 @@ -405,7 +405,8 @@ try: return parser.parse(tokens) except ASDLSyntaxError: - output(sys.exc_info()[1]) + err = sys.exc_info()[1] + output(str(err)) lines = buf.split("\n") output(lines[err.lineno - 1]) # lines starts at 0, files at 1 @@ -422,6 +423,8 @@ for file in files: output(file) mod = parse(file) + if not mod: + break output("module", mod.name) output(len(mod.dfns), "definitions") if not check(mod): Modified: python/branches/py3k-short-float-repr/Python/errors.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/errors.c (original) +++ python/branches/py3k-short-float-repr/Python/errors.c Mon Apr 13 18:30:54 2009 @@ -279,7 +279,15 @@ tstate = PyThreadState_GET(); if (++tstate->recursion_depth > Py_GetRecursionLimit()) { --tstate->recursion_depth; - PyErr_SetObject(PyExc_RuntimeError, PyExc_RecursionErrorInst); + /* throw away the old exception... */ + Py_DECREF(*exc); + Py_DECREF(*val); + /* ... and use the recursion error instead */ + *exc = PyExc_RuntimeError; + *val = PyExc_RecursionErrorInst; + Py_INCREF(*exc); + Py_INCREF(*val); + /* just keeping the old traceback */ return; } PyErr_NormalizeException(exc, val, tb); Modified: python/branches/py3k-short-float-repr/Python/getargs.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/getargs.c (original) +++ python/branches/py3k-short-float-repr/Python/getargs.c Mon Apr 13 18:30:54 2009 @@ -1147,7 +1147,7 @@ if ((Py_ssize_t)strlen(ptr) != size) { Py_DECREF(s); return converterr( - "(encoded string without NULL bytes)", + "encoded string without NULL bytes", arg, msgbuf, bufsize); } *buffer = PyMem_NEW(char, size + 1); Modified: python/branches/py3k-short-float-repr/Python/mysnprintf.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/mysnprintf.c (original) +++ python/branches/py3k-short-float-repr/Python/mysnprintf.c Mon Apr 13 18:30:54 2009 @@ -1,5 +1,4 @@ #include "Python.h" -#include /* snprintf() wrappers. If the platform has vsnprintf, we use it, else we emulate it in a half-hearted way. Even if the platform has it, we wrap Modified: python/branches/py3k-short-float-repr/Tools/msi/msilib.py ============================================================================== --- python/branches/py3k-short-float-repr/Tools/msi/msilib.py (original) +++ python/branches/py3k-short-float-repr/Tools/msi/msilib.py Mon Apr 13 18:30:54 2009 @@ -5,7 +5,7 @@ import win32com.client import pythoncom, pywintypes from win32com.client import constants -import re, string, os, sets, glob, subprocess, sys, winreg, struct +import re, string, os, sets, glob, subprocess, sys, _winreg, struct try: basestring @@ -387,9 +387,9 @@ (r"Software\Microsoft\Win32SDK\Directories", "Install Dir"), ]: try: - key = winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, k) - dir = winreg.QueryValueEx(key, v)[0] - winreg.CloseKey(key) + key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, k) + dir = _winreg.QueryValueEx(key, v)[0] + _winreg.CloseKey(key) except (WindowsError, IndexError): continue cabarc = os.path.join(dir, r"Bin", "cabarc.exe") Modified: python/branches/py3k-short-float-repr/setup.py ============================================================================== --- python/branches/py3k-short-float-repr/setup.py (original) +++ python/branches/py3k-short-float-repr/setup.py Mon Apr 13 18:30:54 2009 @@ -650,6 +650,42 @@ # implementation independent wrapper for these; dbm/dumb.py provides # similar functionality (but slower of course) implemented in Python. + # Sleepycat^WOracle Berkeley DB interface. + # http://www.oracle.com/database/berkeley-db/db/index.html + # + # This requires the Sleepycat^WOracle DB code. The supported versions + # are set below. Visit the URL above to download + # a release. Most open source OSes come with one or more + # versions of BerkeleyDB already installed. + + max_db_ver = (4, 7) + min_db_ver = (3, 3) + db_setup_debug = False # verbose debug prints from this script? + + def allow_db_ver(db_ver): + """Returns a boolean if the given BerkeleyDB version is acceptable. + + Args: + db_ver: A tuple of the version to verify. + """ + if not (min_db_ver <= db_ver <= max_db_ver): + return False + return True + + def gen_db_minor_ver_nums(major): + if major == 4: + for x in range(max_db_ver[1]+1): + if allow_db_ver((4, x)): + yield x + elif major == 3: + for x in (3,): + if allow_db_ver((3, x)): + yield x + else: + raise ValueError("unknown major BerkeleyDB version", major) + + # construct a list of paths to look for the header file in on + # top of the normal inc_dirs. db_inc_paths = [ '/usr/include/db4', '/usr/local/include/db4', @@ -661,8 +697,124 @@ '/sw/include/db4', '/sw/include/db3', ] + # 4.x minor number specific paths + for x in gen_db_minor_ver_nums(4): + db_inc_paths.append('/usr/include/db4%d' % x) + db_inc_paths.append('/usr/include/db4.%d' % x) + db_inc_paths.append('/usr/local/BerkeleyDB.4.%d/include' % x) + db_inc_paths.append('/usr/local/include/db4%d' % x) + db_inc_paths.append('/pkg/db-4.%d/include' % x) + db_inc_paths.append('/opt/db-4.%d/include' % x) + # MacPorts default (http://www.macports.org/) + db_inc_paths.append('/opt/local/include/db4%d' % x) + # 3.x minor number specific paths + for x in gen_db_minor_ver_nums(3): + db_inc_paths.append('/usr/include/db3%d' % x) + db_inc_paths.append('/usr/local/BerkeleyDB.3.%d/include' % x) + db_inc_paths.append('/usr/local/include/db3%d' % x) + db_inc_paths.append('/pkg/db-3.%d/include' % x) + db_inc_paths.append('/opt/db-3.%d/include' % x) + + # Add some common subdirectories for Sleepycat DB to the list, + # based on the standard include directories. This way DB3/4 gets + # picked up when it is installed in a non-standard prefix and + # the user has added that prefix into inc_dirs. + std_variants = [] + for dn in inc_dirs: + std_variants.append(os.path.join(dn, 'db3')) + std_variants.append(os.path.join(dn, 'db4')) + for x in gen_db_minor_ver_nums(4): + std_variants.append(os.path.join(dn, "db4%d"%x)) + std_variants.append(os.path.join(dn, "db4.%d"%x)) + for x in gen_db_minor_ver_nums(3): + std_variants.append(os.path.join(dn, "db3%d"%x)) + std_variants.append(os.path.join(dn, "db3.%d"%x)) + + db_inc_paths = std_variants + db_inc_paths + db_inc_paths = [p for p in db_inc_paths if os.path.exists(p)] + + db_ver_inc_map = {} + + class db_found(Exception): pass + try: + # See whether there is a Sleepycat header in the standard + # search path. + for d in inc_dirs + db_inc_paths: + f = os.path.join(d, "db.h") + if db_setup_debug: print("db: looking for db.h in", f) + if os.path.exists(f): + f = open(f).read() + m = re.search(r"#define\WDB_VERSION_MAJOR\W(\d+)", f) + if m: + db_major = int(m.group(1)) + m = re.search(r"#define\WDB_VERSION_MINOR\W(\d+)", f) + db_minor = int(m.group(1)) + db_ver = (db_major, db_minor) + + # Avoid 4.6 prior to 4.6.21 due to a BerkeleyDB bug + if db_ver == (4, 6): + m = re.search(r"#define\WDB_VERSION_PATCH\W(\d+)", f) + db_patch = int(m.group(1)) + if db_patch < 21: + print("db.h:", db_ver, "patch", db_patch, + "being ignored (4.6.x must be >= 4.6.21)") + continue + + if ( (db_ver not in db_ver_inc_map) and + allow_db_ver(db_ver) ): + # save the include directory with the db.h version + # (first occurrence only) + db_ver_inc_map[db_ver] = d + if db_setup_debug: + print("db.h: found", db_ver, "in", d) + else: + # we already found a header for this library version + if db_setup_debug: print("db.h: ignoring", d) + else: + # ignore this header, it didn't contain a version number + if db_setup_debug: + print("db.h: no version number version in", d) + + db_found_vers = list(db_ver_inc_map.keys()) + db_found_vers.sort() + + while db_found_vers: + db_ver = db_found_vers.pop() + db_incdir = db_ver_inc_map[db_ver] + + # check lib directories parallel to the location of the header + db_dirs_to_check = [ + db_incdir.replace("include", 'lib64'), + db_incdir.replace("include", 'lib'), + ] + db_dirs_to_check = list(filter(os.path.isdir, db_dirs_to_check)) + + # Look for a version specific db-X.Y before an ambiguoius dbX + # XXX should we -ever- look for a dbX name? Do any + # systems really not name their library by version and + # symlink to more general names? + for dblib in (('db-%d.%d' % db_ver), + ('db%d%d' % db_ver), + ('db%d' % db_ver[0])): + dblib_file = self.compiler.find_library_file( + db_dirs_to_check + lib_dirs, dblib ) + if dblib_file: + dblib_dir = [ os.path.abspath(os.path.dirname(dblib_file)) ] + raise db_found + else: + if db_setup_debug: print("db lib: ", dblib, "not found") - db_incs = None + except db_found: + if db_setup_debug: + print("bsddb using BerkeleyDB lib:", db_ver, dblib) + print("bsddb lib dir:", dblib_dir, " inc dir:", db_incdir) + db_incs = [db_incdir] + dblibs = [dblib] + else: + if db_setup_debug: print("db: no appropriate library found") + db_incs = None + dblibs = [] + dblib_dir = None # The sqlite interface sqlite_setup_debug = False # verbose debug prints from this script? @@ -1501,9 +1653,12 @@ ext_modules=[Extension('_struct', ['_struct.c'])], # Scripts to install - scripts = ['Tools/scripts/pydoc', 'Tools/scripts/idle', - 'Tools/scripts/2to3', - 'Lib/smtpd.py'] + # Commented out because we don't want them to override the 2.x + # ones. See #1590. + scripts = [] + #scripts = ['Tools/scripts/pydoc', 'Tools/scripts/idle', + # 'Tools/scripts/2to3', + # 'Lib/smtpd.py'] ) # --install-platlib From python-checkins at python.org Mon Apr 13 18:56:33 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 13 Apr 2009 18:56:33 +0200 (CEST) Subject: [Python-checkins] r71579 - python/trunk/Misc/NEWS Message-ID: <20090413165633.4D7331E403A@bag.python.org> Author: r.david.murray Date: Mon Apr 13 18:56:32 2009 New Revision: 71579 Log: Add missing NEWS item for issue1161031 fix. Modified: python/trunk/Misc/NEWS Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Apr 13 18:56:32 2009 @@ -221,6 +221,12 @@ Library ------- +- Issue #1161031: fix readwrite select flag handling: POLLPRI now + results in a handle_expt_event call, not handle_read_event, and POLLERR + and POLLNVAL now call handle_close, not handle_expt_event. Also, + dispatcher now has an 'ignore_log_types' attribute for suppressing + log messages, which is set to 'warning' by default. + - Issue #5607: fixed Distutils test_get_platform for Mac OS X fat binaries. - Issue #5741: don't disallow "%%" (which is an escape for "%") when setting From python-checkins at python.org Mon Apr 13 19:00:26 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 13 Apr 2009 19:00:26 +0200 (CEST) Subject: [Python-checkins] r71580 - in python/branches/py3k: Misc/NEWS Message-ID: <20090413170026.455971E403A@bag.python.org> Author: r.david.murray Date: Mon Apr 13 19:00:25 2009 New Revision: 71580 Log: Merged revisions 71579 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71579 | r.david.murray | 2009-04-13 12:56:32 -0400 (Mon, 13 Apr 2009) | 2 lines Add missing NEWS item for issue1161031 fix. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Apr 13 19:00:25 2009 @@ -12,6 +12,12 @@ Core and Builtins ----------------- +- Issue #1161031: fix readwrite select flag handling: POLLPRI now + results in a handle_expt_event call, not handle_read_event, and POLLERR + and POLLNVAL now call handle_close, not handle_expt_event. Also, + dispatcher now has an 'ignore_log_types' attribute for suppressing + log messages, which is set to 'warning' by default. + - The string.maketrans() function is deprecated; there is a new static method maketrans() on the bytes and bytearray classes. This removes confusion about the types string.maketrans() is supposed to work with, and mirrors the From python-checkins at python.org Mon Apr 13 19:06:33 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 13 Apr 2009 19:06:33 +0200 (CEST) Subject: [Python-checkins] r71581 - python/branches/py3k/Misc/NEWS Message-ID: <20090413170633.68A4E1E403A@bag.python.org> Author: r.david.murray Date: Mon Apr 13 19:06:33 2009 New Revision: 71581 Log: Move NEWS item to correct section. Modified: python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Apr 13 19:06:33 2009 @@ -12,12 +12,6 @@ Core and Builtins ----------------- -- Issue #1161031: fix readwrite select flag handling: POLLPRI now - results in a handle_expt_event call, not handle_read_event, and POLLERR - and POLLNVAL now call handle_close, not handle_expt_event. Also, - dispatcher now has an 'ignore_log_types' attribute for suppressing - log messages, which is set to 'warning' by default. - - The string.maketrans() function is deprecated; there is a new static method maketrans() on the bytes and bytearray classes. This removes confusion about the types string.maketrans() is supposed to work with, and mirrors the @@ -32,6 +26,12 @@ Library ------- +- Issue #1161031: fix readwrite select flag handling: POLLPRI now + results in a handle_expt_event call, not handle_read_event, and POLLERR + and POLLNVAL now call handle_close, not handle_expt_event. Also, + dispatcher now has an 'ignore_log_types' attribute for suppressing + log messages, which is set to 'warning' by default. + - Issue #2703: SimpleXMLRPCDispatcher.__init__: Provide default values for new arguments introduced in 2.5. From python-checkins at python.org Mon Apr 13 19:08:51 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 13 Apr 2009 19:08:51 +0200 (CEST) Subject: [Python-checkins] r71582 - python/branches/release30-maint/Misc/NEWS Message-ID: <20090413170851.19CE01E4064@bag.python.org> Author: r.david.murray Date: Mon Apr 13 19:08:50 2009 New Revision: 71582 Log: NEWS item for fix for Issue #1161031. Modified: python/branches/release30-maint/Misc/NEWS Modified: python/branches/release30-maint/Misc/NEWS ============================================================================== --- python/branches/release30-maint/Misc/NEWS (original) +++ python/branches/release30-maint/Misc/NEWS Mon Apr 13 19:08:50 2009 @@ -30,6 +30,12 @@ Library ------- +- Issue #1161031: fix readwrite select flag handling: POLLPRI now + results in a handle_expt_event call, not handle_read_event, and POLLERR + and POLLNVAL now call handle_close, not handle_expt_event. Also, + dispatcher now has an 'ignore_log_types' attribute for suppressing + log messages, which is set to 'warning' by default. + - Issue #1491431: Fixed distutils.filelist.glob_to_re for edge cases. Initial fix by Wayne Davison. From python-checkins at python.org Mon Apr 13 19:12:43 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 13 Apr 2009 19:12:43 +0200 (CEST) Subject: [Python-checkins] r71583 - python/branches/release30-maint Message-ID: <20090413171243.9DC3D1E403A@bag.python.org> Author: r.david.murray Date: Mon Apr 13 19:12:43 2009 New Revision: 71583 Log: Recorded merge of revisions 71580-71581 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71580 | r.david.murray | 2009-04-13 13:00:25 -0400 (Mon, 13 Apr 2009) | 9 lines Merged revisions 71579 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71579 | r.david.murray | 2009-04-13 12:56:32 -0400 (Mon, 13 Apr 2009) | 2 lines Add missing NEWS item for issue1161031 fix. ........ ................ r71581 | r.david.murray | 2009-04-13 13:06:33 -0400 (Mon, 13 Apr 2009) | 2 lines Move NEWS item to correct section. ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Mon Apr 13 19:20:45 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 13 Apr 2009 19:20:45 +0200 (CEST) Subject: [Python-checkins] r71584 - in python/branches/py3k-short-float-repr: Include/pyport.h Python/pystrtod.c Message-ID: <20090413172045.D4C031E4175@bag.python.org> Author: mark.dickinson Date: Mon Apr 13 19:20:45 2009 New Revision: 71584 Log: Force 53-bit precision for calls to _Py_dg_strtod and _Py_dg_dtoa Modified: python/branches/py3k-short-float-repr/Include/pyport.h python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Include/pyport.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/pyport.h (original) +++ python/branches/py3k-short-float-repr/Include/pyport.h Mon Apr 13 19:20:45 2009 @@ -465,6 +465,29 @@ errno = 0; \ } while(0) +/* The functions _Py_dg_strtod and _Py_dg_dtoa in Python/dtoa.c require that + the FPU is using 53-bit precision. Here are macros that force this. See + Python/pystrtod.c for an example of their use. */ + +#ifdef USING_X87_FPU +#define _Py_SET_53BIT_PRECISION_HEADER \ + unsigned short old_387controlword, new_387controlword +#define _Py_SET_53BIT_PRECISION_START \ + do { \ + old_387controlword = _Py_get_387controlword(); \ + new_387controlword = (old_387controlword & ~0x0f00) | 0x0200; \ + if (new_387controlword != old_387controlword) \ + _Py_set_387controlword(new_387controlword); \ + } while (0) +#define _Py_SET_53BIT_PRECISION_END \ + if (new_387controlword != old_387controlword) \ + _Py_set_387controlword(old_387controlword) +#else +#define _Py_SET_53BIT_PRECISION_HEADER +#define _Py_SET_53BIT_PRECISION_START +#define _Py_SET_53BIT_PRECISION_END +#endif + /* Py_DEPRECATED(version) * Declare a variable, type, or function deprecated. * Usage: Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Mon Apr 13 19:20:45 2009 @@ -40,11 +40,20 @@ double PyOS_ascii_strtod(const char *nptr, char **endptr) { + double result; + _Py_SET_53BIT_PRECISION_HEADER; + assert(nptr != NULL); /* Set errno to zero, so that we can distinguish zero results and underflows */ errno = 0; - return _Py_dg_strtod(nptr, endptr); + + _Py_SET_53BIT_PRECISION_START; + result = _Py_dg_strtod(nptr, endptr); + _Py_SET_53BIT_PRECISION_END; + + return result; + } double @@ -561,11 +570,15 @@ char *digits, *digits_end; int decpt_as_int, sign, exp_len, exp = 0, use_exp = 0; Py_ssize_t decpt, digits_len, vdigits_start, vdigits_end; + _Py_SET_53BIT_PRECISION_HEADER; /* _Py_dg_dtoa returns a digit string (no decimal point or exponent). Must be matched by a call to _Py_dg_freedtoa. */ + _Py_SET_53BIT_PRECISION_START; digits = _Py_dg_dtoa(d, mode, precision, &decpt_as_int, &sign, &digits_end); + _Py_SET_53BIT_PRECISION_END; + decpt = (Py_ssize_t)decpt_as_int; if (digits == NULL) { /* The only failure mode is no memory. */ From python-checkins at python.org Mon Apr 13 22:03:45 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 13 Apr 2009 22:03:45 +0200 (CEST) Subject: [Python-checkins] r71585 - in python/trunk/Lib/distutils: cmd.py tests/test_cmd.py Message-ID: <20090413200345.45A871E4002@bag.python.org> Author: tarek.ziade Date: Mon Apr 13 22:03:44 2009 New Revision: 71585 Log: improved test coverage for distutils.cmd Modified: python/trunk/Lib/distutils/cmd.py python/trunk/Lib/distutils/tests/test_cmd.py Modified: python/trunk/Lib/distutils/cmd.py ============================================================================== --- python/trunk/Lib/distutils/cmd.py (original) +++ python/trunk/Lib/distutils/cmd.py Mon Apr 13 22:03:44 2009 @@ -214,7 +214,7 @@ # and they can be guaranteed that thereafter, self.foo will be # a list of strings. - def _ensure_stringlike (self, option, what, default=None): + def _ensure_stringlike(self, option, what, default=None): val = getattr(self, option) if val is None: setattr(self, option, default) @@ -224,13 +224,13 @@ "'%s' must be a %s (got `%s`)" % (option, what, val) return val - def ensure_string (self, option, default=None): + def ensure_string(self, option, default=None): """Ensure that 'option' is a string; if not defined, set it to 'default'. """ self._ensure_stringlike(option, "string", default) - def ensure_string_list (self, option): + def ensure_string_list(self, option): """Ensure that 'option' is a list of strings. If 'option' is currently a string, we split it either on /,\s*/ or /\s+/, so "foo bar baz", "foo,bar,baz", and "foo, bar baz" all become @@ -258,20 +258,20 @@ (option, val) - def _ensure_tested_string (self, option, tester, - what, error_fmt, default=None): + def _ensure_tested_string(self, option, tester, + what, error_fmt, default=None): val = self._ensure_stringlike(option, what, default) if val is not None and not tester(val): raise DistutilsOptionError, \ ("error in '%s' option: " + error_fmt) % (option, val) - def ensure_filename (self, option): + def ensure_filename(self, option): """Ensure that 'option' is the name of an existing file.""" self._ensure_tested_string(option, os.path.isfile, "filename", "'%s' does not exist or is not a file") - def ensure_dirname (self, option): + def ensure_dirname(self, option): self._ensure_tested_string(option, os.path.isdir, "directory name", "'%s' does not exist or is not a directory") Modified: python/trunk/Lib/distutils/tests/test_cmd.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_cmd.py (original) +++ python/trunk/Lib/distutils/tests/test_cmd.py Mon Apr 13 22:03:44 2009 @@ -1,5 +1,6 @@ """Tests for distutils.cmd.""" import unittest +import os from distutils.cmd import Command from distutils.dist import Distribution @@ -62,6 +63,45 @@ ' option2 = 1'] self.assertEquals(msgs, wanted) + def test_ensure_string(self): + cmd = self.cmd + cmd.option1 = 'ok' + cmd.ensure_string('option1') + + cmd.option2 = None + cmd.ensure_string('option2', 'xxx') + self.assert_(hasattr(cmd, 'option2')) + + cmd.option3 = 1 + self.assertRaises(DistutilsOptionError, cmd.ensure_string, 'option3') + + def test_ensure_string_list(self): + cmd = self.cmd + cmd.option1 = 'ok,dok' + cmd.ensure_string_list('option1') + self.assertEquals(cmd.option1, ['ok', 'dok']) + + cmd.option2 = ['xxx', 'www'] + cmd.ensure_string_list('option2') + + cmd.option3 = ['ok', 2] + self.assertRaises(DistutilsOptionError, cmd.ensure_string_list, + 'option3') + + def test_ensure_filename(self): + cmd = self.cmd + cmd.option1 = __file__ + cmd.ensure_filename('option1') + cmd.option2 = 'xxx' + self.assertRaises(DistutilsOptionError, cmd.ensure_filename, 'option2') + + def test_ensure_dirname(self): + cmd = self.cmd + cmd.option1 = os.path.dirname(__file__) + cmd.ensure_dirname('option1') + cmd.option2 = 'xxx' + self.assertRaises(DistutilsOptionError, cmd.ensure_dirname, 'option2') + def test_suite(): return unittest.makeSuite(CommandTestCase) From python-checkins at python.org Mon Apr 13 22:05:17 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 13 Apr 2009 22:05:17 +0200 (CEST) Subject: [Python-checkins] r71586 - python/branches/release26-maint Message-ID: <20090413200517.867AF1E4300@bag.python.org> Author: tarek.ziade Date: Mon Apr 13 22:05:17 2009 New Revision: 71586 Log: Blocked revisions 71585 via svnmerge ........ r71585 | tarek.ziade | 2009-04-13 22:03:44 +0200 (Mon, 13 Apr 2009) | 1 line improved test coverage for distutils.cmd ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Apr 13 22:07:24 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 13 Apr 2009 22:07:24 +0200 (CEST) Subject: [Python-checkins] r71587 - in python/branches/py3k: Lib/distutils/tests/test_cmd.py Message-ID: <20090413200724.180A61E4002@bag.python.org> Author: tarek.ziade Date: Mon Apr 13 22:07:23 2009 New Revision: 71587 Log: Merged revisions 71585 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71585 | tarek.ziade | 2009-04-13 22:03:44 +0200 (Mon, 13 Apr 2009) | 1 line improved test coverage for distutils.cmd ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/tests/test_cmd.py Modified: python/branches/py3k/Lib/distutils/tests/test_cmd.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_cmd.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_cmd.py Mon Apr 13 22:07:23 2009 @@ -1,5 +1,6 @@ """Tests for distutils.cmd.""" import unittest +import os from distutils.cmd import Command from distutils.dist import Distribution @@ -62,6 +63,45 @@ ' option2 = 1'] self.assertEquals(msgs, wanted) + def test_ensure_string(self): + cmd = self.cmd + cmd.option1 = 'ok' + cmd.ensure_string('option1') + + cmd.option2 = None + cmd.ensure_string('option2', 'xxx') + self.assert_(hasattr(cmd, 'option2')) + + cmd.option3 = 1 + self.assertRaises(DistutilsOptionError, cmd.ensure_string, 'option3') + + def test_ensure_string_list(self): + cmd = self.cmd + cmd.option1 = 'ok,dok' + cmd.ensure_string_list('option1') + self.assertEquals(cmd.option1, ['ok', 'dok']) + + cmd.option2 = ['xxx', 'www'] + cmd.ensure_string_list('option2') + + cmd.option3 = ['ok', 2] + self.assertRaises(DistutilsOptionError, cmd.ensure_string_list, + 'option3') + + def test_ensure_filename(self): + cmd = self.cmd + cmd.option1 = __file__ + cmd.ensure_filename('option1') + cmd.option2 = 'xxx' + self.assertRaises(DistutilsOptionError, cmd.ensure_filename, 'option2') + + def test_ensure_dirname(self): + cmd = self.cmd + cmd.option1 = os.path.dirname(__file__) + cmd.ensure_dirname('option1') + cmd.option2 = 'xxx' + self.assertRaises(DistutilsOptionError, cmd.ensure_dirname, 'option2') + def test_suite(): return unittest.makeSuite(CommandTestCase) From python-checkins at python.org Mon Apr 13 22:08:14 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 13 Apr 2009 22:08:14 +0200 (CEST) Subject: [Python-checkins] r71588 - python/branches/release30-maint Message-ID: <20090413200814.619961E4002@bag.python.org> Author: tarek.ziade Date: Mon Apr 13 22:08:14 2009 New Revision: 71588 Log: Blocked revisions 71571 via svnmerge ................ r71571 | tarek.ziade | 2009-04-13 14:59:03 +0200 (Mon, 13 Apr 2009) | 9 lines Merged revisions 71569 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71569 | tarek.ziade | 2009-04-13 14:42:26 +0200 (Mon, 13 Apr 2009) | 1 line deactivate test_search_cpp under win32 ........ ................ Modified: python/branches/release30-maint/ (props changed) From nnorwitz at gmail.com Mon Apr 13 22:12:41 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 13 Apr 2009 16:12:41 -0400 Subject: [Python-checkins] Python Regression Test Failures basics (1) Message-ID: <20090413201241.GA26366@python.psfb.org> 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23366 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 test_lib2to3 failed -- errors occurred; run in verbose mode for details 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 -- OSError raises on RLock creation, see issue 3111! test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18902 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [741934 refs] From python-checkins at python.org Mon Apr 13 22:14:55 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 13 Apr 2009 22:14:55 +0200 (CEST) Subject: [Python-checkins] r71589 - python/trunk/Lib/distutils/cmd.py Message-ID: <20090413201455.34AE21E40E2@bag.python.org> Author: tarek.ziade Date: Mon Apr 13 22:14:54 2009 New Revision: 71589 Log: pep8-fied Modified: python/trunk/Lib/distutils/cmd.py Modified: python/trunk/Lib/distutils/cmd.py ============================================================================== --- python/trunk/Lib/distutils/cmd.py (original) +++ python/trunk/Lib/distutils/cmd.py Mon Apr 13 22:14:54 2009 @@ -46,7 +46,7 @@ # -- Creation/initialization methods ------------------------------- - def __init__ (self, dist): + def __init__(self, dist): """Create and initialize a new Command object. Most importantly, invokes the 'initialize_options()' method, which is the real initializer and depends on the actual command being @@ -93,12 +93,8 @@ # always calls 'finalize_options()', to respect/update it. self.finalized = 0 - # __init__ () - - # XXX A more explicit way to customize dry_run would be better. - - def __getattr__ (self, attr): + def __getattr__(self, attr): if attr == 'dry_run': myval = getattr(self, "_" + attr) if myval is None: @@ -108,13 +104,11 @@ else: raise AttributeError, attr - - def ensure_finalized (self): + def ensure_finalized(self): if not self.finalized: self.finalize_options() self.finalized = 1 - # Subclasses must define: # initialize_options() # provide default values for all options; may be customized by @@ -128,7 +122,7 @@ # run the command: do whatever it is we're here to do, # controlled by the command's various option values - def initialize_options (self): + def initialize_options(self): """Set default values for all the options that this command supports. Note that these defaults may be overridden by other commands, by the setup script, by config files, or by the @@ -141,7 +135,7 @@ raise RuntimeError, \ "abstract method -- subclass %s must override" % self.__class__ - def finalize_options (self): + def finalize_options(self): """Set final values for all the options that this command supports. This is always called as late as possible, ie. after any option assignments from the command-line or from other commands have been @@ -170,7 +164,7 @@ self.announce(indent + "%s = %s" % (option, value), level=log.INFO) - def run (self): + def run(self): """A command's raison d'etre: carry out the action it exists to perform, controlled by the options initialized in 'initialize_options()', customized by other commands, the setup @@ -180,17 +174,16 @@ This method must be implemented by all command classes. """ - raise RuntimeError, \ "abstract method -- subclass %s must override" % self.__class__ - def announce (self, msg, level=1): + def announce(self, msg, level=1): """If the current verbosity level is of greater than or equal to 'level' print 'msg' to stdout. """ log.log(level, msg) - def debug_print (self, msg): + def debug_print(self, msg): """Print 'msg' to stdout if the global DEBUG (taken from the DISTUTILS_DEBUG environment variable) flag is true. """ @@ -200,7 +193,6 @@ sys.stdout.flush() - # -- Option validation methods ------------------------------------- # (these are very handy in writing the 'finalize_options()' method) # @@ -279,14 +271,13 @@ # -- Convenience methods for commands ------------------------------ - def get_command_name (self): + def get_command_name(self): if hasattr(self, 'command_name'): return self.command_name else: return self.__class__.__name__ - - def set_undefined_options (self, src_cmd, *option_pairs): + def set_undefined_options(self, src_cmd, *option_pairs): """Set the values of any "undefined" options from corresponding option values in some other command object. "Undefined" here means "is None", which is the convention used to indicate that an option @@ -311,7 +302,7 @@ getattr(src_cmd_obj, src_option)) - def get_finalized_command (self, command, create=1): + def get_finalized_command(self, command, create=1): """Wrapper around Distribution's 'get_command_obj()' method: find (create if necessary and 'create' is true) the command object for 'command', call its 'ensure_finalized()' method, and return the @@ -323,19 +314,18 @@ # XXX rename to 'get_reinitialized_command()'? (should do the # same in dist.py, if so) - def reinitialize_command (self, command, reinit_subcommands=0): + def reinitialize_command(self, command, reinit_subcommands=0): return self.distribution.reinitialize_command( command, reinit_subcommands) - def run_command (self, command): + def run_command(self, command): """Run some other command: uses the 'run_command()' method of Distribution, which creates and finalizes the command object if necessary and then invokes its 'run()' method. """ self.distribution.run_command(command) - - def get_sub_commands (self): + def get_sub_commands(self): """Determine the sub-commands that are relevant in the current distribution (ie., that need to be run). This is based on the 'sub_commands' class attribute: each tuple in that list may include @@ -351,19 +341,17 @@ # -- External world manipulation ----------------------------------- - def warn (self, msg): + def warn(self, msg): log.warn("warning: %s: %s\n" % (self.get_command_name(), msg)) - def execute (self, func, args, msg=None, level=1): + def execute(self, func, args, msg=None, level=1): util.execute(func, args, msg, dry_run=self.dry_run) - - def mkpath (self, name, mode=0777): + def mkpath(self, name, mode=0777): dir_util.mkpath(name, mode, dry_run=self.dry_run) - - def copy_file (self, infile, outfile, + def copy_file(self, infile, outfile, preserve_mode=1, preserve_times=1, link=None, level=1): """Copy a file respecting verbose, dry-run and force flags. (The former two default to whatever is in the Distribution object, and @@ -376,8 +364,7 @@ link, dry_run=self.dry_run) - - def copy_tree (self, infile, outfile, + def copy_tree(self, infile, outfile, preserve_mode=1, preserve_times=1, preserve_symlinks=0, level=1): """Copy an entire directory tree respecting verbose, dry-run, @@ -403,7 +390,6 @@ return archive_util.make_archive( base_name, format, root_dir, base_dir, dry_run=self.dry_run) - def make_file(self, infiles, outfile, func, args, exec_msg=None, skip_msg=None, level=1): """Special case of 'execute()' for operations that process one or @@ -438,17 +424,12 @@ else: log.debug(skip_msg) - # make_file () - -# class Command - - # XXX 'install_misc' class not currently used -- it was the base class for # both 'install_scripts' and 'install_data', but they outgrew it. It might # still be useful for 'install_headers', though, so I'm keeping it around # for the time being. -class install_misc (Command): +class install_misc(Command): """Common base class for installing some files in a subdirectory. Currently used by install_data and install_scripts. """ @@ -459,10 +440,10 @@ self.install_dir = None self.outfiles = [] - def _install_dir_from (self, dirname): + def _install_dir_from(self, dirname): self.set_undefined_options('install', (dirname, 'install_dir')) - def _copy_files (self, filelist): + def _copy_files(self, filelist): self.outfiles = [] if not filelist: return @@ -471,5 +452,5 @@ self.copy_file(f, self.install_dir) self.outfiles.append(os.path.join(self.install_dir, f)) - def get_outputs (self): + def get_outputs(self): return self.outfiles From python-checkins at python.org Mon Apr 13 22:19:58 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 13 Apr 2009 22:19:58 +0200 (CEST) Subject: [Python-checkins] r71590 - in python/branches/py3k: Lib/distutils/cmd.py Message-ID: <20090413201958.C3FB51E4002@bag.python.org> Author: tarek.ziade Date: Mon Apr 13 22:19:58 2009 New Revision: 71590 Log: Merged revisions 71589 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71589 | tarek.ziade | 2009-04-13 22:14:54 +0200 (Mon, 13 Apr 2009) | 1 line pep8-fied ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/cmd.py Modified: python/branches/py3k/Lib/distutils/cmd.py ============================================================================== --- python/branches/py3k/Lib/distutils/cmd.py (original) +++ python/branches/py3k/Lib/distutils/cmd.py Mon Apr 13 22:19:58 2009 @@ -93,9 +93,8 @@ # always calls 'finalize_options()', to respect/update it. self.finalized = 0 - # XXX A more explicit way to customize dry_run would be better. - def __getattr__ (self, attr): + def __getattr__(self, attr): if attr == 'dry_run': myval = getattr(self, "_" + attr) if myval is None: @@ -105,7 +104,7 @@ else: raise AttributeError(attr) - def ensure_finalized (self): + def ensure_finalized(self): if not self.finalized: self.finalize_options() self.finalized = 1 @@ -175,7 +174,6 @@ This method must be implemented by all command classes. """ - raise RuntimeError("abstract method -- subclass %s must override" % self.__class__) @@ -351,7 +349,7 @@ preserve_times, not self.force, link, dry_run=self.dry_run) - def copy_tree (self, infile, outfile, preserve_mode=1, preserve_times=1, + def copy_tree(self, infile, outfile, preserve_mode=1, preserve_times=1, preserve_symlinks=0, level=1): """Copy an entire directory tree respecting verbose, dry-run, and force flags. @@ -373,7 +371,6 @@ return archive_util.make_archive(base_name, format, root_dir, base_dir, dry_run=self.dry_run) - def make_file(self, infiles, outfile, func, args, exec_msg=None, skip_msg=None, level=1): """Special case of 'execute()' for operations that process one or @@ -406,7 +403,6 @@ else: log.debug(skip_msg) - # XXX 'install_misc' class not currently used -- it was the base class for # both 'install_scripts' and 'install_data', but they outgrew it. It might # still be useful for 'install_headers', though, so I'm keeping it around @@ -423,10 +419,10 @@ self.install_dir = None self.outfiles = [] - def _install_dir_from (self, dirname): + def _install_dir_from(self, dirname): self.set_undefined_options('install', (dirname, 'install_dir')) - def _copy_files (self, filelist): + def _copy_files(self, filelist): self.outfiles = [] if not filelist: return @@ -435,5 +431,5 @@ self.copy_file(f, self.install_dir) self.outfiles.append(os.path.join(self.install_dir, f)) - def get_outputs (self): + def get_outputs(self): return self.outfiles From python-checkins at python.org Mon Apr 13 22:26:34 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 13 Apr 2009 22:26:34 +0200 (CEST) Subject: [Python-checkins] r71591 - in python/branches/py3k-short-float-repr/Python: ast.c marshal.c Message-ID: <20090413202634.9C1C61E4033@bag.python.org> Author: mark.dickinson Date: Mon Apr 13 22:26:33 2009 New Revision: 71591 Log: Revert PyOS_ascii_atof -> PyOS_ascii_strtod changes Modified: python/branches/py3k-short-float-repr/Python/ast.c python/branches/py3k-short-float-repr/Python/marshal.c Modified: python/branches/py3k-short-float-repr/Python/ast.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/ast.c (original) +++ python/branches/py3k-short-float-repr/Python/ast.c Mon Apr 13 22:26:33 2009 @@ -3162,16 +3162,16 @@ #ifndef WITHOUT_COMPLEX if (imflag) { compl.real = 0.; - PyFPE_START_PROTECT("strtod", return 0) - compl.imag = PyOS_ascii_strtod(s, NULL); + PyFPE_START_PROTECT("atof", return 0) + compl.imag = PyOS_ascii_atof(s); PyFPE_END_PROTECT(c) return PyComplex_FromCComplex(compl); } else #endif { - PyFPE_START_PROTECT("strtod", return 0) - dx = PyOS_ascii_strtod(s, NULL); + PyFPE_START_PROTECT("atof", return 0) + dx = PyOS_ascii_atof(s); PyFPE_END_PROTECT(dx) return PyFloat_FromDouble(dx); } Modified: python/branches/py3k-short-float-repr/Python/marshal.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/marshal.c (original) +++ python/branches/py3k-short-float-repr/Python/marshal.c Mon Apr 13 22:26:33 2009 @@ -666,8 +666,8 @@ } buf[n] = '\0'; retval = NULL; - PyFPE_START_PROTECT("strtod", break) - dx = PyOS_ascii_strtod(buf, NULL); + PyFPE_START_PROTECT("atof", break) + dx = PyOS_ascii_atof(buf); PyFPE_END_PROTECT(dx) retval = PyFloat_FromDouble(dx); break; @@ -706,8 +706,8 @@ } buf[n] = '\0'; retval = NULL; - PyFPE_START_PROTECT("strtod", break;) - c.real = PyOS_ascii_strtod(buf, NULL); + PyFPE_START_PROTECT("atof", break;) + c.real = PyOS_ascii_atof(buf); PyFPE_END_PROTECT(c) n = r_byte(p); if (n == EOF || r_string(buf, (int)n, p) != n) { @@ -717,8 +717,8 @@ break; } buf[n] = '\0'; - PyFPE_START_PROTECT("strtod", break) - c.imag = PyOS_ascii_strtod(buf, NULL); + PyFPE_START_PROTECT("atof", break) + c.imag = PyOS_ascii_atof(buf); PyFPE_END_PROTECT(c) retval = PyComplex_FromCComplex(c); break; From nnorwitz at gmail.com Mon Apr 13 22:26:36 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Mon, 13 Apr 2009 16:26:36 -0400 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20090413202636.GA30968@python.psfb.org> 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils [17363 refs] [17363 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23366 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 test_lib2to3 failed -- errors occurred; run in verbose mode for details 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 -- OSError raises on RLock creation, see issue 3111! test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18902 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [741174 refs] From python-checkins at python.org Mon Apr 13 22:52:59 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 13 Apr 2009 22:52:59 +0200 (CEST) Subject: [Python-checkins] r71592 - in peps/trunk: pep-0333.txt pep-0376.txt Message-ID: <20090413205259.E5A711E4029@bag.python.org> Author: tarek.ziade Date: Mon Apr 13 22:52:58 2009 New Revision: 71592 Log: pkg_name -> project_name Modified: peps/trunk/pep-0333.txt peps/trunk/pep-0376.txt Modified: peps/trunk/pep-0333.txt ============================================================================== --- peps/trunk/pep-0333.txt (original) +++ peps/trunk/pep-0333.txt Mon Apr 13 22:52:58 2009 @@ -179,7 +179,7 @@ returns an instance of 'AppClass', which is then the iterable return value of the "application callable" as required by the spec. - + If we wanted to use *instances* of 'AppClass' as application objects instead, we would have to implement a '__call__' method, which would be invoked to execute the application, @@ -204,9 +204,9 @@ The server or gateway invokes the application callable once for each request it receives from an HTTP client, that is directed at the application. To illustrate, here is a simple CGI gateway, implemented -as a function taking an application object. Note that this simple -example has limited error handling, because by default an uncaught -exception will be dumped to ``sys.stderr`` and logged by the web +as a function taking an application object. Note that this simple +example has limited error handling, because by default an uncaught +exception will be dumped to ``sys.stderr`` and logged by the web server. :: @@ -256,7 +256,7 @@ exc_info = None # avoid dangling circular ref elif headers_set: raise AssertionError("Headers already set!") - + headers_set[:] = [status,response_headers] return write @@ -294,13 +294,13 @@ The presence of middleware in general is transparent to both the "server/gateway" and the "application/framework" sides of the interface, and should require no special support. A user who -desires to incorporate middleware into an application simply -provides the middleware component to the server, as if it were +desires to incorporate middleware into an application simply +provides the middleware component to the server, as if it were an application, and configures the middleware component to invoke the application, as if the middleware component were a server. Of course, the "application" that the middleware wraps may in fact be another middleware component wrapping another -application, and so on, creating what is referred to as a +application, and so on, creating what is referred to as a "middleware stack". For the most part, middleware must conform to the restrictions @@ -311,7 +311,7 @@ Here is a (tongue-in-cheek) example of a middleware component that converts ``text/plain`` responses to pig latin, using Joe Strout's -``piglatin.py``. (Note: a "real" middleware component would +``piglatin.py``. (Note: a "real" middleware component would probably use a more robust way of checking the content type, and should also check for a content encoding. Also, this simple example ignores the possibility that a word might be split across @@ -320,11 +320,11 @@ :: from piglatin import piglatin - + class LatinIter: """Transform iterated output to piglatin, if it's okay to do so - + Note that the "okayness" can change until the application yields its first non-empty string, so 'transform_ok' has to be a mutable truth value.""" @@ -347,30 +347,30 @@ class Latinator: # by default, don't transform output - transform = False + transform = False def __init__(self, application): self.application = application def __call__(self, environ, start_response): - + transform_ok = [] - + def start_latin(status,response_headers,exc_info=None): # Reset ok flag, in case this is a repeat call - transform_ok[:]=[] + transform_ok[:]=[] for name,value in response_headers: if name.lower()=='content-type' and value=='text/plain': transform_ok.append(True) # Strip content-length if present, else it'll be wrong - response_headers = [(name,value) - for name,value in response_headers + response_headers = [(name,value) + for name,value in response_headers if name.lower()<>'content-length' ] break - + write = start_response(status,response_headers,exc_info) if transform_ok: @@ -417,7 +417,7 @@ ``start_response(status,response_headers)``). The ``status`` parameter is a status string of the form -``"999 Message here"``, and ``response_headers`` is a list of +``"999 Message here"``, and ``response_headers`` is a list of ``(header_name,header_value)`` tuples describing the HTTP response header. The optional ``exc_info`` parameter is described below in the sections on `The start_response() Callable`_ and `Error Handling`_. @@ -425,14 +425,14 @@ attempting to display an error message to the browser. The ``start_response`` callable must return a ``write(body_data)`` -callable that takes one positional parameter: a string to be written +callable that takes one positional parameter: a string to be written as part of the HTTP response body. (Note: the ``write()`` callable is provided only to support certain existing frameworks' imperative output APIs; it should not be used by new applications or frameworks if it can be avoided. See the `Buffering and Streaming`_ section for more details.) -When called by the server, the application object must return an +When called by the server, the application object must return an iterable yielding zero or more strings. This can be accomplished in a variety of ways, such as by returning a list of strings, or by the application being a generator function that yields strings, or @@ -440,10 +440,10 @@ Regardless of how it is accomplished, the application object must always return an iterable yielding zero or more strings. -The server or gateway must transmit the yielded strings to the client -in an unbuffered fashion, completing the transmission of each string +The server or gateway must transmit the yielded strings to the client +in an unbuffered fashion, completing the transmission of each string before requesting another one. (In other words, applications -**should** perform their own buffering. See the `Buffering and +**should** perform their own buffering. See the `Buffering and Streaming`_ section below for more on how application output must be handled.) @@ -456,21 +456,21 @@ such as byte-range transmission. See `Other HTTP Features`_, below, for more details.) -If a call to ``len(iterable)`` succeeds, the server must be able -to rely on the result being accurate. That is, if the iterable -returned by the application provides a working ``__len__()`` +If a call to ``len(iterable)`` succeeds, the server must be able +to rely on the result being accurate. That is, if the iterable +returned by the application provides a working ``__len__()`` method, it **must** return an accurate result. (See the `Handling the Content-Length Header`_ section for information on how this would normally be used.) If the iterable returned by the application has a ``close()`` method, the server or gateway **must** call that method upon completion of the -current request, whether the request was completed normally, or +current request, whether the request was completed normally, or terminated early due to an error. (This is to support resource release by the application. This protocol is intended to complement PEP 325's generator support, and other common iterables with ``close()`` methods. -(Note: the application **must** invoke the ``start_response()`` +(Note: the application **must** invoke the ``start_response()`` callable before the iterable yields its first body string, so that the server can send the headers before any body content. However, this invocation **may** be performed by the iterable's first iteration, so @@ -480,8 +480,8 @@ Finally, servers and gateways **must not** directly use any other attributes of the iterable returned by the application, unless it is an instance of a type specific to that server or gateway, such as a "file -wrapper" returned by ``wsgi.file_wrapper`` (see `Optional -Platform-Specific File Handling`_). In the general case, only +wrapper" returned by ``wsgi.file_wrapper`` (see `Optional +Platform-Specific File Handling`_). In the general case, only attributes specified here, or accessed via e.g. the PEP 234 iteration APIs are acceptable. @@ -496,19 +496,19 @@ **may** be omitted, except as otherwise noted below. ``REQUEST_METHOD`` - The HTTP request method, such as ``"GET"`` or ``"POST"``. This + The HTTP request method, such as ``"GET"`` or ``"POST"``. This cannot ever be an empty string, and so is always required. -``SCRIPT_NAME`` +``SCRIPT_NAME`` The initial portion of the request URL's "path" that corresponds to - the application object, so that the application knows its virtual + the application object, so that the application knows its virtual "location". This **may** be an empty string, if the application - corresponds to the "root" of the server. + corresponds to the "root" of the server. ``PATH_INFO`` - The remainder of the request URL's "path", designating the virtual + The remainder of the request URL's "path", designating the virtual "location" of the request's target within the application. This - **may** be an empty string, if the request URL targets the + **may** be an empty string, if the request URL targets the application root and does not have a trailing slash. ``QUERY_STRING`` @@ -547,7 +547,7 @@ absence of these variables should correspond with the presence or absence of the appropriate HTTP header in the request. -A server or gateway **should** attempt to provide as many other CGI +A server or gateway **should** attempt to provide as many other CGI variables as are applicable. In addition, if SSL is in use, the server or gateway **should** also provide as many of the Apache SSL environment variables [5]_ as are applicable, such as ``HTTPS=on`` and @@ -559,7 +559,7 @@ A WSGI-compliant server or gateway **should** document what variables it provides, along with their definitions as appropriate. Applications -**should** check for the presence of any variables they require, and +**should** check for the presence of any variables they require, and have a fallback plan in the event such a variable is absent. Note: missing variables (such as ``REMOTE_USER`` when no @@ -579,20 +579,20 @@ version 1.0. ``wsgi.url_scheme`` A string representing the "scheme" portion of - the URL at which the application is being + the URL at which the application is being invoked. Normally, this will have the value ``"http"`` or ``"https"``, as appropriate. ``wsgi.input`` An input stream (file-like object) from which the HTTP request body can be read. (The server - or gateway may perform reads on-demand as + or gateway may perform reads on-demand as requested by the application, or it may pre- read the client's request body and buffer it in-memory or on disk, or use any other technique for providing such an input stream, according to its preference.) -``wsgi.errors`` An output stream (file-like object) to which +``wsgi.errors`` An output stream (file-like object) to which error output can be written, for the purpose of recording program or other errors in a standardized and possibly centralized location. @@ -610,13 +610,13 @@ or gateway may supply different error streams to different applications, if this is desired. -``wsgi.multithread`` This value should evaluate true if the +``wsgi.multithread`` This value should evaluate true if the application object may be simultaneously invoked by another thread in the same process, and should evaluate false otherwise. -``wsgi.multiprocess`` This value should evaluate true if an - equivalent application object may be +``wsgi.multiprocess`` This value should evaluate true if an + equivalent application object may be simultaneously invoked by another process, and should evaluate false otherwise. @@ -696,12 +696,12 @@ (As with all WSGI callables, the arguments must be supplied positionally, not by keyword.) The ``start_response`` callable is used to begin the HTTP response, and it must return a -``write(body_data)`` callable (see the `Buffering and Streaming`_ +``write(body_data)`` callable (see the `Buffering and Streaming`_ section, below). The ``status`` argument is an HTTP "status" string like ``"200 OK"`` -or ``"404 Not Found"``. That is, it is a string consisting of a -Status-Code and a Reason-Phrase, in that order and separated by a +or ``"404 Not Found"``. That is, it is a string consisting of a +Status-Code and a Reason-Phrase, in that order and separated by a single space, with no surrounding whitespace or other characters. (See RFC 2616, Section 6.1.1 for more information.) The string **must not** contain control characters, and must not be terminated @@ -733,11 +733,11 @@ Applications and middleware are forbidden from using HTTP/1.1 "hop-by-hop" features or headers, any equivalent features in HTTP/1.0, -or any headers that would affect the persistence of the client's +or any headers that would affect the persistence of the client's connection to the web server. These features are the exclusive province of the actual web server, and a server or gateway **should** consider it a fatal error for an application to attempt -sending them, and raise an error if they are supplied to +sending them, and raise an error if they are supplied to ``start_response()``. (For more specifics on "hop-by-hop" features and headers, please see the `Other HTTP Features`_ section below.) @@ -748,7 +748,7 @@ the application's first invocation of the ``write()`` callable. In other words, response headers must not be sent until there is actual body data available, or until the application's returned iterable is -exhausted. (The only possible exception to this rule is if the +exhausted. (The only possible exception to this rule is if the response headers explicitly include a ``Content-Length`` of zero.) This delaying of response header transmission is to ensure that buffered @@ -772,12 +772,12 @@ raise the ``exc_info`` tuple. That is:: raise exc_info[0],exc_info[1],exc_info[2] - + This will re-raise the exception trapped by the application, and in -principle should abort the application. (It is not safe for the +principle should abort the application. (It is not safe for the application to attempt error output to the browser once the HTTP headers have already been sent.) The application **must not** trap -any exceptions raised by ``start_response``, if it called +any exceptions raised by ``start_response``, if it called ``start_response`` with ``exc_info``. Instead, it should allow such exceptions to propagate back to the server or gateway. See `Error Handling`_ below, for more details. @@ -790,7 +790,7 @@ gateway above for an illustration of the correct logic.) Note: servers, gateways, or middleware implementing ``start_response`` -**should** ensure that no reference is held to the ``exc_info`` +**should** ensure that no reference is held to the ``exc_info`` parameter beyond the duration of the function's execution, to avoid creating a circular reference through the traceback and frames involved. The simplest way to do this is something like:: @@ -833,7 +833,7 @@ (Note: applications and middleware **must not** apply any kind of ``Transfer-Encoding`` to their output, such as chunking or gzipping; -as "hop-by-hop" operations, these encodings are the province of the +as "hop-by-hop" operations, these encodings are the province of the actual web server/gateway. See `Other HTTP Features`_ below, for more details.) @@ -842,7 +842,7 @@ ----------------------- Generally speaking, applications will achieve the best throughput -by buffering their (modestly-sized) output and sending it all at +by buffering their (modestly-sized) output and sending it all at once. This is a common approach in existing frameworks such as Zope: the output is buffered in a StringIO or similar object, then transmitted all at once, along with the response headers. @@ -850,37 +850,37 @@ The corresponding approach in WSGI is for the application to simply return a single-element iterable (such as a list) containing the response body as a single string. This is the recommended approach -for the vast majority of application functions, that render +for the vast majority of application functions, that render HTML pages whose text easily fits in memory. For large files, however, or for specialized uses of HTTP streaming (such as multipart "server push"), an application may need to provide -output in smaller blocks (e.g. to avoid loading a large file into +output in smaller blocks (e.g. to avoid loading a large file into memory). It's also sometimes the case that part of a response may be time-consuming to produce, but it would be useful to send ahead the portion of the response that precedes it. In these cases, applications will usually return an iterator (often a generator-iterator) that produces the output in a block-by-block -fashion. These blocks may be broken to coincide with mulitpart -boundaries (for "server push"), or just before time-consuming +fashion. These blocks may be broken to coincide with mulitpart +boundaries (for "server push"), or just before time-consuming tasks (such as reading another block of an on-disk file). -WSGI servers, gateways, and middleware **must not** delay the +WSGI servers, gateways, and middleware **must not** delay the transmission of any block; they **must** either fully transmit the block to the client, or guarantee that they will continue transmission even while the application is producing its next block. A server/gateway or middleware may provide this guarantee in one of three ways: -1. Send the entire block to the operating system (and request +1. Send the entire block to the operating system (and request that any O/S buffers be flushed) before returning control to the application, OR - + 2. Use a different thread to ensure that the block continues to be transmitted while the application produces the next block. - + 3. (Middleware only) send the entire block to its parent gateway/server @@ -901,7 +901,7 @@ produce any output, it **must** yield an empty string. To put this requirement another way, a middleware component **must -yield at least one value** each time its underlying application +yield at least one value** each time its underlying application yields a value. If the middleware cannot yield any other value, it must yield an empty string. @@ -914,7 +914,7 @@ an iterable. It is also forbidden for middleware to use the ``write()`` callable to transmit data that is yielded by an underlying application. Middleware may only use their parent -server's ``write()`` callable to transmit data that the +server's ``write()`` callable to transmit data that the underlying application sent using a middleware-provided ``write()`` callable. @@ -936,7 +936,7 @@ imperative API, WSGI includes a special ``write()`` callable, returned by the ``start_response`` callable. -New WSGI applications and frameworks **should not** use the +New WSGI applications and frameworks **should not** use the ``write()`` callable if it is possible to avoid doing so. The ``write()`` callable is strictly a hack to support imperative streaming APIs. In general, applications should produce their @@ -956,7 +956,7 @@ An application **must** return an iterable object, even if it uses ``write()`` to produce all or part of its response body. The returned iterable **may** be empty (i.e. yield no non-empty -strings), but if it *does* yield non-empty strings, that output +strings), but if it *does* yield non-empty strings, that output must be treated normally by the server or gateway (i.e., it must be sent or queued immediately). Applications **must not** invoke ``write()`` from within their return iterable, and therefore any @@ -970,7 +970,7 @@ HTTP does not directly support Unicode, and neither does this interface. All encoding/decoding must be handled by the application; all strings passed to or from the server must be standard Python byte -strings, not Unicode objects. The result of using a Unicode object +strings, not Unicode objects. The result of using a Unicode object where a string object is required, is undefined. Note also that strings passed to ``start_response()`` as a status or @@ -980,9 +980,9 @@ On Python platforms where the ``str`` or ``StringType`` type is in fact Unicode-based (e.g. Jython, IronPython, Python 3000, etc.), all -"strings" referred to in this specification must contain only +"strings" referred to in this specification must contain only code points representable in ISO-8859-1 encoding (``\u0000`` through -``\u00FF``, inclusive). It is a fatal error for an application to +``\u00FF``, inclusive). It is a fatal error for an application to supply strings containing any other Unicode character or code point. Similarly, servers and gateways **must not** supply strings to an application containing any other Unicode characters. @@ -1014,7 +1014,7 @@ status = "200 Froody" response_headers = [("content-type","text/plain")] start_response(status, response_headers) - return ["normal body goes here"] + return ["normal body goes here"] except: # XXX should trap runtime issues like MemoryError, KeyboardInterrupt # in a separate handler before this bare 'except:'... @@ -1024,21 +1024,21 @@ return ["error body goes here"] If no output has been written when an exception occurs, the call to -``start_response`` will return normally, and the application will +``start_response`` will return normally, and the application will return an error body to be sent to the browser. However, if any output -has already been sent to the browser, ``start_response`` will reraise -the provided exception. This exception **should not** be trapped by +has already been sent to the browser, ``start_response`` will reraise +the provided exception. This exception **should not** be trapped by the application, and so the application will abort. The server or gateway can then trap this (fatal) exception and abort the response. -Servers **should** trap and log any exception that aborts an -application or the iteration of its return value. If a partial +Servers **should** trap and log any exception that aborts an +application or the iteration of its return value. If a partial response has already been written to the browser when an application error occurs, the server or gateway **may** attempt to add an error message to the output, if the already-sent headers indicate a ``text/*`` content type that the server knows how to modify cleanly. -Some middleware may wish to provide additional exception handling +Some middleware may wish to provide additional exception handling services, or intercept and replace application error messages. In such cases, middleware may choose to **not** re-raise the ``exc_info`` supplied to ``start_response``, but instead raise a middleware-specific @@ -1057,7 +1057,7 @@ HTTP 1.1 Expect/Continue ------------------------ -Servers and gateways that implement HTTP 1.1 **must** provide +Servers and gateways that implement HTTP 1.1 **must** provide transparent support for HTTP 1.1's "expect/continue" mechanism. This may be done in any of several ways: @@ -1069,7 +1069,7 @@ response if/when the application first attempts to read from the input stream. The read request must then remain blocked until the client responds. - + 3. Wait until the client decides that the server does not support expect/continue, and sends the request body on its own. (This is suboptimal, and is not recommended.) @@ -1093,7 +1093,7 @@ with the application being an HTTP "origin server". (See RFC 2616, section 1.3, for the definition of these terms.) -However, because WSGI servers and applications do not communicate via +However, because WSGI servers and applications do not communicate via HTTP, what RFC 2616 calls "hop-by-hop" headers do not apply to WSGI internal communications. WSGI applications **must not** generate any "hop-by-hop" headers [4]_, attempt to use HTTP features that would @@ -1103,7 +1103,7 @@ on their own, such as by decoding any inbound ``Transfer-Encoding``, including chunked encoding if applicable. -Applying these principles to a variety of HTTP features, it should be +Applying these principles to a variety of HTTP features, it should be clear that a server **may** handle cache validation via the ``If-None-Match`` and ``If-Modified-Since`` request headers and the ``Last-Modified`` and ``ETag`` response headers. However, it is @@ -1113,9 +1113,9 @@ Similarly, a server **may** re-encode or transport-encode an application's response, but the application **should** use a -suitable content encoding on its own, and **must not** apply a +suitable content encoding on its own, and **must not** apply a transport encoding. A server **may** transmit byte ranges of the -application's response if requested by the client, and the +application's response if requested by the client, and the application doesn't natively support byte ranges. Again, however, the application **should** perform this function on its own if desired. @@ -1124,7 +1124,7 @@ features can be partially or fully implemented by middleware components, thus freeing both server and application authors from implementing the same features over and over again. - + Thread Support -------------- @@ -1227,14 +1227,14 @@ CGI case they may be able to be set via the server's configuration files. -Applications **should** try to keep such required variables to a -minimum, since not all servers will support easy configuration of -them. Of course, even in the worst case, persons deploying an +Applications **should** try to keep such required variables to a +minimum, since not all servers will support easy configuration of +them. Of course, even in the worst case, persons deploying an application can create a script to supply the necessary configuration values:: from the_app import application - + def new_app(environ,start_response): environ['the_app.configval1'] = 'something' return application(environ,start_response) @@ -1317,7 +1317,7 @@ also implement this protocol.) Finally, middleware that wishes to support pre-2.2 versions of Python, -and iterates over application return values or itself returns an +and iterates over application return values or itself returns an iterable (or both), must follow the appropriate recommendations above. (Note: It should go without saying that to support pre-2.2 versions @@ -1342,7 +1342,7 @@ return iter(lambda: filelike.read(block_size), '') If the server or gateway supplies ``wsgi.file_wrapper``, it must be -a callable that accepts one required positional parameter, and one +a callable that accepts one required positional parameter, and one optional positional parameter. The first parameter is the file-like object to be sent, and the second parameter is an optional block size "suggestion" (which the server/gateway need not use). The @@ -1367,7 +1367,7 @@ gateway checks to see if a wrapper object was returned. (Again, because of the presence of middleware, error handlers, and the like, it is not guaranteed that any wrapper created will actually be used.) - + Apart from the handling of ``close()``, the semantics of returning a file wrapper from the application should be the same as if the application had returned ``iter(filelike.read, '')``. In other words, @@ -1378,7 +1378,7 @@ Of course, platform-specific file transmission APIs don't usually accept arbitrary "file-like" objects. Therefore, a ``wsgi.file_wrapper`` has to introspect the supplied object for -things such as a ``fileno()`` (Unix-like OSes) or a +things such as a ``fileno()`` (Unix-like OSes) or a ``java.nio.FileChannel`` (under Jython) in order to determine if the file-like object is suitable for use with the platform-specific API it supports. @@ -1396,7 +1396,7 @@ self.blksize = blksize if hasattr(filelike,'close'): self.close = filelike.close - + def __getitem__(self,key): data = self.filelike.read(self.blksize) if data: @@ -1408,7 +1408,7 @@ environ['wsgi.file_wrapper'] = FileWrapper result = application(environ, start_response) - + try: if isinstance(result,FileWrapper): # check if result.filelike is usable w/platform-specific @@ -1418,10 +1418,10 @@ for data in result: # etc. - + finally: if hasattr(result,'close'): - result.close() + result.close() Questions and Answers @@ -1578,15 +1578,15 @@ * Should ``wsgi.input`` be an iterator instead of a file? This would help for asynchronous applications and chunked-encoding input streams. - + * Optional extensions are being discussed for pausing iteration of an application's ouptut until input is available or until a callback occurs. - + * Add a section about synchronous vs. asynchronous apps and servers, the relevant threading models, and issues/design goals in these areas. - + Acknowledgements ================ @@ -1608,7 +1608,7 @@ function. His input also guided the design of the exception handling facilities, especially in the area of allowing for middleware that overrides application error messages. - + * Alan Kennedy, whose courageous attempts to implement WSGI-on-Jython (well before the spec was finalized) helped to shape the "supporting older versions of Python" section, as well as the optional @@ -1617,7 +1617,7 @@ * Mark Nottingham, who reviewed the spec extensively for issues with HTTP RFC compliance, especially with regard to HTTP/1.1 features that I didn't even know existed until he pointed them out. - + References ========== @@ -1631,7 +1631,7 @@ .. [3] "Chunked Transfer Coding" -- HTTP/1.1, section 3.6.1 (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1) -.. [4] "End-to-end and Hop-by-hop Headers" -- HTTP/1.1, Section 13.5.1 +.. [4] "End-to-end and Hop-by-hop Headers" -- HTTP/1.1, Section 13.5.1 (http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1) .. [5] mod_ssl Reference, "Environment Variables" Modified: peps/trunk/pep-0376.txt ============================================================================== --- peps/trunk/pep-0376.txt (original) +++ peps/trunk/pep-0376.txt Mon Apr 13 22:52:58 2009 @@ -172,28 +172,28 @@ New functions in pkgutil ======================== -To use the `.egg-info` directory content, we need to add in the standard library a set of -APIs. The best place to put these APIs seems to be `pkgutil`. +To use the `.egg-info` directory content, we need to add in the standard +library a set of APIs. The best place to put these APIs seems to be `pkgutil`. + The new functions added in the package are : -- get_egg_info(pkg_name) -> path or None +- get_egg_info(project_name) -> path or None - Scans all site-packages directories and looks for all `pkg_name.egg-info` + Scans all site-packages directories and looks for all `project_name.egg-info` directories. Returns the directory path that contains a PKG-INFO that matches - `pkg_name` for the `name` metadata. Notice that there should be at most - one result. If more than one path matches the pkg_name, a DistutilsError - is raised. + `project_name` for the `name` metadata. Notice that there should be at most + one result. The first result founded will be returned. If the directory is not found, returns None. -- get_metadata(pkg_name) -> DistributionMetadata or None +- get_metadata(project_name) -> DistributionMetadata or None Uses `get_egg_info` to get the `PKG-INFO` file, and returns a `DistributionMetadata` instance that contains the metadata. This will require a small change in `DistributionMetadata` (see #4908). -- get_egg_info_file(pkg_name, filename) -> file object or None +- get_egg_info_file(project_name, filename) -> file object or None Uses `get_egg_info` and gets any file inside the directory, pointed by filename. From python-checkins at python.org Mon Apr 13 22:58:21 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 13 Apr 2009 22:58:21 +0200 (CEST) Subject: [Python-checkins] r71593 - peps/trunk/pep-0333.txt Message-ID: <20090413205821.41FBE1E4029@bag.python.org> Author: tarek.ziade Date: Mon Apr 13 22:58:19 2009 New Revision: 71593 Log: reverted unintentional commit on pep 333 Modified: peps/trunk/pep-0333.txt Modified: peps/trunk/pep-0333.txt ============================================================================== --- peps/trunk/pep-0333.txt (original) +++ peps/trunk/pep-0333.txt Mon Apr 13 22:58:19 2009 @@ -179,7 +179,7 @@ returns an instance of 'AppClass', which is then the iterable return value of the "application callable" as required by the spec. - + If we wanted to use *instances* of 'AppClass' as application objects instead, we would have to implement a '__call__' method, which would be invoked to execute the application, @@ -204,9 +204,9 @@ The server or gateway invokes the application callable once for each request it receives from an HTTP client, that is directed at the application. To illustrate, here is a simple CGI gateway, implemented -as a function taking an application object. Note that this simple -example has limited error handling, because by default an uncaught -exception will be dumped to ``sys.stderr`` and logged by the web +as a function taking an application object. Note that this simple +example has limited error handling, because by default an uncaught +exception will be dumped to ``sys.stderr`` and logged by the web server. :: @@ -256,7 +256,7 @@ exc_info = None # avoid dangling circular ref elif headers_set: raise AssertionError("Headers already set!") - + headers_set[:] = [status,response_headers] return write @@ -294,13 +294,13 @@ The presence of middleware in general is transparent to both the "server/gateway" and the "application/framework" sides of the interface, and should require no special support. A user who -desires to incorporate middleware into an application simply -provides the middleware component to the server, as if it were +desires to incorporate middleware into an application simply +provides the middleware component to the server, as if it were an application, and configures the middleware component to invoke the application, as if the middleware component were a server. Of course, the "application" that the middleware wraps may in fact be another middleware component wrapping another -application, and so on, creating what is referred to as a +application, and so on, creating what is referred to as a "middleware stack". For the most part, middleware must conform to the restrictions @@ -311,7 +311,7 @@ Here is a (tongue-in-cheek) example of a middleware component that converts ``text/plain`` responses to pig latin, using Joe Strout's -``piglatin.py``. (Note: a "real" middleware component would +``piglatin.py``. (Note: a "real" middleware component would probably use a more robust way of checking the content type, and should also check for a content encoding. Also, this simple example ignores the possibility that a word might be split across @@ -320,11 +320,11 @@ :: from piglatin import piglatin - + class LatinIter: """Transform iterated output to piglatin, if it's okay to do so - + Note that the "okayness" can change until the application yields its first non-empty string, so 'transform_ok' has to be a mutable truth value.""" @@ -347,30 +347,30 @@ class Latinator: # by default, don't transform output - transform = False + transform = False def __init__(self, application): self.application = application def __call__(self, environ, start_response): - + transform_ok = [] - + def start_latin(status,response_headers,exc_info=None): # Reset ok flag, in case this is a repeat call - transform_ok[:]=[] + transform_ok[:]=[] for name,value in response_headers: if name.lower()=='content-type' and value=='text/plain': transform_ok.append(True) # Strip content-length if present, else it'll be wrong - response_headers = [(name,value) - for name,value in response_headers + response_headers = [(name,value) + for name,value in response_headers if name.lower()<>'content-length' ] break - + write = start_response(status,response_headers,exc_info) if transform_ok: @@ -417,7 +417,7 @@ ``start_response(status,response_headers)``). The ``status`` parameter is a status string of the form -``"999 Message here"``, and ``response_headers`` is a list of +``"999 Message here"``, and ``response_headers`` is a list of ``(header_name,header_value)`` tuples describing the HTTP response header. The optional ``exc_info`` parameter is described below in the sections on `The start_response() Callable`_ and `Error Handling`_. @@ -425,14 +425,14 @@ attempting to display an error message to the browser. The ``start_response`` callable must return a ``write(body_data)`` -callable that takes one positional parameter: a string to be written +callable that takes one positional parameter: a string to be written as part of the HTTP response body. (Note: the ``write()`` callable is provided only to support certain existing frameworks' imperative output APIs; it should not be used by new applications or frameworks if it can be avoided. See the `Buffering and Streaming`_ section for more details.) -When called by the server, the application object must return an +When called by the server, the application object must return an iterable yielding zero or more strings. This can be accomplished in a variety of ways, such as by returning a list of strings, or by the application being a generator function that yields strings, or @@ -440,10 +440,10 @@ Regardless of how it is accomplished, the application object must always return an iterable yielding zero or more strings. -The server or gateway must transmit the yielded strings to the client -in an unbuffered fashion, completing the transmission of each string +The server or gateway must transmit the yielded strings to the client +in an unbuffered fashion, completing the transmission of each string before requesting another one. (In other words, applications -**should** perform their own buffering. See the `Buffering and +**should** perform their own buffering. See the `Buffering and Streaming`_ section below for more on how application output must be handled.) @@ -456,21 +456,21 @@ such as byte-range transmission. See `Other HTTP Features`_, below, for more details.) -If a call to ``len(iterable)`` succeeds, the server must be able -to rely on the result being accurate. That is, if the iterable -returned by the application provides a working ``__len__()`` +If a call to ``len(iterable)`` succeeds, the server must be able +to rely on the result being accurate. That is, if the iterable +returned by the application provides a working ``__len__()`` method, it **must** return an accurate result. (See the `Handling the Content-Length Header`_ section for information on how this would normally be used.) If the iterable returned by the application has a ``close()`` method, the server or gateway **must** call that method upon completion of the -current request, whether the request was completed normally, or +current request, whether the request was completed normally, or terminated early due to an error. (This is to support resource release by the application. This protocol is intended to complement PEP 325's generator support, and other common iterables with ``close()`` methods. -(Note: the application **must** invoke the ``start_response()`` +(Note: the application **must** invoke the ``start_response()`` callable before the iterable yields its first body string, so that the server can send the headers before any body content. However, this invocation **may** be performed by the iterable's first iteration, so @@ -480,8 +480,8 @@ Finally, servers and gateways **must not** directly use any other attributes of the iterable returned by the application, unless it is an instance of a type specific to that server or gateway, such as a "file -wrapper" returned by ``wsgi.file_wrapper`` (see `Optional -Platform-Specific File Handling`_). In the general case, only +wrapper" returned by ``wsgi.file_wrapper`` (see `Optional +Platform-Specific File Handling`_). In the general case, only attributes specified here, or accessed via e.g. the PEP 234 iteration APIs are acceptable. @@ -496,19 +496,19 @@ **may** be omitted, except as otherwise noted below. ``REQUEST_METHOD`` - The HTTP request method, such as ``"GET"`` or ``"POST"``. This + The HTTP request method, such as ``"GET"`` or ``"POST"``. This cannot ever be an empty string, and so is always required. -``SCRIPT_NAME`` +``SCRIPT_NAME`` The initial portion of the request URL's "path" that corresponds to - the application object, so that the application knows its virtual + the application object, so that the application knows its virtual "location". This **may** be an empty string, if the application - corresponds to the "root" of the server. + corresponds to the "root" of the server. ``PATH_INFO`` - The remainder of the request URL's "path", designating the virtual + The remainder of the request URL's "path", designating the virtual "location" of the request's target within the application. This - **may** be an empty string, if the request URL targets the + **may** be an empty string, if the request URL targets the application root and does not have a trailing slash. ``QUERY_STRING`` @@ -547,7 +547,7 @@ absence of these variables should correspond with the presence or absence of the appropriate HTTP header in the request. -A server or gateway **should** attempt to provide as many other CGI +A server or gateway **should** attempt to provide as many other CGI variables as are applicable. In addition, if SSL is in use, the server or gateway **should** also provide as many of the Apache SSL environment variables [5]_ as are applicable, such as ``HTTPS=on`` and @@ -559,7 +559,7 @@ A WSGI-compliant server or gateway **should** document what variables it provides, along with their definitions as appropriate. Applications -**should** check for the presence of any variables they require, and +**should** check for the presence of any variables they require, and have a fallback plan in the event such a variable is absent. Note: missing variables (such as ``REMOTE_USER`` when no @@ -579,20 +579,20 @@ version 1.0. ``wsgi.url_scheme`` A string representing the "scheme" portion of - the URL at which the application is being + the URL at which the application is being invoked. Normally, this will have the value ``"http"`` or ``"https"``, as appropriate. ``wsgi.input`` An input stream (file-like object) from which the HTTP request body can be read. (The server - or gateway may perform reads on-demand as + or gateway may perform reads on-demand as requested by the application, or it may pre- read the client's request body and buffer it in-memory or on disk, or use any other technique for providing such an input stream, according to its preference.) -``wsgi.errors`` An output stream (file-like object) to which +``wsgi.errors`` An output stream (file-like object) to which error output can be written, for the purpose of recording program or other errors in a standardized and possibly centralized location. @@ -610,13 +610,13 @@ or gateway may supply different error streams to different applications, if this is desired. -``wsgi.multithread`` This value should evaluate true if the +``wsgi.multithread`` This value should evaluate true if the application object may be simultaneously invoked by another thread in the same process, and should evaluate false otherwise. -``wsgi.multiprocess`` This value should evaluate true if an - equivalent application object may be +``wsgi.multiprocess`` This value should evaluate true if an + equivalent application object may be simultaneously invoked by another process, and should evaluate false otherwise. @@ -696,12 +696,12 @@ (As with all WSGI callables, the arguments must be supplied positionally, not by keyword.) The ``start_response`` callable is used to begin the HTTP response, and it must return a -``write(body_data)`` callable (see the `Buffering and Streaming`_ +``write(body_data)`` callable (see the `Buffering and Streaming`_ section, below). The ``status`` argument is an HTTP "status" string like ``"200 OK"`` -or ``"404 Not Found"``. That is, it is a string consisting of a -Status-Code and a Reason-Phrase, in that order and separated by a +or ``"404 Not Found"``. That is, it is a string consisting of a +Status-Code and a Reason-Phrase, in that order and separated by a single space, with no surrounding whitespace or other characters. (See RFC 2616, Section 6.1.1 for more information.) The string **must not** contain control characters, and must not be terminated @@ -733,11 +733,11 @@ Applications and middleware are forbidden from using HTTP/1.1 "hop-by-hop" features or headers, any equivalent features in HTTP/1.0, -or any headers that would affect the persistence of the client's +or any headers that would affect the persistence of the client's connection to the web server. These features are the exclusive province of the actual web server, and a server or gateway **should** consider it a fatal error for an application to attempt -sending them, and raise an error if they are supplied to +sending them, and raise an error if they are supplied to ``start_response()``. (For more specifics on "hop-by-hop" features and headers, please see the `Other HTTP Features`_ section below.) @@ -748,7 +748,7 @@ the application's first invocation of the ``write()`` callable. In other words, response headers must not be sent until there is actual body data available, or until the application's returned iterable is -exhausted. (The only possible exception to this rule is if the +exhausted. (The only possible exception to this rule is if the response headers explicitly include a ``Content-Length`` of zero.) This delaying of response header transmission is to ensure that buffered @@ -772,12 +772,12 @@ raise the ``exc_info`` tuple. That is:: raise exc_info[0],exc_info[1],exc_info[2] - + This will re-raise the exception trapped by the application, and in -principle should abort the application. (It is not safe for the +principle should abort the application. (It is not safe for the application to attempt error output to the browser once the HTTP headers have already been sent.) The application **must not** trap -any exceptions raised by ``start_response``, if it called +any exceptions raised by ``start_response``, if it called ``start_response`` with ``exc_info``. Instead, it should allow such exceptions to propagate back to the server or gateway. See `Error Handling`_ below, for more details. @@ -790,7 +790,7 @@ gateway above for an illustration of the correct logic.) Note: servers, gateways, or middleware implementing ``start_response`` -**should** ensure that no reference is held to the ``exc_info`` +**should** ensure that no reference is held to the ``exc_info`` parameter beyond the duration of the function's execution, to avoid creating a circular reference through the traceback and frames involved. The simplest way to do this is something like:: @@ -833,7 +833,7 @@ (Note: applications and middleware **must not** apply any kind of ``Transfer-Encoding`` to their output, such as chunking or gzipping; -as "hop-by-hop" operations, these encodings are the province of the +as "hop-by-hop" operations, these encodings are the province of the actual web server/gateway. See `Other HTTP Features`_ below, for more details.) @@ -842,7 +842,7 @@ ----------------------- Generally speaking, applications will achieve the best throughput -by buffering their (modestly-sized) output and sending it all at +by buffering their (modestly-sized) output and sending it all at once. This is a common approach in existing frameworks such as Zope: the output is buffered in a StringIO or similar object, then transmitted all at once, along with the response headers. @@ -850,37 +850,37 @@ The corresponding approach in WSGI is for the application to simply return a single-element iterable (such as a list) containing the response body as a single string. This is the recommended approach -for the vast majority of application functions, that render +for the vast majority of application functions, that render HTML pages whose text easily fits in memory. For large files, however, or for specialized uses of HTTP streaming (such as multipart "server push"), an application may need to provide -output in smaller blocks (e.g. to avoid loading a large file into +output in smaller blocks (e.g. to avoid loading a large file into memory). It's also sometimes the case that part of a response may be time-consuming to produce, but it would be useful to send ahead the portion of the response that precedes it. In these cases, applications will usually return an iterator (often a generator-iterator) that produces the output in a block-by-block -fashion. These blocks may be broken to coincide with mulitpart -boundaries (for "server push"), or just before time-consuming +fashion. These blocks may be broken to coincide with mulitpart +boundaries (for "server push"), or just before time-consuming tasks (such as reading another block of an on-disk file). -WSGI servers, gateways, and middleware **must not** delay the +WSGI servers, gateways, and middleware **must not** delay the transmission of any block; they **must** either fully transmit the block to the client, or guarantee that they will continue transmission even while the application is producing its next block. A server/gateway or middleware may provide this guarantee in one of three ways: -1. Send the entire block to the operating system (and request +1. Send the entire block to the operating system (and request that any O/S buffers be flushed) before returning control to the application, OR - + 2. Use a different thread to ensure that the block continues to be transmitted while the application produces the next block. - + 3. (Middleware only) send the entire block to its parent gateway/server @@ -901,7 +901,7 @@ produce any output, it **must** yield an empty string. To put this requirement another way, a middleware component **must -yield at least one value** each time its underlying application +yield at least one value** each time its underlying application yields a value. If the middleware cannot yield any other value, it must yield an empty string. @@ -914,7 +914,7 @@ an iterable. It is also forbidden for middleware to use the ``write()`` callable to transmit data that is yielded by an underlying application. Middleware may only use their parent -server's ``write()`` callable to transmit data that the +server's ``write()`` callable to transmit data that the underlying application sent using a middleware-provided ``write()`` callable. @@ -936,7 +936,7 @@ imperative API, WSGI includes a special ``write()`` callable, returned by the ``start_response`` callable. -New WSGI applications and frameworks **should not** use the +New WSGI applications and frameworks **should not** use the ``write()`` callable if it is possible to avoid doing so. The ``write()`` callable is strictly a hack to support imperative streaming APIs. In general, applications should produce their @@ -956,7 +956,7 @@ An application **must** return an iterable object, even if it uses ``write()`` to produce all or part of its response body. The returned iterable **may** be empty (i.e. yield no non-empty -strings), but if it *does* yield non-empty strings, that output +strings), but if it *does* yield non-empty strings, that output must be treated normally by the server or gateway (i.e., it must be sent or queued immediately). Applications **must not** invoke ``write()`` from within their return iterable, and therefore any @@ -970,7 +970,7 @@ HTTP does not directly support Unicode, and neither does this interface. All encoding/decoding must be handled by the application; all strings passed to or from the server must be standard Python byte -strings, not Unicode objects. The result of using a Unicode object +strings, not Unicode objects. The result of using a Unicode object where a string object is required, is undefined. Note also that strings passed to ``start_response()`` as a status or @@ -980,9 +980,9 @@ On Python platforms where the ``str`` or ``StringType`` type is in fact Unicode-based (e.g. Jython, IronPython, Python 3000, etc.), all -"strings" referred to in this specification must contain only +"strings" referred to in this specification must contain only code points representable in ISO-8859-1 encoding (``\u0000`` through -``\u00FF``, inclusive). It is a fatal error for an application to +``\u00FF``, inclusive). It is a fatal error for an application to supply strings containing any other Unicode character or code point. Similarly, servers and gateways **must not** supply strings to an application containing any other Unicode characters. @@ -1014,7 +1014,7 @@ status = "200 Froody" response_headers = [("content-type","text/plain")] start_response(status, response_headers) - return ["normal body goes here"] + return ["normal body goes here"] except: # XXX should trap runtime issues like MemoryError, KeyboardInterrupt # in a separate handler before this bare 'except:'... @@ -1024,21 +1024,21 @@ return ["error body goes here"] If no output has been written when an exception occurs, the call to -``start_response`` will return normally, and the application will +``start_response`` will return normally, and the application will return an error body to be sent to the browser. However, if any output -has already been sent to the browser, ``start_response`` will reraise -the provided exception. This exception **should not** be trapped by +has already been sent to the browser, ``start_response`` will reraise +the provided exception. This exception **should not** be trapped by the application, and so the application will abort. The server or gateway can then trap this (fatal) exception and abort the response. -Servers **should** trap and log any exception that aborts an -application or the iteration of its return value. If a partial +Servers **should** trap and log any exception that aborts an +application or the iteration of its return value. If a partial response has already been written to the browser when an application error occurs, the server or gateway **may** attempt to add an error message to the output, if the already-sent headers indicate a ``text/*`` content type that the server knows how to modify cleanly. -Some middleware may wish to provide additional exception handling +Some middleware may wish to provide additional exception handling services, or intercept and replace application error messages. In such cases, middleware may choose to **not** re-raise the ``exc_info`` supplied to ``start_response``, but instead raise a middleware-specific @@ -1057,7 +1057,7 @@ HTTP 1.1 Expect/Continue ------------------------ -Servers and gateways that implement HTTP 1.1 **must** provide +Servers and gateways that implement HTTP 1.1 **must** provide transparent support for HTTP 1.1's "expect/continue" mechanism. This may be done in any of several ways: @@ -1069,7 +1069,7 @@ response if/when the application first attempts to read from the input stream. The read request must then remain blocked until the client responds. - + 3. Wait until the client decides that the server does not support expect/continue, and sends the request body on its own. (This is suboptimal, and is not recommended.) @@ -1093,7 +1093,7 @@ with the application being an HTTP "origin server". (See RFC 2616, section 1.3, for the definition of these terms.) -However, because WSGI servers and applications do not communicate via +However, because WSGI servers and applications do not communicate via HTTP, what RFC 2616 calls "hop-by-hop" headers do not apply to WSGI internal communications. WSGI applications **must not** generate any "hop-by-hop" headers [4]_, attempt to use HTTP features that would @@ -1103,7 +1103,7 @@ on their own, such as by decoding any inbound ``Transfer-Encoding``, including chunked encoding if applicable. -Applying these principles to a variety of HTTP features, it should be +Applying these principles to a variety of HTTP features, it should be clear that a server **may** handle cache validation via the ``If-None-Match`` and ``If-Modified-Since`` request headers and the ``Last-Modified`` and ``ETag`` response headers. However, it is @@ -1113,9 +1113,9 @@ Similarly, a server **may** re-encode or transport-encode an application's response, but the application **should** use a -suitable content encoding on its own, and **must not** apply a +suitable content encoding on its own, and **must not** apply a transport encoding. A server **may** transmit byte ranges of the -application's response if requested by the client, and the +application's response if requested by the client, and the application doesn't natively support byte ranges. Again, however, the application **should** perform this function on its own if desired. @@ -1124,7 +1124,7 @@ features can be partially or fully implemented by middleware components, thus freeing both server and application authors from implementing the same features over and over again. - + Thread Support -------------- @@ -1227,14 +1227,14 @@ CGI case they may be able to be set via the server's configuration files. -Applications **should** try to keep such required variables to a -minimum, since not all servers will support easy configuration of -them. Of course, even in the worst case, persons deploying an +Applications **should** try to keep such required variables to a +minimum, since not all servers will support easy configuration of +them. Of course, even in the worst case, persons deploying an application can create a script to supply the necessary configuration values:: from the_app import application - + def new_app(environ,start_response): environ['the_app.configval1'] = 'something' return application(environ,start_response) @@ -1317,7 +1317,7 @@ also implement this protocol.) Finally, middleware that wishes to support pre-2.2 versions of Python, -and iterates over application return values or itself returns an +and iterates over application return values or itself returns an iterable (or both), must follow the appropriate recommendations above. (Note: It should go without saying that to support pre-2.2 versions @@ -1342,7 +1342,7 @@ return iter(lambda: filelike.read(block_size), '') If the server or gateway supplies ``wsgi.file_wrapper``, it must be -a callable that accepts one required positional parameter, and one +a callable that accepts one required positional parameter, and one optional positional parameter. The first parameter is the file-like object to be sent, and the second parameter is an optional block size "suggestion" (which the server/gateway need not use). The @@ -1367,7 +1367,7 @@ gateway checks to see if a wrapper object was returned. (Again, because of the presence of middleware, error handlers, and the like, it is not guaranteed that any wrapper created will actually be used.) - + Apart from the handling of ``close()``, the semantics of returning a file wrapper from the application should be the same as if the application had returned ``iter(filelike.read, '')``. In other words, @@ -1378,7 +1378,7 @@ Of course, platform-specific file transmission APIs don't usually accept arbitrary "file-like" objects. Therefore, a ``wsgi.file_wrapper`` has to introspect the supplied object for -things such as a ``fileno()`` (Unix-like OSes) or a +things such as a ``fileno()`` (Unix-like OSes) or a ``java.nio.FileChannel`` (under Jython) in order to determine if the file-like object is suitable for use with the platform-specific API it supports. @@ -1396,7 +1396,7 @@ self.blksize = blksize if hasattr(filelike,'close'): self.close = filelike.close - + def __getitem__(self,key): data = self.filelike.read(self.blksize) if data: @@ -1408,7 +1408,7 @@ environ['wsgi.file_wrapper'] = FileWrapper result = application(environ, start_response) - + try: if isinstance(result,FileWrapper): # check if result.filelike is usable w/platform-specific @@ -1418,10 +1418,10 @@ for data in result: # etc. - + finally: if hasattr(result,'close'): - result.close() + result.close() Questions and Answers @@ -1578,15 +1578,15 @@ * Should ``wsgi.input`` be an iterator instead of a file? This would help for asynchronous applications and chunked-encoding input streams. - + * Optional extensions are being discussed for pausing iteration of an application's ouptut until input is available or until a callback occurs. - + * Add a section about synchronous vs. asynchronous apps and servers, the relevant threading models, and issues/design goals in these areas. - + Acknowledgements ================ @@ -1608,7 +1608,7 @@ function. His input also guided the design of the exception handling facilities, especially in the area of allowing for middleware that overrides application error messages. - + * Alan Kennedy, whose courageous attempts to implement WSGI-on-Jython (well before the spec was finalized) helped to shape the "supporting older versions of Python" section, as well as the optional @@ -1617,7 +1617,7 @@ * Mark Nottingham, who reviewed the spec extensively for issues with HTTP RFC compliance, especially with regard to HTTP/1.1 features that I didn't even know existed until he pointed them out. - + References ========== @@ -1631,7 +1631,7 @@ .. [3] "Chunked Transfer Coding" -- HTTP/1.1, section 3.6.1 (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1) -.. [4] "End-to-end and Hop-by-hop Headers" -- HTTP/1.1, Section 13.5.1 +.. [4] "End-to-end and Hop-by-hop Headers" -- HTTP/1.1, Section 13.5.1 (http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1) .. [5] mod_ssl Reference, "Environment Variables" From python-checkins at python.org Mon Apr 13 23:14:20 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 13 Apr 2009 23:14:20 +0200 (CEST) Subject: [Python-checkins] r71594 - peps/trunk/pep-0376.txt Message-ID: <20090413211420.1204A1E4029@bag.python.org> Author: tarek.ziade Date: Mon Apr 13 23:14:19 2009 New Revision: 71594 Log: more details in the abstract Modified: peps/trunk/pep-0376.txt Modified: peps/trunk/pep-0376.txt ============================================================================== --- peps/trunk/pep-0376.txt (original) +++ peps/trunk/pep-0376.txt Mon Apr 13 23:14:19 2009 @@ -17,6 +17,7 @@ This PEP proposes various enhancements for Distutils: - A new format for the .egg-info structure. +- Some APIs to read the meta-data of a project - An install script to install a package in Python. - An uninstall script to uninstall a package in Python. From buildbot at python.org Mon Apr 13 23:23:47 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 13 Apr 2009 21:23:47 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 2.6 Message-ID: <20090413212347.E54C41E4033@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%202.6/builds/244 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From buildbot at python.org Tue Apr 14 00:07:21 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 13 Apr 2009 22:07:21 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.0 Message-ID: <20090413220722.817E81E4029@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.0/builds/269 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From buildbot at python.org Tue Apr 14 00:12:20 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 13 Apr 2009 22:12:20 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 3.0 Message-ID: <20090413221220.657481E4022@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%203.0/builds/219 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From buildbot at python.org Tue Apr 14 00:22:38 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 13 Apr 2009 22:22:38 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090413222238.97DDF1E4029@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/581 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Tue Apr 14 00:50:43 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 14 Apr 2009 00:50:43 +0200 (CEST) Subject: [Python-checkins] r71595 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090413225043.9525A1E4019@bag.python.org> Author: mark.dickinson Date: Tue Apr 14 00:50:43 2009 New Revision: 71595 Log: Fix some compiler warnings on Windows Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Tue Apr 14 00:50:43 2009 @@ -404,7 +404,7 @@ Bfree(b); b = b1; } - b->x[wds++] = carry; + b->x[wds++] = (ULong)carry; b->wds = wds; } return b; @@ -593,7 +593,7 @@ *xc++ = z & FFFFFFFF; } while(x < xae); - *xc = carry; + *xc = (ULong)carry; } } #else @@ -1872,7 +1872,7 @@ else { if (bc.scale && y <= 2*P*Exp_msk1) { if (aadj <= 0x7fffffff) { - if ((z = aadj) <= 0) + if ((z = (ULong)aadj) <= 0) z = 1; aadj = z; aadj1 = bc.dsign ? aadj : -aadj; @@ -1944,7 +1944,7 @@ j = sizeof(ULong); for(k = 0; - sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i; + sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= (unsigned)i; j <<= 1) k++; r = (int*)Balloc(k); @@ -2274,7 +2274,7 @@ */ dval(&eps) = 0.5/tens[ilim-1] - dval(&eps); for(i = 0;;) { - L = dval(&u); + L = (Long)dval(&u); dval(&u) -= L; *s++ = '0' + (int)L; if (dval(&u) < dval(&eps)) From python-checkins at python.org Tue Apr 14 10:00:42 2009 From: python-checkins at python.org (matthias.klose) Date: Tue, 14 Apr 2009 10:00:42 +0200 (CEST) Subject: [Python-checkins] r71596 - python/branches/release30-maint/Doc/tools/sphinxext/pyspecific.py Message-ID: <20090414080042.0AC741E4018@bag.python.org> Author: matthias.klose Date: Tue Apr 14 10:00:41 2009 New Revision: 71596 Log: Backport from the 2.6 branch: r71499 | georg.brandl | 2009-04-11 22:34:17 +0200 (Sa, 11. Apr 2009) | 1 line Add a monkeypatching hack so that the docs can still be built with Sphinx 0.5. Modified: python/branches/release30-maint/Doc/tools/sphinxext/pyspecific.py Modified: python/branches/release30-maint/Doc/tools/sphinxext/pyspecific.py ============================================================================== --- python/branches/release30-maint/Doc/tools/sphinxext/pyspecific.py (original) +++ python/branches/release30-maint/Doc/tools/sphinxext/pyspecific.py Tue Apr 14 10:00:41 2009 @@ -5,7 +5,7 @@ Sphinx extension with Python doc-specific markup. - :copyright: 2008 by Georg Brandl. + :copyright: 2008, 2009 by Georg Brandl. :license: Python license. """ @@ -57,7 +57,11 @@ try: from sphinx.builders import Builder except ImportError: + # using Sphinx < 0.6, which has a different package layout from sphinx.builder import Builder + # monkey-patch toctree directive to accept (and ignore) the :numbered: flag + from sphinx.directives.other import toctree_directive + toctree_directive.options['numbered'] = toctree_directive.options['glob'] try: from sphinx.writers.text import TextWriter From python-checkins at python.org Tue Apr 14 10:02:08 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 14 Apr 2009 10:02:08 +0200 (CEST) Subject: [Python-checkins] r71597 - in python/branches/py3k-short-float-repr: Makefile.pre.in Python/marshal.c Message-ID: <20090414080208.E9E261E4018@bag.python.org> Author: mark.dickinson Date: Tue Apr 14 10:02:08 2009 New Revision: 71597 Log: Add dtoa.h to Makefile.pre.in; fix indentation issue in marshal.c Modified: python/branches/py3k-short-float-repr/Makefile.pre.in python/branches/py3k-short-float-repr/Python/marshal.c Modified: python/branches/py3k-short-float-repr/Makefile.pre.in ============================================================================== --- python/branches/py3k-short-float-repr/Makefile.pre.in (original) +++ python/branches/py3k-short-float-repr/Makefile.pre.in Tue Apr 14 10:02:08 2009 @@ -622,6 +622,7 @@ Include/complexobject.h \ Include/descrobject.h \ Include/dictobject.h \ + Include/dtoa.h \ Include/enumobject.h \ Include/errcode.h \ Include/eval.h \ Modified: python/branches/py3k-short-float-repr/Python/marshal.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/marshal.c (original) +++ python/branches/py3k-short-float-repr/Python/marshal.c Tue Apr 14 10:02:08 2009 @@ -707,7 +707,7 @@ buf[n] = '\0'; retval = NULL; PyFPE_START_PROTECT("atof", break;) - c.real = PyOS_ascii_atof(buf); + c.real = PyOS_ascii_atof(buf); PyFPE_END_PROTECT(c) n = r_byte(p); if (n == EOF || r_string(buf, (int)n, p) != n) { @@ -718,7 +718,7 @@ } buf[n] = '\0'; PyFPE_START_PROTECT("atof", break) - c.imag = PyOS_ascii_atof(buf); + c.imag = PyOS_ascii_atof(buf); PyFPE_END_PROTECT(c) retval = PyComplex_FromCComplex(c); break; From python-checkins at python.org Tue Apr 14 10:05:31 2009 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 14 Apr 2009 10:05:31 +0200 (CEST) Subject: [Python-checkins] r71598 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090414080531.C24C21E42E3@bag.python.org> Author: raymond.hettinger Date: Tue Apr 14 10:05:31 2009 New Revision: 71598 Log: New module names are lowercase Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Tue Apr 14 10:05:31 2009 @@ -67,7 +67,7 @@ reinserting it will move it to the end. The standard library now supports use of ordered dictionaries in several -modules. The :mod:`ConfigParser` module uses them by default. This lets +modules. The :mod:`configparser` module uses them by default. This lets configuration files be read, modified, and then written back in their original order. The :mod:`collections` module's :meth:`namedtuple._asdict` method now returns an ordered dictionary with the values appearing in the same order as From nnorwitz at gmail.com Tue Apr 14 10:11:21 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 14 Apr 2009 04:11:21 -0400 Subject: [Python-checkins] Python Regression Test Failures basics (1) Message-ID: <20090414081121.GA30656@python.psfb.org> 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23366 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 test_lib2to3 failed -- errors occurred; run in verbose mode for details 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 -- OSError raises on RLock creation, see issue 3111! test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18902 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [742041 refs] From python-checkins at python.org Tue Apr 14 10:16:51 2009 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 14 Apr 2009 10:16:51 +0200 (CEST) Subject: [Python-checkins] r71599 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090414081651.281581E401E@bag.python.org> Author: raymond.hettinger Date: Tue Apr 14 10:16:50 2009 New Revision: 71599 Log: Fix-up links. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Tue Apr 14 10:16:50 2009 @@ -57,8 +57,8 @@ Regular Python dictionaries iterate over key/value pairs in arbitrary order. Over the years, a number of authors have written alternative implementations that remember the order that the keys were originally inserted. Based on -the experiences from those implementations, the :mod:`collections` module -now has an :class:`OrderedDict` class. +the experiences from those implementations, a new +:class:`collections.OrderedDict` class has been introduced. The OrderedDict API is substantially the same as regular dictionaries but will iterate over keys and values in a guaranteed order depending on @@ -69,7 +69,7 @@ The standard library now supports use of ordered dictionaries in several modules. The :mod:`configparser` module uses them by default. This lets configuration files be read, modified, and then written back in their original -order. The :mod:`collections` module's :meth:`namedtuple._asdict` method now +order. The *_asdict()* method for :func:`collections.namedtuple` now returns an ordered dictionary with the values appearing in the same order as the underlying tuple indicies. The :mod:`json` module is being built-out with an *object_pairs_hook* to allow OrderedDicts to be built by the decoder. @@ -233,15 +233,15 @@ (Contributed by Gregory Smith.) -* The :mod:`logging` module now implements a simple :class:`NullHandler` +* The :mod:`logging` module now implements a simple :class:`logging.NullHandler` class for applications that are not using logging but are calling library code that does. Setting-up a null handler will suppress - spurious warnings like "No handlers could be found for logger X.Y.Z":: + spurious warnings such as "No handlers could be found for logger foo":: >>> h = logging.NullHandler() >>> logging.getLogger("foo").addHandler(h) - (Contributed by Vinay Sajip; issue:`4384`). + (Contributed by Vinay Sajip; :issue:`4384`). * The :mod:`runpy` module which supports the ``-m`` command line switch now supports the execution of packages by looking for and executing From nnorwitz at gmail.com Tue Apr 14 10:19:12 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 14 Apr 2009 04:19:12 -0400 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20090414081912.GA630@python.psfb.org> 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils [17363 refs] [17363 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23366 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 test_lib2to3 failed -- errors occurred; run in verbose mode for details 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 -- OSError raises on RLock creation, see issue 3111! test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18065 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [741281 refs] From nnorwitz at gmail.com Tue Apr 14 11:21:46 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 14 Apr 2009 05:21:46 -0400 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20090414092146.GA19514@python.psfb.org> More important issues: ---------------------- test_pydoc leaked [0, 0, -21] references, sum=-21 Less important issues: ---------------------- test_asynchat leaked [128, -128, 0] references, sum=0 test_httpservers leaked [-4, 4, 22] references, sum=22 test_smtplib leaked [0, 0, -1] references, sum=-1 test_sys leaked [21, -42, 42] references, sum=21 test_threading leaked [48, 48, 48] references, sum=144 test_urllib2_localnet leaked [3, 3, 3] references, sum=9 From nnorwitz at gmail.com Tue Apr 14 11:40:37 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 14 Apr 2009 05:40:37 -0400 Subject: [Python-checkins] Python Regression Test Failures all (1) Message-ID: <20090414094037.GA24227@python.psfb.org> 337 tests OK. 1 test failed: test_lib2to3 27 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_cd test_cl test_epoll 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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array 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-19522 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23366 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 test_lib2to3 failed -- errors occurred; run in verbose mode for details 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 -- OSError raises on RLock creation, see issue 3111! test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os test_parser Expecting 's_push: parser stack overflow' in next line s_push: parser stack overflow test_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib test_socket test_socketserver 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18065 refs] [17879 refs] [17879 refs] [17879 refs] [17879 refs] test_threading_local test_threadsignals test_time test_timeout 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_unpack test_urllib test_urllib2 test_urllib2_localnet test_urllib2net test_urllibnet test_urlparse test_userdict test_userlist test_userstring test_uu test_uuid WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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 337 tests OK. 1 test failed: test_lib2to3 27 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_cd test_cl test_epoll 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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [757084 refs] From python-checkins at python.org Tue Apr 14 15:16:20 2009 From: python-checkins at python.org (barry.warsaw) Date: Tue, 14 Apr 2009 15:16:20 +0200 (CEST) Subject: [Python-checkins] r71600 - in python/branches/release26-maint: Include/patchlevel.h Lib/distutils/__init__.py Lib/idlelib/idlever.py Lib/pydoc_topics.py Misc/NEWS Misc/RPM/python-2.6.spec Message-ID: <20090414131620.D610C1E4018@bag.python.org> Author: barry.warsaw Date: Tue Apr 14 15:16:19 2009 New Revision: 71600 Log: Bumping to 2.6.2 (final). Modified: python/branches/release26-maint/Include/patchlevel.h python/branches/release26-maint/Lib/distutils/__init__.py python/branches/release26-maint/Lib/idlelib/idlever.py python/branches/release26-maint/Lib/pydoc_topics.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Misc/RPM/python-2.6.spec Modified: python/branches/release26-maint/Include/patchlevel.h ============================================================================== --- python/branches/release26-maint/Include/patchlevel.h (original) +++ python/branches/release26-maint/Include/patchlevel.h Tue Apr 14 15:16:19 2009 @@ -27,7 +27,7 @@ #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "2.6.2c1" +#define PY_VERSION "2.6.2" /*--end constants--*/ /* Subversion Revision number of this file (not of the repository) */ Modified: python/branches/release26-maint/Lib/distutils/__init__.py ============================================================================== --- python/branches/release26-maint/Lib/distutils/__init__.py (original) +++ python/branches/release26-maint/Lib/distutils/__init__.py Tue Apr 14 15:16:19 2009 @@ -22,5 +22,5 @@ # #--start constants-- -__version__ = "2.6.2c1" +__version__ = "2.6.2" #--end constants-- Modified: python/branches/release26-maint/Lib/idlelib/idlever.py ============================================================================== --- python/branches/release26-maint/Lib/idlelib/idlever.py (original) +++ python/branches/release26-maint/Lib/idlelib/idlever.py Tue Apr 14 15:16:19 2009 @@ -1 +1 @@ -IDLE_VERSION = "2.6.2c1" +IDLE_VERSION = "2.6.2" Modified: python/branches/release26-maint/Lib/pydoc_topics.py ============================================================================== --- python/branches/release26-maint/Lib/pydoc_topics.py (original) +++ python/branches/release26-maint/Lib/pydoc_topics.py Tue Apr 14 15:16:19 2009 @@ -1,11 +1,11 @@ -# Autogenerated by Sphinx on Wed Dec 3 21:11:28 2008 +# Autogenerated by Sphinx on Tue Apr 14 09:12:28 2009 topics = {'assert': u'\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': u'\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\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 is recursively defined as\nfollows.\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 a sequence 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\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`` statement in the\n current code block: the name is bound to the object in the current\n local namespace.\n\n * Otherwise: the name is bound to the object in the current global\n namespace.\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 a sequence 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* 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 a plain integer. If it is negative, the\n sequence\'s length is added to it. The resulting value must be a\n nonnegative integer less than the sequence\'s length, and the\n sequence is asked to assign the assigned object to its item with\n that index. If the index is out of range, ``IndexError`` is raised\n (assignment to a subscripted sequence cannot add new items to a\n 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* 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 (small) integers. If either\n bound is negative, the sequence\'s length is added to it. The\n resulting bounds are clipped to lie between zero and the sequence\'s\n length, inclusive. Finally, the sequence object is asked to replace\n the slice with the items of the assigned sequence. The length of\n the 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(In the current implementation, the syntax for targets is taken to be\nthe same as for expressions, and invalid syntax is rejected during the\ncode generation phase, causing less 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\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 ::= target augop (expression_list | yield_expression)\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 initial value is\nretrieved with a ``getattr()`` and the result is assigned with a\n``setattr()``. Notice that the two methods do not necessarily refer\nto the same variable. When ``getattr()`` refers to a class variable,\n``setattr()`` still writes to an instance variable. For example:\n\n class A:\n x = 3 # class variable\n a = A()\n a.x += 1 # writes a.x as 4 leaving A.x as 3\n', + 'assignment': u'\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\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 is recursively defined as\nfollows.\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\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`` statement in the\n current code block: the name is bound to the object in the current\n local namespace.\n\n * Otherwise: the name is bound to the object in the current global\n namespace.\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* 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 a plain integer. If it is negative, the\n sequence\'s length is added to it. The resulting value must be a\n nonnegative integer less than the sequence\'s length, and the\n sequence is asked to assign the assigned object to its item with\n that index. If the index is out of range, ``IndexError`` is raised\n (assignment to a subscripted sequence cannot add new items to a\n 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* 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 (small) integers. If either\n bound is negative, the sequence\'s length is added to it. The\n resulting bounds are clipped to lie between zero and the sequence\'s\n length, inclusive. Finally, the sequence object is asked to replace\n the slice with the items of the assigned sequence. The length of\n the 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(In the current implementation, the syntax for targets is taken to be\nthe same as for expressions, and invalid syntax is rejected during the\ncode generation phase, causing less 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\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 initial value is\nretrieved with a ``getattr()`` and the result is assigned with a\n``setattr()``. Notice that the two methods do not necessarily refer\nto the same variable. When ``getattr()`` refers to a class variable,\n``setattr()`` still writes to an instance variable. For example:\n\n class A:\n x = 3 # class variable\n a = A()\n a.x += 1 # writes a.x as 4 leaving A.x as 3\n', 'atom-identifiers': u'\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', 'atom-literals': u"\nLiterals\n********\n\nPython supports string literals and various numeric literals:\n\n literal ::= stringliteral | integer | longinteger\n | floatnumber | imagnumber\n\nEvaluation of a literal yields an object of the given type (string,\ninteger, long integer, floating point number, complex number) with the\ngiven value. The value may be approximated in the case of floating\npoint and imaginary (complex) literals. See section *Literals* for\ndetails.\n\nAll literals correspond to immutable data types, and hence the\nobject's identity is less important than its value. Multiple\nevaluations of literals with the same value (either the same\noccurrence in the program text or a different occurrence) may obtain\nthe same object or a different object with the same value.\n", 'attribute-access': u'\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 in new-style classes.\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 not simply execute ``self.name = value`` --- this would\n cause a recursive call to itself. Instead, it should insert the\n value in the dictionary of instance attributes, e.g.,\n ``self.__dict__[name] = value``. For new-style classes, rather\n than accessing the instance dictionary, it should call the base\n 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\n\nMore attribute access for new-style classes\n===========================================\n\nThe following methods only apply to new-style classes.\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 builtin functions. See *Special method lookup for new-style\n classes*.\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 new-style class, known as the *owner*\nclass. In the examples below, "the attribute" refers to the attribute\nwhose name is the key of the property in the owner class\'\n``__dict__``. Descriptors can only be implemented as new-style\nclasses themselves.\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. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass ``object()`` or\n``type()``).\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 a new-style object instance, ``a.x`` is transformed\n into the call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a new-style class, ``A.x`` is transformed into the\n call: ``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. Normally, data\ndescriptors define both ``__get__()`` and ``__set__()``, while non-\ndata descriptors have just the ``__get__()`` method. Data descriptors\nalways override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances. [2]\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 both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__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 new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n New in version 2.2.\n\nNotes on using *__slots__*\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 Changed in version 2.3: Previously, adding ``\'__dict__\'`` to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\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 Changed in version 2.3: Previously, adding ``\'__weakref__\'`` to the\n *__slots__* declaration would not enable support for weak\n references.\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* 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* 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__*.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as ``long``, ``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 Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n', 'attribute-references': u'\nAttribute references\n********************\n\nAn attribute reference is a primary followed by a period and a name:\n\n attributeref ::= primary "." identifier\n\nThe primary must evaluate to an object of a type that supports\nattribute references, e.g., a module, list, or an instance. This\nobject is then asked to produce the attribute whose name is the\nidentifier. If this attribute is not available, the exception\n``AttributeError`` is raised. Otherwise, the type and value of the\nobject produced is determined by the object. Multiple evaluations of\nthe same attribute reference may yield different objects.\n', - 'augassign': u'\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 ::= target augop (expression_list | yield_expression)\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 initial value is\nretrieved with a ``getattr()`` and the result is assigned with a\n``setattr()``. Notice that the two methods do not necessarily refer\nto the same variable. When ``getattr()`` refers to a class variable,\n``setattr()`` still writes to an instance variable. For example:\n\n class A:\n x = 3 # class variable\n a = A()\n a.x += 1 # writes a.x as 4 leaving A.x as 3\n', + 'augassign': u'\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 initial value is\nretrieved with a ``getattr()`` and the result is assigned with a\n``setattr()``. Notice that the two methods do not necessarily refer\nto the same variable. When ``getattr()`` refers to a class variable,\n``setattr()`` still writes to an instance variable. For example:\n\n class A:\n x = 3 # class variable\n a = A()\n a.x += 1 # writes a.x as 4 leaving A.x as 3\n', 'binary': u'\nBinary arithmetic operations\n****************************\n\nThe binary arithmetic operations have the conventional priority\nlevels. Note that some of these operations also apply to certain non-\nnumeric types. Apart from the power operator, there are only two\nlevels, one for multiplicative operators and one for additive\noperators:\n\n m_expr ::= u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr\n | m_expr "%" u_expr\n a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr\n\nThe ``*`` (multiplication) operator yields the product of its\narguments. The arguments must either both be numbers, or one argument\nmust be an integer (plain or long) and the other must be a sequence.\nIn the former case, the numbers are converted to a common type and\nthen multiplied together. In the latter case, sequence repetition is\nperformed; a negative repetition factor yields an empty sequence.\n\nThe ``/`` (division) and ``//`` (floor division) operators yield the\nquotient of their arguments. The numeric arguments are first\nconverted to a common type. Plain or long integer division yields an\ninteger of the same type; the result is that of mathematical division\nwith the \'floor\' function applied to the result. Division by zero\nraises the ``ZeroDivisionError`` exception.\n\nThe ``%`` (modulo) operator yields the remainder from the division of\nthe first argument by the second. The numeric arguments are first\nconverted to a common type. A zero right argument raises the\n``ZeroDivisionError`` exception. The arguments may be floating point\nnumbers, e.g., ``3.14%0.7`` equals ``0.34`` (since ``3.14`` equals\n``4*0.7 + 0.34``.) The modulo operator always yields a result with\nthe same sign as its second operand (or zero); the absolute value of\nthe result is strictly smaller than the absolute value of the second\noperand [2].\n\nThe integer division and modulo operators are connected by the\nfollowing identity: ``x == (x/y)*y + (x%y)``. Integer division and\nmodulo are also connected with the built-in function ``divmod()``:\n``divmod(x, y) == (x/y, x%y)``. These identities don\'t hold for\nfloating point numbers; there similar identities hold approximately\nwhere ``x/y`` is replaced by ``floor(x/y)`` or ``floor(x/y) - 1`` [3].\n\nIn addition to performing the modulo operation on numbers, the ``%``\noperator is also overloaded by string and unicode objects to perform\nstring formatting (also known as interpolation). The syntax for string\nformatting is described in the Python Library Reference, section\n*String Formatting Operations*.\n\nDeprecated since version 2.3: The floor division operator, the modulo\noperator, and the ``divmod()`` function are no longer defined for\ncomplex numbers. Instead, convert to a floating point number using\nthe ``abs()`` function if appropriate.\n\nThe ``+`` (addition) operator yields the sum of its arguments. The\narguments must either both be numbers or both sequences of the same\ntype. In the former case, the numbers are converted to a common type\nand then added together. In the latter case, the sequences are\nconcatenated.\n\nThe ``-`` (subtraction) operator yields the difference of its\narguments. The numeric arguments are first converted to a common\ntype.\n', 'bitwise': u'\nBinary bitwise operations\n*************************\n\nEach of the three bitwise operations has a different priority level:\n\n and_expr ::= shift_expr | and_expr "&" shift_expr\n xor_expr ::= and_expr | xor_expr "^" and_expr\n or_expr ::= xor_expr | or_expr "|" xor_expr\n\nThe ``&`` operator yields the bitwise AND of its arguments, which must\nbe plain or long integers. The arguments are converted to a common\ntype.\n\nThe ``^`` operator yields the bitwise XOR (exclusive OR) of its\narguments, which must be plain or long integers. The arguments are\nconverted to a common type.\n\nThe ``|`` operator yields the bitwise (inclusive) OR of its arguments,\nwhich must be plain or long integers. The arguments are converted to\na common type.\n', 'bltin-code-objects': u'\nCode Objects\n************\n\nCode objects are used by the implementation to represent "pseudo-\ncompiled" executable Python code such as a function body. They differ\nfrom function objects because they don\'t contain a reference to their\nglobal execution environment. Code objects are returned by the built-\nin ``compile()`` function and can be extracted from function objects\nthrough their ``func_code`` attribute. See also the ``code`` module.\n\nA code object can be executed or evaluated by passing it (instead of a\nsource string) to the ``exec`` statement or the built-in ``eval()``\nfunction.\n\nSee *The standard type hierarchy* for more information.\n', @@ -18,21 +18,21 @@ 'callable-types': u'\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': u'\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 [","]\n | expression genexpr_for] ")"\n argument_list ::= positional_arguments ["," keyword_arguments]\n ["," "*" expression] ["," keyword_arguments]\n ["," "**" expression]\n | keyword_arguments ["," "*" expression]\n ["," "**" expression]\n | "*" expression ["," "*" expression] ["," "**" 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 certain class instances\nthemselves are callable; extensions may define additional callable\nobject types). All argument expressions are evaluated before the call\nis attempted. Please refer to section *Function definitions* for the\nsyntax 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\nNote: An implementation may provide builtin functions whose positional\n parameters do not have names, even if they are \'named\' for the\n purpose of documentation, and which therefore cannot be supplied by\n keyword. In CPython, this is the case for functions implemented in\n C that use ``PyArg_ParseTuple`` to parse 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. Formal parameters using the syntax ``(sublist)`` cannot be\nused as keyword argument names; the outermost sublist corresponds to a\nsingle unnamed argument slot, and the argument value is assigned to\nthe sublist using the usual tuple assignment rules after all other\nparameter processing is done.\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': u'\nClass definitions\n*****************\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with ``self.name = value``.\nBoth class and instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\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', - 'coercion-rules': u"\nCoercion rules\n**************\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3.0, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don't define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from ``object``) never invoke the\n ``__coerce__()`` method in response to a binary operator; the only\n time ``__coerce__()`` is invoked is when the built-in function\n ``coerce()`` is called.\n\n* For most intents and purposes, an operator that returns\n ``NotImplemented`` is treated the same as one that is not\n implemented at all.\n\n* Below, ``__op__()`` and ``__rop__()`` are used to signify the\n generic method names corresponding to an operator; ``__iop__()`` is\n used for the corresponding in-place operator. For example, for the\n operator '``+``', ``__add__()`` and ``__radd__()`` are used for the\n left and right variant of the binary operator, and ``__iadd__()``\n for the in-place variant.\n\n* For objects *x* and *y*, first ``x.__op__(y)`` is tried. If this is\n not implemented or returns ``NotImplemented``, ``y.__rop__(x)`` is\n tried. If this is also not implemented or returns\n ``NotImplemented``, a ``TypeError`` exception is raised. But see\n the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base's ``__rop__()`` method, the right operand's ``__rop__()``\n method is tried *before* the left operand's ``__op__()`` method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand's ``__op__()`` method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is called\n before that type's ``__op__()`` or ``__rop__()`` method is called,\n but no sooner. If the coercion returns an object of a different\n type for the operand whose coercion is invoked, part of the process\n is redone using the new object.\n\n* When an in-place operator (like '``+=``') is used, if the left\n operand implements ``__iop__()``, it is invoked without any\n coercion. When the operation falls back to ``__op__()`` and/or\n ``__rop__()``, the normal coercion rules apply.\n\n* In ``x + y``, if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In ``x * y``, if one operator is a sequence that implements sequence\n repetition, and the other is an integer (``int`` or ``long``),\n sequence repetition is invoked.\n\n* Rich comparisons (implemented by methods ``__eq__()`` and so on)\n never use coercion. Three-way comparison (implemented by\n ``__cmp__()``) does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types ``int``,\n ``long`` and ``float`` do not use coercion; the type ``complex``\n however does use it. The difference can become apparent when\n subclassing these types. Over time, the type ``complex`` may be\n fixed to avoid coercion. All these types implement a\n ``__coerce__()`` method, for use by the built-in ``coerce()``\n function.\n", + 'coercion-rules': u"\nCoercion rules\n**************\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3.0, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don't define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from ``object``) never invoke the\n ``__coerce__()`` method in response to a binary operator; the only\n time ``__coerce__()`` is invoked is when the built-in function\n ``coerce()`` is called.\n\n* For most intents and purposes, an operator that returns\n ``NotImplemented`` is treated the same as one that is not\n implemented at all.\n\n* Below, ``__op__()`` and ``__rop__()`` are used to signify the\n generic method names corresponding to an operator; ``__iop__()`` is\n used for the corresponding in-place operator. For example, for the\n operator '``+``', ``__add__()`` and ``__radd__()`` are used for the\n left and right variant of the binary operator, and ``__iadd__()``\n for the in-place variant.\n\n* For objects *x* and *y*, first ``x.__op__(y)`` is tried. If this is\n not implemented or returns ``NotImplemented``, ``y.__rop__(x)`` is\n tried. If this is also not implemented or returns\n ``NotImplemented``, a ``TypeError`` exception is raised. But see\n the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base's ``__rop__()`` method, the right operand's ``__rop__()``\n method is tried *before* the left operand's ``__op__()`` method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand's ``__op__()`` method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is called\n before that type's ``__op__()`` or ``__rop__()`` method is called,\n but no sooner. If the coercion returns an object of a different\n type for the operand whose coercion is invoked, part of the process\n is redone using the new object.\n\n* When an in-place operator (like '``+=``') is used, if the left\n operand implements ``__iop__()``, it is invoked without any\n coercion. When the operation falls back to ``__op__()`` and/or\n ``__rop__()``, the normal coercion rules apply.\n\n* In ``x + y``, if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In ``x * y``, if one operator is a sequence that implements sequence\n repetition, and the other is an integer (``int`` or ``long``),\n sequence repetition is invoked.\n\n* Rich comparisons (implemented by methods ``__eq__()`` and so on)\n never use coercion. Three-way comparison (implemented by\n ``__cmp__()``) does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types ``int``,\n ``long`` and ``float`` do not use coercion; the type ``complex``\n however does use coercion for binary operators and rich comparisons,\n despite the above rules. The difference can become apparent when\n subclassing these types. Over time, the type ``complex`` may be\n fixed to avoid coercion. All these types implement a\n ``__coerce__()`` method, for use by the built-in ``coerce()``\n function.\n", 'comparisons': u'\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 forms ``<>`` and ``!=`` are equivalent; for consistency with C,\n``!=`` is preferred; where ``!=`` is mentioned below ``<>`` is also\naccepted. The ``<>`` spelling is considered obsolescent.\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,\nobjects of different types *always* compare unequal, and are ordered\nconsistently but arbitrarily. You can control comparison behavior of\nobjects of non-builtin types by defining a ``__cmp__`` method or rich\ncomparison methods like ``__gt__``, described in section *Special\nmethod names*.\n\n(This unusual definition of comparison was used to simplify the\ndefinition of operations like sorting and the ``in`` and ``not in``\noperators. In the future, the comparison rules for objects of\ndifferent types are likely to change.)\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n Unicode and 8-bit strings are fully interoperable in this behavior.\n [4]\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, ``cmp([1,2,x], [1,2,y])`` returns\n the same as ``cmp(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 their sorted\n (key, value) lists compare equal. [5] Outcomes other than equality\n are resolved consistently, but are not otherwise defined. [6]\n\n* Most other objects of builtin 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\nThe operators ``in`` and ``not in`` test for collection membership.\n``x in s`` evaluates to true if *x* is a member of the collection *s*,\nand false otherwise. ``x not in s`` returns the negation of ``x in\ns``. The collection membership test has traditionally been bound to\nsequences; an object is a member of a collection if the collection is\na sequence and contains an element equal to that object. However, it\nmake sense for many other object types to support membership tests\nwithout being a sequence. In particular, dictionaries (for keys) and\nsets support membership testing.\n\nFor the list and tuple types, ``x in y`` is true if and only if there\nexists an index *i* such that ``x == y[i]`` is true.\n\nFor the Unicode and string types, ``x in y`` is true if and only if\n*x* is a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nNote, *x* and *y* need not be the same type; consequently, ``u\'ab\' in\n\'abc\'`` will return ``True``. Empty strings are always considered to\nbe a substring of any other string, so ``"" in "abc"`` will return\n``True``.\n\nChanged in version 2.3: Previously, *x* was required to be a string of\nlength ``1``.\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__()`` and do\ndefine ``__getitem__()``, ``x in y`` is true if and only if there is a\nnon-negative 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. [7]\n', 'compound': u'\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. Function and class\ndefinitions are also syntactically compound 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`` statements 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 | decorated\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, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\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\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nWarning: 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 internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n 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\nChanged in version 2.5: In previous versions of Python,\n``try``...``except``...``finally`` did not work. ``try``...``except``\nhad to be nested in ``try``...``finally``.\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, a tuple containing an item compatible with the\nexception, or, in the (deprecated) case of string exceptions, is the\nraised string itself (note that the object identities must match, i.e.\nit must be the same string object, not just a string with the same\nvalue).\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 in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the ``sys`` module:\n``sys.exc_type`` receives the object identifying the exception;\n``sys.exc_value`` receives the exception\'s parameter;\n``sys.exc_traceback`` receives a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. These details are also available through the\n``sys.exc_info()`` function, which returns a tuple ``(exc_type,\nexc_value, exc_traceback)``. Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables 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\nNew in version 2.5.\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" expression ["as" target] ":" suite\n\nThe execution of the ``with`` statement proceeds as follows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__enter__()`` method is invoked.\n\n3. 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 5 below.\n\n4. The suite is executed.\n\n5. 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\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\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 decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier [, "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\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 top-level 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 must also have a default value --- this is a syntactic\nrestriction 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.\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 *Expression lists*. Note that the lambda form is\nmerely a shorthand for a simplified function definition; a function\ndefined in a "``def``" statement can be passed around or assigned to\nanother name just like a function defined by a lambda form. The\n"``def``" form is actually more powerful since it allows the execution\nof multiple statements.\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 ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with ``self.name = value``.\nBoth class and instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\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': u'\nWith Statement Context Managers\n*******************************\n\nNew in version 2.5.\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': u'\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': u'\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," the arguments\nare coerced using the coercion rules listed at *Coercion rules*. If\nboth arguments are standard numeric types, the following coercions are\napplied:\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, if either argument is a long integer, the other is\n converted to long integer;\n\n* otherwise, both must be plain integers and no conversion is\n necessary.\n\nSome additional rules apply for certain operators (e.g., a string left\nargument to the \'%\' operator). Extensions can define their own\ncoercions.\n', - 'customization': u'\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_traceback`` 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.exc_traceback`` or ``sys.last_traceback``. Circular\n references which are garbage are detected when the option cycle\n detector is enabled (it\'s on by default), but can only be cleaned\n up if there are no Python-level ``__del__()`` methods involved.\n Refer to the documentation for the ``gc`` module for more\n information about how ``__del__()`` methods are handled by the\n cycle detector, particularly the description of the ``garbage``\n 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. For this reason, ``__del__()`` methods should do\n the absolute minimum needed to maintain external invariants.\n Starting with version 1.5, Python guarantees that globals whose\n name begins with a single underscore are deleted from their\n module before other globals are deleted; if no other references\n to such globals exist, this may help in assuring that imported\n modules are still available at the time when the ``__del__()``\n method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is 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 statement 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.__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 New in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` call ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and\n ``x>=y`` calls ``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\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by ``__cmp__()`` has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\n\nobject.__hash__(self)\n\n Called for the key object for dictionary operations, and by the\n built-in function ``hash()``. Should return an integer usable as a\n hash value for dictionary operations. The only required property\n is that objects which compare equal have the same hash value; it is\n advised to somehow mix together (e.g., using exclusive or) the hash\n values for the components of the object that also play a part in\n comparison of objects.\n\n If a class does not define a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable as dictionary keys. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n the dictionary implementation requires that a key\'s hash value is\n immutable (if the object\'s hash value changes, it will be in the\n wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` 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 ``__cmp__()`` or ``__eq__()`` such that\n the hash value returned is no longer appropriate (e.g. by switching\n to a value-based concept of equality instead of the default\n identity based equality) can explicitly flag themselves as being\n unhashable by setting ``__hash__ = None`` in the class definition.\n Doing so means that not only will instances of the class raise an\n appropriate ``TypeError`` when a program attempts to retrieve their\n hash value, but they will also be correctly identified as\n unhashable when checking ``isinstance(obj, collections.Hashable)``\n (unlike classes which define their own ``__hash__()`` to explicitly\n raise ``TypeError``).\n\n Changed in version 2.5: ``__hash__()`` may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\n Changed in version 2.6: ``__hash__`` may now be set to ``None`` to\n explicitly flag instances of a class as unhashable.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing, and the built-in operation\n ``bool()``; should return ``False`` or ``True``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined (see below). If a class\n defines neither ``__len__()`` nor ``__nonzero__()``, all its\n instances are considered true.\n\nobject.__unicode__(self)\n\n Called to implement ``unicode()`` builtin; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\n', + 'customization': u'\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_traceback`` 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.exc_traceback`` or ``sys.last_traceback``. Circular\n references which are garbage are detected when the option cycle\n detector is enabled (it\'s on by default), but can only be cleaned\n up if there are no Python-level ``__del__()`` methods involved.\n Refer to the documentation for the ``gc`` module for more\n information about how ``__del__()`` methods are handled by the\n cycle detector, particularly the description of the ``garbage``\n 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 and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is 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 statement 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.__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 New in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` call ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and\n ``x>=y`` calls ``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\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by ``__cmp__()`` has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\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 a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable in hashed collections. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n hashable collection implementations require that a object\'s hash\n value is immutable (if the object\'s hash value changes, it will be\n in the wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` 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 ``__cmp__()`` or ``__eq__()`` such that\n the hash value returned is no longer appropriate (e.g. by switching\n to a value-based concept of equality instead of the default\n identity based equality) can explicitly flag themselves as being\n unhashable by setting ``__hash__ = None`` in the class definition.\n Doing so means that not only will instances of the class raise an\n appropriate ``TypeError`` when a program attempts to retrieve their\n hash value, but they will also be correctly identified as\n unhashable when checking ``isinstance(obj, collections.Hashable)``\n (unlike classes which define their own ``__hash__()`` to explicitly\n raise ``TypeError``).\n\n Changed in version 2.5: ``__hash__()`` may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\n Changed in version 2.6: ``__hash__`` may now be set to ``None`` to\n explicitly flag instances of a class as unhashable.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing and the built-in operation\n ``bool()``; should return ``False`` or ``True``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined, and the object is\n considered true if its result is nonzero. If a class defines\n neither ``__len__()`` nor ``__nonzero__()``, all its instances are\n considered true.\n\nobject.__unicode__(self)\n\n Called to implement ``unicode()`` builtin; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\n', 'debugger': u'\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``\n(undocumented) and ``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 python -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 2.4: Restarting post-mortem behavior added.\n\nTypical 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[, locals]])\n\n Execute the *statement* (given as a string) under debugger control.\n The debugger prompt appears before any code is executed; you can\n set breakpoints and type ``continue``, or you can step through the\n statement using ``step`` or ``next`` (all these commands are\n explained below). The optional *globals* and *locals* arguments\n specify the environment in which the code is executed; by default\n the dictionary of the module ``__main__`` is used. (See the\n explanation of the ``exec`` statement or the ``eval()`` built-in\n function.)\n\npdb.runeval(expression[, globals[, locals]])\n\n Evaluate the *expression* (given as a string) under debugger\n control. When ``runeval()`` returns, it returns the value of the\n expression. Otherwise this function is similar to ``run()``.\n\npdb.runcall(function[, argument, ...])\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])\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', 'del': u'\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\nIt is illegal to delete a name from the local namespace if it occurs\nas a free variable in a nested block.\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', 'dict': u'\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] "}"\n key_datum_list ::= key_datum ("," key_datum)* [","]\n key_datum ::= expression ":" expression\n\nA dictionary display yields a new dictionary object.\n\nThe key/datum pairs are evaluated from left to right to define the\nentries of the dictionary: each key object is used as a key into the\ndictionary to store the corresponding datum.\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': u'\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\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n', 'else': u'\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', 'exceptions': u'\nExceptions\n**********\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nWarning: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', - 'exec': u'\nThe ``exec`` statement\n**********************\n\n exec_stmt ::= "exec" or_expr ["in" expression ["," expression]]\n\nThis statement supports dynamic execution of Python code. The first\nexpression should evaluate to either a string, an open file object, or\na code object. If it is a string, the string is parsed as a suite of\nPython statements which is then executed (unless a syntax error\noccurs). If it is an open file, the file is parsed until EOF and\nexecuted. If it is a code object, it is simply executed. In all\ncases, the code that\'s executed is expected to be valid as file input\n(see section *File input*). Be aware that the ``return`` and\n``yield`` statements may not be used outside of function definitions\neven within the context of code passed to the ``exec`` statement.\n\nIn all cases, if the optional parts are omitted, the code is executed\nin the current scope. If only the first expression after ``in`` is\nspecified, it should be a dictionary, which will be used for both the\nglobal and the local variables. If two expressions are given, they\nare used for the global and local variables, respectively. If\nprovided, *locals* can be any mapping object.\n\nChanged in version 2.4: Formerly, *locals* was required to be a\ndictionary.\n\nAs a side effect, an implementation may insert additional keys into\nthe dictionaries given besides those corresponding to variable names\nset by the executed code. For example, the current implementation may\nadd a reference to the dictionary of the built-in module\n``__builtin__`` under the key ``__builtins__`` (!).\n\n**Programmer\'s hints:** dynamic evaluation of expressions is supported\nby the built-in function ``eval()``. The built-in functions\n``globals()`` and ``locals()`` return the current global and local\ndictionary, respectively, which may be useful to pass around for use\nby ``exec``.\n', - 'execmodel': u'\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, or in\nthe second position of an ``except`` clause header. The ``import``\nstatement of the form "``from ...import *``" binds all names defined\nin the imported module, except those beginning with an underscore.\nThis form may only be used at the module level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtin namespace, the namespace of\nthe module ``__builtin__``. The global namespace is searched first.\nIf the name is not found there, the builtin namespace is searched.\nThe global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no \'s\'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``__builtin__`` (no \'s\')\n module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\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\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nWarning: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', + 'exec': u'\nThe ``exec`` statement\n**********************\n\n exec_stmt ::= "exec" or_expr ["in" expression ["," expression]]\n\nThis statement supports dynamic execution of Python code. The first\nexpression should evaluate to either a string, an open file object, or\na code object. If it is a string, the string is parsed as a suite of\nPython statements which is then executed (unless a syntax error\noccurs). [1] If it is an open file, the file is parsed until EOF and\nexecuted. If it is a code object, it is simply executed. In all\ncases, the code that\'s executed is expected to be valid as file input\n(see section *File input*). Be aware that the ``return`` and\n``yield`` statements may not be used outside of function definitions\neven within the context of code passed to the ``exec`` statement.\n\nIn all cases, if the optional parts are omitted, the code is executed\nin the current scope. If only the first expression after ``in`` is\nspecified, it should be a dictionary, which will be used for both the\nglobal and the local variables. If two expressions are given, they\nare used for the global and local variables, respectively. If\nprovided, *locals* can be any mapping object.\n\nChanged in version 2.4: Formerly, *locals* was required to be a\ndictionary.\n\nAs a side effect, an implementation may insert additional keys into\nthe dictionaries given besides those corresponding to variable names\nset by the executed code. For example, the current implementation may\nadd a reference to the dictionary of the built-in module\n``__builtin__`` under the key ``__builtins__`` (!).\n\n**Programmer\'s hints:** dynamic evaluation of expressions is supported\nby the built-in function ``eval()``. The built-in functions\n``globals()`` and ``locals()`` return the current global and local\ndictionary, respectively, which may be useful to pass around for use\nby ``exec``.\n\n-[ Footnotes ]-\n\n[1] Note that the parser only accepts the Unix-style end of line\n convention. If you are reading the code from a file, make sure to\n use universal newline mode to convert Windows or Mac-style\n newlines.\n', + 'execmodel': u'\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, in the\nsecond position of an ``except`` clause header or after ``as`` in a\n``with`` statement. The ``import`` statement of the form ``from ...\nimport *`` binds all names defined in the imported module, except\nthose beginning with an underscore. This form may only be used at the\nmodule level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtin namespace, the namespace of\nthe module ``__builtin__``. The global namespace is searched first.\nIf the name is not found there, the builtin namespace is searched.\nThe global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no \'s\'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``__builtin__`` (no \'s\')\n module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\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\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nWarning: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', 'exprlists': u'\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': u'\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 of floating point numbers can\nlook like octal integers, but are interpreted using radix 10. For\nexample, ``077e010`` is legal, and denotes the same number as\n``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': u'\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, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\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\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nWarning: 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 internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n 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', @@ -43,16 +43,16 @@ 'identifiers': u'\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions:\n\n identifier ::= (letter|"_") (letter | digit | "_")*\n letter ::= lowercase | uppercase\n lowercase ::= "a"..."z"\n uppercase ::= "A"..."Z"\n digit ::= "0"..."9"\n\nIdentifiers are unlimited in length. Case is significant.\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 and del from not while\n as elif global or with\n assert else if pass yield\n break except import print\n class exec in raise\n continue finally is return\n def for lambda try\n\nChanged in version 2.4: ``None`` became a constant and is now\nrecognized by the compiler as a name for the built-in object ``None``.\nAlthough it is not a keyword, you cannot assign a different object to\nit.\n\nChanged in version 2.5: Both ``as`` and ``with`` are only recognized\nwhen the ``with_statement`` future feature has been enabled. It will\nalways be enabled in Python 2.6. See section *The with statement* for\ndetails. Note that using ``as`` and ``with`` as identifiers will\nalways issue a warning, even when the ``with_statement`` future\ndirective is not in effect.\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 ``__builtin__`` module.\n When not in interactive mode, ``_`` has no special meaning and is\n not 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);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\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': u'\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': u'\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': u'\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\nfirst form (without ``from``) repeats these steps for each identifier\nin the list. The form with ``from`` performs step (1) once, and then\nperforms step (2) repeatedly.\n\nIn this context, to "initialize" a built-in or extension module means\nto call an initialization function that the module must provide for\nthe purpose (in the reference implementation, the function\'s name is\nobtained by prepending string "init" to the module\'s name); to\n"initialize" a Python-coded module means to execute the module\'s body.\n\nThe system maintains a table of modules that have been or are being\ninitialized, indexed by module name. This table is accessible as\n``sys.modules``. When a module name is found in this table, step (1)\nis finished. If not, a search for a module definition is started.\nWhen a module is found, it is loaded. Details of the module searching\nand loading process are implementation and platform specific. It\ngenerally involves searching for a "built-in" module with the given\nname and then searching a list of locations given as ``sys.path``.\n\nIf a built-in module is found, its built-in initialization code is\nexecuted and step (1) is finished. If no matching file is found,\n``ImportError`` is raised. If a file is found, it is parsed, yielding\nan executable code block. If a syntax error occurs, ``SyntaxError``\nis raised. Otherwise, an empty module of the given name is created\nand inserted in the module table, and then the code block is executed\nin the context of this module. Exceptions during this execution\nterminate step (1).\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. If the\nwild card form of import --- ``import *`` --- is used in a function\nand the function contains or is a nested block with free variables,\nthe compiler will raise a ``SyntaxError``.\n\n**Hierarchical module names:** when the module names contains one or\nmore dots, the module search path is carried out differently. The\nsequence of identifiers up to the last dot is used to find a\n"package"; the final identifier is then searched inside the package.\nA package is generally a subdirectory of a directory on ``sys.path``\nthat has a file ``__init__.py``.\n\nThe built-in function ``__import__()`` is provided to support\napplications that determine which modules need to be loaded\ndynamically; refer to *Built-in Functions* for additional information.\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 2.6 are ``unicode_literals``,\n``print_function``, ``absolute_import``, ``division``, ``generators``,\n``nested_scopes`` and ``with_statement``. ``generators``,\n``with_statement``, ``nested_scopes`` are redundant in Python version\n2.6 and above because they are always enabled.\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 an ``exec`` statement or calls to the builtin\nfunctions ``compile()`` and ``execfile()`` that occur in a module\n``M`` containing a future statement will, by default, use the new\nsyntax or semantics associated with the future statement. This can,\nstarting with Python 2.2 be controlled by optional arguments to\n``compile()`` --- see the documentation of that function for 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', + 'import': u'\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.\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.\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. If the\nwild card form of import --- ``import *`` --- is used in a function\nand the function contains or is a nested block with free variables,\nthe compiler will 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\nimprt mod`` from within ``pkg.subpkg1`` you will import\n``pkg.subpkg2.mod``. The specification for relative imports is\ncontained within **PEP 328**.\n\nThe built-in function ``__import__()`` is provided to support\napplications that determine which modules need to be loaded\ndynamically; refer to *Built-in Functions* for additional information.\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 2.6 are ``unicode_literals``,\n``print_function``, ``absolute_import``, ``division``, ``generators``,\n``nested_scopes`` and ``with_statement``. ``generators``,\n``with_statement``, ``nested_scopes`` are redundant in Python version\n2.6 and above because they are always enabled.\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 an ``exec`` statement or calls to the builtin\nfunctions ``compile()`` and ``execfile()`` that occur in a module\n``M`` containing a future statement will, by default, use the new\nsyntax or semantics associated with the future statement. This can,\nstarting with Python 2.2 be controlled by optional arguments to\n``compile()`` --- see the documentation of that function for 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', 'in': u'\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 forms ``<>`` and ``!=`` are equivalent; for consistency with C,\n``!=`` is preferred; where ``!=`` is mentioned below ``<>`` is also\naccepted. The ``<>`` spelling is considered obsolescent.\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,\nobjects of different types *always* compare unequal, and are ordered\nconsistently but arbitrarily. You can control comparison behavior of\nobjects of non-builtin types by defining a ``__cmp__`` method or rich\ncomparison methods like ``__gt__``, described in section *Special\nmethod names*.\n\n(This unusual definition of comparison was used to simplify the\ndefinition of operations like sorting and the ``in`` and ``not in``\noperators. In the future, the comparison rules for objects of\ndifferent types are likely to change.)\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n Unicode and 8-bit strings are fully interoperable in this behavior.\n [4]\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, ``cmp([1,2,x], [1,2,y])`` returns\n the same as ``cmp(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 their sorted\n (key, value) lists compare equal. [5] Outcomes other than equality\n are resolved consistently, but are not otherwise defined. [6]\n\n* Most other objects of builtin 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\nThe operators ``in`` and ``not in`` test for collection membership.\n``x in s`` evaluates to true if *x* is a member of the collection *s*,\nand false otherwise. ``x not in s`` returns the negation of ``x in\ns``. The collection membership test has traditionally been bound to\nsequences; an object is a member of a collection if the collection is\na sequence and contains an element equal to that object. However, it\nmake sense for many other object types to support membership tests\nwithout being a sequence. In particular, dictionaries (for keys) and\nsets support membership testing.\n\nFor the list and tuple types, ``x in y`` is true if and only if there\nexists an index *i* such that ``x == y[i]`` is true.\n\nFor the Unicode and string types, ``x in y`` is true if and only if\n*x* is a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nNote, *x* and *y* need not be the same type; consequently, ``u\'ab\' in\n\'abc\'`` will return ``True``. Empty strings are always considered to\nbe a substring of any other string, so ``"" in "abc"`` will return\n``True``.\n\nChanged in version 2.3: Previously, *x* was required to be a string of\nlength ``1``.\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__()`` and do\ndefine ``__getitem__()``, ``x in y`` is true if and only if there is a\nnon-negative 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. [7]\n', 'integers': u'\nInteger and long integer literals\n*********************************\n\nInteger and long integer literals are described by the following\nlexical definitions:\n\n longinteger ::= integer ("l" | "L")\n integer ::= decimalinteger | octinteger | hexinteger | bininteger\n decimalinteger ::= nonzerodigit digit* | "0"\n octinteger ::= "0" ("o" | "O") octdigit+ | "0" octdigit+\n hexinteger ::= "0" ("x" | "X") hexdigit+\n bininteger ::= "0" ("b" | "B") bindigit+\n nonzerodigit ::= "1"..."9"\n octdigit ::= "0"..."7"\n bindigit ::= "0" | "1"\n hexdigit ::= digit | "a"..."f" | "A"..."F"\n\nAlthough both lower case ``\'l\'`` and upper case ``\'L\'`` are allowed as\nsuffix for long integers, it is strongly recommended to always use\n``\'L\'``, since the letter ``\'l\'`` looks too much like the digit\n``\'1\'``.\n\nPlain integer literals that are above the largest representable plain\ninteger (e.g., 2147483647 when using 32-bit arithmetic) are accepted\nas if they were long integers instead. [1] There is no limit for long\ninteger literals apart from what can be stored in available memory.\n\nSome examples of plain integer literals (first row) and long integer\nliterals (second and third rows):\n\n 7 2147483647 0177\n 3L 79228162514264337593543950336L 0377L 0x100000000L\n 79228162514264337593543950336 0xdeadbeef\n', 'lambda': u'\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', 'lists': u'\nList displays\n*************\n\nA list display is a possibly empty series of expressions enclosed in\nsquare brackets:\n\n list_display ::= "[" [expression_list | list_comprehension] "]"\n list_comprehension ::= expression list_for\n list_for ::= "for" target_list "in" old_expression_list [list_iter]\n old_expression_list ::= old_expression [("," old_expression)+ [","]]\n list_iter ::= list_for | list_if\n list_if ::= "if" old_expression [list_iter]\n\nA list display yields a new list object. Its contents are specified\nby providing either a list of expressions or a list comprehension.\nWhen a comma-separated list of expressions is supplied, its elements\nare evaluated from left to right and placed into the list object in\nthat order. When a list comprehension is supplied, it consists of a\nsingle expression followed by at least one ``for`` clause and zero or\nmore ``for`` or ``if`` clauses. In this case, the elements of the new\nlist are those that would be produced by considering each of the\n``for`` or ``if`` clauses a block, nesting from left to right, and\nevaluating the expression to produce a list element each time the\ninnermost block is reached [1].\n', - 'naming': u'\nNaming and binding\n******************\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, or in\nthe second position of an ``except`` clause header. The ``import``\nstatement of the form "``from ...import *``" binds all names defined\nin the imported module, except those beginning with an underscore.\nThis form may only be used at the module level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtin namespace, the namespace of\nthe module ``__builtin__``. The global namespace is searched first.\nIf the name is not found there, the builtin namespace is searched.\nThe global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no \'s\'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``__builtin__`` (no \'s\')\n module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\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\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n', + 'naming': u"\nNaming and binding\n******************\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the '**-c**' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block's execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block's *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, in the\nsecond position of an ``except`` clause header or after ``as`` in a\n``with`` statement. The ``import`` statement of the form ``from ...\nimport *`` binds all names defined in the imported module, except\nthose beginning with an underscore. This form may only be used at the\nmodule level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtin namespace, the namespace of\nthe module ``__builtin__``. The global namespace is searched first.\nIf the name is not found there, the builtin namespace is searched.\nThe global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module's dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no 's'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``__builtin__`` (no 's')\n module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\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\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n", 'numbers': u"\nNumeric literals\n****************\n\nThere are four types of numeric literals: plain integers, long\nintegers, floating point numbers, and imaginary numbers. There are no\ncomplex literals (complex numbers can be formed by adding a real\nnumber and an imaginary 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': u'\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.__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 (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression ``x + y``, where *x* is an\n 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__()`` (described below). Note\n that ``__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.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(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 (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [3] For instance, to evaluate\n the expression ``x - y``, where *y* is an instance of a class that\n has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *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.__idiv__(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 operations (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\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 operation falls back to the normal methods. For instance, to\n evaluate the expression ``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.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``long()``, and ``float()``. Should return a value of\n the appropriate type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions ``oct()`` and ``hex()``.\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n New in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or ``None`` if conversion is impossible. When\n the common type would be the type of ``other``, it is sufficient to\n return ``None``, since the interpreter will also ask the other\n object to attempt a coercion (but sometimes, if the implementation\n of the other type cannot be changed, it is useful to do the\n conversion to the other type here). A return value of\n ``NotImplemented`` is equivalent to returning ``None``.\n', - 'objects': u'\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. (Implementation note: the current implementation uses a\nreference-counting scheme with (optional) delayed detection of\ncyclically linked garbage, which collects most objects as soon as they\nbecome unreachable, but is not guaranteed to collect garbage\ncontaining circular references. See the documentation of the ``gc``\nmodule for information on controlling the collection of cyclic\ngarbage.)\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 provides a convenient way to do\nthis.\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': u'\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| ``or`` | Boolean OR |\n+-------------------------------------------------+---------------------------------------+\n| ``and`` | Boolean AND |\n+-------------------------------------------------+---------------------------------------+\n| ``not`` *x* | Boolean NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``in``, ``not`` ``in`` | Membership tests |\n+-------------------------------------------------+---------------------------------------+\n| ``is``, ``is not`` | Identity tests |\n+-------------------------------------------------+---------------------------------------+\n| ``<``, ``<=``, ``>``, ``>=``, ``<>``, ``!=``, | Comparisons |\n| ``==`` | |\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+-------------------------------------------------+---------------------------------------+\n| ``+x``, ``-x`` | Positive, negative |\n+-------------------------------------------------+---------------------------------------+\n| ``~x`` | Bitwise not |\n+-------------------------------------------------+---------------------------------------+\n| ``**`` | Exponentiation |\n+-------------------------------------------------+---------------------------------------+\n| ``x[index]`` | Subscription |\n+-------------------------------------------------+---------------------------------------+\n| ``x[index:index]`` | Slicing |\n+-------------------------------------------------+---------------------------------------+\n| ``x(arguments...)`` | Call |\n+-------------------------------------------------+---------------------------------------+\n| ``x.attribute`` | Attribute reference |\n+-------------------------------------------------+---------------------------------------+\n| ``(expressions...)`` | Binding or tuple display |\n+-------------------------------------------------+---------------------------------------+\n| ``[expressions...]`` | List display |\n+-------------------------------------------------+---------------------------------------+\n| ``{key:datum...}`` | Dictionary display |\n+-------------------------------------------------+---------------------------------------+\n| ```expressions...``` | String conversion |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] In Python 2.3 and later releases, a list comprehension "leaks" the\n control variables of each ``for`` it contains into the containing\n scope. However, this behavior is deprecated, and relying on it\n will not work in Python 3.0\n\n[2] 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[3] If x is very close to an exact integer multiple of y, it\'s\n possible for ``floor(x/y)`` to be one larger than ``(x-x%y)/y``\n due to rounding. In such cases, Python returns the latter result,\n in order to preserve that ``divmod(x,y)[0] * y + x % y`` be very\n close to ``x``.\n\n[4] While comparisons between unicode strings make sense at the byte\n level, they may be counter-intuitive to users. For example, the\n strings ``u"\\u00C7"`` and ``u"\\u0043\\u0327"`` compare differently,\n even though they both represent the same unicode character (LATIN\n CAPTITAL LETTER C WITH CEDILLA). To compare strings in a human\n recognizable way, compare using ``unicodedata.normalize()``.\n\n[5] The implementation computes this efficiently, without constructing\n lists or sorting.\n\n[6] Earlier versions of Python used lexicographic comparison of the\n sorted (key, value) lists, but this was very expensive for the\n common case of comparing for equality. An even earlier version of\n Python compared dictionaries by identity only, but this caused\n surprises because people expected to be able to test a dictionary\n for emptiness by comparing it to ``{}``.\n\n[7] 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', + 'numeric-types': u'\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.__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 (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression ``x + y``, where *x* is an\n 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__()`` (described below). Note\n that ``__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.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(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 (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [3] For instance, to evaluate\n the expression ``x - y``, where *y* is an instance of a class that\n has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *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.__idiv__(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.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``long()``, and ``float()``. Should return a value of\n the appropriate type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions ``oct()`` and ``hex()``.\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n New in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or ``None`` if conversion is impossible. When\n the common type would be the type of ``other``, it is sufficient to\n return ``None``, since the interpreter will also ask the other\n object to attempt a coercion (but sometimes, if the implementation\n of the other type cannot be changed, it is useful to do the\n conversion to the other type here). A return value of\n ``NotImplemented`` is equivalent to returning ``None``.\n', + 'objects': u'\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. (Implementation note: 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 provides a convenient way to do\nthis.\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': u'\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| ``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+-------------------------------------------------+---------------------------------------+\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+-------------------------------------------------+---------------------------------------+\n| ``+x``, ``-x``, ``~x`` | Positive, negative, bitwise NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``**`` | Exponentiation [8] |\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, string |\n| | conversion |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] In Python 2.3 and later releases, a list comprehension "leaks" the\n control variables of each ``for`` it contains into the containing\n scope. However, this behavior is deprecated, and relying on it\n will not work in Python 3.0\n\n[2] 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[3] If x is very close to an exact integer multiple of y, it\'s\n possible for ``floor(x/y)`` to be one larger than ``(x-x%y)/y``\n due to rounding. In such cases, Python returns the latter result,\n in order to preserve that ``divmod(x,y)[0] * y + x % y`` be very\n close to ``x``.\n\n[4] While comparisons between unicode strings make sense at the byte\n level, they may be counter-intuitive to users. For example, the\n strings ``u"\\u00C7"`` and ``u"\\u0043\\u0327"`` compare differently,\n even though they both represent the same unicode character (LATIN\n CAPTITAL LETTER C WITH CEDILLA). To compare strings in a human\n recognizable way, compare using ``unicodedata.normalize()``.\n\n[5] The implementation computes this efficiently, without constructing\n lists or sorting.\n\n[6] Earlier versions of Python used lexicographic comparison of the\n sorted (key, value) lists, but this was very expensive for the\n common case of comparing for equality. An even earlier version of\n Python compared dictionaries by identity only, but this caused\n surprises because people expected to be able to test a dictionary\n for emptiness by comparing it to ``{}``.\n\n[7] 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[8] 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': u'\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': u'\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. The result type is that of the\narguments after coercion.\n\nWith mixed operand types, the coercion rules for binary arithmetic\noperators apply. For int and long int operands, the result has the\nsame type as the operands (after coercion) unless the second argument\nis negative; in that case, all arguments are converted to float and a\nfloat result is delivered. For example, ``10**2`` returns ``100``, but\n``10**-2`` returns ``0.01``. (This last feature was added in Python\n2.2. In Python 2.1 and before, if both arguments were of integer types\nand the second argument was negative, an exception was raised).\n\nRaising ``0.0`` to a negative power results in a\n``ZeroDivisionError``. Raising a negative number to a fractional power\nresults in a ``ValueError``.\n', 'print': u'\nThe ``print`` statement\n***********************\n\n print_stmt ::= "print" ([expression ("," expression)* [","]]\n | ">>" expression [("," expression)+ [","]])\n\n``print`` evaluates each expression in turn and writes the resulting\nobject to standard output (see below). If an object is not a string,\nit is first converted to a string using the rules for string\nconversions. The (resulting or original) string is then written. A\nspace is written before each object is (converted and) written, unless\nthe output system believes it is positioned at the beginning of a\nline. This is the case (1) when no characters have yet been written\nto standard output, (2) when the last character written to standard\noutput is ``\'\\n\'``, or (3) when the last write operation on standard\noutput was not a ``print`` statement. (In some cases it may be\nfunctional to write an empty string to standard output for this\nreason.)\n\nNote: Objects which act like file objects but which are not the built-in\n file objects often do not properly emulate this aspect of the file\n object\'s behavior, so it is best not to rely on this.\n\nA ``\'\\n\'`` character is written at the end, unless the ``print``\nstatement ends with a comma. This is the only action if the statement\ncontains just the keyword ``print``.\n\nStandard output is defined as the file object named ``stdout`` in the\nbuilt-in module ``sys``. If no such object exists, or if it does not\nhave a ``write()`` method, a ``RuntimeError`` exception is raised.\n\n``print`` also has an extended form, defined by the second portion of\nthe syntax described above. This form is sometimes referred to as\n"``print`` chevron." In this form, the first expression after the\n``>>`` must evaluate to a "file-like" object, specifically an object\nthat has a ``write()`` method as described above. With this extended\nform, the subsequent expressions are printed to this file object. If\nthe first expression evaluates to ``None``, then ``sys.stdout`` is\nused as the file for output.\n', @@ -62,22 +62,22 @@ 'sequence-types': u"\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. (For backwards compatibility, the method\n``__getslice__()`` (see below) can also be defined to handle simple,\nbut not extended slices.) It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``has_key()``,\n``get()``, ``clear()``, ``setdefault()``, ``iterkeys()``,\n``itervalues()``, ``iteritems()``, ``pop()``, ``popitem()``,\n``copy()``, and ``update()`` behaving similar to those for Python's\nstandard dictionary objects. The ``UserDict`` module provides a\n``DictMixin`` class to help create those methods from a base set of\n``__getitem__()``, ``__setitem__()``, ``__delitem__()``, and\n``keys()``. Mutable sequences should provide methods ``append()``,\n``count()``, ``index()``, ``extend()``, ``insert()``, ``pop()``,\n``remove()``, ``reverse()`` and ``sort()``, like Python standard list\nobjects. Finally, sequence types should implement addition (meaning\nconcatenation) and multiplication (meaning repetition) by defining the\nmethods ``__add__()``, ``__radd__()``, ``__iadd__()``, ``__mul__()``,\n``__rmul__()`` and ``__imul__()`` described below; they should not\ndefine ``__coerce__()`` or other numerical operators. It is\nrecommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should be equivalent of ``has_key()``;\nfor sequences, 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``iterkeys()``; 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 ``__nonzero__()`` method and whose\n ``__len__()`` method returns zero is considered to be false in a\n Boolean context.\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 ``iterkeys()``.\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()`` builtin 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()`` builtin will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects should\n normally only provide ``__reversed__()`` if they do not support the\n sequence protocol and an efficient implementation of reverse\n iteration is possible.\n\n New in version 2.6.\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", 'shifting': u'\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 plain or long integers as arguments. The\narguments are converted to a common type. 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,\nn)``. Negative shift counts raise a ``ValueError`` exception.\n', 'slicings': u'\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 ::= simple_slicing | extended_slicing\n simple_slicing ::= primary "[" short_slice "]"\n extended_slicing ::= primary "[" slice_list "]"\n slice_list ::= slice_item ("," slice_item)* [","]\n slice_item ::= expression | proper_slice | ellipsis\n proper_slice ::= short_slice | long_slice\n short_slice ::= [lower_bound] ":" [upper_bound]\n long_slice ::= short_slice ":" [stride]\n lower_bound ::= expression\n upper_bound ::= expression\n stride ::= expression\n ellipsis ::= "..."\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 nor ellipses). Similarly, when the slice\nlist has exactly one short slice and no trailing comma, the\ninterpretation as a simple slicing takes priority over that as an\nextended slicing.\n\nThe semantics for a simple slicing are as follows. The primary must\nevaluate to a sequence object. The lower and upper bound expressions,\nif present, must evaluate to plain integers; defaults are zero and the\n``sys.maxint``, respectively. If either bound is negative, the\nsequence\'s length is added to it. The slicing now selects all items\nwith index *k* such that ``i <= k < j`` where *i* and *j* are the\nspecified lower and upper bounds. This may be an empty sequence. It\nis not an error if *i* or *j* lie outside the range of valid indexes\n(such items don\'t exist so they aren\'t selected).\n\nThe semantics for an extended slicing are as follows. The primary\nmust evaluate to a mapping object, and it is indexed with a key that\nis constructed 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 an ellipsis slice\nitem is the built-in ``Ellipsis`` object. The conversion of a proper\nslice is a slice object (see section *The standard type hierarchy*)\nwhose ``start``, ``stop`` and ``step`` attributes are the values of\nthe expressions given as lower bound, upper bound and stride,\nrespectively, substituting ``None`` for missing expressions.\n', - 'specialattrs': u"\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\nobject.__methods__\n\n Deprecated since version 2.2: Use the built-in function ``dir()``\n to get a list of an object's attributes. This attribute is no\n longer available.\n\nobject.__members__\n\n Deprecated since version 2.2: Use the built-in function ``dir()``\n to get a list of an object's attributes. This attribute is no\n longer available.\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. If there are no base\n classes, this will be an empty tuple.\n\nclass.__name__\n\n The name of the class or type.\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\n[5] These numbers are fairly arbitrary. They are intended to avoid\n printing endless strings of meaningless digits without hampering\n correct use and without having to know the exact precision of\n floating point values on a particular machine.\n\n[6] The advantage of leaving the newline on is that returning an empty\n string is then an unambiguous EOF indication. It is also possible\n (in cases where it might matter, for example, if you want to make\n an exact copy of a file while scanning its lines) to tell whether\n the last line of a file ended in a newline or not (yes this\n happens!).\n", - 'specialnames': u'\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 ``x.__getitem__(i)`` for\nold-style classes and ``type(x).__getitem__(x, i)`` for new-style\nclasses. Except where mentioned, attempts to execute an operation\nraise an 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_traceback`` 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.exc_traceback`` or ``sys.last_traceback``. Circular\n references which are garbage are detected when the option cycle\n detector is enabled (it\'s on by default), but can only be cleaned\n up if there are no Python-level ``__del__()`` methods involved.\n Refer to the documentation for the ``gc`` module for more\n information about how ``__del__()`` methods are handled by the\n cycle detector, particularly the description of the ``garbage``\n 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. For this reason, ``__del__()`` methods should do\n the absolute minimum needed to maintain external invariants.\n Starting with version 1.5, Python guarantees that globals whose\n name begins with a single underscore are deleted from their\n module before other globals are deleted; if no other references\n to such globals exist, this may help in assuring that imported\n modules are still available at the time when the ``__del__()``\n method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is 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 statement 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.__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 New in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` call ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and\n ``x>=y`` calls ``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\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by ``__cmp__()`` has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\n\nobject.__hash__(self)\n\n Called for the key object for dictionary operations, and by the\n built-in function ``hash()``. Should return an integer usable as a\n hash value for dictionary operations. The only required property\n is that objects which compare equal have the same hash value; it is\n advised to somehow mix together (e.g., using exclusive or) the hash\n values for the components of the object that also play a part in\n comparison of objects.\n\n If a class does not define a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable as dictionary keys. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n the dictionary implementation requires that a key\'s hash value is\n immutable (if the object\'s hash value changes, it will be in the\n wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` 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 ``__cmp__()`` or ``__eq__()`` such that\n the hash value returned is no longer appropriate (e.g. by switching\n to a value-based concept of equality instead of the default\n identity based equality) can explicitly flag themselves as being\n unhashable by setting ``__hash__ = None`` in the class definition.\n Doing so means that not only will instances of the class raise an\n appropriate ``TypeError`` when a program attempts to retrieve their\n hash value, but they will also be correctly identified as\n unhashable when checking ``isinstance(obj, collections.Hashable)``\n (unlike classes which define their own ``__hash__()`` to explicitly\n raise ``TypeError``).\n\n Changed in version 2.5: ``__hash__()`` may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\n Changed in version 2.6: ``__hash__`` may now be set to ``None`` to\n explicitly flag instances of a class as unhashable.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing, and the built-in operation\n ``bool()``; should return ``False`` or ``True``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined (see below). If a class\n defines neither ``__len__()`` nor ``__nonzero__()``, all its\n instances are considered true.\n\nobject.__unicode__(self)\n\n Called to implement ``unicode()`` builtin; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\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 in new-style classes.\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 not simply execute ``self.name = value`` --- this would\n cause a recursive call to itself. Instead, it should insert the\n value in the dictionary of instance attributes, e.g.,\n ``self.__dict__[name] = value``. For new-style classes, rather\n than accessing the instance dictionary, it should call the base\n 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\n\nMore attribute access for new-style classes\n-------------------------------------------\n\nThe following methods only apply to new-style classes.\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 builtin functions. See *Special method lookup for new-style\n classes*.\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 new-style class, known as the *owner*\nclass. In the examples below, "the attribute" refers to the attribute\nwhose name is the key of the property in the owner class\'\n``__dict__``. Descriptors can only be implemented as new-style\nclasses themselves.\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. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass ``object()`` or\n``type()``).\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 a new-style object instance, ``a.x`` is transformed\n into the call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a new-style class, ``A.x`` is transformed into the\n call: ``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. Normally, data\ndescriptors define both ``__get__()`` and ``__set__()``, while non-\ndata descriptors have just the ``__get__()`` method. Data descriptors\nalways override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances. [2]\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 both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__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 new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n New in version 2.2.\n\nNotes on using *__slots__*\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 Changed in version 2.3: Previously, adding ``\'__dict__\'`` to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\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 Changed in version 2.3: Previously, adding ``\'__weakref__\'`` to the\n *__slots__* declaration would not enable support for weak\n references.\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* 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* 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__*.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as ``long``, ``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 Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, new-style classes are constructed using ``type()``. A\nclass definition is read into a separate namespace and the value of\nclass name is bound to the result of ``type(name, bases, dict)``.\n\nWhen the class definition is read, if *__metaclass__* is defined then\nthe callable assigned to it will be called instead of ``type()``. 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\n__metaclass__\n\n This variable can be any callable accepting arguments for ``name``,\n ``bases``, and ``dict``. Upon class creation, the callable is used\n instead of the built-in ``type()``.\n\n New in version 2.2.\n\nThe appropriate metaclass is determined by the following precedence\nrules:\n\n* If ``dict[\'__metaclass__\']`` exists, it is used.\n\n* Otherwise, if there is at least one base class, its metaclass is\n used (this looks for a *__class__* attribute first and if not found,\n uses its type).\n\n* Otherwise, if a global variable named __metaclass__ exists, it is\n used.\n\n* Otherwise, the old-style, classic metaclass (types.ClassType) is\n 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\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. (For backwards compatibility, the method\n``__getslice__()`` (see below) can also be defined to handle simple,\nbut not extended slices.) It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``has_key()``,\n``get()``, ``clear()``, ``setdefault()``, ``iterkeys()``,\n``itervalues()``, ``iteritems()``, ``pop()``, ``popitem()``,\n``copy()``, and ``update()`` behaving similar to those for Python\'s\nstandard dictionary objects. The ``UserDict`` module provides a\n``DictMixin`` class to help create those methods from a base set of\n``__getitem__()``, ``__setitem__()``, ``__delitem__()``, and\n``keys()``. Mutable sequences should provide methods ``append()``,\n``count()``, ``index()``, ``extend()``, ``insert()``, ``pop()``,\n``remove()``, ``reverse()`` and ``sort()``, like Python standard list\nobjects. Finally, sequence types should implement addition (meaning\nconcatenation) and multiplication (meaning repetition) by defining the\nmethods ``__add__()``, ``__radd__()``, ``__iadd__()``, ``__mul__()``,\n``__rmul__()`` and ``__imul__()`` described below; they should not\ndefine ``__coerce__()`` or other numerical operators. It is\nrecommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should be equivalent of ``has_key()``;\nfor sequences, 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``iterkeys()``; 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 ``__nonzero__()`` method and whose\n ``__len__()`` method returns zero is considered to be false in a\n Boolean context.\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 ``iterkeys()``.\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()`` builtin 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()`` builtin will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects should\n normally only provide ``__reversed__()`` if they do not support the\n sequence protocol and an efficient implementation of reverse\n iteration is possible.\n\n New in version 2.6.\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\nAdditional methods for emulation of sequence types\n==================================================\n\nThe following optional methods can be defined to further emulate\nsequence objects. Immutable sequences methods should at most only\ndefine ``__getslice__()``; mutable sequences might define all three\nmethods.\n\nobject.__getslice__(self, i, j)\n\n Deprecated since version 2.0: Support slice objects as parameters\n to the ``__getitem__()`` method. (However, built-in types in\n CPython currently still implement ``__getslice__()``. Therefore,\n you have to override it in derived classes when implementing\n slicing.)\n\n Called to implement evaluation of ``self[i:j]``. The returned\n object should be of the same type as *self*. Note that missing *i*\n or *j* in the slice expression are replaced by zero or\n ``sys.maxint``, respectively. If negative indexes are used in the\n slice, the length of the sequence is added to that index. If the\n instance does not implement the ``__len__()`` method, an\n ``AttributeError`` is raised. No guarantee is made that indexes\n adjusted this way are not still negative. Indexes which are\n greater than the length of the sequence are not modified. If no\n ``__getslice__()`` is found, a slice object is created instead, and\n passed to ``__getitem__()`` instead.\n\nobject.__setslice__(self, i, j, sequence)\n\n Called to implement assignment to ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``.\n\n This method is deprecated. If no ``__setslice__()`` is found, or\n for extended slicing of the form ``self[i:j:k]``, a slice object is\n created, and passed to ``__setitem__()``, instead of\n ``__setslice__()`` being called.\n\nobject.__delslice__(self, i, j)\n\n Called to implement deletion of ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``. This method is deprecated. If no\n ``__delslice__()`` is found, or for extended slicing of the form\n ``self[i:j:k]``, a slice object is created, and passed to\n ``__delitem__()``, instead of ``__delslice__()`` being called.\n\nNotice that these methods are only invoked when a single slice with a\nsingle colon is used, and the slice method is available. For slice\noperations involving extended slice notation, or in absence of the\nslice methods, ``__getitem__()``, ``__setitem__()`` or\n``__delitem__()`` is called with a slice object as argument.\n\nThe following example demonstrate how to make your program or module\ncompatible with earlier versions of Python (assuming that methods\n``__getitem__()``, ``__setitem__()`` and ``__delitem__()`` support\nslice objects as arguments):\n\n class MyClass:\n ...\n def __getitem__(self, index):\n ...\n def __setitem__(self, index, value):\n ...\n def __delitem__(self, index):\n ...\n\n if sys.version_info < (2, 0):\n # They won\'t be defined if version is at least 2.0 final\n\n def __getslice__(self, i, j):\n return self[max(0, i):max(0, j):]\n def __setslice__(self, i, j, seq):\n self[max(0, i):max(0, j):] = seq\n def __delslice__(self, i, j):\n del self[max(0, i):max(0, j):]\n ...\n\nNote the calls to ``max()``; these are necessary because of the\nhandling of negative indices before the ``__*slice__()`` methods are\ncalled. When negative indexes are used, the ``__*item__()`` methods\nreceive them as provided, but the ``__*slice__()`` methods get a\n"cooked" form of the index values. For each negative index value, the\nlength of the sequence is added to the index before calling the method\n(which may still result in a negative index); this is the customary\nhandling of negative indexes by the built-in sequence types, and the\n``__*item__()`` methods are expected to do this as well. However,\nsince they should already be doing that, negative indexes cannot be\npassed in; they must be constrained to the bounds of the sequence\nbefore being passed to the ``__*item__()`` methods. Calling ``max(0,\ni)`` conveniently returns the proper value.\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.__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 (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression ``x + y``, where *x* is an\n 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__()`` (described below). Note\n that ``__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.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(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 (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [3] For instance, to evaluate\n the expression ``x - y``, where *y* is an instance of a class that\n has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *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.__idiv__(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 operations (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\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 operation falls back to the normal methods. For instance, to\n evaluate the expression ``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.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``long()``, and ``float()``. Should return a value of\n the appropriate type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions ``oct()`` and ``hex()``.\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n New in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or ``None`` if conversion is impossible. When\n the common type would be the type of ``other``, it is sufficient to\n return ``None``, since the interpreter will also ask the other\n object to attempt a coercion (but sometimes, if the implementation\n of the other type cannot be changed, it is useful to do the\n conversion to the other type here). A return value of\n ``NotImplemented`` is equivalent to returning ``None``.\n\n\nCoercion rules\n==============\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3.0, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don\'t define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from ``object``) never invoke the\n ``__coerce__()`` method in response to a binary operator; the only\n time ``__coerce__()`` is invoked is when the built-in function\n ``coerce()`` is called.\n\n* For most intents and purposes, an operator that returns\n ``NotImplemented`` is treated the same as one that is not\n implemented at all.\n\n* Below, ``__op__()`` and ``__rop__()`` are used to signify the\n generic method names corresponding to an operator; ``__iop__()`` is\n used for the corresponding in-place operator. For example, for the\n operator \'``+``\', ``__add__()`` and ``__radd__()`` are used for the\n left and right variant of the binary operator, and ``__iadd__()``\n for the in-place variant.\n\n* For objects *x* and *y*, first ``x.__op__(y)`` is tried. If this is\n not implemented or returns ``NotImplemented``, ``y.__rop__(x)`` is\n tried. If this is also not implemented or returns\n ``NotImplemented``, a ``TypeError`` exception is raised. But see\n the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base\'s ``__rop__()`` method, the right operand\'s ``__rop__()``\n method is tried *before* the left operand\'s ``__op__()`` method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand\'s ``__op__()`` method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is called\n before that type\'s ``__op__()`` or ``__rop__()`` method is called,\n but no sooner. If the coercion returns an object of a different\n type for the operand whose coercion is invoked, part of the process\n is redone using the new object.\n\n* When an in-place operator (like \'``+=``\') is used, if the left\n operand implements ``__iop__()``, it is invoked without any\n coercion. When the operation falls back to ``__op__()`` and/or\n ``__rop__()``, the normal coercion rules apply.\n\n* In ``x + y``, if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In ``x * y``, if one operator is a sequence that implements sequence\n repetition, and the other is an integer (``int`` or ``long``),\n sequence repetition is invoked.\n\n* Rich comparisons (implemented by methods ``__eq__()`` and so on)\n never use coercion. Three-way comparison (implemented by\n ``__cmp__()``) does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types ``int``,\n ``long`` and ``float`` do not use coercion; the type ``complex``\n however does use it. The difference can become apparent when\n subclassing these types. Over time, the type ``complex`` may be\n fixed to avoid coercion. All these types implement a\n ``__coerce__()`` method, for use by the built-in ``coerce()``\n function.\n\n\nWith Statement Context Managers\n===============================\n\nNew in version 2.5.\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 for old-style classes\n===========================================\n\nFor old-style classes, special methods are always looked up in exactly\nthe same way as any other method or attribute. This is the case\nregardless of whether the method is being looked up explicitly as in\n``x.__getitem__(i)`` or implicitly as in ``x[i]``.\n\nThis behaviour means that special methods may exhibit different\nbehaviour for different instances of a single old-style class if the\nappropriate special attributes are set differently:\n\n >>> class C:\n ... pass\n ...\n >>> c1 = C()\n >>> c2 = C()\n >>> c1.__len__ = lambda: 5\n >>> c2.__len__ = lambda: 9\n >>> len(c1)\n 5\n >>> len(c2)\n 9\n\n\nSpecial method lookup for new-style classes\n===========================================\n\nFor new-style classes, implicit invocations of special methods are\nonly guaranteed to work correctly if defined on an object\'s type, not\nin the object\'s instance dictionary. That behaviour is the reason why\nthe following code raises an exception (unlike the equivalent example\nwith old-style classes):\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 may also bypass the\n``__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):\n ... __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] A descriptor can define any combination of ``__get__()``,\n ``__set__()`` and ``__delete__()``. If it does not define\n ``__get__()``, then accessing the attribute even on an instance\n will return the descriptor object itself. If the descriptor\n defines ``__set__()`` and/or ``__delete__()``, it is a data\n descriptor; if it defines neither, it is a non-data descriptor.\n\n[3] 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', + 'specialattrs': u"\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\nobject.__methods__\n\n Deprecated since version 2.2: Use the built-in function ``dir()``\n to get a list of an object's attributes. This attribute is no\n longer available.\n\nobject.__members__\n\n Deprecated since version 2.2: Use the built-in function ``dir()``\n to get a list of an object's attributes. This attribute is no\n longer available.\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. If there are no base\n classes, this will be an empty tuple.\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\n[5] These numbers are fairly arbitrary. They are intended to avoid\n printing endless strings of meaningless digits without hampering\n correct use and without having to know the exact precision of\n floating point values on a particular machine.\n\n[6] The advantage of leaving the newline on is that returning an empty\n string is then an unambiguous EOF indication. It is also possible\n (in cases where it might matter, for example, if you want to make\n an exact copy of a file while scanning its lines) to tell whether\n the last line of a file ended in a newline or not (yes this\n happens!).\n", + 'specialnames': u'\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 ``x.__getitem__(i)`` for\nold-style classes and ``type(x).__getitem__(x, i)`` for new-style\nclasses. Except where mentioned, attempts to execute an operation\nraise an 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_traceback`` 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.exc_traceback`` or ``sys.last_traceback``. Circular\n references which are garbage are detected when the option cycle\n detector is enabled (it\'s on by default), but can only be cleaned\n up if there are no Python-level ``__del__()`` methods involved.\n Refer to the documentation for the ``gc`` module for more\n information about how ``__del__()`` methods are handled by the\n cycle detector, particularly the description of the ``garbage``\n 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 and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is 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 statement 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.__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 New in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` call ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and\n ``x>=y`` calls ``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\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by ``__cmp__()`` has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\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 a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable in hashed collections. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n hashable collection implementations require that a object\'s hash\n value is immutable (if the object\'s hash value changes, it will be\n in the wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` 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 ``__cmp__()`` or ``__eq__()`` such that\n the hash value returned is no longer appropriate (e.g. by switching\n to a value-based concept of equality instead of the default\n identity based equality) can explicitly flag themselves as being\n unhashable by setting ``__hash__ = None`` in the class definition.\n Doing so means that not only will instances of the class raise an\n appropriate ``TypeError`` when a program attempts to retrieve their\n hash value, but they will also be correctly identified as\n unhashable when checking ``isinstance(obj, collections.Hashable)``\n (unlike classes which define their own ``__hash__()`` to explicitly\n raise ``TypeError``).\n\n Changed in version 2.5: ``__hash__()`` may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\n Changed in version 2.6: ``__hash__`` may now be set to ``None`` to\n explicitly flag instances of a class as unhashable.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing and the built-in operation\n ``bool()``; should return ``False`` or ``True``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined, and the object is\n considered true if its result is nonzero. If a class defines\n neither ``__len__()`` nor ``__nonzero__()``, all its instances are\n considered true.\n\nobject.__unicode__(self)\n\n Called to implement ``unicode()`` builtin; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\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 in new-style classes.\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 not simply execute ``self.name = value`` --- this would\n cause a recursive call to itself. Instead, it should insert the\n value in the dictionary of instance attributes, e.g.,\n ``self.__dict__[name] = value``. For new-style classes, rather\n than accessing the instance dictionary, it should call the base\n 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\n\nMore attribute access for new-style classes\n-------------------------------------------\n\nThe following methods only apply to new-style classes.\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 builtin functions. See *Special method lookup for new-style\n classes*.\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 new-style class, known as the *owner*\nclass. In the examples below, "the attribute" refers to the attribute\nwhose name is the key of the property in the owner class\'\n``__dict__``. Descriptors can only be implemented as new-style\nclasses themselves.\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. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass ``object()`` or\n``type()``).\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 a new-style object instance, ``a.x`` is transformed\n into the call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a new-style class, ``A.x`` is transformed into the\n call: ``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. Normally, data\ndescriptors define both ``__get__()`` and ``__set__()``, while non-\ndata descriptors have just the ``__get__()`` method. Data descriptors\nalways override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances. [2]\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 both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__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 new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n New in version 2.2.\n\nNotes on using *__slots__*\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 Changed in version 2.3: Previously, adding ``\'__dict__\'`` to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\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 Changed in version 2.3: Previously, adding ``\'__weakref__\'`` to the\n *__slots__* declaration would not enable support for weak\n references.\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* 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* 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__*.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as ``long``, ``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 Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, new-style classes are constructed using ``type()``. A\nclass definition is read into a separate namespace and the value of\nclass name is bound to the result of ``type(name, bases, dict)``.\n\nWhen the class definition is read, if *__metaclass__* is defined then\nthe callable assigned to it will be called instead of ``type()``. 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\n__metaclass__\n\n This variable can be any callable accepting arguments for ``name``,\n ``bases``, and ``dict``. Upon class creation, the callable is used\n instead of the built-in ``type()``.\n\n New in version 2.2.\n\nThe appropriate metaclass is determined by the following precedence\nrules:\n\n* If ``dict[\'__metaclass__\']`` exists, it is used.\n\n* Otherwise, if there is at least one base class, its metaclass is\n used (this looks for a *__class__* attribute first and if not found,\n uses its type).\n\n* Otherwise, if a global variable named __metaclass__ exists, it is\n used.\n\n* Otherwise, the old-style, classic metaclass (types.ClassType) is\n 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\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. (For backwards compatibility, the method\n``__getslice__()`` (see below) can also be defined to handle simple,\nbut not extended slices.) It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``has_key()``,\n``get()``, ``clear()``, ``setdefault()``, ``iterkeys()``,\n``itervalues()``, ``iteritems()``, ``pop()``, ``popitem()``,\n``copy()``, and ``update()`` behaving similar to those for Python\'s\nstandard dictionary objects. The ``UserDict`` module provides a\n``DictMixin`` class to help create those methods from a base set of\n``__getitem__()``, ``__setitem__()``, ``__delitem__()``, and\n``keys()``. Mutable sequences should provide methods ``append()``,\n``count()``, ``index()``, ``extend()``, ``insert()``, ``pop()``,\n``remove()``, ``reverse()`` and ``sort()``, like Python standard list\nobjects. Finally, sequence types should implement addition (meaning\nconcatenation) and multiplication (meaning repetition) by defining the\nmethods ``__add__()``, ``__radd__()``, ``__iadd__()``, ``__mul__()``,\n``__rmul__()`` and ``__imul__()`` described below; they should not\ndefine ``__coerce__()`` or other numerical operators. It is\nrecommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should be equivalent of ``has_key()``;\nfor sequences, 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``iterkeys()``; 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 ``__nonzero__()`` method and whose\n ``__len__()`` method returns zero is considered to be false in a\n Boolean context.\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 ``iterkeys()``.\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()`` builtin 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()`` builtin will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects should\n normally only provide ``__reversed__()`` if they do not support the\n sequence protocol and an efficient implementation of reverse\n iteration is possible.\n\n New in version 2.6.\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\nAdditional methods for emulation of sequence types\n==================================================\n\nThe following optional methods can be defined to further emulate\nsequence objects. Immutable sequences methods should at most only\ndefine ``__getslice__()``; mutable sequences might define all three\nmethods.\n\nobject.__getslice__(self, i, j)\n\n Deprecated since version 2.0: Support slice objects as parameters\n to the ``__getitem__()`` method. (However, built-in types in\n CPython currently still implement ``__getslice__()``. Therefore,\n you have to override it in derived classes when implementing\n slicing.)\n\n Called to implement evaluation of ``self[i:j]``. The returned\n object should be of the same type as *self*. Note that missing *i*\n or *j* in the slice expression are replaced by zero or\n ``sys.maxint``, respectively. If negative indexes are used in the\n slice, the length of the sequence is added to that index. If the\n instance does not implement the ``__len__()`` method, an\n ``AttributeError`` is raised. No guarantee is made that indexes\n adjusted this way are not still negative. Indexes which are\n greater than the length of the sequence are not modified. If no\n ``__getslice__()`` is found, a slice object is created instead, and\n passed to ``__getitem__()`` instead.\n\nobject.__setslice__(self, i, j, sequence)\n\n Called to implement assignment to ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``.\n\n This method is deprecated. If no ``__setslice__()`` is found, or\n for extended slicing of the form ``self[i:j:k]``, a slice object is\n created, and passed to ``__setitem__()``, instead of\n ``__setslice__()`` being called.\n\nobject.__delslice__(self, i, j)\n\n Called to implement deletion of ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``. This method is deprecated. If no\n ``__delslice__()`` is found, or for extended slicing of the form\n ``self[i:j:k]``, a slice object is created, and passed to\n ``__delitem__()``, instead of ``__delslice__()`` being called.\n\nNotice that these methods are only invoked when a single slice with a\nsingle colon is used, and the slice method is available. For slice\noperations involving extended slice notation, or in absence of the\nslice methods, ``__getitem__()``, ``__setitem__()`` or\n``__delitem__()`` is called with a slice object as argument.\n\nThe following example demonstrate how to make your program or module\ncompatible with earlier versions of Python (assuming that methods\n``__getitem__()``, ``__setitem__()`` and ``__delitem__()`` support\nslice objects as arguments):\n\n class MyClass:\n ...\n def __getitem__(self, index):\n ...\n def __setitem__(self, index, value):\n ...\n def __delitem__(self, index):\n ...\n\n if sys.version_info < (2, 0):\n # They won\'t be defined if version is at least 2.0 final\n\n def __getslice__(self, i, j):\n return self[max(0, i):max(0, j):]\n def __setslice__(self, i, j, seq):\n self[max(0, i):max(0, j):] = seq\n def __delslice__(self, i, j):\n del self[max(0, i):max(0, j):]\n ...\n\nNote the calls to ``max()``; these are necessary because of the\nhandling of negative indices before the ``__*slice__()`` methods are\ncalled. When negative indexes are used, the ``__*item__()`` methods\nreceive them as provided, but the ``__*slice__()`` methods get a\n"cooked" form of the index values. For each negative index value, the\nlength of the sequence is added to the index before calling the method\n(which may still result in a negative index); this is the customary\nhandling of negative indexes by the built-in sequence types, and the\n``__*item__()`` methods are expected to do this as well. However,\nsince they should already be doing that, negative indexes cannot be\npassed in; they must be constrained to the bounds of the sequence\nbefore being passed to the ``__*item__()`` methods. Calling ``max(0,\ni)`` conveniently returns the proper value.\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.__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 (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression ``x + y``, where *x* is an\n 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__()`` (described below). Note\n that ``__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.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(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 (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [3] For instance, to evaluate\n the expression ``x - y``, where *y* is an instance of a class that\n has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *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.__idiv__(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.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``long()``, and ``float()``. Should return a value of\n the appropriate type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions ``oct()`` and ``hex()``.\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n New in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or ``None`` if conversion is impossible. When\n the common type would be the type of ``other``, it is sufficient to\n return ``None``, since the interpreter will also ask the other\n object to attempt a coercion (but sometimes, if the implementation\n of the other type cannot be changed, it is useful to do the\n conversion to the other type here). A return value of\n ``NotImplemented`` is equivalent to returning ``None``.\n\n\nCoercion rules\n==============\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3.0, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don\'t define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from ``object``) never invoke the\n ``__coerce__()`` method in response to a binary operator; the only\n time ``__coerce__()`` is invoked is when the built-in function\n ``coerce()`` is called.\n\n* For most intents and purposes, an operator that returns\n ``NotImplemented`` is treated the same as one that is not\n implemented at all.\n\n* Below, ``__op__()`` and ``__rop__()`` are used to signify the\n generic method names corresponding to an operator; ``__iop__()`` is\n used for the corresponding in-place operator. For example, for the\n operator \'``+``\', ``__add__()`` and ``__radd__()`` are used for the\n left and right variant of the binary operator, and ``__iadd__()``\n for the in-place variant.\n\n* For objects *x* and *y*, first ``x.__op__(y)`` is tried. If this is\n not implemented or returns ``NotImplemented``, ``y.__rop__(x)`` is\n tried. If this is also not implemented or returns\n ``NotImplemented``, a ``TypeError`` exception is raised. But see\n the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base\'s ``__rop__()`` method, the right operand\'s ``__rop__()``\n method is tried *before* the left operand\'s ``__op__()`` method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand\'s ``__op__()`` method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is called\n before that type\'s ``__op__()`` or ``__rop__()`` method is called,\n but no sooner. If the coercion returns an object of a different\n type for the operand whose coercion is invoked, part of the process\n is redone using the new object.\n\n* When an in-place operator (like \'``+=``\') is used, if the left\n operand implements ``__iop__()``, it is invoked without any\n coercion. When the operation falls back to ``__op__()`` and/or\n ``__rop__()``, the normal coercion rules apply.\n\n* In ``x + y``, if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In ``x * y``, if one operator is a sequence that implements sequence\n repetition, and the other is an integer (``int`` or ``long``),\n sequence repetition is invoked.\n\n* Rich comparisons (implemented by methods ``__eq__()`` and so on)\n never use coercion. Three-way comparison (implemented by\n ``__cmp__()``) does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types ``int``,\n ``long`` and ``float`` do not use coercion; the type ``complex``\n however does use coercion for binary operators and rich comparisons,\n despite the above rules. The difference can become apparent when\n subclassing these types. Over time, the type ``complex`` may be\n fixed to avoid coercion. All these types implement a\n ``__coerce__()`` method, for use by the built-in ``coerce()``\n function.\n\n\nWith Statement Context Managers\n===============================\n\nNew in version 2.5.\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 for old-style classes\n===========================================\n\nFor old-style classes, special methods are always looked up in exactly\nthe same way as any other method or attribute. This is the case\nregardless of whether the method is being looked up explicitly as in\n``x.__getitem__(i)`` or implicitly as in ``x[i]``.\n\nThis behaviour means that special methods may exhibit different\nbehaviour for different instances of a single old-style class if the\nappropriate special attributes are set differently:\n\n >>> class C:\n ... pass\n ...\n >>> c1 = C()\n >>> c2 = C()\n >>> c1.__len__ = lambda: 5\n >>> c2.__len__ = lambda: 9\n >>> len(c1)\n 5\n >>> len(c2)\n 9\n\n\nSpecial method lookup for new-style classes\n===========================================\n\nFor new-style classes, implicit invocations of special methods are\nonly guaranteed to work correctly if defined on an object\'s type, not\nin the object\'s instance dictionary. That behaviour is the reason why\nthe following code raises an exception (unlike the equivalent example\nwith old-style classes):\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):\n ... __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] A descriptor can define any combination of ``__get__()``,\n ``__set__()`` and ``__delete__()``. If it does not define\n ``__get__()``, then accessing the attribute even on an instance\n will return the descriptor object itself. If the descriptor\n defines ``__set__()`` and/or ``__delete__()``, it is a data\n descriptor; if it defines neither, it is a non-data descriptor.\n\n[3] 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-conversions': u'\nString conversions\n******************\n\nA string conversion is an expression list enclosed in reverse (a.k.a.\nbackward) quotes:\n\n string_conversion ::= "\'" expression_list "\'"\n\nA string conversion evaluates the contained expression list and\nconverts the resulting object into a string according to rules\nspecific to its type.\n\nIf the object is a string, a number, ``None``, or a tuple, list or\ndictionary containing only objects whose type is one of these, the\nresulting string is a valid Python expression which can be passed to\nthe built-in function ``eval()`` to yield an expression with the same\nvalue (or an approximation, if floating point numbers are involved).\n\n(In particular, converting a string adds quotes around it and converts\n"funny" characters to escape sequences that are safe to print.)\n\nRecursive objects (for example, lists or dictionaries that contain a\nreference to themselves, directly or indirectly) use ``...`` to\nindicate a recursive reference, and the result cannot be passed to\n``eval()`` to get an equal value (``SyntaxError`` will be raised\ninstead).\n\nThe built-in function ``repr()`` performs exactly the same conversion\nin its argument as enclosing it in parentheses and reverse quotes\ndoes. The built-in function ``str()`` performs a similar but more\nuser-friendly conversion.\n', - 'string-methods': u'\nString Methods\n**************\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Note that none of these methods take keyword\narguments.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbuffer, xrange* section. To output formatted strings use template\nstrings or the ``%`` operator described in the *String Formatting\nOperations* 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 only its first character\n capitalized.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of occurrences of substring *sub* in the range\n [*start*, *end*]. Optional arguments *start* and *end* are\n interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes 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\n Changed in version 2.5: Accept tuples as *suffix*.\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 range [*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(format_string, *args, **kwargs)\n\n Perform a string formatting operation. The *format_string*\n argument can contain literal text or replacement fields delimited\n by braces ``{}``. Each replacement field contains either the\n numeric index of a positional argument, or the name of a keyword\n argument. Returns a copy of *format_string* where each replacement\n field is replaced with the string value of the corresponding\n 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\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(seq)\n\n Return a string which is the concatenation of the strings in the\n sequence *seq*. The separator between elements is the string\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n New in version 2.5.\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]. Optional\n arguments *start* and *end* are interpreted as in slice notation.\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\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\n New in version 2.5.\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\n New in version 2.4.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n Changed in version 2.5: Accept tuples as *prefix*.\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\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string: words start with\n uppercase characters, all remaining cased characters are lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\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 New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n', + 'string-methods': u'\nString Methods\n**************\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Note that none of these methods take keyword\narguments.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbuffer, xrange* section. To output formatted strings use template\nstrings or the ``%`` operator described in the *String Formatting\nOperations* 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 only its first character\n capitalized.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.4: Support for the *fillchar* argument.\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.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes 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\n Changed in version 2.5: Accept tuples as *suffix*.\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 range [*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(format_string, *args, **kwargs)\n\n Perform a string formatting operation. The *format_string*\n argument can contain literal text or replacement fields delimited\n by braces ``{}``. Each replacement field contains either the\n numeric index of a positional argument, or the name of a keyword\n argument. Returns a copy of *format_string* where each replacement\n field is replaced with the string value of the corresponding\n 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\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(seq)\n\n Return a string which is the concatenation of the strings in the\n sequence *seq*. The separator between elements is the string\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n New in version 2.5.\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]. Optional\n arguments *start* and *end* are interpreted as in slice notation.\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\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\n New in version 2.5.\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\n New in version 2.4.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n Changed in version 2.5: Accept tuples as *prefix*.\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\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string: words start with\n uppercase characters, all remaining cased characters are lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\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 New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n', 'strings': u'\nString literals\n***************\n\nString literals are described by the following lexical definitions:\n\n stringliteral ::= [stringprefix](shortstring | longstring)\n stringprefix ::= "r" | "u" | "ur" | "R" | "U" | "UR" | "Ur" | "uR"\n shortstring ::= "\'" shortstringitem* "\'" | \'"\' shortstringitem* \'"\'\n longstring ::= "\'\'\'" longstringitem* "\'\'\'"\n | \'"""\' longstringitem* \'"""\'\n shortstringitem ::= shortstringchar | escapeseq\n longstringitem ::= longstringchar | escapeseq\n shortstringchar ::= \n longstringchar ::= \n escapeseq ::= "\\" \n\nOne syntactic restriction not indicated by these productions is that\nwhitespace is not allowed between the **stringprefix** and the rest of\nthe string literal. The source character set is defined by the\nencoding declaration; it is ASCII if no encoding declaration is given\nin the source file; see section *Encoding declarations*.\n\nIn plain English: String literals can be enclosed in matching single\nquotes (``\'``) or double quotes (``"``). They can also be enclosed in\nmatching groups of three single or double quotes (these are generally\nreferred to as *triple-quoted strings*). The backslash (``\\``)\ncharacter is used to escape characters that otherwise have a special\nmeaning, such as newline, backslash itself, or the quote character.\nString literals may optionally be prefixed with a letter ``\'r\'`` or\n``\'R\'``; such strings are called *raw strings* and use different rules\nfor interpreting backslash escape sequences. A prefix of ``\'u\'`` or\n``\'U\'`` makes the string a Unicode string. Unicode strings use the\nUnicode character set as defined by the Unicode Consortium and ISO\n10646. Some additional escape sequences, described below, are\navailable in Unicode strings. The two prefix characters may be\ncombined; in this case, ``\'u\'`` must appear before ``\'r\'``.\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`` | 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| ``\\N{name}`` | Character named *name* in the | |\n| | Unicode database (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\r`` | ASCII Carriage Return (CR) | |\n+-------------------+-----------------------------------+---------+\n| ``\\t`` | ASCII Horizontal Tab (TAB) | |\n+-------------------+-----------------------------------+---------+\n| ``\\uxxxx`` | Character with 16-bit hex value | (1) |\n| | *xxxx* (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\Uxxxxxxxx`` | Character with 32-bit hex value | (2) |\n| | *xxxxxxxx* (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\v`` | ASCII Vertical Tab (VT) | |\n+-------------------+-----------------------------------+---------+\n| ``\\ooo`` | Character with octal value *ooo* | (3,5) |\n+-------------------+-----------------------------------+---------+\n| ``\\xhh`` | Character with hex value *hh* | (4,5) |\n+-------------------+-----------------------------------+---------+\n\nNotes:\n\n1. Individual code units which form parts of a surrogate pair can be\n encoded using this escape sequence.\n\n2. 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). Individual code units which form parts of a surrogate\n pair can be encoded using this escape sequence.\n\n3. As in Standard C, up to three octal digits are accepted.\n\n4. Unlike in Standard C, exactly two hex digits are required.\n\n5. In a string literal, hexadecimal and octal escapes denote the byte\n with the given value; it is not necessary that the byte encodes a\n character in the source character set. In a Unicode literal, these\n escapes denote a Unicode character with the given value.\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 marked as "(Unicode only)"\nin the table above fall into the category of unrecognized escapes for\nnon-Unicode string literals.\n\nWhen an ``\'r\'`` or ``\'R\'`` prefix is present, a character following a\nbackslash is included in the string without change, and *all\nbackslashes are left in the string*. For example, the string literal\n``r"\\n"`` consists of two characters: a backslash and a lowercase\n``\'n\'``. String quotes can be escaped with a backslash, but the\nbackslash remains in the string; for example, ``r"\\""`` is a valid\nstring literal consisting of two characters: a backslash and a double\nquote; ``r"\\"`` is not a valid string literal (even a raw string\ncannot end in an odd number of backslashes). Specifically, *a raw\nstring cannot end in a single backslash* (since the backslash would\nescape 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\nWhen an ``\'r\'`` or ``\'R\'`` prefix is used in conjunction with a\n``\'u\'`` or ``\'U\'`` prefix, then the ``\\uXXXX`` and ``\\UXXXXXXXX``\nescape sequences are processed while *all other backslashes are left\nin the string*. For example, the string literal ``ur"\\u0062\\n"``\nconsists of three Unicode characters: \'LATIN SMALL LETTER B\', \'REVERSE\nSOLIDUS\', and \'LATIN SMALL LETTER N\'. Backslashes can be escaped with\na preceding backslash; however, both remain in the string. As a\nresult, ``\\uXXXX`` escape sequences are only recognized when there are\nan odd number of backslashes.\n', 'subscriptions': u'\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 of a sequence or mapping type.\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 a\nplain integer. If this value is negative, the length of the sequence\nis added to it (so that, e.g., ``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).\n\nA string\'s items are characters. A character is not a separate data\ntype but a string of exactly one character.\n', 'truth': u"\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``, ``0L``, ``0.0``,\n ``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 ``__nonzero__()`` or ``__len__()`` method, when that method returns\n the 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", 'try': u'\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\nChanged in version 2.5: In previous versions of Python,\n``try``...``except``...``finally`` did not work. ``try``...``except``\nhad to be nested in ``try``...``finally``.\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, a tuple containing an item compatible with the\nexception, or, in the (deprecated) case of string exceptions, is the\nraised string itself (note that the object identities must match, i.e.\nit must be the same string object, not just a string with the same\nvalue).\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 in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the ``sys`` module:\n``sys.exc_type`` receives the object identifying the exception;\n``sys.exc_value`` receives the exception\'s parameter;\n``sys.exc_traceback`` receives a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. These details are also available through the\n``sys.exc_info()`` function, which returns a tuple ``(exc_type,\nexc_value, exc_traceback)``. Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables 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', 'types': u'\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.).\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name ``None``.\n It is used to signify the absence of a value in many situations,\n e.g., it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``NotImplemented``. Numeric methods and rich comparison methods may\n return this value if they do not implement the operation for the\n operands provided. (The interpreter will then try the reflected\n operation, or some other fallback, depending on the operator.) Its\n truth value is true.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``Ellipsis``. It is used to indicate the presence of the ``...``\n syntax in a slice. Its truth value is true.\n\n``numbers.Number``\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n ``numbers.Integral``\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are three types of integers:\n\n Plain integers\n These represent numbers in the range -2147483648 through\n 2147483647. (The range may be larger on machines with a\n larger natural word size, but not smaller.) When the result\n of an operation would fall outside this range, the result is\n normally returned as a long integer (in some cases, the\n exception ``OverflowError`` is raised instead). For the\n purpose of shift and mask operations, integers are assumed to\n have a binary, 2\'s complement notation using 32 or more bits,\n and hiding no bits from the user (i.e., all 4294967296\n different bit patterns correspond to different values).\n\n Long integers\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans\n These represent the truth values False and True. The two\n objects representing the values False and True are the only\n Boolean objects. The Boolean type is a subtype of plain\n integers, and Boolean values behave like the values 0 and 1,\n respectively, in almost all contexts, the exception being\n that when converted to a string, the strings ``"False"`` or\n ``"True"`` are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers and the least surprises when\n switching between the plain and long integer domains. Any\n operation, if it yields a result in the plain integer domain,\n will yield the same result in the long integer domain or when\n using mixed operands. The switch between domains is transparent\n to the programmer.\n\n ``numbers.Real`` (``float``)\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these is\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n ``numbers.Complex``\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number ``z`` can be retrieved through the read-only\n attributes ``z.real`` and ``z.imag``.\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function ``len()`` returns the number of\n items of a sequence. When the length of a sequence is *n*, the\n index set contains the numbers 0, 1, ..., *n*-1. Item *i* of\n sequence *a* is selected by ``a[i]``.\n\n Sequences also support slicing: ``a[i:j]`` selects all items with\n index *k* such that *i* ``<=`` *k* ``<`` *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: ``a[i:j:k]`` selects all items of *a* with index *x*\n where ``x = i + n*k``, *n* ``>=`` ``0`` and *i* ``<=`` *x* ``<``\n *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n The items of a string are characters. There is no separate\n character type; a character is represented by a string of one\n item. Characters represent (at least) 8-bit bytes. The\n built-in functions ``chr()`` and ``ord()`` convert between\n characters and nonnegative integers representing the byte\n values. Bytes with the values 0-127 usually represent the\n corresponding ASCII values, but the interpretation of values\n is up to the program. The string data type is also used to\n represent arrays of bytes, e.g., to hold data read from a\n file.\n\n (On systems whose native character set is not ASCII, strings\n may use EBCDIC in their internal representation, provided the\n functions ``chr()`` and ``ord()`` implement a mapping between\n ASCII and EBCDIC, and string comparison preserves the ASCII\n order. Or perhaps someone can propose a better rule?)\n\n Unicode\n The items of a Unicode object are Unicode code units. A\n Unicode code unit is represented by a Unicode object of one\n item and can hold either a 16-bit or 32-bit value\n representing a Unicode ordinal (the maximum value for the\n ordinal is given in ``sys.maxunicode``, and depends on how\n Python is configured at compile time). Surrogate pairs may\n be present in the Unicode object, and will be reported as two\n separate items. The built-in functions ``unichr()`` and\n ``ord()`` convert between code units and nonnegative integers\n representing the Unicode ordinals as defined in the Unicode\n Standard 3.0. Conversion from and to other encodings are\n possible through the Unicode method ``encode()`` and the\n built-in function ``unicode()``.\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and ``del`` (delete) statements.\n\n There is currently a single intrinsic mutable sequence type:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n The extension module ``array`` provides an additional example of\n a mutable sequence type.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function ``len()``\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n ``set()`` constructor and can be modified afterwards by several\n methods, such as ``add()``.\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in ``frozenset()`` constructor. As a frozenset is\n immutable and *hashable*, it can be used again as an element of\n another set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation ``a[k]`` selects the item indexed by\n ``k`` from the mapping ``a``; this can be used in expressions and\n as the target of assignments or ``del`` statements. The built-in\n function ``len()`` returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``) then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the ``{...}``\n notation (see section *Dictionary displays*).\n\n The extension modules ``dbm``, ``gdbm``, and ``bsddb`` provide\n additional examples of mapping types.\n\nCallable types\n These are the types to which the function call operation (see\n section *Calls*) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section *Function definitions*). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +-------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +=========================+=================================+=============+\n | ``func_doc`` | The function\'s documentation | Writable |\n | | string, or ``None`` if | |\n | | unavailable | |\n +-------------------------+---------------------------------+-------------+\n | ``__doc__`` | Another way of spelling | Writable |\n | | ``func_doc`` | |\n +-------------------------+---------------------------------+-------------+\n | ``func_name`` | The function\'s name | Writable |\n +-------------------------+---------------------------------+-------------+\n | ``__name__`` | Another way of spelling | Writable |\n | | ``func_name`` | |\n +-------------------------+---------------------------------+-------------+\n | ``__module__`` | The name of the module the | Writable |\n | | function was defined in, or | |\n | | ``None`` if unavailable. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_defaults`` | A tuple containing default | Writable |\n | | argument values for those | |\n | | arguments that have defaults, | |\n | | or ``None`` if no arguments | |\n | | have a default value | |\n +-------------------------+---------------------------------+-------------+\n | ``func_code`` | The code object representing | Writable |\n | | the compiled function body. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_globals`` | A reference to the dictionary | Read-only |\n | | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_dict`` | The namespace supporting | Writable |\n | | arbitrary function attributes. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_closure`` | ``None`` or a tuple of cells | Read-only |\n | | that contain bindings for the | |\n | | function\'s free variables. | |\n +-------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Changed in version 2.4: ``func_name`` is now writable.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n User-defined methods\n A user-defined method object combines a class, a class instance\n (or ``None``) and any callable object (normally a user-defined\n function).\n\n Special read-only attributes: ``im_self`` is the class instance\n object, ``im_func`` is the function object; ``im_class`` is the\n class of ``im_self`` for bound methods or the class that asked\n for the method for unbound methods; ``__doc__`` is the method\'s\n documentation (same as ``im_func.__doc__``); ``__name__`` is the\n method name (same as ``im_func.__name__``); ``__module__`` is\n the name of the module the method was defined in, or ``None`` if\n unavailable.\n\n Changed in version 2.2: ``im_self`` used to refer to the class\n that defined the method.\n\n Changed in version 2.6: For 3.0 forward-compatibility,\n ``im_func`` is also available as ``__func__``, and ``im_self``\n as ``__self__``.\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object, an unbound\n user-defined method object, or a class method object. When the\n attribute is a user-defined method object, a new method object\n is only created if the class from which it is being retrieved is\n the same as, or a derived class of, the class stored in the\n original method object; otherwise, the original method object is\n used as it is.\n\n When a user-defined method object is created by retrieving a\n user-defined function object from a class, its ``im_self``\n attribute is ``None`` and the method object is said to be\n unbound. When one is created by retrieving a user-defined\n function object from a class via one of its instances, its\n ``im_self`` attribute is the instance, and the method object is\n said to be bound. In either case, the new method\'s ``im_class``\n attribute is the class from which the retrieval takes place, and\n its ``im_func`` attribute is the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the ``im_func``\n attribute of the new instance is not the original method object\n but its ``im_func`` attribute.\n\n When a user-defined method object is created by retrieving a\n class method object from a class or instance, its ``im_self``\n attribute is the class itself (the same as the ``im_class``\n attribute), and its ``im_func`` attribute is the function object\n underlying the class method.\n\n When an unbound user-defined method object is called, the\n underlying function (``im_func``) is called, with the\n restriction that the first argument must be an instance of the\n proper class (``im_class``) or of a derived class thereof.\n\n When a bound user-defined method object is called, the\n underlying function (``im_func``) is called, inserting the class\n instance (``im_self``) in front of the argument list. For\n instance, when ``C`` is a class which contains a definition for\n a function ``f()``, and ``x`` is an instance of ``C``, calling\n ``x.f(1)`` is equivalent to calling ``C.f(x, 1)``.\n\n When a user-defined method object is derived from a class method\n object, the "class instance" stored in ``im_self`` will actually\n be the class itself, so that calling either ``x.f(1)`` or\n ``C.f(1)`` is equivalent to calling ``f(C,1)`` where ``f`` is\n the underlying function.\n\n Note that the transformation from function object to (unbound or\n bound) method object happens each time the attribute is\n retrieved from the class or instance. In some cases, a fruitful\n optimization is to assign the attribute to a local variable and\n call that local variable. Also notice that this transformation\n only happens for user-defined functions; other callable objects\n (and all non-callable objects) are retrieved without\n transformation. It is also important to note that user-defined\n functions which are attributes of a class instance are not\n converted to bound methods; this *only* happens when the\n function is an attribute of the class.\n\n Generator functions\n A function or method which uses the ``yield`` statement (see\n section *The yield statement*) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s ``next()`` method will cause the function to\n execute until it provides a value using the ``yield`` statement.\n When the function executes a ``return`` statement or falls off\n the end, a ``StopIteration`` exception is raised and the\n iterator will have reached the end of the set of values to be\n returned.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are ``len()`` and ``math.sin()``\n (``math`` is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: ``__doc__`` is the function\'s documentation\n string, or ``None`` if unavailable; ``__name__`` is the\n function\'s name; ``__self__`` is set to ``None`` (but see the\n next item); ``__module__`` is the name of the module the\n function was defined in or ``None`` if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n ``alist.append()``, assuming *alist* is a list object. In this\n case, the special read-only attribute ``__self__`` is set to the\n object denoted by *list*.\n\n Class Types\n Class types, or "new-style classes," are callable. These\n objects normally act as factories for new instances of\n themselves, but variations are possible for class types that\n override ``__new__()``. The arguments of the call are passed to\n ``__new__()`` and, in the typical case, to ``__init__()`` to\n initialize the new instance.\n\n Classic Classes\n Class objects are described below. When a class object is\n called, a new class instance (also described below) is created\n and returned. This implies a call to the class\'s ``__init__()``\n method if it has one. Any arguments are passed on to the\n ``__init__()`` method. If there is no ``__init__()`` method,\n the class must be called without arguments.\n\n Class instances\n Class instances are described below. Class instances are\n callable only when the class has a ``__call__()`` method;\n ``x(arguments)`` is a shorthand for ``x.__call__(arguments)``.\n\nModules\n Modules are imported by the ``import`` statement (see section *The\n import statement*). A module object has a namespace implemented by\n a dictionary object (this is the dictionary referenced by the\n func_globals attribute of functions defined in the module).\n Attribute references are translated to lookups in this dictionary,\n e.g., ``m.x`` is equivalent to ``m.__dict__["x"]``. A module object\n does not contain the code object used to initialize the module\n (since it isn\'t needed once the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``.\n\n Special read-only attribute: ``__dict__`` is the module\'s namespace\n as a dictionary object.\n\n Predefined (writable) attributes: ``__name__`` is the module\'s\n name; ``__doc__`` is the module\'s documentation string, or ``None``\n if unavailable; ``__file__`` is the pathname of the file from which\n the module was loaded, if it was loaded from a file. The\n ``__file__`` attribute is not present for C modules that are\n statically linked into the interpreter; for extension modules\n loaded dynamically from a shared library, it is the pathname of the\n shared library file.\n\nClasses\n Both class types (new-style classes) and class objects (old-\n style/classic classes) are typically created by class definitions\n (see section *Class definitions*). A class has a namespace\n implemented by a dictionary object. Class attribute references are\n translated to lookups in this dictionary, e.g., ``C.x`` is\n translated to ``C.__dict__["x"]`` (although for new-style classes\n in particular there are a number of hooks which allow for other\n means of locating attributes). When the attribute name is not found\n there, the attribute search continues in the base classes. For\n old-style classes, the search is depth-first, left-to-right in the\n order of occurrence in the base class list. New-style classes use\n the more complex C3 method resolution order which behaves correctly\n even in the presence of \'diamond\' inheritance structures where\n there are multiple inheritance paths leading back to a common\n ancestor. Additional details on the C3 MRO used by new-style\n classes can be found in the documentation accompanying the 2.3\n release at http://www.python.org/download/releases/2.3/mro/.\n\n When a class attribute reference (for class ``C``, say) would yield\n a user-defined function object or an unbound user-defined method\n object whose associated class is either ``C`` or one of its base\n classes, it is transformed into an unbound user-defined method\n object whose ``im_class`` attribute is ``C``. When it would yield a\n class method object, it is transformed into a bound user-defined\n method object whose ``im_class`` and ``im_self`` attributes are\n both ``C``. When it would yield a static method object, it is\n transformed into the object wrapped by the static method object.\n See section *Implementing Descriptors* for another way in which\n attributes retrieved from a class may differ from those actually\n contained in its ``__dict__`` (note that only new-style classes\n support descriptors).\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: ``__name__`` is the class name; ``__module__``\n is the module name in which the class was defined; ``__dict__`` is\n the dictionary containing the class\'s namespace; ``__bases__`` is a\n tuple (possibly empty or a singleton) containing the base classes,\n in the order of their occurrence in the base class list;\n ``__doc__`` is the class\'s documentation string, or None if\n undefined.\n\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object or an unbound user-defined method object whose\n associated class is the class (call it ``C``) of the instance for\n which the attribute reference was initiated or one of its bases, it\n is transformed into a bound user-defined method object whose\n ``im_class`` attribute is ``C`` and whose ``im_self`` attribute is\n the instance. Static method and class method objects are also\n transformed, as if they had been retrieved from class ``C``; see\n above under "Classes". See section *Implementing Descriptors* for\n another way in which attributes of a class retrieved via its\n instances may differ from the objects actually stored in the\n class\'s ``__dict__``. If no class attribute is found, and the\n object\'s class has a ``__getattr__()`` method, that is called to\n satisfy the lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n ``__setattr__()`` or ``__delattr__()`` method, this is called\n instead of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n *Special method names*.\n\n Special attributes: ``__dict__`` is the attribute dictionary;\n ``__class__`` is the instance\'s class.\n\nFiles\n A file object represents an open file. File objects are created by\n the ``open()`` built-in function, and also by ``os.popen()``,\n ``os.fdopen()``, and the ``makefile()`` method of socket objects\n (and perhaps by other functions or methods provided by extension\n modules). The objects ``sys.stdin``, ``sys.stdout`` and\n ``sys.stderr`` are initialized to file objects corresponding to the\n interpreter\'s standard input, output and error streams. See *File\n Objects* for complete documentation of file objects.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: ``co_name`` gives the function\n name; ``co_argcount`` is the number of positional arguments\n (including arguments with default values); ``co_nlocals`` is the\n number of local variables used by the function (including\n arguments); ``co_varnames`` is a tuple containing the names of\n the local variables (starting with the argument names);\n ``co_cellvars`` is a tuple containing the names of local\n variables that are referenced by nested functions;\n ``co_freevars`` is a tuple containing the names of free\n variables; ``co_code`` is a string representing the sequence of\n bytecode instructions; ``co_consts`` is a tuple containing the\n literals used by the bytecode; ``co_names`` is a tuple\n containing the names used by the bytecode; ``co_filename`` is\n the filename from which the code was compiled;\n ``co_firstlineno`` is the first line number of the function;\n ``co_lnotab`` is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); ``co_stacksize`` is the required stack size\n (including local variables); ``co_flags`` is an integer encoding\n a number of flags for the interpreter.\n\n The following flag bits are defined for ``co_flags``: bit\n ``0x04`` is set if the function uses the ``*arguments`` syntax\n to accept an arbitrary number of positional arguments; bit\n ``0x08`` is set if the function uses the ``**keywords`` syntax\n to accept arbitrary keyword arguments; bit ``0x20`` is set if\n the function is a generator.\n\n Future feature declarations (``from __future__ import\n division``) also use bits in ``co_flags`` to indicate whether a\n code object was compiled with a particular feature enabled: bit\n ``0x2000`` is set if the function was compiled with future\n division enabled; bits ``0x10`` and ``0x1000`` were used in\n earlier versions of Python.\n\n Other bits in ``co_flags`` are reserved for internal use.\n\n If a code object represents a function, the first item in\n ``co_consts`` is the documentation string of the function, or\n ``None`` if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: ``f_back`` is to the previous\n stack frame (towards the caller), or ``None`` if this is the\n bottom stack frame; ``f_code`` is the code object being executed\n in this frame; ``f_locals`` is the dictionary used to look up\n local variables; ``f_globals`` is used for global variables;\n ``f_builtins`` is used for built-in (intrinsic) names;\n ``f_restricted`` is a flag indicating whether the function is\n executing in restricted execution mode; ``f_lasti`` gives the\n precise instruction (this is an index into the bytecode string\n of the code object).\n\n Special writable attributes: ``f_trace``, if not ``None``, is a\n function called at the start of each source code line (this is\n used by the debugger); ``f_exc_type``, ``f_exc_value``,\n ``f_exc_traceback`` represent the last exception raised in the\n parent frame provided another exception was ever raised in the\n current frame (in all other cases they are None); ``f_lineno``\n is the current line number of the frame --- writing to this from\n within a trace function jumps to the given line (only for the\n bottom-most frame). A debugger can implement a Jump command\n (aka Set Next Statement) by writing to f_lineno.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n *The try statement*.) It is accessible as ``sys.exc_traceback``,\n and also as the third item of the tuple returned by\n ``sys.exc_info()``. The latter is the preferred interface,\n since it works correctly when the program is using multiple\n threads. When the program contains no suitable handler, the\n stack trace is written (nicely formatted) to the standard error\n stream; if the interpreter is interactive, it is also made\n available to the user as ``sys.last_traceback``.\n\n Special read-only attributes: ``tb_next`` is the next level in\n the stack trace (towards the frame where the exception\n occurred), or ``None`` if there is no next level; ``tb_frame``\n points to the execution frame of the current level;\n ``tb_lineno`` gives the line number where the exception\n occurred; ``tb_lasti`` indicates the precise instruction. The\n line number and last instruction in the traceback may differ\n from the line number of its frame object if the exception\n occurred in a ``try`` statement with no matching except clause\n or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices when *extended slice\n syntax* is used. This is a slice using two colons, or multiple\n slices or ellipses separated by commas, e.g., ``a[i:j:step]``,\n ``a[i:j, k:l]``, or ``a[..., i:j]``. They are also created by\n the built-in ``slice()`` function.\n\n Special read-only attributes: ``start`` is the lower bound;\n ``stop`` is the upper bound; ``step`` is the step value; each is\n ``None`` if omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the extended slice that the slice\n object would describe if applied to a sequence of *length*\n items. It returns a tuple of three integers; respectively\n these are the *start* and *stop* indices and the *step* or\n stride length of the slice. Missing or out-of-bounds indices\n are handled in a manner consistent with regular slices.\n\n New in version 2.3.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n ``staticmethod()`` constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in ``classmethod()`` constructor.\n', 'typesfunctions': u'\nFunctions\n*********\n\nFunction objects are created by function definitions. The only\noperation on a function object is to call it: ``func(argument-list)``.\n\nThere are really two flavors of function objects: built-in functions\nand user-defined functions. Both support the same operation (to call\nthe function), but the implementation is different, hence the\ndifferent object types.\n\nSee *Function definitions* for more information.\n', - 'typesmapping': u'\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 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 is\n 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": 2, "two": 3}``:\n\n * ``dict(one=2, two=3)``\n\n * ``dict({\'one\': 2, \'two\': 3})``\n\n * ``dict(zip((\'one\', \'two\'), (2, 3)))``\n\n * ``dict([[\'two\', 3], [\'one\', 2]])``\n\n The first example only works for keys that are valid Python\n identifiers; the others work with any valid keys.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for building a dictionary from\n keyword arguments added.\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 New in version 2.5: If a subclass of dict defines a method\n ``__missing__()``, if the key *key* is not present, the\n ``d[key]`` operation calls that method with the key *key* as\n argument. The ``d[key]`` operation then returns or raises\n whatever is returned or raised by the ``__missing__(key)`` call\n if the key is not present. No other operations or methods invoke\n ``__missing__()``. If ``__missing__()`` is not defined,\n ``KeyError`` is raised. ``__missing__()`` must be a method; it\n cannot be an instance variable. For an example, see\n ``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 New in version 2.2.\n\n key not in d\n\n Equivalent to ``not key in d``.\n\n New in version 2.2.\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 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 New in version 2.3.\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 has_key(key)\n\n Test for the presence of *key* in the dictionary. ``has_key()``\n is deprecated in favor of ``key in d``.\n\n items()\n\n Return a copy of the dictionary\'s list of ``(key, value)``\n pairs.\n\n Note: Keys and values are listed in an arbitrary order which is non-\n random, varies across Python implementations, and depends on\n the dictionary\'s history of insertions and deletions. If\n ``items()``, ``keys()``, ``values()``, ``iteritems()``,\n ``iterkeys()``, and ``itervalues()`` are called with no\n intervening modifications to the dictionary, the lists will\n directly correspond. This allows the creation of ``(value,\n key)`` pairs using ``zip()``: ``pairs = zip(d.values(),\n d.keys())``. The same relationship holds for the\n ``iterkeys()`` and ``itervalues()`` methods: ``pairs =\n zip(d.itervalues(), d.iterkeys())`` provides the same value\n for ``pairs``. Another way to create the same list is ``pairs\n = [(v, k) for (k, v) in d.iteritems()]``.\n\n iteritems()\n\n Return an iterator over the dictionary\'s ``(key, value)`` pairs.\n See the note for ``dict.items()``.\n\n New in version 2.2.\n\n iterkeys()\n\n Return an iterator over the dictionary\'s keys. See the note for\n ``dict.items()``.\n\n New in version 2.2.\n\n itervalues()\n\n Return an iterator over the dictionary\'s values. See the note\n for ``dict.items()``.\n\n New in version 2.2.\n\n keys()\n\n Return a copy of the dictionary\'s list of keys. See the note\n for ``dict.items()``.\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 New in version 2.3.\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 a tuple or other iterable of\n length two). If keyword arguments are specified, the dictionary\n is then is updated with those key/value pairs: ``d.update(red=1,\n blue=2)``.\n\n Changed in version 2.4: Allowed the argument to be an iterable\n of key/value pairs and allowed keyword arguments.\n\n values()\n\n Return a copy of the dictionary\'s list of values. See the note\n for ``dict.items()``.\n', + 'typesmapping': u'\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 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 is\n 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": 2, "two": 3}``:\n\n * ``dict(one=2, two=3)``\n\n * ``dict({\'one\': 2, \'two\': 3})``\n\n * ``dict(zip((\'one\', \'two\'), (2, 3)))``\n\n * ``dict([[\'two\', 3], [\'one\', 2]])``\n\n The first example only works for keys that are valid Python\n identifiers; the others work with any valid keys.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for building a dictionary from\n keyword arguments added.\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 New in version 2.5: If a subclass of dict defines a method\n ``__missing__()``, if the key *key* is not present, the\n ``d[key]`` operation calls that method with the key *key* as\n argument. The ``d[key]`` operation then returns or raises\n whatever is returned or raised by the ``__missing__(key)`` call\n if the key is not present. No other operations or methods invoke\n ``__missing__()``. If ``__missing__()`` is not defined,\n ``KeyError`` is raised. ``__missing__()`` must be a method; it\n cannot be an instance variable. For an example, see\n ``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 New in version 2.2.\n\n key not in d\n\n Equivalent to ``not key in d``.\n\n New in version 2.2.\n\n iter(d)\n\n Return an iterator over the keys of the dictionary. This is a\n shortcut for ``iterkeys()``.\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 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 New in version 2.3.\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 has_key(key)\n\n Test for the presence of *key* in the dictionary. ``has_key()``\n is deprecated in favor of ``key in d``.\n\n items()\n\n Return a copy of the dictionary\'s list of ``(key, value)``\n pairs.\n\n Note: Keys and values are listed in an arbitrary order which is non-\n random, varies across Python implementations, and depends on\n the dictionary\'s history of insertions and deletions. If\n ``items()``, ``keys()``, ``values()``, ``iteritems()``,\n ``iterkeys()``, and ``itervalues()`` are called with no\n intervening modifications to the dictionary, the lists will\n directly correspond. This allows the creation of ``(value,\n key)`` pairs using ``zip()``: ``pairs = zip(d.values(),\n d.keys())``. The same relationship holds for the\n ``iterkeys()`` and ``itervalues()`` methods: ``pairs =\n zip(d.itervalues(), d.iterkeys())`` provides the same value\n for ``pairs``. Another way to create the same list is ``pairs\n = [(v, k) for (k, v) in d.iteritems()]``.\n\n iteritems()\n\n Return an iterator over the dictionary\'s ``(key, value)`` pairs.\n See the note for ``dict.items()``.\n\n Using ``iteritems()`` while adding or deleting entries in the\n dictionary will raise a ``RuntimeError``.\n\n New in version 2.2.\n\n iterkeys()\n\n Return an iterator over the dictionary\'s keys. See the note for\n ``dict.items()``.\n\n Using ``iterkeys()`` while adding or deleting entries in the\n dictionary will raise a ``RuntimeError``.\n\n New in version 2.2.\n\n itervalues()\n\n Return an iterator over the dictionary\'s values. See the note\n for ``dict.items()``.\n\n Using ``itervalues()`` while adding or deleting entries in the\n dictionary will raise a ``RuntimeError``.\n\n New in version 2.2.\n\n keys()\n\n Return a copy of the dictionary\'s list of keys. See the note\n for ``dict.items()``.\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 New in version 2.3.\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 a tuple or other iterable of\n length two). If keyword arguments are specified, the dictionary\n is then is updated with those key/value pairs: ``d.update(red=1,\n blue=2)``.\n\n Changed in version 2.4: Allowed the argument to be an iterable\n of key/value pairs and allowed keyword arguments.\n\n values()\n\n Return a copy of the dictionary\'s list of values. See the note\n for ``dict.items()``.\n', 'typesmethods': u"\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\nThe implementation adds two special read-only attributes to class\ninstance methods: ``m.im_self`` is the object on which the method\noperates, and ``m.im_func`` is the function implementing the method.\nCalling ``m(arg-1, arg-2, ..., arg-n)`` is completely equivalent to\ncalling ``m.im_func(m.im_self, arg-1, arg-2, ..., arg-n)``.\n\nClass instance methods are either *bound* or *unbound*, referring to\nwhether the method was accessed through an instance or a class,\nrespectively. When a method is unbound, its ``im_self`` attribute\nwill be ``None`` and if called, an explicit ``self`` object must be\npassed as the first argument. In this case, ``self`` must be an\ninstance of the unbound method's class (or a subclass of that class),\notherwise a ``TypeError`` is raised.\n\nLike function objects, methods objects support getting arbitrary\nattributes. However, since method attributes are actually stored on\nthe underlying function object (``meth.im_func``), setting method\nattributes on either bound or unbound methods is disallowed.\nAttempting to set a method attribute results in a ``TypeError`` being\nraised. In order to set a method attribute, you need to explicitly\nset it on the underlying function object:\n\n class C:\n def method(self):\n pass\n\n c = C()\n c.method.im_func.whoami = 'my name is c'\n\nSee *The standard type hierarchy* for more information.\n", 'typesmodules': u"\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': u'\nSequence Types --- ``str``, ``unicode``, ``list``, ``tuple``, ``buffer``, ``xrange``\n************************************************************************************\n\nThere are six sequence types: strings, Unicode strings, lists, tuples,\nbuffers, and xrange objects. (For other containers see the built in\n``dict``, ``list``, ``set``, and ``tuple`` classes, and the\n``collections`` module.)\n\nString literals are written in single or double quotes: ``\'xyzzy\'``,\n``"frobozz"``. See *String literals* for more about string literals.\nUnicode strings are much like strings, but are specified in the syntax\nusing a preceding ``\'u\'`` character: ``u\'abc\'``, ``u"def"``. In\naddition to the functionality described here, there are also string-\nspecific methods described in the *String Methods* section. Lists are\nconstructed with square brackets, separating items with commas: ``[a,\nb, c]``. Tuples are constructed by the comma operator (not within\nsquare brackets), with or without enclosing parentheses, but an empty\ntuple must have the enclosing parentheses, such as ``a, b, c`` or\n``()``. A single item tuple must have a trailing comma, such as\n``(d,)``.\n\nBuffer objects are not directly supported by Python syntax, but can be\ncreated by calling the builtin function ``buffer()``. They don\'t\nsupport concatenation or repetition.\n\nObjects of type xrange are similar to buffers in that there is no\nspecific syntax to create them, but they are created using the\n``xrange()`` function. They don\'t support slicing, concatenation or\nrepetition, and using ``in``, ``not in``, ``min()`` or ``max()`` on\nthem 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 compare\nequal and the two sequences must be of the same type and have the same\nlength. (For full details see *Comparisons* in the language\nreference.)\n\nNotes:\n\n1. When *s* is a string or Unicode string object the ``in`` and ``not\n in`` operations act like a substring test. In Python versions\n before 2.3, *x* had to be a string of length 1. In Python 2.3 and\n beyond, *x* may be a string of any length.\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. If *s* and *t* are both strings, some Python implementations such\n as CPython can usually perform an in-place optimization for\n assignments of the form ``s=s+t`` or ``s+=t``. When applicable,\n this optimization makes quadratic run-time much less likely. This\n optimization is both version and implementation dependent. For\n performance sensitive code, it is preferable to use the\n ``str.join()`` method which assures consistent linear concatenation\n performance across versions and implementations.\n\n Changed in version 2.4: Formerly, string concatenation never\n occurred in-place.\n\n\nString Methods\n==============\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Note that none of these methods take keyword\narguments.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbuffer, xrange* section. To output formatted strings use template\nstrings or the ``%`` operator described in the *String Formatting\nOperations* 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 only its first character\n capitalized.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of occurrences of substring *sub* in the range\n [*start*, *end*]. Optional arguments *start* and *end* are\n interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes 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\n Changed in version 2.5: Accept tuples as *suffix*.\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 range [*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(format_string, *args, **kwargs)\n\n Perform a string formatting operation. The *format_string*\n argument can contain literal text or replacement fields delimited\n by braces ``{}``. Each replacement field contains either the\n numeric index of a positional argument, or the name of a keyword\n argument. Returns a copy of *format_string* where each replacement\n field is replaced with the string value of the corresponding\n 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\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(seq)\n\n Return a string which is the concatenation of the strings in the\n sequence *seq*. The separator between elements is the string\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n New in version 2.5.\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]. Optional\n arguments *start* and *end* are interpreted as in slice notation.\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\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\n New in version 2.5.\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\n New in version 2.4.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n Changed in version 2.5: Accept tuples as *prefix*.\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\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string: words start with\n uppercase characters, all remaining cased characters are lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\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 New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n\n\nString Formatting Operations\n============================\n\nString and Unicode objects have one unique built-in operation: the\n``%`` operator (modulo). This is also known as the string\n*formatting* or *interpolation* operator. Given ``format % values``\n(where *format* is a string or Unicode object), ``%`` conversion\nspecifications in *format* are replaced with zero or more elements of\n*values*. The effect is similar to the using ``sprintf`` in the C\nlanguage. If *format* is a Unicode object, or if any of the objects\nbeing converted using the ``%s`` conversion are Unicode objects, the\nresult will also be a Unicode object.\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 %(#)03d quote types.\' % \\\n... {\'language\': "Python", "#": 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\'`` | Obselete 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()``). | (6) |\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 ``%r`` conversion was added in Python 2.0.\n\n The precision determines the maximal number of characters used.\n\n6. If the object or format provided is a ``unicode`` string, the\n resulting string will also be ``unicode``.\n\n The precision determines the maximal number of characters used.\n\n7. 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\nFor safety reasons, floating point precisions are clipped to 50;\n``%f`` conversions for numbers whose absolute value is over 1e25 are\nreplaced by ``%g`` conversions. [5] All other errors raise\nexceptions.\n\nAdditional string operations are defined in standard modules\n``string`` and ``re``.\n\n\nXRange Type\n===========\n\nThe ``xrange`` type is an immutable sequence which is commonly used\nfor looping. The advantage of the ``xrange`` type is that an\n``xrange`` object will always take the same amount of memory, no\nmatter the size of the range it represents. There are no consistent\nperformance advantages.\n\nXRange objects have very little behavior: they only support indexing,\niteration, and the ``len()`` function.\n\n\nMutable Sequence Types\n======================\n\nList objects support additional operations that allow in-place\nmodification of the object. Other mutable sequence types (when added\nto the language) should also support these operations. Strings and\ntuples are immutable sequence types: such objects cannot be modified\nonce created. The following operations are defined on mutable sequence\ntypes (where *x* is an arbitrary object):\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)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\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 | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. 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 list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn\'t have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don\'t return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\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``.\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 In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. While a list is being sorted, the effect of attempting to mutate,\n or even inspect, the list is undefined. The C implementation of\n Python 2.3 and newer makes the list appear empty for the duration,\n and raises ``ValueError`` if it can detect that the list has been\n mutated during a sort.\n', + 'typesseq': u'\nSequence Types --- ``str``, ``unicode``, ``list``, ``tuple``, ``buffer``, ``xrange``\n************************************************************************************\n\nThere are six sequence types: strings, Unicode strings, lists, tuples,\nbuffers, and xrange objects.\n\nFor other containers see the built in ``dict`` and ``set`` classes,\nand the ``collections`` module.\n\nString literals are written in single or double quotes: ``\'xyzzy\'``,\n``"frobozz"``. See *String literals* for more about string literals.\nUnicode strings are much like strings, but are specified in the syntax\nusing a preceding ``\'u\'`` character: ``u\'abc\'``, ``u"def"``. In\naddition to the functionality described here, there are also string-\nspecific methods described in the *String Methods* section. Lists are\nconstructed with square brackets, separating items with commas: ``[a,\nb, c]``. Tuples are constructed by the comma operator (not within\nsquare brackets), with or without enclosing parentheses, but an empty\ntuple must have the enclosing parentheses, such as ``a, b, c`` or\n``()``. A single item tuple must have a trailing comma, such as\n``(d,)``.\n\nBuffer objects are not directly supported by Python syntax, but can be\ncreated by calling the builtin function ``buffer()``. They don\'t\nsupport concatenation or repetition.\n\nObjects of type xrange are similar to buffers in that there is no\nspecific syntax to create them, but they are created using the\n``xrange()`` function. They don\'t support slicing, concatenation or\nrepetition, and using ``in``, ``not in``, ``min()`` or ``max()`` on\nthem 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 compare\nequal and the two sequences must be of the same type and have the same\nlength. (For full details see *Comparisons* in the language\nreference.)\n\nNotes:\n\n1. When *s* is a string or Unicode string object the ``in`` and ``not\n in`` operations act like a substring test. In Python versions\n before 2.3, *x* had to be a string of length 1. In Python 2.3 and\n beyond, *x* may be a string of any length.\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. If *s* and *t* are both strings, some Python implementations such\n as CPython can usually perform an in-place optimization for\n assignments of the form ``s=s+t`` or ``s+=t``. When applicable,\n this optimization makes quadratic run-time much less likely. This\n optimization is both version and implementation dependent. For\n performance sensitive code, it is preferable to use the\n ``str.join()`` method which assures consistent linear concatenation\n performance across versions and implementations.\n\n Changed in version 2.4: Formerly, string concatenation never\n occurred in-place.\n\n\nString Methods\n==============\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Note that none of these methods take keyword\narguments.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbuffer, xrange* section. To output formatted strings use template\nstrings or the ``%`` operator described in the *String Formatting\nOperations* 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 only its first character\n capitalized.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.4: Support for the *fillchar* argument.\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.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes 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\n Changed in version 2.5: Accept tuples as *suffix*.\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 range [*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(format_string, *args, **kwargs)\n\n Perform a string formatting operation. The *format_string*\n argument can contain literal text or replacement fields delimited\n by braces ``{}``. Each replacement field contains either the\n numeric index of a positional argument, or the name of a keyword\n argument. Returns a copy of *format_string* where each replacement\n field is replaced with the string value of the corresponding\n 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\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(seq)\n\n Return a string which is the concatenation of the strings in the\n sequence *seq*. The separator between elements is the string\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n New in version 2.5.\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]. Optional\n arguments *start* and *end* are interpreted as in slice notation.\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\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\n New in version 2.5.\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\n New in version 2.4.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n Changed in version 2.5: Accept tuples as *prefix*.\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\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string: words start with\n uppercase characters, all remaining cased characters are lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\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 New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n\n\nString Formatting Operations\n============================\n\nString and Unicode objects have one unique built-in operation: the\n``%`` operator (modulo). This is also known as the string\n*formatting* or *interpolation* operator. Given ``format % values``\n(where *format* is a string or Unicode object), ``%`` conversion\nspecifications in *format* are replaced with zero or more elements of\n*values*. The effect is similar to the using ``sprintf`` in the C\nlanguage. If *format* is a Unicode object, or if any of the objects\nbeing converted using the ``%s`` conversion are Unicode objects, the\nresult will also be a Unicode object.\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 %(#)03d quote types.\' % \\\n... {\'language\': "Python", "#": 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()``). | (6) |\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 ``%r`` conversion was added in Python 2.0.\n\n The precision determines the maximal number of characters used.\n\n6. If the object or format provided is a ``unicode`` string, the\n resulting string will also be ``unicode``.\n\n The precision determines the maximal number of characters used.\n\n7. 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\nFor safety reasons, floating point precisions are clipped to 50;\n``%f`` conversions for numbers whose absolute value is over 1e50 are\nreplaced by ``%g`` conversions. [5] All other errors raise\nexceptions.\n\nAdditional string operations are defined in standard modules\n``string`` and ``re``.\n\n\nXRange Type\n===========\n\nThe ``xrange`` type is an immutable sequence which is commonly used\nfor looping. The advantage of the ``xrange`` type is that an\n``xrange`` object will always take the same amount of memory, no\nmatter the size of the range it represents. There are no consistent\nperformance advantages.\n\nXRange objects have very little behavior: they only support indexing,\niteration, and the ``len()`` function.\n\n\nMutable Sequence Types\n======================\n\nList objects support additional operations that allow in-place\nmodification of the object. Other mutable sequence types (when added\nto the language) should also support these operations. Strings and\ntuples are immutable sequence types: such objects cannot be modified\nonce created. The following operations are defined on mutable sequence\ntypes (where *x* is an arbitrary object):\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)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\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 | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. 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 list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn\'t have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don\'t return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\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``.\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 In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. While a list is being sorted, the effect of attempting to mutate,\n or even inspect, the list is undefined. The C implementation of\n Python 2.3 and newer makes the list appear empty for the duration,\n and raises ``ValueError`` if it can detect that the list has been\n mutated during a sort.\n', 'typesseq-mutable': u"\nMutable Sequence Types\n**********************\n\nList objects support additional operations that allow in-place\nmodification of the object. Other mutable sequence types (when added\nto the language) should also support these operations. Strings and\ntuples are immutable sequence types: such objects cannot be modified\nonce created. The following operations are defined on mutable sequence\ntypes (where *x* is an arbitrary object):\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)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\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 | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. 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 list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn't have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don't return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\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``.\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 In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. While a list is being sorted, the effect of attempting to mutate,\n or even inspect, the list is undefined. The C implementation of\n Python 2.3 and newer makes the list appear empty for the duration,\n and raises ``ValueError`` if it can detect that the list has been\n mutated during a sort.\n", - 'unary': u'\nUnary arithmetic 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\nplain or long integer argument. The bitwise inversion of ``x`` is\ndefined as ``-(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', + 'unary': u'\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\nplain or long integer argument. The bitwise inversion of ``x`` is\ndefined as ``-(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': u'\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', 'with': u'\nThe ``with`` statement\n**********************\n\nNew in version 2.5.\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" expression ["as" target] ":" suite\n\nThe execution of the ``with`` statement proceeds as follows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__enter__()`` method is invoked.\n\n3. 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 5 below.\n\n4. The suite is executed.\n\n5. 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\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n', 'yield': u'\nThe ``yield`` statement\n***********************\n\n yield_stmt ::= yield_expression\n\nThe ``yield`` statement is only used when defining a generator\nfunction, and is only used in the body of the generator function.\nUsing a ``yield`` statement in a function definition is sufficient to\ncause that definition to create a generator function instead of a\nnormal function.\n\nWhen a generator function is called, it returns an iterator known as a\ngenerator iterator, or more commonly, a generator. The body of the\ngenerator function is executed by calling the generator\'s ``next()``\nmethod repeatedly until it raises an exception.\n\nWhen a ``yield`` statement is executed, the state of the generator is\nfrozen and the value of **expression_list** is returned to\n``next()``\'s caller. By "frozen" we mean that all local state is\nretained, including the current bindings of local variables, the\ninstruction pointer, and the internal evaluation stack: enough\ninformation is saved so that the next time ``next()`` is invoked, the\nfunction can proceed exactly as if the ``yield`` statement were just\nanother external call.\n\nAs of Python version 2.5, the ``yield`` statement is now allowed in\nthe ``try`` clause of a ``try`` ... ``finally`` construct. If the\ngenerator is not resumed before it is finalized (by reaching a zero\nreference count or by being garbage collected), the generator-\niterator\'s ``close()`` method will be called, allowing any pending\n``finally`` clauses to execute.\n\nNote: In Python 2.2, the ``yield`` statement was only allowed when the\n ``generators`` feature has been enabled. This ``__future__`` import\n statement was used to enable the feature:\n\n from __future__ import generators\n\nSee also:\n\n **PEP 0255** - Simple Generators\n The proposal for adding generators and the ``yield`` statement\n to Python.\n\n **PEP 0342** - Coroutines via Enhanced Generators\n The proposal that, among other generator enhancements, proposed\n allowing ``yield`` to appear inside a ``try`` ... ``finally``\n block.\n'} Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Tue Apr 14 15:16:19 2009 @@ -4,6 +4,12 @@ (editors: check NEWS.help for information about editing NEWS using ReST.) +What's New in Python 2.6.2 +========================== + +*Release date: 14-Apr-2009* + + What's New in Python 2.6.2 rc 1 =============================== Modified: python/branches/release26-maint/Misc/RPM/python-2.6.spec ============================================================================== --- python/branches/release26-maint/Misc/RPM/python-2.6.spec (original) +++ python/branches/release26-maint/Misc/RPM/python-2.6.spec Tue Apr 14 15:16:19 2009 @@ -34,7 +34,7 @@ %define name python #--start constants-- -%define version 2.6.2c1 +%define version 2.6.2 %define libver 2.6 #--end constants-- %define release 1pydotorg From python-checkins at python.org Tue Apr 14 15:17:30 2009 From: python-checkins at python.org (barry.warsaw) Date: Tue, 14 Apr 2009 15:17:30 +0200 (CEST) Subject: [Python-checkins] r71601 - python/tags/r262 Message-ID: <20090414131730.A8B6F1E4018@bag.python.org> Author: barry.warsaw Date: Tue Apr 14 15:17:30 2009 New Revision: 71601 Log: Tagging 2.6.2 (final) Added: python/tags/r262/ - copied from r71600, /python/branches/release26-maint/ From buildbot at python.org Tue Apr 14 15:38:28 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 14 Apr 2009 13:38:28 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 2.6 Message-ID: <20090414133828.535891E401D@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%202.6/builds/251 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: barry.warsaw BUILD FAILED: failed test Excerpt from the test logfile: Traceback (most recent call last): File "/home/pybot/buildarea/2.6.klose-ubuntu-i386/build/Lib/test/test_signal.py", line 165, in test_main pickle.dump(None, done_w) File "/home/pybot/buildarea/2.6.klose-ubuntu-i386/build/Lib/contextlib.py", line 153, in __exit__ self.thing.close() IOError: [Errno 9] Bad file descriptor 1 test failed: test_signal make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Tue Apr 14 16:47:30 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 14 Apr 2009 14:47:30 +0000 Subject: [Python-checkins] buildbot failure in x86 XP-4 2.6 Message-ID: <20090414144730.B55131E401D@bag.python.org> The Buildbot has detected a new failure of x86 XP-4 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20XP-4%202.6/builds/194 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: bolen-windows Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: barry.warsaw BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_bsddb3 ====================================================================== ERROR: test01_badpointer (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 21, in test01_badpointer dbs = dbshelve.open(self.filename) File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\dbshelve.py", line 106, in open d.open(filename, dbname, filetype, flags, mode) File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\dbshelve.py", line 171, in open self.db.open(*args, **kwargs) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test03_repr_closed_db (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 37, in test03_repr_closed_db db = hashopen(self.filename) File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\__init__.py", line 361, in hashopen d.open(file, db.DB_HASH, flags, mode) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test04_repr_db (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 43, in test04_repr_db db = hashopen(self.filename) File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\__init__.py", line 361, in hashopen d.open(file, db.DB_HASH, flags, mode) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test05_double_free_make_key_dbt (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 65, in test05_double_free_make_key_dbt db.DB_CREATE | db.DB_THREAD) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test06_key_with_null_bytes (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 77, in test06_key_with_null_bytes db1.open(self.filename, None, db.DB_HASH, db.DB_CREATE) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test07_DB_set_flags_persists (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 101, in test07_DB_set_flags_persists db1.open(self.filename, db.DB_HASH, db.DB_CREATE) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') sincerely, -The Buildbot From python-checkins at python.org Tue Apr 14 17:50:37 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 14 Apr 2009 17:50:37 +0200 (CEST) Subject: [Python-checkins] r71602 - in python/branches/py3k-short-float-repr: Python/dtoa.c configure configure.in pyconfig.h.in Message-ID: <20090414155037.9F6AC1E4025@bag.python.org> Author: mark.dickinson Date: Tue Apr 14 17:50:37 2009 New Revision: 71602 Log: Add support for ARM mixed-endian doubles Modified: python/branches/py3k-short-float-repr/Python/dtoa.c python/branches/py3k-short-float-repr/configure python/branches/py3k-short-float-repr/configure.in python/branches/py3k-short-float-repr/pyconfig.h.in Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Tue Apr 14 17:50:37 2009 @@ -115,7 +115,8 @@ #ifdef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 #define IEEE_8087 #endif -#ifdef DOUBLE_IS_BIG_ENDIAN_IEEE754 + +#if defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) || defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754) #define IEEE_MC68k #endif #if defined(IEEE_8087) + defined(IEEE_MC68k) != 1 Modified: python/branches/py3k-short-float-repr/configure ============================================================================== --- python/branches/py3k-short-float-repr/configure (original) +++ python/branches/py3k-short-float-repr/configure Tue Apr 14 17:50:37 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 71321 . +# From configure.in Revision: 71576 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.1. # @@ -21751,6 +21751,82 @@ fi +# Some ARM platforms use a mixed-endian representation for doubles. +# While Python doesn't currently have full support for these platforms +# (see e.g., issue 1762561), we can at least make sure that float <-> string +# conversions work. +{ echo "$as_me:$LINENO: checking whether C doubles are ARM mixed-endian IEEE 754 binary64" >&5 +echo $ECHO_N "checking whether C doubles are ARM mixed-endian IEEE 754 binary64... $ECHO_C" >&6; } +if test "${ac_cv_mixed_endian_double+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +if test "$cross_compiling" = yes; then + ac_cv_mixed_endian_double=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +int main() { + double x = 9006104071832581.0; + if (memcmp(&x, "\x01\xff\x3f\x43\x05\x04\x03\x02", 8) == 0) + return 0; + else + return 1; +} + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_mixed_endian_double=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_mixed_endian_double=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi + +{ echo "$as_me:$LINENO: result: $ac_cv_mixed_endian_double" >&5 +echo "${ECHO_T}$ac_cv_mixed_endian_double" >&6; } +if test "$ac_cv_mixed_endian_double" = yes +then + +cat >>confdefs.h <<\_ACEOF +#define DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 1 +_ACEOF + +fi + # David Gay's code in Python/dtoa.c requires that the FPU uses 53-bit # rounding; this is a particular problem on x86, where the x87 FPU has # a default rounding precision of 64 bits. For gcc/x86, we try to fix Modified: python/branches/py3k-short-float-repr/configure.in ============================================================================== --- python/branches/py3k-short-float-repr/configure.in (original) +++ python/branches/py3k-short-float-repr/configure.in Tue Apr 14 17:50:37 2009 @@ -3115,6 +3115,33 @@ with the most significant byte first]) fi +# Some ARM platforms use a mixed-endian representation for doubles. +# While Python doesn't currently have full support for these platforms +# (see e.g., issue 1762561), we can at least make sure that float <-> string +# conversions work. +AC_MSG_CHECKING(whether C doubles are ARM mixed-endian IEEE 754 binary64) +AC_CACHE_VAL(ac_cv_mixed_endian_double, [ +AC_TRY_RUN([ +#include +int main() { + double x = 9006104071832581.0; + if (memcmp(&x, "\x01\xff\x3f\x43\x05\x04\x03\x02", 8) == 0) + return 0; + else + return 1; +} +], +ac_cv_mixed_endian_double=yes, +ac_cv_mixed_endian_double=no, +ac_cv_mixed_endian_double=no)]) +AC_MSG_RESULT($ac_cv_mixed_endian_double) +if test "$ac_cv_mixed_endian_double" = yes +then + AC_DEFINE(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754, 1, + [Define if C doubles are 64-bit IEEE 754 binary format, stored + in ARM mixed-endian order (byte order 45670123)]) +fi + # David Gay's code in Python/dtoa.c requires that the FPU uses 53-bit # rounding; this is a particular problem on x86, where the x87 FPU has # a default rounding precision of 64 bits. For gcc/x86, we try to fix Modified: python/branches/py3k-short-float-repr/pyconfig.h.in ============================================================================== --- python/branches/py3k-short-float-repr/pyconfig.h.in (original) +++ python/branches/py3k-short-float-repr/pyconfig.h.in Tue Apr 14 17:50:37 2009 @@ -15,6 +15,10 @@ /* Define if you have the Mach cthreads package */ #undef C_THREADS +/* Define if C doubles are 64-bit IEEE 754 binary format, stored in ARM + mixed-endian order (byte order 45670123) */ +#undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 + /* Define if C doubles are 64-bit IEEE 754 binary format, stored with the most significant byte first */ #undef DOUBLE_IS_BIG_ENDIAN_IEEE754 From python-checkins at python.org Tue Apr 14 18:00:42 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 14 Apr 2009 18:00:42 +0200 (CEST) Subject: [Python-checkins] r71603 - in python/branches/py3k-short-float-repr: Python/dtoa.c configure Message-ID: <20090414160042.0FCAF1E401E@bag.python.org> Author: mark.dickinson Date: Tue Apr 14 18:00:41 2009 New Revision: 71603 Log: Fix endianness detection for universal builds on OS X. Modified: python/branches/py3k-short-float-repr/Python/dtoa.c python/branches/py3k-short-float-repr/configure Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Tue Apr 14 18:00:41 2009 @@ -112,12 +112,24 @@ #define MALLOC PyMem_Malloc #define FREE PyMem_Free -#ifdef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 -#define IEEE_8087 -#endif - -#if defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) || defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754) -#define IEEE_MC68k +/* For Apple universal PPC/Intel builds, the autoconf result will be reporting + the wrong endianness for one of the architectures. Use a different + method for determining endianness of doubles. +*/ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define IEEE_MC68k +# else +# define IEEE_8087 +# endif +#else +# ifdef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 +# define IEEE_8087 +# endif +# if defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) || \ + defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754) +# define IEEE_MC68k +# endif #endif #if defined(IEEE_8087) + defined(IEEE_MC68k) != 1 #error "Exactly one of IEEE_8087 or IEEE_MC68k should be defined." Modified: python/branches/py3k-short-float-repr/configure ============================================================================== --- python/branches/py3k-short-float-repr/configure (original) +++ python/branches/py3k-short-float-repr/configure Tue Apr 14 18:00:41 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 71576 . +# From configure.in Revision: 71602 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.1. # From python-checkins at python.org Tue Apr 14 19:21:15 2009 From: python-checkins at python.org (eric.smith) Date: Tue, 14 Apr 2009 19:21:15 +0200 (CEST) Subject: [Python-checkins] r71604 - python/branches/py3k-short-float-repr/Objects/stringlib/localeutil.h Message-ID: <20090414172115.05EFF1E4014@bag.python.org> Author: eric.smith Date: Tue Apr 14 19:21:14 2009 New Revision: 71604 Log: Silence compiler warning. Modified: python/branches/py3k-short-float-repr/Objects/stringlib/localeutil.h Modified: python/branches/py3k-short-float-repr/Objects/stringlib/localeutil.h ============================================================================== --- python/branches/py3k-short-float-repr/Objects/stringlib/localeutil.h (original) +++ python/branches/py3k-short-float-repr/Objects/stringlib/localeutil.h Tue Apr 14 19:21:14 2009 @@ -125,7 +125,7 @@ separator. They only go between groups. */ STRINGLIB_CHAR *buffer_end = NULL; - STRINGLIB_CHAR *digits_end; + STRINGLIB_CHAR *digits_end = NULL; Py_ssize_t l; Py_ssize_t n_chars; Py_ssize_t thousands_sep_len = strlen(thousands_sep); From python-checkins at python.org Tue Apr 14 21:41:49 2009 From: python-checkins at python.org (mark.dickinson) Date: Tue, 14 Apr 2009 21:41:49 +0200 (CEST) Subject: [Python-checkins] r71605 - in python/branches/py3k-short-float-repr: Include/pymacconfig.h Python/dtoa.c Message-ID: <20090414194149.424051E431C@bag.python.org> Author: mark.dickinson Date: Tue Apr 14 21:41:49 2009 New Revision: 71605 Log: Fix endianness detection for universal builds again (previous fix was bogus, as well as being in the wrong place). Add check that integer endianness matches double endianness Modified: python/branches/py3k-short-float-repr/Include/pymacconfig.h python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Include/pymacconfig.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/pymacconfig.h (original) +++ python/branches/py3k-short-float-repr/Include/pymacconfig.h Tue Apr 14 21:41:49 2009 @@ -17,6 +17,9 @@ # undef SIZEOF_VOID_P # undef SIZEOF__BOOL # undef WORDS_BIGENDIAN +# undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 +# undef DOUBLE_IS_BIG_ENDIAN_IEEE754 +# undef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 # undef VA_LIST_IS_ARRAY # if defined(__LP64__) && defined(__x86_64__) @@ -65,6 +68,9 @@ #ifdef __BIG_ENDIAN__ #define WORDS_BIGENDIAN 1 +#define DOUBLE_IS_BIG_ENDIAN_IEEE754 +#else +#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 #endif /* __BIG_ENDIAN */ Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Tue Apr 14 21:41:49 2009 @@ -112,29 +112,32 @@ #define MALLOC PyMem_Malloc #define FREE PyMem_Free -/* For Apple universal PPC/Intel builds, the autoconf result will be reporting - the wrong endianness for one of the architectures. Use a different - method for determining endianness of doubles. -*/ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define IEEE_MC68k -# else -# define IEEE_8087 -# endif -#else -# ifdef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 -# define IEEE_8087 -# endif -# if defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) || \ - defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754) -# define IEEE_MC68k -# endif +/* This code should also work for ARM mixed-endian format on little-endian + machines, where doubles have byte order 45670123 (in increasing address + order, 0 being the least significant byte). */ +#ifdef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 +# define IEEE_8087 +#endif +#if defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) || \ + defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754) +# define IEEE_MC68k #endif #if defined(IEEE_8087) + defined(IEEE_MC68k) != 1 #error "Exactly one of IEEE_8087 or IEEE_MC68k should be defined." #endif +/* The code below assumes that the endianness of integers matches the + endianness of the two 32-bit words of a double. Check this. */ +#if defined(WORDS_BIGENDIAN) && (defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) || \ + defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754)) +#error "doubles and ints have incompatible endianness" +#endif + +#if !defined(WORDS_BIGENDIAN) && defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) +#error "doubles and ints have incompatible endianness" +#endif + + #if defined(HAVE_UINT32_T) && defined(HAVE_INT32_T) typedef PY_UINT32_T ULong; typedef PY_INT32_T Long; From python-checkins at python.org Tue Apr 14 22:45:17 2009 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 14 Apr 2009 22:45:17 +0200 (CEST) Subject: [Python-checkins] r71606 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090414204517.D63691E4014@bag.python.org> Author: raymond.hettinger Date: Tue Apr 14 22:45:17 2009 New Revision: 71606 Log: Fix links Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Tue Apr 14 22:45:17 2009 @@ -103,7 +103,7 @@ .. seealso:: :pep:`378` - Format Specifier for Thousands Separator - PEP written by Raymond Hettinger; implemented by Eric Smith and + PEP written by Raymond Hettinger and implemented by Eric Smith and Mark Dickinson. @@ -279,7 +279,8 @@ def test_gimzo_without_required_library(self): ... - Also, tests for exceptions have been builtout to work with context managers:: + Also, tests for exceptions have been builtout to work with context managers + using the :keyword:`with` statement:: def test_division_by_zero(self): with self.assertRaises(ZeroDivisionError): @@ -305,7 +306,7 @@ (Contributed by Ross Light; :issue:`4285`.) * A new module, :mod:`importlib` was added. It provides a complete, portable, - pure Python reference implementation of the *import* statement and its + pure Python reference implementation of the :keyword:`import` statement and its counterpart, the :func:`__import__` function. It represents a substantial step forward in documenting and defining the actions that take place during imports. From python-checkins at python.org Tue Apr 14 23:23:09 2009 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 14 Apr 2009 23:23:09 +0200 (CEST) Subject: [Python-checkins] r71607 - python/trunk/Doc/library/turtle.rst Message-ID: <20090414212309.AF5081E4014@bag.python.org> Author: benjamin.peterson Date: Tue Apr 14 23:23:09 2009 New Revision: 71607 Log: tupel -> tuple Modified: python/trunk/Doc/library/turtle.rst Modified: python/trunk/Doc/library/turtle.rst ============================================================================== --- python/trunk/Doc/library/turtle.rst (original) +++ python/trunk/Doc/library/turtle.rst Tue Apr 14 23:23:09 2009 @@ -1244,9 +1244,9 @@ .. function:: screensize(canvwidth=None, canvheight=None, bg=None) - :param canvwidth: positive integer, new width of canvas in pixels - :param canvheight: positive integer, new height of canvas in pixels - :param bg: colorstring or color-tupel, new background color + :param canvwidth: positive integer, new width of canvas in pixels :param + canvheight: positive integer, new height of canvas in pixels :param bg: + colorstring or color-tuple, new background color If no arguments are given, return current (canvaswidth, canvasheight). Else resize the canvas the turtles are drawing on. Do not alter the drawing From python-checkins at python.org Wed Apr 15 00:02:09 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 15 Apr 2009 00:02:09 +0200 (CEST) Subject: [Python-checkins] r71608 - python/branches/py3k/Lib/_pyio.py Message-ID: <20090414220209.0B02E1E4014@bag.python.org> Author: benjamin.peterson Date: Wed Apr 15 00:02:08 2009 New Revision: 71608 Log: other places like this just catch IOError Modified: python/branches/py3k/Lib/_pyio.py Modified: python/branches/py3k/Lib/_pyio.py ============================================================================== --- python/branches/py3k/Lib/_pyio.py (original) +++ python/branches/py3k/Lib/_pyio.py Wed Apr 15 00:02:08 2009 @@ -1438,7 +1438,7 @@ def close(self): try: self.flush() - except: + except IOError: pass # If flush() fails, just give up self.buffer.close() From buildbot at python.org Wed Apr 15 00:07:10 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 14 Apr 2009 22:07:10 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090414220710.D085C1E4014@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/584 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson,raymond.hettinger BUILD FAILED: failed svn sincerely, -The Buildbot From buildbot at python.org Wed Apr 15 00:54:06 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 14 Apr 2009 22:54:06 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo trunk Message-ID: <20090414225406.E951C1E4014@bag.python.org> The Buildbot has detected a new failure of x86 gentoo trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%20trunk/builds/4825 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: The web-page 'force build' button was pressed by 'Mark Dickinson': Test short-float-repr branch Build Source Stamp: [branch branches/py3k-short-float-repr] HEAD Blamelist: BUILD FAILED: failed compile sincerely, -The Buildbot From stackless-checkins-bounces at stackless.com Wed Apr 15 03:16:54 2009 From: stackless-checkins-bounces at stackless.com (stackless-checkins-bounces at stackless.com) Date: Wed, 15 Apr 2009 03:16:54 +0200 Subject: [Python-checkins] Your message to Stackless-checkins awaits moderator approval Message-ID: Your mail to 'Stackless-checkins' with the subject r71609 - in stackless/branches/release26-maint: Doc/distutils/examples.rst Doc/library/email.message.rst Doc/library/itertools.rst Doc/tools/sphinxext/pyspecific.py Doc/tools/sphinxext/static/basic.css Include/patchlevel.h Lib/ConfigParser.py Lib/distutils/__init__.py Lib/distutils/command/bdist_wininst.py Lib/distutils/tests/test_bdist_wininst.py Lib/idlelib/idlever.py Lib/pydoc.py Lib/pydoc_topics.py Lib/test/test_cfgparser.py Misc/NEWS Misc/RPM/python-2.6.spec Objects/stringlib/formatter.h Is being held until the list moderator can review it for approval. The reason it is being held: Message body is too big: 606095 bytes with a limit of 500 KB Either the message will get posted to the list, or you will receive notification of the moderator's decision. If you would like to cancel this posting, please visit the following URL: http://www.stackless.com/mailman/confirm/stackless-checkins/f615b3af7a782c4dd1c5652556d5c7bf80944bf6 From nnorwitz at gmail.com Wed Apr 15 10:11:11 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 15 Apr 2009 04:11:11 -0400 Subject: [Python-checkins] Python Regression Test Failures basics (1) Message-ID: <20090415081111.GA24974@python.psfb.org> 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23366 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 test_lib2to3 failed -- errors occurred; run in verbose mode for details 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 -- OSError raises on RLock creation, see issue 3111! test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18902 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [742041 refs] From nnorwitz at gmail.com Wed Apr 15 10:19:03 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 15 Apr 2009 04:19:03 -0400 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20090415081903.GA27409@python.psfb.org> 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils [17363 refs] [17363 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23366 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 test_lib2to3 failed -- errors occurred; run in verbose mode for details 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 -- OSError raises on RLock creation, see issue 3111! test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18902 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [741281 refs] From python-checkins at python.org Wed Apr 15 11:00:44 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 15 Apr 2009 11:00:44 +0200 (CEST) Subject: [Python-checkins] r71611 - in python/branches/py3k-short-float-repr: configure configure.in Message-ID: <20090415090044.6D42B1E4398@bag.python.org> Author: mark.dickinson Date: Wed Apr 15 11:00:44 2009 New Revision: 71611 Log: Temporary checkin to get more information out of some of the buildbots Modified: python/branches/py3k-short-float-repr/configure python/branches/py3k-short-float-repr/configure.in Modified: python/branches/py3k-short-float-repr/configure ============================================================================== --- python/branches/py3k-short-float-repr/configure (original) +++ python/branches/py3k-short-float-repr/configure Wed Apr 15 11:00:44 2009 @@ -4471,6 +4471,12 @@ # compiler and platform. BASECFLAGS tweaks need to be made even if the # user set OPT. +# tempory inclusion to output the system-specific defines that GCC knows +if test "$GCC" = yes +then + $CC -dM -E - Author: mark.dickinson Date: Wed Apr 15 11:12:08 2009 New Revision: 71612 Log: Add Ned Deily to Misc/ACKS, for all the help he's given us with the py3k-short-float-repr branch Modified: python/branches/py3k-short-float-repr/Misc/ACKS Modified: python/branches/py3k-short-float-repr/Misc/ACKS ============================================================================== --- python/branches/py3k-short-float-repr/Misc/ACKS (original) +++ python/branches/py3k-short-float-repr/Misc/ACKS Wed Apr 15 11:12:08 2009 @@ -160,6 +160,7 @@ Ben Darnell Jonathan Dasteel John DeGood +Ned Deily Vincent Delft Arnaud Delobelle Erik Demaine From python-checkins at python.org Wed Apr 15 12:38:36 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 15 Apr 2009 12:38:36 +0200 (CEST) Subject: [Python-checkins] r71613 - in python/branches/py3k-short-float-repr: configure configure.in Message-ID: <20090415103836.07E1E1E4114@bag.python.org> Author: mark.dickinson Date: Wed Apr 15 12:38:35 2009 New Revision: 71613 Log: Add autoconf test that uses the cpuid instruction to detect whether the CPU supports SSE/SSE2, for gcc/x86. Modified: python/branches/py3k-short-float-repr/configure python/branches/py3k-short-float-repr/configure.in Modified: python/branches/py3k-short-float-repr/configure ============================================================================== --- python/branches/py3k-short-float-repr/configure (original) +++ python/branches/py3k-short-float-repr/configure Wed Apr 15 12:38:35 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 71602 . +# From configure.in Revision: 71611 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.1. # @@ -21845,6 +21845,73 @@ if test "$GCC" = yes && test -n "`$CC -dM -E - &5 +echo $ECHO_N "checking whether SSE2 instructions are available on this CPU... $ECHO_C" >&6; } + if test "$cross_compiling" = yes; then + ac_cv_cpu_has_sse2=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + int main() { + unsigned int ax, bx, cx, dx, func; + func = 1U; + __asm__ __volatile__ ("pushl %%ebx\n\t" /* don't clobber ebx */ + "cpuid\n\t" + "movl %%ebx, %1\n\t" + "popl %%ebx" + : "=a" (ax), "=r" (bx), "=c" (cx), "=d" (dx) + : "a" (func)); + if ((dx & (1U << 26)) && (dx & (1U << 25))) + return 0; + else + return 1; + } + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_cpu_has_sse2=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_cpu_has_sse2=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + { echo "$as_me:$LINENO: result: $ac_cv_cpu_has_sse2" >&5 +echo "${ECHO_T}$ac_cv_cpu_has_sse2" >&6; } + # determine whether we're already using the SSE2 instruction set for math { echo "$as_me:$LINENO: checking whether SSE2 instructions are already enabled for math" >&5 echo $ECHO_N "checking whether SSE2 instructions are already enabled for math... $ECHO_C" >&6; } Modified: python/branches/py3k-short-float-repr/configure.in ============================================================================== --- python/branches/py3k-short-float-repr/configure.in (original) +++ python/branches/py3k-short-float-repr/configure.in Wed Apr 15 12:38:35 2009 @@ -3160,6 +3160,31 @@ if test "$GCC" = yes && test -n "`$CC -dM -E - Author: mark.dickinson Date: Wed Apr 15 13:18:34 2009 New Revision: 71614 Log: Refactor SSE2 detection in configure script, and link everything up so that we don't try to use SSE2 instructions on platforms where they don't exist. Modified: python/branches/py3k-short-float-repr/configure python/branches/py3k-short-float-repr/configure.in Modified: python/branches/py3k-short-float-repr/configure ============================================================================== --- python/branches/py3k-short-float-repr/configure (original) +++ python/branches/py3k-short-float-repr/configure Wed Apr 15 13:18:34 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 71611 . +# From configure.in Revision: 71613 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.1. # @@ -21842,15 +21842,35 @@ # on modern machines) # (2) using inline assembler to get and set the x87 FPU control word # otherwise. +# +# On AMD64 (aka x86-64), gcc automatically enables use of SSE2 +# instructions, so we don't bother trying to detect. if test "$GCC" = yes && test -n "`$CC -dM -E - &5 + # determine whether we're already using the SSE2 instruction set for math + # (e.g., this is true by default on OS X/x86) + { echo "$as_me:$LINENO: checking whether SSE2 instructions are already enabled for math" >&5 +echo $ECHO_N "checking whether SSE2 instructions are already enabled for math... $ECHO_C" >&6; } + if [ "`$CC -dM -E - &5 +echo "${ECHO_T}$ac_sse2_enabled" >&6; } + + # if we're not using SSE2 already, we need to either enable it + # (when available), or use inline assembler to get and set the + # 387 control word. + if test $ac_sse2_enabled = no + then + # Check cpuid for SSE2 availability. Bits 25 and 26 of edx tell + # us about SSE and SSE2 respectively. + { echo "$as_me:$LINENO: checking whether SSE2 instructions are available on this CPU" >&5 echo $ECHO_N "checking whether SSE2 instructions are available on this CPU... $ECHO_C" >&6; } - if test "$cross_compiling" = yes; then + if test "$cross_compiling" = yes; then ac_cv_cpu_has_sse2=no else cat >conftest.$ac_ext <<_ACEOF @@ -21860,20 +21880,22 @@ cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ - int main() { - unsigned int ax, bx, cx, dx, func; - func = 1U; - __asm__ __volatile__ ("pushl %%ebx\n\t" /* don't clobber ebx */ - "cpuid\n\t" - "movl %%ebx, %1\n\t" - "popl %%ebx" - : "=a" (ax), "=r" (bx), "=c" (cx), "=d" (dx) - : "a" (func)); - if ((dx & (1U << 26)) && (dx & (1U << 25))) - return 0; - else - return 1; - } + int main() { + unsigned int ax, bx, cx, dx, func; + func = 1U; + __asm__ __volatile__ ( + "pushl %%ebx\n\t" /* don't clobber ebx */ + "cpuid\n\t" + "movl %%ebx, %1\n\t" + "popl %%ebx" + : "=a" (ax), "=r" (bx), "=c" (cx), "=d" (dx) + : "a" (func) + : "cc" ); + if ((dx & (1U << 25)) && (dx & (1U << 26))) + return 0; + else + return 1; + } _ACEOF rm -f conftest$ac_exeext @@ -21909,24 +21931,10 @@ fi - { echo "$as_me:$LINENO: result: $ac_cv_cpu_has_sse2" >&5 + { echo "$as_me:$LINENO: result: $ac_cv_cpu_has_sse2" >&5 echo "${ECHO_T}$ac_cv_cpu_has_sse2" >&6; } - # determine whether we're already using the SSE2 instruction set for math - { echo "$as_me:$LINENO: checking whether SSE2 instructions are already enabled for math" >&5 -echo $ECHO_N "checking whether SSE2 instructions are already enabled for math... $ECHO_C" >&6; } - if [ "`$CC -dM -E - &5 -echo "${ECHO_T}$ac_sse2_enabled" >&6; } - - # if not, try using gcc options to enable it - if test $ac_sse2_enabled = no - then + # determine whether gcc accepts options to turn on SSE2 { echo "$as_me:$LINENO: checking whether $CC accepts -msse2 -mfpmath=sse" >&5 echo $ECHO_N "checking whether $CC accepts -msse2 -mfpmath=sse... $ECHO_C" >&6; } ac_save_cc="$CC" @@ -21979,17 +21987,17 @@ { echo "$as_me:$LINENO: result: $ac_cv_msse2_ok" >&5 echo "${ECHO_T}$ac_cv_msse2_ok" >&6; } - if test $ac_cv_msse2_ok = yes + if test $ac_cv_cpu_has_sse2 = yes && test $ac_cv_msse2_ok = yes then BASECFLAGS="$BASECFLAGS -msse2 -mfpmath=sse" else + # SSE2 doesn't appear to be available. Check that it's okay + # to use gcc inline assembler to get and set x87 control word cat >>confdefs.h <<\_ACEOF #define USING_X87_FPU 1 _ACEOF - # SSE2 doesn't appear to be available. Check that it's okay - # to use gcc inline assembler to get and set x87 control word { echo "$as_me:$LINENO: checking whether we can use gcc inline assembler to get and set x87 control word" >&5 echo $ECHO_N "checking whether we can use gcc inline assembler to get and set x87 control word... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF Modified: python/branches/py3k-short-float-repr/configure.in ============================================================================== --- python/branches/py3k-short-float-repr/configure.in (original) +++ python/branches/py3k-short-float-repr/configure.in Wed Apr 15 13:18:34 2009 @@ -3157,35 +3157,14 @@ # on modern machines) # (2) using inline assembler to get and set the x87 FPU control word # otherwise. +# +# On AMD64 (aka x86-64), gcc automatically enables use of SSE2 +# instructions, so we don't bother trying to detect. if test "$GCC" = yes && test -n "`$CC -dM -E - Author: mark.dickinson Date: Wed Apr 15 13:32:20 2009 New Revision: 71615 Log: Temporary checkin: rename test_os to _test_os, to allow gentoo buildbot tests to run to completion. Added: python/branches/py3k-short-float-repr/Lib/test/_test_os.py - copied unchanged from r71610, /python/branches/py3k-short-float-repr/Lib/test/test_os.py Removed: python/branches/py3k-short-float-repr/Lib/test/test_os.py Deleted: python/branches/py3k-short-float-repr/Lib/test/test_os.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_os.py Wed Apr 15 13:32:20 2009 +++ (empty file) @@ -1,721 +0,0 @@ -# As a test suite for the os module, this is woefully inadequate, but this -# does add tests for a few functions which have been determined to be more -# portable than they had been thought to be. - -import os -import errno -import unittest -import warnings -import sys -from test import support - -# Tests creating TESTFN -class FileTests(unittest.TestCase): - def setUp(self): - if os.path.exists(support.TESTFN): - os.unlink(support.TESTFN) - tearDown = setUp - - def test_access(self): - f = os.open(support.TESTFN, os.O_CREAT|os.O_RDWR) - os.close(f) - self.assert_(os.access(support.TESTFN, os.W_OK)) - - def test_closerange(self): - first = os.open(support.TESTFN, os.O_CREAT|os.O_RDWR) - # We must allocate two consecutive file descriptors, otherwise - # it will mess up other file descriptors (perhaps even the three - # standard ones). - second = os.dup(first) - try: - retries = 0 - while second != first + 1: - os.close(first) - retries += 1 - if retries > 10: - # XXX test skipped - print("couldn't allocate two consecutive fds, " - "skipping test_closerange", file=sys.stderr) - return - first, second = second, os.dup(second) - finally: - os.close(second) - # close a fd that is open, and one that isn't - os.closerange(first, first + 2) - self.assertRaises(OSError, os.write, first, b"a") - - def test_rename(self): - path = support.TESTFN - old = sys.getrefcount(path) - self.assertRaises(TypeError, os.rename, path, 0) - new = sys.getrefcount(path) - self.assertEqual(old, new) - - def test_read(self): - with open(support.TESTFN, "w+b") as fobj: - fobj.write(b"spam") - fobj.flush() - fd = fobj.fileno() - os.lseek(fd, 0, 0) - s = os.read(fd, 4) - self.assertEqual(type(s), bytes) - self.assertEqual(s, b"spam") - - def test_write(self): - # os.write() accepts bytes- and buffer-like objects but not strings - fd = os.open(support.TESTFN, os.O_CREAT | os.O_WRONLY) - self.assertRaises(TypeError, os.write, fd, "beans") - os.write(fd, b"bacon\n") - os.write(fd, bytearray(b"eggs\n")) - os.write(fd, memoryview(b"spam\n")) - os.close(fd) - with open(support.TESTFN, "rb") as fobj: - self.assertEqual(fobj.read().splitlines(), - [b"bacon", b"eggs", b"spam"]) - - -class TemporaryFileTests(unittest.TestCase): - def setUp(self): - self.files = [] - os.mkdir(support.TESTFN) - - def tearDown(self): - for name in self.files: - os.unlink(name) - os.rmdir(support.TESTFN) - - def check_tempfile(self, name): - # make sure it doesn't already exist: - self.failIf(os.path.exists(name), - "file already exists for temporary file") - # make sure we can create the file - open(name, "w") - self.files.append(name) - - def test_tempnam(self): - if not hasattr(os, "tempnam"): - return - warnings.filterwarnings("ignore", "tempnam", RuntimeWarning, - r"test_os$") - self.check_tempfile(os.tempnam()) - - name = os.tempnam(support.TESTFN) - self.check_tempfile(name) - - name = os.tempnam(support.TESTFN, "pfx") - self.assert_(os.path.basename(name)[:3] == "pfx") - self.check_tempfile(name) - - def test_tmpfile(self): - if not hasattr(os, "tmpfile"): - return - # As with test_tmpnam() below, the Windows implementation of tmpfile() - # attempts to create a file in the root directory of the current drive. - # On Vista and Server 2008, this test will always fail for normal users - # as writing to the root directory requires elevated privileges. With - # XP and below, the semantics of tmpfile() are the same, but the user - # running the test is more likely to have administrative privileges on - # their account already. If that's the case, then os.tmpfile() should - # work. In order to make this test as useful as possible, rather than - # trying to detect Windows versions or whether or not the user has the - # right permissions, just try and create a file in the root directory - # and see if it raises a 'Permission denied' OSError. If it does, then - # test that a subsequent call to os.tmpfile() raises the same error. If - # it doesn't, assume we're on XP or below and the user running the test - # has administrative privileges, and proceed with the test as normal. - if sys.platform == 'win32': - name = '\\python_test_os_test_tmpfile.txt' - if os.path.exists(name): - os.remove(name) - try: - fp = open(name, 'w') - except IOError as first: - # open() failed, assert tmpfile() fails in the same way. - # Although open() raises an IOError and os.tmpfile() raises an - # OSError(), 'args' will be (13, 'Permission denied') in both - # cases. - try: - fp = os.tmpfile() - except OSError as second: - self.assertEqual(first.args, second.args) - else: - self.fail("expected os.tmpfile() to raise OSError") - return - else: - # open() worked, therefore, tmpfile() should work. Close our - # dummy file and proceed with the test as normal. - fp.close() - os.remove(name) - - fp = os.tmpfile() - fp.write("foobar") - fp.seek(0,0) - s = fp.read() - fp.close() - self.assert_(s == "foobar") - - def test_tmpnam(self): - import sys - if not hasattr(os, "tmpnam"): - return - warnings.filterwarnings("ignore", "tmpnam", RuntimeWarning, - r"test_os$") - name = os.tmpnam() - if sys.platform in ("win32",): - # The Windows tmpnam() seems useless. From the MS docs: - # - # The character string that tmpnam creates consists of - # the path prefix, defined by the entry P_tmpdir in the - # file STDIO.H, followed by a sequence consisting of the - # digit characters '0' through '9'; the numerical value - # of this string is in the range 1 - 65,535. Changing the - # definitions of L_tmpnam or P_tmpdir in STDIO.H does not - # change the operation of tmpnam. - # - # The really bizarre part is that, at least under MSVC6, - # P_tmpdir is "\\". That is, the path returned refers to - # the root of the current drive. That's a terrible place to - # put temp files, and, depending on privileges, the user - # may not even be able to open a file in the root directory. - self.failIf(os.path.exists(name), - "file already exists for temporary file") - else: - self.check_tempfile(name) - - def fdopen_helper(self, *args): - fd = os.open(support.TESTFN, os.O_RDONLY) - fp2 = os.fdopen(fd, *args) - fp2.close() - - def test_fdopen(self): - self.fdopen_helper() - self.fdopen_helper('r') - self.fdopen_helper('r', 100) - -# Test attributes on return values from os.*stat* family. -class StatAttributeTests(unittest.TestCase): - def setUp(self): - os.mkdir(support.TESTFN) - self.fname = os.path.join(support.TESTFN, "f1") - f = open(self.fname, 'wb') - f.write(b"ABC") - f.close() - - def tearDown(self): - os.unlink(self.fname) - os.rmdir(support.TESTFN) - - def test_stat_attributes(self): - if not hasattr(os, "stat"): - return - - import stat - result = os.stat(self.fname) - - # Make sure direct access works - self.assertEquals(result[stat.ST_SIZE], 3) - self.assertEquals(result.st_size, 3) - - import sys - - # Make sure all the attributes are there - members = dir(result) - for name in dir(stat): - if name[:3] == 'ST_': - attr = name.lower() - if name.endswith("TIME"): - def trunc(x): return int(x) - else: - def trunc(x): return x - self.assertEquals(trunc(getattr(result, attr)), - result[getattr(stat, name)]) - self.assert_(attr in members) - - try: - result[200] - self.fail("No exception thrown") - except IndexError: - pass - - # Make sure that assignment fails - try: - result.st_mode = 1 - self.fail("No exception thrown") - except AttributeError: - pass - - try: - result.st_rdev = 1 - self.fail("No exception thrown") - except (AttributeError, TypeError): - pass - - try: - result.parrot = 1 - self.fail("No exception thrown") - except AttributeError: - pass - - # Use the stat_result constructor with a too-short tuple. - try: - result2 = os.stat_result((10,)) - self.fail("No exception thrown") - except TypeError: - pass - - # Use the constructr with a too-long tuple. - try: - result2 = os.stat_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)) - except TypeError: - pass - - - def test_statvfs_attributes(self): - if not hasattr(os, "statvfs"): - return - - try: - result = os.statvfs(self.fname) - except OSError as e: - # On AtheOS, glibc always returns ENOSYS - if e.errno == errno.ENOSYS: - return - - # Make sure direct access works - self.assertEquals(result.f_bfree, result[3]) - - # Make sure all the attributes are there. - members = ('bsize', 'frsize', 'blocks', 'bfree', 'bavail', 'files', - 'ffree', 'favail', 'flag', 'namemax') - for value, member in enumerate(members): - self.assertEquals(getattr(result, 'f_' + member), result[value]) - - # Make sure that assignment really fails - try: - result.f_bfree = 1 - self.fail("No exception thrown") - except AttributeError: - pass - - try: - result.parrot = 1 - self.fail("No exception thrown") - except AttributeError: - pass - - # Use the constructor with a too-short tuple. - try: - result2 = os.statvfs_result((10,)) - self.fail("No exception thrown") - except TypeError: - pass - - # Use the constructr with a too-long tuple. - try: - result2 = os.statvfs_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)) - except TypeError: - pass - - def test_utime_dir(self): - delta = 1000000 - st = os.stat(support.TESTFN) - # round to int, because some systems may support sub-second - # time stamps in stat, but not in utime. - os.utime(support.TESTFN, (st.st_atime, int(st.st_mtime-delta))) - st2 = os.stat(support.TESTFN) - self.assertEquals(st2.st_mtime, int(st.st_mtime-delta)) - - # Restrict test to Win32, since there is no guarantee other - # systems support centiseconds - if sys.platform == 'win32': - def get_file_system(path): - root = os.path.splitdrive(os.path.abspath(path))[0] + '\\' - import ctypes - kernel32 = ctypes.windll.kernel32 - buf = ctypes.create_unicode_buffer("", 100) - if kernel32.GetVolumeInformationW(root, None, 0, None, None, None, buf, len(buf)): - return buf.value - - if get_file_system(support.TESTFN) == "NTFS": - def test_1565150(self): - t1 = 1159195039.25 - os.utime(self.fname, (t1, t1)) - self.assertEquals(os.stat(self.fname).st_mtime, t1) - - def test_1686475(self): - # Verify that an open file can be stat'ed - try: - os.stat(r"c:\pagefile.sys") - except WindowsError as e: - if e.errno == 2: # file does not exist; cannot run test - return - self.fail("Could not stat pagefile.sys") - -from test import mapping_tests - -class EnvironTests(mapping_tests.BasicTestMappingProtocol): - """check that os.environ object conform to mapping protocol""" - type2test = None - - def setUp(self): - self.__save = dict(os.environ) - for key, value in self._reference().items(): - os.environ[key] = value - - def tearDown(self): - os.environ.clear() - os.environ.update(self.__save) - - def _reference(self): - return {"KEY1":"VALUE1", "KEY2":"VALUE2", "KEY3":"VALUE3"} - - def _empty_mapping(self): - os.environ.clear() - return os.environ - - # Bug 1110478 - def test_update2(self): - os.environ.clear() - if os.path.exists("/bin/sh"): - os.environ.update(HELLO="World") - value = os.popen("/bin/sh -c 'echo $HELLO'").read().strip() - self.assertEquals(value, "World") - - def test_os_popen_iter(self): - if os.path.exists("/bin/sh"): - popen = os.popen("/bin/sh -c 'echo \"line1\nline2\nline3\"'") - it = iter(popen) - self.assertEquals(next(it), "line1\n") - self.assertEquals(next(it), "line2\n") - self.assertEquals(next(it), "line3\n") - self.assertRaises(StopIteration, next, it) - - # Verify environ keys and values from the OS are of the - # correct str type. - def test_keyvalue_types(self): - for key, val in os.environ.items(): - self.assertEquals(type(key), str) - self.assertEquals(type(val), str) - - def test_items(self): - for key, value in self._reference().items(): - self.assertEqual(os.environ.get(key), value) - -class WalkTests(unittest.TestCase): - """Tests for os.walk().""" - - def test_traversal(self): - import os - from os.path import join - - # Build: - # TESTFN/ - # TEST1/ a file kid and two directory kids - # tmp1 - # SUB1/ a file kid and a directory kid - # tmp2 - # SUB11/ no kids - # SUB2/ a file kid and a dirsymlink kid - # tmp3 - # link/ a symlink to TESTFN.2 - # TEST2/ - # tmp4 a lone file - walk_path = join(support.TESTFN, "TEST1") - sub1_path = join(walk_path, "SUB1") - sub11_path = join(sub1_path, "SUB11") - sub2_path = join(walk_path, "SUB2") - tmp1_path = join(walk_path, "tmp1") - tmp2_path = join(sub1_path, "tmp2") - tmp3_path = join(sub2_path, "tmp3") - link_path = join(sub2_path, "link") - t2_path = join(support.TESTFN, "TEST2") - tmp4_path = join(support.TESTFN, "TEST2", "tmp4") - - # Create stuff. - os.makedirs(sub11_path) - os.makedirs(sub2_path) - os.makedirs(t2_path) - for path in tmp1_path, tmp2_path, tmp3_path, tmp4_path: - f = open(path, "w") - f.write("I'm " + path + " and proud of it. Blame test_os.\n") - f.close() - if hasattr(os, "symlink"): - os.symlink(os.path.abspath(t2_path), link_path) - sub2_tree = (sub2_path, ["link"], ["tmp3"]) - else: - sub2_tree = (sub2_path, [], ["tmp3"]) - - # Walk top-down. - all = list(os.walk(walk_path)) - self.assertEqual(len(all), 4) - # We can't know which order SUB1 and SUB2 will appear in. - # Not flipped: TESTFN, SUB1, SUB11, SUB2 - # flipped: TESTFN, SUB2, SUB1, SUB11 - flipped = all[0][1][0] != "SUB1" - all[0][1].sort() - self.assertEqual(all[0], (walk_path, ["SUB1", "SUB2"], ["tmp1"])) - self.assertEqual(all[1 + flipped], (sub1_path, ["SUB11"], ["tmp2"])) - self.assertEqual(all[2 + flipped], (sub11_path, [], [])) - self.assertEqual(all[3 - 2 * flipped], sub2_tree) - - # Prune the search. - all = [] - for root, dirs, files in os.walk(walk_path): - all.append((root, dirs, files)) - # Don't descend into SUB1. - if 'SUB1' in dirs: - # Note that this also mutates the dirs we appended to all! - dirs.remove('SUB1') - self.assertEqual(len(all), 2) - self.assertEqual(all[0], (walk_path, ["SUB2"], ["tmp1"])) - self.assertEqual(all[1], sub2_tree) - - # Walk bottom-up. - all = list(os.walk(walk_path, topdown=False)) - self.assertEqual(len(all), 4) - # We can't know which order SUB1 and SUB2 will appear in. - # Not flipped: SUB11, SUB1, SUB2, TESTFN - # flipped: SUB2, SUB11, SUB1, TESTFN - flipped = all[3][1][0] != "SUB1" - all[3][1].sort() - self.assertEqual(all[3], (walk_path, ["SUB1", "SUB2"], ["tmp1"])) - self.assertEqual(all[flipped], (sub11_path, [], [])) - self.assertEqual(all[flipped + 1], (sub1_path, ["SUB11"], ["tmp2"])) - self.assertEqual(all[2 - 2 * flipped], sub2_tree) - - if hasattr(os, "symlink"): - # Walk, following symlinks. - for root, dirs, files in os.walk(walk_path, followlinks=True): - if root == link_path: - self.assertEqual(dirs, []) - self.assertEqual(files, ["tmp4"]) - break - else: - self.fail("Didn't follow symlink with followlinks=True") - - def tearDown(self): - # Tear everything down. This is a decent use for bottom-up on - # Windows, which doesn't have a recursive delete command. The - # (not so) subtlety is that rmdir will fail unless the dir's - # kids are removed first, so bottom up is essential. - for root, dirs, files in os.walk(support.TESTFN, topdown=False): - for name in files: - os.remove(os.path.join(root, name)) - for name in dirs: - dirname = os.path.join(root, name) - if not os.path.islink(dirname): - os.rmdir(dirname) - else: - os.remove(dirname) - os.rmdir(support.TESTFN) - -class MakedirTests(unittest.TestCase): - def setUp(self): - os.mkdir(support.TESTFN) - - def test_makedir(self): - base = support.TESTFN - path = os.path.join(base, 'dir1', 'dir2', 'dir3') - os.makedirs(path) # Should work - path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4') - os.makedirs(path) - - # Try paths with a '.' in them - self.failUnlessRaises(OSError, os.makedirs, os.curdir) - path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4', 'dir5', os.curdir) - os.makedirs(path) - path = os.path.join(base, 'dir1', os.curdir, 'dir2', 'dir3', 'dir4', - 'dir5', 'dir6') - os.makedirs(path) - - def tearDown(self): - path = os.path.join(support.TESTFN, 'dir1', 'dir2', 'dir3', - 'dir4', 'dir5', 'dir6') - # If the tests failed, the bottom-most directory ('../dir6') - # may not have been created, so we look for the outermost directory - # that exists. - while not os.path.exists(path) and path != support.TESTFN: - path = os.path.dirname(path) - - os.removedirs(path) - -class DevNullTests(unittest.TestCase): - def test_devnull(self): - f = open(os.devnull, 'w') - f.write('hello') - f.close() - f = open(os.devnull, 'r') - self.assertEqual(f.read(), '') - f.close() - -class URandomTests(unittest.TestCase): - def test_urandom(self): - try: - self.assertEqual(len(os.urandom(1)), 1) - self.assertEqual(len(os.urandom(10)), 10) - self.assertEqual(len(os.urandom(100)), 100) - self.assertEqual(len(os.urandom(1000)), 1000) - except NotImplementedError: - pass - -class ExecTests(unittest.TestCase): - def test_execvpe_with_bad_program(self): - self.assertRaises(OSError, os.execvpe, 'no such app-', ['no such app-'], None) - - def test_execvpe_with_bad_arglist(self): - self.assertRaises(ValueError, os.execvpe, 'notepad', [], None) - -class Win32ErrorTests(unittest.TestCase): - def test_rename(self): - self.assertRaises(WindowsError, os.rename, support.TESTFN, support.TESTFN+".bak") - - def test_remove(self): - self.assertRaises(WindowsError, os.remove, support.TESTFN) - - def test_chdir(self): - self.assertRaises(WindowsError, os.chdir, support.TESTFN) - - def test_mkdir(self): - f = open(support.TESTFN, "w") - try: - self.assertRaises(WindowsError, os.mkdir, support.TESTFN) - finally: - f.close() - os.unlink(support.TESTFN) - - def test_utime(self): - self.assertRaises(WindowsError, os.utime, support.TESTFN, None) - - def test_chmod(self): - self.assertRaises(WindowsError, os.chmod, support.TESTFN, 0) - -class TestInvalidFD(unittest.TestCase): - singles = ["fchdir", "dup", "fdopen", "fdatasync", "fstat", - "fstatvfs", "fsync", "tcgetpgrp", "ttyname"] - #singles.append("close") - #We omit close because it doesn'r raise an exception on some platforms - def get_single(f): - def helper(self): - if hasattr(os, f): - self.check(getattr(os, f)) - return helper - for f in singles: - locals()["test_"+f] = get_single(f) - - def check(self, f, *args): - try: - f(support.make_bad_fd(), *args) - except OSError as e: - self.assertEqual(e.errno, errno.EBADF) - else: - self.fail("%r didn't raise a OSError with a bad file descriptor" - % f) - - def test_isatty(self): - if hasattr(os, "isatty"): - self.assertEqual(os.isatty(support.make_bad_fd()), False) - - def test_closerange(self): - if hasattr(os, "closerange"): - fd = support.make_bad_fd() - self.assertEqual(os.closerange(fd, fd + 10), None) - - def test_dup2(self): - if hasattr(os, "dup2"): - self.check(os.dup2, 20) - - def test_fchmod(self): - if hasattr(os, "fchmod"): - self.check(os.fchmod, 0) - - def test_fchown(self): - if hasattr(os, "fchown"): - self.check(os.fchown, -1, -1) - - def test_fpathconf(self): - if hasattr(os, "fpathconf"): - self.check(os.fpathconf, "PC_NAME_MAX") - - def test_ftruncate(self): - if hasattr(os, "ftruncate"): - self.check(os.ftruncate, 0) - - def test_lseek(self): - if hasattr(os, "lseek"): - self.check(os.lseek, 0, 0) - - def test_read(self): - if hasattr(os, "read"): - self.check(os.read, 1) - - def test_tcsetpgrpt(self): - if hasattr(os, "tcsetpgrp"): - self.check(os.tcsetpgrp, 0) - - def test_write(self): - if hasattr(os, "write"): - self.check(os.write, b" ") - -if sys.platform != 'win32': - class Win32ErrorTests(unittest.TestCase): - pass - - class PosixUidGidTests(unittest.TestCase): - if hasattr(os, 'setuid'): - def test_setuid(self): - if os.getuid() != 0: - self.assertRaises(os.error, os.setuid, 0) - self.assertRaises(OverflowError, os.setuid, 1<<32) - - if hasattr(os, 'setgid'): - def test_setgid(self): - if os.getuid() != 0: - self.assertRaises(os.error, os.setgid, 0) - self.assertRaises(OverflowError, os.setgid, 1<<32) - - if hasattr(os, 'seteuid'): - def test_seteuid(self): - if os.getuid() != 0: - self.assertRaises(os.error, os.seteuid, 0) - self.assertRaises(OverflowError, os.seteuid, 1<<32) - - if hasattr(os, 'setegid'): - def test_setegid(self): - if os.getuid() != 0: - self.assertRaises(os.error, os.setegid, 0) - self.assertRaises(OverflowError, os.setegid, 1<<32) - - if hasattr(os, 'setreuid'): - def test_setreuid(self): - if os.getuid() != 0: - self.assertRaises(os.error, os.setreuid, 0, 0) - self.assertRaises(OverflowError, os.setreuid, 1<<32, 0) - self.assertRaises(OverflowError, os.setreuid, 0, 1<<32) - - if hasattr(os, 'setregid'): - def test_setregid(self): - if os.getuid() != 0: - self.assertRaises(os.error, os.setregid, 0, 0) - self.assertRaises(OverflowError, os.setregid, 1<<32, 0) - self.assertRaises(OverflowError, os.setregid, 0, 1<<32) -else: - class PosixUidGidTests(unittest.TestCase): - pass - -def test_main(): - support.run_unittest( - FileTests, - StatAttributeTests, - EnvironTests, - WalkTests, - MakedirTests, - DevNullTests, - URandomTests, - ExecTests, - Win32ErrorTests, - TestInvalidFD, - PosixUidGidTests - ) - -if __name__ == "__main__": - test_main() From buildbot at python.org Wed Apr 15 13:40:58 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 15 Apr 2009 11:40:58 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu trunk Message-ID: <20090415114059.62E0C1E4019@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%20trunk/builds/1239 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: The web-page 'force build' button was pressed by 'Eric Smith': Test repr change branch Build Source Stamp: [branch branches/py3k-short-float-repr] HEAD Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From python-checkins at python.org Wed Apr 15 14:01:55 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 15 Apr 2009 14:01:55 +0200 (CEST) Subject: [Python-checkins] r71616 - in python/branches/py3k-short-float-repr: Lib/test/_test_os.py Lib/test/test_os.py configure configure.in Message-ID: <20090415120155.7EFA71E4014@bag.python.org> Author: mark.dickinson Date: Wed Apr 15 14:01:54 2009 New Revision: 71616 Log: Revert temporary checkins r71615 and r71611 Added: python/branches/py3k-short-float-repr/Lib/test/test_os.py - copied unchanged from r71614, /python/branches/py3k-short-float-repr/Lib/test/test_os.py Removed: python/branches/py3k-short-float-repr/Lib/test/_test_os.py Modified: python/branches/py3k-short-float-repr/configure python/branches/py3k-short-float-repr/configure.in Deleted: python/branches/py3k-short-float-repr/Lib/test/_test_os.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/_test_os.py Wed Apr 15 14:01:54 2009 +++ (empty file) @@ -1,721 +0,0 @@ -# As a test suite for the os module, this is woefully inadequate, but this -# does add tests for a few functions which have been determined to be more -# portable than they had been thought to be. - -import os -import errno -import unittest -import warnings -import sys -from test import support - -# Tests creating TESTFN -class FileTests(unittest.TestCase): - def setUp(self): - if os.path.exists(support.TESTFN): - os.unlink(support.TESTFN) - tearDown = setUp - - def test_access(self): - f = os.open(support.TESTFN, os.O_CREAT|os.O_RDWR) - os.close(f) - self.assert_(os.access(support.TESTFN, os.W_OK)) - - def test_closerange(self): - first = os.open(support.TESTFN, os.O_CREAT|os.O_RDWR) - # We must allocate two consecutive file descriptors, otherwise - # it will mess up other file descriptors (perhaps even the three - # standard ones). - second = os.dup(first) - try: - retries = 0 - while second != first + 1: - os.close(first) - retries += 1 - if retries > 10: - # XXX test skipped - print("couldn't allocate two consecutive fds, " - "skipping test_closerange", file=sys.stderr) - return - first, second = second, os.dup(second) - finally: - os.close(second) - # close a fd that is open, and one that isn't - os.closerange(first, first + 2) - self.assertRaises(OSError, os.write, first, b"a") - - def test_rename(self): - path = support.TESTFN - old = sys.getrefcount(path) - self.assertRaises(TypeError, os.rename, path, 0) - new = sys.getrefcount(path) - self.assertEqual(old, new) - - def test_read(self): - with open(support.TESTFN, "w+b") as fobj: - fobj.write(b"spam") - fobj.flush() - fd = fobj.fileno() - os.lseek(fd, 0, 0) - s = os.read(fd, 4) - self.assertEqual(type(s), bytes) - self.assertEqual(s, b"spam") - - def test_write(self): - # os.write() accepts bytes- and buffer-like objects but not strings - fd = os.open(support.TESTFN, os.O_CREAT | os.O_WRONLY) - self.assertRaises(TypeError, os.write, fd, "beans") - os.write(fd, b"bacon\n") - os.write(fd, bytearray(b"eggs\n")) - os.write(fd, memoryview(b"spam\n")) - os.close(fd) - with open(support.TESTFN, "rb") as fobj: - self.assertEqual(fobj.read().splitlines(), - [b"bacon", b"eggs", b"spam"]) - - -class TemporaryFileTests(unittest.TestCase): - def setUp(self): - self.files = [] - os.mkdir(support.TESTFN) - - def tearDown(self): - for name in self.files: - os.unlink(name) - os.rmdir(support.TESTFN) - - def check_tempfile(self, name): - # make sure it doesn't already exist: - self.failIf(os.path.exists(name), - "file already exists for temporary file") - # make sure we can create the file - open(name, "w") - self.files.append(name) - - def test_tempnam(self): - if not hasattr(os, "tempnam"): - return - warnings.filterwarnings("ignore", "tempnam", RuntimeWarning, - r"test_os$") - self.check_tempfile(os.tempnam()) - - name = os.tempnam(support.TESTFN) - self.check_tempfile(name) - - name = os.tempnam(support.TESTFN, "pfx") - self.assert_(os.path.basename(name)[:3] == "pfx") - self.check_tempfile(name) - - def test_tmpfile(self): - if not hasattr(os, "tmpfile"): - return - # As with test_tmpnam() below, the Windows implementation of tmpfile() - # attempts to create a file in the root directory of the current drive. - # On Vista and Server 2008, this test will always fail for normal users - # as writing to the root directory requires elevated privileges. With - # XP and below, the semantics of tmpfile() are the same, but the user - # running the test is more likely to have administrative privileges on - # their account already. If that's the case, then os.tmpfile() should - # work. In order to make this test as useful as possible, rather than - # trying to detect Windows versions or whether or not the user has the - # right permissions, just try and create a file in the root directory - # and see if it raises a 'Permission denied' OSError. If it does, then - # test that a subsequent call to os.tmpfile() raises the same error. If - # it doesn't, assume we're on XP or below and the user running the test - # has administrative privileges, and proceed with the test as normal. - if sys.platform == 'win32': - name = '\\python_test_os_test_tmpfile.txt' - if os.path.exists(name): - os.remove(name) - try: - fp = open(name, 'w') - except IOError as first: - # open() failed, assert tmpfile() fails in the same way. - # Although open() raises an IOError and os.tmpfile() raises an - # OSError(), 'args' will be (13, 'Permission denied') in both - # cases. - try: - fp = os.tmpfile() - except OSError as second: - self.assertEqual(first.args, second.args) - else: - self.fail("expected os.tmpfile() to raise OSError") - return - else: - # open() worked, therefore, tmpfile() should work. Close our - # dummy file and proceed with the test as normal. - fp.close() - os.remove(name) - - fp = os.tmpfile() - fp.write("foobar") - fp.seek(0,0) - s = fp.read() - fp.close() - self.assert_(s == "foobar") - - def test_tmpnam(self): - import sys - if not hasattr(os, "tmpnam"): - return - warnings.filterwarnings("ignore", "tmpnam", RuntimeWarning, - r"test_os$") - name = os.tmpnam() - if sys.platform in ("win32",): - # The Windows tmpnam() seems useless. From the MS docs: - # - # The character string that tmpnam creates consists of - # the path prefix, defined by the entry P_tmpdir in the - # file STDIO.H, followed by a sequence consisting of the - # digit characters '0' through '9'; the numerical value - # of this string is in the range 1 - 65,535. Changing the - # definitions of L_tmpnam or P_tmpdir in STDIO.H does not - # change the operation of tmpnam. - # - # The really bizarre part is that, at least under MSVC6, - # P_tmpdir is "\\". That is, the path returned refers to - # the root of the current drive. That's a terrible place to - # put temp files, and, depending on privileges, the user - # may not even be able to open a file in the root directory. - self.failIf(os.path.exists(name), - "file already exists for temporary file") - else: - self.check_tempfile(name) - - def fdopen_helper(self, *args): - fd = os.open(support.TESTFN, os.O_RDONLY) - fp2 = os.fdopen(fd, *args) - fp2.close() - - def test_fdopen(self): - self.fdopen_helper() - self.fdopen_helper('r') - self.fdopen_helper('r', 100) - -# Test attributes on return values from os.*stat* family. -class StatAttributeTests(unittest.TestCase): - def setUp(self): - os.mkdir(support.TESTFN) - self.fname = os.path.join(support.TESTFN, "f1") - f = open(self.fname, 'wb') - f.write(b"ABC") - f.close() - - def tearDown(self): - os.unlink(self.fname) - os.rmdir(support.TESTFN) - - def test_stat_attributes(self): - if not hasattr(os, "stat"): - return - - import stat - result = os.stat(self.fname) - - # Make sure direct access works - self.assertEquals(result[stat.ST_SIZE], 3) - self.assertEquals(result.st_size, 3) - - import sys - - # Make sure all the attributes are there - members = dir(result) - for name in dir(stat): - if name[:3] == 'ST_': - attr = name.lower() - if name.endswith("TIME"): - def trunc(x): return int(x) - else: - def trunc(x): return x - self.assertEquals(trunc(getattr(result, attr)), - result[getattr(stat, name)]) - self.assert_(attr in members) - - try: - result[200] - self.fail("No exception thrown") - except IndexError: - pass - - # Make sure that assignment fails - try: - result.st_mode = 1 - self.fail("No exception thrown") - except AttributeError: - pass - - try: - result.st_rdev = 1 - self.fail("No exception thrown") - except (AttributeError, TypeError): - pass - - try: - result.parrot = 1 - self.fail("No exception thrown") - except AttributeError: - pass - - # Use the stat_result constructor with a too-short tuple. - try: - result2 = os.stat_result((10,)) - self.fail("No exception thrown") - except TypeError: - pass - - # Use the constructr with a too-long tuple. - try: - result2 = os.stat_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)) - except TypeError: - pass - - - def test_statvfs_attributes(self): - if not hasattr(os, "statvfs"): - return - - try: - result = os.statvfs(self.fname) - except OSError as e: - # On AtheOS, glibc always returns ENOSYS - if e.errno == errno.ENOSYS: - return - - # Make sure direct access works - self.assertEquals(result.f_bfree, result[3]) - - # Make sure all the attributes are there. - members = ('bsize', 'frsize', 'blocks', 'bfree', 'bavail', 'files', - 'ffree', 'favail', 'flag', 'namemax') - for value, member in enumerate(members): - self.assertEquals(getattr(result, 'f_' + member), result[value]) - - # Make sure that assignment really fails - try: - result.f_bfree = 1 - self.fail("No exception thrown") - except AttributeError: - pass - - try: - result.parrot = 1 - self.fail("No exception thrown") - except AttributeError: - pass - - # Use the constructor with a too-short tuple. - try: - result2 = os.statvfs_result((10,)) - self.fail("No exception thrown") - except TypeError: - pass - - # Use the constructr with a too-long tuple. - try: - result2 = os.statvfs_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14)) - except TypeError: - pass - - def test_utime_dir(self): - delta = 1000000 - st = os.stat(support.TESTFN) - # round to int, because some systems may support sub-second - # time stamps in stat, but not in utime. - os.utime(support.TESTFN, (st.st_atime, int(st.st_mtime-delta))) - st2 = os.stat(support.TESTFN) - self.assertEquals(st2.st_mtime, int(st.st_mtime-delta)) - - # Restrict test to Win32, since there is no guarantee other - # systems support centiseconds - if sys.platform == 'win32': - def get_file_system(path): - root = os.path.splitdrive(os.path.abspath(path))[0] + '\\' - import ctypes - kernel32 = ctypes.windll.kernel32 - buf = ctypes.create_unicode_buffer("", 100) - if kernel32.GetVolumeInformationW(root, None, 0, None, None, None, buf, len(buf)): - return buf.value - - if get_file_system(support.TESTFN) == "NTFS": - def test_1565150(self): - t1 = 1159195039.25 - os.utime(self.fname, (t1, t1)) - self.assertEquals(os.stat(self.fname).st_mtime, t1) - - def test_1686475(self): - # Verify that an open file can be stat'ed - try: - os.stat(r"c:\pagefile.sys") - except WindowsError as e: - if e.errno == 2: # file does not exist; cannot run test - return - self.fail("Could not stat pagefile.sys") - -from test import mapping_tests - -class EnvironTests(mapping_tests.BasicTestMappingProtocol): - """check that os.environ object conform to mapping protocol""" - type2test = None - - def setUp(self): - self.__save = dict(os.environ) - for key, value in self._reference().items(): - os.environ[key] = value - - def tearDown(self): - os.environ.clear() - os.environ.update(self.__save) - - def _reference(self): - return {"KEY1":"VALUE1", "KEY2":"VALUE2", "KEY3":"VALUE3"} - - def _empty_mapping(self): - os.environ.clear() - return os.environ - - # Bug 1110478 - def test_update2(self): - os.environ.clear() - if os.path.exists("/bin/sh"): - os.environ.update(HELLO="World") - value = os.popen("/bin/sh -c 'echo $HELLO'").read().strip() - self.assertEquals(value, "World") - - def test_os_popen_iter(self): - if os.path.exists("/bin/sh"): - popen = os.popen("/bin/sh -c 'echo \"line1\nline2\nline3\"'") - it = iter(popen) - self.assertEquals(next(it), "line1\n") - self.assertEquals(next(it), "line2\n") - self.assertEquals(next(it), "line3\n") - self.assertRaises(StopIteration, next, it) - - # Verify environ keys and values from the OS are of the - # correct str type. - def test_keyvalue_types(self): - for key, val in os.environ.items(): - self.assertEquals(type(key), str) - self.assertEquals(type(val), str) - - def test_items(self): - for key, value in self._reference().items(): - self.assertEqual(os.environ.get(key), value) - -class WalkTests(unittest.TestCase): - """Tests for os.walk().""" - - def test_traversal(self): - import os - from os.path import join - - # Build: - # TESTFN/ - # TEST1/ a file kid and two directory kids - # tmp1 - # SUB1/ a file kid and a directory kid - # tmp2 - # SUB11/ no kids - # SUB2/ a file kid and a dirsymlink kid - # tmp3 - # link/ a symlink to TESTFN.2 - # TEST2/ - # tmp4 a lone file - walk_path = join(support.TESTFN, "TEST1") - sub1_path = join(walk_path, "SUB1") - sub11_path = join(sub1_path, "SUB11") - sub2_path = join(walk_path, "SUB2") - tmp1_path = join(walk_path, "tmp1") - tmp2_path = join(sub1_path, "tmp2") - tmp3_path = join(sub2_path, "tmp3") - link_path = join(sub2_path, "link") - t2_path = join(support.TESTFN, "TEST2") - tmp4_path = join(support.TESTFN, "TEST2", "tmp4") - - # Create stuff. - os.makedirs(sub11_path) - os.makedirs(sub2_path) - os.makedirs(t2_path) - for path in tmp1_path, tmp2_path, tmp3_path, tmp4_path: - f = open(path, "w") - f.write("I'm " + path + " and proud of it. Blame test_os.\n") - f.close() - if hasattr(os, "symlink"): - os.symlink(os.path.abspath(t2_path), link_path) - sub2_tree = (sub2_path, ["link"], ["tmp3"]) - else: - sub2_tree = (sub2_path, [], ["tmp3"]) - - # Walk top-down. - all = list(os.walk(walk_path)) - self.assertEqual(len(all), 4) - # We can't know which order SUB1 and SUB2 will appear in. - # Not flipped: TESTFN, SUB1, SUB11, SUB2 - # flipped: TESTFN, SUB2, SUB1, SUB11 - flipped = all[0][1][0] != "SUB1" - all[0][1].sort() - self.assertEqual(all[0], (walk_path, ["SUB1", "SUB2"], ["tmp1"])) - self.assertEqual(all[1 + flipped], (sub1_path, ["SUB11"], ["tmp2"])) - self.assertEqual(all[2 + flipped], (sub11_path, [], [])) - self.assertEqual(all[3 - 2 * flipped], sub2_tree) - - # Prune the search. - all = [] - for root, dirs, files in os.walk(walk_path): - all.append((root, dirs, files)) - # Don't descend into SUB1. - if 'SUB1' in dirs: - # Note that this also mutates the dirs we appended to all! - dirs.remove('SUB1') - self.assertEqual(len(all), 2) - self.assertEqual(all[0], (walk_path, ["SUB2"], ["tmp1"])) - self.assertEqual(all[1], sub2_tree) - - # Walk bottom-up. - all = list(os.walk(walk_path, topdown=False)) - self.assertEqual(len(all), 4) - # We can't know which order SUB1 and SUB2 will appear in. - # Not flipped: SUB11, SUB1, SUB2, TESTFN - # flipped: SUB2, SUB11, SUB1, TESTFN - flipped = all[3][1][0] != "SUB1" - all[3][1].sort() - self.assertEqual(all[3], (walk_path, ["SUB1", "SUB2"], ["tmp1"])) - self.assertEqual(all[flipped], (sub11_path, [], [])) - self.assertEqual(all[flipped + 1], (sub1_path, ["SUB11"], ["tmp2"])) - self.assertEqual(all[2 - 2 * flipped], sub2_tree) - - if hasattr(os, "symlink"): - # Walk, following symlinks. - for root, dirs, files in os.walk(walk_path, followlinks=True): - if root == link_path: - self.assertEqual(dirs, []) - self.assertEqual(files, ["tmp4"]) - break - else: - self.fail("Didn't follow symlink with followlinks=True") - - def tearDown(self): - # Tear everything down. This is a decent use for bottom-up on - # Windows, which doesn't have a recursive delete command. The - # (not so) subtlety is that rmdir will fail unless the dir's - # kids are removed first, so bottom up is essential. - for root, dirs, files in os.walk(support.TESTFN, topdown=False): - for name in files: - os.remove(os.path.join(root, name)) - for name in dirs: - dirname = os.path.join(root, name) - if not os.path.islink(dirname): - os.rmdir(dirname) - else: - os.remove(dirname) - os.rmdir(support.TESTFN) - -class MakedirTests(unittest.TestCase): - def setUp(self): - os.mkdir(support.TESTFN) - - def test_makedir(self): - base = support.TESTFN - path = os.path.join(base, 'dir1', 'dir2', 'dir3') - os.makedirs(path) # Should work - path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4') - os.makedirs(path) - - # Try paths with a '.' in them - self.failUnlessRaises(OSError, os.makedirs, os.curdir) - path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4', 'dir5', os.curdir) - os.makedirs(path) - path = os.path.join(base, 'dir1', os.curdir, 'dir2', 'dir3', 'dir4', - 'dir5', 'dir6') - os.makedirs(path) - - def tearDown(self): - path = os.path.join(support.TESTFN, 'dir1', 'dir2', 'dir3', - 'dir4', 'dir5', 'dir6') - # If the tests failed, the bottom-most directory ('../dir6') - # may not have been created, so we look for the outermost directory - # that exists. - while not os.path.exists(path) and path != support.TESTFN: - path = os.path.dirname(path) - - os.removedirs(path) - -class DevNullTests(unittest.TestCase): - def test_devnull(self): - f = open(os.devnull, 'w') - f.write('hello') - f.close() - f = open(os.devnull, 'r') - self.assertEqual(f.read(), '') - f.close() - -class URandomTests(unittest.TestCase): - def test_urandom(self): - try: - self.assertEqual(len(os.urandom(1)), 1) - self.assertEqual(len(os.urandom(10)), 10) - self.assertEqual(len(os.urandom(100)), 100) - self.assertEqual(len(os.urandom(1000)), 1000) - except NotImplementedError: - pass - -class ExecTests(unittest.TestCase): - def test_execvpe_with_bad_program(self): - self.assertRaises(OSError, os.execvpe, 'no such app-', ['no such app-'], None) - - def test_execvpe_with_bad_arglist(self): - self.assertRaises(ValueError, os.execvpe, 'notepad', [], None) - -class Win32ErrorTests(unittest.TestCase): - def test_rename(self): - self.assertRaises(WindowsError, os.rename, support.TESTFN, support.TESTFN+".bak") - - def test_remove(self): - self.assertRaises(WindowsError, os.remove, support.TESTFN) - - def test_chdir(self): - self.assertRaises(WindowsError, os.chdir, support.TESTFN) - - def test_mkdir(self): - f = open(support.TESTFN, "w") - try: - self.assertRaises(WindowsError, os.mkdir, support.TESTFN) - finally: - f.close() - os.unlink(support.TESTFN) - - def test_utime(self): - self.assertRaises(WindowsError, os.utime, support.TESTFN, None) - - def test_chmod(self): - self.assertRaises(WindowsError, os.chmod, support.TESTFN, 0) - -class TestInvalidFD(unittest.TestCase): - singles = ["fchdir", "dup", "fdopen", "fdatasync", "fstat", - "fstatvfs", "fsync", "tcgetpgrp", "ttyname"] - #singles.append("close") - #We omit close because it doesn'r raise an exception on some platforms - def get_single(f): - def helper(self): - if hasattr(os, f): - self.check(getattr(os, f)) - return helper - for f in singles: - locals()["test_"+f] = get_single(f) - - def check(self, f, *args): - try: - f(support.make_bad_fd(), *args) - except OSError as e: - self.assertEqual(e.errno, errno.EBADF) - else: - self.fail("%r didn't raise a OSError with a bad file descriptor" - % f) - - def test_isatty(self): - if hasattr(os, "isatty"): - self.assertEqual(os.isatty(support.make_bad_fd()), False) - - def test_closerange(self): - if hasattr(os, "closerange"): - fd = support.make_bad_fd() - self.assertEqual(os.closerange(fd, fd + 10), None) - - def test_dup2(self): - if hasattr(os, "dup2"): - self.check(os.dup2, 20) - - def test_fchmod(self): - if hasattr(os, "fchmod"): - self.check(os.fchmod, 0) - - def test_fchown(self): - if hasattr(os, "fchown"): - self.check(os.fchown, -1, -1) - - def test_fpathconf(self): - if hasattr(os, "fpathconf"): - self.check(os.fpathconf, "PC_NAME_MAX") - - def test_ftruncate(self): - if hasattr(os, "ftruncate"): - self.check(os.ftruncate, 0) - - def test_lseek(self): - if hasattr(os, "lseek"): - self.check(os.lseek, 0, 0) - - def test_read(self): - if hasattr(os, "read"): - self.check(os.read, 1) - - def test_tcsetpgrpt(self): - if hasattr(os, "tcsetpgrp"): - self.check(os.tcsetpgrp, 0) - - def test_write(self): - if hasattr(os, "write"): - self.check(os.write, b" ") - -if sys.platform != 'win32': - class Win32ErrorTests(unittest.TestCase): - pass - - class PosixUidGidTests(unittest.TestCase): - if hasattr(os, 'setuid'): - def test_setuid(self): - if os.getuid() != 0: - self.assertRaises(os.error, os.setuid, 0) - self.assertRaises(OverflowError, os.setuid, 1<<32) - - if hasattr(os, 'setgid'): - def test_setgid(self): - if os.getuid() != 0: - self.assertRaises(os.error, os.setgid, 0) - self.assertRaises(OverflowError, os.setgid, 1<<32) - - if hasattr(os, 'seteuid'): - def test_seteuid(self): - if os.getuid() != 0: - self.assertRaises(os.error, os.seteuid, 0) - self.assertRaises(OverflowError, os.seteuid, 1<<32) - - if hasattr(os, 'setegid'): - def test_setegid(self): - if os.getuid() != 0: - self.assertRaises(os.error, os.setegid, 0) - self.assertRaises(OverflowError, os.setegid, 1<<32) - - if hasattr(os, 'setreuid'): - def test_setreuid(self): - if os.getuid() != 0: - self.assertRaises(os.error, os.setreuid, 0, 0) - self.assertRaises(OverflowError, os.setreuid, 1<<32, 0) - self.assertRaises(OverflowError, os.setreuid, 0, 1<<32) - - if hasattr(os, 'setregid'): - def test_setregid(self): - if os.getuid() != 0: - self.assertRaises(os.error, os.setregid, 0, 0) - self.assertRaises(OverflowError, os.setregid, 1<<32, 0) - self.assertRaises(OverflowError, os.setregid, 0, 1<<32) -else: - class PosixUidGidTests(unittest.TestCase): - pass - -def test_main(): - support.run_unittest( - FileTests, - StatAttributeTests, - EnvironTests, - WalkTests, - MakedirTests, - DevNullTests, - URandomTests, - ExecTests, - Win32ErrorTests, - TestInvalidFD, - PosixUidGidTests - ) - -if __name__ == "__main__": - test_main() Modified: python/branches/py3k-short-float-repr/configure ============================================================================== --- python/branches/py3k-short-float-repr/configure (original) +++ python/branches/py3k-short-float-repr/configure Wed Apr 15 14:01:54 2009 @@ -4471,12 +4471,6 @@ # compiler and platform. BASECFLAGS tweaks need to be made even if the # user set OPT. -# tempory inclusion to output the system-specific defines that GCC knows -if test "$GCC" = yes -then - $CC -dM -E - The Buildbot has detected a new failure of ppc Debian unstable trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%20trunk/builds/370 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: The web-page 'force build' button was pressed by 'Eric Smith': Test repr change branch Build Source Stamp: [branch branches/py3k-short-float-repr] HEAD Blamelist: BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_distutils ====================================================================== ERROR: test_build_ext (distutils.tests.test_build_ext.BuildExtTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/distutils/unixccompiler.py", line 176, in _compile extra_postargs) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/distutils/ccompiler.py", line 982, in spawn spawn(cmd, dry_run=self.dry_run) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/distutils/spawn.py", line 31, in spawn _spawn_posix(cmd, search_path, dry_run=dry_run) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/distutils/spawn.py", line 139, in _spawn_posix % (cmd[0], exit_status)) distutils.errors.DistutilsExecError: command 'gcc' failed with exit status 1 Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/distutils/tests/test_build_ext.py", line 65, in test_build_ext cmd.run() File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/distutils/command/build_ext.py", line 347, in run self.build_extensions() File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/distutils/command/build_ext.py", line 459, in build_extensions self.build_extension(ext) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/distutils/command/build_ext.py", line 529, in build_extension depends=ext.depends) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/distutils/ccompiler.py", line 649, in compile self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/distutils/unixccompiler.py", line 178, in _compile raise CompileError(msg) distutils.errors.CompileError: command 'gcc' failed with exit status 1 Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/distutils/tests/test_build_ext.py", line 65, in test_build_ext cmd.run() File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/distutils/command/build_ext.py", line 347, in run self.build_extensions() File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/distutils/command/build_ext.py", line 459, in build_extensions self.build_extension(ext) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/distutils/command/build_ext.py", line 529, in build_extension depends=ext.depends) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/distutils/ccompiler.py", line 649, in compile self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/distutils/unixccompiler.py", line 178, in _compile raise CompileError(msg) distutils.errors.CompileError: command 'gcc' failed with exit status 1 make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Wed Apr 15 15:40:49 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 15 Apr 2009 15:40:49 +0200 (CEST) Subject: [Python-checkins] r71618 - in python/branches/py3k-short-float-repr: configure configure.in Message-ID: <20090415134049.89D391E407C@bag.python.org> Author: mark.dickinson Date: Wed Apr 15 15:40:49 2009 New Revision: 71618 Log: Fix confusing indentation Modified: python/branches/py3k-short-float-repr/configure python/branches/py3k-short-float-repr/configure.in Modified: python/branches/py3k-short-float-repr/configure ============================================================================== --- python/branches/py3k-short-float-repr/configure (original) +++ python/branches/py3k-short-float-repr/configure Wed Apr 15 15:40:49 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 71613 . +# From configure.in Revision: 71616 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.1. # @@ -21885,7 +21885,7 @@ : "=a" (ax), "=r" (bx), "=c" (cx), "=d" (dx) : "a" (func) : "cc" ); - if ((dx & (1U << 25)) && (dx & (1U << 26))) + if ((dx & (1U << 25)) && (dx & (1U << 26))) return 0; else return 1; Modified: python/branches/py3k-short-float-repr/configure.in ============================================================================== --- python/branches/py3k-short-float-repr/configure.in (original) +++ python/branches/py3k-short-float-repr/configure.in Wed Apr 15 15:40:49 2009 @@ -3188,7 +3188,7 @@ : "=a" (ax), "=r" (bx), "=c" (cx), "=d" (dx) : "a" (func) : "cc" ); - if ((dx & (1U << 25)) && (dx & (1U << 26))) + if ((dx & (1U << 25)) && (dx & (1U << 26))) return 0; else return 1; From python-checkins at python.org Wed Apr 15 17:38:31 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 15 Apr 2009 17:38:31 +0200 (CEST) Subject: [Python-checkins] r71619 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090415153831.0A7101E405D@bag.python.org> Author: mark.dickinson Date: Wed Apr 15 17:38:30 2009 New Revision: 71619 Log: Merge recent fixes from David Gay into dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Wed Apr 15 17:38:30 2009 @@ -19,7 +19,7 @@ /**************************************************************** * This is dtoa.c by David M. Gay, downloaded from - * http://www.netlib.org/fp/dtoa.c on March 17, 2009 and modified for + * http://www.netlib.org/fp/dtoa.c on April 15, 2009 and modified for * inclusion into the Python core by Mark E. T. Dickinson and Eric V. Smith. * The major modifications are as follows: * @@ -50,10 +50,7 @@ * _Py_dg_dtoa are expected to call _Py_dg_freedtoa to free * the memory allocated by _Py_dg_dtoa. * - * 5. A bug in the original dtoa.c code, in which '.nan' and '.inf' - * were accepted as valid inputs to strtod, has been fixed. - * - * 6. The code has been reformatted to better fit with Python's + * 5. The code has been reformatted to better fit with Python's * C style guide (PEP 7). * ***************************************************************/ @@ -1405,10 +1402,6 @@ } } dig_done: - if (!nd && !nz && !nz0 && (s != s0)) { - /* no digits, just a '.'. Fail. */ - goto ret0; - } e = 0; if (c == 'e' || c == 'E') { if (!nd && !nz && !nz0) { @@ -1449,26 +1442,27 @@ if (!nd) { if (!nz && !nz0) { /* Check for Nan and Infinity */ - switch(c) { - case 'i': - case 'I': - if (match(&s,"nf")) { - --s; - if (!match(&s,"inity")) - ++s; - word0(&rv) = 0x7ff00000; - word1(&rv) = 0; - goto ret; - } - break; - case 'n': - case 'N': - if (match(&s, "an")) { - word0(&rv) = NAN_WORD0; - word1(&rv) = NAN_WORD1; - goto ret; + if (!bc.dplen) + switch(c) { + case 'i': + case 'I': + if (match(&s,"nf")) { + --s; + if (!match(&s,"inity")) + ++s; + word0(&rv) = 0x7ff00000; + word1(&rv) = 0; + goto ret; + } + break; + case 'n': + case 'N': + if (match(&s, "an")) { + word0(&rv) = NAN_WORD0; + word1(&rv) = NAN_WORD1; + goto ret; + } } - } ret0: s = s00; sign = 0; From python-checkins at python.org Wed Apr 15 20:11:05 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 15 Apr 2009 20:11:05 +0200 (CEST) Subject: [Python-checkins] r71620 - python/branches/py3k-short-float-repr/Include/pyport.h Message-ID: <20090415181105.3971E1E448F@bag.python.org> Author: mark.dickinson Date: Wed Apr 15 20:11:04 2009 New Revision: 71620 Log: Add new define PY_NO_SHORT_FLOAT_REPR in pyport.h, to be used on those platforms where Gay's code isn't going to work for one reason or another. Modified: python/branches/py3k-short-float-repr/Include/pyport.h Modified: python/branches/py3k-short-float-repr/Include/pyport.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/pyport.h (original) +++ python/branches/py3k-short-float-repr/Include/pyport.h Wed Apr 15 20:11:04 2009 @@ -488,6 +488,30 @@ #define _Py_SET_53BIT_PRECISION_END #endif +/* If we can't guarantee 53-bit precision, don't use the code + in Python/dtoa.c, but fall back to standard code. This + means that repr of a float will be long (17 sig digits). + + Realistically, there are two things that could go wrong: + + (1) doubles aren't IEEE 754 doubles, or + (2) we're on x86 with the rounding precision set to 64-bits + (extended precision), and we don't know how to change + the rounding precision. + */ + +#if !defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) && \ + !defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) && \ + !defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754) +#define PY_NO_SHORT_FLOAT_REPR +#endif + +/* double rounding is symptomatic of use of extended precision on x86 */ +#ifdef X87_DOUBLE_ROUNDING +#define PY_NO_SHORT_FLOAT_REPR +#endif + + /* Py_DEPRECATED(version) * Declare a variable, type, or function deprecated. * Usage: From python-checkins at python.org Wed Apr 15 20:16:42 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 15 Apr 2009 20:16:42 +0200 (CEST) Subject: [Python-checkins] r71621 - in python/branches/py3k-short-float-repr: Include/dtoa.h Python/dtoa.c Message-ID: <20090415181642.4BDE41E4067@bag.python.org> Author: mark.dickinson Date: Wed Apr 15 20:16:42 2009 New Revision: 71621 Log: Don't compile dtoa.c when PY_NO_SHORT_FLOAT_REPR is defined Modified: python/branches/py3k-short-float-repr/Include/dtoa.h python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Include/dtoa.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/dtoa.h (original) +++ python/branches/py3k-short-float-repr/Include/dtoa.h Wed Apr 15 20:16:42 2009 @@ -1,3 +1,4 @@ +#ifndef PY_SHORT_FLOAT_REPR #ifdef __cplusplus extern "C" { #endif @@ -11,3 +12,4 @@ #ifdef __cplusplus } #endif +#endif Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Wed Apr 15 20:16:42 2009 @@ -104,6 +104,11 @@ /* Linking of Python's #defines to Gay's #defines starts here. */ #include "Python.h" + +/* if PY_NO_SHORT_FLOAT_REPR is defined, then don't even try to compile + the following code */ +#ifndef PY_NO_SHORT_FLOAT_REPR + #include "float.h" #define MALLOC PyMem_Malloc @@ -2637,3 +2642,5 @@ #ifdef __cplusplus } #endif + +#endif /* PY_NO_SHORT_FLOAT_REPR */ From python-checkins at python.org Wed Apr 15 20:22:23 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 15 Apr 2009 20:22:23 +0200 (CEST) Subject: [Python-checkins] r71622 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090415182223.76EF31E406D@bag.python.org> Author: mark.dickinson Date: Wed Apr 15 20:22:23 2009 New Revision: 71622 Log: Use fallback code for PyOS_ascii_strtod when Gay's code isn't available. Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Wed Apr 15 20:22:23 2009 @@ -37,6 +37,9 @@ * * Return value: the #gdouble value. **/ + +#ifndef PY_NO_SHORT_FLOAT_REPR + double PyOS_ascii_strtod(const char *nptr, char **endptr) { @@ -56,8 +59,18 @@ } +#else + +/* + Use system strtod; since strtod is locale aware, we may + have to first fix the decimal separator. + + Note that unlike _Py_dg_strtod, the system strtod may not always give + correctly rounded results. +*/ + double -PyOS_ascii_strtod_fallback(const char *nptr, char **endptr) +PyOS_ascii_strtod(const char *nptr, char **endptr) { char *fail_pos; double val = -1.0; @@ -206,6 +219,8 @@ return val; } +#endif + /* Given a string that may have a decimal point in the current locale, change it back to a dot. Since the string cannot get longer, no need for a maximum buffer size parameter. */ From python-checkins at python.org Wed Apr 15 20:29:00 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 15 Apr 2009 20:29:00 +0200 (CEST) Subject: [Python-checkins] r71623 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090415182900.321F71E4067@bag.python.org> Author: mark.dickinson Date: Wed Apr 15 20:28:59 2009 New Revision: 71623 Log: Move PyOS_ascii_atof to a more appropriate location Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Wed Apr 15 20:28:59 2009 @@ -221,6 +221,13 @@ #endif +double +PyOS_ascii_atof(const char *nptr) +{ + return PyOS_ascii_strtod(nptr, NULL); +} + + /* Given a string that may have a decimal point in the current locale, change it back to a dot. Since the string cannot get longer, no need for a maximum buffer size parameter. */ @@ -520,13 +527,6 @@ return buffer; } -double -PyOS_ascii_atof(const char *nptr) -{ - return PyOS_ascii_strtod(nptr, NULL); -} - - /* I'm using a lookup table here so that I don't have to invent a non-locale specific way to convert to uppercase */ #define OFS_INF 0 From python-checkins at python.org Wed Apr 15 21:19:22 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 15 Apr 2009 21:19:22 +0200 (CEST) Subject: [Python-checkins] r71624 - python/branches/py3k-short-float-repr/Include/dtoa.h Message-ID: <20090415191922.2C2281E4060@bag.python.org> Author: mark.dickinson Date: Wed Apr 15 21:19:21 2009 New Revision: 71624 Log: Fix typo Modified: python/branches/py3k-short-float-repr/Include/dtoa.h Modified: python/branches/py3k-short-float-repr/Include/dtoa.h ============================================================================== --- python/branches/py3k-short-float-repr/Include/dtoa.h (original) +++ python/branches/py3k-short-float-repr/Include/dtoa.h Wed Apr 15 21:19:21 2009 @@ -1,4 +1,4 @@ -#ifndef PY_SHORT_FLOAT_REPR +#ifndef PY_NO_SHORT_FLOAT_REPR #ifdef __cplusplus extern "C" { #endif From python-checkins at python.org Wed Apr 15 21:44:58 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 15 Apr 2009 21:44:58 +0200 (CEST) Subject: [Python-checkins] r71625 - python/branches/release26-maint/Misc/NEWS Message-ID: <20090415194458.299811E4060@bag.python.org> Author: georg.brandl Date: Wed Apr 15 21:44:57 2009 New Revision: 71625 Log: Remove NEWS item for issue that wasnt actually backported. Modified: python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Wed Apr 15 21:44:57 2009 @@ -135,10 +135,6 @@ - Actually make the SimpleXMLRPCServer CGI handler work. -- Issue #2522: locale.format now checks its first argument to ensure it has - been passed only one pattern, avoiding mysterious errors where it appeared - that it was failing to do localization. - - Issue 2625: added missing iteritems() call to the for loop in mailbox.MH.get_message(). From nnorwitz at gmail.com Wed Apr 15 22:11:32 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 15 Apr 2009 16:11:32 -0400 Subject: [Python-checkins] Python Regression Test Failures basics (1) Message-ID: <20090415201132.GA358@python.psfb.org> 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23366 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 test_lib2to3 failed -- errors occurred; run in verbose mode for details 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 -- OSError raises on RLock creation, see issue 3111! test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18902 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [742041 refs] From nnorwitz at gmail.com Wed Apr 15 22:19:25 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 15 Apr 2009 16:19:25 -0400 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20090415201925.GA2804@python.psfb.org> 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils [17363 refs] [17363 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23366 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 test_lib2to3 failed -- errors occurred; run in verbose mode for details 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 -- OSError raises on RLock creation, see issue 3111! test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18065 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [741281 refs] From python-checkins at python.org Wed Apr 15 22:34:30 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 15 Apr 2009 22:34:30 +0200 (CEST) Subject: [Python-checkins] r71626 - python/branches/py3k/Doc/library/filesys.rst Message-ID: <20090415203430.967861E4032@bag.python.org> Author: benjamin.peterson Date: Wed Apr 15 22:34:30 2009 New Revision: 71626 Log: reference the io momdule in file and directory section Modified: python/branches/py3k/Doc/library/filesys.rst Modified: python/branches/py3k/Doc/library/filesys.rst ============================================================================== --- python/branches/py3k/Doc/library/filesys.rst (original) +++ python/branches/py3k/Doc/library/filesys.rst Wed Apr 15 22:34:30 2009 @@ -34,3 +34,7 @@ Operating system interfaces, including functions to work with files at a lower level than the built-in file object. + Module :mod:`io` + Python's framework for dealing with I/O including reading and writing + files. + From python-checkins at python.org Wed Apr 15 23:26:36 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 15 Apr 2009 23:26:36 +0200 (CEST) Subject: [Python-checkins] r71627 - in python/trunk: Lib/test/test_float.py Misc/NEWS Objects/floatobject.c Message-ID: <20090415212636.840CD1E401B@bag.python.org> Author: benjamin.peterson Date: Wed Apr 15 23:26:36 2009 New Revision: 71627 Log: call __float__ on str subclasses #5759 tests by R. David Murray Modified: python/trunk/Lib/test/test_float.py python/trunk/Misc/NEWS python/trunk/Objects/floatobject.c Modified: python/trunk/Lib/test/test_float.py ============================================================================== --- python/trunk/Lib/test/test_float.py (original) +++ python/trunk/Lib/test/test_float.py Wed Apr 15 23:26:36 2009 @@ -82,11 +82,23 @@ def __float__(self): return 42 + # Issue 5759: __float__ not called on str subclasses (though it is on + # unicode subclasses). + class FooStr(str): + def __float__(self): + return float(str(self)) + 1 + + class FooUnicode(unicode): + def __float__(self): + return float(unicode(self)) + 1 + self.assertAlmostEqual(float(Foo0()), 42.) self.assertAlmostEqual(float(Foo1()), 42.) self.assertAlmostEqual(float(Foo2()), 42.) self.assertAlmostEqual(float(Foo3(21)), 42.) self.assertRaises(TypeError, float, Foo4(42)) + self.assertAlmostEqual(float(FooUnicode('8')), 9.) + self.assertAlmostEqual(float(FooStr('8')), 9.) def test_floatasratio(self): for f, ratio in [ Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Apr 15 23:26:36 2009 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #5759: float() didn't call __float__ on str subclasses. + - Issue #5704: the "-3" command-line option now implies "-t". - Issue #2170: refactored xml.dom.minidom.normalize, increasing both Modified: python/trunk/Objects/floatobject.c ============================================================================== --- python/trunk/Objects/floatobject.c (original) +++ python/trunk/Objects/floatobject.c Wed Apr 15 23:26:36 2009 @@ -1630,7 +1630,9 @@ return float_subtype_new(type, args, kwds); /* Wimp out */ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x)) return NULL; - if (PyString_Check(x)) + /* If it's a string, but not a string subclass, use + PyFloat_FromString. */ + if (PyString_CheckExact(x)) return PyFloat_FromString(x, NULL); return PyNumber_Float(x); } From buildbot at python.org Wed Apr 15 23:31:37 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 15 Apr 2009 21:31:37 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu trunk Message-ID: <20090415213137.B49621E401B@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%20trunk/builds/1241 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: benjamin.peterson BUILD FAILED: failed svn sincerely, -The Buildbot From python-checkins at python.org Wed Apr 15 23:34:28 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 15 Apr 2009 23:34:28 +0200 (CEST) Subject: [Python-checkins] r71628 - in python/branches/py3k: Lib/test/test_float.py Misc/NEWS Objects/floatobject.c Message-ID: <20090415213428.59DEA1E401B@bag.python.org> Author: benjamin.peterson Date: Wed Apr 15 23:34:27 2009 New Revision: 71628 Log: Merged revisions 71627 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71627 | benjamin.peterson | 2009-04-15 16:26:36 -0500 (Wed, 15 Apr 2009) | 4 lines call __float__ on str subclasses #5759 tests by R. David Murray ........ Modified: python/branches/py3k/ (props changed) 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 Wed Apr 15 23:34:27 2009 @@ -78,11 +78,18 @@ def __float__(self): return 42 + # Issue 5759: __float__ not called on str subclasses (though it is on + # unicode subclasses). + class FooStr(str): + def __float__(self): + return float(str(self)) + 1 + self.assertAlmostEqual(float(Foo0()), 42.) self.assertAlmostEqual(float(Foo1()), 42.) self.assertAlmostEqual(float(Foo2()), 42.) self.assertAlmostEqual(float(Foo3(21)), 42.) self.assertRaises(TypeError, float, Foo4(42)) + self.assertAlmostEqual(float(FooStr('8')), 9.) def test_floatasratio(self): for f, ratio in [ Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Apr 15 23:34:27 2009 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #5759: float() didn't call __float__ on str subclasses. + - The string.maketrans() function is deprecated; there is a new static method maketrans() on the bytes and bytearray classes. This removes confusion about the types string.maketrans() is supposed to work with, and mirrors the Modified: python/branches/py3k/Objects/floatobject.c ============================================================================== --- python/branches/py3k/Objects/floatobject.c (original) +++ python/branches/py3k/Objects/floatobject.c Wed Apr 15 23:34:27 2009 @@ -1533,7 +1533,9 @@ return float_subtype_new(type, args, kwds); /* Wimp out */ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x)) return NULL; - if (PyUnicode_Check(x)) + /* If it's a string, but not a string subclass, use + PyFloat_FromString. */ + if (PyUnicode_CheckExact(x)) return PyFloat_FromString(x); return PyNumber_Float(x); } From python-checkins at python.org Wed Apr 15 23:40:52 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 15 Apr 2009 23:40:52 +0200 (CEST) Subject: [Python-checkins] r71629 - in python/branches/release30-maint: Lib/test/test_float.py Misc/NEWS Objects/floatobject.c Message-ID: <20090415214052.8B3341E4028@bag.python.org> Author: benjamin.peterson Date: Wed Apr 15 23:40:50 2009 New Revision: 71629 Log: Merged revisions 71628 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71628 | benjamin.peterson | 2009-04-15 16:34:27 -0500 (Wed, 15 Apr 2009) | 11 lines Merged revisions 71627 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71627 | benjamin.peterson | 2009-04-15 16:26:36 -0500 (Wed, 15 Apr 2009) | 4 lines call __float__ on str subclasses #5759 tests by R. David Murray ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Lib/test/test_float.py python/branches/release30-maint/Misc/NEWS python/branches/release30-maint/Objects/floatobject.c Modified: python/branches/release30-maint/Lib/test/test_float.py ============================================================================== --- python/branches/release30-maint/Lib/test/test_float.py (original) +++ python/branches/release30-maint/Lib/test/test_float.py Wed Apr 15 23:40:50 2009 @@ -78,11 +78,18 @@ def __float__(self): return 42 + # Issue 5759: __float__ not called on str subclasses (though it is on + # unicode subclasses). + class FooStr(str): + def __float__(self): + return float(str(self)) + 1 + self.assertAlmostEqual(float(Foo0()), 42.) self.assertAlmostEqual(float(Foo1()), 42.) self.assertAlmostEqual(float(Foo2()), 42.) self.assertAlmostEqual(float(Foo3(21)), 42.) self.assertRaises(TypeError, float, Foo4(42)) + self.assertAlmostEqual(float(FooStr('8')), 9.) def test_floatasratio(self): for f, ratio in [ Modified: python/branches/release30-maint/Misc/NEWS ============================================================================== --- python/branches/release30-maint/Misc/NEWS (original) +++ python/branches/release30-maint/Misc/NEWS Wed Apr 15 23:40:50 2009 @@ -16,6 +16,8 @@ imp.find_module() were converted to UTF-8 while the path is converted to the default filesystem encoding, causing nonsense. +- Issue #5759: float() didn't call __float__ on str subclasses. + - Issue #5392: when a very low recursion limit was set, the interpreter would abort with a fatal error after the recursion limit was hit twice. Modified: python/branches/release30-maint/Objects/floatobject.c ============================================================================== --- python/branches/release30-maint/Objects/floatobject.c (original) +++ python/branches/release30-maint/Objects/floatobject.c Wed Apr 15 23:40:50 2009 @@ -1533,7 +1533,9 @@ return float_subtype_new(type, args, kwds); /* Wimp out */ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x)) return NULL; - if (PyUnicode_Check(x)) + /* If it's a string, but not a string subclass, use + PyFloat_FromString. */ + if (PyUnicode_CheckExact(x)) return PyFloat_FromString(x); return PyNumber_Float(x); } From python-checkins at python.org Wed Apr 15 23:46:14 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 15 Apr 2009 23:46:14 +0200 (CEST) Subject: [Python-checkins] r71630 - in python/branches/release26-maint: Lib/test/test_float.py Misc/NEWS Objects/floatobject.c Message-ID: <20090415214614.F08261E4028@bag.python.org> Author: benjamin.peterson Date: Wed Apr 15 23:46:14 2009 New Revision: 71630 Log: Merged revisions 71627 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71627 | benjamin.peterson | 2009-04-15 16:26:36 -0500 (Wed, 15 Apr 2009) | 4 lines call __float__ on str subclasses #5759 tests by R. David Murray ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_float.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Objects/floatobject.c Modified: python/branches/release26-maint/Lib/test/test_float.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_float.py (original) +++ python/branches/release26-maint/Lib/test/test_float.py Wed Apr 15 23:46:14 2009 @@ -82,11 +82,23 @@ def __float__(self): return 42 + # Issue 5759: __float__ not called on str subclasses (though it is on + # unicode subclasses). + class FooStr(str): + def __float__(self): + return float(str(self)) + 1 + + class FooUnicode(unicode): + def __float__(self): + return float(unicode(self)) + 1 + self.assertAlmostEqual(float(Foo0()), 42.) self.assertAlmostEqual(float(Foo1()), 42.) self.assertAlmostEqual(float(Foo2()), 42.) self.assertAlmostEqual(float(Foo3(21)), 42.) self.assertRaises(TypeError, float, Foo4(42)) + self.assertAlmostEqual(float(FooUnicode('8')), 9.) + self.assertAlmostEqual(float(FooStr('8')), 9.) def test_floatasratio(self): for f, ratio in [ Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Wed Apr 15 23:46:14 2009 @@ -4,10 +4,15 @@ (editors: check NEWS.help for information about editing NEWS using ReST.) -What's New in Python 2.6.2 +What's New in Python 2.6.3 ========================== -*Release date: 14-Apr-2009* +*Release date: XX-XX-XXX* + +Core and Builtins +----------------- + +- Issue #5759: float() didn't call __float__ on str subclasses. What's New in Python 2.6.2 rc 1 Modified: python/branches/release26-maint/Objects/floatobject.c ============================================================================== --- python/branches/release26-maint/Objects/floatobject.c (original) +++ python/branches/release26-maint/Objects/floatobject.c Wed Apr 15 23:46:14 2009 @@ -1630,7 +1630,9 @@ return float_subtype_new(type, args, kwds); /* Wimp out */ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x)) return NULL; - if (PyString_Check(x)) + /* If it's a string, but not a string subclass, use + PyFloat_FromString. */ + if (PyString_CheckExact(x)) return PyFloat_FromString(x, NULL); return PyNumber_Float(x); } From buildbot at python.org Thu Apr 16 00:16:20 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 15 Apr 2009 22:16:20 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.0 Message-ID: <20090415221620.8B3D21E401B@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.0/builds/272 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: benjamin.peterson,matthias.klose BUILD FAILED: failed svn sincerely, -The Buildbot From python-checkins at python.org Thu Apr 16 00:33:07 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 16 Apr 2009 00:33:07 +0200 (CEST) Subject: [Python-checkins] r71631 - python/trunk/Doc/library/subprocess.rst Message-ID: <20090415223307.D85AD1E455D@bag.python.org> Author: r.david.murray Date: Thu Apr 16 00:33:07 2009 New Revision: 71631 Log: Fix for issue3440: add warning to subprocess discussion of env parameter that on Windows SystemRoot is required in order to run side-by-side assemblies. Modified: python/trunk/Doc/library/subprocess.rst Modified: python/trunk/Doc/library/subprocess.rst ============================================================================== --- python/trunk/Doc/library/subprocess.rst (original) +++ python/trunk/Doc/library/subprocess.rst Thu Apr 16 00:33:07 2009 @@ -102,6 +102,13 @@ variables for the new process; these are used instead of inheriting the current process' environment, which is the default behavior. + .. warning:: + + When replacing the environment you must provide any variables + required for the program to execute. On Windows, in order to run + a side-by-side assembly the specified *env* must include a valid + :envvar:`SystemRoot`. + If *universal_newlines* is :const:`True`, the file objects stdout and stderr are opened as text files, but lines may be terminated by any of ``'\n'``, the Unix end-of-line convention, ``'\r'``, the old Macintosh convention or ``'\r\n'``, the From python-checkins at python.org Thu Apr 16 00:34:30 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 16 Apr 2009 00:34:30 +0200 (CEST) Subject: [Python-checkins] r71632 - in python/branches/release26-maint: Doc/library/subprocess.rst Message-ID: <20090415223430.D97C61E401B@bag.python.org> Author: r.david.murray Date: Thu Apr 16 00:34:30 2009 New Revision: 71632 Log: Merged revisions 71631 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71631 | r.david.murray | 2009-04-15 18:33:07 -0400 (Wed, 15 Apr 2009) | 4 lines Fix for issue3440: add warning to subprocess discussion of env parameter that on Windows SystemRoot is required in order to run side-by-side assemblies. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/subprocess.rst Modified: python/branches/release26-maint/Doc/library/subprocess.rst ============================================================================== --- python/branches/release26-maint/Doc/library/subprocess.rst (original) +++ python/branches/release26-maint/Doc/library/subprocess.rst Thu Apr 16 00:34:30 2009 @@ -102,6 +102,13 @@ variables for the new process; these are used instead of inheriting the current process' environment, which is the default behavior. + .. warning:: + + When replacing the environment you must provide any variables + required for the program to execute. On Windows, in order to run + a side-by-side assembly the specified *env* must include a valid + :envvar:`SystemRoot`. + If *universal_newlines* is :const:`True`, the file objects stdout and stderr are opened as text files, but lines may be terminated by any of ``'\n'``, the Unix end-of-line convention, ``'\r'``, the old Macintosh convention or ``'\r\n'``, the From python-checkins at python.org Thu Apr 16 00:35:15 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 16 Apr 2009 00:35:15 +0200 (CEST) Subject: [Python-checkins] r71633 - in python/branches/py3k: Doc/library/subprocess.rst Message-ID: <20090415223515.539C71E401B@bag.python.org> Author: r.david.murray Date: Thu Apr 16 00:35:15 2009 New Revision: 71633 Log: Merged revisions 71631 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71631 | r.david.murray | 2009-04-15 18:33:07 -0400 (Wed, 15 Apr 2009) | 4 lines Fix for issue3440: add warning to subprocess discussion of env parameter that on Windows SystemRoot is required in order to run side-by-side assemblies. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/subprocess.rst Modified: python/branches/py3k/Doc/library/subprocess.rst ============================================================================== --- python/branches/py3k/Doc/library/subprocess.rst (original) +++ python/branches/py3k/Doc/library/subprocess.rst Thu Apr 16 00:35:15 2009 @@ -97,6 +97,13 @@ variables for the new process; these are used instead of inheriting the current process' environment, which is the default behavior. + .. warning:: + + When replacing the environment you must provide any variables + required for the program to execute. On Windows, in order to run + a side-by-side assembly the specified *env* must include a valid + :envvar:`SystemRoot`. + If *universal_newlines* is :const:`True`, the file objects stdout and stderr are opened as text files, but lines may be terminated by any of ``'\n'``, the Unix end-of-line convention, ``'\r'``, the old Macintosh convention or ``'\r\n'``, the From python-checkins at python.org Thu Apr 16 00:38:32 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 16 Apr 2009 00:38:32 +0200 (CEST) Subject: [Python-checkins] r71634 - in python/branches/release30-maint: Doc/library/subprocess.rst Message-ID: <20090415223832.966E81E401B@bag.python.org> Author: r.david.murray Date: Thu Apr 16 00:38:32 2009 New Revision: 71634 Log: Merged revisions 71633 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71633 | r.david.murray | 2009-04-15 18:35:15 -0400 (Wed, 15 Apr 2009) | 11 lines Merged revisions 71631 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71631 | r.david.murray | 2009-04-15 18:33:07 -0400 (Wed, 15 Apr 2009) | 4 lines Fix for issue3440: add warning to subprocess discussion of env parameter that on Windows SystemRoot is required in order to run side-by-side assemblies. ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Doc/library/subprocess.rst Modified: python/branches/release30-maint/Doc/library/subprocess.rst ============================================================================== --- python/branches/release30-maint/Doc/library/subprocess.rst (original) +++ python/branches/release30-maint/Doc/library/subprocess.rst Thu Apr 16 00:38:32 2009 @@ -97,6 +97,13 @@ variables for the new process; these are used instead of inheriting the current process' environment, which is the default behavior. + .. warning:: + + When replacing the environment you must provide any variables + required for the program to execute. On Windows, in order to run + a side-by-side assembly the specified *env* must include a valid + :envvar:`SystemRoot`. + If *universal_newlines* is :const:`True`, the file objects stdout and stderr are opened as text files, but lines may be terminated by any of ``'\n'``, the Unix end-of-line convention, ``'\r'``, the old Macintosh convention or ``'\r\n'``, the From python at rcn.com Thu Apr 16 00:51:57 2009 From: python at rcn.com (Raymond Hettinger) Date: Wed, 15 Apr 2009 15:51:57 -0700 Subject: [Python-checkins] r71634 - in python/branches/release30-maint:Doc/library/subprocess.rst References: <20090415223832.966E81E401B@bag.python.org> Message-ID: Stylistically, we should strongly prefer in-line comments and notes to the ".. warning" directives. Python is not nitroglycerin. We shouldn't fill our docs with big red warning boxes creating the impression that every construct is dangerous, broken, or a complete hack. Instead, it is better to show examples of correct usage, document what a function actually does and note its limitations when necessary. [r.david.murray] > + .. warning:: > + > + When replacing the environment you must provide any variables > + required for the program to execute. On Windows, in order to run > + a side-by-side assembly the specified *env* must include a valid > + :envvar:`SystemRoot`. > + From python-checkins at python.org Thu Apr 16 01:00:41 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 16 Apr 2009 01:00:41 +0200 (CEST) Subject: [Python-checkins] r71635 - in python/branches/release26-maint: Doc/library/asyncore.rst Lib/asyncore.py Lib/test/test_asyncore.py Misc/NEWS Message-ID: <20090415230041.9B9061E4234@bag.python.org> Author: r.david.murray Date: Thu Apr 16 01:00:41 2009 New Revision: 71635 Log: Merged revisions 70873,70904,70934,71490,71553,71579 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70873 | josiah.carlson | 2009-03-31 15:32:34 -0400 (Tue, 31 Mar 2009) | 2 lines This resolves issue 1161031. Tests pass. ........ r70904 | josiah.carlson | 2009-03-31 17:49:36 -0400 (Tue, 31 Mar 2009) | 3 lines Made handle_expt_event() be called last, so that we don't accidentally read after closing the socket. ........ r70934 | josiah.carlson | 2009-03-31 21:28:11 -0400 (Tue, 31 Mar 2009) | 2 lines Fix for failing asyncore tests. ........ r71490 | r.david.murray | 2009-04-11 13:52:56 -0400 (Sat, 11 Apr 2009) | 4 lines Make test_asyncore tests match code changes introduced by the fix to Issue1161031, refactoring the test to simplify it in the process. ........ r71553 | r.david.murray | 2009-04-12 21:06:46 -0400 (Sun, 12 Apr 2009) | 3 lines Adjust test_asyncore to account for intentional asyncore behavior change introduced by r70934 that was causing a test failure when run under -O. ........ r71579 | r.david.murray | 2009-04-13 12:56:32 -0400 (Mon, 13 Apr 2009) | 2 lines Add missing NEWS item for issue1161031 fix. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/asyncore.rst python/branches/release26-maint/Lib/asyncore.py python/branches/release26-maint/Lib/test/test_asyncore.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Doc/library/asyncore.rst ============================================================================== --- python/branches/release26-maint/Doc/library/asyncore.rst (original) +++ python/branches/release26-maint/Doc/library/asyncore.rst Thu Apr 16 01:00:41 2009 @@ -81,7 +81,8 @@ +----------------------+----------------------------------------+ | Event | Description | +======================+========================================+ - | ``handle_connect()`` | Implied by the first write event | + | ``handle_connect()`` | Implied by the first read or write | + | | event | +----------------------+----------------------------------------+ | ``handle_close()`` | Implied by a read event with no data | | | available | Modified: python/branches/release26-maint/Lib/asyncore.py ============================================================================== --- python/branches/release26-maint/Lib/asyncore.py (original) +++ python/branches/release26-maint/Lib/asyncore.py Thu Apr 16 01:00:41 2009 @@ -69,10 +69,12 @@ class ExitNow(Exception): pass +_reraised_exceptions = (ExitNow, KeyboardInterrupt, SystemExit) + def read(obj): try: obj.handle_read_event() - except (ExitNow, KeyboardInterrupt, SystemExit): + except _reraised_exceptions: raise except: obj.handle_error() @@ -80,7 +82,7 @@ def write(obj): try: obj.handle_write_event() - except (ExitNow, KeyboardInterrupt, SystemExit): + except _reraised_exceptions: raise except: obj.handle_error() @@ -88,22 +90,22 @@ def _exception(obj): try: obj.handle_expt_event() - except (ExitNow, KeyboardInterrupt, SystemExit): + except _reraised_exceptions: raise except: obj.handle_error() def readwrite(obj, flags): try: - if flags & (select.POLLIN | select.POLLPRI): + if flags & select.POLLIN: obj.handle_read_event() if flags & select.POLLOUT: obj.handle_write_event() - if flags & (select.POLLERR | select.POLLNVAL): - obj.handle_expt_event() - if flags & select.POLLHUP: + if flags & (select.POLLHUP | select.POLLERR | select.POLLNVAL): obj.handle_close() - except (ExitNow, KeyboardInterrupt, SystemExit): + if flags & select.POLLPRI: + obj.handle_expt_event() + except _reraised_exceptions: raise except: obj.handle_error() @@ -211,6 +213,7 @@ accepting = False closing = False addr = None + ignore_log_types = frozenset(['warning']) def __init__(self, sock=None, map=None): if map is None: @@ -398,7 +401,7 @@ sys.stderr.write('log: %s\n' % str(message)) def log_info(self, message, type='info'): - if __debug__ or type != 'info': + if type not in self.ignore_log_types: print '%s: %s' % (type, message) def handle_read_event(self): @@ -432,22 +435,17 @@ self.handle_write() def handle_expt_event(self): - # if the handle_expt is the same default worthless method, - # we'll not even bother calling it, we'll instead generate - # a useful error - x = True - try: - y1 = self.__class__.handle_expt.im_func - y2 = dispatcher.handle_expt.im_func - x = y1 is y2 - except AttributeError: - pass - - if x: - err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) - msg = _strerror(err) - - raise socket.error(err, msg) + # handle_expt_event() is called if there might be an error on the + # socket, or if there is OOB data + # check for the error condition first + err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) + if err != 0: + # we can get here when select.select() says that there is an + # exceptional condition on the socket + # since there is an error, we'll go ahead and close the socket + # like we would in a subclassed handle_read() that received no + # data + self.handle_close() else: self.handle_expt() @@ -472,7 +470,7 @@ self.handle_close() def handle_expt(self): - self.log_info('unhandled exception', 'warning') + self.log_info('unhandled incoming priority event', 'warning') def handle_read(self): self.log_info('unhandled read event', 'warning') @@ -553,7 +551,7 @@ pass elif not ignore_all: raise - except (ExitNow, KeyboardInterrupt, SystemExit): + except _reraised_exceptions: raise except: if not ignore_all: Modified: python/branches/release26-maint/Lib/test/test_asyncore.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_asyncore.py (original) +++ python/branches/release26-maint/Lib/test/test_asyncore.py Thu Apr 16 01:00:41 2009 @@ -115,12 +115,24 @@ def test_readwrite(self): # Check that correct methods are called by readwrite() + attributes = ('read', 'expt', 'write', 'closed', 'error_handled') + + expected = ( + (select.POLLIN, 'read'), + (select.POLLPRI, 'expt'), + (select.POLLOUT, 'write'), + (select.POLLERR, 'closed'), + (select.POLLHUP, 'closed'), + (select.POLLNVAL, 'closed'), + ) + class testobj: def __init__(self): self.read = False self.write = False self.closed = False self.expt = False + self.error_handled = False def handle_read_event(self): self.read = True @@ -137,54 +149,25 @@ def handle_error(self): self.error_handled = True - for flag in (select.POLLIN, select.POLLPRI): + for flag, expectedattr in expected: tobj = testobj() - self.assertEqual(tobj.read, False) + self.assertEqual(getattr(tobj, expectedattr), False) asyncore.readwrite(tobj, flag) - self.assertEqual(tobj.read, True) - - # check that ExitNow exceptions in the object handler method - # bubbles all the way up through asyncore readwrite call - tr1 = exitingdummy() - self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, flag) - - # check that an exception other than ExitNow in the object handler - # method causes the handle_error method to get called - tr2 = crashingdummy() - asyncore.readwrite(tr2, flag) - self.assertEqual(tr2.error_handled, True) - tobj = testobj() - self.assertEqual(tobj.write, False) - asyncore.readwrite(tobj, select.POLLOUT) - self.assertEqual(tobj.write, True) - - # check that ExitNow exceptions in the object handler method - # bubbles all the way up through asyncore readwrite call - tr1 = exitingdummy() - self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, - select.POLLOUT) - - # check that an exception other than ExitNow in the object handler - # method causes the handle_error method to get called - tr2 = crashingdummy() - asyncore.readwrite(tr2, select.POLLOUT) - self.assertEqual(tr2.error_handled, True) - - for flag in (select.POLLERR, select.POLLHUP, select.POLLNVAL): - tobj = testobj() - self.assertEqual((tobj.expt, tobj.closed)[flag == select.POLLHUP], False) - asyncore.readwrite(tobj, flag) - self.assertEqual((tobj.expt, tobj.closed)[flag == select.POLLHUP], True) + # Only the attribute modified by the routine we expect to be + # called should be True. + for attr in attributes: + self.assertEqual(getattr(tobj, attr), attr==expectedattr) # check that ExitNow exceptions in the object handler method - # bubbles all the way up through asyncore readwrite calls + # bubbles all the way up through asyncore readwrite call tr1 = exitingdummy() self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, flag) # check that an exception other than ExitNow in the object handler # method causes the handle_error method to get called tr2 = crashingdummy() + self.assertEqual(tr2.error_handled, False) asyncore.readwrite(tr2, flag) self.assertEqual(tr2.error_handled, True) @@ -289,15 +272,13 @@ sys.stdout = stdout lines = fp.getvalue().splitlines() - if __debug__: - expected = ['EGGS: %s' % l1, 'info: %s' % l2, 'SPAM: %s' % l3] - else: - expected = ['EGGS: %s' % l1, 'SPAM: %s' % l3] + expected = ['EGGS: %s' % l1, 'info: %s' % l2, 'SPAM: %s' % l3] self.assertEquals(lines, expected) def test_unhandled(self): d = asyncore.dispatcher() + d.ignore_log_types = () # capture output of dispatcher.log_info() (to stdout via print) fp = StringIO() @@ -313,7 +294,7 @@ sys.stdout = stdout lines = fp.getvalue().splitlines() - expected = ['warning: unhandled exception', + expected = ['warning: unhandled incoming priority event', 'warning: unhandled read event', 'warning: unhandled write event', 'warning: unhandled connect event', Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Thu Apr 16 01:00:41 2009 @@ -14,6 +14,15 @@ - Issue #5759: float() didn't call __float__ on str subclasses. +Library +------- + +- Issue #1161031: fix readwrite select flag handling: POLLPRI now + results in a handle_expt_event call, not handle_read_event, and POLLERR + and POLLNVAL now call handle_close, not handle_expt_event. Also, + dispatcher now has an 'ignore_log_types' attribute for suppressing + log messages, which is set to 'warning' by default. + What's New in Python 2.6.2 rc 1 =============================== From python-checkins at python.org Thu Apr 16 01:32:39 2009 From: python-checkins at python.org (eric.smith) Date: Thu, 16 Apr 2009 01:32:39 +0200 (CEST) Subject: [Python-checkins] r71636 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090415233239.C34341E401B@bag.python.org> Author: eric.smith Date: Thu Apr 16 01:32:39 2009 New Revision: 71636 Log: Use fallback code for PyOS_double_to_string when Gay's code isn't available. Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Thu Apr 16 01:32:39 2009 @@ -527,6 +527,120 @@ return buffer; } +#ifdef PY_NO_SHORT_FLOAT_REPR + +/* The fallback code to use if _Py_dg_dtoa is not available. */ + +PyAPI_FUNC(char *) PyOS_double_to_string(double val, + char format_code, + int precision, + int flags, + int *type) +{ + char buf[128]; + char format[32]; + Py_ssize_t len; + char *result; + char *p; + int t; + int upper = 0; + + /* Validate format_code, and map upper and lower case */ + switch (format_code) { + case 'e': /* exponent */ + case 'f': /* fixed */ + case 'g': /* general */ + break; + case 'E': + upper = 1; + format_code = 'e'; + break; + case 'F': + upper = 1; + format_code = 'f'; + break; + case 'G': + upper = 1; + format_code = 'g'; + break; + case 'r': /* repr format */ + /* Supplied precision is unused, must be 0. */ + if (precision != 0) { + PyErr_BadInternalCall(); + return NULL; + } + precision = 17; + format_code = 'g'; + break; + case 's': /* str format */ + /* Supplied precision is unused, must be 0. */ + if (precision != 0) { + PyErr_BadInternalCall(); + return NULL; + } + precision = 12; + format_code = 'g'; + break; + default: + PyErr_BadInternalCall(); + return NULL; + } + + /* Handle nan and inf. */ + if (Py_IS_NAN(val)) { + strcpy(buf, "nan"); + t = Py_DTST_NAN; + } else if (Py_IS_INFINITY(val)) { + if (copysign(1., val) == 1.) + strcpy(buf, "inf"); + else + strcpy(buf, "-inf"); + t = Py_DTST_INFINITE; + } else { + t = Py_DTST_FINITE; + + + if (flags & Py_DTSF_ADD_DOT_0) + format_code = 'Z'; + + PyOS_snprintf(format, 32, "%%%s.%i%c", (flags & Py_DTSF_ALT ? "#" : ""), precision, format_code); + PyOS_ascii_formatd(buf, sizeof(buf), format, val); + } + + len = strlen(buf); + + /* Add 1 for the trailing 0 byte. + Add 1 because we might need to make room for the sign. + */ + result = PyMem_Malloc(len + 2); + if (result == NULL) { + PyErr_NoMemory(); + return NULL; + } + p = result; + + /* Never add sign for nan/inf, even if asked. */ + if (flags & Py_DTSF_SIGN && buf[0] != '-' && t == Py_DTST_FINITE) + *p++ = '+'; + + strcpy(p, buf); + + if (upper) { + /* Convert to upper case. */ + char *p1; + for (p1 = p; *p1; p1++) + *p1 = toupper(*p1); + } + + if (type) + *type = t; + return result; +} + +#else + +/* _Py_dg_dtoa is available. */ + /* I'm using a lookup table here so that I don't have to invent a non-locale specific way to convert to uppercase */ #define OFS_INF 0 @@ -903,3 +1017,4 @@ flags & Py_DTSF_ALT, float_strings, type); } +#endif /* ifdef PY_NO_SHORT_FLOAT_REPR */ From buildbot at python.org Thu Apr 16 01:43:11 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 15 Apr 2009 23:43:11 +0000 Subject: [Python-checkins] buildbot failure in x86 osx.5 2.6 Message-ID: <20090415234312.0F42C1E401B@bag.python.org> The Buildbot has detected a new failure of x86 osx.5 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20osx.5%202.6/builds/257 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: heller-x86-osx5 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: benjamin.peterson,georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From buildbot at python.org Thu Apr 16 02:29:08 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 16 Apr 2009 00:29:08 +0000 Subject: [Python-checkins] buildbot failure in OS X x86 2.6 Message-ID: <20090416002908.8CE3C1E401B@bag.python.org> The Buildbot has detected a new failure of OS X x86 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/OS%20X%20x86%202.6/builds/215 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: noller-osx86 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_asynchat make: *** [buildbottest] Error 1 sincerely, -The Buildbot From rdmurray at bitdance.com Thu Apr 16 02:35:00 2009 From: rdmurray at bitdance.com (R. David Murray) Date: Wed, 15 Apr 2009 20:35:00 -0400 (EDT) Subject: [Python-checkins] r71634 - in python/branches/release30-maint:Doc/library/subprocess.rst In-Reply-To: References: <20090415223832.966E81E401B@bag.python.org> Message-ID: On Wed, 15 Apr 2009 at 15:51, Raymond Hettinger wrote: > Stylistically, we should strongly prefer in-line comments and notes to the > ".. warning" directives. I agree with you, and in fact I started out with a note. However, the fact is that if you replace the environment on Windows and don't specify SystemRoot, then in general the program you try to call will not run. A note felt too tame when I read it over. It seemed to me that that this rated a warning, and Georg was fine with it. The person who analyzed the "bug" wanted to have subprocess automatically add SystemRoot to the environment if it wasn't there, but doing that seemed wrong to me. I'll change it to a note if you still think a warning is excessive. I agree that it could well be. --David From python at rcn.com Thu Apr 16 02:46:32 2009 From: python at rcn.com (Raymond Hettinger) Date: Wed, 15 Apr 2009 17:46:32 -0700 Subject: [Python-checkins] r71634 - in python/branches/release30-maint:Doc/library/subprocess.rst References: <20090415223832.966E81E401B@bag.python.org> Message-ID: <79EF64D956014374AF51E55F66A2CB43@RaymondLaptop1> [R. David Murray] > I'll change it to a note if you still think a warning is excessive. > I agree that it could well be. Thanks, I would appreciate it if you took out the "..warning directive". Unfortunately, the warnings are rendered in big pink boxes that visually dominate everything surrounding them, essentially making the warning more important than the regular docs beside them. When looking at docs for other languages and tools, we don't see them filled with this sort of thing. Too many warnings in the docs makes the language look fragile. Raymond P.S. While you're making the edit, it would be nice to change the phrasing to not use "you". Unfortunately, the docs already have a lot of "when you do this" and "you should do that", but but we shouldn't make it worse. Fred Drake used to monitor the docs for style, tone, grammar and whatnot but now we don't have the services of an editor. From python-checkins at python.org Thu Apr 16 02:49:46 2009 From: python-checkins at python.org (barry.warsaw) Date: Thu, 16 Apr 2009 02:49:46 +0200 (CEST) Subject: [Python-checkins] r71637 - python/branches/release26-maint/Include/patchlevel.h Message-ID: <20090416004946.595551E4232@bag.python.org> Author: barry.warsaw Date: Thu Apr 16 02:49:46 2009 New Revision: 71637 Log: Post release version tweak. Modified: python/branches/release26-maint/Include/patchlevel.h Modified: python/branches/release26-maint/Include/patchlevel.h ============================================================================== --- python/branches/release26-maint/Include/patchlevel.h (original) +++ python/branches/release26-maint/Include/patchlevel.h Thu Apr 16 02:49:46 2009 @@ -27,7 +27,7 @@ #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "2.6.2" +#define PY_VERSION "2.6.2+" /*--end constants--*/ /* Subversion Revision number of this file (not of the repository) */ From buildbot at python.org Thu Apr 16 03:12:34 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 16 Apr 2009 01:12:34 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 2.6 Message-ID: <20090416011235.51AE81E4028@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%202.6/builds/248 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_import make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Thu Apr 16 03:15:16 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 16 Apr 2009 01:15:16 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090416011516.2A3A21E4028@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/268 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: benjamin.peterson,matthias.klose BUILD FAILED: failed test Excerpt from the test logfile: 3 tests failed: test_distutils test_posix test_subprocess ====================================================================== FAIL: test_get_python_inc (distutils.tests.test_sysconfig.SysconfigTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/distutils/tests/test_sysconfig.py", line 45, in test_get_python_inc self.assert_(os.path.isdir(inc_dir), inc_dir) AssertionError: /home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/Include ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From python-checkins at python.org Thu Apr 16 05:18:06 2009 From: python-checkins at python.org (collin.winter) Date: Thu, 16 Apr 2009 05:18:06 +0200 (CEST) Subject: [Python-checkins] r71638 - in python/branches/py3k: Lib/test/pickletester.py Lib/test/test_pickle.py Message-ID: <20090416031806.A124A1E4016@bag.python.org> Author: collin.winter Date: Thu Apr 16 05:18:06 2009 New Revision: 71638 Log: Port r71408 to py3k: issue 5665, add more pickling tests. Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/pickletester.py python/branches/py3k/Lib/test/test_pickle.py Modified: python/branches/py3k/Lib/test/pickletester.py ============================================================================== --- python/branches/py3k/Lib/test/pickletester.py (original) +++ python/branches/py3k/Lib/test/pickletester.py Thu Apr 16 05:18:06 2009 @@ -1,3 +1,4 @@ +import io import unittest import pickle import pickletools @@ -842,7 +843,7 @@ self.assertEqual(x.bar, y.bar) def test_reduce_overrides_default_reduce_ex(self): - for proto in 0, 1, 2: + for proto in protocols: x = REX_one() self.assertEqual(x._reduce_called, 0) s = self.dumps(x, proto) @@ -851,7 +852,7 @@ self.assertEqual(y._reduce_called, 0) def test_reduce_ex_called(self): - for proto in 0, 1, 2: + for proto in protocols: x = REX_two() self.assertEqual(x._proto, None) s = self.dumps(x, proto) @@ -860,7 +861,7 @@ self.assertEqual(y._proto, None) def test_reduce_ex_overrides_reduce(self): - for proto in 0, 1, 2: + for proto in protocols: x = REX_three() self.assertEqual(x._proto, None) s = self.dumps(x, proto) @@ -869,7 +870,7 @@ self.assertEqual(y._proto, None) def test_reduce_ex_calls_base(self): - for proto in 0, 1, 2: + for proto in protocols: x = REX_four() self.assertEqual(x._proto, None) s = self.dumps(x, proto) @@ -878,7 +879,7 @@ self.assertEqual(y._proto, proto) def test_reduce_calls_base(self): - for proto in 0, 1, 2: + for proto in protocols: x = REX_five() self.assertEqual(x._reduce_called, 0) s = self.dumps(x, proto) @@ -917,6 +918,20 @@ except (pickle.PickleError): pass + def test_many_puts_and_gets(self): + # Test that internal data structures correctly deal with lots of + # puts/gets. + keys = ("aaa" + str(i) for i in range(100)) + large_dict = dict((k, [4, 5, 6]) for k in keys) + obj = [dict(large_dict), dict(large_dict), dict(large_dict)] + + for proto in protocols: + dumped = self.dumps(obj, proto) + loaded = self.loads(dumped) + self.assertEqual(loaded, obj, + "Failed protocol %d: %r != %r" + % (proto, obj, loaded)) + # Test classes for reduce_ex class REX_one(object): @@ -1002,6 +1017,7 @@ def __getattr__(self, key): self.foo + class AbstractPickleModuleTests(unittest.TestCase): def test_dump_closed_file(self): @@ -1022,13 +1038,20 @@ finally: os.remove(TESTFN) + def test_load_from_and_dump_to_file(self): + stream = io.BytesIO() + data = [123, {}, 124] + pickle.dump(data, stream) + stream.seek(0) + unpickled = pickle.load(stream) + self.assertEqual(unpickled, data) + def test_highest_protocol(self): # Of course this needs to be changed when HIGHEST_PROTOCOL changes. self.assertEqual(pickle.HIGHEST_PROTOCOL, 3) def test_callapi(self): - from io import BytesIO - f = BytesIO() + f = io.BytesIO() # With and without keyword arguments pickle.dump(123, f, -1) pickle.dump(123, file=f, protocol=-1) @@ -1039,7 +1062,6 @@ def test_bad_init(self): # Test issue3664 (pickle can segfault from a badly initialized Pickler). - from io import BytesIO # Override initialization without calling __init__() of the superclass. class BadPickler(pickle.Pickler): def __init__(self): pass @@ -1091,6 +1113,121 @@ self.assertEqual(self.id_count, 5) self.assertEqual(self.load_count, 5) + +class AbstractPicklerUnpicklerObjectTests(unittest.TestCase): + + pickler_class = None + unpickler_class = None + + def setUp(self): + assert self.pickler_class + assert self.unpickler_class + + def test_clear_pickler_memo(self): + # To test whether clear_memo() has any effect, we pickle an object, + # then pickle it again without clearing the memo; the two serialized + # forms should be different. If we clear_memo() and then pickle the + # object again, the third serialized form should be identical to the + # first one we obtained. + data = ["abcdefg", "abcdefg", 44] + f = io.BytesIO() + pickler = self.pickler_class(f) + + pickler.dump(data) + first_pickled = f.getvalue() + + # Reset StringIO object. + f.seek(0) + f.truncate() + + pickler.dump(data) + second_pickled = f.getvalue() + + # Reset the Pickler and StringIO objects. + pickler.clear_memo() + f.seek(0) + f.truncate() + + pickler.dump(data) + third_pickled = f.getvalue() + + self.assertNotEqual(first_pickled, second_pickled) + self.assertEqual(first_pickled, third_pickled) + + def test_priming_pickler_memo(self): + # Verify that we can set the Pickler's memo attribute. + data = ["abcdefg", "abcdefg", 44] + f = io.BytesIO() + pickler = self.pickler_class(f) + + pickler.dump(data) + first_pickled = f.getvalue() + + f = io.BytesIO() + primed = self.pickler_class(f) + primed.memo = pickler.memo + + primed.dump(data) + primed_pickled = f.getvalue() + + self.assertNotEqual(first_pickled, primed_pickled) + + def test_priming_unpickler_memo(self): + # Verify that we can set the Unpickler's memo attribute. + data = ["abcdefg", "abcdefg", 44] + f = io.BytesIO() + pickler = self.pickler_class(f) + + pickler.dump(data) + first_pickled = f.getvalue() + + f = io.BytesIO() + primed = self.pickler_class(f) + primed.memo = pickler.memo + + primed.dump(data) + primed_pickled = f.getvalue() + + unpickler = self.unpickler_class(io.BytesIO(first_pickled)) + unpickled_data1 = unpickler.load() + + self.assertEqual(unpickled_data1, data) + + primed = self.unpickler_class(io.BytesIO(primed_pickled)) + primed.memo = unpickler.memo + unpickled_data2 = primed.load() + + primed.memo.clear() + + self.assertEqual(unpickled_data2, data) + self.assertTrue(unpickled_data2 is unpickled_data1) + + def test_reusing_unpickler_objects(self): + data1 = ["abcdefg", "abcdefg", 44] + f = io.BytesIO() + pickler = self.pickler_class(f) + pickler.dump(data1) + pickled1 = f.getvalue() + + data2 = ["abcdefg", 44, 44] + f = io.BytesIO() + pickler = self.pickler_class(f) + pickler.dump(data2) + pickled2 = f.getvalue() + + f = io.BytesIO() + f.write(pickled1) + f.seek(0) + unpickler = self.unpickler_class(f) + self.assertEqual(unpickler.load(), data1) + + f.seek(0) + f.truncate() + f.write(pickled2) + f.seek(0) + self.assertEqual(unpickler.load(), data2) + + if __name__ == "__main__": # Print some stuff that can be used to rewrite DATA{0,1,2} from pickletools import dis Modified: python/branches/py3k/Lib/test/test_pickle.py ============================================================================== --- python/branches/py3k/Lib/test/test_pickle.py (original) +++ python/branches/py3k/Lib/test/test_pickle.py Thu Apr 16 05:18:06 2009 @@ -6,6 +6,7 @@ from test.pickletester import AbstractPickleTests from test.pickletester import AbstractPickleModuleTests from test.pickletester import AbstractPersistentPicklerTests +from test.pickletester import AbstractPicklerUnpicklerObjectTests try: import _pickle @@ -60,6 +61,12 @@ return u.load() +class PyPicklerUnpicklerObjectTests(AbstractPicklerUnpicklerObjectTests): + + pickler_class = pickle._Pickler + unpickler_class = pickle._Unpickler + + if has_c_implementation: class CPicklerTests(PyPicklerTests): pickler = _pickle.Pickler @@ -69,11 +76,26 @@ pickler = _pickle.Pickler unpickler = _pickle.Unpickler + class CDumpPickle_LoadPickle(PyPicklerTests): + pickler = _pickle.Pickler + unpickler = pickle._Unpickler + + class DumpPickle_CLoadPickle(PyPicklerTests): + pickler = pickle._Pickler + unpickler = _pickle.Unpickler + + class CPicklerUnpicklerObjectTests(AbstractPicklerUnpicklerObjectTests): + pickler_class = _pickle.Pickler + unpickler_class = _pickle.Unpickler + def test_main(): tests = [PickleTests, PyPicklerTests, PyPersPicklerTests] if has_c_implementation: - tests.extend([CPicklerTests, CPersPicklerTests]) + tests.extend([CPicklerTests, CPersPicklerTests, + CDumpPickle_LoadPickle, DumpPickle_CLoadPickle, + PyPicklerUnpicklerObjectTests, + CPicklerUnpicklerObjectTests]) support.run_unittest(*tests) support.run_doctest(pickle) From python-checkins at python.org Thu Apr 16 05:25:44 2009 From: python-checkins at python.org (hirokazu.yamamoto) Date: Thu, 16 Apr 2009 05:25:44 +0200 (CEST) Subject: [Python-checkins] r71639 - in python/branches/release26-maint: Doc/make.bat Message-ID: <20090416032544.DE3D21E4016@bag.python.org> Author: hirokazu.yamamoto Date: Thu Apr 16 05:25:44 2009 New Revision: 71639 Log: Merged revisions 71380 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71380 | raymond.hettinger | 2009-04-08 06:43:51 +0900 | 1 line Fix make.bat to match makefile changes ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/make.bat Modified: python/branches/release26-maint/Doc/make.bat ============================================================================== --- python/branches/release26-maint/Doc/make.bat (original) +++ python/branches/release26-maint/Doc/make.bat Thu Apr 16 05:25:44 2009 @@ -34,7 +34,7 @@ goto end :checkout -svn co %SVNROOT%/doctools/trunk/sphinx tools/sphinx +svn co %SVNROOT%/external/Sphinx-0.6.1/sphinx tools/sphinx svn co %SVNROOT%/external/docutils-0.5/docutils tools/docutils svn co %SVNROOT%/external/Jinja-2.1.1/jinja2 tools/jinja2 svn co %SVNROOT%/external/Pygments-0.11.1/pygments tools/pygments From python-checkins at python.org Thu Apr 16 08:26:34 2009 From: python-checkins at python.org (thomas.heller) Date: Thu, 16 Apr 2009 08:26:34 +0200 (CEST) Subject: [Python-checkins] r71640 - in python/trunk/Modules/_ctypes: _ctypes.c callbacks.c ctypes.h Message-ID: <20090416062634.2C2CA1E401B@bag.python.org> Author: thomas.heller Date: Thu Apr 16 08:26:33 2009 New Revision: 71640 Log: Remove unneeded code. Modified: python/trunk/Modules/_ctypes/_ctypes.c python/trunk/Modules/_ctypes/callbacks.c python/trunk/Modules/_ctypes/ctypes.h Modified: python/trunk/Modules/_ctypes/_ctypes.c ============================================================================== --- python/trunk/Modules/_ctypes/_ctypes.c (original) +++ python/trunk/Modules/_ctypes/_ctypes.c Thu Apr 16 08:26:33 2009 @@ -5606,11 +5606,6 @@ Py_INCREF(PyExc_ArgError); PyModule_AddObject(m, "ArgumentError", PyExc_ArgError); } - /************************************************* - * - * Others... - */ - init_callbacks_in_module(m); } /***************************************************************** Modified: python/trunk/Modules/_ctypes/callbacks.c ============================================================================== --- python/trunk/Modules/_ctypes/callbacks.c (original) +++ python/trunk/Modules/_ctypes/callbacks.c Thu Apr 16 08:26:33 2009 @@ -466,17 +466,6 @@ return NULL; } -/**************************************************************************** - * - * callback objects: initialization - */ - -void init_callbacks_in_module(PyObject *m) -{ - if (PyType_Ready((PyTypeObject *)&PyType_Type) < 0) - return; -} - #ifdef MS_WIN32 static void LoadPython(void) Modified: python/trunk/Modules/_ctypes/ctypes.h ============================================================================== --- python/trunk/Modules/_ctypes/ctypes.h (original) +++ python/trunk/Modules/_ctypes/ctypes.h Thu Apr 16 08:26:33 2009 @@ -189,8 +189,6 @@ extern PyObject * CreateArrayType(PyObject *itemtype, Py_ssize_t length); -extern void init_callbacks_in_module(PyObject *m); - extern PyMethodDef module_methods[]; extern CThunkObject *AllocFunctionCallback(PyObject *callable, From python-checkins at python.org Thu Apr 16 08:42:02 2009 From: python-checkins at python.org (thomas.heller) Date: Thu, 16 Apr 2009 08:42:02 +0200 (CEST) Subject: [Python-checkins] r71641 - in python/trunk/Modules/_ctypes: ctypes.h malloc_closure.c Message-ID: <20090416064202.D78031E401B@bag.python.org> Author: thomas.heller Date: Thu Apr 16 08:42:02 2009 New Revision: 71641 Log: Remove duplicated function declaration. Make _pagesize static. Modified: python/trunk/Modules/_ctypes/ctypes.h python/trunk/Modules/_ctypes/malloc_closure.c Modified: python/trunk/Modules/_ctypes/ctypes.h ============================================================================== --- python/trunk/Modules/_ctypes/ctypes.h (original) +++ python/trunk/Modules/_ctypes/ctypes.h Thu Apr 16 08:42:02 2009 @@ -351,7 +351,6 @@ }; extern PyTypeObject PyCArg_Type; -extern PyCArgObject *new_CArgObject(void); #define PyCArg_CheckExact(v) ((v)->ob_type == &PyCArg_Type) extern PyCArgObject *new_CArgObject(void); Modified: python/trunk/Modules/_ctypes/malloc_closure.c ============================================================================== --- python/trunk/Modules/_ctypes/malloc_closure.c (original) +++ python/trunk/Modules/_ctypes/malloc_closure.c Thu Apr 16 08:42:02 2009 @@ -32,7 +32,7 @@ } ITEM; static ITEM *free_list; -int _pagesize; +static int _pagesize; static void more_core(void) { From python-checkins at python.org Thu Apr 16 12:46:23 2009 From: python-checkins at python.org (eric.smith) Date: Thu, 16 Apr 2009 12:46:23 +0200 (CEST) Subject: [Python-checkins] r71642 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090416104623.C722A1E4011@bag.python.org> Author: eric.smith Date: Thu Apr 16 12:46:23 2009 New Revision: 71642 Log: When using Py_DTSF_ADD_DOT_O, Don't add '.0' if we have an exponent. The output already looks like a float, no reason to modify it further. Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Thu Apr 16 12:46:23 2009 @@ -333,8 +333,9 @@ } } -/* Ensure that buffer has a decimal point in it. The decimal point - will not be in the current locale, it will always be '.' */ +/* Ensure that buffer has a decimal point in it. The decimal point will not + be in the current locale, it will always be '.'. Don't add a decimal if an + exponent is present. */ Py_LOCAL_INLINE(void) ensure_decimal_point(char* buffer, size_t buf_size) { @@ -363,7 +364,8 @@ insert_count = 1; } } - else { + else if (!(*p == 'e' || *p == 'E')) { + /* Don't add ".0" if we have an exponent. */ chars_to_insert = ".0"; insert_count = 2; } From python-checkins at python.org Thu Apr 16 13:13:51 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 16 Apr 2009 13:13:51 +0200 (CEST) Subject: [Python-checkins] r71643 - python/branches/py3k-short-float-repr/Python/sysmodule.c Message-ID: <20090416111351.194B71E4011@bag.python.org> Author: mark.dickinson Date: Thu Apr 16 13:13:50 2009 New Revision: 71643 Log: Add sys.float_repr_style attribute, for use in testing Modified: python/branches/py3k-short-float-repr/Python/sysmodule.c Modified: python/branches/py3k-short-float-repr/Python/sysmodule.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/sysmodule.c (original) +++ python/branches/py3k-short-float-repr/Python/sysmodule.c Thu Apr 16 13:13:50 2009 @@ -1025,6 +1025,7 @@ executable -- pathname of this Python interpreter\n\ prefix -- prefix used to find the Python library\n\ exec_prefix -- prefix used to find the machine-specific Python library\n\ +float_repr_style -- string indicating the style of repr() output for floats\n\ " ) #ifdef MS_WINDOWS @@ -1428,6 +1429,15 @@ FlagsType.tp_init = NULL; FlagsType.tp_new = NULL; + /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */ +#ifndef PY_NO_SHORT_FLOAT_REPR + SET_SYS_FROM_STRING("float_repr_style", + PyUnicode_FromString("short")); +#else + SET_SYS_FROM_STRING("float_repr_style", + PyUnicode_FromString("legacy")); +#endif + #undef SET_SYS_FROM_STRING if (PyErr_Occurred()) return NULL; From python-checkins at python.org Thu Apr 16 14:07:33 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 16 Apr 2009 14:07:33 +0200 (CEST) Subject: [Python-checkins] r71644 - in python/branches/py3k-short-float-repr/Lib/test: formatfloat_testcases.txt test_float.py Message-ID: <20090416120733.218281E4011@bag.python.org> Author: mark.dickinson Date: Thu Apr 16 14:07:32 2009 New Revision: 71644 Log: Adapt float formatting tests to deal with possibliity that we're not using the short float repr. Modified: python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt python/branches/py3k-short-float-repr/Lib/test/test_float.py Modified: python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt (original) +++ python/branches/py3k-short-float-repr/Lib/test/formatfloat_testcases.txt Thu Apr 16 14:07:32 2009 @@ -314,47 +314,8 @@ %#.5g 234.56 -> 234.56 %#.6g 234.56 -> 234.560 --- repr formatting. Should always include a decimal point (and at --- least one digit after the point) or an exponent. Produces the shortest --- string that rounds correctly. - -%r 0 -> 0.0 -%r 1 -> 1.0 - --- check short repr -%r 0.01 -> 0.01 -%r 0.02 -> 0.02 -%r 0.03 -> 0.03 -%r 0.04 -> 0.04 -%r 0.05 -> 0.05 -%r 1.23456789 -> 1.23456789 -%r 10 -> 10.0 -%r 100 -> 100.0 - --- values >= 1e16 get an exponent -%r 1e15 -> 1000000000000000.0 -%r 0.999999999999e16 -> 9999999999990000.0 -%r 1e16 -> 1e+16 -%r 1.000000000001e16 -> 1.000000000001e+16 -%r 1e17 -> 1e+17 - --- as do values < 1e-4 -%r 1e-3 -> 0.001 -%r 1.001e-4 -> 0.0001001 -%r 1.000000000001e-4 -> 0.0001000000000001 -%r 1e-4 -> 0.0001 -%r 0.999999999999e-4 -> 9.99999999999e-05 -%r 0.999e-4 -> 9.99e-05 -%r 1e-5 -> 1e-05 - --- some values that are designed to fail if the FPU rounding --- precision is 64-bits. -%r 8.72293771110361e+25 -> 8.72293771110361e+25 -%r 7.47005307342313e+26 -> 7.47005307342313e+26 -%r 2.86438000439698e+28 -> 2.86438000439698e+28 -%r 8.89142905246179e+28 -> 8.89142905246179e+28 -%r 3.08578087079232e+35 -> 3.08578087079232e+35 - +-- for repr formatting see the separate test_short_repr test in +-- test_float.py. Not all platforms use short repr for floats. -- str formatting. Result always includes decimal point and at -- least one digit after the point, or an exponent. Modified: python/branches/py3k-short-float-repr/Lib/test/test_float.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_float.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_float.py Thu Apr 16 14:07:32 2009 @@ -1,6 +1,7 @@ import unittest, struct import os +import sys from test import support import math from math import isinf, isnan, copysign, ldexp @@ -14,6 +15,9 @@ test_dir = os.path.dirname(__file__) or os.curdir format_testfile = os.path.join(test_dir, 'formatfloat_testcases.txt') +# determine whether we're using short float repr or not +short_float_repr = getattr(sys, 'float_repr_style', 'none') == 'short' + class GeneralFloatCases(unittest.TestCase): def test_float(self): @@ -333,6 +337,56 @@ self.assertEqual(fmt % float(arg), rhs) self.assertEqual(fmt % -float(arg), '-' + rhs) + @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short', + "applies only when using short float repr style") + def test_short_repr(self): + # test short float repr introduced in Python 3.1. One aspect + # of this repr is that we get some degree of str -> float -> + # str roundtripping. In particular, for any numeric string + # containing 15 or fewer significant digits, those exact same + # digits (modulo trailing zeros) should appear in the output. + # No more repr(0.03) -> "0.029999999999999999"! + + test_strings = [ + # output always includes *either* a decimal point and at + # least one digit after that point, or an exponent. + '0.0', + '1.0', + '0.01', + '0.02', + '0.03', + '0.04', + '0.05', + '1.23456789', + '10.0', + '100.0', + # values >= 1e16 get an exponent... + '1000000000000000.0', + '9999999999999990.0', + '1e+16', + '1e+17', + # ... and so do values < 1e-4 + '0.001', + '0.001001', + '0.00010000000000001', + '0.0001', + '9.999999999999e-05', + '1e-05', + # values designed to provoke failure if the FPU rounding + # precision isn't set correctly + '8.72293771110361e+25', + '7.47005307342313e+26', + '2.86438000439698e+28', + '8.89142905246179e+28', + '3.08578087079232e+35', + ] + + for s in test_strings: + negs = '-'+s + self.assertEqual(s, repr(float(s))) + self.assertEqual(negs, repr(float(negs))) + + # Beginning with Python 2.6 float has cross platform compatible # ways to create and represent inf and nan From python-checkins at python.org Thu Apr 16 14:38:14 2009 From: python-checkins at python.org (eric.smith) Date: Thu, 16 Apr 2009 14:38:14 +0200 (CEST) Subject: [Python-checkins] r71645 - python/branches/py3k-short-float-repr/Python/pystrtod.c Message-ID: <20090416123814.ED47F1E4011@bag.python.org> Author: eric.smith Date: Thu Apr 16 14:38:14 2009 New Revision: 71645 Log: Removed unused 'n' formatting code in PyOS_ascii_formatd. The equivalent code is now in float.__format__. Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Thu Apr 16 14:38:14 2009 @@ -384,40 +384,6 @@ } } -/* Add the locale specific grouping characters to buffer. Note - that any decimal point (if it's present) in buffer is already - locale-specific. Return 0 on error, else 1. */ -Py_LOCAL_INLINE(int) -add_thousands_grouping(char* buffer, size_t buf_size) -{ -#if 0 - Py_ssize_t len = strlen(buffer); - struct lconv *locale_data = localeconv(); - const char *decimal_point = locale_data->decimal_point; - - /* Find the decimal point, if any. We're only concerned - about the characters to the left of the decimal when - adding grouping. */ - char *p = strstr(buffer, decimal_point); - if (!p) { - /* No decimal, use the entire string. */ - - /* If any exponent, adjust p. */ - p = strpbrk(buffer, "eE"); - if (!p) - /* No exponent and no decimal. Use the entire - string. */ - p = buffer + len; - } - /* At this point, p points just past the right-most character we - want to format. We need to add the grouping string for the - characters between buffer and p. */ - return _PyBytes_InsertThousandsGroupingLocale(buffer, len, p-buffer, - buf_size, NULL, 1, 1); -#endif - return 1; -} - /* see FORMATBUFLEN in unicodeobject.c */ #define FLOAT_FORMATBUFLEN 120 @@ -432,9 +398,8 @@ * Converts a #gdouble to a string, using the '.' as * decimal point. To format the number you pass in * a printf()-style format string. Allowed conversion - * specifiers are 'e', 'E', 'f', 'F', 'g', 'G', and 'n'. + * specifiers are 'e', 'E', 'f', 'F', 'g', 'G', and 'Z'. * - * 'n' is the same as 'g', except it uses the current locale. * 'Z' is the same as 'g', except it always has a decimal and * at least one digit after the decimal. * @@ -449,11 +414,6 @@ char format_char; size_t format_len = strlen(format); - /* For type 'n', we need to make a copy of the format string, because - we're going to modify 'n' -> 'g', and format is const char*, so we - can't modify it directly. FLOAT_FORMATBUFLEN should be longer than - we ever need this to be. There's an upcoming check to ensure it's - big enough. */ /* Issue 2264: code 'Z' requires copying the format. 'Z' is 'g', but also with at least one character past the decimal. */ char tmp_format[FLOAT_FORMATBUFLEN]; @@ -479,12 +439,12 @@ if (!(format_char == 'e' || format_char == 'E' || format_char == 'f' || format_char == 'F' || format_char == 'g' || format_char == 'G' || - format_char == 'n' || format_char == 'Z')) + format_char == 'Z')) return NULL; - /* Map 'n' or 'Z' format_char to 'g', by copying the format string and + /* Map 'Z' format_char to 'g', by copying the format string and replacing the final char with a 'g' */ - if (format_char == 'n' || format_char == 'Z') { + if (format_char == 'Z') { if (format_len + 1 >= sizeof(tmp_format)) { /* The format won't fit in our copy. Error out. In practice, this will never happen and will be @@ -503,11 +463,8 @@ /* Do various fixups on the return string */ /* Get the current locale, and find the decimal point string. - Convert that string back to a dot. Do not do this if using the - 'n' (number) format code, since we want to keep the localized - decimal point in that case. */ - if (format_char != 'n') - change_decimal_from_locale_to_dot(buffer); + Convert that string back to a dot. */ + change_decimal_from_locale_to_dot(buffer); /* If an exponent exists, ensure that the exponent is at least MIN_EXPONENT_DIGITS digits, providing the buffer is large enough @@ -521,11 +478,6 @@ if (format_char == 'Z') ensure_decimal_point(buffer, buf_size); - /* If format_char is 'n', add the thousands grouping. */ - if (format_char == 'n') - if (!add_thousands_grouping(buffer, buf_size)) - return NULL; - return buffer; } From python-checkins at python.org Thu Apr 16 14:50:15 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 16 Apr 2009 14:50:15 +0200 (CEST) Subject: [Python-checkins] r71646 - python/branches/py3k-short-float-repr/Doc/library/sys.rst Message-ID: <20090416125015.1AA391E4070@bag.python.org> Author: mark.dickinson Date: Thu Apr 16 14:50:14 2009 New Revision: 71646 Log: Add docs for sys.float_repr_style Modified: python/branches/py3k-short-float-repr/Doc/library/sys.rst Modified: python/branches/py3k-short-float-repr/Doc/library/sys.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/sys.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/sys.rst Thu Apr 16 14:50:14 2009 @@ -266,6 +266,19 @@ The information in the table is simplified. +.. data:: float_repr_style + + A string indicating how the :func:`repr` function behaves for + floats. If the string has value ``'short'`` then for a finite + float ``x``, ``repr(x)`` aims to produce a short string with the + property that ``float(repr(x)) == x``. This is the usual behaviour + in Python 3.1 and later. Otherwise, ``float_repr_style`` has value + ``'legacy'`` and ``repr(x)`` behaves in the same way as it did in + versions of Python prior to 3.1. + + .. versionadded:: 3.1 + + .. function:: getcheckinterval() Return the interpreter's "check interval"; see :func:`setcheckinterval`. From python-checkins at python.org Thu Apr 16 14:51:23 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 16 Apr 2009 14:51:23 +0200 (CEST) Subject: [Python-checkins] r71647 - python/branches/py3k-short-float-repr/Lib/test/test_float.py Message-ID: <20090416125123.175131E4070@bag.python.org> Author: mark.dickinson Date: Thu Apr 16 14:51:22 2009 New Revision: 71647 Log: Remove redundant definition Modified: python/branches/py3k-short-float-repr/Lib/test/test_float.py Modified: python/branches/py3k-short-float-repr/Lib/test/test_float.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_float.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_float.py Thu Apr 16 14:51:22 2009 @@ -15,9 +15,6 @@ test_dir = os.path.dirname(__file__) or os.curdir format_testfile = os.path.join(test_dir, 'formatfloat_testcases.txt') -# determine whether we're using short float repr or not -short_float_repr = getattr(sys, 'float_repr_style', 'none') == 'short' - class GeneralFloatCases(unittest.TestCase): def test_float(self): From python-checkins at python.org Thu Apr 16 14:57:18 2009 From: python-checkins at python.org (eric.smith) Date: Thu, 16 Apr 2009 14:57:18 +0200 (CEST) Subject: [Python-checkins] r71648 - in python/branches/py3k-short-float-repr: Doc/library/filesys.rst Doc/library/subprocess.rst Doc/whatsnew/3.1.rst Lib/_pyio.py Lib/distutils/cmd.py Lib/distutils/tests/test_cmd.py Lib/test/pickletester.py Lib/test/test_float.py Lib/test/test_pickle.py Misc/NEWS Objects/floatobject.c Message-ID: <20090416125718.894371E4070@bag.python.org> Author: eric.smith Date: Thu Apr 16 14:57:18 2009 New Revision: 71648 Log: Merged revisions 71580-71581,71587,71590,71598-71599,71606,71608,71626,71628,71633,71638 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71580 | r.david.murray | 2009-04-13 13:00:25 -0400 (Mon, 13 Apr 2009) | 9 lines Merged revisions 71579 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71579 | r.david.murray | 2009-04-13 12:56:32 -0400 (Mon, 13 Apr 2009) | 2 lines Add missing NEWS item for issue1161031 fix. ........ ................ r71581 | r.david.murray | 2009-04-13 13:06:33 -0400 (Mon, 13 Apr 2009) | 2 lines Move NEWS item to correct section. ................ r71587 | tarek.ziade | 2009-04-13 16:07:23 -0400 (Mon, 13 Apr 2009) | 9 lines Merged revisions 71585 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71585 | tarek.ziade | 2009-04-13 22:03:44 +0200 (Mon, 13 Apr 2009) | 1 line improved test coverage for distutils.cmd ........ ................ r71590 | tarek.ziade | 2009-04-13 16:19:58 -0400 (Mon, 13 Apr 2009) | 9 lines Merged revisions 71589 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71589 | tarek.ziade | 2009-04-13 22:14:54 +0200 (Mon, 13 Apr 2009) | 1 line pep8-fied ........ ................ r71598 | raymond.hettinger | 2009-04-14 04:05:31 -0400 (Tue, 14 Apr 2009) | 1 line New module names are lowercase ................ r71599 | raymond.hettinger | 2009-04-14 04:16:50 -0400 (Tue, 14 Apr 2009) | 1 line Fix-up links. ................ r71606 | raymond.hettinger | 2009-04-14 16:45:17 -0400 (Tue, 14 Apr 2009) | 1 line Fix links ................ r71608 | benjamin.peterson | 2009-04-14 18:02:08 -0400 (Tue, 14 Apr 2009) | 1 line other places like this just catch IOError ................ r71626 | benjamin.peterson | 2009-04-15 16:34:30 -0400 (Wed, 15 Apr 2009) | 1 line reference the io momdule in file and directory section ................ r71628 | benjamin.peterson | 2009-04-15 17:34:27 -0400 (Wed, 15 Apr 2009) | 11 lines Merged revisions 71627 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71627 | benjamin.peterson | 2009-04-15 16:26:36 -0500 (Wed, 15 Apr 2009) | 4 lines call __float__ on str subclasses #5759 tests by R. David Murray ........ ................ r71633 | r.david.murray | 2009-04-15 18:35:15 -0400 (Wed, 15 Apr 2009) | 11 lines Merged revisions 71631 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71631 | r.david.murray | 2009-04-15 18:33:07 -0400 (Wed, 15 Apr 2009) | 4 lines Fix for issue3440: add warning to subprocess discussion of env parameter that on Windows SystemRoot is required in order to run side-by-side assemblies. ........ ................ r71638 | collin.winter | 2009-04-15 23:18:06 -0400 (Wed, 15 Apr 2009) | 1 line Port r71408 to py3k: issue 5665, add more pickling tests. ................ Modified: python/branches/py3k-short-float-repr/ (props changed) python/branches/py3k-short-float-repr/Doc/library/filesys.rst python/branches/py3k-short-float-repr/Doc/library/subprocess.rst python/branches/py3k-short-float-repr/Doc/whatsnew/3.1.rst python/branches/py3k-short-float-repr/Lib/_pyio.py python/branches/py3k-short-float-repr/Lib/distutils/cmd.py python/branches/py3k-short-float-repr/Lib/distutils/tests/test_cmd.py python/branches/py3k-short-float-repr/Lib/test/pickletester.py python/branches/py3k-short-float-repr/Lib/test/test_float.py python/branches/py3k-short-float-repr/Lib/test/test_pickle.py python/branches/py3k-short-float-repr/Misc/NEWS python/branches/py3k-short-float-repr/Objects/floatobject.c Modified: python/branches/py3k-short-float-repr/Doc/library/filesys.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/filesys.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/filesys.rst Thu Apr 16 14:57:18 2009 @@ -34,3 +34,7 @@ Operating system interfaces, including functions to work with files at a lower level than the built-in file object. + Module :mod:`io` + Python's framework for dealing with I/O including reading and writing + files. + Modified: python/branches/py3k-short-float-repr/Doc/library/subprocess.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/library/subprocess.rst (original) +++ python/branches/py3k-short-float-repr/Doc/library/subprocess.rst Thu Apr 16 14:57:18 2009 @@ -97,6 +97,13 @@ variables for the new process; these are used instead of inheriting the current process' environment, which is the default behavior. + .. warning:: + + When replacing the environment you must provide any variables + required for the program to execute. On Windows, in order to run + a side-by-side assembly the specified *env* must include a valid + :envvar:`SystemRoot`. + If *universal_newlines* is :const:`True`, the file objects stdout and stderr are opened as text files, but lines may be terminated by any of ``'\n'``, the Unix end-of-line convention, ``'\r'``, the old Macintosh convention or ``'\r\n'``, the Modified: python/branches/py3k-short-float-repr/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k-short-float-repr/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k-short-float-repr/Doc/whatsnew/3.1.rst Thu Apr 16 14:57:18 2009 @@ -57,8 +57,8 @@ Regular Python dictionaries iterate over key/value pairs in arbitrary order. Over the years, a number of authors have written alternative implementations that remember the order that the keys were originally inserted. Based on -the experiences from those implementations, the :mod:`collections` module -now has an :class:`OrderedDict` class. +the experiences from those implementations, a new +:class:`collections.OrderedDict` class has been introduced. The OrderedDict API is substantially the same as regular dictionaries but will iterate over keys and values in a guaranteed order depending on @@ -67,9 +67,9 @@ reinserting it will move it to the end. The standard library now supports use of ordered dictionaries in several -modules. The :mod:`ConfigParser` module uses them by default. This lets +modules. The :mod:`configparser` module uses them by default. This lets configuration files be read, modified, and then written back in their original -order. The :mod:`collections` module's :meth:`namedtuple._asdict` method now +order. The *_asdict()* method for :func:`collections.namedtuple` now returns an ordered dictionary with the values appearing in the same order as the underlying tuple indicies. The :mod:`json` module is being built-out with an *object_pairs_hook* to allow OrderedDicts to be built by the decoder. @@ -103,7 +103,7 @@ .. seealso:: :pep:`378` - Format Specifier for Thousands Separator - PEP written by Raymond Hettinger; implemented by Eric Smith and + PEP written by Raymond Hettinger and implemented by Eric Smith and Mark Dickinson. @@ -233,15 +233,15 @@ (Contributed by Gregory Smith.) -* The :mod:`logging` module now implements a simple :class:`NullHandler` +* The :mod:`logging` module now implements a simple :class:`logging.NullHandler` class for applications that are not using logging but are calling library code that does. Setting-up a null handler will suppress - spurious warnings like "No handlers could be found for logger X.Y.Z":: + spurious warnings such as "No handlers could be found for logger foo":: >>> h = logging.NullHandler() >>> logging.getLogger("foo").addHandler(h) - (Contributed by Vinay Sajip; issue:`4384`). + (Contributed by Vinay Sajip; :issue:`4384`). * The :mod:`runpy` module which supports the ``-m`` command line switch now supports the execution of packages by looking for and executing @@ -279,7 +279,8 @@ def test_gimzo_without_required_library(self): ... - Also, tests for exceptions have been builtout to work with context managers:: + Also, tests for exceptions have been builtout to work with context managers + using the :keyword:`with` statement:: def test_division_by_zero(self): with self.assertRaises(ZeroDivisionError): @@ -305,7 +306,7 @@ (Contributed by Ross Light; :issue:`4285`.) * A new module, :mod:`importlib` was added. It provides a complete, portable, - pure Python reference implementation of the *import* statement and its + pure Python reference implementation of the :keyword:`import` statement and its counterpart, the :func:`__import__` function. It represents a substantial step forward in documenting and defining the actions that take place during imports. Modified: python/branches/py3k-short-float-repr/Lib/_pyio.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/_pyio.py (original) +++ python/branches/py3k-short-float-repr/Lib/_pyio.py Thu Apr 16 14:57:18 2009 @@ -1438,7 +1438,7 @@ def close(self): try: self.flush() - except: + except IOError: pass # If flush() fails, just give up self.buffer.close() Modified: python/branches/py3k-short-float-repr/Lib/distutils/cmd.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/cmd.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/cmd.py Thu Apr 16 14:57:18 2009 @@ -93,9 +93,8 @@ # always calls 'finalize_options()', to respect/update it. self.finalized = 0 - # XXX A more explicit way to customize dry_run would be better. - def __getattr__ (self, attr): + def __getattr__(self, attr): if attr == 'dry_run': myval = getattr(self, "_" + attr) if myval is None: @@ -105,7 +104,7 @@ else: raise AttributeError(attr) - def ensure_finalized (self): + def ensure_finalized(self): if not self.finalized: self.finalize_options() self.finalized = 1 @@ -175,7 +174,6 @@ This method must be implemented by all command classes. """ - raise RuntimeError("abstract method -- subclass %s must override" % self.__class__) @@ -351,7 +349,7 @@ preserve_times, not self.force, link, dry_run=self.dry_run) - def copy_tree (self, infile, outfile, preserve_mode=1, preserve_times=1, + def copy_tree(self, infile, outfile, preserve_mode=1, preserve_times=1, preserve_symlinks=0, level=1): """Copy an entire directory tree respecting verbose, dry-run, and force flags. @@ -373,7 +371,6 @@ return archive_util.make_archive(base_name, format, root_dir, base_dir, dry_run=self.dry_run) - def make_file(self, infiles, outfile, func, args, exec_msg=None, skip_msg=None, level=1): """Special case of 'execute()' for operations that process one or @@ -406,7 +403,6 @@ else: log.debug(skip_msg) - # XXX 'install_misc' class not currently used -- it was the base class for # both 'install_scripts' and 'install_data', but they outgrew it. It might # still be useful for 'install_headers', though, so I'm keeping it around @@ -423,10 +419,10 @@ self.install_dir = None self.outfiles = [] - def _install_dir_from (self, dirname): + def _install_dir_from(self, dirname): self.set_undefined_options('install', (dirname, 'install_dir')) - def _copy_files (self, filelist): + def _copy_files(self, filelist): self.outfiles = [] if not filelist: return @@ -435,5 +431,5 @@ self.copy_file(f, self.install_dir) self.outfiles.append(os.path.join(self.install_dir, f)) - def get_outputs (self): + def get_outputs(self): return self.outfiles Modified: python/branches/py3k-short-float-repr/Lib/distutils/tests/test_cmd.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/distutils/tests/test_cmd.py (original) +++ python/branches/py3k-short-float-repr/Lib/distutils/tests/test_cmd.py Thu Apr 16 14:57:18 2009 @@ -1,5 +1,6 @@ """Tests for distutils.cmd.""" import unittest +import os from distutils.cmd import Command from distutils.dist import Distribution @@ -62,6 +63,45 @@ ' option2 = 1'] self.assertEquals(msgs, wanted) + def test_ensure_string(self): + cmd = self.cmd + cmd.option1 = 'ok' + cmd.ensure_string('option1') + + cmd.option2 = None + cmd.ensure_string('option2', 'xxx') + self.assert_(hasattr(cmd, 'option2')) + + cmd.option3 = 1 + self.assertRaises(DistutilsOptionError, cmd.ensure_string, 'option3') + + def test_ensure_string_list(self): + cmd = self.cmd + cmd.option1 = 'ok,dok' + cmd.ensure_string_list('option1') + self.assertEquals(cmd.option1, ['ok', 'dok']) + + cmd.option2 = ['xxx', 'www'] + cmd.ensure_string_list('option2') + + cmd.option3 = ['ok', 2] + self.assertRaises(DistutilsOptionError, cmd.ensure_string_list, + 'option3') + + def test_ensure_filename(self): + cmd = self.cmd + cmd.option1 = __file__ + cmd.ensure_filename('option1') + cmd.option2 = 'xxx' + self.assertRaises(DistutilsOptionError, cmd.ensure_filename, 'option2') + + def test_ensure_dirname(self): + cmd = self.cmd + cmd.option1 = os.path.dirname(__file__) + cmd.ensure_dirname('option1') + cmd.option2 = 'xxx' + self.assertRaises(DistutilsOptionError, cmd.ensure_dirname, 'option2') + def test_suite(): return unittest.makeSuite(CommandTestCase) Modified: python/branches/py3k-short-float-repr/Lib/test/pickletester.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/pickletester.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/pickletester.py Thu Apr 16 14:57:18 2009 @@ -1,3 +1,4 @@ +import io import unittest import pickle import pickletools @@ -842,7 +843,7 @@ self.assertEqual(x.bar, y.bar) def test_reduce_overrides_default_reduce_ex(self): - for proto in 0, 1, 2: + for proto in protocols: x = REX_one() self.assertEqual(x._reduce_called, 0) s = self.dumps(x, proto) @@ -851,7 +852,7 @@ self.assertEqual(y._reduce_called, 0) def test_reduce_ex_called(self): - for proto in 0, 1, 2: + for proto in protocols: x = REX_two() self.assertEqual(x._proto, None) s = self.dumps(x, proto) @@ -860,7 +861,7 @@ self.assertEqual(y._proto, None) def test_reduce_ex_overrides_reduce(self): - for proto in 0, 1, 2: + for proto in protocols: x = REX_three() self.assertEqual(x._proto, None) s = self.dumps(x, proto) @@ -869,7 +870,7 @@ self.assertEqual(y._proto, None) def test_reduce_ex_calls_base(self): - for proto in 0, 1, 2: + for proto in protocols: x = REX_four() self.assertEqual(x._proto, None) s = self.dumps(x, proto) @@ -878,7 +879,7 @@ self.assertEqual(y._proto, proto) def test_reduce_calls_base(self): - for proto in 0, 1, 2: + for proto in protocols: x = REX_five() self.assertEqual(x._reduce_called, 0) s = self.dumps(x, proto) @@ -917,6 +918,20 @@ except (pickle.PickleError): pass + def test_many_puts_and_gets(self): + # Test that internal data structures correctly deal with lots of + # puts/gets. + keys = ("aaa" + str(i) for i in range(100)) + large_dict = dict((k, [4, 5, 6]) for k in keys) + obj = [dict(large_dict), dict(large_dict), dict(large_dict)] + + for proto in protocols: + dumped = self.dumps(obj, proto) + loaded = self.loads(dumped) + self.assertEqual(loaded, obj, + "Failed protocol %d: %r != %r" + % (proto, obj, loaded)) + # Test classes for reduce_ex class REX_one(object): @@ -1002,6 +1017,7 @@ def __getattr__(self, key): self.foo + class AbstractPickleModuleTests(unittest.TestCase): def test_dump_closed_file(self): @@ -1022,13 +1038,20 @@ finally: os.remove(TESTFN) + def test_load_from_and_dump_to_file(self): + stream = io.BytesIO() + data = [123, {}, 124] + pickle.dump(data, stream) + stream.seek(0) + unpickled = pickle.load(stream) + self.assertEqual(unpickled, data) + def test_highest_protocol(self): # Of course this needs to be changed when HIGHEST_PROTOCOL changes. self.assertEqual(pickle.HIGHEST_PROTOCOL, 3) def test_callapi(self): - from io import BytesIO - f = BytesIO() + f = io.BytesIO() # With and without keyword arguments pickle.dump(123, f, -1) pickle.dump(123, file=f, protocol=-1) @@ -1039,7 +1062,6 @@ def test_bad_init(self): # Test issue3664 (pickle can segfault from a badly initialized Pickler). - from io import BytesIO # Override initialization without calling __init__() of the superclass. class BadPickler(pickle.Pickler): def __init__(self): pass @@ -1091,6 +1113,121 @@ self.assertEqual(self.id_count, 5) self.assertEqual(self.load_count, 5) + +class AbstractPicklerUnpicklerObjectTests(unittest.TestCase): + + pickler_class = None + unpickler_class = None + + def setUp(self): + assert self.pickler_class + assert self.unpickler_class + + def test_clear_pickler_memo(self): + # To test whether clear_memo() has any effect, we pickle an object, + # then pickle it again without clearing the memo; the two serialized + # forms should be different. If we clear_memo() and then pickle the + # object again, the third serialized form should be identical to the + # first one we obtained. + data = ["abcdefg", "abcdefg", 44] + f = io.BytesIO() + pickler = self.pickler_class(f) + + pickler.dump(data) + first_pickled = f.getvalue() + + # Reset StringIO object. + f.seek(0) + f.truncate() + + pickler.dump(data) + second_pickled = f.getvalue() + + # Reset the Pickler and StringIO objects. + pickler.clear_memo() + f.seek(0) + f.truncate() + + pickler.dump(data) + third_pickled = f.getvalue() + + self.assertNotEqual(first_pickled, second_pickled) + self.assertEqual(first_pickled, third_pickled) + + def test_priming_pickler_memo(self): + # Verify that we can set the Pickler's memo attribute. + data = ["abcdefg", "abcdefg", 44] + f = io.BytesIO() + pickler = self.pickler_class(f) + + pickler.dump(data) + first_pickled = f.getvalue() + + f = io.BytesIO() + primed = self.pickler_class(f) + primed.memo = pickler.memo + + primed.dump(data) + primed_pickled = f.getvalue() + + self.assertNotEqual(first_pickled, primed_pickled) + + def test_priming_unpickler_memo(self): + # Verify that we can set the Unpickler's memo attribute. + data = ["abcdefg", "abcdefg", 44] + f = io.BytesIO() + pickler = self.pickler_class(f) + + pickler.dump(data) + first_pickled = f.getvalue() + + f = io.BytesIO() + primed = self.pickler_class(f) + primed.memo = pickler.memo + + primed.dump(data) + primed_pickled = f.getvalue() + + unpickler = self.unpickler_class(io.BytesIO(first_pickled)) + unpickled_data1 = unpickler.load() + + self.assertEqual(unpickled_data1, data) + + primed = self.unpickler_class(io.BytesIO(primed_pickled)) + primed.memo = unpickler.memo + unpickled_data2 = primed.load() + + primed.memo.clear() + + self.assertEqual(unpickled_data2, data) + self.assertTrue(unpickled_data2 is unpickled_data1) + + def test_reusing_unpickler_objects(self): + data1 = ["abcdefg", "abcdefg", 44] + f = io.BytesIO() + pickler = self.pickler_class(f) + pickler.dump(data1) + pickled1 = f.getvalue() + + data2 = ["abcdefg", 44, 44] + f = io.BytesIO() + pickler = self.pickler_class(f) + pickler.dump(data2) + pickled2 = f.getvalue() + + f = io.BytesIO() + f.write(pickled1) + f.seek(0) + unpickler = self.unpickler_class(f) + self.assertEqual(unpickler.load(), data1) + + f.seek(0) + f.truncate() + f.write(pickled2) + f.seek(0) + self.assertEqual(unpickler.load(), data2) + + if __name__ == "__main__": # Print some stuff that can be used to rewrite DATA{0,1,2} from pickletools import dis Modified: python/branches/py3k-short-float-repr/Lib/test/test_float.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_float.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_float.py Thu Apr 16 14:57:18 2009 @@ -87,11 +87,18 @@ def __float__(self): return 42 + # Issue 5759: __float__ not called on str subclasses (though it is on + # unicode subclasses). + class FooStr(str): + def __float__(self): + return float(str(self)) + 1 + self.assertAlmostEqual(float(Foo0()), 42.) self.assertAlmostEqual(float(Foo1()), 42.) self.assertAlmostEqual(float(Foo2()), 42.) self.assertAlmostEqual(float(Foo3(21)), 42.) self.assertRaises(TypeError, float, Foo4(42)) + self.assertAlmostEqual(float(FooStr('8')), 9.) def test_floatasratio(self): for f, ratio in [ Modified: python/branches/py3k-short-float-repr/Lib/test/test_pickle.py ============================================================================== --- python/branches/py3k-short-float-repr/Lib/test/test_pickle.py (original) +++ python/branches/py3k-short-float-repr/Lib/test/test_pickle.py Thu Apr 16 14:57:18 2009 @@ -6,6 +6,7 @@ from test.pickletester import AbstractPickleTests from test.pickletester import AbstractPickleModuleTests from test.pickletester import AbstractPersistentPicklerTests +from test.pickletester import AbstractPicklerUnpicklerObjectTests try: import _pickle @@ -60,6 +61,12 @@ return u.load() +class PyPicklerUnpicklerObjectTests(AbstractPicklerUnpicklerObjectTests): + + pickler_class = pickle._Pickler + unpickler_class = pickle._Unpickler + + if has_c_implementation: class CPicklerTests(PyPicklerTests): pickler = _pickle.Pickler @@ -69,11 +76,26 @@ pickler = _pickle.Pickler unpickler = _pickle.Unpickler + class CDumpPickle_LoadPickle(PyPicklerTests): + pickler = _pickle.Pickler + unpickler = pickle._Unpickler + + class DumpPickle_CLoadPickle(PyPicklerTests): + pickler = pickle._Pickler + unpickler = _pickle.Unpickler + + class CPicklerUnpicklerObjectTests(AbstractPicklerUnpicklerObjectTests): + pickler_class = _pickle.Pickler + unpickler_class = _pickle.Unpickler + def test_main(): tests = [PickleTests, PyPicklerTests, PyPersPicklerTests] if has_c_implementation: - tests.extend([CPicklerTests, CPersPicklerTests]) + tests.extend([CPicklerTests, CPersPicklerTests, + CDumpPickle_LoadPickle, DumpPickle_CLoadPickle, + PyPicklerUnpicklerObjectTests, + CPicklerUnpicklerObjectTests]) support.run_unittest(*tests) support.run_doctest(pickle) Modified: python/branches/py3k-short-float-repr/Misc/NEWS ============================================================================== --- python/branches/py3k-short-float-repr/Misc/NEWS (original) +++ python/branches/py3k-short-float-repr/Misc/NEWS Thu Apr 16 14:57:18 2009 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #5759: float() didn't call __float__ on str subclasses. + - The string.maketrans() function is deprecated; there is a new static method maketrans() on the bytes and bytearray classes. This removes confusion about the types string.maketrans() is supposed to work with, and mirrors the @@ -26,6 +28,12 @@ Library ------- +- Issue #1161031: fix readwrite select flag handling: POLLPRI now + results in a handle_expt_event call, not handle_read_event, and POLLERR + and POLLNVAL now call handle_close, not handle_expt_event. Also, + dispatcher now has an 'ignore_log_types' attribute for suppressing + log messages, which is set to 'warning' by default. + - Issue #2703: SimpleXMLRPCDispatcher.__init__: Provide default values for new arguments introduced in 2.5. Modified: python/branches/py3k-short-float-repr/Objects/floatobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/floatobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/floatobject.c Thu Apr 16 14:57:18 2009 @@ -1452,7 +1452,9 @@ return float_subtype_new(type, args, kwds); /* Wimp out */ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x)) return NULL; - if (PyUnicode_Check(x)) + /* If it's a string, but not a string subclass, use + PyFloat_FromString. */ + if (PyUnicode_CheckExact(x)) return PyFloat_FromString(x); return PyNumber_Float(x); } From python-checkins at python.org Thu Apr 16 16:50:31 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 16 Apr 2009 16:50:31 +0200 (CEST) Subject: [Python-checkins] r71649 - in python/branches/py3k-short-float-repr: configure configure.in Message-ID: <20090416145031.499F31E401B@bag.python.org> Author: mark.dickinson Date: Thu Apr 16 16:50:29 2009 New Revision: 71649 Log: Use 'test' instead of [[: FreeBSD complains about the [[ Modified: python/branches/py3k-short-float-repr/configure python/branches/py3k-short-float-repr/configure.in Modified: python/branches/py3k-short-float-repr/configure ============================================================================== --- python/branches/py3k-short-float-repr/configure (original) +++ python/branches/py3k-short-float-repr/configure Thu Apr 16 16:50:29 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 71616 . +# From configure.in Revision: 71618 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.1. # @@ -21846,11 +21846,11 @@ # (e.g., this is true by default on OS X/x86) { echo "$as_me:$LINENO: checking whether SSE2 instructions are already enabled for math" >&5 echo $ECHO_N "checking whether SSE2 instructions are already enabled for math... $ECHO_C" >&6; } - if [ "`$CC -dM -E - &5 echo "${ECHO_T}$ac_sse2_enabled" >&6; } Modified: python/branches/py3k-short-float-repr/configure.in ============================================================================== --- python/branches/py3k-short-float-repr/configure.in (original) +++ python/branches/py3k-short-float-repr/configure.in Thu Apr 16 16:50:29 2009 @@ -3160,11 +3160,11 @@ # determine whether we're already using the SSE2 instruction set for math # (e.g., this is true by default on OS X/x86) AC_MSG_CHECKING(whether SSE2 instructions are already enabled for math) - if [[ "`$CC -dM -E - Author: mark.dickinson Date: Thu Apr 16 17:01:01 2009 New Revision: 71650 Log: Silence compiler warning Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/pystrtod.c (original) +++ python/branches/py3k-short-float-repr/Python/pystrtod.c Thu Apr 16 17:01:01 2009 @@ -648,7 +648,7 @@ int use_alt_formatting, char **float_strings, int *type) { char *buf = NULL; - char *p; + char *p = NULL; Py_ssize_t bufsize = 0; char *digits, *digits_end; int decpt_as_int, sign, exp_len, exp = 0, use_exp = 0; From g.brandl at gmx.net Thu Apr 16 20:04:48 2009 From: g.brandl at gmx.net (Georg Brandl) Date: Thu, 16 Apr 2009 20:04:48 +0200 Subject: [Python-checkins] r71634 - in python/branches/release30-maint:Doc/library/subprocess.rst In-Reply-To: <79EF64D956014374AF51E55F66A2CB43@RaymondLaptop1> References: <20090415223832.966E81E401B@bag.python.org> <79EF64D956014374AF51E55F66A2CB43@RaymondLaptop1> Message-ID: Raymond Hettinger schrieb: > [R. David Murray] >> I'll change it to a note if you still think a warning is excessive. >> I agree that it could well be. > > Thanks, I would appreciate it if you took out the "..warning directive". > > Unfortunately, the warnings are rendered in big pink boxes that > visually dominate everything surrounding them, essentially making > the warning more important than the regular docs beside them. > > When looking at docs for other languages and tools, we don't see > them filled with this sort of thing. Too many warnings in the docs > makes the language look fragile. While I agree that too many red boxes make the documentation hard and uncomfortable to read, I feel like the direction to go is probably to not make the boxes red. (This is also why I had originally changed "Warning" into "Caveat" which I feel does not as strong.) There is also the possibility of using one of the other admonitions, like "caution", instead of "warning". > P.S. While you're making the edit, it would be nice to change > the phrasing to not use "you". Unfortunately, the docs already > have a lot of "when you do this" and "you should do that", but > but we shouldn't make it worse. > > Fred Drake used to monitor the docs for style, tone, grammar > and whatnot but now we don't have the services of an editor. I still try to monitor every docs change, but while I can judge the factual and orthographical correctness of each change my sense of writing style is somewhat limited by the language barrier -- I'm sorry for that. Georg From python-checkins at python.org Thu Apr 16 20:12:54 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 16 Apr 2009 20:12:54 +0200 (CEST) Subject: [Python-checkins] r71651 - python/trunk/Doc/library/subprocess.rst Message-ID: <20090416181254.23A221E4276@bag.python.org> Author: r.david.murray Date: Thu Apr 16 20:12:53 2009 New Revision: 71651 Log: Less red ink (warning->note) and add link to def of side-by-side assembly. Modified: python/trunk/Doc/library/subprocess.rst Modified: python/trunk/Doc/library/subprocess.rst ============================================================================== --- python/trunk/Doc/library/subprocess.rst (original) +++ python/trunk/Doc/library/subprocess.rst Thu Apr 16 20:12:53 2009 @@ -102,13 +102,15 @@ variables for the new process; these are used instead of inheriting the current process' environment, which is the default behavior. - .. warning:: + .. note:: - When replacing the environment you must provide any variables - required for the program to execute. On Windows, in order to run - a side-by-side assembly the specified *env* must include a valid + If specified, *env* must provide any variables required + for the program to execute. On Windows, in order to run a + `side-by-side assembly`_ the specified *env* **must** include a valid :envvar:`SystemRoot`. + .. _side-by-side assembly: http://en.wikipedia.org/wiki/Side-by-Side_Assembly + If *universal_newlines* is :const:`True`, the file objects stdout and stderr are opened as text files, but lines may be terminated by any of ``'\n'``, the Unix end-of-line convention, ``'\r'``, the old Macintosh convention or ``'\r\n'``, the From python-checkins at python.org Thu Apr 16 20:15:34 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 16 Apr 2009 20:15:34 +0200 (CEST) Subject: [Python-checkins] r71652 - in python/branches/py3k: Doc/library/subprocess.rst Message-ID: <20090416181534.703691E401B@bag.python.org> Author: r.david.murray Date: Thu Apr 16 20:15:32 2009 New Revision: 71652 Log: Merged revisions 71651 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71651 | r.david.murray | 2009-04-16 14:12:53 -0400 (Thu, 16 Apr 2009) | 2 lines Less red ink (warning->note) and add link to def of side-by-side assembly. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/subprocess.rst Modified: python/branches/py3k/Doc/library/subprocess.rst ============================================================================== --- python/branches/py3k/Doc/library/subprocess.rst (original) +++ python/branches/py3k/Doc/library/subprocess.rst Thu Apr 16 20:15:32 2009 @@ -97,13 +97,15 @@ variables for the new process; these are used instead of inheriting the current process' environment, which is the default behavior. - .. warning:: + .. note:: - When replacing the environment you must provide any variables - required for the program to execute. On Windows, in order to run - a side-by-side assembly the specified *env* must include a valid + If specified, *env* must provide any variables required + for the program to execute. On Windows, in order to run a + `side-by-side assembly`_ the specified *env* **must** include a valid :envvar:`SystemRoot`. + .. _side-by-side assembly: http://en.wikipedia.org/wiki/Side-by-Side_Assembly + If *universal_newlines* is :const:`True`, the file objects stdout and stderr are opened as text files, but lines may be terminated by any of ``'\n'``, the Unix end-of-line convention, ``'\r'``, the old Macintosh convention or ``'\r\n'``, the From python-checkins at python.org Thu Apr 16 20:16:10 2009 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 16 Apr 2009 20:16:10 +0200 (CEST) Subject: [Python-checkins] r71653 - python/trunk/Doc/library/functions.rst Message-ID: <20090416181610.BC65D1E401B@bag.python.org> Author: raymond.hettinger Date: Thu Apr 16 20:16:10 2009 New Revision: 71653 Log: Clarify the behavior of any() and all() with an empty iterable. Modified: python/trunk/Doc/library/functions.rst Modified: python/trunk/Doc/library/functions.rst ============================================================================== --- python/trunk/Doc/library/functions.rst (original) +++ python/trunk/Doc/library/functions.rst Thu Apr 16 20:16:10 2009 @@ -17,7 +17,8 @@ .. function:: all(iterable) - Return True if all elements of the *iterable* are true. Equivalent to:: + Return True if all elements of the *iterable* are true (or if the iterable + is empty). Equivalent to:: def all(iterable): for element in iterable: @@ -30,7 +31,8 @@ .. function:: any(iterable) - Return True if any element of the *iterable* is true. Equivalent to:: + Return True if any element of the *iterable* is true. If the iterable + is empty, return False. Equivalent to:: def any(iterable): for element in iterable: From python-checkins at python.org Thu Apr 16 20:17:08 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 16 Apr 2009 20:17:08 +0200 (CEST) Subject: [Python-checkins] r71654 - in python/branches/release30-maint: Doc/library/subprocess.rst Message-ID: <20090416181708.DF82F1E4044@bag.python.org> Author: r.david.murray Date: Thu Apr 16 20:17:08 2009 New Revision: 71654 Log: Merged revisions 71652 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71652 | r.david.murray | 2009-04-16 14:15:32 -0400 (Thu, 16 Apr 2009) | 9 lines Merged revisions 71651 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71651 | r.david.murray | 2009-04-16 14:12:53 -0400 (Thu, 16 Apr 2009) | 2 lines Less red ink (warning->note) and add link to def of side-by-side assembly. ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Doc/library/subprocess.rst Modified: python/branches/release30-maint/Doc/library/subprocess.rst ============================================================================== --- python/branches/release30-maint/Doc/library/subprocess.rst (original) +++ python/branches/release30-maint/Doc/library/subprocess.rst Thu Apr 16 20:17:08 2009 @@ -97,13 +97,15 @@ variables for the new process; these are used instead of inheriting the current process' environment, which is the default behavior. - .. warning:: + .. note:: - When replacing the environment you must provide any variables - required for the program to execute. On Windows, in order to run - a side-by-side assembly the specified *env* must include a valid + If specified, *env* must provide any variables required + for the program to execute. On Windows, in order to run a + `side-by-side assembly`_ the specified *env* **must** include a valid :envvar:`SystemRoot`. + .. _side-by-side assembly: http://en.wikipedia.org/wiki/Side-by-Side_Assembly + If *universal_newlines* is :const:`True`, the file objects stdout and stderr are opened as text files, but lines may be terminated by any of ``'\n'``, the Unix end-of-line convention, ``'\r'``, the old Macintosh convention or ``'\r\n'``, the From python-checkins at python.org Thu Apr 16 20:17:55 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 16 Apr 2009 20:17:55 +0200 (CEST) Subject: [Python-checkins] r71655 - in python/branches/release26-maint: Doc/library/subprocess.rst Message-ID: <20090416181755.64A4B1E401B@bag.python.org> Author: r.david.murray Date: Thu Apr 16 20:17:55 2009 New Revision: 71655 Log: Merged revisions 71651 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71651 | r.david.murray | 2009-04-16 14:12:53 -0400 (Thu, 16 Apr 2009) | 2 lines Less red ink (warning->note) and add link to def of side-by-side assembly. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/subprocess.rst Modified: python/branches/release26-maint/Doc/library/subprocess.rst ============================================================================== --- python/branches/release26-maint/Doc/library/subprocess.rst (original) +++ python/branches/release26-maint/Doc/library/subprocess.rst Thu Apr 16 20:17:55 2009 @@ -102,13 +102,15 @@ variables for the new process; these are used instead of inheriting the current process' environment, which is the default behavior. - .. warning:: + .. note:: - When replacing the environment you must provide any variables - required for the program to execute. On Windows, in order to run - a side-by-side assembly the specified *env* must include a valid + If specified, *env* must provide any variables required + for the program to execute. On Windows, in order to run a + `side-by-side assembly`_ the specified *env* **must** include a valid :envvar:`SystemRoot`. + .. _side-by-side assembly: http://en.wikipedia.org/wiki/Side-by-Side_Assembly + If *universal_newlines* is :const:`True`, the file objects stdout and stderr are opened as text files, but lines may be terminated by any of ``'\n'``, the Unix end-of-line convention, ``'\r'``, the old Macintosh convention or ``'\r\n'``, the From python-checkins at python.org Thu Apr 16 20:37:24 2009 From: python-checkins at python.org (thomas.heller) Date: Thu, 16 Apr 2009 20:37:24 +0200 (CEST) Subject: [Python-checkins] r71656 - in python/branches/py3k: Modules/_ctypes/_ctypes.c Modules/_ctypes/callbacks.c Modules/_ctypes/ctypes.h Modules/_ctypes/malloc_closure.c Message-ID: <20090416183724.9F3941E401B@bag.python.org> Author: thomas.heller Date: Thu Apr 16 20:37:24 2009 New Revision: 71656 Log: Merged revisions 71640-71641 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71640 | thomas.heller | 2009-04-16 08:26:33 +0200 (Do, 16 Apr 2009) | 1 line Remove unneeded code. ........ r71641 | thomas.heller | 2009-04-16 08:42:02 +0200 (Do, 16 Apr 2009) | 2 lines Remove duplicated function declaration. Make _pagesize static. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Modules/_ctypes/_ctypes.c python/branches/py3k/Modules/_ctypes/callbacks.c python/branches/py3k/Modules/_ctypes/ctypes.h python/branches/py3k/Modules/_ctypes/malloc_closure.c Modified: python/branches/py3k/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k/Modules/_ctypes/_ctypes.c Thu Apr 16 20:37:24 2009 @@ -5411,11 +5411,6 @@ Py_INCREF(PyExc_ArgError); PyModule_AddObject(m, "ArgumentError", PyExc_ArgError); } - /************************************************* - * - * Others... - */ - init_callbacks_in_module(m); return m; } Modified: python/branches/py3k/Modules/_ctypes/callbacks.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/callbacks.c (original) +++ python/branches/py3k/Modules/_ctypes/callbacks.c Thu Apr 16 20:37:24 2009 @@ -463,17 +463,6 @@ return NULL; } -/**************************************************************************** - * - * callback objects: initialization - */ - -void init_callbacks_in_module(PyObject *m) -{ - if (PyType_Ready((PyTypeObject *)&PyType_Type) < 0) - return; -} - #ifdef MS_WIN32 static void LoadPython(void) Modified: python/branches/py3k/Modules/_ctypes/ctypes.h ============================================================================== --- python/branches/py3k/Modules/_ctypes/ctypes.h (original) +++ python/branches/py3k/Modules/_ctypes/ctypes.h Thu Apr 16 20:37:24 2009 @@ -148,8 +148,6 @@ extern PyObject * CreateArrayType(PyObject *itemtype, Py_ssize_t length); -extern void init_callbacks_in_module(PyObject *m); - extern PyMethodDef module_methods[]; extern CThunkObject *AllocFunctionCallback(PyObject *callable, @@ -312,7 +310,6 @@ }; extern PyTypeObject PyCArg_Type; -extern PyCArgObject *new_CArgObject(void); #define PyCArg_CheckExact(v) ((v)->ob_type == &PyCArg_Type) extern PyCArgObject *new_CArgObject(void); Modified: python/branches/py3k/Modules/_ctypes/malloc_closure.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/malloc_closure.c (original) +++ python/branches/py3k/Modules/_ctypes/malloc_closure.c Thu Apr 16 20:37:24 2009 @@ -28,7 +28,7 @@ } ITEM; static ITEM *free_list; -int _pagesize; +static int _pagesize; static void more_core(void) { From python-checkins at python.org Thu Apr 16 21:07:37 2009 From: python-checkins at python.org (vinay.sajip) Date: Thu, 16 Apr 2009 21:07:37 +0200 (CEST) Subject: [Python-checkins] r71657 - in python/trunk/Lib: logging/__init__.py test/test_logging.py Message-ID: <20090416190737.833D41E4017@bag.python.org> Author: vinay.sajip Date: Thu Apr 16 21:07:37 2009 New Revision: 71657 Log: Issue #5768: Change to Unicode output logic and test case for same. Modified: python/trunk/Lib/logging/__init__.py python/trunk/Lib/test/test_logging.py Modified: python/trunk/Lib/logging/__init__.py ============================================================================== --- python/trunk/Lib/logging/__init__.py (original) +++ python/trunk/Lib/logging/__init__.py Thu Apr 16 21:07:37 2009 @@ -753,7 +753,7 @@ The record is then written to the stream with a trailing newline. If exception information is present, it is formatted using traceback.print_exception and appended to the stream. If the stream - has an 'encoding' attribute, it is used to encode the message before + has an 'encoding' attribute, it is used to determine how to do the output to the stream. """ try: @@ -764,11 +764,11 @@ stream.write(fs % msg) else: try: - if (isinstance(msg, unicode) or - getattr(stream, 'encoding', None) is None): - stream.write(fs % msg) + if (isinstance(msg, unicode) and + getattr(stream, 'encoding', None)): + stream.write(fs.decode(stream.encoding) % msg) else: - stream.write(fs % msg.encode(stream.encoding)) + stream.write(fs % msg) except UnicodeError: stream.write(fs % msg.encode("UTF-8")) self.flush() Modified: python/trunk/Lib/test/test_logging.py ============================================================================== --- python/trunk/Lib/test/test_logging.py (original) +++ python/trunk/Lib/test/test_logging.py Thu Apr 16 21:07:37 2009 @@ -894,6 +894,7 @@ message = u'\u0434\u043e \u0441\u0432\u0438\u0434\u0430\u043d\u0438\u044f' #Ensure it's written in a Cyrillic encoding writer_class = codecs.getwriter('cp1251') + writer_class.encoding = 'cp1251' stream = cStringIO.StringIO() writer = writer_class(stream, 'strict') handler = logging.StreamHandler(writer) From python-checkins at python.org Thu Apr 16 21:11:35 2009 From: python-checkins at python.org (vinay.sajip) Date: Thu, 16 Apr 2009 21:11:35 +0200 (CEST) Subject: [Python-checkins] r71658 - in python/branches/release26-maint/Lib: logging/__init__.py test/test_logging.py Message-ID: <20090416191135.F27B61E41EC@bag.python.org> Author: vinay.sajip Date: Thu Apr 16 21:11:35 2009 New Revision: 71658 Log: Issue #5768: Change to Unicode output logic and test case for same. Modified: python/branches/release26-maint/Lib/logging/__init__.py python/branches/release26-maint/Lib/test/test_logging.py Modified: python/branches/release26-maint/Lib/logging/__init__.py ============================================================================== --- python/branches/release26-maint/Lib/logging/__init__.py (original) +++ python/branches/release26-maint/Lib/logging/__init__.py Thu Apr 16 21:11:35 2009 @@ -764,11 +764,11 @@ stream.write(fs % msg) else: try: - if (isinstance(msg, unicode) or - getattr(stream, 'encoding', None) is None): - stream.write(fs % msg) + if (isinstance(msg, unicode) and + getattr(stream, 'encoding', None)): + stream.write(fs.decode(stream.encoding) % msg) else: - stream.write(fs % msg.encode(stream.encoding)) + stream.write(fs % msg) except UnicodeError: stream.write(fs % msg.encode("UTF-8")) self.flush() Modified: python/branches/release26-maint/Lib/test/test_logging.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_logging.py (original) +++ python/branches/release26-maint/Lib/test/test_logging.py Thu Apr 16 21:11:35 2009 @@ -893,6 +893,7 @@ message = u'\u0434\u043e \u0441\u0432\u0438\u0434\u0430\u043d\u0438\u044f' #Ensure it's written in a Cyrillic encoding writer_class = codecs.getwriter('cp1251') + writer_class.encoding = 'cp1251' stream = cStringIO.StringIO() writer = writer_class(stream, 'strict') handler = logging.StreamHandler(writer) From python-checkins at python.org Thu Apr 16 21:12:35 2009 From: python-checkins at python.org (thomas.heller) Date: Thu, 16 Apr 2009 21:12:35 +0200 (CEST) Subject: [Python-checkins] r71659 - in python/branches/release30-maint: Modules/_ctypes/_ctypes.c Modules/_ctypes/callbacks.c Modules/_ctypes/ctypes.h Modules/_ctypes/malloc_closure.c Message-ID: <20090416191235.840E61E4017@bag.python.org> Author: thomas.heller Date: Thu Apr 16 21:12:35 2009 New Revision: 71659 Log: Merged revisions 71656 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71656 | thomas.heller | 2009-04-16 20:37:24 +0200 (Do, 16 Apr 2009) | 14 lines Merged revisions 71640-71641 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71640 | thomas.heller | 2009-04-16 08:26:33 +0200 (Do, 16 Apr 2009) | 1 line Remove unneeded code. ........ r71641 | thomas.heller | 2009-04-16 08:42:02 +0200 (Do, 16 Apr 2009) | 2 lines Remove duplicated function declaration. Make _pagesize static. ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Modules/_ctypes/_ctypes.c python/branches/release30-maint/Modules/_ctypes/callbacks.c python/branches/release30-maint/Modules/_ctypes/ctypes.h python/branches/release30-maint/Modules/_ctypes/malloc_closure.c Modified: python/branches/release30-maint/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/release30-maint/Modules/_ctypes/_ctypes.c (original) +++ python/branches/release30-maint/Modules/_ctypes/_ctypes.c Thu Apr 16 21:12:35 2009 @@ -5411,11 +5411,6 @@ Py_INCREF(PyExc_ArgError); PyModule_AddObject(m, "ArgumentError", PyExc_ArgError); } - /************************************************* - * - * Others... - */ - init_callbacks_in_module(m); return m; } Modified: python/branches/release30-maint/Modules/_ctypes/callbacks.c ============================================================================== --- python/branches/release30-maint/Modules/_ctypes/callbacks.c (original) +++ python/branches/release30-maint/Modules/_ctypes/callbacks.c Thu Apr 16 21:12:35 2009 @@ -463,17 +463,6 @@ return NULL; } -/**************************************************************************** - * - * callback objects: initialization - */ - -void init_callbacks_in_module(PyObject *m) -{ - if (PyType_Ready((PyTypeObject *)&PyType_Type) < 0) - return; -} - #ifdef MS_WIN32 static void LoadPython(void) Modified: python/branches/release30-maint/Modules/_ctypes/ctypes.h ============================================================================== --- python/branches/release30-maint/Modules/_ctypes/ctypes.h (original) +++ python/branches/release30-maint/Modules/_ctypes/ctypes.h Thu Apr 16 21:12:35 2009 @@ -148,8 +148,6 @@ extern PyObject * CreateArrayType(PyObject *itemtype, Py_ssize_t length); -extern void init_callbacks_in_module(PyObject *m); - extern PyMethodDef module_methods[]; extern CThunkObject *AllocFunctionCallback(PyObject *callable, @@ -312,7 +310,6 @@ }; extern PyTypeObject PyCArg_Type; -extern PyCArgObject *new_CArgObject(void); #define PyCArg_CheckExact(v) ((v)->ob_type == &PyCArg_Type) extern PyCArgObject *new_CArgObject(void); Modified: python/branches/release30-maint/Modules/_ctypes/malloc_closure.c ============================================================================== --- python/branches/release30-maint/Modules/_ctypes/malloc_closure.c (original) +++ python/branches/release30-maint/Modules/_ctypes/malloc_closure.c Thu Apr 16 21:12:35 2009 @@ -28,7 +28,7 @@ } ITEM; static ITEM *free_list; -int _pagesize; +static int _pagesize; static void more_core(void) { From python-checkins at python.org Thu Apr 16 21:13:35 2009 From: python-checkins at python.org (thomas.heller) Date: Thu, 16 Apr 2009 21:13:35 +0200 (CEST) Subject: [Python-checkins] r71660 - in python/branches/release26-maint: Modules/_ctypes/_ctypes.c Modules/_ctypes/callbacks.c Modules/_ctypes/ctypes.h Modules/_ctypes/malloc_closure.c Message-ID: <20090416191335.C59FA1E4017@bag.python.org> Author: thomas.heller Date: Thu Apr 16 21:13:35 2009 New Revision: 71660 Log: Merged revisions 71640-71641 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71640 | thomas.heller | 2009-04-16 08:26:33 +0200 (Do, 16 Apr 2009) | 1 line Remove unneeded code. ........ r71641 | thomas.heller | 2009-04-16 08:42:02 +0200 (Do, 16 Apr 2009) | 2 lines Remove duplicated function declaration. Make _pagesize static. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Modules/_ctypes/_ctypes.c python/branches/release26-maint/Modules/_ctypes/callbacks.c python/branches/release26-maint/Modules/_ctypes/ctypes.h python/branches/release26-maint/Modules/_ctypes/malloc_closure.c Modified: python/branches/release26-maint/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/release26-maint/Modules/_ctypes/_ctypes.c (original) +++ python/branches/release26-maint/Modules/_ctypes/_ctypes.c Thu Apr 16 21:13:35 2009 @@ -5606,11 +5606,6 @@ Py_INCREF(PyExc_ArgError); PyModule_AddObject(m, "ArgumentError", PyExc_ArgError); } - /************************************************* - * - * Others... - */ - init_callbacks_in_module(m); } /***************************************************************** Modified: python/branches/release26-maint/Modules/_ctypes/callbacks.c ============================================================================== --- python/branches/release26-maint/Modules/_ctypes/callbacks.c (original) +++ python/branches/release26-maint/Modules/_ctypes/callbacks.c Thu Apr 16 21:13:35 2009 @@ -466,17 +466,6 @@ return NULL; } -/**************************************************************************** - * - * callback objects: initialization - */ - -void init_callbacks_in_module(PyObject *m) -{ - if (PyType_Ready((PyTypeObject *)&PyType_Type) < 0) - return; -} - #ifdef MS_WIN32 static void LoadPython(void) Modified: python/branches/release26-maint/Modules/_ctypes/ctypes.h ============================================================================== --- python/branches/release26-maint/Modules/_ctypes/ctypes.h (original) +++ python/branches/release26-maint/Modules/_ctypes/ctypes.h Thu Apr 16 21:13:35 2009 @@ -189,8 +189,6 @@ extern PyObject * CreateArrayType(PyObject *itemtype, Py_ssize_t length); -extern void init_callbacks_in_module(PyObject *m); - extern PyMethodDef module_methods[]; extern CThunkObject *AllocFunctionCallback(PyObject *callable, @@ -353,7 +351,6 @@ }; extern PyTypeObject PyCArg_Type; -extern PyCArgObject *new_CArgObject(void); #define PyCArg_CheckExact(v) ((v)->ob_type == &PyCArg_Type) extern PyCArgObject *new_CArgObject(void); Modified: python/branches/release26-maint/Modules/_ctypes/malloc_closure.c ============================================================================== --- python/branches/release26-maint/Modules/_ctypes/malloc_closure.c (original) +++ python/branches/release26-maint/Modules/_ctypes/malloc_closure.c Thu Apr 16 21:13:35 2009 @@ -32,7 +32,7 @@ } ITEM; static ITEM *free_list; -int _pagesize; +static int _pagesize; static void more_core(void) { From python-checkins at python.org Thu Apr 16 21:14:09 2009 From: python-checkins at python.org (vinay.sajip) Date: Thu, 16 Apr 2009 21:14:09 +0200 (CEST) Subject: [Python-checkins] r71661 - python/branches/release26-maint/Misc/NEWS Message-ID: <20090416191409.EF7E61E4017@bag.python.org> Author: vinay.sajip Date: Thu Apr 16 21:14:09 2009 New Revision: 71661 Log: Issue #5768: Change to Unicode output logic and test case for same. Modified: python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Thu Apr 16 21:14:09 2009 @@ -17,6 +17,8 @@ Library ------- +- Issue #5768: Fixed bug in Unicode output logic and test case for same. + - Issue #1161031: fix readwrite select flag handling: POLLPRI now results in a handle_expt_event call, not handle_read_event, and POLLERR and POLLNVAL now call handle_close, not handle_expt_event. Also, @@ -126,7 +128,7 @@ - Issue #5741: don't disallow "%%" (which is an escape for "%") when setting a value in SafeConfigParser. -- Issue #5731: Distutils bdist_wininst no longer worked on non-Windows +- Issue #5731: Distutils bdist_wininst no longer worked on non-Windows platforms. Initial patch by Paul Moore. - Issue #1491431: Fixed distutils.filelist.glob_to_re for edge cases. @@ -171,7 +173,7 @@ - Issue #5261: Patch multiprocessing's semaphore.c to support context manager use: "with multiprocessing.Lock()" works now. -- Issue #5177: Multiprocessing's SocketListener class now uses +- Issue #5177: Multiprocessing's SocketListener class now uses socket.SO_REUSEADDR on all connections so that the user no longer needs to wait 120 seconds for the socket to expire. @@ -469,7 +471,7 @@ - Issue #5635: Fix running test_sys with tracing enabled. - regrtest no longer treats ImportError as equivalent to SkipTest. Imports - that should cause a test to be skipped are now done using import_module + that should cause a test to be skipped are now done using import_module from test support, which does the conversion. - Issue #5083: New 'gui' resource for regrtest. From buildbot at python.org Thu Apr 16 21:15:25 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 16 Apr 2009 19:15:25 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.0 Message-ID: <20090416191526.1D4D41E4017@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.0/builds/274 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: make: *** [buildbottest] Aborted sincerely, -The Buildbot From python-checkins at python.org Thu Apr 16 21:15:49 2009 From: python-checkins at python.org (vinay.sajip) Date: Thu, 16 Apr 2009 21:15:49 +0200 (CEST) Subject: [Python-checkins] r71662 - python/trunk/Misc/NEWS Message-ID: <20090416191549.D1EC71E4017@bag.python.org> Author: vinay.sajip Date: Thu Apr 16 21:15:49 2009 New Revision: 71662 Log: Issue #5768: Change to Unicode output logic and test case for same. Modified: python/trunk/Misc/NEWS Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Apr 16 21:15:49 2009 @@ -223,6 +223,8 @@ Library ------- +- Issue #5768: Fixed bug in Unicode output logic and test case for same. + - Issue #1161031: fix readwrite select flag handling: POLLPRI now results in a handle_expt_event call, not handle_read_event, and POLLERR and POLLNVAL now call handle_close, not handle_expt_event. Also, @@ -236,7 +238,7 @@ - Issue #5732: added a new command in Distutils: check. -- Issue #5731: Distutils bdist_wininst no longer worked on non-Windows +- Issue #5731: Distutils bdist_wininst no longer worked on non-Windows platforms. Initial patch by Paul Moore. - Issue #2254: Fix CGIHTTPServer information disclosure. Relative paths are @@ -268,14 +270,14 @@ object when writefile is called causes a ERROR_NO_SYSTEM_RESOURCES. Added docs to note the limitation -- unittest.assertNotEqual() now uses the inequality operator (!=) instead +- unittest.assertNotEqual() now uses the inequality operator (!=) instead of the equality operator. - + - Issue #5663: better failure messages for unittest asserts. Default assertTrue and assertFalse messages are now useful. TestCase has a longMessage attribute. This defaults to False, but if set to True useful error messages are shown in addition to explicit messages passed to assert methods. - + - Issue #3110: Add additional protect around SEM_VALUE_MAX for multiprocessing - In Pdb, prevent the reassignment of __builtin__._ by sys.displayhook on @@ -311,7 +313,7 @@ - Issue #5261: Patch multiprocessing's semaphore.c to support context manager use: "with multiprocessing.Lock()" works now. -- Issue #5177: Multiprocessing's SocketListener class now uses +- Issue #5177: Multiprocessing's SocketListener class now uses socket.SO_REUSEADDR on all connections so that the user no longer needs to wait 120 seconds for the socket to expire. @@ -824,7 +826,7 @@ - Issue #5635: Fix running test_sys with tracing enabled. - regrtest no longer treats ImportError as equivalent to SkipTest. Imports - that should cause a test to be skipped are now done using import_module + that should cause a test to be skipped are now done using import_module from test support, which does the conversion. - Issue #5083: New 'gui' resource for regrtest. From python-checkins at python.org Thu Apr 16 21:52:10 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 16 Apr 2009 21:52:10 +0200 (CEST) Subject: [Python-checkins] r71663 - in python/branches/py3k: Doc/library/sys.rst Doc/license.rst Include/Python.h Include/dtoa.h Include/pymacconfig.h Include/pymath.h Include/pyport.h Lib/test/formatfloat_testcases.txt Makefile.pre.in Misc/ACKS Misc/NEWS PC/pyconfig.h PCbuild/pythoncore.vcproj Python/dtoa.c Python/pymath.c Python/sysmodule.c configure configure.in pyconfig.h.in Message-ID: <20090416195210.AD3A51E401B@bag.python.org> Author: mark.dickinson Date: Thu Apr 16 21:52:09 2009 New Revision: 71663 Log: Issue #1580: use short float repr where possible. - incorporate and adapt David Gay's dtoa and strtod into the Python core - on platforms where we can use Gay's code (almost all!), repr(float) is based on the shortest sequence of decimal digits that rounds correctly. - add sys.float_repr_style attribute to indicate whether we're using Gay's code or not - add autoconf magic to detect and enable SSE2 instructions on x86/gcc - slight change to repr and str: repr switches to exponential notation at 1e16 instead of 1e17, str switches at 1e11 instead of 1e12 Added: python/branches/py3k/Include/dtoa.h python/branches/py3k/Lib/test/formatfloat_testcases.txt python/branches/py3k/Python/dtoa.c Modified: python/branches/py3k/Doc/library/sys.rst python/branches/py3k/Doc/license.rst python/branches/py3k/Include/Python.h python/branches/py3k/Include/pymacconfig.h python/branches/py3k/Include/pymath.h python/branches/py3k/Include/pyport.h python/branches/py3k/Makefile.pre.in python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/NEWS python/branches/py3k/PC/pyconfig.h python/branches/py3k/PCbuild/pythoncore.vcproj python/branches/py3k/Python/pymath.c python/branches/py3k/Python/sysmodule.c python/branches/py3k/configure python/branches/py3k/configure.in python/branches/py3k/pyconfig.h.in Modified: python/branches/py3k/Doc/library/sys.rst ============================================================================== --- python/branches/py3k/Doc/library/sys.rst (original) +++ python/branches/py3k/Doc/library/sys.rst Thu Apr 16 21:52:09 2009 @@ -266,6 +266,19 @@ The information in the table is simplified. +.. data:: float_repr_style + + A string indicating how the :func:`repr` function behaves for + floats. If the string has value ``'short'`` then for a finite + float ``x``, ``repr(x)`` aims to produce a short string with the + property that ``float(repr(x)) == x``. This is the usual behaviour + in Python 3.1 and later. Otherwise, ``float_repr_style`` has value + ``'legacy'`` and ``repr(x)`` behaves in the same way as it did in + versions of Python prior to 3.1. + + .. versionadded:: 3.1 + + .. function:: getcheckinterval() Return the interpreter's "check interval"; see :func:`setcheckinterval`. Modified: python/branches/py3k/Doc/license.rst ============================================================================== --- python/branches/py3k/Doc/license.rst (original) +++ python/branches/py3k/Doc/license.rst Thu Apr 16 21:52:09 2009 @@ -657,3 +657,35 @@ 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. + + +strtod and dtoa +--------------- + +The file :file:`Python/dtoa.c`, which supplies C functions dtoa and +strtod for conversion of C doubles to and from strings, is derived +from the file of the same name by David M. Gay, currently available +from http://www.netlib.org/fp/. The original file, as retrieved on +March 16, 2009, contains the following copyright and licensing +notice:: + + /**************************************************************** + * + * The author of this software is David M. Gay. + * + * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + * + ***************************************************************/ + + Modified: python/branches/py3k/Include/Python.h ============================================================================== --- python/branches/py3k/Include/Python.h (original) +++ python/branches/py3k/Include/Python.h Thu Apr 16 21:52:09 2009 @@ -118,6 +118,7 @@ #include "pystrtod.h" #include "pystrcmp.h" +#include "dtoa.h" /* _Py_Mangle is defined in compile.c */ PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name); Added: python/branches/py3k/Include/dtoa.h ============================================================================== --- (empty file) +++ python/branches/py3k/Include/dtoa.h Thu Apr 16 21:52:09 2009 @@ -0,0 +1,15 @@ +#ifndef PY_NO_SHORT_FLOAT_REPR +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(double) _Py_dg_strtod(const char *str, char **ptr); +PyAPI_FUNC(char *) _Py_dg_dtoa(double d, int mode, int ndigits, + int *decpt, int *sign, char **rve); +PyAPI_FUNC(void) _Py_dg_freedtoa(char *s); + + +#ifdef __cplusplus +} +#endif +#endif Modified: python/branches/py3k/Include/pymacconfig.h ============================================================================== --- python/branches/py3k/Include/pymacconfig.h (original) +++ python/branches/py3k/Include/pymacconfig.h Thu Apr 16 21:52:09 2009 @@ -17,6 +17,9 @@ # undef SIZEOF_VOID_P # undef SIZEOF__BOOL # undef WORDS_BIGENDIAN +# undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 +# undef DOUBLE_IS_BIG_ENDIAN_IEEE754 +# undef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 # undef VA_LIST_IS_ARRAY # if defined(__LP64__) && defined(__x86_64__) @@ -65,6 +68,9 @@ #ifdef __BIG_ENDIAN__ #define WORDS_BIGENDIAN 1 +#define DOUBLE_IS_BIG_ENDIAN_IEEE754 +#else +#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 #endif /* __BIG_ENDIAN */ Modified: python/branches/py3k/Include/pymath.h ============================================================================== --- python/branches/py3k/Include/pymath.h (original) +++ python/branches/py3k/Include/pymath.h Thu Apr 16 21:52:09 2009 @@ -92,6 +92,11 @@ # endif #endif +#ifdef HAVE_GCC_ASM_FOR_X87 +PyAPI_FUNC(unsigned short) _Py_get_387controlword(void); +PyAPI_FUNC(void) _Py_set_387controlword(unsigned short); +#endif + /* Py_IS_NAN(X) * Return 1 if float or double arg is a NaN, else 0. * Caution: Modified: python/branches/py3k/Include/pyport.h ============================================================================== --- python/branches/py3k/Include/pyport.h (original) +++ python/branches/py3k/Include/pyport.h Thu Apr 16 21:52:09 2009 @@ -465,6 +465,53 @@ errno = 0; \ } while(0) +/* The functions _Py_dg_strtod and _Py_dg_dtoa in Python/dtoa.c require that + the FPU is using 53-bit precision. Here are macros that force this. See + Python/pystrtod.c for an example of their use. */ + +#ifdef USING_X87_FPU +#define _Py_SET_53BIT_PRECISION_HEADER \ + unsigned short old_387controlword, new_387controlword +#define _Py_SET_53BIT_PRECISION_START \ + do { \ + old_387controlword = _Py_get_387controlword(); \ + new_387controlword = (old_387controlword & ~0x0f00) | 0x0200; \ + if (new_387controlword != old_387controlword) \ + _Py_set_387controlword(new_387controlword); \ + } while (0) +#define _Py_SET_53BIT_PRECISION_END \ + if (new_387controlword != old_387controlword) \ + _Py_set_387controlword(old_387controlword) +#else +#define _Py_SET_53BIT_PRECISION_HEADER +#define _Py_SET_53BIT_PRECISION_START +#define _Py_SET_53BIT_PRECISION_END +#endif + +/* If we can't guarantee 53-bit precision, don't use the code + in Python/dtoa.c, but fall back to standard code. This + means that repr of a float will be long (17 sig digits). + + Realistically, there are two things that could go wrong: + + (1) doubles aren't IEEE 754 doubles, or + (2) we're on x86 with the rounding precision set to 64-bits + (extended precision), and we don't know how to change + the rounding precision. + */ + +#if !defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) && \ + !defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) && \ + !defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754) +#define PY_NO_SHORT_FLOAT_REPR +#endif + +/* double rounding is symptomatic of use of extended precision on x86 */ +#ifdef X87_DOUBLE_ROUNDING +#define PY_NO_SHORT_FLOAT_REPR +#endif + + /* Py_DEPRECATED(version) * Declare a variable, type, or function deprecated. * Usage: Added: python/branches/py3k/Lib/test/formatfloat_testcases.txt ============================================================================== --- (empty file) +++ python/branches/py3k/Lib/test/formatfloat_testcases.txt Thu Apr 16 21:52:09 2009 @@ -0,0 +1,354 @@ +-- 'f' code formatting, with explicit precision (>= 0). Output always +-- has the given number of places after the point; zeros are added if +-- necessary to make this true. + +-- zeros +%.0f 0 -> 0 +%.1f 0 -> 0.0 +%.2f 0 -> 0.00 +%.3f 0 -> 0.000 +%.50f 0 -> 0.00000000000000000000000000000000000000000000000000 + +-- precision 0; result should never include a . +%.0f 1.5 -> 2 +%.0f 2.5 -> 2 +%.0f 3.5 -> 4 +%.0f 0.0 -> 0 +%.0f 0.1 -> 0 +%.0f 0.001 -> 0 +%.0f 10.0 -> 10 +%.0f 10.1 -> 10 +%.0f 10.01 -> 10 +%.0f 123.456 -> 123 +%.0f 1234.56 -> 1235 +%.0f 1e49 -> 9999999999999999464902769475481793196872414789632 +-- %.0f 1e50 -> 100000000000000007629769841091887003294964970946560 +%.0f 9.9999999999999987e+49 -> 99999999999999986860582406952576489172979654066176 + +-- precision 1 +%.1f 0.0001 -> 0.0 +%.1f 0.001 -> 0.0 +%.1f 0.01 -> 0.0 +%.1f 0.04 -> 0.0 +%.1f 0.06 -> 0.1 +%.1f 0.25 -> 0.2 +%.1f 0.75 -> 0.8 +%.1f 1.4 -> 1.4 +%.1f 1.5 -> 1.5 +%.1f 10.0 -> 10.0 +%.1f 1000.03 -> 1000.0 +%.1f 1234.5678 -> 1234.6 +%.1f 1234.7499 -> 1234.7 +%.1f 1234.75 -> 1234.8 + +-- precision 2 +%.2f 0.0001 -> 0.00 +%.2f 0.001 -> 0.00 +%.2f 0.004999 -> 0.00 +%.2f 0.005001 -> 0.01 +%.2f 0.01 -> 0.01 +%.2f 0.125 -> 0.12 +%.2f 0.375 -> 0.38 +%.2f 1234500 -> 1234500.00 +%.2f 1234560 -> 1234560.00 +%.2f 1234567 -> 1234567.00 +%.2f 1234567.8 -> 1234567.80 +%.2f 1234567.89 -> 1234567.89 +%.2f 1234567.891 -> 1234567.89 +%.2f 1234567.8912 -> 1234567.89 + +-- alternate form always includes a decimal point. This only +-- makes a difference when the precision is 0. +%#.0f 0 -> 0. +%#.1f 0 -> 0.0 +%#.0f 1.5 -> 2. +%#.0f 2.5 -> 2. +%#.0f 10.1 -> 10. +%#.0f 1234.56 -> 1235. +%#.1f 1.4 -> 1.4 +%#.2f 0.375 -> 0.38 + +-- if precision is omitted it defaults to 6 +%f 0 -> 0.000000 +%f 1230000 -> 1230000.000000 +%f 1234567 -> 1234567.000000 +%f 123.4567 -> 123.456700 +%f 1.23456789 -> 1.234568 +%f 0.00012 -> 0.000120 +%f 0.000123 -> 0.000123 +%f 0.00012345 -> 0.000123 +%f 0.000001 -> 0.000001 +%f 0.0000005001 -> 0.000001 +%f 0.0000004999 -> 0.000000 + +-- 'e' code formatting with explicit precision (>= 0). Output should +-- always have exactly the number of places after the point that were +-- requested. + +-- zeros +%.0e 0 -> 0e+00 +%.1e 0 -> 0.0e+00 +%.2e 0 -> 0.00e+00 +%.10e 0 -> 0.0000000000e+00 +%.50e 0 -> 0.00000000000000000000000000000000000000000000000000e+00 + +-- precision 0. no decimal point in the output +%.0e 0.01 -> 1e-02 +%.0e 0.1 -> 1e-01 +%.0e 1 -> 1e+00 +%.0e 10 -> 1e+01 +%.0e 100 -> 1e+02 +%.0e 0.012 -> 1e-02 +%.0e 0.12 -> 1e-01 +%.0e 1.2 -> 1e+00 +%.0e 12 -> 1e+01 +%.0e 120 -> 1e+02 +%.0e 123.456 -> 1e+02 +%.0e 0.000123456 -> 1e-04 +%.0e 123456000 -> 1e+08 +%.0e 0.5 -> 5e-01 +%.0e 1.4 -> 1e+00 +%.0e 1.5 -> 2e+00 +%.0e 1.6 -> 2e+00 +%.0e 2.4999999 -> 2e+00 +%.0e 2.5 -> 2e+00 +%.0e 2.5000001 -> 3e+00 +%.0e 3.499999999999 -> 3e+00 +%.0e 3.5 -> 4e+00 +%.0e 4.5 -> 4e+00 +%.0e 5.5 -> 6e+00 +%.0e 6.5 -> 6e+00 +%.0e 7.5 -> 8e+00 +%.0e 8.5 -> 8e+00 +%.0e 9.4999 -> 9e+00 +%.0e 9.5 -> 1e+01 +%.0e 10.5 -> 1e+01 +%.0e 14.999 -> 1e+01 +%.0e 15 -> 2e+01 + +-- precision 1 +%.1e 0.0001 -> 1.0e-04 +%.1e 0.001 -> 1.0e-03 +%.1e 0.01 -> 1.0e-02 +%.1e 0.1 -> 1.0e-01 +%.1e 1 -> 1.0e+00 +%.1e 10 -> 1.0e+01 +%.1e 100 -> 1.0e+02 +%.1e 120 -> 1.2e+02 +%.1e 123 -> 1.2e+02 +%.1e 123.4 -> 1.2e+02 + +-- precision 2 +%.2e 0.00013 -> 1.30e-04 +%.2e 0.000135 -> 1.35e-04 +%.2e 0.0001357 -> 1.36e-04 +%.2e 0.0001 -> 1.00e-04 +%.2e 0.001 -> 1.00e-03 +%.2e 0.01 -> 1.00e-02 +%.2e 0.1 -> 1.00e-01 +%.2e 1 -> 1.00e+00 +%.2e 10 -> 1.00e+01 +%.2e 100 -> 1.00e+02 +%.2e 1000 -> 1.00e+03 +%.2e 1500 -> 1.50e+03 +%.2e 1590 -> 1.59e+03 +%.2e 1598 -> 1.60e+03 +%.2e 1598.7 -> 1.60e+03 +%.2e 1598.76 -> 1.60e+03 +%.2e 9999 -> 1.00e+04 + +-- omitted precision defaults to 6 +%e 0 -> 0.000000e+00 +%e 165 -> 1.650000e+02 +%e 1234567 -> 1.234567e+06 +%e 12345678 -> 1.234568e+07 +%e 1.1 -> 1.100000e+00 + +-- alternate form always contains a decimal point. This only makes +-- a difference when precision is 0. + +%#.0e 0.01 -> 1.e-02 +%#.0e 0.1 -> 1.e-01 +%#.0e 1 -> 1.e+00 +%#.0e 10 -> 1.e+01 +%#.0e 100 -> 1.e+02 +%#.0e 0.012 -> 1.e-02 +%#.0e 0.12 -> 1.e-01 +%#.0e 1.2 -> 1.e+00 +%#.0e 12 -> 1.e+01 +%#.0e 120 -> 1.e+02 +%#.0e 123.456 -> 1.e+02 +%#.0e 0.000123456 -> 1.e-04 +%#.0e 123456000 -> 1.e+08 +%#.0e 0.5 -> 5.e-01 +%#.0e 1.4 -> 1.e+00 +%#.0e 1.5 -> 2.e+00 +%#.0e 1.6 -> 2.e+00 +%#.0e 2.4999999 -> 2.e+00 +%#.0e 2.5 -> 2.e+00 +%#.0e 2.5000001 -> 3.e+00 +%#.0e 3.499999999999 -> 3.e+00 +%#.0e 3.5 -> 4.e+00 +%#.0e 4.5 -> 4.e+00 +%#.0e 5.5 -> 6.e+00 +%#.0e 6.5 -> 6.e+00 +%#.0e 7.5 -> 8.e+00 +%#.0e 8.5 -> 8.e+00 +%#.0e 9.4999 -> 9.e+00 +%#.0e 9.5 -> 1.e+01 +%#.0e 10.5 -> 1.e+01 +%#.0e 14.999 -> 1.e+01 +%#.0e 15 -> 2.e+01 +%#.1e 123.4 -> 1.2e+02 +%#.2e 0.0001357 -> 1.36e-04 + +-- 'g' code formatting. + +-- zeros +%.0g 0 -> 0 +%.1g 0 -> 0 +%.2g 0 -> 0 +%.3g 0 -> 0 +%.4g 0 -> 0 +%.10g 0 -> 0 +%.50g 0 -> 0 +%.100g 0 -> 0 + +-- precision 0 doesn't make a lot of sense for the 'g' code (what does +-- it mean to have no significant digits?); in practice, it's interpreted +-- as identical to precision 1 +%.0g 1000 -> 1e+03 +%.0g 100 -> 1e+02 +%.0g 10 -> 1e+01 +%.0g 1 -> 1 +%.0g 0.1 -> 0.1 +%.0g 0.01 -> 0.01 +%.0g 1e-3 -> 0.001 +%.0g 1e-4 -> 0.0001 +%.0g 1e-5 -> 1e-05 +%.0g 1e-6 -> 1e-06 +%.0g 12 -> 1e+01 +%.0g 120 -> 1e+02 +%.0g 1.2 -> 1 +%.0g 0.12 -> 0.1 +%.0g 0.012 -> 0.01 +%.0g 0.0012 -> 0.001 +%.0g 0.00012 -> 0.0001 +%.0g 0.000012 -> 1e-05 +%.0g 0.0000012 -> 1e-06 + +-- precision 1 identical to precision 0 +%.1g 1000 -> 1e+03 +%.1g 100 -> 1e+02 +%.1g 10 -> 1e+01 +%.1g 1 -> 1 +%.1g 0.1 -> 0.1 +%.1g 0.01 -> 0.01 +%.1g 1e-3 -> 0.001 +%.1g 1e-4 -> 0.0001 +%.1g 1e-5 -> 1e-05 +%.1g 1e-6 -> 1e-06 +%.1g 12 -> 1e+01 +%.1g 120 -> 1e+02 +%.1g 1.2 -> 1 +%.1g 0.12 -> 0.1 +%.1g 0.012 -> 0.01 +%.1g 0.0012 -> 0.001 +%.1g 0.00012 -> 0.0001 +%.1g 0.000012 -> 1e-05 +%.1g 0.0000012 -> 1e-06 + +-- precision 2 +%.2g 1000 -> 1e+03 +%.2g 100 -> 1e+02 +%.2g 10 -> 10 +%.2g 1 -> 1 +%.2g 0.1 -> 0.1 +%.2g 0.01 -> 0.01 +%.2g 0.001 -> 0.001 +%.2g 1e-4 -> 0.0001 +%.2g 1e-5 -> 1e-05 +%.2g 1e-6 -> 1e-06 +%.2g 1234 -> 1.2e+03 +%.2g 123 -> 1.2e+02 +%.2g 12.3 -> 12 +%.2g 1.23 -> 1.2 +%.2g 0.123 -> 0.12 +%.2g 0.0123 -> 0.012 +%.2g 0.00123 -> 0.0012 +%.2g 0.000123 -> 0.00012 +%.2g 0.0000123 -> 1.2e-05 + +-- alternate g formatting: always include decimal point and +-- exactly significant digits. +%#.0g 0 -> 0. +%#.1g 0 -> 0. +%#.2g 0 -> 0.0 +%#.3g 0 -> 0.00 +%#.4g 0 -> 0.000 + +%#.0g 0.2 -> 0.2 +%#.1g 0.2 -> 0.2 +%#.2g 0.2 -> 0.20 +%#.3g 0.2 -> 0.200 +%#.4g 0.2 -> 0.2000 +%#.10g 0.2 -> 0.2000000000 + +%#.0g 2 -> 2. +%#.1g 2 -> 2. +%#.2g 2 -> 2.0 +%#.3g 2 -> 2.00 +%#.4g 2 -> 2.000 + +%#.0g 20 -> 2.e+01 +%#.1g 20 -> 2.e+01 +%#.2g 20 -> 20. +%#.3g 20 -> 20.0 +%#.4g 20 -> 20.00 + +%#.0g 234.56 -> 2.e+02 +%#.1g 234.56 -> 2.e+02 +%#.2g 234.56 -> 2.3e+02 +%#.3g 234.56 -> 235. +%#.4g 234.56 -> 234.6 +%#.5g 234.56 -> 234.56 +%#.6g 234.56 -> 234.560 + +-- for repr formatting see the separate test_short_repr test in +-- test_float.py. Not all platforms use short repr for floats. + +-- str formatting. Result always includes decimal point and at +-- least one digit after the point, or an exponent. +%s 0 -> 0.0 +%s 1 -> 1.0 + +%s 0.01 -> 0.01 +%s 0.02 -> 0.02 +%s 0.03 -> 0.03 +%s 0.04 -> 0.04 +%s 0.05 -> 0.05 + +-- str truncates to 12 significant digits +%s 1.234123412341 -> 1.23412341234 +%s 1.23412341234 -> 1.23412341234 +%s 1.2341234123 -> 1.2341234123 + +-- values >= 1e11 get an exponent +%s 10 -> 10.0 +%s 100 -> 100.0 +%s 1e10 -> 10000000000.0 +%s 9.999e10 -> 99990000000.0 +%s 99999999999 -> 99999999999.0 +%s 1e11 -> 1e+11 +%s 1e12 -> 1e+12 + +-- as do values < 1e-4 +%s 1e-3 -> 0.001 +%s 1.001e-4 -> 0.0001001 +%s 1.000000000001e-4 -> 0.0001 +%s 1.00000000001e-4 -> 0.000100000000001 +%s 1.0000000001e-4 -> 0.00010000000001 +%s 1e-4 -> 0.0001 +%s 0.999999999999e-4 -> 9.99999999999e-05 +%s 0.999e-4 -> 9.99e-05 +%s 1e-5 -> 1e-05 Modified: python/branches/py3k/Makefile.pre.in ============================================================================== --- python/branches/py3k/Makefile.pre.in (original) +++ python/branches/py3k/Makefile.pre.in Thu Apr 16 21:52:09 2009 @@ -305,6 +305,7 @@ Python/getopt.o \ Python/pystrcmp.o \ Python/pystrtod.o \ + Python/dtoa.o \ Python/formatter_unicode.o \ Python/$(DYNLOADFILE) \ $(LIBOBJS) \ @@ -621,6 +622,7 @@ Include/complexobject.h \ Include/descrobject.h \ Include/dictobject.h \ + Include/dtoa.h \ Include/enumobject.h \ Include/errcode.h \ Include/eval.h \ Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Thu Apr 16 21:52:09 2009 @@ -160,6 +160,7 @@ Ben Darnell Jonathan Dasteel John DeGood +Ned Deily Vincent Delft Arnaud Delobelle Erik Demaine Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Apr 16 21:52:09 2009 @@ -12,6 +12,45 @@ Core and Builtins ----------------- +- The repr function switches to exponential notation at 1e16, not 1e17 + as it did before. This change applies to both 'short' and legacy + float repr styles. For the new repr style, it avoids misleading + output in some cases: an example is repr(2e16+8), which gives + '2.000000000000001e+16'; without this change it would have produced + '20000000000000010.0' instead. + +- Similarly, the str function switches to exponential notation at + 1e11, not 1e12. This avoids printing 13 significant digits in + situations where only 12 of them are correct. Example problem + value: str(1e11 + 0.5). (This minor issue has existed in 2.x for a + long time.) + +- On x86, SSE2 instructions for floating-point are automatically + detected and, where possible, enabled on platforms using the gcc + compiler. As a consequence, some arithmetic operations may have + different (more accurate!) results on some platforms, and + cross-platform consistency of Python arithmetic should be improved. + This applies particularly to Linux/x86. + +- Issue #1580: On most platforms, use a 'short' float repr: for a + finite float x, repr(x) now outputs a string based on the shortest + sequence of decimal digits that rounds to x. Previous behaviour was + to output 17 significant digits and then strip trailing zeros. + + There's a new sys attribute sys.float_repr_style, which takes + the value 'short' to indicate that we're using short float repr, + and 'legacy' if the short float repr isn't available for one + reason or another. + + The float repr change involves incorporating David Gay's 'perfect + rounding' code into the Python core (it's in Python/dtoa.c). As a + secondary consequence, all string-to-float and float-to-string + conversions (including all float formatting operations) will be + correctly rounded on these platforms. + + See issue 1580 discussions for details of platforms for which + this change does not apply. + - Issue #5759: float() didn't call __float__ on str subclasses. - The string.maketrans() function is deprecated; there is a new static method Modified: python/branches/py3k/PC/pyconfig.h ============================================================================== --- python/branches/py3k/PC/pyconfig.h (original) +++ python/branches/py3k/PC/pyconfig.h Thu Apr 16 21:52:09 2009 @@ -752,4 +752,8 @@ socket handles greater than FD_SETSIZE */ #define Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE +/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the + least significant byte first */ +#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1 + #endif /* !Py_CONFIG_H */ Modified: python/branches/py3k/PCbuild/pythoncore.vcproj ============================================================================== --- python/branches/py3k/PCbuild/pythoncore.vcproj (original) +++ python/branches/py3k/PCbuild/pythoncore.vcproj Thu Apr 16 21:52:09 2009 @@ -895,6 +895,10 @@ > + + @@ -1747,6 +1751,10 @@ > + + Added: python/branches/py3k/Python/dtoa.c ============================================================================== --- (empty file) +++ python/branches/py3k/Python/dtoa.c Thu Apr 16 21:52:09 2009 @@ -0,0 +1,2646 @@ +/**************************************************************** + * + * The author of this software is David M. Gay. + * + * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + * + ***************************************************************/ + +/**************************************************************** + * This is dtoa.c by David M. Gay, downloaded from + * http://www.netlib.org/fp/dtoa.c on April 15, 2009 and modified for + * inclusion into the Python core by Mark E. T. Dickinson and Eric V. Smith. + * The major modifications are as follows: + * + * 0. The original code has been specialized to Python's needs by removing + * many of the #ifdef'd sections. In particular, code to support VAX and + * IBM floating-point formats, hex NaNs, hex floats, locale-aware + * treatment of the decimal point, and setting of the inexact flag have + * been removed. + * + * 1. We use PyMem_Malloc and PyMem_Free in place of malloc and free. + * + * 2. The public functions strtod, dtoa and freedtoa all now have + * a _Py_dg_ prefix. + * + * 3. Instead of assuming that PyMem_Malloc always succeeds, we thread + * PyMem_Malloc failures through the code. The functions + * + * Balloc, multadd, s2b, i2b, mult, pow5mult, lshift, diff, d2b + * + * of return type *Bigint all return NULL to indicate a malloc failure. + * Similarly, rv_alloc and nrv_alloc (return type char *) return NULL on + * failure. bigcomp now has return type int (it used to be void) and + * returns -1 on failure and 0 otherwise. _Py_dg_dtoa returns NULL + * on failure. _Py_dg_strtod indicates failure due to malloc failure + * by returning -1.0, setting errno=ENOMEM and *se to s00. + * + * 4. The static variable dtoa_result has been removed. Callers of + * _Py_dg_dtoa are expected to call _Py_dg_freedtoa to free + * the memory allocated by _Py_dg_dtoa. + * + * 5. The code has been reformatted to better fit with Python's + * C style guide (PEP 7). + * + ***************************************************************/ + +/* Please send bug reports for the original dtoa.c code to David M. Gay (dmg + * at acm dot org, with " at " changed at "@" and " dot " changed to "."). + * Please report bugs for this modified version using the Python issue tracker + * (http://bugs.python.org). */ + +/* On a machine with IEEE extended-precision registers, it is + * necessary to specify double-precision (53-bit) rounding precision + * before invoking strtod or dtoa. If the machine uses (the equivalent + * of) Intel 80x87 arithmetic, the call + * _control87(PC_53, MCW_PC); + * does this with many compilers. Whether this or another call is + * appropriate depends on the compiler; for this to work, it may be + * necessary to #include "float.h" or another system-dependent header + * file. + */ + +/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. + * + * This strtod returns a nearest machine number to the input decimal + * string (or sets errno to ERANGE). With IEEE arithmetic, ties are + * broken by the IEEE round-even rule. Otherwise ties are broken by + * biased rounding (add half and chop). + * + * Inspired loosely by William D. Clinger's paper "How to Read Floating + * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. + * + * Modifications: + * + * 1. We only require IEEE, IBM, or VAX double-precision + * arithmetic (not IEEE double-extended). + * 2. We get by with floating-point arithmetic in a case that + * Clinger missed -- when we're computing d * 10^n + * for a small integer d and the integer n is not too + * much larger than 22 (the maximum integer k for which + * we can represent 10^k exactly), we may be able to + * compute (d*10^k) * 10^(e-k) with just one roundoff. + * 3. Rather than a bit-at-a-time adjustment of the binary + * result in the hard case, we use floating-point + * arithmetic to determine the adjustment to within + * one bit; only in really hard cases do we need to + * compute a second residual. + * 4. Because of 3., we don't need a large table of powers of 10 + * for ten-to-e (just some small tables, e.g. of 10^k + * for 0 <= k <= 22). + */ + +/* Linking of Python's #defines to Gay's #defines starts here. */ + +#include "Python.h" + +/* if PY_NO_SHORT_FLOAT_REPR is defined, then don't even try to compile + the following code */ +#ifndef PY_NO_SHORT_FLOAT_REPR + +#include "float.h" + +#define MALLOC PyMem_Malloc +#define FREE PyMem_Free + +/* This code should also work for ARM mixed-endian format on little-endian + machines, where doubles have byte order 45670123 (in increasing address + order, 0 being the least significant byte). */ +#ifdef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 +# define IEEE_8087 +#endif +#if defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) || \ + defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754) +# define IEEE_MC68k +#endif +#if defined(IEEE_8087) + defined(IEEE_MC68k) != 1 +#error "Exactly one of IEEE_8087 or IEEE_MC68k should be defined." +#endif + +/* The code below assumes that the endianness of integers matches the + endianness of the two 32-bit words of a double. Check this. */ +#if defined(WORDS_BIGENDIAN) && (defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) || \ + defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754)) +#error "doubles and ints have incompatible endianness" +#endif + +#if !defined(WORDS_BIGENDIAN) && defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) +#error "doubles and ints have incompatible endianness" +#endif + + +#if defined(HAVE_UINT32_T) && defined(HAVE_INT32_T) +typedef PY_UINT32_T ULong; +typedef PY_INT32_T Long; +#else +#error "Failed to find an exact-width 32-bit integer type" +#endif + +#if defined(HAVE_UINT64_T) +#define ULLong PY_UINT64_T +#else +#undef ULLong +#endif + +#undef DEBUG +#ifdef Py_DEBUG +#define DEBUG +#endif + +/* End Python #define linking */ + +#ifdef DEBUG +#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} +#endif + +#ifndef PRIVATE_MEM +#define PRIVATE_MEM 2304 +#endif +#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) +static double private_mem[PRIVATE_mem], *pmem_next = private_mem; + +#ifdef __cplusplus +extern "C" { +#endif + +typedef union { double d; ULong L[2]; } U; + +#ifdef IEEE_8087 +#define word0(x) (x)->L[1] +#define word1(x) (x)->L[0] +#else +#define word0(x) (x)->L[0] +#define word1(x) (x)->L[1] +#endif +#define dval(x) (x)->d + +#ifndef STRTOD_DIGLIM +#define STRTOD_DIGLIM 40 +#endif + +#ifdef DIGLIM_DEBUG +extern int strtod_diglim; +#else +#define strtod_diglim STRTOD_DIGLIM +#endif + +/* The following definition of Storeinc is appropriate for MIPS processors. + * An alternative that might be better on some machines is + * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) + */ +#if defined(IEEE_8087) +#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ + ((unsigned short *)a)[0] = (unsigned short)c, a++) +#else +#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ + ((unsigned short *)a)[1] = (unsigned short)c, a++) +#endif + +/* #define P DBL_MANT_DIG */ +/* Ten_pmax = floor(P*log(2)/log(5)) */ +/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ +/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ +/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ + +#define Exp_shift 20 +#define Exp_shift1 20 +#define Exp_msk1 0x100000 +#define Exp_msk11 0x100000 +#define Exp_mask 0x7ff00000 +#define P 53 +#define Nbits 53 +#define Bias 1023 +#define Emax 1023 +#define Emin (-1022) +#define Exp_1 0x3ff00000 +#define Exp_11 0x3ff00000 +#define Ebits 11 +#define Frac_mask 0xfffff +#define Frac_mask1 0xfffff +#define Ten_pmax 22 +#define Bletch 0x10 +#define Bndry_mask 0xfffff +#define Bndry_mask1 0xfffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 1 +#define Tiny0 0 +#define Tiny1 1 +#define Quick_max 14 +#define Int_max 14 + +#ifndef Flt_Rounds +#ifdef FLT_ROUNDS +#define Flt_Rounds FLT_ROUNDS +#else +#define Flt_Rounds 1 +#endif +#endif /*Flt_Rounds*/ + +#define Rounding Flt_Rounds + +#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) +#define Big1 0xffffffff + +#ifndef NAN_WORD0 +#define NAN_WORD0 0x7ff80000 +#endif + +#ifndef NAN_WORD1 +#define NAN_WORD1 0 +#endif + + +/* struct BCinfo is used to pass information from _Py_dg_strtod to bigcomp */ + +typedef struct BCinfo BCinfo; +struct +BCinfo { + int dp0, dp1, dplen, dsign, e0, inexact; + int nd, nd0, rounding, scale, uflchk; +}; + +#define FFFFFFFF 0xffffffffUL + +#define Kmax 7 + +/* struct Bigint is used to represent arbitrary-precision integers. These + integers are stored in sign-magnitude format, with the magnitude stored as + an array of base 2**32 digits. Bigints are always normalized: if x is a + Bigint then x->wds >= 1, and either x->wds == 1 or x[wds-1] is nonzero. + + The Bigint fields are as follows: + + - next is a header used by Balloc and Bfree to keep track of lists + of freed Bigints; it's also used for the linked list of + powers of 5 of the form 5**2**i used by pow5mult. + - k indicates which pool this Bigint was allocated from + - maxwds is the maximum number of words space was allocated for + (usually maxwds == 2**k) + - sign is 1 for negative Bigints, 0 for positive. The sign is unused + (ignored on inputs, set to 0 on outputs) in almost all operations + involving Bigints: a notable exception is the diff function, which + ignores signs on inputs but sets the sign of the output correctly. + - wds is the actual number of significant words + - x contains the vector of words (digits) for this Bigint, from least + significant (x[0]) to most significant (x[wds-1]). +*/ + +struct +Bigint { + struct Bigint *next; + int k, maxwds, sign, wds; + ULong x[1]; +}; + +typedef struct Bigint Bigint; + +/* Memory management: memory is allocated from, and returned to, Kmax+1 pools + of memory, where pool k (0 <= k <= Kmax) is for Bigints b with b->maxwds == + 1 << k. These pools are maintained as linked lists, with freelist[k] + pointing to the head of the list for pool k. + + On allocation, if there's no free slot in the appropriate pool, MALLOC is + called to get more memory. This memory is not returned to the system until + Python quits. There's also a private memory pool that's allocated from + in preference to using MALLOC. + + For Bigints with more than (1 << Kmax) digits (which implies at least 1233 + decimal digits), memory is directly allocated using MALLOC, and freed using + FREE. + + XXX: it would be easy to bypass this memory-management system and + translate each call to Balloc into a call to PyMem_Malloc, and each + Bfree to PyMem_Free. Investigate whether this has any significant + performance on impact. */ + +static Bigint *freelist[Kmax+1]; + +/* Allocate space for a Bigint with up to 1<next; + else { + x = 1 << k; + len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) + /sizeof(double); + if (pmem_next - private_mem + len <= PRIVATE_mem) { + rv = (Bigint*)pmem_next; + pmem_next += len; + } + else { + rv = (Bigint*)MALLOC(len*sizeof(double)); + if (rv == NULL) + return NULL; + } + rv->k = k; + rv->maxwds = x; + } + rv->sign = rv->wds = 0; + return rv; +} + +/* Free a Bigint allocated with Balloc */ + +static void +Bfree(Bigint *v) +{ + if (v) { + if (v->k > Kmax) + FREE((void*)v); + else { + v->next = freelist[v->k]; + freelist[v->k] = v; + } + } +} + +#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ + y->wds*sizeof(Long) + 2*sizeof(int)) + +/* Multiply a Bigint b by m and add a. Either modifies b in place and returns + a pointer to the modified b, or Bfrees b and returns a pointer to a copy. + On failure, return NULL. In this case, b will have been already freed. */ + +static Bigint * +multadd(Bigint *b, int m, int a) /* multiply by m and add a */ +{ + int i, wds; +#ifdef ULLong + ULong *x; + ULLong carry, y; +#else + ULong carry, *x, y; + ULong xi, z; +#endif + Bigint *b1; + + wds = b->wds; + x = b->x; + i = 0; + carry = a; + do { +#ifdef ULLong + y = *x * (ULLong)m + carry; + carry = y >> 32; + *x++ = y & FFFFFFFF; +#else + xi = *x; + y = (xi & 0xffff) * m + carry; + z = (xi >> 16) * m + (y >> 16); + carry = z >> 16; + *x++ = (z << 16) + (y & 0xffff); +#endif + } + while(++i < wds); + if (carry) { + if (wds >= b->maxwds) { + b1 = Balloc(b->k+1); + if (b1 == NULL){ + Bfree(b); + return NULL; + } + Bcopy(b1, b); + Bfree(b); + b = b1; + } + b->x[wds++] = (ULong)carry; + b->wds = wds; + } + return b; +} + +/* convert a string s containing nd decimal digits (possibly containing a + decimal separator at position nd0, which is ignored) to a Bigint. This + function carries on where the parsing code in _Py_dg_strtod leaves off: on + entry, y9 contains the result of converting the first 9 digits. Returns + NULL on failure. */ + +static Bigint * +s2b(const char *s, int nd0, int nd, ULong y9, int dplen) +{ + Bigint *b; + int i, k; + Long x, y; + + x = (nd + 8) / 9; + for(k = 0, y = 1; x > y; y <<= 1, k++) ; + b = Balloc(k); + if (b == NULL) + return NULL; + b->x[0] = y9; + b->wds = 1; + + i = 9; + if (9 < nd0) { + s += 9; + do { + b = multadd(b, 10, *s++ - '0'); + if (b == NULL) + return NULL; + } while(++i < nd0); + s += dplen; + } + else + s += dplen + 9; + for(; i < nd; i++) { + b = multadd(b, 10, *s++ - '0'); + if (b == NULL) + return NULL; + } + return b; +} + +/* count leading 0 bits in the 32-bit integer x. */ + +static int +hi0bits(ULong x) +{ + int k = 0; + + if (!(x & 0xffff0000)) { + k = 16; + x <<= 16; + } + if (!(x & 0xff000000)) { + k += 8; + x <<= 8; + } + if (!(x & 0xf0000000)) { + k += 4; + x <<= 4; + } + if (!(x & 0xc0000000)) { + k += 2; + x <<= 2; + } + if (!(x & 0x80000000)) { + k++; + if (!(x & 0x40000000)) + return 32; + } + return k; +} + +/* count trailing 0 bits in the 32-bit integer y, and shift y right by that + number of bits. */ + +static int +lo0bits(ULong *y) +{ + int k; + ULong x = *y; + + if (x & 7) { + if (x & 1) + return 0; + if (x & 2) { + *y = x >> 1; + return 1; + } + *y = x >> 2; + return 2; + } + k = 0; + if (!(x & 0xffff)) { + k = 16; + x >>= 16; + } + if (!(x & 0xff)) { + k += 8; + x >>= 8; + } + if (!(x & 0xf)) { + k += 4; + x >>= 4; + } + if (!(x & 0x3)) { + k += 2; + x >>= 2; + } + if (!(x & 1)) { + k++; + x >>= 1; + if (!x) + return 32; + } + *y = x; + return k; +} + +/* convert a small nonnegative integer to a Bigint */ + +static Bigint * +i2b(int i) +{ + Bigint *b; + + b = Balloc(1); + if (b == NULL) + return NULL; + b->x[0] = i; + b->wds = 1; + return b; +} + +/* multiply two Bigints. Returns a new Bigint, or NULL on failure. Ignores + the signs of a and b. */ + +static Bigint * +mult(Bigint *a, Bigint *b) +{ + Bigint *c; + int k, wa, wb, wc; + ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; + ULong y; +#ifdef ULLong + ULLong carry, z; +#else + ULong carry, z; + ULong z2; +#endif + + if (a->wds < b->wds) { + c = a; + a = b; + b = c; + } + k = a->k; + wa = a->wds; + wb = b->wds; + wc = wa + wb; + if (wc > a->maxwds) + k++; + c = Balloc(k); + if (c == NULL) + return NULL; + for(x = c->x, xa = x + wc; x < xa; x++) + *x = 0; + xa = a->x; + xae = xa + wa; + xb = b->x; + xbe = xb + wb; + xc0 = c->x; +#ifdef ULLong + for(; xb < xbe; xc0++) { + if ((y = *xb++)) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * (ULLong)y + *xc + carry; + carry = z >> 32; + *xc++ = z & FFFFFFFF; + } + while(x < xae); + *xc = (ULong)carry; + } + } +#else + for(; xb < xbe; xb++, xc0++) { + if (y = *xb & 0xffff) { + x = xa; + xc = xc0; + carry = 0; + do { + z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; + carry = z >> 16; + z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; + carry = z2 >> 16; + Storeinc(xc, z2, z); + } + while(x < xae); + *xc = carry; + } + if (y = *xb >> 16) { + x = xa; + xc = xc0; + carry = 0; + z2 = *xc; + do { + z = (*x & 0xffff) * y + (*xc >> 16) + carry; + carry = z >> 16; + Storeinc(xc, z, z2); + z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; + carry = z2 >> 16; + } + while(x < xae); + *xc = z2; + } + } +#endif + for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; + c->wds = wc; + return c; +} + +/* p5s is a linked list of powers of 5 of the form 5**(2**i), i >= 2 */ + +static Bigint *p5s; + +/* multiply the Bigint b by 5**k. Returns a pointer to the result, or NULL on + failure; if the returned pointer is distinct from b then the original + Bigint b will have been Bfree'd. Ignores the sign of b. */ + +static Bigint * +pow5mult(Bigint *b, int k) +{ + Bigint *b1, *p5, *p51; + int i; + static int p05[3] = { 5, 25, 125 }; + + if ((i = k & 3)) { + b = multadd(b, p05[i-1], 0); + if (b == NULL) + return NULL; + } + + if (!(k >>= 2)) + return b; + p5 = p5s; + if (!p5) { + /* first time */ + p5 = i2b(625); + if (p5 == NULL) { + Bfree(b); + return NULL; + } + p5s = p5; + p5->next = 0; + } + for(;;) { + if (k & 1) { + b1 = mult(b, p5); + Bfree(b); + b = b1; + if (b == NULL) + return NULL; + } + if (!(k >>= 1)) + break; + p51 = p5->next; + if (!p51) { + p51 = mult(p5,p5); + if (p51 == NULL) { + Bfree(b); + return NULL; + } + p51->next = 0; + p5->next = p51; + } + p5 = p51; + } + return b; +} + +/* shift a Bigint b left by k bits. Return a pointer to the shifted result, + or NULL on failure. If the returned pointer is distinct from b then the + original b will have been Bfree'd. Ignores the sign of b. */ + +static Bigint * +lshift(Bigint *b, int k) +{ + int i, k1, n, n1; + Bigint *b1; + ULong *x, *x1, *xe, z; + + n = k >> 5; + k1 = b->k; + n1 = n + b->wds + 1; + for(i = b->maxwds; n1 > i; i <<= 1) + k1++; + b1 = Balloc(k1); + if (b1 == NULL) { + Bfree(b); + return NULL; + } + x1 = b1->x; + for(i = 0; i < n; i++) + *x1++ = 0; + x = b->x; + xe = x + b->wds; + if (k &= 0x1f) { + k1 = 32 - k; + z = 0; + do { + *x1++ = *x << k | z; + z = *x++ >> k1; + } + while(x < xe); + if ((*x1 = z)) + ++n1; + } + else do + *x1++ = *x++; + while(x < xe); + b1->wds = n1 - 1; + Bfree(b); + return b1; +} + +/* Do a three-way compare of a and b, returning -1 if a < b, 0 if a == b and + 1 if a > b. Ignores signs of a and b. */ + +static int +cmp(Bigint *a, Bigint *b) +{ + ULong *xa, *xa0, *xb, *xb0; + int i, j; + + i = a->wds; + j = b->wds; +#ifdef DEBUG + if (i > 1 && !a->x[i-1]) + Bug("cmp called with a->x[a->wds-1] == 0"); + if (j > 1 && !b->x[j-1]) + Bug("cmp called with b->x[b->wds-1] == 0"); +#endif + if (i -= j) + return i; + xa0 = a->x; + xa = xa0 + j; + xb0 = b->x; + xb = xb0 + j; + for(;;) { + if (*--xa != *--xb) + return *xa < *xb ? -1 : 1; + if (xa <= xa0) + break; + } + return 0; +} + +/* Take the difference of Bigints a and b, returning a new Bigint. Returns + NULL on failure. The signs of a and b are ignored, but the sign of the + result is set appropriately. */ + +static Bigint * +diff(Bigint *a, Bigint *b) +{ + Bigint *c; + int i, wa, wb; + ULong *xa, *xae, *xb, *xbe, *xc; +#ifdef ULLong + ULLong borrow, y; +#else + ULong borrow, y; + ULong z; +#endif + + i = cmp(a,b); + if (!i) { + c = Balloc(0); + if (c == NULL) + return NULL; + c->wds = 1; + c->x[0] = 0; + return c; + } + if (i < 0) { + c = a; + a = b; + b = c; + i = 1; + } + else + i = 0; + c = Balloc(a->k); + if (c == NULL) + return NULL; + c->sign = i; + wa = a->wds; + xa = a->x; + xae = xa + wa; + wb = b->wds; + xb = b->x; + xbe = xb + wb; + xc = c->x; + borrow = 0; +#ifdef ULLong + do { + y = (ULLong)*xa++ - *xb++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = y & FFFFFFFF; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = y & FFFFFFFF; + } +#else + do { + y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } + while(xb < xbe); + while(xa < xae) { + y = (*xa & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } +#endif + while(!*--xc) + wa--; + c->wds = wa; + return c; +} + +/* Given a positive normal double x, return the difference between x and the next + double up. Doesn't give correct results for subnormals. */ + +static double +ulp(U *x) +{ + Long L; + U u; + + L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; + word0(&u) = L; + word1(&u) = 0; + return dval(&u); +} + +/* Convert a Bigint to a double plus an exponent */ + +static double +b2d(Bigint *a, int *e) +{ + ULong *xa, *xa0, w, y, z; + int k; + U d; + + xa0 = a->x; + xa = xa0 + a->wds; + y = *--xa; +#ifdef DEBUG + if (!y) Bug("zero y in b2d"); +#endif + k = hi0bits(y); + *e = 32 - k; + if (k < Ebits) { + word0(&d) = Exp_1 | y >> (Ebits - k); + w = xa > xa0 ? *--xa : 0; + word1(&d) = y << ((32-Ebits) + k) | w >> (Ebits - k); + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + if (k -= Ebits) { + word0(&d) = Exp_1 | y << k | z >> (32 - k); + y = xa > xa0 ? *--xa : 0; + word1(&d) = z << k | y >> (32 - k); + } + else { + word0(&d) = Exp_1 | y; + word1(&d) = z; + } + ret_d: + return dval(&d); +} + +/* Convert a double to a Bigint plus an exponent. Return NULL on failure. + + Given a finite nonzero double d, return an odd Bigint b and exponent *e + such that fabs(d) = b * 2**e. On return, *bbits gives the number of + significant bits of e; that is, 2**(*bbits-1) <= b < 2**(*bbits). + + If d is zero, then b == 0, *e == -1010, *bbits = 0. + */ + + +static Bigint * +d2b(U *d, int *e, int *bits) +{ + Bigint *b; + int de, k; + ULong *x, y, z; + int i; + + b = Balloc(1); + if (b == NULL) + return NULL; + x = b->x; + + z = word0(d) & Frac_mask; + word0(d) &= 0x7fffffff; /* clear sign bit, which we ignore */ + if ((de = (int)(word0(d) >> Exp_shift))) + z |= Exp_msk1; + if ((y = word1(d))) { + if ((k = lo0bits(&y))) { + x[0] = y | z << (32 - k); + z >>= k; + } + else + x[0] = y; + i = + b->wds = (x[1] = z) ? 2 : 1; + } + else { + k = lo0bits(&z); + x[0] = z; + i = + b->wds = 1; + k += 32; + } + if (de) { + *e = de - Bias - (P-1) + k; + *bits = P - k; + } + else { + *e = de - Bias - (P-1) + 1 + k; + *bits = 32*i - hi0bits(x[i-1]); + } + return b; +} + +/* Compute the ratio of two Bigints, as a double. The result may have an + error of up to 2.5 ulps. */ + +static double +ratio(Bigint *a, Bigint *b) +{ + U da, db; + int k, ka, kb; + + dval(&da) = b2d(a, &ka); + dval(&db) = b2d(b, &kb); + k = ka - kb + 32*(a->wds - b->wds); + if (k > 0) + word0(&da) += k*Exp_msk1; + else { + k = -k; + word0(&db) += k*Exp_msk1; + } + return dval(&da) / dval(&db); +} + +static const double +tens[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22 +}; + +static const double +bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; +static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, + 9007199254740992.*9007199254740992.e-256 + /* = 2^106 * 1e-256 */ +}; +/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ +/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ +#define Scale_Bit 0x10 +#define n_bigtens 5 + +/* case insensitive string match, for recognising 'inf[inity]' and + 'nan' strings. */ + +static int +match(const char **sp, char *t) +{ + int c, d; + const char *s = *sp; + + while((d = *t++)) { + if ((c = *++s) >= 'A' && c <= 'Z') + c += 'a' - 'A'; + if (c != d) + return 0; + } + *sp = s + 1; + return 1; +} + +#define ULbits 32 +#define kshift 5 +#define kmask 31 + + +static int +dshift(Bigint *b, int p2) +{ + int rv = hi0bits(b->x[b->wds-1]) - 4; + if (p2 > 0) + rv -= p2; + return rv & kmask; +} + +/* special case of Bigint division. The quotient is always in the range 0 <= + quotient < 10, and on entry the divisor S is normalized so that its top 4 + bits (28--31) are zero and bit 27 is set. */ + +static int +quorem(Bigint *b, Bigint *S) +{ + int n; + ULong *bx, *bxe, q, *sx, *sxe; +#ifdef ULLong + ULLong borrow, carry, y, ys; +#else + ULong borrow, carry, y, ys; + ULong si, z, zs; +#endif + + n = S->wds; +#ifdef DEBUG + /*debug*/ if (b->wds > n) + /*debug*/ Bug("oversize b in quorem"); +#endif + if (b->wds < n) + return 0; + sx = S->x; + sxe = sx + --n; + bx = b->x; + bxe = bx + n; + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ +#ifdef DEBUG + /*debug*/ if (q > 9) + /*debug*/ Bug("oversized quotient in quorem"); +#endif + if (q) { + borrow = 0; + carry = 0; + do { +#ifdef ULLong + ys = *sx++ * (ULLong)q + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = y & FFFFFFFF; +#else + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#endif + } + while(sx <= sxe); + if (!*bxe) { + bx = b->x; + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + if (cmp(b, S) >= 0) { + q++; + borrow = 0; + carry = 0; + bx = b->x; + sx = S->x; + do { +#ifdef ULLong + ys = *sx++ + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = y & FFFFFFFF; +#else + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#endif + } + while(sx <= sxe); + bx = b->x; + bxe = bx + n; + if (!*bxe) { + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + return q; +} + + +/* return 0 on success, -1 on failure */ + +static int +bigcomp(U *rv, const char *s0, BCinfo *bc) +{ + Bigint *b, *d; + int b2, bbits, d2, dd, dig, dsign, i, j, nd, nd0, p2, p5, speccase; + + dsign = bc->dsign; + nd = bc->nd; + nd0 = bc->nd0; + p5 = nd + bc->e0 - 1; + speccase = 0; + if (rv->d == 0.) { /* special case: value near underflow-to-zero */ + /* threshold was rounded to zero */ + b = i2b(1); + if (b == NULL) + return -1; + p2 = Emin - P + 1; + bbits = 1; + word0(rv) = (P+2) << Exp_shift; + i = 0; + { + speccase = 1; + --p2; + dsign = 0; + goto have_i; + } + } + else + { + b = d2b(rv, &p2, &bbits); + if (b == NULL) + return -1; + } + p2 -= bc->scale; + /* floor(log2(rv)) == bbits - 1 + p2 */ + /* Check for denormal case. */ + i = P - bbits; + if (i > (j = P - Emin - 1 + p2)) { + i = j; + } + { + b = lshift(b, ++i); + if (b == NULL) + return -1; + b->x[0] |= 1; + } + have_i: + p2 -= p5 + i; + d = i2b(1); + if (d == NULL) { + Bfree(b); + return -1; + } + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + */ + if (p5 > 0) { + d = pow5mult(d, p5); + if (d == NULL) { + Bfree(b); + return -1; + } + } + else if (p5 < 0) { + b = pow5mult(b, -p5); + if (b == NULL) { + Bfree(d); + return -1; + } + } + if (p2 > 0) { + b2 = p2; + d2 = 0; + } + else { + b2 = 0; + d2 = -p2; + } + i = dshift(d, d2); + if ((b2 += i) > 0) { + b = lshift(b, b2); + if (b == NULL) { + Bfree(d); + return -1; + } + } + if ((d2 += i) > 0) { + d = lshift(d, d2); + if (d == NULL) { + Bfree(b); + return -1; + } + } + + /* Now b/d = exactly half-way between the two floating-point values */ + /* on either side of the input string. Compute first digit of b/d. */ + + if (!(dig = quorem(b,d))) { + b = multadd(b, 10, 0); /* very unlikely */ + if (b == NULL) { + Bfree(d); + return -1; + } + dig = quorem(b,d); + } + + /* Compare b/d with s0 */ + + assert(nd > 0); + dd = 9999; /* silence gcc compiler warning */ + for(i = 0; i < nd0; ) { + if ((dd = s0[i++] - '0' - dig)) + goto ret; + if (!b->x[0] && b->wds == 1) { + if (i < nd) + dd = 1; + goto ret; + } + b = multadd(b, 10, 0); + if (b == NULL) { + Bfree(d); + return -1; + } + dig = quorem(b,d); + } + for(j = bc->dp1; i++ < nd;) { + if ((dd = s0[j++] - '0' - dig)) + goto ret; + if (!b->x[0] && b->wds == 1) { + if (i < nd) + dd = 1; + goto ret; + } + b = multadd(b, 10, 0); + if (b == NULL) { + Bfree(d); + return -1; + } + dig = quorem(b,d); + } + if (b->x[0] || b->wds > 1) + dd = -1; + ret: + Bfree(b); + Bfree(d); + if (speccase) { + if (dd <= 0) + rv->d = 0.; + } + else if (dd < 0) { + if (!dsign) /* does not happen for round-near */ + retlow1: + dval(rv) -= ulp(rv); + } + else if (dd > 0) { + if (dsign) { + rethi1: + dval(rv) += ulp(rv); + } + } + else { + /* Exact half-way case: apply round-even rule. */ + if (word1(rv) & 1) { + if (dsign) + goto rethi1; + goto retlow1; + } + } + + return 0; +} + +double +_Py_dg_strtod(const char *s00, char **se) +{ + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1, error; + int esign, i, j, k, nd, nd0, nf, nz, nz0, sign; + const char *s, *s0, *s1; + double aadj, aadj1; + Long L; + U aadj2, adj, rv, rv0; + ULong y, z; + BCinfo bc; + Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; + + sign = nz0 = nz = bc.dplen = bc.uflchk = 0; + dval(&rv) = 0.; + for(s = s00;;s++) switch(*s) { + case '-': + sign = 1; + /* no break */ + case '+': + if (*++s) + goto break2; + /* no break */ + case 0: + goto ret0; + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + continue; + default: + goto break2; + } + break2: + if (*s == '0') { + nz0 = 1; + while(*++s == '0') ; + if (!*s) + goto ret; + } + s0 = s; + y = z = 0; + for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) + y = 10*y + c - '0'; + else if (nd < 16) + z = 10*z + c - '0'; + nd0 = nd; + bc.dp0 = bc.dp1 = s - s0; + if (c == '.') { + c = *++s; + bc.dp1 = s - s0; + bc.dplen = bc.dp1 - bc.dp0; + if (!nd) { + for(; c == '0'; c = *++s) + nz++; + if (c > '0' && c <= '9') { + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for(; c >= '0' && c <= '9'; c = *++s) { + have_dig: + nz++; + if (c -= '0') { + nf += nz; + for(i = 1; i < nz; i++) + if (nd++ < 9) + y *= 10; + else if (nd <= DBL_DIG + 1) + z *= 10; + if (nd++ < 9) + y = 10*y + c; + else if (nd <= DBL_DIG + 1) + z = 10*z + c; + nz = 0; + } + } + } + dig_done: + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + goto ret0; + } + s00 = s; + esign = 0; + switch(c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while(c == '0') + c = *++s; + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while((c = *++s) >= '0' && c <= '9') + L = 10*L + c - '0'; + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + e = 19999; /* safe for 16 bit ints */ + else + e = (int)L; + if (esign) + e = -e; + } + else + e = 0; + } + else + s = s00; + } + if (!nd) { + if (!nz && !nz0) { + /* Check for Nan and Infinity */ + if (!bc.dplen) + switch(c) { + case 'i': + case 'I': + if (match(&s,"nf")) { + --s; + if (!match(&s,"inity")) + ++s; + word0(&rv) = 0x7ff00000; + word1(&rv) = 0; + goto ret; + } + break; + case 'n': + case 'N': + if (match(&s, "an")) { + word0(&rv) = NAN_WORD0; + word1(&rv) = NAN_WORD1; + goto ret; + } + } + ret0: + s = s00; + sign = 0; + } + goto ret; + } + bc.e0 = e1 = e -= nf; + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) + nd0 = nd; + k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; + dval(&rv) = y; + if (k > 9) { + dval(&rv) = tens[k - 9] * dval(&rv) + z; + } + bd0 = 0; + if (nd <= DBL_DIG + && Flt_Rounds == 1 + ) { + if (!e) + goto ret; + if (e > 0) { + if (e <= Ten_pmax) { + dval(&rv) *= tens[e]; + goto ret; + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ + e -= i; + dval(&rv) *= tens[i]; + dval(&rv) *= tens[e]; + goto ret; + } + } + else if (e >= -Ten_pmax) { + dval(&rv) /= tens[-e]; + goto ret; + } + } + e1 += nd - k; + + bc.scale = 0; + + /* Get starting approximation = rv * 10**e1 */ + + if (e1 > 0) { + if ((i = e1 & 15)) + dval(&rv) *= tens[i]; + if (e1 &= ~15) { + if (e1 > DBL_MAX_10_EXP) { + ovfl: + errno = ERANGE; + /* Can't trust HUGE_VAL */ + word0(&rv) = Exp_mask; + word1(&rv) = 0; + goto ret; + } + e1 >>= 4; + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(&rv) *= bigtens[j]; + /* The last multiplication could overflow. */ + word0(&rv) -= P*Exp_msk1; + dval(&rv) *= bigtens[j]; + if ((z = word0(&rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-P)) + goto ovfl; + if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { + /* set to largest number */ + /* (Can't trust DBL_MAX) */ + word0(&rv) = Big0; + word1(&rv) = Big1; + } + else + word0(&rv) += P*Exp_msk1; + } + } + else if (e1 < 0) { + e1 = -e1; + if ((i = e1 & 15)) + dval(&rv) /= tens[i]; + if (e1 >>= 4) { + if (e1 >= 1 << n_bigtens) + goto undfl; + if (e1 & Scale_Bit) + bc.scale = 2*P; + for(j = 0; e1 > 0; j++, e1 >>= 1) + if (e1 & 1) + dval(&rv) *= tinytens[j]; + if (bc.scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask) + >> Exp_shift)) > 0) { + /* scaled rv is denormal; clear j low bits */ + if (j >= 32) { + word1(&rv) = 0; + if (j >= 53) + word0(&rv) = (P+2)*Exp_msk1; + else + word0(&rv) &= 0xffffffff << (j-32); + } + else + word1(&rv) &= 0xffffffff << j; + } + if (!dval(&rv)) { + undfl: + dval(&rv) = 0.; + errno = ERANGE; + goto ret; + } + } + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + + bc.nd = nd; + bc.nd0 = nd0; /* Only needed if nd > strtod_diglim, but done here */ + /* to silence an erroneous warning about bc.nd0 */ + /* possibly not being initialized. */ + if (nd > strtod_diglim) { + /* ASSERT(strtod_diglim >= 18); 18 == one more than the */ + /* minimum number of decimal digits to distinguish double values */ + /* in IEEE arithmetic. */ + i = j = 18; + if (i > nd0) + j += bc.dplen; + for(;;) { + if (--j <= bc.dp1 && j >= bc.dp0) + j = bc.dp0 - 1; + if (s0[j] != '0') + break; + --i; + } + e += nd - i; + nd = i; + if (nd0 > nd) + nd0 = nd; + if (nd < 9) { /* must recompute y */ + y = 0; + for(i = 0; i < nd0; ++i) + y = 10*y + s0[i] - '0'; + for(j = bc.dp1; i < nd; ++i) + y = 10*y + s0[j++] - '0'; + } + } + bd0 = s2b(s0, nd0, nd, y, bc.dplen); + if (bd0 == NULL) + goto failed_malloc; + + for(;;) { + bd = Balloc(bd0->k); + if (bd == NULL) { + Bfree(bd0); + goto failed_malloc; + } + Bcopy(bd, bd0); + bb = d2b(&rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ + if (bb == NULL) { + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } + bs = i2b(1); + if (bs == NULL) { + Bfree(bb); + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; + j = bbe - bc.scale; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j += P - Emin; + else + j = P + 1 - bbbits; + bb2 += j; + bd2 += j; + bd2 += bc.scale; + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + if (bs == NULL) { + Bfree(bb); + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } + bb1 = mult(bs, bb); + Bfree(bb); + bb = bb1; + if (bb == NULL) { + Bfree(bs); + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } + } + if (bb2 > 0) { + bb = lshift(bb, bb2); + if (bb == NULL) { + Bfree(bs); + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } + } + if (bd5 > 0) { + bd = pow5mult(bd, bd5); + if (bd == NULL) { + Bfree(bb); + Bfree(bs); + Bfree(bd0); + goto failed_malloc; + } + } + if (bd2 > 0) { + bd = lshift(bd, bd2); + if (bd == NULL) { + Bfree(bb); + Bfree(bs); + Bfree(bd0); + goto failed_malloc; + } + } + if (bs2 > 0) { + bs = lshift(bs, bs2); + if (bs == NULL) { + Bfree(bb); + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } + } + delta = diff(bb, bd); + if (delta == NULL) { + Bfree(bb); + Bfree(bs); + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } + bc.dsign = delta->sign; + delta->sign = 0; + i = cmp(delta, bs); + if (bc.nd > nd && i <= 0) { + if (bc.dsign) + break; /* Must use bigcomp(). */ + { + bc.nd = nd; + i = -1; /* Discarded digits make delta smaller. */ + } + } + + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask + || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1 + ) { + break; + } + if (!delta->x[0] && delta->wds <= 1) { + /* exact result */ + break; + } + delta = lshift(delta,Log2P); + if (delta == NULL) { + Bfree(bb); + Bfree(bs); + Bfree(bd); + Bfree(bd0); + goto failed_malloc; + } + if (cmp(delta, bs) > 0) + goto drop_down; + break; + } + if (i == 0) { + /* exactly half-way between */ + if (bc.dsign) { + if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 + && word1(&rv) == ( + (bc.scale && + (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) ? + (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : + 0xffffffff)) { + /*boundary case -- increment exponent*/ + word0(&rv) = (word0(&rv) & Exp_mask) + + Exp_msk1 + ; + word1(&rv) = 0; + bc.dsign = 0; + break; + } + } + else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { + drop_down: + /* boundary case -- decrement exponent */ + if (bc.scale) { + L = word0(&rv) & Exp_mask; + if (L <= (2*P+1)*Exp_msk1) { + if (L > (P+2)*Exp_msk1) + /* round even ==> */ + /* accept rv */ + break; + /* rv = smallest denormal */ + if (bc.nd >nd) { + bc.uflchk = 1; + break; + } + goto undfl; + } + } + L = (word0(&rv) & Exp_mask) - Exp_msk1; + word0(&rv) = L | Bndry_mask1; + word1(&rv) = 0xffffffff; + break; + } + if (!(word1(&rv) & LSB)) + break; + if (bc.dsign) + dval(&rv) += ulp(&rv); + else { + dval(&rv) -= ulp(&rv); + if (!dval(&rv)) { + if (bc.nd >nd) { + bc.uflchk = 1; + break; + } + goto undfl; + } + } + bc.dsign = 1 - bc.dsign; + break; + } + if ((aadj = ratio(delta, bs)) <= 2.) { + if (bc.dsign) + aadj = aadj1 = 1.; + else if (word1(&rv) || word0(&rv) & Bndry_mask) { + if (word1(&rv) == Tiny1 && !word0(&rv)) { + if (bc.nd >nd) { + bc.uflchk = 1; + break; + } + goto undfl; + } + aadj = 1.; + aadj1 = -1.; + } + else { + /* special case -- power of FLT_RADIX to be */ + /* rounded down... */ + + if (aadj < 2./FLT_RADIX) + aadj = 1./FLT_RADIX; + else + aadj *= 0.5; + aadj1 = -aadj; + } + } + else { + aadj *= 0.5; + aadj1 = bc.dsign ? aadj : -aadj; + if (Flt_Rounds == 0) + aadj1 += 0.5; + } + y = word0(&rv) & Exp_mask; + + /* Check for overflow */ + + if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { + dval(&rv0) = dval(&rv); + word0(&rv) -= P*Exp_msk1; + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; + if ((word0(&rv) & Exp_mask) >= + Exp_msk1*(DBL_MAX_EXP+Bias-P)) { + if (word0(&rv0) == Big0 && word1(&rv0) == Big1) + goto ovfl; + word0(&rv) = Big0; + word1(&rv) = Big1; + goto cont; + } + else + word0(&rv) += P*Exp_msk1; + } + else { + if (bc.scale && y <= 2*P*Exp_msk1) { + if (aadj <= 0x7fffffff) { + if ((z = (ULong)aadj) <= 0) + z = 1; + aadj = z; + aadj1 = bc.dsign ? aadj : -aadj; + } + dval(&aadj2) = aadj1; + word0(&aadj2) += (2*P+1)*Exp_msk1 - y; + aadj1 = dval(&aadj2); + } + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; + } + z = word0(&rv) & Exp_mask; + if (bc.nd == nd) { + if (!bc.scale) + if (y == z) { + /* Can we stop now? */ + L = (Long)aadj; + aadj -= L; + /* The tolerances below are conservative. */ + if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask) { + if (aadj < .4999999 || aadj > .5000001) + break; + } + else if (aadj < .4999999/FLT_RADIX) + break; + } + } + cont: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(delta); + } + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); + if (bc.nd > nd) { + error = bigcomp(&rv, s0, &bc); + if (error) + goto failed_malloc; + } + + if (bc.scale) { + word0(&rv0) = Exp_1 - 2*P*Exp_msk1; + word1(&rv0) = 0; + dval(&rv) *= dval(&rv0); + /* try to avoid the bug of testing an 8087 register value */ + if (!(word0(&rv) & Exp_mask)) + errno = ERANGE; + } + ret: + if (se) + *se = (char *)s; + return sign ? -dval(&rv) : dval(&rv); + + failed_malloc: + if (se) + *se = (char *)s00; + errno = ENOMEM; + return -1.0; +} + +static char * +rv_alloc(int i) +{ + int j, k, *r; + + j = sizeof(ULong); + for(k = 0; + sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= (unsigned)i; + j <<= 1) + k++; + r = (int*)Balloc(k); + if (r == NULL) + return NULL; + *r = k; + return (char *)(r+1); +} + +static char * +nrv_alloc(char *s, char **rve, int n) +{ + char *rv, *t; + + rv = rv_alloc(n); + if (rv == NULL) + return NULL; + t = rv; + while((*t = *s++)) t++; + if (rve) + *rve = t; + return rv; +} + +/* freedtoa(s) must be used to free values s returned by dtoa + * when MULTIPLE_THREADS is #defined. It should be used in all cases, + * but for consistency with earlier versions of dtoa, it is optional + * when MULTIPLE_THREADS is not defined. + */ + +void +_Py_dg_freedtoa(char *s) +{ + Bigint *b = (Bigint *)((int *)s - 1); + b->maxwds = 1 << (b->k = *(int*)b); + Bfree(b); +} + +/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. + * + * Inspired by "How to Print Floating-Point Numbers Accurately" by + * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. + * + * Modifications: + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. + */ + +/* Additional notes (METD): (1) returns NULL on failure. (2) to avoid memory + leakage, a successful call to _Py_dg_dtoa should always be matched by a + call to _Py_dg_freedtoa. */ + +char * +_Py_dg_dtoa(double dd, int mode, int ndigits, + int *decpt, int *sign, char **rve) +{ + /* Arguments ndigits, decpt, sign are similar to those + of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to 9999. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4,5 ==> similar to 2 and 3, respectively, but (in + round-nearest mode) with the tests of mode 0 to + possibly return a shorter string that rounds to d. + With IEEE arithmetic and compilation with + -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same + as modes 2 and 3 when FLT_ROUNDS != 1. + 6-9 ==> Debugging modes similar to mode - 4: don't try + fast floating-point estimate (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, + j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, + spec_case, try_quick; + Long L; + int denorm; + ULong x; + Bigint *b, *b1, *delta, *mlo, *mhi, *S; + U d2, eps, u; + double ds; + char *s, *s0; + + /* set pointers to NULL, to silence gcc compiler warnings and make + cleanup easier on error */ + mlo = mhi = b = S = 0; + s0 = 0; + + u.d = dd; + if (word0(&u) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + word0(&u) &= ~Sign_bit; /* clear sign bit */ + } + else + *sign = 0; + + /* quick return for Infinities, NaNs and zeros */ + if ((word0(&u) & Exp_mask) == Exp_mask) + { + /* Infinity or NaN */ + *decpt = 9999; + if (!word1(&u) && !(word0(&u) & 0xfffff)) + return nrv_alloc("Infinity", rve, 8); + return nrv_alloc("NaN", rve, 3); + } + if (!dval(&u)) { + *decpt = 1; + return nrv_alloc("0", rve, 1); + } + + /* compute k = floor(log10(d)). The computation may leave k + one too large, but should never leave k too small. */ + b = d2b(&u, &be, &bbits); + if (b == NULL) + goto failed_malloc; + if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) { + dval(&d2) = dval(&u); + word0(&d2) &= Frac_mask1; + word0(&d2) |= Exp_11; + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ + + i -= Bias; + denorm = 0; + } + else { + /* d is denormalized */ + + i = bbits + be + (Bias + (P-1) - 1); + x = i > 32 ? word0(&u) << (64 - i) | word1(&u) >> (i - 32) + : word1(&u) << (32 - i); + dval(&d2) = x; + word0(&d2) -= 31*Exp_msk1; /* adjust exponent */ + i -= (Bias + (P-1) - 1) + 1; + denorm = 1; + } + ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + + i*0.301029995663981; + k = (int)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; + if (k >= 0 && k <= Ten_pmax) { + if (dval(&u) < tens[k]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } + if (mode < 0 || mode > 9) + mode = 0; + + try_quick = 1; + + if (mode > 5) { + mode -= 4; + try_quick = 0; + } + leftright = 1; + ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ + /* silence erroneous "gcc -Wall" warning. */ + switch(mode) { + case 0: + case 1: + i = 18; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + s0 = rv_alloc(i); + if (s0 == NULL) + goto failed_malloc; + s = s0; + + + if (ilim >= 0 && ilim <= Quick_max && try_quick) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + dval(&d2) = dval(&u); + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + dval(&u) /= bigtens[n_bigtens-1]; + ieps++; + } + for(; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + dval(&u) /= ds; + } + else if ((j1 = -k)) { + dval(&u) *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + dval(&u) *= bigtens[i]; + } + } + if (k_check && dval(&u) < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + dval(&u) *= 10.; + ieps++; + } + dval(&eps) = ieps*dval(&u) + 7.; + word0(&eps) -= (P-1)*Exp_msk1; + if (ilim == 0) { + S = mhi = 0; + dval(&u) -= 5.; + if (dval(&u) > dval(&eps)) + goto one_digit; + if (dval(&u) < -dval(&eps)) + goto no_digits; + goto fast_failed; + } + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + dval(&eps) = 0.5/tens[ilim-1] - dval(&eps); + for(i = 0;;) { + L = (Long)dval(&u); + dval(&u) -= L; + *s++ = '0' + (int)L; + if (dval(&u) < dval(&eps)) + goto ret1; + if (1. - dval(&u) < dval(&eps)) + goto bump_up; + if (++i >= ilim) + break; + dval(&eps) *= 10.; + dval(&u) *= 10.; + } + } + else { + /* Generate ilim digits, then fix them up. */ + dval(&eps) *= tens[ilim-1]; + for(i = 1;; i++, dval(&u) *= 10.) { + L = (Long)(dval(&u)); + if (!(dval(&u) -= L)) + ilim = i; + *s++ = '0' + (int)L; + if (i == ilim) { + if (dval(&u) > 0.5 + dval(&eps)) + goto bump_up; + else if (dval(&u) < 0.5 - dval(&eps)) { + while(*--s == '0'); + s++; + goto ret1; + } + break; + } + } + } + fast_failed: + s = s0; + dval(&u) = dval(&d2); + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || dval(&u) <= 5*ds) + goto no_digits; + goto one_digit; + } + for(i = 1;; i++, dval(&u) *= 10.) { + L = (Long)(dval(&u) / ds); + dval(&u) -= L*ds; + *s++ = '0' + (int)L; + if (!dval(&u)) { + break; + } + if (i == ilim) { + dval(&u) += dval(&u); + if (dval(&u) > ds || (dval(&u) == ds && L & 1)) { + bump_up: + while(*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + break; + } + } + goto ret1; + } + + m2 = b2; + m5 = b5; + if (leftright) { + i = + denorm ? be + (Bias + (P-1) - 1 + 1) : + 1 + P - bbits; + b2 += i; + s2 += i; + mhi = i2b(1); + if (mhi == NULL) + goto failed_malloc; + } + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + if (mhi == NULL) + goto failed_malloc; + b1 = mult(mhi, b); + Bfree(b); + b = b1; + if (b == NULL) + goto failed_malloc; + } + if ((j = b5 - m5)) { + b = pow5mult(b, j); + if (b == NULL) + goto failed_malloc; + } + } + else { + b = pow5mult(b, b5); + if (b == NULL) + goto failed_malloc; + } + } + S = i2b(1); + if (S == NULL) + goto failed_malloc; + if (s5 > 0) { + S = pow5mult(S, s5); + if (S == NULL) + goto failed_malloc; + } + + /* Check for special case that d is a normalized power of 2. */ + + spec_case = 0; + if ((mode < 2 || leftright) + ) { + if (!word1(&u) && !(word0(&u) & Bndry_mask) + && word0(&u) & (Exp_mask & ~Exp_msk1) + ) { + /* The special case */ + b2 += Log2P; + s2 += Log2P; + spec_case = 1; + } + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ + if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f)) + i = 32 - i; +#define iInc 28 + i = dshift(S, s2); + b2 += i; + m2 += i; + s2 += i; + if (b2 > 0) { + b = lshift(b, b2); + if (b == NULL) + goto failed_malloc; + } + if (s2 > 0) { + S = lshift(S, s2); + if (S == NULL) + goto failed_malloc; + } + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (b == NULL) + goto failed_malloc; + if (leftright) { + mhi = multadd(mhi, 10, 0); + if (mhi == NULL) + goto failed_malloc; + } + ilim = ilim1; + } + } + if (ilim <= 0 && (mode == 3 || mode == 5)) { + if (ilim < 0) { + /* no digits, fcvt style */ + no_digits: + k = -1 - ndigits; + goto ret; + } + else { + S = multadd(S, 5, 0); + if (S == NULL) + goto failed_malloc; + if (cmp(b, S) <= 0) + goto no_digits; + } + one_digit: + *s++ = '1'; + k++; + goto ret; + } + if (leftright) { + if (m2 > 0) { + mhi = lshift(mhi, m2); + if (mhi == NULL) + goto failed_malloc; + } + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + if (mhi == NULL) + goto failed_malloc; + Bcopy(mhi, mlo); + mhi = lshift(mhi, Log2P); + if (mhi == NULL) + goto failed_malloc; + } + + for(i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi); + if (delta == NULL) + goto failed_malloc; + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); + if (j1 == 0 && mode != 1 && !(word1(&u) & 1) + ) { + if (dig == '9') + goto round_9_up; + if (j > 0) + dig++; + *s++ = dig; + goto ret; + } + if (j < 0 || (j == 0 && mode != 1 + && !(word1(&u) & 1) + )) { + if (!b->x[0] && b->wds <= 1) { + goto accept_dig; + } + if (j1 > 0) { + b = lshift(b, 1); + if (b == NULL) + goto failed_malloc; + j1 = cmp(b, S); + if ((j1 > 0 || (j1 == 0 && dig & 1)) + && dig++ == '9') + goto round_9_up; + } + accept_dig: + *s++ = dig; + goto ret; + } + if (j1 > 0) { + if (dig == '9') { /* possible if i == 1 */ + round_9_up: + *s++ = '9'; + goto roundoff; + } + *s++ = dig + 1; + goto ret; + } + *s++ = dig; + if (i == ilim) + break; + b = multadd(b, 10, 0); + if (b == NULL) + goto failed_malloc; + if (mlo == mhi) { + mlo = mhi = multadd(mhi, 10, 0); + if (mlo == NULL) + goto failed_malloc; + } + else { + mlo = multadd(mlo, 10, 0); + if (mlo == NULL) + goto failed_malloc; + mhi = multadd(mhi, 10, 0); + if (mhi == NULL) + goto failed_malloc; + } + } + } + else + for(i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (!b->x[0] && b->wds <= 1) { + goto ret; + } + if (i >= ilim) + break; + b = multadd(b, 10, 0); + if (b == NULL) + goto failed_malloc; + } + + /* Round off last digit */ + + b = lshift(b, 1); + if (b == NULL) + goto failed_malloc; + j = cmp(b, S); + if (j > 0 || (j == 0 && dig & 1)) { + roundoff: + while(*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; + } + else { + while(*--s == '0'); + s++; + } + ret: + Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } + ret1: + Bfree(b); + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; + return s0; + failed_malloc: + if (S) + Bfree(S); + if (mlo && mlo != mhi) + Bfree(mlo); + if (mhi) + Bfree(mhi); + if (b) + Bfree(b); + if (s0) + _Py_dg_freedtoa(s0); + return NULL; +} +#ifdef __cplusplus +} +#endif + +#endif /* PY_NO_SHORT_FLOAT_REPR */ Modified: python/branches/py3k/Python/pymath.c ============================================================================== --- python/branches/py3k/Python/pymath.c (original) +++ python/branches/py3k/Python/pymath.c Thu Apr 16 21:52:09 2009 @@ -13,6 +13,28 @@ } #endif +#ifdef USING_X87_FPU +# ifdef HAVE_GCC_ASM_FOR_X87 + +/* inline assembly for getting and setting the 387 FPU control word on + gcc/x86 */ + +unsigned short _Py_get_387controlword(void) { + unsigned short cw; + __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); + return cw; +} + +void _Py_set_387controlword(unsigned short cw) { + __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); +} + +# else +# error "Unable to get and set x87 control word" +# endif +#endif + + #ifndef HAVE_HYPOT double hypot(double x, double y) { Modified: python/branches/py3k/Python/sysmodule.c ============================================================================== --- python/branches/py3k/Python/sysmodule.c (original) +++ python/branches/py3k/Python/sysmodule.c Thu Apr 16 21:52:09 2009 @@ -1025,6 +1025,7 @@ executable -- pathname of this Python interpreter\n\ prefix -- prefix used to find the Python library\n\ exec_prefix -- prefix used to find the machine-specific Python library\n\ +float_repr_style -- string indicating the style of repr() output for floats\n\ " ) #ifdef MS_WINDOWS @@ -1428,6 +1429,15 @@ FlagsType.tp_init = NULL; FlagsType.tp_new = NULL; + /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */ +#ifndef PY_NO_SHORT_FLOAT_REPR + SET_SYS_FROM_STRING("float_repr_style", + PyUnicode_FromString("short")); +#else + SET_SYS_FROM_STRING("float_repr_style", + PyUnicode_FromString("legacy")); +#endif + #undef SET_SYS_FROM_STRING if (PyErr_Occurred()) return NULL; Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Thu Apr 16 21:52:09 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 71261 . +# From configure.in Revision: 71274 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.1. # @@ -21603,12 +21603,455 @@ fi -# ************************************ -# * Check for mathematical functions * -# ************************************ +# ************************************************** +# * Check for various properties of floating point * +# ************************************************** + +{ echo "$as_me:$LINENO: checking whether C doubles are little-endian IEEE 754 binary64" >&5 +echo $ECHO_N "checking whether C doubles are little-endian IEEE 754 binary64... $ECHO_C" >&6; } +if test "${ac_cv_little_endian_double+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +if test "$cross_compiling" = yes; then + ac_cv_little_endian_double=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +int main() { + double x = 9006104071832581.0; + if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0) + return 0; + else + return 1; +} + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_little_endian_double=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_little_endian_double=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi + +{ echo "$as_me:$LINENO: result: $ac_cv_little_endian_double" >&5 +echo "${ECHO_T}$ac_cv_little_endian_double" >&6; } +if test "$ac_cv_little_endian_double" = yes +then + +cat >>confdefs.h <<\_ACEOF +#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1 +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking whether C doubles are big-endian IEEE 754 binary64" >&5 +echo $ECHO_N "checking whether C doubles are big-endian IEEE 754 binary64... $ECHO_C" >&6; } +if test "${ac_cv_big_endian_double+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +if test "$cross_compiling" = yes; then + ac_cv_big_endian_double=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +int main() { + double x = 9006104071832581.0; + if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0) + return 0; + else + return 1; +} + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_big_endian_double=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_big_endian_double=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi + +{ echo "$as_me:$LINENO: result: $ac_cv_big_endian_double" >&5 +echo "${ECHO_T}$ac_cv_big_endian_double" >&6; } +if test "$ac_cv_big_endian_double" = yes +then + +cat >>confdefs.h <<\_ACEOF +#define DOUBLE_IS_BIG_ENDIAN_IEEE754 1 +_ACEOF + +fi + +# Some ARM platforms use a mixed-endian representation for doubles. +# While Python doesn't currently have full support for these platforms +# (see e.g., issue 1762561), we can at least make sure that float <-> string +# conversions work. +{ echo "$as_me:$LINENO: checking whether C doubles are ARM mixed-endian IEEE 754 binary64" >&5 +echo $ECHO_N "checking whether C doubles are ARM mixed-endian IEEE 754 binary64... $ECHO_C" >&6; } +if test "${ac_cv_mixed_endian_double+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +if test "$cross_compiling" = yes; then + ac_cv_mixed_endian_double=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +int main() { + double x = 9006104071832581.0; + if (memcmp(&x, "\x01\xff\x3f\x43\x05\x04\x03\x02", 8) == 0) + return 0; + else + return 1; +} + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_mixed_endian_double=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_mixed_endian_double=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi -LIBS_SAVE=$LIBS -LIBS="$LIBS $LIBM" + +fi + +{ echo "$as_me:$LINENO: result: $ac_cv_mixed_endian_double" >&5 +echo "${ECHO_T}$ac_cv_mixed_endian_double" >&6; } +if test "$ac_cv_mixed_endian_double" = yes +then + +cat >>confdefs.h <<\_ACEOF +#define DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 1 +_ACEOF + +fi + +# David Gay's code in Python/dtoa.c requires that the FPU uses 53-bit +# rounding; this is a particular problem on x86, where the x87 FPU has +# a default rounding precision of 64 bits. For gcc/x86, we try to fix +# this by: +# +# (1) using the SSE2 instruction set when available (it usually is +# on modern machines) +# (2) using inline assembler to get and set the x87 FPU control word +# otherwise. +# +# On AMD64 (aka x86-64), gcc automatically enables use of SSE2 +# instructions, so we don't bother trying to detect. + +if test "$GCC" = yes && test -n "`$CC -dM -E - &5 +echo $ECHO_N "checking whether SSE2 instructions are already enabled for math... $ECHO_C" >&6; } + if test -n "`$CC -dM -E - &5 +echo "${ECHO_T}$ac_sse2_enabled" >&6; } + + # if we're not using SSE2 already, we need to either enable it + # (when available), or use inline assembler to get and set the + # 387 control word. + if test $ac_sse2_enabled = no + then + # Check cpuid for SSE2 availability. Bits 25 and 26 of edx tell + # us about SSE and SSE2 respectively. + { echo "$as_me:$LINENO: checking whether SSE2 instructions are available on this CPU" >&5 +echo $ECHO_N "checking whether SSE2 instructions are available on this CPU... $ECHO_C" >&6; } + if test "$cross_compiling" = yes; then + ac_cv_cpu_has_sse2=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + int main() { + unsigned int ax, bx, cx, dx, func; + func = 1U; + __asm__ __volatile__ ( + "pushl %%ebx\n\t" /* don't clobber ebx */ + "cpuid\n\t" + "movl %%ebx, %1\n\t" + "popl %%ebx" + : "=a" (ax), "=r" (bx), "=c" (cx), "=d" (dx) + : "a" (func) + : "cc" ); + if ((dx & (1U << 25)) && (dx & (1U << 26))) + return 0; + else + return 1; + } + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_cpu_has_sse2=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_cpu_has_sse2=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + { echo "$as_me:$LINENO: result: $ac_cv_cpu_has_sse2" >&5 +echo "${ECHO_T}$ac_cv_cpu_has_sse2" >&6; } + + # determine whether gcc accepts options to turn on SSE2 + { echo "$as_me:$LINENO: checking whether $CC accepts -msse2 -mfpmath=sse" >&5 +echo $ECHO_N "checking whether $CC accepts -msse2 -mfpmath=sse... $ECHO_C" >&6; } + ac_save_cc="$CC" + CC="$CC -msse2 -mfpmath=sse" + if test "$cross_compiling" = yes; then + ac_cv_msse2_ok=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +int main() { return 0; } +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_msse2_ok=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_msse2_ok=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + CC="$ac_save_cc" + { echo "$as_me:$LINENO: result: $ac_cv_msse2_ok" >&5 +echo "${ECHO_T}$ac_cv_msse2_ok" >&6; } + + if test $ac_cv_cpu_has_sse2 = yes && test $ac_cv_msse2_ok = yes + then + BASECFLAGS="$BASECFLAGS -msse2 -mfpmath=sse" + else + # SSE2 doesn't appear to be available. Check that it's okay + # to use gcc inline assembler to get and set x87 control word + +cat >>confdefs.h <<\_ACEOF +#define USING_X87_FPU 1 +_ACEOF + + { echo "$as_me:$LINENO: checking whether we can use gcc inline assembler to get and set x87 control word" >&5 +echo $ECHO_N "checking whether we can use gcc inline assembler to get and set x87 control word... $ECHO_C" >&6; } + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + unsigned short cw; + __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); + __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + have_gcc_asm_for_x87=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + have_gcc_asm_for_x87=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { echo "$as_me:$LINENO: result: $have_gcc_asm_for_x87" >&5 +echo "${ECHO_T}$have_gcc_asm_for_x87" >&6; } + if test "$have_gcc_asm_for_x87" = yes + then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_GCC_ASM_FOR_X87 1 +_ACEOF + + fi + fi + fi +fi # Detect whether system arithmetic is subject to x87-style double # rounding issues. The result of this test has little meaning on non @@ -21617,10 +22060,9 @@ # 0 otherwise. See http://bugs.python.org/issue2937 for more info. { echo "$as_me:$LINENO: checking for x87-style double rounding" >&5 echo $ECHO_N "checking for x87-style double rounding... $ECHO_C" >&6; } -if test "${ac_cv_x87_double_rounding+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - +# $BASECFLAGS may affect the result +ac_save_cc="$CC" +CC="$CC $BASECFLAGS" if test "$cross_compiling" = yes; then ac_cv_x87_double_rounding=no else @@ -21684,8 +22126,7 @@ fi -fi - +CC="$ac_save_cc" { echo "$as_me:$LINENO: result: $ac_cv_x87_double_rounding" >&5 echo "${ECHO_T}$ac_cv_x87_double_rounding" >&6; } if test "$ac_cv_x87_double_rounding" = yes @@ -21697,6 +22138,13 @@ fi +# ************************************ +# * Check for mathematical functions * +# ************************************ + +LIBS_SAVE=$LIBS +LIBS="$LIBS $LIBM" + # Multiprocessing check for broken sem_getvalue { echo "$as_me:$LINENO: checking for broken sem_getvalue" >&5 echo $ECHO_N "checking for broken sem_getvalue... $ECHO_C" >&6; } Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Thu Apr 16 21:52:09 2009 @@ -3065,12 +3065,176 @@ fi], [AC_MSG_RESULT(default LIBC="$LIBC")]) -# ************************************ -# * Check for mathematical functions * -# ************************************ +# ************************************************** +# * Check for various properties of floating point * +# ************************************************** -LIBS_SAVE=$LIBS -LIBS="$LIBS $LIBM" +AC_MSG_CHECKING(whether C doubles are little-endian IEEE 754 binary64) +AC_CACHE_VAL(ac_cv_little_endian_double, [ +AC_TRY_RUN([ +#include +int main() { + double x = 9006104071832581.0; + if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0) + return 0; + else + return 1; +} +], +ac_cv_little_endian_double=yes, +ac_cv_little_endian_double=no, +ac_cv_little_endian_double=no)]) +AC_MSG_RESULT($ac_cv_little_endian_double) +if test "$ac_cv_little_endian_double" = yes +then + AC_DEFINE(DOUBLE_IS_LITTLE_ENDIAN_IEEE754, 1, + [Define if C doubles are 64-bit IEEE 754 binary format, stored + with the least significant byte first]) +fi + +AC_MSG_CHECKING(whether C doubles are big-endian IEEE 754 binary64) +AC_CACHE_VAL(ac_cv_big_endian_double, [ +AC_TRY_RUN([ +#include +int main() { + double x = 9006104071832581.0; + if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0) + return 0; + else + return 1; +} +], +ac_cv_big_endian_double=yes, +ac_cv_big_endian_double=no, +ac_cv_big_endian_double=no)]) +AC_MSG_RESULT($ac_cv_big_endian_double) +if test "$ac_cv_big_endian_double" = yes +then + AC_DEFINE(DOUBLE_IS_BIG_ENDIAN_IEEE754, 1, + [Define if C doubles are 64-bit IEEE 754 binary format, stored + with the most significant byte first]) +fi + +# Some ARM platforms use a mixed-endian representation for doubles. +# While Python doesn't currently have full support for these platforms +# (see e.g., issue 1762561), we can at least make sure that float <-> string +# conversions work. +AC_MSG_CHECKING(whether C doubles are ARM mixed-endian IEEE 754 binary64) +AC_CACHE_VAL(ac_cv_mixed_endian_double, [ +AC_TRY_RUN([ +#include +int main() { + double x = 9006104071832581.0; + if (memcmp(&x, "\x01\xff\x3f\x43\x05\x04\x03\x02", 8) == 0) + return 0; + else + return 1; +} +], +ac_cv_mixed_endian_double=yes, +ac_cv_mixed_endian_double=no, +ac_cv_mixed_endian_double=no)]) +AC_MSG_RESULT($ac_cv_mixed_endian_double) +if test "$ac_cv_mixed_endian_double" = yes +then + AC_DEFINE(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754, 1, + [Define if C doubles are 64-bit IEEE 754 binary format, stored + in ARM mixed-endian order (byte order 45670123)]) +fi + +# David Gay's code in Python/dtoa.c requires that the FPU uses 53-bit +# rounding; this is a particular problem on x86, where the x87 FPU has +# a default rounding precision of 64 bits. For gcc/x86, we try to fix +# this by: +# +# (1) using the SSE2 instruction set when available (it usually is +# on modern machines) +# (2) using inline assembler to get and set the x87 FPU control word +# otherwise. +# +# On AMD64 (aka x86-64), gcc automatically enables use of SSE2 +# instructions, so we don't bother trying to detect. + +if test "$GCC" = yes && test -n "`$CC -dM -E - #include @@ -3101,7 +3267,8 @@ ], ac_cv_x87_double_rounding=no, ac_cv_x87_double_rounding=yes, -ac_cv_x87_double_rounding=no)]) +ac_cv_x87_double_rounding=no) +CC="$ac_save_cc" AC_MSG_RESULT($ac_cv_x87_double_rounding) if test "$ac_cv_x87_double_rounding" = yes then @@ -3109,6 +3276,13 @@ [Define if arithmetic is subject to x87-style double rounding issue]) fi +# ************************************ +# * Check for mathematical functions * +# ************************************ + +LIBS_SAVE=$LIBS +LIBS="$LIBS $LIBM" + # Multiprocessing check for broken sem_getvalue AC_MSG_CHECKING(for broken sem_getvalue) AC_TRY_RUN([ Modified: python/branches/py3k/pyconfig.h.in ============================================================================== --- python/branches/py3k/pyconfig.h.in (original) +++ python/branches/py3k/pyconfig.h.in Thu Apr 16 21:52:09 2009 @@ -15,6 +15,18 @@ /* Define if you have the Mach cthreads package */ #undef C_THREADS +/* Define if C doubles are 64-bit IEEE 754 binary format, stored in ARM + mixed-endian order (byte order 45670123) */ +#undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 + +/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the most + significant byte first */ +#undef DOUBLE_IS_BIG_ENDIAN_IEEE754 + +/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the + least significant byte first */ +#undef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 + /* Define if --enable-ipv6 is specified */ #undef ENABLE_IPV6 @@ -232,6 +244,10 @@ /* Define to 1 if you have the `gai_strerror' function. */ #undef HAVE_GAI_STRERROR +/* Define if we can use gcc inline assembler to get and set x87 control word + */ +#undef HAVE_GCC_ASM_FOR_X87 + /* Define if you have the getaddrinfo function. */ #undef HAVE_GETADDRINFO @@ -970,6 +986,10 @@ /* Define if you want to use computed gotos in ceval.c. */ #undef USE_COMPUTED_GOTOS +/* Define on x86 hardware if the x87 FPU is being used for floating-point + arithmetic */ +#undef USING_X87_FPU + /* Define if a va_list is an array of some kind */ #undef VA_LIST_IS_ARRAY From python-checkins at python.org Thu Apr 16 22:06:09 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 16 Apr 2009 22:06:09 +0200 (CEST) Subject: [Python-checkins] r71664 - python/branches/release30-maint Message-ID: <20090416200609.917E91E413F@bag.python.org> Author: mark.dickinson Date: Thu Apr 16 22:06:09 2009 New Revision: 71664 Log: Blocked revisions 71663 via svnmerge ........ r71663 | mark.dickinson | 2009-04-16 20:52:09 +0100 (Thu, 16 Apr 2009) | 15 lines Issue #1580: use short float repr where possible. - incorporate and adapt David Gay's dtoa and strtod into the Python core - on platforms where we can use Gay's code (almost all!), repr(float) is based on the shortest sequence of decimal digits that rounds correctly. - add sys.float_repr_style attribute to indicate whether we're using Gay's code or not - add autoconf magic to detect and enable SSE2 instructions on x86/gcc - slight change to repr and str: repr switches to exponential notation at 1e16 instead of 1e17, str switches at 1e11 instead of 1e12 ........ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Thu Apr 16 22:16:11 2009 From: python-checkins at python.org (eric.smith) Date: Thu, 16 Apr 2009 22:16:11 +0200 (CEST) Subject: [Python-checkins] r71665 - in python/branches/py3k: Include/bytesobject.h Include/pystrtod.h Include/unicodeobject.h Lib/test/test_float.py Lib/test/test_format.py Lib/test/test_types.py Misc/NEWS Modules/_pickle.c Objects/bytesobject.c Objects/complexobject.c Objects/floatobject.c Objects/stringlib/formatter.h Objects/stringlib/localeutil.h Objects/unicodeobject.c Python/marshal.c Python/pystrtod.c Message-ID: <20090416201611.3B3481E40AB@bag.python.org> Author: eric.smith Date: Thu Apr 16 22:16:10 2009 New Revision: 71665 Log: The other half of Issue #1580: use short float repr where possible. Addresses the float -> string conversion, using David Gay's code which was added in Mark Dickinson's checkin r71663. Also addresses these, which are intertwined with the short repr changes: - Issue #5772: format(1e100, '<') produces '1e+100', not '1.0e+100' - Issue #5515: 'n' formatting with commas no longer works poorly with leading zeros. - PEP 378 Format Specifier for Thousands Separator: implemented for floats. Modified: python/branches/py3k/Include/bytesobject.h python/branches/py3k/Include/pystrtod.h python/branches/py3k/Include/unicodeobject.h python/branches/py3k/Lib/test/test_float.py python/branches/py3k/Lib/test/test_format.py python/branches/py3k/Lib/test/test_types.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_pickle.c python/branches/py3k/Objects/bytesobject.c python/branches/py3k/Objects/complexobject.c python/branches/py3k/Objects/floatobject.c python/branches/py3k/Objects/stringlib/formatter.h python/branches/py3k/Objects/stringlib/localeutil.h python/branches/py3k/Objects/unicodeobject.c python/branches/py3k/Python/marshal.c python/branches/py3k/Python/pystrtod.c Modified: python/branches/py3k/Include/bytesobject.h ============================================================================== --- python/branches/py3k/Include/bytesobject.h (original) +++ python/branches/py3k/Include/bytesobject.h Thu Apr 16 22:16:10 2009 @@ -91,24 +91,22 @@ into the string pointed to by buffer. For the argument descriptions, see Objects/stringlib/localeutil.h */ -PyAPI_FUNC(int) _PyBytes_InsertThousandsGroupingLocale(char *buffer, - Py_ssize_t n_buffer, - Py_ssize_t n_digits, - Py_ssize_t buf_size, - Py_ssize_t *count, - int append_zero_char); +PyAPI_FUNC(Py_ssize_t) _PyBytes_InsertThousandsGroupingLocale(char *buffer, + Py_ssize_t n_buffer, + char *digits, + Py_ssize_t n_digits, + Py_ssize_t min_width); /* 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 */ -PyAPI_FUNC(int) _PyBytes_InsertThousandsGrouping(char *buffer, - Py_ssize_t n_buffer, - Py_ssize_t n_digits, - Py_ssize_t buf_size, - Py_ssize_t *count, - int append_zero_char, - const char *grouping, - const char *thousands_sep); +PyAPI_FUNC(Py_ssize_t) _PyBytes_InsertThousandsGrouping(char *buffer, + Py_ssize_t n_buffer, + char *digits, + Py_ssize_t n_digits, + Py_ssize_t min_width, + const char *grouping, + const char *thousands_sep); /* Flags used by string formatting */ #define F_LJUST (1<<0) Modified: python/branches/py3k/Include/pystrtod.h ============================================================================== --- python/branches/py3k/Include/pystrtod.h (original) +++ python/branches/py3k/Include/pystrtod.h Thu Apr 16 22:16:10 2009 @@ -10,6 +10,25 @@ PyAPI_FUNC(double) PyOS_ascii_atof(const char *str); PyAPI_FUNC(char *) PyOS_ascii_formatd(char *buffer, size_t buf_len, const char *format, double d); +/* The caller is responsible for calling PyMem_Free to free the buffer + that's is returned. */ +PyAPI_FUNC(char *) PyOS_double_to_string(double val, + char format_code, + int precision, + int flags, + int *type); + + +/* PyOS_double_to_string's "flags" parameter can be set to 0 or more of: */ +#define Py_DTSF_SIGN 0x01 /* always add the sign */ +#define Py_DTSF_ADD_DOT_0 0x02 /* if the result is an integer add ".0" */ +#define Py_DTSF_ALT 0x04 /* "alternate" formatting. it's format_code + specific */ + +/* PyOS_double_to_string's "type", if non-NULL, will be set to one of: */ +#define Py_DTST_FINITE 0 +#define Py_DTST_INFINITE 1 +#define Py_DTST_NAN 2 #ifdef __cplusplus } Modified: python/branches/py3k/Include/unicodeobject.h ============================================================================== --- python/branches/py3k/Include/unicodeobject.h (original) +++ python/branches/py3k/Include/unicodeobject.h Thu Apr 16 22:16:10 2009 @@ -1482,24 +1482,22 @@ into the string pointed to by buffer. For the argument descriptions, see Objects/stringlib/localeutil.h */ -PyAPI_FUNC(int) _PyUnicode_InsertThousandsGroupingLocale(Py_UNICODE *buffer, - Py_ssize_t n_buffer, - Py_ssize_t n_digits, - Py_ssize_t buf_size, - Py_ssize_t *count, - int append_zero_char); +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); /* 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 */ -PyAPI_FUNC(int) _PyUnicode_InsertThousandsGrouping(Py_UNICODE *buffer, - Py_ssize_t n_buffer, - Py_ssize_t n_digits, - Py_ssize_t buf_size, - Py_ssize_t *count, - int append_zero_char, - const char *grouping, - const char *thousands_sep); +PyAPI_FUNC(Py_ssize_t) _PyUnicode_InsertThousandsGrouping(Py_UNICODE *buffer, + Py_ssize_t n_buffer, + Py_UNICODE *digits, + Py_ssize_t n_digits, + Py_ssize_t min_width, + const char *grouping, + const char *thousands_sep); /* === Characters Type APIs =============================================== */ /* Helper array used by Py_UNICODE_ISSPACE(). */ 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 Thu Apr 16 22:16:10 2009 @@ -1,6 +1,7 @@ import unittest, struct import os +import sys from test import support import math from math import isinf, isnan, copysign, ldexp @@ -10,6 +11,10 @@ INF = float("inf") NAN = float("nan") +#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') + class GeneralFloatCases(unittest.TestCase): def test_float(self): @@ -24,6 +29,10 @@ self.assertRaises(ValueError, float, "+-3.14") self.assertRaises(ValueError, float, "-+3.14") self.assertRaises(ValueError, float, "--3.14") + self.assertRaises(ValueError, float, ".nan") + self.assertRaises(ValueError, float, "+.inf") + self.assertRaises(ValueError, float, ".") + self.assertRaises(ValueError, float, "-.") self.assertEqual(float(b" \u0663.\u0661\u0664 ".decode('raw-unicode-escape')), 3.14) @support.run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE') @@ -316,6 +325,73 @@ self.assertEqual(v, eval(repr(v))) floats_file.close() +class FormatTestCase(unittest.TestCase): + @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + def test_format_testfile(self): + for line in open(format_testfile): + if line.startswith('--'): + continue + line = line.strip() + if not line: + continue + + lhs, rhs = map(str.strip, line.split('->')) + fmt, arg = lhs.split() + self.assertEqual(fmt % float(arg), rhs) + self.assertEqual(fmt % -float(arg), '-' + rhs) + + @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short', + "applies only when using short float repr style") + def test_short_repr(self): + # test short float repr introduced in Python 3.1. One aspect + # of this repr is that we get some degree of str -> float -> + # str roundtripping. In particular, for any numeric string + # containing 15 or fewer significant digits, those exact same + # digits (modulo trailing zeros) should appear in the output. + # No more repr(0.03) -> "0.029999999999999999"! + + test_strings = [ + # output always includes *either* a decimal point and at + # least one digit after that point, or an exponent. + '0.0', + '1.0', + '0.01', + '0.02', + '0.03', + '0.04', + '0.05', + '1.23456789', + '10.0', + '100.0', + # values >= 1e16 get an exponent... + '1000000000000000.0', + '9999999999999990.0', + '1e+16', + '1e+17', + # ... and so do values < 1e-4 + '0.001', + '0.001001', + '0.00010000000000001', + '0.0001', + '9.999999999999e-05', + '1e-05', + # values designed to provoke failure if the FPU rounding + # precision isn't set correctly + '8.72293771110361e+25', + '7.47005307342313e+26', + '2.86438000439698e+28', + '8.89142905246179e+28', + '3.08578087079232e+35', + ] + + for s in test_strings: + negs = '-'+s + self.assertEqual(s, repr(float(s))) + self.assertEqual(negs, repr(float(negs))) + + + # Beginning with Python 2.6 float has cross platform compatible # ways to create and represent inf and nan class InfNanTest(unittest.TestCase): Modified: python/branches/py3k/Lib/test/test_format.py ============================================================================== --- python/branches/py3k/Lib/test/test_format.py (original) +++ python/branches/py3k/Lib/test/test_format.py Thu Apr 16 22:16:10 2009 @@ -220,6 +220,11 @@ testformat("%a", "\u0378", "'\\u0378'") # non printable testformat("%r", "\u0374", "'\u0374'") # printable testformat("%a", "\u0374", "'\\u0374'") # printable + + # alternate float formatting + testformat('%g', 1.1, '1.1') + testformat('%#g', 1.1, '1.10000') + # Test exception for unknown format characters if verbose: print('Testing exceptions') Modified: python/branches/py3k/Lib/test/test_types.py ============================================================================== --- python/branches/py3k/Lib/test/test_types.py (original) +++ python/branches/py3k/Lib/test/test_types.py Thu Apr 16 22:16:10 2009 @@ -113,6 +113,9 @@ self.assertEqual(1.5e-101.__format__('e'), '1.500000e-101') self.assertEqual('%e' % 1.5e-101, '1.500000e-101') + self.assertEqual('%g' % 1.0, '1') + self.assertEqual('%#g' % 1.0, '1.00000') + def test_normal_integers(self): # Ensure the first 256 integers are shared a = 256 @@ -358,6 +361,8 @@ self.assertRaises(TypeError, 3 .__format__, 0) # can't have ',' with 'n' self.assertRaises(ValueError, 3 .__format__, ",n") + # can't have ',' with 'c' + self.assertRaises(ValueError, 3 .__format__, ",c") # ensure that only int and float type specifiers work for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] + @@ -547,10 +552,34 @@ # a totaly empty format specifier means something else. # So, just use a sign flag test(1e200, '+g', '+1e+200') - test(1e200, '+', '+1.0e+200') + test(1e200, '+', '+1e+200') + test(1.1e200, '+g', '+1.1e+200') test(1.1e200, '+', '+1.1e+200') + # 0 padding + test(1234., '010f', '1234.000000') + test(1234., '011f', '1234.000000') + test(1234., '012f', '01234.000000') + test(-1234., '011f', '-1234.000000') + test(-1234., '012f', '-1234.000000') + test(-1234., '013f', '-01234.000000') + test(-1234.12341234, '013f', '-01234.123412') + test(-123456.12341234, '011.2f', '-0123456.12') + + # 0 padding with commas + test(1234., '011,f', '1,234.000000') + test(1234., '012,f', '1,234.000000') + test(1234., '013,f', '01,234.000000') + test(-1234., '012,f', '-1,234.000000') + test(-1234., '013,f', '-1,234.000000') + test(-1234., '014,f', '-01,234.000000') + test(-12345., '015,f', '-012,345.000000') + test(-123456., '016,f', '-0,123,456.000000') + test(-123456., '017,f', '-0,123,456.000000') + test(-123456.12341234, '017,f', '-0,123,456.123412') + test(-123456.12341234, '013,.2f', '-0,123,456.12') + # % formatting test(-1.0, '%', '-100.000000%') @@ -575,6 +604,24 @@ self.assertRaises(ValueError, format, 0.0, '#') self.assertRaises(ValueError, format, 0.0, '#20f') + def test_format_spec_errors(self): + # int, float, and string all share the same format spec + # mini-language parser. + + # Check that we can't ask for too many digits. This is + # probably a CPython specific test. It tries to put the width + # into a C long. + self.assertRaises(ValueError, format, 0, '1'*10000 + 'd') + + # Similar with the precision. + self.assertRaises(ValueError, format, 0, '.' + '1'*10000 + 'd') + + # And may as well test both. + self.assertRaises(ValueError, format, 0, '1'*1000 + '.' + '1'*10000 + 'd') + + # Make sure commas aren't allowed with various type codes + for code in 'xXobns': + self.assertRaises(ValueError, format, 0, ',' + code) def test_main(): run_unittest(TypesTests) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Apr 16 22:16:10 2009 @@ -12,6 +12,15 @@ Core and Builtins ----------------- +- Issue #5772: format(1e100, '<') produces '1e+100', not '1.0e+100'. + +- Issue #5515: str.format() presentation type 'n' with commas no + longer works poorly with leading zeros when formatting ints and + floats. + +- Implement PEP 378, Format Specifier for Thousands Separator, for + floats. + - The repr function switches to exponential notation at 1e16, not 1e17 as it did before. This change applies to both 'short' and legacy float repr styles. For the new repr style, it avoids misleading Modified: python/branches/py3k/Modules/_pickle.c ============================================================================== --- python/branches/py3k/Modules/_pickle.c (original) +++ python/branches/py3k/Modules/_pickle.c Thu Apr 16 22:16:10 2009 @@ -1016,16 +1016,31 @@ return -1; if (pickler_write(self, pdata, 9) < 0) return -1; - } + } else { - char pdata[250]; - pdata[0] = FLOAT; - PyOS_ascii_formatd(pdata + 1, sizeof(pdata) - 2, "%.17g", x); - /* Extend the formatted string with a newline character */ - strcat(pdata, "\n"); + int result = -1; + char *buf = NULL; + char op = FLOAT; - if (pickler_write(self, pdata, strlen(pdata)) < 0) - return -1; + if (pickler_write(self, &op, 1) < 0) + goto done; + + buf = PyOS_double_to_string(x, 'r', 0, 0, NULL); + if (!buf) { + PyErr_NoMemory(); + goto done; + } + + if (pickler_write(self, buf, strlen(buf)) < 0) + goto done; + + if (pickler_write(self, "\n", 1) < 0) + goto done; + + result = 0; +done: + PyMem_Free(buf); + return result; } return 0; Modified: python/branches/py3k/Objects/bytesobject.c ============================================================================== --- python/branches/py3k/Objects/bytesobject.c (original) +++ python/branches/py3k/Objects/bytesobject.c Thu Apr 16 22:16:10 2009 @@ -562,6 +562,7 @@ /* -------------------------------------------------------------------- */ /* Methods */ +#include "stringlib/stringdefs.h" #define STRINGLIB_CHAR char #define STRINGLIB_CMP memcmp Modified: python/branches/py3k/Objects/complexobject.c ============================================================================== --- python/branches/py3k/Objects/complexobject.c (original) +++ python/branches/py3k/Objects/complexobject.c Thu Apr 16 22:16:10 2009 @@ -14,22 +14,6 @@ #ifndef WITHOUT_COMPLEX -/* Precisions used by repr() and str(), respectively. - - The repr() precision (17 significant decimal digits) is the minimal number - that is guaranteed to have enough precision so that if the number is read - back in the exact same binary value is recreated. This is true for IEEE - floating point by design, and also happens to work for all other modern - hardware. - - The str() precision is chosen so that in most cases, the rounding noise - created by various operations is suppressed, while giving plenty of - precision for practical use. -*/ - -#define PREC_REPR 17 -#define PREC_STR 12 - /* elementary operations on complex numbers */ static Py_complex c_1 = {1., 0.}; @@ -345,71 +329,114 @@ } -static void -complex_to_buf(char *buf, int bufsz, PyComplexObject *v, int precision) +static PyObject * +complex_format(PyComplexObject *v, char format_code) { - char format[32]; - if (v->cval.real == 0.) { - if (!Py_IS_FINITE(v->cval.imag)) { - if (Py_IS_NAN(v->cval.imag)) - strncpy(buf, "nan*j", 6); - else if (copysign(1, v->cval.imag) == 1) - strncpy(buf, "inf*j", 6); - else - strncpy(buf, "-inf*j", 7); - } - else { - PyOS_snprintf(format, sizeof(format), "%%.%ig", precision); - PyOS_ascii_formatd(buf, bufsz - 1, format, v->cval.imag); - strncat(buf, "j", 1); - } - } else { - char re[64], im[64]; - /* Format imaginary part with sign, real part without */ - if (!Py_IS_FINITE(v->cval.real)) { - if (Py_IS_NAN(v->cval.real)) - strncpy(re, "nan", 4); - /* else if (copysign(1, v->cval.real) == 1) */ - else if (v->cval.real > 0) - strncpy(re, "inf", 4); - else - strncpy(re, "-inf", 5); - } - else { - PyOS_snprintf(format, sizeof(format), "%%.%ig", precision); - PyOS_ascii_formatd(re, sizeof(re), format, v->cval.real); - } - if (!Py_IS_FINITE(v->cval.imag)) { - if (Py_IS_NAN(v->cval.imag)) - strncpy(im, "+nan*", 6); - /* else if (copysign(1, v->cval.imag) == 1) */ - else if (v->cval.imag > 0) - strncpy(im, "+inf*", 6); - else - strncpy(im, "-inf*", 6); - } - else { - PyOS_snprintf(format, sizeof(format), "%%+.%ig", precision); - PyOS_ascii_formatd(im, sizeof(im), format, v->cval.imag); - } - PyOS_snprintf(buf, bufsz, "(%s%sj)", re, im); - } + PyObject *result = NULL; + Py_ssize_t len; + + /* If these are non-NULL, they'll need to be freed. */ + char *pre = NULL; + char *pim = NULL; + char *buf = NULL; + + /* These do not need to be freed. They're either aliases for pim + and pre, or pointers to constants. */ + char *re = NULL; + char *im = NULL; + char *lead = ""; + char *tail = ""; + + + if (v->cval.real == 0.) { + re = ""; + if (!Py_IS_FINITE(v->cval.imag)) { + if (Py_IS_NAN(v->cval.imag)) + im = "nan*"; + else if (copysign(1, v->cval.imag) == 1) + im = "inf*"; + else + im = "-inf*"; + } + else { + pim = PyOS_double_to_string(v->cval.imag, format_code, + 0, 0, NULL); + if (!pim) { + PyErr_NoMemory(); + goto done; + } + im = pim; + } + } else { + /* Format imaginary part with sign, real part without */ + if (!Py_IS_FINITE(v->cval.real)) { + if (Py_IS_NAN(v->cval.real)) + re = "nan"; + /* else if (copysign(1, v->cval.real) == 1) */ + else if (v->cval.real > 0) + re = "inf"; + else + re = "-inf"; + } + else { + pre = PyOS_double_to_string(v->cval.real, format_code, + 0, 0, NULL); + if (!pre) { + PyErr_NoMemory(); + goto done; + } + re = pre; + } + + if (!Py_IS_FINITE(v->cval.imag)) { + if (Py_IS_NAN(v->cval.imag)) + im = "+nan*"; + /* else if (copysign(1, v->cval.imag) == 1) */ + else if (v->cval.imag > 0) + im = "+inf*"; + else + im = "-inf*"; + } + else { + pim = PyOS_double_to_string(v->cval.imag, format_code, + 0, Py_DTSF_SIGN, NULL); + if (!pim) { + PyErr_NoMemory(); + goto done; + } + im = pim; + } + lead = "("; + tail = ")"; + } + /* Alloc the final buffer. Add one for the "j" in the format string, and + one for the trailing zero. */ + len = strlen(lead) + strlen(re) + strlen(im) + strlen(tail) + 2; + buf = PyMem_Malloc(len); + if (!buf) { + PyErr_NoMemory(); + goto done; + } + PyOS_snprintf(buf, len, "%s%s%sj%s", lead, re, im, tail); + result = PyUnicode_FromString(buf); +done: + PyMem_Free(pim); + PyMem_Free(pre); + PyMem_Free(buf); + + return result; } static PyObject * complex_repr(PyComplexObject *v) { - char buf[100]; - complex_to_buf(buf, sizeof(buf), v, PREC_REPR); - return PyUnicode_FromString(buf); + return complex_format(v, 'r'); } static PyObject * complex_str(PyComplexObject *v) { - char buf[100]; - complex_to_buf(buf, sizeof(buf), v, PREC_STR); - return PyUnicode_FromString(buf); + return complex_format(v, 's'); } static long Modified: python/branches/py3k/Objects/floatobject.c ============================================================================== --- python/branches/py3k/Objects/floatobject.c (original) +++ python/branches/py3k/Objects/floatobject.c Thu Apr 16 22:16:10 2009 @@ -197,8 +197,7 @@ sp = s; /* We don't care about overflow or underflow. If the platform supports * them, infinities and signed zeroes (on underflow) are fine. - * However, strtod can return 0 for denormalized numbers, where atof - * does not. So (alas!) we special-case a zero result. Note that + * However, strtod can return 0 for denormalized numbers. Note that * whether strtod sets errno on underflow is not defined, so we can't * key off errno. */ @@ -259,14 +258,6 @@ "null byte in argument for float()"); goto error; } - if (x == 0.0) { - /* See above -- may have been strtod being anal - about denorms. */ - PyFPE_START_PROTECT("atof", goto error) - x = PyOS_ascii_atof(s); - PyFPE_END_PROTECT(x) - errno = 0; /* whether atof ever set errno is undefined */ - } result = PyFloat_FromDouble(x); error: if (s_buffer) @@ -320,72 +311,6 @@ return val; } -/* Methods */ - -static void -format_double(char *buf, size_t buflen, double ob_fval, int precision) -{ - register char *cp; - char format[32]; - int i; - - /* Subroutine for float_repr, float_str and float_print. - We want float numbers to be recognizable as such, - i.e., they should contain a decimal point or an exponent. - However, %g may print the number as an integer; - in such cases, we append ".0" to the string. */ - - PyOS_snprintf(format, 32, "%%.%ig", precision); - PyOS_ascii_formatd(buf, buflen, format, ob_fval); - cp = buf; - if (*cp == '-') - cp++; - for (; *cp != '\0'; cp++) { - /* Any non-digit means it's not an integer; - this takes care of NAN and INF as well. */ - if (!isdigit(Py_CHARMASK(*cp))) - break; - } - if (*cp == '\0') { - *cp++ = '.'; - *cp++ = '0'; - *cp++ = '\0'; - return; - } - /* Checking the next three chars should be more than enough to - * detect inf or nan, even on Windows. We check for inf or nan - * at last because they are rare cases. - */ - for (i=0; *cp != '\0' && i<3; cp++, i++) { - if (isdigit(Py_CHARMASK(*cp)) || *cp == '.') - continue; - /* found something that is neither a digit nor point - * it might be a NaN or INF - */ -#ifdef Py_NAN - if (Py_IS_NAN(ob_fval)) { - strcpy(buf, "nan"); - } - else -#endif - if (Py_IS_INFINITY(ob_fval)) { - cp = buf; - if (*cp == '-') - cp++; - strcpy(cp, "inf"); - } - break; - } - -} - -static void -format_float(char *buf, size_t buflen, PyFloatObject *v, int precision) -{ - assert(PyFloat_Check(v)); - format_double(buf, buflen, PyFloat_AS_DOUBLE(v), precision); -} - /* Macro and helper that convert PyObject obj to a C double and store the value in dbl. If conversion to double raises an exception, obj is set to NULL, and the function invoking this macro returns NULL. If @@ -398,6 +323,8 @@ else if (convert_to_double(&(obj), &(dbl)) < 0) \ return obj; +/* Methods */ + static int convert_to_double(PyObject **v, double *dbl) { @@ -418,38 +345,30 @@ return 0; } -/* Precisions used by repr() and str(), respectively. - - The repr() precision (17 significant decimal digits) is the minimal number - that is guaranteed to have enough precision so that if the number is read - back in the exact same binary value is recreated. This is true for IEEE - floating point by design, and also happens to work for all other modern - hardware. - - The str() precision is chosen so that in most cases, the rounding noise - created by various operations is suppressed, while giving plenty of - precision for practical use. - -*/ - -#define PREC_REPR 17 -#define PREC_STR 12 +static PyObject * +float_str_or_repr(PyFloatObject *v, char format_code) +{ + PyObject *result; + char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v), + format_code, 0, Py_DTSF_ADD_DOT_0, + NULL); + if (!buf) + return PyErr_NoMemory(); + result = PyUnicode_FromString(buf); + PyMem_Free(buf); + return result; +} static PyObject * float_repr(PyFloatObject *v) { - char buf[100]; - format_float(buf, sizeof(buf), v, PREC_REPR); - - return PyUnicode_FromString(buf); + return float_str_or_repr(v, 'r'); } static PyObject * float_str(PyFloatObject *v) { - char buf[100]; - format_float(buf, sizeof(buf), v, PREC_STR); - return PyUnicode_FromString(buf); + return float_str_or_repr(v, 's'); } /* Comparison is pretty much a nightmare. When comparing float to float, @@ -1980,15 +1899,21 @@ i++, p++) { if (PyFloat_CheckExact(p) && Py_REFCNT(p) != 0) { - char buf[100]; - format_float(buf, sizeof(buf), p, PREC_STR); - /* XXX(twouters) cast refcount to - long until %zd is universally - available - */ - fprintf(stderr, + char *buf = PyOS_double_to_string( + PyFloat_AS_DOUBLE(p), 'r', + 0, 0, NULL); + if (buf) { + /* XXX(twouters) cast + refcount to long + until %zd is + universally + available + */ + fprintf(stderr, "# \n", p, (long)Py_REFCNT(p), buf); + PyMem_Free(buf); + } } } list = list->next; @@ -2233,14 +2158,6 @@ } } -/* Should only be used by marshal. */ -int -_PyFloat_Repr(double x, char *p, size_t len) -{ - format_double(p, len, x, PREC_REPR); - return (int)strlen(p); -} - double _PyFloat_Unpack4(const unsigned char *p, int le) { Modified: python/branches/py3k/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k/Objects/stringlib/formatter.h (original) +++ python/branches/py3k/Objects/stringlib/formatter.h Thu Apr 16 22:16:10 2009 @@ -1,6 +1,8 @@ /* implements the string, long, and float formatters. that is, string.__format__, etc. */ +#include + /* Before including this, you must include either: stringlib/unicodedefs.h stringlib/stringdefs.h @@ -13,8 +15,6 @@ be. These are the only non-static functions defined here. */ -#define ALLOW_PARENS_FOR_SIGN 0 - /* Raises an exception about an unknown presentation type for this * type. */ @@ -104,9 +104,6 @@ { switch (c) { case ' ': case '+': case '-': -#if ALLOW_PARENS_FOR_SIGN - case '(': -#endif return 1; default: return 0; @@ -143,7 +140,7 @@ /* end-ptr is used throughout this code to specify the length of the input string */ - Py_ssize_t specified_width; + Py_ssize_t consumed; format->fill_char = '\0'; format->align = '\0'; @@ -170,11 +167,6 @@ if (end-ptr >= 1 && is_sign_element(ptr[0])) { format->sign = ptr[0]; ++ptr; -#if ALLOW_PARENS_FOR_SIGN - if (end-ptr >= 1 && ptr[0] == ')') { - ++ptr; - } -#endif } /* If the next character is #, we're in alternate mode. This only @@ -193,15 +185,17 @@ ++ptr; } - /* XXX add error checking */ - specified_width = get_integer(&ptr, end, &format->width); + consumed = get_integer(&ptr, end, &format->width); + if (consumed == -1) + /* Overflow error. Exception already set. */ + return 0; - /* if specified_width is 0, we didn't consume any characters for - the width. in that case, reset the width to -1, because - get_integer() will have set it to zero */ - if (specified_width == 0) { + /* If consumed is 0, we didn't consume any characters for the + width. In that case, reset the width to -1, because + get_integer() will have set it to zero. -1 is how we record + that the width wasn't specified. */ + if (consumed == 0) format->width = -1; - } /* Comma signifies add thousands separators */ if (end-ptr && ptr[0] == ',') { @@ -213,11 +207,13 @@ if (end-ptr && ptr[0] == '.') { ++ptr; - /* XXX add error checking */ - specified_width = get_integer(&ptr, end, &format->precision); + consumed = get_integer(&ptr, end, &format->precision); + if (consumed == -1) + /* Overflow error. Exception already set. */ + return 0; - /* not having a precision after a dot is an error */ - if (specified_width == 0) { + /* Not having a precision after a dot is an error. */ + if (consumed == 0) { PyErr_Format(PyExc_ValueError, "Format specifier missing precision"); return 0; @@ -225,10 +221,10 @@ } - /* Finally, parse the type field */ + /* Finally, parse the type field. */ if (end-ptr > 1) { - /* invalid conversion spec */ + /* More than one char remain, invalid conversion spec. */ PyErr_Format(PyExc_ValueError, "Invalid conversion specification"); return 0; } @@ -238,9 +234,27 @@ ++ptr; } - if (format->type == 'n' && format->thousands_separators) { - PyErr_Format(PyExc_ValueError, "Cannot specify ',' with 'n'."); - return 0; + /* Do as much validating as we can, just by looking at the format + specifier. Do not take into account what type of formatting + we're doing (int, float, string). */ + + if (format->thousands_separators) { + switch (format->type) { + case 'd': + case 'e': + case 'f': + case 'g': + case 'E': + case 'G': + case '%': + case 'F': + /* These are allowed. See PEP 378.*/ + break; + default: + PyErr_Format(PyExc_ValueError, + "Cannot specify ',' with '%c'.", format->type); + return 0; + } } return 1; @@ -251,6 +265,20 @@ /*********** common routines for numeric formatting *********************/ /************************************************************************/ +/* Locale type codes. */ +#define LT_CURRENT_LOCALE 0 +#define LT_DEFAULT_LOCALE 1 +#define LT_NO_LOCALE 2 + +/* Locale info needed for formatting integers and the part of floats + before and including the decimal. Note that locales only support + 8-bit chars, not unicode. */ +typedef struct { + char *decimal_point; + char *thousands_sep; + char *grouping; +} LocaleInfo; + /* describes the layout for an integer, see the comment in calc_number_widths() for details */ typedef struct { @@ -258,38 +286,84 @@ Py_ssize_t n_prefix; Py_ssize_t n_spadding; Py_ssize_t n_rpadding; - char lsign; - Py_ssize_t n_lsign; - char rsign; - Py_ssize_t n_rsign; - Py_ssize_t n_total; /* just a convenience, it's derivable from the - other fields */ + char sign; + Py_ssize_t n_sign; /* number of digits needed for sign (0/1) */ + Py_ssize_t n_grouped_digits; /* Space taken up by the digits, including + any grouping chars. */ + Py_ssize_t n_decimal; /* 0 if only an integer */ + Py_ssize_t n_remainder; /* Digits in decimal and/or exponent part, + excluding the decimal itself, if + present. */ + + /* These 2 are not the widths of fields, but are needed by + STRINGLIB_GROUPING. */ + Py_ssize_t n_digits; /* The number of digits before a decimal + or exponent. */ + Py_ssize_t n_min_width; /* The min_width we used when we computed + the n_grouped_digits width. */ } NumberFieldWidths; +/* Given a number of the form: + digits[remainder] + where ptr points to the start and end points to the end, find where + the integer part ends. This could be a decimal, an exponent, both, + or neither. + If a decimal point is present, set *has_decimal and increment + remainder beyond it. + Results are undefined (but shouldn't crash) for improperly + formatted strings. +*/ +static void +parse_number(STRINGLIB_CHAR *ptr, Py_ssize_t len, + Py_ssize_t *n_remainder, int *has_decimal) +{ + STRINGLIB_CHAR *end = ptr + len; + STRINGLIB_CHAR *remainder; + + while (ptrn_digits = n_number - n_remainder - (has_decimal?1:0); spec->n_lpadding = 0; - spec->n_prefix = 0; + spec->n_prefix = n_prefix; + spec->n_decimal = has_decimal ? strlen(locale->decimal_point) : 0; + spec->n_remainder = n_remainder; spec->n_spadding = 0; spec->n_rpadding = 0; - spec->lsign = '\0'; - spec->n_lsign = 0; - spec->rsign = '\0'; - spec->n_rsign = 0; + spec->sign = '\0'; + spec->n_sign = 0; /* the output will look like: - | | - | | - | | + | | + | | + | | - lsign and rsign are computed from format->sign and the actual + sign is computed from format->sign and the actual sign of the number prefix is given (it's for the '0x' prefix) @@ -304,108 +378,191 @@ */ /* compute the various parts we're going to write */ - if (format->sign == '+') { + switch (format->sign) { + case '+': /* always put a + or - */ - spec->n_lsign = 1; - spec->lsign = (actual_sign == '-' ? '-' : '+'); - } -#if ALLOW_PARENS_FOR_SIGN - else if (format->sign == '(') { - if (actual_sign == '-') { - spec->n_lsign = 1; - spec->lsign = '('; - spec->n_rsign = 1; - spec->rsign = ')'; - } - } -#endif - else if (format->sign == ' ') { - spec->n_lsign = 1; - spec->lsign = (actual_sign == '-' ? '-' : ' '); - } - else { - /* non specified, or the default (-) */ - if (actual_sign == '-') { - spec->n_lsign = 1; - spec->lsign = '-'; + spec->n_sign = 1; + spec->sign = (sign_char == '-' ? '-' : '+'); + break; + case ' ': + spec->n_sign = 1; + spec->sign = (sign_char == '-' ? '-' : ' '); + break; + default: + /* Not specified, or the default (-) */ + if (sign_char == '-') { + spec->n_sign = 1; + spec->sign = '-'; } } - spec->n_prefix = n_prefix; + /* The number of chars used for non-digits and non-padding. */ + n_non_digit_non_padding = spec->n_sign + spec->n_prefix + spec->n_decimal + + spec->n_remainder; + + /* min_width can go negative, that's okay. format->width == -1 means + we don't care. */ + if (format->fill_char == '0') + spec->n_min_width = format->width - n_non_digit_non_padding; + else + spec->n_min_width = 0; - /* now the number of padding characters */ - if (format->width == -1) { - /* no padding at all, nothing to do */ - } - else { - /* see if any padding is needed */ - if (spec->n_lsign + n_digits + spec->n_rsign + - spec->n_prefix >= format->width) { - /* no padding needed, we're already bigger than the - requested width */ - } - else { - /* determine which of left, space, or right padding is - needed */ - Py_ssize_t padding = format->width - - (spec->n_lsign + spec->n_prefix + - n_digits + spec->n_rsign); - if (format->align == '<') - spec->n_rpadding = padding; - else if (format->align == '>') - spec->n_lpadding = padding; - else if (format->align == '^') { - spec->n_lpadding = padding / 2; - spec->n_rpadding = padding - spec->n_lpadding; - } - else if (format->align == '=') - spec->n_spadding = padding; - else - spec->n_lpadding = padding; + if (spec->n_digits == 0) + /* This case only occurs when using 'c' formatting, we need + to special case it because the grouping code always wants + to have at least one character. */ + spec->n_grouped_digits = 0; + else + spec->n_grouped_digits = STRINGLIB_GROUPING(NULL, 0, NULL, + spec->n_digits, + spec->n_min_width, + locale->grouping, + locale->thousands_sep); + + /* Given the desired width and the total of digit and non-digit + space we consume, see if we need any padding. format->width can + be negative (meaning no padding), but this code still works in + that case. */ + n_padding = format->width - + (n_non_digit_non_padding + spec->n_grouped_digits); + if (n_padding > 0) { + /* Some padding is needed. Determine if it's left, space, or right. */ + switch (format->align) { + case '<': + spec->n_rpadding = n_padding; + break; + case '^': + spec->n_lpadding = n_padding / 2; + spec->n_rpadding = n_padding - spec->n_lpadding; + break; + case '=': + spec->n_spadding = n_padding; + break; + default: + /* Handles '>', plus catch-all just in case. */ + spec->n_lpadding = n_padding; + break; } } - spec->n_total = spec->n_lpadding + spec->n_lsign + spec->n_prefix + - spec->n_spadding + n_digits + spec->n_rsign + spec->n_rpadding; + return spec->n_lpadding + spec->n_sign + spec->n_prefix + + spec->n_spadding + spec->n_grouped_digits + spec->n_decimal + + spec->n_remainder + spec->n_rpadding; } -/* fill in the non-digit parts of a numbers's string representation, - as determined in calc_number_widths(). returns the pointer to - where the digits go. */ -static STRINGLIB_CHAR * -fill_non_digits(STRINGLIB_CHAR *p_buf, const NumberFieldWidths *spec, - STRINGLIB_CHAR *prefix, Py_ssize_t n_digits, - STRINGLIB_CHAR fill_char) +/* Fill in the digit parts of a numbers's string representation, + as determined in calc_number_widths(). + No error checking, since we know the buffer is the correct size. */ +static void +fill_number(STRINGLIB_CHAR *buf, const NumberFieldWidths *spec, + STRINGLIB_CHAR *digits, Py_ssize_t n_digits, + STRINGLIB_CHAR *prefix, STRINGLIB_CHAR fill_char, + LocaleInfo *locale, int toupper) { - STRINGLIB_CHAR *p_digits; + /* Used to keep track of digits, decimal, and remainder. */ + STRINGLIB_CHAR *p = digits; + +#ifndef NDEBUG + Py_ssize_t r; +#endif if (spec->n_lpadding) { - STRINGLIB_FILL(p_buf, fill_char, spec->n_lpadding); - p_buf += spec->n_lpadding; + STRINGLIB_FILL(buf, fill_char, spec->n_lpadding); + buf += spec->n_lpadding; } - if (spec->n_lsign == 1) { - *p_buf++ = spec->lsign; + if (spec->n_sign == 1) { + *buf++ = spec->sign; } if (spec->n_prefix) { - memmove(p_buf, + memmove(buf, prefix, spec->n_prefix * sizeof(STRINGLIB_CHAR)); - p_buf += spec->n_prefix; + if (toupper) { + Py_ssize_t t; + for (t = 0; t < spec->n_prefix; ++t) + buf[t] = STRINGLIB_TOUPPER(buf[t]); + } + buf += spec->n_prefix; } if (spec->n_spadding) { - STRINGLIB_FILL(p_buf, fill_char, spec->n_spadding); - p_buf += spec->n_spadding; + STRINGLIB_FILL(buf, fill_char, spec->n_spadding); + buf += spec->n_spadding; + } + + /* Only for type 'c' special case, it has no digits. */ + if (spec->n_digits != 0) { + /* Fill the digits with InsertThousandsGrouping. */ +#ifndef NDEBUG + r = +#endif + STRINGLIB_GROUPING(buf, spec->n_grouped_digits, digits, + spec->n_digits, spec->n_min_width, + locale->grouping, locale->thousands_sep); +#ifndef NDEBUG + assert(r == spec->n_grouped_digits); +#endif + p += spec->n_digits; } - p_digits = p_buf; - p_buf += n_digits; - if (spec->n_rsign == 1) { - *p_buf++ = spec->rsign; + if (toupper) { + Py_ssize_t t; + for (t = 0; t < spec->n_grouped_digits; ++t) + buf[t] = STRINGLIB_TOUPPER(buf[t]); + } + buf += spec->n_grouped_digits; + + if (spec->n_decimal) { + Py_ssize_t t; + for (t = 0; t < spec->n_decimal; ++t) + buf[t] = locale->decimal_point[t]; + buf += spec->n_decimal; + p += 1; } + + if (spec->n_remainder) { + memcpy(buf, p, spec->n_remainder * sizeof(STRINGLIB_CHAR)); + buf += spec->n_remainder; + p += spec->n_remainder; + } + if (spec->n_rpadding) { - STRINGLIB_FILL(p_buf, fill_char, spec->n_rpadding); - p_buf += spec->n_rpadding; + STRINGLIB_FILL(buf, fill_char, spec->n_rpadding); + buf += spec->n_rpadding; } - return p_digits; } + +static char no_grouping[1] = {CHAR_MAX}; + +/* Find the decimal point character(s?), thousands_separator(s?), and + grouping description, either for the current locale if type is + LT_CURRENT_LOCALE, a hard-coded locale if LT_DEFAULT_LOCALE, or + none if LT_NO_LOCALE. */ +static void +get_locale_info(int type, LocaleInfo *locale_info) +{ + switch (type) { + case LT_CURRENT_LOCALE: { + struct lconv *locale_data = localeconv(); + locale_info->decimal_point = locale_data->decimal_point; + locale_info->thousands_sep = locale_data->thousands_sep; + locale_info->grouping = locale_data->grouping; + break; + } + case LT_DEFAULT_LOCALE: + locale_info->decimal_point = "."; + locale_info->thousands_sep = ","; + locale_info->grouping = "\3"; /* Group every 3 characters, + trailing 0 means repeat + infinitely. */ + break; + case LT_NO_LOCALE: + locale_info->decimal_point = "."; + locale_info->thousands_sep = ""; + locale_info->grouping = no_grouping; + break; + default: + assert(0); + } +} + #endif /* FORMAT_FLOAT || FORMAT_LONG */ /************************************************************************/ @@ -523,19 +680,21 @@ PyObject *tmp = NULL; STRINGLIB_CHAR *pnumeric_chars; STRINGLIB_CHAR numeric_char; - STRINGLIB_CHAR sign = '\0'; - STRINGLIB_CHAR *p; + STRINGLIB_CHAR sign_char = '\0'; Py_ssize_t n_digits; /* count of digits need from the computed string */ - Py_ssize_t n_leading_chars; - Py_ssize_t n_grouping_chars = 0; /* Count of additional chars to - allocate, used for 'n' - formatting. */ + Py_ssize_t n_remainder = 0; /* Used only for 'c' formatting, which + produces non-digits */ Py_ssize_t n_prefix = 0; /* Count of prefix chars, (e.g., '0x') */ + Py_ssize_t n_total; STRINGLIB_CHAR *prefix = NULL; NumberFieldWidths spec; long x; + /* Locale settings, either from the actual locale or + from a hard-code pseudo-locale */ + LocaleInfo locale; + /* no precision allowed on integers */ if (format->precision != -1) { PyErr_SetString(PyExc_ValueError, @@ -543,7 +702,6 @@ goto done; } - /* special case for character formatting */ if (format->type == 'c') { /* error to specify a sign */ @@ -554,6 +712,14 @@ goto done; } + /* Error to specify a comma. */ + if (format->thousands_separators) { + PyErr_SetString(PyExc_ValueError, + "Thousands separators not allowed with integer" + " format specifier 'c'"); + goto done; + } + /* taken from unicodeobject.c formatchar() */ /* Integer input truncated to a character */ /* XXX: won't work for int */ @@ -578,6 +744,13 @@ numeric_char = (STRINGLIB_CHAR)x; pnumeric_chars = &numeric_char; n_digits = 1; + + /* As a sort-of hack, we tell calc_number_widths that we only + have "remainder" characters. calc_number_widths thinks + these are characters that don't get formatted, only copied + into the output string. We do this for 'c' formatting, + because the characters are likely to be non-digits. */ + n_remainder = 1; } else { int base; @@ -629,8 +802,8 @@ /* Is a sign character present in the output? If so, remember it and skip it */ - sign = pnumeric_chars[0]; - if (sign == '-') { + if (pnumeric_chars[0] == '-') { + sign_char = pnumeric_chars[0]; ++prefix; ++leading_chars_to_skip; } @@ -640,86 +813,26 @@ pnumeric_chars += leading_chars_to_skip; } - if (format->type == 'n') - /* Compute how many additional chars we need to allocate - to hold the thousands grouping. */ - STRINGLIB_GROUPING_LOCALE(NULL, n_digits, n_digits, - 0, &n_grouping_chars, 0); - if (format->thousands_separators) - /* Compute how many additional chars we need to allocate - to hold the thousands grouping. */ - STRINGLIB_GROUPING(NULL, n_digits, n_digits, - 0, &n_grouping_chars, 0, "\3", ","); - - /* Calculate the widths of the various leading and trailing parts */ - calc_number_widths(&spec, sign, n_prefix, n_digits + n_grouping_chars, - format); + /* Determine the grouping, separator, and decimal point, if any. */ + get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE : + (format->thousands_separators ? + LT_DEFAULT_LOCALE : + LT_NO_LOCALE), + &locale); + + /* Calculate how much memory we'll need. */ + n_total = calc_number_widths(&spec, n_prefix, sign_char, pnumeric_chars, + n_digits, n_remainder, 0, &locale, format); - /* Allocate a new string to hold the result */ - result = STRINGLIB_NEW(NULL, spec.n_total); + /* Allocate the memory. */ + result = STRINGLIB_NEW(NULL, n_total); if (!result) goto done; - p = STRINGLIB_STR(result); - - /* XXX There is too much magic here regarding the internals of - spec and the location of the prefix and digits. It would be - better if calc_number_widths returned a number of logical - offsets into the buffer, and those were used. Maybe in a - future code cleanup. */ - - /* Fill in the digit parts */ - n_leading_chars = spec.n_lpadding + spec.n_lsign + - spec.n_prefix + spec.n_spadding; - memmove(p + n_leading_chars, - pnumeric_chars, - n_digits * sizeof(STRINGLIB_CHAR)); - - /* If type is 'X', convert the filled in digits to uppercase */ - if (format->type == 'X') { - Py_ssize_t t; - for (t = 0; t < n_digits; ++t) - p[t + n_leading_chars] = STRINGLIB_TOUPPER(p[t + n_leading_chars]); - } - - /* Insert the grouping, if any, after the uppercasing of the digits, so - we can ensure that grouping chars won't be affected. */ - if (n_grouping_chars) { - /* We know this can't fail, since we've already - reserved enough space. */ - STRINGLIB_CHAR *pstart = p + n_leading_chars; -#ifndef NDEBUG - int r; -#endif - if (format->type == 'n') -#ifndef NDEBUG - r = -#endif - STRINGLIB_GROUPING_LOCALE(pstart, n_digits, n_digits, - spec.n_total+n_grouping_chars-n_leading_chars, - NULL, 0); - else -#ifndef NDEBUG - r = -#endif - STRINGLIB_GROUPING(pstart, n_digits, n_digits, - spec.n_total+n_grouping_chars-n_leading_chars, - NULL, 0, "\3", ","); - assert(r); - } - - /* Fill in the non-digit parts (padding, sign, etc.) */ - fill_non_digits(p, &spec, prefix, n_digits + n_grouping_chars, - format->fill_char == '\0' ? ' ' : format->fill_char); - - /* If type is 'X', uppercase the prefix. This has to be done after the - prefix is filled in by fill_non_digits */ - if (format->type == 'X') { - Py_ssize_t t; - for (t = 0; t < n_prefix; ++t) - p[t + spec.n_lpadding + spec.n_lsign] = - STRINGLIB_TOUPPER(p[t + spec.n_lpadding + spec.n_lsign]); - } + /* Populate the memory. */ + fill_number(STRINGLIB_STR(result), &spec, pnumeric_chars, n_digits, + prefix, format->fill_char == '\0' ? ' ' : format->fill_char, + &locale, format->type == 'X'); done: Py_XDECREF(tmp); @@ -733,64 +846,45 @@ #ifdef FORMAT_FLOAT #if STRINGLIB_IS_UNICODE -/* taken from unicodeobject.c */ -static Py_ssize_t -strtounicode(Py_UNICODE *buffer, const char *charbuffer) +static void +strtounicode(Py_UNICODE *buffer, const char *charbuffer, Py_ssize_t len) { - register Py_ssize_t i; - Py_ssize_t len = strlen(charbuffer); - for (i = len - 1; i >= 0; --i) - buffer[i] = (Py_UNICODE) charbuffer[i]; - - return len; + Py_ssize_t i; + for (i = 0; i < len; ++i) + buffer[i] = (Py_UNICODE)charbuffer[i]; } #endif -/* see FORMATBUFLEN in unicodeobject.c */ -#define FLOAT_FORMATBUFLEN 120 - /* much of this is taken from unicodeobject.c */ static PyObject * format_float_internal(PyObject *value, const InternalFormatSpec *format) { - /* fmt = '%.' + `prec` + `type` + '%%' - worst case length = 2 + 10 (len of INT_MAX) + 1 + 2 = 15 (use 20)*/ - char fmt[20]; - - /* taken from unicodeobject.c */ - /* Worst case length calc to ensure no buffer overrun: - - 'g' formats: - fmt = %#.g - buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp - for any double rep.) - len = 1 + prec + 1 + 2 + 5 = 9 + prec - - 'f' formats: - buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50) - len = 1 + 50 + 1 + prec = 52 + prec - - If prec=0 the effective precision is 1 (the leading digit is - always given), therefore increase the length by one. - - */ - char charbuf[FLOAT_FORMATBUFLEN]; + char *buf = NULL; /* buffer returned from PyOS_double_to_string */ Py_ssize_t n_digits; - double x; + Py_ssize_t n_remainder; + Py_ssize_t n_total; + int has_decimal; + double val; Py_ssize_t precision = format->precision; - PyObject *result = NULL; - STRINGLIB_CHAR sign; - char* trailing = ""; + STRINGLIB_CHAR type = format->type; + int add_pct = 0; STRINGLIB_CHAR *p; NumberFieldWidths spec; - STRINGLIB_CHAR type = format->type; + int flags = 0; + PyObject *result = NULL; + STRINGLIB_CHAR sign_char = '\0'; + int float_type; /* Used to see if we have a nan, inf, or regular float. */ #if STRINGLIB_IS_UNICODE - Py_UNICODE unicodebuf[FLOAT_FORMATBUFLEN]; + Py_UNICODE *unicode_tmp = NULL; #endif - /* alternate is not allowed on floats. */ + /* Locale settings, either from the actual locale or + from a hard-code pseudo-locale */ + LocaleInfo locale; + + /* Alternate is not allowed on floats. */ if (format->alternate) { PyErr_SetString(PyExc_ValueError, "Alternate form (#) not allowed in float format " @@ -798,84 +892,106 @@ goto done; } - /* first, do the conversion as 8-bit chars, using the platform's - snprintf. then, if needed, convert to unicode. */ + if (type == '\0') { + /* Omitted type specifier. This is like 'g' but with at least + one digit after the decimal point. */ + type = 'g'; + flags |= Py_DTSF_ADD_DOT_0; + } + + if (type == 'n') + /* 'n' is the same as 'g', except for the locale used to + format the result. We take care of that later. */ + type = 'g'; /* 'F' is the same as 'f', per the PEP */ if (type == 'F') type = 'f'; - x = PyFloat_AsDouble(value); - - if (x == -1.0 && PyErr_Occurred()) + val = PyFloat_AsDouble(value); + if (val == -1.0 && PyErr_Occurred()) goto done; if (type == '%') { type = 'f'; - x *= 100; - trailing = "%"; + val *= 100; + add_pct = 1; } if (precision < 0) precision = 6; - if (type == 'f' && fabs(x) >= 1e50) + if ((type == 'f' || type == 'F') && fabs(val) >= 1e50) type = 'g'; - /* cast "type", because if we're in unicode we need to pass a - 8-bit char. this is safe, because we've restricted what "type" - can be */ - PyOS_snprintf(fmt, sizeof(fmt), "%%.%" PY_FORMAT_SIZE_T "d%c", precision, - (char)type); - - /* do the actual formatting */ - PyOS_ascii_formatd(charbuf, sizeof(charbuf), fmt, x); - - /* adding trailing to fmt with PyOS_snprintf doesn't work, not - sure why. we'll just concatentate it here, no harm done. we - know we can't have a buffer overflow from the fmt size - analysis */ - strcat(charbuf, trailing); - - /* rather than duplicate the code for snprintf for both unicode - and 8 bit strings, we just use the 8 bit version and then - convert to unicode in a separate code path. that's probably - the lesser of 2 evils. */ + /* Cast "type", because if we're in unicode we need to pass a + 8-bit char. This is safe, because we've restricted what "type" + can be. */ + buf = PyOS_double_to_string(val, (char)type, precision, flags, + &float_type); + if (buf == NULL) + goto done; + n_digits = strlen(buf); + + if (add_pct) { + /* We know that buf has a trailing zero (since we just called + strlen() on it), and we don't use that fact any more. So we + can just write over the trailing zero. */ + buf[n_digits] = '%'; + n_digits += 1; + } + + /* Since there is no unicode version of PyOS_double_to_string, + just use the 8 bit version and then convert to unicode. */ #if STRINGLIB_IS_UNICODE - n_digits = strtounicode(unicodebuf, charbuf); - p = unicodebuf; + unicode_tmp = (Py_UNICODE*)PyMem_Malloc((n_digits)*sizeof(Py_UNICODE)); + if (unicode_tmp == NULL) { + PyErr_NoMemory(); + goto done; + } + strtounicode(unicode_tmp, buf, n_digits); + p = unicode_tmp; #else - /* compute the length. I believe this is done because the return - value from snprintf above is unreliable */ - n_digits = strlen(charbuf); - p = charbuf; + p = buf; #endif - /* is a sign character present in the output? if so, remember it + /* Is a sign character present in the output? If so, remember it and skip it */ - sign = p[0]; - if (sign == '-') { + if (*p == '-') { + sign_char = *p; ++p; --n_digits; } - calc_number_widths(&spec, sign, 0, n_digits, format); + /* Determine if we have any "remainder" (after the digits, might include + decimal or exponent or both (or neither)) */ + parse_number(p, n_digits, &n_remainder, &has_decimal); + + /* Determine the grouping, separator, and decimal point, if any. */ + get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE : + (format->thousands_separators ? + LT_DEFAULT_LOCALE : + LT_NO_LOCALE), + &locale); + + /* Calculate how much memory we'll need. */ + n_total = calc_number_widths(&spec, 0, sign_char, p, n_digits, + n_remainder, has_decimal, &locale, format); - /* allocate a string with enough space */ - result = STRINGLIB_NEW(NULL, spec.n_total); + /* Allocate the memory. */ + result = STRINGLIB_NEW(NULL, n_total); if (result == NULL) goto done; - /* Fill in the non-digit parts (padding, sign, etc.) */ - fill_non_digits(STRINGLIB_STR(result), &spec, NULL, n_digits, - format->fill_char == '\0' ? ' ' : format->fill_char); - - /* fill in the digit parts */ - memmove(STRINGLIB_STR(result) + - (spec.n_lpadding + spec.n_lsign + spec.n_spadding), - p, - n_digits * sizeof(STRINGLIB_CHAR)); + /* Populate the memory. */ + fill_number(STRINGLIB_STR(result), &spec, p, n_digits, NULL, + format->fill_char == '\0' ? ' ' : format->fill_char, &locale, + 0); done: + PyMem_Free(buf); +#if STRINGLIB_IS_UNICODE + PyMem_Free(unicode_tmp); +#endif return result; } #endif /* FORMAT_FLOAT */ @@ -1056,11 +1172,7 @@ /* type conversion? */ switch (format.type) { - case '\0': - /* 'Z' means like 'g', but with at least one decimal. See - PyOS_ascii_formatd */ - format.type = 'Z'; - /* Deliberate fall through to the next case statement */ + case '\0': /* No format code: like 'g', but with at least one decimal. */ case 'e': case 'E': case 'f': Modified: python/branches/py3k/Objects/stringlib/localeutil.h ============================================================================== --- python/branches/py3k/Objects/stringlib/localeutil.h (original) +++ python/branches/py3k/Objects/stringlib/localeutil.h Thu Apr 16 22:16:10 2009 @@ -5,161 +5,208 @@ #include +#define MAX(x, y) ((x) < (y) ? (y) : (x)) +#define MIN(x, y) ((x) < (y) ? (x) : (y)) + +typedef struct { + const char *grouping; + char previous; + Py_ssize_t i; /* Where we're currently pointing in grouping. */ +} GroupGenerator; + +static void +_GroupGenerator_init(GroupGenerator *self, const char *grouping) +{ + self->grouping = grouping; + self->i = 0; + self->previous = 0; +} + +/* Returns the next grouping, or 0 to signify end. */ +static Py_ssize_t +_GroupGenerator_next(GroupGenerator *self) +{ + /* Note that we don't really do much error checking here. If a + grouping string contains just CHAR_MAX, for example, then just + terminate the generator. That shouldn't happen, but at least we + fail gracefully. */ + switch (self->grouping[self->i]) { + case 0: + return self->previous; + case CHAR_MAX: + /* Stop the generator. */ + return 0; + default: { + char ch = self->grouping[self->i]; + self->previous = ch; + self->i++; + return (Py_ssize_t)ch; + } + } +} + +/* Fill in some digits, leading zeros, and thousands separator. All + are optional, depending on when we're called. */ +static void +fill(STRINGLIB_CHAR **digits_end, STRINGLIB_CHAR **buffer_end, + Py_ssize_t n_chars, Py_ssize_t n_zeros, const char* thousands_sep, + Py_ssize_t thousands_sep_len) +{ +#if STRINGLIB_IS_UNICODE + Py_ssize_t i; +#endif + + if (thousands_sep) { + *buffer_end -= thousands_sep_len; + + /* Copy the thousands_sep chars into the buffer. */ +#if STRINGLIB_IS_UNICODE + /* Convert from the char's of the thousands_sep from + the locale into unicode. */ + for (i = 0; i < thousands_sep_len; ++i) + (*buffer_end)[i] = thousands_sep[i]; +#else + /* No conversion, just memcpy the thousands_sep. */ + memcpy(*buffer_end, thousands_sep, thousands_sep_len); +#endif + } + + *buffer_end -= n_chars; + *digits_end -= n_chars; + memcpy(*buffer_end, *digits_end, n_chars * sizeof(STRINGLIB_CHAR)); + + *buffer_end -= n_zeros; + STRINGLIB_FILL(*buffer_end, '0', n_zeros); +} + /** * _Py_InsertThousandsGrouping: * @buffer: A pointer to the start of a string. - * @n_buffer: The length of the string. + * @n_buffer: Number of characters in @buffer. + * @digits: A pointer to the digits we're reading from. If count + * is non-NULL, this is unused. * @n_digits: The number of digits in the string, in which we want * to put the grouping chars. - * @buf_size: The maximum size of the buffer pointed to by buffer. - * @count: If non-NULL, points to a variable that will receive the - * number of characters we need to insert (and no formatting - * will actually occur). - * @append_zero_char: If non-zero, put a trailing zero at the end of - * of the resulting string, if and only if we modified the - * string. + * @min_width: The minimum width of the digits in the output string. + * Output will be zero-padded on the left to fill. * @grouping: see definition in localeconv(). * @thousands_sep: see definition in localeconv(). * + * There are 2 modes: counting and filling. If @buffer is NULL, + * we are in counting mode, else filling mode. + * If counting, the required buffer size is returned. + * If filling, we know the buffer will be large enough, so we don't + * need to pass in the buffer size. * Inserts thousand grouping characters (as defined by grouping and * thousands_sep) into the string between buffer and buffer+n_digits. - * If count is non-NULL, don't do any formatting, just count the - * number of characters to insert. This is used by the caller to - * appropriately resize the buffer, if needed. If count is non-NULL, - * buffer can be NULL (it is not dereferenced at all in that case). * * Return value: 0 on error, else 1. Note that no error can occur if * count is non-NULL. * * This name won't be used, the includer of this file should define * it to be the actual function name, based on unicode or string. + * + * As closely as possible, this code mimics the logic in decimal.py's + _insert_thousands_sep(). **/ -int +Py_ssize_t _Py_InsertThousandsGrouping(STRINGLIB_CHAR *buffer, Py_ssize_t n_buffer, + STRINGLIB_CHAR *digits, Py_ssize_t n_digits, - Py_ssize_t buf_size, - Py_ssize_t *count, - int append_zero_char, + Py_ssize_t min_width, const char *grouping, const char *thousands_sep) { - Py_ssize_t thousands_sep_len = strlen(thousands_sep); - STRINGLIB_CHAR *pend = NULL; /* current end of buffer */ - STRINGLIB_CHAR *pmax = NULL; /* max of buffer */ - char current_grouping; - Py_ssize_t remaining = n_digits; /* Number of chars remaining to - be looked at */ - - /* Initialize the character count, if we're just counting. */ - if (count) - *count = 0; - else { - /* We're not just counting, we're modifying buffer */ - pend = buffer + n_buffer; - pmax = buffer + buf_size; + Py_ssize_t count = 0; + Py_ssize_t n_zeros; + int loop_broken = 0; + int use_separator = 0; /* First time through, don't append the + separator. They only go between + groups. */ + STRINGLIB_CHAR *buffer_end = NULL; + STRINGLIB_CHAR *digits_end = NULL; + Py_ssize_t l; + Py_ssize_t n_chars; + Py_ssize_t thousands_sep_len = strlen(thousands_sep); + Py_ssize_t remaining = n_digits; /* Number of chars remaining to + be looked at */ + /* A generator that returns all of the grouping widths, until it + returns 0. */ + GroupGenerator groupgen; + _GroupGenerator_init(&groupgen, grouping); + + if (buffer) { + buffer_end = buffer + n_buffer; + digits_end = digits + n_digits; + } + + while ((l = _GroupGenerator_next(&groupgen)) > 0) { + l = MIN(l, MAX(MAX(remaining, min_width), 1)); + n_zeros = MAX(0, l - remaining); + n_chars = MAX(0, MIN(remaining, l)); + + /* Use n_zero zero's and n_chars chars */ + + /* Count only, don't do anything. */ + count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars; + + if (buffer) { + /* Copy into the output buffer. */ + fill(&digits_end, &buffer_end, n_chars, n_zeros, + use_separator ? thousands_sep : NULL, thousands_sep_len); } - /* Starting at the end and working right-to-left, keep track of - what grouping needs to be added and insert that. */ - current_grouping = *grouping++; - - /* If the first character is 0, perform no grouping at all. */ - if (current_grouping == 0) - return 1; - - while (remaining > current_grouping) { - /* Always leave buffer and pend valid at the end of this - loop, since we might leave with a return statement. */ - - remaining -= current_grouping; - if (count) { - /* We're only counting, not touching the memory. */ - *count += thousands_sep_len; - } - else { - /* Do the formatting. */ - - STRINGLIB_CHAR *plast = buffer + remaining; - - /* Is there room to insert thousands_sep_len chars? */ - if (pmax - pend < thousands_sep_len) - /* No room. */ - return 0; - - /* Move the rest of the string down. */ - memmove(plast + thousands_sep_len, - plast, - (pend - plast) * sizeof(STRINGLIB_CHAR)); - /* Copy the thousands_sep chars into the buffer. */ -#if STRINGLIB_IS_UNICODE - /* Convert from the char's of the thousands_sep from - the locale into unicode. */ - { - Py_ssize_t i; - for (i = 0; i < thousands_sep_len; ++i) - plast[i] = thousands_sep[i]; - } -#else - /* No conversion, just memcpy the thousands_sep. */ - memcpy(plast, thousands_sep, thousands_sep_len); -#endif - } + /* Use a separator next time. */ + use_separator = 1; - /* Adjust end pointer. */ - pend += thousands_sep_len; + remaining -= n_chars; + min_width -= l; - /* Move to the next grouping character, unless we're - repeating (which is designated by a grouping of 0). */ - if (*grouping != 0) { - current_grouping = *grouping++; - if (current_grouping == CHAR_MAX) - /* We're done. */ - break; - } + if (remaining <= 0 && min_width <= 0) { + loop_broken = 1; + break; } - if (append_zero_char) { - /* Append a zero character to mark the end of the string, - if there's room. */ - if (pend - (buffer + remaining) < 1) - /* No room, error. */ - return 0; - *pend = 0; + min_width -= thousands_sep_len; + } + if (!loop_broken) { + /* We left the loop without using a break statement. */ + + l = MAX(MAX(remaining, min_width), 1); + n_zeros = MAX(0, l - remaining); + n_chars = MAX(0, MIN(remaining, l)); + + /* Use n_zero zero's and n_chars chars */ + count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars; + if (buffer) { + /* Copy into the output buffer. */ + fill(&digits_end, &buffer_end, n_chars, n_zeros, + use_separator ? thousands_sep : NULL, thousands_sep_len); } - return 1; + } + return count; } /** * _Py_InsertThousandsGroupingLocale: * @buffer: A pointer to the start of a string. - * @n_buffer: The length of the string. * @n_digits: The number of digits in the string, in which we want * to put the grouping chars. - * @buf_size: The maximum size of the buffer pointed to by buffer. - * @count: If non-NULL, points to a variable that will receive the - * number of characters we need to insert (and no formatting - * will actually occur). - * @append_zero_char: If non-zero, put a trailing zero at the end of - * of the resulting string, if and only if we modified the - * string. * * Reads thee current locale and calls _Py_InsertThousandsGrouping(). **/ -int +Py_ssize_t _Py_InsertThousandsGroupingLocale(STRINGLIB_CHAR *buffer, Py_ssize_t n_buffer, + STRINGLIB_CHAR *digits, Py_ssize_t n_digits, - Py_ssize_t buf_size, - Py_ssize_t *count, - int append_zero_char) + Py_ssize_t min_width) { struct lconv *locale_data = localeconv(); const char *grouping = locale_data->grouping; const char *thousands_sep = locale_data->thousands_sep; - return _Py_InsertThousandsGrouping(buffer, n_buffer, n_digits, - buf_size, count, - append_zero_char, grouping, - thousands_sep); + return _Py_InsertThousandsGrouping(buffer, n_buffer, digits, n_digits, + min_width, grouping, thousands_sep); } #endif /* STRINGLIB_LOCALEUTIL_H */ Modified: python/branches/py3k/Objects/unicodeobject.c ============================================================================== --- python/branches/py3k/Objects/unicodeobject.c (original) +++ python/branches/py3k/Objects/unicodeobject.c Thu Apr 16 22:16:10 2009 @@ -8792,43 +8792,14 @@ return NULL; } -static Py_ssize_t -strtounicode(Py_UNICODE *buffer, const char *charbuffer) +static void +strtounicode(Py_UNICODE *buffer, const char *charbuffer, Py_ssize_t len) { register Py_ssize_t i; - Py_ssize_t len = strlen(charbuffer); for (i = len - 1; i >= 0; i--) buffer[i] = (Py_UNICODE) charbuffer[i]; - - return len; -} - -static int -doubletounicode(Py_UNICODE *buffer, size_t len, const char *format, double x) -{ - Py_ssize_t result; - - PyOS_ascii_formatd((char *)buffer, len, format, x); - result = strtounicode(buffer, (char *)buffer); - return Py_SAFE_DOWNCAST(result, Py_ssize_t, int); } -#if 0 -static int -longtounicode(Py_UNICODE *buffer, size_t len, const char *format, long x) -{ - Py_ssize_t result; - - PyOS_snprintf((char *)buffer, len, format, x); - result = strtounicode(buffer, (char *)buffer); - return Py_SAFE_DOWNCAST(result, Py_ssize_t, int); -} -#endif - -/* XXX To save some code duplication, formatfloat/long/int could have been - shared with stringobject.c, converting from 8-bit to Unicode after the - formatting is done. */ - static int formatfloat(Py_UNICODE *buf, size_t buflen, @@ -8837,54 +8808,59 @@ int type, PyObject *v) { - /* fmt = '%#.' + `prec` + `type` - worst case length = 3 + 10 (len of INT_MAX) + 1 = 14 (use 20)*/ - char fmt[20]; + /* eric.smith: To minimize disturbances in PyUnicode_Format (the + only caller of this routine), I'm going to keep the existing + API to this function. That means that we'll allocate memory and + then copy back into the supplied buffer. But that's better than + all of the changes that would be required in PyUnicode_Format + because it does lots of memory management tricks. */ + + char* p = NULL; + int result = -1; double x; + Py_ssize_t len; x = PyFloat_AsDouble(v); if (x == -1.0 && PyErr_Occurred()) - return -1; + goto done; if (prec < 0) prec = 6; + /* make sure that the decimal representation of precision really does need at most 10 digits: platforms with sizeof(int) == 8 exist! */ if (prec > 0x7fffffffL) { PyErr_SetString(PyExc_OverflowError, "outrageously large precision " "for formatted float"); - return -1; + goto done; } if (type == 'f' && fabs(x) >= 1e50) type = 'g'; - /* Worst case length calc to ensure no buffer overrun: - - 'g' formats: - fmt = %#.g - buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp - for any double rep.) - len = 1 + prec + 1 + 2 + 5 = 9 + prec - - 'f' formats: - buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50) - len = 1 + 50 + 1 + prec = 52 + prec - - If prec=0 the effective precision is 1 (the leading digit is - always given), therefore increase the length by one. - */ if (((type == 'g' || type == 'G') && buflen <= (size_t)10 + (size_t)prec) || - (type == 'f' && buflen <= (size_t)53 + (size_t)prec)) { + ((type == 'f' || type == 'F') && + buflen <= (size_t)53 + (size_t)prec)) { PyErr_SetString(PyExc_OverflowError, "formatted float is too long (precision too large?)"); - return -1; + goto done; } - PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%d%c", - (flags&F_ALT) ? "#" : "", - prec, type); - return doubletounicode(buf, buflen, fmt, x); + + p = PyOS_double_to_string(x, type, prec, + (flags & F_ALT) ? Py_DTSF_ALT : 0, NULL); + len = strlen(p); + if (len+1 >= buflen) { + /* Caller supplied buffer is not large enough. */ + PyErr_NoMemory(); + goto done; + } + strtounicode(buf, p, len); + result = Py_SAFE_DOWNCAST(len, Py_ssize_t, int); + +done: + PyMem_Free(p); + return result; } static PyObject* @@ -8903,84 +8879,6 @@ return result; } -#if 0 -static int -formatint(Py_UNICODE *buf, - size_t buflen, - int flags, - int prec, - int type, - PyObject *v) -{ - /* fmt = '%#.' + `prec` + 'l' + `type` - * worst case length = 3 + 19 (worst len of INT_MAX on 64-bit machine) - * + 1 + 1 - * = 24 - */ - char fmt[64]; /* plenty big enough! */ - char *sign; - long x; - - x = PyLong_AsLong(v); - if (x == -1 && PyErr_Occurred()) - return -1; - if (x < 0 && type == 'u') { - type = 'd'; - } - if (x < 0 && (type == 'x' || type == 'X' || type == 'o')) - sign = "-"; - else - sign = ""; - if (prec < 0) - prec = 1; - - /* buf = '+'/'-'/'' + '0'/'0x'/'' + '[0-9]'*max(prec, len(x in octal)) - * worst case buf = '-0x' + [0-9]*prec, where prec >= 11 - */ - if (buflen <= 14 || buflen <= (size_t)3 + (size_t)prec) { - PyErr_SetString(PyExc_OverflowError, - "formatted integer is too long (precision too large?)"); - return -1; - } - - if ((flags & F_ALT) && - (type == 'x' || type == 'X' || type == 'o')) { - /* When converting under %#o, %#x or %#X, there are a number - * of issues that cause pain: - * - for %#o, we want a different base marker than C - * - when 0 is being converted, the C standard leaves off - * the '0x' or '0X', which is inconsistent with other - * %#x/%#X conversions and inconsistent with Python's - * hex() function - * - there are platforms that violate the standard and - * convert 0 with the '0x' or '0X' - * (Metrowerks, Compaq Tru64) - * - there are platforms that give '0x' when converting - * under %#X, but convert 0 in accordance with the - * standard (OS/2 EMX) - * - * We can achieve the desired consistency by inserting our - * own '0x' or '0X' prefix, and substituting %x/%X in place - * of %#x/%#X. - * - * Note that this is the same approach as used in - * formatint() in stringobject.c - */ - PyOS_snprintf(fmt, sizeof(fmt), "%s0%c%%.%dl%c", - sign, type, prec, type); - } - else { - PyOS_snprintf(fmt, sizeof(fmt), "%s%%%s.%dl%c", - sign, (flags&F_ALT) ? "#" : "", - prec, type); - } - if (sign[0]) - return longtounicode(buf, buflen, fmt, -x); - else - return longtounicode(buf, buflen, fmt, x); -} -#endif - static int formatchar(Py_UNICODE *buf, size_t buflen, @@ -9359,8 +9257,6 @@ case 'F': case 'g': case 'G': - if (c == 'F') - c = 'f'; pbuf = formatbuf; len = formatfloat(pbuf, sizeof(formatbuf)/sizeof(Py_UNICODE), flags, prec, c, v); Modified: python/branches/py3k/Python/marshal.c ============================================================================== --- python/branches/py3k/Python/marshal.c (original) +++ python/branches/py3k/Python/marshal.c Thu Apr 16 22:16:10 2009 @@ -236,12 +236,15 @@ w_string((char*)buf, 8, p); } else { - char buf[256]; /* Plenty to format any double */ - n = _PyFloat_Repr(PyFloat_AS_DOUBLE(v), - buf, sizeof(buf)); + char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v), + 'r', 0, 0, NULL); + if (!buf) + return; + n = strlen(buf); w_byte(TYPE_FLOAT, p); w_byte((int)n, p); w_string(buf, (int)n, p); + PyMem_Free(buf); } } #ifndef WITHOUT_COMPLEX @@ -263,17 +266,24 @@ w_string((char*)buf, 8, p); } else { - char buf[256]; /* Plenty to format any double */ + char *buf; w_byte(TYPE_COMPLEX, p); - n = _PyFloat_Repr(PyComplex_RealAsDouble(v), - buf, sizeof(buf)); + buf = PyOS_double_to_string(PyComplex_RealAsDouble(v), + 'r', 0, 0, NULL); + if (!buf) + return; n = strlen(buf); w_byte((int)n, p); w_string(buf, (int)n, p); - n = _PyFloat_Repr(PyComplex_ImagAsDouble(v), - buf, sizeof(buf)); + PyMem_Free(buf); + buf = PyOS_double_to_string(PyComplex_ImagAsDouble(v), + 'r', 0, 0, NULL); + if (!buf) + return; + n = strlen(buf); w_byte((int)n, p); w_string(buf, (int)n, p); + PyMem_Free(buf); } } #endif Modified: python/branches/py3k/Python/pystrtod.c ============================================================================== --- python/branches/py3k/Python/pystrtod.c (original) +++ python/branches/py3k/Python/pystrtod.c Thu Apr 16 22:16:10 2009 @@ -37,6 +37,38 @@ * * Return value: the #gdouble value. **/ + +#ifndef PY_NO_SHORT_FLOAT_REPR + +double +PyOS_ascii_strtod(const char *nptr, char **endptr) +{ + double result; + _Py_SET_53BIT_PRECISION_HEADER; + + assert(nptr != NULL); + /* Set errno to zero, so that we can distinguish zero results + and underflows */ + errno = 0; + + _Py_SET_53BIT_PRECISION_START; + result = _Py_dg_strtod(nptr, endptr); + _Py_SET_53BIT_PRECISION_END; + + return result; + +} + +#else + +/* + Use system strtod; since strtod is locale aware, we may + have to first fix the decimal separator. + + Note that unlike _Py_dg_strtod, the system strtod may not always give + correctly rounded results. +*/ + double PyOS_ascii_strtod(const char *nptr, char **endptr) { @@ -187,6 +219,15 @@ return val; } +#endif + +double +PyOS_ascii_atof(const char *nptr) +{ + return PyOS_ascii_strtod(nptr, NULL); +} + + /* Given a string that may have a decimal point in the current locale, change it back to a dot. Since the string cannot get longer, no need for a maximum buffer size parameter. */ @@ -292,8 +333,9 @@ } } -/* Ensure that buffer has a decimal point in it. The decimal point - will not be in the current locale, it will always be '.' */ +/* Ensure that buffer has a decimal point in it. The decimal point will not + be in the current locale, it will always be '.'. Don't add a decimal if an + exponent is present. */ Py_LOCAL_INLINE(void) ensure_decimal_point(char* buffer, size_t buf_size) { @@ -322,7 +364,8 @@ insert_count = 1; } } - else { + else if (!(*p == 'e' || *p == 'E')) { + /* Don't add ".0" if we have an exponent. */ chars_to_insert = ".0"; insert_count = 2; } @@ -341,37 +384,6 @@ } } -/* Add the locale specific grouping characters to buffer. Note - that any decimal point (if it's present) in buffer is already - locale-specific. Return 0 on error, else 1. */ -Py_LOCAL_INLINE(int) -add_thousands_grouping(char* buffer, size_t buf_size) -{ - Py_ssize_t len = strlen(buffer); - struct lconv *locale_data = localeconv(); - const char *decimal_point = locale_data->decimal_point; - - /* Find the decimal point, if any. We're only concerned - about the characters to the left of the decimal when - adding grouping. */ - char *p = strstr(buffer, decimal_point); - if (!p) { - /* No decimal, use the entire string. */ - - /* If any exponent, adjust p. */ - p = strpbrk(buffer, "eE"); - if (!p) - /* No exponent and no decimal. Use the entire - string. */ - p = buffer + len; - } - /* At this point, p points just past the right-most character we - want to format. We need to add the grouping string for the - characters between buffer and p. */ - return _PyBytes_InsertThousandsGroupingLocale(buffer, len, p-buffer, - buf_size, NULL, 1); -} - /* see FORMATBUFLEN in unicodeobject.c */ #define FLOAT_FORMATBUFLEN 120 @@ -386,9 +398,8 @@ * Converts a #gdouble to a string, using the '.' as * decimal point. To format the number you pass in * a printf()-style format string. Allowed conversion - * specifiers are 'e', 'E', 'f', 'F', 'g', 'G', and 'n'. + * specifiers are 'e', 'E', 'f', 'F', 'g', 'G', and 'Z'. * - * 'n' is the same as 'g', except it uses the current locale. * 'Z' is the same as 'g', except it always has a decimal and * at least one digit after the decimal. * @@ -403,11 +414,6 @@ char format_char; size_t format_len = strlen(format); - /* For type 'n', we need to make a copy of the format string, because - we're going to modify 'n' -> 'g', and format is const char*, so we - can't modify it directly. FLOAT_FORMATBUFLEN should be longer than - we ever need this to be. There's an upcoming check to ensure it's - big enough. */ /* Issue 2264: code 'Z' requires copying the format. 'Z' is 'g', but also with at least one character past the decimal. */ char tmp_format[FLOAT_FORMATBUFLEN]; @@ -433,12 +439,12 @@ if (!(format_char == 'e' || format_char == 'E' || format_char == 'f' || format_char == 'F' || format_char == 'g' || format_char == 'G' || - format_char == 'n' || format_char == 'Z')) + format_char == 'Z')) return NULL; - /* Map 'n' or 'Z' format_char to 'g', by copying the format string and + /* Map 'Z' format_char to 'g', by copying the format string and replacing the final char with a 'g' */ - if (format_char == 'n' || format_char == 'Z') { + if (format_char == 'Z') { if (format_len + 1 >= sizeof(tmp_format)) { /* The format won't fit in our copy. Error out. In practice, this will never happen and will be @@ -457,11 +463,8 @@ /* Do various fixups on the return string */ /* Get the current locale, and find the decimal point string. - Convert that string back to a dot. Do not do this if using the - 'n' (number) format code, since we want to keep the localized - decimal point in that case. */ - if (format_char != 'n') - change_decimal_from_locale_to_dot(buffer); + Convert that string back to a dot. */ + change_decimal_from_locale_to_dot(buffer); /* If an exponent exists, ensure that the exponent is at least MIN_EXPONENT_DIGITS digits, providing the buffer is large enough @@ -475,16 +478,497 @@ if (format_char == 'Z') ensure_decimal_point(buffer, buf_size); - /* If format_char is 'n', add the thousands grouping. */ - if (format_char == 'n') - if (!add_thousands_grouping(buffer, buf_size)) + return buffer; +} + +#ifdef PY_NO_SHORT_FLOAT_REPR + +/* The fallback code to use if _Py_dg_dtoa is not available. */ + +PyAPI_FUNC(char *) PyOS_double_to_string(double val, + char format_code, + int precision, + int flags, + int *type) +{ + char buf[128]; + char format[32]; + Py_ssize_t len; + char *result; + char *p; + int t; + int upper = 0; + + /* Validate format_code, and map upper and lower case */ + switch (format_code) { + case 'e': /* exponent */ + case 'f': /* fixed */ + case 'g': /* general */ + break; + case 'E': + upper = 1; + format_code = 'e'; + break; + case 'F': + upper = 1; + format_code = 'f'; + break; + case 'G': + upper = 1; + format_code = 'g'; + break; + case 'r': /* repr format */ + /* Supplied precision is unused, must be 0. */ + if (precision != 0) { + PyErr_BadInternalCall(); + return NULL; + } + precision = 17; + format_code = 'g'; + break; + case 's': /* str format */ + /* Supplied precision is unused, must be 0. */ + if (precision != 0) { + PyErr_BadInternalCall(); return NULL; + } + precision = 12; + format_code = 'g'; + break; + default: + PyErr_BadInternalCall(); + return NULL; + } - return buffer; + /* Handle nan and inf. */ + if (Py_IS_NAN(val)) { + strcpy(buf, "nan"); + t = Py_DTST_NAN; + } else if (Py_IS_INFINITY(val)) { + if (copysign(1., val) == 1.) + strcpy(buf, "inf"); + else + strcpy(buf, "-inf"); + t = Py_DTST_INFINITE; + } else { + t = Py_DTST_FINITE; + + + if (flags & Py_DTSF_ADD_DOT_0) + format_code = 'Z'; + + PyOS_snprintf(format, 32, "%%%s.%i%c", (flags & Py_DTSF_ALT ? "#" : ""), precision, format_code); + PyOS_ascii_formatd(buf, sizeof(buf), format, val); + } + + len = strlen(buf); + + /* Add 1 for the trailing 0 byte. + Add 1 because we might need to make room for the sign. + */ + result = PyMem_Malloc(len + 2); + if (result == NULL) { + PyErr_NoMemory(); + return NULL; + } + p = result; + + /* Never add sign for nan/inf, even if asked. */ + if (flags & Py_DTSF_SIGN && buf[0] != '-' && t == Py_DTST_FINITE) + *p++ = '+'; + + strcpy(p, buf); + + if (upper) { + /* Convert to upper case. */ + char *p1; + for (p1 = p; *p1; p1++) + *p1 = toupper(*p1); + } + + if (type) + *type = t; + return result; } -double -PyOS_ascii_atof(const char *nptr) +#else + +/* _Py_dg_dtoa is available. */ + +/* I'm using a lookup table here so that I don't have to invent a non-locale + specific way to convert to uppercase */ +#define OFS_INF 0 +#define OFS_NAN 1 +#define OFS_E 2 + +/* The lengths of these are known to the code below, so don't change them */ +static char *lc_float_strings[] = { + "inf", + "nan", + "e", +}; +static char *uc_float_strings[] = { + "INF", + "NAN", + "E", +}; + + +/* Convert a double d to a string, and return a PyMem_Malloc'd block of + memory contain the resulting string. + + Arguments: + d is the double to be converted + format_code is one of 'e', 'f', 'g', 'r' or 's'. 'e', 'f' and 'g' + correspond to '%e', '%f' and '%g'; 'r' and 's' correspond + to repr and str. + mode is one of '0', '2' or '3', and is completely determined by + format_code: 'e', 'g' and 's' use mode 2; 'f' mode 3, 'r' mode 0. + precision is the desired precision + always_add_sign is nonzero if a '+' sign should be included for positive + numbers + add_dot_0_if_integer is nonzero if integers in non-exponential form + should have ".0" added. Only applies to format codes 'r', 's', and 'g'. + use_alt_formatting is nonzero if alternative formatting should be + used. Only applies to format codes 'e', 'f' and 'g'. + type, if non-NULL, will be set to one of these constants to identify + the type of the 'd' argument: + Py_DTST_FINITE + Py_DTST_INFINITE + Py_DTST_NAN + + Returns a PyMem_Malloc'd block of memory containing the resulting string, + or NULL on error. If NULL is returned, the Python error has been set. + */ + +static char * +format_float_short(double d, char format_code, + int mode, Py_ssize_t precision, + int always_add_sign, int add_dot_0_if_integer, + int use_alt_formatting, char **float_strings, int *type) { - return PyOS_ascii_strtod(nptr, NULL); + char *buf = NULL; + char *p = NULL; + Py_ssize_t bufsize = 0; + char *digits, *digits_end; + int decpt_as_int, sign, exp_len, exp = 0, use_exp = 0; + Py_ssize_t decpt, digits_len, vdigits_start, vdigits_end; + _Py_SET_53BIT_PRECISION_HEADER; + + /* _Py_dg_dtoa returns a digit string (no decimal point or exponent). + Must be matched by a call to _Py_dg_freedtoa. */ + _Py_SET_53BIT_PRECISION_START; + digits = _Py_dg_dtoa(d, mode, precision, &decpt_as_int, &sign, + &digits_end); + _Py_SET_53BIT_PRECISION_END; + + decpt = (Py_ssize_t)decpt_as_int; + if (digits == NULL) { + /* The only failure mode is no memory. */ + PyErr_NoMemory(); + goto exit; + } + assert(digits_end != NULL && digits_end >= digits); + digits_len = digits_end - digits; + + if (digits_len && !isdigit(digits[0])) { + /* Infinities and nans here; adapt Gay's output, + so convert Infinity to inf and NaN to nan, and + ignore sign of nan. Then return. */ + + /* We only need 5 bytes to hold the result "+inf\0" . */ + bufsize = 5; /* Used later in an assert. */ + buf = (char *)PyMem_Malloc(bufsize); + if (buf == NULL) { + PyErr_NoMemory(); + goto exit; + } + p = buf; + + if (digits[0] == 'i' || digits[0] == 'I') { + if (sign == 1) { + *p++ = '-'; + } + else if (always_add_sign) { + *p++ = '+'; + } + strncpy(p, float_strings[OFS_INF], 3); + p += 3; + + if (type) + *type = Py_DTST_INFINITE; + } + else if (digits[0] == 'n' || digits[0] == 'N') { + /* note that we *never* add a sign for a nan, + even if one has explicitly been requested */ + strncpy(p, float_strings[OFS_NAN], 3); + p += 3; + + if (type) + *type = Py_DTST_NAN; + } + else { + /* shouldn't get here: Gay's code should always return + something starting with a digit, an 'I', or 'N' */ + strncpy(p, "ERR", 3); + p += 3; + assert(0); + } + goto exit; + } + + /* The result must be finite (not inf or nan). */ + if (type) + *type = Py_DTST_FINITE; + + + /* We got digits back, format them. We may need to pad 'digits' + either on the left or right (or both) with extra zeros, so in + general the resulting string has the form + + [][] + + where either of the pieces could be empty, and there's a + decimal point that could appear either in or in the + leading or trailing . + + Imagine an infinite 'virtual' string vdigits, consisting of the + string 'digits' (starting at index 0) padded on both the left and + right with infinite strings of zeros. We want to output a slice + + vdigits[vdigits_start : vdigits_end] + + of this virtual string. Thus if vdigits_start < 0 then we'll end + up producing some leading zeros; if vdigits_end > digits_len there + will be trailing zeros in the output. The next section of code + determines whether to use an exponent or not, figures out the + position 'decpt' of the decimal point, and computes 'vdigits_start' + and 'vdigits_end'. */ + vdigits_end = digits_len; + switch (format_code) { + case 'e': + use_exp = 1; + vdigits_end = precision; + break; + case 'f': + vdigits_end = decpt + precision; + break; + case 'g': + if (decpt <= -4 || decpt > precision) + use_exp = 1; + if (use_alt_formatting) + vdigits_end = precision; + break; + case 'r': + /* convert to exponential format at 1e16. We used to convert + at 1e17, but that gives odd-looking results for some values + when a 16-digit 'shortest' repr is padded with bogus zeros. + For example, repr(2e16+8) would give 20000000000000010.0; + the true value is 20000000000000008.0. */ + if (decpt <= -4 || decpt > 16) + use_exp = 1; + break; + case 's': + /* if we're forcing a digit after the point, convert to + exponential format at 1e11. If not, convert at 1e12. */ + if (decpt <= -4 || decpt > + (add_dot_0_if_integer ? precision-1 : precision)) + use_exp = 1; + break; + default: + PyErr_BadInternalCall(); + goto exit; + } + + /* if using an exponent, reset decimal point position to 1 and adjust + exponent accordingly.*/ + if (use_exp) { + exp = decpt - 1; + decpt = 1; + } + /* ensure vdigits_start < decpt <= vdigits_end, or vdigits_start < + decpt < vdigits_end if add_dot_0_if_integer and no exponent */ + vdigits_start = decpt <= 0 ? decpt-1 : 0; + if (!use_exp && add_dot_0_if_integer) + vdigits_end = vdigits_end > decpt ? vdigits_end : decpt + 1; + else + vdigits_end = vdigits_end > decpt ? vdigits_end : decpt; + + /* double check inequalities */ + assert(vdigits_start <= 0 && + 0 <= digits_len && + digits_len <= vdigits_end); + /* decimal point should be in (vdigits_start, vdigits_end] */ + assert(vdigits_start < decpt && decpt <= vdigits_end); + + /* Compute an upper bound how much memory we need. This might be a few + chars too long, but no big deal. */ + bufsize = + /* sign, decimal point and trailing 0 byte */ + 3 + + + /* total digit count (including zero padding on both sides) */ + (vdigits_end - vdigits_start) + + + /* exponent "e+100", max 3 numerical digits */ + (use_exp ? 5 : 0); + + /* Now allocate the memory and initialize p to point to the start of + it. */ + buf = (char *)PyMem_Malloc(bufsize); + if (buf == NULL) { + PyErr_NoMemory(); + goto exit; + } + p = buf; + + /* Add a negative sign if negative, and a plus sign if non-negative + and always_add_sign is true. */ + if (sign == 1) + *p++ = '-'; + else if (always_add_sign) + *p++ = '+'; + + /* note that exactly one of the three 'if' conditions is true, + so we include exactly one decimal point */ + /* Zero padding on left of digit string */ + if (decpt <= 0) { + memset(p, '0', decpt-vdigits_start); + p += decpt - vdigits_start; + *p++ = '.'; + memset(p, '0', 0-decpt); + p += 0-decpt; + } + else { + memset(p, '0', 0-vdigits_start); + p += 0 - vdigits_start; + } + + /* Digits, with included decimal point */ + if (0 < decpt && decpt <= digits_len) { + strncpy(p, digits, decpt-0); + p += decpt-0; + *p++ = '.'; + strncpy(p, digits+decpt, digits_len-decpt); + p += digits_len-decpt; + } + else { + strncpy(p, digits, digits_len); + p += digits_len; + } + + /* And zeros on the right */ + if (digits_len < decpt) { + memset(p, '0', decpt-digits_len); + p += decpt-digits_len; + *p++ = '.'; + memset(p, '0', vdigits_end-decpt); + p += vdigits_end-decpt; + } + else { + memset(p, '0', vdigits_end-digits_len); + p += vdigits_end-digits_len; + } + + /* Delete a trailing decimal pt unless using alternative formatting. */ + if (p[-1] == '.' && !use_alt_formatting) + p--; + + /* Now that we've done zero padding, add an exponent if needed. */ + if (use_exp) { + *p++ = float_strings[OFS_E][0]; + exp_len = sprintf(p, "%+.02d", exp); + p += exp_len; + } + exit: + if (buf) { + *p = '\0'; + /* It's too late if this fails, as we've already stepped on + memory that isn't ours. But it's an okay debugging test. */ + assert(p-buf < bufsize); + } + if (digits) + _Py_dg_freedtoa(digits); + + return buf; +} + + +PyAPI_FUNC(char *) PyOS_double_to_string(double val, + char format_code, + int precision, + int flags, + int *type) +{ + char lc_format_code = format_code; + char** float_strings = lc_float_strings; + int mode = 0; + + /* Validate format_code, and map upper and lower case */ + switch (format_code) { + case 'e': /* exponent */ + case 'f': /* fixed */ + case 'g': /* general */ + case 'r': /* repr format */ + case 's': /* str format */ + break; + case 'E': + lc_format_code = 'e'; + break; + case 'F': + lc_format_code = 'f'; + break; + case 'G': + lc_format_code = 'g'; + break; + default: + PyErr_BadInternalCall(); + return NULL; + } + + if (format_code != lc_format_code) + float_strings = uc_float_strings; + + /* From the format code, compute the mode and make any adjustments as + needed. */ + switch (lc_format_code) { + case 'e': + mode = 2; + precision++; + break; + case 'f': + mode = 3; + break; + case 'g': + mode = 2; + /* precision 0 makes no sense for 'g' format; interpret as 1 */ + if (precision == 0) + precision = 1; + break; + case 'r': + /* "repr" pseudo-mode */ + mode = 0; + /* Supplied precision is unused, must be 0. */ + if (precision != 0) { + PyErr_BadInternalCall(); + return NULL; + } + break; + case 's': + mode = 2; + /* Supplied precision is unused, must be 0. */ + if (precision != 0) { + PyErr_BadInternalCall(); + return NULL; + } + precision = 12; + break; + } + + return format_float_short(val, lc_format_code, mode, precision, + flags & Py_DTSF_SIGN, + flags & Py_DTSF_ADD_DOT_0, + flags & Py_DTSF_ALT, + float_strings, type); } +#endif /* ifdef PY_NO_SHORT_FLOAT_REPR */ From python-checkins at python.org Thu Apr 16 22:16:50 2009 From: python-checkins at python.org (eric.smith) Date: Thu, 16 Apr 2009 22:16:50 +0200 (CEST) Subject: [Python-checkins] r71666 - python/branches/release30-maint Message-ID: <20090416201650.19CA71E4017@bag.python.org> Author: eric.smith Date: Thu Apr 16 22:16:49 2009 New Revision: 71666 Log: Blocked revisions 71665 via svnmerge ........ r71665 | eric.smith | 2009-04-16 16:16:10 -0400 (Thu, 16 Apr 2009) | 14 lines The other half of Issue #1580: use short float repr where possible. Addresses the float -> string conversion, using David Gay's code which was added in Mark Dickinson's checkin r71663. Also addresses these, which are intertwined with the short repr changes: - Issue #5772: format(1e100, '<') produces '1e+100', not '1.0e+100' - Issue #5515: 'n' formatting with commas no longer works poorly with leading zeros. - PEP 378 Format Specifier for Thousands Separator: implemented for floats. ........ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Thu Apr 16 22:21:29 2009 From: python-checkins at python.org (eric.smith) Date: Thu, 16 Apr 2009 22:21:29 +0200 (CEST) Subject: [Python-checkins] r71667 - python/branches/py3k/Misc/NEWS Message-ID: <20090416202129.0F4971E4014@bag.python.org> Author: eric.smith Date: Thu Apr 16 22:21:28 2009 New Revision: 71667 Log: Better wording for Issue #5515 entry. Modified: python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Apr 16 22:21:28 2009 @@ -14,9 +14,8 @@ - Issue #5772: format(1e100, '<') produces '1e+100', not '1.0e+100'. -- Issue #5515: str.format() presentation type 'n' with commas no - longer works poorly with leading zeros when formatting ints and - floats. +- Issue #5515: str.format() type 'n' combined with commas and leading + zeros no longer gives odd results with ints and floats. - Implement PEP 378, Format Specifier for Thousands Separator, for floats. From buildbot at python.org Thu Apr 16 22:39:28 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 16 Apr 2009 20:39:28 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090416203928.DD75D1E4013@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/270 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_posix test_subprocess ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From python-checkins at python.org Fri Apr 17 00:08:31 2009 From: python-checkins at python.org (eric.smith) Date: Fri, 17 Apr 2009 00:08:31 +0200 (CEST) Subject: [Python-checkins] r71668 - python/branches/py3k/Python/pystrtod.c Message-ID: <20090416220831.4ABDC1E4045@bag.python.org> Author: eric.smith Date: Fri Apr 17 00:08:31 2009 New Revision: 71668 Log: Simplify PyOS_double_to_string. Modified: python/branches/py3k/Python/pystrtod.c Modified: python/branches/py3k/Python/pystrtod.c ============================================================================== --- python/branches/py3k/Python/pystrtod.c (original) +++ python/branches/py3k/Python/pystrtod.c Fri Apr 17 00:08:31 2009 @@ -895,58 +895,50 @@ PyAPI_FUNC(char *) PyOS_double_to_string(double val, - char format_code, - int precision, - int flags, + char format_code, + int precision, + int flags, int *type) { - char lc_format_code = format_code; - char** float_strings = lc_float_strings; - int mode = 0; + char **float_strings = lc_float_strings; + int mode; - /* Validate format_code, and map upper and lower case */ + /* Validate format_code, and map upper and lower case. Compute the + mode and make any adjustments as needed. */ switch (format_code) { - case 'e': /* exponent */ - case 'f': /* fixed */ - case 'g': /* general */ - case 'r': /* repr format */ - case 's': /* str format */ - break; + /* exponent */ case 'E': - lc_format_code = 'e'; - break; - case 'F': - lc_format_code = 'f'; - break; - case 'G': - lc_format_code = 'g'; - break; - default: - PyErr_BadInternalCall(); - return NULL; - } - - if (format_code != lc_format_code) float_strings = uc_float_strings; - - /* From the format code, compute the mode and make any adjustments as - needed. */ - switch (lc_format_code) { + format_code = 'e'; + /* Fall through. */ case 'e': mode = 2; precision++; break; + + /* fixed */ + case 'F': + float_strings = uc_float_strings; + format_code = 'f'; + /* Fall through. */ case 'f': mode = 3; break; + + /* general */ + case 'G': + float_strings = uc_float_strings; + format_code = 'g'; + /* Fall through. */ case 'g': mode = 2; /* precision 0 makes no sense for 'g' format; interpret as 1 */ if (precision == 0) precision = 1; break; + + /* repr format */ case 'r': - /* "repr" pseudo-mode */ mode = 0; /* Supplied precision is unused, must be 0. */ if (precision != 0) { @@ -954,6 +946,8 @@ return NULL; } break; + + /* str format */ case 's': mode = 2; /* Supplied precision is unused, must be 0. */ @@ -963,9 +957,13 @@ } precision = 12; break; + + default: + PyErr_BadInternalCall(); + return NULL; } - return format_float_short(val, lc_format_code, mode, precision, + return format_float_short(val, format_code, mode, precision, flags & Py_DTSF_SIGN, flags & Py_DTSF_ADD_DOT_0, flags & Py_DTSF_ALT, From python-checkins at python.org Fri Apr 17 02:11:54 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 17 Apr 2009 02:11:54 +0200 (CEST) Subject: [Python-checkins] r71669 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090417001154.E9B131E40B8@bag.python.org> Author: raymond.hettinger Date: Fri Apr 17 02:11:54 2009 New Revision: 71669 Log: Ladies and gentlemen, the new float.__repr__() has arrived. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Fri Apr 17 02:11:54 2009 @@ -148,6 +148,43 @@ (Contributed by Mark Dickinson; :issue:`4707`.) +* Python now uses David Gay's algorithm for finding the shortest floating + point representation that doesn't change its value. This should help + mitigate the some of the confusion surrounding binary floating point + numbers. + + The significance is easily seen with a number like ``1.1`` which does not + have an exact equivalent in binary floating point. Since there is no exact + equivalent, an expression like ``float("1.1")`` evaluates to the nearest + representable value which is ``0x1.199999999999ap+0`` in hex or + ``1.100000000000000088817841970012523233890533447265625`` in decimal. That + nearest value was and still is used in subsequent floating point + calculations. + + What is new is how the number gets displayed. Formerly, Python used a + simple approach. The value of ``repr(1.1)`` was computed as ``format(1.1, + '.17g')`` which evaluates to ``'1.1000000000000001'``. The advantage of + using 17 digits was that it relied on IEEE-754 guarantees to assure that + ``eval(repr(1.1))`` would round-trip exactly to its original value. The + disadvantage is that many people found the output to be confusing (mistaking + intrinsic limitations of binary floating point representation as being a + problem with Python itself). + + The new algorithm for ``repr(1.1)`` is smarter and returns ``1.1``. + Effectively, it searches all equivalent string representations (ones that + get stored as the same underlying float value) and returns the shortest + representation. + + The new algorithm tends to emit cleaner representations when possible, but + it does not change the underlying values. So, it is still the case that + ``1.1 + 2.2 != 3.3`` even though the representations may suggest otherwise. + + The new algorithm depends on certain features in the underlying floating + point implementation. If the required features are not found, the old + algorithm will continue to be used. Also, the text pickle protocols + assure cross-platform portability by using the old algorithm. + + (Contributed by Eric Smith and Mark Dickinson; :issue:`1580`) New, Improved, and Deprecated Modules ===================================== From nnorwitz at gmail.com Fri Apr 17 10:11:28 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 17 Apr 2009 04:11:28 -0400 Subject: [Python-checkins] Python Regression Test Failures basics (1) Message-ID: <20090417081128.GA6151@python.psfb.org> 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23366 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 test_lib2to3 failed -- errors occurred; run in verbose mode for details 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 -- OSError raises on RLock creation, see issue 3111! test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18065 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [742112 refs] From nnorwitz at gmail.com Fri Apr 17 10:19:22 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 17 Apr 2009 04:19:22 -0400 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20090417081922.GA8603@python.psfb.org> 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils [17363 refs] [17363 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23366 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 test_lib2to3 failed -- errors occurred; run in verbose mode for details 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 -- OSError raises on RLock creation, see issue 3111! test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18902 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [741352 refs] From python-checkins at python.org Fri Apr 17 10:41:24 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 17 Apr 2009 10:41:24 +0200 (CEST) Subject: [Python-checkins] r71670 - in python/branches/py3k: Modules/_pickle.c Python/marshal.c Message-ID: <20090417084124.4BA411E401B@bag.python.org> Author: mark.dickinson Date: Fri Apr 17 10:41:23 2009 New Revision: 71670 Log: Make sure that marshal and pickle continue to output 17 digits of precision for floats. Modified: python/branches/py3k/Modules/_pickle.c python/branches/py3k/Python/marshal.c Modified: python/branches/py3k/Modules/_pickle.c ============================================================================== --- python/branches/py3k/Modules/_pickle.c (original) +++ python/branches/py3k/Modules/_pickle.c Fri Apr 17 10:41:23 2009 @@ -1025,7 +1025,7 @@ if (pickler_write(self, &op, 1) < 0) goto done; - buf = PyOS_double_to_string(x, 'r', 0, 0, NULL); + buf = PyOS_double_to_string(x, 'g', 17, 0, NULL); if (!buf) { PyErr_NoMemory(); goto done; Modified: python/branches/py3k/Python/marshal.c ============================================================================== --- python/branches/py3k/Python/marshal.c (original) +++ python/branches/py3k/Python/marshal.c Fri Apr 17 10:41:23 2009 @@ -237,7 +237,7 @@ } else { char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v), - 'r', 0, 0, NULL); + 'g', 17, 0, NULL); if (!buf) return; n = strlen(buf); @@ -269,7 +269,7 @@ char *buf; w_byte(TYPE_COMPLEX, p); buf = PyOS_double_to_string(PyComplex_RealAsDouble(v), - 'r', 0, 0, NULL); + 'g', 17, 0, NULL); if (!buf) return; n = strlen(buf); @@ -277,7 +277,7 @@ w_string(buf, (int)n, p); PyMem_Free(buf); buf = PyOS_double_to_string(PyComplex_ImagAsDouble(v), - 'r', 0, 0, NULL); + 'g', 17, 0, NULL); if (!buf) return; n = strlen(buf); From dickinsm at gmail.com Fri Apr 17 10:44:36 2009 From: dickinsm at gmail.com (Mark Dickinson) Date: Fri, 17 Apr 2009 09:44:36 +0100 Subject: [Python-checkins] r71669 - python/branches/py3k/Doc/whatsnew/3.1.rst In-Reply-To: <20090417001154.E9B131E40B8@bag.python.org> References: <20090417001154.E9B131E40B8@bag.python.org> Message-ID: <5c6f2a5d0904170144i1f1d2f85oa2bdb77c08297253@mail.gmail.com> On Fri, Apr 17, 2009 at 1:11 AM, raymond.hettinger wrote: > Modified: > ? python/branches/py3k/Doc/whatsnew/3.1.rst Very nice description. Thank you. > + ?algorithm will continue to be used. ?Also, the text pickle protocols > + ?assure cross-platform portability by using the old algorithm. And that should actually be true, now. See r71670. Mark From python-checkins at python.org Fri Apr 17 11:45:20 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 17 Apr 2009 11:45:20 +0200 (CEST) Subject: [Python-checkins] r71671 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090417094520.0E9071E403B@bag.python.org> Author: raymond.hettinger Date: Fri Apr 17 11:45:19 2009 New Revision: 71671 Log: Nits. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Fri Apr 17 11:45:19 2009 @@ -155,7 +155,7 @@ The significance is easily seen with a number like ``1.1`` which does not have an exact equivalent in binary floating point. Since there is no exact - equivalent, an expression like ``float("1.1")`` evaluates to the nearest + equivalent, an expression like ``float('1.1')`` evaluates to the nearest representable value which is ``0x1.199999999999ap+0`` in hex or ``1.100000000000000088817841970012523233890533447265625`` in decimal. That nearest value was and still is used in subsequent floating point @@ -163,16 +163,16 @@ What is new is how the number gets displayed. Formerly, Python used a simple approach. The value of ``repr(1.1)`` was computed as ``format(1.1, - '.17g')`` which evaluates to ``'1.1000000000000001'``. The advantage of + '.17g')`` which evaluated to ``'1.1000000000000001'``. The advantage of using 17 digits was that it relied on IEEE-754 guarantees to assure that ``eval(repr(1.1))`` would round-trip exactly to its original value. The disadvantage is that many people found the output to be confusing (mistaking intrinsic limitations of binary floating point representation as being a problem with Python itself). - The new algorithm for ``repr(1.1)`` is smarter and returns ``1.1``. + The new algorithm for ``repr(1.1)`` is smarter and returns ``'1.1'``. Effectively, it searches all equivalent string representations (ones that - get stored as the same underlying float value) and returns the shortest + get stored with the same underlying float value) and returns the shortest representation. The new algorithm tends to emit cleaner representations when possible, but From python-checkins at python.org Fri Apr 17 12:09:28 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 17 Apr 2009 12:09:28 +0200 (CEST) Subject: [Python-checkins] r71672 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090417100928.12DCB1E401B@bag.python.org> Author: raymond.hettinger Date: Fri Apr 17 12:09:27 2009 New Revision: 71672 Log: Update list of supported types. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Fri Apr 17 12:09:27 2009 @@ -93,8 +93,8 @@ >>> format(Decimal('1234567.89'), ',f') '1,234,567.89' -The currently supported types are :class:`int` and :class:`decimal.Decimal`. -Support for :class:`float` is expected before the beta release. +The supported types are :class:`int`, :class:`float` and :class:`decimal.Decimal`. + Discussions are underway about how to specify alternative separators like dots, spaces, apostrophes, or underscores. Locale-aware applications should use the existing *n* format specifier which already has some support From python-checkins at python.org Fri Apr 17 14:33:24 2009 From: python-checkins at python.org (eric.smith) Date: Fri, 17 Apr 2009 14:33:24 +0200 (CEST) Subject: [Python-checkins] r71673 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090417123324.8F9D21E401B@bag.python.org> Author: eric.smith Date: Fri Apr 17 14:33:24 2009 New Revision: 71673 Log: Nit. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Fri Apr 17 14:33:24 2009 @@ -150,7 +150,7 @@ * Python now uses David Gay's algorithm for finding the shortest floating point representation that doesn't change its value. This should help - mitigate the some of the confusion surrounding binary floating point + mitigate some of the confusion surrounding binary floating point numbers. The significance is easily seen with a number like ``1.1`` which does not From python-checkins at python.org Fri Apr 17 16:29:56 2009 From: python-checkins at python.org (tarek.ziade) Date: Fri, 17 Apr 2009 16:29:56 +0200 (CEST) Subject: [Python-checkins] r71674 - in python/trunk/Lib/distutils: command/check.py tests/test_check.py Message-ID: <20090417142956.8AC921E4010@bag.python.org> Author: tarek.ziade Date: Fri Apr 17 16:29:56 2009 New Revision: 71674 Log: DistutilsSetupError was not raised when one single warning occured Modified: python/trunk/Lib/distutils/command/check.py python/trunk/Lib/distutils/tests/test_check.py Modified: python/trunk/Lib/distutils/command/check.py ============================================================================== --- python/trunk/Lib/distutils/command/check.py (original) +++ python/trunk/Lib/distutils/command/check.py Fri Apr 17 16:29:56 2009 @@ -72,7 +72,7 @@ # let's raise an error in strict mode, if we have at least # one warning - if self.strict and self._warnings > 1: + if self.strict and self._warnings > 0: raise DistutilsSetupError('Please correct your package.') def check_metadata(self): Modified: python/trunk/Lib/distutils/tests/test_check.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_check.py (original) +++ python/trunk/Lib/distutils/tests/test_check.py Fri Apr 17 16:29:56 2009 @@ -72,17 +72,16 @@ self.assertEquals(cmd._warnings, 1) # let's see if we have an error with strict=1 - cmd = check(dist) - cmd.initialize_options() - cmd.strict = 1 - cmd.ensure_finalized() - self.assertRaises(DistutilsSetupError, cmd.run) + metadata = {'url': 'xxx', 'author': 'xxx', + 'author_email': 'xxx', + 'name': 'xxx', 'version': 'xxx', + 'long_description': broken_rest} + self.assertRaises(DistutilsSetupError, self._run, metadata, + **{'strict': 1, 'restructuredtext': 1}) # and non-broken rest - rest = 'title\n=====\n\ntest' - pkg_info, dist = self.create_dist(long_description=rest) - cmd = check(dist) - cmd.check_restructuredtext() + metadata['long_description'] = 'title\n=====\n\ntest' + cmd = self._run(metadata, strict=1, restructuredtext=1) self.assertEquals(cmd._warnings, 0) def test_check_all(self): From python-checkins at python.org Fri Apr 17 16:32:47 2009 From: python-checkins at python.org (tarek.ziade) Date: Fri, 17 Apr 2009 16:32:47 +0200 (CEST) Subject: [Python-checkins] r71675 - python/branches/release26-maint Message-ID: <20090417143247.390D51E4010@bag.python.org> Author: tarek.ziade Date: Fri Apr 17 16:32:46 2009 New Revision: 71675 Log: Blocked revisions 71589 via svnmerge ........ r71589 | tarek.ziade | 2009-04-13 22:14:54 +0200 (Mon, 13 Apr 2009) | 1 line pep8-fied ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Fri Apr 17 16:33:44 2009 From: python-checkins at python.org (tarek.ziade) Date: Fri, 17 Apr 2009 16:33:44 +0200 (CEST) Subject: [Python-checkins] r71676 - python/branches/release26-maint Message-ID: <20090417143344.6A9441E4022@bag.python.org> Author: tarek.ziade Date: Fri Apr 17 16:33:43 2009 New Revision: 71676 Log: Blocked revisions 71674 via svnmerge ........ r71674 | tarek.ziade | 2009-04-17 16:29:56 +0200 (Fri, 17 Apr 2009) | 1 line DistutilsSetupError was not raised when one single warning occured ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Fri Apr 17 16:34:50 2009 From: python-checkins at python.org (tarek.ziade) Date: Fri, 17 Apr 2009 16:34:50 +0200 (CEST) Subject: [Python-checkins] r71677 - in python/branches/py3k: Lib/distutils/command/check.py Lib/distutils/tests/test_check.py Message-ID: <20090417143450.32E6E1E4010@bag.python.org> Author: tarek.ziade Date: Fri Apr 17 16:34:49 2009 New Revision: 71677 Log: Merged revisions 71674 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71674 | tarek.ziade | 2009-04-17 16:29:56 +0200 (Fri, 17 Apr 2009) | 1 line DistutilsSetupError was not raised when one single warning occured ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/command/check.py python/branches/py3k/Lib/distutils/tests/test_check.py Modified: python/branches/py3k/Lib/distutils/command/check.py ============================================================================== --- python/branches/py3k/Lib/distutils/command/check.py (original) +++ python/branches/py3k/Lib/distutils/command/check.py Fri Apr 17 16:34:49 2009 @@ -73,7 +73,7 @@ # let's raise an error in strict mode, if we have at least # one warning - if self.strict and self._warnings > 1: + if self.strict and self._warnings > 0: raise DistutilsSetupError('Please correct your package.') def check_metadata(self): Modified: python/branches/py3k/Lib/distutils/tests/test_check.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_check.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_check.py Fri Apr 17 16:34:49 2009 @@ -72,17 +72,16 @@ self.assertEquals(cmd._warnings, 1) # let's see if we have an error with strict=1 - cmd = check(dist) - cmd.initialize_options() - cmd.strict = 1 - cmd.ensure_finalized() - self.assertRaises(DistutilsSetupError, cmd.run) + metadata = {'url': 'xxx', 'author': 'xxx', + 'author_email': 'xxx', + 'name': 'xxx', 'version': 'xxx', + 'long_description': broken_rest} + self.assertRaises(DistutilsSetupError, self._run, metadata, + **{'strict': 1, 'restructuredtext': 1}) # and non-broken rest - rest = 'title\n=====\n\ntest' - pkg_info, dist = self.create_dist(long_description=rest) - cmd = check(dist) - cmd.check_restructuredtext() + metadata['long_description'] = 'title\n=====\n\ntest' + cmd = self._run(metadata, strict=1, restructuredtext=1) self.assertEquals(cmd._warnings, 0) def test_check_all(self): From python-checkins at python.org Fri Apr 17 16:36:15 2009 From: python-checkins at python.org (tarek.ziade) Date: Fri, 17 Apr 2009 16:36:15 +0200 (CEST) Subject: [Python-checkins] r71678 - python/branches/release30-maint Message-ID: <20090417143615.2DB341E4010@bag.python.org> Author: tarek.ziade Date: Fri Apr 17 16:36:14 2009 New Revision: 71678 Log: Blocked revisions 71590 via svnmerge ................ r71590 | tarek.ziade | 2009-04-13 22:19:58 +0200 (Mon, 13 Apr 2009) | 9 lines Merged revisions 71589 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71589 | tarek.ziade | 2009-04-13 22:14:54 +0200 (Mon, 13 Apr 2009) | 1 line pep8-fied ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Fri Apr 17 16:38:24 2009 From: python-checkins at python.org (tarek.ziade) Date: Fri, 17 Apr 2009 16:38:24 +0200 (CEST) Subject: [Python-checkins] r71679 - python/branches/release30-maint Message-ID: <20090417143824.2F6711E4010@bag.python.org> Author: tarek.ziade Date: Fri Apr 17 16:38:23 2009 New Revision: 71679 Log: Blocked revisions 71677 via svnmerge ................ r71677 | tarek.ziade | 2009-04-17 16:34:49 +0200 (Fri, 17 Apr 2009) | 9 lines Merged revisions 71674 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71674 | tarek.ziade | 2009-04-17 16:29:56 +0200 (Fri, 17 Apr 2009) | 1 line DistutilsSetupError was not raised when one single warning occured ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Fri Apr 17 17:45:52 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 17 Apr 2009 17:45:52 +0200 (CEST) Subject: [Python-checkins] r71680 - in python/branches/py3k-short-float-repr: Objects/floatobject.c Python/dtoa.c Message-ID: <20090417154552.59CBE1E411D@bag.python.org> Author: mark.dickinson Date: Fri Apr 17 17:45:51 2009 New Revision: 71680 Log: Add reminder to check for updates to dtoa.c from time to time. Modified: python/branches/py3k-short-float-repr/Objects/floatobject.c python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Objects/floatobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/floatobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/floatobject.c Fri Apr 17 17:45:51 2009 @@ -899,13 +899,62 @@ return PyLong_FromDouble(wholepart); } +/* round a C double x to the closest multiple of 10**-ndigits */ + +static double +double_round(double x, int ndigits) { + char *buf, *buf_end, shortbuf[20]; + char *mybuf = shortbuf; + int decpt, sign, buflen, mybuflen = 20; + double rounded = -1.0; + + mybuf = shortbuf; + + /* first convert to decimal, as a string; then add sign, exp, and + extra '0 to avoid trouble when buf_end == buf, then convert back. */ + buf = _Py_dg_dtoa(x, 3, ndigits, &decpt, &sign, &buf_end); + printf("buf is %p\n", buf); + if (buf == NULL) { + PyErr_NoMemory(); + goto exit1; + } + buflen = buf_end - buf; + + printf("result is %s\n", buf); + + /* total buffer space needed <= (buf_end - buf) + 8: (1 extra for '0', + 1 for the sign, 5 for exponent, 1 for '\0') */ + if (buflen + 8 > mybuflen) { + mybuflen = buflen+8; + mybuf = (char *)PyMem_Malloc(mybuflen); + if (mybuf == NULL) { + PyErr_NoMemory(); + goto exit2; + } + } + PyOS_snprintf(mybuf, mybuflen, "%s0%se%d", (sign ? "-" : ""), + buf, decpt - buflen); + printf("Checkpoint 1!\n"); + rounded = _Py_dg_strtod(mybuf, NULL); + printf("Checkpoint 2!\n"); + + /* done computing value; now clean up */ + if (mybuf != shortbuf) + PyMem_Free(mybuf); + exit2: + printf("Checkpoint 3!\n"); + printf("buf is %p\n", buf); + _Py_dg_freedtoa(buf); + printf("Checkpoint 4!\n"); + exit1: + return rounded; +} + static PyObject * float_round(PyObject *v, PyObject *args) { #define UNDEF_NDIGITS (-0x7fffffff) /* Unlikely ndigits value */ double x; - double f = 1.0; - double flr, cil; double rounded; int ndigits = UNDEF_NDIGITS; @@ -913,28 +962,13 @@ return NULL; x = PyFloat_AsDouble(v); - - if (ndigits != UNDEF_NDIGITS) { - f = pow(10.0, ndigits); - x *= f; + if (ndigits == UNDEF_NDIGITS) { + rounded = round(x); + if (fabs(x-rounded) == 0.5) + rounded = 2.0*round(x/2.0); + return PyLong_FromDouble(rounded); } - - flr = floor(x); - cil = ceil(x); - - if (x-flr > 0.5) - rounded = cil; - else if (x-flr == 0.5) - rounded = fmod(flr, 2) == 0 ? flr : cil; - else - rounded = flr; - - if (ndigits != UNDEF_NDIGITS) { - rounded /= f; - return PyFloat_FromDouble(rounded); - } - - return PyLong_FromDouble(rounded); + return PyFloat_FromDouble(double_round(x, ndigits)); #undef UNDEF_NDIGITS } Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Fri Apr 17 17:45:51 2009 @@ -21,7 +21,11 @@ * This is dtoa.c by David M. Gay, downloaded from * http://www.netlib.org/fp/dtoa.c on April 15, 2009 and modified for * inclusion into the Python core by Mark E. T. Dickinson and Eric V. Smith. - * The major modifications are as follows: + * + * Please remember to check http://www.netlib.org/fp regularly (and especially + * before any Python release) for bugfixes and updates. + * + * The major modifications from Gay's original code are as follows: * * 0. The original code has been specialized to Python's needs by removing * many of the #ifdef'd sections. In particular, code to support VAX and From python-checkins at python.org Fri Apr 17 17:48:45 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 17 Apr 2009 17:48:45 +0200 (CEST) Subject: [Python-checkins] r71681 - python/branches/py3k-short-float-repr/Objects/floatobject.c Message-ID: <20090417154845.995DD1E4010@bag.python.org> Author: mark.dickinson Date: Fri Apr 17 17:48:44 2009 New Revision: 71681 Log: Undo accidental commit of Objects/floatobject.c changes. Modified: python/branches/py3k-short-float-repr/Objects/floatobject.c Modified: python/branches/py3k-short-float-repr/Objects/floatobject.c ============================================================================== --- python/branches/py3k-short-float-repr/Objects/floatobject.c (original) +++ python/branches/py3k-short-float-repr/Objects/floatobject.c Fri Apr 17 17:48:44 2009 @@ -899,62 +899,13 @@ return PyLong_FromDouble(wholepart); } -/* round a C double x to the closest multiple of 10**-ndigits */ - -static double -double_round(double x, int ndigits) { - char *buf, *buf_end, shortbuf[20]; - char *mybuf = shortbuf; - int decpt, sign, buflen, mybuflen = 20; - double rounded = -1.0; - - mybuf = shortbuf; - - /* first convert to decimal, as a string; then add sign, exp, and - extra '0 to avoid trouble when buf_end == buf, then convert back. */ - buf = _Py_dg_dtoa(x, 3, ndigits, &decpt, &sign, &buf_end); - printf("buf is %p\n", buf); - if (buf == NULL) { - PyErr_NoMemory(); - goto exit1; - } - buflen = buf_end - buf; - - printf("result is %s\n", buf); - - /* total buffer space needed <= (buf_end - buf) + 8: (1 extra for '0', - 1 for the sign, 5 for exponent, 1 for '\0') */ - if (buflen + 8 > mybuflen) { - mybuflen = buflen+8; - mybuf = (char *)PyMem_Malloc(mybuflen); - if (mybuf == NULL) { - PyErr_NoMemory(); - goto exit2; - } - } - PyOS_snprintf(mybuf, mybuflen, "%s0%se%d", (sign ? "-" : ""), - buf, decpt - buflen); - printf("Checkpoint 1!\n"); - rounded = _Py_dg_strtod(mybuf, NULL); - printf("Checkpoint 2!\n"); - - /* done computing value; now clean up */ - if (mybuf != shortbuf) - PyMem_Free(mybuf); - exit2: - printf("Checkpoint 3!\n"); - printf("buf is %p\n", buf); - _Py_dg_freedtoa(buf); - printf("Checkpoint 4!\n"); - exit1: - return rounded; -} - static PyObject * float_round(PyObject *v, PyObject *args) { #define UNDEF_NDIGITS (-0x7fffffff) /* Unlikely ndigits value */ double x; + double f = 1.0; + double flr, cil; double rounded; int ndigits = UNDEF_NDIGITS; @@ -962,13 +913,28 @@ return NULL; x = PyFloat_AsDouble(v); - if (ndigits == UNDEF_NDIGITS) { - rounded = round(x); - if (fabs(x-rounded) == 0.5) - rounded = 2.0*round(x/2.0); - return PyLong_FromDouble(rounded); + + if (ndigits != UNDEF_NDIGITS) { + f = pow(10.0, ndigits); + x *= f; } - return PyFloat_FromDouble(double_round(x, ndigits)); + + flr = floor(x); + cil = ceil(x); + + if (x-flr > 0.5) + rounded = cil; + else if (x-flr == 0.5) + rounded = fmod(flr, 2) == 0 ? flr : cil; + else + rounded = flr; + + if (ndigits != UNDEF_NDIGITS) { + rounded /= f; + return PyFloat_FromDouble(rounded); + } + + return PyLong_FromDouble(rounded); #undef UNDEF_NDIGITS } From python-checkins at python.org Fri Apr 17 18:00:30 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 17 Apr 2009 18:00:30 +0200 (CEST) Subject: [Python-checkins] r71682 - python/branches/py3k-short-float-repr/Python/dtoa.c Message-ID: <20090417160030.624E81E409C@bag.python.org> Author: mark.dickinson Date: Fri Apr 17 18:00:30 2009 New Revision: 71682 Log: Fix bug in memory allocation mechanism for dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c Modified: python/branches/py3k-short-float-repr/Python/dtoa.c ============================================================================== --- python/branches/py3k-short-float-repr/Python/dtoa.c (original) +++ python/branches/py3k-short-float-repr/Python/dtoa.c Fri Apr 17 18:00:30 2009 @@ -57,6 +57,10 @@ * 5. The code has been reformatted to better fit with Python's * C style guide (PEP 7). * + * 6. A bug in the memory allocation has been fixed: to avoid FREEing memory + * that hasn't been MALLOC'ed, private_mem should only be used when k <= + * Kmax. + * ***************************************************************/ /* Please send bug reports for the original dtoa.c code to David M. Gay (dmg @@ -346,7 +350,7 @@ x = 1 << k; len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) /sizeof(double); - if (pmem_next - private_mem + len <= PRIVATE_mem) { + if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) { rv = (Bigint*)pmem_next; pmem_next += len; } From python-checkins at python.org Fri Apr 17 18:03:52 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 17 Apr 2009 18:03:52 +0200 (CEST) Subject: [Python-checkins] r71683 - python/branches/release30-maint Message-ID: <20090417160352.2F1201E4025@bag.python.org> Author: mark.dickinson Date: Fri Apr 17 18:03:52 2009 New Revision: 71683 Log: Blocked revisions 71670 via svnmerge ........ r71670 | mark.dickinson | 2009-04-17 09:41:23 +0100 (Fri, 17 Apr 2009) | 3 lines Make sure that marshal and pickle continue to output 17 digits of precision for floats. ........ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Fri Apr 17 18:06:29 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 17 Apr 2009 18:06:29 +0200 (CEST) Subject: [Python-checkins] r71684 - python/branches/py3k/Python/dtoa.c Message-ID: <20090417160629.0E9731E4025@bag.python.org> Author: mark.dickinson Date: Fri Apr 17 18:06:28 2009 New Revision: 71684 Log: Add reminder to dtoa.c to check for updates regularly. Fix a bug in the memory management in dtoa.c. Modified: python/branches/py3k/Python/dtoa.c Modified: python/branches/py3k/Python/dtoa.c ============================================================================== --- python/branches/py3k/Python/dtoa.c (original) +++ python/branches/py3k/Python/dtoa.c Fri Apr 17 18:06:28 2009 @@ -21,7 +21,11 @@ * This is dtoa.c by David M. Gay, downloaded from * http://www.netlib.org/fp/dtoa.c on April 15, 2009 and modified for * inclusion into the Python core by Mark E. T. Dickinson and Eric V. Smith. - * The major modifications are as follows: + * + * Please remember to check http://www.netlib.org/fp regularly (and especially + * before any Python release) for bugfixes and updates. + * + * The major modifications from Gay's original code are as follows: * * 0. The original code has been specialized to Python's needs by removing * many of the #ifdef'd sections. In particular, code to support VAX and @@ -53,6 +57,10 @@ * 5. The code has been reformatted to better fit with Python's * C style guide (PEP 7). * + * 6. A bug in the memory allocation has been fixed: to avoid FREEing memory + * that hasn't been MALLOC'ed, private_mem should only be used when k <= + * Kmax. + * ***************************************************************/ /* Please send bug reports for the original dtoa.c code to David M. Gay (dmg @@ -342,7 +350,7 @@ x = 1 << k; len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) /sizeof(double); - if (pmem_next - private_mem + len <= PRIVATE_mem) { + if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) { rv = (Bigint*)pmem_next; pmem_next += len; } From python-checkins at python.org Fri Apr 17 18:07:04 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 17 Apr 2009 18:07:04 +0200 (CEST) Subject: [Python-checkins] r71685 - python/branches/release30-maint Message-ID: <20090417160704.BE0D31E40FC@bag.python.org> Author: mark.dickinson Date: Fri Apr 17 18:07:04 2009 New Revision: 71685 Log: Blocked revisions 71684 via svnmerge ........ r71684 | mark.dickinson | 2009-04-17 17:06:28 +0100 (Fri, 17 Apr 2009) | 3 lines Add reminder to dtoa.c to check for updates regularly. Fix a bug in the memory management in dtoa.c. ........ Modified: python/branches/release30-maint/ (props changed) From buildbot at python.org Fri Apr 17 19:00:03 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 17 Apr 2009 17:00:03 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090417170003.8E84D1E401A@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/593 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: eric.smith,raymond.hettinger,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Fri Apr 17 20:34:49 2009 From: python-checkins at python.org (eric.smith) Date: Fri, 17 Apr 2009 20:34:49 +0200 (CEST) Subject: [Python-checkins] r71686 - peps/trunk/pep-0378.txt Message-ID: <20090417183449.4F5A91E4010@bag.python.org> Author: eric.smith Date: Fri Apr 17 20:34:48 2009 New Revision: 71686 Log: Updated to include the empty type ''. See Issue #5782. Modified: peps/trunk/pep-0378.txt Modified: peps/trunk/pep-0378.txt ============================================================================== --- peps/trunk/pep-0378.txt (original) +++ peps/trunk/pep-0378.txt Fri Apr 17 20:34:48 2009 @@ -75,7 +75,7 @@ format(1234.5, "08,.1f") --> '01,234.5' The ',' option is defined as shown above for types 'd', 'e', -'f', 'g', 'E', 'G', '%' and 'F'. To allow future extensions, it is +'f', 'g', 'E', 'G', '%', 'F' and ''. To allow future extensions, it is undefined for other types: binary, octal, hex, character, etc. From buildbot at python.org Fri Apr 17 20:40:26 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 17 Apr 2009 18:40:26 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090417184030.036661E4093@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/272 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_posix test_subprocess ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From python-checkins at python.org Fri Apr 17 20:47:01 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 17 Apr 2009 20:47:01 +0200 (CEST) Subject: [Python-checkins] r71687 - python/branches/py3k/PC/VS8.0/pythoncore.vcproj Message-ID: <20090417184701.A8FDE1E401B@bag.python.org> Author: raymond.hettinger Date: Fri Apr 17 20:47:01 2009 New Revision: 71687 Log: Add dtoc.[ch] to the VS8.0 project file. Modified: python/branches/py3k/PC/VS8.0/pythoncore.vcproj Modified: python/branches/py3k/PC/VS8.0/pythoncore.vcproj ============================================================================== --- python/branches/py3k/PC/VS8.0/pythoncore.vcproj (original) +++ python/branches/py3k/PC/VS8.0/pythoncore.vcproj Fri Apr 17 20:47:01 2009 @@ -707,6 +707,10 @@ > + + @@ -1639,6 +1643,10 @@ > + + From python-checkins at python.org Fri Apr 17 20:58:06 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 17 Apr 2009 20:58:06 +0200 (CEST) Subject: [Python-checkins] r71688 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090417185806.7E2631E401B@bag.python.org> Author: raymond.hettinger Date: Fri Apr 17 20:58:06 2009 New Revision: 71688 Log: Add more examples. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Fri Apr 17 20:58:06 2009 @@ -90,6 +90,10 @@ a number with a thousands separator. That provides a way to humanize a program's output, improving its professional appearance and readability:: + >>> format(1234567, ',d') + '1,234,567' + >>> format(1234567.89, ',.2f') + '1,234,567.89' >>> format(Decimal('1234567.89'), ',f') '1,234,567.89' From python-checkins at python.org Fri Apr 17 21:29:46 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 17 Apr 2009 21:29:46 +0200 (CEST) Subject: [Python-checkins] r71689 - python/branches/py3k/Python/dtoa.c Message-ID: <20090417192946.C42D31E4010@bag.python.org> Author: mark.dickinson Date: Fri Apr 17 21:29:46 2009 New Revision: 71689 Log: Silence compiler warnings on VS8.0 Modified: python/branches/py3k/Python/dtoa.c Modified: python/branches/py3k/Python/dtoa.c ============================================================================== --- python/branches/py3k/Python/dtoa.c (original) +++ python/branches/py3k/Python/dtoa.c Fri Apr 17 21:29:46 2009 @@ -409,7 +409,7 @@ #ifdef ULLong y = *x * (ULLong)m + carry; carry = y >> 32; - *x++ = y & FFFFFFFF; + *x++ = (ULong)(y & FFFFFFFF); #else xi = *x; y = (xi & 0xffff) * m + carry; @@ -616,7 +616,7 @@ do { z = *x++ * (ULLong)y + *xc + carry; carry = z >> 32; - *xc++ = z & FFFFFFFF; + *xc++ = (ULong)(z & FFFFFFFF); } while(x < xae); *xc = (ULong)carry; @@ -846,13 +846,13 @@ do { y = (ULLong)*xa++ - *xb++ - borrow; borrow = y >> 32 & (ULong)1; - *xc++ = y & FFFFFFFF; + *xc++ = (ULong)(y & FFFFFFFF); } while(xb < xbe); while(xa < xae) { y = *xa++ - borrow; borrow = y >> 32 & (ULong)1; - *xc++ = y & FFFFFFFF; + *xc++ = (ULong)(y & FFFFFFFF); } #else do { @@ -1097,7 +1097,7 @@ carry = ys >> 32; y = *bx - (ys & FFFFFFFF) - borrow; borrow = y >> 32 & (ULong)1; - *bx++ = y & FFFFFFFF; + *bx++ = (ULong)(y & FFFFFFFF); #else si = *sx++; ys = (si & 0xffff) * q + carry; @@ -1130,7 +1130,7 @@ carry = ys >> 32; y = *bx - (ys & FFFFFFFF) - borrow; borrow = y >> 32 & (ULong)1; - *bx++ = y & FFFFFFFF; + *bx++ = (ULong)(y & FFFFFFFF); #else si = *sx++; ys = (si & 0xffff) + carry; From nnorwitz at gmail.com Fri Apr 17 22:11:22 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 17 Apr 2009 16:11:22 -0400 Subject: [Python-checkins] Python Regression Test Failures basics (1) Message-ID: <20090417201122.GA24460@python.psfb.org> 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23366 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 test_lib2to3 failed -- errors occurred; run in verbose mode for details 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 -- OSError raises on RLock creation, see issue 3111! test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18902 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [742117 refs] From nnorwitz at gmail.com Fri Apr 17 22:19:33 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 17 Apr 2009 16:19:33 -0400 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20090417201933.GA26896@python.psfb.org> 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils [17363 refs] [17363 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23366 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 test_lib2to3 failed -- errors occurred; run in verbose mode for details 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 -- OSError raises on RLock creation, see issue 3111! test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18902 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [741356 refs] From python-checkins at python.org Fri Apr 17 22:55:52 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 17 Apr 2009 22:55:52 +0200 (CEST) Subject: [Python-checkins] r71690 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090417205552.DE1661E40E1@bag.python.org> Author: raymond.hettinger Date: Fri Apr 17 22:55:52 2009 New Revision: 71690 Log: Add porting notes. Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Fri Apr 17 22:55:52 2009 @@ -431,3 +431,32 @@ * Deprecated :cfunc:`PyNumber_Int`. Use :cfunc:`PyNumber_Long` instead. (Contributed by Mark Dickinson; :issue:`4910`.) + +Porting to Python 3.1 +===================== + +This section lists previously described changes and other bugfixes +that may require changes to your code: + +* The new floating point string representations can break existing doctests. + For example:: + + def e(): + '''Compute the base of natural logarithms. + + >>> e() + 2.7182818284590451 + + ''' + return sum(1/math.factorial(x) for x in reversed(range(30))) + + doctest.testmod() + + ********************************************************************** + Failed example: + e() + Expected: + 2.7182818284590451 + Got: + 2.718281828459045 + ********************************************************************** From python-checkins at python.org Fri Apr 17 22:59:58 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 17 Apr 2009 22:59:58 +0200 (CEST) Subject: [Python-checkins] r71691 - python/branches/py3k/Lib/test/test_float.py Message-ID: <20090417205958.B3F331E405F@bag.python.org> Author: mark.dickinson Date: Fri Apr 17 22:59:58 2009 New Revision: 71691 Log: Sort out some confusion in test_float.py: the two separate FormatTestCase classes have been combined, and test_short_repr has been moved from FormatTestCase to the existing ReprTestCase. Modified: python/branches/py3k/Lib/test/test_float.py 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 Fri Apr 17 22:59:58 2009 @@ -313,19 +313,6 @@ self.assertRaises(ValueError, format, 1e-100, format_spec) self.assertRaises(ValueError, format, -1e-100, format_spec) -class ReprTestCase(unittest.TestCase): - def test_repr(self): - floats_file = open(os.path.join(os.path.split(__file__)[0], - 'floating_points.txt')) - for line in floats_file: - line = line.strip() - if not line or line.startswith('#'): - continue - v = eval(line) - self.assertEqual(v, eval(repr(v))) - floats_file.close() - -class FormatTestCase(unittest.TestCase): @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), "test requires IEEE 754 doubles") def test_format_testfile(self): @@ -341,6 +328,18 @@ self.assertEqual(fmt % float(arg), rhs) self.assertEqual(fmt % -float(arg), '-' + rhs) +class ReprTestCase(unittest.TestCase): + def test_repr(self): + floats_file = open(os.path.join(os.path.split(__file__)[0], + 'floating_points.txt')) + for line in floats_file: + line = line.strip() + if not line or line.startswith('#'): + continue + v = eval(line) + self.assertEqual(v, eval(repr(v))) + floats_file.close() + @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short', "applies only when using short float repr style") def test_short_repr(self): @@ -390,8 +389,6 @@ self.assertEqual(s, repr(float(s))) self.assertEqual(negs, repr(float(negs))) - - # Beginning with Python 2.6 float has cross platform compatible # ways to create and represent inf and nan class InfNanTest(unittest.TestCase): From python-checkins at python.org Sat Apr 18 00:40:53 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 00:40:53 +0200 (CEST) Subject: [Python-checkins] r71692 - in python/branches/py3k: Misc/NEWS Python/pystrtod.c Message-ID: <20090417224053.56C7A1E401D@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 00:40:53 2009 New Revision: 71692 Log: Issue 5780: Fix test_float failures for legacy style float repr. Modified: python/branches/py3k/Misc/NEWS python/branches/py3k/Python/pystrtod.c Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Apr 18 00:40:53 2009 @@ -20,14 +20,7 @@ - Implement PEP 378, Format Specifier for Thousands Separator, for floats. -- The repr function switches to exponential notation at 1e16, not 1e17 - as it did before. This change applies to both 'short' and legacy - float repr styles. For the new repr style, it avoids misleading - output in some cases: an example is repr(2e16+8), which gives - '2.000000000000001e+16'; without this change it would have produced - '20000000000000010.0' instead. - -- Similarly, the str function switches to exponential notation at +- The str function switches to exponential notation at 1e11, not 1e12. This avoids printing 13 significant digits in situations where only 12 of them are correct. Example problem value: str(1e11 + 0.5). (This minor issue has existed in 2.x for a @@ -44,6 +37,9 @@ finite float x, repr(x) now outputs a string based on the shortest sequence of decimal digits that rounds to x. Previous behaviour was to output 17 significant digits and then strip trailing zeros. + Another minor difference is that the new repr switches to + exponential notation at 1e16 instead of the previous 1e17; this + avoids misleading output in some cases. There's a new sys attribute sys.float_repr_style, which takes the value 'short' to indicate that we're using short float repr, Modified: python/branches/py3k/Python/pystrtod.c ============================================================================== --- python/branches/py3k/Python/pystrtod.c (original) +++ python/branches/py3k/Python/pystrtod.c Sat Apr 18 00:40:53 2009 @@ -485,6 +485,50 @@ /* The fallback code to use if _Py_dg_dtoa is not available. */ +/* Remove trailing zeros after the decimal point from a numeric string; also + remove the decimal point if all digits following it are zero. The numeric + string must end in '\0', and should not have any leading or trailing + whitespace. Assumes that the decimal point is '.'. */ +Py_LOCAL_INLINE(void) +remove_trailing_zeros(char *buffer) +{ + char *old_fraction_end, *new_fraction_end, *end, *p; + + p = buffer; + if (*p == '-' || *p == '+') + /* Skip leading sign, if present */ + ++p; + while (isdigit(Py_CHARMASK(*p))) + ++p; + + /* if there's no decimal point there's nothing to do */ + if (*p++ != '.') + return; + + /* scan any digits after the point */ + while (isdigit(Py_CHARMASK(*p))) + ++p; + old_fraction_end = p; + + /* scan up to ending '\0' */ + while (*p != '\0') + p++; + /* +1 to make sure that we move the null byte as well */ + end = p+1; + + /* scan back from fraction_end, looking for removable zeros */ + p = old_fraction_end; + while (*(p-1) == '0') + --p; + /* and remove point if we've got that far */ + if (*(p-1) == '.') + --p; + new_fraction_end = p; + + memmove(new_fraction_end, old_fraction_end, end-old_fraction_end); +} + + PyAPI_FUNC(char *) PyOS_double_to_string(double val, char format_code, int precision, @@ -498,6 +542,7 @@ char *p; int t; int upper = 0; + int strip_trailing_zeros = 0; /* Validate format_code, and map upper and lower case */ switch (format_code) { @@ -532,8 +577,17 @@ PyErr_BadInternalCall(); return NULL; } - precision = 12; - format_code = 'g'; + /* switch to exponential notation at 1e11, or 1e12 if we're + not adding a .0 */ + if (fabs(val) >= (flags & Py_DTSF_ADD_DOT_0 ? 1e11 : 1e12)) { + precision = 11; + format_code = 'e'; + strip_trailing_zeros = 1; + } + else { + precision = 12; + format_code = 'g'; + } break; default: PyErr_BadInternalCall(); @@ -554,11 +608,14 @@ t = Py_DTST_FINITE; - if (flags & Py_DTSF_ADD_DOT_0) + if ((flags & Py_DTSF_ADD_DOT_0) && (format_code != 'e')) format_code = 'Z'; PyOS_snprintf(format, 32, "%%%s.%i%c", (flags & Py_DTSF_ALT ? "#" : ""), precision, format_code); PyOS_ascii_formatd(buf, sizeof(buf), format, val); + /* remove trailing zeros if necessary */ + if (strip_trailing_zeros) + remove_trailing_zeros(buf); } len = strlen(buf); @@ -671,7 +728,7 @@ assert(digits_end != NULL && digits_end >= digits); digits_len = digits_end - digits; - if (digits_len && !isdigit(digits[0])) { + if (digits_len && !isdigit(Py_CHARMASK(digits[0]))) { /* Infinities and nans here; adapt Gay's output, so convert Infinity to inf and NaN to nan, and ignore sign of nan. Then return. */ From python-checkins at python.org Sat Apr 18 02:10:04 2009 From: python-checkins at python.org (eric.smith) Date: Sat, 18 Apr 2009 02:10:04 +0200 (CEST) Subject: [Python-checkins] r71693 - in python/branches/py3k/Python: atof.c strtod.c Message-ID: <20090418001004.90AB01E401B@bag.python.org> Author: eric.smith Date: Sat Apr 18 02:10:04 2009 New Revision: 71693 Log: Removed unused files. Removed: python/branches/py3k/Python/atof.c python/branches/py3k/Python/strtod.c Deleted: python/branches/py3k/Python/atof.c ============================================================================== --- python/branches/py3k/Python/atof.c Sat Apr 18 02:10:04 2009 +++ (empty file) @@ -1,50 +0,0 @@ - -/* Just in case you haven't got an atof() around... - This one doesn't check for bad syntax or overflow, - and is slow and inaccurate. - But it's good enough for the occasional string literal... */ - -#include "pyconfig.h" - -#include - -double atof(char *s) -{ - double a = 0.0; - int e = 0; - int c; - while ((c = *s++) != '\0' && isdigit(c)) { - a = a*10.0 + (c - '0'); - } - if (c == '.') { - while ((c = *s++) != '\0' && isdigit(c)) { - a = a*10.0 + (c - '0'); - e = e-1; - } - } - if (c == 'e' || c == 'E') { - int sign = 1; - int i = 0; - c = *s++; - if (c == '+') - c = *s++; - else if (c == '-') { - c = *s++; - sign = -1; - } - while (isdigit(c)) { - i = i*10 + (c - '0'); - c = *s++; - } - e += i*sign; - } - while (e > 0) { - a *= 10.0; - e--; - } - while (e < 0) { - a *= 0.1; - e++; - } - return a; -} Deleted: python/branches/py3k/Python/strtod.c ============================================================================== --- python/branches/py3k/Python/strtod.c Sat Apr 18 02:10:04 2009 +++ (empty file) @@ -1,156 +0,0 @@ -#include "pyconfig.h" - -/* comp.sources.misc strtod(), as posted in comp.lang.tcl, - with bugfix for "123000.0" and acceptance of space after 'e' sign nuked. - - ************************************************************ - * YOU MUST EDIT THE MACHINE-DEPENDENT DEFINITIONS BELOW!!! * - ************************************************************ -*/ - -/* File : stdtod.c (Modified version of str2dbl.c) - Author : Richard A. O'Keefe @ Quintus Computer Systems, Inc. - Updated: Tuesday August 2nd, 1988 - Defines: double strtod (char *str, char**ptr) -*/ - -/* This is an implementation of the strtod() function described in the - System V manuals, with a different name to avoid linker problems. - All that str2dbl() does itself is check that the argument is well-formed - and is in range. It leaves the work of conversion to atof(), which is - assumed to exist and deliver correct results (if they can be represented). - - There are two reasons why this should be provided to the net: - (a) some UNIX systems do not yet have strtod(), or do not have it - available in the BSD "universe" (but they do have atof()). - (b) some of the UNIX systems that *do* have it get it wrong. - (some crash with large arguments, some assign the wrong *ptr value). - There is a reason why *we* are providing it: we need a correct version - of strtod(), and if we give this one away maybe someone will look for - mistakes in it and fix them for us (:-). -*/ - -/* The following constants are machine-specific. MD{MIN,MAX}EXPT are - integers and MD{MIN,MAX}FRAC are strings such that - 0.${MDMAXFRAC}e${MDMAXEXPT} is the largest representable double, - 0.${MDMINFRAC}e${MDMINEXPT} is the smallest representable +ve double - MD{MIN,MAX}FRAC must not have any trailing zeros. - The values here are for IEEE-754 64-bit floats. - It is not perfectly clear to me whether an IEEE infinity should be - returned for overflow, nor what a portable way of writing one is, - so HUGE is just 0.MAXFRAC*10**MAXEXPT (this seems still to be the - UNIX convention). - - I do know about , but the whole point of this file is that - we can't always trust that stuff to be there or to be correct. -*/ -static int MDMINEXPT = -323; -static char MDMINFRAC[] = "494065645841246544"; -static double ZERO = 0.0; - -static int MDMAXEXPT = 309; -static char MDMAXFRAC[] = "17976931348623157"; -static double HUGE = 1.7976931348623157e308; - -extern double atof(const char *); /* Only called when result known to be ok */ - -#ifdef HAVE_ERRNO_H -#include -#endif -extern int errno; - -double strtod(char *str, char **ptr) -{ - int sign, scale, dotseen; - int esign, expt; - char *save; - register char *sp, *dp; - register int c; - char *buforg, *buflim; - char buffer[64]; /* 45-digit significant + */ - /* 13-digit exponent */ - sp = str; - while (*sp == ' ') sp++; - sign = 1; - if (*sp == '-') sign -= 2, sp++; - dotseen = 0, scale = 0; - dp = buffer; - *dp++ = '0'; *dp++ = '.'; - buforg = dp, buflim = buffer+48; - for (save = sp; c = *sp; sp++) - if (c == '.') { - if (dotseen) break; - dotseen++; - } else - if ((unsigned)(c-'0') > (unsigned)('9'-'0')) { - break; - } else - if (c == '0') { - if (dp != buforg) { - /* This is not the first digit, so we want to keep it */ - if (dp < buflim) *dp++ = c; - if (!dotseen) scale++; - } else { - /* No non-zero digits seen yet */ - /* If a . has been seen, scale must be adjusted */ - if (dotseen) scale--; - } - } else { - /* This is a nonzero digit, so we want to keep it */ - if (dp < buflim) *dp++ = c; - /* If it precedes a ., scale must be adjusted */ - if (!dotseen) scale++; - } - if (sp == save) { - if (ptr) *ptr = str; - errno = EDOM; /* what should this be? */ - return ZERO; - } - - while (dp > buforg && dp[-1] == '0') --dp; - if (dp == buforg) *dp++ = '0'; - *dp = '\0'; - /* Now the contents of buffer are - +--+--------+-+--------+ - |0.|fraction|\|leftover| - +--+--------+-+--------+ - ^dp points here - where fraction begins with 0 iff it is "0", and has at most - 45 digits in it, and leftover is at least 16 characters. - */ - save = sp, expt = 0, esign = 1; - do { - c = *sp++; - if (c != 'e' && c != 'E') break; - c = *sp++; - if (c == '-') esign -= 2, c = *sp++; else - if (c == '+' /* || c == ' ' */ ) c = *sp++; - if ((unsigned)(c-'0') > (unsigned)('9'-'0')) break; - while (c == '0') c = *sp++; - for (; (unsigned)(c-'0') <= (unsigned)('9'-'0'); c = *sp++) - expt = expt*10 + c-'0'; - if (esign < 0) expt = -expt; - save = sp-1; - } while (0); - if (ptr) *ptr = save; - expt += scale; - /* Now the number is sign*0.fraction*10**expt */ - errno = ERANGE; - if (expt > MDMAXEXPT) { - return HUGE*sign; - } else - if (expt == MDMAXEXPT) { - if (strcmp(buforg, MDMAXFRAC) > 0) return HUGE*sign; - } else - if (expt < MDMINEXPT) { - return ZERO*sign; - } else - if (expt == MDMINEXPT) { - if (strcmp(buforg, MDMINFRAC) < 0) return ZERO*sign; - } - /* We have now established that the number can be */ - /* represented without overflow or underflow */ - (void) sprintf(dp, "E%d", expt); - errno = 0; - return atof(buffer)*sign; -} From python-checkins at python.org Sat Apr 18 02:25:01 2009 From: python-checkins at python.org (eric.smith) Date: Sat, 18 Apr 2009 02:25:01 +0200 (CEST) Subject: [Python-checkins] r71694 - in python/branches/release30-maint: Python/atof.c Python/strtod.c Message-ID: <20090418002501.818D71E401B@bag.python.org> Author: eric.smith Date: Sat Apr 18 02:25:01 2009 New Revision: 71694 Log: Merged revisions 71693 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r71693 | eric.smith | 2009-04-17 20:10:04 -0400 (Fri, 17 Apr 2009) | 1 line Removed unused files. ........ Removed: python/branches/release30-maint/Python/atof.c python/branches/release30-maint/Python/strtod.c Modified: python/branches/release30-maint/ (props changed) Deleted: python/branches/release30-maint/Python/atof.c ============================================================================== --- python/branches/release30-maint/Python/atof.c Sat Apr 18 02:25:01 2009 +++ (empty file) @@ -1,50 +0,0 @@ - -/* Just in case you haven't got an atof() around... - This one doesn't check for bad syntax or overflow, - and is slow and inaccurate. - But it's good enough for the occasional string literal... */ - -#include "pyconfig.h" - -#include - -double atof(char *s) -{ - double a = 0.0; - int e = 0; - int c; - while ((c = *s++) != '\0' && isdigit(c)) { - a = a*10.0 + (c - '0'); - } - if (c == '.') { - while ((c = *s++) != '\0' && isdigit(c)) { - a = a*10.0 + (c - '0'); - e = e-1; - } - } - if (c == 'e' || c == 'E') { - int sign = 1; - int i = 0; - c = *s++; - if (c == '+') - c = *s++; - else if (c == '-') { - c = *s++; - sign = -1; - } - while (isdigit(c)) { - i = i*10 + (c - '0'); - c = *s++; - } - e += i*sign; - } - while (e > 0) { - a *= 10.0; - e--; - } - while (e < 0) { - a *= 0.1; - e++; - } - return a; -} Deleted: python/branches/release30-maint/Python/strtod.c ============================================================================== --- python/branches/release30-maint/Python/strtod.c Sat Apr 18 02:25:01 2009 +++ (empty file) @@ -1,156 +0,0 @@ -#include "pyconfig.h" - -/* comp.sources.misc strtod(), as posted in comp.lang.tcl, - with bugfix for "123000.0" and acceptance of space after 'e' sign nuked. - - ************************************************************ - * YOU MUST EDIT THE MACHINE-DEPENDENT DEFINITIONS BELOW!!! * - ************************************************************ -*/ - -/* File : stdtod.c (Modified version of str2dbl.c) - Author : Richard A. O'Keefe @ Quintus Computer Systems, Inc. - Updated: Tuesday August 2nd, 1988 - Defines: double strtod (char *str, char**ptr) -*/ - -/* This is an implementation of the strtod() function described in the - System V manuals, with a different name to avoid linker problems. - All that str2dbl() does itself is check that the argument is well-formed - and is in range. It leaves the work of conversion to atof(), which is - assumed to exist and deliver correct results (if they can be represented). - - There are two reasons why this should be provided to the net: - (a) some UNIX systems do not yet have strtod(), or do not have it - available in the BSD "universe" (but they do have atof()). - (b) some of the UNIX systems that *do* have it get it wrong. - (some crash with large arguments, some assign the wrong *ptr value). - There is a reason why *we* are providing it: we need a correct version - of strtod(), and if we give this one away maybe someone will look for - mistakes in it and fix them for us (:-). -*/ - -/* The following constants are machine-specific. MD{MIN,MAX}EXPT are - integers and MD{MIN,MAX}FRAC are strings such that - 0.${MDMAXFRAC}e${MDMAXEXPT} is the largest representable double, - 0.${MDMINFRAC}e${MDMINEXPT} is the smallest representable +ve double - MD{MIN,MAX}FRAC must not have any trailing zeros. - The values here are for IEEE-754 64-bit floats. - It is not perfectly clear to me whether an IEEE infinity should be - returned for overflow, nor what a portable way of writing one is, - so HUGE is just 0.MAXFRAC*10**MAXEXPT (this seems still to be the - UNIX convention). - - I do know about , but the whole point of this file is that - we can't always trust that stuff to be there or to be correct. -*/ -static int MDMINEXPT = -323; -static char MDMINFRAC[] = "494065645841246544"; -static double ZERO = 0.0; - -static int MDMAXEXPT = 309; -static char MDMAXFRAC[] = "17976931348623157"; -static double HUGE = 1.7976931348623157e308; - -extern double atof(const char *); /* Only called when result known to be ok */ - -#ifdef HAVE_ERRNO_H -#include -#endif -extern int errno; - -double strtod(char *str, char **ptr) -{ - int sign, scale, dotseen; - int esign, expt; - char *save; - register char *sp, *dp; - register int c; - char *buforg, *buflim; - char buffer[64]; /* 45-digit significant + */ - /* 13-digit exponent */ - sp = str; - while (*sp == ' ') sp++; - sign = 1; - if (*sp == '-') sign -= 2, sp++; - dotseen = 0, scale = 0; - dp = buffer; - *dp++ = '0'; *dp++ = '.'; - buforg = dp, buflim = buffer+48; - for (save = sp; c = *sp; sp++) - if (c == '.') { - if (dotseen) break; - dotseen++; - } else - if ((unsigned)(c-'0') > (unsigned)('9'-'0')) { - break; - } else - if (c == '0') { - if (dp != buforg) { - /* This is not the first digit, so we want to keep it */ - if (dp < buflim) *dp++ = c; - if (!dotseen) scale++; - } else { - /* No non-zero digits seen yet */ - /* If a . has been seen, scale must be adjusted */ - if (dotseen) scale--; - } - } else { - /* This is a nonzero digit, so we want to keep it */ - if (dp < buflim) *dp++ = c; - /* If it precedes a ., scale must be adjusted */ - if (!dotseen) scale++; - } - if (sp == save) { - if (ptr) *ptr = str; - errno = EDOM; /* what should this be? */ - return ZERO; - } - - while (dp > buforg && dp[-1] == '0') --dp; - if (dp == buforg) *dp++ = '0'; - *dp = '\0'; - /* Now the contents of buffer are - +--+--------+-+--------+ - |0.|fraction|\|leftover| - +--+--------+-+--------+ - ^dp points here - where fraction begins with 0 iff it is "0", and has at most - 45 digits in it, and leftover is at least 16 characters. - */ - save = sp, expt = 0, esign = 1; - do { - c = *sp++; - if (c != 'e' && c != 'E') break; - c = *sp++; - if (c == '-') esign -= 2, c = *sp++; else - if (c == '+' /* || c == ' ' */ ) c = *sp++; - if ((unsigned)(c-'0') > (unsigned)('9'-'0')) break; - while (c == '0') c = *sp++; - for (; (unsigned)(c-'0') <= (unsigned)('9'-'0'); c = *sp++) - expt = expt*10 + c-'0'; - if (esign < 0) expt = -expt; - save = sp-1; - } while (0); - if (ptr) *ptr = save; - expt += scale; - /* Now the number is sign*0.fraction*10**expt */ - errno = ERANGE; - if (expt > MDMAXEXPT) { - return HUGE*sign; - } else - if (expt == MDMAXEXPT) { - if (strcmp(buforg, MDMAXFRAC) > 0) return HUGE*sign; - } else - if (expt < MDMINEXPT) { - return ZERO*sign; - } else - if (expt == MDMINEXPT) { - if (strcmp(buforg, MDMINFRAC) < 0) return ZERO*sign; - } - /* We have now established that the number can be */ - /* represented without overflow or underflow */ - (void) sprintf(dp, "E%d", expt); - errno = 0; - return atof(buffer)*sign; -} From buildbot at python.org Sat Apr 18 04:12:00 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 18 Apr 2009 02:12:00 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090418021200.E196C1E401E@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/274 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: eric.smith BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_distutils test_posix ====================================================================== FAIL: test_get_python_inc (distutils.tests.test_sysconfig.SysconfigTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/distutils/tests/test_sysconfig.py", line 45, in test_get_python_inc self.assert_(os.path.isdir(inc_dir), inc_dir) AssertionError: /home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/Include ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Sat Apr 18 05:21:29 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 18 Apr 2009 05:21:29 +0200 (CEST) Subject: [Python-checkins] r71695 - in sandbox/trunk/2to3/lib2to3: main.py refactor.py Message-ID: <20090418032129.9E1CA1E401E@bag.python.org> Author: benjamin.peterson Date: Sat Apr 18 05:21:29 2009 New Revision: 71695 Log: refactor multiprocessing support, so it's less hacky to employ and only loads mp when needed Modified: sandbox/trunk/2to3/lib2to3/main.py sandbox/trunk/2to3/lib2to3/refactor.py Modified: sandbox/trunk/2to3/lib2to3/main.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/main.py (original) +++ sandbox/trunk/2to3/lib2to3/main.py Sat Apr 18 05:21:29 2009 @@ -10,12 +10,7 @@ from . import refactor -HAVE_MULTIPROCESS = hasattr(refactor, "MultiprocessRefactoringTool") - -base_refactor = getattr(refactor, "MultiprocessRefactoringTool", - refactor.RefactoringTool) - -class StdoutRefactoringTool(base_refactor): +class StdoutRefactoringTool(refactor.MultiprocessRefactoringTool): """ Prints output to stdout. """ @@ -68,9 +63,8 @@ help="Fix up doctests only") parser.add_option("-f", "--fix", action="append", default=[], help="Each FIX specifies a transformation; default: all") - if HAVE_MULTIPROCESS: - parser.add_option("-j", "--processes", action="store", default=1, - type="int", help="Run 2to3 concurrently") + 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.") parser.add_option("-l", "--list-fixes", action="store_true", @@ -133,11 +127,14 @@ if refactor_stdin: rt.refactor_stdin() else: - if HAVE_MULTIPROCESS: + try: rt.refactor(args, options.write, options.doctests_only, options.processes) - else: - rt.refactor(args, options.write, options.doctests_only) + except refactor.MultiprocessingUnsupported: + assert options.processes > 1 + print >> sys.stderr, "Sorry, -j isn't " \ + "supported on this platform." + return 1 rt.summarize() # Return error status (0 if rt.errors is zero) Modified: sandbox/trunk/2to3/lib2to3/refactor.py ============================================================================== --- sandbox/trunk/2to3/lib2to3/refactor.py (original) +++ sandbox/trunk/2to3/lib2to3/refactor.py Sat Apr 18 05:21:29 2009 @@ -506,58 +506,61 @@ yield "" -try: - import multiprocessing -except ImportError: +class MultiprocessingUnsupported(Exception): pass -else: - class MultiprocessRefactoringTool(RefactoringTool): - def __init__(self, *args, **kwargs): - super(MultiprocessRefactoringTool, self).__init__(*args, **kwargs) + +class MultiprocessRefactoringTool(RefactoringTool): + + def __init__(self, *args, **kwargs): + super(MultiprocessRefactoringTool, self).__init__(*args, **kwargs) + self.queue = None + + def refactor(self, items, write=False, doctests_only=False, + num_processes=1): + if num_processes == 1: + return super(MultiprocessRefactoringTool, self).refactor( + items, write, doctests_only) + try: + import multiprocessing + except ImportError: + raise MultiprocessingUnsupported + if self.queue is not None: + raise RuntimeError("already doing multiple processes") + self.queue = multiprocessing.JoinableQueue() + processes = [multiprocessing.Process(target=self._child) + for i in xrange(num_processes)] + try: + for p in processes: + p.start() + super(MultiprocessRefactoringTool, self).refactor(items, write, + doctests_only) + finally: + self.queue.join() + for i in xrange(num_processes): + self.queue.put(None) + for p in processes: + if p.is_alive(): + p.join() self.queue = None - def refactor(self, items, write=False, doctests_only=False, - num_processes=1): - if num_processes == 1: - return super(MultiprocessRefactoringTool, self).refactor( - items, write, doctests_only) - if self.queue is not None: - raise RuntimeError("already doing multiple processes") - self.queue = multiprocessing.JoinableQueue() - processes = [multiprocessing.Process(target=self._child) - for i in xrange(num_processes)] + def _child(self): + task = self.queue.get() + while task is not None: + args, kwargs = task try: - for p in processes: - p.start() - super(MultiprocessRefactoringTool, self).refactor(items, write, - doctests_only) + super(MultiprocessRefactoringTool, self).refactor_file( + *args, **kwargs) finally: - self.queue.join() - for i in xrange(num_processes): - self.queue.put(None) - for p in processes: - if p.is_alive(): - p.join() - self.queue = None - - def _child(self): + self.queue.task_done() task = self.queue.get() - while task is not None: - args, kwargs = task - try: - super(MultiprocessRefactoringTool, self).refactor_file( - *args, **kwargs) - finally: - self.queue.task_done() - task = self.queue.get() - - def refactor_file(self, *args, **kwargs): - if self.queue is not None: - self.queue.put((args, kwargs)) - else: - return super(MultiprocessRefactoringTool, self).refactor_file( - *args, **kwargs) + + def refactor_file(self, *args, **kwargs): + if self.queue is not None: + self.queue.put((args, kwargs)) + else: + return super(MultiprocessRefactoringTool, self).refactor_file( + *args, **kwargs) def diff_texts(a, b, filename): From python-checkins at python.org Sat Apr 18 10:26:21 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 18 Apr 2009 10:26:21 +0200 (CEST) Subject: [Python-checkins] r71696 - python/trunk/Objects/abstract.c Message-ID: <20090418082621.BA6B61E4040@bag.python.org> Author: georg.brandl Date: Sat Apr 18 10:26:21 2009 New Revision: 71696 Log: "not subscriptable" should be a bit more understandable than "unsubscriptable". Modified: python/trunk/Objects/abstract.c Modified: python/trunk/Objects/abstract.c ============================================================================== --- python/trunk/Objects/abstract.c (original) +++ python/trunk/Objects/abstract.c Sat Apr 18 10:26:21 2009 @@ -153,7 +153,7 @@ "be integer, not '%.200s'", key); } - return type_error("'%.200s' object is unsubscriptable", o); + return type_error("'%.200s' object is not subscriptable", o); } int From python-checkins at python.org Sat Apr 18 12:12:16 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 12:12:16 +0200 (CEST) Subject: [Python-checkins] r71697 - python/branches/py3k/Include/intobject.h Message-ID: <20090418101216.87A411E402C@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 12:12:16 2009 New Revision: 71697 Log: The comments at the top of intobject.h say that it will be removed in 3.1. Make it so. Removed: python/branches/py3k/Include/intobject.h Deleted: python/branches/py3k/Include/intobject.h ============================================================================== --- python/branches/py3k/Include/intobject.h Sat Apr 18 12:12:16 2009 +++ (empty file) @@ -1,36 +0,0 @@ -/* Integer object interface - - This header file exists to make porting code to Python 3.0 easier. It - defines aliases from PyInt_* to PyLong_* and an alias from - PyNumber_Int to PyNumber_Long. - */ - -#ifndef Py_INTOBJECT_H -#define Py_INTOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__GNUC__) -#warning "DeprecationWarning: intobject.h is going to be removed in 3.1" -#elif defined(MS_WINDOWS) -#pragma message("DeprecationWarning: intobject.h is going to be removed in 3.1") -#endif - -#define PyInt_Check(op) PyLong_Check(op) -#define PyInt_FromString PyLong_FromString -#define PyInt_FromUnicode PyLong_FromUnicode -#define PyInt_FromLong PyLong_FromLong -#define PyInt_FromSize_t PyLong_FromSize_t -#define PyInt_FromSsize_t PyLong_FromSsize_t -#define PyInt_AsLong PyLong_AsLong -#define PyInt_AsSsize_t PyLong_AsSsize_t -#define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask -#define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask -#define PyInt_AS_LONG PyLong_AS_LONG -#define PyNumber_Int PyNumber_Long - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTOBJECT_H */ From python-checkins at python.org Sat Apr 18 12:16:36 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 12:16:36 +0200 (CEST) Subject: [Python-checkins] r71698 - python/branches/py3k/Include/pyport.h Message-ID: <20090418101636.8983C1E4039@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 12:16:35 2009 New Revision: 71698 Log: Issue #5781: Only use legacy string<->double conversions when we can't figure out how to get and set the x87 control word. Modified: python/branches/py3k/Include/pyport.h Modified: python/branches/py3k/Include/pyport.h ============================================================================== --- python/branches/py3k/Include/pyport.h (original) +++ python/branches/py3k/Include/pyport.h Sat Apr 18 12:16:35 2009 @@ -506,8 +506,10 @@ #define PY_NO_SHORT_FLOAT_REPR #endif -/* double rounding is symptomatic of use of extended precision on x86 */ -#ifdef X87_DOUBLE_ROUNDING +/* double rounding is symptomatic of use of extended precision on x86. If + we're seeing double rounding, and we don't have any mechanism available for + changing the FPU rounding precision, then don't use Python/dtoa.c. */ +#if defined(X87_DOUBLE_ROUNDING) && !defined(HAVE_GCC_ASM_FOR_X87) #define PY_NO_SHORT_FLOAT_REPR #endif From python-checkins at python.org Sat Apr 18 12:17:33 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 12:17:33 +0200 (CEST) Subject: [Python-checkins] r71699 - python/branches/release30-maint Message-ID: <20090418101733.A62FA1E402C@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 12:17:33 2009 New Revision: 71699 Log: Blocked revisions 71697 via svnmerge ........ r71697 | mark.dickinson | 2009-04-18 11:12:16 +0100 (Sat, 18 Apr 2009) | 3 lines The comments at the top of intobject.h say that it will be removed in 3.1. Make it so. ........ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sat Apr 18 12:18:06 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 12:18:06 +0200 (CEST) Subject: [Python-checkins] r71700 - python/branches/release30-maint Message-ID: <20090418101806.97FEF1E402C@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 12:18:06 2009 New Revision: 71700 Log: Blocked revisions 71698 via svnmerge ........ r71698 | mark.dickinson | 2009-04-18 11:16:35 +0100 (Sat, 18 Apr 2009) | 3 lines Issue #5781: Only use legacy string<->double conversions when we can't figure out how to get and set the x87 control word. ........ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sat Apr 18 13:48:33 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 13:48:33 +0200 (CEST) Subject: [Python-checkins] r71701 - in python/branches/py3k: Lib/test/test_float.py Misc/NEWS Objects/floatobject.c Message-ID: <20090418114833.DF6851E40F4@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 13:48:33 2009 New Revision: 71701 Log: Issue #1869 (and 4707, 5118, 5473, 1456775): use the new string <-> float conversion routines to make round(x, n) correctly rounded for floats x, so that it always agrees with format(x, '.f'). Also fix some other round nuisances, like round(123.456, 1-2**31) giving an integer rather than a float. 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 Apr 18 13:48:33 2009 @@ -389,6 +389,88 @@ self.assertEqual(s, repr(float(s))) self.assertEqual(negs, repr(float(negs))) +class RoundTestCase(unittest.TestCase): + @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + def test_inf_nan(self): + self.assertRaises(OverflowError, round, INF) + self.assertRaises(OverflowError, round, -INF) + self.assertRaises(ValueError, round, NAN) + + @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + def test_large_n(self): + for n in [324, 325, 400, 2**31-1, 2**31, 2**32, 2**100]: + self.assertEqual(round(123.456, n), 123.456) + self.assertEqual(round(-123.456, n), -123.456) + self.assertEqual(round(1e300, n), 1e300) + self.assertEqual(round(1e-320, n), 1e-320) + self.assertEqual(round(1e150, 300), 1e150) + self.assertEqual(round(1e300, 307), 1e300) + self.assertEqual(round(-3.1415, 308), -3.1415) + self.assertEqual(round(1e150, 309), 1e150) + self.assertEqual(round(1.4e-315, 315), 1e-315) + + @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + def test_small_n(self): + for n in [-308, -309, -400, 1-2**31, -2**31, -2**31-1, -2**100]: + self.assertEqual(round(123.456, n), 0.0) + self.assertEqual(round(-123.456, n), -0.0) + self.assertEqual(round(1e300, n), 0.0) + self.assertEqual(round(1e-320, n), 0.0) + + @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + def test_overflow(self): + self.assertRaises(OverflowError, round, 1.6e308, -308) + self.assertRaises(OverflowError, round, -1.7e308, -308) + + @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short', + "applies only when using short float repr style") + def test_previous_round_bugs(self): + # particular cases that have occurred in bug reports + self.assertEqual(round(562949953421312.5, 1), + 562949953421312.5) + self.assertEqual(round(56294995342131.5, 3), + 56294995342131.5) + # round-half-even + self.assertEqual(round(25.0, -1), 20.0) + self.assertEqual(round(35.0, -1), 40.0) + self.assertEqual(round(45.0, -1), 40.0) + self.assertEqual(round(55.0, -1), 60.0) + self.assertEqual(round(65.0, -1), 60.0) + self.assertEqual(round(75.0, -1), 80.0) + self.assertEqual(round(85.0, -1), 80.0) + self.assertEqual(round(95.0, -1), 100.0) + + @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short', + "applies only when using short float repr style") + def test_matches_float_format(self): + # round should give the same results as float formatting + for i in range(500): + x = i/1000. + self.assertEqual(float(format(x, '.0f')), round(x, 0)) + self.assertEqual(float(format(x, '.1f')), round(x, 1)) + self.assertEqual(float(format(x, '.2f')), round(x, 2)) + self.assertEqual(float(format(x, '.3f')), round(x, 3)) + + for i in range(5, 5000, 10): + x = i/1000. + self.assertEqual(float(format(x, '.0f')), round(x, 0)) + self.assertEqual(float(format(x, '.1f')), round(x, 1)) + self.assertEqual(float(format(x, '.2f')), round(x, 2)) + self.assertEqual(float(format(x, '.3f')), round(x, 3)) + + for i in range(500): + x = random.random() + self.assertEqual(float(format(x, '.0f')), round(x, 0)) + self.assertEqual(float(format(x, '.1f')), round(x, 1)) + self.assertEqual(float(format(x, '.2f')), round(x, 2)) + self.assertEqual(float(format(x, '.3f')), round(x, 3)) + + + # Beginning with Python 2.6 float has cross platform compatible # ways to create and represent inf and nan class InfNanTest(unittest.TestCase): @@ -878,6 +960,7 @@ IEEEFormatTestCase, FormatTestCase, ReprTestCase, + RoundTestCase, InfNanTest, HexFloatTestCase, ) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Apr 18 13:48:33 2009 @@ -12,6 +12,11 @@ Core and Builtins ----------------- +- Issue #1869 (and many duplicates): make round(x, n) correctly + rounded for a float x, by using the decimal <-> binary conversions + from Python/dtoa.c. As a consequence, (e.g.) round(x, 2) now + consistently agrees with format(x, '.2f'). + - Issue #5772: format(1e100, '<') produces '1e+100', not '1.0e+100'. - Issue #5515: str.format() type 'n' combined with commas and leading Modified: python/branches/py3k/Objects/floatobject.c ============================================================================== --- python/branches/py3k/Objects/floatobject.c (original) +++ python/branches/py3k/Objects/floatobject.c Sat Apr 18 13:48:33 2009 @@ -899,43 +899,161 @@ return PyLong_FromDouble(wholepart); } +/* double_round: rounds a finite double to the closest multiple of + 10**-ndigits; here ndigits is within reasonable bounds (typically, -308 <= + ndigits <= 323). Returns a Python float, or sets a Python error and + returns NULL on failure (OverflowError and memory errors are possible). */ + +#ifndef PY_NO_SHORT_FLOAT_REPR +/* version of double_round that uses the correctly-rounded string<->double + conversions from Python/dtoa.c */ + static PyObject * -float_round(PyObject *v, PyObject *args) -{ -#define UNDEF_NDIGITS (-0x7fffffff) /* Unlikely ndigits value */ - double x; - double f = 1.0; - double flr, cil; - double rounded; - int ndigits = UNDEF_NDIGITS; +double_round(double x, int ndigits) { - if (!PyArg_ParseTuple(args, "|i", &ndigits)) + double rounded; + Py_ssize_t buflen, mybuflen=100; + char *buf, *buf_end, shortbuf[100], *mybuf=shortbuf; + int decpt, sign; + PyObject *result = NULL; + + /* round to a decimal string */ + buf = _Py_dg_dtoa(x, 3, ndigits, &decpt, &sign, &buf_end); + if (buf == NULL) { + PyErr_NoMemory(); return NULL; + } - x = PyFloat_AsDouble(v); + /* Get new buffer if shortbuf is too small. Space needed <= buf_end - + buf + 8: (1 extra for '0', 1 for sign, 5 for exp, 1 for '\0'). */ + buflen = buf_end - buf; + if (buflen + 8 > mybuflen) { + mybuflen = buflen+8; + mybuf = (char *)PyMem_Malloc(mybuflen); + if (mybuf == NULL) { + PyErr_NoMemory(); + goto exit; + } + } + /* copy buf to mybuf, adding exponent, sign and leading 0 */ + PyOS_snprintf(mybuf, mybuflen, "%s0%se%d", (sign ? "-" : ""), + buf, decpt - (int)buflen); + + /* and convert the resulting string back to a double */ + errno = 0; + rounded = _Py_dg_strtod(mybuf, NULL); + if (errno == ERANGE && fabs(rounded) >= 1.) + PyErr_SetString(PyExc_OverflowError, + "rounded value too large to represent"); + else + result = PyFloat_FromDouble(rounded); - if (ndigits != UNDEF_NDIGITS) { - f = pow(10.0, ndigits); - x *= f; + /* done computing value; now clean up */ + if (mybuf != shortbuf) + PyMem_Free(mybuf); + exit: + _Py_dg_freedtoa(buf); + return result; +} + +#else /* PY_NO_SHORT_FLOAT_REPR */ + +/* fallback version, to be used when correctly rounded binary<->decimal + conversions aren't available */ + +static PyObject * +double_round(double x, int ndigits) { + double pow1, pow2, y, z; + if (ndigits >= 0) { + if (ndigits > 22) { + /* pow1 and pow2 are each safe from overflow, but + pow1*pow2 ~= pow(10.0, ndigits) might overflow */ + pow1 = pow(10.0, (double)(ndigits-22)); + pow2 = 1e22; + } + else { + pow1 = pow(10.0, (double)ndigits); + pow2 = 1.0; + } + y = (x*pow1)*pow2; + /* if y overflows, then rounded value is exactly x */ + if (!Py_IS_FINITE(y)) + return PyFloat_FromDouble(x); } + else { + pow1 = pow(10.0, (double)-ndigits); + pow2 = 1.0; /* unused; silences a gcc compiler warning */ + y = x / pow1; + } + + z = round(y); + if (fabs(y-z) == 0.5) + /* halfway between two integers; use round-half-even */ + z = 2.0*round(y/2.0); - flr = floor(x); - cil = ceil(x); - - if (x-flr > 0.5) - rounded = cil; - else if (x-flr == 0.5) - rounded = fmod(flr, 2) == 0 ? flr : cil; + if (ndigits >= 0) + z = (z / pow2) / pow1; else - rounded = flr; + z *= pow1; - if (ndigits != UNDEF_NDIGITS) { - rounded /= f; - return PyFloat_FromDouble(rounded); + /* if computation resulted in overflow, raise OverflowError */ + if (!Py_IS_FINITE(z)) { + PyErr_SetString(PyExc_OverflowError, + "overflow occurred during round"); + return NULL; } - return PyLong_FromDouble(rounded); -#undef UNDEF_NDIGITS + return PyFloat_FromDouble(z); +} + +#endif /* PY_NO_SHORT_FLOAT_REPR */ + +/* round a Python float v to the closest multiple of 10**-ndigits */ + +static PyObject * +float_round(PyObject *v, PyObject *args) +{ + double x, rounded; + PyObject *o_ndigits = NULL; + Py_ssize_t ndigits; + + x = PyFloat_AsDouble(v); + if (!PyArg_ParseTuple(args, "|O", &o_ndigits)) + return NULL; + if (o_ndigits == NULL) { + /* single-argument round: round to nearest integer */ + rounded = round(x); + if (fabs(x-rounded) == 0.5) + /* halfway case: round to even */ + rounded = 2.0*round(x/2.0); + return PyLong_FromDouble(rounded); + } + + /* interpret second argument as a Py_ssize_t; clips on overflow */ + ndigits = PyNumber_AsSsize_t(o_ndigits, NULL); + if (ndigits == -1 && PyErr_Occurred()) + return NULL; + + /* nans and infinities round to themselves */ + if (!Py_IS_FINITE(x)) + return PyFloat_FromDouble(x); + + /* Deal with extreme values for ndigits. For ndigits > NDIGITS_MAX, x + always rounds to itself. For ndigits < NDIGITS_MIN, x always + rounds to +-0.0. Here 0.30103 is an upper bound for log10(2). */ +#define NDIGITS_MAX ((int)((DBL_MANT_DIG-DBL_MIN_EXP) * 0.30103)) +#define NDIGITS_MIN (-(int)((DBL_MAX_EXP + 1) * 0.30103)) + if (ndigits > NDIGITS_MAX) + /* return x */ + return PyFloat_FromDouble(x); + else if (ndigits < NDIGITS_MIN) + /* return 0.0, but with sign of x */ + return PyFloat_FromDouble(0.0*x); + else + /* finite x, and ndigits is not unreasonably large */ + return double_round(x, (int)ndigits); +#undef NDIGITS_MAX +#undef NDIGITS_MIN } static PyObject * From python-checkins at python.org Sat Apr 18 13:50:42 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 13:50:42 +0200 (CEST) Subject: [Python-checkins] r71702 - python/branches/release30-maint Message-ID: <20090418115042.123F81E4040@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 13:50:41 2009 New Revision: 71702 Log: Blocked revisions 71701 via svnmerge ........ r71701 | mark.dickinson | 2009-04-18 12:48:33 +0100 (Sat, 18 Apr 2009) | 7 lines Issue #1869 (and 4707, 5118, 5473, 1456775): use the new string <-> float conversion routines to make round(x, n) correctly rounded for floats x, so that it always agrees with format(x, '.f'). Also fix some other round nuisances, like round(123.456, 1-2**31) giving an integer rather than a float. ........ Modified: python/branches/release30-maint/ (props changed) From buildbot at python.org Sat Apr 18 14:28:56 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 18 Apr 2009 12:28:56 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090418122856.DA6E41E4039@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/601 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_ctypes Traceback (most recent call last): File "./Lib/test/regrtest.py", line 620, in runtest_inner indirect_test() File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/test/test_ctypes.py", line 11, in test_main skipped, testcases = ctypes.test.get_tests(ctypes.test, "test_*.py", verbosity=0) AttributeError: 'module' object has no attribute 'get_tests' make: *** [buildbottest] Error 1 sincerely, -The Buildbot From ocean-city at m2.ccsnet.ne.jp Sat Apr 18 15:07:50 2009 From: ocean-city at m2.ccsnet.ne.jp (Hirokazu Yamamoto) Date: Sat, 18 Apr 2009 22:07:50 +0900 Subject: [Python-checkins] r71701 - in python/branches/py3k: Lib/test/test_float.py Misc/NEWS Objects/floatobject.c In-Reply-To: <20090418114833.DF6851E40F4@bag.python.org> References: <20090418114833.DF6851E40F4@bag.python.org> Message-ID: <49E9D0A6.2030700@m2.ccsnet.ne.jp> mark.dickinson wrote: > Author: mark.dickinson > Date: Sat Apr 18 13:48:33 2009 > New Revision: 71701 > > Log: > Issue #1869 (and 4707, 5118, 5473, 1456775): use the new > string <-> float conversion routines to make round(x, n) correctly > rounded for floats x, so that it always agrees with format(x, '.f'). > > Also fix some other round nuisances, like round(123.456, 1-2**31) giving > an integer rather than a float. I got linker error "round() cannot be resolved" on VC6(Windows). I cannot know whether this happens on VC9 or not because buildbot is down, but round() seems to be added C standard in C99. Shouldn't this function be checked by HAVE_ROUND? Thank you. From python-checkins at python.org Sat Apr 18 15:10:51 2009 From: python-checkins at python.org (hirokazu.yamamoto) Date: Sat, 18 Apr 2009 15:10:51 +0200 (CEST) Subject: [Python-checkins] r71703 - in python/branches/py3k/PC: VC6/pythoncore.dsp VS7.1/pythoncore.vcproj Message-ID: <20090418131051.7A0451E4049@bag.python.org> Author: hirokazu.yamamoto Date: Sat Apr 18 15:10:51 2009 New Revision: 71703 Log: Added Python/dtoa.c to project files. Modified: python/branches/py3k/PC/VC6/pythoncore.dsp python/branches/py3k/PC/VS7.1/pythoncore.vcproj Modified: python/branches/py3k/PC/VC6/pythoncore.dsp ============================================================================== --- python/branches/py3k/PC/VC6/pythoncore.dsp (original) +++ python/branches/py3k/PC/VC6/pythoncore.dsp Sat Apr 18 15:10:51 2009 @@ -341,6 +341,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Python\dtoa.c +# End Source File +# Begin Source File + SOURCE=..\..\Python\dynload_win.c # End Source File # Begin Source File Modified: python/branches/py3k/PC/VS7.1/pythoncore.vcproj ============================================================================== --- python/branches/py3k/PC/VS7.1/pythoncore.vcproj (original) +++ python/branches/py3k/PC/VS7.1/pythoncore.vcproj Sat Apr 18 15:10:51 2009 @@ -517,6 +517,9 @@ RelativePath="..\..\PC\dl_nt.c"> + + References: <20090418114833.DF6851E40F4@bag.python.org> <49E9D0A6.2030700@m2.ccsnet.ne.jp> Message-ID: <5c6f2a5d0904180636p5818bfc3l1cdd62aa3aad9234@mail.gmail.com> Thanks. I should have expected this. I'll fix it. On Sat, Apr 18, 2009 at 2:07 PM, Hirokazu Yamamoto wrote: > > mark.dickinson wrote: >> >> Author: mark.dickinson >> Date: Sat Apr 18 13:48:33 2009 >> New Revision: 71701 >> >> Log: >> Issue #1869 (and 4707, 5118, 5473, 1456775): ?use the new >> string <-> float conversion routines to make round(x, n) correctly >> rounded for floats x, so that it always agrees with format(x, '.f'). >> >> Also fix some other round nuisances, like round(123.456, 1-2**31) giving >> an integer rather than a float. > > I got linker error "round() cannot be resolved" on VC6(Windows). I cannot > know whether this happens on VC9 or not because buildbot is down, but > round() seems to be added C standard in C99. Shouldn't this function be > checked by HAVE_ROUND? Thank you. > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > http://mail.python.org/mailman/listinfo/python-checkins > From python-checkins at python.org Sat Apr 18 15:58:19 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 15:58:19 +0200 (CEST) Subject: [Python-checkins] r71704 - in python/branches/py3k: Include/pymath.h Python/pymath.c configure configure.in pyconfig.h.in Message-ID: <20090418135819.61C771E403E@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 15:58:18 2009 New Revision: 71704 Log: Add check for C99 round function to configure, and define a fallback function if round doesn't exist. Modified: python/branches/py3k/Include/pymath.h python/branches/py3k/Python/pymath.c python/branches/py3k/configure python/branches/py3k/configure.in python/branches/py3k/pyconfig.h.in Modified: python/branches/py3k/Include/pymath.h ============================================================================== --- python/branches/py3k/Include/pymath.h (original) +++ python/branches/py3k/Include/pymath.h Sat Apr 18 15:58:18 2009 @@ -22,6 +22,10 @@ extern double copysign(double, double); #endif +#ifndef HAVE_ROUND +extern double round(double); +#endif + #ifndef HAVE_ACOSH extern double acosh(double); #endif Modified: python/branches/py3k/Python/pymath.c ============================================================================== --- python/branches/py3k/Python/pymath.c (original) +++ python/branches/py3k/Python/pymath.c Sat Apr 18 15:58:18 2009 @@ -69,6 +69,19 @@ } #endif /* HAVE_COPYSIGN */ +#ifndef HAVE_ROUND +double +round(double x) +{ + double absx, y; + absx = fabs(x); + y = floor(absx); + if (absx - y >= 0.5) + y += 1.0; + return copysign(y, x); +} +#endif /* HAVE_ROUND */ + #ifndef HAVE_LOG1P #include Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Sat Apr 18 15:58:18 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 71274 . +# From configure.in Revision: 71663 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.1. # @@ -22310,7 +22310,8 @@ -for ac_func in acosh asinh atanh copysign expm1 finite hypot log1p + +for ac_func in acosh asinh atanh copysign expm1 finite hypot log1p round do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Sat Apr 18 15:58:18 2009 @@ -3337,7 +3337,7 @@ [Define if tanh(-0.) is -0., or if platform doesn't have signed zeros]) fi -AC_CHECK_FUNCS([acosh asinh atanh copysign expm1 finite hypot log1p]) +AC_CHECK_FUNCS([acosh asinh atanh copysign expm1 finite hypot log1p round]) AC_CHECK_DECLS([isinf, isnan, isfinite], [], [], [[#include ]]) LIBS=$LIBS_SAVE Modified: python/branches/py3k/pyconfig.h.in ============================================================================== --- python/branches/py3k/pyconfig.h.in (original) +++ python/branches/py3k/pyconfig.h.in Sat Apr 18 15:58:18 2009 @@ -521,6 +521,9 @@ /* Define if you have readline 4.0 */ #undef HAVE_RL_PRE_INPUT_HOOK +/* Define to 1 if you have the `round' function. */ +#undef HAVE_ROUND + /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT From python-checkins at python.org Sat Apr 18 16:13:58 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 16:13:58 +0200 (CEST) Subject: [Python-checkins] r71705 - python/trunk/Python/pymath.c Message-ID: <20090418141358.1E2C71E4039@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 16:13:43 2009 New Revision: 71705 Log: copysign shouldn't be declared as static in pymath.c Modified: python/trunk/Python/pymath.c Modified: python/trunk/Python/pymath.c ============================================================================== --- python/trunk/Python/pymath.c (original) +++ python/trunk/Python/pymath.c Sat Apr 18 16:13:43 2009 @@ -35,7 +35,7 @@ #endif /* HAVE_HYPOT */ #ifndef HAVE_COPYSIGN -static double +double copysign(double x, double y) { /* use atan2 to distinguish -0. from 0. */ From python-checkins at python.org Sat Apr 18 16:14:49 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 16:14:49 +0200 (CEST) Subject: [Python-checkins] r71706 - in python/branches/py3k: Python/pymath.c Message-ID: <20090418141449.2733A1E4039@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 16:14:48 2009 New Revision: 71706 Log: Merged revisions 71705 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71705 | mark.dickinson | 2009-04-18 15:13:43 +0100 (Sat, 18 Apr 2009) | 2 lines copysign shouldn't be declared as static in pymath.c ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Python/pymath.c Modified: python/branches/py3k/Python/pymath.c ============================================================================== --- python/branches/py3k/Python/pymath.c (original) +++ python/branches/py3k/Python/pymath.c Sat Apr 18 16:14:48 2009 @@ -57,7 +57,7 @@ #endif /* HAVE_HYPOT */ #ifndef HAVE_COPYSIGN -static double +double copysign(double x, double y) { /* use atan2 to distinguish -0. from 0. */ From python-checkins at python.org Sat Apr 18 16:19:58 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 16:19:58 +0200 (CEST) Subject: [Python-checkins] r71707 - in python/branches/release26-maint: Python/pymath.c Message-ID: <20090418141958.D76421E4039@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 16:19:58 2009 New Revision: 71707 Log: Merged revisions 71705 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71705 | mark.dickinson | 2009-04-18 15:13:43 +0100 (Sat, 18 Apr 2009) | 2 lines copysign shouldn't be declared as static in pymath.c ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Python/pymath.c Modified: python/branches/release26-maint/Python/pymath.c ============================================================================== --- python/branches/release26-maint/Python/pymath.c (original) +++ python/branches/release26-maint/Python/pymath.c Sat Apr 18 16:19:58 2009 @@ -22,7 +22,7 @@ #endif /* HAVE_HYPOT */ #ifndef HAVE_COPYSIGN -static double +double copysign(double x, double y) { /* use atan2 to distinguish -0. from 0. */ From python-checkins at python.org Sat Apr 18 16:21:12 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 16:21:12 +0200 (CEST) Subject: [Python-checkins] r71708 - python/branches/release30-maint Message-ID: <20090418142112.3151B1E4039@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 16:21:12 2009 New Revision: 71708 Log: Blocked revisions 71704 via svnmerge ........ r71704 | mark.dickinson | 2009-04-18 14:58:18 +0100 (Sat, 18 Apr 2009) | 3 lines Add check for C99 round function to configure, and define a fallback function if round doesn't exist. ........ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sat Apr 18 16:21:40 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 16:21:40 +0200 (CEST) Subject: [Python-checkins] r71709 - in python/branches/release30-maint: Python/pymath.c Message-ID: <20090418142140.98CA71E4039@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 16:21:40 2009 New Revision: 71709 Log: Merged revisions 71706 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71706 | mark.dickinson | 2009-04-18 15:14:48 +0100 (Sat, 18 Apr 2009) | 9 lines Merged revisions 71705 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71705 | mark.dickinson | 2009-04-18 15:13:43 +0100 (Sat, 18 Apr 2009) | 2 lines copysign shouldn't be declared as static in pymath.c ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Python/pymath.c Modified: python/branches/release30-maint/Python/pymath.c ============================================================================== --- python/branches/release30-maint/Python/pymath.c (original) +++ python/branches/release30-maint/Python/pymath.c Sat Apr 18 16:21:40 2009 @@ -22,7 +22,7 @@ #endif /* HAVE_HYPOT */ #ifndef HAVE_COPYSIGN -static double +double copysign(double x, double y) { /* use atan2 to distinguish -0. from 0. */ From buildbot at python.org Sat Apr 18 16:36:28 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 18 Apr 2009 14:36:28 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090418143628.70CA81E401F@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/276 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_posix test_subprocess ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From python-checkins at python.org Sat Apr 18 16:41:37 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 16:41:37 +0200 (CEST) Subject: [Python-checkins] r71710 - in python/trunk: Include/pymath.h Python/pymath.c configure configure.in pyconfig.h.in Message-ID: <20090418144137.9622E1E40C0@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 16:41:37 2009 New Revision: 71710 Log: Backport r71704 (add configure check for C99 round function) to trunk. Modified: python/trunk/Include/pymath.h python/trunk/Python/pymath.c python/trunk/configure python/trunk/configure.in python/trunk/pyconfig.h.in Modified: python/trunk/Include/pymath.h ============================================================================== --- python/trunk/Include/pymath.h (original) +++ python/trunk/Include/pymath.h Sat Apr 18 16:41:37 2009 @@ -22,6 +22,10 @@ extern double copysign(double, double); #endif +#ifndef HAVE_ROUND +extern double round(double); +#endif + #ifndef HAVE_ACOSH extern double acosh(double); #endif Modified: python/trunk/Python/pymath.c ============================================================================== --- python/trunk/Python/pymath.c (original) +++ python/trunk/Python/pymath.c Sat Apr 18 16:41:37 2009 @@ -47,6 +47,19 @@ } #endif /* HAVE_COPYSIGN */ +#ifndef HAVE_ROUND +double +round(double x) +{ + double absx, y; + absx = fabs(x); + y = floor(absx); + if (absx - y >= 0.5) + y += 1.0; + return copysign(y, x); +} +#endif /* HAVE_ROUND */ + #ifndef HAVE_LOG1P #include Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Sat Apr 18 16:41:37 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 70903 . +# From configure.in Revision: 71009 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.7. # @@ -22169,7 +22169,8 @@ -for ac_func in acosh asinh atanh copysign expm1 finite hypot log1p + +for ac_func in acosh asinh atanh copysign expm1 finite hypot log1p round do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Sat Apr 18 16:41:37 2009 @@ -3250,7 +3250,7 @@ [Define if tanh(-0.) is -0., or if platform doesn't have signed zeros]) fi -AC_CHECK_FUNCS([acosh asinh atanh copysign expm1 finite hypot log1p]) +AC_CHECK_FUNCS([acosh asinh atanh copysign expm1 finite hypot log1p round]) AC_CHECK_DECLS([isinf, isnan, isfinite], [], [], [[#include ]]) LIBS=$LIBS_SAVE Modified: python/trunk/pyconfig.h.in ============================================================================== --- python/trunk/pyconfig.h.in (original) +++ python/trunk/pyconfig.h.in Sat Apr 18 16:41:37 2009 @@ -504,6 +504,9 @@ /* Define if you have readline 4.0 */ #undef HAVE_RL_PRE_INPUT_HOOK +/* Define to 1 if you have the `round' function. */ +#undef HAVE_ROUND + /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT From python-checkins at python.org Sat Apr 18 16:42:41 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 16:42:41 +0200 (CEST) Subject: [Python-checkins] r71711 - python/branches/py3k Message-ID: <20090418144241.4D9221E401F@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 16:42:41 2009 New Revision: 71711 Log: Blocked revisions 71710 via svnmerge ........ r71710 | mark.dickinson | 2009-04-18 15:41:37 +0100 (Sat, 18 Apr 2009) | 2 lines Backport r71704 (add configure check for C99 round function) to trunk. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Apr 18 16:42:49 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 16:42:49 +0200 (CEST) Subject: [Python-checkins] r71712 - python/branches/release26-maint Message-ID: <20090418144249.CEF251E4039@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 16:42:49 2009 New Revision: 71712 Log: Blocked revisions 71710 via svnmerge ........ r71710 | mark.dickinson | 2009-04-18 15:41:37 +0100 (Sat, 18 Apr 2009) | 2 lines Backport r71704 (add configure check for C99 round function) to trunk. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sat Apr 18 16:47:50 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 18 Apr 2009 16:47:50 +0200 (CEST) Subject: [Python-checkins] r71713 - python/branches/py3k/Lib/_pyio.py Message-ID: <20090418144750.A010C1E401F@bag.python.org> Author: benjamin.peterson Date: Sat Apr 18 16:47:50 2009 New Revision: 71713 Log: add annotations to open() Modified: python/branches/py3k/Lib/_pyio.py Modified: python/branches/py3k/Lib/_pyio.py ============================================================================== --- python/branches/py3k/Lib/_pyio.py (original) +++ python/branches/py3k/Lib/_pyio.py Sat Apr 18 16:47:50 2009 @@ -35,8 +35,9 @@ self.characters_written = characters_written -def open(file, mode="r", buffering=None, encoding=None, errors=None, - newline=None, closefd=True): +def open(file: (str, bytes), mode: str = "r", buffering: int = None, + encoding: str = None, errors: str = None, + newline: str = None, closefd: bool = True) -> "IOBase": r"""Open file and return a stream. Raise IOError upon failure. From python-checkins at python.org Sat Apr 18 16:49:19 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 18 Apr 2009 16:49:19 +0200 (CEST) Subject: [Python-checkins] r71714 - python/branches/py3k/Lib/test/test_io.py Message-ID: <20090418144919.980EC1E40DF@bag.python.org> Author: benjamin.peterson Date: Sat Apr 18 16:49:19 2009 New Revision: 71714 Log: use the more offical skipping api Modified: python/branches/py3k/Lib/test/test_io.py 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 Sat Apr 18 16:49:19 2009 @@ -509,11 +509,11 @@ # Issue #1174606: reading from an unbounded stream such as /dev/zero. zero = "/dev/zero" if not os.path.exists(zero): - raise unittest.SkipTest("{0} does not exist".format(zero)) + self.skip("{0} does not exist".format(zero)) if sys.maxsize > 0x7FFFFFFF: - raise unittest.SkipTest("test can only run in a 32-bit address space") + self.skip("test can only run in a 32-bit address space") if support.real_max_memuse < support._2G: - raise unittest.SkipTest("test requires at least 2GB of memory") + self.skip("test requires at least 2GB of memory") with open(zero, "rb", buffering=0) as f: self.assertRaises(OverflowError, f.read) with open(zero, "rb") as f: From python-checkins at python.org Sat Apr 18 16:59:42 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 16:59:42 +0200 (CEST) Subject: [Python-checkins] r71715 - in python/trunk: Lib/test/test_builtin.py Misc/NEWS Python/bltinmodule.c Message-ID: <20090418145942.9CAD21E401F@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 16:59:42 2009 New Revision: 71715 Log: Issue #1869: Fix a couple of minor round() issues. Modified: python/trunk/Lib/test/test_builtin.py python/trunk/Misc/NEWS python/trunk/Python/bltinmodule.c Modified: python/trunk/Lib/test/test_builtin.py ============================================================================== --- python/trunk/Lib/test/test_builtin.py (original) +++ python/trunk/Lib/test/test_builtin.py Sat Apr 18 16:59:42 2009 @@ -1224,6 +1224,9 @@ self.assertEqual(round(-5.5), -6) self.assertEqual(round(-6.5), -7) + # Issue #1869: integral floats should remain unchanged + self.assertEqual(round(5e15+1), 5e15+1) + # Check behavior on ints self.assertEqual(round(0), 0) self.assertEqual(round(8), 8) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Apr 18 16:59:42 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #1869: fix a couple of minor round() issues. round(5e15+1) + was giving 5e15+2; round(-0.0) was losing the sign of the zero. + - Issue #5759: float() didn't call __float__ on str subclasses. - Issue #5704: the "-3" command-line option now implies "-t". Modified: python/trunk/Python/bltinmodule.c ============================================================================== --- python/trunk/Python/bltinmodule.c (original) +++ python/trunk/Python/bltinmodule.c Sat Apr 18 16:59:42 2009 @@ -2081,10 +2081,7 @@ number /= f; else number *= f; - if (number >= 0.0) - number = floor(number + 0.5); - else - number = ceil(number - 0.5); + number = round(number); if (ndigits < 0) number *= f; else From python-checkins at python.org Sat Apr 18 17:00:19 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 17:00:19 +0200 (CEST) Subject: [Python-checkins] r71716 - python/branches/release26-maint Message-ID: <20090418150019.2E34F1E401F@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 17:00:18 2009 New Revision: 71716 Log: Blocked revisions 71715 via svnmerge ........ r71715 | mark.dickinson | 2009-04-18 15:59:42 +0100 (Sat, 18 Apr 2009) | 2 lines Issue #1869: Fix a couple of minor round() issues. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sat Apr 18 17:01:12 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 17:01:12 +0200 (CEST) Subject: [Python-checkins] r71717 - python/branches/py3k Message-ID: <20090418150112.CBE131E401F@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 17:01:12 2009 New Revision: 71717 Log: Blocked revisions 71715 via svnmerge ........ r71715 | mark.dickinson | 2009-04-18 15:59:42 +0100 (Sat, 18 Apr 2009) | 2 lines Issue #1869: Fix a couple of minor round() issues. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Apr 18 17:17:03 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 18 Apr 2009 17:17:03 +0200 (CEST) Subject: [Python-checkins] r71718 - python/branches/py3k/Objects/bytesobject.c Message-ID: <20090418151703.2393E1E401F@bag.python.org> Author: benjamin.peterson Date: Sat Apr 18 17:17:02 2009 New Revision: 71718 Log: rename internal methods of the bytes object to bytes_ Modified: python/branches/py3k/Objects/bytesobject.c Modified: python/branches/py3k/Objects/bytesobject.c ============================================================================== --- python/branches/py3k/Objects/bytesobject.c (original) +++ python/branches/py3k/Objects/bytesobject.c Sat Apr 18 17:17:02 2009 @@ -365,7 +365,7 @@ } static void -string_dealloc(PyObject *op) +bytes_dealloc(PyObject *op) { Py_TYPE(op)->tp_free(op); } @@ -662,31 +662,31 @@ } static PyObject * -string_repr(PyObject *op) +bytes_repr(PyObject *op) { return PyBytes_Repr(op, 1); } static PyObject * -string_str(PyObject *op) +bytes_str(PyObject *op) { if (Py_BytesWarningFlag) { if (PyErr_WarnEx(PyExc_BytesWarning, "str() on a bytes instance", 1)) return NULL; } - return string_repr(op); + return bytes_repr(op); } static Py_ssize_t -string_length(PyBytesObject *a) +bytes_length(PyBytesObject *a) { return Py_SIZE(a); } /* This is also used by PyBytes_Concat() */ static PyObject * -string_concat(PyObject *a, PyObject *b) +bytes_concat(PyObject *a, PyObject *b) { Py_ssize_t size; Py_buffer va, vb; @@ -734,7 +734,7 @@ } static PyObject * -string_repeat(register PyBytesObject *a, register Py_ssize_t n) +bytes_repeat(register PyBytesObject *a, register Py_ssize_t n) { register Py_ssize_t i; register Py_ssize_t j; @@ -786,7 +786,7 @@ } static int -string_contains(PyObject *self, PyObject *arg) +bytes_contains(PyObject *self, PyObject *arg) { Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError); if (ival == -1 && PyErr_Occurred()) { @@ -809,7 +809,7 @@ } static PyObject * -string_item(PyBytesObject *a, register Py_ssize_t i) +bytes_item(PyBytesObject *a, register Py_ssize_t i) { if (i < 0 || i >= Py_SIZE(a)) { PyErr_SetString(PyExc_IndexError, "index out of range"); @@ -819,7 +819,7 @@ } static PyObject* -string_richcompare(PyBytesObject *a, PyBytesObject *b, int op) +bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op) { int c; Py_ssize_t len_a, len_b; @@ -890,7 +890,7 @@ } static long -string_hash(PyBytesObject *a) +bytes_hash(PyBytesObject *a) { register Py_ssize_t len; register unsigned char *p; @@ -911,7 +911,7 @@ } static PyObject* -string_subscript(PyBytesObject* self, PyObject* item) +bytes_subscript(PyBytesObject* self, PyObject* item) { if (PyIndex_Check(item)) { Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); @@ -976,31 +976,31 @@ } static int -string_buffer_getbuffer(PyBytesObject *self, Py_buffer *view, int flags) +bytes_buffer_getbuffer(PyBytesObject *self, Py_buffer *view, int flags) { return PyBuffer_FillInfo(view, (PyObject*)self, (void *)self->ob_sval, Py_SIZE(self), 1, flags); } -static PySequenceMethods string_as_sequence = { - (lenfunc)string_length, /*sq_length*/ - (binaryfunc)string_concat, /*sq_concat*/ - (ssizeargfunc)string_repeat, /*sq_repeat*/ - (ssizeargfunc)string_item, /*sq_item*/ +static PySequenceMethods bytes_as_sequence = { + (lenfunc)bytes_length, /*sq_length*/ + (binaryfunc)bytes_concat, /*sq_concat*/ + (ssizeargfunc)bytes_repeat, /*sq_repeat*/ + (ssizeargfunc)bytes_item, /*sq_item*/ 0, /*sq_slice*/ 0, /*sq_ass_item*/ 0, /*sq_ass_slice*/ - (objobjproc)string_contains /*sq_contains*/ + (objobjproc)bytes_contains /*sq_contains*/ }; -static PyMappingMethods string_as_mapping = { - (lenfunc)string_length, - (binaryfunc)string_subscript, +static PyMappingMethods bytes_as_mapping = { + (lenfunc)bytes_length, + (binaryfunc)bytes_subscript, 0, }; -static PyBufferProcs string_as_buffer = { - (getbufferproc)string_buffer_getbuffer, +static PyBufferProcs bytes_as_buffer = { + (getbufferproc)bytes_buffer_getbuffer, NULL, }; @@ -1150,7 +1150,7 @@ If maxsplit is given, at most maxsplit splits are done."); static PyObject * -string_split(PyBytesObject *self, PyObject *args) +bytes_split(PyBytesObject *self, PyObject *args) { Py_ssize_t len = PyBytes_GET_SIZE(self), n, i, j; Py_ssize_t maxsplit = -1, count=0; @@ -1230,7 +1230,7 @@ found, returns B and two empty bytes objects."); static PyObject * -string_partition(PyBytesObject *self, PyObject *sep_obj) +bytes_partition(PyBytesObject *self, PyObject *sep_obj) { const char *sep; Py_ssize_t sep_len; @@ -1258,7 +1258,7 @@ bytes objects and B."); static PyObject * -string_rpartition(PyBytesObject *self, PyObject *sep_obj) +bytes_rpartition(PyBytesObject *self, PyObject *sep_obj) { const char *sep; Py_ssize_t sep_len; @@ -1372,7 +1372,7 @@ static PyObject * -string_rsplit(PyBytesObject *self, PyObject *args) +bytes_rsplit(PyBytesObject *self, PyObject *args) { Py_ssize_t len = PyBytes_GET_SIZE(self), n, i, j; Py_ssize_t maxsplit = -1, count=0; @@ -1447,7 +1447,7 @@ Example: b'.'.join([b'ab', b'pq', b'rs']) -> b'ab.pq.rs'."); static PyObject * -string_join(PyObject *self, PyObject *orig) +bytes_join(PyObject *self, PyObject *orig) { char *sep = PyBytes_AS_STRING(self); const Py_ssize_t seplen = PyBytes_GET_SIZE(self); @@ -1542,11 +1542,11 @@ { assert(sep != NULL && PyBytes_Check(sep)); assert(x != NULL); - return string_join(sep, x); + return bytes_join(sep, x); } Py_LOCAL_INLINE(void) -string_adjust_indices(Py_ssize_t *start, Py_ssize_t *end, Py_ssize_t len) +bytes_adjust_indices(Py_ssize_t *start, Py_ssize_t *end, Py_ssize_t len) { if (*end > len) *end = len; @@ -1561,7 +1561,7 @@ } Py_LOCAL_INLINE(Py_ssize_t) -string_find_internal(PyBytesObject *self, PyObject *args, int dir) +bytes_find_internal(PyBytesObject *self, PyObject *args, int dir) { PyObject *subobj; const char *sub; @@ -1612,9 +1612,9 @@ Return -1 on failure."); static PyObject * -string_find(PyBytesObject *self, PyObject *args) +bytes_find(PyBytesObject *self, PyObject *args) { - Py_ssize_t result = string_find_internal(self, args, +1); + Py_ssize_t result = bytes_find_internal(self, args, +1); if (result == -2) return NULL; return PyLong_FromSsize_t(result); @@ -1627,9 +1627,9 @@ Like B.find() but raise ValueError when the substring is not found."); static PyObject * -string_index(PyBytesObject *self, PyObject *args) +bytes_index(PyBytesObject *self, PyObject *args) { - Py_ssize_t result = string_find_internal(self, args, +1); + Py_ssize_t result = bytes_find_internal(self, args, +1); if (result == -2) return NULL; if (result == -1) { @@ -1651,9 +1651,9 @@ Return -1 on failure."); static PyObject * -string_rfind(PyBytesObject *self, PyObject *args) +bytes_rfind(PyBytesObject *self, PyObject *args) { - Py_ssize_t result = string_find_internal(self, args, -1); + Py_ssize_t result = bytes_find_internal(self, args, -1); if (result == -2) return NULL; return PyLong_FromSsize_t(result); @@ -1666,9 +1666,9 @@ Like B.rfind() but raise ValueError when the substring is not found."); static PyObject * -string_rindex(PyBytesObject *self, PyObject *args) +bytes_rindex(PyBytesObject *self, PyObject *args) { - Py_ssize_t result = string_find_internal(self, args, -1); + Py_ssize_t result = bytes_find_internal(self, args, -1); if (result == -2) return NULL; if (result == -1) { @@ -1772,7 +1772,7 @@ Strip leading and trailing bytes contained in the argument.\n\ If the argument is omitted, strip trailing ASCII whitespace."); static PyObject * -string_strip(PyBytesObject *self, PyObject *args) +bytes_strip(PyBytesObject *self, PyObject *args) { if (PyTuple_GET_SIZE(args) == 0) return do_strip(self, BOTHSTRIP); /* Common case */ @@ -1787,7 +1787,7 @@ Strip leading bytes contained in the argument.\n\ If the argument is omitted, strip leading ASCII whitespace."); static PyObject * -string_lstrip(PyBytesObject *self, PyObject *args) +bytes_lstrip(PyBytesObject *self, PyObject *args) { if (PyTuple_GET_SIZE(args) == 0) return do_strip(self, LEFTSTRIP); /* Common case */ @@ -1802,7 +1802,7 @@ Strip trailing bytes contained in the argument.\n\ If the argument is omitted, strip trailing ASCII whitespace."); static PyObject * -string_rstrip(PyBytesObject *self, PyObject *args) +bytes_rstrip(PyBytesObject *self, PyObject *args) { if (PyTuple_GET_SIZE(args) == 0) return do_strip(self, RIGHTSTRIP); /* Common case */ @@ -1819,7 +1819,7 @@ as in slice notation."); static PyObject * -string_count(PyBytesObject *self, PyObject *args) +bytes_count(PyBytesObject *self, PyObject *args) { PyObject *sub_obj; const char *str = PyBytes_AS_STRING(self), *sub; @@ -1837,7 +1837,7 @@ else if (PyObject_AsCharBuffer(sub_obj, &sub, &sub_len)) return NULL; - string_adjust_indices(&start, &end, PyBytes_GET_SIZE(self)); + bytes_adjust_indices(&start, &end, PyBytes_GET_SIZE(self)); return PyLong_FromSsize_t( stringlib_count(str + start, end - start, sub, sub_len) @@ -1854,7 +1854,7 @@ table, which must be a bytes object of length 256."); static PyObject * -string_translate(PyBytesObject *self, PyObject *args) +bytes_translate(PyBytesObject *self, PyObject *args) { register char *input, *output; const char *table; @@ -1952,7 +1952,7 @@ static PyObject * -string_maketrans(PyObject *null, PyObject *args) +bytes_maketrans(PyObject *null, PyObject *args) { return _Py_bytes_maketrans(args); } @@ -2560,7 +2560,7 @@ given, only the first count occurrences are replaced."); static PyObject * -string_replace(PyBytesObject *self, PyObject *args) +bytes_replace(PyBytesObject *self, PyObject *args) { Py_ssize_t count = -1; PyObject *from, *to; @@ -2596,7 +2596,7 @@ * -1 on error, 0 if not found and 1 if found. */ Py_LOCAL(int) -_string_tailmatch(PyBytesObject *self, PyObject *substr, Py_ssize_t start, +_bytes_tailmatch(PyBytesObject *self, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction) { Py_ssize_t len = PyBytes_GET_SIZE(self); @@ -2612,7 +2612,7 @@ return -1; str = PyBytes_AS_STRING(self); - string_adjust_indices(&start, &end, len); + bytes_adjust_indices(&start, &end, len); if (direction < 0) { /* startswith */ @@ -2641,7 +2641,7 @@ prefix can also be a tuple of bytes to try."); static PyObject * -string_startswith(PyBytesObject *self, PyObject *args) +bytes_startswith(PyBytesObject *self, PyObject *args) { Py_ssize_t start = 0; Py_ssize_t end = PY_SSIZE_T_MAX; @@ -2654,7 +2654,7 @@ if (PyTuple_Check(subobj)) { Py_ssize_t i; for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) { - result = _string_tailmatch(self, + result = _bytes_tailmatch(self, PyTuple_GET_ITEM(subobj, i), start, end, -1); if (result == -1) @@ -2665,7 +2665,7 @@ } Py_RETURN_FALSE; } - result = _string_tailmatch(self, subobj, start, end, -1); + result = _bytes_tailmatch(self, subobj, start, end, -1); if (result == -1) return NULL; else @@ -2682,7 +2682,7 @@ suffix can also be a tuple of bytes to try."); static PyObject * -string_endswith(PyBytesObject *self, PyObject *args) +bytes_endswith(PyBytesObject *self, PyObject *args) { Py_ssize_t start = 0; Py_ssize_t end = PY_SSIZE_T_MAX; @@ -2695,7 +2695,7 @@ if (PyTuple_Check(subobj)) { Py_ssize_t i; for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) { - result = _string_tailmatch(self, + result = _bytes_tailmatch(self, PyTuple_GET_ITEM(subobj, i), start, end, +1); if (result == -1) @@ -2706,7 +2706,7 @@ } Py_RETURN_FALSE; } - result = _string_tailmatch(self, subobj, start, end, +1); + result = _bytes_tailmatch(self, subobj, start, end, +1); if (result == -1) return NULL; else @@ -2725,7 +2725,7 @@ able to handle UnicodeDecodeErrors."); static PyObject * -string_decode(PyObject *self, PyObject *args) +bytes_decode(PyObject *self, PyObject *args) { const char *encoding = NULL; const char *errors = NULL; @@ -2762,7 +2762,7 @@ } static PyObject * -string_fromhex(PyObject *cls, PyObject *args) +bytes_fromhex(PyObject *cls, PyObject *args) { PyObject *newstring, *hexobj; char *buf; @@ -2806,10 +2806,10 @@ } PyDoc_STRVAR(sizeof__doc__, -"S.__sizeof__() -> size of S in memory, in bytes"); +"B.__sizeof__() -> size of B in memory, in bytes"); static PyObject * -string_sizeof(PyBytesObject *v) +bytes_sizeof(PyBytesObject *v) { Py_ssize_t res; res = PyBytesObject_SIZE + Py_SIZE(v) * Py_TYPE(v)->tp_itemsize; @@ -2818,28 +2818,28 @@ static PyObject * -string_getnewargs(PyBytesObject *v) +bytes_getnewargs(PyBytesObject *v) { return Py_BuildValue("(s#)", v->ob_sval, Py_SIZE(v)); } static PyMethodDef -string_methods[] = { - {"__getnewargs__", (PyCFunction)string_getnewargs, METH_NOARGS}, +bytes_methods[] = { + {"__getnewargs__", (PyCFunction)bytes_getnewargs, METH_NOARGS}, {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS, _Py_capitalize__doc__}, {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__}, - {"count", (PyCFunction)string_count, METH_VARARGS, count__doc__}, - {"decode", (PyCFunction)string_decode, METH_VARARGS, decode__doc__}, - {"endswith", (PyCFunction)string_endswith, METH_VARARGS, + {"count", (PyCFunction)bytes_count, METH_VARARGS, count__doc__}, + {"decode", (PyCFunction)bytes_decode, METH_VARARGS, decode__doc__}, + {"endswith", (PyCFunction)bytes_endswith, METH_VARARGS, endswith__doc__}, {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS, expandtabs__doc__}, - {"find", (PyCFunction)string_find, METH_VARARGS, find__doc__}, - {"fromhex", (PyCFunction)string_fromhex, METH_VARARGS|METH_CLASS, + {"find", (PyCFunction)bytes_find, METH_VARARGS, find__doc__}, + {"fromhex", (PyCFunction)bytes_fromhex, METH_VARARGS|METH_CLASS, fromhex_doc}, - {"index", (PyCFunction)string_index, METH_VARARGS, index__doc__}, + {"index", (PyCFunction)bytes_index, METH_VARARGS, index__doc__}, {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS, _Py_isalnum__doc__}, {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS, @@ -2854,35 +2854,35 @@ _Py_istitle__doc__}, {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS, _Py_isupper__doc__}, - {"join", (PyCFunction)string_join, METH_O, join__doc__}, + {"join", (PyCFunction)bytes_join, METH_O, join__doc__}, {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__}, {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__}, - {"lstrip", (PyCFunction)string_lstrip, METH_VARARGS, lstrip__doc__}, - {"maketrans", (PyCFunction)string_maketrans, METH_VARARGS|METH_STATIC, + {"lstrip", (PyCFunction)bytes_lstrip, METH_VARARGS, lstrip__doc__}, + {"maketrans", (PyCFunction)bytes_maketrans, METH_VARARGS|METH_STATIC, _Py_maketrans__doc__}, - {"partition", (PyCFunction)string_partition, METH_O, partition__doc__}, - {"replace", (PyCFunction)string_replace, METH_VARARGS, replace__doc__}, - {"rfind", (PyCFunction)string_rfind, METH_VARARGS, rfind__doc__}, - {"rindex", (PyCFunction)string_rindex, METH_VARARGS, rindex__doc__}, + {"partition", (PyCFunction)bytes_partition, METH_O, partition__doc__}, + {"replace", (PyCFunction)bytes_replace, METH_VARARGS, replace__doc__}, + {"rfind", (PyCFunction)bytes_rfind, METH_VARARGS, rfind__doc__}, + {"rindex", (PyCFunction)bytes_rindex, METH_VARARGS, rindex__doc__}, {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__}, - {"rpartition", (PyCFunction)string_rpartition, METH_O, + {"rpartition", (PyCFunction)bytes_rpartition, METH_O, rpartition__doc__}, - {"rsplit", (PyCFunction)string_rsplit, METH_VARARGS, rsplit__doc__}, - {"rstrip", (PyCFunction)string_rstrip, METH_VARARGS, rstrip__doc__}, - {"split", (PyCFunction)string_split, METH_VARARGS, split__doc__}, + {"rsplit", (PyCFunction)bytes_rsplit, METH_VARARGS, rsplit__doc__}, + {"rstrip", (PyCFunction)bytes_rstrip, METH_VARARGS, rstrip__doc__}, + {"split", (PyCFunction)bytes_split, METH_VARARGS, split__doc__}, {"splitlines", (PyCFunction)stringlib_splitlines, METH_VARARGS, splitlines__doc__}, - {"startswith", (PyCFunction)string_startswith, METH_VARARGS, + {"startswith", (PyCFunction)bytes_startswith, METH_VARARGS, startswith__doc__}, - {"strip", (PyCFunction)string_strip, METH_VARARGS, strip__doc__}, + {"strip", (PyCFunction)bytes_strip, METH_VARARGS, strip__doc__}, {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, _Py_swapcase__doc__}, {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, - {"translate", (PyCFunction)string_translate, METH_VARARGS, + {"translate", (PyCFunction)bytes_translate, METH_VARARGS, translate__doc__}, {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__}, - {"__sizeof__", (PyCFunction)string_sizeof, METH_NOARGS, + {"__sizeof__", (PyCFunction)bytes_sizeof, METH_NOARGS, sizeof__doc__}, {NULL, NULL} /* sentinel */ }; @@ -2891,7 +2891,7 @@ str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static PyObject * -string_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *x = NULL; const char *encoding = NULL; @@ -3058,7 +3058,7 @@ Py_ssize_t n; assert(PyType_IsSubtype(type, &PyBytes_Type)); - tmp = string_new(&PyBytes_Type, args, kwds); + tmp = bytes_new(&PyBytes_Type, args, kwds); if (tmp == NULL) return NULL; assert(PyBytes_CheckExact(tmp)); @@ -3074,7 +3074,7 @@ return pnew; } -PyDoc_STRVAR(string_doc, +PyDoc_STRVAR(bytes_doc, "bytes(iterable_of_ints) -> bytes\n\ bytes(string, encoding[, errors]) -> bytes\n\ bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer\n\ @@ -3086,38 +3086,38 @@ - a bytes or a buffer object\n\ - any object implementing the buffer API."); -static PyObject *str_iter(PyObject *seq); +static PyObject *bytes_iter(PyObject *seq); PyTypeObject PyBytes_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "bytes", PyBytesObject_SIZE, sizeof(char), - string_dealloc, /* tp_dealloc */ + bytes_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ - (reprfunc)string_repr, /* tp_repr */ + (reprfunc)bytes_repr, /* tp_repr */ 0, /* tp_as_number */ - &string_as_sequence, /* tp_as_sequence */ - &string_as_mapping, /* tp_as_mapping */ - (hashfunc)string_hash, /* tp_hash */ + &bytes_as_sequence, /* tp_as_sequence */ + &bytes_as_mapping, /* tp_as_mapping */ + (hashfunc)bytes_hash, /* tp_hash */ 0, /* tp_call */ - string_str, /* tp_str */ + bytes_str, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ - &string_as_buffer, /* tp_as_buffer */ + &bytes_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_BYTES_SUBCLASS, /* tp_flags */ - string_doc, /* tp_doc */ + bytes_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ - (richcmpfunc)string_richcompare, /* tp_richcompare */ + (richcmpfunc)bytes_richcompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ - str_iter, /* tp_iter */ + bytes_iter, /* tp_iter */ 0, /* tp_iternext */ - string_methods, /* tp_methods */ + bytes_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ &PyBaseObject_Type, /* tp_base */ @@ -3127,7 +3127,7 @@ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - string_new, /* tp_new */ + bytes_new, /* tp_new */ PyObject_Del, /* tp_free */ }; @@ -3143,7 +3143,7 @@ *pv = NULL; return; } - v = string_concat(*pv, w); + v = bytes_concat(*pv, w); Py_DECREF(*pv); *pv = v; } @@ -3455,7 +3455,7 @@ }; static PyObject * -str_iter(PyObject *seq) +bytes_iter(PyObject *seq) { striterobject *it; From buildbot at python.org Sat Apr 18 17:23:32 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 18 Apr 2009 15:23:32 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 2.6 Message-ID: <20090418152332.638F11E401F@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%202.6/builds/228 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Sat Apr 18 17:31:35 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 18 Apr 2009 17:31:35 +0200 (CEST) Subject: [Python-checkins] r71719 - python/trunk/Objects/bytearrayobject.c Message-ID: <20090418153135.4FE6F1E401F@bag.python.org> Author: benjamin.peterson Date: Sat Apr 18 17:31:34 2009 New Revision: 71719 Log: rename internal bytes_ functions to bytearray Modified: python/trunk/Objects/bytearrayobject.c Modified: python/trunk/Objects/bytearrayobject.c ============================================================================== --- python/trunk/Objects/bytearrayobject.c (original) +++ python/trunk/Objects/bytearrayobject.c Sat Apr 18 17:31:34 2009 @@ -67,7 +67,7 @@ } static Py_ssize_t -bytes_buffer_getreadbuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr) +bytearray_buffer_getreadbuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr) { if ( index != 0 ) { PyErr_SetString(PyExc_SystemError, @@ -79,7 +79,7 @@ } static Py_ssize_t -bytes_buffer_getwritebuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr) +bytearray_buffer_getwritebuf(PyByteArrayObject *self, Py_ssize_t index, const void **ptr) { if ( index != 0 ) { PyErr_SetString(PyExc_SystemError, @@ -91,7 +91,7 @@ } static Py_ssize_t -bytes_buffer_getsegcount(PyByteArrayObject *self, Py_ssize_t *lenp) +bytearray_buffer_getsegcount(PyByteArrayObject *self, Py_ssize_t *lenp) { if ( lenp ) *lenp = Py_SIZE(self); @@ -99,7 +99,7 @@ } static Py_ssize_t -bytes_buffer_getcharbuf(PyByteArrayObject *self, Py_ssize_t index, const char **ptr) +bytearray_buffer_getcharbuf(PyByteArrayObject *self, Py_ssize_t index, const char **ptr) { if ( index != 0 ) { PyErr_SetString(PyExc_SystemError, @@ -111,7 +111,7 @@ } static int -bytes_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags) +bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags) { int ret; void *ptr; @@ -131,7 +131,7 @@ } static void -bytes_releasebuffer(PyByteArrayObject *obj, Py_buffer *view) +bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view) { obj->ob_exports--; } @@ -319,13 +319,13 @@ /* Functions stuffed into the type object */ static Py_ssize_t -bytes_length(PyByteArrayObject *self) +bytearray_length(PyByteArrayObject *self) { return Py_SIZE(self); } static PyObject * -bytes_iconcat(PyByteArrayObject *self, PyObject *other) +bytearray_iconcat(PyByteArrayObject *self, PyObject *other) { Py_ssize_t mysize; Py_ssize_t size; @@ -358,7 +358,7 @@ } static PyObject * -bytes_repeat(PyByteArrayObject *self, Py_ssize_t count) +bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count) { PyByteArrayObject *result; Py_ssize_t mysize; @@ -384,7 +384,7 @@ } static PyObject * -bytes_irepeat(PyByteArrayObject *self, Py_ssize_t count) +bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count) { Py_ssize_t mysize; Py_ssize_t size; @@ -415,7 +415,7 @@ } static PyObject * -bytes_getitem(PyByteArrayObject *self, Py_ssize_t i) +bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i) { if (i < 0) i += Py_SIZE(self); @@ -427,7 +427,7 @@ } static PyObject * -bytes_subscript(PyByteArrayObject *self, PyObject *index) +bytearray_subscript(PyByteArrayObject *self, PyObject *index) { if (PyIndex_Check(index)) { Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError); @@ -482,7 +482,7 @@ } static int -bytes_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi, +bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi, PyObject *values) { Py_ssize_t avail, needed; @@ -497,7 +497,7 @@ values = PyByteArray_FromObject(values); if (values == NULL) return -1; - err = bytes_setslice(self, lo, hi, values); + err = bytearray_setslice(self, lo, hi, values); Py_DECREF(values); return err; } @@ -572,7 +572,7 @@ } static int -bytes_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value) +bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value) { int ival; @@ -585,7 +585,7 @@ } if (value == NULL) - return bytes_setslice(self, i, i+1, NULL); + return bytearray_setslice(self, i, i+1, NULL); if (!_getbytevalue(value, &ival)) return -1; @@ -595,7 +595,7 @@ } static int -bytes_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values) +bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values) { Py_ssize_t start, stop, step, slicelen, needed; char *bytes; @@ -651,7 +651,7 @@ values = PyByteArray_FromObject(values); if (values == NULL) return -1; - err = bytes_ass_subscript(self, index, values); + err = bytearray_ass_subscript(self, index, values); Py_DECREF(values); return err; } @@ -752,7 +752,7 @@ } static int -bytes_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds) +bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"source", "encoding", "errors", 0}; PyObject *arg = NULL; @@ -795,7 +795,7 @@ encoded = arg; Py_INCREF(arg); } - new = bytes_iconcat(self, arg); + new = bytearray_iconcat(self, arg); Py_DECREF(encoded); if (new == NULL) return -1; @@ -816,7 +816,7 @@ if (encoded == NULL) return -1; assert(PyBytes_Check(encoded)); - new = bytes_iconcat(self, encoded); + new = bytearray_iconcat(self, encoded); Py_DECREF(encoded); if (new == NULL) return -1; @@ -917,7 +917,7 @@ /* Mostly copied from string_repr, but without the "smart quote" functionality. */ static PyObject * -bytes_repr(PyByteArrayObject *self) +bytearray_repr(PyByteArrayObject *self) { static const char *hexdigits = "0123456789abcdef"; const char *quote_prefix = "bytearray(b"; @@ -1002,7 +1002,7 @@ } static PyObject * -bytes_str(PyObject *op) +bytearray_str(PyObject *op) { #if 0 if (Py_BytesWarningFlag) { @@ -1010,13 +1010,13 @@ "str() on a bytearray instance", 1)) return NULL; } - return bytes_repr((PyByteArrayObject*)op); + return bytearray_repr((PyByteArrayObject*)op); #endif return PyBytes_FromStringAndSize(((PyByteArrayObject*)op)->ob_bytes, Py_SIZE(op)); } static PyObject * -bytes_richcompare(PyObject *self, PyObject *other, int op) +bytearray_richcompare(PyObject *self, PyObject *other, int op) { Py_ssize_t self_size, other_size; Py_buffer self_bytes, other_bytes; @@ -1093,7 +1093,7 @@ } static void -bytes_dealloc(PyByteArrayObject *self) +bytearray_dealloc(PyByteArrayObject *self) { if (self->ob_exports > 0) { PyErr_SetString(PyExc_SystemError, @@ -1148,7 +1148,7 @@ Py_LOCAL_INLINE(Py_ssize_t) -bytes_find_internal(PyByteArrayObject *self, PyObject *args, int dir) +bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir) { PyObject *subobj; Py_buffer subbuf; @@ -1182,9 +1182,9 @@ Return -1 on failure."); static PyObject * -bytes_find(PyByteArrayObject *self, PyObject *args) +bytearray_find(PyByteArrayObject *self, PyObject *args) { - Py_ssize_t result = bytes_find_internal(self, args, +1); + Py_ssize_t result = bytearray_find_internal(self, args, +1); if (result == -2) return NULL; return PyInt_FromSsize_t(result); @@ -1198,7 +1198,7 @@ as in slice notation."); static PyObject * -bytes_count(PyByteArrayObject *self, PyObject *args) +bytearray_count(PyByteArrayObject *self, PyObject *args) { PyObject *sub_obj; const char *str = PyByteArray_AS_STRING(self); @@ -1229,9 +1229,9 @@ Like B.find() but raise ValueError when the subsection is not found."); static PyObject * -bytes_index(PyByteArrayObject *self, PyObject *args) +bytearray_index(PyByteArrayObject *self, PyObject *args) { - Py_ssize_t result = bytes_find_internal(self, args, +1); + Py_ssize_t result = bytearray_find_internal(self, args, +1); if (result == -2) return NULL; if (result == -1) { @@ -1253,9 +1253,9 @@ Return -1 on failure."); static PyObject * -bytes_rfind(PyByteArrayObject *self, PyObject *args) +bytearray_rfind(PyByteArrayObject *self, PyObject *args) { - Py_ssize_t result = bytes_find_internal(self, args, -1); + Py_ssize_t result = bytearray_find_internal(self, args, -1); if (result == -2) return NULL; return PyInt_FromSsize_t(result); @@ -1268,9 +1268,9 @@ Like B.rfind() but raise ValueError when the subsection is not found."); static PyObject * -bytes_rindex(PyByteArrayObject *self, PyObject *args) +bytearray_rindex(PyByteArrayObject *self, PyObject *args) { - Py_ssize_t result = bytes_find_internal(self, args, -1); + Py_ssize_t result = bytearray_find_internal(self, args, -1); if (result == -2) return NULL; if (result == -1) { @@ -1283,7 +1283,7 @@ static int -bytes_contains(PyObject *self, PyObject *arg) +bytearray_contains(PyObject *self, PyObject *arg) { Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError); if (ival == -1 && PyErr_Occurred()) { @@ -1311,7 +1311,7 @@ * -1 on error, 0 if not found and 1 if found. */ Py_LOCAL(int) -_bytes_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start, +_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction) { Py_ssize_t len = PyByteArray_GET_SIZE(self); @@ -1358,7 +1358,7 @@ prefix can also be a tuple of strings to try."); static PyObject * -bytes_startswith(PyByteArrayObject *self, PyObject *args) +bytearray_startswith(PyByteArrayObject *self, PyObject *args) { Py_ssize_t start = 0; Py_ssize_t end = PY_SSIZE_T_MAX; @@ -1371,7 +1371,7 @@ if (PyTuple_Check(subobj)) { Py_ssize_t i; for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) { - result = _bytes_tailmatch(self, + result = _bytearray_tailmatch(self, PyTuple_GET_ITEM(subobj, i), start, end, -1); if (result == -1) @@ -1382,7 +1382,7 @@ } Py_RETURN_FALSE; } - result = _bytes_tailmatch(self, subobj, start, end, -1); + result = _bytearray_tailmatch(self, subobj, start, end, -1); if (result == -1) return NULL; else @@ -1398,7 +1398,7 @@ suffix can also be a tuple of strings to try."); static PyObject * -bytes_endswith(PyByteArrayObject *self, PyObject *args) +bytearray_endswith(PyByteArrayObject *self, PyObject *args) { Py_ssize_t start = 0; Py_ssize_t end = PY_SSIZE_T_MAX; @@ -1411,7 +1411,7 @@ if (PyTuple_Check(subobj)) { Py_ssize_t i; for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) { - result = _bytes_tailmatch(self, + result = _bytearray_tailmatch(self, PyTuple_GET_ITEM(subobj, i), start, end, +1); if (result == -1) @@ -1422,7 +1422,7 @@ } Py_RETURN_FALSE; } - result = _bytes_tailmatch(self, subobj, start, end, +1); + result = _bytearray_tailmatch(self, subobj, start, end, +1); if (result == -1) return NULL; else @@ -1439,7 +1439,7 @@ table, which must be a bytes object of length 256."); static PyObject * -bytes_translate(PyByteArrayObject *self, PyObject *args) +bytearray_translate(PyByteArrayObject *self, PyObject *args) { register char *input, *output; register const char *table; @@ -2127,7 +2127,7 @@ given, only the first count occurrences are replaced."); static PyObject * -bytes_replace(PyByteArrayObject *self, PyObject *args) +bytearray_replace(PyByteArrayObject *self, PyObject *args) { Py_ssize_t count = -1; PyObject *from, *to, *res; @@ -2278,7 +2278,7 @@ If maxsplit is given, at most maxsplit splits are done."); static PyObject * -bytes_split(PyByteArrayObject *self, PyObject *args) +bytearray_split(PyByteArrayObject *self, PyObject *args) { Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j; Py_ssize_t maxsplit = -1, count = 0; @@ -2385,7 +2385,7 @@ found, returns B and two empty bytearray objects."); static PyObject * -bytes_partition(PyByteArrayObject *self, PyObject *sep_obj) +bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj) { PyObject *bytesep, *result; @@ -2413,7 +2413,7 @@ bytearray objects and B."); static PyObject * -bytes_rpartition(PyByteArrayObject *self, PyObject *sep_obj) +bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj) { PyObject *bytesep, *result; @@ -2516,7 +2516,7 @@ If maxsplit is given, at most maxsplit splits are done."); static PyObject * -bytes_rsplit(PyByteArrayObject *self, PyObject *args) +bytearray_rsplit(PyByteArrayObject *self, PyObject *args) { Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j; Py_ssize_t maxsplit = -1, count = 0; @@ -2585,7 +2585,7 @@ \n\ Reverse the order of the values in B in place."); static PyObject * -bytes_reverse(PyByteArrayObject *self, PyObject *unused) +bytearray_reverse(PyByteArrayObject *self, PyObject *unused) { char swap, *head, *tail; Py_ssize_t i, j, n = Py_SIZE(self); @@ -2607,7 +2607,7 @@ \n\ Insert a single item into the bytearray before the given index."); static PyObject * -bytes_insert(PyByteArrayObject *self, PyObject *args) +bytearray_insert(PyByteArrayObject *self, PyObject *args) { PyObject *value; int ival; @@ -2644,7 +2644,7 @@ \n\ Append a single item to the end of B."); static PyObject * -bytes_append(PyByteArrayObject *self, PyObject *arg) +bytearray_append(PyByteArrayObject *self, PyObject *arg) { int value; Py_ssize_t n = Py_SIZE(self); @@ -2670,16 +2670,16 @@ Append all the elements from the iterator or sequence to the\n\ end of B."); static PyObject * -bytes_extend(PyByteArrayObject *self, PyObject *arg) +bytearray_extend(PyByteArrayObject *self, PyObject *arg) { - PyObject *it, *item, *bytes_obj; + PyObject *it, *item, *bytearray_obj; Py_ssize_t buf_size = 0, len = 0; int value; char *buf; - /* bytes_setslice code only accepts something supporting PEP 3118. */ + /* bytearray_setslice code only accepts something supporting PEP 3118. */ if (PyObject_CheckBuffer(arg)) { - if (bytes_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1) + if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1) return NULL; Py_RETURN_NONE; @@ -2696,16 +2696,16 @@ return NULL; } - bytes_obj = PyByteArray_FromStringAndSize(NULL, buf_size); - if (bytes_obj == NULL) + bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size); + if (bytearray_obj == NULL) return NULL; - buf = PyByteArray_AS_STRING(bytes_obj); + buf = PyByteArray_AS_STRING(bytearray_obj); while ((item = PyIter_Next(it)) != NULL) { if (! _getbytevalue(item, &value)) { Py_DECREF(item); Py_DECREF(it); - Py_DECREF(bytes_obj); + Py_DECREF(bytearray_obj); return NULL; } buf[len++] = value; @@ -2713,27 +2713,27 @@ if (len >= buf_size) { buf_size = len + (len >> 1) + 1; - if (PyByteArray_Resize((PyObject *)bytes_obj, buf_size) < 0) { + if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) { Py_DECREF(it); - Py_DECREF(bytes_obj); + Py_DECREF(bytearray_obj); return NULL; } /* Recompute the `buf' pointer, since the resizing operation may have invalidated it. */ - buf = PyByteArray_AS_STRING(bytes_obj); + buf = PyByteArray_AS_STRING(bytearray_obj); } } Py_DECREF(it); /* Resize down to exact size. */ - if (PyByteArray_Resize((PyObject *)bytes_obj, len) < 0) { - Py_DECREF(bytes_obj); + if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) { + Py_DECREF(bytearray_obj); return NULL; } - if (bytes_setslice(self, Py_SIZE(self), Py_SIZE(self), bytes_obj) == -1) + if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) return NULL; - Py_DECREF(bytes_obj); + Py_DECREF(bytearray_obj); Py_RETURN_NONE; } @@ -2744,7 +2744,7 @@ Remove and return a single item from B. If no index\n\ argument is given, will pop the last value."); static PyObject * -bytes_pop(PyByteArrayObject *self, PyObject *args) +bytearray_pop(PyByteArrayObject *self, PyObject *args) { int value; Py_ssize_t where = -1, n = Py_SIZE(self); @@ -2779,7 +2779,7 @@ \n\ Remove the first occurance of a value in B."); static PyObject * -bytes_remove(PyByteArrayObject *self, PyObject *arg) +bytearray_remove(PyByteArrayObject *self, PyObject *arg) { int value; Py_ssize_t where, n = Py_SIZE(self); @@ -2833,7 +2833,7 @@ Strip leading and trailing bytes contained in the argument.\n\ If the argument is omitted, strip ASCII whitespace."); static PyObject * -bytes_strip(PyByteArrayObject *self, PyObject *args) +bytearray_strip(PyByteArrayObject *self, PyObject *args) { Py_ssize_t left, right, mysize, argsize; void *myptr, *argptr; @@ -2869,7 +2869,7 @@ Strip leading bytes contained in the argument.\n\ If the argument is omitted, strip leading ASCII whitespace."); static PyObject * -bytes_lstrip(PyByteArrayObject *self, PyObject *args) +bytearray_lstrip(PyByteArrayObject *self, PyObject *args) { Py_ssize_t left, right, mysize, argsize; void *myptr, *argptr; @@ -2902,7 +2902,7 @@ Strip trailing bytes contained in the argument.\n\ If the argument is omitted, strip trailing ASCII whitespace."); static PyObject * -bytes_rstrip(PyByteArrayObject *self, PyObject *args) +bytearray_rstrip(PyByteArrayObject *self, PyObject *args) { Py_ssize_t left, right, mysize, argsize; void *myptr, *argptr; @@ -2940,7 +2940,7 @@ able to handle UnicodeDecodeErrors."); static PyObject * -bytes_decode(PyObject *self, PyObject *args) +bytearray_decode(PyObject *self, PyObject *args) { const char *encoding = NULL; const char *errors = NULL; @@ -2964,7 +2964,7 @@ Returns the number of bytes actually allocated."); static PyObject * -bytes_alloc(PyByteArrayObject *self) +bytearray_alloc(PyByteArrayObject *self) { return PyInt_FromSsize_t(self->ob_alloc); } @@ -2975,7 +2975,7 @@ Concatenates any number of bytearray objects, with B in between each pair."); static PyObject * -bytes_join(PyByteArrayObject *self, PyObject *it) +bytearray_join(PyByteArrayObject *self, PyObject *it) { PyObject *seq; Py_ssize_t mysize = Py_SIZE(self); @@ -3066,7 +3066,7 @@ } static PyObject * -bytes_fromhex(PyObject *cls, PyObject *args) +bytearray_fromhex(PyObject *cls, PyObject *args) { PyObject *newbytes; char *buf; @@ -3109,7 +3109,7 @@ PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); static PyObject * -bytes_reduce(PyByteArrayObject *self) +bytearray_reduce(PyByteArrayObject *self) { PyObject *latin1, *dict; if (self->ob_bytes) @@ -3141,7 +3141,7 @@ \n\ Returns the size of B in memory, in bytes"); static PyObject * -bytes_sizeof(PyByteArrayObject *self) +bytearray_sizeof(PyByteArrayObject *self) { Py_ssize_t res; @@ -3149,54 +3149,54 @@ return PyInt_FromSsize_t(res); } -static PySequenceMethods bytes_as_sequence = { - (lenfunc)bytes_length, /* sq_length */ +static PySequenceMethods bytearray_as_sequence = { + (lenfunc)bytearray_length, /* sq_length */ (binaryfunc)PyByteArray_Concat, /* sq_concat */ - (ssizeargfunc)bytes_repeat, /* sq_repeat */ - (ssizeargfunc)bytes_getitem, /* sq_item */ - 0, /* sq_slice */ - (ssizeobjargproc)bytes_setitem, /* sq_ass_item */ - 0, /* sq_ass_slice */ - (objobjproc)bytes_contains, /* sq_contains */ - (binaryfunc)bytes_iconcat, /* sq_inplace_concat */ - (ssizeargfunc)bytes_irepeat, /* sq_inplace_repeat */ + (ssizeargfunc)bytearray_repeat, /* sq_repeat */ + (ssizeargfunc)bytearray_getitem, /* sq_item */ + 0, /* sq_slice */ + (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */ + 0, /* sq_ass_slice */ + (objobjproc)bytearray_contains, /* sq_contains */ + (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */ + (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */ }; -static PyMappingMethods bytes_as_mapping = { - (lenfunc)bytes_length, - (binaryfunc)bytes_subscript, - (objobjargproc)bytes_ass_subscript, +static PyMappingMethods bytearray_as_mapping = { + (lenfunc)bytearray_length, + (binaryfunc)bytearray_subscript, + (objobjargproc)bytearray_ass_subscript, }; -static PyBufferProcs bytes_as_buffer = { - (readbufferproc)bytes_buffer_getreadbuf, - (writebufferproc)bytes_buffer_getwritebuf, - (segcountproc)bytes_buffer_getsegcount, - (charbufferproc)bytes_buffer_getcharbuf, - (getbufferproc)bytes_getbuffer, - (releasebufferproc)bytes_releasebuffer, +static PyBufferProcs bytearray_as_buffer = { + (readbufferproc)bytearray_buffer_getreadbuf, + (writebufferproc)bytearray_buffer_getwritebuf, + (segcountproc)bytearray_buffer_getsegcount, + (charbufferproc)bytearray_buffer_getcharbuf, + (getbufferproc)bytearray_getbuffer, + (releasebufferproc)bytearray_releasebuffer, }; static PyMethodDef -bytes_methods[] = { - {"__alloc__", (PyCFunction)bytes_alloc, METH_NOARGS, alloc_doc}, - {"__reduce__", (PyCFunction)bytes_reduce, METH_NOARGS, reduce_doc}, - {"__sizeof__", (PyCFunction)bytes_sizeof, METH_NOARGS, sizeof_doc}, - {"append", (PyCFunction)bytes_append, METH_O, append__doc__}, +bytearray_methods[] = { + {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc}, + {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc}, + {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc}, + {"append", (PyCFunction)bytearray_append, METH_O, append__doc__}, {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS, _Py_capitalize__doc__}, {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__}, - {"count", (PyCFunction)bytes_count, METH_VARARGS, count__doc__}, - {"decode", (PyCFunction)bytes_decode, METH_VARARGS, decode_doc}, - {"endswith", (PyCFunction)bytes_endswith, METH_VARARGS, endswith__doc__}, + {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__}, + {"decode", (PyCFunction)bytearray_decode, METH_VARARGS, decode_doc}, + {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__}, {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS, expandtabs__doc__}, - {"extend", (PyCFunction)bytes_extend, METH_O, extend__doc__}, - {"find", (PyCFunction)bytes_find, METH_VARARGS, find__doc__}, - {"fromhex", (PyCFunction)bytes_fromhex, METH_VARARGS|METH_CLASS, + {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__}, + {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__}, + {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS, fromhex_doc}, - {"index", (PyCFunction)bytes_index, METH_VARARGS, index__doc__}, - {"insert", (PyCFunction)bytes_insert, METH_VARARGS, insert__doc__}, + {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__}, + {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__}, {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS, _Py_isalnum__doc__}, {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS, @@ -3211,38 +3211,38 @@ _Py_istitle__doc__}, {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS, _Py_isupper__doc__}, - {"join", (PyCFunction)bytes_join, METH_O, join_doc}, + {"join", (PyCFunction)bytearray_join, METH_O, join_doc}, {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__}, {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__}, - {"lstrip", (PyCFunction)bytes_lstrip, METH_VARARGS, lstrip__doc__}, - {"partition", (PyCFunction)bytes_partition, METH_O, partition__doc__}, - {"pop", (PyCFunction)bytes_pop, METH_VARARGS, pop__doc__}, - {"remove", (PyCFunction)bytes_remove, METH_O, remove__doc__}, - {"replace", (PyCFunction)bytes_replace, METH_VARARGS, replace__doc__}, - {"reverse", (PyCFunction)bytes_reverse, METH_NOARGS, reverse__doc__}, - {"rfind", (PyCFunction)bytes_rfind, METH_VARARGS, rfind__doc__}, - {"rindex", (PyCFunction)bytes_rindex, METH_VARARGS, rindex__doc__}, + {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__}, + {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__}, + {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__}, + {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__}, + {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__}, + {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__}, + {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__}, + {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__}, {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__}, - {"rpartition", (PyCFunction)bytes_rpartition, METH_O, rpartition__doc__}, - {"rsplit", (PyCFunction)bytes_rsplit, METH_VARARGS, rsplit__doc__}, - {"rstrip", (PyCFunction)bytes_rstrip, METH_VARARGS, rstrip__doc__}, - {"split", (PyCFunction)bytes_split, METH_VARARGS, split__doc__}, + {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__}, + {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__}, + {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__}, + {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__}, {"splitlines", (PyCFunction)stringlib_splitlines, METH_VARARGS, splitlines__doc__}, - {"startswith", (PyCFunction)bytes_startswith, METH_VARARGS , + {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS , startswith__doc__}, - {"strip", (PyCFunction)bytes_strip, METH_VARARGS, strip__doc__}, + {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__}, {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, _Py_swapcase__doc__}, {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, - {"translate", (PyCFunction)bytes_translate, METH_VARARGS, + {"translate", (PyCFunction)bytearray_translate, METH_VARARGS, translate__doc__}, {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__}, {NULL} }; -PyDoc_STRVAR(bytes_doc, +PyDoc_STRVAR(bytearray_doc, "bytearray(iterable_of_ints) -> bytearray.\n\ bytearray(string, encoding[, errors]) -> bytearray.\n\ bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray.\n\ @@ -3259,38 +3259,38 @@ Construct a zero-initialized bytearray of the given length."); -static PyObject *bytes_iter(PyObject *seq); +static PyObject *bytearray_iter(PyObject *seq); PyTypeObject PyByteArray_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "bytearray", sizeof(PyByteArrayObject), 0, - (destructor)bytes_dealloc, /* tp_dealloc */ + (destructor)bytearray_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ - (reprfunc)bytes_repr, /* tp_repr */ + (reprfunc)bytearray_repr, /* tp_repr */ 0, /* tp_as_number */ - &bytes_as_sequence, /* tp_as_sequence */ - &bytes_as_mapping, /* tp_as_mapping */ + &bytearray_as_sequence, /* tp_as_sequence */ + &bytearray_as_mapping, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ - bytes_str, /* tp_str */ + bytearray_str, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ - &bytes_as_buffer, /* tp_as_buffer */ + &bytearray_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */ - bytes_doc, /* tp_doc */ + bytearray_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ - (richcmpfunc)bytes_richcompare, /* tp_richcompare */ + (richcmpfunc)bytearray_richcompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ - bytes_iter, /* tp_iter */ + bytearray_iter, /* tp_iter */ 0, /* tp_iternext */ - bytes_methods, /* tp_methods */ + bytearray_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ @@ -3298,7 +3298,7 @@ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)bytes_init, /* tp_init */ + (initproc)bytearray_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ PyObject_Del, /* tp_free */ @@ -3313,7 +3313,7 @@ } bytesiterobject; static void -bytesiter_dealloc(bytesiterobject *it) +bytearrayiter_dealloc(bytesiterobject *it) { _PyObject_GC_UNTRACK(it); Py_XDECREF(it->it_seq); @@ -3321,14 +3321,14 @@ } static int -bytesiter_traverse(bytesiterobject *it, visitproc visit, void *arg) +bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg) { Py_VISIT(it->it_seq); return 0; } static PyObject * -bytesiter_next(bytesiterobject *it) +bytearrayiter_next(bytesiterobject *it) { PyByteArrayObject *seq; PyObject *item; @@ -3353,7 +3353,7 @@ } static PyObject * -bytesiter_length_hint(bytesiterobject *it) +bytesarrayiter_length_hint(bytesiterobject *it) { Py_ssize_t len = 0; if (it->it_seq) @@ -3364,8 +3364,8 @@ PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); -static PyMethodDef bytesiter_methods[] = { - {"__length_hint__", (PyCFunction)bytesiter_length_hint, METH_NOARGS, +static PyMethodDef bytearrayiter_methods[] = { + {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS, length_hint_doc}, {NULL, NULL} /* sentinel */ }; @@ -3376,7 +3376,7 @@ sizeof(bytesiterobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ - (destructor)bytesiter_dealloc, /* tp_dealloc */ + (destructor)bytearrayiter_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -3393,18 +3393,18 @@ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ - (traverseproc)bytesiter_traverse, /* tp_traverse */ + (traverseproc)bytearrayiter_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ - (iternextfunc)bytesiter_next, /* tp_iternext */ - bytesiter_methods, /* tp_methods */ + (iternextfunc)bytearrayiter_next, /* tp_iternext */ + bytearrayiter_methods, /* tp_methods */ 0, }; static PyObject * -bytes_iter(PyObject *seq) +bytearray_iter(PyObject *seq) { bytesiterobject *it; From python-checkins at python.org Sat Apr 18 17:42:14 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 18 Apr 2009 17:42:14 +0200 (CEST) Subject: [Python-checkins] r71720 - in python/branches/py3k: Objects/bytearrayobject.c Message-ID: <20090418154214.8E9DB1E401F@bag.python.org> Author: benjamin.peterson Date: Sat Apr 18 17:42:12 2009 New Revision: 71720 Log: Merged revisions 71719 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71719 | benjamin.peterson | 2009-04-18 10:31:34 -0500 (Sat, 18 Apr 2009) | 1 line rename internal bytes_ functions to bytearray ........ Modified: python/branches/py3k/ (props changed) 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 Apr 18 17:42:12 2009 @@ -57,7 +57,7 @@ } static int -bytes_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags) +bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags) { int ret; void *ptr; @@ -77,7 +77,7 @@ } static void -bytes_releasebuffer(PyByteArrayObject *obj, Py_buffer *view) +bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view) { obj->ob_exports--; } @@ -270,13 +270,13 @@ /* Functions stuffed into the type object */ static Py_ssize_t -bytes_length(PyByteArrayObject *self) +bytearray_length(PyByteArrayObject *self) { return Py_SIZE(self); } static PyObject * -bytes_iconcat(PyByteArrayObject *self, PyObject *other) +bytearray_iconcat(PyByteArrayObject *self, PyObject *other) { Py_ssize_t mysize; Py_ssize_t size; @@ -309,7 +309,7 @@ } static PyObject * -bytes_repeat(PyByteArrayObject *self, Py_ssize_t count) +bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count) { PyByteArrayObject *result; Py_ssize_t mysize; @@ -335,7 +335,7 @@ } static PyObject * -bytes_irepeat(PyByteArrayObject *self, Py_ssize_t count) +bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count) { Py_ssize_t mysize; Py_ssize_t size; @@ -366,7 +366,7 @@ } static PyObject * -bytes_getitem(PyByteArrayObject *self, Py_ssize_t i) +bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i) { if (i < 0) i += Py_SIZE(self); @@ -378,7 +378,7 @@ } static PyObject * -bytes_subscript(PyByteArrayObject *self, PyObject *index) +bytearray_subscript(PyByteArrayObject *self, PyObject *index) { if (PyIndex_Check(index)) { Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError); @@ -433,7 +433,7 @@ } static int -bytes_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi, +bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi, PyObject *values) { Py_ssize_t avail, needed; @@ -448,7 +448,7 @@ values = PyByteArray_FromObject(values); if (values == NULL) return -1; - err = bytes_setslice(self, lo, hi, values); + err = bytearray_setslice(self, lo, hi, values); Py_DECREF(values); return err; } @@ -523,7 +523,7 @@ } static int -bytes_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value) +bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value) { int ival; @@ -536,7 +536,7 @@ } if (value == NULL) - return bytes_setslice(self, i, i+1, NULL); + return bytearray_setslice(self, i, i+1, NULL); if (!_getbytevalue(value, &ival)) return -1; @@ -546,7 +546,7 @@ } static int -bytes_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values) +bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values) { Py_ssize_t start, stop, step, slicelen, needed; char *bytes; @@ -602,7 +602,7 @@ values = PyByteArray_FromObject(values); if (values == NULL) return -1; - err = bytes_ass_subscript(self, index, values); + err = bytearray_ass_subscript(self, index, values); Py_DECREF(values); return err; } @@ -703,7 +703,7 @@ } static int -bytes_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds) +bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"source", "encoding", "errors", 0}; PyObject *arg = NULL; @@ -746,7 +746,7 @@ if (encoded == NULL) return -1; assert(PyBytes_Check(encoded)); - new = bytes_iconcat(self, encoded); + new = bytearray_iconcat(self, encoded); Py_DECREF(encoded); if (new == NULL) return -1; @@ -846,7 +846,7 @@ /* Mostly copied from string_repr, but without the "smart quote" functionality. */ static PyObject * -bytes_repr(PyByteArrayObject *self) +bytearray_repr(PyByteArrayObject *self) { static const char *hexdigits = "0123456789abcdef"; const char *quote_prefix = "bytearray(b"; @@ -931,18 +931,18 @@ } static PyObject * -bytes_str(PyObject *op) +bytearray_str(PyObject *op) { if (Py_BytesWarningFlag) { if (PyErr_WarnEx(PyExc_BytesWarning, "str() on a bytearray instance", 1)) return NULL; } - return bytes_repr((PyByteArrayObject*)op); + return bytearray_repr((PyByteArrayObject*)op); } static PyObject * -bytes_richcompare(PyObject *self, PyObject *other, int op) +bytearray_richcompare(PyObject *self, PyObject *other, int op) { Py_ssize_t self_size, other_size; Py_buffer self_bytes, other_bytes; @@ -1017,7 +1017,7 @@ } static void -bytes_dealloc(PyByteArrayObject *self) +bytearray_dealloc(PyByteArrayObject *self) { if (self->ob_exports > 0) { PyErr_SetString(PyExc_SystemError, @@ -1072,7 +1072,7 @@ Py_LOCAL_INLINE(Py_ssize_t) -bytes_find_internal(PyByteArrayObject *self, PyObject *args, int dir) +bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir) { PyObject *subobj; Py_buffer subbuf; @@ -1106,9 +1106,9 @@ Return -1 on failure."); static PyObject * -bytes_find(PyByteArrayObject *self, PyObject *args) +bytearray_find(PyByteArrayObject *self, PyObject *args) { - Py_ssize_t result = bytes_find_internal(self, args, +1); + Py_ssize_t result = bytearray_find_internal(self, args, +1); if (result == -2) return NULL; return PyLong_FromSsize_t(result); @@ -1122,7 +1122,7 @@ as in slice notation."); static PyObject * -bytes_count(PyByteArrayObject *self, PyObject *args) +bytearray_count(PyByteArrayObject *self, PyObject *args) { PyObject *sub_obj; const char *str = PyByteArray_AS_STRING(self); @@ -1153,9 +1153,9 @@ Like B.find() but raise ValueError when the subsection is not found."); static PyObject * -bytes_index(PyByteArrayObject *self, PyObject *args) +bytearray_index(PyByteArrayObject *self, PyObject *args) { - Py_ssize_t result = bytes_find_internal(self, args, +1); + Py_ssize_t result = bytearray_find_internal(self, args, +1); if (result == -2) return NULL; if (result == -1) { @@ -1177,9 +1177,9 @@ Return -1 on failure."); static PyObject * -bytes_rfind(PyByteArrayObject *self, PyObject *args) +bytearray_rfind(PyByteArrayObject *self, PyObject *args) { - Py_ssize_t result = bytes_find_internal(self, args, -1); + Py_ssize_t result = bytearray_find_internal(self, args, -1); if (result == -2) return NULL; return PyLong_FromSsize_t(result); @@ -1192,9 +1192,9 @@ Like B.rfind() but raise ValueError when the subsection is not found."); static PyObject * -bytes_rindex(PyByteArrayObject *self, PyObject *args) +bytearray_rindex(PyByteArrayObject *self, PyObject *args) { - Py_ssize_t result = bytes_find_internal(self, args, -1); + Py_ssize_t result = bytearray_find_internal(self, args, -1); if (result == -2) return NULL; if (result == -1) { @@ -1207,7 +1207,7 @@ static int -bytes_contains(PyObject *self, PyObject *arg) +bytearray_contains(PyObject *self, PyObject *arg) { Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError); if (ival == -1 && PyErr_Occurred()) { @@ -1235,7 +1235,7 @@ * -1 on error, 0 if not found and 1 if found. */ Py_LOCAL(int) -_bytes_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start, +_bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction) { Py_ssize_t len = PyByteArray_GET_SIZE(self); @@ -1282,7 +1282,7 @@ prefix can also be a tuple of strings to try."); static PyObject * -bytes_startswith(PyByteArrayObject *self, PyObject *args) +bytearray_startswith(PyByteArrayObject *self, PyObject *args) { Py_ssize_t start = 0; Py_ssize_t end = PY_SSIZE_T_MAX; @@ -1295,7 +1295,7 @@ if (PyTuple_Check(subobj)) { Py_ssize_t i; for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) { - result = _bytes_tailmatch(self, + result = _bytearray_tailmatch(self, PyTuple_GET_ITEM(subobj, i), start, end, -1); if (result == -1) @@ -1306,7 +1306,7 @@ } Py_RETURN_FALSE; } - result = _bytes_tailmatch(self, subobj, start, end, -1); + result = _bytearray_tailmatch(self, subobj, start, end, -1); if (result == -1) return NULL; else @@ -1322,7 +1322,7 @@ suffix can also be a tuple of strings to try."); static PyObject * -bytes_endswith(PyByteArrayObject *self, PyObject *args) +bytearray_endswith(PyByteArrayObject *self, PyObject *args) { Py_ssize_t start = 0; Py_ssize_t end = PY_SSIZE_T_MAX; @@ -1335,7 +1335,7 @@ if (PyTuple_Check(subobj)) { Py_ssize_t i; for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) { - result = _bytes_tailmatch(self, + result = _bytearray_tailmatch(self, PyTuple_GET_ITEM(subobj, i), start, end, +1); if (result == -1) @@ -1346,7 +1346,7 @@ } Py_RETURN_FALSE; } - result = _bytes_tailmatch(self, subobj, start, end, +1); + result = _bytearray_tailmatch(self, subobj, start, end, +1); if (result == -1) return NULL; else @@ -1363,7 +1363,7 @@ table, which must be a bytes object of length 256."); static PyObject * -bytes_translate(PyByteArrayObject *self, PyObject *args) +bytearray_translate(PyByteArrayObject *self, PyObject *args) { register char *input, *output; register const char *table; @@ -1452,7 +1452,7 @@ static PyObject * -bytes_maketrans(PyObject *null, PyObject *args) +bytearray_maketrans(PyObject *null, PyObject *args) { return _Py_bytes_maketrans(args); } @@ -2059,7 +2059,7 @@ given, only the first count occurrences are replaced."); static PyObject * -bytes_replace(PyByteArrayObject *self, PyObject *args) +bytearray_replace(PyByteArrayObject *self, PyObject *args) { Py_ssize_t count = -1; PyObject *from, *to, *res; @@ -2210,7 +2210,7 @@ If maxsplit is given, at most maxsplit splits are done."); static PyObject * -bytes_split(PyByteArrayObject *self, PyObject *args) +bytearray_split(PyByteArrayObject *self, PyObject *args) { Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j; Py_ssize_t maxsplit = -1, count = 0; @@ -2317,7 +2317,7 @@ found, returns B and two empty bytearray objects."); static PyObject * -bytes_partition(PyByteArrayObject *self, PyObject *sep_obj) +bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj) { PyObject *bytesep, *result; @@ -2345,7 +2345,7 @@ bytearray objects and B."); static PyObject * -bytes_rpartition(PyByteArrayObject *self, PyObject *sep_obj) +bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj) { PyObject *bytesep, *result; @@ -2448,7 +2448,7 @@ If maxsplit is given, at most maxsplit splits are done."); static PyObject * -bytes_rsplit(PyByteArrayObject *self, PyObject *args) +bytearray_rsplit(PyByteArrayObject *self, PyObject *args) { Py_ssize_t len = PyByteArray_GET_SIZE(self), n, i, j; Py_ssize_t maxsplit = -1, count = 0; @@ -2517,7 +2517,7 @@ \n\ Reverse the order of the values in B in place."); static PyObject * -bytes_reverse(PyByteArrayObject *self, PyObject *unused) +bytearray_reverse(PyByteArrayObject *self, PyObject *unused) { char swap, *head, *tail; Py_ssize_t i, j, n = Py_SIZE(self); @@ -2539,7 +2539,7 @@ \n\ Insert a single item into the bytearray before the given index."); static PyObject * -bytes_insert(PyByteArrayObject *self, PyObject *args) +bytearray_insert(PyByteArrayObject *self, PyObject *args) { PyObject *value; int ival; @@ -2576,7 +2576,7 @@ \n\ Append a single item to the end of B."); static PyObject * -bytes_append(PyByteArrayObject *self, PyObject *arg) +bytearray_append(PyByteArrayObject *self, PyObject *arg) { int value; Py_ssize_t n = Py_SIZE(self); @@ -2602,16 +2602,16 @@ Append all the elements from the iterator or sequence to the\n\ end of B."); static PyObject * -bytes_extend(PyByteArrayObject *self, PyObject *arg) +bytearray_extend(PyByteArrayObject *self, PyObject *arg) { - PyObject *it, *item, *bytes_obj; + PyObject *it, *item, *bytearray_obj; Py_ssize_t buf_size = 0, len = 0; int value; char *buf; - /* bytes_setslice code only accepts something supporting PEP 3118. */ + /* bytearray_setslice code only accepts something supporting PEP 3118. */ if (PyObject_CheckBuffer(arg)) { - if (bytes_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1) + if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1) return NULL; Py_RETURN_NONE; @@ -2628,16 +2628,16 @@ return NULL; } - bytes_obj = PyByteArray_FromStringAndSize(NULL, buf_size); - if (bytes_obj == NULL) + bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size); + if (bytearray_obj == NULL) return NULL; - buf = PyByteArray_AS_STRING(bytes_obj); + buf = PyByteArray_AS_STRING(bytearray_obj); while ((item = PyIter_Next(it)) != NULL) { if (! _getbytevalue(item, &value)) { Py_DECREF(item); Py_DECREF(it); - Py_DECREF(bytes_obj); + Py_DECREF(bytearray_obj); return NULL; } buf[len++] = value; @@ -2645,27 +2645,27 @@ if (len >= buf_size) { buf_size = len + (len >> 1) + 1; - if (PyByteArray_Resize((PyObject *)bytes_obj, buf_size) < 0) { + if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) { Py_DECREF(it); - Py_DECREF(bytes_obj); + Py_DECREF(bytearray_obj); return NULL; } /* Recompute the `buf' pointer, since the resizing operation may have invalidated it. */ - buf = PyByteArray_AS_STRING(bytes_obj); + buf = PyByteArray_AS_STRING(bytearray_obj); } } Py_DECREF(it); /* Resize down to exact size. */ - if (PyByteArray_Resize((PyObject *)bytes_obj, len) < 0) { - Py_DECREF(bytes_obj); + if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) { + Py_DECREF(bytearray_obj); return NULL; } - if (bytes_setslice(self, Py_SIZE(self), Py_SIZE(self), bytes_obj) == -1) + if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) return NULL; - Py_DECREF(bytes_obj); + Py_DECREF(bytearray_obj); Py_RETURN_NONE; } @@ -2676,7 +2676,7 @@ Remove and return a single item from B. If no index\n\ argument is given, will pop the last value."); static PyObject * -bytes_pop(PyByteArrayObject *self, PyObject *args) +bytearray_pop(PyByteArrayObject *self, PyObject *args) { int value; Py_ssize_t where = -1, n = Py_SIZE(self); @@ -2711,7 +2711,7 @@ \n\ Remove the first occurrence of a value in B."); static PyObject * -bytes_remove(PyByteArrayObject *self, PyObject *arg) +bytearray_remove(PyByteArrayObject *self, PyObject *arg) { int value; Py_ssize_t where, n = Py_SIZE(self); @@ -2766,7 +2766,7 @@ and return the result as a new bytearray.\n\ If the argument is omitted, strip ASCII whitespace."); static PyObject * -bytes_strip(PyByteArrayObject *self, PyObject *args) +bytearray_strip(PyByteArrayObject *self, PyObject *args) { Py_ssize_t left, right, mysize, argsize; void *myptr, *argptr; @@ -2803,7 +2803,7 @@ and return the result as a new bytearray.\n\ If the argument is omitted, strip leading ASCII whitespace."); static PyObject * -bytes_lstrip(PyByteArrayObject *self, PyObject *args) +bytearray_lstrip(PyByteArrayObject *self, PyObject *args) { Py_ssize_t left, right, mysize, argsize; void *myptr, *argptr; @@ -2837,7 +2837,7 @@ and return the result as a new bytearray.\n\ If the argument is omitted, strip trailing ASCII whitespace."); static PyObject * -bytes_rstrip(PyByteArrayObject *self, PyObject *args) +bytearray_rstrip(PyByteArrayObject *self, PyObject *args) { Py_ssize_t left, right, mysize, argsize; void *myptr, *argptr; @@ -2875,7 +2875,7 @@ able to handle UnicodeDecodeErrors."); static PyObject * -bytes_decode(PyObject *self, PyObject *args) +bytearray_decode(PyObject *self, PyObject *args) { const char *encoding = NULL; const char *errors = NULL; @@ -2893,7 +2893,7 @@ Return the number of bytes actually allocated."); static PyObject * -bytes_alloc(PyByteArrayObject *self) +bytearray_alloc(PyByteArrayObject *self) { return PyLong_FromSsize_t(self->ob_alloc); } @@ -2905,7 +2905,7 @@ in between each pair, and return the result as a new bytearray."); static PyObject * -bytes_join(PyByteArrayObject *self, PyObject *it) +bytearray_join(PyByteArrayObject *self, PyObject *it) { PyObject *seq; Py_ssize_t mysize = Py_SIZE(self); @@ -2998,7 +2998,7 @@ } static PyObject * -bytes_fromhex(PyObject *cls, PyObject *args) +bytearray_fromhex(PyObject *cls, PyObject *args) { PyObject *newbytes, *hexobj; char *buf; @@ -3044,7 +3044,7 @@ PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); static PyObject * -bytes_reduce(PyByteArrayObject *self) +bytearray_reduce(PyByteArrayObject *self) { PyObject *latin1, *dict; if (self->ob_bytes) @@ -3068,7 +3068,7 @@ \n\ Returns the size of B in memory, in bytes"); static PyObject * -bytes_sizeof(PyByteArrayObject *self) +bytearray_sizeof(PyByteArrayObject *self) { Py_ssize_t res; @@ -3076,50 +3076,50 @@ return PyLong_FromSsize_t(res); } -static PySequenceMethods bytes_as_sequence = { - (lenfunc)bytes_length, /* sq_length */ +static PySequenceMethods bytearray_as_sequence = { + (lenfunc)bytearray_length, /* sq_length */ (binaryfunc)PyByteArray_Concat, /* sq_concat */ - (ssizeargfunc)bytes_repeat, /* sq_repeat */ - (ssizeargfunc)bytes_getitem, /* sq_item */ - 0, /* sq_slice */ - (ssizeobjargproc)bytes_setitem, /* sq_ass_item */ - 0, /* sq_ass_slice */ - (objobjproc)bytes_contains, /* sq_contains */ - (binaryfunc)bytes_iconcat, /* sq_inplace_concat */ - (ssizeargfunc)bytes_irepeat, /* sq_inplace_repeat */ + (ssizeargfunc)bytearray_repeat, /* sq_repeat */ + (ssizeargfunc)bytearray_getitem, /* sq_item */ + 0, /* sq_slice */ + (ssizeobjargproc)bytearray_setitem, /* sq_ass_item */ + 0, /* sq_ass_slice */ + (objobjproc)bytearray_contains, /* sq_contains */ + (binaryfunc)bytearray_iconcat, /* sq_inplace_concat */ + (ssizeargfunc)bytearray_irepeat, /* sq_inplace_repeat */ }; -static PyMappingMethods bytes_as_mapping = { - (lenfunc)bytes_length, - (binaryfunc)bytes_subscript, - (objobjargproc)bytes_ass_subscript, +static PyMappingMethods bytearray_as_mapping = { + (lenfunc)bytearray_length, + (binaryfunc)bytearray_subscript, + (objobjargproc)bytearray_ass_subscript, }; -static PyBufferProcs bytes_as_buffer = { - (getbufferproc)bytes_getbuffer, - (releasebufferproc)bytes_releasebuffer, +static PyBufferProcs bytearray_as_buffer = { + (getbufferproc)bytearray_getbuffer, + (releasebufferproc)bytearray_releasebuffer, }; static PyMethodDef -bytes_methods[] = { - {"__alloc__", (PyCFunction)bytes_alloc, METH_NOARGS, alloc_doc}, - {"__reduce__", (PyCFunction)bytes_reduce, METH_NOARGS, reduce_doc}, - {"__sizeof__", (PyCFunction)bytes_sizeof, METH_NOARGS, sizeof_doc}, - {"append", (PyCFunction)bytes_append, METH_O, append__doc__}, +bytearray_methods[] = { + {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc}, + {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc}, + {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc}, + {"append", (PyCFunction)bytearray_append, METH_O, append__doc__}, {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS, _Py_capitalize__doc__}, {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__}, - {"count", (PyCFunction)bytes_count, METH_VARARGS, count__doc__}, - {"decode", (PyCFunction)bytes_decode, METH_VARARGS, decode_doc}, - {"endswith", (PyCFunction)bytes_endswith, METH_VARARGS, endswith__doc__}, + {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__}, + {"decode", (PyCFunction)bytearray_decode, METH_VARARGS, decode_doc}, + {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__}, {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS, expandtabs__doc__}, - {"extend", (PyCFunction)bytes_extend, METH_O, extend__doc__}, - {"find", (PyCFunction)bytes_find, METH_VARARGS, find__doc__}, - {"fromhex", (PyCFunction)bytes_fromhex, METH_VARARGS|METH_CLASS, + {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__}, + {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__}, + {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS, fromhex_doc}, - {"index", (PyCFunction)bytes_index, METH_VARARGS, index__doc__}, - {"insert", (PyCFunction)bytes_insert, METH_VARARGS, insert__doc__}, + {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__}, + {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__}, {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS, _Py_isalnum__doc__}, {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS, @@ -3134,40 +3134,40 @@ _Py_istitle__doc__}, {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS, _Py_isupper__doc__}, - {"join", (PyCFunction)bytes_join, METH_O, join_doc}, + {"join", (PyCFunction)bytearray_join, METH_O, join_doc}, {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__}, {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__}, - {"lstrip", (PyCFunction)bytes_lstrip, METH_VARARGS, lstrip__doc__}, - {"maketrans", (PyCFunction)bytes_maketrans, METH_VARARGS|METH_STATIC, + {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__}, + {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC, _Py_maketrans__doc__}, - {"partition", (PyCFunction)bytes_partition, METH_O, partition__doc__}, - {"pop", (PyCFunction)bytes_pop, METH_VARARGS, pop__doc__}, - {"remove", (PyCFunction)bytes_remove, METH_O, remove__doc__}, - {"replace", (PyCFunction)bytes_replace, METH_VARARGS, replace__doc__}, - {"reverse", (PyCFunction)bytes_reverse, METH_NOARGS, reverse__doc__}, - {"rfind", (PyCFunction)bytes_rfind, METH_VARARGS, rfind__doc__}, - {"rindex", (PyCFunction)bytes_rindex, METH_VARARGS, rindex__doc__}, + {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__}, + {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__}, + {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__}, + {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__}, + {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__}, + {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__}, + {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__}, {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__}, - {"rpartition", (PyCFunction)bytes_rpartition, METH_O, rpartition__doc__}, - {"rsplit", (PyCFunction)bytes_rsplit, METH_VARARGS, rsplit__doc__}, - {"rstrip", (PyCFunction)bytes_rstrip, METH_VARARGS, rstrip__doc__}, - {"split", (PyCFunction)bytes_split, METH_VARARGS, split__doc__}, + {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__}, + {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS, rsplit__doc__}, + {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__}, + {"split", (PyCFunction)bytearray_split, METH_VARARGS, split__doc__}, {"splitlines", (PyCFunction)stringlib_splitlines, METH_VARARGS, splitlines__doc__}, - {"startswith", (PyCFunction)bytes_startswith, METH_VARARGS , + {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS , startswith__doc__}, - {"strip", (PyCFunction)bytes_strip, METH_VARARGS, strip__doc__}, + {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__}, {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, _Py_swapcase__doc__}, {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, - {"translate", (PyCFunction)bytes_translate, METH_VARARGS, + {"translate", (PyCFunction)bytearray_translate, METH_VARARGS, translate__doc__}, {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__}, {NULL} }; -PyDoc_STRVAR(bytes_doc, +PyDoc_STRVAR(bytearray_doc, "bytearray(iterable_of_ints) -> bytearray\n\ bytearray(string, encoding[, errors]) -> bytearray\n\ bytearray(bytes_or_bytearray) -> mutable copy of bytes_or_bytearray\n\ @@ -3184,37 +3184,37 @@ Construct a zero-initialized bytearray of the given length."); -static PyObject *bytes_iter(PyObject *seq); +static PyObject *bytearray_iter(PyObject *seq); PyTypeObject PyByteArray_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "bytearray", sizeof(PyByteArrayObject), 0, - (destructor)bytes_dealloc, /* tp_dealloc */ + (destructor)bytearray_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ - (reprfunc)bytes_repr, /* tp_repr */ + (reprfunc)bytearray_repr, /* tp_repr */ 0, /* tp_as_number */ - &bytes_as_sequence, /* tp_as_sequence */ - &bytes_as_mapping, /* tp_as_mapping */ + &bytearray_as_sequence, /* tp_as_sequence */ + &bytearray_as_mapping, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ - bytes_str, /* tp_str */ + bytearray_str, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ - &bytes_as_buffer, /* tp_as_buffer */ + &bytearray_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - bytes_doc, /* tp_doc */ + bytearray_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ - (richcmpfunc)bytes_richcompare, /* tp_richcompare */ + (richcmpfunc)bytearray_richcompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ - bytes_iter, /* tp_iter */ + bytearray_iter, /* tp_iter */ 0, /* tp_iternext */ - bytes_methods, /* tp_methods */ + bytearray_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ @@ -3222,7 +3222,7 @@ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)bytes_init, /* tp_init */ + (initproc)bytearray_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ PyObject_Del, /* tp_free */ @@ -3237,7 +3237,7 @@ } bytesiterobject; static void -bytesiter_dealloc(bytesiterobject *it) +bytearrayiter_dealloc(bytesiterobject *it) { _PyObject_GC_UNTRACK(it); Py_XDECREF(it->it_seq); @@ -3245,14 +3245,14 @@ } static int -bytesiter_traverse(bytesiterobject *it, visitproc visit, void *arg) +bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg) { Py_VISIT(it->it_seq); return 0; } static PyObject * -bytesiter_next(bytesiterobject *it) +bytearrayiter_next(bytesiterobject *it) { PyByteArrayObject *seq; PyObject *item; @@ -3277,7 +3277,7 @@ } static PyObject * -bytesiter_length_hint(bytesiterobject *it) +bytesarrayiter_length_hint(bytesiterobject *it) { Py_ssize_t len = 0; if (it->it_seq) @@ -3288,8 +3288,8 @@ PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); -static PyMethodDef bytesiter_methods[] = { - {"__length_hint__", (PyCFunction)bytesiter_length_hint, METH_NOARGS, +static PyMethodDef bytearrayiter_methods[] = { + {"__length_hint__", (PyCFunction)bytesarrayiter_length_hint, METH_NOARGS, length_hint_doc}, {NULL, NULL} /* sentinel */ }; @@ -3300,7 +3300,7 @@ sizeof(bytesiterobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ - (destructor)bytesiter_dealloc, /* tp_dealloc */ + (destructor)bytearrayiter_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -3317,18 +3317,18 @@ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ - (traverseproc)bytesiter_traverse, /* tp_traverse */ + (traverseproc)bytearrayiter_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ - (iternextfunc)bytesiter_next, /* tp_iternext */ - bytesiter_methods, /* tp_methods */ + (iternextfunc)bytearrayiter_next, /* tp_iternext */ + bytearrayiter_methods, /* tp_methods */ 0, }; static PyObject * -bytes_iter(PyObject *seq) +bytearray_iter(PyObject *seq) { bytesiterobject *it; From buildbot at python.org Sat Apr 18 19:38:10 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 18 Apr 2009 17:38:10 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090418173811.68F9D1E401F@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/604 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_time make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Sat Apr 18 20:29:36 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 18 Apr 2009 18:29:36 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu trunk Message-ID: <20090418182936.97BDA1E402C@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%20trunk/builds/1248 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_email test_multiprocessing Traceback (most recent call last): File "./Lib/test/regrtest.py", line 569, in runtest_inner the_package = __import__(abstest, globals(), locals(), []) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/test_email.py", line 5, in from email.test.test_email import suite ImportError: cannot import name suite make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sat Apr 18 21:26:21 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 18 Apr 2009 21:26:21 +0200 (CEST) Subject: [Python-checkins] r71721 - python/trunk/Lib/unittest.py Message-ID: <20090418192621.138C71E4039@bag.python.org> Author: benjamin.peterson Date: Sat Apr 18 21:26:19 2009 New Revision: 71721 Log: fix a few nits in unittest.py #5771 Modified: python/trunk/Lib/unittest.py Modified: python/trunk/Lib/unittest.py ============================================================================== --- python/trunk/Lib/unittest.py (original) +++ python/trunk/Lib/unittest.py Sat Apr 18 21:26:19 2009 @@ -265,7 +265,7 @@ def __enter__(self): pass - def __exit__(self, exc_type, exc_value, traceback): + def __exit__(self, exc_type, exc_value, tb): if exc_type is None: try: exc_name = self.expected.__name__ @@ -1141,7 +1141,7 @@ self._testFunc, self._description)) def __str__(self): - return "%s (%s)" % (_strclass(self.__class__), self.__testFunc.__name__) + return "%s (%s)" % (_strclass(self.__class__), self._testFunc.__name__) def __repr__(self): return "<%s testFunc=%s>" % (_strclass(self.__class__), self._testFunc) From nnorwitz at gmail.com Sat Apr 18 22:11:25 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sat, 18 Apr 2009 16:11:25 -0400 Subject: [Python-checkins] Python Regression Test Failures basics (1) Message-ID: <20090418201125.GA19960@python.psfb.org> 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23366 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 test_lib2to3 failed -- errors occurred; run in verbose mode for details 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 -- OSError raises on RLock creation, see issue 3111! test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18902 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [742118 refs] From python-checkins at python.org Sat Apr 18 22:12:47 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 18 Apr 2009 22:12:47 +0200 (CEST) Subject: [Python-checkins] r71722 - in python/trunk: Lib/test/test_descr.py Misc/NEWS Objects/frameobject.c Objects/object.c Message-ID: <20090418201247.8F2761E4160@bag.python.org> Author: benjamin.peterson Date: Sat Apr 18 22:12:47 2009 New Revision: 71722 Log: try to initalize all builtin types with PyType_Ready to avoid problems like #5787 Modified: python/trunk/Lib/test/test_descr.py python/trunk/Misc/NEWS python/trunk/Objects/frameobject.c python/trunk/Objects/object.c Modified: python/trunk/Lib/test/test_descr.py ============================================================================== --- python/trunk/Lib/test/test_descr.py (original) +++ python/trunk/Lib/test/test_descr.py Sat Apr 18 22:12:47 2009 @@ -1,3 +1,4 @@ +import __builtin__ import types import unittest import warnings @@ -3895,6 +3896,17 @@ else: self.fail("new-style class must have a new-style base") + def test_builtin_bases(self): + # Make sure all the builtin types can have their base queried without + # segfaulting. See issue #5787. + builtin_types = [tp for tp in __builtin__.__dict__.itervalues() + if isinstance(tp, type)] + for tp in builtin_types: + object.__getattribute__(tp, "__bases__") + if tp is not object: + self.assertEqual(len(tp.__bases__), 1, tp) + + def test_mutable_bases_with_failing_mro(self): # Testing mutable bases with failing mro... class WorkOnce(type): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Apr 18 22:12:47 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #5787: object.__getattribute__(some_type, "__bases__") segfaulted on + some builtin types. + - Issue #1869: fix a couple of minor round() issues. round(5e15+1) was giving 5e15+2; round(-0.0) was losing the sign of the zero. Modified: python/trunk/Objects/frameobject.c ============================================================================== --- python/trunk/Objects/frameobject.c (original) +++ python/trunk/Objects/frameobject.c Sat Apr 18 22:12:47 2009 @@ -606,14 +606,6 @@ builtin_object = PyString_InternFromString("__builtins__"); if (builtin_object == NULL) return 0; - /* - Traceback objects are not created the normal way (through calling the - type), so PyType_Ready has to be called here. - */ - if (PyType_Ready(&PyTraceBack_Type)) { - Py_DECREF(builtin_object); - return 0; - } return 1; } Modified: python/trunk/Objects/object.c ============================================================================== --- python/trunk/Objects/object.c (original) +++ python/trunk/Objects/object.c Sat Apr 18 22:12:47 2009 @@ -2033,28 +2033,88 @@ _Py_ReadyTypes(void) { if (PyType_Ready(&PyType_Type) < 0) - Py_FatalError("Can't initialize 'type'"); + Py_FatalError("Can't initialize type type"); if (PyType_Ready(&_PyWeakref_RefType) < 0) - Py_FatalError("Can't initialize 'weakref'"); + Py_FatalError("Can't initialize weakref type"); if (PyType_Ready(&PyBool_Type) < 0) - Py_FatalError("Can't initialize 'bool'"); + Py_FatalError("Can't initialize bool type"); if (PyType_Ready(&PyString_Type) < 0) - Py_FatalError("Can't initialize 'str'"); + Py_FatalError("Can't initialize str type"); if (PyType_Ready(&PyByteArray_Type) < 0) - Py_FatalError("Can't initialize 'bytes'"); + Py_FatalError("Can't initialize bytearray"); if (PyType_Ready(&PyList_Type) < 0) - Py_FatalError("Can't initialize 'list'"); + Py_FatalError("Can't initialize list"); if (PyType_Ready(&PyNone_Type) < 0) - Py_FatalError("Can't initialize type(None)"); + Py_FatalError("Can't initialize None type"); if (PyType_Ready(&PyNotImplemented_Type) < 0) - Py_FatalError("Can't initialize type(NotImplemented)"); + Py_FatalError("Can't initialize NotImplemented type"); + + if (PyType_Ready(&PyTraceBack_Type) < 0) + Py_FatalError("Can't initialize traceback type"); + + if (PyType_Ready(&PySuper_Type) < 0) + Py_FatalError("Can't initialize super type"); + + if (PyType_Ready(&PyBaseObject_Type) < 0) + Py_FatalError("Can't initialize object type"); + + if (PyType_Ready(&PyRange_Type) < 0) + Py_FatalError("Can't initialize xrange type"); + + if (PyType_Ready(&PyDict_Type) < 0) + Py_FatalError("Can't initialize dict type"); + + if (PyType_Ready(&PySet_Type) < 0) + Py_FatalError("Can't initialize set type"); + + if (PyType_Ready(&PyUnicode_Type) < 0) + Py_FatalError("Can't initialize unicode type"); + + if (PyType_Ready(&PySlice_Type) < 0) + Py_FatalError("Can't initialize slice type"); + + if (PyType_Ready(&PyStaticMethod_Type) < 0) + Py_FatalError("Can't initialize static method type"); + + if (PyType_Ready(&PyComplex_Type) < 0) + Py_FatalError("Can't initalize complex type"); + + if (PyType_Ready(&PyFloat_Type) < 0) + Py_FatalError("Can't initalize float type"); + + if (PyType_Ready(&PyBuffer_Type) < 0) + Py_FatalError("Can't initialize buffer type"); + + if (PyType_Ready(&PyLong_Type) < 0) + Py_FatalError("Can't initialize long type"); + + if (PyType_Ready(&PyInt_Type) < 0) + Py_FatalError("Can't initialize int type"); + + if (PyType_Ready(&PyFrozenSet_Type) < 0) + Py_FatalError("Can't initialize frozenset type"); + + if (PyType_Ready(&PyProperty_Type) < 0) + Py_FatalError("Can't initialize property type"); + + if (PyType_Ready(&PyMemoryView_Type) < 0) + Py_FatalError("Can't initialize memoryview type"); + + if (PyType_Ready(&PyTuple_Type) < 0) + Py_FatalError("Can't initalize tuple type"); + + if (PyType_Ready(&PyEnum_Type) < 0) + Py_FatalError("Can't initalize enumerate type"); + + if (PyType_Ready(&PyReversed_Type) < 0) + Py_FatalError("Can't initalize reversed type"); } From python-checkins at python.org Sat Apr 18 22:17:53 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 22:17:53 +0200 (CEST) Subject: [Python-checkins] r71723 - in python/branches/py3k: Include/pyport.h Misc/NEWS Objects/floatobject.c Python/pymath.c configure configure.in pyconfig.h.in Message-ID: <20090418201753.471E11E403E@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 22:17:52 2009 New Revision: 71723 Log: The SSE2 detection and enabling could potentially cause problems for binary distributions of Python in situations where the build machine has SSE2 but the target machine does not. Therefore, don't enable SSE2 instructions automatically on x86. Modified: python/branches/py3k/Include/pyport.h python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/floatobject.c python/branches/py3k/Python/pymath.c python/branches/py3k/configure python/branches/py3k/configure.in python/branches/py3k/pyconfig.h.in Modified: python/branches/py3k/Include/pyport.h ============================================================================== --- python/branches/py3k/Include/pyport.h (original) +++ python/branches/py3k/Include/pyport.h Sat Apr 18 22:17:52 2009 @@ -469,7 +469,7 @@ the FPU is using 53-bit precision. Here are macros that force this. See Python/pystrtod.c for an example of their use. */ -#ifdef USING_X87_FPU +#ifdef HAVE_GCC_ASM_FOR_X87 #define _Py_SET_53BIT_PRECISION_HEADER \ unsigned short old_387controlword, new_387controlword #define _Py_SET_53BIT_PRECISION_START \ Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Apr 18 22:17:52 2009 @@ -31,13 +31,6 @@ value: str(1e11 + 0.5). (This minor issue has existed in 2.x for a long time.) -- On x86, SSE2 instructions for floating-point are automatically - detected and, where possible, enabled on platforms using the gcc - compiler. As a consequence, some arithmetic operations may have - different (more accurate!) results on some platforms, and - cross-platform consistency of Python arithmetic should be improved. - This applies particularly to Linux/x86. - - Issue #1580: On most platforms, use a 'short' float repr: for a finite float x, repr(x) now outputs a string based on the shortest sequence of decimal digits that rounds to x. Previous behaviour was Modified: python/branches/py3k/Objects/floatobject.c ============================================================================== --- python/branches/py3k/Objects/floatobject.c (original) +++ python/branches/py3k/Objects/floatobject.c Sat Apr 18 22:17:52 2009 @@ -15,6 +15,11 @@ #define MAX(x, y) ((x) < (y) ? (y) : (x)) #define MIN(x, y) ((x) < (y) ? (x) : (y)) +/* ascii character tests (as opposed to locale tests) */ +#define ISSPACE(c) ((c) == ' ' || (c) == '\f' || (c) == '\n' || \ + (c) == '\r' || (c) == '\t' || (c) == '\v') +#define ISDIGIT(c) ((c) >= '0' && (c) <= '9') + #ifdef HAVE_IEEEFP_H #include #endif @@ -188,7 +193,7 @@ } last = s + len; - while (*s && isspace(Py_CHARMASK(*s))) + while (*s && ISSPACE(Py_CHARMASK(*s))) s++; if (*s == '\0') { PyErr_SetString(PyExc_ValueError, "empty string for float()"); @@ -245,7 +250,7 @@ } /* Since end != s, the platform made *some* kind of sense out of the input. Trust it. */ - while (*end && isspace(Py_CHARMASK(*end))) + while (*end && ISSPACE(Py_CHARMASK(*end))) end++; if (*end != '\0') { PyOS_snprintf(buffer, sizeof(buffer), @@ -1275,7 +1280,7 @@ ********************/ /* leading whitespace and optional sign */ - while (isspace(Py_CHARMASK(*s))) + while (ISSPACE(Py_CHARMASK(*s))) s++; if (*s == '-') { s++; @@ -1299,6 +1304,7 @@ s_store = s; if (*s == '0') { s++; + if (*s == 'x' || *s == 'X') if (tolower(*s) == (int)'x') s++; else @@ -1345,7 +1351,7 @@ exp = 0; /* optional trailing whitespace leading to the end of the string */ - while (isspace(Py_CHARMASK(*s))) + while (ISSPACE(Py_CHARMASK(*s))) s++; if (s != s_end) goto parse_error; Modified: python/branches/py3k/Python/pymath.c ============================================================================== --- python/branches/py3k/Python/pymath.c (original) +++ python/branches/py3k/Python/pymath.c Sat Apr 18 22:17:52 2009 @@ -13,8 +13,7 @@ } #endif -#ifdef USING_X87_FPU -# ifdef HAVE_GCC_ASM_FOR_X87 +#ifdef HAVE_GCC_ASM_FOR_X87 /* inline assembly for getting and setting the 387 FPU control word on gcc/x86 */ @@ -29,9 +28,6 @@ __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); } -# else -# error "Unable to get and set x87 control word" -# endif #endif Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Sat Apr 18 22:17:52 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 71663 . +# From configure.in Revision: 71704 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.1. # @@ -21827,174 +21827,21 @@ fi -# David Gay's code in Python/dtoa.c requires that the FPU uses 53-bit +# The short float repr introduced in Python 3.1 requires the +# correctly-rounded string <-> double conversion functions in +# Python/dtoa.c, which in turn require that the FPU uses 53-bit # rounding; this is a particular problem on x86, where the x87 FPU has # a default rounding precision of 64 bits. For gcc/x86, we try to fix -# this by: -# -# (1) using the SSE2 instruction set when available (it usually is -# on modern machines) -# (2) using inline assembler to get and set the x87 FPU control word -# otherwise. -# -# On AMD64 (aka x86-64), gcc automatically enables use of SSE2 -# instructions, so we don't bother trying to detect. +# this by using inline assembler to get and set the x87 FPU control +# word. if test "$GCC" = yes && test -n "`$CC -dM -E - &5 -echo $ECHO_N "checking whether SSE2 instructions are already enabled for math... $ECHO_C" >&6; } - if test -n "`$CC -dM -E - &5 -echo "${ECHO_T}$ac_sse2_enabled" >&6; } - - # if we're not using SSE2 already, we need to either enable it - # (when available), or use inline assembler to get and set the - # 387 control word. - if test $ac_sse2_enabled = no - then - # Check cpuid for SSE2 availability. Bits 25 and 26 of edx tell - # us about SSE and SSE2 respectively. - { echo "$as_me:$LINENO: checking whether SSE2 instructions are available on this CPU" >&5 -echo $ECHO_N "checking whether SSE2 instructions are available on this CPU... $ECHO_C" >&6; } - if test "$cross_compiling" = yes; then - ac_cv_cpu_has_sse2=no -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - int main() { - unsigned int ax, bx, cx, dx, func; - func = 1U; - __asm__ __volatile__ ( - "pushl %%ebx\n\t" /* don't clobber ebx */ - "cpuid\n\t" - "movl %%ebx, %1\n\t" - "popl %%ebx" - : "=a" (ax), "=r" (bx), "=c" (cx), "=d" (dx) - : "a" (func) - : "cc" ); - if ((dx & (1U << 25)) && (dx & (1U << 26))) - return 0; - else - return 1; - } - -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_cpu_has_sse2=yes -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_cpu_has_sse2=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - - { echo "$as_me:$LINENO: result: $ac_cv_cpu_has_sse2" >&5 -echo "${ECHO_T}$ac_cv_cpu_has_sse2" >&6; } - - # determine whether gcc accepts options to turn on SSE2 - { echo "$as_me:$LINENO: checking whether $CC accepts -msse2 -mfpmath=sse" >&5 -echo $ECHO_N "checking whether $CC accepts -msse2 -mfpmath=sse... $ECHO_C" >&6; } - ac_save_cc="$CC" - CC="$CC -msse2 -mfpmath=sse" - if test "$cross_compiling" = yes; then - ac_cv_msse2_ok=no -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -int main() { return 0; } -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_msse2_ok=yes -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_msse2_ok=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - - CC="$ac_save_cc" - { echo "$as_me:$LINENO: result: $ac_cv_msse2_ok" >&5 -echo "${ECHO_T}$ac_cv_msse2_ok" >&6; } - - if test $ac_cv_cpu_has_sse2 = yes && test $ac_cv_msse2_ok = yes - then - BASECFLAGS="$BASECFLAGS -msse2 -mfpmath=sse" - else - # SSE2 doesn't appear to be available. Check that it's okay - # to use gcc inline assembler to get and set x87 control word - -cat >>confdefs.h <<\_ACEOF -#define USING_X87_FPU 1 -_ACEOF - - { echo "$as_me:$LINENO: checking whether we can use gcc inline assembler to get and set x87 control word" >&5 + # Check that it's okay to use gcc inline assembler to get and set + # x87 control word + { echo "$as_me:$LINENO: checking whether we can use gcc inline assembler to get and set x87 control word" >&5 echo $ECHO_N "checking whether we can use gcc inline assembler to get and set x87 control word... $ECHO_C" >&6; } - cat >conftest.$ac_ext <<_ACEOF + cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -22005,9 +21852,9 @@ main () { - unsigned short cw; - __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); - __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); + unsigned short cw; + __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); + __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); ; return 0; @@ -22039,17 +21886,15 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { echo "$as_me:$LINENO: result: $have_gcc_asm_for_x87" >&5 + { echo "$as_me:$LINENO: result: $have_gcc_asm_for_x87" >&5 echo "${ECHO_T}$have_gcc_asm_for_x87" >&6; } - if test "$have_gcc_asm_for_x87" = yes - then + if test "$have_gcc_asm_for_x87" = yes + then cat >>confdefs.h <<\_ACEOF #define HAVE_GCC_ASM_FOR_X87 1 _ACEOF - fi - fi fi fi Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Sat Apr 18 22:17:52 2009 @@ -3142,97 +3142,28 @@ in ARM mixed-endian order (byte order 45670123)]) fi -# David Gay's code in Python/dtoa.c requires that the FPU uses 53-bit -# rounding; this is a particular problem on x86, where the x87 FPU has -# a default rounding precision of 64 bits. For gcc/x86, we try to fix -# this by: -# -# (1) using the SSE2 instruction set when available (it usually is -# on modern machines) -# (2) using inline assembler to get and set the x87 FPU control word -# otherwise. -# -# On AMD64 (aka x86-64), gcc automatically enables use of SSE2 -# instructions, so we don't bother trying to detect. - +# The short float repr introduced in Python 3.1 requires the +# correctly-rounded string <-> double conversion functions from +# Python/dtoa.c, which in turn require that the FPU uses 53-bit +# rounding; this is a problem on x86, where the x87 FPU has a default +# rounding precision of 64 bits. For gcc/x86, we try to fix this by +# using inline assembler to get and set the x87 FPU control word. if test "$GCC" = yes && test -n "`$CC -dM -E - Author: mark.dickinson Date: Sat Apr 18 22:19:17 2009 New Revision: 71724 Log: Revert accidental changes to Objects/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 Apr 18 22:19:17 2009 @@ -15,11 +15,6 @@ #define MAX(x, y) ((x) < (y) ? (y) : (x)) #define MIN(x, y) ((x) < (y) ? (x) : (y)) -/* ascii character tests (as opposed to locale tests) */ -#define ISSPACE(c) ((c) == ' ' || (c) == '\f' || (c) == '\n' || \ - (c) == '\r' || (c) == '\t' || (c) == '\v') -#define ISDIGIT(c) ((c) >= '0' && (c) <= '9') - #ifdef HAVE_IEEEFP_H #include #endif @@ -193,7 +188,7 @@ } last = s + len; - while (*s && ISSPACE(Py_CHARMASK(*s))) + while (*s && isspace(Py_CHARMASK(*s))) s++; if (*s == '\0') { PyErr_SetString(PyExc_ValueError, "empty string for float()"); @@ -250,7 +245,7 @@ } /* Since end != s, the platform made *some* kind of sense out of the input. Trust it. */ - while (*end && ISSPACE(Py_CHARMASK(*end))) + while (*end && isspace(Py_CHARMASK(*end))) end++; if (*end != '\0') { PyOS_snprintf(buffer, sizeof(buffer), @@ -1280,7 +1275,7 @@ ********************/ /* leading whitespace and optional sign */ - while (ISSPACE(Py_CHARMASK(*s))) + while (isspace(Py_CHARMASK(*s))) s++; if (*s == '-') { s++; @@ -1304,7 +1299,6 @@ s_store = s; if (*s == '0') { s++; - if (*s == 'x' || *s == 'X') if (tolower(*s) == (int)'x') s++; else @@ -1351,7 +1345,7 @@ exp = 0; /* optional trailing whitespace leading to the end of the string */ - while (ISSPACE(Py_CHARMASK(*s))) + while (isspace(Py_CHARMASK(*s))) s++; if (s != s_end) goto parse_error; From nnorwitz at gmail.com Sat Apr 18 22:19:39 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sat, 18 Apr 2009 16:19:39 -0400 Subject: [Python-checkins] Python Regression Test Failures opt (1) Message-ID: <20090418201939.GA30936@python.psfb.org> 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly 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_al test_al skipped -- No module named al test_anydbm test_applesingle test_applesingle skipped -- No module named MacOS test_array 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 test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw 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_difflib test_dircache test_dis test_distutils [17363 refs] [17363 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_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_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 [13183 refs] [13183 refs] [13183 refs] [23366 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 test_lib2to3 failed -- errors occurred; run in verbose mode for details 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 -- OSError raises on RLock creation, see issue 3111! test_mutants test_mutex test_netrc test_new test_nis test_normalization test_ntpath test_old_mailbox test_openpty test_operator test_optparse test_os 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_peepholer test_pep247 test_pep263 test_pep277 test_pep277 skipped -- test works only on NT+ test_pep292 test_pep352 /tmp/python-test/local/lib/python2.7/test/test_pep352.py:31: PendingDeprecationWarning: Please use assertTrue instead. (ins.__class__.__name__, attr)) /tmp/python-test/local/lib/python2.7/test/test_pep352.py:92: PendingDeprecationWarning: Please use assertEqual instead. given, expected)) test_pickle test_pickletools test_pipes test_pkg test_pkgimport test_pkgutil test_platform [14838 refs] [14838 refs] test_plistlib test_poll test_popen [13188 refs] [13188 refs] [13188 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 [18909 refs] test_pyexpat test_queue test_quopri [15708 refs] [15708 refs] test_random test_re 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_sets test_sgmllib test_sha test_shelve test_shlex test_shutil test_signal test_site [13183 refs] [13183 refs] [13186 refs] [13183 refs] test_slice test_smtplib 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_struct test_structmembers test_structseq test_subprocess [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [15083 refs] [13398 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] [13183 refs] . [13183 refs] [13183 refs] this bit of output is from a test of stdout in a different process ... [13183 refs] [13183 refs] [13398 refs] test_sunaudiodev test_sunaudiodev skipped -- No module named sunaudiodev test_sundry test_symtable test_syntax test_sys [13183 refs] [13183 refs] [13412 refs] [13206 refs] test_tarfile test_tcl test_tcl skipped -- No module named _tkinter test_telnetlib test_tempfile [13186 refs] test_textwrap test_thread test_threaded_import test_threadedtempfile test_threading [16679 refs] [18065 refs] [17879 refs] [17879 refs] [17879 refs] [17879 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_unpack test_urllib test_urllib2 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 WARNING: uuid.getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._ifconfig_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. WARNING: uuid._unixdll_getnode is unreliable on many platforms. It is disabled until the code and/or test can be fixed properly. test_wait3 test_wait4 test_warnings test_wave test_weakref 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 332 tests OK. 1 test failed: test_lib2to3 35 tests skipped: test_aepack test_al test_applesingle test_bsddb185 test_bsddb3 test_cd test_cl test_curses test_epoll 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_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 6 skips unexpected on linux2: test_multiprocessing test_ttk_guionly test_epoll test_tk test_ioctl test_ttk_textonly [741358 refs] From python-checkins at python.org Sat Apr 18 22:25:25 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 18 Apr 2009 22:25:25 +0200 (CEST) Subject: [Python-checkins] r71725 - python/trunk/Objects/object.c Message-ID: <20090418202525.7BA041E403E@bag.python.org> Author: benjamin.peterson Date: Sat Apr 18 22:25:25 2009 New Revision: 71725 Log: initalize -> initialize Modified: python/trunk/Objects/object.c Modified: python/trunk/Objects/object.c ============================================================================== --- python/trunk/Objects/object.c (original) +++ python/trunk/Objects/object.c Sat Apr 18 22:25:25 2009 @@ -2087,7 +2087,7 @@ Py_FatalError("Can't initalize complex type"); if (PyType_Ready(&PyFloat_Type) < 0) - Py_FatalError("Can't initalize float type"); + Py_FatalError("Can't initialize float type"); if (PyType_Ready(&PyBuffer_Type) < 0) Py_FatalError("Can't initialize buffer type"); @@ -2108,13 +2108,13 @@ Py_FatalError("Can't initialize memoryview type"); if (PyType_Ready(&PyTuple_Type) < 0) - Py_FatalError("Can't initalize tuple type"); + Py_FatalError("Can't initialize tuple type"); if (PyType_Ready(&PyEnum_Type) < 0) - Py_FatalError("Can't initalize enumerate type"); + Py_FatalError("Can't initialize enumerate type"); if (PyType_Ready(&PyReversed_Type) < 0) - Py_FatalError("Can't initalize reversed type"); + Py_FatalError("Can't initialize reversed type"); } From python-checkins at python.org Sat Apr 18 22:50:25 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 18 Apr 2009 22:50:25 +0200 (CEST) Subject: [Python-checkins] r71726 - in python/branches/release26-maint: Lib/test/test_descr.py Misc/NEWS Objects/frameobject.c Objects/object.c Message-ID: <20090418205025.D1AB01E4040@bag.python.org> Author: benjamin.peterson Date: Sat Apr 18 22:50:24 2009 New Revision: 71726 Log: Merged revisions 71722,71725 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71722 | benjamin.peterson | 2009-04-18 15:12:47 -0500 (Sat, 18 Apr 2009) | 1 line try to initalize all builtin types with PyType_Ready to avoid problems like #5787 ........ r71725 | benjamin.peterson | 2009-04-18 15:25:25 -0500 (Sat, 18 Apr 2009) | 1 line initalize -> initialize ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_descr.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Objects/frameobject.c python/branches/release26-maint/Objects/object.c Modified: python/branches/release26-maint/Lib/test/test_descr.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_descr.py (original) +++ python/branches/release26-maint/Lib/test/test_descr.py Sat Apr 18 22:50:24 2009 @@ -1,3 +1,4 @@ +import __builtin__ import types import unittest import warnings @@ -3838,6 +3839,17 @@ else: self.fail("new-style class must have a new-style base") + def test_builtin_bases(self): + # Make sure all the builtin types can have their base queried without + # segfaulting. See issue #5787. + builtin_types = [tp for tp in __builtin__.__dict__.itervalues() + if isinstance(tp, type)] + for tp in builtin_types: + object.__getattribute__(tp, "__bases__") + if tp is not object: + self.assertEqual(len(tp.__bases__), 1, tp) + + def test_mutable_bases_with_failing_mro(self): # Testing mutable bases with failing mro... class WorkOnce(type): Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sat Apr 18 22:50:24 2009 @@ -12,9 +12,12 @@ Core and Builtins ----------------- +- Issue #5787: object.__getattribute__(some_type, "__bases__") segfaulted on + some builtin types. + - Issue #5759: float() didn't call __float__ on str subclasses. -Library +Librar ------- - Issue #5768: Fixed bug in Unicode output logic and test case for same. Modified: python/branches/release26-maint/Objects/frameobject.c ============================================================================== --- python/branches/release26-maint/Objects/frameobject.c (original) +++ python/branches/release26-maint/Objects/frameobject.c Sat Apr 18 22:50:24 2009 @@ -574,14 +574,6 @@ builtin_object = PyString_InternFromString("__builtins__"); if (builtin_object == NULL) return 0; - /* - Traceback objects are not created the normal way (through calling the - type), so PyType_Ready has to be called here. - */ - if (PyType_Ready(&PyTraceBack_Type)) { - Py_DECREF(builtin_object); - return 0; - } return 1; } Modified: python/branches/release26-maint/Objects/object.c ============================================================================== --- python/branches/release26-maint/Objects/object.c (original) +++ python/branches/release26-maint/Objects/object.c Sat Apr 18 22:50:24 2009 @@ -2022,28 +2022,85 @@ _Py_ReadyTypes(void) { if (PyType_Ready(&PyType_Type) < 0) - Py_FatalError("Can't initialize 'type'"); + Py_FatalError("Can't initialize type type"); if (PyType_Ready(&_PyWeakref_RefType) < 0) - Py_FatalError("Can't initialize 'weakref'"); + Py_FatalError("Can't initialize weakref type"); if (PyType_Ready(&PyBool_Type) < 0) - Py_FatalError("Can't initialize 'bool'"); + Py_FatalError("Can't initialize bool type"); if (PyType_Ready(&PyString_Type) < 0) - Py_FatalError("Can't initialize 'str'"); + Py_FatalError("Can't initialize str type"); if (PyType_Ready(&PyByteArray_Type) < 0) - Py_FatalError("Can't initialize 'bytes'"); + Py_FatalError("Can't initialize bytearray"); if (PyType_Ready(&PyList_Type) < 0) - Py_FatalError("Can't initialize 'list'"); + Py_FatalError("Can't initialize list"); if (PyType_Ready(&PyNone_Type) < 0) - Py_FatalError("Can't initialize type(None)"); + Py_FatalError("Can't initialize None type"); if (PyType_Ready(&PyNotImplemented_Type) < 0) - Py_FatalError("Can't initialize type(NotImplemented)"); + Py_FatalError("Can't initialize NotImplemented type"); + + if (PyType_Ready(&PyTraceBack_Type) < 0) + Py_FatalError("Can't initialize traceback type"); + + if (PyType_Ready(&PySuper_Type) < 0) + Py_FatalError("Can't initialize super type"); + + if (PyType_Ready(&PyBaseObject_Type) < 0) + Py_FatalError("Can't initialize object type"); + + if (PyType_Ready(&PyRange_Type) < 0) + Py_FatalError("Can't initialize xrange type"); + + if (PyType_Ready(&PyDict_Type) < 0) + Py_FatalError("Can't initialize dict type"); + + if (PyType_Ready(&PySet_Type) < 0) + Py_FatalError("Can't initialize set type"); + + if (PyType_Ready(&PyUnicode_Type) < 0) + Py_FatalError("Can't initialize unicode type"); + + if (PyType_Ready(&PySlice_Type) < 0) + Py_FatalError("Can't initialize slice type"); + + if (PyType_Ready(&PyStaticMethod_Type) < 0) + Py_FatalError("Can't initialize static method type"); + + if (PyType_Ready(&PyComplex_Type) < 0) + Py_FatalError("Can't initalize complex type"); + + if (PyType_Ready(&PyFloat_Type) < 0) + Py_FatalError("Can't initialize float type"); + + if (PyType_Ready(&PyBuffer_Type) < 0) + Py_FatalError("Can't initialize buffer type"); + + if (PyType_Ready(&PyLong_Type) < 0) + Py_FatalError("Can't initialize long type"); + + if (PyType_Ready(&PyInt_Type) < 0) + Py_FatalError("Can't initialize int type"); + + if (PyType_Ready(&PyFrozenSet_Type) < 0) + Py_FatalError("Can't initialize frozenset type"); + + if (PyType_Ready(&PyProperty_Type) < 0) + Py_FatalError("Can't initialize property type"); + + if (PyType_Ready(&PyTuple_Type) < 0) + Py_FatalError("Can't initialize tuple type"); + + if (PyType_Ready(&PyEnum_Type) < 0) + Py_FatalError("Can't initialize enumerate type"); + + if (PyType_Ready(&PyReversed_Type) < 0) + Py_FatalError("Can't initialize reversed type"); } From python-checkins at python.org Sat Apr 18 22:54:09 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 18 Apr 2009 22:54:09 +0200 (CEST) Subject: [Python-checkins] r71727 - in python/branches/py3k: Lib/test/test_descr.py Misc/NEWS Objects/frameobject.c Objects/object.c Message-ID: <20090418205409.B56321E4040@bag.python.org> Author: benjamin.peterson Date: Sat Apr 18 22:54:08 2009 New Revision: 71727 Log: Merged revisions 71722 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71722 | benjamin.peterson | 2009-04-18 15:12:47 -0500 (Sat, 18 Apr 2009) | 1 line try to initalize all builtin types with PyType_Ready to avoid problems like #5787 ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_descr.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/frameobject.c python/branches/py3k/Objects/object.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 Sat Apr 18 22:54:08 2009 @@ -1,3 +1,4 @@ +import builtins import types import unittest import warnings @@ -3586,6 +3587,17 @@ else: self.fail("shouldn't be able to create inheritance cycles") + def test_builtin_bases(self): + # Make sure all the builtin types can have their base queried without + # segfaulting. See issue #5787. + builtin_types = [tp for tp in builtins.__dict__.values() + if isinstance(tp, type)] + for tp in builtin_types: + object.__getattribute__(tp, "__bases__") + if tp is not object: + self.assertEqual(len(tp.__bases__), 1, tp) + + def test_mutable_bases_with_failing_mro(self): # Testing mutable bases with failing mro... class WorkOnce(type): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Apr 18 22:54:08 2009 @@ -17,6 +17,9 @@ from Python/dtoa.c. As a consequence, (e.g.) round(x, 2) now consistently agrees with format(x, '.2f'). +- Issue #5787: object.__getattribute__(some_type, "__bases__") segfaulted on + some builtin types. + - Issue #5772: format(1e100, '<') produces '1e+100', not '1.0e+100'. - Issue #5515: str.format() type 'n' combined with commas and leading Modified: python/branches/py3k/Objects/frameobject.c ============================================================================== --- python/branches/py3k/Objects/frameobject.c (original) +++ python/branches/py3k/Objects/frameobject.c Sat Apr 18 22:54:08 2009 @@ -577,7 +577,9 @@ int _PyFrame_Init() { builtin_object = PyUnicode_InternFromString("__builtins__"); - return (builtin_object != NULL); + if (builtin_object == NULL) + return 0; + return 1; } PyFrameObject * Modified: python/branches/py3k/Objects/object.c ============================================================================== --- python/branches/py3k/Objects/object.c (original) +++ python/branches/py3k/Objects/object.c Sat Apr 18 22:54:08 2009 @@ -1479,31 +1479,85 @@ _Py_ReadyTypes(void) { if (PyType_Ready(&PyType_Type) < 0) - Py_FatalError("Can't initialize 'type'"); + Py_FatalError("Can't initialize type type"); if (PyType_Ready(&_PyWeakref_RefType) < 0) - Py_FatalError("Can't initialize 'weakref'"); + Py_FatalError("Can't initialize weakref type"); if (PyType_Ready(&PyBool_Type) < 0) - Py_FatalError("Can't initialize 'bool'"); + Py_FatalError("Can't initialize bool type"); if (PyType_Ready(&PyByteArray_Type) < 0) - Py_FatalError("Can't initialize 'bytes'"); + Py_FatalError("Can't initialize bytearray"); if (PyType_Ready(&PyBytes_Type) < 0) Py_FatalError("Can't initialize 'str'"); if (PyType_Ready(&PyList_Type) < 0) - Py_FatalError("Can't initialize 'list'"); + Py_FatalError("Can't initialize list"); if (PyType_Ready(&PyNone_Type) < 0) - Py_FatalError("Can't initialize type(None)"); + Py_FatalError("Can't initialize None type"); if (PyType_Ready(Py_Ellipsis->ob_type) < 0) Py_FatalError("Can't initialize type(Ellipsis)"); if (PyType_Ready(&PyNotImplemented_Type) < 0) - Py_FatalError("Can't initialize type(NotImplemented)"); + Py_FatalError("Can't initialize NotImplemented type"); + + if (PyType_Ready(&PyTraceBack_Type) < 0) + Py_FatalError("Can't initialize traceback type"); + + if (PyType_Ready(&PySuper_Type) < 0) + Py_FatalError("Can't initialize super type"); + + if (PyType_Ready(&PyBaseObject_Type) < 0) + Py_FatalError("Can't initialize object type"); + + if (PyType_Ready(&PyRange_Type) < 0) + Py_FatalError("Can't initialize range type"); + + if (PyType_Ready(&PyDict_Type) < 0) + Py_FatalError("Can't initialize dict type"); + + if (PyType_Ready(&PySet_Type) < 0) + Py_FatalError("Can't initialize set type"); + + if (PyType_Ready(&PyUnicode_Type) < 0) + Py_FatalError("Can't initialize str type"); + + if (PyType_Ready(&PySlice_Type) < 0) + Py_FatalError("Can't initialize slice type"); + + if (PyType_Ready(&PyStaticMethod_Type) < 0) + Py_FatalError("Can't initialize static method type"); + + if (PyType_Ready(&PyComplex_Type) < 0) + Py_FatalError("Can't initialize complex type"); + + if (PyType_Ready(&PyFloat_Type) < 0) + Py_FatalError("Can't initialize float type"); + + if (PyType_Ready(&PyLong_Type) < 0) + Py_FatalError("Can't initialize int type"); + + if (PyType_Ready(&PyFrozenSet_Type) < 0) + Py_FatalError("Can't initialize frozenset type"); + + if (PyType_Ready(&PyProperty_Type) < 0) + Py_FatalError("Can't initialize property type"); + + if (PyType_Ready(&PyMemoryView_Type) < 0) + Py_FatalError("Can't initialize memoryview type"); + + if (PyType_Ready(&PyTuple_Type) < 0) + Py_FatalError("Can't initialize tuple type"); + + if (PyType_Ready(&PyEnum_Type) < 0) + Py_FatalError("Can't initialize enumerate type"); + + if (PyType_Ready(&PyReversed_Type) < 0) + Py_FatalError("Can't initialize reversed type"); if (PyType_Ready(&PyCode_Type) < 0) Py_FatalError("Can't initialize 'code'"); From python-checkins at python.org Sat Apr 18 22:57:50 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 22:57:50 +0200 (CEST) Subject: [Python-checkins] r71728 - python/branches/release30-maint Message-ID: <20090418205750.B2DB51E4040@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 22:57:50 2009 New Revision: 71728 Log: Blocked revisions 71723-71724 via svnmerge ........ r71723 | mark.dickinson | 2009-04-18 21:17:52 +0100 (Sat, 18 Apr 2009) | 7 lines The SSE2 detection and enabling could potentially cause problems for binary distributions of Python in situations where the build machine has SSE2 but the target machine does not. Therefore, don't enable SSE2 instructions automatically on x86. ........ r71724 | mark.dickinson | 2009-04-18 21:19:17 +0100 (Sat, 18 Apr 2009) | 2 lines Revert accidental changes to Objects/floatobject.c ........ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sat Apr 18 23:03:10 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 18 Apr 2009 23:03:10 +0200 (CEST) Subject: [Python-checkins] r71729 - python/trunk/Lib/test/test_descr.py Message-ID: <20090418210310.D2A181E4040@bag.python.org> Author: benjamin.peterson Date: Sat Apr 18 23:03:10 2009 New Revision: 71729 Log: move test to a more appropiate one Modified: python/trunk/Lib/test/test_descr.py Modified: python/trunk/Lib/test/test_descr.py ============================================================================== --- python/trunk/Lib/test/test_descr.py (original) +++ python/trunk/Lib/test/test_descr.py Sat Apr 18 23:03:10 2009 @@ -3811,31 +3811,6 @@ self.assertEqual(e.a, 2) self.assertEqual(C2.__subclasses__(), [D]) - # stuff that shouldn't: - class L(list): - pass - - try: - L.__bases__ = (dict,) - except TypeError: - pass - else: - self.fail("shouldn't turn list subclass into dict subclass") - - try: - list.__bases__ = (dict,) - except TypeError: - pass - else: - self.fail("shouldn't be able to assign to list.__bases__") - - try: - D.__bases__ = (C2, list) - except TypeError: - pass - else: - assert 0, "best_base calculation found wanting" - try: del D.__bases__ except (TypeError, AttributeError): @@ -3906,6 +3881,36 @@ if tp is not object: self.assertEqual(len(tp.__bases__), 1, tp) + class L(list): + pass + + class C(object): + pass + + class D(C): + pass + + try: + L.__bases__ = (dict,) + except TypeError: + pass + else: + self.fail("shouldn't turn list subclass into dict subclass") + + try: + list.__bases__ = (dict,) + except TypeError: + pass + else: + self.fail("shouldn't be able to assign to list.__bases__") + + try: + D.__bases__ = (C, list) + except TypeError: + pass + else: + assert 0, "best_base calculation found wanting" + def test_mutable_bases_with_failing_mro(self): # Testing mutable bases with failing mro... From python-checkins at python.org Sat Apr 18 23:10:50 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 18 Apr 2009 23:10:50 +0200 (CEST) Subject: [Python-checkins] r71730 - in python/branches/release30-maint: Lib/test/test_descr.py Misc/NEWS Objects/frameobject.c Objects/object.c Message-ID: <20090418211050.A4D531E4040@bag.python.org> Author: benjamin.peterson Date: Sat Apr 18 23:10:48 2009 New Revision: 71730 Log: Merged revisions 71727 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71727 | benjamin.peterson | 2009-04-18 15:54:08 -0500 (Sat, 18 Apr 2009) | 9 lines Merged revisions 71722 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71722 | benjamin.peterson | 2009-04-18 15:12:47 -0500 (Sat, 18 Apr 2009) | 1 line try to initalize all builtin types with PyType_Ready to avoid problems like #5787 ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Lib/test/test_descr.py python/branches/release30-maint/Misc/NEWS python/branches/release30-maint/Objects/frameobject.c python/branches/release30-maint/Objects/object.c Modified: python/branches/release30-maint/Lib/test/test_descr.py ============================================================================== --- python/branches/release30-maint/Lib/test/test_descr.py (original) +++ python/branches/release30-maint/Lib/test/test_descr.py Sat Apr 18 23:10:48 2009 @@ -1,3 +1,4 @@ +import builtins import types import unittest import warnings @@ -3538,6 +3539,17 @@ else: self.fail("shouldn't be able to create inheritance cycles") + def test_builtin_bases(self): + # Make sure all the builtin types can have their base queried without + # segfaulting. See issue #5787. + builtin_types = [tp for tp in builtins.__dict__.values() + if isinstance(tp, type)] + for tp in builtin_types: + object.__getattribute__(tp, "__bases__") + if tp is not object: + self.assertEqual(len(tp.__bases__), 1, tp) + + def test_mutable_bases_with_failing_mro(self): # Testing mutable bases with failing mro... class WorkOnce(type): Modified: python/branches/release30-maint/Misc/NEWS ============================================================================== --- python/branches/release30-maint/Misc/NEWS (original) +++ python/branches/release30-maint/Misc/NEWS Sat Apr 18 23:10:48 2009 @@ -18,6 +18,9 @@ - Issue #5759: float() didn't call __float__ on str subclasses. +- Issue #5787: object.__getattribute__(some_type, "__bases__") segfaulted on + some builtin types. + - Issue #5392: when a very low recursion limit was set, the interpreter would abort with a fatal error after the recursion limit was hit twice. Modified: python/branches/release30-maint/Objects/frameobject.c ============================================================================== --- python/branches/release30-maint/Objects/frameobject.c (original) +++ python/branches/release30-maint/Objects/frameobject.c Sat Apr 18 23:10:48 2009 @@ -577,7 +577,9 @@ int _PyFrame_Init() { builtin_object = PyUnicode_InternFromString("__builtins__"); - return (builtin_object != NULL); + if (builtin_object == NULL) + return 0; + return 1; } PyFrameObject * Modified: python/branches/release30-maint/Objects/object.c ============================================================================== --- python/branches/release30-maint/Objects/object.c (original) +++ python/branches/release30-maint/Objects/object.c Sat Apr 18 23:10:48 2009 @@ -1462,31 +1462,85 @@ _Py_ReadyTypes(void) { if (PyType_Ready(&PyType_Type) < 0) - Py_FatalError("Can't initialize 'type'"); + Py_FatalError("Can't initialize type type"); if (PyType_Ready(&_PyWeakref_RefType) < 0) - Py_FatalError("Can't initialize 'weakref'"); + Py_FatalError("Can't initialize weakref type"); if (PyType_Ready(&PyBool_Type) < 0) - Py_FatalError("Can't initialize 'bool'"); + Py_FatalError("Can't initialize bool type"); if (PyType_Ready(&PyByteArray_Type) < 0) - Py_FatalError("Can't initialize 'bytes'"); + Py_FatalError("Can't initialize bytearray"); if (PyType_Ready(&PyBytes_Type) < 0) Py_FatalError("Can't initialize 'str'"); if (PyType_Ready(&PyList_Type) < 0) - Py_FatalError("Can't initialize 'list'"); + Py_FatalError("Can't initialize list"); if (PyType_Ready(&PyNone_Type) < 0) - Py_FatalError("Can't initialize type(None)"); + Py_FatalError("Can't initialize None type"); if (PyType_Ready(Py_Ellipsis->ob_type) < 0) Py_FatalError("Can't initialize type(Ellipsis)"); if (PyType_Ready(&PyNotImplemented_Type) < 0) - Py_FatalError("Can't initialize type(NotImplemented)"); + Py_FatalError("Can't initialize NotImplemented type"); + + if (PyType_Ready(&PyTraceBack_Type) < 0) + Py_FatalError("Can't initialize traceback type"); + + if (PyType_Ready(&PySuper_Type) < 0) + Py_FatalError("Can't initialize super type"); + + if (PyType_Ready(&PyBaseObject_Type) < 0) + Py_FatalError("Can't initialize object type"); + + if (PyType_Ready(&PyRange_Type) < 0) + Py_FatalError("Can't initialize range type"); + + if (PyType_Ready(&PyDict_Type) < 0) + Py_FatalError("Can't initialize dict type"); + + if (PyType_Ready(&PySet_Type) < 0) + Py_FatalError("Can't initialize set type"); + + if (PyType_Ready(&PyUnicode_Type) < 0) + Py_FatalError("Can't initialize str type"); + + if (PyType_Ready(&PySlice_Type) < 0) + Py_FatalError("Can't initialize slice type"); + + if (PyType_Ready(&PyStaticMethod_Type) < 0) + Py_FatalError("Can't initialize static method type"); + + if (PyType_Ready(&PyComplex_Type) < 0) + Py_FatalError("Can't initialize complex type"); + + if (PyType_Ready(&PyFloat_Type) < 0) + Py_FatalError("Can't initialize float type"); + + if (PyType_Ready(&PyLong_Type) < 0) + Py_FatalError("Can't initialize int type"); + + if (PyType_Ready(&PyFrozenSet_Type) < 0) + Py_FatalError("Can't initialize frozenset type"); + + if (PyType_Ready(&PyProperty_Type) < 0) + Py_FatalError("Can't initialize property type"); + + if (PyType_Ready(&PyMemoryView_Type) < 0) + Py_FatalError("Can't initialize memoryview type"); + + if (PyType_Ready(&PyTuple_Type) < 0) + Py_FatalError("Can't initialize tuple type"); + + if (PyType_Ready(&PyEnum_Type) < 0) + Py_FatalError("Can't initialize enumerate type"); + + if (PyType_Ready(&PyReversed_Type) < 0) + Py_FatalError("Can't initialize reversed type"); if (PyType_Ready(&PyCode_Type) < 0) Py_FatalError("Can't initialize 'code'"); From python-checkins at python.org Sat Apr 18 23:18:20 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 23:18:20 +0200 (CEST) Subject: [Python-checkins] r71731 - in python/branches/py3k: configure configure.in Message-ID: <20090418211820.0729D1E4044@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 23:18:19 2009 New Revision: 71731 Log: Move configure check for broken sem_getvalue outside the LIBS="$LIBS $LIBM" section. Modified: python/branches/py3k/configure python/branches/py3k/configure.in Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Sat Apr 18 23:18:19 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 71704 . +# From configure.in Revision: 71723 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.1. # @@ -21828,17 +21828,15 @@ fi # The short float repr introduced in Python 3.1 requires the -# correctly-rounded string <-> double conversion functions in +# correctly-rounded string <-> double conversion functions from # Python/dtoa.c, which in turn require that the FPU uses 53-bit -# rounding; this is a particular problem on x86, where the x87 FPU has -# a default rounding precision of 64 bits. For gcc/x86, we try to fix -# this by using inline assembler to get and set the x87 FPU control -# word. - +# rounding; this is a problem on x86, where the x87 FPU has a default +# rounding precision of 64 bits. For gcc/x86, we try to fix this by +# using inline assembler to get and set the x87 FPU control word. if test "$GCC" = yes && test -n "`$CC -dM -E - &5 echo $ECHO_N "checking whether we can use gcc inline assembler to get and set x87 control word... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF @@ -21990,87 +21988,6 @@ LIBS_SAVE=$LIBS LIBS="$LIBS $LIBM" -# Multiprocessing check for broken sem_getvalue -{ echo "$as_me:$LINENO: checking for broken sem_getvalue" >&5 -echo $ECHO_N "checking for broken sem_getvalue... $ECHO_C" >&6; } -if test "$cross_compiling" = yes; then - { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run test program while cross compiling -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#include -#include -#include -#include -#include - -int main(void){ - sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); - int count; - int res; - if(a==SEM_FAILED){ - perror("sem_open"); - return 1; - - } - res = sem_getvalue(a, &count); - sem_close(a); - return res==-1 ? 1 : 0; -} - - -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -{ echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } - -cat >>confdefs.h <<\_ACEOF -#define HAVE_BROKEN_SEM_GETVALUE 1 -_ACEOF - - -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - - # On FreeBSD 6.2, it appears that tanh(-0.) returns 0. instead of # -0. on some architectures. { echo "$as_me:$LINENO: checking whether tanh preserves the sign of zero" >&5 @@ -22455,6 +22372,87 @@ LIBS=$LIBS_SAVE +# Multiprocessing check for broken sem_getvalue +{ echo "$as_me:$LINENO: checking for broken sem_getvalue" >&5 +echo $ECHO_N "checking for broken sem_getvalue... $ECHO_C" >&6; } +if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +#include +#include +#include + +int main(void){ + sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + int count; + int res; + if(a==SEM_FAILED){ + perror("sem_open"); + return 1; + + } + res = sem_getvalue(a, &count); + sem_close(a); + return res==-1 ? 1 : 0; +} + + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define HAVE_BROKEN_SEM_GETVALUE 1 +_ACEOF + + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + # determine what size digit to use for Python's longs { echo "$as_me:$LINENO: checking digit size for Python's longs" >&5 echo $ECHO_N "checking digit size for Python's longs... $ECHO_C" >&6; } Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Sat Apr 18 23:18:19 2009 @@ -3214,34 +3214,6 @@ LIBS_SAVE=$LIBS LIBS="$LIBS $LIBM" -# Multiprocessing check for broken sem_getvalue -AC_MSG_CHECKING(for broken sem_getvalue) -AC_TRY_RUN([ -#include -#include -#include -#include -#include - -int main(void){ - sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); - int count; - int res; - if(a==SEM_FAILED){ - perror("sem_open"); - return 1; - - } - res = sem_getvalue(a, &count); - sem_close(a); - return res==-1 ? 1 : 0; -} -] -,AC_MSG_RESULT(no), - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_BROKEN_SEM_GETVALUE, 1, define to 1 if your sem_getvalue is broken.) -) - # On FreeBSD 6.2, it appears that tanh(-0.) returns 0. instead of # -0. on some architectures. AC_MSG_CHECKING(whether tanh preserves the sign of zero) @@ -3273,6 +3245,34 @@ LIBS=$LIBS_SAVE +# Multiprocessing check for broken sem_getvalue +AC_MSG_CHECKING(for broken sem_getvalue) +AC_TRY_RUN([ +#include +#include +#include +#include +#include + +int main(void){ + sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + int count; + int res; + if(a==SEM_FAILED){ + perror("sem_open"); + return 1; + + } + res = sem_getvalue(a, &count); + sem_close(a); + return res==-1 ? 1 : 0; +} +] +,AC_MSG_RESULT(no), + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BROKEN_SEM_GETVALUE, 1, define to 1 if your sem_getvalue is broken.) +) + # determine what size digit to use for Python's longs AC_MSG_CHECKING([digit size for Python's longs]) AC_ARG_ENABLE(big-digits, From python-checkins at python.org Sat Apr 18 23:19:18 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 18 Apr 2009 23:19:18 +0200 (CEST) Subject: [Python-checkins] r71732 - python/branches/release30-maint Message-ID: <20090418211918.AD4D71E4040@bag.python.org> Author: mark.dickinson Date: Sat Apr 18 23:19:18 2009 New Revision: 71732 Log: Blocked revisions 71731 via svnmerge ........ r71731 | mark.dickinson | 2009-04-18 22:18:19 +0100 (Sat, 18 Apr 2009) | 3 lines Move configure check for broken sem_getvalue outside the LIBS="$LIBS $LIBM" section. ........ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sat Apr 18 23:24:34 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 18 Apr 2009 23:24:34 +0200 (CEST) Subject: [Python-checkins] r71733 - python/branches/py3k Message-ID: <20090418212434.121671E4040@bag.python.org> Author: benjamin.peterson Date: Sat Apr 18 23:24:33 2009 New Revision: 71733 Log: Blocked revisions 71725 via svnmerge ........ r71725 | benjamin.peterson | 2009-04-18 15:25:25 -0500 (Sat, 18 Apr 2009) | 1 line initalize -> initialize ........ Modified: python/branches/py3k/ (props changed) From ocean-city at m2.ccsnet.ne.jp Sat Apr 18 23:50:23 2009 From: ocean-city at m2.ccsnet.ne.jp (Hirokazu Yamamoto) Date: Sun, 19 Apr 2009 06:50:23 +0900 Subject: [Python-checkins] r71701 - in python/branches/py3k: Lib/test/test_float.py Misc/NEWS Objects/floatobject.c In-Reply-To: <5c6f2a5d0904180636p5818bfc3l1cdd62aa3aad9234@mail.gmail.com> References: <20090418114833.DF6851E40F4@bag.python.org> <49E9D0A6.2030700@m2.ccsnet.ne.jp> <5c6f2a5d0904180636p5818bfc3l1cdd62aa3aad9234@mail.gmail.com> Message-ID: <49EA4B1F.3070800@m2.ccsnet.ne.jp> Mark Dickinson wrote: > Thanks. I should have expected this. > > I'll fix it. I have confirmed your fix is working. Thanks! From buildbot at python.org Sat Apr 18 23:58:57 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 18 Apr 2009 21:58:57 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu trunk Message-ID: <20090418215857.E811E1E4044@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%20trunk/builds/1250 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: benjamin.peterson BUILD FAILED: failed test Excerpt from the test logfile: make: *** [buildbottest] Alarm clock sincerely, -The Buildbot From python-checkins at python.org Sun Apr 19 00:15:27 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 19 Apr 2009 00:15:27 +0200 (CEST) Subject: [Python-checkins] r71734 - in python/trunk: Include/descrobject.h Include/sliceobject.h Objects/descrobject.c Objects/object.c Objects/sliceobject.c Message-ID: <20090418221527.755191E4039@bag.python.org> Author: benjamin.peterson Date: Sun Apr 19 00:15:26 2009 New Revision: 71734 Log: many more types to initialize (I had to expose some of them) Modified: python/trunk/Include/descrobject.h python/trunk/Include/sliceobject.h python/trunk/Objects/descrobject.c python/trunk/Objects/object.c python/trunk/Objects/sliceobject.c Modified: python/trunk/Include/descrobject.h ============================================================================== --- python/trunk/Include/descrobject.h (original) +++ python/trunk/Include/descrobject.h Sun Apr 19 00:15:26 2009 @@ -68,6 +68,9 @@ } PyWrapperDescrObject; PyAPI_DATA(PyTypeObject) PyWrapperDescr_Type; +PyAPI_DATA(PyTypeObject) PyDictProxy_Type; +PyAPI_DATA(PyTypeObject) PyGetSetDescr_Type; +PyAPI_DATA(PyTypeObject) PyMemberDescr_Type; PyAPI_FUNC(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *); PyAPI_FUNC(PyObject *) PyDescr_NewClassMethod(PyTypeObject *, PyMethodDef *); Modified: python/trunk/Include/sliceobject.h ============================================================================== --- python/trunk/Include/sliceobject.h (original) +++ python/trunk/Include/sliceobject.h Sun Apr 19 00:15:26 2009 @@ -25,6 +25,7 @@ } PySliceObject; PyAPI_DATA(PyTypeObject) PySlice_Type; +PyAPI_DATA(PyTypeObject) PyEllipsis_Type; #define PySlice_Check(op) (Py_TYPE(op) == &PySlice_Type) Modified: python/trunk/Objects/descrobject.c ============================================================================== --- python/trunk/Objects/descrobject.c (original) +++ python/trunk/Objects/descrobject.c Sun Apr 19 00:15:26 2009 @@ -456,7 +456,7 @@ 0, /* tp_descr_set */ }; -static PyTypeObject PyMemberDescr_Type = { +PyTypeObject PyMemberDescr_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "member_descriptor", sizeof(PyMemberDescrObject), @@ -493,7 +493,7 @@ (descrsetfunc)member_set, /* tp_descr_set */ }; -static PyTypeObject PyGetSetDescr_Type = { +PyTypeObject PyGetSetDescr_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "getset_descriptor", sizeof(PyGetSetDescrObject), @@ -819,7 +819,7 @@ return PyObject_RichCompare(v->dict, w, op); } -static PyTypeObject proxytype = { +PyTypeObject PyDictProxy_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "dictproxy", /* tp_name */ sizeof(proxyobject), /* tp_basicsize */ @@ -862,7 +862,7 @@ { proxyobject *pp; - pp = PyObject_GC_New(proxyobject, &proxytype); + pp = PyObject_GC_New(proxyobject, &PyDictProxy_Type); if (pp != NULL) { Py_INCREF(dict); pp->dict = dict; Modified: python/trunk/Objects/object.c ============================================================================== --- python/trunk/Objects/object.c (original) +++ python/trunk/Objects/object.c Sun Apr 19 00:15:26 2009 @@ -2,6 +2,7 @@ /* Generic object operations; and implementation of None (NoObject) */ #include "Python.h" +#include "frameobject.h" #ifdef __cplusplus extern "C" { @@ -2083,8 +2084,10 @@ if (PyType_Ready(&PyStaticMethod_Type) < 0) Py_FatalError("Can't initialize static method type"); +#ifndef WITHOUT_COMPLEX if (PyType_Ready(&PyComplex_Type) < 0) - Py_FatalError("Can't initalize complex type"); + Py_FatalError("Can't initialize complex type"); +#endif if (PyType_Ready(&PyFloat_Type) < 0) Py_FatalError("Can't initialize float type"); @@ -2115,6 +2118,45 @@ if (PyType_Ready(&PyReversed_Type) < 0) Py_FatalError("Can't initialize reversed type"); + + if (PyType_Ready(&PyCode_Type) < 0) + Py_FatalError("Can't initialize code type"); + + if (PyType_Ready(&PyFrame_Type) < 0) + Py_FatalError("Can't initialize frame type"); + + if (PyType_Ready(&PyCFunction_Type) < 0) + Py_FatalError("Can't initialize builtin function type"); + + if (PyType_Ready(&PyMethod_Type) < 0) + Py_FatalError("Can't initialize method type"); + + if (PyType_Ready(&PyFunction_Type) < 0) + Py_FatalError("Can't initialize function type"); + + if (PyType_Ready(&PyClass_Type) < 0) + Py_FatalError("Can't initialize class type"); + + if (PyType_Ready(&PyDictProxy_Type) < 0) + Py_FatalError("Can't initialize dict proxy type"); + + if (PyType_Ready(&PyGen_Type) < 0) + Py_FatalError("Can't initialize generator type"); + + if (PyType_Ready(&PyGetSetDescr_Type) < 0) + Py_FatalError("Can't initialize get-set descriptor type"); + + if (PyType_Ready(&PyWrapperDescr_Type) < 0) + Py_FatalError("Can't initialize wrapper type"); + + if (PyType_Ready(&PyInstance_Type) < 0) + Py_FatalError("Can't initialize instance type"); + + if (PyType_Ready(&PyEllipsis_Type) < 0) + Py_FatalError("Can't initialize ellipsis type"); + + if (PyType_Ready(&PyMemberDescr_Type) < 0) + Py_FatalError("Can't initialize member descriptor type"); } Modified: python/trunk/Objects/sliceobject.c ============================================================================== --- python/trunk/Objects/sliceobject.c (original) +++ python/trunk/Objects/sliceobject.c Sun Apr 19 00:15:26 2009 @@ -22,7 +22,7 @@ return PyString_FromString("Ellipsis"); } -static PyTypeObject PyEllipsis_Type = { +PyTypeObject PyEllipsis_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "ellipsis", /* tp_name */ 0, /* tp_basicsize */ From buildbot at python.org Sun Apr 19 00:36:01 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 18 Apr 2009 22:36:01 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 3.0 Message-ID: <20090418223602.7F0621E4039@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%203.0/builds/291 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: benjamin.peterson,mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: make: *** [buildbottest] Unknown signal 32 sincerely, -The Buildbot From buildbot at python.org Sun Apr 19 00:49:29 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 18 Apr 2009 22:49:29 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 2.6 Message-ID: <20090418224929.CA2531E406A@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%202.6/builds/256 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: benjamin.peterson BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From ncoghlan at gmail.com Sun Apr 19 01:26:24 2009 From: ncoghlan at gmail.com (Nick Coghlan) Date: Sun, 19 Apr 2009 09:26:24 +1000 Subject: [Python-checkins] r71722 - in python/trunk: Lib/test/test_descr.py Misc/NEWS Objects/frameobject.c Objects/object.c In-Reply-To: <20090418201247.8F2761E4160@bag.python.org> References: <20090418201247.8F2761E4160@bag.python.org> Message-ID: <49EA61A0.4070603@gmail.com> benjamin.peterson wrote: > Author: benjamin.peterson > Date: Sat Apr 18 22:12:47 2009 > New Revision: 71722 > > Log: > try to initalize all builtin types with PyType_Ready to avoid problems like #5787 Ah, we almost did this when the __hash__ updates were giving us grief - good to see that particularly game of whack-a-mole dealt with once and for all. > if (PyType_Ready(&PyByteArray_Type) < 0) > - Py_FatalError("Can't initialize 'bytes'"); > + Py_FatalError("Can't initialize bytearray"); > > if (PyType_Ready(&PyList_Type) < 0) > - Py_FatalError("Can't initialize 'list'"); > + Py_FatalError("Can't initialize list"); Very minor nit - the trailing " type" is missing from these two error messages. Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia --------------------------------------------------------------- From buildbot at python.org Sun Apr 19 01:42:38 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 18 Apr 2009 23:42:38 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090418234239.0FA831E402F@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/278 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 3 tests failed: test_distutils test_posix test_subprocess ====================================================================== FAIL: test_get_python_inc (distutils.tests.test_sysconfig.SysconfigTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/distutils/tests/test_sysconfig.py", line 45, in test_get_python_inc self.assert_(os.path.isdir(inc_dir), inc_dir) AssertionError: /home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/Include ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From python-checkins at python.org Sun Apr 19 01:58:45 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sun, 19 Apr 2009 01:58:45 +0200 (CEST) Subject: [Python-checkins] r71735 - python/branches/release26-maint/Doc/library/itertools.rst Message-ID: <20090418235845.89BB01E402F@bag.python.org> Author: raymond.hettinger Date: Sun Apr 19 01:58:45 2009 New Revision: 71735 Log: Remove duplicate recipe. Modified: python/branches/release26-maint/Doc/library/itertools.rst Modified: python/branches/release26-maint/Doc/library/itertools.rst ============================================================================== --- python/branches/release26-maint/Doc/library/itertools.rst (original) +++ python/branches/release26-maint/Doc/library/itertools.rst Sun Apr 19 01:58:45 2009 @@ -702,11 +702,6 @@ pending -= 1 nexts = cycle(islice(nexts, pending)) - 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 compress(data, selectors): "compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F" return (d for d, s in izip(data, selectors) if s) From python-checkins at python.org Sun Apr 19 02:09:37 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 19 Apr 2009 02:09:37 +0200 (CEST) Subject: [Python-checkins] r71736 - in python/branches/py3k: Lib/_pyio.py Lib/test/test_io.py Misc/NEWS Modules/_io/bufferedio.c Message-ID: <20090419000937.0E0441E402F@bag.python.org> Author: antoine.pitrou Date: Sun Apr 19 02:09:36 2009 New Revision: 71736 Log: Issue #5734: BufferedRWPair was poorly tested and had several glaring bugs. Patch by Brian Quinlan. Modified: python/branches/py3k/Lib/_pyio.py 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/_pyio.py ============================================================================== --- python/branches/py3k/Lib/_pyio.py (original) +++ python/branches/py3k/Lib/_pyio.py Sun Apr 19 02:09:36 2009 @@ -839,7 +839,9 @@ def __init__(self, raw, buffer_size=DEFAULT_BUFFER_SIZE): """Create a new buffered reader using the given readable raw IO object. """ - raw._checkReadable() + if not raw.readable(): + raise IOError('"raw" argument must be readable.') + _BufferedIOMixin.__init__(self, raw) if buffer_size <= 0: raise ValueError("invalid buffer size") @@ -970,7 +972,9 @@ def __init__(self, raw, buffer_size=DEFAULT_BUFFER_SIZE, max_buffer_size=None): - raw._checkWritable() + if not raw.writable(): + raise IOError('"raw" argument must be writable.') + _BufferedIOMixin.__init__(self, raw) if buffer_size <= 0: raise ValueError("invalid buffer size") @@ -1076,8 +1080,13 @@ """ if max_buffer_size is not None: warnings.warn("max_buffer_size is deprecated", DeprecationWarning, 2) - reader._checkReadable() - writer._checkWritable() + + if not reader.readable(): + raise IOError('"reader" argument must be readable.') + + if not writer.writable(): + raise IOError('"writer" argument must be writable.') + self.reader = BufferedReader(reader, buffer_size) self.writer = BufferedWriter(writer, buffer_size) 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 Sun Apr 19 02:09:36 2009 @@ -1051,13 +1051,11 @@ class BufferedRWPairTest(unittest.TestCase): - def test_basic(self): - r = self.MockRawIO(()) - w = self.MockRawIO() - pair = self.tp(r, w) + def test_constructor(self): + pair = self.tp(self.MockRawIO(), self.MockRawIO()) self.assertFalse(pair.closed) - def test_max_buffer_size_deprecation(self): + def test_constructor_max_buffer_size_deprecation(self): with support.check_warnings() as w: warnings.simplefilter("always", DeprecationWarning) self.tp(self.MockRawIO(), self.MockRawIO(), 8, 12) @@ -1067,7 +1065,100 @@ self.assertEqual(str(warning.message), "max_buffer_size is deprecated") - # XXX More Tests + def test_constructor_with_not_readable(self): + class NotReadable(MockRawIO): + def readable(self): + return False + + self.assertRaises(IOError, self.tp, NotReadable(), self.MockRawIO()) + + def test_constructor_with_not_writeable(self): + class NotWriteable(MockRawIO): + def writable(self): + return False + + self.assertRaises(IOError, self.tp, self.MockRawIO(), NotWriteable()) + + def test_read(self): + pair = self.tp(self.BytesIO(b"abcdef"), self.MockRawIO()) + + self.assertEqual(pair.read(3), b"abc") + self.assertEqual(pair.read(1), b"d") + self.assertEqual(pair.read(), b"ef") + + def test_read1(self): + # .read1() is delegated to the underlying reader object, so this test + # can be shallow. + pair = self.tp(self.BytesIO(b"abcdef"), self.MockRawIO()) + + self.assertEqual(pair.read1(3), b"abc") + + def test_readinto(self): + pair = self.tp(self.BytesIO(b"abcdef"), self.MockRawIO()) + + data = bytearray(5) + self.assertEqual(pair.readinto(data), 5) + self.assertEqual(data, b"abcde") + + def test_write(self): + w = self.MockRawIO() + pair = self.tp(self.MockRawIO(), w) + + pair.write(b"abc") + pair.flush() + pair.write(b"def") + pair.flush() + self.assertEqual(w._write_stack, [b"abc", b"def"]) + + def test_peek(self): + pair = self.tp(self.BytesIO(b"abcdef"), self.MockRawIO()) + + self.assertTrue(pair.peek(3).startswith(b"abc")) + self.assertEqual(pair.read(3), b"abc") + + def test_readable(self): + pair = self.tp(self.MockRawIO(), self.MockRawIO()) + self.assertTrue(pair.readable()) + + def test_writeable(self): + pair = self.tp(self.MockRawIO(), self.MockRawIO()) + self.assertTrue(pair.writable()) + + def test_seekable(self): + # BufferedRWPairs are never seekable, even if their readers and writers + # are. + pair = self.tp(self.MockRawIO(), self.MockRawIO()) + self.assertFalse(pair.seekable()) + + # .flush() is delegated to the underlying writer object and has been + # tested in the test_write method. + + def test_close_and_closed(self): + pair = self.tp(self.MockRawIO(), self.MockRawIO()) + self.assertFalse(pair.closed) + pair.close() + self.assertTrue(pair.closed) + + def test_isatty(self): + class SelectableIsAtty(MockRawIO): + def __init__(self, isatty): + MockRawIO.__init__(self) + self._isatty = isatty + + def isatty(self): + return self._isatty + + pair = self.tp(SelectableIsAtty(False), SelectableIsAtty(False)) + self.assertFalse(pair.isatty()) + + pair = self.tp(SelectableIsAtty(True), SelectableIsAtty(False)) + self.assertTrue(pair.isatty()) + + pair = self.tp(SelectableIsAtty(False), SelectableIsAtty(True)) + self.assertTrue(pair.isatty()) + + pair = self.tp(SelectableIsAtty(True), SelectableIsAtty(True)) + self.assertTrue(pair.isatty()) class CBufferedRWPairTest(BufferedRWPairTest): tp = io.BufferedRWPair Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Apr 19 02:09:36 2009 @@ -72,6 +72,9 @@ Library ------- +- Issue #5734: BufferedRWPair was poorly tested and had several glaring + bugs. Patch by Brian Quinlan. + - Issue #1161031: fix readwrite select flag handling: POLLPRI now results in a handle_expt_event call, not handle_read_event, and POLLERR and POLLNVAL now call handle_close, not handle_expt_event. Also, Modified: python/branches/py3k/Modules/_io/bufferedio.c ============================================================================== --- python/branches/py3k/Modules/_io/bufferedio.c (original) +++ python/branches/py3k/Modules/_io/bufferedio.c Sun Apr 19 02:09:36 2009 @@ -1846,7 +1846,7 @@ static int BufferedRWPair_init(BufferedRWPairObject *self, PyObject *args, - PyObject *kwds) + PyObject *kwds) { PyObject *reader, *writer; Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; @@ -1865,29 +1865,18 @@ if (_PyIOBase_checkWritable(writer, Py_True) == NULL) return -1; - args = Py_BuildValue("(n)", buffer_size); - if (args == NULL) { - Py_CLEAR(self->reader); - return -1; - } - self->reader = (BufferedObject *)PyType_GenericNew( - &PyBufferedReader_Type, args, NULL); - Py_DECREF(args); + self->reader = (BufferedObject *) PyObject_CallFunction( + (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size); if (self->reader == NULL) return -1; - args = Py_BuildValue("(n)", buffer_size); - if (args == NULL) { - Py_CLEAR(self->reader); - return -1; - } - self->writer = (BufferedObject *)PyType_GenericNew( - &PyBufferedWriter_Type, args, NULL); - Py_DECREF(args); + self->writer = (BufferedObject *) PyObject_CallFunction( + (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size); if (self->writer == NULL) { Py_CLEAR(self->reader); return -1; } + return 0; } @@ -1952,6 +1941,12 @@ } static PyObject * +BufferedRWPair_readinto(BufferedRWPairObject *self, PyObject *args) +{ + return _forward_call(self->reader, "readinto", args); +} + +static PyObject * BufferedRWPair_write(BufferedRWPairObject *self, PyObject *args) { return _forward_call(self->writer, "write", args); @@ -2000,12 +1995,17 @@ return _forward_call(self->reader, "isatty", args); } +static PyObject * +BufferedRWPair_closed_get(BufferedRWPairObject *self, void *context) +{ + return PyObject_GetAttr((PyObject *) self->writer, _PyIO_str_closed); +} static PyMethodDef BufferedRWPair_methods[] = { {"read", (PyCFunction)BufferedRWPair_read, METH_VARARGS}, {"peek", (PyCFunction)BufferedRWPair_peek, METH_VARARGS}, {"read1", (PyCFunction)BufferedRWPair_read1, METH_VARARGS}, - {"readinto", (PyCFunction)Buffered_readinto, METH_VARARGS}, + {"readinto", (PyCFunction)BufferedRWPair_readinto, METH_VARARGS}, {"write", (PyCFunction)BufferedRWPair_write, METH_VARARGS}, {"flush", (PyCFunction)BufferedRWPair_flush, METH_NOARGS}, @@ -2019,6 +2019,11 @@ {NULL, NULL} }; +static PyGetSetDef BufferedRWPair_getset[] = { + {"closed", (getter)BufferedRWPair_closed_get, NULL, NULL}, + {0} +}; + PyTypeObject PyBufferedRWPair_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_io.BufferedRWPair", /*tp_name*/ @@ -2050,7 +2055,7 @@ 0, /* tp_iternext */ BufferedRWPair_methods, /* tp_methods */ 0, /* tp_members */ - 0, /* tp_getset */ + BufferedRWPair_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ From python-checkins at python.org Sun Apr 19 02:10:36 2009 From: python-checkins at python.org (antoine.pitrou) Date: Sun, 19 Apr 2009 02:10:36 +0200 (CEST) Subject: [Python-checkins] r71737 - python/branches/py3k/Lib/test/test_io.py Message-ID: <20090419001036.61AF91E402F@bag.python.org> Author: antoine.pitrou Date: Sun Apr 19 02:10:36 2009 New Revision: 71737 Log: Fix use of test skipping API. Modified: python/branches/py3k/Lib/test/test_io.py 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 Sun Apr 19 02:10:36 2009 @@ -509,11 +509,11 @@ # Issue #1174606: reading from an unbounded stream such as /dev/zero. zero = "/dev/zero" if not os.path.exists(zero): - self.skip("{0} does not exist".format(zero)) + self.skipTest("{0} does not exist".format(zero)) if sys.maxsize > 0x7FFFFFFF: - self.skip("test can only run in a 32-bit address space") + self.skipTest("test can only run in a 32-bit address space") if support.real_max_memuse < support._2G: - self.skip("test requires at least 2GB of memory") + self.skipTest("test requires at least 2GB of memory") with open(zero, "rb", buffering=0) as f: self.assertRaises(OverflowError, f.read) with open(zero, "rb") as f: From python-checkins at python.org Sun Apr 19 04:32:42 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 19 Apr 2009 04:32:42 +0200 (CEST) Subject: [Python-checkins] r71738 - python/trunk/Objects/object.c Message-ID: <20090419023242.97A431E402F@bag.python.org> Author: benjamin.peterson Date: Sun Apr 19 04:32:42 2009 New Revision: 71738 Log: initialize weakref some weakref types Modified: python/trunk/Objects/object.c Modified: python/trunk/Objects/object.c ============================================================================== --- python/trunk/Objects/object.c (original) +++ python/trunk/Objects/object.c Sun Apr 19 04:32:42 2009 @@ -2039,6 +2039,12 @@ if (PyType_Ready(&_PyWeakref_RefType) < 0) Py_FatalError("Can't initialize weakref type"); + if (PyType_Ready(&_PyWeakref_CallableProxyType) < 0) + Py_FatalError("Can't initialize callable weakref proxy type"); + + if (PyType_Ready(&_PyWeakref_ProxyType) < 0) + Py_FatalError("Can't initialize weakref proxy type"); + if (PyType_Ready(&PyBool_Type) < 0) Py_FatalError("Can't initialize bool type"); From python-checkins at python.org Sun Apr 19 04:40:43 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 19 Apr 2009 04:40:43 +0200 (CEST) Subject: [Python-checkins] r71739 - python/trunk/Objects/object.c Message-ID: <20090419024044.002701E402F@bag.python.org> Author: benjamin.peterson Date: Sun Apr 19 04:40:43 2009 New Revision: 71739 Log: make errors consistent Modified: python/trunk/Objects/object.c Modified: python/trunk/Objects/object.c ============================================================================== --- python/trunk/Objects/object.c (original) +++ python/trunk/Objects/object.c Sun Apr 19 04:40:43 2009 @@ -2052,10 +2052,10 @@ Py_FatalError("Can't initialize str type"); if (PyType_Ready(&PyByteArray_Type) < 0) - Py_FatalError("Can't initialize bytearray"); + Py_FatalError("Can't initialize bytearray type"); if (PyType_Ready(&PyList_Type) < 0) - Py_FatalError("Can't initialize list"); + Py_FatalError("Can't initialize list type"); if (PyType_Ready(&PyNone_Type) < 0) Py_FatalError("Can't initialize None type"); From benjamin at python.org Sun Apr 19 04:40:48 2009 From: benjamin at python.org (Benjamin Peterson) Date: Sat, 18 Apr 2009 21:40:48 -0500 Subject: [Python-checkins] r71722 - in python/trunk: Lib/test/test_descr.py Misc/NEWS Objects/frameobject.c Objects/object.c In-Reply-To: <49EA61A0.4070603@gmail.com> References: <20090418201247.8F2761E4160@bag.python.org> <49EA61A0.4070603@gmail.com> Message-ID: <1afaf6160904181940g6adce9ccnc06c898d073de39e@mail.gmail.com> 2009/4/18, Nick Coghlan : > Very minor nit - the trailing " type" is missing from these two error > messages. Well, hopefully no one will every see these messages, but fixed none the less. :) -- Regards, Benjamin From python-checkins at python.org Sun Apr 19 05:02:54 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 19 Apr 2009 05:02:54 +0200 (CEST) Subject: [Python-checkins] r71740 - python/trunk/Makefile.pre.in Message-ID: <20090419030254.B07F61E402F@bag.python.org> Author: benjamin.peterson Date: Sun Apr 19 05:02:54 2009 New Revision: 71740 Log: fix typo Modified: python/trunk/Makefile.pre.in Modified: python/trunk/Makefile.pre.in ============================================================================== --- python/trunk/Makefile.pre.in (original) +++ python/trunk/Makefile.pre.in Sun Apr 19 05:02:54 2009 @@ -827,7 +827,7 @@ sqlite3 sqlite3/test \ logging bsddb bsddb/test csv importlib wsgiref \ lib2to3 lib2to3/fixes lib2to3/pgen2 lib2to3/tests \ - lib2to3/tests/data lib2to3/tests/data/fixes lib2to3/tests/data/fixers/myfixes \ + lib2to3/tests/data lib2to3/tests/data/fixers lib2to3/tests/data/fixers/myfixes \ ctypes ctypes/test ctypes/macholib idlelib idlelib/Icons \ distutils distutils/command distutils/tests $(XMLLIBSUBDIRS) \ multiprocessing multiprocessing/dummy \ From python-checkins at python.org Sun Apr 19 05:14:50 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 19 Apr 2009 05:14:50 +0200 (CEST) Subject: [Python-checkins] r71741 - python/branches/py3k/Makefile.pre.in Message-ID: <20090419031450.8D2611E402F@bag.python.org> Author: benjamin.peterson Date: Sun Apr 19 05:14:50 2009 New Revision: 71741 Log: make python3 alias in altbininstall 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 Sun Apr 19 05:14:50 2009 @@ -789,7 +789,6 @@ then rm -f $(DESTDIR)$(BINDIR)/$(PYTHON); \ else true; \ fi - (cd $(DESTDIR)$(BINDIR); $(LN) python$(VERSION)$(EXE) $(PYTHON)3) -rm -f $(DESTDIR)$(BINDIR)/python-config (cd $(DESTDIR)$(BINDIR); $(LN) -s python$(VERSION)-config python-config) @@ -816,6 +815,7 @@ fi; \ else true; \ fi + (cd $(DESTDIR)$(BINDIR); $(LN) python$(VERSION)$(EXE) $(PYTHON)3) # Install the manual page maninstall: From python-checkins at python.org Sun Apr 19 05:15:21 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 19 Apr 2009 05:15:21 +0200 (CEST) Subject: [Python-checkins] r71742 - in python/branches/py3k/Modules/_io: bufferedio.c bytesio.c fileio.c iobase.c stringio.c textio.c Message-ID: <20090419031521.09AA51E402F@bag.python.org> Author: benjamin.peterson Date: Sun Apr 19 05:15:20 2009 New Revision: 71742 Log: use NULL for the ends of tables Modified: python/branches/py3k/Modules/_io/bufferedio.c python/branches/py3k/Modules/_io/bytesio.c python/branches/py3k/Modules/_io/fileio.c python/branches/py3k/Modules/_io/iobase.c python/branches/py3k/Modules/_io/stringio.c python/branches/py3k/Modules/_io/textio.c Modified: python/branches/py3k/Modules/_io/bufferedio.c ============================================================================== --- python/branches/py3k/Modules/_io/bufferedio.c (original) +++ python/branches/py3k/Modules/_io/bufferedio.c Sun Apr 19 05:15:20 2009 @@ -1414,7 +1414,7 @@ {"closed", (getter)BufferedIOMixin_closed_get, NULL, NULL}, {"name", (getter)BufferedIOMixin_name_get, NULL, NULL}, {"mode", (getter)BufferedIOMixin_mode_get, NULL, NULL}, - {0} + {NULL} }; @@ -1768,7 +1768,7 @@ {"closed", (getter)BufferedIOMixin_closed_get, NULL, NULL}, {"name", (getter)BufferedIOMixin_name_get, NULL, NULL}, {"mode", (getter)BufferedIOMixin_mode_get, NULL, NULL}, - {0} + {NULL} }; @@ -2021,7 +2021,7 @@ static PyGetSetDef BufferedRWPair_getset[] = { {"closed", (getter)BufferedRWPair_closed_get, NULL, NULL}, - {0} + {NULL} }; PyTypeObject PyBufferedRWPair_Type = { @@ -2157,7 +2157,7 @@ {"closed", (getter)BufferedIOMixin_closed_get, NULL, NULL}, {"name", (getter)BufferedIOMixin_name_get, NULL, NULL}, {"mode", (getter)BufferedIOMixin_mode_get, NULL, NULL}, - {0} + {NULL} }; Modified: python/branches/py3k/Modules/_io/bytesio.c ============================================================================== --- python/branches/py3k/Modules/_io/bytesio.c (original) +++ python/branches/py3k/Modules/_io/bytesio.c Sun Apr 19 05:15:20 2009 @@ -684,7 +684,7 @@ static PyGetSetDef bytesio_getsetlist[] = { {"closed", (getter)bytesio_get_closed, NULL, "True if the file is closed."}, - {0}, /* sentinel */ + {NULL}, /* sentinel */ }; static struct PyMethodDef bytesio_methods[] = { Modified: python/branches/py3k/Modules/_io/fileio.c ============================================================================== --- python/branches/py3k/Modules/_io/fileio.c (original) +++ python/branches/py3k/Modules/_io/fileio.c Sun Apr 19 05:15:20 2009 @@ -987,7 +987,7 @@ {"closefd", (getter)get_closefd, NULL, "True if the file descriptor will be closed"}, {"mode", (getter)get_mode, NULL, "String giving the file mode"}, - {0}, + {NULL}, }; PyTypeObject PyFileIO_Type = { Modified: python/branches/py3k/Modules/_io/iobase.c ============================================================================== --- python/branches/py3k/Modules/_io/iobase.c (original) +++ python/branches/py3k/Modules/_io/iobase.c Sun Apr 19 05:15:20 2009 @@ -700,7 +700,7 @@ static PyGetSetDef IOBase_getset[] = { {"closed", (getter)IOBase_closed_get, NULL, NULL}, - {0} + {NULL} }; Modified: python/branches/py3k/Modules/_io/stringio.c ============================================================================== --- python/branches/py3k/Modules/_io/stringio.c (original) +++ python/branches/py3k/Modules/_io/stringio.c Sun Apr 19 05:15:20 2009 @@ -723,7 +723,7 @@ {"encoding", (getter)stringio_encoding, NULL, NULL}, {"errors", (getter)stringio_errors, NULL, NULL}, {"line_buffering", (getter)stringio_line_buffering, NULL, NULL}, - {0} + {NULL} }; PyTypeObject PyStringIO_Type = { Modified: python/branches/py3k/Modules/_io/textio.c ============================================================================== --- python/branches/py3k/Modules/_io/textio.c (original) +++ python/branches/py3k/Modules/_io/textio.c Sun Apr 19 05:15:20 2009 @@ -102,7 +102,7 @@ static PyGetSetDef TextIOBase_getset[] = { {"encoding", (getter)TextIOBase_encoding_get, NULL, TextIOBase_encoding_doc}, {"newlines", (getter)TextIOBase_newlines_get, NULL, TextIOBase_newlines_doc}, - {0} + {NULL} }; PyTypeObject PyTextIOBase_Type = { @@ -534,12 +534,12 @@ {"getstate", (PyCFunction)IncrementalNewlineDecoder_getstate, METH_NOARGS}, {"setstate", (PyCFunction)IncrementalNewlineDecoder_setstate, METH_O}, {"reset", (PyCFunction)IncrementalNewlineDecoder_reset, METH_NOARGS}, - {0} + {NULL} }; static PyGetSetDef IncrementalNewlineDecoder_getset[] = { {"newlines", (getter)IncrementalNewlineDecoder_newlines_get, NULL, NULL}, - {0} + {NULL} }; PyTypeObject PyIncrementalNewlineDecoder_Type = { @@ -2374,7 +2374,7 @@ {"newlines", (getter)TextIOWrapper_newlines_get, NULL, NULL}, {"_CHUNK_SIZE", (getter)TextIOWrapper_chunk_size_get, (setter)TextIOWrapper_chunk_size_set, NULL}, - {0} + {NULL} }; PyTypeObject PyTextIOWrapper_Type = { From buildbot at python.org Sun Apr 19 05:39:41 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 19 Apr 2009 03:39:41 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu trunk Message-ID: <20090419033941.677301E403E@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%20trunk/builds/1252 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: benjamin.peterson BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Sun Apr 19 12:38:20 2009 From: python-checkins at python.org (ronald.oussoren) Date: Sun, 19 Apr 2009 12:38:20 +0200 (CEST) Subject: [Python-checkins] r71743 - python/trunk/Include/pymacconfig.h Message-ID: <20090419103820.3FAF21E403E@bag.python.org> Author: ronald.oussoren Date: Sun Apr 19 12:38:20 2009 New Revision: 71743 Log: Fix for issue5657. Modified: python/trunk/Include/pymacconfig.h Modified: python/trunk/Include/pymacconfig.h ============================================================================== --- python/trunk/Include/pymacconfig.h (original) +++ python/trunk/Include/pymacconfig.h Sun Apr 19 12:38:20 2009 @@ -67,6 +67,18 @@ #define WORDS_BIGENDIAN 1 #endif /* __BIG_ENDIAN */ + /* + * The definition in pyconfig.h is only valid on the OS release + * where configure ran on and not necessarily for all systems where + * the executable can be used on. + * + * Specifically: OSX 10.4 has limited supported for '%zd', while + * 10.5 has full support for '%zd'. A binary built on 10.5 won't + * work properly on 10.4 unless we surpress the definition + * of PY_FORMAT_SIZE_T + */ +#undef PY_FORMAT_SIZE_T + #endif /* defined(_APPLE__) */ From python-checkins at python.org Sun Apr 19 12:39:21 2009 From: python-checkins at python.org (ronald.oussoren) Date: Sun, 19 Apr 2009 12:39:21 +0200 (CEST) Subject: [Python-checkins] r71744 - in python/branches/release26-maint: Include/pymacconfig.h Message-ID: <20090419103921.4B7921E403E@bag.python.org> Author: ronald.oussoren Date: Sun Apr 19 12:39:21 2009 New Revision: 71744 Log: Merged revisions 71743 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71743 | ronald.oussoren | 2009-04-19 12:38:20 +0200 (Sun, 19 Apr 2009) | 2 lines Fix for issue5657. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Include/pymacconfig.h Modified: python/branches/release26-maint/Include/pymacconfig.h ============================================================================== --- python/branches/release26-maint/Include/pymacconfig.h (original) +++ python/branches/release26-maint/Include/pymacconfig.h Sun Apr 19 12:39:21 2009 @@ -67,6 +67,18 @@ #define WORDS_BIGENDIAN 1 #endif /* __BIG_ENDIAN */ + /* + * The definition in pyconfig.h is only valid on the OS release + * where configure ran on and not necessarily for all systems where + * the executable can be used on. + * + * Specifically: OSX 10.4 has limited supported for '%zd', while + * 10.5 has full support for '%zd'. A binary built on 10.5 won't + * work properly on 10.4 unless we surpress the definition + * of PY_FORMAT_SIZE_T + */ +#undef PY_FORMAT_SIZE_T + #endif /* defined(_APPLE__) */ From python-checkins at python.org Sun Apr 19 12:40:48 2009 From: python-checkins at python.org (ronald.oussoren) Date: Sun, 19 Apr 2009 12:40:48 +0200 (CEST) Subject: [Python-checkins] r71745 - in python/branches/py3k: Include/pymacconfig.h Message-ID: <20090419104048.5FEAF1E403E@bag.python.org> Author: ronald.oussoren Date: Sun Apr 19 12:40:48 2009 New Revision: 71745 Log: Merged revisions 71743 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71743 | ronald.oussoren | 2009-04-19 12:38:20 +0200 (Sun, 19 Apr 2009) | 2 lines Fix for issue5657. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Include/pymacconfig.h Modified: python/branches/py3k/Include/pymacconfig.h ============================================================================== --- python/branches/py3k/Include/pymacconfig.h (original) +++ python/branches/py3k/Include/pymacconfig.h Sun Apr 19 12:40:48 2009 @@ -73,6 +73,18 @@ #define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 #endif /* __BIG_ENDIAN */ + /* + * The definition in pyconfig.h is only valid on the OS release + * where configure ran on and not necessarily for all systems where + * the executable can be used on. + * + * Specifically: OSX 10.4 has limited supported for '%zd', while + * 10.5 has full support for '%zd'. A binary built on 10.5 won't + * work properly on 10.4 unless we surpress the definition + * of PY_FORMAT_SIZE_T + */ +#undef PY_FORMAT_SIZE_T + #endif /* defined(_APPLE__) */ From python-checkins at python.org Sun Apr 19 12:41:42 2009 From: python-checkins at python.org (ronald.oussoren) Date: Sun, 19 Apr 2009 12:41:42 +0200 (CEST) Subject: [Python-checkins] r71746 - in python/branches/release30-maint: Include/pymacconfig.h Message-ID: <20090419104142.B12D21E403E@bag.python.org> Author: ronald.oussoren Date: Sun Apr 19 12:41:42 2009 New Revision: 71746 Log: Merged revisions 71745 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71745 | ronald.oussoren | 2009-04-19 12:40:48 +0200 (Sun, 19 Apr 2009) | 9 lines Merged revisions 71743 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71743 | ronald.oussoren | 2009-04-19 12:38:20 +0200 (Sun, 19 Apr 2009) | 2 lines Fix for issue5657. ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Include/pymacconfig.h Modified: python/branches/release30-maint/Include/pymacconfig.h ============================================================================== --- python/branches/release30-maint/Include/pymacconfig.h (original) +++ python/branches/release30-maint/Include/pymacconfig.h Sun Apr 19 12:41:42 2009 @@ -67,6 +67,18 @@ #define WORDS_BIGENDIAN 1 #endif /* __BIG_ENDIAN */ + /* + * The definition in pyconfig.h is only valid on the OS release + * where configure ran on and not necessarily for all systems where + * the executable can be used on. + * + * Specifically: OSX 10.4 has limited supported for '%zd', while + * 10.5 has full support for '%zd'. A binary built on 10.5 won't + * work properly on 10.4 unless we surpress the definition + * of PY_FORMAT_SIZE_T + */ +#undef PY_FORMAT_SIZE_T + #endif /* defined(_APPLE__) */ From python-checkins at python.org Sun Apr 19 13:35:56 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 19 Apr 2009 13:35:56 +0200 (CEST) Subject: [Python-checkins] r71747 - python/branches/py3k/Include/pyport.h Message-ID: <20090419113556.4E6921E40AD@bag.python.org> Author: mark.dickinson Date: Sun Apr 19 13:35:55 2009 New Revision: 71747 Log: Add comments to pyport.h explaining how to enable support for short float repr on platforms that don't currently support it, and reorganize the defines slightly to make adding support easier. Modified: python/branches/py3k/Include/pyport.h Modified: python/branches/py3k/Include/pyport.h ============================================================================== --- python/branches/py3k/Include/pyport.h (original) +++ python/branches/py3k/Include/pyport.h Sun Apr 19 13:35:55 2009 @@ -465,11 +465,33 @@ errno = 0; \ } while(0) -/* The functions _Py_dg_strtod and _Py_dg_dtoa in Python/dtoa.c require that - the FPU is using 53-bit precision. Here are macros that force this. See - Python/pystrtod.c for an example of their use. */ +/* The functions _Py_dg_strtod and _Py_dg_dtoa in Python/dtoa.c (which are + * required to support the short float repr introduced in Python 3.1) require + * that the floating-point unit that's being used for arithmetic operations + * on C doubles is set to use 53-bit precision. It also requires that the + * FPU rounding mode is round-half-to-even, but that's less often an issue. + * + * If your FPU isn't already set to 53-bit precision/round-half-to-even, and + * you want to make use of _Py_dg_strtod and _Py_dg_dtoa, then you should + * + * #define HAVE_PY_SET_53BIT_PRECISION 1 + * + * and also give appropriate definitions for the following three macros: + * + * _PY_SET_53BIT_PRECISION_START : store original FPU settings, and + * set FPU to 53-bit precision/round-half-to-even + * _PY_SET_53BIT_PRECISION_END : restore original FPU settings + * _PY_SET_53BIT_PRECISION_HEADER : any variable declarations needed to + * use the two macros above. + * + * The macros are designed to be used within a single C function: see + * Python/pystrtod.c for an example of their use. + */ +/* get and set x87 control word for gcc/x86 */ #ifdef HAVE_GCC_ASM_FOR_X87 +#define HAVE_PY_SET_53BIT_PRECISION 1 +/* _Py_get/set_387controlword functions are defined in Python/pymath.c */ #define _Py_SET_53BIT_PRECISION_HEADER \ unsigned short old_387controlword, new_387controlword #define _Py_SET_53BIT_PRECISION_START \ @@ -482,7 +504,10 @@ #define _Py_SET_53BIT_PRECISION_END \ if (new_387controlword != old_387controlword) \ _Py_set_387controlword(old_387controlword) -#else +#endif + +/* default definitions are empty */ +#ifndef HAVE_PY_SET_53BIT_PRECISION #define _Py_SET_53BIT_PRECISION_HEADER #define _Py_SET_53BIT_PRECISION_START #define _Py_SET_53BIT_PRECISION_END @@ -509,7 +534,7 @@ /* double rounding is symptomatic of use of extended precision on x86. If we're seeing double rounding, and we don't have any mechanism available for changing the FPU rounding precision, then don't use Python/dtoa.c. */ -#if defined(X87_DOUBLE_ROUNDING) && !defined(HAVE_GCC_ASM_FOR_X87) +#if defined(X87_DOUBLE_ROUNDING) && !defined(HAVE_PY_SET_53BIT_PRECISION) #define PY_NO_SHORT_FLOAT_REPR #endif From python-checkins at python.org Sun Apr 19 13:38:04 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 19 Apr 2009 13:38:04 +0200 (CEST) Subject: [Python-checkins] r71748 - python/branches/release30-maint Message-ID: <20090419113804.5DD731E4059@bag.python.org> Author: mark.dickinson Date: Sun Apr 19 13:38:03 2009 New Revision: 71748 Log: Blocked revisions 71747 via svnmerge ........ r71747 | mark.dickinson | 2009-04-19 12:35:55 +0100 (Sun, 19 Apr 2009) | 4 lines Add comments to pyport.h explaining how to enable support for short float repr on platforms that don't currently support it, and reorganize the defines slightly to make adding support easier. ........ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sun Apr 19 13:47:47 2009 From: python-checkins at python.org (hirokazu.yamamoto) Date: Sun, 19 Apr 2009 13:47:47 +0200 (CEST) Subject: [Python-checkins] r71749 - python/branches/release30-maint Message-ID: <20090419114747.310EA1E403E@bag.python.org> Author: hirokazu.yamamoto Date: Sun Apr 19 13:47:46 2009 New Revision: 71749 Log: Blocked revisions 71703 via svnmerge ........ r71703 | hirokazu.yamamoto | 2009-04-18 22:10:51 +0900 | 1 line Added Python/dtoa.c to project files. ........ Modified: python/branches/release30-maint/ (props changed) From buildbot at python.org Sun Apr 19 17:00:18 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 19 Apr 2009 15:00:18 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090419150018.D231E1E4016@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/280 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: ronald.oussoren BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Sun Apr 19 19:10:47 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 19 Apr 2009 19:10:47 +0200 (CEST) Subject: [Python-checkins] r71750 - python/trunk/Lib/compileall.py Message-ID: <20090419171047.C5EDC1E4012@bag.python.org> Author: mark.dickinson Date: Sun Apr 19 19:10:47 2009 New Revision: 71750 Log: Automatic conversion of floats to integers for struct.pack integer codes is deprecated. Use an explicit int() instead. Modified: python/trunk/Lib/compileall.py Modified: python/trunk/Lib/compileall.py ============================================================================== --- python/trunk/Lib/compileall.py (original) +++ python/trunk/Lib/compileall.py Sun Apr 19 19:10:47 2009 @@ -57,7 +57,7 @@ if tail == '.py': if not force: try: - mtime = os.stat(fullname).st_mtime + mtime = int(os.stat(fullname).st_mtime) expect = struct.pack('<4sl', imp.get_magic(), mtime) cfile = fullname + (__debug__ and 'c' or 'o') with open(cfile, 'rb') as chandle: From python-checkins at python.org Sun Apr 19 19:12:41 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 19 Apr 2009 19:12:41 +0200 (CEST) Subject: [Python-checkins] r71751 - python/branches/release26-maint Message-ID: <20090419171241.CE8E31E4012@bag.python.org> Author: mark.dickinson Date: Sun Apr 19 19:12:41 2009 New Revision: 71751 Log: Blocked revisions 71750 via svnmerge ........ r71750 | mark.dickinson | 2009-04-19 18:10:47 +0100 (Sun, 19 Apr 2009) | 3 lines Automatic conversion of floats to integers for struct.pack integer codes is deprecated. Use an explicit int() instead. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Apr 19 19:14:11 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 19 Apr 2009 19:14:11 +0200 (CEST) Subject: [Python-checkins] r71752 - in python/branches/py3k: Lib/compileall.py Message-ID: <20090419171411.8E06F1E401C@bag.python.org> Author: mark.dickinson Date: Sun Apr 19 19:14:11 2009 New Revision: 71752 Log: Merged revisions 71750 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71750 | mark.dickinson | 2009-04-19 18:10:47 +0100 (Sun, 19 Apr 2009) | 3 lines Automatic conversion of floats to integers for struct.pack integer codes is deprecated. Use an explicit int() instead. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/compileall.py Modified: python/branches/py3k/Lib/compileall.py ============================================================================== --- python/branches/py3k/Lib/compileall.py (original) +++ python/branches/py3k/Lib/compileall.py Sun Apr 19 19:14:11 2009 @@ -57,7 +57,7 @@ if tail == '.py': if not force: try: - mtime = os.stat(fullname).st_mtime + mtime = int(os.stat(fullname).st_mtime) expect = struct.pack('<4sl', imp.get_magic(), mtime) cfile = fullname + (__debug__ and 'c' or 'o') with open(cfile, 'rb') as chandle: From python-checkins at python.org Sun Apr 19 19:14:55 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 19 Apr 2009 19:14:55 +0200 (CEST) Subject: [Python-checkins] r71753 - python/branches/release30-maint Message-ID: <20090419171455.3CEE31E4029@bag.python.org> Author: mark.dickinson Date: Sun Apr 19 19:14:54 2009 New Revision: 71753 Log: Blocked revisions 71752 via svnmerge ................ r71752 | mark.dickinson | 2009-04-19 18:14:11 +0100 (Sun, 19 Apr 2009) | 10 lines Merged revisions 71750 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71750 | mark.dickinson | 2009-04-19 18:10:47 +0100 (Sun, 19 Apr 2009) | 3 lines Automatic conversion of floats to integers for struct.pack integer codes is deprecated. Use an explicit int() instead. ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sun Apr 19 22:40:34 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 19 Apr 2009 22:40:34 +0200 (CEST) Subject: [Python-checkins] r71754 - in python/branches/py3k: Lib/test/test_struct.py Misc/NEWS Modules/_struct.c Message-ID: <20090419204034.579A51E401E@bag.python.org> Author: mark.dickinson Date: Sun Apr 19 22:40:33 2009 New Revision: 71754 Log: Issue #5463: Remove deprecated float coercion from struct module, along with the _PY_STRUCT_FLOAT_COERCE constant. Simplify tests accordingly, and reenable (now-fixed) broken tests. Modified: python/branches/py3k/Lib/test/test_struct.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_struct.c Modified: python/branches/py3k/Lib/test/test_struct.py ============================================================================== --- python/branches/py3k/Lib/test/test_struct.py (original) +++ python/branches/py3k/Lib/test/test_struct.py Sun Apr 19 22:40:33 2009 @@ -11,13 +11,6 @@ IS32BIT = sys.maxsize == 0x7fffffff del sys -try: - import _struct -except ImportError: - PY_STRUCT_FLOAT_COERCE = 2 -else: - PY_STRUCT_FLOAT_COERCE = getattr(_struct, '_PY_STRUCT_FLOAT_COERCE', 0) - def string_reverse(s): return s[::-1] @@ -27,40 +20,7 @@ else: return string_reverse(value) -def with_warning_restore(func): - @wraps(func) - def decorator(*args, **kw): - with warnings.catch_warnings(): - # We need this function to warn every time, so stick an - # unqualifed 'always' at the head of the filter list - warnings.simplefilter("always") - warnings.filterwarnings("error", category=DeprecationWarning) - return func(*args, **kw) - return decorator - class StructTest(unittest.TestCase): - - @with_warning_restore - def check_float_coerce(self, format, number): - # SF bug 1530559. struct.pack raises TypeError where it used to convert. - if PY_STRUCT_FLOAT_COERCE == 2: - # Test for pre-2.5 struct module - packed = struct.pack(format, number) - floored = struct.unpack(format, packed)[0] - self.assertEqual(floored, int(number), - "did not correcly coerce float to int") - return - try: - struct.pack(format, number) - except (struct.error, TypeError): - if PY_STRUCT_FLOAT_COERCE: - self.fail("expected DeprecationWarning for float coerce") - except DeprecationWarning: - if not PY_STRUCT_FLOAT_COERCE: - self.fail("expected to raise struct.error for float coerce") - else: - self.fail("did not raise error for float coerce") - def test_isbigendian(self): self.assertEqual((struct.pack('=i', 1)[0] == 0), ISBIGENDIAN) @@ -270,10 +230,8 @@ else: # x is out of range -- verify pack realizes that. - self.assertRaises((struct.error, OverflowError), - pack, ">" + code, x) - self.assertRaises((struct.error, OverflowError), - pack, "<" + code, x) + self.assertRaises(struct.error, pack, ">" + code, x) + self.assertRaises(struct.error, pack, "<" + code, x) # Much the same for unsigned. code = self.unsigned_code @@ -317,10 +275,8 @@ else: # x is out of range -- verify pack realizes that. - self.assertRaises((struct.error, OverflowError), - pack, ">" + code, x) - self.assertRaises((struct.error, OverflowError), - pack, "<" + code, x) + self.assertRaises(struct.error, pack, ">" + code, x) + self.assertRaises(struct.error, pack, "<" + code, x) def run(self): from random import randrange @@ -353,10 +309,10 @@ # Some error cases. for direction in "<>": for code in self.formatpair: - for badobject in "a string", 3+42j, randrange: - self.assertRaises((struct.error, TypeError), - struct.pack, direction + code, - badobject) + for badobject in "a string", 3+42j, randrange, -1729.0: + self.assertRaises(struct.error, + struct.pack, direction + code, + badobject) for args in [("bB", 1), ("hH", 2), @@ -437,13 +393,14 @@ self.assertRaises((struct.error, OverflowError), struct.pack, endian + 'L', sys.maxsize * 4) - def XXXtest_1530559(self): - # XXX This is broken: see the bug report - # SF bug 1530559. struct.pack raises TypeError where it used to convert. + def test_1530559(self): for endian in ('', '>', '<'): - for fmt in ('B', 'H', 'I', 'L', 'b', 'h', 'i', 'l'): - self.check_float_coerce(endian + fmt, 1.0) - self.check_float_coerce(endian + fmt, 1.5) + for fmt in ('B', 'H', 'I', 'L', 'Q', 'b', 'h', 'i', 'l', 'q'): + self.assertRaises(struct.error, struct.pack, endian + fmt, 1.0) + self.assertRaises(struct.error, struct.pack, endian + fmt, 1.5) + self.assertRaises(struct.error, struct.pack, 'P', 1.0) + self.assertRaises(struct.error, struct.pack, 'P', 1.5) + def test_unpack_from(self): test_string = b'abcd01234' Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Apr 19 22:40:33 2009 @@ -87,6 +87,11 @@ Extension Modules ----------------- +- Issue #5463: In struct module, remove deprecated float coercion + for integer type codes: struct.pack('L', 0.3) should now raise + an error. The _PY_STRUCT_FLOAT_COERCE constant has been removed. + The version number has been bumped to 0.3. + - Issue #5359: Readd the Berkley-DB detection code to allow _dbm be built using Berkley-DB. Modified: python/branches/py3k/Modules/_struct.c ============================================================================== --- python/branches/py3k/Modules/_struct.c (original) +++ python/branches/py3k/Modules/_struct.c Sun Apr 19 22:40:33 2009 @@ -12,17 +12,6 @@ static PyTypeObject PyStructType; -/* If PY_STRUCT_FLOAT_COERCE is defined, the struct module will allow float - arguments for integer formats with a warning for backwards - compatibility. */ - -#define PY_STRUCT_FLOAT_COERCE 1 - -#ifdef PY_STRUCT_FLOAT_COERCE -#define FLOAT_COERCE "integer argument expected, got float" -#endif - - /* The translation function for each format character is table driven */ typedef struct _formatdef { char format; @@ -100,58 +89,40 @@ #pragma options align=reset #endif -/* Helper to get a PyLongObject by hook or by crook. Caller should decref. */ +/* Helper to get a PyLongObject. Caller should decref. */ static PyObject * get_pylong(PyObject *v) { - PyNumberMethods *m; - assert(v != NULL); - if (PyLong_Check(v)) { - Py_INCREF(v); - return v; - } - m = Py_TYPE(v)->tp_as_number; - if (m != NULL && m->nb_int != NULL) { - v = m->nb_int(v); - if (v == NULL) - return NULL; - if (PyLong_Check(v)) - return v; - Py_DECREF(v); + if (!PyLong_Check(v)) { + PyErr_SetString(StructError, + "required argument is not an integer"); + return NULL; } - PyErr_SetString(StructError, - "cannot convert argument to long"); - return NULL; + + Py_INCREF(v); + return v; } -/* Helper routine to get a Python integer and raise the appropriate error - if it isn't one */ +/* Helper routine to get a C long and raise the appropriate error if it isn't + one */ static int get_long(PyObject *v, long *p) { - long x = PyLong_AsLong(v); + long x; + + if (!PyLong_Check(v)) { + PyErr_SetString(StructError, + "required argument is not an integer"); + return -1; + } + x = PyLong_AsLong(v); if (x == -1 && PyErr_Occurred()) { -#ifdef PY_STRUCT_FLOAT_COERCE - if (PyFloat_Check(v)) { - PyObject *o; - int res; - PyErr_Clear(); - if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0) - return -1; - o = PyNumber_Long(v); - if (o == NULL) - return -1; - res = get_long(o, p); - Py_DECREF(o); - return res; - } -#endif - if (PyErr_ExceptionMatches(PyExc_TypeError)) + if (PyErr_ExceptionMatches(PyExc_OverflowError)) PyErr_SetString(StructError, - "required argument is not an integer"); + "argument out of range"); return -1; } *p = x; @@ -164,20 +135,21 @@ static int get_ulong(PyObject *v, unsigned long *p) { - if (PyLong_Check(v)) { - unsigned long x = PyLong_AsUnsignedLong(v); - if (x == (unsigned long)(-1) && PyErr_Occurred()) - return -1; - *p = x; - return 0; - } - if (get_long(v, (long *)p) < 0) - return -1; - if (((long)*p) < 0) { + unsigned long x; + + if (!PyLong_Check(v)) { PyErr_SetString(StructError, - "unsigned argument is < 0"); + "required argument is not an integer"); return -1; } + x = PyLong_AsUnsignedLong(v); + if (x == (unsigned long)-1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + PyErr_SetString(StructError, + "argument out of range"); + return -1; + } + *p = x; return 0; } @@ -189,15 +161,18 @@ get_longlong(PyObject *v, PY_LONG_LONG *p) { PY_LONG_LONG x; - - v = get_pylong(v); - if (v == NULL) + if (!PyLong_Check(v)) { + PyErr_SetString(StructError, + "required argument is not an integer"); return -1; - assert(PyLong_Check(v)); + } x = PyLong_AsLongLong(v); - Py_DECREF(v); - if (x == (PY_LONG_LONG)-1 && PyErr_Occurred()) + if (x == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + PyErr_SetString(StructError, + "argument out of range"); return -1; + } *p = x; return 0; } @@ -208,15 +183,18 @@ get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p) { unsigned PY_LONG_LONG x; - - v = get_pylong(v); - if (v == NULL) + if (!PyLong_Check(v)) { + PyErr_SetString(StructError, + "required argument is not an integer"); return -1; - assert(PyLong_Check(v)); + } x = PyLong_AsUnsignedLongLong(v); - Py_DECREF(v); - if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred()) + if (x == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) + PyErr_SetString(StructError, + "argument out of range"); return -1; + } *p = x; return 0; } @@ -1962,7 +1940,7 @@ { PyObject *ver, *m; - ver = PyBytes_FromString("0.2"); + ver = PyBytes_FromString("0.3"); if (ver == NULL) return NULL; @@ -2028,9 +2006,5 @@ PyModule_AddObject(m, "__version__", ver); -#ifdef PY_STRUCT_FLOAT_COERCE - PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1); -#endif return m; - } From python-checkins at python.org Sun Apr 19 22:41:10 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 19 Apr 2009 22:41:10 +0200 (CEST) Subject: [Python-checkins] r71755 - python/branches/release30-maint Message-ID: <20090419204110.8C3F51E401E@bag.python.org> Author: mark.dickinson Date: Sun Apr 19 22:41:10 2009 New Revision: 71755 Log: Blocked revisions 71754 via svnmerge ........ r71754 | mark.dickinson | 2009-04-19 21:40:33 +0100 (Sun, 19 Apr 2009) | 4 lines Issue #5463: Remove deprecated float coercion from struct module, along with the _PY_STRUCT_FLOAT_COERCE constant. Simplify tests accordingly, and reenable (now-fixed) broken tests. ........ Modified: python/branches/release30-maint/ (props changed) From buildbot at python.org Sun Apr 19 23:21:50 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 19 Apr 2009 21:21:50 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090419212150.B07EB1E401E@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/282 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_posix test_subprocess ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From nnorwitz at gmail.com Sun Apr 19 23:37:44 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 19 Apr 2009 17:37:44 -0400 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20090419213744.GA8412@python.psfb.org> More important issues: ---------------------- test_ssl leaked [0, 322, 0] references, sum=322 Less important issues: ---------------------- test_asynchat leaked [-128, 0, 0] references, sum=-128 test_httpservers leaked [-4, 4, 22] references, sum=22 test_popen2 leaked [-29, 0, 0] references, sum=-29 test_smtplib leaked [92, -81, 81] references, sum=92 test_sys leaked [-21, 21, -21] references, sum=-21 test_threading leaked [48, 48, 48] references, sum=144 test_urllib2_localnet leaked [3, 3, 3] references, sum=9 From buildbot at python.org Sun Apr 19 23:50:49 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 19 Apr 2009 21:50:49 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 3.0 Message-ID: <20090419215049.DE8E71E401E@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%203.0/builds/237 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_smtplib make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 20 04:09:13 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 20 Apr 2009 04:09:13 +0200 (CEST) Subject: [Python-checkins] r71756 - in python/branches/release26-maint: Include/descrobject.h Include/sliceobject.h Objects/descrobject.c Objects/object.c Objects/sliceobject.c Message-ID: <20090420020913.5EFAA1E400C@bag.python.org> Author: benjamin.peterson Date: Mon Apr 20 04:09:13 2009 New Revision: 71756 Log: Merged revisions 71734,71738-71739 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71734 | benjamin.peterson | 2009-04-18 17:15:26 -0500 (Sat, 18 Apr 2009) | 1 line many more types to initialize (I had to expose some of them) ........ r71738 | benjamin.peterson | 2009-04-18 21:32:42 -0500 (Sat, 18 Apr 2009) | 1 line initialize weakref some weakref types ........ r71739 | benjamin.peterson | 2009-04-18 21:40:43 -0500 (Sat, 18 Apr 2009) | 1 line make errors consistent ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Include/descrobject.h python/branches/release26-maint/Include/sliceobject.h python/branches/release26-maint/Objects/descrobject.c python/branches/release26-maint/Objects/object.c python/branches/release26-maint/Objects/sliceobject.c Modified: python/branches/release26-maint/Include/descrobject.h ============================================================================== --- python/branches/release26-maint/Include/descrobject.h (original) +++ python/branches/release26-maint/Include/descrobject.h Mon Apr 20 04:09:13 2009 @@ -68,6 +68,9 @@ } PyWrapperDescrObject; PyAPI_DATA(PyTypeObject) PyWrapperDescr_Type; +PyAPI_DATA(PyTypeObject) PyDictProxy_Type; +PyAPI_DATA(PyTypeObject) PyGetSetDescr_Type; +PyAPI_DATA(PyTypeObject) PyMemberDescr_Type; PyAPI_FUNC(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *); PyAPI_FUNC(PyObject *) PyDescr_NewClassMethod(PyTypeObject *, PyMethodDef *); Modified: python/branches/release26-maint/Include/sliceobject.h ============================================================================== --- python/branches/release26-maint/Include/sliceobject.h (original) +++ python/branches/release26-maint/Include/sliceobject.h Mon Apr 20 04:09:13 2009 @@ -25,6 +25,7 @@ } PySliceObject; PyAPI_DATA(PyTypeObject) PySlice_Type; +PyAPI_DATA(PyTypeObject) PyEllipsis_Type; #define PySlice_Check(op) (Py_TYPE(op) == &PySlice_Type) Modified: python/branches/release26-maint/Objects/descrobject.c ============================================================================== --- python/branches/release26-maint/Objects/descrobject.c (original) +++ python/branches/release26-maint/Objects/descrobject.c Mon Apr 20 04:09:13 2009 @@ -456,7 +456,7 @@ 0, /* tp_descr_set */ }; -static PyTypeObject PyMemberDescr_Type = { +PyTypeObject PyMemberDescr_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "member_descriptor", sizeof(PyMemberDescrObject), @@ -493,7 +493,7 @@ (descrsetfunc)member_set, /* tp_descr_set */ }; -static PyTypeObject PyGetSetDescr_Type = { +PyTypeObject PyGetSetDescr_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "getset_descriptor", sizeof(PyGetSetDescrObject), @@ -819,7 +819,7 @@ return PyObject_RichCompare(v->dict, w, op); } -static PyTypeObject proxytype = { +PyTypeObject PyDictProxy_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "dictproxy", /* tp_name */ sizeof(proxyobject), /* tp_basicsize */ @@ -862,7 +862,7 @@ { proxyobject *pp; - pp = PyObject_GC_New(proxyobject, &proxytype); + pp = PyObject_GC_New(proxyobject, &PyDictProxy_Type); if (pp != NULL) { Py_INCREF(dict); pp->dict = dict; Modified: python/branches/release26-maint/Objects/object.c ============================================================================== --- python/branches/release26-maint/Objects/object.c (original) +++ python/branches/release26-maint/Objects/object.c Mon Apr 20 04:09:13 2009 @@ -2,6 +2,7 @@ /* Generic object operations; and implementation of None (NoObject) */ #include "Python.h" +#include "frameobject.h" #ifdef __cplusplus extern "C" { @@ -2027,6 +2028,12 @@ if (PyType_Ready(&_PyWeakref_RefType) < 0) Py_FatalError("Can't initialize weakref type"); + if (PyType_Ready(&_PyWeakref_CallableProxyType) < 0) + Py_FatalError("Can't initialize callable weakref proxy type"); + + if (PyType_Ready(&_PyWeakref_ProxyType) < 0) + Py_FatalError("Can't initialize weakref proxy type"); + if (PyType_Ready(&PyBool_Type) < 0) Py_FatalError("Can't initialize bool type"); @@ -2034,10 +2041,10 @@ Py_FatalError("Can't initialize str type"); if (PyType_Ready(&PyByteArray_Type) < 0) - Py_FatalError("Can't initialize bytearray"); + Py_FatalError("Can't initialize bytearray type"); if (PyType_Ready(&PyList_Type) < 0) - Py_FatalError("Can't initialize list"); + Py_FatalError("Can't initialize list type"); if (PyType_Ready(&PyNone_Type) < 0) Py_FatalError("Can't initialize None type"); @@ -2072,8 +2079,10 @@ if (PyType_Ready(&PyStaticMethod_Type) < 0) Py_FatalError("Can't initialize static method type"); +#ifndef WITHOUT_COMPLEX if (PyType_Ready(&PyComplex_Type) < 0) - Py_FatalError("Can't initalize complex type"); + Py_FatalError("Can't initialize complex type"); +#endif if (PyType_Ready(&PyFloat_Type) < 0) Py_FatalError("Can't initialize float type"); @@ -2101,6 +2110,45 @@ if (PyType_Ready(&PyReversed_Type) < 0) Py_FatalError("Can't initialize reversed type"); + + if (PyType_Ready(&PyCode_Type) < 0) + Py_FatalError("Can't initialize code type"); + + if (PyType_Ready(&PyFrame_Type) < 0) + Py_FatalError("Can't initialize frame type"); + + if (PyType_Ready(&PyCFunction_Type) < 0) + Py_FatalError("Can't initialize builtin function type"); + + if (PyType_Ready(&PyMethod_Type) < 0) + Py_FatalError("Can't initialize method type"); + + if (PyType_Ready(&PyFunction_Type) < 0) + Py_FatalError("Can't initialize function type"); + + if (PyType_Ready(&PyClass_Type) < 0) + Py_FatalError("Can't initialize class type"); + + if (PyType_Ready(&PyDictProxy_Type) < 0) + Py_FatalError("Can't initialize dict proxy type"); + + if (PyType_Ready(&PyGen_Type) < 0) + Py_FatalError("Can't initialize generator type"); + + if (PyType_Ready(&PyGetSetDescr_Type) < 0) + Py_FatalError("Can't initialize get-set descriptor type"); + + if (PyType_Ready(&PyWrapperDescr_Type) < 0) + Py_FatalError("Can't initialize wrapper type"); + + if (PyType_Ready(&PyInstance_Type) < 0) + Py_FatalError("Can't initialize instance type"); + + if (PyType_Ready(&PyEllipsis_Type) < 0) + Py_FatalError("Can't initialize ellipsis type"); + + if (PyType_Ready(&PyMemberDescr_Type) < 0) + Py_FatalError("Can't initialize member descriptor type"); } Modified: python/branches/release26-maint/Objects/sliceobject.c ============================================================================== --- python/branches/release26-maint/Objects/sliceobject.c (original) +++ python/branches/release26-maint/Objects/sliceobject.c Mon Apr 20 04:09:13 2009 @@ -22,7 +22,7 @@ return PyString_FromString("Ellipsis"); } -static PyTypeObject PyEllipsis_Type = { +PyTypeObject PyEllipsis_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "ellipsis", /* tp_name */ 0, /* tp_basicsize */ From python-checkins at python.org Mon Apr 20 04:09:14 2009 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 20 Apr 2009 04:09:14 +0200 (CEST) Subject: [Python-checkins] r71757 - in python/branches/py3k: Include/descrobject.h Include/sliceobject.h Objects/object.c Objects/sliceobject.c Message-ID: <20090420020914.194001E400C@bag.python.org> Author: benjamin.peterson Date: Mon Apr 20 04:09:13 2009 New Revision: 71757 Log: Merged revisions 71734,71738-71739 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71734 | benjamin.peterson | 2009-04-18 17:15:26 -0500 (Sat, 18 Apr 2009) | 1 line many more types to initialize (I had to expose some of them) ........ r71738 | benjamin.peterson | 2009-04-18 21:32:42 -0500 (Sat, 18 Apr 2009) | 1 line initialize weakref some weakref types ........ r71739 | benjamin.peterson | 2009-04-18 21:40:43 -0500 (Sat, 18 Apr 2009) | 1 line make errors consistent ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Include/descrobject.h python/branches/py3k/Include/sliceobject.h python/branches/py3k/Objects/object.c python/branches/py3k/Objects/sliceobject.c Modified: python/branches/py3k/Include/descrobject.h ============================================================================== --- python/branches/py3k/Include/descrobject.h (original) +++ python/branches/py3k/Include/descrobject.h Mon Apr 20 04:09:13 2009 @@ -73,6 +73,8 @@ PyAPI_DATA(PyTypeObject) PyMethodDescr_Type; PyAPI_DATA(PyTypeObject) PyWrapperDescr_Type; PyAPI_DATA(PyTypeObject) PyDictProxy_Type; +PyAPI_DATA(PyTypeObject) PyGetSetDescr_Type; +PyAPI_DATA(PyTypeObject) PyMemberDescr_Type; PyAPI_FUNC(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *); PyAPI_FUNC(PyObject *) PyDescr_NewClassMethod(PyTypeObject *, PyMethodDef *); Modified: python/branches/py3k/Include/sliceobject.h ============================================================================== --- python/branches/py3k/Include/sliceobject.h (original) +++ python/branches/py3k/Include/sliceobject.h Mon Apr 20 04:09:13 2009 @@ -25,6 +25,7 @@ } PySliceObject; PyAPI_DATA(PyTypeObject) PySlice_Type; +PyAPI_DATA(PyTypeObject) PyEllipsis_Type; #define PySlice_Check(op) (Py_TYPE(op) == &PySlice_Type) Modified: python/branches/py3k/Objects/object.c ============================================================================== --- python/branches/py3k/Objects/object.c (original) +++ python/branches/py3k/Objects/object.c Mon Apr 20 04:09:13 2009 @@ -3,6 +3,7 @@ #include "Python.h" #include "sliceobject.h" /* For PyEllipsis_Type */ +#include "frameobject.h" #ifdef __cplusplus extern "C" { @@ -1484,17 +1485,23 @@ if (PyType_Ready(&_PyWeakref_RefType) < 0) Py_FatalError("Can't initialize weakref type"); + if (PyType_Ready(&_PyWeakref_CallableProxyType) < 0) + Py_FatalError("Can't initialize callable weakref proxy type"); + + if (PyType_Ready(&_PyWeakref_ProxyType) < 0) + Py_FatalError("Can't initialize weakref proxy type"); + if (PyType_Ready(&PyBool_Type) < 0) Py_FatalError("Can't initialize bool type"); if (PyType_Ready(&PyByteArray_Type) < 0) - Py_FatalError("Can't initialize bytearray"); + Py_FatalError("Can't initialize bytearray type"); if (PyType_Ready(&PyBytes_Type) < 0) Py_FatalError("Can't initialize 'str'"); if (PyType_Ready(&PyList_Type) < 0) - Py_FatalError("Can't initialize list"); + Py_FatalError("Can't initialize list type"); if (PyType_Ready(&PyNone_Type) < 0) Py_FatalError("Can't initialize None type"); @@ -1532,9 +1539,10 @@ if (PyType_Ready(&PyStaticMethod_Type) < 0) Py_FatalError("Can't initialize static method type"); +#ifndef WITHOUT_COMPLEX if (PyType_Ready(&PyComplex_Type) < 0) Py_FatalError("Can't initialize complex type"); - +#endif if (PyType_Ready(&PyFloat_Type) < 0) Py_FatalError("Can't initialize float type"); @@ -1559,11 +1567,41 @@ if (PyType_Ready(&PyReversed_Type) < 0) Py_FatalError("Can't initialize reversed type"); - if (PyType_Ready(&PyCode_Type) < 0) - Py_FatalError("Can't initialize 'code'"); - if (PyType_Ready(&PyStdPrinter_Type) < 0) Py_FatalError("Can't initialize StdPrinter"); + + if (PyType_Ready(&PyCode_Type) < 0) + Py_FatalError("Can't initialize code type"); + + if (PyType_Ready(&PyFrame_Type) < 0) + Py_FatalError("Can't initialize frame type"); + + if (PyType_Ready(&PyCFunction_Type) < 0) + Py_FatalError("Can't initialize builtin function type"); + + if (PyType_Ready(&PyMethod_Type) < 0) + Py_FatalError("Can't initialize method type"); + + if (PyType_Ready(&PyFunction_Type) < 0) + Py_FatalError("Can't initialize function type"); + + if (PyType_Ready(&PyDictProxy_Type) < 0) + Py_FatalError("Can't initialize dict proxy type"); + + if (PyType_Ready(&PyGen_Type) < 0) + Py_FatalError("Can't initialize generator type"); + + if (PyType_Ready(&PyGetSetDescr_Type) < 0) + Py_FatalError("Can't initialize get-set descriptor type"); + + if (PyType_Ready(&PyWrapperDescr_Type) < 0) + Py_FatalError("Can't initialize wrapper type"); + + if (PyType_Ready(&PyEllipsis_Type) < 0) + Py_FatalError("Can't initialize ellipsis type"); + + if (PyType_Ready(&PyMemberDescr_Type) < 0) + Py_FatalError("Can't initialize member descriptor type"); } Modified: python/branches/py3k/Objects/sliceobject.c ============================================================================== --- python/branches/py3k/Objects/sliceobject.c (original) +++ python/branches/py3k/Objects/sliceobject.c Mon Apr 20 04:09:13 2009 @@ -22,7 +22,7 @@ return PyUnicode_FromString("Ellipsis"); } -static PyTypeObject PyEllipsis_Type = { +PyTypeObject PyEllipsis_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "ellipsis", /* tp_name */ 0, /* tp_basicsize */ From buildbot at python.org Mon Apr 20 05:08:40 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 20 Apr 2009 03:08:40 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 2.6 Message-ID: <20090420030840.C89441E4014@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%202.6/builds/259 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: benjamin.peterson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_urllib2_localnet make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 20 09:53:55 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 20 Apr 2009 09:53:55 +0200 (CEST) Subject: [Python-checkins] r71758 - python/trunk/Lib/distutils/tests/test_util.py Message-ID: <20090420075355.66BF21E401C@bag.python.org> Author: tarek.ziade Date: Mon Apr 20 09:53:55 2009 New Revision: 71758 Log: #5795 sysconfig._config_vars was shadowed in tearDown Modified: python/trunk/Lib/distutils/tests/test_util.py Modified: python/trunk/Lib/distutils/tests/test_util.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_util.py (original) +++ python/trunk/Lib/distutils/tests/test_util.py Mon Apr 20 09:53:55 2009 @@ -18,7 +18,8 @@ from distutils.util import rfc822_escape from distutils import util # used to patch _environ_checked -from distutils.sysconfig import get_config_vars, _config_vars +from distutils.sysconfig import get_config_vars +from distutils import sysconfig class utilTestCase(unittest.TestCase): @@ -32,7 +33,7 @@ self.join = os.path.join self.isabs = os.path.isabs self.splitdrive = os.path.splitdrive - self._config_vars = copy(_config_vars) + self._config_vars = copy(sysconfig._config_vars) # patching os.uname if hasattr(os, 'uname'): @@ -58,7 +59,7 @@ os.uname = self.uname else: del os.uname - _config_vars = copy(self._config_vars) + sysconfig._config_vars = copy(self._config_vars) def _set_uname(self, uname): self._uname = uname From buildbot at python.org Mon Apr 20 11:18:48 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 20 Apr 2009 09:18:48 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable trunk Message-ID: <20090420091848.3BC7F1E4019@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%20trunk/builds/390 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_distutils make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 20 12:33:47 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 20 Apr 2009 12:33:47 +0200 (CEST) Subject: [Python-checkins] r71759 - python/trunk/Lib/distutils/tests/test_bdist_wininst.py Message-ID: <20090420103347.E0FF71E400C@bag.python.org> Author: tarek.ziade Date: Mon Apr 20 12:33:47 2009 New Revision: 71759 Log: making BuildWinInstTestCase silent in case bdist_wininst is not run under win32 Modified: python/trunk/Lib/distutils/tests/test_bdist_wininst.py Modified: python/trunk/Lib/distutils/tests/test_bdist_wininst.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_bdist_wininst.py (original) +++ python/trunk/Lib/distutils/tests/test_bdist_wininst.py Mon Apr 20 12:33:47 2009 @@ -5,6 +5,7 @@ from distutils.tests import support class BuildWinInstTestCase(support.TempdirManager, + support.LoggingSilencer, unittest.TestCase): def test_get_exe_bytes(self): From buildbot at python.org Mon Apr 20 13:31:26 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 20 Apr 2009 11:31:26 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu trunk Message-ID: <20090420113126.C57A61E400C@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%20trunk/builds/1257 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_threadedtempfile make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 20 14:17:15 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 20 Apr 2009 14:17:15 +0200 (CEST) Subject: [Python-checkins] r71760 - python/branches/release26-maint Message-ID: <20090420121715.EC0591E400C@bag.python.org> Author: tarek.ziade Date: Mon Apr 20 14:17:15 2009 New Revision: 71760 Log: Merged revisions 71758 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71758 | tarek.ziade | 2009-04-20 09:53:55 +0200 (Mon, 20 Apr 2009) | 1 line #5795 sysconfig._config_vars was shadowed in tearDown ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Apr 20 14:18:08 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 20 Apr 2009 14:18:08 +0200 (CEST) Subject: [Python-checkins] r71761 - in python/branches/py3k: Lib/distutils/tests/test_util.py Message-ID: <20090420121808.EAED01E400C@bag.python.org> Author: tarek.ziade Date: Mon Apr 20 14:18:08 2009 New Revision: 71761 Log: Merged revisions 71758 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71758 | tarek.ziade | 2009-04-20 09:53:55 +0200 (Mon, 20 Apr 2009) | 1 line #5795 sysconfig._config_vars was shadowed in tearDown ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/tests/test_util.py Modified: python/branches/py3k/Lib/distutils/tests/test_util.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_util.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_util.py Mon Apr 20 14:18:08 2009 @@ -18,7 +18,8 @@ from distutils.util import rfc822_escape from distutils import util # used to patch _environ_checked -from distutils.sysconfig import get_config_vars, _config_vars +from distutils.sysconfig import get_config_vars +from distutils import sysconfig class utilTestCase(unittest.TestCase): @@ -32,7 +33,7 @@ self.join = os.path.join self.isabs = os.path.isabs self.splitdrive = os.path.splitdrive - self._config_vars = copy(_config_vars) + self._config_vars = copy(sysconfig._config_vars) # patching os.uname if hasattr(os, 'uname'): @@ -58,7 +59,7 @@ os.uname = self.uname else: del os.uname - _config_vars = copy(self._config_vars) + sysconfig._config_vars = copy(self._config_vars) def _set_uname(self, uname): self._uname = uname From python-checkins at python.org Mon Apr 20 14:37:58 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 20 Apr 2009 14:37:58 +0200 (CEST) Subject: [Python-checkins] r71762 - in python/branches/py3k: Lib/distutils/tests/test_bdist_wininst.py Message-ID: <20090420123758.E193C1E4029@bag.python.org> Author: tarek.ziade Date: Mon Apr 20 14:37:58 2009 New Revision: 71762 Log: Merged revisions 71759 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71759 | tarek.ziade | 2009-04-20 12:33:47 +0200 (Mon, 20 Apr 2009) | 1 line making BuildWinInstTestCase silent in case bdist_wininst is not run under win32 ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/tests/test_bdist_wininst.py Modified: python/branches/py3k/Lib/distutils/tests/test_bdist_wininst.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_bdist_wininst.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_bdist_wininst.py Mon Apr 20 14:37:58 2009 @@ -5,6 +5,7 @@ from distutils.tests import support class BuildWinInstTestCase(support.TempdirManager, + support.LoggingSilencer, unittest.TestCase): def test_get_exe_bytes(self): From python-checkins at python.org Mon Apr 20 14:38:48 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 20 Apr 2009 14:38:48 +0200 (CEST) Subject: [Python-checkins] r71763 - python/branches/release30-maint Message-ID: <20090420123848.B34F51E400C@bag.python.org> Author: tarek.ziade Date: Mon Apr 20 14:38:48 2009 New Revision: 71763 Log: Blocked revisions 71761 via svnmerge ................ r71761 | tarek.ziade | 2009-04-20 14:18:08 +0200 (Mon, 20 Apr 2009) | 9 lines Merged revisions 71758 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71758 | tarek.ziade | 2009-04-20 09:53:55 +0200 (Mon, 20 Apr 2009) | 1 line #5795 sysconfig._config_vars was shadowed in tearDown ........ ................ Modified: python/branches/release30-maint/ (props changed) From buildbot at python.org Mon Apr 20 14:39:01 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 20 Apr 2009 12:39:01 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 2.6 Message-ID: <20090420123901.F3DAC1E400C@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%202.6/builds/266 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: Traceback (most recent call last): File "/home/pybot/buildarea/2.6.klose-ubuntu-i386/build/Lib/threading.py", line 525, in __bootstrap_inner self.run() File "/home/pybot/buildarea/2.6.klose-ubuntu-i386/build/Lib/threading.py", line 477, in run self.__target(*self.__args, **self.__kwargs) File "/home/pybot/buildarea/2.6.klose-ubuntu-i386/build/Lib/bsddb/test/test_thread.py", line 306, in readerThread rec = dbutils.DeadlockWrap(c.next, max_retries=10) File "/home/pybot/buildarea/2.6.klose-ubuntu-i386/build/Lib/bsddb/dbutils.py", line 68, in DeadlockWrap return function(*_args, **_kwargs) DBLockDeadlockError: (-30994, 'DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock') Traceback (most recent call last): File "/home/pybot/buildarea/2.6.klose-ubuntu-i386/build/Lib/test/test_signal.py", line 165, in test_main pickle.dump(None, done_w) File "/home/pybot/buildarea/2.6.klose-ubuntu-i386/build/Lib/contextlib.py", line 153, in __exit__ self.thing.close() IOError: [Errno 9] Bad file descriptor 1 test failed: test_signal make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 20 14:39:26 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 20 Apr 2009 14:39:26 +0200 (CEST) Subject: [Python-checkins] r71764 - in python/branches/release30-maint: Lib/distutils/tests/test_bdist_wininst.py Message-ID: <20090420123926.9ABED1E400C@bag.python.org> Author: tarek.ziade Date: Mon Apr 20 14:39:26 2009 New Revision: 71764 Log: Merged revisions 71762 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71762 | tarek.ziade | 2009-04-20 14:37:58 +0200 (Mon, 20 Apr 2009) | 9 lines Merged revisions 71759 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71759 | tarek.ziade | 2009-04-20 12:33:47 +0200 (Mon, 20 Apr 2009) | 1 line making BuildWinInstTestCase silent in case bdist_wininst is not run under win32 ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Lib/distutils/tests/test_bdist_wininst.py Modified: python/branches/release30-maint/Lib/distutils/tests/test_bdist_wininst.py ============================================================================== --- python/branches/release30-maint/Lib/distutils/tests/test_bdist_wininst.py (original) +++ python/branches/release30-maint/Lib/distutils/tests/test_bdist_wininst.py Mon Apr 20 14:39:26 2009 @@ -7,6 +7,7 @@ from distutils.tests import support class BuildWinInstTestCase(support.TempdirManager, + support.LoggingSilencer, unittest.TestCase): def test_get_exe_bytes(self): From python-checkins at python.org Mon Apr 20 14:48:47 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 20 Apr 2009 14:48:47 +0200 (CEST) Subject: [Python-checkins] r71765 - in python/branches/release26-maint: Lib/distutils/tests/test_bdist_wininst.py Message-ID: <20090420124847.DA5E41E4019@bag.python.org> Author: tarek.ziade Date: Mon Apr 20 14:48:47 2009 New Revision: 71765 Log: Merged revisions 71759 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71759 | tarek.ziade | 2009-04-20 12:33:47 +0200 (Mon, 20 Apr 2009) | 1 line making BuildWinInstTestCase silent in case bdist_wininst is not run under win32 ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/distutils/tests/test_bdist_wininst.py Modified: python/branches/release26-maint/Lib/distutils/tests/test_bdist_wininst.py ============================================================================== --- python/branches/release26-maint/Lib/distutils/tests/test_bdist_wininst.py (original) +++ python/branches/release26-maint/Lib/distutils/tests/test_bdist_wininst.py Mon Apr 20 14:48:47 2009 @@ -7,6 +7,7 @@ from distutils.tests import support class BuildWinInstTestCase(support.TempdirManager, + support.LoggingSilencer, unittest.TestCase): def test_get_exe_bytes(self): From buildbot at python.org Mon Apr 20 15:48:15 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 20 Apr 2009 13:48:15 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090420134815.6E6121E402F@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/616 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: tarek.ziade BUILD FAILED: failed failed slave lost sincerely, -The Buildbot From python-checkins at python.org Mon Apr 20 16:29:42 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 20 Apr 2009 16:29:42 +0200 (CEST) Subject: [Python-checkins] r71766 - python/trunk/Misc/NEWS Message-ID: <20090420142942.E52B21E4024@bag.python.org> Author: tarek.ziade Date: Mon Apr 20 16:29:42 2009 New Revision: 71766 Log: adding a NEWS note for #5795 (previously checked via the buildbot) Modified: python/trunk/Misc/NEWS Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Apr 20 16:29:42 2009 @@ -229,6 +229,8 @@ Library ------- +- Issue #5795: Fixed test_distutils failure on Debian ppc. + - Issue #5768: Fixed bug in Unicode output logic and test case for same. - Issue #1161031: fix readwrite select flag handling: POLLPRI now From python-checkins at python.org Mon Apr 20 16:31:46 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 20 Apr 2009 16:31:46 +0200 (CEST) Subject: [Python-checkins] r71767 - python/branches/release26-maint Message-ID: <20090420143146.24A891E4024@bag.python.org> Author: tarek.ziade Date: Mon Apr 20 16:31:45 2009 New Revision: 71767 Log: Blocked revisions 71766 via svnmerge ........ r71766 | tarek.ziade | 2009-04-20 16:29:42 +0200 (Mon, 20 Apr 2009) | 1 line adding a NEWS note for #5795 (previously checked via the buildbot) ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Apr 20 16:33:16 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 20 Apr 2009 16:33:16 +0200 (CEST) Subject: [Python-checkins] r71768 - in python/branches/py3k: Misc/NEWS Message-ID: <20090420143316.2C6811E4024@bag.python.org> Author: tarek.ziade Date: Mon Apr 20 16:33:15 2009 New Revision: 71768 Log: Merged revisions 71766 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71766 | tarek.ziade | 2009-04-20 16:29:42 +0200 (Mon, 20 Apr 2009) | 1 line adding a NEWS note for #5795 (previously checked via the buildbot) ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Apr 20 16:33:15 2009 @@ -408,6 +408,8 @@ Library ------- +- Issue #5795: Fixed test_distutils failure on Debian ppc. + - Issue #5607: fixed Distutils test_get_platform for Mac OS X fat binaries. - Issue #5732: added a new command in Distutils: check. From python-checkins at python.org Mon Apr 20 16:35:13 2009 From: python-checkins at python.org (tarek.ziade) Date: Mon, 20 Apr 2009 16:35:13 +0200 (CEST) Subject: [Python-checkins] r71769 - python/branches/release30-maint Message-ID: <20090420143513.2742C1E4024@bag.python.org> Author: tarek.ziade Date: Mon Apr 20 16:35:12 2009 New Revision: 71769 Log: Blocked revisions 71768 via svnmerge ................ r71768 | tarek.ziade | 2009-04-20 16:33:15 +0200 (Mon, 20 Apr 2009) | 9 lines Merged revisions 71766 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71766 | tarek.ziade | 2009-04-20 16:29:42 +0200 (Mon, 20 Apr 2009) | 1 line adding a NEWS note for #5795 (previously checked via the buildbot) ........ ................ Modified: python/branches/release30-maint/ (props changed) From buildbot at python.org Mon Apr 20 16:42:40 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 20 Apr 2009 14:42:40 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090420144240.20F0B1E4050@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/284 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_distutils test_posix ====================================================================== FAIL: test_get_python_inc (distutils.tests.test_sysconfig.SysconfigTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/distutils/tests/test_sysconfig.py", line 45, in test_get_python_inc self.assert_(os.path.isdir(inc_dir), inc_dir) AssertionError: /home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/Include ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From buildbot at python.org Mon Apr 20 17:47:59 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 20 Apr 2009 15:47:59 +0000 Subject: [Python-checkins] buildbot failure in OS X x86 2.6 Message-ID: <20090420154801.48DCA1E4023@bag.python.org> The Buildbot has detected a new failure of OS X x86 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/OS%20X%20x86%202.6/builds/229 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: noller-osx86 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_asynchat make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Mon Apr 20 18:00:33 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 20 Apr 2009 16:00:33 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090420160033.704931E4023@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/618 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_binhex make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Mon Apr 20 18:04:12 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 20 Apr 2009 16:04:12 +0000 Subject: [Python-checkins] buildbot failure in OS X x86 3.0 Message-ID: <20090420160412.7E2CE1E4024@bag.python.org> The Buildbot has detected a new failure of OS X x86 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/OS%20X%20x86%203.0/builds/245 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: noller-osx86 Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_asynchat test_cmd_line ====================================================================== FAIL: test_run_code (test.test_cmd_line.CmdLineTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/buildbot/buildarea/3.0.noller-osx86/build/Lib/test/test_cmd_line.py", line 143, in test_run_code 0) AssertionError: 1 != 0 make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 20 20:23:36 2009 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 20 Apr 2009 20:23:36 +0200 (CEST) Subject: [Python-checkins] r71770 - python/branches/release26-maint/Doc/library/itertools.rst Message-ID: <20090420182336.625421E40E3@bag.python.org> Author: raymond.hettinger Date: Mon Apr 20 20:23:26 2009 New Revision: 71770 Log: Fix typo Modified: python/branches/release26-maint/Doc/library/itertools.rst Modified: python/branches/release26-maint/Doc/library/itertools.rst ============================================================================== --- python/branches/release26-maint/Doc/library/itertools.rst (original) +++ python/branches/release26-maint/Doc/library/itertools.rst Mon Apr 20 20:23:26 2009 @@ -366,7 +366,7 @@ # izip('ABCD', 'xy') --> Ax By iterables = map(iter, iterables) while iterables: - yield yield tuple(map(next, iterables)) + yield tuple(map(next, iterables)) .. versionchanged:: 2.4 When no iterables are specified, returns a zero length iterator instead of From python-checkins at python.org Mon Apr 20 20:23:58 2009 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 20 Apr 2009 20:23:58 +0200 (CEST) Subject: [Python-checkins] r71771 - python/trunk/Doc/library/itertools.rst Message-ID: <20090420182358.27AF91E4028@bag.python.org> Author: raymond.hettinger Date: Mon Apr 20 20:23:57 2009 New Revision: 71771 Log: Fix typo Modified: python/trunk/Doc/library/itertools.rst Modified: python/trunk/Doc/library/itertools.rst ============================================================================== --- python/trunk/Doc/library/itertools.rst (original) +++ python/trunk/Doc/library/itertools.rst Mon Apr 20 20:23:57 2009 @@ -433,7 +433,7 @@ # izip('ABCD', 'xy') --> Ax By iterables = map(iter, iterables) while iterables: - yield yield tuple(map(next, iterables)) + yield tuple(map(next, iterables)) .. versionchanged:: 2.4 When no iterables are specified, returns a zero length iterator instead of From python-checkins at python.org Mon Apr 20 23:13:33 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 20 Apr 2009 23:13:33 +0200 (CEST) Subject: [Python-checkins] r71772 - in python/trunk: Lib/test/test_int.py Lib/test/test_long.py Misc/NEWS Objects/intobject.c Objects/longobject.c Message-ID: <20090420211333.796381E4022@bag.python.org> Author: mark.dickinson Date: Mon Apr 20 23:13:33 2009 New Revision: 71772 Log: Issue #3166: Make long -> float (and int -> float) conversions correctly rounded, using round-half-to-even. This ensures that the value of float(n) doesn't depend on whether we're using 15-bit digits or 30-bit digits for Python longs. Modified: python/trunk/Lib/test/test_int.py python/trunk/Lib/test/test_long.py python/trunk/Misc/NEWS python/trunk/Objects/intobject.c python/trunk/Objects/longobject.c Modified: python/trunk/Lib/test/test_int.py ============================================================================== --- python/trunk/Lib/test/test_int.py (original) +++ python/trunk/Lib/test/test_int.py Mon Apr 20 23:13:33 2009 @@ -275,6 +275,40 @@ self.assertEqual((a+1).bit_length(), i+1) self.assertEqual((-a-1).bit_length(), i+1) + @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + def test_float_conversion(self): + # values exactly representable as floats + exact_values = [-2, -1, 0, 1, 2, 2**52, 2**53-1, 2**53, 2**53+2, + 2**53+4, 2**54-4, 2**54-2, 2**63, -2**63, 2**64, + -2**64, 10**20, 10**21, 10**22] + for value in exact_values: + self.assertEqual(int(float(int(value))), value) + + # test round-half-to-even + self.assertEqual(int(float(2**53+1)), 2**53) + self.assertEqual(int(float(2**53+2)), 2**53+2) + self.assertEqual(int(float(2**53+3)), 2**53+4) + self.assertEqual(int(float(2**53+5)), 2**53+4) + self.assertEqual(int(float(2**53+6)), 2**53+6) + self.assertEqual(int(float(2**53+7)), 2**53+8) + + self.assertEqual(int(float(-2**53-1)), -2**53) + self.assertEqual(int(float(-2**53-2)), -2**53-2) + self.assertEqual(int(float(-2**53-3)), -2**53-4) + self.assertEqual(int(float(-2**53-5)), -2**53-4) + self.assertEqual(int(float(-2**53-6)), -2**53-6) + self.assertEqual(int(float(-2**53-7)), -2**53-8) + + self.assertEqual(int(float(2**54-2)), 2**54-2) + self.assertEqual(int(float(2**54-1)), 2**54) + self.assertEqual(int(float(2**54+2)), 2**54) + self.assertEqual(int(float(2**54+3)), 2**54+4) + self.assertEqual(int(float(2**54+5)), 2**54+4) + self.assertEqual(int(float(2**54+6)), 2**54+8) + self.assertEqual(int(float(2**54+10)), 2**54+8) + self.assertEqual(int(float(2**54+11)), 2**54+12) + def test_intconversion(self): # Test __int__() class ClassicMissingMethods: Modified: python/trunk/Lib/test/test_long.py ============================================================================== --- python/trunk/Lib/test/test_long.py (original) +++ python/trunk/Lib/test/test_long.py Mon Apr 20 23:13:33 2009 @@ -645,6 +645,65 @@ else: self.assertRaises(TypeError, pow,longx, longy, long(z)) + @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + def test_float_conversion(self): + import sys + DBL_MAX = sys.float_info.max + DBL_MAX_EXP = sys.float_info.max_exp + DBL_MANT_DIG = sys.float_info.mant_dig + + exact_values = [0L, 1L, 2L, + long(2**53-3), + long(2**53-2), + long(2**53-1), + long(2**53), + long(2**53+2), + long(2**54-4), + long(2**54-2), + long(2**54), + long(2**54+4)] + for x in exact_values: + self.assertEqual(long(float(x)), x) + self.assertEqual(long(float(-x)), -x) + + # test round-half-even + for x, y in [(1, 0), (2, 2), (3, 4), (4, 4), (5, 4), (6, 6), (7, 8)]: + for p in xrange(15): + self.assertEqual(long(float(2L**p*(2**53+x))), 2L**p*(2**53+y)) + + for x, y in [(0, 0), (1, 0), (2, 0), (3, 4), (4, 4), (5, 4), (6, 8), + (7, 8), (8, 8), (9, 8), (10, 8), (11, 12), (12, 12), + (13, 12), (14, 16), (15, 16)]: + for p in xrange(15): + self.assertEqual(long(float(2L**p*(2**54+x))), 2L**p*(2**54+y)) + + # behaviour near extremes of floating-point range + long_dbl_max = long(DBL_MAX) + top_power = 2**DBL_MAX_EXP + halfway = (long_dbl_max + top_power)/2 + self.assertEqual(float(long_dbl_max), DBL_MAX) + self.assertEqual(float(long_dbl_max+1), DBL_MAX) + self.assertEqual(float(halfway-1), DBL_MAX) + self.assertRaises(OverflowError, float, halfway) + self.assertEqual(float(1-halfway), -DBL_MAX) + self.assertRaises(OverflowError, float, -halfway) + self.assertRaises(OverflowError, float, top_power-1) + self.assertRaises(OverflowError, float, top_power) + self.assertRaises(OverflowError, float, top_power+1) + self.assertRaises(OverflowError, float, 2*top_power-1) + self.assertRaises(OverflowError, float, 2*top_power) + self.assertRaises(OverflowError, float, top_power*top_power) + + for p in xrange(100): + x = long(2**p * (2**53 + 1) + 1) + y = long(2**p * (2**53+ 2)) + self.assertEqual(long(float(x)), y) + + x = long(2**p * (2**53 + 1)) + y = long(2**p * 2**53) + self.assertEqual(long(float(x)), y) + def test_float_overflow(self): import math Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Apr 20 23:13:33 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #3166: Make long -> float (and int -> float) conversions + correctly rounded. + - Issue #5787: object.__getattribute__(some_type, "__bases__") segfaulted on some builtin types. Modified: python/trunk/Objects/intobject.c ============================================================================== --- python/trunk/Objects/intobject.c (original) +++ python/trunk/Objects/intobject.c Mon Apr 20 23:13:33 2009 @@ -3,6 +3,7 @@ #include "Python.h" #include +#include static PyObject *int_int(PyIntObject *v); @@ -928,12 +929,78 @@ return PyLong_FromLong((v -> ob_ival)); } +static const unsigned char BitLengthTable[32] = { + 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 +}; + +static int +bits_in_ulong(unsigned long d) +{ + int d_bits = 0; + while (d >= 32) { + d_bits += 6; + d >>= 6; + } + d_bits += (int)BitLengthTable[d]; + return d_bits; +} + +#if 8*SIZEOF_LONG-1 <= DBL_MANT_DIG +/* Every Python int can be exactly represented as a float. */ + static PyObject * int_float(PyIntObject *v) { return PyFloat_FromDouble((double)(v -> ob_ival)); } +#else +/* Here not all Python ints are exactly representable as floats, so we may + have to round. We do this manually, since the C standards don't specify + whether converting an integer to a float rounds up or down */ + +static PyObject * +int_float(PyIntObject *v) +{ + unsigned long abs_ival, lsb; + int round_up; + + if (v->ob_ival < 0) + abs_ival = 0U-(unsigned long)v->ob_ival; + else + abs_ival = (unsigned long)v->ob_ival; + if (abs_ival < (1L << DBL_MANT_DIG)) + /* small integer; no need to round */ + return PyFloat_FromDouble((double)v->ob_ival); + + /* Round abs_ival to MANT_DIG significant bits, using the + round-half-to-even rule. abs_ival & lsb picks out the 'rounding' + bit: the first bit after the most significant MANT_DIG bits of + abs_ival. We round up if this bit is set, provided that either: + + (1) abs_ival isn't exactly halfway between two floats, in which + case at least one of the bits following the rounding bit must be + set; i.e., abs_ival & lsb-1 != 0, or: + + (2) the resulting rounded value has least significant bit 0; or + in other words the bit above the rounding bit is set (this is the + 'to-even' bit of round-half-to-even); i.e., abs_ival & 2*lsb != 0 + + The condition "(1) or (2)" equates to abs_ival & 3*lsb-1 != 0. */ + + lsb = 1L << (bits_in_ulong(abs_ival)-DBL_MANT_DIG-1); + round_up = (abs_ival & lsb) && (abs_ival & (3*lsb-1)); + abs_ival &= -2*lsb; + if (round_up) + abs_ival += 2*lsb; + return PyFloat_FromDouble(v->ob_ival < 0 ? + -(double)abs_ival : + (double)abs_ival); +} + +#endif + static PyObject * int_oct(PyIntObject *v) { @@ -1139,16 +1206,10 @@ return NULL; } -static const unsigned char BitLengthTable[32] = { - 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 -}; - static PyObject * int_bit_length(PyIntObject *v) { unsigned long n; - long r = 0; if (v->ob_ival < 0) /* avoid undefined behaviour when v->ob_ival == -LONG_MAX-1 */ @@ -1156,12 +1217,7 @@ else n = (unsigned long)v->ob_ival; - while (n >= 32) { - r += 6; - n >>= 6; - } - r += (long)(BitLengthTable[n]); - return PyInt_FromLong(r); + return PyInt_FromLong(bits_in_ulong(n)); } PyDoc_STRVAR(int_bit_length_doc, Modified: python/trunk/Objects/longobject.c ============================================================================== --- python/trunk/Objects/longobject.c (original) +++ python/trunk/Objects/longobject.c Mon Apr 20 23:13:33 2009 @@ -8,6 +8,7 @@ #include "longintrepr.h" #include "structseq.h" +#include #include #include @@ -38,6 +39,9 @@ if (PyErr_CheckSignals()) PyTryBlock \ } +/* forward declaration */ +static int bits_in_digit(digit d); + /* Normalize (remove leading zeros from) a long int object. Doesn't attempt to free the storage--in most cases, due to the nature of the algorithms used, this could save at most be one word anyway. */ @@ -729,33 +733,166 @@ #undef NBITS_WANTED } -/* Get a C double from a long int object. */ +/* Get a C double from a long int object. Rounds to the nearest double, + using the round-half-to-even rule in the case of a tie. */ double PyLong_AsDouble(PyObject *vv) { - int e = -1; + PyLongObject *v = (PyLongObject *)vv; + Py_ssize_t rnd_digit, rnd_bit, m, n; + digit lsb, *d; + int round_up = 0; double x; if (vv == NULL || !PyLong_Check(vv)) { PyErr_BadInternalCall(); - return -1; - } - x = _PyLong_AsScaledDouble(vv, &e); - if (x == -1.0 && PyErr_Occurred()) return -1.0; - /* 'e' initialized to -1 to silence gcc-4.0.x, but it should be - set correctly after a successful _PyLong_AsScaledDouble() call */ - assert(e >= 0); - if (e > INT_MAX / PyLong_SHIFT) + } + + /* Notes on the method: for simplicity, assume v is positive and >= + 2**DBL_MANT_DIG. (For negative v we just ignore the sign until the + end; for small v no rounding is necessary.) Write n for the number + of bits in v, so that 2**(n-1) <= v < 2**n, and n > DBL_MANT_DIG. + + Some terminology: the *rounding bit* of v is the 1st bit of v that + will be rounded away (bit n - DBL_MANT_DIG - 1); the *parity bit* + is the bit immediately above. The round-half-to-even rule says + that we round up if the rounding bit is set, unless v is exactly + halfway between two floats and the parity bit is zero. + + Write d[0] ... d[m] for the digits of v, least to most significant. + Let rnd_bit be the index of the rounding bit, and rnd_digit the + index of the PyLong digit containing the rounding bit. Then the + bits of the digit d[rnd_digit] look something like: + + rounding bit + | + v + msb -> sssssrttttttttt <- lsb + ^ + | + parity bit + + where 's' represents a 'significant bit' that will be included in + the mantissa of the result, 'r' is the rounding bit, and 't' + represents a 'trailing bit' following the rounding bit. Note that + if the rounding bit is at the top of d[rnd_digit] then the parity + bit will be the lsb of d[rnd_digit+1]. If we set + + lsb = 1 << (rnd_bit % PyLong_SHIFT) + + then d[rnd_digit] & (PyLong_BASE - 2*lsb) selects just the + significant bits of d[rnd_digit], d[rnd_digit] & (lsb-1) gets the + trailing bits, and d[rnd_digit] & lsb gives the rounding bit. + + We initialize the double x to the integer given by digits + d[rnd_digit:m-1], but with the rounding bit and trailing bits of + d[rnd_digit] masked out. So the value of x comes from the top + DBL_MANT_DIG bits of v, multiplied by 2*lsb. Note that in the loop + that produces x, all floating-point operations are exact (assuming + that FLT_RADIX==2). Now if we're rounding down, the value we want + to return is simply + + x * 2**(PyLong_SHIFT * rnd_digit). + + and if we're rounding up, it's + + (x + 2*lsb) * 2**(PyLong_SHIFT * rnd_digit). + + Under the round-half-to-even rule, we round up if, and only + if, the rounding bit is set *and* at least one of the + following three conditions is satisfied: + + (1) the parity bit is set, or + (2) at least one of the trailing bits of d[rnd_digit] is set, or + (3) at least one of the digits d[i], 0 <= i < rnd_digit + is nonzero. + + Finally, we have to worry about overflow. If v >= 2**DBL_MAX_EXP, + or equivalently n > DBL_MAX_EXP, then overflow occurs. If v < + 2**DBL_MAX_EXP then we're usually safe, but there's a corner case + to consider: if v is very close to 2**DBL_MAX_EXP then it's + possible that v is rounded up to exactly 2**DBL_MAX_EXP, and then + again overflow occurs. + */ + + if (Py_SIZE(v) == 0) + return 0.0; + m = ABS(Py_SIZE(v)) - 1; + d = v->ob_digit; + assert(d[m]); /* v should be normalized */ + + /* fast path for case where 0 < abs(v) < 2**DBL_MANT_DIG */ + if (m < DBL_MANT_DIG / PyLong_SHIFT || + (m == DBL_MANT_DIG / PyLong_SHIFT && + d[m] < (digit)1 << DBL_MANT_DIG%PyLong_SHIFT)) { + x = d[m]; + while (--m >= 0) + x = x*PyLong_BASE + d[m]; + return Py_SIZE(v) < 0 ? -x : x; + } + + /* if m is huge then overflow immediately; otherwise, compute the + number of bits n in v. The condition below implies n (= #bits) >= + m * PyLong_SHIFT + 1 > DBL_MAX_EXP, hence v >= 2**DBL_MAX_EXP. */ + if (m > (DBL_MAX_EXP-1)/PyLong_SHIFT) goto overflow; - errno = 0; - x = ldexp(x, e * PyLong_SHIFT); - if (Py_OVERFLOWED(x)) + n = m * PyLong_SHIFT + bits_in_digit(d[m]); + if (n > DBL_MAX_EXP) goto overflow; - return x; -overflow: + /* find location of rounding bit */ + assert(n > DBL_MANT_DIG); /* dealt with |v| < 2**DBL_MANT_DIG above */ + rnd_bit = n - DBL_MANT_DIG - 1; + rnd_digit = rnd_bit/PyLong_SHIFT; + lsb = (digit)1 << (rnd_bit%PyLong_SHIFT); + + /* Get top DBL_MANT_DIG bits of v. Assumes PyLong_SHIFT < + DBL_MANT_DIG, so we'll need bits from at least 2 digits of v. */ + x = d[m]; + assert(m > rnd_digit); + while (--m > rnd_digit) + x = x*PyLong_BASE + d[m]; + x = x*PyLong_BASE + (d[m] & (PyLong_BASE-2*lsb)); + + /* decide whether to round up, using round-half-to-even */ + assert(m == rnd_digit); + if (d[m] & lsb) { /* if (rounding bit is set) */ + digit parity_bit; + if (lsb == PyLong_BASE/2) + parity_bit = d[m+1] & 1; + else + parity_bit = d[m] & 2*lsb; + if (parity_bit) + round_up = 1; + else if (d[m] & (lsb-1)) + round_up = 1; + else { + while (--m >= 0) { + if (d[m]) { + round_up = 1; + break; + } + } + } + } + + /* and round up if necessary */ + if (round_up) { + x += 2*lsb; + if (n == DBL_MAX_EXP && + x == ldexp((double)(2*lsb), DBL_MANT_DIG)) { + /* overflow corner case */ + goto overflow; + } + } + + /* shift, adjust for sign, and return */ + x = ldexp(x, rnd_digit*PyLong_SHIFT); + return Py_SIZE(v) < 0 ? -x : x; + + overflow: PyErr_SetString(PyExc_OverflowError, "long int too large to convert to float"); return -1.0; From python-checkins at python.org Mon Apr 20 23:38:00 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 20 Apr 2009 23:38:00 +0200 (CEST) Subject: [Python-checkins] r71773 - in python/branches/py3k: Lib/test/test_long.py Misc/NEWS Objects/longobject.c Message-ID: <20090420213800.EEE321E4022@bag.python.org> Author: mark.dickinson Date: Mon Apr 20 23:38:00 2009 New Revision: 71773 Log: Merged revisions 71772 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71772 | mark.dickinson | 2009-04-20 22:13:33 +0100 (Mon, 20 Apr 2009) | 5 lines Issue #3166: Make long -> float (and int -> float) conversions correctly rounded, using round-half-to-even. This ensures that the value of float(n) doesn't depend on whether we're using 15-bit digits or 30-bit digits for Python longs. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_long.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/longobject.c 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 Mon Apr 20 23:38:00 2009 @@ -620,6 +620,65 @@ else: self.assertRaises(TypeError, pow,longx, longy, int(z)) + @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + def test_float_conversion(self): + import sys + DBL_MAX = sys.float_info.max + DBL_MAX_EXP = sys.float_info.max_exp + DBL_MANT_DIG = sys.float_info.mant_dig + + exact_values = [0, 1, 2, + 2**53-3, + 2**53-2, + 2**53-1, + 2**53, + 2**53+2, + 2**54-4, + 2**54-2, + 2**54, + 2**54+4] + for x in exact_values: + self.assertEqual(float(x), x) + self.assertEqual(float(-x), -x) + + # test round-half-even + for x, y in [(1, 0), (2, 2), (3, 4), (4, 4), (5, 4), (6, 6), (7, 8)]: + for p in range(15): + self.assertEqual(int(float(2**p*(2**53+x))), 2**p*(2**53+y)) + + for x, y in [(0, 0), (1, 0), (2, 0), (3, 4), (4, 4), (5, 4), (6, 8), + (7, 8), (8, 8), (9, 8), (10, 8), (11, 12), (12, 12), + (13, 12), (14, 16), (15, 16)]: + for p in range(15): + self.assertEqual(int(float(2**p*(2**54+x))), 2**p*(2**54+y)) + + # behaviour near extremes of floating-point range + int_dbl_max = int(DBL_MAX) + top_power = 2**DBL_MAX_EXP + halfway = (int_dbl_max + top_power)//2 + self.assertEqual(float(int_dbl_max), DBL_MAX) + self.assertEqual(float(int_dbl_max+1), DBL_MAX) + self.assertEqual(float(halfway-1), DBL_MAX) + self.assertRaises(OverflowError, float, halfway) + self.assertEqual(float(1-halfway), -DBL_MAX) + self.assertRaises(OverflowError, float, -halfway) + self.assertRaises(OverflowError, float, top_power-1) + self.assertRaises(OverflowError, float, top_power) + self.assertRaises(OverflowError, float, top_power+1) + self.assertRaises(OverflowError, float, 2*top_power-1) + self.assertRaises(OverflowError, float, 2*top_power) + self.assertRaises(OverflowError, float, top_power*top_power) + + for p in range(100): + x = 2**p * (2**53 + 1) + 1 + y = 2**p * (2**53 + 2) + self.assertEqual(int(float(x)), y) + + x = 2**p * (2**53 + 1) + y = 2**p * 2**53 + self.assertEqual(int(float(x)), y) + def test_float_overflow(self): import math Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Apr 20 23:38:00 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #3166: Make long -> float (and int -> float) conversions + correctly rounded. + - Issue #1869 (and many duplicates): make round(x, n) correctly rounded for a float x, by using the decimal <-> binary conversions from Python/dtoa.c. As a consequence, (e.g.) round(x, 2) now Modified: python/branches/py3k/Objects/longobject.c ============================================================================== --- python/branches/py3k/Objects/longobject.c (original) +++ python/branches/py3k/Objects/longobject.c Mon Apr 20 23:38:00 2009 @@ -6,6 +6,7 @@ #include "longintrepr.h" #include "structseq.h" +#include #include #include @@ -100,6 +101,9 @@ if (PyErr_CheckSignals()) PyTryBlock \ } +/* forward declaration */ +static int bits_in_digit(digit d); + /* Normalize (remove leading zeros from) a long int object. Doesn't attempt to free the storage--in most cases, due to the nature of the algorithms used, this could save at most be one word anyway. */ @@ -962,33 +966,166 @@ #undef NBITS_WANTED } -/* Get a C double from a long int object. */ +/* Get a C double from a long int object. Rounds to the nearest double, + using the round-half-to-even rule in the case of a tie. */ double PyLong_AsDouble(PyObject *vv) { - int e = -1; + PyLongObject *v = (PyLongObject *)vv; + Py_ssize_t rnd_digit, rnd_bit, m, n; + digit lsb, *d; + int round_up = 0; double x; if (vv == NULL || !PyLong_Check(vv)) { PyErr_BadInternalCall(); - return -1; - } - x = _PyLong_AsScaledDouble(vv, &e); - if (x == -1.0 && PyErr_Occurred()) return -1.0; - /* 'e' initialized to -1 to silence gcc-4.0.x, but it should be - set correctly after a successful _PyLong_AsScaledDouble() call */ - assert(e >= 0); - if (e > INT_MAX / PyLong_SHIFT) + } + + /* Notes on the method: for simplicity, assume v is positive and >= + 2**DBL_MANT_DIG. (For negative v we just ignore the sign until the + end; for small v no rounding is necessary.) Write n for the number + of bits in v, so that 2**(n-1) <= v < 2**n, and n > DBL_MANT_DIG. + + Some terminology: the *rounding bit* of v is the 1st bit of v that + will be rounded away (bit n - DBL_MANT_DIG - 1); the *parity bit* + is the bit immediately above. The round-half-to-even rule says + that we round up if the rounding bit is set, unless v is exactly + halfway between two floats and the parity bit is zero. + + Write d[0] ... d[m] for the digits of v, least to most significant. + Let rnd_bit be the index of the rounding bit, and rnd_digit the + index of the PyLong digit containing the rounding bit. Then the + bits of the digit d[rnd_digit] look something like: + + rounding bit + | + v + msb -> sssssrttttttttt <- lsb + ^ + | + parity bit + + where 's' represents a 'significant bit' that will be included in + the mantissa of the result, 'r' is the rounding bit, and 't' + represents a 'trailing bit' following the rounding bit. Note that + if the rounding bit is at the top of d[rnd_digit] then the parity + bit will be the lsb of d[rnd_digit+1]. If we set + + lsb = 1 << (rnd_bit % PyLong_SHIFT) + + then d[rnd_digit] & (PyLong_BASE - 2*lsb) selects just the + significant bits of d[rnd_digit], d[rnd_digit] & (lsb-1) gets the + trailing bits, and d[rnd_digit] & lsb gives the rounding bit. + + We initialize the double x to the integer given by digits + d[rnd_digit:m-1], but with the rounding bit and trailing bits of + d[rnd_digit] masked out. So the value of x comes from the top + DBL_MANT_DIG bits of v, multiplied by 2*lsb. Note that in the loop + that produces x, all floating-point operations are exact (assuming + that FLT_RADIX==2). Now if we're rounding down, the value we want + to return is simply + + x * 2**(PyLong_SHIFT * rnd_digit). + + and if we're rounding up, it's + + (x + 2*lsb) * 2**(PyLong_SHIFT * rnd_digit). + + Under the round-half-to-even rule, we round up if, and only + if, the rounding bit is set *and* at least one of the + following three conditions is satisfied: + + (1) the parity bit is set, or + (2) at least one of the trailing bits of d[rnd_digit] is set, or + (3) at least one of the digits d[i], 0 <= i < rnd_digit + is nonzero. + + Finally, we have to worry about overflow. If v >= 2**DBL_MAX_EXP, + or equivalently n > DBL_MAX_EXP, then overflow occurs. If v < + 2**DBL_MAX_EXP then we're usually safe, but there's a corner case + to consider: if v is very close to 2**DBL_MAX_EXP then it's + possible that v is rounded up to exactly 2**DBL_MAX_EXP, and then + again overflow occurs. + */ + + if (Py_SIZE(v) == 0) + return 0.0; + m = ABS(Py_SIZE(v)) - 1; + d = v->ob_digit; + assert(d[m]); /* v should be normalized */ + + /* fast path for case where 0 < abs(v) < 2**DBL_MANT_DIG */ + if (m < DBL_MANT_DIG / PyLong_SHIFT || + (m == DBL_MANT_DIG / PyLong_SHIFT && + d[m] < (digit)1 << DBL_MANT_DIG%PyLong_SHIFT)) { + x = d[m]; + while (--m >= 0) + x = x*PyLong_BASE + d[m]; + return Py_SIZE(v) < 0 ? -x : x; + } + + /* if m is huge then overflow immediately; otherwise, compute the + number of bits n in v. The condition below implies n (= #bits) >= + m * PyLong_SHIFT + 1 > DBL_MAX_EXP, hence v >= 2**DBL_MAX_EXP. */ + if (m > (DBL_MAX_EXP-1)/PyLong_SHIFT) goto overflow; - errno = 0; - x = ldexp(x, e * PyLong_SHIFT); - if (Py_OVERFLOWED(x)) + n = m * PyLong_SHIFT + bits_in_digit(d[m]); + if (n > DBL_MAX_EXP) goto overflow; - return x; -overflow: + /* find location of rounding bit */ + assert(n > DBL_MANT_DIG); /* dealt with |v| < 2**DBL_MANT_DIG above */ + rnd_bit = n - DBL_MANT_DIG - 1; + rnd_digit = rnd_bit/PyLong_SHIFT; + lsb = (digit)1 << (rnd_bit%PyLong_SHIFT); + + /* Get top DBL_MANT_DIG bits of v. Assumes PyLong_SHIFT < + DBL_MANT_DIG, so we'll need bits from at least 2 digits of v. */ + x = d[m]; + assert(m > rnd_digit); + while (--m > rnd_digit) + x = x*PyLong_BASE + d[m]; + x = x*PyLong_BASE + (d[m] & (PyLong_BASE-2*lsb)); + + /* decide whether to round up, using round-half-to-even */ + assert(m == rnd_digit); + if (d[m] & lsb) { /* if (rounding bit is set) */ + digit parity_bit; + if (lsb == PyLong_BASE/2) + parity_bit = d[m+1] & 1; + else + parity_bit = d[m] & 2*lsb; + if (parity_bit) + round_up = 1; + else if (d[m] & (lsb-1)) + round_up = 1; + else { + while (--m >= 0) { + if (d[m]) { + round_up = 1; + break; + } + } + } + } + + /* and round up if necessary */ + if (round_up) { + x += 2*lsb; + if (n == DBL_MAX_EXP && + x == ldexp((double)(2*lsb), DBL_MANT_DIG)) { + /* overflow corner case */ + goto overflow; + } + } + + /* shift, adjust for sign, and return */ + x = ldexp(x, rnd_digit*PyLong_SHIFT); + return Py_SIZE(v) < 0 ? -x : x; + + overflow: PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C double"); return -1.0; From python-checkins at python.org Mon Apr 20 23:38:54 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 20 Apr 2009 23:38:54 +0200 (CEST) Subject: [Python-checkins] r71774 - python/branches/release26-maint Message-ID: <20090420213854.AE8C01E4022@bag.python.org> Author: mark.dickinson Date: Mon Apr 20 23:38:54 2009 New Revision: 71774 Log: Blocked revisions 71772 via svnmerge ........ r71772 | mark.dickinson | 2009-04-20 22:13:33 +0100 (Mon, 20 Apr 2009) | 5 lines Issue #3166: Make long -> float (and int -> float) conversions correctly rounded, using round-half-to-even. This ensures that the value of float(n) doesn't depend on whether we're using 15-bit digits or 30-bit digits for Python longs. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Apr 20 23:39:40 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 20 Apr 2009 23:39:40 +0200 (CEST) Subject: [Python-checkins] r71775 - python/branches/release30-maint Message-ID: <20090420213940.11A9E1E4022@bag.python.org> Author: mark.dickinson Date: Mon Apr 20 23:39:39 2009 New Revision: 71775 Log: Blocked revisions 71773 via svnmerge ................ r71773 | mark.dickinson | 2009-04-20 22:38:00 +0100 (Mon, 20 Apr 2009) | 12 lines Merged revisions 71772 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71772 | mark.dickinson | 2009-04-20 22:13:33 +0100 (Mon, 20 Apr 2009) | 5 lines Issue #3166: Make long -> float (and int -> float) conversions correctly rounded, using round-half-to-even. This ensures that the value of float(n) doesn't depend on whether we're using 15-bit digits or 30-bit digits for Python longs. ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Mon Apr 20 23:41:04 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 20 Apr 2009 23:41:04 +0200 (CEST) Subject: [Python-checkins] r71776 - python/trunk/Lib/test/test_long.py Message-ID: <20090420214104.8C9C01E4022@bag.python.org> Author: mark.dickinson Date: Mon Apr 20 23:41:04 2009 New Revision: 71776 Log: Nit: integer division should use //, not / Modified: python/trunk/Lib/test/test_long.py Modified: python/trunk/Lib/test/test_long.py ============================================================================== --- python/trunk/Lib/test/test_long.py (original) +++ python/trunk/Lib/test/test_long.py Mon Apr 20 23:41:04 2009 @@ -681,7 +681,7 @@ # behaviour near extremes of floating-point range long_dbl_max = long(DBL_MAX) top_power = 2**DBL_MAX_EXP - halfway = (long_dbl_max + top_power)/2 + halfway = (long_dbl_max + top_power)//2 self.assertEqual(float(long_dbl_max), DBL_MAX) self.assertEqual(float(long_dbl_max+1), DBL_MAX) self.assertEqual(float(halfway-1), DBL_MAX) From python-checkins at python.org Mon Apr 20 23:41:28 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 20 Apr 2009 23:41:28 +0200 (CEST) Subject: [Python-checkins] r71777 - python/branches/release26-maint Message-ID: <20090420214128.DB2F11E4022@bag.python.org> Author: mark.dickinson Date: Mon Apr 20 23:41:28 2009 New Revision: 71777 Log: Blocked revisions 71776 via svnmerge ........ r71776 | mark.dickinson | 2009-04-20 22:41:04 +0100 (Mon, 20 Apr 2009) | 2 lines Nit: integer division should use //, not / ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Apr 20 23:42:05 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 20 Apr 2009 23:42:05 +0200 (CEST) Subject: [Python-checkins] r71778 - python/branches/py3k Message-ID: <20090420214205.0299F1E4022@bag.python.org> Author: mark.dickinson Date: Mon Apr 20 23:42:04 2009 New Revision: 71778 Log: Blocked revisions 71776 via svnmerge ........ r71776 | mark.dickinson | 2009-04-20 22:41:04 +0100 (Mon, 20 Apr 2009) | 2 lines Nit: integer division should use //, not / ........ Modified: python/branches/py3k/ (props changed) From buildbot at python.org Tue Apr 21 00:16:35 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 20 Apr 2009 22:16:35 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc trunk Message-ID: <20090420221635.DDD761E403F@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc trunk. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%20trunk/builds/312 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: mark.dickinson,raymond.hettinger,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posixpath sincerely, -The Buildbot From buildbot at python.org Tue Apr 21 01:24:37 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 20 Apr 2009 23:24:37 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090420232437.CA6381E401D@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/286 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 3 tests failed: test_distutils test_posix test_subprocess ====================================================================== FAIL: test_get_python_inc (distutils.tests.test_sysconfig.SysconfigTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/distutils/tests/test_sysconfig.py", line 45, in test_get_python_inc self.assert_(os.path.isdir(inc_dir), inc_dir) AssertionError: /home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/Include ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From python-checkins at python.org Tue Apr 21 05:09:17 2009 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 21 Apr 2009 05:09:17 +0200 (CEST) Subject: [Python-checkins] r71779 - in python/branches/py3k/Lib/json: __init__.py decoder.py tests/test_decode.py tests/test_unicode.py Message-ID: <20090421030917.CD7AE1E401D@bag.python.org> Author: raymond.hettinger Date: Tue Apr 21 05:09:17 2009 New Revision: 71779 Log: Forward port r70471: Add object_pairs_hook. Issue 5381. Modified: python/branches/py3k/Lib/json/__init__.py python/branches/py3k/Lib/json/decoder.py python/branches/py3k/Lib/json/tests/test_decode.py python/branches/py3k/Lib/json/tests/test_unicode.py Modified: python/branches/py3k/Lib/json/__init__.py ============================================================================== --- python/branches/py3k/Lib/json/__init__.py (original) +++ python/branches/py3k/Lib/json/__init__.py Tue Apr 21 05:09:17 2009 @@ -237,11 +237,12 @@ **kw).encode(obj) -_default_decoder = JSONDecoder(encoding=None, object_hook=None) +_default_decoder = JSONDecoder(encoding=None, object_hook=None, + object_pairs_hook=None) def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None, - parse_int=None, parse_constant=None, **kw): + parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing a JSON document) to a Python object. @@ -264,11 +265,11 @@ return loads(fp.read(), encoding=encoding, cls=cls, object_hook=object_hook, parse_float=parse_float, parse_int=parse_int, - parse_constant=parse_constant, **kw) + parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw) def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, - parse_int=None, parse_constant=None, **kw): + parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON document) to a Python object. @@ -303,12 +304,14 @@ """ if (cls is None and encoding is None and object_hook is None and parse_int is None and parse_float is None and - parse_constant is None and not kw): + parse_constant is None and object_pairs_hook is None and not kw): return _default_decoder.decode(s) if cls is None: cls = JSONDecoder if object_hook is not None: kw['object_hook'] = object_hook + if object_pairs_hook is not None: + kw['object_pairs_hook'] = object_pairs_hook if parse_float is not None: kw['parse_float'] = parse_float if parse_int is not None: Modified: python/branches/py3k/Lib/json/decoder.py ============================================================================== --- python/branches/py3k/Lib/json/decoder.py (original) +++ python/branches/py3k/Lib/json/decoder.py Tue Apr 21 05:09:17 2009 @@ -164,7 +164,8 @@ def JSONObject(match, context, _w=WHITESPACE.match): - pairs = {} + pairs = [] + pairs_append = pairs.append s = match.string end = _w(s, match.end()).end() nextchar = s[end:end + 1] @@ -187,7 +188,7 @@ value, end = next(iterscan(s, idx=end, context=context)) except StopIteration: raise ValueError(errmsg("Expecting object", s, end)) - pairs[key] = value + pairs_append((key, value)) end = _w(s, end).end() nextchar = s[end:end + 1] end += 1 @@ -200,6 +201,11 @@ end += 1 if nextchar != '"': raise ValueError(errmsg("Expecting property name", s, end - 1)) + object_pairs_hook = getattr(context, 'object_pairs_hook', None) + if object_pairs_hook is not None: + result = object_pairs_hook(pairs) + return result, end + pairs = dict(pairs) object_hook = getattr(context, 'object_hook', None) if object_hook is not None: pairs = object_hook(pairs) @@ -278,7 +284,8 @@ __all__ = ['__init__', 'decode', 'raw_decode'] def __init__(self, encoding=None, object_hook=None, parse_float=None, - parse_int=None, parse_constant=None, strict=True): + parse_int=None, parse_constant=None, strict=True, + object_pairs_hook=None): """``encoding`` determines the encoding used to interpret any ``str`` objects decoded by this instance (utf-8 by default). It has no effect when decoding ``unicode`` objects. @@ -309,6 +316,7 @@ """ self.encoding = encoding self.object_hook = object_hook + self.object_pairs_hook = object_pairs_hook self.parse_float = parse_float self.parse_int = parse_int self.parse_constant = parse_constant Modified: python/branches/py3k/Lib/json/tests/test_decode.py ============================================================================== --- python/branches/py3k/Lib/json/tests/test_decode.py (original) +++ python/branches/py3k/Lib/json/tests/test_decode.py Tue Apr 21 05:09:17 2009 @@ -1,7 +1,9 @@ import decimal from unittest import TestCase +from io import StringIO import json +from collections import OrderedDict class TestDecode(TestCase): def test_decimal(self): @@ -13,3 +15,20 @@ rval = json.loads('1', parse_int=float) self.assert_(isinstance(rval, float)) self.assertEquals(rval, 1.0) + + def test_object_pairs_hook(self): + s = '{"xkd":1, "kcw":2, "art":3, "hxm":4, "qrt":5, "pad":6, "hoy":7}' + p = [("xkd", 1), ("kcw", 2), ("art", 3), ("hxm", 4), + ("qrt", 5), ("pad", 6), ("hoy", 7)] + self.assertEqual(json.loads(s), eval(s)) + self.assertEqual(json.loads(s, object_pairs_hook = lambda x: x), p) + self.assertEqual(json.load(StringIO(s), + object_pairs_hook=lambda x: x), p) + od = json.loads(s, object_pairs_hook = OrderedDict) + self.assertEqual(od, OrderedDict(p)) + self.assertEqual(type(od), OrderedDict) + # the object_pairs_hook takes priority over the object_hook + self.assertEqual(json.loads(s, + object_pairs_hook = OrderedDict, + object_hook = lambda x: None), + OrderedDict(p)) Modified: python/branches/py3k/Lib/json/tests/test_unicode.py ============================================================================== --- python/branches/py3k/Lib/json/tests/test_unicode.py (original) +++ python/branches/py3k/Lib/json/tests/test_unicode.py Tue Apr 21 05:09:17 2009 @@ -1,6 +1,7 @@ from unittest import TestCase import json +from collections import OrderedDict class TestUnicode(TestCase): def test_encoding1(self): @@ -53,3 +54,18 @@ u = chr(i) js = '"\\u{0:04x}"'.format(i) self.assertEquals(json.loads(js), u) + + def test_object_pairs_hook_with_unicode(self): + s = '{"xkd":1, "kcw":2, "art":3, "hxm":4, "qrt":5, "pad":6, "hoy":7}' + p = [("xkd", 1), ("kcw", 2), ("art", 3), ("hxm", 4), + ("qrt", 5), ("pad", 6), ("hoy", 7)] + self.assertEqual(json.loads(s), eval(s)) + self.assertEqual(json.loads(s, object_pairs_hook = lambda x: x), p) + od = json.loads(s, object_pairs_hook = OrderedDict) + self.assertEqual(od, OrderedDict(p)) + self.assertEqual(type(od), OrderedDict) + # the object_pairs_hook takes priority over the object_hook + self.assertEqual(json.loads(s, + object_pairs_hook = OrderedDict, + object_hook = lambda x: None), + OrderedDict(p)) From python-checkins at python.org Tue Apr 21 05:24:19 2009 From: python-checkins at python.org (senthil.kumaran) Date: Tue, 21 Apr 2009 05:24:19 +0200 (CEST) Subject: [Python-checkins] r71780 - in python/trunk/Lib: test/test_urllib.py urllib.py Message-ID: <20090421032419.3FCFD1E401D@bag.python.org> Author: senthil.kumaran Date: Tue Apr 21 05:24:19 2009 New Revision: 71780 Log: Fix for the Issue918368 - urllib doesn't correct server returned urls Modified: python/trunk/Lib/test/test_urllib.py python/trunk/Lib/urllib.py Modified: python/trunk/Lib/test/test_urllib.py ============================================================================== --- python/trunk/Lib/test/test_urllib.py (original) +++ python/trunk/Lib/test/test_urllib.py Tue Apr 21 05:24:19 2009 @@ -598,6 +598,18 @@ self.assertEqual(('user', 'a:b'),urllib.splitpasswd('user:a:b')) +class URLopener_Tests(unittest.TestCase): + """Testcase to test the open method of URLopener class.""" + + def test_quoted_open(self): + class DummyURLopener(urllib.URLopener): + def open_spam(self, url): + return url + + self.assertEqual(DummyURLopener().open( + 'spam://example/ /'),'//example/%20/') + + # Just commented them out. # Can't really tell why keep failing in windows and sparc. # Everywhere else they work ok, but on those machines, someteimes @@ -693,6 +705,7 @@ urlencode_Tests, Pathname_Tests, Utility_Tests, + URLopener_Tests, #FTPWrapperTests, ) Modified: python/trunk/Lib/urllib.py ============================================================================== --- python/trunk/Lib/urllib.py (original) +++ python/trunk/Lib/urllib.py Tue Apr 21 05:24:19 2009 @@ -176,6 +176,9 @@ def open(self, fullurl, data=None): """Use URLopener().open(file) instead of open(file, 'r').""" fullurl = unwrap(toBytes(fullurl)) + # percent encode url, fixing lame server errors for e.g, like space + # within url paths. + fullurl = quote(fullurl, safe="%/:=&?~#+!$,;'@()*[]") if self.tempcache and fullurl in self.tempcache: filename, headers = self.tempcache[fullurl] fp = open(filename, 'rb') From python-checkins at python.org Tue Apr 21 05:27:13 2009 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 21 Apr 2009 05:27:13 +0200 (CEST) Subject: [Python-checkins] r71781 - python/branches/py3k/Doc/library/json.rst Message-ID: <20090421032713.2B5721E411B@bag.python.org> Author: raymond.hettinger Date: Tue Apr 21 05:27:12 2009 New Revision: 71781 Log: Forward port r70471: Add object_pairs_hook. Issue 5381. Modified: python/branches/py3k/Doc/library/json.rst Modified: python/branches/py3k/Doc/library/json.rst ============================================================================== --- python/branches/py3k/Doc/library/json.rst (original) +++ python/branches/py3k/Doc/library/json.rst Tue Apr 21 05:27:12 2009 @@ -165,7 +165,7 @@ :func:`dump`. -.. function:: load(fp[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, **kw]]]]]]]) +.. function:: load(fp[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]]) Deserialize *fp* (a ``.read()``-supporting file-like object containing a JSON document) to a Python object. @@ -181,6 +181,17 @@ *object_hook* will be used instead of the :class:`dict`. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting). + *object_pairs_hook* is an optional function that will be called with the + result of any object literal decode with an ordered list of pairs. The + return value of *object_pairs_hook* will be used instead of the + :class:`dict`. This feature can be used to implement custom decoders that + rely on the order that the key and value pairs are decoded (for example, + :func:`collections.OrderedDict` will remember the order of insertion). If + *object_hook* is also defined, the *object_pairs_hook* takes priority. + + .. versionchanged:: 3.1 + Added support for *object_pairs_hook*. + *parse_float*, if specified, will be called with the string of every JSON float to be decoded. By default, this is equivalent to ``float(num_str)``. This can be used to use another datatype or parser for JSON floats @@ -201,7 +212,7 @@ class. -.. function:: loads(s[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, **kw]]]]]]]) +.. function:: loads(s[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]]) Deserialize *s* (a :class:`str` or :class:`unicode` instance containing a JSON document) to a Python object. @@ -217,7 +228,7 @@ Encoders and decoders --------------------- -.. class:: JSONDecoder([encoding[, object_hook[, parse_float[, parse_int[, parse_constant[, strict]]]]]]) +.. class:: JSONDecoder([encoding[, object_hook[, parse_float[, parse_int[, parse_constant[, strict[, object_pairs_hook]]]]]]]) Simple JSON decoder. @@ -258,6 +269,17 @@ :class:`dict`. This can be used to provide custom deserializations (e.g. to support JSON-RPC class hinting). + *object_pairs_hook*, if specified will be called with the result of every + JSON object decoded with an ordered list of pairs. The return value of + *object_pairs_hook* will be used instead of the :class:`dict`. This + feature can be used to implement custom decoders that rely on the order + that the key and value pairs are decoded (for example, + :func:`collections.OrderedDict` will remember the order of insertion). If + *object_hook* is also defined, the *object_pairs_hook* takes priority. + + .. versionchanged:: 3.1 + Added support for *object_pairs_hook*. + *parse_float*, if specified, will be called with the string of every JSON float to be decoded. By default, this is equivalent to ``float(num_str)``. This can be used to use another datatype or parser for JSON floats From python-checkins at python.org Tue Apr 21 05:43:15 2009 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 21 Apr 2009 05:43:15 +0200 (CEST) Subject: [Python-checkins] r71782 - in python/branches/py3k: Doc/library/decimal.rst Lib/decimal.py Message-ID: <20090421034315.8A9941E401D@bag.python.org> Author: raymond.hettinger Date: Tue Apr 21 05:43:15 2009 New Revision: 71782 Log: Update links and version info. Modified: python/branches/py3k/Doc/library/decimal.rst python/branches/py3k/Lib/decimal.py Modified: python/branches/py3k/Doc/library/decimal.rst ============================================================================== --- python/branches/py3k/Doc/library/decimal.rst (original) +++ python/branches/py3k/Doc/library/decimal.rst Tue Apr 21 05:43:15 2009 @@ -103,7 +103,7 @@ .. seealso:: * IBM's General Decimal Arithmetic Specification, `The General Decimal Arithmetic - Specification `_. + Specification `_. * IEEE standard 854-1987, `Unofficial IEEE 854 Text `_. Modified: python/branches/py3k/Lib/decimal.py ============================================================================== --- python/branches/py3k/Lib/decimal.py (original) +++ python/branches/py3k/Lib/decimal.py Tue Apr 21 05:43:15 2009 @@ -17,7 +17,7 @@ This is an implementation of decimal floating point arithmetic based on the General Decimal Arithmetic Specification: - www2.hursley.ibm.com/decimal/decarith.html + http://speleotrove.com/decimal/decarith.html and IEEE standard 854-1987: @@ -130,6 +130,8 @@ 'setcontext', 'getcontext', 'localcontext' ] +__version__ = '1.70' # Highest version of the spec this complies with + import copy as _copy import math as _math import numbers as _numbers From python-checkins at python.org Tue Apr 21 13:57:38 2009 From: python-checkins at python.org (eric.smith) Date: Tue, 21 Apr 2009 13:57:38 +0200 (CEST) Subject: [Python-checkins] r71783 - python/branches/py3k/Python/marshal.c Message-ID: <20090421115738.591EF1E4011@bag.python.org> Author: eric.smith Date: Tue Apr 21 13:57:38 2009 New Revision: 71783 Log: Added handling of PyOS_double_to_string out-of-memory errors. Closes issue 5775. Modified: python/branches/py3k/Python/marshal.c Modified: python/branches/py3k/Python/marshal.c ============================================================================== --- python/branches/py3k/Python/marshal.c (original) +++ python/branches/py3k/Python/marshal.c Tue Apr 21 13:57:38 2009 @@ -47,9 +47,14 @@ #define TYPE_SET '<' #define TYPE_FROZENSET '>' +#define WFERR_OK 0 +#define WFERR_UNMARSHALLABLE 1 +#define WFERR_NESTEDTOODEEP 2 +#define WFERR_NOMEMORY 3 + typedef struct { FILE *fp; - int error; + int error; /* see WFERR_* values */ int depth; /* If fp == NULL, the following are valid: */ PyObject *str; @@ -182,7 +187,7 @@ p->depth++; if (p->depth > MAX_MARSHAL_STACK_DEPTH) { - p->error = 2; + p->error = WFERR_NESTEDTOODEEP; } else if (v == NULL) { w_byte(TYPE_NULL, p); @@ -229,7 +234,7 @@ unsigned char buf[8]; if (_PyFloat_Pack8(PyFloat_AsDouble(v), buf, 1) < 0) { - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; return; } w_byte(TYPE_BINARY_FLOAT, p); @@ -238,8 +243,10 @@ else { char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v), 'g', 17, 0, NULL); - if (!buf) - return; + if (!buf) { + p->error = WFERR_NOMEMORY; + return; + } n = strlen(buf); w_byte(TYPE_FLOAT, p); w_byte((int)n, p); @@ -253,14 +260,14 @@ unsigned char buf[8]; if (_PyFloat_Pack8(PyComplex_RealAsDouble(v), buf, 1) < 0) { - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; return; } w_byte(TYPE_BINARY_COMPLEX, p); w_string((char*)buf, 8, p); if (_PyFloat_Pack8(PyComplex_ImagAsDouble(v), buf, 1) < 0) { - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; return; } w_string((char*)buf, 8, p); @@ -270,16 +277,20 @@ w_byte(TYPE_COMPLEX, p); buf = PyOS_double_to_string(PyComplex_RealAsDouble(v), 'g', 17, 0, NULL); - if (!buf) - return; + if (!buf) { + p->error = WFERR_NOMEMORY; + return; + } n = strlen(buf); w_byte((int)n, p); w_string(buf, (int)n, p); PyMem_Free(buf); buf = PyOS_double_to_string(PyComplex_ImagAsDouble(v), 'g', 17, 0, NULL); - if (!buf) - return; + if (!buf) { + p->error = WFERR_NOMEMORY; + return; + } n = strlen(buf); w_byte((int)n, p); w_string(buf, (int)n, p); @@ -293,7 +304,7 @@ if (n > INT_MAX) { /* huge strings are not supported */ p->depth--; - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; return; } w_long((long)n, p); @@ -304,14 +315,14 @@ utf8 = PyUnicode_AsUTF8String(v); if (utf8 == NULL) { p->depth--; - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; return; } w_byte(TYPE_UNICODE, p); n = PyBytes_GET_SIZE(utf8); if (n > INT_MAX) { p->depth--; - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; return; } w_long((long)n, p); @@ -356,14 +367,14 @@ n = PyObject_Size(v); if (n == -1) { p->depth--; - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; return; } w_long((long)n, p); it = PyObject_GetIter(v); if (it == NULL) { p->depth--; - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; return; } while ((value = PyIter_Next(it)) != NULL) { @@ -373,7 +384,7 @@ Py_DECREF(it); if (PyErr_Occurred()) { p->depth--; - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; return; } } @@ -403,14 +414,14 @@ Py_buffer view; if ((*pb->bf_getbuffer)(v, &view, PyBUF_SIMPLE) != 0) { w_byte(TYPE_UNKNOWN, p); - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; } w_byte(TYPE_STRING, p); n = view.len; s = view.buf; if (n > INT_MAX) { p->depth--; - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; return; } w_long((long)n, p); @@ -420,7 +431,7 @@ } else { w_byte(TYPE_UNKNOWN, p); - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; } p->depth--; } @@ -431,7 +442,7 @@ { WFILE wf; wf.fp = fp; - wf.error = 0; + wf.error = WFERR_OK; wf.depth = 0; wf.strings = NULL; wf.version = version; @@ -443,7 +454,7 @@ { WFILE wf; wf.fp = fp; - wf.error = 0; + wf.error = WFERR_OK; wf.depth = 0; wf.strings = (version > 0) ? PyDict_New() : NULL; wf.version = version; @@ -1143,7 +1154,7 @@ return NULL; wf.ptr = PyBytes_AS_STRING((PyBytesObject *)wf.str); wf.end = wf.ptr + PyBytes_Size(wf.str); - wf.error = 0; + wf.error = WFERR_OK; wf.depth = 0; wf.version = version; wf.strings = (version > 0) ? PyDict_New() : NULL; @@ -1160,11 +1171,14 @@ if (_PyBytes_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)) < 0) return NULL; } - if (wf.error) { + if (wf.error != WFERR_OK) { Py_XDECREF(wf.str); - PyErr_SetString(PyExc_ValueError, - (wf.error==1)?"unmarshallable object" - :"object too deeply nested to marshal"); + if (wf.error == WFERR_NOMEMORY) + PyErr_NoMemory(); + else + PyErr_SetString(PyExc_ValueError, + (wf.error==WFERR_UNMARSHALLABLE)?"unmarshallable object" + :"object too deeply nested to marshal"); return NULL; } if (wf.str != NULL) { From python-checkins at python.org Tue Apr 21 13:58:48 2009 From: python-checkins at python.org (eric.smith) Date: Tue, 21 Apr 2009 13:58:48 +0200 (CEST) Subject: [Python-checkins] r71784 - python/branches/release30-maint Message-ID: <20090421115848.A6A441E4011@bag.python.org> Author: eric.smith Date: Tue Apr 21 13:58:48 2009 New Revision: 71784 Log: Blocked revisions 71783 via svnmerge ........ r71783 | eric.smith | 2009-04-21 07:57:38 -0400 (Tue, 21 Apr 2009) | 1 line Added handling of PyOS_double_to_string out-of-memory errors. Closes issue 5775. ........ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Tue Apr 21 15:06:04 2009 From: python-checkins at python.org (r.david.murray) Date: Tue, 21 Apr 2009 15:06:04 +0200 (CEST) Subject: [Python-checkins] r71785 - in python/trunk/Lib/test: test_posix.py test_pty.py Message-ID: <20090421130604.B548F1E4038@bag.python.org> Author: r.david.murray Date: Tue Apr 21 15:06:04 2009 New Revision: 71785 Log: Restore skips of posix and pty tests on Windows by calling the test_support.import_module on the appropriate modules before any other imports. Modified: python/trunk/Lib/test/test_posix.py python/trunk/Lib/test/test_pty.py Modified: python/trunk/Lib/test/test_posix.py ============================================================================== --- python/trunk/Lib/test/test_posix.py (original) +++ python/trunk/Lib/test/test_posix.py Tue Apr 21 15:06:04 2009 @@ -2,6 +2,8 @@ from test import test_support +# Skip these tests if there is no posix module. +posix = test_support.import_module('posix') import time import os @@ -10,7 +12,6 @@ import unittest import warnings -posix = test_support.import_module('posix') warnings.filterwarnings('ignore', '.* potential security risk .*', RuntimeWarning) Modified: python/trunk/Lib/test/test_pty.py ============================================================================== --- python/trunk/Lib/test/test_pty.py (original) +++ python/trunk/Lib/test/test_pty.py Tue Apr 21 15:06:04 2009 @@ -1,10 +1,14 @@ +from test.test_support import verbose, run_unittest, import_module + +#Skip these tests if either fcntl or termios is not available +fcntl = import_module('fcntl') +import_module('termios') + import errno -import fcntl import pty import os import sys import signal -from test.test_support import verbose, run_unittest import unittest TEST_STRING_1 = "I wish to buy a fish license.\n" From buildbot at python.org Tue Apr 21 16:35:19 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 21 Apr 2009 14:35:19 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc trunk Message-ID: <20090421143519.757AB1E4035@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc trunk. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%20trunk/builds/315 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posixpath sincerely, -The Buildbot From python-checkins at python.org Tue Apr 21 20:23:08 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 21 Apr 2009 20:23:08 +0200 (CEST) Subject: [Python-checkins] r71786 - python/trunk/Doc/library/threading.rst Message-ID: <20090421182308.506E31E401F@bag.python.org> Author: georg.brandl Date: Tue Apr 21 20:23:08 2009 New Revision: 71786 Log: #5757: fix copy-paste error in notify(). Modified: python/trunk/Doc/library/threading.rst Modified: python/trunk/Doc/library/threading.rst ============================================================================== --- python/trunk/Doc/library/threading.rst (original) +++ python/trunk/Doc/library/threading.rst Tue Apr 21 20:23:08 2009 @@ -555,12 +555,12 @@ .. method:: Condition.notify() - Wake up a thread waiting on this condition, if any. Wait until notified or until - a timeout occurs. If the calling thread has not acquired the lock when this - method is called, a :exc:`RuntimeError` is raised. + Wake up a thread waiting on this condition, if any. If the calling thread + has not acquired the lock when this method is called, a :exc:`RuntimeError` + is raised. - This method wakes up one of the threads waiting for the condition variable, if - any are waiting; it is a no-op if no threads are waiting. + This method wakes up one of the threads waiting for the condition variable, + if any are waiting; it is a no-op if no threads are waiting. The current implementation wakes up exactly one thread, if any are waiting. However, it's not safe to rely on this behavior. A future, optimized From python-checkins at python.org Tue Apr 21 20:24:34 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 21 Apr 2009 20:24:34 +0200 (CEST) Subject: [Python-checkins] r71787 - python/trunk/Doc/library/functions.rst Message-ID: <20090421182434.87B941E401F@bag.python.org> Author: georg.brandl Date: Tue Apr 21 20:24:34 2009 New Revision: 71787 Log: #5751: fix escaping of \\n. Modified: python/trunk/Doc/library/functions.rst Modified: python/trunk/Doc/library/functions.rst ============================================================================== --- python/trunk/Doc/library/functions.rst (original) +++ python/trunk/Doc/library/functions.rst Tue Apr 21 20:24:34 2009 @@ -830,7 +830,7 @@ accidents.) -.. function:: print([object, ...][, sep=' '][, end='\n'][, file=sys.stdout]) +.. function:: print([object, ...][, sep=' '][, end='\\n'][, file=sys.stdout]) Print *object*\(s) to the stream *file*, separated by *sep* and followed by *end*. *sep*, *end* and *file*, if present, must be given as keyword From python-checkins at python.org Wed Apr 22 02:47:00 2009 From: python-checkins at python.org (eric.smith) Date: Wed, 22 Apr 2009 02:47:00 +0200 (CEST) Subject: [Python-checkins] r71788 - in python/trunk/Doc: ACKS.txt library/string.rst Message-ID: <20090422004700.40B651E4011@bag.python.org> Author: eric.smith Date: Wed Apr 22 02:47:00 2009 New Revision: 71788 Log: Documentation for issue 5237, auto-numbered format fields. Contributed by Terry J. Reedy. Modified: python/trunk/Doc/ACKS.txt python/trunk/Doc/library/string.rst Modified: python/trunk/Doc/ACKS.txt ============================================================================== --- python/trunk/Doc/ACKS.txt (original) +++ python/trunk/Doc/ACKS.txt Wed Apr 22 02:47:00 2009 @@ -156,6 +156,7 @@ * Paul Prescod * Eric S. Raymond * Edward K. Ream + * Terry J. Reedy * Sean Reifschneider * Bernhard Reiter * Armin Rigo Modified: python/trunk/Doc/library/string.rst ============================================================================== --- python/trunk/Doc/library/string.rst (original) +++ python/trunk/Doc/library/string.rst Wed Apr 22 02:47:00 2009 @@ -221,21 +221,26 @@ .. productionlist:: sf replacement_field: "{" `field_name` ["!" `conversion`] [":" `format_spec`] "}" - field_name: (`identifier` | `integer`) ("." `attribute_name` | "[" `element_index` "]")* + field_name: arg_name ("." `attribute_name` | "[" `element_index` "]")* + arg_name: (`identifier` | `integer`)? attribute_name: `identifier` element_index: `integer` conversion: "r" | "s" format_spec: -In less formal terms, the replacement field starts with a *field_name*, which -can either be a number (for a positional argument), or an identifier (for -keyword arguments). Following this is an optional *conversion* field, which is +In less formal terms, the replacement field starts with a *field_name* that specifies +the object whose value is to be formatted and inserted +into the output instead of the replacement field. +The *field_name* is optionally followed by a *conversion* field, which is preceded by an exclamation point ``'!'``, and a *format_spec*, which is preceded -by a colon ``':'``. +by a colon ``':'``. These specify a non-default format for the replacement value. -The *field_name* itself begins with either a number or a keyword. If it's a -number, it refers to a positional argument, and if it's a keyword it refers to a -named keyword argument. This can be followed by any number of index or +The *field_name* itself begins with an *arg_name* that is either either a number or a +keyword. If it's a number, it refers to a positional argument, and if it's a keyword, +it refers to a named keyword argument. If the numerical arg_names in a format string +are 0, 1, 2, ... in sequence, they can all be omitted (not just some) +and the numbers 0, 1, 2, ... will be automatically inserted in that order. +The *arg_name* can be followed by any number of index or attribute expressions. An expression of the form ``'.name'`` selects the named attribute using :func:`getattr`, while an expression of the form ``'[index]'`` does an index lookup using :func:`__getitem__`. @@ -244,6 +249,7 @@ "First, thou shalt count to {0}" # References first positional argument "Bring me a {}" # Implicitly references the first positional argument + "From {} to {}" # Same as "From {0] to {1}" "My quest is {name}" # References keyword argument 'name' "Weight in tons {0.weight}" # 'weight' attribute of first positional arg "Units destroyed: {players[0]}" # First element of keyword argument 'players'. From python-checkins at python.org Wed Apr 22 02:48:42 2009 From: python-checkins at python.org (eric.smith) Date: Wed, 22 Apr 2009 02:48:42 +0200 (CEST) Subject: [Python-checkins] r71789 - python/branches/release26-maint Message-ID: <20090422004842.9FCA71E4011@bag.python.org> Author: eric.smith Date: Wed Apr 22 02:48:42 2009 New Revision: 71789 Log: Blocked revisions 71788 via svnmerge ........ r71788 | eric.smith | 2009-04-21 20:47:00 -0400 (Tue, 21 Apr 2009) | 1 line Documentation for issue 5237, auto-numbered format fields. Contributed by Terry J. Reedy. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Wed Apr 22 02:53:01 2009 From: python-checkins at python.org (eric.smith) Date: Wed, 22 Apr 2009 02:53:01 +0200 (CEST) Subject: [Python-checkins] r71790 - in python/branches/py3k: Doc/ACKS.txt Doc/library/string.rst Message-ID: <20090422005301.E982E1E401F@bag.python.org> Author: eric.smith Date: Wed Apr 22 02:53:01 2009 New Revision: 71790 Log: Merged revisions 71788 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71788 | eric.smith | 2009-04-21 20:47:00 -0400 (Tue, 21 Apr 2009) | 1 line Documentation for issue 5237, auto-numbered format fields. Contributed by Terry J. Reedy. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/ACKS.txt python/branches/py3k/Doc/library/string.rst Modified: python/branches/py3k/Doc/ACKS.txt ============================================================================== --- python/branches/py3k/Doc/ACKS.txt (original) +++ python/branches/py3k/Doc/ACKS.txt Wed Apr 22 02:53:01 2009 @@ -157,6 +157,7 @@ * Paul Prescod * Eric S. Raymond * Edward K. Ream + * Terry J. Reedy * Sean Reifschneider * Bernhard Reiter * Armin Rigo Modified: python/branches/py3k/Doc/library/string.rst ============================================================================== --- python/branches/py3k/Doc/library/string.rst (original) +++ python/branches/py3k/Doc/library/string.rst Wed Apr 22 02:53:01 2009 @@ -196,21 +196,26 @@ .. productionlist:: sf replacement_field: "{" `field_name` ["!" `conversion`] [":" `format_spec`] "}" - field_name: (`identifier` | `integer`) ("." `attribute_name` | "[" `element_index` "]")* + field_name: arg_name ("." `attribute_name` | "[" `element_index` "]")* + arg_name: (`identifier` | `integer`)? attribute_name: `identifier` element_index: `integer` conversion: "r" | "s" | "a" format_spec: -In less formal terms, the replacement field starts with a *field_name*, which -can either be a number (for a positional argument), or an identifier (for -keyword arguments). Following this is an optional *conversion* field, which is +In less formal terms, the replacement field starts with a *field_name* that specifies +the object whose value is to be formatted and inserted +into the output instead of the replacement field. +The *field_name* is optionally followed by a *conversion* field, which is preceded by an exclamation point ``'!'``, and a *format_spec*, which is preceded -by a colon ``':'``. +by a colon ``':'``. These specify a non-default format for the replacement value. -The *field_name* itself begins with either a number or a keyword. If it's a -number, it refers to a positional argument, and if it's a keyword it refers to a -named keyword argument. This can be followed by any number of index or +The *field_name* itself begins with an *arg_name* that is either either a number or a +keyword. If it's a number, it refers to a positional argument, and if it's a keyword, +it refers to a named keyword argument. If the numerical arg_names in a format string +are 0, 1, 2, ... in sequence, they can all be omitted (not just some) +and the numbers 0, 1, 2, ... will be automatically inserted in that order. +The *arg_name* can be followed by any number of index or attribute expressions. An expression of the form ``'.name'`` selects the named attribute using :func:`getattr`, while an expression of the form ``'[index]'`` does an index lookup using :func:`__getitem__`. @@ -219,6 +224,7 @@ "First, thou shalt count to {0}" # References first positional argument "Bring me a {}" # Implicitly references the first positional argument + "From {} to {}" # Same as "From {0] to {1}" "My quest is {name}" # References keyword argument 'name' "Weight in tons {0.weight}" # 'weight' attribute of first positional arg "Units destroyed: {players[0]}" # First element of keyword argument 'players'. From python-checkins at python.org Wed Apr 22 02:54:07 2009 From: python-checkins at python.org (eric.smith) Date: Wed, 22 Apr 2009 02:54:07 +0200 (CEST) Subject: [Python-checkins] r71791 - python/branches/release30-maint Message-ID: <20090422005407.7A6D71E4018@bag.python.org> Author: eric.smith Date: Wed Apr 22 02:54:07 2009 New Revision: 71791 Log: Blocked revisions 71790 via svnmerge ................ r71790 | eric.smith | 2009-04-21 20:53:01 -0400 (Tue, 21 Apr 2009) | 9 lines Merged revisions 71788 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71788 | eric.smith | 2009-04-21 20:47:00 -0400 (Tue, 21 Apr 2009) | 1 line Documentation for issue 5237, auto-numbered format fields. Contributed by Terry J. Reedy. ........ ................ Modified: python/branches/release30-maint/ (props changed) From buildbot at python.org Wed Apr 22 03:26:42 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 22 Apr 2009 01:26:42 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 2.6 Message-ID: <20090422012642.C6D7A1E4011@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%202.6/builds/238 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: eric.smith BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From buildbot at python.org Wed Apr 22 03:41:34 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 22 Apr 2009 01:41:34 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 2.6 Message-ID: <20090422014134.BED831E4018@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%202.6/builds/270 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: eric.smith BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From buildbot at python.org Wed Apr 22 03:41:49 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 22 Apr 2009 01:41:49 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 2.6 Message-ID: <20090422014149.A6B4B1E4018@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%202.6/builds/264 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: eric.smith BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From buildbot at python.org Wed Apr 22 03:42:53 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 22 Apr 2009 01:42:53 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 2.6 Message-ID: <20090422014253.AE3851E4018@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%202.6/builds/261 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: eric.smith BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_bsddb3 make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Wed Apr 22 04:24:39 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 22 Apr 2009 04:24:39 +0200 (CEST) Subject: [Python-checkins] r71792 - in python/branches/py3k: Lib/test/test_posix.py Lib/test/test_pty.py Message-ID: <20090422022439.9BFFB1E4011@bag.python.org> Author: r.david.murray Date: Wed Apr 22 04:24:39 2009 New Revision: 71792 Log: Merged revisions 71785 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71785 | r.david.murray | 2009-04-21 09:06:04 -0400 (Tue, 21 Apr 2009) | 4 lines Restore skips of posix and pty tests on Windows by calling the test_support.import_module on the appropriate modules before any other imports. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_posix.py python/branches/py3k/Lib/test/test_pty.py Modified: python/branches/py3k/Lib/test/test_posix.py ============================================================================== --- python/branches/py3k/Lib/test/test_posix.py (original) +++ python/branches/py3k/Lib/test/test_posix.py Wed Apr 22 04:24:39 2009 @@ -1,7 +1,9 @@ "Test posix functions" from test import support -posix = support.import_module('posix') #skip if not supported + +# Skip these tests if there is no posix module. +posix = support.import_module('posix') import time import os Modified: python/branches/py3k/Lib/test/test_pty.py ============================================================================== --- python/branches/py3k/Lib/test/test_pty.py (original) +++ python/branches/py3k/Lib/test/test_pty.py Wed Apr 22 04:24:39 2009 @@ -1,11 +1,14 @@ -from test import support -pty = support.import_module("pty") #skip if not supported +from test.support import verbose, run_unittest, import_module + +#Skip these tests if either fcntl or termios is not available +fcntl = import_module('fcntl') +import_module('termios') + import errno -import fcntl +import pty import os import sys import signal -from test.support import verbose, run_unittest import unittest TEST_STRING_1 = b"I wish to buy a fish license.\n" From buildbot at python.org Wed Apr 22 04:27:03 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 22 Apr 2009 02:27:03 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090422022703.BEB231E4011@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/560 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: eric.smith BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_posix test_posixpath ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 249, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 143, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== ERROR: test_realpath_basic (test.test_posixpath.PosixPathTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posixpath.py", line 504, in test_realpath_basic os.symlink(ABSTFN+"1", ABSTFN) OSError: [Errno 17] File exists sincerely, -The Buildbot From buildbot at python.org Wed Apr 22 05:17:22 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 22 Apr 2009 03:17:22 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090422031722.7D51C1E4011@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/288 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: eric.smith BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_posix test_smtplib ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From buildbot at python.org Wed Apr 22 05:36:59 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 22 Apr 2009 03:36:59 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090422033659.CCE6D1E4011@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/624 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_mailbox make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Wed Apr 22 08:42:07 2009 From: python-checkins at python.org (martin.v.loewis) Date: Wed, 22 Apr 2009 08:42:07 +0200 (CEST) Subject: [Python-checkins] r71793 - peps/trunk/pep-0383.txt Message-ID: <20090422064207.0E02B1E4011@bag.python.org> Author: martin.v.loewis Date: Wed Apr 22 08:42:06 2009 New Revision: 71793 Log: Add PEP 383. Added: peps/trunk/pep-0383.txt (contents, props changed) Added: peps/trunk/pep-0383.txt ============================================================================== --- (empty file) +++ peps/trunk/pep-0383.txt Wed Apr 22 08:42:06 2009 @@ -0,0 +1,118 @@ +PEP: 383 +Title: Non-decodable Bytes in System Character Interfaces +Version: $Revision$ +Last-Modified: $Date$ +Author: Martin v. L?wis +Status: Draft +Type: Standards Track +Content-Type: text/x-rst +Created: 22-Apr-2009 +Python-Version: 3.1 +Post-History: + +Abstract +======== + +File names, environment variables, and command line arguments are +defined as being character data in POSIX; the C APIs however allow +passing arbitrary bytes - whether these conform to a certain encoding +or not. This PEP proposes a means of dealing with such irregularities +by embedding the bytes in character strings in such a way that allows +recreation of the original byte string. + +Rationale +========= + +The C char type is a data type that is commonly used to represent both +character data and bytes. Certain POSIX interfaces are specified and +widely understood as operating on character data, however, the system +call interfaces make no assumption on the encoding of these data, and +pass them on as-is. With Python 3, character strings use a +Unicode-based internal representation, making it difficult to ignore +the encoding of byte strings in the same way that the C interfaces can +ignore the encoding. + +On the other hand, Microsoft Windows NT has correct the original +design limitation of Unix, and made it explicit in its system +interfaces that these data (file names, environment variables, command +line arguments) are indeed character data, by providing a +Unicode-based API (keeping a C-char-based one for backwards +compatibility). + +For Python 3, one proposed solution is to provide two sets of APIs: a +byte-oriented one, and a character-oriented one, where the +character-oriented one would be limited to not being able to represent +all data accurately. Unfortunately, for Windows, the situation would +be exactly the opposite: the byte-oriented interface cannot represent +all data; only the character-oriented API can. As a consequence, +libraries and applications that want to support all user data in a +cross-platform manner have to accept mish-mash of bytes and characters +exactly in the way that caused endless troubles for Python 2.x. + +With this PEP, a uniform treatment of these data as characters becomes +possible. The uniformity is achieved by using specific encoding +algorithms, meaning that the data can be converted back to bytes on +POSIX systems only if the same encoding is used. + +Specification +============= + +On Windows, Python uses the wide character APIs to access +character-oriented APIs, allowing direct conversion of the +environmental data to Python str objects. + +On POSIX systems, Python currently applies the locale's encoding to +convert the byte data to Unicode. If the locale's encoding is UTF-8, +it can represent the full set of Unicode characters, otherwise, only a +subset is representable. In the latter case, using private-use +characters to represent these bytes would be an option. For UTF-8, +doing so would create an ambiguity, as the private-use characters may +regularly occur in the input also. + +To convert non-decodable bytes, a new error handler "python-escape" is +introduced, which decodes non-decodable bytes using into a private-use +character U+F01xx, which is believed to not conflict with private-use +characters that currently exist in Python codecs. + +The error handler interface is extended to allow the encode error +handler to return byte strings immediately, in addition to returning +Unicode strings which then get encoded again. + +If the locale's encoding is UTF-8, the file system encoding is set to +a new encoding "utf-8b". The UTF-8b codec decodes non-decodable bytes +(which must be >= 0x80) into half surrogate codes U+DC80..U+DCFF. + +Discussion +========== + +While providing a uniform API to non-decodable bytes, this interface +has the limitation that chosen representation only "works" if the data +get converted back to bytes with the python-escape error handler +also. Encoding the data with the locale's encoding and the (default) +strict error handler will raise an exception, encoding them with UTF-8 +will produce non-sensical data. + +For most applications, we assume that they eventually pass data +received from a system interface back into the same system +interfaces. For example, and application invoking os.listdir() will +likely pass the result strings back into APIs like os.stat() or +open(), which then encodes them back into their original byte +representation. Applications that need to process the original byte +strings can obtain them by encoding the character strings with the +file system encoding, passing "python-escape" as the error handler +name. + +Copyright +========= + +This document has been placed in the public domain. + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + coding: utf-8 + End: From nnorwitz at gmail.com Wed Apr 22 11:24:20 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 22 Apr 2009 05:24:20 -0400 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20090422092420.GA21552@python.psfb.org> More important issues: ---------------------- test_softspace leaked [-91, 0, 0] references, sum=-91 Less important issues: ---------------------- test_asynchat leaked [0, 0, 131] references, sum=131 test_cmd_line leaked [0, 0, -25] references, sum=-25 test_file leaked [70, -70, 0] references, sum=0 test_smtplib leaked [0, 88, -92] references, sum=-4 test_socketserver leaked [84, -84, 91] references, sum=91 test_sys leaked [-42, 42, -42] references, sum=-42 test_threading leaked [48, 48, 48] references, sum=144 test_urllib2_localnet leaked [3, 3, 3] references, sum=9 From python-checkins at python.org Wed Apr 22 14:10:48 2009 From: python-checkins at python.org (vinay.sajip) Date: Wed, 22 Apr 2009 14:10:48 +0200 (CEST) Subject: [Python-checkins] r71794 - python/trunk/Lib/logging/__init__.py Message-ID: <20090422121048.3D6FD1E40FD@bag.python.org> Author: vinay.sajip Date: Wed Apr 22 14:10:47 2009 New Revision: 71794 Log: Issue #5170: Fixed regression caused when fixing #5768. Modified: python/trunk/Lib/logging/__init__.py Modified: python/trunk/Lib/logging/__init__.py ============================================================================== --- python/trunk/Lib/logging/__init__.py (original) +++ python/trunk/Lib/logging/__init__.py Wed Apr 22 14:10:47 2009 @@ -766,7 +766,17 @@ try: if (isinstance(msg, unicode) and getattr(stream, 'encoding', None)): - stream.write(fs.decode(stream.encoding) % msg) + fs = fs.decode(stream.encoding) + try: + stream.write(fs % msg) + except UnicodeEncodeError: + #Printing to terminals sometimes fails. For example, + #with an encoding of 'cp1251', the above write will + #work if written to a stream opened or wrapped by + #the codecs module, but fail when writing to a + #terminal even when the codepage is set to cp1251. + #An extra encoding step seems to be needed. + stream.write((fs % msg).encode(stream.encoding)) else: stream.write(fs % msg) except UnicodeError: From python-checkins at python.org Wed Apr 22 14:12:43 2009 From: python-checkins at python.org (vinay.sajip) Date: Wed, 22 Apr 2009 14:12:43 +0200 (CEST) Subject: [Python-checkins] r71795 - python/branches/release26-maint/Lib/logging/__init__.py Message-ID: <20090422121243.797A51E4010@bag.python.org> Author: vinay.sajip Date: Wed Apr 22 14:12:43 2009 New Revision: 71795 Log: Issue #5170: Fixed regression caused when fixing #5768. Modified: python/branches/release26-maint/Lib/logging/__init__.py Modified: python/branches/release26-maint/Lib/logging/__init__.py ============================================================================== --- python/branches/release26-maint/Lib/logging/__init__.py (original) +++ python/branches/release26-maint/Lib/logging/__init__.py Wed Apr 22 14:12:43 2009 @@ -766,7 +766,17 @@ try: if (isinstance(msg, unicode) and getattr(stream, 'encoding', None)): - stream.write(fs.decode(stream.encoding) % msg) + fs = fs.decode(stream.encoding) + try: + stream.write(fs % msg) + except UnicodeEncodeError: + #Printing to terminals sometimes fails. For example, + #with an encoding of 'cp1251', the above write will + #work if written to a stream opened or wrapped by + #the codecs module, but fail when writing to a + #terminal even when the codepage is set to cp1251. + #An extra encoding step seems to be needed. + stream.write((fs % msg).encode(stream.encoding)) else: stream.write(fs % msg) except UnicodeError: From python-checkins at python.org Wed Apr 22 15:29:05 2009 From: python-checkins at python.org (eric.smith) Date: Wed, 22 Apr 2009 15:29:05 +0200 (CEST) Subject: [Python-checkins] r71796 - in python/trunk: Include/pystrtod.h Include/stringobject.h Lib/test/test_format.py Lib/test/test_types.py Misc/NEWS Objects/stringlib/formatter.h Objects/stringlib/localeutil.h Objects/stringlib/stringdefs.h Python/pystrtod.c Message-ID: <20090422132906.021C71E4020@bag.python.org> Author: eric.smith Date: Wed Apr 22 15:29:05 2009 New Revision: 71796 Log: Backport of some of the work in r71665 to trunk. This reworks much of int, long, and float __format__(), and it keeps their implementation in sync with py3k. Also added PyOS_double_to_string. This is the "fallback" version that's also available in trunk, and should be kept in sync with that code. I'll add an issue to document PyOS_double_to_string in the C API. There are many internal cleanups. Externally visible changes include: - Implement PEP 378, Format Specifier for Thousands Separator, for floats, ints, and longs. - Issue #5515: 'n' formatting for ints, longs, and floats handles leading zero formatting poorly. - Issue #5772: For float.__format__, don't add a trailing ".0" if we're using no type code and we have an exponent. Modified: python/trunk/Include/pystrtod.h python/trunk/Include/stringobject.h python/trunk/Lib/test/test_format.py python/trunk/Lib/test/test_types.py python/trunk/Misc/NEWS python/trunk/Objects/stringlib/formatter.h python/trunk/Objects/stringlib/localeutil.h python/trunk/Objects/stringlib/stringdefs.h python/trunk/Python/pystrtod.c Modified: python/trunk/Include/pystrtod.h ============================================================================== --- python/trunk/Include/pystrtod.h (original) +++ python/trunk/Include/pystrtod.h Wed Apr 22 15:29:05 2009 @@ -10,6 +10,25 @@ PyAPI_FUNC(double) PyOS_ascii_atof(const char *str); PyAPI_FUNC(char *) PyOS_ascii_formatd(char *buffer, size_t buf_len, const char *format, double d); +/* The caller is responsible for calling PyMem_Free to free the buffer + that's is returned. */ +PyAPI_FUNC(char *) PyOS_double_to_string(double val, + char format_code, + int precision, + int flags, + int *type); + + +/* PyOS_double_to_string's "flags" parameter can be set to 0 or more of: */ +#define Py_DTSF_SIGN 0x01 /* always add the sign */ +#define Py_DTSF_ADD_DOT_0 0x02 /* if the result is an integer add ".0" */ +#define Py_DTSF_ALT 0x04 /* "alternate" formatting. it's format_code + specific */ + +/* PyOS_double_to_string's "type", if non-NULL, will be set to one of: */ +#define Py_DTST_FINITE 0 +#define Py_DTST_INFINITE 1 +#define Py_DTST_NAN 2 #ifdef __cplusplus } Modified: python/trunk/Include/stringobject.h ============================================================================== --- python/trunk/Include/stringobject.h (original) +++ python/trunk/Include/stringobject.h Wed Apr 22 15:29:05 2009 @@ -177,16 +177,26 @@ strings) */ ); + /* Using the current locale, insert the thousands grouping into the string pointed to by buffer. For the argument descriptions, see Objects/stringlib/localeutil.h */ +PyAPI_FUNC(Py_ssize_t) _PyString_InsertThousandsGroupingLocale(char *buffer, + Py_ssize_t n_buffer, + char *digits, + Py_ssize_t n_digits, + Py_ssize_t min_width); -PyAPI_FUNC(int) _PyString_InsertThousandsGrouping(char *buffer, - Py_ssize_t n_buffer, - Py_ssize_t n_digits, - Py_ssize_t buf_size, - Py_ssize_t *count, - int append_zero_char); +/* 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 */ +PyAPI_FUNC(Py_ssize_t) _PyString_InsertThousandsGrouping(char *buffer, + Py_ssize_t n_buffer, + char *digits, + Py_ssize_t n_digits, + Py_ssize_t min_width, + const char *grouping, + const char *thousands_sep); /* Format the object based on the format_spec, as defined in PEP 3101 (Advanced String Formatting). */ Modified: python/trunk/Lib/test/test_format.py ============================================================================== --- python/trunk/Lib/test/test_format.py (original) +++ python/trunk/Lib/test/test_format.py Wed Apr 22 15:29:05 2009 @@ -232,6 +232,10 @@ testboth("%o", -042L, "-42") testboth("%o", float(042), "42") + # alternate float formatting + testformat('%g', 1.1, '1.1') + testformat('%#g', 1.1, '1.10000') + # Test exception for unknown format characters if verbose: print 'Testing exceptions' Modified: python/trunk/Lib/test/test_types.py ============================================================================== --- python/trunk/Lib/test/test_types.py (original) +++ python/trunk/Lib/test/test_types.py Wed Apr 22 15:29:05 2009 @@ -113,6 +113,9 @@ self.assertEqual(1.5e-101.__format__('e'), '1.500000e-101') self.assertEqual('%e' % 1.5e-101, '1.500000e-101') + self.assertEqual('%g' % 1.0, '1') + self.assertEqual('%#g' % 1.0, '1.00000') + def test_normal_integers(self): # Ensure the first 256 integers are shared a = 256 @@ -412,6 +415,9 @@ self.assertRaises(TypeError, 3 .__format__, None) self.assertRaises(TypeError, 3 .__format__, 0) + # can't have ',' with 'c' + self.assertRaises(ValueError, 3 .__format__, ",c") + # ensure that only int and float type specifiers work for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] + [chr(x) for x in range(ord('A'), ord('Z')+1)]): @@ -609,11 +615,37 @@ # a totaly empty format specifier means something else. # So, just use a sign flag test(1e200, '+g', '+1e+200') - test(1e200, '+', '+1.0e+200') + test(1e200, '+', '+1e+200') + test(1.1e200, '+g', '+1.1e+200') + test(1.1e200, '+', '+1.1e+200') + test(1.1e200, '+g', '+1.1e+200') test(1.1e200, '+', '+1.1e+200') - # % formatting + # 0 padding + test(1234., '010f', '1234.000000') + test(1234., '011f', '1234.000000') + test(1234., '012f', '01234.000000') + test(-1234., '011f', '-1234.000000') + test(-1234., '012f', '-1234.000000') + test(-1234., '013f', '-01234.000000') + test(-1234.12341234, '013f', '-01234.123412') + test(-123456.12341234, '011.2f', '-0123456.12') + + # 0 padding with commas + test(1234., '011,f', '1,234.000000') + test(1234., '012,f', '1,234.000000') + test(1234., '013,f', '01,234.000000') + test(-1234., '012,f', '-1,234.000000') + test(-1234., '013,f', '-1,234.000000') + test(-1234., '014,f', '-01,234.000000') + test(-12345., '015,f', '-012,345.000000') + test(-123456., '016,f', '-0,123,456.000000') + test(-123456., '017,f', '-0,123,456.000000') + test(-123456.12341234, '017,f', '-0,123,456.123412') + test(-123456.12341234, '013,.2f', '-0,123,456.12') + + # % formatting test(-1.0, '%', '-100.000000%') # format spec must be string @@ -637,6 +669,24 @@ self.assertRaises(ValueError, format, 0.0, '#') self.assertRaises(ValueError, format, 0.0, '#20f') + def test_format_spec_errors(self): + # int, float, and string all share the same format spec + # mini-language parser. + + # Check that we can't ask for too many digits. This is + # probably a CPython specific test. It tries to put the width + # into a C long. + self.assertRaises(ValueError, format, 0, '1'*10000 + 'd') + + # Similar with the precision. + self.assertRaises(ValueError, format, 0, '.' + '1'*10000 + 'd') + + # And may as well test both. + self.assertRaises(ValueError, format, 0, '1'*1000 + '.' + '1'*10000 + 'd') + + # Make sure commas aren't allowed with various type codes + for code in 'xXobns': + self.assertRaises(ValueError, format, 0, ',' + code) def test_main(): run_unittest(TypesTests) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Apr 22 15:29:05 2009 @@ -12,6 +12,15 @@ Core and Builtins ----------------- +- Implement PEP 378, Format Specifier for Thousands Separator, for + floats, ints, and longs. + +- Issue #5515: 'n' formatting for ints, longs, and floats handles + leading zero formatting poorly. + +- Issue #5772: For float.__format__, don't add a trailing ".0" if + we're using no type code and we have an exponent. + - Issue #3166: Make long -> float (and int -> float) conversions correctly rounded. Modified: python/trunk/Objects/stringlib/formatter.h ============================================================================== --- python/trunk/Objects/stringlib/formatter.h (original) +++ python/trunk/Objects/stringlib/formatter.h Wed Apr 22 15:29:05 2009 @@ -1,6 +1,8 @@ /* implements the string, long, and float formatters. that is, string.__format__, etc. */ +#include + /* Before including this, you must include either: stringlib/unicodedefs.h stringlib/stringdefs.h @@ -13,8 +15,6 @@ be. These are the only non-static functions defined here. */ -#define ALLOW_PARENS_FOR_SIGN 0 - /* Raises an exception about an unknown presentation type for this * type. */ @@ -104,9 +104,6 @@ { switch (c) { case ' ': case '+': case '-': -#if ALLOW_PARENS_FOR_SIGN - case '(': -#endif return 1; default: return 0; @@ -120,6 +117,7 @@ int alternate; STRINGLIB_CHAR sign; Py_ssize_t width; + int thousands_separators; Py_ssize_t precision; STRINGLIB_CHAR type; } InternalFormatSpec; @@ -132,7 +130,7 @@ */ static int parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec, - Py_ssize_t format_spec_len, + Py_ssize_t format_spec_len, InternalFormatSpec *format, char default_type) { @@ -142,13 +140,14 @@ /* end-ptr is used throughout this code to specify the length of the input string */ - Py_ssize_t specified_width; + Py_ssize_t consumed; format->fill_char = '\0'; format->align = '\0'; format->alternate = 0; format->sign = '\0'; format->width = -1; + format->thousands_separators = 0; format->precision = -1; format->type = default_type; @@ -168,18 +167,13 @@ if (end-ptr >= 1 && is_sign_element(ptr[0])) { format->sign = ptr[0]; ++ptr; -#if ALLOW_PARENS_FOR_SIGN - if (end-ptr >= 1 && ptr[0] == ')') { - ++ptr; - } -#endif } /* If the next character is #, we're in alternate mode. This only applies to integers. */ if (end-ptr >= 1 && ptr[0] == '#') { - format->alternate = 1; - ++ptr; + format->alternate = 1; + ++ptr; } /* The special case for 0-padding (backwards compat) */ @@ -191,25 +185,35 @@ ++ptr; } - /* XXX add error checking */ - specified_width = get_integer(&ptr, end, &format->width); + consumed = get_integer(&ptr, end, &format->width); + if (consumed == -1) + /* Overflow error. Exception already set. */ + return 0; - /* if specified_width is 0, we didn't consume any characters for - the width. in that case, reset the width to -1, because - get_integer() will have set it to zero */ - if (specified_width == 0) { + /* If consumed is 0, we didn't consume any characters for the + width. In that case, reset the width to -1, because + get_integer() will have set it to zero. -1 is how we record + that the width wasn't specified. */ + if (consumed == 0) format->width = -1; + + /* Comma signifies add thousands separators */ + if (end-ptr && ptr[0] == ',') { + format->thousands_separators = 1; + ++ptr; } /* Parse field precision */ if (end-ptr && ptr[0] == '.') { ++ptr; - /* XXX add error checking */ - specified_width = get_integer(&ptr, end, &format->precision); + consumed = get_integer(&ptr, end, &format->precision); + if (consumed == -1) + /* Overflow error. Exception already set. */ + return 0; - /* not having a precision after a dot is an error */ - if (specified_width == 0) { + /* Not having a precision after a dot is an error. */ + if (consumed == 0) { PyErr_Format(PyExc_ValueError, "Format specifier missing precision"); return 0; @@ -217,10 +221,10 @@ } - /* Finally, parse the type field */ + /* Finally, parse the type field. */ if (end-ptr > 1) { - /* invalid conversion spec */ + /* More than one char remain, invalid conversion spec. */ PyErr_Format(PyExc_ValueError, "Invalid conversion specification"); return 0; } @@ -230,6 +234,29 @@ ++ptr; } + /* Do as much validating as we can, just by looking at the format + specifier. Do not take into account what type of formatting + we're doing (int, float, string). */ + + if (format->thousands_separators) { + switch (format->type) { + case 'd': + case 'e': + case 'f': + case 'g': + case 'E': + case 'G': + case '%': + case 'F': + /* These are allowed. See PEP 378.*/ + break; + default: + PyErr_Format(PyExc_ValueError, + "Cannot specify ',' with '%c'.", format->type); + return 0; + } + } + return 1; } @@ -238,6 +265,20 @@ /*********** common routines for numeric formatting *********************/ /************************************************************************/ +/* Locale type codes. */ +#define LT_CURRENT_LOCALE 0 +#define LT_DEFAULT_LOCALE 1 +#define LT_NO_LOCALE 2 + +/* Locale info needed for formatting integers and the part of floats + before and including the decimal. Note that locales only support + 8-bit chars, not unicode. */ +typedef struct { + char *decimal_point; + char *thousands_sep; + char *grouping; +} LocaleInfo; + /* describes the layout for an integer, see the comment in calc_number_widths() for details */ typedef struct { @@ -245,38 +286,84 @@ Py_ssize_t n_prefix; Py_ssize_t n_spadding; Py_ssize_t n_rpadding; - char lsign; - Py_ssize_t n_lsign; - char rsign; - Py_ssize_t n_rsign; - Py_ssize_t n_total; /* just a convenience, it's derivable from the - other fields */ + char sign; + Py_ssize_t n_sign; /* number of digits needed for sign (0/1) */ + Py_ssize_t n_grouped_digits; /* Space taken up by the digits, including + any grouping chars. */ + Py_ssize_t n_decimal; /* 0 if only an integer */ + Py_ssize_t n_remainder; /* Digits in decimal and/or exponent part, + excluding the decimal itself, if + present. */ + + /* These 2 are not the widths of fields, but are needed by + STRINGLIB_GROUPING. */ + Py_ssize_t n_digits; /* The number of digits before a decimal + or exponent. */ + Py_ssize_t n_min_width; /* The min_width we used when we computed + the n_grouped_digits width. */ } NumberFieldWidths; +/* Given a number of the form: + digits[remainder] + where ptr points to the start and end points to the end, find where + the integer part ends. This could be a decimal, an exponent, both, + or neither. + If a decimal point is present, set *has_decimal and increment + remainder beyond it. + Results are undefined (but shouldn't crash) for improperly + formatted strings. +*/ +static void +parse_number(STRINGLIB_CHAR *ptr, Py_ssize_t len, + Py_ssize_t *n_remainder, int *has_decimal) +{ + STRINGLIB_CHAR *end = ptr + len; + STRINGLIB_CHAR *remainder; + + while (ptrn_digits = n_number - n_remainder - (has_decimal?1:0); spec->n_lpadding = 0; - spec->n_prefix = 0; + spec->n_prefix = n_prefix; + spec->n_decimal = has_decimal ? strlen(locale->decimal_point) : 0; + spec->n_remainder = n_remainder; spec->n_spadding = 0; spec->n_rpadding = 0; - spec->lsign = '\0'; - spec->n_lsign = 0; - spec->rsign = '\0'; - spec->n_rsign = 0; + spec->sign = '\0'; + spec->n_sign = 0; /* the output will look like: - | | - | | - | | + | | + | | + | | - lsign and rsign are computed from format->sign and the actual + sign is computed from format->sign and the actual sign of the number prefix is given (it's for the '0x' prefix) @@ -291,108 +378,191 @@ */ /* compute the various parts we're going to write */ - if (format->sign == '+') { + switch (format->sign) { + case '+': /* always put a + or - */ - spec->n_lsign = 1; - spec->lsign = (actual_sign == '-' ? '-' : '+'); - } -#if ALLOW_PARENS_FOR_SIGN - else if (format->sign == '(') { - if (actual_sign == '-') { - spec->n_lsign = 1; - spec->lsign = '('; - spec->n_rsign = 1; - spec->rsign = ')'; - } - } -#endif - else if (format->sign == ' ') { - spec->n_lsign = 1; - spec->lsign = (actual_sign == '-' ? '-' : ' '); - } - else { - /* non specified, or the default (-) */ - if (actual_sign == '-') { - spec->n_lsign = 1; - spec->lsign = '-'; + spec->n_sign = 1; + spec->sign = (sign_char == '-' ? '-' : '+'); + break; + case ' ': + spec->n_sign = 1; + spec->sign = (sign_char == '-' ? '-' : ' '); + break; + default: + /* Not specified, or the default (-) */ + if (sign_char == '-') { + spec->n_sign = 1; + spec->sign = '-'; } } - spec->n_prefix = n_prefix; + /* The number of chars used for non-digits and non-padding. */ + n_non_digit_non_padding = spec->n_sign + spec->n_prefix + spec->n_decimal + + spec->n_remainder; + + /* min_width can go negative, that's okay. format->width == -1 means + we don't care. */ + if (format->fill_char == '0') + spec->n_min_width = format->width - n_non_digit_non_padding; + else + spec->n_min_width = 0; - /* now the number of padding characters */ - if (format->width == -1) { - /* no padding at all, nothing to do */ - } - else { - /* see if any padding is needed */ - if (spec->n_lsign + n_digits + spec->n_rsign + - spec->n_prefix >= format->width) { - /* no padding needed, we're already bigger than the - requested width */ - } - else { - /* determine which of left, space, or right padding is - needed */ - Py_ssize_t padding = format->width - - (spec->n_lsign + spec->n_prefix + - n_digits + spec->n_rsign); - if (format->align == '<') - spec->n_rpadding = padding; - else if (format->align == '>') - spec->n_lpadding = padding; - else if (format->align == '^') { - spec->n_lpadding = padding / 2; - spec->n_rpadding = padding - spec->n_lpadding; - } - else if (format->align == '=') - spec->n_spadding = padding; - else - spec->n_lpadding = padding; + if (spec->n_digits == 0) + /* This case only occurs when using 'c' formatting, we need + to special case it because the grouping code always wants + to have at least one character. */ + spec->n_grouped_digits = 0; + else + spec->n_grouped_digits = STRINGLIB_GROUPING(NULL, 0, NULL, + spec->n_digits, + spec->n_min_width, + locale->grouping, + locale->thousands_sep); + + /* Given the desired width and the total of digit and non-digit + space we consume, see if we need any padding. format->width can + be negative (meaning no padding), but this code still works in + that case. */ + n_padding = format->width - + (n_non_digit_non_padding + spec->n_grouped_digits); + if (n_padding > 0) { + /* Some padding is needed. Determine if it's left, space, or right. */ + switch (format->align) { + case '<': + spec->n_rpadding = n_padding; + break; + case '^': + spec->n_lpadding = n_padding / 2; + spec->n_rpadding = n_padding - spec->n_lpadding; + break; + case '=': + spec->n_spadding = n_padding; + break; + default: + /* Handles '>', plus catch-all just in case. */ + spec->n_lpadding = n_padding; + break; } } - spec->n_total = spec->n_lpadding + spec->n_lsign + spec->n_prefix + - spec->n_spadding + n_digits + spec->n_rsign + spec->n_rpadding; + return spec->n_lpadding + spec->n_sign + spec->n_prefix + + spec->n_spadding + spec->n_grouped_digits + spec->n_decimal + + spec->n_remainder + spec->n_rpadding; } -/* fill in the non-digit parts of a numbers's string representation, - as determined in calc_number_widths(). returns the pointer to - where the digits go. */ -static STRINGLIB_CHAR * -fill_non_digits(STRINGLIB_CHAR *p_buf, const NumberFieldWidths *spec, - STRINGLIB_CHAR *prefix, Py_ssize_t n_digits, - STRINGLIB_CHAR fill_char) +/* Fill in the digit parts of a numbers's string representation, + as determined in calc_number_widths(). + No error checking, since we know the buffer is the correct size. */ +static void +fill_number(STRINGLIB_CHAR *buf, const NumberFieldWidths *spec, + STRINGLIB_CHAR *digits, Py_ssize_t n_digits, + STRINGLIB_CHAR *prefix, STRINGLIB_CHAR fill_char, + LocaleInfo *locale, int toupper) { - STRINGLIB_CHAR *p_digits; + /* Used to keep track of digits, decimal, and remainder. */ + STRINGLIB_CHAR *p = digits; + +#ifndef NDEBUG + Py_ssize_t r; +#endif if (spec->n_lpadding) { - STRINGLIB_FILL(p_buf, fill_char, spec->n_lpadding); - p_buf += spec->n_lpadding; + STRINGLIB_FILL(buf, fill_char, spec->n_lpadding); + buf += spec->n_lpadding; } - if (spec->n_lsign == 1) { - *p_buf++ = spec->lsign; + if (spec->n_sign == 1) { + *buf++ = spec->sign; } if (spec->n_prefix) { - memmove(p_buf, - prefix, - spec->n_prefix * sizeof(STRINGLIB_CHAR)); - p_buf += spec->n_prefix; + memmove(buf, + prefix, + spec->n_prefix * sizeof(STRINGLIB_CHAR)); + if (toupper) { + Py_ssize_t t; + for (t = 0; t < spec->n_prefix; ++t) + buf[t] = STRINGLIB_TOUPPER(buf[t]); + } + buf += spec->n_prefix; } if (spec->n_spadding) { - STRINGLIB_FILL(p_buf, fill_char, spec->n_spadding); - p_buf += spec->n_spadding; + STRINGLIB_FILL(buf, fill_char, spec->n_spadding); + buf += spec->n_spadding; } - p_digits = p_buf; - p_buf += n_digits; - if (spec->n_rsign == 1) { - *p_buf++ = spec->rsign; + + /* Only for type 'c' special case, it has no digits. */ + if (spec->n_digits != 0) { + /* Fill the digits with InsertThousandsGrouping. */ +#ifndef NDEBUG + r = +#endif + STRINGLIB_GROUPING(buf, spec->n_grouped_digits, digits, + spec->n_digits, spec->n_min_width, + locale->grouping, locale->thousands_sep); +#ifndef NDEBUG + assert(r == spec->n_grouped_digits); +#endif + p += spec->n_digits; + } + if (toupper) { + Py_ssize_t t; + for (t = 0; t < spec->n_grouped_digits; ++t) + buf[t] = STRINGLIB_TOUPPER(buf[t]); + } + buf += spec->n_grouped_digits; + + if (spec->n_decimal) { + Py_ssize_t t; + for (t = 0; t < spec->n_decimal; ++t) + buf[t] = locale->decimal_point[t]; + buf += spec->n_decimal; + p += 1; + } + + if (spec->n_remainder) { + memcpy(buf, p, spec->n_remainder * sizeof(STRINGLIB_CHAR)); + buf += spec->n_remainder; + p += spec->n_remainder; } + if (spec->n_rpadding) { - STRINGLIB_FILL(p_buf, fill_char, spec->n_rpadding); - p_buf += spec->n_rpadding; + STRINGLIB_FILL(buf, fill_char, spec->n_rpadding); + buf += spec->n_rpadding; + } +} + +static char no_grouping[1] = {CHAR_MAX}; + +/* Find the decimal point character(s?), thousands_separator(s?), and + grouping description, either for the current locale if type is + LT_CURRENT_LOCALE, a hard-coded locale if LT_DEFAULT_LOCALE, or + none if LT_NO_LOCALE. */ +static void +get_locale_info(int type, LocaleInfo *locale_info) +{ + switch (type) { + case LT_CURRENT_LOCALE: { + struct lconv *locale_data = localeconv(); + locale_info->decimal_point = locale_data->decimal_point; + locale_info->thousands_sep = locale_data->thousands_sep; + locale_info->grouping = locale_data->grouping; + break; + } + case LT_DEFAULT_LOCALE: + locale_info->decimal_point = "."; + locale_info->thousands_sep = ","; + locale_info->grouping = "\3"; /* Group every 3 characters, + trailing 0 means repeat + infinitely. */ + break; + case LT_NO_LOCALE: + locale_info->decimal_point = "."; + locale_info->thousands_sep = ""; + locale_info->grouping = no_grouping; + break; + default: + assert(0); } - return p_digits; } + #endif /* FORMAT_FLOAT || FORMAT_LONG */ /************************************************************************/ @@ -420,7 +590,7 @@ if (format->alternate) { PyErr_SetString(PyExc_ValueError, "Alternate form (#) not allowed in string format " - "specifier"); + "specifier"); goto done; } @@ -504,25 +674,27 @@ static PyObject * format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format, - IntOrLongToString tostring) + IntOrLongToString tostring) { PyObject *result = NULL; PyObject *tmp = NULL; STRINGLIB_CHAR *pnumeric_chars; STRINGLIB_CHAR numeric_char; - STRINGLIB_CHAR sign = '\0'; - STRINGLIB_CHAR *p; + STRINGLIB_CHAR sign_char = '\0'; Py_ssize_t n_digits; /* count of digits need from the computed string */ - Py_ssize_t n_leading_chars; - Py_ssize_t n_grouping_chars = 0; /* Count of additional chars to - allocate, used for 'n' - formatting. */ + Py_ssize_t n_remainder = 0; /* Used only for 'c' formatting, which + produces non-digits */ Py_ssize_t n_prefix = 0; /* Count of prefix chars, (e.g., '0x') */ + Py_ssize_t n_total; STRINGLIB_CHAR *prefix = NULL; NumberFieldWidths spec; long x; + /* Locale settings, either from the actual locale or + from a hard-code pseudo-locale */ + LocaleInfo locale; + /* no precision allowed on integers */ if (format->precision != -1) { PyErr_SetString(PyExc_ValueError, @@ -530,7 +702,6 @@ goto done; } - /* special case for character formatting */ if (format->type == 'c') { /* error to specify a sign */ @@ -541,6 +712,14 @@ goto done; } + /* Error to specify a comma. */ + if (format->thousands_separators) { + PyErr_SetString(PyExc_ValueError, + "Thousands separators not allowed with integer" + " format specifier 'c'"); + goto done; + } + /* taken from unicodeobject.c formatchar() */ /* Integer input truncated to a character */ /* XXX: won't work for int */ @@ -562,31 +741,38 @@ goto done; } #endif - numeric_char = (STRINGLIB_CHAR)x; - pnumeric_chars = &numeric_char; + numeric_char = (STRINGLIB_CHAR)x; + pnumeric_chars = &numeric_char; n_digits = 1; + + /* As a sort-of hack, we tell calc_number_widths that we only + have "remainder" characters. calc_number_widths thinks + these are characters that don't get formatted, only copied + into the output string. We do this for 'c' formatting, + because the characters are likely to be non-digits. */ + n_remainder = 1; } else { int base; - int leading_chars_to_skip = 0; /* Number of characters added by - PyNumber_ToBase that we want to - skip over. */ + int leading_chars_to_skip = 0; /* Number of characters added by + PyNumber_ToBase that we want to + skip over. */ /* Compute the base and how many characters will be added by PyNumber_ToBase */ switch (format->type) { case 'b': base = 2; - leading_chars_to_skip = 2; /* 0b */ + leading_chars_to_skip = 2; /* 0b */ break; case 'o': base = 8; - leading_chars_to_skip = 2; /* 0o */ + leading_chars_to_skip = 2; /* 0o */ break; case 'x': case 'X': base = 16; - leading_chars_to_skip = 2; /* 0x */ + leading_chars_to_skip = 2; /* 0x */ break; default: /* shouldn't be needed, but stops a compiler warning */ case 'd': @@ -595,102 +781,58 @@ break; } - /* The number of prefix chars is the same as the leading - chars to skip */ - if (format->alternate) - n_prefix = leading_chars_to_skip; + /* The number of prefix chars is the same as the leading + chars to skip */ + if (format->alternate) + n_prefix = leading_chars_to_skip; /* Do the hard part, converting to a string in a given base */ - tmp = tostring(value, base); + tmp = tostring(value, base); if (tmp == NULL) goto done; - pnumeric_chars = STRINGLIB_STR(tmp); + pnumeric_chars = STRINGLIB_STR(tmp); n_digits = STRINGLIB_LEN(tmp); - prefix = pnumeric_chars; + prefix = pnumeric_chars; - /* Remember not to modify what pnumeric_chars points to. it - might be interned. Only modify it after we copy it into a - newly allocated output buffer. */ + /* Remember not to modify what pnumeric_chars points to. it + might be interned. Only modify it after we copy it into a + newly allocated output buffer. */ /* Is a sign character present in the output? If so, remember it and skip it */ - sign = pnumeric_chars[0]; - if (sign == '-') { - ++prefix; - ++leading_chars_to_skip; + if (pnumeric_chars[0] == '-') { + sign_char = pnumeric_chars[0]; + ++prefix; + ++leading_chars_to_skip; } - /* Skip over the leading chars (0x, 0b, etc.) */ - n_digits -= leading_chars_to_skip; - pnumeric_chars += leading_chars_to_skip; - } - - if (format->type == 'n') - /* Compute how many additional chars we need to allocate - to hold the thousands grouping. */ - STRINGLIB_GROUPING(NULL, n_digits, n_digits, - 0, &n_grouping_chars, 0); - - /* Calculate the widths of the various leading and trailing parts */ - calc_number_widths(&spec, sign, n_prefix, n_digits + n_grouping_chars, - format); + /* Skip over the leading chars (0x, 0b, etc.) */ + n_digits -= leading_chars_to_skip; + pnumeric_chars += leading_chars_to_skip; + } + + /* Determine the grouping, separator, and decimal point, if any. */ + get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE : + (format->thousands_separators ? + LT_DEFAULT_LOCALE : + LT_NO_LOCALE), + &locale); + + /* Calculate how much memory we'll need. */ + n_total = calc_number_widths(&spec, n_prefix, sign_char, pnumeric_chars, + n_digits, n_remainder, 0, &locale, format); - /* Allocate a new string to hold the result */ - result = STRINGLIB_NEW(NULL, spec.n_total); + /* Allocate the memory. */ + result = STRINGLIB_NEW(NULL, n_total); if (!result) - goto done; - p = STRINGLIB_STR(result); - - /* XXX There is too much magic here regarding the internals of - spec and the location of the prefix and digits. It would be - better if calc_number_widths returned a number of logical - offsets into the buffer, and those were used. Maybe in a - future code cleanup. */ - - /* Fill in the digit parts */ - n_leading_chars = spec.n_lpadding + spec.n_lsign + - spec.n_prefix + spec.n_spadding; - memmove(p + n_leading_chars, - pnumeric_chars, - n_digits * sizeof(STRINGLIB_CHAR)); - - /* If type is 'X', convert the filled in digits to uppercase */ - if (format->type == 'X') { - Py_ssize_t t; - for (t = 0; t < n_digits; ++t) - p[t + n_leading_chars] = STRINGLIB_TOUPPER(p[t + n_leading_chars]); - } - - /* Insert the grouping, if any, after the uppercasing of the digits, so - we can ensure that grouping chars won't be affected. */ - if (n_grouping_chars) { - /* We know this can't fail, since we've already - reserved enough space. */ - STRINGLIB_CHAR *pstart = p + n_leading_chars; -#ifndef NDEBUG - int r = -#endif - STRINGLIB_GROUPING(pstart, n_digits, n_digits, - spec.n_total+n_grouping_chars-n_leading_chars, - NULL, 0); - assert(r); - } - - /* Fill in the non-digit parts (padding, sign, etc.) */ - fill_non_digits(p, &spec, prefix, n_digits + n_grouping_chars, - format->fill_char == '\0' ? ' ' : format->fill_char); - - /* If type is 'X', uppercase the prefix. This has to be done after the - prefix is filled in by fill_non_digits */ - if (format->type == 'X') { - Py_ssize_t t; - for (t = 0; t < n_prefix; ++t) - p[t + spec.n_lpadding + spec.n_lsign] = - STRINGLIB_TOUPPER(p[t + spec.n_lpadding + spec.n_lsign]); - } + goto done; + /* Populate the memory. */ + fill_number(STRINGLIB_STR(result), &spec, pnumeric_chars, n_digits, + prefix, format->fill_char == '\0' ? ' ' : format->fill_char, + &locale, format->type == 'X'); done: Py_XDECREF(tmp); @@ -704,149 +846,152 @@ #ifdef FORMAT_FLOAT #if STRINGLIB_IS_UNICODE -/* taken from unicodeobject.c */ -static Py_ssize_t -strtounicode(Py_UNICODE *buffer, const char *charbuffer) +static void +strtounicode(Py_UNICODE *buffer, const char *charbuffer, Py_ssize_t len) { - register Py_ssize_t i; - Py_ssize_t len = strlen(charbuffer); - for (i = len - 1; i >= 0; --i) - buffer[i] = (Py_UNICODE) charbuffer[i]; - - return len; + Py_ssize_t i; + for (i = 0; i < len; ++i) + buffer[i] = (Py_UNICODE)charbuffer[i]; } #endif -/* see FORMATBUFLEN in unicodeobject.c */ -#define FLOAT_FORMATBUFLEN 120 - /* much of this is taken from unicodeobject.c */ static PyObject * format_float_internal(PyObject *value, - const InternalFormatSpec *format) + const InternalFormatSpec *format) { - /* fmt = '%.' + `prec` + `type` + '%%' - worst case length = 2 + 10 (len of INT_MAX) + 1 + 2 = 15 (use 20)*/ - char fmt[20]; - - /* taken from unicodeobject.c */ - /* Worst case length calc to ensure no buffer overrun: - - 'g' formats: - fmt = %#.g - buf = '-' + [0-9]*prec + '.' + 'e+' + (longest exp - for any double rep.) - len = 1 + prec + 1 + 2 + 5 = 9 + prec - - 'f' formats: - buf = '-' + [0-9]*x + '.' + [0-9]*prec (with x < 50) - len = 1 + 50 + 1 + prec = 52 + prec - - If prec=0 the effective precision is 1 (the leading digit is - always given), therefore increase the length by one. - - */ - char charbuf[FLOAT_FORMATBUFLEN]; + char *buf = NULL; /* buffer returned from PyOS_double_to_string */ Py_ssize_t n_digits; - double x; + Py_ssize_t n_remainder; + Py_ssize_t n_total; + int has_decimal; + double val; Py_ssize_t precision = format->precision; - PyObject *result = NULL; - STRINGLIB_CHAR sign; - char* trailing = ""; + STRINGLIB_CHAR type = format->type; + int add_pct = 0; STRINGLIB_CHAR *p; NumberFieldWidths spec; - STRINGLIB_CHAR type = format->type; + int flags = 0; + PyObject *result = NULL; + STRINGLIB_CHAR sign_char = '\0'; + int float_type; /* Used to see if we have a nan, inf, or regular float. */ #if STRINGLIB_IS_UNICODE - Py_UNICODE unicodebuf[FLOAT_FORMATBUFLEN]; + Py_UNICODE *unicode_tmp = NULL; #endif - /* alternate is not allowed on floats. */ + /* Locale settings, either from the actual locale or + from a hard-code pseudo-locale */ + LocaleInfo locale; + + /* Alternate is not allowed on floats. */ if (format->alternate) { PyErr_SetString(PyExc_ValueError, "Alternate form (#) not allowed in float format " - "specifier"); + "specifier"); goto done; } - /* first, do the conversion as 8-bit chars, using the platform's - snprintf. then, if needed, convert to unicode. */ + if (type == '\0') { + /* Omitted type specifier. This is like 'g' but with at least + one digit after the decimal point. */ + type = 'g'; + flags |= Py_DTSF_ADD_DOT_0; + } + + if (type == 'n') + /* 'n' is the same as 'g', except for the locale used to + format the result. We take care of that later. */ + type = 'g'; /* 'F' is the same as 'f', per the PEP */ if (type == 'F') type = 'f'; - x = PyFloat_AsDouble(value); - - if (x == -1.0 && PyErr_Occurred()) + val = PyFloat_AsDouble(value); + if (val == -1.0 && PyErr_Occurred()) goto done; if (type == '%') { type = 'f'; - x *= 100; - trailing = "%"; + val *= 100; + add_pct = 1; } if (precision < 0) precision = 6; - if (type == 'f' && fabs(x) >= 1e50) + if ((type == 'f' || type == 'F') && fabs(val) >= 1e50) type = 'g'; - /* cast "type", because if we're in unicode we need to pass a - 8-bit char. this is safe, because we've restricted what "type" - can be */ - PyOS_snprintf(fmt, sizeof(fmt), "%%.%" PY_FORMAT_SIZE_T "d%c", precision, - (char)type); - - /* do the actual formatting */ - PyOS_ascii_formatd(charbuf, sizeof(charbuf), fmt, x); - - /* adding trailing to fmt with PyOS_snprintf doesn't work, not - sure why. we'll just concatentate it here, no harm done. we - know we can't have a buffer overflow from the fmt size - analysis */ - strcat(charbuf, trailing); - - /* rather than duplicate the code for snprintf for both unicode - and 8 bit strings, we just use the 8 bit version and then - convert to unicode in a separate code path. that's probably - the lesser of 2 evils. */ + /* Cast "type", because if we're in unicode we need to pass a + 8-bit char. This is safe, because we've restricted what "type" + can be. */ + buf = PyOS_double_to_string(val, (char)type, precision, flags, + &float_type); + if (buf == NULL) + goto done; + n_digits = strlen(buf); + + if (add_pct) { + /* We know that buf has a trailing zero (since we just called + strlen() on it), and we don't use that fact any more. So we + can just write over the trailing zero. */ + buf[n_digits] = '%'; + n_digits += 1; + } + + /* Since there is no unicode version of PyOS_double_to_string, + just use the 8 bit version and then convert to unicode. */ #if STRINGLIB_IS_UNICODE - n_digits = strtounicode(unicodebuf, charbuf); - p = unicodebuf; + unicode_tmp = (Py_UNICODE*)PyMem_Malloc((n_digits)*sizeof(Py_UNICODE)); + if (unicode_tmp == NULL) { + PyErr_NoMemory(); + goto done; + } + strtounicode(unicode_tmp, buf, n_digits); + p = unicode_tmp; #else - /* compute the length. I believe this is done because the return - value from snprintf above is unreliable */ - n_digits = strlen(charbuf); - p = charbuf; + p = buf; #endif - /* is a sign character present in the output? if so, remember it + /* Is a sign character present in the output? If so, remember it and skip it */ - sign = p[0]; - if (sign == '-') { + if (*p == '-') { + sign_char = *p; ++p; --n_digits; } - calc_number_widths(&spec, sign, 0, n_digits, format); + /* Determine if we have any "remainder" (after the digits, might include + decimal or exponent or both (or neither)) */ + parse_number(p, n_digits, &n_remainder, &has_decimal); + + /* Determine the grouping, separator, and decimal point, if any. */ + get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE : + (format->thousands_separators ? + LT_DEFAULT_LOCALE : + LT_NO_LOCALE), + &locale); + + /* Calculate how much memory we'll need. */ + n_total = calc_number_widths(&spec, 0, sign_char, p, n_digits, + n_remainder, has_decimal, &locale, format); - /* allocate a string with enough space */ - result = STRINGLIB_NEW(NULL, spec.n_total); + /* Allocate the memory. */ + result = STRINGLIB_NEW(NULL, n_total); if (result == NULL) goto done; - /* Fill in the non-digit parts (padding, sign, etc.) */ - fill_non_digits(STRINGLIB_STR(result), &spec, NULL, n_digits, - format->fill_char == '\0' ? ' ' : format->fill_char); - - /* fill in the digit parts */ - memmove(STRINGLIB_STR(result) + - (spec.n_lpadding + spec.n_lsign + spec.n_spadding), - p, - n_digits * sizeof(STRINGLIB_CHAR)); + /* Populate the memory. */ + fill_number(STRINGLIB_STR(result), &spec, p, n_digits, NULL, + format->fill_char == '\0' ? ' ' : format->fill_char, &locale, + 0); done: + PyMem_Free(buf); +#if STRINGLIB_IS_UNICODE + PyMem_Free(unicode_tmp); +#endif return result; } #endif /* FORMAT_FLOAT */ @@ -856,8 +1001,8 @@ /************************************************************************/ PyObject * FORMAT_STRING(PyObject *obj, - STRINGLIB_CHAR *format_spec, - Py_ssize_t format_spec_len) + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len) { InternalFormatSpec format; PyObject *result = NULL; @@ -871,7 +1016,7 @@ /* parse the format_spec */ if (!parse_internal_render_format_spec(format_spec, format_spec_len, - &format, 's')) + &format, 's')) goto done; /* type conversion? */ @@ -893,9 +1038,9 @@ #if defined FORMAT_LONG || defined FORMAT_INT static PyObject* format_int_or_long(PyObject* obj, - STRINGLIB_CHAR *format_spec, - Py_ssize_t format_spec_len, - IntOrLongToString tostring) + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len, + IntOrLongToString tostring) { PyObject *result = NULL; PyObject *tmp = NULL; @@ -910,8 +1055,8 @@ /* parse the format_spec */ if (!parse_internal_render_format_spec(format_spec, - format_spec_len, - &format, 'd')) + format_spec_len, + &format, 'd')) goto done; /* type conversion? */ @@ -924,8 +1069,8 @@ case 'X': case 'n': /* no type conversion needed, already an int (or long). do - the formatting */ - result = format_int_or_long_internal(obj, &format, tostring); + the formatting */ + result = format_int_or_long_internal(obj, &format, tostring); break; case 'e': @@ -974,11 +1119,11 @@ PyObject * FORMAT_LONG(PyObject *obj, - STRINGLIB_CHAR *format_spec, - Py_ssize_t format_spec_len) + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len) { return format_int_or_long(obj, format_spec, format_spec_len, - long_format); + long_format); } #endif /* FORMAT_LONG */ @@ -995,19 +1140,19 @@ PyObject * FORMAT_INT(PyObject *obj, - STRINGLIB_CHAR *format_spec, - Py_ssize_t format_spec_len) + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len) { return format_int_or_long(obj, format_spec, format_spec_len, - int_format); + int_format); } #endif /* FORMAT_INT */ #ifdef FORMAT_FLOAT PyObject * FORMAT_FLOAT(PyObject *obj, - STRINGLIB_CHAR *format_spec, - Py_ssize_t format_spec_len) + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len) { PyObject *result = NULL; InternalFormatSpec format; @@ -1021,17 +1166,13 @@ /* parse the format_spec */ if (!parse_internal_render_format_spec(format_spec, - format_spec_len, - &format, '\0')) + format_spec_len, + &format, '\0')) goto done; /* type conversion? */ switch (format.type) { - case '\0': - /* 'Z' means like 'g', but with at least one decimal. See - PyOS_ascii_formatd */ - format.type = 'Z'; - /* Deliberate fall through to the next case statement */ + case '\0': /* No format code: like 'g', but with at least one decimal. */ case 'e': case 'E': case 'f': Modified: python/trunk/Objects/stringlib/localeutil.h ============================================================================== --- python/trunk/Objects/stringlib/localeutil.h (original) +++ python/trunk/Objects/stringlib/localeutil.h Wed Apr 22 15:29:05 2009 @@ -5,126 +5,208 @@ #include +#define MAX(x, y) ((x) < (y) ? (y) : (x)) +#define MIN(x, y) ((x) < (y) ? (x) : (y)) + +typedef struct { + const char *grouping; + char previous; + Py_ssize_t i; /* Where we're currently pointing in grouping. */ +} GroupGenerator; + +static void +_GroupGenerator_init(GroupGenerator *self, const char *grouping) +{ + self->grouping = grouping; + self->i = 0; + self->previous = 0; +} + +/* Returns the next grouping, or 0 to signify end. */ +static Py_ssize_t +_GroupGenerator_next(GroupGenerator *self) +{ + /* Note that we don't really do much error checking here. If a + grouping string contains just CHAR_MAX, for example, then just + terminate the generator. That shouldn't happen, but at least we + fail gracefully. */ + switch (self->grouping[self->i]) { + case 0: + return self->previous; + case CHAR_MAX: + /* Stop the generator. */ + return 0; + default: { + char ch = self->grouping[self->i]; + self->previous = ch; + self->i++; + return (Py_ssize_t)ch; + } + } +} + +/* Fill in some digits, leading zeros, and thousands separator. All + are optional, depending on when we're called. */ +static void +fill(STRINGLIB_CHAR **digits_end, STRINGLIB_CHAR **buffer_end, + Py_ssize_t n_chars, Py_ssize_t n_zeros, const char* thousands_sep, + Py_ssize_t thousands_sep_len) +{ +#if STRINGLIB_IS_UNICODE + Py_ssize_t i; +#endif + + if (thousands_sep) { + *buffer_end -= thousands_sep_len; + + /* Copy the thousands_sep chars into the buffer. */ +#if STRINGLIB_IS_UNICODE + /* Convert from the char's of the thousands_sep from + the locale into unicode. */ + for (i = 0; i < thousands_sep_len; ++i) + (*buffer_end)[i] = thousands_sep[i]; +#else + /* No conversion, just memcpy the thousands_sep. */ + memcpy(*buffer_end, thousands_sep, thousands_sep_len); +#endif + } + + *buffer_end -= n_chars; + *digits_end -= n_chars; + memcpy(*buffer_end, *digits_end, n_chars * sizeof(STRINGLIB_CHAR)); + + *buffer_end -= n_zeros; + STRINGLIB_FILL(*buffer_end, '0', n_zeros); +} + /** * _Py_InsertThousandsGrouping: * @buffer: A pointer to the start of a string. - * @n_buffer: The length of the string. + * @n_buffer: Number of characters in @buffer. + * @digits: A pointer to the digits we're reading from. If count + * is non-NULL, this is unused. * @n_digits: The number of digits in the string, in which we want * to put the grouping chars. - * @buf_size: The maximum size of the buffer pointed to by buffer. - * @count: If non-NULL, points to a variable that will receive the - * number of characters we need to insert (and no formatting - * will actually occur). - * @append_zero_char: If non-zero, put a trailing zero at the end of - * of the resulting string, if and only if we modified the - * string. + * @min_width: The minimum width of the digits in the output string. + * Output will be zero-padded on the left to fill. + * @grouping: see definition in localeconv(). + * @thousands_sep: see definition in localeconv(). * - * Inserts thousand grouping characters (as defined in the current - * locale) into the string between buffer and buffer+n_digits. If - * count is non-NULL, don't do any formatting, just count the number - * of characters to insert. This is used by the caller to - * appropriately resize the buffer, if needed. If count is non-NULL, - * buffer can be NULL (it is not dereferenced at all in that case). + * There are 2 modes: counting and filling. If @buffer is NULL, + * we are in counting mode, else filling mode. + * If counting, the required buffer size is returned. + * If filling, we know the buffer will be large enough, so we don't + * need to pass in the buffer size. + * Inserts thousand grouping characters (as defined by grouping and + * thousands_sep) into the string between buffer and buffer+n_digits. * * Return value: 0 on error, else 1. Note that no error can occur if * count is non-NULL. * * This name won't be used, the includer of this file should define * it to be the actual function name, based on unicode or string. + * + * As closely as possible, this code mimics the logic in decimal.py's + _insert_thousands_sep(). **/ -int +Py_ssize_t _Py_InsertThousandsGrouping(STRINGLIB_CHAR *buffer, - Py_ssize_t n_buffer, - Py_ssize_t n_digits, - Py_ssize_t buf_size, - Py_ssize_t *count, - int append_zero_char) + Py_ssize_t n_buffer, + STRINGLIB_CHAR *digits, + Py_ssize_t n_digits, + Py_ssize_t min_width, + const char *grouping, + const char *thousands_sep) { - struct lconv *locale_data = localeconv(); - const char *grouping = locale_data->grouping; - const char *thousands_sep = locale_data->thousands_sep; - Py_ssize_t thousands_sep_len = strlen(thousands_sep); - STRINGLIB_CHAR *pend = NULL; /* current end of buffer */ - STRINGLIB_CHAR *pmax = NULL; /* max of buffer */ - char current_grouping; - Py_ssize_t remaining = n_digits; /* Number of chars remaining to - be looked at */ - - /* Initialize the character count, if we're just counting. */ - if (count) - *count = 0; - else { - /* We're not just counting, we're modifying buffer */ - pend = buffer + n_buffer; - pmax = buffer + buf_size; - } - - /* Starting at the end and working right-to-left, keep track of - what grouping needs to be added and insert that. */ - current_grouping = *grouping++; - - /* If the first character is 0, perform no grouping at all. */ - if (current_grouping == 0) - return 1; - - while (remaining > current_grouping) { - /* Always leave buffer and pend valid at the end of this - loop, since we might leave with a return statement. */ - - remaining -= current_grouping; - if (count) { - /* We're only counting, not touching the memory. */ - *count += thousands_sep_len; - } - else { - /* Do the formatting. */ - - STRINGLIB_CHAR *plast = buffer + remaining; - - /* Is there room to insert thousands_sep_len chars? */ - if (pmax - pend < thousands_sep_len) - /* No room. */ - return 0; - - /* Move the rest of the string down. */ - memmove(plast + thousands_sep_len, - plast, - (pend - plast) * sizeof(STRINGLIB_CHAR)); - /* Copy the thousands_sep chars into the buffer. */ -#if STRINGLIB_IS_UNICODE - /* Convert from the char's of the thousands_sep from - the locale into unicode. */ - { - Py_ssize_t i; - for (i = 0; i < thousands_sep_len; ++i) - plast[i] = thousands_sep[i]; - } -#else - /* No conversion, just memcpy the thousands_sep. */ - memcpy(plast, thousands_sep, thousands_sep_len); -#endif - } + Py_ssize_t count = 0; + Py_ssize_t n_zeros; + int loop_broken = 0; + int use_separator = 0; /* First time through, don't append the + separator. They only go between + groups. */ + STRINGLIB_CHAR *buffer_end = NULL; + STRINGLIB_CHAR *digits_end = NULL; + Py_ssize_t l; + Py_ssize_t n_chars; + Py_ssize_t thousands_sep_len = strlen(thousands_sep); + Py_ssize_t remaining = n_digits; /* Number of chars remaining to + be looked at */ + /* A generator that returns all of the grouping widths, until it + returns 0. */ + GroupGenerator groupgen; + _GroupGenerator_init(&groupgen, grouping); + + if (buffer) { + buffer_end = buffer + n_buffer; + digits_end = digits + n_digits; + } + + while ((l = _GroupGenerator_next(&groupgen)) > 0) { + l = MIN(l, MAX(MAX(remaining, min_width), 1)); + n_zeros = MAX(0, l - remaining); + n_chars = MAX(0, MIN(remaining, l)); + + /* Use n_zero zero's and n_chars chars */ + + /* Count only, don't do anything. */ + count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars; + + if (buffer) { + /* Copy into the output buffer. */ + fill(&digits_end, &buffer_end, n_chars, n_zeros, + use_separator ? thousands_sep : NULL, thousands_sep_len); + } + + /* Use a separator next time. */ + use_separator = 1; + + remaining -= n_chars; + min_width -= l; + + if (remaining <= 0 && min_width <= 0) { + loop_broken = 1; + break; + } + min_width -= thousands_sep_len; + } + if (!loop_broken) { + /* We left the loop without using a break statement. */ + + l = MAX(MAX(remaining, min_width), 1); + n_zeros = MAX(0, l - remaining); + n_chars = MAX(0, MIN(remaining, l)); + + /* Use n_zero zero's and n_chars chars */ + count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars; + if (buffer) { + /* Copy into the output buffer. */ + fill(&digits_end, &buffer_end, n_chars, n_zeros, + use_separator ? thousands_sep : NULL, thousands_sep_len); + } + } + return count; +} - /* Adjust end pointer. */ - pend += thousands_sep_len; +/** + * _Py_InsertThousandsGroupingLocale: + * @buffer: A pointer to the start of a string. + * @n_digits: The number of digits in the string, in which we want + * to put the grouping chars. + * + * Reads thee current locale and calls _Py_InsertThousandsGrouping(). + **/ +Py_ssize_t +_Py_InsertThousandsGroupingLocale(STRINGLIB_CHAR *buffer, + Py_ssize_t n_buffer, + STRINGLIB_CHAR *digits, + Py_ssize_t n_digits, + Py_ssize_t min_width) +{ + struct lconv *locale_data = localeconv(); + const char *grouping = locale_data->grouping; + const char *thousands_sep = locale_data->thousands_sep; - /* Move to the next grouping character, unless we're - repeating (which is designated by a grouping of 0). */ - if (*grouping != 0) { - current_grouping = *grouping++; - if (current_grouping == CHAR_MAX) - /* We're done. */ - break; - } - } - if (append_zero_char) { - /* Append a zero character to mark the end of the string, - if there's room. */ - if (pend - (buffer + remaining) < 1) - /* No room, error. */ - return 0; - *pend = 0; - } - return 1; + return _Py_InsertThousandsGrouping(buffer, n_buffer, digits, n_digits, + min_width, grouping, thousands_sep); } #endif /* STRINGLIB_LOCALEUTIL_H */ Modified: python/trunk/Objects/stringlib/stringdefs.h ============================================================================== --- python/trunk/Objects/stringlib/stringdefs.h (original) +++ python/trunk/Objects/stringlib/stringdefs.h Wed Apr 22 15:29:05 2009 @@ -6,6 +6,15 @@ compiled as unicode. */ #define STRINGLIB_IS_UNICODE 0 +/* _tolower and _toupper are defined by SUSv2, but they're not ISO C */ +/* This needs to be cleaned up. See issue 5793. */ +#ifndef _tolower +#define _tolower tolower +#endif +#ifndef _toupper +#define _toupper toupper +#endif + #define STRINGLIB_OBJECT PyStringObject #define STRINGLIB_CHAR char #define STRINGLIB_TYPE_NAME "string" @@ -13,8 +22,8 @@ #define STRINGLIB_EMPTY nullstring #define STRINGLIB_ISDECIMAL(x) ((x >= '0') && (x <= '9')) #define STRINGLIB_TODECIMAL(x) (STRINGLIB_ISDECIMAL(x) ? (x - '0') : -1) -#define STRINGLIB_TOUPPER toupper -#define STRINGLIB_TOLOWER tolower +#define STRINGLIB_TOUPPER(x) _toupper(Py_CHARMASK(x)) +#define STRINGLIB_TOLOWER(x) _tolower(Py_CHARMASK(x)) #define STRINGLIB_FILL memset #define STRINGLIB_STR PyString_AS_STRING #define STRINGLIB_LEN PyString_GET_SIZE @@ -24,5 +33,6 @@ #define STRINGLIB_CMP memcmp #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_GROUPING _PyString_InsertThousandsGrouping +#define STRINGLIB_GROUPING_LOCALE _PyString_InsertThousandsGroupingLocale #endif /* !STRINGLIB_STRINGDEFS_H */ Modified: python/trunk/Python/pystrtod.c ============================================================================== --- python/trunk/Python/pystrtod.c (original) +++ python/trunk/Python/pystrtod.c Wed Apr 22 15:29:05 2009 @@ -37,6 +37,15 @@ * * Return value: the #gdouble value. **/ + +/* + Use system strtod; since strtod is locale aware, we may + have to first fix the decimal separator. + + Note that unlike _Py_dg_strtod, the system strtod may not always give + correctly rounded results. +*/ + double PyOS_ascii_strtod(const char *nptr, char **endptr) { @@ -187,6 +196,13 @@ return val; } +double +PyOS_ascii_atof(const char *nptr) +{ + return PyOS_ascii_strtod(nptr, NULL); +} + + /* Given a string that may have a decimal point in the current locale, change it back to a dot. Since the string cannot get longer, no need for a maximum buffer size parameter. */ @@ -292,8 +308,9 @@ } } -/* Ensure that buffer has a decimal point in it. The decimal point - will not be in the current locale, it will always be '.' */ +/* Ensure that buffer has a decimal point in it. The decimal point will not + be in the current locale, it will always be '.'. Don't add a decimal if an + exponent is present. */ Py_LOCAL_INLINE(void) ensure_decimal_point(char* buffer, size_t buf_size) { @@ -322,7 +339,8 @@ insert_count = 1; } } - else { + else if (!(*p == 'e' || *p == 'E')) { + /* Don't add ".0" if we have an exponent. */ chars_to_insert = ".0"; insert_count = 2; } @@ -341,37 +359,6 @@ } } -/* Add the locale specific grouping characters to buffer. Note - that any decimal point (if it's present) in buffer is already - locale-specific. Return 0 on error, else 1. */ -Py_LOCAL_INLINE(int) -add_thousands_grouping(char* buffer, size_t buf_size) -{ - Py_ssize_t len = strlen(buffer); - struct lconv *locale_data = localeconv(); - const char *decimal_point = locale_data->decimal_point; - - /* Find the decimal point, if any. We're only concerned - about the characters to the left of the decimal when - adding grouping. */ - char *p = strstr(buffer, decimal_point); - if (!p) { - /* No decimal, use the entire string. */ - - /* If any exponent, adjust p. */ - p = strpbrk(buffer, "eE"); - if (!p) - /* No exponent and no decimal. Use the entire - string. */ - p = buffer + len; - } - /* At this point, p points just past the right-most character we - want to format. We need to add the grouping string for the - characters between buffer and p. */ - return _PyString_InsertThousandsGrouping(buffer, len, p-buffer, - buf_size, NULL, 1); -} - /* see FORMATBUFLEN in unicodeobject.c */ #define FLOAT_FORMATBUFLEN 120 @@ -386,9 +373,8 @@ * Converts a #gdouble to a string, using the '.' as * decimal point. To format the number you pass in * a printf()-style format string. Allowed conversion - * specifiers are 'e', 'E', 'f', 'F', 'g', 'G', and 'n'. + * specifiers are 'e', 'E', 'f', 'F', 'g', 'G', and 'Z'. * - * 'n' is the same as 'g', except it uses the current locale. * 'Z' is the same as 'g', except it always has a decimal and * at least one digit after the decimal. * @@ -403,11 +389,6 @@ char format_char; size_t format_len = strlen(format); - /* For type 'n', we need to make a copy of the format string, because - we're going to modify 'n' -> 'g', and format is const char*, so we - can't modify it directly. FLOAT_FORMATBUFLEN should be longer than - we ever need this to be. There's an upcoming check to ensure it's - big enough. */ /* Issue 2264: code 'Z' requires copying the format. 'Z' is 'g', but also with at least one character past the decimal. */ char tmp_format[FLOAT_FORMATBUFLEN]; @@ -433,12 +414,12 @@ if (!(format_char == 'e' || format_char == 'E' || format_char == 'f' || format_char == 'F' || format_char == 'g' || format_char == 'G' || - format_char == 'n' || format_char == 'Z')) + format_char == 'Z')) return NULL; - /* Map 'n' or 'Z' format_char to 'g', by copying the format string and + /* Map 'Z' format_char to 'g', by copying the format string and replacing the final char with a 'g' */ - if (format_char == 'n' || format_char == 'Z') { + if (format_char == 'Z') { if (format_len + 1 >= sizeof(tmp_format)) { /* The format won't fit in our copy. Error out. In practice, this will never happen and will be @@ -457,11 +438,8 @@ /* Do various fixups on the return string */ /* Get the current locale, and find the decimal point string. - Convert that string back to a dot. Do not do this if using the - 'n' (number) format code, since we want to keep the localized - decimal point in that case. */ - if (format_char != 'n') - change_decimal_from_locale_to_dot(buffer); + Convert that string back to a dot. */ + change_decimal_from_locale_to_dot(buffer); /* If an exponent exists, ensure that the exponent is at least MIN_EXPONENT_DIGITS digits, providing the buffer is large enough @@ -475,16 +453,111 @@ if (format_char == 'Z') ensure_decimal_point(buffer, buf_size); - /* If format_char is 'n', add the thousands grouping. */ - if (format_char == 'n') - if (!add_thousands_grouping(buffer, buf_size)) - return NULL; - return buffer; } -double -PyOS_ascii_atof(const char *nptr) +PyAPI_FUNC(char *) PyOS_double_to_string(double val, + char format_code, + int precision, + int flags, + int *type) { - return PyOS_ascii_strtod(nptr, NULL); + char buf[128]; + char format[32]; + Py_ssize_t len; + char *result; + char *p; + int t; + int upper = 0; + + /* Validate format_code, and map upper and lower case */ + switch (format_code) { + case 'e': /* exponent */ + case 'f': /* fixed */ + case 'g': /* general */ + break; + case 'E': + upper = 1; + format_code = 'e'; + break; + case 'F': + upper = 1; + format_code = 'f'; + break; + case 'G': + upper = 1; + format_code = 'g'; + break; + case 'r': /* repr format */ + /* Supplied precision is unused, must be 0. */ + if (precision != 0) { + PyErr_BadInternalCall(); + return NULL; + } + precision = 17; + format_code = 'g'; + break; + case 's': /* str format */ + /* Supplied precision is unused, must be 0. */ + if (precision != 0) { + PyErr_BadInternalCall(); + return NULL; + } + precision = 12; + format_code = 'g'; + break; + default: + PyErr_BadInternalCall(); + return NULL; + } + + /* Handle nan and inf. */ + if (Py_IS_NAN(val)) { + strcpy(buf, "nan"); + t = Py_DTST_NAN; + } else if (Py_IS_INFINITY(val)) { + if (copysign(1., val) == 1.) + strcpy(buf, "inf"); + else + strcpy(buf, "-inf"); + t = Py_DTST_INFINITE; + } else { + t = Py_DTST_FINITE; + + + if (flags & Py_DTSF_ADD_DOT_0) + format_code = 'Z'; + + PyOS_snprintf(format, 32, "%%%s.%i%c", (flags & Py_DTSF_ALT ? "#" : ""), precision, format_code); + PyOS_ascii_formatd(buf, sizeof(buf), format, val); + } + + len = strlen(buf); + + /* Add 1 for the trailing 0 byte. + Add 1 because we might need to make room for the sign. + */ + result = PyMem_Malloc(len + 2); + if (result == NULL) { + PyErr_NoMemory(); + return NULL; + } + p = result; + + /* Never add sign for nan/inf, even if asked. */ + if (flags & Py_DTSF_SIGN && buf[0] != '-' && t == Py_DTST_FINITE) + *p++ = '+'; + + strcpy(p, buf); + + if (upper) { + /* Convert to upper case. */ + char *p1; + for (p1 = p; *p1; p1++) + *p1 = toupper(*p1); + } + + if (type) + *type = t; + return result; } From python-checkins at python.org Wed Apr 22 15:30:25 2009 From: python-checkins at python.org (eric.smith) Date: Wed, 22 Apr 2009 15:30:25 +0200 (CEST) Subject: [Python-checkins] r71797 - python/branches/release26-maint Message-ID: <20090422133025.1B9EC1E414C@bag.python.org> Author: eric.smith Date: Wed Apr 22 15:30:24 2009 New Revision: 71797 Log: Blocked revisions 71796 via svnmerge ........ r71796 | eric.smith | 2009-04-22 09:29:05 -0400 (Wed, 22 Apr 2009) | 20 lines Backport of some of the work in r71665 to trunk. This reworks much of int, long, and float __format__(), and it keeps their implementation in sync with py3k. Also added PyOS_double_to_string. This is the "fallback" version that's also available in trunk, and should be kept in sync with that code. I'll add an issue to document PyOS_double_to_string in the C API. There are many internal cleanups. Externally visible changes include: - Implement PEP 378, Format Specifier for Thousands Separator, for floats, ints, and longs. - Issue #5515: 'n' formatting for ints, longs, and floats handles leading zero formatting poorly. - Issue #5772: For float.__format__, don't add a trailing ".0" if we're using no type code and we have an exponent. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Wed Apr 22 15:30:56 2009 From: python-checkins at python.org (eric.smith) Date: Wed, 22 Apr 2009 15:30:56 +0200 (CEST) Subject: [Python-checkins] r71798 - python/branches/py3k Message-ID: <20090422133056.E25F11E4132@bag.python.org> Author: eric.smith Date: Wed Apr 22 15:30:56 2009 New Revision: 71798 Log: Blocked revisions 71796 via svnmerge ........ r71796 | eric.smith | 2009-04-22 09:29:05 -0400 (Wed, 22 Apr 2009) | 20 lines Backport of some of the work in r71665 to trunk. This reworks much of int, long, and float __format__(), and it keeps their implementation in sync with py3k. Also added PyOS_double_to_string. This is the "fallback" version that's also available in trunk, and should be kept in sync with that code. I'll add an issue to document PyOS_double_to_string in the C API. There are many internal cleanups. Externally visible changes include: - Implement PEP 378, Format Specifier for Thousands Separator, for floats, ints, and longs. - Issue #5515: 'n' formatting for ints, longs, and floats handles leading zero formatting poorly. - Issue #5772: For float.__format__, don't add a trailing ".0" if we're using no type code and we have an exponent. ........ Modified: python/branches/py3k/ (props changed) From buildbot at python.org Wed Apr 22 16:11:54 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 22 Apr 2009 14:11:54 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 2.6 Message-ID: <20090422141154.D6A081E4020@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%202.6/builds/272 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: eric.smith BUILD FAILED: failed test Excerpt from the test logfile: Traceback (most recent call last): File "/home/pybot/buildarea/2.6.klose-ubuntu-i386/build/Lib/test/test_signal.py", line 165, in test_main pickle.dump(None, done_w) File "/home/pybot/buildarea/2.6.klose-ubuntu-i386/build/Lib/contextlib.py", line 153, in __exit__ self.thing.close() IOError: [Errno 9] Bad file descriptor 1 test failed: test_signal make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Wed Apr 22 16:14:35 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 22 Apr 2009 14:14:35 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 2.6 Message-ID: <20090422141435.441431E4020@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%202.6/builds/240 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: eric.smith BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_smtplib make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Wed Apr 22 17:26:05 2009 From: python-checkins at python.org (nick.coghlan) Date: Wed, 22 Apr 2009 17:26:05 +0200 (CEST) Subject: [Python-checkins] r71799 - in python/trunk: Doc/library/test.rst Lib/test/test_heapq.py Lib/test/test_support.py Lib/test/test_warnings.py Misc/NEWS Message-ID: <20090422152605.20B1A1E4039@bag.python.org> Author: nick.coghlan Date: Wed Apr 22 17:26:04 2009 New Revision: 71799 Log: Issue 5354: Change API for import_fresh_module() to better support test_warnings use case (also fixes some bugs in the original implementation) Modified: python/trunk/Doc/library/test.rst python/trunk/Lib/test/test_heapq.py python/trunk/Lib/test/test_support.py python/trunk/Lib/test/test_warnings.py python/trunk/Misc/NEWS Modified: python/trunk/Doc/library/test.rst ============================================================================== --- python/trunk/Doc/library/test.rst (original) +++ python/trunk/Doc/library/test.rst Wed Apr 22 17:26:04 2009 @@ -351,15 +351,39 @@ .. versionadded:: 2.7 -.. function:: import_fresh_module(name, blocked_names=None, deprecated=False) +.. function:: import_fresh_module(name, fresh=(), blocked=(), deprecated=False) - This function imports and returns a fresh copy of the named Python module. The - ``sys.modules`` cache is bypassed temporarily, and the ability to import the - modules named in *blocked_names* is suppressed for the duration of the import. + This function imports and returns a fresh copy of the named Python module + by removing the named module from ``sys.modules`` before doing the import. + Note that unlike :func:`reload`, the original module is not affected by + this operation. + + *fresh* is an iterable of additional module names that are also removed + from the ``sys.modules`` cache before doing the import. + + *blocked* is an iterable of module names that are replaced with :const:`0` + in the module cache during the import to ensure that attempts to import + them raise :exc:`ImportError`. + + The named module and any modules named in the *fresh* and *blocked* + parameters are saved before starting the import and then reinserted into + ``sys.modules`` when the fresh import is complete. Module and package deprecation messages are suppressed during this import if *deprecated* is :const:`True`. + This function will raise :exc:`unittest.SkipTest` is the named module + cannot be imported. + + Example use:: + + # Get copies of the warnings module for testing without + # affecting the version being used by the rest of the test suite + # One copy uses the C implementation, the other is forced to use + # the pure Python fallback implementation + py_warnings = import_fresh_module('warnings', blocked=['_warnings']) + c_warnings = import_fresh_module('warnings', fresh=['_warnings']) + .. versionadded:: 2.7 Modified: python/trunk/Lib/test/test_heapq.py ============================================================================== --- python/trunk/Lib/test/test_heapq.py (original) +++ python/trunk/Lib/test/test_heapq.py Wed Apr 22 17:26:04 2009 @@ -8,7 +8,7 @@ # We do a bit of trickery here to be able to test both the C implementation # and the Python implementation of the module. import heapq as c_heapq -py_heapq = test_support.import_fresh_module('heapq', ['_heapq']) +py_heapq = test_support.import_fresh_module('heapq', blocked=['_heapq']) class TestHeap(unittest.TestCase): module = None Modified: python/trunk/Lib/test/test_support.py ============================================================================== --- python/trunk/Lib/test/test_support.py (original) +++ python/trunk/Lib/test/test_support.py Wed Apr 22 17:26:04 2009 @@ -70,12 +70,43 @@ raise unittest.SkipTest(str(msg)) -def import_fresh_module(name, blocked_names=None, deprecated=False): +def _save_and_remove_module(name, orig_modules): + """Helper function to save and remove a module from sys.modules + + Return value is True if the module was in sys.modules and + False otherwise.""" + saved = True + try: + orig_modules[name] = sys.modules[name] + except KeyError: + saved = False + else: + del sys.modules[name] + return saved + + +def _save_and_block_module(name, orig_modules): + """Helper function to save and block a module in sys.modules + + Return value is True if the module was in sys.modules and + False otherwise.""" + saved = True + try: + orig_modules[name] = sys.modules[name] + except KeyError: + saved = False + sys.modules[name] = 0 + return saved + + +def import_fresh_module(name, fresh=(), blocked=(), deprecated=False): """Imports and returns a module, deliberately bypassing the sys.modules cache and importing a fresh copy of the module. Once the import is complete, the sys.modules cache is restored to its original state. - Importing of modules named in blocked_names is prevented while the fresh import + Modules named in fresh are also imported anew if needed by the import. + + Importing of modules named in blocked is prevented while the fresh import takes place. If deprecated is True, any module or package deprecation messages @@ -83,21 +114,24 @@ # NOTE: test_heapq and test_warnings include extra sanity checks to make # sure that this utility function is working as expected with _ignore_deprecated_imports(deprecated): - if blocked_names is None: - blocked_names = () + # Keep track of modules saved for later restoration as well + # as those which just need a blocking entry removed orig_modules = {} - if name in sys.modules: - orig_modules[name] = sys.modules[name] - del sys.modules[name] + names_to_remove = [] + _save_and_remove_module(name, orig_modules) try: - for blocked in blocked_names: - orig_modules[blocked] = sys.modules[blocked] - sys.modules[blocked] = 0 - py_module = importlib.import_module(name) + for fresh_name in fresh: + _save_and_remove_module(fresh_name, orig_modules) + for blocked_name in blocked: + if not _save_and_block_module(blocked_name, orig_modules): + names_to_remove.append(blocked_name) + fresh_module = importlib.import_module(name) finally: - for blocked, module in orig_modules.items(): - sys.modules[blocked] = module - return py_module + for orig_name, module in orig_modules.items(): + sys.modules[orig_name] = module + for name_to_remove in names_to_remove: + del sys.modules[name_to_remove] + return fresh_module def get_attribute(obj, name): Modified: python/trunk/Lib/test/test_warnings.py ============================================================================== --- python/trunk/Lib/test/test_warnings.py (original) +++ python/trunk/Lib/test/test_warnings.py Wed Apr 22 17:26:04 2009 @@ -10,8 +10,8 @@ import warnings as original_warnings -py_warnings = test_support.import_fresh_module('warnings', ['_warnings']) -c_warnings = test_support.import_fresh_module('warnings') +py_warnings = test_support.import_fresh_module('warnings', blocked=['_warnings']) +c_warnings = test_support.import_fresh_module('warnings', fresh=['_warnings']) @contextmanager def warnings_state(module): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Apr 22 17:26:04 2009 @@ -839,6 +839,12 @@ Tests ----- +- Issue #5354: New test support function import_fresh_module() makes + it easy to import both normal and optimised versions of modules. + test_heapq and test_warnings have been adjusted to use it, tests for + other modules with both C and Python implementations in the stdlib + can be adjusted to use it over time. + - Fix test_warnings to no longer reset the warnings filter. - Fix test_logging to no longer reset the warnings filter. From python-checkins at python.org Wed Apr 22 17:39:45 2009 From: python-checkins at python.org (nick.coghlan) Date: Wed, 22 Apr 2009 17:39:45 +0200 (CEST) Subject: [Python-checkins] r71800 - python/branches/release26-maint Message-ID: <20090422153945.9D0161E4016@bag.python.org> Author: nick.coghlan Date: Wed Apr 22 17:39:45 2009 New Revision: 71800 Log: Blocked revisions 71799 via svnmerge ........ r71799 | nick.coghlan | 2009-04-23 01:26:04 +1000 (Thu, 23 Apr 2009) | 1 line Issue 5354: Change API for import_fresh_module() to better support test_warnings use case (also fixes some bugs in the original implementation) ........ Modified: python/branches/release26-maint/ (props changed) From buildbot at python.org Wed Apr 22 18:12:52 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 22 Apr 2009 16:12:52 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu trunk Message-ID: <20090422161252.E9EE71E403A@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%20trunk/builds/1265 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: nick.coghlan BUILD FAILED: failed failed slave lost sincerely, -The Buildbot From python-checkins at python.org Wed Apr 22 18:13:37 2009 From: python-checkins at python.org (nick.coghlan) Date: Wed, 22 Apr 2009 18:13:37 +0200 (CEST) Subject: [Python-checkins] r71801 - in python/branches/py3k: Doc/library/test.rst Lib/test/support.py Lib/test/test_heapq.py Lib/test/test_warnings.py Misc/NEWS Message-ID: <20090422161337.07D0B1E403A@bag.python.org> Author: nick.coghlan Date: Wed Apr 22 18:13:36 2009 New Revision: 71801 Log: Merged revisions 71799 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71799 | nick.coghlan | 2009-04-23 01:26:04 +1000 (Thu, 23 Apr 2009) | 1 line Issue 5354: Change API for import_fresh_module() to better support test_warnings use case (also fixes some bugs in the original implementation) ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/test.rst python/branches/py3k/Lib/test/support.py python/branches/py3k/Lib/test/test_heapq.py python/branches/py3k/Lib/test/test_warnings.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/test.rst ============================================================================== --- python/branches/py3k/Doc/library/test.rst (original) +++ python/branches/py3k/Doc/library/test.rst Wed Apr 22 18:13:36 2009 @@ -8,8 +8,8 @@ The :mod:`test` package contains all regression tests for Python as well as the -modules :mod:`test.test_support` and :mod:`test.regrtest`. -:mod:`test.test_support` is used to enhance your tests while +modules :mod:`test.support` and :mod:`test.regrtest`. +:mod:`test.support` is used to enhance your tests while :mod:`test.regrtest` drives the testing suite. Each module in the :mod:`test` package whose name starts with ``test_`` is a @@ -47,7 +47,7 @@ A basic boilerplate is often used:: import unittest - from test import test_support + from test import support class MyTestCase1(unittest.TestCase): @@ -75,7 +75,7 @@ ... more test classes ... def test_main(): - test_support.run_unittest(MyTestCase1, + support.run_unittest(MyTestCase1, MyTestCase2, ... list other tests ... ) @@ -273,7 +273,7 @@ following :func:`test_main` function:: def test_main(): - test_support.run_unittest(__name__) + support.run_unittest(__name__) This will run all tests defined in the named module. @@ -334,15 +334,39 @@ .. versionadded:: 3.1 -.. function:: import_fresh_module(name, blocked_names=None, deprecated=False) +.. function:: import_fresh_module(name, fresh=(), blocked=(), deprecated=False) - This function imports and returns a fresh copy of the named Python module. The - ``sys.modules`` cache is bypassed temporarily, and the ability to import the - modules named in *blocked_names* is suppressed for the duration of the import. + This function imports and returns a fresh copy of the named Python module + by removing the named module from ``sys.modules`` before doing the import. + Note that unlike :func:`reload`, the original module is not affected by + this operation. + + *fresh* is an iterable of additional module names that are also removed + from the ``sys.modules`` cache before doing the import. + + *blocked* is an iterable of module names that are replaced with :const:`0` + in the module cache during the import to ensure that attempts to import + them raise :exc:`ImportError`. + + The named module and any modules named in the *fresh* and *blocked* + parameters are saved before starting the import and then reinserted into + ``sys.modules`` when the fresh import is complete. Module and package deprecation messages are suppressed during this import if *deprecated* is :const:`True`. + This function will raise :exc:`unittest.SkipTest` is the named module + cannot be imported. + + Example use:: + + # Get copies of the warnings module for testing without + # affecting the version being used by the rest of the test suite + # One copy uses the C implementation, the other is forced to use + # the pure Python fallback implementation + py_warnings = import_fresh_module('warnings', blocked=['_warnings']) + c_warnings = import_fresh_module('warnings', fresh=['_warnings']) + .. versionadded:: 3.1 Modified: python/branches/py3k/Lib/test/support.py ============================================================================== --- python/branches/py3k/Lib/test/support.py (original) +++ python/branches/py3k/Lib/test/support.py Wed Apr 22 18:13:36 2009 @@ -69,12 +69,43 @@ raise unittest.SkipTest(str(msg)) -def import_fresh_module(name, blocked_names=None, deprecated=False): +def _save_and_remove_module(name, orig_modules): + """Helper function to save and remove a module from sys.modules + + Return value is True if the module was in sys.modules and + False otherwise.""" + saved = True + try: + orig_modules[name] = sys.modules[name] + except KeyError: + saved = False + else: + del sys.modules[name] + return saved + + +def _save_and_block_module(name, orig_modules): + """Helper function to save and block a module in sys.modules + + Return value is True if the module was in sys.modules and + False otherwise.""" + saved = True + try: + orig_modules[name] = sys.modules[name] + except KeyError: + saved = False + sys.modules[name] = 0 + return saved + + +def import_fresh_module(name, fresh=(), blocked=(), deprecated=False): """Imports and returns a module, deliberately bypassing the sys.modules cache and importing a fresh copy of the module. Once the import is complete, the sys.modules cache is restored to its original state. - Importing of modules named in blocked_names is prevented while the fresh import + Modules named in fresh are also imported anew if needed by the import. + + Importing of modules named in blocked is prevented while the fresh import takes place. If deprecated is True, any module or package deprecation messages @@ -82,21 +113,24 @@ # NOTE: test_heapq and test_warnings include extra sanity checks to make # sure that this utility function is working as expected with _ignore_deprecated_imports(deprecated): - if blocked_names is None: - blocked_names = () + # Keep track of modules saved for later restoration as well + # as those which just need a blocking entry removed orig_modules = {} - if name in sys.modules: - orig_modules[name] = sys.modules[name] - del sys.modules[name] + names_to_remove = [] + _save_and_remove_module(name, orig_modules) try: - for blocked in blocked_names: - orig_modules[blocked] = sys.modules[blocked] - sys.modules[blocked] = 0 - py_module = importlib.import_module(name) + for fresh_name in fresh: + _save_and_remove_module(fresh_name, orig_modules) + for blocked_name in blocked: + if not _save_and_block_module(blocked_name, orig_modules): + names_to_remove.append(blocked_name) + fresh_module = importlib.import_module(name) finally: - for blocked, module in orig_modules.items(): - sys.modules[blocked] = module - return py_module + for orig_name, module in orig_modules.items(): + sys.modules[orig_name] = module + for name_to_remove in names_to_remove: + del sys.modules[name_to_remove] + return fresh_module def get_attribute(obj, name): Modified: python/branches/py3k/Lib/test/test_heapq.py ============================================================================== --- python/branches/py3k/Lib/test/test_heapq.py (original) +++ python/branches/py3k/Lib/test/test_heapq.py Wed Apr 22 18:13:36 2009 @@ -8,7 +8,7 @@ # We do a bit of trickery here to be able to test both the C implementation # and the Python implementation of the module. import heapq as c_heapq -py_heapq = support.import_fresh_module('heapq', ['_heapq']) +py_heapq = support.import_fresh_module('heapq', blocked=['_heapq']) class TestHeap(unittest.TestCase): module = None Modified: python/branches/py3k/Lib/test/test_warnings.py ============================================================================== --- python/branches/py3k/Lib/test/test_warnings.py (original) +++ python/branches/py3k/Lib/test/test_warnings.py Wed Apr 22 18:13:36 2009 @@ -10,14 +10,8 @@ import warnings as original_warnings -py_warnings = support.import_fresh_module('warnings', ['_warnings']) -# XXX (ncoghlan 20090412): -# Something in Py3k doesn't like sharing the same instance of -# _warnings between original_warnings and c_warnings -# Will leave issue 5354 open until I understand why 3.x breaks -# without the next line, while 2.x doesn't care -del sys.modules['_warnings'] -c_warnings = support.import_fresh_module('warnings') +py_warnings = support.import_fresh_module('warnings', blocked=['_warnings']) +c_warnings = support.import_fresh_module('warnings', fresh=['_warnings']) @contextmanager def warnings_state(module): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Apr 22 18:13:36 2009 @@ -98,6 +98,15 @@ - Issue #5359: Readd the Berkley-DB detection code to allow _dbm be built using Berkley-DB. +Tests +----- + +- Issue #5354: New test support function import_fresh_module() makes + it easy to import both normal and optimised versions of modules. + test_heapq and test_warnings have been adjusted to use it, tests for + other modules with both C and Python implementations in the stdlib + can be adjusted to use it over time. + What's New in Python 3.1 alpha 2? ================================= From python-checkins at python.org Wed Apr 22 18:20:48 2009 From: python-checkins at python.org (eric.smith) Date: Wed, 22 Apr 2009 18:20:48 +0200 (CEST) Subject: [Python-checkins] r71802 - in python/trunk: Lib/test/test_types.py Objects/stringlib/formatter.h Message-ID: <20090422162048.044FA1E4059@bag.python.org> Author: eric.smith Date: Wed Apr 22 18:20:47 2009 New Revision: 71802 Log: Fixed issue 5782: formatting with commas didn't work if no specifier type code was given. Modified: python/trunk/Lib/test/test_types.py python/trunk/Objects/stringlib/formatter.h Modified: python/trunk/Lib/test/test_types.py ============================================================================== --- python/trunk/Lib/test/test_types.py (original) +++ python/trunk/Lib/test/test_types.py Wed Apr 22 18:20:47 2009 @@ -405,6 +405,9 @@ test(123456, "#012X", '0X000001E240') test(-123456, "#012X", '-0X00001E240') + # issue 5782, commas with no specifier type + test(1234, '010,', '00,001,234') + # make sure these are errors # precision disallowed @@ -632,6 +635,9 @@ test(-1234.12341234, '013f', '-01234.123412') test(-123456.12341234, '011.2f', '-0123456.12') + # issue 5782, commas with no specifier type + test(1.2, '010,.2', '0,000,001.2') + # 0 padding with commas test(1234., '011,f', '1,234.000000') test(1234., '012,f', '1,234.000000') Modified: python/trunk/Objects/stringlib/formatter.h ============================================================================== --- python/trunk/Objects/stringlib/formatter.h (original) +++ python/trunk/Objects/stringlib/formatter.h Wed Apr 22 18:20:47 2009 @@ -248,6 +248,7 @@ case 'G': case '%': case 'F': + case '\0': /* These are allowed. See PEP 378.*/ break; default: From python-checkins at python.org Wed Apr 22 18:23:00 2009 From: python-checkins at python.org (nick.coghlan) Date: Wed, 22 Apr 2009 18:23:00 +0200 (CEST) Subject: [Python-checkins] r71803 - python/branches/release30-maint Message-ID: <20090422162300.60B621E403E@bag.python.org> Author: nick.coghlan Date: Wed Apr 22 18:23:00 2009 New Revision: 71803 Log: Blocked revisions 71801 via svnmerge ................ r71801 | nick.coghlan | 2009-04-23 02:13:36 +1000 (Thu, 23 Apr 2009) | 9 lines Merged revisions 71799 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71799 | nick.coghlan | 2009-04-23 01:26:04 +1000 (Thu, 23 Apr 2009) | 1 line Issue 5354: Change API for import_fresh_module() to better support test_warnings use case (also fixes some bugs in the original implementation) ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Wed Apr 22 19:04:28 2009 From: python-checkins at python.org (eric.smith) Date: Wed, 22 Apr 2009 19:04:28 +0200 (CEST) Subject: [Python-checkins] r71804 - in python/branches/py3k: Lib/test/test_types.py Objects/stringlib/formatter.h Message-ID: <20090422170428.C29B81E403A@bag.python.org> Author: eric.smith Date: Wed Apr 22 19:04:27 2009 New Revision: 71804 Log: Merged revisions 71802 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71802 | eric.smith | 2009-04-22 12:20:47 -0400 (Wed, 22 Apr 2009) | 1 line Fixed issue 5782: formatting with commas didn't work if no specifier type code was given. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_types.py python/branches/py3k/Objects/stringlib/formatter.h Modified: python/branches/py3k/Lib/test/test_types.py ============================================================================== --- python/branches/py3k/Lib/test/test_types.py (original) +++ python/branches/py3k/Lib/test/test_types.py Wed Apr 22 19:04:27 2009 @@ -350,6 +350,9 @@ test(1234567, ',', '1,234,567') test(-1234567, ',', '-1,234,567') + # issue 5782, commas with no specifier type + test(1234, '010,', '00,001,234') + # make sure these are errors # precision disallowed @@ -567,6 +570,9 @@ test(-1234.12341234, '013f', '-01234.123412') test(-123456.12341234, '011.2f', '-0123456.12') + # issue 5782, commas with no specifier type + test(1.2, '010,.2', '0,000,001.2') + # 0 padding with commas test(1234., '011,f', '1,234.000000') test(1234., '012,f', '1,234.000000') Modified: python/branches/py3k/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k/Objects/stringlib/formatter.h (original) +++ python/branches/py3k/Objects/stringlib/formatter.h Wed Apr 22 19:04:27 2009 @@ -248,6 +248,7 @@ case 'G': case '%': case 'F': + case '\0': /* These are allowed. See PEP 378.*/ break; default: From python-checkins at python.org Wed Apr 22 19:14:38 2009 From: python-checkins at python.org (eric.smith) Date: Wed, 22 Apr 2009 19:14:38 +0200 (CEST) Subject: [Python-checkins] r71805 - python/branches/release30-maint Message-ID: <20090422171438.4A79D1E421F@bag.python.org> Author: eric.smith Date: Wed Apr 22 19:14:37 2009 New Revision: 71805 Log: Blocked revisions 71804 via svnmerge ................ r71804 | eric.smith | 2009-04-22 13:04:27 -0400 (Wed, 22 Apr 2009) | 9 lines Merged revisions 71802 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71802 | eric.smith | 2009-04-22 12:20:47 -0400 (Wed, 22 Apr 2009) | 1 line Fixed issue 5782: formatting with commas didn't work if no specifier type code was given. ........ ................ Modified: python/branches/release30-maint/ (props changed) From buildbot at python.org Wed Apr 22 19:33:21 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 22 Apr 2009 17:33:21 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 3.0 Message-ID: <20090422173321.493251E4059@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%203.0/builds/303 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: eric.smith BUILD FAILED: failed test Excerpt from the test logfile: make: *** [buildbottest] Unknown signal 32 sincerely, -The Buildbot From python-checkins at python.org Wed Apr 22 19:50:22 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 22 Apr 2009 19:50:22 +0200 (CEST) Subject: [Python-checkins] r71806 - in python/branches/py3k: Doc/library/fractions.rst Lib/fractions.py Lib/test/test_fractions.py Misc/NEWS Message-ID: <20090422175022.4B7E71E40C5@bag.python.org> Author: mark.dickinson Date: Wed Apr 22 19:50:21 2009 New Revision: 71806 Log: Issue #5812: Make Fraction('1e6') valid. The Fraction constructor now accepts all strings accepted by the float and Decimal constructors, with the exception of strings representing NaNs or infinities. Modified: python/branches/py3k/Doc/library/fractions.rst python/branches/py3k/Lib/fractions.py python/branches/py3k/Lib/test/test_fractions.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Doc/library/fractions.rst ============================================================================== --- python/branches/py3k/Doc/library/fractions.rst (original) +++ python/branches/py3k/Doc/library/fractions.rst Wed Apr 22 19:50:21 2009 @@ -25,21 +25,18 @@ :exc:`ZeroDivisionError`. The second version requires that *other_fraction* is an instance of :class:`numbers.Rational` and returns an :class:`Fraction` instance with the same value. The - last version of the constructor expects a string - instance in one of two possible forms. The first form is:: + last version of the constructor expects a string instance. The + usual form for this string is:: [sign] numerator ['/' denominator] where the optional ``sign`` may be either '+' or '-' and ``numerator`` and ``denominator`` (if present) are strings of - decimal digits. The second permitted form is that of a number - containing a decimal point:: - - [sign] integer '.' [fraction] | [sign] '.' fraction - - where ``integer`` and ``fraction`` are strings of digits. In - either form the input string may also have leading and/or trailing - whitespace. Here are some examples:: + decimal digits. In addition, any string that represents a finite + value and is accepted by the :class:`float` constructor is also + accepted by the :class:`Fraction` constructor. In either form the + input string may also have leading and/or trailing whitespace. + Here are some examples:: >>> from fractions import Fraction >>> Fraction(16, -10) @@ -57,6 +54,8 @@ Fraction(1414213, 1000000) >>> Fraction('-.125') Fraction(-1, 8) + >>> Fraction('7e-6') + Fraction(7, 1000000) The :class:`Fraction` class inherits from the abstract base class Modified: python/branches/py3k/Lib/fractions.py ============================================================================== --- python/branches/py3k/Lib/fractions.py (original) +++ python/branches/py3k/Lib/fractions.py Wed Apr 22 19:50:21 2009 @@ -28,13 +28,14 @@ (?P[-+]?) # an optional sign, then (?=\d|\.\d) # lookahead for digit or .digit (?P\d*) # numerator (possibly empty) - (?: # followed by an optional - /(?P\d+) # / and denominator + (?: # followed by + (?:/(?P\d+))? # an optional denominator | # or - \.(?P\d*) # decimal point and fractional part - )? + (?:\.(?P\d*))? # an optional fractional part + (?:E(?P[-+]?\d+))? # and optional exponent + ) \s*\Z # and optional whitespace to finish -""", re.VERBOSE) +""", re.VERBOSE | re.IGNORECASE) class Fraction(numbers.Rational): @@ -65,22 +66,28 @@ if not isinstance(numerator, int) and denominator == 1: if isinstance(numerator, str): # Handle construction from strings. - input = numerator - m = _RATIONAL_FORMAT.match(input) + m = _RATIONAL_FORMAT.match(numerator) if m is None: - raise ValueError('Invalid literal for Fraction: %r' % input) - numerator = m.group('num') - decimal = m.group('decimal') - if decimal: - # The literal is a decimal number. - numerator = int(numerator + decimal) - denominator = 10**len(decimal) + raise ValueError('Invalid literal for Fraction: %r' % + numerator) + numerator = int(m.group('num') or '0') + denom = m.group('denom') + if denom: + denominator = int(denom) else: - # The literal is an integer or fraction. - numerator = int(numerator) - # Default denominator to 1. - denominator = int(m.group('denom') or 1) - + denominator = 1 + decimal = m.group('decimal') + if decimal: + scale = 10**len(decimal) + numerator = numerator * scale + int(decimal) + denominator *= scale + exp = m.group('exp') + if exp: + exp = int(exp) + if exp >= 0: + numerator *= 10**exp + else: + denominator *= 10**-exp if m.group('sign') == '-': numerator = -numerator 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 Wed Apr 22 19:50:21 2009 @@ -78,6 +78,11 @@ self.assertEquals((-16, 5), _components(F(" -3.2 "))) self.assertEquals((-3, 1), _components(F(" -3. "))) self.assertEquals((3, 5), _components(F(" .6 "))) + self.assertEquals((1, 3125), _components(F("32.e-5"))) + self.assertEquals((1000000, 1), _components(F("1E+06"))) + self.assertEquals((-12300, 1), _components(F("-1.23e4"))) + self.assertEquals((0, 1), _components(F(" .0e+0\t"))) + self.assertEquals((0, 1), _components(F("-0.000e0"))) self.assertRaisesMessage( ZeroDivisionError, "Fraction(3, 0)", @@ -86,6 +91,9 @@ ValueError, "Invalid literal for Fraction: '3/'", F, "3/") self.assertRaisesMessage( + ValueError, "Invalid literal for Fraction: '/2'", + F, "/2") + self.assertRaisesMessage( ValueError, "Invalid literal for Fraction: '3 /2'", F, "3 /2") self.assertRaisesMessage( @@ -101,10 +109,6 @@ ValueError, "Invalid literal for Fraction: '3a2'", F, "3a2") self.assertRaisesMessage( - # Only parse ordinary decimals, not scientific form. - ValueError, "Invalid literal for Fraction: '3.2e4'", - F, "3.2e4") - self.assertRaisesMessage( # Don't accept combinations of decimals and rationals. ValueError, "Invalid literal for Fraction: '3/7.2'", F, "3/7.2") Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Apr 22 19:50:21 2009 @@ -75,6 +75,10 @@ Library ------- +- Issue #5812: Fraction('1e6') is valid: more generally, any string + that's valid for float() is now valid for Fraction(), with the + exception of strings representing NaNs and infinities. + - Issue #5734: BufferedRWPair was poorly tested and had several glaring bugs. Patch by Brian Quinlan. From python-checkins at python.org Wed Apr 22 19:51:32 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 22 Apr 2009 19:51:32 +0200 (CEST) Subject: [Python-checkins] r71807 - python/branches/release30-maint Message-ID: <20090422175132.114951E401F@bag.python.org> Author: mark.dickinson Date: Wed Apr 22 19:51:31 2009 New Revision: 71807 Log: Blocked revisions 71806 via svnmerge ........ r71806 | mark.dickinson | 2009-04-22 18:50:21 +0100 (Wed, 22 Apr 2009) | 4 lines Issue #5812: Make Fraction('1e6') valid. The Fraction constructor now accepts all strings accepted by the float and Decimal constructors, with the exception of strings representing NaNs or infinities. ........ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Wed Apr 22 20:15:26 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 22 Apr 2009 20:15:26 +0200 (CEST) Subject: [Python-checkins] r71808 - in python/trunk: Doc/library/fractions.rst Lib/fractions.py Lib/test/test_fractions.py Misc/NEWS Message-ID: <20090422181526.1041D1E401F@bag.python.org> Author: mark.dickinson Date: Wed Apr 22 20:15:25 2009 New Revision: 71808 Log: Issue #5812: make Fraction('1e-6') valid. Backport of r71806. Modified: python/trunk/Doc/library/fractions.rst python/trunk/Lib/fractions.py python/trunk/Lib/test/test_fractions.py python/trunk/Misc/NEWS Modified: python/trunk/Doc/library/fractions.rst ============================================================================== --- python/trunk/Doc/library/fractions.rst (original) +++ python/trunk/Doc/library/fractions.rst Wed Apr 22 20:15:25 2009 @@ -27,20 +27,17 @@ *other_fraction* is an instance of :class:`numbers.Rational` and returns an :class:`Fraction` instance with the same value. The last version of the constructor expects a string or unicode - instance in one of two possible forms. The first form is:: + instance. The usual form for this instance is:: [sign] numerator ['/' denominator] where the optional ``sign`` may be either '+' or '-' and ``numerator`` and ``denominator`` (if present) are strings of - decimal digits. The second permitted form is that of a number - containing a decimal point:: - - [sign] integer '.' [fraction] | [sign] '.' fraction - - where ``integer`` and ``fraction`` are strings of digits. In - either form the input string may also have leading and/or trailing - whitespace. Here are some examples:: + decimal digits. In addition, any string that represents a finite + value and is accepted by the :class:`float` constructor is also + accepted by the :class:`Fraction` constructor. In either form the + input string may also have leading and/or trailing whitespace. + Here are some examples:: >>> from fractions import Fraction >>> Fraction(16, -10) @@ -58,6 +55,8 @@ Fraction(1414213, 1000000) >>> Fraction('-.125') Fraction(-1, 8) + >>> Fraction('7e-6') + Fraction(7, 1000000) The :class:`Fraction` class inherits from the abstract base class Modified: python/trunk/Lib/fractions.py ============================================================================== --- python/trunk/Lib/fractions.py (original) +++ python/trunk/Lib/fractions.py Wed Apr 22 20:15:25 2009 @@ -30,13 +30,14 @@ (?P[-+]?) # an optional sign, then (?=\d|\.\d) # lookahead for digit or .digit (?P\d*) # numerator (possibly empty) - (?: # followed by an optional - /(?P\d+) # / and denominator + (?: # followed by + (?:/(?P\d+))? # an optional denominator | # or - \.(?P\d*) # decimal point and fractional part - )? + (?:\.(?P\d*))? # an optional fractional part + (?:E(?P[-+]?\d+))? # and optional exponent + ) \s*\Z # and optional whitespace to finish -""", re.VERBOSE) +""", re.VERBOSE | re.IGNORECASE) class Fraction(Rational): @@ -67,22 +68,28 @@ if type(numerator) not in (int, long) and denominator == 1: if isinstance(numerator, basestring): # Handle construction from strings. - input = numerator - m = _RATIONAL_FORMAT.match(input) + m = _RATIONAL_FORMAT.match(numerator) if m is None: - raise ValueError('Invalid literal for Fraction: %r' % input) - numerator = m.group('num') - decimal = m.group('decimal') - if decimal: - # The literal is a decimal number. - numerator = int(numerator + decimal) - denominator = 10**len(decimal) + raise ValueError('Invalid literal for Fraction: %r' % + numerator) + numerator = int(m.group('num') or '0') + denom = m.group('denom') + if denom: + denominator = int(denom) else: - # The literal is an integer or fraction. - numerator = int(numerator) - # Default denominator to 1. - denominator = int(m.group('denom') or 1) - + denominator = 1 + decimal = m.group('decimal') + if decimal: + scale = 10**len(decimal) + numerator = numerator * scale + int(decimal) + denominator *= scale + exp = m.group('exp') + if exp: + exp = int(exp) + if exp >= 0: + numerator *= 10**exp + else: + denominator *= 10**-exp if m.group('sign') == '-': numerator = -numerator Modified: python/trunk/Lib/test/test_fractions.py ============================================================================== --- python/trunk/Lib/test/test_fractions.py (original) +++ python/trunk/Lib/test/test_fractions.py Wed Apr 22 20:15:25 2009 @@ -80,6 +80,11 @@ self.assertEquals((-16, 5), _components(F(u" -3.2 "))) self.assertEquals((-3, 1), _components(F(u" -3. "))) self.assertEquals((3, 5), _components(F(u" .6 "))) + self.assertEquals((1, 3125), _components(F("32.e-5"))) + self.assertEquals((1000000, 1), _components(F("1E+06"))) + self.assertEquals((-12300, 1), _components(F("-1.23e4"))) + self.assertEquals((0, 1), _components(F(" .0e+0\t"))) + self.assertEquals((0, 1), _components(F("-0.000e0"))) self.assertRaisesMessage( @@ -89,6 +94,9 @@ ValueError, "Invalid literal for Fraction: '3/'", F, "3/") self.assertRaisesMessage( + ValueError, "Invalid literal for Fraction: '/2'", + F, "/2") + self.assertRaisesMessage( ValueError, "Invalid literal for Fraction: '3 /2'", F, "3 /2") self.assertRaisesMessage( @@ -104,10 +112,6 @@ ValueError, "Invalid literal for Fraction: '3a2'", F, "3a2") self.assertRaisesMessage( - # Only parse ordinary decimals, not scientific form. - ValueError, "Invalid literal for Fraction: '3.2e4'", - F, "3.2e4") - self.assertRaisesMessage( # Don't accept combinations of decimals and fractions. ValueError, "Invalid literal for Fraction: '3/7.2'", F, "3/7.2") Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Apr 22 20:15:25 2009 @@ -241,6 +241,10 @@ Library ------- +- Issue #5812: Fraction('1e6') is valid: more generally, any string + that's valid for float() is now valid for Fraction(), with the + exception of strings representing NaNs and infinities. + - Issue #5795: Fixed test_distutils failure on Debian ppc. - Issue #5768: Fixed bug in Unicode output logic and test case for same. From python-checkins at python.org Wed Apr 22 20:16:13 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 22 Apr 2009 20:16:13 +0200 (CEST) Subject: [Python-checkins] r71809 - python/branches/release26-maint Message-ID: <20090422181613.A8EE71E4164@bag.python.org> Author: mark.dickinson Date: Wed Apr 22 20:16:13 2009 New Revision: 71809 Log: Blocked revisions 71808 via svnmerge ........ r71808 | mark.dickinson | 2009-04-22 19:15:25 +0100 (Wed, 22 Apr 2009) | 2 lines Issue #5812: make Fraction('1e-6') valid. Backport of r71806. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Wed Apr 22 20:17:29 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 22 Apr 2009 20:17:29 +0200 (CEST) Subject: [Python-checkins] r71810 - python/branches/py3k Message-ID: <20090422181729.40E6B1E401F@bag.python.org> Author: mark.dickinson Date: Wed Apr 22 20:17:29 2009 New Revision: 71810 Log: Blocked revisions 71808 via svnmerge ........ r71808 | mark.dickinson | 2009-04-22 19:15:25 +0100 (Wed, 22 Apr 2009) | 2 lines Issue #5812: make Fraction('1e-6') valid. Backport of r71806. ........ Modified: python/branches/py3k/ (props changed) From buildbot at python.org Wed Apr 22 20:43:12 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 22 Apr 2009 18:43:12 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo trunk Message-ID: <20090422184312.C168F1E401F@bag.python.org> The Buildbot has detected a new failure of x86 gentoo trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%20trunk/builds/4860 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: Traceback (most recent call last): File "/home/buildslave/python-trunk/trunk.norwitz-x86/build/Lib/test/test_signal.py", line 165, in test_main pickle.dump(None, done_w) File "/home/buildslave/python-trunk/trunk.norwitz-x86/build/Lib/contextlib.py", line 153, in __exit__ self.thing.close() IOError: [Errno 9] Bad file descriptor 1 test failed: test_signal make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Wed Apr 22 21:08:10 2009 From: python-checkins at python.org (martin.v.loewis) Date: Wed, 22 Apr 2009 21:08:10 +0200 (CEST) Subject: [Python-checkins] r71811 - peps/trunk/pep-0383.txt Message-ID: <20090422190810.C296B1E41A6@bag.python.org> Author: martin.v.loewis Date: Wed Apr 22 21:08:10 2009 New Revision: 71811 Log: Fix typos. Modified: peps/trunk/pep-0383.txt Modified: peps/trunk/pep-0383.txt ============================================================================== --- peps/trunk/pep-0383.txt (original) +++ peps/trunk/pep-0383.txt Wed Apr 22 21:08:10 2009 @@ -32,7 +32,7 @@ the encoding of byte strings in the same way that the C interfaces can ignore the encoding. -On the other hand, Microsoft Windows NT has correct the original +On the other hand, Microsoft Windows NT has corrected the original design limitation of Unix, and made it explicit in its system interfaces that these data (file names, environment variables, command line arguments) are indeed character data, by providing a @@ -94,7 +94,7 @@ For most applications, we assume that they eventually pass data received from a system interface back into the same system -interfaces. For example, and application invoking os.listdir() will +interfaces. For example, an application invoking os.listdir() will likely pass the result strings back into APIs like os.stat() or open(), which then encodes them back into their original byte representation. Applications that need to process the original byte From buildbot at python.org Wed Apr 22 21:18:13 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 22 Apr 2009 19:18:13 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 2.6 Message-ID: <20090422191813.D87AB1E4207@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%202.6/builds/242 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From buildbot at python.org Thu Apr 23 00:41:33 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 22 Apr 2009 22:41:33 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090422224133.86A8C1E40CC@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/290 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: eric.smith,mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 3 tests failed: test_distutils test_posix test_subprocess ====================================================================== FAIL: test_get_python_inc (distutils.tests.test_sysconfig.SysconfigTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/distutils/tests/test_sysconfig.py", line 45, in test_get_python_inc self.assert_(os.path.isdir(inc_dir), inc_dir) AssertionError: /home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/Include ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From buildbot at python.org Thu Apr 23 02:30:34 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 23 Apr 2009 00:30:34 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc trunk Message-ID: <20090423003034.938921E41B8@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc trunk. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%20trunk/builds/320 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posixpath sincerely, -The Buildbot From python-checkins at python.org Thu Apr 23 04:36:01 2009 From: python-checkins at python.org (kurt.kaiser) Date: Thu, 23 Apr 2009 04:36:01 +0200 (CEST) Subject: [Python-checkins] r71812 - in python/trunk/Lib/idlelib: CREDITS.txt EditorWindow.py NEWS.txt idlever.py Message-ID: <20090423023601.B3C281E4032@bag.python.org> Author: kurt.kaiser Date: Thu Apr 23 04:36:01 2009 New Revision: 71812 Log: Produce correct version string to access the .chm docs on Windows. Patch 5783 gpolo. Will port. Modified: python/trunk/Lib/idlelib/CREDITS.txt python/trunk/Lib/idlelib/EditorWindow.py python/trunk/Lib/idlelib/NEWS.txt python/trunk/Lib/idlelib/idlever.py Modified: python/trunk/Lib/idlelib/CREDITS.txt ============================================================================== --- python/trunk/Lib/idlelib/CREDITS.txt (original) +++ python/trunk/Lib/idlelib/CREDITS.txt Thu Apr 23 04:36:01 2009 @@ -2,9 +2,9 @@ original creator of IDLE. Other contributors prior to Version 0.8 include Mark Hammond, Jeremy Hylton, Tim Peters, and Moshe Zadka. -IDLE's recent development has been carried out in the IDLEfork project. -The objective was to develop a version of IDLE which had an execution -environment which could be initialized prior to each run of user code. +IDLE's recent development was carried out in the SF IDLEfork project. The +objective was to develop a version of IDLE which had an execution environment +which could be initialized prior to each run of user code. The IDLEfork project was initiated by David Scherer, with some help from Peter Schneider-Kamp and Nicholas Riley. David wrote the first version of the RPC @@ -12,7 +12,7 @@ the RPC code and Remote Debugger currently integrated in IDLE. Bruce Sherwood contributed considerable time testing and suggesting improvements. -Besides David and Guido, the main developers who have been active on IDLEfork +Besides David and Guido, the main developers who were active on IDLEfork are Stephen M. Gava, who implemented the configuration GUI, the new configuration system, and the About dialog, and Kurt B. Kaiser, who completed the integration of the RPC and remote debugger, implemented the threaded @@ -24,8 +24,9 @@ integration, debugger integration and persistent breakpoints). Scott David Daniels, Tal Einat, Hernan Foffani, Christos Georgiou, -Jim Jewett, Martin v. L?wis, Jason Orendorff, Josh Robb, Nigel Rowe, -Bruce Sherwood, and Jeff Shute have submitted useful patches. Thanks, guys! +Jim Jewett, Martin v. L?wis, Jason Orendorff, Guilherme Polo, Josh Robb, +Nigel Rowe, Bruce Sherwood, Jeff Shute, and Weeble have submitted useful +patches. Thanks, guys! For additional details refer to NEWS.txt and Changelog. Modified: python/trunk/Lib/idlelib/EditorWindow.py ============================================================================== --- python/trunk/Lib/idlelib/EditorWindow.py (original) +++ python/trunk/Lib/idlelib/EditorWindow.py Thu Apr 23 04:36:01 2009 @@ -22,6 +22,16 @@ # The default tab setting for a Text widget, in average-width characters. TK_TABWIDTH_DEFAULT = 8 +def _sphinx_version(): + "Format sys.version_info to produce the Sphinx version string used to install the chm docs" + major, minor, micro, level, serial = sys.version_info + release = '%s%s' % (major, minor) + if micro: + release += '%s' % micro + if level != 'final': + release += '%s%s' % (level[0], serial) + return release + def _find_module(fullname, path=None): """Version of imp.find_module() that handles hierarchical module names""" @@ -64,15 +74,13 @@ 'Doc', 'index.html') elif sys.platform[:3] == 'win': chmfile = os.path.join(sys.prefix, 'Doc', - 'Python%d%d.chm' % sys.version_info[:2]) + 'Python%s.chm' % _sphinx_version()) if os.path.isfile(chmfile): dochome = chmfile - elif macosxSupport.runningAsOSXApp(): # documentation is stored inside the python framework dochome = os.path.join(sys.prefix, 'Resources/English.lproj/Documentation/index.html') - dochome = os.path.normpath(dochome) if os.path.isfile(dochome): EditorWindow.help_url = dochome Modified: python/trunk/Lib/idlelib/NEWS.txt ============================================================================== --- python/trunk/Lib/idlelib/NEWS.txt (original) +++ python/trunk/Lib/idlelib/NEWS.txt Thu Apr 23 04:36:01 2009 @@ -3,6 +3,9 @@ *Release date: XX-XXX-2009* +- Windows: Version string for the .chm help file changed, file not being + accessed Patch 5783 Guilherme Polo + - Allow multiple IDLE GUI/subprocess pairs to exist simultaneously. Thanks to David Scherer for suggesting the use of an ephemeral port for the GUI. Patch 1529142 Weeble. Modified: python/trunk/Lib/idlelib/idlever.py ============================================================================== --- python/trunk/Lib/idlelib/idlever.py (original) +++ python/trunk/Lib/idlelib/idlever.py Thu Apr 23 04:36:01 2009 @@ -1 +1 @@ -IDLE_VERSION = "2.6" +IDLE_VERSION = "2.7a0" From python-checkins at python.org Thu Apr 23 10:44:44 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 23 Apr 2009 10:44:44 +0200 (CEST) Subject: [Python-checkins] r71813 - tracker/instances/python-dev/scripts/adjust_user Message-ID: <20090423084444.4773F1E401E@bag.python.org> Author: martin.v.loewis Date: Thu Apr 23 10:44:43 2009 New Revision: 71813 Log: Create a script to merge two users. Added: tracker/instances/python-dev/scripts/adjust_user (contents, props changed) Added: tracker/instances/python-dev/scripts/adjust_user ============================================================================== --- (empty file) +++ tracker/instances/python-dev/scripts/adjust_user Thu Apr 23 10:44:43 2009 @@ -0,0 +1,45 @@ +# This script changes all references to one user to point to a +# different. Useful if the user has several accounts which he +# doesn't need anymore. + +import sys +sys.path.insert(1,'/home/roundup/roundup/lib/python2.4/site-packages') +import roundup.instance +from roundup.hyperdb import Link, Multilink + +if len(sys.argv) != 3: + print "Usage: adjust_user old new" + raise SystemExit +old, new = sys.argv[1:] + +tracker = roundup.instance.open('.') +db = tracker.open('admin') + +old = db.user.lookup(old) +new = db.user.lookup(new) + +references = [] # class, prop +for klass in db.getclasses(): + klass = db.getclass(klass) + klass.disableJournalling() + for name, typ in klass.getprops().items(): + if isinstance(typ, (Link, Multilink)) and typ.classname=='user': + references.append((klass, name)) +for klass, name in references: + for id in klass.find(**{name:old}): + v = klass.get(id, name) + if isinstance(v, list): + # Multilink + for i in range(len(v)): + if v[i] == old: + v[i] = new + # col:(add, remove) + multilink_changes = {name:([new],[old])} + else: + # Link + v = new + multilink_changes = {} + db.setnode(klass.classname, id, {name: v}, multilink_changes) +db.user.enableJournalling() +db.user.retire(old) +db.commit() From python-checkins at python.org Thu Apr 23 10:44:57 2009 From: python-checkins at python.org (georg.brandl) Date: Thu, 23 Apr 2009 10:44:57 +0200 (CEST) Subject: [Python-checkins] r71814 - python/trunk/Doc/library/json.rst Message-ID: <20090423084457.8CC111E401E@bag.python.org> Author: georg.brandl Date: Thu Apr 23 10:44:57 2009 New Revision: 71814 Log: #5820: fix bug in usage of getreader(). Modified: python/trunk/Doc/library/json.rst Modified: python/trunk/Doc/library/json.rst ============================================================================== --- python/trunk/Doc/library/json.rst (original) +++ python/trunk/Doc/library/json.rst Thu Apr 23 10:44:57 2009 @@ -174,7 +174,7 @@ If the contents of *fp* are encoded with an ASCII based encoding other than UTF-8 (e.g. latin-1), then an appropriate *encoding* name must be specified. Encodings that are not ASCII based (such as UCS-2) are not allowed, and - should be wrapped with ``codecs.getreader(fp)(encoding)``, or simply decoded + should be wrapped with ``codecs.getreader(encoding)(fp)``, or simply decoded to a :class:`unicode` object and passed to :func:`loads`. *object_hook* is an optional function that will be called with the result of From python-checkins at python.org Thu Apr 23 10:49:39 2009 From: python-checkins at python.org (georg.brandl) Date: Thu, 23 Apr 2009 10:49:39 +0200 (CEST) Subject: [Python-checkins] r71815 - python/trunk/Doc/library/turtle.rst Message-ID: <20090423084939.9917A1E4026@bag.python.org> Author: georg.brandl Date: Thu Apr 23 10:49:39 2009 New Revision: 71815 Log: Fix rewrapping accident. Modified: python/trunk/Doc/library/turtle.rst Modified: python/trunk/Doc/library/turtle.rst ============================================================================== --- python/trunk/Doc/library/turtle.rst (original) +++ python/trunk/Doc/library/turtle.rst Thu Apr 23 10:49:39 2009 @@ -1244,9 +1244,9 @@ .. function:: screensize(canvwidth=None, canvheight=None, bg=None) - :param canvwidth: positive integer, new width of canvas in pixels :param - canvheight: positive integer, new height of canvas in pixels :param bg: - colorstring or color-tuple, new background color + :param canvwidth: positive integer, new width of canvas in pixels + :param canvheight: positive integer, new height of canvas in pixels + :param bg: colorstring or color-tuple, new background color If no arguments are given, return current (canvaswidth, canvasheight). Else resize the canvas the turtles are drawing on. Do not alter the drawing From python-checkins at python.org Thu Apr 23 10:49:56 2009 From: python-checkins at python.org (georg.brandl) Date: Thu, 23 Apr 2009 10:49:56 +0200 (CEST) Subject: [Python-checkins] r71816 - python/trunk/Doc/library/__future__.rst Message-ID: <20090423084956.AA2B41E4026@bag.python.org> Author: georg.brandl Date: Thu Apr 23 10:49:56 2009 New Revision: 71816 Log: #5813: add a reference to the "future statements" section. Modified: python/trunk/Doc/library/__future__.rst Modified: python/trunk/Doc/library/__future__.rst ============================================================================== --- python/trunk/Doc/library/__future__.rst (original) +++ python/trunk/Doc/library/__future__.rst Thu Apr 23 10:49:56 2009 @@ -58,3 +58,7 @@ No feature description will ever be deleted from :mod:`__future__`. +.. seealso:: + + :ref:`future` + How the compiler treats future imports. From python-checkins at python.org Thu Apr 23 10:52:03 2009 From: python-checkins at python.org (georg.brandl) Date: Thu, 23 Apr 2009 10:52:03 +0200 (CEST) Subject: [Python-checkins] r71817 - python/trunk/Doc/reference/simple_stmts.rst Message-ID: <20090423085203.927711E4026@bag.python.org> Author: georg.brandl Date: Thu Apr 23 10:52:03 2009 New Revision: 71817 Log: Add link to PEP 236. Modified: python/trunk/Doc/reference/simple_stmts.rst Modified: python/trunk/Doc/reference/simple_stmts.rst ============================================================================== --- python/trunk/Doc/reference/simple_stmts.rst (original) +++ python/trunk/Doc/reference/simple_stmts.rst Thu Apr 23 10:52:03 2009 @@ -907,6 +907,11 @@ a future statement, it will be in effect in the interactive session started after the script is executed. +.. seealso:: + + :pep:`236` - Back to the __future__ + The original proposal for the __future__ mechanism. + .. _global: From nnorwitz at gmail.com Thu Apr 23 11:25:05 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 23 Apr 2009 05:25:05 -0400 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20090423092505.GA19118@python.psfb.org> More important issues: ---------------------- test_ssl leaked [403, 322, 0] references, sum=725 Less important issues: ---------------------- test_cmd_line leaked [50, 0, -25] references, sum=25 test_file leaked [0, 0, 82] references, sum=82 test_smtplib leaked [-88, 0, 88] references, sum=0 test_sys leaked [-42, 42, -42] references, sum=-42 test_threading leaked [48, 48, 48] references, sum=144 test_urllib2_localnet leaked [3, 3, 3] references, sum=9 From python-checkins at python.org Thu Apr 23 21:14:16 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 23 Apr 2009 21:14:16 +0200 (CEST) Subject: [Python-checkins] r71818 - in python/branches/py3k: Lib/test/test_complex.py Misc/NEWS Objects/complexobject.c Python/pystrtod.c Message-ID: <20090423191416.B8AE51E4016@bag.python.org> Author: mark.dickinson Date: Thu Apr 23 21:14:16 2009 New Revision: 71818 Log: Issue #5816: Simplify code for parsing and printing of complex numbers. nans and infs are no longer given special treatment; as a result, repr(complex(z)) recovers z for any complex number z. Modified: python/branches/py3k/Lib/test/test_complex.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/complexobject.c python/branches/py3k/Python/pystrtod.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 Thu Apr 23 21:14:16 2009 @@ -2,7 +2,7 @@ from test import support from random import random -from math import atan2 +from math import atan2, isnan, copysign INF = float("inf") NAN = float("nan") @@ -37,6 +37,29 @@ # check that relative difference < eps self.assert_(abs((x-y)/y) < eps) + def assertFloatsAreIdentical(self, x, y): + """assert that floats x and y are identical, in the sense that: + (1) both x and y are nans, or + (2) both x and y are infinities, with the same sign, or + (3) both x and y are zeros, with the same sign, or + (4) x and y are both finite and nonzero, and x == y + + """ + msg = 'floats {!r} and {!r} are not identical' + + if isnan(x) or isnan(y): + if isnan(x) and isnan(y): + return + elif x == y: + if x != 0.0: + return + # both zero; check that signs match + elif copysign(1.0, x) == copysign(1.0, y): + return + else: + msg += ': zeros have different signs' + self.fail(msg.format(x, y)) + def assertClose(self, x, y, eps=1e-9): """Return true iff complexes x and y "are close\"""" self.assertCloseAbs(x.real, y.real, eps) @@ -202,6 +225,8 @@ self.assertAlmostEqual(complex("+1"), +1) self.assertAlmostEqual(complex("(1+2j)"), 1+2j) self.assertAlmostEqual(complex("(1.3+2.2j)"), 1.3+2.2j) + self.assertAlmostEqual(complex("3.14+1J"), 3.14+1j) + self.assertAlmostEqual(complex(" ( +3.14-6J )"), 3.14-6j) class complex2(complex): pass self.assertAlmostEqual(complex(complex2(1+1j)), 1+1j) @@ -229,8 +254,6 @@ self.assertRaises(TypeError, complex, "1", "1") self.assertRaises(TypeError, complex, 1, "1") - self.assertEqual(complex(" 3.14+J "), 3.14+1j) - # SF bug 543840: complex(string) accepts strings with \0 # Fixed in 2.3. self.assertRaises(ValueError, complex, '1+1j\0j') @@ -254,6 +277,11 @@ self.assertRaises(ValueError, complex, "(1+2j)123") self.assertRaises(ValueError, complex, "1"*500) self.assertRaises(ValueError, complex, "x") + self.assertRaises(ValueError, complex, "J") + self.assertRaises(ValueError, complex, "1j+2") + self.assertRaises(ValueError, complex, "1e1ej") + self.assertRaises(ValueError, complex, "1e++1ej") + self.assertRaises(ValueError, complex, ")1+2j(") class EvilExc(Exception): pass @@ -318,17 +346,17 @@ self.assertEqual(-6j,complex(repr(-6j))) self.assertEqual(6j,complex(repr(6j))) - self.assertEqual(repr(complex(1., INF)), "(1+inf*j)") - self.assertEqual(repr(complex(1., -INF)), "(1-inf*j)") + 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+inf*j)") + self.assertEqual(repr(complex(-INF, INF)), "(-inf+infj)") self.assertEqual(repr(complex(NAN, 1)), "(nan+1j)") - self.assertEqual(repr(complex(1, NAN)), "(1+nan*j)") - self.assertEqual(repr(complex(NAN, NAN)), "(nan+nan*j)") + self.assertEqual(repr(complex(1, NAN)), "(1+nanj)") + self.assertEqual(repr(complex(NAN, NAN)), "(nan+nanj)") - self.assertEqual(repr(complex(0, INF)), "inf*j") - self.assertEqual(repr(complex(0, -INF)), "-inf*j") - self.assertEqual(repr(complex(0, NAN)), "nan*j") + 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) @@ -367,6 +395,21 @@ self.assertEquals(atan2(z1.imag, -1.), atan2(0., -1.)) self.assertEquals(atan2(z2.imag, -1.), atan2(-0., -1.)) + @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + def test_repr_roundtrip(self): + # complex(repr(z)) should recover z exactly, even for complex numbers + # involving an infinity, nan, or negative zero + vals = [0.0, 1e-200, 0.0123, 3.1415, 1e50, INF, NAN] + vals += [-v for v in vals] + for x in vals: + for y in vals: + z = complex(x, y) + roundtrip = complex(repr(z)) + self.assertFloatsAreIdentical(z.real, roundtrip.real) + self.assertFloatsAreIdentical(z.imag, roundtrip.imag) + + def test_main(): support.run_unittest(ComplexTest) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Apr 23 21:14:16 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #5816: complex(repr(z)) now recovers z exactly, even when + z involves nans, infs or negative zeros. + - Issue #3166: Make long -> float (and int -> float) conversions correctly rounded. Modified: python/branches/py3k/Objects/complexobject.c ============================================================================== --- python/branches/py3k/Objects/complexobject.c (original) +++ python/branches/py3k/Objects/complexobject.c Thu Apr 23 21:14:16 2009 @@ -332,99 +332,64 @@ static PyObject * complex_format(PyComplexObject *v, char format_code) { - PyObject *result = NULL; - Py_ssize_t len; + PyObject *result = NULL; + Py_ssize_t len; - /* If these are non-NULL, they'll need to be freed. */ - char *pre = NULL; - char *pim = NULL; - char *buf = NULL; - - /* These do not need to be freed. They're either aliases for pim - and pre, or pointers to constants. */ - char *re = NULL; - char *im = NULL; - char *lead = ""; - char *tail = ""; - - - if (v->cval.real == 0.) { - re = ""; - if (!Py_IS_FINITE(v->cval.imag)) { - if (Py_IS_NAN(v->cval.imag)) - im = "nan*"; - else if (copysign(1, v->cval.imag) == 1) - im = "inf*"; - else - im = "-inf*"; - } - else { - pim = PyOS_double_to_string(v->cval.imag, format_code, - 0, 0, NULL); - if (!pim) { - PyErr_NoMemory(); - goto done; - } - im = pim; - } - } else { - /* Format imaginary part with sign, real part without */ - if (!Py_IS_FINITE(v->cval.real)) { - if (Py_IS_NAN(v->cval.real)) - re = "nan"; - /* else if (copysign(1, v->cval.real) == 1) */ - else if (v->cval.real > 0) - re = "inf"; - else - re = "-inf"; - } - else { - pre = PyOS_double_to_string(v->cval.real, format_code, - 0, 0, NULL); - if (!pre) { - PyErr_NoMemory(); - goto done; - } - re = pre; - } - - if (!Py_IS_FINITE(v->cval.imag)) { - if (Py_IS_NAN(v->cval.imag)) - im = "+nan*"; - /* else if (copysign(1, v->cval.imag) == 1) */ - else if (v->cval.imag > 0) - im = "+inf*"; - else - im = "-inf*"; - } - else { - pim = PyOS_double_to_string(v->cval.imag, format_code, - 0, Py_DTSF_SIGN, NULL); - if (!pim) { - PyErr_NoMemory(); - goto done; - } - im = pim; - } - lead = "("; - tail = ")"; - } - /* Alloc the final buffer. Add one for the "j" in the format string, and - one for the trailing zero. */ - len = strlen(lead) + strlen(re) + strlen(im) + strlen(tail) + 2; - buf = PyMem_Malloc(len); - if (!buf) { - PyErr_NoMemory(); - goto done; - } - PyOS_snprintf(buf, len, "%s%s%sj%s", lead, re, im, tail); - result = PyUnicode_FromString(buf); -done: - PyMem_Free(pim); - PyMem_Free(pre); - PyMem_Free(buf); + /* If these are non-NULL, they'll need to be freed. */ + char *pre = NULL; + char *im = NULL; + char *buf = NULL; + + /* These do not need to be freed. re is either an alias + for pre or a pointer to a constant. lead and tail + are pointers to constants. */ + char *re = NULL; + char *lead = ""; + char *tail = ""; + + if (v->cval.real == 0. && copysign(1.0, v->cval.real)==1.0) { + re = ""; + im = PyOS_double_to_string(v->cval.imag, format_code, + 0, 0, NULL); + if (!im) { + PyErr_NoMemory(); + goto done; + } + } else { + /* Format imaginary part with sign, real part without */ + pre = PyOS_double_to_string(v->cval.real, format_code, + 0, 0, NULL); + if (!pre) { + PyErr_NoMemory(); + goto done; + } + re = pre; + + im = PyOS_double_to_string(v->cval.imag, format_code, + 0, Py_DTSF_SIGN, NULL); + if (!im) { + PyErr_NoMemory(); + goto done; + } + lead = "("; + tail = ")"; + } + /* Alloc the final buffer. Add one for the "j" in the format string, + and one for the trailing zero. */ + len = strlen(lead) + strlen(re) + strlen(im) + strlen(tail) + 2; + buf = PyMem_Malloc(len); + if (!buf) { + PyErr_NoMemory(); + goto done; + } + PyOS_snprintf(buf, len, "%s%s%sj%s", lead, re, im, tail); + result = PyUnicode_FromString(buf); + done: + PyMem_Free(im); + PyMem_Free(pre); + PyMem_Free(buf); - return result; + return result; } static PyObject * @@ -757,11 +722,7 @@ const char *s, *start; char *end; double x=0.0, y=0.0, z; - int got_re=0, got_im=0, got_bracket=0, done=0; - int digit_or_dot; - int sw_error=0; - int sign; - char buffer[256]; /* For errors */ + int got_bracket=0; char s_buffer[256]; Py_ssize_t len; @@ -785,16 +746,13 @@ return NULL; } + errno = 0; + /* position on first nonblank */ start = s; while (*s && isspace(Py_CHARMASK(*s))) s++; - if (s[0] == '\0') { - PyErr_SetString(PyExc_ValueError, - "complex() arg is an empty string"); - return NULL; - } - if (s[0] == '(') { + if (*s == '(') { /* Skip over possible bracket from repr(). */ got_bracket = 1; s++; @@ -802,120 +760,50 @@ s++; } - z = -1.0; - sign = 1; - do { - - switch (*s) { - - case '\0': - if (s-start != len) { - PyErr_SetString( - PyExc_ValueError, - "complex() arg contains a null byte"); - return NULL; - } - if(!done) sw_error=1; - break; - - case ')': - if (!got_bracket || !(got_re || got_im)) { - sw_error=1; - break; - } - got_bracket=0; - done=1; - s++; - while (*s && isspace(Py_CHARMASK(*s))) - s++; - if (*s) sw_error=1; - break; - - case '-': - sign = -1; - /* Fallthrough */ - case '+': - if (done) sw_error=1; - s++; - if ( *s=='\0'||*s=='+'||*s=='-'||*s==')'|| - isspace(Py_CHARMASK(*s)) ) sw_error=1; - break; - - case 'J': - case 'j': - if (got_im || done) { - sw_error = 1; - break; - } - if (z<0.0) { - y=sign; - } - else{ - y=sign*z; - } - got_im=1; - s++; - if (*s!='+' && *s!='-' ) - done=1; - break; - - default: - if (isspace(Py_CHARMASK(*s))) { - while (*s && isspace(Py_CHARMASK(*s))) - s++; - if (*s && *s != ')') - sw_error=1; - else - done = 1; - break; - } - digit_or_dot = - (*s=='.' || isdigit(Py_CHARMASK(*s))); - if (done||!digit_or_dot) { - sw_error=1; - break; - } - errno = 0; - PyFPE_START_PROTECT("strtod", return 0) - z = PyOS_ascii_strtod(s, &end) ; - PyFPE_END_PROTECT(z) - if (errno != 0) { - PyOS_snprintf(buffer, sizeof(buffer), - "float() out of range: %.150s", s); - PyErr_SetString( - PyExc_ValueError, - buffer); - return NULL; - } - s=end; - if (*s=='J' || *s=='j') { - - break; - } - if (got_re) { - sw_error=1; - break; - } - - /* accept a real part */ - x=sign*z; - got_re=1; - if (got_im) done=1; - z = -1.0; - sign = 1; - break; - - } /* end of switch */ - - } while (s - start < len && !sw_error); - - if (sw_error || got_bracket) { - PyErr_SetString(PyExc_ValueError, - "complex() arg is a malformed string"); - return NULL; + /* get float---might be real or imaginary part */ + z = PyOS_ascii_strtod(s, &end); + if (end == s) + goto error; + s = end; + if (*s == '+' || *s == '-') { + /* we've got a real part *and* an imaginary part */ + x = z; + y = PyOS_ascii_strtod(s, &end); + if (end == s || !(*end == 'j' || *end == 'J')) + goto error; + s = ++end; + } + else if (*s == 'j' || *s == 'J') { + /* no real part; z was the imaginary part */ + s++; + y = z; } + else + /* no imaginary part */ + x = z; + + /* trailing whitespace and closing bracket */ + while (*s && isspace(Py_CHARMASK(*s))) + s++; + if (got_bracket && *s == ')') { + got_bracket = 0; + s++; + while (*s && isspace(Py_CHARMASK(*s))) + s++; + } + /* we should now be at the end of the string */ + if (s-start != len || got_bracket) + goto error; return complex_subtype_from_doubles(type, x, y); + + error: + /* check for PyOS_ascii_strtod failure due to lack of memory */ + if (errno == ENOMEM) + return PyErr_NoMemory(); + PyErr_SetString(PyExc_ValueError, + "complex() arg is a malformed string"); + return NULL; } static PyObject * Modified: python/branches/py3k/Python/pystrtod.c ============================================================================== --- python/branches/py3k/Python/pystrtod.c (original) +++ python/branches/py3k/Python/pystrtod.c Thu Apr 23 21:14:16 2009 @@ -630,8 +630,9 @@ } p = result; - /* Never add sign for nan/inf, even if asked. */ - if (flags & Py_DTSF_SIGN && buf[0] != '-' && t == Py_DTST_FINITE) + /* Add sign when requested. It's convenient (esp. when formatting + complex numbers) to include a sign even for inf and nan. */ + if (flags & Py_DTSF_SIGN && buf[0] != '-') *p++ = '+'; strcpy(p, buf); @@ -733,6 +734,10 @@ so convert Infinity to inf and NaN to nan, and ignore sign of nan. Then return. */ + /* ignore the actual sign of a nan */ + if (digits[0] == 'n' || digits[0] == 'N') + sign = 0; + /* We only need 5 bytes to hold the result "+inf\0" . */ bufsize = 5; /* Used later in an assert. */ buf = (char *)PyMem_Malloc(bufsize); @@ -742,13 +747,13 @@ } p = buf; + if (sign == 1) { + *p++ = '-'; + } + else if (always_add_sign) { + *p++ = '+'; + } if (digits[0] == 'i' || digits[0] == 'I') { - if (sign == 1) { - *p++ = '-'; - } - else if (always_add_sign) { - *p++ = '+'; - } strncpy(p, float_strings[OFS_INF], 3); p += 3; @@ -756,8 +761,6 @@ *type = Py_DTST_INFINITE; } else if (digits[0] == 'n' || digits[0] == 'N') { - /* note that we *never* add a sign for a nan, - even if one has explicitly been requested */ strncpy(p, float_strings[OFS_NAN], 3); p += 3; From python-checkins at python.org Thu Apr 23 21:14:56 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 23 Apr 2009 21:14:56 +0200 (CEST) Subject: [Python-checkins] r71819 - python/branches/release30-maint Message-ID: <20090423191456.170131E4016@bag.python.org> Author: mark.dickinson Date: Thu Apr 23 21:14:55 2009 New Revision: 71819 Log: Blocked revisions 71818 via svnmerge ........ r71818 | mark.dickinson | 2009-04-23 20:14:16 +0100 (Thu, 23 Apr 2009) | 4 lines Issue #5816: Simplify code for parsing and printing of complex numbers. nans and infs are no longer given special treatment; as a result, repr(complex(z)) recovers z for any complex number z. ........ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Thu Apr 23 21:15:48 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 23 Apr 2009 21:15:48 +0200 (CEST) Subject: [Python-checkins] r71820 - python/branches/py3k/Misc/NEWS Message-ID: <20090423191548.F15DE1E40D8@bag.python.org> Author: mark.dickinson Date: Thu Apr 23 21:15:48 2009 New Revision: 71820 Log: Fix int/long confusion in Misc/NEWS entry. Modified: python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Apr 23 21:15:48 2009 @@ -15,8 +15,7 @@ - Issue #5816: complex(repr(z)) now recovers z exactly, even when z involves nans, infs or negative zeros. -- Issue #3166: Make long -> float (and int -> float) conversions - correctly rounded. +- Issue #3166: Make int -> float conversions correctly rounded. - Issue #1869 (and many duplicates): make round(x, n) correctly rounded for a float x, by using the decimal <-> binary conversions From python-checkins at python.org Thu Apr 23 21:16:21 2009 From: python-checkins at python.org (mark.dickinson) Date: Thu, 23 Apr 2009 21:16:21 +0200 (CEST) Subject: [Python-checkins] r71821 - python/branches/release30-maint Message-ID: <20090423191621.243E01E4016@bag.python.org> Author: mark.dickinson Date: Thu Apr 23 21:16:20 2009 New Revision: 71821 Log: Blocked revisions 71820 via svnmerge ........ r71820 | mark.dickinson | 2009-04-23 20:15:48 +0100 (Thu, 23 Apr 2009) | 2 lines Fix int/long confusion in Misc/NEWS entry. ........ Modified: python/branches/release30-maint/ (props changed) From nnorwitz at gmail.com Thu Apr 23 23:25:17 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 23 Apr 2009 17:25:17 -0400 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20090423212517.GA23968@python.psfb.org> More important issues: ---------------------- test_ssl leaked [322, 0, -403] references, sum=-81 Less important issues: ---------------------- test_cmd_line leaked [25, -25, 0] references, sum=0 test_smtplib leaked [38, 57, 21] references, sum=116 test_sys leaked [-42, 42, -42] references, sum=-42 test_threading leaked [48, 44, 52] references, sum=144 test_urllib2_localnet leaked [3, 3, 3] references, sum=9 From python-checkins at python.org Fri Apr 24 00:06:13 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 24 Apr 2009 00:06:13 +0200 (CEST) Subject: [Python-checkins] r71822 - python/branches/py3k/Doc/library/decimal.rst Message-ID: <20090423220613.54E2E1E4016@bag.python.org> Author: raymond.hettinger Date: Fri Apr 24 00:06:12 2009 New Revision: 71822 Log: Update decimal docs for the new floating point repr(). Modified: python/branches/py3k/Doc/library/decimal.rst Modified: python/branches/py3k/Doc/library/decimal.rst ============================================================================== --- python/branches/py3k/Doc/library/decimal.rst (original) +++ python/branches/py3k/Doc/library/decimal.rst Fri Apr 24 00:06:12 2009 @@ -30,9 +30,9 @@ people learn at school." -- excerpt from the decimal arithmetic specification. * Decimal numbers can be represented exactly. In contrast, numbers like - :const:`1.1` do not have an exact representation in binary floating point. End - users typically would not expect :const:`1.1` to display as - :const:`1.1000000000000001` as it does with binary floating point. + :const:`1.1` and :const:`2.2` do not have an exact representations in binary + floating point. End users typically would not expect ``1.1 + 2.2`` to display + as :const:`3.3000000000000003` as it does with binary floating point. * The exactness carries over into arithmetic. In decimal floating point, ``0.1 + 0.1 + 0.1 - 0.3`` is exactly equal to zero. In binary floating point, the result From python-checkins at python.org Fri Apr 24 05:09:07 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 24 Apr 2009 05:09:07 +0200 (CEST) Subject: [Python-checkins] r71823 - python/branches/py3k/Doc/tutorial/floatingpoint.rst Message-ID: <20090424030907.342911E4013@bag.python.org> Author: raymond.hettinger Date: Fri Apr 24 05:09:06 2009 New Revision: 71823 Log: Update for the new float.__repr__() Modified: python/branches/py3k/Doc/tutorial/floatingpoint.rst Modified: python/branches/py3k/Doc/tutorial/floatingpoint.rst ============================================================================== --- python/branches/py3k/Doc/tutorial/floatingpoint.rst (original) +++ python/branches/py3k/Doc/tutorial/floatingpoint.rst Fri Apr 24 05:09:06 2009 @@ -48,32 +48,43 @@ 0.0001100110011001100110011001100110011001100110011... -Stop at any finite number of bits, and you get an approximation. This is why -you see things like:: +Stop at any finite number of bits, and you get an approximation. On most +machines today, floats are approximated using a binary fraction with +the numerator using the first 53 bits following the most significant bit and +with the denominator as a power of two. In the case of 1/10, the binary fraction +is ``3602879701896397 / 2 ** 55`` which is close to but not exactly +equal to the true value of 1/10. + +Many users are not aware of the approximation because of the way values are +displayed. Python only prints a decimal approximation to the true decimal +value of the binary approximation stored by the machine. On most machines, if +Python were to print the true decimal value of the binary approximation stored +for 0.1, it would have to display :: >>> 0.1 - 0.10000000000000001 + 0.1000000000000000055511151231257827021181583404541015625 -On most machines today, that is what you'll see if you enter 0.1 at a Python -prompt. You may not, though, because the number of bits used by the hardware to -store floating-point values can vary across machines, and Python only prints a -decimal approximation to the true decimal value of the binary approximation -stored by the machine. On most machines, if Python were to print the true -decimal value of the binary approximation stored for 0.1, it would have to -display :: +That is more digits than most people find useful, so Python keeps the number +of digits manageable by displaying a rounded value instead :: - >>> 0.1 - 0.1000000000000000055511151231257827021181583404541015625 + >>> 1 / 10 + 0.1 -instead! The Python prompt uses the built-in :func:`repr` function to obtain a -string version of everything it displays. For floats, ``repr(float)`` rounds -the true decimal value to 17 significant digits, giving :: - - 0.10000000000000001 - -``repr(float)`` produces 17 significant digits because it turns out that's -enough (on most machines) so that ``eval(repr(x)) == x`` exactly for all finite -floats *x*, but rounding to 16 digits is not enough to make that true. +Just remember, even though the printed result looks like the exact value +of 1/10, the actual stored value is the nearest representable binary fraction. + +Interestingly, there are many different decimal numbers that share the same +nearest approximate binary fraction. For example, the numbers ``0.1`` and +``0.10000000000000001`` and +``0.1000000000000000055511151231257827021181583404541015625`` are all +approximated by ``3602879701896397 / 2 ** 55``. Since all of these decimal +values share the same approximation, any one of them could be displayed and +while still preserving the invariant ``eval(repr(x)) == x``. + +Historically, the Python prompt and built-in :func:`repr` function would chose +the one with 17 significant digits, ``0.10000000000000001``, Starting with +Python 3.1, Python (on most systems) is now able to choose the shortest of +these and simply display ``0.1``. Note that this is in the very nature of binary floating-point: this is not a bug in Python, and it is not a bug in your code either. You'll see the same kind of @@ -85,23 +96,28 @@ you may wish to use that instead. It's unusual for ``eval(str(x))`` to reproduce *x*, but the output may be more pleasant to look at:: - >>> print(str(0.1)) - 0.1 + >>> str(math.pi) + '3.14159265359' + + >>> repr(math.pi) + '3.141592653589793' + + >>> format(math.pi, '.2f') + '3.14' -It's important to realize that this is, in a real sense, an illusion: the value -in the machine is not exactly 1/10, you're simply rounding the *display* of the -true machine value. +It's important to realize that this is, in a real sense, an illusion: you're +simply rounding the *display* of the true machine value. Other surprises follow from this one. For example, after seeing :: - >>> 0.1 - 0.10000000000000001 + >>> format(0.1, '.17g') + '0.10000000000000001' you may be tempted to use the :func:`round` function to chop it back to the single digit you expect. But that makes no difference:: - >>> round(0.1, 1) - 0.10000000000000001 + >>> format(round(0.1, 1), '.17g') + '0.10000000000000001' The problem is that the binary floating-point value stored for "0.1" was already the best possible binary approximation to 1/10, so trying to round it again @@ -115,7 +131,7 @@ ... sum += 0.1 ... >>> sum - 0.99999999999999989 + 0.9999999999999999 Binary floating-point arithmetic holds many surprises like this. The problem with "0.1" is explained in precise detail below, in the "Representation Error" @@ -191,10 +207,7 @@ :dfn:`Representation error` refers to the fact that some (most, actually) decimal fractions cannot be represented exactly as binary (base 2) fractions. This is the chief reason why Python (or Perl, C, C++, Java, Fortran, and many -others) often won't display the exact decimal number you expect:: - - >>> 0.1 - 0.10000000000000001 +others) often won't display the exact decimal number you expect. Why is that? 1/10 is not exactly representable as a binary fraction. Almost all machines today (November 2000) use IEEE-754 floating point arithmetic, and @@ -237,6 +250,10 @@ 7205759403792794 / 72057594037927936 +Dividing both the numerator and denominator by two reduces the fraction to:: + + 3602879701896397 / 36028797018963968 + Note that since we rounded up, this is actually a little bit larger than 1/10; if we had not rounded up, the quotient would have been a little bit smaller than 1/10. But in no case can it be *exactly* 1/10! @@ -244,14 +261,14 @@ So the computer never "sees" 1/10: what it sees is the exact fraction given above, the best 754 double approximation it can get:: - >>> .1 * 2**56 - 7205759403792794.0 + >>> 0.1 * 2 ** 55 + 3602879701896397.0 -If we multiply that fraction by 10\*\*30, we can see the (truncated) value of -its 30 most significant decimal digits:: +If we multiply that fraction by 10\*\*60, we can see the value of out to +60 decimal digits:: - >>> 7205759403792794 * 10**30 / 2**56 - 100000000000000005551115123125 + >>> 3602879701896397 * 10 ** 60 // 2 ** 55 + 1000000000000000055511151231257827021181583404541015625 meaning that the exact number stored in the computer is approximately equal to the decimal value 0.100000000000000005551115123125. Rounding that to 17 @@ -259,4 +276,12 @@ will display on any 754-conforming platform that does best-possible input and output conversions in its C library --- yours may not!). +The :mod:`fractions` and :mod:`decimal` modules make these calculations +easy:: + >>> from decimal import Decimal + >>> from fractions import Fraction + >>> print(Fraction.from_float(0.1)) + 3602879701896397/36028797018963968 + >>> print(Decimal.from_float(0.1)) + 0.1000000000000000055511151231257827021181583404541015625 From nnorwitz at gmail.com Fri Apr 24 11:25:36 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Fri, 24 Apr 2009 05:25:36 -0400 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20090424092536.GA6398@python.psfb.org> More important issues: ---------------------- test_ssl leaked [0, 0, -403] references, sum=-403 Less important issues: ---------------------- test_smtplib leaked [-88, 0, 84] references, sum=-4 test_sys leaked [42, -21, 21] references, sum=42 test_threading leaked [44, 52, 48] references, sum=144 test_urllib2_localnet leaked [3, 3, 3] references, sum=9 From rdmurray at bitdance.com Fri Apr 24 14:25:59 2009 From: rdmurray at bitdance.com (R. David Murray) Date: Fri, 24 Apr 2009 08:25:59 -0400 (EDT) Subject: [Python-checkins] r71823 - python/branches/py3k/Doc/tutorial/floatingpoint.rst In-Reply-To: <20090424030907.342911E4013@bag.python.org> References: <20090424030907.342911E4013@bag.python.org> Message-ID: On Fri, 24 Apr 2009 at 05:09, raymond.hettinger wrote: > +values share the same approximation, any one of them could be displayed and > +while still preserving the invariant ``eval(repr(x)) == x``. I think there's an extra 'and' there. --David From python-checkins at python.org Fri Apr 24 14:46:54 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 24 Apr 2009 14:46:54 +0200 (CEST) Subject: [Python-checkins] r71824 - in python/trunk: Lib/test/test_complex.py Misc/NEWS Objects/complexobject.c Python/pystrtod.c Message-ID: <20090424124654.6DFEF1E4013@bag.python.org> Author: mark.dickinson Date: Fri Apr 24 14:46:53 2009 New Revision: 71824 Log: Issue #5816: - simplify parsing and printing of complex numbers - make complex(repr(z)) round-tripping work for complex numbers involving nans, infs, or negative zeros - don't accept some of the stranger complex strings that were previously allowed---e.g., complex('1..1j') Modified: python/trunk/Lib/test/test_complex.py python/trunk/Misc/NEWS python/trunk/Objects/complexobject.c python/trunk/Python/pystrtod.c Modified: python/trunk/Lib/test/test_complex.py ============================================================================== --- python/trunk/Lib/test/test_complex.py (original) +++ python/trunk/Lib/test/test_complex.py Fri Apr 24 14:46:53 2009 @@ -9,7 +9,7 @@ ) from random import random -from math import atan2 +from math import atan2, isnan, copysign INF = float("inf") NAN = float("nan") @@ -44,6 +44,29 @@ # check that relative difference < eps self.assert_(abs((x-y)/y) < eps) + def assertFloatsAreIdentical(self, x, y): + """assert that floats x and y are identical, in the sense that: + (1) both x and y are nans, or + (2) both x and y are infinities, with the same sign, or + (3) both x and y are zeros, with the same sign, or + (4) x and y are both finite and nonzero, and x == y + + """ + msg = 'floats {!r} and {!r} are not identical' + + if isnan(x) or isnan(y): + if isnan(x) and isnan(y): + return + elif x == y: + if x != 0.0: + return + # both zero; check that signs match + elif copysign(1.0, x) == copysign(1.0, y): + return + else: + msg += ': zeros have different signs' + self.fail(msg.format(x, y)) + def assertClose(self, x, y, eps=1e-9): """Return true iff complexes x and y "are close\"""" self.assertCloseAbs(x.real, y.real, eps) @@ -220,6 +243,17 @@ self.assertAlmostEqual(complex("+1"), +1) self.assertAlmostEqual(complex("(1+2j)"), 1+2j) self.assertAlmostEqual(complex("(1.3+2.2j)"), 1.3+2.2j) + self.assertAlmostEqual(complex("3.14+1J"), 3.14+1j) + self.assertAlmostEqual(complex(" ( +3.14-6J )"), 3.14-6j) + self.assertAlmostEqual(complex(" ( +3.14-J )"), 3.14-1j) + self.assertAlmostEqual(complex(" ( +3.14+j )"), 3.14+1j) + self.assertAlmostEqual(complex("J"), 1j) + self.assertAlmostEqual(complex("( j )"), 1j) + self.assertAlmostEqual(complex("+J"), 1j) + self.assertAlmostEqual(complex("( -j)"), -1j) + self.assertAlmostEqual(complex('1e-500'), 0.0 + 0.0j) + self.assertAlmostEqual(complex('-1e-500j'), 0.0 - 0.0j) + self.assertAlmostEqual(complex('-1e-500+1e-500j'), -0.0 + 0.0j) class complex2(complex): pass self.assertAlmostEqual(complex(complex2(1+1j)), 1+1j) @@ -247,7 +281,6 @@ self.assertRaises(TypeError, complex, "1", "1") self.assertRaises(TypeError, complex, 1, "1") - self.assertEqual(complex(" 3.14+J "), 3.14+1j) if test_support.have_unicode: self.assertEqual(complex(unicode(" 3.14+J ")), 3.14+1j) @@ -275,6 +308,14 @@ if test_support.have_unicode: self.assertRaises(ValueError, complex, unicode("1"*500)) self.assertRaises(ValueError, complex, unicode("x")) + self.assertRaises(ValueError, complex, "1j+2") + self.assertRaises(ValueError, complex, "1e1ej") + self.assertRaises(ValueError, complex, "1e++1ej") + self.assertRaises(ValueError, complex, ")1+2j(") + # the following three are accepted by Python 2.6 + self.assertRaises(ValueError, complex, "1..1j") + self.assertRaises(ValueError, complex, "1.11.1j") + self.assertRaises(ValueError, complex, "1e1.1j") class EvilExc(Exception): pass @@ -339,17 +380,17 @@ self.assertEqual(-6j,complex(repr(-6j))) self.assertEqual(6j,complex(repr(6j))) - self.assertEqual(repr(complex(1., INF)), "(1+inf*j)") - self.assertEqual(repr(complex(1., -INF)), "(1-inf*j)") + 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+inf*j)") + self.assertEqual(repr(complex(-INF, INF)), "(-inf+infj)") self.assertEqual(repr(complex(NAN, 1)), "(nan+1j)") - self.assertEqual(repr(complex(1, NAN)), "(1+nan*j)") - self.assertEqual(repr(complex(NAN, NAN)), "(nan+nan*j)") + self.assertEqual(repr(complex(1, NAN)), "(1+nanj)") + self.assertEqual(repr(complex(NAN, NAN)), "(nan+nanj)") - self.assertEqual(repr(complex(0, INF)), "inf*j") - self.assertEqual(repr(complex(0, -INF)), "-inf*j") - self.assertEqual(repr(complex(0, NAN)), "nan*j") + 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) @@ -388,6 +429,21 @@ self.assertEquals(atan2(z1.imag, -1.), atan2(0., -1.)) self.assertEquals(atan2(z2.imag, -1.), atan2(-0., -1.)) + @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + def test_repr_roundtrip(self): + # complex(repr(z)) should recover z exactly, even for complex numbers + # involving an infinity, nan, or negative zero + vals = [0.0, 1e-200, 0.0123, 3.1415, 1e50, INF, NAN] + vals += [-v for v in vals] + for x in vals: + for y in vals: + z = complex(x, y) + roundtrip = complex(repr(z)) + self.assertFloatsAreIdentical(z.real, roundtrip.real) + self.assertFloatsAreIdentical(z.imag, roundtrip.imag) + + def test_main(): test_support.run_unittest(ComplexTest) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Apr 24 14:46:53 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #5816: complex(repr(z)) now recovers z exactly, even when + z involves nans, infs or negative zeros. + - Implement PEP 378, Format Specifier for Thousands Separator, for floats, ints, and longs. Modified: python/trunk/Objects/complexobject.c ============================================================================== --- python/trunk/Objects/complexobject.c (original) +++ python/trunk/Objects/complexobject.c Fri Apr 24 14:46:53 2009 @@ -353,83 +353,95 @@ } -static void -complex_to_buf(char *buf, int bufsz, PyComplexObject *v, int precision) +static PyObject * +complex_format(PyComplexObject *v, char format_code) { - char format[32]; - if (v->cval.real == 0.) { - if (!Py_IS_FINITE(v->cval.imag)) { - if (Py_IS_NAN(v->cval.imag)) - strncpy(buf, "nan*j", 6); - else if (copysign(1, v->cval.imag) == 1) - strncpy(buf, "inf*j", 6); - else - strncpy(buf, "-inf*j", 7); - } - else { - PyOS_snprintf(format, sizeof(format), "%%.%ig", precision); - PyOS_ascii_formatd(buf, bufsz - 1, format, v->cval.imag); - strncat(buf, "j", 1); + PyObject *result = NULL; + Py_ssize_t len; + + /* If these are non-NULL, they'll need to be freed. */ + char *pre = NULL; + char *im = NULL; + char *buf = NULL; + + /* These do not need to be freed. re is either an alias + for pre or a pointer to a constant. lead and tail + are pointers to constants. */ + char *re = NULL; + char *lead = ""; + char *tail = ""; + + if (v->cval.real == 0. && copysign(1.0, v->cval.real)==1.0) { + re = ""; + im = PyOS_double_to_string(v->cval.imag, format_code, + 0, 0, NULL); + if (!im) { + PyErr_NoMemory(); + goto done; } } else { - char re[64], im[64]; /* Format imaginary part with sign, real part without */ - if (!Py_IS_FINITE(v->cval.real)) { - if (Py_IS_NAN(v->cval.real)) - strncpy(re, "nan", 4); - /* else if (copysign(1, v->cval.real) == 1) */ - else if (v->cval.real > 0) - strncpy(re, "inf", 4); - else - strncpy(re, "-inf", 5); - } - else { - PyOS_snprintf(format, sizeof(format), "%%.%ig", precision); - PyOS_ascii_formatd(re, sizeof(re), format, v->cval.real); - } - if (!Py_IS_FINITE(v->cval.imag)) { - if (Py_IS_NAN(v->cval.imag)) - strncpy(im, "+nan*", 6); - /* else if (copysign(1, v->cval.imag) == 1) */ - else if (v->cval.imag > 0) - strncpy(im, "+inf*", 6); - else - strncpy(im, "-inf*", 6); - } - else { - PyOS_snprintf(format, sizeof(format), "%%+.%ig", precision); - PyOS_ascii_formatd(im, sizeof(im), format, v->cval.imag); - } - PyOS_snprintf(buf, bufsz, "(%s%sj)", re, im); - } + pre = PyOS_double_to_string(v->cval.real, format_code, + 0, 0, NULL); + if (!pre) { + PyErr_NoMemory(); + goto done; + } + re = pre; + + im = PyOS_double_to_string(v->cval.imag, format_code, + 0, Py_DTSF_SIGN, NULL); + if (!im) { + PyErr_NoMemory(); + goto done; + } + lead = "("; + tail = ")"; + } + /* Alloc the final buffer. Add one for the "j" in the format string, + and one for the trailing zero. */ + len = strlen(lead) + strlen(re) + strlen(im) + strlen(tail) + 2; + buf = PyMem_Malloc(len); + if (!buf) { + PyErr_NoMemory(); + goto done; + } + PyOS_snprintf(buf, len, "%s%s%sj%s", lead, re, im, tail); + result = PyString_FromString(buf); + done: + PyMem_Free(im); + PyMem_Free(pre); + PyMem_Free(buf); + + return result; } static int complex_print(PyComplexObject *v, FILE *fp, int flags) { - char buf[100]; - complex_to_buf(buf, sizeof(buf), v, - (flags & Py_PRINT_RAW) ? PREC_STR : PREC_REPR); + PyObject *formatv; + char *buf; + formatv = complex_format(v, (flags & Py_PRINT_RAW) ? 's' : 'r'); + if (formatv == NULL) + return -1; + buf = PyString_AS_STRING(formatv); Py_BEGIN_ALLOW_THREADS fputs(buf, fp); Py_END_ALLOW_THREADS + Py_DECREF(formatv); return 0; } static PyObject * complex_repr(PyComplexObject *v) { - char buf[100]; - complex_to_buf(buf, sizeof(buf), v, PREC_REPR); - return PyString_FromString(buf); + return complex_format(v, 'r'); } static PyObject * complex_str(PyComplexObject *v) { - char buf[100]; - complex_to_buf(buf, sizeof(buf), v, PREC_STR); - return PyString_FromString(buf); + return complex_format(v, 's'); } static long @@ -867,11 +879,7 @@ const char *s, *start; char *end; double x=0.0, y=0.0, z; - int got_re=0, got_im=0, got_bracket=0, done=0; - int digit_or_dot; - int sw_error=0; - int sign; - char buffer[256]; /* For errors */ + int got_bracket=0; #ifdef Py_USING_UNICODE char s_buffer[256]; #endif @@ -903,16 +911,13 @@ return NULL; } + errno = 0; + /* position on first nonblank */ start = s; while (*s && isspace(Py_CHARMASK(*s))) s++; - if (s[0] == '\0') { - PyErr_SetString(PyExc_ValueError, - "complex() arg is an empty string"); - return NULL; - } - if (s[0] == '(') { + if (*s == '(') { /* Skip over possible bracket from repr(). */ got_bracket = 1; s++; @@ -920,120 +925,109 @@ s++; } - z = -1.0; - sign = 1; - do { - - switch (*s) { - - case '\0': - if (s-start != len) { - PyErr_SetString( - PyExc_ValueError, - "complex() arg contains a null byte"); - return NULL; - } - if(!done) sw_error=1; - break; + /* a valid complex string usually takes one of the three forms: - case ')': - if (!got_bracket || !(got_re || got_im)) { - sw_error=1; - break; + - real part only + j - imaginary part only + j - real and imaginary parts + + where represents any numeric string that's accepted by the + float constructor (including 'nan', 'inf', 'infinity', etc.), and + is any string of the form whose first + character is '+' or '-'. + + For backwards compatibility, the extra forms + + j + j + j + + are also accepted, though support for these forms may be removed from + a future version of Python. + */ + + /* first look for forms starting with */ + z = PyOS_ascii_strtod(s, &end); + if (end == s && errno == ENOMEM) + return PyErr_NoMemory(); + if (errno == ERANGE && fabs(z) >= 1.0) + goto overflow; + + if (end != s) { + /* all 4 forms starting with land here */ + s = end; + if (*s == '+' || *s == '-') { + /* j | j */ + x = z; + y = PyOS_ascii_strtod(s, &end); + if (end == s && errno == ENOMEM) + return PyErr_NoMemory(); + if (errno == ERANGE && fabs(z) >= 1.0) + goto overflow; + if (end != s) + /* j */ + s = end; + else { + /* j */ + y = *s == '+' ? 1.0 : -1.0; + s++; } - got_bracket=0; - done=1; + if (!(*s == 'j' || *s == 'J')) + goto parse_error; s++; - while (*s && isspace(Py_CHARMASK(*s))) - s++; - if (*s) sw_error=1; - break; - - case '-': - sign = -1; - /* Fallthrough */ - case '+': - if (done) sw_error=1; + } + else if (*s == 'j' || *s == 'J') { + /* j */ s++; - if ( *s=='\0'||*s=='+'||*s=='-'||*s==')'|| - isspace(Py_CHARMASK(*s)) ) sw_error=1; - break; - - case 'J': - case 'j': - if (got_im || done) { - sw_error = 1; - break; - } - if (z<0.0) { - y=sign; - } - else{ - y=sign*z; - } - got_im=1; + y = z; + } + else + /* */ + x = z; + } + else { + /* not starting with ; must be j or j */ + if (*s == '+' || *s == '-') { + /* j */ + y = *s == '+' ? 1.0 : -1.0; s++; - if (*s!='+' && *s!='-' ) - done=1; - break; - - default: - if (isspace(Py_CHARMASK(*s))) { - while (*s && isspace(Py_CHARMASK(*s))) - s++; - if (*s && *s != ')') - sw_error=1; - else - done = 1; - break; - } - digit_or_dot = - (*s=='.' || isdigit(Py_CHARMASK(*s))); - if (done||!digit_or_dot) { - sw_error=1; - break; - } - errno = 0; - PyFPE_START_PROTECT("strtod", return 0) - z = PyOS_ascii_strtod(s, &end) ; - PyFPE_END_PROTECT(z) - if (errno != 0) { - PyOS_snprintf(buffer, sizeof(buffer), - "float() out of range: %.150s", s); - PyErr_SetString( - PyExc_ValueError, - buffer); - return NULL; - } - s=end; - if (*s=='J' || *s=='j') { - - break; - } - if (got_re) { - sw_error=1; - break; - } + } + else + /* j */ + y = 1.0; + if (!(*s == 'j' || *s == 'J')) + goto parse_error; + s++; + } - /* accept a real part */ - x=sign*z; - got_re=1; - if (got_im) done=1; - z = -1.0; - sign = 1; - break; - - } /* end of switch */ - - } while (s - start < len && !sw_error); - - if (sw_error || got_bracket) { - PyErr_SetString(PyExc_ValueError, - "complex() arg is a malformed string"); - return NULL; + /* trailing whitespace and closing bracket */ + while (*s && isspace(Py_CHARMASK(*s))) + s++; + if (got_bracket) { + /* if there was an opening parenthesis, then the corresponding + closing parenthesis should be right here */ + if (*s != ')') + goto parse_error; + s++; + while (*s && isspace(Py_CHARMASK(*s))) + s++; } + /* we should now be at the end of the string */ + if (s-start != len) + goto parse_error; + return complex_subtype_from_doubles(type, x, y); + + parse_error: + PyErr_SetString(PyExc_ValueError, + "complex() arg is a malformed string"); + return NULL; + + overflow: + PyErr_SetString(PyExc_OverflowError, + "complex() arg overflow"); + } static PyObject * Modified: python/trunk/Python/pystrtod.c ============================================================================== --- python/trunk/Python/pystrtod.c (original) +++ python/trunk/Python/pystrtod.c Fri Apr 24 14:46:53 2009 @@ -544,8 +544,9 @@ } p = result; - /* Never add sign for nan/inf, even if asked. */ - if (flags & Py_DTSF_SIGN && buf[0] != '-' && t == Py_DTST_FINITE) + /* Add sign when requested. It's convenient (esp. when formatting + complex numbers) to include a sign even for inf and nan. */ + if (flags & Py_DTSF_SIGN && buf[0] != '-') *p++ = '+'; strcpy(p, buf); From python-checkins at python.org Fri Apr 24 14:51:43 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 24 Apr 2009 14:51:43 +0200 (CEST) Subject: [Python-checkins] r71825 - python/branches/release26-maint Message-ID: <20090424125143.93C7B1E4013@bag.python.org> Author: mark.dickinson Date: Fri Apr 24 14:51:43 2009 New Revision: 71825 Log: Blocked revisions 71824 via svnmerge ........ r71824 | mark.dickinson | 2009-04-24 13:46:53 +0100 (Fri, 24 Apr 2009) | 7 lines Issue #5816: - simplify parsing and printing of complex numbers - make complex(repr(z)) round-tripping work for complex numbers involving nans, infs, or negative zeros - don't accept some of the stranger complex strings that were previously allowed---e.g., complex('1..1j') ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Fri Apr 24 14:53:02 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 24 Apr 2009 14:53:02 +0200 (CEST) Subject: [Python-checkins] r71826 - python/branches/py3k Message-ID: <20090424125302.DB0B11E4013@bag.python.org> Author: mark.dickinson Date: Fri Apr 24 14:53:02 2009 New Revision: 71826 Log: Blocked revisions 71824 via svnmerge ........ r71824 | mark.dickinson | 2009-04-24 13:46:53 +0100 (Fri, 24 Apr 2009) | 7 lines Issue #5816: - simplify parsing and printing of complex numbers - make complex(repr(z)) round-tripping work for complex numbers involving nans, infs, or negative zeros - don't accept some of the stranger complex strings that were previously allowed---e.g., complex('1..1j') ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Fri Apr 24 15:14:07 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 24 Apr 2009 15:14:07 +0200 (CEST) Subject: [Python-checkins] r71827 - python/trunk/Objects/complexobject.c Message-ID: <20090424131407.B4F1E1E4013@bag.python.org> Author: mark.dickinson Date: Fri Apr 24 15:14:07 2009 New Revision: 71827 Log: Fix missing 'return NULL' Modified: python/trunk/Objects/complexobject.c Modified: python/trunk/Objects/complexobject.c ============================================================================== --- python/trunk/Objects/complexobject.c (original) +++ python/trunk/Objects/complexobject.c Fri Apr 24 15:14:07 2009 @@ -1027,7 +1027,7 @@ overflow: PyErr_SetString(PyExc_OverflowError, "complex() arg overflow"); - + return NULL; } static PyObject * From python-checkins at python.org Fri Apr 24 15:14:47 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 24 Apr 2009 15:14:47 +0200 (CEST) Subject: [Python-checkins] r71828 - python/branches/release26-maint Message-ID: <20090424131447.4295E1E4013@bag.python.org> Author: mark.dickinson Date: Fri Apr 24 15:14:47 2009 New Revision: 71828 Log: Blocked revisions 71827 via svnmerge ........ r71827 | mark.dickinson | 2009-04-24 14:14:07 +0100 (Fri, 24 Apr 2009) | 2 lines Fix missing 'return NULL' ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Fri Apr 24 15:25:20 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 24 Apr 2009 15:25:20 +0200 (CEST) Subject: [Python-checkins] r71829 - in python/branches/py3k: Lib/test/test_complex.py Objects/complexobject.c Message-ID: <20090424132520.DC84B1E4029@bag.python.org> Author: mark.dickinson Date: Fri Apr 24 15:25:20 2009 New Revision: 71829 Log: Make sure that complex parsing code and corresponding tests match for 2.7 and 3.1, and that 3.1 continues to accept complex('j') and complex('4-j') 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 Fri Apr 24 15:25:20 2009 @@ -227,6 +227,15 @@ self.assertAlmostEqual(complex("(1.3+2.2j)"), 1.3+2.2j) self.assertAlmostEqual(complex("3.14+1J"), 3.14+1j) self.assertAlmostEqual(complex(" ( +3.14-6J )"), 3.14-6j) + self.assertAlmostEqual(complex(" ( +3.14-J )"), 3.14-1j) + self.assertAlmostEqual(complex(" ( +3.14+j )"), 3.14+1j) + self.assertAlmostEqual(complex("J"), 1j) + self.assertAlmostEqual(complex("( j )"), 1j) + self.assertAlmostEqual(complex("+J"), 1j) + self.assertAlmostEqual(complex("( -j)"), -1j) + self.assertAlmostEqual(complex('1e-500'), 0.0 + 0.0j) + self.assertAlmostEqual(complex('-1e-500j'), 0.0 - 0.0j) + self.assertAlmostEqual(complex('-1e-500+1e-500j'), -0.0 + 0.0j) class complex2(complex): pass self.assertAlmostEqual(complex(complex2(1+1j)), 1+1j) @@ -277,11 +286,14 @@ self.assertRaises(ValueError, complex, "(1+2j)123") self.assertRaises(ValueError, complex, "1"*500) self.assertRaises(ValueError, complex, "x") - self.assertRaises(ValueError, complex, "J") self.assertRaises(ValueError, complex, "1j+2") self.assertRaises(ValueError, complex, "1e1ej") self.assertRaises(ValueError, complex, "1e++1ej") self.assertRaises(ValueError, complex, ")1+2j(") + # the following three are accepted by Python 2.6 + self.assertRaises(ValueError, complex, "1..1j") + self.assertRaises(ValueError, complex, "1.11.1j") + self.assertRaises(ValueError, complex, "1e1.1j") class EvilExc(Exception): pass Modified: python/branches/py3k/Objects/complexobject.c ============================================================================== --- python/branches/py3k/Objects/complexobject.c (original) +++ python/branches/py3k/Objects/complexobject.c Fri Apr 24 15:25:20 2009 @@ -760,50 +760,109 @@ s++; } - /* get float---might be real or imaginary part */ + /* a valid complex string usually takes one of the three forms: + + - real part only + j - imaginary part only + j - real and imaginary parts + + where represents any numeric string that's accepted by the + float constructor (including 'nan', 'inf', 'infinity', etc.), and + is any string of the form whose first + character is '+' or '-'. + + For backwards compatibility, the extra forms + + j + j + j + + are also accepted, though support for these forms may be removed from + a future version of Python. + */ + + /* first look for forms starting with */ z = PyOS_ascii_strtod(s, &end); - if (end == s) - goto error; - s = end; - if (*s == '+' || *s == '-') { - /* we've got a real part *and* an imaginary part */ - x = z; - y = PyOS_ascii_strtod(s, &end); - if (end == s || !(*end == 'j' || *end == 'J')) - goto error; - s = ++end; + if (end == s && errno == ENOMEM) + return PyErr_NoMemory(); + if (errno == ERANGE && fabs(z) >= 1.0) + goto overflow; + + if (end != s) { + /* all 4 forms starting with land here */ + s = end; + if (*s == '+' || *s == '-') { + /* j | j */ + x = z; + y = PyOS_ascii_strtod(s, &end); + if (end == s && errno == ENOMEM) + return PyErr_NoMemory(); + if (errno == ERANGE && fabs(z) >= 1.0) + goto overflow; + if (end != s) + /* j */ + s = end; + else { + /* j */ + y = *s == '+' ? 1.0 : -1.0; + s++; + } + if (!(*s == 'j' || *s == 'J')) + goto parse_error; + s++; + } + else if (*s == 'j' || *s == 'J') { + /* j */ + s++; + y = z; + } + else + /* */ + x = z; } - else if (*s == 'j' || *s == 'J') { - /* no real part; z was the imaginary part */ + else { + /* not starting with ; must be j or j */ + if (*s == '+' || *s == '-') { + /* j */ + y = *s == '+' ? 1.0 : -1.0; + s++; + } + else + /* j */ + y = 1.0; + if (!(*s == 'j' || *s == 'J')) + goto parse_error; s++; - y = z; } - else - /* no imaginary part */ - x = z; /* trailing whitespace and closing bracket */ while (*s && isspace(Py_CHARMASK(*s))) s++; - if (got_bracket && *s == ')') { - got_bracket = 0; + if (got_bracket) { + /* if there was an opening parenthesis, then the corresponding + closing parenthesis should be right here */ + if (*s != ')') + goto parse_error; s++; while (*s && isspace(Py_CHARMASK(*s))) - s++; + s++; } + /* we should now be at the end of the string */ - if (s-start != len || got_bracket) - goto error; + if (s-start != len) + goto parse_error; return complex_subtype_from_doubles(type, x, y); - error: - /* check for PyOS_ascii_strtod failure due to lack of memory */ - if (errno == ENOMEM) - return PyErr_NoMemory(); + parse_error: PyErr_SetString(PyExc_ValueError, "complex() arg is a malformed string"); return NULL; + + overflow: + PyErr_SetString(PyExc_OverflowError, + "complex() arg overflow"); + return NULL; } static PyObject * From python-checkins at python.org Fri Apr 24 15:26:14 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 24 Apr 2009 15:26:14 +0200 (CEST) Subject: [Python-checkins] r71830 - python/branches/py3k Message-ID: <20090424132614.A37C31E4063@bag.python.org> Author: mark.dickinson Date: Fri Apr 24 15:26:14 2009 New Revision: 71830 Log: Blocked revisions 71827 via svnmerge ........ r71827 | mark.dickinson | 2009-04-24 14:14:07 +0100 (Fri, 24 Apr 2009) | 2 lines Fix missing 'return NULL' ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Fri Apr 24 15:26:51 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 24 Apr 2009 15:26:51 +0200 (CEST) Subject: [Python-checkins] r71831 - python/branches/release30-maint Message-ID: <20090424132651.DF4911E401E@bag.python.org> Author: mark.dickinson Date: Fri Apr 24 15:26:51 2009 New Revision: 71831 Log: Blocked revisions 71829 via svnmerge ........ r71829 | mark.dickinson | 2009-04-24 14:25:20 +0100 (Fri, 24 Apr 2009) | 4 lines Make sure that complex parsing code and corresponding tests match for 2.7 and 3.1, and that 3.1 continues to accept complex('j') and complex('4-j') ........ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Fri Apr 24 15:56:07 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 24 Apr 2009 15:56:07 +0200 (CEST) Subject: [Python-checkins] r71832 - in python/trunk: Lib/fractions.py Lib/test/test_fractions.py Misc/NEWS Message-ID: <20090424135607.829561E4013@bag.python.org> Author: mark.dickinson Date: Fri Apr 24 15:56:07 2009 New Revision: 71832 Log: Issue #5812: The two-argument form of the Fraction constructor now accepts arbitrary Rational instances. Modified: python/trunk/Lib/fractions.py python/trunk/Lib/test/test_fractions.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/fractions.py ============================================================================== --- python/trunk/Lib/fractions.py (original) +++ python/trunk/Lib/fractions.py Fri Apr 24 15:56:07 2009 @@ -56,7 +56,7 @@ __slots__ = ('_numerator', '_denominator') # We're immutable, so use __new__ not __init__ - def __new__(cls, numerator=0, denominator=1): + def __new__(cls, numerator=0, denominator=None): """Constructs a Fraction. Takes a string like '3/2' or '1.5', another Fraction, or a @@ -65,8 +65,13 @@ """ self = super(Fraction, cls).__new__(cls) - if type(numerator) not in (int, long) and denominator == 1: - if isinstance(numerator, basestring): + if denominator is None: + if isinstance(numerator, Rational): + self._numerator = numerator.numerator + self._denominator = numerator.denominator + return self + + elif isinstance(numerator, basestring): # Handle construction from strings. m = _RATIONAL_FORMAT.match(numerator) if m is None: @@ -93,18 +98,22 @@ if m.group('sign') == '-': numerator = -numerator - elif isinstance(numerator, Rational): - # Handle copies from other rationals. Integrals get - # caught here too, but it doesn't matter because - # denominator is already 1. - other_rational = numerator - numerator = other_rational.numerator - denominator = other_rational.denominator + else: + raise TypeError("argument should be a string " + "or a Rational instance") + + elif (isinstance(numerator, Rational) and + isinstance(denominator, Rational)): + numerator, denominator = ( + numerator.numerator * denominator.denominator, + denominator.numerator * numerator.denominator + ) + else: + raise TypeError("both arguments should be " + "Rational instances") if denominator == 0: raise ZeroDivisionError('Fraction(%s, 0)' % numerator) - numerator = operator.index(numerator) - denominator = operator.index(denominator) g = gcd(numerator, denominator) self._numerator = numerator // g self._denominator = denominator // g Modified: python/trunk/Lib/test/test_fractions.py ============================================================================== --- python/trunk/Lib/test/test_fractions.py (original) +++ python/trunk/Lib/test/test_fractions.py Fri Apr 24 15:56:07 2009 @@ -60,13 +60,19 @@ self.assertEquals((7, 15), _components(F(7, 15))) self.assertEquals((10**23, 1), _components(F(10**23))) + self.assertEquals((3, 77), _components(F(F(3, 7), 11))) + self.assertEquals((-9, 5), _components(F(2, F(-10, 9)))) + self.assertEquals((2486, 2485), _components(F(F(22, 7), F(355, 113)))) + self.assertRaisesMessage(ZeroDivisionError, "Fraction(12, 0)", F, 12, 0) self.assertRaises(TypeError, F, 1.5) self.assertRaises(TypeError, F, 1.5 + 3j) - self.assertRaises(TypeError, F, F(1, 2), 3) self.assertRaises(TypeError, F, "3/2", 3) + self.assertRaises(TypeError, F, 3, 0j) + self.assertRaises(TypeError, F, 3, 1j) + def testFromString(self): self.assertEquals((5, 1), _components(F("5"))) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Apr 24 15:56:07 2009 @@ -244,6 +244,10 @@ Library ------- +- Issue #5812: For the two-argument form of the Fraction constructor, + Fraction(m, n), m and n are permitted to be arbitrary Rational + instances. + - Issue #5812: Fraction('1e6') is valid: more generally, any string that's valid for float() is now valid for Fraction(), with the exception of strings representing NaNs and infinities. From python-checkins at python.org Fri Apr 24 15:56:40 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 24 Apr 2009 15:56:40 +0200 (CEST) Subject: [Python-checkins] r71833 - python/branches/release26-maint Message-ID: <20090424135640.439261E4013@bag.python.org> Author: mark.dickinson Date: Fri Apr 24 15:56:40 2009 New Revision: 71833 Log: Blocked revisions 71832 via svnmerge ........ r71832 | mark.dickinson | 2009-04-24 14:56:07 +0100 (Fri, 24 Apr 2009) | 3 lines Issue #5812: The two-argument form of the Fraction constructor now accepts arbitrary Rational instances. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Fri Apr 24 16:06:19 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 24 Apr 2009 16:06:19 +0200 (CEST) Subject: [Python-checkins] r71834 - in python/branches/py3k: Lib/fractions.py Lib/test/test_fractions.py Misc/NEWS Message-ID: <20090424140619.7CEBF1E403D@bag.python.org> Author: mark.dickinson Date: Fri Apr 24 16:06:19 2009 New Revision: 71834 Log: Merged revisions 71832 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71832 | mark.dickinson | 2009-04-24 14:56:07 +0100 (Fri, 24 Apr 2009) | 3 lines Issue #5812: The two-argument form of the Fraction constructor now accepts arbitrary Rational instances. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/fractions.py python/branches/py3k/Lib/test/test_fractions.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/fractions.py ============================================================================== --- python/branches/py3k/Lib/fractions.py (original) +++ python/branches/py3k/Lib/fractions.py Fri Apr 24 16:06:19 2009 @@ -54,7 +54,7 @@ __slots__ = ('_numerator', '_denominator') # We're immutable, so use __new__ not __init__ - def __new__(cls, numerator=0, denominator=1): + def __new__(cls, numerator=0, denominator=None): """Constructs a Rational. Takes a string like '3/2' or '1.5', another Rational, or a @@ -63,8 +63,13 @@ """ self = super(Fraction, cls).__new__(cls) - if not isinstance(numerator, int) and denominator == 1: - if isinstance(numerator, str): + if denominator is None: + if isinstance(numerator, numbers.Rational): + self._numerator = numerator.numerator + self._denominator = numerator.denominator + return self + + elif isinstance(numerator, str): # Handle construction from strings. m = _RATIONAL_FORMAT.match(numerator) if m is None: @@ -91,18 +96,22 @@ if m.group('sign') == '-': numerator = -numerator - elif isinstance(numerator, numbers.Rational): - # Handle copies from other rationals. Integrals get - # caught here too, but it doesn't matter because - # denominator is already 1. - other_rational = numerator - numerator = other_rational.numerator - denominator = other_rational.denominator + else: + raise TypeError("argument should be a string " + "or a Rational instance") + + elif (isinstance(numerator, numbers.Rational) and + isinstance(denominator, numbers.Rational)): + numerator, denominator = ( + numerator.numerator * denominator.denominator, + denominator.numerator * numerator.denominator + ) + else: + raise TypeError("both arguments should be " + "Rational instances") if denominator == 0: raise ZeroDivisionError('Fraction(%s, 0)' % numerator) - numerator = operator.index(numerator) - denominator = operator.index(denominator) g = gcd(numerator, denominator) self._numerator = numerator // g self._denominator = denominator // g 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 Fri Apr 24 16:06:19 2009 @@ -60,13 +60,19 @@ self.assertEquals((7, 15), _components(F(7, 15))) self.assertEquals((10**23, 1), _components(F(10**23))) + self.assertEquals((3, 77), _components(F(F(3, 7), 11))) + self.assertEquals((-9, 5), _components(F(2, F(-10, 9)))) + self.assertEquals((2486, 2485), _components(F(F(22, 7), F(355, 113)))) + self.assertRaisesMessage(ZeroDivisionError, "Fraction(12, 0)", F, 12, 0) self.assertRaises(TypeError, F, 1.5) self.assertRaises(TypeError, F, 1.5 + 3j) - self.assertRaises(TypeError, F, F(1, 2), 3) self.assertRaises(TypeError, F, "3/2", 3) + self.assertRaises(TypeError, F, 3, 0j) + self.assertRaises(TypeError, F, 3, 1j) + def testFromString(self): self.assertEquals((5, 1), _components(F("5"))) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Apr 24 16:06:19 2009 @@ -77,6 +77,10 @@ Library ------- +- Issue #5812: For the two-argument form of the Fraction constructor, + Fraction(m, n), m and n are permitted to be arbitrary Rational + instances. + - Issue #5812: Fraction('1e6') is valid: more generally, any string that's valid for float() is now valid for Fraction(), with the exception of strings representing NaNs and infinities. From python-checkins at python.org Fri Apr 24 16:12:51 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 24 Apr 2009 16:12:51 +0200 (CEST) Subject: [Python-checkins] r71835 - python/branches/release30-maint Message-ID: <20090424141251.45F1C1E4013@bag.python.org> Author: mark.dickinson Date: Fri Apr 24 16:12:51 2009 New Revision: 71835 Log: Blocked revisions 71834 via svnmerge ................ r71834 | mark.dickinson | 2009-04-24 15:06:19 +0100 (Fri, 24 Apr 2009) | 10 lines Merged revisions 71832 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71832 | mark.dickinson | 2009-04-24 14:56:07 +0100 (Fri, 24 Apr 2009) | 3 lines Issue #5812: The two-argument form of the Fraction constructor now accepts arbitrary Rational instances. ........ ................ Modified: python/branches/release30-maint/ (props changed) From buildbot at python.org Fri Apr 24 17:03:45 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 24 Apr 2009 15:03:45 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu trunk Message-ID: <20090424150345.B7D4D1E401D@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%20trunk/builds/1175 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_ssl make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Fri Apr 24 18:03:02 2009 From: python-checkins at python.org (tarek.ziade) Date: Fri, 24 Apr 2009 18:03:02 +0200 (CEST) Subject: [Python-checkins] r71836 - peps/trunk/pep-0376.txt Message-ID: <20090424160302.D861C1E401C@bag.python.org> Author: tarek.ziade Date: Fri Apr 24 18:03:02 2009 New Revision: 71836 Log: changes according to community feedback + uninstall script Modified: peps/trunk/pep-0376.txt Modified: peps/trunk/pep-0376.txt ============================================================================== --- peps/trunk/pep-0376.txt (original) +++ peps/trunk/pep-0376.txt Fri Apr 24 18:03:02 2009 @@ -18,37 +18,41 @@ - A new format for the .egg-info structure. - Some APIs to read the meta-data of a project -- An install script to install a package in Python. -- An uninstall script to uninstall a package in Python. +Definitions +=========== -Rationale -========= +A **project** is a Python application composed of one or many Python packages. +It is distributed using a `setup.py` script with Distutils and/or Setuptools. -There are three problems right now in the way packages -are installed in Python: +Once installed, one or several **packages** are added in Python's site-packages. -- There are too many ways to install a package in Python. +Rationale +========= -- There is no way to uninstall a package. +There are three problems right now in the way projects are installed in +Python: +- There are too many ways to install a project in Python. - There is no API to get the metadata of installed packages. -How packages are installed +How projects are installed -------------------------- -Right now, when a package is installed in Python, using the -Distutils `install` command, the `install_egg_info` subcommand is -called in order to create an `.egg-info` file in the site-packages directory, -right beside the package itself. +Right now, when a project is installed in Python, every package its contains +is installed in the `site-packages` directory with the Distutils `install` +command. -For example, if the `zlib` package is installed, two elements -will be installed in `site-packages`:: +The `install_egg_info` subcommand is called during this process, in order to +create an `.egg-info` file in the `site-packages` directory. - - zlib - - zlib-2.5.2.egg-info +For example, if the `zlib` project is installed (which contains one package), +two elements will be installed in `site-packages`:: -Where `zlib` is the package itself, and `zlib-2.5.2.egg-info` is + - zlib + - zlib-2.5.2-py2.4.egg-info + +Where `zlib` is the package, and `zlib-2.5.2-py2.4.egg-info` is a file containing the package metadata as described in PEP 314. This file corresponds to the file called `PKG-INFO`, built by @@ -59,42 +63,31 @@ packages in the same way that Distutils does: - `easy_install` creates an `EGG-INFO` directory inside an `.egg` directory, - and adds a `PKG-INFO` file inside this directory, amongst other files. + and adds a `PKG-INFO` file inside this directory. The `.egg` directory + contains in that case the packages of the project. - `pip` creates an `.egg-info` directory inside the site-packages directory - besides the package, and adds a `PKG-INFO` file inside it. + and adds a `PKG-INFO` file inside it. Packages are installed in + site-packages directory in a regular way. They both add other files in the `EGG-INFO` or `.egg-info` directory, and -create or modify `.pth` files. `pip` also creates one `.pth` file -per installed package, which may lead to slow initialisation of Python. +create or modify `.pth` files. -The uninstall command +Uninstall information --------------------- -Python doesn't provide any `uninstall` command. If you want to uninstall -a package, you have to be a power user and remove the package directory -from the right site-packages directory, then look over the right pth -files. And this method differs, depending on the tools you are using. +Distutils doesn't provide any `uninstall` command. If you want to uninstall +a project, you have to be a power user and remove the various package +directories from the right `site-packages` directory, then look over the right +`pth` files. And this method differs, depending on the tools you are using. The worst issue is that you depend on the way the packager created his package. When you call `python setup.py install`, it will not be installed the same way -depending on the tool used by the packager (distutils or setuptools). +depending on the tool used by the packager (mainly Distutils or Setuptools). But there's common behavior: files are copied in your installation. And there's a way to keep track of theses file, so to remove them. -Installing a package --------------------- - -There are too many different ways to install a package in Python: - -- by hand, by getting a distribution and running the install command -- using `easy_install`, the script provided by setuptools -- using `pip` - -The problem is: they do not install the package the same way, -and Python should provide one and only one way to do it. - What this PEP proposes ---------------------- @@ -102,9 +95,8 @@ - a new `.egg-info` structure using a directory; - a list of elements this directory holds; -- some new functions in `pkgutil` -- addition of an install and an uninstall script - +- new functions in `pkgutil` to be able to query the information + of installed projects. .egg-info becomes a directory ============================= @@ -124,48 +116,57 @@ will be installed in `site-packages`:: - zlib - - zlib-2.5.2-py2.6.egg-info/ + - zlib-2.5.2.egg-info/ PKG-INFO -To be able to implement this change, the impacted code in Distutils -is the `install_egg_info` command. - +The Python version will also be removed from the .egg-info directory +name. To be able to implement this change, the impacted code in Distutils +is the `install_egg_info` command, and the various third-party projects. -Adding MANIFEST and RECORD in the .egg-info directory -===================================================== +Adding a RECORD in the .egg-info directory +========================================== -Some files can be added inside the `.egg-info` directory at installation -time. They will all be UPPERCASE files. - -- the `MANIFEST` file built by the `sdist` command. Notice that - some fixes were made lately on the default file names added in `MANIFEST` - when `MANIFEST.in` is not provided (see #2279 for instance). +A `RECORD` file will be added inside the `.egg-info` directory at installation +time. - the `RECORD` file will hold the list of installed files. These correspond to the files listed by the `record` option of the `install` command, and will always be generated. This will allow uninstall, as - explained later in this PEP. + explained later in this PEP. -The two files will need to use '/'-separated relative paths. The `install` command will record by default installed files in the -RECORD file. +RECORD file, using these rules: + +- if the installed file is located in a directory in `site-packages`, + it will be a '/'-separated relative path, no matter what is the target + system. This makes this information cross-compatible and allows simple + installation to be relocatable. -The `sdist` module will introduce an `EGG_INFO_FILES` constant to list -all files located in the `.egg-info` directory:: +- if the installed file is located elswhere in the system, a + '/'-separated absolute path is used. + +This will require changing the way the `install` command writes the record +file, so the old `record` behavior will be deprecated. +XXX see how to handle old record (new option, or wait for 2 version?) + +Listing the .egg-info elements in Distutils +=========================================== + +In Distutils, the `dist` module will introduce an `EGG_INFO_FILES` constant +to list all files located in the `.egg-info` directory:: from collections import namedtuple EggInfos = namedtuple('EggInfo', 'manifest record pkg_info') # files added in egg-info - EGG_INFO_FILES = EggInfos('MANIFEST', 'RECORD', 'PKG-INFO') + EGG_INFO_FILES = EggInfos('RECORD', 'PKG-INFO') Back to our `zlib` example, we will have:: - zlib - zlib-2.5.2.egg-info/ PKG-INFO - MANIFEST RECORD XXX See if we want to add Python version in the PKG-INFO @@ -176,7 +177,6 @@ To use the `.egg-info` directory content, we need to add in the standard library a set of APIs. The best place to put these APIs seems to be `pkgutil`. - The new functions added in the package are : - get_egg_info(project_name) -> path or None @@ -216,57 +216,38 @@ files -Adding an install and an uninstall script -========================================= - -XXX decide wheter we include these scripts. - -`easy_install` and `pip` does basically the same work, besides other features -that are not discussed here. - -- they look for the package at PyPI -- they download it and build it -- they install it inside the site-packages directory -- they add an entry in a .pth file - -Distutils will provide two simple reference scripts, that are just able -to do the features mentioned. Third party packages will be able to fetch -dependencies. - -Install script --------------- - -A new script called `install.py` is added in a new directory called `scripts` -in Distutils, and lets people run an installation using:: - - $ python -m distutils.scripts.install zlib - -Where `zlib` can be: -- the name of the package -- an url of an archive -- a path - -The install script process is done in 3 steps: - -1. it looks for the package at PyPI if it's a package name - XXX explain here how (easy_install code) -2. it downloads it in a temporary directory (or copy it if it's a path) -3. it runs the install command, with the --record option - XXX explains here how (see pip code) - -The install script takes several options : - -Uninstall script ----------------- +Adding an Uninstall API +======================= -An uninstall command is added as well that removes the files recorded -in the RECORD file. This removal will warn on files that no longer exist -and will not take care of side effects, like the removal of a file -used by another element of the system. +Distutils provides a very basic way to install a project, which is running +the `install` command over the `setup.py` script of the distribution. - $ python -m distutils.scripts.uninstall zlib +Distutils will provide a very basic `uninstall` command that will remove +all files listed in the `RECORD` file of a project, as long as they are not +mentioned in another `RECORD` file. + +This command will be added in the `util` module and will take the name +of the project to uninstall:: + + >>> from distutils.util import uninstall + >>> uninstall('zlib') + +To make it a reference API for third-party projects that wish to provide +an `uninstall feature`. The `uninstall` API can also be invoked with a +second callable argument, that will be invoked for each file to be removed. +If it returns `True`, the file will be removed. + +Examples:: + + >>> def _remove_and_log(path): + ... logging.info('Removing %s' % path) + ... return True + >>> uninstall('zlib', _remove_and_log) + >>> def _dry_run(path): + ... logging.info('Removing %s (dry run)' % path) + ... return False + >>> uninstall('zlib', _dry_run) -XXX work to be done here : detail specification of the uninstall process Aknowledgments ============== From buildbot at python.org Fri Apr 24 18:27:30 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 24 Apr 2009 16:27:30 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090424162730.8CB9F1E401C@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/292 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 3 tests failed: test_distutils test_posix test_subprocess ====================================================================== FAIL: test_get_python_inc (distutils.tests.test_sysconfig.SysconfigTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/distutils/tests/test_sysconfig.py", line 45, in test_get_python_inc self.assert_(os.path.isdir(inc_dir), inc_dir) AssertionError: /home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/Include ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From python-checkins at python.org Fri Apr 24 18:34:15 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 24 Apr 2009 18:34:15 +0200 (CEST) Subject: [Python-checkins] r71837 - python/trunk/Lib/test/test_math.py Message-ID: <20090424163415.115F11E4013@bag.python.org> Author: mark.dickinson Date: Fri Apr 24 18:34:14 2009 New Revision: 71837 Log: Issue #5593: Use more robust test for double-rounding in test_fsum. While we're at it, use new unittest.skipUnless decorator to implement skipping for that test. Modified: python/trunk/Lib/test/test_math.py Modified: python/trunk/Lib/test/test_math.py ============================================================================== --- python/trunk/Lib/test/test_math.py (original) +++ python/trunk/Lib/test/test_math.py Fri Apr 24 18:34:14 2009 @@ -13,6 +13,11 @@ INF = float('inf') NINF = float('-inf') +# 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 +HAVE_DOUBLE_ROUNDING = (x + y == 1e16 + 4) + # locate file with test values if __name__ == '__main__': file = sys.argv[0] @@ -364,6 +369,10 @@ self.assertEquals(math.frexp(NINF)[0], NINF) self.assert_(math.isnan(math.frexp(NAN)[0])) + @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + @unittest.skipUnless(not HAVE_DOUBLE_ROUNDING, + "fsum is not exact on machines with double rounding") def testFsum(self): # math.fsum relies on exact rounding for correct operation. # There's a known problem with IA32 floating-point that causes @@ -373,14 +382,6 @@ # problem described in issue #2937, we simply skip the whole # test. - if not float.__getformat__("double").startswith("IEEE"): - return - - # on IEEE 754 compliant machines, both of the expressions - # below should round to 10000000000000002.0. - if 1e16+2.0 != 1e16+2.9999: - return - # Python version of math.fsum, for comparison. Uses a # different algorithm based on frexp, ldexp and integer # arithmetic. From python-checkins at python.org Fri Apr 24 18:37:23 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 24 Apr 2009 18:37:23 +0200 (CEST) Subject: [Python-checkins] r71838 - python/trunk/Lib/test/test_math.py Message-ID: <20090424163723.089361E4013@bag.python.org> Author: mark.dickinson Date: Fri Apr 24 18:37:22 2009 New Revision: 71838 Log: Remove unnecessary double negative Modified: python/trunk/Lib/test/test_math.py Modified: python/trunk/Lib/test/test_math.py ============================================================================== --- python/trunk/Lib/test/test_math.py (original) +++ python/trunk/Lib/test/test_math.py Fri Apr 24 18:37:22 2009 @@ -371,7 +371,7 @@ @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), "test requires IEEE 754 doubles") - @unittest.skipUnless(not HAVE_DOUBLE_ROUNDING, + @unittest.skipIf(HAVE_DOUBLE_ROUNDING, "fsum is not exact on machines with double rounding") def testFsum(self): # math.fsum relies on exact rounding for correct operation. From python-checkins at python.org Fri Apr 24 18:39:07 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 24 Apr 2009 18:39:07 +0200 (CEST) Subject: [Python-checkins] r71839 - in python/branches/py3k: Lib/test/test_math.py Message-ID: <20090424163907.326A91E4013@bag.python.org> Author: mark.dickinson Date: Fri Apr 24 18:39:07 2009 New Revision: 71839 Log: Merged revisions 71837-71838 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71837 | mark.dickinson | 2009-04-24 17:34:14 +0100 (Fri, 24 Apr 2009) | 4 lines Issue #5593: Use more robust test for double-rounding in test_fsum. While we're at it, use new unittest.skipUnless decorator to implement skipping for that test. ........ r71838 | mark.dickinson | 2009-04-24 17:37:22 +0100 (Fri, 24 Apr 2009) | 2 lines Remove unnecessary double negative ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_math.py 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 Fri Apr 24 18:39:07 2009 @@ -13,6 +13,11 @@ INF = float('inf') NINF = float('-inf') +# 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 +HAVE_DOUBLE_ROUNDING = (x + y == 1e16 + 4) + # locate file with test values if __name__ == '__main__': file = sys.argv[0] @@ -359,6 +364,10 @@ self.assertEquals(math.frexp(NINF)[0], NINF) self.assert_(math.isnan(math.frexp(NAN)[0])) + @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + @unittest.skipIf(HAVE_DOUBLE_ROUNDING, + "fsum is not exact on machines with double rounding") def testFsum(self): # math.fsum relies on exact rounding for correct operation. # There's a known problem with IA32 floating-point that causes @@ -368,14 +377,6 @@ # problem described in issue #2937, we simply skip the whole # test. - if not float.__getformat__("double").startswith("IEEE"): - return - - # on IEEE 754 compliant machines, both of the expressions - # below should round to 10000000000000002.0. - if 1e16+2.0 != 1e16+2.9999: - return - # Python version of math.fsum, for comparison. Uses a # different algorithm based on frexp, ldexp and integer # arithmetic. From python-checkins at python.org Fri Apr 24 18:40:20 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 24 Apr 2009 18:40:20 +0200 (CEST) Subject: [Python-checkins] r71840 - python/branches/release26-maint Message-ID: <20090424164020.F189D1E4013@bag.python.org> Author: mark.dickinson Date: Fri Apr 24 18:40:20 2009 New Revision: 71840 Log: Blocked revisions 71837-71838 via svnmerge ........ r71837 | mark.dickinson | 2009-04-24 17:34:14 +0100 (Fri, 24 Apr 2009) | 4 lines Issue #5593: Use more robust test for double-rounding in test_fsum. While we're at it, use new unittest.skipUnless decorator to implement skipping for that test. ........ r71838 | mark.dickinson | 2009-04-24 17:37:22 +0100 (Fri, 24 Apr 2009) | 2 lines Remove unnecessary double negative ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Fri Apr 24 18:41:00 2009 From: python-checkins at python.org (mark.dickinson) Date: Fri, 24 Apr 2009 18:41:00 +0200 (CEST) Subject: [Python-checkins] r71841 - python/branches/release30-maint Message-ID: <20090424164100.792611E4013@bag.python.org> Author: mark.dickinson Date: Fri Apr 24 18:41:00 2009 New Revision: 71841 Log: Blocked revisions 71839 via svnmerge ................ r71839 | mark.dickinson | 2009-04-24 17:39:07 +0100 (Fri, 24 Apr 2009) | 15 lines Merged revisions 71837-71838 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71837 | mark.dickinson | 2009-04-24 17:34:14 +0100 (Fri, 24 Apr 2009) | 4 lines Issue #5593: Use more robust test for double-rounding in test_fsum. While we're at it, use new unittest.skipUnless decorator to implement skipping for that test. ........ r71838 | mark.dickinson | 2009-04-24 17:37:22 +0100 (Fri, 24 Apr 2009) | 2 lines Remove unnecessary double negative ........ ................ Modified: python/branches/release30-maint/ (props changed) From buildbot at python.org Fri Apr 24 19:28:15 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 24 Apr 2009 17:28:15 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc trunk Message-ID: <20090424172815.3F8391E4013@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc trunk. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%20trunk/builds/323 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posixpath sincerely, -The Buildbot From buildbot at python.org Fri Apr 24 20:10:00 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 24 Apr 2009 18:10:00 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090424181000.CB3FD1E4013@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/631 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_unicode make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Fri Apr 24 20:10:46 2009 From: python-checkins at python.org (thomas.heller) Date: Fri, 24 Apr 2009 20:10:46 +0200 (CEST) Subject: [Python-checkins] r71842 - python/trunk/Makefile.pre.in Message-ID: <20090424181046.3A30D1E4056@bag.python.org> Author: thomas.heller Date: Fri Apr 24 20:10:46 2009 New Revision: 71842 Log: Issue #5161: wrong paths for ctypes cleanup when Python is built in a directory other than the source directory. Modified: python/trunk/Makefile.pre.in Modified: python/trunk/Makefile.pre.in ============================================================================== --- python/trunk/Makefile.pre.in (original) +++ python/trunk/Makefile.pre.in Fri Apr 24 20:10:46 2009 @@ -1143,8 +1143,8 @@ clean: pycremoval find . -name '*.o' -exec rm -f {} ';' find . -name '*.s[ol]' -exec rm -f {} ';' - find $(srcdir)/build -name 'fficonfig.h' -exec rm -f {} ';' || true - find $(srcdir)/build -name 'fficonfig.py' -exec rm -f {} ';' || true + find build -name 'fficonfig.h' -exec rm -f {} ';' || true + find build -name 'fficonfig.py' -exec rm -f {} ';' || true profile-removal: find . -name '*.gc??' -exec rm -f {} ';' From python-checkins at python.org Fri Apr 24 20:27:10 2009 From: python-checkins at python.org (thomas.heller) Date: Fri, 24 Apr 2009 20:27:10 +0200 (CEST) Subject: [Python-checkins] r71843 - in python/branches/py3k: Makefile.pre.in Message-ID: <20090424182710.7822D1E4013@bag.python.org> Author: thomas.heller Date: Fri Apr 24 20:27:10 2009 New Revision: 71843 Log: Merged revisions 71842 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71842 | thomas.heller | 2009-04-24 20:10:46 +0200 (Fr, 24 Apr 2009) | 3 lines Issue #5161: wrong paths for ctypes cleanup when Python is built in a directory other than the source directory. ........ Modified: python/branches/py3k/ (props changed) 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 Fri Apr 24 20:27:10 2009 @@ -1161,8 +1161,8 @@ clean: pycremoval find . -name '*.o' -exec rm -f {} ';' find . -name '*.s[ol]' -exec rm -f {} ';' - find $(srcdir)/build -name 'fficonfig.h' -exec rm -f {} ';' || true - find $(srcdir)/build -name 'fficonfig.py' -exec rm -f {} ';' || true + find build -name 'fficonfig.h' -exec rm -f {} ';' || true + find build -name 'fficonfig.py' -exec rm -f {} ';' || true profile-removal: find . -name '*.gc??' -exec rm -f {} ';' From python-checkins at python.org Fri Apr 24 20:43:43 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 24 Apr 2009 20:43:43 +0200 (CEST) Subject: [Python-checkins] r71844 - python/branches/py3k/Lib/sched.py Message-ID: <20090424184343.744911E4013@bag.python.org> Author: raymond.hettinger Date: Fri Apr 24 20:43:43 2009 New Revision: 71844 Log: Issue 5830: Events are now comparable when the time and type are the same. Modified: python/branches/py3k/Lib/sched.py Modified: python/branches/py3k/Lib/sched.py ============================================================================== --- python/branches/py3k/Lib/sched.py (original) +++ python/branches/py3k/Lib/sched.py Fri Apr 24 20:43:43 2009 @@ -33,7 +33,13 @@ __all__ = ["scheduler"] -Event = namedtuple('Event', 'time, priority, action, argument') +class Event(namedtuple('Event', 'time, priority, action, argument')): + def __eq__(s, o): return (s.time, s.priority) == (o.time, o.priority) + def __ne__(s, o): return (s.time, s.priority) != (o.time, o.priority) + def __lt__(s, o): return (s.time, s.priority) < (o.time, o.priority) + def __le__(s, o): return (s.time, s.priority) <= (o.time, o.priority) + def __gt__(s, o): return (s.time, s.priority) > (o.time, o.priority) + def __ge__(s, o): return (s.time, s.priority) >= (o.time, o.priority) class scheduler: def __init__(self, timefunc, delayfunc): From python-checkins at python.org Fri Apr 24 20:48:59 2009 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 24 Apr 2009 20:48:59 +0200 (CEST) Subject: [Python-checkins] r71845 - in python/branches/release30-maint: Lib/sched.py Misc/NEWS Message-ID: <20090424184859.DABEF1E4013@bag.python.org> Author: raymond.hettinger Date: Fri Apr 24 20:48:59 2009 New Revision: 71845 Log: Issue 5830: Events are now comparable when the time and type are the same. Modified: python/branches/release30-maint/Lib/sched.py python/branches/release30-maint/Misc/NEWS Modified: python/branches/release30-maint/Lib/sched.py ============================================================================== --- python/branches/release30-maint/Lib/sched.py (original) +++ python/branches/release30-maint/Lib/sched.py Fri Apr 24 20:48:59 2009 @@ -33,7 +33,13 @@ __all__ = ["scheduler"] -Event = namedtuple('Event', 'time, priority, action, argument') +class Event(namedtuple('Event', 'time, priority, action, argument')): + def __eq__(s, o): return (s.time, s.priority) == (o.time, o.priority) + def __ne__(s, o): return (s.time, s.priority) != (o.time, o.priority) + def __lt__(s, o): return (s.time, s.priority) < (o.time, o.priority) + def __le__(s, o): return (s.time, s.priority) <= (o.time, o.priority) + def __gt__(s, o): return (s.time, s.priority) > (o.time, o.priority) + def __ge__(s, o): return (s.time, s.priority) >= (o.time, o.priority) class scheduler: def __init__(self, timefunc, delayfunc): Modified: python/branches/release30-maint/Misc/NEWS ============================================================================== --- python/branches/release30-maint/Misc/NEWS (original) +++ python/branches/release30-maint/Misc/NEWS Fri Apr 24 20:48:59 2009 @@ -35,6 +35,9 @@ Library ------- +- Issue 5830: The sched module no longer raises a TypeError when + prioritizing Events with the same time and priority. + - Issue #1161031: fix readwrite select flag handling: POLLPRI now results in a handle_expt_event call, not handle_read_event, and POLLERR and POLLNVAL now call handle_close, not handle_expt_event. Also, From python-checkins at python.org Fri Apr 24 21:06:29 2009 From: python-checkins at python.org (georg.brandl) Date: Fri, 24 Apr 2009 21:06:29 +0200 (CEST) Subject: [Python-checkins] r71846 - python/branches/py3k/Doc/tutorial/floatingpoint.rst Message-ID: <20090424190629.51D8A1E401E@bag.python.org> Author: georg.brandl Date: Fri Apr 24 21:06:29 2009 New Revision: 71846 Log: Remove leftover word. Modified: python/branches/py3k/Doc/tutorial/floatingpoint.rst Modified: python/branches/py3k/Doc/tutorial/floatingpoint.rst ============================================================================== --- python/branches/py3k/Doc/tutorial/floatingpoint.rst (original) +++ python/branches/py3k/Doc/tutorial/floatingpoint.rst Fri Apr 24 21:06:29 2009 @@ -78,7 +78,7 @@ ``0.10000000000000001`` and ``0.1000000000000000055511151231257827021181583404541015625`` are all approximated by ``3602879701896397 / 2 ** 55``. Since all of these decimal -values share the same approximation, any one of them could be displayed and +values share the same approximation, any one of them could be displayed while still preserving the invariant ``eval(repr(x)) == x``. Historically, the Python prompt and built-in :func:`repr` function would chose From buildbot at python.org Fri Apr 24 21:45:30 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 24 Apr 2009 19:45:30 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu trunk Message-ID: <20090424194530.A35DD1E4013@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%20trunk/builds/1271 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 3 tests failed: test_list test_tuple test_userlist ====================================================================== ERROR: test_getitem (test.test_list.ListTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/seq_tests.py", line 146, in test_getitem self.assertRaises(IndexError, u.__getitem__, len(u)) AttributeError: 'ListTest' object has no attribute 'asse' ====================================================================== ERROR: test_iadd (test.test_list.ListTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/list_tests.py", line 462, in test_iadd super(CommonTest, self).test_iadd() AttributeError: 'super' object has no attribute 'test_iadd' ====================================================================== ERROR: test_len (test.test_list.ListTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/test_list.py", line 49, in test_len super(ListTest, self).test_len() AttributeError: 'super' object has no attribute 'test_len' ====================================================================== ERROR: test_constructors (test.test_tuple.TupleTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/test_tuple.py", line 9, in test_constructors super(TupleTest, self).test_len() AttributeError: 'super' object has no attribute 'test_len' ====================================================================== ERROR: test_getitem (test.test_tuple.TupleTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/seq_tests.py", line 146, in test_getitem self.assertRaises(IndexError, u.__getitem__, len(u)) AttributeError: 'TupleTest' object has no attribute 'asse' ====================================================================== ERROR: test_iadd (test.test_tuple.TupleTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/test_tuple.py", line 32, in test_iadd super(TupleTest, self).test_iadd() AttributeError: 'super' object has no attribute 'test_iadd' ====================================================================== ERROR: test_imul (test.test_tuple.TupleTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/test_tuple.py", line 39, in test_imul super(TupleTest, self).test_imul() AttributeError: 'super' object has no attribute 'test_imul' ====================================================================== ERROR: test_len (test.test_tuple.TupleTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/test_tuple.py", line 26, in test_len super(TupleTest, self).test_len() AttributeError: 'super' object has no attribute 'test_len' ====================================================================== ERROR: test_getitem (test.test_userlist.UserListTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/seq_tests.py", line 146, in test_getitem self.assertRaises(IndexError, u.__getitem__, len(u)) AttributeError: 'UserListTest' object has no attribute 'asse' ====================================================================== ERROR: test_getslice (test.test_userlist.UserListTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/test_userlist.py", line 10, in test_getslice super(UserListTest, self).test_getslice() AttributeError: 'super' object has no attribute 'test_getslice' ====================================================================== ERROR: test_iadd (test.test_userlist.UserListTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/test_userlist.py", line 32, in test_iadd super(UserListTest, self).test_iadd() File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/list_tests.py", line 462, in test_iadd super(CommonTest, self).test_iadd() AttributeError: 'super' object has no attribute 'test_iadd' make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Fri Apr 24 22:00:41 2009 From: python-checkins at python.org (thomas.heller) Date: Fri, 24 Apr 2009 22:00:41 +0200 (CEST) Subject: [Python-checkins] r71847 - in python/trunk: Lib/ctypes/test/test_pickling.py Misc/NEWS Modules/_ctypes/_ctypes.c Message-ID: <20090424200041.A98901E4013@bag.python.org> Author: thomas.heller Date: Fri Apr 24 22:00:41 2009 New Revision: 71847 Log: Issue 5041: ctypes unwilling to allow pickling wide character. Modified: python/trunk/Lib/ctypes/test/test_pickling.py python/trunk/Misc/NEWS python/trunk/Modules/_ctypes/_ctypes.c Modified: python/trunk/Lib/ctypes/test/test_pickling.py ============================================================================== --- python/trunk/Lib/ctypes/test/test_pickling.py (original) +++ python/trunk/Lib/ctypes/test/test_pickling.py Fri Apr 24 22:00:41 2009 @@ -66,6 +66,11 @@ ]: self.assertRaises(ValueError, lambda: self.dumps(item)) + def test_wchar(self): + pickle.dumps(c_char("x")) + # Issue 5049 + pickle.dumps(c_wchar(u"x")) + class PickleTest_1(PickleTest): def dumps(self, item): return pickle.dumps(item, 1) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Apr 24 22:00:41 2009 @@ -244,6 +244,8 @@ Library ------- +- Issue #5041: ctypes does now allow pickling wide character. + - Issue #5812: For the two-argument form of the Fraction constructor, Fraction(m, n), m and n are permitted to be arbitrary Rational instances. Modified: python/trunk/Modules/_ctypes/_ctypes.c ============================================================================== --- python/trunk/Modules/_ctypes/_ctypes.c (original) +++ python/trunk/Modules/_ctypes/_ctypes.c Fri Apr 24 22:00:41 2009 @@ -1952,7 +1952,7 @@ ml = &c_void_p_method; stgdict->flags |= TYPEFLAG_ISPOINTER; break; - case 'u': + case 's': case 'X': case 'O': ml = NULL; From python-checkins at python.org Fri Apr 24 22:05:21 2009 From: python-checkins at python.org (thomas.heller) Date: Fri, 24 Apr 2009 22:05:21 +0200 (CEST) Subject: [Python-checkins] r71848 - in python/branches/py3k: Lib/ctypes/test/test_pickling.py Misc/NEWS Modules/_ctypes/_ctypes.c Message-ID: <20090424200521.464901E4038@bag.python.org> Author: thomas.heller Date: Fri Apr 24 22:05:20 2009 New Revision: 71848 Log: Merged revisions 71847 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71847 | thomas.heller | 2009-04-24 22:00:41 +0200 (Fr, 24 Apr 2009) | 2 lines Issue 5041: ctypes unwilling to allow pickling wide character. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/ctypes/test/test_pickling.py python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_ctypes/_ctypes.c Modified: python/branches/py3k/Lib/ctypes/test/test_pickling.py ============================================================================== --- python/branches/py3k/Lib/ctypes/test/test_pickling.py (original) +++ python/branches/py3k/Lib/ctypes/test/test_pickling.py Fri Apr 24 22:05:20 2009 @@ -66,6 +66,11 @@ ]: self.assertRaises(ValueError, lambda: self.dumps(item)) + def test_wchar(self): + pickle.dumps(c_char(b"x")) + # Issue 5049 + pickle.dumps(c_wchar("x")) + class PickleTest_1(PickleTest): def dumps(self, item): return pickle.dumps(item, 1) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Apr 24 22:05:20 2009 @@ -430,7 +430,7 @@ Library ------- -- Issue #5795: Fixed test_distutils failure on Debian ppc. +- Issue #5041: ctypes does now allow pickling wide character. - Issue #5607: fixed Distutils test_get_platform for Mac OS X fat binaries. Modified: python/branches/py3k/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k/Modules/_ctypes/_ctypes.c Fri Apr 24 22:05:20 2009 @@ -1927,7 +1927,7 @@ ml = &c_void_p_method; stgdict->flags |= TYPEFLAG_ISPOINTER; break; - case 'u': + case 's': case 'X': case 'O': ml = NULL; From python-checkins at python.org Fri Apr 24 22:09:23 2009 From: python-checkins at python.org (thomas.heller) Date: Fri, 24 Apr 2009 22:09:23 +0200 (CEST) Subject: [Python-checkins] r71849 - in python/branches/release30-maint: Lib/ctypes/test/test_pickling.py Misc/NEWS Modules/_ctypes/_ctypes.c Message-ID: <20090424200923.E6DC41E4013@bag.python.org> Author: thomas.heller Date: Fri Apr 24 22:09:23 2009 New Revision: 71849 Log: Merged revisions 71848 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71848 | thomas.heller | 2009-04-24 22:05:20 +0200 (Fr, 24 Apr 2009) | 9 lines Merged revisions 71847 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71847 | thomas.heller | 2009-04-24 22:00:41 +0200 (Fr, 24 Apr 2009) | 2 lines Issue 5041: ctypes unwilling to allow pickling wide character. ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Lib/ctypes/test/test_pickling.py python/branches/release30-maint/Misc/NEWS python/branches/release30-maint/Modules/_ctypes/_ctypes.c Modified: python/branches/release30-maint/Lib/ctypes/test/test_pickling.py ============================================================================== --- python/branches/release30-maint/Lib/ctypes/test/test_pickling.py (original) +++ python/branches/release30-maint/Lib/ctypes/test/test_pickling.py Fri Apr 24 22:09:23 2009 @@ -66,6 +66,11 @@ ]: self.assertRaises(ValueError, lambda: self.dumps(item)) + def test_wchar(self): + pickle.dumps(c_char(b"x")) + # Issue 5049 + pickle.dumps(c_wchar("x")) + class PickleTest_1(PickleTest): def dumps(self, item): return pickle.dumps(item, 1) Modified: python/branches/release30-maint/Misc/NEWS ============================================================================== --- python/branches/release30-maint/Misc/NEWS (original) +++ python/branches/release30-maint/Misc/NEWS Fri Apr 24 22:09:23 2009 @@ -230,6 +230,8 @@ Library ------- +- Issue #5041: ctypes does now allow pickling wide character. + - Issue #5731: Distutils bdist_wininst no longer worked on non-Windows platforms. Initial patch by Paul Moore. Modified: python/branches/release30-maint/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/release30-maint/Modules/_ctypes/_ctypes.c (original) +++ python/branches/release30-maint/Modules/_ctypes/_ctypes.c Fri Apr 24 22:09:23 2009 @@ -1927,7 +1927,7 @@ ml = &c_void_p_method; stgdict->flags |= TYPEFLAG_ISPOINTER; break; - case 'u': + case 's': case 'X': case 'O': ml = NULL; From python-checkins at python.org Fri Apr 24 22:10:25 2009 From: python-checkins at python.org (thomas.heller) Date: Fri, 24 Apr 2009 22:10:25 +0200 (CEST) Subject: [Python-checkins] r71850 - python/branches/py3k/Misc/NEWS Message-ID: <20090424201025.208461E4013@bag.python.org> Author: thomas.heller Date: Fri Apr 24 22:10:24 2009 New Revision: 71850 Log: Fix merge accident. Modified: python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Apr 24 22:10:24 2009 @@ -432,6 +432,8 @@ - Issue #5041: ctypes does now allow pickling wide character. +- Issue #5795: Fixed test_distutils failure on Debian ppc. + - Issue #5607: fixed Distutils test_get_platform for Mac OS X fat binaries. - Issue #5732: added a new command in Distutils: check. From python-checkins at python.org Fri Apr 24 22:18:22 2009 From: python-checkins at python.org (thomas.heller) Date: Fri, 24 Apr 2009 22:18:22 +0200 (CEST) Subject: [Python-checkins] r71851 - in python/branches/release26-maint: Lib/ctypes/test/test_pickling.py Misc/NEWS Modules/_ctypes/_ctypes.c Message-ID: <20090424201822.B64171E4013@bag.python.org> Author: thomas.heller Date: Fri Apr 24 22:18:22 2009 New Revision: 71851 Log: Merged revisions 71847 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71847 | thomas.heller | 2009-04-24 22:00:41 +0200 (Fr, 24 Apr 2009) | 2 lines Issue 5041: ctypes unwilling to allow pickling wide character. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/ctypes/test/test_pickling.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Modules/_ctypes/_ctypes.c Modified: python/branches/release26-maint/Lib/ctypes/test/test_pickling.py ============================================================================== --- python/branches/release26-maint/Lib/ctypes/test/test_pickling.py (original) +++ python/branches/release26-maint/Lib/ctypes/test/test_pickling.py Fri Apr 24 22:18:22 2009 @@ -66,6 +66,11 @@ ]: self.assertRaises(ValueError, lambda: self.dumps(item)) + def test_wchar(self): + pickle.dumps(c_char("x")) + # Issue 5049 + pickle.dumps(c_wchar(u"x")) + class PickleTest_1(PickleTest): def dumps(self, item): return pickle.dumps(item, 1) Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Fri Apr 24 22:18:22 2009 @@ -17,9 +17,11 @@ - Issue #5759: float() didn't call __float__ on str subclasses. -Librar +Library ------- +- Issue #5041: ctypes does now allow pickling wide character. + - Issue #5768: Fixed bug in Unicode output logic and test case for same. - Issue #1161031: fix readwrite select flag handling: POLLPRI now Modified: python/branches/release26-maint/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/release26-maint/Modules/_ctypes/_ctypes.c (original) +++ python/branches/release26-maint/Modules/_ctypes/_ctypes.c Fri Apr 24 22:18:22 2009 @@ -1952,7 +1952,7 @@ ml = &c_void_p_method; stgdict->flags |= TYPEFLAG_ISPOINTER; break; - case 'u': + case 's': case 'X': case 'O': ml = NULL; From python-checkins at python.org Fri Apr 24 22:25:20 2009 From: python-checkins at python.org (martin.v.loewis) Date: Fri, 24 Apr 2009 22:25:20 +0200 (CEST) Subject: [Python-checkins] r71852 - peps/trunk/pep-0383.txt Message-ID: <20090424202520.363C81E4021@bag.python.org> Author: martin.v.loewis Date: Fri Apr 24 22:25:20 2009 New Revision: 71852 Log: Accept Lino Mastrodomenico's proposal of always using low surrogates to represent non-decodable bytes. Modified: peps/trunk/pep-0383.txt Modified: peps/trunk/pep-0383.txt ============================================================================== --- peps/trunk/pep-0383.txt (original) +++ peps/trunk/pep-0383.txt Fri Apr 24 22:25:20 2009 @@ -62,25 +62,23 @@ environmental data to Python str objects. On POSIX systems, Python currently applies the locale's encoding to -convert the byte data to Unicode. If the locale's encoding is UTF-8, -it can represent the full set of Unicode characters, otherwise, only a -subset is representable. In the latter case, using private-use -characters to represent these bytes would be an option. For UTF-8, -doing so would create an ambiguity, as the private-use characters may -regularly occur in the input also. +convert the byte data to Unicode. Non-decodable bytes will be +represented as lone half surrogate codes U+DCxx. To convert non-decodable bytes, a new error handler "python-escape" is -introduced, which decodes non-decodable bytes using into a private-use -character U+F01xx, which is believed to not conflict with private-use -characters that currently exist in Python codecs. +introduced, which produces these half surrogates. On encoding, the +error handler converts the half surrogate back to the corresponding +byte. The error handler interface is extended to allow the encode error handler to return byte strings immediately, in addition to returning Unicode strings which then get encoded again. If the locale's encoding is UTF-8, the file system encoding is set to -a new encoding "utf-8b". The UTF-8b codec decodes non-decodable bytes -(which must be >= 0x80) into half surrogate codes U+DC80..U+DCFF. +a new encoding "utf-8b", as the regular UTF-8 codec would not +re-encode half surrogates as single bytes. The UTF-8b codec decodes +non-decodable bytes (which must be >= 0x80) into half surrogate codes +U+DC80..U+DCFF. Discussion ========== From buildbot at python.org Fri Apr 24 22:26:36 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 24 Apr 2009 20:26:36 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu trunk Message-ID: <20090424202636.C12501E406D@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%20trunk/builds/1178 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: thomas.heller BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_xpickle make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Fri Apr 24 22:31:47 2009 From: python-checkins at python.org (thomas.heller) Date: Fri, 24 Apr 2009 22:31:47 +0200 (CEST) Subject: [Python-checkins] r71853 - in python/trunk: Misc/NEWS Modules/_ctypes/_ctypes.c Modules/_ctypes/callbacks.c Modules/_ctypes/callproc.c Modules/_ctypes/cfield.c Modules/_ctypes/ctypes.h Modules/_ctypes/malloc_closure.c Modules/_ctypes/stgdict.c Message-ID: <20090424203147.F1E371E401E@bag.python.org> Author: thomas.heller Date: Fri Apr 24 22:31:47 2009 New Revision: 71853 Log: Issue #3102: All global symbols that the _ctypes extension defines are now prefixed with 'Py' or '_ctypes'. Modified: python/trunk/Misc/NEWS python/trunk/Modules/_ctypes/_ctypes.c python/trunk/Modules/_ctypes/callbacks.c python/trunk/Modules/_ctypes/callproc.c python/trunk/Modules/_ctypes/cfield.c python/trunk/Modules/_ctypes/ctypes.h python/trunk/Modules/_ctypes/malloc_closure.c python/trunk/Modules/_ctypes/stgdict.c Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Fri Apr 24 22:31:47 2009 @@ -244,6 +244,9 @@ Library ------- +- Issue #3102: All global symbols that the _ctypes extension defines + are now prefixed with 'Py' or '_ctypes'. + - Issue #5041: ctypes does now allow pickling wide character. - Issue #5812: For the two-argument form of the Fraction constructor, Modified: python/trunk/Modules/_ctypes/_ctypes.c ============================================================================== --- python/trunk/Modules/_ctypes/_ctypes.c (original) +++ python/trunk/Modules/_ctypes/_ctypes.c Fri Apr 24 22:31:47 2009 @@ -6,7 +6,7 @@ /* ToDo: - Get rid of the checker (and also the converters) field in CFuncPtrObject and + Get rid of the checker (and also the converters) field in PyCFuncPtrObject and StgDictObject, and replace them by slot functions in StgDictObject. think about a buffer-like object (memory? bytes?) @@ -28,20 +28,20 @@ Name methods, members, getsets ============================================================================== -StructType_Type __new__(), from_address(), __mul__(), from_param() +PyCStructType_Type __new__(), from_address(), __mul__(), from_param() UnionType_Type __new__(), from_address(), __mul__(), from_param() -PointerType_Type __new__(), from_address(), __mul__(), from_param(), set_type() -ArrayType_Type __new__(), from_address(), __mul__(), from_param() -SimpleType_Type __new__(), from_address(), __mul__(), from_param() +PyCPointerType_Type __new__(), from_address(), __mul__(), from_param(), set_type() +PyCArrayType_Type __new__(), from_address(), __mul__(), from_param() +PyCSimpleType_Type __new__(), from_address(), __mul__(), from_param() -CData_Type +PyCData_Type Struct_Type __new__(), __init__() - Pointer_Type __new__(), __init__(), _as_parameter_, contents - Array_Type __new__(), __init__(), _as_parameter_, __get/setitem__(), __len__() + PyCPointer_Type __new__(), __init__(), _as_parameter_, contents + PyCArray_Type __new__(), __init__(), _as_parameter_, __get/setitem__(), __len__() Simple_Type __new__(), __init__(), _as_parameter_ -CField_Type -StgDict_Type +PyCField_Type +PyCStgDict_Type ============================================================================== @@ -87,20 +87,20 @@ */ /* - * StgDict_Type - * StructType_Type + * PyCStgDict_Type + * PyCStructType_Type * UnionType_Type - * PointerType_Type - * ArrayType_Type - * SimpleType_Type + * PyCPointerType_Type + * PyCArrayType_Type + * PyCSimpleType_Type * - * CData_Type + * PyCData_Type * Struct_Type * Union_Type - * Array_Type + * PyCArray_Type * Simple_Type - * Pointer_Type - * CField_Type + * PyCPointer_Type + * PyCField_Type * */ @@ -130,15 +130,15 @@ PyObject *PyExc_ArgError; /* This dict maps ctypes types to POINTER types */ -PyObject *_pointer_type_cache; +PyObject *_ctypes_ptrtype_cache; static PyTypeObject Simple_Type; /* a callable object used for unpickling */ static PyObject *_unpickle; -char *conversion_mode_encoding = NULL; -char *conversion_mode_errors = NULL; +char *_ctypes_conversion_encoding = NULL; +char *_ctypes_conversion_errors = NULL; /****************************************************************/ @@ -300,7 +300,7 @@ already be set. */ char * -alloc_format_string(const char *prefix, const char *suffix) +_ctypes_alloc_format_string(const char *prefix, const char *suffix) { size_t len; char *result; @@ -324,7 +324,7 @@ } /* - StructType_Type - a meta type/class. Creating a new class using this one as + PyCStructType_Type - a meta type/class. Creating a new class using this one as __metaclass__ will call the contructor StructUnionType_new. It replaces the tp_dict member with a new instance of StgDict, and initializes the C accessible fields somehow. @@ -336,7 +336,7 @@ PyCArgObject *parg; StgDictObject *stgdict; - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; @@ -372,7 +372,7 @@ if (PyDict_GetItemString(result->tp_dict, "_abstract_")) return (PyObject *)result; - dict = (StgDictObject *)PyObject_CallObject((PyObject *)&StgDict_Type, NULL); + dict = (StgDictObject *)PyObject_CallObject((PyObject *)&PyCStgDict_Type, NULL); if (!dict) { Py_DECREF(result); return NULL; @@ -386,7 +386,7 @@ } Py_DECREF(result->tp_dict); result->tp_dict = (PyObject *)dict; - dict->format = alloc_format_string(NULL, "B"); + dict->format = _ctypes_alloc_format_string(NULL, "B"); if (dict->format == NULL) { Py_DECREF(result); return NULL; @@ -401,7 +401,7 @@ if (basedict == NULL) return (PyObject *)result; /* copy base dict */ - if (-1 == StgDict_clone(dict, basedict)) { + if (-1 == PyCStgDict_clone(dict, basedict)) { Py_DECREF(result); return NULL; } @@ -418,7 +418,7 @@ } static PyObject * -StructType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +PyCStructType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { return StructUnionType_new(type, args, kwds, 1); } @@ -444,7 +444,7 @@ buf = (void *)PyLong_AsVoidPtr(value); if (PyErr_Occurred()) return NULL; - return CData_AtAddress(type, buf); + return PyCData_AtAddress(type, buf); } static char from_buffer_doc[] = @@ -491,7 +491,7 @@ return NULL; } - result = CData_AtAddress(type, (char *)buffer + offset); + result = PyCData_AtAddress(type, (char *)buffer + offset); if (result == NULL) return NULL; @@ -507,7 +507,7 @@ "C.from_buffer_copy(object, offset=0) -> C instance\ncreate a C instance from a readable buffer"; static PyObject * -GenericCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds); +GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static PyObject * CDataType_from_buffer_copy(PyObject *type, PyObject *args) @@ -548,7 +548,7 @@ return NULL; } - result = GenericCData_new((PyTypeObject *)type, NULL, NULL); + result = GenericPyCData_new((PyTypeObject *)type, NULL, NULL); if (result == NULL) return NULL; memcpy(((CDataObject *)result)->b_ptr, @@ -610,7 +610,7 @@ return NULL; } #endif - return CData_AtAddress(type, address); + return PyCData_AtAddress(type, address); } static char from_param_doc[] = @@ -678,7 +678,7 @@ "Array length must be >= 0, not %zd", #endif length); - return CreateArrayType(self, length); + return PyCArrayType_from_ctype(self, length); } static PySequenceMethods CDataType_as_sequence = { @@ -714,7 +714,7 @@ } static int -StructType_setattro(PyObject *self, PyObject *key, PyObject *value) +PyCStructType_setattro(PyObject *self, PyObject *key, PyObject *value) { /* XXX Should we disallow deleting _fields_? */ if (-1 == PyType_Type.tp_setattro(self, key, value)) @@ -722,7 +722,7 @@ if (value && PyString_Check(key) && 0 == strcmp(PyString_AS_STRING(key), "_fields_")) - return StructUnionType_update_stgdict(self, value, 1); + return PyCStructUnionType_update_stgdict(self, value, 1); return 0; } @@ -736,14 +736,14 @@ if (PyString_Check(key) && 0 == strcmp(PyString_AS_STRING(key), "_fields_")) - return StructUnionType_update_stgdict(self, value, 0); + return PyCStructUnionType_update_stgdict(self, value, 0); return 0; } -PyTypeObject StructType_Type = { +PyTypeObject PyCStructType_Type = { PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.StructType", /* tp_name */ + "_ctypes.PyCStructType", /* tp_name */ 0, /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ @@ -759,7 +759,7 @@ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ - StructType_setattro, /* tp_setattro */ + PyCStructType_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ "metatype for the CData Objects", /* tp_doc */ @@ -779,7 +779,7 @@ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - StructType_new, /* tp_new */ + PyCStructType_new, /* tp_new */ 0, /* tp_free */ }; @@ -830,20 +830,20 @@ /* -The PointerType_Type metaclass must ensure that the subclass of Pointer can be +The PyCPointerType_Type metaclass must ensure that the subclass of Pointer can be created. It must check for a _type_ attribute in the class. Since are no runtime created properties, a CField is probably *not* needed ? class IntPointer(Pointer): _type_ = "i" -The Pointer_Type provides the functionality: a contents method/property, a +The PyCPointer_Type provides the functionality: a contents method/property, a size property/method, and the sequence protocol. */ static int -PointerType_SetProto(StgDictObject *stgdict, PyObject *proto) +PyCPointerType_SetProto(StgDictObject *stgdict, PyObject *proto) { if (!proto || !PyType_Check(proto)) { PyErr_SetString(PyExc_TypeError, @@ -862,11 +862,11 @@ } static PyCArgObject * -PointerType_paramfunc(CDataObject *self) +PyCPointerType_paramfunc(CDataObject *self) { PyCArgObject *parg; - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; @@ -879,7 +879,7 @@ } static PyObject * -PointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyTypeObject *result; StgDictObject *stgdict; @@ -894,18 +894,18 @@ stgdict->proto has info about the pointed to type! */ stgdict = (StgDictObject *)PyObject_CallObject( - (PyObject *)&StgDict_Type, NULL); + (PyObject *)&PyCStgDict_Type, NULL); if (!stgdict) return NULL; stgdict->size = sizeof(void *); - stgdict->align = getentry("P")->pffi_type->alignment; + stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment; stgdict->length = 1; stgdict->ffi_type_pointer = ffi_type_pointer; - stgdict->paramfunc = PointerType_paramfunc; + stgdict->paramfunc = PyCPointerType_paramfunc; stgdict->flags |= TYPEFLAG_ISPOINTER; proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */ - if (proto && -1 == PointerType_SetProto(stgdict, proto)) { + if (proto && -1 == PyCPointerType_SetProto(stgdict, proto)) { Py_DECREF((PyObject *)stgdict); return NULL; } @@ -918,7 +918,7 @@ 'pointer to bytes' in this case. XXX Better would be to fix the format string later... */ - stgdict->format = alloc_format_string("&", + stgdict->format = _ctypes_alloc_format_string("&", itemdict->format ? itemdict->format : "B"); if (stgdict->format == NULL) { Py_DECREF((PyObject *)stgdict); @@ -948,14 +948,14 @@ static PyObject * -PointerType_set_type(PyTypeObject *self, PyObject *type) +PyCPointerType_set_type(PyTypeObject *self, PyObject *type) { StgDictObject *dict; dict = PyType_stgdict((PyObject *)self); assert(dict); - if (-1 == PointerType_SetProto(dict, type)) + if (-1 == PyCPointerType_SetProto(dict, type)) return NULL; if (-1 == PyDict_SetItemString((PyObject *)dict, "_type_", type)) @@ -968,7 +968,7 @@ staticforward PyObject *_byref(PyObject *); static PyObject * -PointerType_from_param(PyObject *type, PyObject *value) +PyCPointerType_from_param(PyObject *type, PyObject *value) { StgDictObject *typedict; @@ -1006,19 +1006,19 @@ return CDataType_from_param(type, value); } -static PyMethodDef PointerType_methods[] = { +static PyMethodDef PyCPointerType_methods[] = { { "from_address", CDataType_from_address, METH_O, from_address_doc }, { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, }, { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, }, { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc}, - { "from_param", (PyCFunction)PointerType_from_param, METH_O, from_param_doc}, - { "set_type", (PyCFunction)PointerType_set_type, METH_O }, + { "from_param", (PyCFunction)PyCPointerType_from_param, METH_O, from_param_doc}, + { "set_type", (PyCFunction)PyCPointerType_set_type, METH_O }, { NULL, NULL }, }; -PyTypeObject PointerType_Type = { +PyTypeObject PyCPointerType_Type = { PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.PointerType", /* tp_name */ + "_ctypes.PyCPointerType", /* tp_name */ 0, /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ @@ -1044,7 +1044,7 @@ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - PointerType_methods, /* tp_methods */ + PyCPointerType_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ @@ -1054,17 +1054,17 @@ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - PointerType_new, /* tp_new */ + PyCPointerType_new, /* tp_new */ 0, /* tp_free */ }; /******************************************************************/ /* - ArrayType_Type + PyCArrayType_Type */ /* - ArrayType_new ensures that the new Array subclass created has a _length_ + PyCArrayType_new ensures that the new Array subclass created has a _length_ attribute, and a _type_ attribute. */ @@ -1122,8 +1122,8 @@ if (PyUnicode_Check(value)) { value = PyUnicode_AsEncodedString(value, - conversion_mode_encoding, - conversion_mode_errors); + _ctypes_conversion_encoding, + _ctypes_conversion_errors); if (!value) return -1; } else if (!PyString_Check(value)) { @@ -1182,8 +1182,8 @@ } if (PyString_Check(value)) { value = PyUnicode_FromEncodedObject(value, - conversion_mode_encoding, - conversion_mode_errors); + _ctypes_conversion_encoding, + _ctypes_conversion_errors); if (!value) return -1; } else if (!PyUnicode_Check(value)) { @@ -1275,9 +1275,9 @@ } static PyCArgObject * -ArrayType_paramfunc(CDataObject *self) +PyCArrayType_paramfunc(CDataObject *self) { - PyCArgObject *p = new_CArgObject(); + PyCArgObject *p = PyCArgObject_new(); if (p == NULL) return NULL; p->tag = 'P'; @@ -1289,7 +1289,7 @@ } static PyObject * -ArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyTypeObject *result; StgDictObject *stgdict; @@ -1322,7 +1322,7 @@ } stgdict = (StgDictObject *)PyObject_CallObject( - (PyObject *)&StgDict_Type, NULL); + (PyObject *)&PyCStgDict_Type, NULL); if (!stgdict) return NULL; @@ -1337,10 +1337,10 @@ assert(itemdict->format); if (itemdict->format[0] == '(') { sprintf(buf, "(%ld,", length); - stgdict->format = alloc_format_string(buf, itemdict->format+1); + stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format+1); } else { sprintf(buf, "(%ld)", length); - stgdict->format = alloc_format_string(buf, itemdict->format); + stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format); } if (stgdict->format == NULL) { Py_DECREF((PyObject *)stgdict); @@ -1374,7 +1374,7 @@ Py_INCREF(proto); stgdict->proto = proto; - stgdict->paramfunc = &ArrayType_paramfunc; + stgdict->paramfunc = &PyCArrayType_paramfunc; /* Arrays are passed as pointers to function calls. */ stgdict->ffi_type_pointer = ffi_type_pointer; @@ -1397,11 +1397,11 @@ /* Special case for character arrays. A permanent annoyance: char arrays are also strings! */ - if (itemdict->getfunc == getentry("c")->getfunc) { + if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) { if (-1 == add_getset(result, CharArray_getsets)) return NULL; #ifdef CTYPES_UNICODE - } else if (itemdict->getfunc == getentry("u")->getfunc) { + } else if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { if (-1 == add_getset(result, WCharArray_getsets)) return NULL; #endif @@ -1410,9 +1410,9 @@ return (PyObject *)result; } -PyTypeObject ArrayType_Type = { +PyTypeObject PyCArrayType_Type = { PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.ArrayType", /* tp_name */ + "_ctypes.PyCArrayType", /* tp_name */ 0, /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ @@ -1448,18 +1448,18 @@ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - ArrayType_new, /* tp_new */ + PyCArrayType_new, /* tp_new */ 0, /* tp_free */ }; /******************************************************************/ /* - SimpleType_Type + PyCSimpleType_Type */ /* -SimpleType_new ensures that the new Simple_Type subclass created has a valid +PyCSimpleType_new ensures that the new Simple_Type subclass created has a valid _type_ attribute. */ @@ -1479,9 +1479,9 @@ } if (PyUnicode_Check(value) || PyString_Check(value)) { PyCArgObject *parg; - struct fielddesc *fd = getentry("Z"); + struct fielddesc *fd = _ctypes_get_fielddesc("Z"); - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; parg->pffi_type = &ffi_type_pointer; @@ -1503,7 +1503,7 @@ StgDictObject *dict; assert(dt); /* Cannot be NULL for pointer or array objects */ dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL; - if (dict && (dict->setfunc == getentry("u")->setfunc)) { + if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) { Py_INCREF(value); return value; } @@ -1512,7 +1512,7 @@ /* byref(c_char(...)) */ PyCArgObject *a = (PyCArgObject *)value; StgDictObject *dict = PyObject_stgdict(a->obj); - if (dict && (dict->setfunc == getentry("u")->setfunc)) { + if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) { Py_INCREF(value); return value; } @@ -1543,9 +1543,9 @@ } if (PyString_Check(value) || PyUnicode_Check(value)) { PyCArgObject *parg; - struct fielddesc *fd = getentry("z"); + struct fielddesc *fd = _ctypes_get_fielddesc("z"); - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; parg->pffi_type = &ffi_type_pointer; @@ -1567,7 +1567,7 @@ StgDictObject *dict; assert(dt); /* Cannot be NULL for pointer or array objects */ dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL; - if (dict && (dict->setfunc == getentry("c")->setfunc)) { + if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) { Py_INCREF(value); return value; } @@ -1576,7 +1576,7 @@ /* byref(c_char(...)) */ PyCArgObject *a = (PyCArgObject *)value; StgDictObject *dict = PyObject_stgdict(a->obj); - if (dict && (dict->setfunc == getentry("c")->setfunc)) { + if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) { Py_INCREF(value); return value; } @@ -1612,9 +1612,9 @@ /* int, long */ if (PyInt_Check(value) || PyLong_Check(value)) { PyCArgObject *parg; - struct fielddesc *fd = getentry("P"); + struct fielddesc *fd = _ctypes_get_fielddesc("P"); - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; parg->pffi_type = &ffi_type_pointer; @@ -1629,9 +1629,9 @@ /* string */ if (PyString_Check(value)) { PyCArgObject *parg; - struct fielddesc *fd = getentry("z"); + struct fielddesc *fd = _ctypes_get_fielddesc("z"); - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; parg->pffi_type = &ffi_type_pointer; @@ -1646,9 +1646,9 @@ /* unicode */ if (PyUnicode_Check(value)) { PyCArgObject *parg; - struct fielddesc *fd = getentry("Z"); + struct fielddesc *fd = _ctypes_get_fielddesc("Z"); - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; parg->pffi_type = &ffi_type_pointer; @@ -1682,11 +1682,11 @@ } } /* function pointer */ - if (CFuncPtrObject_Check(value)) { + if (PyCFuncPtrObject_Check(value)) { PyCArgObject *parg; - CFuncPtrObject *func; - func = (CFuncPtrObject *)value; - parg = new_CArgObject(); + PyCFuncPtrObject *func; + func = (PyCFuncPtrObject *)value; + parg = PyCArgObject_new(); if (parg == NULL) return NULL; parg->pffi_type = &ffi_type_pointer; @@ -1704,7 +1704,7 @@ switch (PyString_AS_STRING(stgd->proto)[0]) { case 'z': /* c_char_p */ case 'Z': /* c_wchar_p */ - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; parg->pffi_type = &ffi_type_pointer; @@ -1783,7 +1783,7 @@ return NULL; stgdict = (StgDictObject *)PyObject_CallObject( - (PyObject *)&StgDict_Type, NULL); + (PyObject *)&PyCStgDict_Type, NULL); if (!stgdict) /* XXX leaks result! */ return NULL; @@ -1810,7 +1810,7 @@ } static PyCArgObject * -SimpleType_paramfunc(CDataObject *self) +PyCSimpleType_paramfunc(CDataObject *self) { StgDictObject *dict; char *fmt; @@ -1822,10 +1822,10 @@ fmt = PyString_AsString(dict->proto); assert(fmt); - fd = getentry(fmt); + fd = _ctypes_get_fielddesc(fmt); assert(fd); - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; @@ -1838,7 +1838,7 @@ } static PyObject * -SimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyTypeObject *result; StgDictObject *stgdict; @@ -1884,7 +1884,7 @@ SIMPLE_TYPE_CHARS); goto error; } - fmt = getentry(PyString_AS_STRING(proto)); + fmt = _ctypes_get_fielddesc(PyString_AS_STRING(proto)); if (fmt == NULL) { Py_DECREF(result); PyErr_Format(PyExc_ValueError, @@ -1894,7 +1894,7 @@ } stgdict = (StgDictObject *)PyObject_CallObject( - (PyObject *)&StgDict_Type, NULL); + (PyObject *)&PyCStgDict_Type, NULL); if (!stgdict) return NULL; @@ -1905,9 +1905,9 @@ stgdict->setfunc = fmt->setfunc; stgdict->getfunc = fmt->getfunc; #ifdef WORDS_BIGENDIAN - stgdict->format = alloc_format_string(">", proto_str); + stgdict->format = _ctypes_alloc_format_string(">", proto_str); #else - stgdict->format = alloc_format_string("<", proto_str); + stgdict->format = _ctypes_alloc_format_string("<", proto_str); #endif if (stgdict->format == NULL) { Py_DECREF(result); @@ -1915,7 +1915,7 @@ return NULL; } - stgdict->paramfunc = SimpleType_paramfunc; + stgdict->paramfunc = PyCSimpleType_paramfunc; /* if (result->tp_base != &Simple_Type) { stgdict->setfunc = NULL; @@ -1936,7 +1936,7 @@ result->tp_dict = (PyObject *)stgdict; /* Install from_param class methods in ctypes base classes. - Overrides the SimpleType_from_param generic method. + Overrides the PyCSimpleType_from_param generic method. */ if (result->tp_base == &Simple_Type) { switch (PyString_AS_STRING(proto)[0]) { @@ -1996,7 +1996,7 @@ } } - if (type == &SimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) { + if (type == &PyCSimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) { PyObject *swapped = CreateSwappedType(type, args, kwds, proto, fmt); StgDictObject *sw_dict; @@ -2011,14 +2011,14 @@ PyObject_SetAttrString(swapped, "__ctype_be__", (PyObject *)result); PyObject_SetAttrString(swapped, "__ctype_le__", swapped); /* We are creating the type for the OTHER endian */ - sw_dict->format = alloc_format_string("<", stgdict->format+1); + sw_dict->format = _ctypes_alloc_format_string("<", stgdict->format+1); #else PyObject_SetAttrString((PyObject *)result, "__ctype_be__", swapped); PyObject_SetAttrString((PyObject *)result, "__ctype_le__", (PyObject *)result); PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result); PyObject_SetAttrString(swapped, "__ctype_be__", swapped); /* We are creating the type for the OTHER endian */ - sw_dict->format = alloc_format_string(">", stgdict->format+1); + sw_dict->format = _ctypes_alloc_format_string(">", stgdict->format+1); #endif Py_DECREF(swapped); if (PyErr_Occurred()) { @@ -2035,7 +2035,7 @@ * Convert a parameter into something that ConvParam can handle. */ static PyObject * -SimpleType_from_param(PyObject *type, PyObject *value) +PyCSimpleType_from_param(PyObject *type, PyObject *value) { StgDictObject *dict; char *fmt; @@ -2057,10 +2057,10 @@ fmt = PyString_AsString(dict->proto); assert(fmt); - fd = getentry(fmt); + fd = _ctypes_get_fielddesc(fmt); assert(fd); - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; @@ -2074,7 +2074,7 @@ as_parameter = PyObject_GetAttrString(value, "_as_parameter_"); if (as_parameter) { - value = SimpleType_from_param(type, as_parameter); + value = PyCSimpleType_from_param(type, as_parameter); Py_DECREF(as_parameter); return value; } @@ -2083,8 +2083,8 @@ return NULL; } -static PyMethodDef SimpleType_methods[] = { - { "from_param", SimpleType_from_param, METH_O, from_param_doc }, +static PyMethodDef PyCSimpleType_methods[] = { + { "from_param", PyCSimpleType_from_param, METH_O, from_param_doc }, { "from_address", CDataType_from_address, METH_O, from_address_doc }, { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, }, { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, }, @@ -2092,9 +2092,9 @@ { NULL, NULL }, }; -PyTypeObject SimpleType_Type = { +PyTypeObject PyCSimpleType_Type = { PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.SimpleType", /* tp_name */ + "_ctypes.PyCSimpleType", /* tp_name */ 0, /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ @@ -2113,14 +2113,14 @@ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "metatype for the SimpleType Objects", /* tp_doc */ + "metatype for the PyCSimpleType Objects", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - SimpleType_methods, /* tp_methods */ + PyCSimpleType_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ @@ -2130,13 +2130,13 @@ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - SimpleType_new, /* tp_new */ + PyCSimpleType_new, /* tp_new */ 0, /* tp_free */ }; /******************************************************************/ /* - CFuncPtrType_Type + PyCFuncPtrType_Type */ static PyObject * @@ -2192,7 +2192,7 @@ PyObject *ob; PyObject *converters = NULL; - stgdict->align = getentry("P")->pffi_type->alignment; + stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment; stgdict->length = 1; stgdict->size = sizeof(void *); stgdict->setfunc = NULL; @@ -2252,11 +2252,11 @@ } static PyCArgObject * -CFuncPtrType_paramfunc(CDataObject *self) +PyCFuncPtrType_paramfunc(CDataObject *self) { PyCArgObject *parg; - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; @@ -2269,24 +2269,24 @@ } static PyObject * -CFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +PyCFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyTypeObject *result; StgDictObject *stgdict; stgdict = (StgDictObject *)PyObject_CallObject( - (PyObject *)&StgDict_Type, NULL); + (PyObject *)&PyCStgDict_Type, NULL); if (!stgdict) return NULL; - stgdict->paramfunc = CFuncPtrType_paramfunc; + stgdict->paramfunc = PyCFuncPtrType_paramfunc; /* We do NOT expose the function signature in the format string. It is impossible, generally, because the only requirement for the argtypes items is that they have a .from_param method - we do not know the types of the arguments (although, in practice, most argtypes would be a ctypes type). */ - stgdict->format = alloc_format_string(NULL, "X{}"); + stgdict->format = _ctypes_alloc_format_string(NULL, "X{}"); stgdict->flags |= TYPEFLAG_ISPOINTER; /* create the new instance (which is a class, @@ -2314,9 +2314,9 @@ return (PyObject *)result; } -PyTypeObject CFuncPtrType_Type = { +PyTypeObject PyCFuncPtrType_Type = { PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.CFuncPtrType", /* tp_name */ + "_ctypes.PyCFuncPtrType", /* tp_name */ 0, /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ @@ -2352,7 +2352,7 @@ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - CFuncPtrType_new, /* tp_new */ + PyCFuncPtrType_new, /* tp_new */ 0, /* tp_free */ }; @@ -2362,7 +2362,7 @@ */ static CDataObject * -CData_GetContainer(CDataObject *self) +PyCData_GetContainer(CDataObject *self) { while (self->b_base) self = self->b_base; @@ -2380,7 +2380,7 @@ static PyObject * GetKeepedObjects(CDataObject *target) { - return CData_GetContainer(target)->b_objects; + return PyCData_GetContainer(target)->b_objects; } static PyObject * @@ -2444,7 +2444,7 @@ Py_DECREF(Py_None); return 0; } - ob = CData_GetContainer(target); + ob = PyCData_GetContainer(target); if (ob->b_objects == NULL || !PyDict_CheckExact(ob->b_objects)) { Py_XDECREF(ob->b_objects); ob->b_objects = keep; /* refcount consumed */ @@ -2463,10 +2463,10 @@ /******************************************************************/ /* - CData_Type + PyCData_Type */ static int -CData_traverse(CDataObject *self, visitproc visit, void *arg) +PyCData_traverse(CDataObject *self, visitproc visit, void *arg) { Py_VISIT(self->b_objects); Py_VISIT((PyObject *)self->b_base); @@ -2474,7 +2474,7 @@ } static int -CData_clear(CDataObject *self) +PyCData_clear(CDataObject *self) { StgDictObject *dict = PyObject_stgdict((PyObject *)self); assert(dict); /* Cannot be NULL for CDataObject instances */ @@ -2488,13 +2488,13 @@ } static void -CData_dealloc(PyObject *self) +PyCData_dealloc(PyObject *self) { - CData_clear((CDataObject *)self); + PyCData_clear((CDataObject *)self); Py_TYPE(self)->tp_free(self); } -static PyMemberDef CData_members[] = { +static PyMemberDef PyCData_members[] = { { "_b_base_", T_OBJECT, offsetof(CDataObject, b_base), READONLY, "the base object" }, @@ -2508,7 +2508,7 @@ }; #if (PY_VERSION_HEX >= 0x02060000) -static int CData_NewGetBuffer(PyObject *_self, Py_buffer *view, int flags) +static int PyCData_NewGetBuffer(PyObject *_self, Py_buffer *view, int flags) { CDataObject *self = (CDataObject *)_self; StgDictObject *dict = PyObject_stgdict(_self); @@ -2536,14 +2536,14 @@ } #endif -static Py_ssize_t CData_GetSegcount(PyObject *_self, Py_ssize_t *lenp) +static Py_ssize_t PyCData_GetSegcount(PyObject *_self, Py_ssize_t *lenp) { if (lenp) *lenp = 1; return 1; } -static Py_ssize_t CData_GetBuffer(PyObject *_self, Py_ssize_t seg, void **pptr) +static Py_ssize_t PyCData_GetBuffer(PyObject *_self, Py_ssize_t seg, void **pptr) { CDataObject *self = (CDataObject *)_self; if (seg != 0) { @@ -2554,13 +2554,13 @@ return self->b_size; } -static PyBufferProcs CData_as_buffer = { - (readbufferproc)CData_GetBuffer, - (writebufferproc)CData_GetBuffer, - (segcountproc)CData_GetSegcount, +static PyBufferProcs PyCData_as_buffer = { + (readbufferproc)PyCData_GetBuffer, + (writebufferproc)PyCData_GetBuffer, + (segcountproc)PyCData_GetSegcount, (charbufferproc)NULL, #if (PY_VERSION_HEX >= 0x02060000) - (getbufferproc)CData_NewGetBuffer, + (getbufferproc)PyCData_NewGetBuffer, (releasebufferproc)NULL, #endif }; @@ -2569,14 +2569,14 @@ * CData objects are mutable, so they cannot be hashable! */ static long -CData_nohash(PyObject *self) +PyCData_nohash(PyObject *self) { PyErr_SetString(PyExc_TypeError, "unhashable type"); return -1; } static PyObject * -CData_reduce(PyObject *_self, PyObject *args) +PyCData_reduce(PyObject *_self, PyObject *args) { CDataObject *self = (CDataObject *)_self; @@ -2593,7 +2593,7 @@ } static PyObject * -CData_setstate(PyObject *_self, PyObject *args) +PyCData_setstate(PyObject *_self, PyObject *args) { void *data; Py_ssize_t len; @@ -2618,25 +2618,25 @@ * default __ctypes_from_outparam__ method returns self. */ static PyObject * -CData_from_outparam(PyObject *self, PyObject *args) +PyCData_from_outparam(PyObject *self, PyObject *args) { Py_INCREF(self); return self; } -static PyMethodDef CData_methods[] = { - { "__ctypes_from_outparam__", CData_from_outparam, METH_NOARGS, }, - { "__reduce__", CData_reduce, METH_NOARGS, }, - { "__setstate__", CData_setstate, METH_VARARGS, }, +static PyMethodDef PyCData_methods[] = { + { "__ctypes_from_outparam__", PyCData_from_outparam, METH_NOARGS, }, + { "__reduce__", PyCData_reduce, METH_NOARGS, }, + { "__setstate__", PyCData_setstate, METH_VARARGS, }, { NULL, NULL }, }; -PyTypeObject CData_Type = { +PyTypeObject PyCData_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_ctypes._CData", sizeof(CDataObject), /* tp_basicsize */ 0, /* tp_itemsize */ - CData_dealloc, /* tp_dealloc */ + PyCData_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -2645,22 +2645,22 @@ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ - CData_nohash, /* tp_hash */ + PyCData_nohash, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ - &CData_as_buffer, /* tp_as_buffer */ + &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */ "XXX to be provided", /* tp_doc */ - (traverseproc)CData_traverse, /* tp_traverse */ - (inquiry)CData_clear, /* tp_clear */ + (traverseproc)PyCData_traverse, /* tp_traverse */ + (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - CData_methods, /* tp_methods */ - CData_members, /* tp_members */ + PyCData_methods, /* tp_methods */ + PyCData_members, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ @@ -2673,7 +2673,7 @@ 0, /* tp_free */ }; -static int CData_MallocBuffer(CDataObject *obj, StgDictObject *dict) +static int PyCData_MallocBuffer(CDataObject *obj, StgDictObject *dict) { if ((size_t)dict->size <= sizeof(obj->b_value)) { /* No need to call malloc, can use the default buffer */ @@ -2702,7 +2702,7 @@ } PyObject * -CData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr) +PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr) { CDataObject *cmem; StgDictObject *dict; @@ -2730,7 +2730,7 @@ cmem->b_base = (CDataObject *)base; cmem->b_index = index; } else { /* copy contents of adr */ - if (-1 == CData_MallocBuffer(cmem, dict)) { + if (-1 == PyCData_MallocBuffer(cmem, dict)) { return NULL; Py_DECREF(cmem); } @@ -2744,7 +2744,7 @@ Box a memory block into a CData instance. */ PyObject * -CData_AtAddress(PyObject *type, void *buf) +PyCData_AtAddress(PyObject *type, void *buf) { CDataObject *pd; StgDictObject *dict; @@ -2773,17 +2773,17 @@ classes. FALSE otherwise FALSE also for subclasses of c_int and such. */ -int IsSimpleSubType(PyObject *obj) +int _ctypes_simple_instance(PyObject *obj) { PyTypeObject *type = (PyTypeObject *)obj; - if (SimpleTypeObject_Check(type)) + if (PyCSimpleTypeObject_Check(type)) return type->tp_base != &Simple_Type; return 0; } PyObject * -CData_get(PyObject *type, GETFUNC getfunc, PyObject *src, +PyCData_get(PyObject *type, GETFUNC getfunc, PyObject *src, Py_ssize_t index, Py_ssize_t size, char *adr) { StgDictObject *dict; @@ -2791,16 +2791,16 @@ return getfunc(adr, size); assert(type); dict = PyType_stgdict(type); - if (dict && dict->getfunc && !IsSimpleSubType(type)) + if (dict && dict->getfunc && !_ctypes_simple_instance(type)) return dict->getfunc(adr, size); - return CData_FromBaseObj(type, src, index, adr); + return PyCData_FromBaseObj(type, src, index, adr); } /* - Helper function for CData_set below. + Helper function for PyCData_set below. */ static PyObject * -_CData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, +_PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, Py_ssize_t size, char *ptr) { CDataObject *src; @@ -2822,15 +2822,15 @@ PyObject *result; ob = PyObject_CallObject(type, value); if (ob == NULL) { - Extend_Error_Info(PyExc_RuntimeError, "(%s) ", + _ctypes_extend_error(PyExc_RuntimeError, "(%s) ", ((PyTypeObject *)type)->tp_name); return NULL; } - result = _CData_set(dst, type, setfunc, ob, + result = _PyCData_set(dst, type, setfunc, ob, size, ptr); Py_DECREF(ob); return result; - } else if (value == Py_None && PointerTypeObject_Check(type)) { + } else if (value == Py_None && PyCPointerTypeObject_Check(type)) { *(void **)ptr = NULL; Py_INCREF(Py_None); return Py_None; @@ -2849,7 +2849,7 @@ src->b_ptr, size); - if (PointerTypeObject_Check(type)) + if (PyCPointerTypeObject_Check(type)) /* XXX */; value = GetKeepedObjects(src); @@ -2857,7 +2857,7 @@ return value; } - if (PointerTypeObject_Check(type) + if (PyCPointerTypeObject_Check(type) && ArrayObject_Check(value)) { StgDictObject *p1, *p2; PyObject *keep; @@ -2898,7 +2898,7 @@ * to the value 'value'. */ int -CData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, +PyCData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, Py_ssize_t index, Py_ssize_t size, char *ptr) { CDataObject *mem = (CDataObject *)dst; @@ -2910,7 +2910,7 @@ return -1; } - result = _CData_set(mem, type, setfunc, value, + result = _PyCData_set(mem, type, setfunc, value, size, ptr); if (result == NULL) return -1; @@ -2924,7 +2924,7 @@ /******************************************************************/ static PyObject * -GenericCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { CDataObject *obj; StgDictObject *dict; @@ -2946,7 +2946,7 @@ obj->b_objects = NULL; obj->b_length = dict->length; - if (-1 == CData_MallocBuffer(obj, dict)) { + if (-1 == PyCData_MallocBuffer(obj, dict)) { Py_DECREF(obj); return NULL; } @@ -2954,11 +2954,11 @@ } /*****************************************************************/ /* - CFuncPtr_Type + PyCFuncPtr_Type */ static int -CFuncPtr_set_errcheck(CFuncPtrObject *self, PyObject *ob) +PyCFuncPtr_set_errcheck(PyCFuncPtrObject *self, PyObject *ob) { if (ob && !PyCallable_Check(ob)) { PyErr_SetString(PyExc_TypeError, @@ -2972,7 +2972,7 @@ } static PyObject * -CFuncPtr_get_errcheck(CFuncPtrObject *self) +PyCFuncPtr_get_errcheck(PyCFuncPtrObject *self) { if (self->errcheck) { Py_INCREF(self->errcheck); @@ -2983,7 +2983,7 @@ } static int -CFuncPtr_set_restype(CFuncPtrObject *self, PyObject *ob) +PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob) { if (ob == NULL) { Py_XDECREF(self->restype); @@ -3008,7 +3008,7 @@ } static PyObject * -CFuncPtr_get_restype(CFuncPtrObject *self) +PyCFuncPtr_get_restype(PyCFuncPtrObject *self) { StgDictObject *dict; if (self->restype) { @@ -3016,7 +3016,7 @@ return self->restype; } dict = PyObject_stgdict((PyObject *)self); - assert(dict); /* Cannot be NULL for CFuncPtrObject instances */ + assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */ if (dict->restype) { Py_INCREF(dict->restype); return dict->restype; @@ -3027,7 +3027,7 @@ } static int -CFuncPtr_set_argtypes(CFuncPtrObject *self, PyObject *ob) +PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob) { PyObject *converters; @@ -3050,7 +3050,7 @@ } static PyObject * -CFuncPtr_get_argtypes(CFuncPtrObject *self) +PyCFuncPtr_get_argtypes(PyCFuncPtrObject *self) { StgDictObject *dict; if (self->argtypes) { @@ -3058,7 +3058,7 @@ return self->argtypes; } dict = PyObject_stgdict((PyObject *)self); - assert(dict); /* Cannot be NULL for CFuncPtrObject instances */ + assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */ if (dict->argtypes) { Py_INCREF(dict->argtypes); return dict->argtypes; @@ -3068,13 +3068,13 @@ } } -static PyGetSetDef CFuncPtr_getsets[] = { - { "errcheck", (getter)CFuncPtr_get_errcheck, (setter)CFuncPtr_set_errcheck, +static PyGetSetDef PyCFuncPtr_getsets[] = { + { "errcheck", (getter)PyCFuncPtr_get_errcheck, (setter)PyCFuncPtr_set_errcheck, "a function to check for errors", NULL }, - { "restype", (getter)CFuncPtr_get_restype, (setter)CFuncPtr_set_restype, + { "restype", (getter)PyCFuncPtr_get_restype, (setter)PyCFuncPtr_set_restype, "specify the result type", NULL }, - { "argtypes", (getter)CFuncPtr_get_argtypes, - (setter)CFuncPtr_set_argtypes, + { "argtypes", (getter)PyCFuncPtr_get_argtypes, + (setter)PyCFuncPtr_set_argtypes, "specify the argument types", NULL }, { NULL, NULL } }; @@ -3129,10 +3129,10 @@ { StgDictObject *dict; - if (PointerTypeObject_Check(arg)) + if (PyCPointerTypeObject_Check(arg)) return 1; - if (ArrayTypeObject_Check(arg)) + if (PyCArrayTypeObject_Check(arg)) return 1; dict = PyType_stgdict(arg); @@ -3162,7 +3162,7 @@ PyObject *argtypes; dict = PyType_stgdict((PyObject *)type); - assert(dict); /* Cannot be NULL. 'type' is a CFuncPtr type. */ + assert(dict); /* Cannot be NULL. 'type' is a PyCFuncPtr type. */ argtypes = dict->argtypes; if (paramflags == NULL || dict->argtypes == NULL) @@ -3236,13 +3236,13 @@ static PyObject * -CFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds) +PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds) { char *name; int (* address)(void); PyObject *dll; PyObject *obj; - CFuncPtrObject *self; + PyCFuncPtrObject *self; void *handle; PyObject *paramflags = NULL; @@ -3298,7 +3298,7 @@ if (!_validate_paramflags(type, paramflags)) return NULL; - self = (CFuncPtrObject *)GenericCData_new(type, args, kwds); + self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds); if (!self) return NULL; @@ -3320,9 +3320,9 @@ #ifdef MS_WIN32 static PyObject * -CFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds) +PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds) { - CFuncPtrObject *self; + PyCFuncPtrObject *self; int index; char *name = NULL; PyObject *paramflags = NULL; @@ -3337,7 +3337,7 @@ if (!_validate_paramflags(type, paramflags)) return NULL; - self = (CFuncPtrObject *)GenericCData_new(type, args, kwds); + self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds); self->index = index + 0x1000; Py_XINCREF(paramflags); self->paramflags = paramflags; @@ -3348,7 +3348,7 @@ #endif /* - CFuncPtr_new accepts different argument lists in addition to the standard + PyCFuncPtr_new accepts different argument lists in addition to the standard _basespec_ keyword arg: one argument form @@ -3361,22 +3361,22 @@ "is|..." - vtable index, method name, creates callable calling COM vtbl */ static PyObject * -CFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - CFuncPtrObject *self; + PyCFuncPtrObject *self; PyObject *callable; StgDictObject *dict; CThunkObject *thunk; if (PyTuple_GET_SIZE(args) == 0) - return GenericCData_new(type, args, kwds); + return GenericPyCData_new(type, args, kwds); if (1 <= PyTuple_GET_SIZE(args) && PyTuple_Check(PyTuple_GET_ITEM(args, 0))) - return CFuncPtr_FromDll(type, args, kwds); + return PyCFuncPtr_FromDll(type, args, kwds); #ifdef MS_WIN32 if (2 <= PyTuple_GET_SIZE(args) && PyInt_Check(PyTuple_GET_ITEM(args, 0))) - return CFuncPtr_FromVtblIndex(type, args, kwds); + return PyCFuncPtr_FromVtblIndex(type, args, kwds); #endif if (1 == PyTuple_GET_SIZE(args) @@ -3386,7 +3386,7 @@ void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0)); if (ptr == NULL && PyErr_Occurred()) return NULL; - ob = (CDataObject *)GenericCData_new(type, args, kwds); + ob = (CDataObject *)GenericPyCData_new(type, args, kwds); if (ob == NULL) return NULL; *(void **)ob->b_ptr = ptr; @@ -3415,7 +3415,7 @@ */ dict = PyType_stgdict((PyObject *)type); - /* XXXX Fails if we do: 'CFuncPtr(lambda x: x)' */ + /* XXXX Fails if we do: 'PyCFuncPtr(lambda x: x)' */ if (!dict || !dict->argtypes) { PyErr_SetString(PyExc_TypeError, "cannot construct instance of this class:" @@ -3423,14 +3423,14 @@ return NULL; } - thunk = AllocFunctionCallback(callable, + thunk = _ctypes_alloc_callback(callable, dict->argtypes, dict->restype, dict->flags); if (!thunk) return NULL; - self = (CFuncPtrObject *)GenericCData_new(type, args, kwds); + self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds); if (self == NULL) { Py_DECREF(thunk); return NULL; @@ -3464,7 +3464,7 @@ return NULL; } - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) { Py_DECREF(obj); return NULL; @@ -3526,7 +3526,7 @@ function. */ static PyObject * -_build_callargs(CFuncPtrObject *self, PyObject *argtypes, +_build_callargs(PyCFuncPtrObject *self, PyObject *argtypes, PyObject *inargs, PyObject *kwds, int *poutmask, int *pinoutmask, unsigned int *pnumretvals) { @@ -3638,7 +3638,7 @@ ((PyTypeObject *)ob)->tp_name); goto error; } - if (ArrayTypeObject_Check(ob)) + if (PyCArrayTypeObject_Check(ob)) ob = PyObject_CallObject(ob, NULL); else /* Create an instance of the pointed-to type */ @@ -3758,7 +3758,7 @@ } static PyObject * -CFuncPtr_call(CFuncPtrObject *self, PyObject *inargs, PyObject *kwds) +PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds) { PyObject *restype; PyObject *converters; @@ -3777,7 +3777,7 @@ int outmask; unsigned int numretvals; - assert(dict); /* Cannot be NULL for CFuncPtrObject instances */ + assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */ restype = self->restype ? self->restype : dict->restype; converters = self->converters ? self->converters : dict->converters; checker = self->checker ? self->checker : dict->checker; @@ -3854,7 +3854,7 @@ } } - result = _CallProc(pProc, + result = _ctypes_callproc(pProc, callargs, #ifdef MS_WIN32 piunk, @@ -3890,7 +3890,7 @@ } static int -CFuncPtr_traverse(CFuncPtrObject *self, visitproc visit, void *arg) +PyCFuncPtr_traverse(PyCFuncPtrObject *self, visitproc visit, void *arg) { Py_VISIT(self->callable); Py_VISIT(self->restype); @@ -3900,11 +3900,11 @@ Py_VISIT(self->converters); Py_VISIT(self->paramflags); Py_VISIT(self->thunk); - return CData_traverse((CDataObject *)self, visit, arg); + return PyCData_traverse((CDataObject *)self, visit, arg); } static int -CFuncPtr_clear(CFuncPtrObject *self) +PyCFuncPtr_clear(PyCFuncPtrObject *self) { Py_CLEAR(self->callable); Py_CLEAR(self->restype); @@ -3914,18 +3914,18 @@ Py_CLEAR(self->converters); Py_CLEAR(self->paramflags); Py_CLEAR(self->thunk); - return CData_clear((CDataObject *)self); + return PyCData_clear((CDataObject *)self); } static void -CFuncPtr_dealloc(CFuncPtrObject *self) +PyCFuncPtr_dealloc(PyCFuncPtrObject *self) { - CFuncPtr_clear(self); + PyCFuncPtr_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static PyObject * -CFuncPtr_repr(CFuncPtrObject *self) +PyCFuncPtr_repr(PyCFuncPtrObject *self) { #ifdef MS_WIN32 if (self->index) @@ -3940,7 +3940,7 @@ } static int -CFuncPtr_nonzero(CFuncPtrObject *self) +PyCFuncPtr_nonzero(PyCFuncPtrObject *self) { return ((*(void **)self->b_ptr != NULL) #ifdef MS_WIN32 @@ -3949,7 +3949,7 @@ ); } -static PyNumberMethods CFuncPtr_as_number = { +static PyNumberMethods PyCFuncPtr_as_number = { 0, /* nb_add */ 0, /* nb_subtract */ 0, /* nb_multiply */ @@ -3960,40 +3960,40 @@ 0, /* nb_negative */ 0, /* nb_positive */ 0, /* nb_absolute */ - (inquiry)CFuncPtr_nonzero, /* nb_nonzero */ + (inquiry)PyCFuncPtr_nonzero, /* nb_nonzero */ }; -PyTypeObject CFuncPtr_Type = { +PyTypeObject PyCFuncPtr_Type = { PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.CFuncPtr", - sizeof(CFuncPtrObject), /* tp_basicsize */ + "_ctypes.PyCFuncPtr", + sizeof(PyCFuncPtrObject), /* tp_basicsize */ 0, /* tp_itemsize */ - (destructor)CFuncPtr_dealloc, /* tp_dealloc */ + (destructor)PyCFuncPtr_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ - (reprfunc)CFuncPtr_repr, /* tp_repr */ - &CFuncPtr_as_number, /* tp_as_number */ + (reprfunc)PyCFuncPtr_repr, /* tp_repr */ + &PyCFuncPtr_as_number, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ - (ternaryfunc)CFuncPtr_call, /* tp_call */ + (ternaryfunc)PyCFuncPtr_call, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ - &CData_as_buffer, /* tp_as_buffer */ + &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */ "Function Pointer", /* tp_doc */ - (traverseproc)CFuncPtr_traverse, /* tp_traverse */ - (inquiry)CFuncPtr_clear, /* tp_clear */ + (traverseproc)PyCFuncPtr_traverse, /* tp_traverse */ + (inquiry)PyCFuncPtr_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ - CFuncPtr_getsets, /* tp_getset */ + PyCFuncPtr_getsets, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ @@ -4001,7 +4001,7 @@ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - CFuncPtr_new, /* tp_new */ + PyCFuncPtr_new, /* tp_new */ 0, /* tp_free */ }; @@ -4125,11 +4125,11 @@ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ - &CData_as_buffer, /* tp_as_buffer */ + &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */ "Structure base class", /* tp_doc */ - (traverseproc)CData_traverse, /* tp_traverse */ - (inquiry)CData_clear, /* tp_clear */ + (traverseproc)PyCData_traverse, /* tp_traverse */ + (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ @@ -4144,7 +4144,7 @@ 0, /* tp_dictoffset */ Struct_init, /* tp_init */ 0, /* tp_alloc */ - GenericCData_new, /* tp_new */ + GenericPyCData_new, /* tp_new */ 0, /* tp_free */ }; @@ -4167,11 +4167,11 @@ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ - &CData_as_buffer, /* tp_as_buffer */ + &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */ "Union base class", /* tp_doc */ - (traverseproc)CData_traverse, /* tp_traverse */ - (inquiry)CData_clear, /* tp_clear */ + (traverseproc)PyCData_traverse, /* tp_traverse */ + (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ @@ -4186,14 +4186,14 @@ 0, /* tp_dictoffset */ Struct_init, /* tp_init */ 0, /* tp_alloc */ - GenericCData_new, /* tp_new */ + GenericPyCData_new, /* tp_new */ 0, /* tp_free */ }; /******************************************************************/ /* - Array_Type + PyCArray_Type */ static int Array_init(CDataObject *self, PyObject *args, PyObject *kw) @@ -4238,7 +4238,7 @@ size = stgdict->size / stgdict->length; offset = index * size; - return CData_get(stgdict->proto, stgdict->getfunc, (PyObject *)self, + return PyCData_get(stgdict->proto, stgdict->getfunc, (PyObject *)self, index, size, self->b_ptr + offset); } @@ -4267,11 +4267,11 @@ itemdict = PyType_stgdict(proto); assert(itemdict); /* proto is the item type of the array, a ctypes type, so this cannot be NULL */ - if (itemdict->getfunc == getentry("c")->getfunc) { + if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) { char *ptr = (char *)self->b_ptr; return PyString_FromStringAndSize(ptr + ilow, len); #ifdef CTYPES_UNICODE - } else if (itemdict->getfunc == getentry("u")->getfunc) { + } else if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { wchar_t *ptr = (wchar_t *)self->b_ptr; return PyUnicode_FromWideChar(ptr + ilow, len); #endif @@ -4321,7 +4321,7 @@ assert(itemdict); /* proto is the item type of the array, a ctypes type, so this cannot be NULL */ - if (itemdict->getfunc == getentry("c")->getfunc) { + if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) { char *ptr = (char *)self->b_ptr; char *dest; @@ -4346,7 +4346,7 @@ return np; } #ifdef CTYPES_UNICODE - if (itemdict->getfunc == getentry("u")->getfunc) { + if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { wchar_t *ptr = (wchar_t *)self->b_ptr; wchar_t *dest; @@ -4415,7 +4415,7 @@ offset = index * size; ptr = self->b_ptr + offset; - return CData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value, + return PyCData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value, index, size, ptr); } @@ -4545,7 +4545,7 @@ Array_ass_subscript, }; -PyTypeObject Array_Type = { +PyTypeObject PyCArray_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_ctypes.Array", sizeof(CDataObject), /* tp_basicsize */ @@ -4564,11 +4564,11 @@ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ - &CData_as_buffer, /* tp_as_buffer */ + &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */ "XXX to be provided", /* tp_doc */ - (traverseproc)CData_traverse, /* tp_traverse */ - (inquiry)CData_clear, /* tp_clear */ + (traverseproc)PyCData_traverse, /* tp_traverse */ + (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ @@ -4583,12 +4583,12 @@ 0, /* tp_dictoffset */ (initproc)Array_init, /* tp_init */ 0, /* tp_alloc */ - GenericCData_new, /* tp_new */ + GenericPyCData_new, /* tp_new */ 0, /* tp_free */ }; PyObject * -CreateArrayType(PyObject *itemtype, Py_ssize_t length) +PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length) { static PyObject *cache; PyObject *key; @@ -4628,14 +4628,14 @@ ((PyTypeObject *)itemtype)->tp_name, (long)length); #endif - result = PyObject_CallFunction((PyObject *)&ArrayType_Type, + result = PyObject_CallFunction((PyObject *)&PyCArrayType_Type, #if (PY_VERSION_HEX < 0x02050000) "s(O){s:i,s:O}", #else "s(O){s:n,s:O}", #endif name, - &Array_Type, + &PyCArray_Type, "_length_", length, "_type_", @@ -4711,7 +4711,7 @@ static PyObject * Simple_from_outparm(PyObject *self, PyObject *args) { - if (IsSimpleSubType((PyObject *)Py_TYPE(self))) { + if (_ctypes_simple_instance((PyObject *)Py_TYPE(self))) { Py_INCREF(self); return self; } @@ -4801,11 +4801,11 @@ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ - &CData_as_buffer, /* tp_as_buffer */ + &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */ "XXX to be provided", /* tp_doc */ - (traverseproc)CData_traverse, /* tp_traverse */ - (inquiry)CData_clear, /* tp_clear */ + (traverseproc)PyCData_traverse, /* tp_traverse */ + (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ @@ -4820,13 +4820,13 @@ 0, /* tp_dictoffset */ (initproc)Simple_init, /* tp_init */ 0, /* tp_alloc */ - GenericCData_new, /* tp_new */ + GenericPyCData_new, /* tp_new */ 0, /* tp_free */ }; /******************************************************************/ /* - Pointer_Type + PyCPointer_Type */ static PyObject * Pointer_item(PyObject *_self, Py_ssize_t index) @@ -4855,7 +4855,7 @@ size = itemdict->size; offset = index * itemdict->size; - return CData_get(proto, stgdict->getfunc, (PyObject *)self, + return PyCData_get(proto, stgdict->getfunc, (PyObject *)self, index, size, (*(char **)self->b_ptr) + offset); } @@ -4893,7 +4893,7 @@ size = itemdict->size; offset = index * itemdict->size; - return CData_set((PyObject *)self, proto, stgdict->setfunc, value, + return PyCData_set((PyObject *)self, proto, stgdict->setfunc, value, index, size, (*(char **)self->b_ptr) + offset); } @@ -4910,7 +4910,7 @@ stgdict = PyObject_stgdict((PyObject *)self); assert(stgdict); /* Cannot be NULL fr pointer instances */ - return CData_FromBaseObj(stgdict->proto, + return PyCData_FromBaseObj(stgdict->proto, (PyObject *)self, 0, *(void **)self->b_ptr); } @@ -4985,7 +4985,7 @@ "Cannot create instance: has no _type_"); return NULL; } - return GenericCData_new(type, args, kw); + return GenericPyCData_new(type, args, kw); } static PyObject * @@ -5009,11 +5009,11 @@ assert(proto); itemdict = PyType_stgdict(proto); assert(itemdict); - if (itemdict->getfunc == getentry("c")->getfunc) { + if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) { char *ptr = *(char **)self->b_ptr; return PyString_FromStringAndSize(ptr + ilow, len); #ifdef CTYPES_UNICODE - } else if (itemdict->getfunc == getentry("u")->getfunc) { + } else if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { wchar_t *ptr = *(wchar_t **)self->b_ptr; return PyUnicode_FromWideChar(ptr + ilow, len); #endif @@ -5103,7 +5103,7 @@ assert(proto); itemdict = PyType_stgdict(proto); assert(itemdict); - if (itemdict->getfunc == getentry("c")->getfunc) { + if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) { char *ptr = *(char **)self->b_ptr; char *dest; @@ -5124,7 +5124,7 @@ return np; } #ifdef CTYPES_UNICODE - if (itemdict->getfunc == getentry("u")->getfunc) { + if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { wchar_t *ptr = *(wchar_t **)self->b_ptr; wchar_t *dest; @@ -5202,7 +5202,7 @@ (inquiry)Pointer_nonzero, /* nb_nonzero */ }; -PyTypeObject Pointer_Type = { +PyTypeObject PyCPointer_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_ctypes._Pointer", sizeof(CDataObject), /* tp_basicsize */ @@ -5221,11 +5221,11 @@ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ - &CData_as_buffer, /* tp_as_buffer */ + &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */ "XXX to be provided", /* tp_doc */ - (traverseproc)CData_traverse, /* tp_traverse */ - (inquiry)CData_clear, /* tp_clear */ + (traverseproc)PyCData_traverse, /* tp_traverse */ + (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ @@ -5354,9 +5354,9 @@ { StgDictObject *dict; - if (PointerTypeObject_Check(arg)) + if (PyCPointerTypeObject_Check(arg)) return 1; - if (CFuncPtrTypeObject_Check(arg)) + if (PyCFuncPtrTypeObject_Check(arg)) return 1; dict = PyType_stgdict(arg); if (dict) { @@ -5392,9 +5392,9 @@ */ if (CDataObject_Check(src)) { CDataObject *obj = (CDataObject *)src; - /* CData_GetContainer will initialize src.b_objects, we need + /* PyCData_GetContainer will initialize src.b_objects, we need this so it can be shared */ - CData_GetContainer(obj); + PyCData_GetContainer(obj); /* But we need a dictionary! */ if (obj->b_objects == Py_None) { Py_DECREF(Py_None); @@ -5448,15 +5448,15 @@ #ifdef WITH_THREAD PyEval_InitThreads(); #endif - m = Py_InitModule3("_ctypes", module_methods, module_docs); + m = Py_InitModule3("_ctypes", _ctypes_module_methods, module_docs); if (!m) return; - _pointer_type_cache = PyDict_New(); - if (_pointer_type_cache == NULL) + _ctypes_ptrtype_cache = PyDict_New(); + if (_ctypes_ptrtype_cache == NULL) return; - PyModule_AddObject(m, "_pointer_type_cache", (PyObject *)_pointer_type_cache); + PyModule_AddObject(m, "_pointer_type_cache", (PyObject *)_ctypes_ptrtype_cache); _unpickle = PyObject_GetAttrString(m, "_unpickle"); if (_unpickle == NULL) @@ -5465,12 +5465,12 @@ if (PyType_Ready(&PyCArg_Type) < 0) return; - if (PyType_Ready(&CThunk_Type) < 0) + if (PyType_Ready(&PyCThunk_Type) < 0) return; /* StgDict is derived from PyDict_Type */ - StgDict_Type.tp_base = &PyDict_Type; - if (PyType_Ready(&StgDict_Type) < 0) + PyCStgDict_Type.tp_base = &PyDict_Type; + if (PyType_Ready(&PyCStgDict_Type) < 0) return; /************************************************* @@ -5478,28 +5478,28 @@ * Metaclasses */ - StructType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&StructType_Type) < 0) + PyCStructType_Type.tp_base = &PyType_Type; + if (PyType_Ready(&PyCStructType_Type) < 0) return; UnionType_Type.tp_base = &PyType_Type; if (PyType_Ready(&UnionType_Type) < 0) return; - PointerType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&PointerType_Type) < 0) + PyCPointerType_Type.tp_base = &PyType_Type; + if (PyType_Ready(&PyCPointerType_Type) < 0) return; - ArrayType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&ArrayType_Type) < 0) + PyCArrayType_Type.tp_base = &PyType_Type; + if (PyType_Ready(&PyCArrayType_Type) < 0) return; - SimpleType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&SimpleType_Type) < 0) + PyCSimpleType_Type.tp_base = &PyType_Type; + if (PyType_Ready(&PyCSimpleType_Type) < 0) return; - CFuncPtrType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&CFuncPtrType_Type) < 0) + PyCFuncPtrType_Type.tp_base = &PyType_Type; + if (PyType_Ready(&PyCFuncPtrType_Type) < 0) return; /************************************************* @@ -5507,52 +5507,52 @@ * Classes using a custom metaclass */ - if (PyType_Ready(&CData_Type) < 0) + if (PyType_Ready(&PyCData_Type) < 0) return; - Py_TYPE(&Struct_Type) = &StructType_Type; - Struct_Type.tp_base = &CData_Type; + Py_TYPE(&Struct_Type) = &PyCStructType_Type; + Struct_Type.tp_base = &PyCData_Type; if (PyType_Ready(&Struct_Type) < 0) return; PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type); Py_TYPE(&Union_Type) = &UnionType_Type; - Union_Type.tp_base = &CData_Type; + Union_Type.tp_base = &PyCData_Type; if (PyType_Ready(&Union_Type) < 0) return; PyModule_AddObject(m, "Union", (PyObject *)&Union_Type); - Py_TYPE(&Pointer_Type) = &PointerType_Type; - Pointer_Type.tp_base = &CData_Type; - if (PyType_Ready(&Pointer_Type) < 0) + Py_TYPE(&PyCPointer_Type) = &PyCPointerType_Type; + PyCPointer_Type.tp_base = &PyCData_Type; + if (PyType_Ready(&PyCPointer_Type) < 0) return; - PyModule_AddObject(m, "_Pointer", (PyObject *)&Pointer_Type); + PyModule_AddObject(m, "_Pointer", (PyObject *)&PyCPointer_Type); - Py_TYPE(&Array_Type) = &ArrayType_Type; - Array_Type.tp_base = &CData_Type; - if (PyType_Ready(&Array_Type) < 0) + Py_TYPE(&PyCArray_Type) = &PyCArrayType_Type; + PyCArray_Type.tp_base = &PyCData_Type; + if (PyType_Ready(&PyCArray_Type) < 0) return; - PyModule_AddObject(m, "Array", (PyObject *)&Array_Type); + PyModule_AddObject(m, "Array", (PyObject *)&PyCArray_Type); - Py_TYPE(&Simple_Type) = &SimpleType_Type; - Simple_Type.tp_base = &CData_Type; + Py_TYPE(&Simple_Type) = &PyCSimpleType_Type; + Simple_Type.tp_base = &PyCData_Type; if (PyType_Ready(&Simple_Type) < 0) return; PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type); - Py_TYPE(&CFuncPtr_Type) = &CFuncPtrType_Type; - CFuncPtr_Type.tp_base = &CData_Type; - if (PyType_Ready(&CFuncPtr_Type) < 0) + Py_TYPE(&PyCFuncPtr_Type) = &PyCFuncPtrType_Type; + PyCFuncPtr_Type.tp_base = &PyCData_Type; + if (PyType_Ready(&PyCFuncPtr_Type) < 0) return; - PyModule_AddObject(m, "CFuncPtr", (PyObject *)&CFuncPtr_Type); + PyModule_AddObject(m, "CFuncPtr", (PyObject *)&PyCFuncPtr_Type); /************************************************* * * Simple classes */ - /* CField_Type is derived from PyBaseObject_Type */ - if (PyType_Ready(&CField_Type) < 0) + /* PyCField_Type is derived from PyBaseObject_Type */ + if (PyType_Ready(&PyCField_Type) < 0) return; /************************************************* @@ -5613,6 +5613,7 @@ * See #1047269 Buffer overwrite in PyUnicode_AsWideChar */ +#if (PY_VERSION_HEX < 0x02040000) #ifdef HAVE_WCHAR_H PyObject *My_PyUnicode_FromWideChar(register const wchar_t *w, @@ -5671,7 +5672,7 @@ return size; } - +#endif #endif /* Modified: python/trunk/Modules/_ctypes/callbacks.c ============================================================================== --- python/trunk/Modules/_ctypes/callbacks.c (original) +++ python/trunk/Modules/_ctypes/callbacks.c Fri Apr 24 22:31:47 2009 @@ -22,7 +22,7 @@ Py_XDECREF(self->callable); Py_XDECREF(self->restype); if (self->pcl) - FreeClosure(self->pcl); + _ctypes_free_closure(self->pcl); PyObject_Del(self); } @@ -46,7 +46,7 @@ return 0; } -PyTypeObject CThunk_Type = { +PyTypeObject PyCThunk_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_ctypes.CThunkObject", sizeof(CThunkObject), /* tp_basicsize */ @@ -97,7 +97,7 @@ /* after code that pyrex generates */ -void _AddTraceback(char *funcname, char *filename, int lineno) +void _ctypes_add_traceback(char *funcname, char *filename, int lineno) { PyObject *py_srcfile = 0; PyObject *py_funcname = 0; @@ -227,7 +227,7 @@ goto Done; } - if (dict && dict->getfunc && !IsSimpleSubType(cnv)) { + if (dict && dict->getfunc && !_ctypes_simple_instance(cnv)) { PyObject *v = dict->getfunc(*pArgs, dict->size); if (!v) { PrintError("create argument %d:\n", i); @@ -241,7 +241,7 @@ BTW, the same problem occurrs when they are pushed as parameters */ } else if (dict) { - /* Hm, shouldn't we use CData_AtAddress() or something like that instead? */ + /* Hm, shouldn't we use PyCData_AtAddress() or something like that instead? */ CDataObject *obj = (CDataObject *)PyObject_CallFunctionObjArgs(cnv, NULL); if (!obj) { PrintError("create argument %d:\n", i); @@ -272,10 +272,10 @@ } #define CHECK(what, x) \ -if (x == NULL) _AddTraceback(what, "_ctypes/callbacks.c", __LINE__ - 1), PyErr_Print() +if (x == NULL) _ctypes_add_traceback(what, "_ctypes/callbacks.c", __LINE__ - 1), PyErr_Print() if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) { - error_object = get_error_object(&space); + error_object = _ctypes_get_errobj(&space); if (error_object == NULL) goto Done; if (flags & FUNCFLAG_USE_ERRNO) { @@ -332,7 +332,7 @@ PyErr_WriteUnraisable(callable); else if (keep == Py_None) /* Nothing to keep */ Py_DECREF(keep); - else if (setfunc != getentry("O")->setfunc) { + else if (setfunc != _ctypes_get_fielddesc("O")->setfunc) { if (-1 == PyErr_Warn(PyExc_RuntimeWarning, "memory leak in callback function.")) PyErr_WriteUnraisable(callable); @@ -367,7 +367,7 @@ CThunkObject *p; int i; - p = PyObject_NewVar(CThunkObject, &CThunk_Type, nArgs); + p = PyObject_NewVar(CThunkObject, &PyCThunk_Type, nArgs); if (p == NULL) { PyErr_NoMemory(); return NULL; @@ -385,7 +385,7 @@ return p; } -CThunkObject *AllocFunctionCallback(PyObject *callable, +CThunkObject *_ctypes_alloc_callback(PyObject *callable, PyObject *converters, PyObject *restype, int flags) @@ -402,7 +402,7 @@ assert(CThunk_CheckExact(p)); - p->pcl = MallocClosure(); + p->pcl = _ctypes_alloc_closure(); if (p->pcl == NULL) { PyErr_NoMemory(); goto error; @@ -413,7 +413,7 @@ PyObject *cnv = PySequence_GetItem(converters, i); if (cnv == NULL) goto error; - p->atypes[i] = GetType(cnv); + p->atypes[i] = _ctypes_get_ffi_type(cnv); Py_DECREF(cnv); } p->atypes[i] = NULL; @@ -441,7 +441,7 @@ #endif result = ffi_prep_cif(&p->cif, cc, Py_SAFE_DOWNCAST(nArgs, Py_ssize_t, int), - GetType(restype), + _ctypes_get_ffi_type(restype), &p->atypes[0]); if (result != FFI_OK) { PyErr_Format(PyExc_RuntimeError, Modified: python/trunk/Modules/_ctypes/callproc.c ============================================================================== --- python/trunk/Modules/_ctypes/callproc.c (original) +++ python/trunk/Modules/_ctypes/callproc.c Fri Apr 24 22:31:47 2009 @@ -20,7 +20,7 @@ /* How are functions called, and how are parameters converted to C ? - 1. _ctypes.c::CFuncPtr_call receives an argument tuple 'inargs' and a + 1. _ctypes.c::PyCFuncPtr_call receives an argument tuple 'inargs' and a keyword dictionary 'kwds'. 2. After several checks, _build_callargs() is called which returns another @@ -32,7 +32,7 @@ the callargs tuple, specifying how to build the return value(s) of the function. - 4. _CallProc is then called with the 'callargs' tuple. _CallProc first + 4. _ctypes_callproc is then called with the 'callargs' tuple. _ctypes_callproc first allocates two arrays. The first is an array of 'struct argument' items, the second array has 'void *' entried. @@ -52,8 +52,8 @@ libffi specific stuff, then it calls ffi_call. So, there are 4 data structures holding processed arguments: - - the inargs tuple (in CFuncPtr_call) - - the callargs tuple (in CFuncPtr_call) + - the inargs tuple (in PyCFuncPtr_call) + - the callargs tuple (in PyCFuncPtr_call) - the 'struct argguments' array - the 'void *' array @@ -118,7 +118,7 @@ kept alive in the thread state dictionary as long as the thread itself. */ PyObject * -get_error_object(int **pspace) +_ctypes_get_errobj(int **pspace) { PyObject *dict = PyThreadState_GetDict(); PyObject *errobj; @@ -158,7 +158,7 @@ get_error_internal(PyObject *self, PyObject *args, int index) { int *space; - PyObject *errobj = get_error_object(&space); + PyObject *errobj = _ctypes_get_errobj(&space); PyObject *result; if (errobj == NULL) @@ -177,7 +177,7 @@ if (!PyArg_ParseTuple(args, "i", &new_errno)) return NULL; - errobj = get_error_object(&space); + errobj = _ctypes_get_errobj(&space); if (errobj == NULL) return NULL; old_errno = space[index]; @@ -410,7 +410,7 @@ /**************************************************************/ PyCArgObject * -new_CArgObject(void) +PyCArgObject_new(void) { PyCArgObject *p; p = PyObject_New(PyCArgObject, &PyCArg_Type); @@ -708,7 +708,7 @@ } -ffi_type *GetType(PyObject *obj) +ffi_type *_ctypes_get_ffi_type(PyObject *obj) { StgDictObject *dict; if (obj == NULL) @@ -788,7 +788,7 @@ } if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) { - error_object = get_error_object(&space); + error_object = _ctypes_get_errobj(&space); if (error_object == NULL) return -1; } @@ -906,24 +906,24 @@ if (dict == NULL) return PyObject_CallFunction(restype, "i", *(int *)result); - if (dict->getfunc && !IsSimpleSubType(restype)) { + if (dict->getfunc && !_ctypes_simple_instance(restype)) { retval = dict->getfunc(result, dict->size); /* If restype is py_object (detected by comparing getfunc with O_get), we have to call Py_DECREF because O_get has already called Py_INCREF. */ - if (dict->getfunc == getentry("O")->getfunc) { + if (dict->getfunc == _ctypes_get_fielddesc("O")->getfunc) { Py_DECREF(retval); } } else - retval = CData_FromBaseObj(restype, NULL, 0, result); + retval = PyCData_FromBaseObj(restype, NULL, 0, result); if (!checker || !retval) return retval; v = PyObject_CallFunctionObjArgs(checker, retval, NULL); if (v == NULL) - _AddTraceback("GetResult", "_ctypes/callproc.c", __LINE__-2); + _ctypes_add_traceback("GetResult", "_ctypes/callproc.c", __LINE__-2); Py_DECREF(retval); return v; } @@ -932,7 +932,7 @@ * Raise a new exception 'exc_class', adding additional text to the original * exception string. */ -void Extend_Error_Info(PyObject *exc_class, char *fmt, ...) +void _ctypes_extend_error(PyObject *exc_class, char *fmt, ...) { va_list vargs; PyObject *tp, *v, *tb, *s, *cls_str, *msg_str; @@ -1057,7 +1057,7 @@ * * - XXX various requirements for restype, not yet collected */ -PyObject *_CallProc(PPROC pProc, +PyObject *_ctypes_callproc(PPROC pProc, PyObject *argtuple, #ifdef MS_WIN32 IUnknown *pIunk, @@ -1110,7 +1110,7 @@ arg = PyTuple_GET_ITEM(argtuple, i); /* borrowed ref */ /* For cdecl functions, we allow more actual arguments than the length of the argtypes tuple. - This is checked in _ctypes::CFuncPtr_Call + This is checked in _ctypes::PyCFuncPtr_Call */ if (argtypes && argtype_count > i) { PyObject *v; @@ -1119,26 +1119,26 @@ arg, NULL); if (v == NULL) { - Extend_Error_Info(PyExc_ArgError, "argument %d: ", i+1); + _ctypes_extend_error(PyExc_ArgError, "argument %d: ", i+1); goto cleanup; } err = ConvParam(v, i+1, pa); Py_DECREF(v); if (-1 == err) { - Extend_Error_Info(PyExc_ArgError, "argument %d: ", i+1); + _ctypes_extend_error(PyExc_ArgError, "argument %d: ", i+1); goto cleanup; } } else { err = ConvParam(arg, i+1, pa); if (-1 == err) { - Extend_Error_Info(PyExc_ArgError, "argument %d: ", i+1); + _ctypes_extend_error(PyExc_ArgError, "argument %d: ", i+1); goto cleanup; /* leaking ? */ } } } - rtype = GetType(restype); + rtype = _ctypes_get_ffi_type(restype); resbuf = alloca(max(rtype->size, sizeof(ffi_arg))); avalues = (void **)alloca(sizeof(void *) * argcount); @@ -1350,7 +1350,7 @@ pIunk = (IUnknown *)(*(void **)(pcom->b_ptr)); lpVtbl = (PPROC *)(pIunk->lpVtbl); - result = _CallProc(lpVtbl[index], + result = _ctypes_callproc(lpVtbl[index], arguments, #ifdef MS_WIN32 pIunk, @@ -1473,7 +1473,7 @@ &PyTuple_Type, &arguments)) return NULL; - result = _CallProc((PPROC)func, + result = _ctypes_callproc((PPROC)func, arguments, #ifdef MS_WIN32 NULL, @@ -1504,7 +1504,7 @@ &PyTuple_Type, &arguments)) return NULL; - result = _CallProc((PPROC)func, + result = _ctypes_callproc((PPROC)func, arguments, #ifdef MS_WIN32 NULL, @@ -1596,7 +1596,7 @@ return NULL; } - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; @@ -1671,17 +1671,17 @@ if (!PyArg_ParseTuple(args, "zs:set_conversion_mode", &coding, &mode)) return NULL; - result = Py_BuildValue("(zz)", conversion_mode_encoding, conversion_mode_errors); + result = Py_BuildValue("(zz)", _ctypes_conversion_encoding, _ctypes_conversion_errors); if (coding) { - PyMem_Free(conversion_mode_encoding); - conversion_mode_encoding = PyMem_Malloc(strlen(coding) + 1); - strcpy(conversion_mode_encoding, coding); + PyMem_Free(_ctypes_conversion_encoding); + _ctypes_conversion_encoding = PyMem_Malloc(strlen(coding) + 1); + strcpy(_ctypes_conversion_encoding, coding); } else { - conversion_mode_encoding = NULL; + _ctypes_conversion_encoding = NULL; } - PyMem_Free(conversion_mode_errors); - conversion_mode_errors = PyMem_Malloc(strlen(mode) + 1); - strcpy(conversion_mode_errors, mode); + PyMem_Free(_ctypes_conversion_errors); + _ctypes_conversion_errors = PyMem_Malloc(strlen(mode) + 1); + strcpy(_ctypes_conversion_errors, mode); return result; } #endif @@ -1780,7 +1780,7 @@ PyObject *key; char *buf; - result = PyDict_GetItem(_pointer_type_cache, cls); + result = PyDict_GetItem(_ctypes_ptrtype_cache, cls); if (result) { Py_INCREF(result); return result; @@ -1788,10 +1788,10 @@ if (PyString_CheckExact(cls)) { buf = alloca(strlen(PyString_AS_STRING(cls)) + 3 + 1); sprintf(buf, "LP_%s", PyString_AS_STRING(cls)); - result = PyObject_CallFunction((PyObject *)Py_TYPE(&Pointer_Type), + result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type), "s(O){}", buf, - &Pointer_Type); + &PyCPointer_Type); if (result == NULL) return result; key = PyLong_FromVoidPtr(result); @@ -1799,10 +1799,10 @@ typ = (PyTypeObject *)cls; buf = alloca(strlen(typ->tp_name) + 3 + 1); sprintf(buf, "LP_%s", typ->tp_name); - result = PyObject_CallFunction((PyObject *)Py_TYPE(&Pointer_Type), + result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type), "s(O){sO}", buf, - &Pointer_Type, + &PyCPointer_Type, "_type_", cls); if (result == NULL) return result; @@ -1812,7 +1812,7 @@ PyErr_SetString(PyExc_TypeError, "must be a ctypes type"); return NULL; } - if (-1 == PyDict_SetItem(_pointer_type_cache, key, result)) { + if (-1 == PyDict_SetItem(_ctypes_ptrtype_cache, key, result)) { Py_DECREF(result); Py_DECREF(key); return NULL; @@ -1827,7 +1827,7 @@ PyObject *result; PyObject *typ; - typ = PyDict_GetItem(_pointer_type_cache, (PyObject *)Py_TYPE(arg)); + typ = PyDict_GetItem(_ctypes_ptrtype_cache, (PyObject *)Py_TYPE(arg)); if (typ) return PyObject_CallFunctionObjArgs(typ, arg, NULL); typ = POINTER(NULL, (PyObject *)Py_TYPE(arg)); @@ -1865,7 +1865,7 @@ return Py_BuildValue("siN", dict->format, dict->ndim, shape); } -PyMethodDef module_methods[] = { +PyMethodDef _ctypes_module_methods[] = { {"get_errno", get_errno, METH_NOARGS}, {"set_errno", set_errno, METH_VARARGS}, {"POINTER", POINTER, METH_O }, Modified: python/trunk/Modules/_ctypes/cfield.c ============================================================================== --- python/trunk/Modules/_ctypes/cfield.c (original) +++ python/trunk/Modules/_ctypes/cfield.c Fri Apr 24 22:31:47 2009 @@ -12,10 +12,10 @@ /******************************************************************/ /* - CField_Type + PyCField_Type */ static PyObject * -CField_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +PyCField_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { CFieldObject *obj; obj = (CFieldObject *)type->tp_alloc(type, 0); @@ -35,7 +35,7 @@ * prev_desc points to the type of the previous bitfield, if any. */ PyObject * -CField_FromDesc(PyObject *desc, Py_ssize_t index, +PyCField_FromDesc(PyObject *desc, Py_ssize_t index, Py_ssize_t *pfield_size, int bitsize, int *pbitofs, Py_ssize_t *psize, Py_ssize_t *poffset, Py_ssize_t *palign, int pack, int big_endian) @@ -52,7 +52,7 @@ #define CONT_BITFIELD 2 #define EXPAND_BITFIELD 3 - self = (CFieldObject *)PyObject_CallObject((PyObject *)&CField_Type, + self = (CFieldObject *)PyObject_CallObject((PyObject *)&PyCField_Type, NULL); if (self == NULL) return NULL; @@ -102,7 +102,7 @@ /* Field descriptors for 'c_char * n' are be scpecial cased to return a Python string instead of an Array object instance... */ - if (ArrayTypeObject_Check(proto)) { + if (PyCArrayTypeObject_Check(proto)) { StgDictObject *adict = PyType_stgdict(proto); StgDictObject *idict; if (adict && adict->proto) { @@ -113,14 +113,14 @@ Py_DECREF(self); return NULL; } - if (idict->getfunc == getentry("c")->getfunc) { - struct fielddesc *fd = getentry("s"); + if (idict->getfunc == _ctypes_get_fielddesc("c")->getfunc) { + struct fielddesc *fd = _ctypes_get_fielddesc("s"); getfunc = fd->getfunc; setfunc = fd->setfunc; } #ifdef CTYPES_UNICODE - if (idict->getfunc == getentry("u")->getfunc) { - struct fielddesc *fd = getentry("U"); + if (idict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { + struct fielddesc *fd = _ctypes_get_fielddesc("U"); getfunc = fd->getfunc; setfunc = fd->setfunc; } @@ -194,7 +194,7 @@ } static int -CField_set(CFieldObject *self, PyObject *inst, PyObject *value) +PyCField_set(CFieldObject *self, PyObject *inst, PyObject *value) { CDataObject *dst; char *ptr; @@ -206,12 +206,12 @@ "can't delete attribute"); return -1; } - return CData_set(inst, self->proto, self->setfunc, value, + return PyCData_set(inst, self->proto, self->setfunc, value, self->index, self->size, ptr); } static PyObject * -CField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type) +PyCField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type) { CDataObject *src; if (inst == NULL) { @@ -220,51 +220,51 @@ } assert(CDataObject_Check(inst)); src = (CDataObject *)inst; - return CData_get(self->proto, self->getfunc, inst, + return PyCData_get(self->proto, self->getfunc, inst, self->index, self->size, src->b_ptr + self->offset); } static PyObject * -CField_get_offset(PyObject *self, void *data) +PyCField_get_offset(PyObject *self, void *data) { return PyInt_FromSsize_t(((CFieldObject *)self)->offset); } static PyObject * -CField_get_size(PyObject *self, void *data) +PyCField_get_size(PyObject *self, void *data) { return PyInt_FromSsize_t(((CFieldObject *)self)->size); } -static PyGetSetDef CField_getset[] = { - { "offset", CField_get_offset, NULL, "offset in bytes of this field" }, - { "size", CField_get_size, NULL, "size in bytes of this field" }, +static PyGetSetDef PyCField_getset[] = { + { "offset", PyCField_get_offset, NULL, "offset in bytes of this field" }, + { "size", PyCField_get_size, NULL, "size in bytes of this field" }, { NULL, NULL, NULL, NULL }, }; static int -CField_traverse(CFieldObject *self, visitproc visit, void *arg) +PyCField_traverse(CFieldObject *self, visitproc visit, void *arg) { Py_VISIT(self->proto); return 0; } static int -CField_clear(CFieldObject *self) +PyCField_clear(CFieldObject *self) { Py_CLEAR(self->proto); return 0; } static void -CField_dealloc(PyObject *self) +PyCField_dealloc(PyObject *self) { - CField_clear((CFieldObject *)self); + PyCField_clear((CFieldObject *)self); self->ob_type->tp_free((PyObject *)self); } static PyObject * -CField_repr(CFieldObject *self) +PyCField_repr(CFieldObject *self) { PyObject *result; Py_ssize_t bits = self->size >> 16; @@ -292,17 +292,17 @@ return result; } -PyTypeObject CField_Type = { +PyTypeObject PyCField_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_ctypes.CField", /* tp_name */ sizeof(CFieldObject), /* tp_basicsize */ 0, /* tp_itemsize */ - CField_dealloc, /* tp_dealloc */ + PyCField_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ - (reprfunc)CField_repr, /* tp_repr */ + (reprfunc)PyCField_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ @@ -314,23 +314,23 @@ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ "Structure/Union member", /* tp_doc */ - (traverseproc)CField_traverse, /* tp_traverse */ - (inquiry)CField_clear, /* tp_clear */ + (traverseproc)PyCField_traverse, /* tp_traverse */ + (inquiry)PyCField_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ - CField_getset, /* tp_getset */ + PyCField_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ - (descrgetfunc)CField_get, /* tp_descr_get */ - (descrsetfunc)CField_set, /* tp_descr_set */ + (descrgetfunc)PyCField_get, /* tp_descr_get */ + (descrsetfunc)PyCField_set, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - CField_new, /* tp_new */ + PyCField_new, /* tp_new */ 0, /* tp_free */ }; @@ -1191,8 +1191,8 @@ if (PyString_Check(value)) { value = PyUnicode_FromEncodedObject(value, - conversion_mode_encoding, - conversion_mode_errors); + _ctypes_conversion_encoding, + _ctypes_conversion_errors); if (!value) return NULL; } else if (!PyUnicode_Check(value)) { @@ -1266,8 +1266,8 @@ if (PyString_Check(value)) { value = PyUnicode_FromEncodedObject(value, - conversion_mode_encoding, - conversion_mode_errors); + _ctypes_conversion_encoding, + _ctypes_conversion_errors); if (!value) return NULL; } else if (!PyUnicode_Check(value)) { @@ -1364,8 +1364,8 @@ return value; } else if (PyUnicode_Check(value)) { PyObject *str = PyUnicode_AsEncodedString(value, - conversion_mode_encoding, - conversion_mode_errors); + _ctypes_conversion_encoding, + _ctypes_conversion_errors); if (str == NULL) return NULL; *(char **)ptr = PyString_AS_STRING(str); @@ -1415,8 +1415,8 @@ } if (PyString_Check(value)) { value = PyUnicode_FromEncodedObject(value, - conversion_mode_encoding, - conversion_mode_errors); + _ctypes_conversion_encoding, + _ctypes_conversion_errors); if (!value) return NULL; } else if (PyInt_Check(value) || PyLong_Check(value)) { @@ -1509,8 +1509,8 @@ value = NULL; } else if (PyString_Check(value)) { value = PyUnicode_FromEncodedObject(value, - conversion_mode_encoding, - conversion_mode_errors); + _ctypes_conversion_encoding, + _ctypes_conversion_errors); if (!value) return NULL; } else if (PyUnicode_Check(value)) { @@ -1670,7 +1670,7 @@ */ struct fielddesc * -getentry(char *fmt) +_ctypes_get_fielddesc(char *fmt) { static int initialized = 0; struct fielddesc *table = formattable; @@ -1679,11 +1679,11 @@ initialized = 1; #ifdef CTYPES_UNICODE if (sizeof(wchar_t) == sizeof(short)) - getentry("u")->pffi_type = &ffi_type_sshort; + _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sshort; else if (sizeof(wchar_t) == sizeof(int)) - getentry("u")->pffi_type = &ffi_type_sint; + _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sint; else if (sizeof(wchar_t) == sizeof(long)) - getentry("u")->pffi_type = &ffi_type_slong; + _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_slong; #endif } Modified: python/trunk/Modules/_ctypes/ctypes.h ============================================================================== --- python/trunk/Modules/_ctypes/ctypes.h (original) +++ python/trunk/Modules/_ctypes/ctypes.h Fri Apr 24 22:31:47 2009 @@ -59,7 +59,7 @@ and this one is not used. Making CDataObject a variable size object would be a better solution, but more -difficult in the presence of CFuncPtrObject. Maybe later. +difficult in the presence of PyCFuncPtrObject. Maybe later. */ union value { char c[16]; @@ -105,8 +105,8 @@ ffi_type *ffi_restype; ffi_type *atypes[1]; } CThunkObject; -extern PyTypeObject CThunk_Type; -#define CThunk_CheckExact(v) ((v)->ob_type == &CThunk_Type) +extern PyTypeObject PyCThunk_Type; +#define CThunk_CheckExact(v) ((v)->ob_type == &PyCThunk_Type) typedef struct { /* First part identical to tagCDataObject */ @@ -137,61 +137,61 @@ GUID *iid; #endif PyObject *paramflags; -} CFuncPtrObject; +} PyCFuncPtrObject; -extern PyTypeObject StgDict_Type; -#define StgDict_CheckExact(v) ((v)->ob_type == &StgDict_Type) -#define StgDict_Check(v) PyObject_TypeCheck(v, &StgDict_Type) +extern PyTypeObject PyCStgDict_Type; +#define PyCStgDict_CheckExact(v) ((v)->ob_type == &PyCStgDict_Type) +#define PyCStgDict_Check(v) PyObject_TypeCheck(v, &PyCStgDict_Type) -extern int StructUnionType_update_stgdict(PyObject *fields, PyObject *type, int isStruct); +extern int PyCStructUnionType_update_stgdict(PyObject *fields, PyObject *type, int isStruct); extern int PyType_stginfo(PyTypeObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength); extern int PyObject_stginfo(PyObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength); -extern PyTypeObject CData_Type; -#define CDataObject_CheckExact(v) ((v)->ob_type == &CData_Type) -#define CDataObject_Check(v) PyObject_TypeCheck(v, &CData_Type) - -extern PyTypeObject SimpleType_Type; -#define SimpleTypeObject_CheckExact(v) ((v)->ob_type == &SimpleType_Type) -#define SimpleTypeObject_Check(v) PyObject_TypeCheck(v, &SimpleType_Type) +extern PyTypeObject PyCData_Type; +#define CDataObject_CheckExact(v) ((v)->ob_type == &PyCData_Type) +#define CDataObject_Check(v) PyObject_TypeCheck(v, &PyCData_Type) + +extern PyTypeObject PyCSimpleType_Type; +#define PyCSimpleTypeObject_CheckExact(v) ((v)->ob_type == &PyCSimpleType_Type) +#define PyCSimpleTypeObject_Check(v) PyObject_TypeCheck(v, &PyCSimpleType_Type) -extern PyTypeObject CField_Type; -extern struct fielddesc *getentry(char *fmt); +extern PyTypeObject PyCField_Type; +extern struct fielddesc *_ctypes_get_fielddesc(char *fmt); extern PyObject * -CField_FromDesc(PyObject *desc, Py_ssize_t index, +PyCField_FromDesc(PyObject *desc, Py_ssize_t index, Py_ssize_t *pfield_size, int bitsize, int *pbitofs, Py_ssize_t *psize, Py_ssize_t *poffset, Py_ssize_t *palign, int pack, int is_big_endian); -extern PyObject *CData_AtAddress(PyObject *type, void *buf); -extern PyObject *CData_FromBytes(PyObject *type, char *data, Py_ssize_t length); +extern PyObject *PyCData_AtAddress(PyObject *type, void *buf); +extern PyObject *PyCData_FromBytes(PyObject *type, char *data, Py_ssize_t length); -extern PyTypeObject ArrayType_Type; -extern PyTypeObject Array_Type; -extern PyTypeObject PointerType_Type; -extern PyTypeObject Pointer_Type; -extern PyTypeObject CFuncPtr_Type; -extern PyTypeObject CFuncPtrType_Type; -extern PyTypeObject StructType_Type; - -#define ArrayTypeObject_Check(v) PyObject_TypeCheck(v, &ArrayType_Type) -#define ArrayObject_Check(v) PyObject_TypeCheck(v, &Array_Type) -#define PointerObject_Check(v) PyObject_TypeCheck(v, &Pointer_Type) -#define PointerTypeObject_Check(v) PyObject_TypeCheck(v, &PointerType_Type) -#define CFuncPtrObject_Check(v) PyObject_TypeCheck(v, &CFuncPtr_Type) -#define CFuncPtrTypeObject_Check(v) PyObject_TypeCheck(v, &CFuncPtrType_Type) -#define StructTypeObject_Check(v) PyObject_TypeCheck(v, &StructType_Type) +extern PyTypeObject PyCArrayType_Type; +extern PyTypeObject PyCArray_Type; +extern PyTypeObject PyCPointerType_Type; +extern PyTypeObject PyCPointer_Type; +extern PyTypeObject PyCFuncPtr_Type; +extern PyTypeObject PyCFuncPtrType_Type; +extern PyTypeObject PyCStructType_Type; + +#define PyCArrayTypeObject_Check(v) PyObject_TypeCheck(v, &PyCArrayType_Type) +#define ArrayObject_Check(v) PyObject_TypeCheck(v, &PyCArray_Type) +#define PointerObject_Check(v) PyObject_TypeCheck(v, &PyCPointer_Type) +#define PyCPointerTypeObject_Check(v) PyObject_TypeCheck(v, &PyCPointerType_Type) +#define PyCFuncPtrObject_Check(v) PyObject_TypeCheck(v, &PyCFuncPtr_Type) +#define PyCFuncPtrTypeObject_Check(v) PyObject_TypeCheck(v, &PyCFuncPtrType_Type) +#define PyCStructTypeObject_Check(v) PyObject_TypeCheck(v, &PyCStructType_Type) extern PyObject * -CreateArrayType(PyObject *itemtype, Py_ssize_t length); +PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length); -extern PyMethodDef module_methods[]; +extern PyMethodDef _ctypes_module_methods[]; -extern CThunkObject *AllocFunctionCallback(PyObject *callable, +extern CThunkObject *_ctypes_alloc_callback(PyObject *callable, PyObject *converters, PyObject *restype, int flags); @@ -223,7 +223,7 @@ PyDictObject dict; /* first part identical to PyDictObject */ /* The size and align fields are unneeded, they are in ffi_type as well. As an experiment shows, it's trivial to get rid of them, the only thing to - remember is that in ArrayType_new the ffi_type fields must be filled in - + remember is that in PyCArrayType_new the ffi_type fields must be filled in - so far it was unneeded because libffi doesn't support arrays at all (because they are passed as pointers to function calls anyway). But it's too much risk to change that now, and there are other fields which doen't @@ -238,7 +238,7 @@ GETFUNC getfunc; /* Only for simple objects */ PARAMFUNC paramfunc; - /* Following fields only used by CFuncPtrType_Type instances */ + /* Following fields only used by PyCFuncPtrType_Type instances */ PyObject *argtypes; /* tuple of CDataObjects */ PyObject *converters; /* tuple([t.from_param for t in argtypes]) */ PyObject *restype; /* CDataObject or NULL */ @@ -272,7 +272,7 @@ construction time, or assigns to it later, tp_setattro should update the StgDictObject function to a generic one. - Currently, CFuncPtr types have 'converters' and 'checker' entries in their + Currently, PyCFuncPtr types have 'converters' and 'checker' entries in their type dict. They are only used to cache attributes from other entries, whihc is wrong. @@ -300,11 +300,11 @@ /* May return NULL, but does not set an exception! */ extern StgDictObject *PyObject_stgdict(PyObject *self); -extern int StgDict_clone(StgDictObject *src, StgDictObject *dst); +extern int PyCStgDict_clone(StgDictObject *src, StgDictObject *dst); typedef int(* PPROC)(void); -PyObject *_CallProc(PPROC pProc, +PyObject *_ctypes_callproc(PPROC pProc, PyObject *arguments, #ifdef MS_WIN32 IUnknown *pIUnk, @@ -352,17 +352,17 @@ extern PyTypeObject PyCArg_Type; #define PyCArg_CheckExact(v) ((v)->ob_type == &PyCArg_Type) -extern PyCArgObject *new_CArgObject(void); +extern PyCArgObject *PyCArgObject_new(void); extern PyObject * -CData_get(PyObject *type, GETFUNC getfunc, PyObject *src, +PyCData_get(PyObject *type, GETFUNC getfunc, PyObject *src, Py_ssize_t index, Py_ssize_t size, char *ptr); extern int -CData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, +PyCData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, Py_ssize_t index, Py_ssize_t size, char *ptr); -extern void Extend_Error_Info(PyObject *exc_class, char *fmt, ...); +extern void _ctypes_extend_error(PyObject *exc_class, char *fmt, ...); struct basespec { CDataObject *base; @@ -372,13 +372,13 @@ extern char basespec_string[]; -extern ffi_type *GetType(PyObject *obj); +extern ffi_type *_ctypes_get_ffi_type(PyObject *obj); /* exception classes */ extern PyObject *PyExc_ArgError; -extern char *conversion_mode_encoding; -extern char *conversion_mode_errors; +extern char *_ctypes_conversion_encoding; +extern char *_ctypes_conversion_errors; /* Python 2.4 macros, which are not available in Python 2.3 */ @@ -415,31 +415,31 @@ #endif +#if (PY_VERSION_HEX < 0x02040000) #ifdef CTYPES_UNICODE # undef PyUnicode_FromWideChar -# define PyUnicode_FromWideChar My_PyUnicode_FromWideChar +# define PyUnicode_FromWideChar PyUnicode_FromWideChar_fixed # undef PyUnicode_AsWideChar -# define PyUnicode_AsWideChar My_PyUnicode_AsWideChar - -extern PyObject *My_PyUnicode_FromWideChar(const wchar_t *, Py_ssize_t); -extern Py_ssize_t My_PyUnicode_AsWideChar(PyUnicodeObject *, wchar_t *, Py_ssize_t); +# define PyUnicode_AsWideChar PyUnicode_AsWideChar_fixed +extern PyObject *PyUnicode_FromWideChar_fixed(const wchar_t *, Py_ssize_t); +extern Py_ssize_t PyUnicode_AsWideChar_fixed(PyUnicodeObject *, wchar_t *, Py_ssize_t); +#endif #endif -extern void FreeClosure(void *); -extern void *MallocClosure(void); +extern void _ctypes_free_closure(void *); +extern void *_ctypes_alloc_closure(void); -extern void _AddTraceback(char *, char *, int); +extern void _ctypes_add_traceback(char *, char *, int); -extern PyObject *CData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr); -extern char *alloc_format_string(const char *prefix, const char *suffix); +extern PyObject *PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr); +extern char *_ctypes_alloc_format_string(const char *prefix, const char *suffix); -/* XXX better name needed! */ -extern int IsSimpleSubType(PyObject *obj); +extern int _ctypes_simple_instance(PyObject *obj); -extern PyObject *_pointer_type_cache; -PyObject *get_error_object(int **pspace); +extern PyObject *_ctypes_ptrtype_cache; +PyObject *_ctypes_get_errobj(int **pspace); #ifdef MS_WIN32 extern PyObject *ComError; Modified: python/trunk/Modules/_ctypes/malloc_closure.c ============================================================================== --- python/trunk/Modules/_ctypes/malloc_closure.c (original) +++ python/trunk/Modules/_ctypes/malloc_closure.c Fri Apr 24 22:31:47 2009 @@ -93,7 +93,7 @@ /******************************************************************/ /* put the item back into the free list */ -void FreeClosure(void *p) +void _ctypes_free_closure(void *p) { ITEM *item = (ITEM *)p; item->next = free_list; @@ -101,7 +101,7 @@ } /* return one item from the free list, allocating more if needed */ -void *MallocClosure(void) +void *_ctypes_alloc_closure(void) { ITEM *item; if (!free_list) Modified: python/trunk/Modules/_ctypes/stgdict.c ============================================================================== --- python/trunk/Modules/_ctypes/stgdict.c (original) +++ python/trunk/Modules/_ctypes/stgdict.c Fri Apr 24 22:31:47 2009 @@ -21,7 +21,7 @@ * PyDict_SetItem() (ma_lookup is NULL) */ static int -StgDict_init(StgDictObject *self, PyObject *args, PyObject *kwds) +PyCStgDict_init(StgDictObject *self, PyObject *args, PyObject *kwds) { if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0) return -1; @@ -32,7 +32,7 @@ } static int -StgDict_clear(StgDictObject *self) +PyCStgDict_clear(StgDictObject *self) { Py_CLEAR(self->proto); Py_CLEAR(self->argtypes); @@ -43,9 +43,9 @@ } static void -StgDict_dealloc(StgDictObject *self) +PyCStgDict_dealloc(StgDictObject *self) { - StgDict_clear(self); + PyCStgDict_clear(self); PyMem_Free(self->format); PyMem_Free(self->shape); PyMem_Free(self->ffi_type_pointer.elements); @@ -53,12 +53,12 @@ } int -StgDict_clone(StgDictObject *dst, StgDictObject *src) +PyCStgDict_clone(StgDictObject *dst, StgDictObject *src) { char *d, *s; Py_ssize_t size; - StgDict_clear(dst); + PyCStgDict_clear(dst); PyMem_Free(dst->ffi_type_pointer.elements); PyMem_Free(dst->format); dst->format = NULL; @@ -106,12 +106,12 @@ return 0; } -PyTypeObject StgDict_Type = { +PyTypeObject PyCStgDict_Type = { PyVarObject_HEAD_INIT(NULL, 0) "StgDict", sizeof(StgDictObject), 0, - (destructor)StgDict_dealloc, /* tp_dealloc */ + (destructor)PyCStgDict_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -142,7 +142,7 @@ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)StgDict_init, /* tp_init */ + (initproc)PyCStgDict_init, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ 0, /* tp_free */ @@ -159,7 +159,7 @@ type = (PyTypeObject *)obj; if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_CLASS)) return NULL; - if (!type->tp_dict || !StgDict_CheckExact(type->tp_dict)) + if (!type->tp_dict || !PyCStgDict_CheckExact(type->tp_dict)) return NULL; return (StgDictObject *)type->tp_dict; } @@ -175,7 +175,7 @@ PyTypeObject *type = self->ob_type; if (!PyType_HasFeature(type, Py_TPFLAGS_HAVE_CLASS)) return NULL; - if (!type->tp_dict || !StgDict_CheckExact(type->tp_dict)) + if (!type->tp_dict || !PyCStgDict_CheckExact(type->tp_dict)) return NULL; return (StgDictObject *)type->tp_dict; } @@ -215,7 +215,7 @@ Py_DECREF(fieldlist); return -1; } - if (Py_TYPE(fdescr) != &CField_Type) { + if (Py_TYPE(fdescr) != &PyCField_Type) { PyErr_SetString(PyExc_TypeError, "unexpected type"); Py_DECREF(fdescr); Py_DECREF(fieldlist); @@ -232,13 +232,13 @@ } continue; } - new_descr = (CFieldObject *)PyObject_CallObject((PyObject *)&CField_Type, NULL); + new_descr = (CFieldObject *)PyObject_CallObject((PyObject *)&PyCField_Type, NULL); if (new_descr == NULL) { Py_DECREF(fdescr); Py_DECREF(fieldlist); return -1; } - assert(Py_TYPE(new_descr) == &CField_Type); + assert(Py_TYPE(new_descr) == &PyCField_Type); new_descr->size = fdescr->size; new_descr->offset = fdescr->offset + offset; new_descr->index = fdescr->index + index; @@ -286,7 +286,7 @@ Py_DECREF(anon_names); return -1; } - assert(Py_TYPE(descr) == &CField_Type); + assert(Py_TYPE(descr) == &PyCField_Type); descr->anonymous = 1; /* descr is in the field descriptor. */ @@ -309,7 +309,7 @@ and create an StgDictObject. Used for Structure and Union subclasses. */ int -StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) +PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) { StgDictObject *stgdict, *basedict; Py_ssize_t len, offset, size, align, i; @@ -418,12 +418,12 @@ assert(stgdict->format == NULL); if (isStruct && !isPacked) { - stgdict->format = alloc_format_string(NULL, "T{"); + stgdict->format = _ctypes_alloc_format_string(NULL, "T{"); } else { /* PEP3118 doesn't support union, or packed structures (well, only standard packing, but we dont support the pep for that). Use 'B' for bytes. */ - stgdict->format = alloc_format_string(NULL, "B"); + stgdict->format = _ctypes_alloc_format_string(NULL, "B"); } #define realdict ((PyObject *)&stgdict->dict) @@ -468,9 +468,9 @@ case FFI_TYPE_SINT8: case FFI_TYPE_SINT16: case FFI_TYPE_SINT32: - if (dict->getfunc != getentry("c")->getfunc + if (dict->getfunc != _ctypes_get_fielddesc("c")->getfunc #ifdef CTYPES_UNICODE - && dict->getfunc != getentry("u")->getfunc + && dict->getfunc != _ctypes_get_fielddesc("u")->getfunc #endif ) break; @@ -500,7 +500,7 @@ sprintf(buf, "%s:%s:", fieldfmt, fieldname); ptr = stgdict->format; - stgdict->format = alloc_format_string(stgdict->format, buf); + stgdict->format = _ctypes_alloc_format_string(stgdict->format, buf); PyMem_Free(ptr); if (stgdict->format == NULL) { @@ -509,7 +509,7 @@ } } if (isStruct) { - prop = CField_FromDesc(desc, i, + prop = PyCField_FromDesc(desc, i, &field_size, bitsize, &bitofs, &size, &offset, &align, pack, big_endian); @@ -517,7 +517,7 @@ size = 0; offset = 0; align = 0; - prop = CField_FromDesc(desc, i, + prop = PyCField_FromDesc(desc, i, &field_size, bitsize, &bitofs, &size, &offset, &align, pack, big_endian); @@ -541,7 +541,7 @@ if (isStruct && !isPacked) { char *ptr = stgdict->format; - stgdict->format = alloc_format_string(stgdict->format, "}"); + stgdict->format = _ctypes_alloc_format_string(stgdict->format, "}"); PyMem_Free(ptr); if (stgdict->format == NULL) return -1; From python-checkins at python.org Fri Apr 24 22:50:01 2009 From: python-checkins at python.org (thomas.heller) Date: Fri, 24 Apr 2009 22:50:01 +0200 (CEST) Subject: [Python-checkins] r71854 - in python/branches/py3k: Misc/NEWS Modules/_ctypes/_ctypes.c Modules/_ctypes/callbacks.c Modules/_ctypes/callproc.c Modules/_ctypes/cfield.c Modules/_ctypes/ctypes.h Modules/_ctypes/malloc_closure.c Modules/_ctypes/stgdict.c Message-ID: <20090424205001.C39BE1E401E@bag.python.org> Author: thomas.heller Date: Fri Apr 24 22:50:00 2009 New Revision: 71854 Log: Merged revisions 71853 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71853 | thomas.heller | 2009-04-24 22:31:47 +0200 (Fr, 24 Apr 2009) | 3 lines Issue #3102: All global symbols that the _ctypes extension defines are now prefixed with 'Py' or '_ctypes'. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_ctypes/_ctypes.c python/branches/py3k/Modules/_ctypes/callbacks.c python/branches/py3k/Modules/_ctypes/callproc.c python/branches/py3k/Modules/_ctypes/cfield.c python/branches/py3k/Modules/_ctypes/ctypes.h python/branches/py3k/Modules/_ctypes/malloc_closure.c python/branches/py3k/Modules/_ctypes/stgdict.c Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Fri Apr 24 22:50:00 2009 @@ -77,6 +77,11 @@ Library ------- +- Issue #3102: All global symbols that the _ctypes extension defines + are now prefixed with 'Py' or '_ctypes'. + +- Issue #5041: ctypes does now allow pickling wide character. + - Issue #5812: For the two-argument form of the Fraction constructor, Fraction(m, n), m and n are permitted to be arbitrary Rational instances. @@ -430,8 +435,6 @@ Library ------- -- Issue #5041: ctypes does now allow pickling wide character. - - Issue #5795: Fixed test_distutils failure on Debian ppc. - Issue #5607: fixed Distutils test_get_platform for Mac OS X fat binaries. Modified: python/branches/py3k/Modules/_ctypes/_ctypes.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/_ctypes.c (original) +++ python/branches/py3k/Modules/_ctypes/_ctypes.c Fri Apr 24 22:50:00 2009 @@ -1,7 +1,7 @@ /* ToDo: - Get rid of the checker (and also the converters) field in CFuncPtrObject and + Get rid of the checker (and also the converters) field in PyCFuncPtrObject and StgDictObject, and replace them by slot functions in StgDictObject. think about a buffer-like object (memory? bytes?) @@ -23,20 +23,20 @@ Name methods, members, getsets ============================================================================== -StructType_Type __new__(), from_address(), __mul__(), from_param() +PyCStructType_Type __new__(), from_address(), __mul__(), from_param() UnionType_Type __new__(), from_address(), __mul__(), from_param() -PointerType_Type __new__(), from_address(), __mul__(), from_param(), set_type() -ArrayType_Type __new__(), from_address(), __mul__(), from_param() -SimpleType_Type __new__(), from_address(), __mul__(), from_param() +PyCPointerType_Type __new__(), from_address(), __mul__(), from_param(), set_type() +PyCArrayType_Type __new__(), from_address(), __mul__(), from_param() +PyCSimpleType_Type __new__(), from_address(), __mul__(), from_param() -CData_Type +PyCData_Type Struct_Type __new__(), __init__() - Pointer_Type __new__(), __init__(), _as_parameter_, contents - Array_Type __new__(), __init__(), _as_parameter_, __get/setitem__(), __len__() + PyCPointer_Type __new__(), __init__(), _as_parameter_, contents + PyCArray_Type __new__(), __init__(), _as_parameter_, __get/setitem__(), __len__() Simple_Type __new__(), __init__(), _as_parameter_ -CField_Type -StgDict_Type +PyCField_Type +PyCStgDict_Type ============================================================================== @@ -82,20 +82,20 @@ */ /* - * StgDict_Type - * StructType_Type + * PyCStgDict_Type + * PyCStructType_Type * UnionType_Type - * PointerType_Type - * ArrayType_Type - * SimpleType_Type + * PyCPointerType_Type + * PyCArrayType_Type + * PyCSimpleType_Type * - * CData_Type + * PyCData_Type * Struct_Type * Union_Type - * Array_Type + * PyCArray_Type * Simple_Type - * Pointer_Type - * CField_Type + * PyCPointer_Type + * PyCField_Type * */ @@ -125,15 +125,15 @@ PyObject *PyExc_ArgError; /* This dict maps ctypes types to POINTER types */ -PyObject *_pointer_type_cache; +PyObject *_ctypes_ptrtype_cache; static PyTypeObject Simple_Type; /* a callable object used for unpickling */ static PyObject *_unpickle; -char *conversion_mode_encoding = NULL; -char *conversion_mode_errors = NULL; +char *_ctypes_conversion_encoding = NULL; +char *_ctypes_conversion_errors = NULL; /****************************************************************/ @@ -267,7 +267,7 @@ already be set. */ char * -alloc_format_string(const char *prefix, const char *suffix) +_ctypes_alloc_format_string(const char *prefix, const char *suffix) { size_t len; char *result; @@ -291,7 +291,7 @@ } /* - StructType_Type - a meta type/class. Creating a new class using this one as + PyCStructType_Type - a meta type/class. Creating a new class using this one as __metaclass__ will call the contructor StructUnionType_new. It replaces the tp_dict member with a new instance of StgDict, and initializes the C accessible fields somehow. @@ -303,7 +303,7 @@ PyCArgObject *parg; StgDictObject *stgdict; - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; @@ -339,7 +339,7 @@ if (PyDict_GetItemString(result->tp_dict, "_abstract_")) return (PyObject *)result; - dict = (StgDictObject *)PyObject_CallObject((PyObject *)&StgDict_Type, NULL); + dict = (StgDictObject *)PyObject_CallObject((PyObject *)&PyCStgDict_Type, NULL); if (!dict) { Py_DECREF(result); return NULL; @@ -353,7 +353,7 @@ } Py_DECREF(result->tp_dict); result->tp_dict = (PyObject *)dict; - dict->format = alloc_format_string(NULL, "B"); + dict->format = _ctypes_alloc_format_string(NULL, "B"); if (dict->format == NULL) { Py_DECREF(result); return NULL; @@ -368,7 +368,7 @@ if (basedict == NULL) return (PyObject *)result; /* copy base dict */ - if (-1 == StgDict_clone(dict, basedict)) { + if (-1 == PyCStgDict_clone(dict, basedict)) { Py_DECREF(result); return NULL; } @@ -385,7 +385,7 @@ } static PyObject * -StructType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +PyCStructType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { return StructUnionType_new(type, args, kwds, 1); } @@ -411,7 +411,7 @@ buf = (void *)PyLong_AsVoidPtr(value); if (PyErr_Occurred()) return NULL; - return CData_AtAddress(type, buf); + return PyCData_AtAddress(type, buf); } static char from_buffer_doc[] = @@ -458,7 +458,7 @@ return NULL; } - result = CData_AtAddress(type, (char *)buffer + offset); + result = PyCData_AtAddress(type, (char *)buffer + offset); if (result == NULL) return NULL; @@ -474,7 +474,7 @@ "C.from_buffer_copy(object, offset=0) -> C instance\ncreate a C instance from a readable buffer"; static PyObject * -GenericCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds); +GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static PyObject * CDataType_from_buffer_copy(PyObject *type, PyObject *args) @@ -515,7 +515,7 @@ return NULL; } - result = GenericCData_new((PyTypeObject *)type, NULL, NULL); + result = GenericPyCData_new((PyTypeObject *)type, NULL, NULL); if (result == NULL) return NULL; memcpy(((CDataObject *)result)->b_ptr, @@ -577,7 +577,7 @@ return NULL; } #endif - return CData_AtAddress(type, address); + return PyCData_AtAddress(type, address); } static char from_param_doc[] = @@ -641,7 +641,7 @@ return PyErr_Format(PyExc_ValueError, "Array length must be >= 0, not %zd", length); - return CreateArrayType(self, length); + return PyCArrayType_from_ctype(self, length); } static PySequenceMethods CDataType_as_sequence = { @@ -677,7 +677,7 @@ } static int -StructType_setattro(PyObject *self, PyObject *key, PyObject *value) +PyCStructType_setattro(PyObject *self, PyObject *key, PyObject *value) { /* XXX Should we disallow deleting _fields_? */ if (-1 == PyType_Type.tp_setattro(self, key, value)) @@ -686,7 +686,7 @@ if (value && PyUnicode_Check(key) && /* XXX struni _PyUnicode_AsString can fail (also in other places)! */ 0 == strcmp(_PyUnicode_AsString(key), "_fields_")) - return StructUnionType_update_stgdict(self, value, 1); + return PyCStructUnionType_update_stgdict(self, value, 1); return 0; } @@ -700,14 +700,14 @@ if (PyUnicode_Check(key) && 0 == strcmp(_PyUnicode_AsString(key), "_fields_")) - return StructUnionType_update_stgdict(self, value, 0); + return PyCStructUnionType_update_stgdict(self, value, 0); return 0; } -PyTypeObject StructType_Type = { +PyTypeObject PyCStructType_Type = { PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.StructType", /* tp_name */ + "_ctypes.PyCStructType", /* tp_name */ 0, /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ @@ -723,7 +723,7 @@ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ - StructType_setattro, /* tp_setattro */ + PyCStructType_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ "metatype for the CData Objects", /* tp_doc */ @@ -743,7 +743,7 @@ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - StructType_new, /* tp_new */ + PyCStructType_new, /* tp_new */ 0, /* tp_free */ }; @@ -794,20 +794,20 @@ /* -The PointerType_Type metaclass must ensure that the subclass of Pointer can be +The PyCPointerType_Type metaclass must ensure that the subclass of Pointer can be created. It must check for a _type_ attribute in the class. Since are no runtime created properties, a CField is probably *not* needed ? class IntPointer(Pointer): _type_ = "i" -The Pointer_Type provides the functionality: a contents method/property, a +The PyCPointer_Type provides the functionality: a contents method/property, a size property/method, and the sequence protocol. */ static int -PointerType_SetProto(StgDictObject *stgdict, PyObject *proto) +PyCPointerType_SetProto(StgDictObject *stgdict, PyObject *proto) { if (!proto || !PyType_Check(proto)) { PyErr_SetString(PyExc_TypeError, @@ -826,11 +826,11 @@ } static PyCArgObject * -PointerType_paramfunc(CDataObject *self) +PyCPointerType_paramfunc(CDataObject *self) { PyCArgObject *parg; - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; @@ -843,7 +843,7 @@ } static PyObject * -PointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyTypeObject *result; StgDictObject *stgdict; @@ -858,18 +858,18 @@ stgdict->proto has info about the pointed to type! */ stgdict = (StgDictObject *)PyObject_CallObject( - (PyObject *)&StgDict_Type, NULL); + (PyObject *)&PyCStgDict_Type, NULL); if (!stgdict) return NULL; stgdict->size = sizeof(void *); - stgdict->align = getentry("P")->pffi_type->alignment; + stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment; stgdict->length = 1; stgdict->ffi_type_pointer = ffi_type_pointer; - stgdict->paramfunc = PointerType_paramfunc; + stgdict->paramfunc = PyCPointerType_paramfunc; stgdict->flags |= TYPEFLAG_ISPOINTER; proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */ - if (proto && -1 == PointerType_SetProto(stgdict, proto)) { + if (proto && -1 == PyCPointerType_SetProto(stgdict, proto)) { Py_DECREF((PyObject *)stgdict); return NULL; } @@ -882,7 +882,7 @@ 'pointer to bytes' in this case. XXX Better would be to fix the format string later... */ - stgdict->format = alloc_format_string("&", + stgdict->format = _ctypes_alloc_format_string("&", itemdict->format ? itemdict->format : "B"); if (stgdict->format == NULL) { Py_DECREF((PyObject *)stgdict); @@ -912,14 +912,14 @@ static PyObject * -PointerType_set_type(PyTypeObject *self, PyObject *type) +PyCPointerType_set_type(PyTypeObject *self, PyObject *type) { StgDictObject *dict; dict = PyType_stgdict((PyObject *)self); assert(dict); - if (-1 == PointerType_SetProto(dict, type)) + if (-1 == PyCPointerType_SetProto(dict, type)) return NULL; if (-1 == PyDict_SetItemString((PyObject *)dict, "_type_", type)) @@ -932,7 +932,7 @@ static PyObject *_byref(PyObject *); static PyObject * -PointerType_from_param(PyObject *type, PyObject *value) +PyCPointerType_from_param(PyObject *type, PyObject *value) { StgDictObject *typedict; @@ -970,19 +970,19 @@ return CDataType_from_param(type, value); } -static PyMethodDef PointerType_methods[] = { +static PyMethodDef PyCPointerType_methods[] = { { "from_address", CDataType_from_address, METH_O, from_address_doc }, { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, }, { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, }, { "in_dll", CDataType_in_dll, METH_VARARGS, in_dll_doc}, - { "from_param", (PyCFunction)PointerType_from_param, METH_O, from_param_doc}, - { "set_type", (PyCFunction)PointerType_set_type, METH_O }, + { "from_param", (PyCFunction)PyCPointerType_from_param, METH_O, from_param_doc}, + { "set_type", (PyCFunction)PyCPointerType_set_type, METH_O }, { NULL, NULL }, }; -PyTypeObject PointerType_Type = { +PyTypeObject PyCPointerType_Type = { PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.PointerType", /* tp_name */ + "_ctypes.PyCPointerType", /* tp_name */ 0, /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ @@ -1008,7 +1008,7 @@ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - PointerType_methods, /* tp_methods */ + PyCPointerType_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ @@ -1018,17 +1018,17 @@ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - PointerType_new, /* tp_new */ + PyCPointerType_new, /* tp_new */ 0, /* tp_free */ }; /******************************************************************/ /* - ArrayType_Type + PyCArrayType_Type */ /* - ArrayType_new ensures that the new Array subclass created has a _length_ + PyCArrayType_new ensures that the new Array subclass created has a _length_ attribute, and a _type_ attribute. */ @@ -1089,8 +1089,8 @@ if (PyUnicode_Check(value)) { value = PyUnicode_AsEncodedString(value, - conversion_mode_encoding, - conversion_mode_errors); + _ctypes_conversion_encoding, + _ctypes_conversion_errors); if (!value) return -1; } else if (!PyBytes_Check(value)) { @@ -1149,8 +1149,8 @@ } if (PyBytes_Check(value)) { value = PyUnicode_FromEncodedObject(value, - conversion_mode_encoding, - conversion_mode_errors); + _ctypes_conversion_encoding, + _ctypes_conversion_errors); if (!value) return -1; } else if (!PyUnicode_Check(value)) { @@ -1242,9 +1242,9 @@ } static PyCArgObject * -ArrayType_paramfunc(CDataObject *self) +PyCArrayType_paramfunc(CDataObject *self) { - PyCArgObject *p = new_CArgObject(); + PyCArgObject *p = PyCArgObject_new(); if (p == NULL) return NULL; p->tag = 'P'; @@ -1256,7 +1256,7 @@ } static PyObject * -ArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyTypeObject *result; StgDictObject *stgdict; @@ -1294,7 +1294,7 @@ } stgdict = (StgDictObject *)PyObject_CallObject( - (PyObject *)&StgDict_Type, NULL); + (PyObject *)&PyCStgDict_Type, NULL); if (!stgdict) return NULL; @@ -1309,10 +1309,10 @@ assert(itemdict->format); if (itemdict->format[0] == '(') { sprintf(buf, "(%ld,", length); - stgdict->format = alloc_format_string(buf, itemdict->format+1); + stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format+1); } else { sprintf(buf, "(%ld)", length); - stgdict->format = alloc_format_string(buf, itemdict->format); + stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format); } if (stgdict->format == NULL) { Py_DECREF((PyObject *)stgdict); @@ -1346,7 +1346,7 @@ Py_INCREF(proto); stgdict->proto = proto; - stgdict->paramfunc = &ArrayType_paramfunc; + stgdict->paramfunc = &PyCArrayType_paramfunc; /* Arrays are passed as pointers to function calls. */ stgdict->ffi_type_pointer = ffi_type_pointer; @@ -1369,11 +1369,11 @@ /* Special case for character arrays. A permanent annoyance: char arrays are also strings! */ - if (itemdict->getfunc == getentry("c")->getfunc) { + if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) { if (-1 == add_getset(result, CharArray_getsets)) return NULL; #ifdef CTYPES_UNICODE - } else if (itemdict->getfunc == getentry("u")->getfunc) { + } else if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { if (-1 == add_getset(result, WCharArray_getsets)) return NULL; #endif @@ -1382,9 +1382,9 @@ return (PyObject *)result; } -PyTypeObject ArrayType_Type = { +PyTypeObject PyCArrayType_Type = { PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.ArrayType", /* tp_name */ + "_ctypes.PyCArrayType", /* tp_name */ 0, /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ @@ -1420,18 +1420,18 @@ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - ArrayType_new, /* tp_new */ + PyCArrayType_new, /* tp_new */ 0, /* tp_free */ }; /******************************************************************/ /* - SimpleType_Type + PyCSimpleType_Type */ /* -SimpleType_new ensures that the new Simple_Type subclass created has a valid +PyCSimpleType_new ensures that the new Simple_Type subclass created has a valid _type_ attribute. */ @@ -1448,9 +1448,9 @@ } if (PyUnicode_Check(value) || PyBytes_Check(value)) { PyCArgObject *parg; - struct fielddesc *fd = getentry("Z"); + struct fielddesc *fd = _ctypes_get_fielddesc("Z"); - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; parg->pffi_type = &ffi_type_pointer; @@ -1472,7 +1472,7 @@ StgDictObject *dict; assert(dt); /* Cannot be NULL for pointer or array objects */ dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL; - if (dict && (dict->setfunc == getentry("u")->setfunc)) { + if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) { Py_INCREF(value); return value; } @@ -1481,7 +1481,7 @@ /* byref(c_char(...)) */ PyCArgObject *a = (PyCArgObject *)value; StgDictObject *dict = PyObject_stgdict(a->obj); - if (dict && (dict->setfunc == getentry("u")->setfunc)) { + if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) { Py_INCREF(value); return value; } @@ -1509,9 +1509,9 @@ } if (PyBytes_Check(value) || PyUnicode_Check(value)) { PyCArgObject *parg; - struct fielddesc *fd = getentry("z"); + struct fielddesc *fd = _ctypes_get_fielddesc("z"); - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; parg->pffi_type = &ffi_type_pointer; @@ -1533,7 +1533,7 @@ StgDictObject *dict; assert(dt); /* Cannot be NULL for pointer or array objects */ dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL; - if (dict && (dict->setfunc == getentry("c")->setfunc)) { + if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) { Py_INCREF(value); return value; } @@ -1542,7 +1542,7 @@ /* byref(c_char(...)) */ PyCArgObject *a = (PyCArgObject *)value; StgDictObject *dict = PyObject_stgdict(a->obj); - if (dict && (dict->setfunc == getentry("c")->setfunc)) { + if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) { Py_INCREF(value); return value; } @@ -1575,9 +1575,9 @@ /* int, long */ if (PyLong_Check(value)) { PyCArgObject *parg; - struct fielddesc *fd = getentry("P"); + struct fielddesc *fd = _ctypes_get_fielddesc("P"); - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; parg->pffi_type = &ffi_type_pointer; @@ -1593,9 +1593,9 @@ /* string */ if (PyBytes_Check(value)) { PyCArgObject *parg; - struct fielddesc *fd = getentry("z"); + struct fielddesc *fd = _ctypes_get_fielddesc("z"); - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; parg->pffi_type = &ffi_type_pointer; @@ -1610,9 +1610,9 @@ /* bytes */ if (PyByteArray_Check(value)) { PyCArgObject *parg; - struct fielddesc *fd = getentry("z"); + struct fielddesc *fd = _ctypes_get_fielddesc("z"); - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; parg->pffi_type = &ffi_type_pointer; @@ -1627,9 +1627,9 @@ /* unicode */ if (PyUnicode_Check(value)) { PyCArgObject *parg; - struct fielddesc *fd = getentry("Z"); + struct fielddesc *fd = _ctypes_get_fielddesc("Z"); - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; parg->pffi_type = &ffi_type_pointer; @@ -1663,11 +1663,11 @@ } } /* function pointer */ - if (CFuncPtrObject_Check(value)) { + if (PyCFuncPtrObject_Check(value)) { PyCArgObject *parg; - CFuncPtrObject *func; - func = (CFuncPtrObject *)value; - parg = new_CArgObject(); + PyCFuncPtrObject *func; + func = (PyCFuncPtrObject *)value; + parg = PyCArgObject_new(); if (parg == NULL) return NULL; parg->pffi_type = &ffi_type_pointer; @@ -1685,7 +1685,7 @@ switch (_PyUnicode_AsString(stgd->proto)[0]) { case 'z': /* c_char_p */ case 'Z': /* c_wchar_p */ - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; parg->pffi_type = &ffi_type_pointer; @@ -1756,7 +1756,7 @@ return NULL; stgdict = (StgDictObject *)PyObject_CallObject( - (PyObject *)&StgDict_Type, NULL); + (PyObject *)&PyCStgDict_Type, NULL); if (!stgdict) /* XXX leaks result! */ return NULL; @@ -1783,7 +1783,7 @@ } static PyCArgObject * -SimpleType_paramfunc(CDataObject *self) +PyCSimpleType_paramfunc(CDataObject *self) { StgDictObject *dict; char *fmt; @@ -1795,10 +1795,10 @@ fmt = _PyUnicode_AsString(dict->proto); assert(fmt); - fd = getentry(fmt); + fd = _ctypes_get_fielddesc(fmt); assert(fd); - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; @@ -1811,7 +1811,7 @@ } static PyObject * -SimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyTypeObject *result; StgDictObject *stgdict; @@ -1860,7 +1860,7 @@ SIMPLE_TYPE_CHARS); goto error; } - fmt = getentry(proto_str); + fmt = _ctypes_get_fielddesc(proto_str); if (fmt == NULL) { Py_DECREF((PyObject *)result); PyErr_Format(PyExc_ValueError, @@ -1869,7 +1869,7 @@ } stgdict = (StgDictObject *)PyObject_CallObject( - (PyObject *)&StgDict_Type, NULL); + (PyObject *)&PyCStgDict_Type, NULL); if (!stgdict) return NULL; @@ -1880,9 +1880,9 @@ stgdict->setfunc = fmt->setfunc; stgdict->getfunc = fmt->getfunc; #ifdef WORDS_BIGENDIAN - stgdict->format = alloc_format_string(">", proto_str); + stgdict->format = _ctypes_alloc_format_string(">", proto_str); #else - stgdict->format = alloc_format_string("<", proto_str); + stgdict->format = _ctypes_alloc_format_string("<", proto_str); #endif if (stgdict->format == NULL) { Py_DECREF(result); @@ -1890,7 +1890,7 @@ return NULL; } - stgdict->paramfunc = SimpleType_paramfunc; + stgdict->paramfunc = PyCSimpleType_paramfunc; /* if (result->tp_base != &Simple_Type) { stgdict->setfunc = NULL; @@ -1911,7 +1911,7 @@ result->tp_dict = (PyObject *)stgdict; /* Install from_param class methods in ctypes base classes. - Overrides the SimpleType_from_param generic method. + Overrides the PyCSimpleType_from_param generic method. */ if (result->tp_base == &Simple_Type) { switch (*proto_str) { @@ -1955,7 +1955,7 @@ } } - if (type == &SimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) { + if (type == &PyCSimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) { PyObject *swapped = CreateSwappedType(type, args, kwds, proto, fmt); StgDictObject *sw_dict; @@ -1970,14 +1970,14 @@ PyObject_SetAttrString(swapped, "__ctype_be__", (PyObject *)result); PyObject_SetAttrString(swapped, "__ctype_le__", swapped); /* We are creating the type for the OTHER endian */ - sw_dict->format = alloc_format_string("<", stgdict->format+1); + sw_dict->format = _ctypes_alloc_format_string("<", stgdict->format+1); #else PyObject_SetAttrString((PyObject *)result, "__ctype_be__", swapped); PyObject_SetAttrString((PyObject *)result, "__ctype_le__", (PyObject *)result); PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result); PyObject_SetAttrString(swapped, "__ctype_be__", swapped); /* We are creating the type for the OTHER endian */ - sw_dict->format = alloc_format_string(">", stgdict->format+1); + sw_dict->format = _ctypes_alloc_format_string(">", stgdict->format+1); #endif Py_DECREF(swapped); if (PyErr_Occurred()) { @@ -1994,7 +1994,7 @@ * Convert a parameter into something that ConvParam can handle. */ static PyObject * -SimpleType_from_param(PyObject *type, PyObject *value) +PyCSimpleType_from_param(PyObject *type, PyObject *value) { StgDictObject *dict; char *fmt; @@ -2016,10 +2016,10 @@ fmt = _PyUnicode_AsString(dict->proto); assert(fmt); - fd = getentry(fmt); + fd = _ctypes_get_fielddesc(fmt); assert(fd); - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; @@ -2033,7 +2033,7 @@ as_parameter = PyObject_GetAttrString(value, "_as_parameter_"); if (as_parameter) { - value = SimpleType_from_param(type, as_parameter); + value = PyCSimpleType_from_param(type, as_parameter); Py_DECREF(as_parameter); return value; } @@ -2042,8 +2042,8 @@ return NULL; } -static PyMethodDef SimpleType_methods[] = { - { "from_param", SimpleType_from_param, METH_O, from_param_doc }, +static PyMethodDef PyCSimpleType_methods[] = { + { "from_param", PyCSimpleType_from_param, METH_O, from_param_doc }, { "from_address", CDataType_from_address, METH_O, from_address_doc }, { "from_buffer", CDataType_from_buffer, METH_VARARGS, from_buffer_doc, }, { "from_buffer_copy", CDataType_from_buffer_copy, METH_VARARGS, from_buffer_copy_doc, }, @@ -2051,9 +2051,9 @@ { NULL, NULL }, }; -PyTypeObject SimpleType_Type = { +PyTypeObject PyCSimpleType_Type = { PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.SimpleType", /* tp_name */ + "_ctypes.PyCSimpleType", /* tp_name */ 0, /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ @@ -2072,14 +2072,14 @@ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "metatype for the SimpleType Objects", /* tp_doc */ + "metatype for the PyCSimpleType Objects", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - SimpleType_methods, /* tp_methods */ + PyCSimpleType_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ @@ -2089,13 +2089,13 @@ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - SimpleType_new, /* tp_new */ + PyCSimpleType_new, /* tp_new */ 0, /* tp_free */ }; /******************************************************************/ /* - CFuncPtrType_Type + PyCFuncPtrType_Type */ static PyObject * @@ -2147,7 +2147,7 @@ PyObject *ob; PyObject *converters = NULL; - stgdict->align = getentry("P")->pffi_type->alignment; + stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment; stgdict->length = 1; stgdict->size = sizeof(void *); stgdict->setfunc = NULL; @@ -2207,11 +2207,11 @@ } static PyCArgObject * -CFuncPtrType_paramfunc(CDataObject *self) +PyCFuncPtrType_paramfunc(CDataObject *self) { PyCArgObject *parg; - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; @@ -2224,24 +2224,24 @@ } static PyObject * -CFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +PyCFuncPtrType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyTypeObject *result; StgDictObject *stgdict; stgdict = (StgDictObject *)PyObject_CallObject( - (PyObject *)&StgDict_Type, NULL); + (PyObject *)&PyCStgDict_Type, NULL); if (!stgdict) return NULL; - stgdict->paramfunc = CFuncPtrType_paramfunc; + stgdict->paramfunc = PyCFuncPtrType_paramfunc; /* We do NOT expose the function signature in the format string. It is impossible, generally, because the only requirement for the argtypes items is that they have a .from_param method - we do not know the types of the arguments (although, in practice, most argtypes would be a ctypes type). */ - stgdict->format = alloc_format_string(NULL, "X{}"); + stgdict->format = _ctypes_alloc_format_string(NULL, "X{}"); stgdict->flags |= TYPEFLAG_ISPOINTER; /* create the new instance (which is a class, @@ -2269,9 +2269,9 @@ return (PyObject *)result; } -PyTypeObject CFuncPtrType_Type = { +PyTypeObject PyCFuncPtrType_Type = { PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.CFuncPtrType", /* tp_name */ + "_ctypes.PyCFuncPtrType", /* tp_name */ 0, /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ @@ -2307,7 +2307,7 @@ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - CFuncPtrType_new, /* tp_new */ + PyCFuncPtrType_new, /* tp_new */ 0, /* tp_free */ }; @@ -2317,7 +2317,7 @@ */ static CDataObject * -CData_GetContainer(CDataObject *self) +PyCData_GetContainer(CDataObject *self) { while (self->b_base) self = self->b_base; @@ -2335,7 +2335,7 @@ static PyObject * GetKeepedObjects(CDataObject *target) { - return CData_GetContainer(target)->b_objects; + return PyCData_GetContainer(target)->b_objects; } static PyObject * @@ -2391,7 +2391,7 @@ Py_DECREF(Py_None); return 0; } - ob = CData_GetContainer(target); + ob = PyCData_GetContainer(target); if (ob->b_objects == NULL || !PyDict_CheckExact(ob->b_objects)) { Py_XDECREF(ob->b_objects); ob->b_objects = keep; /* refcount consumed */ @@ -2410,10 +2410,10 @@ /******************************************************************/ /* - CData_Type + PyCData_Type */ static int -CData_traverse(CDataObject *self, visitproc visit, void *arg) +PyCData_traverse(CDataObject *self, visitproc visit, void *arg) { Py_VISIT(self->b_objects); Py_VISIT((PyObject *)self->b_base); @@ -2421,7 +2421,7 @@ } static int -CData_clear(CDataObject *self) +PyCData_clear(CDataObject *self) { StgDictObject *dict = PyObject_stgdict((PyObject *)self); assert(dict); /* Cannot be NULL for CDataObject instances */ @@ -2435,13 +2435,13 @@ } static void -CData_dealloc(PyObject *self) +PyCData_dealloc(PyObject *self) { - CData_clear((CDataObject *)self); + PyCData_clear((CDataObject *)self); Py_TYPE(self)->tp_free(self); } -static PyMemberDef CData_members[] = { +static PyMemberDef PyCData_members[] = { { "_b_base_", T_OBJECT, offsetof(CDataObject, b_base), READONLY, "the base object" }, @@ -2454,7 +2454,7 @@ { NULL }, }; -static int CData_GetBuffer(PyObject *_self, Py_buffer *view, int flags) +static int PyCData_NewGetBuffer(PyObject *_self, Py_buffer *view, int flags) { CDataObject *self = (CDataObject *)_self; StgDictObject *dict = PyObject_stgdict(_self); @@ -2481,8 +2481,8 @@ return 0; } -static PyBufferProcs CData_as_buffer = { - CData_GetBuffer, +static PyBufferProcs PyCData_as_buffer = { + PyCData_NewGetBuffer, NULL, }; @@ -2490,14 +2490,14 @@ * CData objects are mutable, so they cannot be hashable! */ static long -CData_nohash(PyObject *self) +PyCData_nohash(PyObject *self) { PyErr_SetString(PyExc_TypeError, "unhashable type"); return -1; } static PyObject * -CData_reduce(PyObject *_self, PyObject *args) +PyCData_reduce(PyObject *_self, PyObject *args) { CDataObject *self = (CDataObject *)_self; @@ -2514,7 +2514,7 @@ } static PyObject * -CData_setstate(PyObject *_self, PyObject *args) +PyCData_setstate(PyObject *_self, PyObject *args) { void *data; Py_ssize_t len; @@ -2539,25 +2539,25 @@ * default __ctypes_from_outparam__ method returns self. */ static PyObject * -CData_from_outparam(PyObject *self, PyObject *args) +PyCData_from_outparam(PyObject *self, PyObject *args) { Py_INCREF(self); return self; } -static PyMethodDef CData_methods[] = { - { "__ctypes_from_outparam__", CData_from_outparam, METH_NOARGS, }, - { "__reduce__", CData_reduce, METH_NOARGS, }, - { "__setstate__", CData_setstate, METH_VARARGS, }, +static PyMethodDef PyCData_methods[] = { + { "__ctypes_from_outparam__", PyCData_from_outparam, METH_NOARGS, }, + { "__reduce__", PyCData_reduce, METH_NOARGS, }, + { "__setstate__", PyCData_setstate, METH_VARARGS, }, { NULL, NULL }, }; -PyTypeObject CData_Type = { +PyTypeObject PyCData_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_ctypes._CData", sizeof(CDataObject), /* tp_basicsize */ 0, /* tp_itemsize */ - CData_dealloc, /* tp_dealloc */ + PyCData_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -2566,22 +2566,22 @@ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ - CData_nohash, /* tp_hash */ + PyCData_nohash, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ - &CData_as_buffer, /* tp_as_buffer */ + &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ "XXX to be provided", /* tp_doc */ - (traverseproc)CData_traverse, /* tp_traverse */ - (inquiry)CData_clear, /* tp_clear */ + (traverseproc)PyCData_traverse, /* tp_traverse */ + (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - CData_methods, /* tp_methods */ - CData_members, /* tp_members */ + PyCData_methods, /* tp_methods */ + PyCData_members, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ @@ -2594,7 +2594,7 @@ 0, /* tp_free */ }; -static int CData_MallocBuffer(CDataObject *obj, StgDictObject *dict) +static int PyCData_MallocBuffer(CDataObject *obj, StgDictObject *dict) { if ((size_t)dict->size <= sizeof(obj->b_value)) { /* No need to call malloc, can use the default buffer */ @@ -2623,7 +2623,7 @@ } PyObject * -CData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr) +PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr) { CDataObject *cmem; StgDictObject *dict; @@ -2651,7 +2651,7 @@ cmem->b_base = (CDataObject *)base; cmem->b_index = index; } else { /* copy contents of adr */ - if (-1 == CData_MallocBuffer(cmem, dict)) { + if (-1 == PyCData_MallocBuffer(cmem, dict)) { return NULL; Py_DECREF(cmem); } @@ -2665,7 +2665,7 @@ Box a memory block into a CData instance. */ PyObject * -CData_AtAddress(PyObject *type, void *buf) +PyCData_AtAddress(PyObject *type, void *buf) { CDataObject *pd; StgDictObject *dict; @@ -2694,17 +2694,17 @@ classes. FALSE otherwise FALSE also for subclasses of c_int and such. */ -int IsSimpleSubType(PyObject *obj) +int _ctypes_simple_instance(PyObject *obj) { PyTypeObject *type = (PyTypeObject *)obj; - if (SimpleTypeObject_Check(type)) + if (PyCSimpleTypeObject_Check(type)) return type->tp_base != &Simple_Type; return 0; } PyObject * -CData_get(PyObject *type, GETFUNC getfunc, PyObject *src, +PyCData_get(PyObject *type, GETFUNC getfunc, PyObject *src, Py_ssize_t index, Py_ssize_t size, char *adr) { StgDictObject *dict; @@ -2712,16 +2712,16 @@ return getfunc(adr, size); assert(type); dict = PyType_stgdict(type); - if (dict && dict->getfunc && !IsSimpleSubType(type)) + if (dict && dict->getfunc && !_ctypes_simple_instance(type)) return dict->getfunc(adr, size); - return CData_FromBaseObj(type, src, index, adr); + return PyCData_FromBaseObj(type, src, index, adr); } /* - Helper function for CData_set below. + Helper function for PyCData_set below. */ static PyObject * -_CData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, +_PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, Py_ssize_t size, char *ptr) { CDataObject *src; @@ -2743,15 +2743,15 @@ PyObject *result; ob = PyObject_CallObject(type, value); if (ob == NULL) { - Extend_Error_Info(PyExc_RuntimeError, "(%s) ", + _ctypes_extend_error(PyExc_RuntimeError, "(%s) ", ((PyTypeObject *)type)->tp_name); return NULL; } - result = _CData_set(dst, type, setfunc, ob, + result = _PyCData_set(dst, type, setfunc, ob, size, ptr); Py_DECREF(ob); return result; - } else if (value == Py_None && PointerTypeObject_Check(type)) { + } else if (value == Py_None && PyCPointerTypeObject_Check(type)) { *(void **)ptr = NULL; Py_INCREF(Py_None); return Py_None; @@ -2770,7 +2770,7 @@ src->b_ptr, size); - if (PointerTypeObject_Check(type)) + if (PyCPointerTypeObject_Check(type)) /* XXX */; value = GetKeepedObjects(src); @@ -2778,7 +2778,7 @@ return value; } - if (PointerTypeObject_Check(type) + if (PyCPointerTypeObject_Check(type) && ArrayObject_Check(value)) { StgDictObject *p1, *p2; PyObject *keep; @@ -2819,7 +2819,7 @@ * to the value 'value'. */ int -CData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, +PyCData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, Py_ssize_t index, Py_ssize_t size, char *ptr) { CDataObject *mem = (CDataObject *)dst; @@ -2831,7 +2831,7 @@ return -1; } - result = _CData_set(mem, type, setfunc, value, + result = _PyCData_set(mem, type, setfunc, value, size, ptr); if (result == NULL) return -1; @@ -2845,7 +2845,7 @@ /******************************************************************/ static PyObject * -GenericCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { CDataObject *obj; StgDictObject *dict; @@ -2867,7 +2867,7 @@ obj->b_objects = NULL; obj->b_length = dict->length; - if (-1 == CData_MallocBuffer(obj, dict)) { + if (-1 == PyCData_MallocBuffer(obj, dict)) { Py_DECREF(obj); return NULL; } @@ -2875,11 +2875,11 @@ } /*****************************************************************/ /* - CFuncPtr_Type + PyCFuncPtr_Type */ static int -CFuncPtr_set_errcheck(CFuncPtrObject *self, PyObject *ob) +PyCFuncPtr_set_errcheck(PyCFuncPtrObject *self, PyObject *ob) { if (ob && !PyCallable_Check(ob)) { PyErr_SetString(PyExc_TypeError, @@ -2893,7 +2893,7 @@ } static PyObject * -CFuncPtr_get_errcheck(CFuncPtrObject *self) +PyCFuncPtr_get_errcheck(PyCFuncPtrObject *self) { if (self->errcheck) { Py_INCREF(self->errcheck); @@ -2904,7 +2904,7 @@ } static int -CFuncPtr_set_restype(CFuncPtrObject *self, PyObject *ob) +PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob) { if (ob == NULL) { Py_XDECREF(self->restype); @@ -2929,7 +2929,7 @@ } static PyObject * -CFuncPtr_get_restype(CFuncPtrObject *self) +PyCFuncPtr_get_restype(PyCFuncPtrObject *self) { StgDictObject *dict; if (self->restype) { @@ -2937,7 +2937,7 @@ return self->restype; } dict = PyObject_stgdict((PyObject *)self); - assert(dict); /* Cannot be NULL for CFuncPtrObject instances */ + assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */ if (dict->restype) { Py_INCREF(dict->restype); return dict->restype; @@ -2948,7 +2948,7 @@ } static int -CFuncPtr_set_argtypes(CFuncPtrObject *self, PyObject *ob) +PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob) { PyObject *converters; @@ -2971,7 +2971,7 @@ } static PyObject * -CFuncPtr_get_argtypes(CFuncPtrObject *self) +PyCFuncPtr_get_argtypes(PyCFuncPtrObject *self) { StgDictObject *dict; if (self->argtypes) { @@ -2979,7 +2979,7 @@ return self->argtypes; } dict = PyObject_stgdict((PyObject *)self); - assert(dict); /* Cannot be NULL for CFuncPtrObject instances */ + assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */ if (dict->argtypes) { Py_INCREF(dict->argtypes); return dict->argtypes; @@ -2989,13 +2989,13 @@ } } -static PyGetSetDef CFuncPtr_getsets[] = { - { "errcheck", (getter)CFuncPtr_get_errcheck, (setter)CFuncPtr_set_errcheck, +static PyGetSetDef PyCFuncPtr_getsets[] = { + { "errcheck", (getter)PyCFuncPtr_get_errcheck, (setter)PyCFuncPtr_set_errcheck, "a function to check for errors", NULL }, - { "restype", (getter)CFuncPtr_get_restype, (setter)CFuncPtr_set_restype, + { "restype", (getter)PyCFuncPtr_get_restype, (setter)PyCFuncPtr_set_restype, "specify the result type", NULL }, - { "argtypes", (getter)CFuncPtr_get_argtypes, - (setter)CFuncPtr_set_argtypes, + { "argtypes", (getter)PyCFuncPtr_get_argtypes, + (setter)PyCFuncPtr_set_argtypes, "specify the argument types", NULL }, { NULL, NULL } }; @@ -3050,10 +3050,10 @@ { StgDictObject *dict; - if (PointerTypeObject_Check(arg)) + if (PyCPointerTypeObject_Check(arg)) return 1; - if (ArrayTypeObject_Check(arg)) + if (PyCArrayTypeObject_Check(arg)) return 1; dict = PyType_stgdict(arg); @@ -3083,7 +3083,7 @@ PyObject *argtypes; dict = PyType_stgdict((PyObject *)type); - assert(dict); /* Cannot be NULL. 'type' is a CFuncPtr type. */ + assert(dict); /* Cannot be NULL. 'type' is a PyCFuncPtr type. */ argtypes = dict->argtypes; if (paramflags == NULL || dict->argtypes == NULL) @@ -3161,13 +3161,13 @@ static PyObject * -CFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds) +PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds) { char *name; int (* address)(void); PyObject *dll; PyObject *obj; - CFuncPtrObject *self; + PyCFuncPtrObject *self; void *handle; PyObject *paramflags = NULL; @@ -3223,7 +3223,7 @@ if (!_validate_paramflags(type, paramflags)) return NULL; - self = (CFuncPtrObject *)GenericCData_new(type, args, kwds); + self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds); if (!self) return NULL; @@ -3245,9 +3245,9 @@ #ifdef MS_WIN32 static PyObject * -CFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds) +PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds) { - CFuncPtrObject *self; + PyCFuncPtrObject *self; int index; char *name = NULL; PyObject *paramflags = NULL; @@ -3262,7 +3262,7 @@ if (!_validate_paramflags(type, paramflags)) return NULL; - self = (CFuncPtrObject *)GenericCData_new(type, args, kwds); + self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds); self->index = index + 0x1000; Py_XINCREF(paramflags); self->paramflags = paramflags; @@ -3273,7 +3273,7 @@ #endif /* - CFuncPtr_new accepts different argument lists in addition to the standard + PyCFuncPtr_new accepts different argument lists in addition to the standard _basespec_ keyword arg: one argument form @@ -3286,22 +3286,22 @@ "is|..." - vtable index, method name, creates callable calling COM vtbl */ static PyObject * -CFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - CFuncPtrObject *self; + PyCFuncPtrObject *self; PyObject *callable; StgDictObject *dict; CThunkObject *thunk; if (PyTuple_GET_SIZE(args) == 0) - return GenericCData_new(type, args, kwds); + return GenericPyCData_new(type, args, kwds); if (1 <= PyTuple_GET_SIZE(args) && PyTuple_Check(PyTuple_GET_ITEM(args, 0))) - return CFuncPtr_FromDll(type, args, kwds); + return PyCFuncPtr_FromDll(type, args, kwds); #ifdef MS_WIN32 if (2 <= PyTuple_GET_SIZE(args) && PyLong_Check(PyTuple_GET_ITEM(args, 0))) - return CFuncPtr_FromVtblIndex(type, args, kwds); + return PyCFuncPtr_FromVtblIndex(type, args, kwds); #endif if (1 == PyTuple_GET_SIZE(args) @@ -3310,7 +3310,7 @@ void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0)); if (ptr == NULL && PyErr_Occurred()) return NULL; - ob = (CDataObject *)GenericCData_new(type, args, kwds); + ob = (CDataObject *)GenericPyCData_new(type, args, kwds); if (ob == NULL) return NULL; *(void **)ob->b_ptr = ptr; @@ -3339,7 +3339,7 @@ */ dict = PyType_stgdict((PyObject *)type); - /* XXXX Fails if we do: 'CFuncPtr(lambda x: x)' */ + /* XXXX Fails if we do: 'PyCFuncPtr(lambda x: x)' */ if (!dict || !dict->argtypes) { PyErr_SetString(PyExc_TypeError, "cannot construct instance of this class:" @@ -3347,14 +3347,14 @@ return NULL; } - thunk = AllocFunctionCallback(callable, + thunk = _ctypes_alloc_callback(callable, dict->argtypes, dict->restype, dict->flags); if (!thunk) return NULL; - self = (CFuncPtrObject *)GenericCData_new(type, args, kwds); + self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds); if (self == NULL) { Py_DECREF(thunk); return NULL; @@ -3388,7 +3388,7 @@ return NULL; } - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) { Py_DECREF(obj); return NULL; @@ -3450,7 +3450,7 @@ function. */ static PyObject * -_build_callargs(CFuncPtrObject *self, PyObject *argtypes, +_build_callargs(PyCFuncPtrObject *self, PyObject *argtypes, PyObject *inargs, PyObject *kwds, int *poutmask, int *pinoutmask, unsigned int *pnumretvals) { @@ -3562,7 +3562,7 @@ ((PyTypeObject *)ob)->tp_name); goto error; } - if (ArrayTypeObject_Check(ob)) + if (PyCArrayTypeObject_Check(ob)) ob = PyObject_CallObject(ob, NULL); else /* Create an instance of the pointed-to type */ @@ -3678,7 +3678,7 @@ } static PyObject * -CFuncPtr_call(CFuncPtrObject *self, PyObject *inargs, PyObject *kwds) +PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds) { PyObject *restype; PyObject *converters; @@ -3697,7 +3697,7 @@ int outmask; unsigned int numretvals; - assert(dict); /* Cannot be NULL for CFuncPtrObject instances */ + assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */ restype = self->restype ? self->restype : dict->restype; converters = self->converters ? self->converters : dict->converters; checker = self->checker ? self->checker : dict->checker; @@ -3774,7 +3774,7 @@ } } - result = _CallProc(pProc, + result = _ctypes_callproc(pProc, callargs, #ifdef MS_WIN32 piunk, @@ -3810,7 +3810,7 @@ } static int -CFuncPtr_traverse(CFuncPtrObject *self, visitproc visit, void *arg) +PyCFuncPtr_traverse(PyCFuncPtrObject *self, visitproc visit, void *arg) { Py_VISIT(self->callable); Py_VISIT(self->restype); @@ -3820,11 +3820,11 @@ Py_VISIT(self->converters); Py_VISIT(self->paramflags); Py_VISIT(self->thunk); - return CData_traverse((CDataObject *)self, visit, arg); + return PyCData_traverse((CDataObject *)self, visit, arg); } static int -CFuncPtr_clear(CFuncPtrObject *self) +PyCFuncPtr_clear(PyCFuncPtrObject *self) { Py_CLEAR(self->callable); Py_CLEAR(self->restype); @@ -3834,18 +3834,18 @@ Py_CLEAR(self->converters); Py_CLEAR(self->paramflags); Py_CLEAR(self->thunk); - return CData_clear((CDataObject *)self); + return PyCData_clear((CDataObject *)self); } static void -CFuncPtr_dealloc(CFuncPtrObject *self) +PyCFuncPtr_dealloc(PyCFuncPtrObject *self) { - CFuncPtr_clear(self); + PyCFuncPtr_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static PyObject * -CFuncPtr_repr(CFuncPtrObject *self) +PyCFuncPtr_repr(PyCFuncPtrObject *self) { #ifdef MS_WIN32 if (self->index) @@ -3860,7 +3860,7 @@ } static int -CFuncPtr_bool(CFuncPtrObject *self) +PyCFuncPtr_bool(PyCFuncPtrObject *self) { return ((*(void **)self->b_ptr != NULL) #ifdef MS_WIN32 @@ -3869,7 +3869,7 @@ ); } -static PyNumberMethods CFuncPtr_as_number = { +static PyNumberMethods PyCFuncPtr_as_number = { 0, /* nb_add */ 0, /* nb_subtract */ 0, /* nb_multiply */ @@ -3879,40 +3879,40 @@ 0, /* nb_negative */ 0, /* nb_positive */ 0, /* nb_absolute */ - (inquiry)CFuncPtr_bool, /* nb_bool */ + (inquiry)PyCFuncPtr_bool, /* nb_bool */ }; -PyTypeObject CFuncPtr_Type = { +PyTypeObject PyCFuncPtr_Type = { PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.CFuncPtr", - sizeof(CFuncPtrObject), /* tp_basicsize */ + "_ctypes.PyCFuncPtr", + sizeof(PyCFuncPtrObject), /* tp_basicsize */ 0, /* tp_itemsize */ - (destructor)CFuncPtr_dealloc, /* tp_dealloc */ + (destructor)PyCFuncPtr_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ - (reprfunc)CFuncPtr_repr, /* tp_repr */ - &CFuncPtr_as_number, /* tp_as_number */ + (reprfunc)PyCFuncPtr_repr, /* tp_repr */ + &PyCFuncPtr_as_number, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ - (ternaryfunc)CFuncPtr_call, /* tp_call */ + (ternaryfunc)PyCFuncPtr_call, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ - &CData_as_buffer, /* tp_as_buffer */ + &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ "Function Pointer", /* tp_doc */ - (traverseproc)CFuncPtr_traverse, /* tp_traverse */ - (inquiry)CFuncPtr_clear, /* tp_clear */ + (traverseproc)PyCFuncPtr_traverse, /* tp_traverse */ + (inquiry)PyCFuncPtr_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ - CFuncPtr_getsets, /* tp_getset */ + PyCFuncPtr_getsets, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ @@ -3920,7 +3920,7 @@ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - CFuncPtr_new, /* tp_new */ + PyCFuncPtr_new, /* tp_new */ 0, /* tp_free */ }; @@ -4044,11 +4044,11 @@ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ - &CData_as_buffer, /* tp_as_buffer */ + &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ "Structure base class", /* tp_doc */ - (traverseproc)CData_traverse, /* tp_traverse */ - (inquiry)CData_clear, /* tp_clear */ + (traverseproc)PyCData_traverse, /* tp_traverse */ + (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ @@ -4063,7 +4063,7 @@ 0, /* tp_dictoffset */ Struct_init, /* tp_init */ 0, /* tp_alloc */ - GenericCData_new, /* tp_new */ + GenericPyCData_new, /* tp_new */ 0, /* tp_free */ }; @@ -4086,11 +4086,11 @@ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ - &CData_as_buffer, /* tp_as_buffer */ + &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ "Union base class", /* tp_doc */ - (traverseproc)CData_traverse, /* tp_traverse */ - (inquiry)CData_clear, /* tp_clear */ + (traverseproc)PyCData_traverse, /* tp_traverse */ + (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ @@ -4105,14 +4105,14 @@ 0, /* tp_dictoffset */ Struct_init, /* tp_init */ 0, /* tp_alloc */ - GenericCData_new, /* tp_new */ + GenericPyCData_new, /* tp_new */ 0, /* tp_free */ }; /******************************************************************/ /* - Array_Type + PyCArray_Type */ static int Array_init(CDataObject *self, PyObject *args, PyObject *kw) @@ -4157,7 +4157,7 @@ size = stgdict->size / stgdict->length; offset = index * size; - return CData_get(stgdict->proto, stgdict->getfunc, (PyObject *)self, + return PyCData_get(stgdict->proto, stgdict->getfunc, (PyObject *)self, index, size, self->b_ptr + offset); } @@ -4194,7 +4194,7 @@ assert(itemdict); /* proto is the item type of the array, a ctypes type, so this cannot be NULL */ - if (itemdict->getfunc == getentry("c")->getfunc) { + if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) { char *ptr = (char *)self->b_ptr; char *dest; @@ -4219,7 +4219,7 @@ return np; } #ifdef CTYPES_UNICODE - if (itemdict->getfunc == getentry("u")->getfunc) { + if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { wchar_t *ptr = (wchar_t *)self->b_ptr; wchar_t *dest; @@ -4288,7 +4288,7 @@ offset = index * size; ptr = self->b_ptr + offset; - return CData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value, + return PyCData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value, index, size, ptr); } @@ -4376,7 +4376,7 @@ Array_ass_subscript, }; -PyTypeObject Array_Type = { +PyTypeObject PyCArray_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_ctypes.Array", sizeof(CDataObject), /* tp_basicsize */ @@ -4395,11 +4395,11 @@ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ - &CData_as_buffer, /* tp_as_buffer */ + &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ "XXX to be provided", /* tp_doc */ - (traverseproc)CData_traverse, /* tp_traverse */ - (inquiry)CData_clear, /* tp_clear */ + (traverseproc)PyCData_traverse, /* tp_traverse */ + (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ @@ -4414,12 +4414,12 @@ 0, /* tp_dictoffset */ (initproc)Array_init, /* tp_init */ 0, /* tp_alloc */ - GenericCData_new, /* tp_new */ + GenericPyCData_new, /* tp_new */ 0, /* tp_free */ }; PyObject * -CreateArrayType(PyObject *itemtype, Py_ssize_t length) +PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length) { static PyObject *cache; PyObject *key; @@ -4459,10 +4459,10 @@ ((PyTypeObject *)itemtype)->tp_name, (long)length); #endif - result = PyObject_CallFunction((PyObject *)&ArrayType_Type, + result = PyObject_CallFunction((PyObject *)&PyCArrayType_Type, "U(O){s:n,s:O}", name, - &Array_Type, + &PyCArray_Type, "_length_", length, "_type_", @@ -4538,7 +4538,7 @@ static PyObject * Simple_from_outparm(PyObject *self, PyObject *args) { - if (IsSimpleSubType((PyObject *)Py_TYPE(self))) { + if (_ctypes_simple_instance((PyObject *)Py_TYPE(self))) { Py_INCREF(self); return self; } @@ -4627,11 +4627,11 @@ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ - &CData_as_buffer, /* tp_as_buffer */ + &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ "XXX to be provided", /* tp_doc */ - (traverseproc)CData_traverse, /* tp_traverse */ - (inquiry)CData_clear, /* tp_clear */ + (traverseproc)PyCData_traverse, /* tp_traverse */ + (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ @@ -4646,13 +4646,13 @@ 0, /* tp_dictoffset */ (initproc)Simple_init, /* tp_init */ 0, /* tp_alloc */ - GenericCData_new, /* tp_new */ + GenericPyCData_new, /* tp_new */ 0, /* tp_free */ }; /******************************************************************/ /* - Pointer_Type + PyCPointer_Type */ static PyObject * Pointer_item(PyObject *_self, Py_ssize_t index) @@ -4681,7 +4681,7 @@ size = itemdict->size; offset = index * itemdict->size; - return CData_get(proto, stgdict->getfunc, (PyObject *)self, + return PyCData_get(proto, stgdict->getfunc, (PyObject *)self, index, size, (*(char **)self->b_ptr) + offset); } @@ -4719,7 +4719,7 @@ size = itemdict->size; offset = index * itemdict->size; - return CData_set((PyObject *)self, proto, stgdict->setfunc, value, + return PyCData_set((PyObject *)self, proto, stgdict->setfunc, value, index, size, (*(char **)self->b_ptr) + offset); } @@ -4736,7 +4736,7 @@ stgdict = PyObject_stgdict((PyObject *)self); assert(stgdict); /* Cannot be NULL fr pointer instances */ - return CData_FromBaseObj(stgdict->proto, + return PyCData_FromBaseObj(stgdict->proto, (PyObject *)self, 0, *(void **)self->b_ptr); } @@ -4811,7 +4811,7 @@ "Cannot create instance: has no _type_"); return NULL; } - return GenericCData_new(type, args, kw); + return GenericPyCData_new(type, args, kw); } static PyObject * @@ -4887,7 +4887,7 @@ assert(proto); itemdict = PyType_stgdict(proto); assert(itemdict); - if (itemdict->getfunc == getentry("c")->getfunc) { + if (itemdict->getfunc == _ctypes_get_fielddesc("c")->getfunc) { char *ptr = *(char **)self->b_ptr; char *dest; @@ -4908,7 +4908,7 @@ return np; } #ifdef CTYPES_UNICODE - if (itemdict->getfunc == getentry("u")->getfunc) { + if (itemdict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { wchar_t *ptr = *(wchar_t **)self->b_ptr; wchar_t *dest; @@ -4985,7 +4985,7 @@ (inquiry)Pointer_bool, /* nb_bool */ }; -PyTypeObject Pointer_Type = { +PyTypeObject PyCPointer_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_ctypes._Pointer", sizeof(CDataObject), /* tp_basicsize */ @@ -5004,11 +5004,11 @@ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ - &CData_as_buffer, /* tp_as_buffer */ + &PyCData_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ "XXX to be provided", /* tp_doc */ - (traverseproc)CData_traverse, /* tp_traverse */ - (inquiry)CData_clear, /* tp_clear */ + (traverseproc)PyCData_traverse, /* tp_traverse */ + (inquiry)PyCData_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ @@ -5146,9 +5146,9 @@ { StgDictObject *dict; - if (PointerTypeObject_Check(arg)) + if (PyCPointerTypeObject_Check(arg)) return 1; - if (CFuncPtrTypeObject_Check(arg)) + if (PyCFuncPtrTypeObject_Check(arg)) return 1; dict = PyType_stgdict(arg); if (dict) { @@ -5184,9 +5184,9 @@ */ if (CDataObject_Check(src)) { CDataObject *obj = (CDataObject *)src; - /* CData_GetContainer will initialize src.b_objects, we need + /* PyCData_GetContainer will initialize src.b_objects, we need this so it can be shared */ - CData_GetContainer(obj); + PyCData_GetContainer(obj); /* But we need a dictionary! */ if (obj->b_objects == Py_None) { Py_DECREF(Py_None); @@ -5234,7 +5234,7 @@ "_ctypes", module_docs, -1, - module_methods, + _ctypes_module_methods, NULL, NULL, NULL, @@ -5257,11 +5257,11 @@ if (!m) return NULL; - _pointer_type_cache = PyDict_New(); - if (_pointer_type_cache == NULL) + _ctypes_ptrtype_cache = PyDict_New(); + if (_ctypes_ptrtype_cache == NULL) return NULL; - PyModule_AddObject(m, "_pointer_type_cache", (PyObject *)_pointer_type_cache); + PyModule_AddObject(m, "_pointer_type_cache", (PyObject *)_ctypes_ptrtype_cache); _unpickle = PyObject_GetAttrString(m, "_unpickle"); if (_unpickle == NULL) @@ -5270,12 +5270,12 @@ if (PyType_Ready(&PyCArg_Type) < 0) return NULL; - if (PyType_Ready(&CThunk_Type) < 0) + if (PyType_Ready(&PyCThunk_Type) < 0) return NULL; /* StgDict is derived from PyDict_Type */ - StgDict_Type.tp_base = &PyDict_Type; - if (PyType_Ready(&StgDict_Type) < 0) + PyCStgDict_Type.tp_base = &PyDict_Type; + if (PyType_Ready(&PyCStgDict_Type) < 0) return NULL; /************************************************* @@ -5283,28 +5283,28 @@ * Metaclasses */ - StructType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&StructType_Type) < 0) + PyCStructType_Type.tp_base = &PyType_Type; + if (PyType_Ready(&PyCStructType_Type) < 0) return NULL; UnionType_Type.tp_base = &PyType_Type; if (PyType_Ready(&UnionType_Type) < 0) return NULL; - PointerType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&PointerType_Type) < 0) + PyCPointerType_Type.tp_base = &PyType_Type; + if (PyType_Ready(&PyCPointerType_Type) < 0) return NULL; - ArrayType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&ArrayType_Type) < 0) + PyCArrayType_Type.tp_base = &PyType_Type; + if (PyType_Ready(&PyCArrayType_Type) < 0) return NULL; - SimpleType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&SimpleType_Type) < 0) + PyCSimpleType_Type.tp_base = &PyType_Type; + if (PyType_Ready(&PyCSimpleType_Type) < 0) return NULL; - CFuncPtrType_Type.tp_base = &PyType_Type; - if (PyType_Ready(&CFuncPtrType_Type) < 0) + PyCFuncPtrType_Type.tp_base = &PyType_Type; + if (PyType_Ready(&PyCFuncPtrType_Type) < 0) return NULL; /************************************************* @@ -5312,52 +5312,52 @@ * Classes using a custom metaclass */ - if (PyType_Ready(&CData_Type) < 0) + if (PyType_Ready(&PyCData_Type) < 0) return NULL; - Py_TYPE(&Struct_Type) = &StructType_Type; - Struct_Type.tp_base = &CData_Type; + Py_TYPE(&Struct_Type) = &PyCStructType_Type; + Struct_Type.tp_base = &PyCData_Type; if (PyType_Ready(&Struct_Type) < 0) return NULL; PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type); Py_TYPE(&Union_Type) = &UnionType_Type; - Union_Type.tp_base = &CData_Type; + Union_Type.tp_base = &PyCData_Type; if (PyType_Ready(&Union_Type) < 0) return NULL; PyModule_AddObject(m, "Union", (PyObject *)&Union_Type); - Py_TYPE(&Pointer_Type) = &PointerType_Type; - Pointer_Type.tp_base = &CData_Type; - if (PyType_Ready(&Pointer_Type) < 0) + Py_TYPE(&PyCPointer_Type) = &PyCPointerType_Type; + PyCPointer_Type.tp_base = &PyCData_Type; + if (PyType_Ready(&PyCPointer_Type) < 0) return NULL; - PyModule_AddObject(m, "_Pointer", (PyObject *)&Pointer_Type); + PyModule_AddObject(m, "_Pointer", (PyObject *)&PyCPointer_Type); - Py_TYPE(&Array_Type) = &ArrayType_Type; - Array_Type.tp_base = &CData_Type; - if (PyType_Ready(&Array_Type) < 0) + Py_TYPE(&PyCArray_Type) = &PyCArrayType_Type; + PyCArray_Type.tp_base = &PyCData_Type; + if (PyType_Ready(&PyCArray_Type) < 0) return NULL; - PyModule_AddObject(m, "Array", (PyObject *)&Array_Type); + PyModule_AddObject(m, "Array", (PyObject *)&PyCArray_Type); - Py_TYPE(&Simple_Type) = &SimpleType_Type; - Simple_Type.tp_base = &CData_Type; + Py_TYPE(&Simple_Type) = &PyCSimpleType_Type; + Simple_Type.tp_base = &PyCData_Type; if (PyType_Ready(&Simple_Type) < 0) return NULL; PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type); - Py_TYPE(&CFuncPtr_Type) = &CFuncPtrType_Type; - CFuncPtr_Type.tp_base = &CData_Type; - if (PyType_Ready(&CFuncPtr_Type) < 0) + Py_TYPE(&PyCFuncPtr_Type) = &PyCFuncPtrType_Type; + PyCFuncPtr_Type.tp_base = &PyCData_Type; + if (PyType_Ready(&PyCFuncPtr_Type) < 0) return NULL; - PyModule_AddObject(m, "CFuncPtr", (PyObject *)&CFuncPtr_Type); + PyModule_AddObject(m, "CFuncPtr", (PyObject *)&PyCFuncPtr_Type); /************************************************* * * Simple classes */ - /* CField_Type is derived from PyBaseObject_Type */ - if (PyType_Ready(&CField_Type) < 0) + /* PyCField_Type is derived from PyBaseObject_Type */ + if (PyType_Ready(&PyCField_Type) < 0) return NULL; /************************************************* Modified: python/branches/py3k/Modules/_ctypes/callbacks.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/callbacks.c (original) +++ python/branches/py3k/Modules/_ctypes/callbacks.c Fri Apr 24 22:50:00 2009 @@ -17,7 +17,7 @@ Py_XDECREF(self->callable); Py_XDECREF(self->restype); if (self->pcl) - FreeClosure(self->pcl); + _ctypes_free_closure(self->pcl); PyObject_Del(self); } @@ -41,7 +41,7 @@ return 0; } -PyTypeObject CThunk_Type = { +PyTypeObject PyCThunk_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_ctypes.CThunkObject", sizeof(CThunkObject), /* tp_basicsize */ @@ -92,7 +92,7 @@ /* after code that pyrex generates */ -void _AddTraceback(char *funcname, char *filename, int lineno) +void _ctypes_add_traceback(char *funcname, char *filename, int lineno) { PyObject *py_srcfile = 0; PyObject *py_funcname = 0; @@ -223,7 +223,7 @@ goto Done; } - if (dict && dict->getfunc && !IsSimpleSubType(cnv)) { + if (dict && dict->getfunc && !_ctypes_simple_instance(cnv)) { PyObject *v = dict->getfunc(*pArgs, dict->size); if (!v) { PrintError("create argument %d:\n", i); @@ -237,7 +237,7 @@ BTW, the same problem occurrs when they are pushed as parameters */ } else if (dict) { - /* Hm, shouldn't we use CData_AtAddress() or something like that instead? */ + /* Hm, shouldn't we use PyCData_AtAddress() or something like that instead? */ CDataObject *obj = (CDataObject *)PyObject_CallFunctionObjArgs(cnv, NULL); if (!obj) { PrintError("create argument %d:\n", i); @@ -268,10 +268,10 @@ } #define CHECK(what, x) \ -if (x == NULL) _AddTraceback(what, "_ctypes/callbacks.c", __LINE__ - 1), PyErr_Print() +if (x == NULL) _ctypes_add_traceback(what, "_ctypes/callbacks.c", __LINE__ - 1), PyErr_Print() if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) { - error_object = get_error_object(&space); + error_object = _ctypes_get_errobj(&space); if (error_object == NULL) goto Done; if (flags & FUNCFLAG_USE_ERRNO) { @@ -328,7 +328,7 @@ PyErr_WriteUnraisable(callable); else if (keep == Py_None) /* Nothing to keep */ Py_DECREF(keep); - else if (setfunc != getentry("O")->setfunc) { + else if (setfunc != _ctypes_get_fielddesc("O")->setfunc) { if (-1 == PyErr_WarnEx(PyExc_RuntimeWarning, "memory leak in callback function.", 1)) @@ -364,7 +364,7 @@ CThunkObject *p; int i; - p = PyObject_NewVar(CThunkObject, &CThunk_Type, nArgs); + p = PyObject_NewVar(CThunkObject, &PyCThunk_Type, nArgs); if (p == NULL) { PyErr_NoMemory(); return NULL; @@ -382,7 +382,7 @@ return p; } -CThunkObject *AllocFunctionCallback(PyObject *callable, +CThunkObject *_ctypes_alloc_callback(PyObject *callable, PyObject *converters, PyObject *restype, int flags) @@ -399,7 +399,7 @@ assert(CThunk_CheckExact((PyObject *)p)); - p->pcl = MallocClosure(); + p->pcl = _ctypes_alloc_closure(); if (p->pcl == NULL) { PyErr_NoMemory(); goto error; @@ -410,7 +410,7 @@ PyObject *cnv = PySequence_GetItem(converters, i); if (cnv == NULL) goto error; - p->atypes[i] = GetType(cnv); + p->atypes[i] = _ctypes_get_ffi_type(cnv); Py_DECREF(cnv); } p->atypes[i] = NULL; @@ -438,7 +438,7 @@ #endif result = ffi_prep_cif(&p->cif, cc, Py_SAFE_DOWNCAST(nArgs, Py_ssize_t, int), - GetType(restype), + _ctypes_get_ffi_type(restype), &p->atypes[0]); if (result != FFI_OK) { PyErr_Format(PyExc_RuntimeError, Modified: python/branches/py3k/Modules/_ctypes/callproc.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/callproc.c (original) +++ python/branches/py3k/Modules/_ctypes/callproc.c Fri Apr 24 22:50:00 2009 @@ -15,7 +15,7 @@ /* How are functions called, and how are parameters converted to C ? - 1. _ctypes.c::CFuncPtr_call receives an argument tuple 'inargs' and a + 1. _ctypes.c::PyCFuncPtr_call receives an argument tuple 'inargs' and a keyword dictionary 'kwds'. 2. After several checks, _build_callargs() is called which returns another @@ -27,7 +27,7 @@ the callargs tuple, specifying how to build the return value(s) of the function. - 4. _CallProc is then called with the 'callargs' tuple. _CallProc first + 4. _ctypes_callproc is then called with the 'callargs' tuple. _ctypes_callproc first allocates two arrays. The first is an array of 'struct argument' items, the second array has 'void *' entried. @@ -47,8 +47,8 @@ libffi specific stuff, then it calls ffi_call. So, there are 4 data structures holding processed arguments: - - the inargs tuple (in CFuncPtr_call) - - the callargs tuple (in CFuncPtr_call) + - the inargs tuple (in PyCFuncPtr_call) + - the callargs tuple (in PyCFuncPtr_call) - the 'struct argguments' array - the 'void *' array @@ -113,7 +113,7 @@ kept alive in the thread state dictionary as long as the thread itself. */ PyObject * -get_error_object(int **pspace) +_ctypes_get_errobj(int **pspace) { PyObject *dict = PyThreadState_GetDict(); PyObject *errobj; @@ -153,7 +153,7 @@ get_error_internal(PyObject *self, PyObject *args, int index) { int *space; - PyObject *errobj = get_error_object(&space); + PyObject *errobj = _ctypes_get_errobj(&space); PyObject *result; if (errobj == NULL) @@ -172,7 +172,7 @@ if (!PyArg_ParseTuple(args, "i", &new_errno)) return NULL; - errobj = get_error_object(&space); + errobj = _ctypes_get_errobj(&space); if (errobj == NULL) return NULL; old_errno = space[index]; @@ -405,7 +405,7 @@ /**************************************************************/ PyCArgObject * -new_CArgObject(void) +PyCArgObject_new(void) { PyCArgObject *p; p = PyObject_New(PyCArgObject, &PyCArg_Type); @@ -697,7 +697,7 @@ } -ffi_type *GetType(PyObject *obj) +ffi_type *_ctypes_get_ffi_type(PyObject *obj) { StgDictObject *dict; if (obj == NULL) @@ -777,7 +777,7 @@ } if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) { - error_object = get_error_object(&space); + error_object = _ctypes_get_errobj(&space); if (error_object == NULL) return -1; } @@ -895,24 +895,24 @@ if (dict == NULL) return PyObject_CallFunction(restype, "i", *(int *)result); - if (dict->getfunc && !IsSimpleSubType(restype)) { + if (dict->getfunc && !_ctypes_simple_instance(restype)) { retval = dict->getfunc(result, dict->size); /* If restype is py_object (detected by comparing getfunc with O_get), we have to call Py_DECREF because O_get has already called Py_INCREF. */ - if (dict->getfunc == getentry("O")->getfunc) { + if (dict->getfunc == _ctypes_get_fielddesc("O")->getfunc) { Py_DECREF(retval); } } else - retval = CData_FromBaseObj(restype, NULL, 0, result); + retval = PyCData_FromBaseObj(restype, NULL, 0, result); if (!checker || !retval) return retval; v = PyObject_CallFunctionObjArgs(checker, retval, NULL); if (v == NULL) - _AddTraceback("GetResult", "_ctypes/callproc.c", __LINE__-2); + _ctypes_add_traceback("GetResult", "_ctypes/callproc.c", __LINE__-2); Py_DECREF(retval); return v; } @@ -921,7 +921,7 @@ * Raise a new exception 'exc_class', adding additional text to the original * exception string. */ -void Extend_Error_Info(PyObject *exc_class, char *fmt, ...) +void _ctypes_extend_error(PyObject *exc_class, char *fmt, ...) { va_list vargs; PyObject *tp, *v, *tb, *s, *cls_str, *msg_str; @@ -1042,7 +1042,7 @@ * * - XXX various requirements for restype, not yet collected */ -PyObject *_CallProc(PPROC pProc, +PyObject *_ctypes_callproc(PPROC pProc, PyObject *argtuple, #ifdef MS_WIN32 IUnknown *pIunk, @@ -1095,7 +1095,7 @@ arg = PyTuple_GET_ITEM(argtuple, i); /* borrowed ref */ /* For cdecl functions, we allow more actual arguments than the length of the argtypes tuple. - This is checked in _ctypes::CFuncPtr_Call + This is checked in _ctypes::PyCFuncPtr_Call */ if (argtypes && argtype_count > i) { PyObject *v; @@ -1104,26 +1104,26 @@ arg, NULL); if (v == NULL) { - Extend_Error_Info(PyExc_ArgError, "argument %d: ", i+1); + _ctypes_extend_error(PyExc_ArgError, "argument %d: ", i+1); goto cleanup; } err = ConvParam(v, i+1, pa); Py_DECREF(v); if (-1 == err) { - Extend_Error_Info(PyExc_ArgError, "argument %d: ", i+1); + _ctypes_extend_error(PyExc_ArgError, "argument %d: ", i+1); goto cleanup; } } else { err = ConvParam(arg, i+1, pa); if (-1 == err) { - Extend_Error_Info(PyExc_ArgError, "argument %d: ", i+1); + _ctypes_extend_error(PyExc_ArgError, "argument %d: ", i+1); goto cleanup; /* leaking ? */ } } } - rtype = GetType(restype); + rtype = _ctypes_get_ffi_type(restype); resbuf = alloca(max(rtype->size, sizeof(ffi_arg))); avalues = (void **)alloca(sizeof(void *) * argcount); @@ -1310,7 +1310,7 @@ pIunk = (IUnknown *)(*(void **)(pcom->b_ptr)); lpVtbl = (PPROC *)(pIunk->lpVtbl); - result = _CallProc(lpVtbl[index], + result = _ctypes_callproc(lpVtbl[index], arguments, #ifdef MS_WIN32 pIunk, @@ -1433,7 +1433,7 @@ &PyTuple_Type, &arguments)) return NULL; - result = _CallProc((PPROC)func, + result = _ctypes_callproc((PPROC)func, arguments, #ifdef MS_WIN32 NULL, @@ -1464,7 +1464,7 @@ &PyTuple_Type, &arguments)) return NULL; - result = _CallProc((PPROC)func, + result = _ctypes_callproc((PPROC)func, arguments, #ifdef MS_WIN32 NULL, @@ -1556,7 +1556,7 @@ return NULL; } - parg = new_CArgObject(); + parg = PyCArgObject_new(); if (parg == NULL) return NULL; @@ -1631,17 +1631,17 @@ if (!PyArg_ParseTuple(args, "zs:set_conversion_mode", &coding, &mode)) return NULL; - result = Py_BuildValue("(zz)", conversion_mode_encoding, conversion_mode_errors); + result = Py_BuildValue("(zz)", _ctypes_conversion_encoding, _ctypes_conversion_errors); if (coding) { - PyMem_Free(conversion_mode_encoding); - conversion_mode_encoding = PyMem_Malloc(strlen(coding) + 1); - strcpy(conversion_mode_encoding, coding); + PyMem_Free(_ctypes_conversion_encoding); + _ctypes_conversion_encoding = PyMem_Malloc(strlen(coding) + 1); + strcpy(_ctypes_conversion_encoding, coding); } else { - conversion_mode_encoding = NULL; + _ctypes_conversion_encoding = NULL; } - PyMem_Free(conversion_mode_errors); - conversion_mode_errors = PyMem_Malloc(strlen(mode) + 1); - strcpy(conversion_mode_errors, mode); + PyMem_Free(_ctypes_conversion_errors); + _ctypes_conversion_errors = PyMem_Malloc(strlen(mode) + 1); + strcpy(_ctypes_conversion_errors, mode); return result; } #endif @@ -1732,7 +1732,7 @@ PyObject *key; char *buf; - result = PyDict_GetItem(_pointer_type_cache, cls); + result = PyDict_GetItem(_ctypes_ptrtype_cache, cls); if (result) { Py_INCREF(result); return result; @@ -1741,10 +1741,10 @@ char *name = _PyUnicode_AsString(cls); buf = alloca(strlen(name) + 3 + 1); sprintf(buf, "LP_%s", name); - result = PyObject_CallFunction((PyObject *)Py_TYPE(&Pointer_Type), + result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type), "s(O){}", buf, - &Pointer_Type); + &PyCPointer_Type); if (result == NULL) return result; key = PyLong_FromVoidPtr(result); @@ -1752,10 +1752,10 @@ typ = (PyTypeObject *)cls; buf = alloca(strlen(typ->tp_name) + 3 + 1); sprintf(buf, "LP_%s", typ->tp_name); - result = PyObject_CallFunction((PyObject *)Py_TYPE(&Pointer_Type), + result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type), "s(O){sO}", buf, - &Pointer_Type, + &PyCPointer_Type, "_type_", cls); if (result == NULL) return result; @@ -1765,7 +1765,7 @@ PyErr_SetString(PyExc_TypeError, "must be a ctypes type"); return NULL; } - if (-1 == PyDict_SetItem(_pointer_type_cache, key, result)) { + if (-1 == PyDict_SetItem(_ctypes_ptrtype_cache, key, result)) { Py_DECREF(result); Py_DECREF(key); return NULL; @@ -1780,7 +1780,7 @@ PyObject *result; PyObject *typ; - typ = PyDict_GetItem(_pointer_type_cache, (PyObject *)Py_TYPE(arg)); + typ = PyDict_GetItem(_ctypes_ptrtype_cache, (PyObject *)Py_TYPE(arg)); if (typ) return PyObject_CallFunctionObjArgs(typ, arg, NULL); typ = POINTER(NULL, (PyObject *)Py_TYPE(arg)); @@ -1818,7 +1818,7 @@ return Py_BuildValue("siN", dict->format, dict->ndim, shape); } -PyMethodDef module_methods[] = { +PyMethodDef _ctypes_module_methods[] = { {"get_errno", get_errno, METH_NOARGS}, {"set_errno", set_errno, METH_VARARGS}, {"POINTER", POINTER, METH_O }, Modified: python/branches/py3k/Modules/_ctypes/cfield.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/cfield.c (original) +++ python/branches/py3k/Modules/_ctypes/cfield.c Fri Apr 24 22:50:00 2009 @@ -8,10 +8,10 @@ /******************************************************************/ /* - CField_Type + PyCField_Type */ static PyObject * -CField_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +PyCField_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { CFieldObject *obj; obj = (CFieldObject *)type->tp_alloc(type, 0); @@ -31,7 +31,7 @@ * prev_desc points to the type of the previous bitfield, if any. */ PyObject * -CField_FromDesc(PyObject *desc, Py_ssize_t index, +PyCField_FromDesc(PyObject *desc, Py_ssize_t index, Py_ssize_t *pfield_size, int bitsize, int *pbitofs, Py_ssize_t *psize, Py_ssize_t *poffset, Py_ssize_t *palign, int pack, int big_endian) @@ -48,7 +48,7 @@ #define CONT_BITFIELD 2 #define EXPAND_BITFIELD 3 - self = (CFieldObject *)PyObject_CallObject((PyObject *)&CField_Type, + self = (CFieldObject *)PyObject_CallObject((PyObject *)&PyCField_Type, NULL); if (self == NULL) return NULL; @@ -98,7 +98,7 @@ /* Field descriptors for 'c_char * n' are be scpecial cased to return a Python string instead of an Array object instance... */ - if (ArrayTypeObject_Check(proto)) { + if (PyCArrayTypeObject_Check(proto)) { StgDictObject *adict = PyType_stgdict(proto); StgDictObject *idict; if (adict && adict->proto) { @@ -109,14 +109,14 @@ Py_DECREF(self); return NULL; } - if (idict->getfunc == getentry("c")->getfunc) { - struct fielddesc *fd = getentry("s"); + if (idict->getfunc == _ctypes_get_fielddesc("c")->getfunc) { + struct fielddesc *fd = _ctypes_get_fielddesc("s"); getfunc = fd->getfunc; setfunc = fd->setfunc; } #ifdef CTYPES_UNICODE - if (idict->getfunc == getentry("u")->getfunc) { - struct fielddesc *fd = getentry("U"); + if (idict->getfunc == _ctypes_get_fielddesc("u")->getfunc) { + struct fielddesc *fd = _ctypes_get_fielddesc("U"); getfunc = fd->getfunc; setfunc = fd->setfunc; } @@ -190,7 +190,7 @@ } static int -CField_set(CFieldObject *self, PyObject *inst, PyObject *value) +PyCField_set(CFieldObject *self, PyObject *inst, PyObject *value) { CDataObject *dst; char *ptr; @@ -202,12 +202,12 @@ "can't delete attribute"); return -1; } - return CData_set(inst, self->proto, self->setfunc, value, + return PyCData_set(inst, self->proto, self->setfunc, value, self->index, self->size, ptr); } static PyObject * -CField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type) +PyCField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type) { CDataObject *src; if (inst == NULL) { @@ -216,51 +216,51 @@ } assert(CDataObject_Check(inst)); src = (CDataObject *)inst; - return CData_get(self->proto, self->getfunc, inst, + return PyCData_get(self->proto, self->getfunc, inst, self->index, self->size, src->b_ptr + self->offset); } static PyObject * -CField_get_offset(PyObject *self, void *data) +PyCField_get_offset(PyObject *self, void *data) { return PyLong_FromSsize_t(((CFieldObject *)self)->offset); } static PyObject * -CField_get_size(PyObject *self, void *data) +PyCField_get_size(PyObject *self, void *data) { return PyLong_FromSsize_t(((CFieldObject *)self)->size); } -static PyGetSetDef CField_getset[] = { - { "offset", CField_get_offset, NULL, "offset in bytes of this field" }, - { "size", CField_get_size, NULL, "size in bytes of this field" }, +static PyGetSetDef PyCField_getset[] = { + { "offset", PyCField_get_offset, NULL, "offset in bytes of this field" }, + { "size", PyCField_get_size, NULL, "size in bytes of this field" }, { NULL, NULL, NULL, NULL }, }; static int -CField_traverse(CFieldObject *self, visitproc visit, void *arg) +PyCField_traverse(CFieldObject *self, visitproc visit, void *arg) { Py_VISIT(self->proto); return 0; } static int -CField_clear(CFieldObject *self) +PyCField_clear(CFieldObject *self) { Py_CLEAR(self->proto); return 0; } static void -CField_dealloc(PyObject *self) +PyCField_dealloc(PyObject *self) { - CField_clear((CFieldObject *)self); + PyCField_clear((CFieldObject *)self); self->ob_type->tp_free((PyObject *)self); } static PyObject * -CField_repr(CFieldObject *self) +PyCField_repr(CFieldObject *self) { PyObject *result; Py_ssize_t bits = self->size >> 16; @@ -280,17 +280,17 @@ return result; } -PyTypeObject CField_Type = { +PyTypeObject PyCField_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_ctypes.CField", /* tp_name */ sizeof(CFieldObject), /* tp_basicsize */ 0, /* tp_itemsize */ - CField_dealloc, /* tp_dealloc */ + PyCField_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ - (reprfunc)CField_repr, /* tp_repr */ + (reprfunc)PyCField_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ @@ -302,23 +302,23 @@ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ "Structure/Union member", /* tp_doc */ - (traverseproc)CField_traverse, /* tp_traverse */ - (inquiry)CField_clear, /* tp_clear */ + (traverseproc)PyCField_traverse, /* tp_traverse */ + (inquiry)PyCField_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ - CField_getset, /* tp_getset */ + PyCField_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ - (descrgetfunc)CField_get, /* tp_descr_get */ - (descrsetfunc)CField_set, /* tp_descr_set */ + (descrgetfunc)PyCField_get, /* tp_descr_get */ + (descrsetfunc)PyCField_set, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - CField_new, /* tp_new */ + PyCField_new, /* tp_new */ 0, /* tp_free */ }; @@ -1158,8 +1158,8 @@ { if (PyUnicode_Check(value)) { value = PyUnicode_AsEncodedString(value, - conversion_mode_encoding, - conversion_mode_errors); + _ctypes_conversion_encoding, + _ctypes_conversion_errors); if (value == NULL) return NULL; if (PyBytes_GET_SIZE(value) != 1) { @@ -1207,8 +1207,8 @@ Py_ssize_t len; if (PyBytes_Check(value)) { value = PyUnicode_FromEncodedObject(value, - conversion_mode_encoding, - conversion_mode_errors); + _ctypes_conversion_encoding, + _ctypes_conversion_errors); if (!value) return NULL; } else if (!PyUnicode_Check(value)) { @@ -1282,8 +1282,8 @@ if (PyBytes_Check(value)) { value = PyUnicode_FromEncodedObject(value, - conversion_mode_encoding, - conversion_mode_errors); + _ctypes_conversion_encoding, + _ctypes_conversion_errors); if (!value) return NULL; } else if (!PyUnicode_Check(value)) { @@ -1332,8 +1332,8 @@ if (PyUnicode_Check(value)) { value = PyUnicode_AsEncodedString(value, - conversion_mode_encoding, - conversion_mode_errors); + _ctypes_conversion_encoding, + _ctypes_conversion_errors); if (value == NULL) return NULL; assert(PyBytes_Check(value)); @@ -1383,8 +1383,8 @@ return value; } else if (PyUnicode_Check(value)) { PyObject *str = PyUnicode_AsEncodedString(value, - conversion_mode_encoding, - conversion_mode_errors); + _ctypes_conversion_encoding, + _ctypes_conversion_errors); if (str == NULL) return NULL; *(char **)ptr = PyBytes_AS_STRING(str); @@ -1443,8 +1443,8 @@ } if (PyBytes_Check(value)) { value = PyUnicode_FromEncodedObject(value, - conversion_mode_encoding, - conversion_mode_errors); + _ctypes_conversion_encoding, + _ctypes_conversion_errors); if (!value) return NULL; } else if (!PyUnicode_Check(value)) { @@ -1529,8 +1529,8 @@ value = NULL; } else if (PyBytes_Check(value)) { value = PyUnicode_FromEncodedObject(value, - conversion_mode_encoding, - conversion_mode_errors); + _ctypes_conversion_encoding, + _ctypes_conversion_errors); if (!value) return NULL; } else if (PyUnicode_Check(value)) { @@ -1690,7 +1690,7 @@ */ struct fielddesc * -getentry(const char *fmt) +_ctypes_get_fielddesc(const char *fmt) { static int initialized = 0; struct fielddesc *table = formattable; @@ -1699,11 +1699,11 @@ initialized = 1; #ifdef CTYPES_UNICODE if (sizeof(wchar_t) == sizeof(short)) - getentry("u")->pffi_type = &ffi_type_sshort; + _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sshort; else if (sizeof(wchar_t) == sizeof(int)) - getentry("u")->pffi_type = &ffi_type_sint; + _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sint; else if (sizeof(wchar_t) == sizeof(long)) - getentry("u")->pffi_type = &ffi_type_slong; + _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_slong; #endif } Modified: python/branches/py3k/Modules/_ctypes/ctypes.h ============================================================================== --- python/branches/py3k/Modules/_ctypes/ctypes.h (original) +++ python/branches/py3k/Modules/_ctypes/ctypes.h Fri Apr 24 22:50:00 2009 @@ -18,7 +18,7 @@ and this one is not used. Making CDataObject a variable size object would be a better solution, but more -difficult in the presence of CFuncPtrObject. Maybe later. +difficult in the presence of PyCFuncPtrObject. Maybe later. */ union value { char c[16]; @@ -64,8 +64,8 @@ ffi_type *ffi_restype; ffi_type *atypes[1]; } CThunkObject; -extern PyTypeObject CThunk_Type; -#define CThunk_CheckExact(v) ((v)->ob_type == &CThunk_Type) +extern PyTypeObject PyCThunk_Type; +#define CThunk_CheckExact(v) ((v)->ob_type == &PyCThunk_Type) typedef struct { /* First part identical to tagCDataObject */ @@ -96,61 +96,61 @@ GUID *iid; #endif PyObject *paramflags; -} CFuncPtrObject; +} PyCFuncPtrObject; -extern PyTypeObject StgDict_Type; -#define StgDict_CheckExact(v) ((v)->ob_type == &StgDict_Type) -#define StgDict_Check(v) PyObject_TypeCheck(v, &StgDict_Type) +extern PyTypeObject PyCStgDict_Type; +#define PyCStgDict_CheckExact(v) ((v)->ob_type == &PyCStgDict_Type) +#define PyCStgDict_Check(v) PyObject_TypeCheck(v, &PyCStgDict_Type) -extern int StructUnionType_update_stgdict(PyObject *fields, PyObject *type, int isStruct); +extern int PyCStructUnionType_update_stgdict(PyObject *fields, PyObject *type, int isStruct); extern int PyType_stginfo(PyTypeObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength); extern int PyObject_stginfo(PyObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength); -extern PyTypeObject CData_Type; -#define CDataObject_CheckExact(v) ((v)->ob_type == &CData_Type) -#define CDataObject_Check(v) PyObject_TypeCheck(v, &CData_Type) - -extern PyTypeObject SimpleType_Type; -#define SimpleTypeObject_CheckExact(v) ((v)->ob_type == &SimpleType_Type) -#define SimpleTypeObject_Check(v) PyObject_TypeCheck(v, &SimpleType_Type) +extern PyTypeObject PyCData_Type; +#define CDataObject_CheckExact(v) ((v)->ob_type == &PyCData_Type) +#define CDataObject_Check(v) PyObject_TypeCheck(v, &PyCData_Type) + +extern PyTypeObject PyCSimpleType_Type; +#define PyCSimpleTypeObject_CheckExact(v) ((v)->ob_type == &PyCSimpleType_Type) +#define PyCSimpleTypeObject_Check(v) PyObject_TypeCheck(v, &PyCSimpleType_Type) -extern PyTypeObject CField_Type; -extern struct fielddesc *getentry(const char *fmt); +extern PyTypeObject PyCField_Type; +extern struct fielddesc *_ctypes_get_fielddesc(const char *fmt); extern PyObject * -CField_FromDesc(PyObject *desc, Py_ssize_t index, +PyCField_FromDesc(PyObject *desc, Py_ssize_t index, Py_ssize_t *pfield_size, int bitsize, int *pbitofs, Py_ssize_t *psize, Py_ssize_t *poffset, Py_ssize_t *palign, int pack, int is_big_endian); -extern PyObject *CData_AtAddress(PyObject *type, void *buf); -extern PyObject *CData_FromBytes(PyObject *type, char *data, Py_ssize_t length); +extern PyObject *PyCData_AtAddress(PyObject *type, void *buf); +extern PyObject *PyCData_FromBytes(PyObject *type, char *data, Py_ssize_t length); -extern PyTypeObject ArrayType_Type; -extern PyTypeObject Array_Type; -extern PyTypeObject PointerType_Type; -extern PyTypeObject Pointer_Type; -extern PyTypeObject CFuncPtr_Type; -extern PyTypeObject CFuncPtrType_Type; -extern PyTypeObject StructType_Type; - -#define ArrayTypeObject_Check(v) PyObject_TypeCheck(v, &ArrayType_Type) -#define ArrayObject_Check(v) PyObject_TypeCheck(v, &Array_Type) -#define PointerObject_Check(v) PyObject_TypeCheck(v, &Pointer_Type) -#define PointerTypeObject_Check(v) PyObject_TypeCheck(v, &PointerType_Type) -#define CFuncPtrObject_Check(v) PyObject_TypeCheck(v, &CFuncPtr_Type) -#define CFuncPtrTypeObject_Check(v) PyObject_TypeCheck(v, &CFuncPtrType_Type) -#define StructTypeObject_Check(v) PyObject_TypeCheck(v, &StructType_Type) +extern PyTypeObject PyCArrayType_Type; +extern PyTypeObject PyCArray_Type; +extern PyTypeObject PyCPointerType_Type; +extern PyTypeObject PyCPointer_Type; +extern PyTypeObject PyCFuncPtr_Type; +extern PyTypeObject PyCFuncPtrType_Type; +extern PyTypeObject PyCStructType_Type; + +#define PyCArrayTypeObject_Check(v) PyObject_TypeCheck(v, &PyCArrayType_Type) +#define ArrayObject_Check(v) PyObject_TypeCheck(v, &PyCArray_Type) +#define PointerObject_Check(v) PyObject_TypeCheck(v, &PyCPointer_Type) +#define PyCPointerTypeObject_Check(v) PyObject_TypeCheck(v, &PyCPointerType_Type) +#define PyCFuncPtrObject_Check(v) PyObject_TypeCheck(v, &PyCFuncPtr_Type) +#define PyCFuncPtrTypeObject_Check(v) PyObject_TypeCheck(v, &PyCFuncPtrType_Type) +#define PyCStructTypeObject_Check(v) PyObject_TypeCheck(v, &PyCStructType_Type) extern PyObject * -CreateArrayType(PyObject *itemtype, Py_ssize_t length); +PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length); -extern PyMethodDef module_methods[]; +extern PyMethodDef _ctypes_module_methods[]; -extern CThunkObject *AllocFunctionCallback(PyObject *callable, +extern CThunkObject *_ctypes_alloc_callback(PyObject *callable, PyObject *converters, PyObject *restype, int flags); @@ -182,7 +182,7 @@ PyDictObject dict; /* first part identical to PyDictObject */ /* The size and align fields are unneeded, they are in ffi_type as well. As an experiment shows, it's trivial to get rid of them, the only thing to - remember is that in ArrayType_new the ffi_type fields must be filled in - + remember is that in PyCArrayType_new the ffi_type fields must be filled in - so far it was unneeded because libffi doesn't support arrays at all (because they are passed as pointers to function calls anyway). But it's too much risk to change that now, and there are other fields which doen't @@ -197,7 +197,7 @@ GETFUNC getfunc; /* Only for simple objects */ PARAMFUNC paramfunc; - /* Following fields only used by CFuncPtrType_Type instances */ + /* Following fields only used by PyCFuncPtrType_Type instances */ PyObject *argtypes; /* tuple of CDataObjects */ PyObject *converters; /* tuple([t.from_param for t in argtypes]) */ PyObject *restype; /* CDataObject or NULL */ @@ -231,7 +231,7 @@ construction time, or assigns to it later, tp_setattro should update the StgDictObject function to a generic one. - Currently, CFuncPtr types have 'converters' and 'checker' entries in their + Currently, PyCFuncPtr types have 'converters' and 'checker' entries in their type dict. They are only used to cache attributes from other entries, whihc is wrong. @@ -259,11 +259,11 @@ /* May return NULL, but does not set an exception! */ extern StgDictObject *PyObject_stgdict(PyObject *self); -extern int StgDict_clone(StgDictObject *src, StgDictObject *dst); +extern int PyCStgDict_clone(StgDictObject *src, StgDictObject *dst); typedef int(* PPROC)(void); -PyObject *_CallProc(PPROC pProc, +PyObject *_ctypes_callproc(PPROC pProc, PyObject *arguments, #ifdef MS_WIN32 IUnknown *pIUnk, @@ -311,17 +311,17 @@ extern PyTypeObject PyCArg_Type; #define PyCArg_CheckExact(v) ((v)->ob_type == &PyCArg_Type) -extern PyCArgObject *new_CArgObject(void); +extern PyCArgObject *PyCArgObject_new(void); extern PyObject * -CData_get(PyObject *type, GETFUNC getfunc, PyObject *src, +PyCData_get(PyObject *type, GETFUNC getfunc, PyObject *src, Py_ssize_t index, Py_ssize_t size, char *ptr); extern int -CData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, +PyCData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, Py_ssize_t index, Py_ssize_t size, char *ptr); -extern void Extend_Error_Info(PyObject *exc_class, char *fmt, ...); +extern void _ctypes_extend_error(PyObject *exc_class, char *fmt, ...); struct basespec { CDataObject *base; @@ -331,32 +331,31 @@ extern char basespec_string[]; -extern ffi_type *GetType(PyObject *obj); +extern ffi_type *_ctypes_get_ffi_type(PyObject *obj); /* exception classes */ extern PyObject *PyExc_ArgError; -extern char *conversion_mode_encoding; -extern char *conversion_mode_errors; +extern char *_ctypes_conversion_encoding; +extern char *_ctypes_conversion_errors; #if defined(HAVE_WCHAR_H) # define CTYPES_UNICODE #endif -extern void FreeClosure(void *); -extern void *MallocClosure(void); +extern void _ctypes_free_closure(void *); +extern void *_ctypes_alloc_closure(void); -extern void _AddTraceback(char *, char *, int); +extern void _ctypes_add_traceback(char *, char *, int); -extern PyObject *CData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr); -extern char *alloc_format_string(const char *prefix, const char *suffix); +extern PyObject *PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr); +extern char *_ctypes_alloc_format_string(const char *prefix, const char *suffix); -/* XXX better name needed! */ -extern int IsSimpleSubType(PyObject *obj); +extern int _ctypes_simple_instance(PyObject *obj); -extern PyObject *_pointer_type_cache; -PyObject *get_error_object(int **pspace); +extern PyObject *_ctypes_ptrtype_cache; +PyObject *_ctypes_get_errobj(int **pspace); #ifdef MS_WIN32 extern PyObject *ComError; Modified: python/branches/py3k/Modules/_ctypes/malloc_closure.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/malloc_closure.c (original) +++ python/branches/py3k/Modules/_ctypes/malloc_closure.c Fri Apr 24 22:50:00 2009 @@ -89,7 +89,7 @@ /******************************************************************/ /* put the item back into the free list */ -void FreeClosure(void *p) +void _ctypes_free_closure(void *p) { ITEM *item = (ITEM *)p; item->next = free_list; @@ -97,7 +97,7 @@ } /* return one item from the free list, allocating more if needed */ -void *MallocClosure(void) +void *_ctypes_alloc_closure(void) { ITEM *item; if (!free_list) Modified: python/branches/py3k/Modules/_ctypes/stgdict.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/stgdict.c (original) +++ python/branches/py3k/Modules/_ctypes/stgdict.c Fri Apr 24 22:50:00 2009 @@ -17,7 +17,7 @@ * PyDict_SetItem() (ma_lookup is NULL) */ static int -StgDict_init(StgDictObject *self, PyObject *args, PyObject *kwds) +PyCStgDict_init(StgDictObject *self, PyObject *args, PyObject *kwds) { if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0) return -1; @@ -28,7 +28,7 @@ } static int -StgDict_clear(StgDictObject *self) +PyCStgDict_clear(StgDictObject *self) { Py_CLEAR(self->proto); Py_CLEAR(self->argtypes); @@ -39,9 +39,9 @@ } static void -StgDict_dealloc(StgDictObject *self) +PyCStgDict_dealloc(StgDictObject *self) { - StgDict_clear(self); + PyCStgDict_clear(self); PyMem_Free(self->format); PyMem_Free(self->shape); PyMem_Free(self->ffi_type_pointer.elements); @@ -49,12 +49,12 @@ } int -StgDict_clone(StgDictObject *dst, StgDictObject *src) +PyCStgDict_clone(StgDictObject *dst, StgDictObject *src) { char *d, *s; Py_ssize_t size; - StgDict_clear(dst); + PyCStgDict_clear(dst); PyMem_Free(dst->ffi_type_pointer.elements); PyMem_Free(dst->format); dst->format = NULL; @@ -102,12 +102,12 @@ return 0; } -PyTypeObject StgDict_Type = { +PyTypeObject PyCStgDict_Type = { PyVarObject_HEAD_INIT(NULL, 0) "StgDict", sizeof(StgDictObject), 0, - (destructor)StgDict_dealloc, /* tp_dealloc */ + (destructor)PyCStgDict_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -138,7 +138,7 @@ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)StgDict_init, /* tp_init */ + (initproc)PyCStgDict_init, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ 0, /* tp_free */ @@ -153,7 +153,7 @@ if (!PyType_Check(obj)) return NULL; type = (PyTypeObject *)obj; - if (!type->tp_dict || !StgDict_CheckExact(type->tp_dict)) + if (!type->tp_dict || !PyCStgDict_CheckExact(type->tp_dict)) return NULL; return (StgDictObject *)type->tp_dict; } @@ -167,7 +167,7 @@ PyObject_stgdict(PyObject *self) { PyTypeObject *type = self->ob_type; - if (!type->tp_dict || !StgDict_CheckExact(type->tp_dict)) + if (!type->tp_dict || !PyCStgDict_CheckExact(type->tp_dict)) return NULL; return (StgDictObject *)type->tp_dict; } @@ -207,7 +207,7 @@ Py_DECREF(fieldlist); return -1; } - if (Py_TYPE(fdescr) != &CField_Type) { + if (Py_TYPE(fdescr) != &PyCField_Type) { PyErr_SetString(PyExc_TypeError, "unexpected type"); Py_DECREF(fdescr); Py_DECREF(fieldlist); @@ -224,13 +224,13 @@ } continue; } - new_descr = (CFieldObject *)PyObject_CallObject((PyObject *)&CField_Type, NULL); + new_descr = (CFieldObject *)PyObject_CallObject((PyObject *)&PyCField_Type, NULL); if (new_descr == NULL) { Py_DECREF(fdescr); Py_DECREF(fieldlist); return -1; } - assert(Py_TYPE(new_descr) == &CField_Type); + assert(Py_TYPE(new_descr) == &PyCField_Type); new_descr->size = fdescr->size; new_descr->offset = fdescr->offset + offset; new_descr->index = fdescr->index + index; @@ -278,7 +278,7 @@ Py_DECREF(anon_names); return -1; } - assert(Py_TYPE(descr) == &CField_Type); + assert(Py_TYPE(descr) == &PyCField_Type); descr->anonymous = 1; /* descr is in the field descriptor. */ @@ -301,7 +301,7 @@ and create an StgDictObject. Used for Structure and Union subclasses. */ int -StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) +PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) { StgDictObject *stgdict, *basedict; Py_ssize_t len, offset, size, align, i; @@ -410,12 +410,12 @@ assert(stgdict->format == NULL); if (isStruct && !isPacked) { - stgdict->format = alloc_format_string(NULL, "T{"); + stgdict->format = _ctypes_alloc_format_string(NULL, "T{"); } else { /* PEP3118 doesn't support union, or packed structures (well, only standard packing, but we dont support the pep for that). Use 'B' for bytes. */ - stgdict->format = alloc_format_string(NULL, "B"); + stgdict->format = _ctypes_alloc_format_string(NULL, "B"); } #define realdict ((PyObject *)&stgdict->dict) @@ -456,9 +456,9 @@ case FFI_TYPE_SINT8: case FFI_TYPE_SINT16: case FFI_TYPE_SINT32: - if (dict->getfunc != getentry("c")->getfunc + if (dict->getfunc != _ctypes_get_fielddesc("c")->getfunc #ifdef CTYPES_UNICODE - && dict->getfunc != getentry("u")->getfunc + && dict->getfunc != _ctypes_get_fielddesc("u")->getfunc #endif ) break; @@ -488,7 +488,7 @@ sprintf(buf, "%s:%s:", fieldfmt, fieldname); ptr = stgdict->format; - stgdict->format = alloc_format_string(stgdict->format, buf); + stgdict->format = _ctypes_alloc_format_string(stgdict->format, buf); PyMem_Free(ptr); if (stgdict->format == NULL) { @@ -497,7 +497,7 @@ } } if (isStruct) { - prop = CField_FromDesc(desc, i, + prop = PyCField_FromDesc(desc, i, &field_size, bitsize, &bitofs, &size, &offset, &align, pack, big_endian); @@ -505,7 +505,7 @@ size = 0; offset = 0; align = 0; - prop = CField_FromDesc(desc, i, + prop = PyCField_FromDesc(desc, i, &field_size, bitsize, &bitofs, &size, &offset, &align, pack, big_endian); @@ -529,7 +529,7 @@ if (isStruct && !isPacked) { char *ptr = stgdict->format; - stgdict->format = alloc_format_string(stgdict->format, "}"); + stgdict->format = _ctypes_alloc_format_string(stgdict->format, "}"); PyMem_Free(ptr); if (stgdict->format == NULL) return -1; From buildbot at python.org Sat Apr 25 00:16:19 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 24 Apr 2009 22:16:19 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.0 Message-ID: <20090424221619.90D661E401E@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.0/builds/299 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: mark.dickinson,raymond.hettinger BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_ssl make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Sat Apr 25 00:57:27 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 24 Apr 2009 22:57:27 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 3.x Message-ID: <20090424225727.A477E1E4025@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%203.x/builds/680 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: thomas.heller BUILD FAILED: failed test Excerpt from the test logfile: make: *** [buildbottest] Unknown signal 32 sincerely, -The Buildbot From python-checkins at python.org Sat Apr 25 00:59:52 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 25 Apr 2009 00:59:52 +0200 (CEST) Subject: [Python-checkins] r71855 - in python/branches/py3k/Lib: _pyio.py test/test_io.py Message-ID: <20090424225952.3D19D1E4025@bag.python.org> Author: benjamin.peterson Date: Sat Apr 25 00:59:52 2009 New Revision: 71855 Log: readline() args must be an int #3521 Modified: python/branches/py3k/Lib/_pyio.py python/branches/py3k/Lib/test/test_io.py Modified: python/branches/py3k/Lib/_pyio.py ============================================================================== --- python/branches/py3k/Lib/_pyio.py (original) +++ python/branches/py3k/Lib/_pyio.py Sat Apr 25 00:59:52 2009 @@ -460,6 +460,8 @@ return 1 if limit is None: limit = -1 + elif not isinstance(limit, int): + raise TypeError("limit must be an integer") res = bytearray() while limit < 0 or len(res) < limit: b = self.read(nreadahead()) @@ -1741,6 +1743,8 @@ raise ValueError("read from closed file") if limit is None: limit = -1 + elif not isinstance(limit, int): + raise TypeError("limit must be an integer") # Grab all the decoded text (we will rewind any extra bits later). line = self._get_decoded_chars() 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 Sat Apr 25 00:59:52 2009 @@ -319,7 +319,7 @@ f.close() def test_readline(self): - f = io.open(support.TESTFN, "wb") + f = self.open(support.TESTFN, "wb") f.write(b"abc\ndef\nxyzzy\nfoo\x00bar\nanother line") f.close() f = self.open(support.TESTFN, "rb") @@ -329,7 +329,10 @@ self.assertEqual(f.readline(4), b"zzy\n") self.assertEqual(f.readline(), b"foo\x00bar\n") self.assertEqual(f.readline(), b"another line") + self.assertRaises(TypeError, f.readline, 5.3) f.close() + f = self.open(support.TESTFN, "r") + self.assertRaises(TypeError, f.readline, 5.3) def test_raw_bytes_io(self): f = self.BytesIO() From buildbot at python.org Sat Apr 25 01:00:54 2009 From: buildbot at python.org (buildbot at python.org) Date: Fri, 24 Apr 2009 23:00:54 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090424230054.77C3A1E4025@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/294 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: mark.dickinson,raymond.hettinger BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Sat Apr 25 01:05:53 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 25 Apr 2009 01:05:53 +0200 (CEST) Subject: [Python-checkins] r71856 - in python/branches/release30-maint: Include/descrobject.h Include/sliceobject.h Objects/object.c Objects/sliceobject.c Message-ID: <20090424230553.D2D051E4025@bag.python.org> Author: benjamin.peterson Date: Sat Apr 25 01:05:53 2009 New Revision: 71856 Log: Merged revisions 71757 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71757 | benjamin.peterson | 2009-04-19 21:09:13 -0500 (Sun, 19 Apr 2009) | 17 lines Merged revisions 71734,71738-71739 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71734 | benjamin.peterson | 2009-04-18 17:15:26 -0500 (Sat, 18 Apr 2009) | 1 line many more types to initialize (I had to expose some of them) ........ r71738 | benjamin.peterson | 2009-04-18 21:32:42 -0500 (Sat, 18 Apr 2009) | 1 line initialize weakref some weakref types ........ r71739 | benjamin.peterson | 2009-04-18 21:40:43 -0500 (Sat, 18 Apr 2009) | 1 line make errors consistent ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Include/descrobject.h python/branches/release30-maint/Include/sliceobject.h python/branches/release30-maint/Objects/object.c python/branches/release30-maint/Objects/sliceobject.c Modified: python/branches/release30-maint/Include/descrobject.h ============================================================================== --- python/branches/release30-maint/Include/descrobject.h (original) +++ python/branches/release30-maint/Include/descrobject.h Sat Apr 25 01:05:53 2009 @@ -73,6 +73,8 @@ PyAPI_DATA(PyTypeObject) PyMethodDescr_Type; PyAPI_DATA(PyTypeObject) PyWrapperDescr_Type; PyAPI_DATA(PyTypeObject) PyDictProxy_Type; +PyAPI_DATA(PyTypeObject) PyGetSetDescr_Type; +PyAPI_DATA(PyTypeObject) PyMemberDescr_Type; PyAPI_FUNC(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *); PyAPI_FUNC(PyObject *) PyDescr_NewClassMethod(PyTypeObject *, PyMethodDef *); Modified: python/branches/release30-maint/Include/sliceobject.h ============================================================================== --- python/branches/release30-maint/Include/sliceobject.h (original) +++ python/branches/release30-maint/Include/sliceobject.h Sat Apr 25 01:05:53 2009 @@ -25,6 +25,7 @@ } PySliceObject; PyAPI_DATA(PyTypeObject) PySlice_Type; +PyAPI_DATA(PyTypeObject) PyEllipsis_Type; #define PySlice_Check(op) (Py_TYPE(op) == &PySlice_Type) Modified: python/branches/release30-maint/Objects/object.c ============================================================================== --- python/branches/release30-maint/Objects/object.c (original) +++ python/branches/release30-maint/Objects/object.c Sat Apr 25 01:05:53 2009 @@ -3,6 +3,7 @@ #include "Python.h" #include "sliceobject.h" /* For PyEllipsis_Type */ +#include "frameobject.h" #ifdef __cplusplus extern "C" { @@ -1467,17 +1468,23 @@ if (PyType_Ready(&_PyWeakref_RefType) < 0) Py_FatalError("Can't initialize weakref type"); + if (PyType_Ready(&_PyWeakref_CallableProxyType) < 0) + Py_FatalError("Can't initialize callable weakref proxy type"); + + if (PyType_Ready(&_PyWeakref_ProxyType) < 0) + Py_FatalError("Can't initialize weakref proxy type"); + if (PyType_Ready(&PyBool_Type) < 0) Py_FatalError("Can't initialize bool type"); if (PyType_Ready(&PyByteArray_Type) < 0) - Py_FatalError("Can't initialize bytearray"); + Py_FatalError("Can't initialize bytearray type"); if (PyType_Ready(&PyBytes_Type) < 0) Py_FatalError("Can't initialize 'str'"); if (PyType_Ready(&PyList_Type) < 0) - Py_FatalError("Can't initialize list"); + Py_FatalError("Can't initialize list type"); if (PyType_Ready(&PyNone_Type) < 0) Py_FatalError("Can't initialize None type"); @@ -1515,9 +1522,10 @@ if (PyType_Ready(&PyStaticMethod_Type) < 0) Py_FatalError("Can't initialize static method type"); +#ifndef WITHOUT_COMPLEX if (PyType_Ready(&PyComplex_Type) < 0) Py_FatalError("Can't initialize complex type"); - +#endif if (PyType_Ready(&PyFloat_Type) < 0) Py_FatalError("Can't initialize float type"); @@ -1542,11 +1550,41 @@ if (PyType_Ready(&PyReversed_Type) < 0) Py_FatalError("Can't initialize reversed type"); - if (PyType_Ready(&PyCode_Type) < 0) - Py_FatalError("Can't initialize 'code'"); - if (PyType_Ready(&PyStdPrinter_Type) < 0) Py_FatalError("Can't initialize StdPrinter"); + + if (PyType_Ready(&PyCode_Type) < 0) + Py_FatalError("Can't initialize code type"); + + if (PyType_Ready(&PyFrame_Type) < 0) + Py_FatalError("Can't initialize frame type"); + + if (PyType_Ready(&PyCFunction_Type) < 0) + Py_FatalError("Can't initialize builtin function type"); + + if (PyType_Ready(&PyMethod_Type) < 0) + Py_FatalError("Can't initialize method type"); + + if (PyType_Ready(&PyFunction_Type) < 0) + Py_FatalError("Can't initialize function type"); + + if (PyType_Ready(&PyDictProxy_Type) < 0) + Py_FatalError("Can't initialize dict proxy type"); + + if (PyType_Ready(&PyGen_Type) < 0) + Py_FatalError("Can't initialize generator type"); + + if (PyType_Ready(&PyGetSetDescr_Type) < 0) + Py_FatalError("Can't initialize get-set descriptor type"); + + if (PyType_Ready(&PyWrapperDescr_Type) < 0) + Py_FatalError("Can't initialize wrapper type"); + + if (PyType_Ready(&PyEllipsis_Type) < 0) + Py_FatalError("Can't initialize ellipsis type"); + + if (PyType_Ready(&PyMemberDescr_Type) < 0) + Py_FatalError("Can't initialize member descriptor type"); } Modified: python/branches/release30-maint/Objects/sliceobject.c ============================================================================== --- python/branches/release30-maint/Objects/sliceobject.c (original) +++ python/branches/release30-maint/Objects/sliceobject.c Sat Apr 25 01:05:53 2009 @@ -22,7 +22,7 @@ return PyUnicode_FromString("Ellipsis"); } -static PyTypeObject PyEllipsis_Type = { +PyTypeObject PyEllipsis_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "ellipsis", /* tp_name */ 0, /* tp_basicsize */ From python-checkins at python.org Sat Apr 25 01:14:51 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 25 Apr 2009 01:14:51 +0200 (CEST) Subject: [Python-checkins] r71857 - python/branches/py3k/Lib/test/test_io.py Message-ID: <20090424231451.0CF821E401F@bag.python.org> Author: benjamin.peterson Date: Sat Apr 25 01:14:50 2009 New Revision: 71857 Log: make sure to close files Modified: python/branches/py3k/Lib/test/test_io.py 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 Sat Apr 25 01:14:50 2009 @@ -291,48 +291,42 @@ self.assertEqual(f.read(2), b"x") def test_raw_file_io(self): - f = self.open(support.TESTFN, "wb", buffering=0) - self.assertEqual(f.readable(), False) - self.assertEqual(f.writable(), True) - self.assertEqual(f.seekable(), True) - self.write_ops(f) - f.close() - f = self.open(support.TESTFN, "rb", buffering=0) - self.assertEqual(f.readable(), True) - self.assertEqual(f.writable(), False) - self.assertEqual(f.seekable(), True) - self.read_ops(f) - f.close() + with self.open(support.TESTFN, "wb", buffering=0) as f: + self.assertEqual(f.readable(), False) + self.assertEqual(f.writable(), True) + self.assertEqual(f.seekable(), True) + self.write_ops(f) + with self.open(support.TESTFN, "rb", buffering=0) as f: + self.assertEqual(f.readable(), True) + self.assertEqual(f.writable(), False) + self.assertEqual(f.seekable(), True) + self.read_ops(f) def test_buffered_file_io(self): - f = self.open(support.TESTFN, "wb") - self.assertEqual(f.readable(), False) - self.assertEqual(f.writable(), True) - self.assertEqual(f.seekable(), True) - self.write_ops(f) - f.close() - f = self.open(support.TESTFN, "rb") - self.assertEqual(f.readable(), True) - self.assertEqual(f.writable(), False) - self.assertEqual(f.seekable(), True) - self.read_ops(f, True) - f.close() + with self.open(support.TESTFN, "wb") as f: + self.assertEqual(f.readable(), False) + self.assertEqual(f.writable(), True) + self.assertEqual(f.seekable(), True) + self.write_ops(f) + with self.open(support.TESTFN, "rb") as f: + self.assertEqual(f.readable(), True) + self.assertEqual(f.writable(), False) + self.assertEqual(f.seekable(), True) + self.read_ops(f, True) def test_readline(self): - f = self.open(support.TESTFN, "wb") - f.write(b"abc\ndef\nxyzzy\nfoo\x00bar\nanother line") - f.close() - f = self.open(support.TESTFN, "rb") - self.assertEqual(f.readline(), b"abc\n") - self.assertEqual(f.readline(10), b"def\n") - self.assertEqual(f.readline(2), b"xy") - self.assertEqual(f.readline(4), b"zzy\n") - self.assertEqual(f.readline(), b"foo\x00bar\n") - self.assertEqual(f.readline(), b"another line") - self.assertRaises(TypeError, f.readline, 5.3) - f.close() - f = self.open(support.TESTFN, "r") - self.assertRaises(TypeError, f.readline, 5.3) + with self.open(support.TESTFN, "wb") as f: + f.write(b"abc\ndef\nxyzzy\nfoo\x00bar\nanother line") + with self.open(support.TESTFN, "rb") as f: + self.assertEqual(f.readline(), b"abc\n") + self.assertEqual(f.readline(10), b"def\n") + self.assertEqual(f.readline(2), b"xy") + self.assertEqual(f.readline(4), b"zzy\n") + self.assertEqual(f.readline(), b"foo\x00bar\n") + self.assertEqual(f.readline(), b"another line") + self.assertRaises(TypeError, f.readline, 5.3) + with self.open(support.TESTFN, "r") as f: + self.assertRaises(TypeError, f.readline, 5.3) def test_raw_bytes_io(self): f = self.BytesIO() @@ -407,8 +401,8 @@ f.write(b"xxx") del f self.assertEqual(record, [1, 2, 3]) - f = open(support.TESTFN, "rb") - self.assertEqual(f.read(), b"xxx") + with open(support.TESTFN, "rb") as f: + self.assertEqual(f.read(), b"xxx") def _check_base_destructor(self, base): record = [] @@ -452,22 +446,18 @@ self._check_base_destructor(self.TextIOBase) def test_close_flushes(self): - f = self.open(support.TESTFN, "wb") - f.write(b"xxx") - f.close() - f = self.open(support.TESTFN, "rb") - self.assertEqual(f.read(), b"xxx") - f.close() + with self.open(support.TESTFN, "wb") as f: + f.write(b"xxx") + with self.open(support.TESTFN, "rb") as f: + self.assertEqual(f.read(), b"xxx") def test_array_writes(self): a = array.array('i', range(10)) n = len(a.tostring()) - f = self.open(support.TESTFN, "wb", 0) - self.assertEqual(f.write(a), n) - f.close() - f = self.open(support.TESTFN, "wb") - self.assertEqual(f.write(a), n) - f.close() + with self.open(support.TESTFN, "wb", 0) as f: + self.assertEqual(f.write(a), n) + with self.open(support.TESTFN, "wb") as f: + self.assertEqual(f.write(a), n) def test_closefd(self): self.assertRaises(ValueError, self.open, support.TESTFN, 'w', @@ -792,7 +782,7 @@ f.f = f wr = weakref.ref(f) del f - gc.collect() + support.gc_collect() self.assert_(wr() is None, wr) class PyBufferedReaderTest(BufferedReaderTest): From python-checkins at python.org Sat Apr 25 01:26:21 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 25 Apr 2009 01:26:21 +0200 (CEST) Subject: [Python-checkins] r71858 - python/branches/py3k/Lib/test/test_io.py Message-ID: <20090424232621.DBADC1E401F@bag.python.org> Author: benjamin.peterson Date: Sat Apr 25 01:26:21 2009 New Revision: 71858 Log: only allow ints in readline Modified: python/branches/py3k/Lib/test/test_io.py 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 Sat Apr 25 01:26:21 2009 @@ -400,6 +400,7 @@ f = MyFileIO(support.TESTFN, "wb") f.write(b"xxx") del f + support.gc_collect() self.assertEqual(record, [1, 2, 3]) with open(support.TESTFN, "rb") as f: self.assertEqual(f.read(), b"xxx") @@ -431,6 +432,7 @@ super().flush() f = MyIO() del f + support.gc_collect() self.assertEqual(record, [1, 2, 3]) def test_IOBase_destructor(self): @@ -493,7 +495,7 @@ f.f = f wr = weakref.ref(f) del f - gc.collect() + support.gc_collect() self.assert_(wr() is None, wr) with open(support.TESTFN, "rb") as f: self.assertEqual(f.read(), b"abcxxx") @@ -564,6 +566,7 @@ bufio = MyBufferedIO(rawio) writable = bufio.writable() del bufio + support.gc_collect() if writable: self.assertEqual(record, [1, 2, 3]) else: @@ -921,6 +924,7 @@ bufio = self.tp(writer, 8) bufio.write(b"abc") del bufio + support.gc_collect() self.assertEquals(b"abc", writer._write_stack[0]) def test_truncate(self): @@ -1033,7 +1037,7 @@ f.x = f wr = weakref.ref(f) del f - gc.collect() + support.gc_collect() self.assert_(wr() is None, wr) with open(support.TESTFN, "rb") as f: self.assertEqual(f.read(), b"123xxx") @@ -1631,6 +1635,7 @@ t = self.TextIOWrapper(b, encoding="ascii") t.write("abc") del t + support.gc_collect() self.assertEquals([b"abc"], l) def test_override_destructor(self): @@ -1653,6 +1658,7 @@ b = self.BytesIO() t = MyTextIO(b, encoding="ascii") del t + support.gc_collect() self.assertEqual(record, [1, 2, 3]) def test_error_through_destructor(self): @@ -1948,7 +1954,7 @@ t.x = t wr = weakref.ref(t) del t - gc.collect() + support.gc_collect() self.assert_(wr() is None, wr) with open(support.TESTFN, "rb") as f: self.assertEqual(f.read(), b"456def") @@ -2172,7 +2178,7 @@ b.c = c wr = weakref.ref(c) del c, b - gc.collect() + support.gc_collect() self.assert_(wr() is None, wr) def test_abcs(self): From python-checkins at python.org Sat Apr 25 01:29:56 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 25 Apr 2009 01:29:56 +0200 (CEST) Subject: [Python-checkins] r71859 - python/branches/release30-maint/Lib/io.py Message-ID: <20090424232956.EB8E11E401F@bag.python.org> Author: benjamin.peterson Date: Sat Apr 25 01:29:56 2009 New Revision: 71859 Log: allow only ints in readline Modified: python/branches/release30-maint/Lib/io.py Modified: python/branches/release30-maint/Lib/io.py ============================================================================== --- python/branches/release30-maint/Lib/io.py (original) +++ python/branches/release30-maint/Lib/io.py Sat Apr 25 01:29:56 2009 @@ -505,6 +505,8 @@ return 1 if limit is None: limit = -1 + elif not isinstance(limit, int): + raise TypeError("limit must be an integer") res = bytearray() while limit < 0 or len(res) < limit: b = self.read(nreadahead()) @@ -1752,6 +1754,8 @@ self._checkClosed() if limit is None: limit = -1 + elif not isinstance(limit, int): + raise TypeError("limit must be an integer") # Grab all the decoded text (we will rewind any extra bits later). line = self._get_decoded_chars() From python-checkins at python.org Sat Apr 25 01:31:01 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 25 Apr 2009 01:31:01 +0200 (CEST) Subject: [Python-checkins] r71858 - svn:log Message-ID: <20090424233101.2230B1E401F@bag.python.org> Author: benjamin.peterson Revision: 71858 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -1 +1 @@ -only allow ints in readline \ No newline at end of file +these tests must call gc_collect() for non-refcounting gcs \ No newline at end of file From buildbot at python.org Sat Apr 25 02:31:49 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 00:31:49 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090425003149.260201E4025@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/633 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl,raymond.hettinger,thomas.heller BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_http_cookiejar make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sat Apr 25 02:41:22 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 25 Apr 2009 02:41:22 +0200 (CEST) Subject: [Python-checkins] r71860 - in python/trunk: Lib/test/test_descr.py Misc/NEWS Objects/typeobject.c Message-ID: <20090425004122.965E21E4025@bag.python.org> Author: benjamin.peterson Date: Sat Apr 25 02:41:22 2009 New Revision: 71860 Log: fix a segfault when setting __class__ in __del__ #5283 Modified: python/trunk/Lib/test/test_descr.py python/trunk/Misc/NEWS python/trunk/Objects/typeobject.c Modified: python/trunk/Lib/test/test_descr.py ============================================================================== --- python/trunk/Lib/test/test_descr.py (original) +++ python/trunk/Lib/test/test_descr.py Sat Apr 25 02:41:22 2009 @@ -3003,6 +3003,16 @@ continue cant(cls(), cls2) + # Issue5283: when __class__ changes in __del__, the wrong + # type gets DECREF'd. + class O(object): + pass + class A(object): + def __del__(self): + self.__class__ = O + l = [A() for x in range(100)] + del l + def test_set_dict(self): # Testing __dict__ assignment... class C(object): pass Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Apr 25 02:41:22 2009 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #5283: Setting __class__ in __del__ caused a segfault. + - Issue #5816: complex(repr(z)) now recovers z exactly, even when z involves nans, infs or negative zeros. Modified: python/trunk/Objects/typeobject.c ============================================================================== --- python/trunk/Objects/typeobject.c (original) +++ python/trunk/Objects/typeobject.c Sat Apr 25 02:41:22 2009 @@ -928,6 +928,9 @@ assert(base); } + /* Extract the type again; tp_del may have changed it */ + type = Py_TYPE(self); + /* Call the base tp_dealloc() */ assert(basedealloc); basedealloc(self); @@ -1009,6 +1012,9 @@ } } + /* Extract the type again; tp_del may have changed it */ + type = Py_TYPE(self); + /* Call the base tp_dealloc(); first retrack self if * basedealloc knows about gc. */ From python-checkins at python.org Sat Apr 25 02:44:45 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 25 Apr 2009 02:44:45 +0200 (CEST) Subject: [Python-checkins] r71861 - in python/branches/release26-maint: Lib/test/test_descr.py Misc/NEWS Objects/typeobject.c Message-ID: <20090425004445.2DE241E4025@bag.python.org> Author: benjamin.peterson Date: Sat Apr 25 02:44:44 2009 New Revision: 71861 Log: Merged revisions 71860 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71860 | benjamin.peterson | 2009-04-24 19:41:22 -0500 (Fri, 24 Apr 2009) | 1 line fix a segfault when setting __class__ in __del__ #5283 ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_descr.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Objects/typeobject.c Modified: python/branches/release26-maint/Lib/test/test_descr.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_descr.py (original) +++ python/branches/release26-maint/Lib/test/test_descr.py Sat Apr 25 02:44:44 2009 @@ -2959,6 +2959,16 @@ continue cant(cls(), cls2) + # Issue5283: when __class__ changes in __del__, the wrong + # type gets DECREF'd. + class O(object): + pass + class A(object): + def __del__(self): + self.__class__ = O + l = [A() for x in range(100)] + del l + def test_set_dict(self): # Testing __dict__ assignment... class C(object): pass Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sat Apr 25 02:44:44 2009 @@ -15,6 +15,8 @@ - Issue #5787: object.__getattribute__(some_type, "__bases__") segfaulted on some builtin types. +- Issue #5283: Setting __class__ in __del__ caused a segfault. + - Issue #5759: float() didn't call __float__ on str subclasses. Library Modified: python/branches/release26-maint/Objects/typeobject.c ============================================================================== --- python/branches/release26-maint/Objects/typeobject.c (original) +++ python/branches/release26-maint/Objects/typeobject.c Sat Apr 25 02:44:44 2009 @@ -928,6 +928,9 @@ assert(base); } + /* Extract the type again; tp_del may have changed it */ + type = Py_TYPE(self); + /* Call the base tp_dealloc() */ assert(basedealloc); basedealloc(self); @@ -1009,6 +1012,9 @@ } } + /* Extract the type again; tp_del may have changed it */ + type = Py_TYPE(self); + /* Call the base tp_dealloc(); first retrack self if * basedealloc knows about gc. */ From python-checkins at python.org Sat Apr 25 03:08:45 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 25 Apr 2009 03:08:45 +0200 (CEST) Subject: [Python-checkins] r71862 - in python/branches/py3k: Lib/test/test_descr.py Misc/NEWS Objects/typeobject.c Message-ID: <20090425010845.BAABF1E4081@bag.python.org> Author: benjamin.peterson Date: Sat Apr 25 03:08:45 2009 New Revision: 71862 Log: Merged revisions 71860 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71860 | benjamin.peterson | 2009-04-24 19:41:22 -0500 (Fri, 24 Apr 2009) | 1 line fix a segfault when setting __class__ in __del__ #5283 ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_descr.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/typeobject.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 Sat Apr 25 03:08:45 2009 @@ -2747,6 +2747,16 @@ continue cant(cls(), cls2) + # Issue5283: when __class__ changes in __del__, the wrong + # type gets DECREF'd. + class O(object): + pass + class A(object): + def __del__(self): + self.__class__ = O + l = [A() for x in range(100)] + del l + def test_set_dict(self): # Testing __dict__ assignment... class C(object): pass Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Apr 25 03:08:45 2009 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #5283: Setting __class__ in __del__ caused a segfault. + - Issue #5816: complex(repr(z)) now recovers z exactly, even when z involves nans, infs or negative zeros. Modified: python/branches/py3k/Objects/typeobject.c ============================================================================== --- python/branches/py3k/Objects/typeobject.c (original) +++ python/branches/py3k/Objects/typeobject.c Sat Apr 25 03:08:45 2009 @@ -877,6 +877,9 @@ assert(base); } + /* Extract the type again; tp_del may have changed it */ + type = Py_TYPE(self); + /* Call the base tp_dealloc() */ assert(basedealloc); basedealloc(self); @@ -958,6 +961,9 @@ } } + /* Extract the type again; tp_del may have changed it */ + type = Py_TYPE(self); + /* Call the base tp_dealloc(); first retrack self if * basedealloc knows about gc. */ From ryan at rbftpnetworks.com Fri Apr 24 20:13:37 2009 From: ryan at rbftpnetworks.com (ryan at rbftpnetworks.com) Date: Fri, 24 Apr 2009 19:13:37 +0100 Subject: [Python-checkins] Gaming news link Message-ID: <0139828c6373bd13fadc00a090ebd465@www.list.flyawaysimulation.com> Dear Sir / Madam, We are interested in posting our gaming news and information site on your links section. Our site is GamerBeef.com and can be found at http://www.gamerbeef.com Our site includes daily updated gaming news from all genres and consoles, with focus on PC gaming. We also have a new discussion forum, cheats and screenshots section. We would of course offer a link back to your site in return. Let me know your thoughts. Best Regards, Ryan -- Ryan Barclay Managing Director RBFTP Networks Limited. DDI: +44 (0)870 490 1870 WWW: http://www.rbftpnetworks.com RBFTP Networks Limited Registered in England No 05718807 Registered Office: 68 Aldersbrook Road, London, E12 5DL. From python-checkins at python.org Sat Apr 25 03:37:40 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 25 Apr 2009 03:37:40 +0200 (CEST) Subject: [Python-checkins] r71863 - in python/branches/release30-maint: Lib/test/test_descr.py Misc/NEWS Objects/typeobject.c Message-ID: <20090425013740.A79A81E4025@bag.python.org> Author: benjamin.peterson Date: Sat Apr 25 03:37:40 2009 New Revision: 71863 Log: Merged revisions 71862 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71862 | benjamin.peterson | 2009-04-24 20:08:45 -0500 (Fri, 24 Apr 2009) | 9 lines Merged revisions 71860 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71860 | benjamin.peterson | 2009-04-24 19:41:22 -0500 (Fri, 24 Apr 2009) | 1 line fix a segfault when setting __class__ in __del__ #5283 ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Lib/test/test_descr.py python/branches/release30-maint/Misc/NEWS python/branches/release30-maint/Objects/typeobject.c Modified: python/branches/release30-maint/Lib/test/test_descr.py ============================================================================== --- python/branches/release30-maint/Lib/test/test_descr.py (original) +++ python/branches/release30-maint/Lib/test/test_descr.py Sat Apr 25 03:37:40 2009 @@ -2712,6 +2712,16 @@ continue cant(cls(), cls2) + # Issue5283: when __class__ changes in __del__, the wrong + # type gets DECREF'd. + class O(object): + pass + class A(object): + def __del__(self): + self.__class__ = O + l = [A() for x in range(100)] + del l + def test_set_dict(self): # Testing __dict__ assignment... class C(object): pass Modified: python/branches/release30-maint/Misc/NEWS ============================================================================== --- python/branches/release30-maint/Misc/NEWS (original) +++ python/branches/release30-maint/Misc/NEWS Sat Apr 25 03:37:40 2009 @@ -16,6 +16,8 @@ imp.find_module() were converted to UTF-8 while the path is converted to the default filesystem encoding, causing nonsense. +- Issue #5283: Setting __class__ in __del__ caused a segfault. + - Issue #5759: float() didn't call __float__ on str subclasses. - Issue #5787: object.__getattribute__(some_type, "__bases__") segfaulted on Modified: python/branches/release30-maint/Objects/typeobject.c ============================================================================== --- python/branches/release30-maint/Objects/typeobject.c (original) +++ python/branches/release30-maint/Objects/typeobject.c Sat Apr 25 03:37:40 2009 @@ -877,6 +877,9 @@ assert(base); } + /* Extract the type again; tp_del may have changed it */ + type = Py_TYPE(self); + /* Call the base tp_dealloc() */ assert(basedealloc); basedealloc(self); @@ -958,6 +961,9 @@ } } + /* Extract the type again; tp_del may have changed it */ + type = Py_TYPE(self); + /* Call the base tp_dealloc(); first retrack self if * basedealloc knows about gc. */ From buildbot at python.org Sat Apr 25 03:47:41 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 01:47:41 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 2.6 Message-ID: <20090425014741.41E571E4025@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%202.6/builds/248 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: benjamin.peterson BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From buildbot at python.org Sat Apr 25 07:58:48 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 05:58:48 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090425055848.A83961E4021@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/296 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: benjamin.peterson BUILD FAILED: failed test Excerpt from the test logfile: 3 tests failed: test_distutils test_posix test_subprocess ====================================================================== FAIL: test_get_python_inc (distutils.tests.test_sysconfig.SysconfigTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/distutils/tests/test_sysconfig.py", line 45, in test_get_python_inc self.assert_(os.path.isdir(inc_dir), inc_dir) AssertionError: /home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/Include ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From python-checkins at python.org Sat Apr 25 10:44:39 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 25 Apr 2009 10:44:39 +0200 (CEST) Subject: [Python-checkins] r71864 - tracker/instances/python-dev/scripts/roundup-summary Message-ID: <20090425084439.7A4241E40B8@bag.python.org> Author: martin.v.loewis Date: Sat Apr 25 10:44:39 2009 New Revision: 71864 Log: Issue274: Change Activity Summary dates to year-month-day format. Modified: tracker/instances/python-dev/scripts/roundup-summary Modified: tracker/instances/python-dev/scripts/roundup-summary ============================================================================== --- tracker/instances/python-dev/scripts/roundup-summary (original) +++ tracker/instances/python-dev/scripts/roundup-summary Sat Apr 25 10:44:39 2009 @@ -33,7 +33,7 @@ discussionThreshold = 3 # Date format per time.strftime -dateFormat="%x" #locale-appropriate +dateFormat="%F" # ISO 8601: yyyy-mm-dd ##### END CONFIGURATION; ALSO SEE CUSTOMIZATION BELOW From python-checkins at python.org Sat Apr 25 10:59:43 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 25 Apr 2009 10:59:43 +0200 (CEST) Subject: [Python-checkins] r71865 - in tracker/roundup-src: BUILD.txt CHANGES.txt doc/announcement.txt doc/upgrading.txt roundup/__init__.py roundup/backends/rdbms_common.py roundup/cgi/actions.py roundup/cgi/templating.py roundup/mailer.py setup.py share/roundup/templates/classic/html/issue.item.html share/roundup/templates/classic/html/user.index.html test/test_cgi.py Message-ID: <20090425085943.C83371E4030@bag.python.org> Author: martin.v.loewis Date: Sat Apr 25 10:59:43 2009 New Revision: 71865 Log: Issue #270: Upgrade to 1.4.8. Modified: tracker/roundup-src/BUILD.txt tracker/roundup-src/CHANGES.txt tracker/roundup-src/doc/announcement.txt tracker/roundup-src/doc/upgrading.txt tracker/roundup-src/roundup/__init__.py tracker/roundup-src/roundup/backends/rdbms_common.py tracker/roundup-src/roundup/cgi/actions.py tracker/roundup-src/roundup/cgi/templating.py tracker/roundup-src/roundup/mailer.py tracker/roundup-src/setup.py tracker/roundup-src/share/roundup/templates/classic/html/issue.item.html tracker/roundup-src/share/roundup/templates/classic/html/user.index.html tracker/roundup-src/test/test_cgi.py Modified: tracker/roundup-src/BUILD.txt ============================================================================== --- tracker/roundup-src/BUILD.txt (original) +++ tracker/roundup-src/BUILD.txt Sat Apr 25 10:59:43 2009 @@ -9,7 +9,7 @@ Building and distributing a release of Roundup is done by running: 1. Make sure the unit tests run! "./run_tests.py" -2. Tag the CVS for the release, eg. "cvs tag -R release-0-6-3" +2. XXX "tag" SVN?? 3. Edit roundup/__init__.py and doc/announcement.txt to reflect the new version and appropriate announcements. Add truncated announcement to setup.py description field. Modified: tracker/roundup-src/CHANGES.txt ============================================================================== --- tracker/roundup-src/CHANGES.txt (original) +++ tracker/roundup-src/CHANGES.txt Sat Apr 25 10:59:43 2009 @@ -1,6 +1,24 @@ This file contains the changes to the Roundup system over time. The entries are given with the most recent entry first. +2009-03-?? 1.4.9 (r??) + +Fixes: + +- fixed action taken in response to invalid GET request +- fixed classic tracker template to submit POST requests when appropriate + + +2009-03-18 1.4.8 (r4209) + +Fixes: +- bug introduced into hyperdb filter (issue 2550505) +- bug introduced into CVS export and view (issue 2550529) +- bugs introduced in the migration to the email package (issue 2550531) +- handle bogus pagination values (issue 2550530) +- fix TLS handling with some SMTP servers (issues 2484879 and 1912923) + + 2009-03-13 1.4.7 (r4202) Features: Modified: tracker/roundup-src/doc/announcement.txt ============================================================================== --- tracker/roundup-src/doc/announcement.txt (original) +++ tracker/roundup-src/doc/announcement.txt Sat Apr 25 10:59:43 2009 @@ -1,19 +1,16 @@ -I'm proud to release version 1.4.7 of Roundup. +I'm proud to release version 1.4.8 of Roundup. -1.4.7 is primarily a bugfix release which contains important security -fixes: +This release fixes some regressions: + +- bug introduced into hyperdb filter (issue 2550505) +- bug introduced into CVS export and view (issue 2550529) +- bugs introduced in the migration to the email package (issue 2550531) + +And adds a couple of other fixes: + +- handle bogus pagination values (issue 2550530) +- fix TLS handling with some SMTP servers (issues 2484879 and 1912923) -- a number of security issues were discovered by Daniel Diniz -- EditCSV and ExportCSV altered to include permission checks -- HTTP POST required on actions which alter data -- HTML file uploads served as application/octet-stream -- Handle Unauthorised in file serving correctly -- New item action reject creation of new users -- Item retirement was not being controlled -- Roundup is now compatible with Python 2.6 -- Improved French and German translations -- Improve consistency of item sorting in HTML interface -- Various other small bug fixes, robustification and optimisation Though some new features made it in also: Modified: tracker/roundup-src/doc/upgrading.txt ============================================================================== --- tracker/roundup-src/doc/upgrading.txt (original) +++ tracker/roundup-src/doc/upgrading.txt Sat Apr 25 10:59:43 2009 @@ -13,6 +13,56 @@ .. contents:: +Migrating from 1.4.x to 1.4.9 +============================= + +Fix the "remove" button in issue files and messages lists +--------------------------------------------------------- + +The "remove" button(s) in the issue messages list needs to be altered. Find +the following in your tracker's ``html/issue.item.html`` template:: + + Modified: tracker/instances/python-dev/html/_generic.help.html ============================================================================== --- tracker/instances/python-dev/html/_generic.help.html (original) +++ tracker/instances/python-dev/html/_generic.help.html Sat Apr 25 11:01:13 2009 @@ -93,7 +93,7 @@ @@ -149,7 +149,7 @@ Modified: tracker/instances/python-dev/html/issue.item.html ============================================================================== --- tracker/instances/python-dev/html/issue.item.html (original) +++ tracker/instances/python-dev/html/issue.item.html Sat Apr 25 11:01:13 2009 @@ -216,7 +216,7 @@ tal:attributes="href string:file${file/id}">edit - From python-checkins at python.org Sat Apr 25 11:07:34 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 25 Apr 2009 11:07:34 +0200 (CEST) Subject: [Python-checkins] r71867 - tracker/instances/python-dev/html/page.html Message-ID: <20090425090734.E97D51E402D@bag.python.org> Author: martin.v.loewis Date: Sat Apr 25 11:07:34 2009 New Revision: 71867 Log: Issue 261: Update copyright date to 2009. Modified: tracker/instances/python-dev/html/page.html Modified: tracker/instances/python-dev/html/page.html ============================================================================== --- tracker/instances/python-dev/html/page.html (original) +++ tracker/instances/python-dev/html/page.html Sat Apr 25 11:07:34 2009 @@ -247,7 +247,7 @@ hosting by Upfront Systems / powered by Roundup -Copyright © 1990-2006, Python Software Foundation
+Copyright © 1990-2009, Python Software Foundation
Legal Statements From python-checkins at python.org Sat Apr 25 11:16:11 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 25 Apr 2009 11:16:11 +0200 (CEST) Subject: [Python-checkins] r71868 - in tracker/instances/python-dev: detectors/autonosy.py schema.py Message-ID: <20090425091611.378B31E402D@bag.python.org> Author: martin.v.loewis Date: Sat Apr 25 11:16:11 2009 New Revision: 71868 Log: Issue258: Auto add users as nosy based on components. Added: tracker/instances/python-dev/detectors/autonosy.py (contents, props changed) Modified: tracker/instances/python-dev/schema.py Added: tracker/instances/python-dev/detectors/autonosy.py ============================================================================== --- (empty file) +++ tracker/instances/python-dev/detectors/autonosy.py Sat Apr 25 11:16:11 2009 @@ -0,0 +1,34 @@ +# Auditor to automatically add users as nosy to issues when +# the component field gets set + +# Python 2.3 ... 2.6 compatibility: +from roundup.anypy.sets_ import set + +def autonosy(db, cl, nodeid, newvalues): + + if 'components' not in newvalues: + # Without components, nobody needs to be added as nosy + return + else: + components = newvalues['components'] + + nosy = set() + if 'nosy' in newvalues: + new_nosy = newvalues.get('nosy', []) + new_nosy = [value for value in new_nosy if db.hasnode('user', value)] + nosy |= set(new_nosy) + else: + old_nosy = db.issue.get(nodeid, 'nosy') + nosy |= set(old_nosy) + + for component in components: + users = db.component.get(component, 'add_as_nosy') + nosy |= set(users) + + newvalues['nosy'] = list(nosy) + + +def init(db): + db.issue.audit('create', autonosy) + db.issue.audit('set', autonosy) + Modified: tracker/instances/python-dev/schema.py ============================================================================== --- tracker/instances/python-dev/schema.py (original) +++ tracker/instances/python-dev/schema.py Sat Apr 25 11:16:11 2009 @@ -21,7 +21,8 @@ name=String(), description=String(), order=Number(), - assign_to=Link('user')) + assign_to=Link('user'), + add_as_nosy=Multilink('user')) component.setkey('name') # Version From python-checkins at python.org Sat Apr 25 11:47:00 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 25 Apr 2009 11:47:00 +0200 (CEST) Subject: [Python-checkins] r71869 - in python/trunk: Lib/test/test_complex.py Objects/complexobject.c Message-ID: <20090425094700.AA1CC1E402D@bag.python.org> Author: mark.dickinson Date: Sat Apr 25 11:47:00 2009 New Revision: 71869 Log: Fix typo in complex parsing code; expand tests. Modified: python/trunk/Lib/test/test_complex.py python/trunk/Objects/complexobject.c Modified: python/trunk/Lib/test/test_complex.py ============================================================================== --- python/trunk/Lib/test/test_complex.py (original) +++ python/trunk/Lib/test/test_complex.py Sat Apr 25 11:47:00 2009 @@ -432,10 +432,11 @@ @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), "test requires IEEE 754 doubles") def test_repr_roundtrip(self): - # complex(repr(z)) should recover z exactly, even for complex numbers - # involving an infinity, nan, or negative zero - vals = [0.0, 1e-200, 0.0123, 3.1415, 1e50, INF, NAN] + vals = [0.0, 1e-500, 1e-315, 1e-200, 0.0123, 3.1415, 1e50, INF, NAN] vals += [-v for v in vals] + + # complex(repr(z)) should recover z exactly, even for complex + # numbers involving an infinity, nan, or negative zero for x in vals: for y in vals: z = complex(x, y) @@ -443,6 +444,21 @@ self.assertFloatsAreIdentical(z.real, roundtrip.real) self.assertFloatsAreIdentical(z.imag, roundtrip.imag) + # if we predefine some constants, then eval(repr(z)) should + # also work, except that it might change the sign of zeros + inf, nan = float('inf'), float('nan') + infj, nanj = complex(0.0, inf), complex(0.0, nan) + for x in vals: + for y in vals: + z = complex(x, y) + roundtrip = eval(repr(z)) + # adding 0.0 has no effect beside changing -0.0 to 0.0 + self.assertFloatsAreIdentical(0.0 + z.real, + 0.0 + roundtrip.real) + self.assertFloatsAreIdentical(0.0 + z.imag, + 0.0 + roundtrip.imag) + + def test_main(): test_support.run_unittest(ComplexTest) Modified: python/trunk/Objects/complexobject.c ============================================================================== --- python/trunk/Objects/complexobject.c (original) +++ python/trunk/Objects/complexobject.c Sat Apr 25 11:47:00 2009 @@ -962,7 +962,7 @@ y = PyOS_ascii_strtod(s, &end); if (end == s && errno == ENOMEM) return PyErr_NoMemory(); - if (errno == ERANGE && fabs(z) >= 1.0) + if (errno == ERANGE && fabs(y) >= 1.0) goto overflow; if (end != s) /* j */ From python-checkins at python.org Sat Apr 25 12:11:41 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 25 Apr 2009 12:11:41 +0200 (CEST) Subject: [Python-checkins] r71870 - in python/branches/py3k: Lib/test/test_complex.py Objects/complexobject.c Message-ID: <20090425101141.3544E1E4018@bag.python.org> Author: mark.dickinson Date: Sat Apr 25 12:11:40 2009 New Revision: 71870 Log: Merged revisions 71869 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71869 | mark.dickinson | 2009-04-25 10:47:00 +0100 (Sat, 25 Apr 2009) | 2 lines Fix typo in complex parsing code; expand tests. ........ Modified: python/branches/py3k/ (props changed) 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 Apr 25 12:11:40 2009 @@ -410,10 +410,11 @@ @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), "test requires IEEE 754 doubles") def test_repr_roundtrip(self): - # complex(repr(z)) should recover z exactly, even for complex numbers - # involving an infinity, nan, or negative zero - vals = [0.0, 1e-200, 0.0123, 3.1415, 1e50, INF, NAN] + vals = [0.0, 1e-500, 1e-315, 1e-200, 0.0123, 3.1415, 1e50, INF, NAN] vals += [-v for v in vals] + + # complex(repr(z)) should recover z exactly, even for complex + # numbers involving an infinity, nan, or negative zero for x in vals: for y in vals: z = complex(x, y) @@ -421,6 +422,21 @@ self.assertFloatsAreIdentical(z.real, roundtrip.real) self.assertFloatsAreIdentical(z.imag, roundtrip.imag) + # if we predefine some constants, then eval(repr(z)) should + # also work, except that it might change the sign of zeros + inf, nan = float('inf'), float('nan') + infj, nanj = complex(0.0, inf), complex(0.0, nan) + for x in vals: + for y in vals: + z = complex(x, y) + roundtrip = eval(repr(z)) + # adding 0.0 has no effect beside changing -0.0 to 0.0 + self.assertFloatsAreIdentical(0.0 + z.real, + 0.0 + roundtrip.real) + self.assertFloatsAreIdentical(0.0 + z.imag, + 0.0 + roundtrip.imag) + + def test_main(): support.run_unittest(ComplexTest) Modified: python/branches/py3k/Objects/complexobject.c ============================================================================== --- python/branches/py3k/Objects/complexobject.c (original) +++ python/branches/py3k/Objects/complexobject.c Sat Apr 25 12:11:40 2009 @@ -797,7 +797,7 @@ y = PyOS_ascii_strtod(s, &end); if (end == s && errno == ENOMEM) return PyErr_NoMemory(); - if (errno == ERANGE && fabs(z) >= 1.0) + if (errno == ERANGE && fabs(y) >= 1.0) goto overflow; if (end != s) /* j */ From python-checkins at python.org Sat Apr 25 12:12:24 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 25 Apr 2009 12:12:24 +0200 (CEST) Subject: [Python-checkins] r71871 - python/branches/release26-maint Message-ID: <20090425101224.5BCFC1E4018@bag.python.org> Author: mark.dickinson Date: Sat Apr 25 12:12:24 2009 New Revision: 71871 Log: Blocked revisions 71869 via svnmerge ........ r71869 | mark.dickinson | 2009-04-25 10:47:00 +0100 (Sat, 25 Apr 2009) | 2 lines Fix typo in complex parsing code; expand tests. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sat Apr 25 12:13:19 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 25 Apr 2009 12:13:19 +0200 (CEST) Subject: [Python-checkins] r71872 - python/branches/release30-maint Message-ID: <20090425101319.931861E4018@bag.python.org> Author: mark.dickinson Date: Sat Apr 25 12:13:19 2009 New Revision: 71872 Log: Blocked revisions 71870 via svnmerge ................ r71870 | mark.dickinson | 2009-04-25 11:11:40 +0100 (Sat, 25 Apr 2009) | 9 lines Merged revisions 71869 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71869 | mark.dickinson | 2009-04-25 10:47:00 +0100 (Sat, 25 Apr 2009) | 2 lines Fix typo in complex parsing code; expand tests. ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sat Apr 25 13:15:06 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 13:15:06 +0200 (CEST) Subject: [Python-checkins] r71873 - python/trunk/Doc/c-api/structures.rst Message-ID: <20090425111506.A59A71E4018@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 13:15:06 2009 New Revision: 71873 Log: Reformat prior to expanding. Modified: python/trunk/Doc/c-api/structures.rst Modified: python/trunk/Doc/c-api/structures.rst ============================================================================== --- python/trunk/Doc/c-api/structures.rst (original) +++ python/trunk/Doc/c-api/structures.rst Sat Apr 25 13:15:06 2009 @@ -9,28 +9,29 @@ object types for Python. This section describes these structures and how they are used. -All Python objects ultimately share a small number of fields at the beginning of -the object's representation in memory. These are represented by the -:ctype:`PyObject` and :ctype:`PyVarObject` types, which are defined, in turn, by -the expansions of some macros also used, whether directly or indirectly, in the -definition of all other Python objects. +All Python objects ultimately share a small number of fields at the beginning +of the object's representation in memory. These are represented by the +:ctype:`PyObject` and :ctype:`PyVarObject` types, which are defined, in turn, +by the expansions of some macros also used, whether directly or indirectly, in +the definition of all other Python objects. .. ctype:: PyObject - All object types are extensions of this type. This is a type which contains the - information Python needs to treat a pointer to an object as an object. In a - normal "release" build, it contains only the object's reference count and a - pointer to the corresponding type object. It corresponds to the fields defined - by the expansion of the ``PyObject_HEAD`` macro. + All object types are extensions of this type. This is a type which + contains the information Python needs to treat a pointer to an object as an + object. In a normal "release" build, it contains only the object's + reference count and a pointer to the corresponding type object. It + corresponds to the fields defined by the expansion of the ``PyObject_HEAD`` + macro. .. ctype:: PyVarObject - This is an extension of :ctype:`PyObject` that adds the :attr:`ob_size` field. - This is only used for objects that have some notion of *length*. This type does - not often appear in the Python/C API. It corresponds to the fields defined by - the expansion of the ``PyObject_VAR_HEAD`` macro. + This is an extension of :ctype:`PyObject` that adds the :attr:`ob_size` + field. This is only used for objects that have some notion of *length*. + This type does not often appear in the Python/C API. It corresponds to the + fields defined by the expansion of the ``PyObject_VAR_HEAD`` macro. These macros are used in the definition of :ctype:`PyObject` and :ctype:`PyVarObject`: @@ -40,9 +41,9 @@ This is a macro which expands to the declarations of the fields of the :ctype:`PyObject` type; it is used when declaring new types which represent - objects without a varying length. The specific fields it expands to depend on - the definition of :cmacro:`Py_TRACE_REFS`. By default, that macro is not - defined, and :cmacro:`PyObject_HEAD` expands to:: + objects without a varying length. The specific fields it expands to depend + on the definition of :cmacro:`Py_TRACE_REFS`. By default, that macro is + not defined, and :cmacro:`PyObject_HEAD` expands to:: Py_ssize_t ob_refcnt; PyTypeObject *ob_type; @@ -57,9 +58,9 @@ .. cmacro:: PyObject_VAR_HEAD This is a macro which expands to the declarations of the fields of the - :ctype:`PyVarObject` type; it is used when declaring new types which represent - objects with a length that varies from instance to instance. This macro always - expands to:: + :ctype:`PyVarObject` type; it is used when declaring new types which + represent objects with a length that varies from instance to instance. + This macro always expands to:: PyObject_HEAD Py_ssize_t ob_size; @@ -72,11 +73,12 @@ .. ctype:: PyCFunction - Type of the functions used to implement most Python callables in C. Functions of - this type take two :ctype:`PyObject\*` parameters and return one such value. If - the return value is *NULL*, an exception shall have been set. If not *NULL*, - the return value is interpreted as the return value of the function as exposed - in Python. The function must return a new reference. + Type of the functions used to implement most Python callables in C. + Functions of this type take two :ctype:`PyObject\*` parameters and return + one such value. If the return value is *NULL*, an exception shall have + been set. If not *NULL*, the return value is interpreted as the return + value of the function as exposed in Python. The function must return a new + reference. .. ctype:: PyMethodDef @@ -117,20 +119,21 @@ .. data:: METH_VARARGS This is the typical calling convention, where the methods have the type - :ctype:`PyCFunction`. The function expects two :ctype:`PyObject\*` values. The - first one is the *self* object for methods; for module functions, it has the - value given to :cfunc:`Py_InitModule4` (or *NULL* if :cfunc:`Py_InitModule` was - used). The second parameter (often called *args*) is a tuple object - representing all arguments. This parameter is typically processed using - :cfunc:`PyArg_ParseTuple` or :cfunc:`PyArg_UnpackTuple`. + :ctype:`PyCFunction`. The function expects two :ctype:`PyObject\*` values. + The first one is the *self* object for methods; for module functions, it + has the value given to :cfunc:`Py_InitModule4` (or *NULL* if + :cfunc:`Py_InitModule` was used). The second parameter (often called + *args*) is a tuple object representing all arguments. This parameter is + typically processed using :cfunc:`PyArg_ParseTuple` or + :cfunc:`PyArg_UnpackTuple`. .. data:: METH_KEYWORDS - Methods with these flags must be of type :ctype:`PyCFunctionWithKeywords`. The - function expects three parameters: *self*, *args*, and a dictionary of all the - keyword arguments. The flag is typically combined with :const:`METH_VARARGS`, - and the parameters are typically processed using + Methods with these flags must be of type :ctype:`PyCFunctionWithKeywords`. + The function expects three parameters: *self*, *args*, and a dictionary of + all the keyword arguments. The flag is typically combined with + :const:`METH_VARARGS`, and the parameters are typically processed using :cfunc:`PyArg_ParseTupleAndKeywords`. @@ -139,8 +142,8 @@ Methods without parameters don't need to check whether arguments are given if they are listed with the :const:`METH_NOARGS` flag. They need to be of type :ctype:`PyCFunction`. When used with object methods, the first parameter is - typically named ``self`` and will hold a reference to the object instance. In - all cases the second parameter will be *NULL*. + typically named ``self`` and will hold a reference to the object instance. + In all cases the second parameter will be *NULL*. .. data:: METH_O @@ -154,11 +157,11 @@ .. data:: METH_OLDARGS This calling convention is deprecated. The method must be of type - :ctype:`PyCFunction`. The second argument is *NULL* if no arguments are given, - a single object if exactly one argument is given, and a tuple of objects if more - than one argument is given. There is no way for a function using this - convention to distinguish between a call with multiple arguments and a call with - a tuple as the only argument. + :ctype:`PyCFunction`. The second argument is *NULL* if no arguments are + given, a single object if exactly one argument is given, and a tuple of + objects if more than one argument is given. There is no way for a function + using this convention to distinguish between a call with multiple arguments + and a call with a tuple as the only argument. These two constants are not used to indicate the calling convention but the binding when use with methods of classes. These may not be used for functions @@ -170,9 +173,10 @@ .. index:: builtin: classmethod - The method will be passed the type object as the first parameter rather than an - instance of the type. This is used to create *class methods*, similar to what - is created when using the :func:`classmethod` built-in function. + The method will be passed the type object as the first parameter rather + than an instance of the type. This is used to create *class methods*, + similar to what is created when using the :func:`classmethod` built-in + function. .. versionadded:: 2.3 @@ -181,9 +185,9 @@ .. index:: builtin: staticmethod - The method will be passed *NULL* as the first parameter rather than an instance - of the type. This is used to create *static methods*, similar to what is - created when using the :func:`staticmethod` built-in function. + The method will be passed *NULL* as the first parameter rather than an + instance of the type. This is used to create *static methods*, similar to + what is created when using the :func:`staticmethod` built-in function. .. versionadded:: 2.3 @@ -195,12 +199,13 @@ The method will be loaded in place of existing definitions. Without *METH_COEXIST*, the default is to skip repeated definitions. Since slot - wrappers are loaded before the method table, the existence of a *sq_contains* - slot, for example, would generate a wrapped method named :meth:`__contains__` - and preclude the loading of a corresponding PyCFunction with the same name. - With the flag defined, the PyCFunction will be loaded in place of the wrapper - object and will co-exist with the slot. This is helpful because calls to - PyCFunctions are optimized more than wrapper object calls. + wrappers are loaded before the method table, the existence of a + *sq_contains* slot, for example, would generate a wrapped method named + :meth:`__contains__` and preclude the loading of a corresponding + PyCFunction with the same name. With the flag defined, the PyCFunction + will be loaded in place of the wrapper object and will co-exist with the + slot. This is helpful because calls to PyCFunctions are optimized more + than wrapper object calls. .. versionadded:: 2.4 @@ -269,6 +274,7 @@ .. cfunction:: PyObject* Py_FindMethod(PyMethodDef table[], PyObject *ob, char *name) - Return a bound method object for an extension type implemented in C. This can - be useful in the implementation of a :attr:`tp_getattro` or :attr:`tp_getattr` - handler that does not use the :cfunc:`PyObject_GenericGetAttr` function. + Return a bound method object for an extension type implemented in C. This + can be useful in the implementation of a :attr:`tp_getattro` or + :attr:`tp_getattr` handler that does not use the + :cfunc:`PyObject_GenericGetAttr` function. From python-checkins at python.org Sat Apr 25 13:59:09 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 13:59:09 +0200 (CEST) Subject: [Python-checkins] r71874 - python/trunk/Doc/c-api/structures.rst Message-ID: <20090425115909.66F1F1E4018@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 13:59:09 2009 New Revision: 71874 Log: First attempt to document PyObject_HEAD_INIT and PyVarObject_HEAD_INIT. Modified: python/trunk/Doc/c-api/structures.rst Modified: python/trunk/Doc/c-api/structures.rst ============================================================================== --- python/trunk/Doc/c-api/structures.rst (original) +++ python/trunk/Doc/c-api/structures.rst Sat Apr 25 13:59:09 2009 @@ -68,7 +68,24 @@ Note that :cmacro:`PyObject_HEAD` is part of the expansion, and that its own expansion varies depending on the definition of :cmacro:`Py_TRACE_REFS`. -PyObject_HEAD_INIT + +.. cmacro:: PyObject_HEAD_INIT(type) + + This is a macro which expands to initialization values for a new + :ctype:`PyObject` type. This macro expands to:: + + _PyObject_EXTRA_INIT + 1, type, + + +.. cmacro:: PyVarObject_HEAD_INIT(type, size) + + This is a macro which expands to initialization values for a new + :ctype:`PyVarObject` type, including the :attr:`ob_size` field. + This macro expands to:: + + _PyObject_EXTRA_INIT + 1, type, size, .. ctype:: PyCFunction From python-checkins at python.org Sat Apr 25 14:15:07 2009 From: python-checkins at python.org (walter.doerwald) Date: Sat, 25 Apr 2009 14:15:07 +0200 (CEST) Subject: [Python-checkins] r71875 - in python/trunk: Lib/test/test_support.py Misc/NEWS Message-ID: <20090425121507.C0C8E1E4018@bag.python.org> Author: walter.doerwald Date: Sat Apr 25 14:15:07 2009 New Revision: 71875 Log: Issue #5837: Certain sequences of calls to set() and unset() for support.EnvironmentVarGuard objects restored the environment variables incorrectly on __exit__. Fix this by recording the initial value of each environment variable on the first access in set() or unset(). Modified: python/trunk/Lib/test/test_support.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/test/test_support.py ============================================================================== --- python/trunk/Lib/test/test_support.py (original) +++ python/trunk/Lib/test/test_support.py Sat Apr 25 14:15:07 2009 @@ -532,30 +532,32 @@ a context manager.""" def __init__(self): - self._environ = os.environ - self._unset = set() - self._reset = dict() + self._changed = {} def set(self, envvar, value): - if envvar not in self._environ: - self._unset.add(envvar) - else: - self._reset[envvar] = self._environ[envvar] - self._environ[envvar] = value + # Remember the initial value on the first access + if envvar not in self._changed: + self._changed[envvar] = os.environ.get(envvar) + os.environ[envvar] = value def unset(self, envvar): - if envvar in self._environ: - self._reset[envvar] = self._environ[envvar] - del self._environ[envvar] + # Remember the initial value on the first access + if envvar not in self._changed: + self._changed[envvar] = os.environ.get(envvar) + if envvar in os.environ: + del os.environ[envvar] def __enter__(self): return self def __exit__(self, *ignore_exc): - for envvar, value in self._reset.iteritems(): - self._environ[envvar] = value - for unset in self._unset: - del self._environ[unset] + for (k, v) in self._changed.items(): + if v is None: + if k in os.environ: + del os.environ[k] + else: + os.environ[k] = v + class TransientResource(object): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Apr 25 14:15:07 2009 @@ -875,6 +875,10 @@ - Issue #5083: New 'gui' resource for regrtest. +- Issue #5837: Certain sequences of calls to set() and unset() for + support.EnvironmentVarGuard objects restored the environment variables + incorrectly on __exit__. + What's New in Python 2.6 final ============================== From python-checkins at python.org Sat Apr 25 14:23:49 2009 From: python-checkins at python.org (walter.doerwald) Date: Sat, 25 Apr 2009 14:23:49 +0200 (CEST) Subject: [Python-checkins] r71876 - in python/branches/release26-maint: Lib/test/test_support.py Misc/NEWS Message-ID: <20090425122349.6A04F1E4022@bag.python.org> Author: walter.doerwald Date: Sat Apr 25 14:23:49 2009 New Revision: 71876 Log: Merged revisions 71875 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71875 | walter.doerwald | 2009-04-25 14:15:07 +0200 (Sa, 25 Apr 2009) | 7 lines Issue #5837: Certain sequences of calls to set() and unset() for support.EnvironmentVarGuard objects restored the environment variables incorrectly on __exit__. Fix this by recording the initial value of each environment variable on the first access in set() or unset(). ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_support.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/test/test_support.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_support.py (original) +++ python/branches/release26-maint/Lib/test/test_support.py Sat Apr 25 14:23:49 2009 @@ -454,30 +454,32 @@ a context manager.""" def __init__(self): - self._environ = os.environ - self._unset = set() - self._reset = dict() + self._changed = {} def set(self, envvar, value): - if envvar not in self._environ: - self._unset.add(envvar) - else: - self._reset[envvar] = self._environ[envvar] - self._environ[envvar] = value + # Remember the initial value on the first access + if envvar not in self._changed: + self._changed[envvar] = os.environ.get(envvar) + os.environ[envvar] = value def unset(self, envvar): - if envvar in self._environ: - self._reset[envvar] = self._environ[envvar] - del self._environ[envvar] + # Remember the initial value on the first access + if envvar not in self._changed: + self._changed[envvar] = os.environ.get(envvar) + if envvar in os.environ: + del os.environ[envvar] def __enter__(self): return self def __exit__(self, *ignore_exc): - for envvar, value in self._reset.iteritems(): - self._environ[envvar] = value - for unset in self._unset: - del self._environ[unset] + for (k, v) in self._changed.items(): + if v is None: + if k in os.environ: + del os.environ[k] + else: + os.environ[k] = v + class TransientResource(object): Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sat Apr 25 14:23:49 2009 @@ -32,6 +32,13 @@ dispatcher now has an 'ignore_log_types' attribute for suppressing log messages, which is set to 'warning' by default. +Tests +----- + +- Issue #5837: Certain sequences of calls to set() and unset() for + support.EnvironmentVarGuard objects restored the environment variables + incorrectly on __exit__. + What's New in Python 2.6.2 rc 1 =============================== From python-checkins at python.org Sat Apr 25 14:31:24 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 25 Apr 2009 14:31:24 +0200 (CEST) Subject: [Python-checkins] r71877 - peps/trunk/pep-0383.txt Message-ID: <20090425123124.09C8C1E4018@bag.python.org> Author: martin.v.loewis Date: Sat Apr 25 14:31:23 2009 New Revision: 71877 Log: Add more rationale, as requested by Paul Moore. Modified: peps/trunk/pep-0383.txt Modified: peps/trunk/pep-0383.txt ============================================================================== --- peps/trunk/pep-0383.txt (original) +++ peps/trunk/pep-0383.txt Sat Apr 25 14:31:23 2009 @@ -54,6 +54,11 @@ algorithms, meaning that the data can be converted back to bytes on POSIX systems only if the same encoding is used. +Being able to treat such strings uniformly will allow application +writers to abstract from details specific to the operating system, and +reduces the risk of one API failing when the other API would have +worked. + Specification ============= From python-checkins at python.org Sat Apr 25 14:38:08 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 25 Apr 2009 14:38:08 +0200 (CEST) Subject: [Python-checkins] r71878 - in python/trunk: Lib/distutils/tests/test_util.py Misc/NEWS Message-ID: <20090425123808.9BEAB1E4018@bag.python.org> Author: tarek.ziade Date: Sat Apr 25 14:38:08 2009 New Revision: 71878 Log: Issue #4951: Fixed failure in test_httpservers Modified: python/trunk/Lib/distutils/tests/test_util.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/distutils/tests/test_util.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_util.py (original) +++ python/trunk/Lib/distutils/tests/test_util.py Sat Apr 25 14:38:08 2009 @@ -29,7 +29,7 @@ self.platform = sys.platform self.version = sys.version self.sep = os.sep - self.environ = os.environ + self.environ = dict(os.environ) self.join = os.path.join self.isabs = os.path.isabs self.splitdrive = os.path.splitdrive @@ -51,7 +51,10 @@ sys.platform = self.platform sys.version = self.version os.sep = self.sep - os.environ = self.environ + for k, v in self.environ.items(): + os.environ[k] = v + for k in set(os.environ) - set(self.environ): + del os.environ[k] os.path.join = self.join os.path.isabs = self.isabs os.path.splitdrive = self.splitdrive Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Apr 25 14:38:08 2009 @@ -246,6 +246,8 @@ Library ------- +- Issue #4951: Fixed failure in test_httpservers. + - Issue #3102: All global symbols that the _ctypes extension defines are now prefixed with 'Py' or '_ctypes'. From python-checkins at python.org Sat Apr 25 14:39:56 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 25 Apr 2009 14:39:56 +0200 (CEST) Subject: [Python-checkins] r71879 - in python/branches/py3k: Lib/distutils/tests/test_util.py Misc/NEWS Message-ID: <20090425123956.B203E1E4018@bag.python.org> Author: tarek.ziade Date: Sat Apr 25 14:39:56 2009 New Revision: 71879 Log: Merged revisions 71878 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71878 | tarek.ziade | 2009-04-25 14:38:08 +0200 (Sat, 25 Apr 2009) | 1 line Issue #4951: Fixed failure in test_httpservers ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/tests/test_util.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/distutils/tests/test_util.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_util.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_util.py Sat Apr 25 14:39:56 2009 @@ -29,7 +29,7 @@ self.platform = sys.platform self.version = sys.version self.sep = os.sep - self.environ = os.environ + self.environ = dict(os.environ) self.join = os.path.join self.isabs = os.path.isabs self.splitdrive = os.path.splitdrive @@ -51,7 +51,10 @@ sys.platform = self.platform sys.version = self.version os.sep = self.sep - os.environ = self.environ + for k, v in self.environ.items(): + os.environ[k] = v + for k in set(os.environ) - set(self.environ): + del os.environ[k] os.path.join = self.join os.path.isabs = self.isabs os.path.splitdrive = self.splitdrive Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Apr 25 14:39:56 2009 @@ -437,6 +437,8 @@ Library ------- +- Issue #4951: Fixed failure in test_httpservers. + - Issue #5795: Fixed test_distutils failure on Debian ppc. - Issue #5607: fixed Distutils test_get_platform for Mac OS X fat binaries. From python-checkins at python.org Sat Apr 25 14:44:37 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 25 Apr 2009 14:44:37 +0200 (CEST) Subject: [Python-checkins] r71880 - python/branches/release26-maint Message-ID: <20090425124437.DFA6D1E4018@bag.python.org> Author: tarek.ziade Date: Sat Apr 25 14:44:37 2009 New Revision: 71880 Log: Blocked revisions 71878 via svnmerge ........ r71878 | tarek.ziade | 2009-04-25 14:38:08 +0200 (Sat, 25 Apr 2009) | 1 line Issue #4951: Fixed failure in test_httpservers ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sat Apr 25 14:48:44 2009 From: python-checkins at python.org (walter.doerwald) Date: Sat, 25 Apr 2009 14:48:44 +0200 (CEST) Subject: [Python-checkins] r71881 - in python/branches/py3k: Lib/test/support.py Misc/NEWS Message-ID: <20090425124844.4A0D31E4033@bag.python.org> Author: walter.doerwald Date: Sat Apr 25 14:48:43 2009 New Revision: 71881 Log: Merged revisions 71875 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71875 | walter.doerwald | 2009-04-25 14:15:07 +0200 (Sa, 25 Apr 2009) | 7 lines Issue #5837: Certain sequences of calls to set() and unset() for support.EnvironmentVarGuard objects restored the environment variables incorrectly on __exit__. Fix this by recording the initial value of each environment variable on the first access in set() or unset(). ........ Modified: python/branches/py3k/ (props changed) 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 Sat Apr 25 14:48:43 2009 @@ -516,30 +516,31 @@ a context manager.""" def __init__(self): - self._environ = os.environ - self._unset = set() - self._reset = dict() + self._changed = {} def set(self, envvar, value): - if envvar not in self._environ: - self._unset.add(envvar) - else: - self._reset[envvar] = self._environ[envvar] - self._environ[envvar] = value + # Remember the initial value on the first access + if envvar not in self._changed: + self._changed[envvar] = os.environ.get(envvar) + os.environ[envvar] = value def unset(self, envvar): - if envvar in self._environ: - self._reset[envvar] = self._environ[envvar] - del self._environ[envvar] + # Remember the initial value on the first access + if envvar not in self._changed: + self._changed[envvar] = os.environ.get(envvar) + if envvar in os.environ: + del os.environ[envvar] def __enter__(self): return self def __exit__(self, *ignore_exc): - for envvar, value in self._reset.items(): - self._environ[envvar] = value - for unset in self._unset: - del self._environ[unset] + for (k, v) in self._changed.items(): + if v is None: + if k in os.environ: + del os.environ[k] + else: + os.environ[k] = v class TransientResource(object): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Apr 25 14:48:43 2009 @@ -124,6 +124,10 @@ other modules with both C and Python implementations in the stdlib can be adjusted to use it over time. +- Issue #5837: Certain sequences of calls to set() and unset() for + support.EnvironmentVarGuard objects restored the environment variables + incorrectly on __exit__. + What's New in Python 3.1 alpha 2? ================================= From python-checkins at python.org Sat Apr 25 14:49:10 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 14:49:10 +0200 (CEST) Subject: [Python-checkins] r71882 - in python/trunk/Doc/includes: email-alternative.py email-dir.py email-mime.py email-simple.py Message-ID: <20090425124910.ADE321E4033@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 14:49:10 2009 New Revision: 71882 Log: Issue #4239: adjust email examples not to use connect() and terminate with quit() and not close(). Modified: python/trunk/Doc/includes/email-alternative.py python/trunk/Doc/includes/email-dir.py python/trunk/Doc/includes/email-mime.py python/trunk/Doc/includes/email-simple.py Modified: python/trunk/Doc/includes/email-alternative.py ============================================================================== --- python/trunk/Doc/includes/email-alternative.py (original) +++ python/trunk/Doc/includes/email-alternative.py Sat Apr 25 14:49:10 2009 @@ -45,4 +45,4 @@ # sendmail function takes 3 arguments: sender's address, recipient's address # and message to send - here it is sent as one string. s.sendmail(me, you, msg.as_string()) -s.close() +s.quit() Modified: python/trunk/Doc/includes/email-dir.py ============================================================================== --- python/trunk/Doc/includes/email-dir.py (original) +++ python/trunk/Doc/includes/email-dir.py Sat Apr 25 14:49:10 2009 @@ -106,9 +106,8 @@ fp.close() else: s = smtplib.SMTP() - s.connect() s.sendmail(opts.sender, opts.recipients, composed) - s.close() + s.quit() if __name__ == '__main__': Modified: python/trunk/Doc/includes/email-mime.py ============================================================================== --- python/trunk/Doc/includes/email-mime.py (original) +++ python/trunk/Doc/includes/email-mime.py Sat Apr 25 14:49:10 2009 @@ -27,6 +27,5 @@ # Send the email via our own SMTP server. s = smtplib.SMTP() -s.connect() s.sendmail(me, family, msg.as_string()) -s.close() +s.quit() Modified: python/trunk/Doc/includes/email-simple.py ============================================================================== --- python/trunk/Doc/includes/email-simple.py (original) +++ python/trunk/Doc/includes/email-simple.py Sat Apr 25 14:49:10 2009 @@ -20,6 +20,5 @@ # Send the message via our own SMTP server, but don't include the # envelope header. s = smtplib.SMTP() -s.connect() s.sendmail(me, [you], msg.as_string()) -s.close() +s.quit() From python-checkins at python.org Sat Apr 25 14:51:30 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 25 Apr 2009 14:51:30 +0200 (CEST) Subject: [Python-checkins] r71883 - tracker/instances/python-dev/detectors/autonosy.py Message-ID: <20090425125130.343401E4020@bag.python.org> Author: martin.v.loewis Date: Sat Apr 25 14:51:29 2009 New Revision: 71883 Log: Fix autonosy for new issues. 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 Sat Apr 25 14:51:29 2009 @@ -18,8 +18,9 @@ new_nosy = [value for value in new_nosy if db.hasnode('user', value)] nosy |= set(new_nosy) else: - old_nosy = db.issue.get(nodeid, 'nosy') - nosy |= set(old_nosy) + if nodeid: + old_nosy = db.issue.get(nodeid, 'nosy') + nosy |= set(old_nosy) for component in components: users = db.component.get(component, 'add_as_nosy') From python-checkins at python.org Sat Apr 25 14:51:59 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 25 Apr 2009 14:51:59 +0200 (CEST) Subject: [Python-checkins] r71884 - in python/trunk: Lib/distutils/tests/test_build_scripts.py Misc/NEWS Message-ID: <20090425125159.6C8371E4020@bag.python.org> Author: tarek.ziade Date: Sat Apr 25 14:51:59 2009 New Revision: 71884 Log: #5810: Fixed Distutils test_build_scripts Modified: python/trunk/Lib/distutils/tests/test_build_scripts.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/distutils/tests/test_build_scripts.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_build_scripts.py (original) +++ python/trunk/Lib/distutils/tests/test_build_scripts.py Sat Apr 25 14:51:59 2009 @@ -90,7 +90,7 @@ # On linux-g++-32 with command line `./configure --enable-ipv6 # --with-suffix=3`, python is compiled okay but the build scripts # failed when writing the name of the executable - old = sysconfig._config_vars.get('VERSION') + old = sysconfig.get_config_vars().get('VERSION') sysconfig._config_vars['VERSION'] = 4 try: cmd.run() Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Apr 25 14:51:59 2009 @@ -246,6 +246,9 @@ Library ------- +- Issue #5810: Fixed Distutils test_build_scripts so it uses + sysconfig.get_config_vars. + - Issue #4951: Fixed failure in test_httpservers. - Issue #3102: All global symbols that the _ctypes extension defines From python-checkins at python.org Sat Apr 25 14:53:27 2009 From: python-checkins at python.org (walter.doerwald) Date: Sat, 25 Apr 2009 14:53:27 +0200 (CEST) Subject: [Python-checkins] r71885 - in python/branches/release30-maint: Lib/test/support.py Misc/NEWS Message-ID: <20090425125327.1A5531E4020@bag.python.org> Author: walter.doerwald Date: Sat Apr 25 14:53:26 2009 New Revision: 71885 Log: Merged revisions 71881 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71881 | walter.doerwald | 2009-04-25 14:48:43 +0200 (Sa, 25 Apr 2009) | 14 lines Merged revisions 71875 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71875 | walter.doerwald | 2009-04-25 14:15:07 +0200 (Sa, 25 Apr 2009) | 7 lines Issue #5837: Certain sequences of calls to set() and unset() for support.EnvironmentVarGuard objects restored the environment variables incorrectly on __exit__. Fix this by recording the initial value of each environment variable on the first access in set() or unset(). ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Lib/test/support.py python/branches/release30-maint/Misc/NEWS Modified: python/branches/release30-maint/Lib/test/support.py ============================================================================== --- python/branches/release30-maint/Lib/test/support.py (original) +++ python/branches/release30-maint/Lib/test/support.py Sat Apr 25 14:53:26 2009 @@ -441,30 +441,31 @@ a context manager.""" def __init__(self): - self._environ = os.environ - self._unset = set() - self._reset = dict() + self._changed = {} def set(self, envvar, value): - if envvar not in self._environ: - self._unset.add(envvar) - else: - self._reset[envvar] = self._environ[envvar] - self._environ[envvar] = value + # Remember the initial value on the first access + if envvar not in self._changed: + self._changed[envvar] = os.environ.get(envvar) + os.environ[envvar] = value def unset(self, envvar): - if envvar in self._environ: - self._reset[envvar] = self._environ[envvar] - del self._environ[envvar] + # Remember the initial value on the first access + if envvar not in self._changed: + self._changed[envvar] = os.environ.get(envvar) + if envvar in os.environ: + del os.environ[envvar] def __enter__(self): return self def __exit__(self, *ignore_exc): - for envvar, value in self._reset.items(): - self._environ[envvar] = value - for unset in self._unset: - del self._environ[unset] + for (k, v) in self._changed.items(): + if v is None: + if k in os.environ: + del os.environ[k] + else: + os.environ[k] = v class TransientResource(object): Modified: python/branches/release30-maint/Misc/NEWS ============================================================================== --- python/branches/release30-maint/Misc/NEWS (original) +++ python/branches/release30-maint/Misc/NEWS Sat Apr 25 14:53:26 2009 @@ -119,6 +119,13 @@ - Issue #5359: Readd the Berkley-DB detection code to allow _dbm be built using Berkley-DB. +Tests +----- + +- Issue #5837: Certain sequences of calls to set() and unset() for + support.EnvironmentVarGuard objects restored the environment variables + incorrectly on __exit__. + What's New in Python 3.0.1? =========================== From python-checkins at python.org Sat Apr 25 14:53:56 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 25 Apr 2009 14:53:56 +0200 (CEST) Subject: [Python-checkins] r71886 - in python/branches/py3k: Lib/distutils/tests/test_build_scripts.py Misc/NEWS Message-ID: <20090425125356.BBA561E406F@bag.python.org> Author: tarek.ziade Date: Sat Apr 25 14:53:56 2009 New Revision: 71886 Log: Merged revisions 71884 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71884 | tarek.ziade | 2009-04-25 14:51:59 +0200 (Sat, 25 Apr 2009) | 1 line #5810: Fixed Distutils test_build_scripts ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/tests/test_build_scripts.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/distutils/tests/test_build_scripts.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_build_scripts.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_build_scripts.py Sat Apr 25 14:53:56 2009 @@ -90,7 +90,7 @@ # On linux-g++-32 with command line `./configure --enable-ipv6 # --with-suffix=3`, python is compiled okay but the build scripts # failed when writing the name of the executable - old = sysconfig._config_vars.get('VERSION') + old = sysconfig.get_config_vars().get('VERSION') sysconfig._config_vars['VERSION'] = 4 try: cmd.run() Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Apr 25 14:53:56 2009 @@ -441,6 +441,9 @@ Library ------- +- Issue #5810: Fixed Distutils test_build_scripts so it uses + sysconfig.get_config_vars. + - Issue #4951: Fixed failure in test_httpservers. - Issue #5795: Fixed test_distutils failure on Debian ppc. From python-checkins at python.org Sat Apr 25 14:55:57 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 25 Apr 2009 14:55:57 +0200 (CEST) Subject: [Python-checkins] r71887 - in python/branches/release26-maint: Lib/distutils/tests/test_build_scripts.py Misc/NEWS Message-ID: <20090425125557.1C7DA1E40CE@bag.python.org> Author: tarek.ziade Date: Sat Apr 25 14:55:56 2009 New Revision: 71887 Log: Merged revisions 71884 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71884 | tarek.ziade | 2009-04-25 14:51:59 +0200 (Sat, 25 Apr 2009) | 1 line #5810: Fixed Distutils test_build_scripts ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/distutils/tests/test_build_scripts.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/distutils/tests/test_build_scripts.py ============================================================================== --- python/branches/release26-maint/Lib/distutils/tests/test_build_scripts.py (original) +++ python/branches/release26-maint/Lib/distutils/tests/test_build_scripts.py Sat Apr 25 14:55:56 2009 @@ -90,7 +90,7 @@ # On linux-g++-32 with command line `./configure --enable-ipv6 # --with-suffix=3`, python is compiled okay but the build scripts # failed when writing the name of the executable - old = sysconfig._config_vars.get('VERSION') + old = sysconfig.get_config_vars().get('VERSION') sysconfig._config_vars['VERSION'] = 4 try: cmd.run() Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sat Apr 25 14:55:56 2009 @@ -139,6 +139,9 @@ Library ------- +- Issue #5810: Fixed Distutils test_build_scripts so it uses + sysconfig.get_config_vars. + - Issue #5741: don't disallow "%%" (which is an escape for "%") when setting a value in SafeConfigParser. From python-checkins at python.org Sat Apr 25 14:57:01 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 25 Apr 2009 14:57:01 +0200 (CEST) Subject: [Python-checkins] r71888 - python/branches/release30-maint Message-ID: <20090425125701.6FC791E4035@bag.python.org> Author: tarek.ziade Date: Sat Apr 25 14:57:01 2009 New Revision: 71888 Log: Blocked revisions 71879 via svnmerge ................ r71879 | tarek.ziade | 2009-04-25 14:39:56 +0200 (Sat, 25 Apr 2009) | 9 lines Merged revisions 71878 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71878 | tarek.ziade | 2009-04-25 14:38:08 +0200 (Sat, 25 Apr 2009) | 1 line Issue #4951: Fixed failure in test_httpservers ........ ................ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sat Apr 25 14:58:32 2009 From: python-checkins at python.org (tarek.ziade) Date: Sat, 25 Apr 2009 14:58:32 +0200 (CEST) Subject: [Python-checkins] r71889 - in python/branches/release30-maint: Lib/distutils/tests/test_build_scripts.py Misc/NEWS Message-ID: <20090425125832.BD5B01E4020@bag.python.org> Author: tarek.ziade Date: Sat Apr 25 14:58:32 2009 New Revision: 71889 Log: Merged revisions 71886 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71886 | tarek.ziade | 2009-04-25 14:53:56 +0200 (Sat, 25 Apr 2009) | 9 lines Merged revisions 71884 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71884 | tarek.ziade | 2009-04-25 14:51:59 +0200 (Sat, 25 Apr 2009) | 1 line #5810: Fixed Distutils test_build_scripts ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Lib/distutils/tests/test_build_scripts.py python/branches/release30-maint/Misc/NEWS Modified: python/branches/release30-maint/Lib/distutils/tests/test_build_scripts.py ============================================================================== --- python/branches/release30-maint/Lib/distutils/tests/test_build_scripts.py (original) +++ python/branches/release30-maint/Lib/distutils/tests/test_build_scripts.py Sat Apr 25 14:58:32 2009 @@ -90,7 +90,7 @@ # On linux-g++-32 with command line `./configure --enable-ipv6 # --with-suffix=3`, python is compiled okay but the build scripts # failed when writing the name of the executable - old = sysconfig._config_vars.get('VERSION') + old = sysconfig.get_config_vars().get('VERSION') sysconfig._config_vars['VERSION'] = 4 try: cmd.run() Modified: python/branches/release30-maint/Misc/NEWS ============================================================================== --- python/branches/release30-maint/Misc/NEWS (original) +++ python/branches/release30-maint/Misc/NEWS Sat Apr 25 14:58:32 2009 @@ -239,6 +239,9 @@ Library ------- +- Issue #5810: Fixed Distutils test_build_scripts so it uses + sysconfig.get_config_vars. + - Issue #5041: ctypes does now allow pickling wide character. - Issue #5731: Distutils bdist_wininst no longer worked on non-Windows From python-checkins at python.org Sat Apr 25 15:07:40 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 15:07:40 +0200 (CEST) Subject: [Python-checkins] r71890 - python/trunk/Doc/c-api/init.rst Message-ID: <20090425130740.B78AA1E4020@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 15:07:40 2009 New Revision: 71890 Log: Rewrite a sentence to be more in line with the rest of the documentation with regard to person and audience. Modified: python/trunk/Doc/c-api/init.rst Modified: python/trunk/Doc/c-api/init.rst ============================================================================== --- python/trunk/Doc/c-api/init.rst (original) +++ python/trunk/Doc/c-api/init.rst Sat Apr 25 15:07:40 2009 @@ -492,13 +492,13 @@ global variable). Conversely, when acquiring the lock and restoring the thread state, the lock must be acquired before storing the thread state pointer. -Why am I going on with so much detail about this? Because when threads are -created from C, they don't have the global interpreter lock, nor is there a -thread state data structure for them. Such threads must bootstrap themselves -into existence, by first creating a thread state data structure, then acquiring -the lock, and finally storing their thread state pointer, before they can start -using the Python/C API. When they are done, they should reset the thread state -pointer, release the lock, and finally free their thread state data structure. +It is important to note that when threads are created from C, they don't have +the global interpreter lock, nor is there a thread state data structure for +them. Such threads must bootstrap themselves into existence, by first +creating a thread state data structure, then acquiring the lock, and finally +storing their thread state pointer, before they can start using the Python/C +API. When they are done, they should reset the thread state pointer, release +the lock, and finally free their thread state data structure. Beginning with version 2.3, threads can now take advantage of the :cfunc:`PyGILState_\*` functions to do all of the above automatically. The From python-checkins at python.org Sat Apr 25 15:16:51 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 25 Apr 2009 15:16:51 +0200 (CEST) Subject: [Python-checkins] r71891 - in python/branches/release26-maint: Lib/test/test_complex.py Misc/NEWS Objects/complexobject.c Message-ID: <20090425131651.3C0461E4022@bag.python.org> Author: mark.dickinson Date: Sat Apr 25 15:16:50 2009 New Revision: 71891 Log: Issue #5829: complex('1e-500') shouldn't raise an exception. Also fix some confusing indentation. Modified: python/branches/release26-maint/Lib/test/test_complex.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Objects/complexobject.c Modified: python/branches/release26-maint/Lib/test/test_complex.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_complex.py (original) +++ python/branches/release26-maint/Lib/test/test_complex.py Sat Apr 25 15:16:50 2009 @@ -220,6 +220,9 @@ self.assertAlmostEqual(complex("+1"), +1) self.assertAlmostEqual(complex("(1+2j)"), 1+2j) self.assertAlmostEqual(complex("(1.3+2.2j)"), 1.3+2.2j) + self.assertAlmostEqual(complex("1E-500"), 1e-500+0j) + self.assertAlmostEqual(complex("1e-500J"), 1e-500j) + self.assertAlmostEqual(complex("+1e-315-1e-400j"), 1e-315-1e-400j) class complex2(complex): pass self.assertAlmostEqual(complex(complex2(1+1j)), 1+1j) Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sat Apr 25 15:16:50 2009 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #5829: complex('1e-500') no longer raises an exception + - Issue #5787: object.__getattribute__(some_type, "__bases__") segfaulted on some builtin types. Modified: python/branches/release26-maint/Objects/complexobject.c ============================================================================== --- python/branches/release26-maint/Objects/complexobject.c (original) +++ python/branches/release26-maint/Objects/complexobject.c Sat Apr 25 15:16:50 2009 @@ -995,16 +995,16 @@ } errno = 0; PyFPE_START_PROTECT("strtod", return 0) - z = PyOS_ascii_strtod(s, &end) ; + z = PyOS_ascii_strtod(s, &end) ; PyFPE_END_PROTECT(z) - if (errno != 0) { - PyOS_snprintf(buffer, sizeof(buffer), - "float() out of range: %.150s", s); - PyErr_SetString( - PyExc_ValueError, - buffer); - return NULL; - } + if (errno == ERANGE && fabs(z) >= 1.0) { + PyOS_snprintf(buffer, sizeof(buffer), + "float() out of range: %.150s", s); + PyErr_SetString( + PyExc_ValueError, + buffer); + return NULL; + } s=end; if (*s=='J' || *s=='j') { From buildbot at python.org Sat Apr 25 15:24:51 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 13:24:51 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 3.x Message-ID: <20090425132451.585DD1E4022@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%203.x/builds/800 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_os test_time ====================================================================== FAIL: test_update2 (test.test_os.EnvironTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_os.py", line 382, in test_update2 self.assertEquals(value, "World") AssertionError: '' != 'World' ====================================================================== FAIL: test_tzset (test.test_time.TimeTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_time.py", line 166, in test_tzset self.failIfEqual(time.gmtime(xmas2002), time.localtime(xmas2002)) AssertionError: time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) == time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sat Apr 25 15:28:27 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 25 Apr 2009 15:28:27 +0200 (CEST) Subject: [Python-checkins] r71892 - in python/branches/release30-maint: Lib/test/test_complex.py Misc/NEWS Objects/complexobject.c Message-ID: <20090425132827.321EC1E40CE@bag.python.org> Author: mark.dickinson Date: Sat Apr 25 15:28:26 2009 New Revision: 71892 Log: Issue #5829: complex('1e-500') shouldn't raise an exception; also, fix indentation problems. Modified: python/branches/release30-maint/Lib/test/test_complex.py python/branches/release30-maint/Misc/NEWS python/branches/release30-maint/Objects/complexobject.c Modified: python/branches/release30-maint/Lib/test/test_complex.py ============================================================================== --- python/branches/release30-maint/Lib/test/test_complex.py (original) +++ python/branches/release30-maint/Lib/test/test_complex.py Sat Apr 25 15:28:26 2009 @@ -202,6 +202,9 @@ self.assertAlmostEqual(complex("+1"), +1) self.assertAlmostEqual(complex("(1+2j)"), 1+2j) self.assertAlmostEqual(complex("(1.3+2.2j)"), 1.3+2.2j) + self.assertAlmostEqual(complex("1E-500"), 1e-500+0j) + self.assertAlmostEqual(complex("1e-500J"), 1e-500j) + self.assertAlmostEqual(complex("+1e-315-1e-400j"), 1e-315-1e-400j) class complex2(complex): pass self.assertAlmostEqual(complex(complex2(1+1j)), 1+1j) Modified: python/branches/release30-maint/Misc/NEWS ============================================================================== --- python/branches/release30-maint/Misc/NEWS (original) +++ python/branches/release30-maint/Misc/NEWS Sat Apr 25 15:28:26 2009 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #5829: complex('1e-500') no longer raises an exception + - Issue #5604: non-ASCII characters in module name passed to imp.find_module() were converted to UTF-8 while the path is converted to the default filesystem encoding, causing nonsense. Modified: python/branches/release30-maint/Objects/complexobject.c ============================================================================== --- python/branches/release30-maint/Objects/complexobject.c (original) +++ python/branches/release30-maint/Objects/complexobject.c Sat Apr 25 15:28:26 2009 @@ -850,16 +850,16 @@ } errno = 0; PyFPE_START_PROTECT("strtod", return 0) - z = PyOS_ascii_strtod(s, &end) ; + z = PyOS_ascii_strtod(s, &end) ; PyFPE_END_PROTECT(z) - if (errno != 0) { - PyOS_snprintf(buffer, sizeof(buffer), - "float() out of range: %.150s", s); - PyErr_SetString( - PyExc_ValueError, - buffer); - return NULL; - } + if (errno == ERANGE && fabs(z) >= 1.0) { + PyOS_snprintf(buffer, sizeof(buffer), + "float() out of range: %.150s", s); + PyErr_SetString( + PyExc_ValueError, + buffer); + return NULL; + } s=end; if (*s=='J' || *s=='j') { From python-checkins at python.org Sat Apr 25 15:58:59 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 15:58:59 +0200 (CEST) Subject: [Python-checkins] r71893 - python/trunk/Doc/c-api/arg.rst Message-ID: <20090425135859.2C7C61E4010@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 15:58:58 2009 New Revision: 71893 Log: Reformat file prior to editing. Modified: python/trunk/Doc/c-api/arg.rst Modified: python/trunk/Doc/c-api/arg.rst ============================================================================== --- python/trunk/Doc/c-api/arg.rst (original) +++ python/trunk/Doc/c-api/arg.rst Sat Apr 25 15:58:58 2009 @@ -10,46 +10,48 @@ :ref:`extending-index`. The first three of these functions described, :cfunc:`PyArg_ParseTuple`, -:cfunc:`PyArg_ParseTupleAndKeywords`, and :cfunc:`PyArg_Parse`, all use *format -strings* which are used to tell the function about the expected arguments. The -format strings use the same syntax for each of these functions. +:cfunc:`PyArg_ParseTupleAndKeywords`, and :cfunc:`PyArg_Parse`, all use +*format strings* which are used to tell the function about the expected +arguments. The format strings use the same syntax for each of these +functions. A format string consists of zero or more "format units." A format unit -describes one Python object; it is usually a single character or a parenthesized -sequence of format units. With a few exceptions, a format unit that is not a -parenthesized sequence normally corresponds to a single address argument to -these functions. In the following description, the quoted form is the format -unit; the entry in (round) parentheses is the Python object type that matches -the format unit; and the entry in [square] brackets is the type of the C -variable(s) whose address should be passed. +describes one Python object; it is usually a single character or a +parenthesized sequence of format units. With a few exceptions, a format unit +that is not a parenthesized sequence normally corresponds to a single address +argument to these functions. In the following description, the quoted form is +the format unit; the entry in (round) parentheses is the Python object type +that matches the format unit; and the entry in [square] brackets is the type +of the C variable(s) whose address should be passed. ``s`` (string or Unicode object) [const char \*] - Convert a Python string or Unicode object to a C pointer to a character string. - You must not provide storage for the string itself; a pointer to an existing - string is stored into the character pointer variable whose address you pass. - The C string is NUL-terminated. The Python string must not contain embedded NUL - bytes; if it does, a :exc:`TypeError` exception is raised. Unicode objects are - converted to C strings using the default encoding. If this conversion fails, a - :exc:`UnicodeError` is raised. + Convert a Python string or Unicode object to a C pointer to a character + string. You must not provide storage for the string itself; a pointer to + an existing string is stored into the character pointer variable whose + address you pass. The C string is NUL-terminated. The Python string must + not contain embedded NUL bytes; if it does, a :exc:`TypeError` exception is + raised. Unicode objects are converted to C strings using the default + encoding. If this conversion fails, a :exc:`UnicodeError` is raised. ``s#`` (string, Unicode or any read buffer compatible object) [const char \*, int (or :ctype:`Py_ssize_t`, see below)] - This variant on ``s`` stores into two C variables, the first one a pointer to a - character string, the second one its length. In this case the Python string may - contain embedded null bytes. Unicode objects pass back a pointer to the default - encoded string version of the object if such a conversion is possible. All - other read-buffer compatible objects pass back a reference to the raw internal - data representation. - - Starting with Python 2.5 the type of the length argument can be - controlled by defining the macro :cmacro:`PY_SSIZE_T_CLEAN` before - including :file:`Python.h`. If the macro is defined, length is a - :ctype:`Py_ssize_t` rather than an int. + This variant on ``s`` stores into two C variables, the first one a pointer + to a character string, the second one its length. In this case the Python + string may contain embedded null bytes. Unicode objects pass back a + pointer to the default encoded string version of the object if such a + conversion is possible. All other read-buffer compatible objects pass back + a reference to the raw internal data representation. + + Starting with Python 2.5 the type of the length argument can be controlled + by defining the macro :cmacro:`PY_SSIZE_T_CLEAN` before including + :file:`Python.h`. If the macro is defined, length is a :ctype:`Py_ssize_t` + rather than an int. ``s*`` (string, Unicode, or any buffer compatible object) [Py_buffer \*] - Similar to ``s#``, this code fills a Py_buffer structure provided by the caller. - The buffer gets locked, so that the caller can subsequently use the buffer even - inside a ``Py_BEGIN_ALLOW_THREADS`` block; the caller is responsible for calling - ``PyBuffer_Release`` with the structure after it has processed the data. + Similar to ``s#``, this code fills a Py_buffer structure provided by the + caller. The buffer gets locked, so that the caller can subsequently use + the buffer even inside a ``Py_BEGIN_ALLOW_THREADS`` block; the caller is + responsible for calling ``PyBuffer_Release`` with the structure after it + has processed the data. .. versionadded:: 2.6 @@ -66,83 +68,86 @@ .. versionadded:: 2.6 ``u`` (Unicode object) [Py_UNICODE \*] - Convert a Python Unicode object to a C pointer to a NUL-terminated buffer of - 16-bit Unicode (UTF-16) data. As with ``s``, there is no need to provide - storage for the Unicode data buffer; a pointer to the existing Unicode data is - stored into the :ctype:`Py_UNICODE` pointer variable whose address you pass. + Convert a Python Unicode object to a C pointer to a NUL-terminated buffer + of 16-bit Unicode (UTF-16) data. As with ``s``, there is no need to + provide storage for the Unicode data buffer; a pointer to the existing + Unicode data is stored into the :ctype:`Py_UNICODE` pointer variable whose + address you pass. ``u#`` (Unicode object) [Py_UNICODE \*, int] - This variant on ``u`` stores into two C variables, the first one a pointer to a - Unicode data buffer, the second one its length. Non-Unicode objects are handled - by interpreting their read-buffer pointer as pointer to a :ctype:`Py_UNICODE` - array. + This variant on ``u`` stores into two C variables, the first one a pointer + to a Unicode data buffer, the second one its length. Non-Unicode objects + are handled by interpreting their read-buffer pointer as pointer to a + :ctype:`Py_UNICODE` array. ``es`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] - This variant on ``s`` is used for encoding Unicode and objects convertible to - Unicode into a character buffer. It only works for encoded data without embedded - NUL bytes. + This variant on ``s`` is used for encoding Unicode and objects convertible + to Unicode into a character buffer. It only works for encoded data without + embedded NUL bytes. This format requires two arguments. The first is only used as input, and - must be a :ctype:`const char\*` which points to the name of an encoding as a - NUL-terminated string, or *NULL*, in which case the default encoding is used. - An exception is raised if the named encoding is not known to Python. The - second argument must be a :ctype:`char\*\*`; the value of the pointer it - references will be set to a buffer with the contents of the argument text. - The text will be encoded in the encoding specified by the first argument. - - :cfunc:`PyArg_ParseTuple` will allocate a buffer of the needed size, copy the - encoded data into this buffer and adjust *\*buffer* to reference the newly - allocated storage. The caller is responsible for calling :cfunc:`PyMem_Free` to - free the allocated buffer after use. + must be a :ctype:`const char\*` which points to the name of an encoding as + a NUL-terminated string, or *NULL*, in which case the default encoding is + used. An exception is raised if the named encoding is not known to Python. + The second argument must be a :ctype:`char\*\*`; the value of the pointer + it references will be set to a buffer with the contents of the argument + text. The text will be encoded in the encoding specified by the first + argument. + + :cfunc:`PyArg_ParseTuple` will allocate a buffer of the needed size, copy + the encoded data into this buffer and adjust *\*buffer* to reference the + newly allocated storage. The caller is responsible for calling + :cfunc:`PyMem_Free` to free the allocated buffer after use. ``et`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] Same as ``es`` except that 8-bit string objects are passed through without - recoding them. Instead, the implementation assumes that the string object uses - the encoding passed in as parameter. + recoding them. Instead, the implementation assumes that the string object + uses the encoding passed in as parameter. ``es#`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer, int \*buffer_length] - This variant on ``s#`` is used for encoding Unicode and objects convertible to - Unicode into a character buffer. Unlike the ``es`` format, this variant allows - input data which contains NUL characters. - - It requires three arguments. The first is only used as input, and must be a - :ctype:`const char\*` which points to the name of an encoding as a - NUL-terminated string, or *NULL*, in which case the default encoding is used. - An exception is raised if the named encoding is not known to Python. The - second argument must be a :ctype:`char\*\*`; the value of the pointer it - references will be set to a buffer with the contents of the argument text. - The text will be encoded in the encoding specified by the first argument. - The third argument must be a pointer to an integer; the referenced integer - will be set to the number of bytes in the output buffer. + This variant on ``s#`` is used for encoding Unicode and objects convertible + to Unicode into a character buffer. Unlike the ``es`` format, this variant + allows input data which contains NUL characters. + + It requires three arguments. The first is only used as input, and must be + a :ctype:`const char\*` which points to the name of an encoding as a + NUL-terminated string, or *NULL*, in which case the default encoding is + used. An exception is raised if the named encoding is not known to Python. + The second argument must be a :ctype:`char\*\*`; the value of the pointer + it references will be set to a buffer with the contents of the argument + text. The text will be encoded in the encoding specified by the first + argument. The third argument must be a pointer to an integer; the + referenced integer will be set to the number of bytes in the output buffer. There are two modes of operation: - If *\*buffer* points a *NULL* pointer, the function will allocate a buffer of - the needed size, copy the encoded data into this buffer and set *\*buffer* to - reference the newly allocated storage. The caller is responsible for calling - :cfunc:`PyMem_Free` to free the allocated buffer after usage. + If *\*buffer* points a *NULL* pointer, the function will allocate a buffer + of the needed size, copy the encoded data into this buffer and set + *\*buffer* to reference the newly allocated storage. The caller is + responsible for calling :cfunc:`PyMem_Free` to free the allocated buffer + after usage. If *\*buffer* points to a non-*NULL* pointer (an already allocated buffer), - :cfunc:`PyArg_ParseTuple` will use this location as the buffer and interpret the - initial value of *\*buffer_length* as the buffer size. It will then copy the - encoded data into the buffer and NUL-terminate it. If the buffer is not large - enough, a :exc:`ValueError` will be set. + :cfunc:`PyArg_ParseTuple` will use this location as the buffer and + interpret the initial value of *\*buffer_length* as the buffer size. It + will then copy the encoded data into the buffer and NUL-terminate it. If + the buffer is not large enough, a :exc:`ValueError` will be set. In both cases, *\*buffer_length* is set to the length of the encoded data without the trailing NUL byte. ``et#`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] - Same as ``es#`` except that string objects are passed through without recoding - them. Instead, the implementation assumes that the string object uses the - encoding passed in as parameter. + Same as ``es#`` except that string objects are passed through without + recoding them. Instead, the implementation assumes that the string object + uses the encoding passed in as parameter. ``b`` (integer) [unsigned char] Convert a nonnegative Python integer to an unsigned tiny int, stored in a C :ctype:`unsigned char`. ``B`` (integer) [unsigned char] - Convert a Python integer to a tiny int without overflow checking, stored in a C - :ctype:`unsigned char`. + Convert a Python integer to a tiny int without overflow checking, stored in + a C :ctype:`unsigned char`. .. versionadded:: 2.3 @@ -150,8 +155,8 @@ Convert a Python integer to a C :ctype:`short int`. ``H`` (integer) [unsigned short int] - Convert a Python integer to a C :ctype:`unsigned short int`, without overflow - checking. + Convert a Python integer to a C :ctype:`unsigned short int`, without + overflow checking. .. versionadded:: 2.3 @@ -168,20 +173,21 @@ Convert a Python integer to a C :ctype:`long int`. ``k`` (integer) [unsigned long] - Convert a Python integer or long integer to a C :ctype:`unsigned long` without - overflow checking. + Convert a Python integer or long integer to a C :ctype:`unsigned long` + without overflow checking. .. versionadded:: 2.3 ``L`` (integer) [PY_LONG_LONG] Convert a Python integer to a C :ctype:`long long`. This format is only - available on platforms that support :ctype:`long long` (or :ctype:`_int64` on - Windows). + available on platforms that support :ctype:`long long` (or :ctype:`_int64` + on Windows). ``K`` (integer) [unsigned PY_LONG_LONG] Convert a Python integer or long integer to a C :ctype:`unsigned long long` without overflow checking. This format is only available on platforms that - support :ctype:`unsigned long long` (or :ctype:`unsigned _int64` on Windows). + support :ctype:`unsigned long long` (or :ctype:`unsigned _int64` on + Windows). .. versionadded:: 2.3 @@ -204,60 +210,61 @@ Convert a Python complex number to a C :ctype:`Py_complex` structure. ``O`` (object) [PyObject \*] - Store a Python object (without any conversion) in a C object pointer. The C - program thus receives the actual object that was passed. The object's reference - count is not increased. The pointer stored is not *NULL*. + Store a Python object (without any conversion) in a C object pointer. The + C program thus receives the actual object that was passed. The object's + reference count is not increased. The pointer stored is not *NULL*. ``O!`` (object) [*typeobject*, PyObject \*] Store a Python object in a C object pointer. This is similar to ``O``, but - takes two C arguments: the first is the address of a Python type object, the - second is the address of the C variable (of type :ctype:`PyObject\*`) into which - the object pointer is stored. If the Python object does not have the required - type, :exc:`TypeError` is raised. + takes two C arguments: the first is the address of a Python type object, + the second is the address of the C variable (of type :ctype:`PyObject\*`) + into which the object pointer is stored. If the Python object does not + have the required type, :exc:`TypeError` is raised. ``O&`` (object) [*converter*, *anything*] - Convert a Python object to a C variable through a *converter* function. This - takes two arguments: the first is a function, the second is the address of a C - variable (of arbitrary type), converted to :ctype:`void \*`. The *converter* - function in turn is called as follows:: + Convert a Python object to a C variable through a *converter* function. + This takes two arguments: the first is a function, the second is the + address of a C variable (of arbitrary type), converted to :ctype:`void \*`. + The *converter* function in turn is called as follows:: status = converter(object, address); where *object* is the Python object to be converted and *address* is the - :ctype:`void\*` argument that was passed to the :cfunc:`PyArg_Parse\*` function. - The returned *status* should be ``1`` for a successful conversion and ``0`` if - the conversion has failed. When the conversion fails, the *converter* function - should raise an exception and leave the content of *address* unmodified. + :ctype:`void\*` argument that was passed to the :cfunc:`PyArg_Parse\*` + function. The returned *status* should be ``1`` for a successful + conversion and ``0`` if the conversion has failed. When the conversion + fails, the *converter* function should raise an exception and leave the + content of *address* unmodified. ``S`` (string) [PyStringObject \*] Like ``O`` but requires that the Python object is a string object. Raises - :exc:`TypeError` if the object is not a string object. The C variable may also - be declared as :ctype:`PyObject\*`. + :exc:`TypeError` if the object is not a string object. The C variable may + also be declared as :ctype:`PyObject\*`. ``U`` (Unicode string) [PyUnicodeObject \*] Like ``O`` but requires that the Python object is a Unicode object. Raises - :exc:`TypeError` if the object is not a Unicode object. The C variable may also - be declared as :ctype:`PyObject\*`. + :exc:`TypeError` if the object is not a Unicode object. The C variable may + also be declared as :ctype:`PyObject\*`. ``t#`` (read-only character buffer) [char \*, int] Like ``s#``, but accepts any object which implements the read-only buffer - interface. The :ctype:`char\*` variable is set to point to the first byte of - the buffer, and the :ctype:`int` is set to the length of the buffer. Only - single-segment buffer objects are accepted; :exc:`TypeError` is raised for all - others. + interface. The :ctype:`char\*` variable is set to point to the first byte + of the buffer, and the :ctype:`int` is set to the length of the buffer. + Only single-segment buffer objects are accepted; :exc:`TypeError` is raised + for all others. ``w`` (read-write character buffer) [char \*] - Similar to ``s``, but accepts any object which implements the read-write buffer - interface. The caller must determine the length of the buffer by other means, - or use ``w#`` instead. Only single-segment buffer objects are accepted; - :exc:`TypeError` is raised for all others. + Similar to ``s``, but accepts any object which implements the read-write + buffer interface. The caller must determine the length of the buffer by + other means, or use ``w#`` instead. Only single-segment buffer objects are + accepted; :exc:`TypeError` is raised for all others. ``w#`` (read-write character buffer) [char \*, Py_ssize_t] Like ``s#``, but accepts any object which implements the read-write buffer - interface. The :ctype:`char \*` variable is set to point to the first byte of - the buffer, and the :ctype:`int` is set to the length of the buffer. Only - single-segment buffer objects are accepted; :exc:`TypeError` is raised for all - others. + interface. The :ctype:`char \*` variable is set to point to the first byte + of the buffer, and the :ctype:`int` is set to the length of the buffer. + Only single-segment buffer objects are accepted; :exc:`TypeError` is raised + for all others. ``w*`` (read-write byte-oriented buffer) [Py_buffer \*] This is to ``w`` what ``s*`` is to ``s``. @@ -265,72 +272,72 @@ .. versionadded:: 2.6 ``(items)`` (tuple) [*matching-items*] - The object must be a Python sequence whose length is the number of format units - in *items*. The C arguments must correspond to the individual format units in - *items*. Format units for sequences may be nested. + The object must be a Python sequence whose length is the number of format + units in *items*. The C arguments must correspond to the individual format + units in *items*. Format units for sequences may be nested. .. note:: - Prior to Python version 1.5.2, this format specifier only accepted a tuple - containing the individual parameters, not an arbitrary sequence. Code which - previously caused :exc:`TypeError` to be raised here may now proceed without an - exception. This is not expected to be a problem for existing code. + Prior to Python version 1.5.2, this format specifier only accepted a + tuple containing the individual parameters, not an arbitrary sequence. + Code which previously caused :exc:`TypeError` to be raised here may now + proceed without an exception. This is not expected to be a problem for + existing code. It is possible to pass Python long integers where integers are requested; however no proper range checking is done --- the most significant bits are silently truncated when the receiving field is too small to receive the value -(actually, the semantics are inherited from downcasts in C --- your mileage may -vary). +(actually, the semantics are inherited from downcasts in C --- your mileage +may vary). A few other characters have a meaning in a format string. These may not occur inside nested parentheses. They are: ``|`` - Indicates that the remaining arguments in the Python argument list are optional. - The C variables corresponding to optional arguments should be initialized to - their default value --- when an optional argument is not specified, - :cfunc:`PyArg_ParseTuple` does not touch the contents of the corresponding C - variable(s). + Indicates that the remaining arguments in the Python argument list are + optional. The C variables corresponding to optional arguments should be + initialized to their default value --- when an optional argument is not + specified, :cfunc:`PyArg_ParseTuple` does not touch the contents of the + corresponding C variable(s). ``:`` - The list of format units ends here; the string after the colon is used as the - function name in error messages (the "associated value" of the exception that - :cfunc:`PyArg_ParseTuple` raises). + The list of format units ends here; the string after the colon is used as + the function name in error messages (the "associated value" of the + exception that :cfunc:`PyArg_ParseTuple` raises). ``;`` - The list of format units ends here; the string after the semicolon is used as - the error message *instead* of the default error message. ``:`` and ``;`` - mutually exclude each other. + The list of format units ends here; the string after the semicolon is used + as the error message *instead* of the default error message. ``:`` and + ``;`` mutually exclude each other. Note that any Python object references which are provided to the caller are *borrowed* references; do not decrement their reference count! Additional arguments passed to these functions must be addresses of variables whose type is determined by the format string; these are used to store values -from the input tuple. There are a few cases, as described in the list of format -units above, where these parameters are used as input values; they should match -what is specified for the corresponding format unit in that case. - -For the conversion to succeed, the *arg* object must match the format -and the format must be exhausted. On success, the -:cfunc:`PyArg_Parse\*` functions return true, otherwise they return -false and raise an appropriate exception. When the -:cfunc:`PyArg_Parse\*` functions fail due to conversion failure in one -of the format units, the variables at the addresses corresponding to that +from the input tuple. There are a few cases, as described in the list of +format units above, where these parameters are used as input values; they +should match what is specified for the corresponding format unit in that case. + +For the conversion to succeed, the *arg* object must match the format and the +format must be exhausted. On success, the :cfunc:`PyArg_Parse\*` functions +return true, otherwise they return false and raise an appropriate exception. +When the :cfunc:`PyArg_Parse\*` functions fail due to conversion failure in +one of the format units, the variables at the addresses corresponding to that and the following format units are left untouched. .. cfunction:: int PyArg_ParseTuple(PyObject *args, const char *format, ...) - Parse the parameters of a function that takes only positional parameters into - local variables. Returns true on success; on failure, it returns false and - raises the appropriate exception. + Parse the parameters of a function that takes only positional parameters + into local variables. Returns true on success; on failure, it returns + false and raises the appropriate exception. .. cfunction:: int PyArg_VaParse(PyObject *args, const char *format, va_list vargs) - Identical to :cfunc:`PyArg_ParseTuple`, except that it accepts a va_list rather - than a variable number of arguments. + Identical to :cfunc:`PyArg_ParseTuple`, except that it accepts a va_list + rather than a variable number of arguments. .. cfunction:: int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], ...) @@ -348,32 +355,33 @@ .. cfunction:: int PyArg_Parse(PyObject *args, const char *format, ...) - Function used to deconstruct the argument lists of "old-style" functions --- - these are functions which use the :const:`METH_OLDARGS` parameter parsing - method. This is not recommended for use in parameter parsing in new code, and - most code in the standard interpreter has been modified to no longer use this - for that purpose. It does remain a convenient way to decompose other tuples, - however, and may continue to be used for that purpose. + Function used to deconstruct the argument lists of "old-style" functions + --- these are functions which use the :const:`METH_OLDARGS` parameter + parsing method. This is not recommended for use in parameter parsing in + new code, and most code in the standard interpreter has been modified to no + longer use this for that purpose. It does remain a convenient way to + decompose other tuples, however, and may continue to be used for that + purpose. .. cfunction:: int PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...) A simpler form of parameter retrieval which does not use a format string to - specify the types of the arguments. Functions which use this method to retrieve - their parameters should be declared as :const:`METH_VARARGS` in function or - method tables. The tuple containing the actual parameters should be passed as - *args*; it must actually be a tuple. The length of the tuple must be at least - *min* and no more than *max*; *min* and *max* may be equal. Additional - arguments must be passed to the function, each of which should be a pointer to a - :ctype:`PyObject\*` variable; these will be filled in with the values from - *args*; they will contain borrowed references. The variables which correspond - to optional parameters not given by *args* will not be filled in; these should - be initialized by the caller. This function returns true on success and false if - *args* is not a tuple or contains the wrong number of elements; an exception - will be set if there was a failure. + specify the types of the arguments. Functions which use this method to + retrieve their parameters should be declared as :const:`METH_VARARGS` in + function or method tables. The tuple containing the actual parameters + should be passed as *args*; it must actually be a tuple. The length of the + tuple must be at least *min* and no more than *max*; *min* and *max* may be + equal. Additional arguments must be passed to the function, each of which + should be a pointer to a :ctype:`PyObject\*` variable; these will be filled + in with the values from *args*; they will contain borrowed references. The + variables which correspond to optional parameters not given by *args* will + not be filled in; these should be initialized by the caller. This function + returns true on success and false if *args* is not a tuple or contains the + wrong number of elements; an exception will be set if there was a failure. - This is an example of the use of this function, taken from the sources for the - :mod:`_weakref` helper module for weak references:: + This is an example of the use of this function, taken from the sources for + the :mod:`_weakref` helper module for weak references:: static PyObject * weakref_ref(PyObject *self, PyObject *args) @@ -388,8 +396,8 @@ return result; } - The call to :cfunc:`PyArg_UnpackTuple` in this example is entirely equivalent to - this call to :cfunc:`PyArg_ParseTuple`:: + The call to :cfunc:`PyArg_UnpackTuple` in this example is entirely + equivalent to this call to :cfunc:`PyArg_ParseTuple`:: PyArg_ParseTuple(args, "O|O:ref", &object, &callback) @@ -398,40 +406,42 @@ .. cfunction:: PyObject* Py_BuildValue(const char *format, ...) - Create a new value based on a format string similar to those accepted by the - :cfunc:`PyArg_Parse\*` family of functions and a sequence of values. Returns - the value or *NULL* in the case of an error; an exception will be raised if - *NULL* is returned. - - :cfunc:`Py_BuildValue` does not always build a tuple. It builds a tuple only if - its format string contains two or more format units. If the format string is - empty, it returns ``None``; if it contains exactly one format unit, it returns - whatever object is described by that format unit. To force it to return a tuple - of size 0 or one, parenthesize the format string. - - When memory buffers are passed as parameters to supply data to build objects, as - for the ``s`` and ``s#`` formats, the required data is copied. Buffers provided - by the caller are never referenced by the objects created by - :cfunc:`Py_BuildValue`. In other words, if your code invokes :cfunc:`malloc` - and passes the allocated memory to :cfunc:`Py_BuildValue`, your code is - responsible for calling :cfunc:`free` for that memory once + Create a new value based on a format string similar to those accepted by + the :cfunc:`PyArg_Parse\*` family of functions and a sequence of values. + Returns the value or *NULL* in the case of an error; an exception will be + raised if *NULL* is returned. + + :cfunc:`Py_BuildValue` does not always build a tuple. It builds a tuple + only if its format string contains two or more format units. If the format + string is empty, it returns ``None``; if it contains exactly one format + unit, it returns whatever object is described by that format unit. To + force it to return a tuple of size 0 or one, parenthesize the format + string. + + When memory buffers are passed as parameters to supply data to build + objects, as for the ``s`` and ``s#`` formats, the required data is copied. + Buffers provided by the caller are never referenced by the objects created + by :cfunc:`Py_BuildValue`. In other words, if your code invokes + :cfunc:`malloc` and passes the allocated memory to :cfunc:`Py_BuildValue`, + your code is responsible for calling :cfunc:`free` for that memory once :cfunc:`Py_BuildValue` returns. - In the following description, the quoted form is the format unit; the entry in - (round) parentheses is the Python object type that the format unit will return; - and the entry in [square] brackets is the type of the C value(s) to be passed. - - The characters space, tab, colon and comma are ignored in format strings (but - not within format units such as ``s#``). This can be used to make long format - strings a tad more readable. + In the following description, the quoted form is the format unit; the entry + in (round) parentheses is the Python object type that the format unit will + return; and the entry in [square] brackets is the type of the C value(s) to + be passed. + + The characters space, tab, colon and comma are ignored in format strings + (but not within format units such as ``s#``). This can be used to make + long format strings a tad more readable. ``s`` (string) [char \*] - Convert a null-terminated C string to a Python object. If the C string pointer - is *NULL*, ``None`` is used. + Convert a null-terminated C string to a Python object. If the C string + pointer is *NULL*, ``None`` is used. ``s#`` (string) [char \*, int] - Convert a C string and its length to a Python object. If the C string pointer - is *NULL*, the length is ignored and ``None`` is returned. + Convert a C string and its length to a Python object. If the C string + pointer is *NULL*, the length is ignored and ``None`` is returned. ``z`` (string or ``None``) [char \*] Same as ``s``. @@ -440,13 +450,14 @@ Same as ``s#``. ``u`` (Unicode string) [Py_UNICODE \*] - Convert a null-terminated buffer of Unicode (UCS-2 or UCS-4) data to a Python - Unicode object. If the Unicode buffer pointer is *NULL*, ``None`` is returned. + Convert a null-terminated buffer of Unicode (UCS-2 or UCS-4) data to a + Python Unicode object. If the Unicode buffer pointer is *NULL*, + ``None`` is returned. ``u#`` (Unicode string) [Py_UNICODE \*, int] - Convert a Unicode (UCS-2 or UCS-4) data buffer and its length to a Python - Unicode object. If the Unicode buffer pointer is *NULL*, the length is ignored - and ``None`` is returned. + Convert a Unicode (UCS-2 or UCS-4) data buffer and its length to a + Python Unicode object. If the Unicode buffer pointer is *NULL*, the + length is ignored and ``None`` is returned. ``i`` (integer) [int] Convert a plain C :ctype:`int` to a Python integer object. @@ -467,20 +478,20 @@ Convert a C :ctype:`unsigned short int` to a Python integer object. ``I`` (integer/long) [unsigned int] - Convert a C :ctype:`unsigned int` to a Python integer object or a Python long - integer object, if it is larger than ``sys.maxint``. + Convert a C :ctype:`unsigned int` to a Python integer object or a Python + long integer object, if it is larger than ``sys.maxint``. ``k`` (integer/long) [unsigned long] - Convert a C :ctype:`unsigned long` to a Python integer object or a Python long - integer object, if it is larger than ``sys.maxint``. + Convert a C :ctype:`unsigned long` to a Python integer object or a + Python long integer object, if it is larger than ``sys.maxint``. ``L`` (long) [PY_LONG_LONG] - Convert a C :ctype:`long long` to a Python long integer object. Only available - on platforms that support :ctype:`long long`. + Convert a C :ctype:`long long` to a Python long integer object. Only + available on platforms that support :ctype:`long long`. ``K`` (long) [unsigned PY_LONG_LONG] - Convert a C :ctype:`unsigned long long` to a Python long integer object. Only - available on platforms that support :ctype:`unsigned long long`. + Convert a C :ctype:`unsigned long long` to a Python long integer object. + Only available on platforms that support :ctype:`unsigned long long`. ``n`` (int) [Py_ssize_t] Convert a C :ctype:`Py_ssize_t` to a Python integer or long integer. @@ -488,8 +499,8 @@ .. versionadded:: 2.5 ``c`` (string of length 1) [char] - Convert a C :ctype:`int` representing a character to a Python string of length - 1. + Convert a C :ctype:`int` representing a character to a Python string of + length 1. ``d`` (float) [double] Convert a C :ctype:`double` to a Python floating point number. @@ -502,39 +513,41 @@ ``O`` (object) [PyObject \*] Pass a Python object untouched (except for its reference count, which is - incremented by one). If the object passed in is a *NULL* pointer, it is assumed - that this was caused because the call producing the argument found an error and - set an exception. Therefore, :cfunc:`Py_BuildValue` will return *NULL* but won't - raise an exception. If no exception has been raised yet, :exc:`SystemError` is - set. + incremented by one). If the object passed in is a *NULL* pointer, it is + assumed that this was caused because the call producing the argument + found an error and set an exception. Therefore, :cfunc:`Py_BuildValue` + will return *NULL* but won't raise an exception. If no exception has + been raised yet, :exc:`SystemError` is set. ``S`` (object) [PyObject \*] Same as ``O``. ``N`` (object) [PyObject \*] - Same as ``O``, except it doesn't increment the reference count on the object. - Useful when the object is created by a call to an object constructor in the - argument list. + Same as ``O``, except it doesn't increment the reference count on the + object. Useful when the object is created by a call to an object + constructor in the argument list. ``O&`` (object) [*converter*, *anything*] - Convert *anything* to a Python object through a *converter* function. The - function is called with *anything* (which should be compatible with :ctype:`void - \*`) as its argument and should return a "new" Python object, or *NULL* if an - error occurred. + Convert *anything* to a Python object through a *converter* function. + The function is called with *anything* (which should be compatible with + :ctype:`void \*`) as its argument and should return a "new" Python + object, or *NULL* if an error occurred. ``(items)`` (tuple) [*matching-items*] - Convert a sequence of C values to a Python tuple with the same number of items. + Convert a sequence of C values to a Python tuple with the same number of + items. ``[items]`` (list) [*matching-items*] - Convert a sequence of C values to a Python list with the same number of items. + Convert a sequence of C values to a Python list with the same number of + items. ``{items}`` (dictionary) [*matching-items*] - Convert a sequence of C values to a Python dictionary. Each pair of consecutive - C values adds one item to the dictionary, serving as key and value, - respectively. + Convert a sequence of C values to a Python dictionary. Each pair of + consecutive C values adds one item to the dictionary, serving as key and + value, respectively. - If there is an error in the format string, the :exc:`SystemError` exception is - set and *NULL* returned. + If there is an error in the format string, the :exc:`SystemError` exception + is set and *NULL* returned. .. cfunction:: PyObject* Py_VaBuildValue(const char *format, va_list vargs) From python-checkins at python.org Sat Apr 25 16:03:16 2009 From: python-checkins at python.org (walter.doerwald) Date: Sat, 25 Apr 2009 16:03:16 +0200 (CEST) Subject: [Python-checkins] r71894 - in python/trunk: Lib/test/test_unicodedata.py Misc/NEWS Objects/unicodetype_db.h Tools/unicode/makeunicodedata.py Message-ID: <20090425140316.820AE1E4010@bag.python.org> Author: walter.doerwald Date: Sat Apr 25 16:03:16 2009 New Revision: 71894 Log: Issue #5828 (Invalid behavior of unicode.lower): Fixed bogus logic in makeunicodedata.py and regenerated the Unicode database (This fixes u'\u1d79'.lower() == '\x00'). Modified: python/trunk/Lib/test/test_unicodedata.py python/trunk/Misc/NEWS python/trunk/Objects/unicodetype_db.h python/trunk/Tools/unicode/makeunicodedata.py Modified: python/trunk/Lib/test/test_unicodedata.py ============================================================================== --- python/trunk/Lib/test/test_unicodedata.py (original) +++ python/trunk/Lib/test/test_unicodedata.py Sat Apr 25 16:03:16 2009 @@ -20,7 +20,7 @@ class UnicodeMethodsTest(unittest.TestCase): # update this, if the database changes - expectedchecksum = 'aef99984a58c8e1e5363a3175f2ff9608599a93e' + expectedchecksum = 'b7db9b5f1d804976fa921d2009cbef6f025620c1' def test_method_checksum(self): h = hashlib.sha1() @@ -257,6 +257,19 @@ # the upper-case mapping: as delta, or as absolute value self.assert_(u"a".upper()==u'A') self.assert_(u"\u1d79".upper()==u'\ua77d') + self.assert_(u".".upper()==u".") + + def test_bug_5828(self): + self.assertEqual(u"\u1d79".lower(), u"\u1d79") + # Only U+0000 should have U+0000 as its upper/lower/titlecase variant + self.assertEqual( + [ + c for c in range(sys.maxunicode+1) + if u"\x00" in unichr(c).lower()+unichr(c).upper()+unichr(c).title() + ], + [0] + ) + def test_main(): test.test_support.run_unittest( Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Apr 25 16:03:16 2009 @@ -773,6 +773,10 @@ - Issue #2703: SimpleXMLRPCDispatcher.__init__: Provide default values for new arguments introduced in 2.5. +- Issue #5828 (Invalid behavior of unicode.lower): Fixed bogus logic in + makeunicodedata.py and regenerated the Unicode database (This fixes + u'\u1d79'.lower() == '\x00'). + Tools/Demos ----------- Modified: python/trunk/Objects/unicodetype_db.h ============================================================================== --- python/trunk/Objects/unicodetype_db.h (original) +++ python/trunk/Objects/unicodetype_db.h Sat Apr 25 16:03:16 2009 @@ -118,7 +118,7 @@ {0, 0, 0, 0, 7, 4}, {0, 0, 0, 0, 8, 4}, {0, 0, 0, 0, 9, 4}, - {42877, 0, 42877, 0, 0, 265}, + {42877, 7545, 42877, 0, 0, 265}, {3814, 0, 3814, 0, 0, 9}, {65477, 0, 65477, 0, 0, 9}, {0, 57921, 0, 0, 0, 129}, @@ -159,7 +159,7 @@ {0, 54787, 0, 0, 0, 129}, {0, 54753, 0, 0, 0, 129}, {58272, 0, 58272, 0, 0, 9}, - {0, 7545, 0, 0, 0, 385}, + {42877, 7545, 42877, 0, 0, 385}, {0, 40, 0, 0, 0, 129}, {65496, 0, 65496, 0, 0, 9}, }; Modified: python/trunk/Tools/unicode/makeunicodedata.py ============================================================================== --- python/trunk/Tools/unicode/makeunicodedata.py (original) +++ python/trunk/Tools/unicode/makeunicodedata.py Sat Apr 25 16:03:16 2009 @@ -371,33 +371,32 @@ flags |= UPPER_MASK # use delta predictor for upper/lower/title if it fits if record[12]: - upper = int(record[12], 16) - char - if -32768 <= upper <= 32767 and delta: - upper = upper & 0xffff - else: - upper += char - delta = False + upper = int(record[12], 16) else: - upper = 0 + upper = char if record[13]: - lower = int(record[13], 16) - char - if -32768 <= lower <= 32767 and delta: - lower = lower & 0xffff - else: - lower += char - delta = False + lower = int(record[13], 16) else: - lower = 0 + lower = char if record[14]: - title = int(record[14], 16) - char - if -32768 <= lower <= 32767 and delta: - title = title & 0xffff - else: - title += char - delta = False + title = int(record[14], 16) + else: + # UCD.html says that a missing title char means that + # it defaults to the uppercase character, not to the + # character itself. Apparently, in the current UCD (5.x) + # this feature is never used + title = upper + upper_d = upper - char + lower_d = lower - char + title_d = title - char + if -32768 <= upper_d <= 32767 and \ + -32768 <= lower_d <= 32767 and \ + -32768 <= title_d <= 32767: + # use deltas + upper = upper_d & 0xffff + lower = lower_d & 0xffff + title = title_d & 0xffff else: - title = 0 - if not delta: flags |= NODELTA_MASK # decimal digit, integer digit decimal = 0 From python-checkins at python.org Sat Apr 25 16:05:53 2009 From: python-checkins at python.org (walter.doerwald) Date: Sat, 25 Apr 2009 16:05:53 +0200 (CEST) Subject: [Python-checkins] r71895 - in python/branches/release26-maint: Lib/test/test_unicodedata.py Misc/NEWS Objects/unicodetype_db.h Tools/unicode/makeunicodedata.py Message-ID: <20090425140553.19B2B1E4043@bag.python.org> Author: walter.doerwald Date: Sat Apr 25 16:05:52 2009 New Revision: 71895 Log: Merged revisions 71894 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71894 | walter.doerwald | 2009-04-25 16:03:16 +0200 (Sa, 25 Apr 2009) | 4 lines Issue #5828 (Invalid behavior of unicode.lower): Fixed bogus logic in makeunicodedata.py and regenerated the Unicode database (This fixes u'\u1d79'.lower() == '\x00'). ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_unicodedata.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Objects/unicodetype_db.h python/branches/release26-maint/Tools/unicode/makeunicodedata.py Modified: python/branches/release26-maint/Lib/test/test_unicodedata.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_unicodedata.py (original) +++ python/branches/release26-maint/Lib/test/test_unicodedata.py Sat Apr 25 16:05:52 2009 @@ -20,7 +20,7 @@ class UnicodeMethodsTest(unittest.TestCase): # update this, if the database changes - expectedchecksum = 'aef99984a58c8e1e5363a3175f2ff9608599a93e' + expectedchecksum = 'b7db9b5f1d804976fa921d2009cbef6f025620c1' def test_method_checksum(self): h = hashlib.sha1() @@ -257,6 +257,19 @@ # the upper-case mapping: as delta, or as absolute value self.assert_(u"a".upper()==u'A') self.assert_(u"\u1d79".upper()==u'\ua77d') + self.assert_(u".".upper()==u".") + + def test_bug_5828(self): + self.assertEqual(u"\u1d79".lower(), u"\u1d79") + # Only U+0000 should have U+0000 as its upper/lower/titlecase variant + self.assertEqual( + [ + c for c in range(sys.maxunicode+1) + if u"\x00" in unichr(c).lower()+unichr(c).upper()+unichr(c).title() + ], + [0] + ) + def test_main(): test.test_support.run_unittest( Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sat Apr 25 16:05:52 2009 @@ -34,6 +34,10 @@ dispatcher now has an 'ignore_log_types' attribute for suppressing log messages, which is set to 'warning' by default. +- Issue #5828 (Invalid behavior of unicode.lower): Fixed bogus logic in + makeunicodedata.py and regenerated the Unicode database (This fixes + u'\u1d79'.lower() == '\x00'). + Tests ----- Modified: python/branches/release26-maint/Objects/unicodetype_db.h ============================================================================== --- python/branches/release26-maint/Objects/unicodetype_db.h (original) +++ python/branches/release26-maint/Objects/unicodetype_db.h Sat Apr 25 16:05:52 2009 @@ -118,7 +118,7 @@ {0, 0, 0, 0, 7, 4}, {0, 0, 0, 0, 8, 4}, {0, 0, 0, 0, 9, 4}, - {42877, 0, 42877, 0, 0, 265}, + {42877, 7545, 42877, 0, 0, 265}, {3814, 0, 3814, 0, 0, 9}, {65477, 0, 65477, 0, 0, 9}, {0, 57921, 0, 0, 0, 129}, @@ -159,7 +159,7 @@ {0, 54787, 0, 0, 0, 129}, {0, 54753, 0, 0, 0, 129}, {58272, 0, 58272, 0, 0, 9}, - {0, 7545, 0, 0, 0, 385}, + {42877, 7545, 42877, 0, 0, 385}, {0, 40, 0, 0, 0, 129}, {65496, 0, 65496, 0, 0, 9}, }; Modified: python/branches/release26-maint/Tools/unicode/makeunicodedata.py ============================================================================== --- python/branches/release26-maint/Tools/unicode/makeunicodedata.py (original) +++ python/branches/release26-maint/Tools/unicode/makeunicodedata.py Sat Apr 25 16:05:52 2009 @@ -371,33 +371,32 @@ flags |= UPPER_MASK # use delta predictor for upper/lower/title if it fits if record[12]: - upper = int(record[12], 16) - char - if -32768 <= upper <= 32767 and delta: - upper = upper & 0xffff - else: - upper += char - delta = False + upper = int(record[12], 16) else: - upper = 0 + upper = char if record[13]: - lower = int(record[13], 16) - char - if -32768 <= lower <= 32767 and delta: - lower = lower & 0xffff - else: - lower += char - delta = False + lower = int(record[13], 16) else: - lower = 0 + lower = char if record[14]: - title = int(record[14], 16) - char - if -32768 <= lower <= 32767 and delta: - title = title & 0xffff - else: - title += char - delta = False + title = int(record[14], 16) + else: + # UCD.html says that a missing title char means that + # it defaults to the uppercase character, not to the + # character itself. Apparently, in the current UCD (5.x) + # this feature is never used + title = upper + upper_d = upper - char + lower_d = lower - char + title_d = title - char + if -32768 <= upper_d <= 32767 and \ + -32768 <= lower_d <= 32767 and \ + -32768 <= title_d <= 32767: + # use deltas + upper = upper_d & 0xffff + lower = lower_d & 0xffff + title = title_d & 0xffff else: - title = 0 - if not delta: flags |= NODELTA_MASK # decimal digit, integer digit decimal = 0 From buildbot at python.org Sat Apr 25 16:09:50 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 14:09:50 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc trunk Message-ID: <20090425140951.0F82F1E4022@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc trunk. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%20trunk/builds/328 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: jeroen.ruigrok,walter.doerwald BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posixpath sincerely, -The Buildbot From buildbot at python.org Sat Apr 25 16:12:09 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 14:12:09 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu trunk Message-ID: <20090425141209.8A63E1E4010@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%20trunk/builds/1184 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: jeroen.ruigrok,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_time ====================================================================== FAIL: test_tzset (test.test_time.TimeTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-ubuntu-i386/build/Lib/test/test_time.py", line 161, in test_tzset self.failIfEqual(time.gmtime(xmas2002), time.localtime(xmas2002)) AssertionError: time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) == time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sat Apr 25 16:13:57 2009 From: python-checkins at python.org (walter.doerwald) Date: Sat, 25 Apr 2009 16:13:57 +0200 (CEST) Subject: [Python-checkins] r71896 - in python/branches/py3k: Lib/test/test_unicodedata.py Misc/NEWS Objects/unicodetype_db.h Tools/unicode/makeunicodedata.py Message-ID: <20090425141357.3CD4D1E4010@bag.python.org> Author: walter.doerwald Date: Sat Apr 25 16:13:56 2009 New Revision: 71896 Log: Merged revisions 71894 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71894 | walter.doerwald | 2009-04-25 16:03:16 +0200 (Sa, 25 Apr 2009) | 4 lines Issue #5828 (Invalid behavior of unicode.lower): Fixed bogus logic in makeunicodedata.py and regenerated the Unicode database (This fixes u'\u1d79'.lower() == '\x00'). ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_unicodedata.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/unicodetype_db.h python/branches/py3k/Tools/unicode/makeunicodedata.py Modified: python/branches/py3k/Lib/test/test_unicodedata.py ============================================================================== --- python/branches/py3k/Lib/test/test_unicodedata.py (original) +++ python/branches/py3k/Lib/test/test_unicodedata.py Sat Apr 25 16:13:56 2009 @@ -20,7 +20,7 @@ class UnicodeMethodsTest(unittest.TestCase): # update this, if the database changes - expectedchecksum = 'aef99984a58c8e1e5363a3175f2ff9608599a93e' + expectedchecksum = 'b7db9b5f1d804976fa921d2009cbef6f025620c1' def test_method_checksum(self): h = hashlib.sha1() @@ -258,6 +258,19 @@ # the upper-case mapping: as delta, or as absolute value self.assert_("a".upper()=='A') self.assert_("\u1d79".upper()=='\ua77d') + self.assert_(".".upper()=='.') + + def test_bug_5828(self): + self.assertEqual("\u1d79".lower(), "\u1d79") + # Only U+0000 should have U+0000 as its upper/lower/titlecase variant + self.assertEqual( + [ + c for c in range(sys.maxunicode+1) + if "\x00" in chr(c).lower()+chr(c).upper()+chr(c).title() + ], + [0] + ) + def test_main(): test.support.run_unittest( Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Apr 25 16:13:56 2009 @@ -104,6 +104,10 @@ - Issue #2703: SimpleXMLRPCDispatcher.__init__: Provide default values for new arguments introduced in 2.5. +- Issue #5828 (Invalid behavior of unicode.lower): Fixed bogus logic in + makeunicodedata.py and regenerated the Unicode database (This fixes + u'\u1d79'.lower() == '\x00'). + Extension Modules ----------------- Modified: python/branches/py3k/Objects/unicodetype_db.h ============================================================================== --- python/branches/py3k/Objects/unicodetype_db.h (original) +++ python/branches/py3k/Objects/unicodetype_db.h Sat Apr 25 16:13:56 2009 @@ -127,7 +127,7 @@ {0, 0, 0, 0, 8, 1540}, {0, 0, 0, 0, 9, 1540}, {0, 0, 0, 0, 0, 1792}, - {42877, 0, 42877, 0, 0, 3849}, + {42877, 7545, 42877, 0, 0, 3849}, {3814, 0, 3814, 0, 0, 1801}, {65477, 0, 65477, 0, 0, 1801}, {0, 57921, 0, 0, 0, 1921}, @@ -174,7 +174,7 @@ {0, 54787, 0, 0, 0, 1921}, {0, 54753, 0, 0, 0, 1921}, {58272, 0, 58272, 0, 0, 1801}, - {0, 7545, 0, 0, 0, 3969}, + {42877, 7545, 42877, 0, 0, 3969}, {0, 40, 0, 0, 0, 1921}, {65496, 0, 65496, 0, 0, 1801}, }; Modified: python/branches/py3k/Tools/unicode/makeunicodedata.py ============================================================================== --- python/branches/py3k/Tools/unicode/makeunicodedata.py (original) +++ python/branches/py3k/Tools/unicode/makeunicodedata.py Sat Apr 25 16:13:56 2009 @@ -383,33 +383,32 @@ flags |= XID_CONTINUE_MASK # use delta predictor for upper/lower/title if it fits if record[12]: - upper = int(record[12], 16) - char - if -32768 <= upper <= 32767 and delta: - upper = upper & 0xffff - else: - upper += char - delta = False + upper = int(record[12], 16) else: - upper = 0 + upper = char if record[13]: - lower = int(record[13], 16) - char - if -32768 <= lower <= 32767 and delta: - lower = lower & 0xffff - else: - lower += char - delta = False + lower = int(record[13], 16) else: - lower = 0 + lower = char if record[14]: - title = int(record[14], 16) - char - if -32768 <= lower <= 32767 and delta: - title = title & 0xffff - else: - title += char - delta = False + title = int(record[14], 16) + else: + # UCD.html says that a missing title char means that + # it defaults to the uppercase character, not to the + # character itself. Apparently, in the current UCD (5.x) + # this feature is never used + title = upper + upper_d = upper - char + lower_d = lower - char + title_d = title - char + if -32768 <= upper_d <= 32767 and \ + -32768 <= lower_d <= 32767 and \ + -32768 <= title_d <= 32767: + # use deltas + upper = upper_d & 0xffff + lower = lower_d & 0xffff + title = title_d & 0xffff else: - title = 0 - if not delta: flags |= NODELTA_MASK # decimal digit, integer digit decimal = 0 From python-checkins at python.org Sat Apr 25 16:17:13 2009 From: python-checkins at python.org (walter.doerwald) Date: Sat, 25 Apr 2009 16:17:13 +0200 (CEST) Subject: [Python-checkins] r71897 - in python/branches/release30-maint: Lib/test/test_unicodedata.py Misc/NEWS Objects/unicodetype_db.h Tools/unicode/makeunicodedata.py Message-ID: <20090425141713.4C2F71E4010@bag.python.org> Author: walter.doerwald Date: Sat Apr 25 16:17:13 2009 New Revision: 71897 Log: Merged revisions 71896 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71896 | walter.doerwald | 2009-04-25 16:13:56 +0200 (Sa, 25 Apr 2009) | 11 lines Merged revisions 71894 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71894 | walter.doerwald | 2009-04-25 16:03:16 +0200 (Sa, 25 Apr 2009) | 4 lines Issue #5828 (Invalid behavior of unicode.lower): Fixed bogus logic in makeunicodedata.py and regenerated the Unicode database (This fixes u'\u1d79'.lower() == '\x00'). ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Lib/test/test_unicodedata.py python/branches/release30-maint/Misc/NEWS python/branches/release30-maint/Objects/unicodetype_db.h python/branches/release30-maint/Tools/unicode/makeunicodedata.py Modified: python/branches/release30-maint/Lib/test/test_unicodedata.py ============================================================================== --- python/branches/release30-maint/Lib/test/test_unicodedata.py (original) +++ python/branches/release30-maint/Lib/test/test_unicodedata.py Sat Apr 25 16:17:13 2009 @@ -20,7 +20,7 @@ class UnicodeMethodsTest(unittest.TestCase): # update this, if the database changes - expectedchecksum = 'aef99984a58c8e1e5363a3175f2ff9608599a93e' + expectedchecksum = 'b7db9b5f1d804976fa921d2009cbef6f025620c1' def test_method_checksum(self): h = hashlib.sha1() @@ -258,6 +258,19 @@ # the upper-case mapping: as delta, or as absolute value self.assert_("a".upper()=='A') self.assert_("\u1d79".upper()=='\ua77d') + self.assert_(".".upper()=='.') + + def test_bug_5828(self): + self.assertEqual("\u1d79".lower(), "\u1d79") + # Only U+0000 should have U+0000 as its upper/lower/titlecase variant + self.assertEqual( + [ + c for c in range(sys.maxunicode+1) + if "\x00" in chr(c).lower()+chr(c).upper()+chr(c).title() + ], + [0] + ) + def test_main(): test.support.run_unittest( Modified: python/branches/release30-maint/Misc/NEWS ============================================================================== --- python/branches/release30-maint/Misc/NEWS (original) +++ python/branches/release30-maint/Misc/NEWS Sat Apr 25 16:17:13 2009 @@ -55,6 +55,10 @@ guaranteed to be safe interp argument given to the PythonCmd in place of the Tcl interpreter taken from a PythonCmd_ClientData. +- Issue #5828 (Invalid behavior of unicode.lower): Fixed bogus logic in + makeunicodedata.py and regenerated the Unicode database (This fixes + u'\u1d79'.lower() == '\x00'). + - Issue #5193: Guarantee that tkinter.Text.search returns a string. - Issue #5334: array.fromfile() failed to insert values when EOFError was Modified: python/branches/release30-maint/Objects/unicodetype_db.h ============================================================================== --- python/branches/release30-maint/Objects/unicodetype_db.h (original) +++ python/branches/release30-maint/Objects/unicodetype_db.h Sat Apr 25 16:17:13 2009 @@ -127,7 +127,7 @@ {0, 0, 0, 0, 8, 1540}, {0, 0, 0, 0, 9, 1540}, {0, 0, 0, 0, 0, 1792}, - {42877, 0, 42877, 0, 0, 3849}, + {42877, 7545, 42877, 0, 0, 3849}, {3814, 0, 3814, 0, 0, 1801}, {65477, 0, 65477, 0, 0, 1801}, {0, 57921, 0, 0, 0, 1921}, @@ -174,7 +174,7 @@ {0, 54787, 0, 0, 0, 1921}, {0, 54753, 0, 0, 0, 1921}, {58272, 0, 58272, 0, 0, 1801}, - {0, 7545, 0, 0, 0, 3969}, + {42877, 7545, 42877, 0, 0, 3969}, {0, 40, 0, 0, 0, 1921}, {65496, 0, 65496, 0, 0, 1801}, }; Modified: python/branches/release30-maint/Tools/unicode/makeunicodedata.py ============================================================================== --- python/branches/release30-maint/Tools/unicode/makeunicodedata.py (original) +++ python/branches/release30-maint/Tools/unicode/makeunicodedata.py Sat Apr 25 16:17:13 2009 @@ -383,33 +383,32 @@ flags |= XID_CONTINUE_MASK # use delta predictor for upper/lower/title if it fits if record[12]: - upper = int(record[12], 16) - char - if -32768 <= upper <= 32767 and delta: - upper = upper & 0xffff - else: - upper += char - delta = False + upper = int(record[12], 16) else: - upper = 0 + upper = char if record[13]: - lower = int(record[13], 16) - char - if -32768 <= lower <= 32767 and delta: - lower = lower & 0xffff - else: - lower += char - delta = False + lower = int(record[13], 16) else: - lower = 0 + lower = char if record[14]: - title = int(record[14], 16) - char - if -32768 <= lower <= 32767 and delta: - title = title & 0xffff - else: - title += char - delta = False + title = int(record[14], 16) + else: + # UCD.html says that a missing title char means that + # it defaults to the uppercase character, not to the + # character itself. Apparently, in the current UCD (5.x) + # this feature is never used + title = upper + upper_d = upper - char + lower_d = lower - char + title_d = title - char + if -32768 <= upper_d <= 32767 and \ + -32768 <= lower_d <= 32767 and \ + -32768 <= title_d <= 32767: + # use deltas + upper = upper_d & 0xffff + lower = lower_d & 0xffff + title = title_d & 0xffff else: - title = 0 - if not delta: flags |= NODELTA_MASK # decimal digit, integer digit decimal = 0 From python-checkins at python.org Sat Apr 25 16:24:31 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 16:24:31 +0200 (CEST) Subject: [Python-checkins] r71898 - python/trunk/Doc/c-api/dict.rst Message-ID: <20090425142431.34AC61E4010@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 16:24:30 2009 New Revision: 71898 Log: Reformat prior to editing. Modified: python/trunk/Doc/c-api/dict.rst Modified: python/trunk/Doc/c-api/dict.rst ============================================================================== --- python/trunk/Doc/c-api/dict.rst (original) +++ python/trunk/Doc/c-api/dict.rst Sat Apr 25 16:24:30 2009 @@ -19,8 +19,9 @@ single: DictType (in module types) single: DictionaryType (in module types) - This instance of :ctype:`PyTypeObject` represents the Python dictionary type. - This is exposed to Python programs as ``dict`` and ``types.DictType``. + This instance of :ctype:`PyTypeObject` represents the Python dictionary + type. This is exposed to Python programs as ``dict`` and + ``types.DictType``. .. cfunction:: int PyDict_Check(PyObject *p) @@ -34,8 +35,8 @@ .. cfunction:: int PyDict_CheckExact(PyObject *p) - Return true if *p* is a dict object, but not an instance of a subtype of the - dict type. + Return true if *p* is a dict object, but not an instance of a subtype of + the dict type. .. versionadded:: 2.4 @@ -47,9 +48,9 @@ .. cfunction:: PyObject* PyDictProxy_New(PyObject *dict) - Return a proxy object for a mapping which enforces read-only behavior. This is - normally used to create a proxy to prevent modification of the dictionary for - non-dynamic class types. + Return a proxy object for a mapping which enforces read-only behavior. + This is normally used to create a proxy to prevent modification of the + dictionary for non-dynamic class types. .. versionadded:: 2.2 @@ -61,9 +62,9 @@ .. cfunction:: int PyDict_Contains(PyObject *p, PyObject *key) - Determine if dictionary *p* contains *key*. If an item in *p* is matches *key*, - return ``1``, otherwise return ``0``. On error, return ``-1``. This is - equivalent to the Python expression ``key in p``. + Determine if dictionary *p* contains *key*. If an item in *p* is matches + *key*, return ``1``, otherwise return ``0``. On error, return ``-1``. + This is equivalent to the Python expression ``key in p``. .. versionadded:: 2.4 @@ -78,24 +79,25 @@ .. cfunction:: int PyDict_SetItem(PyObject *p, PyObject *key, PyObject *val) Insert *value* into the dictionary *p* with a key of *key*. *key* must be - :term:`hashable`; if it isn't, :exc:`TypeError` will be raised. Return ``0`` - on success or ``-1`` on failure. + :term:`hashable`; if it isn't, :exc:`TypeError` will be raised. Return + ``0`` on success or ``-1`` on failure. .. cfunction:: int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val) .. index:: single: PyString_FromString() - Insert *value* into the dictionary *p* using *key* as a key. *key* should be a - :ctype:`char\*`. The key object is created using ``PyString_FromString(key)``. - Return ``0`` on success or ``-1`` on failure. + Insert *value* into the dictionary *p* using *key* as a key. *key* should + be a :ctype:`char\*`. The key object is created using + ``PyString_FromString(key)``. Return ``0`` on success or ``-1`` on + failure. .. cfunction:: int PyDict_DelItem(PyObject *p, PyObject *key) - Remove the entry in dictionary *p* with key *key*. *key* must be hashable; if it - isn't, :exc:`TypeError` is raised. Return ``0`` on success or ``-1`` on - failure. + Remove the entry in dictionary *p* with key *key*. *key* must be hashable; + if it isn't, :exc:`TypeError` is raised. Return ``0`` on success or ``-1`` + on failure. .. cfunction:: int PyDict_DelItemString(PyObject *p, char *key) @@ -106,8 +108,8 @@ .. cfunction:: PyObject* PyDict_GetItem(PyObject *p, PyObject *key) - Return the object from dictionary *p* which has a key *key*. Return *NULL* if - the key *key* is not present, but *without* setting an exception. + Return the object from dictionary *p* which has a key *key*. Return *NULL* + if the key *key* is not present, but *without* setting an exception. .. cfunction:: PyObject* PyDict_GetItemString(PyObject *p, const char *key) @@ -118,41 +120,42 @@ .. cfunction:: PyObject* PyDict_Items(PyObject *p) - Return a :ctype:`PyListObject` containing all the items from the dictionary, as - in the dictionary method :meth:`dict.items`. + Return a :ctype:`PyListObject` containing all the items from the + dictionary, as in the dictionary method :meth:`dict.items`. .. cfunction:: PyObject* PyDict_Keys(PyObject *p) - Return a :ctype:`PyListObject` containing all the keys from the dictionary, as - in the dictionary method :meth:`dict.keys`. + Return a :ctype:`PyListObject` containing all the keys from the dictionary, + as in the dictionary method :meth:`dict.keys`. .. cfunction:: PyObject* PyDict_Values(PyObject *p) - Return a :ctype:`PyListObject` containing all the values from the dictionary - *p*, as in the dictionary method :meth:`dict.values`. + Return a :ctype:`PyListObject` containing all the values from the + dictionary *p*, as in the dictionary method :meth:`dict.values`. .. cfunction:: Py_ssize_t PyDict_Size(PyObject *p) .. index:: builtin: len - Return the number of items in the dictionary. This is equivalent to ``len(p)`` - on a dictionary. + Return the number of items in the dictionary. This is equivalent to + ``len(p)`` on a dictionary. .. cfunction:: int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) Iterate over all key-value pairs in the dictionary *p*. The :ctype:`int` - referred to by *ppos* must be initialized to ``0`` prior to the first call to - this function to start the iteration; the function returns true for each pair in - the dictionary, and false once all pairs have been reported. The parameters - *pkey* and *pvalue* should either point to :ctype:`PyObject\*` variables that - will be filled in with each key and value, respectively, or may be *NULL*. Any - references returned through them are borrowed. *ppos* should not be altered - during iteration. Its value represents offsets within the internal dictionary - structure, and since the structure is sparse, the offsets are not consecutive. + referred to by *ppos* must be initialized to ``0`` prior to the first call + to this function to start the iteration; the function returns true for each + pair in the dictionary, and false once all pairs have been reported. The + parameters *pkey* and *pvalue* should either point to :ctype:`PyObject\*` + variables that will be filled in with each key and value, respectively, or + may be *NULL*. Any references returned through them are borrowed. *ppos* + should not be altered during iteration. Its value represents offsets within + the internal dictionary structure, and since the structure is sparse, the + offsets are not consecutive. For example:: @@ -164,9 +167,10 @@ ... } - The dictionary *p* should not be mutated during iteration. It is safe (since - Python 2.1) to modify the values of the keys as you iterate over the dictionary, - but only so long as the set of keys does not change. For example:: + The dictionary *p* should not be mutated during iteration. It is safe + (since Python 2.1) to modify the values of the keys as you iterate over the + dictionary, but only so long as the set of keys does not change. For + example:: PyObject *key, *value; Py_ssize_t pos = 0; @@ -186,12 +190,12 @@ .. cfunction:: int PyDict_Merge(PyObject *a, PyObject *b, int override) - Iterate over mapping object *b* adding key-value pairs to dictionary *a*. *b* - may be a dictionary, or any object supporting :func:`PyMapping_Keys` and - :func:`PyObject_GetItem`. If *override* is true, existing pairs in *a* will be - replaced if a matching key is found in *b*, otherwise pairs will only be added - if there is not a matching key in *a*. Return ``0`` on success or ``-1`` if an - exception was raised. + Iterate over mapping object *b* adding key-value pairs to dictionary *a*. + *b* may be a dictionary, or any object supporting :func:`PyMapping_Keys` + and :func:`PyObject_GetItem`. If *override* is true, existing pairs in *a* + will be replaced if a matching key is found in *b*, otherwise pairs will + only be added if there is not a matching key in *a*. Return ``0`` on + success or ``-1`` if an exception was raised. .. versionadded:: 2.2 @@ -206,11 +210,12 @@ .. cfunction:: int PyDict_MergeFromSeq2(PyObject *a, PyObject *seq2, int override) - Update or merge into dictionary *a*, from the key-value pairs in *seq2*. *seq2* - must be an iterable object producing iterable objects of length 2, viewed as - key-value pairs. In case of duplicate keys, the last wins if *override* is - true, else the first wins. Return ``0`` on success or ``-1`` if an exception was - raised. Equivalent Python (except for the return value):: + Update or merge into dictionary *a*, from the key-value pairs in *seq2*. + *seq2* must be an iterable object producing iterable objects of length 2, + viewed as key-value pairs. In case of duplicate keys, the last wins if + *override* is true, else the first wins. Return ``0`` on success or ``-1`` + if an exception was raised. Equivalent Python (except for the return + value):: def PyDict_MergeFromSeq2(a, seq2, override): for key, value in seq2: From python-checkins at python.org Sat Apr 25 16:27:01 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 16:27:01 +0200 (CEST) Subject: [Python-checkins] r71899 - python/trunk/Doc/c-api/dict.rst Message-ID: <20090425142701.1DD461E4010@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 16:27:00 2009 New Revision: 71899 Log: The type for ppos has been Py_ssize_t since 2.5, reflect this in the documentation. Modified: python/trunk/Doc/c-api/dict.rst Modified: python/trunk/Doc/c-api/dict.rst ============================================================================== --- python/trunk/Doc/c-api/dict.rst (original) +++ python/trunk/Doc/c-api/dict.rst Sat Apr 25 16:27:00 2009 @@ -146,7 +146,7 @@ .. cfunction:: int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) - Iterate over all key-value pairs in the dictionary *p*. The :ctype:`int` + Iterate over all key-value pairs in the dictionary *p*. The :ctype:`Py_ssize_t` referred to by *ppos* must be initialized to ``0`` prior to the first call to this function to start the iteration; the function returns true for each pair in the dictionary, and false once all pairs have been reported. The From python-checkins at python.org Sat Apr 25 16:28:02 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 16:28:02 +0200 (CEST) Subject: [Python-checkins] r71900 - python/trunk/Doc/c-api/dict.rst Message-ID: <20090425142802.55ECF1E4010@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 16:28:02 2009 New Revision: 71900 Log: Reformat paragraph. Modified: python/trunk/Doc/c-api/dict.rst Modified: python/trunk/Doc/c-api/dict.rst ============================================================================== --- python/trunk/Doc/c-api/dict.rst (original) +++ python/trunk/Doc/c-api/dict.rst Sat Apr 25 16:28:02 2009 @@ -146,16 +146,16 @@ .. cfunction:: int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) - Iterate over all key-value pairs in the dictionary *p*. The :ctype:`Py_ssize_t` - referred to by *ppos* must be initialized to ``0`` prior to the first call - to this function to start the iteration; the function returns true for each - pair in the dictionary, and false once all pairs have been reported. The - parameters *pkey* and *pvalue* should either point to :ctype:`PyObject\*` - variables that will be filled in with each key and value, respectively, or - may be *NULL*. Any references returned through them are borrowed. *ppos* - should not be altered during iteration. Its value represents offsets within - the internal dictionary structure, and since the structure is sparse, the - offsets are not consecutive. + Iterate over all key-value pairs in the dictionary *p*. The + :ctype:`Py_ssize_t` referred to by *ppos* must be initialized to ``0`` + prior to the first call to this function to start the iteration; the + function returns true for each pair in the dictionary, and false once all + pairs have been reported. The parameters *pkey* and *pvalue* should either + point to :ctype:`PyObject\*` variables that will be filled in with each key + and value, respectively, or may be *NULL*. Any references returned through + them are borrowed. *ppos* should not be altered during iteration. Its + value represents offsets within the internal dictionary structure, and + since the structure is sparse, the offsets are not consecutive. For example:: From buildbot at python.org Sat Apr 25 16:44:31 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 14:44:31 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo trunk Message-ID: <20090425144431.D82C01E4010@bag.python.org> The Buildbot has detected a new failure of x86 gentoo trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%20trunk/builds/4873 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: jeroen.ruigrok,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Sat Apr 25 16:50:26 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 25 Apr 2009 16:50:26 +0200 (CEST) Subject: [Python-checkins] r71901 - python/trunk/Doc/includes/mp_distributing.py Message-ID: <20090425145026.269B71E4010@bag.python.org> Author: georg.brandl Date: Sat Apr 25 16:50:25 2009 New Revision: 71901 Log: #3320: fix spelling. Modified: python/trunk/Doc/includes/mp_distributing.py Modified: python/trunk/Doc/includes/mp_distributing.py ============================================================================== --- python/trunk/Doc/includes/mp_distributing.py (original) +++ python/trunk/Doc/includes/mp_distributing.py Sat Apr 25 16:50:25 2009 @@ -38,7 +38,7 @@ return _logger _logger = logging.getLogger('distributing') -_logger.propogate = 0 +_logger.propagate = 0 _formatter = logging.Formatter(util.DEFAULT_LOGGING_FORMAT) _handler = logging.StreamHandler() From buildbot at python.org Sat Apr 25 16:51:12 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 14:51:12 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable trunk Message-ID: <20090425145112.394D11E4010@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%20trunk/builds/412 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: jeroen.ruigrok,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_os ====================================================================== FAIL: test_update2 (test.test_os.EnvironTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/test/test_os.py", line 348, in test_update2 self.assertEquals(value, "World") AssertionError: '' != 'World' make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sat Apr 25 16:51:31 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 25 Apr 2009 16:51:31 +0200 (CEST) Subject: [Python-checkins] r71902 - python/trunk/Doc/library/unittest.rst Message-ID: <20090425145131.F2E9D1E4010@bag.python.org> Author: georg.brandl Date: Sat Apr 25 16:51:31 2009 New Revision: 71902 Log: #5834: use "failure" instead of "error" because the two have different meanings in unittest context. Modified: python/trunk/Doc/library/unittest.rst Modified: python/trunk/Doc/library/unittest.rst ============================================================================== --- python/trunk/Doc/library/unittest.rst (original) +++ python/trunk/Doc/library/unittest.rst Sat Apr 25 16:51:31 2009 @@ -609,7 +609,7 @@ assert_(expr[, msg]) failUnless(expr[, msg]) - Signal a test failure if *expr* is false; the explanation for the error + Signal a test failure if *expr* is false; the explanation for the failure will be *msg* if given, otherwise it will be :const:`None`. .. deprecated:: 2.7 From buildbot at python.org Sat Apr 25 16:52:18 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 14:52:18 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 2.6 Message-ID: <20090425145218.923471E4010@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%202.6/builds/275 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: walter.doerwald BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Sat Apr 25 17:05:04 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 25 Apr 2009 17:05:04 +0200 (CEST) Subject: [Python-checkins] r71903 - python/trunk/Doc/library/tarfile.rst Message-ID: <20090425150504.B182D1E4010@bag.python.org> Author: georg.brandl Date: Sat Apr 25 17:05:04 2009 New Revision: 71903 Log: #5821: add some capabilities of TarFile's file-like object. Modified: python/trunk/Doc/library/tarfile.rst Modified: python/trunk/Doc/library/tarfile.rst ============================================================================== --- python/trunk/Doc/library/tarfile.rst (original) +++ python/trunk/Doc/library/tarfile.rst Sat Apr 25 17:05:04 2009 @@ -384,8 +384,9 @@ .. note:: - The file-like object is read-only and provides the following methods: - :meth:`read`, :meth:`readline`, :meth:`readlines`, :meth:`seek`, :meth:`tell`. + The file-like object is read-only. It provides the methods + :meth:`read`, :meth:`readline`, :meth:`readlines`, :meth:`seek`, :meth:`tell`, + and :meth:`close`, and also supports iteration over its lines. .. method:: TarFile.add(name, arcname=None, recursive=True, exclude=None) From buildbot at python.org Sat Apr 25 17:08:11 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 15:08:11 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 2.6 Message-ID: <20090425150811.DAC121E4027@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%202.6/builds/284 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: mark.dickinson,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Sat Apr 25 17:11:29 2009 From: python-checkins at python.org (georg.brandl) Date: Sat, 25 Apr 2009 17:11:29 +0200 (CEST) Subject: [Python-checkins] r71904 - in python/trunk: Doc/library/commands.rst Lib/commands.py Message-ID: <20090425151129.D10701E4010@bag.python.org> Author: georg.brandl Date: Sat Apr 25 17:11:29 2009 New Revision: 71904 Log: #5841: add deprecation py3k warning and notice in the docs for commands module. Modified: python/trunk/Doc/library/commands.rst python/trunk/Lib/commands.py Modified: python/trunk/Doc/library/commands.rst ============================================================================== --- python/trunk/Doc/library/commands.rst (original) +++ python/trunk/Doc/library/commands.rst Sat Apr 25 17:11:29 2009 @@ -5,6 +5,12 @@ .. module:: commands :platform: Unix :synopsis: Utility functions for running external commands. + :deprecated: + +.. deprecated:: 2.6 + The :mod:`commands` module has been removed in Python 3.0. Use the + :mod:`subprocess` module instead. + .. sectionauthor:: Sue Williams Modified: python/trunk/Lib/commands.py ============================================================================== --- python/trunk/Lib/commands.py (original) +++ python/trunk/Lib/commands.py Sat Apr 25 17:11:29 2009 @@ -18,6 +18,10 @@ [Note: it would be nice to add functions to interpret the exit status.] """ +from warnings import warnpy3k +warnpy3k("the commands module has been removed in Python 3.0; " + "use the subprocess module instead", stacklevel=2) +del warnpy3k __all__ = ["getstatusoutput","getoutput","getstatus"] @@ -63,8 +67,6 @@ # Make command argument from directory and pathname (prefix space, add quotes). # def mk2arg(head, x): - from warnings import warnpy3k - warnpy3k("In 3.x, mk2arg has been removed.") import os return mkarg(os.path.join(head, x)) @@ -77,8 +79,6 @@ # with backslash. # def mkarg(x): - from warnings import warnpy3k - warnpy3k("in 3.x, mkarg has been removed.") if '\'' not in x: return ' \'' + x + '\'' s = ' "' From buildbot at python.org Sat Apr 25 17:28:38 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 15:28:38 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090425152838.DC3CE1E4010@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/637 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_cmath make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Sat Apr 25 18:34:05 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 16:34:05 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 3.x Message-ID: <20090425163406.079991E4010@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%203.x/builds/679 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: tarek.ziade,walter.doerwald BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_os test_time make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sat Apr 25 18:36:03 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 25 Apr 2009 18:36:03 +0200 (CEST) Subject: [Python-checkins] r71905 - tracker/instances/python-dev/extensions/local_replace.py Message-ID: <20090425163603.F19491E404D@bag.python.org> Author: martin.v.loewis Date: Sat Apr 25 18:36:03 2009 New Revision: 71905 Log: Issue #276: Fix regular expressions. Modified: tracker/instances/python-dev/extensions/local_replace.py Modified: tracker/instances/python-dev/extensions/local_replace.py ============================================================================== --- tracker/instances/python-dev/extensions/local_replace.py (original) +++ tracker/instances/python-dev/extensions/local_replace.py Sat Apr 25 18:36:03 2009 @@ -8,8 +8,8 @@ "\grev\g\g"), (re.compile('(?P\s+)(?Pr|r\s+)(?P\d+)'), "\g\g\g"), - (re.compile('(?P\s+)(?P(Demo|Doc|Grammar|Include|Lib|Mac|Misc|Modules|Parser|PC|PCbuild|Python|RISCOS|Tools)/[-.a-zA-Z0-9]+[a-zA-Z0-9])'), - "\g\g"), + (re.compile(r'\b(?P(?:Demo|Doc|Grammar|Include|Lib|Mac|Misc|Modules|Parser|PC|PCbuild|Python|RISCOS|Tools|Objects)/[-.a-zA-Z0-9_/]+[a-zA-Z0-9]/?)'), + '\g'), ] def localReplace(message): From python-checkins at python.org Sat Apr 25 18:37:18 2009 From: python-checkins at python.org (thomas.heller) Date: Sat, 25 Apr 2009 18:37:18 +0200 (CEST) Subject: [Python-checkins] r71906 - python/trunk/Modules/_ctypes/callproc.c Message-ID: <20090425163718.828711E4010@bag.python.org> Author: thomas.heller Date: Sat Apr 25 18:37:18 2009 New Revision: 71906 Log: Issue #5087: Avoid redundant call to FormatError() Modified: python/trunk/Modules/_ctypes/callproc.c Modified: python/trunk/Modules/_ctypes/callproc.c ============================================================================== --- python/trunk/Modules/_ctypes/callproc.c (original) +++ python/trunk/Modules/_ctypes/callproc.c Sat Apr 25 18:37:18 2009 @@ -234,154 +234,150 @@ } #ifndef DONT_USE_SEH -void SetException(DWORD code, EXCEPTION_RECORD *pr) +static void SetException(DWORD code, EXCEPTION_RECORD *pr) { - TCHAR *lpMsgBuf; - lpMsgBuf = FormatError(code); - if(lpMsgBuf) { - PyErr_SetFromWindowsErr(code); - LocalFree(lpMsgBuf); - } else { - switch (code) { - case EXCEPTION_ACCESS_VIOLATION: - /* The thread attempted to read from or write - to a virtual address for which it does not - have the appropriate access. */ - if (pr->ExceptionInformation[0] == 0) - PyErr_Format(PyExc_WindowsError, - "exception: access violation reading %p", - pr->ExceptionInformation[1]); - else - PyErr_Format(PyExc_WindowsError, - "exception: access violation writing %p", - pr->ExceptionInformation[1]); - break; - case EXCEPTION_BREAKPOINT: - /* A breakpoint was encountered. */ - PyErr_SetString(PyExc_WindowsError, - "exception: breakpoint encountered"); - break; - - case EXCEPTION_DATATYPE_MISALIGNMENT: - /* The thread attempted to read or write data that is - misaligned on hardware that does not provide - alignment. For example, 16-bit values must be - aligned on 2-byte boundaries, 32-bit values on - 4-byte boundaries, and so on. */ - PyErr_SetString(PyExc_WindowsError, - "exception: datatype misalignment"); - break; - - case EXCEPTION_SINGLE_STEP: - /* A trace trap or other single-instruction mechanism - signaled that one instruction has been executed. */ - PyErr_SetString(PyExc_WindowsError, - "exception: single step"); - break; - - case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: - /* The thread attempted to access an array element - that is out of bounds, and the underlying hardware - supports bounds checking. */ - PyErr_SetString(PyExc_WindowsError, - "exception: array bounds exceeded"); - break; - - case EXCEPTION_FLT_DENORMAL_OPERAND: - /* One of the operands in a floating-point operation - is denormal. A denormal value is one that is too - small to represent as a standard floating-point - value. */ - PyErr_SetString(PyExc_WindowsError, - "exception: floating-point operand denormal"); - break; - - case EXCEPTION_FLT_DIVIDE_BY_ZERO: - /* The thread attempted to divide a floating-point - value by a floating-point divisor of zero. */ - PyErr_SetString(PyExc_WindowsError, - "exception: float divide by zero"); - break; - - case EXCEPTION_FLT_INEXACT_RESULT: - /* The result of a floating-point operation cannot be - represented exactly as a decimal fraction. */ - PyErr_SetString(PyExc_WindowsError, - "exception: float inexact"); - break; - - case EXCEPTION_FLT_INVALID_OPERATION: - /* This exception represents any floating-point - exception not included in this list. */ - PyErr_SetString(PyExc_WindowsError, - "exception: float invalid operation"); - break; - - case EXCEPTION_FLT_OVERFLOW: - /* The exponent of a floating-point operation is - greater than the magnitude allowed by the - corresponding type. */ - PyErr_SetString(PyExc_WindowsError, - "exception: float overflow"); - break; - - case EXCEPTION_FLT_STACK_CHECK: - /* The stack overflowed or underflowed as the result - of a floating-point operation. */ - PyErr_SetString(PyExc_WindowsError, - "exception: stack over/underflow"); - break; - - case EXCEPTION_STACK_OVERFLOW: - /* The stack overflowed or underflowed as the result - of a floating-point operation. */ - PyErr_SetString(PyExc_WindowsError, - "exception: stack overflow"); - break; - - case EXCEPTION_FLT_UNDERFLOW: - /* The exponent of a floating-point operation is less - than the magnitude allowed by the corresponding - type. */ - PyErr_SetString(PyExc_WindowsError, - "exception: float underflow"); - break; - - case EXCEPTION_INT_DIVIDE_BY_ZERO: - /* The thread attempted to divide an integer value by - an integer divisor of zero. */ - PyErr_SetString(PyExc_WindowsError, - "exception: integer divide by zero"); - break; - - case EXCEPTION_INT_OVERFLOW: - /* The result of an integer operation caused a carry - out of the most significant bit of the result. */ - PyErr_SetString(PyExc_WindowsError, - "exception: integer overflow"); - break; - - case EXCEPTION_PRIV_INSTRUCTION: - /* The thread attempted to execute an instruction - whose operation is not allowed in the current - machine mode. */ - PyErr_SetString(PyExc_WindowsError, - "exception: priviledged instruction"); - break; - - case EXCEPTION_NONCONTINUABLE_EXCEPTION: - /* The thread attempted to continue execution after a - noncontinuable exception occurred. */ - PyErr_SetString(PyExc_WindowsError, - "exception: nocontinuable"); - break; - default: - printf("error %d\n", code); + /* The 'code' is a normal win32 error code so it could be handled by + PyErr_SetFromWindowsErr(). However, for some errors, we have additional + information not included in the error code. We handle those here and + delegate all others to the generic function. */ + switch (code) { + case EXCEPTION_ACCESS_VIOLATION: + /* The thread attempted to read from or write + to a virtual address for which it does not + have the appropriate access. */ + if (pr->ExceptionInformation[0] == 0) PyErr_Format(PyExc_WindowsError, - "exception code 0x%08x", - code); - break; - } + "exception: access violation reading %p", + pr->ExceptionInformation[1]); + else + PyErr_Format(PyExc_WindowsError, + "exception: access violation writing %p", + pr->ExceptionInformation[1]); + break; + + case EXCEPTION_BREAKPOINT: + /* A breakpoint was encountered. */ + PyErr_SetString(PyExc_WindowsError, + "exception: breakpoint encountered"); + break; + + case EXCEPTION_DATATYPE_MISALIGNMENT: + /* The thread attempted to read or write data that is + misaligned on hardware that does not provide + alignment. For example, 16-bit values must be + aligned on 2-byte boundaries, 32-bit values on + 4-byte boundaries, and so on. */ + PyErr_SetString(PyExc_WindowsError, + "exception: datatype misalignment"); + break; + + case EXCEPTION_SINGLE_STEP: + /* A trace trap or other single-instruction mechanism + signaled that one instruction has been executed. */ + PyErr_SetString(PyExc_WindowsError, + "exception: single step"); + break; + + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + /* The thread attempted to access an array element + that is out of bounds, and the underlying hardware + supports bounds checking. */ + PyErr_SetString(PyExc_WindowsError, + "exception: array bounds exceeded"); + break; + + case EXCEPTION_FLT_DENORMAL_OPERAND: + /* One of the operands in a floating-point operation + is denormal. A denormal value is one that is too + small to represent as a standard floating-point + value. */ + PyErr_SetString(PyExc_WindowsError, + "exception: floating-point operand denormal"); + break; + + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + /* The thread attempted to divide a floating-point + value by a floating-point divisor of zero. */ + PyErr_SetString(PyExc_WindowsError, + "exception: float divide by zero"); + break; + + case EXCEPTION_FLT_INEXACT_RESULT: + /* The result of a floating-point operation cannot be + represented exactly as a decimal fraction. */ + PyErr_SetString(PyExc_WindowsError, + "exception: float inexact"); + break; + + case EXCEPTION_FLT_INVALID_OPERATION: + /* This exception represents any floating-point + exception not included in this list. */ + PyErr_SetString(PyExc_WindowsError, + "exception: float invalid operation"); + break; + + case EXCEPTION_FLT_OVERFLOW: + /* The exponent of a floating-point operation is + greater than the magnitude allowed by the + corresponding type. */ + PyErr_SetString(PyExc_WindowsError, + "exception: float overflow"); + break; + + case EXCEPTION_FLT_STACK_CHECK: + /* The stack overflowed or underflowed as the result + of a floating-point operation. */ + PyErr_SetString(PyExc_WindowsError, + "exception: stack over/underflow"); + break; + + case EXCEPTION_STACK_OVERFLOW: + /* The stack overflowed or underflowed as the result + of a floating-point operation. */ + PyErr_SetString(PyExc_WindowsError, + "exception: stack overflow"); + break; + + case EXCEPTION_FLT_UNDERFLOW: + /* The exponent of a floating-point operation is less + than the magnitude allowed by the corresponding + type. */ + PyErr_SetString(PyExc_WindowsError, + "exception: float underflow"); + break; + + case EXCEPTION_INT_DIVIDE_BY_ZERO: + /* The thread attempted to divide an integer value by + an integer divisor of zero. */ + PyErr_SetString(PyExc_WindowsError, + "exception: integer divide by zero"); + break; + + case EXCEPTION_INT_OVERFLOW: + /* The result of an integer operation caused a carry + out of the most significant bit of the result. */ + PyErr_SetString(PyExc_WindowsError, + "exception: integer overflow"); + break; + + case EXCEPTION_PRIV_INSTRUCTION: + /* The thread attempted to execute an instruction + whose operation is not allowed in the current + machine mode. */ + PyErr_SetString(PyExc_WindowsError, + "exception: priviledged instruction"); + break; + + case EXCEPTION_NONCONTINUABLE_EXCEPTION: + /* The thread attempted to continue execution after a + noncontinuable exception occurred. */ + PyErr_SetString(PyExc_WindowsError, + "exception: nocontinuable"); + break; + + default: + PyErr_SetFromWindowsErr(code); + break; } } From buildbot at python.org Sat Apr 25 18:39:10 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 16:39:10 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu trunk Message-ID: <20090425163910.9E5F11E4010@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%20trunk/builds/1186 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: georg.brandl,jeroen.ruigrok BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_os make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sat Apr 25 18:49:23 2009 From: python-checkins at python.org (thomas.heller) Date: Sat, 25 Apr 2009 18:49:23 +0200 (CEST) Subject: [Python-checkins] r71907 - in python/branches/py3k: Modules/_ctypes/callproc.c Message-ID: <20090425164923.AB9371E410E@bag.python.org> Author: thomas.heller Date: Sat Apr 25 18:49:23 2009 New Revision: 71907 Log: Merged revisions 71906 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71906 | thomas.heller | 2009-04-25 18:37:18 +0200 (Sa, 25 Apr 2009) | 1 line Issue #5087: Avoid redundant call to FormatError() ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Modules/_ctypes/callproc.c Modified: python/branches/py3k/Modules/_ctypes/callproc.c ============================================================================== --- python/branches/py3k/Modules/_ctypes/callproc.c (original) +++ python/branches/py3k/Modules/_ctypes/callproc.c Sat Apr 25 18:49:23 2009 @@ -229,154 +229,150 @@ } #ifndef DONT_USE_SEH -void SetException(DWORD code, EXCEPTION_RECORD *pr) +static void SetException(DWORD code, EXCEPTION_RECORD *pr) { - WCHAR *lpMsgBuf; - lpMsgBuf = FormatError(code); - if(lpMsgBuf) { - PyErr_SetFromWindowsErr(code); - LocalFree(lpMsgBuf); - } else { - switch (code) { - case EXCEPTION_ACCESS_VIOLATION: - /* The thread attempted to read from or write - to a virtual address for which it does not - have the appropriate access. */ - if (pr->ExceptionInformation[0] == 0) - PyErr_Format(PyExc_WindowsError, - "exception: access violation reading %p", - pr->ExceptionInformation[1]); - else - PyErr_Format(PyExc_WindowsError, - "exception: access violation writing %p", - pr->ExceptionInformation[1]); - break; - case EXCEPTION_BREAKPOINT: - /* A breakpoint was encountered. */ - PyErr_SetString(PyExc_WindowsError, - "exception: breakpoint encountered"); - break; - - case EXCEPTION_DATATYPE_MISALIGNMENT: - /* The thread attempted to read or write data that is - misaligned on hardware that does not provide - alignment. For example, 16-bit values must be - aligned on 2-byte boundaries, 32-bit values on - 4-byte boundaries, and so on. */ - PyErr_SetString(PyExc_WindowsError, - "exception: datatype misalignment"); - break; - - case EXCEPTION_SINGLE_STEP: - /* A trace trap or other single-instruction mechanism - signaled that one instruction has been executed. */ - PyErr_SetString(PyExc_WindowsError, - "exception: single step"); - break; - - case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: - /* The thread attempted to access an array element - that is out of bounds, and the underlying hardware - supports bounds checking. */ - PyErr_SetString(PyExc_WindowsError, - "exception: array bounds exceeded"); - break; - - case EXCEPTION_FLT_DENORMAL_OPERAND: - /* One of the operands in a floating-point operation - is denormal. A denormal value is one that is too - small to represent as a standard floating-point - value. */ - PyErr_SetString(PyExc_WindowsError, - "exception: floating-point operand denormal"); - break; - - case EXCEPTION_FLT_DIVIDE_BY_ZERO: - /* The thread attempted to divide a floating-point - value by a floating-point divisor of zero. */ - PyErr_SetString(PyExc_WindowsError, - "exception: float divide by zero"); - break; - - case EXCEPTION_FLT_INEXACT_RESULT: - /* The result of a floating-point operation cannot be - represented exactly as a decimal fraction. */ - PyErr_SetString(PyExc_WindowsError, - "exception: float inexact"); - break; - - case EXCEPTION_FLT_INVALID_OPERATION: - /* This exception represents any floating-point - exception not included in this list. */ - PyErr_SetString(PyExc_WindowsError, - "exception: float invalid operation"); - break; - - case EXCEPTION_FLT_OVERFLOW: - /* The exponent of a floating-point operation is - greater than the magnitude allowed by the - corresponding type. */ - PyErr_SetString(PyExc_WindowsError, - "exception: float overflow"); - break; - - case EXCEPTION_FLT_STACK_CHECK: - /* The stack overflowed or underflowed as the result - of a floating-point operation. */ - PyErr_SetString(PyExc_WindowsError, - "exception: stack over/underflow"); - break; - - case EXCEPTION_STACK_OVERFLOW: - /* The stack overflowed or underflowed as the result - of a floating-point operation. */ - PyErr_SetString(PyExc_WindowsError, - "exception: stack overflow"); - break; - - case EXCEPTION_FLT_UNDERFLOW: - /* The exponent of a floating-point operation is less - than the magnitude allowed by the corresponding - type. */ - PyErr_SetString(PyExc_WindowsError, - "exception: float underflow"); - break; - - case EXCEPTION_INT_DIVIDE_BY_ZERO: - /* The thread attempted to divide an integer value by - an integer divisor of zero. */ - PyErr_SetString(PyExc_WindowsError, - "exception: integer divide by zero"); - break; - - case EXCEPTION_INT_OVERFLOW: - /* The result of an integer operation caused a carry - out of the most significant bit of the result. */ - PyErr_SetString(PyExc_WindowsError, - "exception: integer overflow"); - break; - - case EXCEPTION_PRIV_INSTRUCTION: - /* The thread attempted to execute an instruction - whose operation is not allowed in the current - machine mode. */ - PyErr_SetString(PyExc_WindowsError, - "exception: priviledged instruction"); - break; - - case EXCEPTION_NONCONTINUABLE_EXCEPTION: - /* The thread attempted to continue execution after a - noncontinuable exception occurred. */ - PyErr_SetString(PyExc_WindowsError, - "exception: nocontinuable"); - break; - default: - printf("error %d\n", code); + /* The 'code' is a normal win32 error code so it could be handled by + PyErr_SetFromWindowsErr(). However, for some errors, we have additional + information not included in the error code. We handle those here and + delegate all others to the generic function. */ + switch (code) { + case EXCEPTION_ACCESS_VIOLATION: + /* The thread attempted to read from or write + to a virtual address for which it does not + have the appropriate access. */ + if (pr->ExceptionInformation[0] == 0) PyErr_Format(PyExc_WindowsError, - "exception code 0x%08x", - code); - break; - } + "exception: access violation reading %p", + pr->ExceptionInformation[1]); + else + PyErr_Format(PyExc_WindowsError, + "exception: access violation writing %p", + pr->ExceptionInformation[1]); + break; + + case EXCEPTION_BREAKPOINT: + /* A breakpoint was encountered. */ + PyErr_SetString(PyExc_WindowsError, + "exception: breakpoint encountered"); + break; + + case EXCEPTION_DATATYPE_MISALIGNMENT: + /* The thread attempted to read or write data that is + misaligned on hardware that does not provide + alignment. For example, 16-bit values must be + aligned on 2-byte boundaries, 32-bit values on + 4-byte boundaries, and so on. */ + PyErr_SetString(PyExc_WindowsError, + "exception: datatype misalignment"); + break; + + case EXCEPTION_SINGLE_STEP: + /* A trace trap or other single-instruction mechanism + signaled that one instruction has been executed. */ + PyErr_SetString(PyExc_WindowsError, + "exception: single step"); + break; + + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + /* The thread attempted to access an array element + that is out of bounds, and the underlying hardware + supports bounds checking. */ + PyErr_SetString(PyExc_WindowsError, + "exception: array bounds exceeded"); + break; + + case EXCEPTION_FLT_DENORMAL_OPERAND: + /* One of the operands in a floating-point operation + is denormal. A denormal value is one that is too + small to represent as a standard floating-point + value. */ + PyErr_SetString(PyExc_WindowsError, + "exception: floating-point operand denormal"); + break; + + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + /* The thread attempted to divide a floating-point + value by a floating-point divisor of zero. */ + PyErr_SetString(PyExc_WindowsError, + "exception: float divide by zero"); + break; + + case EXCEPTION_FLT_INEXACT_RESULT: + /* The result of a floating-point operation cannot be + represented exactly as a decimal fraction. */ + PyErr_SetString(PyExc_WindowsError, + "exception: float inexact"); + break; + + case EXCEPTION_FLT_INVALID_OPERATION: + /* This exception represents any floating-point + exception not included in this list. */ + PyErr_SetString(PyExc_WindowsError, + "exception: float invalid operation"); + break; + + case EXCEPTION_FLT_OVERFLOW: + /* The exponent of a floating-point operation is + greater than the magnitude allowed by the + corresponding type. */ + PyErr_SetString(PyExc_WindowsError, + "exception: float overflow"); + break; + + case EXCEPTION_FLT_STACK_CHECK: + /* The stack overflowed or underflowed as the result + of a floating-point operation. */ + PyErr_SetString(PyExc_WindowsError, + "exception: stack over/underflow"); + break; + + case EXCEPTION_STACK_OVERFLOW: + /* The stack overflowed or underflowed as the result + of a floating-point operation. */ + PyErr_SetString(PyExc_WindowsError, + "exception: stack overflow"); + break; + + case EXCEPTION_FLT_UNDERFLOW: + /* The exponent of a floating-point operation is less + than the magnitude allowed by the corresponding + type. */ + PyErr_SetString(PyExc_WindowsError, + "exception: float underflow"); + break; + + case EXCEPTION_INT_DIVIDE_BY_ZERO: + /* The thread attempted to divide an integer value by + an integer divisor of zero. */ + PyErr_SetString(PyExc_WindowsError, + "exception: integer divide by zero"); + break; + + case EXCEPTION_INT_OVERFLOW: + /* The result of an integer operation caused a carry + out of the most significant bit of the result. */ + PyErr_SetString(PyExc_WindowsError, + "exception: integer overflow"); + break; + + case EXCEPTION_PRIV_INSTRUCTION: + /* The thread attempted to execute an instruction + whose operation is not allowed in the current + machine mode. */ + PyErr_SetString(PyExc_WindowsError, + "exception: priviledged instruction"); + break; + + case EXCEPTION_NONCONTINUABLE_EXCEPTION: + /* The thread attempted to continue execution after a + noncontinuable exception occurred. */ + PyErr_SetString(PyExc_WindowsError, + "exception: nocontinuable"); + break; + + default: + PyErr_SetFromWindowsErr(code); + break; } } From buildbot at python.org Sat Apr 25 18:50:22 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 16:50:22 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090425165022.A1B051E4110@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/298 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: tarek.ziade,walter.doerwald BUILD FAILED: failed test Excerpt from the test logfile: 3 tests failed: test_distutils test_posix test_subprocess ====================================================================== FAIL: test_get_python_inc (distutils.tests.test_sysconfig.SysconfigTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/distutils/tests/test_sysconfig.py", line 45, in test_get_python_inc self.assert_(os.path.isdir(inc_dir), inc_dir) AssertionError: /home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/Include ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From buildbot at python.org Sat Apr 25 18:50:29 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 16:50:29 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu trunk Message-ID: <20090425165029.64CE51E401B@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%20trunk/builds/1277 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: jeroen.ruigrok,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: ======= Backtrace: ========= /lib/libc.so.6.1[0x200000000025ade0] /lib/libc.so.6.1(cfree-0x41bc3a0)[0x200000000025f460] /usr/lib/libdb-4.7.so(__os_free-0x288b670)[0x2000000001b901a0] /usr/lib/libdb-4.7.so(__os_closehandle-0x2889130)[0x2000000001b926f0] /usr/lib/libdb-4.7.so(__fop_file_setup-0x28ca840)[0x2000000001b50ff0] /usr/lib/libdb-4.7.so(__db_open-0x2926fe0)[0x2000000001af4860] /usr/lib/libdb-4.7.so(__db_open_pp+0x8fac10)[0x2000000001ae51f0] /home/pybot/buildarea/trunk.klose-debian-ia64/build/build/lib.linux-ia64-2.7-pydebug/_bsddb.so[0x20000000018b26f0] ./python(PyCFunction_Call+0x20000000003dd8c0)[0x4000000000428250] ./python[0x4000000000282c30] ./python(PyEval_EvalFrameEx+0x1ffffffffbe56ed0)[0x4000000000272720] ./python(PyEval_EvalCodeEx+0x1ffffffffbe5edc0)[0x400000000027a620] ./python[0x4000000000283ec0] ./python[0x4000000000283220] ./python(PyEval_EvalFrameEx+0x1ffffffffbe56ed0)[0x4000000000272720] ./python(PyEval_EvalCodeEx+0x1ffffffffbe5edc0)[0x400000000027a620] ./python[0x4000000000283ec0] ./python[0x4000000000283220] ./python(PyEval_EvalFrameEx+0x1ffffffffbe56ed0)[0x4000000000272720] ./python(PyEval_EvalCodeEx+0x1ffffffffbe5edc0)[0x400000000027a620] ./python[0x4000000000283ec0] ./python[0x4000000000283220] ./python(PyEval_EvalFrameEx+0x1ffffffffbe56ed0)[0x4000000000272720] ./python(PyEval_EvalCodeEx+0x1ffffffffbe5edc0)[0x400000000027a620] ./python[0x400000000041eb70] ./python(PyObject_Call+0x1ffffffffbc28040)[0x40000000000438b0] ./python[0x4000000000066630] ./python(PyObject_Call+0x1ffffffffbc28040)[0x40000000000438b0] ./python(PyEval_CallObjectWithKeywords+0x1ffffffffbe65760)[0x4000000000280fe0] ./python(PyInstance_New+0x2000000000004760)[0x400000000004eee0] ./python(PyObject_Call+0x1ffffffffbc28040)[0x40000000000438b0] ./python[0x4000000000285540] ./python[0x4000000000283280] ./python(PyEval_EvalFrameEx+0x1ffffffffbe56ed0)[0x4000000000272720] ./python(PyEval_EvalCodeEx+0x1ffffffffbe5edc0)[0x400000000027a620] ./python[0x400000000041eb70] ./python(PyObject_Call+0x1ffffffffbc28040)[0x40000000000438b0] ./python[0x4000000000286420] ./python(PyEval_EvalFrameEx+0x1ffffffffbe576b0)[0x4000000000272f00] ./python[0x4000000000283b40] ./python[0x4000000000283220] ./python(PyEval_EvalFrameEx+0x1ffffffffbe56ed0)[0x4000000000272720] ./python(PyEval_EvalCodeEx+0x1ffffffffbe5edc0)[0x400000000027a620] ./python[0x4000000000283ec0] ./python[0x4000000000283220] ./python(PyEval_EvalFrameEx+0x1ffffffffbe56ed0)[0x4000000000272720] ./python(PyEval_EvalCodeEx+0x1ffffffffbe5edc0)[0x400000000027a620] ./python[0x400000000041eb70] ./python(PyObject_Call+0x1ffffffffbc28040)[0x40000000000438b0] ./python[0x4000000000286420] ./python(PyEval_EvalFrameEx+0x1ffffffffbe576b0)[0x4000000000272f00] ./python(PyEval_EvalCodeEx+0x1ffffffffbe5edc0)[0x400000000027a620] ./python[0x400000000041eb70] ./python(PyObject_Call+0x1ffffffffbc28040)[0x40000000000438b0] ./python[0x4000000000066630] ./python(PyObject_Call+0x1ffffffffbc28040)[0x40000000000438b0] ./python[0x40000000001c1bb0] ./python(PyObject_Call+0x1ffffffffbc28040)[0x40000000000438b0] ./python[0x4000000000285540] ./python[0x4000000000283280] ./python(PyEval_EvalFrameEx+0x1ffffffffbe56ed0)[0x4000000000272720] ./python[0x4000000000283b40] ./python[0x4000000000283220] ======= Memory map: ======== 00000000-00004000 r--p 00000000 00:00 0 2000000000000000-200000000003c000 r-xp 00000000 03:05 2420685 /lib/ld-2.8.so 2000000000048000-2000000000050000 rw-p 00038000 03:05 2420685 /lib/ld-2.8.so 2000000000050000-2000000000078000 r-xp 00000000 03:05 2420667 /lib/libpthread-2.8.so 2000000000078000-2000000000084000 ---p 00028000 03:05 2420667 /lib/libpthread-2.8.so 2000000000084000-200000000008c000 rw-p 00024000 03:05 2420667 /lib/libpthread-2.8.so 200000000008c000-2000000000094000 rw-p 200000000008c000 00:00 0 2000000000094000-200000000009c000 r-xp 00000000 03:05 2420682 /lib/libdl-2.8.so 200000000009c000-20000000000a8000 ---p 00008000 03:05 2420682 /lib/libdlmake: *** [buildbottest] Aborted sincerely, -The Buildbot From python-checkins at python.org Sat Apr 25 19:26:39 2009 From: python-checkins at python.org (kurt.kaiser) Date: Sat, 25 Apr 2009 19:26:39 +0200 (CEST) Subject: [Python-checkins] r71908 - in python/branches/release26-maint: Lib/idlelib/CREDITS.txt Lib/idlelib/EditorWindow.py Lib/idlelib/NEWS.txt Lib/idlelib/idlever.py Message-ID: <20090425172639.C293C1E4010@bag.python.org> Author: kurt.kaiser Date: Sat Apr 25 19:26:39 2009 New Revision: 71908 Log: Merged revisions 71812 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71812 | kurt.kaiser | 2009-04-22 22:36:01 -0400 (Wed, 22 Apr 2009) | 2 lines Produce correct version string to access the .chm docs on Windows. Patch 5783 gpolo. Will port. ........ Also, I straightened out NEWS.txt, bumped idlever.py, and updated CREDITS.txt. Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/idlelib/CREDITS.txt python/branches/release26-maint/Lib/idlelib/EditorWindow.py python/branches/release26-maint/Lib/idlelib/NEWS.txt python/branches/release26-maint/Lib/idlelib/idlever.py Modified: python/branches/release26-maint/Lib/idlelib/CREDITS.txt ============================================================================== --- python/branches/release26-maint/Lib/idlelib/CREDITS.txt (original) +++ python/branches/release26-maint/Lib/idlelib/CREDITS.txt Sat Apr 25 19:26:39 2009 @@ -2,9 +2,9 @@ original creator of IDLE. Other contributors prior to Version 0.8 include Mark Hammond, Jeremy Hylton, Tim Peters, and Moshe Zadka. -IDLE's recent development has been carried out in the IDLEfork project. -The objective was to develop a version of IDLE which had an execution -environment which could be initialized prior to each run of user code. +IDLE's recent development was carried out in the SF IDLEfork project. The +objective was to develop a version of IDLE which had an execution environment +which could be initialized prior to each run of user code. The IDLEfork project was initiated by David Scherer, with some help from Peter Schneider-Kamp and Nicholas Riley. David wrote the first version of the RPC @@ -12,7 +12,7 @@ the RPC code and Remote Debugger currently integrated in IDLE. Bruce Sherwood contributed considerable time testing and suggesting improvements. -Besides David and Guido, the main developers who have been active on IDLEfork +Besides David and Guido, the main developers who were active on IDLEfork are Stephen M. Gava, who implemented the configuration GUI, the new configuration system, and the About dialog, and Kurt B. Kaiser, who completed the integration of the RPC and remote debugger, implemented the threaded @@ -24,8 +24,9 @@ integration, debugger integration and persistent breakpoints). Scott David Daniels, Tal Einat, Hernan Foffani, Christos Georgiou, -Jim Jewett, Martin v. L?wis, Jason Orendorff, Josh Robb, Nigel Rowe, -Bruce Sherwood, and Jeff Shute have submitted useful patches. Thanks, guys! +Jim Jewett, Martin v. L?wis, Jason Orendorff, Guilherme Polo, Josh Robb, +Nigel Rowe, Bruce Sherwood, and Jeff Shute have submitted useful patches. +Thanks, guys! For additional details refer to NEWS.txt and Changelog. Modified: python/branches/release26-maint/Lib/idlelib/EditorWindow.py ============================================================================== --- python/branches/release26-maint/Lib/idlelib/EditorWindow.py (original) +++ python/branches/release26-maint/Lib/idlelib/EditorWindow.py Sat Apr 25 19:26:39 2009 @@ -22,6 +22,16 @@ # The default tab setting for a Text widget, in average-width characters. TK_TABWIDTH_DEFAULT = 8 +def _sphinx_version(): + "Format sys.version_info to produce the Sphinx version string used to install the chm docs" + major, minor, micro, level, serial = sys.version_info + release = '%s%s' % (major, minor) + if micro: + release += '%s' % micro + if level != 'final': + release += '%s%s' % (level[0], serial) + return release + def _find_module(fullname, path=None): """Version of imp.find_module() that handles hierarchical module names""" @@ -64,15 +74,13 @@ 'Doc', 'index.html') elif sys.platform[:3] == 'win': chmfile = os.path.join(sys.prefix, 'Doc', - 'Python%d%d.chm' % sys.version_info[:2]) + 'Python%s.chm' % _sphinx_version()) if os.path.isfile(chmfile): dochome = chmfile - elif macosxSupport.runningAsOSXApp(): # documentation is stored inside the python framework dochome = os.path.join(sys.prefix, 'Resources/English.lproj/Documentation/index.html') - dochome = os.path.normpath(dochome) if os.path.isfile(dochome): EditorWindow.help_url = dochome Modified: python/branches/release26-maint/Lib/idlelib/NEWS.txt ============================================================================== --- python/branches/release26-maint/Lib/idlelib/NEWS.txt (original) +++ python/branches/release26-maint/Lib/idlelib/NEWS.txt Sat Apr 25 19:26:39 2009 @@ -1,7 +1,22 @@ -What's New in IDLE 2.6a3? -========================= +What's New in IDLE 2.6.3rc1? +============================ + +*Release date: XX-XXX-2009* + +- Windows: Version string for the .chm help file changed, file not being + accessed Patch 5783 Guilherme Polo + +What's New in IDLE 2.6.2rc1? +============================ + +*Release date: 06-Apr-2009* + +- Issue #3549: On MacOS the preferences menu was not present + +What's New in IDLE 2.6? +======================= -*Release date: XX-XXX-2008* +*Release date: 01-Oct-2008* - Issue #2665: On Windows, an IDLE installation upgraded from an old version would not start if a custom theme was defined. @@ -23,7 +38,7 @@ in the config dialog would cause non-Python files to be colored as if they were Python source; improve use of ColorDelagator. Patch 1334. Tal Einat. -- ScriptBinding event handlers weren't returning 'break'. Patch 2050, Tal Einat. +- ScriptBinding event handlers weren't returning 'break'. Patch 2050, Tal Einat - There was an error on exit if no sys.exitfunc was defined. Issue 1647. Modified: python/branches/release26-maint/Lib/idlelib/idlever.py ============================================================================== --- python/branches/release26-maint/Lib/idlelib/idlever.py (original) +++ python/branches/release26-maint/Lib/idlelib/idlever.py Sat Apr 25 19:26:39 2009 @@ -1 +1 @@ -IDLE_VERSION = "2.6.2" +IDLE_VERSION = "2.6.3rc1" From python-checkins at python.org Sat Apr 25 19:30:40 2009 From: python-checkins at python.org (kurt.kaiser) Date: Sat, 25 Apr 2009 19:30:40 +0200 (CEST) Subject: [Python-checkins] r71909 - in python/branches/release26-maint: Lib/idlelib/EditorWindow.py Message-ID: <20090425173040.DA9121E4020@bag.python.org> Author: kurt.kaiser Date: Sat Apr 25 19:30:40 2009 New Revision: 71909 Log: Merged revisions 68801 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r68801 | raymond.hettinger | 2009-01-20 05:46:23 -0500 (Tue, 20 Jan 2009) | 5 lines Use Georg's new permalinks to documentation by version number. That assures that IDLE's help always points to the correct version and the latest update with all bug fixes. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/idlelib/EditorWindow.py Modified: python/branches/release26-maint/Lib/idlelib/EditorWindow.py ============================================================================== --- python/branches/release26-maint/Lib/idlelib/EditorWindow.py (original) +++ python/branches/release26-maint/Lib/idlelib/EditorWindow.py Sat Apr 25 19:30:40 2009 @@ -88,7 +88,7 @@ # Safari requires real file:-URLs EditorWindow.help_url = 'file://' + EditorWindow.help_url else: - EditorWindow.help_url = "http://www.python.org/doc/current" + EditorWindow.help_url = "http://docs.python.org/%d.%d" % sys.version_info[:2] currentTheme=idleConf.CurrentTheme() self.flist = flist root = root or flist.root From python-checkins at python.org Sat Apr 25 19:59:04 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 19:59:04 +0200 (CEST) Subject: [Python-checkins] r71910 - in python/trunk/Doc/c-api: allocation.rst arg.rst buffer.rst dict.rst list.rst long.rst mapping.rst object.rst sequence.rst set.rst string.rst tuple.rst type.rst Message-ID: <20090425175904.35C1E1E4010@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 19:59:03 2009 New Revision: 71910 Log: Issue #4129: Belatedly document which C API functions had their argument(s) or return type changed from int or int * to Py_ssize_t or Py_ssize_t * as this might cause problems on 64-bit platforms. Modified: python/trunk/Doc/c-api/allocation.rst python/trunk/Doc/c-api/arg.rst python/trunk/Doc/c-api/buffer.rst python/trunk/Doc/c-api/dict.rst python/trunk/Doc/c-api/list.rst python/trunk/Doc/c-api/long.rst python/trunk/Doc/c-api/mapping.rst python/trunk/Doc/c-api/object.rst python/trunk/Doc/c-api/sequence.rst python/trunk/Doc/c-api/set.rst python/trunk/Doc/c-api/string.rst python/trunk/Doc/c-api/tuple.rst python/trunk/Doc/c-api/type.rst Modified: python/trunk/Doc/c-api/allocation.rst ============================================================================== --- python/trunk/Doc/c-api/allocation.rst (original) +++ python/trunk/Doc/c-api/allocation.rst Sat Apr 25 19:59:03 2009 @@ -11,6 +11,10 @@ .. cfunction:: PyVarObject* _PyObject_NewVar(PyTypeObject *type, Py_ssize_t size) + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: void _PyObject_Del(PyObject *op) Modified: python/trunk/Doc/c-api/arg.rst ============================================================================== --- python/trunk/Doc/c-api/arg.rst (original) +++ python/trunk/Doc/c-api/arg.rst Sat Apr 25 19:59:03 2009 @@ -403,6 +403,10 @@ .. versionadded:: 2.2 + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *min* and *max*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* Py_BuildValue(const char *format, ...) Modified: python/trunk/Doc/c-api/buffer.rst ============================================================================== --- python/trunk/Doc/c-api/buffer.rst (original) +++ python/trunk/Doc/c-api/buffer.rst Sat Apr 25 19:59:03 2009 @@ -376,6 +376,11 @@ then the new buffer's contents extend to the length of the *base* object's exported buffer data. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *offset* and *size*. This + might require changes in your code for properly supporting 64-bit + systems. + .. cfunction:: PyObject* PyBuffer_FromReadWriteObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size) @@ -383,6 +388,11 @@ those for :cfunc:`PyBuffer_FromObject`. If the *base* object does not export the writeable buffer protocol, then :exc:`TypeError` is raised. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *offset* and *size*. This + might require changes in your code for properly supporting 64-bit + systems. + .. cfunction:: PyObject* PyBuffer_FromMemory(void *ptr, Py_ssize_t size) @@ -393,11 +403,19 @@ :const:`Py_END_OF_BUFFER` may *not* be passed for the *size* parameter; :exc:`ValueError` will be raised in that case. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size) Similar to :cfunc:`PyBuffer_FromMemory`, but the returned buffer is writable. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyBuffer_New(Py_ssize_t size) @@ -405,3 +423,7 @@ *size* bytes. :exc:`ValueError` is returned if *size* is not zero or positive. Note that the memory buffer (as returned by :cfunc:`PyObject_AsWriteBuffer`) is not specifically aligned. + + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. Modified: python/trunk/Doc/c-api/dict.rst ============================================================================== --- python/trunk/Doc/c-api/dict.rst (original) +++ python/trunk/Doc/c-api/dict.rst Sat Apr 25 19:59:03 2009 @@ -143,6 +143,10 @@ Return the number of items in the dictionary. This is equivalent to ``len(p)`` on a dictionary. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) @@ -187,6 +191,10 @@ Py_DECREF(o); } + .. versionchanged:: 2.5 + This function used an :ctype:`int *` type for *ppos*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyDict_Merge(PyObject *a, PyObject *b, int override) Modified: python/trunk/Doc/c-api/list.rst ============================================================================== --- python/trunk/Doc/c-api/list.rst (original) +++ python/trunk/Doc/c-api/list.rst Sat Apr 25 19:59:03 2009 @@ -49,6 +49,10 @@ :cfunc:`PySequence_SetItem` or expose the object to Python code before setting all items to a real object with :cfunc:`PyList_SetItem`. + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PyList_Size(PyObject *list) @@ -57,6 +61,10 @@ Return the length of the list object in *list*; this is equivalent to ``len(list)`` on a list object. + .. versionchanged:: 2.5 + This function returned an :ctype:`int`. This might require changes in + your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PyList_GET_SIZE(PyObject *list) @@ -69,6 +77,10 @@ must be positive, indexing from the end of the list is not supported. If *pos* is out of bounds, return *NULL* and set an :exc:`IndexError` exception. + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *index*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyList_GET_ITEM(PyObject *list, Py_ssize_t i) @@ -85,6 +97,10 @@ This function "steals" a reference to *item* and discards a reference to an item already in the list at the affected position. + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *index*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: void PyList_SET_ITEM(PyObject *list, Py_ssize_t i, PyObject *o) @@ -104,6 +120,10 @@ if successful; return ``-1`` and set an exception if unsuccessful. Analogous to ``list.insert(index, item)``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *index*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyList_Append(PyObject *list, PyObject *item) @@ -118,6 +138,10 @@ and *high*. Return *NULL* and set an exception if unsuccessful. Analogous to ``list[low:high]``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *low* and *high*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyList_SetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high, PyObject *itemlist) @@ -126,6 +150,10 @@ indicating the assignment of an empty list (slice deletion). Return ``0`` on success, ``-1`` on failure. + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *low* and *high*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyList_Sort(PyObject *list) Modified: python/trunk/Doc/c-api/long.rst ============================================================================== --- python/trunk/Doc/c-api/long.rst (original) +++ python/trunk/Doc/c-api/long.rst Sat Apr 25 19:59:03 2009 @@ -106,6 +106,10 @@ .. versionadded:: 1.6 + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *length*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyLong_FromVoidPtr(void *p) Modified: python/trunk/Doc/c-api/mapping.rst ============================================================================== --- python/trunk/Doc/c-api/mapping.rst (original) +++ python/trunk/Doc/c-api/mapping.rst Sat Apr 25 19:59:03 2009 @@ -12,7 +12,8 @@ function always succeeds. -.. cfunction:: Py_ssize_t PyMapping_Length(PyObject *o) +.. cfunction:: Py_ssize_t PyMapping_Size(PyObject *o) + Py_ssize_t PyMapping_Length(PyObject *o) .. index:: builtin: len @@ -20,6 +21,10 @@ objects that do not provide mapping protocol, this is equivalent to the Python expression ``len(o)``. + .. versionchanged:: 2.5 + These functions returned an :ctype:`int` type. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyMapping_DelItemString(PyObject *o, char *key) Modified: python/trunk/Doc/c-api/object.rst ============================================================================== --- python/trunk/Doc/c-api/object.rst (original) +++ python/trunk/Doc/c-api/object.rst Sat Apr 25 19:59:03 2009 @@ -351,6 +351,10 @@ and mapping protocols, the sequence length is returned. On error, ``-1`` is returned. This is the equivalent to the Python expression ``len(o)``. + .. versionchanged:: 2.5 + These functions returned an :ctype:`int` type. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyObject_GetItem(PyObject *o, PyObject *key) Modified: python/trunk/Doc/c-api/sequence.rst ============================================================================== --- python/trunk/Doc/c-api/sequence.rst (original) +++ python/trunk/Doc/c-api/sequence.rst Sat Apr 25 19:59:03 2009 @@ -13,6 +13,7 @@ .. cfunction:: Py_ssize_t PySequence_Size(PyObject *o) + Py_ssize_t PySequence_Length(PyObject *o) .. index:: builtin: len @@ -20,10 +21,9 @@ For objects that do not provide sequence protocol, this is equivalent to the Python expression ``len(o)``. - -.. cfunction:: Py_ssize_t PySequence_Length(PyObject *o) - - Alternate name for :cfunc:`PySequence_Size`. + .. versionchanged:: 2.5 + These functions returned an :ctype:`int` type. This might require + changes in your code for properly supporting 64-bit systems. .. cfunction:: PyObject* PySequence_Concat(PyObject *o1, PyObject *o2) @@ -37,6 +37,10 @@ Return the result of repeating sequence object *o* *count* times, or *NULL* on failure. This is the equivalent of the Python expression ``o * count``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *count*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PySequence_InPlaceConcat(PyObject *o1, PyObject *o2) @@ -51,18 +55,30 @@ failure. The operation is done *in-place* when *o* supports it. This is the equivalent of the Python expression ``o *= count``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *count*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PySequence_GetItem(PyObject *o, Py_ssize_t i) Return the *i*th element of *o*, or *NULL* on failure. This is the equivalent of the Python expression ``o[i]``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PySequence_GetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2) Return the slice of sequence object *o* between *i1* and *i2*, or *NULL* on failure. This is the equivalent of the Python expression ``o[i1:i2]``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i1* and *i2*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v) @@ -70,24 +86,40 @@ is the equivalent of the Python statement ``o[i] = v``. This function *does not* steal a reference to *v*. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PySequence_DelItem(PyObject *o, Py_ssize_t i) Delete the *i*th element of object *o*. Returns ``-1`` on failure. This is the equivalent of the Python statement ``del o[i]``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PySequence_SetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2, PyObject *v) Assign the sequence object *v* to the slice in sequence object *o* from *i1* to *i2*. This is the equivalent of the Python statement ``o[i1:i2] = v``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i1* and *i2*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PySequence_DelSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2) Delete the slice in sequence object *o* from *i1* to *i2*. Returns ``-1`` on failure. This is the equivalent of the Python statement ``del o[i1:i2]``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i1* and *i2*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PySequence_Count(PyObject *o, PyObject *value) @@ -95,6 +127,10 @@ of keys for which ``o[key] == value``. On failure, return ``-1``. This is equivalent to the Python expression ``o.count(value)``. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: int PySequence_Contains(PyObject *o, PyObject *value) @@ -108,6 +144,10 @@ Return the first index *i* for which ``o[i] == value``. On error, return ``-1``. This is equivalent to the Python expression ``o.index(value)``. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PySequence_List(PyObject *o) Modified: python/trunk/Doc/c-api/set.rst ============================================================================== --- python/trunk/Doc/c-api/set.rst (original) +++ python/trunk/Doc/c-api/set.rst Sat Apr 25 19:59:03 2009 @@ -116,6 +116,10 @@ ``len(anyset)``. Raises a :exc:`PyExc_SystemError` if *anyset* is not a :class:`set`, :class:`frozenset`, or an instance of a subtype. + .. versionchanged:: 2.5 + This function returned an :ctype:`int`. This might require changes in + your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PySet_GET_SIZE(PyObject *anyset) Modified: python/trunk/Doc/c-api/string.rst ============================================================================== --- python/trunk/Doc/c-api/string.rst (original) +++ python/trunk/Doc/c-api/string.rst Sat Apr 25 19:59:03 2009 @@ -60,6 +60,10 @@ *len* on success, and *NULL* on failure. If *v* is *NULL*, the contents of the string are uninitialized. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *len*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyString_FromFormat(const char *format, ...) @@ -134,6 +138,10 @@ Return the length of the string in string object *string*. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PyString_GET_SIZE(PyObject *string) @@ -202,6 +210,9 @@ fails, the original string object at *\*string* is deallocated, *\*string* is set to *NULL*, a memory exception is set, and ``-1`` is returned. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *newsize*. This might + require changes in your code for properly supporting 64-bit systems. .. cfunction:: PyObject* PyString_Format(PyObject *format, PyObject *args) Modified: python/trunk/Doc/c-api/tuple.rst ============================================================================== --- python/trunk/Doc/c-api/tuple.rst (original) +++ python/trunk/Doc/c-api/tuple.rst Sat Apr 25 19:59:03 2009 @@ -42,6 +42,10 @@ Return a new tuple object of size *len*, or *NULL* on failure. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *len*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyTuple_Pack(Py_ssize_t n, ...) @@ -51,11 +55,19 @@ .. versionadded:: 2.4 + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *n*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PyTuple_Size(PyObject *p) Take a pointer to a tuple object, and return the size of that tuple. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PyTuple_GET_SIZE(PyObject *p) @@ -68,6 +80,10 @@ Return the object at position *pos* in the tuple pointed to by *p*. If *pos* is out of bounds, return *NULL* and sets an :exc:`IndexError` exception. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *pos*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyTuple_GET_ITEM(PyObject *p, Py_ssize_t pos) @@ -79,6 +95,10 @@ Take a slice of the tuple pointed to by *p* from *low* to *high* and return it as a new tuple. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *low* and *high*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o) @@ -89,6 +109,10 @@ This function "steals" a reference to *o*. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *pos*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: void PyTuple_SET_ITEM(PyObject *p, Py_ssize_t pos, PyObject *o) @@ -116,6 +140,10 @@ .. versionchanged:: 2.2 Removed unused third parameter, *last_is_sticky*. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *newsize*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyTuple_ClearFreeList(void) Modified: python/trunk/Doc/c-api/type.rst ============================================================================== --- python/trunk/Doc/c-api/type.rst (original) +++ python/trunk/Doc/c-api/type.rst Sat Apr 25 19:59:03 2009 @@ -76,6 +76,10 @@ .. versionadded:: 2.2 + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *nitems*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds) From python-checkins at python.org Sat Apr 25 20:18:54 2009 From: python-checkins at python.org (kurt.kaiser) Date: Sat, 25 Apr 2009 20:18:54 +0200 (CEST) Subject: [Python-checkins] r71911 - in python/branches/release26-maint: Lib/idlelib/EditorWindow.py Lib/idlelib/NEWS.txt Message-ID: <20090425181854.6803F1E4010@bag.python.org> Author: kurt.kaiser Date: Sat Apr 25 20:18:54 2009 New Revision: 71911 Log: Merged revisions 70723 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70723 | kurt.kaiser | 2009-03-30 12:22:00 -0400 (Mon, 30 Mar 2009) | 1 line Tk 8.5 Text widget requires 'wordprocessor' tabstyle attr to handle mixed space/tab properly. Issue 5120, patch by Guilherme Polo. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/idlelib/EditorWindow.py python/branches/release26-maint/Lib/idlelib/NEWS.txt Modified: python/branches/release26-maint/Lib/idlelib/EditorWindow.py ============================================================================== --- python/branches/release26-maint/Lib/idlelib/EditorWindow.py (original) +++ python/branches/release26-maint/Lib/idlelib/EditorWindow.py Sat Apr 25 20:18:54 2009 @@ -113,10 +113,18 @@ self.text_frame = text_frame = Frame(top) self.vbar = vbar = Scrollbar(text_frame, name='vbar') self.width = idleConf.GetOption('main','EditorWindow','width') - self.text = text = MultiCallCreator(Text)( - text_frame, name='text', padx=5, wrap='none', - width=self.width, - height=idleConf.GetOption('main','EditorWindow','height') ) + text_options = { + 'name': 'text', + 'padx': 5, + 'wrap': 'none', + 'width': self.width, + 'height': idleConf.GetOption('main', 'EditorWindow', 'height')} + if TkVersion >= 8.5: + # Starting with tk 8.5 we have to set the new tabstyle option + # to 'wordprocessor' to achieve the same display of tabs as in + # older tk versions. + text_options['tabstyle'] = 'wordprocessor' + self.text = text = MultiCallCreator(Text)(text_frame, **text_options) self.top.focused_widget = self.text self.createmenubar() Modified: python/branches/release26-maint/Lib/idlelib/NEWS.txt ============================================================================== --- python/branches/release26-maint/Lib/idlelib/NEWS.txt (original) +++ python/branches/release26-maint/Lib/idlelib/NEWS.txt Sat Apr 25 20:18:54 2009 @@ -6,6 +6,9 @@ - Windows: Version string for the .chm help file changed, file not being accessed Patch 5783 Guilherme Polo +- Tk 8.5 Text widget requires 'wordprocessor' tabstyle attr to handle + mixed space/tab properly. Issue 5129, patch by Guilherme Polo. + What's New in IDLE 2.6.2rc1? ============================ From python-checkins at python.org Sat Apr 25 20:22:27 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 25 Apr 2009 20:22:27 +0200 (CEST) Subject: [Python-checkins] r71912 - python/branches/py3k/Include/pymacconfig.h Message-ID: <20090425182227.965781E4010@bag.python.org> Author: mark.dickinson Date: Sat Apr 25 20:22:27 2009 New Revision: 71912 Log: Don't try to use x87 assembly on OS X universal builds. Modified: python/branches/py3k/Include/pymacconfig.h Modified: python/branches/py3k/Include/pymacconfig.h ============================================================================== --- python/branches/py3k/Include/pymacconfig.h (original) +++ python/branches/py3k/Include/pymacconfig.h Sat Apr 25 20:22:27 2009 @@ -20,6 +20,9 @@ # undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 # undef DOUBLE_IS_BIG_ENDIAN_IEEE754 # undef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 +/* we don't ever need to play with the x87 control word on OS X/Intel, so just + pretend that we can't, to avoid problems on Intel+PPC builds */ +# undef HAVE_GCC_ASM_FOR_X87 # undef VA_LIST_IS_ARRAY # if defined(__LP64__) && defined(__x86_64__) From python-checkins at python.org Sat Apr 25 20:23:15 2009 From: python-checkins at python.org (mark.dickinson) Date: Sat, 25 Apr 2009 20:23:15 +0200 (CEST) Subject: [Python-checkins] r71913 - python/branches/release30-maint Message-ID: <20090425182315.78A741E4010@bag.python.org> Author: mark.dickinson Date: Sat Apr 25 20:23:15 2009 New Revision: 71913 Log: Blocked revisions 71912 via svnmerge ........ r71912 | mark.dickinson | 2009-04-25 19:22:27 +0100 (Sat, 25 Apr 2009) | 2 lines Don't try to use x87 assembly on OS X universal builds. ........ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sat Apr 25 20:31:20 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 20:31:20 +0200 (CEST) Subject: [Python-checkins] r71914 - python/trunk/Doc/c-api/slice.rst Message-ID: <20090425183120.87C3F1E4010@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 20:31:20 2009 New Revision: 71914 Log: Reformat prior to editing. Modified: python/trunk/Doc/c-api/slice.rst Modified: python/trunk/Doc/c-api/slice.rst ============================================================================== --- python/trunk/Doc/c-api/slice.rst (original) +++ python/trunk/Doc/c-api/slice.rst Sat Apr 25 20:31:20 2009 @@ -22,34 +22,35 @@ .. cfunction:: PyObject* PySlice_New(PyObject *start, PyObject *stop, PyObject *step) Return a new slice object with the given values. The *start*, *stop*, and - *step* parameters are used as the values of the slice object attributes of the - same names. Any of the values may be *NULL*, in which case the ``None`` will be - used for the corresponding attribute. Return *NULL* if the new object could not - be allocated. + *step* parameters are used as the values of the slice object attributes of + the same names. Any of the values may be *NULL*, in which case the + ``None`` will be used for the corresponding attribute. Return *NULL* if + the new object could not be allocated. .. cfunction:: int PySlice_GetIndices(PySliceObject *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 *length* as - errors. + assuming a sequence of length *length*. Treats indices greater than + *length* as errors. - Returns 0 on success and -1 on error with no exception set (unless one of the - indices was not :const:`None` and failed to be converted to an integer, in which - case -1 is returned with an exception set). - - You probably do not want to use this function. If you want to use slice objects - in versions of Python prior to 2.3, you would probably do well to incorporate - the source of :cfunc:`PySlice_GetIndicesEx`, suitably renamed, in the source of - your extension. + Returns 0 on success and -1 on error with no exception set (unless one of + the indices was not :const:`None` and failed to be converted to an integer, + in which case -1 is returned with an exception set). + + You probably do not want to use this function. If you want to use slice + objects in versions of Python prior to 2.3, you would probably do well to + incorporate the source of :cfunc:`PySlice_GetIndicesEx`, suitably renamed, + in the source of your extension. .. cfunction:: 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) - Usable replacement for :cfunc:`PySlice_GetIndices`. Retrieve the start, stop, - and step indices from the slice object *slice* assuming a sequence of length - *length*, and store the length of the slice in *slicelength*. Out of bounds - indices are clipped in a manner consistent with the handling of normal slices. + Usable replacement for :cfunc:`PySlice_GetIndices`. Retrieve the start, + stop, and step indices from the slice object *slice* assuming a sequence of + length *length*, and store the length of the slice in *slicelength*. Out + of bounds indices are clipped in a manner consistent with the handling of + normal slices. Returns 0 on success and -1 on error with exception set. From python-checkins at python.org Sat Apr 25 20:46:03 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 20:46:03 +0200 (CEST) Subject: [Python-checkins] r71915 - python/trunk/Doc/c-api/slice.rst Message-ID: <20090425184603.CB4261E4010@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 20:46:03 2009 New Revision: 71915 Log: Issue #4129: Document more int -> Py_ssize_t changes. Modified: python/trunk/Doc/c-api/slice.rst Modified: python/trunk/Doc/c-api/slice.rst ============================================================================== --- python/trunk/Doc/c-api/slice.rst (original) +++ python/trunk/Doc/c-api/slice.rst Sat Apr 25 20:46:03 2009 @@ -43,6 +43,11 @@ incorporate the source of :cfunc:`PySlice_GetIndicesEx`, suitably renamed, in the source of your extension. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *length* and an + :ctype:`int *` type for *start*, *stop*, and *step*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: 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) @@ -55,3 +60,9 @@ Returns 0 on success and -1 on error with exception set. .. versionadded:: 2.3 + + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *length* and an + :ctype:`int *` type for *start*, *stop*, *step*, and *slicelength*. This + might require changes in your code for properly supporting 64-bit + systems. From buildbot at python.org Sat Apr 25 20:50:39 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 18:50:39 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 3.x Message-ID: <20090425185039.A7D811E4010@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%203.x/builds/804 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_os test_time make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sat Apr 25 20:52:14 2009 From: python-checkins at python.org (thomas.heller) Date: Sat, 25 Apr 2009 20:52:14 +0200 (CEST) Subject: [Python-checkins] r71907 - svn:log Message-ID: <20090425185214.5A2AC1E4010@bag.python.org> Author: thomas.heller Revision: 71907 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -4,5 +4,5 @@ ........ r71906 | thomas.heller | 2009-04-25 18:37:18 +0200 (Sa, 25 Apr 2009) | 1 line - Issue #5087: Avoid redundant call to FormatError() + Issue #5078: Avoid redundant call to FormatError() ........ From python-checkins at python.org Sat Apr 25 20:52:38 2009 From: python-checkins at python.org (thomas.heller) Date: Sat, 25 Apr 2009 20:52:38 +0200 (CEST) Subject: [Python-checkins] r71906 - svn:log Message-ID: <20090425185238.320D21E4010@bag.python.org> Author: thomas.heller Revision: 71906 Property Name: svn:log Action: modified Property diff: --- old property value +++ new property value @@ -1 +1 @@ -Issue #5087: Avoid redundant call to FormatError() \ No newline at end of file +Issue #5078: Avoid redundant call to FormatError() \ No newline at end of file From python-checkins at python.org Sat Apr 25 20:53:48 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 20:53:48 +0200 (CEST) Subject: [Python-checkins] r71916 - python/trunk/Doc/c-api/allocation.rst Message-ID: <20090425185348.674F71E4010@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 20:53:48 2009 New Revision: 71916 Log: Reformat prior to editing. Modified: python/trunk/Doc/c-api/allocation.rst Modified: python/trunk/Doc/c-api/allocation.rst ============================================================================== --- python/trunk/Doc/c-api/allocation.rst (original) +++ python/trunk/Doc/c-api/allocation.rst Sat Apr 25 20:53:48 2009 @@ -21,10 +21,11 @@ .. cfunction:: PyObject* PyObject_Init(PyObject *op, PyTypeObject *type) - Initialize a newly-allocated object *op* with its type and initial reference. - Returns the initialized object. If *type* indicates that the object - participates in the cyclic garbage detector, it is added to the detector's set - of observed objects. Other fields of the object are not affected. + Initialize a newly-allocated object *op* with its type and initial + reference. Returns the initialized object. If *type* indicates that the + object participates in the cyclic garbage detector, it is added to the + detector's set of observed objects. Other fields of the object are not + affected. .. cfunction:: PyVarObject* PyObject_InitVar(PyVarObject *op, PyTypeObject *type, Py_ssize_t size) @@ -35,74 +36,79 @@ .. cfunction:: TYPE* PyObject_New(TYPE, PyTypeObject *type) - Allocate a new Python object using the C structure type *TYPE* and the Python - type object *type*. Fields not defined by the Python object header are not - initialized; the object's reference count will be one. The size of the memory - allocation is determined from the :attr:`tp_basicsize` field of the type object. + Allocate a new Python object using the C structure type *TYPE* and the + Python type object *type*. Fields not defined by the Python object header + are not initialized; the object's reference count will be one. The size of + the memory allocation is determined from the :attr:`tp_basicsize` field of + the type object. .. cfunction:: TYPE* PyObject_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size) - Allocate a new Python object using the C structure type *TYPE* and the Python - type object *type*. Fields not defined by the Python object header are not - initialized. The allocated memory allows for the *TYPE* structure plus *size* - fields of the size given by the :attr:`tp_itemsize` field of *type*. This is - useful for implementing objects like tuples, which are able to determine their - size at construction time. Embedding the array of fields into the same - allocation decreases the number of allocations, improving the memory management - efficiency. + Allocate a new Python object using the C structure type *TYPE* and the + Python type object *type*. Fields not defined by the Python object header + are not initialized. The allocated memory allows for the *TYPE* structure + plus *size* fields of the size given by the :attr:`tp_itemsize` field of + *type*. This is useful for implementing objects like tuples, which are + able to determine their size at construction time. Embedding the array of + fields into the same allocation decreases the number of allocations, + improving the memory management efficiency. .. cfunction:: void PyObject_Del(PyObject *op) Releases memory allocated to an object using :cfunc:`PyObject_New` or - :cfunc:`PyObject_NewVar`. This is normally called from the :attr:`tp_dealloc` - handler specified in the object's type. The fields of the object should not be - accessed after this call as the memory is no longer a valid Python object. + :cfunc:`PyObject_NewVar`. This is normally called from the + :attr:`tp_dealloc` handler specified in the object's type. The fields of + the object should not be accessed after this call as the memory is no + longer a valid Python object. .. cfunction:: PyObject* Py_InitModule(char *name, PyMethodDef *methods) - Create a new module object based on a name and table of functions, returning the - new module object. + Create a new module object based on a name and table of functions, + returning the new module object. .. versionchanged:: 2.3 - Older versions of Python did not support *NULL* as the value for the *methods* - argument. + Older versions of Python did not support *NULL* as the value for the + *methods* argument. .. cfunction:: PyObject* Py_InitModule3(char *name, PyMethodDef *methods, char *doc) - Create a new module object based on a name and table of functions, returning the - new module object. If *doc* is non-*NULL*, it will be used to define the - docstring for the module. + Create a new module object based on a name and table of functions, + returning the new module object. If *doc* is non-*NULL*, it will be used + to define the docstring for the module. .. versionchanged:: 2.3 - Older versions of Python did not support *NULL* as the value for the *methods* - argument. + Older versions of Python did not support *NULL* as the value for the + *methods* argument. .. cfunction:: PyObject* Py_InitModule4(char *name, PyMethodDef *methods, char *doc, PyObject *self, int apiver) - Create a new module object based on a name and table of functions, returning the - new module object. If *doc* is non-*NULL*, it will be used to define the - docstring for the module. If *self* is non-*NULL*, it will passed to the - functions of the module as their (otherwise *NULL*) first parameter. (This was - added as an experimental feature, and there are no known uses in the current - version of Python.) For *apiver*, the only value which should be passed is - defined by the constant :const:`PYTHON_API_VERSION`. + Create a new module object based on a name and table of functions, + returning the new module object. If *doc* is non-*NULL*, it will be used + to define the docstring for the module. If *self* is non-*NULL*, it will + passed to the functions of the module as their (otherwise *NULL*) first + parameter. (This was added as an experimental feature, and there are no + known uses in the current version of Python.) For *apiver*, the only value + which should be passed is defined by the constant + :const:`PYTHON_API_VERSION`. .. note:: - Most uses of this function should probably be using the :cfunc:`Py_InitModule3` - instead; only use this if you are sure you need it. + Most uses of this function should probably be using the + :cfunc:`Py_InitModule3` instead; only use this if you are sure you need + it. .. versionchanged:: 2.3 - Older versions of Python did not support *NULL* as the value for the *methods* - argument. + Older versions of Python did not support *NULL* as the value for the + *methods* argument. .. cvar:: PyObject _Py_NoneStruct - Object which is visible in Python as ``None``. This should only be accessed - using the ``Py_None`` macro, which evaluates to a pointer to this object. + Object which is visible in Python as ``None``. This should only be + accessed using the ``Py_None`` macro, which evaluates to a pointer to this + object. From python-checkins at python.org Sat Apr 25 20:57:32 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 20:57:32 +0200 (CEST) Subject: [Python-checkins] r71917 - python/trunk/Doc/c-api/arg.rst Message-ID: <20090425185732.9EE941E4010@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 20:57:32 2009 New Revision: 71917 Log: Reference to an int type, whereas it's a Py_ssize_t as the synopsis states. Modified: python/trunk/Doc/c-api/arg.rst Modified: python/trunk/Doc/c-api/arg.rst ============================================================================== --- python/trunk/Doc/c-api/arg.rst (original) +++ python/trunk/Doc/c-api/arg.rst Sat Apr 25 20:57:32 2009 @@ -262,9 +262,9 @@ ``w#`` (read-write character buffer) [char \*, Py_ssize_t] Like ``s#``, but accepts any object which implements the read-write buffer interface. The :ctype:`char \*` variable is set to point to the first byte - of the buffer, and the :ctype:`int` is set to the length of the buffer. - Only single-segment buffer objects are accepted; :exc:`TypeError` is raised - for all others. + of the buffer, and the :ctype:`Py_ssize_t` is set to the length of the + buffer. Only single-segment buffer objects are accepted; :exc:`TypeError` + is raised for all others. ``w*`` (read-write byte-oriented buffer) [Py_buffer \*] This is to ``w`` what ``s*`` is to ``s``. From python-checkins at python.org Sat Apr 25 21:04:16 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 21:04:16 +0200 (CEST) Subject: [Python-checkins] r71918 - python/trunk/Doc/c-api/buffer.rst Message-ID: <20090425190416.6C9431E4010@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 21:04:15 2009 New Revision: 71918 Log: Since I edited this file, reformat for future edits. Modified: python/trunk/Doc/c-api/buffer.rst Modified: python/trunk/Doc/c-api/buffer.rst ============================================================================== --- python/trunk/Doc/c-api/buffer.rst (original) +++ python/trunk/Doc/c-api/buffer.rst Sat Apr 25 21:04:15 2009 @@ -14,9 +14,10 @@ single: buffer interface Python objects implemented in C can export a group of functions called the -"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. +"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. Two examples of objects that support the buffer interface are strings and arrays. The string object exposes the character contents in the buffer @@ -30,10 +31,10 @@ returning data from the target object. Starting from version 1.6, Python has been providing Python-level buffer -objects and a C-level buffer API so that any builtin or used-defined type -can expose its characteristics. Both, however, have been deprecated because -of various shortcomings, and have been officially removed in Python 3.0 in -favour of a new C-level buffer API and a new Python-level object named +objects and a C-level buffer API so that any builtin or used-defined type can +expose its characteristics. Both, however, have been deprecated because of +various shortcomings, and have been officially removed in Python 3.0 in favour +of a new C-level buffer API and a new Python-level object named :class:`memoryview`. The new buffer API has been backported to Python 2.6, and the @@ -64,9 +65,9 @@ .. cmember:: const char *format :noindex: - A *NULL* terminated string in :mod:`struct` module style syntax giving the - contents of the elements available through the buffer. If this is *NULL*, - ``"B"`` (unsigned bytes) is assumed. + A *NULL* terminated string in :mod:`struct` module style syntax giving + the contents of the elements available through the buffer. If this is + *NULL*, ``"B"`` (unsigned bytes) is assumed. .. cmember:: int ndim @@ -116,11 +117,11 @@ .. cmember:: Py_ssize_t itemsize This is a storage for the itemsize (in bytes) of each element of the - shared memory. It is technically un-necessary as it can be obtained using - :cfunc:`PyBuffer_SizeFromFormat`, however an exporter may know this - information without parsing the format string and it is necessary to know - the itemsize for proper interpretation of striding. Therefore, storing it - is more convenient and faster. + shared memory. It is technically un-necessary as it can be obtained + using :cfunc:`PyBuffer_SizeFromFormat`, however an exporter may know + this information without parsing the format string and it is necessary + to know the itemsize for proper interpretation of striding. Therefore, + storing it is more convenient and faster. .. cmember:: void *internal @@ -143,20 +144,20 @@ .. cfunction:: int PyObject_GetBuffer(PyObject *obj, PyObject *view, int flags) Export *obj* into a :ctype:`Py_buffer`, *view*. These arguments must - never be *NULL*. The *flags* argument is a bit field indicating what kind - of buffer the caller is prepared to deal with and therefore what kind of - buffer the exporter is allowed to return. The buffer interface allows for - complicated memory sharing possibilities, but some caller may not be able - to handle all the complexibity but may want to see if the exporter will - let them take a simpler view to its memory. + never be *NULL*. The *flags* argument is a bit field indicating what + kind of buffer the caller is prepared to deal with and therefore what + kind of buffer the exporter is allowed to return. The buffer interface + allows for complicated memory sharing possibilities, but some caller may + not be able to handle all the complexibity but may want to see if the + exporter will let them take a simpler view to its memory. Some exporters may not be able to share memory in every possible way and may need to raise errors to signal to some consumers that something is just not possible. These errors should be a :exc:`BufferError` unless - there is another error that is actually causing the problem. The exporter - can use flags information to simplify how much of the :cdata:`Py_buffer` - structure is filled in with non-default values and/or raise an error if - the object can't support a simpler view of its memory. + there is another error that is actually causing the problem. The + exporter can use flags information to simplify how much of the + :cdata:`Py_buffer` structure is filled in with non-default values and/or + raise an error if the object can't support a simpler view of its memory. 0 is returned on success and -1 on error. @@ -267,16 +268,16 @@ .. cfunction:: int PyObject_CopyToObject(PyObject *obj, void *buf, Py_ssize_t len, char fortran) - Copy *len* bytes of data pointed to by the contiguous chunk of memory pointed - to by *buf* into the buffer exported by obj. The buffer must of course be - writable. Return 0 on success and return -1 and raise an error on failure. - If the object does not have a writable buffer, then an error is raised. If - *fortran* is ``'F'``, then if the object is multi-dimensional, then the data - will be copied into the array in Fortran-style (first dimension varies the - fastest). If *fortran* is ``'C'``, then the data will be copied into the - array in C-style (last dimension varies the fastest). If *fortran* is - ``'A'``, then it does not matter and the copy will be made in whatever way is - more efficient. + Copy *len* bytes of data pointed to by the contiguous chunk of memory + pointed to by *buf* into the buffer exported by obj. The buffer must of + course be writable. Return 0 on success and return -1 and raise an error + on failure. If the object does not have a writable buffer, then an error + is raised. If *fortran* is ``'F'``, then if the object is + multi-dimensional, then the data will be copied into the array in + Fortran-style (first dimension varies the fastest). If *fortran* is + ``'C'``, then the data will be copied into the array in C-style (last + dimension varies the fastest). If *fortran* is ``'A'``, then it does not + matter and the copy will be made in whatever way is more efficient. .. cfunction:: int PyBuffer_IsContiguous(Py_buffer *view, char fortran) @@ -324,17 +325,18 @@ A "buffer object" is defined in the :file:`bufferobject.h` header (included by :file:`Python.h`). These objects look very similar to string objects at the Python programming level: they support slicing, indexing, concatenation, and -some other standard string operations. However, their data can come from one of -two sources: from a block of memory, or from another object which exports the -buffer interface. +some other standard string operations. However, their data can come from one +of two sources: from a block of memory, or from another object which exports +the buffer interface. Buffer objects are useful as a way to expose the data from another object's -buffer interface to the Python programmer. They can also be used as a zero-copy -slicing mechanism. Using their ability to reference a block of memory, it is -possible to expose any data to the Python programmer quite easily. The memory -could be a large, constant array in a C extension, it could be a raw block of -memory for manipulation before passing to an operating system library, or it -could be used to pass around structured data in its native, in-memory format. +buffer interface to the Python programmer. They can also be used as a +zero-copy slicing mechanism. Using their ability to reference a block of +memory, it is possible to expose any data to the Python programmer quite +easily. The memory could be a large, constant array in a C extension, it could +be a raw block of memory for manipulation before passing to an operating +system library, or it could be used to pass around structured data in its +native, in-memory format. .. ctype:: PyBufferObject @@ -355,9 +357,10 @@ This constant may be passed as the *size* parameter to :cfunc:`PyBuffer_FromObject` or :cfunc:`PyBuffer_FromReadWriteObject`. It - indicates that the new :ctype:`PyBufferObject` should refer to *base* object - from the specified *offset* to the end of its exported buffer. Using this - enables the caller to avoid querying the *base* object for its length. + indicates that the new :ctype:`PyBufferObject` should refer to *base* + object from the specified *offset* to the end of its exported buffer. + Using this enables the caller to avoid querying the *base* object for its + length. .. cfunction:: int PyBuffer_Check(PyObject *p) @@ -367,14 +370,14 @@ .. cfunction:: PyObject* PyBuffer_FromObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size) - Return a new read-only buffer object. This raises :exc:`TypeError` if *base* - doesn't support the read-only buffer protocol or doesn't provide exactly one - buffer segment, or it raises :exc:`ValueError` if *offset* is less than zero. - The buffer will hold a reference to the *base* object, and the buffer's contents - will refer to the *base* object's buffer interface, starting as position - *offset* and extending for *size* bytes. If *size* is :const:`Py_END_OF_BUFFER`, - then the new buffer's contents extend to the length of the *base* object's - exported buffer data. + Return a new read-only buffer object. This raises :exc:`TypeError` if + *base* doesn't support the read-only buffer protocol or doesn't provide + exactly one buffer segment, or it raises :exc:`ValueError` if *offset* is + less than zero. The buffer will hold a reference to the *base* object, and + the buffer's contents will refer to the *base* object's buffer interface, + starting as position *offset* and extending for *size* bytes. If *size* is + :const:`Py_END_OF_BUFFER`, then the new buffer's contents extend to the + length of the *base* object's exported buffer data. .. versionchanged:: 2.5 This function used an :ctype:`int` type for *offset* and *size*. This @@ -384,9 +387,9 @@ .. cfunction:: PyObject* PyBuffer_FromReadWriteObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size) - Return a new writable buffer object. Parameters and exceptions are similar to - those for :cfunc:`PyBuffer_FromObject`. If the *base* object does not export - the writeable buffer protocol, then :exc:`TypeError` is raised. + Return a new writable buffer object. Parameters and exceptions are similar + to those for :cfunc:`PyBuffer_FromObject`. If the *base* object does not + export the writeable buffer protocol, then :exc:`TypeError` is raised. .. versionchanged:: 2.5 This function used an :ctype:`int` type for *offset* and *size*. This @@ -396,12 +399,12 @@ .. cfunction:: PyObject* PyBuffer_FromMemory(void *ptr, Py_ssize_t size) - Return a new read-only buffer object that reads from a specified location in - memory, with a specified size. The caller is responsible for ensuring that the - memory buffer, passed in as *ptr*, is not deallocated while the returned buffer - object exists. Raises :exc:`ValueError` if *size* is less than zero. Note that - :const:`Py_END_OF_BUFFER` may *not* be passed for the *size* parameter; - :exc:`ValueError` will be raised in that case. + Return a new read-only buffer object that reads from a specified location + in memory, with a specified size. The caller is responsible for ensuring + that the memory buffer, passed in as *ptr*, is not deallocated while the + returned buffer object exists. Raises :exc:`ValueError` if *size* is less + than zero. Note that :const:`Py_END_OF_BUFFER` may *not* be passed for the + *size* parameter; :exc:`ValueError` will be raised in that case. .. versionchanged:: 2.5 This function used an :ctype:`int` type for *size*. This might require @@ -410,7 +413,8 @@ .. cfunction:: PyObject* PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size) - Similar to :cfunc:`PyBuffer_FromMemory`, but the returned buffer is writable. + Similar to :cfunc:`PyBuffer_FromMemory`, but the returned buffer is + writable. .. versionchanged:: 2.5 This function used an :ctype:`int` type for *size*. This might require @@ -420,9 +424,9 @@ .. cfunction:: PyObject* PyBuffer_New(Py_ssize_t size) Return a new writable buffer object that maintains its own memory buffer of - *size* bytes. :exc:`ValueError` is returned if *size* is not zero or positive. - Note that the memory buffer (as returned by :cfunc:`PyObject_AsWriteBuffer`) is - not specifically aligned. + *size* bytes. :exc:`ValueError` is returned if *size* is not zero or + positive. Note that the memory buffer (as returned by + :cfunc:`PyObject_AsWriteBuffer`) is not specifically aligned. .. versionchanged:: 2.5 This function used an :ctype:`int` type for *size*. This might require From python-checkins at python.org Sat Apr 25 21:10:53 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 21:10:53 +0200 (CEST) Subject: [Python-checkins] r71919 - python/trunk/Doc/c-api/gcsupport.rst Message-ID: <20090425191053.7A7FC1E4010@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 21:10:52 2009 New Revision: 71919 Log: Reformat prior to editing. Modified: python/trunk/Doc/c-api/gcsupport.rst Modified: python/trunk/Doc/c-api/gcsupport.rst ============================================================================== --- python/trunk/Doc/c-api/gcsupport.rst (original) +++ python/trunk/Doc/c-api/gcsupport.rst Sat Apr 25 21:10:52 2009 @@ -9,7 +9,8 @@ references requires support from object types which are "containers" for other objects which may also be containers. Types which do not store references to other objects, or which only store references to atomic types (such as numbers -or strings), do not need to provide any explicit support for garbage collection. +or strings), do not need to provide any explicit support for garbage +collection. .. An example showing the use of these interfaces can be found in "Supporting the .. Cycle Collector (XXX not found: ../ext/example-cycle-support.html)". @@ -23,13 +24,14 @@ .. data:: Py_TPFLAGS_HAVE_GC :noindex: - Objects with a type with this flag set must conform with the rules documented - here. For convenience these objects will be referred to as container objects. + Objects with a type with this flag set must conform with the rules + documented here. For convenience these objects will be referred to as + container objects. Constructors for container types must conform to two rules: -#. The memory for the object must be allocated using :cfunc:`PyObject_GC_New` or - :cfunc:`PyObject_GC_VarNew`. +#. The memory for the object must be allocated using :cfunc:`PyObject_GC_New` + or :cfunc:`PyObject_GC_VarNew`. #. Once all the fields which may contain references to other containers are initialized, it must call :cfunc:`PyObject_GC_Track`. @@ -49,17 +51,17 @@ .. cfunction:: PyVarObject * PyObject_GC_Resize(PyVarObject *op, Py_ssize_t) - Resize an object allocated by :cfunc:`PyObject_NewVar`. Returns the resized - object or *NULL* on failure. + Resize an object allocated by :cfunc:`PyObject_NewVar`. Returns the + resized object or *NULL* on failure. .. cfunction:: void PyObject_GC_Track(PyObject *op) - Adds the object *op* to the set of container objects tracked by the collector. - The collector can run at unexpected times so objects must be valid while being - tracked. This should be called once all the fields followed by the - :attr:`tp_traverse` handler become valid, usually near the end of the - constructor. + Adds the object *op* to the set of container objects tracked by the + collector. The collector can run at unexpected times so objects must be + valid while being tracked. This should be called once all the fields + followed by the :attr:`tp_traverse` handler become valid, usually near the + end of the constructor. .. cfunction:: void _PyObject_GC_TRACK(PyObject *op) @@ -85,10 +87,10 @@ .. cfunction:: void PyObject_GC_UnTrack(void *op) Remove the object *op* from the set of container objects tracked by the - collector. Note that :cfunc:`PyObject_GC_Track` can be called again on this - object to add it back to the set of tracked objects. The deallocator - (:attr:`tp_dealloc` handler) should call this for the object before any of the - fields used by the :attr:`tp_traverse` handler become invalid. + collector. Note that :cfunc:`PyObject_GC_Track` can be called again on + this object to add it back to the set of tracked objects. The deallocator + (:attr:`tp_dealloc` handler) should call this for the object before any of + the fields used by the :attr:`tp_traverse` handler become invalid. .. cfunction:: void _PyObject_GC_UNTRACK(PyObject *op) @@ -101,11 +103,12 @@ .. ctype:: int (*visitproc)(PyObject *object, void *arg) - Type of the visitor function passed to the :attr:`tp_traverse` handler. The - function should be called with an object to traverse as *object* and the third - parameter to the :attr:`tp_traverse` handler as *arg*. The Python core uses - several visitor functions to implement cyclic garbage detection; it's not - expected that users will need to write their own visitor functions. + Type of the visitor function passed to the :attr:`tp_traverse` handler. + The function should be called with an object to traverse as *object* and + the third parameter to the :attr:`tp_traverse` handler as *arg*. The + Python core uses several visitor functions to implement cyclic garbage + detection; it's not expected that users will need to write their own + visitor functions. The :attr:`tp_traverse` handler must have the following type: @@ -114,10 +117,10 @@ Traversal function for a container object. Implementations must call the *visit* function for each object directly contained by *self*, with the - parameters to *visit* being the contained object and the *arg* value passed to - the handler. The *visit* function must not be called with a *NULL* object - argument. If *visit* returns a non-zero value that value should be returned - immediately. + parameters to *visit* being the contained object and the *arg* value passed + to the handler. The *visit* function must not be called with a *NULL* + object argument. If *visit* returns a non-zero value that value should be + returned immediately. To simplify writing :attr:`tp_traverse` handlers, a :cfunc:`Py_VISIT` macro is provided. In order to use this macro, the :attr:`tp_traverse` implementation @@ -126,9 +129,9 @@ .. cfunction:: void Py_VISIT(PyObject *o) - Call the *visit* callback, with arguments *o* and *arg*. If *visit* returns a - non-zero value, then return it. Using this macro, :attr:`tp_traverse` handlers - look like:: + Call the *visit* callback, with arguments *o* and *arg*. If *visit* returns + a non-zero value, then return it. Using this macro, :attr:`tp_traverse` + handlers look like:: static int my_traverse(Noddy *self, visitproc visit, void *arg) @@ -140,14 +143,15 @@ .. versionadded:: 2.4 -The :attr:`tp_clear` handler must be of the :ctype:`inquiry` type, or *NULL* if -the object is immutable. +The :attr:`tp_clear` handler must be of the :ctype:`inquiry` type, or *NULL* +if the object is immutable. .. ctype:: int (*inquiry)(PyObject *self) - Drop references that may have created reference cycles. Immutable objects do - not have to define this method since they can never directly create reference - cycles. Note that the object must still be valid after calling this method - (don't just call :cfunc:`Py_DECREF` on a reference). The collector will call - this method if it detects that this object is involved in a reference cycle. + Drop references that may have created reference cycles. Immutable objects + do not have to define this method since they can never directly create + reference cycles. Note that the object must still be valid after calling + this method (don't just call :cfunc:`Py_DECREF` on a reference). The + collector will call this method if it detects that this object is involved + in a reference cycle. From buildbot at python.org Sat Apr 25 21:19:02 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 19:19:02 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090425191902.BFFB01E4010@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/574 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: tarek.ziade,walter.doerwald BUILD FAILED: failed test Excerpt from the test logfile: 3 tests failed: test_os test_posix test_posixpath ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 251, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 177, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== ERROR: test_expanduser (test.test_posixpath.PosixPathTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posixpath.py", line 422, in test_expanduser orig_home = os.environ['HOME'] File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/os.py", line 391, in __getitem__ return self.data[self.keymap(key)] KeyError: 'HOME' ====================================================================== ERROR: test_realpath_basic (test.test_posixpath.PosixPathTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posixpath.py", line 504, in test_realpath_basic os.symlink(ABSTFN+"1", ABSTFN) OSError: [Errno 17] File exists sincerely, -The Buildbot From buildbot at python.org Sat Apr 25 21:36:22 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 19:36:22 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable trunk Message-ID: <20090425193622.60DCF1E4010@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%20trunk/builds/414 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: georg.brandl,jeroen.ruigrok,thomas.heller BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_os ====================================================================== FAIL: test_update2 (test.test_os.EnvironTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/test/test_os.py", line 348, in test_update2 self.assertEquals(value, "World") AssertionError: '' != 'World' make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sat Apr 25 21:44:55 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 21:44:55 +0200 (CEST) Subject: [Python-checkins] r71920 - python/trunk/Doc/c-api/gcsupport.rst Message-ID: <20090425194455.2E9741E4010@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 21:44:55 2009 New Revision: 71920 Log: Issue #4129: More documentation pointers about int -> Py_ssize_t. Also fix up the documentation for PyObject_GC_Resize(). It seems that since it first got documented, the documentation was actually for _PyObject_GC_Resize(). Modified: python/trunk/Doc/c-api/gcsupport.rst Modified: python/trunk/Doc/c-api/gcsupport.rst ============================================================================== --- python/trunk/Doc/c-api/gcsupport.rst (original) +++ python/trunk/Doc/c-api/gcsupport.rst Sat Apr 25 21:44:55 2009 @@ -48,12 +48,20 @@ Analogous to :cfunc:`PyObject_NewVar` but for container objects with the :const:`Py_TPFLAGS_HAVE_GC` flag set. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. -.. cfunction:: PyVarObject * PyObject_GC_Resize(PyVarObject *op, Py_ssize_t) + +.. cfunction:: TYPE* PyObject_GC_Resize(TYPE, PyVarObject *op, Py_ssize_t newsize) Resize an object allocated by :cfunc:`PyObject_NewVar`. Returns the resized object or *NULL* on failure. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *newsize*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: void PyObject_GC_Track(PyObject *op) From python-checkins at python.org Sat Apr 25 21:46:19 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 21:46:19 +0200 (CEST) Subject: [Python-checkins] r71921 - python/trunk/Doc/c-api/allocation.rst Message-ID: <20090425194619.B3F141E4010@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 21:46:19 2009 New Revision: 71921 Log: Issue #4129: Documentation notes for int -> Py_ssize_t changes. Modified: python/trunk/Doc/c-api/allocation.rst Modified: python/trunk/Doc/c-api/allocation.rst ============================================================================== --- python/trunk/Doc/c-api/allocation.rst (original) +++ python/trunk/Doc/c-api/allocation.rst Sat Apr 25 21:46:19 2009 @@ -33,6 +33,10 @@ This does everything :cfunc:`PyObject_Init` does, and also initializes the length information for a variable-size object. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: TYPE* PyObject_New(TYPE, PyTypeObject *type) @@ -54,6 +58,10 @@ fields into the same allocation decreases the number of allocations, improving the memory management efficiency. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: void PyObject_Del(PyObject *op) From python-checkins at python.org Sat Apr 25 21:49:05 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 21:49:05 +0200 (CEST) Subject: [Python-checkins] r71922 - python/trunk/Doc/c-api/list.rst Message-ID: <20090425194905.8245C1E4091@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 21:49:05 2009 New Revision: 71922 Log: Reformat, since I've been busy here anyway. Modified: python/trunk/Doc/c-api/list.rst Modified: python/trunk/Doc/c-api/list.rst ============================================================================== --- python/trunk/Doc/c-api/list.rst (original) +++ python/trunk/Doc/c-api/list.rst Sat Apr 25 21:49:05 2009 @@ -17,8 +17,9 @@ .. index:: single: ListType (in module types) - This instance of :ctype:`PyTypeObject` represents the Python list type. This is - the same object as ``list`` and ``types.ListType`` in the Python layer. + This instance of :ctype:`PyTypeObject` represents the Python list type. + This is the same object as ``list`` and ``types.ListType`` in the Python + layer. .. cfunction:: int PyList_Check(PyObject *p) @@ -32,8 +33,8 @@ .. cfunction:: int PyList_CheckExact(PyObject *p) - Return true if *p* is a list object, but not an instance of a subtype of the - list type. + Return true if *p* is a list object, but not an instance of a subtype of + the list type. .. versionadded:: 2.2 @@ -44,10 +45,10 @@ .. note:: - If *length* is greater than zero, the returned list object's items are set to - ``NULL``. Thus you cannot use abstract API functions such as - :cfunc:`PySequence_SetItem` or expose the object to Python code before setting - all items to a real object with :cfunc:`PyList_SetItem`. + If *length* is greater than zero, the returned list object's items are + set to ``NULL``. Thus you cannot use abstract API functions such as + :cfunc:`PySequence_SetItem` or expose the object to Python code before + setting all items to a real object with :cfunc:`PyList_SetItem`. .. versionchanged:: 2.5 This function used an :ctype:`int` for *size*. This might require @@ -73,9 +74,10 @@ .. cfunction:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index) - Return the object at position *pos* in the list pointed to by *p*. 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 :exc:`IndexError` exception. + Return the object at position *pos* in the list pointed to by *p*. 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 + :exc:`IndexError` exception. .. versionchanged:: 2.5 This function used an :ctype:`int` for *index*. This might require @@ -89,13 +91,13 @@ .. cfunction:: int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item) - Set the item at index *index* in list to *item*. Return ``0`` on success or - ``-1`` on failure. + Set the item at index *index* in list to *item*. Return ``0`` on success + or ``-1`` on failure. .. note:: - This function "steals" a reference to *item* and discards a reference to an item - already in the list at the affected position. + This function "steals" a reference to *item* and discards a reference to + an item already in the list at the affected position. .. versionchanged:: 2.5 This function used an :ctype:`int` for *index*. This might require @@ -104,21 +106,22 @@ .. cfunction:: void PyList_SET_ITEM(PyObject *list, Py_ssize_t i, PyObject *o) - Macro form of :cfunc:`PyList_SetItem` without error checking. This is normally - only used to fill in new lists where there is no previous content. + Macro form of :cfunc:`PyList_SetItem` without error checking. This is + normally only used to fill in new lists where there is no previous content. .. note:: This function "steals" a reference to *item*, and, unlike - :cfunc:`PyList_SetItem`, does *not* discard a reference to any item that it - being replaced; any reference in *list* at position *i* will be leaked. + :cfunc:`PyList_SetItem`, does *not* discard a reference to any item that + it being replaced; any reference in *list* at position *i* will be + leaked. .. cfunction:: int PyList_Insert(PyObject *list, Py_ssize_t index, PyObject *item) - Insert the item *item* into list *list* in front of index *index*. Return ``0`` - if successful; return ``-1`` and set an exception if unsuccessful. Analogous to - ``list.insert(index, item)``. + Insert the item *item* into list *list* in front of index *index*. Return + ``0`` if successful; return ``-1`` and set an exception if unsuccessful. + Analogous to ``list.insert(index, item)``. .. versionchanged:: 2.5 This function used an :ctype:`int` for *index*. This might require @@ -127,16 +130,16 @@ .. cfunction:: int PyList_Append(PyObject *list, PyObject *item) - Append the object *item* at the end of list *list*. Return ``0`` if successful; - return ``-1`` and set an exception if unsuccessful. Analogous to - ``list.append(item)``. + Append the object *item* at the end of list *list*. Return ``0`` if + successful; return ``-1`` and set an exception if unsuccessful. Analogous + to ``list.append(item)``. .. cfunction:: PyObject* PyList_GetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high) - Return a list of the objects in *list* containing the objects *between* *low* - and *high*. Return *NULL* and set an exception if unsuccessful. Analogous to - ``list[low:high]``. + Return a list of the objects in *list* containing the objects *between* + *low* and *high*. Return *NULL* and set an exception if unsuccessful. + Analogous to ``list[low:high]``. .. versionchanged:: 2.5 This function used an :ctype:`int` for *low* and *high*. This might @@ -145,10 +148,10 @@ .. cfunction:: int PyList_SetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high, PyObject *itemlist) - Set the slice of *list* between *low* and *high* to the contents of *itemlist*. - Analogous to ``list[low:high] = itemlist``. The *itemlist* may be *NULL*, - indicating the assignment of an empty list (slice deletion). Return ``0`` on - success, ``-1`` on failure. + Set the slice of *list* between *low* and *high* to the contents of + *itemlist*. Analogous to ``list[low:high] = itemlist``. The *itemlist* may + be *NULL*, indicating the assignment of an empty list (slice deletion). + Return ``0`` on success, ``-1`` on failure. .. versionchanged:: 2.5 This function used an :ctype:`int` for *low* and *high*. This might @@ -157,8 +160,8 @@ .. cfunction:: int PyList_Sort(PyObject *list) - Sort the items of *list* in place. Return ``0`` on success, ``-1`` on failure. - This is equivalent to ``list.sort()``. + Sort the items of *list* in place. Return ``0`` on success, ``-1`` on + failure. This is equivalent to ``list.sort()``. .. cfunction:: int PyList_Reverse(PyObject *list) From python-checkins at python.org Sat Apr 25 21:54:34 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 21:54:34 +0200 (CEST) Subject: [Python-checkins] r71923 - python/trunk/Doc/c-api/list.rst Message-ID: <20090425195434.DD39A1E4022@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 21:54:34 2009 New Revision: 71923 Log: Issue #4129: Add a versionchanged notice for a few forgotten entries. Modified: python/trunk/Doc/c-api/list.rst Modified: python/trunk/Doc/c-api/list.rst ============================================================================== --- python/trunk/Doc/c-api/list.rst (original) +++ python/trunk/Doc/c-api/list.rst Sat Apr 25 21:54:34 2009 @@ -71,6 +71,10 @@ Macro form of :cfunc:`PyList_Size` without error checking. + .. versionchanged:: 2.5 + This function returned an :ctype:`int`. This might require changes in + your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index) @@ -88,6 +92,10 @@ Macro form of :cfunc:`PyList_GetItem` without error checking. + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *i*. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item) @@ -116,6 +124,10 @@ it being replaced; any reference in *list* at position *i* will be leaked. + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *i*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyList_Insert(PyObject *list, Py_ssize_t index, PyObject *item) From python-checkins at python.org Sat Apr 25 22:14:29 2009 From: python-checkins at python.org (kurt.kaiser) Date: Sat, 25 Apr 2009 22:14:29 +0200 (CEST) Subject: [Python-checkins] r71924 - python/branches/py3k/Lib/idlelib/NEWS.txt Message-ID: <20090425201429.44ABF1E4018@bag.python.org> Author: kurt.kaiser Date: Sat Apr 25 22:14:29 2009 New Revision: 71924 Log: Fix up IDLE's NEWS.txt. Include missed changes, keep 2.7 changes in separate section to make merging easier. Update release dates. Modified: python/branches/py3k/Lib/idlelib/NEWS.txt Modified: python/branches/py3k/Lib/idlelib/NEWS.txt ============================================================================== --- python/branches/py3k/Lib/idlelib/NEWS.txt (original) +++ python/branches/py3k/Lib/idlelib/NEWS.txt Sat Apr 25 22:14:29 2009 @@ -1,17 +1,13 @@ -What's New in IDLE 3.1a1? +What's New in IDLE 3.1b1? ========================= -*Release date: XX-XXX-XXXX* +*Release date: XX-XXX-09* -- Allow multiple IDLE GUI/subprocess pairs to exist simultaneously. Thanks to - David Scherer for suggesting the use of an ephemeral port for the GUI. - Patch 1529142 Weeble. -- Remove port spec from run.py and fix bug where subprocess fails to - extract port from command line when warnings are present. +What's New in IDLE 3.1a1? +========================= -- Tk 8.5 Text widget requires 'wordprocessor' tabstyle attr to handle - mixed space/tab properly. Issue 5120, patch by Guilherme Polo. +*Release date: 07-Mar-09* - Issue #4815: Offer conversion to UTF-8 if source files have no encoding declaration and are not encoded in UTF-8. @@ -23,11 +19,40 @@ user configuration of source encoding; all according to PEP 3120. -- Issue #3549: On MacOS the preferences menu was not present - - Issue #2665: On Windows, an IDLE installation upgraded from an old version would not start if a custom theme was defined. +What's New in IDLE 2.7? (UNRELEASED, but merged into 3.1 releases above.) +======================= + +*Release date: XX-XXX-2009* + +- Allow multiple IDLE GUI/subprocess pairs to exist simultaneously. Thanks to + David Scherer for suggesting the use of an ephemeral port for the GUI. + Patch 1529142 Weeble. + +- Remove port spec from run.py and fix bug where subprocess fails to + extract port from command line when warnings are present. + +- Tk 8.5 Text widget requires 'wordprocessor' tabstyle attr to handle + mixed space/tab properly. Issue 5120, patch by Guilherme Polo. + +- Issue #3549: On MacOS the preferences menu was not present + +What's New in IDLE 3.0 final? +============================= + +*Release date: 03-Dec-2008* + +- IDLE would print a "Unhandled server exception!" message when internal + debugging is enabled. + +- Issue #4455: IDLE failed to display the windows list when two windows have + the same title. + +- Issue #4383: When IDLE cannot make the connection to its subprocess, it would + fail to properly display the error message. + What's New in IDLE 3.0a3? ========================= @@ -43,6 +68,8 @@ - Shell was not colorizing due to bug introduced at r57998, Bug 1586. +- Issue #1585: IDLE uses non-existent xrange() function. + What's New in IDLE 3.0a2? ========================= @@ -56,7 +83,7 @@ What's New in IDLE 3.0a1? ========================= -*Release date: 31-AUG-2007* +*Release date: 31-Aug-2007* - IDLE converted to Python 3000 syntax. @@ -69,18 +96,32 @@ - atexit call replaces sys.exitfunc. The functionality of delete-exitfunc flag in config-main.cfg remains unchanged: if set, registered exit functions will be cleared before IDLE exits. - -What's New in IDLE 2.6a1? -========================= -*Release date: XX-XXX-200X* UNRELEASED, but merged into 3.0 +What's New in IDLE 2.6 final? +============================= + +*Release date: 01-Oct-2008*, merged into 3.0 releases detailed above (3.0rc2) + +- Issue #2665: On Windows, an IDLE installation upgraded from an old version + would not start if a custom theme was defined. + +- Home / Control-A toggles between left margin and end of leading white + space. issue1196903, patch by Jeff Shute. + +- Improved AutoCompleteWindow logic. issue2062, patch by Tal Einat. + +- Autocompletion of filenames now support alternate separators, e.g. the + '/' char on Windows. issue2061 Patch by Tal Einat. + +- Make IDLE Help window non-modal, singleton, and re-raise if called. + issue964437 Patch by Guilherme Polo. - Configured selection highlighting colors were ignored; updating highlighting in the config dialog would cause non-Python files to be colored as if they were Python source; improve use of ColorDelagator. Patch 1334. Tal Einat. -- ScriptBinding event handlers weren't returning 'break'. Patch 2050, Tal Einat. +- ScriptBinding event handlers weren't returning 'break'. Patch 2050, Tal Einat - There was an error on exit if no sys.exitfunc was defined. Issue 1647. From python-checkins at python.org Sat Apr 25 22:37:39 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 22:37:39 +0200 (CEST) Subject: [Python-checkins] r71925 - python/trunk/Doc/c-api/list.rst Message-ID: <20090425203739.D39F71E4018@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 22:37:39 2009 New Revision: 71925 Log: Since it's a macro, actually refer to it as such instead of function. Modified: python/trunk/Doc/c-api/list.rst Modified: python/trunk/Doc/c-api/list.rst ============================================================================== --- python/trunk/Doc/c-api/list.rst (original) +++ python/trunk/Doc/c-api/list.rst Sat Apr 25 22:37:39 2009 @@ -72,8 +72,8 @@ Macro form of :cfunc:`PyList_Size` without error checking. .. versionchanged:: 2.5 - This function returned an :ctype:`int`. This might require changes in - your code for properly supporting 64-bit systems. + This macro returned an :ctype:`int`. This might require changes in your + code for properly supporting 64-bit systems. .. cfunction:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index) @@ -93,8 +93,8 @@ Macro form of :cfunc:`PyList_GetItem` without error checking. .. versionchanged:: 2.5 - This function used an :ctype:`int` for *i*. This might require changes - in your code for properly supporting 64-bit systems. + This macro used an :ctype:`int` for *i*. This might require changes in + your code for properly supporting 64-bit systems. .. cfunction:: int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item) @@ -119,13 +119,13 @@ .. note:: - This function "steals" a reference to *item*, and, unlike + This macro "steals" a reference to *item*, and, unlike :cfunc:`PyList_SetItem`, does *not* discard a reference to any item that it being replaced; any reference in *list* at position *i* will be leaked. .. versionchanged:: 2.5 - This function used an :ctype:`int` for *i*. This might require + This macro used an :ctype:`int` for *i*. This might require changes in your code for properly supporting 64-bit systems. From python-checkins at python.org Sat Apr 25 22:40:11 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 22:40:11 +0200 (CEST) Subject: [Python-checkins] r71926 - python/trunk/Doc/c-api/marshal.rst Message-ID: <20090425204011.0D0111E402A@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 22:40:10 2009 New Revision: 71926 Log: Reformat prior to editing. Modified: python/trunk/Doc/c-api/marshal.rst Modified: python/trunk/Doc/c-api/marshal.rst ============================================================================== --- python/trunk/Doc/c-api/marshal.rst (original) +++ python/trunk/Doc/c-api/marshal.rst Sat Apr 25 22:40:10 2009 @@ -5,25 +5,26 @@ Data marshalling support ======================== -These routines allow C code to work with serialized objects using the same data -format as the :mod:`marshal` module. There are functions to write data into the -serialization format, and additional functions that can be used to read the data -back. Files used to store marshalled data must be opened in binary mode. +These routines allow C code to work with serialized objects using the same +data format as the :mod:`marshal` module. There are functions to write data +into the serialization format, and additional functions that can be used to +read the data back. Files used to store marshalled data must be opened in +binary mode. Numeric values are stored with the least significant byte first. -The module supports two versions of the data format: version 0 is the historical -version, version 1 (new in Python 2.4) shares interned strings in the file, and -upon unmarshalling. Version 2 (new in Python 2.5) uses a binary format for -floating point numbers. -*Py_MARSHAL_VERSION* indicates the current file format (currently 2). +The module supports two versions of the data format: version 0 is the +historical version, version 1 (new in Python 2.4) shares interned strings in +the file, and upon unmarshalling. Version 2 (new in Python 2.5) uses a binary +format for floating point numbers. *Py_MARSHAL_VERSION* indicates the current +file format (currently 2). .. cfunction:: void PyMarshal_WriteLongToFile(long value, FILE *file, int version) - Marshal a :ctype:`long` integer, *value*, to *file*. This will only write the - least-significant 32 bits of *value*; regardless of the size of the native - :ctype:`long` type. + Marshal a :ctype:`long` integer, *value*, to *file*. This will only write + the least-significant 32 bits of *value*; regardless of the size of the + native :ctype:`long` type. .. versionchanged:: 2.4 *version* indicates the file format. @@ -48,24 +49,24 @@ The following functions allow marshalled values to be read back in. XXX What about error detection? It appears that reading past the end of the -file will always result in a negative numeric value (where that's relevant), but -it's not clear that negative values won't be handled properly when there's no -error. What's the right way to tell? Should only non-negative values be written -using these routines? +file will always result in a negative numeric value (where that's relevant), +but it's not clear that negative values won't be handled properly when there's +no error. What's the right way to tell? Should only non-negative values be +written using these routines? .. cfunction:: long PyMarshal_ReadLongFromFile(FILE *file) - Return a C :ctype:`long` from the data stream in a :ctype:`FILE\*` opened for - reading. Only a 32-bit value can be read in using this function, regardless of - the native size of :ctype:`long`. + Return a C :ctype:`long` from the data stream in a :ctype:`FILE\*` opened + for reading. Only a 32-bit value can be read in using this function, + regardless of the native size of :ctype:`long`. .. cfunction:: int PyMarshal_ReadShortFromFile(FILE *file) - Return a C :ctype:`short` from the data stream in a :ctype:`FILE\*` opened for - reading. Only a 16-bit value can be read in using this function, regardless of - the native size of :ctype:`short`. + Return a C :ctype:`short` from the data stream in a :ctype:`FILE\*` opened + for reading. Only a 16-bit value can be read in using this function, + regardless of the native size of :ctype:`short`. .. cfunction:: PyObject* PyMarshal_ReadObjectFromFile(FILE *file) @@ -78,17 +79,18 @@ .. cfunction:: PyObject* PyMarshal_ReadLastObjectFromFile(FILE *file) Return a Python object from the data stream in a :ctype:`FILE\*` opened for - reading. Unlike :cfunc:`PyMarshal_ReadObjectFromFile`, this function assumes - that no further objects will be read from the file, allowing it to aggressively - load file data into memory so that the de-serialization can operate from data in - memory rather than reading a byte at a time from the file. Only use these - variant if you are certain that you won't be reading anything else from the - file. On error, sets the appropriate exception (:exc:`EOFError` or - :exc:`TypeError`) and returns *NULL*. + reading. Unlike :cfunc:`PyMarshal_ReadObjectFromFile`, this function + assumes that no further objects will be read from the file, allowing it to + aggressively load file data into memory so that the de-serialization can + operate from data in memory rather than reading a byte at a time from the + file. Only use these variant if you are certain that you won't be reading + anything else from the file. On error, sets the appropriate exception + (:exc:`EOFError` or :exc:`TypeError`) and returns *NULL*. .. cfunction:: PyObject* PyMarshal_ReadObjectFromString(char *string, Py_ssize_t len) - Return a Python object from the data stream in a character buffer containing - *len* bytes pointed to by *string*. On error, sets the appropriate exception - (:exc:`EOFError` or :exc:`TypeError`) and returns *NULL*. + Return a Python object from the data stream in a character buffer + containing *len* bytes pointed to by *string*. On error, sets the + appropriate exception (:exc:`EOFError` or :exc:`TypeError`) and returns + *NULL*. From python-checkins at python.org Sat Apr 25 22:41:40 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 22:41:40 +0200 (CEST) Subject: [Python-checkins] r71927 - python/trunk/Doc/c-api/marshal.rst Message-ID: <20090425204140.65F821E4020@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 22:41:40 2009 New Revision: 71927 Log: Issue #4129: int -> Py_ssize_t documentation. Modified: python/trunk/Doc/c-api/marshal.rst Modified: python/trunk/Doc/c-api/marshal.rst ============================================================================== --- python/trunk/Doc/c-api/marshal.rst (original) +++ python/trunk/Doc/c-api/marshal.rst Sat Apr 25 22:41:40 2009 @@ -94,3 +94,7 @@ containing *len* bytes pointed to by *string*. On error, sets the appropriate exception (:exc:`EOFError` or :exc:`TypeError`) and returns *NULL*. + + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *len*. This might require + changes in your code for properly supporting 64-bit systems. From python-checkins at python.org Sat Apr 25 22:43:30 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 22:43:30 +0200 (CEST) Subject: [Python-checkins] r71928 - python/trunk/Doc/c-api/objbuffer.rst Message-ID: <20090425204330.5A88D1E4018@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 22:43:30 2009 New Revision: 71928 Log: Reformat prior to editing. Modified: python/trunk/Doc/c-api/objbuffer.rst Modified: python/trunk/Doc/c-api/objbuffer.rst ============================================================================== --- python/trunk/Doc/c-api/objbuffer.rst (original) +++ python/trunk/Doc/c-api/objbuffer.rst Sat Apr 25 22:43:30 2009 @@ -9,27 +9,28 @@ This section describes the legacy buffer protocol, which has been introduced in Python 1.6. It is still supported but deprecated in the Python 2.x series. Python 3.0 introduces a new buffer protocol which fixes weaknesses and -shortcomings of the protocol, and has been backported to Python 2.6. -See :ref:`bufferobjects` for more information. +shortcomings of the protocol, and has been backported to Python 2.6. See +:ref:`bufferobjects` for more information. .. cfunction:: int PyObject_AsCharBuffer(PyObject *obj, const char **buffer, Py_ssize_t *buffer_len) Returns a pointer to a read-only memory location usable as character-based input. The *obj* argument must support the single-segment character buffer - interface. On success, returns ``0``, sets *buffer* to the memory location and - *buffer_len* to the buffer length. Returns ``-1`` and sets a :exc:`TypeError` - on error. + interface. On success, returns ``0``, sets *buffer* to the memory location + and *buffer_len* to the buffer length. Returns ``-1`` and sets a + :exc:`TypeError` on error. .. versionadded:: 1.6 .. cfunction:: int PyObject_AsReadBuffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len) - Returns a pointer to a read-only memory location containing arbitrary data. The - *obj* argument must support the single-segment readable buffer interface. On - success, returns ``0``, sets *buffer* to the memory location and *buffer_len* to - the buffer length. Returns ``-1`` and sets a :exc:`TypeError` on error. + Returns a pointer to a read-only memory location containing arbitrary data. + The *obj* argument must support the single-segment readable buffer + interface. On success, returns ``0``, sets *buffer* to the memory location + and *buffer_len* to the buffer length. Returns ``-1`` and sets a + :exc:`TypeError` on error. .. versionadded:: 1.6 @@ -45,9 +46,9 @@ .. cfunction:: int PyObject_AsWriteBuffer(PyObject *obj, void **buffer, Py_ssize_t *buffer_len) Returns a pointer to a writeable memory location. The *obj* argument must - support the single-segment, character buffer interface. On success, returns - ``0``, sets *buffer* to the memory location and *buffer_len* to the buffer - length. Returns ``-1`` and sets a :exc:`TypeError` on error. + support the single-segment, character buffer interface. On success, + returns ``0``, sets *buffer* to the memory location and *buffer_len* to the + buffer length. Returns ``-1`` and sets a :exc:`TypeError` on error. .. versionadded:: 1.6 From python-checkins at python.org Sat Apr 25 22:44:59 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 22:44:59 +0200 (CEST) Subject: [Python-checkins] r71929 - python/trunk/Doc/c-api/objbuffer.rst Message-ID: <20090425204459.48E811E4018@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 22:44:58 2009 New Revision: 71929 Log: Issue #4129: int -> Py_ssize_t documentation. Modified: python/trunk/Doc/c-api/objbuffer.rst Modified: python/trunk/Doc/c-api/objbuffer.rst ============================================================================== --- python/trunk/Doc/c-api/objbuffer.rst (original) +++ python/trunk/Doc/c-api/objbuffer.rst Sat Apr 25 22:44:58 2009 @@ -23,6 +23,10 @@ .. versionadded:: 1.6 + .. versionchanged:: 2.5 + This function used an :ctype:`int *` type for *buffer_len*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyObject_AsReadBuffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len) @@ -34,6 +38,10 @@ .. versionadded:: 1.6 + .. versionchanged:: 2.5 + This function used an :ctype:`int *` type for *buffer_len*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyObject_CheckReadBuffer(PyObject *o) @@ -52,3 +60,7 @@ .. versionadded:: 1.6 + .. versionchanged:: 2.5 + This function used an :ctype:`int *` type for *buffer_len*. This might + require changes in your code for properly supporting 64-bit systems. + From python-checkins at python.org Sat Apr 25 22:47:43 2009 From: python-checkins at python.org (michael.foord) Date: Sat, 25 Apr 2009 22:47:43 +0200 (CEST) Subject: [Python-checkins] r71930 - python/branches/py3k/Doc/whatsnew/3.1.rst Message-ID: <20090425204743.B202F1E4018@bag.python.org> Author: michael.foord Date: Sat Apr 25 22:47:43 2009 New Revision: 71930 Log: Doc fix, closing issue 5826 Modified: python/branches/py3k/Doc/whatsnew/3.1.rst Modified: python/branches/py3k/Doc/whatsnew/3.1.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/3.1.rst (original) +++ python/branches/py3k/Doc/whatsnew/3.1.rst Sat Apr 25 22:47:43 2009 @@ -332,7 +332,7 @@ :func:`assertDictContainsSubset`, :func:`assertListEqual`, :func:`assertTupleEqual`, :func:`assertSequenceEqual`, :func:`assertRaisesRegexp`, :func:`assertIsNone`, - and :func:`assertIsNotNot`. + and :func:`assertIsNotNone`. (Contributed by Benjamin Peterson and Antoine Pitrou.) From python-checkins at python.org Sat Apr 25 22:50:27 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 22:50:27 +0200 (CEST) Subject: [Python-checkins] r71931 - python/trunk/Doc/c-api/sequence.rst Message-ID: <20090425205027.5522D1E4091@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 22:50:27 2009 New Revision: 71931 Log: Issue #4129: int -> Py_ssize_t documentation. Modified: python/trunk/Doc/c-api/sequence.rst Modified: python/trunk/Doc/c-api/sequence.rst ============================================================================== --- python/trunk/Doc/c-api/sequence.rst (original) +++ python/trunk/Doc/c-api/sequence.rst Sat Apr 25 22:50:27 2009 @@ -178,6 +178,10 @@ Return the *i*th element of *o*, assuming that *o* was returned by :cfunc:`PySequence_Fast`, *o* is not *NULL*, and that *i* is within bounds. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject** PySequence_Fast_ITEMS(PyObject *o) @@ -200,6 +204,10 @@ .. versionadded:: 2.3 + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PySequence_Fast_GET_SIZE(PyObject *o) From python-checkins at python.org Sat Apr 25 22:55:39 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 22:55:39 +0200 (CEST) Subject: [Python-checkins] r71932 - python/trunk/Doc/c-api/string.rst Message-ID: <20090425205539.E56771E4067@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 22:55:39 2009 New Revision: 71932 Log: Issue #4129: more int -> Py_ssize_t documentation. Modified: python/trunk/Doc/c-api/string.rst Modified: python/trunk/Doc/c-api/string.rst ============================================================================== --- python/trunk/Doc/c-api/string.rst (original) +++ python/trunk/Doc/c-api/string.rst Sat Apr 25 22:55:39 2009 @@ -147,6 +147,10 @@ Macro form of :cfunc:`PyString_Size` but without error checking. + .. versionchanged:: 2.5 + This macro returned an :ctype:`int` type. This might require changes in + your code for properly supporting 64-bit systems. + .. cfunction:: char* PyString_AsString(PyObject *string) @@ -182,6 +186,10 @@ *string* and operates on that. If *string* is not a string object at all, :cfunc:`PyString_AsStringAndSize` returns ``-1`` and raises :exc:`TypeError`. + .. versionchanged:: 2.5 + This function used an :ctype:`int *` type for *length*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: void PyString_Concat(PyObject **string, PyObject *newpart) @@ -261,6 +269,10 @@ This function is not available in 3.x and does not have a PyBytes alias. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyString_AsDecodedObject(PyObject *str, const char *encoding, const char *errors) @@ -287,6 +299,10 @@ This function is not available in 3.x and does not have a PyBytes alias. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyString_AsEncodedObject(PyObject *str, const char *encoding, const char *errors) From python-checkins at python.org Sat Apr 25 22:58:35 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 22:58:35 +0200 (CEST) Subject: [Python-checkins] r71933 - python/trunk/Doc/c-api/tuple.rst Message-ID: <20090425205835.480971E4018@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 22:58:35 2009 New Revision: 71933 Log: Issue #4129: more int -> Py_ssize_t documentation. Modified: python/trunk/Doc/c-api/tuple.rst Modified: python/trunk/Doc/c-api/tuple.rst ============================================================================== --- python/trunk/Doc/c-api/tuple.rst (original) +++ python/trunk/Doc/c-api/tuple.rst Sat Apr 25 22:58:35 2009 @@ -74,6 +74,10 @@ Return the size of the tuple *p*, which must be non-*NULL* and point to a tuple; no error checking is performed. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyTuple_GetItem(PyObject *p, Py_ssize_t pos) @@ -89,6 +93,10 @@ Like :cfunc:`PyTuple_GetItem`, but does no checking of its arguments. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *pos*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyTuple_GetSlice(PyObject *p, Py_ssize_t low, Py_ssize_t high) @@ -123,6 +131,10 @@ This function "steals" a reference to *o*. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *pos*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: int _PyTuple_Resize(PyObject **p, Py_ssize_t newsize) From python-checkins at python.org Sat Apr 25 23:02:34 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 23:02:34 +0200 (CEST) Subject: [Python-checkins] r71934 - python/trunk/Doc/c-api/typeobj.rst Message-ID: <20090425210234.9D5521E4018@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 23:02:34 2009 New Revision: 71934 Log: Issue #4129: field changed from int to Py_ssize_t. Modified: python/trunk/Doc/c-api/typeobj.rst Modified: python/trunk/Doc/c-api/typeobj.rst ============================================================================== --- python/trunk/Doc/c-api/typeobj.rst (original) +++ python/trunk/Doc/c-api/typeobj.rst Sat Apr 25 23:02:34 2009 @@ -64,6 +64,10 @@ This field is not inherited by subtypes. + .. versionchanged:: 2.5 + This field used to be an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cmember:: PyTypeObject* PyObject.ob_type From python-checkins at python.org Sat Apr 25 23:04:19 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 25 Apr 2009 23:04:19 +0200 (CEST) Subject: [Python-checkins] r71935 - python/branches/py3k/Makefile.pre.in Message-ID: <20090425210419.AFB9A1E4042@bag.python.org> Author: benjamin.peterson Date: Sat Apr 25 23:04:19 2009 New Revision: 71935 Log: fix some issues with install and altinstall #5818 1. fullinstall should install 'python' 2. remove link targets if already exist 3. make python3-config 4. install the man in altinstall 5. $(EXE) consistency Patch by Larry Hastings 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 Apr 25 23:04:19 2009 @@ -746,20 +746,20 @@ -$(TESTPYTHON) $(TESTPROG) $(MEMTESTOPTS) $(TESTPYTHON) $(TESTPROG) $(MEMTESTOPTS) -# Install everything -fullinstall: @FRAMEWORKINSTALLFIRST@ altinstall bininstall maninstall @FRAMEWORKINSTALLLAST@ +# Install everything, and install Python 3 to "python" +fullinstall: @FRAMEWORKINSTALLFIRST@ altinstall bininstall @FRAMEWORKINSTALLLAST@ -# "make install" is an alias for "make altinstall" since we never want to -# overwrite Python 2.x. +# "make install" is an alias for "make altinstall" since we don't want to +# overwrite Python 2.x by default. install: altinstall @echo "* Note: not installed as 'python'." @echo "* Use 'make fullinstall' to install as 'python'." @echo "* However, 'make fullinstall' is discouraged," @echo "* as it will clobber your Python 2.x installation." -# Install almost everything without disturbing previous versions +# Install almost everything without disturbing 2.x versions altinstall: @FRAMEWORKALTINSTALLFIRST@ altbininstall libinstall inclinstall libainstall \ - sharedinstall oldsharedinstall @FRAMEWORKALTINSTALLLAST@ + sharedinstall oldsharedinstall maninstall @FRAMEWORKALTINSTALLLAST@ # Install shared libraries enabled by Setup DESTDIRS= $(exec_prefix) $(LIBDIR) $(BINLIBDEST) $(DESTSHARED) @@ -785,10 +785,11 @@ # Install the interpreter (by creating a hard link to python$(VERSION)) bininstall: altbininstall - -if test -f $(DESTDIR)$(BINDIR)/$(PYTHON) -o -h $(DESTDIR)$(BINDIR)/$(PYTHON); \ - then rm -f $(DESTDIR)$(BINDIR)/$(PYTHON); \ + -if test -f $(DESTDIR)$(BINDIR)/$(PYTHON)$(EXE) -o -h $(DESTDIR)$(BINDIR)/$(PYTHON)$(EXE); \ + then rm -f $(DESTDIR)$(BINDIR)/$(PYTHON)$(EXE); \ else true; \ fi + (cd $(DESTDIR)$(BINDIR); $(LN) python$(VERSION)$(EXE) $(PYTHON)$(EXE)) -rm -f $(DESTDIR)$(BINDIR)/python-config (cd $(DESTDIR)$(BINDIR); $(LN) -s python$(VERSION)-config python-config) @@ -815,7 +816,13 @@ fi; \ else true; \ fi - (cd $(DESTDIR)$(BINDIR); $(LN) python$(VERSION)$(EXE) $(PYTHON)3) + -if test -f $(DESTDIR)$(BINDIR)/$(PYTHON)3$(EXE) -o -h $(DESTDIR)$(BINDIR)/$(PYTHON)3$(EXE); \ + then rm -f $(DESTDIR)$(BINDIR)/$(PYTHON)3$(EXE); \ + else true; \ + fi + (cd $(DESTDIR)$(BINDIR); $(LN) python$(VERSION)$(EXE) $(PYTHON)3$(EXE)) + -rm -f $(DESTDIR)$(BINDIR)/python3-config + (cd $(DESTDIR)$(BINDIR); $(LN) -s python$(VERSION)-config python3-config) # Install the manual page maninstall: From python-checkins at python.org Sat Apr 25 23:11:46 2009 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 25 Apr 2009 23:11:46 +0200 (CEST) Subject: [Python-checkins] r71936 - in python/branches/py3k: Misc/NEWS Tools/scripts/idle Tools/scripts/idle3 Tools/scripts/pydoc Tools/scripts/pydoc3 setup.py Message-ID: <20090425211146.2AFE81E4010@bag.python.org> Author: benjamin.peterson Date: Sat Apr 25 23:11:45 2009 New Revision: 71936 Log: install idle and pydoc with a 3 suffix #5756 Added: python/branches/py3k/Tools/scripts/idle3 - copied, changed from r71924, /python/branches/py3k/Tools/scripts/idle python/branches/py3k/Tools/scripts/pydoc3 - copied, changed from r71924, /python/branches/py3k/Tools/scripts/pydoc Removed: python/branches/py3k/Tools/scripts/idle python/branches/py3k/Tools/scripts/pydoc Modified: python/branches/py3k/Misc/NEWS python/branches/py3k/setup.py Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sat Apr 25 23:11:45 2009 @@ -76,6 +76,11 @@ - Issue #1113244: Py_XINCREF, Py_DECREF, Py_XDECREF: Add `do { ... } while (0)' to avoid compiler warnings. +Installation +------------ + +- Issue #5756: Install idle and pydoc with a 3 suffix. + Library ------- Deleted: python/branches/py3k/Tools/scripts/idle ============================================================================== --- python/branches/py3k/Tools/scripts/idle Sat Apr 25 23:11:45 2009 +++ (empty file) @@ -1,5 +0,0 @@ -#! /usr/bin/env python - -from idlelib.PyShell import main -if __name__ == '__main__': - main() Copied: python/branches/py3k/Tools/scripts/idle3 (from r71924, /python/branches/py3k/Tools/scripts/idle) ============================================================================== --- /python/branches/py3k/Tools/scripts/idle (original) +++ python/branches/py3k/Tools/scripts/idle3 Sat Apr 25 23:11:45 2009 @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 from idlelib.PyShell import main if __name__ == '__main__': Deleted: python/branches/py3k/Tools/scripts/pydoc ============================================================================== --- python/branches/py3k/Tools/scripts/pydoc Sat Apr 25 23:11:45 2009 +++ (empty file) @@ -1,5 +0,0 @@ -#!/usr/bin/env python - -import pydoc -if __name__ == '__main__': - pydoc.cli() Copied: python/branches/py3k/Tools/scripts/pydoc3 (from r71924, /python/branches/py3k/Tools/scripts/pydoc) ============================================================================== --- /python/branches/py3k/Tools/scripts/pydoc (original) +++ python/branches/py3k/Tools/scripts/pydoc3 Sat Apr 25 23:11:45 2009 @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import pydoc if __name__ == '__main__': Modified: python/branches/py3k/setup.py ============================================================================== --- python/branches/py3k/setup.py (original) +++ python/branches/py3k/setup.py Sat Apr 25 23:11:45 2009 @@ -1652,13 +1652,7 @@ # called unless there's at least one extension module defined. ext_modules=[Extension('_struct', ['_struct.c'])], - # Scripts to install - # Commented out because we don't want them to override the 2.x - # ones. See #1590. - scripts = [] - #scripts = ['Tools/scripts/pydoc', 'Tools/scripts/idle', - # 'Tools/scripts/2to3', - # 'Lib/smtpd.py'] + scripts = ["Tools/scripts/pydoc3", "Tools/scripts/idle3"] ) # --install-platlib From python-checkins at python.org Sat Apr 25 23:16:05 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sat, 25 Apr 2009 23:16:05 +0200 (CEST) Subject: [Python-checkins] r71937 - python/trunk/Doc/c-api/unicode.rst Message-ID: <20090425211605.ACC051E4010@bag.python.org> Author: jeroen.ruigrok Date: Sat Apr 25 23:16:05 2009 New Revision: 71937 Log: Issue #4129: document int -> Py_ssize_t changes. Modified: python/trunk/Doc/c-api/unicode.rst Modified: python/trunk/Doc/c-api/unicode.rst ============================================================================== --- python/trunk/Doc/c-api/unicode.rst (original) +++ python/trunk/Doc/c-api/unicode.rst Sat Apr 25 23:16:05 2009 @@ -71,12 +71,20 @@ Return the size of the object. *o* has to be a :ctype:`PyUnicodeObject` (not checked). + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PyUnicode_GET_DATA_SIZE(PyObject *o) Return the size of the object's internal buffer in bytes. *o* has to be a :ctype:`PyUnicodeObject` (not checked). + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: Py_UNICODE* PyUnicode_AS_UNICODE(PyObject *o) @@ -202,6 +210,10 @@ Therefore, modification of the resulting Unicode object is only allowed when *u* is *NULL*. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: Py_UNICODE* PyUnicode_AsUnicode(PyObject *unicode) @@ -213,6 +225,10 @@ Return the length of the Unicode object. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_FromEncodedObject(PyObject *obj, const char *encoding, const char *errors) @@ -249,6 +265,10 @@ Create a Unicode object from the :ctype:`wchar_t` buffer *w* of the given size. Return *NULL* on failure. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode, wchar_t *w, Py_ssize_t size) @@ -260,6 +280,11 @@ to make sure that the :ctype:`wchar_t` string is 0-terminated in case this is required by the application. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type and used an :ctype:`int` + type for *size*. This might require changes in your code for properly + supporting 64-bit systems. + .. _builtincodecs: @@ -299,6 +324,10 @@ using the Python codec registry. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_Encode(const Py_UNICODE *s, Py_ssize_t size, const char *encoding, const char *errors) @@ -308,6 +337,10 @@ looked up using the Python codec registry. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsEncodedString(PyObject *unicode, const char *encoding, const char *errors) @@ -327,6 +360,10 @@ Create a Unicode object by decoding *size* bytes of the UTF-8 encoded string *s*. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_DecodeUTF8Stateful(const char *s, Py_ssize_t size, const char *errors, Py_ssize_t *consumed) @@ -337,12 +374,20 @@ .. versionadded:: 2.4 + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_EncodeUTF8(const Py_UNICODE *s, Py_ssize_t size, const char *errors) Encode the :ctype:`Py_UNICODE` buffer of the given size using UTF-8 and return a Python string object. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsUTF8String(PyObject *unicode) @@ -450,6 +495,10 @@ Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_DecodeUTF16Stateful(const char *s, Py_ssize_t size, const char *errors, int *byteorder, Py_ssize_t *consumed) @@ -461,6 +510,11 @@ .. versionadded:: 2.4 + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size* and an :ctype:`int *` + type for *consumed*. This might require changes in your code for + properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_EncodeUTF16(const Py_UNICODE *s, Py_ssize_t size, const char *errors, int byteorder) @@ -481,6 +535,10 @@ Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsUTF16String(PyObject *unicode) @@ -498,6 +556,10 @@ Create a Unicode object by decoding *size* bytes of the Unicode-Escape encoded string *s*. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size) @@ -505,6 +567,10 @@ return a Python string object. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsUnicodeEscapeString(PyObject *unicode) @@ -522,6 +588,10 @@ Create a Unicode object by decoding *size* bytes of the Raw-Unicode-Escape encoded string *s*. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size, const char *errors) @@ -529,6 +599,10 @@ and return a Python string object. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) @@ -547,12 +621,20 @@ Create a Unicode object by decoding *size* bytes of the Latin-1 encoded string *s*. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_EncodeLatin1(const Py_UNICODE *s, Py_ssize_t size, const char *errors) Encode the :ctype:`Py_UNICODE` buffer of the given size using Latin-1 and return a Python string object. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsLatin1String(PyObject *unicode) @@ -571,12 +653,20 @@ Create a Unicode object by decoding *size* bytes of the ASCII encoded string *s*. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_EncodeASCII(const Py_UNICODE *s, Py_ssize_t size, const char *errors) Encode the :ctype:`Py_UNICODE` buffer of the given size using ASCII and return a Python string object. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsASCIIString(PyObject *unicode) @@ -622,6 +712,10 @@ .. versionchanged:: 2.4 Allowed unicode string as mapping argument. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_EncodeCharmap(const Py_UNICODE *s, Py_ssize_t size, PyObject *mapping, const char *errors) @@ -629,6 +723,10 @@ *mapping* object and return a Python string object. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsCharmapString(PyObject *unicode, PyObject *mapping) @@ -652,6 +750,10 @@ and sequences work well. Unmapped character ordinals (ones which cause a :exc:`LookupError`) are left untouched and are copied as-is. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + These are the MBCS codec APIs. They are currently only available on Windows and use the Win32 MBCS converters to implement the conversions. Note that MBCS (or DBCS) is a class of encodings, not just one. The target encoding is defined by @@ -665,6 +767,10 @@ Create a Unicode object by decoding *size* bytes of the MBCS encoded string *s*. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_DecodeMBCSStateful(const char *s, int size, const char *errors, int *consumed) @@ -681,6 +787,10 @@ Encode the :ctype:`Py_UNICODE` buffer of the given size using MBCS and return a Python string object. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsMBCSString(PyObject *unicode) @@ -715,6 +825,10 @@ separator. At most *maxsplit* splits will be done. If negative, no limit is set. Separators are not included in the resulting list. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *maxsplit*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_Splitlines(PyObject *s, int keepend) @@ -751,6 +865,11 @@ (*direction* == -1 means to do a prefix match, *direction* == 1 a suffix match), 0 otherwise. Return ``-1`` if an error occurred. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *start* and *end*. This + might require changes in your code for properly supporting 64-bit + systems. + .. cfunction:: Py_ssize_t PyUnicode_Find(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction) @@ -760,12 +879,22 @@ ``-1`` indicates that no match was found, and ``-2`` indicates that an error occurred and an exception has been set. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *start* and *end*. This + might require changes in your code for properly supporting 64-bit + systems. + .. cfunction:: Py_ssize_t PyUnicode_Count(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end) Return the number of non-overlapping occurrences of *substr* in ``str[start:end]``. Return ``-1`` if an error occurred. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type and used an :ctype:`int` + type for *start* and *end*. This might require changes in your code for + properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_Replace(PyObject *str, PyObject *substr, PyObject *replstr, Py_ssize_t maxcount) @@ -773,6 +902,10 @@ return the resulting Unicode object. *maxcount* == -1 means replace all occurrences. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *maxcount*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyUnicode_Compare(PyObject *left, PyObject *right) From buildbot at python.org Sat Apr 25 23:34:04 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 21:34:04 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090425213404.BF1901E4010@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/639 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: thomas.heller BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_bytes make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sat Apr 25 23:40:15 2009 From: python-checkins at python.org (eric.smith) Date: Sat, 25 Apr 2009 23:40:15 +0200 (CEST) Subject: [Python-checkins] r71938 - in python/trunk: Doc/c-api/conversion.rst Include/pystrtod.h Lib/test/test_ascii_formatd.py Misc/NEWS Modules/cPickle.c Objects/floatobject.c Objects/stringobject.c Objects/unicodeobject.c Python/pystrtod.c Message-ID: <20090425214015.D0BC81E405B@bag.python.org> Author: eric.smith Date: Sat Apr 25 23:40:15 2009 New Revision: 71938 Log: Issue #5835, deprecate PyOS_ascii_formatd. If anyone wants to clean up the documentation, feel free. It's my first documentation foray, and it's not that great. Will port to py3k with a different strategy. Added: python/trunk/Lib/test/test_ascii_formatd.py Modified: python/trunk/Doc/c-api/conversion.rst python/trunk/Include/pystrtod.h python/trunk/Misc/NEWS python/trunk/Modules/cPickle.c python/trunk/Objects/floatobject.c python/trunk/Objects/stringobject.c python/trunk/Objects/unicodeobject.c python/trunk/Python/pystrtod.c Modified: python/trunk/Doc/c-api/conversion.rst ============================================================================== --- python/trunk/Doc/c-api/conversion.rst (original) +++ python/trunk/Doc/c-api/conversion.rst Sat Apr 25 23:40:15 2009 @@ -76,7 +76,42 @@ the conversion failed. .. versionadded:: 2.4 + .. deprecated:: 2.7 + This function is removed in Python 2.7 and 3.1. Use :func:`PyOS_double_to_string` + instead. +.. cfunction:: char * PyOS_double_to_string(double val, char format_code, int precision, int flags, int *ptype) + + Convert a :ctype:`double` *val* to a string using supplied + *format_code*, *precision*, and *flags*. + + *format_code* must be one of ``'e'``, ``'E'``, ``'f'``, ``'F'``, + ``'g'``, ``'G'``, ``'s'``, or ``'r'``. For ``'s'`` and ``'r'``, the + supplied *precision* must be 0 and is ignored. These specify the + standards :func:`str` and :func:`repr` formats, respectively. + + *flags* can be zero or more of the values *Py_DTSF_SIGN*, + *Py_DTSF_ADD_DOT_0*, or *Py_DTSF_ALT*, and-ed together. + + *Py_DTSF_SIGN* means always precede the returned string with a + sign character, even if *val* is non-negative. + + *Py_DTSF_ADD_DOT_0* means ensure that the returned string will + not look like an integer. + + *Py_DTSF_ALT* means apply "alternate" formatting rules. See the + documentation for the :func:`PyOS_snprintf` ``'#'`` specifier + for details. + + If *ptype* is non-NULL, then the value it points to will be set to + one of *Py_DTST_FINITE*, *Py_DTST_INFINITE*, or *Py_DTST_NAN*, + signifying that *val* is a finite number, an infinite number, or + not a number, respectively. + + The return value is a pointer to *buffer* with the converted string or NULL if + the conversion failed. + + .. versionadded:: 2.7 .. cfunction:: double PyOS_ascii_atof(const char *nptr) Modified: python/trunk/Include/pystrtod.h ============================================================================== --- python/trunk/Include/pystrtod.h (original) +++ python/trunk/Include/pystrtod.h Sat Apr 25 23:40:15 2009 @@ -8,7 +8,17 @@ PyAPI_FUNC(double) PyOS_ascii_strtod(const char *str, char **ptr); PyAPI_FUNC(double) PyOS_ascii_atof(const char *str); -PyAPI_FUNC(char *) PyOS_ascii_formatd(char *buffer, size_t buf_len, const char *format, double d); + +/* Deprecated in 2.7 and 3.1. Will disappear in 2.8 (if it exists) and 3.2 */ +PyAPI_FUNC(char *) PyOS_ascii_formatd(char *buffer, size_t buf_len, + const char *format, double d); + +/* Use PyOS_double_to_string instead. It's the same, except it allocates + the appropriately sized buffer and returns it. This function will go + away in Python 2.8 and 3.2. */ +PyAPI_FUNC(void) _PyOS_double_to_string(char *buf, size_t buf_len, double val, + char format_code, int precision, + int flags, int* type); /* The caller is responsible for calling PyMem_Free to free the buffer that's is returned. */ Added: python/trunk/Lib/test/test_ascii_formatd.py ============================================================================== --- (empty file) +++ python/trunk/Lib/test/test_ascii_formatd.py Sat Apr 25 23:40:15 2009 @@ -0,0 +1,62 @@ +# PyOS_ascii_formatd is deprecated and not called from anywhere in +# Python itself. So this module is the only place it gets tested. +# Test that it works, and test that it's deprecated. + +import unittest +from test_support import check_warnings, run_unittest, cpython_only + + +class FormatDeprecationTests(unittest.TestCase): + + @cpython_only + def testFormatDeprecation(self): + # delay importing ctypes until we know we're in CPython + from ctypes import (pythonapi, create_string_buffer, sizeof, byref, + c_double) + PyOS_ascii_formatd = pythonapi.PyOS_ascii_formatd + buf = create_string_buffer(' ' * 100) + + with check_warnings() as w: + PyOS_ascii_formatd(byref(buf), sizeof(buf), '%+.10f', + c_double(10.0)) + self.assertEqual(buf.value, '+10.0000000000') + + self.assertEqual(str(w.message), 'PyOS_ascii_formatd is deprecated, ' + 'use PyOS_double_to_string instead') + +class FormatTests(unittest.TestCase): + # ensure that, for the restricted set of format codes, + # %-formatting returns the same values os PyOS_ascii_formatd + @cpython_only + def testFormat(self): + # delay importing ctypes until we know we're in CPython + from ctypes import (pythonapi, create_string_buffer, sizeof, byref, + c_double) + PyOS_ascii_formatd = pythonapi.PyOS_ascii_formatd + buf = create_string_buffer(' ' * 100) + + tests = [ + ('%f', 100.0), + ('%g', 100.0), + ('%#g', 100.0), + ('%#.2g', 100.0), + ('%#.2g', 123.4567), + ('%#.2g', 1.234567e200), + ('%e', 1.234567e200), + ('%e', 1.234), + ('%+e', 1.234), + ('%-e', 1.234), + ] + + with check_warnings(): + for format, val in tests: + PyOS_ascii_formatd(byref(buf), sizeof(buf), format, + c_double(val)) + self.assertEqual(buf.value, format % val) + + +def test_main(): + run_unittest(FormatDeprecationTests, FormatTests) + +if __name__ == '__main__': + test_main() Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sat Apr 25 23:40:15 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #5835: Deprecate PyOS_ascii_formatd and replace it with + _PyOS_double_to_string or PyOS_double_to_string. + - Issue #5283: Setting __class__ in __del__ caused a segfault. - Issue #5816: complex(repr(z)) now recovers z exactly, even when Modified: python/trunk/Modules/cPickle.c ============================================================================== --- python/trunk/Modules/cPickle.c (original) +++ python/trunk/Modules/cPickle.c Sat Apr 25 23:40:15 2009 @@ -1166,7 +1166,8 @@ else { char c_str[250]; c_str[0] = FLOAT; - PyOS_ascii_formatd(c_str + 1, sizeof(c_str) - 2, "%.17g", x); + _PyOS_double_to_string(c_str + 1, sizeof(c_str) - 2, x, 'g', + 17, 0, NULL); /* Extend the formatted string with a newline character */ strcat(c_str, "\n"); Modified: python/trunk/Objects/floatobject.c ============================================================================== --- python/trunk/Objects/floatobject.c (original) +++ python/trunk/Objects/floatobject.c Sat Apr 25 23:40:15 2009 @@ -342,7 +342,6 @@ format_float(char *buf, size_t buflen, PyFloatObject *v, int precision) { register char *cp; - char format[32]; int i; /* Subroutine for float_repr and float_print. @@ -352,8 +351,8 @@ in such cases, we append ".0" to the string. */ assert(PyFloat_Check(v)); - PyOS_snprintf(format, 32, "%%.%ig", precision); - PyOS_ascii_formatd(buf, buflen, format, v->ob_fval); + _PyOS_double_to_string(buf, buflen, v->ob_fval, 'g', precision, + 0, NULL); cp = buf; if (*cp == '-') cp++; Modified: python/trunk/Objects/stringobject.c ============================================================================== --- python/trunk/Objects/stringobject.c (original) +++ python/trunk/Objects/stringobject.c Sat Apr 25 23:40:15 2009 @@ -4332,9 +4332,6 @@ formatfloat(char *buf, size_t buflen, int flags, int prec, int type, PyObject *v) { - /* fmt = '%#.' + `prec` + `type` - worst case length = 3 + 10 (len of INT_MAX) + 1 = 14 (use 20)*/ - char fmt[20]; double x; x = PyFloat_AsDouble(v); if (x == -1.0 && PyErr_Occurred()) { @@ -4378,10 +4375,8 @@ "formatted float is too long (precision too large?)"); return -1; } - PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%d%c", - (flags&F_ALT) ? "#" : "", - prec, type); - PyOS_ascii_formatd(buf, buflen, fmt, x); + _PyOS_double_to_string(buf, buflen, x, type, prec, + (flags&F_ALT)?Py_DTSF_ALT:0, NULL); return (int)strlen(buf); } Modified: python/trunk/Objects/unicodeobject.c ============================================================================== --- python/trunk/Objects/unicodeobject.c (original) +++ python/trunk/Objects/unicodeobject.c Sat Apr 25 23:40:15 2009 @@ -8245,11 +8245,13 @@ } static int -doubletounicode(Py_UNICODE *buffer, size_t len, const char *format, double x) +doubletounicode(Py_UNICODE *buffer, size_t len, int format_code, + int precision, int flags, double x) { Py_ssize_t result; - PyOS_ascii_formatd((char *)buffer, len, format, x); + _PyOS_double_to_string((char *)buffer, len, x, format_code, precision, + flags, NULL); result = strtounicode(buffer, (char *)buffer); return Py_SAFE_DOWNCAST(result, Py_ssize_t, int); } @@ -8276,9 +8278,6 @@ int type, PyObject *v) { - /* fmt = '%#.' + `prec` + `type` - worst case length = 3 + 10 (len of INT_MAX) + 1 = 14 (use 20)*/ - char fmt[20]; double x; x = PyFloat_AsDouble(v); @@ -8320,10 +8319,8 @@ "formatted float is too long (precision too large?)"); return -1; } - PyOS_snprintf(fmt, sizeof(fmt), "%%%s.%d%c", - (flags&F_ALT) ? "#" : "", - prec, type); - return doubletounicode(buf, buflen, fmt, x); + return doubletounicode(buf, buflen, type, prec, + (flags&F_ALT)?Py_DTSF_ALT:0, x); } static PyObject* Modified: python/trunk/Python/pystrtod.c ============================================================================== --- python/trunk/Python/pystrtod.c (original) +++ python/trunk/Python/pystrtod.c Sat Apr 25 23:40:15 2009 @@ -236,6 +236,25 @@ } +Py_LOCAL_INLINE(void) +ensure_sign(char* buffer, size_t buf_size) +{ + Py_ssize_t len; + + if (buffer[0] == '-') + /* Already have a sign. */ + return; + + /* Include the trailing 0 byte. */ + len = strlen(buffer)+1; + if (len >= buf_size+1) + /* No room for the sign, don't do anything. */ + return; + + memmove(buffer+1, buffer, len); + buffer[0] = '+'; +} + /* From the C99 standard, section 7.19.6: The exponent always contains at least two digits, and only as many more digits as necessary to represent the exponent. @@ -363,7 +382,7 @@ #define FLOAT_FORMATBUFLEN 120 /** - * PyOS_ascii_formatd: + * _PyOS_ascii_formatd: * @buffer: A buffer to place the resulting string in * @buf_size: The length of the buffer. * @format: The printf()-style format to use for the @@ -380,7 +399,8 @@ * * Return value: The pointer to the buffer with the converted string. **/ -char * +/* DEPRECATED, will be deleted in 2.8 and 3.2 */ +PyAPI_FUNC(char *) PyOS_ascii_formatd(char *buffer, size_t buf_size, const char *format, @@ -393,6 +413,11 @@ also with at least one character past the decimal. */ char tmp_format[FLOAT_FORMATBUFLEN]; + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "PyOS_ascii_formatd is deprecated, " + "use PyOS_double_to_string instead", 1) < 0) + return NULL; + /* The last character in the format string must be the format char */ format_char = format[format_len - 1]; @@ -456,20 +481,22 @@ return buffer; } -PyAPI_FUNC(char *) PyOS_double_to_string(double val, - char format_code, - int precision, - int flags, - int *type) +PyAPI_FUNC(void) +_PyOS_double_to_string(char *buf, size_t buf_len, double val, + char format_code, int precision, + int flags, int *ptype) { - char buf[128]; char format[32]; - Py_ssize_t len; - char *result; - char *p; int t; int upper = 0; + if (buf_len < 1) { + assert(0); + /* There's no way to signal this error. Just return. */ + return; + } + buf[0] = 0; + /* Validate format_code, and map upper and lower case */ switch (format_code) { case 'e': /* exponent */ @@ -490,25 +517,29 @@ break; case 'r': /* repr format */ /* Supplied precision is unused, must be 0. */ - if (precision != 0) { - PyErr_BadInternalCall(); - return NULL; - } + if (precision != 0) + return; precision = 17; format_code = 'g'; break; case 's': /* str format */ /* Supplied precision is unused, must be 0. */ - if (precision != 0) { - PyErr_BadInternalCall(); - return NULL; - } + if (precision != 0) + return; precision = 12; format_code = 'g'; break; default: - PyErr_BadInternalCall(); - return NULL; + assert(0); + return; + } + + /* Check for buf too small to fit "-inf". Other buffer too small + conditions are dealt with when converting or formatting finite + numbers. */ + if (buf_len < 5) { + assert(0); + return; } /* Handle nan and inf. */ @@ -524,41 +555,74 @@ } else { t = Py_DTST_FINITE; + /* Build the format string. */ + PyOS_snprintf(format, sizeof(format), "%%%s.%i%c", + (flags & Py_DTSF_ALT ? "#" : ""), precision, + format_code); + + /* Have PyOS_snprintf do the hard work. */ + PyOS_snprintf(buf, buf_len, format, val); + + /* Do various fixups on the return string */ + + /* Get the current locale, and find the decimal point string. + Convert that string back to a dot. */ + change_decimal_from_locale_to_dot(buf); + + /* If an exponent exists, ensure that the exponent is at least + MIN_EXPONENT_DIGITS digits, providing the buffer is large + enough for the extra zeros. Also, if there are more than + MIN_EXPONENT_DIGITS, remove as many zeros as possible until + we get back to MIN_EXPONENT_DIGITS */ + ensure_minumim_exponent_length(buf, buf_len); + /* Possibly make sure we have at least one character after the + decimal point (and make sure we have a decimal point). */ if (flags & Py_DTSF_ADD_DOT_0) - format_code = 'Z'; + ensure_decimal_point(buf, buf_len); + } - PyOS_snprintf(format, 32, "%%%s.%i%c", (flags & Py_DTSF_ALT ? "#" : ""), precision, format_code); - PyOS_ascii_formatd(buf, sizeof(buf), format, val); + /* Add the sign if asked and the result isn't negative. */ + if (flags & Py_DTSF_SIGN && buf[0] != '-') + ensure_sign(buf, buf_len); + + if (upper) { + /* Convert to upper case. */ + char *p; + for (p = buf; *p; p++) + *p = toupper(*p); } + if (ptype) + *ptype = t; +} + + +PyAPI_FUNC(char *) PyOS_double_to_string(double val, + char format_code, + int precision, + int flags, + int *ptype) +{ + char buf[128]; + Py_ssize_t len; + char *result; + + _PyOS_double_to_string(buf, sizeof(buf), val, format_code, precision, + flags, ptype); len = strlen(buf); + if (len == 0) { + PyErr_BadInternalCall(); + return NULL; + } - /* Add 1 for the trailing 0 byte. - Add 1 because we might need to make room for the sign. - */ - result = PyMem_Malloc(len + 2); + /* Add 1 for the trailing 0 byte. */ + result = PyMem_Malloc(len + 1); if (result == NULL) { PyErr_NoMemory(); return NULL; } - p = result; - - /* Add sign when requested. It's convenient (esp. when formatting - complex numbers) to include a sign even for inf and nan. */ - if (flags & Py_DTSF_SIGN && buf[0] != '-') - *p++ = '+'; - - strcpy(p, buf); - - if (upper) { - /* Convert to upper case. */ - char *p1; - for (p1 = p; *p1; p1++) - *p1 = toupper(*p1); - } + strcpy(result, buf); - if (type) - *type = t; return result; } From python-checkins at python.org Sat Apr 25 23:41:27 2009 From: python-checkins at python.org (eric.smith) Date: Sat, 25 Apr 2009 23:41:27 +0200 (CEST) Subject: [Python-checkins] r71939 - python/branches/release26-maint Message-ID: <20090425214127.975741E4010@bag.python.org> Author: eric.smith Date: Sat Apr 25 23:41:27 2009 New Revision: 71939 Log: Blocked revisions 71938 via svnmerge ........ r71938 | eric.smith | 2009-04-25 17:40:15 -0400 (Sat, 25 Apr 2009) | 5 lines Issue #5835, deprecate PyOS_ascii_formatd. If anyone wants to clean up the documentation, feel free. It's my first documentation foray, and it's not that great. Will port to py3k with a different strategy. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sat Apr 25 23:42:04 2009 From: python-checkins at python.org (eric.smith) Date: Sat, 25 Apr 2009 23:42:04 +0200 (CEST) Subject: [Python-checkins] r71940 - python/branches/py3k Message-ID: <20090425214204.266C21E4010@bag.python.org> Author: eric.smith Date: Sat Apr 25 23:42:04 2009 New Revision: 71940 Log: Blocked revisions 71938 via svnmerge ........ r71938 | eric.smith | 2009-04-25 17:40:15 -0400 (Sat, 25 Apr 2009) | 5 lines Issue #5835, deprecate PyOS_ascii_formatd. If anyone wants to clean up the documentation, feel free. It's my first documentation foray, and it's not that great. Will port to py3k with a different strategy. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Sat Apr 25 23:42:38 2009 From: python-checkins at python.org (eric.smith) Date: Sat, 25 Apr 2009 23:42:38 +0200 (CEST) Subject: [Python-checkins] r71941 - python/branches/release30-maint Message-ID: <20090425214238.632E81E4010@bag.python.org> Author: eric.smith Date: Sat Apr 25 23:42:38 2009 New Revision: 71941 Log: Blocked revisions 71940 via svnmerge ................ r71940 | eric.smith | 2009-04-25 17:42:04 -0400 (Sat, 25 Apr 2009) | 12 lines Blocked revisions 71938 via svnmerge ........ r71938 | eric.smith | 2009-04-25 17:40:15 -0400 (Sat, 25 Apr 2009) | 5 lines Issue #5835, deprecate PyOS_ascii_formatd. If anyone wants to clean up the documentation, feel free. It's my first documentation foray, and it's not that great. Will port to py3k with a different strategy. ........ ................ Modified: python/branches/release30-maint/ (props changed) From buildbot at python.org Sat Apr 25 23:44:23 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 21:44:23 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 3.x Message-ID: <20090425214423.23DC91E4010@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%203.x/builds/806 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson,michael.foord BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From python-checkins at python.org Sun Apr 26 00:14:33 2009 From: python-checkins at python.org (kurt.kaiser) Date: Sun, 26 Apr 2009 00:14:33 +0200 (CEST) Subject: [Python-checkins] r71942 - in python/branches/release30-maint: Lib/idlelib/NEWS.txt Message-ID: <20090425221433.7BC5A1E4018@bag.python.org> Author: kurt.kaiser Date: Sun Apr 26 00:14:33 2009 New Revision: 71942 Log: Edit IDLE's NEWS.txt to be consistent with py3k HEAD Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Lib/idlelib/NEWS.txt Modified: python/branches/release30-maint/Lib/idlelib/NEWS.txt ============================================================================== --- python/branches/release30-maint/Lib/idlelib/NEWS.txt (original) +++ python/branches/release30-maint/Lib/idlelib/NEWS.txt Sun Apr 26 00:14:33 2009 @@ -13,10 +13,26 @@ user configuration of source encoding; all according to PEP 3120. +What's New in IDLE 2.7? (UNRELEASED, but merged into 3.0 releases above.) +======================= + +*Release date: XX-XXX-2009* + - Issue #3549: On MacOS the preferences menu was not present -- Issue #2665: On Windows, an IDLE installation upgraded from an old version - would not start if a custom theme was defined. +What's New in IDLE 3.0 final? +============================= + +*Release date: 03-Dec-2008* + +- IDLE would print a "Unhandled server exception!" message when internal + debugging is enabled. + +- Issue #4455: IDLE failed to display the windows list when two windows have + the same title. + +- Issue #4383: When IDLE cannot make the connection to its subprocess, it would + fail to properly display the error message. What's New in IDLE 3.0a3? @@ -33,6 +49,8 @@ - Shell was not colorizing due to bug introduced at r57998, Bug 1586. +- Issue #1585: IDLE uses non-existent xrange() function. + What's New in IDLE 3.0a2? ========================= @@ -46,7 +64,7 @@ What's New in IDLE 3.0a1? ========================= -*Release date: 31-AUG-2007* +*Release date: 31-Aug-2007* - IDLE converted to Python 3000 syntax. @@ -59,18 +77,29 @@ - atexit call replaces sys.exitfunc. The functionality of delete-exitfunc flag in config-main.cfg remains unchanged: if set, registered exit functions will be cleared before IDLE exits. - -What's New in IDLE 2.6a1? -========================= -*Release date: XX-XXX-200X* UNRELEASED, but merged into 3.0 +What's New in IDLE 2.6 final? +============================= + +*Release date: 01-Oct-2008*, merged into 3.0 releases detailed above (3.0rc2) + +- Issue #2665: On Windows, an IDLE installation upgraded from an old version + would not start if a custom theme was defined. + +- Home / Control-A toggles between left margin and end of leading white + space. issue1196903, patch by Jeff Shute. + +- Improved AutoCompleteWindow logic. issue2062, patch by Tal Einat. + +- Autocompletion of filenames now support alternate separators, e.g. the + '/' char on Windows. issue2061 Patch by Tal Einat. - Configured selection highlighting colors were ignored; updating highlighting in the config dialog would cause non-Python files to be colored as if they were Python source; improve use of ColorDelagator. Patch 1334. Tal Einat. -- ScriptBinding event handlers weren't returning 'break'. Patch 2050, Tal Einat. +- ScriptBinding event handlers weren't returning 'break'. Patch 2050, Tal Einat - There was an error on exit if no sys.exitfunc was defined. Issue 1647. From buildbot at python.org Sun Apr 26 00:16:12 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 22:16:12 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu trunk Message-ID: <20090425221612.A3FA21E4018@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%20trunk/builds/1188 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: eric.smith,jeroen.ruigrok BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_xpickle make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sun Apr 26 00:34:54 2009 From: python-checkins at python.org (kurt.kaiser) Date: Sun, 26 Apr 2009 00:34:54 +0200 (CEST) Subject: [Python-checkins] r71943 - python/branches/py3k/Lib/idlelib/NEWS.txt Message-ID: <20090425223454.CD4281E4018@bag.python.org> Author: kurt.kaiser Date: Sun Apr 26 00:34:54 2009 New Revision: 71943 Log: Remove item from NEWS.txt; not checked in yet... Modified: python/branches/py3k/Lib/idlelib/NEWS.txt Modified: python/branches/py3k/Lib/idlelib/NEWS.txt ============================================================================== --- python/branches/py3k/Lib/idlelib/NEWS.txt (original) +++ python/branches/py3k/Lib/idlelib/NEWS.txt Sun Apr 26 00:34:54 2009 @@ -114,9 +114,6 @@ - Autocompletion of filenames now support alternate separators, e.g. the '/' char on Windows. issue2061 Patch by Tal Einat. -- Make IDLE Help window non-modal, singleton, and re-raise if called. - issue964437 Patch by Guilherme Polo. - - Configured selection highlighting colors were ignored; updating highlighting in the config dialog would cause non-Python files to be colored as if they were Python source; improve use of ColorDelagator. Patch 1334. Tal Einat. From python-checkins at python.org Sun Apr 26 01:23:34 2009 From: python-checkins at python.org (kurt.kaiser) Date: Sun, 26 Apr 2009 01:23:34 +0200 (CEST) Subject: [Python-checkins] r71944 - in python/branches/release30-maint: Lib/idlelib/EditorWindow.py Lib/idlelib/NEWS.txt Message-ID: <20090425232334.A74DB1E4010@bag.python.org> Author: kurt.kaiser Date: Sun Apr 26 01:23:34 2009 New Revision: 71944 Log: Merged revisions 71189 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71189 | kurt.kaiser | 2009-04-04 16:38:52 -0400 (Sat, 04 Apr 2009) | 9 lines Merged revisions 70723 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r70723 | kurt.kaiser | 2009-03-30 12:22:00 -0400 (Mon, 30 Mar 2009) | 1 line Tk 8.5 Text widget requires 'wordprocessor' tabstyle attr to handle mixed space/tab properly. Issue 5120, patch by Guilherme Polo. ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Lib/idlelib/EditorWindow.py python/branches/release30-maint/Lib/idlelib/NEWS.txt Modified: python/branches/release30-maint/Lib/idlelib/EditorWindow.py ============================================================================== --- python/branches/release30-maint/Lib/idlelib/EditorWindow.py (original) +++ python/branches/release30-maint/Lib/idlelib/EditorWindow.py Sun Apr 26 01:23:34 2009 @@ -107,10 +107,18 @@ self.text_frame = text_frame = Frame(top) self.vbar = vbar = Scrollbar(text_frame, name='vbar') self.width = idleConf.GetOption('main','EditorWindow','width') - self.text = text = MultiCallCreator(Text)( - text_frame, name='text', padx=5, wrap='none', - width=self.width, - height=idleConf.GetOption('main','EditorWindow','height') ) + text_options = { + 'name': 'text', + 'padx': 5, + 'wrap': 'none', + 'width': self.width, + 'height': idleConf.GetOption('main', 'EditorWindow', 'height')} + if TkVersion >= 8.5: + # Starting with tk 8.5 we have to set the new tabstyle option + # to 'wordprocessor' to achieve the same display of tabs as in + # older tk versions. + text_options['tabstyle'] = 'wordprocessor' + self.text = text = MultiCallCreator(Text)(text_frame, **text_options) self.top.focused_widget = self.text self.createmenubar() Modified: python/branches/release30-maint/Lib/idlelib/NEWS.txt ============================================================================== --- python/branches/release30-maint/Lib/idlelib/NEWS.txt (original) +++ python/branches/release30-maint/Lib/idlelib/NEWS.txt Sun Apr 26 01:23:34 2009 @@ -18,6 +18,9 @@ *Release date: XX-XXX-2009* +- Tk 8.5 Text widget requires 'wordprocessor' tabstyle attr to handle + mixed space/tab properly. Issue 5120, patch by Guilherme Polo. + - Issue #3549: On MacOS the preferences menu was not present What's New in IDLE 3.0 final? From buildbot at python.org Sun Apr 26 01:30:00 2009 From: buildbot at python.org (buildbot at python.org) Date: Sat, 25 Apr 2009 23:30:00 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090425233000.5D2401E4010@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/300 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Sun Apr 26 01:31:00 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sun, 26 Apr 2009 01:31:00 +0200 (CEST) Subject: [Python-checkins] r71945 - peps/trunk/pep-0378.txt Message-ID: <20090425233100.9BCE61E4010@bag.python.org> Author: raymond.hettinger Date: Sun Apr 26 01:31:00 2009 New Revision: 71945 Log: Mark 378 (thousands separator) as final. The implementation was checked-in by Mark Dickinson and Eric Smith. Modified: peps/trunk/pep-0378.txt Modified: peps/trunk/pep-0378.txt ============================================================================== --- peps/trunk/pep-0378.txt (original) +++ peps/trunk/pep-0378.txt Sun Apr 26 01:31:00 2009 @@ -3,7 +3,7 @@ Version: $Revision$ Last-Modified: $Date$ Author: Raymond Hettinger -Status: Accepted +Status: Final Type: Standards Track Content-Type: text/x-rst Created: 12-Mar-2009 From python-checkins at python.org Sun Apr 26 02:34:36 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sun, 26 Apr 2009 02:34:36 +0200 (CEST) Subject: [Python-checkins] r71946 - peps/trunk/pep-0315.txt Message-ID: <20090426003437.05F081E4022@bag.python.org> Author: raymond.hettinger Date: Sun Apr 26 02:34:36 2009 New Revision: 71946 Log: Revive PEP 315. Modified: peps/trunk/pep-0315.txt Modified: peps/trunk/pep-0315.txt ============================================================================== --- peps/trunk/pep-0315.txt (original) +++ peps/trunk/pep-0315.txt Sun Apr 26 02:34:36 2009 @@ -2,9 +2,9 @@ Title: Enhanced While Loop Version: $Revision$ Last-Modified: $Date$ -Author: W Isaac Carroll - Raymond Hettinger -Status: Deferred +Author: Raymond Hettinger + W Isaac Carroll +Status: Draft Type: Standards Track Content-Type: text/plain Created: 25-Apr-2003 From python-checkins at python.org Sun Apr 26 02:53:18 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sun, 26 Apr 2009 02:53:18 +0200 (CEST) Subject: [Python-checkins] r71947 - in python/trunk: Lib/test/test_unicodedata.py Misc/NEWS Objects/unicodectype.c Message-ID: <20090426005318.5DEC01E40A9@bag.python.org> Author: martin.v.loewis Date: Sun Apr 26 02:53:18 2009 New Revision: 71947 Log: Issue #4971: Fix titlecase for characters that are their own titlecase, but not their own uppercase. Modified: python/trunk/Lib/test/test_unicodedata.py python/trunk/Misc/NEWS python/trunk/Objects/unicodectype.c Modified: python/trunk/Lib/test/test_unicodedata.py ============================================================================== --- python/trunk/Lib/test/test_unicodedata.py (original) +++ python/trunk/Lib/test/test_unicodedata.py Sun Apr 26 02:53:18 2009 @@ -20,7 +20,7 @@ class UnicodeMethodsTest(unittest.TestCase): # update this, if the database changes - expectedchecksum = 'b7db9b5f1d804976fa921d2009cbef6f025620c1' + expectedchecksum = '6ec65b65835614ec00634c674bba0e50cd32c189' def test_method_checksum(self): h = hashlib.sha1() @@ -270,6 +270,11 @@ [0] ) + def test_buf_4971(self): + # LETTER DZ WITH CARON: DZ, Dz, dz + self.assertEqual(u"\u01c4".title(), u"\u01c5") + self.assertEqual(u"\u01c5".title(), u"\u01c5") + self.assertEqual(u"\u01c6".title(), u"\u01c5") def test_main(): test.test_support.run_unittest( Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Sun Apr 26 02:53:18 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #4971: Fix titlecase for characters that are their own + titlecase, but not their own uppercase. + - Issue #5835: Deprecate PyOS_ascii_formatd and replace it with _PyOS_double_to_string or PyOS_double_to_string. Modified: python/trunk/Objects/unicodectype.c ============================================================================== --- python/trunk/Objects/unicodectype.c (original) +++ python/trunk/Objects/unicodectype.c Sun Apr 26 02:53:18 2009 @@ -76,12 +76,7 @@ Py_UNICODE _PyUnicode_ToTitlecase(register Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); - int delta; - - if (ctype->title) - delta = ctype->title; - else - delta = ctype->upper; + int delta = ctype->title; if (ctype->flags & NODELTA_MASK) return delta; From python-checkins at python.org Sun Apr 26 03:01:58 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sun, 26 Apr 2009 03:01:58 +0200 (CEST) Subject: [Python-checkins] r71948 - in python/branches/release26-maint: Lib/test/test_unicodedata.py Misc/NEWS Objects/unicodectype.c Message-ID: <20090426010158.7A4C81E4018@bag.python.org> Author: martin.v.loewis Date: Sun Apr 26 03:01:58 2009 New Revision: 71948 Log: Merged revisions 71947 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71947 | martin.v.loewis | 2009-04-26 02:53:18 +0200 (So, 26 Apr 2009) | 3 lines Issue #4971: Fix titlecase for characters that are their own titlecase, but not their own uppercase. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_unicodedata.py python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Objects/unicodectype.c Modified: python/branches/release26-maint/Lib/test/test_unicodedata.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_unicodedata.py (original) +++ python/branches/release26-maint/Lib/test/test_unicodedata.py Sun Apr 26 03:01:58 2009 @@ -20,7 +20,7 @@ class UnicodeMethodsTest(unittest.TestCase): # update this, if the database changes - expectedchecksum = 'b7db9b5f1d804976fa921d2009cbef6f025620c1' + expectedchecksum = '6ec65b65835614ec00634c674bba0e50cd32c189' def test_method_checksum(self): h = hashlib.sha1() @@ -270,6 +270,11 @@ [0] ) + def test_buf_4971(self): + # LETTER DZ WITH CARON: DZ, Dz, dz + self.assertEqual(u"\u01c4".title(), u"\u01c5") + self.assertEqual(u"\u01c5".title(), u"\u01c5") + self.assertEqual(u"\u01c6".title(), u"\u01c5") def test_main(): test.test_support.run_unittest( Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Sun Apr 26 03:01:58 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #4971: Fix titlecase for characters that are their own + titlecase, but not their own uppercase. + - Issue #5829: complex('1e-500') no longer raises an exception - Issue #5787: object.__getattribute__(some_type, "__bases__") segfaulted on Modified: python/branches/release26-maint/Objects/unicodectype.c ============================================================================== --- python/branches/release26-maint/Objects/unicodectype.c (original) +++ python/branches/release26-maint/Objects/unicodectype.c Sun Apr 26 03:01:58 2009 @@ -76,12 +76,7 @@ Py_UNICODE _PyUnicode_ToTitlecase(register Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); - int delta; - - if (ctype->title) - delta = ctype->title; - else - delta = ctype->upper; + int delta = ctype->title; if (ctype->flags & NODELTA_MASK) return delta; From python-checkins at python.org Sun Apr 26 03:02:07 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sun, 26 Apr 2009 03:02:07 +0200 (CEST) Subject: [Python-checkins] r71949 - in python/branches/py3k: Lib/test/test_unicodedata.py Misc/NEWS Objects/unicodectype.c Message-ID: <20090426010207.D9C4E1E4018@bag.python.org> Author: martin.v.loewis Date: Sun Apr 26 03:02:07 2009 New Revision: 71949 Log: Merged revisions 71947 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71947 | martin.v.loewis | 2009-04-26 02:53:18 +0200 (So, 26 Apr 2009) | 3 lines Issue #4971: Fix titlecase for characters that are their own titlecase, but not their own uppercase. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_unicodedata.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/unicodectype.c Modified: python/branches/py3k/Lib/test/test_unicodedata.py ============================================================================== --- python/branches/py3k/Lib/test/test_unicodedata.py (original) +++ python/branches/py3k/Lib/test/test_unicodedata.py Sun Apr 26 03:02:07 2009 @@ -20,7 +20,7 @@ class UnicodeMethodsTest(unittest.TestCase): # update this, if the database changes - expectedchecksum = 'b7db9b5f1d804976fa921d2009cbef6f025620c1' + expectedchecksum = '6ec65b65835614ec00634c674bba0e50cd32c189' def test_method_checksum(self): h = hashlib.sha1() @@ -271,6 +271,11 @@ [0] ) + def test_buf_4971(self): + # LETTER DZ WITH CARON: DZ, Dz, dz + self.assertEqual("\u01c4".title(), "\u01c5") + self.assertEqual("\u01c5".title(), "\u01c5") + self.assertEqual("\u01c6".title(), "\u01c5") def test_main(): test.support.run_unittest( Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Apr 26 03:02:07 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #4971: Fix titlecase for characters that are their own + titlecase, but not their own uppercase. + - Issue #5283: Setting __class__ in __del__ caused a segfault. - Issue #5816: complex(repr(z)) now recovers z exactly, even when Modified: python/branches/py3k/Objects/unicodectype.c ============================================================================== --- python/branches/py3k/Objects/unicodectype.c (original) +++ python/branches/py3k/Objects/unicodectype.c Sun Apr 26 03:02:07 2009 @@ -79,12 +79,7 @@ Py_UNICODE _PyUnicode_ToTitlecase(register Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); - int delta; - - if (ctype->title) - delta = ctype->title; - else - delta = ctype->upper; + int delta = ctype->title; if (ctype->flags & NODELTA_MASK) return delta; From python-checkins at python.org Sun Apr 26 03:04:33 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sun, 26 Apr 2009 03:04:33 +0200 (CEST) Subject: [Python-checkins] r71950 - in python/branches/release30-maint: Lib/test/test_unicodedata.py Misc/NEWS Objects/unicodectype.c Message-ID: <20090426010433.D2C641E4018@bag.python.org> Author: martin.v.loewis Date: Sun Apr 26 03:04:33 2009 New Revision: 71950 Log: Merged revisions 71949 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71949 | martin.v.loewis | 2009-04-26 03:02:07 +0200 (So, 26 Apr 2009) | 10 lines Merged revisions 71947 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71947 | martin.v.loewis | 2009-04-26 02:53:18 +0200 (So, 26 Apr 2009) | 3 lines Issue #4971: Fix titlecase for characters that are their own titlecase, but not their own uppercase. ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Lib/test/test_unicodedata.py python/branches/release30-maint/Misc/NEWS python/branches/release30-maint/Objects/unicodectype.c Modified: python/branches/release30-maint/Lib/test/test_unicodedata.py ============================================================================== --- python/branches/release30-maint/Lib/test/test_unicodedata.py (original) +++ python/branches/release30-maint/Lib/test/test_unicodedata.py Sun Apr 26 03:04:33 2009 @@ -20,7 +20,7 @@ class UnicodeMethodsTest(unittest.TestCase): # update this, if the database changes - expectedchecksum = 'b7db9b5f1d804976fa921d2009cbef6f025620c1' + expectedchecksum = '6ec65b65835614ec00634c674bba0e50cd32c189' def test_method_checksum(self): h = hashlib.sha1() @@ -271,6 +271,11 @@ [0] ) + def test_buf_4971(self): + # LETTER DZ WITH CARON: DZ, Dz, dz + self.assertEqual("\u01c4".title(), "\u01c5") + self.assertEqual("\u01c5".title(), "\u01c5") + self.assertEqual("\u01c6".title(), "\u01c5") def test_main(): test.support.run_unittest( Modified: python/branches/release30-maint/Misc/NEWS ============================================================================== --- python/branches/release30-maint/Misc/NEWS (original) +++ python/branches/release30-maint/Misc/NEWS Sun Apr 26 03:04:33 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #4971: Fix titlecase for characters that are their own + titlecase, but not their own uppercase. + - Issue #5829: complex('1e-500') no longer raises an exception - Issue #5604: non-ASCII characters in module name passed to Modified: python/branches/release30-maint/Objects/unicodectype.c ============================================================================== --- python/branches/release30-maint/Objects/unicodectype.c (original) +++ python/branches/release30-maint/Objects/unicodectype.c Sun Apr 26 03:04:33 2009 @@ -79,12 +79,7 @@ Py_UNICODE _PyUnicode_ToTitlecase(register Py_UNICODE ch) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch); - int delta; - - if (ctype->title) - delta = ctype->title; - else - delta = ctype->upper; + int delta = ctype->title; if (ctype->flags & NODELTA_MASK) return delta; From python-checkins at python.org Sun Apr 26 03:33:55 2009 From: python-checkins at python.org (kurt.kaiser) Date: Sun, 26 Apr 2009 03:33:55 +0200 (CEST) Subject: [Python-checkins] r71952 - in python/branches/py3k: Lib/idlelib/CREDITS.txt Lib/idlelib/EditorWindow.py Lib/idlelib/NEWS.txt Message-ID: <20090426013355.4B7631E4013@bag.python.org> Author: kurt.kaiser Date: Sun Apr 26 03:33:55 2009 New Revision: 71952 Log: Merged revisions 71812 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71812 | kurt.kaiser | 2009-04-22 22:36:01 -0400 (Wed, 22 Apr 2009) | 2 lines Produce correct version string to access the .chm docs on Windows. Patch 5783 gpolo. Will port. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/idlelib/CREDITS.txt python/branches/py3k/Lib/idlelib/EditorWindow.py python/branches/py3k/Lib/idlelib/NEWS.txt Modified: python/branches/py3k/Lib/idlelib/CREDITS.txt ============================================================================== --- python/branches/py3k/Lib/idlelib/CREDITS.txt (original) +++ python/branches/py3k/Lib/idlelib/CREDITS.txt Sun Apr 26 03:33:55 2009 @@ -2,9 +2,9 @@ original creator of IDLE. Other contributors prior to Version 0.8 include Mark Hammond, Jeremy Hylton, Tim Peters, and Moshe Zadka. -IDLE's recent development has been carried out in the IDLEfork project. -The objective was to develop a version of IDLE which had an execution -environment which could be initialized prior to each run of user code. +IDLE's recent development was carried out in the SF IDLEfork project. The +objective was to develop a version of IDLE which had an execution environment +which could be initialized prior to each run of user code. The IDLEfork project was initiated by David Scherer, with some help from Peter Schneider-Kamp and Nicholas Riley. David wrote the first version of the RPC @@ -12,7 +12,7 @@ the RPC code and Remote Debugger currently integrated in IDLE. Bruce Sherwood contributed considerable time testing and suggesting improvements. -Besides David and Guido, the main developers who have been active on IDLEfork +Besides David and Guido, the main developers who were active on IDLEfork are Stephen M. Gava, who implemented the configuration GUI, the new configuration system, and the About dialog, and Kurt B. Kaiser, who completed the integration of the RPC and remote debugger, implemented the threaded @@ -24,8 +24,9 @@ integration, debugger integration and persistent breakpoints). Scott David Daniels, Tal Einat, Hernan Foffani, Christos Georgiou, -Jim Jewett, Martin v. L??wis, Jason Orendorff, Josh Robb, Nigel Rowe, -Bruce Sherwood, and Jeff Shute have submitted useful patches. Thanks, guys! +Jim Jewett, Martin v. L?wis, Jason Orendorff, Guilherme Polo, Josh Robb, +Nigel Rowe, Bruce Sherwood, Jeff Shute, and Weeble have submitted useful +patches. Thanks, guys! For additional details refer to NEWS.txt and Changelog. Modified: python/branches/py3k/Lib/idlelib/EditorWindow.py ============================================================================== --- python/branches/py3k/Lib/idlelib/EditorWindow.py (original) +++ python/branches/py3k/Lib/idlelib/EditorWindow.py Sun Apr 26 03:33:55 2009 @@ -24,6 +24,16 @@ # The default tab setting for a Text widget, in average-width characters. TK_TABWIDTH_DEFAULT = 8 +def _sphinx_version(): + "Format sys.version_info to produce the Sphinx version string used to install the chm docs" + major, minor, micro, level, serial = sys.version_info + release = '%s%s' % (major, minor) + if micro: + release += '%s' % micro + if level != 'final': + release += '%s%s' % (level[0], serial) + return release + def _find_module(fullname, path=None): """Version of imp.find_module() that handles hierarchical module names""" @@ -66,15 +76,13 @@ 'Doc', 'index.html') elif sys.platform[:3] == 'win': chmfile = os.path.join(sys.prefix, 'Doc', - 'Python%d%d.chm' % sys.version_info[:2]) + 'Python%s.chm' % _sphinx_version()) if os.path.isfile(chmfile): dochome = chmfile - elif macosxSupport.runningAsOSXApp(): # documentation is stored inside the python framework dochome = os.path.join(sys.prefix, 'Resources/English.lproj/Documentation/index.html') - dochome = os.path.normpath(dochome) if os.path.isfile(dochome): EditorWindow.help_url = dochome Modified: python/branches/py3k/Lib/idlelib/NEWS.txt ============================================================================== --- python/branches/py3k/Lib/idlelib/NEWS.txt (original) +++ python/branches/py3k/Lib/idlelib/NEWS.txt Sun Apr 26 03:33:55 2009 @@ -27,6 +27,9 @@ *Release date: XX-XXX-2009* +- Windows: Version string for the .chm help file changed, file not being + accessed Patch 5783 Guilherme Polo + - Allow multiple IDLE GUI/subprocess pairs to exist simultaneously. Thanks to David Scherer for suggesting the use of an ephemeral port for the GUI. Patch 1529142 Weeble. From python-checkins at python.org Sun Apr 26 04:05:55 2009 From: python-checkins at python.org (kurt.kaiser) Date: Sun, 26 Apr 2009 04:05:55 +0200 (CEST) Subject: [Python-checkins] r71953 - in python/branches/release30-maint: Lib/idlelib/CREDITS.txt Lib/idlelib/EditorWindow.py Lib/idlelib/NEWS.txt Message-ID: <20090426020555.5E3181E4020@bag.python.org> Author: kurt.kaiser Date: Sun Apr 26 04:05:55 2009 New Revision: 71953 Log: Merged revisions 71952 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71952 | kurt.kaiser | 2009-04-25 21:33:55 -0400 (Sat, 25 Apr 2009) | 10 lines Merged revisions 71812 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71812 | kurt.kaiser | 2009-04-22 22:36:01 -0400 (Wed, 22 Apr 2009) | 2 lines Produce correct version string to access the .chm docs on Windows. Patch 5783 gpolo. Will port. ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Lib/idlelib/CREDITS.txt python/branches/release30-maint/Lib/idlelib/EditorWindow.py python/branches/release30-maint/Lib/idlelib/NEWS.txt Modified: python/branches/release30-maint/Lib/idlelib/CREDITS.txt ============================================================================== --- python/branches/release30-maint/Lib/idlelib/CREDITS.txt (original) +++ python/branches/release30-maint/Lib/idlelib/CREDITS.txt Sun Apr 26 04:05:55 2009 @@ -2,9 +2,9 @@ original creator of IDLE. Other contributors prior to Version 0.8 include Mark Hammond, Jeremy Hylton, Tim Peters, and Moshe Zadka. -IDLE's recent development has been carried out in the IDLEfork project. -The objective was to develop a version of IDLE which had an execution -environment which could be initialized prior to each run of user code. +IDLE's recent development was carried out in the SF IDLEfork project. The +objective was to develop a version of IDLE which had an execution environment +which could be initialized prior to each run of user code. The IDLEfork project was initiated by David Scherer, with some help from Peter Schneider-Kamp and Nicholas Riley. David wrote the first version of the RPC @@ -12,7 +12,7 @@ the RPC code and Remote Debugger currently integrated in IDLE. Bruce Sherwood contributed considerable time testing and suggesting improvements. -Besides David and Guido, the main developers who have been active on IDLEfork +Besides David and Guido, the main developers who were active on IDLEfork are Stephen M. Gava, who implemented the configuration GUI, the new configuration system, and the About dialog, and Kurt B. Kaiser, who completed the integration of the RPC and remote debugger, implemented the threaded @@ -24,8 +24,9 @@ integration, debugger integration and persistent breakpoints). Scott David Daniels, Tal Einat, Hernan Foffani, Christos Georgiou, -Jim Jewett, Martin v. L??wis, Jason Orendorff, Josh Robb, Nigel Rowe, -Bruce Sherwood, and Jeff Shute have submitted useful patches. Thanks, guys! +Jim Jewett, Martin v. L?wis, Jason Orendorff, Guilherme Polo, Josh Robb, +Nigel Rowe, Bruce Sherwood, and Jeff Shute have submitted useful patches. +Thanks, guys! For additional details refer to NEWS.txt and Changelog. Modified: python/branches/release30-maint/Lib/idlelib/EditorWindow.py ============================================================================== --- python/branches/release30-maint/Lib/idlelib/EditorWindow.py (original) +++ python/branches/release30-maint/Lib/idlelib/EditorWindow.py Sun Apr 26 04:05:55 2009 @@ -24,6 +24,16 @@ # The default tab setting for a Text widget, in average-width characters. TK_TABWIDTH_DEFAULT = 8 +def _sphinx_version(): + "Format sys.version_info to produce the Sphinx version string used to install the chm docs" + major, minor, micro, level, serial = sys.version_info + release = '%s%s' % (major, minor) + if micro: + release += '%s' % micro + if level != 'final': + release += '%s%s' % (level[0], serial) + return release + def _find_module(fullname, path=None): """Version of imp.find_module() that handles hierarchical module names""" @@ -66,15 +76,13 @@ 'Doc', 'index.html') elif sys.platform[:3] == 'win': chmfile = os.path.join(sys.prefix, 'Doc', - 'Python%d%d.chm' % sys.version_info[:2]) + 'Python%s.chm' % _sphinx_version()) if os.path.isfile(chmfile): dochome = chmfile - elif macosxSupport.runningAsOSXApp(): # documentation is stored inside the python framework dochome = os.path.join(sys.prefix, 'Resources/English.lproj/Documentation/index.html') - dochome = os.path.normpath(dochome) if os.path.isfile(dochome): EditorWindow.help_url = dochome Modified: python/branches/release30-maint/Lib/idlelib/NEWS.txt ============================================================================== --- python/branches/release30-maint/Lib/idlelib/NEWS.txt (original) +++ python/branches/release30-maint/Lib/idlelib/NEWS.txt Sun Apr 26 04:05:55 2009 @@ -13,11 +13,14 @@ user configuration of source encoding; all according to PEP 3120. -What's New in IDLE 2.7? (UNRELEASED, but merged into 3.0 releases above.) +What's New in IDLE 2.7? (UNRELEASED, but merged into 3.0.x releases above.) ======================= *Release date: XX-XXX-2009* +- Windows: Version string for the .chm help file changed, file not being + accessed Patch 5783 Guilherme Polo + - Tk 8.5 Text widget requires 'wordprocessor' tabstyle attr to handle mixed space/tab properly. Issue 5120, patch by Guilherme Polo. From buildbot at python.org Sun Apr 26 04:33:20 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 26 Apr 2009 02:33:20 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 2.6 Message-ID: <20090426023320.8749C1E4020@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%202.6/builds/279 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: eric.smith BUILD FAILED: failed test Excerpt from the test logfile: Traceback (most recent call last): File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/SocketServer.py", line 281, in _handle_request_noblock self.process_request(request, client_address) File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/SocketServer.py", line 307, in process_request self.finish_request(request, client_address) File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/SocketServer.py", line 320, in finish_request self.RequestHandlerClass(request, client_address, self) File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/SocketServer.py", line 615, in __init__ self.handle() File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/BaseHTTPServer.py", line 329, in handle self.handle_one_request() File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/BaseHTTPServer.py", line 312, in handle_one_request self.raw_requestline = self.rfile.readline() File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/socket.py", line 404, in readline data = self._sock.recv(self._rbufsize) error: [Errno 9] Bad file descriptor Traceback (most recent call last): File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/threading.py", line 525, in __bootstrap_inner self.run() File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/threading.py", line 477, in run self.__target(*self.__args, **self.__kwargs) File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/bsddb/test/test_thread.py", line 306, in readerThread rec = dbutils.DeadlockWrap(c.next, max_retries=10) File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/bsddb/dbutils.py", line 68, in DeadlockWrap return function(*_args, **_kwargs) DBLockDeadlockError: (-30994, 'DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock') Traceback (most recent call last): File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/threading.py", line 525, in __bootstrap_inner self.run() File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/threading.py", line 477, in run self.__target(*self.__args, **self.__kwargs) File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/bsddb/test/test_thread.py", line 306, in readerThread rec = dbutils.DeadlockWrap(c.next, max_retries=10) File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/bsddb/dbutils.py", line 68, in DeadlockWrap return function(*_args, **_kwargs) DBLockDeadlockError: (-30994, 'DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock') 1 test failed: test_urllib2_localnet make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sun Apr 26 05:34:07 2009 From: python-checkins at python.org (hirokazu.yamamoto) Date: Sun, 26 Apr 2009 05:34:07 +0200 (CEST) Subject: [Python-checkins] r71954 - in python/branches/py3k/Doc: library/json.rst reference/datamodel.rst Message-ID: <20090426033407.2C3201E402D@bag.python.org> Author: hirokazu.yamamoto Date: Sun Apr 26 05:34:06 2009 New Revision: 71954 Log: Fixed documentation build warning. Modified: python/branches/py3k/Doc/library/json.rst python/branches/py3k/Doc/reference/datamodel.rst Modified: python/branches/py3k/Doc/library/json.rst ============================================================================== --- python/branches/py3k/Doc/library/json.rst (original) +++ python/branches/py3k/Doc/library/json.rst Sun Apr 26 05:34:06 2009 @@ -190,7 +190,7 @@ *object_hook* is also defined, the *object_pairs_hook* takes priority. .. versionchanged:: 3.1 - Added support for *object_pairs_hook*. + Added support for *object_pairs_hook*. *parse_float*, if specified, will be called with the string of every JSON float to be decoded. By default, this is equivalent to ``float(num_str)``. @@ -278,7 +278,7 @@ *object_hook* is also defined, the *object_pairs_hook* takes priority. .. versionchanged:: 3.1 - Added support for *object_pairs_hook*. + Added support for *object_pairs_hook*. *parse_float*, if specified, will be called with the string of every JSON float to be decoded. By default, this is equivalent to ``float(num_str)``. Modified: python/branches/py3k/Doc/reference/datamodel.rst ============================================================================== --- python/branches/py3k/Doc/reference/datamodel.rst (original) +++ python/branches/py3k/Doc/reference/datamodel.rst Sun Apr 26 05:34:06 2009 @@ -1569,7 +1569,7 @@ :class:`collections.OrderedDict`. That mapping records the methods and attributes of *A* as they are defined within the body of the class statement. Once those definitions are executed, the ordered dictionary is fully populated -and the metaclass's :meth:`__new__ ` method gets invoked. That method builds +and the metaclass's :meth:`__new__` method gets invoked. That method builds the new type and it saves the ordered dictionary keys in an attribute called *members*. From python-checkins at python.org Sun Apr 26 08:01:07 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 26 Apr 2009 08:01:07 +0200 (CEST) Subject: [Python-checkins] r71955 - python/trunk/Doc/c-api/conversion.rst Message-ID: <20090426060107.7D9541E4022@bag.python.org> Author: georg.brandl Date: Sun Apr 26 08:01:04 2009 New Revision: 71955 Log: Mostly formatting nits, and "and-ed together" -> "or-ed together" flags. Modified: python/trunk/Doc/c-api/conversion.rst Modified: python/trunk/Doc/c-api/conversion.rst ============================================================================== --- python/trunk/Doc/c-api/conversion.rst (original) +++ python/trunk/Doc/c-api/conversion.rst Sun Apr 26 08:01:04 2009 @@ -65,7 +65,7 @@ See the Unix man page :manpage:`strtod(2)` for details. -.. cfunction:: char * PyOS_ascii_formatd(char *buffer, size_t buf_len, const char *format, double d) +.. cfunction:: char* PyOS_ascii_formatd(char *buffer, size_t buf_len, const char *format, double d) Convert a :ctype:`double` to a string using the ``'.'`` as the decimal separator. *format* is a :cfunc:`printf`\ -style format string specifying the @@ -80,39 +80,40 @@ This function is removed in Python 2.7 and 3.1. Use :func:`PyOS_double_to_string` instead. -.. cfunction:: char * PyOS_double_to_string(double val, char format_code, int precision, int flags, int *ptype) + +.. cfunction:: char* PyOS_double_to_string(double val, char format_code, int precision, int flags, int *ptype) Convert a :ctype:`double` *val* to a string using supplied *format_code*, *precision*, and *flags*. - *format_code* must be one of ``'e'``, ``'E'``, ``'f'``, ``'F'``, - ``'g'``, ``'G'``, ``'s'``, or ``'r'``. For ``'s'`` and ``'r'``, the - supplied *precision* must be 0 and is ignored. These specify the - standards :func:`str` and :func:`repr` formats, respectively. + *format_code* must be one of ``'e'``, ``'E'``, ``'f'``, ``'F'``, ``'g'``, + ``'G'``, ``'s'``, or ``'r'``. For ``'s'`` and ``'r'``, the supplied + *precision* must be 0 and is ignored. These specify the standard + :func:`str` and :func:`repr` formats, respectively. *flags* can be zero or more of the values *Py_DTSF_SIGN*, - *Py_DTSF_ADD_DOT_0*, or *Py_DTSF_ALT*, and-ed together. + *Py_DTSF_ADD_DOT_0*, or *Py_DTSF_ALT*, or-ed together: - *Py_DTSF_SIGN* means always precede the returned string with a - sign character, even if *val* is non-negative. + * *Py_DTSF_SIGN* means to always precede the returned string with a sign + character, even if *val* is non-negative. - *Py_DTSF_ADD_DOT_0* means ensure that the returned string will - not look like an integer. + * *Py_DTSF_ADD_DOT_0* means to ensure that the returned string will not look + like an integer. - *Py_DTSF_ALT* means apply "alternate" formatting rules. See the - documentation for the :func:`PyOS_snprintf` ``'#'`` specifier - for details. - - If *ptype* is non-NULL, then the value it points to will be set to - one of *Py_DTST_FINITE*, *Py_DTST_INFINITE*, or *Py_DTST_NAN*, - signifying that *val* is a finite number, an infinite number, or - not a number, respectively. + * *Py_DTSF_ALT* means to apply "alternate" formatting rules. See the + documentation for the :cfunc:`PyOS_snprintf` ``'#'`` specifier for + details. - The return value is a pointer to *buffer* with the converted string or NULL if - the conversion failed. + If *ptype* is non-NULL, then the value it points to will be set to one of + *Py_DTST_FINITE*, *Py_DTST_INFINITE*, or *Py_DTST_NAN*, signifying that + *val* is a finite number, an infinite number, or not a number, respectively. + + The return value is a pointer to *buffer* with the converted string or + *NULL* if the conversion failed. .. versionadded:: 2.7 + .. cfunction:: double PyOS_ascii_atof(const char *nptr) Convert a string to a :ctype:`double` in a locale-independent way. @@ -122,7 +123,7 @@ See the Unix man page :manpage:`atof(2)` for details. -.. cfunction:: char * PyOS_stricmp(char *s1, char *s2) +.. cfunction:: char* PyOS_stricmp(char *s1, char *s2) Case insensitive comparison of strings. The function works almost identically to :cfunc:`strcmp` except that it ignores the case. @@ -130,7 +131,7 @@ .. versionadded:: 2.6 -.. cfunction:: char * PyOS_strnicmp(char *s1, char *s2, Py_ssize_t size) +.. cfunction:: char* PyOS_strnicmp(char *s1, char *s2, Py_ssize_t size) Case insensitive comparison of strings. The function works almost identically to :cfunc:`strncmp` except that it ignores the case. From python-checkins at python.org Sun Apr 26 08:05:19 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 26 Apr 2009 08:05:19 +0200 (CEST) Subject: [Python-checkins] r71956 - python/trunk/Doc/README.txt Message-ID: <20090426060519.225581E4022@bag.python.org> Author: georg.brandl Date: Sun Apr 26 08:05:18 2009 New Revision: 71956 Log: Update versions in instructions for manual set-up. Modified: python/trunk/Doc/README.txt Modified: python/trunk/Doc/README.txt ============================================================================== --- python/trunk/Doc/README.txt (original) +++ python/trunk/Doc/README.txt Sun Apr 26 08:05:18 2009 @@ -74,17 +74,23 @@ You'll need to checkout the Sphinx package to the `tools/` directory:: - svn co http://svn.python.org/projects/doctools/trunk/sphinx tools/sphinx + svn co http://svn.python.org/projects/external/Sphinx-0.6.1/sphinx tools/sphinx Then, you need to install Docutils, either by checking it out via :: - svn co http://svn.python.org/projects/external/docutils-0.4/docutils tools/docutils + svn co http://svn.python.org/projects/external/docutils-0.5/docutils tools/docutils or by installing it from http://docutils.sf.net/. +You also need Jinja2, either by checking it out via :: + + svn co http://svn.python.org/projects/external/Jinja-2.1.1/jinja2 tools/jinja2 + +or by installing it from PyPI. + You can optionally also install Pygments, either as a checkout via :: - svn co http://svn.python.org/projects/external/Pygments-0.9/pygments tools/pygments + svn co http://svn.python.org/projects/external/Pygments-0.11.1/pygments tools/pygments or from PyPI at http://pypi.python.org/pypi/Pygments. From python-checkins at python.org Sun Apr 26 08:05:58 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 26 Apr 2009 08:05:58 +0200 (CEST) Subject: [Python-checkins] r71957 - python/trunk/Doc/Makefile Message-ID: <20090426060558.B09011E4022@bag.python.org> Author: georg.brandl Date: Sun Apr 26 08:05:58 2009 New Revision: 71957 Log: Note that the versions are also in README.txt. Modified: python/trunk/Doc/Makefile Modified: python/trunk/Doc/Makefile ============================================================================== --- python/trunk/Doc/Makefile (original) +++ python/trunk/Doc/Makefile Sun Apr 26 08:05:58 2009 @@ -29,6 +29,7 @@ @echo " dist to create a \"dist\" directory with archived docs for download" checkout: + # Note: if you update versions here, do the same in README.txt @if [ ! -d tools/sphinx ]; then \ echo "Checking out Sphinx..."; \ svn checkout $(SVNROOT)/external/Sphinx-0.6.1/sphinx tools/sphinx; \ From python-checkins at python.org Sun Apr 26 08:06:19 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 26 Apr 2009 08:06:19 +0200 (CEST) Subject: [Python-checkins] r71958 - python/trunk/Doc/TODO.txt Message-ID: <20090426060619.C784A1E4020@bag.python.org> Author: georg.brandl Date: Sun Apr 26 08:06:19 2009 New Revision: 71958 Log: Remove outdated TODO file. Removed: python/trunk/Doc/TODO.txt Deleted: python/trunk/Doc/TODO.txt ============================================================================== --- python/trunk/Doc/TODO.txt Sun Apr 26 08:06:19 2009 +++ (empty file) @@ -1,6 +0,0 @@ -To do -===== - -* split very large files and add toctrees -* finish "Documenting Python" -* care about XXX comments From python-checkins at python.org Sun Apr 26 08:06:53 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 26 Apr 2009 08:06:53 +0200 (CEST) Subject: [Python-checkins] r71959 - python/trunk/Doc/Makefile Message-ID: <20090426060653.3A61C1E4020@bag.python.org> Author: georg.brandl Date: Sun Apr 26 08:06:53 2009 New Revision: 71959 Log: Another file where the versions need to be up to date. Modified: python/trunk/Doc/Makefile Modified: python/trunk/Doc/Makefile ============================================================================== --- python/trunk/Doc/Makefile (original) +++ python/trunk/Doc/Makefile Sun Apr 26 08:06:53 2009 @@ -29,7 +29,7 @@ @echo " dist to create a \"dist\" directory with archived docs for download" checkout: - # Note: if you update versions here, do the same in README.txt + # Note: if you update versions here, do the same in make.bat and README.txt @if [ ! -d tools/sphinx ]; then \ echo "Checking out Sphinx..."; \ svn checkout $(SVNROOT)/external/Sphinx-0.6.1/sphinx tools/sphinx; \ From buildbot at python.org Sun Apr 26 08:25:32 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 26 Apr 2009 06:25:32 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090426062532.BE13F1E4022@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/302 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: kurt.kaiser,martin.v.loewis BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_posix test_subprocess ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From nnorwitz at gmail.com Sun Apr 26 11:25:18 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 26 Apr 2009 05:25:18 -0400 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20090426092518.GA23849@python.psfb.org> More important issues: ---------------------- test_ssl leaked [403, -403, 403] references, sum=403 Less important issues: ---------------------- test_cmd_line leaked [-25, 0, 25] references, sum=0 test_smtplib leaked [4, -5, 0] references, sum=-1 test_sys leaked [-42, 42, -42] references, sum=-42 test_threading leaked [48, 48, 48] references, sum=144 test_urllib2_localnet leaked [3, 279, -4] references, sum=278 From python-checkins at python.org Sun Apr 26 11:56:45 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 26 Apr 2009 11:56:45 +0200 (CEST) Subject: [Python-checkins] r71960 - in python/trunk: Doc/Makefile Doc/tools/sphinxext/pyspecific.py Lib/pydoc.py Lib/pydoc_data Lib/pydoc_data/__init__.py Lib/pydoc_data/topics.py Lib/pydoc_topics.py Message-ID: <20090426095645.8002F1E4012@bag.python.org> Author: georg.brandl Date: Sun Apr 26 11:56:44 2009 New Revision: 71960 Log: Move pydoc_topics module to its own subdirectory, so that no generated code is in Lib/. Added: python/trunk/Lib/pydoc_data/ python/trunk/Lib/pydoc_data/__init__.py (contents, props changed) python/trunk/Lib/pydoc_data/topics.py - copied unchanged from r71954, /python/trunk/Lib/pydoc_topics.py Removed: python/trunk/Lib/pydoc_topics.py Modified: python/trunk/Doc/Makefile python/trunk/Doc/tools/sphinxext/pyspecific.py python/trunk/Lib/pydoc.py Modified: python/trunk/Doc/Makefile ============================================================================== --- python/trunk/Doc/Makefile (original) +++ python/trunk/Doc/Makefile Sun Apr 26 11:56:44 2009 @@ -28,8 +28,8 @@ @echo " coverage to check documentation coverage for library and C API" @echo " dist to create a \"dist\" directory with archived docs for download" +# Note: if you update versions here, do the same in make.bat and README.txt checkout: - # Note: if you update versions here, do the same in make.bat and README.txt @if [ ! -d tools/sphinx ]; then \ echo "Checking out Sphinx..."; \ svn checkout $(SVNROOT)/external/Sphinx-0.6.1/sphinx tools/sphinx; \ @@ -102,8 +102,8 @@ pydoc-topics: BUILDER = pydoc-topics pydoc-topics: build - @echo "Building finished; now copy build/pydoc-topics/pydoc_topics.py " \ - "into the Lib/ directory" + @echo "Building finished; now copy build/pydoc-topics/topics.py " \ + "to Lib/pydoc_data/topics.py" htmlview: html $(PYTHON) -c "import webbrowser; webbrowser.open('build/html/index.html')" @@ -133,7 +133,7 @@ (cd dist; zip -q -r -9 python-$(DISTVERSION)-docs-text.zip python-$(DISTVERSION)-docs-text) rm -r dist/python-$(DISTVERSION)-docs-text rm dist/python-$(DISTVERSION)-docs-text.tar - + # archive the A4 latex -rm -r build/latex make latex PAPER=a4 Modified: python/trunk/Doc/tools/sphinxext/pyspecific.py ============================================================================== --- python/trunk/Doc/tools/sphinxext/pyspecific.py (original) +++ python/trunk/Doc/tools/sphinxext/pyspecific.py Sun Apr 26 11:56:44 2009 @@ -5,7 +5,7 @@ Sphinx extension with Python doc-specific markup. - :copyright: 2008 by Georg Brandl. + :copyright: 2008, 2009 by Georg Brandl. :license: Python license. """ @@ -89,7 +89,7 @@ self.topics[label] = writer.output def finish(self): - f = open(path.join(self.outdir, 'pydoc_topics.py'), 'w') + f = open(path.join(self.outdir, 'topics.py'), 'w') try: f.write('# Autogenerated by Sphinx on %s\n' % asctime()) f.write('topics = ' + pformat(self.topics) + '\n') Modified: python/trunk/Lib/pydoc.py ============================================================================== --- python/trunk/Lib/pydoc.py (original) +++ python/trunk/Lib/pydoc.py Sun Apr 26 11:56:44 2009 @@ -1533,11 +1533,11 @@ # These dictionaries map a topic name to either an alias, or a tuple # (label, seealso-items). The "label" is the label of the corresponding # section in the .rst file under Doc/ and an index into the dictionary - # in pydoc_topics.py. + # in pydoc_data/topics.py. # # CAUTION: if you change one of these dictionaries, be sure to adapt the # list of needed labels in Doc/tools/sphinxext/pyspecific.py and - # regenerate the pydoc_topics.py file by running + # regenerate the pydoc_data/topics.py file by running # make pydoc-topics # in Doc/ and copying the output file into the Lib/ directory. @@ -1821,11 +1821,11 @@ def showtopic(self, topic, more_xrefs=''): try: - import pydoc_topics + import pydoc_data.topics except ImportError: self.output.write(''' Sorry, topic and keyword documentation is not available because the -module "pydoc_topics" could not be found. +module "pydoc_data.topics" could not be found. ''') return target = self.topics.get(topic, self.keywords.get(topic)) @@ -1837,7 +1837,7 @@ label, xrefs = target try: - doc = pydoc_topics.topics[label] + doc = pydoc_data.topics.topics[label] except KeyError: self.output.write('no documentation found for %s\n' % repr(topic)) return Added: python/trunk/Lib/pydoc_data/__init__.py ============================================================================== Deleted: python/trunk/Lib/pydoc_topics.py ============================================================================== --- python/trunk/Lib/pydoc_topics.py Sun Apr 26 11:56:44 2009 +++ (empty file) @@ -1,83 +0,0 @@ -# Autogenerated by Sphinx on Thu Oct 2 15:45:36 2008 -topics = {'assert': u'\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': u'\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\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 is recursively defined as\nfollows.\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 a sequence 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\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`` statement in the\n current code block: the name is bound to the object in the current\n local namespace.\n\n * Otherwise: the name is bound to the object in the current global\n namespace.\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 a sequence 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* 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 a plain integer. If it is negative, the\n sequence\'s length is added to it. The resulting value must be a\n nonnegative integer less than the sequence\'s length, and the\n sequence is asked to assign the assigned object to its item with\n that index. If the index is out of range, ``IndexError`` is raised\n (assignment to a subscripted sequence cannot add new items to a\n 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* 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 (small) integers. If either\n bound is negative, the sequence\'s length is added to it. The\n resulting bounds are clipped to lie between zero and the sequence\'s\n length, inclusive. Finally, the sequence object is asked to replace\n the slice with the items of the assigned sequence. The length of\n the 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(In the current implementation, the syntax for targets is taken to be\nthe same as for expressions, and invalid syntax is rejected during the\ncode generation phase, causing less 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\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 ::= target augop (expression_list | yield_expression)\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 initial value is\nretrieved with a ``getattr()`` and the result is assigned with a\n``setattr()``. Notice that the two methods do not necessarily refer\nto the same variable. When ``getattr()`` refers to a class variable,\n``setattr()`` still writes to an instance variable. For example:\n\n class A:\n x = 3 # class variable\n a = A()\n a.x += 1 # writes a.x as 4 leaving A.x as 3\n', - 'atom-identifiers': u'\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', - 'atom-literals': u"\nLiterals\n********\n\nPython supports string literals and various numeric literals:\n\n literal ::= stringliteral | integer | longinteger\n | floatnumber | imagnumber\n\nEvaluation of a literal yields an object of the given type (string,\ninteger, long integer, floating point number, complex number) with the\ngiven value. The value may be approximated in the case of floating\npoint and imaginary (complex) literals. See section *Literals* for\ndetails.\n\nAll literals correspond to immutable data types, and hence the\nobject's identity is less important than its value. Multiple\nevaluations of literals with the same value (either the same\noccurrence in the program text or a different occurrence) may obtain\nthe same object or a different object with the same value.\n", - 'attribute-access': u'\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 in new-style classes.\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 not simply execute ``self.name = value`` --- this would\n cause a recursive call to itself. Instead, it should insert the\n value in the dictionary of instance attributes, e.g.,\n ``self.__dict__[name] = value``. For new-style classes, rather\n than accessing the instance dictionary, it should call the base\n 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\n\nMore attribute access for new-style classes\n===========================================\n\nThe following methods only apply to new-style classes.\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 builtin functions. See *Special method lookup for new-style\n classes*.\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 new-style class, known as the *owner*\nclass. In the examples below, "the attribute" refers to the attribute\nwhose name is the key of the property in the owner class\'\n``__dict__``. Descriptors can only be implemented as new-style\nclasses themselves.\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. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass ``object()`` or\n``type()``).\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 a new-style object instance, ``a.x`` is transformed\n into the call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a new-style class, ``A.x`` is transformed into the\n call: ``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. Normally, data\ndescriptors define both ``__get__()`` and ``__set__()``, while non-\ndata descriptors have just the ``__get__()`` method. Data descriptors\nalways override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances. [2]\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 both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__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 new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n New in version 2.2.\n\nNotes on using *__slots__*\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 Changed in version 2.3: Previously, adding ``\'__dict__\'`` to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\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 Changed in version 2.3: Previously, adding ``\'__weakref__\'`` to the\n *__slots__* declaration would not enable support for weak\n references.\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* 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* 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__*.\n\n* *__slots__* do not work for classes derived from "variable-length"\n built-in types such as ``long``, ``str`` and ``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 Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n', - 'attribute-references': u'\nAttribute references\n********************\n\nAn attribute reference is a primary followed by a period and a name:\n\n attributeref ::= primary "." identifier\n\nThe primary must evaluate to an object of a type that supports\nattribute references, e.g., a module, list, or an instance. This\nobject is then asked to produce the attribute whose name is the\nidentifier. If this attribute is not available, the exception\n``AttributeError`` is raised. Otherwise, the type and value of the\nobject produced is determined by the object. Multiple evaluations of\nthe same attribute reference may yield different objects.\n', - 'augassign': u'\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 ::= target augop (expression_list | yield_expression)\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 initial value is\nretrieved with a ``getattr()`` and the result is assigned with a\n``setattr()``. Notice that the two methods do not necessarily refer\nto the same variable. When ``getattr()`` refers to a class variable,\n``setattr()`` still writes to an instance variable. For example:\n\n class A:\n x = 3 # class variable\n a = A()\n a.x += 1 # writes a.x as 4 leaving A.x as 3\n', - 'binary': u'\nBinary arithmetic operations\n****************************\n\nThe binary arithmetic operations have the conventional priority\nlevels. Note that some of these operations also apply to certain non-\nnumeric types. Apart from the power operator, there are only two\nlevels, one for multiplicative operators and one for additive\noperators:\n\n m_expr ::= u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr\n | m_expr "%" u_expr\n a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr\n\nThe ``*`` (multiplication) operator yields the product of its\narguments. The arguments must either both be numbers, or one argument\nmust be an integer (plain or long) and the other must be a sequence.\nIn the former case, the numbers are converted to a common type and\nthen multiplied together. In the latter case, sequence repetition is\nperformed; a negative repetition factor yields an empty sequence.\n\nThe ``/`` (division) and ``//`` (floor division) operators yield the\nquotient of their arguments. The numeric arguments are first\nconverted to a common type. Plain or long integer division yields an\ninteger of the same type; the result is that of mathematical division\nwith the \'floor\' function applied to the result. Division by zero\nraises the ``ZeroDivisionError`` exception.\n\nThe ``%`` (modulo) operator yields the remainder from the division of\nthe first argument by the second. The numeric arguments are first\nconverted to a common type. A zero right argument raises the\n``ZeroDivisionError`` exception. The arguments may be floating point\nnumbers, e.g., ``3.14%0.7`` equals ``0.34`` (since ``3.14`` equals\n``4*0.7 + 0.34``.) The modulo operator always yields a result with\nthe same sign as its second operand (or zero); the absolute value of\nthe result is strictly smaller than the absolute value of the second\noperand [2].\n\nThe integer division and modulo operators are connected by the\nfollowing identity: ``x == (x/y)*y + (x%y)``. Integer division and\nmodulo are also connected with the built-in function ``divmod()``:\n``divmod(x, y) == (x/y, x%y)``. These identities don\'t hold for\nfloating point numbers; there similar identities hold approximately\nwhere ``x/y`` is replaced by ``floor(x/y)`` or ``floor(x/y) - 1`` [3].\n\nIn addition to performing the modulo operation on numbers, the ``%``\noperator is also overloaded by string and unicode objects to perform\nstring formatting (also known as interpolation). The syntax for string\nformatting is described in the Python Library Reference, section\n*String Formatting Operations*.\n\nDeprecated since version 2.3: The floor division operator, the modulo\noperator, and the ``divmod()`` function are no longer defined for\ncomplex numbers. Instead, convert to a floating point number using\nthe ``abs()`` function if appropriate.\n\nThe ``+`` (addition) operator yields the sum of its arguments. The\narguments must either both be numbers or both sequences of the same\ntype. In the former case, the numbers are converted to a common type\nand then added together. In the latter case, the sequences are\nconcatenated.\n\nThe ``-`` (subtraction) operator yields the difference of its\narguments. The numeric arguments are first converted to a common\ntype.\n', - 'bitwise': u'\nBinary bitwise operations\n*************************\n\nEach of the three bitwise operations has a different priority level:\n\n and_expr ::= shift_expr | and_expr "&" shift_expr\n xor_expr ::= and_expr | xor_expr "^" and_expr\n or_expr ::= xor_expr | or_expr "|" xor_expr\n\nThe ``&`` operator yields the bitwise AND of its arguments, which must\nbe plain or long integers. The arguments are converted to a common\ntype.\n\nThe ``^`` operator yields the bitwise XOR (exclusive OR) of its\narguments, which must be plain or long integers. The arguments are\nconverted to a common type.\n\nThe ``|`` operator yields the bitwise (inclusive) OR of its arguments,\nwhich must be plain or long integers. The arguments are converted to\na common type.\n', - 'bltin-code-objects': u'\nCode Objects\n************\n\nCode objects are used by the implementation to represent "pseudo-\ncompiled" executable Python code such as a function body. They differ\nfrom function objects because they don\'t contain a reference to their\nglobal execution environment. Code objects are returned by the built-\nin ``compile()`` function and can be extracted from function objects\nthrough their ``func_code`` attribute. See also the ``code`` module.\n\nA code object can be executed or evaluated by passing it (instead of a\nsource string) to the ``exec`` statement or the built-in ``eval()``\nfunction.\n\nSee *The standard type hierarchy* for more information.\n', - 'bltin-ellipsis-object': u'\nThe Ellipsis Object\n*******************\n\nThis object is used by extended slice notation (see *Slicings*). It\nsupports no special operations. There is exactly one ellipsis object,\nnamed ``Ellipsis`` (a built-in name).\n\nIt is written as ``Ellipsis``.\n', - 'bltin-file-objects': u'\nFile Objects\n************\n\nFile objects are implemented using C\'s ``stdio`` package and can be\ncreated with the built-in ``open()`` function. File objects are also\nreturned by some other built-in functions and methods, such as\n``os.popen()`` and ``os.fdopen()`` and the ``makefile()`` method of\nsocket objects. Temporary files can be created using the ``tempfile``\nmodule, and high-level file operations such as copying, moving, and\ndeleting files and directories can be achieved with the ``shutil``\nmodule.\n\nWhen a file operation fails for an I/O-related reason, the exception\n``IOError`` is raised. This includes situations where the operation\nis not defined for some reason, like ``seek()`` on a tty device or\nwriting a file opened for reading.\n\nFiles have the following methods:\n\nfile.close()\n\n Close the file. A closed file cannot be read or written any more.\n Any operation which requires that the file be open will raise a\n ``ValueError`` after the file has been closed. Calling ``close()``\n more than once is allowed.\n\n As of Python 2.5, you can avoid having to call this method\n explicitly if you use the ``with`` statement. For example, the\n following code will automatically close *f* when the ``with`` block\n is exited:\n\n from __future__ import with_statement # This isn\'t required in Python 2.6\n\n with open("hello.txt") as f:\n for line in f:\n print line\n\n In older versions of Python, you would have needed to do this to\n get the same effect:\n\n f = open("hello.txt")\n try:\n for line in f:\n print line\n finally:\n f.close()\n\n Note: Not all "file-like" types in Python support use as a context\n manager for the ``with`` statement. If your code is intended to\n work with any file-like object, you can use the function\n ``contextlib.closing()`` instead of using the object directly.\n\nfile.flush()\n\n Flush the internal buffer, like ``stdio``\'s ``fflush``. This may\n be a no-op on some file-like objects.\n\nfile.fileno()\n\n Return the integer "file descriptor" that is used by the underlying\n implementation to request I/O operations from the operating system.\n This can be useful for other, lower level interfaces that use file\n descriptors, such as the ``fcntl`` module or ``os.read()`` and\n friends.\n\n Note: File-like objects which do not have a real file descriptor should\n *not* provide this method!\n\nfile.isatty()\n\n Return ``True`` if the file is connected to a tty(-like) device,\n else ``False``.\n\n Note: If a file-like object is not associated with a real file, this\n method should *not* be implemented.\n\nfile.next()\n\n A file object is its own iterator, for example ``iter(f)`` returns\n *f* (unless *f* is closed). When a file is used as an iterator,\n typically in a ``for`` loop (for example, ``for line in f: print\n line``), the ``next()`` method is called repeatedly. This method\n returns the next input line, or raises ``StopIteration`` when EOF\n is hit when the file is open for reading (behavior is undefined\n when the file is open for writing). In order to make a ``for``\n loop the most efficient way of looping over the lines of a file (a\n very common operation), the ``next()`` method uses a hidden read-\n ahead buffer. As a consequence of using a read-ahead buffer,\n combining ``next()`` with other file methods (like ``readline()``)\n does not work right. However, using ``seek()`` to reposition the\n file to an absolute position will flush the read-ahead buffer.\n\n New in version 2.3.\n\nfile.read([size])\n\n Read at most *size* bytes from the file (less if the read hits EOF\n before obtaining *size* bytes). If the *size* argument is negative\n or omitted, read all data until EOF is reached. The bytes are\n returned as a string object. An empty string is returned when EOF\n is encountered immediately. (For certain files, like ttys, it\n makes sense to continue reading after an EOF is hit.) Note that\n this method may call the underlying C function ``fread`` more than\n once in an effort to acquire as close to *size* bytes as possible.\n Also note that when in non-blocking mode, less data than was\n requested may be returned, even if no *size* parameter was given.\n\n Note: This function is simply a wrapper for the underlying ``fread`` C\n function, and will behave the same in corner cases, such as\n whether the EOF value is cached.\n\nfile.readline([size])\n\n Read one entire line from the file. A trailing newline character\n is kept in the string (but may be absent when a file ends with an\n incomplete line). [6] If the *size* argument is present and non-\n negative, it is a maximum byte count (including the trailing\n newline) and an incomplete line may be returned. An empty string is\n returned *only* when EOF is encountered immediately.\n\n Note: Unlike ``stdio``\'s ``fgets``, the returned string contains null\n characters (``\'\\0\'``) if they occurred in the input.\n\nfile.readlines([sizehint])\n\n Read until EOF using ``readline()`` and return a list containing\n the lines thus read. If the optional *sizehint* argument is\n present, instead of reading up to EOF, whole lines totalling\n approximately *sizehint* bytes (possibly after rounding up to an\n internal buffer size) are read. Objects implementing a file-like\n interface may choose to ignore *sizehint* if it cannot be\n implemented, or cannot be implemented efficiently.\n\nfile.xreadlines()\n\n This method returns the same thing as ``iter(f)``.\n\n New in version 2.1.\n\n Deprecated since version 2.3: Use ``for line in file`` instead.\n\nfile.seek(offset[, whence])\n\n Set the file\'s current position, like ``stdio``\'s ``fseek``. The\n *whence* argument is optional and defaults to ``os.SEEK_SET`` or\n ``0`` (absolute file positioning); other values are ``os.SEEK_CUR``\n or ``1`` (seek relative to the current position) and\n ``os.SEEK_END`` or ``2`` (seek relative to the file\'s end). There\n is no return value.\n\n For example, ``f.seek(2, os.SEEK_CUR)`` advances the position by\n two and ``f.seek(-3, os.SEEK_END)`` sets the position to the third\n to last.\n\n Note that if the file is opened for appending (mode ``\'a\'`` or\n ``\'a+\'``), any ``seek()`` operations will be undone at the next\n write. If the file is only opened for writing in append mode (mode\n ``\'a\'``), this method is essentially a no-op, but it remains useful\n for files opened in append mode with reading enabled (mode\n ``\'a+\'``). If the file is opened in text mode (without ``\'b\'``),\n only offsets returned by ``tell()`` are legal. Use of other\n offsets causes undefined behavior.\n\n Note that not all file objects are seekable.\n\n Changed in version 2.6: Passing float values as offset has been\n deprecated.\n\nfile.tell()\n\n Return the file\'s current position, like ``stdio``\'s ``ftell``.\n\n Note: On Windows, ``tell()`` can return illegal values (after an\n ``fgets``) when reading files with Unix-style line-endings. Use\n binary mode (``\'rb\'``) to circumvent this problem.\n\nfile.truncate([size])\n\n Truncate the file\'s size. If the optional *size* argument is\n present, the file is truncated to (at most) that size. The size\n defaults to the current position. The current file position is not\n changed. Note that if a specified size exceeds the file\'s current\n size, the result is platform-dependent: possibilities include that\n the file may remain unchanged, increase to the specified size as if\n zero-filled, or increase to the specified size with undefined new\n content. Availability: Windows, many Unix variants.\n\nfile.write(str)\n\n Write a string to the file. There is no return value. Due to\n buffering, the string may not actually show up in the file until\n the ``flush()`` or ``close()`` method is called.\n\nfile.writelines(sequence)\n\n Write a sequence of strings to the file. The sequence can be any\n iterable object producing strings, typically a list of strings.\n There is no return value. (The name is intended to match\n ``readlines()``; ``writelines()`` does not add line separators.)\n\nFiles support the iterator protocol. Each iteration returns the same\nresult as ``file.readline()``, and iteration ends when the\n``readline()`` method returns an empty string.\n\nFile objects also offer a number of other interesting attributes.\nThese are not required for file-like objects, but should be\nimplemented if they make sense for the particular object.\n\nfile.closed\n\n bool indicating the current state of the file object. This is a\n read-only attribute; the ``close()`` method changes the value. It\n may not be available on all file-like objects.\n\nfile.encoding\n\n The encoding that this file uses. When Unicode strings are written\n to a file, they will be converted to byte strings using this\n encoding. In addition, when the file is connected to a terminal,\n the attribute gives the encoding that the terminal is likely to use\n (that information might be incorrect if the user has misconfigured\n the terminal). The attribute is read-only and may not be present\n on all file-like objects. It may also be ``None``, in which case\n the file uses the system default encoding for converting Unicode\n strings.\n\n New in version 2.3.\n\nfile.errors\n\n The Unicode error handler used along with the encoding.\n\n New in version 2.6.\n\nfile.mode\n\n The I/O mode for the file. If the file was created using the\n ``open()`` built-in function, this will be the value of the *mode*\n parameter. This is a read-only attribute and may not be present on\n all file-like objects.\n\nfile.name\n\n If the file object was created using ``open()``, the name of the\n file. Otherwise, some string that indicates the source of the file\n object, of the form ``<...>``. This is a read-only attribute and\n may not be present on all file-like objects.\n\nfile.newlines\n\n If Python was built with the *--with-universal-newlines* option to\n **configure** (the default) this read-only attribute exists, and\n for files opened in universal newline read mode it keeps track of\n the types of newlines encountered while reading the file. The\n values it can take are ``\'\\r\'``, ``\'\\n\'``, ``\'\\r\\n\'``, ``None``\n (unknown, no newlines read yet) or a tuple containing all the\n newline types seen, to indicate that multiple newline conventions\n were encountered. For files not opened in universal newline read\n mode the value of this attribute will be ``None``.\n\nfile.softspace\n\n Boolean that indicates whether a space character needs to be\n printed before another value when using the ``print`` statement.\n Classes that are trying to simulate a file object should also have\n a writable ``softspace`` attribute, which should be initialized to\n zero. This will be automatic for most classes implemented in\n Python (care may be needed for objects that override attribute\n access); types implemented in C will have to provide a writable\n ``softspace`` attribute.\n\n Note: This attribute is not used to control the ``print`` statement,\n but to allow the implementation of ``print`` to keep track of its\n internal state.\n', - 'bltin-null-object': u"\nThe Null Object\n***************\n\nThis object is returned by functions that don't explicitly return a\nvalue. It supports no special operations. There is exactly one null\nobject, named ``None`` (a built-in name).\n\nIt is written as ``None``.\n", - 'bltin-type-objects': u"\nType Objects\n************\n\nType objects represent the various object types. An object's type is\naccessed by the built-in function ``type()``. There are no special\noperations on types. The standard module ``types`` defines names for\nall standard built-in types.\n\nTypes are written like this: ````.\n", - 'booleans': u'\nBoolean operations\n******************\n\nBoolean operations have the lowest priority of all Python operations:\n\n expression ::= conditional_expression | lambda_form\n old_expression ::= or_test | old_lambda_form\n conditional_expression ::= or_test ["if" or_test "else" expression]\n or_test ::= and_test | or_test "or" and_test\n and_test ::= not_test | and_test "and" not_test\n not_test ::= comparison | "not" not_test\n\nIn the context of Boolean operations, and also when expressions are\nused by control flow statements, the following values are interpreted\nas false: ``False``, ``None``, numeric zero of all types, and empty\nstrings and containers (including strings, tuples, lists,\ndictionaries, sets and frozensets). All other values are interpreted\nas true. (See the ``__nonzero__()`` special method for a way to\nchange this.)\n\nThe operator ``not`` yields ``True`` if its argument is false,\n``False`` otherwise.\n\nThe expression ``x if C else y`` first evaluates *C* (*not* *x*); if\n*C* is true, *x* is evaluated and its value is returned; otherwise,\n*y* is evaluated and its value is returned.\n\nNew in version 2.5.\n\nThe expression ``x and y`` first evaluates *x*; if *x* is false, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\nThe expression ``x or y`` first evaluates *x*; if *x* is true, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\n(Note that neither ``and`` nor ``or`` restrict the value and type they\nreturn to ``False`` and ``True``, but rather return the last evaluated\nargument. This is sometimes useful, e.g., if ``s`` is a string that\nshould be replaced by a default value if it is empty, the expression\n``s or \'foo\'`` yields the desired value. Because ``not`` has to\ninvent a value anyway, it does not bother to return a value of the\nsame type as its argument, so e.g., ``not \'foo\'`` yields ``False``,\nnot ``\'\'``.)\n', - 'break': u'\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': u'\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': u'\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 [","]\n | expression genexpr_for] ")"\n argument_list ::= positional_arguments ["," keyword_arguments]\n ["," "*" expression] ["," keyword_arguments]\n ["," "**" expression]\n | keyword_arguments ["," "*" expression]\n ["," "**" expression]\n | "*" expression ["," "*" expression] ["," "**" 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 certain class instances\nthemselves are callable; extensions may define additional callable\nobject types). All argument expressions are evaluated before the call\nis attempted. Please refer to section *Function definitions* for the\nsyntax 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\nNote: An implementation may provide builtin functions whose positional\n parameters do not have names, even if they are \'named\' for the\n purpose of documentation, and which therefore cannot be supplied by\n keyword. In CPython, this is the case for functions implemented in\n C that use ``PyArg_ParseTuple`` to parse 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. Formal parameters using the syntax ``(sublist)`` cannot be\nused as keyword argument names; the outermost sublist corresponds to a\nsingle unnamed argument slot, and the argument value is assigned to\nthe sublist using the usual tuple assignment rules after all other\nparameter processing is done.\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': u'\nClass definitions\n*****************\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with ``self.name = value``.\nBoth class and instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\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', - 'coercion-rules': u"\nCoercion rules\n**************\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3.0, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don't define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from ``object``) never invoke the\n ``__coerce__()`` method in response to a binary operator; the only\n time ``__coerce__()`` is invoked is when the built-in function\n ``coerce()`` is called.\n\n* For most intents and purposes, an operator that returns\n ``NotImplemented`` is treated the same as one that is not\n implemented at all.\n\n* Below, ``__op__()`` and ``__rop__()`` are used to signify the\n generic method names corresponding to an operator; ``__iop__()`` is\n used for the corresponding in-place operator. For example, for the\n operator '``+``', ``__add__()`` and ``__radd__()`` are used for the\n left and right variant of the binary operator, and ``__iadd__()``\n for the in-place variant.\n\n* For objects *x* and *y*, first ``x.__op__(y)`` is tried. If this is\n not implemented or returns ``NotImplemented``, ``y.__rop__(x)`` is\n tried. If this is also not implemented or returns\n ``NotImplemented``, a ``TypeError`` exception is raised. But see\n the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base's ``__rop__()`` method, the right operand's ``__rop__()``\n method is tried *before* the left operand's ``__op__()`` method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand's ``__op__()`` method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is called\n before that type's ``__op__()`` or ``__rop__()`` method is called,\n but no sooner. If the coercion returns an object of a different\n type for the operand whose coercion is invoked, part of the process\n is redone using the new object.\n\n* When an in-place operator (like '``+=``') is used, if the left\n operand implements ``__iop__()``, it is invoked without any\n coercion. When the operation falls back to ``__op__()`` and/or\n ``__rop__()``, the normal coercion rules apply.\n\n* In ``x + y``, if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In ``x * y``, if one operator is a sequence that implements sequence\n repetition, and the other is an integer (``int`` or ``long``),\n sequence repetition is invoked.\n\n* Rich comparisons (implemented by methods ``__eq__()`` and so on)\n never use coercion. Three-way comparison (implemented by\n ``__cmp__()``) does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types ``int``,\n ``long`` and ``float`` do not use coercion; the type ``complex``\n however does use it. The difference can become apparent when\n subclassing these types. Over time, the type ``complex`` may be\n fixed to avoid coercion. All these types implement a\n ``__coerce__()`` method, for use by the built-in ``coerce()``\n function.\n", - 'comparisons': u'\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 forms ``<>`` and ``!=`` are equivalent; for consistency with C,\n``!=`` is preferred; where ``!=`` is mentioned below ``<>`` is also\naccepted. The ``<>`` spelling is considered obsolescent.\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,\nobjects of different types *always* compare unequal, and are ordered\nconsistently but arbitrarily. You can control comparison behavior of\nobjects of non-builtin types by defining a ``__cmp__`` method or rich\ncomparison methods like ``__gt__``, described in section *Special\nmethod names*.\n\n(This unusual definition of comparison was used to simplify the\ndefinition of operations like sorting and the ``in`` and ``not in``\noperators. In the future, the comparison rules for objects of\ndifferent types are likely to change.)\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n Unicode and 8-bit strings are fully interoperable in this behavior.\n [4]\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, ``cmp([1,2,x], [1,2,y])`` returns\n the same as ``cmp(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 their sorted\n (key, value) lists compare equal. [5] Outcomes other than equality\n are resolved consistently, but are not otherwise defined. [6]\n\n* Most other objects of builtin 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\nThe operators ``in`` and ``not in`` test for collection membership.\n``x in s`` evaluates to true if *x* is a member of the collection *s*,\nand false otherwise. ``x not in s`` returns the negation of ``x in\ns``. The collection membership test has traditionally been bound to\nsequences; an object is a member of a collection if the collection is\na sequence and contains an element equal to that object. However, it\nmake sense for many other object types to support membership tests\nwithout being a sequence. In particular, dictionaries (for keys) and\nsets support membership testing.\n\nFor the list and tuple types, ``x in y`` is true if and only if there\nexists an index *i* such that ``x == y[i]`` is true.\n\nFor the Unicode and string types, ``x in y`` is true if and only if\n*x* is a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nNote, *x* and *y* need not be the same type; consequently, ``u\'ab\' in\n\'abc\'`` will return ``True``. Empty strings are always considered to\nbe a substring of any other string, so ``"" in "abc"`` will return\n``True``.\n\nChanged in version 2.3: Previously, *x* was required to be a string of\nlength ``1``.\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__()`` and do\ndefine ``__getitem__()``, ``x in y`` is true if and only if there is a\nnon-negative 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. [7]\n', - 'compound': u'\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. Function and class\ndefinitions are also syntactically compound 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`` statements 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 | decorated\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, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\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\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nWarning: 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 internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n 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 ["," target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nChanged in version 2.5: In previous versions of Python,\n``try``...``except``...``finally`` did not work. ``try``...``except``\nhad to be nested in ``try``...``finally``.\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, a tuple containing an item compatible with the\nexception, or, in the (deprecated) case of string exceptions, is the\nraised string itself (note that the object identities must match, i.e.\nit must be the same string object, not just a string with the same\nvalue).\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 in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the ``sys`` module:\n``sys.exc_type`` receives the object identifying the exception;\n``sys.exc_value`` receives the exception\'s parameter;\n``sys.exc_traceback`` receives a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. These details are also available through the\n``sys.exc_info()`` function, which returns a tuple ``(exc_type,\nexc_value, exc_traceback)``. Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables 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\nNew in version 2.5.\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" expression ["as" target] ":" suite\n\nThe execution of the ``with`` statement proceeds as follows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__enter__()`` method is invoked.\n\n3. 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 5 below.\n\n4. The suite is executed.\n\n5. 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\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\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 decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier [, "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\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 top-level 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 must also have a default value --- this is a syntactic\nrestriction 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.\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 *Expression lists*. Note that the lambda form is\nmerely a shorthand for a simplified function definition; a function\ndefined in a "``def``" statement can be passed around or assigned to\nanother name just like a function defined by a lambda form. The\n"``def``" form is actually more powerful since it allows the execution\nof multiple statements.\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 ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with ``self.name = value``.\nBoth class and instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\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': u'\nWith Statement Context Managers\n*******************************\n\nNew in version 2.5.\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': u'\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': u'\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," the arguments\nare coerced using the coercion rules listed at *Coercion rules*. If\nboth arguments are standard numeric types, the following coercions are\napplied:\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, if either argument is a long integer, the other is\n converted to long integer;\n\n* otherwise, both must be plain integers and no conversion is\n necessary.\n\nSome additional rules apply for certain operators (e.g., a string left\nargument to the \'%\' operator). Extensions can define their own\ncoercions.\n', - 'customization': u'\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_traceback`` 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.exc_traceback`` or ``sys.last_traceback``. Circular\n references which are garbage are detected when the option cycle\n detector is enabled (it\'s on by default), but can only be cleaned\n up if there are no Python-level ``__del__()`` methods involved.\n Refer to the documentation for the ``gc`` module for more\n information about how ``__del__()`` methods are handled by the\n cycle detector, particularly the description of the ``garbage``\n 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. For this reason, ``__del__()`` methods should do\n the absolute minimum needed to maintain external invariants.\n Starting with version 1.5, Python guarantees that globals whose\n name begins with a single underscore are deleted from their\n module before other globals are deleted; if no other references\n to such globals exist, this may help in assuring that imported\n modules are still available at the time when the ``__del__()``\n method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is 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 statement 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.__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 New in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` call ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and\n ``x>=y`` calls ``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\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by ``__cmp__()`` has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\n\nobject.__hash__(self)\n\n Called for the key object for dictionary operations, and by the\n built-in function ``hash()``. Should return an integer usable as a\n hash value for dictionary operations. The only required property\n is that objects which compare equal have the same hash value; it is\n advised to somehow mix together (e.g., using exclusive or) the hash\n values for the components of the object that also play a part in\n comparison of objects.\n\n If a class does not define a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable as dictionary keys. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n the dictionary implementation requires that a key\'s hash value is\n immutable (if the object\'s hash value changes, it will be in the\n wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` 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 ``__cmp__()`` or ``__eq__()`` such that\n the hash value returned is no longer appropriate (e.g. by switching\n to a value-based concept of equality instead of the default\n identity based equality) can explicitly flag themselves as being\n unhashable by setting ``__hash__ = None`` in the class definition.\n Doing so means that not only will instances of the class raise an\n appropriate ``TypeError`` when a program attempts to retrieve their\n hash value, but they will also be correctly identified as\n unhashable when checking ``isinstance(obj, collections.Hashable)``\n (unlike classes which define their own ``__hash__()`` to explicitly\n raise ``TypeError``).\n\n Changed in version 2.5: ``__hash__()`` may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\n Changed in version 2.6: ``__hash__`` may now be set to ``None`` to\n explicitly flag instances of a class as unhashable.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing, and the built-in operation\n ``bool()``; should return ``False`` or ``True``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined (see below). If a class\n defines neither ``__len__()`` nor ``__nonzero__()``, all its\n instances are considered true.\n\nobject.__unicode__(self)\n\n Called to implement ``unicode()`` builtin; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\n', - 'debugger': u'\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``\n(undocumented) and ``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 python -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 2.4: Restarting post-mortem behavior added.\n\nTypical 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[, locals]])\n\n Execute the *statement* (given as a string) under debugger control.\n The debugger prompt appears before any code is executed; you can\n set breakpoints and type ``continue``, or you can step through the\n statement using ``step`` or ``next`` (all these commands are\n explained below). The optional *globals* and *locals* arguments\n specify the environment in which the code is executed; by default\n the dictionary of the module ``__main__`` is used. (See the\n explanation of the ``exec`` statement or the ``eval()`` built-in\n function.)\n\npdb.runeval(expression[, globals[, locals]])\n\n Evaluate the *expression* (given as a string) under debugger\n control. When ``runeval()`` returns, it returns the value of the\n expression. Otherwise this function is similar to ``run()``.\n\npdb.runcall(function[, argument, ...])\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])\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', - 'del': u'\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\nIt is illegal to delete a name from the local namespace if it occurs\nas a free variable in a nested block.\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', - 'dict': u'\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] "}"\n key_datum_list ::= key_datum ("," key_datum)* [","]\n key_datum ::= expression ":" expression\n\nA dictionary display yields a new dictionary object.\n\nThe key/datum pairs are evaluated from left to right to define the\nentries of the dictionary: each key object is used as a key into the\ndictionary to store the corresponding datum.\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': u'\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\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n', - 'else': u'\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', - 'exceptions': u'\nExceptions\n**********\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nWarning: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', - 'exec': u'\nThe ``exec`` statement\n**********************\n\n exec_stmt ::= "exec" or_expr ["in" expression ["," expression]]\n\nThis statement supports dynamic execution of Python code. The first\nexpression should evaluate to either a string, an open file object, or\na code object. If it is a string, the string is parsed as a suite of\nPython statements which is then executed (unless a syntax error\noccurs). If it is an open file, the file is parsed until EOF and\nexecuted. If it is a code object, it is simply executed. In all\ncases, the code that\'s executed is expected to be valid as file input\n(see section *File input*). Be aware that the ``return`` and\n``yield`` statements may not be used outside of function definitions\neven within the context of code passed to the ``exec`` statement.\n\nIn all cases, if the optional parts are omitted, the code is executed\nin the current scope. If only the first expression after ``in`` is\nspecified, it should be a dictionary, which will be used for both the\nglobal and the local variables. If two expressions are given, they\nare used for the global and local variables, respectively. If\nprovided, *locals* can be any mapping object.\n\nChanged in version 2.4: Formerly, *locals* was required to be a\ndictionary.\n\nAs a side effect, an implementation may insert additional keys into\nthe dictionaries given besides those corresponding to variable names\nset by the executed code. For example, the current implementation may\nadd a reference to the dictionary of the built-in module\n``__builtin__`` under the key ``__builtins__`` (!).\n\n**Programmer\'s hints:** dynamic evaluation of expressions is supported\nby the built-in function ``eval()``. The built-in functions\n``globals()`` and ``locals()`` return the current global and local\ndictionary, respectively, which may be useful to pass around for use\nby ``exec``.\n', - 'execmodel': u'\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, or in\nthe second position of an ``except`` clause header. The ``import``\nstatement of the form "``from ...import *``" binds all names defined\nin the imported module, except those beginning with an underscore.\nThis form may only be used at the module level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtin namespace, the namespace of\nthe module ``__builtin__``. The global namespace is searched first.\nIf the name is not found there, the builtin namespace is searched.\nThe global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no \'s\'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``__builtin__`` (no \'s\')\n module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\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\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nWarning: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', - 'exprlists': u'\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': u'\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 of floating point numbers can\nlook like octal integers, but are interpreted using radix 10. For\nexample, ``077e010`` is legal, and denotes the same number as\n``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': u'\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, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\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\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nWarning: 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 internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n 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': u'\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 ::= (identifier | integer) ("." attribute_name | "[" element_index "]")*\n attribute_name ::= identifier\n element_index ::= integer\n conversion ::= "r" | "s"\n format_spec ::= \n\nIn less formal terms, the replacement field starts with a\n*field_name*, which can either be a number (for a positional\nargument), or an identifier (for keyword arguments). Following this\nis an optional *conversion* field, which is preceded by an exclamation\npoint ``\'!\'``, and a *format_spec*, which is preceded by a colon\n``\':\'``.\n\nThe *field_name* itself begins with either a number or a keyword. If\nit\'s a number, it refers to a positional argument, and if it\'s a\nkeyword it refers to a named keyword argument. This can be followed\nby any number of index or attribute expressions. An expression of the\nform ``\'.name\'`` selects the named attribute using ``getattr()``,\nwhile an expression of the form ``\'[index]\'`` does an index lookup\nusing ``__getitem__()``.\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\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\nTwo conversion flags are currently supported: ``\'!s\'`` which calls\n``str()`` on the value, and ``\'!r\'`` which calls ``repr()``.\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\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 it\'s\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\nFor example, suppose you wanted to have a replacement field whose\nfield width is determined by another variable:\n\n "A man with two {0:{1}}".format("noses", 10)\n\nThis would first evaluate the inner replacement field, making the\nformat string effectively:\n\n "A man with two {0:10}"\n\nThen the outer replacement field would be evaluated, producing:\n\n "noses "\n\nWhich is substituted into the string, yielding:\n\n "A man with two noses "\n\n(The extra space is because we specified a field width of 10, and\nbecause left alignment is the default for strings.)\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\nbuiltin ``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.\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" | "x" | "X" | "%"\n\nThe *fill* character can be any character other than \'}\' (which\nsignifies the end of the field). The presence of a fill character is\nsignaled by the *next* character, which must be one of the alignment\noptions. If the second character of *format_spec* is not a valid\nalignment option, then it is assumed that both the fill character and\nthe alignment option are absent.\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\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 ignored for integer values.\n\nFinally, the *type* determines how the data should be presented.\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\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\'``. |\n +-----------+------------------------------------------------------------+\n | ``\'g\'`` | General format. This prints the number as a fixed-point |\n | | number, unless the number is too large, in which case it |\n | | switches to ``\'e\'`` exponent notation. Infinity and NaN |\n | | values are formatted as ``inf``, ``-inf`` and ``nan``, |\n | | respectively. |\n +-----------+------------------------------------------------------------+\n | ``\'G\'`` | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n | | if the number gets to 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 | The same as ``\'g\'``. |\n +-----------+------------------------------------------------------------+\n', - 'function': u'\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier [, "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\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 top-level 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 must also have a default value --- this is a syntactic\nrestriction 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.\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 *Expression lists*. Note that the lambda form is\nmerely a shorthand for a simplified function definition; a function\ndefined in a "``def``" statement can be passed around or assigned to\nanother name just like a function defined by a lambda form. The\n"``def``" form is actually more powerful since it allows the execution\nof multiple statements.\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': u'\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(The current implementation does not enforce the latter two\nrestrictions, but programs should not abuse this freedom, as future\nimplementations may enforce them or silently change the meaning of the\nprogram.)\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 an\n``exec`` statement does not affect the code block *containing* the\n``exec`` statement, and code contained in an ``exec`` statement is\nunaffected by ``global`` statements in the code containing the\n``exec`` statement. The same applies to the ``eval()``,\n``execfile()`` and ``compile()`` functions.\n', - 'id-classes': u'\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 ``__builtin__`` module.\n When not in interactive mode, ``_`` has no special meaning and is\n not 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);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\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': u'\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions:\n\n identifier ::= (letter|"_") (letter | digit | "_")*\n letter ::= lowercase | uppercase\n lowercase ::= "a"..."z"\n uppercase ::= "A"..."Z"\n digit ::= "0"..."9"\n\nIdentifiers are unlimited in length. Case is significant.\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 and del from not while\n as elif global or with\n assert else if pass yield\n break except import print\n class exec in raise\n continue finally is return\n def for lambda try\n\nChanged in version 2.4: ``None`` became a constant and is now\nrecognized by the compiler as a name for the built-in object ``None``.\nAlthough it is not a keyword, you cannot assign a different object to\nit.\n\nChanged in version 2.5: Both ``as`` and ``with`` are only recognized\nwhen the ``with_statement`` future feature has been enabled. It will\nalways be enabled in Python 2.6. See section *The with statement* for\ndetails. Note that using ``as`` and ``with`` as identifiers will\nalways issue a warning, even when the ``with_statement`` future\ndirective is not in effect.\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 ``__builtin__`` module.\n When not in interactive mode, ``_`` has no special meaning and is\n not 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);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\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': u'\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': u'\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': u'\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\nfirst form (without ``from``) repeats these steps for each identifier\nin the list. The form with ``from`` performs step (1) once, and then\nperforms step (2) repeatedly.\n\nIn this context, to "initialize" a built-in or extension module means\nto call an initialization function that the module must provide for\nthe purpose (in the reference implementation, the function\'s name is\nobtained by prepending string "init" to the module\'s name); to\n"initialize" a Python-coded module means to execute the module\'s body.\n\nThe system maintains a table of modules that have been or are being\ninitialized, indexed by module name. This table is accessible as\n``sys.modules``. When a module name is found in this table, step (1)\nis finished. If not, a search for a module definition is started.\nWhen a module is found, it is loaded. Details of the module searching\nand loading process are implementation and platform specific. It\ngenerally involves searching for a "built-in" module with the given\nname and then searching a list of locations given as ``sys.path``.\n\nIf a built-in module is found, its built-in initialization code is\nexecuted and step (1) is finished. If no matching file is found,\n``ImportError`` is raised. If a file is found, it is parsed, yielding\nan executable code block. If a syntax error occurs, ``SyntaxError``\nis raised. Otherwise, an empty module of the given name is created\nand inserted in the module table, and then the code block is executed\nin the context of this module. Exceptions during this execution\nterminate step (1).\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. If the\nwild card form of import --- ``import *`` --- is used in a function\nand the function contains or is a nested block with free variables,\nthe compiler will raise a ``SyntaxError``.\n\n**Hierarchical module names:** when the module names contains one or\nmore dots, the module search path is carried out differently. The\nsequence of identifiers up to the last dot is used to find a\n"package"; the final identifier is then searched inside the package.\nA package is generally a subdirectory of a directory on ``sys.path``\nthat has a file ``__init__.py``.\n\nThe built-in function ``__import__()`` is provided to support\napplications that determine which modules need to be loaded\ndynamically; refer to *Built-in Functions* for additional information.\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 2.5 are ``absolute_import``,\n``division``, ``generators``, ``nested_scopes`` and\n``with_statement``. ``generators`` and ``nested_scopes`` are\nredundant in Python version 2.3 and above because they are always\nenabled.\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 an ``exec`` statement or calls to the builtin\nfunctions ``compile()`` and ``execfile()`` that occur in a module\n``M`` containing a future statement will, by default, use the new\nsyntax or semantics associated with the future statement. This can,\nstarting with Python 2.2 be controlled by optional arguments to\n``compile()`` --- see the documentation of that function for 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', - 'in': u'\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 forms ``<>`` and ``!=`` are equivalent; for consistency with C,\n``!=`` is preferred; where ``!=`` is mentioned below ``<>`` is also\naccepted. The ``<>`` spelling is considered obsolescent.\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,\nobjects of different types *always* compare unequal, and are ordered\nconsistently but arbitrarily. You can control comparison behavior of\nobjects of non-builtin types by defining a ``__cmp__`` method or rich\ncomparison methods like ``__gt__``, described in section *Special\nmethod names*.\n\n(This unusual definition of comparison was used to simplify the\ndefinition of operations like sorting and the ``in`` and ``not in``\noperators. In the future, the comparison rules for objects of\ndifferent types are likely to change.)\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n Unicode and 8-bit strings are fully interoperable in this behavior.\n [4]\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, ``cmp([1,2,x], [1,2,y])`` returns\n the same as ``cmp(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 their sorted\n (key, value) lists compare equal. [5] Outcomes other than equality\n are resolved consistently, but are not otherwise defined. [6]\n\n* Most other objects of builtin 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\nThe operators ``in`` and ``not in`` test for collection membership.\n``x in s`` evaluates to true if *x* is a member of the collection *s*,\nand false otherwise. ``x not in s`` returns the negation of ``x in\ns``. The collection membership test has traditionally been bound to\nsequences; an object is a member of a collection if the collection is\na sequence and contains an element equal to that object. However, it\nmake sense for many other object types to support membership tests\nwithout being a sequence. In particular, dictionaries (for keys) and\nsets support membership testing.\n\nFor the list and tuple types, ``x in y`` is true if and only if there\nexists an index *i* such that ``x == y[i]`` is true.\n\nFor the Unicode and string types, ``x in y`` is true if and only if\n*x* is a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nNote, *x* and *y* need not be the same type; consequently, ``u\'ab\' in\n\'abc\'`` will return ``True``. Empty strings are always considered to\nbe a substring of any other string, so ``"" in "abc"`` will return\n``True``.\n\nChanged in version 2.3: Previously, *x* was required to be a string of\nlength ``1``.\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__()`` and do\ndefine ``__getitem__()``, ``x in y`` is true if and only if there is a\nnon-negative 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. [7]\n', - 'integers': u'\nInteger and long integer literals\n*********************************\n\nInteger and long integer literals are described by the following\nlexical definitions:\n\n longinteger ::= integer ("l" | "L")\n integer ::= decimalinteger | octinteger | hexinteger\n decimalinteger ::= nonzerodigit digit* | "0"\n octinteger ::= "0" octdigit+\n hexinteger ::= "0" ("x" | "X") hexdigit+\n nonzerodigit ::= "1"..."9"\n octdigit ::= "0"..."7"\n hexdigit ::= digit | "a"..."f" | "A"..."F"\n\nAlthough both lower case ``\'l\'`` and upper case ``\'L\'`` are allowed as\nsuffix for long integers, it is strongly recommended to always use\n``\'L\'``, since the letter ``\'l\'`` looks too much like the digit\n``\'1\'``.\n\nPlain integer literals that are above the largest representable plain\ninteger (e.g., 2147483647 when using 32-bit arithmetic) are accepted\nas if they were long integers instead. [1] There is no limit for long\ninteger literals apart from what can be stored in available memory.\n\nSome examples of plain integer literals (first row) and long integer\nliterals (second and third rows):\n\n 7 2147483647 0177\n 3L 79228162514264337593543950336L 0377L 0x100000000L\n 79228162514264337593543950336 0xdeadbeef\n', - 'lambda': u'\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', - 'lists': u'\nList displays\n*************\n\nA list display is a possibly empty series of expressions enclosed in\nsquare brackets:\n\n list_display ::= "[" [expression_list | list_comprehension] "]"\n list_comprehension ::= expression list_for\n list_for ::= "for" target_list "in" old_expression_list [list_iter]\n old_expression_list ::= old_expression [("," old_expression)+ [","]]\n list_iter ::= list_for | list_if\n list_if ::= "if" old_expression [list_iter]\n\nA list display yields a new list object. Its contents are specified\nby providing either a list of expressions or a list comprehension.\nWhen a comma-separated list of expressions is supplied, its elements\nare evaluated from left to right and placed into the list object in\nthat order. When a list comprehension is supplied, it consists of a\nsingle expression followed by at least one ``for`` clause and zero or\nmore ``for`` or ``if`` clauses. In this case, the elements of the new\nlist are those that would be produced by considering each of the\n``for`` or ``if`` clauses a block, nesting from left to right, and\nevaluating the expression to produce a list element each time the\ninnermost block is reached [1].\n', - 'naming': u'\nNaming and binding\n******************\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, or in\nthe second position of an ``except`` clause header. The ``import``\nstatement of the form "``from ...import *``" binds all names defined\nin the imported module, except those beginning with an underscore.\nThis form may only be used at the module level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtin namespace, the namespace of\nthe module ``__builtin__``. The global namespace is searched first.\nIf the name is not found there, the builtin namespace is searched.\nThe global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no \'s\'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``__builtin__`` (no \'s\')\n module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\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\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n', - 'numbers': u"\nNumeric literals\n****************\n\nThere are four types of numeric literals: plain integers, long\nintegers, floating point numbers, and imaginary numbers. There are no\ncomplex literals (complex numbers can be formed by adding a real\nnumber and an imaginary 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': u'\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.__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 (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression ``x + y``, where *x* is an\n 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__()`` (described below). Note\n that ``__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.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(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 (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [3] For instance, to evaluate\n the expression ``x - y``, where *y* is an instance of a class that\n has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *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.__idiv__(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 operations (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\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 operation falls back to the normal methods. For instance, to\n evaluate the expression ``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.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``long()``, and ``float()``. Should return a value of\n the appropriate type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions ``oct()`` and ``hex()``.\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n New in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or ``None`` if conversion is impossible. When\n the common type would be the type of ``other``, it is sufficient to\n return ``None``, since the interpreter will also ask the other\n object to attempt a coercion (but sometimes, if the implementation\n of the other type cannot be changed, it is useful to do the\n conversion to the other type here). A return value of\n ``NotImplemented`` is equivalent to returning ``None``.\n', - 'objects': u'\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. (Implementation note: the current implementation uses a\nreference-counting scheme with (optional) delayed detection of\ncyclically linked garbage, which collects most objects as soon as they\nbecome unreachable, but is not guaranteed to collect garbage\ncontaining circular references. See the documentation of the ``gc``\nmodule for information on controlling the collection of cyclic\ngarbage.)\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 provides a convenient way to do\nthis.\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': u'\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| ``or`` | Boolean OR |\n+-------------------------------------------------+---------------------------------------+\n| ``and`` | Boolean AND |\n+-------------------------------------------------+---------------------------------------+\n| ``not`` *x* | Boolean NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``in``, ``not`` ``in`` | Membership tests |\n+-------------------------------------------------+---------------------------------------+\n| ``is``, ``is not`` | Identity tests |\n+-------------------------------------------------+---------------------------------------+\n| ``<``, ``<=``, ``>``, ``>=``, ``<>``, ``!=``, | Comparisons |\n| ``==`` | |\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+-------------------------------------------------+---------------------------------------+\n| ``+x``, ``-x`` | Positive, negative |\n+-------------------------------------------------+---------------------------------------+\n| ``~x`` | Bitwise not |\n+-------------------------------------------------+---------------------------------------+\n| ``**`` | Exponentiation |\n+-------------------------------------------------+---------------------------------------+\n| ``x[index]`` | Subscription |\n+-------------------------------------------------+---------------------------------------+\n| ``x[index:index]`` | Slicing |\n+-------------------------------------------------+---------------------------------------+\n| ``x(arguments...)`` | Call |\n+-------------------------------------------------+---------------------------------------+\n| ``x.attribute`` | Attribute reference |\n+-------------------------------------------------+---------------------------------------+\n| ``(expressions...)`` | Binding or tuple display |\n+-------------------------------------------------+---------------------------------------+\n| ``[expressions...]`` | List display |\n+-------------------------------------------------+---------------------------------------+\n| ``{key:datum...}`` | Dictionary display |\n+-------------------------------------------------+---------------------------------------+\n| ```expressions...``` | String conversion |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] In Python 2.3 and later releases, a list comprehension "leaks" the\n control variables of each ``for`` it contains into the containing\n scope. However, this behavior is deprecated, and relying on it\n will not work in Python 3.0\n\n[2] 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[3] If x is very close to an exact integer multiple of y, it\'s\n possible for ``floor(x/y)`` to be one larger than ``(x-x%y)/y``\n due to rounding. In such cases, Python returns the latter result,\n in order to preserve that ``divmod(x,y)[0] * y + x % y`` be very\n close to ``x``.\n\n[4] While comparisons between unicode strings make sense at the byte\n level, they may be counter-intuitive to users. For example, the\n strings ``u"\\u00C7"`` and ``u"\\u0043\\u0327"`` compare differently,\n even though they both represent the same unicode character (LATIN\n CAPTITAL LETTER C WITH CEDILLA). To compare strings in a human\n recognizable way, compare using ``unicodedata.normalize()``.\n\n[5] The implementation computes this efficiently, without constructing\n lists or sorting.\n\n[6] Earlier versions of Python used lexicographic comparison of the\n sorted (key, value) lists, but this was very expensive for the\n common case of comparing for equality. An even earlier version of\n Python compared dictionaries by identity only, but this caused\n surprises because people expected to be able to test a dictionary\n for emptiness by comparing it to ``{}``.\n\n[7] 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', - 'pass': u'\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': u'\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. The result type is that of the\narguments after coercion.\n\nWith mixed operand types, the coercion rules for binary arithmetic\noperators apply. For int and long int operands, the result has the\nsame type as the operands (after coercion) unless the second argument\nis negative; in that case, all arguments are converted to float and a\nfloat result is delivered. For example, ``10**2`` returns ``100``, but\n``10**-2`` returns ``0.01``. (This last feature was added in Python\n2.2. In Python 2.1 and before, if both arguments were of integer types\nand the second argument was negative, an exception was raised).\n\nRaising ``0.0`` to a negative power results in a\n``ZeroDivisionError``. Raising a negative number to a fractional power\nresults in a ``ValueError``.\n', - 'print': u'\nThe ``print`` statement\n***********************\n\n print_stmt ::= "print" ([expression ("," expression)* [","]]\n | ">>" expression [("," expression)+ [","]])\n\n``print`` evaluates each expression in turn and writes the resulting\nobject to standard output (see below). If an object is not a string,\nit is first converted to a string using the rules for string\nconversions. The (resulting or original) string is then written. A\nspace is written before each object is (converted and) written, unless\nthe output system believes it is positioned at the beginning of a\nline. This is the case (1) when no characters have yet been written\nto standard output, (2) when the last character written to standard\noutput is ``\'\\n\'``, or (3) when the last write operation on standard\noutput was not a ``print`` statement. (In some cases it may be\nfunctional to write an empty string to standard output for this\nreason.)\n\nNote: Objects which act like file objects but which are not the built-in\n file objects often do not properly emulate this aspect of the file\n object\'s behavior, so it is best not to rely on this.\n\nA ``\'\\n\'`` character is written at the end, unless the ``print``\nstatement ends with a comma. This is the only action if the statement\ncontains just the keyword ``print``.\n\nStandard output is defined as the file object named ``stdout`` in the\nbuilt-in module ``sys``. If no such object exists, or if it does not\nhave a ``write()`` method, a ``RuntimeError`` exception is raised.\n\n``print`` also has an extended form, defined by the second portion of\nthe syntax described above. This form is sometimes referred to as\n"``print`` chevron." In this form, the first expression after the\n``>>`` must evaluate to a "file-like" object, specifically an object\nthat has a ``write()`` method as described above. With this extended\nform, the subsequent expressions are printed to this file object. If\nthe first expression evaluates to ``None``, then ``sys.stdout`` is\nused as the file for output.\n', - 'raise': u'\nThe ``raise`` statement\n***********************\n\n raise_stmt ::= "raise" [expression ["," expression ["," 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 expressions to get three objects,\nusing ``None`` as the value of omitted expressions. The first two\nobjects are used to determine the *type* and *value* of the exception.\n\nIf the first object is an instance, the type of the exception is the\nclass of the instance, the instance itself is the value, and the\nsecond object must be ``None``.\n\nIf the first object is a class, it becomes the type of the exception.\nThe second object is used to determine the exception value: If it is\nan instance of the class, the instance becomes the exception value. If\nthe second object is a tuple, it is used as the argument list for the\nclass constructor; if it is ``None``, an empty argument list is used,\nand any other object is treated as a single argument to the\nconstructor. The instance so created by calling the constructor is\nused as the exception value.\n\nIf a third object is present and not ``None``, it must be a traceback\nobject (see section *The standard type hierarchy*), and it is\nsubstituted instead of the current location as the place where the\nexception occurred. If the third object is present and not a\ntraceback object or ``None``, a ``TypeError`` exception is raised.\nThe three-expression form of ``raise`` is useful to re-raise an\nexception transparently in an except clause, but ``raise`` with no\nexpressions should be preferred if the exception to be re-raised was\nthe most recently active exception in the current scope.\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', - 'return': u'\nThe ``return`` statement\n************************\n\n return_stmt ::= "return" [expression_list]\n\n``return`` may only occur syntactically nested in a function\ndefinition, not within a nested class definition.\n\nIf an expression list is present, it is evaluated, else ``None`` is\nsubstituted.\n\n``return`` leaves the current function call with the expression list\n(or ``None``) as return value.\n\nWhen ``return`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nleaving the function.\n\nIn a generator function, the ``return`` statement is not allowed to\ninclude an **expression_list**. In that context, a bare ``return``\nindicates that the generator is done and will cause ``StopIteration``\nto be raised.\n', - 'sequence-methods': u'\nAdditional methods for emulation of sequence types\n**************************************************\n\nThe following optional methods can be defined to further emulate\nsequence objects. Immutable sequences methods should at most only\ndefine ``__getslice__()``; mutable sequences might define all three\nmethods.\n\nobject.__getslice__(self, i, j)\n\n Deprecated since version 2.0: Support slice objects as parameters\n to the ``__getitem__()`` method. (However, built-in types in\n CPython currently still implement ``__getslice__()``. Therefore,\n you have to override it in derived classes when implementing\n slicing.)\n\n Called to implement evaluation of ``self[i:j]``. The returned\n object should be of the same type as *self*. Note that missing *i*\n or *j* in the slice expression are replaced by zero or\n ``sys.maxint``, respectively. If negative indexes are used in the\n slice, the length of the sequence is added to that index. If the\n instance does not implement the ``__len__()`` method, an\n ``AttributeError`` is raised. No guarantee is made that indexes\n adjusted this way are not still negative. Indexes which are\n greater than the length of the sequence are not modified. If no\n ``__getslice__()`` is found, a slice object is created instead, and\n passed to ``__getitem__()`` instead.\n\nobject.__setslice__(self, i, j, sequence)\n\n Called to implement assignment to ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``.\n\n This method is deprecated. If no ``__setslice__()`` is found, or\n for extended slicing of the form ``self[i:j:k]``, a slice object is\n created, and passed to ``__setitem__()``, instead of\n ``__setslice__()`` being called.\n\nobject.__delslice__(self, i, j)\n\n Called to implement deletion of ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``. This method is deprecated. If no\n ``__delslice__()`` is found, or for extended slicing of the form\n ``self[i:j:k]``, a slice object is created, and passed to\n ``__delitem__()``, instead of ``__delslice__()`` being called.\n\nNotice that these methods are only invoked when a single slice with a\nsingle colon is used, and the slice method is available. For slice\noperations involving extended slice notation, or in absence of the\nslice methods, ``__getitem__()``, ``__setitem__()`` or\n``__delitem__()`` is called with a slice object as argument.\n\nThe following example demonstrate how to make your program or module\ncompatible with earlier versions of Python (assuming that methods\n``__getitem__()``, ``__setitem__()`` and ``__delitem__()`` support\nslice objects as arguments):\n\n class MyClass:\n ...\n def __getitem__(self, index):\n ...\n def __setitem__(self, index, value):\n ...\n def __delitem__(self, index):\n ...\n\n if sys.version_info < (2, 0):\n # They won\'t be defined if version is at least 2.0 final\n\n def __getslice__(self, i, j):\n return self[max(0, i):max(0, j):]\n def __setslice__(self, i, j, seq):\n self[max(0, i):max(0, j):] = seq\n def __delslice__(self, i, j):\n del self[max(0, i):max(0, j):]\n ...\n\nNote the calls to ``max()``; these are necessary because of the\nhandling of negative indices before the ``__*slice__()`` methods are\ncalled. When negative indexes are used, the ``__*item__()`` methods\nreceive them as provided, but the ``__*slice__()`` methods get a\n"cooked" form of the index values. For each negative index value, the\nlength of the sequence is added to the index before calling the method\n(which may still result in a negative index); this is the customary\nhandling of negative indexes by the built-in sequence types, and the\n``__*item__()`` methods are expected to do this as well. However,\nsince they should already be doing that, negative indexes cannot be\npassed in; they must be constrained to the bounds of the sequence\nbefore being passed to the ``__*item__()`` methods. Calling ``max(0,\ni)`` conveniently returns the proper value.\n', - 'sequence-types': u"\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. (For backwards compatibility, the method\n``__getslice__()`` (see below) can also be defined to handle simple,\nbut not extended slices.) It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``has_key()``,\n``get()``, ``clear()``, ``setdefault()``, ``iterkeys()``,\n``itervalues()``, ``iteritems()``, ``pop()``, ``popitem()``,\n``copy()``, and ``update()`` behaving similar to those for Python's\nstandard dictionary objects. The ``UserDict`` module provides a\n``DictMixin`` class to help create those methods from a base set of\n``__getitem__()``, ``__setitem__()``, ``__delitem__()``, and\n``keys()``. Mutable sequences should provide methods ``append()``,\n``count()``, ``index()``, ``extend()``, ``insert()``, ``pop()``,\n``remove()``, ``reverse()`` and ``sort()``, like Python standard list\nobjects. Finally, sequence types should implement addition (meaning\nconcatenation) and multiplication (meaning repetition) by defining the\nmethods ``__add__()``, ``__radd__()``, ``__iadd__()``, ``__mul__()``,\n``__rmul__()`` and ``__imul__()`` described below; they should not\ndefine ``__coerce__()`` or other numerical operators. It is\nrecommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should be equivalent of ``has_key()``;\nfor sequences, 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``iterkeys()``; 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 ``__nonzero__()`` method and whose\n ``__len__()`` method returns zero is considered to be false in a\n Boolean context.\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 ``iterkeys()``.\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()`` builtin 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()`` builtin will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects should\n normally only provide ``__reversed__()`` if they do not support the\n sequence protocol and an efficient implementation of reverse\n iteration is possible.\n\n New in version 2.6.\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", - 'shifting': u'\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 plain or long integers as arguments. The\narguments are converted to a common type. 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,\nn)``. Negative shift counts raise a ``ValueError`` exception.\n', - 'slicings': u'\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 ::= simple_slicing | extended_slicing\n simple_slicing ::= primary "[" short_slice "]"\n extended_slicing ::= primary "[" slice_list "]"\n slice_list ::= slice_item ("," slice_item)* [","]\n slice_item ::= expression | proper_slice | ellipsis\n proper_slice ::= short_slice | long_slice\n short_slice ::= [lower_bound] ":" [upper_bound]\n long_slice ::= short_slice ":" [stride]\n lower_bound ::= expression\n upper_bound ::= expression\n stride ::= expression\n ellipsis ::= "..."\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 nor ellipses). Similarly, when the slice\nlist has exactly one short slice and no trailing comma, the\ninterpretation as a simple slicing takes priority over that as an\nextended slicing.\n\nThe semantics for a simple slicing are as follows. The primary must\nevaluate to a sequence object. The lower and upper bound expressions,\nif present, must evaluate to plain integers; defaults are zero and the\n``sys.maxint``, respectively. If either bound is negative, the\nsequence\'s length is added to it. The slicing now selects all items\nwith index *k* such that ``i <= k < j`` where *i* and *j* are the\nspecified lower and upper bounds. This may be an empty sequence. It\nis not an error if *i* or *j* lie outside the range of valid indexes\n(such items don\'t exist so they aren\'t selected).\n\nThe semantics for an extended slicing are as follows. The primary\nmust evaluate to a mapping object, and it is indexed with a key that\nis constructed 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 an ellipsis slice\nitem is the built-in ``Ellipsis`` object. The conversion of a proper\nslice is a slice object (see section *The standard type hierarchy*)\nwhose ``start``, ``stop`` and ``step`` attributes are the values of\nthe expressions given as lower bound, upper bound and stride,\nrespectively, substituting ``None`` for missing expressions.\n', - 'specialattrs': u"\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\nobject.__methods__\n\n Deprecated since version 2.2: Use the built-in function ``dir()``\n to get a list of an object's attributes. This attribute is no\n longer available.\n\nobject.__members__\n\n Deprecated since version 2.2: Use the built-in function ``dir()``\n to get a list of an object's attributes. This attribute is no\n longer available.\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. If there are no base\n classes, this will be an empty tuple.\n\nclass.__name__\n\n The name of the class or type.\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\n[5] These numbers are fairly arbitrary. They are intended to avoid\n printing endless strings of meaningless digits without hampering\n correct use and without having to know the exact precision of\n floating point values on a particular machine.\n\n[6] The advantage of leaving the newline on is that returning an empty\n string is then an unambiguous EOF indication. It is also possible\n (in cases where it might matter, for example, if you want to make\n an exact copy of a file while scanning its lines) to tell whether\n the last line of a file ended in a newline or not (yes this\n happens!).\n", - 'specialnames': u'\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 ``x.__getitem__(i)`` for\nold-style classes and ``type(x).__getitem__(x, i)`` for new-style\nclasses. Except where mentioned, attempts to execute an operation\nraise an 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_traceback`` 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.exc_traceback`` or ``sys.last_traceback``. Circular\n references which are garbage are detected when the option cycle\n detector is enabled (it\'s on by default), but can only be cleaned\n up if there are no Python-level ``__del__()`` methods involved.\n Refer to the documentation for the ``gc`` module for more\n information about how ``__del__()`` methods are handled by the\n cycle detector, particularly the description of the ``garbage``\n 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. For this reason, ``__del__()`` methods should do\n the absolute minimum needed to maintain external invariants.\n Starting with version 1.5, Python guarantees that globals whose\n name begins with a single underscore are deleted from their\n module before other globals are deleted; if no other references\n to such globals exist, this may help in assuring that imported\n modules are still available at the time when the ``__del__()``\n method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is 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 statement 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.__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 New in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` call ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and\n ``x>=y`` calls ``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\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by ``__cmp__()`` has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\n\nobject.__hash__(self)\n\n Called for the key object for dictionary operations, and by the\n built-in function ``hash()``. Should return an integer usable as a\n hash value for dictionary operations. The only required property\n is that objects which compare equal have the same hash value; it is\n advised to somehow mix together (e.g., using exclusive or) the hash\n values for the components of the object that also play a part in\n comparison of objects.\n\n If a class does not define a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable as dictionary keys. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n the dictionary implementation requires that a key\'s hash value is\n immutable (if the object\'s hash value changes, it will be in the\n wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` 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 ``__cmp__()`` or ``__eq__()`` such that\n the hash value returned is no longer appropriate (e.g. by switching\n to a value-based concept of equality instead of the default\n identity based equality) can explicitly flag themselves as being\n unhashable by setting ``__hash__ = None`` in the class definition.\n Doing so means that not only will instances of the class raise an\n appropriate ``TypeError`` when a program attempts to retrieve their\n hash value, but they will also be correctly identified as\n unhashable when checking ``isinstance(obj, collections.Hashable)``\n (unlike classes which define their own ``__hash__()`` to explicitly\n raise ``TypeError``).\n\n Changed in version 2.5: ``__hash__()`` may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\n Changed in version 2.6: ``__hash__`` may now be set to ``None`` to\n explicitly flag instances of a class as unhashable.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing, and the built-in operation\n ``bool()``; should return ``False`` or ``True``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined (see below). If a class\n defines neither ``__len__()`` nor ``__nonzero__()``, all its\n instances are considered true.\n\nobject.__unicode__(self)\n\n Called to implement ``unicode()`` builtin; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\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 in new-style classes.\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 not simply execute ``self.name = value`` --- this would\n cause a recursive call to itself. Instead, it should insert the\n value in the dictionary of instance attributes, e.g.,\n ``self.__dict__[name] = value``. For new-style classes, rather\n than accessing the instance dictionary, it should call the base\n 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\n\nMore attribute access for new-style classes\n-------------------------------------------\n\nThe following methods only apply to new-style classes.\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 builtin functions. See *Special method lookup for new-style\n classes*.\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 new-style class, known as the *owner*\nclass. In the examples below, "the attribute" refers to the attribute\nwhose name is the key of the property in the owner class\'\n``__dict__``. Descriptors can only be implemented as new-style\nclasses themselves.\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. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass ``object()`` or\n``type()``).\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 a new-style object instance, ``a.x`` is transformed\n into the call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a new-style class, ``A.x`` is transformed into the\n call: ``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. Normally, data\ndescriptors define both ``__get__()`` and ``__set__()``, while non-\ndata descriptors have just the ``__get__()`` method. Data descriptors\nalways override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances. [2]\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 both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__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 new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n New in version 2.2.\n\nNotes on using *__slots__*\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 Changed in version 2.3: Previously, adding ``\'__dict__\'`` to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\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 Changed in version 2.3: Previously, adding ``\'__weakref__\'`` to the\n *__slots__* declaration would not enable support for weak\n references.\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* 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* 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__*.\n\n* *__slots__* do not work for classes derived from "variable-length"\n built-in types such as ``long``, ``str`` and ``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 Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, new-style classes are constructed using ``type()``. A\nclass definition is read into a separate namespace and the value of\nclass name is bound to the result of ``type(name, bases, dict)``.\n\nWhen the class definition is read, if *__metaclass__* is defined then\nthe callable assigned to it will be called instead of ``type()``. 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\n__metaclass__\n\n This variable can be any callable accepting arguments for ``name``,\n ``bases``, and ``dict``. Upon class creation, the callable is used\n instead of the built-in ``type()``.\n\n New in version 2.2.\n\nThe appropriate metaclass is determined by the following precedence\nrules:\n\n* If ``dict[\'__metaclass__\']`` exists, it is used.\n\n* Otherwise, if there is at least one base class, its metaclass is\n used (this looks for a *__class__* attribute first and if not found,\n uses its type).\n\n* Otherwise, if a global variable named __metaclass__ exists, it is\n used.\n\n* Otherwise, the old-style, classic metaclass (types.ClassType) is\n 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\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. (For backwards compatibility, the method\n``__getslice__()`` (see below) can also be defined to handle simple,\nbut not extended slices.) It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``has_key()``,\n``get()``, ``clear()``, ``setdefault()``, ``iterkeys()``,\n``itervalues()``, ``iteritems()``, ``pop()``, ``popitem()``,\n``copy()``, and ``update()`` behaving similar to those for Python\'s\nstandard dictionary objects. The ``UserDict`` module provides a\n``DictMixin`` class to help create those methods from a base set of\n``__getitem__()``, ``__setitem__()``, ``__delitem__()``, and\n``keys()``. Mutable sequences should provide methods ``append()``,\n``count()``, ``index()``, ``extend()``, ``insert()``, ``pop()``,\n``remove()``, ``reverse()`` and ``sort()``, like Python standard list\nobjects. Finally, sequence types should implement addition (meaning\nconcatenation) and multiplication (meaning repetition) by defining the\nmethods ``__add__()``, ``__radd__()``, ``__iadd__()``, ``__mul__()``,\n``__rmul__()`` and ``__imul__()`` described below; they should not\ndefine ``__coerce__()`` or other numerical operators. It is\nrecommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should be equivalent of ``has_key()``;\nfor sequences, 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``iterkeys()``; 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 ``__nonzero__()`` method and whose\n ``__len__()`` method returns zero is considered to be false in a\n Boolean context.\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 ``iterkeys()``.\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()`` builtin 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()`` builtin will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects should\n normally only provide ``__reversed__()`` if they do not support the\n sequence protocol and an efficient implementation of reverse\n iteration is possible.\n\n New in version 2.6.\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\nAdditional methods for emulation of sequence types\n==================================================\n\nThe following optional methods can be defined to further emulate\nsequence objects. Immutable sequences methods should at most only\ndefine ``__getslice__()``; mutable sequences might define all three\nmethods.\n\nobject.__getslice__(self, i, j)\n\n Deprecated since version 2.0: Support slice objects as parameters\n to the ``__getitem__()`` method. (However, built-in types in\n CPython currently still implement ``__getslice__()``. Therefore,\n you have to override it in derived classes when implementing\n slicing.)\n\n Called to implement evaluation of ``self[i:j]``. The returned\n object should be of the same type as *self*. Note that missing *i*\n or *j* in the slice expression are replaced by zero or\n ``sys.maxint``, respectively. If negative indexes are used in the\n slice, the length of the sequence is added to that index. If the\n instance does not implement the ``__len__()`` method, an\n ``AttributeError`` is raised. No guarantee is made that indexes\n adjusted this way are not still negative. Indexes which are\n greater than the length of the sequence are not modified. If no\n ``__getslice__()`` is found, a slice object is created instead, and\n passed to ``__getitem__()`` instead.\n\nobject.__setslice__(self, i, j, sequence)\n\n Called to implement assignment to ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``.\n\n This method is deprecated. If no ``__setslice__()`` is found, or\n for extended slicing of the form ``self[i:j:k]``, a slice object is\n created, and passed to ``__setitem__()``, instead of\n ``__setslice__()`` being called.\n\nobject.__delslice__(self, i, j)\n\n Called to implement deletion of ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``. This method is deprecated. If no\n ``__delslice__()`` is found, or for extended slicing of the form\n ``self[i:j:k]``, a slice object is created, and passed to\n ``__delitem__()``, instead of ``__delslice__()`` being called.\n\nNotice that these methods are only invoked when a single slice with a\nsingle colon is used, and the slice method is available. For slice\noperations involving extended slice notation, or in absence of the\nslice methods, ``__getitem__()``, ``__setitem__()`` or\n``__delitem__()`` is called with a slice object as argument.\n\nThe following example demonstrate how to make your program or module\ncompatible with earlier versions of Python (assuming that methods\n``__getitem__()``, ``__setitem__()`` and ``__delitem__()`` support\nslice objects as arguments):\n\n class MyClass:\n ...\n def __getitem__(self, index):\n ...\n def __setitem__(self, index, value):\n ...\n def __delitem__(self, index):\n ...\n\n if sys.version_info < (2, 0):\n # They won\'t be defined if version is at least 2.0 final\n\n def __getslice__(self, i, j):\n return self[max(0, i):max(0, j):]\n def __setslice__(self, i, j, seq):\n self[max(0, i):max(0, j):] = seq\n def __delslice__(self, i, j):\n del self[max(0, i):max(0, j):]\n ...\n\nNote the calls to ``max()``; these are necessary because of the\nhandling of negative indices before the ``__*slice__()`` methods are\ncalled. When negative indexes are used, the ``__*item__()`` methods\nreceive them as provided, but the ``__*slice__()`` methods get a\n"cooked" form of the index values. For each negative index value, the\nlength of the sequence is added to the index before calling the method\n(which may still result in a negative index); this is the customary\nhandling of negative indexes by the built-in sequence types, and the\n``__*item__()`` methods are expected to do this as well. However,\nsince they should already be doing that, negative indexes cannot be\npassed in; they must be constrained to the bounds of the sequence\nbefore being passed to the ``__*item__()`` methods. Calling ``max(0,\ni)`` conveniently returns the proper value.\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.__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 (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression ``x + y``, where *x* is an\n 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__()`` (described below). Note\n that ``__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.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(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 (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [3] For instance, to evaluate\n the expression ``x - y``, where *y* is an instance of a class that\n has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *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.__idiv__(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 operations (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\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 operation falls back to the normal methods. For instance, to\n evaluate the expression ``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.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``long()``, and ``float()``. Should return a value of\n the appropriate type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions ``oct()`` and ``hex()``.\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n New in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or ``None`` if conversion is impossible. When\n the common type would be the type of ``other``, it is sufficient to\n return ``None``, since the interpreter will also ask the other\n object to attempt a coercion (but sometimes, if the implementation\n of the other type cannot be changed, it is useful to do the\n conversion to the other type here). A return value of\n ``NotImplemented`` is equivalent to returning ``None``.\n\n\nCoercion rules\n==============\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3.0, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don\'t define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from ``object``) never invoke the\n ``__coerce__()`` method in response to a binary operator; the only\n time ``__coerce__()`` is invoked is when the built-in function\n ``coerce()`` is called.\n\n* For most intents and purposes, an operator that returns\n ``NotImplemented`` is treated the same as one that is not\n implemented at all.\n\n* Below, ``__op__()`` and ``__rop__()`` are used to signify the\n generic method names corresponding to an operator; ``__iop__()`` is\n used for the corresponding in-place operator. For example, for the\n operator \'``+``\', ``__add__()`` and ``__radd__()`` are used for the\n left and right variant of the binary operator, and ``__iadd__()``\n for the in-place variant.\n\n* For objects *x* and *y*, first ``x.__op__(y)`` is tried. If this is\n not implemented or returns ``NotImplemented``, ``y.__rop__(x)`` is\n tried. If this is also not implemented or returns\n ``NotImplemented``, a ``TypeError`` exception is raised. But see\n the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base\'s ``__rop__()`` method, the right operand\'s ``__rop__()``\n method is tried *before* the left operand\'s ``__op__()`` method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand\'s ``__op__()`` method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is called\n before that type\'s ``__op__()`` or ``__rop__()`` method is called,\n but no sooner. If the coercion returns an object of a different\n type for the operand whose coercion is invoked, part of the process\n is redone using the new object.\n\n* When an in-place operator (like \'``+=``\') is used, if the left\n operand implements ``__iop__()``, it is invoked without any\n coercion. When the operation falls back to ``__op__()`` and/or\n ``__rop__()``, the normal coercion rules apply.\n\n* In ``x + y``, if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In ``x * y``, if one operator is a sequence that implements sequence\n repetition, and the other is an integer (``int`` or ``long``),\n sequence repetition is invoked.\n\n* Rich comparisons (implemented by methods ``__eq__()`` and so on)\n never use coercion. Three-way comparison (implemented by\n ``__cmp__()``) does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types ``int``,\n ``long`` and ``float`` do not use coercion; the type ``complex``\n however does use it. The difference can become apparent when\n subclassing these types. Over time, the type ``complex`` may be\n fixed to avoid coercion. All these types implement a\n ``__coerce__()`` method, for use by the built-in ``coerce()``\n function.\n\n\nWith Statement Context Managers\n===============================\n\nNew in version 2.5.\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 for old-style classes\n===========================================\n\nFor old-style classes, special methods are always looked up in exactly\nthe same way as any other method or attribute. This is the case\nregardless of whether the method is being looked up explicitly as in\n``x.__getitem__(i)`` or implicitly as in ``x[i]``.\n\nThis behaviour means that special methods may exhibit different\nbehaviour for different instances of a single old-style class if the\nappropriate special attributes are set differently:\n\n >>> class C:\n ... pass\n ...\n >>> c1 = C()\n >>> c2 = C()\n >>> c1.__len__ = lambda: 5\n >>> c2.__len__ = lambda: 9\n >>> len(c1)\n 5\n >>> len(c2)\n 9\n\n\nSpecial method lookup for new-style classes\n===========================================\n\nFor new-style classes, implicit invocations of special methods are\nonly guaranteed to work correctly if defined on an object\'s type, not\nin the object\'s instance dictionary. That behaviour is the reason why\nthe following code raises an exception (unlike the equivalent example\nwith old-style classes):\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 may also bypass the\n``__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):\n ... __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] A descriptor can define any combination of ``__get__()``,\n ``__set__()`` and ``__delete__()``. If it does not define\n ``__get__()``, then accessing the attribute even on an instance\n will return the descriptor object itself. If the descriptor\n defines ``__set__()`` and/or ``__delete__()``, it is a data\n descriptor; if it defines neither, it is a non-data descriptor.\n\n[3] 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-conversions': u'\nString conversions\n******************\n\nA string conversion is an expression list enclosed in reverse (a.k.a.\nbackward) quotes:\n\n string_conversion ::= "\'" expression_list "\'"\n\nA string conversion evaluates the contained expression list and\nconverts the resulting object into a string according to rules\nspecific to its type.\n\nIf the object is a string, a number, ``None``, or a tuple, list or\ndictionary containing only objects whose type is one of these, the\nresulting string is a valid Python expression which can be passed to\nthe built-in function ``eval()`` to yield an expression with the same\nvalue (or an approximation, if floating point numbers are involved).\n\n(In particular, converting a string adds quotes around it and converts\n"funny" characters to escape sequences that are safe to print.)\n\nRecursive objects (for example, lists or dictionaries that contain a\nreference to themselves, directly or indirectly) use ``...`` to\nindicate a recursive reference, and the result cannot be passed to\n``eval()`` to get an equal value (``SyntaxError`` will be raised\ninstead).\n\nThe built-in function ``repr()`` performs exactly the same conversion\nin its argument as enclosing it in parentheses and reverse quotes\ndoes. The built-in function ``str()`` performs a similar but more\nuser-friendly conversion.\n', - 'string-methods': u'\nString Methods\n**************\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Note that none of these methods take keyword\narguments.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbuffer, xrange* section. To output formatted strings use template\nstrings or the ``%`` operator described in the *String Formatting\nOperations* 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 only its first character\n capitalized.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of occurrences of substring *sub* in the range\n [*start*, *end*]. Optional arguments *start* and *end* are\n interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes 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\n Changed in version 2.5: Accept tuples as *suffix*.\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 range [*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(format_string, *args, **kwargs)\n\n Perform a string formatting operation. The *format_string*\n argument can contain literal text or replacement fields delimited\n by braces ``{}``. Each replacement field contains either the\n numeric index of a positional argument, or the name of a keyword\n argument. Returns a copy of *format_string* where each replacement\n field is replaced with the string value of the corresponding\n 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\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(seq)\n\n Return a string which is the concatenation of the strings in the\n sequence *seq*. The separator between elements is the string\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n New in version 2.5.\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]. Optional\n arguments *start* and *end* are interpreted as in slice notation.\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\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\n New in version 2.5.\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\n New in version 2.4.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n Changed in version 2.5: Accept tuples as *prefix*.\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\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string: words start with\n uppercase characters, all remaining cased characters are lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\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 New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n', - 'strings': u'\nString literals\n***************\n\nString literals are described by the following lexical definitions:\n\n stringliteral ::= [stringprefix](shortstring | longstring)\n stringprefix ::= "r" | "u" | "ur" | "R" | "U" | "UR" | "Ur" | "uR"\n shortstring ::= "\'" shortstringitem* "\'" | \'"\' shortstringitem* \'"\'\n longstring ::= "\'\'\'" longstringitem* "\'\'\'"\n | \'"""\' longstringitem* \'"""\'\n shortstringitem ::= shortstringchar | escapeseq\n longstringitem ::= longstringchar | escapeseq\n shortstringchar ::= \n longstringchar ::= \n escapeseq ::= "\\" \n\nOne syntactic restriction not indicated by these productions is that\nwhitespace is not allowed between the **stringprefix** and the rest of\nthe string literal. The source character set is defined by the\nencoding declaration; it is ASCII if no encoding declaration is given\nin the source file; see section *Encoding declarations*.\n\nIn plain English: String literals can be enclosed in matching single\nquotes (``\'``) or double quotes (``"``). They can also be enclosed in\nmatching groups of three single or double quotes (these are generally\nreferred to as *triple-quoted strings*). The backslash (``\\``)\ncharacter is used to escape characters that otherwise have a special\nmeaning, such as newline, backslash itself, or the quote character.\nString literals may optionally be prefixed with a letter ``\'r\'`` or\n``\'R\'``; such strings are called *raw strings* and use different rules\nfor interpreting backslash escape sequences. A prefix of ``\'u\'`` or\n``\'U\'`` makes the string a Unicode string. Unicode strings use the\nUnicode character set as defined by the Unicode Consortium and ISO\n10646. Some additional escape sequences, described below, are\navailable in Unicode strings. The two prefix characters may be\ncombined; in this case, ``\'u\'`` must appear before ``\'r\'``.\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`` | 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| ``\\N{name}`` | Character named *name* in the | |\n| | Unicode database (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\r`` | ASCII Carriage Return (CR) | |\n+-------------------+-----------------------------------+---------+\n| ``\\t`` | ASCII Horizontal Tab (TAB) | |\n+-------------------+-----------------------------------+---------+\n| ``\\uxxxx`` | Character with 16-bit hex value | (1) |\n| | *xxxx* (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\Uxxxxxxxx`` | Character with 32-bit hex value | (2) |\n| | *xxxxxxxx* (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\v`` | ASCII Vertical Tab (VT) | |\n+-------------------+-----------------------------------+---------+\n| ``\\ooo`` | Character with octal value *ooo* | (3,5) |\n+-------------------+-----------------------------------+---------+\n| ``\\xhh`` | Character with hex value *hh* | (4,5) |\n+-------------------+-----------------------------------+---------+\n\nNotes:\n\n1. Individual code units which form parts of a surrogate pair can be\n encoded using this escape sequence.\n\n2. 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). Individual code units which form parts of a surrogate\n pair can be encoded using this escape sequence.\n\n3. As in Standard C, up to three octal digits are accepted.\n\n4. Unlike in Standard C, exactly two hex digits are required.\n\n5. In a string literal, hexadecimal and octal escapes denote the byte\n with the given value; it is not necessary that the byte encodes a\n character in the source character set. In a Unicode literal, these\n escapes denote a Unicode character with the given value.\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 marked as "(Unicode only)"\nin the table above fall into the category of unrecognized escapes for\nnon-Unicode string literals.\n\nWhen an ``\'r\'`` or ``\'R\'`` prefix is present, a character following a\nbackslash is included in the string without change, and *all\nbackslashes are left in the string*. For example, the string literal\n``r"\\n"`` consists of two characters: a backslash and a lowercase\n``\'n\'``. String quotes can be escaped with a backslash, but the\nbackslash remains in the string; for example, ``r"\\""`` is a valid\nstring literal consisting of two characters: a backslash and a double\nquote; ``r"\\"`` is not a valid string literal (even a raw string\ncannot end in an odd number of backslashes). Specifically, *a raw\nstring cannot end in a single backslash* (since the backslash would\nescape 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\nWhen an ``\'r\'`` or ``\'R\'`` prefix is used in conjunction with a\n``\'u\'`` or ``\'U\'`` prefix, then the ``\\uXXXX`` and ``\\UXXXXXXXX``\nescape sequences are processed while *all other backslashes are left\nin the string*. For example, the string literal ``ur"\\u0062\\n"``\nconsists of three Unicode characters: \'LATIN SMALL LETTER B\', \'REVERSE\nSOLIDUS\', and \'LATIN SMALL LETTER N\'. Backslashes can be escaped with\na preceding backslash; however, both remain in the string. As a\nresult, ``\\uXXXX`` escape sequences are only recognized when there are\nan odd number of backslashes.\n', - 'subscriptions': u'\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 of a sequence or mapping type.\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 a\nplain integer. If this value is negative, the length of the sequence\nis added to it (so that, e.g., ``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).\n\nA string\'s items are characters. A character is not a separate data\ntype but a string of exactly one character.\n', - 'truth': u"\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``, ``0L``, ``0.0``,\n ``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 ``__nonzero__()`` or ``__len__()`` method, when that method returns\n the 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", - 'try': u'\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 ["," target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nChanged in version 2.5: In previous versions of Python,\n``try``...``except``...``finally`` did not work. ``try``...``except``\nhad to be nested in ``try``...``finally``.\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, a tuple containing an item compatible with the\nexception, or, in the (deprecated) case of string exceptions, is the\nraised string itself (note that the object identities must match, i.e.\nit must be the same string object, not just a string with the same\nvalue).\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 in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the ``sys`` module:\n``sys.exc_type`` receives the object identifying the exception;\n``sys.exc_value`` receives the exception\'s parameter;\n``sys.exc_traceback`` receives a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. These details are also available through the\n``sys.exc_info()`` function, which returns a tuple ``(exc_type,\nexc_value, exc_traceback)``. Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables 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', - 'types': u'\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.).\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name ``None``.\n It is used to signify the absence of a value in many situations,\n e.g., it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``NotImplemented``. Numeric methods and rich comparison methods may\n return this value if they do not implement the operation for the\n operands provided. (The interpreter will then try the reflected\n operation, or some other fallback, depending on the operator.) Its\n truth value is true.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``Ellipsis``. It is used to indicate the presence of the ``...``\n syntax in a slice. Its truth value is true.\n\n``numbers.Number``\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n ``numbers.Integral``\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are three types of integers:\n\n Plain integers\n These represent numbers in the range -2147483648 through\n 2147483647. (The range may be larger on machines with a\n larger natural word size, but not smaller.) When the result\n of an operation would fall outside this range, the result is\n normally returned as a long integer (in some cases, the\n exception ``OverflowError`` is raised instead). For the\n purpose of shift and mask operations, integers are assumed to\n have a binary, 2\'s complement notation using 32 or more bits,\n and hiding no bits from the user (i.e., all 4294967296\n different bit patterns correspond to different values).\n\n Long integers\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans\n These represent the truth values False and True. The two\n objects representing the values False and True are the only\n Boolean objects. The Boolean type is a subtype of plain\n integers, and Boolean values behave like the values 0 and 1,\n respectively, in almost all contexts, the exception being\n that when converted to a string, the strings ``"False"`` or\n ``"True"`` are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers and the least surprises when\n switching between the plain and long integer domains. Any\n operation, if it yields a result in the plain integer domain,\n will yield the same result in the long integer domain or when\n using mixed operands. The switch between domains is transparent\n to the programmer.\n\n ``numbers.Real`` (``float``)\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these is\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n ``numbers.Complex``\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number ``z`` can be retrieved through the read-only\n attributes ``z.real`` and ``z.imag``.\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function ``len()`` returns the number of\n items of a sequence. When the length of a sequence is *n*, the\n index set contains the numbers 0, 1, ..., *n*-1. Item *i* of\n sequence *a* is selected by ``a[i]``.\n\n Sequences also support slicing: ``a[i:j]`` selects all items with\n index *k* such that *i* ``<=`` *k* ``<`` *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: ``a[i:j:k]`` selects all items of *a* with index *x*\n where ``x = i + n*k``, *n* ``>=`` ``0`` and *i* ``<=`` *x* ``<``\n *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n The items of a string are characters. There is no separate\n character type; a character is represented by a string of one\n item. Characters represent (at least) 8-bit bytes. The\n built-in functions ``chr()`` and ``ord()`` convert between\n characters and nonnegative integers representing the byte\n values. Bytes with the values 0-127 usually represent the\n corresponding ASCII values, but the interpretation of values\n is up to the program. The string data type is also used to\n represent arrays of bytes, e.g., to hold data read from a\n file.\n\n (On systems whose native character set is not ASCII, strings\n may use EBCDIC in their internal representation, provided the\n functions ``chr()`` and ``ord()`` implement a mapping between\n ASCII and EBCDIC, and string comparison preserves the ASCII\n order. Or perhaps someone can propose a better rule?)\n\n Unicode\n The items of a Unicode object are Unicode code units. A\n Unicode code unit is represented by a Unicode object of one\n item and can hold either a 16-bit or 32-bit value\n representing a Unicode ordinal (the maximum value for the\n ordinal is given in ``sys.maxunicode``, and depends on how\n Python is configured at compile time). Surrogate pairs may\n be present in the Unicode object, and will be reported as two\n separate items. The built-in functions ``unichr()`` and\n ``ord()`` convert between code units and nonnegative integers\n representing the Unicode ordinals as defined in the Unicode\n Standard 3.0. Conversion from and to other encodings are\n possible through the Unicode method ``encode()`` and the\n built-in function ``unicode()``.\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and ``del`` (delete) statements.\n\n There is currently a single intrinsic mutable sequence type:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n The extension module ``array`` provides an additional example of\n a mutable sequence type.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function ``len()``\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n ``set()`` constructor and can be modified afterwards by several\n methods, such as ``add()``.\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in ``frozenset()`` constructor. As a frozenset is\n immutable and *hashable*, it can be used again as an element of\n another set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation ``a[k]`` selects the item indexed by\n ``k`` from the mapping ``a``; this can be used in expressions and\n as the target of assignments or ``del`` statements. The built-in\n function ``len()`` returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``) then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the ``{...}``\n notation (see section *Dictionary displays*).\n\n The extension modules ``dbm``, ``gdbm``, and ``bsddb`` provide\n additional examples of mapping types.\n\nCallable types\n These are the types to which the function call operation (see\n section *Calls*) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section *Function definitions*). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +-------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +=========================+=================================+=============+\n | ``func_doc`` | The function\'s documentation | Writable |\n | | string, or ``None`` if | |\n | | unavailable | |\n +-------------------------+---------------------------------+-------------+\n | ``__doc__`` | Another way of spelling | Writable |\n | | ``func_doc`` | |\n +-------------------------+---------------------------------+-------------+\n | ``func_name`` | The function\'s name | Writable |\n +-------------------------+---------------------------------+-------------+\n | ``__name__`` | Another way of spelling | Writable |\n | | ``func_name`` | |\n +-------------------------+---------------------------------+-------------+\n | ``__module__`` | The name of the module the | Writable |\n | | function was defined in, or | |\n | | ``None`` if unavailable. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_defaults`` | A tuple containing default | Writable |\n | | argument values for those | |\n | | arguments that have defaults, | |\n | | or ``None`` if no arguments | |\n | | have a default value | |\n +-------------------------+---------------------------------+-------------+\n | ``func_code`` | The code object representing | Writable |\n | | the compiled function body. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_globals`` | A reference to the dictionary | Read-only |\n | | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_dict`` | The namespace supporting | Writable |\n | | arbitrary function attributes. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_closure`` | ``None`` or a tuple of cells | Read-only |\n | | that contain bindings for the | |\n | | function\'s free variables. | |\n +-------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Changed in version 2.4: ``func_name`` is now writable.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n User-defined methods\n A user-defined method object combines a class, a class instance\n (or ``None``) and any callable object (normally a user-defined\n function).\n\n Special read-only attributes: ``im_self`` is the class instance\n object, ``im_func`` is the function object; ``im_class`` is the\n class of ``im_self`` for bound methods or the class that asked\n for the method for unbound methods; ``__doc__`` is the method\'s\n documentation (same as ``im_func.__doc__``); ``__name__`` is the\n method name (same as ``im_func.__name__``); ``__module__`` is\n the name of the module the method was defined in, or ``None`` if\n unavailable.\n\n Changed in version 2.2: ``im_self`` used to refer to the class\n that defined the method.\n\n Changed in version 2.6: For 3.0 forward-compatibility,\n ``im_func`` is also available as ``__func__``, and ``im_self``\n as ``__self__``.\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object, an unbound\n user-defined method object, or a class method object. When the\n attribute is a user-defined method object, a new method object\n is only created if the class from which it is being retrieved is\n the same as, or a derived class of, the class stored in the\n original method object; otherwise, the original method object is\n used as it is.\n\n When a user-defined method object is created by retrieving a\n user-defined function object from a class, its ``im_self``\n attribute is ``None`` and the method object is said to be\n unbound. When one is created by retrieving a user-defined\n function object from a class via one of its instances, its\n ``im_self`` attribute is the instance, and the method object is\n said to be bound. In either case, the new method\'s ``im_class``\n attribute is the class from which the retrieval takes place, and\n its ``im_func`` attribute is the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the ``im_func``\n attribute of the new instance is not the original method object\n but its ``im_func`` attribute.\n\n When a user-defined method object is created by retrieving a\n class method object from a class or instance, its ``im_self``\n attribute is the class itself (the same as the ``im_class``\n attribute), and its ``im_func`` attribute is the function object\n underlying the class method.\n\n When an unbound user-defined method object is called, the\n underlying function (``im_func``) is called, with the\n restriction that the first argument must be an instance of the\n proper class (``im_class``) or of a derived class thereof.\n\n When a bound user-defined method object is called, the\n underlying function (``im_func``) is called, inserting the class\n instance (``im_self``) in front of the argument list. For\n instance, when ``C`` is a class which contains a definition for\n a function ``f()``, and ``x`` is an instance of ``C``, calling\n ``x.f(1)`` is equivalent to calling ``C.f(x, 1)``.\n\n When a user-defined method object is derived from a class method\n object, the "class instance" stored in ``im_self`` will actually\n be the class itself, so that calling either ``x.f(1)`` or\n ``C.f(1)`` is equivalent to calling ``f(C,1)`` where ``f`` is\n the underlying function.\n\n Note that the transformation from function object to (unbound or\n bound) method object happens each time the attribute is\n retrieved from the class or instance. In some cases, a fruitful\n optimization is to assign the attribute to a local variable and\n call that local variable. Also notice that this transformation\n only happens for user-defined functions; other callable objects\n (and all non-callable objects) are retrieved without\n transformation. It is also important to note that user-defined\n functions which are attributes of a class instance are not\n converted to bound methods; this *only* happens when the\n function is an attribute of the class.\n\n Generator functions\n A function or method which uses the ``yield`` statement (see\n section *The yield statement*) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s ``next()`` method will cause the function to\n execute until it provides a value using the ``yield`` statement.\n When the function executes a ``return`` statement or falls off\n the end, a ``StopIteration`` exception is raised and the\n iterator will have reached the end of the set of values to be\n returned.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are ``len()`` and ``math.sin()``\n (``math`` is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: ``__doc__`` is the function\'s documentation\n string, or ``None`` if unavailable; ``__name__`` is the\n function\'s name; ``__self__`` is set to ``None`` (but see the\n next item); ``__module__`` is the name of the module the\n function was defined in or ``None`` if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n ``alist.append()``, assuming *alist* is a list object. In this\n case, the special read-only attribute ``__self__`` is set to the\n object denoted by *list*.\n\n Class Types\n Class types, or "new-style classes," are callable. These\n objects normally act as factories for new instances of\n themselves, but variations are possible for class types that\n override ``__new__()``. The arguments of the call are passed to\n ``__new__()`` and, in the typical case, to ``__init__()`` to\n initialize the new instance.\n\n Classic Classes\n Class objects are described below. When a class object is\n called, a new class instance (also described below) is created\n and returned. This implies a call to the class\'s ``__init__()``\n method if it has one. Any arguments are passed on to the\n ``__init__()`` method. If there is no ``__init__()`` method,\n the class must be called without arguments.\n\n Class instances\n Class instances are described below. Class instances are\n callable only when the class has a ``__call__()`` method;\n ``x(arguments)`` is a shorthand for ``x.__call__(arguments)``.\n\nModules\n Modules are imported by the ``import`` statement (see section *The\n import statement*). A module object has a namespace implemented by\n a dictionary object (this is the dictionary referenced by the\n func_globals attribute of functions defined in the module).\n Attribute references are translated to lookups in this dictionary,\n e.g., ``m.x`` is equivalent to ``m.__dict__["x"]``. A module object\n does not contain the code object used to initialize the module\n (since it isn\'t needed once the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``.\n\n Special read-only attribute: ``__dict__`` is the module\'s namespace\n as a dictionary object.\n\n Predefined (writable) attributes: ``__name__`` is the module\'s\n name; ``__doc__`` is the module\'s documentation string, or ``None``\n if unavailable; ``__file__`` is the pathname of the file from which\n the module was loaded, if it was loaded from a file. The\n ``__file__`` attribute is not present for C modules that are\n statically linked into the interpreter; for extension modules\n loaded dynamically from a shared library, it is the pathname of the\n shared library file.\n\nClasses\n Both class types (new-style classes) and class objects (old-\n style/classic classes) are typically created by class definitions\n (see section *Class definitions*). A class has a namespace\n implemented by a dictionary object. Class attribute references are\n translated to lookups in this dictionary, e.g., ``C.x`` is\n translated to ``C.__dict__["x"]`` (although for new-style classes\n in particular there are a number of hooks which allow for other\n means of locating attributes). When the attribute name is not found\n there, the attribute search continues in the base classes. For\n old-style classes, the search is depth-first, left-to-right in the\n order of occurrence in the base class list. New-style classes use\n the more complex C3 method resolution order which behaves correctly\n even in the presence of \'diamond\' inheritance structures where\n there are multiple inheritance paths leading back to a common\n ancestor. Additional details on the C3 MRO used by new-style\n classes can be found in the documentation accompanying the 2.3\n release at http://www.python.org/download/releases/2.3/mro/.\n\n When a class attribute reference (for class ``C``, say) would yield\n a user-defined function object or an unbound user-defined method\n object whose associated class is either ``C`` or one of its base\n classes, it is transformed into an unbound user-defined method\n object whose ``im_class`` attribute is ``C``. When it would yield a\n class method object, it is transformed into a bound user-defined\n method object whose ``im_class`` and ``im_self`` attributes are\n both ``C``. When it would yield a static method object, it is\n transformed into the object wrapped by the static method object.\n See section *Implementing Descriptors* for another way in which\n attributes retrieved from a class may differ from those actually\n contained in its ``__dict__`` (note that only new-style classes\n support descriptors).\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: ``__name__`` is the class name; ``__module__``\n is the module name in which the class was defined; ``__dict__`` is\n the dictionary containing the class\'s namespace; ``__bases__`` is a\n tuple (possibly empty or a singleton) containing the base classes,\n in the order of their occurrence in the base class list;\n ``__doc__`` is the class\'s documentation string, or None if\n undefined.\n\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object or an unbound user-defined method object whose\n associated class is the class (call it ``C``) of the instance for\n which the attribute reference was initiated or one of its bases, it\n is transformed into a bound user-defined method object whose\n ``im_class`` attribute is ``C`` and whose ``im_self`` attribute is\n the instance. Static method and class method objects are also\n transformed, as if they had been retrieved from class ``C``; see\n above under "Classes". See section *Implementing Descriptors* for\n another way in which attributes of a class retrieved via its\n instances may differ from the objects actually stored in the\n class\'s ``__dict__``. If no class attribute is found, and the\n object\'s class has a ``__getattr__()`` method, that is called to\n satisfy the lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n ``__setattr__()`` or ``__delattr__()`` method, this is called\n instead of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n *Special method names*.\n\n Special attributes: ``__dict__`` is the attribute dictionary;\n ``__class__`` is the instance\'s class.\n\nFiles\n A file object represents an open file. File objects are created by\n the ``open()`` built-in function, and also by ``os.popen()``,\n ``os.fdopen()``, and the ``makefile()`` method of socket objects\n (and perhaps by other functions or methods provided by extension\n modules). The objects ``sys.stdin``, ``sys.stdout`` and\n ``sys.stderr`` are initialized to file objects corresponding to the\n interpreter\'s standard input, output and error streams. See *File\n Objects* for complete documentation of file objects.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: ``co_name`` gives the function\n name; ``co_argcount`` is the number of positional arguments\n (including arguments with default values); ``co_nlocals`` is the\n number of local variables used by the function (including\n arguments); ``co_varnames`` is a tuple containing the names of\n the local variables (starting with the argument names);\n ``co_cellvars`` is a tuple containing the names of local\n variables that are referenced by nested functions;\n ``co_freevars`` is a tuple containing the names of free\n variables; ``co_code`` is a string representing the sequence of\n bytecode instructions; ``co_consts`` is a tuple containing the\n literals used by the bytecode; ``co_names`` is a tuple\n containing the names used by the bytecode; ``co_filename`` is\n the filename from which the code was compiled;\n ``co_firstlineno`` is the first line number of the function;\n ``co_lnotab`` is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); ``co_stacksize`` is the required stack size\n (including local variables); ``co_flags`` is an integer encoding\n a number of flags for the interpreter.\n\n The following flag bits are defined for ``co_flags``: bit\n ``0x04`` is set if the function uses the ``*arguments`` syntax\n to accept an arbitrary number of positional arguments; bit\n ``0x08`` is set if the function uses the ``**keywords`` syntax\n to accept arbitrary keyword arguments; bit ``0x20`` is set if\n the function is a generator.\n\n Future feature declarations (``from __future__ import\n division``) also use bits in ``co_flags`` to indicate whether a\n code object was compiled with a particular feature enabled: bit\n ``0x2000`` is set if the function was compiled with future\n division enabled; bits ``0x10`` and ``0x1000`` were used in\n earlier versions of Python.\n\n Other bits in ``co_flags`` are reserved for internal use.\n\n If a code object represents a function, the first item in\n ``co_consts`` is the documentation string of the function, or\n ``None`` if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: ``f_back`` is to the previous\n stack frame (towards the caller), or ``None`` if this is the\n bottom stack frame; ``f_code`` is the code object being executed\n in this frame; ``f_locals`` is the dictionary used to look up\n local variables; ``f_globals`` is used for global variables;\n ``f_builtins`` is used for built-in (intrinsic) names;\n ``f_restricted`` is a flag indicating whether the function is\n executing in restricted execution mode; ``f_lasti`` gives the\n precise instruction (this is an index into the bytecode string\n of the code object).\n\n Special writable attributes: ``f_trace``, if not ``None``, is a\n function called at the start of each source code line (this is\n used by the debugger); ``f_exc_type``, ``f_exc_value``,\n ``f_exc_traceback`` represent the last exception raised in the\n parent frame provided another exception was ever raised in the\n current frame (in all other cases they are None); ``f_lineno``\n is the current line number of the frame --- writing to this from\n within a trace function jumps to the given line (only for the\n bottom-most frame). A debugger can implement a Jump command\n (aka Set Next Statement) by writing to f_lineno.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n *The try statement*.) It is accessible as ``sys.exc_traceback``,\n and also as the third item of the tuple returned by\n ``sys.exc_info()``. The latter is the preferred interface,\n since it works correctly when the program is using multiple\n threads. When the program contains no suitable handler, the\n stack trace is written (nicely formatted) to the standard error\n stream; if the interpreter is interactive, it is also made\n available to the user as ``sys.last_traceback``.\n\n Special read-only attributes: ``tb_next`` is the next level in\n the stack trace (towards the frame where the exception\n occurred), or ``None`` if there is no next level; ``tb_frame``\n points to the execution frame of the current level;\n ``tb_lineno`` gives the line number where the exception\n occurred; ``tb_lasti`` indicates the precise instruction. The\n line number and last instruction in the traceback may differ\n from the line number of its frame object if the exception\n occurred in a ``try`` statement with no matching except clause\n or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices when *extended slice\n syntax* is used. This is a slice using two colons, or multiple\n slices or ellipses separated by commas, e.g., ``a[i:j:step]``,\n ``a[i:j, k:l]``, or ``a[..., i:j]``. They are also created by\n the built-in ``slice()`` function.\n\n Special read-only attributes: ``start`` is the lower bound;\n ``stop`` is the upper bound; ``step`` is the step value; each is\n ``None`` if omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the extended slice that the slice\n object would describe if applied to a sequence of *length*\n items. It returns a tuple of three integers; respectively\n these are the *start* and *stop* indices and the *step* or\n stride length of the slice. Missing or out-of-bounds indices\n are handled in a manner consistent with regular slices.\n\n New in version 2.3.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n ``staticmethod()`` constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in ``classmethod()`` constructor.\n', - 'typesfunctions': u'\nFunctions\n*********\n\nFunction objects are created by function definitions. The only\noperation on a function object is to call it: ``func(argument-list)``.\n\nThere are really two flavors of function objects: built-in functions\nand user-defined functions. Both support the same operation (to call\nthe function), but the implementation is different, hence the\ndifferent object types.\n\nSee *Function definitions* for more information.\n', - 'typesmapping': u'\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 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 is\n 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": 2, "two": 3}``:\n\n * ``dict(one=2, two=3)``\n\n * ``dict({\'one\': 2, \'two\': 3})``\n\n * ``dict(zip((\'one\', \'two\'), (2, 3)))``\n\n * ``dict([[\'two\', 3], [\'one\', 2]])``\n\n The first example only works for keys that are valid Python\n identifiers; the others work with any valid keys.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for building a dictionary from\n keyword arguments added.\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 New in version 2.5: If a subclass of dict defines a method\n ``__missing__()``, if the key *key* is not present, the\n ``d[key]`` operation calls that method with the key *key* as\n argument. The ``d[key]`` operation then returns or raises\n whatever is returned or raised by the ``__missing__(key)`` call\n if the key is not present. No other operations or methods invoke\n ``__missing__()``. If ``__missing__()`` is not defined,\n ``KeyError`` is raised. ``__missing__()`` must be a method; it\n cannot be an instance variable. For an example, see\n ``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 New in version 2.2.\n\n key not in d\n\n Equivalent to ``not key in d``.\n\n New in version 2.2.\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 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 New in version 2.3.\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 has_key(key)\n\n ``dict.has_key(key)`` is equivalent to ``key in d``, but\n deprecated.\n\n items()\n\n Return a copy of the dictionary\'s list of ``(key, value)``\n pairs.\n\n Note: Keys and values are listed in an arbitrary order which is non-\n random, varies across Python implementations, and depends on\n the dictionary\'s history of insertions and deletions. If\n ``items()``, ``keys()``, ``values()``, ``iteritems()``,\n ``iterkeys()``, and ``itervalues()`` are called with no\n intervening modifications to the dictionary, the lists will\n directly correspond. This allows the creation of ``(value,\n key)`` pairs using ``zip()``: ``pairs = zip(d.values(),\n d.keys())``. The same relationship holds for the\n ``iterkeys()`` and ``itervalues()`` methods: ``pairs =\n zip(d.itervalues(), d.iterkeys())`` provides the same value\n for ``pairs``. Another way to create the same list is ``pairs\n = [(v, k) for (k, v) in d.iteritems()]``.\n\n iteritems()\n\n Return an iterator over the dictionary\'s ``(key, value)`` pairs.\n See the note for ``dict.items()``.\n\n New in version 2.2.\n\n iterkeys()\n\n Return an iterator over the dictionary\'s keys. See the note for\n ``dict.items()``.\n\n New in version 2.2.\n\n itervalues()\n\n Return an iterator over the dictionary\'s values. See the note\n for ``dict.items()``.\n\n New in version 2.2.\n\n keys()\n\n Return a copy of the dictionary\'s list of keys. See the note\n for ``dict.items()``.\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 New in version 2.3.\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 a tuple or other iterable of\n length two). If keyword arguments are specified, the dictionary\n is then is updated with those key/value pairs: ``d.update(red=1,\n blue=2)``.\n\n Changed in version 2.4: Allowed the argument to be an iterable\n of key/value pairs and allowed keyword arguments.\n\n values()\n\n Return a copy of the dictionary\'s list of values. See the note\n for ``dict.items()``.\n', - 'typesmethods': u"\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\nThe implementation adds two special read-only attributes to class\ninstance methods: ``m.im_self`` is the object on which the method\noperates, and ``m.im_func`` is the function implementing the method.\nCalling ``m(arg-1, arg-2, ..., arg-n)`` is completely equivalent to\ncalling ``m.im_func(m.im_self, arg-1, arg-2, ..., arg-n)``.\n\nClass instance methods are either *bound* or *unbound*, referring to\nwhether the method was accessed through an instance or a class,\nrespectively. When a method is unbound, its ``im_self`` attribute\nwill be ``None`` and if called, an explicit ``self`` object must be\npassed as the first argument. In this case, ``self`` must be an\ninstance of the unbound method's class (or a subclass of that class),\notherwise a ``TypeError`` is raised.\n\nLike function objects, methods objects support getting arbitrary\nattributes. However, since method attributes are actually stored on\nthe underlying function object (``meth.im_func``), setting method\nattributes on either bound or unbound methods is disallowed.\nAttempting to set a method attribute results in a ``TypeError`` being\nraised. In order to set a method attribute, you need to explicitly\nset it on the underlying function object:\n\n class C:\n def method(self):\n pass\n\n c = C()\n c.method.im_func.whoami = 'my name is c'\n\nSee *The standard type hierarchy* for more information.\n", - 'typesmodules': u"\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': u'\nSequence Types --- ``str``, ``unicode``, ``list``, ``tuple``, ``buffer``, ``xrange``\n************************************************************************************\n\nThere are six sequence types: strings, Unicode strings, lists, tuples,\nbuffers, and xrange objects. (For other containers see the built in\n``dict``, ``list``, ``set``, and ``tuple`` classes, and the\n``collections`` module.)\n\nString literals are written in single or double quotes: ``\'xyzzy\'``,\n``"frobozz"``. See *String literals* for more about string literals.\nUnicode strings are much like strings, but are specified in the syntax\nusing a preceding ``\'u\'`` character: ``u\'abc\'``, ``u"def"``. In\naddition to the functionality described here, there are also string-\nspecific methods described in the *String Methods* section. Lists are\nconstructed with square brackets, separating items with commas: ``[a,\nb, c]``. Tuples are constructed by the comma operator (not within\nsquare brackets), with or without enclosing parentheses, but an empty\ntuple must have the enclosing parentheses, such as ``a, b, c`` or\n``()``. A single item tuple must have a trailing comma, such as\n``(d,)``.\n\nBuffer objects are not directly supported by Python syntax, but can be\ncreated by calling the builtin function ``buffer()``. They don\'t\nsupport concatenation or repetition.\n\nObjects of type xrange are similar to buffers in that there is no\nspecific syntax to create them, but they are created using the\n``xrange()`` function. They don\'t support slicing, concatenation or\nrepetition, and using ``in``, ``not in``, ``min()`` or ``max()`` on\nthem 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 compare\nequal and the two sequences must be of the same type and have the same\nlength. (For full details see *Comparisons* in the language\nreference.)\n\nNotes:\n\n1. When *s* is a string or Unicode string object the ``in`` and ``not\n in`` operations act like a substring test. In Python versions\n before 2.3, *x* had to be a string of length 1. In Python 2.3 and\n beyond, *x* may be a string of any length.\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. If *s* and *t* are both strings, some Python implementations such\n as CPython can usually perform an in-place optimization for\n assignments of the form ``s=s+t`` or ``s+=t``. When applicable,\n this optimization makes quadratic run-time much less likely. This\n optimization is both version and implementation dependent. For\n performance sensitive code, it is preferable to use the\n ``str.join()`` method which assures consistent linear concatenation\n performance across versions and implementations.\n\n Changed in version 2.4: Formerly, string concatenation never\n occurred in-place.\n\n\nString Methods\n==============\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Note that none of these methods take keyword\narguments.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbuffer, xrange* section. To output formatted strings use template\nstrings or the ``%`` operator described in the *String Formatting\nOperations* 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 only its first character\n capitalized.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of occurrences of substring *sub* in the range\n [*start*, *end*]. Optional arguments *start* and *end* are\n interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes 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\n Changed in version 2.5: Accept tuples as *suffix*.\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 range [*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(format_string, *args, **kwargs)\n\n Perform a string formatting operation. The *format_string*\n argument can contain literal text or replacement fields delimited\n by braces ``{}``. Each replacement field contains either the\n numeric index of a positional argument, or the name of a keyword\n argument. Returns a copy of *format_string* where each replacement\n field is replaced with the string value of the corresponding\n 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\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(seq)\n\n Return a string which is the concatenation of the strings in the\n sequence *seq*. The separator between elements is the string\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n New in version 2.5.\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]. Optional\n arguments *start* and *end* are interpreted as in slice notation.\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\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\n New in version 2.5.\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\n New in version 2.4.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n Changed in version 2.5: Accept tuples as *prefix*.\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\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string: words start with\n uppercase characters, all remaining cased characters are lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\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 New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n\n\nString Formatting Operations\n============================\n\nString and Unicode objects have one unique built-in operation: the\n``%`` operator (modulo). This is also known as the string\n*formatting* or *interpolation* operator. Given ``format % values``\n(where *format* is a string or Unicode object), ``%`` conversion\nspecifications in *format* are replaced with zero or more elements of\n*values*. The effect is similar to the using ``sprintf`` in the C\nlanguage. If *format* is a Unicode object, or if any of the objects\nbeing converted using the ``%s`` conversion are Unicode objects, the\nresult will also be a Unicode object.\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 %(#)03d quote types.\' % \\\n... {\'language\': "Python", "#": 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\'`` | Obselete 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()``). | (6) |\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 ``%r`` conversion was added in Python 2.0.\n\n The precision determines the maximal number of characters used.\n\n6. If the object or format provided is a ``unicode`` string, the\n resulting string will also be ``unicode``.\n\n The precision determines the maximal number of characters used.\n\n7. 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\nFor safety reasons, floating point precisions are clipped to 50;\n``%f`` conversions for numbers whose absolute value is over 1e25 are\nreplaced by ``%g`` conversions. [5] All other errors raise\nexceptions.\n\nAdditional string operations are defined in standard modules\n``string`` and ``re``.\n\n\nXRange Type\n===========\n\nThe ``xrange`` type is an immutable sequence which is commonly used\nfor looping. The advantage of the ``xrange`` type is that an\n``xrange`` object will always take the same amount of memory, no\nmatter the size of the range it represents. There are no consistent\nperformance advantages.\n\nXRange objects have very little behavior: they only support indexing,\niteration, and the ``len()`` function.\n\n\nMutable Sequence Types\n======================\n\nList objects support additional operations that allow in-place\nmodification of the object. Other mutable sequence types (when added\nto the language) should also support these operations. Strings and\ntuples are immutable sequence types: such objects cannot be modified\nonce created. The following operations are defined on mutable sequence\ntypes (where *x* is an arbitrary object):\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)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\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 | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. 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 list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn\'t have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don\'t return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\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``.\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 In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. While a list is being sorted, the effect of attempting to mutate,\n or even inspect, the list is undefined. The C implementation of\n Python 2.3 and newer makes the list appear empty for the duration,\n and raises ``ValueError`` if it can detect that the list has been\n mutated during a sort.\n', - 'typesseq-mutable': u"\nMutable Sequence Types\n**********************\n\nList objects support additional operations that allow in-place\nmodification of the object. Other mutable sequence types (when added\nto the language) should also support these operations. Strings and\ntuples are immutable sequence types: such objects cannot be modified\nonce created. The following operations are defined on mutable sequence\ntypes (where *x* is an arbitrary object):\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)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\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 | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. 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 list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn't have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don't return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\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``.\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 In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. While a list is being sorted, the effect of attempting to mutate,\n or even inspect, the list is undefined. The C implementation of\n Python 2.3 and newer makes the list appear empty for the duration,\n and raises ``ValueError`` if it can detect that the list has been\n mutated during a sort.\n", - 'unary': u'\nUnary arithmetic 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\nplain or long integer argument. The bitwise inversion of ``x`` is\ndefined as ``-(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': u'\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', - 'with': u'\nThe ``with`` statement\n**********************\n\nNew in version 2.5.\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" expression ["as" target] ":" suite\n\nThe execution of the ``with`` statement proceeds as follows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__enter__()`` method is invoked.\n\n3. 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 5 below.\n\n4. The suite is executed.\n\n5. 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\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n', - 'yield': u'\nThe ``yield`` statement\n***********************\n\n yield_stmt ::= yield_expression\n\nThe ``yield`` statement is only used when defining a generator\nfunction, and is only used in the body of the generator function.\nUsing a ``yield`` statement in a function definition is sufficient to\ncause that definition to create a generator function instead of a\nnormal function.\n\nWhen a generator function is called, it returns an iterator known as a\ngenerator iterator, or more commonly, a generator. The body of the\ngenerator function is executed by calling the generator\'s ``next()``\nmethod repeatedly until it raises an exception.\n\nWhen a ``yield`` statement is executed, the state of the generator is\nfrozen and the value of **expression_list** is returned to\n``next()``\'s caller. By "frozen" we mean that all local state is\nretained, including the current bindings of local variables, the\ninstruction pointer, and the internal evaluation stack: enough\ninformation is saved so that the next time ``next()`` is invoked, the\nfunction can proceed exactly as if the ``yield`` statement were just\nanother external call.\n\nAs of Python version 2.5, the ``yield`` statement is now allowed in\nthe ``try`` clause of a ``try`` ... ``finally`` construct. If the\ngenerator is not resumed before it is finalized (by reaching a zero\nreference count or by being garbage collected), the generator-\niterator\'s ``close()`` method will be called, allowing any pending\n``finally`` clauses to execute.\n\nNote: In Python 2.2, the ``yield`` statement was only allowed when the\n ``generators`` feature has been enabled. This ``__future__`` import\n statement was used to enable the feature:\n\n from __future__ import generators\n\nSee also:\n\n **PEP 0255** - Simple Generators\n The proposal for adding generators and the ``yield`` statement\n to Python.\n\n **PEP 0342** - Coroutines via Enhanced Generators\n The proposal that, among other generator enhancements, proposed\n allowing ``yield`` to appear inside a ``try`` ... ``finally``\n block.\n'} From python-checkins at python.org Sun Apr 26 11:57:30 2009 From: python-checkins at python.org (georg.brandl) Date: Sun, 26 Apr 2009 11:57:30 +0200 (CEST) Subject: [Python-checkins] r71961 - python/trunk/Lib/pydoc_data/topics.py Message-ID: <20090426095730.F0B781E4012@bag.python.org> Author: georg.brandl Date: Sun Apr 26 11:57:29 2009 New Revision: 71961 Log: Update pydoc topics. Modified: python/trunk/Lib/pydoc_data/topics.py Modified: python/trunk/Lib/pydoc_data/topics.py ============================================================================== --- python/trunk/Lib/pydoc_data/topics.py (original) +++ python/trunk/Lib/pydoc_data/topics.py Sun Apr 26 11:57:29 2009 @@ -1,16 +1,16 @@ -# Autogenerated by Sphinx on Thu Oct 2 15:45:36 2008 +# Autogenerated by Sphinx on Sun Apr 26 11:57:02 2009 topics = {'assert': u'\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': u'\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\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 is recursively defined as\nfollows.\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 a sequence 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\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`` statement in the\n current code block: the name is bound to the object in the current\n local namespace.\n\n * Otherwise: the name is bound to the object in the current global\n namespace.\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 a sequence 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* 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 a plain integer. If it is negative, the\n sequence\'s length is added to it. The resulting value must be a\n nonnegative integer less than the sequence\'s length, and the\n sequence is asked to assign the assigned object to its item with\n that index. If the index is out of range, ``IndexError`` is raised\n (assignment to a subscripted sequence cannot add new items to a\n 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* 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 (small) integers. If either\n bound is negative, the sequence\'s length is added to it. The\n resulting bounds are clipped to lie between zero and the sequence\'s\n length, inclusive. Finally, the sequence object is asked to replace\n the slice with the items of the assigned sequence. The length of\n the 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(In the current implementation, the syntax for targets is taken to be\nthe same as for expressions, and invalid syntax is rejected during the\ncode generation phase, causing less 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\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 ::= target augop (expression_list | yield_expression)\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 initial value is\nretrieved with a ``getattr()`` and the result is assigned with a\n``setattr()``. Notice that the two methods do not necessarily refer\nto the same variable. When ``getattr()`` refers to a class variable,\n``setattr()`` still writes to an instance variable. For example:\n\n class A:\n x = 3 # class variable\n a = A()\n a.x += 1 # writes a.x as 4 leaving A.x as 3\n', + 'assignment': u'\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\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 is recursively defined as\nfollows.\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\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`` statement in the\n current code block: the name is bound to the object in the current\n local namespace.\n\n * Otherwise: the name is bound to the object in the current global\n namespace.\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* 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 a plain integer. If it is negative, the\n sequence\'s length is added to it. The resulting value must be a\n nonnegative integer less than the sequence\'s length, and the\n sequence is asked to assign the assigned object to its item with\n that index. If the index is out of range, ``IndexError`` is raised\n (assignment to a subscripted sequence cannot add new items to a\n 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* 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 (small) integers. If either\n bound is negative, the sequence\'s length is added to it. The\n resulting bounds are clipped to lie between zero and the sequence\'s\n length, inclusive. Finally, the sequence object is asked to replace\n the slice with the items of the assigned sequence. The length of\n the 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(In the current implementation, the syntax for targets is taken to be\nthe same as for expressions, and invalid syntax is rejected during the\ncode generation phase, causing less 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\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 initial value is\nretrieved with a ``getattr()`` and the result is assigned with a\n``setattr()``. Notice that the two methods do not necessarily refer\nto the same variable. When ``getattr()`` refers to a class variable,\n``setattr()`` still writes to an instance variable. For example:\n\n class A:\n x = 3 # class variable\n a = A()\n a.x += 1 # writes a.x as 4 leaving A.x as 3\n', 'atom-identifiers': u'\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', 'atom-literals': u"\nLiterals\n********\n\nPython supports string literals and various numeric literals:\n\n literal ::= stringliteral | integer | longinteger\n | floatnumber | imagnumber\n\nEvaluation of a literal yields an object of the given type (string,\ninteger, long integer, floating point number, complex number) with the\ngiven value. The value may be approximated in the case of floating\npoint and imaginary (complex) literals. See section *Literals* for\ndetails.\n\nAll literals correspond to immutable data types, and hence the\nobject's identity is less important than its value. Multiple\nevaluations of literals with the same value (either the same\noccurrence in the program text or a different occurrence) may obtain\nthe same object or a different object with the same value.\n", - 'attribute-access': u'\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 in new-style classes.\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 not simply execute ``self.name = value`` --- this would\n cause a recursive call to itself. Instead, it should insert the\n value in the dictionary of instance attributes, e.g.,\n ``self.__dict__[name] = value``. For new-style classes, rather\n than accessing the instance dictionary, it should call the base\n 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\n\nMore attribute access for new-style classes\n===========================================\n\nThe following methods only apply to new-style classes.\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 builtin functions. See *Special method lookup for new-style\n classes*.\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 new-style class, known as the *owner*\nclass. In the examples below, "the attribute" refers to the attribute\nwhose name is the key of the property in the owner class\'\n``__dict__``. Descriptors can only be implemented as new-style\nclasses themselves.\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. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass ``object()`` or\n``type()``).\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 a new-style object instance, ``a.x`` is transformed\n into the call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a new-style class, ``A.x`` is transformed into the\n call: ``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. Normally, data\ndescriptors define both ``__get__()`` and ``__set__()``, while non-\ndata descriptors have just the ``__get__()`` method. Data descriptors\nalways override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances. [2]\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 both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__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 new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n New in version 2.2.\n\nNotes on using *__slots__*\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 Changed in version 2.3: Previously, adding ``\'__dict__\'`` to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\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 Changed in version 2.3: Previously, adding ``\'__weakref__\'`` to the\n *__slots__* declaration would not enable support for weak\n references.\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* 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* 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__*.\n\n* *__slots__* do not work for classes derived from "variable-length"\n built-in types such as ``long``, ``str`` and ``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 Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n', + 'attribute-access': u'\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 in new-style classes.\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 not simply execute ``self.name = value`` --- this would\n cause a recursive call to itself. Instead, it should insert the\n value in the dictionary of instance attributes, e.g.,\n ``self.__dict__[name] = value``. For new-style classes, rather\n than accessing the instance dictionary, it should call the base\n 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\n\nMore attribute access for new-style classes\n===========================================\n\nThe following methods only apply to new-style classes.\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 builtin functions. See *Special method lookup for new-style\n classes*.\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 new-style class, known as the *owner*\nclass. In the examples below, "the attribute" refers to the attribute\nwhose name is the key of the property in the owner class\'\n``__dict__``. Descriptors can only be implemented as new-style\nclasses themselves.\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. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass ``object()`` or\n``type()``).\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 a new-style object instance, ``a.x`` is transformed\n into the call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a new-style class, ``A.x`` is transformed into the\n call: ``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. Normally, data\ndescriptors define both ``__get__()`` and ``__set__()``, while non-\ndata descriptors have just the ``__get__()`` method. Data descriptors\nalways override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances. [2]\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 both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__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 new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n New in version 2.2.\n\nNotes on using *__slots__*\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 Changed in version 2.3: Previously, adding ``\'__dict__\'`` to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\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 Changed in version 2.3: Previously, adding ``\'__weakref__\'`` to the\n *__slots__* declaration would not enable support for weak\n references.\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* 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* 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__*.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as ``long``, ``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 Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n', 'attribute-references': u'\nAttribute references\n********************\n\nAn attribute reference is a primary followed by a period and a name:\n\n attributeref ::= primary "." identifier\n\nThe primary must evaluate to an object of a type that supports\nattribute references, e.g., a module, list, or an instance. This\nobject is then asked to produce the attribute whose name is the\nidentifier. If this attribute is not available, the exception\n``AttributeError`` is raised. Otherwise, the type and value of the\nobject produced is determined by the object. Multiple evaluations of\nthe same attribute reference may yield different objects.\n', - 'augassign': u'\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 ::= target augop (expression_list | yield_expression)\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 initial value is\nretrieved with a ``getattr()`` and the result is assigned with a\n``setattr()``. Notice that the two methods do not necessarily refer\nto the same variable. When ``getattr()`` refers to a class variable,\n``setattr()`` still writes to an instance variable. For example:\n\n class A:\n x = 3 # class variable\n a = A()\n a.x += 1 # writes a.x as 4 leaving A.x as 3\n', + 'augassign': u'\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 initial value is\nretrieved with a ``getattr()`` and the result is assigned with a\n``setattr()``. Notice that the two methods do not necessarily refer\nto the same variable. When ``getattr()`` refers to a class variable,\n``setattr()`` still writes to an instance variable. For example:\n\n class A:\n x = 3 # class variable\n a = A()\n a.x += 1 # writes a.x as 4 leaving A.x as 3\n', 'binary': u'\nBinary arithmetic operations\n****************************\n\nThe binary arithmetic operations have the conventional priority\nlevels. Note that some of these operations also apply to certain non-\nnumeric types. Apart from the power operator, there are only two\nlevels, one for multiplicative operators and one for additive\noperators:\n\n m_expr ::= u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr\n | m_expr "%" u_expr\n a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr\n\nThe ``*`` (multiplication) operator yields the product of its\narguments. The arguments must either both be numbers, or one argument\nmust be an integer (plain or long) and the other must be a sequence.\nIn the former case, the numbers are converted to a common type and\nthen multiplied together. In the latter case, sequence repetition is\nperformed; a negative repetition factor yields an empty sequence.\n\nThe ``/`` (division) and ``//`` (floor division) operators yield the\nquotient of their arguments. The numeric arguments are first\nconverted to a common type. Plain or long integer division yields an\ninteger of the same type; the result is that of mathematical division\nwith the \'floor\' function applied to the result. Division by zero\nraises the ``ZeroDivisionError`` exception.\n\nThe ``%`` (modulo) operator yields the remainder from the division of\nthe first argument by the second. The numeric arguments are first\nconverted to a common type. A zero right argument raises the\n``ZeroDivisionError`` exception. The arguments may be floating point\nnumbers, e.g., ``3.14%0.7`` equals ``0.34`` (since ``3.14`` equals\n``4*0.7 + 0.34``.) The modulo operator always yields a result with\nthe same sign as its second operand (or zero); the absolute value of\nthe result is strictly smaller than the absolute value of the second\noperand [2].\n\nThe integer division and modulo operators are connected by the\nfollowing identity: ``x == (x/y)*y + (x%y)``. Integer division and\nmodulo are also connected with the built-in function ``divmod()``:\n``divmod(x, y) == (x/y, x%y)``. These identities don\'t hold for\nfloating point numbers; there similar identities hold approximately\nwhere ``x/y`` is replaced by ``floor(x/y)`` or ``floor(x/y) - 1`` [3].\n\nIn addition to performing the modulo operation on numbers, the ``%``\noperator is also overloaded by string and unicode objects to perform\nstring formatting (also known as interpolation). The syntax for string\nformatting is described in the Python Library Reference, section\n*String Formatting Operations*.\n\nDeprecated since version 2.3: The floor division operator, the modulo\noperator, and the ``divmod()`` function are no longer defined for\ncomplex numbers. Instead, convert to a floating point number using\nthe ``abs()`` function if appropriate.\n\nThe ``+`` (addition) operator yields the sum of its arguments. The\narguments must either both be numbers or both sequences of the same\ntype. In the former case, the numbers are converted to a common type\nand then added together. In the latter case, the sequences are\nconcatenated.\n\nThe ``-`` (subtraction) operator yields the difference of its\narguments. The numeric arguments are first converted to a common\ntype.\n', 'bitwise': u'\nBinary bitwise operations\n*************************\n\nEach of the three bitwise operations has a different priority level:\n\n and_expr ::= shift_expr | and_expr "&" shift_expr\n xor_expr ::= and_expr | xor_expr "^" and_expr\n or_expr ::= xor_expr | or_expr "|" xor_expr\n\nThe ``&`` operator yields the bitwise AND of its arguments, which must\nbe plain or long integers. The arguments are converted to a common\ntype.\n\nThe ``^`` operator yields the bitwise XOR (exclusive OR) of its\narguments, which must be plain or long integers. The arguments are\nconverted to a common type.\n\nThe ``|`` operator yields the bitwise (inclusive) OR of its arguments,\nwhich must be plain or long integers. The arguments are converted to\na common type.\n', 'bltin-code-objects': u'\nCode Objects\n************\n\nCode objects are used by the implementation to represent "pseudo-\ncompiled" executable Python code such as a function body. They differ\nfrom function objects because they don\'t contain a reference to their\nglobal execution environment. Code objects are returned by the built-\nin ``compile()`` function and can be extracted from function objects\nthrough their ``func_code`` attribute. See also the ``code`` module.\n\nA code object can be executed or evaluated by passing it (instead of a\nsource string) to the ``exec`` statement or the built-in ``eval()``\nfunction.\n\nSee *The standard type hierarchy* for more information.\n', 'bltin-ellipsis-object': u'\nThe Ellipsis Object\n*******************\n\nThis object is used by extended slice notation (see *Slicings*). It\nsupports no special operations. There is exactly one ellipsis object,\nnamed ``Ellipsis`` (a built-in name).\n\nIt is written as ``Ellipsis``.\n', - 'bltin-file-objects': u'\nFile Objects\n************\n\nFile objects are implemented using C\'s ``stdio`` package and can be\ncreated with the built-in ``open()`` function. File objects are also\nreturned by some other built-in functions and methods, such as\n``os.popen()`` and ``os.fdopen()`` and the ``makefile()`` method of\nsocket objects. Temporary files can be created using the ``tempfile``\nmodule, and high-level file operations such as copying, moving, and\ndeleting files and directories can be achieved with the ``shutil``\nmodule.\n\nWhen a file operation fails for an I/O-related reason, the exception\n``IOError`` is raised. This includes situations where the operation\nis not defined for some reason, like ``seek()`` on a tty device or\nwriting a file opened for reading.\n\nFiles have the following methods:\n\nfile.close()\n\n Close the file. A closed file cannot be read or written any more.\n Any operation which requires that the file be open will raise a\n ``ValueError`` after the file has been closed. Calling ``close()``\n more than once is allowed.\n\n As of Python 2.5, you can avoid having to call this method\n explicitly if you use the ``with`` statement. For example, the\n following code will automatically close *f* when the ``with`` block\n is exited:\n\n from __future__ import with_statement # This isn\'t required in Python 2.6\n\n with open("hello.txt") as f:\n for line in f:\n print line\n\n In older versions of Python, you would have needed to do this to\n get the same effect:\n\n f = open("hello.txt")\n try:\n for line in f:\n print line\n finally:\n f.close()\n\n Note: Not all "file-like" types in Python support use as a context\n manager for the ``with`` statement. If your code is intended to\n work with any file-like object, you can use the function\n ``contextlib.closing()`` instead of using the object directly.\n\nfile.flush()\n\n Flush the internal buffer, like ``stdio``\'s ``fflush``. This may\n be a no-op on some file-like objects.\n\nfile.fileno()\n\n Return the integer "file descriptor" that is used by the underlying\n implementation to request I/O operations from the operating system.\n This can be useful for other, lower level interfaces that use file\n descriptors, such as the ``fcntl`` module or ``os.read()`` and\n friends.\n\n Note: File-like objects which do not have a real file descriptor should\n *not* provide this method!\n\nfile.isatty()\n\n Return ``True`` if the file is connected to a tty(-like) device,\n else ``False``.\n\n Note: If a file-like object is not associated with a real file, this\n method should *not* be implemented.\n\nfile.next()\n\n A file object is its own iterator, for example ``iter(f)`` returns\n *f* (unless *f* is closed). When a file is used as an iterator,\n typically in a ``for`` loop (for example, ``for line in f: print\n line``), the ``next()`` method is called repeatedly. This method\n returns the next input line, or raises ``StopIteration`` when EOF\n is hit when the file is open for reading (behavior is undefined\n when the file is open for writing). In order to make a ``for``\n loop the most efficient way of looping over the lines of a file (a\n very common operation), the ``next()`` method uses a hidden read-\n ahead buffer. As a consequence of using a read-ahead buffer,\n combining ``next()`` with other file methods (like ``readline()``)\n does not work right. However, using ``seek()`` to reposition the\n file to an absolute position will flush the read-ahead buffer.\n\n New in version 2.3.\n\nfile.read([size])\n\n Read at most *size* bytes from the file (less if the read hits EOF\n before obtaining *size* bytes). If the *size* argument is negative\n or omitted, read all data until EOF is reached. The bytes are\n returned as a string object. An empty string is returned when EOF\n is encountered immediately. (For certain files, like ttys, it\n makes sense to continue reading after an EOF is hit.) Note that\n this method may call the underlying C function ``fread`` more than\n once in an effort to acquire as close to *size* bytes as possible.\n Also note that when in non-blocking mode, less data than was\n requested may be returned, even if no *size* parameter was given.\n\n Note: This function is simply a wrapper for the underlying ``fread`` C\n function, and will behave the same in corner cases, such as\n whether the EOF value is cached.\n\nfile.readline([size])\n\n Read one entire line from the file. A trailing newline character\n is kept in the string (but may be absent when a file ends with an\n incomplete line). [6] If the *size* argument is present and non-\n negative, it is a maximum byte count (including the trailing\n newline) and an incomplete line may be returned. An empty string is\n returned *only* when EOF is encountered immediately.\n\n Note: Unlike ``stdio``\'s ``fgets``, the returned string contains null\n characters (``\'\\0\'``) if they occurred in the input.\n\nfile.readlines([sizehint])\n\n Read until EOF using ``readline()`` and return a list containing\n the lines thus read. If the optional *sizehint* argument is\n present, instead of reading up to EOF, whole lines totalling\n approximately *sizehint* bytes (possibly after rounding up to an\n internal buffer size) are read. Objects implementing a file-like\n interface may choose to ignore *sizehint* if it cannot be\n implemented, or cannot be implemented efficiently.\n\nfile.xreadlines()\n\n This method returns the same thing as ``iter(f)``.\n\n New in version 2.1.\n\n Deprecated since version 2.3: Use ``for line in file`` instead.\n\nfile.seek(offset[, whence])\n\n Set the file\'s current position, like ``stdio``\'s ``fseek``. The\n *whence* argument is optional and defaults to ``os.SEEK_SET`` or\n ``0`` (absolute file positioning); other values are ``os.SEEK_CUR``\n or ``1`` (seek relative to the current position) and\n ``os.SEEK_END`` or ``2`` (seek relative to the file\'s end). There\n is no return value.\n\n For example, ``f.seek(2, os.SEEK_CUR)`` advances the position by\n two and ``f.seek(-3, os.SEEK_END)`` sets the position to the third\n to last.\n\n Note that if the file is opened for appending (mode ``\'a\'`` or\n ``\'a+\'``), any ``seek()`` operations will be undone at the next\n write. If the file is only opened for writing in append mode (mode\n ``\'a\'``), this method is essentially a no-op, but it remains useful\n for files opened in append mode with reading enabled (mode\n ``\'a+\'``). If the file is opened in text mode (without ``\'b\'``),\n only offsets returned by ``tell()`` are legal. Use of other\n offsets causes undefined behavior.\n\n Note that not all file objects are seekable.\n\n Changed in version 2.6: Passing float values as offset has been\n deprecated.\n\nfile.tell()\n\n Return the file\'s current position, like ``stdio``\'s ``ftell``.\n\n Note: On Windows, ``tell()`` can return illegal values (after an\n ``fgets``) when reading files with Unix-style line-endings. Use\n binary mode (``\'rb\'``) to circumvent this problem.\n\nfile.truncate([size])\n\n Truncate the file\'s size. If the optional *size* argument is\n present, the file is truncated to (at most) that size. The size\n defaults to the current position. The current file position is not\n changed. Note that if a specified size exceeds the file\'s current\n size, the result is platform-dependent: possibilities include that\n the file may remain unchanged, increase to the specified size as if\n zero-filled, or increase to the specified size with undefined new\n content. Availability: Windows, many Unix variants.\n\nfile.write(str)\n\n Write a string to the file. There is no return value. Due to\n buffering, the string may not actually show up in the file until\n the ``flush()`` or ``close()`` method is called.\n\nfile.writelines(sequence)\n\n Write a sequence of strings to the file. The sequence can be any\n iterable object producing strings, typically a list of strings.\n There is no return value. (The name is intended to match\n ``readlines()``; ``writelines()`` does not add line separators.)\n\nFiles support the iterator protocol. Each iteration returns the same\nresult as ``file.readline()``, and iteration ends when the\n``readline()`` method returns an empty string.\n\nFile objects also offer a number of other interesting attributes.\nThese are not required for file-like objects, but should be\nimplemented if they make sense for the particular object.\n\nfile.closed\n\n bool indicating the current state of the file object. This is a\n read-only attribute; the ``close()`` method changes the value. It\n may not be available on all file-like objects.\n\nfile.encoding\n\n The encoding that this file uses. When Unicode strings are written\n to a file, they will be converted to byte strings using this\n encoding. In addition, when the file is connected to a terminal,\n the attribute gives the encoding that the terminal is likely to use\n (that information might be incorrect if the user has misconfigured\n the terminal). The attribute is read-only and may not be present\n on all file-like objects. It may also be ``None``, in which case\n the file uses the system default encoding for converting Unicode\n strings.\n\n New in version 2.3.\n\nfile.errors\n\n The Unicode error handler used along with the encoding.\n\n New in version 2.6.\n\nfile.mode\n\n The I/O mode for the file. If the file was created using the\n ``open()`` built-in function, this will be the value of the *mode*\n parameter. This is a read-only attribute and may not be present on\n all file-like objects.\n\nfile.name\n\n If the file object was created using ``open()``, the name of the\n file. Otherwise, some string that indicates the source of the file\n object, of the form ``<...>``. This is a read-only attribute and\n may not be present on all file-like objects.\n\nfile.newlines\n\n If Python was built with the *--with-universal-newlines* option to\n **configure** (the default) this read-only attribute exists, and\n for files opened in universal newline read mode it keeps track of\n the types of newlines encountered while reading the file. The\n values it can take are ``\'\\r\'``, ``\'\\n\'``, ``\'\\r\\n\'``, ``None``\n (unknown, no newlines read yet) or a tuple containing all the\n newline types seen, to indicate that multiple newline conventions\n were encountered. For files not opened in universal newline read\n mode the value of this attribute will be ``None``.\n\nfile.softspace\n\n Boolean that indicates whether a space character needs to be\n printed before another value when using the ``print`` statement.\n Classes that are trying to simulate a file object should also have\n a writable ``softspace`` attribute, which should be initialized to\n zero. This will be automatic for most classes implemented in\n Python (care may be needed for objects that override attribute\n access); types implemented in C will have to provide a writable\n ``softspace`` attribute.\n\n Note: This attribute is not used to control the ``print`` statement,\n but to allow the implementation of ``print`` to keep track of its\n internal state.\n', + 'bltin-file-objects': u'\nFile Objects\n************\n\nFile objects are implemented using C\'s ``stdio`` package and can be\ncreated with the built-in ``open()`` function. File objects are also\nreturned by some other built-in functions and methods, such as\n``os.popen()`` and ``os.fdopen()`` and the ``makefile()`` method of\nsocket objects. Temporary files can be created using the ``tempfile``\nmodule, and high-level file operations such as copying, moving, and\ndeleting files and directories can be achieved with the ``shutil``\nmodule.\n\nWhen a file operation fails for an I/O-related reason, the exception\n``IOError`` is raised. This includes situations where the operation\nis not defined for some reason, like ``seek()`` on a tty device or\nwriting a file opened for reading.\n\nFiles have the following methods:\n\nfile.close()\n\n Close the file. A closed file cannot be read or written any more.\n Any operation which requires that the file be open will raise a\n ``ValueError`` after the file has been closed. Calling ``close()``\n more than once is allowed.\n\n As of Python 2.5, you can avoid having to call this method\n explicitly if you use the ``with`` statement. For example, the\n following code will automatically close *f* when the ``with`` block\n is exited:\n\n from __future__ import with_statement # This isn\'t required in Python 2.6\n\n with open("hello.txt") as f:\n for line in f:\n print line\n\n In older versions of Python, you would have needed to do this to\n get the same effect:\n\n f = open("hello.txt")\n try:\n for line in f:\n print line\n finally:\n f.close()\n\n Note: Not all "file-like" types in Python support use as a context\n manager for the ``with`` statement. If your code is intended to\n work with any file-like object, you can use the function\n ``contextlib.closing()`` instead of using the object directly.\n\nfile.flush()\n\n Flush the internal buffer, like ``stdio``\'s ``fflush``. This may\n be a no-op on some file-like objects.\n\n Note: ``flush()`` does not necessarily write the file\'s data to disk.\n Use ``flush()`` followed by ``os.fsync()`` to ensure this\n behavior.\n\nfile.fileno()\n\n Return the integer "file descriptor" that is used by the underlying\n implementation to request I/O operations from the operating system.\n This can be useful for other, lower level interfaces that use file\n descriptors, such as the ``fcntl`` module or ``os.read()`` and\n friends.\n\n Note: File-like objects which do not have a real file descriptor should\n *not* provide this method!\n\nfile.isatty()\n\n Return ``True`` if the file is connected to a tty(-like) device,\n else ``False``.\n\n Note: If a file-like object is not associated with a real file, this\n method should *not* be implemented.\n\nfile.next()\n\n A file object is its own iterator, for example ``iter(f)`` returns\n *f* (unless *f* is closed). When a file is used as an iterator,\n typically in a ``for`` loop (for example, ``for line in f: print\n line``), the ``next()`` method is called repeatedly. This method\n returns the next input line, or raises ``StopIteration`` when EOF\n is hit when the file is open for reading (behavior is undefined\n when the file is open for writing). In order to make a ``for``\n loop the most efficient way of looping over the lines of a file (a\n very common operation), the ``next()`` method uses a hidden read-\n ahead buffer. As a consequence of using a read-ahead buffer,\n combining ``next()`` with other file methods (like ``readline()``)\n does not work right. However, using ``seek()`` to reposition the\n file to an absolute position will flush the read-ahead buffer.\n\n New in version 2.3.\n\nfile.read([size])\n\n Read at most *size* bytes from the file (less if the read hits EOF\n before obtaining *size* bytes). If the *size* argument is negative\n or omitted, read all data until EOF is reached. The bytes are\n returned as a string object. An empty string is returned when EOF\n is encountered immediately. (For certain files, like ttys, it\n makes sense to continue reading after an EOF is hit.) Note that\n this method may call the underlying C function ``fread`` more than\n once in an effort to acquire as close to *size* bytes as possible.\n Also note that when in non-blocking mode, less data than was\n requested may be returned, even if no *size* parameter was given.\n\n Note: This function is simply a wrapper for the underlying ``fread`` C\n function, and will behave the same in corner cases, such as\n whether the EOF value is cached.\n\nfile.readline([size])\n\n Read one entire line from the file. A trailing newline character\n is kept in the string (but may be absent when a file ends with an\n incomplete line). [6] If the *size* argument is present and non-\n negative, it is a maximum byte count (including the trailing\n newline) and an incomplete line may be returned. An empty string is\n returned *only* when EOF is encountered immediately.\n\n Note: Unlike ``stdio``\'s ``fgets``, the returned string contains null\n characters (``\'\\0\'``) if they occurred in the input.\n\nfile.readlines([sizehint])\n\n Read until EOF using ``readline()`` and return a list containing\n the lines thus read. If the optional *sizehint* argument is\n present, instead of reading up to EOF, whole lines totalling\n approximately *sizehint* bytes (possibly after rounding up to an\n internal buffer size) are read. Objects implementing a file-like\n interface may choose to ignore *sizehint* if it cannot be\n implemented, or cannot be implemented efficiently.\n\nfile.xreadlines()\n\n This method returns the same thing as ``iter(f)``.\n\n New in version 2.1.\n\n Deprecated since version 2.3: Use ``for line in file`` instead.\n\nfile.seek(offset[, whence])\n\n Set the file\'s current position, like ``stdio``\'s ``fseek``. The\n *whence* argument is optional and defaults to ``os.SEEK_SET`` or\n ``0`` (absolute file positioning); other values are ``os.SEEK_CUR``\n or ``1`` (seek relative to the current position) and\n ``os.SEEK_END`` or ``2`` (seek relative to the file\'s end). There\n is no return value.\n\n For example, ``f.seek(2, os.SEEK_CUR)`` advances the position by\n two and ``f.seek(-3, os.SEEK_END)`` sets the position to the third\n to last.\n\n Note that if the file is opened for appending (mode ``\'a\'`` or\n ``\'a+\'``), any ``seek()`` operations will be undone at the next\n write. If the file is only opened for writing in append mode (mode\n ``\'a\'``), this method is essentially a no-op, but it remains useful\n for files opened in append mode with reading enabled (mode\n ``\'a+\'``). If the file is opened in text mode (without ``\'b\'``),\n only offsets returned by ``tell()`` are legal. Use of other\n offsets causes undefined behavior.\n\n Note that not all file objects are seekable.\n\n Changed in version 2.6: Passing float values as offset has been\n deprecated.\n\nfile.tell()\n\n Return the file\'s current position, like ``stdio``\'s ``ftell``.\n\n Note: On Windows, ``tell()`` can return illegal values (after an\n ``fgets``) when reading files with Unix-style line-endings. Use\n binary mode (``\'rb\'``) to circumvent this problem.\n\nfile.truncate([size])\n\n Truncate the file\'s size. If the optional *size* argument is\n present, the file is truncated to (at most) that size. The size\n defaults to the current position. The current file position is not\n changed. Note that if a specified size exceeds the file\'s current\n size, the result is platform-dependent: possibilities include that\n the file may remain unchanged, increase to the specified size as if\n zero-filled, or increase to the specified size with undefined new\n content. Availability: Windows, many Unix variants.\n\nfile.write(str)\n\n Write a string to the file. There is no return value. Due to\n buffering, the string may not actually show up in the file until\n the ``flush()`` or ``close()`` method is called.\n\nfile.writelines(sequence)\n\n Write a sequence of strings to the file. The sequence can be any\n iterable object producing strings, typically a list of strings.\n There is no return value. (The name is intended to match\n ``readlines()``; ``writelines()`` does not add line separators.)\n\nFiles support the iterator protocol. Each iteration returns the same\nresult as ``file.readline()``, and iteration ends when the\n``readline()`` method returns an empty string.\n\nFile objects also offer a number of other interesting attributes.\nThese are not required for file-like objects, but should be\nimplemented if they make sense for the particular object.\n\nfile.closed\n\n bool indicating the current state of the file object. This is a\n read-only attribute; the ``close()`` method changes the value. It\n may not be available on all file-like objects.\n\nfile.encoding\n\n The encoding that this file uses. When Unicode strings are written\n to a file, they will be converted to byte strings using this\n encoding. In addition, when the file is connected to a terminal,\n the attribute gives the encoding that the terminal is likely to use\n (that information might be incorrect if the user has misconfigured\n the terminal). The attribute is read-only and may not be present\n on all file-like objects. It may also be ``None``, in which case\n the file uses the system default encoding for converting Unicode\n strings.\n\n New in version 2.3.\n\nfile.errors\n\n The Unicode error handler used along with the encoding.\n\n New in version 2.6.\n\nfile.mode\n\n The I/O mode for the file. If the file was created using the\n ``open()`` built-in function, this will be the value of the *mode*\n parameter. This is a read-only attribute and may not be present on\n all file-like objects.\n\nfile.name\n\n If the file object was created using ``open()``, the name of the\n file. Otherwise, some string that indicates the source of the file\n object, of the form ``<...>``. This is a read-only attribute and\n may not be present on all file-like objects.\n\nfile.newlines\n\n If Python was built with the *--with-universal-newlines* option to\n **configure** (the default) this read-only attribute exists, and\n for files opened in universal newline read mode it keeps track of\n the types of newlines encountered while reading the file. The\n values it can take are ``\'\\r\'``, ``\'\\n\'``, ``\'\\r\\n\'``, ``None``\n (unknown, no newlines read yet) or a tuple containing all the\n newline types seen, to indicate that multiple newline conventions\n were encountered. For files not opened in universal newline read\n mode the value of this attribute will be ``None``.\n\nfile.softspace\n\n Boolean that indicates whether a space character needs to be\n printed before another value when using the ``print`` statement.\n Classes that are trying to simulate a file object should also have\n a writable ``softspace`` attribute, which should be initialized to\n zero. This will be automatic for most classes implemented in\n Python (care may be needed for objects that override attribute\n access); types implemented in C will have to provide a writable\n ``softspace`` attribute.\n\n Note: This attribute is not used to control the ``print`` statement,\n but to allow the implementation of ``print`` to keep track of its\n internal state.\n', 'bltin-null-object': u"\nThe Null Object\n***************\n\nThis object is returned by functions that don't explicitly return a\nvalue. It supports no special operations. There is exactly one null\nobject, named ``None`` (a built-in name).\n\nIt is written as ``None``.\n", 'bltin-type-objects': u"\nType Objects\n************\n\nType objects represent the various object types. An object's type is\naccessed by the built-in function ``type()``. There are no special\noperations on types. The standard module ``types`` defines names for\nall standard built-in types.\n\nTypes are written like this: ````.\n", 'booleans': u'\nBoolean operations\n******************\n\nBoolean operations have the lowest priority of all Python operations:\n\n expression ::= conditional_expression | lambda_form\n old_expression ::= or_test | old_lambda_form\n conditional_expression ::= or_test ["if" or_test "else" expression]\n or_test ::= and_test | or_test "or" and_test\n and_test ::= not_test | and_test "and" not_test\n not_test ::= comparison | "not" not_test\n\nIn the context of Boolean operations, and also when expressions are\nused by control flow statements, the following values are interpreted\nas false: ``False``, ``None``, numeric zero of all types, and empty\nstrings and containers (including strings, tuples, lists,\ndictionaries, sets and frozensets). All other values are interpreted\nas true. (See the ``__nonzero__()`` special method for a way to\nchange this.)\n\nThe operator ``not`` yields ``True`` if its argument is false,\n``False`` otherwise.\n\nThe expression ``x if C else y`` first evaluates *C* (*not* *x*); if\n*C* is true, *x* is evaluated and its value is returned; otherwise,\n*y* is evaluated and its value is returned.\n\nNew in version 2.5.\n\nThe expression ``x and y`` first evaluates *x*; if *x* is false, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\nThe expression ``x or y`` first evaluates *x*; if *x* is true, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\n(Note that neither ``and`` nor ``or`` restrict the value and type they\nreturn to ``False`` and ``True``, but rather return the last evaluated\nargument. This is sometimes useful, e.g., if ``s`` is a string that\nshould be replaced by a default value if it is empty, the expression\n``s or \'foo\'`` yields the desired value. Because ``not`` has to\ninvent a value anyway, it does not bother to return a value of the\nsame type as its argument, so e.g., ``not \'foo\'`` yields ``False``,\nnot ``\'\'``.)\n', @@ -18,41 +18,41 @@ 'callable-types': u'\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': u'\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 [","]\n | expression genexpr_for] ")"\n argument_list ::= positional_arguments ["," keyword_arguments]\n ["," "*" expression] ["," keyword_arguments]\n ["," "**" expression]\n | keyword_arguments ["," "*" expression]\n ["," "**" expression]\n | "*" expression ["," "*" expression] ["," "**" 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 certain class instances\nthemselves are callable; extensions may define additional callable\nobject types). All argument expressions are evaluated before the call\nis attempted. Please refer to section *Function definitions* for the\nsyntax 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\nNote: An implementation may provide builtin functions whose positional\n parameters do not have names, even if they are \'named\' for the\n purpose of documentation, and which therefore cannot be supplied by\n keyword. In CPython, this is the case for functions implemented in\n C that use ``PyArg_ParseTuple`` to parse 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. Formal parameters using the syntax ``(sublist)`` cannot be\nused as keyword argument names; the outermost sublist corresponds to a\nsingle unnamed argument slot, and the argument value is assigned to\nthe sublist using the usual tuple assignment rules after all other\nparameter processing is done.\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': u'\nClass definitions\n*****************\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with ``self.name = value``.\nBoth class and instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\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', - 'coercion-rules': u"\nCoercion rules\n**************\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3.0, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don't define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from ``object``) never invoke the\n ``__coerce__()`` method in response to a binary operator; the only\n time ``__coerce__()`` is invoked is when the built-in function\n ``coerce()`` is called.\n\n* For most intents and purposes, an operator that returns\n ``NotImplemented`` is treated the same as one that is not\n implemented at all.\n\n* Below, ``__op__()`` and ``__rop__()`` are used to signify the\n generic method names corresponding to an operator; ``__iop__()`` is\n used for the corresponding in-place operator. For example, for the\n operator '``+``', ``__add__()`` and ``__radd__()`` are used for the\n left and right variant of the binary operator, and ``__iadd__()``\n for the in-place variant.\n\n* For objects *x* and *y*, first ``x.__op__(y)`` is tried. If this is\n not implemented or returns ``NotImplemented``, ``y.__rop__(x)`` is\n tried. If this is also not implemented or returns\n ``NotImplemented``, a ``TypeError`` exception is raised. But see\n the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base's ``__rop__()`` method, the right operand's ``__rop__()``\n method is tried *before* the left operand's ``__op__()`` method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand's ``__op__()`` method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is called\n before that type's ``__op__()`` or ``__rop__()`` method is called,\n but no sooner. If the coercion returns an object of a different\n type for the operand whose coercion is invoked, part of the process\n is redone using the new object.\n\n* When an in-place operator (like '``+=``') is used, if the left\n operand implements ``__iop__()``, it is invoked without any\n coercion. When the operation falls back to ``__op__()`` and/or\n ``__rop__()``, the normal coercion rules apply.\n\n* In ``x + y``, if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In ``x * y``, if one operator is a sequence that implements sequence\n repetition, and the other is an integer (``int`` or ``long``),\n sequence repetition is invoked.\n\n* Rich comparisons (implemented by methods ``__eq__()`` and so on)\n never use coercion. Three-way comparison (implemented by\n ``__cmp__()``) does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types ``int``,\n ``long`` and ``float`` do not use coercion; the type ``complex``\n however does use it. The difference can become apparent when\n subclassing these types. Over time, the type ``complex`` may be\n fixed to avoid coercion. All these types implement a\n ``__coerce__()`` method, for use by the built-in ``coerce()``\n function.\n", + 'coercion-rules': u"\nCoercion rules\n**************\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3.0, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don't define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from ``object``) never invoke the\n ``__coerce__()`` method in response to a binary operator; the only\n time ``__coerce__()`` is invoked is when the built-in function\n ``coerce()`` is called.\n\n* For most intents and purposes, an operator that returns\n ``NotImplemented`` is treated the same as one that is not\n implemented at all.\n\n* Below, ``__op__()`` and ``__rop__()`` are used to signify the\n generic method names corresponding to an operator; ``__iop__()`` is\n used for the corresponding in-place operator. For example, for the\n operator '``+``', ``__add__()`` and ``__radd__()`` are used for the\n left and right variant of the binary operator, and ``__iadd__()``\n for the in-place variant.\n\n* For objects *x* and *y*, first ``x.__op__(y)`` is tried. If this is\n not implemented or returns ``NotImplemented``, ``y.__rop__(x)`` is\n tried. If this is also not implemented or returns\n ``NotImplemented``, a ``TypeError`` exception is raised. But see\n the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base's ``__rop__()`` method, the right operand's ``__rop__()``\n method is tried *before* the left operand's ``__op__()`` method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand's ``__op__()`` method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is called\n before that type's ``__op__()`` or ``__rop__()`` method is called,\n but no sooner. If the coercion returns an object of a different\n type for the operand whose coercion is invoked, part of the process\n is redone using the new object.\n\n* When an in-place operator (like '``+=``') is used, if the left\n operand implements ``__iop__()``, it is invoked without any\n coercion. When the operation falls back to ``__op__()`` and/or\n ``__rop__()``, the normal coercion rules apply.\n\n* In ``x + y``, if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In ``x * y``, if one operator is a sequence that implements sequence\n repetition, and the other is an integer (``int`` or ``long``),\n sequence repetition is invoked.\n\n* Rich comparisons (implemented by methods ``__eq__()`` and so on)\n never use coercion. Three-way comparison (implemented by\n ``__cmp__()``) does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types ``int``,\n ``long`` and ``float`` do not use coercion; the type ``complex``\n however does use coercion for binary operators and rich comparisons,\n despite the above rules. The difference can become apparent when\n subclassing these types. Over time, the type ``complex`` may be\n fixed to avoid coercion. All these types implement a\n ``__coerce__()`` method, for use by the built-in ``coerce()``\n function.\n", 'comparisons': u'\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 forms ``<>`` and ``!=`` are equivalent; for consistency with C,\n``!=`` is preferred; where ``!=`` is mentioned below ``<>`` is also\naccepted. The ``<>`` spelling is considered obsolescent.\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,\nobjects of different types *always* compare unequal, and are ordered\nconsistently but arbitrarily. You can control comparison behavior of\nobjects of non-builtin types by defining a ``__cmp__`` method or rich\ncomparison methods like ``__gt__``, described in section *Special\nmethod names*.\n\n(This unusual definition of comparison was used to simplify the\ndefinition of operations like sorting and the ``in`` and ``not in``\noperators. In the future, the comparison rules for objects of\ndifferent types are likely to change.)\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n Unicode and 8-bit strings are fully interoperable in this behavior.\n [4]\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, ``cmp([1,2,x], [1,2,y])`` returns\n the same as ``cmp(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 their sorted\n (key, value) lists compare equal. [5] Outcomes other than equality\n are resolved consistently, but are not otherwise defined. [6]\n\n* Most other objects of builtin 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\nThe operators ``in`` and ``not in`` test for collection membership.\n``x in s`` evaluates to true if *x* is a member of the collection *s*,\nand false otherwise. ``x not in s`` returns the negation of ``x in\ns``. The collection membership test has traditionally been bound to\nsequences; an object is a member of a collection if the collection is\na sequence and contains an element equal to that object. However, it\nmake sense for many other object types to support membership tests\nwithout being a sequence. In particular, dictionaries (for keys) and\nsets support membership testing.\n\nFor the list and tuple types, ``x in y`` is true if and only if there\nexists an index *i* such that ``x == y[i]`` is true.\n\nFor the Unicode and string types, ``x in y`` is true if and only if\n*x* is a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nNote, *x* and *y* need not be the same type; consequently, ``u\'ab\' in\n\'abc\'`` will return ``True``. Empty strings are always considered to\nbe a substring of any other string, so ``"" in "abc"`` will return\n``True``.\n\nChanged in version 2.3: Previously, *x* was required to be a string of\nlength ``1``.\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__()`` and do\ndefine ``__getitem__()``, ``x in y`` is true if and only if there is a\nnon-negative 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. [7]\n', - 'compound': u'\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. Function and class\ndefinitions are also syntactically compound 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`` statements 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 | decorated\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, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\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\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nWarning: 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 internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n 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 ["," target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nChanged in version 2.5: In previous versions of Python,\n``try``...``except``...``finally`` did not work. ``try``...``except``\nhad to be nested in ``try``...``finally``.\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, a tuple containing an item compatible with the\nexception, or, in the (deprecated) case of string exceptions, is the\nraised string itself (note that the object identities must match, i.e.\nit must be the same string object, not just a string with the same\nvalue).\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 in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the ``sys`` module:\n``sys.exc_type`` receives the object identifying the exception;\n``sys.exc_value`` receives the exception\'s parameter;\n``sys.exc_traceback`` receives a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. These details are also available through the\n``sys.exc_info()`` function, which returns a tuple ``(exc_type,\nexc_value, exc_traceback)``. Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables 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\nNew in version 2.5.\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" expression ["as" target] ":" suite\n\nThe execution of the ``with`` statement proceeds as follows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__enter__()`` method is invoked.\n\n3. 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 5 below.\n\n4. The suite is executed.\n\n5. 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\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\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 decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier [, "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\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 top-level 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 must also have a default value --- this is a syntactic\nrestriction 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.\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 *Expression lists*. Note that the lambda form is\nmerely a shorthand for a simplified function definition; a function\ndefined in a "``def``" statement can be passed around or assigned to\nanother name just like a function defined by a lambda form. The\n"``def``" form is actually more powerful since it allows the execution\nof multiple statements.\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 ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with ``self.name = value``.\nBoth class and instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\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': u'\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. Function and class\ndefinitions are also syntactically compound 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`` statements 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 | decorated\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, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\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\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nWarning: 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 internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n 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\nChanged in version 2.5: In previous versions of Python,\n``try``...``except``...``finally`` did not work. ``try``...``except``\nhad to be nested in ``try``...``finally``.\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, a tuple containing an item compatible with the\nexception, or, in the (deprecated) case of string exceptions, is the\nraised string itself (note that the object identities must match, i.e.\nit must be the same string object, not just a string with the same\nvalue).\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 in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the ``sys`` module:\n``sys.exc_type`` receives the object identifying the exception;\n``sys.exc_value`` receives the exception\'s parameter;\n``sys.exc_traceback`` receives a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. These details are also available through the\n``sys.exc_info()`` function, which returns a tuple ``(exc_type,\nexc_value, exc_traceback)``. Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables 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\nNew in version 2.5.\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" expression ["as" target] ":" suite\n\nThe execution of the ``with`` statement proceeds as follows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__enter__()`` method is invoked.\n\n3. 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 5 below.\n\n4. The suite is executed.\n\n5. 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\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\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 decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier [, "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\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 top-level 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 must also have a default value --- this is a syntactic\nrestriction 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.\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.\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 ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with ``self.name = value``.\nBoth class and instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\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': u'\nWith Statement Context Managers\n*******************************\n\nNew in version 2.5.\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': u'\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': u'\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," the arguments\nare coerced using the coercion rules listed at *Coercion rules*. If\nboth arguments are standard numeric types, the following coercions are\napplied:\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, if either argument is a long integer, the other is\n converted to long integer;\n\n* otherwise, both must be plain integers and no conversion is\n necessary.\n\nSome additional rules apply for certain operators (e.g., a string left\nargument to the \'%\' operator). Extensions can define their own\ncoercions.\n', - 'customization': u'\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_traceback`` 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.exc_traceback`` or ``sys.last_traceback``. Circular\n references which are garbage are detected when the option cycle\n detector is enabled (it\'s on by default), but can only be cleaned\n up if there are no Python-level ``__del__()`` methods involved.\n Refer to the documentation for the ``gc`` module for more\n information about how ``__del__()`` methods are handled by the\n cycle detector, particularly the description of the ``garbage``\n 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. For this reason, ``__del__()`` methods should do\n the absolute minimum needed to maintain external invariants.\n Starting with version 1.5, Python guarantees that globals whose\n name begins with a single underscore are deleted from their\n module before other globals are deleted; if no other references\n to such globals exist, this may help in assuring that imported\n modules are still available at the time when the ``__del__()``\n method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is 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 statement 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.__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 New in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` call ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and\n ``x>=y`` calls ``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\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by ``__cmp__()`` has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\n\nobject.__hash__(self)\n\n Called for the key object for dictionary operations, and by the\n built-in function ``hash()``. Should return an integer usable as a\n hash value for dictionary operations. The only required property\n is that objects which compare equal have the same hash value; it is\n advised to somehow mix together (e.g., using exclusive or) the hash\n values for the components of the object that also play a part in\n comparison of objects.\n\n If a class does not define a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable as dictionary keys. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n the dictionary implementation requires that a key\'s hash value is\n immutable (if the object\'s hash value changes, it will be in the\n wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` 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 ``__cmp__()`` or ``__eq__()`` such that\n the hash value returned is no longer appropriate (e.g. by switching\n to a value-based concept of equality instead of the default\n identity based equality) can explicitly flag themselves as being\n unhashable by setting ``__hash__ = None`` in the class definition.\n Doing so means that not only will instances of the class raise an\n appropriate ``TypeError`` when a program attempts to retrieve their\n hash value, but they will also be correctly identified as\n unhashable when checking ``isinstance(obj, collections.Hashable)``\n (unlike classes which define their own ``__hash__()`` to explicitly\n raise ``TypeError``).\n\n Changed in version 2.5: ``__hash__()`` may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\n Changed in version 2.6: ``__hash__`` may now be set to ``None`` to\n explicitly flag instances of a class as unhashable.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing, and the built-in operation\n ``bool()``; should return ``False`` or ``True``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined (see below). If a class\n defines neither ``__len__()`` nor ``__nonzero__()``, all its\n instances are considered true.\n\nobject.__unicode__(self)\n\n Called to implement ``unicode()`` builtin; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\n', + 'customization': u'\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_traceback`` 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.exc_traceback`` or ``sys.last_traceback``. Circular\n references which are garbage are detected when the option cycle\n detector is enabled (it\'s on by default), but can only be cleaned\n up if there are no Python-level ``__del__()`` methods involved.\n Refer to the documentation for the ``gc`` module for more\n information about how ``__del__()`` methods are handled by the\n cycle detector, particularly the description of the ``garbage``\n 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 and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is 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 statement 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.__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 New in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` call ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and\n ``x>=y`` calls ``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 the Total Ordering recipe in the ASPN cookbook.\n\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by ``__cmp__()`` has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\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 a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable in hashed collections. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n hashable collection implementations require that a object\'s hash\n value is immutable (if the object\'s hash value changes, it will be\n in the wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` 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 ``__cmp__()`` or ``__eq__()`` such that\n the hash value returned is no longer appropriate (e.g. by switching\n to a value-based concept of equality instead of the default\n identity based equality) can explicitly flag themselves as being\n unhashable by setting ``__hash__ = None`` in the class definition.\n Doing so means that not only will instances of the class raise an\n appropriate ``TypeError`` when a program attempts to retrieve their\n hash value, but they will also be correctly identified as\n unhashable when checking ``isinstance(obj, collections.Hashable)``\n (unlike classes which define their own ``__hash__()`` to explicitly\n raise ``TypeError``).\n\n Changed in version 2.5: ``__hash__()`` may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\n Changed in version 2.6: ``__hash__`` may now be set to ``None`` to\n explicitly flag instances of a class as unhashable.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing and the built-in operation\n ``bool()``; should return ``False`` or ``True``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined, and the object is\n considered true if its result is nonzero. If a class defines\n neither ``__len__()`` nor ``__nonzero__()``, all its instances are\n considered true.\n\nobject.__unicode__(self)\n\n Called to implement ``unicode()`` builtin; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\n', 'debugger': u'\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``\n(undocumented) and ``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 python -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 2.4: Restarting post-mortem behavior added.\n\nTypical 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[, locals]])\n\n Execute the *statement* (given as a string) under debugger control.\n The debugger prompt appears before any code is executed; you can\n set breakpoints and type ``continue``, or you can step through the\n statement using ``step`` or ``next`` (all these commands are\n explained below). The optional *globals* and *locals* arguments\n specify the environment in which the code is executed; by default\n the dictionary of the module ``__main__`` is used. (See the\n explanation of the ``exec`` statement or the ``eval()`` built-in\n function.)\n\npdb.runeval(expression[, globals[, locals]])\n\n Evaluate the *expression* (given as a string) under debugger\n control. When ``runeval()`` returns, it returns the value of the\n expression. Otherwise this function is similar to ``run()``.\n\npdb.runcall(function[, argument, ...])\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])\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', 'del': u'\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\nIt is illegal to delete a name from the local namespace if it occurs\nas a free variable in a nested block.\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', 'dict': u'\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] "}"\n key_datum_list ::= key_datum ("," key_datum)* [","]\n key_datum ::= expression ":" expression\n\nA dictionary display yields a new dictionary object.\n\nThe key/datum pairs are evaluated from left to right to define the\nentries of the dictionary: each key object is used as a key into the\ndictionary to store the corresponding datum.\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': u'\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\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n', 'else': u'\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', 'exceptions': u'\nExceptions\n**********\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nWarning: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', - 'exec': u'\nThe ``exec`` statement\n**********************\n\n exec_stmt ::= "exec" or_expr ["in" expression ["," expression]]\n\nThis statement supports dynamic execution of Python code. The first\nexpression should evaluate to either a string, an open file object, or\na code object. If it is a string, the string is parsed as a suite of\nPython statements which is then executed (unless a syntax error\noccurs). If it is an open file, the file is parsed until EOF and\nexecuted. If it is a code object, it is simply executed. In all\ncases, the code that\'s executed is expected to be valid as file input\n(see section *File input*). Be aware that the ``return`` and\n``yield`` statements may not be used outside of function definitions\neven within the context of code passed to the ``exec`` statement.\n\nIn all cases, if the optional parts are omitted, the code is executed\nin the current scope. If only the first expression after ``in`` is\nspecified, it should be a dictionary, which will be used for both the\nglobal and the local variables. If two expressions are given, they\nare used for the global and local variables, respectively. If\nprovided, *locals* can be any mapping object.\n\nChanged in version 2.4: Formerly, *locals* was required to be a\ndictionary.\n\nAs a side effect, an implementation may insert additional keys into\nthe dictionaries given besides those corresponding to variable names\nset by the executed code. For example, the current implementation may\nadd a reference to the dictionary of the built-in module\n``__builtin__`` under the key ``__builtins__`` (!).\n\n**Programmer\'s hints:** dynamic evaluation of expressions is supported\nby the built-in function ``eval()``. The built-in functions\n``globals()`` and ``locals()`` return the current global and local\ndictionary, respectively, which may be useful to pass around for use\nby ``exec``.\n', - 'execmodel': u'\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, or in\nthe second position of an ``except`` clause header. The ``import``\nstatement of the form "``from ...import *``" binds all names defined\nin the imported module, except those beginning with an underscore.\nThis form may only be used at the module level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtin namespace, the namespace of\nthe module ``__builtin__``. The global namespace is searched first.\nIf the name is not found there, the builtin namespace is searched.\nThe global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no \'s\'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``__builtin__`` (no \'s\')\n module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\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\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nWarning: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', + 'exec': u'\nThe ``exec`` statement\n**********************\n\n exec_stmt ::= "exec" or_expr ["in" expression ["," expression]]\n\nThis statement supports dynamic execution of Python code. The first\nexpression should evaluate to either a string, an open file object, or\na code object. If it is a string, the string is parsed as a suite of\nPython statements which is then executed (unless a syntax error\noccurs). [1] If it is an open file, the file is parsed until EOF and\nexecuted. If it is a code object, it is simply executed. In all\ncases, the code that\'s executed is expected to be valid as file input\n(see section *File input*). Be aware that the ``return`` and\n``yield`` statements may not be used outside of function definitions\neven within the context of code passed to the ``exec`` statement.\n\nIn all cases, if the optional parts are omitted, the code is executed\nin the current scope. If only the first expression after ``in`` is\nspecified, it should be a dictionary, which will be used for both the\nglobal and the local variables. If two expressions are given, they\nare used for the global and local variables, respectively. If\nprovided, *locals* can be any mapping object.\n\nChanged in version 2.4: Formerly, *locals* was required to be a\ndictionary.\n\nAs a side effect, an implementation may insert additional keys into\nthe dictionaries given besides those corresponding to variable names\nset by the executed code. For example, the current implementation may\nadd a reference to the dictionary of the built-in module\n``__builtin__`` under the key ``__builtins__`` (!).\n\n**Programmer\'s hints:** dynamic evaluation of expressions is supported\nby the built-in function ``eval()``. The built-in functions\n``globals()`` and ``locals()`` return the current global and local\ndictionary, respectively, which may be useful to pass around for use\nby ``exec``.\n\n-[ Footnotes ]-\n\n[1] Note that the parser only accepts the Unix-style end of line\n convention. If you are reading the code from a file, make sure to\n use universal newline mode to convert Windows or Mac-style\n newlines.\n', + 'execmodel': u'\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, in the\nsecond position of an ``except`` clause header or after ``as`` in a\n``with`` statement. The ``import`` statement of the form ``from ...\nimport *`` binds all names defined in the imported module, except\nthose beginning with an underscore. This form may only be used at the\nmodule level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtin namespace, the namespace of\nthe module ``__builtin__``. The global namespace is searched first.\nIf the name is not found there, the builtin namespace is searched.\nThe global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no \'s\'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``__builtin__`` (no \'s\')\n module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\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\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nWarning: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', 'exprlists': u'\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': u'\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 of floating point numbers can\nlook like octal integers, but are interpreted using radix 10. For\nexample, ``077e010`` is legal, and denotes the same number as\n``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': u'\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, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\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\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nWarning: 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 internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n 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': u'\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 ::= (identifier | integer) ("." attribute_name | "[" element_index "]")*\n attribute_name ::= identifier\n element_index ::= integer\n conversion ::= "r" | "s"\n format_spec ::= \n\nIn less formal terms, the replacement field starts with a\n*field_name*, which can either be a number (for a positional\nargument), or an identifier (for keyword arguments). Following this\nis an optional *conversion* field, which is preceded by an exclamation\npoint ``\'!\'``, and a *format_spec*, which is preceded by a colon\n``\':\'``.\n\nThe *field_name* itself begins with either a number or a keyword. If\nit\'s a number, it refers to a positional argument, and if it\'s a\nkeyword it refers to a named keyword argument. This can be followed\nby any number of index or attribute expressions. An expression of the\nform ``\'.name\'`` selects the named attribute using ``getattr()``,\nwhile an expression of the form ``\'[index]\'`` does an index lookup\nusing ``__getitem__()``.\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\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\nTwo conversion flags are currently supported: ``\'!s\'`` which calls\n``str()`` on the value, and ``\'!r\'`` which calls ``repr()``.\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\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 it\'s\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\nFor example, suppose you wanted to have a replacement field whose\nfield width is determined by another variable:\n\n "A man with two {0:{1}}".format("noses", 10)\n\nThis would first evaluate the inner replacement field, making the\nformat string effectively:\n\n "A man with two {0:10}"\n\nThen the outer replacement field would be evaluated, producing:\n\n "noses "\n\nWhich is substituted into the string, yielding:\n\n "A man with two noses "\n\n(The extra space is because we specified a field width of 10, and\nbecause left alignment is the default for strings.)\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\nbuiltin ``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.\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" | "x" | "X" | "%"\n\nThe *fill* character can be any character other than \'}\' (which\nsignifies the end of the field). The presence of a fill character is\nsignaled by the *next* character, which must be one of the alignment\noptions. If the second character of *format_spec* is not a valid\nalignment option, then it is assumed that both the fill character and\nthe alignment option are absent.\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\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 ignored for integer values.\n\nFinally, the *type* determines how the data should be presented.\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\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\'``. |\n +-----------+------------------------------------------------------------+\n | ``\'g\'`` | General format. This prints the number as a fixed-point |\n | | number, unless the number is too large, in which case it |\n | | switches to ``\'e\'`` exponent notation. Infinity and NaN |\n | | values are formatted as ``inf``, ``-inf`` and ``nan``, |\n | | respectively. |\n +-----------+------------------------------------------------------------+\n | ``\'G\'`` | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n | | if the number gets to 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 | The same as ``\'g\'``. |\n +-----------+------------------------------------------------------------+\n', - 'function': u'\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier [, "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\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 top-level 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 must also have a default value --- this is a syntactic\nrestriction 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.\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 *Expression lists*. Note that the lambda form is\nmerely a shorthand for a simplified function definition; a function\ndefined in a "``def``" statement can be passed around or assigned to\nanother name just like a function defined by a lambda form. The\n"``def``" form is actually more powerful since it allows the execution\nof multiple statements.\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', + 'for': u'\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, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\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\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nWarning: 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 internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n 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': u'\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\n conversion ::= "r" | "s"\n format_spec ::= \n\nIn less formal terms, the replacement field starts with a *field_name*\nthat specifies the object whose value is to be formatted and inserted\ninto the output instead of the replacement field. The *field_name* is\noptionally followed by a *conversion* field, which is preceded by an\nexclamation point ``\'!\'``, and a *format_spec*, which is preceded by a\ncolon ``\':\'``. These specify a non-default format for the replacement\nvalue.\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\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\nTwo conversion flags are currently supported: ``\'!s\'`` which calls\n``str()`` on the value, and ``\'!r\'`` which calls ``repr()``.\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\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 it\'s\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\nFor example, suppose you wanted to have a replacement field whose\nfield width is determined by another variable:\n\n "A man with two {0:{1}}".format("noses", 10)\n\nThis would first evaluate the inner replacement field, making the\nformat string effectively:\n\n "A man with two {0:10}"\n\nThen the outer replacement field would be evaluated, producing:\n\n "noses "\n\nWhich is substituted into the string, yielding:\n\n "A man with two noses "\n\n(The extra space is because we specified a field width of 10, and\nbecause left alignment is the default for strings.)\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\nbuiltin ``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.\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" | "x" | "X" | "%"\n\nThe *fill* character can be any character other than \'}\' (which\nsignifies the end of the field). The presence of a fill character is\nsignaled by the *next* character, which must be one of the alignment\noptions. If the second character of *format_spec* is not a valid\nalignment option, then it is assumed that both the fill character and\nthe alignment option are absent.\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\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 ignored for integer values.\n\nFinally, the *type* determines how the data should be presented.\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\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\'``. |\n +-----------+------------------------------------------------------------+\n | ``\'g\'`` | General format. This prints the number as a fixed-point |\n | | number, unless the number is too large, in which case it |\n | | switches to ``\'e\'`` exponent notation. Infinity and NaN |\n | | values are formatted as ``inf``, ``-inf`` and ``nan``, |\n | | respectively. |\n +-----------+------------------------------------------------------------+\n | ``\'G\'`` | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n | | if the number gets to 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 | The same as ``\'g\'``. |\n +-----------+------------------------------------------------------------+\n', + 'function': u'\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier [, "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\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 top-level 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 must also have a default value --- this is a syntactic\nrestriction 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.\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.\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': u'\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(The current implementation does not enforce the latter two\nrestrictions, but programs should not abuse this freedom, as future\nimplementations may enforce them or silently change the meaning of the\nprogram.)\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 an\n``exec`` statement does not affect the code block *containing* the\n``exec`` statement, and code contained in an ``exec`` statement is\nunaffected by ``global`` statements in the code containing the\n``exec`` statement. The same applies to the ``eval()``,\n``execfile()`` and ``compile()`` functions.\n', 'id-classes': u'\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 ``__builtin__`` module.\n When not in interactive mode, ``_`` has no special meaning and is\n not 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);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\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': u'\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions:\n\n identifier ::= (letter|"_") (letter | digit | "_")*\n letter ::= lowercase | uppercase\n lowercase ::= "a"..."z"\n uppercase ::= "A"..."Z"\n digit ::= "0"..."9"\n\nIdentifiers are unlimited in length. Case is significant.\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 and del from not while\n as elif global or with\n assert else if pass yield\n break except import print\n class exec in raise\n continue finally is return\n def for lambda try\n\nChanged in version 2.4: ``None`` became a constant and is now\nrecognized by the compiler as a name for the built-in object ``None``.\nAlthough it is not a keyword, you cannot assign a different object to\nit.\n\nChanged in version 2.5: Both ``as`` and ``with`` are only recognized\nwhen the ``with_statement`` future feature has been enabled. It will\nalways be enabled in Python 2.6. See section *The with statement* for\ndetails. Note that using ``as`` and ``with`` as identifiers will\nalways issue a warning, even when the ``with_statement`` future\ndirective is not in effect.\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 ``__builtin__`` module.\n When not in interactive mode, ``_`` has no special meaning and is\n not 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);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\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': u'\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': u'\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': u'\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\nfirst form (without ``from``) repeats these steps for each identifier\nin the list. The form with ``from`` performs step (1) once, and then\nperforms step (2) repeatedly.\n\nIn this context, to "initialize" a built-in or extension module means\nto call an initialization function that the module must provide for\nthe purpose (in the reference implementation, the function\'s name is\nobtained by prepending string "init" to the module\'s name); to\n"initialize" a Python-coded module means to execute the module\'s body.\n\nThe system maintains a table of modules that have been or are being\ninitialized, indexed by module name. This table is accessible as\n``sys.modules``. When a module name is found in this table, step (1)\nis finished. If not, a search for a module definition is started.\nWhen a module is found, it is loaded. Details of the module searching\nand loading process are implementation and platform specific. It\ngenerally involves searching for a "built-in" module with the given\nname and then searching a list of locations given as ``sys.path``.\n\nIf a built-in module is found, its built-in initialization code is\nexecuted and step (1) is finished. If no matching file is found,\n``ImportError`` is raised. If a file is found, it is parsed, yielding\nan executable code block. If a syntax error occurs, ``SyntaxError``\nis raised. Otherwise, an empty module of the given name is created\nand inserted in the module table, and then the code block is executed\nin the context of this module. Exceptions during this execution\nterminate step (1).\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. If the\nwild card form of import --- ``import *`` --- is used in a function\nand the function contains or is a nested block with free variables,\nthe compiler will raise a ``SyntaxError``.\n\n**Hierarchical module names:** when the module names contains one or\nmore dots, the module search path is carried out differently. The\nsequence of identifiers up to the last dot is used to find a\n"package"; the final identifier is then searched inside the package.\nA package is generally a subdirectory of a directory on ``sys.path``\nthat has a file ``__init__.py``.\n\nThe built-in function ``__import__()`` is provided to support\napplications that determine which modules need to be loaded\ndynamically; refer to *Built-in Functions* for additional information.\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 2.5 are ``absolute_import``,\n``division``, ``generators``, ``nested_scopes`` and\n``with_statement``. ``generators`` and ``nested_scopes`` are\nredundant in Python version 2.3 and above because they are always\nenabled.\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 an ``exec`` statement or calls to the builtin\nfunctions ``compile()`` and ``execfile()`` that occur in a module\n``M`` containing a future statement will, by default, use the new\nsyntax or semantics associated with the future statement. This can,\nstarting with Python 2.2 be controlled by optional arguments to\n``compile()`` --- see the documentation of that function for 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', + 'import': u'\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.\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.\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. If the\nwild card form of import --- ``import *`` --- is used in a function\nand the function contains or is a nested block with free variables,\nthe compiler will 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\nimprt mod`` from within ``pkg.subpkg1`` you will import\n``pkg.subpkg2.mod``. The specification for relative imports is\ncontained within **PEP 328**.\n\nThe built-in function ``__import__()`` is provided to support\napplications that determine which modules need to be loaded\ndynamically; refer to *Built-in Functions* for additional information.\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 2.6 are ``unicode_literals``,\n``print_function``, ``absolute_import``, ``division``, ``generators``,\n``nested_scopes`` and ``with_statement``. ``generators``,\n``with_statement``, ``nested_scopes`` are redundant in Python version\n2.6 and above because they are always enabled.\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 an ``exec`` statement or calls to the builtin\nfunctions ``compile()`` and ``execfile()`` that occur in a module\n``M`` containing a future statement will, by default, use the new\nsyntax or semantics associated with the future statement. This can,\nstarting with Python 2.2 be controlled by optional arguments to\n``compile()`` --- see the documentation of that function for 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': u'\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 forms ``<>`` and ``!=`` are equivalent; for consistency with C,\n``!=`` is preferred; where ``!=`` is mentioned below ``<>`` is also\naccepted. The ``<>`` spelling is considered obsolescent.\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,\nobjects of different types *always* compare unequal, and are ordered\nconsistently but arbitrarily. You can control comparison behavior of\nobjects of non-builtin types by defining a ``__cmp__`` method or rich\ncomparison methods like ``__gt__``, described in section *Special\nmethod names*.\n\n(This unusual definition of comparison was used to simplify the\ndefinition of operations like sorting and the ``in`` and ``not in``\noperators. In the future, the comparison rules for objects of\ndifferent types are likely to change.)\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n Unicode and 8-bit strings are fully interoperable in this behavior.\n [4]\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, ``cmp([1,2,x], [1,2,y])`` returns\n the same as ``cmp(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 their sorted\n (key, value) lists compare equal. [5] Outcomes other than equality\n are resolved consistently, but are not otherwise defined. [6]\n\n* Most other objects of builtin 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\nThe operators ``in`` and ``not in`` test for collection membership.\n``x in s`` evaluates to true if *x* is a member of the collection *s*,\nand false otherwise. ``x not in s`` returns the negation of ``x in\ns``. The collection membership test has traditionally been bound to\nsequences; an object is a member of a collection if the collection is\na sequence and contains an element equal to that object. However, it\nmake sense for many other object types to support membership tests\nwithout being a sequence. In particular, dictionaries (for keys) and\nsets support membership testing.\n\nFor the list and tuple types, ``x in y`` is true if and only if there\nexists an index *i* such that ``x == y[i]`` is true.\n\nFor the Unicode and string types, ``x in y`` is true if and only if\n*x* is a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nNote, *x* and *y* need not be the same type; consequently, ``u\'ab\' in\n\'abc\'`` will return ``True``. Empty strings are always considered to\nbe a substring of any other string, so ``"" in "abc"`` will return\n``True``.\n\nChanged in version 2.3: Previously, *x* was required to be a string of\nlength ``1``.\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__()`` and do\ndefine ``__getitem__()``, ``x in y`` is true if and only if there is a\nnon-negative 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. [7]\n', - 'integers': u'\nInteger and long integer literals\n*********************************\n\nInteger and long integer literals are described by the following\nlexical definitions:\n\n longinteger ::= integer ("l" | "L")\n integer ::= decimalinteger | octinteger | hexinteger\n decimalinteger ::= nonzerodigit digit* | "0"\n octinteger ::= "0" octdigit+\n hexinteger ::= "0" ("x" | "X") hexdigit+\n nonzerodigit ::= "1"..."9"\n octdigit ::= "0"..."7"\n hexdigit ::= digit | "a"..."f" | "A"..."F"\n\nAlthough both lower case ``\'l\'`` and upper case ``\'L\'`` are allowed as\nsuffix for long integers, it is strongly recommended to always use\n``\'L\'``, since the letter ``\'l\'`` looks too much like the digit\n``\'1\'``.\n\nPlain integer literals that are above the largest representable plain\ninteger (e.g., 2147483647 when using 32-bit arithmetic) are accepted\nas if they were long integers instead. [1] There is no limit for long\ninteger literals apart from what can be stored in available memory.\n\nSome examples of plain integer literals (first row) and long integer\nliterals (second and third rows):\n\n 7 2147483647 0177\n 3L 79228162514264337593543950336L 0377L 0x100000000L\n 79228162514264337593543950336 0xdeadbeef\n', - 'lambda': u'\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', + 'integers': u'\nInteger and long integer literals\n*********************************\n\nInteger and long integer literals are described by the following\nlexical definitions:\n\n longinteger ::= integer ("l" | "L")\n integer ::= decimalinteger | octinteger | hexinteger | bininteger\n decimalinteger ::= nonzerodigit digit* | "0"\n octinteger ::= "0" ("o" | "O") octdigit+ | "0" octdigit+\n hexinteger ::= "0" ("x" | "X") hexdigit+\n bininteger ::= "0" ("b" | "B") bindigit+\n nonzerodigit ::= "1"..."9"\n octdigit ::= "0"..."7"\n bindigit ::= "0" | "1"\n hexdigit ::= digit | "a"..."f" | "A"..."F"\n\nAlthough both lower case ``\'l\'`` and upper case ``\'L\'`` are allowed as\nsuffix for long integers, it is strongly recommended to always use\n``\'L\'``, since the letter ``\'l\'`` looks too much like the digit\n``\'1\'``.\n\nPlain integer literals that are above the largest representable plain\ninteger (e.g., 2147483647 when using 32-bit arithmetic) are accepted\nas if they were long integers instead. [1] There is no limit for long\ninteger literals apart from what can be stored in available memory.\n\nSome examples of plain integer literals (first row) and long integer\nliterals (second and third rows):\n\n 7 2147483647 0177\n 3L 79228162514264337593543950336L 0377L 0x100000000L\n 79228162514264337593543950336 0xdeadbeef\n', + 'lambda': u'\nLambdas\n*******\n\n lambda_form ::= "lambda" [parameter_list]: expression\n old_lambda_form ::= "lambda" [parameter_list]: old_expression\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 name(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.\n', 'lists': u'\nList displays\n*************\n\nA list display is a possibly empty series of expressions enclosed in\nsquare brackets:\n\n list_display ::= "[" [expression_list | list_comprehension] "]"\n list_comprehension ::= expression list_for\n list_for ::= "for" target_list "in" old_expression_list [list_iter]\n old_expression_list ::= old_expression [("," old_expression)+ [","]]\n list_iter ::= list_for | list_if\n list_if ::= "if" old_expression [list_iter]\n\nA list display yields a new list object. Its contents are specified\nby providing either a list of expressions or a list comprehension.\nWhen a comma-separated list of expressions is supplied, its elements\nare evaluated from left to right and placed into the list object in\nthat order. When a list comprehension is supplied, it consists of a\nsingle expression followed by at least one ``for`` clause and zero or\nmore ``for`` or ``if`` clauses. In this case, the elements of the new\nlist are those that would be produced by considering each of the\n``for`` or ``if`` clauses a block, nesting from left to right, and\nevaluating the expression to produce a list element each time the\ninnermost block is reached [1].\n', - 'naming': u'\nNaming and binding\n******************\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, or in\nthe second position of an ``except`` clause header. The ``import``\nstatement of the form "``from ...import *``" binds all names defined\nin the imported module, except those beginning with an underscore.\nThis form may only be used at the module level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtin namespace, the namespace of\nthe module ``__builtin__``. The global namespace is searched first.\nIf the name is not found there, the builtin namespace is searched.\nThe global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no \'s\'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``__builtin__`` (no \'s\')\n module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\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\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n', + 'naming': u"\nNaming and binding\n******************\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the '**-c**' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block's execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block's *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, in the\nsecond position of an ``except`` clause header or after ``as`` in a\n``with`` statement. The ``import`` statement of the form ``from ...\nimport *`` binds all names defined in the imported module, except\nthose beginning with an underscore. This form may only be used at the\nmodule level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtin namespace, the namespace of\nthe module ``__builtin__``. The global namespace is searched first.\nIf the name is not found there, the builtin namespace is searched.\nThe global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module's dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no 's'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``__builtin__`` (no 's')\n module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\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\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n", 'numbers': u"\nNumeric literals\n****************\n\nThere are four types of numeric literals: plain integers, long\nintegers, floating point numbers, and imaginary numbers. There are no\ncomplex literals (complex numbers can be formed by adding a real\nnumber and an imaginary 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': u'\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.__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 (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression ``x + y``, where *x* is an\n 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__()`` (described below). Note\n that ``__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.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(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 (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [3] For instance, to evaluate\n the expression ``x - y``, where *y* is an instance of a class that\n has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *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.__idiv__(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 operations (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\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 operation falls back to the normal methods. For instance, to\n evaluate the expression ``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.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``long()``, and ``float()``. Should return a value of\n the appropriate type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions ``oct()`` and ``hex()``.\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n New in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or ``None`` if conversion is impossible. When\n the common type would be the type of ``other``, it is sufficient to\n return ``None``, since the interpreter will also ask the other\n object to attempt a coercion (but sometimes, if the implementation\n of the other type cannot be changed, it is useful to do the\n conversion to the other type here). A return value of\n ``NotImplemented`` is equivalent to returning ``None``.\n', - 'objects': u'\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. (Implementation note: the current implementation uses a\nreference-counting scheme with (optional) delayed detection of\ncyclically linked garbage, which collects most objects as soon as they\nbecome unreachable, but is not guaranteed to collect garbage\ncontaining circular references. See the documentation of the ``gc``\nmodule for information on controlling the collection of cyclic\ngarbage.)\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 provides a convenient way to do\nthis.\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': u'\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| ``or`` | Boolean OR |\n+-------------------------------------------------+---------------------------------------+\n| ``and`` | Boolean AND |\n+-------------------------------------------------+---------------------------------------+\n| ``not`` *x* | Boolean NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``in``, ``not`` ``in`` | Membership tests |\n+-------------------------------------------------+---------------------------------------+\n| ``is``, ``is not`` | Identity tests |\n+-------------------------------------------------+---------------------------------------+\n| ``<``, ``<=``, ``>``, ``>=``, ``<>``, ``!=``, | Comparisons |\n| ``==`` | |\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+-------------------------------------------------+---------------------------------------+\n| ``+x``, ``-x`` | Positive, negative |\n+-------------------------------------------------+---------------------------------------+\n| ``~x`` | Bitwise not |\n+-------------------------------------------------+---------------------------------------+\n| ``**`` | Exponentiation |\n+-------------------------------------------------+---------------------------------------+\n| ``x[index]`` | Subscription |\n+-------------------------------------------------+---------------------------------------+\n| ``x[index:index]`` | Slicing |\n+-------------------------------------------------+---------------------------------------+\n| ``x(arguments...)`` | Call |\n+-------------------------------------------------+---------------------------------------+\n| ``x.attribute`` | Attribute reference |\n+-------------------------------------------------+---------------------------------------+\n| ``(expressions...)`` | Binding or tuple display |\n+-------------------------------------------------+---------------------------------------+\n| ``[expressions...]`` | List display |\n+-------------------------------------------------+---------------------------------------+\n| ``{key:datum...}`` | Dictionary display |\n+-------------------------------------------------+---------------------------------------+\n| ```expressions...``` | String conversion |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] In Python 2.3 and later releases, a list comprehension "leaks" the\n control variables of each ``for`` it contains into the containing\n scope. However, this behavior is deprecated, and relying on it\n will not work in Python 3.0\n\n[2] 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[3] If x is very close to an exact integer multiple of y, it\'s\n possible for ``floor(x/y)`` to be one larger than ``(x-x%y)/y``\n due to rounding. In such cases, Python returns the latter result,\n in order to preserve that ``divmod(x,y)[0] * y + x % y`` be very\n close to ``x``.\n\n[4] While comparisons between unicode strings make sense at the byte\n level, they may be counter-intuitive to users. For example, the\n strings ``u"\\u00C7"`` and ``u"\\u0043\\u0327"`` compare differently,\n even though they both represent the same unicode character (LATIN\n CAPTITAL LETTER C WITH CEDILLA). To compare strings in a human\n recognizable way, compare using ``unicodedata.normalize()``.\n\n[5] The implementation computes this efficiently, without constructing\n lists or sorting.\n\n[6] Earlier versions of Python used lexicographic comparison of the\n sorted (key, value) lists, but this was very expensive for the\n common case of comparing for equality. An even earlier version of\n Python compared dictionaries by identity only, but this caused\n surprises because people expected to be able to test a dictionary\n for emptiness by comparing it to ``{}``.\n\n[7] 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', + 'numeric-types': u'\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.__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 (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression ``x + y``, where *x* is an\n 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__()`` (described below). Note\n that ``__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.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(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 (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [3] For instance, to evaluate\n the expression ``x - y``, where *y* is an instance of a class that\n has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *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.__idiv__(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.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``long()``, and ``float()``. Should return a value of\n the appropriate type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions ``oct()`` and ``hex()``.\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n New in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or ``None`` if conversion is impossible. When\n the common type would be the type of ``other``, it is sufficient to\n return ``None``, since the interpreter will also ask the other\n object to attempt a coercion (but sometimes, if the implementation\n of the other type cannot be changed, it is useful to do the\n conversion to the other type here). A return value of\n ``NotImplemented`` is equivalent to returning ``None``.\n', + 'objects': u'\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. (Implementation note: 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 provides a convenient way to do\nthis.\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': u'\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| ``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+-------------------------------------------------+---------------------------------------+\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+-------------------------------------------------+---------------------------------------+\n| ``+x``, ``-x``, ``~x`` | Positive, negative, bitwise NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``**`` | Exponentiation [8] |\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, string |\n| | conversion |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] In Python 2.3 and later releases, a list comprehension "leaks" the\n control variables of each ``for`` it contains into the containing\n scope. However, this behavior is deprecated, and relying on it\n will not work in Python 3.0\n\n[2] 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[3] If x is very close to an exact integer multiple of y, it\'s\n possible for ``floor(x/y)`` to be one larger than ``(x-x%y)/y``\n due to rounding. In such cases, Python returns the latter result,\n in order to preserve that ``divmod(x,y)[0] * y + x % y`` be very\n close to ``x``.\n\n[4] While comparisons between unicode strings make sense at the byte\n level, they may be counter-intuitive to users. For example, the\n strings ``u"\\u00C7"`` and ``u"\\u0043\\u0327"`` compare differently,\n even though they both represent the same unicode character (LATIN\n CAPTITAL LETTER C WITH CEDILLA). To compare strings in a human\n recognizable way, compare using ``unicodedata.normalize()``.\n\n[5] The implementation computes this efficiently, without constructing\n lists or sorting.\n\n[6] Earlier versions of Python used lexicographic comparison of the\n sorted (key, value) lists, but this was very expensive for the\n common case of comparing for equality. An even earlier version of\n Python compared dictionaries by identity only, but this caused\n surprises because people expected to be able to test a dictionary\n for emptiness by comparing it to ``{}``.\n\n[7] 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[8] 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': u'\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': u'\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. The result type is that of the\narguments after coercion.\n\nWith mixed operand types, the coercion rules for binary arithmetic\noperators apply. For int and long int operands, the result has the\nsame type as the operands (after coercion) unless the second argument\nis negative; in that case, all arguments are converted to float and a\nfloat result is delivered. For example, ``10**2`` returns ``100``, but\n``10**-2`` returns ``0.01``. (This last feature was added in Python\n2.2. In Python 2.1 and before, if both arguments were of integer types\nand the second argument was negative, an exception was raised).\n\nRaising ``0.0`` to a negative power results in a\n``ZeroDivisionError``. Raising a negative number to a fractional power\nresults in a ``ValueError``.\n', 'print': u'\nThe ``print`` statement\n***********************\n\n print_stmt ::= "print" ([expression ("," expression)* [","]]\n | ">>" expression [("," expression)+ [","]])\n\n``print`` evaluates each expression in turn and writes the resulting\nobject to standard output (see below). If an object is not a string,\nit is first converted to a string using the rules for string\nconversions. The (resulting or original) string is then written. A\nspace is written before each object is (converted and) written, unless\nthe output system believes it is positioned at the beginning of a\nline. This is the case (1) when no characters have yet been written\nto standard output, (2) when the last character written to standard\noutput is ``\'\\n\'``, or (3) when the last write operation on standard\noutput was not a ``print`` statement. (In some cases it may be\nfunctional to write an empty string to standard output for this\nreason.)\n\nNote: Objects which act like file objects but which are not the built-in\n file objects often do not properly emulate this aspect of the file\n object\'s behavior, so it is best not to rely on this.\n\nA ``\'\\n\'`` character is written at the end, unless the ``print``\nstatement ends with a comma. This is the only action if the statement\ncontains just the keyword ``print``.\n\nStandard output is defined as the file object named ``stdout`` in the\nbuilt-in module ``sys``. If no such object exists, or if it does not\nhave a ``write()`` method, a ``RuntimeError`` exception is raised.\n\n``print`` also has an extended form, defined by the second portion of\nthe syntax described above. This form is sometimes referred to as\n"``print`` chevron." In this form, the first expression after the\n``>>`` must evaluate to a "file-like" object, specifically an object\nthat has a ``write()`` method as described above. With this extended\nform, the subsequent expressions are printed to this file object. If\nthe first expression evaluates to ``None``, then ``sys.stdout`` is\nused as the file for output.\n', @@ -62,22 +62,22 @@ 'sequence-types': u"\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. (For backwards compatibility, the method\n``__getslice__()`` (see below) can also be defined to handle simple,\nbut not extended slices.) It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``has_key()``,\n``get()``, ``clear()``, ``setdefault()``, ``iterkeys()``,\n``itervalues()``, ``iteritems()``, ``pop()``, ``popitem()``,\n``copy()``, and ``update()`` behaving similar to those for Python's\nstandard dictionary objects. The ``UserDict`` module provides a\n``DictMixin`` class to help create those methods from a base set of\n``__getitem__()``, ``__setitem__()``, ``__delitem__()``, and\n``keys()``. Mutable sequences should provide methods ``append()``,\n``count()``, ``index()``, ``extend()``, ``insert()``, ``pop()``,\n``remove()``, ``reverse()`` and ``sort()``, like Python standard list\nobjects. Finally, sequence types should implement addition (meaning\nconcatenation) and multiplication (meaning repetition) by defining the\nmethods ``__add__()``, ``__radd__()``, ``__iadd__()``, ``__mul__()``,\n``__rmul__()`` and ``__imul__()`` described below; they should not\ndefine ``__coerce__()`` or other numerical operators. It is\nrecommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should be equivalent of ``has_key()``;\nfor sequences, 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``iterkeys()``; 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 ``__nonzero__()`` method and whose\n ``__len__()`` method returns zero is considered to be false in a\n Boolean context.\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 ``iterkeys()``.\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()`` builtin 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()`` builtin will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects should\n normally only provide ``__reversed__()`` if they do not support the\n sequence protocol and an efficient implementation of reverse\n iteration is possible.\n\n New in version 2.6.\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", 'shifting': u'\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 plain or long integers as arguments. The\narguments are converted to a common type. 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,\nn)``. Negative shift counts raise a ``ValueError`` exception.\n', 'slicings': u'\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 ::= simple_slicing | extended_slicing\n simple_slicing ::= primary "[" short_slice "]"\n extended_slicing ::= primary "[" slice_list "]"\n slice_list ::= slice_item ("," slice_item)* [","]\n slice_item ::= expression | proper_slice | ellipsis\n proper_slice ::= short_slice | long_slice\n short_slice ::= [lower_bound] ":" [upper_bound]\n long_slice ::= short_slice ":" [stride]\n lower_bound ::= expression\n upper_bound ::= expression\n stride ::= expression\n ellipsis ::= "..."\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 nor ellipses). Similarly, when the slice\nlist has exactly one short slice and no trailing comma, the\ninterpretation as a simple slicing takes priority over that as an\nextended slicing.\n\nThe semantics for a simple slicing are as follows. The primary must\nevaluate to a sequence object. The lower and upper bound expressions,\nif present, must evaluate to plain integers; defaults are zero and the\n``sys.maxint``, respectively. If either bound is negative, the\nsequence\'s length is added to it. The slicing now selects all items\nwith index *k* such that ``i <= k < j`` where *i* and *j* are the\nspecified lower and upper bounds. This may be an empty sequence. It\nis not an error if *i* or *j* lie outside the range of valid indexes\n(such items don\'t exist so they aren\'t selected).\n\nThe semantics for an extended slicing are as follows. The primary\nmust evaluate to a mapping object, and it is indexed with a key that\nis constructed 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 an ellipsis slice\nitem is the built-in ``Ellipsis`` object. The conversion of a proper\nslice is a slice object (see section *The standard type hierarchy*)\nwhose ``start``, ``stop`` and ``step`` attributes are the values of\nthe expressions given as lower bound, upper bound and stride,\nrespectively, substituting ``None`` for missing expressions.\n', - 'specialattrs': u"\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\nobject.__methods__\n\n Deprecated since version 2.2: Use the built-in function ``dir()``\n to get a list of an object's attributes. This attribute is no\n longer available.\n\nobject.__members__\n\n Deprecated since version 2.2: Use the built-in function ``dir()``\n to get a list of an object's attributes. This attribute is no\n longer available.\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. If there are no base\n classes, this will be an empty tuple.\n\nclass.__name__\n\n The name of the class or type.\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\n[5] These numbers are fairly arbitrary. They are intended to avoid\n printing endless strings of meaningless digits without hampering\n correct use and without having to know the exact precision of\n floating point values on a particular machine.\n\n[6] The advantage of leaving the newline on is that returning an empty\n string is then an unambiguous EOF indication. It is also possible\n (in cases where it might matter, for example, if you want to make\n an exact copy of a file while scanning its lines) to tell whether\n the last line of a file ended in a newline or not (yes this\n happens!).\n", - 'specialnames': u'\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 ``x.__getitem__(i)`` for\nold-style classes and ``type(x).__getitem__(x, i)`` for new-style\nclasses. Except where mentioned, attempts to execute an operation\nraise an 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_traceback`` 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.exc_traceback`` or ``sys.last_traceback``. Circular\n references which are garbage are detected when the option cycle\n detector is enabled (it\'s on by default), but can only be cleaned\n up if there are no Python-level ``__del__()`` methods involved.\n Refer to the documentation for the ``gc`` module for more\n information about how ``__del__()`` methods are handled by the\n cycle detector, particularly the description of the ``garbage``\n 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. For this reason, ``__del__()`` methods should do\n the absolute minimum needed to maintain external invariants.\n Starting with version 1.5, Python guarantees that globals whose\n name begins with a single underscore are deleted from their\n module before other globals are deleted; if no other references\n to such globals exist, this may help in assuring that imported\n modules are still available at the time when the ``__del__()``\n method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is 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 statement 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.__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 New in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` call ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and\n ``x>=y`` calls ``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\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by ``__cmp__()`` has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\n\nobject.__hash__(self)\n\n Called for the key object for dictionary operations, and by the\n built-in function ``hash()``. Should return an integer usable as a\n hash value for dictionary operations. The only required property\n is that objects which compare equal have the same hash value; it is\n advised to somehow mix together (e.g., using exclusive or) the hash\n values for the components of the object that also play a part in\n comparison of objects.\n\n If a class does not define a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable as dictionary keys. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n the dictionary implementation requires that a key\'s hash value is\n immutable (if the object\'s hash value changes, it will be in the\n wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` 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 ``__cmp__()`` or ``__eq__()`` such that\n the hash value returned is no longer appropriate (e.g. by switching\n to a value-based concept of equality instead of the default\n identity based equality) can explicitly flag themselves as being\n unhashable by setting ``__hash__ = None`` in the class definition.\n Doing so means that not only will instances of the class raise an\n appropriate ``TypeError`` when a program attempts to retrieve their\n hash value, but they will also be correctly identified as\n unhashable when checking ``isinstance(obj, collections.Hashable)``\n (unlike classes which define their own ``__hash__()`` to explicitly\n raise ``TypeError``).\n\n Changed in version 2.5: ``__hash__()`` may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\n Changed in version 2.6: ``__hash__`` may now be set to ``None`` to\n explicitly flag instances of a class as unhashable.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing, and the built-in operation\n ``bool()``; should return ``False`` or ``True``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined (see below). If a class\n defines neither ``__len__()`` nor ``__nonzero__()``, all its\n instances are considered true.\n\nobject.__unicode__(self)\n\n Called to implement ``unicode()`` builtin; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\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 in new-style classes.\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 not simply execute ``self.name = value`` --- this would\n cause a recursive call to itself. Instead, it should insert the\n value in the dictionary of instance attributes, e.g.,\n ``self.__dict__[name] = value``. For new-style classes, rather\n than accessing the instance dictionary, it should call the base\n 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\n\nMore attribute access for new-style classes\n-------------------------------------------\n\nThe following methods only apply to new-style classes.\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 builtin functions. See *Special method lookup for new-style\n classes*.\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 new-style class, known as the *owner*\nclass. In the examples below, "the attribute" refers to the attribute\nwhose name is the key of the property in the owner class\'\n``__dict__``. Descriptors can only be implemented as new-style\nclasses themselves.\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. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass ``object()`` or\n``type()``).\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 a new-style object instance, ``a.x`` is transformed\n into the call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a new-style class, ``A.x`` is transformed into the\n call: ``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. Normally, data\ndescriptors define both ``__get__()`` and ``__set__()``, while non-\ndata descriptors have just the ``__get__()`` method. Data descriptors\nalways override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances. [2]\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 both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__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 new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n New in version 2.2.\n\nNotes on using *__slots__*\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 Changed in version 2.3: Previously, adding ``\'__dict__\'`` to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\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 Changed in version 2.3: Previously, adding ``\'__weakref__\'`` to the\n *__slots__* declaration would not enable support for weak\n references.\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* 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* 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__*.\n\n* *__slots__* do not work for classes derived from "variable-length"\n built-in types such as ``long``, ``str`` and ``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 Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, new-style classes are constructed using ``type()``. A\nclass definition is read into a separate namespace and the value of\nclass name is bound to the result of ``type(name, bases, dict)``.\n\nWhen the class definition is read, if *__metaclass__* is defined then\nthe callable assigned to it will be called instead of ``type()``. 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\n__metaclass__\n\n This variable can be any callable accepting arguments for ``name``,\n ``bases``, and ``dict``. Upon class creation, the callable is used\n instead of the built-in ``type()``.\n\n New in version 2.2.\n\nThe appropriate metaclass is determined by the following precedence\nrules:\n\n* If ``dict[\'__metaclass__\']`` exists, it is used.\n\n* Otherwise, if there is at least one base class, its metaclass is\n used (this looks for a *__class__* attribute first and if not found,\n uses its type).\n\n* Otherwise, if a global variable named __metaclass__ exists, it is\n used.\n\n* Otherwise, the old-style, classic metaclass (types.ClassType) is\n 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\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. (For backwards compatibility, the method\n``__getslice__()`` (see below) can also be defined to handle simple,\nbut not extended slices.) It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``has_key()``,\n``get()``, ``clear()``, ``setdefault()``, ``iterkeys()``,\n``itervalues()``, ``iteritems()``, ``pop()``, ``popitem()``,\n``copy()``, and ``update()`` behaving similar to those for Python\'s\nstandard dictionary objects. The ``UserDict`` module provides a\n``DictMixin`` class to help create those methods from a base set of\n``__getitem__()``, ``__setitem__()``, ``__delitem__()``, and\n``keys()``. Mutable sequences should provide methods ``append()``,\n``count()``, ``index()``, ``extend()``, ``insert()``, ``pop()``,\n``remove()``, ``reverse()`` and ``sort()``, like Python standard list\nobjects. Finally, sequence types should implement addition (meaning\nconcatenation) and multiplication (meaning repetition) by defining the\nmethods ``__add__()``, ``__radd__()``, ``__iadd__()``, ``__mul__()``,\n``__rmul__()`` and ``__imul__()`` described below; they should not\ndefine ``__coerce__()`` or other numerical operators. It is\nrecommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should be equivalent of ``has_key()``;\nfor sequences, 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``iterkeys()``; 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 ``__nonzero__()`` method and whose\n ``__len__()`` method returns zero is considered to be false in a\n Boolean context.\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 ``iterkeys()``.\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()`` builtin 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()`` builtin will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects should\n normally only provide ``__reversed__()`` if they do not support the\n sequence protocol and an efficient implementation of reverse\n iteration is possible.\n\n New in version 2.6.\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\nAdditional methods for emulation of sequence types\n==================================================\n\nThe following optional methods can be defined to further emulate\nsequence objects. Immutable sequences methods should at most only\ndefine ``__getslice__()``; mutable sequences might define all three\nmethods.\n\nobject.__getslice__(self, i, j)\n\n Deprecated since version 2.0: Support slice objects as parameters\n to the ``__getitem__()`` method. (However, built-in types in\n CPython currently still implement ``__getslice__()``. Therefore,\n you have to override it in derived classes when implementing\n slicing.)\n\n Called to implement evaluation of ``self[i:j]``. The returned\n object should be of the same type as *self*. Note that missing *i*\n or *j* in the slice expression are replaced by zero or\n ``sys.maxint``, respectively. If negative indexes are used in the\n slice, the length of the sequence is added to that index. If the\n instance does not implement the ``__len__()`` method, an\n ``AttributeError`` is raised. No guarantee is made that indexes\n adjusted this way are not still negative. Indexes which are\n greater than the length of the sequence are not modified. If no\n ``__getslice__()`` is found, a slice object is created instead, and\n passed to ``__getitem__()`` instead.\n\nobject.__setslice__(self, i, j, sequence)\n\n Called to implement assignment to ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``.\n\n This method is deprecated. If no ``__setslice__()`` is found, or\n for extended slicing of the form ``self[i:j:k]``, a slice object is\n created, and passed to ``__setitem__()``, instead of\n ``__setslice__()`` being called.\n\nobject.__delslice__(self, i, j)\n\n Called to implement deletion of ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``. This method is deprecated. If no\n ``__delslice__()`` is found, or for extended slicing of the form\n ``self[i:j:k]``, a slice object is created, and passed to\n ``__delitem__()``, instead of ``__delslice__()`` being called.\n\nNotice that these methods are only invoked when a single slice with a\nsingle colon is used, and the slice method is available. For slice\noperations involving extended slice notation, or in absence of the\nslice methods, ``__getitem__()``, ``__setitem__()`` or\n``__delitem__()`` is called with a slice object as argument.\n\nThe following example demonstrate how to make your program or module\ncompatible with earlier versions of Python (assuming that methods\n``__getitem__()``, ``__setitem__()`` and ``__delitem__()`` support\nslice objects as arguments):\n\n class MyClass:\n ...\n def __getitem__(self, index):\n ...\n def __setitem__(self, index, value):\n ...\n def __delitem__(self, index):\n ...\n\n if sys.version_info < (2, 0):\n # They won\'t be defined if version is at least 2.0 final\n\n def __getslice__(self, i, j):\n return self[max(0, i):max(0, j):]\n def __setslice__(self, i, j, seq):\n self[max(0, i):max(0, j):] = seq\n def __delslice__(self, i, j):\n del self[max(0, i):max(0, j):]\n ...\n\nNote the calls to ``max()``; these are necessary because of the\nhandling of negative indices before the ``__*slice__()`` methods are\ncalled. When negative indexes are used, the ``__*item__()`` methods\nreceive them as provided, but the ``__*slice__()`` methods get a\n"cooked" form of the index values. For each negative index value, the\nlength of the sequence is added to the index before calling the method\n(which may still result in a negative index); this is the customary\nhandling of negative indexes by the built-in sequence types, and the\n``__*item__()`` methods are expected to do this as well. However,\nsince they should already be doing that, negative indexes cannot be\npassed in; they must be constrained to the bounds of the sequence\nbefore being passed to the ``__*item__()`` methods. Calling ``max(0,\ni)`` conveniently returns the proper value.\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.__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 (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression ``x + y``, where *x* is an\n 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__()`` (described below). Note\n that ``__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.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(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 (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [3] For instance, to evaluate\n the expression ``x - y``, where *y* is an instance of a class that\n has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *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.__idiv__(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 operations (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\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 operation falls back to the normal methods. For instance, to\n evaluate the expression ``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.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``long()``, and ``float()``. Should return a value of\n the appropriate type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions ``oct()`` and ``hex()``.\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n New in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or ``None`` if conversion is impossible. When\n the common type would be the type of ``other``, it is sufficient to\n return ``None``, since the interpreter will also ask the other\n object to attempt a coercion (but sometimes, if the implementation\n of the other type cannot be changed, it is useful to do the\n conversion to the other type here). A return value of\n ``NotImplemented`` is equivalent to returning ``None``.\n\n\nCoercion rules\n==============\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3.0, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don\'t define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from ``object``) never invoke the\n ``__coerce__()`` method in response to a binary operator; the only\n time ``__coerce__()`` is invoked is when the built-in function\n ``coerce()`` is called.\n\n* For most intents and purposes, an operator that returns\n ``NotImplemented`` is treated the same as one that is not\n implemented at all.\n\n* Below, ``__op__()`` and ``__rop__()`` are used to signify the\n generic method names corresponding to an operator; ``__iop__()`` is\n used for the corresponding in-place operator. For example, for the\n operator \'``+``\', ``__add__()`` and ``__radd__()`` are used for the\n left and right variant of the binary operator, and ``__iadd__()``\n for the in-place variant.\n\n* For objects *x* and *y*, first ``x.__op__(y)`` is tried. If this is\n not implemented or returns ``NotImplemented``, ``y.__rop__(x)`` is\n tried. If this is also not implemented or returns\n ``NotImplemented``, a ``TypeError`` exception is raised. But see\n the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base\'s ``__rop__()`` method, the right operand\'s ``__rop__()``\n method is tried *before* the left operand\'s ``__op__()`` method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand\'s ``__op__()`` method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is called\n before that type\'s ``__op__()`` or ``__rop__()`` method is called,\n but no sooner. If the coercion returns an object of a different\n type for the operand whose coercion is invoked, part of the process\n is redone using the new object.\n\n* When an in-place operator (like \'``+=``\') is used, if the left\n operand implements ``__iop__()``, it is invoked without any\n coercion. When the operation falls back to ``__op__()`` and/or\n ``__rop__()``, the normal coercion rules apply.\n\n* In ``x + y``, if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In ``x * y``, if one operator is a sequence that implements sequence\n repetition, and the other is an integer (``int`` or ``long``),\n sequence repetition is invoked.\n\n* Rich comparisons (implemented by methods ``__eq__()`` and so on)\n never use coercion. Three-way comparison (implemented by\n ``__cmp__()``) does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types ``int``,\n ``long`` and ``float`` do not use coercion; the type ``complex``\n however does use it. The difference can become apparent when\n subclassing these types. Over time, the type ``complex`` may be\n fixed to avoid coercion. All these types implement a\n ``__coerce__()`` method, for use by the built-in ``coerce()``\n function.\n\n\nWith Statement Context Managers\n===============================\n\nNew in version 2.5.\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 for old-style classes\n===========================================\n\nFor old-style classes, special methods are always looked up in exactly\nthe same way as any other method or attribute. This is the case\nregardless of whether the method is being looked up explicitly as in\n``x.__getitem__(i)`` or implicitly as in ``x[i]``.\n\nThis behaviour means that special methods may exhibit different\nbehaviour for different instances of a single old-style class if the\nappropriate special attributes are set differently:\n\n >>> class C:\n ... pass\n ...\n >>> c1 = C()\n >>> c2 = C()\n >>> c1.__len__ = lambda: 5\n >>> c2.__len__ = lambda: 9\n >>> len(c1)\n 5\n >>> len(c2)\n 9\n\n\nSpecial method lookup for new-style classes\n===========================================\n\nFor new-style classes, implicit invocations of special methods are\nonly guaranteed to work correctly if defined on an object\'s type, not\nin the object\'s instance dictionary. That behaviour is the reason why\nthe following code raises an exception (unlike the equivalent example\nwith old-style classes):\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 may also bypass the\n``__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):\n ... __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] A descriptor can define any combination of ``__get__()``,\n ``__set__()`` and ``__delete__()``. If it does not define\n ``__get__()``, then accessing the attribute even on an instance\n will return the descriptor object itself. If the descriptor\n defines ``__set__()`` and/or ``__delete__()``, it is a data\n descriptor; if it defines neither, it is a non-data descriptor.\n\n[3] 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', + 'specialattrs': u"\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\nobject.__methods__\n\n Deprecated since version 2.2: Use the built-in function ``dir()``\n to get a list of an object's attributes. This attribute is no\n longer available.\n\nobject.__members__\n\n Deprecated since version 2.2: Use the built-in function ``dir()``\n to get a list of an object's attributes. This attribute is no\n longer available.\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. If there are no base\n classes, this will be an empty tuple.\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\n[5] These numbers are fairly arbitrary. They are intended to avoid\n printing endless strings of meaningless digits without hampering\n correct use and without having to know the exact precision of\n floating point values on a particular machine.\n\n[6] The advantage of leaving the newline on is that returning an empty\n string is then an unambiguous EOF indication. It is also possible\n (in cases where it might matter, for example, if you want to make\n an exact copy of a file while scanning its lines) to tell whether\n the last line of a file ended in a newline or not (yes this\n happens!).\n", + 'specialnames': u'\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 ``x.__getitem__(i)`` for\nold-style classes and ``type(x).__getitem__(x, i)`` for new-style\nclasses. Except where mentioned, attempts to execute an operation\nraise an 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_traceback`` 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.exc_traceback`` or ``sys.last_traceback``. Circular\n references which are garbage are detected when the option cycle\n detector is enabled (it\'s on by default), but can only be cleaned\n up if there are no Python-level ``__del__()`` methods involved.\n Refer to the documentation for the ``gc`` module for more\n information about how ``__del__()`` methods are handled by the\n cycle detector, particularly the description of the ``garbage``\n 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 and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is 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 statement 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.__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 New in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` call ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and\n ``x>=y`` calls ``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 the Total Ordering recipe in the ASPN cookbook.\n\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by ``__cmp__()`` has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\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 a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable in hashed collections. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n hashable collection implementations require that a object\'s hash\n value is immutable (if the object\'s hash value changes, it will be\n in the wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` 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 ``__cmp__()`` or ``__eq__()`` such that\n the hash value returned is no longer appropriate (e.g. by switching\n to a value-based concept of equality instead of the default\n identity based equality) can explicitly flag themselves as being\n unhashable by setting ``__hash__ = None`` in the class definition.\n Doing so means that not only will instances of the class raise an\n appropriate ``TypeError`` when a program attempts to retrieve their\n hash value, but they will also be correctly identified as\n unhashable when checking ``isinstance(obj, collections.Hashable)``\n (unlike classes which define their own ``__hash__()`` to explicitly\n raise ``TypeError``).\n\n Changed in version 2.5: ``__hash__()`` may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\n Changed in version 2.6: ``__hash__`` may now be set to ``None`` to\n explicitly flag instances of a class as unhashable.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing and the built-in operation\n ``bool()``; should return ``False`` or ``True``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined, and the object is\n considered true if its result is nonzero. If a class defines\n neither ``__len__()`` nor ``__nonzero__()``, all its instances are\n considered true.\n\nobject.__unicode__(self)\n\n Called to implement ``unicode()`` builtin; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\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 in new-style classes.\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 not simply execute ``self.name = value`` --- this would\n cause a recursive call to itself. Instead, it should insert the\n value in the dictionary of instance attributes, e.g.,\n ``self.__dict__[name] = value``. For new-style classes, rather\n than accessing the instance dictionary, it should call the base\n 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\n\nMore attribute access for new-style classes\n-------------------------------------------\n\nThe following methods only apply to new-style classes.\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 builtin functions. See *Special method lookup for new-style\n classes*.\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 new-style class, known as the *owner*\nclass. In the examples below, "the attribute" refers to the attribute\nwhose name is the key of the property in the owner class\'\n``__dict__``. Descriptors can only be implemented as new-style\nclasses themselves.\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. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass ``object()`` or\n``type()``).\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 a new-style object instance, ``a.x`` is transformed\n into the call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a new-style class, ``A.x`` is transformed into the\n call: ``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. Normally, data\ndescriptors define both ``__get__()`` and ``__set__()``, while non-\ndata descriptors have just the ``__get__()`` method. Data descriptors\nalways override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances. [2]\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 both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__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 new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n New in version 2.2.\n\nNotes on using *__slots__*\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 Changed in version 2.3: Previously, adding ``\'__dict__\'`` to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\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 Changed in version 2.3: Previously, adding ``\'__weakref__\'`` to the\n *__slots__* declaration would not enable support for weak\n references.\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* 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* 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__*.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as ``long``, ``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 Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, new-style classes are constructed using ``type()``. A\nclass definition is read into a separate namespace and the value of\nclass name is bound to the result of ``type(name, bases, dict)``.\n\nWhen the class definition is read, if *__metaclass__* is defined then\nthe callable assigned to it will be called instead of ``type()``. 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\n__metaclass__\n\n This variable can be any callable accepting arguments for ``name``,\n ``bases``, and ``dict``. Upon class creation, the callable is used\n instead of the built-in ``type()``.\n\n New in version 2.2.\n\nThe appropriate metaclass is determined by the following precedence\nrules:\n\n* If ``dict[\'__metaclass__\']`` exists, it is used.\n\n* Otherwise, if there is at least one base class, its metaclass is\n used (this looks for a *__class__* attribute first and if not found,\n uses its type).\n\n* Otherwise, if a global variable named __metaclass__ exists, it is\n used.\n\n* Otherwise, the old-style, classic metaclass (types.ClassType) is\n 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\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. (For backwards compatibility, the method\n``__getslice__()`` (see below) can also be defined to handle simple,\nbut not extended slices.) It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``has_key()``,\n``get()``, ``clear()``, ``setdefault()``, ``iterkeys()``,\n``itervalues()``, ``iteritems()``, ``pop()``, ``popitem()``,\n``copy()``, and ``update()`` behaving similar to those for Python\'s\nstandard dictionary objects. The ``UserDict`` module provides a\n``DictMixin`` class to help create those methods from a base set of\n``__getitem__()``, ``__setitem__()``, ``__delitem__()``, and\n``keys()``. Mutable sequences should provide methods ``append()``,\n``count()``, ``index()``, ``extend()``, ``insert()``, ``pop()``,\n``remove()``, ``reverse()`` and ``sort()``, like Python standard list\nobjects. Finally, sequence types should implement addition (meaning\nconcatenation) and multiplication (meaning repetition) by defining the\nmethods ``__add__()``, ``__radd__()``, ``__iadd__()``, ``__mul__()``,\n``__rmul__()`` and ``__imul__()`` described below; they should not\ndefine ``__coerce__()`` or other numerical operators. It is\nrecommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should be equivalent of ``has_key()``;\nfor sequences, 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``iterkeys()``; 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 ``__nonzero__()`` method and whose\n ``__len__()`` method returns zero is considered to be false in a\n Boolean context.\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 ``iterkeys()``.\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()`` builtin 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()`` builtin will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects should\n normally only provide ``__reversed__()`` if they do not support the\n sequence protocol and an efficient implementation of reverse\n iteration is possible.\n\n New in version 2.6.\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\nAdditional methods for emulation of sequence types\n==================================================\n\nThe following optional methods can be defined to further emulate\nsequence objects. Immutable sequences methods should at most only\ndefine ``__getslice__()``; mutable sequences might define all three\nmethods.\n\nobject.__getslice__(self, i, j)\n\n Deprecated since version 2.0: Support slice objects as parameters\n to the ``__getitem__()`` method. (However, built-in types in\n CPython currently still implement ``__getslice__()``. Therefore,\n you have to override it in derived classes when implementing\n slicing.)\n\n Called to implement evaluation of ``self[i:j]``. The returned\n object should be of the same type as *self*. Note that missing *i*\n or *j* in the slice expression are replaced by zero or\n ``sys.maxint``, respectively. If negative indexes are used in the\n slice, the length of the sequence is added to that index. If the\n instance does not implement the ``__len__()`` method, an\n ``AttributeError`` is raised. No guarantee is made that indexes\n adjusted this way are not still negative. Indexes which are\n greater than the length of the sequence are not modified. If no\n ``__getslice__()`` is found, a slice object is created instead, and\n passed to ``__getitem__()`` instead.\n\nobject.__setslice__(self, i, j, sequence)\n\n Called to implement assignment to ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``.\n\n This method is deprecated. If no ``__setslice__()`` is found, or\n for extended slicing of the form ``self[i:j:k]``, a slice object is\n created, and passed to ``__setitem__()``, instead of\n ``__setslice__()`` being called.\n\nobject.__delslice__(self, i, j)\n\n Called to implement deletion of ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``. This method is deprecated. If no\n ``__delslice__()`` is found, or for extended slicing of the form\n ``self[i:j:k]``, a slice object is created, and passed to\n ``__delitem__()``, instead of ``__delslice__()`` being called.\n\nNotice that these methods are only invoked when a single slice with a\nsingle colon is used, and the slice method is available. For slice\noperations involving extended slice notation, or in absence of the\nslice methods, ``__getitem__()``, ``__setitem__()`` or\n``__delitem__()`` is called with a slice object as argument.\n\nThe following example demonstrate how to make your program or module\ncompatible with earlier versions of Python (assuming that methods\n``__getitem__()``, ``__setitem__()`` and ``__delitem__()`` support\nslice objects as arguments):\n\n class MyClass:\n ...\n def __getitem__(self, index):\n ...\n def __setitem__(self, index, value):\n ...\n def __delitem__(self, index):\n ...\n\n if sys.version_info < (2, 0):\n # They won\'t be defined if version is at least 2.0 final\n\n def __getslice__(self, i, j):\n return self[max(0, i):max(0, j):]\n def __setslice__(self, i, j, seq):\n self[max(0, i):max(0, j):] = seq\n def __delslice__(self, i, j):\n del self[max(0, i):max(0, j):]\n ...\n\nNote the calls to ``max()``; these are necessary because of the\nhandling of negative indices before the ``__*slice__()`` methods are\ncalled. When negative indexes are used, the ``__*item__()`` methods\nreceive them as provided, but the ``__*slice__()`` methods get a\n"cooked" form of the index values. For each negative index value, the\nlength of the sequence is added to the index before calling the method\n(which may still result in a negative index); this is the customary\nhandling of negative indexes by the built-in sequence types, and the\n``__*item__()`` methods are expected to do this as well. However,\nsince they should already be doing that, negative indexes cannot be\npassed in; they must be constrained to the bounds of the sequence\nbefore being passed to the ``__*item__()`` methods. Calling ``max(0,\ni)`` conveniently returns the proper value.\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.__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 (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression ``x + y``, where *x* is an\n 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__()`` (described below). Note\n that ``__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.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(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 (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [3] For instance, to evaluate\n the expression ``x - y``, where *y* is an instance of a class that\n has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *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.__idiv__(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.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``long()``, and ``float()``. Should return a value of\n the appropriate type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions ``oct()`` and ``hex()``.\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n New in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or ``None`` if conversion is impossible. When\n the common type would be the type of ``other``, it is sufficient to\n return ``None``, since the interpreter will also ask the other\n object to attempt a coercion (but sometimes, if the implementation\n of the other type cannot be changed, it is useful to do the\n conversion to the other type here). A return value of\n ``NotImplemented`` is equivalent to returning ``None``.\n\n\nCoercion rules\n==============\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3.0, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don\'t define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from ``object``) never invoke the\n ``__coerce__()`` method in response to a binary operator; the only\n time ``__coerce__()`` is invoked is when the built-in function\n ``coerce()`` is called.\n\n* For most intents and purposes, an operator that returns\n ``NotImplemented`` is treated the same as one that is not\n implemented at all.\n\n* Below, ``__op__()`` and ``__rop__()`` are used to signify the\n generic method names corresponding to an operator; ``__iop__()`` is\n used for the corresponding in-place operator. For example, for the\n operator \'``+``\', ``__add__()`` and ``__radd__()`` are used for the\n left and right variant of the binary operator, and ``__iadd__()``\n for the in-place variant.\n\n* For objects *x* and *y*, first ``x.__op__(y)`` is tried. If this is\n not implemented or returns ``NotImplemented``, ``y.__rop__(x)`` is\n tried. If this is also not implemented or returns\n ``NotImplemented``, a ``TypeError`` exception is raised. But see\n the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base\'s ``__rop__()`` method, the right operand\'s ``__rop__()``\n method is tried *before* the left operand\'s ``__op__()`` method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand\'s ``__op__()`` method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is called\n before that type\'s ``__op__()`` or ``__rop__()`` method is called,\n but no sooner. If the coercion returns an object of a different\n type for the operand whose coercion is invoked, part of the process\n is redone using the new object.\n\n* When an in-place operator (like \'``+=``\') is used, if the left\n operand implements ``__iop__()``, it is invoked without any\n coercion. When the operation falls back to ``__op__()`` and/or\n ``__rop__()``, the normal coercion rules apply.\n\n* In ``x + y``, if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In ``x * y``, if one operator is a sequence that implements sequence\n repetition, and the other is an integer (``int`` or ``long``),\n sequence repetition is invoked.\n\n* Rich comparisons (implemented by methods ``__eq__()`` and so on)\n never use coercion. Three-way comparison (implemented by\n ``__cmp__()``) does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types ``int``,\n ``long`` and ``float`` do not use coercion; the type ``complex``\n however does use coercion for binary operators and rich comparisons,\n despite the above rules. The difference can become apparent when\n subclassing these types. Over time, the type ``complex`` may be\n fixed to avoid coercion. All these types implement a\n ``__coerce__()`` method, for use by the built-in ``coerce()``\n function.\n\n\nWith Statement Context Managers\n===============================\n\nNew in version 2.5.\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 for old-style classes\n===========================================\n\nFor old-style classes, special methods are always looked up in exactly\nthe same way as any other method or attribute. This is the case\nregardless of whether the method is being looked up explicitly as in\n``x.__getitem__(i)`` or implicitly as in ``x[i]``.\n\nThis behaviour means that special methods may exhibit different\nbehaviour for different instances of a single old-style class if the\nappropriate special attributes are set differently:\n\n >>> class C:\n ... pass\n ...\n >>> c1 = C()\n >>> c2 = C()\n >>> c1.__len__ = lambda: 5\n >>> c2.__len__ = lambda: 9\n >>> len(c1)\n 5\n >>> len(c2)\n 9\n\n\nSpecial method lookup for new-style classes\n===========================================\n\nFor new-style classes, implicit invocations of special methods are\nonly guaranteed to work correctly if defined on an object\'s type, not\nin the object\'s instance dictionary. That behaviour is the reason why\nthe following code raises an exception (unlike the equivalent example\nwith old-style classes):\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):\n ... __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] A descriptor can define any combination of ``__get__()``,\n ``__set__()`` and ``__delete__()``. If it does not define\n ``__get__()``, then accessing the attribute even on an instance\n will return the descriptor object itself. If the descriptor\n defines ``__set__()`` and/or ``__delete__()``, it is a data\n descriptor; if it defines neither, it is a non-data descriptor.\n\n[3] 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-conversions': u'\nString conversions\n******************\n\nA string conversion is an expression list enclosed in reverse (a.k.a.\nbackward) quotes:\n\n string_conversion ::= "\'" expression_list "\'"\n\nA string conversion evaluates the contained expression list and\nconverts the resulting object into a string according to rules\nspecific to its type.\n\nIf the object is a string, a number, ``None``, or a tuple, list or\ndictionary containing only objects whose type is one of these, the\nresulting string is a valid Python expression which can be passed to\nthe built-in function ``eval()`` to yield an expression with the same\nvalue (or an approximation, if floating point numbers are involved).\n\n(In particular, converting a string adds quotes around it and converts\n"funny" characters to escape sequences that are safe to print.)\n\nRecursive objects (for example, lists or dictionaries that contain a\nreference to themselves, directly or indirectly) use ``...`` to\nindicate a recursive reference, and the result cannot be passed to\n``eval()`` to get an equal value (``SyntaxError`` will be raised\ninstead).\n\nThe built-in function ``repr()`` performs exactly the same conversion\nin its argument as enclosing it in parentheses and reverse quotes\ndoes. The built-in function ``str()`` performs a similar but more\nuser-friendly conversion.\n', - 'string-methods': u'\nString Methods\n**************\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Note that none of these methods take keyword\narguments.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbuffer, xrange* section. To output formatted strings use template\nstrings or the ``%`` operator described in the *String Formatting\nOperations* 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 only its first character\n capitalized.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of occurrences of substring *sub* in the range\n [*start*, *end*]. Optional arguments *start* and *end* are\n interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes 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\n Changed in version 2.5: Accept tuples as *suffix*.\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 range [*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(format_string, *args, **kwargs)\n\n Perform a string formatting operation. The *format_string*\n argument can contain literal text or replacement fields delimited\n by braces ``{}``. Each replacement field contains either the\n numeric index of a positional argument, or the name of a keyword\n argument. Returns a copy of *format_string* where each replacement\n field is replaced with the string value of the corresponding\n 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\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(seq)\n\n Return a string which is the concatenation of the strings in the\n sequence *seq*. The separator between elements is the string\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n New in version 2.5.\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]. Optional\n arguments *start* and *end* are interpreted as in slice notation.\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\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\n New in version 2.5.\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\n New in version 2.4.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n Changed in version 2.5: Accept tuples as *prefix*.\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\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string: words start with\n uppercase characters, all remaining cased characters are lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\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 New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n', + 'string-methods': u'\nString Methods\n**************\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Note that none of these methods take keyword\narguments.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbuffer, xrange* section. To output formatted strings use template\nstrings or the ``%`` operator described in the *String Formatting\nOperations* 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 only its first character\n capitalized.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.4: Support for the *fillchar* argument.\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.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes 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\n Changed in version 2.5: Accept tuples as *suffix*.\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 range [*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 *format_string*\n argument can contain literal text or replacement fields delimited\n by braces ``{}``. Each replacement field contains either the\n numeric index of a positional argument, or the name of a keyword\n argument. Returns a copy of *format_string* where each replacement\n field is replaced with the string value of the corresponding\n 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\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(seq)\n\n Return a string which is the concatenation of the strings in the\n sequence *seq*. The separator between elements is the string\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n New in version 2.5.\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]. Optional\n arguments *start* and *end* are interpreted as in slice notation.\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\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\n New in version 2.5.\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\n New in version 2.4.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n Changed in version 2.5: Accept tuples as *prefix*.\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\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string: words start with\n uppercase characters, all remaining cased characters are lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\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 New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n', 'strings': u'\nString literals\n***************\n\nString literals are described by the following lexical definitions:\n\n stringliteral ::= [stringprefix](shortstring | longstring)\n stringprefix ::= "r" | "u" | "ur" | "R" | "U" | "UR" | "Ur" | "uR"\n shortstring ::= "\'" shortstringitem* "\'" | \'"\' shortstringitem* \'"\'\n longstring ::= "\'\'\'" longstringitem* "\'\'\'"\n | \'"""\' longstringitem* \'"""\'\n shortstringitem ::= shortstringchar | escapeseq\n longstringitem ::= longstringchar | escapeseq\n shortstringchar ::= \n longstringchar ::= \n escapeseq ::= "\\" \n\nOne syntactic restriction not indicated by these productions is that\nwhitespace is not allowed between the **stringprefix** and the rest of\nthe string literal. The source character set is defined by the\nencoding declaration; it is ASCII if no encoding declaration is given\nin the source file; see section *Encoding declarations*.\n\nIn plain English: String literals can be enclosed in matching single\nquotes (``\'``) or double quotes (``"``). They can also be enclosed in\nmatching groups of three single or double quotes (these are generally\nreferred to as *triple-quoted strings*). The backslash (``\\``)\ncharacter is used to escape characters that otherwise have a special\nmeaning, such as newline, backslash itself, or the quote character.\nString literals may optionally be prefixed with a letter ``\'r\'`` or\n``\'R\'``; such strings are called *raw strings* and use different rules\nfor interpreting backslash escape sequences. A prefix of ``\'u\'`` or\n``\'U\'`` makes the string a Unicode string. Unicode strings use the\nUnicode character set as defined by the Unicode Consortium and ISO\n10646. Some additional escape sequences, described below, are\navailable in Unicode strings. The two prefix characters may be\ncombined; in this case, ``\'u\'`` must appear before ``\'r\'``.\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`` | 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| ``\\N{name}`` | Character named *name* in the | |\n| | Unicode database (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\r`` | ASCII Carriage Return (CR) | |\n+-------------------+-----------------------------------+---------+\n| ``\\t`` | ASCII Horizontal Tab (TAB) | |\n+-------------------+-----------------------------------+---------+\n| ``\\uxxxx`` | Character with 16-bit hex value | (1) |\n| | *xxxx* (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\Uxxxxxxxx`` | Character with 32-bit hex value | (2) |\n| | *xxxxxxxx* (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\v`` | ASCII Vertical Tab (VT) | |\n+-------------------+-----------------------------------+---------+\n| ``\\ooo`` | Character with octal value *ooo* | (3,5) |\n+-------------------+-----------------------------------+---------+\n| ``\\xhh`` | Character with hex value *hh* | (4,5) |\n+-------------------+-----------------------------------+---------+\n\nNotes:\n\n1. Individual code units which form parts of a surrogate pair can be\n encoded using this escape sequence.\n\n2. 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). Individual code units which form parts of a surrogate\n pair can be encoded using this escape sequence.\n\n3. As in Standard C, up to three octal digits are accepted.\n\n4. Unlike in Standard C, exactly two hex digits are required.\n\n5. In a string literal, hexadecimal and octal escapes denote the byte\n with the given value; it is not necessary that the byte encodes a\n character in the source character set. In a Unicode literal, these\n escapes denote a Unicode character with the given value.\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 marked as "(Unicode only)"\nin the table above fall into the category of unrecognized escapes for\nnon-Unicode string literals.\n\nWhen an ``\'r\'`` or ``\'R\'`` prefix is present, a character following a\nbackslash is included in the string without change, and *all\nbackslashes are left in the string*. For example, the string literal\n``r"\\n"`` consists of two characters: a backslash and a lowercase\n``\'n\'``. String quotes can be escaped with a backslash, but the\nbackslash remains in the string; for example, ``r"\\""`` is a valid\nstring literal consisting of two characters: a backslash and a double\nquote; ``r"\\"`` is not a valid string literal (even a raw string\ncannot end in an odd number of backslashes). Specifically, *a raw\nstring cannot end in a single backslash* (since the backslash would\nescape 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\nWhen an ``\'r\'`` or ``\'R\'`` prefix is used in conjunction with a\n``\'u\'`` or ``\'U\'`` prefix, then the ``\\uXXXX`` and ``\\UXXXXXXXX``\nescape sequences are processed while *all other backslashes are left\nin the string*. For example, the string literal ``ur"\\u0062\\n"``\nconsists of three Unicode characters: \'LATIN SMALL LETTER B\', \'REVERSE\nSOLIDUS\', and \'LATIN SMALL LETTER N\'. Backslashes can be escaped with\na preceding backslash; however, both remain in the string. As a\nresult, ``\\uXXXX`` escape sequences are only recognized when there are\nan odd number of backslashes.\n', 'subscriptions': u'\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 of a sequence or mapping type.\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 a\nplain integer. If this value is negative, the length of the sequence\nis added to it (so that, e.g., ``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).\n\nA string\'s items are characters. A character is not a separate data\ntype but a string of exactly one character.\n', 'truth': u"\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``, ``0L``, ``0.0``,\n ``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 ``__nonzero__()`` or ``__len__()`` method, when that method returns\n the 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", - 'try': u'\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 ["," target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nChanged in version 2.5: In previous versions of Python,\n``try``...``except``...``finally`` did not work. ``try``...``except``\nhad to be nested in ``try``...``finally``.\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, a tuple containing an item compatible with the\nexception, or, in the (deprecated) case of string exceptions, is the\nraised string itself (note that the object identities must match, i.e.\nit must be the same string object, not just a string with the same\nvalue).\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 in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the ``sys`` module:\n``sys.exc_type`` receives the object identifying the exception;\n``sys.exc_value`` receives the exception\'s parameter;\n``sys.exc_traceback`` receives a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. These details are also available through the\n``sys.exc_info()`` function, which returns a tuple ``(exc_type,\nexc_value, exc_traceback)``. Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables 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', - 'types': u'\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.).\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name ``None``.\n It is used to signify the absence of a value in many situations,\n e.g., it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``NotImplemented``. Numeric methods and rich comparison methods may\n return this value if they do not implement the operation for the\n operands provided. (The interpreter will then try the reflected\n operation, or some other fallback, depending on the operator.) Its\n truth value is true.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``Ellipsis``. It is used to indicate the presence of the ``...``\n syntax in a slice. Its truth value is true.\n\n``numbers.Number``\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n ``numbers.Integral``\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are three types of integers:\n\n Plain integers\n These represent numbers in the range -2147483648 through\n 2147483647. (The range may be larger on machines with a\n larger natural word size, but not smaller.) When the result\n of an operation would fall outside this range, the result is\n normally returned as a long integer (in some cases, the\n exception ``OverflowError`` is raised instead). For the\n purpose of shift and mask operations, integers are assumed to\n have a binary, 2\'s complement notation using 32 or more bits,\n and hiding no bits from the user (i.e., all 4294967296\n different bit patterns correspond to different values).\n\n Long integers\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans\n These represent the truth values False and True. The two\n objects representing the values False and True are the only\n Boolean objects. The Boolean type is a subtype of plain\n integers, and Boolean values behave like the values 0 and 1,\n respectively, in almost all contexts, the exception being\n that when converted to a string, the strings ``"False"`` or\n ``"True"`` are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers and the least surprises when\n switching between the plain and long integer domains. Any\n operation, if it yields a result in the plain integer domain,\n will yield the same result in the long integer domain or when\n using mixed operands. The switch between domains is transparent\n to the programmer.\n\n ``numbers.Real`` (``float``)\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these is\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n ``numbers.Complex``\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number ``z`` can be retrieved through the read-only\n attributes ``z.real`` and ``z.imag``.\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function ``len()`` returns the number of\n items of a sequence. When the length of a sequence is *n*, the\n index set contains the numbers 0, 1, ..., *n*-1. Item *i* of\n sequence *a* is selected by ``a[i]``.\n\n Sequences also support slicing: ``a[i:j]`` selects all items with\n index *k* such that *i* ``<=`` *k* ``<`` *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: ``a[i:j:k]`` selects all items of *a* with index *x*\n where ``x = i + n*k``, *n* ``>=`` ``0`` and *i* ``<=`` *x* ``<``\n *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n The items of a string are characters. There is no separate\n character type; a character is represented by a string of one\n item. Characters represent (at least) 8-bit bytes. The\n built-in functions ``chr()`` and ``ord()`` convert between\n characters and nonnegative integers representing the byte\n values. Bytes with the values 0-127 usually represent the\n corresponding ASCII values, but the interpretation of values\n is up to the program. The string data type is also used to\n represent arrays of bytes, e.g., to hold data read from a\n file.\n\n (On systems whose native character set is not ASCII, strings\n may use EBCDIC in their internal representation, provided the\n functions ``chr()`` and ``ord()`` implement a mapping between\n ASCII and EBCDIC, and string comparison preserves the ASCII\n order. Or perhaps someone can propose a better rule?)\n\n Unicode\n The items of a Unicode object are Unicode code units. A\n Unicode code unit is represented by a Unicode object of one\n item and can hold either a 16-bit or 32-bit value\n representing a Unicode ordinal (the maximum value for the\n ordinal is given in ``sys.maxunicode``, and depends on how\n Python is configured at compile time). Surrogate pairs may\n be present in the Unicode object, and will be reported as two\n separate items. The built-in functions ``unichr()`` and\n ``ord()`` convert between code units and nonnegative integers\n representing the Unicode ordinals as defined in the Unicode\n Standard 3.0. Conversion from and to other encodings are\n possible through the Unicode method ``encode()`` and the\n built-in function ``unicode()``.\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and ``del`` (delete) statements.\n\n There is currently a single intrinsic mutable sequence type:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n The extension module ``array`` provides an additional example of\n a mutable sequence type.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function ``len()``\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n ``set()`` constructor and can be modified afterwards by several\n methods, such as ``add()``.\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in ``frozenset()`` constructor. As a frozenset is\n immutable and *hashable*, it can be used again as an element of\n another set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation ``a[k]`` selects the item indexed by\n ``k`` from the mapping ``a``; this can be used in expressions and\n as the target of assignments or ``del`` statements. The built-in\n function ``len()`` returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``) then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the ``{...}``\n notation (see section *Dictionary displays*).\n\n The extension modules ``dbm``, ``gdbm``, and ``bsddb`` provide\n additional examples of mapping types.\n\nCallable types\n These are the types to which the function call operation (see\n section *Calls*) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section *Function definitions*). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +-------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +=========================+=================================+=============+\n | ``func_doc`` | The function\'s documentation | Writable |\n | | string, or ``None`` if | |\n | | unavailable | |\n +-------------------------+---------------------------------+-------------+\n | ``__doc__`` | Another way of spelling | Writable |\n | | ``func_doc`` | |\n +-------------------------+---------------------------------+-------------+\n | ``func_name`` | The function\'s name | Writable |\n +-------------------------+---------------------------------+-------------+\n | ``__name__`` | Another way of spelling | Writable |\n | | ``func_name`` | |\n +-------------------------+---------------------------------+-------------+\n | ``__module__`` | The name of the module the | Writable |\n | | function was defined in, or | |\n | | ``None`` if unavailable. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_defaults`` | A tuple containing default | Writable |\n | | argument values for those | |\n | | arguments that have defaults, | |\n | | or ``None`` if no arguments | |\n | | have a default value | |\n +-------------------------+---------------------------------+-------------+\n | ``func_code`` | The code object representing | Writable |\n | | the compiled function body. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_globals`` | A reference to the dictionary | Read-only |\n | | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_dict`` | The namespace supporting | Writable |\n | | arbitrary function attributes. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_closure`` | ``None`` or a tuple of cells | Read-only |\n | | that contain bindings for the | |\n | | function\'s free variables. | |\n +-------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Changed in version 2.4: ``func_name`` is now writable.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n User-defined methods\n A user-defined method object combines a class, a class instance\n (or ``None``) and any callable object (normally a user-defined\n function).\n\n Special read-only attributes: ``im_self`` is the class instance\n object, ``im_func`` is the function object; ``im_class`` is the\n class of ``im_self`` for bound methods or the class that asked\n for the method for unbound methods; ``__doc__`` is the method\'s\n documentation (same as ``im_func.__doc__``); ``__name__`` is the\n method name (same as ``im_func.__name__``); ``__module__`` is\n the name of the module the method was defined in, or ``None`` if\n unavailable.\n\n Changed in version 2.2: ``im_self`` used to refer to the class\n that defined the method.\n\n Changed in version 2.6: For 3.0 forward-compatibility,\n ``im_func`` is also available as ``__func__``, and ``im_self``\n as ``__self__``.\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object, an unbound\n user-defined method object, or a class method object. When the\n attribute is a user-defined method object, a new method object\n is only created if the class from which it is being retrieved is\n the same as, or a derived class of, the class stored in the\n original method object; otherwise, the original method object is\n used as it is.\n\n When a user-defined method object is created by retrieving a\n user-defined function object from a class, its ``im_self``\n attribute is ``None`` and the method object is said to be\n unbound. When one is created by retrieving a user-defined\n function object from a class via one of its instances, its\n ``im_self`` attribute is the instance, and the method object is\n said to be bound. In either case, the new method\'s ``im_class``\n attribute is the class from which the retrieval takes place, and\n its ``im_func`` attribute is the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the ``im_func``\n attribute of the new instance is not the original method object\n but its ``im_func`` attribute.\n\n When a user-defined method object is created by retrieving a\n class method object from a class or instance, its ``im_self``\n attribute is the class itself (the same as the ``im_class``\n attribute), and its ``im_func`` attribute is the function object\n underlying the class method.\n\n When an unbound user-defined method object is called, the\n underlying function (``im_func``) is called, with the\n restriction that the first argument must be an instance of the\n proper class (``im_class``) or of a derived class thereof.\n\n When a bound user-defined method object is called, the\n underlying function (``im_func``) is called, inserting the class\n instance (``im_self``) in front of the argument list. For\n instance, when ``C`` is a class which contains a definition for\n a function ``f()``, and ``x`` is an instance of ``C``, calling\n ``x.f(1)`` is equivalent to calling ``C.f(x, 1)``.\n\n When a user-defined method object is derived from a class method\n object, the "class instance" stored in ``im_self`` will actually\n be the class itself, so that calling either ``x.f(1)`` or\n ``C.f(1)`` is equivalent to calling ``f(C,1)`` where ``f`` is\n the underlying function.\n\n Note that the transformation from function object to (unbound or\n bound) method object happens each time the attribute is\n retrieved from the class or instance. In some cases, a fruitful\n optimization is to assign the attribute to a local variable and\n call that local variable. Also notice that this transformation\n only happens for user-defined functions; other callable objects\n (and all non-callable objects) are retrieved without\n transformation. It is also important to note that user-defined\n functions which are attributes of a class instance are not\n converted to bound methods; this *only* happens when the\n function is an attribute of the class.\n\n Generator functions\n A function or method which uses the ``yield`` statement (see\n section *The yield statement*) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s ``next()`` method will cause the function to\n execute until it provides a value using the ``yield`` statement.\n When the function executes a ``return`` statement or falls off\n the end, a ``StopIteration`` exception is raised and the\n iterator will have reached the end of the set of values to be\n returned.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are ``len()`` and ``math.sin()``\n (``math`` is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: ``__doc__`` is the function\'s documentation\n string, or ``None`` if unavailable; ``__name__`` is the\n function\'s name; ``__self__`` is set to ``None`` (but see the\n next item); ``__module__`` is the name of the module the\n function was defined in or ``None`` if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n ``alist.append()``, assuming *alist* is a list object. In this\n case, the special read-only attribute ``__self__`` is set to the\n object denoted by *list*.\n\n Class Types\n Class types, or "new-style classes," are callable. These\n objects normally act as factories for new instances of\n themselves, but variations are possible for class types that\n override ``__new__()``. The arguments of the call are passed to\n ``__new__()`` and, in the typical case, to ``__init__()`` to\n initialize the new instance.\n\n Classic Classes\n Class objects are described below. When a class object is\n called, a new class instance (also described below) is created\n and returned. This implies a call to the class\'s ``__init__()``\n method if it has one. Any arguments are passed on to the\n ``__init__()`` method. If there is no ``__init__()`` method,\n the class must be called without arguments.\n\n Class instances\n Class instances are described below. Class instances are\n callable only when the class has a ``__call__()`` method;\n ``x(arguments)`` is a shorthand for ``x.__call__(arguments)``.\n\nModules\n Modules are imported by the ``import`` statement (see section *The\n import statement*). A module object has a namespace implemented by\n a dictionary object (this is the dictionary referenced by the\n func_globals attribute of functions defined in the module).\n Attribute references are translated to lookups in this dictionary,\n e.g., ``m.x`` is equivalent to ``m.__dict__["x"]``. A module object\n does not contain the code object used to initialize the module\n (since it isn\'t needed once the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``.\n\n Special read-only attribute: ``__dict__`` is the module\'s namespace\n as a dictionary object.\n\n Predefined (writable) attributes: ``__name__`` is the module\'s\n name; ``__doc__`` is the module\'s documentation string, or ``None``\n if unavailable; ``__file__`` is the pathname of the file from which\n the module was loaded, if it was loaded from a file. The\n ``__file__`` attribute is not present for C modules that are\n statically linked into the interpreter; for extension modules\n loaded dynamically from a shared library, it is the pathname of the\n shared library file.\n\nClasses\n Both class types (new-style classes) and class objects (old-\n style/classic classes) are typically created by class definitions\n (see section *Class definitions*). A class has a namespace\n implemented by a dictionary object. Class attribute references are\n translated to lookups in this dictionary, e.g., ``C.x`` is\n translated to ``C.__dict__["x"]`` (although for new-style classes\n in particular there are a number of hooks which allow for other\n means of locating attributes). When the attribute name is not found\n there, the attribute search continues in the base classes. For\n old-style classes, the search is depth-first, left-to-right in the\n order of occurrence in the base class list. New-style classes use\n the more complex C3 method resolution order which behaves correctly\n even in the presence of \'diamond\' inheritance structures where\n there are multiple inheritance paths leading back to a common\n ancestor. Additional details on the C3 MRO used by new-style\n classes can be found in the documentation accompanying the 2.3\n release at http://www.python.org/download/releases/2.3/mro/.\n\n When a class attribute reference (for class ``C``, say) would yield\n a user-defined function object or an unbound user-defined method\n object whose associated class is either ``C`` or one of its base\n classes, it is transformed into an unbound user-defined method\n object whose ``im_class`` attribute is ``C``. When it would yield a\n class method object, it is transformed into a bound user-defined\n method object whose ``im_class`` and ``im_self`` attributes are\n both ``C``. When it would yield a static method object, it is\n transformed into the object wrapped by the static method object.\n See section *Implementing Descriptors* for another way in which\n attributes retrieved from a class may differ from those actually\n contained in its ``__dict__`` (note that only new-style classes\n support descriptors).\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: ``__name__`` is the class name; ``__module__``\n is the module name in which the class was defined; ``__dict__`` is\n the dictionary containing the class\'s namespace; ``__bases__`` is a\n tuple (possibly empty or a singleton) containing the base classes,\n in the order of their occurrence in the base class list;\n ``__doc__`` is the class\'s documentation string, or None if\n undefined.\n\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object or an unbound user-defined method object whose\n associated class is the class (call it ``C``) of the instance for\n which the attribute reference was initiated or one of its bases, it\n is transformed into a bound user-defined method object whose\n ``im_class`` attribute is ``C`` and whose ``im_self`` attribute is\n the instance. Static method and class method objects are also\n transformed, as if they had been retrieved from class ``C``; see\n above under "Classes". See section *Implementing Descriptors* for\n another way in which attributes of a class retrieved via its\n instances may differ from the objects actually stored in the\n class\'s ``__dict__``. If no class attribute is found, and the\n object\'s class has a ``__getattr__()`` method, that is called to\n satisfy the lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n ``__setattr__()`` or ``__delattr__()`` method, this is called\n instead of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n *Special method names*.\n\n Special attributes: ``__dict__`` is the attribute dictionary;\n ``__class__`` is the instance\'s class.\n\nFiles\n A file object represents an open file. File objects are created by\n the ``open()`` built-in function, and also by ``os.popen()``,\n ``os.fdopen()``, and the ``makefile()`` method of socket objects\n (and perhaps by other functions or methods provided by extension\n modules). The objects ``sys.stdin``, ``sys.stdout`` and\n ``sys.stderr`` are initialized to file objects corresponding to the\n interpreter\'s standard input, output and error streams. See *File\n Objects* for complete documentation of file objects.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: ``co_name`` gives the function\n name; ``co_argcount`` is the number of positional arguments\n (including arguments with default values); ``co_nlocals`` is the\n number of local variables used by the function (including\n arguments); ``co_varnames`` is a tuple containing the names of\n the local variables (starting with the argument names);\n ``co_cellvars`` is a tuple containing the names of local\n variables that are referenced by nested functions;\n ``co_freevars`` is a tuple containing the names of free\n variables; ``co_code`` is a string representing the sequence of\n bytecode instructions; ``co_consts`` is a tuple containing the\n literals used by the bytecode; ``co_names`` is a tuple\n containing the names used by the bytecode; ``co_filename`` is\n the filename from which the code was compiled;\n ``co_firstlineno`` is the first line number of the function;\n ``co_lnotab`` is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); ``co_stacksize`` is the required stack size\n (including local variables); ``co_flags`` is an integer encoding\n a number of flags for the interpreter.\n\n The following flag bits are defined for ``co_flags``: bit\n ``0x04`` is set if the function uses the ``*arguments`` syntax\n to accept an arbitrary number of positional arguments; bit\n ``0x08`` is set if the function uses the ``**keywords`` syntax\n to accept arbitrary keyword arguments; bit ``0x20`` is set if\n the function is a generator.\n\n Future feature declarations (``from __future__ import\n division``) also use bits in ``co_flags`` to indicate whether a\n code object was compiled with a particular feature enabled: bit\n ``0x2000`` is set if the function was compiled with future\n division enabled; bits ``0x10`` and ``0x1000`` were used in\n earlier versions of Python.\n\n Other bits in ``co_flags`` are reserved for internal use.\n\n If a code object represents a function, the first item in\n ``co_consts`` is the documentation string of the function, or\n ``None`` if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: ``f_back`` is to the previous\n stack frame (towards the caller), or ``None`` if this is the\n bottom stack frame; ``f_code`` is the code object being executed\n in this frame; ``f_locals`` is the dictionary used to look up\n local variables; ``f_globals`` is used for global variables;\n ``f_builtins`` is used for built-in (intrinsic) names;\n ``f_restricted`` is a flag indicating whether the function is\n executing in restricted execution mode; ``f_lasti`` gives the\n precise instruction (this is an index into the bytecode string\n of the code object).\n\n Special writable attributes: ``f_trace``, if not ``None``, is a\n function called at the start of each source code line (this is\n used by the debugger); ``f_exc_type``, ``f_exc_value``,\n ``f_exc_traceback`` represent the last exception raised in the\n parent frame provided another exception was ever raised in the\n current frame (in all other cases they are None); ``f_lineno``\n is the current line number of the frame --- writing to this from\n within a trace function jumps to the given line (only for the\n bottom-most frame). A debugger can implement a Jump command\n (aka Set Next Statement) by writing to f_lineno.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n *The try statement*.) It is accessible as ``sys.exc_traceback``,\n and also as the third item of the tuple returned by\n ``sys.exc_info()``. The latter is the preferred interface,\n since it works correctly when the program is using multiple\n threads. When the program contains no suitable handler, the\n stack trace is written (nicely formatted) to the standard error\n stream; if the interpreter is interactive, it is also made\n available to the user as ``sys.last_traceback``.\n\n Special read-only attributes: ``tb_next`` is the next level in\n the stack trace (towards the frame where the exception\n occurred), or ``None`` if there is no next level; ``tb_frame``\n points to the execution frame of the current level;\n ``tb_lineno`` gives the line number where the exception\n occurred; ``tb_lasti`` indicates the precise instruction. The\n line number and last instruction in the traceback may differ\n from the line number of its frame object if the exception\n occurred in a ``try`` statement with no matching except clause\n or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices when *extended slice\n syntax* is used. This is a slice using two colons, or multiple\n slices or ellipses separated by commas, e.g., ``a[i:j:step]``,\n ``a[i:j, k:l]``, or ``a[..., i:j]``. They are also created by\n the built-in ``slice()`` function.\n\n Special read-only attributes: ``start`` is the lower bound;\n ``stop`` is the upper bound; ``step`` is the step value; each is\n ``None`` if omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the extended slice that the slice\n object would describe if applied to a sequence of *length*\n items. It returns a tuple of three integers; respectively\n these are the *start* and *stop* indices and the *step* or\n stride length of the slice. Missing or out-of-bounds indices\n are handled in a manner consistent with regular slices.\n\n New in version 2.3.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n ``staticmethod()`` constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in ``classmethod()`` constructor.\n', + 'try': u'\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\nChanged in version 2.5: In previous versions of Python,\n``try``...``except``...``finally`` did not work. ``try``...``except``\nhad to be nested in ``try``...``finally``.\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, a tuple containing an item compatible with the\nexception, or, in the (deprecated) case of string exceptions, is the\nraised string itself (note that the object identities must match, i.e.\nit must be the same string object, not just a string with the same\nvalue).\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 in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the ``sys`` module:\n``sys.exc_type`` receives the object identifying the exception;\n``sys.exc_value`` receives the exception\'s parameter;\n``sys.exc_traceback`` receives a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. These details are also available through the\n``sys.exc_info()`` function, which returns a tuple ``(exc_type,\nexc_value, exc_traceback)``. Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables 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', + 'types': u'\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.).\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name ``None``.\n It is used to signify the absence of a value in many situations,\n e.g., it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``NotImplemented``. Numeric methods and rich comparison methods may\n return this value if they do not implement the operation for the\n operands provided. (The interpreter will then try the reflected\n operation, or some other fallback, depending on the operator.) Its\n truth value is true.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``Ellipsis``. It is used to indicate the presence of the ``...``\n syntax in a slice. Its truth value is true.\n\n``numbers.Number``\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n ``numbers.Integral``\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are three types of integers:\n\n Plain integers\n These represent numbers in the range -2147483648 through\n 2147483647. (The range may be larger on machines with a\n larger natural word size, but not smaller.) When the result\n of an operation would fall outside this range, the result is\n normally returned as a long integer (in some cases, the\n exception ``OverflowError`` is raised instead). For the\n purpose of shift and mask operations, integers are assumed to\n have a binary, 2\'s complement notation using 32 or more bits,\n and hiding no bits from the user (i.e., all 4294967296\n different bit patterns correspond to different values).\n\n Long integers\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans\n These represent the truth values False and True. The two\n objects representing the values False and True are the only\n Boolean objects. The Boolean type is a subtype of plain\n integers, and Boolean values behave like the values 0 and 1,\n respectively, in almost all contexts, the exception being\n that when converted to a string, the strings ``"False"`` or\n ``"True"`` are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers and the least surprises when\n switching between the plain and long integer domains. Any\n operation, if it yields a result in the plain integer domain,\n will yield the same result in the long integer domain or when\n using mixed operands. The switch between domains is transparent\n to the programmer.\n\n ``numbers.Real`` (``float``)\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these is\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n ``numbers.Complex``\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number ``z`` can be retrieved through the read-only\n attributes ``z.real`` and ``z.imag``.\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function ``len()`` returns the number of\n items of a sequence. When the length of a sequence is *n*, the\n index set contains the numbers 0, 1, ..., *n*-1. Item *i* of\n sequence *a* is selected by ``a[i]``.\n\n Sequences also support slicing: ``a[i:j]`` selects all items with\n index *k* such that *i* ``<=`` *k* ``<`` *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: ``a[i:j:k]`` selects all items of *a* with index *x*\n where ``x = i + n*k``, *n* ``>=`` ``0`` and *i* ``<=`` *x* ``<``\n *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n The items of a string are characters. There is no separate\n character type; a character is represented by a string of one\n item. Characters represent (at least) 8-bit bytes. The\n built-in functions ``chr()`` and ``ord()`` convert between\n characters and nonnegative integers representing the byte\n values. Bytes with the values 0-127 usually represent the\n corresponding ASCII values, but the interpretation of values\n is up to the program. The string data type is also used to\n represent arrays of bytes, e.g., to hold data read from a\n file.\n\n (On systems whose native character set is not ASCII, strings\n may use EBCDIC in their internal representation, provided the\n functions ``chr()`` and ``ord()`` implement a mapping between\n ASCII and EBCDIC, and string comparison preserves the ASCII\n order. Or perhaps someone can propose a better rule?)\n\n Unicode\n The items of a Unicode object are Unicode code units. A\n Unicode code unit is represented by a Unicode object of one\n item and can hold either a 16-bit or 32-bit value\n representing a Unicode ordinal (the maximum value for the\n ordinal is given in ``sys.maxunicode``, and depends on how\n Python is configured at compile time). Surrogate pairs may\n be present in the Unicode object, and will be reported as two\n separate items. The built-in functions ``unichr()`` and\n ``ord()`` convert between code units and nonnegative integers\n representing the Unicode ordinals as defined in the Unicode\n Standard 3.0. Conversion from and to other encodings are\n possible through the Unicode method ``encode()`` and the\n built-in function ``unicode()``.\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and ``del`` (delete) statements.\n\n There are currently two intrinsic mutable sequence types:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n Byte Arrays\n A bytearray object is a mutable array. They are created by\n the built-in ``bytearray()`` constructor. Aside from being\n mutable (and hence unhashable), byte arrays otherwise provide\n the same interface and functionality as immutable bytes\n objects.\n\n The extension module ``array`` provides an additional example of\n a mutable sequence type.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function ``len()``\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n ``set()`` constructor and can be modified afterwards by several\n methods, such as ``add()``.\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in ``frozenset()`` constructor. As a frozenset is\n immutable and *hashable*, it can be used again as an element of\n another set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation ``a[k]`` selects the item indexed by\n ``k`` from the mapping ``a``; this can be used in expressions and\n as the target of assignments or ``del`` statements. The built-in\n function ``len()`` returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``) then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the ``{...}``\n notation (see section *Dictionary displays*).\n\n The extension modules ``dbm``, ``gdbm``, and ``bsddb`` provide\n additional examples of mapping types.\n\nCallable types\n These are the types to which the function call operation (see\n section *Calls*) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section *Function definitions*). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +-------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +=========================+=================================+=============+\n | ``func_doc`` | The function\'s documentation | Writable |\n | | string, or ``None`` if | |\n | | unavailable | |\n +-------------------------+---------------------------------+-------------+\n | ``__doc__`` | Another way of spelling | Writable |\n | | ``func_doc`` | |\n +-------------------------+---------------------------------+-------------+\n | ``func_name`` | The function\'s name | Writable |\n +-------------------------+---------------------------------+-------------+\n | ``__name__`` | Another way of spelling | Writable |\n | | ``func_name`` | |\n +-------------------------+---------------------------------+-------------+\n | ``__module__`` | The name of the module the | Writable |\n | | function was defined in, or | |\n | | ``None`` if unavailable. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_defaults`` | A tuple containing default | Writable |\n | | argument values for those | |\n | | arguments that have defaults, | |\n | | or ``None`` if no arguments | |\n | | have a default value | |\n +-------------------------+---------------------------------+-------------+\n | ``func_code`` | The code object representing | Writable |\n | | the compiled function body. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_globals`` | A reference to the dictionary | Read-only |\n | | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_dict`` | The namespace supporting | Writable |\n | | arbitrary function attributes. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_closure`` | ``None`` or a tuple of cells | Read-only |\n | | that contain bindings for the | |\n | | function\'s free variables. | |\n +-------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Changed in version 2.4: ``func_name`` is now writable.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n User-defined methods\n A user-defined method object combines a class, a class instance\n (or ``None``) and any callable object (normally a user-defined\n function).\n\n Special read-only attributes: ``im_self`` is the class instance\n object, ``im_func`` is the function object; ``im_class`` is the\n class of ``im_self`` for bound methods or the class that asked\n for the method for unbound methods; ``__doc__`` is the method\'s\n documentation (same as ``im_func.__doc__``); ``__name__`` is the\n method name (same as ``im_func.__name__``); ``__module__`` is\n the name of the module the method was defined in, or ``None`` if\n unavailable.\n\n Changed in version 2.2: ``im_self`` used to refer to the class\n that defined the method.\n\n Changed in version 2.6: For 3.0 forward-compatibility,\n ``im_func`` is also available as ``__func__``, and ``im_self``\n as ``__self__``.\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object, an unbound\n user-defined method object, or a class method object. When the\n attribute is a user-defined method object, a new method object\n is only created if the class from which it is being retrieved is\n the same as, or a derived class of, the class stored in the\n original method object; otherwise, the original method object is\n used as it is.\n\n When a user-defined method object is created by retrieving a\n user-defined function object from a class, its ``im_self``\n attribute is ``None`` and the method object is said to be\n unbound. When one is created by retrieving a user-defined\n function object from a class via one of its instances, its\n ``im_self`` attribute is the instance, and the method object is\n said to be bound. In either case, the new method\'s ``im_class``\n attribute is the class from which the retrieval takes place, and\n its ``im_func`` attribute is the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the ``im_func``\n attribute of the new instance is not the original method object\n but its ``im_func`` attribute.\n\n When a user-defined method object is created by retrieving a\n class method object from a class or instance, its ``im_self``\n attribute is the class itself (the same as the ``im_class``\n attribute), and its ``im_func`` attribute is the function object\n underlying the class method.\n\n When an unbound user-defined method object is called, the\n underlying function (``im_func``) is called, with the\n restriction that the first argument must be an instance of the\n proper class (``im_class``) or of a derived class thereof.\n\n When a bound user-defined method object is called, the\n underlying function (``im_func``) is called, inserting the class\n instance (``im_self``) in front of the argument list. For\n instance, when ``C`` is a class which contains a definition for\n a function ``f()``, and ``x`` is an instance of ``C``, calling\n ``x.f(1)`` is equivalent to calling ``C.f(x, 1)``.\n\n When a user-defined method object is derived from a class method\n object, the "class instance" stored in ``im_self`` will actually\n be the class itself, so that calling either ``x.f(1)`` or\n ``C.f(1)`` is equivalent to calling ``f(C,1)`` where ``f`` is\n the underlying function.\n\n Note that the transformation from function object to (unbound or\n bound) method object happens each time the attribute is\n retrieved from the class or instance. In some cases, a fruitful\n optimization is to assign the attribute to a local variable and\n call that local variable. Also notice that this transformation\n only happens for user-defined functions; other callable objects\n (and all non-callable objects) are retrieved without\n transformation. It is also important to note that user-defined\n functions which are attributes of a class instance are not\n converted to bound methods; this *only* happens when the\n function is an attribute of the class.\n\n Generator functions\n A function or method which uses the ``yield`` statement (see\n section *The yield statement*) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s ``next()`` method will cause the function to\n execute until it provides a value using the ``yield`` statement.\n When the function executes a ``return`` statement or falls off\n the end, a ``StopIteration`` exception is raised and the\n iterator will have reached the end of the set of values to be\n returned.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are ``len()`` and ``math.sin()``\n (``math`` is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: ``__doc__`` is the function\'s documentation\n string, or ``None`` if unavailable; ``__name__`` is the\n function\'s name; ``__self__`` is set to ``None`` (but see the\n next item); ``__module__`` is the name of the module the\n function was defined in or ``None`` if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n ``alist.append()``, assuming *alist* is a list object. In this\n case, the special read-only attribute ``__self__`` is set to the\n object denoted by *list*.\n\n Class Types\n Class types, or "new-style classes," are callable. These\n objects normally act as factories for new instances of\n themselves, but variations are possible for class types that\n override ``__new__()``. The arguments of the call are passed to\n ``__new__()`` and, in the typical case, to ``__init__()`` to\n initialize the new instance.\n\n Classic Classes\n Class objects are described below. When a class object is\n called, a new class instance (also described below) is created\n and returned. This implies a call to the class\'s ``__init__()``\n method if it has one. Any arguments are passed on to the\n ``__init__()`` method. If there is no ``__init__()`` method,\n the class must be called without arguments.\n\n Class instances\n Class instances are described below. Class instances are\n callable only when the class has a ``__call__()`` method;\n ``x(arguments)`` is a shorthand for ``x.__call__(arguments)``.\n\nModules\n Modules are imported by the ``import`` statement (see section *The\n import statement*). A module object has a namespace implemented by\n a dictionary object (this is the dictionary referenced by the\n func_globals attribute of functions defined in the module).\n Attribute references are translated to lookups in this dictionary,\n e.g., ``m.x`` is equivalent to ``m.__dict__["x"]``. A module object\n does not contain the code object used to initialize the module\n (since it isn\'t needed once the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``.\n\n Special read-only attribute: ``__dict__`` is the module\'s namespace\n as a dictionary object.\n\n Predefined (writable) attributes: ``__name__`` is the module\'s\n name; ``__doc__`` is the module\'s documentation string, or ``None``\n if unavailable; ``__file__`` is the pathname of the file from which\n the module was loaded, if it was loaded from a file. The\n ``__file__`` attribute is not present for C modules that are\n statically linked into the interpreter; for extension modules\n loaded dynamically from a shared library, it is the pathname of the\n shared library file.\n\nClasses\n Both class types (new-style classes) and class objects (old-\n style/classic classes) are typically created by class definitions\n (see section *Class definitions*). A class has a namespace\n implemented by a dictionary object. Class attribute references are\n translated to lookups in this dictionary, e.g., ``C.x`` is\n translated to ``C.__dict__["x"]`` (although for new-style classes\n in particular there are a number of hooks which allow for other\n means of locating attributes). When the attribute name is not found\n there, the attribute search continues in the base classes. For\n old-style classes, the search is depth-first, left-to-right in the\n order of occurrence in the base class list. New-style classes use\n the more complex C3 method resolution order which behaves correctly\n even in the presence of \'diamond\' inheritance structures where\n there are multiple inheritance paths leading back to a common\n ancestor. Additional details on the C3 MRO used by new-style\n classes can be found in the documentation accompanying the 2.3\n release at http://www.python.org/download/releases/2.3/mro/.\n\n When a class attribute reference (for class ``C``, say) would yield\n a user-defined function object or an unbound user-defined method\n object whose associated class is either ``C`` or one of its base\n classes, it is transformed into an unbound user-defined method\n object whose ``im_class`` attribute is ``C``. When it would yield a\n class method object, it is transformed into a bound user-defined\n method object whose ``im_class`` and ``im_self`` attributes are\n both ``C``. When it would yield a static method object, it is\n transformed into the object wrapped by the static method object.\n See section *Implementing Descriptors* for another way in which\n attributes retrieved from a class may differ from those actually\n contained in its ``__dict__`` (note that only new-style classes\n support descriptors).\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: ``__name__`` is the class name; ``__module__``\n is the module name in which the class was defined; ``__dict__`` is\n the dictionary containing the class\'s namespace; ``__bases__`` is a\n tuple (possibly empty or a singleton) containing the base classes,\n in the order of their occurrence in the base class list;\n ``__doc__`` is the class\'s documentation string, or None if\n undefined.\n\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object or an unbound user-defined method object whose\n associated class is the class (call it ``C``) of the instance for\n which the attribute reference was initiated or one of its bases, it\n is transformed into a bound user-defined method object whose\n ``im_class`` attribute is ``C`` and whose ``im_self`` attribute is\n the instance. Static method and class method objects are also\n transformed, as if they had been retrieved from class ``C``; see\n above under "Classes". See section *Implementing Descriptors* for\n another way in which attributes of a class retrieved via its\n instances may differ from the objects actually stored in the\n class\'s ``__dict__``. If no class attribute is found, and the\n object\'s class has a ``__getattr__()`` method, that is called to\n satisfy the lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n ``__setattr__()`` or ``__delattr__()`` method, this is called\n instead of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n *Special method names*.\n\n Special attributes: ``__dict__`` is the attribute dictionary;\n ``__class__`` is the instance\'s class.\n\nFiles\n A file object represents an open file. File objects are created by\n the ``open()`` built-in function, and also by ``os.popen()``,\n ``os.fdopen()``, and the ``makefile()`` method of socket objects\n (and perhaps by other functions or methods provided by extension\n modules). The objects ``sys.stdin``, ``sys.stdout`` and\n ``sys.stderr`` are initialized to file objects corresponding to the\n interpreter\'s standard input, output and error streams. See *File\n Objects* for complete documentation of file objects.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: ``co_name`` gives the function\n name; ``co_argcount`` is the number of positional arguments\n (including arguments with default values); ``co_nlocals`` is the\n number of local variables used by the function (including\n arguments); ``co_varnames`` is a tuple containing the names of\n the local variables (starting with the argument names);\n ``co_cellvars`` is a tuple containing the names of local\n variables that are referenced by nested functions;\n ``co_freevars`` is a tuple containing the names of free\n variables; ``co_code`` is a string representing the sequence of\n bytecode instructions; ``co_consts`` is a tuple containing the\n literals used by the bytecode; ``co_names`` is a tuple\n containing the names used by the bytecode; ``co_filename`` is\n the filename from which the code was compiled;\n ``co_firstlineno`` is the first line number of the function;\n ``co_lnotab`` is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); ``co_stacksize`` is the required stack size\n (including local variables); ``co_flags`` is an integer encoding\n a number of flags for the interpreter.\n\n The following flag bits are defined for ``co_flags``: bit\n ``0x04`` is set if the function uses the ``*arguments`` syntax\n to accept an arbitrary number of positional arguments; bit\n ``0x08`` is set if the function uses the ``**keywords`` syntax\n to accept arbitrary keyword arguments; bit ``0x20`` is set if\n the function is a generator.\n\n Future feature declarations (``from __future__ import\n division``) also use bits in ``co_flags`` to indicate whether a\n code object was compiled with a particular feature enabled: bit\n ``0x2000`` is set if the function was compiled with future\n division enabled; bits ``0x10`` and ``0x1000`` were used in\n earlier versions of Python.\n\n Other bits in ``co_flags`` are reserved for internal use.\n\n If a code object represents a function, the first item in\n ``co_consts`` is the documentation string of the function, or\n ``None`` if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: ``f_back`` is to the previous\n stack frame (towards the caller), or ``None`` if this is the\n bottom stack frame; ``f_code`` is the code object being executed\n in this frame; ``f_locals`` is the dictionary used to look up\n local variables; ``f_globals`` is used for global variables;\n ``f_builtins`` is used for built-in (intrinsic) names;\n ``f_restricted`` is a flag indicating whether the function is\n executing in restricted execution mode; ``f_lasti`` gives the\n precise instruction (this is an index into the bytecode string\n of the code object).\n\n Special writable attributes: ``f_trace``, if not ``None``, is a\n function called at the start of each source code line (this is\n used by the debugger); ``f_exc_type``, ``f_exc_value``,\n ``f_exc_traceback`` represent the last exception raised in the\n parent frame provided another exception was ever raised in the\n current frame (in all other cases they are None); ``f_lineno``\n is the current line number of the frame --- writing to this from\n within a trace function jumps to the given line (only for the\n bottom-most frame). A debugger can implement a Jump command\n (aka Set Next Statement) by writing to f_lineno.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n *The try statement*.) It is accessible as ``sys.exc_traceback``,\n and also as the third item of the tuple returned by\n ``sys.exc_info()``. The latter is the preferred interface,\n since it works correctly when the program is using multiple\n threads. When the program contains no suitable handler, the\n stack trace is written (nicely formatted) to the standard error\n stream; if the interpreter is interactive, it is also made\n available to the user as ``sys.last_traceback``.\n\n Special read-only attributes: ``tb_next`` is the next level in\n the stack trace (towards the frame where the exception\n occurred), or ``None`` if there is no next level; ``tb_frame``\n points to the execution frame of the current level;\n ``tb_lineno`` gives the line number where the exception\n occurred; ``tb_lasti`` indicates the precise instruction. The\n line number and last instruction in the traceback may differ\n from the line number of its frame object if the exception\n occurred in a ``try`` statement with no matching except clause\n or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices when *extended slice\n syntax* is used. This is a slice using two colons, or multiple\n slices or ellipses separated by commas, e.g., ``a[i:j:step]``,\n ``a[i:j, k:l]``, or ``a[..., i:j]``. They are also created by\n the built-in ``slice()`` function.\n\n Special read-only attributes: ``start`` is the lower bound;\n ``stop`` is the upper bound; ``step`` is the step value; each is\n ``None`` if omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the extended slice that the slice\n object would describe if applied to a sequence of *length*\n items. It returns a tuple of three integers; respectively\n these are the *start* and *stop* indices and the *step* or\n stride length of the slice. Missing or out-of-bounds indices\n are handled in a manner consistent with regular slices.\n\n New in version 2.3.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n ``staticmethod()`` constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in ``classmethod()`` constructor.\n', 'typesfunctions': u'\nFunctions\n*********\n\nFunction objects are created by function definitions. The only\noperation on a function object is to call it: ``func(argument-list)``.\n\nThere are really two flavors of function objects: built-in functions\nand user-defined functions. Both support the same operation (to call\nthe function), but the implementation is different, hence the\ndifferent object types.\n\nSee *Function definitions* for more information.\n', - 'typesmapping': u'\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 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 is\n 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": 2, "two": 3}``:\n\n * ``dict(one=2, two=3)``\n\n * ``dict({\'one\': 2, \'two\': 3})``\n\n * ``dict(zip((\'one\', \'two\'), (2, 3)))``\n\n * ``dict([[\'two\', 3], [\'one\', 2]])``\n\n The first example only works for keys that are valid Python\n identifiers; the others work with any valid keys.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for building a dictionary from\n keyword arguments added.\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 New in version 2.5: If a subclass of dict defines a method\n ``__missing__()``, if the key *key* is not present, the\n ``d[key]`` operation calls that method with the key *key* as\n argument. The ``d[key]`` operation then returns or raises\n whatever is returned or raised by the ``__missing__(key)`` call\n if the key is not present. No other operations or methods invoke\n ``__missing__()``. If ``__missing__()`` is not defined,\n ``KeyError`` is raised. ``__missing__()`` must be a method; it\n cannot be an instance variable. For an example, see\n ``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 New in version 2.2.\n\n key not in d\n\n Equivalent to ``not key in d``.\n\n New in version 2.2.\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 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 New in version 2.3.\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 has_key(key)\n\n ``dict.has_key(key)`` is equivalent to ``key in d``, but\n deprecated.\n\n items()\n\n Return a copy of the dictionary\'s list of ``(key, value)``\n pairs.\n\n Note: Keys and values are listed in an arbitrary order which is non-\n random, varies across Python implementations, and depends on\n the dictionary\'s history of insertions and deletions. If\n ``items()``, ``keys()``, ``values()``, ``iteritems()``,\n ``iterkeys()``, and ``itervalues()`` are called with no\n intervening modifications to the dictionary, the lists will\n directly correspond. This allows the creation of ``(value,\n key)`` pairs using ``zip()``: ``pairs = zip(d.values(),\n d.keys())``. The same relationship holds for the\n ``iterkeys()`` and ``itervalues()`` methods: ``pairs =\n zip(d.itervalues(), d.iterkeys())`` provides the same value\n for ``pairs``. Another way to create the same list is ``pairs\n = [(v, k) for (k, v) in d.iteritems()]``.\n\n iteritems()\n\n Return an iterator over the dictionary\'s ``(key, value)`` pairs.\n See the note for ``dict.items()``.\n\n New in version 2.2.\n\n iterkeys()\n\n Return an iterator over the dictionary\'s keys. See the note for\n ``dict.items()``.\n\n New in version 2.2.\n\n itervalues()\n\n Return an iterator over the dictionary\'s values. See the note\n for ``dict.items()``.\n\n New in version 2.2.\n\n keys()\n\n Return a copy of the dictionary\'s list of keys. See the note\n for ``dict.items()``.\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 New in version 2.3.\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 a tuple or other iterable of\n length two). If keyword arguments are specified, the dictionary\n is then is updated with those key/value pairs: ``d.update(red=1,\n blue=2)``.\n\n Changed in version 2.4: Allowed the argument to be an iterable\n of key/value pairs and allowed keyword arguments.\n\n values()\n\n Return a copy of the dictionary\'s list of values. See the note\n for ``dict.items()``.\n', + 'typesmapping': u'\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 is\n 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": 2, "two": 3}``:\n\n * ``dict(one=2, two=3)``\n\n * ``dict({\'one\': 2, \'two\': 3})``\n\n * ``dict(zip((\'one\', \'two\'), (2, 3)))``\n\n * ``dict([[\'two\', 3], [\'one\', 2]])``\n\n The first example only works for keys that are valid Python\n identifiers; the others work with any valid keys.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for building a dictionary from\n keyword arguments added.\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 New in version 2.5: If a subclass of dict defines a method\n ``__missing__()``, if the key *key* is not present, the\n ``d[key]`` operation calls that method with the key *key* as\n argument. The ``d[key]`` operation then returns or raises\n whatever is returned or raised by the ``__missing__(key)`` call\n if the key is not present. No other operations or methods invoke\n ``__missing__()``. If ``__missing__()`` is not defined,\n ``KeyError`` is raised. ``__missing__()`` must be a method; it\n cannot be an instance variable. For an example, see\n ``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 New in version 2.2.\n\n key not in d\n\n Equivalent to ``not key in d``.\n\n New in version 2.2.\n\n iter(d)\n\n Return an iterator over the keys of the dictionary. This is a\n shortcut for ``iterkeys()``.\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 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 New in version 2.3.\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 has_key(key)\n\n Test for the presence of *key* in the dictionary. ``has_key()``\n is deprecated in favor of ``key in d``.\n\n items()\n\n Return a copy of the dictionary\'s list of ``(key, value)``\n pairs.\n\n Note: Keys and values are listed in an arbitrary order which is non-\n random, varies across Python implementations, and depends on\n the dictionary\'s history of insertions and deletions. If\n ``items()``, ``keys()``, ``values()``, ``iteritems()``,\n ``iterkeys()``, and ``itervalues()`` are called with no\n intervening modifications to the dictionary, the lists will\n directly correspond. This allows the creation of ``(value,\n key)`` pairs using ``zip()``: ``pairs = zip(d.values(),\n d.keys())``. The same relationship holds for the\n ``iterkeys()`` and ``itervalues()`` methods: ``pairs =\n zip(d.itervalues(), d.iterkeys())`` provides the same value\n for ``pairs``. Another way to create the same list is ``pairs\n = [(v, k) for (k, v) in d.iteritems()]``.\n\n iteritems()\n\n Return an iterator over the dictionary\'s ``(key, value)`` pairs.\n See the note for ``dict.items()``.\n\n Using ``iteritems()`` while adding or deleting entries in the\n dictionary will raise a ``RuntimeError``.\n\n New in version 2.2.\n\n iterkeys()\n\n Return an iterator over the dictionary\'s keys. See the note for\n ``dict.items()``.\n\n Using ``iterkeys()`` while adding or deleting entries in the\n dictionary will raise a ``RuntimeError``.\n\n New in version 2.2.\n\n itervalues()\n\n Return an iterator over the dictionary\'s values. See the note\n for ``dict.items()``.\n\n Using ``itervalues()`` while adding or deleting entries in the\n dictionary will raise a ``RuntimeError``.\n\n New in version 2.2.\n\n keys()\n\n Return a copy of the dictionary\'s list of keys. See the note\n for ``dict.items()``.\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 New in version 2.3.\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 a tuple or other iterable of\n length two). If keyword arguments are specified, the dictionary\n is then is updated with those key/value pairs: ``d.update(red=1,\n blue=2)``.\n\n Changed in version 2.4: Allowed the argument to be an iterable\n of key/value pairs and allowed keyword arguments.\n\n values()\n\n Return a copy of the dictionary\'s list of values. See the note\n for ``dict.items()``.\n', 'typesmethods': u"\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\nThe implementation adds two special read-only attributes to class\ninstance methods: ``m.im_self`` is the object on which the method\noperates, and ``m.im_func`` is the function implementing the method.\nCalling ``m(arg-1, arg-2, ..., arg-n)`` is completely equivalent to\ncalling ``m.im_func(m.im_self, arg-1, arg-2, ..., arg-n)``.\n\nClass instance methods are either *bound* or *unbound*, referring to\nwhether the method was accessed through an instance or a class,\nrespectively. When a method is unbound, its ``im_self`` attribute\nwill be ``None`` and if called, an explicit ``self`` object must be\npassed as the first argument. In this case, ``self`` must be an\ninstance of the unbound method's class (or a subclass of that class),\notherwise a ``TypeError`` is raised.\n\nLike function objects, methods objects support getting arbitrary\nattributes. However, since method attributes are actually stored on\nthe underlying function object (``meth.im_func``), setting method\nattributes on either bound or unbound methods is disallowed.\nAttempting to set a method attribute results in a ``TypeError`` being\nraised. In order to set a method attribute, you need to explicitly\nset it on the underlying function object:\n\n class C:\n def method(self):\n pass\n\n c = C()\n c.method.im_func.whoami = 'my name is c'\n\nSee *The standard type hierarchy* for more information.\n", 'typesmodules': u"\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': u'\nSequence Types --- ``str``, ``unicode``, ``list``, ``tuple``, ``buffer``, ``xrange``\n************************************************************************************\n\nThere are six sequence types: strings, Unicode strings, lists, tuples,\nbuffers, and xrange objects. (For other containers see the built in\n``dict``, ``list``, ``set``, and ``tuple`` classes, and the\n``collections`` module.)\n\nString literals are written in single or double quotes: ``\'xyzzy\'``,\n``"frobozz"``. See *String literals* for more about string literals.\nUnicode strings are much like strings, but are specified in the syntax\nusing a preceding ``\'u\'`` character: ``u\'abc\'``, ``u"def"``. In\naddition to the functionality described here, there are also string-\nspecific methods described in the *String Methods* section. Lists are\nconstructed with square brackets, separating items with commas: ``[a,\nb, c]``. Tuples are constructed by the comma operator (not within\nsquare brackets), with or without enclosing parentheses, but an empty\ntuple must have the enclosing parentheses, such as ``a, b, c`` or\n``()``. A single item tuple must have a trailing comma, such as\n``(d,)``.\n\nBuffer objects are not directly supported by Python syntax, but can be\ncreated by calling the builtin function ``buffer()``. They don\'t\nsupport concatenation or repetition.\n\nObjects of type xrange are similar to buffers in that there is no\nspecific syntax to create them, but they are created using the\n``xrange()`` function. They don\'t support slicing, concatenation or\nrepetition, and using ``in``, ``not in``, ``min()`` or ``max()`` on\nthem 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 compare\nequal and the two sequences must be of the same type and have the same\nlength. (For full details see *Comparisons* in the language\nreference.)\n\nNotes:\n\n1. When *s* is a string or Unicode string object the ``in`` and ``not\n in`` operations act like a substring test. In Python versions\n before 2.3, *x* had to be a string of length 1. In Python 2.3 and\n beyond, *x* may be a string of any length.\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. If *s* and *t* are both strings, some Python implementations such\n as CPython can usually perform an in-place optimization for\n assignments of the form ``s=s+t`` or ``s+=t``. When applicable,\n this optimization makes quadratic run-time much less likely. This\n optimization is both version and implementation dependent. For\n performance sensitive code, it is preferable to use the\n ``str.join()`` method which assures consistent linear concatenation\n performance across versions and implementations.\n\n Changed in version 2.4: Formerly, string concatenation never\n occurred in-place.\n\n\nString Methods\n==============\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Note that none of these methods take keyword\narguments.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbuffer, xrange* section. To output formatted strings use template\nstrings or the ``%`` operator described in the *String Formatting\nOperations* 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 only its first character\n capitalized.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of occurrences of substring *sub* in the range\n [*start*, *end*]. Optional arguments *start* and *end* are\n interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes 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\n Changed in version 2.5: Accept tuples as *suffix*.\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 range [*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(format_string, *args, **kwargs)\n\n Perform a string formatting operation. The *format_string*\n argument can contain literal text or replacement fields delimited\n by braces ``{}``. Each replacement field contains either the\n numeric index of a positional argument, or the name of a keyword\n argument. Returns a copy of *format_string* where each replacement\n field is replaced with the string value of the corresponding\n 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\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(seq)\n\n Return a string which is the concatenation of the strings in the\n sequence *seq*. The separator between elements is the string\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n New in version 2.5.\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]. Optional\n arguments *start* and *end* are interpreted as in slice notation.\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\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\n New in version 2.5.\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\n New in version 2.4.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n Changed in version 2.5: Accept tuples as *prefix*.\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\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string: words start with\n uppercase characters, all remaining cased characters are lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\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 New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n\n\nString Formatting Operations\n============================\n\nString and Unicode objects have one unique built-in operation: the\n``%`` operator (modulo). This is also known as the string\n*formatting* or *interpolation* operator. Given ``format % values``\n(where *format* is a string or Unicode object), ``%`` conversion\nspecifications in *format* are replaced with zero or more elements of\n*values*. The effect is similar to the using ``sprintf`` in the C\nlanguage. If *format* is a Unicode object, or if any of the objects\nbeing converted using the ``%s`` conversion are Unicode objects, the\nresult will also be a Unicode object.\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 %(#)03d quote types.\' % \\\n... {\'language\': "Python", "#": 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\'`` | Obselete 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()``). | (6) |\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 ``%r`` conversion was added in Python 2.0.\n\n The precision determines the maximal number of characters used.\n\n6. If the object or format provided is a ``unicode`` string, the\n resulting string will also be ``unicode``.\n\n The precision determines the maximal number of characters used.\n\n7. 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\nFor safety reasons, floating point precisions are clipped to 50;\n``%f`` conversions for numbers whose absolute value is over 1e25 are\nreplaced by ``%g`` conversions. [5] All other errors raise\nexceptions.\n\nAdditional string operations are defined in standard modules\n``string`` and ``re``.\n\n\nXRange Type\n===========\n\nThe ``xrange`` type is an immutable sequence which is commonly used\nfor looping. The advantage of the ``xrange`` type is that an\n``xrange`` object will always take the same amount of memory, no\nmatter the size of the range it represents. There are no consistent\nperformance advantages.\n\nXRange objects have very little behavior: they only support indexing,\niteration, and the ``len()`` function.\n\n\nMutable Sequence Types\n======================\n\nList objects support additional operations that allow in-place\nmodification of the object. Other mutable sequence types (when added\nto the language) should also support these operations. Strings and\ntuples are immutable sequence types: such objects cannot be modified\nonce created. The following operations are defined on mutable sequence\ntypes (where *x* is an arbitrary object):\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)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\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 | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. 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 list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn\'t have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don\'t return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\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``.\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 In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. While a list is being sorted, the effect of attempting to mutate,\n or even inspect, the list is undefined. The C implementation of\n Python 2.3 and newer makes the list appear empty for the duration,\n and raises ``ValueError`` if it can detect that the list has been\n mutated during a sort.\n', + 'typesseq': u'\nSequence Types --- ``str``, ``unicode``, ``list``, ``tuple``, ``buffer``, ``xrange``\n************************************************************************************\n\nThere are six sequence types: strings, Unicode strings, lists, tuples,\nbuffers, and xrange objects.\n\nFor other containers see the built in ``dict`` and ``set`` classes,\nand the ``collections`` module.\n\nString literals are written in single or double quotes: ``\'xyzzy\'``,\n``"frobozz"``. See *String literals* for more about string literals.\nUnicode strings are much like strings, but are specified in the syntax\nusing a preceding ``\'u\'`` character: ``u\'abc\'``, ``u"def"``. In\naddition to the functionality described here, there are also string-\nspecific methods described in the *String Methods* section. Lists are\nconstructed with square brackets, separating items with commas: ``[a,\nb, c]``. Tuples are constructed by the comma operator (not within\nsquare brackets), with or without enclosing parentheses, but an empty\ntuple must have the enclosing parentheses, such as ``a, b, c`` or\n``()``. A single item tuple must have a trailing comma, such as\n``(d,)``.\n\nBuffer objects are not directly supported by Python syntax, but can be\ncreated by calling the builtin function ``buffer()``. They don\'t\nsupport concatenation or repetition.\n\nObjects of type xrange are similar to buffers in that there is no\nspecific syntax to create them, but they are created using the\n``xrange()`` function. They don\'t support slicing, concatenation or\nrepetition, and using ``in``, ``not in``, ``min()`` or ``max()`` on\nthem 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 compare\nequal and the two sequences must be of the same type and have the same\nlength. (For full details see *Comparisons* in the language\nreference.)\n\nNotes:\n\n1. When *s* is a string or Unicode string object the ``in`` and ``not\n in`` operations act like a substring test. In Python versions\n before 2.3, *x* had to be a string of length 1. In Python 2.3 and\n beyond, *x* may be a string of any length.\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. If *s* and *t* are both strings, some Python implementations such\n as CPython can usually perform an in-place optimization for\n assignments of the form ``s=s+t`` or ``s+=t``. When applicable,\n this optimization makes quadratic run-time much less likely. This\n optimization is both version and implementation dependent. For\n performance sensitive code, it is preferable to use the\n ``str.join()`` method which assures consistent linear concatenation\n performance across versions and implementations.\n\n Changed in version 2.4: Formerly, string concatenation never\n occurred in-place.\n\n\nString Methods\n==============\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Note that none of these methods take keyword\narguments.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbuffer, xrange* section. To output formatted strings use template\nstrings or the ``%`` operator described in the *String Formatting\nOperations* 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 only its first character\n capitalized.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.4: Support for the *fillchar* argument.\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.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes 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\n Changed in version 2.5: Accept tuples as *suffix*.\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 range [*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 *format_string*\n argument can contain literal text or replacement fields delimited\n by braces ``{}``. Each replacement field contains either the\n numeric index of a positional argument, or the name of a keyword\n argument. Returns a copy of *format_string* where each replacement\n field is replaced with the string value of the corresponding\n 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\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(seq)\n\n Return a string which is the concatenation of the strings in the\n sequence *seq*. The separator between elements is the string\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n New in version 2.5.\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]. Optional\n arguments *start* and *end* are interpreted as in slice notation.\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\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\n New in version 2.5.\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\n New in version 2.4.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n Changed in version 2.5: Accept tuples as *prefix*.\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\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string: words start with\n uppercase characters, all remaining cased characters are lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\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 New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n\n\nString Formatting Operations\n============================\n\nString and Unicode objects have one unique built-in operation: the\n``%`` operator (modulo). This is also known as the string\n*formatting* or *interpolation* operator. Given ``format % values``\n(where *format* is a string or Unicode object), ``%`` conversion\nspecifications in *format* are replaced with zero or more elements of\n*values*. The effect is similar to the using ``sprintf`` in the C\nlanguage. If *format* is a Unicode object, or if any of the objects\nbeing converted using the ``%s`` conversion are Unicode objects, the\nresult will also be a Unicode object.\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 %(#)03d quote types.\' % \\\n... {\'language\': "Python", "#": 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()``). | (6) |\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 ``%r`` conversion was added in Python 2.0.\n\n The precision determines the maximal number of characters used.\n\n6. If the object or format provided is a ``unicode`` string, the\n resulting string will also be ``unicode``.\n\n The precision determines the maximal number of characters used.\n\n7. 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\nFor safety reasons, floating point precisions are clipped to 50;\n``%f`` conversions for numbers whose absolute value is over 1e50 are\nreplaced by ``%g`` conversions. [5] All other errors raise\nexceptions.\n\nAdditional string operations are defined in standard modules\n``string`` and ``re``.\n\n\nXRange Type\n===========\n\nThe ``xrange`` type is an immutable sequence which is commonly used\nfor looping. The advantage of the ``xrange`` type is that an\n``xrange`` object will always take the same amount of memory, no\nmatter the size of the range it represents. There are no consistent\nperformance advantages.\n\nXRange objects have very little behavior: they only support indexing,\niteration, and the ``len()`` function.\n\n\nMutable Sequence Types\n======================\n\nList objects support additional operations that allow in-place\nmodification of the object. Other mutable sequence types (when added\nto the language) should also support these operations. Strings and\ntuples are immutable sequence types: such objects cannot be modified\nonce created. The following operations are defined on mutable sequence\ntypes (where *x* is an arbitrary object):\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)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\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 | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. 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 list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn\'t have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don\'t return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\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``.\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 In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. While a list is being sorted, the effect of attempting to mutate,\n or even inspect, the list is undefined. The C implementation of\n Python 2.3 and newer makes the list appear empty for the duration,\n and raises ``ValueError`` if it can detect that the list has been\n mutated during a sort.\n', 'typesseq-mutable': u"\nMutable Sequence Types\n**********************\n\nList objects support additional operations that allow in-place\nmodification of the object. Other mutable sequence types (when added\nto the language) should also support these operations. Strings and\ntuples are immutable sequence types: such objects cannot be modified\nonce created. The following operations are defined on mutable sequence\ntypes (where *x* is an arbitrary object):\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)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\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 | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. 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 list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn't have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don't return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\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``.\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 In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. While a list is being sorted, the effect of attempting to mutate,\n or even inspect, the list is undefined. The C implementation of\n Python 2.3 and newer makes the list appear empty for the duration,\n and raises ``ValueError`` if it can detect that the list has been\n mutated during a sort.\n", - 'unary': u'\nUnary arithmetic 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\nplain or long integer argument. The bitwise inversion of ``x`` is\ndefined as ``-(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', + 'unary': u'\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\nplain or long integer argument. The bitwise inversion of ``x`` is\ndefined as ``-(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': u'\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', 'with': u'\nThe ``with`` statement\n**********************\n\nNew in version 2.5.\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" expression ["as" target] ":" suite\n\nThe execution of the ``with`` statement proceeds as follows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__enter__()`` method is invoked.\n\n3. 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 5 below.\n\n4. The suite is executed.\n\n5. 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\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n', 'yield': u'\nThe ``yield`` statement\n***********************\n\n yield_stmt ::= yield_expression\n\nThe ``yield`` statement is only used when defining a generator\nfunction, and is only used in the body of the generator function.\nUsing a ``yield`` statement in a function definition is sufficient to\ncause that definition to create a generator function instead of a\nnormal function.\n\nWhen a generator function is called, it returns an iterator known as a\ngenerator iterator, or more commonly, a generator. The body of the\ngenerator function is executed by calling the generator\'s ``next()``\nmethod repeatedly until it raises an exception.\n\nWhen a ``yield`` statement is executed, the state of the generator is\nfrozen and the value of **expression_list** is returned to\n``next()``\'s caller. By "frozen" we mean that all local state is\nretained, including the current bindings of local variables, the\ninstruction pointer, and the internal evaluation stack: enough\ninformation is saved so that the next time ``next()`` is invoked, the\nfunction can proceed exactly as if the ``yield`` statement were just\nanother external call.\n\nAs of Python version 2.5, the ``yield`` statement is now allowed in\nthe ``try`` clause of a ``try`` ... ``finally`` construct. If the\ngenerator is not resumed before it is finalized (by reaching a zero\nreference count or by being garbage collected), the generator-\niterator\'s ``close()`` method will be called, allowing any pending\n``finally`` clauses to execute.\n\nNote: In Python 2.2, the ``yield`` statement was only allowed when the\n ``generators`` feature has been enabled. This ``__future__`` import\n statement was used to enable the feature:\n\n from __future__ import generators\n\nSee also:\n\n **PEP 0255** - Simple Generators\n The proposal for adding generators and the ``yield`` statement\n to Python.\n\n **PEP 0342** - Coroutines via Enhanced Generators\n The proposal that, among other generator enhancements, proposed\n allowing ``yield`` to appear inside a ``try`` ... ``finally``\n block.\n'} From python-checkins at python.org Sun Apr 26 12:05:11 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 26 Apr 2009 12:05:11 +0200 (CEST) Subject: [Python-checkins] r71962 - python/trunk/Doc/c-api/conversion.rst Message-ID: <20090426100511.4C8AF1E4012@bag.python.org> Author: eric.smith Date: Sun Apr 26 12:05:11 2009 New Revision: 71962 Log: Note that the caller is resposible for freeing the result of PyOS_double_to_string. Modified: python/trunk/Doc/c-api/conversion.rst Modified: python/trunk/Doc/c-api/conversion.rst ============================================================================== --- python/trunk/Doc/c-api/conversion.rst (original) +++ python/trunk/Doc/c-api/conversion.rst Sun Apr 26 12:05:11 2009 @@ -109,7 +109,8 @@ *val* is a finite number, an infinite number, or not a number, respectively. The return value is a pointer to *buffer* with the converted string or - *NULL* if the conversion failed. + *NULL* if the conversion failed. The caller is responsible for freeing the + returned string by calling :cfunc:`PyMem_Free`. .. versionadded:: 2.7 From python-checkins at python.org Sun Apr 26 16:00:08 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 26 Apr 2009 16:00:08 +0200 (CEST) Subject: [Python-checkins] r71963 - python/trunk/Objects/complexobject.c Message-ID: <20090426140008.6922E1E4010@bag.python.org> Author: mark.dickinson Date: Sun Apr 26 16:00:08 2009 New Revision: 71963 Log: Reset errno before both calls to PyOS_ascii_strtod, not just one. Modified: python/trunk/Objects/complexobject.c Modified: python/trunk/Objects/complexobject.c ============================================================================== --- python/trunk/Objects/complexobject.c (original) +++ python/trunk/Objects/complexobject.c Sun Apr 26 16:00:08 2009 @@ -911,8 +911,6 @@ return NULL; } - errno = 0; - /* position on first nonblank */ start = s; while (*s && isspace(Py_CHARMASK(*s))) @@ -947,6 +945,7 @@ */ /* first look for forms starting with */ + errno = 0; z = PyOS_ascii_strtod(s, &end); if (end == s && errno == ENOMEM) return PyErr_NoMemory(); @@ -959,6 +958,7 @@ if (*s == '+' || *s == '-') { /* j | j */ x = z; + errno = 0; y = PyOS_ascii_strtod(s, &end); if (end == s && errno == ENOMEM) return PyErr_NoMemory(); From python-checkins at python.org Sun Apr 26 16:00:59 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 26 Apr 2009 16:00:59 +0200 (CEST) Subject: [Python-checkins] r71964 - python/branches/release26-maint Message-ID: <20090426140059.7495F1E4010@bag.python.org> Author: mark.dickinson Date: Sun Apr 26 16:00:59 2009 New Revision: 71964 Log: Blocked revisions 71963 via svnmerge ........ r71963 | mark.dickinson | 2009-04-26 15:00:08 +0100 (Sun, 26 Apr 2009) | 2 lines Reset errno before both calls to PyOS_ascii_strtod, not just one. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Apr 26 16:11:18 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 26 Apr 2009 16:11:18 +0200 (CEST) Subject: [Python-checkins] r71965 - in python/branches/py3k: Objects/complexobject.c Message-ID: <20090426141118.E6C9B1E4010@bag.python.org> Author: mark.dickinson Date: Sun Apr 26 16:11:18 2009 New Revision: 71965 Log: Merged revisions 71963 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71963 | mark.dickinson | 2009-04-26 15:00:08 +0100 (Sun, 26 Apr 2009) | 2 lines Reset errno before both calls to PyOS_ascii_strtod, not just one. ........ Modified: python/branches/py3k/ (props changed) 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 Sun Apr 26 16:11:18 2009 @@ -746,8 +746,6 @@ return NULL; } - errno = 0; - /* position on first nonblank */ start = s; while (*s && isspace(Py_CHARMASK(*s))) @@ -782,6 +780,7 @@ */ /* first look for forms starting with */ + errno = 0; z = PyOS_ascii_strtod(s, &end); if (end == s && errno == ENOMEM) return PyErr_NoMemory(); @@ -794,6 +793,7 @@ if (*s == '+' || *s == '-') { /* j | j */ x = z; + errno = 0; y = PyOS_ascii_strtod(s, &end); if (end == s && errno == ENOMEM) return PyErr_NoMemory(); From python-checkins at python.org Sun Apr 26 16:11:57 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 26 Apr 2009 16:11:57 +0200 (CEST) Subject: [Python-checkins] r71966 - python/branches/release30-maint Message-ID: <20090426141157.887701E4010@bag.python.org> Author: mark.dickinson Date: Sun Apr 26 16:11:57 2009 New Revision: 71966 Log: Blocked revisions 71965 via svnmerge ................ r71965 | mark.dickinson | 2009-04-26 15:11:18 +0100 (Sun, 26 Apr 2009) | 9 lines Merged revisions 71963 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71963 | mark.dickinson | 2009-04-26 15:00:08 +0100 (Sun, 26 Apr 2009) | 2 lines Reset errno before both calls to PyOS_ascii_strtod, not just one. ........ ................ Modified: python/branches/release30-maint/ (props changed) From buildbot at python.org Sun Apr 26 16:46:44 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 26 Apr 2009 14:46:44 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable trunk Message-ID: <20090426144644.453971E4010@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%20trunk/builds/418 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: eric.smith,mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_os make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sun Apr 26 17:30:48 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 26 Apr 2009 17:30:48 +0200 (CEST) Subject: [Python-checkins] r71967 - in python/branches/py3k: Objects/floatobject.c Python/pystrtod.c Message-ID: <20090426153048.49B811E4108@bag.python.org> Author: mark.dickinson Date: Sun Apr 26 17:30:47 2009 New Revision: 71967 Log: Internal plumbing changes for float parsing: - check for nans and infs within PyOS_ascii_strtod - simplify parsing in PyFloat_FromString, and handle out-of-memory errors properly Modified: python/branches/py3k/Objects/floatobject.c python/branches/py3k/Python/pystrtod.c Modified: python/branches/py3k/Objects/floatobject.c ============================================================================== --- python/branches/py3k/Objects/floatobject.c (original) +++ python/branches/py3k/Objects/floatobject.c Sun Apr 26 17:30:47 2009 @@ -162,7 +162,7 @@ PyObject * PyFloat_FromString(PyObject *v) { - const char *s, *last, *end, *sp; + const char *s, *last, *end; double x; char buffer[256]; /* for errors */ char *s_buffer = NULL; @@ -186,76 +186,40 @@ "float() argument must be a string or a number"); return NULL; } - last = s + len; + while (*s && isspace(Py_CHARMASK(*s))) s++; - if (*s == '\0') { - PyErr_SetString(PyExc_ValueError, "empty string for float()"); - goto error; - } - sp = s; - /* We don't care about overflow or underflow. If the platform supports - * them, infinities and signed zeroes (on underflow) are fine. - * However, strtod can return 0 for denormalized numbers. Note that - * whether strtod sets errno on underflow is not defined, so we can't - * key off errno. - */ + /* We don't care about overflow or underflow. If the platform + * supports them, infinities and signed zeroes (on underflow) are + * fine. */ + errno = 0; PyFPE_START_PROTECT("strtod", goto error) x = PyOS_ascii_strtod(s, (char **)&end); PyFPE_END_PROTECT(x) - errno = 0; - /* Believe it or not, Solaris 2.6 can move end *beyond* the null - byte at the end of the string, when the input is inf(inity). */ - if (end > last) - end = last; - /* Check for inf and nan. This is done late because it rarely happens. */ if (end == s) { - char *p = (char*)sp; - int sign = 1; - - if (*p == '-') { - sign = -1; - p++; - } - if (*p == '+') { - p++; - } - if (PyOS_strnicmp(p, "inf", 4) == 0) { - if (s_buffer != NULL) - PyMem_FREE(s_buffer); - Py_RETURN_INF(sign); - } - if (PyOS_strnicmp(p, "infinity", 9) == 0) { - if (s_buffer != NULL) - PyMem_FREE(s_buffer); - Py_RETURN_INF(sign); - } -#ifdef Py_NAN - if(PyOS_strnicmp(p, "nan", 4) == 0) { - if (s_buffer != NULL) - PyMem_FREE(s_buffer); - Py_RETURN_NAN; + if (errno == ENOMEM) + PyErr_NoMemory(); + else { + PyOS_snprintf(buffer, sizeof(buffer), + "invalid literal for float(): %.200s", s); + PyErr_SetString(PyExc_ValueError, buffer); } -#endif - PyOS_snprintf(buffer, sizeof(buffer), - "invalid literal for float(): %.200s", s); - PyErr_SetString(PyExc_ValueError, buffer); goto error; } /* Since end != s, the platform made *some* kind of sense out of the input. Trust it. */ while (*end && isspace(Py_CHARMASK(*end))) end++; - if (*end != '\0') { - PyOS_snprintf(buffer, sizeof(buffer), - "invalid literal for float(): %.200s", s); - PyErr_SetString(PyExc_ValueError, buffer); - goto error; - } - else if (end != last) { - PyErr_SetString(PyExc_ValueError, - "null byte in argument for float()"); + if (end != last) { + if (*end == '\0') + PyErr_SetString(PyExc_ValueError, + "null byte in argument for float()"); + else { + PyOS_snprintf(buffer, sizeof(buffer), + "invalid literal for float(): %.200s", s); + PyErr_SetString(PyExc_ValueError, buffer); + } goto error; } result = PyFloat_FromDouble(x); Modified: python/branches/py3k/Python/pystrtod.c ============================================================================== --- python/branches/py3k/Python/pystrtod.c (original) +++ python/branches/py3k/Python/pystrtod.c Sun Apr 26 17:30:47 2009 @@ -94,6 +94,10 @@ decimal_point_pos = NULL; + /* Set errno to zero, so that we can distinguish zero results + and underflows */ + errno = 0; + /* We process any leading whitespace and the optional sign manually, then pass the remainder to the system strtod. This ensures that the result of an underflow has the correct sign. (bug #1725) */ @@ -107,27 +111,53 @@ if (*p == '-') { negate = 1; p++; - } else if (*p == '+') { + } + else if (*p == '+') { p++; } - /* What's left should begin with a digit, a decimal point, or one of - the letters i, I, n, N. It should not begin with 0x or 0X */ - if ((!ISDIGIT(*p) && - *p != '.' && *p != 'i' && *p != 'I' && *p != 'n' && *p != 'N') - || - (*p == '0' && (p[1] == 'x' || p[1] == 'X'))) - { - if (endptr) - *endptr = (char*)nptr; - errno = EINVAL; - return val; + /* Parse infinities and nans */ + if (*p == 'i' || *p == 'I') { + if (PyOS_strnicmp(p, "inf", 3) == 0) { + val = Py_HUGE_VAL; + if (PyOS_strnicmp(p+3, "inity", 5) == 0) + fail_pos = (char *)p+8; + else + fail_pos = (char *)p+3; + goto got_val; + } + else + goto invalid_string; } - digits_pos = p; +#ifdef Py_NAN + if (*p == 'n' || *p == 'N') { + if (PyOS_strnicmp(p, "nan", 3) == 0) { + val = Py_NAN; + fail_pos = (char *)p+3; + goto got_val; + } + else + goto invalid_string; + } +#endif + + /* Some platform strtods accept hex floats; Python shouldn't (at the + moment), so we check explicitly for strings starting with '0x'. */ + if (*p == '0' && (*(p+1) == 'x' || *(p+1) == 'X')) + goto invalid_string; + + /* Check that what's left begins with a digit or decimal point */ + if (!ISDIGIT(*p) && *p != '.') + goto invalid_string; - if (decimal_point[0] != '.' || + digits_pos = p; + if (decimal_point[0] != '.' || decimal_point[1] != 0) { + /* Look for a '.' in the input; if present, it'll need to be + swapped for the current locale's decimal point before we + call strtod. On the other hand, if we find the current + locale's decimal point then the input is invalid. */ while (ISDIGIT(*p)) p++; @@ -135,6 +165,7 @@ { decimal_point_pos = p++; + /* locate end of number */ while (ISDIGIT(*p)) p++; @@ -147,27 +178,16 @@ end = p; } else if (strncmp(p, decimal_point, decimal_point_len) == 0) - { /* Python bug #1417699 */ - if (endptr) - *endptr = (char*)nptr; - errno = EINVAL; - return val; - } + goto invalid_string; /* For the other cases, we need not convert the decimal point */ } - /* Set errno to zero, so that we can distinguish zero results - and underflows */ - errno = 0; - - if (decimal_point_pos) - { + if (decimal_point_pos) { char *copy, *c; - - /* We need to convert the '.' to the locale specific decimal - point */ + /* Create a copy of the input, with the '.' converted to the + locale-specific decimal point */ copy = (char *)PyMem_MALLOC(end - digits_pos + 1 + decimal_point_len); if (copy == NULL) { @@ -208,8 +228,9 @@ } if (fail_pos == digits_pos) - fail_pos = (char *)nptr; + goto invalid_string; + got_val: if (negate && fail_pos != nptr) val = -val; @@ -217,6 +238,12 @@ *endptr = fail_pos; return val; + + invalid_string: + if (endptr) + *endptr = (char*)nptr; + errno = EINVAL; + return -1.0; } #endif From python-checkins at python.org Sun Apr 26 17:32:53 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 26 Apr 2009 17:32:53 +0200 (CEST) Subject: [Python-checkins] r71968 - python/branches/release30-maint Message-ID: <20090426153253.5BAE01E4010@bag.python.org> Author: mark.dickinson Date: Sun Apr 26 17:32:53 2009 New Revision: 71968 Log: Blocked revisions 71967 via svnmerge ........ r71967 | mark.dickinson | 2009-04-26 16:30:47 +0100 (Sun, 26 Apr 2009) | 5 lines Internal plumbing changes for float parsing: - check for nans and infs within PyOS_ascii_strtod - simplify parsing in PyFloat_FromString, and handle out-of-memory errors properly ........ Modified: python/branches/release30-maint/ (props changed) From buildbot at python.org Sun Apr 26 17:46:39 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 26 Apr 2009 15:46:39 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 3.x Message-ID: <20090426154639.3BD2E1E4010@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%203.x/builds/813 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_os ====================================================================== FAIL: test_update2 (test.test_os.EnvironTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_os.py", line 382, in test_update2 self.assertEquals(value, "World") AssertionError: '' != 'World' make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sun Apr 26 18:04:06 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 26 Apr 2009 18:04:06 +0200 (CEST) Subject: [Python-checkins] r71969 - in python/trunk: Objects/floatobject.c Python/pystrtod.c Message-ID: <20090426160406.E01811E4010@bag.python.org> Author: mark.dickinson Date: Sun Apr 26 18:04:05 2009 New Revision: 71969 Log: Backport r71967 changes from py3k to trunk. (Internal plumbing changes for float parsing.) Modified: python/trunk/Objects/floatobject.c python/trunk/Python/pystrtod.c Modified: python/trunk/Objects/floatobject.c ============================================================================== --- python/trunk/Objects/floatobject.c (original) +++ python/trunk/Objects/floatobject.c Sun Apr 26 18:04:05 2009 @@ -177,7 +177,7 @@ PyObject * PyFloat_FromString(PyObject *v, char **pend) { - const char *s, *last, *end, *sp; + const char *s, *last, *end; double x; char buffer[256]; /* for errors */ #ifdef Py_USING_UNICODE @@ -212,81 +212,42 @@ "float() argument must be a string or a number"); return NULL; } - last = s + len; + while (*s && isspace(Py_CHARMASK(*s))) s++; - if (*s == '\0') { - PyErr_SetString(PyExc_ValueError, "empty string for float()"); - return NULL; - } - sp = s; - /* We don't care about overflow or underflow. If the platform supports - * them, infinities and signed zeroes (on underflow) are fine. - * However, strtod can return 0 for denormalized numbers, where atof - * does not. So (alas!) we special-case a zero result. Note that - * whether strtod sets errno on underflow is not defined, so we can't - * key off errno. - */ + /* We don't care about overflow or underflow. If the platform + * supports them, infinities and signed zeroes (on underflow) are + * fine. */ + errno = 0; PyFPE_START_PROTECT("strtod", return NULL) x = PyOS_ascii_strtod(s, (char **)&end); PyFPE_END_PROTECT(x) - errno = 0; - /* Believe it or not, Solaris 2.6 can move end *beyond* the null - byte at the end of the string, when the input is inf(inity). */ - if (end > last) - end = last; - /* Check for inf and nan. This is done late because it rarely happens. */ if (end == s) { - char *p = (char*)sp; - int sign = 1; - - if (*p == '-') { - sign = -1; - p++; - } - if (*p == '+') { - p++; - } - if (PyOS_strnicmp(p, "inf", 4) == 0) { - Py_RETURN_INF(sign); - } - if (PyOS_strnicmp(p, "infinity", 9) == 0) { - Py_RETURN_INF(sign); - } -#ifdef Py_NAN - if(PyOS_strnicmp(p, "nan", 4) == 0) { - Py_RETURN_NAN; + if (errno == ENOMEM) + PyErr_NoMemory(); + else { + PyOS_snprintf(buffer, sizeof(buffer), + "invalid literal for float(): %.200s", s); + PyErr_SetString(PyExc_ValueError, buffer); } -#endif - PyOS_snprintf(buffer, sizeof(buffer), - "invalid literal for float(): %.200s", s); - PyErr_SetString(PyExc_ValueError, buffer); return NULL; } /* Since end != s, the platform made *some* kind of sense out of the input. Trust it. */ while (*end && isspace(Py_CHARMASK(*end))) end++; - if (*end != '\0') { - PyOS_snprintf(buffer, sizeof(buffer), - "invalid literal for float(): %.200s", s); - PyErr_SetString(PyExc_ValueError, buffer); - return NULL; - } - else if (end != last) { - PyErr_SetString(PyExc_ValueError, - "null byte in argument for float()"); + if (end != last) { + if (*end == '\0') + PyErr_SetString(PyExc_ValueError, + "null byte in argument for float()"); + else { + PyOS_snprintf(buffer, sizeof(buffer), + "invalid literal for float(): %.200s", s); + PyErr_SetString(PyExc_ValueError, buffer); + } return NULL; } - if (x == 0.0) { - /* See above -- may have been strtod being anal - about denorms. */ - PyFPE_START_PROTECT("atof", return NULL) - x = PyOS_ascii_atof(s); - PyFPE_END_PROTECT(x) - errno = 0; /* whether atof ever set errno is undefined */ - } return PyFloat_FromDouble(x); } Modified: python/trunk/Python/pystrtod.c ============================================================================== --- python/trunk/Python/pystrtod.c (original) +++ python/trunk/Python/pystrtod.c Sun Apr 26 18:04:05 2009 @@ -71,6 +71,10 @@ decimal_point_pos = NULL; + /* Set errno to zero, so that we can distinguish zero results + and underflows */ + errno = 0; + /* We process any leading whitespace and the optional sign manually, then pass the remainder to the system strtod. This ensures that the result of an underflow has the correct sign. (bug #1725) */ @@ -84,27 +88,53 @@ if (*p == '-') { negate = 1; p++; - } else if (*p == '+') { + } + else if (*p == '+') { p++; } - /* What's left should begin with a digit, a decimal point, or one of - the letters i, I, n, N. It should not begin with 0x or 0X */ - if ((!ISDIGIT(*p) && - *p != '.' && *p != 'i' && *p != 'I' && *p != 'n' && *p != 'N') - || - (*p == '0' && (p[1] == 'x' || p[1] == 'X'))) - { - if (endptr) - *endptr = (char*)nptr; - errno = EINVAL; - return val; + /* Parse infinities and nans */ + if (*p == 'i' || *p == 'I') { + if (PyOS_strnicmp(p, "inf", 3) == 0) { + val = Py_HUGE_VAL; + if (PyOS_strnicmp(p+3, "inity", 5) == 0) + fail_pos = (char *)p+8; + else + fail_pos = (char *)p+3; + goto got_val; + } + else + goto invalid_string; } - digits_pos = p; +#ifdef Py_NAN + if (*p == 'n' || *p == 'N') { + if (PyOS_strnicmp(p, "nan", 3) == 0) { + val = Py_NAN; + fail_pos = (char *)p+3; + goto got_val; + } + else + goto invalid_string; + } +#endif + + /* Some platform strtods accept hex floats; Python shouldn't (at the + moment), so we check explicitly for strings starting with '0x'. */ + if (*p == '0' && (*(p+1) == 'x' || *(p+1) == 'X')) + goto invalid_string; + + /* Check that what's left begins with a digit or decimal point */ + if (!ISDIGIT(*p) && *p != '.') + goto invalid_string; - if (decimal_point[0] != '.' || + digits_pos = p; + if (decimal_point[0] != '.' || decimal_point[1] != 0) { + /* Look for a '.' in the input; if present, it'll need to be + swapped for the current locale's decimal point before we + call strtod. On the other hand, if we find the current + locale's decimal point then the input is invalid. */ while (ISDIGIT(*p)) p++; @@ -112,6 +142,7 @@ { decimal_point_pos = p++; + /* locate end of number */ while (ISDIGIT(*p)) p++; @@ -124,27 +155,16 @@ end = p; } else if (strncmp(p, decimal_point, decimal_point_len) == 0) - { /* Python bug #1417699 */ - if (endptr) - *endptr = (char*)nptr; - errno = EINVAL; - return val; - } + goto invalid_string; /* For the other cases, we need not convert the decimal point */ } - /* Set errno to zero, so that we can distinguish zero results - and underflows */ - errno = 0; - - if (decimal_point_pos) - { + if (decimal_point_pos) { char *copy, *c; - - /* We need to convert the '.' to the locale specific decimal - point */ + /* Create a copy of the input, with the '.' converted to the + locale-specific decimal point */ copy = (char *)PyMem_MALLOC(end - digits_pos + 1 + decimal_point_len); if (copy == NULL) { @@ -185,8 +205,9 @@ } if (fail_pos == digits_pos) - fail_pos = (char *)nptr; + goto invalid_string; + got_val: if (negate && fail_pos != nptr) val = -val; @@ -194,6 +215,12 @@ *endptr = fail_pos; return val; + + invalid_string: + if (endptr) + *endptr = (char*)nptr; + errno = EINVAL; + return -1.0; } double From python-checkins at python.org Sun Apr 26 18:04:47 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 26 Apr 2009 18:04:47 +0200 (CEST) Subject: [Python-checkins] r71970 - python/branches/release26-maint Message-ID: <20090426160447.01B2A1E4010@bag.python.org> Author: mark.dickinson Date: Sun Apr 26 18:04:46 2009 New Revision: 71970 Log: Blocked revisions 71969 via svnmerge ........ r71969 | mark.dickinson | 2009-04-26 17:04:05 +0100 (Sun, 26 Apr 2009) | 3 lines Backport r71967 changes from py3k to trunk. (Internal plumbing changes for float parsing.) ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Sun Apr 26 18:05:52 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 26 Apr 2009 18:05:52 +0200 (CEST) Subject: [Python-checkins] r71971 - python/branches/py3k Message-ID: <20090426160552.C45DE1E4010@bag.python.org> Author: mark.dickinson Date: Sun Apr 26 18:05:51 2009 New Revision: 71971 Log: Blocked revisions 71969 via svnmerge ........ r71969 | mark.dickinson | 2009-04-26 17:04:05 +0100 (Sun, 26 Apr 2009) | 3 lines Backport r71967 changes from py3k to trunk. (Internal plumbing changes for float parsing.) ........ Modified: python/branches/py3k/ (props changed) From buildbot at python.org Sun Apr 26 18:29:20 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 26 Apr 2009 16:29:20 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo trunk Message-ID: <20090426162921.134261E4010@bag.python.org> The Buildbot has detected a new failure of x86 gentoo trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%20trunk/builds/4881 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_os ====================================================================== FAIL: test_update2 (test.test_os.EnvironTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildslave/python-trunk/trunk.norwitz-x86/build/Lib/test/test_os.py", line 348, in test_update2 self.assertEquals(value, "World") AssertionError: '' != 'World' make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Sun Apr 26 18:42:02 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 26 Apr 2009 16:42:02 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090426164203.9E8701E4011@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/643 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: hirokazu.yamamoto,mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_os test_time ====================================================================== FAIL: test_update2 (test.test_os.EnvironTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/test/test_os.py", line 382, in test_update2 self.assertEquals(value, "World") AssertionError: '' != 'World' ====================================================================== FAIL: test_tzset (test.test_time.TimeTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/test/test_time.py", line 166, in test_tzset self.failIfEqual(time.gmtime(xmas2002), time.localtime(xmas2002)) AssertionError: time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) == time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Sun Apr 26 19:00:33 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 26 Apr 2009 17:00:33 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 3.x Message-ID: <20090426170034.46E8B1E4011@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%203.x/builds/688 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_os ====================================================================== FAIL: test_update2 (test.test_os.EnvironTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/test/test_os.py", line 382, in test_update2 self.assertEquals(value, "World") AssertionError: '' != 'World' make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Sun Apr 26 20:22:27 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 26 Apr 2009 18:22:27 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc trunk Message-ID: <20090426182227.46F251E4010@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc trunk. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%20trunk/builds/335 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posixpath sincerely, -The Buildbot From python-checkins at python.org Sun Apr 26 21:11:43 2009 From: python-checkins at python.org (walter.doerwald) Date: Sun, 26 Apr 2009 21:11:43 +0200 (CEST) Subject: [Python-checkins] r71972 - python/trunk/Lib/test/test_unicodedata.py Message-ID: <20090426191143.837821E4002@bag.python.org> Author: walter.doerwald Date: Sun Apr 26 21:11:43 2009 New Revision: 71972 Log: Fix typo. Modified: python/trunk/Lib/test/test_unicodedata.py Modified: python/trunk/Lib/test/test_unicodedata.py ============================================================================== --- python/trunk/Lib/test/test_unicodedata.py (original) +++ python/trunk/Lib/test/test_unicodedata.py Sun Apr 26 21:11:43 2009 @@ -270,7 +270,7 @@ [0] ) - def test_buf_4971(self): + def test_bug_4971(self): # LETTER DZ WITH CARON: DZ, Dz, dz self.assertEqual(u"\u01c4".title(), u"\u01c5") self.assertEqual(u"\u01c5".title(), u"\u01c5") From python-checkins at python.org Sun Apr 26 21:12:55 2009 From: python-checkins at python.org (walter.doerwald) Date: Sun, 26 Apr 2009 21:12:55 +0200 (CEST) Subject: [Python-checkins] r71973 - in python/branches/release26-maint: Lib/test/test_unicodedata.py Message-ID: <20090426191255.E75E71E4002@bag.python.org> Author: walter.doerwald Date: Sun Apr 26 21:12:55 2009 New Revision: 71973 Log: Merged revisions 71972 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71972 | walter.doerwald | 2009-04-26 21:11:43 +0200 (So, 26 Apr 2009) | 2 lines Fix typo. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_unicodedata.py Modified: python/branches/release26-maint/Lib/test/test_unicodedata.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_unicodedata.py (original) +++ python/branches/release26-maint/Lib/test/test_unicodedata.py Sun Apr 26 21:12:55 2009 @@ -270,7 +270,7 @@ [0] ) - def test_buf_4971(self): + def test_bug_4971(self): # LETTER DZ WITH CARON: DZ, Dz, dz self.assertEqual(u"\u01c4".title(), u"\u01c5") self.assertEqual(u"\u01c5".title(), u"\u01c5") From python-checkins at python.org Sun Apr 26 21:16:11 2009 From: python-checkins at python.org (walter.doerwald) Date: Sun, 26 Apr 2009 21:16:11 +0200 (CEST) Subject: [Python-checkins] r71974 - in python/branches/py3k: Lib/test/test_unicodedata.py Message-ID: <20090426191611.A9C401E4002@bag.python.org> Author: walter.doerwald Date: Sun Apr 26 21:16:11 2009 New Revision: 71974 Log: Merged revisions 71972 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71972 | walter.doerwald | 2009-04-26 21:11:43 +0200 (So, 26 Apr 2009) | 2 lines Fix typo. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_unicodedata.py Modified: python/branches/py3k/Lib/test/test_unicodedata.py ============================================================================== --- python/branches/py3k/Lib/test/test_unicodedata.py (original) +++ python/branches/py3k/Lib/test/test_unicodedata.py Sun Apr 26 21:16:11 2009 @@ -271,7 +271,7 @@ [0] ) - def test_buf_4971(self): + def test_bug_4971(self): # LETTER DZ WITH CARON: DZ, Dz, dz self.assertEqual("\u01c4".title(), "\u01c5") self.assertEqual("\u01c5".title(), "\u01c5") From python-checkins at python.org Sun Apr 26 21:20:30 2009 From: python-checkins at python.org (walter.doerwald) Date: Sun, 26 Apr 2009 21:20:30 +0200 (CEST) Subject: [Python-checkins] r71975 - in python/branches/release30-maint: Lib/test/test_unicodedata.py Message-ID: <20090426192030.08F131E4010@bag.python.org> Author: walter.doerwald Date: Sun Apr 26 21:20:29 2009 New Revision: 71975 Log: Merged revisions 71974 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71974 | walter.doerwald | 2009-04-26 21:16:11 +0200 (So, 26 Apr 2009) | 9 lines Merged revisions 71972 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71972 | walter.doerwald | 2009-04-26 21:11:43 +0200 (So, 26 Apr 2009) | 2 lines Fix typo. ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Lib/test/test_unicodedata.py Modified: python/branches/release30-maint/Lib/test/test_unicodedata.py ============================================================================== --- python/branches/release30-maint/Lib/test/test_unicodedata.py (original) +++ python/branches/release30-maint/Lib/test/test_unicodedata.py Sun Apr 26 21:20:29 2009 @@ -271,7 +271,7 @@ [0] ) - def test_buf_4971(self): + def test_bug_4971(self): # LETTER DZ WITH CARON: DZ, Dz, dz self.assertEqual("\u01c4".title(), "\u01c5") self.assertEqual("\u01c5".title(), "\u01c5") From buildbot at python.org Sun Apr 26 21:35:02 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 26 Apr 2009 19:35:02 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu trunk Message-ID: <20090426193502.AC25E1E4002@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%20trunk/builds/1193 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: walter.doerwald BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_os test_time make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sun Apr 26 21:54:55 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 26 Apr 2009 21:54:55 +0200 (CEST) Subject: [Python-checkins] r71976 - python/trunk/Python/pystrtod.c Message-ID: <20090426195455.75C921E4002@bag.python.org> Author: mark.dickinson Date: Sun Apr 26 21:54:55 2009 New Revision: 71976 Log: Fix typo in function name Modified: python/trunk/Python/pystrtod.c Modified: python/trunk/Python/pystrtod.c ============================================================================== --- python/trunk/Python/pystrtod.c (original) +++ python/trunk/Python/pystrtod.c Sun Apr 26 21:54:55 2009 @@ -291,7 +291,7 @@ /* Ensure that any exponent, if present, is at least MIN_EXPONENT_DIGITS in length. */ Py_LOCAL_INLINE(void) -ensure_minumim_exponent_length(char* buffer, size_t buf_size) +ensure_minimum_exponent_length(char* buffer, size_t buf_size) { char *p = strpbrk(buffer, "eE"); if (p && (*(p + 1) == '-' || *(p + 1) == '+')) { @@ -498,7 +498,7 @@ for the extra zeros. Also, if there are more than MIN_EXPONENT_DIGITS, remove as many zeros as possible until we get back to MIN_EXPONENT_DIGITS */ - ensure_minumim_exponent_length(buffer, buf_size); + ensure_minimum_exponent_length(buffer, buf_size); /* If format_char is 'Z', make sure we have at least one character after the decimal point (and make sure we have a decimal point). */ @@ -601,7 +601,7 @@ enough for the extra zeros. Also, if there are more than MIN_EXPONENT_DIGITS, remove as many zeros as possible until we get back to MIN_EXPONENT_DIGITS */ - ensure_minumim_exponent_length(buf, buf_len); + ensure_minimum_exponent_length(buf, buf_len); /* Possibly make sure we have at least one character after the decimal point (and make sure we have a decimal point). */ From python-checkins at python.org Sun Apr 26 21:59:00 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 26 Apr 2009 21:59:00 +0200 (CEST) Subject: [Python-checkins] r71977 - in python/branches/release26-maint: Python/pystrtod.c Message-ID: <20090426195900.827631E4002@bag.python.org> Author: mark.dickinson Date: Sun Apr 26 21:59:00 2009 New Revision: 71977 Log: Merged revisions 71976 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71976 | mark.dickinson | 2009-04-26 20:54:55 +0100 (Sun, 26 Apr 2009) | 2 lines Fix typo in function name ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Python/pystrtod.c Modified: python/branches/release26-maint/Python/pystrtod.c ============================================================================== --- python/branches/release26-maint/Python/pystrtod.c (original) +++ python/branches/release26-maint/Python/pystrtod.c Sun Apr 26 21:59:00 2009 @@ -229,7 +229,7 @@ /* Ensure that any exponent, if present, is at least MIN_EXPONENT_DIGITS in length. */ Py_LOCAL_INLINE(void) -ensure_minumim_exponent_length(char* buffer, size_t buf_size) +ensure_minimum_exponent_length(char* buffer, size_t buf_size) { char *p = strpbrk(buffer, "eE"); if (p && (*(p + 1) == '-' || *(p + 1) == '+')) { @@ -468,7 +468,7 @@ for the extra zeros. Also, if there are more than MIN_EXPONENT_DIGITS, remove as many zeros as possible until we get back to MIN_EXPONENT_DIGITS */ - ensure_minumim_exponent_length(buffer, buf_size); + ensure_minimum_exponent_length(buffer, buf_size); /* If format_char is 'Z', make sure we have at least one character after the decimal point (and make sure we have a decimal point). */ From python-checkins at python.org Sun Apr 26 22:02:25 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 26 Apr 2009 22:02:25 +0200 (CEST) Subject: [Python-checkins] r71978 - in python/branches/py3k: Python/pystrtod.c Message-ID: <20090426200225.925131E4002@bag.python.org> Author: mark.dickinson Date: Sun Apr 26 22:02:24 2009 New Revision: 71978 Log: Merged revisions 71976 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71976 | mark.dickinson | 2009-04-26 20:54:55 +0100 (Sun, 26 Apr 2009) | 2 lines Fix typo in function name ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Python/pystrtod.c Modified: python/branches/py3k/Python/pystrtod.c ============================================================================== --- python/branches/py3k/Python/pystrtod.c (original) +++ python/branches/py3k/Python/pystrtod.c Sun Apr 26 22:02:24 2009 @@ -297,7 +297,7 @@ /* Ensure that any exponent, if present, is at least MIN_EXPONENT_DIGITS in length. */ Py_LOCAL_INLINE(void) -ensure_minumim_exponent_length(char* buffer, size_t buf_size) +ensure_minimum_exponent_length(char* buffer, size_t buf_size) { char *p = strpbrk(buffer, "eE"); if (p && (*(p + 1) == '-' || *(p + 1) == '+')) { @@ -498,7 +498,7 @@ for the extra zeros. Also, if there are more than MIN_EXPONENT_DIGITS, remove as many zeros as possible until we get back to MIN_EXPONENT_DIGITS */ - ensure_minumim_exponent_length(buffer, buf_size); + ensure_minimum_exponent_length(buffer, buf_size); /* If format_char is 'Z', make sure we have at least one character after the decimal point (and make sure we have a decimal point). */ From python-checkins at python.org Sun Apr 26 22:10:50 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sun, 26 Apr 2009 22:10:50 +0200 (CEST) Subject: [Python-checkins] r71979 - python/branches/py3k/Doc/tutorial/floatingpoint.rst Message-ID: <20090426201050.F2F7C1E4061@bag.python.org> Author: raymond.hettinger Date: Sun Apr 26 22:10:50 2009 New Revision: 71979 Log: Remove the round() discussion which is now out-of-date. Modified: python/branches/py3k/Doc/tutorial/floatingpoint.rst Modified: python/branches/py3k/Doc/tutorial/floatingpoint.rst ============================================================================== --- python/branches/py3k/Doc/tutorial/floatingpoint.rst (original) +++ python/branches/py3k/Doc/tutorial/floatingpoint.rst Sun Apr 26 22:10:50 2009 @@ -108,23 +108,8 @@ It's important to realize that this is, in a real sense, an illusion: you're simply rounding the *display* of the true machine value. -Other surprises follow from this one. For example, after seeing :: - - >>> format(0.1, '.17g') - '0.10000000000000001' - -you may be tempted to use the :func:`round` function to chop it back to the -single digit you expect. But that makes no difference:: - - >>> format(round(0.1, 1), '.17g') - '0.10000000000000001' - -The problem is that the binary floating-point value stored for "0.1" was already -the best possible binary approximation to 1/10, so trying to round it again -can't make it better: it was already as good as it gets. - -Another consequence is that since 0.1 is not exactly 1/10, summing ten values of -0.1 may not yield exactly 1.0, either:: +One illusion may beget another. For example, since 0.1 is not exactly 1/10, +summing ten values of 0.1 may not yield exactly 1.0, either:: >>> sum = 0.0 >>> for i in range(10): From python-checkins at python.org Sun Apr 26 22:11:23 2009 From: python-checkins at python.org (mark.dickinson) Date: Sun, 26 Apr 2009 22:11:23 +0200 (CEST) Subject: [Python-checkins] r71980 - in python/branches/release30-maint: Python/pystrtod.c Message-ID: <20090426201123.1865A1E4002@bag.python.org> Author: mark.dickinson Date: Sun Apr 26 22:11:22 2009 New Revision: 71980 Log: Merged revisions 71978 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71978 | mark.dickinson | 2009-04-26 21:02:24 +0100 (Sun, 26 Apr 2009) | 9 lines Merged revisions 71976 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71976 | mark.dickinson | 2009-04-26 20:54:55 +0100 (Sun, 26 Apr 2009) | 2 lines Fix typo in function name ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Python/pystrtod.c Modified: python/branches/release30-maint/Python/pystrtod.c ============================================================================== --- python/branches/release30-maint/Python/pystrtod.c (original) +++ python/branches/release30-maint/Python/pystrtod.c Sun Apr 26 22:11:22 2009 @@ -229,7 +229,7 @@ /* Ensure that any exponent, if present, is at least MIN_EXPONENT_DIGITS in length. */ Py_LOCAL_INLINE(void) -ensure_minumim_exponent_length(char* buffer, size_t buf_size) +ensure_minimum_exponent_length(char* buffer, size_t buf_size) { char *p = strpbrk(buffer, "eE"); if (p && (*(p + 1) == '-' || *(p + 1) == '+')) { @@ -468,7 +468,7 @@ for the extra zeros. Also, if there are more than MIN_EXPONENT_DIGITS, remove as many zeros as possible until we get back to MIN_EXPONENT_DIGITS */ - ensure_minumim_exponent_length(buffer, buf_size); + ensure_minimum_exponent_length(buffer, buf_size); /* If format_char is 'Z', make sure we have at least one character after the decimal point (and make sure we have a decimal point). */ From python-checkins at python.org Sun Apr 26 22:21:12 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sun, 26 Apr 2009 22:21:12 +0200 (CEST) Subject: [Python-checkins] r71981 - in python/branches/py3k: Doc/c-api/structures.rst Message-ID: <20090426202112.D2E6B1E4002@bag.python.org> Author: jeroen.ruigrok Date: Sun Apr 26 22:21:12 2009 New Revision: 71981 Log: Merged revisions 71873 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71873 | jeroen.ruigrok | 2009-04-25 13:15:06 +0200 (za, 25 apr 2009) | 2 lines Reformat prior to expanding. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/structures.rst Modified: python/branches/py3k/Doc/c-api/structures.rst ============================================================================== --- python/branches/py3k/Doc/c-api/structures.rst (original) +++ python/branches/py3k/Doc/c-api/structures.rst Sun Apr 26 22:21:12 2009 @@ -9,28 +9,29 @@ object types for Python. This section describes these structures and how they are used. -All Python objects ultimately share a small number of fields at the beginning of -the object's representation in memory. These are represented by the -:ctype:`PyObject` and :ctype:`PyVarObject` types, which are defined, in turn, by -the expansions of some macros also used, whether directly or indirectly, in the -definition of all other Python objects. +All Python objects ultimately share a small number of fields at the beginning +of the object's representation in memory. These are represented by the +:ctype:`PyObject` and :ctype:`PyVarObject` types, which are defined, in turn, +by the expansions of some macros also used, whether directly or indirectly, in +the definition of all other Python objects. .. ctype:: PyObject - All object types are extensions of this type. This is a type which contains the - information Python needs to treat a pointer to an object as an object. In a - normal "release" build, it contains only the object's reference count and a - pointer to the corresponding type object. It corresponds to the fields defined - by the expansion of the ``PyObject_HEAD`` macro. + All object types are extensions of this type. This is a type which + contains the information Python needs to treat a pointer to an object as an + object. In a normal "release" build, it contains only the object's + reference count and a pointer to the corresponding type object. It + corresponds to the fields defined by the expansion of the ``PyObject_HEAD`` + macro. .. ctype:: PyVarObject - This is an extension of :ctype:`PyObject` that adds the :attr:`ob_size` field. - This is only used for objects that have some notion of *length*. This type does - not often appear in the Python/C API. It corresponds to the fields defined by - the expansion of the ``PyObject_VAR_HEAD`` macro. + This is an extension of :ctype:`PyObject` that adds the :attr:`ob_size` + field. This is only used for objects that have some notion of *length*. + This type does not often appear in the Python/C API. It corresponds to the + fields defined by the expansion of the ``PyObject_VAR_HEAD`` macro. These macros are used in the definition of :ctype:`PyObject` and :ctype:`PyVarObject`: @@ -41,9 +42,9 @@ This is a macro which expands to the declarations of the fields of the :ctype:`PyObject` type; it is used when declaring new types which represent - objects without a varying length. The specific fields it expands to depend on - the definition of :cmacro:`Py_TRACE_REFS`. By default, that macro is not - defined, and :cmacro:`PyObject_HEAD` expands to:: + objects without a varying length. The specific fields it expands to depend + on the definition of :cmacro:`Py_TRACE_REFS`. By default, that macro is + not defined, and :cmacro:`PyObject_HEAD` expands to:: Py_ssize_t ob_refcnt; PyTypeObject *ob_type; @@ -58,9 +59,9 @@ .. cmacro:: PyObject_VAR_HEAD This is a macro which expands to the declarations of the fields of the - :ctype:`PyVarObject` type; it is used when declaring new types which represent - objects with a length that varies from instance to instance. This macro always - expands to:: + :ctype:`PyVarObject` type; it is used when declaring new types which + represent objects with a length that varies from instance to instance. + This macro always expands to:: PyObject_HEAD Py_ssize_t ob_size; @@ -73,11 +74,12 @@ .. ctype:: PyCFunction - Type of the functions used to implement most Python callables in C. Functions of - this type take two :ctype:`PyObject\*` parameters and return one such value. If - the return value is *NULL*, an exception shall have been set. If not *NULL*, - the return value is interpreted as the return value of the function as exposed - in Python. The function must return a new reference. + Type of the functions used to implement most Python callables in C. + Functions of this type take two :ctype:`PyObject\*` parameters and return + one such value. If the return value is *NULL*, an exception shall have + been set. If not *NULL*, the return value is interpreted as the return + value of the function as exposed in Python. The function must return a new + reference. .. ctype:: PyCFunctionWithKeywords @@ -126,20 +128,21 @@ .. data:: METH_VARARGS This is the typical calling convention, where the methods have the type - :ctype:`PyCFunction`. The function expects two :ctype:`PyObject\*` values. The - first one is the *self* object for methods; for module functions, it has the - value given to :cfunc:`Py_InitModule4` (or *NULL* if :cfunc:`Py_InitModule` was - used). The second parameter (often called *args*) is a tuple object - representing all arguments. This parameter is typically processed using - :cfunc:`PyArg_ParseTuple` or :cfunc:`PyArg_UnpackTuple`. + :ctype:`PyCFunction`. The function expects two :ctype:`PyObject\*` values. + The first one is the *self* object for methods; for module functions, it + has the value given to :cfunc:`Py_InitModule4` (or *NULL* if + :cfunc:`Py_InitModule` was used). The second parameter (often called + *args*) is a tuple object representing all arguments. This parameter is + typically processed using :cfunc:`PyArg_ParseTuple` or + :cfunc:`PyArg_UnpackTuple`. .. data:: METH_KEYWORDS - Methods with these flags must be of type :ctype:`PyCFunctionWithKeywords`. The - function expects three parameters: *self*, *args*, and a dictionary of all the - keyword arguments. The flag is typically combined with :const:`METH_VARARGS`, - and the parameters are typically processed using + Methods with these flags must be of type :ctype:`PyCFunctionWithKeywords`. + The function expects three parameters: *self*, *args*, and a dictionary of + all the keyword arguments. The flag is typically combined with + :const:`METH_VARARGS`, and the parameters are typically processed using :cfunc:`PyArg_ParseTupleAndKeywords`. @@ -148,8 +151,8 @@ Methods without parameters don't need to check whether arguments are given if they are listed with the :const:`METH_NOARGS` flag. They need to be of type :ctype:`PyCFunction`. When used with object methods, the first parameter is - typically named ``self`` and will hold a reference to the object instance. In - all cases the second parameter will be *NULL*. + typically named ``self`` and will hold a reference to the object instance. + In all cases the second parameter will be *NULL*. .. data:: METH_O @@ -170,18 +173,19 @@ .. index:: builtin: classmethod - The method will be passed the type object as the first parameter rather than an - instance of the type. This is used to create *class methods*, similar to what - is created when using the :func:`classmethod` built-in function. + The method will be passed the type object as the first parameter rather + than an instance of the type. This is used to create *class methods*, + similar to what is created when using the :func:`classmethod` built-in + function. .. data:: METH_STATIC .. index:: builtin: staticmethod - The method will be passed *NULL* as the first parameter rather than an instance - of the type. This is used to create *static methods*, similar to what is - created when using the :func:`staticmethod` built-in function. + The method will be passed *NULL* as the first parameter rather than an + instance of the type. This is used to create *static methods*, similar to + what is created when using the :func:`staticmethod` built-in function. One other constant controls whether a method is loaded in place of another definition with the same method name. @@ -191,12 +195,13 @@ The method will be loaded in place of existing definitions. Without *METH_COEXIST*, the default is to skip repeated definitions. Since slot - wrappers are loaded before the method table, the existence of a *sq_contains* - slot, for example, would generate a wrapped method named :meth:`__contains__` - and preclude the loading of a corresponding PyCFunction with the same name. - With the flag defined, the PyCFunction will be loaded in place of the wrapper - object and will co-exist with the slot. This is helpful because calls to - PyCFunctions are optimized more than wrapper object calls. + wrappers are loaded before the method table, the existence of a + *sq_contains* slot, for example, would generate a wrapped method named + :meth:`__contains__` and preclude the loading of a corresponding + PyCFunction with the same name. With the flag defined, the PyCFunction + will be loaded in place of the wrapper object and will co-exist with the + slot. This is helpful because calls to PyCFunctions are optimized more + than wrapper object calls. .. ctype:: PyMemberDef From python-checkins at python.org Sun Apr 26 22:24:01 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sun, 26 Apr 2009 22:24:01 +0200 (CEST) Subject: [Python-checkins] r71982 - tracker/instances/python-dev/detectors/statusauditor.py Message-ID: <20090426202401.EEEAF1E4002@bag.python.org> Author: martin.v.loewis Date: Sun Apr 26 22:24:01 2009 New Revision: 71982 Log: Issue #256: Refuse to close an issue if there are open dependencies. Modified: tracker/instances/python-dev/detectors/statusauditor.py Modified: tracker/instances/python-dev/detectors/statusauditor.py ============================================================================== --- tracker/instances/python-dev/detectors/statusauditor.py (original) +++ tracker/instances/python-dev/detectors/statusauditor.py Sun Apr 26 22:24:01 2009 @@ -17,7 +17,12 @@ dependencies = cl.get(nodeid, 'dependencies') dependencies = newvalues.get('dependencies', dependencies) - # don't do anything if there's no blockers or the status hasn't + # Check which dependencies are still open + closed = db.status.lookup('closed') + dep = [nid for nid in dependencies if cl.get(nid,'status') != closed] + dependencies = dep + + # don't do anything if there's no open blockers or the status hasn't # changed if not dependencies or not newvalues.has_key('status'): return @@ -31,7 +36,7 @@ s = 'issues %s are'%s # ok, see if we're trying to resolve - if newvalues.get('status') and newvalues['status'] == db.status.lookup('closed'): + if newvalues.get('status') and newvalues['status'] == closed: raise ValueError, "This issue can't be closed until %s closed."%s @@ -88,7 +93,7 @@ # fire before changes are made db.issue.audit('create', init_status) # db.issue.audit('create', block_resolution) -# db.issue.audit('set', block_resolution) + db.issue.audit('set', block_resolution) # db.issue.audit('set', resolve) # adjust after changes are committed From python-checkins at python.org Sun Apr 26 22:25:45 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sun, 26 Apr 2009 22:25:45 +0200 (CEST) Subject: [Python-checkins] r71983 - in python/branches/py3k: Doc/c-api/init.rst Doc/c-api/structures.rst Doc/includes/email-alternative.py Doc/includes/email-dir.py Doc/includes/email-mime.py Doc/includes/email-simple.py Message-ID: <20090426202545.B58F21E4002@bag.python.org> Author: jeroen.ruigrok Date: Sun Apr 26 22:25:45 2009 New Revision: 71983 Log: Merged revisions 71874,71882,71890 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71874 | jeroen.ruigrok | 2009-04-25 13:59:09 +0200 (za, 25 apr 2009) | 2 lines First attempt to document PyObject_HEAD_INIT and PyVarObject_HEAD_INIT. ........ r71882 | jeroen.ruigrok | 2009-04-25 14:49:10 +0200 (za, 25 apr 2009) | 3 lines Issue #4239: adjust email examples not to use connect() and terminate with quit() and not close(). ........ r71890 | jeroen.ruigrok | 2009-04-25 15:07:40 +0200 (za, 25 apr 2009) | 3 lines Rewrite a sentence to be more in line with the rest of the documentation with regard to person and audience. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/init.rst python/branches/py3k/Doc/c-api/structures.rst python/branches/py3k/Doc/includes/email-alternative.py python/branches/py3k/Doc/includes/email-dir.py python/branches/py3k/Doc/includes/email-mime.py python/branches/py3k/Doc/includes/email-simple.py 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 Sun Apr 26 22:25:45 2009 @@ -489,13 +489,13 @@ global variable). Conversely, when acquiring the lock and restoring the thread state, the lock must be acquired before storing the thread state pointer. -Why am I going on with so much detail about this? Because when threads are -created from C, they don't have the global interpreter lock, nor is there a -thread state data structure for them. Such threads must bootstrap themselves -into existence, by first creating a thread state data structure, then acquiring -the lock, and finally storing their thread state pointer, before they can start -using the Python/C API. When they are done, they should reset the thread state -pointer, release the lock, and finally free their thread state data structure. +It is important to note that when threads are created from C, they don't have +the global interpreter lock, nor is there a thread state data structure for +them. Such threads must bootstrap themselves into existence, by first +creating a thread state data structure, then acquiring the lock, and finally +storing their thread state pointer, before they can start using the Python/C +API. When they are done, they should reset the thread state pointer, release +the lock, and finally free their thread state data structure. Threads can take advantage of the :cfunc:`PyGILState_\*` functions to do all of the above automatically. The typical idiom for calling into Python from a C Modified: python/branches/py3k/Doc/c-api/structures.rst ============================================================================== --- python/branches/py3k/Doc/c-api/structures.rst (original) +++ python/branches/py3k/Doc/c-api/structures.rst Sun Apr 26 22:25:45 2009 @@ -69,7 +69,24 @@ Note that :cmacro:`PyObject_HEAD` is part of the expansion, and that its own expansion varies depending on the definition of :cmacro:`Py_TRACE_REFS`. -.. cmacro:: PyObject_HEAD_INIT + +.. cmacro:: PyObject_HEAD_INIT(type) + + This is a macro which expands to initialization values for a new + :ctype:`PyObject` type. This macro expands to:: + + _PyObject_EXTRA_INIT + 1, type, + + +.. cmacro:: PyVarObject_HEAD_INIT(type, size) + + This is a macro which expands to initialization values for a new + :ctype:`PyVarObject` type, including the :attr:`ob_size` field. + This macro expands to:: + + _PyObject_EXTRA_INIT + 1, type, size, .. ctype:: PyCFunction Modified: python/branches/py3k/Doc/includes/email-alternative.py ============================================================================== --- python/branches/py3k/Doc/includes/email-alternative.py (original) +++ python/branches/py3k/Doc/includes/email-alternative.py Sun Apr 26 22:25:45 2009 @@ -45,4 +45,4 @@ # sendmail function takes 3 arguments: sender's address, recipient's address # and message to send - here it is sent as one string. s.sendmail(me, you, msg.as_string()) -s.close() +s.quit() Modified: python/branches/py3k/Doc/includes/email-dir.py ============================================================================== --- python/branches/py3k/Doc/includes/email-dir.py (original) +++ python/branches/py3k/Doc/includes/email-dir.py Sun Apr 26 22:25:45 2009 @@ -106,9 +106,8 @@ fp.close() else: s = smtplib.SMTP() - s.connect() s.sendmail(opts.sender, opts.recipients, composed) - s.close() + s.quit() if __name__ == '__main__': Modified: python/branches/py3k/Doc/includes/email-mime.py ============================================================================== --- python/branches/py3k/Doc/includes/email-mime.py (original) +++ python/branches/py3k/Doc/includes/email-mime.py Sun Apr 26 22:25:45 2009 @@ -27,6 +27,5 @@ # Send the email via our own SMTP server. s = smtplib.SMTP() -s.connect() s.sendmail(me, family, msg.as_string()) -s.close() +s.quit() Modified: python/branches/py3k/Doc/includes/email-simple.py ============================================================================== --- python/branches/py3k/Doc/includes/email-simple.py (original) +++ python/branches/py3k/Doc/includes/email-simple.py Sun Apr 26 22:25:45 2009 @@ -20,6 +20,5 @@ # Send the message via our own SMTP server, but don't include the # envelope header. s = smtplib.SMTP() -s.connect() s.sendmail(me, [you], msg.as_string()) -s.close() +s.quit() From buildbot at python.org Sun Apr 26 22:37:14 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 26 Apr 2009 20:37:14 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 2.6 Message-ID: <20090426203715.06B691E4002@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%202.6/builds/260 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: walter.doerwald BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From buildbot at python.org Sun Apr 26 22:46:14 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 26 Apr 2009 20:46:14 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090426204614.3E3E61E4002@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/304 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_distutils test_posix ====================================================================== FAIL: test_get_python_inc (distutils.tests.test_sysconfig.SysconfigTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/distutils/tests/test_sysconfig.py", line 45, in test_get_python_inc self.assert_(os.path.isdir(inc_dir), inc_dir) AssertionError: /home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/Include ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Sun Apr 26 22:51:44 2009 From: python-checkins at python.org (walter.doerwald) Date: Sun, 26 Apr 2009 22:51:44 +0200 (CEST) Subject: [Python-checkins] r71984 - in python/trunk/Lib/test: test_optparse.py test_posixpath.py test_site.py test_tempfile.py test_urllib.py test_xmlrpc.py Message-ID: <20090426205144.865BA1E4002@bag.python.org> Author: walter.doerwald Date: Sun Apr 26 22:51:44 2009 New Revision: 71984 Log: Use test.test_support.EnvironmentVarGuard where tests change environment vars. Modified: python/trunk/Lib/test/test_optparse.py python/trunk/Lib/test/test_posixpath.py python/trunk/Lib/test/test_site.py python/trunk/Lib/test/test_tempfile.py python/trunk/Lib/test/test_urllib.py python/trunk/Lib/test/test_xmlrpc.py Modified: python/trunk/Lib/test/test_optparse.py ============================================================================== --- python/trunk/Lib/test/test_optparse.py (original) +++ python/trunk/Lib/test/test_optparse.py Sun Apr 26 22:51:44 2009 @@ -1464,15 +1464,9 @@ # we must restore its original value -- otherwise, this test # screws things up for other tests when it's part of the Python # test suite. - orig_columns = os.environ.get('COLUMNS') - os.environ['COLUMNS'] = str(columns) - try: + with test_support.EnvironmentVarGuard() as env: + env.set('COLUMNS', str(columns)) return InterceptingOptionParser(option_list=options) - finally: - if orig_columns is None: - del os.environ['COLUMNS'] - else: - os.environ['COLUMNS'] = orig_columns def assertHelpEquals(self, expected_output): if type(expected_output) is types.UnicodeType: @@ -1499,16 +1493,10 @@ self.assertHelpEquals(_expected_help_long_opts_first) def test_help_title_formatter(self): - save = os.environ.get("COLUMNS") - try: - os.environ["COLUMNS"] = "80" + with test_support.EnvironmentVarGuard() as env: + env.set("COLUMNS", "80") self.parser.formatter = TitledHelpFormatter() self.assertHelpEquals(_expected_help_title_formatter) - finally: - if save is not None: - os.environ["COLUMNS"] = save - else: - del os.environ["COLUMNS"] def test_wrap_columns(self): # Ensure that wrapping respects $COLUMNS environment variable. Modified: python/trunk/Lib/test/test_posixpath.py ============================================================================== --- python/trunk/Lib/test/test_posixpath.py (original) +++ python/trunk/Lib/test/test_posixpath.py Sun Apr 26 22:51:44 2009 @@ -345,10 +345,9 @@ self.assert_(isinstance(posixpath.expanduser("~root/"), basestring)) self.assert_(isinstance(posixpath.expanduser("~foo/"), basestring)) - orig_home = os.environ['HOME'] - os.environ['HOME'] = '/' - self.assertEqual(posixpath.expanduser("~"), "/") - os.environ['HOME'] = orig_home + with test_support.EnvironmentVarGuard() as env: + env.set('HOME', '/') + self.assertEqual(posixpath.expanduser("~"), "/") self.assertRaises(TypeError, posixpath.expanduser) Modified: python/trunk/Lib/test/test_site.py ============================================================================== --- python/trunk/Lib/test/test_site.py (original) +++ python/trunk/Lib/test/test_site.py Sun Apr 26 22:51:44 2009 @@ -5,7 +5,7 @@ """ import unittest -from test.test_support import run_unittest, TESTFN +from test.test_support import run_unittest, TESTFN, EnvironmentVarGuard import __builtin__ import os import sys Modified: python/trunk/Lib/test/test_tempfile.py ============================================================================== --- python/trunk/Lib/test/test_tempfile.py (original) +++ python/trunk/Lib/test/test_tempfile.py Sun Apr 26 22:51:44 2009 @@ -149,13 +149,11 @@ # _candidate_tempdir_list contains the expected directories # Make sure the interesting environment variables are all set. - added = [] - try: + with test_support.EnvironmentVarGuard() as env: for envname in 'TMPDIR', 'TEMP', 'TMP': dirname = os.getenv(envname) if not dirname: - os.environ[envname] = os.path.abspath(envname) - added.append(envname) + env.set(envname, os.path.abspath(envname)) cand = tempfile._candidate_tempdir_list() @@ -173,9 +171,6 @@ # Not practical to try to verify the presence of OS-specific # paths in this list. - finally: - for p in added: - del os.environ[p] test_classes.append(test__candidate_tempdir_list) Modified: python/trunk/Lib/test/test_urllib.py ============================================================================== --- python/trunk/Lib/test/test_urllib.py (original) +++ python/trunk/Lib/test/test_urllib.py Sun Apr 26 22:51:44 2009 @@ -98,20 +98,20 @@ class ProxyTests(unittest.TestCase): def setUp(self): - # Save all proxy related env vars - self._saved_environ = dict([(k, v) for k, v in os.environ.iteritems() - if k.lower().find('proxy') >= 0]) + # Records changes to env vars + self.env = test_support.EnvironmentVarGuard() # Delete all proxy related env vars - for k in self._saved_environ: - del os.environ[k] + for k, v in os.environ.iteritems(): + if 'proxy' in k.lower(): + env.unset(k) def tearDown(self): # Restore all proxy related env vars - for k, v in self._saved_environ.iteritems(): - os.environ[k] = v + self.env.__exit__() + del self.env def test_getproxies_environment_keep_no_proxies(self): - os.environ['NO_PROXY'] = 'localhost' + self.env.set('NO_PROXY', 'localhost') proxies = urllib.getproxies_environment() # getproxies_environment use lowered case truncated (no '_proxy') keys self.assertEquals('localhost', proxies['no']) Modified: python/trunk/Lib/test/test_xmlrpc.py ============================================================================== --- python/trunk/Lib/test/test_xmlrpc.py (original) +++ python/trunk/Lib/test/test_xmlrpc.py Sun Apr 26 22:51:44 2009 @@ -604,25 +604,25 @@ self.cgi = None def test_cgi_get(self): - os.environ['REQUEST_METHOD'] = 'GET' - # if the method is GET and no request_text is given, it runs handle_get - # get sysout output - tmp = sys.stdout - sys.stdout = open(test_support.TESTFN, "w") - self.cgi.handle_request() - sys.stdout.close() - sys.stdout = tmp + with test_support.EnvironmentVarGuard() as env: + env.set('REQUEST_METHOD', 'GET') + # if the method is GET and no request_text is given, it runs handle_get + # get sysout output + tmp = sys.stdout + sys.stdout = open(test_support.TESTFN, "w") + self.cgi.handle_request() + sys.stdout.close() + sys.stdout = tmp - # parse Status header - handle = open(test_support.TESTFN, "r").read() - status = handle.split()[1] - message = ' '.join(handle.split()[2:4]) + # parse Status header + handle = open(test_support.TESTFN, "r").read() + status = handle.split()[1] + message = ' '.join(handle.split()[2:4]) - self.assertEqual(status, '400') - self.assertEqual(message, 'Bad Request') + self.assertEqual(status, '400') + self.assertEqual(message, 'Bad Request') - os.remove(test_support.TESTFN) - os.environ['REQUEST_METHOD'] = '' + os.remove(test_support.TESTFN) def test_cgi_xmlrpc_response(self): data = """ @@ -645,11 +645,9 @@ sys.stdin = open("xmldata.txt", "r") sys.stdout = open(test_support.TESTFN, "w") - os.environ['CONTENT_LENGTH'] = str(len(data)) - try: + with test_support.EnvironmentVarGuard() as env: + env.set('CONTENT_LENGTH', str(len(data))) self.cgi.handle_request() - finally: - del os.environ['CONTENT_LENGTH'] sys.stdin.close() sys.stdout.close() From python-checkins at python.org Sun Apr 26 23:04:55 2009 From: python-checkins at python.org (walter.doerwald) Date: Sun, 26 Apr 2009 23:04:55 +0200 (CEST) Subject: [Python-checkins] r71985 - in python/branches/release26-maint: Lib/test/test_optparse.py Lib/test/test_posixpath.py Lib/test/test_site.py Lib/test/test_tempfile.py Lib/test/test_urllib.py Lib/test/test_xmlrpc.py Message-ID: <20090426210455.3E7F51E4002@bag.python.org> Author: walter.doerwald Date: Sun Apr 26 23:04:55 2009 New Revision: 71985 Log: Merged revisions 71984 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71984 | walter.doerwald | 2009-04-26 22:51:44 +0200 (So, 26 Apr 2009) | 2 lines Use test.test_support.EnvironmentVarGuard where tests change environment vars. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/test/test_optparse.py python/branches/release26-maint/Lib/test/test_posixpath.py python/branches/release26-maint/Lib/test/test_site.py python/branches/release26-maint/Lib/test/test_tempfile.py python/branches/release26-maint/Lib/test/test_urllib.py python/branches/release26-maint/Lib/test/test_xmlrpc.py Modified: python/branches/release26-maint/Lib/test/test_optparse.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_optparse.py (original) +++ python/branches/release26-maint/Lib/test/test_optparse.py Sun Apr 26 23:04:55 2009 @@ -1464,15 +1464,9 @@ # we must restore its original value -- otherwise, this test # screws things up for other tests when it's part of the Python # test suite. - orig_columns = os.environ.get('COLUMNS') - os.environ['COLUMNS'] = str(columns) - try: + with test_support.EnvironmentVarGuard() as env: + env.set('COLUMNS', str(columns)) return InterceptingOptionParser(option_list=options) - finally: - if orig_columns is None: - del os.environ['COLUMNS'] - else: - os.environ['COLUMNS'] = orig_columns def assertHelpEquals(self, expected_output): if type(expected_output) is types.UnicodeType: @@ -1499,16 +1493,10 @@ self.assertHelpEquals(_expected_help_long_opts_first) def test_help_title_formatter(self): - save = os.environ.get("COLUMNS") - try: - os.environ["COLUMNS"] = "80" + with test_support.EnvironmentVarGuard() as env: + env.set("COLUMNS", "80") self.parser.formatter = TitledHelpFormatter() self.assertHelpEquals(_expected_help_title_formatter) - finally: - if save is not None: - os.environ["COLUMNS"] = save - else: - del os.environ["COLUMNS"] def test_wrap_columns(self): # Ensure that wrapping respects $COLUMNS environment variable. Modified: python/branches/release26-maint/Lib/test/test_posixpath.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_posixpath.py (original) +++ python/branches/release26-maint/Lib/test/test_posixpath.py Sun Apr 26 23:04:55 2009 @@ -345,10 +345,9 @@ self.assert_(isinstance(posixpath.expanduser("~root/"), basestring)) self.assert_(isinstance(posixpath.expanduser("~foo/"), basestring)) - orig_home = os.environ['HOME'] - os.environ['HOME'] = '/' - self.assertEqual(posixpath.expanduser("~"), "/") - os.environ['HOME'] = orig_home + with test_support.EnvironmentVarGuard() as env: + env.set('HOME', '/') + self.assertEqual(posixpath.expanduser("~"), "/") self.assertRaises(TypeError, posixpath.expanduser) Modified: python/branches/release26-maint/Lib/test/test_site.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_site.py (original) +++ python/branches/release26-maint/Lib/test/test_site.py Sun Apr 26 23:04:55 2009 @@ -5,7 +5,7 @@ """ import unittest -from test.test_support import TestSkipped, run_unittest, TESTFN +from test.test_support import TestSkipped, run_unittest, TESTFN, EnvironmentVarGuard import __builtin__ import os import sys Modified: python/branches/release26-maint/Lib/test/test_tempfile.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_tempfile.py (original) +++ python/branches/release26-maint/Lib/test/test_tempfile.py Sun Apr 26 23:04:55 2009 @@ -149,13 +149,11 @@ # _candidate_tempdir_list contains the expected directories # Make sure the interesting environment variables are all set. - added = [] - try: + with test_support.EnvironmentVarGuard() as env: for envname in 'TMPDIR', 'TEMP', 'TMP': dirname = os.getenv(envname) if not dirname: - os.environ[envname] = os.path.abspath(envname) - added.append(envname) + env.set(envname, os.path.abspath(envname)) cand = tempfile._candidate_tempdir_list() @@ -173,9 +171,6 @@ # Not practical to try to verify the presence of OS-specific # paths in this list. - finally: - for p in added: - del os.environ[p] test_classes.append(test__candidate_tempdir_list) Modified: python/branches/release26-maint/Lib/test/test_urllib.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_urllib.py (original) +++ python/branches/release26-maint/Lib/test/test_urllib.py Sun Apr 26 23:04:55 2009 @@ -98,20 +98,20 @@ class ProxyTests(unittest.TestCase): def setUp(self): - # Save all proxy related env vars - self._saved_environ = dict([(k, v) for k, v in os.environ.iteritems() - if k.lower().find('proxy') >= 0]) + # Records changes to env vars + self.env = test_support.EnvironmentVarGuard() # Delete all proxy related env vars - for k in self._saved_environ: - del os.environ[k] + for k, v in os.environ.iteritems(): + if 'proxy' in k.lower(): + env.unset(k) def tearDown(self): # Restore all proxy related env vars - for k, v in self._saved_environ.iteritems(): - os.environ[k] = v + self.env.__exit__() + del self.env def test_getproxies_environment_keep_no_proxies(self): - os.environ['NO_PROXY'] = 'localhost' + self.env.set('NO_PROXY', 'localhost') proxies = urllib.getproxies_environment() # getproxies_environment use lowered case truncated (no '_proxy') keys self.assertEquals('localhost', proxies['no']) Modified: python/branches/release26-maint/Lib/test/test_xmlrpc.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_xmlrpc.py (original) +++ python/branches/release26-maint/Lib/test/test_xmlrpc.py Sun Apr 26 23:04:55 2009 @@ -583,25 +583,25 @@ self.cgi = None def test_cgi_get(self): - os.environ['REQUEST_METHOD'] = 'GET' - # if the method is GET and no request_text is given, it runs handle_get - # get sysout output - tmp = sys.stdout - sys.stdout = open(test_support.TESTFN, "w") - self.cgi.handle_request() - sys.stdout.close() - sys.stdout = tmp + with test_support.EnvironmentVarGuard() as env: + env.set('REQUEST_METHOD', 'GET') + # if the method is GET and no request_text is given, it runs handle_get + # get sysout output + tmp = sys.stdout + sys.stdout = open(test_support.TESTFN, "w") + self.cgi.handle_request() + sys.stdout.close() + sys.stdout = tmp - # parse Status header - handle = open(test_support.TESTFN, "r").read() - status = handle.split()[1] - message = ' '.join(handle.split()[2:4]) + # parse Status header + handle = open(test_support.TESTFN, "r").read() + status = handle.split()[1] + message = ' '.join(handle.split()[2:4]) - self.assertEqual(status, '400') - self.assertEqual(message, 'Bad Request') + self.assertEqual(status, '400') + self.assertEqual(message, 'Bad Request') - os.remove(test_support.TESTFN) - os.environ['REQUEST_METHOD'] = '' + os.remove(test_support.TESTFN) def test_cgi_xmlrpc_response(self): data = """ @@ -624,11 +624,9 @@ sys.stdin = open("xmldata.txt", "r") sys.stdout = open(test_support.TESTFN, "w") - os.environ['CONTENT_LENGTH'] = str(len(data)) - try: + with test_support.EnvironmentVarGuard() as env: + env.set('CONTENT_LENGTH', str(len(data))) self.cgi.handle_request() - finally: - del os.environ['CONTENT_LENGTH'] sys.stdin.close() sys.stdout.close() From buildbot at python.org Sun Apr 26 23:05:44 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 26 Apr 2009 21:05:44 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 3.0 Message-ID: <20090426210544.9D3611E4002@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%203.0/builds/326 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: walter.doerwald BUILD FAILED: failed test Excerpt from the test logfile: make: *** [buildbottest] Unknown signal 32 sincerely, -The Buildbot From python-checkins at python.org Sun Apr 26 23:06:15 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Sun, 26 Apr 2009 23:06:15 +0200 (CEST) Subject: [Python-checkins] r71986 - in python/branches/py3k: Doc/c-api/allocation.rst Doc/c-api/arg.rst Doc/c-api/buffer.rst Doc/c-api/dict.rst Doc/c-api/gcsupport.rst Doc/c-api/list.rst Doc/c-api/long.rst Doc/c-api/mapping.rst Doc/c-api/object.rst Doc/c-api/sequence.rst Doc/c-api/set.rst Doc/c-api/slice.rst Doc/c-api/tuple.rst Doc/c-api/type.rst Message-ID: <20090426210615.6B5C51E4002@bag.python.org> Author: jeroen.ruigrok Date: Sun Apr 26 23:06:15 2009 New Revision: 71986 Log: Merged revisions 71898-71900,71910,71914-71919 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71898 | jeroen.ruigrok | 2009-04-25 16:24:30 +0200 (za, 25 apr 2009) | 2 lines Reformat prior to editing. ........ r71899 | jeroen.ruigrok | 2009-04-25 16:27:00 +0200 (za, 25 apr 2009) | 3 lines The type for ppos has been Py_ssize_t since 2.5, reflect this in the documentation. ........ r71900 | jeroen.ruigrok | 2009-04-25 16:28:02 +0200 (za, 25 apr 2009) | 2 lines Reformat paragraph. ........ r71910 | jeroen.ruigrok | 2009-04-25 19:59:03 +0200 (za, 25 apr 2009) | 4 lines Issue #4129: Belatedly document which C API functions had their argument(s) or return type changed from int or int * to Py_ssize_t or Py_ssize_t * as this might cause problems on 64-bit platforms. ........ r71914 | jeroen.ruigrok | 2009-04-25 20:31:20 +0200 (za, 25 apr 2009) | 2 lines Reformat prior to editing. ........ r71915 | jeroen.ruigrok | 2009-04-25 20:46:03 +0200 (za, 25 apr 2009) | 2 lines Issue #4129: Document more int -> Py_ssize_t changes. ........ r71916 | jeroen.ruigrok | 2009-04-25 20:53:48 +0200 (za, 25 apr 2009) | 2 lines Reformat prior to editing. ........ r71917 | jeroen.ruigrok | 2009-04-25 20:57:32 +0200 (za, 25 apr 2009) | 2 lines Reference to an int type, whereas it's a Py_ssize_t as the synopsis states. ........ r71918 | jeroen.ruigrok | 2009-04-25 21:04:15 +0200 (za, 25 apr 2009) | 2 lines Since I edited this file, reformat for future edits. ........ r71919 | jeroen.ruigrok | 2009-04-25 21:10:52 +0200 (za, 25 apr 2009) | 2 lines Reformat prior to editing. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/allocation.rst python/branches/py3k/Doc/c-api/arg.rst python/branches/py3k/Doc/c-api/buffer.rst python/branches/py3k/Doc/c-api/dict.rst python/branches/py3k/Doc/c-api/gcsupport.rst python/branches/py3k/Doc/c-api/list.rst python/branches/py3k/Doc/c-api/long.rst python/branches/py3k/Doc/c-api/mapping.rst python/branches/py3k/Doc/c-api/object.rst python/branches/py3k/Doc/c-api/sequence.rst python/branches/py3k/Doc/c-api/set.rst python/branches/py3k/Doc/c-api/slice.rst python/branches/py3k/Doc/c-api/tuple.rst python/branches/py3k/Doc/c-api/type.rst Modified: python/branches/py3k/Doc/c-api/allocation.rst ============================================================================== --- python/branches/py3k/Doc/c-api/allocation.rst (original) +++ python/branches/py3k/Doc/c-api/allocation.rst Sun Apr 26 23:06:15 2009 @@ -11,13 +11,18 @@ .. cfunction:: PyVarObject* _PyObject_NewVar(PyTypeObject *type, Py_ssize_t size) + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyObject_Init(PyObject *op, PyTypeObject *type) - Initialize a newly-allocated object *op* with its type and initial reference. - Returns the initialized object. If *type* indicates that the object - participates in the cyclic garbage detector, it is added to the detector's set - of observed objects. Other fields of the object are not affected. + Initialize a newly-allocated object *op* with its type and initial + reference. Returns the initialized object. If *type* indicates that the + object participates in the cyclic garbage detector, it is added to the + detector's set of observed objects. Other fields of the object are not + affected. .. cfunction:: PyVarObject* PyObject_InitVar(PyVarObject *op, PyTypeObject *type, Py_ssize_t size) @@ -28,30 +33,32 @@ .. cfunction:: TYPE* PyObject_New(TYPE, PyTypeObject *type) - Allocate a new Python object using the C structure type *TYPE* and the Python - type object *type*. Fields not defined by the Python object header are not - initialized; the object's reference count will be one. The size of the memory - allocation is determined from the :attr:`tp_basicsize` field of the type object. + Allocate a new Python object using the C structure type *TYPE* and the + Python type object *type*. Fields not defined by the Python object header + are not initialized; the object's reference count will be one. The size of + the memory allocation is determined from the :attr:`tp_basicsize` field of + the type object. .. cfunction:: TYPE* PyObject_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size) - Allocate a new Python object using the C structure type *TYPE* and the Python - type object *type*. Fields not defined by the Python object header are not - initialized. The allocated memory allows for the *TYPE* structure plus *size* - fields of the size given by the :attr:`tp_itemsize` field of *type*. This is - useful for implementing objects like tuples, which are able to determine their - size at construction time. Embedding the array of fields into the same - allocation decreases the number of allocations, improving the memory management - efficiency. + Allocate a new Python object using the C structure type *TYPE* and the + Python type object *type*. Fields not defined by the Python object header + are not initialized. The allocated memory allows for the *TYPE* structure + plus *size* fields of the size given by the :attr:`tp_itemsize` field of + *type*. This is useful for implementing objects like tuples, which are + able to determine their size at construction time. Embedding the array of + fields into the same allocation decreases the number of allocations, + improving the memory management efficiency. .. cfunction:: void PyObject_Del(PyObject *op) Releases memory allocated to an object using :cfunc:`PyObject_New` or - :cfunc:`PyObject_NewVar`. This is normally called from the :attr:`tp_dealloc` - handler specified in the object's type. The fields of the object should not be - accessed after this call as the memory is no longer a valid Python object. + :cfunc:`PyObject_NewVar`. This is normally called from the + :attr:`tp_dealloc` handler specified in the object's type. The fields of + the object should not be accessed after this call as the memory is no + longer a valid Python object. .. cvar:: PyObject _Py_NoneStruct Modified: python/branches/py3k/Doc/c-api/arg.rst ============================================================================== --- python/branches/py3k/Doc/c-api/arg.rst (original) +++ python/branches/py3k/Doc/c-api/arg.rst Sun Apr 26 23:06:15 2009 @@ -278,10 +278,10 @@ ``w#`` (read-write character buffer) [char \*, int] Like ``s#``, but accepts any object which implements the read-write buffer - interface. The :ctype:`char \*` variable is set to point to the first byte of - the buffer, and the :ctype:`int` is set to the length of the buffer. Only - single-segment buffer objects are accepted; :exc:`TypeError` is raised for all - others. + interface. The :ctype:`char \*` variable is set to point to the first byte + of the buffer, and the :ctype:`int` is set to the length of the buffer. + Only single-segment buffer objects are accepted; :exc:`TypeError` is raised + for all others. ``(items)`` (tuple) [*matching-items*] The object must be a Python sequence whose length is the number of format units @@ -406,6 +406,10 @@ PyArg_ParseTuple(args, "O|O:ref", &object, &callback) + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *min* and *max*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* Py_BuildValue(const char *format, ...) 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 Apr 26 23:06:15 2009 @@ -15,8 +15,8 @@ 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. +format. Clients of the object can use the buffer interface to access the +object data directly, without needing to copy it first. Two examples of objects that support the buffer interface are bytes and arrays. The bytes object exposes the character contents in the buffer @@ -61,9 +61,9 @@ .. cmember:: const char *format :noindex: - A *NULL* terminated string in :mod:`struct` module style syntax giving the - contents of the elements available through the buffer. If this is *NULL*, - ``"B"`` (unsigned bytes) is assumed. + A *NULL* terminated string in :mod:`struct` module style syntax giving + the contents of the elements available through the buffer. If this is + *NULL*, ``"B"`` (unsigned bytes) is assumed. .. cmember:: int ndim @@ -113,11 +113,11 @@ .. cmember:: Py_ssize_t itemsize This is a storage for the itemsize (in bytes) of each element of the - shared memory. It is technically un-necessary as it can be obtained using - :cfunc:`PyBuffer_SizeFromFormat`, however an exporter may know this - information without parsing the format string and it is necessary to know - the itemsize for proper interpretation of striding. Therefore, storing it - is more convenient and faster. + shared memory. It is technically un-necessary as it can be obtained + using :cfunc:`PyBuffer_SizeFromFormat`, however an exporter may know + this information without parsing the format string and it is necessary + to know the itemsize for proper interpretation of striding. Therefore, + storing it is more convenient and faster. .. cmember:: void *internal @@ -140,20 +140,20 @@ .. cfunction:: int PyObject_GetBuffer(PyObject *obj, PyObject *view, int flags) Export *obj* into a :ctype:`Py_buffer`, *view*. These arguments must - never be *NULL*. The *flags* argument is a bit field indicating what kind - of buffer the caller is prepared to deal with and therefore what kind of - buffer the exporter is allowed to return. The buffer interface allows for - complicated memory sharing possibilities, but some caller may not be able - to handle all the complexibity but may want to see if the exporter will - let them take a simpler view to its memory. + never be *NULL*. The *flags* argument is a bit field indicating what + kind of buffer the caller is prepared to deal with and therefore what + kind of buffer the exporter is allowed to return. The buffer interface + allows for complicated memory sharing possibilities, but some caller may + not be able to handle all the complexibity but may want to see if the + exporter will let them take a simpler view to its memory. Some exporters may not be able to share memory in every possible way and may need to raise errors to signal to some consumers that something is just not possible. These errors should be a :exc:`BufferError` unless - there is another error that is actually causing the problem. The exporter - can use flags information to simplify how much of the :cdata:`Py_buffer` - structure is filled in with non-default values and/or raise an error if - the object can't support a simpler view of its memory. + there is another error that is actually causing the problem. The + exporter can use flags information to simplify how much of the + :cdata:`Py_buffer` structure is filled in with non-default values and/or + raise an error if the object can't support a simpler view of its memory. 0 is returned on success and -1 on error. @@ -264,16 +264,16 @@ .. cfunction:: int PyObject_CopyToObject(PyObject *obj, void *buf, Py_ssize_t len, char fortran) - Copy *len* bytes of data pointed to by the contiguous chunk of memory pointed - to by *buf* into the buffer exported by obj. The buffer must of course be - writable. Return 0 on success and return -1 and raise an error on failure. - If the object does not have a writable buffer, then an error is raised. If - *fortran* is ``'F'``, then if the object is multi-dimensional, then the data - will be copied into the array in Fortran-style (first dimension varies the - fastest). If *fortran* is ``'C'``, then the data will be copied into the - array in C-style (last dimension varies the fastest). If *fortran* is - ``'A'``, then it does not matter and the copy will be made in whatever way is - more efficient. + Copy *len* bytes of data pointed to by the contiguous chunk of memory + pointed to by *buf* into the buffer exported by obj. The buffer must of + course be writable. Return 0 on success and return -1 and raise an error + on failure. If the object does not have a writable buffer, then an error + is raised. If *fortran* is ``'F'``, then if the object is + multi-dimensional, then the data will be copied into the array in + Fortran-style (first dimension varies the fastest). If *fortran* is + ``'C'``, then the data will be copied into the array in C-style (last + dimension varies the fastest). If *fortran* is ``'A'``, then it does not + matter and the copy will be made in whatever way is more efficient. .. cfunction:: int PyBuffer_IsContiguous(Py_buffer *view, char fortran) Modified: python/branches/py3k/Doc/c-api/dict.rst ============================================================================== --- python/branches/py3k/Doc/c-api/dict.rst (original) +++ python/branches/py3k/Doc/c-api/dict.rst Sun Apr 26 23:06:15 2009 @@ -19,8 +19,9 @@ single: DictType (in module types) single: DictionaryType (in module types) - This instance of :ctype:`PyTypeObject` represents the Python dictionary type. - This is exposed to Python programs as ``dict`` and ``types.DictType``. + This instance of :ctype:`PyTypeObject` represents the Python dictionary + type. This is exposed to Python programs as ``dict`` and + ``types.DictType``. .. cfunction:: int PyDict_Check(PyObject *p) @@ -31,8 +32,8 @@ .. cfunction:: int PyDict_CheckExact(PyObject *p) - Return true if *p* is a dict object, but not an instance of a subtype of the - dict type. + Return true if *p* is a dict object, but not an instance of a subtype of + the dict type. .. cfunction:: PyObject* PyDict_New() @@ -42,9 +43,9 @@ .. cfunction:: PyObject* PyDictProxy_New(PyObject *dict) - Return a proxy object for a mapping which enforces read-only behavior. This is - normally used to create a proxy to prevent modification of the dictionary for - non-dynamic class types. + Return a proxy object for a mapping which enforces read-only behavior. + This is normally used to create a proxy to prevent modification of the + dictionary for non-dynamic class types. .. cfunction:: void PyDict_Clear(PyObject *p) @@ -54,9 +55,9 @@ .. cfunction:: int PyDict_Contains(PyObject *p, PyObject *key) - Determine if dictionary *p* contains *key*. If an item in *p* is matches *key*, - return ``1``, otherwise return ``0``. On error, return ``-1``. This is - equivalent to the Python expression ``key in p``. + Determine if dictionary *p* contains *key*. If an item in *p* is matches + *key*, return ``1``, otherwise return ``0``. On error, return ``-1``. + This is equivalent to the Python expression ``key in p``. .. cfunction:: PyObject* PyDict_Copy(PyObject *p) @@ -67,25 +68,25 @@ .. cfunction:: int PyDict_SetItem(PyObject *p, PyObject *key, PyObject *val) Insert *value* into the dictionary *p* with a key of *key*. *key* must be - :term:`hashable`; if it isn't, :exc:`TypeError` will be raised. Return ``0`` - on success or ``-1`` on failure. + :term:`hashable`; if it isn't, :exc:`TypeError` will be raised. Return + ``0`` on success or ``-1`` on failure. .. cfunction:: int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val) .. index:: single: PyUnicode_FromString() - Insert *value* into the dictionary *p* using *key* as a key. *key* should be - a :ctype:`char\*`. The key object is created using - :cfunc:`PyUnicode_FromString(key)`. Return ``0`` on success or ``-1`` on + Insert *value* into the dictionary *p* using *key* as a key. *key* should + be a :ctype:`char\*`. The key object is created using + ``PyUnicode_FromString(key)``. Return ``0`` on success or ``-1`` on failure. .. cfunction:: int PyDict_DelItem(PyObject *p, PyObject *key) - Remove the entry in dictionary *p* with key *key*. *key* must be hashable; if it - isn't, :exc:`TypeError` is raised. Return ``0`` on success or ``-1`` on - failure. + Remove the entry in dictionary *p* with key *key*. *key* must be hashable; + if it isn't, :exc:`TypeError` is raised. Return ``0`` on success or ``-1`` + on failure. .. cfunction:: int PyDict_DelItemString(PyObject *p, char *key) @@ -96,8 +97,8 @@ .. cfunction:: PyObject* PyDict_GetItem(PyObject *p, PyObject *key) - Return the object from dictionary *p* which has a key *key*. Return *NULL* if - the key *key* is not present, but *without* setting an exception. + Return the object from dictionary *p* which has a key *key*. Return *NULL* + if the key *key* is not present, but *without* setting an exception. .. cfunction:: PyObject* PyDict_GetItemWithError(PyObject *p, PyObject *key) @@ -116,41 +117,46 @@ .. cfunction:: PyObject* PyDict_Items(PyObject *p) - Return a :ctype:`PyListObject` containing all the items from the dictionary, as - in the dictionary method :meth:`dict.items`. + Return a :ctype:`PyListObject` containing all the items from the + dictionary, as in the dictionary method :meth:`dict.items`. .. cfunction:: PyObject* PyDict_Keys(PyObject *p) - Return a :ctype:`PyListObject` containing all the keys from the dictionary, as - in the dictionary method :meth:`dict.keys`. + Return a :ctype:`PyListObject` containing all the keys from the dictionary, + as in the dictionary method :meth:`dict.keys`. .. cfunction:: PyObject* PyDict_Values(PyObject *p) - Return a :ctype:`PyListObject` containing all the values from the dictionary - *p*, as in the dictionary method :meth:`dict.values`. + Return a :ctype:`PyListObject` containing all the values from the + dictionary *p*, as in the dictionary method :meth:`dict.values`. .. cfunction:: Py_ssize_t PyDict_Size(PyObject *p) .. index:: builtin: len - Return the number of items in the dictionary. This is equivalent to ``len(p)`` - on a dictionary. + Return the number of items in the dictionary. This is equivalent to + ``len(p)`` on a dictionary. + + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. .. cfunction:: int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) - Iterate over all key-value pairs in the dictionary *p*. The :ctype:`int` - referred to by *ppos* must be initialized to ``0`` prior to the first call to - this function to start the iteration; the function returns true for each pair in - the dictionary, and false once all pairs have been reported. The parameters - *pkey* and *pvalue* should either point to :ctype:`PyObject\*` variables that - will be filled in with each key and value, respectively, or may be *NULL*. Any - references returned through them are borrowed. *ppos* should not be altered - during iteration. Its value represents offsets within the internal dictionary - structure, and since the structure is sparse, the offsets are not consecutive. + Iterate over all key-value pairs in the dictionary *p*. The + :ctype:`Py_ssize_t` referred to by *ppos* must be initialized to ``0`` + prior to the first call to this function to start the iteration; the + function returns true for each pair in the dictionary, and false once all + pairs have been reported. The parameters *pkey* and *pvalue* should either + point to :ctype:`PyObject\*` variables that will be filled in with each key + and value, respectively, or may be *NULL*. Any references returned through + them are borrowed. *ppos* should not be altered during iteration. Its + value represents offsets within the internal dictionary structure, and + since the structure is sparse, the offsets are not consecutive. For example:: @@ -163,8 +169,8 @@ } The dictionary *p* should not be mutated during iteration. It is safe to - modify the values of the keys as you iterate over the dictionary, but only so - long as the set of keys does not change. For example:: + modify the values of the keys as you iterate over the dictionary, but only + so long as the set of keys does not change. For example:: PyObject *key, *value; Py_ssize_t pos = 0; @@ -184,15 +190,19 @@ Py_DECREF(o); } + .. versionchanged:: 2.5 + This function used an :ctype:`int *` type for *ppos*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyDict_Merge(PyObject *a, PyObject *b, int override) - Iterate over mapping object *b* adding key-value pairs to dictionary *a*. *b* - may be a dictionary, or any object supporting :func:`PyMapping_Keys` and - :func:`PyObject_GetItem`. If *override* is true, existing pairs in *a* will be - replaced if a matching key is found in *b*, otherwise pairs will only be added - if there is not a matching key in *a*. Return ``0`` on success or ``-1`` if an - exception was raised. + Iterate over mapping object *b* adding key-value pairs to dictionary *a*. + *b* may be a dictionary, or any object supporting :func:`PyMapping_Keys` + and :func:`PyObject_GetItem`. If *override* is true, existing pairs in *a* + will be replaced if a matching key is found in *b*, otherwise pairs will + only be added if there is not a matching key in *a*. Return ``0`` on + success or ``-1`` if an exception was raised. .. cfunction:: int PyDict_Update(PyObject *a, PyObject *b) @@ -203,11 +213,12 @@ .. cfunction:: int PyDict_MergeFromSeq2(PyObject *a, PyObject *seq2, int override) - Update or merge into dictionary *a*, from the key-value pairs in *seq2*. *seq2* - must be an iterable object producing iterable objects of length 2, viewed as - key-value pairs. In case of duplicate keys, the last wins if *override* is - true, else the first wins. Return ``0`` on success or ``-1`` if an exception was - raised. Equivalent Python (except for the return value):: + Update or merge into dictionary *a*, from the key-value pairs in *seq2*. + *seq2* must be an iterable object producing iterable objects of length 2, + viewed as key-value pairs. In case of duplicate keys, the last wins if + *override* is true, else the first wins. Return ``0`` on success or ``-1`` + if an exception was raised. Equivalent Python (except for the return + value):: def PyDict_MergeFromSeq2(a, seq2, override): for key, value in seq2: Modified: python/branches/py3k/Doc/c-api/gcsupport.rst ============================================================================== --- python/branches/py3k/Doc/c-api/gcsupport.rst (original) +++ python/branches/py3k/Doc/c-api/gcsupport.rst Sun Apr 26 23:06:15 2009 @@ -9,7 +9,8 @@ references requires support from object types which are "containers" for other objects which may also be containers. Types which do not store references to other objects, or which only store references to atomic types (such as numbers -or strings), do not need to provide any explicit support for garbage collection. +or strings), do not need to provide any explicit support for garbage +collection. To create a container type, the :attr:`tp_flags` field of the type object must include the :const:`Py_TPFLAGS_HAVE_GC` and provide an implementation of the @@ -20,13 +21,14 @@ .. data:: Py_TPFLAGS_HAVE_GC :noindex: - Objects with a type with this flag set must conform with the rules documented - here. For convenience these objects will be referred to as container objects. + Objects with a type with this flag set must conform with the rules + documented here. For convenience these objects will be referred to as + container objects. Constructors for container types must conform to two rules: -#. The memory for the object must be allocated using :cfunc:`PyObject_GC_New` or - :cfunc:`PyObject_GC_VarNew`. +#. The memory for the object must be allocated using :cfunc:`PyObject_GC_New` + or :cfunc:`PyObject_GC_VarNew`. #. Once all the fields which may contain references to other containers are initialized, it must call :cfunc:`PyObject_GC_Track`. @@ -46,17 +48,17 @@ .. cfunction:: PyVarObject * PyObject_GC_Resize(PyVarObject *op, Py_ssize_t) - Resize an object allocated by :cfunc:`PyObject_NewVar`. Returns the resized - object or *NULL* on failure. + Resize an object allocated by :cfunc:`PyObject_NewVar`. Returns the + resized object or *NULL* on failure. .. cfunction:: void PyObject_GC_Track(PyObject *op) - Adds the object *op* to the set of container objects tracked by the collector. - The collector can run at unexpected times so objects must be valid while being - tracked. This should be called once all the fields followed by the - :attr:`tp_traverse` handler become valid, usually near the end of the - constructor. + Adds the object *op* to the set of container objects tracked by the + collector. The collector can run at unexpected times so objects must be + valid while being tracked. This should be called once all the fields + followed by the :attr:`tp_traverse` handler become valid, usually near the + end of the constructor. .. cfunction:: void _PyObject_GC_TRACK(PyObject *op) @@ -82,10 +84,10 @@ .. cfunction:: void PyObject_GC_UnTrack(void *op) Remove the object *op* from the set of container objects tracked by the - collector. Note that :cfunc:`PyObject_GC_Track` can be called again on this - object to add it back to the set of tracked objects. The deallocator - (:attr:`tp_dealloc` handler) should call this for the object before any of the - fields used by the :attr:`tp_traverse` handler become invalid. + collector. Note that :cfunc:`PyObject_GC_Track` can be called again on + this object to add it back to the set of tracked objects. The deallocator + (:attr:`tp_dealloc` handler) should call this for the object before any of + the fields used by the :attr:`tp_traverse` handler become invalid. .. cfunction:: void _PyObject_GC_UNTRACK(PyObject *op) @@ -98,11 +100,12 @@ .. ctype:: int (*visitproc)(PyObject *object, void *arg) - Type of the visitor function passed to the :attr:`tp_traverse` handler. The - function should be called with an object to traverse as *object* and the third - parameter to the :attr:`tp_traverse` handler as *arg*. The Python core uses - several visitor functions to implement cyclic garbage detection; it's not - expected that users will need to write their own visitor functions. + Type of the visitor function passed to the :attr:`tp_traverse` handler. + The function should be called with an object to traverse as *object* and + the third parameter to the :attr:`tp_traverse` handler as *arg*. The + Python core uses several visitor functions to implement cyclic garbage + detection; it's not expected that users will need to write their own + visitor functions. The :attr:`tp_traverse` handler must have the following type: @@ -111,10 +114,10 @@ Traversal function for a container object. Implementations must call the *visit* function for each object directly contained by *self*, with the - parameters to *visit* being the contained object and the *arg* value passed to - the handler. The *visit* function must not be called with a *NULL* object - argument. If *visit* returns a non-zero value that value should be returned - immediately. + parameters to *visit* being the contained object and the *arg* value passed + to the handler. The *visit* function must not be called with a *NULL* + object argument. If *visit* returns a non-zero value that value should be + returned immediately. To simplify writing :attr:`tp_traverse` handlers, a :cfunc:`Py_VISIT` macro is provided. In order to use this macro, the :attr:`tp_traverse` implementation @@ -123,9 +126,9 @@ .. cfunction:: void Py_VISIT(PyObject *o) - Call the *visit* callback, with arguments *o* and *arg*. If *visit* returns a - non-zero value, then return it. Using this macro, :attr:`tp_traverse` handlers - look like:: + Call the *visit* callback, with arguments *o* and *arg*. If *visit* returns + a non-zero value, then return it. Using this macro, :attr:`tp_traverse` + handlers look like:: static int my_traverse(Noddy *self, visitproc visit, void *arg) @@ -135,14 +138,15 @@ return 0; } -The :attr:`tp_clear` handler must be of the :ctype:`inquiry` type, or *NULL* if -the object is immutable. +The :attr:`tp_clear` handler must be of the :ctype:`inquiry` type, or *NULL* +if the object is immutable. .. ctype:: int (*inquiry)(PyObject *self) - Drop references that may have created reference cycles. Immutable objects do - not have to define this method since they can never directly create reference - cycles. Note that the object must still be valid after calling this method - (don't just call :cfunc:`Py_DECREF` on a reference). The collector will call - this method if it detects that this object is involved in a reference cycle. + Drop references that may have created reference cycles. Immutable objects + do not have to define this method since they can never directly create + reference cycles. Note that the object must still be valid after calling + this method (don't just call :cfunc:`Py_DECREF` on a reference). The + collector will call this method if it detects that this object is involved + in a reference cycle. 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 Sun Apr 26 23:06:15 2009 @@ -44,6 +44,10 @@ :cfunc:`PySequence_SetItem` or expose the object to Python code before setting all items to a real object with :cfunc:`PyList_SetItem`. + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PyList_Size(PyObject *list) @@ -52,6 +56,10 @@ Return the length of the list object in *list*; this is equivalent to ``len(list)`` on a list object. + .. versionchanged:: 2.5 + This function returned an :ctype:`int`. This might require changes in + your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PyList_GET_SIZE(PyObject *list) @@ -64,6 +72,10 @@ must be positive, indexing from the end of the list is not supported. If *pos* is out of bounds, return *NULL* and set an :exc:`IndexError` exception. + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *index*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyList_GET_ITEM(PyObject *list, Py_ssize_t i) @@ -80,6 +92,10 @@ This function "steals" a reference to *item* and discards a reference to an item already in the list at the affected position. + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *index*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: void PyList_SET_ITEM(PyObject *list, Py_ssize_t i, PyObject *o) @@ -99,6 +115,10 @@ if successful; return ``-1`` and set an exception if unsuccessful. Analogous to ``list.insert(index, item)``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *index*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyList_Append(PyObject *list, PyObject *item) @@ -113,6 +133,10 @@ and *high*. Return *NULL* and set an exception if unsuccessful. Analogous to ``list[low:high]``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *low* and *high*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyList_SetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high, PyObject *itemlist) @@ -121,6 +145,10 @@ indicating the assignment of an empty list (slice deletion). Return ``0`` on success, ``-1`` on failure. + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *low* and *high*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyList_Sort(PyObject *list) Modified: python/branches/py3k/Doc/c-api/long.rst ============================================================================== --- python/branches/py3k/Doc/c-api/long.rst (original) +++ python/branches/py3k/Doc/c-api/long.rst Sun Apr 26 23:06:15 2009 @@ -100,6 +100,10 @@ string is first encoded to a byte string using :cfunc:`PyUnicode_EncodeDecimal` and then converted using :cfunc:`PyLong_FromString`. + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *length*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyLong_FromVoidPtr(void *p) Modified: python/branches/py3k/Doc/c-api/mapping.rst ============================================================================== --- python/branches/py3k/Doc/c-api/mapping.rst (original) +++ python/branches/py3k/Doc/c-api/mapping.rst Sun Apr 26 23:06:15 2009 @@ -12,7 +12,8 @@ function always succeeds. -.. cfunction:: Py_ssize_t PyMapping_Length(PyObject *o) +.. cfunction:: Py_ssize_t PyMapping_Size(PyObject *o) + Py_ssize_t PyMapping_Length(PyObject *o) .. index:: builtin: len @@ -20,6 +21,10 @@ objects that do not provide mapping protocol, this is equivalent to the Python expression ``len(o)``. + .. versionchanged:: 2.5 + These functions returned an :ctype:`int` type. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyMapping_DelItemString(PyObject *o, char *key) Modified: python/branches/py3k/Doc/c-api/object.rst ============================================================================== --- python/branches/py3k/Doc/c-api/object.rst (original) +++ python/branches/py3k/Doc/c-api/object.rst Sun Apr 26 23:06:15 2009 @@ -304,6 +304,10 @@ and mapping protocols, the sequence length is returned. On error, ``-1`` is returned. This is the equivalent to the Python expression ``len(o)``. + .. versionchanged:: 2.5 + These functions returned an :ctype:`int` type. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyObject_GetItem(PyObject *o, PyObject *key) Modified: python/branches/py3k/Doc/c-api/sequence.rst ============================================================================== --- python/branches/py3k/Doc/c-api/sequence.rst (original) +++ python/branches/py3k/Doc/c-api/sequence.rst Sun Apr 26 23:06:15 2009 @@ -13,6 +13,7 @@ .. cfunction:: Py_ssize_t PySequence_Size(PyObject *o) + Py_ssize_t PySequence_Length(PyObject *o) .. index:: builtin: len @@ -20,10 +21,9 @@ For objects that do not provide sequence protocol, this is equivalent to the Python expression ``len(o)``. - -.. cfunction:: Py_ssize_t PySequence_Length(PyObject *o) - - Alternate name for :cfunc:`PySequence_Size`. + .. versionchanged:: 2.5 + These functions returned an :ctype:`int` type. This might require + changes in your code for properly supporting 64-bit systems. .. cfunction:: PyObject* PySequence_Concat(PyObject *o1, PyObject *o2) @@ -37,6 +37,10 @@ Return the result of repeating sequence object *o* *count* times, or *NULL* on failure. This is the equivalent of the Python expression ``o * count``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *count*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PySequence_InPlaceConcat(PyObject *o1, PyObject *o2) @@ -51,18 +55,30 @@ failure. The operation is done *in-place* when *o* supports it. This is the equivalent of the Python expression ``o *= count``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *count*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PySequence_GetItem(PyObject *o, Py_ssize_t i) Return the *i*th element of *o*, or *NULL* on failure. This is the equivalent of the Python expression ``o[i]``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PySequence_GetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2) Return the slice of sequence object *o* between *i1* and *i2*, or *NULL* on failure. This is the equivalent of the Python expression ``o[i1:i2]``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i1* and *i2*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v) @@ -70,24 +86,40 @@ is the equivalent of the Python statement ``o[i] = v``. This function *does not* steal a reference to *v*. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PySequence_DelItem(PyObject *o, Py_ssize_t i) Delete the *i*th element of object *o*. Returns ``-1`` on failure. This is the equivalent of the Python statement ``del o[i]``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PySequence_SetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2, PyObject *v) Assign the sequence object *v* to the slice in sequence object *o* from *i1* to *i2*. This is the equivalent of the Python statement ``o[i1:i2] = v``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i1* and *i2*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PySequence_DelSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2) Delete the slice in sequence object *o* from *i1* to *i2*. Returns ``-1`` on failure. This is the equivalent of the Python statement ``del o[i1:i2]``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i1* and *i2*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PySequence_Count(PyObject *o, PyObject *value) @@ -95,6 +127,10 @@ of keys for which ``o[key] == value``. On failure, return ``-1``. This is equivalent to the Python expression ``o.count(value)``. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: int PySequence_Contains(PyObject *o, PyObject *value) @@ -108,6 +144,10 @@ Return the first index *i* for which ``o[i] == value``. On error, return ``-1``. This is equivalent to the Python expression ``o.index(value)``. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PySequence_List(PyObject *o) Modified: python/branches/py3k/Doc/c-api/set.rst ============================================================================== --- python/branches/py3k/Doc/c-api/set.rst (original) +++ python/branches/py3k/Doc/c-api/set.rst Sun Apr 26 23:06:15 2009 @@ -106,6 +106,10 @@ ``len(anyset)``. Raises a :exc:`PyExc_SystemError` if *anyset* is not a :class:`set`, :class:`frozenset`, or an instance of a subtype. + .. versionchanged:: 2.5 + This function returned an :ctype:`int`. This might require changes in + your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PySet_GET_SIZE(PyObject *anyset) 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 Sun Apr 26 23:06:15 2009 @@ -22,30 +22,42 @@ .. cfunction:: PyObject* PySlice_New(PyObject *start, PyObject *stop, PyObject *step) Return a new slice object with the given values. The *start*, *stop*, and - *step* parameters are used as the values of the slice object attributes of the - same names. Any of the values may be *NULL*, in which case the ``None`` will be - used for the corresponding attribute. Return *NULL* if the new object could not - be allocated. + *step* parameters are used as the values of the slice object attributes of + the same names. Any of the values may be *NULL*, in which case the + ``None`` will be used for the corresponding attribute. Return *NULL* if + the new object could not be allocated. .. cfunction:: int PySlice_GetIndices(PySliceObject *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 *length* as - errors. + assuming a sequence of length *length*. Treats indices greater than + *length* as errors. - Returns 0 on success and -1 on error with no exception set (unless one of the - indices was not :const:`None` and failed to be converted to an integer, in which - case -1 is returned with an exception set). + Returns 0 on success and -1 on error with no exception set (unless one of + the indices was not :const:`None` and failed to be converted to an integer, + in which case -1 is returned with an exception set). You probably do not want to use this function. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *length* and an + :ctype:`int *` type for *start*, *stop*, and *step*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: 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) - Usable replacement for :cfunc:`PySlice_GetIndices`. Retrieve the start, stop, - and step indices from the slice object *slice* assuming a sequence of length - *length*, and store the length of the slice in *slicelength*. Out of bounds - indices are clipped in a manner consistent with the handling of normal slices. + Usable replacement for :cfunc:`PySlice_GetIndices`. Retrieve the start, + stop, and step indices from the slice object *slice* assuming a sequence of + length *length*, and store the length of the slice in *slicelength*. Out + of bounds indices are clipped in a manner consistent with the handling of + normal slices. Returns 0 on success and -1 on error with exception set. + + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *length* and an + :ctype:`int *` type for *start*, *stop*, *step*, and *slicelength*. This + might require changes in your code for properly supporting 64-bit + systems. Modified: python/branches/py3k/Doc/c-api/tuple.rst ============================================================================== --- python/branches/py3k/Doc/c-api/tuple.rst (original) +++ python/branches/py3k/Doc/c-api/tuple.rst Sun Apr 26 23:06:15 2009 @@ -37,6 +37,10 @@ Return a new tuple object of size *len*, or *NULL* on failure. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *len*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyTuple_Pack(Py_ssize_t n, ...) @@ -44,11 +48,19 @@ are initialized to the subsequent *n* C arguments pointing to Python objects. ``PyTuple_Pack(2, a, b)`` is equivalent to ``Py_BuildValue("(OO)", a, b)``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *n*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PyTuple_Size(PyObject *p) Take a pointer to a tuple object, and return the size of that tuple. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PyTuple_GET_SIZE(PyObject *p) @@ -61,6 +73,10 @@ Return the object at position *pos* in the tuple pointed to by *p*. If *pos* is out of bounds, return *NULL* and sets an :exc:`IndexError` exception. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *pos*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyTuple_GET_ITEM(PyObject *p, Py_ssize_t pos) @@ -72,6 +88,10 @@ Take a slice of the tuple pointed to by *p* from *low* to *high* and return it as a new tuple. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *low* and *high*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o) @@ -82,6 +102,10 @@ This function "steals" a reference to *o*. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *pos*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: void PyTuple_SET_ITEM(PyObject *p, Py_ssize_t pos, PyObject *o) @@ -106,6 +130,11 @@ ``*p`` is destroyed. On failure, returns ``-1`` and sets ``*p`` to *NULL*, and raises :exc:`MemoryError` or :exc:`SystemError`. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *newsize*. This might + require changes in your code for properly supporting 64-bit systems. + + .. cfunction:: int PyTuple_ClearFreeList(void) Clear the free list. Return the total number of freed items. Modified: python/branches/py3k/Doc/c-api/type.rst ============================================================================== --- python/branches/py3k/Doc/c-api/type.rst (original) +++ python/branches/py3k/Doc/c-api/type.rst Sun Apr 26 23:06:15 2009 @@ -66,6 +66,10 @@ XXX: Document. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *nitems*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds) From python-checkins at python.org Sun Apr 26 23:26:45 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 26 Apr 2009 23:26:45 +0200 (CEST) Subject: [Python-checkins] r71987 - python/branches/py3k/Lib/test/support.py Message-ID: <20090426212645.D4F781E4002@bag.python.org> Author: eric.smith Date: Sun Apr 26 23:26:45 2009 New Revision: 71987 Log: Fixed 2.x-ism. 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 Sun Apr 26 23:26:45 2009 @@ -804,8 +804,8 @@ # Returns a tuple ({platform_name: run_me}, default_value) if not guards: return ({'cpython': True}, False) - is_true = guards.values()[0] - assert guards.values() == [is_true] * len(guards) # all True or all False + is_true = list(guards.values())[0] + assert list(guards.values()) == [is_true] * len(guards) # all True or all False return (guards, not is_true) # Use the following check to guard CPython's implementation-specific tests -- From python-checkins at python.org Sun Apr 26 23:27:39 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 26 Apr 2009 23:27:39 +0200 (CEST) Subject: [Python-checkins] r71988 - python/branches/release30-maint Message-ID: <20090426212739.0B9011E4002@bag.python.org> Author: eric.smith Date: Sun Apr 26 23:27:38 2009 New Revision: 71988 Log: Blocked revisions 71987 via svnmerge ........ r71987 | eric.smith | 2009-04-26 17:26:45 -0400 (Sun, 26 Apr 2009) | 1 line Fixed 2.x-ism. ........ Modified: python/branches/release30-maint/ (props changed) From buildbot at python.org Sun Apr 26 23:30:28 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 26 Apr 2009 21:30:28 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu trunk Message-ID: <20090426213028.3F9371E4002@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%20trunk/builds/1195 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: walter.doerwald BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_time make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sun Apr 26 23:35:15 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 26 Apr 2009 23:35:15 +0200 (CEST) Subject: [Python-checkins] r71989 - in python/branches/py3k: Doc/c-api/conversion.rst Misc/NEWS Python/pystrtod.c Message-ID: <20090426213515.3337D1E4002@bag.python.org> Author: eric.smith Date: Sun Apr 26 23:35:14 2009 New Revision: 71989 Log: Issue #5835: Deprecate PyOS_ascii_formatd. Modified: python/branches/py3k/Doc/c-api/conversion.rst python/branches/py3k/Misc/NEWS python/branches/py3k/Python/pystrtod.c Modified: python/branches/py3k/Doc/c-api/conversion.rst ============================================================================== --- python/branches/py3k/Doc/c-api/conversion.rst (original) +++ python/branches/py3k/Doc/c-api/conversion.rst Sun Apr 26 23:35:14 2009 @@ -73,6 +73,43 @@ The return value is a pointer to *buffer* with the converted string or NULL if the conversion failed. + .. deprecated:: 3.1 + Use :cfunc:`PyOS_double_to_string` instead. + + +.. cfunction:: char* PyOS_double_to_string(double val, char format_code, int precision, int flags, int *ptype) + + Convert a :ctype:`double` *val* to a string using supplied + *format_code*, *precision*, and *flags*. + + *format_code* must be one of ``'e'``, ``'E'``, ``'f'``, ``'F'``, ``'g'``, + ``'G'``, ``'s'``, or ``'r'``. For ``'s'`` and ``'r'``, the supplied + *precision* must be 0 and is ignored. These specify the standard + :func:`str` and :func:`repr` formats, respectively. + + *flags* can be zero or more of the values *Py_DTSF_SIGN*, + *Py_DTSF_ADD_DOT_0*, or *Py_DTSF_ALT*, or-ed together: + + * *Py_DTSF_SIGN* means to always precede the returned string with a sign + character, even if *val* is non-negative. + + * *Py_DTSF_ADD_DOT_0* means to ensure that the returned string will not look + like an integer. + + * *Py_DTSF_ALT* means to apply "alternate" formatting rules. See the + documentation for the :cfunc:`PyOS_snprintf` ``'#'`` specifier for + details. + + If *ptype* is non-NULL, then the value it points to will be set to one of + *Py_DTST_FINITE*, *Py_DTST_INFINITE*, or *Py_DTST_NAN*, signifying that + *val* is a finite number, an infinite number, or not a number, respectively. + + The return value is a pointer to *buffer* with the converted string or + *NULL* if the conversion failed. The caller is responsible for freeing the + returned string by calling :cfunc:`PyMem_Free`. + + .. versionadded:: 3.1 + .. cfunction:: double PyOS_ascii_atof(const char *nptr) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Sun Apr 26 23:35:14 2009 @@ -12,6 +12,8 @@ Core and Builtins ----------------- +- Issue #5835: Deprecate PyOS_ascii_formatd. + - Issue #4971: Fix titlecase for characters that are their own titlecase, but not their own uppercase. Modified: python/branches/py3k/Python/pystrtod.c ============================================================================== --- python/branches/py3k/Python/pystrtod.c (original) +++ python/branches/py3k/Python/pystrtod.c Sun Apr 26 23:35:14 2009 @@ -433,7 +433,7 @@ * Return value: The pointer to the buffer with the converted string. **/ char * -PyOS_ascii_formatd(char *buffer, +_PyOS_ascii_formatd(char *buffer, size_t buf_size, const char *format, double d) @@ -508,6 +508,20 @@ return buffer; } +char * +PyOS_ascii_formatd(char *buffer, + size_t buf_size, + const char *format, + double d) +{ + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "PyOS_ascii_formatd is deprecated, " + "use PyOS_double_to_string instead", 1) < 0) + return NULL; + + return _PyOS_ascii_formatd(buffer, buf_size, format, d); +} + #ifdef PY_NO_SHORT_FLOAT_REPR /* The fallback code to use if _Py_dg_dtoa is not available. */ @@ -638,8 +652,10 @@ if ((flags & Py_DTSF_ADD_DOT_0) && (format_code != 'e')) format_code = 'Z'; - PyOS_snprintf(format, 32, "%%%s.%i%c", (flags & Py_DTSF_ALT ? "#" : ""), precision, format_code); - PyOS_ascii_formatd(buf, sizeof(buf), format, val); + PyOS_snprintf(format, sizeof(format), "%%%s.%i%c", + (flags & Py_DTSF_ALT ? "#" : ""), precision, + format_code); + _PyOS_ascii_formatd(buf, sizeof(buf), format, val); /* remove trailing zeros if necessary */ if (strip_trailing_zeros) remove_trailing_zeros(buf); From python-checkins at python.org Sun Apr 26 23:35:52 2009 From: python-checkins at python.org (eric.smith) Date: Sun, 26 Apr 2009 23:35:52 +0200 (CEST) Subject: [Python-checkins] r71990 - python/branches/release30-maint Message-ID: <20090426213552.8972D1E40A9@bag.python.org> Author: eric.smith Date: Sun Apr 26 23:35:52 2009 New Revision: 71990 Log: Blocked revisions 71989 via svnmerge ........ r71989 | eric.smith | 2009-04-26 17:35:14 -0400 (Sun, 26 Apr 2009) | 1 line Issue #5835: Deprecate PyOS_ascii_formatd. ........ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Sun Apr 26 23:37:46 2009 From: python-checkins at python.org (raymond.hettinger) Date: Sun, 26 Apr 2009 23:37:46 +0200 (CEST) Subject: [Python-checkins] r71991 - python/branches/py3k/Doc/tutorial/floatingpoint.rst Message-ID: <20090426213746.B44BF1E4010@bag.python.org> Author: raymond.hettinger Date: Sun Apr 26 23:37:46 2009 New Revision: 71991 Log: Improve the rounding and summing examples. Modified: python/branches/py3k/Doc/tutorial/floatingpoint.rst Modified: python/branches/py3k/Doc/tutorial/floatingpoint.rst ============================================================================== --- python/branches/py3k/Doc/tutorial/floatingpoint.rst (original) +++ python/branches/py3k/Doc/tutorial/floatingpoint.rst Sun Apr 26 23:37:46 2009 @@ -109,14 +109,24 @@ simply rounding the *display* of the true machine value. One illusion may beget another. For example, since 0.1 is not exactly 1/10, -summing ten values of 0.1 may not yield exactly 1.0, either:: +summing three values of 0.1 may not yield exactly 0.3, either:: - >>> sum = 0.0 - >>> for i in range(10): - ... sum += 0.1 - ... - >>> sum - 0.9999999999999999 + >>> .1 + .1 + .1 == .3 + False + +Also, since the 0.1 cannot get any closer to the exact value of 1/10 and +0.3 cannot get any closer to the exact value of 3/10, then pre-rounding with +:func:`round` function cannot help:: + + >>> round(.1, 1) + round(.1, 1) + round(.1, 1) == round(.3, 1) + False + +Though the numbers cannot be made closer to their intended exact values, +the :func:`round` function can be useful for post-rounding so that results +have inexact values that are comparable to one another:: + + >>> round(.1 + .1 + .1, 1) == round(.3, 1) + True Binary floating-point arithmetic holds many surprises like this. The problem with "0.1" is explained in precise detail below, in the "Representation Error" From python-checkins at python.org Sun Apr 26 23:39:21 2009 From: python-checkins at python.org (walter.doerwald) Date: Sun, 26 Apr 2009 23:39:21 +0200 (CEST) Subject: [Python-checkins] r71992 - in python/branches/py3k: Lib/test/test_optparse.py Lib/test/test_posixpath.py Lib/test/test_site.py Lib/test/test_tempfile.py Lib/test/test_urllib.py Lib/test/test_xmlrpc.py Message-ID: <20090426213921.5C6811E4010@bag.python.org> Author: walter.doerwald Date: Sun Apr 26 23:39:21 2009 New Revision: 71992 Log: Merged revisions 71984 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71984 | walter.doerwald | 2009-04-26 22:51:44 +0200 (So, 26 Apr 2009) | 2 lines Use test.test_support.EnvironmentVarGuard where tests change environment vars. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_optparse.py python/branches/py3k/Lib/test/test_posixpath.py python/branches/py3k/Lib/test/test_site.py python/branches/py3k/Lib/test/test_tempfile.py python/branches/py3k/Lib/test/test_urllib.py python/branches/py3k/Lib/test/test_xmlrpc.py Modified: python/branches/py3k/Lib/test/test_optparse.py ============================================================================== --- python/branches/py3k/Lib/test/test_optparse.py (original) +++ python/branches/py3k/Lib/test/test_optparse.py Sun Apr 26 23:39:21 2009 @@ -1448,15 +1448,9 @@ # we must restore its original value -- otherwise, this test # screws things up for other tests when it's part of the Python # test suite. - orig_columns = os.environ.get('COLUMNS') - os.environ['COLUMNS'] = str(columns) - try: + with test_support.EnvironmentVarGuard() as env: + env.set('COLUMNS', str(columns)) return InterceptingOptionParser(option_list=options) - finally: - if orig_columns is None: - del os.environ['COLUMNS'] - else: - os.environ['COLUMNS'] = orig_columns def assertHelpEquals(self, expected_output): save_argv = sys.argv[:] @@ -1479,16 +1473,10 @@ self.assertHelpEquals(_expected_help_long_opts_first) def test_help_title_formatter(self): - save = os.environ.get("COLUMNS") - try: - os.environ["COLUMNS"] = "80" + with test_support.EnvironmentVarGuard() as env: + env.set("COLUMNS", "80") self.parser.formatter = TitledHelpFormatter() self.assertHelpEquals(_expected_help_title_formatter) - finally: - if save is not None: - os.environ["COLUMNS"] = save - else: - del os.environ["COLUMNS"] def test_wrap_columns(self): # Ensure that wrapping respects $COLUMNS environment variable. 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 Sun Apr 26 23:39:21 2009 @@ -419,10 +419,9 @@ self.assert_(isinstance(posixpath.expanduser(b"~root/"), bytes)) self.assert_(isinstance(posixpath.expanduser(b"~foo/"), bytes)) - orig_home = os.environ['HOME'] - os.environ['HOME'] = '/' - self.assertEqual(posixpath.expanduser("~"), "/") - os.environ['HOME'] = orig_home + with test_support.EnvironmentVarGuard() as env: + env.set('HOME', '/') + self.assertEqual(posixpath.expanduser("~"), "/") self.assertRaises(TypeError, posixpath.expanduser) Modified: python/branches/py3k/Lib/test/test_site.py ============================================================================== --- python/branches/py3k/Lib/test/test_site.py (original) +++ python/branches/py3k/Lib/test/test_site.py Sun Apr 26 23:39:21 2009 @@ -5,7 +5,7 @@ """ import unittest -from test.support import run_unittest, TESTFN +from test.support import run_unittest, TESTFN, EnvironmentVarGuard import builtins import os import sys 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 Apr 26 23:39:21 2009 @@ -149,13 +149,11 @@ # _candidate_tempdir_list contains the expected directories # Make sure the interesting environment variables are all set. - added = [] - try: + with test_support.EnvironmentVarGuard() as env: for envname in 'TMPDIR', 'TEMP', 'TMP': dirname = os.getenv(envname) if not dirname: - os.environ[envname] = os.path.abspath(envname) - added.append(envname) + env.set(envname, os.path.abspath(envname)) cand = tempfile._candidate_tempdir_list() @@ -173,9 +171,6 @@ # Not practical to try to verify the presence of OS-specific # paths in this list. - finally: - for p in added: - del os.environ[p] test_classes.append(test__candidate_tempdir_list) Modified: python/branches/py3k/Lib/test/test_urllib.py ============================================================================== --- python/branches/py3k/Lib/test/test_urllib.py (original) +++ python/branches/py3k/Lib/test/test_urllib.py Sun Apr 26 23:39:21 2009 @@ -117,27 +117,19 @@ class ProxyTests(unittest.TestCase): def setUp(self): - # Save all proxy related env vars - self._saved_environ = dict([(k, v) for k, v in os.environ.items() - if k.lower().find('proxy') >= 0]) - # Delete all proxy related env vars - for k in self._saved_environ: - del os.environ[k] + # Records changes to env vars + self.env = support.EnvironmentVarGuard() def tearDown(self): # Restore all proxy related env vars - for k, v in self._saved_environ.items(): - os.environ[k] = v + self.env.__exit__() + del self.env def test_getproxies_environment_keep_no_proxies(self): - try: - os.environ['NO_PROXY'] = 'localhost' - proxies = urllib.request.getproxies_environment() - # getproxies_environment use lowered case truncated (no '_proxy') keys - self.assertEquals('localhost', proxies['no']) - finally: - # The old value will be restored by tearDown, if applicable. - del os.environ['NO_PROXY'] + self.env.set('NO_PROXY', 'localhost') + proxies = urllib.request.getproxies_environment() + # getproxies_environment use lowered case truncated (no '_proxy') keys + self.assertEquals('localhost', proxies['no']) class urlopen_HttpTests(unittest.TestCase): 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 Sun Apr 26 23:39:21 2009 @@ -571,25 +571,25 @@ self.cgi = None def test_cgi_get(self): - os.environ['REQUEST_METHOD'] = 'GET' - # if the method is GET and no request_text is given, it runs handle_get - # get sysout output - tmp = sys.stdout - sys.stdout = open(support.TESTFN, "w") - self.cgi.handle_request() - sys.stdout.close() - sys.stdout = tmp + with support.EnvironmentVarGuard() as env: + env.set('REQUEST_METHOD', 'GET') + # if the method is GET and no request_text is given, it runs handle_get + # get sysout output + tmp = sys.stdout + sys.stdout = open(support.TESTFN, "w") + self.cgi.handle_request() + sys.stdout.close() + sys.stdout = tmp - # parse Status header - handle = open(support.TESTFN, "r").read() - status = handle.split()[1] - message = ' '.join(handle.split()[2:4]) + # parse Status header + handle = open(support.TESTFN, "r").read() + status = handle.split()[1] + message = ' '.join(handle.split()[2:4]) - self.assertEqual(status, '400') - self.assertEqual(message, 'Bad Request') + self.assertEqual(status, '400') + self.assertEqual(message, 'Bad Request') - os.remove(support.TESTFN) - os.environ['REQUEST_METHOD'] = '' + os.remove(support.TESTFN) def test_cgi_xmlrpc_response(self): data = """ @@ -612,11 +612,9 @@ sys.stdin = open("xmldata.txt", "r") sys.stdout = open(support.TESTFN, "w") - os.environ['CONTENT_LENGTH'] = str(len(data)) - try: + with support.EnvironmentVarGuard() as env: + env.set('CONTENT_LENGTH', str(len(data))) self.cgi.handle_request() - finally: - del os.environ['CONTENT_LENGTH'] sys.stdin.close() sys.stdout.close() From buildbot at python.org Sun Apr 26 23:55:42 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 26 Apr 2009 21:55:42 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 3.x Message-ID: <20090426215542.53DF61E411F@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%203.x/builds/690 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: walter.doerwald BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_os ====================================================================== FAIL: test_update2 (test.test_os.EnvironTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/test/test_os.py", line 382, in test_update2 self.assertEquals(value, "World") AssertionError: '' != 'World' make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Sun Apr 26 23:59:28 2009 From: python-checkins at python.org (walter.doerwald) Date: Sun, 26 Apr 2009 23:59:28 +0200 (CEST) Subject: [Python-checkins] r71993 - in python/branches/release30-maint: Lib/test/test_optparse.py Lib/test/test_site.py Lib/test/test_tempfile.py Lib/test/test_urllib.py Lib/test/test_xmlrpc.py Message-ID: <20090426215928.25B4E1E4002@bag.python.org> Author: walter.doerwald Date: Sun Apr 26 23:59:27 2009 New Revision: 71993 Log: Merged revisions 71992 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r71992 | walter.doerwald | 2009-04-26 23:39:21 +0200 (So, 26 Apr 2009) | 9 lines Merged revisions 71984 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71984 | walter.doerwald | 2009-04-26 22:51:44 +0200 (So, 26 Apr 2009) | 2 lines Use test.test_support.EnvironmentVarGuard where tests change environment vars. ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Lib/test/test_optparse.py python/branches/release30-maint/Lib/test/test_site.py python/branches/release30-maint/Lib/test/test_tempfile.py python/branches/release30-maint/Lib/test/test_urllib.py python/branches/release30-maint/Lib/test/test_xmlrpc.py Modified: python/branches/release30-maint/Lib/test/test_optparse.py ============================================================================== --- python/branches/release30-maint/Lib/test/test_optparse.py (original) +++ python/branches/release30-maint/Lib/test/test_optparse.py Sun Apr 26 23:59:27 2009 @@ -1448,15 +1448,9 @@ # we must restore its original value -- otherwise, this test # screws things up for other tests when it's part of the Python # test suite. - orig_columns = os.environ.get('COLUMNS') - os.environ['COLUMNS'] = str(columns) - try: + with support.EnvironmentVarGuard() as env: + env.set('COLUMNS', str(columns)) return InterceptingOptionParser(option_list=options) - finally: - if orig_columns is None: - del os.environ['COLUMNS'] - else: - os.environ['COLUMNS'] = orig_columns def assertHelpEquals(self, expected_output): save_argv = sys.argv[:] @@ -1479,16 +1473,10 @@ self.assertHelpEquals(_expected_help_long_opts_first) def test_help_title_formatter(self): - save = os.environ.get("COLUMNS") - try: - os.environ["COLUMNS"] = "80" + with support.EnvironmentVarGuard() as env: + env.set("COLUMNS", "80") self.parser.formatter = TitledHelpFormatter() self.assertHelpEquals(_expected_help_title_formatter) - finally: - if save is not None: - os.environ["COLUMNS"] = save - else: - del os.environ["COLUMNS"] def test_wrap_columns(self): # Ensure that wrapping respects $COLUMNS environment variable. Modified: python/branches/release30-maint/Lib/test/test_site.py ============================================================================== --- python/branches/release30-maint/Lib/test/test_site.py (original) +++ python/branches/release30-maint/Lib/test/test_site.py Sun Apr 26 23:59:27 2009 @@ -5,7 +5,7 @@ """ import unittest -from test.support import TestSkipped, run_unittest, TESTFN +from test.support import TestSkipped, run_unittest, TESTFN, EnvironmentVarGuard import builtins import os import sys Modified: python/branches/release30-maint/Lib/test/test_tempfile.py ============================================================================== --- python/branches/release30-maint/Lib/test/test_tempfile.py (original) +++ python/branches/release30-maint/Lib/test/test_tempfile.py Sun Apr 26 23:59:27 2009 @@ -149,13 +149,11 @@ # _candidate_tempdir_list contains the expected directories # Make sure the interesting environment variables are all set. - added = [] - try: + with support.EnvironmentVarGuard() as env: for envname in 'TMPDIR', 'TEMP', 'TMP': dirname = os.getenv(envname) if not dirname: - os.environ[envname] = os.path.abspath(envname) - added.append(envname) + env.set(envname, os.path.abspath(envname)) cand = tempfile._candidate_tempdir_list() @@ -173,9 +171,6 @@ # Not practical to try to verify the presence of OS-specific # paths in this list. - finally: - for p in added: - del os.environ[p] test_classes.append(test__candidate_tempdir_list) Modified: python/branches/release30-maint/Lib/test/test_urllib.py ============================================================================== --- python/branches/release30-maint/Lib/test/test_urllib.py (original) +++ python/branches/release30-maint/Lib/test/test_urllib.py Sun Apr 26 23:59:27 2009 @@ -117,27 +117,19 @@ class ProxyTests(unittest.TestCase): def setUp(self): - # Save all proxy related env vars - self._saved_environ = dict([(k, v) for k, v in os.environ.items() - if k.lower().find('proxy') >= 0]) - # Delete all proxy related env vars - for k in self._saved_environ: - del os.environ[k] + # Records changes to env vars + self.env = support.EnvironmentVarGuard() def tearDown(self): # Restore all proxy related env vars - for k, v in self._saved_environ.items(): - os.environ[k] = v + self.env.__exit__() + del self.env def test_getproxies_environment_keep_no_proxies(self): - try: - os.environ['NO_PROXY'] = 'localhost' - proxies = urllib.request.getproxies_environment() - # getproxies_environment use lowered case truncated (no '_proxy') keys - self.assertEquals('localhost', proxies['no']) - finally: - # The old value will be restored by tearDown, if applicable. - del os.environ['NO_PROXY'] + self.env.set('NO_PROXY', 'localhost') + proxies = urllib.request.getproxies_environment() + # getproxies_environment use lowered case truncated (no '_proxy') keys + self.assertEquals('localhost', proxies['no']) class urlopen_HttpTests(unittest.TestCase): Modified: python/branches/release30-maint/Lib/test/test_xmlrpc.py ============================================================================== --- python/branches/release30-maint/Lib/test/test_xmlrpc.py (original) +++ python/branches/release30-maint/Lib/test/test_xmlrpc.py Sun Apr 26 23:59:27 2009 @@ -544,25 +544,25 @@ self.cgi = None def test_cgi_get(self): - os.environ['REQUEST_METHOD'] = 'GET' - # if the method is GET and no request_text is given, it runs handle_get - # get sysout output - tmp = sys.stdout - sys.stdout = open(support.TESTFN, "w") - self.cgi.handle_request() - sys.stdout.close() - sys.stdout = tmp + with support.EnvironmentVarGuard() as env: + env.set('REQUEST_METHOD', 'GET') + # if the method is GET and no request_text is given, it runs handle_get + # get sysout output + tmp = sys.stdout + sys.stdout = open(support.TESTFN, "w") + self.cgi.handle_request() + sys.stdout.close() + sys.stdout = tmp + + # parse Status header + handle = open(support.TESTFN, "r").read() + status = handle.split()[1] + message = ' '.join(handle.split()[2:4]) - # parse Status header - handle = open(support.TESTFN, "r").read() - status = handle.split()[1] - message = ' '.join(handle.split()[2:4]) - - self.assertEqual(status, '400') - self.assertEqual(message, 'Bad Request') + self.assertEqual(status, '400') + self.assertEqual(message, 'Bad Request') - os.remove(support.TESTFN) - os.environ['REQUEST_METHOD'] = '' + os.remove(support.TESTFN) def test_cgi_xmlrpc_response(self): data = """ From python-checkins at python.org Mon Apr 27 00:01:46 2009 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 27 Apr 2009 00:01:46 +0200 (CEST) Subject: [Python-checkins] r71994 - python/branches/py3k/Doc/tutorial/floatingpoint.rst Message-ID: <20090426220146.5F2491E4002@bag.python.org> Author: raymond.hettinger Date: Mon Apr 27 00:01:46 2009 New Revision: 71994 Log: Add link to math.fsum(). Modified: python/branches/py3k/Doc/tutorial/floatingpoint.rst Modified: python/branches/py3k/Doc/tutorial/floatingpoint.rst ============================================================================== --- python/branches/py3k/Doc/tutorial/floatingpoint.rst (original) +++ python/branches/py3k/Doc/tutorial/floatingpoint.rst Mon Apr 27 00:01:46 2009 @@ -189,6 +189,16 @@ across different versions of Python (platform independence) and exchanging data with other languages that support the same format (such as Java and C99). +Another helpful tool is the :func:`math.fsum` function which helps mitigate +loss-of-precision during summation. It tracks "lost digits" as values are +added onto a running total. That can make a difference in overall accuracy +so that the errors do not accumulate to the point where they affect the +final total: + + >>> sum([0.1] * 10) == 1.0 + False + >>> math.fsum([0.1] * 10) == 1.0 + True .. _tut-fp-error: From nnorwitz at gmail.com Mon Apr 27 00:23:12 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Sun, 26 Apr 2009 18:23:12 -0400 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20090426222312.GA24122@python.psfb.org> More important issues: ---------------------- test_itertools leaked [0, 0, 32] references, sum=32 Less important issues: ---------------------- test_cmd_line leaked [0, 25, 0] references, sum=25 test_popen2 leaked [54, -54, 0] references, sum=0 test_smtplib leaked [0, -6, 6] references, sum=0 test_socketserver leaked [83, -83, 0] references, sum=0 test_sys leaked [42, -42, 42] references, sum=42 test_threadedtempfile leaked [102, -102, 0] references, sum=0 test_threading leaked [53, 43, 48] references, sum=144 test_urllib2_localnet leaked [-11, 17, -279] references, sum=-273 test_xmlrpc leaked [0, 8, 77] references, sum=85 From buildbot at python.org Mon Apr 27 00:41:42 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 26 Apr 2009 22:41:42 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 3.x Message-ID: <20090426224142.A5F331E4002@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%203.x/builds/819 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: eric.smith,raymond.hettinger,walter.doerwald BUILD FAILED: failed test Excerpt from the test logfile: 4 tests failed: test_optparse test_os test_posixpath test_tempfile ====================================================================== ERROR: test_help (test.test_optparse.TestHelp) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_optparse.py", line 1432, in setUp self.parser = self.make_parser(80) File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_optparse.py", line 1451, in make_parser with test_support.EnvironmentVarGuard() as env: NameError: global name 'test_support' is not defined ====================================================================== ERROR: test_help_description_groups (test.test_optparse.TestHelp) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_optparse.py", line 1432, in setUp self.parser = self.make_parser(80) File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_optparse.py", line 1451, in make_parser with test_support.EnvironmentVarGuard() as env: NameError: global name 'test_support' is not defined ====================================================================== ERROR: test_help_long_opts_first (test.test_optparse.TestHelp) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_optparse.py", line 1432, in setUp self.parser = self.make_parser(80) File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_optparse.py", line 1451, in make_parser with test_support.EnvironmentVarGuard() as env: NameError: global name 'test_support' is not defined ====================================================================== ERROR: test_help_old_usage (test.test_optparse.TestHelp) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_optparse.py", line 1432, in setUp self.parser = self.make_parser(80) File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_optparse.py", line 1451, in make_parser with test_support.EnvironmentVarGuard() as env: NameError: global name 'test_support' is not defined ====================================================================== ERROR: test_help_title_formatter (test.test_optparse.TestHelp) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_optparse.py", line 1432, in setUp self.parser = self.make_parser(80) File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_optparse.py", line 1451, in make_parser with test_support.EnvironmentVarGuard() as env: NameError: global name 'test_support' is not defined ====================================================================== ERROR: test_help_unicode (test.test_optparse.TestHelp) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_optparse.py", line 1432, in setUp self.parser = self.make_parser(80) File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_optparse.py", line 1451, in make_parser with test_support.EnvironmentVarGuard() as env: NameError: global name 'test_support' is not defined ====================================================================== ERROR: test_help_unicode_description (test.test_optparse.TestHelp) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_optparse.py", line 1432, in setUp self.parser = self.make_parser(80) File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_optparse.py", line 1451, in make_parser with test_support.EnvironmentVarGuard() as env: NameError: global name 'test_support' is not defined ====================================================================== ERROR: test_wrap_columns (test.test_optparse.TestHelp) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_optparse.py", line 1432, in setUp self.parser = self.make_parser(80) File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_optparse.py", line 1451, in make_parser with test_support.EnvironmentVarGuard() as env: NameError: global name 'test_support' is not defined ====================================================================== ERROR: test_expanduser (test.test_posixpath.PosixPathTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_posixpath.py", line 422, in test_expanduser with test_support.EnvironmentVarGuard() as env: NameError: global name 'test_support' is not defined ====================================================================== ERROR: test_wanted_dirs (test.test_tempfile.test__candidate_tempdir_list) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_tempfile.py", line 152, in test_wanted_dirs with test_support.EnvironmentVarGuard() as env: NameError: global name 'test_support' is not defined make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Mon Apr 27 00:46:00 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 26 Apr 2009 22:46:00 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 2.6 Message-ID: <20090426224600.981BA1E4002@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%202.6/builds/284 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: walter.doerwald BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_modulefinder make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 27 01:22:11 2009 From: python-checkins at python.org (kurt.kaiser) Date: Mon, 27 Apr 2009 01:22:11 +0200 (CEST) Subject: [Python-checkins] r71995 - in python/trunk/Lib/idlelib: NEWS.txt OutputWindow.py Message-ID: <20090426232211.933C71E4002@bag.python.org> Author: kurt.kaiser Date: Mon Apr 27 01:22:11 2009 New Revision: 71995 Log: Right click 'go to file/line' not working if spaces in path. Bug 5559. Modified: python/trunk/Lib/idlelib/NEWS.txt python/trunk/Lib/idlelib/OutputWindow.py Modified: python/trunk/Lib/idlelib/NEWS.txt ============================================================================== --- python/trunk/Lib/idlelib/NEWS.txt (original) +++ python/trunk/Lib/idlelib/NEWS.txt Mon Apr 27 01:22:11 2009 @@ -3,6 +3,9 @@ *Release date: XX-XXX-2009* +- OutputWindow/PyShell right click menu "Go to file/line" wasn't working with + file paths containing spaces. Bug 5559. + - Windows: Version string for the .chm help file changed, file not being accessed Patch 5783 Guilherme Polo Modified: python/trunk/Lib/idlelib/OutputWindow.py ============================================================================== --- python/trunk/Lib/idlelib/OutputWindow.py (original) +++ python/trunk/Lib/idlelib/OutputWindow.py Mon Apr 27 01:22:11 2009 @@ -63,6 +63,7 @@ r'file "([^"]*)", line (\d+)', r'([^\s]+)\((\d+)\)', r'([^\s]+):\s*(\d+):', + r'^\s*(\S+.*?):\s*(\d+):', # Win path with spaces, trim leading spaces ] file_line_progs = None @@ -96,17 +97,17 @@ def _file_line_helper(self, line): for prog in self.file_line_progs: - m = prog.search(line) - if m: - break + match = prog.search(line) + if match: + filename, lineno = match.group(1, 2) + try: + f = open(filename, "r") + f.close() + break + except IOError: + continue else: return None - filename, lineno = m.group(1, 2) - try: - f = open(filename, "r") - f.close() - except IOError: - return None try: return filename, int(lineno) except TypeError: @@ -139,19 +140,3 @@ text.tag_configure(tag, **cnf) text.tag_raise('sel') self.write = self.owin.write - -#class PseudoFile: -# -# def __init__(self, owin, tags, mark="end"): -# self.owin = owin -# self.tags = tags -# self.mark = mark - -# def write(self, s): -# self.owin.write(s, self.tags, self.mark) - -# def writelines(self, l): -# map(self.write, l) - -# def flush(self): -# pass From buildbot at python.org Mon Apr 27 01:33:00 2009 From: buildbot at python.org (buildbot at python.org) Date: Sun, 26 Apr 2009 23:33:00 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 2.6 Message-ID: <20090426233300.9CDA41E4002@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%202.6/builds/262 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: walter.doerwald BUILD FAILED: failed test Excerpt from the test logfile: make: *** [buildbottest] Killed sincerely, -The Buildbot From buildbot at python.org Mon Apr 27 03:14:35 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 27 Apr 2009 01:14:35 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable trunk Message-ID: <20090427011435.F257F1E4010@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%20trunk/builds/422 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: walter.doerwald BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_time make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 27 03:44:28 2009 From: python-checkins at python.org (hirokazu.yamamoto) Date: Mon, 27 Apr 2009 03:44:28 +0200 (CEST) Subject: [Python-checkins] r71996 - in python/branches/py3k/Lib/test: test_optparse.py test_posixpath.py test_tempfile.py Message-ID: <20090427014428.A27C91E4002@bag.python.org> Author: hirokazu.yamamoto Date: Mon Apr 27 03:44:28 2009 New Revision: 71996 Log: test_support was renamed to support on py3k. Modified: python/branches/py3k/Lib/test/test_optparse.py python/branches/py3k/Lib/test/test_posixpath.py python/branches/py3k/Lib/test/test_tempfile.py Modified: python/branches/py3k/Lib/test/test_optparse.py ============================================================================== --- python/branches/py3k/Lib/test/test_optparse.py (original) +++ python/branches/py3k/Lib/test/test_optparse.py Mon Apr 27 03:44:28 2009 @@ -1448,7 +1448,7 @@ # we must restore its original value -- otherwise, this test # screws things up for other tests when it's part of the Python # test suite. - with test_support.EnvironmentVarGuard() as env: + with support.EnvironmentVarGuard() as env: env.set('COLUMNS', str(columns)) return InterceptingOptionParser(option_list=options) @@ -1473,7 +1473,7 @@ self.assertHelpEquals(_expected_help_long_opts_first) def test_help_title_formatter(self): - with test_support.EnvironmentVarGuard() as env: + with support.EnvironmentVarGuard() as env: env.set("COLUMNS", "80") self.parser.formatter = TitledHelpFormatter() self.assertHelpEquals(_expected_help_title_formatter) 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 Mon Apr 27 03:44:28 2009 @@ -419,7 +419,7 @@ self.assert_(isinstance(posixpath.expanduser(b"~root/"), bytes)) self.assert_(isinstance(posixpath.expanduser(b"~foo/"), bytes)) - with test_support.EnvironmentVarGuard() as env: + with support.EnvironmentVarGuard() as env: env.set('HOME', '/') self.assertEqual(posixpath.expanduser("~"), "/") 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 Apr 27 03:44:28 2009 @@ -149,7 +149,7 @@ # _candidate_tempdir_list contains the expected directories # Make sure the interesting environment variables are all set. - with test_support.EnvironmentVarGuard() as env: + with support.EnvironmentVarGuard() as env: for envname in 'TMPDIR', 'TEMP', 'TMP': dirname = os.getenv(envname) if not dirname: From buildbot at python.org Mon Apr 27 05:06:33 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 27 Apr 2009 03:06:33 +0000 Subject: [Python-checkins] buildbot failure in x86 XP-4 trunk Message-ID: <20090427030633.A95111E4023@bag.python.org> The Buildbot has detected a new failure of x86 XP-4 trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20XP-4%20trunk/builds/2080 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: bolen-windows Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: mark.dickinson,walter.doerwald BUILD FAILED: failed test Excerpt from the test logfile: 4 tests failed: test__locale test_bsddb3 test_types test_urllib Traceback (most recent call last): File "../lib/test/regrtest.py", line 569, in runtest_inner the_package = __import__(abstest, globals(), locals(), []) File "E:\cygwin\home\db3l\buildarea\trunk.bolen-windows\build\lib\test\test__locale.py", line 2, in from _locale import (setlocale, LC_NUMERIC, RADIXCHAR, THOUSEP, nl_langinfo, ImportError: cannot import name RADIXCHAR ====================================================================== ERROR: test01_basic_replication (bsddb.test.test_replication.DBReplicationManager) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\trunk.bolen-windows\build\lib\bsddb\test\test_replication.py", line 170, in test01_basic_replication mode=0666, txn=txn) DBNoSuchFileError: (2, 'No such file or directory -- connection closed: Successful return: 0') ====================================================================== ERROR: test01_basic_replication (bsddb.test.test_replication.DBReplicationManager) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\trunk.bolen-windows\build\lib\bsddb\test\test_replication.py", line 58, in tearDown if self.dbClient : DBError: (0, 'DB object has been closed') ====================================================================== FAIL: test01_basic_replication (bsddb.test.test_replication.DBBaseReplication) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\trunk.bolen-windows\build\lib\bsddb\test\test_replication.py", line 315, in test01_basic_replication self.assertTrue(time.time() The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/306 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: eric.smith,walter.doerwald BUILD FAILED: failed test Excerpt from the test logfile: 3 tests failed: test_distutils test_posix test_subprocess ====================================================================== FAIL: test_get_python_inc (distutils.tests.test_sysconfig.SysconfigTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/distutils/tests/test_sysconfig.py", line 45, in test_get_python_inc self.assert_(os.path.isdir(inc_dir), inc_dir) AssertionError: /home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/Include ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 27 07:16:01 2009 From: python-checkins at python.org (martin.v.loewis) Date: Mon, 27 Apr 2009 07:16:01 +0200 (CEST) Subject: [Python-checkins] r71997 - tracker/instances/python-dev/html/issue.item.html Message-ID: <20090427051601.AE2671E400C@bag.python.org> Author: martin.v.loewis Date: Mon Apr 27 07:16:01 2009 New Revision: 71997 Log: Issue #271: add permalinks for the messages. Modified: tracker/instances/python-dev/html/issue.item.html Modified: tracker/instances/python-dev/html/issue.item.html ============================================================================== --- tracker/instances/python-dev/html/issue.item.html (original) +++ tracker/instances/python-dev/html/issue.item.html Mon Apr 27 07:16:01 2009 @@ -232,8 +232,9 @@ >Messages
- +
DownloadDescriptoinDescription Content Type Uploaded By Date
%s
%s
+
+ + +and add ``method="POST"`` as shown below:: + +
+ + + +Then also find:: + + + + + +and add ``method="POST"`` as shown below:: + + + + + + +Fixing the "retire" button in user management list +-------------------------------------------------- + +If you made the change to the "reture" link in the user management list as +listed below in `Migrating from 1.4.x to 1.4.7`_ then you'll need to fix that +change by adding ``method="POST"`` to the ```` tag:: + + + + + + + Migrating from 1.4.x to 1.4.7 ============================= @@ -53,7 +103,7 @@ Should be replaced with:: -
Modified: tracker/roundup-src/roundup/__init__.py ============================================================================== --- tracker/roundup-src/roundup/__init__.py (original) +++ tracker/roundup-src/roundup/__init__.py Sat Apr 25 10:59:43 2009 @@ -68,6 +68,6 @@ ''' __docformat__ = 'restructuredtext' -__version__ = '1.4.7' +__version__ = '1.4.8' # vim: set filetype=python ts=4 sw=4 et si Modified: tracker/roundup-src/roundup/backends/rdbms_common.py ============================================================================== --- tracker/roundup-src/roundup/backends/rdbms_common.py (original) +++ tracker/roundup-src/roundup/backends/rdbms_common.py Sat Apr 25 10:59:43 2009 @@ -2366,7 +2366,7 @@ if search_matches is not None: s = ','.join([a for x in search_matches]) where.append('_%s.id in (%s)'%(icn, s)) - args = args + search_matches.keys() + args = args + [x for x in search_matches] # construct the SQL frum.append('_'+icn) Modified: tracker/roundup-src/roundup/cgi/actions.py ============================================================================== --- tracker/roundup-src/roundup/cgi/actions.py (original) +++ tracker/roundup-src/roundup/cgi/actions.py Sat Apr 25 10:59:43 2009 @@ -105,7 +105,7 @@ """Retire the context item.""" # ensure modification comes via POST if self.client.env['REQUEST_METHOD'] != 'POST': - self.client.error_message.append(self._('Invalid request')) + raise roundup.exceptions.Reject(self._('Invalid request')) # if we want to view the index template now, then unset the itemid # context info (a special-case for retire actions on the index page) @@ -284,7 +284,7 @@ """ # ensure modification comes via POST if self.client.env['REQUEST_METHOD'] != 'POST': - self.client.error_message.append(self._('Invalid request')) + raise roundup.exceptions.Reject(self._('Invalid request')) # figure the properties list for the class cl = self.db.classes[self.classname] @@ -587,7 +587,7 @@ """ # ensure modification comes via POST if self.client.env['REQUEST_METHOD'] != 'POST': - self.client.error_message.append(self._('Invalid request')) + raise roundup.exceptions.Reject(self._('Invalid request')) user_activity = self.lastUserActivity() if user_activity: @@ -633,7 +633,7 @@ ''' # ensure modification comes via POST if self.client.env['REQUEST_METHOD'] != 'POST': - self.client.error_message.append(self._('Invalid request')) + raise roundup.exceptions.Reject(self._('Invalid request')) # parse the props from the form try: @@ -819,7 +819,7 @@ """ # ensure modification comes via POST if self.client.env['REQUEST_METHOD'] != 'POST': - self.client.error_message.append(self._('Invalid request')) + raise roundup.exceptions.Reject(self._('Invalid request')) # parse the props from the form try: @@ -937,7 +937,7 @@ """ # ensure modification comes via POST if self.client.env['REQUEST_METHOD'] != 'POST': - self.client.error_message.append(self._('Invalid request')) + raise roundup.exceptions.Reject(self._('Invalid request')) # we need the username at a minimum if not self.form.has_key('__login_name'): @@ -1094,11 +1094,11 @@ def permission(self, args): """Raise Unauthorised if the current user is not allowed to execute this action. Users may override this method.""" - + pass def handle(self, args): - + raise NotImplementedError # vim: set filetype=python sts=4 sw=4 et si : Modified: tracker/roundup-src/roundup/cgi/templating.py ============================================================================== --- tracker/roundup-src/roundup/cgi/templating.py (original) +++ tracker/roundup-src/roundup/cgi/templating.py Sat Apr 25 10:59:43 2009 @@ -624,7 +624,6 @@ classname=self._klass.classname, property=name): raise Unauthorised('view', self._klass.classname, translator=self._client.translator) - row.append(str(klass.get(itemid, name))) value = self._klass.get(nodeid, name) if value is None: l.append('') @@ -1132,7 +1131,7 @@ # The context for a search page should be the class, not any # node. self._client.nodeid = None - + # use our fabricated request return pt.render(self._client, req.classname, req) @@ -1960,7 +1959,7 @@ else: fn = lambda optionid: linkcl.get(optionid, propname) additional_fns.append(fn) - + for optionid in options: # get the option value, and if it's None use an empty string option = linkcl.get(optionid, k) or '' @@ -2148,7 +2147,7 @@ for opt in linkcl.filter(None, conditions, sort_on) if self._db.security.hasPermission("View", self._client.userid, linkcl.classname, itemid=opt)] - + # make sure we list the current values if they're retired for val in value: if val not in options: @@ -2181,7 +2180,7 @@ else: fn = lambda optionid: linkcl.get(optionid, propname) additional_fns.append(fn) - + for optionid in options: # get the option value, and if it's None use an empty string option = linkcl.get(optionid, k) or '' @@ -2410,8 +2409,8 @@ try: self.pagesize = int(self.form.getfirst(name)) except ValueError: - # Not an integer. XXX report to user somehow? - pass + # not an integer - ignore + pass self.startwith = 0 for name in ':startwith @startwith'.split(): @@ -2420,7 +2419,7 @@ try: self.startwith = int(self.form.getfirst(name)) except ValueError: - # Not an integer. XXX report to user somehow? + # not an integer - ignore pass # dispname Modified: tracker/roundup-src/roundup/mailer.py ============================================================================== --- tracker/roundup-src/roundup/mailer.py (original) +++ tracker/roundup-src/roundup/mailer.py Sat Apr 25 10:59:43 2009 @@ -214,6 +214,7 @@ # start the TLS if requested if config["MAIL_TLS"]: + self.ehlo() self.starttls(config["MAIL_TLS_KEYFILE"], config["MAIL_TLS_CERTFILE"]) Modified: tracker/roundup-src/setup.py ============================================================================== --- tracker/roundup-src/setup.py (original) +++ tracker/roundup-src/setup.py Sat Apr 25 10:59:43 2009 @@ -101,33 +101,17 @@ description="A simple-to-use and -install issue-tracking system" " with command-line, web and e-mail interfaces. Highly" " customisable.", - long_description= -'''In this release -=============== - -1.4.7 is primarily a bugfix release which contains important security -fixes: - -- a number of security issues were discovered by Daniel Diniz -- EditCSV and ExportCSV altered to include permission checks -- HTTP POST required on actions which alter data -- HTML file uploads served as application/octet-stream -- Handle Unauthorised in file serving correctly -- New item action reject creation of new users -- Item retirement was not being controlled -- Roundup is now compatible with Python 2.6 -- Improved French and German translations -- Improve consistency of item sorting in HTML interface -- Various other small bug fixes, robustification and optimisation - -Though some new features made it in also: - -- Provide a "no selection" option in web interface selection widgets -- Debug logging now uses the logging module rather than print -- Allow CGI frontend to serve XMLRPC requests. -- Added XMLRPC actions, as well as bridging CGI actions to XMLRPC actions. -- Optimized large file serving via mod_python / sendfile(). -- Support resuming downloads for (large) files. + long_description=''' +1.4.8 fixes some regressions: + +- bug introduced into hyperdb filter (issue 2550505) +- bug introduced into CVS export and view (issue 2550529) +- bugs introduced in the migration to the email package (issue 2550531) + +And adds a couple of other fixes: + +- handle bogus pagination values (issue 2550530) +- fix TLS handling with some SMTP servers (issues 2484879 and 1912923) If you're upgrading from an older version of Roundup you *must* follow the "Software Upgrade" guidelines given in the maintenance documentation. Modified: tracker/roundup-src/share/roundup/templates/classic/html/issue.item.html ============================================================================== --- tracker/roundup-src/share/roundup/templates/classic/html/issue.item.html (original) +++ tracker/roundup-src/share/roundup/templates/classic/html/issue.item.html Sat Apr 25 10:59:43 2009 @@ -151,7 +151,7 @@ tal:attributes="href string:file${file/id}">edit
- @@ -172,7 +172,7 @@ Date: - Modified: tracker/roundup-src/share/roundup/templates/classic/html/user.index.html ============================================================================== --- tracker/roundup-src/share/roundup/templates/classic/html/user.index.html (original) +++ tracker/roundup-src/share/roundup/templates/classic/html/user.index.html Sat Apr 25 10:59:43 2009 @@ -34,7 +34,7 @@     - Modified: tracker/roundup-src/test/test_cgi.py ============================================================================== --- tracker/roundup-src/test/test_cgi.py (original) +++ tracker/roundup-src/test/test_cgi.py Sat Apr 25 10:59:43 2009 @@ -10,7 +10,7 @@ # # $Id: test_cgi.py,v 1.36 2008-08-07 06:12:57 richard Exp $ -import unittest, os, shutil, errno, sys, difflib, cgi, re +import unittest, os, shutil, errno, sys, difflib, cgi, re, StringIO from roundup.cgi import client, actions, exceptions from roundup.cgi.exceptions import FormError @@ -18,6 +18,8 @@ from roundup.cgi.form_parser import FormParser from roundup import init, instance, password, hyperdb, date +from mocknull import MockNull + import db_test_base NEEDS_INSTANCE = 1 @@ -614,13 +616,13 @@ # SECURITY # # XXX test all default permissions - def _make_client(self, form, classname='user', nodeid='2', userid='2'): + def _make_client(self, form, classname='user', nodeid='1', userid='2'): cl = client.Client(self.instance, None, {'PATH_INFO':'/', 'REQUEST_METHOD':'POST'}, makeForm(form)) cl.classname = 'user' - cl.nodeid = '1' + cl.nodeid = nodeid cl.db = self.db - cl.userid = '2' + cl.userid = userid cl.language = ('en',) return cl @@ -646,6 +648,33 @@ self.failUnlessRaises(exceptions.Unauthorised, actions.EditItemAction(cl).handle) + def testCSVExport(self): + cl = self._make_client({'@columns': 'id,name'}, nodeid=None, + userid='1') + cl.classname = 'status' + output = StringIO.StringIO() + cl.request = MockNull() + cl.request.wfile = output + actions.ExportCSVAction(cl).handle() + self.assertEquals('id,name\r\n1,unread\r\n2,deferred\r\n3,chatting\r\n' + '4,need-eg\r\n5,in-progress\r\n6,testing\r\n7,done-cbb\r\n' + '8,resolved\r\n', + output.getvalue()) + + def testCSVExportFailPermission(self): + cl = self._make_client({'@columns': 'id,email,password'}, nodeid=None, + userid='2') + cl.classname = 'user' + output = StringIO.StringIO() + cl.request = MockNull() + cl.request.wfile = output + self.assertRaises(exceptions.Unauthorised, + actions.ExportCSVAction(cl).handle) + + +def test_suite(): + suite = unittest.TestSuite() + def test_suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(FormTestCase)) From python-checkins at python.org Sat Apr 25 11:01:14 2009 From: python-checkins at python.org (martin.v.loewis) Date: Sat, 25 Apr 2009 11:01:14 +0200 (CEST) Subject: [Python-checkins] r71866 - in tracker/instances/python-dev: detectors/nosyreaction.py html/_generic.help-list.html html/_generic.help.html html/issue.item.html html/user.index.html Message-ID: <20090425090114.18C361E40F1@bag.python.org> Author: martin.v.loewis Date: Sat Apr 25 11:01:13 2009 New Revision: 71866 Log: Issue #270: Upgrade to Roundup 1.4.8. Modified: tracker/instances/python-dev/detectors/nosyreaction.py tracker/instances/python-dev/html/_generic.help-list.html tracker/instances/python-dev/html/_generic.help.html tracker/instances/python-dev/html/issue.item.html tracker/instances/python-dev/html/user.index.html Modified: tracker/instances/python-dev/detectors/nosyreaction.py ============================================================================== --- tracker/instances/python-dev/detectors/nosyreaction.py (original) +++ tracker/instances/python-dev/detectors/nosyreaction.py Sat Apr 25 11:01:13 2009 @@ -1,11 +1,10 @@ -import sets from roundup import roundupdb, hyperdb def updatenosy(db, cl, nodeid, newvalues): '''Update the nosy list for changes to the assignee ''' # nodeid will be None if this is a new node - current_nosy = sets.Set() + current_nosy = set() if nodeid is None: ok = ('new', 'yes') else: @@ -26,7 +25,7 @@ continue current_nosy.add(value) - new_nosy = sets.Set(current_nosy) + new_nosy = set(current_nosy) # add assignee(s) to the nosy list if newvalues.has_key('assignee') and newvalues['assignee'] is not None: Modified: tracker/instances/python-dev/html/_generic.help-list.html ============================================================================== --- tracker/instances/python-dev/html/_generic.help-list.html (original) +++ tracker/instances/python-dev/html/_generic.help-list.html Sat Apr 25 11:01:13 2009 @@ -64,7 +64,7 @@ + tal:content="python:item[prop]">
+ tal:content="python:item[prop]">
+ tal:content="python:item[prop]">
- @@ -239,7 +239,7 @@ Date: - Modified: tracker/instances/python-dev/html/user.index.html ============================================================================== --- tracker/instances/python-dev/html/user.index.html (original) +++ tracker/instances/python-dev/html/user.index.html Sat Apr 25 11:01:13 2009 @@ -62,9 +62,13 @@       - retire + + + + + +
msg (view) + - (view) Author: () Date: Author: kurt.kaiser Date: Mon Apr 27 07:36:55 2009 New Revision: 71998 Log: Use of 'filter' in keybindingDialog.py was causing custom key assignment to fail. Patch 5707 amaury.forgeotdarc. Modified: python/branches/py3k/Lib/idlelib/NEWS.txt python/branches/py3k/Lib/idlelib/keybindingDialog.py Modified: python/branches/py3k/Lib/idlelib/NEWS.txt ============================================================================== --- python/branches/py3k/Lib/idlelib/NEWS.txt (original) +++ python/branches/py3k/Lib/idlelib/NEWS.txt Mon Apr 27 07:36:55 2009 @@ -3,6 +3,9 @@ *Release date: XX-XXX-09* +- Use of 'filter' in keybindingDialog.py was causing custom key assignment to + fail. Patch 5707 amaury.forgeotdarc. + What's New in IDLE 3.1a1? ========================= Modified: python/branches/py3k/Lib/idlelib/keybindingDialog.py ============================================================================== --- python/branches/py3k/Lib/idlelib/keybindingDialog.py (original) +++ python/branches/py3k/Lib/idlelib/keybindingDialog.py Mon Apr 27 07:36:55 2009 @@ -168,7 +168,7 @@ def GetModifiers(self): modList = [variable.get() for variable in self.modifier_vars] - return filter(None, modList) + return [mod for mod in modList if mod] def ClearKeySeq(self): self.listKeysFinal.select_clear(0,END) From python-checkins at python.org Mon Apr 27 07:43:17 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Mon, 27 Apr 2009 07:43:17 +0200 (CEST) Subject: [Python-checkins] r71999 - in python/branches/py3k: Doc/c-api/allocation.rst Doc/c-api/gcsupport.rst Doc/c-api/list.rst Doc/c-api/marshal.rst Doc/c-api/objbuffer.rst Doc/c-api/sequence.rst Doc/c-api/tuple.rst Doc/c-api/typeobj.rst Doc/c-api/unicode.rst Message-ID: <20090427054317.874FD1E400C@bag.python.org> Author: jeroen.ruigrok Date: Mon Apr 27 07:43:17 2009 New Revision: 71999 Log: Merged revisions 71920-71923,71925-71929,71931-71934,71937 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71920 | jeroen.ruigrok | 2009-04-25 21:44:55 +0200 (za, 25 apr 2009) | 5 lines Issue #4129: More documentation pointers about int -> Py_ssize_t. Also fix up the documentation for PyObject_GC_Resize(). It seems that since it first got documented, the documentation was actually for _PyObject_GC_Resize(). ........ r71921 | jeroen.ruigrok | 2009-04-25 21:46:19 +0200 (za, 25 apr 2009) | 2 lines Issue #4129: Documentation notes for int -> Py_ssize_t changes. ........ r71922 | jeroen.ruigrok | 2009-04-25 21:49:05 +0200 (za, 25 apr 2009) | 2 lines Reformat, since I've been busy here anyway. ........ r71923 | jeroen.ruigrok | 2009-04-25 21:54:34 +0200 (za, 25 apr 2009) | 2 lines Issue #4129: Add a versionchanged notice for a few forgotten entries. ........ r71925 | jeroen.ruigrok | 2009-04-25 22:37:39 +0200 (za, 25 apr 2009) | 2 lines Since it's a macro, actually refer to it as such instead of function. ........ r71926 | jeroen.ruigrok | 2009-04-25 22:40:10 +0200 (za, 25 apr 2009) | 2 lines Reformat prior to editing. ........ r71927 | jeroen.ruigrok | 2009-04-25 22:41:40 +0200 (za, 25 apr 2009) | 2 lines Issue #4129: int -> Py_ssize_t documentation. ........ r71928 | jeroen.ruigrok | 2009-04-25 22:43:30 +0200 (za, 25 apr 2009) | 2 lines Reformat prior to editing. ........ r71929 | jeroen.ruigrok | 2009-04-25 22:44:58 +0200 (za, 25 apr 2009) | 2 lines Issue #4129: int -> Py_ssize_t documentation. ........ r71931 | jeroen.ruigrok | 2009-04-25 22:50:27 +0200 (za, 25 apr 2009) | 2 lines Issue #4129: int -> Py_ssize_t documentation. ........ r71932 | jeroen.ruigrok | 2009-04-25 22:55:39 +0200 (za, 25 apr 2009) | 2 lines Issue #4129: more int -> Py_ssize_t documentation. ........ r71933 | jeroen.ruigrok | 2009-04-25 22:58:35 +0200 (za, 25 apr 2009) | 2 lines Issue #4129: more int -> Py_ssize_t documentation. ........ r71934 | jeroen.ruigrok | 2009-04-25 23:02:34 +0200 (za, 25 apr 2009) | 2 lines Issue #4129: field changed from int to Py_ssize_t. ........ r71937 | jeroen.ruigrok | 2009-04-25 23:16:05 +0200 (za, 25 apr 2009) | 2 lines Issue #4129: document int -> Py_ssize_t changes. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/allocation.rst python/branches/py3k/Doc/c-api/gcsupport.rst python/branches/py3k/Doc/c-api/list.rst python/branches/py3k/Doc/c-api/marshal.rst python/branches/py3k/Doc/c-api/objbuffer.rst python/branches/py3k/Doc/c-api/sequence.rst python/branches/py3k/Doc/c-api/tuple.rst python/branches/py3k/Doc/c-api/typeobj.rst python/branches/py3k/Doc/c-api/unicode.rst Modified: python/branches/py3k/Doc/c-api/allocation.rst ============================================================================== --- python/branches/py3k/Doc/c-api/allocation.rst (original) +++ python/branches/py3k/Doc/c-api/allocation.rst Mon Apr 27 07:43:17 2009 @@ -30,6 +30,10 @@ This does everything :cfunc:`PyObject_Init` does, and also initializes the length information for a variable-size object. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: TYPE* PyObject_New(TYPE, PyTypeObject *type) @@ -51,6 +55,10 @@ fields into the same allocation decreases the number of allocations, improving the memory management efficiency. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: void PyObject_Del(PyObject *op) Modified: python/branches/py3k/Doc/c-api/gcsupport.rst ============================================================================== --- python/branches/py3k/Doc/c-api/gcsupport.rst (original) +++ python/branches/py3k/Doc/c-api/gcsupport.rst Mon Apr 27 07:43:17 2009 @@ -45,12 +45,20 @@ Analogous to :cfunc:`PyObject_NewVar` but for container objects with the :const:`Py_TPFLAGS_HAVE_GC` flag set. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. -.. cfunction:: PyVarObject * PyObject_GC_Resize(PyVarObject *op, Py_ssize_t) + +.. cfunction:: TYPE* PyObject_GC_Resize(TYPE, PyVarObject *op, Py_ssize_t newsize) Resize an object allocated by :cfunc:`PyObject_NewVar`. Returns the resized object or *NULL* on failure. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *newsize*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: void PyObject_GC_Track(PyObject *op) 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 Mon Apr 27 07:43:17 2009 @@ -17,8 +17,9 @@ .. index:: single: ListType (in module types) - This instance of :ctype:`PyTypeObject` represents the Python list type. This is - the same object as ``list`` and ``types.ListType`` in the Python layer. + This instance of :ctype:`PyTypeObject` represents the Python list type. + This is the same object as ``list`` and ``types.ListType`` in the Python + layer. .. cfunction:: int PyList_Check(PyObject *p) @@ -29,8 +30,8 @@ .. cfunction:: int PyList_CheckExact(PyObject *p) - Return true if *p* is a list object, but not an instance of a subtype of the - list type. + Return true if *p* is a list object, but not an instance of a subtype of + the list type. .. cfunction:: PyObject* PyList_New(Py_ssize_t len) @@ -39,10 +40,10 @@ .. note:: - If *length* is greater than zero, the returned list object's items are set to - ``NULL``. Thus you cannot use abstract API functions such as - :cfunc:`PySequence_SetItem` or expose the object to Python code before setting - all items to a real object with :cfunc:`PyList_SetItem`. + If *length* is greater than zero, the returned list object's items are + set to ``NULL``. Thus you cannot use abstract API functions such as + :cfunc:`PySequence_SetItem` or expose the object to Python code before + setting all items to a real object with :cfunc:`PyList_SetItem`. .. versionchanged:: 2.5 This function used an :ctype:`int` for *size*. This might require @@ -65,12 +66,17 @@ Macro form of :cfunc:`PyList_Size` without error checking. + .. versionchanged:: 2.5 + This macro returned an :ctype:`int`. This might require changes in your + code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index) - Return the object at position *pos* in the list pointed to by *p*. 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 :exc:`IndexError` exception. + Return the object at position *pos* in the list pointed to by *p*. 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 + :exc:`IndexError` exception. .. versionchanged:: 2.5 This function used an :ctype:`int` for *index*. This might require @@ -81,16 +87,20 @@ Macro form of :cfunc:`PyList_GetItem` without error checking. + .. versionchanged:: 2.5 + This macro used an :ctype:`int` for *i*. This might require changes in + your code for properly supporting 64-bit systems. + .. cfunction:: int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item) - Set the item at index *index* in list to *item*. Return ``0`` on success or - ``-1`` on failure. + Set the item at index *index* in list to *item*. Return ``0`` on success + or ``-1`` on failure. .. note:: - This function "steals" a reference to *item* and discards a reference to an item - already in the list at the affected position. + This function "steals" a reference to *item* and discards a reference to + an item already in the list at the affected position. .. versionchanged:: 2.5 This function used an :ctype:`int` for *index*. This might require @@ -99,21 +109,26 @@ .. cfunction:: void PyList_SET_ITEM(PyObject *list, Py_ssize_t i, PyObject *o) - Macro form of :cfunc:`PyList_SetItem` without error checking. This is normally - only used to fill in new lists where there is no previous content. + Macro form of :cfunc:`PyList_SetItem` without error checking. This is + normally only used to fill in new lists where there is no previous content. .. note:: - This function "steals" a reference to *item*, and, unlike - :cfunc:`PyList_SetItem`, does *not* discard a reference to any item that it - being replaced; any reference in *list* at position *i* will be leaked. + This macro "steals" a reference to *item*, and, unlike + :cfunc:`PyList_SetItem`, does *not* discard a reference to any item that + is being replaced; any reference in *list* at position *i* will be + leaked. + + .. versionchanged:: 2.5 + This macro used an :ctype:`int` for *i*. This might require + changes in your code for properly supporting 64-bit systems. .. cfunction:: int PyList_Insert(PyObject *list, Py_ssize_t index, PyObject *item) - Insert the item *item* into list *list* in front of index *index*. Return ``0`` - if successful; return ``-1`` and set an exception if unsuccessful. Analogous to - ``list.insert(index, item)``. + Insert the item *item* into list *list* in front of index *index*. Return + ``0`` if successful; return ``-1`` and set an exception if unsuccessful. + Analogous to ``list.insert(index, item)``. .. versionchanged:: 2.5 This function used an :ctype:`int` for *index*. This might require @@ -122,16 +137,16 @@ .. cfunction:: int PyList_Append(PyObject *list, PyObject *item) - Append the object *item* at the end of list *list*. Return ``0`` if successful; - return ``-1`` and set an exception if unsuccessful. Analogous to - ``list.append(item)``. + Append the object *item* at the end of list *list*. Return ``0`` if + successful; return ``-1`` and set an exception if unsuccessful. Analogous + to ``list.append(item)``. .. cfunction:: PyObject* PyList_GetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high) - Return a list of the objects in *list* containing the objects *between* *low* - and *high*. Return *NULL* and set an exception if unsuccessful. Analogous to - ``list[low:high]``. + Return a list of the objects in *list* containing the objects *between* + *low* and *high*. Return *NULL* and set an exception if unsuccessful. + Analogous to ``list[low:high]``. .. versionchanged:: 2.5 This function used an :ctype:`int` for *low* and *high*. This might @@ -140,10 +155,10 @@ .. cfunction:: int PyList_SetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high, PyObject *itemlist) - Set the slice of *list* between *low* and *high* to the contents of *itemlist*. - Analogous to ``list[low:high] = itemlist``. The *itemlist* may be *NULL*, - indicating the assignment of an empty list (slice deletion). Return ``0`` on - success, ``-1`` on failure. + Set the slice of *list* between *low* and *high* to the contents of + *itemlist*. Analogous to ``list[low:high] = itemlist``. The *itemlist* may + be *NULL*, indicating the assignment of an empty list (slice deletion). + Return ``0`` on success, ``-1`` on failure. .. versionchanged:: 2.5 This function used an :ctype:`int` for *low* and *high*. This might @@ -152,8 +167,8 @@ .. cfunction:: int PyList_Sort(PyObject *list) - Sort the items of *list* in place. Return ``0`` on success, ``-1`` on failure. - This is equivalent to ``list.sort()``. + Sort the items of *list* in place. Return ``0`` on success, ``-1`` on + failure. This is equivalent to ``list.sort()``. .. cfunction:: int PyList_Reverse(PyObject *list) Modified: python/branches/py3k/Doc/c-api/marshal.rst ============================================================================== --- python/branches/py3k/Doc/c-api/marshal.rst (original) +++ python/branches/py3k/Doc/c-api/marshal.rst Mon Apr 27 07:43:17 2009 @@ -5,24 +5,25 @@ Data marshalling support ======================== -These routines allow C code to work with serialized objects using the same data -format as the :mod:`marshal` module. There are functions to write data into the -serialization format, and additional functions that can be used to read the data -back. Files used to store marshalled data must be opened in binary mode. +These routines allow C code to work with serialized objects using the same +data format as the :mod:`marshal` module. There are functions to write data +into the serialization format, and additional functions that can be used to +read the data back. Files used to store marshalled data must be opened in +binary mode. Numeric values are stored with the least significant byte first. -The module supports two versions of the data format: version 0 is the historical -version, version 1 shares interned strings in the file, and upon unmarshalling. -Version 2 uses a binary format for floating point numbers. +The module supports two versions of the data format: version 0 is the +historical version, version 1 shares interned strings in the file, and upon +unmarshalling. Version 2 uses a binary format for floating point numbers. *Py_MARSHAL_VERSION* indicates the current file format (currently 2). .. cfunction:: void PyMarshal_WriteLongToFile(long value, FILE *file, int version) - Marshal a :ctype:`long` integer, *value*, to *file*. This will only write the - least-significant 32 bits of *value*; regardless of the size of the native - :ctype:`long` type. *version* indicates the file format. + Marshal a :ctype:`long` integer, *value*, to *file*. This will only write + the least-significant 32 bits of *value*; regardless of the size of the + native :ctype:`long` type. *version* indicates the file format. .. cfunction:: void PyMarshal_WriteObjectToFile(PyObject *value, FILE *file, int version) @@ -40,24 +41,24 @@ The following functions allow marshalled values to be read back in. XXX What about error detection? It appears that reading past the end of the -file will always result in a negative numeric value (where that's relevant), but -it's not clear that negative values won't be handled properly when there's no -error. What's the right way to tell? Should only non-negative values be written -using these routines? +file will always result in a negative numeric value (where that's relevant), +but it's not clear that negative values won't be handled properly when there's +no error. What's the right way to tell? Should only non-negative values be +written using these routines? .. cfunction:: long PyMarshal_ReadLongFromFile(FILE *file) - Return a C :ctype:`long` from the data stream in a :ctype:`FILE\*` opened for - reading. Only a 32-bit value can be read in using this function, regardless of - the native size of :ctype:`long`. + Return a C :ctype:`long` from the data stream in a :ctype:`FILE\*` opened + for reading. Only a 32-bit value can be read in using this function, + regardless of the native size of :ctype:`long`. .. cfunction:: int PyMarshal_ReadShortFromFile(FILE *file) - Return a C :ctype:`short` from the data stream in a :ctype:`FILE\*` opened for - reading. Only a 16-bit value can be read in using this function, regardless of - the native size of :ctype:`short`. + Return a C :ctype:`short` from the data stream in a :ctype:`FILE\*` opened + for reading. Only a 16-bit value can be read in using this function, + regardless of the native size of :ctype:`short`. .. cfunction:: PyObject* PyMarshal_ReadObjectFromFile(FILE *file) @@ -70,17 +71,22 @@ .. cfunction:: PyObject* PyMarshal_ReadLastObjectFromFile(FILE *file) Return a Python object from the data stream in a :ctype:`FILE\*` opened for - reading. Unlike :cfunc:`PyMarshal_ReadObjectFromFile`, this function assumes - that no further objects will be read from the file, allowing it to aggressively - load file data into memory so that the de-serialization can operate from data in - memory rather than reading a byte at a time from the file. Only use these - variant if you are certain that you won't be reading anything else from the - file. On error, sets the appropriate exception (:exc:`EOFError` or - :exc:`TypeError`) and returns *NULL*. + reading. Unlike :cfunc:`PyMarshal_ReadObjectFromFile`, this function + assumes that no further objects will be read from the file, allowing it to + aggressively load file data into memory so that the de-serialization can + operate from data in memory rather than reading a byte at a time from the + file. Only use these variant if you are certain that you won't be reading + anything else from the file. On error, sets the appropriate exception + (:exc:`EOFError` or :exc:`TypeError`) and returns *NULL*. .. cfunction:: PyObject* PyMarshal_ReadObjectFromString(char *string, Py_ssize_t len) - Return a Python object from the data stream in a character buffer containing - *len* bytes pointed to by *string*. On error, sets the appropriate exception - (:exc:`EOFError` or :exc:`TypeError`) and returns *NULL*. + Return a Python object from the data stream in a character buffer + containing *len* bytes pointed to by *string*. On error, sets the + appropriate exception (:exc:`EOFError` or :exc:`TypeError`) and returns + *NULL*. + + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *len*. This might require + changes in your code for properly supporting 64-bit systems. Modified: python/branches/py3k/Doc/c-api/objbuffer.rst ============================================================================== --- python/branches/py3k/Doc/c-api/objbuffer.rst (original) +++ python/branches/py3k/Doc/c-api/objbuffer.rst Mon Apr 27 07:43:17 2009 @@ -10,17 +10,26 @@ Returns a pointer to a read-only memory location usable as character-based input. The *obj* argument must support the single-segment character buffer - interface. On success, returns ``0``, sets *buffer* to the memory location and - *buffer_len* to the buffer length. Returns ``-1`` and sets a :exc:`TypeError` - on error. + interface. On success, returns ``0``, sets *buffer* to the memory location + and *buffer_len* to the buffer length. Returns ``-1`` and sets a + :exc:`TypeError` on error. + + .. versionchanged:: 2.5 + This function used an :ctype:`int *` type for *buffer_len*. This might + require changes in your code for properly supporting 64-bit systems. .. cfunction:: int PyObject_AsReadBuffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len) - Returns a pointer to a read-only memory location containing arbitrary data. The - *obj* argument must support the single-segment readable buffer interface. On - success, returns ``0``, sets *buffer* to the memory location and *buffer_len* to - the buffer length. Returns ``-1`` and sets a :exc:`TypeError` on error. + Returns a pointer to a read-only memory location containing arbitrary data. + The *obj* argument must support the single-segment readable buffer + interface. On success, returns ``0``, sets *buffer* to the memory location + and *buffer_len* to the buffer length. Returns ``-1`` and sets a + :exc:`TypeError` on error. + + .. versionchanged:: 2.5 + This function used an :ctype:`int *` type for *buffer_len*. This might + require changes in your code for properly supporting 64-bit systems. .. cfunction:: int PyObject_CheckReadBuffer(PyObject *o) @@ -32,6 +41,11 @@ .. cfunction:: int PyObject_AsWriteBuffer(PyObject *obj, void **buffer, Py_ssize_t *buffer_len) Returns a pointer to a writable memory location. The *obj* argument must - support the single-segment, character buffer interface. On success, returns - ``0``, sets *buffer* to the memory location and *buffer_len* to the buffer - length. Returns ``-1`` and sets a :exc:`TypeError` on error. + support the single-segment, character buffer interface. On success, + returns ``0``, sets *buffer* to the memory location and *buffer_len* to the + buffer length. Returns ``-1`` and sets a :exc:`TypeError` on error. + + .. versionchanged:: 2.5 + This function used an :ctype:`int *` type for *buffer_len*. This might + require changes in your code for properly supporting 64-bit systems. + Modified: python/branches/py3k/Doc/c-api/sequence.rst ============================================================================== --- python/branches/py3k/Doc/c-api/sequence.rst (original) +++ python/branches/py3k/Doc/c-api/sequence.rst Mon Apr 27 07:43:17 2009 @@ -178,6 +178,10 @@ Return the *i*th element of *o*, assuming that *o* was returned by :cfunc:`PySequence_Fast`, *o* is not *NULL*, and that *i* is within bounds. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject** PySequence_Fast_ITEMS(PyObject *o) @@ -196,6 +200,10 @@ :cfunc:`PySequence_Check(o)` is true and without adjustment for negative indices. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PySequence_Fast_GET_SIZE(PyObject *o) Modified: python/branches/py3k/Doc/c-api/tuple.rst ============================================================================== --- python/branches/py3k/Doc/c-api/tuple.rst (original) +++ python/branches/py3k/Doc/c-api/tuple.rst Mon Apr 27 07:43:17 2009 @@ -67,6 +67,10 @@ Return the size of the tuple *p*, which must be non-*NULL* and point to a tuple; no error checking is performed. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyTuple_GetItem(PyObject *p, Py_ssize_t pos) @@ -82,6 +86,10 @@ Like :cfunc:`PyTuple_GetItem`, but does no checking of its arguments. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *pos*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyTuple_GetSlice(PyObject *p, Py_ssize_t low, Py_ssize_t high) @@ -116,6 +124,10 @@ This function "steals" a reference to *o*. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *pos*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: int _PyTuple_Resize(PyObject **p, Py_ssize_t newsize) 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 Apr 27 07:43:17 2009 @@ -64,6 +64,10 @@ This field is not inherited by subtypes. + .. versionchanged:: 2.5 + This field used to be an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cmember:: PyTypeObject* PyObject.ob_type 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 Mon Apr 27 07:43:17 2009 @@ -65,12 +65,20 @@ Return the size of the object. *o* has to be a :ctype:`PyUnicodeObject` (not checked). + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PyUnicode_GET_DATA_SIZE(PyObject *o) Return the size of the object's internal buffer in bytes. *o* has to be a :ctype:`PyUnicodeObject` (not checked). + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: Py_UNICODE* PyUnicode_AS_UNICODE(PyObject *o) @@ -206,6 +214,9 @@ Therefore, modification of the resulting Unicode object is only allowed when *u* is *NULL*. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. .. cfunction:: PyObject* PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size) @@ -317,6 +328,10 @@ Return the length of the Unicode object. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_FromEncodedObject(PyObject *obj, const char *encoding, const char *errors) @@ -355,6 +370,10 @@ using wcslen. Return *NULL* on failure. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode, wchar_t *w, Py_ssize_t size) @@ -366,6 +385,11 @@ to make sure that the :ctype:`wchar_t` string is 0-terminated in case this is required by the application. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type and used an :ctype:`int` + type for *size*. This might require changes in your code for properly + supporting 64-bit systems. + .. _builtincodecs: @@ -405,6 +429,10 @@ using the Python codec registry. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_Encode(const Py_UNICODE *s, Py_ssize_t size, const char *encoding, const char *errors) @@ -414,6 +442,10 @@ to be used is looked up using the Python codec registry. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsEncodedString(PyObject *unicode, const char *encoding, const char *errors) @@ -433,6 +465,10 @@ Create a Unicode object by decoding *size* bytes of the UTF-8 encoded string *s*. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_DecodeUTF8Stateful(const char *s, Py_ssize_t size, const char *errors, Py_ssize_t *consumed) @@ -441,6 +477,10 @@ treated as an error. Those bytes will not be decoded and the number of bytes that have been decoded will be stored in *consumed*. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_EncodeUTF8(const Py_UNICODE *s, Py_ssize_t size, const char *errors) @@ -448,6 +488,10 @@ return a Python bytes object. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsUTF8String(PyObject *unicode) @@ -547,6 +591,10 @@ Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_DecodeUTF16Stateful(const char *s, Py_ssize_t size, const char *errors, int *byteorder, Py_ssize_t *consumed) @@ -556,6 +604,11 @@ split surrogate pair) as an error. Those bytes will not be decoded and the number of bytes that have been decoded will be stored in *consumed*. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size* and an :ctype:`int *` + type for *consumed*. This might require changes in your code for + properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_EncodeUTF16(const Py_UNICODE *s, Py_ssize_t size, const char *errors, int byteorder) @@ -576,6 +629,10 @@ Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsUTF16String(PyObject *unicode) @@ -593,6 +650,10 @@ Create a Unicode object by decoding *size* bytes of the Unicode-Escape encoded string *s*. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size) @@ -600,6 +661,10 @@ return a Python string object. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsUnicodeEscapeString(PyObject *unicode) @@ -617,6 +682,10 @@ Create a Unicode object by decoding *size* bytes of the Raw-Unicode-Escape encoded string *s*. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size, const char *errors) @@ -624,6 +693,10 @@ and return a Python string object. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) @@ -642,6 +715,10 @@ Create a Unicode object by decoding *size* bytes of the Latin-1 encoded string *s*. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_EncodeLatin1(const Py_UNICODE *s, Py_ssize_t size, const char *errors) @@ -649,6 +726,10 @@ return a Python bytes object. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsLatin1String(PyObject *unicode) @@ -667,6 +748,10 @@ Create a Unicode object by decoding *size* bytes of the ASCII encoded string *s*. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_EncodeASCII(const Py_UNICODE *s, Py_ssize_t size, const char *errors) @@ -674,6 +759,10 @@ return a Python bytes object. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsASCIIString(PyObject *unicode) @@ -716,6 +805,10 @@ Byte values greater that the length of the string and U+FFFE "characters" are treated as "undefined mapping". + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_EncodeCharmap(const Py_UNICODE *s, Py_ssize_t size, PyObject *mapping, const char *errors) @@ -723,6 +816,10 @@ *mapping* object and return a Python string object. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsCharmapString(PyObject *unicode, PyObject *mapping) @@ -746,6 +843,10 @@ and sequences work well. Unmapped character ordinals (ones which cause a :exc:`LookupError`) are left untouched and are copied as-is. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + These are the MBCS codec APIs. They are currently only available on Windows and use the Win32 MBCS converters to implement the conversions. Note that MBCS (or DBCS) is a class of encodings, not just one. The target encoding is defined by @@ -759,6 +860,10 @@ Create a Unicode object by decoding *size* bytes of the MBCS encoded string *s*. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_DecodeMBCSStateful(const char *s, int size, const char *errors, int *consumed) @@ -774,6 +879,10 @@ a Python bytes object. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsMBCSString(PyObject *unicode) @@ -808,6 +917,10 @@ separator. At most *maxsplit* splits will be done. If negative, no limit is set. Separators are not included in the resulting list. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *maxsplit*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_Splitlines(PyObject *s, int keepend) @@ -844,6 +957,11 @@ (*direction* == -1 means to do a prefix match, *direction* == 1 a suffix match), 0 otherwise. Return ``-1`` if an error occurred. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *start* and *end*. This + might require changes in your code for properly supporting 64-bit + systems. + .. cfunction:: Py_ssize_t PyUnicode_Find(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction) @@ -853,12 +971,22 @@ ``-1`` indicates that no match was found, and ``-2`` indicates that an error occurred and an exception has been set. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *start* and *end*. This + might require changes in your code for properly supporting 64-bit + systems. + .. cfunction:: Py_ssize_t PyUnicode_Count(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end) Return the number of non-overlapping occurrences of *substr* in ``str[start:end]``. Return ``-1`` if an error occurred. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type and used an :ctype:`int` + type for *start* and *end*. This might require changes in your code for + properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_Replace(PyObject *str, PyObject *substr, PyObject *replstr, Py_ssize_t maxcount) @@ -866,6 +994,10 @@ return the resulting Unicode object. *maxcount* == -1 means replace all occurrences. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *maxcount*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyUnicode_Compare(PyObject *left, PyObject *right) From buildbot at python.org Mon Apr 27 07:52:57 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 27 Apr 2009 05:52:57 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 3.x Message-ID: <20090427055257.D19F51E400C@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%203.x/builds/705 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: kurt.kaiser BUILD FAILED: failed test Excerpt from the test logfile: make: *** [buildbottest] Unknown signal 32 sincerely, -The Buildbot From buildbot at python.org Mon Apr 27 08:03:18 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 27 Apr 2009 06:03:18 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 3.x Message-ID: <20090427060318.5D5BA1E417C@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%203.x/builds/822 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: jeroen.ruigrok BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_time ====================================================================== FAIL: test_tzset (test.test_time.TimeTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_time.py", line 166, in test_tzset self.failIfEqual(time.gmtime(xmas2002), time.localtime(xmas2002)) AssertionError: time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) == time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 27 08:13:55 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 08:13:55 +0200 (CEST) Subject: [Python-checkins] r72000 - python/branches/py3k/Doc/library/functions.rst Message-ID: <20090427061355.CFF911E403F@bag.python.org> Author: georg.brandl Date: Mon Apr 27 08:13:55 2009 New Revision: 72000 Log: #5061: improve open() docs a bit. 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 Mon Apr 27 08:13:55 2009 @@ -676,38 +676,39 @@ *closefd* is set to ``False``.) *mode* is an optional string that specifies the mode in which the file is - opened. It defaults to ``'r'`` which means open for reading in text mode. - Other common values are ``'w'`` for writing (truncating the file if it - already exists), and ``'a'`` for appending (which on *some* Unix systems, - means that *all* writes append to the end of the file regardless of the - current seek position). In text mode, if *encoding* is not specified the - encoding used is platform dependent. (For reading and writing raw bytes use - binary mode and leave *encoding* unspecified.) The available modes are: + opened. The available modes are: ========= =============================================================== Character Meaning --------- --------------------------------------------------------------- ``'r'`` open for reading (default) - ``'w'`` open for writing, truncating the file first + ``'w'`` open for writing, truncating the file first if it exists ``'a'`` open for writing, appending to the end of the file if it exists - ``'b'`` binary mode + ========= =============================================================== + + Several characters can be appended that modify the given mode: + + ========= =============================================================== ``'t'`` text mode (default) - ``'+'`` open a disk file for updating (reading and writing) + ``'b'`` binary mode + ``'+'`` open for updating (reading and writing) ``'U'`` universal newline mode (for backwards compatibility; should not be used in new code) ========= =============================================================== - The default mode is ``'rt'`` (open for reading text). For binary random - access, the mode ``'w+b'`` opens and truncates the file to 0 bytes, while - ``'r+b'`` opens the file without truncation. + The mode ``'w+'`` opens and truncates the file to 0 bytes, while ``'r+'`` + opens the file without truncation. On *some* Unix systems, append mode means + that *all* writes append to the end of the file regardless of the current + seek position. Python distinguishes between files opened in binary and text modes, even when the underlying operating system doesn't. Files opened in binary mode (including ``'b'`` in the *mode* argument) return contents as ``bytes`` objects without any decoding. In text mode (the default, or when ``'t'`` is included in the *mode* argument), the contents of the file are returned as - strings, the bytes having been first decoded using a platform-dependent - encoding or using the specified *encoding* if given. + strings, the bytes having been first decoded using the specified *encoding*. + If *encoding* is not specified, a platform-dependent default encoding is + used, see below. *buffering* is an optional integer used to set the buffering policy. By default full buffering is on. Pass 0 to switch buffering off (only allowed From buildbot at python.org Mon Apr 27 08:17:26 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 27 Apr 2009 06:17:26 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090427061726.AF9AE1E4036@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/648 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: kurt.kaiser BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_os test_time make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Mon Apr 27 09:05:23 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 27 Apr 2009 07:05:23 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090427070523.523651E4036@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/584 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: jeroen.ruigrok BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_importlib test_posix Traceback (most recent call last): File "./Lib/test/regrtest.py", line 620, in runtest_inner File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_importlib.py", line 6, in test_main run_unittest(importlib.test.test_suite('importlib.test')) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/__init__.py", line 22, in test_suite package_tests = getattr(sys.modules[package_name], 'test_suite')() File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/source/__init__.py", line 8, in test_suite return importlib.test.test_suite('importlib.test.source', directory) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/__init__.py", line 16, in test_suite __import__(module_name, level=0) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/source/test_case_sensitivity.py", line 12, in class CaseSensitivityTest(unittest.TestCase): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/util.py", line 13, in case_insensitive_tests original_name = os.listdir('.')[0] IndexError: list index out of range ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 251, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 177, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Mon Apr 27 10:07:12 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Mon, 27 Apr 2009 10:07:12 +0200 (CEST) Subject: [Python-checkins] r72001 - in python/branches/py3k/Doc: c-api/allocation.rst c-api/arg.rst c-api/dict.rst c-api/gcsupport.rst c-api/list.rst c-api/long.rst c-api/mapping.rst c-api/marshal.rst c-api/objbuffer.rst c-api/object.rst c-api/sequence.rst c-api/set.rst c-api/slice.rst c-api/tuple.rst c-api/type.rst c-api/typeobj.rst c-api/unicode.rst distutils/setupscript.rst library/re.rst Message-ID: <20090427080712.A24FB1E4002@bag.python.org> Author: jeroen.ruigrok Date: Mon Apr 27 10:07:12 2009 New Revision: 72001 Log: After discussing some more with Georg, do no migrate versionchanged:: 2.5 to this branch. While I am here, also get rid of other versionchanged:: 2.x constructs, as discussed. Modified: python/branches/py3k/Doc/c-api/allocation.rst python/branches/py3k/Doc/c-api/arg.rst python/branches/py3k/Doc/c-api/dict.rst python/branches/py3k/Doc/c-api/gcsupport.rst python/branches/py3k/Doc/c-api/list.rst python/branches/py3k/Doc/c-api/long.rst python/branches/py3k/Doc/c-api/mapping.rst python/branches/py3k/Doc/c-api/marshal.rst python/branches/py3k/Doc/c-api/objbuffer.rst python/branches/py3k/Doc/c-api/object.rst python/branches/py3k/Doc/c-api/sequence.rst python/branches/py3k/Doc/c-api/set.rst python/branches/py3k/Doc/c-api/slice.rst python/branches/py3k/Doc/c-api/tuple.rst python/branches/py3k/Doc/c-api/type.rst python/branches/py3k/Doc/c-api/typeobj.rst python/branches/py3k/Doc/c-api/unicode.rst python/branches/py3k/Doc/distutils/setupscript.rst python/branches/py3k/Doc/library/re.rst Modified: python/branches/py3k/Doc/c-api/allocation.rst ============================================================================== --- python/branches/py3k/Doc/c-api/allocation.rst (original) +++ python/branches/py3k/Doc/c-api/allocation.rst Mon Apr 27 10:07:12 2009 @@ -11,10 +11,6 @@ .. cfunction:: PyVarObject* _PyObject_NewVar(PyTypeObject *type, Py_ssize_t size) - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyObject_Init(PyObject *op, PyTypeObject *type) @@ -30,10 +26,6 @@ This does everything :cfunc:`PyObject_Init` does, and also initializes the length information for a variable-size object. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: TYPE* PyObject_New(TYPE, PyTypeObject *type) @@ -55,10 +47,6 @@ fields into the same allocation decreases the number of allocations, improving the memory management efficiency. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: void PyObject_Del(PyObject *op) Modified: python/branches/py3k/Doc/c-api/arg.rst ============================================================================== --- python/branches/py3k/Doc/c-api/arg.rst (original) +++ python/branches/py3k/Doc/c-api/arg.rst Mon Apr 27 10:07:12 2009 @@ -406,10 +406,6 @@ PyArg_ParseTuple(args, "O|O:ref", &object, &callback) - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *min* and *max*. This might - require changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* Py_BuildValue(const char *format, ...) Modified: python/branches/py3k/Doc/c-api/dict.rst ============================================================================== --- python/branches/py3k/Doc/c-api/dict.rst (original) +++ python/branches/py3k/Doc/c-api/dict.rst Mon Apr 27 10:07:12 2009 @@ -140,10 +140,6 @@ Return the number of items in the dictionary. This is equivalent to ``len(p)`` on a dictionary. - .. versionchanged:: 2.5 - This function returned an :ctype:`int` type. This might require changes - in your code for properly supporting 64-bit systems. - .. cfunction:: int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) @@ -190,10 +186,6 @@ Py_DECREF(o); } - .. versionchanged:: 2.5 - This function used an :ctype:`int *` type for *ppos*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: int PyDict_Merge(PyObject *a, PyObject *b, int override) Modified: python/branches/py3k/Doc/c-api/gcsupport.rst ============================================================================== --- python/branches/py3k/Doc/c-api/gcsupport.rst (original) +++ python/branches/py3k/Doc/c-api/gcsupport.rst Mon Apr 27 10:07:12 2009 @@ -45,20 +45,12 @@ Analogous to :cfunc:`PyObject_NewVar` but for container objects with the :const:`Py_TPFLAGS_HAVE_GC` flag set. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: TYPE* PyObject_GC_Resize(TYPE, PyVarObject *op, Py_ssize_t newsize) Resize an object allocated by :cfunc:`PyObject_NewVar`. Returns the resized object or *NULL* on failure. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *newsize*. This might - require changes in your code for properly supporting 64-bit systems. - .. cfunction:: void PyObject_GC_Track(PyObject *op) 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 Mon Apr 27 10:07:12 2009 @@ -45,10 +45,6 @@ :cfunc:`PySequence_SetItem` or expose the object to Python code before setting all items to a real object with :cfunc:`PyList_SetItem`. - .. versionchanged:: 2.5 - This function used an :ctype:`int` for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: Py_ssize_t PyList_Size(PyObject *list) @@ -57,19 +53,11 @@ Return the length of the list object in *list*; this is equivalent to ``len(list)`` on a list object. - .. versionchanged:: 2.5 - This function returned an :ctype:`int`. This might require changes in - your code for properly supporting 64-bit systems. - .. cfunction:: Py_ssize_t PyList_GET_SIZE(PyObject *list) Macro form of :cfunc:`PyList_Size` without error checking. - .. versionchanged:: 2.5 - This macro returned an :ctype:`int`. This might require changes in your - code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index) @@ -78,19 +66,11 @@ supported. If *pos* is out of bounds, return *NULL* and set an :exc:`IndexError` exception. - .. versionchanged:: 2.5 - This function used an :ctype:`int` for *index*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyList_GET_ITEM(PyObject *list, Py_ssize_t i) Macro form of :cfunc:`PyList_GetItem` without error checking. - .. versionchanged:: 2.5 - This macro used an :ctype:`int` for *i*. This might require changes in - your code for properly supporting 64-bit systems. - .. cfunction:: int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item) @@ -102,10 +82,6 @@ This function "steals" a reference to *item* and discards a reference to an item already in the list at the affected position. - .. versionchanged:: 2.5 - This function used an :ctype:`int` for *index*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: void PyList_SET_ITEM(PyObject *list, Py_ssize_t i, PyObject *o) @@ -119,10 +95,6 @@ is being replaced; any reference in *list* at position *i* will be leaked. - .. versionchanged:: 2.5 - This macro used an :ctype:`int` for *i*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: int PyList_Insert(PyObject *list, Py_ssize_t index, PyObject *item) @@ -130,10 +102,6 @@ ``0`` if successful; return ``-1`` and set an exception if unsuccessful. Analogous to ``list.insert(index, item)``. - .. versionchanged:: 2.5 - This function used an :ctype:`int` for *index*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: int PyList_Append(PyObject *list, PyObject *item) @@ -148,10 +116,6 @@ *low* and *high*. Return *NULL* and set an exception if unsuccessful. Analogous to ``list[low:high]``. - .. versionchanged:: 2.5 - This function used an :ctype:`int` for *low* and *high*. This might - require changes in your code for properly supporting 64-bit systems. - .. cfunction:: int PyList_SetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high, PyObject *itemlist) @@ -160,10 +124,6 @@ be *NULL*, indicating the assignment of an empty list (slice deletion). Return ``0`` on success, ``-1`` on failure. - .. versionchanged:: 2.5 - This function used an :ctype:`int` for *low* and *high*. This might - require changes in your code for properly supporting 64-bit systems. - .. cfunction:: int PyList_Sort(PyObject *list) Modified: python/branches/py3k/Doc/c-api/long.rst ============================================================================== --- python/branches/py3k/Doc/c-api/long.rst (original) +++ python/branches/py3k/Doc/c-api/long.rst Mon Apr 27 10:07:12 2009 @@ -100,10 +100,6 @@ string is first encoded to a byte string using :cfunc:`PyUnicode_EncodeDecimal` and then converted using :cfunc:`PyLong_FromString`. - .. versionchanged:: 2.5 - This function used an :ctype:`int` for *length*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyLong_FromVoidPtr(void *p) Modified: python/branches/py3k/Doc/c-api/mapping.rst ============================================================================== --- python/branches/py3k/Doc/c-api/mapping.rst (original) +++ python/branches/py3k/Doc/c-api/mapping.rst Mon Apr 27 10:07:12 2009 @@ -21,10 +21,6 @@ objects that do not provide mapping protocol, this is equivalent to the Python expression ``len(o)``. - .. versionchanged:: 2.5 - These functions returned an :ctype:`int` type. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: int PyMapping_DelItemString(PyObject *o, char *key) Modified: python/branches/py3k/Doc/c-api/marshal.rst ============================================================================== --- python/branches/py3k/Doc/c-api/marshal.rst (original) +++ python/branches/py3k/Doc/c-api/marshal.rst Mon Apr 27 10:07:12 2009 @@ -87,6 +87,3 @@ appropriate exception (:exc:`EOFError` or :exc:`TypeError`) and returns *NULL*. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *len*. This might require - changes in your code for properly supporting 64-bit systems. Modified: python/branches/py3k/Doc/c-api/objbuffer.rst ============================================================================== --- python/branches/py3k/Doc/c-api/objbuffer.rst (original) +++ python/branches/py3k/Doc/c-api/objbuffer.rst Mon Apr 27 10:07:12 2009 @@ -14,10 +14,6 @@ and *buffer_len* to the buffer length. Returns ``-1`` and sets a :exc:`TypeError` on error. - .. versionchanged:: 2.5 - This function used an :ctype:`int *` type for *buffer_len*. This might - require changes in your code for properly supporting 64-bit systems. - .. cfunction:: int PyObject_AsReadBuffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len) @@ -27,10 +23,6 @@ and *buffer_len* to the buffer length. Returns ``-1`` and sets a :exc:`TypeError` on error. - .. versionchanged:: 2.5 - This function used an :ctype:`int *` type for *buffer_len*. This might - require changes in your code for properly supporting 64-bit systems. - .. cfunction:: int PyObject_CheckReadBuffer(PyObject *o) @@ -45,7 +37,3 @@ returns ``0``, sets *buffer* to the memory location and *buffer_len* to the buffer length. Returns ``-1`` and sets a :exc:`TypeError` on error. - .. versionchanged:: 2.5 - This function used an :ctype:`int *` type for *buffer_len*. This might - require changes in your code for properly supporting 64-bit systems. - Modified: python/branches/py3k/Doc/c-api/object.rst ============================================================================== --- python/branches/py3k/Doc/c-api/object.rst (original) +++ python/branches/py3k/Doc/c-api/object.rst Mon Apr 27 10:07:12 2009 @@ -304,10 +304,6 @@ and mapping protocols, the sequence length is returned. On error, ``-1`` is returned. This is the equivalent to the Python expression ``len(o)``. - .. versionchanged:: 2.5 - These functions returned an :ctype:`int` type. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyObject_GetItem(PyObject *o, PyObject *key) Modified: python/branches/py3k/Doc/c-api/sequence.rst ============================================================================== --- python/branches/py3k/Doc/c-api/sequence.rst (original) +++ python/branches/py3k/Doc/c-api/sequence.rst Mon Apr 27 10:07:12 2009 @@ -21,10 +21,6 @@ For objects that do not provide sequence protocol, this is equivalent to the Python expression ``len(o)``. - .. versionchanged:: 2.5 - These functions returned an :ctype:`int` type. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PySequence_Concat(PyObject *o1, PyObject *o2) @@ -37,10 +33,6 @@ Return the result of repeating sequence object *o* *count* times, or *NULL* on failure. This is the equivalent of the Python expression ``o * count``. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *count*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PySequence_InPlaceConcat(PyObject *o1, PyObject *o2) @@ -55,30 +47,18 @@ failure. The operation is done *in-place* when *o* supports it. This is the equivalent of the Python expression ``o *= count``. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *count*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PySequence_GetItem(PyObject *o, Py_ssize_t i) Return the *i*th element of *o*, or *NULL* on failure. This is the equivalent of the Python expression ``o[i]``. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *i*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PySequence_GetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2) Return the slice of sequence object *o* between *i1* and *i2*, or *NULL* on failure. This is the equivalent of the Python expression ``o[i1:i2]``. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *i1* and *i2*. This might - require changes in your code for properly supporting 64-bit systems. - .. cfunction:: int PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v) @@ -86,40 +66,24 @@ is the equivalent of the Python statement ``o[i] = v``. This function *does not* steal a reference to *v*. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *i*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: int PySequence_DelItem(PyObject *o, Py_ssize_t i) Delete the *i*th element of object *o*. Returns ``-1`` on failure. This is the equivalent of the Python statement ``del o[i]``. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *i*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: int PySequence_SetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2, PyObject *v) Assign the sequence object *v* to the slice in sequence object *o* from *i1* to *i2*. This is the equivalent of the Python statement ``o[i1:i2] = v``. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *i1* and *i2*. This might - require changes in your code for properly supporting 64-bit systems. - .. cfunction:: int PySequence_DelSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2) Delete the slice in sequence object *o* from *i1* to *i2*. Returns ``-1`` on failure. This is the equivalent of the Python statement ``del o[i1:i2]``. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *i1* and *i2*. This might - require changes in your code for properly supporting 64-bit systems. - .. cfunction:: Py_ssize_t PySequence_Count(PyObject *o, PyObject *value) @@ -127,10 +91,6 @@ of keys for which ``o[key] == value``. On failure, return ``-1``. This is equivalent to the Python expression ``o.count(value)``. - .. versionchanged:: 2.5 - This function returned an :ctype:`int` type. This might require changes - in your code for properly supporting 64-bit systems. - .. cfunction:: int PySequence_Contains(PyObject *o, PyObject *value) @@ -144,10 +104,6 @@ Return the first index *i* for which ``o[i] == value``. On error, return ``-1``. This is equivalent to the Python expression ``o.index(value)``. - .. versionchanged:: 2.5 - This function returned an :ctype:`int` type. This might require changes - in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PySequence_List(PyObject *o) @@ -178,10 +134,6 @@ Return the *i*th element of *o*, assuming that *o* was returned by :cfunc:`PySequence_Fast`, *o* is not *NULL*, and that *i* is within bounds. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *i*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject** PySequence_Fast_ITEMS(PyObject *o) @@ -200,10 +152,6 @@ :cfunc:`PySequence_Check(o)` is true and without adjustment for negative indices. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *i*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: Py_ssize_t PySequence_Fast_GET_SIZE(PyObject *o) Modified: python/branches/py3k/Doc/c-api/set.rst ============================================================================== --- python/branches/py3k/Doc/c-api/set.rst (original) +++ python/branches/py3k/Doc/c-api/set.rst Mon Apr 27 10:07:12 2009 @@ -106,10 +106,6 @@ ``len(anyset)``. Raises a :exc:`PyExc_SystemError` if *anyset* is not a :class:`set`, :class:`frozenset`, or an instance of a subtype. - .. versionchanged:: 2.5 - This function returned an :ctype:`int`. This might require changes in - your code for properly supporting 64-bit systems. - .. cfunction:: Py_ssize_t PySet_GET_SIZE(PyObject *anyset) 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 Mon Apr 27 10:07:12 2009 @@ -40,11 +40,6 @@ You probably do not want to use this function. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *length* and an - :ctype:`int *` type for *start*, *stop*, and *step*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: 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) @@ -56,8 +51,3 @@ Returns 0 on success and -1 on error with exception set. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *length* and an - :ctype:`int *` type for *start*, *stop*, *step*, and *slicelength*. This - might require changes in your code for properly supporting 64-bit - systems. Modified: python/branches/py3k/Doc/c-api/tuple.rst ============================================================================== --- python/branches/py3k/Doc/c-api/tuple.rst (original) +++ python/branches/py3k/Doc/c-api/tuple.rst Mon Apr 27 10:07:12 2009 @@ -37,10 +37,6 @@ Return a new tuple object of size *len*, or *NULL* on failure. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *len*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyTuple_Pack(Py_ssize_t n, ...) @@ -48,58 +44,34 @@ are initialized to the subsequent *n* C arguments pointing to Python objects. ``PyTuple_Pack(2, a, b)`` is equivalent to ``Py_BuildValue("(OO)", a, b)``. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *n*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: Py_ssize_t PyTuple_Size(PyObject *p) Take a pointer to a tuple object, and return the size of that tuple. - .. versionchanged:: 2.5 - This function returned an :ctype:`int` type. This might require changes - in your code for properly supporting 64-bit systems. - .. cfunction:: Py_ssize_t PyTuple_GET_SIZE(PyObject *p) Return the size of the tuple *p*, which must be non-*NULL* and point to a tuple; no error checking is performed. - .. versionchanged:: 2.5 - This function returned an :ctype:`int` type. This might require changes - in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyTuple_GetItem(PyObject *p, Py_ssize_t pos) Return the object at position *pos* in the tuple pointed to by *p*. If *pos* is out of bounds, return *NULL* and sets an :exc:`IndexError` exception. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *pos*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyTuple_GET_ITEM(PyObject *p, Py_ssize_t pos) Like :cfunc:`PyTuple_GetItem`, but does no checking of its arguments. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *pos*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyTuple_GetSlice(PyObject *p, Py_ssize_t low, Py_ssize_t high) Take a slice of the tuple pointed to by *p* from *low* to *high* and return it as a new tuple. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *low* and *high*. This might - require changes in your code for properly supporting 64-bit systems. - .. cfunction:: int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o) @@ -110,10 +82,6 @@ This function "steals" a reference to *o*. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *pos*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: void PyTuple_SET_ITEM(PyObject *p, Py_ssize_t pos, PyObject *o) @@ -124,10 +92,6 @@ This function "steals" a reference to *o*. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *pos*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: int _PyTuple_Resize(PyObject **p, Py_ssize_t newsize) @@ -142,10 +106,6 @@ ``*p`` is destroyed. On failure, returns ``-1`` and sets ``*p`` to *NULL*, and raises :exc:`MemoryError` or :exc:`SystemError`. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *newsize*. This might - require changes in your code for properly supporting 64-bit systems. - .. cfunction:: int PyTuple_ClearFreeList(void) Modified: python/branches/py3k/Doc/c-api/type.rst ============================================================================== --- python/branches/py3k/Doc/c-api/type.rst (original) +++ python/branches/py3k/Doc/c-api/type.rst Mon Apr 27 10:07:12 2009 @@ -66,10 +66,6 @@ XXX: Document. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *nitems*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds) 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 Apr 27 10:07:12 2009 @@ -64,10 +64,6 @@ This field is not inherited by subtypes. - .. versionchanged:: 2.5 - This field used to be an :ctype:`int` type. This might require changes - in your code for properly supporting 64-bit systems. - .. cmember:: PyTypeObject* PyObject.ob_type 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 Mon Apr 27 10:07:12 2009 @@ -65,20 +65,12 @@ Return the size of the object. *o* has to be a :ctype:`PyUnicodeObject` (not checked). - .. versionchanged:: 2.5 - This function returned an :ctype:`int` type. This might require changes - in your code for properly supporting 64-bit systems. - .. cfunction:: Py_ssize_t PyUnicode_GET_DATA_SIZE(PyObject *o) Return the size of the object's internal buffer in bytes. *o* has to be a :ctype:`PyUnicodeObject` (not checked). - .. versionchanged:: 2.5 - This function returned an :ctype:`int` type. This might require changes - in your code for properly supporting 64-bit systems. - .. cfunction:: Py_UNICODE* PyUnicode_AS_UNICODE(PyObject *o) @@ -214,9 +206,6 @@ Therefore, modification of the resulting Unicode object is only allowed when *u* is *NULL*. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. .. cfunction:: PyObject* PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size) @@ -328,10 +317,6 @@ Return the length of the Unicode object. - .. versionchanged:: 2.5 - This function returned an :ctype:`int` type. This might require changes - in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_FromEncodedObject(PyObject *obj, const char *encoding, const char *errors) @@ -370,10 +355,6 @@ using wcslen. Return *NULL* on failure. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode, wchar_t *w, Py_ssize_t size) @@ -385,11 +366,6 @@ to make sure that the :ctype:`wchar_t` string is 0-terminated in case this is required by the application. - .. versionchanged:: 2.5 - This function returned an :ctype:`int` type and used an :ctype:`int` - type for *size*. This might require changes in your code for properly - supporting 64-bit systems. - .. _builtincodecs: @@ -429,10 +405,6 @@ using the Python codec registry. Return *NULL* if an exception was raised by the codec. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_Encode(const Py_UNICODE *s, Py_ssize_t size, const char *encoding, const char *errors) @@ -442,10 +414,6 @@ to be used is looked up using the Python codec registry. Return *NULL* if an exception was raised by the codec. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_AsEncodedString(PyObject *unicode, const char *encoding, const char *errors) @@ -465,10 +433,6 @@ Create a Unicode object by decoding *size* bytes of the UTF-8 encoded string *s*. Return *NULL* if an exception was raised by the codec. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_DecodeUTF8Stateful(const char *s, Py_ssize_t size, const char *errors, Py_ssize_t *consumed) @@ -477,10 +441,6 @@ treated as an error. Those bytes will not be decoded and the number of bytes that have been decoded will be stored in *consumed*. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_EncodeUTF8(const Py_UNICODE *s, Py_ssize_t size, const char *errors) @@ -488,10 +448,6 @@ return a Python bytes object. Return *NULL* if an exception was raised by the codec. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_AsUTF8String(PyObject *unicode) @@ -591,10 +547,6 @@ Return *NULL* if an exception was raised by the codec. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_DecodeUTF16Stateful(const char *s, Py_ssize_t size, const char *errors, int *byteorder, Py_ssize_t *consumed) @@ -604,11 +556,6 @@ split surrogate pair) as an error. Those bytes will not be decoded and the number of bytes that have been decoded will be stored in *consumed*. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size* and an :ctype:`int *` - type for *consumed*. This might require changes in your code for - properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_EncodeUTF16(const Py_UNICODE *s, Py_ssize_t size, const char *errors, int byteorder) @@ -629,10 +576,6 @@ Return *NULL* if an exception was raised by the codec. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_AsUTF16String(PyObject *unicode) @@ -650,10 +593,6 @@ Create a Unicode object by decoding *size* bytes of the Unicode-Escape encoded string *s*. Return *NULL* if an exception was raised by the codec. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size) @@ -661,10 +600,6 @@ return a Python string object. Return *NULL* if an exception was raised by the codec. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_AsUnicodeEscapeString(PyObject *unicode) @@ -682,10 +617,6 @@ Create a Unicode object by decoding *size* bytes of the Raw-Unicode-Escape encoded string *s*. Return *NULL* if an exception was raised by the codec. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size, const char *errors) @@ -693,10 +624,6 @@ and return a Python string object. Return *NULL* if an exception was raised by the codec. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) @@ -715,10 +642,6 @@ Create a Unicode object by decoding *size* bytes of the Latin-1 encoded string *s*. Return *NULL* if an exception was raised by the codec. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_EncodeLatin1(const Py_UNICODE *s, Py_ssize_t size, const char *errors) @@ -726,10 +649,6 @@ return a Python bytes object. Return *NULL* if an exception was raised by the codec. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_AsLatin1String(PyObject *unicode) @@ -748,10 +667,6 @@ Create a Unicode object by decoding *size* bytes of the ASCII encoded string *s*. Return *NULL* if an exception was raised by the codec. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_EncodeASCII(const Py_UNICODE *s, Py_ssize_t size, const char *errors) @@ -759,10 +674,6 @@ return a Python bytes object. Return *NULL* if an exception was raised by the codec. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_AsASCIIString(PyObject *unicode) @@ -805,10 +716,6 @@ Byte values greater that the length of the string and U+FFFE "characters" are treated as "undefined mapping". - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_EncodeCharmap(const Py_UNICODE *s, Py_ssize_t size, PyObject *mapping, const char *errors) @@ -816,10 +723,6 @@ *mapping* object and return a Python string object. Return *NULL* if an exception was raised by the codec. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_AsCharmapString(PyObject *unicode, PyObject *mapping) @@ -843,9 +746,6 @@ and sequences work well. Unmapped character ordinals (ones which cause a :exc:`LookupError`) are left untouched and are copied as-is. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. These are the MBCS codec APIs. They are currently only available on Windows and use the Win32 MBCS converters to implement the conversions. Note that MBCS (or @@ -860,10 +760,6 @@ Create a Unicode object by decoding *size* bytes of the MBCS encoded string *s*. Return *NULL* if an exception was raised by the codec. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_DecodeMBCSStateful(const char *s, int size, const char *errors, int *consumed) @@ -879,10 +775,6 @@ a Python bytes object. Return *NULL* if an exception was raised by the codec. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *size*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_AsMBCSString(PyObject *unicode) @@ -917,10 +809,6 @@ separator. At most *maxsplit* splits will be done. If negative, no limit is set. Separators are not included in the resulting list. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *maxsplit*. This might require - changes in your code for properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_Splitlines(PyObject *s, int keepend) @@ -957,11 +845,6 @@ (*direction* == -1 means to do a prefix match, *direction* == 1 a suffix match), 0 otherwise. Return ``-1`` if an error occurred. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *start* and *end*. This - might require changes in your code for properly supporting 64-bit - systems. - .. cfunction:: Py_ssize_t PyUnicode_Find(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction) @@ -971,22 +854,12 @@ ``-1`` indicates that no match was found, and ``-2`` indicates that an error occurred and an exception has been set. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *start* and *end*. This - might require changes in your code for properly supporting 64-bit - systems. - .. cfunction:: Py_ssize_t PyUnicode_Count(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end) Return the number of non-overlapping occurrences of *substr* in ``str[start:end]``. Return ``-1`` if an error occurred. - .. versionchanged:: 2.5 - This function returned an :ctype:`int` type and used an :ctype:`int` - type for *start* and *end*. This might require changes in your code for - properly supporting 64-bit systems. - .. cfunction:: PyObject* PyUnicode_Replace(PyObject *str, PyObject *substr, PyObject *replstr, Py_ssize_t maxcount) @@ -994,10 +867,6 @@ return the resulting Unicode object. *maxcount* == -1 means replace all occurrences. - .. versionchanged:: 2.5 - This function used an :ctype:`int` type for *maxcount*. This might - require changes in your code for properly supporting 64-bit systems. - .. cfunction:: int PyUnicode_Compare(PyObject *left, PyObject *right) Modified: python/branches/py3k/Doc/distutils/setupscript.rst ============================================================================== --- python/branches/py3k/Doc/distutils/setupscript.rst (original) +++ python/branches/py3k/Doc/distutils/setupscript.rst Mon Apr 27 10:07:12 2009 @@ -454,9 +454,6 @@ scripts=['scripts/xmlproc_parse', 'scripts/xmlproc_val'] ) -.. versionchanged:: 2.7 - All the scripts will also be added to the ``MANIFEST`` - file if no template is provided. See :ref:`manifest`. .. _distutils-installing-package-data: @@ -501,11 +498,6 @@ ) -.. versionchanged:: 2.7 - All the files that match ``package_data`` will be added to the ``MANIFEST`` - file if no template is provided. See :ref:`manifest`. - - .. _distutils-additional-files: Installing Additional Files @@ -542,11 +534,6 @@ files directly in the target directory, an empty string should be given as the directory. -.. versionchanged:: 2.7 - All the files that match ``data_files`` will be added to the ``MANIFEST`` - file if no template is provided. See :ref:`manifest`. - - .. _meta-data: Modified: python/branches/py3k/Doc/library/re.rst ============================================================================== --- python/branches/py3k/Doc/library/re.rst (original) +++ python/branches/py3k/Doc/library/re.rst Mon Apr 27 10:07:12 2009 @@ -605,7 +605,7 @@ >>> re.split("(?m)^$", "foo\n\nbar\n") ['foo\n\nbar\n'] - .. versionchanged:: 2.7,3.1 + .. versionchanged:: 3.1 Added the optional flags argument. @@ -675,7 +675,7 @@ character ``'0'``. The backreference ``\g<0>`` substitutes in the entire substring matched by the RE. - .. versionchanged:: 2.7,3.1 + .. versionchanged:: 3.1 Added the optional flags argument. @@ -684,7 +684,7 @@ Perform the same operation as :func:`sub`, but return a tuple ``(new_string, number_of_subs_made)``. - .. versionchanged:: 2.7,3.1 + .. versionchanged:: 3.1 Added the optional flags argument. From python-checkins at python.org Mon Apr 27 10:58:15 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 10:58:15 +0200 (CEST) Subject: [Python-checkins] r72002 - python/branches/py3k/Doc/distutils/setupscript.rst Message-ID: <20090427085815.B87BE1E4002@bag.python.org> Author: georg.brandl Date: Mon Apr 27 10:58:15 2009 New Revision: 72002 Log: Reintroduce versionchanged tags, but with correct version. Modified: python/branches/py3k/Doc/distutils/setupscript.rst Modified: python/branches/py3k/Doc/distutils/setupscript.rst ============================================================================== --- python/branches/py3k/Doc/distutils/setupscript.rst (original) +++ python/branches/py3k/Doc/distutils/setupscript.rst Mon Apr 27 10:58:15 2009 @@ -454,6 +454,10 @@ scripts=['scripts/xmlproc_parse', 'scripts/xmlproc_val'] ) +.. versionchanged:: 3.1 + All the scripts will also be added to the ``MANIFEST`` file if no template is + provided. See :ref:`manifest`. + .. _distutils-installing-package-data: @@ -498,6 +502,11 @@ ) +.. versionchanged:: 3.1 + All the files that match ``package_data`` will be added to the ``MANIFEST`` + file if no template is provided. See :ref:`manifest`. + + .. _distutils-additional-files: Installing Additional Files @@ -534,6 +543,10 @@ files directly in the target directory, an empty string should be given as the directory. +.. versionchanged:: 3.1 + All the files that match ``data_files`` will be added to the ``MANIFEST`` + file if no template is provided. See :ref:`manifest`. + .. _meta-data: From python-checkins at python.org Mon Apr 27 14:43:21 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Mon, 27 Apr 2009 14:43:21 +0200 (CEST) Subject: [Python-checkins] r72003 - python/branches/py3k Message-ID: <20090427124321.E5E3A1E4015@bag.python.org> Author: jeroen.ruigrok Date: Mon Apr 27 14:43:21 2009 New Revision: 72003 Log: For some reason the property did not get committed properly even though the diffs said it did. Modified: python/branches/py3k/ (props changed) From buildbot at python.org Mon Apr 27 15:19:40 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 27 Apr 2009 13:19:40 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 3.x Message-ID: <20090427131941.67EB21E4016@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%203.x/builds/695 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl,jeroen.ruigrok BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_time ====================================================================== FAIL: test_tzset (test.test_time.TimeTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-debian-ppc/build/Lib/test/test_time.py", line 166, in test_tzset self.failIfEqual(time.gmtime(xmas2002), time.localtime(xmas2002)) AssertionError: time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) == time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Mon Apr 27 15:24:43 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 27 Apr 2009 13:24:43 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090427132444.72B711E4016@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/650 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl,jeroen.ruigrok BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_time ====================================================================== FAIL: test_tzset (test.test_time.TimeTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/test/test_time.py", line 166, in test_tzset self.failIfEqual(time.gmtime(xmas2002), time.localtime(xmas2002)) AssertionError: time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) == time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 27 15:44:27 2009 From: python-checkins at python.org (vinay.sajip) Date: Mon, 27 Apr 2009 15:44:27 +0200 (CEST) Subject: [Python-checkins] r72004 - in python/trunk: Lib/logging/__init__.py Misc/NEWS Message-ID: <20090427134427.4F5BA1E4016@bag.python.org> Author: vinay.sajip Date: Mon Apr 27 15:44:27 2009 New Revision: 72004 Log: Issue #5854: Updated __all__ to include some missing names and remove some names which should not be exported. Modified: python/trunk/Lib/logging/__init__.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/logging/__init__.py ============================================================================== --- python/trunk/Lib/logging/__init__.py (original) +++ python/trunk/Lib/logging/__init__.py Mon Apr 27 15:44:27 2009 @@ -24,9 +24,12 @@ """ __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', - 'FATAL', 'FileHandler', 'Filter', 'Filterer', 'Formatter', 'Handler', - 'INFO', 'LogRecord', 'Logger', 'Manager', 'NOTSET', 'PlaceHolder', - 'RootLogger', 'StreamHandler', 'WARN', 'WARNING'] + 'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO', + 'LogRecord', 'Logger', 'LoggerAdapter', 'NOTSET', 'NullHandler', + 'StreamHandler', 'WARN', 'WARNING', 'addLevelName', 'basicConfig', + 'captureWarnings', 'critical', 'debug', 'disable', 'error', + 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass', + 'info', 'log', 'makeLogRecord', 'setLoggerClass', 'warn', 'warning'] import sys, os, types, time, string, cStringIO, traceback, warnings @@ -43,8 +46,8 @@ __author__ = "Vinay Sajip " __status__ = "production" -__version__ = "0.5.0.7" -__date__ = "20 January 2009" +__version__ = "0.5.0.8" +__date__ = "27 April 2009" #--------------------------------------------------------------------------- # Miscellaneous module data Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Apr 27 15:44:27 2009 @@ -252,7 +252,10 @@ Library ------- -- Issue #5810: Fixed Distutils test_build_scripts so it uses +- Issue #5854: Updated __all__ to include some missing names and remove some + names which should not be exported. + +- Issue #5810: Fixed Distutils test_build_scripts so it uses sysconfig.get_config_vars. - Issue #4951: Fixed failure in test_httpservers. From python-checkins at python.org Mon Apr 27 15:51:32 2009 From: python-checkins at python.org (vinay.sajip) Date: Mon, 27 Apr 2009 15:51:32 +0200 (CEST) Subject: [Python-checkins] r72005 - in python/branches/release26-maint: Lib/logging/__init__.py Misc/NEWS Message-ID: <20090427135132.878AA1E4016@bag.python.org> Author: vinay.sajip Date: Mon Apr 27 15:51:32 2009 New Revision: 72005 Log: Issue #5854: Updated __all__ to include some missing names and remove some names which should not be exported. Modified: python/branches/release26-maint/Lib/logging/__init__.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/logging/__init__.py ============================================================================== --- python/branches/release26-maint/Lib/logging/__init__.py (original) +++ python/branches/release26-maint/Lib/logging/__init__.py Mon Apr 27 15:51:32 2009 @@ -24,9 +24,12 @@ """ __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', - 'FATAL', 'FileHandler', 'Filter', 'Filterer', 'Formatter', 'Handler', - 'INFO', 'LogRecord', 'Logger', 'Manager', 'NOTSET', 'PlaceHolder', - 'RootLogger', 'StreamHandler', 'WARN', 'WARNING'] + 'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO', + 'LogRecord', 'Logger', 'LoggerAdapter', 'NOTSET', 'NullHandler', + 'StreamHandler', 'WARN', 'WARNING', 'addLevelName', 'basicConfig', + 'captureWarnings', 'critical', 'debug', 'disable', 'error', + 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass', + 'info', 'log', 'makeLogRecord', 'setLoggerClass', 'warn', 'warning'] import sys, os, types, time, string, cStringIO, traceback Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Mon Apr 27 15:51:32 2009 @@ -148,7 +148,10 @@ Library ------- -- Issue #5810: Fixed Distutils test_build_scripts so it uses +- Issue #5854: Updated __all__ to include some missing names and remove some + names which should not be exported. + +- Issue #5810: Fixed Distutils test_build_scripts so it uses sysconfig.get_config_vars. - Issue #5741: don't disallow "%%" (which is an escape for "%") when setting From python-checkins at python.org Mon Apr 27 15:55:05 2009 From: python-checkins at python.org (vinay.sajip) Date: Mon, 27 Apr 2009 15:55:05 +0200 (CEST) Subject: [Python-checkins] r72006 - in python/branches/py3k: Lib/logging/__init__.py Misc/NEWS Message-ID: <20090427135505.8F74E1E4016@bag.python.org> Author: vinay.sajip Date: Mon Apr 27 15:55:05 2009 New Revision: 72006 Log: Issue #5854: Updated __all__ to include some missing names and remove some names which should not be exported. Modified: python/branches/py3k/Lib/logging/__init__.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 Mon Apr 27 15:55:05 2009 @@ -26,9 +26,12 @@ import sys, os, time, io, traceback, warnings __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', - 'FATAL', 'FileHandler', 'Filter', 'Filterer', 'Formatter', 'Handler', - 'INFO', 'LogRecord', 'Logger', 'Manager', 'NOTSET', 'PlaceHolder', - 'RootLogger', 'StreamHandler', 'WARN', 'WARNING'] + 'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO', + 'LogRecord', 'Logger', 'LoggerAdapter', 'NOTSET', 'NullHandler', + 'StreamHandler', 'WARN', 'WARNING', 'addLevelName', 'basicConfig', + 'captureWarnings', 'critical', 'debug', 'disable', 'error', + 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass', + 'info', 'log', 'makeLogRecord', 'setLoggerClass', 'warn', 'warning'] try: import codecs Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Apr 27 15:55:05 2009 @@ -89,6 +89,9 @@ Library ------- +- Issue #5854: Updated __all__ to include some missing names and remove some + names which should not be exported. + - Issue #3102: All global symbols that the _ctypes extension defines are now prefixed with 'Py' or '_ctypes'. @@ -455,7 +458,7 @@ Library ------- -- Issue #5810: Fixed Distutils test_build_scripts so it uses +- Issue #5810: Fixed Distutils test_build_scripts so it uses sysconfig.get_config_vars. - Issue #4951: Fixed failure in test_httpservers. @@ -466,7 +469,7 @@ - Issue #5732: added a new command in Distutils: check. -- Issue #5731: Distutils bdist_wininst no longer worked on non-Windows +- Issue #5731: Distutils bdist_wininst no longer worked on non-Windows platforms. Initial patch by Paul Moore. - Issue #5095: Added bdist_msi to the list of bdist supported formats. @@ -931,7 +934,7 @@ ----- - regrtest no longer treats ImportError as equivalent to SkipTest. Imports - that should cause a test to be skipped are now done using import_module + that should cause a test to be skipped are now done using import_module from test support, which does the conversion. - Issue #5083: New 'gui' resource for regrtest. From buildbot at python.org Mon Apr 27 16:10:07 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 27 Apr 2009 14:10:07 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo trunk Message-ID: <20090427141008.0FC521E4016@bag.python.org> The Buildbot has detected a new failure of x86 gentoo trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%20trunk/builds/4886 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: vinay.sajip BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_time ====================================================================== FAIL: test_tzset (test.test_time.TimeTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildslave/python-trunk/trunk.norwitz-x86/build/Lib/test/test_time.py", line 152, in test_tzset time.gmtime(xmas2002), time.localtime(xmas2002) AssertionError: time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) != time.struct_time(tm_year=2002, tm_mon=12, tm_mday=24, tm_hour=19, tm_min=0, tm_sec=0, tm_wday=1, tm_yday=358, tm_isdst=0) make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Mon Apr 27 16:31:52 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 27 Apr 2009 14:31:52 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable trunk Message-ID: <20090427143153.222AF1E4016@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%20trunk/builds/424 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: vinay.sajip BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_os test_time make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 27 17:09:25 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 17:09:25 +0200 (CEST) Subject: [Python-checkins] r72007 - python/trunk/Doc/library/traceback.rst Message-ID: <20090427150925.AC1CB1E4016@bag.python.org> Author: georg.brandl Date: Mon Apr 27 17:09:25 2009 New Revision: 72007 Log: #5856: fix typo s in traceback example. Modified: python/trunk/Doc/library/traceback.rst Modified: python/trunk/Doc/library/traceback.rst ============================================================================== --- python/trunk/Doc/library/traceback.rst (original) +++ python/trunk/Doc/library/traceback.rst Mon Apr 27 17:09:25 2009 @@ -1,4 +1,3 @@ - :mod:`traceback` --- Print or retrieve a stack traceback ======================================================== @@ -275,10 +274,10 @@ This last example demonstrates the final few formatting functions:: >>> import traceback - >>> format_list([('spam.py', 3, '', 'spam.eggs()'), - ... ('eggs.py', 42, 'eggs', 'return "bacon"')]) + >>> traceback.format_list([('spam.py', 3, '', 'spam.eggs()'), + ... ('eggs.py', 42, 'eggs', 'return "bacon"')]) [' File "spam.py", line 3, in \n spam.eggs()\n', ' File "eggs.py", line 42, in eggs\n return "bacon"\n'] - >>> theError = IndexError('tuple indx out of range') - >>> traceback.format_exception_only(type(theError), theError) + >>> an_error = IndexError('tuple index out of range') + >>> traceback.format_exception_only(type(an_error), an_error) ['IndexError: tuple index out of range\n'] From python-checkins at python.org Mon Apr 27 17:10:44 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 17:10:44 +0200 (CEST) Subject: [Python-checkins] r72008 - in python/trunk/Doc: distutils/apiref.rst using/cmdline.rst Message-ID: <20090427151044.39A511E4016@bag.python.org> Author: georg.brandl Date: Mon Apr 27 17:10:44 2009 New Revision: 72008 Log: Remove ".. warning::" markup that doesnt contain warnings for users, rather todo items. Modified: python/trunk/Doc/distutils/apiref.rst python/trunk/Doc/using/cmdline.rst Modified: python/trunk/Doc/distutils/apiref.rst ============================================================================== --- python/trunk/Doc/distutils/apiref.rst (original) +++ python/trunk/Doc/distutils/apiref.rst Mon Apr 27 17:10:44 2009 @@ -869,9 +869,7 @@ prefix of all files and directories in the archive. *root_dir* and *base_dir* both default to the current directory. Returns the name of the archive file. - .. warning:: - - This should be changed to support bz2 files + .. XXX This should be changed to support bz2 files. .. function:: make_tarball(base_name, base_dir[, compress='gzip', verbose=0, dry_run=0]) @@ -884,9 +882,7 @@ possibly plus the appropriate compression extension (:file:`.gz`, :file:`.bz2` or :file:`.Z`). Return the output filename. - .. warning:: - - This should be replaced with calls to the :mod:`tarfile` module. + .. XXX This should be replaced with calls to the :mod:`tarfile` module. .. function:: make_zipfile(base_name, base_dir[, verbose=0, dry_run=0]) @@ -1329,10 +1325,8 @@ Wraps *text* to less than *width* wide. - .. warning:: - - Should be replaced with :mod:`textwrap` (which is available in Python 2.3 and - later). + .. XXX Should be replaced with :mod:`textwrap` (which is available in Python + 2.3 and later). .. class:: FancyGetopt([option_table=None]) @@ -1381,8 +1375,8 @@ ================================================ .. module:: distutils.filelist - :synopsis: The FileList class, used for poking about the file system and building lists of - files. + :synopsis: The FileList class, used for poking about the file system and + building lists of files. This module provides the :class:`FileList` class, used for poking about the @@ -1396,13 +1390,8 @@ :synopsis: A simple logging mechanism, 282-style -.. warning:: - - Should be replaced with standard :mod:`logging` module. +.. XXX Should be replaced with standard :mod:`logging` module. -.. % \subsubsection{\module{} --- } -.. % \declaremodule{standard}{distutils.magic} -.. % \modulesynopsis{ } :mod:`distutils.spawn` --- Spawn a sub-process Modified: python/trunk/Doc/using/cmdline.rst ============================================================================== --- python/trunk/Doc/using/cmdline.rst (original) +++ python/trunk/Doc/using/cmdline.rst Mon Apr 27 17:10:44 2009 @@ -360,7 +360,7 @@ Skip the first line of the source, allowing use of non-Unix forms of ``#!cmd``. This is intended for a DOS specific hack only. - .. warning:: The line numbers in error messages will be off by one! + .. note:: The line numbers in error messages will be off by one. .. cmdoption:: -3 From python-checkins at python.org Mon Apr 27 17:29:10 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 17:29:10 +0200 (CEST) Subject: [Python-checkins] r72009 - in python/trunk/Doc: c-api/intro.rst documenting/markup.rst extending/extending.rst library/2to3.rst library/aifc.rst library/codeop.rst library/configparser.rst library/fileinput.rst library/functions.rst library/httplib.rst library/inspect.rst library/locale.rst library/marshal.rst library/os.path.rst library/pickle.rst library/string.rst library/subprocess.rst library/tabnanny.rst library/unittest.rst reference/compound_stmts.rst reference/executionmodel.rst Message-ID: <20090427152910.3A6761E4016@bag.python.org> Author: georg.brandl Date: Mon Apr 27 17:29:09 2009 New Revision: 72009 Log: Demote warnings to notices where appropriate, following the goal that as few "red box" warnings should clutter the docs as possible. Part 1: stuff that gets merged to Py3k. Modified: python/trunk/Doc/c-api/intro.rst python/trunk/Doc/documenting/markup.rst python/trunk/Doc/extending/extending.rst python/trunk/Doc/library/2to3.rst python/trunk/Doc/library/aifc.rst python/trunk/Doc/library/codeop.rst python/trunk/Doc/library/configparser.rst python/trunk/Doc/library/fileinput.rst python/trunk/Doc/library/functions.rst python/trunk/Doc/library/httplib.rst python/trunk/Doc/library/inspect.rst python/trunk/Doc/library/locale.rst python/trunk/Doc/library/marshal.rst python/trunk/Doc/library/os.path.rst python/trunk/Doc/library/pickle.rst python/trunk/Doc/library/string.rst python/trunk/Doc/library/subprocess.rst python/trunk/Doc/library/tabnanny.rst python/trunk/Doc/library/unittest.rst python/trunk/Doc/reference/compound_stmts.rst python/trunk/Doc/reference/executionmodel.rst Modified: python/trunk/Doc/c-api/intro.rst ============================================================================== --- python/trunk/Doc/c-api/intro.rst (original) +++ python/trunk/Doc/c-api/intro.rst Mon Apr 27 17:29:09 2009 @@ -44,7 +44,7 @@ ````, ````, ````, and ```` (if available). -.. warning:: +.. note:: Since Python may define some pre-processor definitions which affect the standard headers on some systems, you *must* include :file:`Python.h` before any standard Modified: python/trunk/Doc/documenting/markup.rst ============================================================================== --- python/trunk/Doc/documenting/markup.rst (original) +++ python/trunk/Doc/documenting/markup.rst Mon Apr 27 17:29:09 2009 @@ -594,11 +594,11 @@ .. describe:: warning - An important bit of information about an API that a user should be very aware - of when using whatever bit of API the warning pertains to. The content of - the directive should be written in complete sentences and include all - appropriate punctuation. This differs from ``note`` in that it is recommended - over ``note`` for information regarding security. + An important bit of information about an API that a user should be aware of + when using whatever bit of API the warning pertains to. The content of the + directive should be written in complete sentences and include all appropriate + punctuation. This should only be chosen over ``note`` for information + regarding the possibility of crashes, data loss, or security implications. .. describe:: versionadded Modified: python/trunk/Doc/extending/extending.rst ============================================================================== --- python/trunk/Doc/extending/extending.rst (original) +++ python/trunk/Doc/extending/extending.rst Mon Apr 27 17:29:09 2009 @@ -47,7 +47,7 @@ which pulls in the Python API (you can add a comment describing the purpose of the module and a copyright notice if you like). -.. warning:: +.. note:: Since Python may define some pre-processor definitions which affect the standard headers on some systems, you *must* include :file:`Python.h` before any standard Modified: python/trunk/Doc/library/2to3.rst ============================================================================== --- python/trunk/Doc/library/2to3.rst (original) +++ python/trunk/Doc/library/2to3.rst Mon Apr 27 17:29:09 2009 @@ -354,7 +354,7 @@ .. moduleauthor:: Collin Winter -.. warning:: +.. note:: The :mod:`lib2to3` API should be considered unstable and may change drastically in the future. Modified: python/trunk/Doc/library/aifc.rst ============================================================================== --- python/trunk/Doc/library/aifc.rst (original) +++ python/trunk/Doc/library/aifc.rst Mon Apr 27 17:29:09 2009 @@ -1,4 +1,3 @@ - :mod:`aifc` --- Read and write AIFF and AIFC files ================================================== @@ -16,10 +15,11 @@ samples in a file. AIFF-C is a newer version of the format that includes the ability to compress the audio data. -.. warning:: +.. note:: Some operations may only work under IRIX; these will raise :exc:`ImportError` - when attempting to import the :mod:`cl` module, which is only available on IRIX. + when attempting to import the :mod:`cl` module, which is only available on + IRIX. Audio files have a number of parameters that describe the audio data. The sampling rate or frame rate is the number of times per second the sound is Modified: python/trunk/Doc/library/codeop.rst ============================================================================== --- python/trunk/Doc/library/codeop.rst (original) +++ python/trunk/Doc/library/codeop.rst Mon Apr 27 17:29:09 2009 @@ -42,7 +42,7 @@ (``'single'``, the default) or as an :term:`expression` (``'eval'``). Any other value will cause :exc:`ValueError` to be raised. - .. warning:: + .. note:: It is possible (but not likely) that the parser stops parsing with a successful outcome before reaching the end of the source; in this case, Modified: python/trunk/Doc/library/configparser.rst ============================================================================== --- python/trunk/Doc/library/configparser.rst (original) +++ python/trunk/Doc/library/configparser.rst Mon Apr 27 17:29:09 2009 @@ -27,10 +27,10 @@ can use this to write Python programs which can be customized by end users easily. -.. warning:: +.. note:: - This library does *not* interpret or write the value-type prefixes used in the - Windows Registry extended version of INI syntax. + This library does *not* interpret or write the value-type prefixes used in + the Windows Registry extended version of INI syntax. The configuration file consists of sections, led by a ``[section]`` header and followed by ``name: value`` entries, with continuations in the style of Modified: python/trunk/Doc/library/fileinput.rst ============================================================================== --- python/trunk/Doc/library/fileinput.rst (original) +++ python/trunk/Doc/library/fileinput.rst Mon Apr 27 17:29:09 2009 @@ -150,7 +150,7 @@ it is deleted when the output file is closed. In-place filtering is disabled when standard input is read. -.. warning:: +.. note:: The current implementation does not work for MS-DOS 8+3 filesystems. Modified: python/trunk/Doc/library/functions.rst ============================================================================== --- python/trunk/Doc/library/functions.rst (original) +++ python/trunk/Doc/library/functions.rst Mon Apr 27 17:29:09 2009 @@ -364,7 +364,7 @@ If both dictionaries are omitted, the expression is executed in the environment where :func:`execfile` is called. The return value is ``None``. - .. warning:: + .. note:: The default *locals* act as described for function :func:`locals` below: modifications to the default *locals* dictionary should not be attempted. Pass @@ -633,7 +633,7 @@ Update and return a dictionary representing the current local symbol table. - .. warning:: + .. note:: The contents of this dictionary should not be modified; changes may not affect the values of local variables used by the interpreter. @@ -1363,7 +1363,7 @@ else that has a :attr:`__dict__` attribute), returns a dictionary corresponding to the object's symbol table. - .. warning:: + .. note:: The returned dictionary should not be modified: the effects on the corresponding symbol table are undefined. [#]_ Modified: python/trunk/Doc/library/httplib.rst ============================================================================== --- python/trunk/Doc/library/httplib.rst (original) +++ python/trunk/Doc/library/httplib.rst Mon Apr 27 17:29:09 2009 @@ -68,9 +68,9 @@ formatted file that contains your private key. *cert_file* is a PEM formatted certificate chain file. - .. warning:: + .. note:: - This does not do any certificate verification! + This does not do any certificate verification. .. versionadded:: 2.0 Modified: python/trunk/Doc/library/inspect.rst ============================================================================== --- python/trunk/Doc/library/inspect.rst (original) +++ python/trunk/Doc/library/inspect.rst Mon Apr 27 17:29:09 2009 @@ -510,7 +510,7 @@ the function name, a list of lines of context from the source code, and the index of the current line within that list. -.. warning:: +.. note:: Keeping references to frame objects, as found in the first element of the frame records these functions return, can cause your program to create reference Modified: python/trunk/Doc/library/locale.rst ============================================================================== --- python/trunk/Doc/library/locale.rst (original) +++ python/trunk/Doc/library/locale.rst Mon Apr 27 17:29:09 2009 @@ -398,7 +398,7 @@ Return name of the n-th day of the week. - .. warning:: + .. note:: This follows the US convention of :const:`DAY_1` being Sunday, not the international convention (ISO 8601) that Monday is the first day of the week. @@ -434,7 +434,7 @@ Return a regular expression that can be used with the regex function to recognize a positive response to a yes/no question. - .. warning:: + .. note:: The expression is in the syntax suitable for the :cfunc:`regex` function from the C library, which might differ from the syntax used in :mod:`re`. Modified: python/trunk/Doc/library/marshal.rst ============================================================================== --- python/trunk/Doc/library/marshal.rst (original) +++ python/trunk/Doc/library/marshal.rst Mon Apr 27 17:29:09 2009 @@ -85,7 +85,7 @@ file must be an open file object opened in binary mode (``'rb'`` or ``'r+b'``). - .. warning:: + .. note:: If an object containing an unsupported type was marshalled with :func:`dump`, :func:`load` will substitute ``None`` for the unmarshallable type. Modified: python/trunk/Doc/library/os.path.rst ============================================================================== --- python/trunk/Doc/library/os.path.rst (original) +++ python/trunk/Doc/library/os.path.rst Mon Apr 27 17:29:09 2009 @@ -10,7 +10,7 @@ write files see :func:`open`, and for accessing the filesystem see the :mod:`os` module. -.. warning:: +.. note:: On Windows, many of these functions do not properly support UNC pathnames. :func:`splitunc` and :func:`ismount` do handle them correctly. @@ -317,7 +317,7 @@ identify them with ``os.path.islink(file)`` and ``os.path.isdir(file)``, and invoke :func:`walk` as necessary. - .. warning:: + .. note:: This function is deprecated and has been removed in 3.0 in favor of :func:`os.walk`. Modified: python/trunk/Doc/library/pickle.rst ============================================================================== --- python/trunk/Doc/library/pickle.rst (original) +++ python/trunk/Doc/library/pickle.rst Mon Apr 27 17:29:09 2009 @@ -77,8 +77,8 @@ .. warning:: The :mod:`pickle` module is not intended to be secure against erroneous or - maliciously constructed data. Never unpickle data received from an untrusted or - unauthenticated source. + maliciously constructed data. Never unpickle data received from an untrusted + or unauthenticated source. Note that serialization is a more primitive notion than persistence; although :mod:`pickle` reads and writes file objects, it does not handle the issue of @@ -453,7 +453,7 @@ :meth:`__getstate__` and :meth:`__setstate__`, the state object needn't be a dictionary and these methods can do what they want. [#]_ - .. warning:: + .. note:: For :term:`new-style class`\es, if :meth:`__getstate__` returns a false value, the :meth:`__setstate__` method will not be called. Modified: python/trunk/Doc/library/string.rst ============================================================================== --- python/trunk/Doc/library/string.rst (original) +++ python/trunk/Doc/library/string.rst Mon Apr 27 17:29:09 2009 @@ -599,7 +599,7 @@ map each character in *from* into the character at the same position in *to*; *from* and *to* must have the same length. - .. warning:: + .. note:: Don't use strings derived from :const:`lowercase` and :const:`uppercase` as arguments; in some locales, these don't have the same length. For case Modified: python/trunk/Doc/library/subprocess.rst ============================================================================== --- python/trunk/Doc/library/subprocess.rst (original) +++ python/trunk/Doc/library/subprocess.rst Mon Apr 27 17:29:09 2009 @@ -301,10 +301,10 @@ .. warning:: - Use :meth:`communicate` rather than :meth:`.stdin.write`, - :meth:`.stdout.read` or :meth:`.stderr.read` to avoid deadlocks due - to any of the other OS pipe buffers filling up and blocking the child - process. + Use :meth:`communicate` rather than :attr:`.stdin.write `, + :attr:`.stdout.read ` or :attr:`.stderr.read ` to avoid + deadlocks due to any of the other OS pipe buffers filling up and blocking the + child process. .. attribute:: Popen.stdin Modified: python/trunk/Doc/library/tabnanny.rst ============================================================================== --- python/trunk/Doc/library/tabnanny.rst (original) +++ python/trunk/Doc/library/tabnanny.rst Mon Apr 27 17:29:09 2009 @@ -1,4 +1,3 @@ - :mod:`tabnanny` --- Detection of ambiguous indentation ====================================================== @@ -14,9 +13,9 @@ is possible to import it into an IDE and use the function :func:`check` described below. -.. warning:: +.. note:: - The API provided by this module is likely to change in future releases; such + The API provided by this module is likely to change in future releases; such changes may not be backward compatible. Modified: python/trunk/Doc/library/unittest.rst ============================================================================== --- python/trunk/Doc/library/unittest.rst (original) +++ python/trunk/Doc/library/unittest.rst Mon Apr 27 17:29:09 2009 @@ -1086,7 +1086,7 @@ creates an instance of the class for each test method defined for the class. - .. warning:: + .. note:: While using a hierarchy of :class:`TestCase`\ -derived classes can be convenient in sharing fixtures and helper functions, defining test Modified: python/trunk/Doc/reference/compound_stmts.rst ============================================================================== --- python/trunk/Doc/reference/compound_stmts.rst (original) +++ python/trunk/Doc/reference/compound_stmts.rst Mon Apr 27 17:29:09 2009 @@ -178,7 +178,7 @@ effect of Pascal's ``for i := a to b do``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``. -.. warning:: +.. note:: .. index:: single: loop; over mutable sequence Modified: python/trunk/Doc/reference/executionmodel.rst ============================================================================== --- python/trunk/Doc/reference/executionmodel.rst (original) +++ python/trunk/Doc/reference/executionmodel.rst Mon Apr 27 17:29:09 2009 @@ -231,7 +231,7 @@ :keyword:`except` clause is selected by object identity. An arbitrary value can be raised along with the identifying string which can be passed to the handler. -.. warning:: +.. note:: Messages to exceptions are not part of the Python API. Their contents may change from one version of Python to the next without warning and should not be From python-checkins at python.org Mon Apr 27 17:29:27 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 17:29:27 +0200 (CEST) Subject: [Python-checkins] r72010 - in python/trunk/Doc/library: aepack.rst aetools.rst aetypes.rst autogil.rst bastion.rst binhex.rst carbon.rst colorpicker.rst commands.rst easydialogs.rst framework.rst gl.rst hotshot.rst ic.rst mac.rst macos.rst macostools.rst plistlib.rst rexec.rst undoc.rst Message-ID: <20090427152927.4A3221E4016@bag.python.org> Author: georg.brandl Date: Mon Apr 27 17:29:26 2009 New Revision: 72010 Log: Demote warnings to notices, part 2: stuff that is 2.x-only. Modified: python/trunk/Doc/library/aepack.rst python/trunk/Doc/library/aetools.rst python/trunk/Doc/library/aetypes.rst python/trunk/Doc/library/autogil.rst python/trunk/Doc/library/bastion.rst python/trunk/Doc/library/binhex.rst python/trunk/Doc/library/carbon.rst python/trunk/Doc/library/colorpicker.rst python/trunk/Doc/library/commands.rst python/trunk/Doc/library/easydialogs.rst python/trunk/Doc/library/framework.rst python/trunk/Doc/library/gl.rst python/trunk/Doc/library/hotshot.rst python/trunk/Doc/library/ic.rst python/trunk/Doc/library/mac.rst python/trunk/Doc/library/macos.rst python/trunk/Doc/library/macostools.rst python/trunk/Doc/library/plistlib.rst python/trunk/Doc/library/rexec.rst python/trunk/Doc/library/undoc.rst Modified: python/trunk/Doc/library/aepack.rst ============================================================================== --- python/trunk/Doc/library/aepack.rst (original) +++ python/trunk/Doc/library/aepack.rst Mon Apr 27 17:29:26 2009 @@ -14,9 +14,9 @@ AppleEvent descriptor is handled by Python objects of built-in type :class:`AEDesc`, defined in module :mod:`Carbon.AE`. -.. warning:: +.. note:: - This module is removed in 3.0. + This module has been removed in Python 3.x. The :mod:`aepack` module defines the following functions: Modified: python/trunk/Doc/library/aetools.rst ============================================================================== --- python/trunk/Doc/library/aetools.rst (original) +++ python/trunk/Doc/library/aetools.rst Mon Apr 27 17:29:26 2009 @@ -22,9 +22,9 @@ manager, see section :ref:`osx-gui-scripts` for details. This restriction may be lifted in future releases. -.. warning:: +.. note:: - This module is removed in 3.0. + This module has been removed in Python 3.x. The :mod:`aetools` module defines the following functions: Modified: python/trunk/Doc/library/aetypes.rst ============================================================================== --- python/trunk/Doc/library/aetypes.rst (original) +++ python/trunk/Doc/library/aetypes.rst Mon Apr 27 17:29:26 2009 @@ -31,9 +31,9 @@ contains object specifiers for a number of common OSA classes such as ``Document``, ``Window``, ``Character``, etc. -.. warning:: +.. note:: - This module is removed in 3.0. + This module has been removed in Python 3.x. Modified: python/trunk/Doc/library/autogil.rst ============================================================================== --- python/trunk/Doc/library/autogil.rst (original) +++ python/trunk/Doc/library/autogil.rst Mon Apr 27 17:29:26 2009 @@ -13,9 +13,9 @@ automatically locks and unlocks Python's :term:`Global Interpreter Lock` when running an event loop. -.. warning:: +.. note:: - This module has been removed in 3.0. + This module has been removed in Python 3.x. .. exception:: AutoGILError Modified: python/trunk/Doc/library/bastion.rst ============================================================================== --- python/trunk/Doc/library/bastion.rst (original) +++ python/trunk/Doc/library/bastion.rst Mon Apr 27 17:29:26 2009 @@ -15,7 +15,7 @@ .. versionchanged:: 2.3 Disabled module. -.. warning:: +.. note:: The documentation has been left in place to help in reading old code that uses the module. Modified: python/trunk/Doc/library/binhex.rst ============================================================================== --- python/trunk/Doc/library/binhex.rst (original) +++ python/trunk/Doc/library/binhex.rst Mon Apr 27 17:29:26 2009 @@ -1,4 +1,3 @@ - :mod:`binhex` --- Encode and decode binhex4 files ================================================= @@ -11,9 +10,9 @@ file and the finder information are encoded (or decoded), on other platforms only the data fork is handled. -.. warning:: +.. note:: - In 3.0, special Macintosh support is removed. + In Python 3.x, special Macintosh support has been removed. The :mod:`binhex` module defines the following functions: Modified: python/trunk/Doc/library/carbon.rst ============================================================================== --- python/trunk/Doc/library/carbon.rst (original) +++ python/trunk/Doc/library/carbon.rst Mon Apr 27 17:29:26 2009 @@ -22,9 +22,9 @@ from Carbon import AE -.. warning:: +.. note:: - The Carbon modules are removed in 3.0. + The Carbon modules have been removed in Python 3.0. :mod:`Carbon.AE` --- Apple Events Modified: python/trunk/Doc/library/colorpicker.rst ============================================================================== --- python/trunk/Doc/library/colorpicker.rst (original) +++ python/trunk/Doc/library/colorpicker.rst Mon Apr 27 17:29:26 2009 @@ -13,9 +13,9 @@ The :mod:`ColorPicker` module provides access to the standard color picker dialog. -.. warning:: +.. note:: - This module is removed in 3.0. + This module has been removed in Python 3.x. .. function:: GetColor(prompt, rgb) Modified: python/trunk/Doc/library/commands.rst ============================================================================== --- python/trunk/Doc/library/commands.rst (original) +++ python/trunk/Doc/library/commands.rst Mon Apr 27 17:29:26 2009 @@ -22,11 +22,12 @@ processes and retrieving their results. Using the :mod:`subprocess` module is preferable to using the :mod:`commands` module. -.. warning:: +.. note:: - In 3.x, :func:`getstatus` and two undocumented functions (:func:`mk2arg` and - :func:`mkarg`) have been removed. Also, :func:`getstatusoutput` and - :func:`getoutput` have been moved to the :mod:`subprocess` module. + In Python 3.x, :func:`getstatus` and two undocumented functions + (:func:`mk2arg` and :func:`mkarg`) have been removed. Also, + :func:`getstatusoutput` and :func:`getoutput` have been moved to the + :mod:`subprocess` module. The :mod:`commands` module defines the following functions: Modified: python/trunk/Doc/library/easydialogs.rst ============================================================================== --- python/trunk/Doc/library/easydialogs.rst (original) +++ python/trunk/Doc/library/easydialogs.rst Mon Apr 27 17:29:26 2009 @@ -16,9 +16,9 @@ type and item number) to those in the default :const:`DLOG` resource. See source code for details. -.. warning:: +.. note:: - This module is removed in 3.0. + This module has been removed in Python 3.x. The :mod:`EasyDialogs` module defines the following functions: Modified: python/trunk/Doc/library/framework.rst ============================================================================== --- python/trunk/Doc/library/framework.rst (original) +++ python/trunk/Doc/library/framework.rst Mon Apr 27 17:29:26 2009 @@ -16,9 +16,9 @@ dialog window in a non-standard way it is not necessary to override the complete event handling. -.. warning:: +.. note:: - This module is removed in 3.0. + This module has been removed in Python 3.x. Work on the :mod:`FrameWork` has pretty much stopped, now that :mod:`PyObjC` is available for full Cocoa access from Python, and the documentation describes Modified: python/trunk/Doc/library/gl.rst ============================================================================== --- python/trunk/Doc/library/gl.rst (original) +++ python/trunk/Doc/library/gl.rst Mon Apr 27 17:29:26 2009 @@ -1,4 +1,3 @@ - :mod:`gl` --- *Graphics Library* interface ========================================== @@ -17,9 +16,9 @@ .. warning:: - Some illegal calls to the GL library cause the Python interpreter to dump core. - In particular, the use of most GL calls is unsafe before the first window is - opened. + Some illegal calls to the GL library cause the Python interpreter to dump + core. In particular, the use of most GL calls is unsafe before the first + window is opened. The module is too large to document here in its entirety, but the following should help you to get started. The parameter conventions for the C functions Modified: python/trunk/Doc/library/hotshot.rst ============================================================================== --- python/trunk/Doc/library/hotshot.rst (original) +++ python/trunk/Doc/library/hotshot.rst Mon Apr 27 17:29:26 2009 @@ -26,7 +26,7 @@ The results should be more meaningful than in the past: the timing core contained a critical bug. -.. warning:: +.. note:: The :mod:`hotshot` profiler does not yet work well with threads. It is useful to use an unthreaded script to run the profiler over the code you're interested in Modified: python/trunk/Doc/library/ic.rst ============================================================================== --- python/trunk/Doc/library/ic.rst (original) +++ python/trunk/Doc/library/ic.rst Mon Apr 27 17:29:26 2009 @@ -1,4 +1,3 @@ - :mod:`ic` --- Access to the Mac OS X Internet Config ==================================================== @@ -11,9 +10,9 @@ This module provides access to various internet-related preferences set through :program:`System Preferences` or the :program:`Finder`. -.. warning:: +.. note:: - This module is removed in 3.0. + This module has been removed in Python 3.x. .. index:: module: icglue Modified: python/trunk/Doc/library/mac.rst ============================================================================== --- python/trunk/Doc/library/mac.rst (original) +++ python/trunk/Doc/library/mac.rst Mon Apr 27 17:29:26 2009 @@ -10,9 +10,9 @@ modules, and the HOWTO :ref:`using-on-mac` for a general introduction to Mac-specific Python programming. -.. warning:: +.. note:: - These modules are deprecated and are removed in 3.0. + These modules are deprecated and have been removed in Python 3.x. .. toctree:: Modified: python/trunk/Doc/library/macos.rst ============================================================================== --- python/trunk/Doc/library/macos.rst (original) +++ python/trunk/Doc/library/macos.rst Mon Apr 27 17:29:26 2009 @@ -11,9 +11,9 @@ interpreter, such as how the interpreter eventloop functions and the like. Use with care. -.. warning:: +.. note:: - This module is removed in 3.0. + This module has been removed in Python 3.x. Note the capitalization of the module name; this is a historical artifact. Modified: python/trunk/Doc/library/macostools.rst ============================================================================== --- python/trunk/Doc/library/macostools.rst (original) +++ python/trunk/Doc/library/macostools.rst Mon Apr 27 17:29:26 2009 @@ -13,9 +13,9 @@ :class:`FSSpec` objects. This module expects a filesystem which supports forked files, so it should not be used on UFS partitions. -.. warning:: +.. note:: - This module is removed in 3.0. + This module has been removed in Python 3.0. The :mod:`macostools` module defines the following functions: Modified: python/trunk/Doc/library/plistlib.rst ============================================================================== --- python/trunk/Doc/library/plistlib.rst (original) +++ python/trunk/Doc/library/plistlib.rst Mon Apr 27 17:29:26 2009 @@ -75,10 +75,9 @@ Read a plist from the resource with type *restype* from the resource fork of *path*. Availability: Mac OS X. - .. warning:: - - In 3.0, this function is removed. + .. note:: + In Python 3.x, this function has been removed. .. function:: writePlistToResource(rootObject, path[, restype='plst'[, resid=0]]) @@ -86,9 +85,9 @@ Write *rootObject* as a resource with type *restype* to the resource fork of *path*. Availability: Mac OS X. - .. warning:: + .. note:: - In 3.0, this function is removed. + In Python 3.x, this function has been removed. Modified: python/trunk/Doc/library/rexec.rst ============================================================================== --- python/trunk/Doc/library/rexec.rst (original) +++ python/trunk/Doc/library/rexec.rst Mon Apr 27 17:29:26 2009 @@ -1,4 +1,3 @@ - :mod:`rexec` --- Restricted execution framework =============================================== Modified: python/trunk/Doc/library/undoc.rst ============================================================================== --- python/trunk/Doc/library/undoc.rst (original) +++ python/trunk/Doc/library/undoc.rst Mon Apr 27 17:29:26 2009 @@ -20,9 +20,8 @@ Some of these are very old and/or not very robust; marked with "hmm." :mod:`ihooks` - --- Import hook support (for :mod:`rexec`; may become obsolete). - - .. warning:: The :mod:`ihooks` module has been removed in Python 3.0. + --- Import hook support (for :mod:`rexec`; may become obsolete). Removed in + Python 3.x. Platform specific modules @@ -47,27 +46,19 @@ ========== :mod:`audiodev` - --- Platform-independent API for playing audio data. - - .. warning:: The :mod:`audiodev` module has been removed in 3.0. + --- Platform-independent API for playing audio data. Removed in Python 3.x. :mod:`linuxaudiodev` --- Play audio data on the Linux audio device. Replaced in Python 2.3 by the - :mod:`ossaudiodev` module. - - .. warning:: The :mod:`linuxaudiodev` module has been removed in Python 3.0. + :mod:`ossaudiodev` module. Removed in Python 3.x. :mod:`sunaudio` --- Interpret Sun audio headers (may become obsolete or a tool/demo). - - .. warning:: The :mod:`sunaudio` module has been removed in Python 3.0. + Removed in Python 3.x. :mod:`toaiff` --- Convert "arbitrary" sound files to AIFF files; should probably become a tool - or demo. Requires the external program :program:`sox`. - - - .. warning:: The :mod:`toaiff` module has been removed in 3.0. + or demo. Requires the external program :program:`sox`. Removed in Python 3.x. .. _undoc-mac-modules: @@ -239,9 +230,8 @@ \envvar{PYTHONPATH}. :mod:`timing` - --- Measure time intervals to high resolution (use :func:`time.clock` instead). - - .. warning:: The :mod:`timing` module has been removed in Python 3.0. + --- Measure time intervals to high resolution (use :func:`time.clock` + instead). Removed in Python 3.x. SGI-specific Extension modules @@ -255,6 +245,4 @@ :mod:`sv` --- Interface to the "simple video" board on SGI Indigo (obsolete hardware). - - .. warning:: The :mod:`sv` module has been removed in Python 3.0. - + Removed in Python 3.x. From python-checkins at python.org Mon Apr 27 17:35:22 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 17:35:22 +0200 (CEST) Subject: [Python-checkins] r72011 - python/branches/py3k Message-ID: <20090427153522.3F25D1E4016@bag.python.org> Author: georg.brandl Date: Mon Apr 27 17:35:21 2009 New Revision: 72011 Log: Blocked revisions 72010 via svnmerge ........ r72010 | georg.brandl | 2009-04-27 17:29:26 +0200 (Mo, 27 Apr 2009) | 2 lines Demote warnings to notices, part 2: stuff that is 2.x-only. ........ Modified: python/branches/py3k/ (props changed) From buildbot at python.org Mon Apr 27 17:49:09 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 27 Apr 2009 15:49:09 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 3.x Message-ID: <20090427154909.7BA6A1E4016@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%203.x/builds/709 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: make: *** [buildbottest] Unknown signal 32 sincerely, -The Buildbot From buildbot at python.org Mon Apr 27 18:16:14 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 27 Apr 2009 16:16:14 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090427161614.2A2471E41C2@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/652 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_time make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Mon Apr 27 18:16:25 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 27 Apr 2009 16:16:25 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 3.x Message-ID: <20090427161625.AA2D21E4191@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%203.x/builds/697 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_os make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 27 18:20:51 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:20:51 +0200 (CEST) Subject: [Python-checkins] r72012 - in python/branches/py3k: Doc/c-api/intro.rst Doc/documenting/markup.rst Doc/extending/extending.rst Doc/library/2to3.rst Doc/library/aifc.rst Doc/library/codeop.rst Doc/library/configparser.rst Doc/library/fileinput.rst Doc/library/functions.rst Doc/library/http.client.rst Doc/library/inspect.rst Doc/library/locale.rst Doc/library/marshal.rst Doc/library/os.path.rst Doc/library/pickle.rst Doc/library/string.rst Doc/library/subprocess.rst Doc/library/tabnanny.rst Doc/library/unittest.rst Doc/reference/compound_stmts.rst Doc/reference/executionmodel.rst Message-ID: <20090427162051.026391E41AA@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:20:50 2009 New Revision: 72012 Log: Merged revisions 72009 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72009 | georg.brandl | 2009-04-27 17:29:09 +0200 (Mo, 27 Apr 2009) | 3 lines Demote warnings to notices where appropriate, following the goal that as few "red box" warnings should clutter the docs as possible. Part 1: stuff that gets merged to Py3k. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/intro.rst python/branches/py3k/Doc/documenting/markup.rst python/branches/py3k/Doc/extending/extending.rst python/branches/py3k/Doc/library/2to3.rst python/branches/py3k/Doc/library/aifc.rst python/branches/py3k/Doc/library/codeop.rst python/branches/py3k/Doc/library/configparser.rst python/branches/py3k/Doc/library/fileinput.rst python/branches/py3k/Doc/library/functions.rst python/branches/py3k/Doc/library/http.client.rst python/branches/py3k/Doc/library/inspect.rst python/branches/py3k/Doc/library/locale.rst python/branches/py3k/Doc/library/marshal.rst python/branches/py3k/Doc/library/os.path.rst python/branches/py3k/Doc/library/pickle.rst python/branches/py3k/Doc/library/string.rst python/branches/py3k/Doc/library/subprocess.rst python/branches/py3k/Doc/library/tabnanny.rst python/branches/py3k/Doc/library/unittest.rst python/branches/py3k/Doc/reference/compound_stmts.rst python/branches/py3k/Doc/reference/executionmodel.rst Modified: python/branches/py3k/Doc/c-api/intro.rst ============================================================================== --- python/branches/py3k/Doc/c-api/intro.rst (original) +++ python/branches/py3k/Doc/c-api/intro.rst Mon Apr 27 18:20:50 2009 @@ -44,7 +44,7 @@ ````, ````, ````, and ```` (if available). -.. warning:: +.. note:: Since Python may define some pre-processor definitions which affect the standard headers on some systems, you *must* include :file:`Python.h` before any standard Modified: python/branches/py3k/Doc/documenting/markup.rst ============================================================================== --- python/branches/py3k/Doc/documenting/markup.rst (original) +++ python/branches/py3k/Doc/documenting/markup.rst Mon Apr 27 18:20:50 2009 @@ -594,11 +594,11 @@ .. describe:: warning - An important bit of information about an API that a user should be very aware - of when using whatever bit of API the warning pertains to. The content of - the directive should be written in complete sentences and include all - appropriate punctuation. This differs from ``note`` in that it is recommended - over ``note`` for information regarding security. + An important bit of information about an API that a user should be aware of + when using whatever bit of API the warning pertains to. The content of the + directive should be written in complete sentences and include all appropriate + punctuation. This should only be chosen over ``note`` for information + regarding the possibility of crashes, data loss, or security implications. .. describe:: versionadded Modified: python/branches/py3k/Doc/extending/extending.rst ============================================================================== --- python/branches/py3k/Doc/extending/extending.rst (original) +++ python/branches/py3k/Doc/extending/extending.rst Mon Apr 27 18:20:50 2009 @@ -47,7 +47,7 @@ which pulls in the Python API (you can add a comment describing the purpose of the module and a copyright notice if you like). -.. warning:: +.. note:: Since Python may define some pre-processor definitions which affect the standard headers on some systems, you *must* include :file:`Python.h` before any standard Modified: python/branches/py3k/Doc/library/2to3.rst ============================================================================== --- python/branches/py3k/Doc/library/2to3.rst (original) +++ python/branches/py3k/Doc/library/2to3.rst Mon Apr 27 18:20:50 2009 @@ -354,7 +354,7 @@ .. moduleauthor:: Collin Winter -.. warning:: +.. note:: The :mod:`lib2to3` API should be considered unstable and may change drastically in the future. Modified: python/branches/py3k/Doc/library/aifc.rst ============================================================================== --- python/branches/py3k/Doc/library/aifc.rst (original) +++ python/branches/py3k/Doc/library/aifc.rst Mon Apr 27 18:20:50 2009 @@ -1,4 +1,3 @@ - :mod:`aifc` --- Read and write AIFF and AIFC files ================================================== @@ -16,10 +15,11 @@ samples in a file. AIFF-C is a newer version of the format that includes the ability to compress the audio data. -.. warning:: +.. note:: Some operations may only work under IRIX; these will raise :exc:`ImportError` - when attempting to import the :mod:`cl` module, which is only available on IRIX. + when attempting to import the :mod:`cl` module, which is only available on + IRIX. Audio files have a number of parameters that describe the audio data. The sampling rate or frame rate is the number of times per second the sound is Modified: python/branches/py3k/Doc/library/codeop.rst ============================================================================== --- python/branches/py3k/Doc/library/codeop.rst (original) +++ python/branches/py3k/Doc/library/codeop.rst Mon Apr 27 18:20:50 2009 @@ -42,7 +42,7 @@ (``'single'``, the default) or as an :term:`expression` (``'eval'``). Any other value will cause :exc:`ValueError` to be raised. - .. warning:: + .. note:: It is possible (but not likely) that the parser stops parsing with a successful outcome before reaching the end of the source; in this case, Modified: python/branches/py3k/Doc/library/configparser.rst ============================================================================== --- python/branches/py3k/Doc/library/configparser.rst (original) +++ python/branches/py3k/Doc/library/configparser.rst Mon Apr 27 18:20:50 2009 @@ -21,10 +21,10 @@ can use this to write Python programs which can be customized by end users easily. -.. warning:: +.. note:: - This library does *not* interpret or write the value-type prefixes used in the - Windows Registry extended version of INI syntax. + This library does *not* interpret or write the value-type prefixes used in + the Windows Registry extended version of INI syntax. The configuration file consists of sections, led by a ``[section]`` header and followed by ``name: value`` entries, with continuations in the style of Modified: python/branches/py3k/Doc/library/fileinput.rst ============================================================================== --- python/branches/py3k/Doc/library/fileinput.rst (original) +++ python/branches/py3k/Doc/library/fileinput.rst Mon Apr 27 18:20:50 2009 @@ -144,7 +144,7 @@ it is deleted when the output file is closed. In-place filtering is disabled when standard input is read. -.. warning:: +.. note:: The current implementation does not work for MS-DOS 8+3 filesystems. Modified: python/branches/py3k/Doc/library/functions.rst ============================================================================== --- python/branches/py3k/Doc/library/functions.rst (original) +++ python/branches/py3k/Doc/library/functions.rst Mon Apr 27 18:20:50 2009 @@ -359,7 +359,7 @@ global and local dictionary, respectively, which may be useful to pass around for use as the second and third argument to :func:`exec`. - .. warning:: + .. note:: The default *locals* act as described for function :func:`locals` below: modifications to the default *locals* dictionary should not be attempted. @@ -591,7 +591,7 @@ Update and return a dictionary representing the current local symbol table. - .. warning:: + .. note:: The contents of this dictionary should not be modified; changes may not affect the values of local variables used by the interpreter. @@ -1166,7 +1166,7 @@ else that has a :attr:`__dict__` attribute), returns a dictionary corresponding to the object's symbol table. - .. warning:: + .. note:: The returned dictionary should not be modified: the effects on the corresponding symbol table are undefined. [#]_ Modified: python/branches/py3k/Doc/library/http.client.rst ============================================================================== --- python/branches/py3k/Doc/library/http.client.rst (original) +++ python/branches/py3k/Doc/library/http.client.rst Mon Apr 27 18:20:50 2009 @@ -52,9 +52,9 @@ formatted file that contains your private key. *cert_file* is a PEM formatted certificate chain file. - .. warning:: + .. note:: - This does not do any certificate verification! + This does not do any certificate verification. .. class:: HTTPResponse(sock[, debuglevel=0][, strict=0]) Modified: python/branches/py3k/Doc/library/inspect.rst ============================================================================== --- python/branches/py3k/Doc/library/inspect.rst (original) +++ python/branches/py3k/Doc/library/inspect.rst Mon Apr 27 18:20:50 2009 @@ -455,7 +455,7 @@ the function name, a list of lines of context from the source code, and the index of the current line within that list. -.. warning:: +.. note:: Keeping references to frame objects, as found in the first element of the frame records these functions return, can cause your program to create reference Modified: python/branches/py3k/Doc/library/locale.rst ============================================================================== --- python/branches/py3k/Doc/library/locale.rst (original) +++ python/branches/py3k/Doc/library/locale.rst Mon Apr 27 18:20:50 2009 @@ -377,7 +377,7 @@ Return name of the n-th day of the week. - .. warning:: + .. note:: This follows the US convention of :const:`DAY_1` being Sunday, not the international convention (ISO 8601) that Monday is the first day of the week. @@ -413,7 +413,7 @@ Return a regular expression that can be used with the regex function to recognize a positive response to a yes/no question. - .. warning:: + .. note:: The expression is in the syntax suitable for the :cfunc:`regex` function from the C library, which might differ from the syntax used in :mod:`re`. Modified: python/branches/py3k/Doc/library/marshal.rst ============================================================================== --- python/branches/py3k/Doc/library/marshal.rst (original) +++ python/branches/py3k/Doc/library/marshal.rst Mon Apr 27 18:20:50 2009 @@ -73,7 +73,7 @@ file must be an open file object opened in binary mode (``'rb'`` or ``'r+b'``). - .. warning:: + .. note:: If an object containing an unsupported type was marshalled with :func:`dump`, :func:`load` will substitute ``None`` for the unmarshallable type. 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 Mon Apr 27 18:20:50 2009 @@ -23,12 +23,11 @@ their parameters. The result is an object of the same type, if a path or file name is returned. -.. warning:: +.. note:: On Windows, many of these functions do not properly support UNC pathnames. :func:`splitunc` and :func:`ismount` do handle them correctly. - .. note:: Since different operating systems have different path name conventions, there @@ -288,6 +287,33 @@ *unc* will always be the empty string. Availability: Windows. +<<<<<<< .working +======= +.. function:: walk(path, visit, arg) + + Calls the function *visit* with arguments ``(arg, dirname, names)`` for each + directory in the directory tree rooted at *path* (including *path* itself, if it + is a directory). The argument *dirname* specifies the visited directory, the + argument *names* lists the files in the directory (gotten from + ``os.listdir(dirname)``). The *visit* function may modify *names* to influence + the set of directories visited below *dirname*, e.g. to avoid visiting certain + parts of the tree. (The object referred to by *names* must be modified in + place, using :keyword:`del` or slice assignment.) + + .. note:: + + Symbolic links to directories are not treated as subdirectories, and that + :func:`walk` therefore will not visit them. To visit linked directories you must + identify them with ``os.path.islink(file)`` and ``os.path.isdir(file)``, and + invoke :func:`walk` as necessary. + + .. note:: + + This function is deprecated and has been removed in 3.0 in favor of + :func:`os.walk`. + + +>>>>>>> .merge-right.r72009 .. data:: supports_unicode_filenames True if arbitrary Unicode strings can be used as file names (within limitations Modified: python/branches/py3k/Doc/library/pickle.rst ============================================================================== --- python/branches/py3k/Doc/library/pickle.rst (original) +++ python/branches/py3k/Doc/library/pickle.rst Mon Apr 27 18:20:50 2009 @@ -66,8 +66,8 @@ .. warning:: The :mod:`pickle` module is not intended to be secure against erroneous or - maliciously constructed data. Never unpickle data received from an untrusted or - unauthenticated source. + maliciously constructed data. Never unpickle data received from an untrusted + or unauthenticated source. Note that serialization is a more primitive notion than persistence; although :mod:`pickle` reads and writes file objects, it does not handle the issue of @@ -437,6 +437,7 @@ the methods :meth:`__getstate__` and :meth:`__setstate__`. .. note:: + At unpickling time, some methods like :meth:`__getattr__`, :meth:`__getattribute__`, or :meth:`__setattr__` may be called upon the instance. In case those methods rely on some internal invariant being Modified: python/branches/py3k/Doc/library/string.rst ============================================================================== --- python/branches/py3k/Doc/library/string.rst (original) +++ python/branches/py3k/Doc/library/string.rst Mon Apr 27 18:20:50 2009 @@ -1,4 +1,3 @@ - :mod:`string` --- Common string operations ========================================== Modified: python/branches/py3k/Doc/library/subprocess.rst ============================================================================== --- python/branches/py3k/Doc/library/subprocess.rst (original) +++ python/branches/py3k/Doc/library/subprocess.rst Mon Apr 27 18:20:50 2009 @@ -321,10 +321,10 @@ .. warning:: - Use :meth:`communicate` rather than :meth:`.stdin.write`, - :meth:`.stdout.read` or :meth:`.stderr.read` to avoid deadlocks due - to any of the other OS pipe buffers filling up and blocking the child - process. + Use :meth:`communicate` rather than :attr:`.stdin.write `, + :attr:`.stdout.read ` or :attr:`.stderr.read ` to avoid + deadlocks due to any of the other OS pipe buffers filling up and blocking the + child process. .. attribute:: Popen.stdin Modified: python/branches/py3k/Doc/library/tabnanny.rst ============================================================================== --- python/branches/py3k/Doc/library/tabnanny.rst (original) +++ python/branches/py3k/Doc/library/tabnanny.rst Mon Apr 27 18:20:50 2009 @@ -1,4 +1,3 @@ - :mod:`tabnanny` --- Detection of ambiguous indentation ====================================================== @@ -14,9 +13,9 @@ is possible to import it into an IDE and use the function :func:`check` described below. -.. warning:: +.. note:: - The API provided by this module is likely to change in future releases; such + The API provided by this module is likely to change in future releases; such changes may not be backward compatible. Modified: python/branches/py3k/Doc/library/unittest.rst ============================================================================== --- python/branches/py3k/Doc/library/unittest.rst (original) +++ python/branches/py3k/Doc/library/unittest.rst Mon Apr 27 18:20:50 2009 @@ -1085,7 +1085,7 @@ creates an instance of the class for each test method defined for the class. - .. warning:: + .. note:: While using a hierarchy of :class:`TestCase`\ -derived classes can be convenient in sharing fixtures and helper functions, defining test Modified: python/branches/py3k/Doc/reference/compound_stmts.rst ============================================================================== --- python/branches/py3k/Doc/reference/compound_stmts.rst (original) +++ python/branches/py3k/Doc/reference/compound_stmts.rst Mon Apr 27 18:20:50 2009 @@ -186,7 +186,7 @@ emulate the effect of Pascal's ``for i := a to b do``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``. -.. warning:: +.. note:: .. index:: single: loop; over mutable sequence Modified: python/branches/py3k/Doc/reference/executionmodel.rst ============================================================================== --- python/branches/py3k/Doc/reference/executionmodel.rst (original) +++ python/branches/py3k/Doc/reference/executionmodel.rst Mon Apr 27 18:20:50 2009 @@ -222,7 +222,7 @@ the instance or a base class thereof. The instance can be received by the handler and can carry additional information about the exceptional condition. -.. warning:: +.. note:: Exception messages are not part of the Python API. Their contents may change from one version of Python to the next without warning and should not be From python-checkins at python.org Mon Apr 27 18:22:44 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:22:44 +0200 (CEST) Subject: [Python-checkins] r72013 - in python/branches/py3k: Doc/library/traceback.rst Message-ID: <20090427162245.003B11E412B@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:22:44 2009 New Revision: 72013 Log: Merged revisions 72007 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72007 | georg.brandl | 2009-04-27 17:09:25 +0200 (Mo, 27 Apr 2009) | 1 line #5856: fix typo s in traceback example. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/traceback.rst Modified: python/branches/py3k/Doc/library/traceback.rst ============================================================================== --- python/branches/py3k/Doc/library/traceback.rst (original) +++ python/branches/py3k/Doc/library/traceback.rst Mon Apr 27 18:22:44 2009 @@ -269,10 +269,10 @@ This last example demonstrates the final few formatting functions:: >>> import traceback - >>> format_list([('spam.py', 3, '', 'spam.eggs()'), - ... ('eggs.py', 42, 'eggs', 'return "bacon"')]) + >>> traceback.format_list([('spam.py', 3, '', 'spam.eggs()'), + ... ('eggs.py', 42, 'eggs', 'return "bacon"')]) [' File "spam.py", line 3, in \n spam.eggs()\n', ' File "eggs.py", line 42, in eggs\n return "bacon"\n'] - >>> theError = IndexError('tuple indx out of range') - >>> traceback.format_exception_only(type(theError), theError) + >>> an_error = IndexError('tuple index out of range') + >>> traceback.format_exception_only(type(an_error), an_error) ['IndexError: tuple index out of range\n'] From python-checkins at python.org Mon Apr 27 18:23:47 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:23:47 +0200 (CEST) Subject: [Python-checkins] r72014 - in python/branches/py3k: Doc/distutils/apiref.rst Doc/using/cmdline.rst Message-ID: <20090427162347.4D4121E405E@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:23:47 2009 New Revision: 72014 Log: Merged revisions 72008 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72008 | georg.brandl | 2009-04-27 17:10:44 +0200 (Mo, 27 Apr 2009) | 1 line Remove ".. warning::" markup that doesnt contain warnings for users, rather todo items. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/distutils/apiref.rst python/branches/py3k/Doc/using/cmdline.rst Modified: python/branches/py3k/Doc/distutils/apiref.rst ============================================================================== --- python/branches/py3k/Doc/distutils/apiref.rst (original) +++ python/branches/py3k/Doc/distutils/apiref.rst Mon Apr 27 18:23:47 2009 @@ -869,9 +869,7 @@ prefix of all files and directories in the archive. *root_dir* and *base_dir* both default to the current directory. Returns the name of the archive file. - .. warning:: - - This should be changed to support bz2 files + .. XXX This should be changed to support bz2 files. .. function:: make_tarball(base_name, base_dir[, compress='gzip', verbose=0, dry_run=0]) @@ -884,9 +882,7 @@ possibly plus the appropriate compression extension (:file:`.gz`, :file:`.bz2` or :file:`.Z`). Return the output filename. - .. warning:: - - This should be replaced with calls to the :mod:`tarfile` module. + .. XXX This should be replaced with calls to the :mod:`tarfile` module. .. function:: make_zipfile(base_name, base_dir[, verbose=0, dry_run=0]) @@ -1329,10 +1325,8 @@ Wraps *text* to less than *width* wide. - .. warning:: - - Should be replaced with :mod:`textwrap` (which is available in Python 2.3 and - later). + .. XXX Should be replaced with :mod:`textwrap` (which is available in Python + 2.3 and later). .. class:: FancyGetopt([option_table=None]) @@ -1381,8 +1375,8 @@ ================================================ .. module:: distutils.filelist - :synopsis: The FileList class, used for poking about the file system and building lists of - files. + :synopsis: The FileList class, used for poking about the file system and + building lists of files. This module provides the :class:`FileList` class, used for poking about the @@ -1396,13 +1390,8 @@ :synopsis: A simple logging mechanism, 282-style -.. warning:: - - Should be replaced with standard :mod:`logging` module. +.. XXX Should be replaced with standard :mod:`logging` module. -.. % \subsubsection{\module{} --- } -.. % \declaremodule{standard}{distutils.magic} -.. % \modulesynopsis{ } :mod:`distutils.spawn` --- Spawn a sub-process Modified: python/branches/py3k/Doc/using/cmdline.rst ============================================================================== --- python/branches/py3k/Doc/using/cmdline.rst (original) +++ python/branches/py3k/Doc/using/cmdline.rst Mon Apr 27 18:23:47 2009 @@ -318,7 +318,7 @@ Skip the first line of the source, allowing use of non-Unix forms of ``#!cmd``. This is intended for a DOS specific hack only. - .. warning:: The line numbers in error messages will be off by one! + .. note:: The line numbers in error messages will be off by one. .. _using-on-envvars: From python-checkins at python.org Mon Apr 27 18:24:36 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:24:36 +0200 (CEST) Subject: [Python-checkins] r72015 - python/branches/py3k Message-ID: <20090427162436.599E61E401D@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:24:36 2009 New Revision: 72015 Log: Recorded merge of revisions 72004 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72004 | vinay.sajip | 2009-04-27 15:44:27 +0200 (Mo, 27 Apr 2009) | 1 line Issue #5854: Updated __all__ to include some missing names and remove some names which should not be exported. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Mon Apr 27 18:28:58 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:28:58 +0200 (CEST) Subject: [Python-checkins] r72016 - in python/branches/py3k: Doc/Makefile Doc/tools/sphinxext/pyspecific.py Lib/pydoc.py Lib/pydoc_data Lib/pydoc_topics.py Message-ID: <20090427162858.66BD81E401D@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:28:57 2009 New Revision: 72016 Log: Merged revisions 71960 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71960 | georg.brandl | 2009-04-26 11:56:44 +0200 (So, 26 Apr 2009) | 1 line Move pydoc_topics module to its own subdirectory, so that no generated code is in Lib/. ........ Added: python/branches/py3k/Lib/pydoc_data/ - copied from r71960, /python/trunk/Lib/pydoc_data/ Removed: python/branches/py3k/Lib/pydoc_topics.py Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/Makefile python/branches/py3k/Doc/tools/sphinxext/pyspecific.py python/branches/py3k/Lib/pydoc.py Modified: python/branches/py3k/Doc/Makefile ============================================================================== --- python/branches/py3k/Doc/Makefile (original) +++ python/branches/py3k/Doc/Makefile Mon Apr 27 18:28:57 2009 @@ -28,6 +28,7 @@ @echo " coverage to check documentation coverage for library and C API" @echo " dist to create a \"dist\" directory with archived docs for download" +# Note: if you update versions here, do the same in make.bat and README.txt checkout: @if [ ! -d tools/sphinx ]; then \ echo "Checking out Sphinx..."; \ @@ -101,8 +102,8 @@ pydoc-topics: BUILDER = pydoc-topics pydoc-topics: build - @echo "Building finished; now copy build/pydoc-topics/pydoc_topics.py " \ - "into the Lib/ directory" + @echo "Building finished; now copy build/pydoc-topics/topics.py " \ + "to Lib/pydoc_data/topics.py" htmlview: html $(PYTHON) -c "import webbrowser; webbrowser.open('build/html/index.html')" @@ -132,7 +133,7 @@ (cd dist; zip -q -r -9 python-$(DISTVERSION)-docs-text.zip python-$(DISTVERSION)-docs-text) rm -r dist/python-$(DISTVERSION)-docs-text rm dist/python-$(DISTVERSION)-docs-text.tar - + # archive the A4 latex -rm -r build/latex make latex PAPER=a4 Modified: python/branches/py3k/Doc/tools/sphinxext/pyspecific.py ============================================================================== --- python/branches/py3k/Doc/tools/sphinxext/pyspecific.py (original) +++ python/branches/py3k/Doc/tools/sphinxext/pyspecific.py Mon Apr 27 18:28:57 2009 @@ -5,7 +5,7 @@ Sphinx extension with Python doc-specific markup. - :copyright: 2008 by Georg Brandl. + :copyright: 2008, 2009 by Georg Brandl. :license: Python license. """ @@ -87,7 +87,7 @@ self.topics[label] = str(writer.output) def finish(self): - f = open(path.join(self.outdir, 'pydoc_topics.py'), 'w') + f = open(path.join(self.outdir, 'topics.py'), 'w') try: f.write('# Autogenerated by Sphinx on %s\n' % asctime()) f.write('topics = ' + pformat(self.topics) + '\n') Modified: python/branches/py3k/Lib/pydoc.py ============================================================================== --- python/branches/py3k/Lib/pydoc.py (original) +++ python/branches/py3k/Lib/pydoc.py Mon Apr 27 18:28:57 2009 @@ -1530,11 +1530,11 @@ # These dictionaries map a topic name to either an alias, or a tuple # (label, seealso-items). The "label" is the label of the corresponding # section in the .rst file under Doc/ and an index into the dictionary - # in pydoc_topics.py. + # in pydoc_data/topics.py. # # CAUTION: if you change one of these dictionaries, be sure to adapt the # list of needed labels in Doc/tools/sphinxext/pyspecific.py and - # regenerate the pydoc_topics.py file by running + # regenerate the pydoc_data/topics.py file by running # make pydoc-topics # in Doc/ and copying the output file into the Lib/ directory. @@ -1809,11 +1809,11 @@ def showtopic(self, topic, more_xrefs=''): try: - import pydoc_topics + import pydoc_data.topics except ImportError: self.output.write(''' Sorry, topic and keyword documentation is not available because the -module "pydoc_topics" could not be found. +module "pydoc_data.topics" could not be found. ''') return target = self.topics.get(topic, self.keywords.get(topic)) @@ -1825,7 +1825,7 @@ label, xrefs = target try: - doc = pydoc_topics.topics[label] + doc = pydoc_data.topics.topics[label] except KeyError: self.output.write('no documentation found for %s\n' % repr(topic)) return Deleted: python/branches/py3k/Lib/pydoc_topics.py ============================================================================== --- python/branches/py3k/Lib/pydoc_topics.py Mon Apr 27 18:28:57 2009 +++ (empty file) @@ -1,78 +0,0 @@ -# Autogenerated by Sphinx on Thu Nov 20 20:13:48 2008 -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:\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 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 a sequence 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* 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(In the current implementation, the syntax for targets is taken to be\nthe same as for expressions, and invalid syntax is rejected during the\ncode generation phase, causing less 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 ::= target augop (expression_list | yield_expression)\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 initial value is\nretrieved with a ``getattr()`` and the result is assigned with a\n``setattr()``. Notice that the two methods do not necessarily refer\nto the same variable. When ``getattr()`` refers to a class variable,\n``setattr()`` still writes to an instance variable. For example:\n\n class A:\n x = 3 # class variable\n a = A()\n a.x += 1 # writes a.x as 4 leaving A.x as 3\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', - 'atom-literals': "\nLiterals\n********\n\nPython supports string and bytes literals and various numeric\nliterals:\n\n literal ::= stringliteral | bytesliteral\n | integer | floatnumber | imagnumber\n\nEvaluation of a literal yields an object of the given type (string,\nbytes, integer, floating point number, complex number) with the given\nvalue. The value may be approximated in the case of floating point\nand imaginary (complex) literals. See section *Literals* for details.\n\nWith the exception of bytes literals, these all correspond to\nimmutable data types, and hence the object's identity is less\nimportant than its value. Multiple evaluations of literals with the\nsame value (either the same occurrence in the program text or a\ndifferent occurrence) may obtain the same object or a different object\nwith the same value.\n", - 'attribute-access': '\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 builtin 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. Normally, data\ndescriptors define both ``__get__()`` and ``__set__()``, while non-\ndata descriptors have just the ``__get__()`` method. Data descriptors\nalways override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances. [2]\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* 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* 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__*.\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', - 'attribute-references': '\nAttribute references\n********************\n\nAn attribute reference is a primary followed by a period and a name:\n\n attributeref ::= primary "." identifier\n\nThe primary must evaluate to an object of a type that supports\nattribute references, which most objects do. This object is then\nasked to produce the attribute whose name is the identifier (which can\nbe customized by overriding the ``__getattr__()`` method). If this\nattribute is not available, the exception ``AttributeError`` is\nraised. Otherwise, the type and value of the object produced is\ndetermined by the object. Multiple evaluations of the same attribute\nreference may yield different objects.\n', - 'augassign': '\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 ::= target augop (expression_list | yield_expression)\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 initial value is\nretrieved with a ``getattr()`` and the result is assigned with a\n``setattr()``. Notice that the two methods do not necessarily refer\nto the same variable. When ``getattr()`` refers to a class variable,\n``setattr()`` still writes to an instance variable. For example:\n\n class A:\n x = 3 # class variable\n a = A()\n a.x += 1 # writes a.x as 4 leaving A.x as 3\n', - 'binary': '\nBinary arithmetic operations\n****************************\n\nThe binary arithmetic operations have the conventional priority\nlevels. Note that some of these operations also apply to certain non-\nnumeric types. Apart from the power operator, there are only two\nlevels, one for multiplicative operators and one for additive\noperators:\n\n m_expr ::= u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr\n | m_expr "%" u_expr\n a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr\n\nThe ``*`` (multiplication) operator yields the product of its\narguments. The arguments must either both be numbers, or one argument\nmust be an integer and the other must be a sequence. In the former\ncase, the numbers are converted to a common type and then multiplied\ntogether. In the latter case, sequence repetition is performed; a\nnegative repetition factor yields an empty sequence.\n\nThe ``/`` (division) and ``//`` (floor division) operators yield the\nquotient of their arguments. The numeric arguments are first\nconverted to a common type. Integer division yields a float, while\nfloor division of integers results in an integer; the result is that\nof mathematical division with the \'floor\' function applied to the\nresult. Division by zero raises the ``ZeroDivisionError`` exception.\n\nThe ``%`` (modulo) operator yields the remainder from the division of\nthe first argument by the second. The numeric arguments are first\nconverted to a common type. A zero right argument raises the\n``ZeroDivisionError`` exception. The arguments may be floating point\nnumbers, e.g., ``3.14%0.7`` equals ``0.34`` (since ``3.14`` equals\n``4*0.7 + 0.34``.) The modulo operator always yields a result with\nthe same sign as its second operand (or zero); the absolute value of\nthe result is strictly smaller than the absolute value of the second\noperand [1].\n\nThe floor division and modulo operators are connected by the following\nidentity: ``x == (x//y)*y + (x%y)``. Floor division and modulo are\nalso connected with the built-in function ``divmod()``: ``divmod(x, y)\n== (x//y, x%y)``. [2].\n\nIn addition to performing the modulo operation on numbers, the ``%``\noperator is also overloaded by string objects to perform old-style\nstring formatting (also known as interpolation). The syntax for\nstring formatting is described in the Python Library Reference,\nsection *Old String Formatting Operations*.\n\nThe floor division operator, the modulo operator, and the ``divmod()``\nfunction are not defined for complex numbers. Instead, convert to a\nfloating point number using the ``abs()`` function if appropriate.\n\nThe ``+`` (addition) operator yields the sum of its arguments. The\narguments must either both be numbers or both sequences of the same\ntype. In the former case, the numbers are converted to a common type\nand then added together. In the latter case, the sequences are\nconcatenated.\n\nThe ``-`` (subtraction) operator yields the difference of its\narguments. The numeric arguments are first converted to a common\ntype.\n', - 'bitwise': '\nBinary bitwise operations\n*************************\n\nEach of the three bitwise operations has a different priority level:\n\n and_expr ::= shift_expr | and_expr "&" shift_expr\n xor_expr ::= and_expr | xor_expr "^" and_expr\n or_expr ::= xor_expr | or_expr "|" xor_expr\n\nThe ``&`` operator yields the bitwise AND of its arguments, which must\nbe integers.\n\nThe ``^`` operator yields the bitwise XOR (exclusive OR) of its\narguments, which must be integers.\n\nThe ``|`` operator yields the bitwise (inclusive) OR of its arguments,\nwhich must be integers.\n', - 'bltin-code-objects': '\nCode Objects\n************\n\nCode objects are used by the implementation to represent "pseudo-\ncompiled" executable Python code such as a function body. They differ\nfrom function objects because they don\'t contain a reference to their\nglobal execution environment. Code objects are returned by the built-\nin ``compile()`` function and can be extracted from function objects\nthrough their ``__code__`` attribute. See also the ``code`` module.\n\nA code object can be executed or evaluated by passing it (instead of a\nsource string) to the ``exec()`` or ``eval()`` built-in functions.\n\nSee *The standard type hierarchy* for more information.\n', - 'bltin-ellipsis-object': '\nThe Ellipsis Object\n*******************\n\nThis object is commonly used by slicing (see *Slicings*). It supports\nno special operations. There is exactly one ellipsis object, named\n``Ellipsis`` (a built-in name).\n\nIt is written as ``Ellipsis`` or ``...``.\n', - 'bltin-file-objects': '\nFile Objects\n************\n\nFile objects are implemented using C\'s ``stdio`` package and can be\ncreated with the built-in ``open()`` function. File objects are also\nreturned by some other built-in functions and methods, such as\n``os.popen()`` and ``os.fdopen()`` and the ``makefile()`` method of\nsocket objects. Temporary files can be created using the ``tempfile``\nmodule, and high-level file operations such as copying, moving, and\ndeleting files and directories can be achieved with the ``shutil``\nmodule.\n\nWhen a file operation fails for an I/O-related reason, the exception\n``IOError`` is raised. This includes situations where the operation\nis not defined for some reason, like ``seek()`` on a tty device or\nwriting a file opened for reading.\n\nFiles have the following methods:\n\nfile.close()\n\n Close the file. A closed file cannot be read or written any more.\n Any operation which requires that the file be open will raise a\n ``ValueError`` after the file has been closed. Calling ``close()``\n more than once is allowed.\n\n You can avoid having to call this method explicitly if you use the\n ``with`` statement. For example, the following code will\n automatically close *f* when the ``with`` block is exited:\n\n from __future__ import with_statement # This isn\'t required in Python 2.6\n\n with open("hello.txt") as f:\n for line in f:\n print(line)\n\n In older versions of Python, you would have needed to do this to\n get the same effect:\n\n f = open("hello.txt")\n try:\n for line in f:\n print(line)\n finally:\n f.close()\n\n Note: Not all "file-like" types in Python support use as a context\n manager for the ``with`` statement. If your code is intended to\n work with any file-like object, you can use the function\n ``contextlib.closing()`` instead of using the object directly.\n\nfile.flush()\n\n Flush the internal buffer, like ``stdio``\'s ``fflush``. This may\n be a no-op on some file-like objects.\n\nfile.fileno()\n\n Return the integer "file descriptor" that is used by the underlying\n implementation to request I/O operations from the operating system.\n This can be useful for other, lower level interfaces that use file\n descriptors, such as the ``fcntl`` module or ``os.read()`` and\n friends.\n\n Note: File-like objects which do not have a real file descriptor should\n *not* provide this method!\n\nfile.isatty()\n\n Return ``True`` if the file is connected to a tty(-like) device,\n else ``False``.\n\n Note: If a file-like object is not associated with a real file, this\n method should *not* be implemented.\n\nfile.__next__()\n\n A file object is its own iterator, for example ``iter(f)`` returns\n *f* (unless *f* is closed). When a file is used as an iterator,\n typically in a ``for`` loop (for example, ``for line in f:\n print(line)``), the ``__next__()`` method is called repeatedly.\n This method returns the next input line, or raises\n ``StopIteration`` when EOF is hit when the file is open for reading\n (behavior is undefined when the file is open for writing). In\n order to make a ``for`` loop the most efficient way of looping over\n the lines of a file (a very common operation), the ``__next__()``\n method uses a hidden read-ahead buffer. As a consequence of using\n a read-ahead buffer, combining ``__next__()`` with other file\n methods (like ``readline()``) does not work right. However, using\n ``seek()`` to reposition the file to an absolute position will\n flush the read-ahead buffer.\n\nfile.read([size])\n\n Read at most *size* bytes from the file (less if the read hits EOF\n before obtaining *size* bytes). If the *size* argument is negative\n or omitted, read all data until EOF is reached. The bytes are\n returned as a string object. An empty string is returned when EOF\n is encountered immediately. (For certain files, like ttys, it\n makes sense to continue reading after an EOF is hit.) Note that\n this method may call the underlying C function ``fread`` more than\n once in an effort to acquire as close to *size* bytes as possible.\n Also note that when in non-blocking mode, less data than was\n requested may be returned, even if no *size* parameter was given.\n\nfile.readline([size])\n\n Read one entire line from the file. A trailing newline character\n is kept in the string (but may be absent when a file ends with an\n incomplete line). [6] If the *size* argument is present and non-\n negative, it is a maximum byte count (including the trailing\n newline) and an incomplete line may be returned. An empty string is\n returned *only* when EOF is encountered immediately.\n\n Note: Unlike ``stdio``\'s ``fgets``, the returned string contains null\n characters (``\'\\0\'``) if they occurred in the input.\n\nfile.readlines([sizehint])\n\n Read until EOF using ``readline()`` and return a list containing\n the lines thus read. If the optional *sizehint* argument is\n present, instead of reading up to EOF, whole lines totalling\n approximately *sizehint* bytes (possibly after rounding up to an\n internal buffer size) are read. Objects implementing a file-like\n interface may choose to ignore *sizehint* if it cannot be\n implemented, or cannot be implemented efficiently.\n\nfile.seek(offset[, whence])\n\n Set the file\'s current position, like ``stdio``\'s ``fseek``. The\n *whence* argument is optional and defaults to ``os.SEEK_SET`` or\n ``0`` (absolute file positioning); other values are ``os.SEEK_CUR``\n or ``1`` (seek relative to the current position) and\n ``os.SEEK_END`` or ``2`` (seek relative to the file\'s end). There\n is no return value.\n\n For example, ``f.seek(2, os.SEEK_CUR)`` advances the position by\n two and ``f.seek(-3, os.SEEK_END)`` sets the position to the third\n to last.\n\n Note that if the file is opened for appending (mode ``\'a\'`` or\n ``\'a+\'``), any ``seek()`` operations will be undone at the next\n write. If the file is only opened for writing in append mode (mode\n ``\'a\'``), this method is essentially a no-op, but it remains useful\n for files opened in append mode with reading enabled (mode\n ``\'a+\'``). If the file is opened in text mode (without ``\'b\'``),\n only offsets returned by ``tell()`` are legal. Use of other\n offsets causes undefined behavior.\n\n Note that not all file objects are seekable.\n\nfile.tell()\n\n Return the file\'s current position, like ``stdio``\'s ``ftell``.\n\n Note: On Windows, ``tell()`` can return illegal values (after an\n ``fgets``) when reading files with Unix-style line-endings. Use\n binary mode (``\'rb\'``) to circumvent this problem.\n\nfile.truncate([size])\n\n Truncate the file\'s size. If the optional *size* argument is\n present, the file is truncated to (at most) that size. The size\n defaults to the current position. The current file position is not\n changed. Note that if a specified size exceeds the file\'s current\n size, the result is platform-dependent: possibilities include that\n the file may remain unchanged, increase to the specified size as if\n zero-filled, or increase to the specified size with undefined new\n content. Availability: Windows, many Unix variants.\n\nfile.write(str)\n\n Write a string to the file. Due to buffering, the string may not\n actually show up in the file until the ``flush()`` or ``close()``\n method is called.\n\n The meaning of the return value is not defined for every file-like\n object. Some (mostly low-level) file-like objects may return the\n number of bytes actually written, others return ``None``.\n\nfile.writelines(sequence)\n\n Write a sequence of strings to the file. The sequence can be any\n iterable object producing strings, typically a list of strings.\n There is no return value. (The name is intended to match\n ``readlines()``; ``writelines()`` does not add line separators.)\n\nFiles support the iterator protocol. Each iteration returns the same\nresult as ``file.readline()``, and iteration ends when the\n``readline()`` method returns an empty string.\n\nFile objects also offer a number of other interesting attributes.\nThese are not required for file-like objects, but should be\nimplemented if they make sense for the particular object.\n\nfile.closed\n\n bool indicating the current state of the file object. This is a\n read-only attribute; the ``close()`` method changes the value. It\n may not be available on all file-like objects.\n\nfile.encoding\n\n The encoding that this file uses. When strings are written to a\n file, they will be converted to byte strings using this encoding.\n In addition, when the file is connected to a terminal, the\n attribute gives the encoding that the terminal is likely to use\n (that information might be incorrect if the user has misconfigured\n the terminal). The attribute is read-only and may not be present\n on all file-like objects. It may also be ``None``, in which case\n the file uses the system default encoding for converting strings.\n\nfile.errors\n\n The Unicode error handler used along with the encoding.\n\nfile.mode\n\n The I/O mode for the file. If the file was created using the\n ``open()`` built-in function, this will be the value of the *mode*\n parameter. This is a read-only attribute and may not be present on\n all file-like objects.\n\nfile.name\n\n If the file object was created using ``open()``, the name of the\n file. Otherwise, some string that indicates the source of the file\n object, of the form ``<...>``. This is a read-only attribute and\n may not be present on all file-like objects.\n\nfile.newlines\n\n If Python was built with the *--with-universal-newlines* option to\n **configure** (the default) this read-only attribute exists, and\n for files opened in universal newline read mode it keeps track of\n the types of newlines encountered while reading the file. The\n values it can take are ``\'\\r\'``, ``\'\\n\'``, ``\'\\r\\n\'``, ``None``\n (unknown, no newlines read yet) or a tuple containing all the\n newline types seen, to indicate that multiple newline conventions\n were encountered. For files not opened in universal newline read\n mode the value of this attribute will be ``None``.\n', - 'bltin-null-object': "\nThe Null Object\n***************\n\nThis object is returned by functions that don't explicitly return a\nvalue. It supports no special operations. There is exactly one null\nobject, named ``None`` (a built-in name).\n\nIt is written as ``None``.\n", - 'bltin-type-objects': "\nType Objects\n************\n\nType objects represent the various object types. An object's type is\naccessed by the built-in function ``type()``. There are no special\noperations on types. The standard module ``types`` defines names for\nall standard built-in types.\n\nTypes are written like this: ````.\n", - 'booleans': '\nBoolean operations\n******************\n\nBoolean operations have the lowest priority of all Python operations:\n\n expression ::= conditional_expression | lambda_form\n expression_nocond ::= or_test | lambda_form_nocond\n conditional_expression ::= or_test ["if" or_test "else" expression]\n or_test ::= and_test | or_test "or" and_test\n and_test ::= not_test | and_test "and" not_test\n not_test ::= comparison | "not" not_test\n\nIn the context of Boolean operations, and also when expressions are\nused by control flow statements, the following values are interpreted\nas false: ``False``, ``None``, numeric zero of all types, and empty\nstrings and containers (including strings, tuples, lists,\ndictionaries, sets and frozensets). All other values are interpreted\nas true. User-defined objects can customize their truth value by\nproviding a ``__bool__()`` method.\n\nThe operator ``not`` yields ``True`` if its argument is false,\n``False`` otherwise.\n\nThe expression ``x if C else y`` first evaluates *C* (*not* *x*); if\n*C* is true, *x* is evaluated and its value is returned; otherwise,\n*y* is evaluated and its value is returned.\n\nThe expression ``x and y`` first evaluates *x*; if *x* is false, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\nThe expression ``x or y`` first evaluates *x*; if *x* is true, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\n(Note that neither ``and`` nor ``or`` restrict the value and type they\nreturn to ``False`` and ``True``, but rather return the last evaluated\nargument. This is sometimes useful, e.g., if ``s`` is a string that\nshould be replaced by a default value if it is empty, the expression\n``s or \'foo\'`` yields the desired value. Because ``not`` has to\ninvent a value anyway, it does not bother to return a value of the\nsame type as its argument, so e.g., ``not \'foo\'`` yields ``False``,\nnot ``\'\'``.)\n', - '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\nNote: An implementation may provide builtin functions whose positional\n parameters do not have names, even if they are \'named\' for the\n purpose of documentation, and which therefore cannot be supplied by\n keyword. In CPython, this is the case for functions implemented in\n C that use ``PyArg_ParseTuple`` to parse 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 ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\nClasses can also be decorated; as with 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\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by instances. Instance variables can\nbe set in a method with ``self.name = value``. Both class and\ninstance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. Descriptors can be used to create\ninstance variables with different implementation details.\n\nSee also:\n\n **PEP 3129** - Class Decorators\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\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-builtin\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, ``cmp([1,2,x], [1,2,y])`` returns\n the same as ``cmp(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 their sorted\n ``(key, value)`` lists compare equal. [4] Outcomes other than\n equality are resolved consistently, but are not otherwise defined.\n [5]\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 builtin 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\nnumberic 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`` equivalent to ``any(x is e or x == e for val e\nin y)``.\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__()`` and do\ndefine ``__getitem__()``, ``x in y`` is true if and only if there is a\nnon-negative 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. [6]\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., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nWarning: 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 N = None\n del N\n\nThat means that you have to assign the exception to a different name\nif you want to be able to refer to it after the except clause. The\nreason for this is that with the traceback attached to them,\nexceptions will form a reference cycle with the stack frame, keeping\nall locals in that frame alive until the next garbage collection\noccurs.\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" expression ["as" target] ":" suite\n\nThe execution of the ``with`` statement proceeds as follows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__enter__()`` method is invoked.\n\n3. 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 5 below.\n\n4. The suite is executed.\n\n5. 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\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 *Expression lists*. Note that the lambda form is\nmerely a shorthand for a simplified function definition; a function\ndefined in a "``def``" statement can be passed around or assigned to\nanother name just like a function defined by a lambda form. The\n"``def``" form is actually more powerful since it allows the execution\nof multiple statements 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 ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\nClasses can also be decorated; as with 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\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by instances. Instance variables can\nbe set in a method with ``self.name = value``. Both class and\ninstance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. Descriptors can be used to create\ninstance variables with different implementation details.\n\nSee also:\n\n **PEP 3129** - Class Decorators\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\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. For this reason, ``__del__()`` methods should do\n the absolute minimum needed to maintain external invariants.\n Starting with version 1.5, Python guarantees that globals whose\n name begins with a single underscore are deleted from their\n module before other globals are deleted; if no other references\n to such globals exist, this may help in assuring that imported\n modules are still available at the time when the ``__del__()``\n 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\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 overrrides ``__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 (see\n below) and ``True`` is returned when the length is not zero. If a\n class defines neither ``__len__()`` nor ``__bool__()``, all its\n instances 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``\n(undocumented) and ``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 python -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\nTypical 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[, locals]])\n\n Execute the *statement* (given as a string) under debugger control.\n The debugger prompt appears before any code is executed; you can\n set breakpoints and type ``continue``, or you can step through the\n statement using ``step`` or ``next`` (all these commands are\n explained below). The optional *globals* and *locals* arguments\n specify the environment in which the code is executed; by default\n the dictionary of the module ``__main__`` is used. (See the\n explanation of the built-in ``exec()`` or ``eval()`` functions.)\n\npdb.runeval(expression[, globals[, locals]])\n\n Evaluate the *expression* (given as a string) under debugger\n control. When ``runeval()`` returns, it returns the value of the\n expression. Otherwise this function is similar to ``run()``.\n\npdb.runcall(function[, argument, ...])\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])\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', - '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\nIt is illegal to delete a name from the local namespace if it occurs\nas a free variable in a nested block.\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', - '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', - 'else': '\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', - 'exceptions': '\nExceptions\n**********\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nWarning: Exception messages are not part of the Python API. Their contents\n may change from one version of Python to the next without warning\n and should not be relied on by code which will run under multiple\n versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', - 'execmodel': '\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The string argument passed\nto the built-in functions ``eval()`` and ``exec()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block,\nunless declared as ``nonlocal``. If a name is bound at the module\nlevel, it is a global variable. (The variables of the module code\nblock are local and global.) If a variable is used in a code block\nbut not defined there, it is a *free variable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, or in\nthe second position of an ``except`` clause header. The ``import``\nstatement of the form "``from ...import *``" binds all names defined\nin the imported module, except those beginning with an underscore.\nThis form may only be used at the module level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the ``global`` statement occurs within a block, all uses of the\nname specified in the statement refer to the binding of that name in\nthe top-level namespace. Names are resolved in the top-level\nnamespace by searching the global namespace, i.e. the namespace of the\nmodule containing the code block, and the builtin namespace, the\nnamespace of the module ``builtins``. The global namespace is\nsearched first. If the name is not found there, the builtin namespace\nis searched. The global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``builtins``; when in any other module, ``__builtins__`` is an alias\nfor the dictionary of the ``builtins`` module itself.\n``__builtins__`` can be set to a user-created dictionary to create a\nweak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``builtins`` module and\n modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\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\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nWarning: Exception messages are not part of the Python API. Their contents\n may change from one version of Python to the next without warning\n and should not be relied on by code which will run under multiple\n versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', - '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., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nWarning: 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 ::= (identifier | integer) ("." attribute_name | "[" element_index "]")*\n attribute_name ::= identifier\n element_index ::= integer\n conversion ::= "r" | "s" | "a"\n format_spec ::= \n\nIn less formal terms, the replacement field starts with a\n*field_name*, which can either be a number (for a positional\nargument), or an identifier (for keyword arguments). Following this\nis an optional *conversion* field, which is preceded by an exclamation\npoint ``\'!\'``, and a *format_spec*, which is preceded by a colon\n``\':\'``.\n\nThe *field_name* itself begins with either a number or a keyword. If\nit\'s a number, it refers to a positional argument, and if it\'s a\nkeyword it refers to a named keyword argument. This can be followed\nby any number of index or attribute expressions. An expression of the\nform ``\'.name\'`` selects the named attribute using ``getattr()``,\nwhile an expression of the form ``\'[index]\'`` does an index lookup\nusing ``__getitem__()``.\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\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\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 it\'s\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\nFor example, suppose you wanted to have a replacement field whose\nfield width is determined by another variable:\n\n "A man with two {0:{1}}".format("noses", 10)\n\nThis would first evaluate the inner replacement field, making the\nformat string effectively:\n\n "A man with two {0:10}"\n\nThen the outer replacement field would be evaluated, producing:\n\n "noses "\n\nWhich is substituted into the string, yielding:\n\n "A man with two noses "\n\n(The extra space is because we specified a field width of 10, and\nbecause left alignment is the default for strings.)\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\nbuiltin ``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.\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" | "x" | "X" | "%"\n\nThe *fill* character can be any character other than \'}\' (which\nsignifies the end of the field). The presence of a fill character is\nsignaled by the *next* character, which must be one of the alignment\noptions. If the second character of *format_spec* is not a valid\nalignment option, then it is assumed that both the fill character and\nthe alignment option are absent.\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\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 ignored for integer values.\n\nFinally, the *type* determines how the data should be presented.\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\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\'``. |\n +-----------+------------------------------------------------------------+\n | ``\'g\'`` | General format. This prints the number as a fixed-point |\n | | number, unless the number is too large, in which case it |\n | | switches to ``\'e\'`` exponent notation. Infinity and NaN |\n | | values are formatted as ``inf``, ``-inf`` and ``nan``, |\n | | respectively. |\n +-----------+------------------------------------------------------------+\n | ``\'G\'`` | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n | | if the number gets to 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 | The same as ``\'g\'``. |\n +-----------+------------------------------------------------------------+\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 *Expression lists*. Note that the lambda form is\nmerely a shorthand for a simplified function definition; a function\ndefined in a "``def``" statement can be passed around or assigned to\nanother name just like a function defined by a lambda form. The\n"``def``" form is actually more powerful since it allows the execution\nof multiple statements 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(The current implementation does not enforce the latter two\nrestrictions, but programs should not abuse this freedom, as future\nimplementations may enforce them or silently change the meaning of the\nprogram.)\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 builtin ``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);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\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);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\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\nfirst form (without ``from``) repeats these steps for each identifier\nin the list. The form with ``from`` performs step (1) once, and then\nperforms step (2) repeatedly.\n\nIn this context, to "initialize" a built-in or extension module means\nto call an initialization function that the module must provide for\nthe purpose (in the reference implementation, the function\'s name is\nobtained by prepending string "init" to the module\'s name); to\n"initialize" a Python-coded module means to execute the module\'s body.\n\nThe system maintains a table of modules that have been or are being\ninitialized, indexed by module name. This table is accessible as\n``sys.modules``. When a module name is found in this table, step (1)\nis finished. If not, a search for a module definition is started.\nWhen a module is found, it is loaded. Details of the module searching\nand loading process are implementation and platform specific. It\ngenerally involves searching for a "built-in" module with the given\nname and then searching a list of locations given as ``sys.path``.\n\nIf a built-in module is found, its built-in initialization code is\nexecuted and step (1) is finished. If no matching file is found,\n``ImportError`` is raised. If a file is found, it is parsed, yielding\nan executable code block. If a syntax error occurs, ``SyntaxError``\nis raised. Otherwise, an empty module of the given name is created\nand inserted in the module table, and then the code block is executed\nin the context of this module. Exceptions during this execution\nterminate step (1).\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. If the\nwild card form of import --- ``import *`` --- is used in a function\nand the function contains or is a nested block with free variables,\nthe compiler will raise a ``SyntaxError``.\n\n**Hierarchical module names:** when the module names contains one or\nmore dots, the module search path is carried out differently. The\nsequence of identifiers up to the last dot is used to find a\n"package"; the final identifier is then searched inside the package.\nA package is generally a subdirectory of a directory on ``sys.path``\nthat has a file ``__init__.py``.\n\nThe built-in function ``__import__()`` is provided to support\napplications that determine which modules need to be loaded\ndynamically; refer to *Built-in Functions* for additional information.\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 builtin 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', - '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-builtin\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, ``cmp([1,2,x], [1,2,y])`` returns\n the same as ``cmp(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 their sorted\n ``(key, value)`` lists compare equal. [4] Outcomes other than\n equality are resolved consistently, but are not otherwise defined.\n [5]\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 builtin 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\nnumberic 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`` equivalent to ``any(x is e or x == e for val e\nin y)``.\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__()`` and do\ndefine ``__getitem__()``, ``x in y`` is true if and only if there is a\nnon-negative 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. [6]\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': '\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', - 'lists': '\nList displays\n*************\n\nA list display is a possibly empty series of expressions enclosed in\nsquare brackets:\n\n list_display ::= "[" [expression_list | comprehension] "]"\n\nA list display yields a new list object, the contents being specified\nby either a list of expressions or a comprehension. When a comma-\nseparated list of expressions is supplied, its elements are evaluated\nfrom left to right and placed into the list object in that order.\nWhen a comprehension is supplied, the list is constructed from the\nelements resulting from the comprehension.\n', - 'naming': '\nNaming and binding\n******************\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The string argument passed\nto the built-in functions ``eval()`` and ``exec()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block,\nunless declared as ``nonlocal``. If a name is bound at the module\nlevel, it is a global variable. (The variables of the module code\nblock are local and global.) If a variable is used in a code block\nbut not defined there, it is a *free variable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, or in\nthe second position of an ``except`` clause header. The ``import``\nstatement of the form "``from ...import *``" binds all names defined\nin the imported module, except those beginning with an underscore.\nThis form may only be used at the module level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the ``global`` statement occurs within a block, all uses of the\nname specified in the statement refer to the binding of that name in\nthe top-level namespace. Names are resolved in the top-level\nnamespace by searching the global namespace, i.e. the namespace of the\nmodule containing the code block, and the builtin namespace, the\nnamespace of the module ``builtins``. The global namespace is\nsearched first. If the name is not found there, the builtin namespace\nis searched. The global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``builtins``; when in any other module, ``__builtins__`` is an alias\nfor the dictionary of the ``builtins`` module itself.\n``__builtins__`` can be set to a user-created dictionary to create a\nweak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``builtins`` module and\n modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\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', - '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. [3] 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 operations (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\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 operation falls back to the normal methods. For instance, to\n evaluate the expression ``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. (Implementation note: the current implementation uses a\nreference-counting scheme with (optional) delayed detection of\ncyclically linked garbage, which collects most objects as soon as they\nbecome unreachable, but is not guaranteed to collect garbage\ncontaining circular references. See the documentation of the ``gc``\nmodule for information on controlling the collection of cyclic\ngarbage.)\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| ``or`` | Boolean OR |\n+------------------------------------------------+---------------------------------------+\n| ``and`` | Boolean AND |\n+------------------------------------------------+---------------------------------------+\n| ``not`` *x* | Boolean NOT |\n+------------------------------------------------+---------------------------------------+\n| ``in``, ``not`` ``in`` | Membership tests |\n+------------------------------------------------+---------------------------------------+\n| ``is``, ``is not`` | Identity tests |\n+------------------------------------------------+---------------------------------------+\n| ``<``, ``<=``, ``>``, ``>=``, ``!=``, ``==`` | Comparisons |\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+------------------------------------------------+---------------------------------------+\n| ``+x``, ``-x`` | Positive, negative |\n+------------------------------------------------+---------------------------------------+\n| ``~x`` | Bitwise not |\n+------------------------------------------------+---------------------------------------+\n| ``**`` | Exponentiation |\n+------------------------------------------------+---------------------------------------+\n| ``x[index]`` | Subscription |\n+------------------------------------------------+---------------------------------------+\n| ``x[index:index]`` | Slicing |\n+------------------------------------------------+---------------------------------------+\n| ``x(arguments...)`` | Call |\n+------------------------------------------------+---------------------------------------+\n| ``x.attribute`` | Attribute reference |\n+------------------------------------------------+---------------------------------------+\n| ``(expressions...)`` | Binding, tuple display, generator |\n| | expressions |\n+------------------------------------------------+---------------------------------------+\n| ``[expressions...]`` | List display |\n+------------------------------------------------+---------------------------------------+\n| ``{expressions...}`` | Dictionary or set 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 CAPTITAL LETTER C WITH CEDILLA). To compare strings in a human\n recognizable way, compare using ``unicodedata.normalize()``.\n\n[4] The implementation computes this efficiently, without constructing\n lists or sorting.\n\n[5] Earlier versions of Python used lexicographic comparison of the\n sorted (key, value) lists, but this was very expensive for the\n common case of comparing for equality. An even earlier version of\n Python compared dictionaries by identity only, but this caused\n surprises because people expected to be able to test a dictionary\n for emptiness by comparing it to ``{}``.\n\n[6] 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', - '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 RuntimeError("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', - 'return': '\nThe ``return`` statement\n************************\n\n return_stmt ::= "return" [expression_list]\n\n``return`` may only occur syntactically nested in a function\ndefinition, not within a nested class definition.\n\nIf an expression list is present, it is evaluated, else ``None`` is\nsubstituted.\n\n``return`` leaves the current function call with the expression list\n(or ``None``) as return value.\n\nWhen ``return`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nleaving the function.\n\nIn a generator function, the ``return`` statement is not allowed to\ninclude an **expression_list**. In that context, a bare ``return``\nindicates that the generator is done and will cause ``StopIteration``\nto be raised.\n', - 'sequence-types': "\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()`` builtin 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()`` builtin will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects should\n normally only provide ``__reversed__()`` if they do not support the\n sequence protocol and an efficient implementation of reverse\n iteration is possible.\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", - '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', - '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. If there are no base\n classes, this will be an empty tuple.\n\nclass.__name__\n\n The name of the class or type.\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\n[5] These numbers are fairly arbitrary. They are intended to avoid\n printing endless strings of meaningless digits without hampering\n correct use and without having to know the exact precision of\n floating point values on a particular machine.\n\n[6] The advantage of leaving the newline on is that returning an empty\n string is then an unambiguous EOF indication. It is also possible\n (in cases where it might matter, for example, if you want to make\n an exact copy of a file while scanning its lines) to tell whether\n the last line of a file ended in a newline or not (yes this\n happens!).\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. For this reason, ``__del__()`` methods should do\n the absolute minimum needed to maintain external invariants.\n Starting with version 1.5, Python guarantees that globals whose\n name begins with a single underscore are deleted from their\n module before other globals are deleted; if no other references\n to such globals exist, this may help in assuring that imported\n modules are still available at the time when the ``__del__()``\n 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\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 overrrides ``__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 (see\n below) and ``True`` is returned when the length is not zero. If a\n class defines neither ``__len__()`` nor ``__bool__()``, all its\n instances 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 builtin 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. Normally, data\ndescriptors define both ``__get__()`` and ``__set__()``, while non-\ndata descriptors have just the ``__get__()`` method. Data descriptors\nalways override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances. [2]\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* 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* 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__*.\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 based with the bases, it is\n 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\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()`` builtin 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()`` builtin will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects should\n normally only provide ``__reversed__()`` if they do not support the\n sequence protocol and an efficient implementation of reverse\n iteration is possible.\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\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. [3] 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 operations (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\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 operation falls back to the normal methods. For instance, to\n evaluate the expression ``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 may also bypass the\n``__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] A descriptor can define any combination of ``__get__()``,\n ``__set__()`` and ``__delete__()``. If it does not define\n ``__get__()``, then accessing the attribute even on an instance\n will return the descriptor object itself. If the descriptor\n defines ``__set__()`` and/or ``__delete__()``, it is a data\n descriptor; if it defines neither, it is a non-data descriptor.\n\n[3] 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. Note that none of\nthese methods take keyword arguments.\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 only its first character\n capitalized.\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 occurrences of substring *sub* in the range\n [*start*, *end*]. Optional arguments *start* and *end* are\n interpreted as in slice notation.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\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 range [*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(format_string, *args, **kwargs)\n\n Perform a string formatting operation. The *format_string*\n argument can contain literal text or replacement fields delimited\n by braces ``{}``. Each replacement field contains either the\n numeric index of a positional argument, or the name of a keyword\n argument. Returns a copy of *format_string* where each replacement\n field is replaced with the string value of the corresponding\n 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.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(seq)\n\n Return a string which is the concatenation of the strings in the\n sequence *seq*. A ``TypeError`` will be raised if there are any\n 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\nstr.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]. Optional\n arguments *start* and *end* are interpreted as in slice notation.\n 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: words start with\n uppercase characters, all remaining cased characters are lowercase.\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\n ordinals(integers) to Unicode ordinals, strings or ``None``.\n Unmapped characters are left untouched. Characters mapped to\n ``None`` are deleted.\n\n A *map* for ``translate()`` is usually best created by\n ``str.maketrans()``.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\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', - '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"\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\nString literals may optionally be prefixed with a letter ``\'r\'`` or\n``\'R\'``; such strings are called *raw strings* and treat backslashes\nas literal characters. As a result, ``\'\\U\'`` and ``\'\\u\'`` escapes in\nraw strings are not treated specially.\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\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, at most two hex digits are accepted.\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. Unlike in Standard C, exactly\n two hex digits are 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). Individual code units which form parts of a surrogate\n pair can be encoded using this escape sequence.\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. If this value is negative, the length of the sequence is\nadded to it (so that, e.g., ``x[-1]`` selects the last item of ``x``.)\nThe resulting value must be a nonnegative integer less than the number\nof items in the sequence, and the subscription selects the item whose\nindex is that value (counting from zero).\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", - 'try': '\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 N = None\n del N\n\nThat means that you have to assign the exception to a different name\nif you want to be able to refer to it after the except clause. The\nreason for this is that with the traceback attached to them,\nexceptions will form a reference cycle with the stack frame, keeping\nall locals in that frame alive until the next garbage collection\noccurs.\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', - 'types': '\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.), although such additions\nwill often be provided via the standard library instead.\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name ``None``.\n It is used to signify the absence of a value in many situations,\n e.g., it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``NotImplemented``. Numeric methods and rich comparison methods may\n return this value if they do not implement the operation for the\n operands provided. (The interpreter will then try the reflected\n operation, or some other fallback, depending on the operator.) Its\n truth value is true.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the literal ``...`` or the\n built-in name ``Ellipsis``. Its truth value is true.\n\n``numbers.Number``\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n ``numbers.Integral``\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are two types of integers:\n\n Integers (``int``)\n\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans (``bool``)\n These represent the truth values False and True. The two\n objects representing the values False and True are the only\n Boolean objects. The Boolean type is a subtype of the integer\n type, and Boolean values behave like the values 0 and 1,\n respectively, in almost all contexts, the exception being\n that when converted to a string, the strings ``"False"`` or\n ``"True"`` are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers.\n\n ``numbers.Real`` (``float``)\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these is\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n ``numbers.Complex`` (``complex``)\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number ``z`` can be retrieved through the read-only\n attributes ``z.real`` and ``z.imag``.\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function ``len()`` returns the number of\n items of a sequence. When the length of a sequence is *n*, the\n index set contains the numbers 0, 1, ..., *n*-1. Item *i* of\n sequence *a* is selected by ``a[i]``.\n\n Sequences also support slicing: ``a[i:j]`` selects all items with\n index *k* such that *i* ``<=`` *k* ``<`` *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: ``a[i:j:k]`` selects all items of *a* with index *x*\n where ``x = i + n*k``, *n* ``>=`` ``0`` and *i* ``<=`` *x* ``<``\n *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n The items of a string object are Unicode code units. A\n Unicode code unit is represented by a string object of one\n item and can hold either a 16-bit or 32-bit value\n representing a Unicode ordinal (the maximum value for the\n ordinal is given in ``sys.maxunicode``, and depends on how\n Python is configured at compile time). Surrogate pairs may\n be present in the Unicode object, and will be reported as two\n separate items. The built-in functions ``chr()`` and\n ``ord()`` convert between code units and nonnegative integers\n representing the Unicode ordinals as defined in the Unicode\n Standard 3.0. Conversion from and to other encodings are\n possible through the string method ``encode()``.\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Bytes\n A bytes object is an immutable array. The items are 8-bit\n bytes, represented by integers in the range 0 <= x < 256.\n Bytes literals (like ``b\'abc\'`` and the built-in function\n ``bytes()`` can be used to construct bytes objects. Also,\n bytes objects can be decoded to strings via the ``decode()``\n method.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and ``del`` (delete) statements.\n\n There is currently a single intrinsic mutable sequence type:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n Byte Arrays\n A bytearray object is a mutable array. They are created by\n the built-in ``bytearray()`` constructor. Aside from being\n mutable (and hence unhashable), byte arrays otherwise provide\n the same interface and functionality as immutable bytes\n objects.\n\n The extension module ``array`` provides an additional example of\n a mutable sequence type, as does the ``collections`` module.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function ``len()``\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n ``set()`` constructor and can be modified afterwards by several\n methods, such as ``add()``.\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in ``frozenset()`` constructor. As a frozenset is\n immutable and *hashable*, it can be used again as an element of\n another set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation ``a[k]`` selects the item indexed by\n ``k`` from the mapping ``a``; this can be used in expressions and\n as the target of assignments or ``del`` statements. The built-in\n function ``len()`` returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``) then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the ``{...}``\n notation (see section *Dictionary displays*).\n\n The extension modules ``dbm.ndbm`` and ``dbm.gnu`` provide\n additional examples of mapping types, as does the\n ``collections`` module.\n\nCallable types\n These are the types to which the function call operation (see\n section *Calls*) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section *Function definitions*). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +---------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +===========================+=================================+=============+\n | ``__doc__`` | The function\'s documentation | Writable |\n | | string, or ``None`` if | |\n | | unavailable | |\n +---------------------------+---------------------------------+-------------+\n | ``__name__`` | The function\'s name | Writable |\n +---------------------------+---------------------------------+-------------+\n | ``__module__`` | The name of the module the | Writable |\n | | function was defined in, or | |\n | | ``None`` if unavailable. | |\n +---------------------------+---------------------------------+-------------+\n | ``__defaults__`` | A tuple containing default | Writable |\n | | argument values for those | |\n | | arguments that have defaults, | |\n | | or ``None`` if no arguments | |\n | | have a default value | |\n +---------------------------+---------------------------------+-------------+\n | ``__code__`` | The code object representing | Writable |\n | | the compiled function body. | |\n +---------------------------+---------------------------------+-------------+\n | ``__globals__`` | A reference to the dictionary | Read-only |\n | | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +---------------------------+---------------------------------+-------------+\n | ``__dict__`` | The namespace supporting | Writable |\n | | arbitrary function attributes. | |\n +---------------------------+---------------------------------+-------------+\n | ``__closure__`` | ``None`` or a tuple of cells | Read-only |\n | | that contain bindings for the | |\n | | function\'s free variables. | |\n +---------------------------+---------------------------------+-------------+\n | ``__annotations__`` | A dict containing annotations | Writable |\n | | of parameters. The keys of the | |\n | | dict are the parameter names, | |\n | | or ``\'return\'`` for the return | |\n | | annotation, if provided. | |\n +---------------------------+---------------------------------+-------------+\n | ``__kwdefaults__`` | A dict containing defaults for | Writable |\n | | keyword-only parameters. | |\n +---------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n Instance methods\n An instance method object combines a class, a class instance and\n any callable object (normally a user-defined function).\n\n Special read-only attributes: ``__self__`` is the class instance\n object, ``__func__`` is the function object; ``__doc__`` is the\n method\'s documentation (same as ``__func__.__doc__``);\n ``__name__`` is the method name (same as ``__func__.__name__``);\n ``__module__`` is the name of the module the method was defined\n in, or ``None`` if unavailable.\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object or a class\n method object.\n\n When an instance method object is created by retrieving a user-\n defined function object from a class via one of its instances,\n its ``__self__`` attribute is the instance, and the method\n object is said to be bound. The new method\'s ``__func__``\n attribute is the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the ``__func__``\n attribute of the new instance is not the original method object\n but its ``__func__`` attribute.\n\n When an instance method object is created by retrieving a class\n method object from a class or instance, its ``__self__``\n attribute is the class itself, and its ``__func__`` attribute is\n the function object underlying the class method.\n\n When an instance method object is called, the underlying\n function (``__func__``) is called, inserting the class instance\n (``__self__``) in front of the argument list. For instance,\n when ``C`` is a class which contains a definition for a function\n ``f()``, and ``x`` is an instance of ``C``, calling ``x.f(1)``\n is equivalent to calling ``C.f(x, 1)``.\n\n When an instance method object is derived from a class method\n object, the "class instance" stored in ``__self__`` will\n actually be the class itself, so that calling either ``x.f(1)``\n or ``C.f(1)`` is equivalent to calling ``f(C,1)`` where ``f`` is\n the underlying function.\n\n Note that the transformation from function object to instance\n method object happens each time the attribute is retrieved from\n the instance. In some cases, a fruitful optimization is to\n assign the attribute to a local variable and call that local\n variable. Also notice that this transformation only happens for\n user-defined functions; other callable objects (and all non-\n callable objects) are retrieved without transformation. It is\n also important to note that user-defined functions which are\n attributes of a class instance are not converted to bound\n methods; this *only* happens when the function is an attribute\n of the class.\n\n Generator functions\n A function or method which uses the ``yield`` statement (see\n section *The yield statement*) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s ``__next__()`` method will cause the function to\n execute until it provides a value using the ``yield`` statement.\n When the function executes a ``return`` statement or falls off\n the end, a ``StopIteration`` exception is raised and the\n iterator will have reached the end of the set of values to be\n returned.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are ``len()`` and ``math.sin()``\n (``math`` is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: ``__doc__`` is the function\'s documentation\n string, or ``None`` if unavailable; ``__name__`` is the\n function\'s name; ``__self__`` is set to ``None`` (but see the\n next item); ``__module__`` is the name of the module the\n function was defined in or ``None`` if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n ``alist.append()``, assuming *alist* is a list object. In this\n case, the special read-only attribute ``__self__`` is set to the\n object denoted by *list*.\n\n Classes\n Classes are callable. These objects normally act as factories\n for new instances of themselves, but variations are possible for\n class types that override ``__new__()``. The arguments of the\n call are passed to ``__new__()`` and, in the typical case, to\n ``__init__()`` to initialize the new instance.\n\n Class Instances\n Instances of arbitrary classes can be made callable by defining\n a ``__call__()`` method in their class.\n\nModules\n Modules are imported by the ``import`` statement (see section *The\n import statement*). A module object has a namespace implemented by\n a dictionary object (this is the dictionary referenced by the\n __globals__ attribute of functions defined in the module).\n Attribute references are translated to lookups in this dictionary,\n e.g., ``m.x`` is equivalent to ``m.__dict__["x"]``. A module object\n does not contain the code object used to initialize the module\n (since it isn\'t needed once the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``.\n\n Special read-only attribute: ``__dict__`` is the module\'s namespace\n as a dictionary object.\n\n Predefined (writable) attributes: ``__name__`` is the module\'s\n name; ``__doc__`` is the module\'s documentation string, or ``None``\n if unavailable; ``__file__`` is the pathname of the file from which\n the module was loaded, if it was loaded from a file. The\n ``__file__`` attribute is not present for C modules that are\n statically linked into the interpreter; for extension modules\n loaded dynamically from a shared library, it is the pathname of the\n shared library file.\n\nCustom classes\n Custon class types are typically created by class definitions (see\n section *Class definitions*). A class has a namespace implemented\n by a dictionary object. Class attribute references are translated\n to lookups in this dictionary, e.g., ``C.x`` is translated to\n ``C.__dict__["x"]`` (although there are a number of hooks which\n allow for other means of locating attributes). When the attribute\n name is not found there, the attribute search continues in the base\n classes. This search of the base classes uses the C3 method\n resolution order which behaves correctly even in the presence of\n \'diamond\' inheritance structures where there are multiple\n inheritance paths leading back to a common ancestor. Additional\n details on the C3 MRO used by Python can be found in the\n documentation accompanying the 2.3 release at\n http://www.python.org/download/releases/2.3/mro/.\n\n When a class attribute reference (for class ``C``, say) would yield\n a class method object, it is transformed into an instance method\n object whose ``__self__`` attributes is ``C``. When it would yield\n a static method object, it is transformed into the object wrapped\n by the static method object. See section *Implementing Descriptors*\n for another way in which attributes retrieved from a class may\n differ from those actually contained in its ``__dict__``.\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: ``__name__`` is the class name; ``__module__``\n is the module name in which the class was defined; ``__dict__`` is\n the dictionary containing the class\'s namespace; ``__bases__`` is a\n tuple (possibly empty or a singleton) containing the base classes,\n in the order of their occurrence in the base class list;\n ``__doc__`` is the class\'s documentation string, or None if\n undefined.\n\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object, it is transformed into an instance method object\n whose ``__self__`` attribute is the instance. Static method and\n class method objects are also transformed; see above under\n "Classes". See section *Implementing Descriptors* for another way\n in which attributes of a class retrieved via its instances may\n differ from the objects actually stored in the class\'s\n ``__dict__``. If no class attribute is found, and the object\'s\n class has a ``__getattr__()`` method, that is called to satisfy the\n lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n ``__setattr__()`` or ``__delattr__()`` method, this is called\n instead of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n *Special method names*.\n\n Special attributes: ``__dict__`` is the attribute dictionary;\n ``__class__`` is the instance\'s class.\n\nFiles\n A file object represents an open file. File objects are created by\n the ``open()`` built-in function, and also by ``os.popen()``,\n ``os.fdopen()``, and the ``makefile()`` method of socket objects\n (and perhaps by other functions or methods provided by extension\n modules). The objects ``sys.stdin``, ``sys.stdout`` and\n ``sys.stderr`` are initialized to file objects corresponding to the\n interpreter\'s standard input, output and error streams. See *File\n Objects* for complete documentation of file objects.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: ``co_name`` gives the function\n name; ``co_argcount`` is the number of positional arguments\n (including arguments with default values); ``co_nlocals`` is the\n number of local variables used by the function (including\n arguments); ``co_varnames`` is a tuple containing the names of\n the local variables (starting with the argument names);\n ``co_cellvars`` is a tuple containing the names of local\n variables that are referenced by nested functions;\n ``co_freevars`` is a tuple containing the names of free\n variables; ``co_code`` is a string representing the sequence of\n bytecode instructions; ``co_consts`` is a tuple containing the\n literals used by the bytecode; ``co_names`` is a tuple\n containing the names used by the bytecode; ``co_filename`` is\n the filename from which the code was compiled;\n ``co_firstlineno`` is the first line number of the function;\n ``co_lnotab`` is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); ``co_stacksize`` is the required stack size\n (including local variables); ``co_flags`` is an integer encoding\n a number of flags for the interpreter.\n\n The following flag bits are defined for ``co_flags``: bit\n ``0x04`` is set if the function uses the ``*arguments`` syntax\n to accept an arbitrary number of positional arguments; bit\n ``0x08`` is set if the function uses the ``**keywords`` syntax\n to accept arbitrary keyword arguments; bit ``0x20`` is set if\n the function is a generator.\n\n Future feature declarations (``from __future__ import\n division``) also use bits in ``co_flags`` to indicate whether a\n code object was compiled with a particular feature enabled: bit\n ``0x2000`` is set if the function was compiled with future\n division enabled; bits ``0x10`` and ``0x1000`` were used in\n earlier versions of Python.\n\n Other bits in ``co_flags`` are reserved for internal use.\n\n If a code object represents a function, the first item in\n ``co_consts`` is the documentation string of the function, or\n ``None`` if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: ``f_back`` is to the previous\n stack frame (towards the caller), or ``None`` if this is the\n bottom stack frame; ``f_code`` is the code object being executed\n in this frame; ``f_locals`` is the dictionary used to look up\n local variables; ``f_globals`` is used for global variables;\n ``f_builtins`` is used for built-in (intrinsic) names;\n ``f_lasti`` gives the precise instruction (this is an index into\n the bytecode string of the code object).\n\n Special writable attributes: ``f_trace``, if not ``None``, is a\n function called at the start of each source code line (this is\n used by the debugger); ``f_lineno`` is the current line number\n of the frame --- writing to this from within a trace function\n jumps to the given line (only for the bottom-most frame). A\n debugger can implement a Jump command (aka Set Next Statement)\n by writing to f_lineno.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n *The try statement*.) It is accessible as the third item of the\n tuple returned by ``sys.exc_info()``. When the program contains\n no suitable handler, the stack trace is written (nicely\n formatted) to the standard error stream; if the interpreter is\n interactive, it is also made available to the user as\n ``sys.last_traceback``.\n\n Special read-only attributes: ``tb_next`` is the next level in\n the stack trace (towards the frame where the exception\n occurred), or ``None`` if there is no next level; ``tb_frame``\n points to the execution frame of the current level;\n ``tb_lineno`` gives the line number where the exception\n occurred; ``tb_lasti`` indicates the precise instruction. The\n line number and last instruction in the traceback may differ\n from the line number of its frame object if the exception\n occurred in a ``try`` statement with no matching except clause\n or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices for ``__getitem__()``\n methods. They are also created by the built-in ``slice()``\n function.\n\n Special read-only attributes: ``start`` is the lower bound;\n ``stop`` is the upper bound; ``step`` is the step value; each is\n ``None`` if omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the slice that the slice object\n would describe if applied to a sequence of *length* items.\n It returns a tuple of three integers; respectively these are\n the *start* and *stop* indices and the *step* or stride\n length of the slice. Missing or out-of-bounds indices are\n handled in a manner consistent with regular slices.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n ``staticmethod()`` constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in ``classmethod()`` constructor.\n', - 'typesfunctions': '\nFunctions\n*********\n\nFunction objects are created by function definitions. The only\noperation on a function object is to call it: ``func(argument-list)``.\n\nThere are really two flavors of function objects: built-in functions\nand user-defined functions. Both support the same operation (to call\nthe function), but the implementation is different, hence the\ndifferent object types.\n\nSee *Function definitions* for more information.\n', - '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 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": 2, "two": 3}``:\n\n * ``dict(one=2, two=3)``\n\n * ``dict({\'one\': 2, \'two\': 3})``\n\n * ``dict(zip((\'one\', \'two\'), (2, 3)))``\n\n * ``dict([[\'two\', 3], [\'one\', 2]])``\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 clear()\n\n Remove all items from the dictionary.\n\n copy()\n\n Return a shallow copy of the dictionary.\n\n 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 a tuple or other iterable of\n length two). If keyword arguments are specified, the\n dictionary is then is updated with those key/value pairs:\n ``d.update(red=1, 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\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 and\nhashable, then the items view is also set-like. (Values views are not\ntreated as set-like since the entries are generally not unique.) Then\nthese set operations are available ("other" refers either to another\nview or a set):\n\ndictview & other\n\n Return the intersection of the dictview and the other object as a\n new set.\n\ndictview | other\n\n Return the union of the dictview and the other object as a new set.\n\ndictview - other\n\n Return the difference between the dictview and the other object\n (all elements in *dictview* that aren\'t in *other*) as a new set.\n\ndictview ^ other\n\n Return the symmetric difference (all elements either in *dictview*\n or *other*, but not in both) of the dictview and the other object\n as a new set.\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', - '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 five sequence types: strings, byte sequences, byte arrays,\nlists, tuples, and range objects. (For other containers see the\nbuilt-in ``dict``, ``list``, ``set``, and ``tuple`` classes, and the\n``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\nWarning: While string objects are sequences of characters (represented by\n strings of length 1), bytes and bytearray objects are sequences of\n *integers* (between 0 and 255), representing the ASCII value of\n single bytes. That means that for a bytes or bytearray object *b*,\n ``b[0]`` will be an integer, while ``b[0:1]`` will be a bytes or\n bytearray object of length 1. The representation of bytes objects\n uses the literal format (``b\'...\'``) since it is generally more\n useful than e.g. ``bytes([50, 19, 100])``. You can always convert a\n bytes object into a list of integers using ``list(b)``.Also, while\n in previous Python versions, byte strings and Unicode strings could\n be exchanged for each other rather freely (barring encoding issues),\n strings and bytes are now completely separate concepts. There\'s no\n implicit en-/decoding if you pass and object of the wrong type. A\n string always compares unequal to a bytes or bytearray 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. If *s* and *t* are both strings, some Python implementations such\n as CPython can usually perform an in-place optimization for\n assignments of the form ``s=s+t`` or ``s+=t``. When applicable,\n this optimization makes quadratic run-time much less likely. This\n optimization is both version and implementation dependent. For\n performance sensitive code, it is preferable to use the\n ``str.join()`` method which assures consistent linear concatenation\n performance across versions and implementations.\n\n\nString Methods\n==============\n\nString objects support the methods listed below. Note that none of\nthese methods take keyword arguments.\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 only its first character\n capitalized.\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 occurrences of substring *sub* in the range\n [*start*, *end*]. Optional arguments *start* and *end* are\n interpreted as in slice notation.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\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 range [*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(format_string, *args, **kwargs)\n\n Perform a string formatting operation. The *format_string*\n argument can contain literal text or replacement fields delimited\n by braces ``{}``. Each replacement field contains either the\n numeric index of a positional argument, or the name of a keyword\n argument. Returns a copy of *format_string* where each replacement\n field is replaced with the string value of the corresponding\n 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.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(seq)\n\n Return a string which is the concatenation of the strings in the\n sequence *seq*. A ``TypeError`` will be raised if there are any\n 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\nstr.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]. Optional\n arguments *start* and *end* are interpreted as in slice notation.\n 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: words start with\n uppercase characters, all remaining cased characters are lowercase.\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\n ordinals(integers) to Unicode ordinals, strings or ``None``.\n Unmapped characters are left untouched. Characters mapped to\n ``None`` are deleted.\n\n A *map* for ``translate()`` is usually best created by\n ``str.maketrans()``.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\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 %(#)03d quote types.\' % \\\n... {\'language\': "Python", "#": 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\'`` | Obselete 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\nFor safety reasons, floating point precisions are clipped to 50;\n``%f`` conversions for numbers whose absolute value is over 1e25 are\nreplaced by ``%g`` conversions. [5] All other errors raise\nexceptions.\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 very little behavior: they only support indexing,\niteration, and the ``len()`` function.\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``.\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 While a list is being sorted, the effect of attempting to mutate,\n or even inspect, the list is undefined. The C implementation makes\n the list appear empty for the duration, and raises ``ValueError``\n if it can detect 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\nThe bytes and bytearray types have an additional class method:\n\nbytes.fromhex(string)\nbytearray.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', - '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``.\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 While a list is being sorted, the effect of attempting to mutate,\n or even inspect, the list is undefined. The C implementation makes\n the list appear empty for the duration, and raises ``ValueError``\n if it can detect that the list has been mutated during a sort.\n\n8. ``sort()`` is not supported by ``bytearray`` objects.\n', - 'unary': '\nUnary arithmetic 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', - 'with': '\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" expression ["as" target] ":" suite\n\nThe execution of the ``with`` statement proceeds as follows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__enter__()`` method is invoked.\n\n3. 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 5 below.\n\n4. The suite is executed.\n\n5. 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\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n', - 'yield': '\nThe ``yield`` statement\n***********************\n\n yield_stmt ::= yield_expression\n\nThe ``yield`` statement is only used when defining a generator\nfunction, and is only used in the body of the generator function.\nUsing a ``yield`` statement in a function definition is sufficient to\ncause that definition to create a generator function instead of a\nnormal function. When a generator function is called, it returns an\niterator known as a generator iterator, or more commonly, a generator.\nThe body of the generator function is executed by calling the\ngenerator\'s ``next()`` method repeatedly until it raises an exception.\n\nWhen a ``yield`` statement is executed, the state of the generator is\nfrozen and the value of **expression_list** is returned to\n``next()``\'s caller. By "frozen" we mean that all local state is\nretained, including the current bindings of local variables, the\ninstruction pointer, and the internal evaluation stack: enough\ninformation is saved so that the next time ``next()`` is invoked, the\nfunction can proceed exactly as if the ``yield`` statement were just\nanother external call.\n\nThe ``yield`` statement is allowed in the ``try`` clause of a ``try``\n... ``finally`` construct. If the generator is not resumed before it\nis finalized (by reaching a zero reference count or by being garbage\ncollected), the generator-iterator\'s ``close()`` method will be\ncalled, allowing any pending ``finally`` clauses to execute.\n\nSee also:\n\n **PEP 0255** - Simple Generators\n The proposal for adding generators and the ``yield`` statement\n to Python.\n\n **PEP 0342** - Coroutines via Enhanced Generators\n The proposal that, among other generator enhancements, proposed\n allowing ``yield`` to appear inside a ``try`` ... ``finally``\n block.\n'} From python-checkins at python.org Mon Apr 27 18:29:51 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:29:51 +0200 (CEST) Subject: [Python-checkins] r72017 - in python/branches/py3k: Doc/README.txt Message-ID: <20090427162951.7983C1E4042@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:29:51 2009 New Revision: 72017 Log: Merged revisions 71956 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71956 | georg.brandl | 2009-04-26 08:05:18 +0200 (So, 26 Apr 2009) | 1 line Update versions in instructions for manual set-up. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/README.txt Modified: python/branches/py3k/Doc/README.txt ============================================================================== --- python/branches/py3k/Doc/README.txt (original) +++ python/branches/py3k/Doc/README.txt Mon Apr 27 18:29:51 2009 @@ -79,17 +79,23 @@ You'll need to checkout the Sphinx package to the `tools/` directory:: - svn co http://svn.python.org/projects/doctools/trunk/sphinx tools/sphinx + svn co http://svn.python.org/projects/external/Sphinx-0.6.1/sphinx tools/sphinx Then, you need to install Docutils, either by checking it out via :: - svn co http://svn.python.org/projects/external/docutils-0.4/docutils tools/docutils + svn co http://svn.python.org/projects/external/docutils-0.5/docutils tools/docutils or by installing it from http://docutils.sf.net/. +You also need Jinja2, either by checking it out via :: + + svn co http://svn.python.org/projects/external/Jinja-2.1.1/jinja2 tools/jinja2 + +or by installing it from PyPI. + You can optionally also install Pygments, either as a checkout via :: - svn co http://svn.python.org/projects/external/Pygments-0.9/pygments tools/pygments + svn co http://svn.python.org/projects/external/Pygments-0.11.1/pygments tools/pygments or from PyPI at http://pypi.python.org/pypi/Pygments. From python-checkins at python.org Mon Apr 27 18:32:11 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:32:11 +0200 (CEST) Subject: [Python-checkins] r72018 - in python/branches/py3k: Doc/TODO.txt Message-ID: <20090427163211.649861E4017@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:32:11 2009 New Revision: 72018 Log: Merged revisions 71958 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71958 | georg.brandl | 2009-04-26 08:06:19 +0200 (So, 26 Apr 2009) | 1 line Remove outdated TODO file. ........ Removed: python/branches/py3k/Doc/TODO.txt Modified: python/branches/py3k/ (props changed) Deleted: python/branches/py3k/Doc/TODO.txt ============================================================================== --- python/branches/py3k/Doc/TODO.txt Mon Apr 27 18:32:11 2009 +++ (empty file) @@ -1,7 +0,0 @@ -To do -===== - -* split very large files and add toctrees -* finish "Documenting Python" -* care about XXX comments -* X-refs to statements From python-checkins at python.org Mon Apr 27 18:34:37 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:34:37 +0200 (CEST) Subject: [Python-checkins] r72019 - python/branches/py3k/Doc/library/os.path.rst Message-ID: <20090427163437.975331E4017@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:34:37 2009 New Revision: 72019 Log: Remove merging accident. 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 Mon Apr 27 18:34:37 2009 @@ -287,33 +287,6 @@ *unc* will always be the empty string. Availability: Windows. -<<<<<<< .working -======= -.. function:: walk(path, visit, arg) - - Calls the function *visit* with arguments ``(arg, dirname, names)`` for each - directory in the directory tree rooted at *path* (including *path* itself, if it - is a directory). The argument *dirname* specifies the visited directory, the - argument *names* lists the files in the directory (gotten from - ``os.listdir(dirname)``). The *visit* function may modify *names* to influence - the set of directories visited below *dirname*, e.g. to avoid visiting certain - parts of the tree. (The object referred to by *names* must be modified in - place, using :keyword:`del` or slice assignment.) - - .. note:: - - Symbolic links to directories are not treated as subdirectories, and that - :func:`walk` therefore will not visit them. To visit linked directories you must - identify them with ``os.path.islink(file)`` and ``os.path.isdir(file)``, and - invoke :func:`walk` as necessary. - - .. note:: - - This function is deprecated and has been removed in 3.0 in favor of - :func:`os.walk`. - - ->>>>>>> .merge-right.r72009 .. data:: supports_unicode_filenames True if arbitrary Unicode strings can be used as file names (within limitations From python-checkins at python.org Mon Apr 27 18:34:58 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:34:58 +0200 (CEST) Subject: [Python-checkins] r72020 - python/branches/py3k/Lib/pydoc_data/topics.py Message-ID: <20090427163458.937161E4017@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:34:57 2009 New Revision: 72020 Log: Update pydoc topics for py3k. 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 Mon Apr 27 18:34:57 2009 @@ -1,83 +1,78 @@ -# Autogenerated by Sphinx on Thu Oct 2 15:45:36 2008 -topics = {'assert': u'\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': u'\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\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 is recursively defined as\nfollows.\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 a sequence 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\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`` statement in the\n current code block: the name is bound to the object in the current\n local namespace.\n\n * Otherwise: the name is bound to the object in the current global\n namespace.\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 a sequence 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* 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 a plain integer. If it is negative, the\n sequence\'s length is added to it. The resulting value must be a\n nonnegative integer less than the sequence\'s length, and the\n sequence is asked to assign the assigned object to its item with\n that index. If the index is out of range, ``IndexError`` is raised\n (assignment to a subscripted sequence cannot add new items to a\n 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* 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 (small) integers. If either\n bound is negative, the sequence\'s length is added to it. The\n resulting bounds are clipped to lie between zero and the sequence\'s\n length, inclusive. Finally, the sequence object is asked to replace\n the slice with the items of the assigned sequence. The length of\n the 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(In the current implementation, the syntax for targets is taken to be\nthe same as for expressions, and invalid syntax is rejected during the\ncode generation phase, causing less 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\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 ::= target augop (expression_list | yield_expression)\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 initial value is\nretrieved with a ``getattr()`` and the result is assigned with a\n``setattr()``. Notice that the two methods do not necessarily refer\nto the same variable. When ``getattr()`` refers to a class variable,\n``setattr()`` still writes to an instance variable. For example:\n\n class A:\n x = 3 # class variable\n a = A()\n a.x += 1 # writes a.x as 4 leaving A.x as 3\n', - 'atom-identifiers': u'\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', - 'atom-literals': u"\nLiterals\n********\n\nPython supports string literals and various numeric literals:\n\n literal ::= stringliteral | integer | longinteger\n | floatnumber | imagnumber\n\nEvaluation of a literal yields an object of the given type (string,\ninteger, long integer, floating point number, complex number) with the\ngiven value. The value may be approximated in the case of floating\npoint and imaginary (complex) literals. See section *Literals* for\ndetails.\n\nAll literals correspond to immutable data types, and hence the\nobject's identity is less important than its value. Multiple\nevaluations of literals with the same value (either the same\noccurrence in the program text or a different occurrence) may obtain\nthe same object or a different object with the same value.\n", - 'attribute-access': u'\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 in new-style classes.\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 not simply execute ``self.name = value`` --- this would\n cause a recursive call to itself. Instead, it should insert the\n value in the dictionary of instance attributes, e.g.,\n ``self.__dict__[name] = value``. For new-style classes, rather\n than accessing the instance dictionary, it should call the base\n 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\n\nMore attribute access for new-style classes\n===========================================\n\nThe following methods only apply to new-style classes.\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 builtin functions. See *Special method lookup for new-style\n classes*.\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 new-style class, known as the *owner*\nclass. In the examples below, "the attribute" refers to the attribute\nwhose name is the key of the property in the owner class\'\n``__dict__``. Descriptors can only be implemented as new-style\nclasses themselves.\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. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass ``object()`` or\n``type()``).\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 a new-style object instance, ``a.x`` is transformed\n into the call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a new-style class, ``A.x`` is transformed into the\n call: ``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. Normally, data\ndescriptors define both ``__get__()`` and ``__set__()``, while non-\ndata descriptors have just the ``__get__()`` method. Data descriptors\nalways override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances. [2]\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 both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__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 new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n New in version 2.2.\n\nNotes on using *__slots__*\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 Changed in version 2.3: Previously, adding ``\'__dict__\'`` to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\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 Changed in version 2.3: Previously, adding ``\'__weakref__\'`` to the\n *__slots__* declaration would not enable support for weak\n references.\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* 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* 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__*.\n\n* *__slots__* do not work for classes derived from "variable-length"\n built-in types such as ``long``, ``str`` and ``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 Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n', - 'attribute-references': u'\nAttribute references\n********************\n\nAn attribute reference is a primary followed by a period and a name:\n\n attributeref ::= primary "." identifier\n\nThe primary must evaluate to an object of a type that supports\nattribute references, e.g., a module, list, or an instance. This\nobject is then asked to produce the attribute whose name is the\nidentifier. If this attribute is not available, the exception\n``AttributeError`` is raised. Otherwise, the type and value of the\nobject produced is determined by the object. Multiple evaluations of\nthe same attribute reference may yield different objects.\n', - 'augassign': u'\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 ::= target augop (expression_list | yield_expression)\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 initial value is\nretrieved with a ``getattr()`` and the result is assigned with a\n``setattr()``. Notice that the two methods do not necessarily refer\nto the same variable. When ``getattr()`` refers to a class variable,\n``setattr()`` still writes to an instance variable. For example:\n\n class A:\n x = 3 # class variable\n a = A()\n a.x += 1 # writes a.x as 4 leaving A.x as 3\n', - 'binary': u'\nBinary arithmetic operations\n****************************\n\nThe binary arithmetic operations have the conventional priority\nlevels. Note that some of these operations also apply to certain non-\nnumeric types. Apart from the power operator, there are only two\nlevels, one for multiplicative operators and one for additive\noperators:\n\n m_expr ::= u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr\n | m_expr "%" u_expr\n a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr\n\nThe ``*`` (multiplication) operator yields the product of its\narguments. The arguments must either both be numbers, or one argument\nmust be an integer (plain or long) and the other must be a sequence.\nIn the former case, the numbers are converted to a common type and\nthen multiplied together. In the latter case, sequence repetition is\nperformed; a negative repetition factor yields an empty sequence.\n\nThe ``/`` (division) and ``//`` (floor division) operators yield the\nquotient of their arguments. The numeric arguments are first\nconverted to a common type. Plain or long integer division yields an\ninteger of the same type; the result is that of mathematical division\nwith the \'floor\' function applied to the result. Division by zero\nraises the ``ZeroDivisionError`` exception.\n\nThe ``%`` (modulo) operator yields the remainder from the division of\nthe first argument by the second. The numeric arguments are first\nconverted to a common type. A zero right argument raises the\n``ZeroDivisionError`` exception. The arguments may be floating point\nnumbers, e.g., ``3.14%0.7`` equals ``0.34`` (since ``3.14`` equals\n``4*0.7 + 0.34``.) The modulo operator always yields a result with\nthe same sign as its second operand (or zero); the absolute value of\nthe result is strictly smaller than the absolute value of the second\noperand [2].\n\nThe integer division and modulo operators are connected by the\nfollowing identity: ``x == (x/y)*y + (x%y)``. Integer division and\nmodulo are also connected with the built-in function ``divmod()``:\n``divmod(x, y) == (x/y, x%y)``. These identities don\'t hold for\nfloating point numbers; there similar identities hold approximately\nwhere ``x/y`` is replaced by ``floor(x/y)`` or ``floor(x/y) - 1`` [3].\n\nIn addition to performing the modulo operation on numbers, the ``%``\noperator is also overloaded by string and unicode objects to perform\nstring formatting (also known as interpolation). The syntax for string\nformatting is described in the Python Library Reference, section\n*String Formatting Operations*.\n\nDeprecated since version 2.3: The floor division operator, the modulo\noperator, and the ``divmod()`` function are no longer defined for\ncomplex numbers. Instead, convert to a floating point number using\nthe ``abs()`` function if appropriate.\n\nThe ``+`` (addition) operator yields the sum of its arguments. The\narguments must either both be numbers or both sequences of the same\ntype. In the former case, the numbers are converted to a common type\nand then added together. In the latter case, the sequences are\nconcatenated.\n\nThe ``-`` (subtraction) operator yields the difference of its\narguments. The numeric arguments are first converted to a common\ntype.\n', - 'bitwise': u'\nBinary bitwise operations\n*************************\n\nEach of the three bitwise operations has a different priority level:\n\n and_expr ::= shift_expr | and_expr "&" shift_expr\n xor_expr ::= and_expr | xor_expr "^" and_expr\n or_expr ::= xor_expr | or_expr "|" xor_expr\n\nThe ``&`` operator yields the bitwise AND of its arguments, which must\nbe plain or long integers. The arguments are converted to a common\ntype.\n\nThe ``^`` operator yields the bitwise XOR (exclusive OR) of its\narguments, which must be plain or long integers. The arguments are\nconverted to a common type.\n\nThe ``|`` operator yields the bitwise (inclusive) OR of its arguments,\nwhich must be plain or long integers. The arguments are converted to\na common type.\n', - 'bltin-code-objects': u'\nCode Objects\n************\n\nCode objects are used by the implementation to represent "pseudo-\ncompiled" executable Python code such as a function body. They differ\nfrom function objects because they don\'t contain a reference to their\nglobal execution environment. Code objects are returned by the built-\nin ``compile()`` function and can be extracted from function objects\nthrough their ``func_code`` attribute. See also the ``code`` module.\n\nA code object can be executed or evaluated by passing it (instead of a\nsource string) to the ``exec`` statement or the built-in ``eval()``\nfunction.\n\nSee *The standard type hierarchy* for more information.\n', - 'bltin-ellipsis-object': u'\nThe Ellipsis Object\n*******************\n\nThis object is used by extended slice notation (see *Slicings*). It\nsupports no special operations. There is exactly one ellipsis object,\nnamed ``Ellipsis`` (a built-in name).\n\nIt is written as ``Ellipsis``.\n', - 'bltin-file-objects': u'\nFile Objects\n************\n\nFile objects are implemented using C\'s ``stdio`` package and can be\ncreated with the built-in ``open()`` function. File objects are also\nreturned by some other built-in functions and methods, such as\n``os.popen()`` and ``os.fdopen()`` and the ``makefile()`` method of\nsocket objects. Temporary files can be created using the ``tempfile``\nmodule, and high-level file operations such as copying, moving, and\ndeleting files and directories can be achieved with the ``shutil``\nmodule.\n\nWhen a file operation fails for an I/O-related reason, the exception\n``IOError`` is raised. This includes situations where the operation\nis not defined for some reason, like ``seek()`` on a tty device or\nwriting a file opened for reading.\n\nFiles have the following methods:\n\nfile.close()\n\n Close the file. A closed file cannot be read or written any more.\n Any operation which requires that the file be open will raise a\n ``ValueError`` after the file has been closed. Calling ``close()``\n more than once is allowed.\n\n As of Python 2.5, you can avoid having to call this method\n explicitly if you use the ``with`` statement. For example, the\n following code will automatically close *f* when the ``with`` block\n is exited:\n\n from __future__ import with_statement # This isn\'t required in Python 2.6\n\n with open("hello.txt") as f:\n for line in f:\n print line\n\n In older versions of Python, you would have needed to do this to\n get the same effect:\n\n f = open("hello.txt")\n try:\n for line in f:\n print line\n finally:\n f.close()\n\n Note: Not all "file-like" types in Python support use as a context\n manager for the ``with`` statement. If your code is intended to\n work with any file-like object, you can use the function\n ``contextlib.closing()`` instead of using the object directly.\n\nfile.flush()\n\n Flush the internal buffer, like ``stdio``\'s ``fflush``. This may\n be a no-op on some file-like objects.\n\nfile.fileno()\n\n Return the integer "file descriptor" that is used by the underlying\n implementation to request I/O operations from the operating system.\n This can be useful for other, lower level interfaces that use file\n descriptors, such as the ``fcntl`` module or ``os.read()`` and\n friends.\n\n Note: File-like objects which do not have a real file descriptor should\n *not* provide this method!\n\nfile.isatty()\n\n Return ``True`` if the file is connected to a tty(-like) device,\n else ``False``.\n\n Note: If a file-like object is not associated with a real file, this\n method should *not* be implemented.\n\nfile.next()\n\n A file object is its own iterator, for example ``iter(f)`` returns\n *f* (unless *f* is closed). When a file is used as an iterator,\n typically in a ``for`` loop (for example, ``for line in f: print\n line``), the ``next()`` method is called repeatedly. This method\n returns the next input line, or raises ``StopIteration`` when EOF\n is hit when the file is open for reading (behavior is undefined\n when the file is open for writing). In order to make a ``for``\n loop the most efficient way of looping over the lines of a file (a\n very common operation), the ``next()`` method uses a hidden read-\n ahead buffer. As a consequence of using a read-ahead buffer,\n combining ``next()`` with other file methods (like ``readline()``)\n does not work right. However, using ``seek()`` to reposition the\n file to an absolute position will flush the read-ahead buffer.\n\n New in version 2.3.\n\nfile.read([size])\n\n Read at most *size* bytes from the file (less if the read hits EOF\n before obtaining *size* bytes). If the *size* argument is negative\n or omitted, read all data until EOF is reached. The bytes are\n returned as a string object. An empty string is returned when EOF\n is encountered immediately. (For certain files, like ttys, it\n makes sense to continue reading after an EOF is hit.) Note that\n this method may call the underlying C function ``fread`` more than\n once in an effort to acquire as close to *size* bytes as possible.\n Also note that when in non-blocking mode, less data than was\n requested may be returned, even if no *size* parameter was given.\n\n Note: This function is simply a wrapper for the underlying ``fread`` C\n function, and will behave the same in corner cases, such as\n whether the EOF value is cached.\n\nfile.readline([size])\n\n Read one entire line from the file. A trailing newline character\n is kept in the string (but may be absent when a file ends with an\n incomplete line). [6] If the *size* argument is present and non-\n negative, it is a maximum byte count (including the trailing\n newline) and an incomplete line may be returned. An empty string is\n returned *only* when EOF is encountered immediately.\n\n Note: Unlike ``stdio``\'s ``fgets``, the returned string contains null\n characters (``\'\\0\'``) if they occurred in the input.\n\nfile.readlines([sizehint])\n\n Read until EOF using ``readline()`` and return a list containing\n the lines thus read. If the optional *sizehint* argument is\n present, instead of reading up to EOF, whole lines totalling\n approximately *sizehint* bytes (possibly after rounding up to an\n internal buffer size) are read. Objects implementing a file-like\n interface may choose to ignore *sizehint* if it cannot be\n implemented, or cannot be implemented efficiently.\n\nfile.xreadlines()\n\n This method returns the same thing as ``iter(f)``.\n\n New in version 2.1.\n\n Deprecated since version 2.3: Use ``for line in file`` instead.\n\nfile.seek(offset[, whence])\n\n Set the file\'s current position, like ``stdio``\'s ``fseek``. The\n *whence* argument is optional and defaults to ``os.SEEK_SET`` or\n ``0`` (absolute file positioning); other values are ``os.SEEK_CUR``\n or ``1`` (seek relative to the current position) and\n ``os.SEEK_END`` or ``2`` (seek relative to the file\'s end). There\n is no return value.\n\n For example, ``f.seek(2, os.SEEK_CUR)`` advances the position by\n two and ``f.seek(-3, os.SEEK_END)`` sets the position to the third\n to last.\n\n Note that if the file is opened for appending (mode ``\'a\'`` or\n ``\'a+\'``), any ``seek()`` operations will be undone at the next\n write. If the file is only opened for writing in append mode (mode\n ``\'a\'``), this method is essentially a no-op, but it remains useful\n for files opened in append mode with reading enabled (mode\n ``\'a+\'``). If the file is opened in text mode (without ``\'b\'``),\n only offsets returned by ``tell()`` are legal. Use of other\n offsets causes undefined behavior.\n\n Note that not all file objects are seekable.\n\n Changed in version 2.6: Passing float values as offset has been\n deprecated.\n\nfile.tell()\n\n Return the file\'s current position, like ``stdio``\'s ``ftell``.\n\n Note: On Windows, ``tell()`` can return illegal values (after an\n ``fgets``) when reading files with Unix-style line-endings. Use\n binary mode (``\'rb\'``) to circumvent this problem.\n\nfile.truncate([size])\n\n Truncate the file\'s size. If the optional *size* argument is\n present, the file is truncated to (at most) that size. The size\n defaults to the current position. The current file position is not\n changed. Note that if a specified size exceeds the file\'s current\n size, the result is platform-dependent: possibilities include that\n the file may remain unchanged, increase to the specified size as if\n zero-filled, or increase to the specified size with undefined new\n content. Availability: Windows, many Unix variants.\n\nfile.write(str)\n\n Write a string to the file. There is no return value. Due to\n buffering, the string may not actually show up in the file until\n the ``flush()`` or ``close()`` method is called.\n\nfile.writelines(sequence)\n\n Write a sequence of strings to the file. The sequence can be any\n iterable object producing strings, typically a list of strings.\n There is no return value. (The name is intended to match\n ``readlines()``; ``writelines()`` does not add line separators.)\n\nFiles support the iterator protocol. Each iteration returns the same\nresult as ``file.readline()``, and iteration ends when the\n``readline()`` method returns an empty string.\n\nFile objects also offer a number of other interesting attributes.\nThese are not required for file-like objects, but should be\nimplemented if they make sense for the particular object.\n\nfile.closed\n\n bool indicating the current state of the file object. This is a\n read-only attribute; the ``close()`` method changes the value. It\n may not be available on all file-like objects.\n\nfile.encoding\n\n The encoding that this file uses. When Unicode strings are written\n to a file, they will be converted to byte strings using this\n encoding. In addition, when the file is connected to a terminal,\n the attribute gives the encoding that the terminal is likely to use\n (that information might be incorrect if the user has misconfigured\n the terminal). The attribute is read-only and may not be present\n on all file-like objects. It may also be ``None``, in which case\n the file uses the system default encoding for converting Unicode\n strings.\n\n New in version 2.3.\n\nfile.errors\n\n The Unicode error handler used along with the encoding.\n\n New in version 2.6.\n\nfile.mode\n\n The I/O mode for the file. If the file was created using the\n ``open()`` built-in function, this will be the value of the *mode*\n parameter. This is a read-only attribute and may not be present on\n all file-like objects.\n\nfile.name\n\n If the file object was created using ``open()``, the name of the\n file. Otherwise, some string that indicates the source of the file\n object, of the form ``<...>``. This is a read-only attribute and\n may not be present on all file-like objects.\n\nfile.newlines\n\n If Python was built with the *--with-universal-newlines* option to\n **configure** (the default) this read-only attribute exists, and\n for files opened in universal newline read mode it keeps track of\n the types of newlines encountered while reading the file. The\n values it can take are ``\'\\r\'``, ``\'\\n\'``, ``\'\\r\\n\'``, ``None``\n (unknown, no newlines read yet) or a tuple containing all the\n newline types seen, to indicate that multiple newline conventions\n were encountered. For files not opened in universal newline read\n mode the value of this attribute will be ``None``.\n\nfile.softspace\n\n Boolean that indicates whether a space character needs to be\n printed before another value when using the ``print`` statement.\n Classes that are trying to simulate a file object should also have\n a writable ``softspace`` attribute, which should be initialized to\n zero. This will be automatic for most classes implemented in\n Python (care may be needed for objects that override attribute\n access); types implemented in C will have to provide a writable\n ``softspace`` attribute.\n\n Note: This attribute is not used to control the ``print`` statement,\n but to allow the implementation of ``print`` to keep track of its\n internal state.\n', - 'bltin-null-object': u"\nThe Null Object\n***************\n\nThis object is returned by functions that don't explicitly return a\nvalue. It supports no special operations. There is exactly one null\nobject, named ``None`` (a built-in name).\n\nIt is written as ``None``.\n", - 'bltin-type-objects': u"\nType Objects\n************\n\nType objects represent the various object types. An object's type is\naccessed by the built-in function ``type()``. There are no special\noperations on types. The standard module ``types`` defines names for\nall standard built-in types.\n\nTypes are written like this: ````.\n", - 'booleans': u'\nBoolean operations\n******************\n\nBoolean operations have the lowest priority of all Python operations:\n\n expression ::= conditional_expression | lambda_form\n old_expression ::= or_test | old_lambda_form\n conditional_expression ::= or_test ["if" or_test "else" expression]\n or_test ::= and_test | or_test "or" and_test\n and_test ::= not_test | and_test "and" not_test\n not_test ::= comparison | "not" not_test\n\nIn the context of Boolean operations, and also when expressions are\nused by control flow statements, the following values are interpreted\nas false: ``False``, ``None``, numeric zero of all types, and empty\nstrings and containers (including strings, tuples, lists,\ndictionaries, sets and frozensets). All other values are interpreted\nas true. (See the ``__nonzero__()`` special method for a way to\nchange this.)\n\nThe operator ``not`` yields ``True`` if its argument is false,\n``False`` otherwise.\n\nThe expression ``x if C else y`` first evaluates *C* (*not* *x*); if\n*C* is true, *x* is evaluated and its value is returned; otherwise,\n*y* is evaluated and its value is returned.\n\nNew in version 2.5.\n\nThe expression ``x and y`` first evaluates *x*; if *x* is false, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\nThe expression ``x or y`` first evaluates *x*; if *x* is true, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\n(Note that neither ``and`` nor ``or`` restrict the value and type they\nreturn to ``False`` and ``True``, but rather return the last evaluated\nargument. This is sometimes useful, e.g., if ``s`` is a string that\nshould be replaced by a default value if it is empty, the expression\n``s or \'foo\'`` yields the desired value. Because ``not`` has to\ninvent a value anyway, it does not bother to return a value of the\nsame type as its argument, so e.g., ``not \'foo\'`` yields ``False``,\nnot ``\'\'``.)\n', - 'break': u'\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': u'\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': u'\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 [","]\n | expression genexpr_for] ")"\n argument_list ::= positional_arguments ["," keyword_arguments]\n ["," "*" expression] ["," keyword_arguments]\n ["," "**" expression]\n | keyword_arguments ["," "*" expression]\n ["," "**" expression]\n | "*" expression ["," "*" expression] ["," "**" 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 certain class instances\nthemselves are callable; extensions may define additional callable\nobject types). All argument expressions are evaluated before the call\nis attempted. Please refer to section *Function definitions* for the\nsyntax 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\nNote: An implementation may provide builtin functions whose positional\n parameters do not have names, even if they are \'named\' for the\n purpose of documentation, and which therefore cannot be supplied by\n keyword. In CPython, this is the case for functions implemented in\n C that use ``PyArg_ParseTuple`` to parse 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. Formal parameters using the syntax ``(sublist)`` cannot be\nused as keyword argument names; the outermost sublist corresponds to a\nsingle unnamed argument slot, and the argument value is assigned to\nthe sublist using the usual tuple assignment rules after all other\nparameter processing is done.\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': u'\nClass definitions\n*****************\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with ``self.name = value``.\nBoth class and instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\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', - 'coercion-rules': u"\nCoercion rules\n**************\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3.0, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don't define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from ``object``) never invoke the\n ``__coerce__()`` method in response to a binary operator; the only\n time ``__coerce__()`` is invoked is when the built-in function\n ``coerce()`` is called.\n\n* For most intents and purposes, an operator that returns\n ``NotImplemented`` is treated the same as one that is not\n implemented at all.\n\n* Below, ``__op__()`` and ``__rop__()`` are used to signify the\n generic method names corresponding to an operator; ``__iop__()`` is\n used for the corresponding in-place operator. For example, for the\n operator '``+``', ``__add__()`` and ``__radd__()`` are used for the\n left and right variant of the binary operator, and ``__iadd__()``\n for the in-place variant.\n\n* For objects *x* and *y*, first ``x.__op__(y)`` is tried. If this is\n not implemented or returns ``NotImplemented``, ``y.__rop__(x)`` is\n tried. If this is also not implemented or returns\n ``NotImplemented``, a ``TypeError`` exception is raised. But see\n the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base's ``__rop__()`` method, the right operand's ``__rop__()``\n method is tried *before* the left operand's ``__op__()`` method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand's ``__op__()`` method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is called\n before that type's ``__op__()`` or ``__rop__()`` method is called,\n but no sooner. If the coercion returns an object of a different\n type for the operand whose coercion is invoked, part of the process\n is redone using the new object.\n\n* When an in-place operator (like '``+=``') is used, if the left\n operand implements ``__iop__()``, it is invoked without any\n coercion. When the operation falls back to ``__op__()`` and/or\n ``__rop__()``, the normal coercion rules apply.\n\n* In ``x + y``, if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In ``x * y``, if one operator is a sequence that implements sequence\n repetition, and the other is an integer (``int`` or ``long``),\n sequence repetition is invoked.\n\n* Rich comparisons (implemented by methods ``__eq__()`` and so on)\n never use coercion. Three-way comparison (implemented by\n ``__cmp__()``) does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types ``int``,\n ``long`` and ``float`` do not use coercion; the type ``complex``\n however does use it. The difference can become apparent when\n subclassing these types. Over time, the type ``complex`` may be\n fixed to avoid coercion. All these types implement a\n ``__coerce__()`` method, for use by the built-in ``coerce()``\n function.\n", - 'comparisons': u'\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 forms ``<>`` and ``!=`` are equivalent; for consistency with C,\n``!=`` is preferred; where ``!=`` is mentioned below ``<>`` is also\naccepted. The ``<>`` spelling is considered obsolescent.\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,\nobjects of different types *always* compare unequal, and are ordered\nconsistently but arbitrarily. You can control comparison behavior of\nobjects of non-builtin types by defining a ``__cmp__`` method or rich\ncomparison methods like ``__gt__``, described in section *Special\nmethod names*.\n\n(This unusual definition of comparison was used to simplify the\ndefinition of operations like sorting and the ``in`` and ``not in``\noperators. In the future, the comparison rules for objects of\ndifferent types are likely to change.)\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n Unicode and 8-bit strings are fully interoperable in this behavior.\n [4]\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, ``cmp([1,2,x], [1,2,y])`` returns\n the same as ``cmp(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 their sorted\n (key, value) lists compare equal. [5] Outcomes other than equality\n are resolved consistently, but are not otherwise defined. [6]\n\n* Most other objects of builtin 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\nThe operators ``in`` and ``not in`` test for collection membership.\n``x in s`` evaluates to true if *x* is a member of the collection *s*,\nand false otherwise. ``x not in s`` returns the negation of ``x in\ns``. The collection membership test has traditionally been bound to\nsequences; an object is a member of a collection if the collection is\na sequence and contains an element equal to that object. However, it\nmake sense for many other object types to support membership tests\nwithout being a sequence. In particular, dictionaries (for keys) and\nsets support membership testing.\n\nFor the list and tuple types, ``x in y`` is true if and only if there\nexists an index *i* such that ``x == y[i]`` is true.\n\nFor the Unicode and string types, ``x in y`` is true if and only if\n*x* is a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nNote, *x* and *y* need not be the same type; consequently, ``u\'ab\' in\n\'abc\'`` will return ``True``. Empty strings are always considered to\nbe a substring of any other string, so ``"" in "abc"`` will return\n``True``.\n\nChanged in version 2.3: Previously, *x* was required to be a string of\nlength ``1``.\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__()`` and do\ndefine ``__getitem__()``, ``x in y`` is true if and only if there is a\nnon-negative 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. [7]\n', - 'compound': u'\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. Function and class\ndefinitions are also syntactically compound 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`` statements 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 | decorated\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, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\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\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nWarning: 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 internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n 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 ["," target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nChanged in version 2.5: In previous versions of Python,\n``try``...``except``...``finally`` did not work. ``try``...``except``\nhad to be nested in ``try``...``finally``.\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, a tuple containing an item compatible with the\nexception, or, in the (deprecated) case of string exceptions, is the\nraised string itself (note that the object identities must match, i.e.\nit must be the same string object, not just a string with the same\nvalue).\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 in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the ``sys`` module:\n``sys.exc_type`` receives the object identifying the exception;\n``sys.exc_value`` receives the exception\'s parameter;\n``sys.exc_traceback`` receives a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. These details are also available through the\n``sys.exc_info()`` function, which returns a tuple ``(exc_type,\nexc_value, exc_traceback)``. Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables 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\nNew in version 2.5.\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" expression ["as" target] ":" suite\n\nThe execution of the ``with`` statement proceeds as follows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__enter__()`` method is invoked.\n\n3. 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 5 below.\n\n4. The suite is executed.\n\n5. 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\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\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 decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier [, "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\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 top-level 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 must also have a default value --- this is a syntactic\nrestriction 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.\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 *Expression lists*. Note that the lambda form is\nmerely a shorthand for a simplified function definition; a function\ndefined in a "``def``" statement can be passed around or assigned to\nanother name just like a function defined by a lambda form. The\n"``def``" form is actually more powerful since it allows the execution\nof multiple statements.\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 ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with ``self.name = value``.\nBoth class and instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\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': u'\nWith Statement Context Managers\n*******************************\n\nNew in version 2.5.\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': u'\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': u'\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," the arguments\nare coerced using the coercion rules listed at *Coercion rules*. If\nboth arguments are standard numeric types, the following coercions are\napplied:\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, if either argument is a long integer, the other is\n converted to long integer;\n\n* otherwise, both must be plain integers and no conversion is\n necessary.\n\nSome additional rules apply for certain operators (e.g., a string left\nargument to the \'%\' operator). Extensions can define their own\ncoercions.\n', - 'customization': u'\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_traceback`` 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.exc_traceback`` or ``sys.last_traceback``. Circular\n references which are garbage are detected when the option cycle\n detector is enabled (it\'s on by default), but can only be cleaned\n up if there are no Python-level ``__del__()`` methods involved.\n Refer to the documentation for the ``gc`` module for more\n information about how ``__del__()`` methods are handled by the\n cycle detector, particularly the description of the ``garbage``\n 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. For this reason, ``__del__()`` methods should do\n the absolute minimum needed to maintain external invariants.\n Starting with version 1.5, Python guarantees that globals whose\n name begins with a single underscore are deleted from their\n module before other globals are deleted; if no other references\n to such globals exist, this may help in assuring that imported\n modules are still available at the time when the ``__del__()``\n method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is 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 statement 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.__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 New in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` call ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and\n ``x>=y`` calls ``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\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by ``__cmp__()`` has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\n\nobject.__hash__(self)\n\n Called for the key object for dictionary operations, and by the\n built-in function ``hash()``. Should return an integer usable as a\n hash value for dictionary operations. The only required property\n is that objects which compare equal have the same hash value; it is\n advised to somehow mix together (e.g., using exclusive or) the hash\n values for the components of the object that also play a part in\n comparison of objects.\n\n If a class does not define a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable as dictionary keys. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n the dictionary implementation requires that a key\'s hash value is\n immutable (if the object\'s hash value changes, it will be in the\n wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` 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 ``__cmp__()`` or ``__eq__()`` such that\n the hash value returned is no longer appropriate (e.g. by switching\n to a value-based concept of equality instead of the default\n identity based equality) can explicitly flag themselves as being\n unhashable by setting ``__hash__ = None`` in the class definition.\n Doing so means that not only will instances of the class raise an\n appropriate ``TypeError`` when a program attempts to retrieve their\n hash value, but they will also be correctly identified as\n unhashable when checking ``isinstance(obj, collections.Hashable)``\n (unlike classes which define their own ``__hash__()`` to explicitly\n raise ``TypeError``).\n\n Changed in version 2.5: ``__hash__()`` may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\n Changed in version 2.6: ``__hash__`` may now be set to ``None`` to\n explicitly flag instances of a class as unhashable.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing, and the built-in operation\n ``bool()``; should return ``False`` or ``True``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined (see below). If a class\n defines neither ``__len__()`` nor ``__nonzero__()``, all its\n instances are considered true.\n\nobject.__unicode__(self)\n\n Called to implement ``unicode()`` builtin; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\n', - 'debugger': u'\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``\n(undocumented) and ``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 python -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 2.4: Restarting post-mortem behavior added.\n\nTypical 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[, locals]])\n\n Execute the *statement* (given as a string) under debugger control.\n The debugger prompt appears before any code is executed; you can\n set breakpoints and type ``continue``, or you can step through the\n statement using ``step`` or ``next`` (all these commands are\n explained below). The optional *globals* and *locals* arguments\n specify the environment in which the code is executed; by default\n the dictionary of the module ``__main__`` is used. (See the\n explanation of the ``exec`` statement or the ``eval()`` built-in\n function.)\n\npdb.runeval(expression[, globals[, locals]])\n\n Evaluate the *expression* (given as a string) under debugger\n control. When ``runeval()`` returns, it returns the value of the\n expression. Otherwise this function is similar to ``run()``.\n\npdb.runcall(function[, argument, ...])\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])\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', - 'del': u'\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\nIt is illegal to delete a name from the local namespace if it occurs\nas a free variable in a nested block.\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', - 'dict': u'\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] "}"\n key_datum_list ::= key_datum ("," key_datum)* [","]\n key_datum ::= expression ":" expression\n\nA dictionary display yields a new dictionary object.\n\nThe key/datum pairs are evaluated from left to right to define the\nentries of the dictionary: each key object is used as a key into the\ndictionary to store the corresponding datum.\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': u'\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\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n', - 'else': u'\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', - 'exceptions': u'\nExceptions\n**********\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nWarning: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', - 'exec': u'\nThe ``exec`` statement\n**********************\n\n exec_stmt ::= "exec" or_expr ["in" expression ["," expression]]\n\nThis statement supports dynamic execution of Python code. The first\nexpression should evaluate to either a string, an open file object, or\na code object. If it is a string, the string is parsed as a suite of\nPython statements which is then executed (unless a syntax error\noccurs). If it is an open file, the file is parsed until EOF and\nexecuted. If it is a code object, it is simply executed. In all\ncases, the code that\'s executed is expected to be valid as file input\n(see section *File input*). Be aware that the ``return`` and\n``yield`` statements may not be used outside of function definitions\neven within the context of code passed to the ``exec`` statement.\n\nIn all cases, if the optional parts are omitted, the code is executed\nin the current scope. If only the first expression after ``in`` is\nspecified, it should be a dictionary, which will be used for both the\nglobal and the local variables. If two expressions are given, they\nare used for the global and local variables, respectively. If\nprovided, *locals* can be any mapping object.\n\nChanged in version 2.4: Formerly, *locals* was required to be a\ndictionary.\n\nAs a side effect, an implementation may insert additional keys into\nthe dictionaries given besides those corresponding to variable names\nset by the executed code. For example, the current implementation may\nadd a reference to the dictionary of the built-in module\n``__builtin__`` under the key ``__builtins__`` (!).\n\n**Programmer\'s hints:** dynamic evaluation of expressions is supported\nby the built-in function ``eval()``. The built-in functions\n``globals()`` and ``locals()`` return the current global and local\ndictionary, respectively, which may be useful to pass around for use\nby ``exec``.\n', - 'execmodel': u'\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, or in\nthe second position of an ``except`` clause header. The ``import``\nstatement of the form "``from ...import *``" binds all names defined\nin the imported module, except those beginning with an underscore.\nThis form may only be used at the module level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtin namespace, the namespace of\nthe module ``__builtin__``. The global namespace is searched first.\nIf the name is not found there, the builtin namespace is searched.\nThe global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no \'s\'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``__builtin__`` (no \'s\')\n module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\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\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nWarning: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', - 'exprlists': u'\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': u'\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 of floating point numbers can\nlook like octal integers, but are interpreted using radix 10. For\nexample, ``077e010`` is legal, and denotes the same number as\n``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': u'\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, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\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\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nWarning: 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 internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n 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': u'\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 ::= (identifier | integer) ("." attribute_name | "[" element_index "]")*\n attribute_name ::= identifier\n element_index ::= integer\n conversion ::= "r" | "s"\n format_spec ::= \n\nIn less formal terms, the replacement field starts with a\n*field_name*, which can either be a number (for a positional\nargument), or an identifier (for keyword arguments). Following this\nis an optional *conversion* field, which is preceded by an exclamation\npoint ``\'!\'``, and a *format_spec*, which is preceded by a colon\n``\':\'``.\n\nThe *field_name* itself begins with either a number or a keyword. If\nit\'s a number, it refers to a positional argument, and if it\'s a\nkeyword it refers to a named keyword argument. This can be followed\nby any number of index or attribute expressions. An expression of the\nform ``\'.name\'`` selects the named attribute using ``getattr()``,\nwhile an expression of the form ``\'[index]\'`` does an index lookup\nusing ``__getitem__()``.\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\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\nTwo conversion flags are currently supported: ``\'!s\'`` which calls\n``str()`` on the value, and ``\'!r\'`` which calls ``repr()``.\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\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 it\'s\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\nFor example, suppose you wanted to have a replacement field whose\nfield width is determined by another variable:\n\n "A man with two {0:{1}}".format("noses", 10)\n\nThis would first evaluate the inner replacement field, making the\nformat string effectively:\n\n "A man with two {0:10}"\n\nThen the outer replacement field would be evaluated, producing:\n\n "noses "\n\nWhich is substituted into the string, yielding:\n\n "A man with two noses "\n\n(The extra space is because we specified a field width of 10, and\nbecause left alignment is the default for strings.)\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\nbuiltin ``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.\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" | "x" | "X" | "%"\n\nThe *fill* character can be any character other than \'}\' (which\nsignifies the end of the field). The presence of a fill character is\nsignaled by the *next* character, which must be one of the alignment\noptions. If the second character of *format_spec* is not a valid\nalignment option, then it is assumed that both the fill character and\nthe alignment option are absent.\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\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 ignored for integer values.\n\nFinally, the *type* determines how the data should be presented.\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\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\'``. |\n +-----------+------------------------------------------------------------+\n | ``\'g\'`` | General format. This prints the number as a fixed-point |\n | | number, unless the number is too large, in which case it |\n | | switches to ``\'e\'`` exponent notation. Infinity and NaN |\n | | values are formatted as ``inf``, ``-inf`` and ``nan``, |\n | | respectively. |\n +-----------+------------------------------------------------------------+\n | ``\'G\'`` | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n | | if the number gets to 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 | The same as ``\'g\'``. |\n +-----------+------------------------------------------------------------+\n', - 'function': u'\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier [, "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\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 top-level 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 must also have a default value --- this is a syntactic\nrestriction 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.\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 *Expression lists*. Note that the lambda form is\nmerely a shorthand for a simplified function definition; a function\ndefined in a "``def``" statement can be passed around or assigned to\nanother name just like a function defined by a lambda form. The\n"``def``" form is actually more powerful since it allows the execution\nof multiple statements.\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': u'\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(The current implementation does not enforce the latter two\nrestrictions, but programs should not abuse this freedom, as future\nimplementations may enforce them or silently change the meaning of the\nprogram.)\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 an\n``exec`` statement does not affect the code block *containing* the\n``exec`` statement, and code contained in an ``exec`` statement is\nunaffected by ``global`` statements in the code containing the\n``exec`` statement. The same applies to the ``eval()``,\n``execfile()`` and ``compile()`` functions.\n', - 'id-classes': u'\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 ``__builtin__`` module.\n When not in interactive mode, ``_`` has no special meaning and is\n not 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);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\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': u'\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions:\n\n identifier ::= (letter|"_") (letter | digit | "_")*\n letter ::= lowercase | uppercase\n lowercase ::= "a"..."z"\n uppercase ::= "A"..."Z"\n digit ::= "0"..."9"\n\nIdentifiers are unlimited in length. Case is significant.\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 and del from not while\n as elif global or with\n assert else if pass yield\n break except import print\n class exec in raise\n continue finally is return\n def for lambda try\n\nChanged in version 2.4: ``None`` became a constant and is now\nrecognized by the compiler as a name for the built-in object ``None``.\nAlthough it is not a keyword, you cannot assign a different object to\nit.\n\nChanged in version 2.5: Both ``as`` and ``with`` are only recognized\nwhen the ``with_statement`` future feature has been enabled. It will\nalways be enabled in Python 2.6. See section *The with statement* for\ndetails. Note that using ``as`` and ``with`` as identifiers will\nalways issue a warning, even when the ``with_statement`` future\ndirective is not in effect.\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 ``__builtin__`` module.\n When not in interactive mode, ``_`` has no special meaning and is\n not 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);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\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': u'\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': u'\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': u'\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\nfirst form (without ``from``) repeats these steps for each identifier\nin the list. The form with ``from`` performs step (1) once, and then\nperforms step (2) repeatedly.\n\nIn this context, to "initialize" a built-in or extension module means\nto call an initialization function that the module must provide for\nthe purpose (in the reference implementation, the function\'s name is\nobtained by prepending string "init" to the module\'s name); to\n"initialize" a Python-coded module means to execute the module\'s body.\n\nThe system maintains a table of modules that have been or are being\ninitialized, indexed by module name. This table is accessible as\n``sys.modules``. When a module name is found in this table, step (1)\nis finished. If not, a search for a module definition is started.\nWhen a module is found, it is loaded. Details of the module searching\nand loading process are implementation and platform specific. It\ngenerally involves searching for a "built-in" module with the given\nname and then searching a list of locations given as ``sys.path``.\n\nIf a built-in module is found, its built-in initialization code is\nexecuted and step (1) is finished. If no matching file is found,\n``ImportError`` is raised. If a file is found, it is parsed, yielding\nan executable code block. If a syntax error occurs, ``SyntaxError``\nis raised. Otherwise, an empty module of the given name is created\nand inserted in the module table, and then the code block is executed\nin the context of this module. Exceptions during this execution\nterminate step (1).\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. If the\nwild card form of import --- ``import *`` --- is used in a function\nand the function contains or is a nested block with free variables,\nthe compiler will raise a ``SyntaxError``.\n\n**Hierarchical module names:** when the module names contains one or\nmore dots, the module search path is carried out differently. The\nsequence of identifiers up to the last dot is used to find a\n"package"; the final identifier is then searched inside the package.\nA package is generally a subdirectory of a directory on ``sys.path``\nthat has a file ``__init__.py``.\n\nThe built-in function ``__import__()`` is provided to support\napplications that determine which modules need to be loaded\ndynamically; refer to *Built-in Functions* for additional information.\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 2.5 are ``absolute_import``,\n``division``, ``generators``, ``nested_scopes`` and\n``with_statement``. ``generators`` and ``nested_scopes`` are\nredundant in Python version 2.3 and above because they are always\nenabled.\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 an ``exec`` statement or calls to the builtin\nfunctions ``compile()`` and ``execfile()`` that occur in a module\n``M`` containing a future statement will, by default, use the new\nsyntax or semantics associated with the future statement. This can,\nstarting with Python 2.2 be controlled by optional arguments to\n``compile()`` --- see the documentation of that function for 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', - 'in': u'\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 forms ``<>`` and ``!=`` are equivalent; for consistency with C,\n``!=`` is preferred; where ``!=`` is mentioned below ``<>`` is also\naccepted. The ``<>`` spelling is considered obsolescent.\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,\nobjects of different types *always* compare unequal, and are ordered\nconsistently but arbitrarily. You can control comparison behavior of\nobjects of non-builtin types by defining a ``__cmp__`` method or rich\ncomparison methods like ``__gt__``, described in section *Special\nmethod names*.\n\n(This unusual definition of comparison was used to simplify the\ndefinition of operations like sorting and the ``in`` and ``not in``\noperators. In the future, the comparison rules for objects of\ndifferent types are likely to change.)\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n Unicode and 8-bit strings are fully interoperable in this behavior.\n [4]\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, ``cmp([1,2,x], [1,2,y])`` returns\n the same as ``cmp(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 their sorted\n (key, value) lists compare equal. [5] Outcomes other than equality\n are resolved consistently, but are not otherwise defined. [6]\n\n* Most other objects of builtin 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\nThe operators ``in`` and ``not in`` test for collection membership.\n``x in s`` evaluates to true if *x* is a member of the collection *s*,\nand false otherwise. ``x not in s`` returns the negation of ``x in\ns``. The collection membership test has traditionally been bound to\nsequences; an object is a member of a collection if the collection is\na sequence and contains an element equal to that object. However, it\nmake sense for many other object types to support membership tests\nwithout being a sequence. In particular, dictionaries (for keys) and\nsets support membership testing.\n\nFor the list and tuple types, ``x in y`` is true if and only if there\nexists an index *i* such that ``x == y[i]`` is true.\n\nFor the Unicode and string types, ``x in y`` is true if and only if\n*x* is a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nNote, *x* and *y* need not be the same type; consequently, ``u\'ab\' in\n\'abc\'`` will return ``True``. Empty strings are always considered to\nbe a substring of any other string, so ``"" in "abc"`` will return\n``True``.\n\nChanged in version 2.3: Previously, *x* was required to be a string of\nlength ``1``.\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__()`` and do\ndefine ``__getitem__()``, ``x in y`` is true if and only if there is a\nnon-negative 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. [7]\n', - 'integers': u'\nInteger and long integer literals\n*********************************\n\nInteger and long integer literals are described by the following\nlexical definitions:\n\n longinteger ::= integer ("l" | "L")\n integer ::= decimalinteger | octinteger | hexinteger\n decimalinteger ::= nonzerodigit digit* | "0"\n octinteger ::= "0" octdigit+\n hexinteger ::= "0" ("x" | "X") hexdigit+\n nonzerodigit ::= "1"..."9"\n octdigit ::= "0"..."7"\n hexdigit ::= digit | "a"..."f" | "A"..."F"\n\nAlthough both lower case ``\'l\'`` and upper case ``\'L\'`` are allowed as\nsuffix for long integers, it is strongly recommended to always use\n``\'L\'``, since the letter ``\'l\'`` looks too much like the digit\n``\'1\'``.\n\nPlain integer literals that are above the largest representable plain\ninteger (e.g., 2147483647 when using 32-bit arithmetic) are accepted\nas if they were long integers instead. [1] There is no limit for long\ninteger literals apart from what can be stored in available memory.\n\nSome examples of plain integer literals (first row) and long integer\nliterals (second and third rows):\n\n 7 2147483647 0177\n 3L 79228162514264337593543950336L 0377L 0x100000000L\n 79228162514264337593543950336 0xdeadbeef\n', - 'lambda': u'\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', - 'lists': u'\nList displays\n*************\n\nA list display is a possibly empty series of expressions enclosed in\nsquare brackets:\n\n list_display ::= "[" [expression_list | list_comprehension] "]"\n list_comprehension ::= expression list_for\n list_for ::= "for" target_list "in" old_expression_list [list_iter]\n old_expression_list ::= old_expression [("," old_expression)+ [","]]\n list_iter ::= list_for | list_if\n list_if ::= "if" old_expression [list_iter]\n\nA list display yields a new list object. Its contents are specified\nby providing either a list of expressions or a list comprehension.\nWhen a comma-separated list of expressions is supplied, its elements\nare evaluated from left to right and placed into the list object in\nthat order. When a list comprehension is supplied, it consists of a\nsingle expression followed by at least one ``for`` clause and zero or\nmore ``for`` or ``if`` clauses. In this case, the elements of the new\nlist are those that would be produced by considering each of the\n``for`` or ``if`` clauses a block, nesting from left to right, and\nevaluating the expression to produce a list element each time the\ninnermost block is reached [1].\n', - 'naming': u'\nNaming and binding\n******************\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, or in\nthe second position of an ``except`` clause header. The ``import``\nstatement of the form "``from ...import *``" binds all names defined\nin the imported module, except those beginning with an underscore.\nThis form may only be used at the module level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtin namespace, the namespace of\nthe module ``__builtin__``. The global namespace is searched first.\nIf the name is not found there, the builtin namespace is searched.\nThe global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no \'s\'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``__builtin__`` (no \'s\')\n module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\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\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n', - 'numbers': u"\nNumeric literals\n****************\n\nThere are four types of numeric literals: plain integers, long\nintegers, floating point numbers, and imaginary numbers. There are no\ncomplex literals (complex numbers can be formed by adding a real\nnumber and an imaginary 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': u'\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.__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 (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression ``x + y``, where *x* is an\n 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__()`` (described below). Note\n that ``__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.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(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 (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [3] For instance, to evaluate\n the expression ``x - y``, where *y* is an instance of a class that\n has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *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.__idiv__(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 operations (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\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 operation falls back to the normal methods. For instance, to\n evaluate the expression ``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.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``long()``, and ``float()``. Should return a value of\n the appropriate type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions ``oct()`` and ``hex()``.\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n New in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or ``None`` if conversion is impossible. When\n the common type would be the type of ``other``, it is sufficient to\n return ``None``, since the interpreter will also ask the other\n object to attempt a coercion (but sometimes, if the implementation\n of the other type cannot be changed, it is useful to do the\n conversion to the other type here). A return value of\n ``NotImplemented`` is equivalent to returning ``None``.\n', - 'objects': u'\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. (Implementation note: the current implementation uses a\nreference-counting scheme with (optional) delayed detection of\ncyclically linked garbage, which collects most objects as soon as they\nbecome unreachable, but is not guaranteed to collect garbage\ncontaining circular references. See the documentation of the ``gc``\nmodule for information on controlling the collection of cyclic\ngarbage.)\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 provides a convenient way to do\nthis.\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': u'\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| ``or`` | Boolean OR |\n+-------------------------------------------------+---------------------------------------+\n| ``and`` | Boolean AND |\n+-------------------------------------------------+---------------------------------------+\n| ``not`` *x* | Boolean NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``in``, ``not`` ``in`` | Membership tests |\n+-------------------------------------------------+---------------------------------------+\n| ``is``, ``is not`` | Identity tests |\n+-------------------------------------------------+---------------------------------------+\n| ``<``, ``<=``, ``>``, ``>=``, ``<>``, ``!=``, | Comparisons |\n| ``==`` | |\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+-------------------------------------------------+---------------------------------------+\n| ``+x``, ``-x`` | Positive, negative |\n+-------------------------------------------------+---------------------------------------+\n| ``~x`` | Bitwise not |\n+-------------------------------------------------+---------------------------------------+\n| ``**`` | Exponentiation |\n+-------------------------------------------------+---------------------------------------+\n| ``x[index]`` | Subscription |\n+-------------------------------------------------+---------------------------------------+\n| ``x[index:index]`` | Slicing |\n+-------------------------------------------------+---------------------------------------+\n| ``x(arguments...)`` | Call |\n+-------------------------------------------------+---------------------------------------+\n| ``x.attribute`` | Attribute reference |\n+-------------------------------------------------+---------------------------------------+\n| ``(expressions...)`` | Binding or tuple display |\n+-------------------------------------------------+---------------------------------------+\n| ``[expressions...]`` | List display |\n+-------------------------------------------------+---------------------------------------+\n| ``{key:datum...}`` | Dictionary display |\n+-------------------------------------------------+---------------------------------------+\n| ```expressions...``` | String conversion |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] In Python 2.3 and later releases, a list comprehension "leaks" the\n control variables of each ``for`` it contains into the containing\n scope. However, this behavior is deprecated, and relying on it\n will not work in Python 3.0\n\n[2] 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[3] If x is very close to an exact integer multiple of y, it\'s\n possible for ``floor(x/y)`` to be one larger than ``(x-x%y)/y``\n due to rounding. In such cases, Python returns the latter result,\n in order to preserve that ``divmod(x,y)[0] * y + x % y`` be very\n close to ``x``.\n\n[4] While comparisons between unicode strings make sense at the byte\n level, they may be counter-intuitive to users. For example, the\n strings ``u"\\u00C7"`` and ``u"\\u0043\\u0327"`` compare differently,\n even though they both represent the same unicode character (LATIN\n CAPTITAL LETTER C WITH CEDILLA). To compare strings in a human\n recognizable way, compare using ``unicodedata.normalize()``.\n\n[5] The implementation computes this efficiently, without constructing\n lists or sorting.\n\n[6] Earlier versions of Python used lexicographic comparison of the\n sorted (key, value) lists, but this was very expensive for the\n common case of comparing for equality. An even earlier version of\n Python compared dictionaries by identity only, but this caused\n surprises because people expected to be able to test a dictionary\n for emptiness by comparing it to ``{}``.\n\n[7] 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', - 'pass': u'\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': u'\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. The result type is that of the\narguments after coercion.\n\nWith mixed operand types, the coercion rules for binary arithmetic\noperators apply. For int and long int operands, the result has the\nsame type as the operands (after coercion) unless the second argument\nis negative; in that case, all arguments are converted to float and a\nfloat result is delivered. For example, ``10**2`` returns ``100``, but\n``10**-2`` returns ``0.01``. (This last feature was added in Python\n2.2. In Python 2.1 and before, if both arguments were of integer types\nand the second argument was negative, an exception was raised).\n\nRaising ``0.0`` to a negative power results in a\n``ZeroDivisionError``. Raising a negative number to a fractional power\nresults in a ``ValueError``.\n', - 'print': u'\nThe ``print`` statement\n***********************\n\n print_stmt ::= "print" ([expression ("," expression)* [","]]\n | ">>" expression [("," expression)+ [","]])\n\n``print`` evaluates each expression in turn and writes the resulting\nobject to standard output (see below). If an object is not a string,\nit is first converted to a string using the rules for string\nconversions. The (resulting or original) string is then written. A\nspace is written before each object is (converted and) written, unless\nthe output system believes it is positioned at the beginning of a\nline. This is the case (1) when no characters have yet been written\nto standard output, (2) when the last character written to standard\noutput is ``\'\\n\'``, or (3) when the last write operation on standard\noutput was not a ``print`` statement. (In some cases it may be\nfunctional to write an empty string to standard output for this\nreason.)\n\nNote: Objects which act like file objects but which are not the built-in\n file objects often do not properly emulate this aspect of the file\n object\'s behavior, so it is best not to rely on this.\n\nA ``\'\\n\'`` character is written at the end, unless the ``print``\nstatement ends with a comma. This is the only action if the statement\ncontains just the keyword ``print``.\n\nStandard output is defined as the file object named ``stdout`` in the\nbuilt-in module ``sys``. If no such object exists, or if it does not\nhave a ``write()`` method, a ``RuntimeError`` exception is raised.\n\n``print`` also has an extended form, defined by the second portion of\nthe syntax described above. This form is sometimes referred to as\n"``print`` chevron." In this form, the first expression after the\n``>>`` must evaluate to a "file-like" object, specifically an object\nthat has a ``write()`` method as described above. With this extended\nform, the subsequent expressions are printed to this file object. If\nthe first expression evaluates to ``None``, then ``sys.stdout`` is\nused as the file for output.\n', - 'raise': u'\nThe ``raise`` statement\n***********************\n\n raise_stmt ::= "raise" [expression ["," expression ["," 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 expressions to get three objects,\nusing ``None`` as the value of omitted expressions. The first two\nobjects are used to determine the *type* and *value* of the exception.\n\nIf the first object is an instance, the type of the exception is the\nclass of the instance, the instance itself is the value, and the\nsecond object must be ``None``.\n\nIf the first object is a class, it becomes the type of the exception.\nThe second object is used to determine the exception value: If it is\nan instance of the class, the instance becomes the exception value. If\nthe second object is a tuple, it is used as the argument list for the\nclass constructor; if it is ``None``, an empty argument list is used,\nand any other object is treated as a single argument to the\nconstructor. The instance so created by calling the constructor is\nused as the exception value.\n\nIf a third object is present and not ``None``, it must be a traceback\nobject (see section *The standard type hierarchy*), and it is\nsubstituted instead of the current location as the place where the\nexception occurred. If the third object is present and not a\ntraceback object or ``None``, a ``TypeError`` exception is raised.\nThe three-expression form of ``raise`` is useful to re-raise an\nexception transparently in an except clause, but ``raise`` with no\nexpressions should be preferred if the exception to be re-raised was\nthe most recently active exception in the current scope.\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', - 'return': u'\nThe ``return`` statement\n************************\n\n return_stmt ::= "return" [expression_list]\n\n``return`` may only occur syntactically nested in a function\ndefinition, not within a nested class definition.\n\nIf an expression list is present, it is evaluated, else ``None`` is\nsubstituted.\n\n``return`` leaves the current function call with the expression list\n(or ``None``) as return value.\n\nWhen ``return`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nleaving the function.\n\nIn a generator function, the ``return`` statement is not allowed to\ninclude an **expression_list**. In that context, a bare ``return``\nindicates that the generator is done and will cause ``StopIteration``\nto be raised.\n', - 'sequence-methods': u'\nAdditional methods for emulation of sequence types\n**************************************************\n\nThe following optional methods can be defined to further emulate\nsequence objects. Immutable sequences methods should at most only\ndefine ``__getslice__()``; mutable sequences might define all three\nmethods.\n\nobject.__getslice__(self, i, j)\n\n Deprecated since version 2.0: Support slice objects as parameters\n to the ``__getitem__()`` method. (However, built-in types in\n CPython currently still implement ``__getslice__()``. Therefore,\n you have to override it in derived classes when implementing\n slicing.)\n\n Called to implement evaluation of ``self[i:j]``. The returned\n object should be of the same type as *self*. Note that missing *i*\n or *j* in the slice expression are replaced by zero or\n ``sys.maxint``, respectively. If negative indexes are used in the\n slice, the length of the sequence is added to that index. If the\n instance does not implement the ``__len__()`` method, an\n ``AttributeError`` is raised. No guarantee is made that indexes\n adjusted this way are not still negative. Indexes which are\n greater than the length of the sequence are not modified. If no\n ``__getslice__()`` is found, a slice object is created instead, and\n passed to ``__getitem__()`` instead.\n\nobject.__setslice__(self, i, j, sequence)\n\n Called to implement assignment to ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``.\n\n This method is deprecated. If no ``__setslice__()`` is found, or\n for extended slicing of the form ``self[i:j:k]``, a slice object is\n created, and passed to ``__setitem__()``, instead of\n ``__setslice__()`` being called.\n\nobject.__delslice__(self, i, j)\n\n Called to implement deletion of ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``. This method is deprecated. If no\n ``__delslice__()`` is found, or for extended slicing of the form\n ``self[i:j:k]``, a slice object is created, and passed to\n ``__delitem__()``, instead of ``__delslice__()`` being called.\n\nNotice that these methods are only invoked when a single slice with a\nsingle colon is used, and the slice method is available. For slice\noperations involving extended slice notation, or in absence of the\nslice methods, ``__getitem__()``, ``__setitem__()`` or\n``__delitem__()`` is called with a slice object as argument.\n\nThe following example demonstrate how to make your program or module\ncompatible with earlier versions of Python (assuming that methods\n``__getitem__()``, ``__setitem__()`` and ``__delitem__()`` support\nslice objects as arguments):\n\n class MyClass:\n ...\n def __getitem__(self, index):\n ...\n def __setitem__(self, index, value):\n ...\n def __delitem__(self, index):\n ...\n\n if sys.version_info < (2, 0):\n # They won\'t be defined if version is at least 2.0 final\n\n def __getslice__(self, i, j):\n return self[max(0, i):max(0, j):]\n def __setslice__(self, i, j, seq):\n self[max(0, i):max(0, j):] = seq\n def __delslice__(self, i, j):\n del self[max(0, i):max(0, j):]\n ...\n\nNote the calls to ``max()``; these are necessary because of the\nhandling of negative indices before the ``__*slice__()`` methods are\ncalled. When negative indexes are used, the ``__*item__()`` methods\nreceive them as provided, but the ``__*slice__()`` methods get a\n"cooked" form of the index values. For each negative index value, the\nlength of the sequence is added to the index before calling the method\n(which may still result in a negative index); this is the customary\nhandling of negative indexes by the built-in sequence types, and the\n``__*item__()`` methods are expected to do this as well. However,\nsince they should already be doing that, negative indexes cannot be\npassed in; they must be constrained to the bounds of the sequence\nbefore being passed to the ``__*item__()`` methods. Calling ``max(0,\ni)`` conveniently returns the proper value.\n', - 'sequence-types': u"\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. (For backwards compatibility, the method\n``__getslice__()`` (see below) can also be defined to handle simple,\nbut not extended slices.) It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``has_key()``,\n``get()``, ``clear()``, ``setdefault()``, ``iterkeys()``,\n``itervalues()``, ``iteritems()``, ``pop()``, ``popitem()``,\n``copy()``, and ``update()`` behaving similar to those for Python's\nstandard dictionary objects. The ``UserDict`` module provides a\n``DictMixin`` class to help create those methods from a base set of\n``__getitem__()``, ``__setitem__()``, ``__delitem__()``, and\n``keys()``. Mutable sequences should provide methods ``append()``,\n``count()``, ``index()``, ``extend()``, ``insert()``, ``pop()``,\n``remove()``, ``reverse()`` and ``sort()``, like Python standard list\nobjects. Finally, sequence types should implement addition (meaning\nconcatenation) and multiplication (meaning repetition) by defining the\nmethods ``__add__()``, ``__radd__()``, ``__iadd__()``, ``__mul__()``,\n``__rmul__()`` and ``__imul__()`` described below; they should not\ndefine ``__coerce__()`` or other numerical operators. It is\nrecommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should be equivalent of ``has_key()``;\nfor sequences, 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``iterkeys()``; 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 ``__nonzero__()`` method and whose\n ``__len__()`` method returns zero is considered to be false in a\n Boolean context.\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 ``iterkeys()``.\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()`` builtin 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()`` builtin will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects should\n normally only provide ``__reversed__()`` if they do not support the\n sequence protocol and an efficient implementation of reverse\n iteration is possible.\n\n New in version 2.6.\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", - 'shifting': u'\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 plain or long integers as arguments. The\narguments are converted to a common type. 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,\nn)``. Negative shift counts raise a ``ValueError`` exception.\n', - 'slicings': u'\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 ::= simple_slicing | extended_slicing\n simple_slicing ::= primary "[" short_slice "]"\n extended_slicing ::= primary "[" slice_list "]"\n slice_list ::= slice_item ("," slice_item)* [","]\n slice_item ::= expression | proper_slice | ellipsis\n proper_slice ::= short_slice | long_slice\n short_slice ::= [lower_bound] ":" [upper_bound]\n long_slice ::= short_slice ":" [stride]\n lower_bound ::= expression\n upper_bound ::= expression\n stride ::= expression\n ellipsis ::= "..."\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 nor ellipses). Similarly, when the slice\nlist has exactly one short slice and no trailing comma, the\ninterpretation as a simple slicing takes priority over that as an\nextended slicing.\n\nThe semantics for a simple slicing are as follows. The primary must\nevaluate to a sequence object. The lower and upper bound expressions,\nif present, must evaluate to plain integers; defaults are zero and the\n``sys.maxint``, respectively. If either bound is negative, the\nsequence\'s length is added to it. The slicing now selects all items\nwith index *k* such that ``i <= k < j`` where *i* and *j* are the\nspecified lower and upper bounds. This may be an empty sequence. It\nis not an error if *i* or *j* lie outside the range of valid indexes\n(such items don\'t exist so they aren\'t selected).\n\nThe semantics for an extended slicing are as follows. The primary\nmust evaluate to a mapping object, and it is indexed with a key that\nis constructed 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 an ellipsis slice\nitem is the built-in ``Ellipsis`` object. The conversion of a proper\nslice is a slice object (see section *The standard type hierarchy*)\nwhose ``start``, ``stop`` and ``step`` attributes are the values of\nthe expressions given as lower bound, upper bound and stride,\nrespectively, substituting ``None`` for missing expressions.\n', - 'specialattrs': u"\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\nobject.__methods__\n\n Deprecated since version 2.2: Use the built-in function ``dir()``\n to get a list of an object's attributes. This attribute is no\n longer available.\n\nobject.__members__\n\n Deprecated since version 2.2: Use the built-in function ``dir()``\n to get a list of an object's attributes. This attribute is no\n longer available.\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. If there are no base\n classes, this will be an empty tuple.\n\nclass.__name__\n\n The name of the class or type.\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\n[5] These numbers are fairly arbitrary. They are intended to avoid\n printing endless strings of meaningless digits without hampering\n correct use and without having to know the exact precision of\n floating point values on a particular machine.\n\n[6] The advantage of leaving the newline on is that returning an empty\n string is then an unambiguous EOF indication. It is also possible\n (in cases where it might matter, for example, if you want to make\n an exact copy of a file while scanning its lines) to tell whether\n the last line of a file ended in a newline or not (yes this\n happens!).\n", - 'specialnames': u'\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 ``x.__getitem__(i)`` for\nold-style classes and ``type(x).__getitem__(x, i)`` for new-style\nclasses. Except where mentioned, attempts to execute an operation\nraise an 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_traceback`` 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.exc_traceback`` or ``sys.last_traceback``. Circular\n references which are garbage are detected when the option cycle\n detector is enabled (it\'s on by default), but can only be cleaned\n up if there are no Python-level ``__del__()`` methods involved.\n Refer to the documentation for the ``gc`` module for more\n information about how ``__del__()`` methods are handled by the\n cycle detector, particularly the description of the ``garbage``\n 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. For this reason, ``__del__()`` methods should do\n the absolute minimum needed to maintain external invariants.\n Starting with version 1.5, Python guarantees that globals whose\n name begins with a single underscore are deleted from their\n module before other globals are deleted; if no other references\n to such globals exist, this may help in assuring that imported\n modules are still available at the time when the ``__del__()``\n method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is 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 statement 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.__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 New in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` call ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and\n ``x>=y`` calls ``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\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by ``__cmp__()`` has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\n\nobject.__hash__(self)\n\n Called for the key object for dictionary operations, and by the\n built-in function ``hash()``. Should return an integer usable as a\n hash value for dictionary operations. The only required property\n is that objects which compare equal have the same hash value; it is\n advised to somehow mix together (e.g., using exclusive or) the hash\n values for the components of the object that also play a part in\n comparison of objects.\n\n If a class does not define a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable as dictionary keys. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n the dictionary implementation requires that a key\'s hash value is\n immutable (if the object\'s hash value changes, it will be in the\n wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` 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 ``__cmp__()`` or ``__eq__()`` such that\n the hash value returned is no longer appropriate (e.g. by switching\n to a value-based concept of equality instead of the default\n identity based equality) can explicitly flag themselves as being\n unhashable by setting ``__hash__ = None`` in the class definition.\n Doing so means that not only will instances of the class raise an\n appropriate ``TypeError`` when a program attempts to retrieve their\n hash value, but they will also be correctly identified as\n unhashable when checking ``isinstance(obj, collections.Hashable)``\n (unlike classes which define their own ``__hash__()`` to explicitly\n raise ``TypeError``).\n\n Changed in version 2.5: ``__hash__()`` may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\n Changed in version 2.6: ``__hash__`` may now be set to ``None`` to\n explicitly flag instances of a class as unhashable.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing, and the built-in operation\n ``bool()``; should return ``False`` or ``True``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined (see below). If a class\n defines neither ``__len__()`` nor ``__nonzero__()``, all its\n instances are considered true.\n\nobject.__unicode__(self)\n\n Called to implement ``unicode()`` builtin; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\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 in new-style classes.\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 not simply execute ``self.name = value`` --- this would\n cause a recursive call to itself. Instead, it should insert the\n value in the dictionary of instance attributes, e.g.,\n ``self.__dict__[name] = value``. For new-style classes, rather\n than accessing the instance dictionary, it should call the base\n 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\n\nMore attribute access for new-style classes\n-------------------------------------------\n\nThe following methods only apply to new-style classes.\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 builtin functions. See *Special method lookup for new-style\n classes*.\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 new-style class, known as the *owner*\nclass. In the examples below, "the attribute" refers to the attribute\nwhose name is the key of the property in the owner class\'\n``__dict__``. Descriptors can only be implemented as new-style\nclasses themselves.\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. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass ``object()`` or\n``type()``).\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 a new-style object instance, ``a.x`` is transformed\n into the call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a new-style class, ``A.x`` is transformed into the\n call: ``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. Normally, data\ndescriptors define both ``__get__()`` and ``__set__()``, while non-\ndata descriptors have just the ``__get__()`` method. Data descriptors\nalways override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances. [2]\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 both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__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 new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n New in version 2.2.\n\nNotes on using *__slots__*\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 Changed in version 2.3: Previously, adding ``\'__dict__\'`` to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\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 Changed in version 2.3: Previously, adding ``\'__weakref__\'`` to the\n *__slots__* declaration would not enable support for weak\n references.\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* 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* 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__*.\n\n* *__slots__* do not work for classes derived from "variable-length"\n built-in types such as ``long``, ``str`` and ``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 Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, new-style classes are constructed using ``type()``. A\nclass definition is read into a separate namespace and the value of\nclass name is bound to the result of ``type(name, bases, dict)``.\n\nWhen the class definition is read, if *__metaclass__* is defined then\nthe callable assigned to it will be called instead of ``type()``. 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\n__metaclass__\n\n This variable can be any callable accepting arguments for ``name``,\n ``bases``, and ``dict``. Upon class creation, the callable is used\n instead of the built-in ``type()``.\n\n New in version 2.2.\n\nThe appropriate metaclass is determined by the following precedence\nrules:\n\n* If ``dict[\'__metaclass__\']`` exists, it is used.\n\n* Otherwise, if there is at least one base class, its metaclass is\n used (this looks for a *__class__* attribute first and if not found,\n uses its type).\n\n* Otherwise, if a global variable named __metaclass__ exists, it is\n used.\n\n* Otherwise, the old-style, classic metaclass (types.ClassType) is\n 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\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. (For backwards compatibility, the method\n``__getslice__()`` (see below) can also be defined to handle simple,\nbut not extended slices.) It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``has_key()``,\n``get()``, ``clear()``, ``setdefault()``, ``iterkeys()``,\n``itervalues()``, ``iteritems()``, ``pop()``, ``popitem()``,\n``copy()``, and ``update()`` behaving similar to those for Python\'s\nstandard dictionary objects. The ``UserDict`` module provides a\n``DictMixin`` class to help create those methods from a base set of\n``__getitem__()``, ``__setitem__()``, ``__delitem__()``, and\n``keys()``. Mutable sequences should provide methods ``append()``,\n``count()``, ``index()``, ``extend()``, ``insert()``, ``pop()``,\n``remove()``, ``reverse()`` and ``sort()``, like Python standard list\nobjects. Finally, sequence types should implement addition (meaning\nconcatenation) and multiplication (meaning repetition) by defining the\nmethods ``__add__()``, ``__radd__()``, ``__iadd__()``, ``__mul__()``,\n``__rmul__()`` and ``__imul__()`` described below; they should not\ndefine ``__coerce__()`` or other numerical operators. It is\nrecommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should be equivalent of ``has_key()``;\nfor sequences, 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``iterkeys()``; 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 ``__nonzero__()`` method and whose\n ``__len__()`` method returns zero is considered to be false in a\n Boolean context.\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 ``iterkeys()``.\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()`` builtin 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()`` builtin will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects should\n normally only provide ``__reversed__()`` if they do not support the\n sequence protocol and an efficient implementation of reverse\n iteration is possible.\n\n New in version 2.6.\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\nAdditional methods for emulation of sequence types\n==================================================\n\nThe following optional methods can be defined to further emulate\nsequence objects. Immutable sequences methods should at most only\ndefine ``__getslice__()``; mutable sequences might define all three\nmethods.\n\nobject.__getslice__(self, i, j)\n\n Deprecated since version 2.0: Support slice objects as parameters\n to the ``__getitem__()`` method. (However, built-in types in\n CPython currently still implement ``__getslice__()``. Therefore,\n you have to override it in derived classes when implementing\n slicing.)\n\n Called to implement evaluation of ``self[i:j]``. The returned\n object should be of the same type as *self*. Note that missing *i*\n or *j* in the slice expression are replaced by zero or\n ``sys.maxint``, respectively. If negative indexes are used in the\n slice, the length of the sequence is added to that index. If the\n instance does not implement the ``__len__()`` method, an\n ``AttributeError`` is raised. No guarantee is made that indexes\n adjusted this way are not still negative. Indexes which are\n greater than the length of the sequence are not modified. If no\n ``__getslice__()`` is found, a slice object is created instead, and\n passed to ``__getitem__()`` instead.\n\nobject.__setslice__(self, i, j, sequence)\n\n Called to implement assignment to ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``.\n\n This method is deprecated. If no ``__setslice__()`` is found, or\n for extended slicing of the form ``self[i:j:k]``, a slice object is\n created, and passed to ``__setitem__()``, instead of\n ``__setslice__()`` being called.\n\nobject.__delslice__(self, i, j)\n\n Called to implement deletion of ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``. This method is deprecated. If no\n ``__delslice__()`` is found, or for extended slicing of the form\n ``self[i:j:k]``, a slice object is created, and passed to\n ``__delitem__()``, instead of ``__delslice__()`` being called.\n\nNotice that these methods are only invoked when a single slice with a\nsingle colon is used, and the slice method is available. For slice\noperations involving extended slice notation, or in absence of the\nslice methods, ``__getitem__()``, ``__setitem__()`` or\n``__delitem__()`` is called with a slice object as argument.\n\nThe following example demonstrate how to make your program or module\ncompatible with earlier versions of Python (assuming that methods\n``__getitem__()``, ``__setitem__()`` and ``__delitem__()`` support\nslice objects as arguments):\n\n class MyClass:\n ...\n def __getitem__(self, index):\n ...\n def __setitem__(self, index, value):\n ...\n def __delitem__(self, index):\n ...\n\n if sys.version_info < (2, 0):\n # They won\'t be defined if version is at least 2.0 final\n\n def __getslice__(self, i, j):\n return self[max(0, i):max(0, j):]\n def __setslice__(self, i, j, seq):\n self[max(0, i):max(0, j):] = seq\n def __delslice__(self, i, j):\n del self[max(0, i):max(0, j):]\n ...\n\nNote the calls to ``max()``; these are necessary because of the\nhandling of negative indices before the ``__*slice__()`` methods are\ncalled. When negative indexes are used, the ``__*item__()`` methods\nreceive them as provided, but the ``__*slice__()`` methods get a\n"cooked" form of the index values. For each negative index value, the\nlength of the sequence is added to the index before calling the method\n(which may still result in a negative index); this is the customary\nhandling of negative indexes by the built-in sequence types, and the\n``__*item__()`` methods are expected to do this as well. However,\nsince they should already be doing that, negative indexes cannot be\npassed in; they must be constrained to the bounds of the sequence\nbefore being passed to the ``__*item__()`` methods. Calling ``max(0,\ni)`` conveniently returns the proper value.\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.__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 (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression ``x + y``, where *x* is an\n 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__()`` (described below). Note\n that ``__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.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(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 (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [3] For instance, to evaluate\n the expression ``x - y``, where *y* is an instance of a class that\n has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *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.__idiv__(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 operations (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\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 operation falls back to the normal methods. For instance, to\n evaluate the expression ``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.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``long()``, and ``float()``. Should return a value of\n the appropriate type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions ``oct()`` and ``hex()``.\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n New in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or ``None`` if conversion is impossible. When\n the common type would be the type of ``other``, it is sufficient to\n return ``None``, since the interpreter will also ask the other\n object to attempt a coercion (but sometimes, if the implementation\n of the other type cannot be changed, it is useful to do the\n conversion to the other type here). A return value of\n ``NotImplemented`` is equivalent to returning ``None``.\n\n\nCoercion rules\n==============\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3.0, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don\'t define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from ``object``) never invoke the\n ``__coerce__()`` method in response to a binary operator; the only\n time ``__coerce__()`` is invoked is when the built-in function\n ``coerce()`` is called.\n\n* For most intents and purposes, an operator that returns\n ``NotImplemented`` is treated the same as one that is not\n implemented at all.\n\n* Below, ``__op__()`` and ``__rop__()`` are used to signify the\n generic method names corresponding to an operator; ``__iop__()`` is\n used for the corresponding in-place operator. For example, for the\n operator \'``+``\', ``__add__()`` and ``__radd__()`` are used for the\n left and right variant of the binary operator, and ``__iadd__()``\n for the in-place variant.\n\n* For objects *x* and *y*, first ``x.__op__(y)`` is tried. If this is\n not implemented or returns ``NotImplemented``, ``y.__rop__(x)`` is\n tried. If this is also not implemented or returns\n ``NotImplemented``, a ``TypeError`` exception is raised. But see\n the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base\'s ``__rop__()`` method, the right operand\'s ``__rop__()``\n method is tried *before* the left operand\'s ``__op__()`` method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand\'s ``__op__()`` method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is called\n before that type\'s ``__op__()`` or ``__rop__()`` method is called,\n but no sooner. If the coercion returns an object of a different\n type for the operand whose coercion is invoked, part of the process\n is redone using the new object.\n\n* When an in-place operator (like \'``+=``\') is used, if the left\n operand implements ``__iop__()``, it is invoked without any\n coercion. When the operation falls back to ``__op__()`` and/or\n ``__rop__()``, the normal coercion rules apply.\n\n* In ``x + y``, if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In ``x * y``, if one operator is a sequence that implements sequence\n repetition, and the other is an integer (``int`` or ``long``),\n sequence repetition is invoked.\n\n* Rich comparisons (implemented by methods ``__eq__()`` and so on)\n never use coercion. Three-way comparison (implemented by\n ``__cmp__()``) does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types ``int``,\n ``long`` and ``float`` do not use coercion; the type ``complex``\n however does use it. The difference can become apparent when\n subclassing these types. Over time, the type ``complex`` may be\n fixed to avoid coercion. All these types implement a\n ``__coerce__()`` method, for use by the built-in ``coerce()``\n function.\n\n\nWith Statement Context Managers\n===============================\n\nNew in version 2.5.\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 for old-style classes\n===========================================\n\nFor old-style classes, special methods are always looked up in exactly\nthe same way as any other method or attribute. This is the case\nregardless of whether the method is being looked up explicitly as in\n``x.__getitem__(i)`` or implicitly as in ``x[i]``.\n\nThis behaviour means that special methods may exhibit different\nbehaviour for different instances of a single old-style class if the\nappropriate special attributes are set differently:\n\n >>> class C:\n ... pass\n ...\n >>> c1 = C()\n >>> c2 = C()\n >>> c1.__len__ = lambda: 5\n >>> c2.__len__ = lambda: 9\n >>> len(c1)\n 5\n >>> len(c2)\n 9\n\n\nSpecial method lookup for new-style classes\n===========================================\n\nFor new-style classes, implicit invocations of special methods are\nonly guaranteed to work correctly if defined on an object\'s type, not\nin the object\'s instance dictionary. That behaviour is the reason why\nthe following code raises an exception (unlike the equivalent example\nwith old-style classes):\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 may also bypass the\n``__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):\n ... __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] A descriptor can define any combination of ``__get__()``,\n ``__set__()`` and ``__delete__()``. If it does not define\n ``__get__()``, then accessing the attribute even on an instance\n will return the descriptor object itself. If the descriptor\n defines ``__set__()`` and/or ``__delete__()``, it is a data\n descriptor; if it defines neither, it is a non-data descriptor.\n\n[3] 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-conversions': u'\nString conversions\n******************\n\nA string conversion is an expression list enclosed in reverse (a.k.a.\nbackward) quotes:\n\n string_conversion ::= "\'" expression_list "\'"\n\nA string conversion evaluates the contained expression list and\nconverts the resulting object into a string according to rules\nspecific to its type.\n\nIf the object is a string, a number, ``None``, or a tuple, list or\ndictionary containing only objects whose type is one of these, the\nresulting string is a valid Python expression which can be passed to\nthe built-in function ``eval()`` to yield an expression with the same\nvalue (or an approximation, if floating point numbers are involved).\n\n(In particular, converting a string adds quotes around it and converts\n"funny" characters to escape sequences that are safe to print.)\n\nRecursive objects (for example, lists or dictionaries that contain a\nreference to themselves, directly or indirectly) use ``...`` to\nindicate a recursive reference, and the result cannot be passed to\n``eval()`` to get an equal value (``SyntaxError`` will be raised\ninstead).\n\nThe built-in function ``repr()`` performs exactly the same conversion\nin its argument as enclosing it in parentheses and reverse quotes\ndoes. The built-in function ``str()`` performs a similar but more\nuser-friendly conversion.\n', - 'string-methods': u'\nString Methods\n**************\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Note that none of these methods take keyword\narguments.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbuffer, xrange* section. To output formatted strings use template\nstrings or the ``%`` operator described in the *String Formatting\nOperations* 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 only its first character\n capitalized.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of occurrences of substring *sub* in the range\n [*start*, *end*]. Optional arguments *start* and *end* are\n interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes 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\n Changed in version 2.5: Accept tuples as *suffix*.\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 range [*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(format_string, *args, **kwargs)\n\n Perform a string formatting operation. The *format_string*\n argument can contain literal text or replacement fields delimited\n by braces ``{}``. Each replacement field contains either the\n numeric index of a positional argument, or the name of a keyword\n argument. Returns a copy of *format_string* where each replacement\n field is replaced with the string value of the corresponding\n 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\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(seq)\n\n Return a string which is the concatenation of the strings in the\n sequence *seq*. The separator between elements is the string\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n New in version 2.5.\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]. Optional\n arguments *start* and *end* are interpreted as in slice notation.\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\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\n New in version 2.5.\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\n New in version 2.4.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n Changed in version 2.5: Accept tuples as *prefix*.\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\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string: words start with\n uppercase characters, all remaining cased characters are lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\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 New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n', - 'strings': u'\nString literals\n***************\n\nString literals are described by the following lexical definitions:\n\n stringliteral ::= [stringprefix](shortstring | longstring)\n stringprefix ::= "r" | "u" | "ur" | "R" | "U" | "UR" | "Ur" | "uR"\n shortstring ::= "\'" shortstringitem* "\'" | \'"\' shortstringitem* \'"\'\n longstring ::= "\'\'\'" longstringitem* "\'\'\'"\n | \'"""\' longstringitem* \'"""\'\n shortstringitem ::= shortstringchar | escapeseq\n longstringitem ::= longstringchar | escapeseq\n shortstringchar ::= \n longstringchar ::= \n escapeseq ::= "\\" \n\nOne syntactic restriction not indicated by these productions is that\nwhitespace is not allowed between the **stringprefix** and the rest of\nthe string literal. The source character set is defined by the\nencoding declaration; it is ASCII if no encoding declaration is given\nin the source file; see section *Encoding declarations*.\n\nIn plain English: String literals can be enclosed in matching single\nquotes (``\'``) or double quotes (``"``). They can also be enclosed in\nmatching groups of three single or double quotes (these are generally\nreferred to as *triple-quoted strings*). The backslash (``\\``)\ncharacter is used to escape characters that otherwise have a special\nmeaning, such as newline, backslash itself, or the quote character.\nString literals may optionally be prefixed with a letter ``\'r\'`` or\n``\'R\'``; such strings are called *raw strings* and use different rules\nfor interpreting backslash escape sequences. A prefix of ``\'u\'`` or\n``\'U\'`` makes the string a Unicode string. Unicode strings use the\nUnicode character set as defined by the Unicode Consortium and ISO\n10646. Some additional escape sequences, described below, are\navailable in Unicode strings. The two prefix characters may be\ncombined; in this case, ``\'u\'`` must appear before ``\'r\'``.\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`` | 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| ``\\N{name}`` | Character named *name* in the | |\n| | Unicode database (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\r`` | ASCII Carriage Return (CR) | |\n+-------------------+-----------------------------------+---------+\n| ``\\t`` | ASCII Horizontal Tab (TAB) | |\n+-------------------+-----------------------------------+---------+\n| ``\\uxxxx`` | Character with 16-bit hex value | (1) |\n| | *xxxx* (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\Uxxxxxxxx`` | Character with 32-bit hex value | (2) |\n| | *xxxxxxxx* (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\v`` | ASCII Vertical Tab (VT) | |\n+-------------------+-----------------------------------+---------+\n| ``\\ooo`` | Character with octal value *ooo* | (3,5) |\n+-------------------+-----------------------------------+---------+\n| ``\\xhh`` | Character with hex value *hh* | (4,5) |\n+-------------------+-----------------------------------+---------+\n\nNotes:\n\n1. Individual code units which form parts of a surrogate pair can be\n encoded using this escape sequence.\n\n2. 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). Individual code units which form parts of a surrogate\n pair can be encoded using this escape sequence.\n\n3. As in Standard C, up to three octal digits are accepted.\n\n4. Unlike in Standard C, exactly two hex digits are required.\n\n5. In a string literal, hexadecimal and octal escapes denote the byte\n with the given value; it is not necessary that the byte encodes a\n character in the source character set. In a Unicode literal, these\n escapes denote a Unicode character with the given value.\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 marked as "(Unicode only)"\nin the table above fall into the category of unrecognized escapes for\nnon-Unicode string literals.\n\nWhen an ``\'r\'`` or ``\'R\'`` prefix is present, a character following a\nbackslash is included in the string without change, and *all\nbackslashes are left in the string*. For example, the string literal\n``r"\\n"`` consists of two characters: a backslash and a lowercase\n``\'n\'``. String quotes can be escaped with a backslash, but the\nbackslash remains in the string; for example, ``r"\\""`` is a valid\nstring literal consisting of two characters: a backslash and a double\nquote; ``r"\\"`` is not a valid string literal (even a raw string\ncannot end in an odd number of backslashes). Specifically, *a raw\nstring cannot end in a single backslash* (since the backslash would\nescape 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\nWhen an ``\'r\'`` or ``\'R\'`` prefix is used in conjunction with a\n``\'u\'`` or ``\'U\'`` prefix, then the ``\\uXXXX`` and ``\\UXXXXXXXX``\nescape sequences are processed while *all other backslashes are left\nin the string*. For example, the string literal ``ur"\\u0062\\n"``\nconsists of three Unicode characters: \'LATIN SMALL LETTER B\', \'REVERSE\nSOLIDUS\', and \'LATIN SMALL LETTER N\'. Backslashes can be escaped with\na preceding backslash; however, both remain in the string. As a\nresult, ``\\uXXXX`` escape sequences are only recognized when there are\nan odd number of backslashes.\n', - 'subscriptions': u'\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 of a sequence or mapping type.\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 a\nplain integer. If this value is negative, the length of the sequence\nis added to it (so that, e.g., ``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).\n\nA string\'s items are characters. A character is not a separate data\ntype but a string of exactly one character.\n', - 'truth': u"\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``, ``0L``, ``0.0``,\n ``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 ``__nonzero__()`` or ``__len__()`` method, when that method returns\n the 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", - 'try': u'\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 ["," target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nChanged in version 2.5: In previous versions of Python,\n``try``...``except``...``finally`` did not work. ``try``...``except``\nhad to be nested in ``try``...``finally``.\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, a tuple containing an item compatible with the\nexception, or, in the (deprecated) case of string exceptions, is the\nraised string itself (note that the object identities must match, i.e.\nit must be the same string object, not just a string with the same\nvalue).\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 in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the ``sys`` module:\n``sys.exc_type`` receives the object identifying the exception;\n``sys.exc_value`` receives the exception\'s parameter;\n``sys.exc_traceback`` receives a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. These details are also available through the\n``sys.exc_info()`` function, which returns a tuple ``(exc_type,\nexc_value, exc_traceback)``. Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables 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', - 'types': u'\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.).\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name ``None``.\n It is used to signify the absence of a value in many situations,\n e.g., it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``NotImplemented``. Numeric methods and rich comparison methods may\n return this value if they do not implement the operation for the\n operands provided. (The interpreter will then try the reflected\n operation, or some other fallback, depending on the operator.) Its\n truth value is true.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``Ellipsis``. It is used to indicate the presence of the ``...``\n syntax in a slice. Its truth value is true.\n\n``numbers.Number``\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n ``numbers.Integral``\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are three types of integers:\n\n Plain integers\n These represent numbers in the range -2147483648 through\n 2147483647. (The range may be larger on machines with a\n larger natural word size, but not smaller.) When the result\n of an operation would fall outside this range, the result is\n normally returned as a long integer (in some cases, the\n exception ``OverflowError`` is raised instead). For the\n purpose of shift and mask operations, integers are assumed to\n have a binary, 2\'s complement notation using 32 or more bits,\n and hiding no bits from the user (i.e., all 4294967296\n different bit patterns correspond to different values).\n\n Long integers\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans\n These represent the truth values False and True. The two\n objects representing the values False and True are the only\n Boolean objects. The Boolean type is a subtype of plain\n integers, and Boolean values behave like the values 0 and 1,\n respectively, in almost all contexts, the exception being\n that when converted to a string, the strings ``"False"`` or\n ``"True"`` are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers and the least surprises when\n switching between the plain and long integer domains. Any\n operation, if it yields a result in the plain integer domain,\n will yield the same result in the long integer domain or when\n using mixed operands. The switch between domains is transparent\n to the programmer.\n\n ``numbers.Real`` (``float``)\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these is\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n ``numbers.Complex``\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number ``z`` can be retrieved through the read-only\n attributes ``z.real`` and ``z.imag``.\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function ``len()`` returns the number of\n items of a sequence. When the length of a sequence is *n*, the\n index set contains the numbers 0, 1, ..., *n*-1. Item *i* of\n sequence *a* is selected by ``a[i]``.\n\n Sequences also support slicing: ``a[i:j]`` selects all items with\n index *k* such that *i* ``<=`` *k* ``<`` *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: ``a[i:j:k]`` selects all items of *a* with index *x*\n where ``x = i + n*k``, *n* ``>=`` ``0`` and *i* ``<=`` *x* ``<``\n *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n The items of a string are characters. There is no separate\n character type; a character is represented by a string of one\n item. Characters represent (at least) 8-bit bytes. The\n built-in functions ``chr()`` and ``ord()`` convert between\n characters and nonnegative integers representing the byte\n values. Bytes with the values 0-127 usually represent the\n corresponding ASCII values, but the interpretation of values\n is up to the program. The string data type is also used to\n represent arrays of bytes, e.g., to hold data read from a\n file.\n\n (On systems whose native character set is not ASCII, strings\n may use EBCDIC in their internal representation, provided the\n functions ``chr()`` and ``ord()`` implement a mapping between\n ASCII and EBCDIC, and string comparison preserves the ASCII\n order. Or perhaps someone can propose a better rule?)\n\n Unicode\n The items of a Unicode object are Unicode code units. A\n Unicode code unit is represented by a Unicode object of one\n item and can hold either a 16-bit or 32-bit value\n representing a Unicode ordinal (the maximum value for the\n ordinal is given in ``sys.maxunicode``, and depends on how\n Python is configured at compile time). Surrogate pairs may\n be present in the Unicode object, and will be reported as two\n separate items. The built-in functions ``unichr()`` and\n ``ord()`` convert between code units and nonnegative integers\n representing the Unicode ordinals as defined in the Unicode\n Standard 3.0. Conversion from and to other encodings are\n possible through the Unicode method ``encode()`` and the\n built-in function ``unicode()``.\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and ``del`` (delete) statements.\n\n There is currently a single intrinsic mutable sequence type:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n The extension module ``array`` provides an additional example of\n a mutable sequence type.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function ``len()``\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n ``set()`` constructor and can be modified afterwards by several\n methods, such as ``add()``.\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in ``frozenset()`` constructor. As a frozenset is\n immutable and *hashable*, it can be used again as an element of\n another set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation ``a[k]`` selects the item indexed by\n ``k`` from the mapping ``a``; this can be used in expressions and\n as the target of assignments or ``del`` statements. The built-in\n function ``len()`` returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``) then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the ``{...}``\n notation (see section *Dictionary displays*).\n\n The extension modules ``dbm``, ``gdbm``, and ``bsddb`` provide\n additional examples of mapping types.\n\nCallable types\n These are the types to which the function call operation (see\n section *Calls*) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section *Function definitions*). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +-------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +=========================+=================================+=============+\n | ``func_doc`` | The function\'s documentation | Writable |\n | | string, or ``None`` if | |\n | | unavailable | |\n +-------------------------+---------------------------------+-------------+\n | ``__doc__`` | Another way of spelling | Writable |\n | | ``func_doc`` | |\n +-------------------------+---------------------------------+-------------+\n | ``func_name`` | The function\'s name | Writable |\n +-------------------------+---------------------------------+-------------+\n | ``__name__`` | Another way of spelling | Writable |\n | | ``func_name`` | |\n +-------------------------+---------------------------------+-------------+\n | ``__module__`` | The name of the module the | Writable |\n | | function was defined in, or | |\n | | ``None`` if unavailable. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_defaults`` | A tuple containing default | Writable |\n | | argument values for those | |\n | | arguments that have defaults, | |\n | | or ``None`` if no arguments | |\n | | have a default value | |\n +-------------------------+---------------------------------+-------------+\n | ``func_code`` | The code object representing | Writable |\n | | the compiled function body. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_globals`` | A reference to the dictionary | Read-only |\n | | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_dict`` | The namespace supporting | Writable |\n | | arbitrary function attributes. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_closure`` | ``None`` or a tuple of cells | Read-only |\n | | that contain bindings for the | |\n | | function\'s free variables. | |\n +-------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Changed in version 2.4: ``func_name`` is now writable.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n User-defined methods\n A user-defined method object combines a class, a class instance\n (or ``None``) and any callable object (normally a user-defined\n function).\n\n Special read-only attributes: ``im_self`` is the class instance\n object, ``im_func`` is the function object; ``im_class`` is the\n class of ``im_self`` for bound methods or the class that asked\n for the method for unbound methods; ``__doc__`` is the method\'s\n documentation (same as ``im_func.__doc__``); ``__name__`` is the\n method name (same as ``im_func.__name__``); ``__module__`` is\n the name of the module the method was defined in, or ``None`` if\n unavailable.\n\n Changed in version 2.2: ``im_self`` used to refer to the class\n that defined the method.\n\n Changed in version 2.6: For 3.0 forward-compatibility,\n ``im_func`` is also available as ``__func__``, and ``im_self``\n as ``__self__``.\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object, an unbound\n user-defined method object, or a class method object. When the\n attribute is a user-defined method object, a new method object\n is only created if the class from which it is being retrieved is\n the same as, or a derived class of, the class stored in the\n original method object; otherwise, the original method object is\n used as it is.\n\n When a user-defined method object is created by retrieving a\n user-defined function object from a class, its ``im_self``\n attribute is ``None`` and the method object is said to be\n unbound. When one is created by retrieving a user-defined\n function object from a class via one of its instances, its\n ``im_self`` attribute is the instance, and the method object is\n said to be bound. In either case, the new method\'s ``im_class``\n attribute is the class from which the retrieval takes place, and\n its ``im_func`` attribute is the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the ``im_func``\n attribute of the new instance is not the original method object\n but its ``im_func`` attribute.\n\n When a user-defined method object is created by retrieving a\n class method object from a class or instance, its ``im_self``\n attribute is the class itself (the same as the ``im_class``\n attribute), and its ``im_func`` attribute is the function object\n underlying the class method.\n\n When an unbound user-defined method object is called, the\n underlying function (``im_func``) is called, with the\n restriction that the first argument must be an instance of the\n proper class (``im_class``) or of a derived class thereof.\n\n When a bound user-defined method object is called, the\n underlying function (``im_func``) is called, inserting the class\n instance (``im_self``) in front of the argument list. For\n instance, when ``C`` is a class which contains a definition for\n a function ``f()``, and ``x`` is an instance of ``C``, calling\n ``x.f(1)`` is equivalent to calling ``C.f(x, 1)``.\n\n When a user-defined method object is derived from a class method\n object, the "class instance" stored in ``im_self`` will actually\n be the class itself, so that calling either ``x.f(1)`` or\n ``C.f(1)`` is equivalent to calling ``f(C,1)`` where ``f`` is\n the underlying function.\n\n Note that the transformation from function object to (unbound or\n bound) method object happens each time the attribute is\n retrieved from the class or instance. In some cases, a fruitful\n optimization is to assign the attribute to a local variable and\n call that local variable. Also notice that this transformation\n only happens for user-defined functions; other callable objects\n (and all non-callable objects) are retrieved without\n transformation. It is also important to note that user-defined\n functions which are attributes of a class instance are not\n converted to bound methods; this *only* happens when the\n function is an attribute of the class.\n\n Generator functions\n A function or method which uses the ``yield`` statement (see\n section *The yield statement*) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s ``next()`` method will cause the function to\n execute until it provides a value using the ``yield`` statement.\n When the function executes a ``return`` statement or falls off\n the end, a ``StopIteration`` exception is raised and the\n iterator will have reached the end of the set of values to be\n returned.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are ``len()`` and ``math.sin()``\n (``math`` is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: ``__doc__`` is the function\'s documentation\n string, or ``None`` if unavailable; ``__name__`` is the\n function\'s name; ``__self__`` is set to ``None`` (but see the\n next item); ``__module__`` is the name of the module the\n function was defined in or ``None`` if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n ``alist.append()``, assuming *alist* is a list object. In this\n case, the special read-only attribute ``__self__`` is set to the\n object denoted by *list*.\n\n Class Types\n Class types, or "new-style classes," are callable. These\n objects normally act as factories for new instances of\n themselves, but variations are possible for class types that\n override ``__new__()``. The arguments of the call are passed to\n ``__new__()`` and, in the typical case, to ``__init__()`` to\n initialize the new instance.\n\n Classic Classes\n Class objects are described below. When a class object is\n called, a new class instance (also described below) is created\n and returned. This implies a call to the class\'s ``__init__()``\n method if it has one. Any arguments are passed on to the\n ``__init__()`` method. If there is no ``__init__()`` method,\n the class must be called without arguments.\n\n Class instances\n Class instances are described below. Class instances are\n callable only when the class has a ``__call__()`` method;\n ``x(arguments)`` is a shorthand for ``x.__call__(arguments)``.\n\nModules\n Modules are imported by the ``import`` statement (see section *The\n import statement*). A module object has a namespace implemented by\n a dictionary object (this is the dictionary referenced by the\n func_globals attribute of functions defined in the module).\n Attribute references are translated to lookups in this dictionary,\n e.g., ``m.x`` is equivalent to ``m.__dict__["x"]``. A module object\n does not contain the code object used to initialize the module\n (since it isn\'t needed once the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``.\n\n Special read-only attribute: ``__dict__`` is the module\'s namespace\n as a dictionary object.\n\n Predefined (writable) attributes: ``__name__`` is the module\'s\n name; ``__doc__`` is the module\'s documentation string, or ``None``\n if unavailable; ``__file__`` is the pathname of the file from which\n the module was loaded, if it was loaded from a file. The\n ``__file__`` attribute is not present for C modules that are\n statically linked into the interpreter; for extension modules\n loaded dynamically from a shared library, it is the pathname of the\n shared library file.\n\nClasses\n Both class types (new-style classes) and class objects (old-\n style/classic classes) are typically created by class definitions\n (see section *Class definitions*). A class has a namespace\n implemented by a dictionary object. Class attribute references are\n translated to lookups in this dictionary, e.g., ``C.x`` is\n translated to ``C.__dict__["x"]`` (although for new-style classes\n in particular there are a number of hooks which allow for other\n means of locating attributes). When the attribute name is not found\n there, the attribute search continues in the base classes. For\n old-style classes, the search is depth-first, left-to-right in the\n order of occurrence in the base class list. New-style classes use\n the more complex C3 method resolution order which behaves correctly\n even in the presence of \'diamond\' inheritance structures where\n there are multiple inheritance paths leading back to a common\n ancestor. Additional details on the C3 MRO used by new-style\n classes can be found in the documentation accompanying the 2.3\n release at http://www.python.org/download/releases/2.3/mro/.\n\n When a class attribute reference (for class ``C``, say) would yield\n a user-defined function object or an unbound user-defined method\n object whose associated class is either ``C`` or one of its base\n classes, it is transformed into an unbound user-defined method\n object whose ``im_class`` attribute is ``C``. When it would yield a\n class method object, it is transformed into a bound user-defined\n method object whose ``im_class`` and ``im_self`` attributes are\n both ``C``. When it would yield a static method object, it is\n transformed into the object wrapped by the static method object.\n See section *Implementing Descriptors* for another way in which\n attributes retrieved from a class may differ from those actually\n contained in its ``__dict__`` (note that only new-style classes\n support descriptors).\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: ``__name__`` is the class name; ``__module__``\n is the module name in which the class was defined; ``__dict__`` is\n the dictionary containing the class\'s namespace; ``__bases__`` is a\n tuple (possibly empty or a singleton) containing the base classes,\n in the order of their occurrence in the base class list;\n ``__doc__`` is the class\'s documentation string, or None if\n undefined.\n\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object or an unbound user-defined method object whose\n associated class is the class (call it ``C``) of the instance for\n which the attribute reference was initiated or one of its bases, it\n is transformed into a bound user-defined method object whose\n ``im_class`` attribute is ``C`` and whose ``im_self`` attribute is\n the instance. Static method and class method objects are also\n transformed, as if they had been retrieved from class ``C``; see\n above under "Classes". See section *Implementing Descriptors* for\n another way in which attributes of a class retrieved via its\n instances may differ from the objects actually stored in the\n class\'s ``__dict__``. If no class attribute is found, and the\n object\'s class has a ``__getattr__()`` method, that is called to\n satisfy the lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n ``__setattr__()`` or ``__delattr__()`` method, this is called\n instead of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n *Special method names*.\n\n Special attributes: ``__dict__`` is the attribute dictionary;\n ``__class__`` is the instance\'s class.\n\nFiles\n A file object represents an open file. File objects are created by\n the ``open()`` built-in function, and also by ``os.popen()``,\n ``os.fdopen()``, and the ``makefile()`` method of socket objects\n (and perhaps by other functions or methods provided by extension\n modules). The objects ``sys.stdin``, ``sys.stdout`` and\n ``sys.stderr`` are initialized to file objects corresponding to the\n interpreter\'s standard input, output and error streams. See *File\n Objects* for complete documentation of file objects.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: ``co_name`` gives the function\n name; ``co_argcount`` is the number of positional arguments\n (including arguments with default values); ``co_nlocals`` is the\n number of local variables used by the function (including\n arguments); ``co_varnames`` is a tuple containing the names of\n the local variables (starting with the argument names);\n ``co_cellvars`` is a tuple containing the names of local\n variables that are referenced by nested functions;\n ``co_freevars`` is a tuple containing the names of free\n variables; ``co_code`` is a string representing the sequence of\n bytecode instructions; ``co_consts`` is a tuple containing the\n literals used by the bytecode; ``co_names`` is a tuple\n containing the names used by the bytecode; ``co_filename`` is\n the filename from which the code was compiled;\n ``co_firstlineno`` is the first line number of the function;\n ``co_lnotab`` is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); ``co_stacksize`` is the required stack size\n (including local variables); ``co_flags`` is an integer encoding\n a number of flags for the interpreter.\n\n The following flag bits are defined for ``co_flags``: bit\n ``0x04`` is set if the function uses the ``*arguments`` syntax\n to accept an arbitrary number of positional arguments; bit\n ``0x08`` is set if the function uses the ``**keywords`` syntax\n to accept arbitrary keyword arguments; bit ``0x20`` is set if\n the function is a generator.\n\n Future feature declarations (``from __future__ import\n division``) also use bits in ``co_flags`` to indicate whether a\n code object was compiled with a particular feature enabled: bit\n ``0x2000`` is set if the function was compiled with future\n division enabled; bits ``0x10`` and ``0x1000`` were used in\n earlier versions of Python.\n\n Other bits in ``co_flags`` are reserved for internal use.\n\n If a code object represents a function, the first item in\n ``co_consts`` is the documentation string of the function, or\n ``None`` if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: ``f_back`` is to the previous\n stack frame (towards the caller), or ``None`` if this is the\n bottom stack frame; ``f_code`` is the code object being executed\n in this frame; ``f_locals`` is the dictionary used to look up\n local variables; ``f_globals`` is used for global variables;\n ``f_builtins`` is used for built-in (intrinsic) names;\n ``f_restricted`` is a flag indicating whether the function is\n executing in restricted execution mode; ``f_lasti`` gives the\n precise instruction (this is an index into the bytecode string\n of the code object).\n\n Special writable attributes: ``f_trace``, if not ``None``, is a\n function called at the start of each source code line (this is\n used by the debugger); ``f_exc_type``, ``f_exc_value``,\n ``f_exc_traceback`` represent the last exception raised in the\n parent frame provided another exception was ever raised in the\n current frame (in all other cases they are None); ``f_lineno``\n is the current line number of the frame --- writing to this from\n within a trace function jumps to the given line (only for the\n bottom-most frame). A debugger can implement a Jump command\n (aka Set Next Statement) by writing to f_lineno.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n *The try statement*.) It is accessible as ``sys.exc_traceback``,\n and also as the third item of the tuple returned by\n ``sys.exc_info()``. The latter is the preferred interface,\n since it works correctly when the program is using multiple\n threads. When the program contains no suitable handler, the\n stack trace is written (nicely formatted) to the standard error\n stream; if the interpreter is interactive, it is also made\n available to the user as ``sys.last_traceback``.\n\n Special read-only attributes: ``tb_next`` is the next level in\n the stack trace (towards the frame where the exception\n occurred), or ``None`` if there is no next level; ``tb_frame``\n points to the execution frame of the current level;\n ``tb_lineno`` gives the line number where the exception\n occurred; ``tb_lasti`` indicates the precise instruction. The\n line number and last instruction in the traceback may differ\n from the line number of its frame object if the exception\n occurred in a ``try`` statement with no matching except clause\n or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices when *extended slice\n syntax* is used. This is a slice using two colons, or multiple\n slices or ellipses separated by commas, e.g., ``a[i:j:step]``,\n ``a[i:j, k:l]``, or ``a[..., i:j]``. They are also created by\n the built-in ``slice()`` function.\n\n Special read-only attributes: ``start`` is the lower bound;\n ``stop`` is the upper bound; ``step`` is the step value; each is\n ``None`` if omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the extended slice that the slice\n object would describe if applied to a sequence of *length*\n items. It returns a tuple of three integers; respectively\n these are the *start* and *stop* indices and the *step* or\n stride length of the slice. Missing or out-of-bounds indices\n are handled in a manner consistent with regular slices.\n\n New in version 2.3.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n ``staticmethod()`` constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in ``classmethod()`` constructor.\n', - 'typesfunctions': u'\nFunctions\n*********\n\nFunction objects are created by function definitions. The only\noperation on a function object is to call it: ``func(argument-list)``.\n\nThere are really two flavors of function objects: built-in functions\nand user-defined functions. Both support the same operation (to call\nthe function), but the implementation is different, hence the\ndifferent object types.\n\nSee *Function definitions* for more information.\n', - 'typesmapping': u'\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 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 is\n 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": 2, "two": 3}``:\n\n * ``dict(one=2, two=3)``\n\n * ``dict({\'one\': 2, \'two\': 3})``\n\n * ``dict(zip((\'one\', \'two\'), (2, 3)))``\n\n * ``dict([[\'two\', 3], [\'one\', 2]])``\n\n The first example only works for keys that are valid Python\n identifiers; the others work with any valid keys.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for building a dictionary from\n keyword arguments added.\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 New in version 2.5: If a subclass of dict defines a method\n ``__missing__()``, if the key *key* is not present, the\n ``d[key]`` operation calls that method with the key *key* as\n argument. The ``d[key]`` operation then returns or raises\n whatever is returned or raised by the ``__missing__(key)`` call\n if the key is not present. No other operations or methods invoke\n ``__missing__()``. If ``__missing__()`` is not defined,\n ``KeyError`` is raised. ``__missing__()`` must be a method; it\n cannot be an instance variable. For an example, see\n ``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 New in version 2.2.\n\n key not in d\n\n Equivalent to ``not key in d``.\n\n New in version 2.2.\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 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 New in version 2.3.\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 has_key(key)\n\n ``dict.has_key(key)`` is equivalent to ``key in d``, but\n deprecated.\n\n items()\n\n Return a copy of the dictionary\'s list of ``(key, value)``\n pairs.\n\n Note: Keys and values are listed in an arbitrary order which is non-\n random, varies across Python implementations, and depends on\n the dictionary\'s history of insertions and deletions. If\n ``items()``, ``keys()``, ``values()``, ``iteritems()``,\n ``iterkeys()``, and ``itervalues()`` are called with no\n intervening modifications to the dictionary, the lists will\n directly correspond. This allows the creation of ``(value,\n key)`` pairs using ``zip()``: ``pairs = zip(d.values(),\n d.keys())``. The same relationship holds for the\n ``iterkeys()`` and ``itervalues()`` methods: ``pairs =\n zip(d.itervalues(), d.iterkeys())`` provides the same value\n for ``pairs``. Another way to create the same list is ``pairs\n = [(v, k) for (k, v) in d.iteritems()]``.\n\n iteritems()\n\n Return an iterator over the dictionary\'s ``(key, value)`` pairs.\n See the note for ``dict.items()``.\n\n New in version 2.2.\n\n iterkeys()\n\n Return an iterator over the dictionary\'s keys. See the note for\n ``dict.items()``.\n\n New in version 2.2.\n\n itervalues()\n\n Return an iterator over the dictionary\'s values. See the note\n for ``dict.items()``.\n\n New in version 2.2.\n\n keys()\n\n Return a copy of the dictionary\'s list of keys. See the note\n for ``dict.items()``.\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 New in version 2.3.\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 a tuple or other iterable of\n length two). If keyword arguments are specified, the dictionary\n is then is updated with those key/value pairs: ``d.update(red=1,\n blue=2)``.\n\n Changed in version 2.4: Allowed the argument to be an iterable\n of key/value pairs and allowed keyword arguments.\n\n values()\n\n Return a copy of the dictionary\'s list of values. See the note\n for ``dict.items()``.\n', - 'typesmethods': u"\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\nThe implementation adds two special read-only attributes to class\ninstance methods: ``m.im_self`` is the object on which the method\noperates, and ``m.im_func`` is the function implementing the method.\nCalling ``m(arg-1, arg-2, ..., arg-n)`` is completely equivalent to\ncalling ``m.im_func(m.im_self, arg-1, arg-2, ..., arg-n)``.\n\nClass instance methods are either *bound* or *unbound*, referring to\nwhether the method was accessed through an instance or a class,\nrespectively. When a method is unbound, its ``im_self`` attribute\nwill be ``None`` and if called, an explicit ``self`` object must be\npassed as the first argument. In this case, ``self`` must be an\ninstance of the unbound method's class (or a subclass of that class),\notherwise a ``TypeError`` is raised.\n\nLike function objects, methods objects support getting arbitrary\nattributes. However, since method attributes are actually stored on\nthe underlying function object (``meth.im_func``), setting method\nattributes on either bound or unbound methods is disallowed.\nAttempting to set a method attribute results in a ``TypeError`` being\nraised. In order to set a method attribute, you need to explicitly\nset it on the underlying function object:\n\n class C:\n def method(self):\n pass\n\n c = C()\n c.method.im_func.whoami = 'my name is c'\n\nSee *The standard type hierarchy* for more information.\n", - 'typesmodules': u"\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': u'\nSequence Types --- ``str``, ``unicode``, ``list``, ``tuple``, ``buffer``, ``xrange``\n************************************************************************************\n\nThere are six sequence types: strings, Unicode strings, lists, tuples,\nbuffers, and xrange objects. (For other containers see the built in\n``dict``, ``list``, ``set``, and ``tuple`` classes, and the\n``collections`` module.)\n\nString literals are written in single or double quotes: ``\'xyzzy\'``,\n``"frobozz"``. See *String literals* for more about string literals.\nUnicode strings are much like strings, but are specified in the syntax\nusing a preceding ``\'u\'`` character: ``u\'abc\'``, ``u"def"``. In\naddition to the functionality described here, there are also string-\nspecific methods described in the *String Methods* section. Lists are\nconstructed with square brackets, separating items with commas: ``[a,\nb, c]``. Tuples are constructed by the comma operator (not within\nsquare brackets), with or without enclosing parentheses, but an empty\ntuple must have the enclosing parentheses, such as ``a, b, c`` or\n``()``. A single item tuple must have a trailing comma, such as\n``(d,)``.\n\nBuffer objects are not directly supported by Python syntax, but can be\ncreated by calling the builtin function ``buffer()``. They don\'t\nsupport concatenation or repetition.\n\nObjects of type xrange are similar to buffers in that there is no\nspecific syntax to create them, but they are created using the\n``xrange()`` function. They don\'t support slicing, concatenation or\nrepetition, and using ``in``, ``not in``, ``min()`` or ``max()`` on\nthem 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 compare\nequal and the two sequences must be of the same type and have the same\nlength. (For full details see *Comparisons* in the language\nreference.)\n\nNotes:\n\n1. When *s* is a string or Unicode string object the ``in`` and ``not\n in`` operations act like a substring test. In Python versions\n before 2.3, *x* had to be a string of length 1. In Python 2.3 and\n beyond, *x* may be a string of any length.\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. If *s* and *t* are both strings, some Python implementations such\n as CPython can usually perform an in-place optimization for\n assignments of the form ``s=s+t`` or ``s+=t``. When applicable,\n this optimization makes quadratic run-time much less likely. This\n optimization is both version and implementation dependent. For\n performance sensitive code, it is preferable to use the\n ``str.join()`` method which assures consistent linear concatenation\n performance across versions and implementations.\n\n Changed in version 2.4: Formerly, string concatenation never\n occurred in-place.\n\n\nString Methods\n==============\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Note that none of these methods take keyword\narguments.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbuffer, xrange* section. To output formatted strings use template\nstrings or the ``%`` operator described in the *String Formatting\nOperations* 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 only its first character\n capitalized.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of occurrences of substring *sub* in the range\n [*start*, *end*]. Optional arguments *start* and *end* are\n interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes 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\n Changed in version 2.5: Accept tuples as *suffix*.\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 range [*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(format_string, *args, **kwargs)\n\n Perform a string formatting operation. The *format_string*\n argument can contain literal text or replacement fields delimited\n by braces ``{}``. Each replacement field contains either the\n numeric index of a positional argument, or the name of a keyword\n argument. Returns a copy of *format_string* where each replacement\n field is replaced with the string value of the corresponding\n 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\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\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\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(seq)\n\n Return a string which is the concatenation of the strings in the\n sequence *seq*. The separator between elements is the string\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n New in version 2.5.\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]. Optional\n arguments *start* and *end* are interpreted as in slice notation.\n 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\n Changed in version 2.4: Support for the *fillchar* argument.\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\n New in version 2.5.\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\n New in version 2.4.\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\n Changed in version 2.2.2: Support for the *chars* argument.\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\n Changed in version 2.5: Accept tuples as *prefix*.\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\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string: words start with\n uppercase characters, all remaining cased characters are lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\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 New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n\n\nString Formatting Operations\n============================\n\nString and Unicode objects have one unique built-in operation: the\n``%`` operator (modulo). This is also known as the string\n*formatting* or *interpolation* operator. Given ``format % values``\n(where *format* is a string or Unicode object), ``%`` conversion\nspecifications in *format* are replaced with zero or more elements of\n*values*. The effect is similar to the using ``sprintf`` in the C\nlanguage. If *format* is a Unicode object, or if any of the objects\nbeing converted using the ``%s`` conversion are Unicode objects, the\nresult will also be a Unicode object.\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 %(#)03d quote types.\' % \\\n... {\'language\': "Python", "#": 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\'`` | Obselete 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()``). | (6) |\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 ``%r`` conversion was added in Python 2.0.\n\n The precision determines the maximal number of characters used.\n\n6. If the object or format provided is a ``unicode`` string, the\n resulting string will also be ``unicode``.\n\n The precision determines the maximal number of characters used.\n\n7. 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\nFor safety reasons, floating point precisions are clipped to 50;\n``%f`` conversions for numbers whose absolute value is over 1e25 are\nreplaced by ``%g`` conversions. [5] All other errors raise\nexceptions.\n\nAdditional string operations are defined in standard modules\n``string`` and ``re``.\n\n\nXRange Type\n===========\n\nThe ``xrange`` type is an immutable sequence which is commonly used\nfor looping. The advantage of the ``xrange`` type is that an\n``xrange`` object will always take the same amount of memory, no\nmatter the size of the range it represents. There are no consistent\nperformance advantages.\n\nXRange objects have very little behavior: they only support indexing,\niteration, and the ``len()`` function.\n\n\nMutable Sequence Types\n======================\n\nList objects support additional operations that allow in-place\nmodification of the object. Other mutable sequence types (when added\nto the language) should also support these operations. Strings and\ntuples are immutable sequence types: such objects cannot be modified\nonce created. The following operations are defined on mutable sequence\ntypes (where *x* is an arbitrary object):\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)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\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 | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. 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 list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn\'t have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don\'t return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\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``.\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 In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. While a list is being sorted, the effect of attempting to mutate,\n or even inspect, the list is undefined. The C implementation of\n Python 2.3 and newer makes the list appear empty for the duration,\n and raises ``ValueError`` if it can detect that the list has been\n mutated during a sort.\n', - 'typesseq-mutable': u"\nMutable Sequence Types\n**********************\n\nList objects support additional operations that allow in-place\nmodification of the object. Other mutable sequence types (when added\nto the language) should also support these operations. Strings and\ntuples are immutable sequence types: such objects cannot be modified\nonce created. The following operations are defined on mutable sequence\ntypes (where *x* is an arbitrary object):\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)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\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 | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. 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 list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn't have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don't return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\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``.\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 In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. While a list is being sorted, the effect of attempting to mutate,\n or even inspect, the list is undefined. The C implementation of\n Python 2.3 and newer makes the list appear empty for the duration,\n and raises ``ValueError`` if it can detect that the list has been\n mutated during a sort.\n", - 'unary': u'\nUnary arithmetic 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\nplain or long integer argument. The bitwise inversion of ``x`` is\ndefined as ``-(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': u'\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', - 'with': u'\nThe ``with`` statement\n**********************\n\nNew in version 2.5.\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" expression ["as" target] ":" suite\n\nThe execution of the ``with`` statement proceeds as follows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__enter__()`` method is invoked.\n\n3. 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 5 below.\n\n4. The suite is executed.\n\n5. 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\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n', - 'yield': u'\nThe ``yield`` statement\n***********************\n\n yield_stmt ::= yield_expression\n\nThe ``yield`` statement is only used when defining a generator\nfunction, and is only used in the body of the generator function.\nUsing a ``yield`` statement in a function definition is sufficient to\ncause that definition to create a generator function instead of a\nnormal function.\n\nWhen a generator function is called, it returns an iterator known as a\ngenerator iterator, or more commonly, a generator. The body of the\ngenerator function is executed by calling the generator\'s ``next()``\nmethod repeatedly until it raises an exception.\n\nWhen a ``yield`` statement is executed, the state of the generator is\nfrozen and the value of **expression_list** is returned to\n``next()``\'s caller. By "frozen" we mean that all local state is\nretained, including the current bindings of local variables, the\ninstruction pointer, and the internal evaluation stack: enough\ninformation is saved so that the next time ``next()`` is invoked, the\nfunction can proceed exactly as if the ``yield`` statement were just\nanother external call.\n\nAs of Python version 2.5, the ``yield`` statement is now allowed in\nthe ``try`` clause of a ``try`` ... ``finally`` construct. If the\ngenerator is not resumed before it is finalized (by reaching a zero\nreference count or by being garbage collected), the generator-\niterator\'s ``close()`` method will be called, allowing any pending\n``finally`` clauses to execute.\n\nNote: In Python 2.2, the ``yield`` statement was only allowed when the\n ``generators`` feature has been enabled. This ``__future__`` import\n statement was used to enable the feature:\n\n from __future__ import generators\n\nSee also:\n\n **PEP 0255** - Simple Generators\n The proposal for adding generators and the ``yield`` statement\n to Python.\n\n **PEP 0342** - Coroutines via Enhanced Generators\n The proposal that, among other generator enhancements, proposed\n allowing ``yield`` to appear inside a ``try`` ... ``finally``\n block.\n'} +# Autogenerated by Sphinx on Mon Apr 27 18:34:24 2009 +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 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* 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(In the current implementation, the syntax for targets is taken to be\nthe same as for expressions, and invalid syntax is rejected during the\ncode generation phase, causing less 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 initial value is\nretrieved with a ``getattr()`` and the result is assigned with a\n``setattr()``. Notice that the two methods do not necessarily refer\nto the same variable. When ``getattr()`` refers to a class variable,\n``setattr()`` still writes to an instance variable. For example:\n\n class A:\n x = 3 # class variable\n a = A()\n a.x += 1 # writes a.x as 4 leaving A.x as 3\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', + 'atom-literals': "\nLiterals\n********\n\nPython supports string and bytes literals and various numeric\nliterals:\n\n literal ::= stringliteral | bytesliteral\n | integer | floatnumber | imagnumber\n\nEvaluation of a literal yields an object of the given type (string,\nbytes, integer, floating point number, complex number) with the given\nvalue. The value may be approximated in the case of floating point\nand imaginary (complex) literals. See section *Literals* for details.\n\nWith the exception of bytes literals, these all correspond to\nimmutable data types, and hence the object's identity is less\nimportant than its value. Multiple evaluations of literals with the\nsame value (either the same occurrence in the program text or a\ndifferent occurrence) may obtain the same object or a different object\nwith the same value.\n", + 'attribute-access': '\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 builtin 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. Normally, data\ndescriptors define both ``__get__()`` and ``__set__()``, while non-\ndata descriptors have just the ``__get__()`` method. Data descriptors\nalways override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances. [2]\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* 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* 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__*.\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', + 'attribute-references': '\nAttribute references\n********************\n\nAn attribute reference is a primary followed by a period and a name:\n\n attributeref ::= primary "." identifier\n\nThe primary must evaluate to an object of a type that supports\nattribute references, which most objects do. This object is then\nasked to produce the attribute whose name is the identifier (which can\nbe customized by overriding the ``__getattr__()`` method). If this\nattribute is not available, the exception ``AttributeError`` is\nraised. Otherwise, the type and value of the object produced is\ndetermined by the object. Multiple evaluations of the same attribute\nreference may yield different objects.\n', + 'augassign': '\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 initial value is\nretrieved with a ``getattr()`` and the result is assigned with a\n``setattr()``. Notice that the two methods do not necessarily refer\nto the same variable. When ``getattr()`` refers to a class variable,\n``setattr()`` still writes to an instance variable. For example:\n\n class A:\n x = 3 # class variable\n a = A()\n a.x += 1 # writes a.x as 4 leaving A.x as 3\n', + 'binary': '\nBinary arithmetic operations\n****************************\n\nThe binary arithmetic operations have the conventional priority\nlevels. Note that some of these operations also apply to certain non-\nnumeric types. Apart from the power operator, there are only two\nlevels, one for multiplicative operators and one for additive\noperators:\n\n m_expr ::= u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr\n | m_expr "%" u_expr\n a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr\n\nThe ``*`` (multiplication) operator yields the product of its\narguments. The arguments must either both be numbers, or one argument\nmust be an integer and the other must be a sequence. In the former\ncase, the numbers are converted to a common type and then multiplied\ntogether. In the latter case, sequence repetition is performed; a\nnegative repetition factor yields an empty sequence.\n\nThe ``/`` (division) and ``//`` (floor division) operators yield the\nquotient of their arguments. The numeric arguments are first\nconverted to a common type. Integer division yields a float, while\nfloor division of integers results in an integer; the result is that\nof mathematical division with the \'floor\' function applied to the\nresult. Division by zero raises the ``ZeroDivisionError`` exception.\n\nThe ``%`` (modulo) operator yields the remainder from the division of\nthe first argument by the second. The numeric arguments are first\nconverted to a common type. A zero right argument raises the\n``ZeroDivisionError`` exception. The arguments may be floating point\nnumbers, e.g., ``3.14%0.7`` equals ``0.34`` (since ``3.14`` equals\n``4*0.7 + 0.34``.) The modulo operator always yields a result with\nthe same sign as its second operand (or zero); the absolute value of\nthe result is strictly smaller than the absolute value of the second\noperand [1].\n\nThe floor division and modulo operators are connected by the following\nidentity: ``x == (x//y)*y + (x%y)``. Floor division and modulo are\nalso connected with the built-in function ``divmod()``: ``divmod(x, y)\n== (x//y, x%y)``. [2].\n\nIn addition to performing the modulo operation on numbers, the ``%``\noperator is also overloaded by string objects to perform old-style\nstring formatting (also known as interpolation). The syntax for\nstring formatting is described in the Python Library Reference,\nsection *Old String Formatting Operations*.\n\nThe floor division operator, the modulo operator, and the ``divmod()``\nfunction are not defined for complex numbers. Instead, convert to a\nfloating point number using the ``abs()`` function if appropriate.\n\nThe ``+`` (addition) operator yields the sum of its arguments. The\narguments must either both be numbers or both sequences of the same\ntype. In the former case, the numbers are converted to a common type\nand then added together. In the latter case, the sequences are\nconcatenated.\n\nThe ``-`` (subtraction) operator yields the difference of its\narguments. The numeric arguments are first converted to a common\ntype.\n', + 'bitwise': '\nBinary bitwise operations\n*************************\n\nEach of the three bitwise operations has a different priority level:\n\n and_expr ::= shift_expr | and_expr "&" shift_expr\n xor_expr ::= and_expr | xor_expr "^" and_expr\n or_expr ::= xor_expr | or_expr "|" xor_expr\n\nThe ``&`` operator yields the bitwise AND of its arguments, which must\nbe integers.\n\nThe ``^`` operator yields the bitwise XOR (exclusive OR) of its\narguments, which must be integers.\n\nThe ``|`` operator yields the bitwise (inclusive) OR of its arguments,\nwhich must be integers.\n', + 'bltin-code-objects': '\nCode Objects\n************\n\nCode objects are used by the implementation to represent "pseudo-\ncompiled" executable Python code such as a function body. They differ\nfrom function objects because they don\'t contain a reference to their\nglobal execution environment. Code objects are returned by the built-\nin ``compile()`` function and can be extracted from function objects\nthrough their ``__code__`` attribute. See also the ``code`` module.\n\nA code object can be executed or evaluated by passing it (instead of a\nsource string) to the ``exec()`` or ``eval()`` built-in functions.\n\nSee *The standard type hierarchy* for more information.\n', + 'bltin-ellipsis-object': '\nThe Ellipsis Object\n*******************\n\nThis object is commonly used by slicing (see *Slicings*). It supports\nno special operations. There is exactly one ellipsis object, named\n``Ellipsis`` (a built-in name).\n\nIt is written as ``Ellipsis`` or ``...``.\n', + 'bltin-file-objects': '\nFile Objects\n************\n\nFile objects are implemented using C\'s ``stdio`` package and can be\ncreated with the built-in ``open()`` function. File objects are also\nreturned by some other built-in functions and methods, such as\n``os.popen()`` and ``os.fdopen()`` and the ``makefile()`` method of\nsocket objects. Temporary files can be created using the ``tempfile``\nmodule, and high-level file operations such as copying, moving, and\ndeleting files and directories can be achieved with the ``shutil``\nmodule.\n\nWhen a file operation fails for an I/O-related reason, the exception\n``IOError`` is raised. This includes situations where the operation\nis not defined for some reason, like ``seek()`` on a tty device or\nwriting a file opened for reading.\n\nFiles have the following methods:\n\nfile.close()\n\n Close the file. A closed file cannot be read or written any more.\n Any operation which requires that the file be open will raise a\n ``ValueError`` after the file has been closed. Calling ``close()``\n more than once is allowed.\n\n You can avoid having to call this method explicitly if you use the\n ``with`` statement. For example, the following code will\n automatically close *f* when the ``with`` block is exited:\n\n from __future__ import with_statement # This isn\'t required in Python 2.6\n\n with open("hello.txt") as f:\n for line in f:\n print(line)\n\n In older versions of Python, you would have needed to do this to\n get the same effect:\n\n f = open("hello.txt")\n try:\n for line in f:\n print(line)\n finally:\n f.close()\n\n Note: Not all "file-like" types in Python support use as a context\n manager for the ``with`` statement. If your code is intended to\n work with any file-like object, you can use the function\n ``contextlib.closing()`` instead of using the object directly.\n\nfile.flush()\n\n Flush the internal buffer, like ``stdio``\'s ``fflush``. This may\n be a no-op on some file-like objects.\n\n Note: ``flush()`` does not necessarily write the file\'s data to disk.\n Use ``flush()`` followed by ``os.fsync()`` to ensure this\n behavior.\n\nfile.fileno()\n\n Return the integer "file descriptor" that is used by the underlying\n implementation to request I/O operations from the operating system.\n This can be useful for other, lower level interfaces that use file\n descriptors, such as the ``fcntl`` module or ``os.read()`` and\n friends.\n\n Note: File-like objects which do not have a real file descriptor should\n *not* provide this method!\n\nfile.isatty()\n\n Return ``True`` if the file is connected to a tty(-like) device,\n else ``False``.\n\n Note: If a file-like object is not associated with a real file, this\n method should *not* be implemented.\n\nfile.__next__()\n\n A file object is its own iterator, for example ``iter(f)`` returns\n *f* (unless *f* is closed). When a file is used as an iterator,\n typically in a ``for`` loop (for example, ``for line in f:\n print(line)``), the ``__next__()`` method is called repeatedly.\n This method returns the next input line, or raises\n ``StopIteration`` when EOF is hit when the file is open for reading\n (behavior is undefined when the file is open for writing). In\n order to make a ``for`` loop the most efficient way of looping over\n the lines of a file (a very common operation), the ``__next__()``\n method uses a hidden read-ahead buffer. As a consequence of using\n a read-ahead buffer, combining ``__next__()`` with other file\n methods (like ``readline()``) does not work right. However, using\n ``seek()`` to reposition the file to an absolute position will\n flush the read-ahead buffer.\n\nfile.read([size])\n\n Read at most *size* bytes from the file (less if the read hits EOF\n before obtaining *size* bytes). If the *size* argument is negative\n or omitted, read all data until EOF is reached. The bytes are\n returned as a string object. An empty string is returned when EOF\n is encountered immediately. (For certain files, like ttys, it\n makes sense to continue reading after an EOF is hit.) Note that\n this method may call the underlying C function ``fread`` more than\n once in an effort to acquire as close to *size* bytes as possible.\n Also note that when in non-blocking mode, less data than was\n requested may be returned, even if no *size* parameter was given.\n\nfile.readline([size])\n\n Read one entire line from the file. A trailing newline character\n is kept in the string (but may be absent when a file ends with an\n incomplete line). [6] If the *size* argument is present and non-\n negative, it is a maximum byte count (including the trailing\n newline) and an incomplete line may be returned. An empty string is\n returned *only* when EOF is encountered immediately.\n\n Note: Unlike ``stdio``\'s ``fgets``, the returned string contains null\n characters (``\'\\0\'``) if they occurred in the input.\n\nfile.readlines([sizehint])\n\n Read until EOF using ``readline()`` and return a list containing\n the lines thus read. If the optional *sizehint* argument is\n present, instead of reading up to EOF, whole lines totalling\n approximately *sizehint* bytes (possibly after rounding up to an\n internal buffer size) are read. Objects implementing a file-like\n interface may choose to ignore *sizehint* if it cannot be\n implemented, or cannot be implemented efficiently.\n\nfile.seek(offset[, whence])\n\n Set the file\'s current position, like ``stdio``\'s ``fseek``. The\n *whence* argument is optional and defaults to ``os.SEEK_SET`` or\n ``0`` (absolute file positioning); other values are ``os.SEEK_CUR``\n or ``1`` (seek relative to the current position) and\n ``os.SEEK_END`` or ``2`` (seek relative to the file\'s end). There\n is no return value.\n\n For example, ``f.seek(2, os.SEEK_CUR)`` advances the position by\n two and ``f.seek(-3, os.SEEK_END)`` sets the position to the third\n to last.\n\n Note that if the file is opened for appending (mode ``\'a\'`` or\n ``\'a+\'``), any ``seek()`` operations will be undone at the next\n write. If the file is only opened for writing in append mode (mode\n ``\'a\'``), this method is essentially a no-op, but it remains useful\n for files opened in append mode with reading enabled (mode\n ``\'a+\'``). If the file is opened in text mode (without ``\'b\'``),\n only offsets returned by ``tell()`` are legal. Use of other\n offsets causes undefined behavior.\n\n Note that not all file objects are seekable.\n\nfile.tell()\n\n Return the file\'s current position, like ``stdio``\'s ``ftell``.\n\n Note: On Windows, ``tell()`` can return illegal values (after an\n ``fgets``) when reading files with Unix-style line-endings. Use\n binary mode (``\'rb\'``) to circumvent this problem.\n\nfile.truncate([size])\n\n Truncate the file\'s size. If the optional *size* argument is\n present, the file is truncated to (at most) that size. The size\n defaults to the current position. The current file position is not\n changed. Note that if a specified size exceeds the file\'s current\n size, the result is platform-dependent: possibilities include that\n the file may remain unchanged, increase to the specified size as if\n zero-filled, or increase to the specified size with undefined new\n content. Availability: Windows, many Unix variants.\n\nfile.write(str)\n\n Write a string to the file. Due to buffering, the string may not\n actually show up in the file until the ``flush()`` or ``close()``\n method is called.\n\n The meaning of the return value is not defined for every file-like\n object. Some (mostly low-level) file-like objects may return the\n number of bytes actually written, others return ``None``.\n\nfile.writelines(sequence)\n\n Write a sequence of strings to the file. The sequence can be any\n iterable object producing strings, typically a list of strings.\n There is no return value. (The name is intended to match\n ``readlines()``; ``writelines()`` does not add line separators.)\n\nFiles support the iterator protocol. Each iteration returns the same\nresult as ``file.readline()``, and iteration ends when the\n``readline()`` method returns an empty string.\n\nFile objects also offer a number of other interesting attributes.\nThese are not required for file-like objects, but should be\nimplemented if they make sense for the particular object.\n\nfile.closed\n\n bool indicating the current state of the file object. This is a\n read-only attribute; the ``close()`` method changes the value. It\n may not be available on all file-like objects.\n\nfile.encoding\n\n The encoding that this file uses. When strings are written to a\n file, they will be converted to byte strings using this encoding.\n In addition, when the file is connected to a terminal, the\n attribute gives the encoding that the terminal is likely to use\n (that information might be incorrect if the user has misconfigured\n the terminal). The attribute is read-only and may not be present\n on all file-like objects. It may also be ``None``, in which case\n the file uses the system default encoding for converting strings.\n\nfile.errors\n\n The Unicode error handler used along with the encoding.\n\nfile.mode\n\n The I/O mode for the file. If the file was created using the\n ``open()`` built-in function, this will be the value of the *mode*\n parameter. This is a read-only attribute and may not be present on\n all file-like objects.\n\nfile.name\n\n If the file object was created using ``open()``, the name of the\n file. Otherwise, some string that indicates the source of the file\n object, of the form ``<...>``. This is a read-only attribute and\n may not be present on all file-like objects.\n\nfile.newlines\n\n If Python was built with the *--with-universal-newlines* option to\n **configure** (the default) this read-only attribute exists, and\n for files opened in universal newline read mode it keeps track of\n the types of newlines encountered while reading the file. The\n values it can take are ``\'\\r\'``, ``\'\\n\'``, ``\'\\r\\n\'``, ``None``\n (unknown, no newlines read yet) or a tuple containing all the\n newline types seen, to indicate that multiple newline conventions\n were encountered. For files not opened in universal newline read\n mode the value of this attribute will be ``None``.\n', + 'bltin-null-object': "\nThe Null Object\n***************\n\nThis object is returned by functions that don't explicitly return a\nvalue. It supports no special operations. There is exactly one null\nobject, named ``None`` (a built-in name).\n\nIt is written as ``None``.\n", + 'bltin-type-objects': "\nType Objects\n************\n\nType objects represent the various object types. An object's type is\naccessed by the built-in function ``type()``. There are no special\noperations on types. The standard module ``types`` defines names for\nall standard built-in types.\n\nTypes are written like this: ````.\n", + 'booleans': '\nBoolean operations\n******************\n\nBoolean operations have the lowest priority of all Python operations:\n\n expression ::= conditional_expression | lambda_form\n expression_nocond ::= or_test | lambda_form_nocond\n conditional_expression ::= or_test ["if" or_test "else" expression]\n or_test ::= and_test | or_test "or" and_test\n and_test ::= not_test | and_test "and" not_test\n not_test ::= comparison | "not" not_test\n\nIn the context of Boolean operations, and also when expressions are\nused by control flow statements, the following values are interpreted\nas false: ``False``, ``None``, numeric zero of all types, and empty\nstrings and containers (including strings, tuples, lists,\ndictionaries, sets and frozensets). All other values are interpreted\nas true. User-defined objects can customize their truth value by\nproviding a ``__bool__()`` method.\n\nThe operator ``not`` yields ``True`` if its argument is false,\n``False`` otherwise.\n\nThe expression ``x if C else y`` first evaluates *C* (*not* *x*); if\n*C* is true, *x* is evaluated and its value is returned; otherwise,\n*y* is evaluated and its value is returned.\n\nThe expression ``x and y`` first evaluates *x*; if *x* is false, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\nThe expression ``x or y`` first evaluates *x*; if *x* is true, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\n(Note that neither ``and`` nor ``or`` restrict the value and type they\nreturn to ``False`` and ``True``, but rather return the last evaluated\nargument. This is sometimes useful, e.g., if ``s`` is a string that\nshould be replaced by a default value if it is empty, the expression\n``s or \'foo\'`` yields the desired value. Because ``not`` has to\ninvent a value anyway, it does not bother to return a value of the\nsame type as its argument, so e.g., ``not \'foo\'`` yields ``False``,\nnot ``\'\'``.)\n', + '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\nNote: An implementation may provide builtin functions whose positional\n parameters do not have names, even if they are \'named\' for the\n purpose of documentation, and which therefore cannot be supplied by\n keyword. In CPython, this is the case for functions implemented in\n C that use ``PyArg_ParseTuple`` to parse 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 ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\nClasses can also be decorated; as with 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\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by instances. Instance variables can\nbe set in a method with ``self.name = value``. Both class and\ninstance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. Descriptors can be used to create\ninstance variables with different implementation details.\n\nSee also:\n\n **PEP 3129** - Class Decorators\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\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-builtin\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 their sorted\n ``(key, value)`` lists compare equal. [4] Outcomes other than\n equality are resolved consistently, but are not otherwise defined.\n [5]\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 builtin 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 val\ne in y)``.\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__()`` and do\ndefine ``__getitem__()``, ``x in y`` is true if and only if there is a\nnon-negative 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. [6]\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., ``range(3)`` returns the list ``[0, 1, 2]``.\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 N = None\n del N\n\nThat means that you have to assign the exception to a different name\nif you want to be able to refer to it after the except clause. The\nreason for this is that with the traceback attached to them,\nexceptions will form a reference cycle with the stack frame, keeping\nall locals in that frame alive until the next garbage collection\noccurs.\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" expression ["as" target] ":" suite\n\nThe execution of the ``with`` statement proceeds as follows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__enter__()`` method is invoked.\n\n3. 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 5 below.\n\n4. The suite is executed.\n\n5. 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\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 ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\nClasses can also be decorated; as with 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\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by instances. Instance variables can\nbe set in a method with ``self.name = value``. Both class and\ninstance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. Descriptors can be used to create\ninstance variables with different implementation details.\n\nSee also:\n\n **PEP 3129** - Class Decorators\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\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 the Total Ordering recipe in the ASPN cookbook.\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``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined, and the object is\n considered true if its result is nonzero. If a class defines\n neither ``__len__()`` nor ``__bool__()``, all its instances are\n 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``\n(undocumented) and ``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 python -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\nTypical 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[, locals]])\n\n Execute the *statement* (given as a string) under debugger control.\n The debugger prompt appears before any code is executed; you can\n set breakpoints and type ``continue``, or you can step through the\n statement using ``step`` or ``next`` (all these commands are\n explained below). The optional *globals* and *locals* arguments\n specify the environment in which the code is executed; by default\n the dictionary of the module ``__main__`` is used. (See the\n explanation of the built-in ``exec()`` or ``eval()`` functions.)\n\npdb.runeval(expression[, globals[, locals]])\n\n Evaluate the *expression* (given as a string) under debugger\n control. When ``runeval()`` returns, it returns the value of the\n expression. Otherwise this function is similar to ``run()``.\n\npdb.runcall(function[, argument, ...])\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])\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', + '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\nIt is illegal to delete a name from the local namespace if it occurs\nas a free variable in a nested block.\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', + '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', + 'else': '\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', + 'exceptions': '\nExceptions\n**********\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nNote: Exception messages are not part of the Python API. Their contents\n may change from one version of Python to the next without warning\n and should not be relied on by code which will run under multiple\n versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', + 'execmodel': '\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The string argument passed\nto the built-in functions ``eval()`` and ``exec()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes comprehensions and generator\nexpressions since they are implemented using a function scope. This\nmeans that the following will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block,\nunless declared as ``nonlocal``. If a name is bound at the module\nlevel, it is a global variable. (The variables of the module code\nblock are local and global.) If a variable is used in a code block\nbut not defined there, it is a *free variable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, or\nafter ``as`` in a ``with`` statement or :keyword.`except` clause. The\n``import`` statement of the form ``from ... import *`` binds all names\ndefined in the imported module, except those beginning with an\nunderscore. This form may only be used at the module level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the ``global`` statement occurs within a block, all uses of the\nname specified in the statement refer to the binding of that name in\nthe top-level namespace. Names are resolved in the top-level\nnamespace by searching the global namespace, i.e. the namespace of the\nmodule containing the code block, and the builtin namespace, the\nnamespace of the module ``builtins``. The global namespace is\nsearched first. If the name is not found there, the builtin namespace\nis searched. The global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``builtins``; when in any other module, ``__builtins__`` is an alias\nfor the dictionary of the ``builtins`` module itself.\n``__builtins__`` can be set to a user-created dictionary to create a\nweak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``builtins`` module and\n modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\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\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nNote: Exception messages are not part of the Python API. Their contents\n may change from one version of Python to the next without warning\n and should not be relied on by code which will run under multiple\n versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', + '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., ``range(3)`` returns the list ``[0, 1, 2]``.\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\n conversion ::= "r" | "s" | "a"\n format_spec ::= \n\nIn less formal terms, the replacement field starts with a *field_name*\nthat specifies the object whose value is to be formatted and inserted\ninto the output instead of the replacement field. The *field_name* is\noptionally followed by a *conversion* field, which is preceded by an\nexclamation point ``\'!\'``, and a *format_spec*, which is preceded by a\ncolon ``\':\'``. These specify a non-default format for the replacement\nvalue.\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\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\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 it\'s\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\nFor example, suppose you wanted to have a replacement field whose\nfield width is determined by another variable:\n\n "A man with two {0:{1}}".format("noses", 10)\n\nThis would first evaluate the inner replacement field, making the\nformat string effectively:\n\n "A man with two {0:10}"\n\nThen the outer replacement field would be evaluated, producing:\n\n "noses "\n\nWhich is substituted into the string, yielding:\n\n "A man with two noses "\n\n(The extra space is because we specified a field width of 10, and\nbecause left alignment is the default for strings.)\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\nbuiltin ``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.\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" | "x" | "X" | "%"\n\nThe *fill* character can be any character other than \'}\' (which\nsignifies the end of the field). The presence of a fill character is\nsignaled by the *next* character, which must be one of the alignment\noptions. If the second character of *format_spec* is not a valid\nalignment option, then it is assumed that both the fill character and\nthe alignment option are absent.\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\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 ignored for integer values.\n\nFinally, the *type* determines how the data should be presented.\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\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\'``. |\n +-----------+------------------------------------------------------------+\n | ``\'g\'`` | General format. This prints the number as a fixed-point |\n | | number, unless the number is too large, in which case it |\n | | switches to ``\'e\'`` exponent notation. Infinity and NaN |\n | | values are formatted as ``inf``, ``-inf`` and ``nan``, |\n | | respectively. |\n +-----------+------------------------------------------------------------+\n | ``\'G\'`` | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n | | if the number gets to 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 | The same as ``\'g\'``. |\n +-----------+------------------------------------------------------------+\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(The current implementation does not enforce the latter two\nrestrictions, but programs should not abuse this freedom, as future\nimplementations may enforce them or silently change the meaning of the\nprogram.)\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 builtin ``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);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\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);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\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.\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 for 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\nimprt mod`` from within ``pkg.subpkg1`` you will import\n``pkg.subpkg2.mod``. The specification for relative imports is\ncontained within **PEP 328**.\n\nThe built-in function ``__import__()`` is provided to support\napplications that determine which modules need to be loaded\ndynamically; refer to *Built-in Functions* for additional information.\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 builtin 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', + '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-builtin\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 their sorted\n ``(key, value)`` lists compare equal. [4] Outcomes other than\n equality are resolved consistently, but are not otherwise defined.\n [5]\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 builtin 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 val\ne in y)``.\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__()`` and do\ndefine ``__getitem__()``, ``x in y`` is true if and only if there is a\nnon-negative 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. [6]\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', + 'lists': '\nList displays\n*************\n\nA list display is a possibly empty series of expressions enclosed in\nsquare brackets:\n\n list_display ::= "[" [expression_list | comprehension] "]"\n\nA list display yields a new list object, the contents being specified\nby either a list of expressions or a comprehension. When a comma-\nseparated list of expressions is supplied, its elements are evaluated\nfrom left to right and placed into the list object in that order.\nWhen a comprehension is supplied, the list is constructed from the\nelements resulting from the comprehension.\n', + 'naming': "\nNaming and binding\n******************\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the '**-c**' option) is a code block. The string argument passed\nto the built-in functions ``eval()`` and ``exec()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block's execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes comprehensions and generator\nexpressions since they are implemented using a function scope. This\nmeans that the following will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block's *environment*.\n\nIf a name is bound in a block, it is a local variable of that block,\nunless declared as ``nonlocal``. If a name is bound at the module\nlevel, it is a global variable. (The variables of the module code\nblock are local and global.) If a variable is used in a code block\nbut not defined there, it is a *free variable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, or\nafter ``as`` in a ``with`` statement or :keyword.`except` clause. The\n``import`` statement of the form ``from ... import *`` binds all names\ndefined in the imported module, except those beginning with an\nunderscore. This form may only be used at the module level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the ``global`` statement occurs within a block, all uses of the\nname specified in the statement refer to the binding of that name in\nthe top-level namespace. Names are resolved in the top-level\nnamespace by searching the global namespace, i.e. the namespace of the\nmodule containing the code block, and the builtin namespace, the\nnamespace of the module ``builtins``. The global namespace is\nsearched first. If the name is not found there, the builtin namespace\nis searched. The global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module's dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``builtins``; when in any other module, ``__builtins__`` is an alias\nfor the dictionary of the ``builtins`` module itself.\n``__builtins__`` can be set to a user-created dictionary to create a\nweak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``builtins`` module and\n modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\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", + '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. [3] 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. (Implementation note: 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| ``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+-------------------------------------------------+---------------------------------------+\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+-------------------------------------------------+---------------------------------------+\n| ``+x``, ``-x``, ``~x`` | Positive, negative, bitwise NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``**`` | Exponentiation [7] |\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] The implementation computes this efficiently, without constructing\n lists or sorting.\n\n[5] Earlier versions of Python used lexicographic comparison of the\n sorted (key, value) lists, but this was very expensive for the\n common case of comparing for equality. An even earlier version of\n Python compared dictionaries by identity only, but this caused\n surprises because people expected to be able to test a dictionary\n for emptiness by comparing it to ``{}``.\n\n[6] 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[7] 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', + 'return': '\nThe ``return`` statement\n************************\n\n return_stmt ::= "return" [expression_list]\n\n``return`` may only occur syntactically nested in a function\ndefinition, not within a nested class definition.\n\nIf an expression list is present, it is evaluated, else ``None`` is\nsubstituted.\n\n``return`` leaves the current function call with the expression list\n(or ``None``) as return value.\n\nWhen ``return`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nleaving the function.\n\nIn a generator function, the ``return`` statement is not allowed to\ninclude an **expression_list**. In that context, a bare ``return``\nindicates that the generator is done and will cause ``StopIteration``\nto be raised.\n', + 'sequence-types': "\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()`` builtin 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()`` builtin will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects should\n normally only provide ``__reversed__()`` if they do not support the\n sequence protocol and an efficient implementation of reverse\n iteration is possible.\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", + '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', + '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. If there are no base\n classes, this will be an empty tuple.\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\n[5] These numbers are fairly arbitrary. They are intended to avoid\n printing endless strings of meaningless digits without hampering\n correct use and without having to know the exact precision of\n floating point values on a particular machine.\n\n[6] The advantage of leaving the newline on is that returning an empty\n string is then an unambiguous EOF indication. It is also possible\n (in cases where it might matter, for example, if you want to make\n an exact copy of a file while scanning its lines) to tell whether\n the last line of a file ended in a newline or not (yes this\n happens!).\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 the Total Ordering recipe in the ASPN cookbook.\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``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined, and the object is\n considered true if its result is nonzero. If a class defines\n neither ``__len__()`` nor ``__bool__()``, all its instances are\n 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 builtin 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. Normally, data\ndescriptors define both ``__get__()`` and ``__set__()``, while non-\ndata descriptors have just the ``__get__()`` method. Data descriptors\nalways override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances. [2]\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* 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* 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__*.\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 based with the bases, it is\n 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\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()`` builtin 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()`` builtin will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects should\n normally only provide ``__reversed__()`` if they do not support the\n sequence protocol and an efficient implementation of reverse\n iteration is possible.\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\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. [3] 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] A descriptor can define any combination of ``__get__()``,\n ``__set__()`` and ``__delete__()``. If it does not define\n ``__get__()``, then accessing the attribute even on an instance\n will return the descriptor object itself. If the descriptor\n defines ``__set__()`` and/or ``__delete__()``, it is a data\n descriptor; if it defines neither, it is a non-data descriptor.\n\n[3] 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. Note that none of\nthese methods take keyword arguments.\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 only its first character\n capitalized.\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[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\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 range [*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 *format_string*\n argument can contain literal text or replacement fields delimited\n by braces ``{}``. Each replacement field contains either the\n numeric index of a positional argument, or the name of a keyword\n argument. Returns a copy of *format_string* where each replacement\n field is replaced with the string value of the corresponding\n 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.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(seq)\n\n Return a string which is the concatenation of the strings in the\n sequence *seq*. A ``TypeError`` will be raised if there are any\n 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]. Optional\n arguments *start* and *end* are interpreted as in slice notation.\n 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: words start with\n uppercase characters, all remaining cased characters are lowercase.\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', + '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"\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\nString literals may optionally be prefixed with a letter ``\'r\'`` or\n``\'R\'``; such strings are called *raw strings* and treat backslashes\nas literal characters. As a result, ``\'\\U\'`` and ``\'\\u\'`` escapes in\nraw strings are not treated specially.\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\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, at most two hex digits are accepted.\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. Unlike in Standard C, exactly\n two hex digits are 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). Individual code units which form parts of a surrogate\n pair can be encoded using this escape sequence.\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. If this value is negative, the length of the sequence is\nadded to it (so that, e.g., ``x[-1]`` selects the last item of ``x``.)\nThe resulting value must be a nonnegative integer less than the number\nof items in the sequence, and the subscription selects the item whose\nindex is that value (counting from zero).\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", + 'try': '\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 N = None\n del N\n\nThat means that you have to assign the exception to a different name\nif you want to be able to refer to it after the except clause. The\nreason for this is that with the traceback attached to them,\nexceptions will form a reference cycle with the stack frame, keeping\nall locals in that frame alive until the next garbage collection\noccurs.\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', + 'types': '\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.), although such additions\nwill often be provided via the standard library instead.\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name ``None``.\n It is used to signify the absence of a value in many situations,\n e.g., it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``NotImplemented``. Numeric methods and rich comparison methods may\n return this value if they do not implement the operation for the\n operands provided. (The interpreter will then try the reflected\n operation, or some other fallback, depending on the operator.) Its\n truth value is true.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the literal ``...`` or the\n built-in name ``Ellipsis``. Its truth value is true.\n\n``numbers.Number``\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n ``numbers.Integral``\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are two types of integers:\n\n Integers (``int``)\n\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans (``bool``)\n These represent the truth values False and True. The two\n objects representing the values False and True are the only\n Boolean objects. The Boolean type is a subtype of the integer\n type, and Boolean values behave like the values 0 and 1,\n respectively, in almost all contexts, the exception being\n that when converted to a string, the strings ``"False"`` or\n ``"True"`` are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers.\n\n ``numbers.Real`` (``float``)\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these is\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n ``numbers.Complex`` (``complex``)\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number ``z`` can be retrieved through the read-only\n attributes ``z.real`` and ``z.imag``.\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function ``len()`` returns the number of\n items of a sequence. When the length of a sequence is *n*, the\n index set contains the numbers 0, 1, ..., *n*-1. Item *i* of\n sequence *a* is selected by ``a[i]``.\n\n Sequences also support slicing: ``a[i:j]`` selects all items with\n index *k* such that *i* ``<=`` *k* ``<`` *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: ``a[i:j:k]`` selects all items of *a* with index *x*\n where ``x = i + n*k``, *n* ``>=`` ``0`` and *i* ``<=`` *x* ``<``\n *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n The items of a string object are Unicode code units. A\n Unicode code unit is represented by a string object of one\n item and can hold either a 16-bit or 32-bit value\n representing a Unicode ordinal (the maximum value for the\n ordinal is given in ``sys.maxunicode``, and depends on how\n Python is configured at compile time). Surrogate pairs may\n be present in the Unicode object, and will be reported as two\n separate items. The built-in functions ``chr()`` and\n ``ord()`` convert between code units and nonnegative integers\n representing the Unicode ordinals as defined in the Unicode\n Standard 3.0. Conversion from and to other encodings are\n possible through the string method ``encode()``.\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Bytes\n A bytes object is an immutable array. The items are 8-bit\n bytes, represented by integers in the range 0 <= x < 256.\n Bytes literals (like ``b\'abc\'`` and the built-in function\n ``bytes()`` can be used to construct bytes objects. Also,\n bytes objects can be decoded to strings via the ``decode()``\n method.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and ``del`` (delete) statements.\n\n There are currently two intrinsic mutable sequence types:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n Byte Arrays\n A bytearray object is a mutable array. They are created by\n the built-in ``bytearray()`` constructor. Aside from being\n mutable (and hence unhashable), byte arrays otherwise provide\n the same interface and functionality as immutable bytes\n objects.\n\n The extension module ``array`` provides an additional example of\n a mutable sequence type, as does the ``collections`` module.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function ``len()``\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n ``set()`` constructor and can be modified afterwards by several\n methods, such as ``add()``.\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in ``frozenset()`` constructor. As a frozenset is\n immutable and *hashable*, it can be used again as an element of\n another set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation ``a[k]`` selects the item indexed by\n ``k`` from the mapping ``a``; this can be used in expressions and\n as the target of assignments or ``del`` statements. The built-in\n function ``len()`` returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``) then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the ``{...}``\n notation (see section *Dictionary displays*).\n\n The extension modules ``dbm.ndbm`` and ``dbm.gnu`` provide\n additional examples of mapping types, as does the\n ``collections`` module.\n\nCallable types\n These are the types to which the function call operation (see\n section *Calls*) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section *Function definitions*). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +---------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +===========================+=================================+=============+\n | ``__doc__`` | The function\'s documentation | Writable |\n | | string, or ``None`` if | |\n | | unavailable | |\n +---------------------------+---------------------------------+-------------+\n | ``__name__`` | The function\'s name | Writable |\n +---------------------------+---------------------------------+-------------+\n | ``__module__`` | The name of the module the | Writable |\n | | function was defined in, or | |\n | | ``None`` if unavailable. | |\n +---------------------------+---------------------------------+-------------+\n | ``__defaults__`` | A tuple containing default | Writable |\n | | argument values for those | |\n | | arguments that have defaults, | |\n | | or ``None`` if no arguments | |\n | | have a default value | |\n +---------------------------+---------------------------------+-------------+\n | ``__code__`` | The code object representing | Writable |\n | | the compiled function body. | |\n +---------------------------+---------------------------------+-------------+\n | ``__globals__`` | A reference to the dictionary | Read-only |\n | | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +---------------------------+---------------------------------+-------------+\n | ``__dict__`` | The namespace supporting | Writable |\n | | arbitrary function attributes. | |\n +---------------------------+---------------------------------+-------------+\n | ``__closure__`` | ``None`` or a tuple of cells | Read-only |\n | | that contain bindings for the | |\n | | function\'s free variables. | |\n +---------------------------+---------------------------------+-------------+\n | ``__annotations__`` | A dict containing annotations | Writable |\n | | of parameters. The keys of the | |\n | | dict are the parameter names, | |\n | | or ``\'return\'`` for the return | |\n | | annotation, if provided. | |\n +---------------------------+---------------------------------+-------------+\n | ``__kwdefaults__`` | A dict containing defaults for | Writable |\n | | keyword-only parameters. | |\n +---------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n Instance methods\n An instance method object combines a class, a class instance and\n any callable object (normally a user-defined function).\n\n Special read-only attributes: ``__self__`` is the class instance\n object, ``__func__`` is the function object; ``__doc__`` is the\n method\'s documentation (same as ``__func__.__doc__``);\n ``__name__`` is the method name (same as ``__func__.__name__``);\n ``__module__`` is the name of the module the method was defined\n in, or ``None`` if unavailable.\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object or a class\n method object.\n\n When an instance method object is created by retrieving a user-\n defined function object from a class via one of its instances,\n its ``__self__`` attribute is the instance, and the method\n object is said to be bound. The new method\'s ``__func__``\n attribute is the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the ``__func__``\n attribute of the new instance is not the original method object\n but its ``__func__`` attribute.\n\n When an instance method object is created by retrieving a class\n method object from a class or instance, its ``__self__``\n attribute is the class itself, and its ``__func__`` attribute is\n the function object underlying the class method.\n\n When an instance method object is called, the underlying\n function (``__func__``) is called, inserting the class instance\n (``__self__``) in front of the argument list. For instance,\n when ``C`` is a class which contains a definition for a function\n ``f()``, and ``x`` is an instance of ``C``, calling ``x.f(1)``\n is equivalent to calling ``C.f(x, 1)``.\n\n When an instance method object is derived from a class method\n object, the "class instance" stored in ``__self__`` will\n actually be the class itself, so that calling either ``x.f(1)``\n or ``C.f(1)`` is equivalent to calling ``f(C,1)`` where ``f`` is\n the underlying function.\n\n Note that the transformation from function object to instance\n method object happens each time the attribute is retrieved from\n the instance. In some cases, a fruitful optimization is to\n assign the attribute to a local variable and call that local\n variable. Also notice that this transformation only happens for\n user-defined functions; other callable objects (and all non-\n callable objects) are retrieved without transformation. It is\n also important to note that user-defined functions which are\n attributes of a class instance are not converted to bound\n methods; this *only* happens when the function is an attribute\n of the class.\n\n Generator functions\n A function or method which uses the ``yield`` statement (see\n section *The yield statement*) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s ``__next__()`` method will cause the function to\n execute until it provides a value using the ``yield`` statement.\n When the function executes a ``return`` statement or falls off\n the end, a ``StopIteration`` exception is raised and the\n iterator will have reached the end of the set of values to be\n returned.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are ``len()`` and ``math.sin()``\n (``math`` is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: ``__doc__`` is the function\'s documentation\n string, or ``None`` if unavailable; ``__name__`` is the\n function\'s name; ``__self__`` is set to ``None`` (but see the\n next item); ``__module__`` is the name of the module the\n function was defined in or ``None`` if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n ``alist.append()``, assuming *alist* is a list object. In this\n case, the special read-only attribute ``__self__`` is set to the\n object denoted by *list*.\n\n Classes\n Classes are callable. These objects normally act as factories\n for new instances of themselves, but variations are possible for\n class types that override ``__new__()``. The arguments of the\n call are passed to ``__new__()`` and, in the typical case, to\n ``__init__()`` to initialize the new instance.\n\n Class Instances\n Instances of arbitrary classes can be made callable by defining\n a ``__call__()`` method in their class.\n\nModules\n Modules are imported by the ``import`` statement (see section *The\n import statement*). A module object has a namespace implemented by\n a dictionary object (this is the dictionary referenced by the\n __globals__ attribute of functions defined in the module).\n Attribute references are translated to lookups in this dictionary,\n e.g., ``m.x`` is equivalent to ``m.__dict__["x"]``. A module object\n does not contain the code object used to initialize the module\n (since it isn\'t needed once the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``.\n\n Special read-only attribute: ``__dict__`` is the module\'s namespace\n as a dictionary object.\n\n Predefined (writable) attributes: ``__name__`` is the module\'s\n name; ``__doc__`` is the module\'s documentation string, or ``None``\n if unavailable; ``__file__`` is the pathname of the file from which\n the module was loaded, if it was loaded from a file. The\n ``__file__`` attribute is not present for C modules that are\n statically linked into the interpreter; for extension modules\n loaded dynamically from a shared library, it is the pathname of the\n shared library file.\n\nCustom classes\n Custon class types are typically created by class definitions (see\n section *Class definitions*). A class has a namespace implemented\n by a dictionary object. Class attribute references are translated\n to lookups in this dictionary, e.g., ``C.x`` is translated to\n ``C.__dict__["x"]`` (although there are a number of hooks which\n allow for other means of locating attributes). When the attribute\n name is not found there, the attribute search continues in the base\n classes. This search of the base classes uses the C3 method\n resolution order which behaves correctly even in the presence of\n \'diamond\' inheritance structures where there are multiple\n inheritance paths leading back to a common ancestor. Additional\n details on the C3 MRO used by Python can be found in the\n documentation accompanying the 2.3 release at\n http://www.python.org/download/releases/2.3/mro/.\n\n When a class attribute reference (for class ``C``, say) would yield\n a class method object, it is transformed into an instance method\n object whose ``__self__`` attributes is ``C``. When it would yield\n a static method object, it is transformed into the object wrapped\n by the static method object. See section *Implementing Descriptors*\n for another way in which attributes retrieved from a class may\n differ from those actually contained in its ``__dict__``.\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: ``__name__`` is the class name; ``__module__``\n is the module name in which the class was defined; ``__dict__`` is\n the dictionary containing the class\'s namespace; ``__bases__`` is a\n tuple (possibly empty or a singleton) containing the base classes,\n in the order of their occurrence in the base class list;\n ``__doc__`` is the class\'s documentation string, or None if\n undefined.\n\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object, it is transformed into an instance method object\n whose ``__self__`` attribute is the instance. Static method and\n class method objects are also transformed; see above under\n "Classes". See section *Implementing Descriptors* for another way\n in which attributes of a class retrieved via its instances may\n differ from the objects actually stored in the class\'s\n ``__dict__``. If no class attribute is found, and the object\'s\n class has a ``__getattr__()`` method, that is called to satisfy the\n lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n ``__setattr__()`` or ``__delattr__()`` method, this is called\n instead of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n *Special method names*.\n\n Special attributes: ``__dict__`` is the attribute dictionary;\n ``__class__`` is the instance\'s class.\n\nFiles\n A file object represents an open file. File objects are created by\n the ``open()`` built-in function, and also by ``os.popen()``,\n ``os.fdopen()``, and the ``makefile()`` method of socket objects\n (and perhaps by other functions or methods provided by extension\n modules). The objects ``sys.stdin``, ``sys.stdout`` and\n ``sys.stderr`` are initialized to file objects corresponding to the\n interpreter\'s standard input, output and error streams. See *File\n Objects* for complete documentation of file objects.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: ``co_name`` gives the function\n name; ``co_argcount`` is the number of positional arguments\n (including arguments with default values); ``co_nlocals`` is the\n number of local variables used by the function (including\n arguments); ``co_varnames`` is a tuple containing the names of\n the local variables (starting with the argument names);\n ``co_cellvars`` is a tuple containing the names of local\n variables that are referenced by nested functions;\n ``co_freevars`` is a tuple containing the names of free\n variables; ``co_code`` is a string representing the sequence of\n bytecode instructions; ``co_consts`` is a tuple containing the\n literals used by the bytecode; ``co_names`` is a tuple\n containing the names used by the bytecode; ``co_filename`` is\n the filename from which the code was compiled;\n ``co_firstlineno`` is the first line number of the function;\n ``co_lnotab`` is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); ``co_stacksize`` is the required stack size\n (including local variables); ``co_flags`` is an integer encoding\n a number of flags for the interpreter.\n\n The following flag bits are defined for ``co_flags``: bit\n ``0x04`` is set if the function uses the ``*arguments`` syntax\n to accept an arbitrary number of positional arguments; bit\n ``0x08`` is set if the function uses the ``**keywords`` syntax\n to accept arbitrary keyword arguments; bit ``0x20`` is set if\n the function is a generator.\n\n Future feature declarations (``from __future__ import\n division``) also use bits in ``co_flags`` to indicate whether a\n code object was compiled with a particular feature enabled: bit\n ``0x2000`` is set if the function was compiled with future\n division enabled; bits ``0x10`` and ``0x1000`` were used in\n earlier versions of Python.\n\n Other bits in ``co_flags`` are reserved for internal use.\n\n If a code object represents a function, the first item in\n ``co_consts`` is the documentation string of the function, or\n ``None`` if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: ``f_back`` is to the previous\n stack frame (towards the caller), or ``None`` if this is the\n bottom stack frame; ``f_code`` is the code object being executed\n in this frame; ``f_locals`` is the dictionary used to look up\n local variables; ``f_globals`` is used for global variables;\n ``f_builtins`` is used for built-in (intrinsic) names;\n ``f_lasti`` gives the precise instruction (this is an index into\n the bytecode string of the code object).\n\n Special writable attributes: ``f_trace``, if not ``None``, is a\n function called at the start of each source code line (this is\n used by the debugger); ``f_lineno`` is the current line number\n of the frame --- writing to this from within a trace function\n jumps to the given line (only for the bottom-most frame). A\n debugger can implement a Jump command (aka Set Next Statement)\n by writing to f_lineno.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n *The try statement*.) It is accessible as the third item of the\n tuple returned by ``sys.exc_info()``. When the program contains\n no suitable handler, the stack trace is written (nicely\n formatted) to the standard error stream; if the interpreter is\n interactive, it is also made available to the user as\n ``sys.last_traceback``.\n\n Special read-only attributes: ``tb_next`` is the next level in\n the stack trace (towards the frame where the exception\n occurred), or ``None`` if there is no next level; ``tb_frame``\n points to the execution frame of the current level;\n ``tb_lineno`` gives the line number where the exception\n occurred; ``tb_lasti`` indicates the precise instruction. The\n line number and last instruction in the traceback may differ\n from the line number of its frame object if the exception\n occurred in a ``try`` statement with no matching except clause\n or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices for ``__getitem__()``\n methods. They are also created by the built-in ``slice()``\n function.\n\n Special read-only attributes: ``start`` is the lower bound;\n ``stop`` is the upper bound; ``step`` is the step value; each is\n ``None`` if omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the slice that the slice object\n would describe if applied to a sequence of *length* items.\n It returns a tuple of three integers; respectively these are\n the *start* and *stop* indices and the *step* or stride\n length of the slice. Missing or out-of-bounds indices are\n handled in a manner consistent with regular slices.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n ``staticmethod()`` constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in ``classmethod()`` constructor.\n', + 'typesfunctions': '\nFunctions\n*********\n\nFunction objects are created by function definitions. The only\noperation on a function object is to call it: ``func(argument-list)``.\n\nThere are really two flavors of function objects: built-in functions\nand user-defined functions. Both support the same operation (to call\nthe function), but the implementation is different, hence the\ndifferent object types.\n\nSee *Function definitions* for more information.\n', + '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": 2, "two": 3}``:\n\n * ``dict(one=2, two=3)``\n\n * ``dict({\'one\': 2, \'two\': 3})``\n\n * ``dict(zip((\'one\', \'two\'), (2, 3)))``\n\n * ``dict([[\'two\', 3], [\'one\', 2]])``\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 ``iterkeys()``.\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 a tuple or other iterable of\n length two). If keyword arguments are specified, the\n dictionary is then is updated with those key/value pairs:\n ``d.update(red=1, 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 will raise a ``RuntimeError``.\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 and\nhashable, then the items view is also set-like. (Values views are not\ntreated as set-like since the entries are generally not unique.) Then\nthese set operations are available ("other" refers either to another\nview or a set):\n\ndictview & other\n\n Return the intersection of the dictview and the other object as a\n new set.\n\ndictview | other\n\n Return the union of the dictview and the other object as a new set.\n\ndictview - other\n\n Return the difference between the dictview and the other object\n (all elements in *dictview* that aren\'t in *other*) as a new set.\n\ndictview ^ other\n\n Return the symmetric difference (all elements either in *dictview*\n or *other*, but not in both) of the dictview and the other object\n as a new set.\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', + '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\nWarning: While string objects are sequences of characters (represented by\n strings of length 1), bytes and bytearray objects are sequences of\n *integers* (between 0 and 255), representing the ASCII value of\n single bytes. That means that for a bytes or bytearray object *b*,\n ``b[0]`` will be an integer, while ``b[0:1]`` will be a bytes or\n bytearray object of length 1. The representation of bytes objects\n uses the literal format (``b\'...\'``) since it is generally more\n useful than e.g. ``bytes([50, 19, 100])``. You can always convert a\n bytes object into a list of integers using ``list(b)``.Also, while\n in previous Python versions, byte strings and Unicode strings could\n be exchanged for each other rather freely (barring encoding issues),\n strings and bytes are now completely separate concepts. There\'s no\n implicit en-/decoding if you pass and object of the wrong type. A\n string always compares unequal to a bytes or bytearray 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. If *s* and *t* are both strings, some Python implementations such\n as CPython can usually perform an in-place optimization for\n assignments of the form ``s=s+t`` or ``s+=t``. When applicable,\n this optimization makes quadratic run-time much less likely. This\n optimization is both version and implementation dependent. For\n performance sensitive code, it is preferable to use the\n ``str.join()`` method which assures consistent linear concatenation\n performance across versions and implementations.\n\n\nString Methods\n==============\n\nString objects support the methods listed below. Note that none of\nthese methods take keyword arguments.\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 only its first character\n capitalized.\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[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\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 range [*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 *format_string*\n argument can contain literal text or replacement fields delimited\n by braces ``{}``. Each replacement field contains either the\n numeric index of a positional argument, or the name of a keyword\n argument. Returns a copy of *format_string* where each replacement\n field is replaced with the string value of the corresponding\n 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.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(seq)\n\n Return a string which is the concatenation of the strings in the\n sequence *seq*. A ``TypeError`` will be raised if there are any\n 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]. Optional\n arguments *start* and *end* are interpreted as in slice notation.\n 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: words start with\n uppercase characters, all remaining cased characters are lowercase.\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 %(#)03d quote types.\' % \\\n... {\'language\': "Python", "#": 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\nFor safety reasons, floating point precisions are clipped to 50;\n``%f`` conversions for numbers whose absolute value is over 1e50 are\nreplaced by ``%g`` conversions. [5] All other errors raise\nexceptions.\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 very little behavior: they only support indexing,\niteration, and the ``len()`` function.\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``.\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 While a list is being sorted, the effect of attempting to mutate,\n or even inspect, the list is undefined. The C implementation makes\n the list appear empty for the duration, and raises ``ValueError``\n if it can detect 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\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])\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)\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``.\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 While a list is being sorted, the effect of attempting to mutate,\n or even inspect, the list is undefined. The C implementation makes\n the list appear empty for the duration, and raises ``ValueError``\n if it can detect 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', + 'with': '\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" expression ["as" target] ":" suite\n\nThe execution of the ``with`` statement proceeds as follows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__enter__()`` method is invoked.\n\n3. 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 5 below.\n\n4. The suite is executed.\n\n5. 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\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n', + 'yield': '\nThe ``yield`` statement\n***********************\n\n yield_stmt ::= yield_expression\n\nThe ``yield`` statement is only used when defining a generator\nfunction, and is only used in the body of the generator function.\nUsing a ``yield`` statement in a function definition is sufficient to\ncause that definition to create a generator function instead of a\nnormal function. When a generator function is called, it returns an\niterator known as a generator iterator, or more commonly, a generator.\nThe body of the generator function is executed by calling the\n``next()`` function on the generator repeatedly until it raises an\nexception.\n\nWhen a ``yield`` statement is executed, the state of the generator is\nfrozen and the value of **expression_list** is returned to\n``next()``\'s caller. By "frozen" we mean that all local state is\nretained, including the current bindings of local variables, the\ninstruction pointer, and the internal evaluation stack: enough\ninformation is saved so that the next time ``next()`` is invoked, the\nfunction can proceed exactly as if the ``yield`` statement were just\nanother external call.\n\nThe ``yield`` statement is allowed in the ``try`` clause of a ``try``\n... ``finally`` construct. If the generator is not resumed before it\nis finalized (by reaching a zero reference count or by being garbage\ncollected), the generator-iterator\'s ``close()`` method will be\ncalled, allowing any pending ``finally`` clauses to execute.\n\nSee also:\n\n **PEP 0255** - Simple Generators\n The proposal for adding generators and the ``yield`` statement\n to Python.\n\n **PEP 0342** - Coroutines via Enhanced Generators\n The proposal that, among other generator enhancements, proposed\n allowing ``yield`` to appear inside a ``try`` ... ``finally``\n block.\n'} From python-checkins at python.org Mon Apr 27 18:36:04 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:36:04 +0200 (CEST) Subject: [Python-checkins] r72021 - python/branches/py3k Message-ID: <20090427163604.12A991E4017@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:36:03 2009 New Revision: 72021 Log: Recorded merge of revisions 71957,71959,71961 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71957 | georg.brandl | 2009-04-26 08:05:58 +0200 (So, 26 Apr 2009) | 2 lines Note that the versions are also in README.txt. ........ r71959 | georg.brandl | 2009-04-26 08:06:53 +0200 (So, 26 Apr 2009) | 2 lines Another file where the versions need to be up to date. ........ r71961 | georg.brandl | 2009-04-26 11:57:29 +0200 (So, 26 Apr 2009) | 2 lines Update pydoc topics. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Mon Apr 27 18:38:14 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:38:14 +0200 (CEST) Subject: [Python-checkins] r72022 - in python/branches/py3k: Doc/whatsnew/2.7.rst Message-ID: <20090427163814.C93CD1E41D8@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:38:14 2009 New Revision: 72022 Log: Merged revisions 71503 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71503 | eric.smith | 2009-04-12 04:57:29 +0200 (So, 12 Apr 2009) | 1 line Take credit for my patch for issue 5237. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/whatsnew/2.7.rst Modified: python/branches/py3k/Doc/whatsnew/2.7.rst ============================================================================== --- python/branches/py3k/Doc/whatsnew/2.7.rst (original) +++ python/branches/py3k/Doc/whatsnew/2.7.rst Mon Apr 27 18:38:14 2009 @@ -102,7 +102,7 @@ specifier will use the next argument, and so on. You can't mix auto-numbering and explicit numbering -- either number all of your specifier fields or none of them -- but you can mix auto-numbering and named fields, as in the second - example above. (Contributed by XXX; :issue`5237`.) + example above. (Contributed by Eric Smith; :issue`5237`.) * The :func:`int` and :func:`long` types gained a ``bit_length`` method that returns the number of bits necessary to represent From python-checkins at python.org Mon Apr 27 18:38:34 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:38:34 +0200 (CEST) Subject: [Python-checkins] r72023 - python/branches/py3k Message-ID: <20090427163834.EF2661E41DF@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:38:34 2009 New Revision: 72023 Log: Blocked revisions 71507 via svnmerge ........ r71507 | georg.brandl | 2009-04-12 14:08:12 +0200 (So, 12 Apr 2009) | 1 line #5704: let python -3 imply -t as well. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Mon Apr 27 18:41:41 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:41:41 +0200 (CEST) Subject: [Python-checkins] r72024 - in python/branches/py3k: Doc/reference/compound_stmts.rst Lib/optparse.py Message-ID: <20090427164141.5B0511E4017@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:41:41 2009 New Revision: 72024 Log: Merged revisions 71540,71563 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71540 | georg.brandl | 2009-04-12 22:30:53 +0200 (So, 12 Apr 2009) | 1 line #5719: add short usage example to optparse docstring. ........ r71563 | georg.brandl | 2009-04-13 14:36:18 +0200 (Mo, 13 Apr 2009) | 1 line Simplify markup. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/reference/compound_stmts.rst python/branches/py3k/Lib/optparse.py Modified: python/branches/py3k/Doc/reference/compound_stmts.rst ============================================================================== --- python/branches/py3k/Doc/reference/compound_stmts.rst (original) +++ python/branches/py3k/Doc/reference/compound_stmts.rst Mon Apr 27 18:41:41 2009 @@ -1,4 +1,3 @@ - .. _compound: ******************* Modified: python/branches/py3k/Lib/optparse.py ============================================================================== --- python/branches/py3k/Lib/optparse.py (original) +++ python/branches/py3k/Lib/optparse.py Mon Apr 27 18:41:41 2009 @@ -6,6 +6,19 @@ For support, use the optik-users at lists.sourceforge.net mailing list (http://lists.sourceforge.net/lists/listinfo/optik-users). + +Simple usage example: + + from optparse import OptionParser + + parser = OptionParser() + parser.add_option("-f", "--file", dest="filename", + help="write report to FILE", metavar="FILE") + parser.add_option("-q", "--quiet", + action="store_false", dest="verbose", default=True, + help="don't print status messages to stdout") + + (options, args) = parser.parse_args() """ __version__ = "1.5.3" From python-checkins at python.org Mon Apr 27 18:42:58 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:42:58 +0200 (CEST) Subject: [Python-checkins] r72025 - in python/branches/py3k: Lib/configparser.py Lib/test/test_cfgparser.py Misc/NEWS Message-ID: <20090427164258.8ECBD1E4017@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:42:58 2009 New Revision: 72025 Log: Merged revisions 71537 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71537 | georg.brandl | 2009-04-12 19:24:11 +0200 (So, 12 Apr 2009) | 1 line #5741: dont disallow double percent signs in SafeConfigParser.set() keys. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/configparser.py python/branches/py3k/Lib/test/test_cfgparser.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/configparser.py ============================================================================== --- python/branches/py3k/Lib/configparser.py (original) +++ python/branches/py3k/Lib/configparser.py Mon Apr 27 18:42:58 2009 @@ -620,7 +620,6 @@ return ''.join(L) _interpvar_re = re.compile(r"%\(([^)]+)\)s") - _badpercent_re = re.compile(r"%[^%]|%$") def _interpolate_some(self, option, accum, rest, section, map, depth): if depth > MAX_INTERPOLATION_DEPTH: @@ -667,9 +666,10 @@ # check for bad percent signs: # first, replace all "good" interpolations tmp_value = self._interpvar_re.sub('', value) + tmp_value = tmp_value.replace('%%', '') # then, check if there's a lone percent sign left - m = self._badpercent_re.search(tmp_value) - if m: + percent_index = tmp_value.find('%') + if percent_index != -1: raise ValueError("invalid interpolation syntax in %r at " - "position %d" % (value, m.start())) + "position %d" % (value, percent_index)) ConfigParser.set(self, section, option, value) 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 Mon Apr 27 18:42:58 2009 @@ -424,6 +424,10 @@ self.assertEqual(cf.get('sect', "option1"), "foo") + # bug #5741: double percents are *not* malformed + cf.set("sect", "option2", "foo%%bar") + self.assertEqual(cf.get("sect", "option2"), "foo%bar") + def test_set_nonstring_types(self): cf = self.fromstring("[sect]\n" "option1=foo\n") Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Apr 27 18:42:58 2009 @@ -467,6 +467,9 @@ - Issue #5607: fixed Distutils test_get_platform for Mac OS X fat binaries. +- Issue #5741: don't disallow "%%" (which is an escape for "%") when setting + a value in SafeConfigParser. + - Issue #5732: added a new command in Distutils: check. - Issue #5731: Distutils bdist_wininst no longer worked on non-Windows From python-checkins at python.org Mon Apr 27 18:43:37 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:43:37 +0200 (CEST) Subject: [Python-checkins] r72026 - in python/branches/py3k: Lib/configparser.py Message-ID: <20090427164337.24CC61E4017@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:43:36 2009 New Revision: 72026 Log: Merged revisions 71564 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71564 | georg.brandl | 2009-04-13 14:36:24 +0200 (Mo, 13 Apr 2009) | 1 line #5741 followup: should also allow %%(blah)s. ........ Modified: python/branches/py3k/ (props changed) 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 Mon Apr 27 18:43:36 2009 @@ -665,8 +665,8 @@ raise TypeError("option values must be strings") # check for bad percent signs: # first, replace all "good" interpolations - tmp_value = self._interpvar_re.sub('', value) - tmp_value = tmp_value.replace('%%', '') + tmp_value = value.replace('%%', '') + tmp_value = self._interpvar_re.sub('', tmp_value) # then, check if there's a lone percent sign left percent_index = tmp_value.find('%') if percent_index != -1: From python-checkins at python.org Mon Apr 27 18:45:26 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:45:26 +0200 (CEST) Subject: [Python-checkins] r72027 - in python/branches/py3k: Doc/library/email.message.rst Doc/library/multiprocessing.rst Message-ID: <20090427164526.6E2B41E4017@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:45:26 2009 New Revision: 72027 Log: Merged revisions 71544,71546,71554-71555 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71544 | benjamin.peterson | 2009-04-13 01:19:56 +0200 (Mo, 13 Apr 2009) | 1 line fix extra parenthesis #5774 ........ r71546 | benjamin.peterson | 2009-04-13 01:44:15 +0200 (Mo, 13 Apr 2009) | 1 line fix missing quote ........ r71554 | hirokazu.yamamoto | 2009-04-13 03:07:06 +0200 (Mo, 13 Apr 2009) | 1 line Fixed typo. (email.Utils => email.utils) ........ r71555 | hirokazu.yamamoto | 2009-04-13 03:21:56 +0200 (Mo, 13 Apr 2009) | 1 line Fixed another typos. (email.Utils => email.utils) ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/email.message.rst python/branches/py3k/Doc/library/multiprocessing.rst 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 Mon Apr 27 18:45:26 2009 @@ -349,13 +349,13 @@ If your application doesn't care whether the parameter was encoded as in :rfc:`2231`, you can collapse the parameter value by calling - :func:`email.Utils.collapse_rfc2231_value`, passing in the return value + :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 isn't. For example:: rawparam = msg.get_param('foo') - param = email.Utils.collapse_rfc2231_value(rawparam) + param = email.utils.collapse_rfc2231_value(rawparam) In any case, the parameter value (either the returned string, or the ``VALUE`` item in the 3-tuple) is always unquoted, unless *unquote* is set @@ -412,7 +412,7 @@ does not have a ``filename`` parameter, this method falls back to looking for the ``name`` parameter. If neither is found, or the header is missing, then *failobj* is returned. The returned string will always be - unquoted as per :meth:`Utils.unquote`. + unquoted as per :func:`email.utils.unquote`. .. method:: get_boundary([failobj]) @@ -420,7 +420,7 @@ Return the value of the ``boundary`` parameter of the :mailheader:`Content-Type` header of the message, or *failobj* if either the header is missing, or has no ``boundary`` parameter. The returned - string will always be unquoted as per :meth:`Utils.unquote`. + string will always be unquoted as per :func:`email.utils.unquote`. .. method:: set_boundary(boundary) Modified: python/branches/py3k/Doc/library/multiprocessing.rst ============================================================================== --- python/branches/py3k/Doc/library/multiprocessing.rst (original) +++ python/branches/py3k/Doc/library/multiprocessing.rst Mon Apr 27 18:45:26 2009 @@ -1160,7 +1160,7 @@ Connect a local manager object to a remote manager process: >>> from multiprocessing.managers import BaseManager - >>> m = BaseManager(address='127.0.0.1', authkey='abc)) + >>> m = BaseManager(address='127.0.0.1', authkey='abc') >>> m.connect() .. method:: shutdown() From python-checkins at python.org Mon Apr 27 18:46:17 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:46:17 +0200 (CEST) Subject: [Python-checkins] r72028 - in python/branches/py3k: Doc/library/email.charset.rst Doc/library/email.encoders.rst Doc/library/email.errors.rst Doc/library/email.generator.rst Doc/library/email.header.rst Doc/library/email.message.rst Doc/library/email.mime.rst Doc/library/email.parser.rst Message-ID: <20090427164617.888A51E4017@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:46:17 2009 New Revision: 72028 Log: Merged revisions 71572 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71572 | georg.brandl | 2009-04-13 15:13:25 +0200 (Mo, 13 Apr 2009) | 1 line #5745: more linking for identifiers in email docs. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/email.charset.rst python/branches/py3k/Doc/library/email.encoders.rst python/branches/py3k/Doc/library/email.errors.rst python/branches/py3k/Doc/library/email.generator.rst python/branches/py3k/Doc/library/email.header.rst python/branches/py3k/Doc/library/email.message.rst python/branches/py3k/Doc/library/email.mime.rst python/branches/py3k/Doc/library/email.parser.rst Modified: python/branches/py3k/Doc/library/email.charset.rst ============================================================================== --- python/branches/py3k/Doc/library/email.charset.rst (original) +++ python/branches/py3k/Doc/library/email.charset.rst Mon Apr 27 18:46:17 2009 @@ -161,8 +161,8 @@ charset to the output charset automatically. This is not useful for multibyte character sets, which have line length issues (multibyte characters must be split on a character, not a byte boundary); use the - higher-level :class:`Header` class to deal with these issues (see - :mod:`email.header`). *convert* defaults to ``False``. + higher-level :class:`~email.header.Header` class to deal with these issues + (see :mod:`email.header`). *convert* defaults to ``False``. The type of encoding (base64 or quoted-printable) will be based on the *header_encoding* attribute. Modified: python/branches/py3k/Doc/library/email.encoders.rst ============================================================================== --- python/branches/py3k/Doc/library/email.encoders.rst (original) +++ python/branches/py3k/Doc/library/email.encoders.rst Mon Apr 27 18:46:17 2009 @@ -5,18 +5,18 @@ :synopsis: Encoders for email message payloads. -When creating :class:`Message` objects from scratch, you often need to encode -the payloads for transport through compliant mail servers. This is especially -true for :mimetype:`image/\*` and :mimetype:`text/\*` type messages containing -binary data. +When creating :class:`~email.message.Message` objects from scratch, you often +need to encode the payloads for transport through compliant mail servers. This +is especially true for :mimetype:`image/\*` and :mimetype:`text/\*` type messages +containing binary data. The :mod:`email` package provides some convenient encodings in its :mod:`encoders` module. These encoders are actually used by the -:class:`MIMEAudio` and :class:`MIMEImage` class constructors to provide default -encodings. All encoder functions take exactly one argument, the message object -to encode. They usually extract the payload, encode it, and reset the payload -to this newly encoded value. They should also set the -:mailheader:`Content-Transfer-Encoding` header as appropriate. +:class:`~email.mime.audio.MIMEAudio` and :class:`~email.mime.image.MIMEImage` +class constructors to provide default encodings. All encoder functions take +exactly one argument, the message object to encode. They usually extract the +payload, encode it, and reset the payload to this newly encoded value. They +should also set the :mailheader:`Content-Transfer-Encoding` header as appropriate. Here are the encoding functions provided: Modified: python/branches/py3k/Doc/library/email.errors.rst ============================================================================== --- python/branches/py3k/Doc/library/email.errors.rst (original) +++ python/branches/py3k/Doc/library/email.errors.rst Mon Apr 27 18:46:17 2009 @@ -17,8 +17,8 @@ .. exception:: MessageParseError() - This is the base class for exceptions thrown by the :class:`Parser` class. It - is derived from :exc:`MessageError`. + This is the base class for exceptions thrown by the :class:`~email.parser.Parser` + class. It is derived from :exc:`MessageError`. .. exception:: HeaderParseError() @@ -55,11 +55,12 @@ Since :meth:`Message.add_payload` is deprecated, this exception is rarely raised in practice. However the exception may also be raised if the :meth:`attach` method is called on an instance of a class derived from - :class:`MIMENonMultipart` (e.g. :class:`MIMEImage`). + :class:`~email.mime.nonmultipart.MIMENonMultipart` (e.g. + :class:`~email.mime.image.MIMEImage`). -Here's the list of the defects that the :class:`FeedParser` can find while -parsing messages. Note that the defects are added to the message where the -problem was found, so for example, if a message nested inside a +Here's the list of the defects that the :class:`~email.mime.parser.FeedParser` +can find while parsing messages. Note that the defects are added to the message +where the problem was found, so for example, if a message nested inside a :mimetype:`multipart/alternative` had a malformed header, that nested message object would have a defect, but the containing messages would not. Modified: python/branches/py3k/Doc/library/email.generator.rst ============================================================================== --- python/branches/py3k/Doc/library/email.generator.rst (original) +++ python/branches/py3k/Doc/library/email.generator.rst Mon Apr 27 18:46:17 2009 @@ -16,8 +16,8 @@ yourself. However the bundled generator knows how to generate most email in a standards-compliant way, should handle MIME and non-MIME email messages just fine, and is designed so that the transformation from flat text, to a message -structure via the :class:`Parser` class, and back to flat text, is idempotent -(the input is identical to the output). +structure via the :class:`~email.parser.Parser` class, and back to flat text, +is idempotent (the input is identical to the output). Here are the public methods of the :class:`Generator` class, imported from the :mod:`email.generator` module: @@ -41,8 +41,8 @@ Optional *maxheaderlen* specifies the longest length for a non-continued header. When a header line is longer than *maxheaderlen* (in characters, with tabs expanded to 8 spaces), the header will be split as defined in the - :mod:`email.header.Header` class. Set to zero to disable header wrapping. The - default is 78, as recommended (but not required) by :rfc:`2822`. + :class:`~email.header.Header` class. Set to zero to disable header wrapping. + The default is 78, as recommended (but not required) by :rfc:`2822`. The other public :class:`Generator` methods are: Modified: python/branches/py3k/Doc/library/email.header.rst ============================================================================== --- python/branches/py3k/Doc/library/email.header.rst (original) +++ python/branches/py3k/Doc/library/email.header.rst Mon Apr 27 18:46:17 2009 @@ -21,10 +21,10 @@ If you want to include non-ASCII characters in your email headers, say in the :mailheader:`Subject` or :mailheader:`To` fields, you should use the -:class:`Header` class and assign the field in the :class:`Message` object to an -instance of :class:`Header` instead of using a string for the header value. -Import the :class:`Header` class from the :mod:`email.header` module. For -example:: +:class:`Header` class and assign the field in the :class:`~email.message.Message` +object to an instance of :class:`Header` instead of using a string for the header +value. Import the :class:`Header` class from the :mod:`email.header` module. +For example:: >>> from email.message import Message >>> from email.header import Header @@ -39,9 +39,9 @@ Notice here how we wanted the :mailheader:`Subject` field to contain a non-ASCII character? We did this by creating a :class:`Header` instance and passing in the character set that the byte string was encoded in. When the subsequent -:class:`Message` instance was flattened, the :mailheader:`Subject` field was -properly :rfc:`2047` encoded. MIME-aware mail readers would show this header -using the embedded ISO-8859-1 character. +:class:`~email.message.Message` instance was flattened, the :mailheader:`Subject` +field was properly :rfc:`2047` encoded. MIME-aware mail readers would show this +header using the embedded ISO-8859-1 character. Here is the :class:`Header` class description: @@ -81,10 +81,11 @@ Append the string *s* to the MIME header. - Optional *charset*, if given, should be a :class:`Charset` instance (see - :mod:`email.charset`) or the name of a character set, which will be - converted to a :class:`Charset` instance. A value of ``None`` (the - default) means that the *charset* given in the constructor is used. + Optional *charset*, if given, should be a :class:`~email.charset.Charset` + instance (see :mod:`email.charset`) or the name of a character set, which + will be converted to a :class:`~email.charset.Charset` instance. A value + of ``None`` (the default) means that the *charset* given in the constructor + is used. *s* may be an instance of :class:`bytes` or :class:`str`. If it is an instance of :class:`bytes`, then *charset* is the encoding of that byte 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 Mon Apr 27 18:46:17 2009 @@ -45,8 +45,8 @@ Note that this method is provided as a convenience and may not always format the message the way you want. For example, by default it mangles lines that begin with ``From``. For more flexibility, instantiate a - :class:`Generator` instance and use its :meth:`flatten` method directly. - For example:: + :class:`~email.generator.Generator` instance and use its :meth:`flatten` + method directly. For example:: from io import StringIO from email.generator import Generator @@ -122,11 +122,12 @@ .. method:: set_charset(charset) Set the character set of the payload to *charset*, which can either be a - :class:`Charset` instance (see :mod:`email.charset`), a string naming a - character set, or ``None``. If it is a string, it will be converted to a - :class:`Charset` instance. If *charset* is ``None``, the ``charset`` - parameter will be removed from the :mailheader:`Content-Type` - header. Anything else will generate a :exc:`TypeError`. + :class:`~email.charset.Charset` instance (see :mod:`email.charset`), a + string naming a character set, or ``None``. If it is a string, it will + be converted to a :class:`~email.charset.Charset` instance. If *charset* + is ``None``, the ``charset`` parameter will be removed from the + :mailheader:`Content-Type` header. Anything else will generate a + :exc:`TypeError`. The message will be assumed to be of type :mimetype:`text/\*` encoded with *charset.input_charset*. It will be converted to *charset.output_charset* @@ -137,8 +138,8 @@ .. method:: get_charset() - Return the :class:`Charset` instance associated with the message's - payload. + Return the :class:`~email.charset.Charset` instance associated with the + message's payload. The following methods implement a mapping-like interface for accessing the message's :rfc:`2822` headers. Note that there are some semantic differences @@ -445,7 +446,7 @@ that header has no ``charset`` parameter, *failobj* is returned. Note that this method differs from :meth:`get_charset` which returns the - :class:`Charset` instance for the default encoding of the message body. + :class:`~email.charset.Charset` instance for the default encoding of the message body. .. method:: get_charsets([failobj]) @@ -495,10 +496,11 @@ text can become visible. The *preamble* attribute contains this leading extra-armor text for MIME - documents. When the :class:`Parser` discovers some text after the headers - but before the first boundary string, it assigns this text to the - message's *preamble* attribute. When the :class:`Generator` is writing - out the plain text representation of a MIME message, and it finds the + documents. When the :class:`~email.parser.Parser` discovers some text + after the headers but before the first boundary string, it assigns this + text to the message's *preamble* attribute. When the + :class:`~email.generator.Generator` is writing out the plain text + representation of a MIME message, and it finds the message has a *preamble* attribute, it will write this text in the area between the headers and the first boundary. See :mod:`email.parser` and :mod:`email.generator` for details. Modified: python/branches/py3k/Doc/library/email.mime.rst ============================================================================== --- python/branches/py3k/Doc/library/email.mime.rst (original) +++ python/branches/py3k/Doc/library/email.mime.rst Mon Apr 27 18:46:17 2009 @@ -8,14 +8,15 @@ Ordinarily, you get a message object structure by passing a file or some text to a parser, which parses the text and returns the root message object. However you can also build a complete message structure from scratch, or even individual -:class:`Message` objects by hand. In fact, you can also take an existing -structure and add new :class:`Message` objects, move them around, etc. This -makes a very convenient interface for slicing-and-dicing MIME messages. - -You can create a new object structure by creating :class:`Message` instances, -adding attachments and all the appropriate headers manually. For MIME messages -though, the :mod:`email` package provides some convenient subclasses to make -things easier. +:class:`~email.message.Message` objects by hand. In fact, you can also take an +existing structure and add new :class:`~email.message.Message` objects, move them +around, etc. This makes a very convenient interface for slicing-and-dicing MIME +messages. + +You can create a new object structure by creating :class:`~email.message.Message` +instances, adding attachments and all the appropriate headers manually. For MIME +messages though, the :mod:`email` package provides some convenient subclasses to +make things easier. Here are the classes: @@ -25,10 +26,11 @@ Module: :mod:`email.mime.base` - This is the base class for all the MIME-specific subclasses of :class:`Message`. - Ordinarily you won't create instances specifically of :class:`MIMEBase`, - although you could. :class:`MIMEBase` is provided primarily as a convenient - base class for more specific MIME-aware subclasses. + This is the base class for all the MIME-specific subclasses of + :class:`~email.message.Message`. Ordinarily you won't create instances + specifically of :class:`MIMEBase`, although you could. :class:`MIMEBase` + is provided primarily as a convenient base class for more specific + MIME-aware subclasses. *_maintype* is the :mailheader:`Content-Type` major type (e.g. :mimetype:`text` or :mimetype:`image`), and *_subtype* is the :mailheader:`Content-Type` minor @@ -46,11 +48,11 @@ Module: :mod:`email.mime.nonmultipart` - A subclass of :class:`MIMEBase`, this is an intermediate base class for MIME - messages that are not :mimetype:`multipart`. The primary purpose of this class - is to prevent the use of the :meth:`attach` method, which only makes sense for - :mimetype:`multipart` messages. If :meth:`attach` is called, a - :exc:`MultipartConversionError` exception is raised. + A subclass of :class:`~email.mime.base.MIMEBase`, this is an intermediate base + class for MIME messages that are not :mimetype:`multipart`. The primary + purpose of this class is to prevent the use of the :meth:`attach` method, + which only makes sense for :mimetype:`multipart` messages. If :meth:`attach` + is called, a :exc:`~email.errors.MultipartConversionError` exception is raised. .. currentmodule:: email.mime.multipart @@ -59,12 +61,12 @@ Module: :mod:`email.mime.multipart` - A subclass of :class:`MIMEBase`, this is an intermediate base class for MIME - messages that are :mimetype:`multipart`. Optional *_subtype* defaults to - :mimetype:`mixed`, but can be used to specify the subtype of the message. A - :mailheader:`Content-Type` header of :mimetype:`multipart/_subtype` will be - added to the message object. A :mailheader:`MIME-Version` header will also be - added. + A subclass of :class:`~email.mime.base.MIMEBase`, this is an intermediate base + class for MIME messages that are :mimetype:`multipart`. Optional *_subtype* + defaults to :mimetype:`mixed`, but can be used to specify the subtype of the + message. A :mailheader:`Content-Type` header of :mimetype:`multipart/_subtype` + will be added to the message object. A :mailheader:`MIME-Version` header will + also be added. Optional *boundary* is the multipart boundary string. When ``None`` (the default), the boundary is calculated when needed. @@ -84,10 +86,11 @@ Module: :mod:`email.mime.application` - A subclass of :class:`MIMENonMultipart`, the :class:`MIMEApplication` class is - used to represent MIME message objects of major type :mimetype:`application`. - *_data* is a string containing the raw byte data. Optional *_subtype* specifies - the MIME subtype and defaults to :mimetype:`octet-stream`. + A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the + :class:`MIMEApplication` class is used to represent MIME message objects of + major type :mimetype:`application`. *_data* is a string containing the raw + byte data. Optional *_subtype* specifies the MIME subtype and defaults to + :mimetype:`octet-stream`. Optional *_encoder* is a callable (i.e. function) which will perform the actual encoding of the data for transport. This callable takes one argument, which is @@ -106,13 +109,14 @@ Module: :mod:`email.mime.audio` - A subclass of :class:`MIMENonMultipart`, the :class:`MIMEAudio` class is used to - create MIME message objects of major type :mimetype:`audio`. *_audiodata* is a - string containing the raw audio data. If this data can be decoded by the - standard Python module :mod:`sndhdr`, then the subtype will be automatically - included in the :mailheader:`Content-Type` header. Otherwise you can explicitly - specify the audio subtype via the *_subtype* parameter. If the minor type could - not be guessed and *_subtype* was not given, then :exc:`TypeError` is raised. + A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the + :class:`MIMEAudio` class is used to create MIME message objects of major type + :mimetype:`audio`. *_audiodata* is a string containing the raw audio data. If + this data can be decoded by the standard Python module :mod:`sndhdr`, then the + subtype will be automatically included in the :mailheader:`Content-Type` header. + Otherwise you can explicitly specify the audio subtype via the *_subtype* + parameter. If the minor type could not be guessed and *_subtype* was not given, + then :exc:`TypeError` is raised. Optional *_encoder* is a callable (i.e. function) which will perform the actual encoding of the audio data for transport. This callable takes one argument, @@ -131,13 +135,14 @@ Module: :mod:`email.mime.image` - A subclass of :class:`MIMENonMultipart`, the :class:`MIMEImage` class is used to - create MIME message objects of major type :mimetype:`image`. *_imagedata* is a - string containing the raw image data. If this data can be decoded by the - standard Python module :mod:`imghdr`, then the subtype will be automatically - included in the :mailheader:`Content-Type` header. Otherwise you can explicitly - specify the image subtype via the *_subtype* parameter. If the minor type could - not be guessed and *_subtype* was not given, then :exc:`TypeError` is raised. + A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the + :class:`MIMEImage` class is used to create MIME message objects of major type + :mimetype:`image`. *_imagedata* is a string containing the raw image data. If + this data can be decoded by the standard Python module :mod:`imghdr`, then the + subtype will be automatically included in the :mailheader:`Content-Type` header. + Otherwise you can explicitly specify the image subtype via the *_subtype* + parameter. If the minor type could not be guessed and *_subtype* was not given, + then :exc:`TypeError` is raised. Optional *_encoder* is a callable (i.e. function) which will perform the actual encoding of the image data for transport. This callable takes one argument, @@ -147,7 +152,8 @@ object as necessary. The default encoding is base64. See the :mod:`email.encoders` module for a list of the built-in encoders. - *_params* are passed straight through to the :class:`MIMEBase` constructor. + *_params* are passed straight through to the :class:`~email.mime.base.MIMEBase` + constructor. .. currentmodule:: email.mime.message @@ -156,10 +162,11 @@ Module: :mod:`email.mime.message` - A subclass of :class:`MIMENonMultipart`, the :class:`MIMEMessage` class is used - to create MIME objects of main type :mimetype:`message`. *_msg* is used as the - payload, and must be an instance of class :class:`Message` (or a subclass - thereof), otherwise a :exc:`TypeError` is raised. + A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the + :class:`MIMEMessage` class is used to create MIME objects of main type + :mimetype:`message`. *_msg* is used as the payload, and must be an instance + of class :class:`~email.message.Message` (or a subclass thereof), otherwise + a :exc:`TypeError` is raised. Optional *_subtype* sets the subtype of the message; it defaults to :mimetype:`rfc822`. @@ -171,10 +178,11 @@ Module: :mod:`email.mime.text` - A subclass of :class:`MIMENonMultipart`, the :class:`MIMEText` class is used to - create MIME objects of major type :mimetype:`text`. *_text* is the string for - the payload. *_subtype* is the minor type and defaults to :mimetype:`plain`. - *_charset* is the character set of the text and is passed as a parameter to the - :class:`MIMENonMultipart` constructor; it defaults to ``us-ascii``. No guessing - or encoding is performed on the text data. + A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the + :class:`MIMEText` class is used to create MIME objects of major type + :mimetype:`text`. *_text* is the string for the payload. *_subtype* is the + minor type and defaults to :mimetype:`plain`. *_charset* is the character + set of the text and is passed as a parameter to the + :class:`~email.mime.nonmultipart.MIMENonMultipart` constructor; it defaults + to ``us-ascii``. No guessing or encoding is performed on the text data. Modified: python/branches/py3k/Doc/library/email.parser.rst ============================================================================== --- python/branches/py3k/Doc/library/email.parser.rst (original) +++ python/branches/py3k/Doc/library/email.parser.rst Mon Apr 27 18:46:17 2009 @@ -6,18 +6,18 @@ Message object structures can be created in one of two ways: they can be created -from whole cloth by instantiating :class:`Message` objects and stringing them -together via :meth:`attach` and :meth:`set_payload` calls, or they can be -created by parsing a flat text representation of the email message. +from whole cloth by instantiating :class:`~email.message.Message` objects and +stringing them together via :meth:`attach` and :meth:`set_payload` calls, or they +can be created by parsing a flat text representation of the email message. The :mod:`email` package provides a standard parser that understands most email document structures, including MIME documents. You can pass the parser a string -or a file object, and the parser will return to you the root :class:`Message` -instance of the object structure. For simple, non-MIME messages the payload of -this root object will likely be a string containing the text of the message. -For MIME messages, the root object will return ``True`` from its -:meth:`is_multipart` method, and the subparts can be accessed via the -:meth:`get_payload` and :meth:`walk` methods. +or a file object, and the parser will return to you the root +:class:`~email.message.Message` instance of the object structure. For simple, +non-MIME messages the payload of this root object will likely be a string +containing the text of the message. For MIME messages, the root object will +return ``True`` from its :meth:`is_multipart` method, and the subparts can be +accessed via the :meth:`get_payload` and :meth:`walk` methods. There are actually two parser interfaces available for use, the classic :class:`Parser` API and the incremental :class:`FeedParser` API. The classic @@ -31,8 +31,8 @@ Note that the parser can be extended in limited ways, and of course you can implement your own parser completely from scratch. There is no magical connection between the :mod:`email` package's bundled parser and the -:class:`Message` class, so your custom parser can create message object trees -any way it finds necessary. +:class:`~email.message.Message` class, so your custom parser can create message +object trees any way it finds necessary. FeedParser API @@ -101,8 +101,8 @@ The constructor for the :class:`Parser` class takes an optional argument *_class*. This must be a callable factory (such as a function or a class), and it is used whenever a sub-message object needs to be created. It defaults to - :class:`Message` (see :mod:`email.message`). The factory will be called without - arguments. + :class:`~email.message.Message` (see :mod:`email.message`). The factory will + be called without arguments. The optional *strict* flag is ignored. @@ -179,7 +179,8 @@ * All :mimetype:`multipart` type messages will be parsed as a container message object with a list of sub-message objects for their payload. The outer container message will return ``True`` for :meth:`is_multipart` and their - :meth:`get_payload` method will return the list of :class:`Message` subparts. + :meth:`get_payload` method will return the list of :class:`~email.message.Message` + subparts. * Most messages with a content type of :mimetype:`message/\*` (e.g. :mimetype:`message/delivery-status` and :mimetype:`message/rfc822`) will also be From python-checkins at python.org Mon Apr 27 18:48:18 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:48:18 +0200 (CEST) Subject: [Python-checkins] r72029 - python/branches/py3k Message-ID: <20090427164818.C28281E4017@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:48:18 2009 New Revision: 72029 Log: Blocked revisions 71787 via svnmerge ........ r71787 | georg.brandl | 2009-04-21 20:24:34 +0200 (Di, 21 Apr 2009) | 1 line #5751: fix escaping of \\n. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Mon Apr 27 18:49:42 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:49:42 +0200 (CEST) Subject: [Python-checkins] r72030 - in python/branches/py3k: Doc/library/functions.rst Doc/library/threading.rst Doc/library/turtle.rst Objects/abstract.c Message-ID: <20090427164942.6B3521E4017@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:49:41 2009 New Revision: 72030 Log: Merged revisions 71607,71653,71696,71771,71786 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71607 | benjamin.peterson | 2009-04-14 23:23:09 +0200 (Di, 14 Apr 2009) | 1 line tupel -> tuple ........ r71653 | raymond.hettinger | 2009-04-16 20:16:10 +0200 (Do, 16 Apr 2009) | 1 line Clarify the behavior of any() and all() with an empty iterable. ........ r71696 | georg.brandl | 2009-04-18 10:26:21 +0200 (Sa, 18 Apr 2009) | 1 line "not subscriptable" should be a bit more understandable than "unsubscriptable". ........ r71771 | raymond.hettinger | 2009-04-20 20:23:57 +0200 (Mo, 20 Apr 2009) | 1 line Fix typo ........ r71786 | georg.brandl | 2009-04-21 20:23:08 +0200 (Di, 21 Apr 2009) | 1 line #5757: fix copy-paste error in notify(). ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/functions.rst python/branches/py3k/Doc/library/threading.rst python/branches/py3k/Doc/library/turtle.rst python/branches/py3k/Objects/abstract.c Modified: python/branches/py3k/Doc/library/functions.rst ============================================================================== --- python/branches/py3k/Doc/library/functions.rst (original) +++ python/branches/py3k/Doc/library/functions.rst Mon Apr 27 18:49:41 2009 @@ -17,7 +17,8 @@ .. function:: all(iterable) - Return True if all elements of the *iterable* are true. Equivalent to:: + Return True if all elements of the *iterable* are true (or if the iterable + is empty). Equivalent to:: def all(iterable): for element in iterable: @@ -28,7 +29,8 @@ .. function:: any(iterable) - Return True if any element of the *iterable* is true. Equivalent to:: + Return True if any element of the *iterable* is true. If the iterable + is empty, return False. Equivalent to:: def any(iterable): for element in iterable: Modified: python/branches/py3k/Doc/library/threading.rst ============================================================================== --- python/branches/py3k/Doc/library/threading.rst (original) +++ python/branches/py3k/Doc/library/threading.rst Mon Apr 27 18:49:41 2009 @@ -537,12 +537,12 @@ .. method:: Condition.notify() - Wake up a thread waiting on this condition, if any. Wait until notified or until - a timeout occurs. If the calling thread has not acquired the lock when this - method is called, a :exc:`RuntimeError` is raised. + Wake up a thread waiting on this condition, if any. If the calling thread + has not acquired the lock when this method is called, a :exc:`RuntimeError` + is raised. - This method wakes up one of the threads waiting for the condition variable, if - any are waiting; it is a no-op if no threads are waiting. + This method wakes up one of the threads waiting for the condition variable, + if any are waiting; it is a no-op if no threads are waiting. The current implementation wakes up exactly one thread, if any are waiting. However, it's not safe to rely on this behavior. A future, optimized Modified: python/branches/py3k/Doc/library/turtle.rst ============================================================================== --- python/branches/py3k/Doc/library/turtle.rst (original) +++ python/branches/py3k/Doc/library/turtle.rst Mon Apr 27 18:49:41 2009 @@ -1220,9 +1220,9 @@ .. function:: screensize(canvwidth=None, canvheight=None, bg=None) - :param canvwidth: positive integer, new width of canvas in pixels - :param canvheight: positive integer, new height of canvas in pixels - :param bg: colorstring or color-tupel, new background color + :param canvwidth: positive integer, new width of canvas in pixels :param + canvheight: positive integer, new height of canvas in pixels :param bg: + colorstring or color-tuple, new background color If no arguments are given, return current (canvaswidth, canvasheight). Else resize the canvas the turtles are drawing on. Do not alter the drawing Modified: python/branches/py3k/Objects/abstract.c ============================================================================== --- python/branches/py3k/Objects/abstract.c (original) +++ python/branches/py3k/Objects/abstract.c Mon Apr 27 18:49:41 2009 @@ -135,7 +135,7 @@ "be integer, not '%.200s'", key); } - return type_error("'%.200s' object is unsubscriptable", o); + return type_error("'%.200s' object is not subscriptable", o); } int From python-checkins at python.org Mon Apr 27 18:50:10 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:50:10 +0200 (CEST) Subject: [Python-checkins] r72031 - in python/branches/py3k: Makefile.pre.in Message-ID: <20090427165010.5CC0A1E4017@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:50:10 2009 New Revision: 72031 Log: Merged revisions 71740 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71740 | benjamin.peterson | 2009-04-19 05:02:54 +0200 (So, 19 Apr 2009) | 1 line fix typo ........ Modified: python/branches/py3k/ (props changed) 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 Mon Apr 27 18:50:10 2009 @@ -850,7 +850,7 @@ sqlite3 sqlite3/test \ logging bsddb bsddb/test csv wsgiref urllib \ lib2to3 lib2to3/fixes lib2to3/pgen2 lib2to3/tests \ - lib2to3/tests/data lib2to3/tests/data/fixes lib2to3/tests/data/fixers/myfixes \ + lib2to3/tests/data lib2to3/tests/data/fixers lib2to3/tests/data/fixers/myfixes \ ctypes ctypes/test ctypes/macholib idlelib idlelib/Icons \ distutils distutils/command distutils/tests $(XMLLIBSUBDIRS) \ importlib importlib/test importlib/test/builtin \ From python-checkins at python.org Mon Apr 27 18:51:45 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:51:45 +0200 (CEST) Subject: [Python-checkins] r72032 - in python/branches/py3k: Doc/includes/mp_distributing.py Doc/library/__future__.rst Doc/library/json.rst Doc/library/tarfile.rst Doc/library/turtle.rst Doc/library/unittest.rst Doc/reference/simple_stmts.rst Message-ID: <20090427165145.64B141E4017@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:51:45 2009 New Revision: 72032 Log: Merged revisions 71814-71817,71901-71903 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71814 | georg.brandl | 2009-04-23 10:44:57 +0200 (Do, 23 Apr 2009) | 1 line #5820: fix bug in usage of getreader(). ........ r71815 | georg.brandl | 2009-04-23 10:49:39 +0200 (Do, 23 Apr 2009) | 1 line Fix rewrapping accident. ........ r71816 | georg.brandl | 2009-04-23 10:49:56 +0200 (Do, 23 Apr 2009) | 1 line #5813: add a reference to the "future statements" section. ........ r71817 | georg.brandl | 2009-04-23 10:52:03 +0200 (Do, 23 Apr 2009) | 1 line Add link to PEP 236. ........ r71901 | georg.brandl | 2009-04-25 16:50:25 +0200 (Sa, 25 Apr 2009) | 1 line #3320: fix spelling. ........ r71902 | georg.brandl | 2009-04-25 16:51:31 +0200 (Sa, 25 Apr 2009) | 1 line #5834: use "failure" instead of "error" because the two have different meanings in unittest context. ........ r71903 | georg.brandl | 2009-04-25 17:05:04 +0200 (Sa, 25 Apr 2009) | 1 line #5821: add some capabilities of TarFile's file-like object. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/includes/mp_distributing.py python/branches/py3k/Doc/library/__future__.rst python/branches/py3k/Doc/library/json.rst python/branches/py3k/Doc/library/tarfile.rst python/branches/py3k/Doc/library/turtle.rst python/branches/py3k/Doc/library/unittest.rst python/branches/py3k/Doc/reference/simple_stmts.rst Modified: python/branches/py3k/Doc/includes/mp_distributing.py ============================================================================== --- python/branches/py3k/Doc/includes/mp_distributing.py (original) +++ python/branches/py3k/Doc/includes/mp_distributing.py Mon Apr 27 18:51:45 2009 @@ -38,7 +38,7 @@ return _logger _logger = logging.getLogger('distributing') -_logger.propogate = 0 +_logger.propagate = 0 _formatter = logging.Formatter(util.DEFAULT_LOGGING_FORMAT) _handler = logging.StreamHandler() Modified: python/branches/py3k/Doc/library/__future__.rst ============================================================================== --- python/branches/py3k/Doc/library/__future__.rst (original) +++ python/branches/py3k/Doc/library/__future__.rst Mon Apr 27 18:51:45 2009 @@ -58,3 +58,7 @@ No feature description will ever be deleted from :mod:`__future__`. +.. seealso:: + + :ref:`future` + How the compiler treats future imports. Modified: python/branches/py3k/Doc/library/json.rst ============================================================================== --- python/branches/py3k/Doc/library/json.rst (original) +++ python/branches/py3k/Doc/library/json.rst Mon Apr 27 18:51:45 2009 @@ -173,7 +173,7 @@ If the contents of *fp* are encoded with an ASCII based encoding other than UTF-8 (e.g. latin-1), then an appropriate *encoding* name must be specified. Encodings that are not ASCII based (such as UCS-2) are not allowed, and - should be wrapped with ``codecs.getreader(fp)(encoding)``, or simply decoded + should be wrapped with ``codecs.getreader(encoding)(fp)``, or simply decoded to a :class:`unicode` object and passed to :func:`loads`. *object_hook* is an optional function that will be called with the result of Modified: python/branches/py3k/Doc/library/tarfile.rst ============================================================================== --- python/branches/py3k/Doc/library/tarfile.rst (original) +++ python/branches/py3k/Doc/library/tarfile.rst Mon Apr 27 18:51:45 2009 @@ -352,8 +352,9 @@ .. note:: - The file-like object is read-only and provides the following methods: - :meth:`read`, :meth:`readline`, :meth:`readlines`, :meth:`seek`, :meth:`tell`. + The file-like object is read-only. It provides the methods + :meth:`read`, :meth:`readline`, :meth:`readlines`, :meth:`seek`, :meth:`tell`, + and :meth:`close`, and also supports iteration over its lines. .. method:: TarFile.add(name, arcname=None, recursive=True, exclude=None) Modified: python/branches/py3k/Doc/library/turtle.rst ============================================================================== --- python/branches/py3k/Doc/library/turtle.rst (original) +++ python/branches/py3k/Doc/library/turtle.rst Mon Apr 27 18:51:45 2009 @@ -1220,9 +1220,9 @@ .. function:: screensize(canvwidth=None, canvheight=None, bg=None) - :param canvwidth: positive integer, new width of canvas in pixels :param - canvheight: positive integer, new height of canvas in pixels :param bg: - colorstring or color-tuple, new background color + :param canvwidth: positive integer, new width of canvas in pixels + :param canvheight: positive integer, new height of canvas in pixels + :param bg: colorstring or color-tuple, new background color If no arguments are given, return current (canvaswidth, canvasheight). Else resize the canvas the turtles are drawing on. Do not alter the drawing Modified: python/branches/py3k/Doc/library/unittest.rst ============================================================================== --- python/branches/py3k/Doc/library/unittest.rst (original) +++ python/branches/py3k/Doc/library/unittest.rst Mon Apr 27 18:51:45 2009 @@ -608,7 +608,7 @@ assert_(expr[, msg]) failUnless(expr[, msg]) - Signal a test failure if *expr* is false; the explanation for the error + Signal a test failure if *expr* is false; the explanation for the failure will be *msg* if given, otherwise it will be :const:`None`. .. deprecated:: 3.1 Modified: python/branches/py3k/Doc/reference/simple_stmts.rst ============================================================================== --- python/branches/py3k/Doc/reference/simple_stmts.rst (original) +++ python/branches/py3k/Doc/reference/simple_stmts.rst Mon Apr 27 18:51:45 2009 @@ -897,6 +897,11 @@ a future statement, it will be in effect in the interactive session started after the script is executed. +.. seealso:: + + :pep:`236` - Back to the __future__ + The original proposal for the __future__ mechanism. + .. _global: From python-checkins at python.org Mon Apr 27 18:52:18 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:52:18 +0200 (CEST) Subject: [Python-checkins] r72033 - python/branches/py3k Message-ID: <20090427165218.556371E413F@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:52:18 2009 New Revision: 72033 Log: Blocked revisions 71893,71904 via svnmerge ........ r71893 | jeroen.ruigrok | 2009-04-25 15:58:58 +0200 (Sa, 25 Apr 2009) | 2 lines Reformat file prior to editing. ........ r71904 | georg.brandl | 2009-04-25 17:11:29 +0200 (Sa, 25 Apr 2009) | 1 line #5841: add deprecation py3k warning and notice in the docs for commands module. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Mon Apr 27 18:54:23 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:54:23 +0200 (CEST) Subject: [Python-checkins] r72034 - in python/branches/py3k: Doc/c-api/conversion.rst Message-ID: <20090427165423.1EBF71E4017@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:54:22 2009 New Revision: 72034 Log: Merged revisions 71955,71962 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71955 | georg.brandl | 2009-04-26 08:01:04 +0200 (So, 26 Apr 2009) | 1 line Mostly formatting nits, and "and-ed together" -> "or-ed together" flags. ........ r71962 | eric.smith | 2009-04-26 12:05:11 +0200 (So, 26 Apr 2009) | 1 line Note that the caller is resposible for freeing the result of PyOS_double_to_string. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/c-api/conversion.rst Modified: python/branches/py3k/Doc/c-api/conversion.rst ============================================================================== --- python/branches/py3k/Doc/c-api/conversion.rst (original) +++ python/branches/py3k/Doc/c-api/conversion.rst Mon Apr 27 18:54:22 2009 @@ -63,7 +63,7 @@ See the Unix man page :manpage:`strtod(2)` for details. -.. cfunction:: char * PyOS_ascii_formatd(char *buffer, size_t buf_len, const char *format, double d) +.. cfunction:: char* PyOS_ascii_formatd(char *buffer, size_t buf_len, const char *format, double d) Convert a :ctype:`double` to a string using the ``'.'`` as the decimal separator. *format* is a :cfunc:`printf`\ -style format string specifying the @@ -118,13 +118,13 @@ See the Unix man page :manpage:`atof(2)` for details. -.. cfunction:: char * PyOS_stricmp(char *s1, char *s2) +.. cfunction:: char* PyOS_stricmp(char *s1, char *s2) Case insensitive comparison of strings. The function works almost identically to :cfunc:`strcmp` except that it ignores the case. -.. cfunction:: char * PyOS_strnicmp(char *s1, char *s2, Py_ssize_t size) +.. cfunction:: char* PyOS_strnicmp(char *s1, char *s2, Py_ssize_t size) Case insensitive comparison of strings. The function works almost identically to :cfunc:`strncmp` except that it ignores the case. From python-checkins at python.org Mon Apr 27 18:58:05 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 18:58:05 +0200 (CEST) Subject: [Python-checkins] r72035 - in python/branches/py3k: Lib/idlelib/NEWS.txt Lib/idlelib/OutputWindow.py Message-ID: <20090427165805.A3E611E4017@bag.python.org> Author: georg.brandl Date: Mon Apr 27 18:58:05 2009 New Revision: 72035 Log: Merged revisions 71995 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71995 | kurt.kaiser | 2009-04-27 01:22:11 +0200 (Mo, 27 Apr 2009) | 2 lines Right click 'go to file/line' not working if spaces in path. Bug 5559. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/idlelib/NEWS.txt python/branches/py3k/Lib/idlelib/OutputWindow.py Modified: python/branches/py3k/Lib/idlelib/NEWS.txt ============================================================================== --- python/branches/py3k/Lib/idlelib/NEWS.txt (original) +++ python/branches/py3k/Lib/idlelib/NEWS.txt Mon Apr 27 18:58:05 2009 @@ -30,6 +30,9 @@ *Release date: XX-XXX-2009* +- OutputWindow/PyShell right click menu "Go to file/line" wasn't working with + file paths containing spaces. Bug 5559. + - Windows: Version string for the .chm help file changed, file not being accessed Patch 5783 Guilherme Polo Modified: python/branches/py3k/Lib/idlelib/OutputWindow.py ============================================================================== --- python/branches/py3k/Lib/idlelib/OutputWindow.py (original) +++ python/branches/py3k/Lib/idlelib/OutputWindow.py Mon Apr 27 18:58:05 2009 @@ -58,6 +58,7 @@ r'file "([^"]*)", line (\d+)', r'([^\s]+)\((\d+)\)', r'([^\s]+):\s*(\d+):', + r'^\s*(\S+.*?):\s*(\d+):', # Win path with spaces, trim leading spaces ] file_line_progs = None @@ -91,17 +92,17 @@ def _file_line_helper(self, line): for prog in self.file_line_progs: - m = prog.search(line) - if m: - break + match = prog.search(line) + if match: + filename, lineno = match.group(1, 2) + try: + f = open(filename, "r") + f.close() + break + except IOError: + continue else: return None - filename, lineno = m.group(1, 2) - try: - f = open(filename, "r") - f.close() - except IOError: - return None try: return filename, int(lineno) except TypeError: @@ -134,19 +135,3 @@ text.tag_configure(tag, **cnf) text.tag_raise('sel') self.write = self.owin.write - -#class PseudoFile: -# -# def __init__(self, owin, tags, mark="end"): -# self.owin = owin -# self.tags = tags -# self.mark = mark - -# def write(self, s): -# self.owin.write(s, self.tags, self.mark) - -# def writelines(self, l): -# map(self.write, l) - -# def flush(self): -# pass From python-checkins at python.org Mon Apr 27 19:04:23 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 19:04:23 +0200 (CEST) Subject: [Python-checkins] r72036 - python/trunk/Doc/library/unittest.rst Message-ID: <20090427170423.9DD9A1E4017@bag.python.org> Author: georg.brandl Date: Mon Apr 27 19:04:23 2009 New Revision: 72036 Log: #5848: small unittest doc patch. Modified: python/trunk/Doc/library/unittest.rst Modified: python/trunk/Doc/library/unittest.rst ============================================================================== --- python/trunk/Doc/library/unittest.rst (original) +++ python/trunk/Doc/library/unittest.rst Mon Apr 27 19:04:23 2009 @@ -955,7 +955,6 @@ along with the method name. .. versionchanged:: 2.7 - In earlier versions this only returned the first line of the test method's docstring, if available or the :const:`None`. That led to undesirable behavior of not printing the test name when someone was @@ -1047,6 +1046,20 @@ Return the number of tests represented by this test object, including all individual tests and sub-suites. + + .. method:: __iter__() + + Tests grouped by a :class:`TestSuite` are always accessed by iteration. + Subclasses can lazily provide tests by overriding :meth:`__iter__`. Note + that this method maybe called several times on a single suite + (for example when counting tests or comparing for equality) + so the tests returned must be the same for repeated iterations. + + .. versionchanged:: 2.7 + In earlier versions the :class:`TestSuite` accessed tests directly rather + than through iteration, so overriding :meth:`__iter__` wasn't sufficient + for providing tests. + In the typical usage of a :class:`TestSuite` object, the :meth:`run` method is invoked by a :class:`TestRunner` rather than by the end-user test harness. @@ -1194,7 +1207,6 @@ unexpected exception. .. versionchanged:: 2.2 - Contains formatted tracebacks instead of :func:`sys.exc_info` results. @@ -1206,7 +1218,6 @@ :meth:`TestCase.assert\*` methods. .. versionchanged:: 2.2 - Contains formatted tracebacks instead of :func:`sys.exc_info` results. .. attribute:: skipped @@ -1346,6 +1357,12 @@ has a few configurable parameters, but is essentially very simple. Graphical applications which run test suites should provide alternate implementations. + .. method:: _makeResult() + + This method returns the instance of ``TestResult`` used by :meth:`run`. + It is not intended to be called directly, but can be overridden in + subclasses to provide a custom ``TestResult``. + .. function:: main([module[, defaultTest[, argv[, testRunner[, testLoader]]]]]) From python-checkins at python.org Mon Apr 27 19:09:53 2009 From: python-checkins at python.org (georg.brandl) Date: Mon, 27 Apr 2009 19:09:53 +0200 (CEST) Subject: [Python-checkins] r72037 - python/trunk/Doc/c-api/init.rst Message-ID: <20090427170953.9CC981E41DE@bag.python.org> Author: georg.brandl Date: Mon Apr 27 19:09:53 2009 New Revision: 72037 Log: #5840: dont claim we dont support TLS. Modified: python/trunk/Doc/c-api/init.rst Modified: python/trunk/Doc/c-api/init.rst ============================================================================== --- python/trunk/Doc/c-api/init.rst (original) +++ python/trunk/Doc/c-api/init.rst Mon Apr 27 19:09:53 2009 @@ -419,10 +419,9 @@ The Python interpreter needs to keep some bookkeeping information separate per thread --- for this it uses a data structure called :ctype:`PyThreadState`. There's one global variable, however: the pointer to the current -:ctype:`PyThreadState` structure. While most thread packages have a way to -store "per-thread global data," Python's internal platform independent thread -abstraction doesn't support this yet. Therefore, the current thread state must -be manipulated explicitly. +:ctype:`PyThreadState` structure. Before the addition of :dfn:`thread-local +storage` (:dfn:`TLS`) the current thread state had to be manipulated +explicitly. This is easy enough in most cases. Most code manipulating the global interpreter lock has the following simple structure:: From python-checkins at python.org Mon Apr 27 19:22:36 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 27 Apr 2009 19:22:36 +0200 (CEST) Subject: [Python-checkins] r72038 - python/trunk/Doc/library/traceback.rst Message-ID: <20090427172236.D3E801E41D0@bag.python.org> Author: r.david.murray Date: Mon Apr 27 19:22:36 2009 New Revision: 72038 Log: Make sys.xxx variable references into links, note that print_last only works when an exception gets to the interactive prompt, and update the examples after testing. The last one is now a valid Sphinx doctest, but of the preceding two one can't be made a doctest and the other one I'm postponing to 3.x because sphinx handles doctests as Unicode strings and that makes the 2.x output confusing. Modified: python/trunk/Doc/library/traceback.rst Modified: python/trunk/Doc/library/traceback.rst ============================================================================== --- python/trunk/Doc/library/traceback.rst (original) +++ python/trunk/Doc/library/traceback.rst Mon Apr 27 19:22:36 2009 @@ -14,7 +14,7 @@ .. index:: object: traceback The module uses traceback objects --- this is the object type that is stored in -the variables ``sys.exc_traceback`` (deprecated) and ``sys.last_traceback`` and +the variables :data:`sys.exc_traceback` (deprecated) and :data:`sys.last_traceback` and returned as the third item from :func:`sys.exc_info`. The module defines the following functions: @@ -58,7 +58,8 @@ .. function:: print_last([limit[, file]]) This is a shorthand for ``print_exception(sys.last_type, sys.last_value, - sys.last_traceback, limit, file)``. + sys.last_traceback, limit, file)``. In general it will work only after + an exception has reached an interactive prompt (see :data:`sys.last_type`). .. function:: print_stack([f[, limit[, file]]]) @@ -195,27 +196,25 @@ print "*** format_tb:" print repr(traceback.format_tb(exceptionTraceback)) print "*** tb_lineno:", traceback.tb_lineno(exceptionTraceback) - print "*** print_last:" - traceback.print_last() The output for the example would look similar to this:: *** print_tb: - File "", line 9, in + File "", line 10, in lumberjack() *** print_exception: Traceback (most recent call last): - File "", line 9, in + File "", line 10, in lumberjack() - File "", line 3, in lumberjack + File "", line 4, in lumberjack bright_side_of_death() IndexError: tuple index out of range *** print_exc: Traceback (most recent call last): - File "", line 9, in + File "", line 10, in lumberjack() - File "", line 3, in lumberjack + File "", line 4, in lumberjack bright_side_of_death() IndexError: tuple index out of range *** format_exc, first and last line: @@ -223,27 +222,19 @@ IndexError: tuple index out of range *** format_exception: ['Traceback (most recent call last):\n', - ' File "", line 9, in \n lumberjack()\n', - ' File "", line 3, in lumberjack\n bright_side_of_death()\n', - ' File "", line 6, in bright_side_of_death\n return tuple()[0]\n', + ' File "", line 10, in \n lumberjack()\n', + ' File "", line 4, in lumberjack\n bright_side_of_death()\n', + ' File "", line 7, in bright_side_of_death\n return tuple()[0]\n', 'IndexError: tuple index out of range\n'] *** extract_tb: - [('', 9, '', 'lumberjack()'), - ('', 3, 'lumberjack', 'bright_side_of_death()'), - ('', 6, 'bright_side_of_death', 'return tuple()[0]')] + [('', 10, '', 'lumberjack()'), + ('', 4, 'lumberjack', 'bright_side_of_death()'), + (u'', 7, 'bright_side_of_death', 'return tuple()[0]')] *** format_tb: - [' File "", line 9, in \n lumberjack()\n', - ' File "", line 3, in lumberjack\n bright_side_of_death()\n', - ' File "", line 6, in bright_side_of_death\n return tuple()[0]\n'] - *** tb_lineno: 2 - *** print_last: - Traceback (most recent call last): - File "", line 9, in - lumberjack() - File "", line 3, in lumberjack - bright_side_of_death() - IndexError: tuple index out of range - + [' File "", line 10, in \n lumberjack()\n', + ' File "", line 4, in lumberjack\n bright_side_of_death()\n', + ' File "", line 7, in bright_side_of_death\n return tuple()[0]\n'] + *** tb_lineno: 10 The following example shows the different ways to print and format the stack:: @@ -271,7 +262,10 @@ ' File "", line 8, in lumberstack\n print repr(traceback.format_stack())\n'] -This last example demonstrates the final few formatting functions:: +This last example demonstrates the final few formatting functions: + +.. doctest:: + :options: +NORMALIZE_WHITESPACE >>> import traceback >>> traceback.format_list([('spam.py', 3, '', 'spam.eggs()'), From buildbot at python.org Mon Apr 27 19:43:01 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 27 Apr 2009 17:43:01 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090427174301.8A4791E4017@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/588 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: 4 tests failed: test_importlib test_os test_posix test_time Traceback (most recent call last): File "./Lib/test/regrtest.py", line 620, in runtest_inner File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_importlib.py", line 6, in test_main run_unittest(importlib.test.test_suite('importlib.test')) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/__init__.py", line 22, in test_suite package_tests = getattr(sys.modules[package_name], 'test_suite')() File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/source/__init__.py", line 8, in test_suite return importlib.test.test_suite('importlib.test.source', directory) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/__init__.py", line 16, in test_suite __import__(module_name, level=0) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/source/test_case_sensitivity.py", line 12, in class CaseSensitivityTest(unittest.TestCase): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/util.py", line 13, in case_insensitive_tests original_name = os.listdir('.')[0] IndexError: list index out of range ====================================================================== FAIL: test_update2 (test.test_os.EnvironTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_os.py", line 382, in test_update2 self.assertEquals(value, "World") AssertionError: '' != 'World' ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 251, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 177, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_tzset (test.test_time.TimeTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_time.py", line 157, in test_tzset time.gmtime(xmas2002), time.localtime(xmas2002) AssertionError: time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) != time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=1, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) sincerely, -The Buildbot From python-checkins at python.org Mon Apr 27 20:38:20 2009 From: python-checkins at python.org (r.david.murray) Date: Mon, 27 Apr 2009 20:38:20 +0200 (CEST) Subject: [Python-checkins] r72039 - in python/branches/py3k: Doc/library/traceback.rst Message-ID: <20090427183820.2AD501E401A@bag.python.org> Author: r.david.murray Date: Mon Apr 27 20:38:19 2009 New Revision: 72039 Log: Third to last example is now marked as a test, but I can't actually test it yet since sphinx can't run the doctests using python3. Merged revisions 72038 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72038 | r.david.murray | 2009-04-27 13:22:36 -0400 (Mon, 27 Apr 2009) | 8 lines Make sys.xxx variable references into links, note that print_last only works when an exception gets to the interactive prompt, and update the examples after testing. The last one is now a valid Sphinx doctest, but of the preceding two one can't be made a doctest and the other one I'm postponing to 3.x because sphinx handles doctests as Unicode strings and that makes the 2.x output confusing. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/traceback.rst Modified: python/branches/py3k/Doc/library/traceback.rst ============================================================================== --- python/branches/py3k/Doc/library/traceback.rst (original) +++ python/branches/py3k/Doc/library/traceback.rst Mon Apr 27 20:38:19 2009 @@ -14,7 +14,7 @@ .. index:: object: traceback The module uses traceback objects --- this is the object type that is stored in -the ``sys.last_traceback`` variable and returned as the third item from +the :data:`sys.last_traceback` variable and returned as the third item from :func:`sys.exc_info`. The module defines the following functions: @@ -55,7 +55,8 @@ .. function:: print_last([limit[, file[, chain]]]) This is a shorthand for ``print_exception(sys.last_type, sys.last_value, - sys.last_traceback, limit, file)``. + sys.last_traceback, limit, file)``. In general it will work only after + an exception has reached an interactive prompt (see :data:`sys.last_type`). .. function:: print_stack([f[, limit[, file]]]) @@ -157,7 +158,9 @@ The following example demonstrates the different ways to print and format the -exception and traceback:: +exception and traceback: + +.. testcode:: import sys, traceback @@ -190,27 +193,27 @@ print("*** format_tb:") print(repr(traceback.format_tb(exceptionTraceback))) print("*** tb_lineno:", traceback.tb_lineno(exceptionTraceback)) - print("*** print_last:") - traceback.print_last() +The output for the example would look similar to this: -The output for the example would look similar to this:: +.. testoutput:: + :options: +NORMALIZE_WHITESPACE *** print_tb: - File "", line 9, in + File "", line 10, in lumberjack() *** print_exception: Traceback (most recent call last): - File "", line 9, in + File "", line 10, in lumberjack() - File "", line 3, in lumberjack + File "", line 4, in lumberjack bright_side_of_death() IndexError: tuple index out of range *** print_exc: Traceback (most recent call last): - File "", line 9, in + File "", line 10, in lumberjack() - File "", line 3, in lumberjack + File "", line 4, in lumberjack bright_side_of_death() IndexError: tuple index out of range *** format_exc, first and last line: @@ -218,26 +221,19 @@ IndexError: tuple index out of range *** format_exception: ['Traceback (most recent call last):\n', - ' File "", line 9, in \n lumberjack()\n', - ' File "", line 3, in lumberjack\n bright_side_of_death()\n', - ' File "", line 6, in bright_side_of_death\n return tuple()[0]\n', + ' File "", line 10, in \n lumberjack()\n', + ' File "", line 4, in lumberjack\n bright_side_of_death()\n', + ' File "", line 7, in bright_side_of_death\n return tuple()[0]\n', 'IndexError: tuple index out of range\n'] *** extract_tb: - [('', 9, '', 'lumberjack()'), - ('', 3, 'lumberjack', 'bright_side_of_death()'), - ('', 6, 'bright_side_of_death', 'return tuple()[0]')] + [('', 10, '', 'lumberjack()'), + ('', 4, 'lumberjack', 'bright_side_of_death()'), + (u'', 7, 'bright_side_of_death', 'return tuple()[0]')] *** format_tb: - [' File "", line 9, in \n lumberjack()\n', - ' File "", line 3, in lumberjack\n bright_side_of_death()\n', - ' File "", line 6, in bright_side_of_death\n return tuple()[0]\n'] - *** tb_lineno: 2 - *** print_last: - Traceback (most recent call last): - File "", line 9, in - lumberjack() - File "", line 3, in lumberjack - bright_side_of_death() - IndexError: tuple index out of range + [' File "", line 10, in \n lumberjack()\n', + ' File "", line 4, in lumberjack\n bright_side_of_death()\n', + ' File "", line 7, in bright_side_of_death\n return tuple()[0]\n'] + *** tb_lineno: 10 The following example shows the different ways to print and format the stack:: @@ -266,7 +262,10 @@ ' File "", line 8, in lumberstack\n print(repr(traceback.format_stack()))\n'] -This last example demonstrates the final few formatting functions:: +This last example demonstrates the final few formatting functions: + +.. doctest:: + :options: +NORMALIZE_WHITESPACE >>> import traceback >>> traceback.format_list([('spam.py', 3, '', 'spam.eggs()'), From python-checkins at python.org Mon Apr 27 21:04:37 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 27 Apr 2009 21:04:37 +0200 (CEST) Subject: [Python-checkins] r72040 - in python/trunk: Include/Python.h Include/bytes_methods.h Include/pyctype.h Makefile.pre.in Misc/NEWS Objects/bytearrayobject.c Objects/bytes_methods.c Objects/stringlib/stringdefs.h PC/VC6/pythoncore.dsp PC/VS7.1/pythoncore.vcproj PC/VS8.0/pythoncore.vcproj PC/os2emx/Makefile PCbuild/pythoncore.vcproj Python/pyctype.c Python/pystrtod.c Message-ID: <20090427190437.C4F131E4042@bag.python.org> Author: eric.smith Date: Mon Apr 27 21:04:37 2009 New Revision: 72040 Log: Issue #5793: rationalize isdigit / isalpha / tolower, etc. Will port to py3k. Should fix Windows buildbot errors. Added: python/trunk/Include/pyctype.h python/trunk/Python/pyctype.c Modified: python/trunk/Include/Python.h python/trunk/Include/bytes_methods.h python/trunk/Makefile.pre.in python/trunk/Misc/NEWS python/trunk/Objects/bytearrayobject.c python/trunk/Objects/bytes_methods.c python/trunk/Objects/stringlib/stringdefs.h python/trunk/PC/VC6/pythoncore.dsp python/trunk/PC/VS7.1/pythoncore.vcproj python/trunk/PC/VS8.0/pythoncore.vcproj python/trunk/PC/os2emx/Makefile python/trunk/PCbuild/pythoncore.vcproj python/trunk/Python/pystrtod.c Modified: python/trunk/Include/Python.h ============================================================================== --- python/trunk/Include/Python.h (original) +++ python/trunk/Include/Python.h Mon Apr 27 21:04:37 2009 @@ -134,6 +134,7 @@ #include "compile.h" #include "eval.h" +#include "pyctype.h" #include "pystrtod.h" #include "pystrcmp.h" Modified: python/trunk/Include/bytes_methods.h ============================================================================== --- python/trunk/Include/bytes_methods.h (original) +++ python/trunk/Include/bytes_methods.h Mon Apr 27 21:04:37 2009 @@ -34,23 +34,15 @@ extern const char _Py_capitalize__doc__[]; extern const char _Py_swapcase__doc__[]; -#define FLAG_LOWER 0x01 -#define FLAG_UPPER 0x02 -#define FLAG_ALPHA (FLAG_LOWER|FLAG_UPPER) -#define FLAG_DIGIT 0x04 -#define FLAG_ALNUM (FLAG_ALPHA|FLAG_DIGIT) -#define FLAG_SPACE 0x08 -#define FLAG_XDIGIT 0x10 - -extern const unsigned int _Py_ctype_table[256]; - -#define ISLOWER(c) (_Py_ctype_table[Py_CHARMASK(c)] & FLAG_LOWER) -#define ISUPPER(c) (_Py_ctype_table[Py_CHARMASK(c)] & FLAG_UPPER) -#define ISALPHA(c) (_Py_ctype_table[Py_CHARMASK(c)] & FLAG_ALPHA) -#define ISDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & FLAG_DIGIT) -#define ISXDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & FLAG_XDIGIT) -#define ISALNUM(c) (_Py_ctype_table[Py_CHARMASK(c)] & FLAG_ALNUM) -#define ISSPACE(c) (_Py_ctype_table[Py_CHARMASK(c)] & FLAG_SPACE) +/* These are left in for backward compatibility and will be removed + in 2.8/3.2 */ +#define ISLOWER(c) Py_ISLOWER(c) +#define ISUPPER(c) Py_ISUPPER(c) +#define ISALPHA(c) Py_ISALPHA(c) +#define ISDIGIT(c) Py_ISDIGIT(c) +#define ISXDIGIT(c) Py_ISXDIGIT(c) +#define ISALNUM(c) Py_ISALNUM(c) +#define ISSPACE(c) Py_ISSPACE(c) #undef islower #define islower(c) undefined_islower(c) @@ -67,11 +59,10 @@ #undef isspace #define isspace(c) undefined_isspace(c) -extern const unsigned char _Py_ctype_tolower[256]; -extern const unsigned char _Py_ctype_toupper[256]; - -#define TOLOWER(c) (_Py_ctype_tolower[Py_CHARMASK(c)]) -#define TOUPPER(c) (_Py_ctype_toupper[Py_CHARMASK(c)]) +/* These are left in for backward compatibility and will be removed + in 2.8/3.2 */ +#define TOLOWER(c) Py_TOLOWER(c) +#define TOUPPER(c) Py_TOUPPER(c) #undef tolower #define tolower(c) undefined_tolower(c) Added: python/trunk/Include/pyctype.h ============================================================================== --- (empty file) +++ python/trunk/Include/pyctype.h Mon Apr 27 21:04:37 2009 @@ -0,0 +1,28 @@ +#ifndef PYCTYPE_H +#define PYCTYPE_H + +#define PY_CTF_LOWER 0x01 +#define PY_CTF_UPPER 0x02 +#define PY_CTF_ALPHA (PY_CTF_LOWER|PY_CTF_UPPER) +#define PY_CTF_DIGIT 0x04 +#define PY_CTF_ALNUM (PY_CTF_ALPHA|PY_CTF_DIGIT) +#define PY_CTF_SPACE 0x08 +#define PY_CTF_XDIGIT 0x10 + +extern const unsigned int _Py_ctype_table[256]; + +#define Py_ISLOWER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_LOWER) +#define Py_ISUPPER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_UPPER) +#define Py_ISALPHA(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALPHA) +#define Py_ISDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_DIGIT) +#define Py_ISXDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_XDIGIT) +#define Py_ISALNUM(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALNUM) +#define Py_ISSPACE(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_SPACE) + +extern const unsigned char _Py_ctype_tolower[256]; +extern const unsigned char _Py_ctype_toupper[256]; + +#define Py_TOLOWER(c) (_Py_ctype_tolower[Py_CHARMASK(c)]) +#define Py_TOUPPER(c) (_Py_ctype_toupper[Py_CHARMASK(c)]) + +#endif /* !PYCTYPE_H */ Modified: python/trunk/Makefile.pre.in ============================================================================== --- python/trunk/Makefile.pre.in (original) +++ python/trunk/Makefile.pre.in Mon Apr 27 21:04:37 2009 @@ -275,6 +275,7 @@ Python/mysnprintf.o \ Python/peephole.o \ Python/pyarena.o \ + Python/pyctype.o \ Python/pyfpe.o \ Python/pymath.o \ Python/pystate.o \ @@ -633,6 +634,7 @@ Include/pgen.h \ Include/pgenheaders.h \ Include/pyarena.h \ + Include/pyctype.h \ Include/pydebug.h \ Include/pyerrors.h \ Include/pyfpe.h \ Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Apr 27 21:04:37 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #5793: Rationalize isdigit / isalpha / tolower, etc. Includes + new Py_ISDIGIT / Py_ISALPHA / Py_TOLOWER, etc. in pctypes.h. + - Issue #4971: Fix titlecase for characters that are their own titlecase, but not their own uppercase. Modified: python/trunk/Objects/bytearrayobject.c ============================================================================== --- python/trunk/Objects/bytearrayobject.c (original) +++ python/trunk/Objects/bytearrayobject.c Mon Apr 27 21:04:37 2009 @@ -2244,16 +2244,16 @@ for (i = j = 0; i < len; ) { /* find a token */ - while (i < len && ISSPACE(s[i])) + while (i < len && Py_ISSPACE(s[i])) i++; j = i; - while (i < len && !ISSPACE(s[i])) + while (i < len && !Py_ISSPACE(s[i])) i++; if (j < i) { if (maxcount-- <= 0) break; SPLIT_ADD(s, j, i); - while (i < len && ISSPACE(s[i])) + while (i < len && Py_ISSPACE(s[i])) i++; j = i; } @@ -2478,16 +2478,16 @@ for (i = j = len - 1; i >= 0; ) { /* find a token */ - while (i >= 0 && ISSPACE(s[i])) + while (i >= 0 && Py_ISSPACE(s[i])) i--; j = i; - while (i >= 0 && !ISSPACE(s[i])) + while (i >= 0 && !Py_ISSPACE(s[i])) i--; if (j > i) { if (maxcount-- <= 0) break; SPLIT_ADD(s, i + 1, j + 1); - while (i >= 0 && ISSPACE(s[i])) + while (i >= 0 && Py_ISSPACE(s[i])) i--; j = i; } @@ -3054,11 +3054,11 @@ static int hex_digit_to_int(char c) { - if (ISDIGIT(c)) + if (Py_ISDIGIT(c)) return c - '0'; else { - if (ISUPPER(c)) - c = TOLOWER(c); + if (Py_ISUPPER(c)) + c = Py_TOLOWER(c); if (c >= 'a' && c <= 'f') return c - 'a' + 10; } Modified: python/trunk/Objects/bytes_methods.c ============================================================================== --- python/trunk/Objects/bytes_methods.c (original) +++ python/trunk/Objects/bytes_methods.c Mon Apr 27 21:04:37 2009 @@ -1,219 +1,6 @@ #include "Python.h" #include "bytes_methods.h" -/* Our own locale-independent ctype.h-like macros */ - -const unsigned int _Py_ctype_table[256] = { - 0, /* 0x0 '\x00' */ - 0, /* 0x1 '\x01' */ - 0, /* 0x2 '\x02' */ - 0, /* 0x3 '\x03' */ - 0, /* 0x4 '\x04' */ - 0, /* 0x5 '\x05' */ - 0, /* 0x6 '\x06' */ - 0, /* 0x7 '\x07' */ - 0, /* 0x8 '\x08' */ - FLAG_SPACE, /* 0x9 '\t' */ - FLAG_SPACE, /* 0xa '\n' */ - FLAG_SPACE, /* 0xb '\v' */ - FLAG_SPACE, /* 0xc '\f' */ - FLAG_SPACE, /* 0xd '\r' */ - 0, /* 0xe '\x0e' */ - 0, /* 0xf '\x0f' */ - 0, /* 0x10 '\x10' */ - 0, /* 0x11 '\x11' */ - 0, /* 0x12 '\x12' */ - 0, /* 0x13 '\x13' */ - 0, /* 0x14 '\x14' */ - 0, /* 0x15 '\x15' */ - 0, /* 0x16 '\x16' */ - 0, /* 0x17 '\x17' */ - 0, /* 0x18 '\x18' */ - 0, /* 0x19 '\x19' */ - 0, /* 0x1a '\x1a' */ - 0, /* 0x1b '\x1b' */ - 0, /* 0x1c '\x1c' */ - 0, /* 0x1d '\x1d' */ - 0, /* 0x1e '\x1e' */ - 0, /* 0x1f '\x1f' */ - FLAG_SPACE, /* 0x20 ' ' */ - 0, /* 0x21 '!' */ - 0, /* 0x22 '"' */ - 0, /* 0x23 '#' */ - 0, /* 0x24 '$' */ - 0, /* 0x25 '%' */ - 0, /* 0x26 '&' */ - 0, /* 0x27 "'" */ - 0, /* 0x28 '(' */ - 0, /* 0x29 ')' */ - 0, /* 0x2a '*' */ - 0, /* 0x2b '+' */ - 0, /* 0x2c ',' */ - 0, /* 0x2d '-' */ - 0, /* 0x2e '.' */ - 0, /* 0x2f '/' */ - FLAG_DIGIT|FLAG_XDIGIT, /* 0x30 '0' */ - FLAG_DIGIT|FLAG_XDIGIT, /* 0x31 '1' */ - FLAG_DIGIT|FLAG_XDIGIT, /* 0x32 '2' */ - FLAG_DIGIT|FLAG_XDIGIT, /* 0x33 '3' */ - FLAG_DIGIT|FLAG_XDIGIT, /* 0x34 '4' */ - FLAG_DIGIT|FLAG_XDIGIT, /* 0x35 '5' */ - FLAG_DIGIT|FLAG_XDIGIT, /* 0x36 '6' */ - FLAG_DIGIT|FLAG_XDIGIT, /* 0x37 '7' */ - FLAG_DIGIT|FLAG_XDIGIT, /* 0x38 '8' */ - FLAG_DIGIT|FLAG_XDIGIT, /* 0x39 '9' */ - 0, /* 0x3a ':' */ - 0, /* 0x3b ';' */ - 0, /* 0x3c '<' */ - 0, /* 0x3d '=' */ - 0, /* 0x3e '>' */ - 0, /* 0x3f '?' */ - 0, /* 0x40 '@' */ - FLAG_UPPER|FLAG_XDIGIT, /* 0x41 'A' */ - FLAG_UPPER|FLAG_XDIGIT, /* 0x42 'B' */ - FLAG_UPPER|FLAG_XDIGIT, /* 0x43 'C' */ - FLAG_UPPER|FLAG_XDIGIT, /* 0x44 'D' */ - FLAG_UPPER|FLAG_XDIGIT, /* 0x45 'E' */ - FLAG_UPPER|FLAG_XDIGIT, /* 0x46 'F' */ - FLAG_UPPER, /* 0x47 'G' */ - FLAG_UPPER, /* 0x48 'H' */ - FLAG_UPPER, /* 0x49 'I' */ - FLAG_UPPER, /* 0x4a 'J' */ - FLAG_UPPER, /* 0x4b 'K' */ - FLAG_UPPER, /* 0x4c 'L' */ - FLAG_UPPER, /* 0x4d 'M' */ - FLAG_UPPER, /* 0x4e 'N' */ - FLAG_UPPER, /* 0x4f 'O' */ - FLAG_UPPER, /* 0x50 'P' */ - FLAG_UPPER, /* 0x51 'Q' */ - FLAG_UPPER, /* 0x52 'R' */ - FLAG_UPPER, /* 0x53 'S' */ - FLAG_UPPER, /* 0x54 'T' */ - FLAG_UPPER, /* 0x55 'U' */ - FLAG_UPPER, /* 0x56 'V' */ - FLAG_UPPER, /* 0x57 'W' */ - FLAG_UPPER, /* 0x58 'X' */ - FLAG_UPPER, /* 0x59 'Y' */ - FLAG_UPPER, /* 0x5a 'Z' */ - 0, /* 0x5b '[' */ - 0, /* 0x5c '\\' */ - 0, /* 0x5d ']' */ - 0, /* 0x5e '^' */ - 0, /* 0x5f '_' */ - 0, /* 0x60 '`' */ - FLAG_LOWER|FLAG_XDIGIT, /* 0x61 'a' */ - FLAG_LOWER|FLAG_XDIGIT, /* 0x62 'b' */ - FLAG_LOWER|FLAG_XDIGIT, /* 0x63 'c' */ - FLAG_LOWER|FLAG_XDIGIT, /* 0x64 'd' */ - FLAG_LOWER|FLAG_XDIGIT, /* 0x65 'e' */ - FLAG_LOWER|FLAG_XDIGIT, /* 0x66 'f' */ - FLAG_LOWER, /* 0x67 'g' */ - FLAG_LOWER, /* 0x68 'h' */ - FLAG_LOWER, /* 0x69 'i' */ - FLAG_LOWER, /* 0x6a 'j' */ - FLAG_LOWER, /* 0x6b 'k' */ - FLAG_LOWER, /* 0x6c 'l' */ - FLAG_LOWER, /* 0x6d 'm' */ - FLAG_LOWER, /* 0x6e 'n' */ - FLAG_LOWER, /* 0x6f 'o' */ - FLAG_LOWER, /* 0x70 'p' */ - FLAG_LOWER, /* 0x71 'q' */ - FLAG_LOWER, /* 0x72 'r' */ - FLAG_LOWER, /* 0x73 's' */ - FLAG_LOWER, /* 0x74 't' */ - FLAG_LOWER, /* 0x75 'u' */ - FLAG_LOWER, /* 0x76 'v' */ - FLAG_LOWER, /* 0x77 'w' */ - FLAG_LOWER, /* 0x78 'x' */ - FLAG_LOWER, /* 0x79 'y' */ - FLAG_LOWER, /* 0x7a 'z' */ - 0, /* 0x7b '{' */ - 0, /* 0x7c '|' */ - 0, /* 0x7d '}' */ - 0, /* 0x7e '~' */ - 0, /* 0x7f '\x7f' */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - - -const unsigned char _Py_ctype_tolower[256] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, - 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, - 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, - 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, -}; - -const unsigned char _Py_ctype_toupper[256] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, - 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, - 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, - 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, -}; - - PyDoc_STRVAR_shared(_Py_isspace__doc__, "B.isspace() -> bool\n\ \n\ @@ -228,7 +15,7 @@ register const unsigned char *e; /* Shortcut for single character strings */ - if (len == 1 && ISSPACE(*p)) + if (len == 1 && Py_ISSPACE(*p)) Py_RETURN_TRUE; /* Special case for empty strings */ @@ -237,7 +24,7 @@ e = p + len; for (; p < e; p++) { - if (!ISSPACE(*p)) + if (!Py_ISSPACE(*p)) Py_RETURN_FALSE; } Py_RETURN_TRUE; @@ -258,7 +45,7 @@ register const unsigned char *e; /* Shortcut for single character strings */ - if (len == 1 && ISALPHA(*p)) + if (len == 1 && Py_ISALPHA(*p)) Py_RETURN_TRUE; /* Special case for empty strings */ @@ -267,7 +54,7 @@ e = p + len; for (; p < e; p++) { - if (!ISALPHA(*p)) + if (!Py_ISALPHA(*p)) Py_RETURN_FALSE; } Py_RETURN_TRUE; @@ -288,7 +75,7 @@ register const unsigned char *e; /* Shortcut for single character strings */ - if (len == 1 && ISALNUM(*p)) + if (len == 1 && Py_ISALNUM(*p)) Py_RETURN_TRUE; /* Special case for empty strings */ @@ -297,7 +84,7 @@ e = p + len; for (; p < e; p++) { - if (!ISALNUM(*p)) + if (!Py_ISALNUM(*p)) Py_RETURN_FALSE; } Py_RETURN_TRUE; @@ -318,7 +105,7 @@ register const unsigned char *e; /* Shortcut for single character strings */ - if (len == 1 && ISDIGIT(*p)) + if (len == 1 && Py_ISDIGIT(*p)) Py_RETURN_TRUE; /* Special case for empty strings */ @@ -327,7 +114,7 @@ e = p + len; for (; p < e; p++) { - if (!ISDIGIT(*p)) + if (!Py_ISDIGIT(*p)) Py_RETURN_FALSE; } Py_RETURN_TRUE; @@ -350,7 +137,7 @@ /* Shortcut for single character strings */ if (len == 1) - return PyBool_FromLong(ISLOWER(*p)); + return PyBool_FromLong(Py_ISLOWER(*p)); /* Special case for empty strings */ if (len == 0) @@ -359,9 +146,9 @@ e = p + len; cased = 0; for (; p < e; p++) { - if (ISUPPER(*p)) + if (Py_ISUPPER(*p)) Py_RETURN_FALSE; - else if (!cased && ISLOWER(*p)) + else if (!cased && Py_ISLOWER(*p)) cased = 1; } return PyBool_FromLong(cased); @@ -384,7 +171,7 @@ /* Shortcut for single character strings */ if (len == 1) - return PyBool_FromLong(ISUPPER(*p)); + return PyBool_FromLong(Py_ISUPPER(*p)); /* Special case for empty strings */ if (len == 0) @@ -393,9 +180,9 @@ e = p + len; cased = 0; for (; p < e; p++) { - if (ISLOWER(*p)) + if (Py_ISLOWER(*p)) Py_RETURN_FALSE; - else if (!cased && ISUPPER(*p)) + else if (!cased && Py_ISUPPER(*p)) cased = 1; } return PyBool_FromLong(cased); @@ -420,7 +207,7 @@ /* Shortcut for single character strings */ if (len == 1) - return PyBool_FromLong(ISUPPER(*p)); + return PyBool_FromLong(Py_ISUPPER(*p)); /* Special case for empty strings */ if (len == 0) @@ -432,13 +219,13 @@ for (; p < e; p++) { register const unsigned char ch = *p; - if (ISUPPER(ch)) { + if (Py_ISUPPER(ch)) { if (previous_is_cased) Py_RETURN_FALSE; previous_is_cased = 1; cased = 1; } - else if (ISLOWER(ch)) { + else if (Py_ISLOWER(ch)) { if (!previous_is_cased) Py_RETURN_FALSE; previous_is_cased = 1; @@ -473,8 +260,8 @@ for (i = 0; i < len; i++) { int c = Py_CHARMASK(result[i]); - if (ISUPPER(c)) - result[i] = TOLOWER(c); + if (Py_ISUPPER(c)) + result[i] = Py_TOLOWER(c); } } @@ -501,8 +288,8 @@ for (i = 0; i < len; i++) { int c = Py_CHARMASK(result[i]); - if (ISLOWER(c)) - result[i] = TOUPPER(c); + if (Py_ISLOWER(c)) + result[i] = Py_TOUPPER(c); } } @@ -527,13 +314,13 @@ */ for (i = 0; i < len; i++) { int c = Py_CHARMASK(*s++); - if (ISLOWER(c)) { + if (Py_ISLOWER(c)) { if (!previous_is_cased) - c = TOUPPER(c); + c = Py_TOUPPER(c); previous_is_cased = 1; - } else if (ISUPPER(c)) { + } else if (Py_ISUPPER(c)) { if (previous_is_cased) - c = TOLOWER(c); + c = Py_TOLOWER(c); previous_is_cased = 1; } else previous_is_cased = 0; @@ -560,16 +347,16 @@ */ if (0 < len) { int c = Py_CHARMASK(*s++); - if (ISLOWER(c)) - *result = TOUPPER(c); + if (Py_ISLOWER(c)) + *result = Py_TOUPPER(c); else *result = c; result++; } for (i = 1; i < len; i++) { int c = Py_CHARMASK(*s++); - if (ISUPPER(c)) - *result = TOLOWER(c); + if (Py_ISUPPER(c)) + *result = Py_TOLOWER(c); else *result = c; result++; @@ -596,11 +383,11 @@ */ for (i = 0; i < len; i++) { int c = Py_CHARMASK(*s++); - if (ISLOWER(c)) { - *result = TOUPPER(c); + if (Py_ISLOWER(c)) { + *result = Py_TOUPPER(c); } - else if (ISUPPER(c)) { - *result = TOLOWER(c); + else if (Py_ISUPPER(c)) { + *result = Py_TOLOWER(c); } else *result = c; Modified: python/trunk/Objects/stringlib/stringdefs.h ============================================================================== --- python/trunk/Objects/stringlib/stringdefs.h (original) +++ python/trunk/Objects/stringlib/stringdefs.h Mon Apr 27 21:04:37 2009 @@ -6,15 +6,6 @@ compiled as unicode. */ #define STRINGLIB_IS_UNICODE 0 -/* _tolower and _toupper are defined by SUSv2, but they're not ISO C */ -/* This needs to be cleaned up. See issue 5793. */ -#ifndef _tolower -#define _tolower tolower -#endif -#ifndef _toupper -#define _toupper toupper -#endif - #define STRINGLIB_OBJECT PyStringObject #define STRINGLIB_CHAR char #define STRINGLIB_TYPE_NAME "string" @@ -22,8 +13,8 @@ #define STRINGLIB_EMPTY nullstring #define STRINGLIB_ISDECIMAL(x) ((x >= '0') && (x <= '9')) #define STRINGLIB_TODECIMAL(x) (STRINGLIB_ISDECIMAL(x) ? (x - '0') : -1) -#define STRINGLIB_TOUPPER(x) _toupper(Py_CHARMASK(x)) -#define STRINGLIB_TOLOWER(x) _tolower(Py_CHARMASK(x)) +#define STRINGLIB_TOUPPER Py_TOUPPER +#define STRINGLIB_TOLOWER Py_TOLOWER #define STRINGLIB_FILL memset #define STRINGLIB_STR PyString_AS_STRING #define STRINGLIB_LEN PyString_GET_SIZE Modified: python/trunk/PC/VC6/pythoncore.dsp ============================================================================== --- python/trunk/PC/VC6/pythoncore.dsp (original) +++ python/trunk/PC/VC6/pythoncore.dsp Mon Apr 27 21:04:37 2009 @@ -603,6 +603,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Python\pyctype.c +# End Source File +# Begin Source File + SOURCE=..\..\Python\pyfpe.c # End Source File # Begin Source File Modified: python/trunk/PC/VS7.1/pythoncore.vcproj ============================================================================== --- python/trunk/PC/VS7.1/pythoncore.vcproj (original) +++ python/trunk/PC/VS7.1/pythoncore.vcproj Mon Apr 27 21:04:37 2009 @@ -722,6 +722,9 @@ RelativePath="..\..\Python\pyarena.c"> + + + + @@ -1743,6 +1747,10 @@ > + + Modified: python/trunk/PC/os2emx/Makefile ============================================================================== --- python/trunk/PC/os2emx/Makefile (original) +++ python/trunk/PC/os2emx/Makefile Mon Apr 27 21:04:37 2009 @@ -362,6 +362,7 @@ Python/mystrtoul.c \ Python/peephole.c \ Python/pyarena.c \ + Python/pyctype.c \ Python/pyfpe.c \ Python/pymath.c \ Python/pystate.c \ Modified: python/trunk/PCbuild/pythoncore.vcproj ============================================================================== --- python/trunk/PCbuild/pythoncore.vcproj (original) +++ python/trunk/PCbuild/pythoncore.vcproj Mon Apr 27 21:04:37 2009 @@ -851,6 +851,10 @@ > + + @@ -1743,6 +1747,10 @@ > + + Added: python/trunk/Python/pyctype.c ============================================================================== --- (empty file) +++ python/trunk/Python/pyctype.c Mon Apr 27 21:04:37 2009 @@ -0,0 +1,214 @@ +#include "Python.h" + +/* Our own locale-independent ctype.h-like macros */ + +const unsigned int _Py_ctype_table[256] = { + 0, /* 0x0 '\x00' */ + 0, /* 0x1 '\x01' */ + 0, /* 0x2 '\x02' */ + 0, /* 0x3 '\x03' */ + 0, /* 0x4 '\x04' */ + 0, /* 0x5 '\x05' */ + 0, /* 0x6 '\x06' */ + 0, /* 0x7 '\x07' */ + 0, /* 0x8 '\x08' */ + PY_CTF_SPACE, /* 0x9 '\t' */ + PY_CTF_SPACE, /* 0xa '\n' */ + PY_CTF_SPACE, /* 0xb '\v' */ + PY_CTF_SPACE, /* 0xc '\f' */ + PY_CTF_SPACE, /* 0xd '\r' */ + 0, /* 0xe '\x0e' */ + 0, /* 0xf '\x0f' */ + 0, /* 0x10 '\x10' */ + 0, /* 0x11 '\x11' */ + 0, /* 0x12 '\x12' */ + 0, /* 0x13 '\x13' */ + 0, /* 0x14 '\x14' */ + 0, /* 0x15 '\x15' */ + 0, /* 0x16 '\x16' */ + 0, /* 0x17 '\x17' */ + 0, /* 0x18 '\x18' */ + 0, /* 0x19 '\x19' */ + 0, /* 0x1a '\x1a' */ + 0, /* 0x1b '\x1b' */ + 0, /* 0x1c '\x1c' */ + 0, /* 0x1d '\x1d' */ + 0, /* 0x1e '\x1e' */ + 0, /* 0x1f '\x1f' */ + PY_CTF_SPACE, /* 0x20 ' ' */ + 0, /* 0x21 '!' */ + 0, /* 0x22 '"' */ + 0, /* 0x23 '#' */ + 0, /* 0x24 '$' */ + 0, /* 0x25 '%' */ + 0, /* 0x26 '&' */ + 0, /* 0x27 "'" */ + 0, /* 0x28 '(' */ + 0, /* 0x29 ')' */ + 0, /* 0x2a '*' */ + 0, /* 0x2b '+' */ + 0, /* 0x2c ',' */ + 0, /* 0x2d '-' */ + 0, /* 0x2e '.' */ + 0, /* 0x2f '/' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x30 '0' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x31 '1' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x32 '2' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x33 '3' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x34 '4' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x35 '5' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x36 '6' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x37 '7' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x38 '8' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x39 '9' */ + 0, /* 0x3a ':' */ + 0, /* 0x3b ';' */ + 0, /* 0x3c '<' */ + 0, /* 0x3d '=' */ + 0, /* 0x3e '>' */ + 0, /* 0x3f '?' */ + 0, /* 0x40 '@' */ + PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x41 'A' */ + PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x42 'B' */ + PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x43 'C' */ + PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x44 'D' */ + PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x45 'E' */ + PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x46 'F' */ + PY_CTF_UPPER, /* 0x47 'G' */ + PY_CTF_UPPER, /* 0x48 'H' */ + PY_CTF_UPPER, /* 0x49 'I' */ + PY_CTF_UPPER, /* 0x4a 'J' */ + PY_CTF_UPPER, /* 0x4b 'K' */ + PY_CTF_UPPER, /* 0x4c 'L' */ + PY_CTF_UPPER, /* 0x4d 'M' */ + PY_CTF_UPPER, /* 0x4e 'N' */ + PY_CTF_UPPER, /* 0x4f 'O' */ + PY_CTF_UPPER, /* 0x50 'P' */ + PY_CTF_UPPER, /* 0x51 'Q' */ + PY_CTF_UPPER, /* 0x52 'R' */ + PY_CTF_UPPER, /* 0x53 'S' */ + PY_CTF_UPPER, /* 0x54 'T' */ + PY_CTF_UPPER, /* 0x55 'U' */ + PY_CTF_UPPER, /* 0x56 'V' */ + PY_CTF_UPPER, /* 0x57 'W' */ + PY_CTF_UPPER, /* 0x58 'X' */ + PY_CTF_UPPER, /* 0x59 'Y' */ + PY_CTF_UPPER, /* 0x5a 'Z' */ + 0, /* 0x5b '[' */ + 0, /* 0x5c '\\' */ + 0, /* 0x5d ']' */ + 0, /* 0x5e '^' */ + 0, /* 0x5f '_' */ + 0, /* 0x60 '`' */ + PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x61 'a' */ + PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x62 'b' */ + PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x63 'c' */ + PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x64 'd' */ + PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x65 'e' */ + PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x66 'f' */ + PY_CTF_LOWER, /* 0x67 'g' */ + PY_CTF_LOWER, /* 0x68 'h' */ + PY_CTF_LOWER, /* 0x69 'i' */ + PY_CTF_LOWER, /* 0x6a 'j' */ + PY_CTF_LOWER, /* 0x6b 'k' */ + PY_CTF_LOWER, /* 0x6c 'l' */ + PY_CTF_LOWER, /* 0x6d 'm' */ + PY_CTF_LOWER, /* 0x6e 'n' */ + PY_CTF_LOWER, /* 0x6f 'o' */ + PY_CTF_LOWER, /* 0x70 'p' */ + PY_CTF_LOWER, /* 0x71 'q' */ + PY_CTF_LOWER, /* 0x72 'r' */ + PY_CTF_LOWER, /* 0x73 's' */ + PY_CTF_LOWER, /* 0x74 't' */ + PY_CTF_LOWER, /* 0x75 'u' */ + PY_CTF_LOWER, /* 0x76 'v' */ + PY_CTF_LOWER, /* 0x77 'w' */ + PY_CTF_LOWER, /* 0x78 'x' */ + PY_CTF_LOWER, /* 0x79 'y' */ + PY_CTF_LOWER, /* 0x7a 'z' */ + 0, /* 0x7b '{' */ + 0, /* 0x7c '|' */ + 0, /* 0x7d '}' */ + 0, /* 0x7e '~' */ + 0, /* 0x7f '\x7f' */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + + +const unsigned char _Py_ctype_tolower[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +const unsigned char _Py_ctype_toupper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + Modified: python/trunk/Python/pystrtod.c ============================================================================== --- python/trunk/Python/pystrtod.c (original) +++ python/trunk/Python/pystrtod.c Mon Apr 27 21:04:37 2009 @@ -3,12 +3,6 @@ #include #include -/* ascii character tests (as opposed to locale tests) */ -#define ISSPACE(c) ((c) == ' ' || (c) == '\f' || (c) == '\n' || \ - (c) == '\r' || (c) == '\t' || (c) == '\v') -#define ISDIGIT(c) ((c) >= '0' && (c) <= '9') - - /** * PyOS_ascii_strtod: * @nptr: the string to convert to a numeric value. @@ -81,7 +75,7 @@ p = nptr; /* Skip leading space */ - while (ISSPACE(*p)) + while (Py_ISSPACE(*p)) p++; /* Process leading sign, if present */ @@ -124,7 +118,7 @@ goto invalid_string; /* Check that what's left begins with a digit or decimal point */ - if (!ISDIGIT(*p) && *p != '.') + if (!Py_ISDIGIT(*p) && *p != '.') goto invalid_string; digits_pos = p; @@ -135,7 +129,7 @@ swapped for the current locale's decimal point before we call strtod. On the other hand, if we find the current locale's decimal point then the input is invalid. */ - while (ISDIGIT(*p)) + while (Py_ISDIGIT(*p)) p++; if (*p == '.') @@ -143,14 +137,14 @@ decimal_point_pos = p++; /* locate end of number */ - while (ISDIGIT(*p)) + while (Py_ISDIGIT(*p)) p++; if (*p == 'e' || *p == 'E') p++; if (*p == '+' || *p == '-') p++; - while (ISDIGIT(*p)) + while (Py_ISDIGIT(*p)) p++; end = p; } @@ -244,7 +238,7 @@ if (*buffer == '+' || *buffer == '-') buffer++; - while (isdigit(Py_CHARMASK(*buffer))) + while (Py_ISDIGIT(*buffer)) buffer++; if (strncmp(buffer, decimal_point, decimal_point_len) == 0) { *buffer = '.'; @@ -306,7 +300,7 @@ /* Find the end of the exponent, keeping track of leading zeros. */ - while (*p && isdigit(Py_CHARMASK(*p))) { + while (*p && Py_ISDIGIT(*p)) { if (in_leading_zeros && *p == '0') ++leading_zero_cnt; if (*p != '0') @@ -369,11 +363,11 @@ /* Skip leading sign, if present. I think this could only ever be '-', but it can't hurt to check for both. */ ++p; - while (*p && isdigit(Py_CHARMASK(*p))) + while (*p && Py_ISDIGIT(*p)) ++p; if (*p == '.') { - if (isdigit(Py_CHARMASK(*(p+1)))) { + if (Py_ISDIGIT(*(p+1))) { /* Nothing to do, we already have a decimal point and a digit after it */ } From python-checkins at python.org Mon Apr 27 21:36:00 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 27 Apr 2009 21:36:00 +0200 (CEST) Subject: [Python-checkins] r72041 - python/branches/release26-maint Message-ID: <20090427193600.517801E4075@bag.python.org> Author: eric.smith Date: Mon Apr 27 21:36:00 2009 New Revision: 72041 Log: Blocked revisions 72040 via svnmerge ........ r72040 | eric.smith | 2009-04-27 15:04:37 -0400 (Mon, 27 Apr 2009) | 1 line Issue #5793: rationalize isdigit / isalpha / tolower, etc. Will port to py3k. Should fix Windows buildbot errors. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Mon Apr 27 21:41:00 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 27 Apr 2009 21:41:00 +0200 (CEST) Subject: [Python-checkins] r72042 - python/branches/py3k/Objects/longobject.c Message-ID: <20090427194100.338581E401A@bag.python.org> Author: mark.dickinson Date: Mon Apr 27 21:41:00 2009 New Revision: 72042 Log: Typo fix. Thanks Damien Diederen. 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 Mon Apr 27 21:41:00 2009 @@ -209,7 +209,7 @@ return (PyObject*)v; } -#if PyLONG_SHIFT==15 +#if PyLong_SHIFT==15 /* 2 digits */ if (!(abs_ival >> 2*PyLong_SHIFT)) { v = _PyLong_New(2); From python-checkins at python.org Mon Apr 27 21:42:39 2009 From: python-checkins at python.org (mark.dickinson) Date: Mon, 27 Apr 2009 21:42:39 +0200 (CEST) Subject: [Python-checkins] r72043 - python/branches/release30-maint Message-ID: <20090427194239.71FB91E4075@bag.python.org> Author: mark.dickinson Date: Mon Apr 27 21:42:39 2009 New Revision: 72043 Log: Blocked revisions 72042 via svnmerge ........ r72042 | mark.dickinson | 2009-04-27 20:41:00 +0100 (Mon, 27 Apr 2009) | 2 lines Typo fix. Thanks Damien Diederen. ........ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Mon Apr 27 22:39:49 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 27 Apr 2009 22:39:49 +0200 (CEST) Subject: [Python-checkins] r72044 - in python/branches/py3k: Include/Python.h Include/bytes_methods.h Makefile.pre.in Misc/NEWS Objects/bytearrayobject.c Objects/bytes_methods.c Objects/stringlib/stringdefs.h PC/VC6/pythoncore.dsp PC/VS7.1/pythoncore.vcproj PC/VS8.0/pythoncore.vcproj PC/os2emx/Makefile PCbuild/pythoncore.vcproj Python/pystrtod.c Message-ID: <20090427203949.BBDB61E4017@bag.python.org> Author: eric.smith Date: Mon Apr 27 22:39:49 2009 New Revision: 72044 Log: Merged revisions 72040 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72040 | eric.smith | 2009-04-27 15:04:37 -0400 (Mon, 27 Apr 2009) | 1 line Issue #5793: rationalize isdigit / isalpha / tolower, etc. Will port to py3k. Should fix Windows buildbot errors. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Include/Python.h python/branches/py3k/Include/bytes_methods.h python/branches/py3k/Makefile.pre.in python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/bytearrayobject.c python/branches/py3k/Objects/bytes_methods.c python/branches/py3k/Objects/stringlib/stringdefs.h python/branches/py3k/PC/VC6/pythoncore.dsp python/branches/py3k/PC/VS7.1/pythoncore.vcproj python/branches/py3k/PC/VS8.0/pythoncore.vcproj python/branches/py3k/PC/os2emx/Makefile python/branches/py3k/PCbuild/pythoncore.vcproj python/branches/py3k/Python/pystrtod.c Modified: python/branches/py3k/Include/Python.h ============================================================================== --- python/branches/py3k/Include/Python.h (original) +++ python/branches/py3k/Include/Python.h Mon Apr 27 22:39:49 2009 @@ -116,6 +116,7 @@ #include "compile.h" #include "eval.h" +#include "pyctype.h" #include "pystrtod.h" #include "pystrcmp.h" #include "dtoa.h" Modified: python/branches/py3k/Include/bytes_methods.h ============================================================================== --- python/branches/py3k/Include/bytes_methods.h (original) +++ python/branches/py3k/Include/bytes_methods.h Mon Apr 27 22:39:49 2009 @@ -38,23 +38,15 @@ extern const char _Py_swapcase__doc__[]; extern const char _Py_maketrans__doc__[]; -#define FLAG_LOWER 0x01 -#define FLAG_UPPER 0x02 -#define FLAG_ALPHA (FLAG_LOWER|FLAG_UPPER) -#define FLAG_DIGIT 0x04 -#define FLAG_ALNUM (FLAG_ALPHA|FLAG_DIGIT) -#define FLAG_SPACE 0x08 -#define FLAG_XDIGIT 0x10 - -extern const unsigned int _Py_ctype_table[256]; - -#define ISLOWER(c) (_Py_ctype_table[Py_CHARMASK(c)] & FLAG_LOWER) -#define ISUPPER(c) (_Py_ctype_table[Py_CHARMASK(c)] & FLAG_UPPER) -#define ISALPHA(c) (_Py_ctype_table[Py_CHARMASK(c)] & FLAG_ALPHA) -#define ISDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & FLAG_DIGIT) -#define ISXDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & FLAG_XDIGIT) -#define ISALNUM(c) (_Py_ctype_table[Py_CHARMASK(c)] & FLAG_ALNUM) -#define ISSPACE(c) (_Py_ctype_table[Py_CHARMASK(c)] & FLAG_SPACE) +/* These are left in for backward compatibility and will be removed + in 2.8/3.2 */ +#define ISLOWER(c) Py_ISLOWER(c) +#define ISUPPER(c) Py_ISUPPER(c) +#define ISALPHA(c) Py_ISALPHA(c) +#define ISDIGIT(c) Py_ISDIGIT(c) +#define ISXDIGIT(c) Py_ISXDIGIT(c) +#define ISALNUM(c) Py_ISALNUM(c) +#define ISSPACE(c) Py_ISSPACE(c) #undef islower #define islower(c) undefined_islower(c) @@ -71,11 +63,10 @@ #undef isspace #define isspace(c) undefined_isspace(c) -extern const unsigned char _Py_ctype_tolower[256]; -extern const unsigned char _Py_ctype_toupper[256]; - -#define TOLOWER(c) (_Py_ctype_tolower[Py_CHARMASK(c)]) -#define TOUPPER(c) (_Py_ctype_toupper[Py_CHARMASK(c)]) +/* These are left in for backward compatibility and will be removed + in 2.8/3.2 */ +#define TOLOWER(c) Py_TOLOWER(c) +#define TOUPPER(c) Py_TOUPPER(c) #undef tolower #define tolower(c) undefined_tolower(c) Modified: python/branches/py3k/Makefile.pre.in ============================================================================== --- python/branches/py3k/Makefile.pre.in (original) +++ python/branches/py3k/Makefile.pre.in Mon Apr 27 22:39:49 2009 @@ -294,6 +294,7 @@ Python/mysnprintf.o \ Python/peephole.o \ Python/pyarena.o \ + Python/pyctype.o \ Python/pyfpe.o \ Python/pymath.o \ Python/pystate.o \ @@ -653,6 +654,7 @@ Include/pgen.h \ Include/pgenheaders.h \ Include/pyarena.h \ + Include/pyctype.h \ Include/pydebug.h \ Include/pyerrors.h \ Include/pyfpe.h \ Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Apr 27 22:39:49 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #5793: Rationalize isdigit / isalpha / tolower, etc. Includes + new Py_ISDIGIT / Py_ISALPHA / Py_TOLOWER, etc. in pctypes.h. + - Issue #5835: Deprecate PyOS_ascii_formatd. - Issue #4971: Fix titlecase for characters that are their own Modified: python/branches/py3k/Objects/bytearrayobject.c ============================================================================== --- python/branches/py3k/Objects/bytearrayobject.c (original) +++ python/branches/py3k/Objects/bytearrayobject.c Mon Apr 27 22:39:49 2009 @@ -2176,16 +2176,16 @@ for (i = j = 0; i < len; ) { /* find a token */ - while (i < len && ISSPACE(s[i])) + while (i < len && Py_ISSPACE(s[i])) i++; j = i; - while (i < len && !ISSPACE(s[i])) + while (i < len && !Py_ISSPACE(s[i])) i++; if (j < i) { if (maxcount-- <= 0) break; SPLIT_ADD(s, j, i); - while (i < len && ISSPACE(s[i])) + while (i < len && Py_ISSPACE(s[i])) i++; j = i; } @@ -2410,16 +2410,16 @@ for (i = j = len - 1; i >= 0; ) { /* find a token */ - while (i >= 0 && ISSPACE(s[i])) + while (i >= 0 && Py_ISSPACE(s[i])) i--; j = i; - while (i >= 0 && !ISSPACE(s[i])) + while (i >= 0 && !Py_ISSPACE(s[i])) i--; if (j > i) { if (maxcount-- <= 0) break; SPLIT_ADD(s, i + 1, j + 1); - while (i >= 0 && ISSPACE(s[i])) + while (i >= 0 && Py_ISSPACE(s[i])) i--; j = i; } @@ -2986,11 +2986,11 @@ { if (c >= 128) return -1; - if (ISDIGIT(c)) + if (Py_ISDIGIT(c)) return c - '0'; else { - if (ISUPPER(c)) - c = TOLOWER(c); + if (Py_ISUPPER(c)) + c = Py_TOLOWER(c); if (c >= 'a' && c <= 'f') return c - 'a' + 10; } Modified: python/branches/py3k/Objects/bytes_methods.c ============================================================================== --- python/branches/py3k/Objects/bytes_methods.c (original) +++ python/branches/py3k/Objects/bytes_methods.c Mon Apr 27 22:39:49 2009 @@ -1,219 +1,6 @@ #include "Python.h" #include "bytes_methods.h" -/* Our own locale-independent ctype.h-like macros */ - -const unsigned int _Py_ctype_table[256] = { - 0, /* 0x0 '\x00' */ - 0, /* 0x1 '\x01' */ - 0, /* 0x2 '\x02' */ - 0, /* 0x3 '\x03' */ - 0, /* 0x4 '\x04' */ - 0, /* 0x5 '\x05' */ - 0, /* 0x6 '\x06' */ - 0, /* 0x7 '\x07' */ - 0, /* 0x8 '\x08' */ - FLAG_SPACE, /* 0x9 '\t' */ - FLAG_SPACE, /* 0xa '\n' */ - FLAG_SPACE, /* 0xb '\v' */ - FLAG_SPACE, /* 0xc '\f' */ - FLAG_SPACE, /* 0xd '\r' */ - 0, /* 0xe '\x0e' */ - 0, /* 0xf '\x0f' */ - 0, /* 0x10 '\x10' */ - 0, /* 0x11 '\x11' */ - 0, /* 0x12 '\x12' */ - 0, /* 0x13 '\x13' */ - 0, /* 0x14 '\x14' */ - 0, /* 0x15 '\x15' */ - 0, /* 0x16 '\x16' */ - 0, /* 0x17 '\x17' */ - 0, /* 0x18 '\x18' */ - 0, /* 0x19 '\x19' */ - 0, /* 0x1a '\x1a' */ - 0, /* 0x1b '\x1b' */ - 0, /* 0x1c '\x1c' */ - 0, /* 0x1d '\x1d' */ - 0, /* 0x1e '\x1e' */ - 0, /* 0x1f '\x1f' */ - FLAG_SPACE, /* 0x20 ' ' */ - 0, /* 0x21 '!' */ - 0, /* 0x22 '"' */ - 0, /* 0x23 '#' */ - 0, /* 0x24 '$' */ - 0, /* 0x25 '%' */ - 0, /* 0x26 '&' */ - 0, /* 0x27 "'" */ - 0, /* 0x28 '(' */ - 0, /* 0x29 ')' */ - 0, /* 0x2a '*' */ - 0, /* 0x2b '+' */ - 0, /* 0x2c ',' */ - 0, /* 0x2d '-' */ - 0, /* 0x2e '.' */ - 0, /* 0x2f '/' */ - FLAG_DIGIT|FLAG_XDIGIT, /* 0x30 '0' */ - FLAG_DIGIT|FLAG_XDIGIT, /* 0x31 '1' */ - FLAG_DIGIT|FLAG_XDIGIT, /* 0x32 '2' */ - FLAG_DIGIT|FLAG_XDIGIT, /* 0x33 '3' */ - FLAG_DIGIT|FLAG_XDIGIT, /* 0x34 '4' */ - FLAG_DIGIT|FLAG_XDIGIT, /* 0x35 '5' */ - FLAG_DIGIT|FLAG_XDIGIT, /* 0x36 '6' */ - FLAG_DIGIT|FLAG_XDIGIT, /* 0x37 '7' */ - FLAG_DIGIT|FLAG_XDIGIT, /* 0x38 '8' */ - FLAG_DIGIT|FLAG_XDIGIT, /* 0x39 '9' */ - 0, /* 0x3a ':' */ - 0, /* 0x3b ';' */ - 0, /* 0x3c '<' */ - 0, /* 0x3d '=' */ - 0, /* 0x3e '>' */ - 0, /* 0x3f '?' */ - 0, /* 0x40 '@' */ - FLAG_UPPER|FLAG_XDIGIT, /* 0x41 'A' */ - FLAG_UPPER|FLAG_XDIGIT, /* 0x42 'B' */ - FLAG_UPPER|FLAG_XDIGIT, /* 0x43 'C' */ - FLAG_UPPER|FLAG_XDIGIT, /* 0x44 'D' */ - FLAG_UPPER|FLAG_XDIGIT, /* 0x45 'E' */ - FLAG_UPPER|FLAG_XDIGIT, /* 0x46 'F' */ - FLAG_UPPER, /* 0x47 'G' */ - FLAG_UPPER, /* 0x48 'H' */ - FLAG_UPPER, /* 0x49 'I' */ - FLAG_UPPER, /* 0x4a 'J' */ - FLAG_UPPER, /* 0x4b 'K' */ - FLAG_UPPER, /* 0x4c 'L' */ - FLAG_UPPER, /* 0x4d 'M' */ - FLAG_UPPER, /* 0x4e 'N' */ - FLAG_UPPER, /* 0x4f 'O' */ - FLAG_UPPER, /* 0x50 'P' */ - FLAG_UPPER, /* 0x51 'Q' */ - FLAG_UPPER, /* 0x52 'R' */ - FLAG_UPPER, /* 0x53 'S' */ - FLAG_UPPER, /* 0x54 'T' */ - FLAG_UPPER, /* 0x55 'U' */ - FLAG_UPPER, /* 0x56 'V' */ - FLAG_UPPER, /* 0x57 'W' */ - FLAG_UPPER, /* 0x58 'X' */ - FLAG_UPPER, /* 0x59 'Y' */ - FLAG_UPPER, /* 0x5a 'Z' */ - 0, /* 0x5b '[' */ - 0, /* 0x5c '\\' */ - 0, /* 0x5d ']' */ - 0, /* 0x5e '^' */ - 0, /* 0x5f '_' */ - 0, /* 0x60 '`' */ - FLAG_LOWER|FLAG_XDIGIT, /* 0x61 'a' */ - FLAG_LOWER|FLAG_XDIGIT, /* 0x62 'b' */ - FLAG_LOWER|FLAG_XDIGIT, /* 0x63 'c' */ - FLAG_LOWER|FLAG_XDIGIT, /* 0x64 'd' */ - FLAG_LOWER|FLAG_XDIGIT, /* 0x65 'e' */ - FLAG_LOWER|FLAG_XDIGIT, /* 0x66 'f' */ - FLAG_LOWER, /* 0x67 'g' */ - FLAG_LOWER, /* 0x68 'h' */ - FLAG_LOWER, /* 0x69 'i' */ - FLAG_LOWER, /* 0x6a 'j' */ - FLAG_LOWER, /* 0x6b 'k' */ - FLAG_LOWER, /* 0x6c 'l' */ - FLAG_LOWER, /* 0x6d 'm' */ - FLAG_LOWER, /* 0x6e 'n' */ - FLAG_LOWER, /* 0x6f 'o' */ - FLAG_LOWER, /* 0x70 'p' */ - FLAG_LOWER, /* 0x71 'q' */ - FLAG_LOWER, /* 0x72 'r' */ - FLAG_LOWER, /* 0x73 's' */ - FLAG_LOWER, /* 0x74 't' */ - FLAG_LOWER, /* 0x75 'u' */ - FLAG_LOWER, /* 0x76 'v' */ - FLAG_LOWER, /* 0x77 'w' */ - FLAG_LOWER, /* 0x78 'x' */ - FLAG_LOWER, /* 0x79 'y' */ - FLAG_LOWER, /* 0x7a 'z' */ - 0, /* 0x7b '{' */ - 0, /* 0x7c '|' */ - 0, /* 0x7d '}' */ - 0, /* 0x7e '~' */ - 0, /* 0x7f '\x7f' */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - - -const unsigned char _Py_ctype_tolower[256] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, - 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, - 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, - 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, -}; - -const unsigned char _Py_ctype_toupper[256] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, - 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, - 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, - 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, -}; - - PyDoc_STRVAR_shared(_Py_isspace__doc__, "B.isspace() -> bool\n\ \n\ @@ -228,7 +15,7 @@ register const unsigned char *e; /* Shortcut for single character strings */ - if (len == 1 && ISSPACE(*p)) + if (len == 1 && Py_ISSPACE(*p)) Py_RETURN_TRUE; /* Special case for empty strings */ @@ -237,7 +24,7 @@ e = p + len; for (; p < e; p++) { - if (!ISSPACE(*p)) + if (!Py_ISSPACE(*p)) Py_RETURN_FALSE; } Py_RETURN_TRUE; @@ -258,7 +45,7 @@ register const unsigned char *e; /* Shortcut for single character strings */ - if (len == 1 && ISALPHA(*p)) + if (len == 1 && Py_ISALPHA(*p)) Py_RETURN_TRUE; /* Special case for empty strings */ @@ -267,7 +54,7 @@ e = p + len; for (; p < e; p++) { - if (!ISALPHA(*p)) + if (!Py_ISALPHA(*p)) Py_RETURN_FALSE; } Py_RETURN_TRUE; @@ -288,7 +75,7 @@ register const unsigned char *e; /* Shortcut for single character strings */ - if (len == 1 && ISALNUM(*p)) + if (len == 1 && Py_ISALNUM(*p)) Py_RETURN_TRUE; /* Special case for empty strings */ @@ -297,7 +84,7 @@ e = p + len; for (; p < e; p++) { - if (!ISALNUM(*p)) + if (!Py_ISALNUM(*p)) Py_RETURN_FALSE; } Py_RETURN_TRUE; @@ -318,7 +105,7 @@ register const unsigned char *e; /* Shortcut for single character strings */ - if (len == 1 && ISDIGIT(*p)) + if (len == 1 && Py_ISDIGIT(*p)) Py_RETURN_TRUE; /* Special case for empty strings */ @@ -327,7 +114,7 @@ e = p + len; for (; p < e; p++) { - if (!ISDIGIT(*p)) + if (!Py_ISDIGIT(*p)) Py_RETURN_FALSE; } Py_RETURN_TRUE; @@ -350,7 +137,7 @@ /* Shortcut for single character strings */ if (len == 1) - return PyBool_FromLong(ISLOWER(*p)); + return PyBool_FromLong(Py_ISLOWER(*p)); /* Special case for empty strings */ if (len == 0) @@ -359,9 +146,9 @@ e = p + len; cased = 0; for (; p < e; p++) { - if (ISUPPER(*p)) + if (Py_ISUPPER(*p)) Py_RETURN_FALSE; - else if (!cased && ISLOWER(*p)) + else if (!cased && Py_ISLOWER(*p)) cased = 1; } return PyBool_FromLong(cased); @@ -384,7 +171,7 @@ /* Shortcut for single character strings */ if (len == 1) - return PyBool_FromLong(ISUPPER(*p)); + return PyBool_FromLong(Py_ISUPPER(*p)); /* Special case for empty strings */ if (len == 0) @@ -393,9 +180,9 @@ e = p + len; cased = 0; for (; p < e; p++) { - if (ISLOWER(*p)) + if (Py_ISLOWER(*p)) Py_RETURN_FALSE; - else if (!cased && ISUPPER(*p)) + else if (!cased && Py_ISUPPER(*p)) cased = 1; } return PyBool_FromLong(cased); @@ -420,7 +207,7 @@ /* Shortcut for single character strings */ if (len == 1) - return PyBool_FromLong(ISUPPER(*p)); + return PyBool_FromLong(Py_ISUPPER(*p)); /* Special case for empty strings */ if (len == 0) @@ -432,13 +219,13 @@ for (; p < e; p++) { register const unsigned char ch = *p; - if (ISUPPER(ch)) { + if (Py_ISUPPER(ch)) { if (previous_is_cased) Py_RETURN_FALSE; previous_is_cased = 1; cased = 1; } - else if (ISLOWER(ch)) { + else if (Py_ISLOWER(ch)) { if (!previous_is_cased) Py_RETURN_FALSE; previous_is_cased = 1; @@ -473,8 +260,8 @@ for (i = 0; i < len; i++) { int c = Py_CHARMASK(result[i]); - if (ISUPPER(c)) - result[i] = TOLOWER(c); + if (Py_ISUPPER(c)) + result[i] = Py_TOLOWER(c); } } @@ -501,8 +288,8 @@ for (i = 0; i < len; i++) { int c = Py_CHARMASK(result[i]); - if (ISLOWER(c)) - result[i] = TOUPPER(c); + if (Py_ISLOWER(c)) + result[i] = Py_TOUPPER(c); } } @@ -527,13 +314,13 @@ */ for (i = 0; i < len; i++) { int c = Py_CHARMASK(*s++); - if (ISLOWER(c)) { + if (Py_ISLOWER(c)) { if (!previous_is_cased) - c = TOUPPER(c); + c = Py_TOUPPER(c); previous_is_cased = 1; - } else if (ISUPPER(c)) { + } else if (Py_ISUPPER(c)) { if (previous_is_cased) - c = TOLOWER(c); + c = Py_TOLOWER(c); previous_is_cased = 1; } else previous_is_cased = 0; @@ -560,16 +347,16 @@ */ if (0 < len) { int c = Py_CHARMASK(*s++); - if (ISLOWER(c)) - *result = TOUPPER(c); + if (Py_ISLOWER(c)) + *result = Py_TOUPPER(c); else *result = c; result++; } for (i = 1; i < len; i++) { int c = Py_CHARMASK(*s++); - if (ISUPPER(c)) - *result = TOLOWER(c); + if (Py_ISUPPER(c)) + *result = Py_TOLOWER(c); else *result = c; result++; @@ -596,11 +383,11 @@ */ for (i = 0; i < len; i++) { int c = Py_CHARMASK(*s++); - if (ISLOWER(c)) { - *result = TOUPPER(c); + if (Py_ISLOWER(c)) { + *result = Py_TOUPPER(c); } - else if (ISUPPER(c)) { - *result = TOLOWER(c); + else if (Py_ISUPPER(c)) { + *result = Py_TOLOWER(c); } else *result = c; Modified: python/branches/py3k/Objects/stringlib/stringdefs.h ============================================================================== --- python/branches/py3k/Objects/stringlib/stringdefs.h (original) +++ python/branches/py3k/Objects/stringlib/stringdefs.h Mon Apr 27 22:39:49 2009 @@ -13,8 +13,8 @@ #define STRINGLIB_EMPTY nullstring #define STRINGLIB_ISDECIMAL(x) ((x >= '0') && (x <= '9')) #define STRINGLIB_TODECIMAL(x) (STRINGLIB_ISDECIMAL(x) ? (x - '0') : -1) -#define STRINGLIB_TOUPPER toupper -#define STRINGLIB_TOLOWER tolower +#define STRINGLIB_TOUPPER Py_TOUPPER +#define STRINGLIB_TOLOWER Py_TOLOWER #define STRINGLIB_FILL memset #define STRINGLIB_STR PyBytes_AS_STRING #define STRINGLIB_LEN PyBytes_GET_SIZE Modified: python/branches/py3k/PC/VC6/pythoncore.dsp ============================================================================== --- python/branches/py3k/PC/VC6/pythoncore.dsp (original) +++ python/branches/py3k/PC/VC6/pythoncore.dsp Mon Apr 27 22:39:49 2009 @@ -603,6 +603,10 @@ # End Source File # Begin Source File +SOURCE=..\..\Python\pyctype.c +# End Source File +# Begin Source File + SOURCE=..\..\Python\pyfpe.c # End Source File # Begin Source File Modified: python/branches/py3k/PC/VS7.1/pythoncore.vcproj ============================================================================== --- python/branches/py3k/PC/VS7.1/pythoncore.vcproj (original) +++ python/branches/py3k/PC/VS7.1/pythoncore.vcproj Mon Apr 27 22:39:49 2009 @@ -721,6 +721,9 @@ RelativePath="..\..\Python\pyarena.c"> + + + + @@ -1731,6 +1735,10 @@ > + + Modified: python/branches/py3k/PC/os2emx/Makefile ============================================================================== --- python/branches/py3k/PC/os2emx/Makefile (original) +++ python/branches/py3k/PC/os2emx/Makefile Mon Apr 27 22:39:49 2009 @@ -349,6 +349,7 @@ Python/mysnprintf.c \ Python/mystrtoul.c \ Python/pyarena.c \ + Python/pyctype.c \ Python/pyfpe.c \ Python/pystate.c \ Python/pystrtod.c \ Modified: python/branches/py3k/PCbuild/pythoncore.vcproj ============================================================================== --- python/branches/py3k/PCbuild/pythoncore.vcproj (original) +++ python/branches/py3k/PCbuild/pythoncore.vcproj Mon Apr 27 22:39:49 2009 @@ -847,6 +847,10 @@ > + + @@ -1731,6 +1735,10 @@ > + + Modified: python/branches/py3k/Python/pystrtod.c ============================================================================== --- python/branches/py3k/Python/pystrtod.c (original) +++ python/branches/py3k/Python/pystrtod.c Mon Apr 27 22:39:49 2009 @@ -3,12 +3,6 @@ #include #include -/* ascii character tests (as opposed to locale tests) */ -#define ISSPACE(c) ((c) == ' ' || (c) == '\f' || (c) == '\n' || \ - (c) == '\r' || (c) == '\t' || (c) == '\v') -#define ISDIGIT(c) ((c) >= '0' && (c) <= '9') - - /** * PyOS_ascii_strtod: * @nptr: the string to convert to a numeric value. @@ -104,7 +98,7 @@ p = nptr; /* Skip leading space */ - while (ISSPACE(*p)) + while (Py_ISSPACE(*p)) p++; /* Process leading sign, if present */ @@ -147,7 +141,7 @@ goto invalid_string; /* Check that what's left begins with a digit or decimal point */ - if (!ISDIGIT(*p) && *p != '.') + if (!Py_ISDIGIT(*p) && *p != '.') goto invalid_string; digits_pos = p; @@ -158,7 +152,7 @@ swapped for the current locale's decimal point before we call strtod. On the other hand, if we find the current locale's decimal point then the input is invalid. */ - while (ISDIGIT(*p)) + while (Py_ISDIGIT(*p)) p++; if (*p == '.') @@ -166,14 +160,14 @@ decimal_point_pos = p++; /* locate end of number */ - while (ISDIGIT(*p)) + while (Py_ISDIGIT(*p)) p++; if (*p == 'e' || *p == 'E') p++; if (*p == '+' || *p == '-') p++; - while (ISDIGIT(*p)) + while (Py_ISDIGIT(*p)) p++; end = p; } @@ -269,7 +263,7 @@ if (*buffer == '+' || *buffer == '-') buffer++; - while (isdigit(Py_CHARMASK(*buffer))) + while (Py_ISDIGIT(*buffer)) buffer++; if (strncmp(buffer, decimal_point, decimal_point_len) == 0) { *buffer = '.'; @@ -312,7 +306,7 @@ /* Find the end of the exponent, keeping track of leading zeros. */ - while (*p && isdigit(Py_CHARMASK(*p))) { + while (*p && Py_ISDIGIT(*p)) { if (in_leading_zeros && *p == '0') ++leading_zero_cnt; if (*p != '0') @@ -375,11 +369,11 @@ /* Skip leading sign, if present. I think this could only ever be '-', but it can't hurt to check for both. */ ++p; - while (*p && isdigit(Py_CHARMASK(*p))) + while (*p && Py_ISDIGIT(*p)) ++p; if (*p == '.') { - if (isdigit(Py_CHARMASK(*(p+1)))) { + if (Py_ISDIGIT(*(p+1))) { /* Nothing to do, we already have a decimal point and a digit after it */ } From buildbot at python.org Mon Apr 27 22:45:13 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 27 Apr 2009 20:45:13 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 3.x Message-ID: <20090427204514.007DD1E401A@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%203.x/builds/829 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: eric.smith BUILD FAILED: failed compile sincerely, -The Buildbot From buildbot at python.org Mon Apr 27 22:45:35 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 27 Apr 2009 20:45:35 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 2.6 Message-ID: <20090427204535.E0AA71E4017@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%202.6/builds/284 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: eric.smith BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_bsddb3 make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 27 22:50:20 2009 From: python-checkins at python.org (antoine.pitrou) Date: Mon, 27 Apr 2009 22:50:20 +0200 (CEST) Subject: [Python-checkins] r72045 - in python/trunk: Lib/mimetypes.py Misc/NEWS Message-ID: <20090427205020.AAE511E403C@bag.python.org> Author: antoine.pitrou Date: Mon Apr 27 22:50:20 2009 New Revision: 72045 Log: Issue #5853: calling a function of the mimetypes module from several threads at once could hit the recursion limit if the mimetypes database hadn't been initialized before. Modified: python/trunk/Lib/mimetypes.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/mimetypes.py ============================================================================== --- python/trunk/Lib/mimetypes.py (original) +++ python/trunk/Lib/mimetypes.py Mon Apr 27 22:50:20 2009 @@ -44,6 +44,7 @@ ] inited = False +_db = None class MimeTypes: @@ -237,9 +238,9 @@ Optional `strict' argument when false adds a bunch of commonly found, but non-standard types. """ - if not inited: + if _db is None: init() - return guess_type(url, strict) + return _db.guess_type(url, strict) def guess_all_extensions(type, strict=True): @@ -255,9 +256,9 @@ Optional `strict' argument when false adds a bunch of commonly found, but non-standard types. """ - if not inited: + if _db is None: init() - return guess_all_extensions(type, strict) + return _db.guess_all_extensions(type, strict) def guess_extension(type, strict=True): """Guess the extension for a file based on its MIME type. @@ -271,9 +272,9 @@ Optional `strict' argument when false adds a bunch of commonly found, but non-standard types. """ - if not inited: + if _db is None: init() - return guess_extension(type, strict) + return _db.guess_extension(type, strict) def add_type(type, ext, strict=True): """Add a mapping between a type and an extension. @@ -287,16 +288,15 @@ list of standard types, else to the list of non-standard types. """ - if not inited: + if _db is None: init() - return add_type(type, ext, strict) + return _db.add_type(type, ext, strict) def init(files=None): - global guess_all_extensions, guess_extension, guess_type global suffix_map, types_map, encodings_map, common_types - global add_type, inited - inited = True + global inited, _db + inited = True # so that MimeTypes.__init__() doesn't call us again db = MimeTypes() if files is None: files = knownfiles @@ -306,11 +306,9 @@ encodings_map = db.encodings_map suffix_map = db.suffix_map types_map = db.types_map[True] - guess_all_extensions = db.guess_all_extensions - guess_extension = db.guess_extension - guess_type = db.guess_type - add_type = db.add_type common_types = db.types_map[False] + # Make the DB a global variable now that it is fully initialized + _db = db def read_mime_types(file): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Apr 27 22:50:20 2009 @@ -255,6 +255,10 @@ Library ------- +- Issue #5853: calling a function of the mimetypes module from several threads + at once could hit the recursion limit if the mimetypes database hadn't been + initialized before. + - Issue #5854: Updated __all__ to include some missing names and remove some names which should not be exported. From python-checkins at python.org Mon Apr 27 22:54:42 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 27 Apr 2009 22:54:42 +0200 (CEST) Subject: [Python-checkins] r72046 - in python/branches/py3k: Include/pyctype.h Python/pyctype.c Message-ID: <20090427205442.BD4961E4017@bag.python.org> Author: eric.smith Date: Mon Apr 27 22:54:42 2009 New Revision: 72046 Log: Include files missed in r72044. Added: python/branches/py3k/Include/pyctype.h python/branches/py3k/Python/pyctype.c Added: python/branches/py3k/Include/pyctype.h ============================================================================== --- (empty file) +++ python/branches/py3k/Include/pyctype.h Mon Apr 27 22:54:42 2009 @@ -0,0 +1,28 @@ +#ifndef PYCTYPE_H +#define PYCTYPE_H + +#define PY_CTF_LOWER 0x01 +#define PY_CTF_UPPER 0x02 +#define PY_CTF_ALPHA (PY_CTF_LOWER|PY_CTF_UPPER) +#define PY_CTF_DIGIT 0x04 +#define PY_CTF_ALNUM (PY_CTF_ALPHA|PY_CTF_DIGIT) +#define PY_CTF_SPACE 0x08 +#define PY_CTF_XDIGIT 0x10 + +extern const unsigned int _Py_ctype_table[256]; + +#define Py_ISLOWER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_LOWER) +#define Py_ISUPPER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_UPPER) +#define Py_ISALPHA(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALPHA) +#define Py_ISDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_DIGIT) +#define Py_ISXDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_XDIGIT) +#define Py_ISALNUM(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALNUM) +#define Py_ISSPACE(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_SPACE) + +extern const unsigned char _Py_ctype_tolower[256]; +extern const unsigned char _Py_ctype_toupper[256]; + +#define Py_TOLOWER(c) (_Py_ctype_tolower[Py_CHARMASK(c)]) +#define Py_TOUPPER(c) (_Py_ctype_toupper[Py_CHARMASK(c)]) + +#endif /* !PYCTYPE_H */ Added: python/branches/py3k/Python/pyctype.c ============================================================================== --- (empty file) +++ python/branches/py3k/Python/pyctype.c Mon Apr 27 22:54:42 2009 @@ -0,0 +1,214 @@ +#include "Python.h" + +/* Our own locale-independent ctype.h-like macros */ + +const unsigned int _Py_ctype_table[256] = { + 0, /* 0x0 '\x00' */ + 0, /* 0x1 '\x01' */ + 0, /* 0x2 '\x02' */ + 0, /* 0x3 '\x03' */ + 0, /* 0x4 '\x04' */ + 0, /* 0x5 '\x05' */ + 0, /* 0x6 '\x06' */ + 0, /* 0x7 '\x07' */ + 0, /* 0x8 '\x08' */ + PY_CTF_SPACE, /* 0x9 '\t' */ + PY_CTF_SPACE, /* 0xa '\n' */ + PY_CTF_SPACE, /* 0xb '\v' */ + PY_CTF_SPACE, /* 0xc '\f' */ + PY_CTF_SPACE, /* 0xd '\r' */ + 0, /* 0xe '\x0e' */ + 0, /* 0xf '\x0f' */ + 0, /* 0x10 '\x10' */ + 0, /* 0x11 '\x11' */ + 0, /* 0x12 '\x12' */ + 0, /* 0x13 '\x13' */ + 0, /* 0x14 '\x14' */ + 0, /* 0x15 '\x15' */ + 0, /* 0x16 '\x16' */ + 0, /* 0x17 '\x17' */ + 0, /* 0x18 '\x18' */ + 0, /* 0x19 '\x19' */ + 0, /* 0x1a '\x1a' */ + 0, /* 0x1b '\x1b' */ + 0, /* 0x1c '\x1c' */ + 0, /* 0x1d '\x1d' */ + 0, /* 0x1e '\x1e' */ + 0, /* 0x1f '\x1f' */ + PY_CTF_SPACE, /* 0x20 ' ' */ + 0, /* 0x21 '!' */ + 0, /* 0x22 '"' */ + 0, /* 0x23 '#' */ + 0, /* 0x24 '$' */ + 0, /* 0x25 '%' */ + 0, /* 0x26 '&' */ + 0, /* 0x27 "'" */ + 0, /* 0x28 '(' */ + 0, /* 0x29 ')' */ + 0, /* 0x2a '*' */ + 0, /* 0x2b '+' */ + 0, /* 0x2c ',' */ + 0, /* 0x2d '-' */ + 0, /* 0x2e '.' */ + 0, /* 0x2f '/' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x30 '0' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x31 '1' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x32 '2' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x33 '3' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x34 '4' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x35 '5' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x36 '6' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x37 '7' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x38 '8' */ + PY_CTF_DIGIT|PY_CTF_XDIGIT, /* 0x39 '9' */ + 0, /* 0x3a ':' */ + 0, /* 0x3b ';' */ + 0, /* 0x3c '<' */ + 0, /* 0x3d '=' */ + 0, /* 0x3e '>' */ + 0, /* 0x3f '?' */ + 0, /* 0x40 '@' */ + PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x41 'A' */ + PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x42 'B' */ + PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x43 'C' */ + PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x44 'D' */ + PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x45 'E' */ + PY_CTF_UPPER|PY_CTF_XDIGIT, /* 0x46 'F' */ + PY_CTF_UPPER, /* 0x47 'G' */ + PY_CTF_UPPER, /* 0x48 'H' */ + PY_CTF_UPPER, /* 0x49 'I' */ + PY_CTF_UPPER, /* 0x4a 'J' */ + PY_CTF_UPPER, /* 0x4b 'K' */ + PY_CTF_UPPER, /* 0x4c 'L' */ + PY_CTF_UPPER, /* 0x4d 'M' */ + PY_CTF_UPPER, /* 0x4e 'N' */ + PY_CTF_UPPER, /* 0x4f 'O' */ + PY_CTF_UPPER, /* 0x50 'P' */ + PY_CTF_UPPER, /* 0x51 'Q' */ + PY_CTF_UPPER, /* 0x52 'R' */ + PY_CTF_UPPER, /* 0x53 'S' */ + PY_CTF_UPPER, /* 0x54 'T' */ + PY_CTF_UPPER, /* 0x55 'U' */ + PY_CTF_UPPER, /* 0x56 'V' */ + PY_CTF_UPPER, /* 0x57 'W' */ + PY_CTF_UPPER, /* 0x58 'X' */ + PY_CTF_UPPER, /* 0x59 'Y' */ + PY_CTF_UPPER, /* 0x5a 'Z' */ + 0, /* 0x5b '[' */ + 0, /* 0x5c '\\' */ + 0, /* 0x5d ']' */ + 0, /* 0x5e '^' */ + 0, /* 0x5f '_' */ + 0, /* 0x60 '`' */ + PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x61 'a' */ + PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x62 'b' */ + PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x63 'c' */ + PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x64 'd' */ + PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x65 'e' */ + PY_CTF_LOWER|PY_CTF_XDIGIT, /* 0x66 'f' */ + PY_CTF_LOWER, /* 0x67 'g' */ + PY_CTF_LOWER, /* 0x68 'h' */ + PY_CTF_LOWER, /* 0x69 'i' */ + PY_CTF_LOWER, /* 0x6a 'j' */ + PY_CTF_LOWER, /* 0x6b 'k' */ + PY_CTF_LOWER, /* 0x6c 'l' */ + PY_CTF_LOWER, /* 0x6d 'm' */ + PY_CTF_LOWER, /* 0x6e 'n' */ + PY_CTF_LOWER, /* 0x6f 'o' */ + PY_CTF_LOWER, /* 0x70 'p' */ + PY_CTF_LOWER, /* 0x71 'q' */ + PY_CTF_LOWER, /* 0x72 'r' */ + PY_CTF_LOWER, /* 0x73 's' */ + PY_CTF_LOWER, /* 0x74 't' */ + PY_CTF_LOWER, /* 0x75 'u' */ + PY_CTF_LOWER, /* 0x76 'v' */ + PY_CTF_LOWER, /* 0x77 'w' */ + PY_CTF_LOWER, /* 0x78 'x' */ + PY_CTF_LOWER, /* 0x79 'y' */ + PY_CTF_LOWER, /* 0x7a 'z' */ + 0, /* 0x7b '{' */ + 0, /* 0x7c '|' */ + 0, /* 0x7d '}' */ + 0, /* 0x7e '~' */ + 0, /* 0x7f '\x7f' */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + + +const unsigned char _Py_ctype_tolower[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +const unsigned char _Py_ctype_toupper[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + From python-checkins at python.org Mon Apr 27 22:55:19 2009 From: python-checkins at python.org (eric.smith) Date: Mon, 27 Apr 2009 22:55:19 +0200 (CEST) Subject: [Python-checkins] r72047 - python/branches/release30-maint Message-ID: <20090427205519.6F88B1E4017@bag.python.org> Author: eric.smith Date: Mon Apr 27 22:55:19 2009 New Revision: 72047 Log: Blocked revisions 72046 via svnmerge ........ r72046 | eric.smith | 2009-04-27 16:54:42 -0400 (Mon, 27 Apr 2009) | 1 line Include files missed in r72044. ........ Modified: python/branches/release30-maint/ (props changed) From python-checkins at python.org Mon Apr 27 23:01:13 2009 From: python-checkins at python.org (antoine.pitrou) Date: Mon, 27 Apr 2009 23:01:13 +0200 (CEST) Subject: [Python-checkins] r72048 - in python/branches/release26-maint: Lib/mimetypes.py Misc/NEWS Message-ID: <20090427210113.BF2681E4017@bag.python.org> Author: antoine.pitrou Date: Mon Apr 27 23:01:13 2009 New Revision: 72048 Log: Merged revisions 72045 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72045 | antoine.pitrou | 2009-04-27 22:50:20 +0200 (lun., 27 avril 2009) | 5 lines Issue #5853: calling a function of the mimetypes module from several threads at once could hit the recursion limit if the mimetypes database hadn't been initialized before. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/mimetypes.py python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/mimetypes.py ============================================================================== --- python/branches/release26-maint/Lib/mimetypes.py (original) +++ python/branches/release26-maint/Lib/mimetypes.py Mon Apr 27 23:01:13 2009 @@ -44,6 +44,7 @@ ] inited = False +_db = None class MimeTypes: @@ -237,9 +238,9 @@ Optional `strict' argument when false adds a bunch of commonly found, but non-standard types. """ - if not inited: + if _db is None: init() - return guess_type(url, strict) + return _db.guess_type(url, strict) def guess_all_extensions(type, strict=True): @@ -255,9 +256,9 @@ Optional `strict' argument when false adds a bunch of commonly found, but non-standard types. """ - if not inited: + if _db is None: init() - return guess_all_extensions(type, strict) + return _db.guess_all_extensions(type, strict) def guess_extension(type, strict=True): """Guess the extension for a file based on its MIME type. @@ -271,9 +272,9 @@ Optional `strict' argument when false adds a bunch of commonly found, but non-standard types. """ - if not inited: + if _db is None: init() - return guess_extension(type, strict) + return _db.guess_extension(type, strict) def add_type(type, ext, strict=True): """Add a mapping between a type and an extension. @@ -287,16 +288,15 @@ list of standard types, else to the list of non-standard types. """ - if not inited: + if _db is None: init() - return add_type(type, ext, strict) + return _db.add_type(type, ext, strict) def init(files=None): - global guess_all_extensions, guess_extension, guess_type global suffix_map, types_map, encodings_map, common_types - global add_type, inited - inited = True + global inited, _db + inited = True # so that MimeTypes.__init__() doesn't call us again db = MimeTypes() if files is None: files = knownfiles @@ -306,11 +306,9 @@ encodings_map = db.encodings_map suffix_map = db.suffix_map types_map = db.types_map[True] - guess_all_extensions = db.guess_all_extensions - guess_extension = db.guess_extension - guess_type = db.guess_type - add_type = db.add_type common_types = db.types_map[False] + # Make the DB a global variable now that it is fully initialized + _db = db def read_mime_types(file): Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Mon Apr 27 23:01:13 2009 @@ -27,6 +27,10 @@ Library ------- +- Issue #5853: calling a function of the mimetypes module from several threads + at once could hit the recursion limit if the mimetypes database hadn't been + initialized before. + - Issue #5041: ctypes does now allow pickling wide character. - Issue #5768: Fixed bug in Unicode output logic and test case for same. From python-checkins at python.org Mon Apr 27 23:01:21 2009 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 27 Apr 2009 23:01:21 +0200 (CEST) Subject: [Python-checkins] r72049 - python/branches/py3k/Doc/library/difflib.rst Message-ID: <20090427210121.9D0F71E4017@bag.python.org> Author: raymond.hettinger Date: Mon Apr 27 23:01:21 2009 New Revision: 72049 Log: Add another example to the seealso section. 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 Mon Apr 27 23:01:21 2009 @@ -560,8 +560,15 @@ insert a[8:8] b[8:17] equal a[8:29] b[17:38] -See also the function :func:`get_close_matches` in this module, which shows how -simple code building on :class:`SequenceMatcher` can be used to do useful work. +.. seealso:: + + * The :func:`get_close_matches` function in this module which shows how + simple code building on :class:`SequenceMatcher` can be used to do useful + work. + + * `Simple version control recipe + `_ for a small application + built with :class:`SequenceMatcher`. .. _differ-objects: From python-checkins at python.org Mon Apr 27 23:04:19 2009 From: python-checkins at python.org (antoine.pitrou) Date: Mon, 27 Apr 2009 23:04:19 +0200 (CEST) Subject: [Python-checkins] r72050 - in python/branches/py3k: Lib/mimetypes.py Misc/NEWS Message-ID: <20090427210419.B28EE1E4017@bag.python.org> Author: antoine.pitrou Date: Mon Apr 27 23:04:19 2009 New Revision: 72050 Log: Merged revisions 72045 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72045 | antoine.pitrou | 2009-04-27 22:50:20 +0200 (lun., 27 avril 2009) | 5 lines Issue #5853: calling a function of the mimetypes module from several threads at once could hit the recursion limit if the mimetypes database hadn't been initialized before. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/mimetypes.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/mimetypes.py ============================================================================== --- python/branches/py3k/Lib/mimetypes.py (original) +++ python/branches/py3k/Lib/mimetypes.py Mon Apr 27 23:04:19 2009 @@ -44,6 +44,7 @@ ] inited = False +_db = None class MimeTypes: @@ -237,9 +238,9 @@ Optional `strict' argument when false adds a bunch of commonly found, but non-standard types. """ - if not inited: + if _db is None: init() - return guess_type(url, strict) + return _db.guess_type(url, strict) def guess_all_extensions(type, strict=True): @@ -255,9 +256,9 @@ Optional `strict' argument when false adds a bunch of commonly found, but non-standard types. """ - if not inited: + if _db is None: init() - return guess_all_extensions(type, strict) + return _db.guess_all_extensions(type, strict) def guess_extension(type, strict=True): """Guess the extension for a file based on its MIME type. @@ -271,9 +272,9 @@ Optional `strict' argument when false adds a bunch of commonly found, but non-standard types. """ - if not inited: + if _db is None: init() - return guess_extension(type, strict) + return _db.guess_extension(type, strict) def add_type(type, ext, strict=True): """Add a mapping between a type and an extension. @@ -287,16 +288,15 @@ list of standard types, else to the list of non-standard types. """ - if not inited: + if _db is None: init() - return add_type(type, ext, strict) + return _db.add_type(type, ext, strict) def init(files=None): - global guess_all_extensions, guess_extension, guess_type global suffix_map, types_map, encodings_map, common_types - global add_type, inited - inited = True + global inited, _db + inited = True # so that MimeTypes.__init__() doesn't call us again db = MimeTypes() if files is None: files = knownfiles @@ -306,11 +306,9 @@ encodings_map = db.encodings_map suffix_map = db.suffix_map types_map = db.types_map[True] - guess_all_extensions = db.guess_all_extensions - guess_extension = db.guess_extension - guess_type = db.guess_type - add_type = db.add_type common_types = db.types_map[False] + # Make the DB a global variable now that it is fully initialized + _db = db def read_mime_types(file): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Mon Apr 27 23:04:19 2009 @@ -92,6 +92,10 @@ Library ------- +- Issue #5853: calling a function of the mimetypes module from several threads + at once could hit the recursion limit if the mimetypes database hadn't been + initialized before. + - Issue #5854: Updated __all__ to include some missing names and remove some names which should not be exported. From python-checkins at python.org Mon Apr 27 23:06:06 2009 From: python-checkins at python.org (antoine.pitrou) Date: Mon, 27 Apr 2009 23:06:06 +0200 (CEST) Subject: [Python-checkins] r72051 - in python/branches/release30-maint: Lib/mimetypes.py Misc/NEWS Message-ID: <20090427210606.540EC1E4017@bag.python.org> Author: antoine.pitrou Date: Mon Apr 27 23:06:06 2009 New Revision: 72051 Log: Merged revisions 72050 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r72050 | antoine.pitrou | 2009-04-27 23:04:19 +0200 (lun., 27 avril 2009) | 11 lines Merged revisions 72045 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72045 | antoine.pitrou | 2009-04-27 22:50:20 +0200 (lun., 27 avril 2009) | 5 lines Issue #5853: calling a function of the mimetypes module from several threads at once could hit the recursion limit if the mimetypes database hadn't been initialized before. ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Lib/mimetypes.py python/branches/release30-maint/Misc/NEWS Modified: python/branches/release30-maint/Lib/mimetypes.py ============================================================================== --- python/branches/release30-maint/Lib/mimetypes.py (original) +++ python/branches/release30-maint/Lib/mimetypes.py Mon Apr 27 23:06:06 2009 @@ -44,6 +44,7 @@ ] inited = False +_db = None class MimeTypes: @@ -237,9 +238,9 @@ Optional `strict' argument when false adds a bunch of commonly found, but non-standard types. """ - if not inited: + if _db is None: init() - return guess_type(url, strict) + return _db.guess_type(url, strict) def guess_all_extensions(type, strict=True): @@ -255,9 +256,9 @@ Optional `strict' argument when false adds a bunch of commonly found, but non-standard types. """ - if not inited: + if _db is None: init() - return guess_all_extensions(type, strict) + return _db.guess_all_extensions(type, strict) def guess_extension(type, strict=True): """Guess the extension for a file based on its MIME type. @@ -271,9 +272,9 @@ Optional `strict' argument when false adds a bunch of commonly found, but non-standard types. """ - if not inited: + if _db is None: init() - return guess_extension(type, strict) + return _db.guess_extension(type, strict) def add_type(type, ext, strict=True): """Add a mapping between a type and an extension. @@ -287,16 +288,15 @@ list of standard types, else to the list of non-standard types. """ - if not inited: + if _db is None: init() - return add_type(type, ext, strict) + return _db.add_type(type, ext, strict) def init(files=None): - global guess_all_extensions, guess_extension, guess_type global suffix_map, types_map, encodings_map, common_types - global add_type, inited - inited = True + global inited, _db + inited = True # so that MimeTypes.__init__() doesn't call us again db = MimeTypes() if files is None: files = knownfiles @@ -306,11 +306,9 @@ encodings_map = db.encodings_map suffix_map = db.suffix_map types_map = db.types_map[True] - guess_all_extensions = db.guess_all_extensions - guess_extension = db.guess_extension - guess_type = db.guess_type - add_type = db.add_type common_types = db.types_map[False] + # Make the DB a global variable now that it is fully initialized + _db = db def read_mime_types(file): Modified: python/branches/release30-maint/Misc/NEWS ============================================================================== --- python/branches/release30-maint/Misc/NEWS (original) +++ python/branches/release30-maint/Misc/NEWS Mon Apr 27 23:06:06 2009 @@ -42,6 +42,10 @@ Library ------- +- Issue #5853: calling a function of the mimetypes module from several threads + at once could hit the recursion limit if the mimetypes database hadn't been + initialized before. + - Issue 5830: The sched module no longer raises a TypeError when prioritizing Events with the same time and priority. From python-checkins at python.org Mon Apr 27 23:12:27 2009 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 27 Apr 2009 23:12:27 +0200 (CEST) Subject: [Python-checkins] r72052 - python/trunk/Lib/decimal.py Message-ID: <20090427211227.642901E401C@bag.python.org> Author: raymond.hettinger Date: Mon Apr 27 23:12:27 2009 New Revision: 72052 Log: Update spec version number. Modified: python/trunk/Lib/decimal.py Modified: python/trunk/Lib/decimal.py ============================================================================== --- python/trunk/Lib/decimal.py (original) +++ python/trunk/Lib/decimal.py Mon Apr 27 23:12:27 2009 @@ -134,7 +134,7 @@ 'setcontext', 'getcontext', 'localcontext' ] -__version__ = '1.68' # Highest version of the spec this complies with +__version__ = '1.70' # Highest version of the spec this complies with import copy as _copy import math as _math From python-checkins at python.org Mon Apr 27 23:12:54 2009 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 27 Apr 2009 23:12:54 +0200 (CEST) Subject: [Python-checkins] r72053 - python/trunk/Doc/library/difflib.rst Message-ID: <20090427211254.4E4601E401A@bag.python.org> Author: raymond.hettinger Date: Mon Apr 27 23:12:54 2009 New Revision: 72053 Log: Add example to the seealso section. Modified: python/trunk/Doc/library/difflib.rst Modified: python/trunk/Doc/library/difflib.rst ============================================================================== --- python/trunk/Doc/library/difflib.rst (original) +++ python/trunk/Doc/library/difflib.rst Mon Apr 27 23:12:54 2009 @@ -577,8 +577,15 @@ insert a[8:8] b[8:17] equal a[8:29] b[17:38] -See also the function :func:`get_close_matches` in this module, which shows how -simple code building on :class:`SequenceMatcher` can be used to do useful work. +.. seealso:: + + * The :func:`get_close_matches` function in this module which shows how + simple code building on :class:`SequenceMatcher` can be used to do useful + work. + + * `Simple version control recipe + `_ for a small application + built with :class:`SequenceMatcher`. .. _differ-objects: From buildbot at python.org Mon Apr 27 23:20:39 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 27 Apr 2009 21:20:39 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 2.6 Message-ID: <20090427212039.E1E581E401A@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%202.6/builds/287 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: eric.smith BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_pydoc ====================================================================== FAIL: test_html_doc (test.test_pydoc.PyDocDocTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/test/test_pydoc.py", line 223, in test_html_doc self.fail("outputs are not equal, see diff above") AssertionError: outputs are not equal, see diff above ====================================================================== FAIL: test_text_doc (test.test_pydoc.PyDocDocTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/2.6.klose-debian-ia64/build/Lib/test/test_pydoc.py", line 231, in test_text_doc self.fail("outputs are not equal, see diff above") AssertionError: outputs are not equal, see diff above make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Mon Apr 27 23:53:27 2009 From: python-checkins at python.org (antoine.pitrou) Date: Mon, 27 Apr 2009 23:53:27 +0200 (CEST) Subject: [Python-checkins] r72054 - in python/trunk: Misc/ACKS Misc/NEWS Modules/unicodedata.c Modules/unicodedata_db.h Tools/unicode/makeunicodedata.py Message-ID: <20090427215327.625C01E401A@bag.python.org> Author: antoine.pitrou Date: Mon Apr 27 23:53:26 2009 New Revision: 72054 Log: Issue #1734234: Massively speedup `unicodedata.normalize()` when the string is already in normalized form, by performing a quick check beforehand. Original patch by Rauli Ruohonen. Modified: python/trunk/Misc/ACKS python/trunk/Misc/NEWS python/trunk/Modules/unicodedata.c python/trunk/Modules/unicodedata_db.h python/trunk/Tools/unicode/makeunicodedata.py Modified: python/trunk/Misc/ACKS ============================================================================== --- python/trunk/Misc/ACKS (original) +++ python/trunk/Misc/ACKS Mon Apr 27 23:53:26 2009 @@ -612,6 +612,7 @@ Paul Rubin Sam Ruby Audun S. Runde +Rauli Ruohonen Jeff Rush Sam Rushing Mark Russell Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Mon Apr 27 23:53:26 2009 @@ -255,6 +255,10 @@ Library ------- +- Issue #1734234: Massively speedup ``unicodedata.normalize()`` when the + string is already in normalized form, by performing a quick check beforehand. + Original patch by Rauli Ruohonen. + - Issue #5853: calling a function of the mimetypes module from several threads at once could hit the recursion limit if the mimetypes database hadn't been initialized before. Modified: python/trunk/Modules/unicodedata.c ============================================================================== --- python/trunk/Modules/unicodedata.c (original) +++ python/trunk/Modules/unicodedata.c Mon Apr 27 23:53:26 2009 @@ -27,6 +27,7 @@ const unsigned char mirrored; /* true if mirrored in bidir mode */ const unsigned char east_asian_width; /* index into _PyUnicode_EastAsianWidth */ + const unsigned char normalization_quick_check; /* see is_normalized() */ } _PyUnicode_DatabaseRecord; typedef struct change_record { @@ -720,7 +721,39 @@ PyUnicode_Resize(&result, o - PyUnicode_AS_UNICODE(result)); return result; } - + +/* Return 1 if the input is certainly normalized, 0 if it might not be. */ +static int +is_normalized(PyObject *self, PyObject *input, int nfc, int k) +{ + Py_UNICODE *i, *end; + unsigned char prev_combining = 0, quickcheck_mask; + + /* An older version of the database is requested, quickchecks must be + disabled. */ + if (self != NULL) + return 0; + + /* The two quickcheck bits at this shift mean 0=Yes, 1=Maybe, 2=No, + as described in http://unicode.org/reports/tr15/#Annex8. */ + quickcheck_mask = 3 << ((nfc ? 4 : 0) + (k ? 2 : 0)); + + i = PyUnicode_AS_UNICODE(input); + end = i + PyUnicode_GET_SIZE(input); + while (i < end) { + const _PyUnicode_DatabaseRecord *record = _getrecord_ex(*i++); + unsigned char combining = record->combining; + unsigned char quickcheck = record->normalization_quick_check; + + if (quickcheck & quickcheck_mask) + return 0; /* this string might need normalization */ + if (combining && prev_combining > combining) + return 0; /* non-canonical sort order, not normalized */ + prev_combining = combining; + } + return 1; /* certainly normalized */ +} + PyDoc_STRVAR(unicodedata_normalize__doc__, "normalize(form, unistr)\n\ \n\ @@ -744,14 +777,34 @@ return input; } - if (strcmp(form, "NFC") == 0) + if (strcmp(form, "NFC") == 0) { + if (is_normalized(self, input, 1, 0)) { + Py_INCREF(input); + return input; + } return nfc_nfkc(self, input, 0); - if (strcmp(form, "NFKC") == 0) + } + if (strcmp(form, "NFKC") == 0) { + if (is_normalized(self, input, 1, 1)) { + Py_INCREF(input); + return input; + } return nfc_nfkc(self, input, 1); - if (strcmp(form, "NFD") == 0) + } + if (strcmp(form, "NFD") == 0) { + if (is_normalized(self, input, 0, 0)) { + Py_INCREF(input); + return input; + } return nfd_nfkd(self, input, 0); - if (strcmp(form, "NFKD") == 0) + } + if (strcmp(form, "NFKD") == 0) { + if (is_normalized(self, input, 0, 1)) { + Py_INCREF(input); + return input; + } return nfd_nfkd(self, input, 1); + } PyErr_SetString(PyExc_ValueError, "invalid normalization form"); return NULL; } Modified: python/trunk/Modules/unicodedata_db.h ============================================================================== --- python/trunk/Modules/unicodedata_db.h (original) +++ python/trunk/Modules/unicodedata_db.h Mon Apr 27 23:53:26 2009 @@ -3,235 +3,323 @@ #define UNIDATA_VERSION "5.1.0" /* a list of unique database records */ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { - {0, 0, 0, 0, 0}, - {13, 0, 15, 0, 5}, - {13, 0, 17, 0, 5}, - {13, 0, 16, 0, 5}, - {13, 0, 18, 0, 5}, - {10, 0, 18, 0, 3}, - {26, 0, 19, 0, 3}, - {26, 0, 11, 0, 3}, - {28, 0, 11, 0, 3}, - {22, 0, 19, 1, 3}, - {23, 0, 19, 1, 3}, - {27, 0, 10, 0, 3}, - {26, 0, 13, 0, 3}, - {21, 0, 10, 0, 3}, - {7, 0, 9, 0, 3}, - {27, 0, 19, 1, 3}, - {27, 0, 19, 0, 3}, - {1, 0, 1, 0, 3}, - {29, 0, 19, 0, 3}, - {20, 0, 19, 0, 3}, - {2, 0, 1, 0, 3}, - {10, 0, 13, 0, 5}, - {26, 0, 19, 0, 4}, - {28, 0, 11, 0, 4}, - {30, 0, 19, 0, 3}, - {30, 0, 19, 0, 4}, - {29, 0, 19, 0, 4}, - {30, 0, 19, 0, 5}, - {2, 0, 1, 0, 4}, - {24, 0, 19, 1, 5}, - {14, 0, 15, 0, 4}, - {30, 0, 11, 0, 4}, - {27, 0, 11, 0, 4}, - {9, 0, 9, 0, 4}, - {2, 0, 1, 0, 5}, - {25, 0, 19, 1, 5}, - {9, 0, 19, 0, 4}, - {1, 0, 1, 0, 5}, - {1, 0, 1, 0, 4}, - {27, 0, 19, 0, 4}, - {19, 0, 1, 0, 5}, - {3, 0, 1, 0, 5}, - {18, 0, 1, 0, 5}, - {18, 0, 19, 0, 5}, - {29, 0, 19, 0, 5}, - {18, 0, 19, 0, 4}, - {18, 0, 1, 0, 4}, - {4, 230, 14, 0, 4}, - {4, 232, 14, 0, 4}, - {4, 220, 14, 0, 4}, - {4, 216, 14, 0, 4}, - {4, 202, 14, 0, 4}, - {4, 1, 14, 0, 4}, - {4, 240, 14, 0, 4}, - {4, 0, 14, 0, 4}, - {4, 233, 14, 0, 4}, - {4, 234, 14, 0, 4}, - {26, 0, 19, 0, 5}, - {27, 0, 19, 0, 5}, - {30, 0, 1, 0, 5}, - {4, 230, 14, 0, 5}, - {6, 0, 14, 0, 5}, - {26, 0, 1, 0, 5}, - {21, 0, 19, 0, 5}, - {4, 220, 14, 0, 5}, - {4, 222, 14, 0, 5}, - {4, 228, 14, 0, 5}, - {4, 10, 14, 0, 5}, - {4, 11, 14, 0, 5}, - {4, 12, 14, 0, 5}, - {4, 13, 14, 0, 5}, - {4, 14, 14, 0, 5}, - {4, 15, 14, 0, 5}, - {4, 16, 14, 0, 5}, - {4, 17, 14, 0, 5}, - {4, 18, 14, 0, 5}, - {4, 19, 14, 0, 5}, - {4, 20, 14, 0, 5}, - {4, 21, 14, 0, 5}, - {4, 22, 14, 0, 5}, - {21, 0, 4, 0, 5}, - {4, 23, 14, 0, 5}, - {26, 0, 4, 0, 5}, - {4, 24, 14, 0, 5}, - {4, 25, 14, 0, 5}, - {19, 0, 4, 0, 5}, - {14, 0, 12, 0, 5}, - {27, 0, 5, 0, 5}, - {26, 0, 11, 0, 5}, - {28, 0, 5, 0, 5}, - {26, 0, 13, 0, 5}, - {26, 0, 5, 0, 5}, - {4, 30, 14, 0, 5}, - {4, 31, 14, 0, 5}, - {4, 32, 14, 0, 5}, - {19, 0, 5, 0, 5}, - {18, 0, 5, 0, 5}, - {4, 27, 14, 0, 5}, - {4, 28, 14, 0, 5}, - {4, 29, 14, 0, 5}, - {4, 33, 14, 0, 5}, - {4, 34, 14, 0, 5}, - {7, 0, 12, 0, 5}, - {26, 0, 12, 0, 5}, - {4, 35, 14, 0, 5}, - {7, 0, 9, 0, 5}, - {30, 0, 5, 0, 5}, - {14, 0, 15, 0, 5}, - {4, 36, 14, 0, 5}, - {4, 0, 14, 0, 5}, - {7, 0, 4, 0, 5}, - {18, 0, 4, 0, 5}, - {5, 0, 1, 0, 5}, - {4, 7, 14, 0, 5}, - {4, 9, 14, 0, 5}, - {7, 0, 1, 0, 5}, - {28, 0, 11, 0, 5}, - {9, 0, 1, 0, 5}, - {4, 84, 14, 0, 5}, - {4, 91, 14, 0, 5}, - {9, 0, 19, 0, 5}, - {4, 0, 1, 0, 5}, - {4, 103, 14, 0, 5}, - {4, 107, 14, 0, 5}, - {4, 118, 14, 0, 5}, - {4, 122, 14, 0, 5}, - {4, 216, 14, 0, 5}, - {22, 0, 19, 1, 5}, - {23, 0, 19, 1, 5}, - {4, 129, 14, 0, 5}, - {4, 130, 14, 0, 5}, - {4, 132, 14, 0, 5}, - {19, 0, 1, 0, 2}, - {10, 0, 18, 0, 5}, - {8, 0, 1, 0, 5}, - {14, 0, 1, 0, 5}, - {5, 9, 1, 0, 5}, - {4, 234, 14, 0, 5}, - {4, 214, 14, 0, 5}, - {4, 202, 14, 0, 5}, - {14, 0, 4, 0, 5}, - {21, 0, 19, 0, 4}, - {24, 0, 19, 0, 4}, - {25, 0, 19, 0, 4}, - {22, 0, 19, 0, 5}, - {24, 0, 19, 0, 5}, - {11, 0, 18, 0, 5}, - {12, 0, 16, 0, 5}, - {14, 0, 2, 0, 5}, - {14, 0, 6, 0, 5}, - {14, 0, 8, 0, 5}, - {14, 0, 3, 0, 5}, - {14, 0, 7, 0, 5}, - {26, 0, 11, 0, 4}, - {20, 0, 19, 0, 5}, - {27, 0, 13, 0, 5}, - {9, 0, 9, 0, 5}, - {27, 0, 10, 0, 5}, - {28, 0, 11, 0, 1}, - {4, 1, 14, 0, 5}, - {30, 0, 11, 0, 5}, - {27, 0, 19, 1, 5}, - {8, 0, 1, 0, 4}, - {27, 0, 19, 1, 4}, - {27, 0, 11, 0, 5}, - {22, 0, 19, 1, 2}, - {23, 0, 19, 1, 2}, - {30, 0, 1, 0, 4}, - {30, 0, 19, 0, 2}, - {10, 0, 18, 0, 0}, - {26, 0, 19, 0, 2}, - {18, 0, 1, 0, 2}, - {8, 0, 1, 0, 2}, - {21, 0, 19, 0, 2}, - {22, 0, 19, 0, 2}, - {23, 0, 19, 0, 2}, - {4, 218, 14, 0, 2}, - {4, 228, 14, 0, 2}, - {4, 232, 14, 0, 2}, - {4, 222, 14, 0, 2}, - {4, 224, 14, 0, 2}, - {4, 8, 14, 0, 2}, - {29, 0, 19, 0, 2}, - {30, 0, 1, 0, 2}, - {9, 0, 1, 0, 2}, - {9, 0, 19, 0, 2}, - {29, 0, 1, 0, 5}, - {15, 0, 1, 0, 5}, - {16, 0, 1, 0, 4}, - {4, 26, 14, 0, 5}, - {23, 0, 19, 0, 5}, - {20, 0, 19, 0, 2}, - {26, 0, 13, 0, 2}, - {26, 0, 11, 0, 2}, - {27, 0, 10, 0, 2}, - {21, 0, 10, 0, 2}, - {27, 0, 19, 1, 2}, - {27, 0, 19, 0, 2}, - {28, 0, 11, 0, 2}, - {26, 0, 19, 0, 0}, - {26, 0, 11, 0, 0}, - {28, 0, 11, 0, 0}, - {22, 0, 19, 1, 0}, - {23, 0, 19, 1, 0}, - {27, 0, 10, 0, 0}, - {26, 0, 13, 0, 0}, - {21, 0, 10, 0, 0}, - {7, 0, 9, 0, 0}, - {27, 0, 19, 1, 0}, - {27, 0, 19, 0, 0}, - {1, 0, 1, 0, 0}, - {29, 0, 19, 0, 0}, - {20, 0, 19, 0, 0}, - {2, 0, 1, 0, 0}, - {26, 0, 19, 0, 1}, - {22, 0, 19, 1, 1}, - {23, 0, 19, 1, 1}, - {19, 0, 1, 0, 1}, - {18, 0, 1, 0, 1}, - {30, 0, 19, 0, 0}, - {30, 0, 19, 0, 1}, - {27, 0, 19, 0, 1}, - {14, 0, 19, 0, 5}, - {8, 0, 19, 0, 5}, - {9, 0, 4, 0, 5}, - {5, 216, 1, 0, 5}, - {5, 226, 1, 0, 5}, - {27, 0, 1, 0, 5}, - {27, 0, 1, 1, 5}, + {0, 0, 0, 0, 0, 0}, + {13, 0, 15, 0, 5, 0}, + {13, 0, 17, 0, 5, 0}, + {13, 0, 16, 0, 5, 0}, + {13, 0, 18, 0, 5, 0}, + {10, 0, 18, 0, 3, 0}, + {26, 0, 19, 0, 3, 0}, + {26, 0, 11, 0, 3, 0}, + {28, 0, 11, 0, 3, 0}, + {22, 0, 19, 1, 3, 0}, + {23, 0, 19, 1, 3, 0}, + {27, 0, 10, 0, 3, 0}, + {26, 0, 13, 0, 3, 0}, + {21, 0, 10, 0, 3, 0}, + {7, 0, 9, 0, 3, 0}, + {27, 0, 19, 1, 3, 0}, + {27, 0, 19, 0, 3, 0}, + {1, 0, 1, 0, 3, 0}, + {29, 0, 19, 0, 3, 0}, + {20, 0, 19, 0, 3, 0}, + {2, 0, 1, 0, 3, 0}, + {10, 0, 13, 0, 5, 136}, + {26, 0, 19, 0, 4, 0}, + {28, 0, 11, 0, 4, 0}, + {30, 0, 19, 0, 3, 0}, + {30, 0, 19, 0, 4, 0}, + {29, 0, 19, 0, 4, 136}, + {30, 0, 19, 0, 5, 0}, + {2, 0, 1, 0, 4, 136}, + {24, 0, 19, 1, 5, 0}, + {14, 0, 15, 0, 4, 0}, + {29, 0, 19, 0, 3, 136}, + {30, 0, 11, 0, 4, 0}, + {27, 0, 11, 0, 4, 0}, + {9, 0, 9, 0, 4, 136}, + {2, 0, 1, 0, 5, 136}, + {25, 0, 19, 1, 5, 0}, + {9, 0, 19, 0, 4, 136}, + {1, 0, 1, 0, 5, 10}, + {1, 0, 1, 0, 4, 0}, + {27, 0, 19, 0, 4, 0}, + {2, 0, 1, 0, 4, 0}, + {2, 0, 1, 0, 4, 10}, + {2, 0, 1, 0, 5, 10}, + {1, 0, 1, 0, 5, 0}, + {1, 0, 1, 0, 4, 136}, + {2, 0, 1, 0, 5, 0}, + {19, 0, 1, 0, 5, 0}, + {1, 0, 1, 0, 5, 136}, + {3, 0, 1, 0, 5, 136}, + {18, 0, 1, 0, 5, 136}, + {18, 0, 19, 0, 5, 0}, + {18, 0, 1, 0, 5, 0}, + {29, 0, 19, 0, 5, 0}, + {29, 0, 19, 0, 4, 0}, + {18, 0, 19, 0, 4, 0}, + {18, 0, 1, 0, 4, 0}, + {29, 0, 19, 0, 5, 136}, + {4, 230, 14, 0, 4, 80}, + {4, 230, 14, 0, 4, 0}, + {4, 232, 14, 0, 4, 0}, + {4, 220, 14, 0, 4, 0}, + {4, 216, 14, 0, 4, 80}, + {4, 202, 14, 0, 4, 0}, + {4, 220, 14, 0, 4, 80}, + {4, 202, 14, 0, 4, 80}, + {4, 1, 14, 0, 4, 0}, + {4, 1, 14, 0, 4, 80}, + {4, 230, 14, 0, 4, 170}, + {4, 240, 14, 0, 4, 80}, + {4, 0, 14, 0, 4, 0}, + {4, 233, 14, 0, 4, 0}, + {4, 234, 14, 0, 4, 0}, + {18, 0, 19, 0, 5, 170}, + {26, 0, 19, 0, 5, 170}, + {29, 0, 19, 0, 5, 138}, + {1, 0, 1, 0, 5, 138}, + {27, 0, 19, 0, 5, 0}, + {1, 0, 1, 0, 4, 10}, + {30, 0, 1, 0, 5, 0}, + {4, 230, 14, 0, 5, 0}, + {6, 0, 14, 0, 5, 0}, + {26, 0, 1, 0, 5, 0}, + {21, 0, 19, 0, 5, 0}, + {4, 220, 14, 0, 5, 0}, + {4, 222, 14, 0, 5, 0}, + {4, 228, 14, 0, 5, 0}, + {4, 10, 14, 0, 5, 0}, + {4, 11, 14, 0, 5, 0}, + {4, 12, 14, 0, 5, 0}, + {4, 13, 14, 0, 5, 0}, + {4, 14, 14, 0, 5, 0}, + {4, 15, 14, 0, 5, 0}, + {4, 16, 14, 0, 5, 0}, + {4, 17, 14, 0, 5, 0}, + {4, 18, 14, 0, 5, 0}, + {4, 19, 14, 0, 5, 0}, + {4, 20, 14, 0, 5, 0}, + {4, 21, 14, 0, 5, 0}, + {4, 22, 14, 0, 5, 0}, + {21, 0, 4, 0, 5, 0}, + {4, 23, 14, 0, 5, 0}, + {26, 0, 4, 0, 5, 0}, + {4, 24, 14, 0, 5, 0}, + {4, 25, 14, 0, 5, 0}, + {19, 0, 4, 0, 5, 0}, + {14, 0, 12, 0, 5, 0}, + {27, 0, 5, 0, 5, 0}, + {26, 0, 11, 0, 5, 0}, + {28, 0, 5, 0, 5, 0}, + {26, 0, 13, 0, 5, 0}, + {26, 0, 5, 0, 5, 0}, + {4, 30, 14, 0, 5, 0}, + {4, 31, 14, 0, 5, 0}, + {4, 32, 14, 0, 5, 0}, + {19, 0, 5, 0, 5, 0}, + {19, 0, 5, 0, 5, 10}, + {18, 0, 5, 0, 5, 0}, + {4, 27, 14, 0, 5, 0}, + {4, 28, 14, 0, 5, 0}, + {4, 29, 14, 0, 5, 0}, + {4, 33, 14, 0, 5, 0}, + {4, 34, 14, 0, 5, 0}, + {4, 230, 14, 0, 5, 80}, + {4, 220, 14, 0, 5, 80}, + {7, 0, 12, 0, 5, 0}, + {26, 0, 12, 0, 5, 0}, + {4, 35, 14, 0, 5, 0}, + {19, 0, 5, 0, 5, 136}, + {7, 0, 9, 0, 5, 0}, + {30, 0, 5, 0, 5, 0}, + {14, 0, 15, 0, 5, 0}, + {4, 36, 14, 0, 5, 0}, + {4, 0, 14, 0, 5, 0}, + {7, 0, 4, 0, 5, 0}, + {18, 0, 4, 0, 5, 0}, + {26, 0, 19, 0, 5, 0}, + {5, 0, 1, 0, 5, 0}, + {19, 0, 1, 0, 5, 10}, + {4, 7, 14, 0, 5, 80}, + {4, 9, 14, 0, 5, 0}, + {19, 0, 1, 0, 5, 170}, + {7, 0, 1, 0, 5, 0}, + {4, 7, 14, 0, 5, 0}, + {5, 0, 1, 0, 5, 80}, + {5, 0, 1, 0, 5, 10}, + {28, 0, 11, 0, 5, 0}, + {9, 0, 1, 0, 5, 0}, + {4, 0, 14, 0, 5, 80}, + {4, 0, 14, 0, 5, 10}, + {4, 84, 14, 0, 5, 0}, + {4, 91, 14, 0, 5, 80}, + {9, 0, 19, 0, 5, 0}, + {4, 0, 1, 0, 5, 0}, + {4, 9, 14, 0, 5, 80}, + {19, 0, 1, 0, 5, 136}, + {4, 103, 14, 0, 5, 0}, + {4, 107, 14, 0, 5, 0}, + {4, 118, 14, 0, 5, 0}, + {4, 122, 14, 0, 5, 0}, + {26, 0, 1, 0, 5, 136}, + {4, 216, 14, 0, 5, 0}, + {22, 0, 19, 1, 5, 0}, + {23, 0, 19, 1, 5, 0}, + {4, 129, 14, 0, 5, 0}, + {4, 130, 14, 0, 5, 0}, + {4, 0, 14, 0, 5, 170}, + {4, 132, 14, 0, 5, 0}, + {4, 0, 14, 0, 5, 136}, + {19, 0, 1, 0, 2, 0}, + {19, 0, 1, 0, 5, 80}, + {10, 0, 18, 0, 5, 0}, + {8, 0, 1, 0, 5, 0}, + {14, 0, 1, 0, 5, 0}, + {5, 9, 1, 0, 5, 0}, + {4, 234, 14, 0, 5, 0}, + {4, 214, 14, 0, 5, 0}, + {4, 202, 14, 0, 5, 0}, + {2, 0, 1, 0, 5, 138}, + {2, 0, 1, 0, 5, 170}, + {3, 0, 1, 0, 5, 10}, + {1, 0, 1, 0, 5, 170}, + {29, 0, 19, 0, 5, 170}, + {10, 0, 18, 0, 5, 170}, + {10, 0, 18, 0, 5, 136}, + {14, 0, 4, 0, 5, 0}, + {21, 0, 19, 0, 4, 0}, + {21, 0, 19, 0, 5, 136}, + {26, 0, 19, 0, 5, 136}, + {24, 0, 19, 0, 4, 0}, + {25, 0, 19, 0, 4, 0}, + {22, 0, 19, 0, 5, 0}, + {24, 0, 19, 0, 5, 0}, + {26, 0, 19, 0, 4, 136}, + {11, 0, 18, 0, 5, 0}, + {12, 0, 16, 0, 5, 0}, + {14, 0, 2, 0, 5, 0}, + {14, 0, 6, 0, 5, 0}, + {14, 0, 8, 0, 5, 0}, + {14, 0, 3, 0, 5, 0}, + {14, 0, 7, 0, 5, 0}, + {26, 0, 11, 0, 4, 0}, + {26, 0, 11, 0, 4, 136}, + {26, 0, 11, 0, 5, 136}, + {20, 0, 19, 0, 5, 0}, + {27, 0, 13, 0, 5, 0}, + {9, 0, 9, 0, 5, 136}, + {27, 0, 10, 0, 5, 136}, + {27, 0, 19, 0, 5, 136}, + {22, 0, 19, 1, 5, 136}, + {23, 0, 19, 1, 5, 136}, + {28, 0, 11, 0, 5, 136}, + {28, 0, 11, 0, 1, 0}, + {4, 1, 14, 0, 5, 0}, + {30, 0, 19, 0, 5, 136}, + {30, 0, 19, 0, 4, 136}, + {1, 0, 1, 0, 4, 170}, + {30, 0, 11, 0, 5, 0}, + {27, 0, 19, 1, 5, 136}, + {9, 0, 19, 0, 5, 136}, + {8, 0, 1, 0, 4, 136}, + {8, 0, 1, 0, 5, 136}, + {27, 0, 19, 0, 5, 10}, + {30, 0, 19, 0, 5, 10}, + {27, 0, 19, 1, 5, 0}, + {27, 0, 19, 1, 4, 0}, + {27, 0, 19, 1, 5, 10}, + {27, 0, 10, 0, 5, 0}, + {27, 0, 11, 0, 5, 0}, + {27, 0, 19, 1, 4, 136}, + {27, 0, 19, 1, 4, 10}, + {22, 0, 19, 1, 2, 170}, + {23, 0, 19, 1, 2, 170}, + {30, 0, 1, 0, 4, 136}, + {9, 0, 19, 0, 4, 0}, + {27, 0, 19, 1, 5, 170}, + {30, 0, 19, 0, 2, 0}, + {30, 0, 19, 0, 2, 136}, + {10, 0, 18, 0, 0, 136}, + {26, 0, 19, 0, 2, 0}, + {18, 0, 1, 0, 2, 0}, + {8, 0, 1, 0, 2, 0}, + {22, 0, 19, 1, 2, 0}, + {23, 0, 19, 1, 2, 0}, + {21, 0, 19, 0, 2, 0}, + {22, 0, 19, 0, 2, 0}, + {23, 0, 19, 0, 2, 0}, + {4, 218, 14, 0, 2, 0}, + {4, 228, 14, 0, 2, 0}, + {4, 232, 14, 0, 2, 0}, + {4, 222, 14, 0, 2, 0}, + {4, 224, 14, 0, 2, 0}, + {8, 0, 1, 0, 2, 136}, + {19, 0, 1, 0, 2, 10}, + {4, 8, 14, 0, 2, 80}, + {29, 0, 19, 0, 2, 136}, + {18, 0, 1, 0, 2, 10}, + {19, 0, 1, 0, 2, 136}, + {30, 0, 1, 0, 2, 0}, + {9, 0, 1, 0, 2, 136}, + {30, 0, 1, 0, 2, 136}, + {9, 0, 19, 0, 2, 136}, + {29, 0, 1, 0, 5, 0}, + {15, 0, 1, 0, 5, 0}, + {16, 0, 1, 0, 4, 0}, + {19, 0, 1, 0, 2, 170}, + {19, 0, 4, 0, 5, 170}, + {4, 26, 14, 0, 5, 0}, + {19, 0, 4, 0, 5, 136}, + {23, 0, 19, 0, 5, 0}, + {28, 0, 5, 0, 5, 136}, + {26, 0, 19, 0, 2, 136}, + {22, 0, 19, 0, 2, 136}, + {23, 0, 19, 0, 2, 136}, + {21, 0, 19, 0, 2, 136}, + {20, 0, 19, 0, 2, 136}, + {26, 0, 13, 0, 2, 136}, + {22, 0, 19, 1, 2, 136}, + {23, 0, 19, 1, 2, 136}, + {26, 0, 11, 0, 2, 136}, + {27, 0, 10, 0, 2, 136}, + {21, 0, 10, 0, 2, 136}, + {27, 0, 19, 1, 2, 136}, + {27, 0, 19, 0, 2, 136}, + {28, 0, 11, 0, 2, 136}, + {26, 0, 19, 0, 0, 136}, + {26, 0, 11, 0, 0, 136}, + {28, 0, 11, 0, 0, 136}, + {22, 0, 19, 1, 0, 136}, + {23, 0, 19, 1, 0, 136}, + {27, 0, 10, 0, 0, 136}, + {26, 0, 13, 0, 0, 136}, + {21, 0, 10, 0, 0, 136}, + {7, 0, 9, 0, 0, 136}, + {27, 0, 19, 1, 0, 136}, + {27, 0, 19, 0, 0, 136}, + {1, 0, 1, 0, 0, 136}, + {29, 0, 19, 0, 0, 136}, + {20, 0, 19, 0, 0, 136}, + {2, 0, 1, 0, 0, 136}, + {26, 0, 19, 0, 1, 136}, + {22, 0, 19, 1, 1, 136}, + {23, 0, 19, 1, 1, 136}, + {19, 0, 1, 0, 1, 136}, + {18, 0, 1, 0, 1, 136}, + {30, 0, 19, 0, 0, 136}, + {30, 0, 19, 0, 1, 136}, + {27, 0, 19, 0, 1, 136}, + {14, 0, 19, 0, 5, 0}, + {8, 0, 19, 0, 5, 0}, + {9, 0, 4, 0, 5, 0}, + {30, 0, 1, 0, 5, 170}, + {5, 216, 1, 0, 5, 0}, + {5, 226, 1, 0, 5, 0}, + {27, 0, 1, 0, 5, 136}, + {27, 0, 1, 1, 5, 136}, + {7, 0, 9, 0, 5, 136}, }; /* Reindexing of NFC first characters. */ @@ -568,206 +656,514 @@ NULL }; /* index tables for the database records */ -#define SHIFT 8 +#define SHIFT 7 static unsigned char index1[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 53, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 54, 55, 52, 52, 52, 56, - 21, 57, 58, 59, 60, 61, 8, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 62, 63, 63, 63, - 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 52, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 8, 8, 8, 76, 77, 78, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 21, 21, 21, 79, 80, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 81, 82, - 83, 84, 85, 86, 87, 88, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 89, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 90, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 52, 52, 91, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 92, 93, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 94, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 94, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 40, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 16, 50, 51, 52, + 16, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 16, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 98, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 99, 100, 97, 97, 97, 97, 97, 97, + 97, 97, 101, 40, 40, 102, 103, 104, 105, 106, 107, 108, 16, 109, 16, 16, + 16, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 111, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 114, 114, 115, 116, 117, 118, 119, 119, 120, 121, 122, 123, 124, 125, + 126, 127, 128, 129, 16, 130, 131, 132, 133, 134, 16, 16, 16, 16, 16, 16, + 135, 16, 136, 16, 137, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, + 40, 138, 16, 139, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 75, 140, 141, 142, 143, 16, 144, 16, 145, 146, 147, + 148, 149, 150, 151, 152, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 153, 154, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 155, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 114, 114, 114, 114, 156, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 157, 16, 158, 159, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 160, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 160, }; -static unsigned char index2[] = { +static unsigned short index2[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 2, 5, 6, 6, 7, 8, 7, 6, 6, 9, 10, 6, 11, 12, 13, 12, 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 12, 6, 15, 16, 15, 6, 6, 17, @@ -776,1273 +1172,1131 @@ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 9, 16, 10, 16, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 22, 8, 8, 23, 8, 24, - 25, 26, 27, 28, 29, 16, 30, 25, 18, 31, 32, 33, 33, 26, 34, 25, 22, 26, - 33, 28, 35, 36, 36, 36, 22, 37, 37, 37, 37, 37, 37, 38, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 38, 37, 37, 37, 37, 37, 37, 39, 38, 37, 37, 37, 37, - 37, 38, 28, 28, 28, 34, 34, 34, 34, 28, 34, 28, 28, 28, 34, 28, 28, 34, - 34, 28, 34, 28, 28, 34, 34, 34, 39, 28, 28, 28, 34, 28, 34, 28, 34, 37, - 28, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 28, 37, - 28, 37, 34, 37, 34, 37, 34, 37, 28, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 38, 28, 37, 34, 37, 28, 37, 34, 37, 34, 37, 28, 38, 28, 37, 34, 37, - 34, 28, 37, 34, 37, 34, 37, 34, 38, 28, 38, 28, 37, 28, 37, 34, 37, 28, - 28, 38, 28, 37, 28, 37, 34, 37, 34, 38, 28, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 38, 28, 37, 34, 37, 28, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 37, 34, 37, 34, 37, 34, - 34, 34, 37, 37, 34, 37, 34, 37, 37, 34, 37, 37, 37, 34, 34, 37, 37, 37, - 37, 34, 37, 37, 34, 37, 37, 37, 34, 34, 34, 37, 37, 34, 37, 37, 34, 37, - 34, 37, 34, 37, 37, 34, 37, 34, 34, 37, 34, 37, 37, 34, 37, 37, 37, 34, - 37, 34, 37, 37, 34, 34, 40, 37, 34, 34, 34, 40, 40, 40, 40, 37, 41, 34, - 37, 41, 34, 37, 41, 34, 37, 28, 37, 28, 37, 28, 37, 28, 37, 28, 37, 28, - 37, 28, 37, 28, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 34, 37, 41, 34, 37, 34, 37, 37, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 34, 34, 34, 34, 34, 34, 37, 37, 34, 37, 37, 34, 34, 37, 34, 37, 37, - 37, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 34, 28, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 28, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 40, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 42, 42, 42, 42, 42, 42, 42, 44, - 44, 26, 44, 43, 45, 43, 45, 45, 45, 43, 45, 43, 43, 46, 42, 44, 44, 44, - 44, 44, 44, 26, 26, 26, 26, 44, 26, 44, 26, 42, 42, 42, 42, 42, 44, 44, - 44, 44, 44, 44, 44, 43, 44, 42, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 49, 49, 49, 49, 48, 50, 49, - 49, 49, 49, 49, 51, 51, 49, 49, 49, 49, 51, 51, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 52, 52, 52, 52, 52, 49, 49, 49, 49, 47, 47, 47, 47, - 47, 47, 47, 47, 53, 47, 49, 49, 49, 47, 47, 47, 49, 49, 54, 47, 47, 47, - 49, 49, 49, 49, 47, 48, 49, 49, 47, 55, 56, 56, 55, 56, 56, 55, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 37, 34, 37, 34, 43, 44, 37, - 34, 0, 0, 42, 34, 34, 34, 57, 0, 0, 0, 0, 0, 44, 44, 37, 57, 37, 37, 37, - 0, 37, 0, 37, 37, 34, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 0, 38, 38, 38, 38, 38, 38, 38, 37, 37, 34, 34, 34, 34, - 34, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 34, 28, 28, 28, 28, 28, 28, 28, 34, 34, 34, 34, 34, 37, 34, 34, 37, 37, - 37, 34, 34, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 34, 34, 34, 34, 37, 34, 58, 37, - 34, 37, 37, 34, 34, 37, 37, 37, 37, 38, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 34, 28, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 59, 60, 60, 60, 60, 60, - 61, 61, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 0, 0, 42, 62, 62, 62, 62, 62, 62, 0, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 0, 62, 63, 0, 0, 0, 0, 0, 0, 64, 60, 60, 60, 60, 64, 60, 60, 60, 65, 64, - 60, 60, 60, 60, 60, 60, 64, 64, 64, 64, 64, 64, 60, 60, 64, 60, 60, 65, - 66, 60, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 82, 60, 64, 82, 75, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 0, 0, 0, 0, 0, 85, 85, 85, 82, 82, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 86, 86, 86, 86, 0, 0, 58, 58, 87, 88, 88, 89, 90, 91, 27, - 27, 60, 60, 60, 60, 60, 60, 60, 60, 92, 93, 94, 91, 0, 0, 91, 91, 0, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 96, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 97, 98, 99, 92, 93, 94, 100, 101, 60, 60, 64, 64, 60, - 60, 60, 60, 60, 64, 60, 60, 0, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 88, 103, 103, 91, 95, 95, 104, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 91, 95, 60, 60, 60, 60, 60, 60, 60, 86, 61, 60, 60, 60, 60, 64, 60, - 96, 96, 60, 60, 27, 64, 60, 60, 64, 95, 95, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 95, 95, 95, 106, 106, 95, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 0, 107, 95, 108, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 60, 64, 60, 60, 64, 60, 60, 64, 64, 64, 60, 64, 64, - 60, 64, 60, 60, 60, 64, 60, 64, 60, 64, 60, 64, 60, 60, 0, 0, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 60, 60, 60, 60, 60, 60, - 60, 64, 60, 111, 111, 27, 57, 57, 57, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 25, 26, 27, 28, 29, 16, 30, 25, 31, 32, 33, 34, 34, 26, 35, 25, 22, 26, + 34, 28, 36, 37, 37, 37, 22, 38, 38, 38, 38, 38, 38, 39, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 39, 38, 38, 38, 38, 38, 38, 40, 39, 38, 38, 38, 38, + 38, 39, 41, 42, 42, 43, 43, 43, 43, 41, 43, 42, 42, 42, 43, 42, 42, 43, + 43, 41, 43, 42, 42, 43, 43, 43, 40, 41, 42, 42, 43, 42, 43, 41, 43, 38, + 42, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 44, 41, 38, + 42, 38, 43, 38, 43, 38, 43, 38, 42, 38, 43, 38, 43, 38, 43, 38, 43, 38, + 43, 39, 41, 38, 43, 38, 42, 38, 43, 38, 43, 38, 41, 45, 28, 38, 43, 38, + 43, 41, 38, 43, 38, 43, 38, 43, 45, 28, 39, 41, 38, 42, 38, 43, 38, 42, + 28, 39, 41, 38, 42, 38, 43, 38, 43, 39, 41, 38, 43, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 39, 41, 38, 43, 38, 42, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 38, 43, 38, 43, 38, 43, + 35, 46, 44, 44, 46, 44, 46, 44, 44, 46, 44, 44, 44, 46, 46, 44, 44, 44, + 44, 46, 44, 44, 46, 44, 44, 44, 46, 46, 46, 44, 44, 46, 44, 38, 43, 44, + 46, 44, 46, 44, 44, 46, 44, 46, 46, 44, 46, 44, 38, 43, 44, 44, 44, 46, + 44, 46, 44, 44, 46, 46, 47, 44, 46, 46, 46, 47, 47, 47, 47, 48, 49, 35, + 48, 49, 35, 48, 49, 35, 38, 42, 38, 42, 38, 42, 38, 42, 38, 42, 38, 42, + 38, 42, 38, 42, 46, 38, 43, 38, 43, 38, 43, 44, 46, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 43, 48, 49, 35, 38, 43, 44, 44, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 44, 46, 38, 43, 44, + 46, 44, 46, 44, 46, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, + 43, 46, 46, 46, 46, 46, 46, 44, 44, 46, 44, 44, 46, 46, 44, 46, 44, 44, + 44, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 46, 41, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 41, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 47, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 52, 52, 52, 52, 52, 52, 52, 53, + 53, 54, 53, 51, 55, 51, 55, 55, 55, 51, 55, 51, 51, 56, 52, 53, 53, 53, + 53, 53, 53, 26, 26, 26, 26, 57, 26, 53, 54, 50, 50, 50, 50, 50, 53, 53, + 53, 53, 53, 53, 53, 51, 53, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 58, 58, 58, 58, 58, 59, 58, 58, 58, 58, 58, + 58, 58, 59, 59, 58, 59, 58, 59, 58, 58, 60, 61, 61, 61, 61, 60, 62, 61, + 61, 61, 61, 61, 63, 63, 64, 64, 64, 64, 65, 65, 61, 61, 61, 61, 64, 64, + 61, 64, 64, 61, 61, 66, 66, 66, 66, 67, 61, 61, 61, 61, 59, 59, 59, 68, + 68, 58, 68, 68, 69, 59, 61, 61, 61, 59, 59, 59, 61, 61, 70, 59, 59, 59, + 61, 61, 61, 61, 59, 60, 61, 61, 59, 71, 72, 72, 71, 72, 72, 71, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 44, 46, 44, 46, 73, 53, 44, + 46, 0, 0, 50, 46, 46, 46, 74, 0, 0, 0, 0, 0, 57, 75, 38, 74, 38, 38, 38, + 0, 38, 0, 38, 38, 43, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 0, 39, 39, 39, 39, 39, 39, 39, 38, 38, 43, 43, 43, 43, + 43, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 46, 41, 41, 41, 41, 41, 41, 41, 43, 43, 43, 43, 43, 44, 35, 35, 48, 76, + 76, 35, 35, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 35, 35, 35, 46, 48, 35, 77, 44, + 46, 48, 44, 46, 46, 44, 44, 44, 38, 78, 44, 38, 44, 44, 44, 38, 44, 44, + 44, 44, 38, 38, 38, 44, 39, 39, 39, 39, 39, 39, 39, 39, 39, 78, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 43, 42, + 46, 43, 46, 46, 46, 43, 46, 46, 46, 46, 43, 43, 43, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 38, 43, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 79, 80, 80, 80, 80, 80, + 81, 81, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 38, 43, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 46, + 38, 43, 38, 43, 44, 46, 38, 43, 44, 46, 38, 43, 38, 43, 38, 43, 44, 46, + 38, 43, 38, 43, 38, 43, 44, 46, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 44, 46, 38, 43, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 0, 0, 52, 82, 82, 82, 82, 82, 82, 0, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 35, + 0, 82, 83, 0, 0, 0, 0, 0, 0, 84, 80, 80, 80, 80, 84, 80, 80, 80, 85, 84, + 80, 80, 80, 80, 80, 80, 84, 84, 84, 84, 84, 84, 80, 80, 84, 80, 80, 85, + 86, 80, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 102, 80, 84, 102, 95, 0, 0, 0, 0, 0, 0, 0, 0, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 0, 0, 0, 0, 0, + 105, 105, 105, 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 106, 106, + 106, 0, 0, 77, 77, 107, 108, 108, 109, 110, 111, 27, 27, 80, 80, 80, 80, + 80, 80, 80, 80, 112, 113, 114, 111, 0, 0, 111, 111, 0, 115, 116, 116, + 116, 116, 116, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 117, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 118, 119, 120, + 112, 113, 114, 121, 122, 123, 123, 124, 84, 80, 80, 80, 80, 80, 84, 80, + 80, 0, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 108, 126, 126, + 111, 115, 115, 127, 115, 115, 115, 115, 128, 128, 128, 128, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 116, + 115, 116, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 116, 111, 115, 80, 80, 80, 80, 80, 80, 80, 106, 81, + 80, 80, 80, 80, 84, 80, 117, 117, 80, 80, 27, 84, 80, 80, 84, 115, 115, + 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 115, 115, 115, 130, + 130, 115, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 0, 131, 115, 132, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 80, 84, 80, 80, 84, 80, 80, 84, 84, + 84, 80, 84, 84, 80, 84, 80, 80, 80, 84, 80, 84, 80, 84, 80, 84, 80, 80, + 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 133, 133, 133, 133, 133, 133, 133, 133, + 133, 133, 133, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 134, + 134, 134, 134, 134, 134, 134, 134, 134, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 80, 80, + 80, 80, 80, 80, 80, 84, 80, 135, 135, 27, 136, 136, 136, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 109, 112, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 113, 40, 112, - 112, 112, 109, 109, 109, 109, 109, 109, 109, 109, 112, 112, 112, 112, - 114, 0, 0, 40, 60, 64, 60, 60, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 109, 109, 62, 62, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 115, 62, 42, 40, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 0, 109, 112, - 112, 0, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 40, 40, 0, 0, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 0, 0, 0, 40, 40, 40, 40, 0, 0, - 113, 40, 112, 112, 112, 109, 109, 109, 109, 0, 0, 112, 112, 0, 0, 112, - 112, 114, 40, 0, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 0, 40, 40, 0, 40, 40, - 40, 109, 109, 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 40, - 40, 116, 116, 117, 117, 117, 117, 117, 117, 59, 0, 0, 0, 0, 0, 0, 109, - 109, 112, 0, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 40, 40, 0, 0, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 0, 40, 40, 0, 40, 40, - 0, 0, 113, 0, 112, 112, 112, 109, 109, 0, 0, 0, 0, 109, 109, 0, 0, 109, - 109, 114, 0, 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 0, 40, 0, 0, - 0, 0, 0, 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 109, - 109, 40, 40, 40, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 109, 112, 0, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 0, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, - 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 0, 40, 40, 40, 40, 40, 0, 0, 113, - 40, 112, 112, 112, 109, 109, 109, 109, 109, 0, 109, 109, 112, 0, 112, - 112, 114, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, - 109, 109, 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 116, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 112, 112, 0, 40, 40, - 40, 40, 40, 40, 40, 40, 0, 0, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, - 40, 40, 40, 40, 40, 0, 40, 40, 0, 40, 40, 40, 40, 40, 0, 0, 113, 40, 112, - 109, 112, 109, 109, 109, 109, 0, 0, 112, 112, 0, 0, 112, 112, 114, 0, 0, - 0, 0, 0, 0, 0, 0, 109, 112, 0, 0, 0, 0, 40, 40, 0, 40, 40, 40, 109, 109, - 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 59, 40, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 40, 0, 40, 40, 40, 40, 40, - 40, 0, 0, 0, 40, 40, 40, 0, 40, 40, 40, 40, 0, 0, 0, 40, 40, 0, 40, 0, - 40, 40, 0, 0, 0, 40, 40, 0, 0, 0, 40, 40, 40, 0, 0, 0, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 112, 112, 109, 112, 112, 0, - 0, 0, 112, 112, 112, 0, 112, 112, 112, 114, 0, 0, 40, 0, 0, 0, 0, 0, 0, - 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 115, 117, 117, 117, 27, 27, 27, 27, 27, 27, 116, 27, - 0, 0, 0, 0, 0, 0, 112, 112, 112, 0, 40, 40, 40, 40, 40, 40, 40, 40, 0, - 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 0, 40, 40, 40, 40, 40, 0, 0, 0, 40, 109, 109, 109, 112, 112, 112, - 112, 0, 109, 109, 109, 0, 109, 109, 109, 114, 0, 0, 0, 0, 0, 0, 0, 118, - 119, 0, 40, 40, 0, 0, 0, 0, 0, 0, 40, 40, 109, 109, 0, 0, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 0, 0, 0, 0, 0, 0, 0, 0, 120, 120, 120, - 120, 120, 120, 120, 59, 0, 0, 112, 112, 0, 40, 40, 40, 40, 40, 40, 40, - 40, 0, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 0, 40, 40, 40, 40, 40, 0, 0, 113, 40, 112, 121, 112, 112, - 112, 112, 112, 0, 121, 112, 112, 0, 112, 112, 109, 114, 0, 0, 0, 0, 0, 0, - 0, 112, 112, 0, 0, 0, 0, 0, 0, 0, 40, 0, 40, 40, 109, 109, 0, 0, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 27, 27, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 112, 0, 40, 40, 40, 40, 40, 40, 40, 40, - 0, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 40, 112, 112, 112, 109, 109, - 109, 109, 0, 112, 112, 112, 0, 112, 112, 112, 114, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 109, 109, 0, 0, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 117, 117, 117, 117, 117, 117, 0, 0, 0, - 59, 40, 40, 40, 40, 40, 40, 0, 0, 112, 112, 0, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 0, 0, 40, 40, 40, - 40, 40, 40, 40, 0, 0, 0, 114, 0, 0, 0, 0, 112, 112, 112, 109, 109, 109, - 0, 109, 0, 112, 112, 112, 112, 112, 112, 112, 112, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 112, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 109, 40, 40, 109, - 109, 109, 109, 122, 122, 114, 0, 0, 0, 0, 116, 40, 40, 40, 40, 40, 40, - 42, 109, 123, 123, 123, 123, 109, 109, 109, 62, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 115, 62, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 40, 40, 0, 40, 0, 0, 40, 40, 0, 40, 0, 0, 40, 0, 0, 0, 0, 0, 0, 40, 40, - 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 0, 40, 0, 40, 0, 0, - 40, 40, 0, 40, 40, 40, 40, 109, 40, 40, 109, 109, 109, 109, 124, 124, 0, - 109, 109, 40, 0, 0, 40, 40, 40, 40, 40, 0, 42, 0, 125, 125, 125, 125, - 109, 109, 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 0, - 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 59, 59, 59, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 59, 59, 59, 59, 59, 64, 64, 59, - 59, 59, 59, 59, 59, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 59, 64, 59, 64, 59, - 126, 127, 128, 127, 128, 112, 112, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, - 0, 0, 129, 130, 109, 131, 109, 109, 109, 109, 109, 130, 130, 130, 130, - 109, 112, 130, 109, 60, 60, 114, 62, 60, 60, 40, 40, 40, 40, 0, 0, 0, 0, - 109, 109, 109, 109, 109, 109, 109, 109, 0, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 0, 59, 59, 59, 59, 59, 59, 59, 59, 64, 59, 59, 59, 59, 59, 59, - 0, 59, 59, 62, 62, 62, 62, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 112, 112, 109, 109, 109, 109, - 112, 109, 109, 109, 109, 109, 113, 112, 114, 114, 112, 112, 109, 109, 40, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 62, 62, 62, 62, 62, 62, - 40, 40, 40, 40, 40, 40, 112, 112, 109, 109, 40, 40, 40, 40, 109, 109, - 109, 40, 112, 112, 112, 40, 40, 112, 112, 112, 112, 112, 112, 112, 40, - 40, 40, 109, 109, 109, 109, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 109, 112, 112, 109, 109, 112, 112, 112, 112, 112, 112, 64, 40, - 112, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 0, 0, 0, 59, - 59, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 62, - 42, 0, 0, 0, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, 0, 0, 0, 132, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 0, 0, 40, - 40, 40, 40, 40, 40, 40, 0, 40, 0, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 0, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 0, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, 0, - 40, 0, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 60, 59, 62, 62, 62, 62, - 62, 62, 62, 62, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 117, 0, 0, 0, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 62, 62, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 133, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 127, 128, 0, 0, 0, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 62, - 62, 62, 134, 134, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 109, - 109, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 109, 109, 114, 62, 62, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 109, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 0, 109, 109, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 135, 135, 112, 109, 109, 109, 109, 109, 109, - 109, 112, 112, 112, 112, 112, 112, 112, 112, 109, 112, 112, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 114, 109, 62, 62, 62, 42, 62, 62, 62, - 116, 40, 60, 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, - 0, 0, 0, 0, 0, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 0, 0, 0, - 0, 0, 0, 57, 57, 57, 57, 57, 57, 63, 57, 57, 57, 57, 109, 109, 109, 133, - 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 0, 0, 0, 0, 0, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 42, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, - 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 66, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 109, 109, - 109, 112, 112, 112, 112, 109, 109, 112, 112, 112, 0, 0, 0, 0, 112, 112, - 109, 112, 112, 112, 112, 112, 112, 65, 60, 64, 0, 0, 0, 0, 27, 0, 0, 0, - 57, 57, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 40, - 40, 40, 40, 40, 40, 40, 112, 112, 0, 0, 0, 0, 0, 0, 115, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 0, 0, 0, 0, 57, 57, 27, 27, 27, 27, 27, 27, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 133, 137, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 138, 47, 47, 47, 47, 47, + 47, 47, 138, 47, 47, 138, 47, 47, 47, 47, 47, 0, 0, 139, 47, 137, 137, + 137, 133, 133, 133, 133, 133, 133, 133, 133, 137, 137, 137, 137, 140, 0, + 0, 47, 80, 84, 80, 80, 0, 0, 0, 141, 141, 141, 141, 141, 141, 141, 141, + 47, 47, 133, 133, 82, 82, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 82, 52, 47, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 0, 133, 137, + 137, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 0, 0, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 0, 0, 47, 47, 47, 47, 0, 0, + 143, 47, 144, 137, 137, 133, 133, 133, 133, 0, 0, 137, 137, 0, 0, 145, + 145, 140, 47, 0, 0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 141, 141, 0, 141, + 47, 47, 133, 133, 0, 0, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 47, 47, 146, 146, 147, 147, 147, 147, 147, 147, 79, 0, 0, 0, 0, 0, 0, + 133, 133, 137, 0, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 47, 47, 0, 0, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 141, 0, 47, 141, 0, 47, + 47, 0, 0, 143, 0, 137, 137, 137, 133, 133, 0, 0, 0, 0, 133, 133, 0, 0, + 133, 133, 140, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0, 141, 141, 141, 47, 0, + 141, 0, 0, 0, 0, 0, 0, 0, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 133, 133, 47, 47, 47, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, + 133, 137, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 0, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 0, 47, 47, 47, 47, + 47, 0, 0, 143, 47, 137, 137, 137, 133, 133, 133, 133, 133, 0, 133, 133, + 137, 0, 137, 137, 140, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 47, 47, 133, 133, 0, 0, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 137, + 137, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 0, 0, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 0, 47, 47, 47, 47, 47, 0, + 0, 143, 47, 144, 133, 137, 133, 133, 133, 133, 0, 0, 137, 145, 0, 0, 145, + 145, 140, 0, 0, 0, 0, 0, 0, 0, 0, 148, 144, 0, 0, 0, 0, 141, 141, 0, 47, + 47, 47, 133, 133, 0, 0, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 79, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 47, 0, 47, + 47, 47, 47, 47, 47, 0, 0, 0, 47, 47, 47, 0, 47, 47, 138, 47, 0, 0, 0, 47, + 47, 0, 47, 0, 47, 47, 0, 0, 0, 47, 47, 0, 0, 0, 47, 47, 47, 0, 0, 0, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 144, 137, 133, + 137, 137, 0, 0, 0, 137, 137, 137, 0, 145, 145, 145, 140, 0, 0, 47, 0, 0, + 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 147, 147, 147, 27, 27, 27, 27, 27, 27, + 146, 27, 0, 0, 0, 0, 0, 0, 137, 137, 137, 0, 47, 47, 47, 47, 47, 47, 47, + 47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 0, 47, 47, 47, 47, 47, 0, 0, 0, 47, 133, 133, 133, 137, 137, + 137, 137, 0, 133, 133, 149, 0, 133, 133, 133, 140, 0, 0, 0, 0, 0, 0, 0, + 150, 151, 0, 47, 47, 0, 0, 0, 0, 0, 0, 47, 47, 133, 133, 0, 0, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 0, 0, 0, 0, 0, 0, 0, 0, 152, 152, + 152, 152, 152, 152, 152, 79, 0, 0, 137, 137, 0, 47, 47, 47, 47, 47, 47, + 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 0, 0, 143, 47, 137, 153, 145, 137, + 144, 137, 137, 0, 153, 145, 145, 0, 145, 145, 133, 140, 0, 0, 0, 0, 0, 0, + 0, 144, 144, 0, 0, 0, 0, 0, 0, 0, 47, 0, 47, 47, 133, 133, 0, 0, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 0, 27, 27, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 137, 137, 0, 47, 47, 47, 47, 47, 47, 47, 47, + 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 47, 144, 137, 137, 133, 133, + 133, 133, 0, 137, 137, 137, 0, 145, 145, 145, 140, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 133, 133, 0, 0, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 147, 147, 147, 147, 147, 147, 0, 0, 0, + 79, 47, 47, 47, 47, 47, 47, 0, 0, 137, 137, 0, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 0, 47, 47, 47, + 47, 47, 47, 47, 0, 0, 0, 154, 0, 0, 0, 0, 144, 137, 137, 133, 133, 133, + 0, 133, 0, 137, 137, 145, 137, 145, 145, 145, 144, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 137, 137, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 133, 47, 155, + 133, 133, 133, 133, 156, 156, 140, 0, 0, 0, 0, 146, 47, 47, 47, 47, 47, + 47, 52, 133, 157, 157, 157, 157, 133, 133, 133, 82, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 82, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 47, 47, 0, 47, 0, 0, 47, 47, 0, 47, 0, 0, 47, 0, 0, 0, 0, 0, 0, 47, + 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 0, 47, 0, 47, + 0, 0, 47, 47, 0, 47, 47, 47, 47, 133, 47, 155, 133, 133, 133, 133, 158, + 158, 0, 133, 133, 47, 0, 0, 47, 47, 47, 47, 47, 0, 52, 0, 159, 159, 159, + 159, 133, 133, 0, 0, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 0, + 0, 155, 155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 79, 79, 79, 82, 82, 82, 82, + 82, 82, 82, 82, 160, 82, 82, 82, 82, 82, 82, 79, 79, 79, 79, 79, 84, 84, + 79, 79, 79, 79, 79, 79, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 79, 84, 79, 84, 79, + 161, 162, 163, 162, 163, 137, 137, 47, 47, 47, 141, 47, 47, 47, 47, 0, + 47, 47, 47, 47, 141, 47, 47, 47, 47, 141, 47, 47, 47, 47, 141, 47, 47, + 47, 47, 141, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 141, 47, 47, + 47, 0, 0, 0, 0, 164, 165, 166, 167, 166, 166, 168, 166, 168, 165, 165, + 165, 165, 133, 137, 165, 166, 80, 80, 140, 82, 80, 80, 47, 47, 47, 47, 0, + 0, 0, 0, 133, 133, 133, 166, 133, 133, 133, 133, 0, 133, 133, 133, 133, + 166, 133, 133, 133, 133, 166, 133, 133, 133, 133, 166, 133, 133, 133, + 133, 166, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, + 166, 133, 133, 133, 0, 79, 79, 79, 79, 79, 79, 79, 79, 84, 79, 79, 79, + 79, 79, 79, 0, 79, 79, 82, 82, 82, 82, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 138, 47, 47, 47, 47, 137, 137, 133, + 148, 133, 133, 137, 133, 133, 133, 133, 133, 143, 137, 140, 140, 137, + 137, 133, 133, 47, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 82, + 82, 82, 82, 82, 82, 47, 47, 47, 47, 47, 47, 137, 137, 133, 133, 47, 47, + 47, 47, 133, 133, 133, 47, 137, 137, 137, 47, 47, 137, 137, 137, 137, + 137, 137, 137, 47, 47, 47, 133, 133, 133, 133, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 133, 137, 137, 133, 133, 137, 137, 137, 137, + 137, 137, 84, 47, 137, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 0, 0, 0, 0, 79, 79, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 82, 50, 0, 0, 0, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 0, 0, 0, 0, 0, + 169, 47, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 0, 0, 0, 0, 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, + 47, 47, 47, 0, 47, 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, + 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 47, + 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 80, 79, 82, 82, 82, 82, 82, 82, 82, + 82, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 82, 82, 47, 47, 47, 47, 47, + 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 162, 163, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 82, 82, 82, 172, 172, 172, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 0, 47, 47, 47, 47, 133, 133, 140, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 133, 133, 140, 82, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 133, 133, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 0, 47, 47, 47, 0, 133, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 173, 173, + 137, 133, 133, 133, 133, 133, 133, 133, 137, 137, 137, 137, 137, 137, + 137, 137, 133, 137, 137, 133, 133, 133, 133, 133, 133, 133, 133, 133, + 140, 133, 82, 82, 82, 52, 82, 82, 82, 146, 47, 80, 0, 0, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 0, 0, 0, 0, 0, 0, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 0, 0, 0, 0, 0, 0, 136, 136, 136, 136, 136, + 136, 83, 136, 136, 136, 136, 133, 133, 133, 171, 0, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 52, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 86, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 133, 133, 133, 137, 137, 137, 137, + 133, 133, 137, 137, 137, 0, 0, 0, 0, 137, 137, 133, 137, 137, 137, 137, + 137, 137, 85, 80, 84, 0, 0, 0, 0, 27, 0, 0, 0, 136, 136, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 47, 47, 47, 47, + 47, 47, 47, 137, 137, 0, 0, 0, 0, 0, 0, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 0, 0, 0, 0, 136, 136, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 60, 64, 112, 112, - 112, 0, 0, 62, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 109, 109, 109, 112, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 113, 112, 109, 109, 109, 109, - 109, 112, 109, 112, 112, 112, 112, 112, 109, 112, 136, 40, 40, 40, 40, - 40, 40, 40, 0, 0, 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 62, 62, 62, 62, 62, 62, 62, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 60, - 64, 60, 60, 60, 60, 60, 60, 60, 59, 59, 59, 59, 59, 59, 59, 59, 59, 0, 0, - 0, 109, 109, 112, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 112, 109, - 109, 109, 109, 112, 112, 109, 109, 136, 0, 0, 0, 40, 40, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 112, 112, 112, 112, 112, 112, 112, 112, 109, - 109, 109, 109, 109, 109, 109, 109, 112, 112, 109, 113, 0, 0, 0, 62, 62, - 62, 62, 62, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 0, 0, - 40, 40, 40, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 42, 42, 42, 42, 42, 42, 62, 62, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 42, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 60, 60, - 64, 60, 60, 60, 60, 60, 60, 60, 64, 60, 60, 137, 138, 64, 139, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 60, 64, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, - 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 0, 0, 37, 37, 37, 37, 37, 37, - 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 34, - 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, - 34, 34, 34, 0, 0, 37, 37, 37, 37, 37, 37, 0, 0, 34, 34, 34, 34, 34, 34, - 34, 34, 0, 37, 0, 37, 0, 37, 0, 37, 34, 34, 34, 34, 34, 34, 34, 34, 37, - 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 41, 41, 41, 41, 41, 41, - 41, 41, 34, 34, 34, 34, 34, 34, 34, 34, 41, 41, 41, 41, 41, 41, 41, 41, - 34, 34, 34, 34, 34, 34, 34, 34, 41, 41, 41, 41, 41, 41, 41, 41, 34, 34, - 34, 34, 34, 0, 34, 34, 37, 37, 37, 37, 41, 44, 34, 44, 44, 44, 34, 34, - 34, 0, 34, 34, 37, 37, 37, 37, 41, 44, 44, 44, 34, 34, 34, 34, 0, 0, 34, - 34, 37, 37, 37, 37, 0, 44, 44, 44, 34, 34, 34, 34, 34, 34, 34, 34, 37, - 37, 37, 37, 37, 44, 44, 44, 0, 0, 34, 34, 34, 0, 34, 34, 37, 37, 37, 37, - 41, 44, 44, 0, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, - 107, 107, 107, 135, 140, 141, 63, 63, 141, 141, 141, 22, 57, 142, 143, - 144, 145, 142, 143, 144, 145, 22, 22, 22, 57, 22, 22, 22, 22, 146, 147, - 148, 149, 150, 151, 152, 21, 153, 88, 153, 153, 88, 22, 57, 57, 57, 29, - 35, 22, 57, 57, 22, 154, 154, 57, 57, 57, 155, 127, 128, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 58, 57, 154, 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 133, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 107, 107, 107, 107, - 107, 107, 156, 34, 0, 0, 33, 156, 156, 156, 156, 156, 157, 157, 58, 127, - 128, 28, 156, 33, 33, 33, 33, 156, 156, 156, 156, 156, 157, 157, 58, 127, - 128, 0, 42, 42, 42, 42, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 158, 116, 116, 23, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 60, 159, 159, 60, 60, 60, 60, 159, 159, - 159, 60, 60, 61, 61, 61, 61, 60, 61, 61, 61, 159, 159, 60, 64, 60, 159, - 159, 64, 64, 64, 64, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, - 27, 37, 25, 27, 25, 27, 37, 27, 25, 34, 37, 37, 37, 34, 34, 37, 37, 37, - 28, 27, 37, 25, 27, 27, 37, 37, 37, 37, 37, 27, 27, 27, 25, 25, 27, 37, - 27, 38, 27, 37, 27, 37, 38, 37, 37, 160, 34, 37, 37, 37, 37, 34, 40, 40, - 40, 40, 34, 27, 27, 34, 34, 37, 37, 161, 58, 58, 58, 58, 37, 34, 34, 34, - 34, 27, 58, 27, 27, 34, 59, 0, 0, 0, 36, 36, 120, 120, 120, 120, 120, - 120, 36, 36, 36, 36, 120, 162, 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 134, 134, 134, 134, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 134, 134, 134, 134, 134, 134, 134, 134, 134, 37, 34, 134, - 134, 134, 134, 0, 0, 0, 0, 0, 0, 0, 39, 39, 39, 39, 39, 25, 25, 25, 25, - 25, 58, 58, 27, 27, 27, 27, 58, 27, 27, 58, 27, 27, 58, 27, 27, 27, 27, - 27, 27, 27, 58, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 58, - 58, 27, 27, 39, 27, 39, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 80, 84, 137, 137, 137, 0, 0, + 82, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 133, 133, 133, 133, 137, 47, 138, 47, 138, 47, 138, 47, 138, 47, + 138, 47, 47, 47, 138, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 143, 144, 133, 133, 133, 133, 133, 145, 133, 145, 137, 137, 145, + 145, 133, 145, 174, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 82, 82, 82, 82, 82, 82, 82, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 80, 84, 80, 80, 80, 80, 80, 80, 80, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, 0, 133, 133, 137, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 137, 133, 133, 133, 133, 137, 137, + 133, 133, 174, 0, 0, 0, 47, 47, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 137, 137, 137, 137, 137, 137, 137, 137, 133, 133, 133, 133, 133, 133, + 133, 133, 137, 137, 133, 143, 0, 0, 0, 82, 82, 82, 82, 82, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 0, 0, 0, 47, 47, 47, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 52, 52, 52, 52, 52, 52, 82, 82, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 50, 50, 50, 52, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 52, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 52, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 35, 35, 35, 35, 35, 35, 35, 35, 35, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 50, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 80, 80, 84, 80, 80, 80, 80, 80, 80, 80, 84, 80, 80, + 175, 176, 84, 177, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 84, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 43, 43, + 43, 43, 35, 178, 46, 46, 44, 46, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 44, 46, 44, 46, 44, 46, 43, 43, 43, 43, + 43, 43, 43, 43, 38, 38, 38, 38, 38, 38, 38, 38, 43, 43, 43, 43, 43, 43, + 0, 0, 38, 38, 38, 38, 38, 38, 0, 0, 43, 43, 43, 43, 43, 43, 43, 43, 38, + 38, 38, 38, 38, 38, 38, 38, 43, 43, 43, 43, 43, 43, 43, 43, 38, 38, 38, + 38, 38, 38, 38, 38, 43, 43, 43, 43, 43, 43, 0, 0, 38, 38, 38, 38, 38, 38, + 0, 0, 43, 43, 43, 43, 43, 43, 43, 43, 0, 38, 0, 38, 0, 38, 0, 38, 43, 43, + 43, 43, 43, 43, 43, 43, 38, 38, 38, 38, 38, 38, 38, 38, 43, 179, 43, 179, + 43, 179, 43, 179, 43, 179, 43, 179, 43, 179, 0, 0, 43, 43, 43, 43, 43, + 43, 43, 43, 180, 180, 180, 180, 180, 180, 180, 180, 43, 43, 43, 43, 43, + 43, 43, 43, 180, 180, 180, 180, 180, 180, 180, 180, 43, 43, 43, 43, 43, + 43, 43, 43, 180, 180, 180, 180, 180, 180, 180, 180, 43, 43, 43, 43, 43, + 0, 43, 43, 38, 38, 38, 181, 180, 57, 179, 57, 57, 75, 43, 43, 43, 0, 43, + 43, 38, 181, 38, 181, 180, 75, 75, 75, 43, 43, 43, 179, 0, 0, 43, 43, 38, + 38, 38, 181, 0, 75, 75, 75, 43, 43, 43, 179, 43, 43, 43, 43, 38, 38, 38, + 181, 38, 75, 182, 182, 0, 0, 43, 43, 43, 0, 43, 43, 38, 181, 38, 181, + 180, 182, 57, 0, 183, 183, 184, 184, 184, 184, 184, 184, 184, 184, 184, + 131, 131, 131, 173, 185, 186, 187, 83, 186, 186, 186, 22, 188, 189, 190, + 191, 192, 189, 190, 191, 192, 22, 22, 22, 136, 193, 193, 193, 22, 194, + 195, 196, 197, 198, 199, 200, 21, 201, 108, 201, 202, 203, 22, 188, 188, + 136, 29, 36, 22, 188, 136, 193, 204, 204, 136, 136, 136, 205, 162, 163, + 188, 188, 188, 136, 136, 136, 136, 136, 136, 136, 136, 77, 136, 204, 136, + 136, 188, 136, 136, 136, 136, 136, 136, 136, 184, 131, 131, 131, 131, + 131, 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, 131, 206, 35, 0, 0, 34, 206, + 206, 206, 206, 206, 207, 207, 208, 209, 210, 28, 206, 34, 34, 34, 34, + 206, 206, 206, 206, 206, 207, 207, 208, 209, 210, 0, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, + 211, 212, 146, 146, 23, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 80, 80, 213, 213, 80, 80, 80, 80, 213, 213, 213, 80, 80, 81, 81, 81, + 81, 80, 81, 81, 81, 213, 213, 80, 84, 80, 213, 213, 84, 84, 84, 84, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, 214, 48, 215, 27, 215, + 214, 48, 27, 215, 35, 48, 48, 48, 35, 35, 48, 48, 48, 28, 27, 48, 215, + 27, 27, 48, 48, 48, 48, 48, 27, 27, 214, 215, 215, 27, 48, 27, 216, 27, + 48, 27, 181, 216, 48, 48, 217, 35, 48, 48, 44, 48, 35, 155, 155, 155, + 155, 35, 27, 214, 35, 35, 48, 48, 218, 77, 77, 77, 77, 48, 35, 35, 35, + 35, 27, 77, 27, 27, 46, 79, 0, 0, 0, 37, 37, 219, 219, 219, 219, 219, + 219, 37, 37, 37, 37, 219, 220, 220, 220, 220, 220, 220, 220, 220, 220, + 220, 220, 220, 221, 221, 221, 221, 220, 220, 220, 220, 220, 220, 220, + 220, 220, 220, 221, 221, 221, 221, 221, 221, 172, 172, 172, 44, 46, 172, + 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 25, 25, 25, 25, + 25, 222, 222, 27, 27, 27, 27, 77, 27, 27, 77, 27, 27, 77, 27, 27, 27, 27, + 27, 27, 27, 222, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 223, 222, + 222, 27, 27, 40, 27, 40, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 39, 161, 163, 163, - 161, 58, 58, 39, 163, 161, 161, 163, 161, 161, 58, 39, 58, 163, 157, 164, - 58, 163, 161, 58, 58, 58, 163, 161, 161, 163, 39, 163, 163, 161, 161, 39, - 161, 39, 161, 39, 39, 39, 39, 163, 163, 161, 163, 161, 161, 161, 161, - 161, 39, 39, 39, 39, 58, 161, 58, 161, 163, 163, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 163, 161, 161, 161, 163, 58, 58, 58, 58, 58, - 163, 161, 161, 161, 58, 58, 58, 58, 58, 58, 58, 58, 58, 161, 163, 39, - 161, 58, 163, 163, 163, 163, 161, 161, 163, 163, 58, 58, 163, 163, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 163, 163, 161, 161, 163, 163, 161, 161, 161, 161, 161, 58, - 58, 161, 161, 161, 161, 58, 58, 39, 58, 58, 161, 39, 58, 58, 58, 58, 58, - 58, 58, 58, 161, 161, 58, 39, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 58, 58, 58, 58, - 58, 161, 163, 58, 58, 58, 58, 58, 58, 58, 58, 58, 161, 161, 161, 161, - 161, 58, 58, 161, 161, 58, 58, 58, 58, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 58, 58, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 27, 27, 27, 27, 27, 27, 27, 27, 161, 161, - 161, 161, 27, 27, 27, 27, 27, 27, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 161, 161, 27, 27, 27, 27, 27, 27, 27, 165, 166, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 27, 58, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 59, 27, 27, 27, - 27, 27, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 40, 224, 225, 225, + 226, 77, 77, 40, 225, 226, 224, 225, 226, 224, 77, 40, 77, 225, 227, 228, + 77, 225, 224, 77, 77, 77, 225, 224, 224, 225, 40, 225, 225, 224, 224, 40, + 226, 40, 226, 40, 40, 40, 40, 225, 229, 218, 225, 218, 218, 224, 224, + 224, 40, 40, 40, 40, 77, 224, 77, 224, 225, 225, 224, 224, 224, 226, 224, + 224, 226, 224, 224, 226, 225, 226, 224, 224, 225, 77, 77, 77, 77, 77, + 225, 224, 224, 224, 77, 77, 77, 77, 77, 77, 77, 77, 77, 224, 230, 40, + 226, 77, 225, 225, 225, 225, 224, 224, 225, 225, 77, 222, 230, 230, 226, + 226, 224, 224, 226, 226, 224, 224, 226, 226, 224, 224, 224, 224, 224, + 224, 226, 226, 225, 225, 226, 226, 225, 225, 226, 226, 224, 224, 224, 77, + 77, 224, 224, 224, 224, 77, 77, 40, 77, 77, 224, 40, 77, 77, 77, 77, 77, + 77, 77, 77, 224, 224, 77, 40, 224, 224, 224, 224, 224, 224, 226, 226, + 226, 226, 224, 224, 224, 224, 224, 224, 224, 224, 224, 77, 77, 77, 77, + 77, 224, 225, 77, 77, 77, 77, 77, 77, 77, 77, 77, 224, 224, 224, 224, + 224, 77, 77, 224, 224, 77, 77, 77, 77, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 226, 226, 226, 226, 224, 224, 224, 224, 224, 224, 226, + 226, 226, 226, 77, 77, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 27, 27, 27, 27, 27, 27, 27, 27, 224, 224, + 224, 224, 27, 27, 27, 27, 27, 27, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 224, 224, 27, 27, 27, 27, 27, 27, 27, 231, 232, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 27, 77, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 79, 27, 27, 27, + 27, 27, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 58, 58, 58, 58, 58, - 58, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 77, 77, 77, 77, 77, + 77, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 167, 167, 167, 167, 167, 167, 167, 167, 167, - 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, - 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, - 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, - 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, - 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 120, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 0, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 219, + 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, + 234, 234, 234, 234, 234, 234, 234, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 27, 27, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 25, 25, 27, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, - 25, 25, 27, 27, 25, 39, 27, 27, 27, 27, 25, 25, 27, 27, 25, 39, 27, 27, - 27, 27, 25, 25, 25, 27, 27, 25, 27, 27, 25, 25, 25, 25, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25, 25, 25, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 25, 27, 27, 27, 27, 27, 27, 27, 27, 58, 58, - 58, 58, 58, 58, 58, 58, 27, 27, 27, 27, 27, 25, 25, 27, 27, 25, 27, 27, - 27, 27, 25, 25, 27, 27, 27, 27, 25, 25, 27, 27, 27, 27, 27, 27, 25, 27, - 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 27, - 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25, 27, 25, 25, 25, - 27, 25, 25, 25, 25, 27, 25, 25, 27, 39, 27, 27, 27, 27, 27, 27, 27, 27, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 27, 27, 25, 25, 25, 25, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 25, 25, 27, 25, 25, 25, 25, 25, 25, 25, 27, + 27, 27, 27, 27, 27, 27, 27, 25, 25, 27, 27, 25, 40, 27, 27, 27, 27, 25, + 25, 27, 27, 25, 40, 27, 27, 27, 27, 25, 25, 25, 27, 27, 25, 27, 27, 25, + 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 27, 27, 27, + 27, 27, 27, 27, 27, 77, 77, 77, 77, 77, 77, 77, 77, 27, 27, 27, 27, 27, + 25, 25, 27, 27, 25, 27, 27, 27, 27, 25, 25, 27, 27, 27, 27, 25, 25, 27, + 27, 27, 27, 27, 27, 25, 27, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 25, 27, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 59, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 27, 27, - 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 0, 27, 27, - 27, 27, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 27, 0, 27, 27, 27, - 27, 0, 0, 0, 27, 0, 27, 27, 27, 27, 27, 27, 27, 0, 0, 27, 27, 27, 27, 27, - 27, 27, 127, 128, 127, 128, 127, 128, 127, 128, 127, 128, 127, 128, 127, - 128, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 27, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 0, 161, 58, 58, 161, 161, 127, 128, 58, 161, - 161, 58, 0, 161, 0, 0, 0, 58, 58, 58, 161, 161, 161, 161, 58, 58, 58, 58, - 58, 161, 161, 161, 58, 58, 58, 161, 161, 161, 161, 9, 10, 9, 10, 9, 10, - 9, 10, 127, 128, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 127, 128, 9, 10, 127, 128, - 127, 128, 127, 128, 127, 128, 127, 128, 127, 128, 127, 128, 127, 128, - 127, 128, 58, 58, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 58, 58, 58, 58, 58, 58, - 58, 58, 161, 58, 58, 58, 58, 58, 58, 58, 161, 161, 161, 161, 161, 161, - 58, 58, 58, 161, 58, 58, 58, 58, 161, 161, 161, 161, 161, 58, 161, 161, - 58, 58, 127, 128, 127, 128, 161, 58, 58, 58, 58, 161, 58, 161, 161, 161, - 58, 58, 161, 161, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 161, 161, 161, - 161, 161, 161, 58, 58, 127, 128, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 58, 161, 161, 161, 161, 58, 58, 161, 58, - 161, 58, 58, 161, 58, 161, 161, 161, 161, 58, 58, 58, 58, 58, 161, 161, - 58, 58, 58, 58, 58, 58, 161, 161, 161, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 161, 161, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 161, 161, 58, 58, 58, 58, - 161, 161, 161, 161, 58, 161, 161, 58, 58, 161, 161, 58, 58, 58, 58, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 58, - 58, 161, 161, 161, 161, 161, 161, 161, 161, 58, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 58, 58, 58, 58, 58, 161, 58, 161, 58, - 58, 58, 161, 161, 161, 161, 161, 58, 58, 58, 58, 58, 161, 161, 161, 58, - 58, 58, 58, 161, 58, 58, 58, 161, 161, 161, 161, 161, 58, 161, 58, 58, + 27, 25, 25, 27, 25, 25, 25, 27, 25, 25, 25, 25, 27, 25, 25, 27, 40, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 27, 27, 58, - 58, 58, 58, 58, 58, 0, 0, 0, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 79, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 0, 0, 0, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 0, 37, 34, 37, 37, 37, 34, 34, 37, 34, 37, 34, 37, 34, 37, 37, 37, 0, - 34, 37, 34, 34, 37, 34, 34, 34, 34, 34, 34, 34, 42, 0, 0, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 34, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 57, 57, 57, 57, 120, 57, 57, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, - 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, - 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, - 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, - 40, 40, 40, 40, 0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 57, 57, 29, 35, 29, 35, 57, 57, 57, 29, 35, 57, 29, 35, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 63, 57, 57, 63, 57, 29, 35, 57, 57, 29, 35, 127, - 128, 127, 128, 127, 128, 127, 128, 57, 57, 57, 57, 57, 43, 57, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 0, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 0, 0, 0, 0, 169, 170, 170, 170, 168, 171, 132, 172, 165, 166, 165, - 166, 165, 166, 165, 166, 165, 166, 168, 168, 165, 166, 165, 166, 165, - 166, 165, 166, 173, 174, 175, 175, 168, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 176, 177, 178, 179, 180, 180, 173, 171, 171, 171, 171, - 171, 168, 168, 172, 172, 172, 171, 132, 170, 168, 27, 0, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, - 181, 181, 182, 182, 171, 171, 132, 173, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 170, 171, 171, 171, 132, 0, 0, 0, 0, 0, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 0, 0, 0, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 0, 183, 183, 184, 184, 184, 184, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 0, 0, 0, 0, 0, 0, 0, 0, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 168, 168, 0, 184, 184, 184, - 184, 184, 184, 184, 184, 184, 184, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 185, - 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 168, 168, 168, 183, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 168, 168, 168, 168, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 0, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 168, 168, - 168, 168, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 168, 168, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 168, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 0, 27, 27, 27, 27, 0, 27, 27, 27, 27, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 0, 27, 0, 27, 27, 27, 27, 0, 0, 0, 27, 0, 27, 27, 27, 27, 27, + 27, 27, 0, 0, 27, 27, 27, 27, 27, 27, 27, 162, 163, 162, 163, 162, 163, + 162, 163, 162, 163, 162, 163, 162, 163, 234, 234, 234, 234, 234, 234, + 234, 234, 234, 234, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 27, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 171, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, 0, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 42, 57, 57, 57, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 0, 0, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 40, 60, - 61, 61, 61, 57, 0, 0, 0, 0, 0, 0, 0, 0, 60, 60, 57, 43, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 44, 44, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 34, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 42, 34, 34, 34, 34, 34, 34, - 34, 34, 37, 34, 37, 34, 37, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 43, - 186, 186, 37, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, - 40, 40, 40, 40, 109, 40, 40, 40, 114, 40, 40, 40, 40, 109, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 112, 112, 109, 109, 112, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 57, 57, 57, 57, 0, 0, 0, 0, 0, 0, 0, 0, 112, - 112, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 62, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 109, 109, 109, 109, 109, 64, 64, 64, 62, 62, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 112, 136, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 109, 109, 109, 109, 109, 109, 112, 112, 109, 109, - 112, 112, 109, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 109, 40, 40, - 40, 40, 40, 40, 40, 40, 109, 112, 0, 0, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 0, 0, 62, 62, 62, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, 0, 0, - 0, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 34, 34, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 85, 189, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 157, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 0, - 85, 85, 85, 85, 85, 0, 85, 0, 85, 85, 0, 85, 85, 0, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 144, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 0, 0, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 89, 27, - 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 170, 170, 170, 170, 170, 170, 170, 174, 175, 170, 0, 0, 0, 0, 0, 0, 60, - 60, 60, 60, 60, 60, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, 173, 173, 191, - 191, 174, 175, 174, 175, 174, 175, 174, 175, 174, 175, 174, 175, 174, - 175, 174, 175, 170, 170, 174, 175, 170, 170, 170, 170, 191, 191, 191, - 192, 170, 192, 0, 170, 192, 170, 170, 173, 165, 166, 165, 166, 165, 166, - 193, 170, 170, 194, 195, 196, 196, 197, 0, 170, 198, 193, 170, 0, 0, 0, - 0, 95, 95, 95, 95, 95, 0, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 0, 0, 107, 0, - 199, 199, 200, 201, 200, 199, 199, 202, 203, 199, 204, 205, 206, 205, - 205, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 205, 199, 208, - 209, 208, 199, 199, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 202, 199, 203, 211, 212, 211, 213, 213, 213, 213, 213, 213, - 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, - 213, 213, 213, 213, 213, 213, 202, 209, 203, 209, 202, 203, 214, 215, - 216, 214, 214, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 218, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 218, 218, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 0, 0, 0, 217, 217, 217, 217, 217, - 217, 0, 0, 217, 217, 217, 217, 217, 217, 0, 0, 217, 217, 217, 217, 217, - 217, 0, 0, 217, 217, 217, 0, 0, 0, 201, 201, 209, 211, 219, 201, 201, 0, - 220, 221, 221, 221, 221, 220, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 222, - 222, 222, 27, 25, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 0, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 62, 57, - 59, 0, 0, 0, 0, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 0, 0, 0, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 120, 120, 120, - 120, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 120, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 0, 117, 117, 117, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 134, 40, - 40, 40, 40, 40, 40, 40, 40, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 0, 62, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, - 40, 62, 134, 134, 134, 134, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, 85, 85, 0, 0, 85, 0, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 0, 85, 85, 0, 0, 0, 85, 0, 0, 85, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 224, - 224, 224, 224, 0, 0, 0, 0, 0, 57, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 0, 0, 0, - 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 85, 109, 109, 109, 0, 109, 109, 0, 0, 0, 0, 0, 109, 64, 109, 60, - 85, 85, 85, 85, 0, 85, 85, 85, 0, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 0, 0, - 0, 0, 60, 159, 64, 0, 0, 0, 0, 114, 224, 224, 224, 224, 224, 224, 224, - 224, 0, 0, 0, 0, 0, 0, 0, 0, 82, 82, 82, 82, 82, 82, 82, 82, 82, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 27, 27, 27, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 0, 224, 77, 77, 224, 224, 162, 163, 77, 224, 224, 77, 0, 224, 0, 0, + 0, 77, 77, 77, 224, 224, 224, 224, 77, 77, 77, 77, 77, 224, 224, 224, 77, + 77, 77, 224, 224, 224, 224, 9, 10, 9, 10, 9, 10, 9, 10, 162, 163, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 162, 163, 9, 10, 162, 163, 162, 163, 162, 163, 162, 163, 162, + 163, 162, 163, 162, 163, 162, 163, 162, 163, 77, 77, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 77, 77, 77, 77, 77, 77, 77, 77, 224, 77, 77, 77, 77, 77, + 77, 77, 224, 224, 224, 224, 224, 224, 77, 77, 77, 224, 77, 77, 77, 77, + 224, 224, 224, 224, 224, 77, 224, 224, 77, 77, 162, 163, 162, 163, 224, + 77, 77, 77, 77, 224, 77, 224, 224, 224, 77, 77, 224, 224, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 224, 224, 224, 224, 224, 224, 77, 77, 162, 163, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 224, 224, 218, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 77, + 224, 224, 224, 224, 77, 77, 224, 77, 224, 77, 77, 224, 77, 224, 224, 224, + 224, 77, 77, 77, 77, 77, 224, 224, 77, 77, 77, 77, 77, 77, 224, 224, 224, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 224, 224, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 224, 224, 77, 77, 77, 77, 224, 224, 224, 224, 77, 224, 224, 77, 77, + 224, 218, 208, 208, 77, 77, 224, 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 77, 77, 224, 224, 224, 224, 224, 224, 224, + 224, 77, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 77, 77, + 77, 77, 77, 235, 77, 224, 77, 77, 77, 224, 224, 224, 224, 224, 77, 77, + 77, 77, 77, 224, 224, 224, 77, 77, 77, 77, 224, 77, 77, 77, 224, 224, + 224, 224, 224, 77, 224, 77, 77, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 27, 27, 77, 77, 77, 77, 77, 77, 0, 0, 0, 27, 27, 27, + 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 0, 44, 46, 44, 44, 44, 46, 46, 44, 46, 44, 46, 44, 46, 44, + 44, 44, 0, 46, 44, 46, 46, 44, 46, 46, 46, 46, 46, 46, 35, 50, 0, 0, 44, + 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, + 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, + 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, + 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, + 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, + 46, 44, 46, 44, 46, 44, 46, 44, 46, 46, 27, 27, 27, 27, 27, 27, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 136, 136, 136, 152, 136, 136, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, + 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, + 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, + 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 136, 136, 29, 36, 29, 36, 136, 136, 136, 29, 36, + 136, 29, 36, 136, 136, 136, 136, 136, 136, 136, 136, 136, 83, 136, 136, + 83, 136, 29, 36, 136, 136, 29, 36, 162, 163, 162, 163, 162, 163, 162, + 163, 136, 136, 136, 136, 136, 51, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 0, 236, 236, 236, 236, + 237, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 0, 0, 0, 0, 238, + 239, 239, 239, 236, 240, 169, 241, 242, 243, 242, 243, 242, 243, 242, + 243, 242, 243, 236, 236, 242, 243, 242, 243, 242, 243, 242, 243, 244, + 245, 246, 246, 236, 241, 241, 241, 241, 241, 241, 241, 241, 241, 247, + 248, 249, 250, 251, 251, 244, 240, 240, 240, 240, 240, 237, 236, 252, + 252, 252, 240, 169, 239, 236, 27, 0, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 253, 169, 253, 169, 253, 169, 253, 169, 253, 169, + 253, 169, 253, 169, 253, 169, 253, 169, 253, 169, 253, 169, 253, 169, + 169, 253, 169, 253, 169, 253, 169, 169, 169, 169, 169, 169, 253, 253, + 169, 253, 253, 169, 253, 253, 169, 253, 253, 169, 253, 253, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 253, 169, 169, 0, 0, 254, 254, 255, 255, + 240, 256, 257, 244, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 253, 169, 253, 169, 253, 169, 253, 169, 253, 169, 253, 169, 253, + 169, 253, 169, 253, 169, 253, 169, 253, 169, 253, 169, 169, 253, 169, + 253, 169, 253, 169, 169, 169, 169, 169, 169, 253, 253, 169, 253, 253, + 169, 253, 253, 169, 253, 253, 169, 253, 253, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 253, 169, 169, 253, 253, 253, 253, 239, 240, 240, 256, + 257, 0, 0, 0, 0, 0, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 0, 0, 0, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 0, + 258, 258, 259, 259, 259, 259, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 0, 0, 0, 0, + 0, 0, 0, 0, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 237, 237, 0, 259, 259, 259, 259, 259, 259, 259, + 259, 259, 259, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 261, 261, 261, 261, 261, + 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 237, 237, 237, 258, + 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 261, 261, 261, 261, 261, 261, 261, + 261, 261, 261, 261, 261, 261, 261, 261, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 237, 237, 237, 237, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 0, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 237, 237, 237, 237, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 237, + 237, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 237, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 240, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 0, 0, 0, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 52, 136, 136, 136, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 46, 44, 46, 44, 46, 44, 46, 44, + 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, + 46, 44, 46, 44, 46, 0, 0, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 47, 80, 81, 81, 81, 136, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 136, 51, 44, 46, + 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 53, 53, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 46, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 50, 46, 46, 46, + 46, 46, 46, 46, 46, 44, 46, 44, 46, 44, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 51, 262, 262, 44, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 47, 47, 47, 47, 47, 47, 47, 133, 47, 47, 47, 140, 47, 47, 47, 47, 133, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 137, 137, 133, 133, 137, 27, 27, 27, 27, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 136, 136, 136, 136, 0, 0, 0, 0, + 0, 0, 0, 0, 137, 137, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 82, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 133, 133, 133, 133, 133, 84, 84, 84, 82, 82, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 137, 174, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 133, 133, 133, 133, 133, 133, 137, 137, 133, 133, 137, 137, 133, + 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 133, 47, 47, 47, 47, 47, 47, + 47, 47, 133, 137, 0, 0, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 0, 0, 82, 82, 82, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 169, 169, 265, 169, 265, 169, + 169, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 169, 265, 169, + 265, 169, 169, 265, 265, 169, 169, 169, 265, 265, 265, 265, 0, 0, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 0, 0, 0, 0, 0, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 35, 35, 35, 35, 35, 0, 0, 0, 0, 0, 266, 267, 266, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 207, 266, 266, 266, 266, + 266, 266, 266, 266, 266, 266, 266, 266, 266, 0, 266, 266, 266, 266, 266, + 0, 266, 0, 266, 266, 0, 266, 266, 0, 266, 266, 266, 266, 266, 266, 266, + 266, 266, 268, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 191, 269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 0, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 270, 27, 0, 0, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 271, 271, 271, 271, 271, 271, 271, 272, 273, 271, 0, 0, 0, 0, + 0, 0, 80, 80, 80, 80, 80, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 271, 274, + 274, 275, 275, 272, 273, 272, 273, 272, 273, 272, 273, 272, 273, 272, + 273, 272, 273, 272, 273, 239, 239, 272, 273, 271, 271, 271, 271, 275, + 275, 275, 276, 271, 276, 0, 271, 276, 271, 271, 274, 277, 278, 277, 278, + 277, 278, 279, 271, 271, 280, 281, 282, 282, 283, 0, 271, 284, 279, 271, + 0, 0, 0, 0, 128, 128, 128, 115, 128, 0, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 0, 0, 131, 0, 285, 285, 286, 287, 286, 285, 285, 288, 289, + 285, 290, 291, 292, 291, 291, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 291, 285, 294, 295, 294, 285, 285, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 288, 285, 289, 297, 298, 297, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 288, 295, 289, + 295, 288, 289, 300, 301, 302, 300, 300, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 304, 303, 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, 304, 304, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 0, 0, 0, + 303, 303, 303, 303, 303, 303, 0, 0, 303, 303, 303, 303, 303, 303, 0, 0, + 303, 303, 303, 303, 303, 303, 0, 0, 303, 303, 303, 0, 0, 0, 287, 287, + 295, 297, 305, 287, 287, 0, 306, 307, 307, 307, 307, 306, 306, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 308, 308, 308, 27, 25, 0, 0, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, + 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, + 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 0, 0, 0, 0, 0, 82, 136, 79, 0, 0, 0, 0, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 0, 0, 0, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 309, 309, 309, 309, 309, 309, 309, 309, 309, + 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, + 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, + 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, + 309, 309, 152, 152, 152, 152, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 152, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 84, 0, 0, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 0, 147, 147, 147, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 172, 47, + 47, 47, 47, 47, 47, 47, 47, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 0, 82, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, + 47, 82, 172, 172, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 0, 0, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 62, 62, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 105, 105, 105, 105, 105, 105, 0, 0, 105, 0, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 0, 105, 105, 0, 0, 0, 105, 0, 0, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 310, 310, 310, + 310, 0, 0, 0, 0, 0, 136, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 0, 0, 0, 0, 0, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 0, 0, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 225, 225, 159, 159, 159, 59, 59, 59, 226, 225, 225, - 225, 225, 225, 107, 107, 107, 107, 107, 107, 107, 107, 64, 64, 64, 64, - 64, 64, 64, 64, 59, 59, 60, 60, 60, 60, 60, 64, 64, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, + 0, 0, 0, 105, 133, 133, 133, 0, 133, 133, 0, 0, 0, 0, 0, 133, 84, 133, + 80, 105, 105, 105, 105, 0, 105, 105, 105, 0, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 0, 0, 0, 0, 80, 213, 84, 0, 0, 0, + 0, 140, 310, 310, 310, 310, 310, 310, 310, 310, 0, 0, 0, 0, 0, 0, 0, 0, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 82, 82, 82, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 311, 311, 311, 311, 311, 311, 311, + 312, 312, 213, 213, 213, 79, 79, 79, 313, 312, 312, 312, 312, 312, 131, + 131, 131, 131, 131, 131, 131, 131, 84, 84, 84, 84, 84, 84, 84, 84, 79, + 79, 80, 80, 80, 80, 80, 84, 84, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 80, 80, 80, 80, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 311, 311, 311, 311, 311, 311, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 60, 60, 60, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 27, 80, 80, 80, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 34, 34, 34, 34, 34, 34, 34, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 37, 0, 37, 37, 0, 0, 37, 0, 0, 37, 37, 0, 0, 37, - 37, 37, 37, 0, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 0, 34, 0, - 34, 34, 34, 34, 34, 34, 34, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, - 37, 0, 37, 37, 37, 37, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, 0, 37, 37, - 37, 37, 37, 37, 37, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 0, 37, - 37, 37, 37, 0, 37, 37, 37, 37, 37, 0, 37, 0, 0, 0, 37, 37, 37, 37, 37, - 37, 37, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 227, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 228, - 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 227, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 228, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 227, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 228, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 227, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 228, 34, 34, 34, 34, 34, 34, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 227, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 228, 34, 34, - 34, 34, 34, 34, 37, 34, 0, 0, 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 35, 35, 35, 35, 35, 35, 35, 0, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 48, 0, 48, 48, 0, 0, 48, 0, 0, 48, 48, 0, + 0, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 35, 35, 35, 35, 0, + 35, 0, 35, 35, 35, 35, 35, 35, 35, 0, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 48, 48, 0, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, + 48, 48, 48, 48, 48, 48, 0, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 48, 48, 0, + 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 0, 48, 0, 0, 0, 48, 48, 48, 48, + 48, 48, 48, 0, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 314, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 315, 35, 35, 35, 35, 35, 35, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 314, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 315, 35, 35, 35, 35, 35, 35, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 314, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 315, 35, 35, 35, 35, 35, 35, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 314, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 315, 35, 35, 35, 35, 35, + 35, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 314, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 315, 35, + 35, 35, 35, 35, 35, 48, 35, 0, 0, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, @@ -2055,81 +2309,52 @@ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 0, 0, }; /* decomposition data */ Modified: python/trunk/Tools/unicode/makeunicodedata.py ============================================================================== --- python/trunk/Tools/unicode/makeunicodedata.py (original) +++ python/trunk/Tools/unicode/makeunicodedata.py Mon Apr 27 23:53:26 2009 @@ -34,6 +34,7 @@ UNICODE_DATA = "UnicodeData%s.txt" COMPOSITION_EXCLUSIONS = "CompositionExclusions%s.txt" EASTASIAN_WIDTH = "EastAsianWidth%s.txt" +DERIVEDNORMALIZATION_PROPS = "DerivedNormalizationProps%s.txt" old_versions = ["3.2.0"] @@ -66,7 +67,8 @@ version = "" unicode = UnicodeData(UNICODE_DATA % version, COMPOSITION_EXCLUSIONS % version, - EASTASIAN_WIDTH % version) + EASTASIAN_WIDTH % version, + DERIVEDNORMALIZATION_PROPS % version) print len(filter(None, unicode.table)), "characters" @@ -87,7 +89,7 @@ def makeunicodedata(unicode, trace): - dummy = (0, 0, 0, 0, 0) + dummy = (0, 0, 0, 0, 0, 0) table = [dummy] cache = {0: dummy} index = [0] * len(unicode.chars) @@ -107,8 +109,10 @@ bidirectional = BIDIRECTIONAL_NAMES.index(record[4]) mirrored = record[9] == "Y" eastasianwidth = EASTASIANWIDTH_NAMES.index(record[15]) + normalizationquickcheck = record[16] item = ( - category, combining, bidirectional, mirrored, eastasianwidth + category, combining, bidirectional, mirrored, eastasianwidth, + normalizationquickcheck ) # add entry to index and item tables i = cache.get(item) @@ -222,7 +226,7 @@ print >>fp, \ "const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = {" for item in table: - print >>fp, " {%d, %d, %d, %d, %d}," % item + print >>fp, " {%d, %d, %d, %d, %d, %d}," % item print >>fp, "};" print >>fp @@ -698,7 +702,8 @@ class UnicodeData: - def __init__(self, filename, exclusions, eastasianwidth, expand=1): + def __init__(self, filename, exclusions, eastasianwidth, + derivednormalizationprops=None, expand=1): self.changed = [] file = open(filename) table = [None] * 0x110000 @@ -761,6 +766,28 @@ for i in range(0, 0x110000): if table[i] is not None: table[i].append(widths[i]) + if derivednormalizationprops: + quickchecks = [0] * 0x110000 # default is Yes + qc_order = 'NFD_QC NFKD_QC NFC_QC NFKC_QC'.split() + for s in open(derivednormalizationprops): + if '#' in s: + s = s[:s.index('#')] + s = [i.strip() for i in s.split(';')] + if len(s) < 2 or s[1] not in qc_order: + continue + quickcheck = 'MN'.index(s[2]) + 1 # Maybe or No + quickcheck_shift = qc_order.index(s[1])*2 + quickcheck <<= quickcheck_shift + if '..' not in s[0]: + first = last = int(s[0], 16) + else: + first, last = [int(c, 16) for c in s[0].split('..')] + for char in range(first, last+1): + assert not (quickchecks[char]>>quickcheck_shift)&3 + quickchecks[char] |= quickcheck + for i in range(0, 0x110000): + if table[i] is not None: + table[i].append(quickchecks[i]) def uselatin1(self): # restrict character range to ISO Latin 1 From buildbot at python.org Mon Apr 27 23:53:33 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 27 Apr 2009 21:53:33 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090427215334.31D761E4046@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/590 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_posix test_time ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 251, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 177, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_tzset (test.test_time.TimeTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_time.py", line 157, in test_tzset time.gmtime(xmas2002), time.localtime(xmas2002) AssertionError: time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) != time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=1, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) sincerely, -The Buildbot From buildbot at python.org Mon Apr 27 23:56:45 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 27 Apr 2009 21:56:45 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090427215645.DD4051E402E@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/655 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_time make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Tue Apr 28 00:31:41 2009 From: python-checkins at python.org (antoine.pitrou) Date: Tue, 28 Apr 2009 00:31:41 +0200 (CEST) Subject: [Python-checkins] r72055 - in python/branches/py3k: Misc/ACKS Misc/NEWS Modules/unicodedata.c Modules/unicodedata_db.h Tools/unicode/makeunicodedata.py Message-ID: <20090427223141.5C11C1E401A@bag.python.org> Author: antoine.pitrou Date: Tue Apr 28 00:31:40 2009 New Revision: 72055 Log: Merged revisions 72054 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72054 | antoine.pitrou | 2009-04-27 23:53:26 +0200 (lun., 27 avril 2009) | 5 lines Issue #1734234: Massively speedup `unicodedata.normalize()` when the string is already in normalized form, by performing a quick check beforehand. Original patch by Rauli Ruohonen. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/unicodedata.c python/branches/py3k/Modules/unicodedata_db.h python/branches/py3k/Tools/unicode/makeunicodedata.py Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Tue Apr 28 00:31:40 2009 @@ -616,6 +616,7 @@ Paul Rubin Sam Ruby Audun S. Runde +Rauli Ruohonen Jeff Rush Sam Rushing Mark Russell Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Tue Apr 28 00:31:40 2009 @@ -92,6 +92,10 @@ Library ------- +- Issue #1734234: Massively speedup ``unicodedata.normalize()`` when the + string is already in normalized form, by performing a quick check beforehand. + Original patch by Rauli Ruohonen. + - Issue #5853: calling a function of the mimetypes module from several threads at once could hit the recursion limit if the mimetypes database hadn't been initialized before. Modified: python/branches/py3k/Modules/unicodedata.c ============================================================================== --- python/branches/py3k/Modules/unicodedata.c (original) +++ python/branches/py3k/Modules/unicodedata.c Tue Apr 28 00:31:40 2009 @@ -27,6 +27,7 @@ const unsigned char mirrored; /* true if mirrored in bidir mode */ const unsigned char east_asian_width; /* index into _PyUnicode_EastAsianWidth */ + const unsigned char normalization_quick_check; /* see is_normalized() */ } _PyUnicode_DatabaseRecord; typedef struct change_record { @@ -722,7 +723,39 @@ PyUnicode_Resize(&result, o - PyUnicode_AS_UNICODE(result)); return result; } - + +/* Return 1 if the input is certainly normalized, 0 if it might not be. */ +static int +is_normalized(PyObject *self, PyObject *input, int nfc, int k) +{ + Py_UNICODE *i, *end; + unsigned char prev_combining = 0, quickcheck_mask; + + /* An older version of the database is requested, quickchecks must be + disabled. */ + if (self && UCD_Check(self)) + return 0; + + /* The two quickcheck bits at this shift mean 0=Yes, 1=Maybe, 2=No, + as described in http://unicode.org/reports/tr15/#Annex8. */ + quickcheck_mask = 3 << ((nfc ? 4 : 0) + (k ? 2 : 0)); + + i = PyUnicode_AS_UNICODE(input); + end = i + PyUnicode_GET_SIZE(input); + while (i < end) { + const _PyUnicode_DatabaseRecord *record = _getrecord_ex(*i++); + unsigned char combining = record->combining; + unsigned char quickcheck = record->normalization_quick_check; + + if (quickcheck & quickcheck_mask) + return 0; /* this string might need normalization */ + if (combining && prev_combining > combining) + return 0; /* non-canonical sort order, not normalized */ + prev_combining = combining; + } + return 1; /* certainly normalized */ +} + PyDoc_STRVAR(unicodedata_normalize__doc__, "normalize(form, unistr)\n\ \n\ @@ -746,14 +779,34 @@ return input; } - if (strcmp(form, "NFC") == 0) + if (strcmp(form, "NFC") == 0) { + if (is_normalized(self, input, 1, 0)) { + Py_INCREF(input); + return input; + } return nfc_nfkc(self, input, 0); - if (strcmp(form, "NFKC") == 0) + } + if (strcmp(form, "NFKC") == 0) { + if (is_normalized(self, input, 1, 1)) { + Py_INCREF(input); + return input; + } return nfc_nfkc(self, input, 1); - if (strcmp(form, "NFD") == 0) + } + if (strcmp(form, "NFD") == 0) { + if (is_normalized(self, input, 0, 0)) { + Py_INCREF(input); + return input; + } return nfd_nfkd(self, input, 0); - if (strcmp(form, "NFKD") == 0) + } + if (strcmp(form, "NFKD") == 0) { + if (is_normalized(self, input, 0, 1)) { + Py_INCREF(input); + return input; + } return nfd_nfkd(self, input, 1); + } PyErr_SetString(PyExc_ValueError, "invalid normalization form"); return NULL; } Modified: python/branches/py3k/Modules/unicodedata_db.h ============================================================================== --- python/branches/py3k/Modules/unicodedata_db.h (original) +++ python/branches/py3k/Modules/unicodedata_db.h Tue Apr 28 00:31:40 2009 @@ -3,235 +3,323 @@ #define UNIDATA_VERSION "5.1.0" /* a list of unique database records */ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { - {0, 0, 0, 0, 0}, - {13, 0, 15, 0, 5}, - {13, 0, 17, 0, 5}, - {13, 0, 16, 0, 5}, - {13, 0, 18, 0, 5}, - {10, 0, 18, 0, 3}, - {26, 0, 19, 0, 3}, - {26, 0, 11, 0, 3}, - {28, 0, 11, 0, 3}, - {22, 0, 19, 1, 3}, - {23, 0, 19, 1, 3}, - {27, 0, 10, 0, 3}, - {26, 0, 13, 0, 3}, - {21, 0, 10, 0, 3}, - {7, 0, 9, 0, 3}, - {27, 0, 19, 1, 3}, - {27, 0, 19, 0, 3}, - {1, 0, 1, 0, 3}, - {29, 0, 19, 0, 3}, - {20, 0, 19, 0, 3}, - {2, 0, 1, 0, 3}, - {10, 0, 13, 0, 5}, - {26, 0, 19, 0, 4}, - {28, 0, 11, 0, 4}, - {30, 0, 19, 0, 3}, - {30, 0, 19, 0, 4}, - {29, 0, 19, 0, 4}, - {30, 0, 19, 0, 5}, - {2, 0, 1, 0, 4}, - {24, 0, 19, 1, 5}, - {14, 0, 15, 0, 4}, - {30, 0, 11, 0, 4}, - {27, 0, 11, 0, 4}, - {9, 0, 9, 0, 4}, - {2, 0, 1, 0, 5}, - {25, 0, 19, 1, 5}, - {9, 0, 19, 0, 4}, - {1, 0, 1, 0, 5}, - {1, 0, 1, 0, 4}, - {27, 0, 19, 0, 4}, - {19, 0, 1, 0, 5}, - {3, 0, 1, 0, 5}, - {18, 0, 1, 0, 5}, - {18, 0, 19, 0, 5}, - {29, 0, 19, 0, 5}, - {18, 0, 19, 0, 4}, - {18, 0, 1, 0, 4}, - {4, 230, 14, 0, 4}, - {4, 232, 14, 0, 4}, - {4, 220, 14, 0, 4}, - {4, 216, 14, 0, 4}, - {4, 202, 14, 0, 4}, - {4, 1, 14, 0, 4}, - {4, 240, 14, 0, 4}, - {4, 0, 14, 0, 4}, - {4, 233, 14, 0, 4}, - {4, 234, 14, 0, 4}, - {26, 0, 19, 0, 5}, - {27, 0, 19, 0, 5}, - {30, 0, 1, 0, 5}, - {4, 230, 14, 0, 5}, - {6, 0, 14, 0, 5}, - {26, 0, 1, 0, 5}, - {21, 0, 19, 0, 5}, - {4, 220, 14, 0, 5}, - {4, 222, 14, 0, 5}, - {4, 228, 14, 0, 5}, - {4, 10, 14, 0, 5}, - {4, 11, 14, 0, 5}, - {4, 12, 14, 0, 5}, - {4, 13, 14, 0, 5}, - {4, 14, 14, 0, 5}, - {4, 15, 14, 0, 5}, - {4, 16, 14, 0, 5}, - {4, 17, 14, 0, 5}, - {4, 18, 14, 0, 5}, - {4, 19, 14, 0, 5}, - {4, 20, 14, 0, 5}, - {4, 21, 14, 0, 5}, - {4, 22, 14, 0, 5}, - {21, 0, 4, 0, 5}, - {4, 23, 14, 0, 5}, - {26, 0, 4, 0, 5}, - {4, 24, 14, 0, 5}, - {4, 25, 14, 0, 5}, - {19, 0, 4, 0, 5}, - {14, 0, 12, 0, 5}, - {27, 0, 5, 0, 5}, - {26, 0, 11, 0, 5}, - {28, 0, 5, 0, 5}, - {26, 0, 13, 0, 5}, - {26, 0, 5, 0, 5}, - {4, 30, 14, 0, 5}, - {4, 31, 14, 0, 5}, - {4, 32, 14, 0, 5}, - {19, 0, 5, 0, 5}, - {18, 0, 5, 0, 5}, - {4, 27, 14, 0, 5}, - {4, 28, 14, 0, 5}, - {4, 29, 14, 0, 5}, - {4, 33, 14, 0, 5}, - {4, 34, 14, 0, 5}, - {7, 0, 12, 0, 5}, - {26, 0, 12, 0, 5}, - {4, 35, 14, 0, 5}, - {7, 0, 9, 0, 5}, - {30, 0, 5, 0, 5}, - {14, 0, 15, 0, 5}, - {4, 36, 14, 0, 5}, - {4, 0, 14, 0, 5}, - {7, 0, 4, 0, 5}, - {18, 0, 4, 0, 5}, - {5, 0, 1, 0, 5}, - {4, 7, 14, 0, 5}, - {4, 9, 14, 0, 5}, - {7, 0, 1, 0, 5}, - {28, 0, 11, 0, 5}, - {9, 0, 1, 0, 5}, - {4, 84, 14, 0, 5}, - {4, 91, 14, 0, 5}, - {9, 0, 19, 0, 5}, - {4, 0, 1, 0, 5}, - {4, 103, 14, 0, 5}, - {4, 107, 14, 0, 5}, - {4, 118, 14, 0, 5}, - {4, 122, 14, 0, 5}, - {4, 216, 14, 0, 5}, - {22, 0, 19, 1, 5}, - {23, 0, 19, 1, 5}, - {4, 129, 14, 0, 5}, - {4, 130, 14, 0, 5}, - {4, 132, 14, 0, 5}, - {19, 0, 1, 0, 2}, - {10, 0, 18, 0, 5}, - {8, 0, 1, 0, 5}, - {14, 0, 1, 0, 5}, - {5, 9, 1, 0, 5}, - {4, 234, 14, 0, 5}, - {4, 214, 14, 0, 5}, - {4, 202, 14, 0, 5}, - {14, 0, 4, 0, 5}, - {21, 0, 19, 0, 4}, - {24, 0, 19, 0, 4}, - {25, 0, 19, 0, 4}, - {22, 0, 19, 0, 5}, - {24, 0, 19, 0, 5}, - {11, 0, 18, 0, 5}, - {12, 0, 16, 0, 5}, - {14, 0, 2, 0, 5}, - {14, 0, 6, 0, 5}, - {14, 0, 8, 0, 5}, - {14, 0, 3, 0, 5}, - {14, 0, 7, 0, 5}, - {26, 0, 11, 0, 4}, - {20, 0, 19, 0, 5}, - {27, 0, 13, 0, 5}, - {9, 0, 9, 0, 5}, - {27, 0, 10, 0, 5}, - {28, 0, 11, 0, 1}, - {4, 1, 14, 0, 5}, - {30, 0, 11, 0, 5}, - {27, 0, 19, 1, 5}, - {8, 0, 1, 0, 4}, - {27, 0, 19, 1, 4}, - {27, 0, 11, 0, 5}, - {22, 0, 19, 1, 2}, - {23, 0, 19, 1, 2}, - {30, 0, 1, 0, 4}, - {30, 0, 19, 0, 2}, - {10, 0, 18, 0, 0}, - {26, 0, 19, 0, 2}, - {18, 0, 1, 0, 2}, - {8, 0, 1, 0, 2}, - {21, 0, 19, 0, 2}, - {22, 0, 19, 0, 2}, - {23, 0, 19, 0, 2}, - {4, 218, 14, 0, 2}, - {4, 228, 14, 0, 2}, - {4, 232, 14, 0, 2}, - {4, 222, 14, 0, 2}, - {4, 224, 14, 0, 2}, - {4, 8, 14, 0, 2}, - {29, 0, 19, 0, 2}, - {30, 0, 1, 0, 2}, - {9, 0, 1, 0, 2}, - {9, 0, 19, 0, 2}, - {29, 0, 1, 0, 5}, - {15, 0, 1, 0, 5}, - {16, 0, 1, 0, 4}, - {4, 26, 14, 0, 5}, - {23, 0, 19, 0, 5}, - {20, 0, 19, 0, 2}, - {26, 0, 13, 0, 2}, - {26, 0, 11, 0, 2}, - {27, 0, 10, 0, 2}, - {21, 0, 10, 0, 2}, - {27, 0, 19, 1, 2}, - {27, 0, 19, 0, 2}, - {28, 0, 11, 0, 2}, - {26, 0, 19, 0, 0}, - {26, 0, 11, 0, 0}, - {28, 0, 11, 0, 0}, - {22, 0, 19, 1, 0}, - {23, 0, 19, 1, 0}, - {27, 0, 10, 0, 0}, - {26, 0, 13, 0, 0}, - {21, 0, 10, 0, 0}, - {7, 0, 9, 0, 0}, - {27, 0, 19, 1, 0}, - {27, 0, 19, 0, 0}, - {1, 0, 1, 0, 0}, - {29, 0, 19, 0, 0}, - {20, 0, 19, 0, 0}, - {2, 0, 1, 0, 0}, - {26, 0, 19, 0, 1}, - {22, 0, 19, 1, 1}, - {23, 0, 19, 1, 1}, - {19, 0, 1, 0, 1}, - {18, 0, 1, 0, 1}, - {30, 0, 19, 0, 0}, - {30, 0, 19, 0, 1}, - {27, 0, 19, 0, 1}, - {14, 0, 19, 0, 5}, - {8, 0, 19, 0, 5}, - {9, 0, 4, 0, 5}, - {5, 216, 1, 0, 5}, - {5, 226, 1, 0, 5}, - {27, 0, 1, 0, 5}, - {27, 0, 1, 1, 5}, + {0, 0, 0, 0, 0, 0}, + {13, 0, 15, 0, 5, 0}, + {13, 0, 17, 0, 5, 0}, + {13, 0, 16, 0, 5, 0}, + {13, 0, 18, 0, 5, 0}, + {10, 0, 18, 0, 3, 0}, + {26, 0, 19, 0, 3, 0}, + {26, 0, 11, 0, 3, 0}, + {28, 0, 11, 0, 3, 0}, + {22, 0, 19, 1, 3, 0}, + {23, 0, 19, 1, 3, 0}, + {27, 0, 10, 0, 3, 0}, + {26, 0, 13, 0, 3, 0}, + {21, 0, 10, 0, 3, 0}, + {7, 0, 9, 0, 3, 0}, + {27, 0, 19, 1, 3, 0}, + {27, 0, 19, 0, 3, 0}, + {1, 0, 1, 0, 3, 0}, + {29, 0, 19, 0, 3, 0}, + {20, 0, 19, 0, 3, 0}, + {2, 0, 1, 0, 3, 0}, + {10, 0, 13, 0, 5, 136}, + {26, 0, 19, 0, 4, 0}, + {28, 0, 11, 0, 4, 0}, + {30, 0, 19, 0, 3, 0}, + {30, 0, 19, 0, 4, 0}, + {29, 0, 19, 0, 4, 136}, + {30, 0, 19, 0, 5, 0}, + {2, 0, 1, 0, 4, 136}, + {24, 0, 19, 1, 5, 0}, + {14, 0, 15, 0, 4, 0}, + {29, 0, 19, 0, 3, 136}, + {30, 0, 11, 0, 4, 0}, + {27, 0, 11, 0, 4, 0}, + {9, 0, 9, 0, 4, 136}, + {2, 0, 1, 0, 5, 136}, + {25, 0, 19, 1, 5, 0}, + {9, 0, 19, 0, 4, 136}, + {1, 0, 1, 0, 5, 10}, + {1, 0, 1, 0, 4, 0}, + {27, 0, 19, 0, 4, 0}, + {2, 0, 1, 0, 4, 0}, + {2, 0, 1, 0, 4, 10}, + {2, 0, 1, 0, 5, 10}, + {1, 0, 1, 0, 5, 0}, + {1, 0, 1, 0, 4, 136}, + {2, 0, 1, 0, 5, 0}, + {19, 0, 1, 0, 5, 0}, + {1, 0, 1, 0, 5, 136}, + {3, 0, 1, 0, 5, 136}, + {18, 0, 1, 0, 5, 136}, + {18, 0, 19, 0, 5, 0}, + {18, 0, 1, 0, 5, 0}, + {29, 0, 19, 0, 5, 0}, + {29, 0, 19, 0, 4, 0}, + {18, 0, 19, 0, 4, 0}, + {18, 0, 1, 0, 4, 0}, + {29, 0, 19, 0, 5, 136}, + {4, 230, 14, 0, 4, 80}, + {4, 230, 14, 0, 4, 0}, + {4, 232, 14, 0, 4, 0}, + {4, 220, 14, 0, 4, 0}, + {4, 216, 14, 0, 4, 80}, + {4, 202, 14, 0, 4, 0}, + {4, 220, 14, 0, 4, 80}, + {4, 202, 14, 0, 4, 80}, + {4, 1, 14, 0, 4, 0}, + {4, 1, 14, 0, 4, 80}, + {4, 230, 14, 0, 4, 170}, + {4, 240, 14, 0, 4, 80}, + {4, 0, 14, 0, 4, 0}, + {4, 233, 14, 0, 4, 0}, + {4, 234, 14, 0, 4, 0}, + {18, 0, 19, 0, 5, 170}, + {26, 0, 19, 0, 5, 170}, + {29, 0, 19, 0, 5, 138}, + {1, 0, 1, 0, 5, 138}, + {27, 0, 19, 0, 5, 0}, + {1, 0, 1, 0, 4, 10}, + {30, 0, 1, 0, 5, 0}, + {4, 230, 14, 0, 5, 0}, + {6, 0, 14, 0, 5, 0}, + {26, 0, 1, 0, 5, 0}, + {21, 0, 19, 0, 5, 0}, + {4, 220, 14, 0, 5, 0}, + {4, 222, 14, 0, 5, 0}, + {4, 228, 14, 0, 5, 0}, + {4, 10, 14, 0, 5, 0}, + {4, 11, 14, 0, 5, 0}, + {4, 12, 14, 0, 5, 0}, + {4, 13, 14, 0, 5, 0}, + {4, 14, 14, 0, 5, 0}, + {4, 15, 14, 0, 5, 0}, + {4, 16, 14, 0, 5, 0}, + {4, 17, 14, 0, 5, 0}, + {4, 18, 14, 0, 5, 0}, + {4, 19, 14, 0, 5, 0}, + {4, 20, 14, 0, 5, 0}, + {4, 21, 14, 0, 5, 0}, + {4, 22, 14, 0, 5, 0}, + {21, 0, 4, 0, 5, 0}, + {4, 23, 14, 0, 5, 0}, + {26, 0, 4, 0, 5, 0}, + {4, 24, 14, 0, 5, 0}, + {4, 25, 14, 0, 5, 0}, + {19, 0, 4, 0, 5, 0}, + {14, 0, 12, 0, 5, 0}, + {27, 0, 5, 0, 5, 0}, + {26, 0, 11, 0, 5, 0}, + {28, 0, 5, 0, 5, 0}, + {26, 0, 13, 0, 5, 0}, + {26, 0, 5, 0, 5, 0}, + {4, 30, 14, 0, 5, 0}, + {4, 31, 14, 0, 5, 0}, + {4, 32, 14, 0, 5, 0}, + {19, 0, 5, 0, 5, 0}, + {19, 0, 5, 0, 5, 10}, + {18, 0, 5, 0, 5, 0}, + {4, 27, 14, 0, 5, 0}, + {4, 28, 14, 0, 5, 0}, + {4, 29, 14, 0, 5, 0}, + {4, 33, 14, 0, 5, 0}, + {4, 34, 14, 0, 5, 0}, + {4, 230, 14, 0, 5, 80}, + {4, 220, 14, 0, 5, 80}, + {7, 0, 12, 0, 5, 0}, + {26, 0, 12, 0, 5, 0}, + {4, 35, 14, 0, 5, 0}, + {19, 0, 5, 0, 5, 136}, + {7, 0, 9, 0, 5, 0}, + {30, 0, 5, 0, 5, 0}, + {14, 0, 15, 0, 5, 0}, + {4, 36, 14, 0, 5, 0}, + {4, 0, 14, 0, 5, 0}, + {7, 0, 4, 0, 5, 0}, + {18, 0, 4, 0, 5, 0}, + {26, 0, 19, 0, 5, 0}, + {5, 0, 1, 0, 5, 0}, + {19, 0, 1, 0, 5, 10}, + {4, 7, 14, 0, 5, 80}, + {4, 9, 14, 0, 5, 0}, + {19, 0, 1, 0, 5, 170}, + {7, 0, 1, 0, 5, 0}, + {4, 7, 14, 0, 5, 0}, + {5, 0, 1, 0, 5, 80}, + {5, 0, 1, 0, 5, 10}, + {28, 0, 11, 0, 5, 0}, + {9, 0, 1, 0, 5, 0}, + {4, 0, 14, 0, 5, 80}, + {4, 0, 14, 0, 5, 10}, + {4, 84, 14, 0, 5, 0}, + {4, 91, 14, 0, 5, 80}, + {9, 0, 19, 0, 5, 0}, + {4, 0, 1, 0, 5, 0}, + {4, 9, 14, 0, 5, 80}, + {19, 0, 1, 0, 5, 136}, + {4, 103, 14, 0, 5, 0}, + {4, 107, 14, 0, 5, 0}, + {4, 118, 14, 0, 5, 0}, + {4, 122, 14, 0, 5, 0}, + {26, 0, 1, 0, 5, 136}, + {4, 216, 14, 0, 5, 0}, + {22, 0, 19, 1, 5, 0}, + {23, 0, 19, 1, 5, 0}, + {4, 129, 14, 0, 5, 0}, + {4, 130, 14, 0, 5, 0}, + {4, 0, 14, 0, 5, 170}, + {4, 132, 14, 0, 5, 0}, + {4, 0, 14, 0, 5, 136}, + {19, 0, 1, 0, 2, 0}, + {19, 0, 1, 0, 5, 80}, + {10, 0, 18, 0, 5, 0}, + {8, 0, 1, 0, 5, 0}, + {14, 0, 1, 0, 5, 0}, + {5, 9, 1, 0, 5, 0}, + {4, 234, 14, 0, 5, 0}, + {4, 214, 14, 0, 5, 0}, + {4, 202, 14, 0, 5, 0}, + {2, 0, 1, 0, 5, 138}, + {2, 0, 1, 0, 5, 170}, + {3, 0, 1, 0, 5, 10}, + {1, 0, 1, 0, 5, 170}, + {29, 0, 19, 0, 5, 170}, + {10, 0, 18, 0, 5, 170}, + {10, 0, 18, 0, 5, 136}, + {14, 0, 4, 0, 5, 0}, + {21, 0, 19, 0, 4, 0}, + {21, 0, 19, 0, 5, 136}, + {26, 0, 19, 0, 5, 136}, + {24, 0, 19, 0, 4, 0}, + {25, 0, 19, 0, 4, 0}, + {22, 0, 19, 0, 5, 0}, + {24, 0, 19, 0, 5, 0}, + {26, 0, 19, 0, 4, 136}, + {11, 0, 18, 0, 5, 0}, + {12, 0, 16, 0, 5, 0}, + {14, 0, 2, 0, 5, 0}, + {14, 0, 6, 0, 5, 0}, + {14, 0, 8, 0, 5, 0}, + {14, 0, 3, 0, 5, 0}, + {14, 0, 7, 0, 5, 0}, + {26, 0, 11, 0, 4, 0}, + {26, 0, 11, 0, 4, 136}, + {26, 0, 11, 0, 5, 136}, + {20, 0, 19, 0, 5, 0}, + {27, 0, 13, 0, 5, 0}, + {9, 0, 9, 0, 5, 136}, + {27, 0, 10, 0, 5, 136}, + {27, 0, 19, 0, 5, 136}, + {22, 0, 19, 1, 5, 136}, + {23, 0, 19, 1, 5, 136}, + {28, 0, 11, 0, 5, 136}, + {28, 0, 11, 0, 1, 0}, + {4, 1, 14, 0, 5, 0}, + {30, 0, 19, 0, 5, 136}, + {30, 0, 19, 0, 4, 136}, + {1, 0, 1, 0, 4, 170}, + {30, 0, 11, 0, 5, 0}, + {27, 0, 19, 1, 5, 136}, + {9, 0, 19, 0, 5, 136}, + {8, 0, 1, 0, 4, 136}, + {8, 0, 1, 0, 5, 136}, + {27, 0, 19, 0, 5, 10}, + {30, 0, 19, 0, 5, 10}, + {27, 0, 19, 1, 5, 0}, + {27, 0, 19, 1, 4, 0}, + {27, 0, 19, 1, 5, 10}, + {27, 0, 10, 0, 5, 0}, + {27, 0, 11, 0, 5, 0}, + {27, 0, 19, 1, 4, 136}, + {27, 0, 19, 1, 4, 10}, + {22, 0, 19, 1, 2, 170}, + {23, 0, 19, 1, 2, 170}, + {30, 0, 1, 0, 4, 136}, + {9, 0, 19, 0, 4, 0}, + {27, 0, 19, 1, 5, 170}, + {30, 0, 19, 0, 2, 0}, + {30, 0, 19, 0, 2, 136}, + {10, 0, 18, 0, 0, 136}, + {26, 0, 19, 0, 2, 0}, + {18, 0, 1, 0, 2, 0}, + {8, 0, 1, 0, 2, 0}, + {22, 0, 19, 1, 2, 0}, + {23, 0, 19, 1, 2, 0}, + {21, 0, 19, 0, 2, 0}, + {22, 0, 19, 0, 2, 0}, + {23, 0, 19, 0, 2, 0}, + {4, 218, 14, 0, 2, 0}, + {4, 228, 14, 0, 2, 0}, + {4, 232, 14, 0, 2, 0}, + {4, 222, 14, 0, 2, 0}, + {4, 224, 14, 0, 2, 0}, + {8, 0, 1, 0, 2, 136}, + {19, 0, 1, 0, 2, 10}, + {4, 8, 14, 0, 2, 80}, + {29, 0, 19, 0, 2, 136}, + {18, 0, 1, 0, 2, 10}, + {19, 0, 1, 0, 2, 136}, + {30, 0, 1, 0, 2, 0}, + {9, 0, 1, 0, 2, 136}, + {30, 0, 1, 0, 2, 136}, + {9, 0, 19, 0, 2, 136}, + {29, 0, 1, 0, 5, 0}, + {15, 0, 1, 0, 5, 0}, + {16, 0, 1, 0, 4, 0}, + {19, 0, 1, 0, 2, 170}, + {19, 0, 4, 0, 5, 170}, + {4, 26, 14, 0, 5, 0}, + {19, 0, 4, 0, 5, 136}, + {23, 0, 19, 0, 5, 0}, + {28, 0, 5, 0, 5, 136}, + {26, 0, 19, 0, 2, 136}, + {22, 0, 19, 0, 2, 136}, + {23, 0, 19, 0, 2, 136}, + {21, 0, 19, 0, 2, 136}, + {20, 0, 19, 0, 2, 136}, + {26, 0, 13, 0, 2, 136}, + {22, 0, 19, 1, 2, 136}, + {23, 0, 19, 1, 2, 136}, + {26, 0, 11, 0, 2, 136}, + {27, 0, 10, 0, 2, 136}, + {21, 0, 10, 0, 2, 136}, + {27, 0, 19, 1, 2, 136}, + {27, 0, 19, 0, 2, 136}, + {28, 0, 11, 0, 2, 136}, + {26, 0, 19, 0, 0, 136}, + {26, 0, 11, 0, 0, 136}, + {28, 0, 11, 0, 0, 136}, + {22, 0, 19, 1, 0, 136}, + {23, 0, 19, 1, 0, 136}, + {27, 0, 10, 0, 0, 136}, + {26, 0, 13, 0, 0, 136}, + {21, 0, 10, 0, 0, 136}, + {7, 0, 9, 0, 0, 136}, + {27, 0, 19, 1, 0, 136}, + {27, 0, 19, 0, 0, 136}, + {1, 0, 1, 0, 0, 136}, + {29, 0, 19, 0, 0, 136}, + {20, 0, 19, 0, 0, 136}, + {2, 0, 1, 0, 0, 136}, + {26, 0, 19, 0, 1, 136}, + {22, 0, 19, 1, 1, 136}, + {23, 0, 19, 1, 1, 136}, + {19, 0, 1, 0, 1, 136}, + {18, 0, 1, 0, 1, 136}, + {30, 0, 19, 0, 0, 136}, + {30, 0, 19, 0, 1, 136}, + {27, 0, 19, 0, 1, 136}, + {14, 0, 19, 0, 5, 0}, + {8, 0, 19, 0, 5, 0}, + {9, 0, 4, 0, 5, 0}, + {30, 0, 1, 0, 5, 170}, + {5, 216, 1, 0, 5, 0}, + {5, 226, 1, 0, 5, 0}, + {27, 0, 1, 0, 5, 136}, + {27, 0, 1, 1, 5, 136}, + {7, 0, 9, 0, 5, 136}, }; /* Reindexing of NFC first characters. */ @@ -568,206 +656,514 @@ NULL }; /* index tables for the database records */ -#define SHIFT 8 +#define SHIFT 7 static unsigned char index1[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 53, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 54, 55, 52, 52, 52, 56, - 21, 57, 58, 59, 60, 61, 8, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 62, 63, 63, 63, - 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 52, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 8, 8, 8, 76, 77, 78, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 21, 21, 21, 79, 80, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 81, 82, - 83, 84, 85, 86, 87, 88, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 89, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 90, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 52, 52, 91, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 92, 93, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 94, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 94, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 40, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 16, 50, 51, 52, + 16, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 16, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 98, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 99, 100, 97, 97, 97, 97, 97, 97, + 97, 97, 101, 40, 40, 102, 103, 104, 105, 106, 107, 108, 16, 109, 16, 16, + 16, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 111, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 114, 114, 115, 116, 117, 118, 119, 119, 120, 121, 122, 123, 124, 125, + 126, 127, 128, 129, 16, 130, 131, 132, 133, 134, 16, 16, 16, 16, 16, 16, + 135, 16, 136, 16, 137, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, + 40, 138, 16, 139, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 75, 140, 141, 142, 143, 16, 144, 16, 145, 146, 147, + 148, 149, 150, 151, 152, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 153, 154, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 155, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 114, 114, 114, 114, 156, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 157, 16, 158, 159, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 160, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 160, }; -static unsigned char index2[] = { +static unsigned short index2[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 2, 5, 6, 6, 7, 8, 7, 6, 6, 9, 10, 6, 11, 12, 13, 12, 12, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 12, 6, 15, 16, 15, 6, 6, 17, @@ -776,1273 +1172,1131 @@ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 9, 16, 10, 16, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 22, 8, 8, 23, 8, 24, - 25, 26, 27, 28, 29, 16, 30, 25, 18, 31, 32, 33, 33, 26, 34, 25, 22, 26, - 33, 28, 35, 36, 36, 36, 22, 37, 37, 37, 37, 37, 37, 38, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 38, 37, 37, 37, 37, 37, 37, 39, 38, 37, 37, 37, 37, - 37, 38, 28, 28, 28, 34, 34, 34, 34, 28, 34, 28, 28, 28, 34, 28, 28, 34, - 34, 28, 34, 28, 28, 34, 34, 34, 39, 28, 28, 28, 34, 28, 34, 28, 34, 37, - 28, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 28, 37, - 28, 37, 34, 37, 34, 37, 34, 37, 28, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 38, 28, 37, 34, 37, 28, 37, 34, 37, 34, 37, 28, 38, 28, 37, 34, 37, - 34, 28, 37, 34, 37, 34, 37, 34, 38, 28, 38, 28, 37, 28, 37, 34, 37, 28, - 28, 38, 28, 37, 28, 37, 34, 37, 34, 38, 28, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 38, 28, 37, 34, 37, 28, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 37, 34, 37, 34, 37, 34, - 34, 34, 37, 37, 34, 37, 34, 37, 37, 34, 37, 37, 37, 34, 34, 37, 37, 37, - 37, 34, 37, 37, 34, 37, 37, 37, 34, 34, 34, 37, 37, 34, 37, 37, 34, 37, - 34, 37, 34, 37, 37, 34, 37, 34, 34, 37, 34, 37, 37, 34, 37, 37, 37, 34, - 37, 34, 37, 37, 34, 34, 40, 37, 34, 34, 34, 40, 40, 40, 40, 37, 41, 34, - 37, 41, 34, 37, 41, 34, 37, 28, 37, 28, 37, 28, 37, 28, 37, 28, 37, 28, - 37, 28, 37, 28, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 34, 37, 41, 34, 37, 34, 37, 37, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 34, 34, 34, 34, 34, 34, 37, 37, 34, 37, 37, 34, 34, 37, 34, 37, 37, - 37, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 34, 28, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 28, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 40, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 42, 42, 42, 42, 42, 42, 42, 44, - 44, 26, 44, 43, 45, 43, 45, 45, 45, 43, 45, 43, 43, 46, 42, 44, 44, 44, - 44, 44, 44, 26, 26, 26, 26, 44, 26, 44, 26, 42, 42, 42, 42, 42, 44, 44, - 44, 44, 44, 44, 44, 43, 44, 42, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 49, 49, 49, 49, 48, 50, 49, - 49, 49, 49, 49, 51, 51, 49, 49, 49, 49, 51, 51, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 52, 52, 52, 52, 52, 49, 49, 49, 49, 47, 47, 47, 47, - 47, 47, 47, 47, 53, 47, 49, 49, 49, 47, 47, 47, 49, 49, 54, 47, 47, 47, - 49, 49, 49, 49, 47, 48, 49, 49, 47, 55, 56, 56, 55, 56, 56, 55, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 37, 34, 37, 34, 43, 44, 37, - 34, 0, 0, 42, 34, 34, 34, 57, 0, 0, 0, 0, 0, 44, 44, 37, 57, 37, 37, 37, - 0, 37, 0, 37, 37, 34, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 0, 38, 38, 38, 38, 38, 38, 38, 37, 37, 34, 34, 34, 34, - 34, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 34, 28, 28, 28, 28, 28, 28, 28, 34, 34, 34, 34, 34, 37, 34, 34, 37, 37, - 37, 34, 34, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 34, 34, 34, 34, 37, 34, 58, 37, - 34, 37, 37, 34, 34, 37, 37, 37, 37, 38, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 34, 28, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 59, 60, 60, 60, 60, 60, - 61, 61, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 0, 0, 42, 62, 62, 62, 62, 62, 62, 0, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 0, 62, 63, 0, 0, 0, 0, 0, 0, 64, 60, 60, 60, 60, 64, 60, 60, 60, 65, 64, - 60, 60, 60, 60, 60, 60, 64, 64, 64, 64, 64, 64, 60, 60, 64, 60, 60, 65, - 66, 60, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 82, 60, 64, 82, 75, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 0, 0, 0, 0, 0, 85, 85, 85, 82, 82, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 86, 86, 86, 86, 0, 0, 58, 58, 87, 88, 88, 89, 90, 91, 27, - 27, 60, 60, 60, 60, 60, 60, 60, 60, 92, 93, 94, 91, 0, 0, 91, 91, 0, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 96, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 97, 98, 99, 92, 93, 94, 100, 101, 60, 60, 64, 64, 60, - 60, 60, 60, 60, 64, 60, 60, 0, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 88, 103, 103, 91, 95, 95, 104, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 91, 95, 60, 60, 60, 60, 60, 60, 60, 86, 61, 60, 60, 60, 60, 64, 60, - 96, 96, 60, 60, 27, 64, 60, 60, 64, 95, 95, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 95, 95, 95, 106, 106, 95, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 0, 107, 95, 108, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 60, 64, 60, 60, 64, 60, 60, 64, 64, 64, 60, 64, 64, - 60, 64, 60, 60, 60, 64, 60, 64, 60, 64, 60, 64, 60, 60, 0, 0, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 60, 60, 60, 60, 60, 60, - 60, 64, 60, 111, 111, 27, 57, 57, 57, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 25, 26, 27, 28, 29, 16, 30, 25, 31, 32, 33, 34, 34, 26, 35, 25, 22, 26, + 34, 28, 36, 37, 37, 37, 22, 38, 38, 38, 38, 38, 38, 39, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 39, 38, 38, 38, 38, 38, 38, 40, 39, 38, 38, 38, 38, + 38, 39, 41, 42, 42, 43, 43, 43, 43, 41, 43, 42, 42, 42, 43, 42, 42, 43, + 43, 41, 43, 42, 42, 43, 43, 43, 40, 41, 42, 42, 43, 42, 43, 41, 43, 38, + 42, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 44, 41, 38, + 42, 38, 43, 38, 43, 38, 43, 38, 42, 38, 43, 38, 43, 38, 43, 38, 43, 38, + 43, 39, 41, 38, 43, 38, 42, 38, 43, 38, 43, 38, 41, 45, 28, 38, 43, 38, + 43, 41, 38, 43, 38, 43, 38, 43, 45, 28, 39, 41, 38, 42, 38, 43, 38, 42, + 28, 39, 41, 38, 42, 38, 43, 38, 43, 39, 41, 38, 43, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 39, 41, 38, 43, 38, 42, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 38, 43, 38, 43, 38, 43, + 35, 46, 44, 44, 46, 44, 46, 44, 44, 46, 44, 44, 44, 46, 46, 44, 44, 44, + 44, 46, 44, 44, 46, 44, 44, 44, 46, 46, 46, 44, 44, 46, 44, 38, 43, 44, + 46, 44, 46, 44, 44, 46, 44, 46, 46, 44, 46, 44, 38, 43, 44, 44, 44, 46, + 44, 46, 44, 44, 46, 46, 47, 44, 46, 46, 46, 47, 47, 47, 47, 48, 49, 35, + 48, 49, 35, 48, 49, 35, 38, 42, 38, 42, 38, 42, 38, 42, 38, 42, 38, 42, + 38, 42, 38, 42, 46, 38, 43, 38, 43, 38, 43, 44, 46, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 43, 48, 49, 35, 38, 43, 44, 44, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 44, 46, 38, 43, 44, + 46, 44, 46, 44, 46, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, + 43, 46, 46, 46, 46, 46, 46, 44, 44, 46, 44, 44, 46, 46, 44, 46, 44, 44, + 44, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 46, 41, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 41, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 47, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 52, 52, 52, 52, 52, 52, 52, 53, + 53, 54, 53, 51, 55, 51, 55, 55, 55, 51, 55, 51, 51, 56, 52, 53, 53, 53, + 53, 53, 53, 26, 26, 26, 26, 57, 26, 53, 54, 50, 50, 50, 50, 50, 53, 53, + 53, 53, 53, 53, 53, 51, 53, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 58, 58, 58, 58, 58, 59, 58, 58, 58, 58, 58, + 58, 58, 59, 59, 58, 59, 58, 59, 58, 58, 60, 61, 61, 61, 61, 60, 62, 61, + 61, 61, 61, 61, 63, 63, 64, 64, 64, 64, 65, 65, 61, 61, 61, 61, 64, 64, + 61, 64, 64, 61, 61, 66, 66, 66, 66, 67, 61, 61, 61, 61, 59, 59, 59, 68, + 68, 58, 68, 68, 69, 59, 61, 61, 61, 59, 59, 59, 61, 61, 70, 59, 59, 59, + 61, 61, 61, 61, 59, 60, 61, 61, 59, 71, 72, 72, 71, 72, 72, 71, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 44, 46, 44, 46, 73, 53, 44, + 46, 0, 0, 50, 46, 46, 46, 74, 0, 0, 0, 0, 0, 57, 75, 38, 74, 38, 38, 38, + 0, 38, 0, 38, 38, 43, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 0, 39, 39, 39, 39, 39, 39, 39, 38, 38, 43, 43, 43, 43, + 43, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 46, 41, 41, 41, 41, 41, 41, 41, 43, 43, 43, 43, 43, 44, 35, 35, 48, 76, + 76, 35, 35, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 35, 35, 35, 46, 48, 35, 77, 44, + 46, 48, 44, 46, 46, 44, 44, 44, 38, 78, 44, 38, 44, 44, 44, 38, 44, 44, + 44, 44, 38, 38, 38, 44, 39, 39, 39, 39, 39, 39, 39, 39, 39, 78, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 43, 42, + 46, 43, 46, 46, 46, 43, 46, 46, 46, 46, 43, 43, 43, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 38, 43, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 79, 80, 80, 80, 80, 80, + 81, 81, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 38, 43, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 46, + 38, 43, 38, 43, 44, 46, 38, 43, 44, 46, 38, 43, 38, 43, 38, 43, 44, 46, + 38, 43, 38, 43, 38, 43, 44, 46, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 44, 46, 38, 43, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 0, 0, 52, 82, 82, 82, 82, 82, 82, 0, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 35, + 0, 82, 83, 0, 0, 0, 0, 0, 0, 84, 80, 80, 80, 80, 84, 80, 80, 80, 85, 84, + 80, 80, 80, 80, 80, 80, 84, 84, 84, 84, 84, 84, 80, 80, 84, 80, 80, 85, + 86, 80, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 102, 80, 84, 102, 95, 0, 0, 0, 0, 0, 0, 0, 0, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 0, 0, 0, 0, 0, + 105, 105, 105, 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 106, 106, + 106, 0, 0, 77, 77, 107, 108, 108, 109, 110, 111, 27, 27, 80, 80, 80, 80, + 80, 80, 80, 80, 112, 113, 114, 111, 0, 0, 111, 111, 0, 115, 116, 116, + 116, 116, 116, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 117, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 118, 119, 120, + 112, 113, 114, 121, 122, 123, 123, 124, 84, 80, 80, 80, 80, 80, 84, 80, + 80, 0, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 108, 126, 126, + 111, 115, 115, 127, 115, 115, 115, 115, 128, 128, 128, 128, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 116, + 115, 116, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 116, 111, 115, 80, 80, 80, 80, 80, 80, 80, 106, 81, + 80, 80, 80, 80, 84, 80, 117, 117, 80, 80, 27, 84, 80, 80, 84, 115, 115, + 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 115, 115, 115, 130, + 130, 115, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 0, 131, 115, 132, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 80, 84, 80, 80, 84, 80, 80, 84, 84, + 84, 80, 84, 84, 80, 84, 80, 80, 80, 84, 80, 84, 80, 84, 80, 84, 80, 80, + 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 133, 133, 133, 133, 133, 133, 133, 133, + 133, 133, 133, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 134, + 134, 134, 134, 134, 134, 134, 134, 134, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 80, 80, + 80, 80, 80, 80, 80, 84, 80, 135, 135, 27, 136, 136, 136, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 109, 112, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 113, 40, 112, - 112, 112, 109, 109, 109, 109, 109, 109, 109, 109, 112, 112, 112, 112, - 114, 0, 0, 40, 60, 64, 60, 60, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 109, 109, 62, 62, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 115, 62, 42, 40, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 0, 109, 112, - 112, 0, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 40, 40, 0, 0, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 0, 0, 0, 40, 40, 40, 40, 0, 0, - 113, 40, 112, 112, 112, 109, 109, 109, 109, 0, 0, 112, 112, 0, 0, 112, - 112, 114, 40, 0, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 0, 40, 40, 0, 40, 40, - 40, 109, 109, 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 40, - 40, 116, 116, 117, 117, 117, 117, 117, 117, 59, 0, 0, 0, 0, 0, 0, 109, - 109, 112, 0, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 40, 40, 0, 0, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 0, 40, 40, 0, 40, 40, - 0, 0, 113, 0, 112, 112, 112, 109, 109, 0, 0, 0, 0, 109, 109, 0, 0, 109, - 109, 114, 0, 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 0, 40, 0, 0, - 0, 0, 0, 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 109, - 109, 40, 40, 40, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 109, 112, 0, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 0, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, - 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 0, 40, 40, 40, 40, 40, 0, 0, 113, - 40, 112, 112, 112, 109, 109, 109, 109, 109, 0, 109, 109, 112, 0, 112, - 112, 114, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, - 109, 109, 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 116, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 112, 112, 0, 40, 40, - 40, 40, 40, 40, 40, 40, 0, 0, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, - 40, 40, 40, 40, 40, 0, 40, 40, 0, 40, 40, 40, 40, 40, 0, 0, 113, 40, 112, - 109, 112, 109, 109, 109, 109, 0, 0, 112, 112, 0, 0, 112, 112, 114, 0, 0, - 0, 0, 0, 0, 0, 0, 109, 112, 0, 0, 0, 0, 40, 40, 0, 40, 40, 40, 109, 109, - 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 59, 40, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 40, 0, 40, 40, 40, 40, 40, - 40, 0, 0, 0, 40, 40, 40, 0, 40, 40, 40, 40, 0, 0, 0, 40, 40, 0, 40, 0, - 40, 40, 0, 0, 0, 40, 40, 0, 0, 0, 40, 40, 40, 0, 0, 0, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 112, 112, 109, 112, 112, 0, - 0, 0, 112, 112, 112, 0, 112, 112, 112, 114, 0, 0, 40, 0, 0, 0, 0, 0, 0, - 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 115, 117, 117, 117, 27, 27, 27, 27, 27, 27, 116, 27, - 0, 0, 0, 0, 0, 0, 112, 112, 112, 0, 40, 40, 40, 40, 40, 40, 40, 40, 0, - 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 0, 40, 40, 40, 40, 40, 0, 0, 0, 40, 109, 109, 109, 112, 112, 112, - 112, 0, 109, 109, 109, 0, 109, 109, 109, 114, 0, 0, 0, 0, 0, 0, 0, 118, - 119, 0, 40, 40, 0, 0, 0, 0, 0, 0, 40, 40, 109, 109, 0, 0, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 0, 0, 0, 0, 0, 0, 0, 0, 120, 120, 120, - 120, 120, 120, 120, 59, 0, 0, 112, 112, 0, 40, 40, 40, 40, 40, 40, 40, - 40, 0, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 0, 40, 40, 40, 40, 40, 0, 0, 113, 40, 112, 121, 112, 112, - 112, 112, 112, 0, 121, 112, 112, 0, 112, 112, 109, 114, 0, 0, 0, 0, 0, 0, - 0, 112, 112, 0, 0, 0, 0, 0, 0, 0, 40, 0, 40, 40, 109, 109, 0, 0, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 27, 27, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 112, 0, 40, 40, 40, 40, 40, 40, 40, 40, - 0, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 40, 112, 112, 112, 109, 109, - 109, 109, 0, 112, 112, 112, 0, 112, 112, 112, 114, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 109, 109, 0, 0, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 117, 117, 117, 117, 117, 117, 0, 0, 0, - 59, 40, 40, 40, 40, 40, 40, 0, 0, 112, 112, 0, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 0, 0, 40, 40, 40, - 40, 40, 40, 40, 0, 0, 0, 114, 0, 0, 0, 0, 112, 112, 112, 109, 109, 109, - 0, 109, 0, 112, 112, 112, 112, 112, 112, 112, 112, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 112, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 109, 40, 40, 109, - 109, 109, 109, 122, 122, 114, 0, 0, 0, 0, 116, 40, 40, 40, 40, 40, 40, - 42, 109, 123, 123, 123, 123, 109, 109, 109, 62, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 115, 62, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 40, 40, 0, 40, 0, 0, 40, 40, 0, 40, 0, 0, 40, 0, 0, 0, 0, 0, 0, 40, 40, - 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 0, 40, 0, 40, 0, 0, - 40, 40, 0, 40, 40, 40, 40, 109, 40, 40, 109, 109, 109, 109, 124, 124, 0, - 109, 109, 40, 0, 0, 40, 40, 40, 40, 40, 0, 42, 0, 125, 125, 125, 125, - 109, 109, 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 0, - 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 59, 59, 59, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 59, 59, 59, 59, 59, 64, 64, 59, - 59, 59, 59, 59, 59, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 59, 64, 59, 64, 59, - 126, 127, 128, 127, 128, 112, 112, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, - 0, 0, 129, 130, 109, 131, 109, 109, 109, 109, 109, 130, 130, 130, 130, - 109, 112, 130, 109, 60, 60, 114, 62, 60, 60, 40, 40, 40, 40, 0, 0, 0, 0, - 109, 109, 109, 109, 109, 109, 109, 109, 0, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 0, 59, 59, 59, 59, 59, 59, 59, 59, 64, 59, 59, 59, 59, 59, 59, - 0, 59, 59, 62, 62, 62, 62, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 112, 112, 109, 109, 109, 109, - 112, 109, 109, 109, 109, 109, 113, 112, 114, 114, 112, 112, 109, 109, 40, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 62, 62, 62, 62, 62, 62, - 40, 40, 40, 40, 40, 40, 112, 112, 109, 109, 40, 40, 40, 40, 109, 109, - 109, 40, 112, 112, 112, 40, 40, 112, 112, 112, 112, 112, 112, 112, 40, - 40, 40, 109, 109, 109, 109, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 109, 112, 112, 109, 109, 112, 112, 112, 112, 112, 112, 64, 40, - 112, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 0, 0, 0, 59, - 59, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 62, - 42, 0, 0, 0, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, 0, 0, 0, 132, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 0, 0, 40, - 40, 40, 40, 40, 40, 40, 0, 40, 0, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 0, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 0, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, 0, - 40, 0, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 60, 59, 62, 62, 62, 62, - 62, 62, 62, 62, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 117, 0, 0, 0, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 62, 62, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 133, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 127, 128, 0, 0, 0, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 62, - 62, 62, 134, 134, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 109, - 109, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 109, 109, 114, 62, 62, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 109, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 0, 109, 109, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 135, 135, 112, 109, 109, 109, 109, 109, 109, - 109, 112, 112, 112, 112, 112, 112, 112, 112, 109, 112, 112, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 114, 109, 62, 62, 62, 42, 62, 62, 62, - 116, 40, 60, 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, - 0, 0, 0, 0, 0, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 0, 0, 0, - 0, 0, 0, 57, 57, 57, 57, 57, 57, 63, 57, 57, 57, 57, 109, 109, 109, 133, - 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 0, 0, 0, 0, 0, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 42, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, - 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 66, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 109, 109, - 109, 112, 112, 112, 112, 109, 109, 112, 112, 112, 0, 0, 0, 0, 112, 112, - 109, 112, 112, 112, 112, 112, 112, 65, 60, 64, 0, 0, 0, 0, 27, 0, 0, 0, - 57, 57, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 40, - 40, 40, 40, 40, 40, 40, 112, 112, 0, 0, 0, 0, 0, 0, 115, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 0, 0, 0, 0, 57, 57, 27, 27, 27, 27, 27, 27, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 133, 137, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 138, 47, 47, 47, 47, 47, + 47, 47, 138, 47, 47, 138, 47, 47, 47, 47, 47, 0, 0, 139, 47, 137, 137, + 137, 133, 133, 133, 133, 133, 133, 133, 133, 137, 137, 137, 137, 140, 0, + 0, 47, 80, 84, 80, 80, 0, 0, 0, 141, 141, 141, 141, 141, 141, 141, 141, + 47, 47, 133, 133, 82, 82, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 82, 52, 47, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 0, 133, 137, + 137, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 0, 0, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 0, 0, 47, 47, 47, 47, 0, 0, + 143, 47, 144, 137, 137, 133, 133, 133, 133, 0, 0, 137, 137, 0, 0, 145, + 145, 140, 47, 0, 0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 141, 141, 0, 141, + 47, 47, 133, 133, 0, 0, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 47, 47, 146, 146, 147, 147, 147, 147, 147, 147, 79, 0, 0, 0, 0, 0, 0, + 133, 133, 137, 0, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 47, 47, 0, 0, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 141, 0, 47, 141, 0, 47, + 47, 0, 0, 143, 0, 137, 137, 137, 133, 133, 0, 0, 0, 0, 133, 133, 0, 0, + 133, 133, 140, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0, 141, 141, 141, 47, 0, + 141, 0, 0, 0, 0, 0, 0, 0, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 133, 133, 47, 47, 47, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, + 133, 137, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 0, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 0, 47, 47, 47, 47, + 47, 0, 0, 143, 47, 137, 137, 137, 133, 133, 133, 133, 133, 0, 133, 133, + 137, 0, 137, 137, 140, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 47, 47, 133, 133, 0, 0, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 137, + 137, 0, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 47, 47, 0, 0, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 0, 47, 47, 47, 47, 47, 0, + 0, 143, 47, 144, 133, 137, 133, 133, 133, 133, 0, 0, 137, 145, 0, 0, 145, + 145, 140, 0, 0, 0, 0, 0, 0, 0, 0, 148, 144, 0, 0, 0, 0, 141, 141, 0, 47, + 47, 47, 133, 133, 0, 0, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 79, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 47, 0, 47, + 47, 47, 47, 47, 47, 0, 0, 0, 47, 47, 47, 0, 47, 47, 138, 47, 0, 0, 0, 47, + 47, 0, 47, 0, 47, 47, 0, 0, 0, 47, 47, 0, 0, 0, 47, 47, 47, 0, 0, 0, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 144, 137, 133, + 137, 137, 0, 0, 0, 137, 137, 137, 0, 145, 145, 145, 140, 0, 0, 47, 0, 0, + 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 147, 147, 147, 27, 27, 27, 27, 27, 27, + 146, 27, 0, 0, 0, 0, 0, 0, 137, 137, 137, 0, 47, 47, 47, 47, 47, 47, 47, + 47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 0, 47, 47, 47, 47, 47, 0, 0, 0, 47, 133, 133, 133, 137, 137, + 137, 137, 0, 133, 133, 149, 0, 133, 133, 133, 140, 0, 0, 0, 0, 0, 0, 0, + 150, 151, 0, 47, 47, 0, 0, 0, 0, 0, 0, 47, 47, 133, 133, 0, 0, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 0, 0, 0, 0, 0, 0, 0, 0, 152, 152, + 152, 152, 152, 152, 152, 79, 0, 0, 137, 137, 0, 47, 47, 47, 47, 47, 47, + 47, 47, 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 0, 0, 143, 47, 137, 153, 145, 137, + 144, 137, 137, 0, 153, 145, 145, 0, 145, 145, 133, 140, 0, 0, 0, 0, 0, 0, + 0, 144, 144, 0, 0, 0, 0, 0, 0, 0, 47, 0, 47, 47, 133, 133, 0, 0, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 0, 27, 27, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 137, 137, 0, 47, 47, 47, 47, 47, 47, 47, 47, + 0, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 47, 144, 137, 137, 133, 133, + 133, 133, 0, 137, 137, 137, 0, 145, 145, 145, 140, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 133, 133, 0, 0, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 147, 147, 147, 147, 147, 147, 0, 0, 0, + 79, 47, 47, 47, 47, 47, 47, 0, 0, 137, 137, 0, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 0, 47, 47, 47, + 47, 47, 47, 47, 0, 0, 0, 154, 0, 0, 0, 0, 144, 137, 137, 133, 133, 133, + 0, 133, 0, 137, 137, 145, 137, 145, 145, 145, 144, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 137, 137, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 133, 47, 155, + 133, 133, 133, 133, 156, 156, 140, 0, 0, 0, 0, 146, 47, 47, 47, 47, 47, + 47, 52, 133, 157, 157, 157, 157, 133, 133, 133, 82, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 82, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 47, 47, 0, 47, 0, 0, 47, 47, 0, 47, 0, 0, 47, 0, 0, 0, 0, 0, 0, 47, + 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 0, 47, 0, 47, + 0, 0, 47, 47, 0, 47, 47, 47, 47, 133, 47, 155, 133, 133, 133, 133, 158, + 158, 0, 133, 133, 47, 0, 0, 47, 47, 47, 47, 47, 0, 52, 0, 159, 159, 159, + 159, 133, 133, 0, 0, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 0, + 0, 155, 155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 79, 79, 79, 82, 82, 82, 82, + 82, 82, 82, 82, 160, 82, 82, 82, 82, 82, 82, 79, 79, 79, 79, 79, 84, 84, + 79, 79, 79, 79, 79, 79, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 79, 84, 79, 84, 79, + 161, 162, 163, 162, 163, 137, 137, 47, 47, 47, 141, 47, 47, 47, 47, 0, + 47, 47, 47, 47, 141, 47, 47, 47, 47, 141, 47, 47, 47, 47, 141, 47, 47, + 47, 47, 141, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 141, 47, 47, + 47, 0, 0, 0, 0, 164, 165, 166, 167, 166, 166, 168, 166, 168, 165, 165, + 165, 165, 133, 137, 165, 166, 80, 80, 140, 82, 80, 80, 47, 47, 47, 47, 0, + 0, 0, 0, 133, 133, 133, 166, 133, 133, 133, 133, 0, 133, 133, 133, 133, + 166, 133, 133, 133, 133, 166, 133, 133, 133, 133, 166, 133, 133, 133, + 133, 166, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, + 166, 133, 133, 133, 0, 79, 79, 79, 79, 79, 79, 79, 79, 84, 79, 79, 79, + 79, 79, 79, 0, 79, 79, 82, 82, 82, 82, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 138, 47, 47, 47, 47, 137, 137, 133, + 148, 133, 133, 137, 133, 133, 133, 133, 133, 143, 137, 140, 140, 137, + 137, 133, 133, 47, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 82, + 82, 82, 82, 82, 82, 47, 47, 47, 47, 47, 47, 137, 137, 133, 133, 47, 47, + 47, 47, 133, 133, 133, 47, 137, 137, 137, 47, 47, 137, 137, 137, 137, + 137, 137, 137, 47, 47, 47, 133, 133, 133, 133, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 133, 137, 137, 133, 133, 137, 137, 137, 137, + 137, 137, 84, 47, 137, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 0, 0, 0, 0, 79, 79, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 82, 50, 0, 0, 0, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 0, 0, 0, 0, 0, + 169, 47, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 0, 0, 0, 0, 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, + 47, 47, 47, 0, 47, 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, + 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 47, + 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 80, 79, 82, 82, 82, 82, 82, 82, 82, + 82, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 82, 82, 47, 47, 47, 47, 47, + 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 162, 163, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 82, 82, 82, 172, 172, 172, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 0, 47, 47, 47, 47, 133, 133, 140, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 133, 133, 140, 82, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 133, 133, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 0, 47, 47, 47, 0, 133, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 173, 173, + 137, 133, 133, 133, 133, 133, 133, 133, 137, 137, 137, 137, 137, 137, + 137, 137, 133, 137, 137, 133, 133, 133, 133, 133, 133, 133, 133, 133, + 140, 133, 82, 82, 82, 52, 82, 82, 82, 146, 47, 80, 0, 0, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 0, 0, 0, 0, 0, 0, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 0, 0, 0, 0, 0, 0, 136, 136, 136, 136, 136, + 136, 83, 136, 136, 136, 136, 133, 133, 133, 171, 0, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 52, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 86, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 133, 133, 133, 137, 137, 137, 137, + 133, 133, 137, 137, 137, 0, 0, 0, 0, 137, 137, 133, 137, 137, 137, 137, + 137, 137, 85, 80, 84, 0, 0, 0, 0, 27, 0, 0, 0, 136, 136, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 0, 0, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 47, 47, 47, 47, + 47, 47, 47, 137, 137, 0, 0, 0, 0, 0, 0, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 0, 0, 0, 0, 136, 136, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 60, 64, 112, 112, - 112, 0, 0, 62, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 109, 109, 109, 112, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 113, 112, 109, 109, 109, 109, - 109, 112, 109, 112, 112, 112, 112, 112, 109, 112, 136, 40, 40, 40, 40, - 40, 40, 40, 0, 0, 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 62, 62, 62, 62, 62, 62, 62, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 60, - 64, 60, 60, 60, 60, 60, 60, 60, 59, 59, 59, 59, 59, 59, 59, 59, 59, 0, 0, - 0, 109, 109, 112, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 112, 109, - 109, 109, 109, 112, 112, 109, 109, 136, 0, 0, 0, 40, 40, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 112, 112, 112, 112, 112, 112, 112, 112, 109, - 109, 109, 109, 109, 109, 109, 109, 112, 112, 109, 113, 0, 0, 0, 62, 62, - 62, 62, 62, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 0, 0, - 40, 40, 40, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 42, 42, 42, 42, 42, 42, 62, 62, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 42, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 60, 60, - 64, 60, 60, 60, 60, 60, 60, 60, 64, 60, 60, 137, 138, 64, 139, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 60, 64, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, - 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 0, 0, 37, 37, 37, 37, 37, 37, - 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 34, - 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, - 34, 34, 34, 0, 0, 37, 37, 37, 37, 37, 37, 0, 0, 34, 34, 34, 34, 34, 34, - 34, 34, 0, 37, 0, 37, 0, 37, 0, 37, 34, 34, 34, 34, 34, 34, 34, 34, 37, - 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 41, 41, 41, 41, 41, 41, - 41, 41, 34, 34, 34, 34, 34, 34, 34, 34, 41, 41, 41, 41, 41, 41, 41, 41, - 34, 34, 34, 34, 34, 34, 34, 34, 41, 41, 41, 41, 41, 41, 41, 41, 34, 34, - 34, 34, 34, 0, 34, 34, 37, 37, 37, 37, 41, 44, 34, 44, 44, 44, 34, 34, - 34, 0, 34, 34, 37, 37, 37, 37, 41, 44, 44, 44, 34, 34, 34, 34, 0, 0, 34, - 34, 37, 37, 37, 37, 0, 44, 44, 44, 34, 34, 34, 34, 34, 34, 34, 34, 37, - 37, 37, 37, 37, 44, 44, 44, 0, 0, 34, 34, 34, 0, 34, 34, 37, 37, 37, 37, - 41, 44, 44, 0, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, - 107, 107, 107, 135, 140, 141, 63, 63, 141, 141, 141, 22, 57, 142, 143, - 144, 145, 142, 143, 144, 145, 22, 22, 22, 57, 22, 22, 22, 22, 146, 147, - 148, 149, 150, 151, 152, 21, 153, 88, 153, 153, 88, 22, 57, 57, 57, 29, - 35, 22, 57, 57, 22, 154, 154, 57, 57, 57, 155, 127, 128, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 58, 57, 154, 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 133, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 107, 107, 107, 107, - 107, 107, 156, 34, 0, 0, 33, 156, 156, 156, 156, 156, 157, 157, 58, 127, - 128, 28, 156, 33, 33, 33, 33, 156, 156, 156, 156, 156, 157, 157, 58, 127, - 128, 0, 42, 42, 42, 42, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 158, 116, 116, 23, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 60, 159, 159, 60, 60, 60, 60, 159, 159, - 159, 60, 60, 61, 61, 61, 61, 60, 61, 61, 61, 159, 159, 60, 64, 60, 159, - 159, 64, 64, 64, 64, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, - 27, 37, 25, 27, 25, 27, 37, 27, 25, 34, 37, 37, 37, 34, 34, 37, 37, 37, - 28, 27, 37, 25, 27, 27, 37, 37, 37, 37, 37, 27, 27, 27, 25, 25, 27, 37, - 27, 38, 27, 37, 27, 37, 38, 37, 37, 160, 34, 37, 37, 37, 37, 34, 40, 40, - 40, 40, 34, 27, 27, 34, 34, 37, 37, 161, 58, 58, 58, 58, 37, 34, 34, 34, - 34, 27, 58, 27, 27, 34, 59, 0, 0, 0, 36, 36, 120, 120, 120, 120, 120, - 120, 36, 36, 36, 36, 120, 162, 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 134, 134, 134, 134, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 134, 134, 134, 134, 134, 134, 134, 134, 134, 37, 34, 134, - 134, 134, 134, 0, 0, 0, 0, 0, 0, 0, 39, 39, 39, 39, 39, 25, 25, 25, 25, - 25, 58, 58, 27, 27, 27, 27, 58, 27, 27, 58, 27, 27, 58, 27, 27, 27, 27, - 27, 27, 27, 58, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 58, - 58, 27, 27, 39, 27, 39, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 80, 84, 137, 137, 137, 0, 0, + 82, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 133, 133, 133, 133, 137, 47, 138, 47, 138, 47, 138, 47, 138, 47, + 138, 47, 47, 47, 138, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 143, 144, 133, 133, 133, 133, 133, 145, 133, 145, 137, 137, 145, + 145, 133, 145, 174, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 82, 82, 82, 82, 82, 82, 82, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 80, 84, 80, 80, 80, 80, 80, 80, 80, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, 0, 133, 133, 137, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 137, 133, 133, 133, 133, 137, 137, + 133, 133, 174, 0, 0, 0, 47, 47, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 137, 137, 137, 137, 137, 137, 137, 137, 133, 133, 133, 133, 133, 133, + 133, 133, 137, 137, 133, 143, 0, 0, 0, 82, 82, 82, 82, 82, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 0, 0, 0, 47, 47, 47, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 52, 52, 52, 52, 52, 52, 82, 82, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 50, 50, 50, 52, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 52, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 52, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 35, 35, 35, 35, 35, 35, 35, 35, 35, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 50, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 80, 80, 84, 80, 80, 80, 80, 80, 80, 80, 84, 80, 80, + 175, 176, 84, 177, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 84, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 43, 43, + 43, 43, 35, 178, 46, 46, 44, 46, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, + 38, 43, 38, 43, 38, 43, 38, 43, 44, 46, 44, 46, 44, 46, 43, 43, 43, 43, + 43, 43, 43, 43, 38, 38, 38, 38, 38, 38, 38, 38, 43, 43, 43, 43, 43, 43, + 0, 0, 38, 38, 38, 38, 38, 38, 0, 0, 43, 43, 43, 43, 43, 43, 43, 43, 38, + 38, 38, 38, 38, 38, 38, 38, 43, 43, 43, 43, 43, 43, 43, 43, 38, 38, 38, + 38, 38, 38, 38, 38, 43, 43, 43, 43, 43, 43, 0, 0, 38, 38, 38, 38, 38, 38, + 0, 0, 43, 43, 43, 43, 43, 43, 43, 43, 0, 38, 0, 38, 0, 38, 0, 38, 43, 43, + 43, 43, 43, 43, 43, 43, 38, 38, 38, 38, 38, 38, 38, 38, 43, 179, 43, 179, + 43, 179, 43, 179, 43, 179, 43, 179, 43, 179, 0, 0, 43, 43, 43, 43, 43, + 43, 43, 43, 180, 180, 180, 180, 180, 180, 180, 180, 43, 43, 43, 43, 43, + 43, 43, 43, 180, 180, 180, 180, 180, 180, 180, 180, 43, 43, 43, 43, 43, + 43, 43, 43, 180, 180, 180, 180, 180, 180, 180, 180, 43, 43, 43, 43, 43, + 0, 43, 43, 38, 38, 38, 181, 180, 57, 179, 57, 57, 75, 43, 43, 43, 0, 43, + 43, 38, 181, 38, 181, 180, 75, 75, 75, 43, 43, 43, 179, 0, 0, 43, 43, 38, + 38, 38, 181, 0, 75, 75, 75, 43, 43, 43, 179, 43, 43, 43, 43, 38, 38, 38, + 181, 38, 75, 182, 182, 0, 0, 43, 43, 43, 0, 43, 43, 38, 181, 38, 181, + 180, 182, 57, 0, 183, 183, 184, 184, 184, 184, 184, 184, 184, 184, 184, + 131, 131, 131, 173, 185, 186, 187, 83, 186, 186, 186, 22, 188, 189, 190, + 191, 192, 189, 190, 191, 192, 22, 22, 22, 136, 193, 193, 193, 22, 194, + 195, 196, 197, 198, 199, 200, 21, 201, 108, 201, 202, 203, 22, 188, 188, + 136, 29, 36, 22, 188, 136, 193, 204, 204, 136, 136, 136, 205, 162, 163, + 188, 188, 188, 136, 136, 136, 136, 136, 136, 136, 136, 77, 136, 204, 136, + 136, 188, 136, 136, 136, 136, 136, 136, 136, 184, 131, 131, 131, 131, + 131, 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, 131, 206, 35, 0, 0, 34, 206, + 206, 206, 206, 206, 207, 207, 208, 209, 210, 28, 206, 34, 34, 34, 34, + 206, 206, 206, 206, 206, 207, 207, 208, 209, 210, 0, 50, 50, 50, 50, 50, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, + 211, 212, 146, 146, 23, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 80, 80, 213, 213, 80, 80, 80, 80, 213, 213, 213, 80, 80, 81, 81, 81, + 81, 80, 81, 81, 81, 213, 213, 80, 84, 80, 213, 213, 84, 84, 84, 84, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 214, 214, 48, 215, 27, 215, + 214, 48, 27, 215, 35, 48, 48, 48, 35, 35, 48, 48, 48, 28, 27, 48, 215, + 27, 27, 48, 48, 48, 48, 48, 27, 27, 214, 215, 215, 27, 48, 27, 216, 27, + 48, 27, 181, 216, 48, 48, 217, 35, 48, 48, 44, 48, 35, 155, 155, 155, + 155, 35, 27, 214, 35, 35, 48, 48, 218, 77, 77, 77, 77, 48, 35, 35, 35, + 35, 27, 77, 27, 27, 46, 79, 0, 0, 0, 37, 37, 219, 219, 219, 219, 219, + 219, 37, 37, 37, 37, 219, 220, 220, 220, 220, 220, 220, 220, 220, 220, + 220, 220, 220, 221, 221, 221, 221, 220, 220, 220, 220, 220, 220, 220, + 220, 220, 220, 221, 221, 221, 221, 221, 221, 172, 172, 172, 44, 46, 172, + 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 25, 25, 25, 25, + 25, 222, 222, 27, 27, 27, 27, 77, 27, 27, 77, 27, 27, 77, 27, 27, 27, 27, + 27, 27, 27, 222, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 223, 222, + 222, 27, 27, 40, 27, 40, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 39, 161, 163, 163, - 161, 58, 58, 39, 163, 161, 161, 163, 161, 161, 58, 39, 58, 163, 157, 164, - 58, 163, 161, 58, 58, 58, 163, 161, 161, 163, 39, 163, 163, 161, 161, 39, - 161, 39, 161, 39, 39, 39, 39, 163, 163, 161, 163, 161, 161, 161, 161, - 161, 39, 39, 39, 39, 58, 161, 58, 161, 163, 163, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 163, 161, 161, 161, 163, 58, 58, 58, 58, 58, - 163, 161, 161, 161, 58, 58, 58, 58, 58, 58, 58, 58, 58, 161, 163, 39, - 161, 58, 163, 163, 163, 163, 161, 161, 163, 163, 58, 58, 163, 163, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 163, 163, 161, 161, 163, 163, 161, 161, 161, 161, 161, 58, - 58, 161, 161, 161, 161, 58, 58, 39, 58, 58, 161, 39, 58, 58, 58, 58, 58, - 58, 58, 58, 161, 161, 58, 39, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 58, 58, 58, 58, - 58, 161, 163, 58, 58, 58, 58, 58, 58, 58, 58, 58, 161, 161, 161, 161, - 161, 58, 58, 161, 161, 58, 58, 58, 58, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 58, 58, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 27, 27, 27, 27, 27, 27, 27, 27, 161, 161, - 161, 161, 27, 27, 27, 27, 27, 27, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 161, 161, 27, 27, 27, 27, 27, 27, 27, 165, 166, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 27, 58, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 59, 27, 27, 27, - 27, 27, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 40, 224, 225, 225, + 226, 77, 77, 40, 225, 226, 224, 225, 226, 224, 77, 40, 77, 225, 227, 228, + 77, 225, 224, 77, 77, 77, 225, 224, 224, 225, 40, 225, 225, 224, 224, 40, + 226, 40, 226, 40, 40, 40, 40, 225, 229, 218, 225, 218, 218, 224, 224, + 224, 40, 40, 40, 40, 77, 224, 77, 224, 225, 225, 224, 224, 224, 226, 224, + 224, 226, 224, 224, 226, 225, 226, 224, 224, 225, 77, 77, 77, 77, 77, + 225, 224, 224, 224, 77, 77, 77, 77, 77, 77, 77, 77, 77, 224, 230, 40, + 226, 77, 225, 225, 225, 225, 224, 224, 225, 225, 77, 222, 230, 230, 226, + 226, 224, 224, 226, 226, 224, 224, 226, 226, 224, 224, 224, 224, 224, + 224, 226, 226, 225, 225, 226, 226, 225, 225, 226, 226, 224, 224, 224, 77, + 77, 224, 224, 224, 224, 77, 77, 40, 77, 77, 224, 40, 77, 77, 77, 77, 77, + 77, 77, 77, 224, 224, 77, 40, 224, 224, 224, 224, 224, 224, 226, 226, + 226, 226, 224, 224, 224, 224, 224, 224, 224, 224, 224, 77, 77, 77, 77, + 77, 224, 225, 77, 77, 77, 77, 77, 77, 77, 77, 77, 224, 224, 224, 224, + 224, 77, 77, 224, 224, 77, 77, 77, 77, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 226, 226, 226, 226, 224, 224, 224, 224, 224, 224, 226, + 226, 226, 226, 77, 77, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 27, 27, 27, 27, 27, 27, 27, 27, 224, 224, + 224, 224, 27, 27, 27, 27, 27, 27, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 224, 224, 27, 27, 27, 27, 27, 27, 27, 231, 232, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 27, 77, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 79, 27, 27, 27, + 27, 27, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 58, 58, 58, 58, 58, - 58, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 77, 77, 77, 77, 77, + 77, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 167, 167, 167, 167, 167, 167, 167, 167, 167, - 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, - 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, - 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, - 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, - 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 120, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 0, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 219, + 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, + 234, 234, 234, 234, 234, 234, 234, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 27, 27, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 25, 25, 27, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, - 25, 25, 27, 27, 25, 39, 27, 27, 27, 27, 25, 25, 27, 27, 25, 39, 27, 27, - 27, 27, 25, 25, 25, 27, 27, 25, 27, 27, 25, 25, 25, 25, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25, 25, 25, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 25, 27, 27, 27, 27, 27, 27, 27, 27, 58, 58, - 58, 58, 58, 58, 58, 58, 27, 27, 27, 27, 27, 25, 25, 27, 27, 25, 27, 27, - 27, 27, 25, 25, 27, 27, 27, 27, 25, 25, 27, 27, 27, 27, 27, 27, 25, 27, - 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 27, - 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25, 27, 25, 25, 25, - 27, 25, 25, 25, 25, 27, 25, 25, 27, 39, 27, 27, 27, 27, 27, 27, 27, 27, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 27, 27, 25, 25, 25, 25, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 25, 25, 27, 25, 25, 25, 25, 25, 25, 25, 27, + 27, 27, 27, 27, 27, 27, 27, 25, 25, 27, 27, 25, 40, 27, 27, 27, 27, 25, + 25, 27, 27, 25, 40, 27, 27, 27, 27, 25, 25, 25, 27, 27, 25, 27, 27, 25, + 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 27, 27, 27, + 27, 27, 27, 27, 27, 77, 77, 77, 77, 77, 77, 77, 77, 27, 27, 27, 27, 27, + 25, 25, 27, 27, 25, 27, 27, 27, 27, 25, 25, 27, 27, 27, 27, 25, 25, 27, + 27, 27, 27, 27, 27, 25, 27, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 25, 27, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 59, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 27, 27, - 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 0, 27, 27, - 27, 27, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 25, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 27, 0, 27, 27, 27, - 27, 0, 0, 0, 27, 0, 27, 27, 27, 27, 27, 27, 27, 0, 0, 27, 27, 27, 27, 27, - 27, 27, 127, 128, 127, 128, 127, 128, 127, 128, 127, 128, 127, 128, 127, - 128, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 27, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 0, 161, 58, 58, 161, 161, 127, 128, 58, 161, - 161, 58, 0, 161, 0, 0, 0, 58, 58, 58, 161, 161, 161, 161, 58, 58, 58, 58, - 58, 161, 161, 161, 58, 58, 58, 161, 161, 161, 161, 9, 10, 9, 10, 9, 10, - 9, 10, 127, 128, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 127, 128, 9, 10, 127, 128, - 127, 128, 127, 128, 127, 128, 127, 128, 127, 128, 127, 128, 127, 128, - 127, 128, 58, 58, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 58, 58, 58, 58, 58, 58, - 58, 58, 161, 58, 58, 58, 58, 58, 58, 58, 161, 161, 161, 161, 161, 161, - 58, 58, 58, 161, 58, 58, 58, 58, 161, 161, 161, 161, 161, 58, 161, 161, - 58, 58, 127, 128, 127, 128, 161, 58, 58, 58, 58, 161, 58, 161, 161, 161, - 58, 58, 161, 161, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 161, 161, 161, - 161, 161, 161, 58, 58, 127, 128, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 58, 161, 161, 161, 161, 58, 58, 161, 58, - 161, 58, 58, 161, 58, 161, 161, 161, 161, 58, 58, 58, 58, 58, 161, 161, - 58, 58, 58, 58, 58, 58, 161, 161, 161, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 161, 161, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 161, 161, 58, 58, 58, 58, - 161, 161, 161, 161, 58, 161, 161, 58, 58, 161, 161, 58, 58, 58, 58, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 58, - 58, 161, 161, 161, 161, 161, 161, 161, 161, 58, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 161, 58, 58, 58, 58, 58, 161, 58, 161, 58, - 58, 58, 161, 161, 161, 161, 161, 58, 58, 58, 58, 58, 161, 161, 161, 58, - 58, 58, 58, 161, 58, 58, 58, 161, 161, 161, 161, 161, 58, 161, 58, 58, + 27, 25, 25, 27, 25, 25, 25, 27, 25, 25, 25, 25, 27, 25, 25, 27, 40, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 27, 27, 58, - 58, 58, 58, 58, 58, 0, 0, 0, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 79, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 0, 0, 0, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 0, 37, 34, 37, 37, 37, 34, 34, 37, 34, 37, 34, 37, 34, 37, 37, 37, 0, - 34, 37, 34, 34, 37, 34, 34, 34, 34, 34, 34, 34, 42, 0, 0, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 34, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 57, 57, 57, 57, 120, 57, 57, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, - 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, - 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, - 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, - 40, 40, 40, 40, 0, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 57, 57, 29, 35, 29, 35, 57, 57, 57, 29, 35, 57, 29, 35, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 63, 57, 57, 63, 57, 29, 35, 57, 57, 29, 35, 127, - 128, 127, 128, 127, 128, 127, 128, 57, 57, 57, 57, 57, 43, 57, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 0, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 0, 0, 0, 0, 169, 170, 170, 170, 168, 171, 132, 172, 165, 166, 165, - 166, 165, 166, 165, 166, 165, 166, 168, 168, 165, 166, 165, 166, 165, - 166, 165, 166, 173, 174, 175, 175, 168, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 176, 177, 178, 179, 180, 180, 173, 171, 171, 171, 171, - 171, 168, 168, 172, 172, 172, 171, 132, 170, 168, 27, 0, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, - 181, 181, 182, 182, 171, 171, 132, 173, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 170, 171, 171, 171, 132, 0, 0, 0, 0, 0, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 0, 0, 0, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 0, 183, 183, 184, 184, 184, 184, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 0, 0, 0, 0, 0, 0, 0, 0, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 168, 168, 0, 184, 184, 184, - 184, 184, 184, 184, 184, 184, 184, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 185, - 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 168, 168, 168, 183, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 168, 168, 168, 168, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 0, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 168, 168, - 168, 168, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 168, 168, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, - 183, 183, 183, 183, 183, 183, 183, 183, 168, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 0, 27, 27, 27, 27, 0, 27, 27, 27, 27, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 25, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 0, 27, 0, 27, 27, 27, 27, 0, 0, 0, 27, 0, 27, 27, 27, 27, 27, + 27, 27, 0, 0, 27, 27, 27, 27, 27, 27, 27, 162, 163, 162, 163, 162, 163, + 162, 163, 162, 163, 162, 163, 162, 163, 234, 234, 234, 234, 234, 234, + 234, 234, 234, 234, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 27, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 171, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, 0, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 42, 57, 57, 57, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 0, 0, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 40, 60, - 61, 61, 61, 57, 0, 0, 0, 0, 0, 0, 0, 0, 60, 60, 57, 43, 37, 34, 37, 34, - 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, - 37, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 44, 44, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 34, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, - 34, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 42, 34, 34, 34, 34, 34, 34, - 34, 34, 37, 34, 37, 34, 37, 37, 34, 37, 34, 37, 34, 37, 34, 37, 34, 43, - 186, 186, 37, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, - 40, 40, 40, 40, 109, 40, 40, 40, 114, 40, 40, 40, 40, 109, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 112, 112, 109, 109, 112, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 57, 57, 57, 57, 0, 0, 0, 0, 0, 0, 0, 0, 112, - 112, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 62, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 109, 109, 109, 109, 109, 64, 64, 64, 62, 62, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 112, 136, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 109, 109, 109, 109, 109, 109, 112, 112, 109, 109, - 112, 112, 109, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 109, 40, 40, - 40, 40, 40, 40, 40, 40, 109, 112, 0, 0, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 0, 0, 62, 62, 62, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, 0, 0, - 0, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 34, 34, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 85, 189, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 157, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 0, - 85, 85, 85, 85, 85, 0, 85, 0, 85, 85, 0, 85, 85, 0, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 144, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 0, 0, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 89, 27, - 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 170, 170, 170, 170, 170, 170, 170, 174, 175, 170, 0, 0, 0, 0, 0, 0, 60, - 60, 60, 60, 60, 60, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, 173, 173, 191, - 191, 174, 175, 174, 175, 174, 175, 174, 175, 174, 175, 174, 175, 174, - 175, 174, 175, 170, 170, 174, 175, 170, 170, 170, 170, 191, 191, 191, - 192, 170, 192, 0, 170, 192, 170, 170, 173, 165, 166, 165, 166, 165, 166, - 193, 170, 170, 194, 195, 196, 196, 197, 0, 170, 198, 193, 170, 0, 0, 0, - 0, 95, 95, 95, 95, 95, 0, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 0, 0, 107, 0, - 199, 199, 200, 201, 200, 199, 199, 202, 203, 199, 204, 205, 206, 205, - 205, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 205, 199, 208, - 209, 208, 199, 199, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 202, 199, 203, 211, 212, 211, 213, 213, 213, 213, 213, 213, - 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, - 213, 213, 213, 213, 213, 213, 202, 209, 203, 209, 202, 203, 214, 215, - 216, 214, 214, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 218, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 218, 218, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 0, 0, 0, 217, 217, 217, 217, 217, - 217, 0, 0, 217, 217, 217, 217, 217, 217, 0, 0, 217, 217, 217, 217, 217, - 217, 0, 0, 217, 217, 217, 0, 0, 0, 201, 201, 209, 211, 219, 201, 201, 0, - 220, 221, 221, 221, 221, 220, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 222, - 222, 222, 27, 25, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 40, 40, 0, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 62, 57, - 59, 0, 0, 0, 0, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 0, 0, 0, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 120, 120, 120, - 120, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 120, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 0, 117, 117, 117, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 134, 40, - 40, 40, 40, 40, 40, 40, 40, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 0, 62, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, - 40, 62, 134, 134, 134, 134, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, 85, 85, 0, 0, 85, 0, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 0, 85, 85, 0, 0, 0, 85, 0, 0, 85, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 224, - 224, 224, 224, 0, 0, 0, 0, 0, 57, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 0, 0, 0, - 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 85, 109, 109, 109, 0, 109, 109, 0, 0, 0, 0, 0, 109, 64, 109, 60, - 85, 85, 85, 85, 0, 85, 85, 85, 0, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 0, 0, - 0, 0, 60, 159, 64, 0, 0, 0, 0, 114, 224, 224, 224, 224, 224, 224, 224, - 224, 0, 0, 0, 0, 0, 0, 0, 0, 82, 82, 82, 82, 82, 82, 82, 82, 82, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 27, 27, 27, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 0, 224, 77, 77, 224, 224, 162, 163, 77, 224, 224, 77, 0, 224, 0, 0, + 0, 77, 77, 77, 224, 224, 224, 224, 77, 77, 77, 77, 77, 224, 224, 224, 77, + 77, 77, 224, 224, 224, 224, 9, 10, 9, 10, 9, 10, 9, 10, 162, 163, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 162, 163, 9, 10, 162, 163, 162, 163, 162, 163, 162, 163, 162, + 163, 162, 163, 162, 163, 162, 163, 162, 163, 77, 77, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 77, 77, 77, 77, 77, 77, 77, 77, 224, 77, 77, 77, 77, 77, + 77, 77, 224, 224, 224, 224, 224, 224, 77, 77, 77, 224, 77, 77, 77, 77, + 224, 224, 224, 224, 224, 77, 224, 224, 77, 77, 162, 163, 162, 163, 224, + 77, 77, 77, 77, 224, 77, 224, 224, 224, 77, 77, 224, 224, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 224, 224, 224, 224, 224, 224, 77, 77, 162, 163, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 224, 224, 218, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 77, + 224, 224, 224, 224, 77, 77, 224, 77, 224, 77, 77, 224, 77, 224, 224, 224, + 224, 77, 77, 77, 77, 77, 224, 224, 77, 77, 77, 77, 77, 77, 224, 224, 224, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 224, 224, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 224, 224, 77, 77, 77, 77, 224, 224, 224, 224, 77, 224, 224, 77, 77, + 224, 218, 208, 208, 77, 77, 224, 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 77, 77, 224, 224, 224, 224, 224, 224, 224, + 224, 77, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 77, 77, + 77, 77, 77, 235, 77, 224, 77, 77, 77, 224, 224, 224, 224, 224, 77, 77, + 77, 77, 77, 224, 224, 224, 77, 77, 77, 77, 224, 77, 77, 77, 224, 224, + 224, 224, 224, 77, 224, 77, 77, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 27, 27, 77, 77, 77, 77, 77, 77, 0, 0, 0, 27, 27, 27, + 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 0, 44, 46, 44, 44, 44, 46, 46, 44, 46, 44, 46, 44, 46, 44, + 44, 44, 0, 46, 44, 46, 46, 44, 46, 46, 46, 46, 46, 46, 35, 50, 0, 0, 44, + 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, + 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, + 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, + 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, + 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, + 46, 44, 46, 44, 46, 44, 46, 44, 46, 46, 27, 27, 27, 27, 27, 27, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 136, 136, 136, 152, 136, 136, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, + 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, + 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, + 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 136, 136, 29, 36, 29, 36, 136, 136, 136, 29, 36, + 136, 29, 36, 136, 136, 136, 136, 136, 136, 136, 136, 136, 83, 136, 136, + 83, 136, 29, 36, 136, 136, 29, 36, 162, 163, 162, 163, 162, 163, 162, + 163, 136, 136, 136, 136, 136, 51, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 0, 236, 236, 236, 236, + 237, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 0, 0, 0, 0, 238, + 239, 239, 239, 236, 240, 169, 241, 242, 243, 242, 243, 242, 243, 242, + 243, 242, 243, 236, 236, 242, 243, 242, 243, 242, 243, 242, 243, 244, + 245, 246, 246, 236, 241, 241, 241, 241, 241, 241, 241, 241, 241, 247, + 248, 249, 250, 251, 251, 244, 240, 240, 240, 240, 240, 237, 236, 252, + 252, 252, 240, 169, 239, 236, 27, 0, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 253, 169, 253, 169, 253, 169, 253, 169, 253, 169, + 253, 169, 253, 169, 253, 169, 253, 169, 253, 169, 253, 169, 253, 169, + 169, 253, 169, 253, 169, 253, 169, 169, 169, 169, 169, 169, 253, 253, + 169, 253, 253, 169, 253, 253, 169, 253, 253, 169, 253, 253, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 253, 169, 169, 0, 0, 254, 254, 255, 255, + 240, 256, 257, 244, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 253, 169, 253, 169, 253, 169, 253, 169, 253, 169, 253, 169, 253, + 169, 253, 169, 253, 169, 253, 169, 253, 169, 253, 169, 169, 253, 169, + 253, 169, 253, 169, 169, 169, 169, 169, 169, 253, 253, 169, 253, 253, + 169, 253, 253, 169, 253, 253, 169, 253, 253, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 253, 169, 169, 253, 253, 253, 253, 239, 240, 240, 256, + 257, 0, 0, 0, 0, 0, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 0, 0, 0, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 0, + 258, 258, 259, 259, 259, 259, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 0, 0, 0, 0, + 0, 0, 0, 0, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 237, 237, 0, 259, 259, 259, 259, 259, 259, 259, + 259, 259, 259, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 261, 261, 261, 261, 261, + 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 237, 237, 237, 258, + 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 261, 261, 261, 261, 261, 261, 261, + 261, 261, 261, 261, 261, 261, 261, 261, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 237, 237, 237, 237, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 0, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 237, 237, 237, 237, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 237, + 237, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 237, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 240, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 0, 0, 0, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 52, 136, 136, 136, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 46, 44, 46, 44, 46, 44, 46, 44, + 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, + 46, 44, 46, 44, 46, 0, 0, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 47, 80, 81, 81, 81, 136, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 136, 51, 44, 46, + 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 53, 53, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 46, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 44, 46, 50, 46, 46, 46, + 46, 46, 46, 46, 46, 44, 46, 44, 46, 44, 44, 46, 44, 46, 44, 46, 44, 46, + 44, 46, 51, 262, 262, 44, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 47, 47, 47, 47, 47, 47, 47, 133, 47, 47, 47, 140, 47, 47, 47, 47, 133, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 137, 137, 133, 133, 137, 27, 27, 27, 27, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 136, 136, 136, 136, 0, 0, 0, 0, + 0, 0, 0, 0, 137, 137, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 82, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 133, 133, 133, 133, 133, 84, 84, 84, 82, 82, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 137, 174, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 133, 133, 133, 133, 133, 133, 137, 137, 133, 133, 137, 137, 133, + 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 133, 47, 47, 47, 47, 47, 47, + 47, 47, 133, 137, 0, 0, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 0, 0, 82, 82, 82, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 169, 169, 265, 169, 265, 169, + 169, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 169, 265, 169, + 265, 169, 169, 265, 265, 169, 169, 169, 265, 265, 265, 265, 0, 0, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 0, 0, 0, 0, 0, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 35, 35, 35, 35, 35, 0, 0, 0, 0, 0, 266, 267, 266, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 207, 266, 266, 266, 266, + 266, 266, 266, 266, 266, 266, 266, 266, 266, 0, 266, 266, 266, 266, 266, + 0, 266, 0, 266, 266, 0, 266, 266, 0, 266, 266, 266, 266, 266, 266, 266, + 266, 266, 268, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 191, 269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 0, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 270, 27, 0, 0, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 271, 271, 271, 271, 271, 271, 271, 272, 273, 271, 0, 0, 0, 0, + 0, 0, 80, 80, 80, 80, 80, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 271, 274, + 274, 275, 275, 272, 273, 272, 273, 272, 273, 272, 273, 272, 273, 272, + 273, 272, 273, 272, 273, 239, 239, 272, 273, 271, 271, 271, 271, 275, + 275, 275, 276, 271, 276, 0, 271, 276, 271, 271, 274, 277, 278, 277, 278, + 277, 278, 279, 271, 271, 280, 281, 282, 282, 283, 0, 271, 284, 279, 271, + 0, 0, 0, 0, 128, 128, 128, 115, 128, 0, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 0, 0, 131, 0, 285, 285, 286, 287, 286, 285, 285, 288, 289, + 285, 290, 291, 292, 291, 291, 293, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 291, 285, 294, 295, 294, 285, 285, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 288, 285, 289, 297, 298, 297, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 299, 288, 295, 289, + 295, 288, 289, 300, 301, 302, 300, 300, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 304, 303, 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, 304, 304, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 0, 0, 0, + 303, 303, 303, 303, 303, 303, 0, 0, 303, 303, 303, 303, 303, 303, 0, 0, + 303, 303, 303, 303, 303, 303, 0, 0, 303, 303, 303, 0, 0, 0, 287, 287, + 295, 297, 305, 287, 287, 0, 306, 307, 307, 307, 307, 306, 306, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 308, 308, 308, 27, 25, 0, 0, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, + 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, + 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 0, 0, 0, 0, 0, 82, 136, 79, 0, 0, 0, 0, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 0, 0, 0, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 309, 309, 309, 309, 309, 309, 309, 309, 309, + 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, + 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, + 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, + 309, 309, 152, 152, 152, 152, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 152, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 84, 0, 0, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 0, 147, 147, 147, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 172, 47, + 47, 47, 47, 47, 47, 47, 47, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 0, 82, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, + 47, 82, 172, 172, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 0, 0, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 62, 62, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 105, 105, 105, 105, 105, 105, 0, 0, 105, 0, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 0, 105, 105, 0, 0, 0, 105, 0, 0, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 310, 310, 310, + 310, 0, 0, 0, 0, 0, 136, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 0, 0, 0, 0, 0, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 0, 0, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 225, 225, 159, 159, 159, 59, 59, 59, 226, 225, 225, - 225, 225, 225, 107, 107, 107, 107, 107, 107, 107, 107, 64, 64, 64, 64, - 64, 64, 64, 64, 59, 59, 60, 60, 60, 60, 60, 64, 64, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, + 0, 0, 0, 105, 133, 133, 133, 0, 133, 133, 0, 0, 0, 0, 0, 133, 84, 133, + 80, 105, 105, 105, 105, 0, 105, 105, 105, 0, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 0, 0, 0, 0, 80, 213, 84, 0, 0, 0, + 0, 140, 310, 310, 310, 310, 310, 310, 310, 310, 0, 0, 0, 0, 0, 0, 0, 0, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 82, 82, 82, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 311, 311, 311, 311, 311, 311, 311, + 312, 312, 213, 213, 213, 79, 79, 79, 313, 312, 312, 312, 312, 312, 131, + 131, 131, 131, 131, 131, 131, 131, 84, 84, 84, 84, 84, 84, 84, 84, 79, + 79, 80, 80, 80, 80, 80, 84, 84, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 80, 80, 80, 80, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 311, 311, 311, 311, 311, 311, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 60, 60, 60, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 27, 80, 80, 80, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 34, 34, 34, 34, 34, 34, 34, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 37, 0, 37, 37, 0, 0, 37, 0, 0, 37, 37, 0, 0, 37, - 37, 37, 37, 0, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 0, 34, 0, - 34, 34, 34, 34, 34, 34, 34, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, - 37, 0, 37, 37, 37, 37, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, 0, 37, 37, - 37, 37, 37, 37, 37, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 0, 37, - 37, 37, 37, 0, 37, 37, 37, 37, 37, 0, 37, 0, 0, 0, 37, 37, 37, 37, 37, - 37, 37, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 227, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 228, - 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 227, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 228, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 227, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 228, 34, 34, 34, 34, 34, 34, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 227, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 228, 34, 34, 34, 34, 34, 34, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 227, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 228, 34, 34, - 34, 34, 34, 34, 37, 34, 0, 0, 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 35, 35, 35, 35, 35, 35, 35, 0, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 48, 0, 48, 48, 0, 0, 48, 0, 0, 48, 48, 0, + 0, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 35, 35, 35, 35, 0, + 35, 0, 35, 35, 35, 35, 35, 35, 35, 0, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 48, 48, 0, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, + 48, 48, 48, 48, 48, 48, 0, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 48, 48, 0, + 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 0, 48, 0, 0, 0, 48, 48, 48, 48, + 48, 48, 48, 0, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 314, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 315, 35, 35, 35, 35, 35, 35, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 314, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 315, 35, 35, 35, 35, 35, 35, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 314, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 315, 35, 35, 35, 35, 35, 35, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 314, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 315, 35, 35, 35, 35, 35, + 35, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 314, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 315, 35, + 35, 35, 35, 35, 35, 48, 35, 0, 0, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, @@ -2055,81 +2309,52 @@ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 264, 0, 0, }; /* decomposition data */ Modified: python/branches/py3k/Tools/unicode/makeunicodedata.py ============================================================================== --- python/branches/py3k/Tools/unicode/makeunicodedata.py (original) +++ python/branches/py3k/Tools/unicode/makeunicodedata.py Tue Apr 28 00:31:40 2009 @@ -36,6 +36,7 @@ COMPOSITION_EXCLUSIONS = "CompositionExclusions%s.txt" EASTASIAN_WIDTH = "EastAsianWidth%s.txt" DERIVED_CORE_PROPERTIES = "DerivedCoreProperties%s.txt" +DERIVEDNORMALIZATION_PROPS = "DerivedNormalizationProps%s.txt" old_versions = ["3.2.0"] @@ -72,7 +73,8 @@ unicode = UnicodeData(UNICODE_DATA % version, COMPOSITION_EXCLUSIONS % version, EASTASIAN_WIDTH % version, - DERIVED_CORE_PROPERTIES % version) + DERIVED_CORE_PROPERTIES % version, + DERIVEDNORMALIZATION_PROPS % version) print(len(list(filter(None, unicode.table))), "characters") @@ -94,7 +96,7 @@ def makeunicodedata(unicode, trace): - dummy = (0, 0, 0, 0, 0) + dummy = (0, 0, 0, 0, 0, 0) table = [dummy] cache = {0: dummy} index = [0] * len(unicode.chars) @@ -114,8 +116,10 @@ bidirectional = BIDIRECTIONAL_NAMES.index(record[4]) mirrored = record[9] == "Y" eastasianwidth = EASTASIANWIDTH_NAMES.index(record[15]) + normalizationquickcheck = record[17] item = ( - category, combining, bidirectional, mirrored, eastasianwidth + category, combining, bidirectional, mirrored, eastasianwidth, + normalizationquickcheck ) # add entry to index and item tables i = cache.get(item) @@ -227,7 +231,7 @@ print("/* a list of unique database records */", file=fp) print("const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = {", file=fp) for item in table: - print(" {%d, %d, %d, %d, %d}," % item, file=fp) + print(" {%d, %d, %d, %d, %d, %d}," % item, file=fp) print("};", file=fp) print(file=fp) @@ -717,7 +721,7 @@ # derived-props] (17) def __init__(self, filename, exclusions, eastasianwidth, - derivedprops, expand=1): + derivedprops, derivednormalizationprops=None, expand=1): self.changed = [] file = open(filename) table = [None] * 0x110000 @@ -803,6 +807,29 @@ # apply to unassigned code points; ignore them table[char][-1].add(p) + if derivednormalizationprops: + quickchecks = [0] * 0x110000 # default is Yes + qc_order = 'NFD_QC NFKD_QC NFC_QC NFKC_QC'.split() + for s in open(derivednormalizationprops): + if '#' in s: + s = s[:s.index('#')] + s = [i.strip() for i in s.split(';')] + if len(s) < 2 or s[1] not in qc_order: + continue + quickcheck = 'MN'.index(s[2]) + 1 # Maybe or No + quickcheck_shift = qc_order.index(s[1])*2 + quickcheck <<= quickcheck_shift + if '..' not in s[0]: + first = last = int(s[0], 16) + else: + first, last = [int(c, 16) for c in s[0].split('..')] + for char in range(first, last+1): + assert not (quickchecks[char]>>quickcheck_shift)&3 + quickchecks[char] |= quickcheck + for i in range(0, 0x110000): + if table[i] is not None: + table[i].append(quickchecks[i]) + def uselatin1(self): # restrict character range to ISO Latin 1 self.chars = list(range(256)) From buildbot at python.org Tue Apr 28 01:35:50 2009 From: buildbot at python.org (buildbot at python.org) Date: Mon, 27 Apr 2009 23:35:50 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo trunk Message-ID: <20090427233550.B92E01E401C@bag.python.org> The Buildbot has detected a new failure of x86 gentoo trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%20trunk/builds/4890 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: antoine.pitrou BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_os make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Tue Apr 28 04:12:35 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 28 Apr 2009 02:12:35 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 3.x Message-ID: <20090428021235.CA0EE1E401A@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%203.x/builds/702 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: antoine.pitrou BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_os make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Tue Apr 28 04:27:02 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 28 Apr 2009 02:27:02 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090428022702.A5D771E40F1@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/308 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: antoine.pitrou,eric.smith BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_posix test_subprocess ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From buildbot at python.org Tue Apr 28 04:28:10 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 28 Apr 2009 02:28:10 +0000 Subject: [Python-checkins] buildbot failure in x86 XP-4 3.x Message-ID: <20090428022811.098CA1E401A@bag.python.org> The Buildbot has detected a new failure of x86 XP-4 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20XP-4%203.x/builds/507 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: bolen-windows Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test__locale test_codecs Traceback (most recent call last): File "../lib/test/regrtest.py", line 613, in runtest_inner the_package = __import__(abstest, globals(), locals(), []) File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\test\test__locale.py", line 2, in from _locale import (setlocale, LC_ALL, LC_CTYPE, LC_NUMERIC, RADIXCHAR, THOUSEP, nl_langinfo, ImportError: cannot import name RADIXCHAR ====================================================================== ERROR: test_basics (test.test_codecs.BasicUnicodeTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\test\test_codecs.py", line 1344, in test_basics encodedresult += encoder.encode(c) File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\encodings\ascii.py", line 22, in encode return codecs.ascii_encode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_encode' ====================================================================== ERROR: test_decoder_state (test.test_codecs.BasicUnicodeTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\test\test_codecs.py", line 1429, in test_decoder_state self.check_state_handling_decode(encoding, u, u.encode(encoding)) File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\test\test_codecs.py", line 30, in check_state_handling_decode part1 = d.decode(s[:i]) File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\encodings\ascii.py", line 26, in decode return codecs.ascii_decode(input, self.errors)[0] AttributeError: 'NoneType' object has no attribute 'ascii_decode' sincerely, -The Buildbot From buildbot at python.org Tue Apr 28 06:07:24 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 28 Apr 2009 04:07:24 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090428040725.3EF571E400C@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/592 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: antoine.pitrou BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_os test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 251, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 177, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Tue Apr 28 09:33:09 2009 From: python-checkins at python.org (eric.smith) Date: Tue, 28 Apr 2009 09:33:09 +0200 (CEST) Subject: [Python-checkins] r72056 - python/trunk/Python/pystrtod.c Message-ID: <20090428073309.95BD01E4011@bag.python.org> Author: eric.smith Date: Tue Apr 28 09:33:09 2009 New Revision: 72056 Log: Silence warning on Windows. Modified: python/trunk/Python/pystrtod.c Modified: python/trunk/Python/pystrtod.c ============================================================================== --- python/trunk/Python/pystrtod.c (original) +++ python/trunk/Python/pystrtod.c Tue Apr 28 09:33:09 2009 @@ -260,7 +260,7 @@ Py_LOCAL_INLINE(void) ensure_sign(char* buffer, size_t buf_size) { - Py_ssize_t len; + size_t len; if (buffer[0] == '-') /* Already have a sign. */ From python-checkins at python.org Tue Apr 28 09:34:38 2009 From: python-checkins at python.org (eric.smith) Date: Tue, 28 Apr 2009 09:34:38 +0200 (CEST) Subject: [Python-checkins] r72057 - python/branches/release26-maint Message-ID: <20090428073438.01C261E4011@bag.python.org> Author: eric.smith Date: Tue Apr 28 09:34:37 2009 New Revision: 72057 Log: Blocked revisions 72056 via svnmerge ........ r72056 | eric.smith | 2009-04-28 03:33:09 -0400 (Tue, 28 Apr 2009) | 1 line Silence warning on Windows. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Tue Apr 28 09:37:06 2009 From: python-checkins at python.org (eric.smith) Date: Tue, 28 Apr 2009 09:37:06 +0200 (CEST) Subject: [Python-checkins] r72058 - python/branches/py3k Message-ID: <20090428073706.67C821E4011@bag.python.org> Author: eric.smith Date: Tue Apr 28 09:37:06 2009 New Revision: 72058 Log: Blocked revisions 72056 via svnmerge ........ r72056 | eric.smith | 2009-04-28 03:33:09 -0400 (Tue, 28 Apr 2009) | 1 line Silence warning on Windows. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Tue Apr 28 09:38:01 2009 From: python-checkins at python.org (eric.smith) Date: Tue, 28 Apr 2009 09:38:01 +0200 (CEST) Subject: [Python-checkins] r72059 - python/branches/release30-maint Message-ID: <20090428073801.8191C1E4011@bag.python.org> Author: eric.smith Date: Tue Apr 28 09:38:01 2009 New Revision: 72059 Log: Blocked revisions 72058 via svnmerge ................ r72058 | eric.smith | 2009-04-28 03:37:06 -0400 (Tue, 28 Apr 2009) | 8 lines Blocked revisions 72056 via svnmerge ........ r72056 | eric.smith | 2009-04-28 03:33:09 -0400 (Tue, 28 Apr 2009) | 1 line Silence warning on Windows. ........ ................ Modified: python/branches/release30-maint/ (props changed) From buildbot at python.org Tue Apr 28 10:13:49 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 28 Apr 2009 08:13:49 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 2.6 Message-ID: <20090428081349.7E2611E401E@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%202.6/builds/298 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: eric.smith BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_popen2 make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Tue Apr 28 10:20:14 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 28 Apr 2009 08:20:14 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable trunk Message-ID: <20090428082014.52F541E4011@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%20trunk/builds/428 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: eric.smith BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_os make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Tue Apr 28 10:24:30 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 28 Apr 2009 08:24:30 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 3.x Message-ID: <20090428082431.113D61E4011@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%203.x/builds/833 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: eric.smith BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_time ====================================================================== FAIL: test_tzset (test.test_time.TimeTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_time.py", line 166, in test_tzset self.failIfEqual(time.gmtime(xmas2002), time.localtime(xmas2002)) AssertionError: time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) == time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Tue Apr 28 10:35:36 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 28 Apr 2009 08:35:36 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc trunk Message-ID: <20090428083537.049551E4011@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc trunk. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%20trunk/builds/343 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: eric.smith BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_os test_time ====================================================================== FAIL: test_update2 (test.test_os.EnvironTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/trunk.loewis-sun/build/Lib/test/test_os.py", line 348, in test_update2 self.assertEquals(value, "World") AssertionError: '' != 'World' ====================================================================== FAIL: test_tzset (test.test_time.TimeTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/trunk.loewis-sun/build/Lib/test/test_time.py", line 152, in test_tzset time.gmtime(xmas2002), time.localtime(xmas2002) AssertionError: time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) != time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=1, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) sincerely, -The Buildbot From buildbot at python.org Tue Apr 28 11:45:37 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 28 Apr 2009 09:45:37 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 2.6 Message-ID: <20090428094537.330B21E4011@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%202.6/builds/289 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: eric.smith BUILD FAILED: failed failed slave lost sincerely, -The Buildbot From nnorwitz at gmail.com Tue Apr 28 12:02:28 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 28 Apr 2009 06:02:28 -0400 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20090428100228.GA22782@python.psfb.org> More important issues: ---------------------- test_ssl leaked [0, 0, 322] references, sum=322 Less important issues: ---------------------- test_asynchat leaked [-132, 0, 0] references, sum=-132 test_cmd_line leaked [25, 0, -25] references, sum=0 test_docxmlrpc leaked [0, 0, -5] references, sum=-5 test_smtplib leaked [94, 0, -4] references, sum=90 test_sys leaked [42, -42, 42] references, sum=42 test_threading leaked [48, 48, 48] references, sum=144 test_urllib2_localnet leaked [3, 272, -266] references, sum=9 From python-checkins at python.org Tue Apr 28 18:08:18 2009 From: python-checkins at python.org (r.david.murray) Date: Tue, 28 Apr 2009 18:08:18 +0200 (CEST) Subject: [Python-checkins] r72060 - python/trunk/Doc/library/multiprocessing.rst Message-ID: <20090428160818.E94681E4011@bag.python.org> Author: r.david.murray Date: Tue Apr 28 18:08:18 2009 New Revision: 72060 Log: Various small fixups to the multiprocessing docs, mostly fixing and enabling doctests that Sphinx can run, and fixing and disabling tests that Sphinx can't run. I hand checked every test not now marked as a doctest, and all except the two that have open bug reports against them now work, at least on Linux/trunk. (I did not look at the last example at all since there was already an open bug). I did not read the whole document with an editor's eye, but I did fix a few things I noticed while working on the tests. Modified: python/trunk/Doc/library/multiprocessing.rst Modified: python/trunk/Doc/library/multiprocessing.rst ============================================================================== --- python/trunk/Doc/library/multiprocessing.rst (original) +++ python/trunk/Doc/library/multiprocessing.rst Tue Apr 28 18:08:18 2009 @@ -42,12 +42,18 @@ >>> p.map(f, [1,2,3]) Process PoolWorker-1: Process PoolWorker-2: + Process PoolWorker-3: + Traceback (most recent call last): Traceback (most recent call last): Traceback (most recent call last): AttributeError: 'module' object has no attribute 'f' AttributeError: 'module' object has no attribute 'f' AttributeError: 'module' object has no attribute 'f' + (If you try this it will actually output three full tracebacks + interleaved in a semi-random fashion, and then you may have to + stop the master process somehow.) + The :class:`Process` class ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -418,7 +424,9 @@ :attr:`exit_code` methods should only be called by the process that created the process object. - Example usage of some of the methods of :class:`Process`:: + Example usage of some of the methods of :class:`Process`: + + .. doctest:: >>> import multiprocessing, time, signal >>> p = multiprocessing.Process(target=time.sleep, args=(1000,)) @@ -428,6 +436,7 @@ >>> print p, p.is_alive() True >>> p.terminate() + >>> time.sleep(0.1) >>> print p, p.is_alive() False >>> p.exitcode == -signal.SIGTERM @@ -669,7 +678,7 @@ freeze_support() Process(target=f).start() - If the ``freeze_support()`` line is missed out then trying to run the frozen + If the ``freeze_support()`` line is omitted then trying to run the frozen executable will raise :exc:`RuntimeError`. If the module is being run normally by the Python interpreter then @@ -683,7 +692,7 @@ setExecutable(os.path.join(sys.exec_prefix, 'pythonw.exe')) - before they can create child processes. (Windows only) + before they can create child processes. (Windows only) .. note:: @@ -766,8 +775,8 @@ *buffer* must be an object satisfying the writable buffer interface. If *offset* is given then the message will be written into the buffer from - *that position. Offset must be a non-negative integer less than the - *length of *buffer* (in bytes). + that position. Offset must be a non-negative integer less than the + length of *buffer* (in bytes). If the buffer is too short then a :exc:`BufferTooShort` exception is raised and the complete message is available as ``e.args[0]`` where ``e`` @@ -776,6 +785,8 @@ For example: +.. doctest:: + >>> from multiprocessing import Pipe >>> a, b = Pipe() >>> a.send([1, 'hello', None]) @@ -868,8 +879,9 @@ specifies a timeout in seconds. If *block* is ``False`` then *timeout* is ignored. - Note that on OS/X ``sem_timedwait`` is unsupported, so timeout arguments - for these will be ignored. +.. note:: + On OS/X ``sem_timedwait`` is unsupported, so timeout arguments for the + aforementioned :meth:`acquire` methods will be ignored on OS/X. .. note:: @@ -1066,7 +1078,7 @@ lock = Lock() n = Value('i', 7) - x = Value(ctypes.c_double, 1.0/3.0, lock=False) + x = Value(c_double, 1.0/3.0, lock=False) s = Array('c', 'hello world', lock=lock) A = Array(Point, [(1.875,-6.25), (-5.75,2.0), (2.375,9.5)], lock=lock) @@ -1148,21 +1160,21 @@ Returns a :class:`Server` object which represents the actual server under the control of the Manager. The :class:`Server` object supports the - :meth:`serve_forever` method: + :meth:`serve_forever` method:: >>> from multiprocessing.managers import BaseManager - >>> m = BaseManager(address=('', 50000), authkey='abc')) - >>> server = m.get_server() - >>> s.serve_forever() + >>> manager = BaseManager(address=('', 50000), authkey='abc') + >>> server = manager.get_server() + >>> server.serve_forever() - :class:`Server` additionally have an :attr:`address` attribute. + :class:`Server` additionally has an :attr:`address` attribute. .. method:: connect() - Connect a local manager object to a remote manager process: + Connect a local manager object to a remote manager process:: >>> from multiprocessing.managers import BaseManager - >>> m = BaseManager(address='127.0.0.1', authkey='abc') + >>> m = BaseManager(address=('127.0.0.1', 5000), authkey='abc') >>> m.connect() .. method:: shutdown() @@ -1290,7 +1302,9 @@ Its representation shows the values of its attributes. However, when using a proxy for a namespace object, an attribute beginning with -``'_'`` will be an attribute of the proxy and not an attribute of the referent:: +``'_'`` will be an attribute of the proxy and not an attribute of the referent: + +.. doctest:: >>> manager = multiprocessing.Manager() >>> Global = manager.Namespace() @@ -1342,17 +1356,15 @@ >>> import Queue >>> queue = Queue.Queue() >>> class QueueManager(BaseManager): pass - ... >>> QueueManager.register('get_queue', callable=lambda:queue) >>> m = QueueManager(address=('', 50000), authkey='abracadabra') >>> s = m.get_server() - >>> s.serveForever() + >>> s.serve_forever() One client can access the server as follows:: >>> from multiprocessing.managers import BaseManager >>> class QueueManager(BaseManager): pass - ... >>> QueueManager.register('get_queue') >>> m = QueueManager(address=('foo.bar.org', 50000), authkey='abracadabra') >>> m.connect() @@ -1363,10 +1375,10 @@ >>> from multiprocessing.managers import BaseManager >>> class QueueManager(BaseManager): pass - ... - >>> QueueManager.register('getQueue') - >>> m = QueueManager.from_address(address=('foo.bar.org', 50000), authkey='abracadabra') - >>> queue = m.getQueue() + >>> QueueManager.register('get_queue') + >>> m = QueueManager(address=('foo.bar.org', 50000), authkey='abracadabra') + >>> m.connect() + >>> queue = m.get_queue() >>> queue.get() 'hello' @@ -1402,7 +1414,9 @@ A proxy object has methods which invoke corresponding methods of its referent (although not every method of the referent will necessarily be available through the proxy). A proxy can usually be used in most of the same ways that its -referent can:: +referent can: + +.. doctest:: >>> from multiprocessing import Manager >>> manager = Manager() @@ -1410,7 +1424,7 @@ >>> print l [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> print repr(l) - + >>> l[4] 16 >>> l[2:5] @@ -1423,7 +1437,9 @@ An important feature of proxy objects is that they are picklable so they can be passed between processes. Note, however, that if a proxy is sent to the corresponding manager's process then unpickling it will produce the referent -itself. This means, for example, that one shared object can contain a second:: +itself. This means, for example, that one shared object can contain a second: + +.. doctest:: >>> a = manager.list() >>> b = manager.list() @@ -1437,12 +1453,14 @@ .. note:: The proxy types in :mod:`multiprocessing` do nothing to support comparisons - by value. So, for instance, :: + by value. So, for instance, we have: + + .. doctest:: - manager.list([1,2,3]) == [1,2,3] + >>> manager.list([1,2,3]) == [1,2,3] + False - will return ``False``. One should just use a copy of the referent instead - when making comparisons. + One should just use a copy of the referent instead when making comparisons. .. class:: BaseProxy @@ -1474,7 +1492,9 @@ Note in particular that an exception will be raised if *methodname* has not been *exposed* - An example of the usage of :meth:`_callmethod`:: + An example of the usage of :meth:`_callmethod`: + + .. doctest:: >>> l = manager.list(range(10)) >>> l._callmethod('__len__') @@ -1899,12 +1919,12 @@ >>> logger.warning('doomed') [WARNING/MainProcess] doomed >>> m = multiprocessing.Manager() - [INFO/SyncManager-1] child process calling self.run() - [INFO/SyncManager-1] created temp directory /.../pymp-Wh47O_ - [INFO/SyncManager-1] manager serving at '/.../listener-lWsERs' + [INFO/SyncManager-...] child process calling self.run() + [INFO/SyncManager-...] created temp directory /.../pymp-... + [INFO/SyncManager-...] manager serving at '/.../listener-...' >>> del m [INFO/MainProcess] sending shutdown message to manager - [INFO/SyncManager-1] manager exiting with exitcode 0 + [INFO/SyncManager-...] manager exiting with exitcode 0 In addition to having these two logging functions, the multiprocessing also exposes two additional logging level attributes. These are :const:`SUBWARNING` @@ -1931,18 +1951,18 @@ >>> logger.warning('doomed') [WARNING/MainProcess] doomed >>> m = multiprocessing.Manager() - [INFO/SyncManager-1] child process calling self.run() - [INFO/SyncManager-1] created temp directory /.../pymp-djGBXN - [INFO/SyncManager-1] manager serving at '/.../pymp-djGBXN/listener-knBYGe' + [INFO/SyncManager-...] child process calling self.run() + [INFO/SyncManager-...] created temp directory /.../pymp-... + [INFO/SyncManager-...] manager serving at '/.../pymp-djGBXN/listener-...' >>> del m [SUBDEBUG/MainProcess] finalizer calling ... [INFO/MainProcess] sending shutdown message to manager - [DEBUG/SyncManager-1] manager received shutdown message - [SUBDEBUG/SyncManager-1] calling ... - [SUBDEBUG/SyncManager-1] calling - [SUBDEBUG/SyncManager-1] finalizer calling ... - [INFO/SyncManager-1] manager exiting with exitcode 0 + [DEBUG/SyncManager-...] manager received shutdown message + [SUBDEBUG/SyncManager-...] calling ... + [SUBDEBUG/SyncManager-...] calling + [SUBDEBUG/SyncManager-...] finalizer calling ... + [INFO/SyncManager-...] manager exiting with exitcode 0 The :mod:`multiprocessing.dummy` module ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From buildbot at python.org Tue Apr 28 18:14:06 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 28 Apr 2009 16:14:06 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo trunk Message-ID: <20090428161407.483B01E4011@bag.python.org> The Buildbot has detected a new failure of x86 gentoo trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%20trunk/builds/4892 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: The web-page 'force build' button was pressed by 'dfa': ADFS Build Source Stamp: [branch TYS] UYS Blamelist: BUILD FAILED: failed svn sincerely, -The Buildbot From python-checkins at python.org Tue Apr 28 19:08:15 2009 From: python-checkins at python.org (martin.v.loewis) Date: Tue, 28 Apr 2009 19:08:15 +0200 (CEST) Subject: [Python-checkins] r72061 - peps/trunk/pep-0383.txt Message-ID: <20090428170815.28CC61E4011@bag.python.org> Author: martin.v.loewis Date: Tue Apr 28 19:08:14 2009 New Revision: 72061 Log: Clarify what invalid bytes are in UTF-8. Modified: peps/trunk/pep-0383.txt Modified: peps/trunk/pep-0383.txt ============================================================================== --- peps/trunk/pep-0383.txt (original) +++ peps/trunk/pep-0383.txt Tue Apr 28 19:08:14 2009 @@ -82,8 +82,11 @@ If the locale's encoding is UTF-8, the file system encoding is set to a new encoding "utf-8b", as the regular UTF-8 codec would not re-encode half surrogates as single bytes. The UTF-8b codec decodes -non-decodable bytes (which must be >= 0x80) into half surrogate codes -U+DC80..U+DCFF. +invalid bytes (which must be >= 0x80) into half surrogate codes +U+DC80..U+DCFF. Unlike the utf-8 codec, the utf-8b codec follows the +strict definition of UTF-8 to determine what an invalid byte is +(which, among other restrictions, disallows to encode surrogate codes +in UTF-8). Discussion ========== From python-checkins at python.org Tue Apr 28 20:02:00 2009 From: python-checkins at python.org (r.david.murray) Date: Tue, 28 Apr 2009 20:02:00 +0200 (CEST) Subject: [Python-checkins] r72062 - in python/branches/py3k: Doc/library/multiprocessing.rst Message-ID: <20090428180200.AB66D1E401E@bag.python.org> Author: r.david.murray Date: Tue Apr 28 20:02:00 2009 New Revision: 72062 Log: Merged revisions 72060 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72060 | r.david.murray | 2009-04-28 12:08:18 -0400 (Tue, 28 Apr 2009) | 10 lines Various small fixups to the multiprocessing docs, mostly fixing and enabling doctests that Sphinx can run, and fixing and disabling tests that Sphinx can't run. I hand checked every test not now marked as a doctest, and all except the two that have open bug reports against them now work, at least on Linux/trunk. (I did not look at the last example at all since there was already an open bug). I did not read the whole document with an editor's eye, but I did fix a few things I noticed while working on the tests. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/multiprocessing.rst Modified: python/branches/py3k/Doc/library/multiprocessing.rst ============================================================================== --- python/branches/py3k/Doc/library/multiprocessing.rst (original) +++ python/branches/py3k/Doc/library/multiprocessing.rst Tue Apr 28 20:02:00 2009 @@ -40,12 +40,18 @@ >>> p.map(f, [1,2,3]) Process PoolWorker-1: Process PoolWorker-2: + Process PoolWorker-3: + Traceback (most recent call last): Traceback (most recent call last): Traceback (most recent call last): AttributeError: 'module' object has no attribute 'f' AttributeError: 'module' object has no attribute 'f' AttributeError: 'module' object has no attribute 'f' + (If you try this it will actually output three full tracebacks + interleaved in a semi-random fashion, and then you may have to + stop the master process somehow.) + The :class:`Process` class ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -416,7 +422,9 @@ :attr:`exit_code` methods should only be called by the process that created the process object. - Example usage of some of the methods of :class:`Process`:: + Example usage of some of the methods of :class:`Process`: + + .. doctest:: >>> import multiprocessing, time, signal >>> p = multiprocessing.Process(target=time.sleep, args=(1000,)) @@ -426,6 +434,7 @@ >>> print(p, p.is_alive()) True >>> p.terminate() + >>> time.sleep(0.1) >>> print(p, p.is_alive()) False >>> p.exitcode == -signal.SIGTERM @@ -667,7 +676,7 @@ freeze_support() Process(target=f).start() - If the ``freeze_support()`` line is missed out then trying to run the frozen + If the ``freeze_support()`` line is omitted then trying to run the frozen executable will raise :exc:`RuntimeError`. If the module is being run normally by the Python interpreter then @@ -681,7 +690,7 @@ setExecutable(os.path.join(sys.exec_prefix, 'pythonw.exe')) - before they can create child processes. (Windows only) + before they can create child processes. (Windows only) .. note:: @@ -764,8 +773,8 @@ *buffer* must be an object satisfying the writable buffer interface. If *offset* is given then the message will be written into the buffer from - *that position. Offset must be a non-negative integer less than the - *length of *buffer* (in bytes). + that position. Offset must be a non-negative integer less than the + length of *buffer* (in bytes). If the buffer is too short then a :exc:`BufferTooShort` exception is raised and the complete message is available as ``e.args[0]`` where ``e`` @@ -774,6 +783,8 @@ For example: +.. doctest:: + >>> from multiprocessing import Pipe >>> a, b = Pipe() >>> a.send([1, 'hello', None]) @@ -866,8 +877,9 @@ specifies a timeout in seconds. If *block* is ``False`` then *timeout* is ignored. - Note that on OS/X ``sem_timedwait`` is unsupported, so timeout arguments - for these will be ignored. +.. note:: + On OS/X ``sem_timedwait`` is unsupported, so timeout arguments for the + aforementioned :meth:`acquire` methods will be ignored on OS/X. .. note:: @@ -1064,7 +1076,7 @@ lock = Lock() n = Value('i', 7) - x = Value(ctypes.c_double, 1.0/3.0, lock=False) + x = Value(c_double, 1.0/3.0, lock=False) s = Array('c', 'hello world', lock=lock) A = Array(Point, [(1.875,-6.25), (-5.75,2.0), (2.375,9.5)], lock=lock) @@ -1146,21 +1158,21 @@ Returns a :class:`Server` object which represents the actual server under the control of the Manager. The :class:`Server` object supports the - :meth:`serve_forever` method: + :meth:`serve_forever` method:: >>> from multiprocessing.managers import BaseManager - >>> m = BaseManager(address=('', 50000), authkey='abc')) - >>> server = m.get_server() - >>> s.serve_forever() + >>> manager = BaseManager(address=('', 50000), authkey='abc') + >>> server = manager.get_server() + >>> server.serve_forever() - :class:`Server` additionally have an :attr:`address` attribute. + :class:`Server` additionally has an :attr:`address` attribute. .. method:: connect() - Connect a local manager object to a remote manager process: + Connect a local manager object to a remote manager process:: >>> from multiprocessing.managers import BaseManager - >>> m = BaseManager(address='127.0.0.1', authkey='abc') + >>> m = BaseManager(address=('127.0.0.1', 5000), authkey='abc') >>> m.connect() .. method:: shutdown() @@ -1288,7 +1300,9 @@ Its representation shows the values of its attributes. However, when using a proxy for a namespace object, an attribute beginning with -``'_'`` will be an attribute of the proxy and not an attribute of the referent:: +``'_'`` will be an attribute of the proxy and not an attribute of the referent: + +.. doctest:: >>> manager = multiprocessing.Manager() >>> Global = manager.Namespace() @@ -1340,17 +1354,15 @@ >>> import queue >>> queue = queue.Queue() >>> class QueueManager(BaseManager): pass - ... >>> QueueManager.register('get_queue', callable=lambda:queue) >>> m = QueueManager(address=('', 50000), authkey='abracadabra') >>> s = m.get_server() - >>> s.serveForever() + >>> s.serve_forever() One client can access the server as follows:: >>> from multiprocessing.managers import BaseManager >>> class QueueManager(BaseManager): pass - ... >>> QueueManager.register('get_queue') >>> m = QueueManager(address=('foo.bar.org', 50000), authkey='abracadabra') >>> m.connect() @@ -1361,10 +1373,10 @@ >>> from multiprocessing.managers import BaseManager >>> class QueueManager(BaseManager): pass - ... - >>> QueueManager.register('getQueue') - >>> m = QueueManager.from_address(address=('foo.bar.org', 50000), authkey='abracadabra') - >>> queue = m.getQueue() + >>> QueueManager.register('get_queue') + >>> m = QueueManager(address=('foo.bar.org', 50000), authkey='abracadabra') + >>> m.connect() + >>> queue = m.get_queue() >>> queue.get() 'hello' @@ -1400,7 +1412,9 @@ A proxy object has methods which invoke corresponding methods of its referent (although not every method of the referent will necessarily be available through the proxy). A proxy can usually be used in most of the same ways that its -referent can:: +referent can: + +.. doctest:: >>> from multiprocessing import Manager >>> manager = Manager() @@ -1408,7 +1422,7 @@ >>> print(l) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> print(repr(l)) - + >>> l[4] 16 >>> l[2:5] @@ -1421,7 +1435,9 @@ An important feature of proxy objects is that they are picklable so they can be passed between processes. Note, however, that if a proxy is sent to the corresponding manager's process then unpickling it will produce the referent -itself. This means, for example, that one shared object can contain a second:: +itself. This means, for example, that one shared object can contain a second: + +.. doctest:: >>> a = manager.list() >>> b = manager.list() @@ -1435,12 +1451,14 @@ .. note:: The proxy types in :mod:`multiprocessing` do nothing to support comparisons - by value. So, for instance, :: + by value. So, for instance, we have: + + .. doctest:: - manager.list([1,2,3]) == [1,2,3] + >>> manager.list([1,2,3]) == [1,2,3] + False - will return ``False``. One should just use a copy of the referent instead - when making comparisons. + One should just use a copy of the referent instead when making comparisons. .. class:: BaseProxy @@ -1472,7 +1490,9 @@ Note in particular that an exception will be raised if *methodname* has not been *exposed* - An example of the usage of :meth:`_callmethod`:: + An example of the usage of :meth:`_callmethod`: + + .. doctest:: >>> l = manager.list(range(10)) >>> l._callmethod('__len__') @@ -1897,12 +1917,12 @@ >>> logger.warning('doomed') [WARNING/MainProcess] doomed >>> m = multiprocessing.Manager() - [INFO/SyncManager-1] child process calling self.run() - [INFO/SyncManager-1] created temp directory /.../pymp-Wh47O_ - [INFO/SyncManager-1] manager serving at '/.../listener-lWsERs' + [INFO/SyncManager-...] child process calling self.run() + [INFO/SyncManager-...] created temp directory /.../pymp-... + [INFO/SyncManager-...] manager serving at '/.../listener-...' >>> del m [INFO/MainProcess] sending shutdown message to manager - [INFO/SyncManager-1] manager exiting with exitcode 0 + [INFO/SyncManager-...] manager exiting with exitcode 0 In addition to having these two logging functions, the multiprocessing also exposes two additional logging level attributes. These are :const:`SUBWARNING` @@ -1929,18 +1949,18 @@ >>> logger.warning('doomed') [WARNING/MainProcess] doomed >>> m = multiprocessing.Manager() - [INFO/SyncManager-1] child process calling self.run() - [INFO/SyncManager-1] created temp directory /.../pymp-djGBXN - [INFO/SyncManager-1] manager serving at '/.../pymp-djGBXN/listener-knBYGe' + [INFO/SyncManager-...] child process calling self.run() + [INFO/SyncManager-...] created temp directory /.../pymp-... + [INFO/SyncManager-...] manager serving at '/.../pymp-djGBXN/listener-...' >>> del m [SUBDEBUG/MainProcess] finalizer calling ... [INFO/MainProcess] sending shutdown message to manager - [DEBUG/SyncManager-1] manager received shutdown message - [SUBDEBUG/SyncManager-1] calling ... - [SUBDEBUG/SyncManager-1] calling - [SUBDEBUG/SyncManager-1] finalizer calling ... - [INFO/SyncManager-1] manager exiting with exitcode 0 + [DEBUG/SyncManager-...] manager received shutdown message + [SUBDEBUG/SyncManager-...] calling ... + [SUBDEBUG/SyncManager-...] calling + [SUBDEBUG/SyncManager-...] finalizer calling ... + [INFO/SyncManager-...] manager exiting with exitcode 0 The :mod:`multiprocessing.dummy` module ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From python-checkins at python.org Tue Apr 28 20:06:15 2009 From: python-checkins at python.org (r.david.murray) Date: Tue, 28 Apr 2009 20:06:15 +0200 (CEST) Subject: [Python-checkins] r72063 - in python/branches/release26-maint: Doc/library/multiprocessing.rst Message-ID: <20090428180615.C83241E401E@bag.python.org> Author: r.david.murray Date: Tue Apr 28 20:06:10 2009 New Revision: 72063 Log: Merged revisions 72060 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72060 | r.david.murray | 2009-04-28 12:08:18 -0400 (Tue, 28 Apr 2009) | 10 lines Various small fixups to the multiprocessing docs, mostly fixing and enabling doctests that Sphinx can run, and fixing and disabling tests that Sphinx can't run. I hand checked every test not now marked as a doctest, and all except the two that have open bug reports against them now work, at least on Linux/trunk. (I did not look at the last example at all since there was already an open bug). I did not read the whole document with an editor's eye, but I did fix a few things I noticed while working on the tests. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/multiprocessing.rst Modified: python/branches/release26-maint/Doc/library/multiprocessing.rst ============================================================================== --- python/branches/release26-maint/Doc/library/multiprocessing.rst (original) +++ python/branches/release26-maint/Doc/library/multiprocessing.rst Tue Apr 28 20:06:10 2009 @@ -42,12 +42,18 @@ >>> p.map(f, [1,2,3]) Process PoolWorker-1: Process PoolWorker-2: + Process PoolWorker-3: + Traceback (most recent call last): Traceback (most recent call last): Traceback (most recent call last): AttributeError: 'module' object has no attribute 'f' AttributeError: 'module' object has no attribute 'f' AttributeError: 'module' object has no attribute 'f' + (If you try this it will actually output three full tracebacks + interleaved in a semi-random fashion, and then you may have to + stop the master process somehow.) + The :class:`Process` class ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -418,7 +424,9 @@ :attr:`exit_code` methods should only be called by the process that created the process object. - Example usage of some of the methods of :class:`Process`:: + Example usage of some of the methods of :class:`Process`: + + .. doctest:: >>> import multiprocessing, time, signal >>> p = multiprocessing.Process(target=time.sleep, args=(1000,)) @@ -428,6 +436,7 @@ >>> print p, p.is_alive() True >>> p.terminate() + >>> time.sleep(0.1) >>> print p, p.is_alive() False >>> p.exitcode == -signal.SIGTERM @@ -669,7 +678,7 @@ freeze_support() Process(target=f).start() - If the ``freeze_support()`` line is missed out then trying to run the frozen + If the ``freeze_support()`` line is omitted then trying to run the frozen executable will raise :exc:`RuntimeError`. If the module is being run normally by the Python interpreter then @@ -683,7 +692,7 @@ setExecutable(os.path.join(sys.exec_prefix, 'pythonw.exe')) - before they can create child processes. (Windows only) + before they can create child processes. (Windows only) .. note:: @@ -763,8 +772,8 @@ *buffer* must be an object satisfying the writable buffer interface. If *offset* is given then the message will be written into the buffer from - *that position. Offset must be a non-negative integer less than the - *length of *buffer* (in bytes). + that position. Offset must be a non-negative integer less than the + length of *buffer* (in bytes). If the buffer is too short then a :exc:`BufferTooShort` exception is raised and the complete message is available as ``e.args[0]`` where ``e`` @@ -773,6 +782,8 @@ For example: +.. doctest:: + >>> from multiprocessing import Pipe >>> a, b = Pipe() >>> a.send([1, 'hello', None]) @@ -859,8 +870,9 @@ specifies a timeout in seconds. If *block* is ``False`` then *timeout* is ignored. - Note that on OS/X ``sem_timedwait`` is unsupported, so timeout arguments - for these will be ignored. +.. note:: + On OS/X ``sem_timedwait`` is unsupported, so timeout arguments for the + aforementioned :meth:`acquire` methods will be ignored on OS/X. .. note:: @@ -1057,7 +1069,7 @@ lock = Lock() n = Value('i', 7) - x = Value(ctypes.c_double, 1.0/3.0, lock=False) + x = Value(c_double, 1.0/3.0, lock=False) s = Array('c', 'hello world', lock=lock) A = Array(Point, [(1.875,-6.25), (-5.75,2.0), (2.375,9.5)], lock=lock) @@ -1138,21 +1150,21 @@ Returns a :class:`Server` object which represents the actual server under the control of the Manager. The :class:`Server` object supports the - :meth:`serve_forever` method: + :meth:`serve_forever` method:: >>> from multiprocessing.managers import BaseManager - >>> m = BaseManager(address=('', 50000), authkey='abc')) - >>> server = m.get_server() - >>> s.serve_forever() + >>> manager = BaseManager(address=('', 50000), authkey='abc') + >>> server = manager.get_server() + >>> server.serve_forever() - :class:`Server` additionally have an :attr:`address` attribute. + :class:`Server` additionally has an :attr:`address` attribute. .. method:: connect() - Connect a local manager object to a remote manager process: + Connect a local manager object to a remote manager process:: >>> from multiprocessing.managers import BaseManager - >>> m = BaseManager(address='127.0.0.1', authkey='abc)) + >>> m = BaseManager(address=('127.0.0.1', 5000), authkey='abc') >>> m.connect() .. method:: shutdown() @@ -1280,7 +1292,9 @@ Its representation shows the values of its attributes. However, when using a proxy for a namespace object, an attribute beginning with -``'_'`` will be an attribute of the proxy and not an attribute of the referent:: +``'_'`` will be an attribute of the proxy and not an attribute of the referent: + +.. doctest:: >>> manager = multiprocessing.Manager() >>> Global = manager.Namespace() @@ -1332,17 +1346,15 @@ >>> import Queue >>> queue = Queue.Queue() >>> class QueueManager(BaseManager): pass - ... >>> QueueManager.register('get_queue', callable=lambda:queue) >>> m = QueueManager(address=('', 50000), authkey='abracadabra') >>> s = m.get_server() - >>> s.serveForever() + >>> s.serve_forever() One client can access the server as follows:: >>> from multiprocessing.managers import BaseManager >>> class QueueManager(BaseManager): pass - ... >>> QueueManager.register('get_queue') >>> m = QueueManager(address=('foo.bar.org', 50000), authkey='abracadabra') >>> m.connect() @@ -1353,10 +1365,10 @@ >>> from multiprocessing.managers import BaseManager >>> class QueueManager(BaseManager): pass - ... - >>> QueueManager.register('getQueue') - >>> m = QueueManager.from_address(address=('foo.bar.org', 50000), authkey='abracadabra') - >>> queue = m.getQueue() + >>> QueueManager.register('get_queue') + >>> m = QueueManager(address=('foo.bar.org', 50000), authkey='abracadabra') + >>> m.connect() + >>> queue = m.get_queue() >>> queue.get() 'hello' @@ -1392,7 +1404,9 @@ A proxy object has methods which invoke corresponding methods of its referent (although not every method of the referent will necessarily be available through the proxy). A proxy can usually be used in most of the same ways that its -referent can:: +referent can: + +.. doctest:: >>> from multiprocessing import Manager >>> manager = Manager() @@ -1400,7 +1414,7 @@ >>> print l [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> print repr(l) - + >>> l[4] 16 >>> l[2:5] @@ -1413,7 +1427,9 @@ An important feature of proxy objects is that they are picklable so they can be passed between processes. Note, however, that if a proxy is sent to the corresponding manager's process then unpickling it will produce the referent -itself. This means, for example, that one shared object can contain a second:: +itself. This means, for example, that one shared object can contain a second: + +.. doctest:: >>> a = manager.list() >>> b = manager.list() @@ -1427,12 +1443,14 @@ .. note:: The proxy types in :mod:`multiprocessing` do nothing to support comparisons - by value. So, for instance, :: + by value. So, for instance, we have: + + .. doctest:: - manager.list([1,2,3]) == [1,2,3] + >>> manager.list([1,2,3]) == [1,2,3] + False - will return ``False``. One should just use a copy of the referent instead - when making comparisons. + One should just use a copy of the referent instead when making comparisons. .. class:: BaseProxy @@ -1464,7 +1482,9 @@ Note in particular that an exception will be raised if *methodname* has not been *exposed* - An example of the usage of :meth:`_callmethod`:: + An example of the usage of :meth:`_callmethod`: + + .. doctest:: >>> l = manager.list(range(10)) >>> l._callmethod('__len__') @@ -1887,12 +1907,12 @@ >>> logger.warning('doomed') [WARNING/MainProcess] doomed >>> m = multiprocessing.Manager() - [INFO/SyncManager-1] child process calling self.run() - [INFO/SyncManager-1] created temp directory /.../pymp-Wh47O_ - [INFO/SyncManager-1] manager serving at '/.../listener-lWsERs' + [INFO/SyncManager-...] child process calling self.run() + [INFO/SyncManager-...] created temp directory /.../pymp-... + [INFO/SyncManager-...] manager serving at '/.../listener-...' >>> del m [INFO/MainProcess] sending shutdown message to manager - [INFO/SyncManager-1] manager exiting with exitcode 0 + [INFO/SyncManager-...] manager exiting with exitcode 0 In addition to having these two logging functions, the multiprocessing also exposes two additional logging level attributes. These are :const:`SUBWARNING` @@ -1919,18 +1939,18 @@ >>> logger.warning('doomed') [WARNING/MainProcess] doomed >>> m = multiprocessing.Manager() - [INFO/SyncManager-1] child process calling self.run() - [INFO/SyncManager-1] created temp directory /.../pymp-djGBXN - [INFO/SyncManager-1] manager serving at '/.../pymp-djGBXN/listener-knBYGe' + [INFO/SyncManager-...] child process calling self.run() + [INFO/SyncManager-...] created temp directory /.../pymp-... + [INFO/SyncManager-...] manager serving at '/.../pymp-djGBXN/listener-...' >>> del m [SUBDEBUG/MainProcess] finalizer calling ... [INFO/MainProcess] sending shutdown message to manager - [DEBUG/SyncManager-1] manager received shutdown message - [SUBDEBUG/SyncManager-1] calling ... - [SUBDEBUG/SyncManager-1] calling - [SUBDEBUG/SyncManager-1] finalizer calling ... - [INFO/SyncManager-1] manager exiting with exitcode 0 + [DEBUG/SyncManager-...] manager received shutdown message + [SUBDEBUG/SyncManager-...] calling ... + [SUBDEBUG/SyncManager-...] calling + [SUBDEBUG/SyncManager-...] finalizer calling ... + [INFO/SyncManager-...] manager exiting with exitcode 0 The :mod:`multiprocessing.dummy` module ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From python-checkins at python.org Tue Apr 28 20:08:52 2009 From: python-checkins at python.org (r.david.murray) Date: Tue, 28 Apr 2009 20:08:52 +0200 (CEST) Subject: [Python-checkins] r72064 - in python/branches/release30-maint: Doc/library/multiprocessing.rst Message-ID: <20090428180852.66C7A1E4011@bag.python.org> Author: r.david.murray Date: Tue Apr 28 20:08:51 2009 New Revision: 72064 Log: Merged revisions 72062 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r72062 | r.david.murray | 2009-04-28 14:02:00 -0400 (Tue, 28 Apr 2009) | 16 lines Merged revisions 72060 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72060 | r.david.murray | 2009-04-28 12:08:18 -0400 (Tue, 28 Apr 2009) | 10 lines Various small fixups to the multiprocessing docs, mostly fixing and enabling doctests that Sphinx can run, and fixing and disabling tests that Sphinx can't run. I hand checked every test not now marked as a doctest, and all except the two that have open bug reports against them now work, at least on Linux/trunk. (I did not look at the last example at all since there was already an open bug). I did not read the whole document with an editor's eye, but I did fix a few things I noticed while working on the tests. ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Doc/library/multiprocessing.rst Modified: python/branches/release30-maint/Doc/library/multiprocessing.rst ============================================================================== --- python/branches/release30-maint/Doc/library/multiprocessing.rst (original) +++ python/branches/release30-maint/Doc/library/multiprocessing.rst Tue Apr 28 20:08:51 2009 @@ -40,12 +40,18 @@ >>> p.map(f, [1,2,3]) Process PoolWorker-1: Process PoolWorker-2: + Process PoolWorker-3: + Traceback (most recent call last): Traceback (most recent call last): Traceback (most recent call last): AttributeError: 'module' object has no attribute 'f' AttributeError: 'module' object has no attribute 'f' AttributeError: 'module' object has no attribute 'f' + (If you try this it will actually output three full tracebacks + interleaved in a semi-random fashion, and then you may have to + stop the master process somehow.) + The :class:`Process` class ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -416,7 +422,9 @@ :attr:`exit_code` methods should only be called by the process that created the process object. - Example usage of some of the methods of :class:`Process`:: + Example usage of some of the methods of :class:`Process`: + + .. doctest:: >>> import multiprocessing, time, signal >>> p = multiprocessing.Process(target=time.sleep, args=(1000,)) @@ -426,6 +434,7 @@ >>> print(p, p.is_alive()) True >>> p.terminate() + >>> time.sleep(0.1) >>> print(p, p.is_alive()) False >>> p.exitcode == -signal.SIGTERM @@ -667,7 +676,7 @@ freeze_support() Process(target=f).start() - If the ``freeze_support()`` line is missed out then trying to run the frozen + If the ``freeze_support()`` line is omitted then trying to run the frozen executable will raise :exc:`RuntimeError`. If the module is being run normally by the Python interpreter then @@ -681,7 +690,7 @@ setExecutable(os.path.join(sys.exec_prefix, 'pythonw.exe')) - before they can create child processes. (Windows only) + before they can create child processes. (Windows only) .. note:: @@ -761,8 +770,8 @@ *buffer* must be an object satisfying the writable buffer interface. If *offset* is given then the message will be written into the buffer from - *that position. Offset must be a non-negative integer less than the - *length of *buffer* (in bytes). + that position. Offset must be a non-negative integer less than the + length of *buffer* (in bytes). If the buffer is too short then a :exc:`BufferTooShort` exception is raised and the complete message is available as ``e.args[0]`` where ``e`` @@ -771,6 +780,8 @@ For example: +.. doctest:: + >>> from multiprocessing import Pipe >>> a, b = Pipe() >>> a.send([1, 'hello', None]) @@ -857,8 +868,9 @@ specifies a timeout in seconds. If *block* is ``False`` then *timeout* is ignored. - Note that on OS/X ``sem_timedwait`` is unsupported, so timeout arguments - for these will be ignored. +.. note:: + On OS/X ``sem_timedwait`` is unsupported, so timeout arguments for the + aforementioned :meth:`acquire` methods will be ignored on OS/X. .. note:: @@ -1055,7 +1067,7 @@ lock = Lock() n = Value('i', 7) - x = Value(ctypes.c_double, 1.0/3.0, lock=False) + x = Value(c_double, 1.0/3.0, lock=False) s = Array('c', 'hello world', lock=lock) A = Array(Point, [(1.875,-6.25), (-5.75,2.0), (2.375,9.5)], lock=lock) @@ -1136,21 +1148,21 @@ Returns a :class:`Server` object which represents the actual server under the control of the Manager. The :class:`Server` object supports the - :meth:`serve_forever` method: + :meth:`serve_forever` method:: >>> from multiprocessing.managers import BaseManager - >>> m = BaseManager(address=('', 50000), authkey='abc')) - >>> server = m.get_server() - >>> s.serve_forever() + >>> manager = BaseManager(address=('', 50000), authkey='abc') + >>> server = manager.get_server() + >>> server.serve_forever() - :class:`Server` additionally have an :attr:`address` attribute. + :class:`Server` additionally has an :attr:`address` attribute. .. method:: connect() - Connect a local manager object to a remote manager process: + Connect a local manager object to a remote manager process:: >>> from multiprocessing.managers import BaseManager - >>> m = BaseManager(address='127.0.0.1', authkey='abc)) + >>> m = BaseManager(address=('127.0.0.1', 5000), authkey='abc') >>> m.connect() .. method:: shutdown() @@ -1278,7 +1290,9 @@ Its representation shows the values of its attributes. However, when using a proxy for a namespace object, an attribute beginning with -``'_'`` will be an attribute of the proxy and not an attribute of the referent:: +``'_'`` will be an attribute of the proxy and not an attribute of the referent: + +.. doctest:: >>> manager = multiprocessing.Manager() >>> Global = manager.Namespace() @@ -1330,17 +1344,15 @@ >>> import queue >>> queue = queue.Queue() >>> class QueueManager(BaseManager): pass - ... >>> QueueManager.register('get_queue', callable=lambda:queue) >>> m = QueueManager(address=('', 50000), authkey='abracadabra') >>> s = m.get_server() - >>> s.serveForever() + >>> s.serve_forever() One client can access the server as follows:: >>> from multiprocessing.managers import BaseManager >>> class QueueManager(BaseManager): pass - ... >>> QueueManager.register('get_queue') >>> m = QueueManager(address=('foo.bar.org', 50000), authkey='abracadabra') >>> m.connect() @@ -1351,10 +1363,10 @@ >>> from multiprocessing.managers import BaseManager >>> class QueueManager(BaseManager): pass - ... - >>> QueueManager.register('getQueue') - >>> m = QueueManager.from_address(address=('foo.bar.org', 50000), authkey='abracadabra') - >>> queue = m.getQueue() + >>> QueueManager.register('get_queue') + >>> m = QueueManager(address=('foo.bar.org', 50000), authkey='abracadabra') + >>> m.connect() + >>> queue = m.get_queue() >>> queue.get() 'hello' @@ -1390,7 +1402,9 @@ A proxy object has methods which invoke corresponding methods of its referent (although not every method of the referent will necessarily be available through the proxy). A proxy can usually be used in most of the same ways that its -referent can:: +referent can: + +.. doctest:: >>> from multiprocessing import Manager >>> manager = Manager() @@ -1398,7 +1412,7 @@ >>> print(l) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> print(repr(l)) - + >>> l[4] 16 >>> l[2:5] @@ -1411,7 +1425,9 @@ An important feature of proxy objects is that they are picklable so they can be passed between processes. Note, however, that if a proxy is sent to the corresponding manager's process then unpickling it will produce the referent -itself. This means, for example, that one shared object can contain a second:: +itself. This means, for example, that one shared object can contain a second: + +.. doctest:: >>> a = manager.list() >>> b = manager.list() @@ -1425,12 +1441,14 @@ .. note:: The proxy types in :mod:`multiprocessing` do nothing to support comparisons - by value. So, for instance, :: + by value. So, for instance, we have: + + .. doctest:: - manager.list([1,2,3]) == [1,2,3] + >>> manager.list([1,2,3]) == [1,2,3] + False - will return ``False``. One should just use a copy of the referent instead - when making comparisons. + One should just use a copy of the referent instead when making comparisons. .. class:: BaseProxy @@ -1462,7 +1480,9 @@ Note in particular that an exception will be raised if *methodname* has not been *exposed* - An example of the usage of :meth:`_callmethod`:: + An example of the usage of :meth:`_callmethod`: + + .. doctest:: >>> l = manager.list(range(10)) >>> l._callmethod('__len__') @@ -1873,13 +1893,55 @@ >>> logger.warning('doomed') [WARNING/MainProcess] doomed >>> m = multiprocessing.Manager() +<<<<<<< .working [INFO/SyncManager-1] child process calling self.run() [INFO/SyncManager-1] manager bound to '\\\\.\\pipe\\pyc-2776-0-lj0tfa' +======= + [INFO/SyncManager-...] child process calling self.run() + [INFO/SyncManager-...] created temp directory /.../pymp-... + [INFO/SyncManager-...] manager serving at '/.../listener-...' +>>>>>>> .merge-right.r72062 >>> del m [INFO/MainProcess] sending shutdown message to manager - [INFO/SyncManager-1] manager exiting with exitcode 0 + [INFO/SyncManager-...] manager exiting with exitcode 0 +<<<<<<< .working +======= ++----------------+----------------+ +| Level | Numeric value | ++================+================+ +| ``SUBWARNING`` | 25 | ++----------------+----------------+ +| ``SUBDEBUG`` | 5 | ++----------------+----------------+ + +For a full table of logging levels, see the :mod:`logging` module. + +These additional logging levels are used primarily for certain debug messages +within the multiprocessing module. Below is the same example as above, except +with :const:`SUBDEBUG` enabled:: + + >>> import multiprocessing, logging + >>> logger = multiprocessing.log_to_stderr() + >>> logger.setLevel(multiprocessing.SUBDEBUG) + >>> logger.warning('doomed') + [WARNING/MainProcess] doomed + >>> m = multiprocessing.Manager() + [INFO/SyncManager-...] child process calling self.run() + [INFO/SyncManager-...] created temp directory /.../pymp-... + [INFO/SyncManager-...] manager serving at '/.../pymp-djGBXN/listener-...' + >>> del m + [SUBDEBUG/MainProcess] finalizer calling ... + [INFO/MainProcess] sending shutdown message to manager + [DEBUG/SyncManager-...] manager received shutdown message + [SUBDEBUG/SyncManager-...] calling ... + [SUBDEBUG/SyncManager-...] calling + [SUBDEBUG/SyncManager-...] finalizer calling ... + [INFO/SyncManager-...] manager exiting with exitcode 0 + +>>>>>>> .merge-right.r72062 The :mod:`multiprocessing.dummy` module ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From python-checkins at python.org Tue Apr 28 20:10:49 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 28 Apr 2009 20:10:49 +0200 (CEST) Subject: [Python-checkins] r72065 - python/branches/release26-maint Message-ID: <20090428181049.74EBB1E417C@bag.python.org> Author: georg.brandl Date: Tue Apr 28 20:10:47 2009 New Revision: 72065 Log: Blocked revisions 71237 via svnmerge ........ r71237 | georg.brandl | 2009-04-05 16:24:52 +0200 (So, 05 Apr 2009) | 1 line #1326077: fix traceback formatting of SyntaxErrors. This fixes two differences with formatting coming from Python: a) the reproduction of location details in the error message if no line text is given, b) the prefixing of the last line by one space. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Tue Apr 28 20:11:53 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 28 Apr 2009 20:11:53 +0200 (CEST) Subject: [Python-checkins] r72066 - in python/branches/release26-maint: Doc/reference/expressions.rst Doc/tools/sphinxext/susp-ignored.csv Message-ID: <20090428181153.89FA61E401E@bag.python.org> Author: georg.brandl Date: Tue Apr 28 20:11:53 2009 New Revision: 72066 Log: Merged revisions 71397-71398,71441 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71397 | georg.brandl | 2009-04-08 18:36:39 +0200 (Mi, 08 Apr 2009) | 1 line Remove redundant backtick. ........ r71398 | georg.brandl | 2009-04-08 18:39:04 +0200 (Mi, 08 Apr 2009) | 1 line Update ignore file for suspicious builder. ........ r71441 | georg.brandl | 2009-04-10 10:16:47 +0200 (Fr, 10 Apr 2009) | 1 line Let "lambda" point to the correct heading. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/reference/expressions.rst python/branches/release26-maint/Doc/tools/sphinxext/susp-ignored.csv Modified: python/branches/release26-maint/Doc/reference/expressions.rst ============================================================================== --- python/branches/release26-maint/Doc/reference/expressions.rst (original) +++ python/branches/release26-maint/Doc/reference/expressions.rst Tue Apr 28 20:11:53 2009 @@ -1177,6 +1177,7 @@ .. _lambdas: +.. _lambda: Lambdas ======= @@ -1201,8 +1202,6 @@ See section :ref:`function` for the syntax of parameter lists. Note that functions created with lambda forms cannot contain statements. -.. _lambda: - .. _exprlists: Modified: python/branches/release26-maint/Doc/tools/sphinxext/susp-ignored.csv ============================================================================== --- python/branches/release26-maint/Doc/tools/sphinxext/susp-ignored.csv (original) +++ python/branches/release26-maint/Doc/tools/sphinxext/susp-ignored.csv Tue Apr 28 20:11:53 2009 @@ -48,6 +48,8 @@ library/httplib,,:port,host:port library/imaplib,,:MM,"""DD-Mmm-YYYY HH:MM:SS +HHMM""" library/imaplib,,:SS,"""DD-Mmm-YYYY HH:MM:SS +HHMM""" +library/itertools,,:stop,elements from seq[start:stop:step] +library/itertools,,:step,elements from seq[start:stop:step] library/linecache,,:sys,"sys:x:3:3:sys:/dev:/bin/sh" library/logging,,:And, library/logging,,:package1, From python-checkins at python.org Tue Apr 28 20:13:36 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 28 Apr 2009 20:13:36 +0200 (CEST) Subject: [Python-checkins] r72067 - python/branches/release26-maint Message-ID: <20090428181336.7A8081E4011@bag.python.org> Author: georg.brandl Date: Tue Apr 28 20:13:35 2009 New Revision: 72067 Log: Blocked revisions 69130,70647,70652,70770,70777,70788,71101,71405,71485,71492,71498,71503 via svnmerge ........ r69130 | andrew.kuchling | 2009-01-31 03:50:09 +0100 (Sa, 31 Jan 2009) | 1 line Add a section ........ r70647 | antoine.pitrou | 2009-03-28 20:10:13 +0100 (Sa, 28 M?r 2009) | 3 lines Publicize the GC untracking optimization ........ r70652 | antoine.pitrou | 2009-03-28 20:17:54 +0100 (Sa, 28 M?r 2009) | 3 lines Fix a typo and be more specific ........ r70770 | andrew.kuchling | 2009-03-31 00:30:20 +0200 (Di, 31 M?r 2009) | 1 line Add several items and placeholders ........ r70777 | andrew.kuchling | 2009-03-31 01:09:46 +0200 (Di, 31 M?r 2009) | 1 line Add more items ........ r70788 | andrew.kuchling | 2009-03-31 03:21:01 +0200 (Di, 31 M?r 2009) | 1 line Add various items ........ r71101 | andrew.kuchling | 2009-04-03 23:43:00 +0200 (Fr, 03 Apr 2009) | 1 line Add some items ........ r71405 | andrew.kuchling | 2009-04-09 13:22:47 +0200 (Do, 09 Apr 2009) | 1 line Add items ........ r71485 | andrew.kuchling | 2009-04-11 18:12:23 +0200 (Sa, 11 Apr 2009) | 1 line Add various items ........ r71492 | georg.brandl | 2009-04-11 20:19:27 +0200 (Sa, 11 Apr 2009) | 1 line Take credit for a patch of mine. ........ r71498 | benjamin.peterson | 2009-04-11 22:27:15 +0200 (Sa, 11 Apr 2009) | 1 line fix markup ........ r71503 | eric.smith | 2009-04-12 04:57:29 +0200 (So, 12 Apr 2009) | 1 line Take credit for my patch for issue 5237. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Tue Apr 28 20:14:13 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 28 Apr 2009 20:14:13 +0200 (CEST) Subject: [Python-checkins] r72068 - python/branches/release26-maint Message-ID: <20090428181413.209601E401E@bag.python.org> Author: georg.brandl Date: Tue Apr 28 20:14:12 2009 New Revision: 72068 Log: Blocked revisions 71507 via svnmerge ........ r71507 | georg.brandl | 2009-04-12 14:08:12 +0200 (So, 12 Apr 2009) | 1 line #5704: let python -3 imply -t as well. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Tue Apr 28 20:16:05 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 28 Apr 2009 20:16:05 +0200 (CEST) Subject: [Python-checkins] r72069 - in python/branches/release26-maint: Doc/library/email.charset.rst Doc/library/email.encoders.rst Doc/library/email.errors.rst Doc/library/email.generator.rst Doc/library/email.header.rst Doc/library/email.message.rst Doc/library/email.mime.rst Doc/library/email.parser.rst Doc/library/functions.rst Doc/library/turtle.rst Doc/reference/compound_stmts.rst Lib/optparse.py Message-ID: <20090428181605.3F7641E417F@bag.python.org> Author: georg.brandl Date: Tue Apr 28 20:16:02 2009 New Revision: 72069 Log: Merged revisions 71540,71544,71546,71563,71572,71607,71653 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71540 | georg.brandl | 2009-04-12 22:30:53 +0200 (So, 12 Apr 2009) | 1 line #5719: add short usage example to optparse docstring. ........ r71544 | benjamin.peterson | 2009-04-13 01:19:56 +0200 (Mo, 13 Apr 2009) | 1 line fix extra parenthesis #5774 ........ r71546 | benjamin.peterson | 2009-04-13 01:44:15 +0200 (Mo, 13 Apr 2009) | 1 line fix missing quote ........ r71563 | georg.brandl | 2009-04-13 14:36:18 +0200 (Mo, 13 Apr 2009) | 1 line Simplify markup. ........ r71572 | georg.brandl | 2009-04-13 15:13:25 +0200 (Mo, 13 Apr 2009) | 1 line #5745: more linking for identifiers in email docs. ........ r71607 | benjamin.peterson | 2009-04-14 23:23:09 +0200 (Di, 14 Apr 2009) | 1 line tupel -> tuple ........ r71653 | raymond.hettinger | 2009-04-16 20:16:10 +0200 (Do, 16 Apr 2009) | 1 line Clarify the behavior of any() and all() with an empty iterable. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/email.charset.rst python/branches/release26-maint/Doc/library/email.encoders.rst python/branches/release26-maint/Doc/library/email.errors.rst python/branches/release26-maint/Doc/library/email.generator.rst python/branches/release26-maint/Doc/library/email.header.rst python/branches/release26-maint/Doc/library/email.message.rst python/branches/release26-maint/Doc/library/email.mime.rst python/branches/release26-maint/Doc/library/email.parser.rst python/branches/release26-maint/Doc/library/functions.rst python/branches/release26-maint/Doc/library/turtle.rst python/branches/release26-maint/Doc/reference/compound_stmts.rst python/branches/release26-maint/Lib/optparse.py Modified: python/branches/release26-maint/Doc/library/email.charset.rst ============================================================================== --- python/branches/release26-maint/Doc/library/email.charset.rst (original) +++ python/branches/release26-maint/Doc/library/email.charset.rst Tue Apr 28 20:16:02 2009 @@ -163,8 +163,8 @@ charset to the output charset automatically. This is not useful for multibyte character sets, which have line length issues (multibyte characters must be split on a character, not a byte boundary); use the - higher-level :class:`Header` class to deal with these issues (see - :mod:`email.header`). *convert* defaults to ``False``. + higher-level :class:`~email.header.Header` class to deal with these issues + (see :mod:`email.header`). *convert* defaults to ``False``. The type of encoding (base64 or quoted-printable) will be based on the *header_encoding* attribute. Modified: python/branches/release26-maint/Doc/library/email.encoders.rst ============================================================================== --- python/branches/release26-maint/Doc/library/email.encoders.rst (original) +++ python/branches/release26-maint/Doc/library/email.encoders.rst Tue Apr 28 20:16:02 2009 @@ -5,18 +5,18 @@ :synopsis: Encoders for email message payloads. -When creating :class:`Message` objects from scratch, you often need to encode -the payloads for transport through compliant mail servers. This is especially -true for :mimetype:`image/\*` and :mimetype:`text/\*` type messages containing -binary data. +When creating :class:`~email.message.Message` objects from scratch, you often +need to encode the payloads for transport through compliant mail servers. This +is especially true for :mimetype:`image/\*` and :mimetype:`text/\*` type messages +containing binary data. The :mod:`email` package provides some convenient encodings in its :mod:`encoders` module. These encoders are actually used by the -:class:`MIMEAudio` and :class:`MIMEImage` class constructors to provide default -encodings. All encoder functions take exactly one argument, the message object -to encode. They usually extract the payload, encode it, and reset the payload -to this newly encoded value. They should also set the -:mailheader:`Content-Transfer-Encoding` header as appropriate. +:class:`~email.mime.audio.MIMEAudio` and :class:`~email.mime.image.MIMEImage` +class constructors to provide default encodings. All encoder functions take +exactly one argument, the message object to encode. They usually extract the +payload, encode it, and reset the payload to this newly encoded value. They +should also set the :mailheader:`Content-Transfer-Encoding` header as appropriate. Here are the encoding functions provided: Modified: python/branches/release26-maint/Doc/library/email.errors.rst ============================================================================== --- python/branches/release26-maint/Doc/library/email.errors.rst (original) +++ python/branches/release26-maint/Doc/library/email.errors.rst Tue Apr 28 20:16:02 2009 @@ -17,8 +17,8 @@ .. exception:: MessageParseError() - This is the base class for exceptions thrown by the :class:`Parser` class. It - is derived from :exc:`MessageError`. + This is the base class for exceptions thrown by the :class:`~email.parser.Parser` + class. It is derived from :exc:`MessageError`. .. exception:: HeaderParseError() @@ -55,11 +55,12 @@ Since :meth:`Message.add_payload` is deprecated, this exception is rarely raised in practice. However the exception may also be raised if the :meth:`attach` method is called on an instance of a class derived from - :class:`MIMENonMultipart` (e.g. :class:`MIMEImage`). + :class:`~email.mime.nonmultipart.MIMENonMultipart` (e.g. + :class:`~email.mime.image.MIMEImage`). -Here's the list of the defects that the :class:`FeedParser` can find while -parsing messages. Note that the defects are added to the message where the -problem was found, so for example, if a message nested inside a +Here's the list of the defects that the :class:`~email.mime.parser.FeedParser` +can find while parsing messages. Note that the defects are added to the message +where the problem was found, so for example, if a message nested inside a :mimetype:`multipart/alternative` had a malformed header, that nested message object would have a defect, but the containing messages would not. Modified: python/branches/release26-maint/Doc/library/email.generator.rst ============================================================================== --- python/branches/release26-maint/Doc/library/email.generator.rst (original) +++ python/branches/release26-maint/Doc/library/email.generator.rst Tue Apr 28 20:16:02 2009 @@ -16,8 +16,8 @@ yourself. However the bundled generator knows how to generate most email in a standards-compliant way, should handle MIME and non-MIME email messages just fine, and is designed so that the transformation from flat text, to a message -structure via the :class:`Parser` class, and back to flat text, is idempotent -(the input is identical to the output). +structure via the :class:`~email.parser.Parser` class, and back to flat text, +is idempotent (the input is identical to the output). Here are the public methods of the :class:`Generator` class, imported from the :mod:`email.generator` module: @@ -41,8 +41,8 @@ Optional *maxheaderlen* specifies the longest length for a non-continued header. When a header line is longer than *maxheaderlen* (in characters, with tabs expanded to 8 spaces), the header will be split as defined in the - :mod:`email.header.Header` class. Set to zero to disable header wrapping. The - default is 78, as recommended (but not required) by :rfc:`2822`. + :class:`~email.header.Header` class. Set to zero to disable header wrapping. + The default is 78, as recommended (but not required) by :rfc:`2822`. The other public :class:`Generator` methods are: Modified: python/branches/release26-maint/Doc/library/email.header.rst ============================================================================== --- python/branches/release26-maint/Doc/library/email.header.rst (original) +++ python/branches/release26-maint/Doc/library/email.header.rst Tue Apr 28 20:16:02 2009 @@ -21,10 +21,10 @@ If you want to include non-ASCII characters in your email headers, say in the :mailheader:`Subject` or :mailheader:`To` fields, you should use the -:class:`Header` class and assign the field in the :class:`Message` object to an -instance of :class:`Header` instead of using a string for the header value. -Import the :class:`Header` class from the :mod:`email.header` module. For -example:: +:class:`Header` class and assign the field in the :class:`~email.message.Message` +object to an instance of :class:`Header` instead of using a string for the header +value. Import the :class:`Header` class from the :mod:`email.header` module. +For example:: >>> from email.message import Message >>> from email.header import Header @@ -39,9 +39,9 @@ Notice here how we wanted the :mailheader:`Subject` field to contain a non-ASCII character? We did this by creating a :class:`Header` instance and passing in the character set that the byte string was encoded in. When the subsequent -:class:`Message` instance was flattened, the :mailheader:`Subject` field was -properly :rfc:`2047` encoded. MIME-aware mail readers would show this header -using the embedded ISO-8859-1 character. +:class:`~email.message.Message` instance was flattened, the :mailheader:`Subject` +field was properly :rfc:`2047` encoded. MIME-aware mail readers would show this +header using the embedded ISO-8859-1 character. .. versionadded:: 2.2.2 @@ -83,10 +83,11 @@ Append the string *s* to the MIME header. - Optional *charset*, if given, should be a :class:`Charset` instance (see - :mod:`email.charset`) or the name of a character set, which will be - converted to a :class:`Charset` instance. A value of ``None`` (the - default) means that the *charset* given in the constructor is used. + Optional *charset*, if given, should be a :class:`~email.charset.Charset` + instance (see :mod:`email.charset`) or the name of a character set, which + will be converted to a :class:`~email.charset.Charset` instance. A value + of ``None`` (the default) means that the *charset* given in the constructor + is used. *s* may be a byte string or a Unicode string. If it is a byte string (i.e. ``isinstance(s, str)`` is true), then *charset* is the encoding of Modified: python/branches/release26-maint/Doc/library/email.message.rst ============================================================================== --- python/branches/release26-maint/Doc/library/email.message.rst (original) +++ python/branches/release26-maint/Doc/library/email.message.rst Tue Apr 28 20:16:02 2009 @@ -45,8 +45,8 @@ Note that this method is provided as a convenience and may not always format the message the way you want. For example, by default it mangles lines that begin with ``From``. For more flexibility, instantiate a - :class:`Generator` instance and use its :meth:`flatten` method directly. - For example:: + :class:`~email.generator.Generator` instance and use its :meth:`flatten` + method directly. For example:: from cStringIO import StringIO from email.generator import Generator @@ -126,11 +126,12 @@ .. method:: set_charset(charset) Set the character set of the payload to *charset*, which can either be a - :class:`Charset` instance (see :mod:`email.charset`), a string naming a - character set, or ``None``. If it is a string, it will be converted to a - :class:`Charset` instance. If *charset* is ``None``, the ``charset`` - parameter will be removed from the :mailheader:`Content-Type` - header. Anything else will generate a :exc:`TypeError`. + :class:`~email.charset.Charset` instance (see :mod:`email.charset`), a + string naming a character set, or ``None``. If it is a string, it will + be converted to a :class:`~email.charset.Charset` instance. If *charset* + is ``None``, the ``charset`` parameter will be removed from the + :mailheader:`Content-Type` header. Anything else will generate a + :exc:`TypeError`. The message will be assumed to be of type :mimetype:`text/\*` encoded with *charset.input_charset*. It will be converted to *charset.output_charset* @@ -144,8 +145,8 @@ .. method:: get_charset() - Return the :class:`Charset` instance associated with the message's - payload. + Return the :class:`~email.charset.Charset` instance associated with the + message's payload. .. versionadded:: 2.2.2 @@ -478,7 +479,7 @@ that header has no ``charset`` parameter, *failobj* is returned. Note that this method differs from :meth:`get_charset` which returns the - :class:`Charset` instance for the default encoding of the message body. + :class:`~email.charset.Charset` instance for the default encoding of the message body. .. versionadded:: 2.2.2 @@ -534,10 +535,11 @@ text can become visible. The *preamble* attribute contains this leading extra-armor text for MIME - documents. When the :class:`Parser` discovers some text after the headers - but before the first boundary string, it assigns this text to the - message's *preamble* attribute. When the :class:`Generator` is writing - out the plain text representation of a MIME message, and it finds the + documents. When the :class:`~email.parser.Parser` discovers some text + after the headers but before the first boundary string, it assigns this + text to the message's *preamble* attribute. When the + :class:`~email.generator.Generator` is writing out the plain text + representation of a MIME message, and it finds the message has a *preamble* attribute, it will write this text in the area between the headers and the first boundary. See :mod:`email.parser` and :mod:`email.generator` for details. Modified: python/branches/release26-maint/Doc/library/email.mime.rst ============================================================================== --- python/branches/release26-maint/Doc/library/email.mime.rst (original) +++ python/branches/release26-maint/Doc/library/email.mime.rst Tue Apr 28 20:16:02 2009 @@ -8,14 +8,15 @@ Ordinarily, you get a message object structure by passing a file or some text to a parser, which parses the text and returns the root message object. However you can also build a complete message structure from scratch, or even individual -:class:`Message` objects by hand. In fact, you can also take an existing -structure and add new :class:`Message` objects, move them around, etc. This -makes a very convenient interface for slicing-and-dicing MIME messages. - -You can create a new object structure by creating :class:`Message` instances, -adding attachments and all the appropriate headers manually. For MIME messages -though, the :mod:`email` package provides some convenient subclasses to make -things easier. +:class:`~email.message.Message` objects by hand. In fact, you can also take an +existing structure and add new :class:`~email.message.Message` objects, move them +around, etc. This makes a very convenient interface for slicing-and-dicing MIME +messages. + +You can create a new object structure by creating :class:`~email.message.Message` +instances, adding attachments and all the appropriate headers manually. For MIME +messages though, the :mod:`email` package provides some convenient subclasses to +make things easier. Here are the classes: @@ -25,10 +26,11 @@ Module: :mod:`email.mime.base` - This is the base class for all the MIME-specific subclasses of :class:`Message`. - Ordinarily you won't create instances specifically of :class:`MIMEBase`, - although you could. :class:`MIMEBase` is provided primarily as a convenient - base class for more specific MIME-aware subclasses. + This is the base class for all the MIME-specific subclasses of + :class:`~email.message.Message`. Ordinarily you won't create instances + specifically of :class:`MIMEBase`, although you could. :class:`MIMEBase` + is provided primarily as a convenient base class for more specific + MIME-aware subclasses. *_maintype* is the :mailheader:`Content-Type` major type (e.g. :mimetype:`text` or :mimetype:`image`), and *_subtype* is the :mailheader:`Content-Type` minor @@ -46,11 +48,11 @@ Module: :mod:`email.mime.nonmultipart` - A subclass of :class:`MIMEBase`, this is an intermediate base class for MIME - messages that are not :mimetype:`multipart`. The primary purpose of this class - is to prevent the use of the :meth:`attach` method, which only makes sense for - :mimetype:`multipart` messages. If :meth:`attach` is called, a - :exc:`MultipartConversionError` exception is raised. + A subclass of :class:`~email.mime.base.MIMEBase`, this is an intermediate base + class for MIME messages that are not :mimetype:`multipart`. The primary + purpose of this class is to prevent the use of the :meth:`attach` method, + which only makes sense for :mimetype:`multipart` messages. If :meth:`attach` + is called, a :exc:`~email.errors.MultipartConversionError` exception is raised. .. versionadded:: 2.2.2 @@ -61,12 +63,12 @@ Module: :mod:`email.mime.multipart` - A subclass of :class:`MIMEBase`, this is an intermediate base class for MIME - messages that are :mimetype:`multipart`. Optional *_subtype* defaults to - :mimetype:`mixed`, but can be used to specify the subtype of the message. A - :mailheader:`Content-Type` header of :mimetype:`multipart/_subtype` will be - added to the message object. A :mailheader:`MIME-Version` header will also be - added. + A subclass of :class:`~email.mime.base.MIMEBase`, this is an intermediate base + class for MIME messages that are :mimetype:`multipart`. Optional *_subtype* + defaults to :mimetype:`mixed`, but can be used to specify the subtype of the + message. A :mailheader:`Content-Type` header of :mimetype:`multipart/_subtype` + will be added to the message object. A :mailheader:`MIME-Version` header will + also be added. Optional *boundary* is the multipart boundary string. When ``None`` (the default), the boundary is calculated when needed. @@ -88,10 +90,11 @@ Module: :mod:`email.mime.application` - A subclass of :class:`MIMENonMultipart`, the :class:`MIMEApplication` class is - used to represent MIME message objects of major type :mimetype:`application`. - *_data* is a string containing the raw byte data. Optional *_subtype* specifies - the MIME subtype and defaults to :mimetype:`octet-stream`. + A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the + :class:`MIMEApplication` class is used to represent MIME message objects of + major type :mimetype:`application`. *_data* is a string containing the raw + byte data. Optional *_subtype* specifies the MIME subtype and defaults to + :mimetype:`octet-stream`. Optional *_encoder* is a callable (i.e. function) which will perform the actual encoding of the data for transport. This callable takes one argument, which is @@ -112,13 +115,14 @@ Module: :mod:`email.mime.audio` - A subclass of :class:`MIMENonMultipart`, the :class:`MIMEAudio` class is used to - create MIME message objects of major type :mimetype:`audio`. *_audiodata* is a - string containing the raw audio data. If this data can be decoded by the - standard Python module :mod:`sndhdr`, then the subtype will be automatically - included in the :mailheader:`Content-Type` header. Otherwise you can explicitly - specify the audio subtype via the *_subtype* parameter. If the minor type could - not be guessed and *_subtype* was not given, then :exc:`TypeError` is raised. + A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the + :class:`MIMEAudio` class is used to create MIME message objects of major type + :mimetype:`audio`. *_audiodata* is a string containing the raw audio data. If + this data can be decoded by the standard Python module :mod:`sndhdr`, then the + subtype will be automatically included in the :mailheader:`Content-Type` header. + Otherwise you can explicitly specify the audio subtype via the *_subtype* + parameter. If the minor type could not be guessed and *_subtype* was not given, + then :exc:`TypeError` is raised. Optional *_encoder* is a callable (i.e. function) which will perform the actual encoding of the audio data for transport. This callable takes one argument, @@ -137,13 +141,14 @@ Module: :mod:`email.mime.image` - A subclass of :class:`MIMENonMultipart`, the :class:`MIMEImage` class is used to - create MIME message objects of major type :mimetype:`image`. *_imagedata* is a - string containing the raw image data. If this data can be decoded by the - standard Python module :mod:`imghdr`, then the subtype will be automatically - included in the :mailheader:`Content-Type` header. Otherwise you can explicitly - specify the image subtype via the *_subtype* parameter. If the minor type could - not be guessed and *_subtype* was not given, then :exc:`TypeError` is raised. + A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the + :class:`MIMEImage` class is used to create MIME message objects of major type + :mimetype:`image`. *_imagedata* is a string containing the raw image data. If + this data can be decoded by the standard Python module :mod:`imghdr`, then the + subtype will be automatically included in the :mailheader:`Content-Type` header. + Otherwise you can explicitly specify the image subtype via the *_subtype* + parameter. If the minor type could not be guessed and *_subtype* was not given, + then :exc:`TypeError` is raised. Optional *_encoder* is a callable (i.e. function) which will perform the actual encoding of the image data for transport. This callable takes one argument, @@ -153,7 +158,8 @@ object as necessary. The default encoding is base64. See the :mod:`email.encoders` module for a list of the built-in encoders. - *_params* are passed straight through to the :class:`MIMEBase` constructor. + *_params* are passed straight through to the :class:`~email.mime.base.MIMEBase` + constructor. .. currentmodule:: email.mime.message @@ -162,10 +168,11 @@ Module: :mod:`email.mime.message` - A subclass of :class:`MIMENonMultipart`, the :class:`MIMEMessage` class is used - to create MIME objects of main type :mimetype:`message`. *_msg* is used as the - payload, and must be an instance of class :class:`Message` (or a subclass - thereof), otherwise a :exc:`TypeError` is raised. + A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the + :class:`MIMEMessage` class is used to create MIME objects of main type + :mimetype:`message`. *_msg* is used as the payload, and must be an instance + of class :class:`~email.message.Message` (or a subclass thereof), otherwise + a :exc:`TypeError` is raised. Optional *_subtype* sets the subtype of the message; it defaults to :mimetype:`rfc822`. @@ -177,12 +184,13 @@ Module: :mod:`email.mime.text` - A subclass of :class:`MIMENonMultipart`, the :class:`MIMEText` class is used to - create MIME objects of major type :mimetype:`text`. *_text* is the string for - the payload. *_subtype* is the minor type and defaults to :mimetype:`plain`. - *_charset* is the character set of the text and is passed as a parameter to the - :class:`MIMENonMultipart` constructor; it defaults to ``us-ascii``. No guessing - or encoding is performed on the text data. + A subclass of :class:`~email.mime.nonmultipart.MIMENonMultipart`, the + :class:`MIMEText` class is used to create MIME objects of major type + :mimetype:`text`. *_text* is the string for the payload. *_subtype* is the + minor type and defaults to :mimetype:`plain`. *_charset* is the character + set of the text and is passed as a parameter to the + :class:`~email.mime.nonmultipart.MIMENonMultipart` constructor; it defaults + to ``us-ascii``. No guessing or encoding is performed on the text data. .. versionchanged:: 2.4 The previously deprecated *_encoding* argument has been removed. Encoding Modified: python/branches/release26-maint/Doc/library/email.parser.rst ============================================================================== --- python/branches/release26-maint/Doc/library/email.parser.rst (original) +++ python/branches/release26-maint/Doc/library/email.parser.rst Tue Apr 28 20:16:02 2009 @@ -6,18 +6,18 @@ Message object structures can be created in one of two ways: they can be created -from whole cloth by instantiating :class:`Message` objects and stringing them -together via :meth:`attach` and :meth:`set_payload` calls, or they can be -created by parsing a flat text representation of the email message. +from whole cloth by instantiating :class:`~email.message.Message` objects and +stringing them together via :meth:`attach` and :meth:`set_payload` calls, or they +can be created by parsing a flat text representation of the email message. The :mod:`email` package provides a standard parser that understands most email document structures, including MIME documents. You can pass the parser a string -or a file object, and the parser will return to you the root :class:`Message` -instance of the object structure. For simple, non-MIME messages the payload of -this root object will likely be a string containing the text of the message. -For MIME messages, the root object will return ``True`` from its -:meth:`is_multipart` method, and the subparts can be accessed via the -:meth:`get_payload` and :meth:`walk` methods. +or a file object, and the parser will return to you the root +:class:`~email.message.Message` instance of the object structure. For simple, +non-MIME messages the payload of this root object will likely be a string +containing the text of the message. For MIME messages, the root object will +return ``True`` from its :meth:`is_multipart` method, and the subparts can be +accessed via the :meth:`get_payload` and :meth:`walk` methods. There are actually two parser interfaces available for use, the classic :class:`Parser` API and the incremental :class:`FeedParser` API. The classic @@ -31,8 +31,8 @@ Note that the parser can be extended in limited ways, and of course you can implement your own parser completely from scratch. There is no magical connection between the :mod:`email` package's bundled parser and the -:class:`Message` class, so your custom parser can create message object trees -any way it finds necessary. +:class:`~email.message.Message` class, so your custom parser can create message +object trees any way it finds necessary. FeedParser API @@ -103,8 +103,8 @@ The constructor for the :class:`Parser` class takes an optional argument *_class*. This must be a callable factory (such as a function or a class), and it is used whenever a sub-message object needs to be created. It defaults to - :class:`Message` (see :mod:`email.message`). The factory will be called without - arguments. + :class:`~email.message.Message` (see :mod:`email.message`). The factory will + be called without arguments. The optional *strict* flag is ignored. @@ -199,7 +199,8 @@ * All :mimetype:`multipart` type messages will be parsed as a container message object with a list of sub-message objects for their payload. The outer container message will return ``True`` for :meth:`is_multipart` and their - :meth:`get_payload` method will return the list of :class:`Message` subparts. + :meth:`get_payload` method will return the list of :class:`~email.message.Message` + subparts. * Most messages with a content type of :mimetype:`message/\*` (e.g. :mimetype:`message/delivery-status` and :mimetype:`message/rfc822`) will also be Modified: python/branches/release26-maint/Doc/library/functions.rst ============================================================================== --- python/branches/release26-maint/Doc/library/functions.rst (original) +++ python/branches/release26-maint/Doc/library/functions.rst Tue Apr 28 20:16:02 2009 @@ -17,7 +17,8 @@ .. function:: all(iterable) - Return True if all elements of the *iterable* are true. Equivalent to:: + Return True if all elements of the *iterable* are true (or if the iterable + is empty). Equivalent to:: def all(iterable): for element in iterable: @@ -30,7 +31,8 @@ .. function:: any(iterable) - Return True if any element of the *iterable* is true. Equivalent to:: + Return True if any element of the *iterable* is true. If the iterable + is empty, return False. Equivalent to:: def any(iterable): for element in iterable: Modified: python/branches/release26-maint/Doc/library/turtle.rst ============================================================================== --- python/branches/release26-maint/Doc/library/turtle.rst (original) +++ python/branches/release26-maint/Doc/library/turtle.rst Tue Apr 28 20:16:02 2009 @@ -1244,9 +1244,9 @@ .. function:: screensize(canvwidth=None, canvheight=None, bg=None) - :param canvwidth: positive integer, new width of canvas in pixels - :param canvheight: positive integer, new height of canvas in pixels - :param bg: colorstring or color-tupel, new background color + :param canvwidth: positive integer, new width of canvas in pixels :param + canvheight: positive integer, new height of canvas in pixels :param bg: + colorstring or color-tuple, new background color If no arguments are given, return current (canvaswidth, canvasheight). Else resize the canvas the turtles are drawing on. Do not alter the drawing Modified: python/branches/release26-maint/Doc/reference/compound_stmts.rst ============================================================================== --- python/branches/release26-maint/Doc/reference/compound_stmts.rst (original) +++ python/branches/release26-maint/Doc/reference/compound_stmts.rst Tue Apr 28 20:16:02 2009 @@ -1,4 +1,3 @@ - .. _compound: ******************* @@ -195,12 +194,10 @@ inserts an item in the sequence before the current item, the current item will be treated again the next time through the loop. This can lead to nasty bugs that can be avoided by making a temporary copy using a slice of the whole - sequence, e.g., - -:: + sequence, e.g., :: - for x in a[:]: - if x < 0: a.remove(x) + for x in a[:]: + if x < 0: a.remove(x) .. _try: Modified: python/branches/release26-maint/Lib/optparse.py ============================================================================== --- python/branches/release26-maint/Lib/optparse.py (original) +++ python/branches/release26-maint/Lib/optparse.py Tue Apr 28 20:16:02 2009 @@ -6,6 +6,19 @@ For support, use the optik-users at lists.sourceforge.net mailing list (http://lists.sourceforge.net/lists/listinfo/optik-users). + +Simple usage example: + + from optparse import OptionParser + + parser = OptionParser() + parser.add_option("-f", "--file", dest="filename", + help="write report to FILE", metavar="FILE") + parser.add_option("-q", "--quiet", + action="store_false", dest="verbose", default=True, + help="don't print status messages to stdout") + + (options, args) = parser.parse_args() """ __version__ = "1.5.3" From python-checkins at python.org Tue Apr 28 20:16:33 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 28 Apr 2009 20:16:33 +0200 (CEST) Subject: [Python-checkins] r72070 - python/branches/release26-maint Message-ID: <20090428181633.CD5461E401E@bag.python.org> Author: georg.brandl Date: Tue Apr 28 20:16:33 2009 New Revision: 72070 Log: Blocked revisions 71696 via svnmerge ........ r71696 | georg.brandl | 2009-04-18 10:26:21 +0200 (Sa, 18 Apr 2009) | 1 line "not subscriptable" should be a bit more understandable than "unsubscriptable". ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Tue Apr 28 20:18:54 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 28 Apr 2009 20:18:54 +0200 (CEST) Subject: [Python-checkins] r72071 - in python/branches/release26-maint: Doc/includes/mp_distributing.py Doc/library/__future__.rst Doc/library/functions.rst Doc/library/json.rst Doc/library/tarfile.rst Doc/library/threading.rst Doc/library/turtle.rst Doc/reference/simple_stmts.rst Message-ID: <20090428181854.146B31E401E@bag.python.org> Author: georg.brandl Date: Tue Apr 28 20:18:53 2009 New Revision: 72071 Log: Merged revisions 71786-71787,71814-71817,71901-71903 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71786 | georg.brandl | 2009-04-21 20:23:08 +0200 (Di, 21 Apr 2009) | 1 line #5757: fix copy-paste error in notify(). ........ r71787 | georg.brandl | 2009-04-21 20:24:34 +0200 (Di, 21 Apr 2009) | 1 line #5751: fix escaping of \\n. ........ r71814 | georg.brandl | 2009-04-23 10:44:57 +0200 (Do, 23 Apr 2009) | 1 line #5820: fix bug in usage of getreader(). ........ r71815 | georg.brandl | 2009-04-23 10:49:39 +0200 (Do, 23 Apr 2009) | 1 line Fix rewrapping accident. ........ r71816 | georg.brandl | 2009-04-23 10:49:56 +0200 (Do, 23 Apr 2009) | 1 line #5813: add a reference to the "future statements" section. ........ r71817 | georg.brandl | 2009-04-23 10:52:03 +0200 (Do, 23 Apr 2009) | 1 line Add link to PEP 236. ........ r71901 | georg.brandl | 2009-04-25 16:50:25 +0200 (Sa, 25 Apr 2009) | 1 line #3320: fix spelling. ........ r71902 | georg.brandl | 2009-04-25 16:51:31 +0200 (Sa, 25 Apr 2009) | 1 line #5834: use "failure" instead of "error" because the two have different meanings in unittest context. ........ r71903 | georg.brandl | 2009-04-25 17:05:04 +0200 (Sa, 25 Apr 2009) | 1 line #5821: add some capabilities of TarFile's file-like object. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/includes/mp_distributing.py python/branches/release26-maint/Doc/library/__future__.rst python/branches/release26-maint/Doc/library/functions.rst python/branches/release26-maint/Doc/library/json.rst python/branches/release26-maint/Doc/library/tarfile.rst python/branches/release26-maint/Doc/library/threading.rst python/branches/release26-maint/Doc/library/turtle.rst python/branches/release26-maint/Doc/reference/simple_stmts.rst Modified: python/branches/release26-maint/Doc/includes/mp_distributing.py ============================================================================== --- python/branches/release26-maint/Doc/includes/mp_distributing.py (original) +++ python/branches/release26-maint/Doc/includes/mp_distributing.py Tue Apr 28 20:18:53 2009 @@ -38,7 +38,7 @@ return _logger _logger = logging.getLogger('distributing') -_logger.propogate = 0 +_logger.propagate = 0 _formatter = logging.Formatter(util.DEFAULT_LOGGING_FORMAT) _handler = logging.StreamHandler() Modified: python/branches/release26-maint/Doc/library/__future__.rst ============================================================================== --- python/branches/release26-maint/Doc/library/__future__.rst (original) +++ python/branches/release26-maint/Doc/library/__future__.rst Tue Apr 28 20:18:53 2009 @@ -58,3 +58,7 @@ No feature description will ever be deleted from :mod:`__future__`. +.. seealso:: + + :ref:`future` + How the compiler treats future imports. Modified: python/branches/release26-maint/Doc/library/functions.rst ============================================================================== --- python/branches/release26-maint/Doc/library/functions.rst (original) +++ python/branches/release26-maint/Doc/library/functions.rst Tue Apr 28 20:18:53 2009 @@ -815,7 +815,7 @@ accidents.) -.. function:: print([object, ...][, sep=' '][, end='\n'][, file=sys.stdout]) +.. function:: print([object, ...][, sep=' '][, end='\\n'][, file=sys.stdout]) Print *object*\(s) to the stream *file*, separated by *sep* and followed by *end*. *sep*, *end* and *file*, if present, must be given as keyword Modified: python/branches/release26-maint/Doc/library/json.rst ============================================================================== --- python/branches/release26-maint/Doc/library/json.rst (original) +++ python/branches/release26-maint/Doc/library/json.rst Tue Apr 28 20:18:53 2009 @@ -174,7 +174,7 @@ If the contents of *fp* are encoded with an ASCII based encoding other than UTF-8 (e.g. latin-1), then an appropriate *encoding* name must be specified. Encodings that are not ASCII based (such as UCS-2) are not allowed, and - should be wrapped with ``codecs.getreader(fp)(encoding)``, or simply decoded + should be wrapped with ``codecs.getreader(encoding)(fp)``, or simply decoded to a :class:`unicode` object and passed to :func:`loads`. *object_hook* is an optional function that will be called with the result of Modified: python/branches/release26-maint/Doc/library/tarfile.rst ============================================================================== --- python/branches/release26-maint/Doc/library/tarfile.rst (original) +++ python/branches/release26-maint/Doc/library/tarfile.rst Tue Apr 28 20:18:53 2009 @@ -384,8 +384,9 @@ .. note:: - The file-like object is read-only and provides the following methods: - :meth:`read`, :meth:`readline`, :meth:`readlines`, :meth:`seek`, :meth:`tell`. + The file-like object is read-only. It provides the methods + :meth:`read`, :meth:`readline`, :meth:`readlines`, :meth:`seek`, :meth:`tell`, + and :meth:`close`, and also supports iteration over its lines. .. method:: TarFile.add(name, arcname=None, recursive=True, exclude=None) Modified: python/branches/release26-maint/Doc/library/threading.rst ============================================================================== --- python/branches/release26-maint/Doc/library/threading.rst (original) +++ python/branches/release26-maint/Doc/library/threading.rst Tue Apr 28 20:18:53 2009 @@ -555,12 +555,12 @@ .. method:: Condition.notify() - Wake up a thread waiting on this condition, if any. Wait until notified or until - a timeout occurs. If the calling thread has not acquired the lock when this - method is called, a :exc:`RuntimeError` is raised. + Wake up a thread waiting on this condition, if any. If the calling thread + has not acquired the lock when this method is called, a :exc:`RuntimeError` + is raised. - This method wakes up one of the threads waiting for the condition variable, if - any are waiting; it is a no-op if no threads are waiting. + This method wakes up one of the threads waiting for the condition variable, + if any are waiting; it is a no-op if no threads are waiting. The current implementation wakes up exactly one thread, if any are waiting. However, it's not safe to rely on this behavior. A future, optimized Modified: python/branches/release26-maint/Doc/library/turtle.rst ============================================================================== --- python/branches/release26-maint/Doc/library/turtle.rst (original) +++ python/branches/release26-maint/Doc/library/turtle.rst Tue Apr 28 20:18:53 2009 @@ -1244,9 +1244,9 @@ .. function:: screensize(canvwidth=None, canvheight=None, bg=None) - :param canvwidth: positive integer, new width of canvas in pixels :param - canvheight: positive integer, new height of canvas in pixels :param bg: - colorstring or color-tuple, new background color + :param canvwidth: positive integer, new width of canvas in pixels + :param canvheight: positive integer, new height of canvas in pixels + :param bg: colorstring or color-tuple, new background color If no arguments are given, return current (canvaswidth, canvasheight). Else resize the canvas the turtles are drawing on. Do not alter the drawing Modified: python/branches/release26-maint/Doc/reference/simple_stmts.rst ============================================================================== --- python/branches/release26-maint/Doc/reference/simple_stmts.rst (original) +++ python/branches/release26-maint/Doc/reference/simple_stmts.rst Tue Apr 28 20:18:53 2009 @@ -907,6 +907,11 @@ a future statement, it will be in effect in the interactive session started after the script is executed. +.. seealso:: + + :pep:`236` - Back to the __future__ + The original proposal for the __future__ mechanism. + .. _global: From python-checkins at python.org Tue Apr 28 20:19:43 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 28 Apr 2009 20:19:43 +0200 (CEST) Subject: [Python-checkins] r72072 - python/branches/release26-maint Message-ID: <20090428181943.96F291E4024@bag.python.org> Author: georg.brandl Date: Tue Apr 28 20:19:43 2009 New Revision: 72072 Log: Blocked revisions 71904,71955 via svnmerge ........ r71904 | georg.brandl | 2009-04-25 17:11:29 +0200 (Sa, 25 Apr 2009) | 1 line #5841: add deprecation py3k warning and notice in the docs for commands module. ........ r71955 | georg.brandl | 2009-04-26 08:01:04 +0200 (So, 26 Apr 2009) | 1 line Mostly formatting nits, and "and-ed together" -> "or-ed together" flags. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Tue Apr 28 20:20:25 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 28 Apr 2009 20:20:25 +0200 (CEST) Subject: [Python-checkins] r72073 - in python/branches/release26-maint: Doc/Makefile Doc/README.txt Doc/TODO.txt Message-ID: <20090428182025.295331E4024@bag.python.org> Author: georg.brandl Date: Tue Apr 28 20:20:24 2009 New Revision: 72073 Log: Merged revisions 71956-71959 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71956 | georg.brandl | 2009-04-26 08:05:18 +0200 (So, 26 Apr 2009) | 1 line Update versions in instructions for manual set-up. ........ r71957 | georg.brandl | 2009-04-26 08:05:58 +0200 (So, 26 Apr 2009) | 2 lines Note that the versions are also in README.txt. ........ r71958 | georg.brandl | 2009-04-26 08:06:19 +0200 (So, 26 Apr 2009) | 1 line Remove outdated TODO file. ........ r71959 | georg.brandl | 2009-04-26 08:06:53 +0200 (So, 26 Apr 2009) | 2 lines Another file where the versions need to be up to date. ........ Removed: python/branches/release26-maint/Doc/TODO.txt Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/Makefile python/branches/release26-maint/Doc/README.txt Modified: python/branches/release26-maint/Doc/Makefile ============================================================================== --- python/branches/release26-maint/Doc/Makefile (original) +++ python/branches/release26-maint/Doc/Makefile Tue Apr 28 20:20:24 2009 @@ -29,6 +29,7 @@ @echo " dist to create a \"dist\" directory with archived docs for download" checkout: + # Note: if you update versions here, do the same in make.bat and README.txt @if [ ! -d tools/sphinx ]; then \ echo "Checking out Sphinx..."; \ svn checkout $(SVNROOT)/external/Sphinx-0.6.1/sphinx tools/sphinx; \ Modified: python/branches/release26-maint/Doc/README.txt ============================================================================== --- python/branches/release26-maint/Doc/README.txt (original) +++ python/branches/release26-maint/Doc/README.txt Tue Apr 28 20:20:24 2009 @@ -74,17 +74,23 @@ You'll need to checkout the Sphinx package to the `tools/` directory:: - svn co http://svn.python.org/projects/doctools/trunk/sphinx tools/sphinx + svn co http://svn.python.org/projects/external/Sphinx-0.6.1/sphinx tools/sphinx Then, you need to install Docutils, either by checking it out via :: - svn co http://svn.python.org/projects/external/docutils-0.4/docutils tools/docutils + svn co http://svn.python.org/projects/external/docutils-0.5/docutils tools/docutils or by installing it from http://docutils.sf.net/. +You also need Jinja2, either by checking it out via :: + + svn co http://svn.python.org/projects/external/Jinja-2.1.1/jinja2 tools/jinja2 + +or by installing it from PyPI. + You can optionally also install Pygments, either as a checkout via :: - svn co http://svn.python.org/projects/external/Pygments-0.9/pygments tools/pygments + svn co http://svn.python.org/projects/external/Pygments-0.11.1/pygments tools/pygments or from PyPI at http://pypi.python.org/pypi/Pygments. Deleted: python/branches/release26-maint/Doc/TODO.txt ============================================================================== --- python/branches/release26-maint/Doc/TODO.txt Tue Apr 28 20:20:24 2009 +++ (empty file) @@ -1,6 +0,0 @@ -To do -===== - -* split very large files and add toctrees -* finish "Documenting Python" -* care about XXX comments From python-checkins at python.org Tue Apr 28 20:20:48 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 28 Apr 2009 20:20:48 +0200 (CEST) Subject: [Python-checkins] r72074 - python/branches/release26-maint Message-ID: <20090428182048.98B161E4024@bag.python.org> Author: georg.brandl Date: Tue Apr 28 20:20:48 2009 New Revision: 72074 Log: Blocked revisions 71960-71961 via svnmerge ........ r71960 | georg.brandl | 2009-04-26 11:56:44 +0200 (So, 26 Apr 2009) | 1 line Move pydoc_topics module to its own subdirectory, so that no generated code is in Lib/. ........ r71961 | georg.brandl | 2009-04-26 11:57:29 +0200 (So, 26 Apr 2009) | 2 lines Update pydoc topics. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Tue Apr 28 20:23:29 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 28 Apr 2009 20:23:29 +0200 (CEST) Subject: [Python-checkins] r72075 - in python/branches/release26-maint: Doc/c-api/init.rst Doc/c-api/intro.rst Doc/distutils/apiref.rst Doc/documenting/markup.rst Doc/extending/extending.rst Doc/library/2to3.rst Doc/library/aepack.rst Doc/library/aetools.rst Doc/library/aetypes.rst Doc/library/aifc.rst Doc/library/autogil.rst Doc/library/bastion.rst Doc/library/binhex.rst Doc/library/carbon.rst Doc/library/codeop.rst Doc/library/colorpicker.rst Doc/library/commands.rst Doc/library/configparser.rst Doc/library/easydialogs.rst Doc/library/fileinput.rst Doc/library/framework.rst Doc/library/functions.rst Doc/library/gl.rst Doc/library/hotshot.rst Doc/library/httplib.rst Doc/library/ic.rst Doc/library/inspect.rst Doc/library/locale.rst Doc/library/mac.rst Doc/library/macos.rst Doc/library/macostools.rst Doc/library/marshal.rst Doc/library/os.path.rst Doc/library/pickle.rst Doc/library/plistlib.rst Doc/library/rexec.rst Doc/library/string.rst Doc/library/subprocess.rst Doc/library/tabnanny.rst Doc/library/traceback.rst Doc/library/undoc.rst Doc/reference/compound_stmts.rst Doc/reference/executionmodel.rst Doc/using/cmdline.rst Message-ID: <20090428182329.DE5DC1E4011@bag.python.org> Author: georg.brandl Date: Tue Apr 28 20:23:28 2009 New Revision: 72075 Log: Merged revisions 72007-72010,72036-72037 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72007 | georg.brandl | 2009-04-27 17:09:25 +0200 (Mo, 27 Apr 2009) | 1 line #5856: fix typo s in traceback example. ........ r72008 | georg.brandl | 2009-04-27 17:10:44 +0200 (Mo, 27 Apr 2009) | 1 line Remove ".. warning::" markup that doesnt contain warnings for users, rather todo items. ........ r72009 | georg.brandl | 2009-04-27 17:29:09 +0200 (Mo, 27 Apr 2009) | 3 lines Demote warnings to notices where appropriate, following the goal that as few "red box" warnings should clutter the docs as possible. Part 1: stuff that gets merged to Py3k. ........ r72010 | georg.brandl | 2009-04-27 17:29:26 +0200 (Mo, 27 Apr 2009) | 2 lines Demote warnings to notices, part 2: stuff that is 2.x-only. ........ r72036 | georg.brandl | 2009-04-27 19:04:23 +0200 (Mo, 27 Apr 2009) | 1 line #5848: small unittest doc patch. ........ r72037 | georg.brandl | 2009-04-27 19:09:53 +0200 (Mo, 27 Apr 2009) | 1 line #5840: dont claim we dont support TLS. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/c-api/init.rst python/branches/release26-maint/Doc/c-api/intro.rst python/branches/release26-maint/Doc/distutils/apiref.rst python/branches/release26-maint/Doc/documenting/markup.rst python/branches/release26-maint/Doc/extending/extending.rst python/branches/release26-maint/Doc/library/2to3.rst python/branches/release26-maint/Doc/library/aepack.rst python/branches/release26-maint/Doc/library/aetools.rst python/branches/release26-maint/Doc/library/aetypes.rst python/branches/release26-maint/Doc/library/aifc.rst python/branches/release26-maint/Doc/library/autogil.rst python/branches/release26-maint/Doc/library/bastion.rst python/branches/release26-maint/Doc/library/binhex.rst python/branches/release26-maint/Doc/library/carbon.rst python/branches/release26-maint/Doc/library/codeop.rst python/branches/release26-maint/Doc/library/colorpicker.rst python/branches/release26-maint/Doc/library/commands.rst python/branches/release26-maint/Doc/library/configparser.rst python/branches/release26-maint/Doc/library/easydialogs.rst python/branches/release26-maint/Doc/library/fileinput.rst python/branches/release26-maint/Doc/library/framework.rst python/branches/release26-maint/Doc/library/functions.rst python/branches/release26-maint/Doc/library/gl.rst python/branches/release26-maint/Doc/library/hotshot.rst python/branches/release26-maint/Doc/library/httplib.rst python/branches/release26-maint/Doc/library/ic.rst python/branches/release26-maint/Doc/library/inspect.rst python/branches/release26-maint/Doc/library/locale.rst python/branches/release26-maint/Doc/library/mac.rst python/branches/release26-maint/Doc/library/macos.rst python/branches/release26-maint/Doc/library/macostools.rst python/branches/release26-maint/Doc/library/marshal.rst python/branches/release26-maint/Doc/library/os.path.rst python/branches/release26-maint/Doc/library/pickle.rst python/branches/release26-maint/Doc/library/plistlib.rst python/branches/release26-maint/Doc/library/rexec.rst python/branches/release26-maint/Doc/library/string.rst python/branches/release26-maint/Doc/library/subprocess.rst python/branches/release26-maint/Doc/library/tabnanny.rst python/branches/release26-maint/Doc/library/traceback.rst python/branches/release26-maint/Doc/library/undoc.rst python/branches/release26-maint/Doc/reference/compound_stmts.rst python/branches/release26-maint/Doc/reference/executionmodel.rst python/branches/release26-maint/Doc/using/cmdline.rst Modified: python/branches/release26-maint/Doc/c-api/init.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/init.rst (original) +++ python/branches/release26-maint/Doc/c-api/init.rst Tue Apr 28 20:23:28 2009 @@ -419,10 +419,9 @@ The Python interpreter needs to keep some bookkeeping information separate per thread --- for this it uses a data structure called :ctype:`PyThreadState`. There's one global variable, however: the pointer to the current -:ctype:`PyThreadState` structure. While most thread packages have a way to -store "per-thread global data," Python's internal platform independent thread -abstraction doesn't support this yet. Therefore, the current thread state must -be manipulated explicitly. +:ctype:`PyThreadState` structure. Before the addition of :dfn:`thread-local +storage` (:dfn:`TLS`) the current thread state had to be manipulated +explicitly. This is easy enough in most cases. Most code manipulating the global interpreter lock has the following simple structure:: Modified: python/branches/release26-maint/Doc/c-api/intro.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/intro.rst (original) +++ python/branches/release26-maint/Doc/c-api/intro.rst Tue Apr 28 20:23:28 2009 @@ -44,7 +44,7 @@ ````, ````, ````, and ```` (if available). -.. warning:: +.. note:: Since Python may define some pre-processor definitions which affect the standard headers on some systems, you *must* include :file:`Python.h` before any standard Modified: python/branches/release26-maint/Doc/distutils/apiref.rst ============================================================================== --- python/branches/release26-maint/Doc/distutils/apiref.rst (original) +++ python/branches/release26-maint/Doc/distutils/apiref.rst Tue Apr 28 20:23:28 2009 @@ -886,9 +886,7 @@ prefix of all files and directories in the archive. *root_dir* and *base_dir* both default to the current directory. Returns the name of the archive file. - .. warning:: - - This should be changed to support bz2 files + .. XXX This should be changed to support bz2 files. .. function:: make_tarball(base_name, base_dir[, compress='gzip', verbose=0, dry_run=0]) @@ -901,9 +899,7 @@ possibly plus the appropriate compression extension (:file:`.gz`, :file:`.bz2` or :file:`.Z`). Return the output filename. - .. warning:: - - This should be replaced with calls to the :mod:`tarfile` module. + .. XXX This should be replaced with calls to the :mod:`tarfile` module. .. function:: make_zipfile(base_name, base_dir[, verbose=0, dry_run=0]) @@ -1346,10 +1342,8 @@ Wraps *text* to less than *width* wide. - .. warning:: - - Should be replaced with :mod:`textwrap` (which is available in Python 2.3 and - later). + .. XXX Should be replaced with :mod:`textwrap` (which is available in Python + 2.3 and later). .. class:: FancyGetopt([option_table=None]) @@ -1398,8 +1392,8 @@ ================================================ .. module:: distutils.filelist - :synopsis: The FileList class, used for poking about the file system and building lists of - files. + :synopsis: The FileList class, used for poking about the file system and + building lists of files. This module provides the :class:`FileList` class, used for poking about the @@ -1413,13 +1407,8 @@ :synopsis: A simple logging mechanism, 282-style -.. warning:: - - Should be replaced with standard :mod:`logging` module. +.. XXX Should be replaced with standard :mod:`logging` module. -.. % \subsubsection{\module{} --- } -.. % \declaremodule{standard}{distutils.magic} -.. % \modulesynopsis{ } :mod:`distutils.spawn` --- Spawn a sub-process Modified: python/branches/release26-maint/Doc/documenting/markup.rst ============================================================================== --- python/branches/release26-maint/Doc/documenting/markup.rst (original) +++ python/branches/release26-maint/Doc/documenting/markup.rst Tue Apr 28 20:23:28 2009 @@ -594,11 +594,11 @@ .. describe:: warning - An important bit of information about an API that a user should be very aware - of when using whatever bit of API the warning pertains to. The content of - the directive should be written in complete sentences and include all - appropriate punctuation. This differs from ``note`` in that it is recommended - over ``note`` for information regarding security. + An important bit of information about an API that a user should be aware of + when using whatever bit of API the warning pertains to. The content of the + directive should be written in complete sentences and include all appropriate + punctuation. This should only be chosen over ``note`` for information + regarding the possibility of crashes, data loss, or security implications. .. describe:: versionadded Modified: python/branches/release26-maint/Doc/extending/extending.rst ============================================================================== --- python/branches/release26-maint/Doc/extending/extending.rst (original) +++ python/branches/release26-maint/Doc/extending/extending.rst Tue Apr 28 20:23:28 2009 @@ -47,7 +47,7 @@ which pulls in the Python API (you can add a comment describing the purpose of the module and a copyright notice if you like). -.. warning:: +.. note:: Since Python may define some pre-processor definitions which affect the standard headers on some systems, you *must* include :file:`Python.h` before any standard Modified: python/branches/release26-maint/Doc/library/2to3.rst ============================================================================== --- python/branches/release26-maint/Doc/library/2to3.rst (original) +++ python/branches/release26-maint/Doc/library/2to3.rst Tue Apr 28 20:23:28 2009 @@ -101,7 +101,7 @@ .. moduleauthor:: Collin Winter -.. warning:: +.. note:: The :mod:`lib2to3` API should be considered unstable and may change drastically in the future. Modified: python/branches/release26-maint/Doc/library/aepack.rst ============================================================================== --- python/branches/release26-maint/Doc/library/aepack.rst (original) +++ python/branches/release26-maint/Doc/library/aepack.rst Tue Apr 28 20:23:28 2009 @@ -14,9 +14,9 @@ AppleEvent descriptor is handled by Python objects of built-in type :class:`AEDesc`, defined in module :mod:`Carbon.AE`. -.. warning:: +.. note:: - This module is removed in 3.0. + This module has been removed in Python 3.x. The :mod:`aepack` module defines the following functions: Modified: python/branches/release26-maint/Doc/library/aetools.rst ============================================================================== --- python/branches/release26-maint/Doc/library/aetools.rst (original) +++ python/branches/release26-maint/Doc/library/aetools.rst Tue Apr 28 20:23:28 2009 @@ -22,9 +22,9 @@ manager, see section :ref:`osx-gui-scripts` for details. This restriction may be lifted in future releases. -.. warning:: +.. note:: - This module is removed in 3.0. + This module has been removed in Python 3.x. The :mod:`aetools` module defines the following functions: Modified: python/branches/release26-maint/Doc/library/aetypes.rst ============================================================================== --- python/branches/release26-maint/Doc/library/aetypes.rst (original) +++ python/branches/release26-maint/Doc/library/aetypes.rst Tue Apr 28 20:23:28 2009 @@ -31,9 +31,9 @@ contains object specifiers for a number of common OSA classes such as ``Document``, ``Window``, ``Character``, etc. -.. warning:: +.. note:: - This module is removed in 3.0. + This module has been removed in Python 3.x. Modified: python/branches/release26-maint/Doc/library/aifc.rst ============================================================================== --- python/branches/release26-maint/Doc/library/aifc.rst (original) +++ python/branches/release26-maint/Doc/library/aifc.rst Tue Apr 28 20:23:28 2009 @@ -1,4 +1,3 @@ - :mod:`aifc` --- Read and write AIFF and AIFC files ================================================== @@ -16,10 +15,11 @@ samples in a file. AIFF-C is a newer version of the format that includes the ability to compress the audio data. -.. warning:: +.. note:: Some operations may only work under IRIX; these will raise :exc:`ImportError` - when attempting to import the :mod:`cl` module, which is only available on IRIX. + when attempting to import the :mod:`cl` module, which is only available on + IRIX. Audio files have a number of parameters that describe the audio data. The sampling rate or frame rate is the number of times per second the sound is Modified: python/branches/release26-maint/Doc/library/autogil.rst ============================================================================== --- python/branches/release26-maint/Doc/library/autogil.rst (original) +++ python/branches/release26-maint/Doc/library/autogil.rst Tue Apr 28 20:23:28 2009 @@ -13,9 +13,9 @@ automatically locks and unlocks Python's :term:`Global Interpreter Lock` when running an event loop. -.. warning:: +.. note:: - This module has been removed in 3.0. + This module has been removed in Python 3.x. .. exception:: AutoGILError Modified: python/branches/release26-maint/Doc/library/bastion.rst ============================================================================== --- python/branches/release26-maint/Doc/library/bastion.rst (original) +++ python/branches/release26-maint/Doc/library/bastion.rst Tue Apr 28 20:23:28 2009 @@ -15,7 +15,7 @@ .. versionchanged:: 2.3 Disabled module. -.. warning:: +.. note:: The documentation has been left in place to help in reading old code that uses the module. Modified: python/branches/release26-maint/Doc/library/binhex.rst ============================================================================== --- python/branches/release26-maint/Doc/library/binhex.rst (original) +++ python/branches/release26-maint/Doc/library/binhex.rst Tue Apr 28 20:23:28 2009 @@ -1,4 +1,3 @@ - :mod:`binhex` --- Encode and decode binhex4 files ================================================= @@ -11,9 +10,9 @@ file and the finder information are encoded (or decoded), on other platforms only the data fork is handled. -.. warning:: +.. note:: - In 3.0, special Macintosh support is removed. + In Python 3.x, special Macintosh support has been removed. The :mod:`binhex` module defines the following functions: Modified: python/branches/release26-maint/Doc/library/carbon.rst ============================================================================== --- python/branches/release26-maint/Doc/library/carbon.rst (original) +++ python/branches/release26-maint/Doc/library/carbon.rst Tue Apr 28 20:23:28 2009 @@ -22,9 +22,9 @@ from Carbon import AE -.. warning:: +.. note:: - The Carbon modules are removed in 3.0. + The Carbon modules have been removed in Python 3.0. :mod:`Carbon.AE` --- Apple Events Modified: python/branches/release26-maint/Doc/library/codeop.rst ============================================================================== --- python/branches/release26-maint/Doc/library/codeop.rst (original) +++ python/branches/release26-maint/Doc/library/codeop.rst Tue Apr 28 20:23:28 2009 @@ -42,7 +42,7 @@ (``'single'``, the default) or as an :term:`expression` (``'eval'``). Any other value will cause :exc:`ValueError` to be raised. - .. warning:: + .. note:: It is possible (but not likely) that the parser stops parsing with a successful outcome before reaching the end of the source; in this case, Modified: python/branches/release26-maint/Doc/library/colorpicker.rst ============================================================================== --- python/branches/release26-maint/Doc/library/colorpicker.rst (original) +++ python/branches/release26-maint/Doc/library/colorpicker.rst Tue Apr 28 20:23:28 2009 @@ -13,9 +13,9 @@ The :mod:`ColorPicker` module provides access to the standard color picker dialog. -.. warning:: +.. note:: - This module is removed in 3.0. + This module has been removed in Python 3.x. .. function:: GetColor(prompt, rgb) Modified: python/branches/release26-maint/Doc/library/commands.rst ============================================================================== --- python/branches/release26-maint/Doc/library/commands.rst (original) +++ python/branches/release26-maint/Doc/library/commands.rst Tue Apr 28 20:23:28 2009 @@ -16,11 +16,12 @@ processes and retrieving their results. Using the :mod:`subprocess` module is preferable to using the :mod:`commands` module. -.. warning:: +.. note:: - In 3.x, :func:`getstatus` and two undocumented functions (:func:`mk2arg` and - :func:`mkarg`) have been removed. Also, :func:`getstatusoutput` and - :func:`getoutput` have been moved to the :mod:`subprocess` module. + In Python 3.x, :func:`getstatus` and two undocumented functions + (:func:`mk2arg` and :func:`mkarg`) have been removed. Also, + :func:`getstatusoutput` and :func:`getoutput` have been moved to the + :mod:`subprocess` module. The :mod:`commands` module defines the following functions: Modified: python/branches/release26-maint/Doc/library/configparser.rst ============================================================================== --- python/branches/release26-maint/Doc/library/configparser.rst (original) +++ python/branches/release26-maint/Doc/library/configparser.rst Tue Apr 28 20:23:28 2009 @@ -27,10 +27,10 @@ can use this to write Python programs which can be customized by end users easily. -.. warning:: +.. note:: - This library does *not* interpret or write the value-type prefixes used in the - Windows Registry extended version of INI syntax. + This library does *not* interpret or write the value-type prefixes used in + the Windows Registry extended version of INI syntax. The configuration file consists of sections, led by a ``[section]`` header and followed by ``name: value`` entries, with continuations in the style of Modified: python/branches/release26-maint/Doc/library/easydialogs.rst ============================================================================== --- python/branches/release26-maint/Doc/library/easydialogs.rst (original) +++ python/branches/release26-maint/Doc/library/easydialogs.rst Tue Apr 28 20:23:28 2009 @@ -16,9 +16,9 @@ type and item number) to those in the default :const:`DLOG` resource. See source code for details. -.. warning:: +.. note:: - This module is removed in 3.0. + This module has been removed in Python 3.x. The :mod:`EasyDialogs` module defines the following functions: Modified: python/branches/release26-maint/Doc/library/fileinput.rst ============================================================================== --- python/branches/release26-maint/Doc/library/fileinput.rst (original) +++ python/branches/release26-maint/Doc/library/fileinput.rst Tue Apr 28 20:23:28 2009 @@ -150,7 +150,7 @@ it is deleted when the output file is closed. In-place filtering is disabled when standard input is read. -.. warning:: +.. note:: The current implementation does not work for MS-DOS 8+3 filesystems. Modified: python/branches/release26-maint/Doc/library/framework.rst ============================================================================== --- python/branches/release26-maint/Doc/library/framework.rst (original) +++ python/branches/release26-maint/Doc/library/framework.rst Tue Apr 28 20:23:28 2009 @@ -16,9 +16,9 @@ dialog window in a non-standard way it is not necessary to override the complete event handling. -.. warning:: +.. note:: - This module is removed in 3.0. + This module has been removed in Python 3.x. Work on the :mod:`FrameWork` has pretty much stopped, now that :mod:`PyObjC` is available for full Cocoa access from Python, and the documentation describes Modified: python/branches/release26-maint/Doc/library/functions.rst ============================================================================== --- python/branches/release26-maint/Doc/library/functions.rst (original) +++ python/branches/release26-maint/Doc/library/functions.rst Tue Apr 28 20:23:28 2009 @@ -364,7 +364,7 @@ If both dictionaries are omitted, the expression is executed in the environment where :func:`execfile` is called. The return value is ``None``. - .. warning:: + .. note:: The default *locals* act as described for function :func:`locals` below: modifications to the default *locals* dictionary should not be attempted. Pass @@ -625,7 +625,7 @@ Update and return a dictionary representing the current local symbol table. - .. warning:: + .. note:: The contents of this dictionary should not be modified; changes may not affect the values of local variables used by the interpreter. @@ -1348,7 +1348,7 @@ else that has a :attr:`__dict__` attribute), returns a dictionary corresponding to the object's symbol table. - .. warning:: + .. note:: The returned dictionary should not be modified: the effects on the corresponding symbol table are undefined. [#]_ Modified: python/branches/release26-maint/Doc/library/gl.rst ============================================================================== --- python/branches/release26-maint/Doc/library/gl.rst (original) +++ python/branches/release26-maint/Doc/library/gl.rst Tue Apr 28 20:23:28 2009 @@ -1,4 +1,3 @@ - :mod:`gl` --- *Graphics Library* interface ========================================== @@ -17,9 +16,9 @@ .. warning:: - Some illegal calls to the GL library cause the Python interpreter to dump core. - In particular, the use of most GL calls is unsafe before the first window is - opened. + Some illegal calls to the GL library cause the Python interpreter to dump + core. In particular, the use of most GL calls is unsafe before the first + window is opened. The module is too large to document here in its entirety, but the following should help you to get started. The parameter conventions for the C functions Modified: python/branches/release26-maint/Doc/library/hotshot.rst ============================================================================== --- python/branches/release26-maint/Doc/library/hotshot.rst (original) +++ python/branches/release26-maint/Doc/library/hotshot.rst Tue Apr 28 20:23:28 2009 @@ -26,7 +26,7 @@ The results should be more meaningful than in the past: the timing core contained a critical bug. -.. warning:: +.. note:: The :mod:`hotshot` profiler does not yet work well with threads. It is useful to use an unthreaded script to run the profiler over the code you're interested in Modified: python/branches/release26-maint/Doc/library/httplib.rst ============================================================================== --- python/branches/release26-maint/Doc/library/httplib.rst (original) +++ python/branches/release26-maint/Doc/library/httplib.rst Tue Apr 28 20:23:28 2009 @@ -68,9 +68,9 @@ formatted file that contains your private key. *cert_file* is a PEM formatted certificate chain file. - .. warning:: + .. note:: - This does not do any certificate verification! + This does not do any certificate verification. .. versionadded:: 2.0 Modified: python/branches/release26-maint/Doc/library/ic.rst ============================================================================== --- python/branches/release26-maint/Doc/library/ic.rst (original) +++ python/branches/release26-maint/Doc/library/ic.rst Tue Apr 28 20:23:28 2009 @@ -1,4 +1,3 @@ - :mod:`ic` --- Access to the Mac OS X Internet Config ==================================================== @@ -11,9 +10,9 @@ This module provides access to various internet-related preferences set through :program:`System Preferences` or the :program:`Finder`. -.. warning:: +.. note:: - This module is removed in 3.0. + This module has been removed in Python 3.x. .. index:: module: icglue Modified: python/branches/release26-maint/Doc/library/inspect.rst ============================================================================== --- python/branches/release26-maint/Doc/library/inspect.rst (original) +++ python/branches/release26-maint/Doc/library/inspect.rst Tue Apr 28 20:23:28 2009 @@ -510,7 +510,7 @@ the function name, a list of lines of context from the source code, and the index of the current line within that list. -.. warning:: +.. note:: Keeping references to frame objects, as found in the first element of the frame records these functions return, can cause your program to create reference Modified: python/branches/release26-maint/Doc/library/locale.rst ============================================================================== --- python/branches/release26-maint/Doc/library/locale.rst (original) +++ python/branches/release26-maint/Doc/library/locale.rst Tue Apr 28 20:23:28 2009 @@ -398,7 +398,7 @@ Return name of the n-th day of the week. - .. warning:: + .. note:: This follows the US convention of :const:`DAY_1` being Sunday, not the international convention (ISO 8601) that Monday is the first day of the week. @@ -434,7 +434,7 @@ Return a regular expression that can be used with the regex function to recognize a positive response to a yes/no question. - .. warning:: + .. note:: The expression is in the syntax suitable for the :cfunc:`regex` function from the C library, which might differ from the syntax used in :mod:`re`. Modified: python/branches/release26-maint/Doc/library/mac.rst ============================================================================== --- python/branches/release26-maint/Doc/library/mac.rst (original) +++ python/branches/release26-maint/Doc/library/mac.rst Tue Apr 28 20:23:28 2009 @@ -10,9 +10,9 @@ modules, and the HOWTO :ref:`using-on-mac` for a general introduction to Mac-specific Python programming. -.. warning:: +.. note:: - These modules are deprecated and are removed in 3.0. + These modules are deprecated and have been removed in Python 3.x. .. toctree:: Modified: python/branches/release26-maint/Doc/library/macos.rst ============================================================================== --- python/branches/release26-maint/Doc/library/macos.rst (original) +++ python/branches/release26-maint/Doc/library/macos.rst Tue Apr 28 20:23:28 2009 @@ -11,9 +11,9 @@ interpreter, such as how the interpreter eventloop functions and the like. Use with care. -.. warning:: +.. note:: - This module is removed in 3.0. + This module has been removed in Python 3.x. Note the capitalization of the module name; this is a historical artifact. Modified: python/branches/release26-maint/Doc/library/macostools.rst ============================================================================== --- python/branches/release26-maint/Doc/library/macostools.rst (original) +++ python/branches/release26-maint/Doc/library/macostools.rst Tue Apr 28 20:23:28 2009 @@ -13,9 +13,9 @@ :class:`FSSpec` objects. This module expects a filesystem which supports forked files, so it should not be used on UFS partitions. -.. warning:: +.. note:: - This module is removed in 3.0. + This module has been removed in Python 3.0. The :mod:`macostools` module defines the following functions: Modified: python/branches/release26-maint/Doc/library/marshal.rst ============================================================================== --- python/branches/release26-maint/Doc/library/marshal.rst (original) +++ python/branches/release26-maint/Doc/library/marshal.rst Tue Apr 28 20:23:28 2009 @@ -85,7 +85,7 @@ file must be an open file object opened in binary mode (``'rb'`` or ``'r+b'``). - .. warning:: + .. note:: If an object containing an unsupported type was marshalled with :func:`dump`, :func:`load` will substitute ``None`` for the unmarshallable type. Modified: python/branches/release26-maint/Doc/library/os.path.rst ============================================================================== --- python/branches/release26-maint/Doc/library/os.path.rst (original) +++ python/branches/release26-maint/Doc/library/os.path.rst Tue Apr 28 20:23:28 2009 @@ -10,7 +10,7 @@ write files see :func:`open`, and for accessing the filesystem see the :mod:`os` module. -.. warning:: +.. note:: On Windows, many of these functions do not properly support UNC pathnames. :func:`splitunc` and :func:`ismount` do handle them correctly. @@ -317,7 +317,7 @@ identify them with ``os.path.islink(file)`` and ``os.path.isdir(file)``, and invoke :func:`walk` as necessary. - .. warning:: + .. note:: This function is deprecated and has been removed in 3.0 in favor of :func:`os.walk`. Modified: python/branches/release26-maint/Doc/library/pickle.rst ============================================================================== --- python/branches/release26-maint/Doc/library/pickle.rst (original) +++ python/branches/release26-maint/Doc/library/pickle.rst Tue Apr 28 20:23:28 2009 @@ -77,8 +77,8 @@ .. warning:: The :mod:`pickle` module is not intended to be secure against erroneous or - maliciously constructed data. Never unpickle data received from an untrusted or - unauthenticated source. + maliciously constructed data. Never unpickle data received from an untrusted + or unauthenticated source. Note that serialization is a more primitive notion than persistence; although :mod:`pickle` reads and writes file objects, it does not handle the issue of @@ -453,7 +453,7 @@ :meth:`__getstate__` and :meth:`__setstate__`, the state object needn't be a dictionary and these methods can do what they want. [#]_ - .. warning:: + .. note:: For :term:`new-style class`\es, if :meth:`__getstate__` returns a false value, the :meth:`__setstate__` method will not be called. Modified: python/branches/release26-maint/Doc/library/plistlib.rst ============================================================================== --- python/branches/release26-maint/Doc/library/plistlib.rst (original) +++ python/branches/release26-maint/Doc/library/plistlib.rst Tue Apr 28 20:23:28 2009 @@ -75,10 +75,9 @@ Read a plist from the resource with type *restype* from the resource fork of *path*. Availability: Mac OS X. - .. warning:: - - In 3.0, this function is removed. + .. note:: + In Python 3.x, this function has been removed. .. function:: writePlistToResource(rootObject, path[, restype='plst'[, resid=0]]) @@ -86,9 +85,9 @@ Write *rootObject* as a resource with type *restype* to the resource fork of *path*. Availability: Mac OS X. - .. warning:: + .. note:: - In 3.0, this function is removed. + In Python 3.x, this function has been removed. Modified: python/branches/release26-maint/Doc/library/rexec.rst ============================================================================== --- python/branches/release26-maint/Doc/library/rexec.rst (original) +++ python/branches/release26-maint/Doc/library/rexec.rst Tue Apr 28 20:23:28 2009 @@ -1,4 +1,3 @@ - :mod:`rexec` --- Restricted execution framework =============================================== Modified: python/branches/release26-maint/Doc/library/string.rst ============================================================================== --- python/branches/release26-maint/Doc/library/string.rst (original) +++ python/branches/release26-maint/Doc/library/string.rst Tue Apr 28 20:23:28 2009 @@ -592,7 +592,7 @@ map each character in *from* into the character at the same position in *to*; *from* and *to* must have the same length. - .. warning:: + .. note:: Don't use strings derived from :const:`lowercase` and :const:`uppercase` as arguments; in some locales, these don't have the same length. For case Modified: python/branches/release26-maint/Doc/library/subprocess.rst ============================================================================== --- python/branches/release26-maint/Doc/library/subprocess.rst (original) +++ python/branches/release26-maint/Doc/library/subprocess.rst Tue Apr 28 20:23:28 2009 @@ -276,10 +276,10 @@ .. warning:: - Use :meth:`communicate` rather than :meth:`.stdin.write`, - :meth:`.stdout.read` or :meth:`.stderr.read` to avoid deadlocks due - to any of the other OS pipe buffers filling up and blocking the child - process. + Use :meth:`communicate` rather than :attr:`.stdin.write `, + :attr:`.stdout.read ` or :attr:`.stderr.read ` to avoid + deadlocks due to any of the other OS pipe buffers filling up and blocking the + child process. .. attribute:: Popen.stdin Modified: python/branches/release26-maint/Doc/library/tabnanny.rst ============================================================================== --- python/branches/release26-maint/Doc/library/tabnanny.rst (original) +++ python/branches/release26-maint/Doc/library/tabnanny.rst Tue Apr 28 20:23:28 2009 @@ -1,4 +1,3 @@ - :mod:`tabnanny` --- Detection of ambiguous indentation ====================================================== @@ -14,9 +13,9 @@ is possible to import it into an IDE and use the function :func:`check` described below. -.. warning:: +.. note:: - The API provided by this module is likely to change in future releases; such + The API provided by this module is likely to change in future releases; such changes may not be backward compatible. Modified: python/branches/release26-maint/Doc/library/traceback.rst ============================================================================== --- python/branches/release26-maint/Doc/library/traceback.rst (original) +++ python/branches/release26-maint/Doc/library/traceback.rst Tue Apr 28 20:23:28 2009 @@ -1,4 +1,3 @@ - :mod:`traceback` --- Print or retrieve a stack traceback ======================================================== @@ -275,10 +274,10 @@ This last example demonstrates the final few formatting functions:: >>> import traceback - >>> format_list([('spam.py', 3, '', 'spam.eggs()'), - ... ('eggs.py', 42, 'eggs', 'return "bacon"')]) + >>> traceback.format_list([('spam.py', 3, '', 'spam.eggs()'), + ... ('eggs.py', 42, 'eggs', 'return "bacon"')]) [' File "spam.py", line 3, in \n spam.eggs()\n', ' File "eggs.py", line 42, in eggs\n return "bacon"\n'] - >>> theError = IndexError('tuple indx out of range') - >>> traceback.format_exception_only(type(theError), theError) + >>> an_error = IndexError('tuple index out of range') + >>> traceback.format_exception_only(type(an_error), an_error) ['IndexError: tuple index out of range\n'] Modified: python/branches/release26-maint/Doc/library/undoc.rst ============================================================================== --- python/branches/release26-maint/Doc/library/undoc.rst (original) +++ python/branches/release26-maint/Doc/library/undoc.rst Tue Apr 28 20:23:28 2009 @@ -20,9 +20,8 @@ Some of these are very old and/or not very robust; marked with "hmm." :mod:`ihooks` - --- Import hook support (for :mod:`rexec`; may become obsolete). - - .. warning:: The :mod:`ihooks` module has been removed in Python 3.0. + --- Import hook support (for :mod:`rexec`; may become obsolete). Removed in + Python 3.x. Platform specific modules @@ -47,27 +46,19 @@ ========== :mod:`audiodev` - --- Platform-independent API for playing audio data. - - .. warning:: The :mod:`audiodev` module has been removed in 3.0. + --- Platform-independent API for playing audio data. Removed in Python 3.x. :mod:`linuxaudiodev` --- Play audio data on the Linux audio device. Replaced in Python 2.3 by the - :mod:`ossaudiodev` module. - - .. warning:: The :mod:`linuxaudiodev` module has been removed in Python 3.0. + :mod:`ossaudiodev` module. Removed in Python 3.x. :mod:`sunaudio` --- Interpret Sun audio headers (may become obsolete or a tool/demo). - - .. warning:: The :mod:`sunaudio` module has been removed in Python 3.0. + Removed in Python 3.x. :mod:`toaiff` --- Convert "arbitrary" sound files to AIFF files; should probably become a tool - or demo. Requires the external program :program:`sox`. - - - .. warning:: The :mod:`toaiff` module has been removed in 3.0. + or demo. Requires the external program :program:`sox`. Removed in Python 3.x. .. _undoc-mac-modules: @@ -239,9 +230,8 @@ \envvar{PYTHONPATH}. :mod:`timing` - --- Measure time intervals to high resolution (use :func:`time.clock` instead). - - .. warning:: The :mod:`timing` module has been removed in Python 3.0. + --- Measure time intervals to high resolution (use :func:`time.clock` + instead). Removed in Python 3.x. SGI-specific Extension modules @@ -255,6 +245,4 @@ :mod:`sv` --- Interface to the "simple video" board on SGI Indigo (obsolete hardware). - - .. warning:: The :mod:`sv` module has been removed in Python 3.0. - + Removed in Python 3.x. Modified: python/branches/release26-maint/Doc/reference/compound_stmts.rst ============================================================================== --- python/branches/release26-maint/Doc/reference/compound_stmts.rst (original) +++ python/branches/release26-maint/Doc/reference/compound_stmts.rst Tue Apr 28 20:23:28 2009 @@ -178,7 +178,7 @@ effect of Pascal's ``for i := a to b do``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``. -.. warning:: +.. note:: .. index:: single: loop; over mutable sequence Modified: python/branches/release26-maint/Doc/reference/executionmodel.rst ============================================================================== --- python/branches/release26-maint/Doc/reference/executionmodel.rst (original) +++ python/branches/release26-maint/Doc/reference/executionmodel.rst Tue Apr 28 20:23:28 2009 @@ -231,7 +231,7 @@ :keyword:`except` clause is selected by object identity. An arbitrary value can be raised along with the identifying string which can be passed to the handler. -.. warning:: +.. note:: Messages to exceptions are not part of the Python API. Their contents may change from one version of Python to the next without warning and should not be Modified: python/branches/release26-maint/Doc/using/cmdline.rst ============================================================================== --- python/branches/release26-maint/Doc/using/cmdline.rst (original) +++ python/branches/release26-maint/Doc/using/cmdline.rst Tue Apr 28 20:23:28 2009 @@ -351,7 +351,7 @@ Skip the first line of the source, allowing use of non-Unix forms of ``#!cmd``. This is intended for a DOS specific hack only. - .. warning:: The line numbers in error messages will be off by one! + .. note:: The line numbers in error messages will be off by one. .. cmdoption:: -3 From python-checkins at python.org Tue Apr 28 20:24:36 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 28 Apr 2009 20:24:36 +0200 (CEST) Subject: [Python-checkins] r72076 - python/branches/release26-maint/Doc/Makefile Message-ID: <20090428182436.A82271E4011@bag.python.org> Author: georg.brandl Date: Tue Apr 28 20:24:36 2009 New Revision: 72076 Log: Move comment to the right place. Modified: python/branches/release26-maint/Doc/Makefile Modified: python/branches/release26-maint/Doc/Makefile ============================================================================== --- python/branches/release26-maint/Doc/Makefile (original) +++ python/branches/release26-maint/Doc/Makefile Tue Apr 28 20:24:36 2009 @@ -28,8 +28,8 @@ @echo " coverage to check documentation coverage for library and C API" @echo " dist to create a \"dist\" directory with archived docs for download" +# Note: if you update versions here, do the same in make.bat and README.txt checkout: - # Note: if you update versions here, do the same in make.bat and README.txt @if [ ! -d tools/sphinx ]; then \ echo "Checking out Sphinx..."; \ svn checkout $(SVNROOT)/external/Sphinx-0.6.1/sphinx tools/sphinx; \ From buildbot at python.org Tue Apr 28 20:43:11 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 28 Apr 2009 18:43:11 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090428184311.356B61E4194@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/659 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_os ====================================================================== FAIL: test_update2 (test.test_os.EnvironTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/test/test_os.py", line 382, in test_update2 self.assertEquals(value, "World") AssertionError: '' != 'World' make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Tue Apr 28 20:53:14 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 28 Apr 2009 20:53:14 +0200 (CEST) Subject: [Python-checkins] r72077 - python/branches/release26-maint/Lib/pydoc_topics.py Message-ID: <20090428185314.72D751E4011@bag.python.org> Author: georg.brandl Date: Tue Apr 28 20:53:13 2009 New Revision: 72077 Log: Update pydoc topics. Modified: python/branches/release26-maint/Lib/pydoc_topics.py Modified: python/branches/release26-maint/Lib/pydoc_topics.py ============================================================================== --- python/branches/release26-maint/Lib/pydoc_topics.py (original) +++ python/branches/release26-maint/Lib/pydoc_topics.py Tue Apr 28 20:53:13 2009 @@ -1,4 +1,4 @@ -# Autogenerated by Sphinx on Tue Apr 14 09:12:28 2009 +# Autogenerated by Sphinx on Tue Apr 28 20:27:10 2009 topics = {'assert': u'\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': u'\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\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 is recursively defined as\nfollows.\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\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`` statement in the\n current code block: the name is bound to the object in the current\n local namespace.\n\n * Otherwise: the name is bound to the object in the current global\n namespace.\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* 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 a plain integer. If it is negative, the\n sequence\'s length is added to it. The resulting value must be a\n nonnegative integer less than the sequence\'s length, and the\n sequence is asked to assign the assigned object to its item with\n that index. If the index is out of range, ``IndexError`` is raised\n (assignment to a subscripted sequence cannot add new items to a\n 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* 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 (small) integers. If either\n bound is negative, the sequence\'s length is added to it. The\n resulting bounds are clipped to lie between zero and the sequence\'s\n length, inclusive. Finally, the sequence object is asked to replace\n the slice with the items of the assigned sequence. The length of\n the 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(In the current implementation, the syntax for targets is taken to be\nthe same as for expressions, and invalid syntax is rejected during the\ncode generation phase, causing less 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\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 initial value is\nretrieved with a ``getattr()`` and the result is assigned with a\n``setattr()``. Notice that the two methods do not necessarily refer\nto the same variable. When ``getattr()`` refers to a class variable,\n``setattr()`` still writes to an instance variable. For example:\n\n class A:\n x = 3 # class variable\n a = A()\n a.x += 1 # writes a.x as 4 leaving A.x as 3\n', 'atom-identifiers': u'\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', @@ -20,7 +20,7 @@ 'class': u'\nClass definitions\n*****************\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with ``self.name = value``.\nBoth class and instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\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', 'coercion-rules': u"\nCoercion rules\n**************\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3.0, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don't define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from ``object``) never invoke the\n ``__coerce__()`` method in response to a binary operator; the only\n time ``__coerce__()`` is invoked is when the built-in function\n ``coerce()`` is called.\n\n* For most intents and purposes, an operator that returns\n ``NotImplemented`` is treated the same as one that is not\n implemented at all.\n\n* Below, ``__op__()`` and ``__rop__()`` are used to signify the\n generic method names corresponding to an operator; ``__iop__()`` is\n used for the corresponding in-place operator. For example, for the\n operator '``+``', ``__add__()`` and ``__radd__()`` are used for the\n left and right variant of the binary operator, and ``__iadd__()``\n for the in-place variant.\n\n* For objects *x* and *y*, first ``x.__op__(y)`` is tried. If this is\n not implemented or returns ``NotImplemented``, ``y.__rop__(x)`` is\n tried. If this is also not implemented or returns\n ``NotImplemented``, a ``TypeError`` exception is raised. But see\n the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base's ``__rop__()`` method, the right operand's ``__rop__()``\n method is tried *before* the left operand's ``__op__()`` method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand's ``__op__()`` method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is called\n before that type's ``__op__()`` or ``__rop__()`` method is called,\n but no sooner. If the coercion returns an object of a different\n type for the operand whose coercion is invoked, part of the process\n is redone using the new object.\n\n* When an in-place operator (like '``+=``') is used, if the left\n operand implements ``__iop__()``, it is invoked without any\n coercion. When the operation falls back to ``__op__()`` and/or\n ``__rop__()``, the normal coercion rules apply.\n\n* In ``x + y``, if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In ``x * y``, if one operator is a sequence that implements sequence\n repetition, and the other is an integer (``int`` or ``long``),\n sequence repetition is invoked.\n\n* Rich comparisons (implemented by methods ``__eq__()`` and so on)\n never use coercion. Three-way comparison (implemented by\n ``__cmp__()``) does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types ``int``,\n ``long`` and ``float`` do not use coercion; the type ``complex``\n however does use coercion for binary operators and rich comparisons,\n despite the above rules. The difference can become apparent when\n subclassing these types. Over time, the type ``complex`` may be\n fixed to avoid coercion. All these types implement a\n ``__coerce__()`` method, for use by the built-in ``coerce()``\n function.\n", 'comparisons': u'\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 forms ``<>`` and ``!=`` are equivalent; for consistency with C,\n``!=`` is preferred; where ``!=`` is mentioned below ``<>`` is also\naccepted. The ``<>`` spelling is considered obsolescent.\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,\nobjects of different types *always* compare unequal, and are ordered\nconsistently but arbitrarily. You can control comparison behavior of\nobjects of non-builtin types by defining a ``__cmp__`` method or rich\ncomparison methods like ``__gt__``, described in section *Special\nmethod names*.\n\n(This unusual definition of comparison was used to simplify the\ndefinition of operations like sorting and the ``in`` and ``not in``\noperators. In the future, the comparison rules for objects of\ndifferent types are likely to change.)\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n Unicode and 8-bit strings are fully interoperable in this behavior.\n [4]\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, ``cmp([1,2,x], [1,2,y])`` returns\n the same as ``cmp(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 their sorted\n (key, value) lists compare equal. [5] Outcomes other than equality\n are resolved consistently, but are not otherwise defined. [6]\n\n* Most other objects of builtin 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\nThe operators ``in`` and ``not in`` test for collection membership.\n``x in s`` evaluates to true if *x* is a member of the collection *s*,\nand false otherwise. ``x not in s`` returns the negation of ``x in\ns``. The collection membership test has traditionally been bound to\nsequences; an object is a member of a collection if the collection is\na sequence and contains an element equal to that object. However, it\nmake sense for many other object types to support membership tests\nwithout being a sequence. In particular, dictionaries (for keys) and\nsets support membership testing.\n\nFor the list and tuple types, ``x in y`` is true if and only if there\nexists an index *i* such that ``x == y[i]`` is true.\n\nFor the Unicode and string types, ``x in y`` is true if and only if\n*x* is a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nNote, *x* and *y* need not be the same type; consequently, ``u\'ab\' in\n\'abc\'`` will return ``True``. Empty strings are always considered to\nbe a substring of any other string, so ``"" in "abc"`` will return\n``True``.\n\nChanged in version 2.3: Previously, *x* was required to be a string of\nlength ``1``.\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__()`` and do\ndefine ``__getitem__()``, ``x in y`` is true if and only if there is a\nnon-negative 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. [7]\n', - 'compound': u'\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. Function and class\ndefinitions are also syntactically compound 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`` statements 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 | decorated\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, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\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\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nWarning: 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 internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n 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\nChanged in version 2.5: In previous versions of Python,\n``try``...``except``...``finally`` did not work. ``try``...``except``\nhad to be nested in ``try``...``finally``.\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, a tuple containing an item compatible with the\nexception, or, in the (deprecated) case of string exceptions, is the\nraised string itself (note that the object identities must match, i.e.\nit must be the same string object, not just a string with the same\nvalue).\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 in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the ``sys`` module:\n``sys.exc_type`` receives the object identifying the exception;\n``sys.exc_value`` receives the exception\'s parameter;\n``sys.exc_traceback`` receives a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. These details are also available through the\n``sys.exc_info()`` function, which returns a tuple ``(exc_type,\nexc_value, exc_traceback)``. Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables 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\nNew in version 2.5.\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" expression ["as" target] ":" suite\n\nThe execution of the ``with`` statement proceeds as follows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__enter__()`` method is invoked.\n\n3. 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 5 below.\n\n4. The suite is executed.\n\n5. 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\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\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 decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier [, "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\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 top-level 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 must also have a default value --- this is a syntactic\nrestriction 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.\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 *Expression lists*. Note that the lambda form is\nmerely a shorthand for a simplified function definition; a function\ndefined in a "``def``" statement can be passed around or assigned to\nanother name just like a function defined by a lambda form. The\n"``def``" form is actually more powerful since it allows the execution\nof multiple statements.\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 ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with ``self.name = value``.\nBoth class and instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\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': u'\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. Function and class\ndefinitions are also syntactically compound 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`` statements 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 | decorated\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, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\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\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\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 internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n 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\nChanged in version 2.5: In previous versions of Python,\n``try``...``except``...``finally`` did not work. ``try``...``except``\nhad to be nested in ``try``...``finally``.\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, a tuple containing an item compatible with the\nexception, or, in the (deprecated) case of string exceptions, is the\nraised string itself (note that the object identities must match, i.e.\nit must be the same string object, not just a string with the same\nvalue).\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 in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the ``sys`` module:\n``sys.exc_type`` receives the object identifying the exception;\n``sys.exc_value`` receives the exception\'s parameter;\n``sys.exc_traceback`` receives a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. These details are also available through the\n``sys.exc_info()`` function, which returns a tuple ``(exc_type,\nexc_value, exc_traceback)``. Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables 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\nNew in version 2.5.\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" expression ["as" target] ":" suite\n\nThe execution of the ``with`` statement proceeds as follows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__enter__()`` method is invoked.\n\n3. 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 5 below.\n\n4. The suite is executed.\n\n5. 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\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\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 decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier [, "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\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 top-level 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 must also have a default value --- this is a syntactic\nrestriction 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.\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.\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 ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with ``self.name = value``.\nBoth class and instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\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': u'\nWith Statement Context Managers\n*******************************\n\nNew in version 2.5.\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': u'\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': u'\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," the arguments\nare coerced using the coercion rules listed at *Coercion rules*. If\nboth arguments are standard numeric types, the following coercions are\napplied:\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, if either argument is a long integer, the other is\n converted to long integer;\n\n* otherwise, both must be plain integers and no conversion is\n necessary.\n\nSome additional rules apply for certain operators (e.g., a string left\nargument to the \'%\' operator). Extensions can define their own\ncoercions.\n', @@ -30,23 +30,23 @@ 'dict': u'\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] "}"\n key_datum_list ::= key_datum ("," key_datum)* [","]\n key_datum ::= expression ":" expression\n\nA dictionary display yields a new dictionary object.\n\nThe key/datum pairs are evaluated from left to right to define the\nentries of the dictionary: each key object is used as a key into the\ndictionary to store the corresponding datum.\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': u'\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\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n', 'else': u'\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', - 'exceptions': u'\nExceptions\n**********\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nWarning: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', + 'exceptions': u'\nExceptions\n**********\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nNote: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', 'exec': u'\nThe ``exec`` statement\n**********************\n\n exec_stmt ::= "exec" or_expr ["in" expression ["," expression]]\n\nThis statement supports dynamic execution of Python code. The first\nexpression should evaluate to either a string, an open file object, or\na code object. If it is a string, the string is parsed as a suite of\nPython statements which is then executed (unless a syntax error\noccurs). [1] If it is an open file, the file is parsed until EOF and\nexecuted. If it is a code object, it is simply executed. In all\ncases, the code that\'s executed is expected to be valid as file input\n(see section *File input*). Be aware that the ``return`` and\n``yield`` statements may not be used outside of function definitions\neven within the context of code passed to the ``exec`` statement.\n\nIn all cases, if the optional parts are omitted, the code is executed\nin the current scope. If only the first expression after ``in`` is\nspecified, it should be a dictionary, which will be used for both the\nglobal and the local variables. If two expressions are given, they\nare used for the global and local variables, respectively. If\nprovided, *locals* can be any mapping object.\n\nChanged in version 2.4: Formerly, *locals* was required to be a\ndictionary.\n\nAs a side effect, an implementation may insert additional keys into\nthe dictionaries given besides those corresponding to variable names\nset by the executed code. For example, the current implementation may\nadd a reference to the dictionary of the built-in module\n``__builtin__`` under the key ``__builtins__`` (!).\n\n**Programmer\'s hints:** dynamic evaluation of expressions is supported\nby the built-in function ``eval()``. The built-in functions\n``globals()`` and ``locals()`` return the current global and local\ndictionary, respectively, which may be useful to pass around for use\nby ``exec``.\n\n-[ Footnotes ]-\n\n[1] Note that the parser only accepts the Unix-style end of line\n convention. If you are reading the code from a file, make sure to\n use universal newline mode to convert Windows or Mac-style\n newlines.\n', - 'execmodel': u'\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, in the\nsecond position of an ``except`` clause header or after ``as`` in a\n``with`` statement. The ``import`` statement of the form ``from ...\nimport *`` binds all names defined in the imported module, except\nthose beginning with an underscore. This form may only be used at the\nmodule level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtin namespace, the namespace of\nthe module ``__builtin__``. The global namespace is searched first.\nIf the name is not found there, the builtin namespace is searched.\nThe global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no \'s\'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``__builtin__`` (no \'s\')\n module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\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\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nWarning: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', + 'execmodel': u'\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, in the\nsecond position of an ``except`` clause header or after ``as`` in a\n``with`` statement. The ``import`` statement of the form ``from ...\nimport *`` binds all names defined in the imported module, except\nthose beginning with an underscore. This form may only be used at the\nmodule level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtin namespace, the namespace of\nthe module ``__builtin__``. The global namespace is searched first.\nIf the name is not found there, the builtin namespace is searched.\nThe global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no \'s\'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``__builtin__`` (no \'s\')\n module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\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\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nNote: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', 'exprlists': u'\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': u'\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 of floating point numbers can\nlook like octal integers, but are interpreted using radix 10. For\nexample, ``077e010`` is legal, and denotes the same number as\n``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': u'\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, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\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\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nWarning: 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 internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n 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', + 'for': u'\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, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\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\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\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 internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n 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': u'\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 ::= (identifier | integer) ("." attribute_name | "[" element_index "]")*\n attribute_name ::= identifier\n element_index ::= integer\n conversion ::= "r" | "s"\n format_spec ::= \n\nIn less formal terms, the replacement field starts with a\n*field_name*, which can either be a number (for a positional\nargument), or an identifier (for keyword arguments). Following this\nis an optional *conversion* field, which is preceded by an exclamation\npoint ``\'!\'``, and a *format_spec*, which is preceded by a colon\n``\':\'``.\n\nThe *field_name* itself begins with either a number or a keyword. If\nit\'s a number, it refers to a positional argument, and if it\'s a\nkeyword it refers to a named keyword argument. This can be followed\nby any number of index or attribute expressions. An expression of the\nform ``\'.name\'`` selects the named attribute using ``getattr()``,\nwhile an expression of the form ``\'[index]\'`` does an index lookup\nusing ``__getitem__()``.\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\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\nTwo conversion flags are currently supported: ``\'!s\'`` which calls\n``str()`` on the value, and ``\'!r\'`` which calls ``repr()``.\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\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 it\'s\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\nFor example, suppose you wanted to have a replacement field whose\nfield width is determined by another variable:\n\n "A man with two {0:{1}}".format("noses", 10)\n\nThis would first evaluate the inner replacement field, making the\nformat string effectively:\n\n "A man with two {0:10}"\n\nThen the outer replacement field would be evaluated, producing:\n\n "noses "\n\nWhich is substituted into the string, yielding:\n\n "A man with two noses "\n\n(The extra space is because we specified a field width of 10, and\nbecause left alignment is the default for strings.)\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\nbuiltin ``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.\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" | "x" | "X" | "%"\n\nThe *fill* character can be any character other than \'}\' (which\nsignifies the end of the field). The presence of a fill character is\nsignaled by the *next* character, which must be one of the alignment\noptions. If the second character of *format_spec* is not a valid\nalignment option, then it is assumed that both the fill character and\nthe alignment option are absent.\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\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 ignored for integer values.\n\nFinally, the *type* determines how the data should be presented.\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\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\'``. |\n +-----------+------------------------------------------------------------+\n | ``\'g\'`` | General format. This prints the number as a fixed-point |\n | | number, unless the number is too large, in which case it |\n | | switches to ``\'e\'`` exponent notation. Infinity and NaN |\n | | values are formatted as ``inf``, ``-inf`` and ``nan``, |\n | | respectively. |\n +-----------+------------------------------------------------------------+\n | ``\'G\'`` | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n | | if the number gets to 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 | The same as ``\'g\'``. |\n +-----------+------------------------------------------------------------+\n', - 'function': u'\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier [, "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\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 top-level 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 must also have a default value --- this is a syntactic\nrestriction 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.\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 *Expression lists*. Note that the lambda form is\nmerely a shorthand for a simplified function definition; a function\ndefined in a "``def``" statement can be passed around or assigned to\nanother name just like a function defined by a lambda form. The\n"``def``" form is actually more powerful since it allows the execution\nof multiple statements.\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', + 'function': u'\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier [, "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\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 top-level 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 must also have a default value --- this is a syntactic\nrestriction 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.\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.\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': u'\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(The current implementation does not enforce the latter two\nrestrictions, but programs should not abuse this freedom, as future\nimplementations may enforce them or silently change the meaning of the\nprogram.)\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 an\n``exec`` statement does not affect the code block *containing* the\n``exec`` statement, and code contained in an ``exec`` statement is\nunaffected by ``global`` statements in the code containing the\n``exec`` statement. The same applies to the ``eval()``,\n``execfile()`` and ``compile()`` functions.\n', 'id-classes': u'\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 ``__builtin__`` module.\n When not in interactive mode, ``_`` has no special meaning and is\n not 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);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\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': u'\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions:\n\n identifier ::= (letter|"_") (letter | digit | "_")*\n letter ::= lowercase | uppercase\n lowercase ::= "a"..."z"\n uppercase ::= "A"..."Z"\n digit ::= "0"..."9"\n\nIdentifiers are unlimited in length. Case is significant.\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 and del from not while\n as elif global or with\n assert else if pass yield\n break except import print\n class exec in raise\n continue finally is return\n def for lambda try\n\nChanged in version 2.4: ``None`` became a constant and is now\nrecognized by the compiler as a name for the built-in object ``None``.\nAlthough it is not a keyword, you cannot assign a different object to\nit.\n\nChanged in version 2.5: Both ``as`` and ``with`` are only recognized\nwhen the ``with_statement`` future feature has been enabled. It will\nalways be enabled in Python 2.6. See section *The with statement* for\ndetails. Note that using ``as`` and ``with`` as identifiers will\nalways issue a warning, even when the ``with_statement`` future\ndirective is not in effect.\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 ``__builtin__`` module.\n When not in interactive mode, ``_`` has no special meaning and is\n not 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);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\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': u'\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': u'\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': u'\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.\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.\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. If the\nwild card form of import --- ``import *`` --- is used in a function\nand the function contains or is a nested block with free variables,\nthe compiler will 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\nimprt mod`` from within ``pkg.subpkg1`` you will import\n``pkg.subpkg2.mod``. The specification for relative imports is\ncontained within **PEP 328**.\n\nThe built-in function ``__import__()`` is provided to support\napplications that determine which modules need to be loaded\ndynamically; refer to *Built-in Functions* for additional information.\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 2.6 are ``unicode_literals``,\n``print_function``, ``absolute_import``, ``division``, ``generators``,\n``nested_scopes`` and ``with_statement``. ``generators``,\n``with_statement``, ``nested_scopes`` are redundant in Python version\n2.6 and above because they are always enabled.\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 an ``exec`` statement or calls to the builtin\nfunctions ``compile()`` and ``execfile()`` that occur in a module\n``M`` containing a future statement will, by default, use the new\nsyntax or semantics associated with the future statement. This can,\nstarting with Python 2.2 be controlled by optional arguments to\n``compile()`` --- see the documentation of that function for 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', + 'import': u'\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.\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.\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. If the\nwild card form of import --- ``import *`` --- is used in a function\nand the function contains or is a nested block with free variables,\nthe compiler will 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\nimprt mod`` from within ``pkg.subpkg1`` you will import\n``pkg.subpkg2.mod``. The specification for relative imports is\ncontained within **PEP 328**.\n\nThe built-in function ``__import__()`` is provided to support\napplications that determine which modules need to be loaded\ndynamically; refer to *Built-in Functions* for additional information.\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 2.6 are ``unicode_literals``,\n``print_function``, ``absolute_import``, ``division``, ``generators``,\n``nested_scopes`` and ``with_statement``. ``generators``,\n``with_statement``, ``nested_scopes`` are redundant in Python version\n2.6 and above because they are always enabled.\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 an ``exec`` statement or calls to the builtin\nfunctions ``compile()`` and ``execfile()`` that occur in a module\n``M`` containing a future statement will, by default, use the new\nsyntax or semantics associated with the future statement. This can,\nstarting with Python 2.2 be controlled by optional arguments to\n``compile()`` --- see the documentation of that function for 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': u'\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 forms ``<>`` and ``!=`` are equivalent; for consistency with C,\n``!=`` is preferred; where ``!=`` is mentioned below ``<>`` is also\naccepted. The ``<>`` spelling is considered obsolescent.\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,\nobjects of different types *always* compare unequal, and are ordered\nconsistently but arbitrarily. You can control comparison behavior of\nobjects of non-builtin types by defining a ``__cmp__`` method or rich\ncomparison methods like ``__gt__``, described in section *Special\nmethod names*.\n\n(This unusual definition of comparison was used to simplify the\ndefinition of operations like sorting and the ``in`` and ``not in``\noperators. In the future, the comparison rules for objects of\ndifferent types are likely to change.)\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n Unicode and 8-bit strings are fully interoperable in this behavior.\n [4]\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, ``cmp([1,2,x], [1,2,y])`` returns\n the same as ``cmp(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 their sorted\n (key, value) lists compare equal. [5] Outcomes other than equality\n are resolved consistently, but are not otherwise defined. [6]\n\n* Most other objects of builtin 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\nThe operators ``in`` and ``not in`` test for collection membership.\n``x in s`` evaluates to true if *x* is a member of the collection *s*,\nand false otherwise. ``x not in s`` returns the negation of ``x in\ns``. The collection membership test has traditionally been bound to\nsequences; an object is a member of a collection if the collection is\na sequence and contains an element equal to that object. However, it\nmake sense for many other object types to support membership tests\nwithout being a sequence. In particular, dictionaries (for keys) and\nsets support membership testing.\n\nFor the list and tuple types, ``x in y`` is true if and only if there\nexists an index *i* such that ``x == y[i]`` is true.\n\nFor the Unicode and string types, ``x in y`` is true if and only if\n*x* is a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nNote, *x* and *y* need not be the same type; consequently, ``u\'ab\' in\n\'abc\'`` will return ``True``. Empty strings are always considered to\nbe a substring of any other string, so ``"" in "abc"`` will return\n``True``.\n\nChanged in version 2.3: Previously, *x* was required to be a string of\nlength ``1``.\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__()`` and do\ndefine ``__getitem__()``, ``x in y`` is true if and only if there is a\nnon-negative 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. [7]\n', 'integers': u'\nInteger and long integer literals\n*********************************\n\nInteger and long integer literals are described by the following\nlexical definitions:\n\n longinteger ::= integer ("l" | "L")\n integer ::= decimalinteger | octinteger | hexinteger | bininteger\n decimalinteger ::= nonzerodigit digit* | "0"\n octinteger ::= "0" ("o" | "O") octdigit+ | "0" octdigit+\n hexinteger ::= "0" ("x" | "X") hexdigit+\n bininteger ::= "0" ("b" | "B") bindigit+\n nonzerodigit ::= "1"..."9"\n octdigit ::= "0"..."7"\n bindigit ::= "0" | "1"\n hexdigit ::= digit | "a"..."f" | "A"..."F"\n\nAlthough both lower case ``\'l\'`` and upper case ``\'L\'`` are allowed as\nsuffix for long integers, it is strongly recommended to always use\n``\'L\'``, since the letter ``\'l\'`` looks too much like the digit\n``\'1\'``.\n\nPlain integer literals that are above the largest representable plain\ninteger (e.g., 2147483647 when using 32-bit arithmetic) are accepted\nas if they were long integers instead. [1] There is no limit for long\ninteger literals apart from what can be stored in available memory.\n\nSome examples of plain integer literals (first row) and long integer\nliterals (second and third rows):\n\n 7 2147483647 0177\n 3L 79228162514264337593543950336L 0377L 0x100000000L\n 79228162514264337593543950336 0xdeadbeef\n', - 'lambda': u'\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', + 'lambda': u'\nLambdas\n*******\n\n lambda_form ::= "lambda" [parameter_list]: expression\n old_lambda_form ::= "lambda" [parameter_list]: old_expression\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 name(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.\n', 'lists': u'\nList displays\n*************\n\nA list display is a possibly empty series of expressions enclosed in\nsquare brackets:\n\n list_display ::= "[" [expression_list | list_comprehension] "]"\n list_comprehension ::= expression list_for\n list_for ::= "for" target_list "in" old_expression_list [list_iter]\n old_expression_list ::= old_expression [("," old_expression)+ [","]]\n list_iter ::= list_for | list_if\n list_if ::= "if" old_expression [list_iter]\n\nA list display yields a new list object. Its contents are specified\nby providing either a list of expressions or a list comprehension.\nWhen a comma-separated list of expressions is supplied, its elements\nare evaluated from left to right and placed into the list object in\nthat order. When a list comprehension is supplied, it consists of a\nsingle expression followed by at least one ``for`` clause and zero or\nmore ``for`` or ``if`` clauses. In this case, the elements of the new\nlist are those that would be produced by considering each of the\n``for`` or ``if`` clauses a block, nesting from left to right, and\nevaluating the expression to produce a list element each time the\ninnermost block is reached [1].\n', 'naming': u"\nNaming and binding\n******************\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the '**-c**' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block's execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block's *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, in the\nsecond position of an ``except`` clause header or after ``as`` in a\n``with`` statement. The ``import`` statement of the form ``from ...\nimport *`` binds all names defined in the imported module, except\nthose beginning with an underscore. This form may only be used at the\nmodule level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtin namespace, the namespace of\nthe module ``__builtin__``. The global namespace is searched first.\nIf the name is not found there, the builtin namespace is searched.\nThe global statement must precede all uses of the name.\n\nThe built-in namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module's dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no 's'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\nNote: Users should not touch ``__builtins__``; it is strictly an\n implementation detail. Users wanting to override values in the\n built-in namespace should ``import`` the ``__builtin__`` (no 's')\n module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\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\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n", 'numbers': u"\nNumeric literals\n****************\n\nThere are four types of numeric literals: plain integers, long\nintegers, floating point numbers, and imaginary numbers. There are no\ncomplex literals (complex numbers can be formed by adding a real\nnumber and an imaginary 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", From python-checkins at python.org Tue Apr 28 21:01:44 2009 From: python-checkins at python.org (r.david.murray) Date: Tue, 28 Apr 2009 21:01:44 +0200 (CEST) Subject: [Python-checkins] r72078 - in python/branches/release26-maint: Doc/library/traceback.rst Message-ID: <20090428190144.6CBE71E417B@bag.python.org> Author: r.david.murray Date: Tue Apr 28 21:01:43 2009 New Revision: 72078 Log: Merged revisions 72038 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72038 | r.david.murray | 2009-04-27 13:22:36 -0400 (Mon, 27 Apr 2009) | 8 lines Make sys.xxx variable references into links, note that print_last only works when an exception gets to the interactive prompt, and update the examples after testing. The last one is now a valid Sphinx doctest, but of the preceding two one can't be made a doctest and the other one I'm postponing to 3.x because sphinx handles doctests as Unicode strings and that makes the 2.x output confusing. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/traceback.rst Modified: python/branches/release26-maint/Doc/library/traceback.rst ============================================================================== --- python/branches/release26-maint/Doc/library/traceback.rst (original) +++ python/branches/release26-maint/Doc/library/traceback.rst Tue Apr 28 21:01:43 2009 @@ -14,7 +14,7 @@ .. index:: object: traceback The module uses traceback objects --- this is the object type that is stored in -the variables ``sys.exc_traceback`` (deprecated) and ``sys.last_traceback`` and +the variables :data:`sys.exc_traceback` (deprecated) and :data:`sys.last_traceback` and returned as the third item from :func:`sys.exc_info`. The module defines the following functions: @@ -58,7 +58,8 @@ .. function:: print_last([limit[, file]]) This is a shorthand for ``print_exception(sys.last_type, sys.last_value, - sys.last_traceback, limit, file)``. + sys.last_traceback, limit, file)``. In general it will work only after + an exception has reached an interactive prompt (see :data:`sys.last_type`). .. function:: print_stack([f[, limit[, file]]]) @@ -195,27 +196,25 @@ print "*** format_tb:" print repr(traceback.format_tb(exceptionTraceback)) print "*** tb_lineno:", traceback.tb_lineno(exceptionTraceback) - print "*** print_last:" - traceback.print_last() The output for the example would look similar to this:: *** print_tb: - File "", line 9, in + File "", line 10, in lumberjack() *** print_exception: Traceback (most recent call last): - File "", line 9, in + File "", line 10, in lumberjack() - File "", line 3, in lumberjack + File "", line 4, in lumberjack bright_side_of_death() IndexError: tuple index out of range *** print_exc: Traceback (most recent call last): - File "", line 9, in + File "", line 10, in lumberjack() - File "", line 3, in lumberjack + File "", line 4, in lumberjack bright_side_of_death() IndexError: tuple index out of range *** format_exc, first and last line: @@ -223,27 +222,19 @@ IndexError: tuple index out of range *** format_exception: ['Traceback (most recent call last):\n', - ' File "", line 9, in \n lumberjack()\n', - ' File "", line 3, in lumberjack\n bright_side_of_death()\n', - ' File "", line 6, in bright_side_of_death\n return tuple()[0]\n', + ' File "", line 10, in \n lumberjack()\n', + ' File "", line 4, in lumberjack\n bright_side_of_death()\n', + ' File "", line 7, in bright_side_of_death\n return tuple()[0]\n', 'IndexError: tuple index out of range\n'] *** extract_tb: - [('', 9, '', 'lumberjack()'), - ('', 3, 'lumberjack', 'bright_side_of_death()'), - ('', 6, 'bright_side_of_death', 'return tuple()[0]')] + [('', 10, '', 'lumberjack()'), + ('', 4, 'lumberjack', 'bright_side_of_death()'), + (u'', 7, 'bright_side_of_death', 'return tuple()[0]')] *** format_tb: - [' File "", line 9, in \n lumberjack()\n', - ' File "", line 3, in lumberjack\n bright_side_of_death()\n', - ' File "", line 6, in bright_side_of_death\n return tuple()[0]\n'] - *** tb_lineno: 2 - *** print_last: - Traceback (most recent call last): - File "", line 9, in - lumberjack() - File "", line 3, in lumberjack - bright_side_of_death() - IndexError: tuple index out of range - + [' File "", line 10, in \n lumberjack()\n', + ' File "", line 4, in lumberjack\n bright_side_of_death()\n', + ' File "", line 7, in bright_side_of_death\n return tuple()[0]\n'] + *** tb_lineno: 10 The following example shows the different ways to print and format the stack:: @@ -271,7 +262,10 @@ ' File "", line 8, in lumberstack\n print repr(traceback.format_stack())\n'] -This last example demonstrates the final few formatting functions:: +This last example demonstrates the final few formatting functions: + +.. doctest:: + :options: +NORMALIZE_WHITESPACE >>> import traceback >>> traceback.format_list([('spam.py', 3, '', 'spam.eggs()'), From python-checkins at python.org Tue Apr 28 21:02:56 2009 From: python-checkins at python.org (r.david.murray) Date: Tue, 28 Apr 2009 21:02:56 +0200 (CEST) Subject: [Python-checkins] r72079 - python/trunk/Doc/library/traceback.rst Message-ID: <20090428190256.805071E4220@bag.python.org> Author: r.david.murray Date: Tue Apr 28 21:02:55 2009 New Revision: 72079 Log: Remove spurious 'u'. Modified: python/trunk/Doc/library/traceback.rst Modified: python/trunk/Doc/library/traceback.rst ============================================================================== --- python/trunk/Doc/library/traceback.rst (original) +++ python/trunk/Doc/library/traceback.rst Tue Apr 28 21:02:55 2009 @@ -229,13 +229,14 @@ *** extract_tb: [('', 10, '', 'lumberjack()'), ('', 4, 'lumberjack', 'bright_side_of_death()'), - (u'', 7, 'bright_side_of_death', 'return tuple()[0]')] + ('', 7, 'bright_side_of_death', 'return tuple()[0]')] *** format_tb: [' File "", line 10, in \n lumberjack()\n', ' File "", line 4, in lumberjack\n bright_side_of_death()\n', ' File "", line 7, in bright_side_of_death\n return tuple()[0]\n'] *** tb_lineno: 10 + The following example shows the different ways to print and format the stack:: >>> import traceback From python-checkins at python.org Tue Apr 28 21:03:52 2009 From: python-checkins at python.org (r.david.murray) Date: Tue, 28 Apr 2009 21:03:52 +0200 (CEST) Subject: [Python-checkins] r72080 - in python/branches/release26-maint: Doc/library/traceback.rst Message-ID: <20090428190352.2BFBE1E4083@bag.python.org> Author: r.david.murray Date: Tue Apr 28 21:03:51 2009 New Revision: 72080 Log: Merged revisions 72079 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72079 | r.david.murray | 2009-04-28 15:02:55 -0400 (Tue, 28 Apr 2009) | 2 lines Remove spurious 'u'. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/library/traceback.rst Modified: python/branches/release26-maint/Doc/library/traceback.rst ============================================================================== --- python/branches/release26-maint/Doc/library/traceback.rst (original) +++ python/branches/release26-maint/Doc/library/traceback.rst Tue Apr 28 21:03:51 2009 @@ -229,13 +229,14 @@ *** extract_tb: [('', 10, '', 'lumberjack()'), ('', 4, 'lumberjack', 'bright_side_of_death()'), - (u'', 7, 'bright_side_of_death', 'return tuple()[0]')] + ('', 7, 'bright_side_of_death', 'return tuple()[0]')] *** format_tb: [' File "", line 10, in \n lumberjack()\n', ' File "", line 4, in lumberjack\n bright_side_of_death()\n', ' File "", line 7, in bright_side_of_death\n return tuple()[0]\n'] *** tb_lineno: 10 + The following example shows the different ways to print and format the stack:: >>> import traceback From python-checkins at python.org Tue Apr 28 21:23:41 2009 From: python-checkins at python.org (thomas.heller) Date: Tue, 28 Apr 2009 21:23:41 +0200 (CEST) Subject: [Python-checkins] r72081 - in python/trunk: Misc/NEWS Modules/_ctypes/libffi/configure Modules/_ctypes/libffi/configure.ac Message-ID: <20090428192341.9B9C81E4055@bag.python.org> Author: thomas.heller Date: Tue Apr 28 21:23:41 2009 New Revision: 72081 Log: Issue #4305: ctypes fails to build on mipsel-linux-gnu (detects mips instead of mipsel) Modified: python/trunk/Misc/NEWS python/trunk/Modules/_ctypes/libffi/configure python/trunk/Modules/_ctypes/libffi/configure.ac Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Tue Apr 28 21:23:41 2009 @@ -255,6 +255,8 @@ Library ------- +- Issue #4305: ctypes should now build again on mipsel-linux-gnu + - Issue #1734234: Massively speedup ``unicodedata.normalize()`` when the string is already in normalized form, by performing a quick check beforehand. Original patch by Rauli Ruohonen. Modified: python/trunk/Modules/_ctypes/libffi/configure ============================================================================== --- python/trunk/Modules/_ctypes/libffi/configure (original) +++ python/trunk/Modules/_ctypes/libffi/configure Tue Apr 28 21:23:41 2009 @@ -20426,10 +20426,10 @@ ;; mips-sgi-irix5.* | mips-sgi-irix6.*) - TARGET=MIPS; TARGETDIR=mips + TARGET=MIPS_IRIX; TARGETDIR=mips ;; mips*-*-linux*) - TARGET=MIPS; TARGETDIR=mips + TARGET=MIPS_LINUX; TARGETDIR=mips ;; powerpc*-*-linux* | powerpc-*-sysv*) @@ -20484,7 +20484,7 @@ { (exit 1); exit 1; }; } fi - if test x$TARGET = xMIPS; then + if expr x$TARGET : 'xMIPS' > /dev/null; then MIPS_TRUE= MIPS_FALSE='#' else Modified: python/trunk/Modules/_ctypes/libffi/configure.ac ============================================================================== --- python/trunk/Modules/_ctypes/libffi/configure.ac (original) +++ python/trunk/Modules/_ctypes/libffi/configure.ac Tue Apr 28 21:23:41 2009 @@ -106,10 +106,10 @@ ;; mips-sgi-irix5.* | mips-sgi-irix6.*) - TARGET=MIPS; TARGETDIR=mips + TARGET=MIPS_IRIX; TARGETDIR=mips ;; mips*-*-linux*) - TARGET=MIPS; TARGETDIR=mips + TARGET=MIPS_LINUX; TARGETDIR=mips ;; powerpc*-*-linux* | powerpc-*-sysv*) @@ -162,7 +162,7 @@ AC_MSG_ERROR(["libffi has not been ported to $host."]) fi -AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS) +AM_CONDITIONAL(MIPS,[expr x$TARGET : 'xMIPS' > /dev/null]) AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC) AM_CONDITIONAL(X86, test x$TARGET = xX86) AM_CONDITIONAL(X86_FREEBSD, test x$TARGET = xX86_FREEBSD) From buildbot at python.org Tue Apr 28 21:39:00 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 28 Apr 2009 19:39:00 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090428193900.F02141E4011@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/310 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Tue Apr 28 21:55:59 2009 From: python-checkins at python.org (thomas.heller) Date: Tue, 28 Apr 2009 21:55:59 +0200 (CEST) Subject: [Python-checkins] r72082 - in python/branches/py3k: Misc/NEWS Modules/_ctypes/libffi/configure Modules/_ctypes/libffi/configure.ac Message-ID: <20090428195559.244CE1E4011@bag.python.org> Author: thomas.heller Date: Tue Apr 28 21:55:58 2009 New Revision: 72082 Log: Merged revisions 72081 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72081 | thomas.heller | 2009-04-28 21:23:41 +0200 (Di, 28 Apr 2009) | 3 lines Issue #4305: ctypes fails to build on mipsel-linux-gnu (detects mips instead of mipsel) ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Misc/NEWS python/branches/py3k/Modules/_ctypes/libffi/configure python/branches/py3k/Modules/_ctypes/libffi/configure.ac Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Tue Apr 28 21:55:58 2009 @@ -92,6 +92,8 @@ Library ------- +- Issue #4305: ctypes should now build again on mipsel-linux-gnu + - Issue #1734234: Massively speedup ``unicodedata.normalize()`` when the string is already in normalized form, by performing a quick check beforehand. Original patch by Rauli Ruohonen. Modified: python/branches/py3k/Modules/_ctypes/libffi/configure ============================================================================== --- python/branches/py3k/Modules/_ctypes/libffi/configure (original) +++ python/branches/py3k/Modules/_ctypes/libffi/configure Tue Apr 28 21:55:58 2009 @@ -20426,10 +20426,10 @@ ;; mips-sgi-irix5.* | mips-sgi-irix6.*) - TARGET=MIPS; TARGETDIR=mips + TARGET=MIPS_IRIX; TARGETDIR=mips ;; mips*-*-linux*) - TARGET=MIPS; TARGETDIR=mips + TARGET=MIPS_LINUX; TARGETDIR=mips ;; powerpc*-*-linux* | powerpc-*-sysv*) @@ -20484,7 +20484,7 @@ { (exit 1); exit 1; }; } fi - if test x$TARGET = xMIPS; then + if expr x$TARGET : 'xMIPS' > /dev/null; then MIPS_TRUE= MIPS_FALSE='#' else Modified: python/branches/py3k/Modules/_ctypes/libffi/configure.ac ============================================================================== --- python/branches/py3k/Modules/_ctypes/libffi/configure.ac (original) +++ python/branches/py3k/Modules/_ctypes/libffi/configure.ac Tue Apr 28 21:55:58 2009 @@ -106,10 +106,10 @@ ;; mips-sgi-irix5.* | mips-sgi-irix6.*) - TARGET=MIPS; TARGETDIR=mips + TARGET=MIPS_IRIX; TARGETDIR=mips ;; mips*-*-linux*) - TARGET=MIPS; TARGETDIR=mips + TARGET=MIPS_LINUX; TARGETDIR=mips ;; powerpc*-*-linux* | powerpc-*-sysv*) @@ -162,7 +162,7 @@ AC_MSG_ERROR(["libffi has not been ported to $host."]) fi -AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS) +AM_CONDITIONAL(MIPS,[expr x$TARGET : 'xMIPS' > /dev/null]) AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC) AM_CONDITIONAL(X86, test x$TARGET = xX86) AM_CONDITIONAL(X86_FREEBSD, test x$TARGET = xX86_FREEBSD) From python-checkins at python.org Tue Apr 28 22:01:18 2009 From: python-checkins at python.org (thomas.heller) Date: Tue, 28 Apr 2009 22:01:18 +0200 (CEST) Subject: [Python-checkins] r72083 - in python/branches/release26-maint: Misc/NEWS Modules/_ctypes/libffi/configure Modules/_ctypes/libffi/configure.ac Message-ID: <20090428200118.D89701E4011@bag.python.org> Author: thomas.heller Date: Tue Apr 28 22:01:18 2009 New Revision: 72083 Log: Merged revisions 72081 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72081 | thomas.heller | 2009-04-28 21:23:41 +0200 (Di, 28 Apr 2009) | 3 lines Issue #4305: ctypes fails to build on mipsel-linux-gnu (detects mips instead of mipsel) ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Misc/NEWS python/branches/release26-maint/Modules/_ctypes/libffi/configure python/branches/release26-maint/Modules/_ctypes/libffi/configure.ac Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Tue Apr 28 22:01:18 2009 @@ -27,6 +27,8 @@ Library ------- +- Issue #4305: ctypes should now build again on mipsel-linux-gnu + - Issue #5853: calling a function of the mimetypes module from several threads at once could hit the recursion limit if the mimetypes database hadn't been initialized before. Modified: python/branches/release26-maint/Modules/_ctypes/libffi/configure ============================================================================== --- python/branches/release26-maint/Modules/_ctypes/libffi/configure (original) +++ python/branches/release26-maint/Modules/_ctypes/libffi/configure Tue Apr 28 22:01:18 2009 @@ -20426,10 +20426,10 @@ ;; mips-sgi-irix5.* | mips-sgi-irix6.*) - TARGET=MIPS; TARGETDIR=mips + TARGET=MIPS_IRIX; TARGETDIR=mips ;; mips*-*-linux*) - TARGET=MIPS; TARGETDIR=mips + TARGET=MIPS_LINUX; TARGETDIR=mips ;; powerpc*-*-linux* | powerpc-*-sysv*) @@ -20484,7 +20484,7 @@ { (exit 1); exit 1; }; } fi - if test x$TARGET = xMIPS; then + if expr x$TARGET : 'xMIPS' > /dev/null; then MIPS_TRUE= MIPS_FALSE='#' else Modified: python/branches/release26-maint/Modules/_ctypes/libffi/configure.ac ============================================================================== --- python/branches/release26-maint/Modules/_ctypes/libffi/configure.ac (original) +++ python/branches/release26-maint/Modules/_ctypes/libffi/configure.ac Tue Apr 28 22:01:18 2009 @@ -106,10 +106,10 @@ ;; mips-sgi-irix5.* | mips-sgi-irix6.*) - TARGET=MIPS; TARGETDIR=mips + TARGET=MIPS_IRIX; TARGETDIR=mips ;; mips*-*-linux*) - TARGET=MIPS; TARGETDIR=mips + TARGET=MIPS_LINUX; TARGETDIR=mips ;; powerpc*-*-linux* | powerpc-*-sysv*) @@ -162,7 +162,7 @@ AC_MSG_ERROR(["libffi has not been ported to $host."]) fi -AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS) +AM_CONDITIONAL(MIPS,[expr x$TARGET : 'xMIPS' > /dev/null]) AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC) AM_CONDITIONAL(X86, test x$TARGET = xX86) AM_CONDITIONAL(X86_FREEBSD, test x$TARGET = xX86_FREEBSD) From python-checkins at python.org Tue Apr 28 22:02:31 2009 From: python-checkins at python.org (thomas.heller) Date: Tue, 28 Apr 2009 22:02:31 +0200 (CEST) Subject: [Python-checkins] r72084 - in python/branches/release30-maint: Misc/NEWS Modules/_ctypes/libffi/configure Modules/_ctypes/libffi/configure.ac Message-ID: <20090428200231.438161E4011@bag.python.org> Author: thomas.heller Date: Tue Apr 28 22:02:30 2009 New Revision: 72084 Log: Merged revisions 72082 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r72082 | thomas.heller | 2009-04-28 21:55:58 +0200 (Di, 28 Apr 2009) | 10 lines Merged revisions 72081 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72081 | thomas.heller | 2009-04-28 21:23:41 +0200 (Di, 28 Apr 2009) | 3 lines Issue #4305: ctypes fails to build on mipsel-linux-gnu (detects mips instead of mipsel) ........ ................ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Misc/NEWS python/branches/release30-maint/Modules/_ctypes/libffi/configure python/branches/release30-maint/Modules/_ctypes/libffi/configure.ac Modified: python/branches/release30-maint/Misc/NEWS ============================================================================== --- python/branches/release30-maint/Misc/NEWS (original) +++ python/branches/release30-maint/Misc/NEWS Tue Apr 28 22:02:30 2009 @@ -42,6 +42,8 @@ Library ------- +- Issue #4305: ctypes should now build again on mipsel-linux-gnu + - Issue #5853: calling a function of the mimetypes module from several threads at once could hit the recursion limit if the mimetypes database hadn't been initialized before. Modified: python/branches/release30-maint/Modules/_ctypes/libffi/configure ============================================================================== --- python/branches/release30-maint/Modules/_ctypes/libffi/configure (original) +++ python/branches/release30-maint/Modules/_ctypes/libffi/configure Tue Apr 28 22:02:30 2009 @@ -20426,10 +20426,10 @@ ;; mips-sgi-irix5.* | mips-sgi-irix6.*) - TARGET=MIPS; TARGETDIR=mips + TARGET=MIPS_IRIX; TARGETDIR=mips ;; mips*-*-linux*) - TARGET=MIPS; TARGETDIR=mips + TARGET=MIPS_LINUX; TARGETDIR=mips ;; powerpc*-*-linux* | powerpc-*-sysv*) @@ -20484,7 +20484,7 @@ { (exit 1); exit 1; }; } fi - if test x$TARGET = xMIPS; then + if expr x$TARGET : 'xMIPS' > /dev/null; then MIPS_TRUE= MIPS_FALSE='#' else Modified: python/branches/release30-maint/Modules/_ctypes/libffi/configure.ac ============================================================================== --- python/branches/release30-maint/Modules/_ctypes/libffi/configure.ac (original) +++ python/branches/release30-maint/Modules/_ctypes/libffi/configure.ac Tue Apr 28 22:02:30 2009 @@ -106,10 +106,10 @@ ;; mips-sgi-irix5.* | mips-sgi-irix6.*) - TARGET=MIPS; TARGETDIR=mips + TARGET=MIPS_IRIX; TARGETDIR=mips ;; mips*-*-linux*) - TARGET=MIPS; TARGETDIR=mips + TARGET=MIPS_LINUX; TARGETDIR=mips ;; powerpc*-*-linux* | powerpc-*-sysv*) @@ -162,7 +162,7 @@ AC_MSG_ERROR(["libffi has not been ported to $host."]) fi -AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS) +AM_CONDITIONAL(MIPS,[expr x$TARGET : 'xMIPS' > /dev/null]) AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC) AM_CONDITIONAL(X86, test x$TARGET = xX86) AM_CONDITIONAL(X86_FREEBSD, test x$TARGET = xX86_FREEBSD) From buildbot at python.org Tue Apr 28 22:11:38 2009 From: buildbot at python.org (buildbot at python.org) Date: Tue, 28 Apr 2009 20:11:38 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 3.x Message-ID: <20090428201138.CB47A1E4011@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%203.x/builds/835 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: thomas.heller BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_time ====================================================================== FAIL: test_tzset (test.test_time.TimeTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_time.py", line 166, in test_tzset self.failIfEqual(time.gmtime(xmas2002), time.localtime(xmas2002)) AssertionError: time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) == time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Tue Apr 28 23:48:36 2009 From: python-checkins at python.org (georg.brandl) Date: Tue, 28 Apr 2009 23:48:36 +0200 (CEST) Subject: [Python-checkins] r72085 - in python/trunk/Doc: howto/functional.rst library/collections.rst library/decimal.rst library/subprocess.rst whatsnew/2.7.rst Message-ID: <20090428214836.8CA321E401F@bag.python.org> Author: georg.brandl Date: Tue Apr 28 23:48:35 2009 New Revision: 72085 Log: Make the doctests in the docs pass, except for those in the turtle module. Modified: python/trunk/Doc/howto/functional.rst python/trunk/Doc/library/collections.rst python/trunk/Doc/library/decimal.rst python/trunk/Doc/library/subprocess.rst python/trunk/Doc/whatsnew/2.7.rst Modified: python/trunk/Doc/howto/functional.rst ============================================================================== --- python/trunk/Doc/howto/functional.rst (original) +++ python/trunk/Doc/howto/functional.rst Tue Apr 28 23:48:35 2009 @@ -472,7 +472,7 @@ >>> gen = generate_ints(3) >>> gen - + >>> gen.next() 0 >>> gen.next() Modified: python/trunk/Doc/library/collections.rst ============================================================================== --- python/trunk/Doc/library/collections.rst (original) +++ python/trunk/Doc/library/collections.rst Tue Apr 28 23:48:35 2009 @@ -184,7 +184,7 @@ class is similar to bags or multisets in other languages. Elements are counted from an *iterable* or initialized from another - *mapping* (or counter):: + *mapping* (or counter): >>> c = Counter() # a new, empty counter >>> c = Counter('gallahad') # a new counter from an iterable @@ -192,7 +192,7 @@ >>> c = Counter(cats=4, dogs=8) # a new counter from keyword args Counter objects have a dictionary interface except that they return a zero - count for missing items instead of raising a :exc:`KeyError`:: + count for missing items instead of raising a :exc:`KeyError`: >>> c = Counter(['eggs', 'ham']) >>> c['bacon'] # count of a missing element is zero @@ -225,7 +225,7 @@ Return a list of the *n* most common elements and their counts from the most common to the least. If *n* is not specified, :func:`most_common` returns *all* elements in the counter. Elements with equal counts are - ordered arbitrarily:: + ordered arbitrarily: >>> Counter('abracadabra').most_common(3) [('a', 5), ('r', 2), ('b', 2)] Modified: python/trunk/Doc/library/decimal.rst ============================================================================== --- python/trunk/Doc/library/decimal.rst (original) +++ python/trunk/Doc/library/decimal.rst Tue Apr 28 23:48:35 2009 @@ -1850,7 +1850,7 @@ >>> Decimal('3.214').quantize(TWOPLACES, context=Context(traps=[Inexact])) Traceback (most recent call last): ... - Inexact + Inexact: None Q. Once I have valid two place inputs, how do I maintain that invariant throughout an application? Modified: python/trunk/Doc/library/subprocess.rst ============================================================================== --- python/trunk/Doc/library/subprocess.rst (original) +++ python/trunk/Doc/library/subprocess.rst Tue Apr 28 23:48:35 2009 @@ -181,13 +181,13 @@ :attr:`returncode` attribute and output in the :attr:`output` attribute. - The arguments are the same as for the :class:`Popen` constructor. Example: + The arguments are the same as for the :class:`Popen` constructor. Example:: >>> subprocess.check_output(["ls", "-l", "/dev/null"]) 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' The stdout argument is not allowed as it is used internally. - To capture standard error in the result, use stderr=subprocess.STDOUT. + To capture standard error in the result, use ``stderr=subprocess.STDOUT``:: >>> subprocess.check_output( ["/bin/sh", "-c", "ls non_existent_file ; exit 0"], Modified: python/trunk/Doc/whatsnew/2.7.rst ============================================================================== --- python/trunk/Doc/whatsnew/2.7.rst (original) +++ python/trunk/Doc/whatsnew/2.7.rst Tue Apr 28 23:48:35 2009 @@ -220,21 +220,24 @@ * New class: the :class:`Counter` class in the :mod:`collections` module is useful for tallying data. :class:`Counter` instances behave mostly like dictionaries but return zero for missing keys instead of - raising a :exc:`KeyError`:: + raising a :exc:`KeyError`: - >>> from collections import Counter - >>> c=Counter() - >>> for letter in 'here is a sample of english text': - ... c[letter] += 1 - ... - >>> c - Counter({' ': 6, 'e': 5, 's': 3, 'a': 2, 'i': 2, 'h': 2, - 'l': 2, 't': 2, 'g': 1, 'f': 1, 'm': 1, 'o': 1, 'n': 1, - 'p': 1, 'r': 1, 'x': 1}) - >>> c['e'] - 5 - >>> c['z'] - 0 + .. doctest:: + :options: +NORMALIZE_WHITESPACE + + >>> from collections import Counter + >>> c = Counter() + >>> for letter in 'here is a sample of english text': + ... c[letter] += 1 + ... + >>> c + Counter({' ': 6, 'e': 5, 's': 3, 'a': 2, 'i': 2, 'h': 2, + 'l': 2, 't': 2, 'g': 1, 'f': 1, 'm': 1, 'o': 1, 'n': 1, + 'p': 1, 'r': 1, 'x': 1}) + >>> c['e'] + 5 + >>> c['z'] + 0 There are two additional :class:`Counter` methods: :meth:`most_common` returns the N most common elements and their counts, and :meth:`elements` @@ -247,7 +250,7 @@ 'a', 'a', ' ', ' ', ' ', ' ', ' ', ' ', 'e', 'e', 'e', 'e', 'e', 'g', 'f', 'i', 'i', 'h', 'h', 'm', 'l', 'l', 'o', 'n', 'p', 's', - 's', 's', 'r', 't', 't', 'x'] + 's', 's', 'r', 't', 't', 'x' Contributed by Raymond Hettinger; :issue:`1696199`. @@ -257,7 +260,8 @@ renamed to legal names that are derived from the field's position within the list of fields: - >>> T=namedtuple('T', ['field1', '$illegal', 'for', 'field2'], rename=True) + >>> from collections import namedtuple + >>> T = namedtuple('T', ['field1', '$illegal', 'for', 'field2'], rename=True) >>> T._fields ('field1', '_1', '_2', 'field2') From nnorwitz at gmail.com Wed Apr 29 00:10:29 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Tue, 28 Apr 2009 18:10:29 -0400 Subject: [Python-checkins] Python Regression Test Failures refleak (2) Message-ID: <20090428221029.GA23410@python.psfb.org> More important issues: ---------------------- test_pydoc leaked [-21, 21, 21] references, sum=21 test_ssl leaked [322, 0, -403] references, sum=-81 Less important issues: ---------------------- test_cmd_line leaked [0, 0, 25] references, sum=25 test_file leaked [0, 0, 80] references, sum=80 test_smtplib leaked [-2, 14, -96] references, sum=-84 test_sys leaked [-42, 42, -42] references, sum=-42 test_threading leaked [48, 48, 48] references, sum=144 test_urllib2_localnet leaked [-280, 286, -280] references, sum=-274 From python-checkins at python.org Wed Apr 29 02:34:27 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 29 Apr 2009 02:34:27 +0200 (CEST) Subject: [Python-checkins] r72086 - in python/branches/py3k: Doc/library/tokenize.rst Lib/tokenize.py Message-ID: <20090429003427.96A301E4018@bag.python.org> Author: raymond.hettinger Date: Wed Apr 29 02:34:27 2009 New Revision: 72086 Log: Issue #5857: tokenize.tokenize() now returns named tuples. Modified: python/branches/py3k/Doc/library/tokenize.rst python/branches/py3k/Lib/tokenize.py Modified: python/branches/py3k/Doc/library/tokenize.rst ============================================================================== --- python/branches/py3k/Doc/library/tokenize.rst (original) +++ python/branches/py3k/Doc/library/tokenize.rst Wed Apr 29 02:34:27 2009 @@ -27,7 +27,12 @@ column where the token begins in the source; a 2-tuple ``(erow, ecol)`` of ints specifying the row and column where the token ends in the source; and the line on which the token was found. The line passed (the last tuple item) - is the *logical* line; continuation lines are included. + is the *logical* line; continuation lines are included. The 5 tuple is + returned as a :term:`named tuple` with the field names: + ``type string start end line``. + + .. versionchanged:: 3.1 + Added support for named tuples. :func:`tokenize` determines the source encoding of the file by looking for a UTF-8 BOM or encoding cookie, according to :pep:`263`. Modified: python/branches/py3k/Lib/tokenize.py ============================================================================== --- python/branches/py3k/Lib/tokenize.py (original) +++ python/branches/py3k/Lib/tokenize.py Wed Apr 29 02:34:27 2009 @@ -24,6 +24,7 @@ 'Skip Montanaro, Raymond Hettinger, Trent Nelson, ' 'Michael Foord') +import collections import re, string, sys from token import * from codecs import lookup, BOM_UTF8 @@ -31,7 +32,7 @@ import token __all__ = [x for x in dir(token) if x[0] != '_'] + ["COMMENT", "tokenize", - "detect_encoding", "NL", "untokenize", "ENCODING"] + "detect_encoding", "NL", "untokenize", "ENCODING", "Tokenize"] del token COMMENT = N_TOKENS @@ -42,6 +43,8 @@ tok_name[ENCODING] = 'ENCODING' N_TOKENS += 3 +TokenInfo = collections.namedtuple('TokenInfo', 'type string start end line') + def group(*choices): return '(' + '|'.join(choices) + ')' def any(*choices): return group(*choices) + '*' def maybe(*choices): return group(*choices) + '?' @@ -346,7 +349,7 @@ indents = [0] if encoding is not None: - yield (ENCODING, encoding, (0, 0), (0, 0), '') + yield TokenInfo(ENCODING, encoding, (0, 0), (0, 0), '') while True: # loop over lines in stream try: line = readline() @@ -364,12 +367,12 @@ endmatch = endprog.match(line) if endmatch: pos = end = endmatch.end(0) - yield (STRING, contstr + line[:end], + yield TokenInfo(STRING, contstr + line[:end], strstart, (lnum, end), contline + line) contstr, needcont = '', 0 contline = None elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n': - yield (ERRORTOKEN, contstr + line, + yield TokenInfo(ERRORTOKEN, contstr + line, strstart, (lnum, len(line)), contline) contstr = '' contline = None @@ -394,25 +397,25 @@ if line[pos] == '#': comment_token = line[pos:].rstrip('\r\n') nl_pos = pos + len(comment_token) - yield (COMMENT, comment_token, + yield TokenInfo(COMMENT, comment_token, (lnum, pos), (lnum, pos + len(comment_token)), line) - yield (NL, line[nl_pos:], + yield TokenInfo(NL, line[nl_pos:], (lnum, nl_pos), (lnum, len(line)), line) else: - yield ((NL, COMMENT)[line[pos] == '#'], line[pos:], + yield TokenInfo((NL, COMMENT)[line[pos] == '#'], line[pos:], (lnum, pos), (lnum, len(line)), line) continue if column > indents[-1]: # count indents or dedents indents.append(column) - yield (INDENT, line[:pos], (lnum, 0), (lnum, pos), line) + yield TokenInfo(INDENT, line[:pos], (lnum, 0), (lnum, pos), line) while column < indents[-1]: if column not in indents: raise IndentationError( "unindent does not match any outer indentation level", ("", lnum, pos, line)) indents = indents[:-1] - yield (DEDENT, '', (lnum, pos), (lnum, pos), line) + yield TokenInfo(DEDENT, '', (lnum, pos), (lnum, pos), line) else: # continued statement if not line: @@ -428,20 +431,20 @@ if (initial in numchars or # ordinary number (initial == '.' and token != '.' and token != '...')): - yield (NUMBER, token, spos, epos, line) + yield TokenInfo(NUMBER, token, spos, epos, line) elif initial in '\r\n': - yield (NL if parenlev > 0 else NEWLINE, + yield TokenInfo(NL if parenlev > 0 else NEWLINE, token, spos, epos, line) elif initial == '#': assert not token.endswith("\n") - yield (COMMENT, token, spos, epos, line) + yield TokenInfo(COMMENT, token, spos, epos, line) elif token in triple_quoted: endprog = endprogs[token] endmatch = endprog.match(line, pos) if endmatch: # all on one line pos = endmatch.end(0) token = line[start:pos] - yield (STRING, token, spos, (lnum, pos), line) + yield TokenInfo(STRING, token, spos, (lnum, pos), line) else: strstart = (lnum, start) # multiple lines contstr = line[start:] @@ -458,23 +461,23 @@ contline = line break else: # ordinary string - yield (STRING, token, spos, epos, line) + yield TokenInfo(STRING, token, spos, epos, line) elif initial in namechars: # ordinary name - yield (NAME, token, spos, epos, line) + yield TokenInfo(NAME, token, spos, epos, line) elif initial == '\\': # continued stmt continued = 1 else: if initial in '([{': parenlev = parenlev + 1 elif initial in ')]}': parenlev = parenlev - 1 - yield (OP, token, spos, epos, line) + yield TokenInfo(OP, token, spos, epos, line) else: - yield (ERRORTOKEN, line[pos], + yield TokenInfo(ERRORTOKEN, line[pos], (lnum, pos), (lnum, pos+1), line) pos = pos + 1 for indent in indents[1:]: # pop remaining indent levels - yield (DEDENT, '', (lnum, 0), (lnum, 0), '') - yield (ENDMARKER, '', (lnum, 0), (lnum, 0), '') + yield TokenInfo(DEDENT, '', (lnum, 0), (lnum, 0), '') + yield TokenInfo(ENDMARKER, '', (lnum, 0), (lnum, 0), '') # An undocumented, backwards compatible, API for all the places in the standard From python-checkins at python.org Wed Apr 29 02:38:08 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 29 Apr 2009 02:38:08 +0200 (CEST) Subject: [Python-checkins] r72087 - python/branches/py3k/Misc/NEWS Message-ID: <20090429003808.84C6A1E40C9@bag.python.org> Author: raymond.hettinger Date: Wed Apr 29 02:38:08 2009 New Revision: 72087 Log: Issue #5857: tokenize.tokenize() now returns named tuples. Modified: python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Apr 29 02:38:08 2009 @@ -92,6 +92,8 @@ Library ------- +- Issue #5857: tokenize.tokenize() now returns named tuples. + - Issue #4305: ctypes should now build again on mipsel-linux-gnu - Issue #1734234: Massively speedup ``unicodedata.normalize()`` when the From buildbot at python.org Wed Apr 29 02:41:57 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 29 Apr 2009 00:41:57 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090429004157.8F12E1E4019@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/596 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: raymond.hettinger BUILD FAILED: failed compile sincerely, -The Buildbot From python-checkins at python.org Wed Apr 29 08:26:44 2009 From: python-checkins at python.org (martin.v.loewis) Date: Wed, 29 Apr 2009 08:26:44 +0200 (CEST) Subject: [Python-checkins] r72088 - peps/trunk/pep-0383.txt Message-ID: <20090429062644.F18561E4022@bag.python.org> Author: martin.v.loewis Date: Wed Apr 29 08:26:43 2009 New Revision: 72088 Log: Clarify that byte-oriented interfaces are not touched. Add example showing script-level usage of the error handler. Modified: peps/trunk/pep-0383.txt Modified: peps/trunk/pep-0383.txt ============================================================================== --- peps/trunk/pep-0383.txt (original) +++ peps/trunk/pep-0383.txt Wed Apr 29 08:26:43 2009 @@ -88,6 +88,10 @@ (which, among other restrictions, disallows to encode surrogate codes in UTF-8). +Byte-orientied interfaces that already exist in Python 3.0 are not +affected by this specification. They are neither enhanced nor +deprecated. + Discussion ========== @@ -106,7 +110,15 @@ representation. Applications that need to process the original byte strings can obtain them by encoding the character strings with the file system encoding, passing "python-escape" as the error handler -name. +name. For example, a function that works like os.listdir, except +for accepting and returning bytes, would be written as:: + + def listdir_b(dirname): + fse = sys.getfilesystemencoding() + dirname = dirname.decode(fse, "python-escape") + for fn in os.listdir(dirname): + # fn is now a str object + yield fn.encode(fse, "python-escape" Copyright ========= From python-checkins at python.org Wed Apr 29 08:37:13 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 29 Apr 2009 08:37:13 +0200 (CEST) Subject: [Python-checkins] r72089 - python/branches/py3k/Doc/library/functions.rst Message-ID: <20090429063713.1B29C1E4011@bag.python.org> Author: georg.brandl Date: Wed Apr 29 08:37:12 2009 New Revision: 72089 Log: Die, buffer(), die. 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 Wed Apr 29 08:37:12 2009 @@ -98,7 +98,7 @@ :class:`bytearray` -- it has the same non-mutating methods and the same indexing and slicing behavior. - Accordingly, constructor arguments are interpreted as for :func:`buffer`. + Accordingly, constructor arguments are interpreted as for :func:`bytearray`. Bytes objects can also be created with literals, see :ref:`strings`. From python-checkins at python.org Wed Apr 29 08:39:41 2009 From: python-checkins at python.org (martin.v.loewis) Date: Wed, 29 Apr 2009 08:39:41 +0200 (CEST) Subject: [Python-checkins] r72090 - peps/trunk/pep-0382.txt Message-ID: <20090429063941.3B8071E4011@bag.python.org> Author: martin.v.loewis Date: Wed Apr 29 08:39:41 2009 New Revision: 72090 Log: Make import algorithm explicit. Mention extension naming discussion. Modified: peps/trunk/pep-0382.txt Modified: peps/trunk/pep-0382.txt ============================================================================== --- peps/trunk/pep-0382.txt (original) +++ peps/trunk/pep-0382.txt Wed Apr 29 08:39:41 2009 @@ -115,9 +115,20 @@ extend_path will be extended to recognize namespace packages according to this PEP, and avoid adding directories twice to __path__. -No other change to the importing mechanism is made; searching -modules (including __init__.py) will continue to stop at the first -module encountered. +No other change to the importing mechanism is made; searching modules +(including __init__.py) will continue to stop at the first module +encountered. In summary, the process import a package foo works like +this: + + 1. sys.path is search for a directory foo, or a file foo.. + If a file is found, it is treated as a module, and imported. + 2. if it is a directory, it checks for *.pkg files. If it finds + any, a package is created, and its __path__ is extended. + 3. The __init__ module is imported; this import will search the + __path__ that got computed already. + 4. If neither a *.pkg file nor an __init__.py was found, the + directory is skipped, and search for the module/package + continues. Discussion ========== @@ -149,6 +160,9 @@ users of this feature are encouraged to comment on this particular question. +It also has been proposed to rename the extension from .pkg to +something else. + Copyright ========= From python-checkins at python.org Wed Apr 29 09:00:35 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 29 Apr 2009 09:00:35 +0200 (CEST) Subject: [Python-checkins] r72091 - in python/branches/release30-maint: Doc/library/functions.rst Message-ID: <20090429070035.3F5141E406B@bag.python.org> Author: georg.brandl Date: Wed Apr 29 09:00:34 2009 New Revision: 72091 Log: Merged revisions 72089 via svnmerge from svn+ssh://svn.python.org/python/branches/py3k ........ r72089 | georg.brandl | 2009-04-29 08:37:12 +0200 (Mi, 29 Apr 2009) | 1 line Die, buffer(), die. ........ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Doc/library/functions.rst Modified: python/branches/release30-maint/Doc/library/functions.rst ============================================================================== --- python/branches/release30-maint/Doc/library/functions.rst (original) +++ python/branches/release30-maint/Doc/library/functions.rst Wed Apr 29 09:00:34 2009 @@ -96,7 +96,7 @@ :class:`bytearray` -- it has the same non-mutating methods and the same indexing and slicing behavior. - Accordingly, constructor arguments are interpreted as for :func:`buffer`. + Accordingly, constructor arguments are interpreted as for :func:`bytearray`. Bytes objects can also be created with literals, see :ref:`strings`. From python-checkins at python.org Wed Apr 29 09:01:55 2009 From: python-checkins at python.org (georg.brandl) Date: Wed, 29 Apr 2009 09:01:55 +0200 (CEST) Subject: [Python-checkins] r72092 - peps/trunk/pep-0375.txt Message-ID: <20090429070155.9E0D21E416E@bag.python.org> Author: georg.brandl Date: Wed Apr 29 09:01:55 2009 New Revision: 72092 Log: Add nested with stuff. Modified: peps/trunk/pep-0375.txt Modified: peps/trunk/pep-0375.txt ============================================================================== --- peps/trunk/pep-0375.txt (original) +++ peps/trunk/pep-0375.txt Wed Apr 29 09:01:55 2009 @@ -54,6 +54,7 @@ - Fixing contextlib.nested() [#contextlib]_. - auto-numbered replacement fields in str.format() strings [#strformat]_ - Upgrading xml.etree to the latest external version [#etree]_ +- Nested with-statements in one with statement Footnotes From buildbot at python.org Wed Apr 29 09:57:32 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 29 Apr 2009 07:57:32 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090429075732.7A6B41E4021@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/312 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_posix ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Wed Apr 29 10:00:07 2009 From: python-checkins at python.org (jeroen.ruigrok) Date: Wed, 29 Apr 2009 10:00:07 +0200 (CEST) Subject: [Python-checkins] r72093 - in python/branches/release26-maint: Doc/c-api/allocation.rst Doc/c-api/arg.rst Doc/c-api/buffer.rst Doc/c-api/dict.rst Doc/c-api/gcsupport.rst Doc/c-api/init.rst Doc/c-api/list.rst Doc/c-api/long.rst Doc/c-api/mapping.rst Doc/c-api/marshal.rst Doc/c-api/objbuffer.rst Doc/c-api/object.rst Doc/c-api/sequence.rst Doc/c-api/set.rst Doc/c-api/slice.rst Doc/c-api/string.rst Doc/c-api/structures.rst Doc/c-api/tuple.rst Doc/c-api/type.rst Doc/c-api/typeobj.rst Doc/c-api/unicode.rst Doc/includes/email-alternative.py Doc/includes/email-dir.py Doc/includes/email-mime.py Doc/includes/email-simple.py Message-ID: <20090429080007.6A39F1E4021@bag.python.org> Author: jeroen.ruigrok Date: Wed Apr 29 10:00:05 2009 New Revision: 72093 Log: Merged revisions 71873-71874,71882,71890,71893,71898-71900,71910,71914-71923,71925-71929,71931-71934,71937 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r71873 | jeroen.ruigrok | 2009-04-25 13:15:06 +0200 (za, 25 apr 2009) | 2 lines Reformat prior to expanding. ........ r71874 | jeroen.ruigrok | 2009-04-25 13:59:09 +0200 (za, 25 apr 2009) | 2 lines First attempt to document PyObject_HEAD_INIT and PyVarObject_HEAD_INIT. ........ r71882 | jeroen.ruigrok | 2009-04-25 14:49:10 +0200 (za, 25 apr 2009) | 3 lines Issue #4239: adjust email examples not to use connect() and terminate with quit() and not close(). ........ r71890 | jeroen.ruigrok | 2009-04-25 15:07:40 +0200 (za, 25 apr 2009) | 3 lines Rewrite a sentence to be more in line with the rest of the documentation with regard to person and audience. ........ r71893 | jeroen.ruigrok | 2009-04-25 15:58:58 +0200 (za, 25 apr 2009) | 2 lines Reformat file prior to editing. ........ r71898 | jeroen.ruigrok | 2009-04-25 16:24:30 +0200 (za, 25 apr 2009) | 2 lines Reformat prior to editing. ........ r71899 | jeroen.ruigrok | 2009-04-25 16:27:00 +0200 (za, 25 apr 2009) | 3 lines The type for ppos has been Py_ssize_t since 2.5, reflect this in the documentation. ........ r71900 | jeroen.ruigrok | 2009-04-25 16:28:02 +0200 (za, 25 apr 2009) | 2 lines Reformat paragraph. ........ r71910 | jeroen.ruigrok | 2009-04-25 19:59:03 +0200 (za, 25 apr 2009) | 4 lines Issue #4129: Belatedly document which C API functions had their argument(s) or return type changed from int or int * to Py_ssize_t or Py_ssize_t * as this might cause problems on 64-bit platforms. ........ r71914 | jeroen.ruigrok | 2009-04-25 20:31:20 +0200 (za, 25 apr 2009) | 2 lines Reformat prior to editing. ........ r71915 | jeroen.ruigrok | 2009-04-25 20:46:03 +0200 (za, 25 apr 2009) | 2 lines Issue #4129: Document more int -> Py_ssize_t changes. ........ r71916 | jeroen.ruigrok | 2009-04-25 20:53:48 +0200 (za, 25 apr 2009) | 2 lines Reformat prior to editing. ........ r71917 | jeroen.ruigrok | 2009-04-25 20:57:32 +0200 (za, 25 apr 2009) | 2 lines Reference to an int type, whereas it's a Py_ssize_t as the synopsis states. ........ r71918 | jeroen.ruigrok | 2009-04-25 21:04:15 +0200 (za, 25 apr 2009) | 2 lines Since I edited this file, reformat for future edits. ........ r71919 | jeroen.ruigrok | 2009-04-25 21:10:52 +0200 (za, 25 apr 2009) | 2 lines Reformat prior to editing. ........ r71920 | jeroen.ruigrok | 2009-04-25 21:44:55 +0200 (za, 25 apr 2009) | 5 lines Issue #4129: More documentation pointers about int -> Py_ssize_t. Also fix up the documentation for PyObject_GC_Resize(). It seems that since it first got documented, the documentation was actually for _PyObject_GC_Resize(). ........ r71921 | jeroen.ruigrok | 2009-04-25 21:46:19 +0200 (za, 25 apr 2009) | 2 lines Issue #4129: Documentation notes for int -> Py_ssize_t changes. ........ r71922 | jeroen.ruigrok | 2009-04-25 21:49:05 +0200 (za, 25 apr 2009) | 2 lines Reformat, since I've been busy here anyway. ........ r71923 | jeroen.ruigrok | 2009-04-25 21:54:34 +0200 (za, 25 apr 2009) | 2 lines Issue #4129: Add a versionchanged notice for a few forgotten entries. ........ r71925 | jeroen.ruigrok | 2009-04-25 22:37:39 +0200 (za, 25 apr 2009) | 2 lines Since it's a macro, actually refer to it as such instead of function. ........ r71926 | jeroen.ruigrok | 2009-04-25 22:40:10 +0200 (za, 25 apr 2009) | 2 lines Reformat prior to editing. ........ r71927 | jeroen.ruigrok | 2009-04-25 22:41:40 +0200 (za, 25 apr 2009) | 2 lines Issue #4129: int -> Py_ssize_t documentation. ........ r71928 | jeroen.ruigrok | 2009-04-25 22:43:30 +0200 (za, 25 apr 2009) | 2 lines Reformat prior to editing. ........ r71929 | jeroen.ruigrok | 2009-04-25 22:44:58 +0200 (za, 25 apr 2009) | 2 lines Issue #4129: int -> Py_ssize_t documentation. ........ r71931 | jeroen.ruigrok | 2009-04-25 22:50:27 +0200 (za, 25 apr 2009) | 2 lines Issue #4129: int -> Py_ssize_t documentation. ........ r71932 | jeroen.ruigrok | 2009-04-25 22:55:39 +0200 (za, 25 apr 2009) | 2 lines Issue #4129: more int -> Py_ssize_t documentation. ........ r71933 | jeroen.ruigrok | 2009-04-25 22:58:35 +0200 (za, 25 apr 2009) | 2 lines Issue #4129: more int -> Py_ssize_t documentation. ........ r71934 | jeroen.ruigrok | 2009-04-25 23:02:34 +0200 (za, 25 apr 2009) | 2 lines Issue #4129: field changed from int to Py_ssize_t. ........ r71937 | jeroen.ruigrok | 2009-04-25 23:16:05 +0200 (za, 25 apr 2009) | 2 lines Issue #4129: document int -> Py_ssize_t changes. ........ Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Doc/c-api/allocation.rst python/branches/release26-maint/Doc/c-api/arg.rst python/branches/release26-maint/Doc/c-api/buffer.rst python/branches/release26-maint/Doc/c-api/dict.rst python/branches/release26-maint/Doc/c-api/gcsupport.rst python/branches/release26-maint/Doc/c-api/init.rst python/branches/release26-maint/Doc/c-api/list.rst python/branches/release26-maint/Doc/c-api/long.rst python/branches/release26-maint/Doc/c-api/mapping.rst python/branches/release26-maint/Doc/c-api/marshal.rst python/branches/release26-maint/Doc/c-api/objbuffer.rst python/branches/release26-maint/Doc/c-api/object.rst python/branches/release26-maint/Doc/c-api/sequence.rst python/branches/release26-maint/Doc/c-api/set.rst python/branches/release26-maint/Doc/c-api/slice.rst python/branches/release26-maint/Doc/c-api/string.rst python/branches/release26-maint/Doc/c-api/structures.rst python/branches/release26-maint/Doc/c-api/tuple.rst python/branches/release26-maint/Doc/c-api/type.rst python/branches/release26-maint/Doc/c-api/typeobj.rst python/branches/release26-maint/Doc/c-api/unicode.rst python/branches/release26-maint/Doc/includes/email-alternative.py python/branches/release26-maint/Doc/includes/email-dir.py python/branches/release26-maint/Doc/includes/email-mime.py python/branches/release26-maint/Doc/includes/email-simple.py Modified: python/branches/release26-maint/Doc/c-api/allocation.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/allocation.rst (original) +++ python/branches/release26-maint/Doc/c-api/allocation.rst Wed Apr 29 10:00:05 2009 @@ -11,16 +11,21 @@ .. cfunction:: PyVarObject* _PyObject_NewVar(PyTypeObject *type, Py_ssize_t size) + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: void _PyObject_Del(PyObject *op) .. cfunction:: PyObject* PyObject_Init(PyObject *op, PyTypeObject *type) - Initialize a newly-allocated object *op* with its type and initial reference. - Returns the initialized object. If *type* indicates that the object - participates in the cyclic garbage detector, it is added to the detector's set - of observed objects. Other fields of the object are not affected. + Initialize a newly-allocated object *op* with its type and initial + reference. Returns the initialized object. If *type* indicates that the + object participates in the cyclic garbage detector, it is added to the + detector's set of observed objects. Other fields of the object are not + affected. .. cfunction:: PyVarObject* PyObject_InitVar(PyVarObject *op, PyTypeObject *type, Py_ssize_t size) @@ -28,77 +33,90 @@ This does everything :cfunc:`PyObject_Init` does, and also initializes the length information for a variable-size object. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: TYPE* PyObject_New(TYPE, PyTypeObject *type) - Allocate a new Python object using the C structure type *TYPE* and the Python - type object *type*. Fields not defined by the Python object header are not - initialized; the object's reference count will be one. The size of the memory - allocation is determined from the :attr:`tp_basicsize` field of the type object. + Allocate a new Python object using the C structure type *TYPE* and the + Python type object *type*. Fields not defined by the Python object header + are not initialized; the object's reference count will be one. The size of + the memory allocation is determined from the :attr:`tp_basicsize` field of + the type object. .. cfunction:: TYPE* PyObject_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size) - Allocate a new Python object using the C structure type *TYPE* and the Python - type object *type*. Fields not defined by the Python object header are not - initialized. The allocated memory allows for the *TYPE* structure plus *size* - fields of the size given by the :attr:`tp_itemsize` field of *type*. This is - useful for implementing objects like tuples, which are able to determine their - size at construction time. Embedding the array of fields into the same - allocation decreases the number of allocations, improving the memory management - efficiency. + Allocate a new Python object using the C structure type *TYPE* and the + Python type object *type*. Fields not defined by the Python object header + are not initialized. The allocated memory allows for the *TYPE* structure + plus *size* fields of the size given by the :attr:`tp_itemsize` field of + *type*. This is useful for implementing objects like tuples, which are + able to determine their size at construction time. Embedding the array of + fields into the same allocation decreases the number of allocations, + improving the memory management efficiency. + + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. .. cfunction:: void PyObject_Del(PyObject *op) Releases memory allocated to an object using :cfunc:`PyObject_New` or - :cfunc:`PyObject_NewVar`. This is normally called from the :attr:`tp_dealloc` - handler specified in the object's type. The fields of the object should not be - accessed after this call as the memory is no longer a valid Python object. + :cfunc:`PyObject_NewVar`. This is normally called from the + :attr:`tp_dealloc` handler specified in the object's type. The fields of + the object should not be accessed after this call as the memory is no + longer a valid Python object. .. cfunction:: PyObject* Py_InitModule(char *name, PyMethodDef *methods) - Create a new module object based on a name and table of functions, returning the - new module object. + Create a new module object based on a name and table of functions, + returning the new module object. .. versionchanged:: 2.3 - Older versions of Python did not support *NULL* as the value for the *methods* - argument. + Older versions of Python did not support *NULL* as the value for the + *methods* argument. .. cfunction:: PyObject* Py_InitModule3(char *name, PyMethodDef *methods, char *doc) - Create a new module object based on a name and table of functions, returning the - new module object. If *doc* is non-*NULL*, it will be used to define the - docstring for the module. + Create a new module object based on a name and table of functions, + returning the new module object. If *doc* is non-*NULL*, it will be used + to define the docstring for the module. .. versionchanged:: 2.3 - Older versions of Python did not support *NULL* as the value for the *methods* - argument. + Older versions of Python did not support *NULL* as the value for the + *methods* argument. .. cfunction:: PyObject* Py_InitModule4(char *name, PyMethodDef *methods, char *doc, PyObject *self, int apiver) - Create a new module object based on a name and table of functions, returning the - new module object. If *doc* is non-*NULL*, it will be used to define the - docstring for the module. If *self* is non-*NULL*, it will passed to the - functions of the module as their (otherwise *NULL*) first parameter. (This was - added as an experimental feature, and there are no known uses in the current - version of Python.) For *apiver*, the only value which should be passed is - defined by the constant :const:`PYTHON_API_VERSION`. + Create a new module object based on a name and table of functions, + returning the new module object. If *doc* is non-*NULL*, it will be used + to define the docstring for the module. If *self* is non-*NULL*, it will + passed to the functions of the module as their (otherwise *NULL*) first + parameter. (This was added as an experimental feature, and there are no + known uses in the current version of Python.) For *apiver*, the only value + which should be passed is defined by the constant + :const:`PYTHON_API_VERSION`. .. note:: - Most uses of this function should probably be using the :cfunc:`Py_InitModule3` - instead; only use this if you are sure you need it. + Most uses of this function should probably be using the + :cfunc:`Py_InitModule3` instead; only use this if you are sure you need + it. .. versionchanged:: 2.3 - Older versions of Python did not support *NULL* as the value for the *methods* - argument. + Older versions of Python did not support *NULL* as the value for the + *methods* argument. .. cvar:: PyObject _Py_NoneStruct - Object which is visible in Python as ``None``. This should only be accessed - using the ``Py_None`` macro, which evaluates to a pointer to this object. + Object which is visible in Python as ``None``. This should only be + accessed using the ``Py_None`` macro, which evaluates to a pointer to this + object. Modified: python/branches/release26-maint/Doc/c-api/arg.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/arg.rst (original) +++ python/branches/release26-maint/Doc/c-api/arg.rst Wed Apr 29 10:00:05 2009 @@ -10,46 +10,48 @@ :ref:`extending-index`. The first three of these functions described, :cfunc:`PyArg_ParseTuple`, -:cfunc:`PyArg_ParseTupleAndKeywords`, and :cfunc:`PyArg_Parse`, all use *format -strings* which are used to tell the function about the expected arguments. The -format strings use the same syntax for each of these functions. +:cfunc:`PyArg_ParseTupleAndKeywords`, and :cfunc:`PyArg_Parse`, all use +*format strings* which are used to tell the function about the expected +arguments. The format strings use the same syntax for each of these +functions. A format string consists of zero or more "format units." A format unit -describes one Python object; it is usually a single character or a parenthesized -sequence of format units. With a few exceptions, a format unit that is not a -parenthesized sequence normally corresponds to a single address argument to -these functions. In the following description, the quoted form is the format -unit; the entry in (round) parentheses is the Python object type that matches -the format unit; and the entry in [square] brackets is the type of the C -variable(s) whose address should be passed. +describes one Python object; it is usually a single character or a +parenthesized sequence of format units. With a few exceptions, a format unit +that is not a parenthesized sequence normally corresponds to a single address +argument to these functions. In the following description, the quoted form is +the format unit; the entry in (round) parentheses is the Python object type +that matches the format unit; and the entry in [square] brackets is the type +of the C variable(s) whose address should be passed. ``s`` (string or Unicode object) [const char \*] - Convert a Python string or Unicode object to a C pointer to a character string. - You must not provide storage for the string itself; a pointer to an existing - string is stored into the character pointer variable whose address you pass. - The C string is NUL-terminated. The Python string must not contain embedded NUL - bytes; if it does, a :exc:`TypeError` exception is raised. Unicode objects are - converted to C strings using the default encoding. If this conversion fails, a - :exc:`UnicodeError` is raised. + Convert a Python string or Unicode object to a C pointer to a character + string. You must not provide storage for the string itself; a pointer to + an existing string is stored into the character pointer variable whose + address you pass. The C string is NUL-terminated. The Python string must + not contain embedded NUL bytes; if it does, a :exc:`TypeError` exception is + raised. Unicode objects are converted to C strings using the default + encoding. If this conversion fails, a :exc:`UnicodeError` is raised. ``s#`` (string, Unicode or any read buffer compatible object) [const char \*, int (or :ctype:`Py_ssize_t`, see below)] - This variant on ``s`` stores into two C variables, the first one a pointer to a - character string, the second one its length. In this case the Python string may - contain embedded null bytes. Unicode objects pass back a pointer to the default - encoded string version of the object if such a conversion is possible. All - other read-buffer compatible objects pass back a reference to the raw internal - data representation. - - Starting with Python 2.5 the type of the length argument can be - controlled by defining the macro :cmacro:`PY_SSIZE_T_CLEAN` before - including :file:`Python.h`. If the macro is defined, length is a - :ctype:`Py_ssize_t` rather than an int. + This variant on ``s`` stores into two C variables, the first one a pointer + to a character string, the second one its length. In this case the Python + string may contain embedded null bytes. Unicode objects pass back a + pointer to the default encoded string version of the object if such a + conversion is possible. All other read-buffer compatible objects pass back + a reference to the raw internal data representation. + + Starting with Python 2.5 the type of the length argument can be controlled + by defining the macro :cmacro:`PY_SSIZE_T_CLEAN` before including + :file:`Python.h`. If the macro is defined, length is a :ctype:`Py_ssize_t` + rather than an int. ``s*`` (string, Unicode, or any buffer compatible object) [Py_buffer \*] - Similar to ``s#``, this code fills a Py_buffer structure provided by the caller. - The buffer gets locked, so that the caller can subsequently use the buffer even - inside a ``Py_BEGIN_ALLOW_THREADS`` block; the caller is responsible for calling - ``PyBuffer_Release`` with the structure after it has processed the data. + Similar to ``s#``, this code fills a Py_buffer structure provided by the + caller. The buffer gets locked, so that the caller can subsequently use + the buffer even inside a ``Py_BEGIN_ALLOW_THREADS`` block; the caller is + responsible for calling ``PyBuffer_Release`` with the structure after it + has processed the data. .. versionadded:: 2.6 @@ -66,83 +68,86 @@ .. versionadded:: 2.6 ``u`` (Unicode object) [Py_UNICODE \*] - Convert a Python Unicode object to a C pointer to a NUL-terminated buffer of - 16-bit Unicode (UTF-16) data. As with ``s``, there is no need to provide - storage for the Unicode data buffer; a pointer to the existing Unicode data is - stored into the :ctype:`Py_UNICODE` pointer variable whose address you pass. + Convert a Python Unicode object to a C pointer to a NUL-terminated buffer + of 16-bit Unicode (UTF-16) data. As with ``s``, there is no need to + provide storage for the Unicode data buffer; a pointer to the existing + Unicode data is stored into the :ctype:`Py_UNICODE` pointer variable whose + address you pass. ``u#`` (Unicode object) [Py_UNICODE \*, int] - This variant on ``u`` stores into two C variables, the first one a pointer to a - Unicode data buffer, the second one its length. Non-Unicode objects are handled - by interpreting their read-buffer pointer as pointer to a :ctype:`Py_UNICODE` - array. + This variant on ``u`` stores into two C variables, the first one a pointer + to a Unicode data buffer, the second one its length. Non-Unicode objects + are handled by interpreting their read-buffer pointer as pointer to a + :ctype:`Py_UNICODE` array. ``es`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] - This variant on ``s`` is used for encoding Unicode and objects convertible to - Unicode into a character buffer. It only works for encoded data without embedded - NUL bytes. + This variant on ``s`` is used for encoding Unicode and objects convertible + to Unicode into a character buffer. It only works for encoded data without + embedded NUL bytes. This format requires two arguments. The first is only used as input, and - must be a :ctype:`const char\*` which points to the name of an encoding as a - NUL-terminated string, or *NULL*, in which case the default encoding is used. - An exception is raised if the named encoding is not known to Python. The - second argument must be a :ctype:`char\*\*`; the value of the pointer it - references will be set to a buffer with the contents of the argument text. - The text will be encoded in the encoding specified by the first argument. - - :cfunc:`PyArg_ParseTuple` will allocate a buffer of the needed size, copy the - encoded data into this buffer and adjust *\*buffer* to reference the newly - allocated storage. The caller is responsible for calling :cfunc:`PyMem_Free` to - free the allocated buffer after use. + must be a :ctype:`const char\*` which points to the name of an encoding as + a NUL-terminated string, or *NULL*, in which case the default encoding is + used. An exception is raised if the named encoding is not known to Python. + The second argument must be a :ctype:`char\*\*`; the value of the pointer + it references will be set to a buffer with the contents of the argument + text. The text will be encoded in the encoding specified by the first + argument. + + :cfunc:`PyArg_ParseTuple` will allocate a buffer of the needed size, copy + the encoded data into this buffer and adjust *\*buffer* to reference the + newly allocated storage. The caller is responsible for calling + :cfunc:`PyMem_Free` to free the allocated buffer after use. ``et`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] Same as ``es`` except that 8-bit string objects are passed through without - recoding them. Instead, the implementation assumes that the string object uses - the encoding passed in as parameter. + recoding them. Instead, the implementation assumes that the string object + uses the encoding passed in as parameter. ``es#`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer, int \*buffer_length] - This variant on ``s#`` is used for encoding Unicode and objects convertible to - Unicode into a character buffer. Unlike the ``es`` format, this variant allows - input data which contains NUL characters. - - It requires three arguments. The first is only used as input, and must be a - :ctype:`const char\*` which points to the name of an encoding as a - NUL-terminated string, or *NULL*, in which case the default encoding is used. - An exception is raised if the named encoding is not known to Python. The - second argument must be a :ctype:`char\*\*`; the value of the pointer it - references will be set to a buffer with the contents of the argument text. - The text will be encoded in the encoding specified by the first argument. - The third argument must be a pointer to an integer; the referenced integer - will be set to the number of bytes in the output buffer. + This variant on ``s#`` is used for encoding Unicode and objects convertible + to Unicode into a character buffer. Unlike the ``es`` format, this variant + allows input data which contains NUL characters. + + It requires three arguments. The first is only used as input, and must be + a :ctype:`const char\*` which points to the name of an encoding as a + NUL-terminated string, or *NULL*, in which case the default encoding is + used. An exception is raised if the named encoding is not known to Python. + The second argument must be a :ctype:`char\*\*`; the value of the pointer + it references will be set to a buffer with the contents of the argument + text. The text will be encoded in the encoding specified by the first + argument. The third argument must be a pointer to an integer; the + referenced integer will be set to the number of bytes in the output buffer. There are two modes of operation: - If *\*buffer* points a *NULL* pointer, the function will allocate a buffer of - the needed size, copy the encoded data into this buffer and set *\*buffer* to - reference the newly allocated storage. The caller is responsible for calling - :cfunc:`PyMem_Free` to free the allocated buffer after usage. + If *\*buffer* points a *NULL* pointer, the function will allocate a buffer + of the needed size, copy the encoded data into this buffer and set + *\*buffer* to reference the newly allocated storage. The caller is + responsible for calling :cfunc:`PyMem_Free` to free the allocated buffer + after usage. If *\*buffer* points to a non-*NULL* pointer (an already allocated buffer), - :cfunc:`PyArg_ParseTuple` will use this location as the buffer and interpret the - initial value of *\*buffer_length* as the buffer size. It will then copy the - encoded data into the buffer and NUL-terminate it. If the buffer is not large - enough, a :exc:`ValueError` will be set. + :cfunc:`PyArg_ParseTuple` will use this location as the buffer and + interpret the initial value of *\*buffer_length* as the buffer size. It + will then copy the encoded data into the buffer and NUL-terminate it. If + the buffer is not large enough, a :exc:`ValueError` will be set. In both cases, *\*buffer_length* is set to the length of the encoded data without the trailing NUL byte. ``et#`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] - Same as ``es#`` except that string objects are passed through without recoding - them. Instead, the implementation assumes that the string object uses the - encoding passed in as parameter. + Same as ``es#`` except that string objects are passed through without + recoding them. Instead, the implementation assumes that the string object + uses the encoding passed in as parameter. ``b`` (integer) [unsigned char] Convert a nonnegative Python integer to an unsigned tiny int, stored in a C :ctype:`unsigned char`. ``B`` (integer) [unsigned char] - Convert a Python integer to a tiny int without overflow checking, stored in a C - :ctype:`unsigned char`. + Convert a Python integer to a tiny int without overflow checking, stored in + a C :ctype:`unsigned char`. .. versionadded:: 2.3 @@ -150,8 +155,8 @@ Convert a Python integer to a C :ctype:`short int`. ``H`` (integer) [unsigned short int] - Convert a Python integer to a C :ctype:`unsigned short int`, without overflow - checking. + Convert a Python integer to a C :ctype:`unsigned short int`, without + overflow checking. .. versionadded:: 2.3 @@ -168,20 +173,21 @@ Convert a Python integer to a C :ctype:`long int`. ``k`` (integer) [unsigned long] - Convert a Python integer or long integer to a C :ctype:`unsigned long` without - overflow checking. + Convert a Python integer or long integer to a C :ctype:`unsigned long` + without overflow checking. .. versionadded:: 2.3 ``L`` (integer) [PY_LONG_LONG] Convert a Python integer to a C :ctype:`long long`. This format is only - available on platforms that support :ctype:`long long` (or :ctype:`_int64` on - Windows). + available on platforms that support :ctype:`long long` (or :ctype:`_int64` + on Windows). ``K`` (integer) [unsigned PY_LONG_LONG] Convert a Python integer or long integer to a C :ctype:`unsigned long long` without overflow checking. This format is only available on platforms that - support :ctype:`unsigned long long` (or :ctype:`unsigned _int64` on Windows). + support :ctype:`unsigned long long` (or :ctype:`unsigned _int64` on + Windows). .. versionadded:: 2.3 @@ -204,60 +210,61 @@ Convert a Python complex number to a C :ctype:`Py_complex` structure. ``O`` (object) [PyObject \*] - Store a Python object (without any conversion) in a C object pointer. The C - program thus receives the actual object that was passed. The object's reference - count is not increased. The pointer stored is not *NULL*. + Store a Python object (without any conversion) in a C object pointer. The + C program thus receives the actual object that was passed. The object's + reference count is not increased. The pointer stored is not *NULL*. ``O!`` (object) [*typeobject*, PyObject \*] Store a Python object in a C object pointer. This is similar to ``O``, but - takes two C arguments: the first is the address of a Python type object, the - second is the address of the C variable (of type :ctype:`PyObject\*`) into which - the object pointer is stored. If the Python object does not have the required - type, :exc:`TypeError` is raised. + takes two C arguments: the first is the address of a Python type object, + the second is the address of the C variable (of type :ctype:`PyObject\*`) + into which the object pointer is stored. If the Python object does not + have the required type, :exc:`TypeError` is raised. ``O&`` (object) [*converter*, *anything*] - Convert a Python object to a C variable through a *converter* function. This - takes two arguments: the first is a function, the second is the address of a C - variable (of arbitrary type), converted to :ctype:`void \*`. The *converter* - function in turn is called as follows:: + Convert a Python object to a C variable through a *converter* function. + This takes two arguments: the first is a function, the second is the + address of a C variable (of arbitrary type), converted to :ctype:`void \*`. + The *converter* function in turn is called as follows:: status = converter(object, address); where *object* is the Python object to be converted and *address* is the - :ctype:`void\*` argument that was passed to the :cfunc:`PyArg_Parse\*` function. - The returned *status* should be ``1`` for a successful conversion and ``0`` if - the conversion has failed. When the conversion fails, the *converter* function - should raise an exception and leave the content of *address* unmodified. + :ctype:`void\*` argument that was passed to the :cfunc:`PyArg_Parse\*` + function. The returned *status* should be ``1`` for a successful + conversion and ``0`` if the conversion has failed. When the conversion + fails, the *converter* function should raise an exception and leave the + content of *address* unmodified. ``S`` (string) [PyStringObject \*] Like ``O`` but requires that the Python object is a string object. Raises - :exc:`TypeError` if the object is not a string object. The C variable may also - be declared as :ctype:`PyObject\*`. + :exc:`TypeError` if the object is not a string object. The C variable may + also be declared as :ctype:`PyObject\*`. ``U`` (Unicode string) [PyUnicodeObject \*] Like ``O`` but requires that the Python object is a Unicode object. Raises - :exc:`TypeError` if the object is not a Unicode object. The C variable may also - be declared as :ctype:`PyObject\*`. + :exc:`TypeError` if the object is not a Unicode object. The C variable may + also be declared as :ctype:`PyObject\*`. ``t#`` (read-only character buffer) [char \*, int] Like ``s#``, but accepts any object which implements the read-only buffer - interface. The :ctype:`char\*` variable is set to point to the first byte of - the buffer, and the :ctype:`int` is set to the length of the buffer. Only - single-segment buffer objects are accepted; :exc:`TypeError` is raised for all - others. + interface. The :ctype:`char\*` variable is set to point to the first byte + of the buffer, and the :ctype:`int` is set to the length of the buffer. + Only single-segment buffer objects are accepted; :exc:`TypeError` is raised + for all others. ``w`` (read-write character buffer) [char \*] - Similar to ``s``, but accepts any object which implements the read-write buffer - interface. The caller must determine the length of the buffer by other means, - or use ``w#`` instead. Only single-segment buffer objects are accepted; - :exc:`TypeError` is raised for all others. + Similar to ``s``, but accepts any object which implements the read-write + buffer interface. The caller must determine the length of the buffer by + other means, or use ``w#`` instead. Only single-segment buffer objects are + accepted; :exc:`TypeError` is raised for all others. ``w#`` (read-write character buffer) [char \*, Py_ssize_t] Like ``s#``, but accepts any object which implements the read-write buffer - interface. The :ctype:`char \*` variable is set to point to the first byte of - the buffer, and the :ctype:`int` is set to the length of the buffer. Only - single-segment buffer objects are accepted; :exc:`TypeError` is raised for all - others. + interface. The :ctype:`char \*` variable is set to point to the first byte + of the buffer, and the :ctype:`Py_ssize_t` is set to the length of the + buffer. Only single-segment buffer objects are accepted; :exc:`TypeError` + is raised for all others. ``w*`` (read-write byte-oriented buffer) [Py_buffer \*] This is to ``w`` what ``s*`` is to ``s``. @@ -265,72 +272,72 @@ .. versionadded:: 2.6 ``(items)`` (tuple) [*matching-items*] - The object must be a Python sequence whose length is the number of format units - in *items*. The C arguments must correspond to the individual format units in - *items*. Format units for sequences may be nested. + The object must be a Python sequence whose length is the number of format + units in *items*. The C arguments must correspond to the individual format + units in *items*. Format units for sequences may be nested. .. note:: - Prior to Python version 1.5.2, this format specifier only accepted a tuple - containing the individual parameters, not an arbitrary sequence. Code which - previously caused :exc:`TypeError` to be raised here may now proceed without an - exception. This is not expected to be a problem for existing code. + Prior to Python version 1.5.2, this format specifier only accepted a + tuple containing the individual parameters, not an arbitrary sequence. + Code which previously caused :exc:`TypeError` to be raised here may now + proceed without an exception. This is not expected to be a problem for + existing code. It is possible to pass Python long integers where integers are requested; however no proper range checking is done --- the most significant bits are silently truncated when the receiving field is too small to receive the value -(actually, the semantics are inherited from downcasts in C --- your mileage may -vary). +(actually, the semantics are inherited from downcasts in C --- your mileage +may vary). A few other characters have a meaning in a format string. These may not occur inside nested parentheses. They are: ``|`` - Indicates that the remaining arguments in the Python argument list are optional. - The C variables corresponding to optional arguments should be initialized to - their default value --- when an optional argument is not specified, - :cfunc:`PyArg_ParseTuple` does not touch the contents of the corresponding C - variable(s). + Indicates that the remaining arguments in the Python argument list are + optional. The C variables corresponding to optional arguments should be + initialized to their default value --- when an optional argument is not + specified, :cfunc:`PyArg_ParseTuple` does not touch the contents of the + corresponding C variable(s). ``:`` - The list of format units ends here; the string after the colon is used as the - function name in error messages (the "associated value" of the exception that - :cfunc:`PyArg_ParseTuple` raises). + The list of format units ends here; the string after the colon is used as + the function name in error messages (the "associated value" of the + exception that :cfunc:`PyArg_ParseTuple` raises). ``;`` - The list of format units ends here; the string after the semicolon is used as - the error message *instead* of the default error message. ``:`` and ``;`` - mutually exclude each other. + The list of format units ends here; the string after the semicolon is used + as the error message *instead* of the default error message. ``:`` and + ``;`` mutually exclude each other. Note that any Python object references which are provided to the caller are *borrowed* references; do not decrement their reference count! Additional arguments passed to these functions must be addresses of variables whose type is determined by the format string; these are used to store values -from the input tuple. There are a few cases, as described in the list of format -units above, where these parameters are used as input values; they should match -what is specified for the corresponding format unit in that case. - -For the conversion to succeed, the *arg* object must match the format -and the format must be exhausted. On success, the -:cfunc:`PyArg_Parse\*` functions return true, otherwise they return -false and raise an appropriate exception. When the -:cfunc:`PyArg_Parse\*` functions fail due to conversion failure in one -of the format units, the variables at the addresses corresponding to that +from the input tuple. There are a few cases, as described in the list of +format units above, where these parameters are used as input values; they +should match what is specified for the corresponding format unit in that case. + +For the conversion to succeed, the *arg* object must match the format and the +format must be exhausted. On success, the :cfunc:`PyArg_Parse\*` functions +return true, otherwise they return false and raise an appropriate exception. +When the :cfunc:`PyArg_Parse\*` functions fail due to conversion failure in +one of the format units, the variables at the addresses corresponding to that and the following format units are left untouched. .. cfunction:: int PyArg_ParseTuple(PyObject *args, const char *format, ...) - Parse the parameters of a function that takes only positional parameters into - local variables. Returns true on success; on failure, it returns false and - raises the appropriate exception. + Parse the parameters of a function that takes only positional parameters + into local variables. Returns true on success; on failure, it returns + false and raises the appropriate exception. .. cfunction:: int PyArg_VaParse(PyObject *args, const char *format, va_list vargs) - Identical to :cfunc:`PyArg_ParseTuple`, except that it accepts a va_list rather - than a variable number of arguments. + Identical to :cfunc:`PyArg_ParseTuple`, except that it accepts a va_list + rather than a variable number of arguments. .. cfunction:: int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], ...) @@ -348,32 +355,33 @@ .. cfunction:: int PyArg_Parse(PyObject *args, const char *format, ...) - Function used to deconstruct the argument lists of "old-style" functions --- - these are functions which use the :const:`METH_OLDARGS` parameter parsing - method. This is not recommended for use in parameter parsing in new code, and - most code in the standard interpreter has been modified to no longer use this - for that purpose. It does remain a convenient way to decompose other tuples, - however, and may continue to be used for that purpose. + Function used to deconstruct the argument lists of "old-style" functions + --- these are functions which use the :const:`METH_OLDARGS` parameter + parsing method. This is not recommended for use in parameter parsing in + new code, and most code in the standard interpreter has been modified to no + longer use this for that purpose. It does remain a convenient way to + decompose other tuples, however, and may continue to be used for that + purpose. .. cfunction:: int PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...) A simpler form of parameter retrieval which does not use a format string to - specify the types of the arguments. Functions which use this method to retrieve - their parameters should be declared as :const:`METH_VARARGS` in function or - method tables. The tuple containing the actual parameters should be passed as - *args*; it must actually be a tuple. The length of the tuple must be at least - *min* and no more than *max*; *min* and *max* may be equal. Additional - arguments must be passed to the function, each of which should be a pointer to a - :ctype:`PyObject\*` variable; these will be filled in with the values from - *args*; they will contain borrowed references. The variables which correspond - to optional parameters not given by *args* will not be filled in; these should - be initialized by the caller. This function returns true on success and false if - *args* is not a tuple or contains the wrong number of elements; an exception - will be set if there was a failure. + specify the types of the arguments. Functions which use this method to + retrieve their parameters should be declared as :const:`METH_VARARGS` in + function or method tables. The tuple containing the actual parameters + should be passed as *args*; it must actually be a tuple. The length of the + tuple must be at least *min* and no more than *max*; *min* and *max* may be + equal. Additional arguments must be passed to the function, each of which + should be a pointer to a :ctype:`PyObject\*` variable; these will be filled + in with the values from *args*; they will contain borrowed references. The + variables which correspond to optional parameters not given by *args* will + not be filled in; these should be initialized by the caller. This function + returns true on success and false if *args* is not a tuple or contains the + wrong number of elements; an exception will be set if there was a failure. - This is an example of the use of this function, taken from the sources for the - :mod:`_weakref` helper module for weak references:: + This is an example of the use of this function, taken from the sources for + the :mod:`_weakref` helper module for weak references:: static PyObject * weakref_ref(PyObject *self, PyObject *args) @@ -388,50 +396,56 @@ return result; } - The call to :cfunc:`PyArg_UnpackTuple` in this example is entirely equivalent to - this call to :cfunc:`PyArg_ParseTuple`:: + The call to :cfunc:`PyArg_UnpackTuple` in this example is entirely + equivalent to this call to :cfunc:`PyArg_ParseTuple`:: PyArg_ParseTuple(args, "O|O:ref", &object, &callback) .. versionadded:: 2.2 + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *min* and *max*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* Py_BuildValue(const char *format, ...) - Create a new value based on a format string similar to those accepted by the - :cfunc:`PyArg_Parse\*` family of functions and a sequence of values. Returns - the value or *NULL* in the case of an error; an exception will be raised if - *NULL* is returned. - - :cfunc:`Py_BuildValue` does not always build a tuple. It builds a tuple only if - its format string contains two or more format units. If the format string is - empty, it returns ``None``; if it contains exactly one format unit, it returns - whatever object is described by that format unit. To force it to return a tuple - of size 0 or one, parenthesize the format string. - - When memory buffers are passed as parameters to supply data to build objects, as - for the ``s`` and ``s#`` formats, the required data is copied. Buffers provided - by the caller are never referenced by the objects created by - :cfunc:`Py_BuildValue`. In other words, if your code invokes :cfunc:`malloc` - and passes the allocated memory to :cfunc:`Py_BuildValue`, your code is - responsible for calling :cfunc:`free` for that memory once + Create a new value based on a format string similar to those accepted by + the :cfunc:`PyArg_Parse\*` family of functions and a sequence of values. + Returns the value or *NULL* in the case of an error; an exception will be + raised if *NULL* is returned. + + :cfunc:`Py_BuildValue` does not always build a tuple. It builds a tuple + only if its format string contains two or more format units. If the format + string is empty, it returns ``None``; if it contains exactly one format + unit, it returns whatever object is described by that format unit. To + force it to return a tuple of size 0 or one, parenthesize the format + string. + + When memory buffers are passed as parameters to supply data to build + objects, as for the ``s`` and ``s#`` formats, the required data is copied. + Buffers provided by the caller are never referenced by the objects created + by :cfunc:`Py_BuildValue`. In other words, if your code invokes + :cfunc:`malloc` and passes the allocated memory to :cfunc:`Py_BuildValue`, + your code is responsible for calling :cfunc:`free` for that memory once :cfunc:`Py_BuildValue` returns. - In the following description, the quoted form is the format unit; the entry in - (round) parentheses is the Python object type that the format unit will return; - and the entry in [square] brackets is the type of the C value(s) to be passed. - - The characters space, tab, colon and comma are ignored in format strings (but - not within format units such as ``s#``). This can be used to make long format - strings a tad more readable. + In the following description, the quoted form is the format unit; the entry + in (round) parentheses is the Python object type that the format unit will + return; and the entry in [square] brackets is the type of the C value(s) to + be passed. + + The characters space, tab, colon and comma are ignored in format strings + (but not within format units such as ``s#``). This can be used to make + long format strings a tad more readable. ``s`` (string) [char \*] - Convert a null-terminated C string to a Python object. If the C string pointer - is *NULL*, ``None`` is used. + Convert a null-terminated C string to a Python object. If the C string + pointer is *NULL*, ``None`` is used. ``s#`` (string) [char \*, int] - Convert a C string and its length to a Python object. If the C string pointer - is *NULL*, the length is ignored and ``None`` is returned. + Convert a C string and its length to a Python object. If the C string + pointer is *NULL*, the length is ignored and ``None`` is returned. ``z`` (string or ``None``) [char \*] Same as ``s``. @@ -440,13 +454,14 @@ Same as ``s#``. ``u`` (Unicode string) [Py_UNICODE \*] - Convert a null-terminated buffer of Unicode (UCS-2 or UCS-4) data to a Python - Unicode object. If the Unicode buffer pointer is *NULL*, ``None`` is returned. + Convert a null-terminated buffer of Unicode (UCS-2 or UCS-4) data to a + Python Unicode object. If the Unicode buffer pointer is *NULL*, + ``None`` is returned. ``u#`` (Unicode string) [Py_UNICODE \*, int] - Convert a Unicode (UCS-2 or UCS-4) data buffer and its length to a Python - Unicode object. If the Unicode buffer pointer is *NULL*, the length is ignored - and ``None`` is returned. + Convert a Unicode (UCS-2 or UCS-4) data buffer and its length to a + Python Unicode object. If the Unicode buffer pointer is *NULL*, the + length is ignored and ``None`` is returned. ``i`` (integer) [int] Convert a plain C :ctype:`int` to a Python integer object. @@ -467,20 +482,20 @@ Convert a C :ctype:`unsigned short int` to a Python integer object. ``I`` (integer/long) [unsigned int] - Convert a C :ctype:`unsigned int` to a Python integer object or a Python long - integer object, if it is larger than ``sys.maxint``. + Convert a C :ctype:`unsigned int` to a Python integer object or a Python + long integer object, if it is larger than ``sys.maxint``. ``k`` (integer/long) [unsigned long] - Convert a C :ctype:`unsigned long` to a Python integer object or a Python long - integer object, if it is larger than ``sys.maxint``. + Convert a C :ctype:`unsigned long` to a Python integer object or a + Python long integer object, if it is larger than ``sys.maxint``. ``L`` (long) [PY_LONG_LONG] - Convert a C :ctype:`long long` to a Python long integer object. Only available - on platforms that support :ctype:`long long`. + Convert a C :ctype:`long long` to a Python long integer object. Only + available on platforms that support :ctype:`long long`. ``K`` (long) [unsigned PY_LONG_LONG] - Convert a C :ctype:`unsigned long long` to a Python long integer object. Only - available on platforms that support :ctype:`unsigned long long`. + Convert a C :ctype:`unsigned long long` to a Python long integer object. + Only available on platforms that support :ctype:`unsigned long long`. ``n`` (int) [Py_ssize_t] Convert a C :ctype:`Py_ssize_t` to a Python integer or long integer. @@ -488,8 +503,8 @@ .. versionadded:: 2.5 ``c`` (string of length 1) [char] - Convert a C :ctype:`int` representing a character to a Python string of length - 1. + Convert a C :ctype:`int` representing a character to a Python string of + length 1. ``d`` (float) [double] Convert a C :ctype:`double` to a Python floating point number. @@ -502,39 +517,41 @@ ``O`` (object) [PyObject \*] Pass a Python object untouched (except for its reference count, which is - incremented by one). If the object passed in is a *NULL* pointer, it is assumed - that this was caused because the call producing the argument found an error and - set an exception. Therefore, :cfunc:`Py_BuildValue` will return *NULL* but won't - raise an exception. If no exception has been raised yet, :exc:`SystemError` is - set. + incremented by one). If the object passed in is a *NULL* pointer, it is + assumed that this was caused because the call producing the argument + found an error and set an exception. Therefore, :cfunc:`Py_BuildValue` + will return *NULL* but won't raise an exception. If no exception has + been raised yet, :exc:`SystemError` is set. ``S`` (object) [PyObject \*] Same as ``O``. ``N`` (object) [PyObject \*] - Same as ``O``, except it doesn't increment the reference count on the object. - Useful when the object is created by a call to an object constructor in the - argument list. + Same as ``O``, except it doesn't increment the reference count on the + object. Useful when the object is created by a call to an object + constructor in the argument list. ``O&`` (object) [*converter*, *anything*] - Convert *anything* to a Python object through a *converter* function. The - function is called with *anything* (which should be compatible with :ctype:`void - \*`) as its argument and should return a "new" Python object, or *NULL* if an - error occurred. + Convert *anything* to a Python object through a *converter* function. + The function is called with *anything* (which should be compatible with + :ctype:`void \*`) as its argument and should return a "new" Python + object, or *NULL* if an error occurred. ``(items)`` (tuple) [*matching-items*] - Convert a sequence of C values to a Python tuple with the same number of items. + Convert a sequence of C values to a Python tuple with the same number of + items. ``[items]`` (list) [*matching-items*] - Convert a sequence of C values to a Python list with the same number of items. + Convert a sequence of C values to a Python list with the same number of + items. ``{items}`` (dictionary) [*matching-items*] - Convert a sequence of C values to a Python dictionary. Each pair of consecutive - C values adds one item to the dictionary, serving as key and value, - respectively. + Convert a sequence of C values to a Python dictionary. Each pair of + consecutive C values adds one item to the dictionary, serving as key and + value, respectively. - If there is an error in the format string, the :exc:`SystemError` exception is - set and *NULL* returned. + If there is an error in the format string, the :exc:`SystemError` exception + is set and *NULL* returned. .. cfunction:: PyObject* Py_VaBuildValue(const char *format, va_list vargs) Modified: python/branches/release26-maint/Doc/c-api/buffer.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/buffer.rst (original) +++ python/branches/release26-maint/Doc/c-api/buffer.rst Wed Apr 29 10:00:05 2009 @@ -13,9 +13,10 @@ single: buffer interface Python objects implemented in C can export a group of functions called the -"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. +"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. Two examples of objects that support the buffer interface are strings and arrays. The string object exposes the character contents in the buffer @@ -28,6 +29,280 @@ :cfunc:`PyArg_ParseTuple` that operate against an object's buffer interface, returning data from the target object. +Starting from version 1.6, Python has been providing Python-level buffer +objects and a C-level buffer API so that any builtin or used-defined type can +expose its characteristics. Both, however, have been deprecated because of +various shortcomings, and have been officially removed in Python 3.0 in favour +of a new C-level buffer API and a new Python-level object named +:class:`memoryview`. + +The new buffer API has been backported to Python 2.6, and the +:class:`memoryview` object has been backported to Python 2.7. It is strongly +advised to use them rather than the old APIs, unless you are blocked from +doing so for compatibility reasons. + + +The new-style Py_buffer struct +============================== + + +.. ctype:: Py_buffer + + .. cmember:: void *buf + + A pointer to the start of the memory for the object. + + .. cmember:: Py_ssize_t len + :noindex: + + The total length of the memory in bytes. + + .. cmember:: int readonly + + An indicator of whether the buffer is read only. + + .. cmember:: const char *format + :noindex: + + A *NULL* terminated string in :mod:`struct` module style syntax giving + the contents of the elements available through the buffer. If this is + *NULL*, ``"B"`` (unsigned bytes) is assumed. + + .. cmember:: int ndim + + The number of dimensions the memory represents as a multi-dimensional + array. If it is 0, :cdata:`strides` and :cdata:`suboffsets` must be + *NULL*. + + .. cmember:: Py_ssize_t *shape + + An array of :ctype:`Py_ssize_t`\s the length of :cdata:`ndim` giving the + shape of the memory as a multi-dimensional array. Note that + ``((*shape)[0] * ... * (*shape)[ndims-1])*itemsize`` should be equal to + :cdata:`len`. + + .. cmember:: Py_ssize_t *strides + + An array of :ctype:`Py_ssize_t`\s the length of :cdata:`ndim` giving the + number of bytes to skip to get to a new element in each dimension. + + .. cmember:: Py_ssize_t *suboffsets + + An array of :ctype:`Py_ssize_t`\s the length of :cdata:`ndim`. If these + suboffset numbers are greater than or equal to 0, then the value stored + along the indicated dimension is a pointer and the suboffset value + dictates how many bytes to add to the pointer after de-referencing. A + suboffset value that it negative indicates that no de-referencing should + occur (striding in a contiguous memory block). + + Here is a function that returns a pointer to the element in an N-D array + pointed to by an N-dimesional index when there are both non-NULL strides + and suboffsets:: + + void *get_item_pointer(int ndim, void *buf, Py_ssize_t *strides, + Py_ssize_t *suboffsets, Py_ssize_t *indices) { + char *pointer = (char*)buf; + int i; + for (i = 0; i < ndim; i++) { + pointer += strides[i] * indices[i]; + if (suboffsets[i] >=0 ) { + pointer = *((char**)pointer) + suboffsets[i]; + } + } + return (void*)pointer; + } + + + .. cmember:: Py_ssize_t itemsize + + This is a storage for the itemsize (in bytes) of each element of the + shared memory. It is technically un-necessary as it can be obtained + using :cfunc:`PyBuffer_SizeFromFormat`, however an exporter may know + this information without parsing the format string and it is necessary + to know the itemsize for proper interpretation of striding. Therefore, + storing it is more convenient and faster. + + .. cmember:: void *internal + + This is for use internally by the exporting object. For example, this + might be re-cast as an integer by the exporter and used to store flags + about whether or not the shape, strides, and suboffsets arrays must be + freed when the buffer is released. The consumer should never alter this + value. + + +Buffer related functions +======================== + + +.. cfunction:: int PyObject_CheckBuffer(PyObject *obj) + + Return 1 if *obj* supports the buffer interface otherwise 0. + + +.. cfunction:: int PyObject_GetBuffer(PyObject *obj, PyObject *view, int flags) + + Export *obj* into a :ctype:`Py_buffer`, *view*. These arguments must + never be *NULL*. The *flags* argument is a bit field indicating what + kind of buffer the caller is prepared to deal with and therefore what + kind of buffer the exporter is allowed to return. The buffer interface + allows for complicated memory sharing possibilities, but some caller may + not be able to handle all the complexibity but may want to see if the + exporter will let them take a simpler view to its memory. + + Some exporters may not be able to share memory in every possible way and + may need to raise errors to signal to some consumers that something is + just not possible. These errors should be a :exc:`BufferError` unless + there is another error that is actually causing the problem. The + exporter can use flags information to simplify how much of the + :cdata:`Py_buffer` structure is filled in with non-default values and/or + raise an error if the object can't support a simpler view of its memory. + + 0 is returned on success and -1 on error. + + The following table gives possible values to the *flags* arguments. + + +------------------------------+---------------------------------------------------+ + | Flag | Description | + +==============================+===================================================+ + | :cmacro:`PyBUF_SIMPLE` | This is the default flag state. The returned | + | | buffer may or may not have writable memory. The | + | | format of the data will be assumed to be unsigned | + | | bytes. This is a "stand-alone" flag constant. It | + | | never needs to be '|'d to the others. The exporter| + | | will raise an error if it cannot provide such a | + | | contiguous buffer of bytes. | + | | | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_WRITABLE` | The returned buffer must be writable. If it is | + | | not writable, then raise an error. | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_STRIDES` | This implies :cmacro:`PyBUF_ND`. The returned | + | | buffer must provide strides information (i.e. the | + | | strides cannot be NULL). This would be used when | + | | the consumer can handle strided, discontiguous | + | | arrays. Handling strides automatically assumes | + | | you can handle shape. The exporter can raise an | + | | error if a strided representation of the data is | + | | not possible (i.e. without the suboffsets). | + | | | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_ND` | The returned buffer must provide shape | + | | information. The memory will be assumed C-style | + | | contiguous (last dimension varies the | + | | fastest). The exporter may raise an error if it | + | | cannot provide this kind of contiguous buffer. If | + | | this is not given then shape will be *NULL*. | + | | | + | | | + | | | + +------------------------------+---------------------------------------------------+ + |:cmacro:`PyBUF_C_CONTIGUOUS` | These flags indicate that the contiguity returned | + |:cmacro:`PyBUF_F_CONTIGUOUS` | buffer must be respectively, C-contiguous (last | + |:cmacro:`PyBUF_ANY_CONTIGUOUS`| dimension varies the fastest), Fortran contiguous | + | | (first dimension varies the fastest) or either | + | | one. All of these flags imply | + | | :cmacro:`PyBUF_STRIDES` and guarantee that the | + | | strides buffer info structure will be filled in | + | | correctly. | + | | | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_INDIRECT` | This flag indicates the returned buffer must have | + | | suboffsets information (which can be NULL if no | + | | suboffsets are needed). This can be used when | + | | the consumer can handle indirect array | + | | referencing implied by these suboffsets. This | + | | implies :cmacro:`PyBUF_STRIDES`. | + | | | + | | | + | | | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_FORMAT` | The returned buffer must have true format | + | | information if this flag is provided. This would | + | | be used when the consumer is going to be checking | + | | for what 'kind' of data is actually stored. An | + | | exporter should always be able to provide this | + | | information if requested. If format is not | + | | explicitly requested then the format must be | + | | returned as *NULL* (which means ``'B'``, or | + | | unsigned bytes) | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_STRIDED` | This is equivalent to ``(PyBUF_STRIDES | | + | | PyBUF_WRITABLE)``. | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_STRIDED_RO` | This is equivalent to ``(PyBUF_STRIDES)``. | + | | | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_RECORDS` | This is equivalent to ``(PyBUF_STRIDES | | + | | PyBUF_FORMAT | PyBUF_WRITABLE)``. | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_RECORDS_RO` | This is equivalent to ``(PyBUF_STRIDES | | + | | PyBUF_FORMAT)``. | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_FULL` | This is equivalent to ``(PyBUF_INDIRECT | | + | | PyBUF_FORMAT | PyBUF_WRITABLE)``. | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_FULL_RO` | This is equivalent to ``(PyBUF_INDIRECT | | + | | PyBUF_FORMAT)``. | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_CONTIG` | This is equivalent to ``(PyBUF_ND | | + | | PyBUF_WRITABLE)``. | + +------------------------------+---------------------------------------------------+ + | :cmacro:`PyBUF_CONTIG_RO` | This is equivalent to ``(PyBUF_ND)``. | + | | | + +------------------------------+---------------------------------------------------+ + + +.. cfunction:: void PyBuffer_Release(PyObject *obj, Py_buffer *view) + + Release the buffer *view* over *obj*. This shouldd be called when the buffer + is no longer being used as it may free memory from it. + + +.. cfunction:: Py_ssize_t PyBuffer_SizeFromFormat(const char *) + + Return the implied :cdata:`~Py_buffer.itemsize` from the struct-stype + :cdata:`~Py_buffer.format`. + + +.. cfunction:: int PyObject_CopyToObject(PyObject *obj, void *buf, Py_ssize_t len, char fortran) + + Copy *len* bytes of data pointed to by the contiguous chunk of memory + pointed to by *buf* into the buffer exported by obj. The buffer must of + course be writable. Return 0 on success and return -1 and raise an error + on failure. If the object does not have a writable buffer, then an error + is raised. If *fortran* is ``'F'``, then if the object is + multi-dimensional, then the data will be copied into the array in + Fortran-style (first dimension varies the fastest). If *fortran* is + ``'C'``, then the data will be copied into the array in C-style (last + dimension varies the fastest). If *fortran* is ``'A'``, then it does not + matter and the copy will be made in whatever way is more efficient. + + +.. cfunction:: int PyBuffer_IsContiguous(Py_buffer *view, char fortran) + + Return 1 if the memory defined by the *view* is C-style (*fortran* is + ``'C'``) or Fortran-style (*fortran* is ``'F'``) contiguous or either one + (*fortran* is ``'A'``). Return 0 otherwise. + + +.. cfunction:: void PyBuffer_FillContiguousStrides(int ndim, Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t itemsize, char fortran) + + Fill the *strides* array with byte-strides of a contiguous (C-style if + *fortran* is ``'C'`` or Fortran-style if *fortran* is ``'F'`` array of the + given shape with the given number of bytes per element. + + +.. cfunction:: int PyBuffer_FillInfo(Py_buffer *view, void *buf, Py_ssize_t len, int readonly, int infoflags) + + Fill in a buffer-info structure, *view*, correctly for an exporter that can + only share a contiguous chunk of memory of "unsigned bytes" of the given + length. Return 0 on success and -1 (with raising an error) on error. + + +Old-style buffer objects +======================== + .. index:: single: PyBufferProcs More information on the buffer interface is provided in the section @@ -36,17 +311,18 @@ A "buffer object" is defined in the :file:`bufferobject.h` header (included by :file:`Python.h`). These objects look very similar to string objects at the Python programming level: they support slicing, indexing, concatenation, and -some other standard string operations. However, their data can come from one of -two sources: from a block of memory, or from another object which exports the -buffer interface. +some other standard string operations. However, their data can come from one +of two sources: from a block of memory, or from another object which exports +the buffer interface. Buffer objects are useful as a way to expose the data from another object's -buffer interface to the Python programmer. They can also be used as a zero-copy -slicing mechanism. Using their ability to reference a block of memory, it is -possible to expose any data to the Python programmer quite easily. The memory -could be a large, constant array in a C extension, it could be a raw block of -memory for manipulation before passing to an operating system library, or it -could be used to pass around structured data in its native, in-memory format. +buffer interface to the Python programmer. They can also be used as a +zero-copy slicing mechanism. Using their ability to reference a block of +memory, it is possible to expose any data to the Python programmer quite +easily. The memory could be a large, constant array in a C extension, it could +be a raw block of memory for manipulation before passing to an operating +system library, or it could be used to pass around structured data in its +native, in-memory format. .. ctype:: PyBufferObject @@ -67,9 +343,10 @@ This constant may be passed as the *size* parameter to :cfunc:`PyBuffer_FromObject` or :cfunc:`PyBuffer_FromReadWriteObject`. It - indicates that the new :ctype:`PyBufferObject` should refer to *base* object - from the specified *offset* to the end of its exported buffer. Using this - enables the caller to avoid querying the *base* object for its length. + indicates that the new :ctype:`PyBufferObject` should refer to *base* + object from the specified *offset* to the end of its exported buffer. + Using this enables the caller to avoid querying the *base* object for its + length. .. cfunction:: int PyBuffer_Check(PyObject *p) @@ -79,41 +356,64 @@ .. cfunction:: PyObject* PyBuffer_FromObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size) - Return a new read-only buffer object. This raises :exc:`TypeError` if *base* - doesn't support the read-only buffer protocol or doesn't provide exactly one - buffer segment, or it raises :exc:`ValueError` if *offset* is less than zero. - The buffer will hold a reference to the *base* object, and the buffer's contents - will refer to the *base* object's buffer interface, starting as position - *offset* and extending for *size* bytes. If *size* is :const:`Py_END_OF_BUFFER`, - then the new buffer's contents extend to the length of the *base* object's - exported buffer data. + Return a new read-only buffer object. This raises :exc:`TypeError` if + *base* doesn't support the read-only buffer protocol or doesn't provide + exactly one buffer segment, or it raises :exc:`ValueError` if *offset* is + less than zero. The buffer will hold a reference to the *base* object, and + the buffer's contents will refer to the *base* object's buffer interface, + starting as position *offset* and extending for *size* bytes. If *size* is + :const:`Py_END_OF_BUFFER`, then the new buffer's contents extend to the + length of the *base* object's exported buffer data. + + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *offset* and *size*. This + might require changes in your code for properly supporting 64-bit + systems. .. cfunction:: PyObject* PyBuffer_FromReadWriteObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size) - Return a new writable buffer object. Parameters and exceptions are similar to - those for :cfunc:`PyBuffer_FromObject`. If the *base* object does not export - the writeable buffer protocol, then :exc:`TypeError` is raised. + Return a new writable buffer object. Parameters and exceptions are similar + to those for :cfunc:`PyBuffer_FromObject`. If the *base* object does not + export the writeable buffer protocol, then :exc:`TypeError` is raised. + + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *offset* and *size*. This + might require changes in your code for properly supporting 64-bit + systems. .. cfunction:: PyObject* PyBuffer_FromMemory(void *ptr, Py_ssize_t size) - Return a new read-only buffer object that reads from a specified location in - memory, with a specified size. The caller is responsible for ensuring that the - memory buffer, passed in as *ptr*, is not deallocated while the returned buffer - object exists. Raises :exc:`ValueError` if *size* is less than zero. Note that - :const:`Py_END_OF_BUFFER` may *not* be passed for the *size* parameter; - :exc:`ValueError` will be raised in that case. + Return a new read-only buffer object that reads from a specified location + in memory, with a specified size. The caller is responsible for ensuring + that the memory buffer, passed in as *ptr*, is not deallocated while the + returned buffer object exists. Raises :exc:`ValueError` if *size* is less + than zero. Note that :const:`Py_END_OF_BUFFER` may *not* be passed for the + *size* parameter; :exc:`ValueError` will be raised in that case. + + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. .. cfunction:: PyObject* PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size) - Similar to :cfunc:`PyBuffer_FromMemory`, but the returned buffer is writable. + Similar to :cfunc:`PyBuffer_FromMemory`, but the returned buffer is + writable. + + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. .. cfunction:: PyObject* PyBuffer_New(Py_ssize_t size) Return a new writable buffer object that maintains its own memory buffer of - *size* bytes. :exc:`ValueError` is returned if *size* is not zero or positive. - Note that the memory buffer (as returned by :cfunc:`PyObject_AsWriteBuffer`) is - not specifically aligned. + *size* bytes. :exc:`ValueError` is returned if *size* is not zero or + positive. Note that the memory buffer (as returned by + :cfunc:`PyObject_AsWriteBuffer`) is not specifically aligned. + + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. Modified: python/branches/release26-maint/Doc/c-api/dict.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/dict.rst (original) +++ python/branches/release26-maint/Doc/c-api/dict.rst Wed Apr 29 10:00:05 2009 @@ -19,8 +19,9 @@ single: DictType (in module types) single: DictionaryType (in module types) - This instance of :ctype:`PyTypeObject` represents the Python dictionary type. - This is exposed to Python programs as ``dict`` and ``types.DictType``. + This instance of :ctype:`PyTypeObject` represents the Python dictionary + type. This is exposed to Python programs as ``dict`` and + ``types.DictType``. .. cfunction:: int PyDict_Check(PyObject *p) @@ -34,8 +35,8 @@ .. cfunction:: int PyDict_CheckExact(PyObject *p) - Return true if *p* is a dict object, but not an instance of a subtype of the - dict type. + Return true if *p* is a dict object, but not an instance of a subtype of + the dict type. .. versionadded:: 2.4 @@ -47,9 +48,9 @@ .. cfunction:: PyObject* PyDictProxy_New(PyObject *dict) - Return a proxy object for a mapping which enforces read-only behavior. This is - normally used to create a proxy to prevent modification of the dictionary for - non-dynamic class types. + Return a proxy object for a mapping which enforces read-only behavior. + This is normally used to create a proxy to prevent modification of the + dictionary for non-dynamic class types. .. versionadded:: 2.2 @@ -61,9 +62,9 @@ .. cfunction:: int PyDict_Contains(PyObject *p, PyObject *key) - Determine if dictionary *p* contains *key*. If an item in *p* is matches *key*, - return ``1``, otherwise return ``0``. On error, return ``-1``. This is - equivalent to the Python expression ``key in p``. + Determine if dictionary *p* contains *key*. If an item in *p* is matches + *key*, return ``1``, otherwise return ``0``. On error, return ``-1``. + This is equivalent to the Python expression ``key in p``. .. versionadded:: 2.4 @@ -78,24 +79,25 @@ .. cfunction:: int PyDict_SetItem(PyObject *p, PyObject *key, PyObject *val) Insert *value* into the dictionary *p* with a key of *key*. *key* must be - :term:`hashable`; if it isn't, :exc:`TypeError` will be raised. Return ``0`` - on success or ``-1`` on failure. + :term:`hashable`; if it isn't, :exc:`TypeError` will be raised. Return + ``0`` on success or ``-1`` on failure. .. cfunction:: int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val) .. index:: single: PyString_FromString() - Insert *value* into the dictionary *p* using *key* as a key. *key* should be a - :ctype:`char\*`. The key object is created using ``PyString_FromString(key)``. - Return ``0`` on success or ``-1`` on failure. + Insert *value* into the dictionary *p* using *key* as a key. *key* should + be a :ctype:`char\*`. The key object is created using + ``PyString_FromString(key)``. Return ``0`` on success or ``-1`` on + failure. .. cfunction:: int PyDict_DelItem(PyObject *p, PyObject *key) - Remove the entry in dictionary *p* with key *key*. *key* must be hashable; if it - isn't, :exc:`TypeError` is raised. Return ``0`` on success or ``-1`` on - failure. + Remove the entry in dictionary *p* with key *key*. *key* must be hashable; + if it isn't, :exc:`TypeError` is raised. Return ``0`` on success or ``-1`` + on failure. .. cfunction:: int PyDict_DelItemString(PyObject *p, char *key) @@ -106,8 +108,8 @@ .. cfunction:: PyObject* PyDict_GetItem(PyObject *p, PyObject *key) - Return the object from dictionary *p* which has a key *key*. Return *NULL* if - the key *key* is not present, but *without* setting an exception. + Return the object from dictionary *p* which has a key *key*. Return *NULL* + if the key *key* is not present, but *without* setting an exception. .. cfunction:: PyObject* PyDict_GetItemString(PyObject *p, const char *key) @@ -118,41 +120,46 @@ .. cfunction:: PyObject* PyDict_Items(PyObject *p) - Return a :ctype:`PyListObject` containing all the items from the dictionary, as - in the dictionary method :meth:`dict.items`. + Return a :ctype:`PyListObject` containing all the items from the + dictionary, as in the dictionary method :meth:`dict.items`. .. cfunction:: PyObject* PyDict_Keys(PyObject *p) - Return a :ctype:`PyListObject` containing all the keys from the dictionary, as - in the dictionary method :meth:`dict.keys`. + Return a :ctype:`PyListObject` containing all the keys from the dictionary, + as in the dictionary method :meth:`dict.keys`. .. cfunction:: PyObject* PyDict_Values(PyObject *p) - Return a :ctype:`PyListObject` containing all the values from the dictionary - *p*, as in the dictionary method :meth:`dict.values`. + Return a :ctype:`PyListObject` containing all the values from the + dictionary *p*, as in the dictionary method :meth:`dict.values`. .. cfunction:: Py_ssize_t PyDict_Size(PyObject *p) .. index:: builtin: len - Return the number of items in the dictionary. This is equivalent to ``len(p)`` - on a dictionary. + Return the number of items in the dictionary. This is equivalent to + ``len(p)`` on a dictionary. + + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. .. cfunction:: int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) - Iterate over all key-value pairs in the dictionary *p*. The :ctype:`int` - referred to by *ppos* must be initialized to ``0`` prior to the first call to - this function to start the iteration; the function returns true for each pair in - the dictionary, and false once all pairs have been reported. The parameters - *pkey* and *pvalue* should either point to :ctype:`PyObject\*` variables that - will be filled in with each key and value, respectively, or may be *NULL*. Any - references returned through them are borrowed. *ppos* should not be altered - during iteration. Its value represents offsets within the internal dictionary - structure, and since the structure is sparse, the offsets are not consecutive. + Iterate over all key-value pairs in the dictionary *p*. The + :ctype:`Py_ssize_t` referred to by *ppos* must be initialized to ``0`` + prior to the first call to this function to start the iteration; the + function returns true for each pair in the dictionary, and false once all + pairs have been reported. The parameters *pkey* and *pvalue* should either + point to :ctype:`PyObject\*` variables that will be filled in with each key + and value, respectively, or may be *NULL*. Any references returned through + them are borrowed. *ppos* should not be altered during iteration. Its + value represents offsets within the internal dictionary structure, and + since the structure is sparse, the offsets are not consecutive. For example:: @@ -164,9 +171,10 @@ ... } - The dictionary *p* should not be mutated during iteration. It is safe (since - Python 2.1) to modify the values of the keys as you iterate over the dictionary, - but only so long as the set of keys does not change. For example:: + The dictionary *p* should not be mutated during iteration. It is safe + (since Python 2.1) to modify the values of the keys as you iterate over the + dictionary, but only so long as the set of keys does not change. For + example:: PyObject *key, *value; Py_ssize_t pos = 0; @@ -183,15 +191,19 @@ Py_DECREF(o); } + .. versionchanged:: 2.5 + This function used an :ctype:`int *` type for *ppos*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyDict_Merge(PyObject *a, PyObject *b, int override) - Iterate over mapping object *b* adding key-value pairs to dictionary *a*. *b* - may be a dictionary, or any object supporting :func:`PyMapping_Keys` and - :func:`PyObject_GetItem`. If *override* is true, existing pairs in *a* will be - replaced if a matching key is found in *b*, otherwise pairs will only be added - if there is not a matching key in *a*. Return ``0`` on success or ``-1`` if an - exception was raised. + Iterate over mapping object *b* adding key-value pairs to dictionary *a*. + *b* may be a dictionary, or any object supporting :func:`PyMapping_Keys` + and :func:`PyObject_GetItem`. If *override* is true, existing pairs in *a* + will be replaced if a matching key is found in *b*, otherwise pairs will + only be added if there is not a matching key in *a*. Return ``0`` on + success or ``-1`` if an exception was raised. .. versionadded:: 2.2 @@ -206,11 +218,12 @@ .. cfunction:: int PyDict_MergeFromSeq2(PyObject *a, PyObject *seq2, int override) - Update or merge into dictionary *a*, from the key-value pairs in *seq2*. *seq2* - must be an iterable object producing iterable objects of length 2, viewed as - key-value pairs. In case of duplicate keys, the last wins if *override* is - true, else the first wins. Return ``0`` on success or ``-1`` if an exception was - raised. Equivalent Python (except for the return value):: + Update or merge into dictionary *a*, from the key-value pairs in *seq2*. + *seq2* must be an iterable object producing iterable objects of length 2, + viewed as key-value pairs. In case of duplicate keys, the last wins if + *override* is true, else the first wins. Return ``0`` on success or ``-1`` + if an exception was raised. Equivalent Python (except for the return + value):: def PyDict_MergeFromSeq2(a, seq2, override): for key, value in seq2: Modified: python/branches/release26-maint/Doc/c-api/gcsupport.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/gcsupport.rst (original) +++ python/branches/release26-maint/Doc/c-api/gcsupport.rst Wed Apr 29 10:00:05 2009 @@ -9,7 +9,8 @@ references requires support from object types which are "containers" for other objects which may also be containers. Types which do not store references to other objects, or which only store references to atomic types (such as numbers -or strings), do not need to provide any explicit support for garbage collection. +or strings), do not need to provide any explicit support for garbage +collection. .. An example showing the use of these interfaces can be found in "Supporting the .. Cycle Collector (XXX not found: ../ext/example-cycle-support.html)". @@ -23,13 +24,14 @@ .. data:: Py_TPFLAGS_HAVE_GC :noindex: - Objects with a type with this flag set must conform with the rules documented - here. For convenience these objects will be referred to as container objects. + Objects with a type with this flag set must conform with the rules + documented here. For convenience these objects will be referred to as + container objects. Constructors for container types must conform to two rules: -#. The memory for the object must be allocated using :cfunc:`PyObject_GC_New` or - :cfunc:`PyObject_GC_VarNew`. +#. The memory for the object must be allocated using :cfunc:`PyObject_GC_New` + or :cfunc:`PyObject_GC_VarNew`. #. Once all the fields which may contain references to other containers are initialized, it must call :cfunc:`PyObject_GC_Track`. @@ -46,20 +48,28 @@ Analogous to :cfunc:`PyObject_NewVar` but for container objects with the :const:`Py_TPFLAGS_HAVE_GC` flag set. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. -.. cfunction:: PyVarObject * PyObject_GC_Resize(PyVarObject *op, Py_ssize_t) - Resize an object allocated by :cfunc:`PyObject_NewVar`. Returns the resized - object or *NULL* on failure. +.. cfunction:: TYPE* PyObject_GC_Resize(TYPE, PyVarObject *op, Py_ssize_t newsize) + + Resize an object allocated by :cfunc:`PyObject_NewVar`. Returns the + resized object or *NULL* on failure. + + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *newsize*. This might + require changes in your code for properly supporting 64-bit systems. .. cfunction:: void PyObject_GC_Track(PyObject *op) - Adds the object *op* to the set of container objects tracked by the collector. - The collector can run at unexpected times so objects must be valid while being - tracked. This should be called once all the fields followed by the - :attr:`tp_traverse` handler become valid, usually near the end of the - constructor. + Adds the object *op* to the set of container objects tracked by the + collector. The collector can run at unexpected times so objects must be + valid while being tracked. This should be called once all the fields + followed by the :attr:`tp_traverse` handler become valid, usually near the + end of the constructor. .. cfunction:: void _PyObject_GC_TRACK(PyObject *op) @@ -85,10 +95,10 @@ .. cfunction:: void PyObject_GC_UnTrack(void *op) Remove the object *op* from the set of container objects tracked by the - collector. Note that :cfunc:`PyObject_GC_Track` can be called again on this - object to add it back to the set of tracked objects. The deallocator - (:attr:`tp_dealloc` handler) should call this for the object before any of the - fields used by the :attr:`tp_traverse` handler become invalid. + collector. Note that :cfunc:`PyObject_GC_Track` can be called again on + this object to add it back to the set of tracked objects. The deallocator + (:attr:`tp_dealloc` handler) should call this for the object before any of + the fields used by the :attr:`tp_traverse` handler become invalid. .. cfunction:: void _PyObject_GC_UNTRACK(PyObject *op) @@ -101,11 +111,12 @@ .. ctype:: int (*visitproc)(PyObject *object, void *arg) - Type of the visitor function passed to the :attr:`tp_traverse` handler. The - function should be called with an object to traverse as *object* and the third - parameter to the :attr:`tp_traverse` handler as *arg*. The Python core uses - several visitor functions to implement cyclic garbage detection; it's not - expected that users will need to write their own visitor functions. + Type of the visitor function passed to the :attr:`tp_traverse` handler. + The function should be called with an object to traverse as *object* and + the third parameter to the :attr:`tp_traverse` handler as *arg*. The + Python core uses several visitor functions to implement cyclic garbage + detection; it's not expected that users will need to write their own + visitor functions. The :attr:`tp_traverse` handler must have the following type: @@ -114,10 +125,10 @@ Traversal function for a container object. Implementations must call the *visit* function for each object directly contained by *self*, with the - parameters to *visit* being the contained object and the *arg* value passed to - the handler. The *visit* function must not be called with a *NULL* object - argument. If *visit* returns a non-zero value that value should be returned - immediately. + parameters to *visit* being the contained object and the *arg* value passed + to the handler. The *visit* function must not be called with a *NULL* + object argument. If *visit* returns a non-zero value that value should be + returned immediately. To simplify writing :attr:`tp_traverse` handlers, a :cfunc:`Py_VISIT` macro is provided. In order to use this macro, the :attr:`tp_traverse` implementation @@ -126,9 +137,9 @@ .. cfunction:: void Py_VISIT(PyObject *o) - Call the *visit* callback, with arguments *o* and *arg*. If *visit* returns a - non-zero value, then return it. Using this macro, :attr:`tp_traverse` handlers - look like:: + Call the *visit* callback, with arguments *o* and *arg*. If *visit* returns + a non-zero value, then return it. Using this macro, :attr:`tp_traverse` + handlers look like:: static int my_traverse(Noddy *self, visitproc visit, void *arg) @@ -140,14 +151,15 @@ .. versionadded:: 2.4 -The :attr:`tp_clear` handler must be of the :ctype:`inquiry` type, or *NULL* if -the object is immutable. +The :attr:`tp_clear` handler must be of the :ctype:`inquiry` type, or *NULL* +if the object is immutable. .. ctype:: int (*inquiry)(PyObject *self) - Drop references that may have created reference cycles. Immutable objects do - not have to define this method since they can never directly create reference - cycles. Note that the object must still be valid after calling this method - (don't just call :cfunc:`Py_DECREF` on a reference). The collector will call - this method if it detects that this object is involved in a reference cycle. + Drop references that may have created reference cycles. Immutable objects + do not have to define this method since they can never directly create + reference cycles. Note that the object must still be valid after calling + this method (don't just call :cfunc:`Py_DECREF` on a reference). The + collector will call this method if it detects that this object is involved + in a reference cycle. Modified: python/branches/release26-maint/Doc/c-api/init.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/init.rst (original) +++ python/branches/release26-maint/Doc/c-api/init.rst Wed Apr 29 10:00:05 2009 @@ -491,13 +491,13 @@ global variable). Conversely, when acquiring the lock and restoring the thread state, the lock must be acquired before storing the thread state pointer. -Why am I going on with so much detail about this? Because when threads are -created from C, they don't have the global interpreter lock, nor is there a -thread state data structure for them. Such threads must bootstrap themselves -into existence, by first creating a thread state data structure, then acquiring -the lock, and finally storing their thread state pointer, before they can start -using the Python/C API. When they are done, they should reset the thread state -pointer, release the lock, and finally free their thread state data structure. +It is important to note that when threads are created from C, they don't have +the global interpreter lock, nor is there a thread state data structure for +them. Such threads must bootstrap themselves into existence, by first +creating a thread state data structure, then acquiring the lock, and finally +storing their thread state pointer, before they can start using the Python/C +API. When they are done, they should reset the thread state pointer, release +the lock, and finally free their thread state data structure. Beginning with version 2.3, threads can now take advantage of the :cfunc:`PyGILState_\*` functions to do all of the above automatically. The Modified: python/branches/release26-maint/Doc/c-api/list.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/list.rst (original) +++ python/branches/release26-maint/Doc/c-api/list.rst Wed Apr 29 10:00:05 2009 @@ -17,8 +17,9 @@ .. index:: single: ListType (in module types) - This instance of :ctype:`PyTypeObject` represents the Python list type. This is - the same object as ``list`` and ``types.ListType`` in the Python layer. + This instance of :ctype:`PyTypeObject` represents the Python list type. + This is the same object as ``list`` and ``types.ListType`` in the Python + layer. .. cfunction:: int PyList_Check(PyObject *p) @@ -32,8 +33,8 @@ .. cfunction:: int PyList_CheckExact(PyObject *p) - Return true if *p* is a list object, but not an instance of a subtype of the - list type. + Return true if *p* is a list object, but not an instance of a subtype of + the list type. .. versionadded:: 2.2 @@ -44,10 +45,14 @@ .. note:: - If *length* is greater than zero, the returned list object's items are set to - ``NULL``. Thus you cannot use abstract API functions such as - :cfunc:`PySequence_SetItem` or expose the object to Python code before setting - all items to a real object with :cfunc:`PyList_SetItem`. + If *length* is greater than zero, the returned list object's items are + set to ``NULL``. Thus you cannot use abstract API functions such as + :cfunc:`PySequence_SetItem` or expose the object to Python code before + setting all items to a real object with :cfunc:`PyList_SetItem`. + + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *size*. This might require + changes in your code for properly supporting 64-bit systems. .. cfunction:: Py_ssize_t PyList_Size(PyObject *list) @@ -57,80 +62,118 @@ Return the length of the list object in *list*; this is equivalent to ``len(list)`` on a list object. + .. versionchanged:: 2.5 + This function returned an :ctype:`int`. This might require changes in + your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PyList_GET_SIZE(PyObject *list) Macro form of :cfunc:`PyList_Size` without error checking. + .. versionchanged:: 2.5 + This macro returned an :ctype:`int`. This might require changes in your + code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index) - Return the object at position *pos* in the list pointed to by *p*. 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 :exc:`IndexError` exception. + Return the object at position *pos* in the list pointed to by *p*. 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 + :exc:`IndexError` exception. + + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *index*. This might require + changes in your code for properly supporting 64-bit systems. .. cfunction:: PyObject* PyList_GET_ITEM(PyObject *list, Py_ssize_t i) Macro form of :cfunc:`PyList_GetItem` without error checking. + .. versionchanged:: 2.5 + This macro used an :ctype:`int` for *i*. This might require changes in + your code for properly supporting 64-bit systems. + .. cfunction:: int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item) - Set the item at index *index* in list to *item*. Return ``0`` on success or - ``-1`` on failure. + Set the item at index *index* in list to *item*. Return ``0`` on success + or ``-1`` on failure. .. note:: - This function "steals" a reference to *item* and discards a reference to an item - already in the list at the affected position. + This function "steals" a reference to *item* and discards a reference to + an item already in the list at the affected position. + + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *index*. This might require + changes in your code for properly supporting 64-bit systems. .. cfunction:: void PyList_SET_ITEM(PyObject *list, Py_ssize_t i, PyObject *o) - Macro form of :cfunc:`PyList_SetItem` without error checking. This is normally - only used to fill in new lists where there is no previous content. + Macro form of :cfunc:`PyList_SetItem` without error checking. This is + normally only used to fill in new lists where there is no previous content. .. note:: - This function "steals" a reference to *item*, and, unlike - :cfunc:`PyList_SetItem`, does *not* discard a reference to any item that it - being replaced; any reference in *list* at position *i* will be leaked. + This macro "steals" a reference to *item*, and, unlike + :cfunc:`PyList_SetItem`, does *not* discard a reference to any item that + it being replaced; any reference in *list* at position *i* will be + leaked. + + .. versionchanged:: 2.5 + This macro used an :ctype:`int` for *i*. This might require + changes in your code for properly supporting 64-bit systems. .. cfunction:: int PyList_Insert(PyObject *list, Py_ssize_t index, PyObject *item) - Insert the item *item* into list *list* in front of index *index*. Return ``0`` - if successful; return ``-1`` and set an exception if unsuccessful. Analogous to - ``list.insert(index, item)``. + Insert the item *item* into list *list* in front of index *index*. Return + ``0`` if successful; return ``-1`` and set an exception if unsuccessful. + Analogous to ``list.insert(index, item)``. + + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *index*. This might require + changes in your code for properly supporting 64-bit systems. .. cfunction:: int PyList_Append(PyObject *list, PyObject *item) - Append the object *item* at the end of list *list*. Return ``0`` if successful; - return ``-1`` and set an exception if unsuccessful. Analogous to - ``list.append(item)``. + Append the object *item* at the end of list *list*. Return ``0`` if + successful; return ``-1`` and set an exception if unsuccessful. Analogous + to ``list.append(item)``. .. cfunction:: PyObject* PyList_GetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high) - Return a list of the objects in *list* containing the objects *between* *low* - and *high*. Return *NULL* and set an exception if unsuccessful. Analogous to - ``list[low:high]``. + Return a list of the objects in *list* containing the objects *between* + *low* and *high*. Return *NULL* and set an exception if unsuccessful. + Analogous to ``list[low:high]``. + + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *low* and *high*. This might + require changes in your code for properly supporting 64-bit systems. .. cfunction:: int PyList_SetSlice(PyObject *list, Py_ssize_t low, Py_ssize_t high, PyObject *itemlist) - Set the slice of *list* between *low* and *high* to the contents of *itemlist*. - Analogous to ``list[low:high] = itemlist``. The *itemlist* may be *NULL*, - indicating the assignment of an empty list (slice deletion). Return ``0`` on - success, ``-1`` on failure. + Set the slice of *list* between *low* and *high* to the contents of + *itemlist*. Analogous to ``list[low:high] = itemlist``. The *itemlist* may + be *NULL*, indicating the assignment of an empty list (slice deletion). + Return ``0`` on success, ``-1`` on failure. + + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *low* and *high*. This might + require changes in your code for properly supporting 64-bit systems. .. cfunction:: int PyList_Sort(PyObject *list) - Sort the items of *list* in place. Return ``0`` on success, ``-1`` on failure. - This is equivalent to ``list.sort()``. + Sort the items of *list* in place. Return ``0`` on success, ``-1`` on + failure. This is equivalent to ``list.sort()``. .. cfunction:: int PyList_Reverse(PyObject *list) Modified: python/branches/release26-maint/Doc/c-api/long.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/long.rst (original) +++ python/branches/release26-maint/Doc/c-api/long.rst Wed Apr 29 10:00:05 2009 @@ -106,6 +106,10 @@ .. versionadded:: 1.6 + .. versionchanged:: 2.5 + This function used an :ctype:`int` for *length*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyLong_FromVoidPtr(void *p) Modified: python/branches/release26-maint/Doc/c-api/mapping.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/mapping.rst (original) +++ python/branches/release26-maint/Doc/c-api/mapping.rst Wed Apr 29 10:00:05 2009 @@ -12,7 +12,8 @@ function always succeeds. -.. cfunction:: Py_ssize_t PyMapping_Length(PyObject *o) +.. cfunction:: Py_ssize_t PyMapping_Size(PyObject *o) + Py_ssize_t PyMapping_Length(PyObject *o) .. index:: builtin: len @@ -20,6 +21,10 @@ objects that do not provide mapping protocol, this is equivalent to the Python expression ``len(o)``. + .. versionchanged:: 2.5 + These functions returned an :ctype:`int` type. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyMapping_DelItemString(PyObject *o, char *key) Modified: python/branches/release26-maint/Doc/c-api/marshal.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/marshal.rst (original) +++ python/branches/release26-maint/Doc/c-api/marshal.rst Wed Apr 29 10:00:05 2009 @@ -5,25 +5,26 @@ Data marshalling support ======================== -These routines allow C code to work with serialized objects using the same data -format as the :mod:`marshal` module. There are functions to write data into the -serialization format, and additional functions that can be used to read the data -back. Files used to store marshalled data must be opened in binary mode. +These routines allow C code to work with serialized objects using the same +data format as the :mod:`marshal` module. There are functions to write data +into the serialization format, and additional functions that can be used to +read the data back. Files used to store marshalled data must be opened in +binary mode. Numeric values are stored with the least significant byte first. -The module supports two versions of the data format: version 0 is the historical -version, version 1 (new in Python 2.4) shares interned strings in the file, and -upon unmarshalling. Version 2 (new in Python 2.5) uses a binary format for -floating point numbers. -*Py_MARSHAL_VERSION* indicates the current file format (currently 2). +The module supports two versions of the data format: version 0 is the +historical version, version 1 (new in Python 2.4) shares interned strings in +the file, and upon unmarshalling. Version 2 (new in Python 2.5) uses a binary +format for floating point numbers. *Py_MARSHAL_VERSION* indicates the current +file format (currently 2). .. cfunction:: void PyMarshal_WriteLongToFile(long value, FILE *file, int version) - Marshal a :ctype:`long` integer, *value*, to *file*. This will only write the - least-significant 32 bits of *value*; regardless of the size of the native - :ctype:`long` type. + Marshal a :ctype:`long` integer, *value*, to *file*. This will only write + the least-significant 32 bits of *value*; regardless of the size of the + native :ctype:`long` type. .. versionchanged:: 2.4 *version* indicates the file format. @@ -48,24 +49,24 @@ The following functions allow marshalled values to be read back in. XXX What about error detection? It appears that reading past the end of the -file will always result in a negative numeric value (where that's relevant), but -it's not clear that negative values won't be handled properly when there's no -error. What's the right way to tell? Should only non-negative values be written -using these routines? +file will always result in a negative numeric value (where that's relevant), +but it's not clear that negative values won't be handled properly when there's +no error. What's the right way to tell? Should only non-negative values be +written using these routines? .. cfunction:: long PyMarshal_ReadLongFromFile(FILE *file) - Return a C :ctype:`long` from the data stream in a :ctype:`FILE\*` opened for - reading. Only a 32-bit value can be read in using this function, regardless of - the native size of :ctype:`long`. + Return a C :ctype:`long` from the data stream in a :ctype:`FILE\*` opened + for reading. Only a 32-bit value can be read in using this function, + regardless of the native size of :ctype:`long`. .. cfunction:: int PyMarshal_ReadShortFromFile(FILE *file) - Return a C :ctype:`short` from the data stream in a :ctype:`FILE\*` opened for - reading. Only a 16-bit value can be read in using this function, regardless of - the native size of :ctype:`short`. + Return a C :ctype:`short` from the data stream in a :ctype:`FILE\*` opened + for reading. Only a 16-bit value can be read in using this function, + regardless of the native size of :ctype:`short`. .. cfunction:: PyObject* PyMarshal_ReadObjectFromFile(FILE *file) @@ -78,17 +79,22 @@ .. cfunction:: PyObject* PyMarshal_ReadLastObjectFromFile(FILE *file) Return a Python object from the data stream in a :ctype:`FILE\*` opened for - reading. Unlike :cfunc:`PyMarshal_ReadObjectFromFile`, this function assumes - that no further objects will be read from the file, allowing it to aggressively - load file data into memory so that the de-serialization can operate from data in - memory rather than reading a byte at a time from the file. Only use these - variant if you are certain that you won't be reading anything else from the - file. On error, sets the appropriate exception (:exc:`EOFError` or - :exc:`TypeError`) and returns *NULL*. + reading. Unlike :cfunc:`PyMarshal_ReadObjectFromFile`, this function + assumes that no further objects will be read from the file, allowing it to + aggressively load file data into memory so that the de-serialization can + operate from data in memory rather than reading a byte at a time from the + file. Only use these variant if you are certain that you won't be reading + anything else from the file. On error, sets the appropriate exception + (:exc:`EOFError` or :exc:`TypeError`) and returns *NULL*. .. cfunction:: PyObject* PyMarshal_ReadObjectFromString(char *string, Py_ssize_t len) - Return a Python object from the data stream in a character buffer containing - *len* bytes pointed to by *string*. On error, sets the appropriate exception - (:exc:`EOFError` or :exc:`TypeError`) and returns *NULL*. + Return a Python object from the data stream in a character buffer + containing *len* bytes pointed to by *string*. On error, sets the + appropriate exception (:exc:`EOFError` or :exc:`TypeError`) and returns + *NULL*. + + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *len*. This might require + changes in your code for properly supporting 64-bit systems. Modified: python/branches/release26-maint/Doc/c-api/objbuffer.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/objbuffer.rst (original) +++ python/branches/release26-maint/Doc/c-api/objbuffer.rst Wed Apr 29 10:00:05 2009 @@ -2,30 +2,46 @@ .. _abstract-buffer: -Buffer Protocol -=============== +Old Buffer Protocol +=================== + + +This section describes the legacy buffer protocol, which has been introduced +in Python 1.6. It is still supported but deprecated in the Python 2.x series. +Python 3.0 introduces a new buffer protocol which fixes weaknesses and +shortcomings of the protocol, and has been backported to Python 2.6. See +:ref:`bufferobjects` for more information. .. cfunction:: int PyObject_AsCharBuffer(PyObject *obj, const char **buffer, Py_ssize_t *buffer_len) Returns a pointer to a read-only memory location usable as character-based input. The *obj* argument must support the single-segment character buffer - interface. On success, returns ``0``, sets *buffer* to the memory location and - *buffer_len* to the buffer length. Returns ``-1`` and sets a :exc:`TypeError` - on error. + interface. On success, returns ``0``, sets *buffer* to the memory location + and *buffer_len* to the buffer length. Returns ``-1`` and sets a + :exc:`TypeError` on error. .. versionadded:: 1.6 + .. versionchanged:: 2.5 + This function used an :ctype:`int *` type for *buffer_len*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyObject_AsReadBuffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len) - Returns a pointer to a read-only memory location containing arbitrary data. The - *obj* argument must support the single-segment readable buffer interface. On - success, returns ``0``, sets *buffer* to the memory location and *buffer_len* to - the buffer length. Returns ``-1`` and sets a :exc:`TypeError` on error. + Returns a pointer to a read-only memory location containing arbitrary data. + The *obj* argument must support the single-segment readable buffer + interface. On success, returns ``0``, sets *buffer* to the memory location + and *buffer_len* to the buffer length. Returns ``-1`` and sets a + :exc:`TypeError` on error. .. versionadded:: 1.6 + .. versionchanged:: 2.5 + This function used an :ctype:`int *` type for *buffer_len*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyObject_CheckReadBuffer(PyObject *o) @@ -38,9 +54,13 @@ .. cfunction:: int PyObject_AsWriteBuffer(PyObject *obj, void **buffer, Py_ssize_t *buffer_len) Returns a pointer to a writeable memory location. The *obj* argument must - support the single-segment, character buffer interface. On success, returns - ``0``, sets *buffer* to the memory location and *buffer_len* to the buffer - length. Returns ``-1`` and sets a :exc:`TypeError` on error. + support the single-segment, character buffer interface. On success, + returns ``0``, sets *buffer* to the memory location and *buffer_len* to the + buffer length. Returns ``-1`` and sets a :exc:`TypeError` on error. .. versionadded:: 1.6 + .. versionchanged:: 2.5 + This function used an :ctype:`int *` type for *buffer_len*. This might + require changes in your code for properly supporting 64-bit systems. + Modified: python/branches/release26-maint/Doc/c-api/object.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/object.rst (original) +++ python/branches/release26-maint/Doc/c-api/object.rst Wed Apr 29 10:00:05 2009 @@ -351,6 +351,10 @@ and mapping protocols, the sequence length is returned. On error, ``-1`` is returned. This is the equivalent to the Python expression ``len(o)``. + .. versionchanged:: 2.5 + These functions returned an :ctype:`int` type. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyObject_GetItem(PyObject *o, PyObject *key) Modified: python/branches/release26-maint/Doc/c-api/sequence.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/sequence.rst (original) +++ python/branches/release26-maint/Doc/c-api/sequence.rst Wed Apr 29 10:00:05 2009 @@ -13,6 +13,7 @@ .. cfunction:: Py_ssize_t PySequence_Size(PyObject *o) + Py_ssize_t PySequence_Length(PyObject *o) .. index:: builtin: len @@ -20,10 +21,9 @@ For objects that do not provide sequence protocol, this is equivalent to the Python expression ``len(o)``. - -.. cfunction:: Py_ssize_t PySequence_Length(PyObject *o) - - Alternate name for :cfunc:`PySequence_Size`. + .. versionchanged:: 2.5 + These functions returned an :ctype:`int` type. This might require + changes in your code for properly supporting 64-bit systems. .. cfunction:: PyObject* PySequence_Concat(PyObject *o1, PyObject *o2) @@ -37,6 +37,10 @@ Return the result of repeating sequence object *o* *count* times, or *NULL* on failure. This is the equivalent of the Python expression ``o * count``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *count*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PySequence_InPlaceConcat(PyObject *o1, PyObject *o2) @@ -51,18 +55,30 @@ failure. The operation is done *in-place* when *o* supports it. This is the equivalent of the Python expression ``o *= count``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *count*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PySequence_GetItem(PyObject *o, Py_ssize_t i) Return the *i*th element of *o*, or *NULL* on failure. This is the equivalent of the Python expression ``o[i]``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PySequence_GetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2) Return the slice of sequence object *o* between *i1* and *i2*, or *NULL* on failure. This is the equivalent of the Python expression ``o[i1:i2]``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i1* and *i2*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v) @@ -70,24 +86,40 @@ is the equivalent of the Python statement ``o[i] = v``. This function *does not* steal a reference to *v*. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PySequence_DelItem(PyObject *o, Py_ssize_t i) Delete the *i*th element of object *o*. Returns ``-1`` on failure. This is the equivalent of the Python statement ``del o[i]``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PySequence_SetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2, PyObject *v) Assign the sequence object *v* to the slice in sequence object *o* from *i1* to *i2*. This is the equivalent of the Python statement ``o[i1:i2] = v``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i1* and *i2*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PySequence_DelSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2) Delete the slice in sequence object *o* from *i1* to *i2*. Returns ``-1`` on failure. This is the equivalent of the Python statement ``del o[i1:i2]``. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i1* and *i2*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PySequence_Count(PyObject *o, PyObject *value) @@ -95,6 +127,10 @@ of keys for which ``o[key] == value``. On failure, return ``-1``. This is equivalent to the Python expression ``o.count(value)``. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: int PySequence_Contains(PyObject *o, PyObject *value) @@ -108,6 +144,10 @@ Return the first index *i* for which ``o[i] == value``. On error, return ``-1``. This is equivalent to the Python expression ``o.index(value)``. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PySequence_List(PyObject *o) @@ -138,6 +178,10 @@ Return the *i*th element of *o*, assuming that *o* was returned by :cfunc:`PySequence_Fast`, *o* is not *NULL*, and that *i* is within bounds. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject** PySequence_Fast_ITEMS(PyObject *o) @@ -160,6 +204,10 @@ .. versionadded:: 2.3 + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *i*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PySequence_Fast_GET_SIZE(PyObject *o) Modified: python/branches/release26-maint/Doc/c-api/set.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/set.rst (original) +++ python/branches/release26-maint/Doc/c-api/set.rst Wed Apr 29 10:00:05 2009 @@ -116,6 +116,10 @@ ``len(anyset)``. Raises a :exc:`PyExc_SystemError` if *anyset* is not a :class:`set`, :class:`frozenset`, or an instance of a subtype. + .. versionchanged:: 2.5 + This function returned an :ctype:`int`. This might require changes in + your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PySet_GET_SIZE(PyObject *anyset) Modified: python/branches/release26-maint/Doc/c-api/slice.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/slice.rst (original) +++ python/branches/release26-maint/Doc/c-api/slice.rst Wed Apr 29 10:00:05 2009 @@ -22,35 +22,47 @@ .. cfunction:: PyObject* PySlice_New(PyObject *start, PyObject *stop, PyObject *step) Return a new slice object with the given values. The *start*, *stop*, and - *step* parameters are used as the values of the slice object attributes of the - same names. Any of the values may be *NULL*, in which case the ``None`` will be - used for the corresponding attribute. Return *NULL* if the new object could not - be allocated. + *step* parameters are used as the values of the slice object attributes of + the same names. Any of the values may be *NULL*, in which case the + ``None`` will be used for the corresponding attribute. Return *NULL* if + the new object could not be allocated. .. cfunction:: int PySlice_GetIndices(PySliceObject *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 *length* as - errors. + assuming a sequence of length *length*. Treats indices greater than + *length* as errors. - Returns 0 on success and -1 on error with no exception set (unless one of the - indices was not :const:`None` and failed to be converted to an integer, in which - case -1 is returned with an exception set). - - You probably do not want to use this function. If you want to use slice objects - in versions of Python prior to 2.3, you would probably do well to incorporate - the source of :cfunc:`PySlice_GetIndicesEx`, suitably renamed, in the source of - your extension. + Returns 0 on success and -1 on error with no exception set (unless one of + the indices was not :const:`None` and failed to be converted to an integer, + in which case -1 is returned with an exception set). + + You probably do not want to use this function. If you want to use slice + objects in versions of Python prior to 2.3, you would probably do well to + incorporate the source of :cfunc:`PySlice_GetIndicesEx`, suitably renamed, + in the source of your extension. + + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *length* and an + :ctype:`int *` type for *start*, *stop*, and *step*. This might require + changes in your code for properly supporting 64-bit systems. .. cfunction:: 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) - Usable replacement for :cfunc:`PySlice_GetIndices`. Retrieve the start, stop, - and step indices from the slice object *slice* assuming a sequence of length - *length*, and store the length of the slice in *slicelength*. Out of bounds - indices are clipped in a manner consistent with the handling of normal slices. + Usable replacement for :cfunc:`PySlice_GetIndices`. Retrieve the start, + stop, and step indices from the slice object *slice* assuming a sequence of + length *length*, and store the length of the slice in *slicelength*. Out + of bounds indices are clipped in a manner consistent with the handling of + normal slices. Returns 0 on success and -1 on error with exception set. .. versionadded:: 2.3 + + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *length* and an + :ctype:`int *` type for *start*, *stop*, *step*, and *slicelength*. This + might require changes in your code for properly supporting 64-bit + systems. Modified: python/branches/release26-maint/Doc/c-api/string.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/string.rst (original) +++ python/branches/release26-maint/Doc/c-api/string.rst Wed Apr 29 10:00:05 2009 @@ -58,6 +58,10 @@ *len* on success, and *NULL* on failure. If *v* is *NULL*, the contents of the string are uninitialized. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *len*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyString_FromFormat(const char *format, ...) @@ -132,11 +136,19 @@ Return the length of the string in string object *string*. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PyString_GET_SIZE(PyObject *string) Macro form of :cfunc:`PyString_Size` but without error checking. + .. versionchanged:: 2.5 + This macro returned an :ctype:`int` type. This might require changes in + your code for properly supporting 64-bit systems. + .. cfunction:: char* PyString_AsString(PyObject *string) @@ -172,6 +184,10 @@ *string* and operates on that. If *string* is not a string object at all, :cfunc:`PyString_AsStringAndSize` returns ``-1`` and raises :exc:`TypeError`. + .. versionchanged:: 2.5 + This function used an :ctype:`int *` type for *length*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: void PyString_Concat(PyObject **string, PyObject *newpart) @@ -200,6 +216,9 @@ fails, the original string object at *\*string* is deallocated, *\*string* is set to *NULL*, a memory exception is set, and ``-1`` is returned. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *newsize*. This might + require changes in your code for properly supporting 64-bit systems. .. cfunction:: PyObject* PyString_Format(PyObject *format, PyObject *args) @@ -236,6 +255,10 @@ The codec to be used is looked up using the Python codec registry. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyString_AsDecodedObject(PyObject *str, const char *encoding, const char *errors) @@ -254,6 +277,10 @@ :meth:`encode` method. The codec to be used is looked up using the Python codec registry. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyString_AsEncodedObject(PyObject *str, const char *encoding, const char *errors) Modified: python/branches/release26-maint/Doc/c-api/structures.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/structures.rst (original) +++ python/branches/release26-maint/Doc/c-api/structures.rst Wed Apr 29 10:00:05 2009 @@ -9,28 +9,29 @@ object types for Python. This section describes these structures and how they are used. -All Python objects ultimately share a small number of fields at the beginning of -the object's representation in memory. These are represented by the -:ctype:`PyObject` and :ctype:`PyVarObject` types, which are defined, in turn, by -the expansions of some macros also used, whether directly or indirectly, in the -definition of all other Python objects. +All Python objects ultimately share a small number of fields at the beginning +of the object's representation in memory. These are represented by the +:ctype:`PyObject` and :ctype:`PyVarObject` types, which are defined, in turn, +by the expansions of some macros also used, whether directly or indirectly, in +the definition of all other Python objects. .. ctype:: PyObject - All object types are extensions of this type. This is a type which contains the - information Python needs to treat a pointer to an object as an object. In a - normal "release" build, it contains only the object's reference count and a - pointer to the corresponding type object. It corresponds to the fields defined - by the expansion of the ``PyObject_HEAD`` macro. + All object types are extensions of this type. This is a type which + contains the information Python needs to treat a pointer to an object as an + object. In a normal "release" build, it contains only the object's + reference count and a pointer to the corresponding type object. It + corresponds to the fields defined by the expansion of the ``PyObject_HEAD`` + macro. .. ctype:: PyVarObject - This is an extension of :ctype:`PyObject` that adds the :attr:`ob_size` field. - This is only used for objects that have some notion of *length*. This type does - not often appear in the Python/C API. It corresponds to the fields defined by - the expansion of the ``PyObject_VAR_HEAD`` macro. + This is an extension of :ctype:`PyObject` that adds the :attr:`ob_size` + field. This is only used for objects that have some notion of *length*. + This type does not often appear in the Python/C API. It corresponds to the + fields defined by the expansion of the ``PyObject_VAR_HEAD`` macro. These macros are used in the definition of :ctype:`PyObject` and :ctype:`PyVarObject`: @@ -40,9 +41,9 @@ This is a macro which expands to the declarations of the fields of the :ctype:`PyObject` type; it is used when declaring new types which represent - objects without a varying length. The specific fields it expands to depend on - the definition of :cmacro:`Py_TRACE_REFS`. By default, that macro is not - defined, and :cmacro:`PyObject_HEAD` expands to:: + objects without a varying length. The specific fields it expands to depend + on the definition of :cmacro:`Py_TRACE_REFS`. By default, that macro is + not defined, and :cmacro:`PyObject_HEAD` expands to:: Py_ssize_t ob_refcnt; PyTypeObject *ob_type; @@ -57,9 +58,9 @@ .. cmacro:: PyObject_VAR_HEAD This is a macro which expands to the declarations of the fields of the - :ctype:`PyVarObject` type; it is used when declaring new types which represent - objects with a length that varies from instance to instance. This macro always - expands to:: + :ctype:`PyVarObject` type; it is used when declaring new types which + represent objects with a length that varies from instance to instance. + This macro always expands to:: PyObject_HEAD Py_ssize_t ob_size; @@ -67,16 +68,34 @@ Note that :cmacro:`PyObject_HEAD` is part of the expansion, and that its own expansion varies depending on the definition of :cmacro:`Py_TRACE_REFS`. -PyObject_HEAD_INIT + +.. cmacro:: PyObject_HEAD_INIT(type) + + This is a macro which expands to initialization values for a new + :ctype:`PyObject` type. This macro expands to:: + + _PyObject_EXTRA_INIT + 1, type, + + +.. cmacro:: PyVarObject_HEAD_INIT(type, size) + + This is a macro which expands to initialization values for a new + :ctype:`PyVarObject` type, including the :attr:`ob_size` field. + This macro expands to:: + + _PyObject_EXTRA_INIT + 1, type, size, .. ctype:: PyCFunction - Type of the functions used to implement most Python callables in C. Functions of - this type take two :ctype:`PyObject\*` parameters and return one such value. If - the return value is *NULL*, an exception shall have been set. If not *NULL*, - the return value is interpreted as the return value of the function as exposed - in Python. The function must return a new reference. + Type of the functions used to implement most Python callables in C. + Functions of this type take two :ctype:`PyObject\*` parameters and return + one such value. If the return value is *NULL*, an exception shall have + been set. If not *NULL*, the return value is interpreted as the return + value of the function as exposed in Python. The function must return a new + reference. .. ctype:: PyMethodDef @@ -117,20 +136,21 @@ .. data:: METH_VARARGS This is the typical calling convention, where the methods have the type - :ctype:`PyCFunction`. The function expects two :ctype:`PyObject\*` values. The - first one is the *self* object for methods; for module functions, it has the - value given to :cfunc:`Py_InitModule4` (or *NULL* if :cfunc:`Py_InitModule` was - used). The second parameter (often called *args*) is a tuple object - representing all arguments. This parameter is typically processed using - :cfunc:`PyArg_ParseTuple` or :cfunc:`PyArg_UnpackTuple`. + :ctype:`PyCFunction`. The function expects two :ctype:`PyObject\*` values. + The first one is the *self* object for methods; for module functions, it + has the value given to :cfunc:`Py_InitModule4` (or *NULL* if + :cfunc:`Py_InitModule` was used). The second parameter (often called + *args*) is a tuple object representing all arguments. This parameter is + typically processed using :cfunc:`PyArg_ParseTuple` or + :cfunc:`PyArg_UnpackTuple`. .. data:: METH_KEYWORDS - Methods with these flags must be of type :ctype:`PyCFunctionWithKeywords`. The - function expects three parameters: *self*, *args*, and a dictionary of all the - keyword arguments. The flag is typically combined with :const:`METH_VARARGS`, - and the parameters are typically processed using + Methods with these flags must be of type :ctype:`PyCFunctionWithKeywords`. + The function expects three parameters: *self*, *args*, and a dictionary of + all the keyword arguments. The flag is typically combined with + :const:`METH_VARARGS`, and the parameters are typically processed using :cfunc:`PyArg_ParseTupleAndKeywords`. @@ -139,8 +159,8 @@ Methods without parameters don't need to check whether arguments are given if they are listed with the :const:`METH_NOARGS` flag. They need to be of type :ctype:`PyCFunction`. When used with object methods, the first parameter is - typically named ``self`` and will hold a reference to the object instance. In - all cases the second parameter will be *NULL*. + typically named ``self`` and will hold a reference to the object instance. + In all cases the second parameter will be *NULL*. .. data:: METH_O @@ -154,11 +174,11 @@ .. data:: METH_OLDARGS This calling convention is deprecated. The method must be of type - :ctype:`PyCFunction`. The second argument is *NULL* if no arguments are given, - a single object if exactly one argument is given, and a tuple of objects if more - than one argument is given. There is no way for a function using this - convention to distinguish between a call with multiple arguments and a call with - a tuple as the only argument. + :ctype:`PyCFunction`. The second argument is *NULL* if no arguments are + given, a single object if exactly one argument is given, and a tuple of + objects if more than one argument is given. There is no way for a function + using this convention to distinguish between a call with multiple arguments + and a call with a tuple as the only argument. These two constants are not used to indicate the calling convention but the binding when use with methods of classes. These may not be used for functions @@ -170,9 +190,10 @@ .. index:: builtin: classmethod - The method will be passed the type object as the first parameter rather than an - instance of the type. This is used to create *class methods*, similar to what - is created when using the :func:`classmethod` built-in function. + The method will be passed the type object as the first parameter rather + than an instance of the type. This is used to create *class methods*, + similar to what is created when using the :func:`classmethod` built-in + function. .. versionadded:: 2.3 @@ -181,9 +202,9 @@ .. index:: builtin: staticmethod - The method will be passed *NULL* as the first parameter rather than an instance - of the type. This is used to create *static methods*, similar to what is - created when using the :func:`staticmethod` built-in function. + The method will be passed *NULL* as the first parameter rather than an + instance of the type. This is used to create *static methods*, similar to + what is created when using the :func:`staticmethod` built-in function. .. versionadded:: 2.3 @@ -195,12 +216,13 @@ The method will be loaded in place of existing definitions. Without *METH_COEXIST*, the default is to skip repeated definitions. Since slot - wrappers are loaded before the method table, the existence of a *sq_contains* - slot, for example, would generate a wrapped method named :meth:`__contains__` - and preclude the loading of a corresponding PyCFunction with the same name. - With the flag defined, the PyCFunction will be loaded in place of the wrapper - object and will co-exist with the slot. This is helpful because calls to - PyCFunctions are optimized more than wrapper object calls. + wrappers are loaded before the method table, the existence of a + *sq_contains* slot, for example, would generate a wrapped method named + :meth:`__contains__` and preclude the loading of a corresponding + PyCFunction with the same name. With the flag defined, the PyCFunction + will be loaded in place of the wrapper object and will co-exist with the + slot. This is helpful because calls to PyCFunctions are optimized more + than wrapper object calls. .. versionadded:: 2.4 @@ -269,6 +291,7 @@ .. cfunction:: PyObject* Py_FindMethod(PyMethodDef table[], PyObject *ob, char *name) - Return a bound method object for an extension type implemented in C. This can - be useful in the implementation of a :attr:`tp_getattro` or :attr:`tp_getattr` - handler that does not use the :cfunc:`PyObject_GenericGetAttr` function. + Return a bound method object for an extension type implemented in C. This + can be useful in the implementation of a :attr:`tp_getattro` or + :attr:`tp_getattr` handler that does not use the + :cfunc:`PyObject_GenericGetAttr` function. Modified: python/branches/release26-maint/Doc/c-api/tuple.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/tuple.rst (original) +++ python/branches/release26-maint/Doc/c-api/tuple.rst Wed Apr 29 10:00:05 2009 @@ -42,6 +42,10 @@ Return a new tuple object of size *len*, or *NULL* on failure. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *len*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyTuple_Pack(Py_ssize_t n, ...) @@ -51,34 +55,58 @@ .. versionadded:: 2.4 + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *n*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PyTuple_Size(PyObject *p) Take a pointer to a tuple object, and return the size of that tuple. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PyTuple_GET_SIZE(PyObject *p) Return the size of the tuple *p*, which must be non-*NULL* and point to a tuple; no error checking is performed. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyTuple_GetItem(PyObject *p, Py_ssize_t pos) Return the object at position *pos* in the tuple pointed to by *p*. If *pos* is out of bounds, return *NULL* and sets an :exc:`IndexError` exception. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *pos*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyTuple_GET_ITEM(PyObject *p, Py_ssize_t pos) Like :cfunc:`PyTuple_GetItem`, but does no checking of its arguments. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *pos*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyTuple_GetSlice(PyObject *p, Py_ssize_t low, Py_ssize_t high) Take a slice of the tuple pointed to by *p* from *low* to *high* and return it as a new tuple. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *low* and *high*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o) @@ -89,6 +117,10 @@ This function "steals" a reference to *o*. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *pos*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: void PyTuple_SET_ITEM(PyObject *p, Py_ssize_t pos, PyObject *o) @@ -99,6 +131,10 @@ This function "steals" a reference to *o*. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *pos*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: int _PyTuple_Resize(PyObject **p, Py_ssize_t newsize) @@ -116,6 +152,10 @@ .. versionchanged:: 2.2 Removed unused third parameter, *last_is_sticky*. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *newsize*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyTuple_ClearFreeList(void) Modified: python/branches/release26-maint/Doc/c-api/type.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/type.rst (original) +++ python/branches/release26-maint/Doc/c-api/type.rst Wed Apr 29 10:00:05 2009 @@ -76,6 +76,10 @@ .. versionadded:: 2.2 + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *nitems*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds) Modified: python/branches/release26-maint/Doc/c-api/typeobj.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/typeobj.rst (original) +++ python/branches/release26-maint/Doc/c-api/typeobj.rst Wed Apr 29 10:00:05 2009 @@ -64,6 +64,10 @@ This field is not inherited by subtypes. + .. versionchanged:: 2.5 + This field used to be an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cmember:: PyTypeObject* PyObject.ob_type Modified: python/branches/release26-maint/Doc/c-api/unicode.rst ============================================================================== --- python/branches/release26-maint/Doc/c-api/unicode.rst (original) +++ python/branches/release26-maint/Doc/c-api/unicode.rst Wed Apr 29 10:00:05 2009 @@ -71,12 +71,20 @@ Return the size of the object. *o* has to be a :ctype:`PyUnicodeObject` (not checked). + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PyUnicode_GET_DATA_SIZE(PyObject *o) Return the size of the object's internal buffer in bytes. *o* has to be a :ctype:`PyUnicodeObject` (not checked). + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: Py_UNICODE* PyUnicode_AS_UNICODE(PyObject *o) @@ -202,6 +210,10 @@ Therefore, modification of the resulting Unicode object is only allowed when *u* is *NULL*. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: Py_UNICODE* PyUnicode_AsUnicode(PyObject *unicode) @@ -213,6 +225,10 @@ Return the length of the Unicode object. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type. This might require changes + in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_FromEncodedObject(PyObject *obj, const char *encoding, const char *errors) @@ -249,6 +265,10 @@ Create a Unicode object from the :ctype:`wchar_t` buffer *w* of the given size. Return *NULL* on failure. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: Py_ssize_t PyUnicode_AsWideChar(PyUnicodeObject *unicode, wchar_t *w, Py_ssize_t size) @@ -260,6 +280,11 @@ to make sure that the :ctype:`wchar_t` string is 0-terminated in case this is required by the application. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type and used an :ctype:`int` + type for *size*. This might require changes in your code for properly + supporting 64-bit systems. + .. _builtincodecs: @@ -299,6 +324,10 @@ using the Python codec registry. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_Encode(const Py_UNICODE *s, Py_ssize_t size, const char *encoding, const char *errors) @@ -308,6 +337,10 @@ looked up using the Python codec registry. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsEncodedString(PyObject *unicode, const char *encoding, const char *errors) @@ -327,6 +360,10 @@ Create a Unicode object by decoding *size* bytes of the UTF-8 encoded string *s*. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_DecodeUTF8Stateful(const char *s, Py_ssize_t size, const char *errors, Py_ssize_t *consumed) @@ -337,12 +374,20 @@ .. versionadded:: 2.4 + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_EncodeUTF8(const Py_UNICODE *s, Py_ssize_t size, const char *errors) Encode the :ctype:`Py_UNICODE` buffer of the given size using UTF-8 and return a Python string object. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsUTF8String(PyObject *unicode) @@ -450,6 +495,10 @@ Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_DecodeUTF16Stateful(const char *s, Py_ssize_t size, const char *errors, int *byteorder, Py_ssize_t *consumed) @@ -461,6 +510,11 @@ .. versionadded:: 2.4 + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size* and an :ctype:`int *` + type for *consumed*. This might require changes in your code for + properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_EncodeUTF16(const Py_UNICODE *s, Py_ssize_t size, const char *errors, int byteorder) @@ -481,6 +535,10 @@ Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsUTF16String(PyObject *unicode) @@ -498,6 +556,10 @@ Create a Unicode object by decoding *size* bytes of the Unicode-Escape encoded string *s*. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size) @@ -505,6 +567,10 @@ return a Python string object. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsUnicodeEscapeString(PyObject *unicode) @@ -522,6 +588,10 @@ Create a Unicode object by decoding *size* bytes of the Raw-Unicode-Escape encoded string *s*. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size, const char *errors) @@ -529,6 +599,10 @@ and return a Python string object. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) @@ -547,12 +621,20 @@ Create a Unicode object by decoding *size* bytes of the Latin-1 encoded string *s*. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_EncodeLatin1(const Py_UNICODE *s, Py_ssize_t size, const char *errors) Encode the :ctype:`Py_UNICODE` buffer of the given size using Latin-1 and return a Python string object. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsLatin1String(PyObject *unicode) @@ -571,12 +653,20 @@ Create a Unicode object by decoding *size* bytes of the ASCII encoded string *s*. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_EncodeASCII(const Py_UNICODE *s, Py_ssize_t size, const char *errors) Encode the :ctype:`Py_UNICODE` buffer of the given size using ASCII and return a Python string object. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsASCIIString(PyObject *unicode) @@ -622,6 +712,10 @@ .. versionchanged:: 2.4 Allowed unicode string as mapping argument. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_EncodeCharmap(const Py_UNICODE *s, Py_ssize_t size, PyObject *mapping, const char *errors) @@ -629,6 +723,10 @@ *mapping* object and return a Python string object. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsCharmapString(PyObject *unicode, PyObject *mapping) @@ -652,6 +750,10 @@ and sequences work well. Unmapped character ordinals (ones which cause a :exc:`LookupError`) are left untouched and are copied as-is. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + These are the MBCS codec APIs. They are currently only available on Windows and use the Win32 MBCS converters to implement the conversions. Note that MBCS (or DBCS) is a class of encodings, not just one. The target encoding is defined by @@ -665,6 +767,10 @@ Create a Unicode object by decoding *size* bytes of the MBCS encoded string *s*. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_DecodeMBCSStateful(const char *s, int size, const char *errors, int *consumed) @@ -681,6 +787,10 @@ Encode the :ctype:`Py_UNICODE` buffer of the given size using MBCS and return a Python string object. Return *NULL* if an exception was raised by the codec. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *size*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_AsMBCSString(PyObject *unicode) @@ -715,6 +825,10 @@ separator. At most *maxsplit* splits will be done. If negative, no limit is set. Separators are not included in the resulting list. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *maxsplit*. This might require + changes in your code for properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_Splitlines(PyObject *s, int keepend) @@ -751,6 +865,11 @@ (*direction* == -1 means to do a prefix match, *direction* == 1 a suffix match), 0 otherwise. Return ``-1`` if an error occurred. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *start* and *end*. This + might require changes in your code for properly supporting 64-bit + systems. + .. cfunction:: Py_ssize_t PyUnicode_Find(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end, int direction) @@ -760,12 +879,22 @@ ``-1`` indicates that no match was found, and ``-2`` indicates that an error occurred and an exception has been set. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *start* and *end*. This + might require changes in your code for properly supporting 64-bit + systems. + .. cfunction:: Py_ssize_t PyUnicode_Count(PyObject *str, PyObject *substr, Py_ssize_t start, Py_ssize_t end) Return the number of non-overlapping occurrences of *substr* in ``str[start:end]``. Return ``-1`` if an error occurred. + .. versionchanged:: 2.5 + This function returned an :ctype:`int` type and used an :ctype:`int` + type for *start* and *end*. This might require changes in your code for + properly supporting 64-bit systems. + .. cfunction:: PyObject* PyUnicode_Replace(PyObject *str, PyObject *substr, PyObject *replstr, Py_ssize_t maxcount) @@ -773,6 +902,10 @@ return the resulting Unicode object. *maxcount* == -1 means replace all occurrences. + .. versionchanged:: 2.5 + This function used an :ctype:`int` type for *maxcount*. This might + require changes in your code for properly supporting 64-bit systems. + .. cfunction:: int PyUnicode_Compare(PyObject *left, PyObject *right) Modified: python/branches/release26-maint/Doc/includes/email-alternative.py ============================================================================== --- python/branches/release26-maint/Doc/includes/email-alternative.py (original) +++ python/branches/release26-maint/Doc/includes/email-alternative.py Wed Apr 29 10:00:05 2009 @@ -45,4 +45,4 @@ # sendmail function takes 3 arguments: sender's address, recipient's address # and message to send - here it is sent as one string. s.sendmail(me, you, msg.as_string()) -s.close() +s.quit() Modified: python/branches/release26-maint/Doc/includes/email-dir.py ============================================================================== --- python/branches/release26-maint/Doc/includes/email-dir.py (original) +++ python/branches/release26-maint/Doc/includes/email-dir.py Wed Apr 29 10:00:05 2009 @@ -106,9 +106,8 @@ fp.close() else: s = smtplib.SMTP() - s.connect() s.sendmail(opts.sender, opts.recipients, composed) - s.close() + s.quit() if __name__ == '__main__': Modified: python/branches/release26-maint/Doc/includes/email-mime.py ============================================================================== --- python/branches/release26-maint/Doc/includes/email-mime.py (original) +++ python/branches/release26-maint/Doc/includes/email-mime.py Wed Apr 29 10:00:05 2009 @@ -27,6 +27,5 @@ # Send the email via our own SMTP server. s = smtplib.SMTP() -s.connect() s.sendmail(me, family, msg.as_string()) -s.close() +s.quit() Modified: python/branches/release26-maint/Doc/includes/email-simple.py ============================================================================== --- python/branches/release26-maint/Doc/includes/email-simple.py (original) +++ python/branches/release26-maint/Doc/includes/email-simple.py Wed Apr 29 10:00:05 2009 @@ -20,6 +20,5 @@ # Send the message via our own SMTP server, but don't include the # envelope header. s = smtplib.SMTP() -s.connect() s.sendmail(me, [you], msg.as_string()) -s.close() +s.quit() From python-checkins at python.org Wed Apr 29 10:03:46 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 29 Apr 2009 10:03:46 +0200 (CEST) Subject: [Python-checkins] r72094 - in python/trunk: Lib/distutils/tests/test_config_cmd.py Misc/NEWS Message-ID: <20090429080346.D23901E4021@bag.python.org> Author: tarek.ziade Date: Wed Apr 29 10:03:46 2009 New Revision: 72094 Log: Fixed #5874 : distutils.tests.test_config_cmd is not locale-sensitive anymore Modified: python/trunk/Lib/distutils/tests/test_config_cmd.py python/trunk/Misc/NEWS Modified: python/trunk/Lib/distutils/tests/test_config_cmd.py ============================================================================== --- python/trunk/Lib/distutils/tests/test_config_cmd.py (original) +++ python/trunk/Lib/distutils/tests/test_config_cmd.py Wed Apr 29 10:03:46 2009 @@ -46,7 +46,7 @@ match = cmd.search_cpp(pattern='xxx', body='// xxx') self.assertEquals(match, 0) - match = cmd.search_cpp(pattern='command', body='// xxx') + match = cmd.search_cpp(pattern='_configtest', body='// xxx') self.assertEquals(match, 1) def test_finalize_options(self): Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Apr 29 10:03:46 2009 @@ -255,6 +255,9 @@ Library ------- +- Issue #5874: distutils.tests.test_config_cmd is not locale-sensitive + anymore. + - Issue #4305: ctypes should now build again on mipsel-linux-gnu - Issue #1734234: Massively speedup ``unicodedata.normalize()`` when the From python-checkins at python.org Wed Apr 29 10:05:28 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 29 Apr 2009 10:05:28 +0200 (CEST) Subject: [Python-checkins] r72095 - python/branches/release26-maint Message-ID: <20090429080528.E49781E4058@bag.python.org> Author: tarek.ziade Date: Wed Apr 29 10:05:28 2009 New Revision: 72095 Log: Blocked revisions 72094 via svnmerge ........ r72094 | tarek.ziade | 2009-04-29 10:03:46 +0200 (Wed, 29 Apr 2009) | 1 line Fixed #5874 : distutils.tests.test_config_cmd is not locale-sensitive anymore ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Wed Apr 29 10:07:45 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 29 Apr 2009 10:07:45 +0200 (CEST) Subject: [Python-checkins] r72096 - in python/branches/py3k: Lib/distutils/tests/test_config_cmd.py Misc/NEWS Message-ID: <20090429080745.033BE1E4016@bag.python.org> Author: tarek.ziade Date: Wed Apr 29 10:07:44 2009 New Revision: 72096 Log: Merged revisions 72094 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72094 | tarek.ziade | 2009-04-29 10:03:46 +0200 (Wed, 29 Apr 2009) | 1 line Fixed #5874 : distutils.tests.test_config_cmd is not locale-sensitive anymore ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/distutils/tests/test_config_cmd.py python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/distutils/tests/test_config_cmd.py ============================================================================== --- python/branches/py3k/Lib/distutils/tests/test_config_cmd.py (original) +++ python/branches/py3k/Lib/distutils/tests/test_config_cmd.py Wed Apr 29 10:07:44 2009 @@ -46,7 +46,7 @@ match = cmd.search_cpp(pattern='xxx', body='// xxx') self.assertEquals(match, 0) - match = cmd.search_cpp(pattern='command', body='// xxx') + match = cmd.search_cpp(pattern='_configtest', body='// xxx') self.assertEquals(match, 1) def test_finalize_options(self): Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Apr 29 10:07:44 2009 @@ -473,6 +473,9 @@ Library ------- +- Issue #5874: distutils.tests.test_config_cmd is not locale-sensitive + anymore. + - Issue #5810: Fixed Distutils test_build_scripts so it uses sysconfig.get_config_vars. From python-checkins at python.org Wed Apr 29 10:08:42 2009 From: python-checkins at python.org (tarek.ziade) Date: Wed, 29 Apr 2009 10:08:42 +0200 (CEST) Subject: [Python-checkins] r72097 - python/branches/release30-maint Message-ID: <20090429080842.4AD591E4016@bag.python.org> Author: tarek.ziade Date: Wed Apr 29 10:08:41 2009 New Revision: 72097 Log: Blocked revisions 72096 via svnmerge ................ r72096 | tarek.ziade | 2009-04-29 10:07:44 +0200 (Wed, 29 Apr 2009) | 9 lines Merged revisions 72094 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72094 | tarek.ziade | 2009-04-29 10:03:46 +0200 (Wed, 29 Apr 2009) | 1 line Fixed #5874 : distutils.tests.test_config_cmd is not locale-sensitive anymore ........ ................ Modified: python/branches/release30-maint/ (props changed) From buildbot at python.org Wed Apr 29 10:43:44 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 29 Apr 2009 08:43:44 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu trunk Message-ID: <20090429084345.1DE5F1E4016@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%20trunk/builds/1204 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: georg.brandl,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_os test_time make: *** [buildbottest] Error 1 sincerely, -The Buildbot From dickinsm at gmail.com Wed Apr 29 11:33:36 2009 From: dickinsm at gmail.com (Mark Dickinson) Date: Wed, 29 Apr 2009 10:33:36 +0100 Subject: [Python-checkins] r72086 - in python/branches/py3k: Doc/library/tokenize.rst Lib/tokenize.py In-Reply-To: <20090429003427.96A301E4018@bag.python.org> References: <20090429003427.96A301E4018@bag.python.org> Message-ID: <5c6f2a5d0904290233o1d98a218j671c0866377e421c@mail.gmail.com> On Wed, Apr 29, 2009 at 1:34 AM, raymond.hettinger wrote: > Modified: python/branches/py3k/Lib/tokenize.py > ============================================================================== > --- python/branches/py3k/Lib/tokenize.py ? ? ? ?(original) > +++ python/branches/py3k/Lib/tokenize.py ? ? ? ?Wed Apr 29 02:34:27 2009 > @@ -24,6 +24,7 @@ > ? ? ? ? ? ? ? ?'Skip Montanaro, Raymond Hettinger, Trent Nelson, ' > ? ? ? ? ? ? ? ?'Michael Foord') > > +import collections This import seems to be causing a circular dependency in the build process. On Linux, after doing a make distclean && ./configure && make the build fails with: [...] ar cr libpython3.1.a Modules/_threadmodule.o Modules/signalmodule.o Modules/posixmodule.o Modules/errnomodule.o Modules/pwdmodule.o Modules/_sre.o Modules/_codecsmodule.o Modules/_weakref.o Modules/_iomodule.o Modules/iobase.o Modules/fileio.o Modules/bytesio.o Modules/bufferedio.o Modules/textio.o Modules/stringio.o Modules/zipimport.o Modules/symtablemodule.o Modules/xxsubtype.o ranlib libpython3.1.a gcc -pthread -Xlinker -export-dynamic -o python \ Modules/python.o \ libpython3.1.a -lpthread -ldl -lutil -lm Traceback (most recent call last): File "./setup.py", line 1660, in main() File "./setup.py", line 1634, in main import warnings File "/home/dickinsm/svn/python/py3k/Lib/warnings.py", line 6, in import linecache File "/home/dickinsm/svn/python/py3k/Lib/linecache.py", line 10, in import tokenize File "/home/dickinsm/svn/python/py3k/Lib/tokenize.py", line 27, in import collections File "/home/dickinsm/svn/python/py3k/Lib/collections.py", line 9, in from _collections import deque, defaultdict ImportError: No module named _collections make: *** [sharedmods] Error 1 ...presumably because the collections module hasn't been built yet. From nnorwitz at gmail.com Wed Apr 29 12:14:37 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 29 Apr 2009 06:14:37 -0400 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20090429101437.GA28893@python.psfb.org> More important issues: ---------------------- test_pydoc leaked [-21, 0, 0] references, sum=-21 Less important issues: ---------------------- test_file leaked [0, 80, -11] references, sum=69 test_popen2 leaked [0, 0, 29] references, sum=29 test_smtplib leaked [0, 0, 180] references, sum=180 test_ssl leaked [0, -403, 403] references, sum=0 test_threading leaked [48, 48, 48] references, sum=144 test_urllib2_localnet leaked [-266, 272, -266] references, sum=-260 From buildbot at python.org Wed Apr 29 12:57:32 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 29 Apr 2009 10:57:32 +0000 Subject: [Python-checkins] buildbot failure in x86 XP-4 2.6 Message-ID: <20090429105732.EEE071E4013@bag.python.org> The Buildbot has detected a new failure of x86 XP-4 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20XP-4%202.6/builds/231 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: bolen-windows Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: jeroen.ruigrok BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_bsddb3 ====================================================================== ERROR: test01_badpointer (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 21, in test01_badpointer dbs = dbshelve.open(self.filename) File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\dbshelve.py", line 106, in open d.open(filename, dbname, filetype, flags, mode) File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\dbshelve.py", line 171, in open self.db.open(*args, **kwargs) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test03_repr_closed_db (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 37, in test03_repr_closed_db db = hashopen(self.filename) File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\__init__.py", line 361, in hashopen d.open(file, db.DB_HASH, flags, mode) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test04_repr_db (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 43, in test04_repr_db db = hashopen(self.filename) File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\__init__.py", line 361, in hashopen d.open(file, db.DB_HASH, flags, mode) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test05_double_free_make_key_dbt (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 65, in test05_double_free_make_key_dbt db.DB_CREATE | db.DB_THREAD) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test06_key_with_null_bytes (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 77, in test06_key_with_null_bytes db1.open(self.filename, None, db.DB_HASH, db.DB_CREATE) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test07_DB_set_flags_persists (bsddb.test.test_misc.MiscTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\2.6.bolen-windows\build\lib\bsddb\test\test_misc.py", line 101, in test07_DB_set_flags_persists db1.open(self.filename, db.DB_HASH, db.DB_CREATE) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') sincerely, -The Buildbot From eric at trueblade.com Wed Apr 29 13:27:10 2009 From: eric at trueblade.com (Eric Smith) Date: Wed, 29 Apr 2009 07:27:10 -0400 Subject: [Python-checkins] r72086 - in python/branches/py3k: Doc/library/tokenize.rst Lib/tokenize.py In-Reply-To: <5c6f2a5d0904290233o1d98a218j671c0866377e421c@mail.gmail.com> References: <20090429003427.96A301E4018@bag.python.org> <5c6f2a5d0904290233o1d98a218j671c0866377e421c@mail.gmail.com> Message-ID: <49F8398E.3030303@trueblade.com> Mark Dickinson wrote: > On Wed, Apr 29, 2009 at 1:34 AM, raymond.hettinger > wrote: > >> Modified: python/branches/py3k/Lib/tokenize.py >> ============================================================================== >> --- python/branches/py3k/Lib/tokenize.py (original) >> +++ python/branches/py3k/Lib/tokenize.py Wed Apr 29 02:34:27 2009 >> @@ -24,6 +24,7 @@ >> 'Skip Montanaro, Raymond Hettinger, Trent Nelson, ' >> 'Michael Foord') >> >> +import collections > > This import seems to be causing a circular dependency in > the build process. On Linux, after doing a > > make distclean && ./configure && make > > the build fails with: Same error on MacOS. From python-checkins at python.org Wed Apr 29 14:34:19 2009 From: python-checkins at python.org (eric.smith) Date: Wed, 29 Apr 2009 14:34:19 +0200 (CEST) Subject: [Python-checkins] r72098 - python/branches/py3k/Lib/test/test_ascii_formatd.py Message-ID: <20090429123419.C6E1A1E4013@bag.python.org> Author: eric.smith Date: Wed Apr 29 14:34:19 2009 New Revision: 72098 Log: Added test that didn't make it in an svnmerge. Added: python/branches/py3k/Lib/test/test_ascii_formatd.py Added: python/branches/py3k/Lib/test/test_ascii_formatd.py ============================================================================== --- (empty file) +++ python/branches/py3k/Lib/test/test_ascii_formatd.py Wed Apr 29 14:34:19 2009 @@ -0,0 +1,62 @@ +# PyOS_ascii_formatd is deprecated and not called from anywhere in +# Python itself. So this module is the only place it gets tested. +# Test that it works, and test that it's deprecated. + +import unittest +from test.support import check_warnings, run_unittest, cpython_only + +class FormatDeprecationTests(unittest.TestCase): + + @cpython_only + def testFormatDeprecation(self): + # delay importing ctypes until we know we're in CPython + from ctypes import (pythonapi, create_string_buffer, sizeof, byref, + c_double) + PyOS_ascii_formatd = pythonapi.PyOS_ascii_formatd + buf = create_string_buffer(100) + + with check_warnings() as w: + PyOS_ascii_formatd(byref(buf), sizeof(buf), b'%+.10f', + c_double(10.0)) + self.assertEqual(buf.value, b'+10.0000000000') + + self.assertEqual(str(w.message), 'PyOS_ascii_formatd is deprecated, ' + 'use PyOS_double_to_string instead') + +class FormatTests(unittest.TestCase): + # ensure that, for the restricted set of format codes, + # %-formatting returns the same values os PyOS_ascii_formatd + @cpython_only + def testFormat(self): + # delay importing ctypes until we know we're in CPython + from ctypes import (pythonapi, create_string_buffer, sizeof, byref, + c_double) + PyOS_ascii_formatd = pythonapi.PyOS_ascii_formatd + buf = create_string_buffer(100) + + tests = [ + ('%f', 100.0), + ('%g', 100.0), + ('%#g', 100.0), + ('%#.2g', 100.0), + ('%#.2g', 123.4567), + ('%#.2g', 1.234567e200), + ('%e', 1.234567e200), + ('%e', 1.234), + ('%+e', 1.234), + ('%-e', 1.234), + ] + + with check_warnings(): + for format, val in tests: + PyOS_ascii_formatd(byref(buf), sizeof(buf), + bytes(format, 'ascii'), + c_double(val)) + self.assertEqual(buf.value, bytes(format % val, 'ascii')) + + +def test_main(): + run_unittest(FormatDeprecationTests, FormatTests) + +if __name__ == '__main__': + test_main() From python-checkins at python.org Wed Apr 29 14:38:15 2009 From: python-checkins at python.org (eric.smith) Date: Wed, 29 Apr 2009 14:38:15 +0200 (CEST) Subject: [Python-checkins] r72099 - python/branches/release30-maint Message-ID: <20090429123815.B51951E4013@bag.python.org> Author: eric.smith Date: Wed Apr 29 14:38:15 2009 New Revision: 72099 Log: Blocked revisions 72098 via svnmerge ........ r72098 | eric.smith | 2009-04-29 08:34:19 -0400 (Wed, 29 Apr 2009) | 1 line Added test that didn't make it in an svnmerge. ........ Modified: python/branches/release30-maint/ (props changed) From buildbot at python.org Wed Apr 29 14:56:01 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 29 Apr 2009 12:56:01 +0000 Subject: [Python-checkins] buildbot failure in x86 XP-4 3.x Message-ID: <20090429125601.5FC421E41F7@bag.python.org> The Buildbot has detected a new failure of x86 XP-4 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20XP-4%203.x/builds/513 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: bolen-windows Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: georg.brandl,tarek.ziade BUILD FAILED: failed test Excerpt from the test logfile: 3 tests failed: test___all__ test__locale test_cprofile ====================================================================== ERROR: test_all (test.test___all__.AllTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\test\test___all__.py", line 135, in test_all self.check_all("tokenize") File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\test\test___all__.py", line 23, in check_all exec("from %s import *" % modname, names) File "", line 1, in AttributeError: 'module' object has no attribute 'Tokenize' Traceback (most recent call last): File "../lib/test/regrtest.py", line 613, in runtest_inner the_package = __import__(abstest, globals(), locals(), []) File "E:\cygwin\home\db3l\buildarea\3.x.bolen-windows\build\lib\test\test__locale.py", line 2, in from _locale import (setlocale, LC_ALL, LC_CTYPE, LC_NUMERIC, RADIXCHAR, THOUSEP, nl_langinfo, ImportError: cannot import name RADIXCHAR sincerely, -The Buildbot From python-checkins at python.org Wed Apr 29 15:17:38 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 29 Apr 2009 15:17:38 +0200 (CEST) Subject: [Python-checkins] r72100 - in python/trunk: Lib/aifc.py Lib/test/Sine-1000Hz-300ms.aif Lib/test/test_aifc.py Lib/test/test_sundry.py Misc/ACKS Misc/NEWS Message-ID: <20090429131738.75FD31E4013@bag.python.org> Author: r.david.murray Date: Wed Apr 29 15:17:37 2009 New Revision: 72100 Log: Fix issue 2245. aifc now skips any chunk type it doesn't actually process instead of throwing errors for anything not in an explicit skip list. This is per this spec: http://www.cnpbagwell.com/aiff-c.txt. Spec reference and test sound file provided by Santiago Peres??n, fix based on patch by Hiroaki Kawai. Added: python/trunk/Lib/test/Sine-1000Hz-300ms.aif (contents, props changed) python/trunk/Lib/test/test_aifc.py Modified: python/trunk/Lib/aifc.py python/trunk/Lib/test/test_sundry.py python/trunk/Misc/ACKS python/trunk/Misc/NEWS Modified: python/trunk/Lib/aifc.py ============================================================================== --- python/trunk/Lib/aifc.py (original) +++ python/trunk/Lib/aifc.py Wed Apr 29 15:17:37 2009 @@ -144,9 +144,6 @@ _AIFC_version = 0xA2805140L # Version 1 of AIFF-C -_skiplist = 'COMT', 'INST', 'MIDI', 'AESD', \ - 'APPL', 'NAME', 'AUTH', '(c) ', 'ANNO' - def _read_long(file): try: return struct.unpack('>l', file.read(4))[0] @@ -314,10 +311,6 @@ self._version = _read_ulong(chunk) elif chunkname == 'MARK': self._readmark(chunk) - elif chunkname in _skiplist: - pass - else: - raise Error, 'unrecognized chunk type '+chunk.chunkname chunk.skip() if not self._comm_chunk_read or not self._ssnd_chunk: raise Error, 'COMM chunk and/or SSND chunk missing' Added: python/trunk/Lib/test/Sine-1000Hz-300ms.aif ============================================================================== Binary file. No diff available. Added: python/trunk/Lib/test/test_aifc.py ============================================================================== --- (empty file) +++ python/trunk/Lib/test/test_aifc.py Wed Apr 29 15:17:37 2009 @@ -0,0 +1,24 @@ +from test.test_support import findfile, run_unittest +import unittest + +import aifc + + +class AIFCTest(unittest.TestCase): + + def setUp(self): + self.sndfilepath = findfile('Sine-1000Hz-300ms.aif') + + def test_skipunknown(self): + #Issue 2245 + #This file contains chunk types aifc doesn't recognize. + f = aifc.open(self.sndfilepath) + f.close() + + +def test_main(): + run_unittest(AIFCTest) + + +if __name__ == "__main__": + unittest.main() Modified: python/trunk/Lib/test/test_sundry.py ============================================================================== --- python/trunk/Lib/test/test_sundry.py (original) +++ python/trunk/Lib/test/test_sundry.py Wed Apr 29 15:17:37 2009 @@ -11,7 +11,6 @@ with warnings.catch_warnings(): warnings.simplefilter("ignore") import CGIHTTPServer - import aifc import audiodev import bdb import cgitb Modified: python/trunk/Misc/ACKS ============================================================================== --- python/trunk/Misc/ACKS (original) +++ python/trunk/Misc/ACKS Wed Apr 29 15:17:37 2009 @@ -370,6 +370,7 @@ Peter van Kampen Jacob Kaplan-Moss Lou Kates +Hiroaki Kawai Sebastien Keim Robert Kern Randall Kern @@ -541,6 +542,7 @@ Samuele Pedroni Marcel van der Peijl Steven Pemberton +Santiago Peres?n Mark Perrego Trevor Perrin Tim Peters Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Apr 29 15:17:37 2009 @@ -255,6 +255,8 @@ Library ------- +- Issue #2245: aifc now skips chunk types it doesn't recognize, per spec. + - Issue #5874: distutils.tests.test_config_cmd is not locale-sensitive anymore. From buildbot at python.org Wed Apr 29 15:36:39 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 29 Apr 2009 13:36:39 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.0 Message-ID: <20090429133640.2610F1E4027@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.0/builds/321 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: eric.smith BUILD FAILED: failed failed slave lost sincerely, -The Buildbot From buildbot at python.org Wed Apr 29 15:43:18 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 29 Apr 2009 13:43:18 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo trunk Message-ID: <20090429134318.DB7A41E403E@bag.python.org> The Buildbot has detected a new failure of x86 gentoo trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%20trunk/builds/4895 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_os ====================================================================== FAIL: test_update2 (test.test_os.EnvironTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildslave/python-trunk/trunk.norwitz-x86/build/Lib/test/test_os.py", line 348, in test_update2 self.assertEquals(value, "World") AssertionError: '' != 'World' make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Wed Apr 29 15:51:45 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 29 Apr 2009 15:51:45 +0200 (CEST) Subject: [Python-checkins] r72101 - python/trunk/Lib/test/test_aifc.py Message-ID: <20090429135145.4789B1E4028@bag.python.org> Author: r.david.murray Date: Wed Apr 29 15:51:44 2009 New Revision: 72101 Log: Now that we've got a test_aifc, add a few tests. Modified: python/trunk/Lib/test/test_aifc.py Modified: python/trunk/Lib/test/test_aifc.py ============================================================================== --- python/trunk/Lib/test/test_aifc.py (original) +++ python/trunk/Lib/test/test_aifc.py Wed Apr 29 15:51:44 2009 @@ -15,6 +15,36 @@ f = aifc.open(self.sndfilepath) f.close() + def test_params(self): + f = aifc.open(self.sndfilepath) + self.assertEqual(f.getnchannels(), 2) + self.assertEqual(f.getsampwidth(), 2) + self.assertEqual(f.getframerate(), 48000) + self.assertEqual(f.getnframes(), 14400) + self.assertEqual(f.getcomptype(), 'NONE') + self.assertEqual(f.getcompname(), 'not compressed') + self.assertEqual(f.getparams(), (2, 2, 48000, 14400, 'NONE', 'not compressed')) + f.close() + + def test_read(self): + f = aifc.open(self.sndfilepath) + self.assertEqual(f.tell(), 0) + self.assertEqual(f.readframes(2), '\x00\x00\x00\x00\x0b\xd4\x0b\xd4') + f.rewind() + pos0 = f.tell() + self.assertEqual(pos0, 0) + self.assertEqual(f.readframes(2), '\x00\x00\x00\x00\x0b\xd4\x0b\xd4') + pos2 = f.tell() + self.assertEqual(pos2, 2) + self.assertEqual(f.readframes(2), '\x17t\x17t"\xad"\xad') + f.setpos(pos2) + self.assertEqual(f.readframes(2), '\x17t\x17t"\xad"\xad') + f.setpos(pos0) + self.assertEqual(f.readframes(2), '\x00\x00\x00\x00\x0b\xd4\x0b\xd4') + f.close() + + #XXX Need more tests! + def test_main(): run_unittest(AIFCTest) From buildbot at python.org Wed Apr 29 15:52:06 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 29 Apr 2009 13:52:06 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090429135207.12C8C1E4028@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/314 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: eric.smith BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_posix test_subprocess ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From buildbot at python.org Wed Apr 29 16:06:39 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 29 Apr 2009 14:06:39 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable trunk Message-ID: <20090429140639.AD6B51E404E@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%20trunk/builds/431 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/threading.py", line 524, in __bootstrap_inner self.run() File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/threading.py", line 477, in run self.__target(*self.__args, **self.__kwargs) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/bsddb/test/test_thread.py", line 306, in readerThread rec = dbutils.DeadlockWrap(c.next, max_retries=10) File "/home/pybot/buildarea/trunk.klose-debian-ppc/build/Lib/bsddb/dbutils.py", line 68, in DeadlockWrap return function(*_args, **_kwargs) DBLockDeadlockError: (-30994, 'DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock') 1 test failed: test_time make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Wed Apr 29 16:21:25 2009 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 29 Apr 2009 16:21:25 +0200 (CEST) Subject: [Python-checkins] r72102 - python/branches/py3k/Lib/tokenize.py Message-ID: <20090429142125.AC5D01E402A@bag.python.org> Author: raymond.hettinger Date: Wed Apr 29 16:21:25 2009 New Revision: 72102 Log: Remove dependency on the collections module. Modified: python/branches/py3k/Lib/tokenize.py Modified: python/branches/py3k/Lib/tokenize.py ============================================================================== --- python/branches/py3k/Lib/tokenize.py (original) +++ python/branches/py3k/Lib/tokenize.py Wed Apr 29 16:21:25 2009 @@ -24,7 +24,6 @@ 'Skip Montanaro, Raymond Hettinger, Trent Nelson, ' 'Michael Foord') -import collections import re, string, sys from token import * from codecs import lookup, BOM_UTF8 @@ -32,7 +31,7 @@ import token __all__ = [x for x in dir(token) if x[0] != '_'] + ["COMMENT", "tokenize", - "detect_encoding", "NL", "untokenize", "ENCODING", "Tokenize"] + "detect_encoding", "NL", "untokenize", "ENCODING", "TokenInfo"] del token COMMENT = N_TOKENS @@ -43,7 +42,46 @@ tok_name[ENCODING] = 'ENCODING' N_TOKENS += 3 -TokenInfo = collections.namedtuple('TokenInfo', 'type string start end line') +class TokenInfo(tuple): + 'TokenInfo(type, string, start, end, line)' + + __slots__ = () + + _fields = ('type', 'string', 'start', 'end', 'line') + + def __new__(cls, type, string, start, end, line): + return tuple.__new__(cls, (type, string, start, end, line)) + + @classmethod + def _make(cls, iterable, new=tuple.__new__, len=len): + 'Make a new TokenInfo object from a sequence or iterable' + result = new(cls, iterable) + if len(result) != 5: + raise TypeError('Expected 5 arguments, got %d' % len(result)) + return result + + def __repr__(self): + return 'TokenInfo(type=%r, string=%r, start=%r, end=%r, line=%r)' % self + + def _asdict(self): + 'Return a new dict which maps field names to their values' + return dict(zip(self._fields, self)) + + def _replace(self, **kwds): + 'Return a new TokenInfo object replacing specified fields with new values' + result = self._make(map(kwds.pop, ('type', 'string', 'start', 'end', 'line'), self)) + if kwds: + raise ValueError('Got unexpected field names: %r' % kwds.keys()) + return result + + def __getnewargs__(self): + return tuple(self) + + type = property(lambda t: t[0]) + string = property(lambda t: t[1]) + start = property(lambda t: t[2]) + end = property(lambda t: t[3]) + line = property(lambda t: t[4]) def group(*choices): return '(' + '|'.join(choices) + ')' def any(*choices): return group(*choices) + '*' From buildbot at python.org Wed Apr 29 16:49:47 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 29 Apr 2009 14:49:47 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc trunk Message-ID: <20090429144947.58CAD1E4029@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc trunk. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%20trunk/builds/346 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_os sincerely, -The Buildbot From python-checkins at python.org Wed Apr 29 16:54:29 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 29 Apr 2009 16:54:29 +0200 (CEST) Subject: [Python-checkins] r72103 - in python/branches/release26-maint: Lib/aifc.py Lib/test/Sine-1000Hz-300ms.aif Lib/test/test_aifc.py Lib/test/test_sundry.py Misc/ACKS Misc/NEWS Message-ID: <20090429145429.8ECEF1E4011@bag.python.org> Author: r.david.murray Date: Wed Apr 29 16:54:29 2009 New Revision: 72103 Log: Merged revisions 72100-72101 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72100 | r.david.murray | 2009-04-29 09:17:37 -0400 (Wed, 29 Apr 2009) | 7 lines Fix issue 2245. aifc now skips any chunk type it doesn't actually process instead of throwing errors for anything not in an explicit skip list. This is per this spec: http://www.cnpbagwell.com/aiff-c.txt. Spec reference and test sound file provided by Santiago Peres??n, fix based on patch by Hiroaki Kawai. ........ r72101 | r.david.murray | 2009-04-29 09:51:44 -0400 (Wed, 29 Apr 2009) | 2 lines Now that we've got a test_aifc, add a few tests. ........ Added: python/branches/release26-maint/Lib/test/Sine-1000Hz-300ms.aif - copied unchanged from r72101, /python/trunk/Lib/test/Sine-1000Hz-300ms.aif python/branches/release26-maint/Lib/test/test_aifc.py - copied unchanged from r72101, /python/trunk/Lib/test/test_aifc.py Modified: python/branches/release26-maint/ (props changed) python/branches/release26-maint/Lib/aifc.py python/branches/release26-maint/Lib/test/test_sundry.py python/branches/release26-maint/Misc/ACKS python/branches/release26-maint/Misc/NEWS Modified: python/branches/release26-maint/Lib/aifc.py ============================================================================== --- python/branches/release26-maint/Lib/aifc.py (original) +++ python/branches/release26-maint/Lib/aifc.py Wed Apr 29 16:54:29 2009 @@ -144,9 +144,6 @@ _AIFC_version = 0xA2805140L # Version 1 of AIFF-C -_skiplist = 'COMT', 'INST', 'MIDI', 'AESD', \ - 'APPL', 'NAME', 'AUTH', '(c) ', 'ANNO' - def _read_long(file): try: return struct.unpack('>l', file.read(4))[0] @@ -314,10 +311,6 @@ self._version = _read_ulong(chunk) elif chunkname == 'MARK': self._readmark(chunk) - elif chunkname in _skiplist: - pass - else: - raise Error, 'unrecognized chunk type '+chunk.chunkname chunk.skip() if not self._comm_chunk_read or not self._ssnd_chunk: raise Error, 'COMM chunk and/or SSND chunk missing' Modified: python/branches/release26-maint/Lib/test/test_sundry.py ============================================================================== --- python/branches/release26-maint/Lib/test/test_sundry.py (original) +++ python/branches/release26-maint/Lib/test/test_sundry.py Wed Apr 29 16:54:29 2009 @@ -10,7 +10,6 @@ def test_at_least_import_untested_modules(self): with warnings.catch_warnings(): import CGIHTTPServer - import aifc import audiodev import bdb import cgitb Modified: python/branches/release26-maint/Misc/ACKS ============================================================================== --- python/branches/release26-maint/Misc/ACKS (original) +++ python/branches/release26-maint/Misc/ACKS Wed Apr 29 16:54:29 2009 @@ -362,6 +362,7 @@ Peter van Kampen Jacob Kaplan-Moss Lou Kates +Hiroaki Kawai Sebastien Keim Robert Kern Randall Kern @@ -527,6 +528,7 @@ Samuele Pedroni Marcel van der Peijl Steven Pemberton +Santiago Peres?n Mark Perrego Trevor Perrin Tim Peters Modified: python/branches/release26-maint/Misc/NEWS ============================================================================== --- python/branches/release26-maint/Misc/NEWS (original) +++ python/branches/release26-maint/Misc/NEWS Wed Apr 29 16:54:29 2009 @@ -27,6 +27,8 @@ Library ------- +- Issue #2245: aifc now skips chunk types it doesn't recognize, per spec. + - Issue #4305: ctypes should now build again on mipsel-linux-gnu - Issue #5853: calling a function of the mimetypes module from several threads From buildbot at python.org Wed Apr 29 17:08:40 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 29 Apr 2009 15:08:40 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu trunk Message-ID: <20090429150840.EB05D1E4011@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%20trunk/builds/1295 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/threading.py", line 524, in __bootstrap_inner self.run() File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/threading.py", line 477, in run self.__target(*self.__args, **self.__kwargs) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/bsddb/test/test_thread.py", line 306, in readerThread rec = dbutils.DeadlockWrap(c.next, max_retries=10) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/bsddb/dbutils.py", line 68, in DeadlockWrap return function(*_args, **_kwargs) DBLockDeadlockError: (-30994, 'DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock') 1 test failed: test_shelve ====================================================================== ERROR: test_update (test.test_shelve.TestAsciiFileShelve) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/mapping_tests.py", line 179, in test_update self.assertEqual(d, self._empty_mapping()) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/test_shelve.py", line 108, in _empty_mapping x= shelve.open(self.fn+str(self.counter), **self._args) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/shelve.py", line 234, in open return DbfilenameShelf(filename, flag, protocol, writeback) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/shelve.py", line 218, in __init__ Shelf.__init__(self, anydbm.open(filename, flag), protocol, writeback) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/anydbm.py", line 83, in open return mod.open(file, flag, mode) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/dbhash.py", line 19, in open return bsddb.hashopen(file, flag, mode) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/bsddb/__init__.py", line 361, in hashopen d.open(file, db.DB_HASH, flags, mode) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test_write (test.test_shelve.TestAsciiFileShelve) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/mapping_tests.py", line 104, in test_write p = self._empty_mapping() File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/test_shelve.py", line 108, in _empty_mapping x= shelve.open(self.fn+str(self.counter), **self._args) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/shelve.py", line 234, in open return DbfilenameShelf(filename, flag, protocol, writeback) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/shelve.py", line 218, in __init__ Shelf.__init__(self, anydbm.open(filename, flag), protocol, writeback) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/anydbm.py", line 83, in open return mod.open(file, flag, mode) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/dbhash.py", line 19, in open return bsddb.hashopen(file, flag, mode) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/bsddb/__init__.py", line 361, in hashopen d.open(file, db.DB_HASH, flags, mode) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test_update (test.test_shelve.TestBinaryFileShelve) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/mapping_tests.py", line 179, in test_update self.assertEqual(d, self._empty_mapping()) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/test_shelve.py", line 108, in _empty_mapping x= shelve.open(self.fn+str(self.counter), **self._args) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/shelve.py", line 234, in open return DbfilenameShelf(filename, flag, protocol, writeback) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/shelve.py", line 218, in __init__ Shelf.__init__(self, anydbm.open(filename, flag), protocol, writeback) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/anydbm.py", line 83, in open return mod.open(file, flag, mode) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/dbhash.py", line 19, in open return bsddb.hashopen(file, flag, mode) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/bsddb/__init__.py", line 361, in hashopen d.open(file, db.DB_HASH, flags, mode) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test_write (test.test_shelve.TestBinaryFileShelve) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/mapping_tests.py", line 104, in test_write p = self._empty_mapping() File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/test_shelve.py", line 108, in _empty_mapping x= shelve.open(self.fn+str(self.counter), **self._args) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/shelve.py", line 234, in open return DbfilenameShelf(filename, flag, protocol, writeback) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/shelve.py", line 218, in __init__ Shelf.__init__(self, anydbm.open(filename, flag), protocol, writeback) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/anydbm.py", line 83, in open return mod.open(file, flag, mode) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/dbhash.py", line 19, in open return bsddb.hashopen(file, flag, mode) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/bsddb/__init__.py", line 361, in hashopen d.open(file, db.DB_HASH, flags, mode) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test_update (test.test_shelve.TestProto2FileShelve) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/mapping_tests.py", line 179, in test_update self.assertEqual(d, self._empty_mapping()) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/test_shelve.py", line 108, in _empty_mapping x= shelve.open(self.fn+str(self.counter), **self._args) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/shelve.py", line 234, in open return DbfilenameShelf(filename, flag, protocol, writeback) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/shelve.py", line 218, in __init__ Shelf.__init__(self, anydbm.open(filename, flag), protocol, writeback) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/anydbm.py", line 83, in open return mod.open(file, flag, mode) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/dbhash.py", line 19, in open return bsddb.hashopen(file, flag, mode) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/bsddb/__init__.py", line 361, in hashopen d.open(file, db.DB_HASH, flags, mode) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') ====================================================================== ERROR: test_write (test.test_shelve.TestProto2FileShelve) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/mapping_tests.py", line 104, in test_write p = self._empty_mapping() File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/test/test_shelve.py", line 108, in _empty_mapping x= shelve.open(self.fn+str(self.counter), **self._args) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/shelve.py", line 234, in open return DbfilenameShelf(filename, flag, protocol, writeback) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/shelve.py", line 218, in __init__ Shelf.__init__(self, anydbm.open(filename, flag), protocol, writeback) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/anydbm.py", line 83, in open return mod.open(file, flag, mode) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/dbhash.py", line 19, in open return bsddb.hashopen(file, flag, mode) File "/home/pybot/buildarea/trunk.klose-debian-ia64/build/Lib/bsddb/__init__.py", line 361, in hashopen d.open(file, db.DB_HASH, flags, mode) DBFileExistsError: (17, 'File exists -- __fop_file_setup: Retry limit (100) exceeded') make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Wed Apr 29 17:34:32 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 29 Apr 2009 17:34:32 +0200 (CEST) Subject: [Python-checkins] r72104 - in python/branches/py3k: Lib/aifc.py Lib/test/Sine-1000Hz-300ms.aif Lib/test/test_aifc.py Lib/test/test_sundry.py Misc/ACKS Misc/NEWS Message-ID: <20090429153432.D2B801E4016@bag.python.org> Author: r.david.murray Date: Wed Apr 29 17:34:32 2009 New Revision: 72104 Log: Merged revisions 72100-72101 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72100 | r.david.murray | 2009-04-29 09:17:37 -0400 (Wed, 29 Apr 2009) | 7 lines Fix issue 2245. aifc now skips any chunk type it doesn't actually process instead of throwing errors for anything not in an explicit skip list. This is per this spec: http://www.cnpbagwell.com/aiff-c.txt. Spec reference and test sound file provided by Santiago Peres??n, fix based on patch by Hiroaki Kawai. ........ r72101 | r.david.murray | 2009-04-29 09:51:44 -0400 (Wed, 29 Apr 2009) | 2 lines Now that we've got a test_aifc, add a few tests. ........ Added: python/branches/py3k/Lib/test/Sine-1000Hz-300ms.aif - copied unchanged from r72101, /python/trunk/Lib/test/Sine-1000Hz-300ms.aif python/branches/py3k/Lib/test/test_aifc.py - copied, changed from r72101, /python/trunk/Lib/test/test_aifc.py Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/aifc.py python/branches/py3k/Lib/test/test_sundry.py python/branches/py3k/Misc/ACKS python/branches/py3k/Misc/NEWS Modified: python/branches/py3k/Lib/aifc.py ============================================================================== --- python/branches/py3k/Lib/aifc.py (original) +++ python/branches/py3k/Lib/aifc.py Wed Apr 29 17:34:32 2009 @@ -144,9 +144,6 @@ _AIFC_version = 0xA2805140 # Version 1 of AIFF-C -_skiplist = b'COMT', b'INST', b'MIDI', b'AESD', \ - b'APPL', b'NAME', b'AUTH', b'(c) ', b'ANNO' - def _read_long(file): try: return struct.unpack('>l', file.read(4))[0] @@ -313,11 +310,6 @@ self._version = _read_ulong(chunk) elif chunkname == b'MARK': self._readmark(chunk) - elif chunkname in _skiplist: - pass - else: - raise Error('unrecognized chunk type ' + - chunkname.decode('latin1')) chunk.skip() if not self._comm_chunk_read or not self._ssnd_chunk: raise Error('COMM chunk and/or SSND chunk missing') Copied: python/branches/py3k/Lib/test/test_aifc.py (from r72101, /python/trunk/Lib/test/test_aifc.py) ============================================================================== --- /python/trunk/Lib/test/test_aifc.py (original) +++ python/branches/py3k/Lib/test/test_aifc.py Wed Apr 29 17:34:32 2009 @@ -1,4 +1,4 @@ -from test.test_support import findfile, run_unittest +from test.support import findfile, run_unittest import unittest import aifc @@ -21,26 +21,31 @@ self.assertEqual(f.getsampwidth(), 2) self.assertEqual(f.getframerate(), 48000) self.assertEqual(f.getnframes(), 14400) - self.assertEqual(f.getcomptype(), 'NONE') - self.assertEqual(f.getcompname(), 'not compressed') - self.assertEqual(f.getparams(), (2, 2, 48000, 14400, 'NONE', 'not compressed')) + # XXX: are the next two correct? The docs say/imply they are supposed + # to be strings. + self.assertEqual(f.getcomptype(), b'NONE') + self.assertEqual(f.getcompname(), b'not compressed') + self.assertEqual( + f.getparams(), + (2, 2, 48000, 14400, b'NONE', b'not compressed'), + ) f.close() def test_read(self): f = aifc.open(self.sndfilepath) self.assertEqual(f.tell(), 0) - self.assertEqual(f.readframes(2), '\x00\x00\x00\x00\x0b\xd4\x0b\xd4') + self.assertEqual(f.readframes(2), b'\x00\x00\x00\x00\x0b\xd4\x0b\xd4') f.rewind() pos0 = f.tell() self.assertEqual(pos0, 0) - self.assertEqual(f.readframes(2), '\x00\x00\x00\x00\x0b\xd4\x0b\xd4') + self.assertEqual(f.readframes(2), b'\x00\x00\x00\x00\x0b\xd4\x0b\xd4') pos2 = f.tell() self.assertEqual(pos2, 2) - self.assertEqual(f.readframes(2), '\x17t\x17t"\xad"\xad') + self.assertEqual(f.readframes(2), b'\x17t\x17t"\xad"\xad') f.setpos(pos2) - self.assertEqual(f.readframes(2), '\x17t\x17t"\xad"\xad') + self.assertEqual(f.readframes(2), b'\x17t\x17t"\xad"\xad') f.setpos(pos0) - self.assertEqual(f.readframes(2), '\x00\x00\x00\x00\x0b\xd4\x0b\xd4') + self.assertEqual(f.readframes(2), b'\x00\x00\x00\x00\x0b\xd4\x0b\xd4') f.close() #XXX Need more tests! Modified: python/branches/py3k/Lib/test/test_sundry.py ============================================================================== --- python/branches/py3k/Lib/test/test_sundry.py (original) +++ python/branches/py3k/Lib/test/test_sundry.py Wed Apr 29 17:34:32 2009 @@ -9,7 +9,6 @@ def test_at_least_import_untested_modules(self): with warnings.catch_warnings(): warnings.simplefilter("ignore") - import aifc import bdb import cgitb import code Modified: python/branches/py3k/Misc/ACKS ============================================================================== --- python/branches/py3k/Misc/ACKS (original) +++ python/branches/py3k/Misc/ACKS Wed Apr 29 17:34:32 2009 @@ -372,6 +372,7 @@ Peter van Kampen Jacob Kaplan-Moss Lou Kates +Hiroaki Kawai Sebastien Keim Robert Kern Randall Kern @@ -545,6 +546,7 @@ Samuele Pedroni Marcel van der Peijl Steven Pemberton +Santiago Peres?n Mark Perrego Trevor Perrin Tim Peters Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Apr 29 17:34:32 2009 @@ -473,6 +473,8 @@ Library ------- +- Issue #2245: aifc now skips chunk types it doesn't recognize, per spec. + - Issue #5874: distutils.tests.test_config_cmd is not locale-sensitive anymore. From buildbot at python.org Wed Apr 29 17:42:22 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 29 Apr 2009 15:42:22 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo 3.x Message-ID: <20090429154223.1D1E61E4011@bag.python.org> The Buildbot has detected a new failure of x86 gentoo 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%203.x/builds/724 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: make: *** [buildbottest] Unknown signal 32 sincerely, -The Buildbot From python-checkins at python.org Wed Apr 29 17:54:48 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 29 Apr 2009 17:54:48 +0200 (CEST) Subject: [Python-checkins] r72105 - in python/branches/release30-maint: Lib/aifc.py Lib/test/Sine-1000Hz-300ms.aif Lib/test/test_aifc.py Lib/test/test_sundry.py Misc/ACKS Misc/NEWS Message-ID: <20090429155448.C95E71E4011@bag.python.org> Author: r.david.murray Date: Wed Apr 29 17:54:48 2009 New Revision: 72105 Log: Merged revisions 72104 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ................ r72104 | r.david.murray | 2009-04-29 11:34:32 -0400 (Wed, 29 Apr 2009) | 17 lines Merged revisions 72100-72101 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72100 | r.david.murray | 2009-04-29 09:17:37 -0400 (Wed, 29 Apr 2009) | 7 lines Fix issue 2245. aifc now skips any chunk type it doesn't actually process instead of throwing errors for anything not in an explicit skip list. This is per this spec: http://www.cnpbagwell.com/aiff-c.txt. Spec reference and test sound file provided by Santiago Peres??n, fix based on patch by Hiroaki Kawai. ........ r72101 | r.david.murray | 2009-04-29 09:51:44 -0400 (Wed, 29 Apr 2009) | 2 lines Now that we've got a test_aifc, add a few tests. ........ ................ Added: python/branches/release30-maint/Lib/test/Sine-1000Hz-300ms.aif - copied unchanged from r72104, /python/branches/py3k/Lib/test/Sine-1000Hz-300ms.aif python/branches/release30-maint/Lib/test/test_aifc.py - copied unchanged from r72104, /python/branches/py3k/Lib/test/test_aifc.py Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Lib/aifc.py python/branches/release30-maint/Lib/test/test_sundry.py python/branches/release30-maint/Misc/ACKS python/branches/release30-maint/Misc/NEWS Modified: python/branches/release30-maint/Lib/aifc.py ============================================================================== --- python/branches/release30-maint/Lib/aifc.py (original) +++ python/branches/release30-maint/Lib/aifc.py Wed Apr 29 17:54:48 2009 @@ -144,9 +144,6 @@ _AIFC_version = 0xA2805140 # Version 1 of AIFF-C -_skiplist = b'COMT', b'INST', b'MIDI', b'AESD', \ - b'APPL', b'NAME', b'AUTH', b'(c) ', b'ANNO' - def _read_long(file): try: return struct.unpack('>l', file.read(4))[0] @@ -313,11 +310,6 @@ self._version = _read_ulong(chunk) elif chunkname == b'MARK': self._readmark(chunk) - elif chunkname in _skiplist: - pass - else: - raise Error('unrecognized chunk type ' + - chunkname.decode('latin1')) chunk.skip() if not self._comm_chunk_read or not self._ssnd_chunk: raise Error('COMM chunk and/or SSND chunk missing') Modified: python/branches/release30-maint/Lib/test/test_sundry.py ============================================================================== --- python/branches/release30-maint/Lib/test/test_sundry.py (original) +++ python/branches/release30-maint/Lib/test/test_sundry.py Wed Apr 29 17:54:48 2009 @@ -8,7 +8,6 @@ class TestUntestedModules(unittest.TestCase): def test_at_least_import_untested_modules(self): with warnings.catch_warnings(): - import aifc import bdb import cgitb import code Modified: python/branches/release30-maint/Misc/ACKS ============================================================================== --- python/branches/release30-maint/Misc/ACKS (original) +++ python/branches/release30-maint/Misc/ACKS Wed Apr 29 17:54:48 2009 @@ -362,6 +362,7 @@ Peter van Kampen Jacob Kaplan-Moss Lou Kates +Hiroaki Kawai Sebastien Keim Robert Kern Randall Kern @@ -527,6 +528,7 @@ Samuele Pedroni Marcel van der Peijl Steven Pemberton +Santiago Peres?n Mark Perrego Trevor Perrin Tim Peters Modified: python/branches/release30-maint/Misc/NEWS ============================================================================== --- python/branches/release30-maint/Misc/NEWS (original) +++ python/branches/release30-maint/Misc/NEWS Wed Apr 29 17:54:48 2009 @@ -42,6 +42,8 @@ Library ------- +- Issue #2245: aifc now skips chunk types it doesn't recognize, per spec. + - Issue #4305: ctypes should now build again on mipsel-linux-gnu - Issue #5853: calling a function of the mimetypes module from several threads From buildbot at python.org Wed Apr 29 18:28:32 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 29 Apr 2009 16:28:32 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 3.x Message-ID: <20090429162832.C2D6A1E4027@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%203.x/builds/710 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_os make: *** [buildbottest] Error 1 sincerely, -The Buildbot From nnorwitz at gmail.com Wed Apr 29 18:31:34 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 29 Apr 2009 12:31:34 -0400 Subject: [Python-checkins] Python Regression Test Failures doc (1) Message-ID: <20090429163134.GA13321@python.psfb.org> rm -rf build/* rm -rf tools/sphinx Checking out Sphinx... A tools/sphinx/jinja2glue.py A tools/sphinx/quickstart.py A tools/sphinx/theming.py A tools/sphinx/pycode A tools/sphinx/pycode/nodes.py A tools/sphinx/pycode/Grammar.txt A tools/sphinx/pycode/__init__.py A tools/sphinx/pycode/pgen2 A tools/sphinx/pycode/pgen2/tokenize.py A tools/sphinx/pycode/pgen2/pgen.py A tools/sphinx/pycode/pgen2/parse.py A tools/sphinx/pycode/pgen2/driver.py A tools/sphinx/pycode/pgen2/__init__.py A tools/sphinx/pycode/pgen2/literals.py A tools/sphinx/pycode/pgen2/token.py A tools/sphinx/pycode/pgen2/grammar.py A tools/sphinx/themes A tools/sphinx/themes/sphinxdoc A tools/sphinx/themes/sphinxdoc/layout.html A tools/sphinx/themes/sphinxdoc/theme.conf A tools/sphinx/themes/sphinxdoc/static A tools/sphinx/themes/sphinxdoc/static/contents.png A tools/sphinx/themes/sphinxdoc/static/navigation.png A tools/sphinx/themes/sphinxdoc/static/sphinxdoc.css A tools/sphinx/themes/basic A tools/sphinx/themes/basic/page.html A tools/sphinx/themes/basic/layout.html A tools/sphinx/themes/basic/genindex-single.html A tools/sphinx/themes/basic/genindex.html A tools/sphinx/themes/basic/opensearch.xml A tools/sphinx/themes/basic/theme.conf A tools/sphinx/themes/basic/static A tools/sphinx/themes/basic/static/doctools.js A tools/sphinx/themes/basic/static/searchtools.js A tools/sphinx/themes/basic/static/file.png A tools/sphinx/themes/basic/static/plus.png A tools/sphinx/themes/basic/static/basic.css A tools/sphinx/themes/basic/static/jquery.js A tools/sphinx/themes/basic/static/minus.png A tools/sphinx/themes/basic/changes A tools/sphinx/themes/basic/changes/versionchanges.html A tools/sphinx/themes/basic/changes/frameset.html A tools/sphinx/themes/basic/changes/rstsource.html A tools/sphinx/themes/basic/search.html A tools/sphinx/themes/basic/defindex.html A tools/sphinx/themes/basic/modindex.html A tools/sphinx/themes/basic/genindex-split.html A tools/sphinx/themes/default A tools/sphinx/themes/default/theme.conf A tools/sphinx/themes/default/static A tools/sphinx/themes/default/static/default.css_t A tools/sphinx/themes/traditional A tools/sphinx/themes/traditional/theme.conf A tools/sphinx/themes/traditional/static A tools/sphinx/themes/traditional/static/traditional.css A tools/sphinx/setup_command.py A tools/sphinx/__init__.py A tools/sphinx/application.py A tools/sphinx/environment.py A tools/sphinx/search.py A tools/sphinx/config.py A tools/sphinx/highlighting.py A tools/sphinx/writers A tools/sphinx/writers/latex.py A tools/sphinx/writers/__init__.py A tools/sphinx/writers/html.py A tools/sphinx/writers/text.py A tools/sphinx/locale A tools/sphinx/locale/__init__.py A tools/sphinx/locale/ru A tools/sphinx/locale/ru/LC_MESSAGES A tools/sphinx/locale/ru/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/ru/LC_MESSAGES/sphinx.js A tools/sphinx/locale/ru/LC_MESSAGES/sphinx.po A tools/sphinx/locale/de A tools/sphinx/locale/de/LC_MESSAGES A tools/sphinx/locale/de/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/de/LC_MESSAGES/sphinx.js A tools/sphinx/locale/de/LC_MESSAGES/sphinx.po A tools/sphinx/locale/ja A tools/sphinx/locale/ja/LC_MESSAGES A tools/sphinx/locale/ja/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/ja/LC_MESSAGES/sphinx.js A tools/sphinx/locale/ja/LC_MESSAGES/sphinx.po A tools/sphinx/locale/zh_TW A tools/sphinx/locale/zh_TW/LC_MESSAGES A tools/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.js A tools/sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po A tools/sphinx/locale/fi A tools/sphinx/locale/fi/LC_MESSAGES A tools/sphinx/locale/fi/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/fi/LC_MESSAGES/sphinx.js A tools/sphinx/locale/fi/LC_MESSAGES/sphinx.po A tools/sphinx/locale/uk_UA A tools/sphinx/locale/uk_UA/LC_MESSAGES A tools/sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/uk_UA/LC_MESSAGES/sphinx.js A tools/sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po A tools/sphinx/locale/cs A tools/sphinx/locale/cs/LC_MESSAGES A tools/sphinx/locale/cs/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/cs/LC_MESSAGES/sphinx.js A tools/sphinx/locale/cs/LC_MESSAGES/sphinx.po A tools/sphinx/locale/pt_BR A tools/sphinx/locale/pt_BR/LC_MESSAGES A tools/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.js A tools/sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po A tools/sphinx/locale/es A tools/sphinx/locale/es/LC_MESSAGES A tools/sphinx/locale/es/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/es/LC_MESSAGES/sphinx.js A tools/sphinx/locale/es/LC_MESSAGES/sphinx.po A tools/sphinx/locale/fr A tools/sphinx/locale/fr/LC_MESSAGES A tools/sphinx/locale/fr/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/fr/LC_MESSAGES/sphinx.js A tools/sphinx/locale/fr/LC_MESSAGES/sphinx.po A tools/sphinx/locale/nl A tools/sphinx/locale/nl/LC_MESSAGES A tools/sphinx/locale/nl/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/nl/LC_MESSAGES/sphinx.js A tools/sphinx/locale/nl/LC_MESSAGES/sphinx.po A tools/sphinx/locale/sphinx.pot A tools/sphinx/locale/pl A tools/sphinx/locale/pl/LC_MESSAGES A tools/sphinx/locale/pl/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/pl/LC_MESSAGES/sphinx.js A tools/sphinx/locale/pl/LC_MESSAGES/sphinx.po A tools/sphinx/locale/it A tools/sphinx/locale/it/LC_MESSAGES A tools/sphinx/locale/it/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/it/LC_MESSAGES/sphinx.js A tools/sphinx/locale/it/LC_MESSAGES/sphinx.po A tools/sphinx/locale/sl A tools/sphinx/locale/sl/LC_MESSAGES A tools/sphinx/locale/sl/LC_MESSAGES/sphinx.mo A tools/sphinx/locale/sl/LC_MESSAGES/sphinx.js A tools/sphinx/locale/sl/LC_MESSAGES/sphinx.po A tools/sphinx/ext A tools/sphinx/ext/graphviz.py A tools/sphinx/ext/coverage.py A tools/sphinx/ext/intersphinx.py A tools/sphinx/ext/inheritance_diagram.py A tools/sphinx/ext/autodoc.py A tools/sphinx/ext/pngmath.py A tools/sphinx/ext/__init__.py A tools/sphinx/ext/autosummary A tools/sphinx/ext/autosummary/generate.py A tools/sphinx/ext/autosummary/__init__.py A tools/sphinx/ext/autosummary/templates A tools/sphinx/ext/autosummary/templates/module A tools/sphinx/ext/refcounting.py A tools/sphinx/ext/ifconfig.py A tools/sphinx/ext/mathbase.py A tools/sphinx/ext/doctest.py A tools/sphinx/ext/todo.py A tools/sphinx/ext/jsmath.py A tools/sphinx/directives A tools/sphinx/directives/code.py A tools/sphinx/directives/desc.py A tools/sphinx/directives/__init__.py A tools/sphinx/directives/other.py A tools/sphinx/cmdline.py A tools/sphinx/errors.py A tools/sphinx/texinputs A tools/sphinx/texinputs/python.ist A tools/sphinx/texinputs/howto.cls A tools/sphinx/texinputs/tabulary.sty A tools/sphinx/texinputs/sphinx.sty A tools/sphinx/texinputs/fncychap.sty A tools/sphinx/texinputs/Makefile A tools/sphinx/texinputs/manual.cls A tools/sphinx/addnodes.py A tools/sphinx/builders A tools/sphinx/builders/changes.py A tools/sphinx/builders/linkcheck.py A tools/sphinx/builders/htmlhelp.py A tools/sphinx/builders/latex.py A tools/sphinx/builders/qthelp.py A tools/sphinx/builders/__init__.py A tools/sphinx/builders/html.py A tools/sphinx/builders/text.py A tools/sphinx/roles.py A tools/sphinx/builder.py A tools/sphinx/util A tools/sphinx/util/stemmer.py A tools/sphinx/util/tags.py A tools/sphinx/util/__init__.py A tools/sphinx/util/docstrings.py A tools/sphinx/util/texescape.py A tools/sphinx/util/console.py A tools/sphinx/util/jsdump.py A tools/sphinx/util/compat.py A tools/sphinx/util/png.py A tools/sphinx/util/smartypants.py Checked out revision 72105. svn update tools/sphinx At revision 72105. svn update tools/docutils At revision 72105. svn update tools/jinja2 At revision 72105. svn update tools/pygments At revision 72105. mkdir -p build/html build/doctrees python tools/sphinx-build.py -b html -d build/doctrees -D latex_paper_size= . build/html Running Sphinx v0.6.1 loading pickled environment... not found building [html]: targets for 392 source files that are out of date updating environment: 392 added, 0 changed, 0 removed reading sources... [ 0%] about reading sources... [ 0%] bugs reading sources... [ 0%] c-api/abstract reading sources... [ 1%] c-api/allocation reading sources... [ 1%] c-api/arg reading sources... [ 1%] c-api/bool reading sources... [ 1%] c-api/buffer reading sources... [ 2%] c-api/bytearray reading sources... [ 2%] c-api/bytes reading sources... [ 2%] c-api/cell reading sources... [ 2%] c-api/cobject reading sources... [ 3%] c-api/complex reading sources... [ 3%] c-api/concrete reading sources... [ 3%] c-api/conversion reading sources... [ 3%] c-api/datetime reading sources... [ 4%] c-api/descriptor reading sources... [ 4%] c-api/dict reading sources... [ 4%] c-api/exceptions reading sources... [ 4%] c-api/file reading sources... [ 5%] c-api/float reading sources... [ 5%] c-api/function reading sources... [ 5%] c-api/gcsupport reading sources... [ 5%] c-api/gen reading sources... [ 6%] c-api/import reading sources... [ 6%] c-api/index reading sources... [ 6%] c-api/init reading sources... [ 6%] c-api/intro reading sources... [ 7%] c-api/iter reading sources... [ 7%] c-api/iterator reading sources... [ 7%] c-api/list reading sources... [ 7%] c-api/long reading sources... [ 8%] c-api/mapping reading sources... [ 8%] c-api/marshal reading sources... [ 8%] c-api/memory reading sources... [ 8%] c-api/method reading sources... [ 9%] c-api/module reading sources... [ 9%] c-api/none reading sources... [ 9%] c-api/number reading sources... [ 9%] c-api/objbuffer reading sources... [ 10%] c-api/object reading sources... [ 10%] c-api/objimpl reading sources... [ 10%] c-api/refcounting reading sources... [ 10%] c-api/reflection reading sources... [ 11%] c-api/sequence reading sources... [ 11%] c-api/set reading sources... [ 11%] c-api/slice reading sources... [ 11%] c-api/structures reading sources... [ 12%] c-api/sys reading sources... [ 12%] c-api/tuple reading sources... [ 12%] c-api/type reading sources... [ 13%] c-api/typeobj reading sources... [ 13%] c-api/unicode reading sources... [ 13%] c-api/utilities reading sources... [ 13%] c-api/veryhigh reading sources... [ 14%] c-api/weakref reading sources... [ 14%] contents reading sources... [ 14%] copyright reading sources... [ 14%] distutils/apiref reading sources... [ 15%] distutils/builtdist reading sources... [ 15%] distutils/commandref reading sources... [ 15%] distutils/configfile reading sources... [ 15%] distutils/examples reading sources... [ 16%] distutils/extending reading sources... [ 16%] distutils/index reading sources... [ 16%] distutils/introduction reading sources... [ 16%] distutils/packageindex reading sources... [ 17%] distutils/setupscript reading sources... [ 17%] distutils/sourcedist reading sources... [ 17%] distutils/uploading reading sources... [ 17%] documenting/fromlatex reading sources... [ 18%] documenting/index reading sources... [ 18%] documenting/intro reading sources... [ 18%] documenting/markup reading sources... [ 18%] documenting/rest reading sources... [ 19%] documenting/style reading sources... [ 19%] extending/building reading sources... [ 19%] extending/embedding reading sources... [ 19%] extending/extending reading sources... [ 20%] extending/index reading sources... [ 20%] extending/newtypes reading sources... [ 20%] extending/windows reading sources... [ 20%] glossary reading sources... [ 21%] howto/advocacy reading sources... [ 21%] howto/cporting reading sources... [ 21%] howto/curses reading sources... [ 21%] howto/doanddont reading sources... [ 22%] howto/functional reading sources... [ 22%] howto/index reading sources... [ 22%] howto/regex reading sources... [ 22%] howto/sockets reading sources... [ 23%] howto/unicode reading sources... [ 23%] howto/urllib2 reading sources... [ 23%] howto/webservers reading sources... [ 23%] install/index reading sources... [ 24%] library/2to3 reading sources... [ 24%] library/__future__ reading sources... [ 24%] library/__main__ reading sources... [ 25%] library/_dummy_thread reading sources... [ 25%] library/_thread reading sources... [ 25%] library/abc reading sources... [ 25%] library/aifc reading sources... [ 26%] library/allos reading sources... [ 26%] library/archiving reading sources... [ 26%] library/array reading sources... [ 26%] library/ast reading sources... [ 27%] library/asynchat reading sources... [ 27%] library/asyncore reading sources... [ 27%] library/atexit reading sources... [ 27%] library/audioop reading sources... [ 28%] library/base64 reading sources... [ 28%] library/bdb reading sources... [ 28%] library/binascii reading sources... [ 28%] library/binhex reading sources... [ 29%] library/bisect reading sources... [ 29%] library/builtins reading sources... [ 29%] library/bz2 reading sources... [ 29%] library/calendar reading sources... [ 30%] library/cgi reading sources... [ 30%] library/cgitb reading sources... [ 30%] library/chunk reading sources... [ 30%] library/cmath reading sources... [ 31%] library/cmd reading sources... [ 31%] library/code reading sources... [ 31%] library/codecs reading sources... [ 31%] library/codeop reading sources... [ 32%] library/collections reading sources... [ 32%] library/colorsys reading sources... [ 32%] library/compileall reading sources... [ 32%] library/configparser reading sources... [ 33%] library/constants reading sources... [ 33%] library/contextlib reading sources... [ 33%] library/copy reading sources... [ 33%] library/copyreg reading sources... [ 34%] library/crypt reading sources... [ 34%] library/crypto reading sources... [ 34%] library/csv reading sources... [ 34%] library/ctypes reading sources... [ 35%] library/curses reading sources... [ 35%] library/curses.ascii reading sources... [ 35%] library/curses.panel reading sources... [ 35%] library/custominterp reading sources... [ 36%] library/datatypes reading sources... [ 36%] library/datetime reading sources... [ 36%] library/dbm reading sources... [ 36%] library/debug reading sources... [ 37%] library/decimal reading sources... [ 37%] library/development reading sources... [ 37%] library/difflib reading sources... [ 38%] library/dis reading sources... [ 38%] library/distutils reading sources... [ 38%] library/doctest reading sources... [ 38%] library/dummy_threading reading sources... [ 39%] library/email reading sources... [ 39%] library/email-examples reading sources... [ 39%] library/email.charset reading sources... [ 39%] library/email.encoders reading sources... [ 40%] library/email.errors reading sources... [ 40%] library/email.generator reading sources... [ 40%] library/email.header reading sources... [ 40%] library/email.iterators reading sources... [ 41%] library/email.message reading sources... [ 41%] library/email.mime reading sources... [ 41%] library/email.parser reading sources... [ 41%] library/email.util reading sources... [ 42%] library/errno reading sources... [ 42%] library/exceptions reading sources... [ 42%] library/fcntl reading sources... [ 42%] library/filecmp reading sources... [ 43%] library/fileformats reading sources... [ 43%] library/fileinput reading sources... [ 43%] library/filesys reading sources... [ 43%] library/fnmatch reading sources... [ 44%] library/formatter reading sources... [ 44%] library/fpectl reading sources... [ 44%] library/fractions reading sources... [ 44%] library/frameworks reading sources... [ 45%] library/ftplib reading sources... [ 45%] library/functions reading sources... [ 45%] library/functools reading sources... [ 45%] library/gc reading sources... [ 46%] library/getopt reading sources... [ 46%] library/getpass reading sources... [ 46%] library/gettext reading sources... [ 46%] library/glob reading sources... [ 47%] library/grp reading sources... [ 47%] library/gzip reading sources... [ 47%] library/hashlib reading sources... [ 47%] library/heapq reading sources... [ 48%] library/hmac reading sources... [ 48%] library/html.entities reading sources... [ 48%] library/html.parser reading sources... [ 48%] library/http.client reading sources... [ 49%] library/http.cookiejar reading sources... [ 49%] library/http.cookies reading sources... [ 49%] library/http.server reading sources... [ 50%] library/i18n reading sources... [ 50%] library/idle reading sources... [ 50%] library/imaplib reading sources... [ 50%] library/imghdr reading sources... [ 51%] library/imp reading sources... [ 51%] library/index reading sources... [ 51%] library/inspect reading sources... [ 51%] library/internet reading sources... [ 52%] library/intro reading sources... [ 52%] library/io reading sources... [ 52%] library/ipc reading sources... [ 52%] library/itertools reading sources... [ 53%] library/json reading sources... [ 53%] library/keyword reading sources... [ 53%] library/language reading sources... [ 53%] library/linecache reading sources... [ 54%] library/locale reading sources... [ 54%] library/logging reading sources... [ 54%] library/macpath reading sources... [ 54%] library/mailbox reading sources... [ 55%] library/mailcap reading sources... [ 55%] library/markup reading sources... [ 55%] library/marshal reading sources... [ 55%] library/math reading sources... [ 56%] library/mimetypes reading sources... [ 56%] library/misc reading sources... [ 56%] library/mm reading sources... [ 56%] library/mmap reading sources... [ 57%] library/modulefinder reading sources... [ 57%] library/modules reading sources... [ 57%] library/msilib reading sources... [ 57%] library/msvcrt reading sources... [ 58%] library/multiprocessing reST markup error: /home/neal/python/r30/Doc/library/multiprocessing.rst:1899: (SEVERE/4) Missing matching underline for section title overline. ======= [INFO/SyncManager-...] child process calling self.run() [INFO/SyncManager-...] created temp directory /.../pymp-... make: *** [build] Error 1 From python-checkins at python.org Wed Apr 29 18:44:29 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 29 Apr 2009 18:44:29 +0200 (CEST) Subject: [Python-checkins] r72106 - in python/branches/release30-maint: Doc/library/multiprocessing.rst Message-ID: <20090429164429.05C451E419A@bag.python.org> Author: r.david.murray Date: Wed Apr 29 18:44:28 2009 New Revision: 72106 Log: Roll back mistaken checkin of conflicted multiprocessing.rst file. Merge needs to wait until previous updates to file are merged. Rolled back revisions 72062 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Doc/library/multiprocessing.rst Modified: python/branches/release30-maint/Doc/library/multiprocessing.rst ============================================================================== --- python/branches/release30-maint/Doc/library/multiprocessing.rst (original) +++ python/branches/release30-maint/Doc/library/multiprocessing.rst Wed Apr 29 18:44:28 2009 @@ -40,18 +40,12 @@ >>> p.map(f, [1,2,3]) Process PoolWorker-1: Process PoolWorker-2: - Process PoolWorker-3: - Traceback (most recent call last): Traceback (most recent call last): Traceback (most recent call last): AttributeError: 'module' object has no attribute 'f' AttributeError: 'module' object has no attribute 'f' AttributeError: 'module' object has no attribute 'f' - (If you try this it will actually output three full tracebacks - interleaved in a semi-random fashion, and then you may have to - stop the master process somehow.) - The :class:`Process` class ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -422,9 +416,7 @@ :attr:`exit_code` methods should only be called by the process that created the process object. - Example usage of some of the methods of :class:`Process`: - - .. doctest:: + Example usage of some of the methods of :class:`Process`:: >>> import multiprocessing, time, signal >>> p = multiprocessing.Process(target=time.sleep, args=(1000,)) @@ -434,7 +426,6 @@ >>> print(p, p.is_alive()) True >>> p.terminate() - >>> time.sleep(0.1) >>> print(p, p.is_alive()) False >>> p.exitcode == -signal.SIGTERM @@ -676,7 +667,7 @@ freeze_support() Process(target=f).start() - If the ``freeze_support()`` line is omitted then trying to run the frozen + If the ``freeze_support()`` line is missed out then trying to run the frozen executable will raise :exc:`RuntimeError`. If the module is being run normally by the Python interpreter then @@ -690,7 +681,7 @@ setExecutable(os.path.join(sys.exec_prefix, 'pythonw.exe')) - before they can create child processes. (Windows only) + before they can create child processes. (Windows only) .. note:: @@ -770,8 +761,8 @@ *buffer* must be an object satisfying the writable buffer interface. If *offset* is given then the message will be written into the buffer from - that position. Offset must be a non-negative integer less than the - length of *buffer* (in bytes). + *that position. Offset must be a non-negative integer less than the + *length of *buffer* (in bytes). If the buffer is too short then a :exc:`BufferTooShort` exception is raised and the complete message is available as ``e.args[0]`` where ``e`` @@ -780,8 +771,6 @@ For example: -.. doctest:: - >>> from multiprocessing import Pipe >>> a, b = Pipe() >>> a.send([1, 'hello', None]) @@ -868,9 +857,8 @@ specifies a timeout in seconds. If *block* is ``False`` then *timeout* is ignored. -.. note:: - On OS/X ``sem_timedwait`` is unsupported, so timeout arguments for the - aforementioned :meth:`acquire` methods will be ignored on OS/X. + Note that on OS/X ``sem_timedwait`` is unsupported, so timeout arguments + for these will be ignored. .. note:: @@ -1067,7 +1055,7 @@ lock = Lock() n = Value('i', 7) - x = Value(c_double, 1.0/3.0, lock=False) + x = Value(ctypes.c_double, 1.0/3.0, lock=False) s = Array('c', 'hello world', lock=lock) A = Array(Point, [(1.875,-6.25), (-5.75,2.0), (2.375,9.5)], lock=lock) @@ -1148,21 +1136,21 @@ Returns a :class:`Server` object which represents the actual server under the control of the Manager. The :class:`Server` object supports the - :meth:`serve_forever` method:: + :meth:`serve_forever` method: >>> from multiprocessing.managers import BaseManager - >>> manager = BaseManager(address=('', 50000), authkey='abc') - >>> server = manager.get_server() - >>> server.serve_forever() + >>> m = BaseManager(address=('', 50000), authkey='abc')) + >>> server = m.get_server() + >>> s.serve_forever() - :class:`Server` additionally has an :attr:`address` attribute. + :class:`Server` additionally have an :attr:`address` attribute. .. method:: connect() - Connect a local manager object to a remote manager process:: + Connect a local manager object to a remote manager process: >>> from multiprocessing.managers import BaseManager - >>> m = BaseManager(address=('127.0.0.1', 5000), authkey='abc') + >>> m = BaseManager(address='127.0.0.1', authkey='abc')) >>> m.connect() .. method:: shutdown() @@ -1290,9 +1278,7 @@ Its representation shows the values of its attributes. However, when using a proxy for a namespace object, an attribute beginning with -``'_'`` will be an attribute of the proxy and not an attribute of the referent: - -.. doctest:: +``'_'`` will be an attribute of the proxy and not an attribute of the referent:: >>> manager = multiprocessing.Manager() >>> Global = manager.Namespace() @@ -1344,15 +1330,17 @@ >>> import queue >>> queue = queue.Queue() >>> class QueueManager(BaseManager): pass + ... >>> QueueManager.register('get_queue', callable=lambda:queue) >>> m = QueueManager(address=('', 50000), authkey='abracadabra') >>> s = m.get_server() - >>> s.serve_forever() + >>> s.serveForever() One client can access the server as follows:: >>> from multiprocessing.managers import BaseManager >>> class QueueManager(BaseManager): pass + ... >>> QueueManager.register('get_queue') >>> m = QueueManager(address=('foo.bar.org', 50000), authkey='abracadabra') >>> m.connect() @@ -1363,10 +1351,10 @@ >>> from multiprocessing.managers import BaseManager >>> class QueueManager(BaseManager): pass - >>> QueueManager.register('get_queue') - >>> m = QueueManager(address=('foo.bar.org', 50000), authkey='abracadabra') - >>> m.connect() - >>> queue = m.get_queue() + ... + >>> QueueManager.register('getQueue') + >>> m = QueueManager.from_address(address=('foo.bar.org', 50000), authkey='abracadabra') + >>> queue = m.getQueue() >>> queue.get() 'hello' @@ -1402,9 +1390,7 @@ A proxy object has methods which invoke corresponding methods of its referent (although not every method of the referent will necessarily be available through the proxy). A proxy can usually be used in most of the same ways that its -referent can: - -.. doctest:: +referent can:: >>> from multiprocessing import Manager >>> manager = Manager() @@ -1412,7 +1398,7 @@ >>> print(l) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> print(repr(l)) - + >>> l[4] 16 >>> l[2:5] @@ -1425,9 +1411,7 @@ An important feature of proxy objects is that they are picklable so they can be passed between processes. Note, however, that if a proxy is sent to the corresponding manager's process then unpickling it will produce the referent -itself. This means, for example, that one shared object can contain a second: - -.. doctest:: +itself. This means, for example, that one shared object can contain a second:: >>> a = manager.list() >>> b = manager.list() @@ -1441,14 +1425,12 @@ .. note:: The proxy types in :mod:`multiprocessing` do nothing to support comparisons - by value. So, for instance, we have: - - .. doctest:: + by value. So, for instance, :: - >>> manager.list([1,2,3]) == [1,2,3] - False + manager.list([1,2,3]) == [1,2,3] - One should just use a copy of the referent instead when making comparisons. + will return ``False``. One should just use a copy of the referent instead + when making comparisons. .. class:: BaseProxy @@ -1480,9 +1462,7 @@ Note in particular that an exception will be raised if *methodname* has not been *exposed* - An example of the usage of :meth:`_callmethod`: - - .. doctest:: + An example of the usage of :meth:`_callmethod`:: >>> l = manager.list(range(10)) >>> l._callmethod('__len__') @@ -1893,55 +1873,13 @@ >>> logger.warning('doomed') [WARNING/MainProcess] doomed >>> m = multiprocessing.Manager() -<<<<<<< .working [INFO/SyncManager-1] child process calling self.run() [INFO/SyncManager-1] manager bound to '\\\\.\\pipe\\pyc-2776-0-lj0tfa' -======= - [INFO/SyncManager-...] child process calling self.run() - [INFO/SyncManager-...] created temp directory /.../pymp-... - [INFO/SyncManager-...] manager serving at '/.../listener-...' ->>>>>>> .merge-right.r72062 >>> del m [INFO/MainProcess] sending shutdown message to manager - [INFO/SyncManager-...] manager exiting with exitcode 0 + [INFO/SyncManager-1] manager exiting with exitcode 0 -<<<<<<< .working -======= -+----------------+----------------+ -| Level | Numeric value | -+================+================+ -| ``SUBWARNING`` | 25 | -+----------------+----------------+ -| ``SUBDEBUG`` | 5 | -+----------------+----------------+ - -For a full table of logging levels, see the :mod:`logging` module. - -These additional logging levels are used primarily for certain debug messages -within the multiprocessing module. Below is the same example as above, except -with :const:`SUBDEBUG` enabled:: - - >>> import multiprocessing, logging - >>> logger = multiprocessing.log_to_stderr() - >>> logger.setLevel(multiprocessing.SUBDEBUG) - >>> logger.warning('doomed') - [WARNING/MainProcess] doomed - >>> m = multiprocessing.Manager() - [INFO/SyncManager-...] child process calling self.run() - [INFO/SyncManager-...] created temp directory /.../pymp-... - [INFO/SyncManager-...] manager serving at '/.../pymp-djGBXN/listener-...' - >>> del m - [SUBDEBUG/MainProcess] finalizer calling ... - [INFO/MainProcess] sending shutdown message to manager - [DEBUG/SyncManager-...] manager received shutdown message - [SUBDEBUG/SyncManager-...] calling ... - [SUBDEBUG/SyncManager-...] calling - [SUBDEBUG/SyncManager-...] finalizer calling ... - [INFO/SyncManager-...] manager exiting with exitcode 0 - ->>>>>>> .merge-right.r72062 The :mod:`multiprocessing.dummy` module ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From python-checkins at python.org Wed Apr 29 19:18:20 2009 From: python-checkins at python.org (matthias.klose) Date: Wed, 29 Apr 2009 19:18:20 +0200 (CEST) Subject: [Python-checkins] r72107 - in python/trunk: Misc/NEWS README configure.in setup.py Message-ID: <20090429171820.45AF61E4011@bag.python.org> Author: matthias.klose Date: Wed Apr 29 19:18:19 2009 New Revision: 72107 Log: - Issue #4587: Add configure option --with-dbmliborder=db1:db2:... to specify the order that backends for the dbm extension are checked. Modified: python/trunk/Misc/NEWS python/trunk/README python/trunk/configure.in python/trunk/setup.py Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Apr 29 19:18:19 2009 @@ -814,6 +814,9 @@ Build ----- +- Issue #4587: Add configure option --with-dbmliborder=db1:db2:... to specify + the order that backends for the dbm extension are checked. + - Link the shared python library with $(MODLIBS). - Issue #5134: Silence compiler warnings when compiling sqlite with VC++. Modified: python/trunk/README ============================================================================== --- python/trunk/README (original) +++ python/trunk/README Wed Apr 29 19:18:19 2009 @@ -1068,6 +1068,9 @@ --with-system-ffi: Build the _ctypes extension module using an ffi library installed on the system. +--with-dbmliborder=db1:db2:...: Specify the order that backends for the + dbm extension are checked. Valid value is a colon separated string + with the backend names `ndbm', `gdbm' and `bdb'. Building for multiple architectures (using the VPATH feature) ------------------------------------------------------------- Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Wed Apr 29 19:18:19 2009 @@ -1918,6 +1918,26 @@ AC_MSG_RESULT($with_system_ffi) +# Check for --with-dbmliborder +AC_MSG_CHECKING(for --with-dbmliborder) +AC_ARG_WITH(dbmliborder, + AC_HELP_STRING(--with-dbmliborder=db1:db2:..., order to check db backends for dbm), +[ +if test x$with_dbmliborder = xyes +then +AC_MSG_ERROR([proper usage is --with-dbmliborder=db1:db2:...]) +else + for db in `echo $with_dbmliborder | sed 's/:/ /g'`; do + if test x$db != xndbm && test x$db != xgdbm && test x$db != xbdb + then + AC_MSG_ERROR([proper usage is --with-dbmliborder=db1:db2:...]) + fi + done + AC_MSG_RESULT($with_dbmliborder) +fi], +[AC_MSG_ERROR([proper usage is --with-dbmliborder=db1:db2:...]) +]) + # Determine if signalmodule should be used. AC_SUBST(USE_SIGNAL_MODULE) AC_SUBST(SIGNAL_OBJS) Modified: python/trunk/setup.py ============================================================================== --- python/trunk/setup.py (original) +++ python/trunk/setup.py Wed Apr 29 19:18:19 2009 @@ -1000,39 +1000,68 @@ # The standard Unix dbm module: if platform not in ['cygwin']: - if find_file("ndbm.h", inc_dirs, []) is not None: - # Some systems have -lndbm, others don't - if self.compiler.find_library_file(lib_dirs, 'ndbm'): - ndbm_libs = ['ndbm'] - else: - ndbm_libs = [] - exts.append( Extension('dbm', ['dbmmodule.c'], - define_macros=[('HAVE_NDBM_H',None)], - libraries = ndbm_libs ) ) - elif self.compiler.find_library_file(lib_dirs, 'gdbm'): - gdbm_libs = ['gdbm'] - if self.compiler.find_library_file(lib_dirs, 'gdbm_compat'): - gdbm_libs.append('gdbm_compat') - if find_file("gdbm/ndbm.h", inc_dirs, []) is not None: - exts.append( Extension( - 'dbm', ['dbmmodule.c'], - define_macros=[('HAVE_GDBM_NDBM_H',None)], - libraries = gdbm_libs ) ) - elif find_file("gdbm-ndbm.h", inc_dirs, []) is not None: - exts.append( Extension( - 'dbm', ['dbmmodule.c'], - define_macros=[('HAVE_GDBM_DASH_NDBM_H',None)], - libraries = gdbm_libs ) ) - else: - missing.append('dbm') - elif db_incs is not None: - exts.append( Extension('dbm', ['dbmmodule.c'], - library_dirs=dblib_dir, - runtime_library_dirs=dblib_dir, - include_dirs=db_incs, - define_macros=[('HAVE_BERKDB_H',None), - ('DB_DBM_HSEARCH',None)], - libraries=dblibs)) + config_args = sysconfig.get_config_var("CONFIG_ARGS") + dbm_args = [arg.split('=')[-1] for arg in args.split() + if arg.startswith('--with-dbmliborder=')] + if dbm_args: + dbm_order = "ndbm:gdbm:bdb".split(":") + else: + dbm_order = dbm_args.split(":") + dbmext = None + for cand in dbm_order: + if cand == "ndbm": + if find_file("ndbm.h", inc_dirs, []) is not None: + # Some systems have -lndbm, others don't + if self.compiler.find_library_file(lib_dirs, 'ndbm'): + ndbm_libs = ['ndbm'] + else: + ndbm_libs = [] + print "building dbm using ndbm" + dbmext = Extension('dbm', ['dbmmodule.c'], + define_macros=[ + ('HAVE_NDBM_H',None), + ], + libraries=ndbm_libs) + break + + elif cand == "gdbm": + if self.compiler.find_library_file(lib_dirs, 'gdbm'): + gdbm_libs = ['gdbm'] + if self.compiler.find_library_file(lib_dirs, 'gdbm_compat'): + gdbm_libs.append('gdbm_compat') + if find_file("gdbm/ndbm.h", inc_dirs, []) is not None: + print "building dbm using gdbm" + dbmext = Extension( + 'dbm', ['dbmmodule.c'], + define_macros=[ + ('HAVE_GDBM_NDBM_H', None), + ], + libraries = gdbm_libs) + break + if find_file("gdbm-ndbm.h", inc_dirs, []) is not None: + print "building dbm using gdbm" + dbmext = Extension( + 'dbm', ['dbmmodule.c'], + define_macros=[ + ('HAVE_GDBM_DASH_NDBM_H', None), + ], + libraries = gdbm_libs) + break + elif cand == "bdb": + if db_incs is not None: + print "building dbm using bdb" + dbmext = Extension('dbm', ['dbmmodule.c'], + library_dirs=dblib_dir, + runtime_library_dirs=dblib_dir, + include_dirs=db_incs, + define_macros=[ + ('HAVE_BERKDB_H', None), + ('DB_DBM_HSEARCH', None), + ], + libraries=dblibs) + break + if dbmext is not None: + exts.append(dbmext) else: missing.append('dbm') From buildbot at python.org Wed Apr 29 19:24:02 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 29 Apr 2009 17:24:02 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu trunk Message-ID: <20090429172402.E77171E4011@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%20trunk/builds/1207 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From buildbot at python.org Wed Apr 29 19:24:41 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 29 Apr 2009 17:24:41 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo trunk Message-ID: <20090429172441.EA4401E4016@bag.python.org> The Buildbot has detected a new failure of x86 gentoo trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%20trunk/builds/4897 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From python-checkins at python.org Wed Apr 29 20:22:48 2009 From: python-checkins at python.org (guido.van.rossum) Date: Wed, 29 Apr 2009 20:22:48 +0200 (CEST) Subject: [Python-checkins] r72108 - peps/trunk/pep-0382.txt Message-ID: <20090429182248.542C21E4011@bag.python.org> Author: guido.van.rossum Date: Wed Apr 29 20:22:48 2009 New Revision: 72108 Log: Fix ReST warnings. Modified: peps/trunk/pep-0382.txt Modified: peps/trunk/pep-0382.txt ============================================================================== --- peps/trunk/pep-0382.txt (original) +++ peps/trunk/pep-0382.txt Wed Apr 29 20:22:48 2009 @@ -122,11 +122,11 @@ 1. sys.path is search for a directory foo, or a file foo.. If a file is found, it is treated as a module, and imported. - 2. if it is a directory, it checks for *.pkg files. If it finds + 2. if it is a directory, it checks for \*.pkg files. If it finds any, a package is created, and its __path__ is extended. 3. The __init__ module is imported; this import will search the __path__ that got computed already. - 4. If neither a *.pkg file nor an __init__.py was found, the + 4. If neither a \*.pkg file nor an __init__.py was found, the directory is skipped, and search for the module/package continues. From python-checkins at python.org Wed Apr 29 20:47:07 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 29 Apr 2009 20:47:07 +0200 (CEST) Subject: [Python-checkins] r72109 - in python/branches/py3k: Lib/test/formatfloat_testcases.txt Lib/test/test_float.py Misc/NEWS Python/pystrtod.c Message-ID: <20090429184707.813551E4020@bag.python.org> Author: mark.dickinson Date: Wed Apr 29 20:47:07 2009 New Revision: 72109 Log: Issue #5864: Fix problem with empty code formatting for floats, where a bogus trailing zero could be added. Modified: python/branches/py3k/Lib/test/formatfloat_testcases.txt python/branches/py3k/Lib/test/test_float.py python/branches/py3k/Misc/NEWS python/branches/py3k/Python/pystrtod.c Modified: python/branches/py3k/Lib/test/formatfloat_testcases.txt ============================================================================== --- python/branches/py3k/Lib/test/formatfloat_testcases.txt (original) +++ python/branches/py3k/Lib/test/formatfloat_testcases.txt Wed Apr 29 20:47:07 2009 @@ -339,6 +339,8 @@ %s 1e10 -> 10000000000.0 %s 9.999e10 -> 99990000000.0 %s 99999999999 -> 99999999999.0 +%s 99999999999.9 -> 99999999999.9 +%s 99999999999.99 -> 1e+11 %s 1e11 -> 1e+11 %s 1e12 -> 1e+12 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 Wed Apr 29 20:47:07 2009 @@ -328,6 +328,11 @@ self.assertEqual(fmt % float(arg), rhs) self.assertEqual(fmt % -float(arg), '-' + rhs) + def test_issue5864(self): + self.assertEquals(format(123.456, '.4'), '123.5') + self.assertEquals(format(1234.56, '.4'), '1.235e+03') + self.assertEquals(format(12345.6, '.4'), '1.235e+04') + class ReprTestCase(unittest.TestCase): def test_repr(self): floats_file = open(os.path.join(os.path.split(__file__)[0], Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Wed Apr 29 20:47:07 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #5864: Fix empty format code formatting for floats so that it + never gives more than the requested number of significant digits. + - Issue #5793: Rationalize isdigit / isalpha / tolower, etc. Includes new Py_ISDIGIT / Py_ISALPHA / Py_TOLOWER, etc. in pctypes.h. Modified: python/branches/py3k/Python/pystrtod.c ============================================================================== --- python/branches/py3k/Python/pystrtod.c (original) +++ python/branches/py3k/Python/pystrtod.c Wed Apr 29 20:47:07 2009 @@ -354,14 +354,61 @@ } } -/* Ensure that buffer has a decimal point in it. The decimal point will not - be in the current locale, it will always be '.'. Don't add a decimal if an - exponent is present. */ +/* Remove trailing zeros after the decimal point from a numeric string; also + remove the decimal point if all digits following it are zero. The numeric + string must end in '\0', and should not have any leading or trailing + whitespace. Assumes that the decimal point is '.'. */ Py_LOCAL_INLINE(void) -ensure_decimal_point(char* buffer, size_t buf_size) +remove_trailing_zeros(char *buffer) { - int insert_count = 0; - char* chars_to_insert; + char *old_fraction_end, *new_fraction_end, *end, *p; + + p = buffer; + if (*p == '-' || *p == '+') + /* Skip leading sign, if present */ + ++p; + while (Py_ISDIGIT(*p)) + ++p; + + /* if there's no decimal point there's nothing to do */ + if (*p++ != '.') + return; + + /* scan any digits after the point */ + while (Py_ISDIGIT(*p)) + ++p; + old_fraction_end = p; + + /* scan up to ending '\0' */ + while (*p != '\0') + p++; + /* +1 to make sure that we move the null byte as well */ + end = p+1; + + /* scan back from fraction_end, looking for removable zeros */ + p = old_fraction_end; + while (*(p-1) == '0') + --p; + /* and remove point if we've got that far */ + if (*(p-1) == '.') + --p; + new_fraction_end = p; + + memmove(new_fraction_end, old_fraction_end, end-old_fraction_end); +} + +/* Ensure that buffer has a decimal point in it. The decimal point will not + be in the current locale, it will always be '.'. Don't add a decimal point + if an exponent is present. Also, convert to exponential notation where + adding a '.0' would produce too many significant digits (see issue 5864). + + Returns a pointer to the fixed buffer, or NULL on failure. +*/ +Py_LOCAL_INLINE(char *) +ensure_decimal_point(char* buffer, size_t buf_size, int precision) +{ + int digit_count, insert_count = 0, convert_to_exp = 0; + char *chars_to_insert, *digits_start; /* search for the first non-digit character */ char *p = buffer; @@ -369,8 +416,10 @@ /* Skip leading sign, if present. I think this could only ever be '-', but it can't hurt to check for both. */ ++p; + digits_start = p; while (*p && Py_ISDIGIT(*p)) ++p; + digit_count = Py_SAFE_DOWNCAST(p - digits_start, Py_ssize_t, int); if (*p == '.') { if (Py_ISDIGIT(*(p+1))) { @@ -380,6 +429,8 @@ else { /* We have a decimal point, but no following digit. Insert a zero after the decimal. */ + /* can't ever get here via PyOS_double_to_string */ + assert(precision == -1); ++p; chars_to_insert = "0"; insert_count = 1; @@ -387,8 +438,22 @@ } else if (!(*p == 'e' || *p == 'E')) { /* Don't add ".0" if we have an exponent. */ - chars_to_insert = ".0"; - insert_count = 2; + if (digit_count == precision) { + /* issue 5864: don't add a trailing .0 in the case + where the '%g'-formatted result already has as many + significant digits as were requested. Switch to + exponential notation instead. */ + convert_to_exp = 1; + /* no exponent, no point, and we shouldn't land here + for infs and nans, so we must be at the end of the + string. */ + assert(*p == '\0'); + } + else { + assert(precision == -1 || digit_count < precision); + chars_to_insert = ".0"; + insert_count = 2; + } } if (insert_count) { size_t buf_len = strlen(buffer); @@ -403,6 +468,30 @@ memcpy(p, chars_to_insert, insert_count); } } + if (convert_to_exp) { + int written; + size_t buf_avail; + p = digits_start; + /* insert decimal point */ + assert(digit_count >= 1); + memmove(p+2, p+1, digit_count); /* safe, but overwrites nul */ + p[1] = '.'; + p += digit_count+1; + assert(p <= buf_size+buffer); + buf_avail = buf_size+buffer-p; + if (buf_avail == 0) + return NULL; + /* Add exponent. It's okay to use lower case 'e': we only + arrive here as a result of using the empty format code or + repr/str builtins and those never want an upper case 'E' */ + written = PyOS_snprintf(p, buf_avail, "e%+.02d", digit_count-1); + if (!(0 <= written && + written < Py_SAFE_DOWNCAST(buf_avail, size_t, int))) + /* output truncated, or something else bad happened */ + return NULL; + remove_trailing_zeros(buffer); + } + return buffer; } /* see FORMATBUFLEN in unicodeobject.c */ @@ -425,12 +514,14 @@ * at least one digit after the decimal. * * Return value: The pointer to the buffer with the converted string. + * On failure returns NULL but does not set any Python exception. **/ char * _PyOS_ascii_formatd(char *buffer, size_t buf_size, const char *format, - double d) + double d, + int precision) { char format_char; size_t format_len = strlen(format); @@ -495,9 +586,12 @@ ensure_minimum_exponent_length(buffer, buf_size); /* If format_char is 'Z', make sure we have at least one character - after the decimal point (and make sure we have a decimal point). */ + after the decimal point (and make sure we have a decimal point); + also switch to exponential notation in some edge cases where the + extra character would produce more significant digits that we + really want. */ if (format_char == 'Z') - ensure_decimal_point(buffer, buf_size); + buffer = ensure_decimal_point(buffer, buf_size, precision); return buffer; } @@ -513,57 +607,13 @@ "use PyOS_double_to_string instead", 1) < 0) return NULL; - return _PyOS_ascii_formatd(buffer, buf_size, format, d); + return _PyOS_ascii_formatd(buffer, buf_size, format, d, -1); } #ifdef PY_NO_SHORT_FLOAT_REPR /* The fallback code to use if _Py_dg_dtoa is not available. */ -/* Remove trailing zeros after the decimal point from a numeric string; also - remove the decimal point if all digits following it are zero. The numeric - string must end in '\0', and should not have any leading or trailing - whitespace. Assumes that the decimal point is '.'. */ -Py_LOCAL_INLINE(void) -remove_trailing_zeros(char *buffer) -{ - char *old_fraction_end, *new_fraction_end, *end, *p; - - p = buffer; - if (*p == '-' || *p == '+') - /* Skip leading sign, if present */ - ++p; - while (isdigit(Py_CHARMASK(*p))) - ++p; - - /* if there's no decimal point there's nothing to do */ - if (*p++ != '.') - return; - - /* scan any digits after the point */ - while (isdigit(Py_CHARMASK(*p))) - ++p; - old_fraction_end = p; - - /* scan up to ending '\0' */ - while (*p != '\0') - p++; - /* +1 to make sure that we move the null byte as well */ - end = p+1; - - /* scan back from fraction_end, looking for removable zeros */ - p = old_fraction_end; - while (*(p-1) == '0') - --p; - /* and remove point if we've got that far */ - if (*(p-1) == '.') - --p; - new_fraction_end = p; - - memmove(new_fraction_end, old_fraction_end, end-old_fraction_end); -} - - PyAPI_FUNC(char *) PyOS_double_to_string(double val, char format_code, int precision, @@ -577,7 +627,6 @@ char *p; int t; int upper = 0; - int strip_trailing_zeros = 0; /* Validate format_code, and map upper and lower case */ switch (format_code) { @@ -612,17 +661,8 @@ PyErr_BadInternalCall(); return NULL; } - /* switch to exponential notation at 1e11, or 1e12 if we're - not adding a .0 */ - if (fabs(val) >= (flags & Py_DTSF_ADD_DOT_0 ? 1e11 : 1e12)) { - precision = 11; - format_code = 'e'; - strip_trailing_zeros = 1; - } - else { - precision = 12; - format_code = 'g'; - } + precision = 12; + format_code = 'g'; break; default: PyErr_BadInternalCall(); @@ -641,18 +681,13 @@ t = Py_DTST_INFINITE; } else { t = Py_DTST_FINITE; - - - if ((flags & Py_DTSF_ADD_DOT_0) && (format_code != 'e')) + if (flags & Py_DTSF_ADD_DOT_0) format_code = 'Z'; PyOS_snprintf(format, sizeof(format), "%%%s.%i%c", (flags & Py_DTSF_ALT ? "#" : ""), precision, format_code); - _PyOS_ascii_formatd(buf, sizeof(buf), format, val); - /* remove trailing zeros if necessary */ - if (strip_trailing_zeros) - remove_trailing_zeros(buf); + _PyOS_ascii_formatd(buf, sizeof(buf), format, val, precision); } len = strlen(buf); @@ -678,7 +713,7 @@ /* Convert to upper case. */ char *p1; for (p1 = p; *p1; p1++) - *p1 = toupper(*p1); + *p1 = Py_TOUPPER(*p1); } if (type) @@ -766,7 +801,7 @@ assert(digits_end != NULL && digits_end >= digits); digits_len = digits_end - digits; - if (digits_len && !isdigit(Py_CHARMASK(digits[0]))) { + if (digits_len && !Py_ISDIGIT(digits[0])) { /* Infinities and nans here; adapt Gay's output, so convert Infinity to inf and NaN to nan, and ignore sign of nan. Then return. */ @@ -851,7 +886,8 @@ vdigits_end = decpt + precision; break; case 'g': - if (decpt <= -4 || decpt > precision) + if (decpt <= -4 || decpt > + (add_dot_0_if_integer ? precision-1 : precision)) use_exp = 1; if (use_alt_formatting) vdigits_end = precision; From python-checkins at python.org Wed Apr 29 20:48:14 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 29 Apr 2009 20:48:14 +0200 (CEST) Subject: [Python-checkins] r72110 - python/branches/release30-maint Message-ID: <20090429184814.53BF71E4020@bag.python.org> Author: mark.dickinson Date: Wed Apr 29 20:48:14 2009 New Revision: 72110 Log: Blocked revisions 72109 via svnmerge ........ r72109 | mark.dickinson | 2009-04-29 19:47:07 +0100 (Wed, 29 Apr 2009) | 3 lines Issue #5864: Fix problem with empty code formatting for floats, where a bogus trailing zero could be added. ........ Modified: python/branches/release30-maint/ (props changed) From buildbot at python.org Wed Apr 29 20:56:48 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 29 Apr 2009 18:56:48 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc trunk Message-ID: <20090429185648.A9E041E4011@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc trunk. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%20trunk/builds/348 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: matthias.klose BUILD FAILED: failed compile sincerely, -The Buildbot From buildbot at python.org Wed Apr 29 21:02:34 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 29 Apr 2009 19:02:34 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 3.x Message-ID: <20090429190234.61BD51E4011@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%203.x/builds/841 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_os ====================================================================== FAIL: test_update2 (test.test_os.EnvironTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-ubuntu-i386/build/Lib/test/test_os.py", line 382, in test_update2 self.assertEquals(value, "World") AssertionError: '' != 'World' make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Wed Apr 29 21:38:05 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 29 Apr 2009 19:38:05 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090429193806.36F0E1E4011@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/601 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_posix test_time ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 251, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 177, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From python-checkins at python.org Wed Apr 29 21:52:50 2009 From: python-checkins at python.org (matthias.klose) Date: Wed, 29 Apr 2009 21:52:50 +0200 (CEST) Subject: [Python-checkins] r72111 - in python/trunk: configure.in setup.py Message-ID: <20090429195250.0E8FE1E4011@bag.python.org> Author: matthias.klose Date: Wed Apr 29 21:52:49 2009 New Revision: 72111 Log: - Issue #4587: Add configure option --with-dbmliborder=db1:db2:... to specify the order that backends for the dbm extension are checked. Modified: python/trunk/configure.in python/trunk/setup.py Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Wed Apr 29 21:52:49 2009 @@ -1921,7 +1921,7 @@ # Check for --with-dbmliborder AC_MSG_CHECKING(for --with-dbmliborder) AC_ARG_WITH(dbmliborder, - AC_HELP_STRING(--with-dbmliborder=db1:db2:..., order to check db backends for dbm), + AC_HELP_STRING([--with-dbmliborder=db1:db2:...], [order to check db backends for dbm. Valid value is a colon separated string with the backend names `ndbm', `gdbm' and `bdb'.]), [ if test x$with_dbmliborder = xyes then Modified: python/trunk/setup.py ============================================================================== --- python/trunk/setup.py (original) +++ python/trunk/setup.py Wed Apr 29 21:52:49 2009 @@ -1000,13 +1000,14 @@ # The standard Unix dbm module: if platform not in ['cygwin']: - config_args = sysconfig.get_config_var("CONFIG_ARGS") - dbm_args = [arg.split('=')[-1] for arg in args.split() + config_args = [arg.strip("'") + for arg in sysconfig.get_config_var("CONFIG_ARGS").split()] + dbm_args = [arg.split('=')[-1] for arg in config_args if arg.startswith('--with-dbmliborder=')] if dbm_args: - dbm_order = "ndbm:gdbm:bdb".split(":") + dbm_order = dbm_args[-1].split(":") else: - dbm_order = dbm_args.split(":") + dbm_order = "ndbm:gdbm:bdb".split(":") dbmext = None for cand in dbm_order: if cand == "ndbm": From python-checkins at python.org Wed Apr 29 22:01:33 2009 From: python-checkins at python.org (martin.v.loewis) Date: Wed, 29 Apr 2009 22:01:33 +0200 (CEST) Subject: [Python-checkins] r72112 - peps/trunk/pep-0383.txt Message-ID: <20090429200133.346A71E4011@bag.python.org> Author: martin.v.loewis Date: Wed Apr 29 22:01:33 2009 New Revision: 72112 Log: Make differences between status quo and proposed change explicit. Modified: peps/trunk/pep-0383.txt Modified: peps/trunk/pep-0383.txt ============================================================================== --- peps/trunk/pep-0383.txt (original) +++ peps/trunk/pep-0383.txt Wed Apr 29 22:01:33 2009 @@ -67,8 +67,9 @@ environmental data to Python str objects. On POSIX systems, Python currently applies the locale's encoding to -convert the byte data to Unicode. Non-decodable bytes will be -represented as lone half surrogate codes U+DCxx. +convert the byte data to Unicode, failing for characters that cannot +be decoded. With this PEP, non-decodable bytes will be represented as +lone half surrogate codes U+DCxx. To convert non-decodable bytes, a new error handler "python-escape" is introduced, which produces these half surrogates. On encoding, the From python-checkins at python.org Wed Apr 29 22:06:30 2009 From: python-checkins at python.org (martin.v.loewis) Date: Wed, 29 Apr 2009 22:06:30 +0200 (CEST) Subject: [Python-checkins] r72113 - peps/trunk/pep-0383.txt Message-ID: <20090429200630.030851E4011@bag.python.org> Author: martin.v.loewis Date: Wed Apr 29 22:06:29 2009 New Revision: 72113 Log: Fix code example. Specify that the error handler is used on all relevant APIs. Modified: peps/trunk/pep-0383.txt Modified: peps/trunk/pep-0383.txt ============================================================================== --- peps/trunk/pep-0383.txt (original) +++ peps/trunk/pep-0383.txt Wed Apr 29 22:06:29 2009 @@ -74,7 +74,8 @@ To convert non-decodable bytes, a new error handler "python-escape" is introduced, which produces these half surrogates. On encoding, the error handler converts the half surrogate back to the corresponding -byte. +byte. This error handler used used in any API that receives or produces +file names, command line arguments, or environment variables. The error handler interface is extended to allow the encode error handler to return byte strings immediately, in addition to returning @@ -119,7 +120,7 @@ dirname = dirname.decode(fse, "python-escape") for fn in os.listdir(dirname): # fn is now a str object - yield fn.encode(fse, "python-escape" + yield fn.encode(fse, "python-escape") Copyright ========= From python-checkins at python.org Wed Apr 29 22:09:50 2009 From: python-checkins at python.org (matthias.klose) Date: Wed, 29 Apr 2009 22:09:50 +0200 (CEST) Subject: [Python-checkins] r72114 - python/trunk/configure.in Message-ID: <20090429200950.5EAE51E4011@bag.python.org> Author: matthias.klose Date: Wed Apr 29 22:09:50 2009 New Revision: 72114 Log: - configure.in: Don't error, when no --with-dbmliborder option is present Modified: python/trunk/configure.in Modified: python/trunk/configure.in ============================================================================== --- python/trunk/configure.in (original) +++ python/trunk/configure.in Wed Apr 29 22:09:50 2009 @@ -1933,10 +1933,8 @@ AC_MSG_ERROR([proper usage is --with-dbmliborder=db1:db2:...]) fi done - AC_MSG_RESULT($with_dbmliborder) -fi], -[AC_MSG_ERROR([proper usage is --with-dbmliborder=db1:db2:...]) -]) +fi]) +AC_MSG_RESULT($with_dbmliborder) # Determine if signalmodule should be used. AC_SUBST(USE_SIGNAL_MODULE) From python-checkins at python.org Wed Apr 29 22:15:19 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 29 Apr 2009 22:15:19 +0200 (CEST) Subject: [Python-checkins] r72115 - python/trunk/Lib/test/test_aifc.py Message-ID: <20090429201519.354D71E410A@bag.python.org> Author: r.david.murray Date: Wed Apr 29 22:15:18 2009 New Revision: 72115 Log: More aifc tests. Modified: python/trunk/Lib/test/test_aifc.py Modified: python/trunk/Lib/test/test_aifc.py ============================================================================== --- python/trunk/Lib/test/test_aifc.py (original) +++ python/trunk/Lib/test/test_aifc.py Wed Apr 29 22:15:18 2009 @@ -1,5 +1,6 @@ -from test.test_support import findfile, run_unittest +from test.test_support import findfile, run_unittest, TESTFN import unittest +import os import aifc @@ -7,16 +8,29 @@ class AIFCTest(unittest.TestCase): def setUp(self): + self.f = self.fout = None self.sndfilepath = findfile('Sine-1000Hz-300ms.aif') + def tearDown(self): + if self.f is not None: + self.f.close() + if self.fout is not None: + try: + self.fout.close() + except (aifc.Error, AttributeError): + pass + try: + os.remove(TESTFN) + except OSError: + pass + def test_skipunknown(self): #Issue 2245 #This file contains chunk types aifc doesn't recognize. f = aifc.open(self.sndfilepath) - f.close() def test_params(self): - f = aifc.open(self.sndfilepath) + f = self.f = aifc.open(self.sndfilepath) self.assertEqual(f.getnchannels(), 2) self.assertEqual(f.getsampwidth(), 2) self.assertEqual(f.getframerate(), 48000) @@ -24,10 +38,9 @@ self.assertEqual(f.getcomptype(), 'NONE') self.assertEqual(f.getcompname(), 'not compressed') self.assertEqual(f.getparams(), (2, 2, 48000, 14400, 'NONE', 'not compressed')) - f.close() def test_read(self): - f = aifc.open(self.sndfilepath) + f = self.f = aifc.open(self.sndfilepath) self.assertEqual(f.tell(), 0) self.assertEqual(f.readframes(2), '\x00\x00\x00\x00\x0b\xd4\x0b\xd4') f.rewind() @@ -41,9 +54,42 @@ self.assertEqual(f.readframes(2), '\x17t\x17t"\xad"\xad') f.setpos(pos0) self.assertEqual(f.readframes(2), '\x00\x00\x00\x00\x0b\xd4\x0b\xd4') - f.close() - #XXX Need more tests! + def test_write(self): + f = self.f = aifc.open(self.sndfilepath) + fout = self.fout = aifc.open(TESTFN, 'wb') + fout.aifc() + fout.setparams(f.getparams()) + for frame in range(f.getnframes()): + fout.writeframes(f.readframes(1)) + fout.close() + fout = self.fout = aifc.open(TESTFN, 'rb') + f.rewind() + self.assertEqual(f.getparams(), fout.getparams()) + self.assertEqual(f.readframes(5), fout.readframes(5)) + + def test_compress(self): + f = self.f = aifc.open(self.sndfilepath) + fout = self.fout = aifc.open(TESTFN, 'wb') + fout.aifc() + fout.setnchannels(f.getnchannels()) + fout.setsampwidth(f.getsampwidth()) + fout.setframerate(f.getframerate()) + fout.setcomptype('ULAW', 'foo') + for frame in range(f.getnframes()): + fout.writeframes(f.readframes(1)) + fout.close() + self.assertLess( + os.stat(TESTFN).st_size, + os.stat(self.sndfilepath).st_size*0.75, + ) + fout = self.fout = aifc.open(TESTFN, 'rb') + f.rewind() + self.assertEqual(f.getparams()[0:3], fout.getparams()[0:3]) + self.assertEqual(fout.getcomptype(), 'ULAW') + self.assertEqual(fout.getcompname(), 'foo') + # XXX: this test fails, not sure if it should succeed or not + # self.assertEqual(f.readframes(5), fout.readframes(5)) def test_main(): From python-checkins at python.org Wed Apr 29 22:25:16 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 29 Apr 2009 22:25:16 +0200 (CEST) Subject: [Python-checkins] r72116 - python/branches/release26-maint Message-ID: <20090429202516.E87571E4011@bag.python.org> Author: r.david.murray Date: Wed Apr 29 22:25:16 2009 New Revision: 72116 Log: One of these tests uses a unittest method that wasn't backported. Blocked revisions 72115 via svnmerge ........ r72115 | r.david.murray | 2009-04-29 16:15:18 -0400 (Wed, 29 Apr 2009) | 2 lines More aifc tests. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Wed Apr 29 22:36:25 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 29 Apr 2009 22:36:25 +0200 (CEST) Subject: [Python-checkins] r72117 - python/trunk/configure Message-ID: <20090429203625.CC0FF1E4011@bag.python.org> Author: benjamin.peterson Date: Wed Apr 29 22:36:25 2009 New Revision: 72117 Log: run autoconf Modified: python/trunk/configure Modified: python/trunk/configure ============================================================================== --- python/trunk/configure (original) +++ python/trunk/configure Wed Apr 29 22:36:25 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 71009 . +# From configure.in Revision: 72114 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 2.7. # @@ -1346,6 +1346,10 @@ --with-pydebug build with Py_DEBUG defined --with-libs='lib1 ...' link against additional libs --with-system-ffi build _ctypes module using an installed ffi library + --with-dbmliborder=db1:db2:... + order to check db backends for dbm. Valid value is a + colon separated string with the backend names + `ndbm', `gdbm' and `bdb'. --with-signal-module disable/enable signal module --with-dec-threads use DEC Alpha/OSF1 thread-safe libraries --with(out)-threads[=DIRECTORY] @@ -14248,6 +14252,33 @@ { echo "$as_me:$LINENO: result: $with_system_ffi" >&5 echo "${ECHO_T}$with_system_ffi" >&6; } +# Check for --with-dbmliborder +{ echo "$as_me:$LINENO: checking for --with-dbmliborder" >&5 +echo $ECHO_N "checking for --with-dbmliborder... $ECHO_C" >&6; } + +# Check whether --with-dbmliborder was given. +if test "${with_dbmliborder+set}" = set; then + withval=$with_dbmliborder; +if test x$with_dbmliborder = xyes +then +{ { echo "$as_me:$LINENO: error: proper usage is --with-dbmliborder=db1:db2:..." >&5 +echo "$as_me: error: proper usage is --with-dbmliborder=db1:db2:..." >&2;} + { (exit 1); exit 1; }; } +else + for db in `echo $with_dbmliborder | sed 's/:/ /g'`; do + if test x$db != xndbm && test x$db != xgdbm && test x$db != xbdb + then + { { echo "$as_me:$LINENO: error: proper usage is --with-dbmliborder=db1:db2:..." >&5 +echo "$as_me: error: proper usage is --with-dbmliborder=db1:db2:..." >&2;} + { (exit 1); exit 1; }; } + fi + done +fi +fi + +{ echo "$as_me:$LINENO: result: $with_dbmliborder" >&5 +echo "${ECHO_T}$with_dbmliborder" >&6; } + # Determine if signalmodule should be used. From python-checkins at python.org Wed Apr 29 22:40:42 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 29 Apr 2009 22:40:42 +0200 (CEST) Subject: [Python-checkins] r72118 - in python/branches/py3k: Lib/test/test_aifc.py Message-ID: <20090429204042.B96781E4097@bag.python.org> Author: r.david.murray Date: Wed Apr 29 22:40:42 2009 New Revision: 72118 Log: Merged revisions 72115 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72115 | r.david.murray | 2009-04-29 16:15:18 -0400 (Wed, 29 Apr 2009) | 2 lines More aifc tests. ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/test/test_aifc.py Modified: python/branches/py3k/Lib/test/test_aifc.py ============================================================================== --- python/branches/py3k/Lib/test/test_aifc.py (original) +++ python/branches/py3k/Lib/test/test_aifc.py Wed Apr 29 22:40:42 2009 @@ -1,5 +1,6 @@ -from test.support import findfile, run_unittest +from test.support import findfile, run_unittest, TESTFN import unittest +import os import aifc @@ -7,16 +8,29 @@ class AIFCTest(unittest.TestCase): def setUp(self): + self.f = self.fout = None self.sndfilepath = findfile('Sine-1000Hz-300ms.aif') + def tearDown(self): + if self.f is not None: + self.f.close() + if self.fout is not None: + try: + self.fout.close() + except (aifc.Error, AttributeError): + pass + try: + os.remove(TESTFN) + except OSError: + pass + def test_skipunknown(self): #Issue 2245 #This file contains chunk types aifc doesn't recognize. f = aifc.open(self.sndfilepath) - f.close() def test_params(self): - f = aifc.open(self.sndfilepath) + f = self.f = aifc.open(self.sndfilepath) self.assertEqual(f.getnchannels(), 2) self.assertEqual(f.getsampwidth(), 2) self.assertEqual(f.getframerate(), 48000) @@ -29,10 +43,9 @@ f.getparams(), (2, 2, 48000, 14400, b'NONE', b'not compressed'), ) - f.close() def test_read(self): - f = aifc.open(self.sndfilepath) + f = self.f = aifc.open(self.sndfilepath) self.assertEqual(f.tell(), 0) self.assertEqual(f.readframes(2), b'\x00\x00\x00\x00\x0b\xd4\x0b\xd4') f.rewind() @@ -46,9 +59,42 @@ self.assertEqual(f.readframes(2), b'\x17t\x17t"\xad"\xad') f.setpos(pos0) self.assertEqual(f.readframes(2), b'\x00\x00\x00\x00\x0b\xd4\x0b\xd4') - f.close() - #XXX Need more tests! + def test_write(self): + f = self.f = aifc.open(self.sndfilepath) + fout = self.fout = aifc.open(TESTFN, 'wb') + fout.aifc() + fout.setparams(f.getparams()) + for frame in range(f.getnframes()): + fout.writeframes(f.readframes(1)) + fout.close() + fout = self.fout = aifc.open(TESTFN, 'rb') + f.rewind() + self.assertEqual(f.getparams(), fout.getparams()) + self.assertEqual(f.readframes(5), fout.readframes(5)) + + def test_compress(self): + f = self.f = aifc.open(self.sndfilepath) + fout = self.fout = aifc.open(TESTFN, 'wb') + fout.aifc() + fout.setnchannels(f.getnchannels()) + fout.setsampwidth(f.getsampwidth()) + fout.setframerate(f.getframerate()) + fout.setcomptype(b'ULAW', b'foo') + for frame in range(f.getnframes()): + fout.writeframes(f.readframes(1)) + fout.close() + self.assertLess( + os.stat(TESTFN).st_size, + os.stat(self.sndfilepath).st_size*0.75, + ) + fout = self.fout = aifc.open(TESTFN, 'rb') + f.rewind() + self.assertEqual(f.getparams()[0:3], fout.getparams()[0:3]) + self.assertEqual(fout.getcomptype(), b'ULAW') + self.assertEqual(fout.getcompname(), b'foo') + # XXX: this test fails, not sure if it should succeed or not + # self.assertEqual(f.readframes(5), fout.readframes(5)) def test_main(): From python-checkins at python.org Wed Apr 29 22:41:00 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 29 Apr 2009 22:41:00 +0200 (CEST) Subject: [Python-checkins] r72119 - in python/trunk: Lib/test/test_float.py Misc/NEWS Python/pystrtod.c Message-ID: <20090429204100.F30391E4179@bag.python.org> Author: mark.dickinson Date: Wed Apr 29 22:41:00 2009 New Revision: 72119 Log: Issue #5864: format(1234.5, '.4') gives misleading result (Backport of r72109 from py3k.) Modified: python/trunk/Lib/test/test_float.py python/trunk/Misc/NEWS python/trunk/Python/pystrtod.c Modified: python/trunk/Lib/test/test_float.py ============================================================================== --- python/trunk/Lib/test/test_float.py (original) +++ python/trunk/Lib/test/test_float.py Wed Apr 29 22:41:00 2009 @@ -253,6 +253,11 @@ self.assertEquals(math.atan2(float('-1e-1000'), -1), math.atan2(-0.0, -1)) + def test_issue5864(self): + self.assertEquals(format(123.456, '.4'), '123.5') + self.assertEquals(format(1234.56, '.4'), '1.235e+03') + self.assertEquals(format(12345.6, '.4'), '1.235e+04') + class ReprTestCase(unittest.TestCase): def test_repr(self): floats_file = open(os.path.join(os.path.split(__file__)[0], Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Wed Apr 29 22:41:00 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #5864: Fix empty format code formatting for floats so that it + never gives more than the requested number of significant digits. + - Issue #5793: Rationalize isdigit / isalpha / tolower, etc. Includes new Py_ISDIGIT / Py_ISALPHA / Py_TOLOWER, etc. in pctypes.h. Modified: python/trunk/Python/pystrtod.c ============================================================================== --- python/trunk/Python/pystrtod.c (original) +++ python/trunk/Python/pystrtod.c Wed Apr 29 22:41:00 2009 @@ -348,14 +348,61 @@ } } -/* Ensure that buffer has a decimal point in it. The decimal point will not - be in the current locale, it will always be '.'. Don't add a decimal if an - exponent is present. */ +/* Remove trailing zeros after the decimal point from a numeric string; also + remove the decimal point if all digits following it are zero. The numeric + string must end in '\0', and should not have any leading or trailing + whitespace. Assumes that the decimal point is '.'. */ Py_LOCAL_INLINE(void) -ensure_decimal_point(char* buffer, size_t buf_size) +remove_trailing_zeros(char *buffer) +{ + char *old_fraction_end, *new_fraction_end, *end, *p; + + p = buffer; + if (*p == '-' || *p == '+') + /* Skip leading sign, if present */ + ++p; + while (Py_ISDIGIT(*p)) + ++p; + + /* if there's no decimal point there's nothing to do */ + if (*p++ != '.') + return; + + /* scan any digits after the point */ + while (Py_ISDIGIT(*p)) + ++p; + old_fraction_end = p; + + /* scan up to ending '\0' */ + while (*p != '\0') + p++; + /* +1 to make sure that we move the null byte as well */ + end = p+1; + + /* scan back from fraction_end, looking for removable zeros */ + p = old_fraction_end; + while (*(p-1) == '0') + --p; + /* and remove point if we've got that far */ + if (*(p-1) == '.') + --p; + new_fraction_end = p; + + memmove(new_fraction_end, old_fraction_end, end-old_fraction_end); +} + +/* Ensure that buffer has a decimal point in it. The decimal point will not + be in the current locale, it will always be '.'. Don't add a decimal point + if an exponent is present. Also, convert to exponential notation where + adding a '.0' would produce too many significant digits (see issue 5864). + + Returns a pointer to the fixed buffer, or NULL on failure. +*/ +Py_LOCAL_INLINE(char *) +ensure_decimal_point(char* buffer, size_t buf_size, int precision) { - int insert_count = 0; - char* chars_to_insert; + int digit_count, insert_count = 0, convert_to_exp = 0; + char* chars_to_insert, *digits_start; /* search for the first non-digit character */ char *p = buffer; @@ -363,8 +410,10 @@ /* Skip leading sign, if present. I think this could only ever be '-', but it can't hurt to check for both. */ ++p; + digits_start = p; while (*p && Py_ISDIGIT(*p)) ++p; + digit_count = Py_SAFE_DOWNCAST(p - digits_start, Py_ssize_t, int); if (*p == '.') { if (Py_ISDIGIT(*(p+1))) { @@ -374,6 +423,8 @@ else { /* We have a decimal point, but no following digit. Insert a zero after the decimal. */ + /* can't ever get here via PyOS_double_to_string */ + assert(precision == -1); ++p; chars_to_insert = "0"; insert_count = 1; @@ -381,8 +432,22 @@ } else if (!(*p == 'e' || *p == 'E')) { /* Don't add ".0" if we have an exponent. */ - chars_to_insert = ".0"; - insert_count = 2; + if (digit_count == precision) { + /* issue 5864: don't add a trailing .0 in the case + where the '%g'-formatted result already has as many + significant digits as were requested. Switch to + exponential notation instead. */ + convert_to_exp = 1; + /* no exponent, no point, and we shouldn't land here + for infs and nans, so we must be at the end of the + string. */ + assert(*p == '\0'); + } + else { + assert(precision == -1 || digit_count < precision); + chars_to_insert = ".0"; + insert_count = 2; + } } if (insert_count) { size_t buf_len = strlen(buffer); @@ -397,6 +462,30 @@ memcpy(p, chars_to_insert, insert_count); } } + if (convert_to_exp) { + int written; + size_t buf_avail; + p = digits_start; + /* insert decimal point */ + assert(digit_count >= 1); + memmove(p+2, p+1, digit_count); /* safe, but overwrites nul */ + p[1] = '.'; + p += digit_count+1; + assert(p <= buf_size+buffer); + buf_avail = buf_size+buffer-p; + if (buf_avail == 0) + return NULL; + /* Add exponent. It's okay to use lower case 'e': we only + arrive here as a result of using the empty format code or + repr/str builtins and those never want an upper case 'E' */ + written = PyOS_snprintf(p, buf_avail, "e%+.02d", digit_count-1); + if (!(0 <= written && + written < Py_SAFE_DOWNCAST(buf_avail, size_t, int))) + /* output truncated, or something else bad happened */ + return NULL; + remove_trailing_zeros(buffer); + } + return buffer; } /* see FORMATBUFLEN in unicodeobject.c */ @@ -419,6 +508,7 @@ * at least one digit after the decimal. * * Return value: The pointer to the buffer with the converted string. + * On failure returns NULL but does not set any Python exception. **/ /* DEPRECATED, will be deleted in 2.8 and 3.2 */ PyAPI_FUNC(char *) @@ -495,9 +585,12 @@ ensure_minimum_exponent_length(buffer, buf_size); /* If format_char is 'Z', make sure we have at least one character - after the decimal point (and make sure we have a decimal point). */ + after the decimal point (and make sure we have a decimal point); + also switch to exponential notation in some edge cases where the + extra character would produce more significant digits that we + really want. */ if (format_char == 'Z') - ensure_decimal_point(buffer, buf_size); + buffer = ensure_decimal_point(buffer, buf_size, -1); return buffer; } @@ -600,7 +693,7 @@ /* Possibly make sure we have at least one character after the decimal point (and make sure we have a decimal point). */ if (flags & Py_DTSF_ADD_DOT_0) - ensure_decimal_point(buf, buf_len); + buf = ensure_decimal_point(buf, buf_len, precision); } /* Add the sign if asked and the result isn't negative. */ From python-checkins at python.org Wed Apr 29 22:41:53 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 29 Apr 2009 22:41:53 +0200 (CEST) Subject: [Python-checkins] r72120 - python/branches/release26-maint Message-ID: <20090429204153.F01851E4016@bag.python.org> Author: mark.dickinson Date: Wed Apr 29 22:41:53 2009 New Revision: 72120 Log: Blocked revisions 72119 via svnmerge ........ r72119 | mark.dickinson | 2009-04-29 21:41:00 +0100 (Wed, 29 Apr 2009) | 3 lines Issue #5864: format(1234.5, '.4') gives misleading result (Backport of r72109 from py3k.) ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Wed Apr 29 22:43:11 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 29 Apr 2009 22:43:11 +0200 (CEST) Subject: [Python-checkins] r72121 - python/branches/py3k Message-ID: <20090429204311.A48BB1E40D1@bag.python.org> Author: mark.dickinson Date: Wed Apr 29 22:43:11 2009 New Revision: 72121 Log: Blocked revisions 72119 via svnmerge ........ r72119 | mark.dickinson | 2009-04-29 21:41:00 +0100 (Wed, 29 Apr 2009) | 3 lines Issue #5864: format(1234.5, '.4') gives misleading result (Backport of r72109 from py3k.) ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Wed Apr 29 22:44:57 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 29 Apr 2009 22:44:57 +0200 (CEST) Subject: [Python-checkins] r72122 - python/branches/release30-maint Message-ID: <20090429204457.D37111E4011@bag.python.org> Author: r.david.murray Date: Wed Apr 29 22:44:57 2009 New Revision: 72122 Log: Blocked revisions 72118 via svnmerge ................ r72118 | r.david.murray | 2009-04-29 16:40:42 -0400 (Wed, 29 Apr 2009) | 9 lines Merged revisions 72115 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72115 | r.david.murray | 2009-04-29 16:15:18 -0400 (Wed, 29 Apr 2009) | 2 lines More aifc tests. ........ ................ Test uses unittest method that wasn't backported. Modified: python/branches/release30-maint/ (props changed) From buildbot at python.org Wed Apr 29 22:47:08 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 29 Apr 2009 20:47:08 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090429204708.412E81E4011@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/316 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: mark.dickinson,r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_posix test_subprocess ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From buildbot at python.org Wed Apr 29 23:18:16 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 29 Apr 2009 21:18:16 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 2.6 Message-ID: <20090429211816.CC5491E4020@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 2.6. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%202.6/builds/306 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/release26-maint] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: sincerely, -The Buildbot From buildbot at python.org Wed Apr 29 23:49:44 2009 From: buildbot at python.org (buildbot at python.org) Date: Wed, 29 Apr 2009 21:49:44 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo trunk Message-ID: <20090429214944.9A4A71E4016@bag.python.org> The Buildbot has detected a new failure of x86 gentoo trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%20trunk/builds/4899 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: matthias.klose,r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_time ====================================================================== FAIL: test_tzset (test.test_time.TimeTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/buildslave/python-trunk/trunk.norwitz-x86/build/Lib/test/test_time.py", line 152, in test_tzset time.gmtime(xmas2002), time.localtime(xmas2002) AssertionError: time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) != time.struct_time(tm_year=2002, tm_mon=12, tm_mday=24, tm_hour=19, tm_min=0, tm_sec=0, tm_wday=1, tm_yday=358, tm_isdst=0) make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Wed Apr 29 23:50:39 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 29 Apr 2009 23:50:39 +0200 (CEST) Subject: [Python-checkins] r72123 - in python/branches/py3k: Doc/library/aifc.rst Lib/test/test_aifc.py Message-ID: <20090429215039.D0A4E1E4011@bag.python.org> Author: r.david.murray Date: Wed Apr 29 23:50:39 2009 New Revision: 72123 Log: Document the fact that 'compname' and 'comptype' are bytes. Modified: python/branches/py3k/Doc/library/aifc.rst python/branches/py3k/Lib/test/test_aifc.py Modified: python/branches/py3k/Doc/library/aifc.rst ============================================================================== --- python/branches/py3k/Doc/library/aifc.rst (original) +++ python/branches/py3k/Doc/library/aifc.rst Wed Apr 29 23:50:39 2009 @@ -74,14 +74,16 @@ .. method:: aifc.getcomptype() - Return a four-character string describing the type of compression used in the - audio file. For AIFF files, the returned value is ``'NONE'``. + Return a bytes array of length 4 describing the type of compression + used in the audio file. For AIFF files, the returned value is + ``b'NONE'``. .. method:: aifc.getcompname() - Return a human-readable description of the type of compression used in the audio - file. For AIFF files, the returned value is ``'not compressed'``. + Return a bytes array convertible to a human-readable description + of the type of compression used in the audio file. For AIFF files, + the returned value is ``b'not compressed'``. .. method:: aifc.getparams() @@ -180,11 +182,12 @@ single: A-LAW single: G.722 - Specify the compression type. If not specified, the audio data will not be - compressed. In AIFF files, compression is not possible. The name parameter - should be a human-readable description of the compression type, the type - parameter should be a four-character string. Currently the following - compression types are supported: NONE, ULAW, ALAW, G722. + Specify the compression type. If not specified, the audio data will + not be compressed. In AIFF files, compression is not possible. + The name parameter should be a human-readable description of the + compression type as a bytes array, the type parameter should be a + bytes array of length 4. Currently the following compression types + are supported: ``b'NONE'``, ``b'ULAW'``, ``b'ALAW'``, ``b'G722'``. .. method:: aifc.setparams(nchannels, sampwidth, framerate, comptype, compname) Modified: python/branches/py3k/Lib/test/test_aifc.py ============================================================================== --- python/branches/py3k/Lib/test/test_aifc.py (original) +++ python/branches/py3k/Lib/test/test_aifc.py Wed Apr 29 23:50:39 2009 @@ -35,8 +35,6 @@ self.assertEqual(f.getsampwidth(), 2) self.assertEqual(f.getframerate(), 48000) self.assertEqual(f.getnframes(), 14400) - # XXX: are the next two correct? The docs say/imply they are supposed - # to be strings. self.assertEqual(f.getcomptype(), b'NONE') self.assertEqual(f.getcompname(), b'not compressed') self.assertEqual( From python-checkins at python.org Wed Apr 29 23:52:37 2009 From: python-checkins at python.org (r.david.murray) Date: Wed, 29 Apr 2009 23:52:37 +0200 (CEST) Subject: [Python-checkins] r72124 - in python/branches/release30-maint: Doc/library/aifc.rst Lib/test/test_aifc.py Message-ID: <20090429215237.C23CA1E4115@bag.python.org> Author: r.david.murray Date: Wed Apr 29 23:52:37 2009 New Revision: 72124 Log: Merged revisions 72123 via svnmerge from svn+ssh://pythondev at svn.python.org/python/branches/py3k ........ r72123 | r.david.murray | 2009-04-29 17:50:39 -0400 (Wed, 29 Apr 2009) | 2 lines Document the fact that 'compname' and 'comptype' are bytes. ........ Modified: python/branches/release30-maint/ (props changed) python/branches/release30-maint/Doc/library/aifc.rst python/branches/release30-maint/Lib/test/test_aifc.py Modified: python/branches/release30-maint/Doc/library/aifc.rst ============================================================================== --- python/branches/release30-maint/Doc/library/aifc.rst (original) +++ python/branches/release30-maint/Doc/library/aifc.rst Wed Apr 29 23:52:37 2009 @@ -74,14 +74,16 @@ .. method:: aifc.getcomptype() - Return a four-character string describing the type of compression used in the - audio file. For AIFF files, the returned value is ``'NONE'``. + Return a bytes array of length 4 describing the type of compression + used in the audio file. For AIFF files, the returned value is + ``b'NONE'``. .. method:: aifc.getcompname() - Return a human-readable description of the type of compression used in the audio - file. For AIFF files, the returned value is ``'not compressed'``. + Return a bytes array convertible to a human-readable description + of the type of compression used in the audio file. For AIFF files, + the returned value is ``b'not compressed'``. .. method:: aifc.getparams() @@ -180,11 +182,12 @@ single: A-LAW single: G.722 - Specify the compression type. If not specified, the audio data will not be - compressed. In AIFF files, compression is not possible. The name parameter - should be a human-readable description of the compression type, the type - parameter should be a four-character string. Currently the following - compression types are supported: NONE, ULAW, ALAW, G722. + Specify the compression type. If not specified, the audio data will + not be compressed. In AIFF files, compression is not possible. + The name parameter should be a human-readable description of the + compression type as a bytes array, the type parameter should be a + bytes array of length 4. Currently the following compression types + are supported: ``b'NONE'``, ``b'ULAW'``, ``b'ALAW'``, ``b'G722'``. .. method:: aifc.setparams(nchannels, sampwidth, framerate, comptype, compname) Modified: python/branches/release30-maint/Lib/test/test_aifc.py ============================================================================== --- python/branches/release30-maint/Lib/test/test_aifc.py (original) +++ python/branches/release30-maint/Lib/test/test_aifc.py Wed Apr 29 23:52:37 2009 @@ -21,8 +21,6 @@ self.assertEqual(f.getsampwidth(), 2) self.assertEqual(f.getframerate(), 48000) self.assertEqual(f.getnframes(), 14400) - # XXX: are the next two correct? The docs say/imply they are supposed - # to be strings. self.assertEqual(f.getcomptype(), b'NONE') self.assertEqual(f.getcompname(), b'not compressed') self.assertEqual( From python-checkins at python.org Wed Apr 29 23:53:47 2009 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 29 Apr 2009 23:53:47 +0200 (CEST) Subject: [Python-checkins] r72125 - python/branches/py3k/Lib/io.py Message-ID: <20090429215347.C1CFA1E4011@bag.python.org> Author: benjamin.peterson Date: Wed Apr 29 23:53:47 2009 New Revision: 72125 Log: add UnsupportedOperation to __all__ Modified: python/branches/py3k/Lib/io.py Modified: python/branches/py3k/Lib/io.py ============================================================================== --- python/branches/py3k/Lib/io.py (original) +++ python/branches/py3k/Lib/io.py Wed Apr 29 23:53:47 2009 @@ -53,7 +53,7 @@ "BytesIO", "StringIO", "BufferedIOBase", "BufferedReader", "BufferedWriter", "BufferedRWPair", "BufferedRandom", "TextIOBase", "TextIOWrapper", - "SEEK_SET", "SEEK_CUR", "SEEK_END"] + "UnsupportedOperation", "SEEK_SET", "SEEK_CUR", "SEEK_END"] import _io From python-checkins at python.org Wed Apr 29 23:56:53 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 29 Apr 2009 23:56:53 +0200 (CEST) Subject: [Python-checkins] r72126 - in python/trunk: Objects/floatobject.c Python/pystrtod.c Message-ID: <20090429215653.DD0DF1E4011@bag.python.org> Author: mark.dickinson Date: Wed Apr 29 23:56:53 2009 New Revision: 72126 Log: Remove format_float and use _PyOS_double_to_string instead. Modified: python/trunk/Objects/floatobject.c python/trunk/Python/pystrtod.c Modified: python/trunk/Objects/floatobject.c ============================================================================== --- python/trunk/Objects/floatobject.c (original) +++ python/trunk/Objects/floatobject.c Wed Apr 29 23:56:53 2009 @@ -299,63 +299,6 @@ /* Methods */ -static void -format_float(char *buf, size_t buflen, PyFloatObject *v, int precision) -{ - register char *cp; - int i; - - /* Subroutine for float_repr and float_print. - We want float numbers to be recognizable as such, - i.e., they should contain a decimal point or an exponent. - However, %g may print the number as an integer; - in such cases, we append ".0" to the string. */ - - assert(PyFloat_Check(v)); - _PyOS_double_to_string(buf, buflen, v->ob_fval, 'g', precision, - 0, NULL); - cp = buf; - if (*cp == '-') - cp++; - for (; *cp != '\0'; cp++) { - /* Any non-digit means it's not an integer; - this takes care of NAN and INF as well. */ - if (!isdigit(Py_CHARMASK(*cp))) - break; - } - if (*cp == '\0') { - *cp++ = '.'; - *cp++ = '0'; - *cp++ = '\0'; - return; - } - /* Checking the next three chars should be more than enough to - * detect inf or nan, even on Windows. We check for inf or nan - * at last because they are rare cases. - */ - for (i=0; *cp != '\0' && i<3; cp++, i++) { - if (isdigit(Py_CHARMASK(*cp)) || *cp == '.') - continue; - /* found something that is neither a digit nor point - * it might be a NaN or INF - */ -#ifdef Py_NAN - if (Py_IS_NAN(v->ob_fval)) { - strcpy(buf, "nan"); - } - else -#endif - if (Py_IS_INFINITY(v->ob_fval)) { - cp = buf; - if (*cp == '-') - cp++; - strcpy(cp, "inf"); - } - break; - } - -} - /* XXX PyFloat_AsStringEx should not be a public API function (for one XXX thing, its signature passes a buffer without a length; for another, XXX it isn't useful outside this file). @@ -363,7 +306,8 @@ void PyFloat_AsStringEx(char *buf, PyFloatObject *v, int precision) { - format_float(buf, 100, v, precision); + _PyOS_double_to_string(buf, 100, v->ob_fval, 'g', precision, + Py_DTSF_ADD_DOT_0, NULL); } /* Macro and helper that convert PyObject obj to a C double and store @@ -402,36 +346,21 @@ return 0; } -/* Precisions used by repr() and str(), respectively. - - The repr() precision (17 significant decimal digits) is the minimal number - that is guaranteed to have enough precision so that if the number is read - back in the exact same binary value is recreated. This is true for IEEE - floating point by design, and also happens to work for all other modern - hardware. - - The str() precision is chosen so that in most cases, the rounding noise - created by various operations is suppressed, while giving plenty of - precision for practical use. - -*/ - -#define PREC_REPR 17 -#define PREC_STR 12 - /* XXX PyFloat_AsString and PyFloat_AsReprString should be deprecated: XXX they pass a char buffer without passing a length. */ void PyFloat_AsString(char *buf, PyFloatObject *v) { - format_float(buf, 100, v, PREC_STR); + _PyOS_double_to_string(buf, 100, v->ob_fval, 's', 0, + Py_DTSF_ADD_DOT_0, NULL); } void PyFloat_AsReprString(char *buf, PyFloatObject *v) { - format_float(buf, 100, v, PREC_REPR); + _PyOS_double_to_string(buf, 100, v->ob_fval, 'r', 0, + Py_DTSF_ADD_DOT_0, NULL); } /* ARGSUSED */ @@ -439,8 +368,9 @@ float_print(PyFloatObject *v, FILE *fp, int flags) { char buf[100]; - format_float(buf, sizeof(buf), v, - (flags & Py_PRINT_RAW) ? PREC_STR : PREC_REPR); + _PyOS_double_to_string(buf, sizeof(buf), v->ob_fval, + (flags & Py_PRINT_RAW) ? 's' : 'r', + 0, Py_DTSF_ADD_DOT_0, NULL); Py_BEGIN_ALLOW_THREADS fputs(buf, fp); Py_END_ALLOW_THREADS @@ -451,8 +381,8 @@ float_repr(PyFloatObject *v) { char buf[100]; - format_float(buf, sizeof(buf), v, PREC_REPR); - + _PyOS_double_to_string(buf, sizeof(buf), v->ob_fval, 'r', 0, + Py_DTSF_ADD_DOT_0, NULL); return PyString_FromString(buf); } @@ -460,7 +390,8 @@ float_str(PyFloatObject *v) { char buf[100]; - format_float(buf, sizeof(buf), v, PREC_STR); + _PyOS_double_to_string(buf, sizeof(buf), v->ob_fval, 's', 0, + Py_DTSF_ADD_DOT_0, NULL); return PyString_FromString(buf); } Modified: python/trunk/Python/pystrtod.c ============================================================================== --- python/trunk/Python/pystrtod.c (original) +++ python/trunk/Python/pystrtod.c Wed Apr 29 23:56:53 2009 @@ -595,6 +595,20 @@ return buffer; } +/* Precisions used by repr() and str(), respectively. + + The repr() precision (17 significant decimal digits) is the minimal number + that is guaranteed to have enough precision so that if the number is read + back in the exact same binary value is recreated. This is true for IEEE + floating point by design, and also happens to work for all other modern + hardware. + + The str() precision (12 significant decimal digits) is chosen so that in + most cases, the rounding noise created by various operations is suppressed, + while giving plenty of precision for practical use. + +*/ + PyAPI_FUNC(void) _PyOS_double_to_string(char *buf, size_t buf_len, double val, char format_code, int precision, From python-checkins at python.org Wed Apr 29 23:57:15 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 29 Apr 2009 23:57:15 +0200 (CEST) Subject: [Python-checkins] r72127 - in python/trunk/Lib/test: formatfloat_testcases.txt test_float.py Message-ID: <20090429215715.851A81E4011@bag.python.org> Author: mark.dickinson Date: Wed Apr 29 23:57:15 2009 New Revision: 72127 Log: Backport some of the float formatting tests from py3k. Added: python/trunk/Lib/test/formatfloat_testcases.txt Modified: python/trunk/Lib/test/test_float.py Added: python/trunk/Lib/test/formatfloat_testcases.txt ============================================================================== --- (empty file) +++ python/trunk/Lib/test/formatfloat_testcases.txt Wed Apr 29 23:57:15 2009 @@ -0,0 +1,356 @@ +-- 'f' code formatting, with explicit precision (>= 0). Output always +-- has the given number of places after the point; zeros are added if +-- necessary to make this true. + +-- zeros +%.0f 0 -> 0 +%.1f 0 -> 0.0 +%.2f 0 -> 0.00 +%.3f 0 -> 0.000 +%.50f 0 -> 0.00000000000000000000000000000000000000000000000000 + +-- precision 0; result should never include a . +%.0f 1.5 -> 2 +%.0f 2.5 -> 2 +%.0f 3.5 -> 4 +%.0f 0.0 -> 0 +%.0f 0.1 -> 0 +%.0f 0.001 -> 0 +%.0f 10.0 -> 10 +%.0f 10.1 -> 10 +%.0f 10.01 -> 10 +%.0f 123.456 -> 123 +%.0f 1234.56 -> 1235 +%.0f 1e49 -> 9999999999999999464902769475481793196872414789632 +-- %.0f 1e50 -> 100000000000000007629769841091887003294964970946560 +%.0f 9.9999999999999987e+49 -> 99999999999999986860582406952576489172979654066176 + +-- precision 1 +%.1f 0.0001 -> 0.0 +%.1f 0.001 -> 0.0 +%.1f 0.01 -> 0.0 +%.1f 0.04 -> 0.0 +%.1f 0.06 -> 0.1 +%.1f 0.25 -> 0.2 +%.1f 0.75 -> 0.8 +%.1f 1.4 -> 1.4 +%.1f 1.5 -> 1.5 +%.1f 10.0 -> 10.0 +%.1f 1000.03 -> 1000.0 +%.1f 1234.5678 -> 1234.6 +%.1f 1234.7499 -> 1234.7 +%.1f 1234.75 -> 1234.8 + +-- precision 2 +%.2f 0.0001 -> 0.00 +%.2f 0.001 -> 0.00 +%.2f 0.004999 -> 0.00 +%.2f 0.005001 -> 0.01 +%.2f 0.01 -> 0.01 +%.2f 0.125 -> 0.12 +%.2f 0.375 -> 0.38 +%.2f 1234500 -> 1234500.00 +%.2f 1234560 -> 1234560.00 +%.2f 1234567 -> 1234567.00 +%.2f 1234567.8 -> 1234567.80 +%.2f 1234567.89 -> 1234567.89 +%.2f 1234567.891 -> 1234567.89 +%.2f 1234567.8912 -> 1234567.89 + +-- alternate form always includes a decimal point. This only +-- makes a difference when the precision is 0. +%#.0f 0 -> 0. +%#.1f 0 -> 0.0 +%#.0f 1.5 -> 2. +%#.0f 2.5 -> 2. +%#.0f 10.1 -> 10. +%#.0f 1234.56 -> 1235. +%#.1f 1.4 -> 1.4 +%#.2f 0.375 -> 0.38 + +-- if precision is omitted it defaults to 6 +%f 0 -> 0.000000 +%f 1230000 -> 1230000.000000 +%f 1234567 -> 1234567.000000 +%f 123.4567 -> 123.456700 +%f 1.23456789 -> 1.234568 +%f 0.00012 -> 0.000120 +%f 0.000123 -> 0.000123 +%f 0.00012345 -> 0.000123 +%f 0.000001 -> 0.000001 +%f 0.0000005001 -> 0.000001 +%f 0.0000004999 -> 0.000000 + +-- 'e' code formatting with explicit precision (>= 0). Output should +-- always have exactly the number of places after the point that were +-- requested. + +-- zeros +%.0e 0 -> 0e+00 +%.1e 0 -> 0.0e+00 +%.2e 0 -> 0.00e+00 +%.10e 0 -> 0.0000000000e+00 +%.50e 0 -> 0.00000000000000000000000000000000000000000000000000e+00 + +-- precision 0. no decimal point in the output +%.0e 0.01 -> 1e-02 +%.0e 0.1 -> 1e-01 +%.0e 1 -> 1e+00 +%.0e 10 -> 1e+01 +%.0e 100 -> 1e+02 +%.0e 0.012 -> 1e-02 +%.0e 0.12 -> 1e-01 +%.0e 1.2 -> 1e+00 +%.0e 12 -> 1e+01 +%.0e 120 -> 1e+02 +%.0e 123.456 -> 1e+02 +%.0e 0.000123456 -> 1e-04 +%.0e 123456000 -> 1e+08 +%.0e 0.5 -> 5e-01 +%.0e 1.4 -> 1e+00 +%.0e 1.5 -> 2e+00 +%.0e 1.6 -> 2e+00 +%.0e 2.4999999 -> 2e+00 +%.0e 2.5 -> 2e+00 +%.0e 2.5000001 -> 3e+00 +%.0e 3.499999999999 -> 3e+00 +%.0e 3.5 -> 4e+00 +%.0e 4.5 -> 4e+00 +%.0e 5.5 -> 6e+00 +%.0e 6.5 -> 6e+00 +%.0e 7.5 -> 8e+00 +%.0e 8.5 -> 8e+00 +%.0e 9.4999 -> 9e+00 +%.0e 9.5 -> 1e+01 +%.0e 10.5 -> 1e+01 +%.0e 14.999 -> 1e+01 +%.0e 15 -> 2e+01 + +-- precision 1 +%.1e 0.0001 -> 1.0e-04 +%.1e 0.001 -> 1.0e-03 +%.1e 0.01 -> 1.0e-02 +%.1e 0.1 -> 1.0e-01 +%.1e 1 -> 1.0e+00 +%.1e 10 -> 1.0e+01 +%.1e 100 -> 1.0e+02 +%.1e 120 -> 1.2e+02 +%.1e 123 -> 1.2e+02 +%.1e 123.4 -> 1.2e+02 + +-- precision 2 +%.2e 0.00013 -> 1.30e-04 +%.2e 0.000135 -> 1.35e-04 +%.2e 0.0001357 -> 1.36e-04 +%.2e 0.0001 -> 1.00e-04 +%.2e 0.001 -> 1.00e-03 +%.2e 0.01 -> 1.00e-02 +%.2e 0.1 -> 1.00e-01 +%.2e 1 -> 1.00e+00 +%.2e 10 -> 1.00e+01 +%.2e 100 -> 1.00e+02 +%.2e 1000 -> 1.00e+03 +%.2e 1500 -> 1.50e+03 +%.2e 1590 -> 1.59e+03 +%.2e 1598 -> 1.60e+03 +%.2e 1598.7 -> 1.60e+03 +%.2e 1598.76 -> 1.60e+03 +%.2e 9999 -> 1.00e+04 + +-- omitted precision defaults to 6 +%e 0 -> 0.000000e+00 +%e 165 -> 1.650000e+02 +%e 1234567 -> 1.234567e+06 +%e 12345678 -> 1.234568e+07 +%e 1.1 -> 1.100000e+00 + +-- alternate form always contains a decimal point. This only makes +-- a difference when precision is 0. + +%#.0e 0.01 -> 1.e-02 +%#.0e 0.1 -> 1.e-01 +%#.0e 1 -> 1.e+00 +%#.0e 10 -> 1.e+01 +%#.0e 100 -> 1.e+02 +%#.0e 0.012 -> 1.e-02 +%#.0e 0.12 -> 1.e-01 +%#.0e 1.2 -> 1.e+00 +%#.0e 12 -> 1.e+01 +%#.0e 120 -> 1.e+02 +%#.0e 123.456 -> 1.e+02 +%#.0e 0.000123456 -> 1.e-04 +%#.0e 123456000 -> 1.e+08 +%#.0e 0.5 -> 5.e-01 +%#.0e 1.4 -> 1.e+00 +%#.0e 1.5 -> 2.e+00 +%#.0e 1.6 -> 2.e+00 +%#.0e 2.4999999 -> 2.e+00 +%#.0e 2.5 -> 2.e+00 +%#.0e 2.5000001 -> 3.e+00 +%#.0e 3.499999999999 -> 3.e+00 +%#.0e 3.5 -> 4.e+00 +%#.0e 4.5 -> 4.e+00 +%#.0e 5.5 -> 6.e+00 +%#.0e 6.5 -> 6.e+00 +%#.0e 7.5 -> 8.e+00 +%#.0e 8.5 -> 8.e+00 +%#.0e 9.4999 -> 9.e+00 +%#.0e 9.5 -> 1.e+01 +%#.0e 10.5 -> 1.e+01 +%#.0e 14.999 -> 1.e+01 +%#.0e 15 -> 2.e+01 +%#.1e 123.4 -> 1.2e+02 +%#.2e 0.0001357 -> 1.36e-04 + +-- 'g' code formatting. + +-- zeros +%.0g 0 -> 0 +%.1g 0 -> 0 +%.2g 0 -> 0 +%.3g 0 -> 0 +%.4g 0 -> 0 +%.10g 0 -> 0 +%.50g 0 -> 0 +%.100g 0 -> 0 + +-- precision 0 doesn't make a lot of sense for the 'g' code (what does +-- it mean to have no significant digits?); in practice, it's interpreted +-- as identical to precision 1 +%.0g 1000 -> 1e+03 +%.0g 100 -> 1e+02 +%.0g 10 -> 1e+01 +%.0g 1 -> 1 +%.0g 0.1 -> 0.1 +%.0g 0.01 -> 0.01 +%.0g 1e-3 -> 0.001 +%.0g 1e-4 -> 0.0001 +%.0g 1e-5 -> 1e-05 +%.0g 1e-6 -> 1e-06 +%.0g 12 -> 1e+01 +%.0g 120 -> 1e+02 +%.0g 1.2 -> 1 +%.0g 0.12 -> 0.1 +%.0g 0.012 -> 0.01 +%.0g 0.0012 -> 0.001 +%.0g 0.00012 -> 0.0001 +%.0g 0.000012 -> 1e-05 +%.0g 0.0000012 -> 1e-06 + +-- precision 1 identical to precision 0 +%.1g 1000 -> 1e+03 +%.1g 100 -> 1e+02 +%.1g 10 -> 1e+01 +%.1g 1 -> 1 +%.1g 0.1 -> 0.1 +%.1g 0.01 -> 0.01 +%.1g 1e-3 -> 0.001 +%.1g 1e-4 -> 0.0001 +%.1g 1e-5 -> 1e-05 +%.1g 1e-6 -> 1e-06 +%.1g 12 -> 1e+01 +%.1g 120 -> 1e+02 +%.1g 1.2 -> 1 +%.1g 0.12 -> 0.1 +%.1g 0.012 -> 0.01 +%.1g 0.0012 -> 0.001 +%.1g 0.00012 -> 0.0001 +%.1g 0.000012 -> 1e-05 +%.1g 0.0000012 -> 1e-06 + +-- precision 2 +%.2g 1000 -> 1e+03 +%.2g 100 -> 1e+02 +%.2g 10 -> 10 +%.2g 1 -> 1 +%.2g 0.1 -> 0.1 +%.2g 0.01 -> 0.01 +%.2g 0.001 -> 0.001 +%.2g 1e-4 -> 0.0001 +%.2g 1e-5 -> 1e-05 +%.2g 1e-6 -> 1e-06 +%.2g 1234 -> 1.2e+03 +%.2g 123 -> 1.2e+02 +%.2g 12.3 -> 12 +%.2g 1.23 -> 1.2 +%.2g 0.123 -> 0.12 +%.2g 0.0123 -> 0.012 +%.2g 0.00123 -> 0.0012 +%.2g 0.000123 -> 0.00012 +%.2g 0.0000123 -> 1.2e-05 + +-- alternate g formatting: always include decimal point and +-- exactly significant digits. +%#.0g 0 -> 0. +%#.1g 0 -> 0. +%#.2g 0 -> 0.0 +%#.3g 0 -> 0.00 +%#.4g 0 -> 0.000 + +%#.0g 0.2 -> 0.2 +%#.1g 0.2 -> 0.2 +%#.2g 0.2 -> 0.20 +%#.3g 0.2 -> 0.200 +%#.4g 0.2 -> 0.2000 +%#.10g 0.2 -> 0.2000000000 + +%#.0g 2 -> 2. +%#.1g 2 -> 2. +%#.2g 2 -> 2.0 +%#.3g 2 -> 2.00 +%#.4g 2 -> 2.000 + +%#.0g 20 -> 2.e+01 +%#.1g 20 -> 2.e+01 +%#.2g 20 -> 20. +%#.3g 20 -> 20.0 +%#.4g 20 -> 20.00 + +%#.0g 234.56 -> 2.e+02 +%#.1g 234.56 -> 2.e+02 +%#.2g 234.56 -> 2.3e+02 +%#.3g 234.56 -> 235. +%#.4g 234.56 -> 234.6 +%#.5g 234.56 -> 234.56 +%#.6g 234.56 -> 234.560 + +-- for repr formatting see the separate test_short_repr test in +-- test_float.py. Not all platforms use short repr for floats. + +-- str formatting. Result always includes decimal point and at +-- least one digit after the point, or an exponent. +%s 0 -> 0.0 +%s 1 -> 1.0 + +%s 0.01 -> 0.01 +%s 0.02 -> 0.02 +%s 0.03 -> 0.03 +%s 0.04 -> 0.04 +%s 0.05 -> 0.05 + +-- str truncates to 12 significant digits +%s 1.234123412341 -> 1.23412341234 +%s 1.23412341234 -> 1.23412341234 +%s 1.2341234123 -> 1.2341234123 + +-- values >= 1e11 get an exponent +%s 10 -> 10.0 +%s 100 -> 100.0 +%s 1e10 -> 10000000000.0 +%s 9.999e10 -> 99990000000.0 +%s 99999999999 -> 99999999999.0 +%s 99999999999.9 -> 99999999999.9 +%s 99999999999.99 -> 1e+11 +%s 1e11 -> 1e+11 +%s 1e12 -> 1e+12 + +-- as do values < 1e-4 +%s 1e-3 -> 0.001 +%s 1.001e-4 -> 0.0001001 +%s 1.000000000001e-4 -> 0.0001 +%s 1.00000000001e-4 -> 0.000100000000001 +%s 1.0000000001e-4 -> 0.00010000000001 +%s 1e-4 -> 0.0001 +%s 0.999999999999e-4 -> 9.99999999999e-05 +%s 0.999e-4 -> 9.99e-05 +%s 1e-5 -> 1e-05 Modified: python/trunk/Lib/test/test_float.py ============================================================================== --- python/trunk/Lib/test/test_float.py (original) +++ python/trunk/Lib/test/test_float.py Wed Apr 29 23:57:15 2009 @@ -10,6 +10,10 @@ INF = float("inf") NAN = float("nan") +#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') + class GeneralFloatCases(unittest.TestCase): def test_float(self): @@ -253,6 +257,21 @@ self.assertEquals(math.atan2(float('-1e-1000'), -1), math.atan2(-0.0, -1)) + @unittest.skipUnless(float.__getformat__("double").startswith("IEEE"), + "test requires IEEE 754 doubles") + def test_format_testfile(self): + for line in open(format_testfile): + if line.startswith('--'): + continue + line = line.strip() + if not line: + continue + + lhs, rhs = map(str.strip, line.split('->')) + fmt, arg = lhs.split() + self.assertEqual(fmt % float(arg), rhs) + self.assertEqual(fmt % -float(arg), '-' + rhs) + def test_issue5864(self): self.assertEquals(format(123.456, '.4'), '123.5') self.assertEquals(format(1234.56, '.4'), '1.235e+03') From python-checkins at python.org Wed Apr 29 23:58:05 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 29 Apr 2009 23:58:05 +0200 (CEST) Subject: [Python-checkins] r72128 - python/branches/release26-maint Message-ID: <20090429215805.A2B331E4011@bag.python.org> Author: mark.dickinson Date: Wed Apr 29 23:58:04 2009 New Revision: 72128 Log: Blocked revisions 72126-72127 via svnmerge ........ r72126 | mark.dickinson | 2009-04-29 22:56:53 +0100 (Wed, 29 Apr 2009) | 2 lines Remove format_float and use _PyOS_double_to_string instead. ........ r72127 | mark.dickinson | 2009-04-29 22:57:15 +0100 (Wed, 29 Apr 2009) | 2 lines Backport some of the float formatting tests from py3k. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Wed Apr 29 23:58:53 2009 From: python-checkins at python.org (mark.dickinson) Date: Wed, 29 Apr 2009 23:58:53 +0200 (CEST) Subject: [Python-checkins] r72129 - python/branches/py3k Message-ID: <20090429215853.170901E4011@bag.python.org> Author: mark.dickinson Date: Wed Apr 29 23:58:53 2009 New Revision: 72129 Log: Blocked revisions 72126-72127 via svnmerge ........ r72126 | mark.dickinson | 2009-04-29 22:56:53 +0100 (Wed, 29 Apr 2009) | 2 lines Remove format_float and use _PyOS_double_to_string instead. ........ r72127 | mark.dickinson | 2009-04-29 22:57:15 +0100 (Wed, 29 Apr 2009) | 2 lines Backport some of the float formatting tests from py3k. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Thu Apr 30 00:00:44 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 30 Apr 2009 00:00:44 +0200 (CEST) Subject: [Python-checkins] r72130 - python/branches/py3k/Lib/test/test_io.py Message-ID: <20090429220044.872C71E410A@bag.python.org> Author: benjamin.peterson Date: Thu Apr 30 00:00:44 2009 New Revision: 72130 Log: fix test__all__ Modified: python/branches/py3k/Lib/test/test_io.py 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 Thu Apr 30 00:00:44 2009 @@ -2089,7 +2089,7 @@ self.assertTrue(obj is not None, name) if name == "open": continue - elif "error" in name.lower(): + elif "error" in name.lower() or name == "UnsupportedOperation": self.assertTrue(issubclass(obj, Exception), name) elif not name.startswith("SEEK_"): self.assertTrue(issubclass(obj, self.IOBase)) From nnorwitz at gmail.com Thu Apr 30 00:21:18 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Wed, 29 Apr 2009 18:21:18 -0400 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20090429222117.GA19844@python.psfb.org> More important issues: ---------------------- test_ssl leaked [-403, 403, -403] references, sum=-403 Less important issues: ---------------------- test_cmd_line leaked [25, 0, 25] references, sum=50 test_popen2 leaked [0, -29, 54] references, sum=25 test_smtplib leaked [0, 96, -96] references, sum=0 test_socketserver leaked [-80, 0, 0] references, sum=-80 test_sys leaked [-21, 21, 0] references, sum=0 test_threading leaked [48, 48, 48] references, sum=144 test_urllib2_localnet leaked [282, -276, 3] references, sum=9 test_xmlrpc leaked [0, 85, 85] references, sum=170 From python-checkins at python.org Thu Apr 30 00:43:35 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 30 Apr 2009 00:43:35 +0200 (CEST) Subject: [Python-checkins] r72131 - python/trunk/Lib/test/test_shutil.py Message-ID: <20090429224335.7138E1E4016@bag.python.org> Author: benjamin.peterson Date: Thu Apr 30 00:43:35 2009 New Revision: 72131 Log: fix test_shutil on ZFS #5676 Modified: python/trunk/Lib/test/test_shutil.py Modified: python/trunk/Lib/test/test_shutil.py ============================================================================== --- python/trunk/Lib/test/test_shutil.py (original) +++ python/trunk/Lib/test/test_shutil.py Thu Apr 30 00:43:35 2009 @@ -45,9 +45,23 @@ shutil.rmtree(TESTFN) def check_args_to_onerror(self, func, arg, exc): + # test_rmtree_errors deliberately runs rmtree + # on a directory that is chmod 400, which will fail. + # This function is run when shutil.rmtree fails. + # 99.9% of the time it initially fails to remove + # a file in the directory, so the first time through + # func is os.remove. + # However, some Linux machines running ZFS on + # FUSE experienced a failure earlier in the process + # at os.listdir. The first failure may legally + # be either. if self.errorState == 0: - self.assertEqual(func, os.remove) - self.assertEqual(arg, self.childpath) + if func is os.remove: + self.assertEqual(arg, self.childpath) + else: + self.assertIs(func, os.listdir, + "func must be either os.remove or os.listdir") + self.assertEqual(arg, TESTFN) self.failUnless(issubclass(exc[0], OSError)) self.errorState = 1 else: From python-checkins at python.org Thu Apr 30 00:44:08 2009 From: python-checkins at python.org (georg.brandl) Date: Thu, 30 Apr 2009 00:44:08 +0200 (CEST) Subject: [Python-checkins] r72132 - python/trunk/Doc/howto/regex.rst Message-ID: <20090429224408.01D191E4016@bag.python.org> Author: georg.brandl Date: Thu Apr 30 00:44:07 2009 New Revision: 72132 Log: #5878: fix repr of re object. Modified: python/trunk/Doc/howto/regex.rst Modified: python/trunk/Doc/howto/regex.rst ============================================================================== --- python/trunk/Doc/howto/regex.rst (original) +++ python/trunk/Doc/howto/regex.rst Thu Apr 30 00:44:07 2009 @@ -264,7 +264,7 @@ >>> import re >>> p = re.compile('ab*') >>> print p - + <_sre.SRE_Pattern object at 80b4150> :func:`re.compile` also accepts an optional *flags* argument, used to enable various special features and syntax variations. We'll go over the available From python-checkins at python.org Thu Apr 30 00:44:15 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 30 Apr 2009 00:44:15 +0200 (CEST) Subject: [Python-checkins] r72133 - python/trunk/Lib/test/regrtest.py Message-ID: <20090429224415.5A80A1E4016@bag.python.org> Author: benjamin.peterson Date: Thu Apr 30 00:44:15 2009 New Revision: 72133 Log: make sure mode is removable while cleaning up test droppings Modified: python/trunk/Lib/test/regrtest.py Modified: python/trunk/Lib/test/regrtest.py ============================================================================== --- python/trunk/Lib/test/regrtest.py (original) +++ python/trunk/Lib/test/regrtest.py Thu Apr 30 00:44:15 2009 @@ -620,6 +620,7 @@ def cleanup_test_droppings(testname, verbose): import shutil + import stat # Try to clean up junk commonly left behind. While tests shouldn't leave # any files or directories behind, when a test fails that can be tedious @@ -644,6 +645,10 @@ if verbose: print "%r left behind %s %r" % (testname, kind, name) try: + # if we have chmod, fix possible permissions problems + # that might prevent cleanup + if (hasattr(os, 'chmod')): + os.chmod(name, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) nuker(name) except Exception, msg: print >> sys.stderr, ("%r left behind %s %r and it couldn't be " From python-checkins at python.org Thu Apr 30 02:06:33 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 30 Apr 2009 02:06:33 +0200 (CEST) Subject: [Python-checkins] r72134 - python/trunk/Lib/test/test_aifc.py Message-ID: <20090430000633.2C9DE1E4014@bag.python.org> Author: benjamin.peterson Date: Thu Apr 30 02:06:33 2009 New Revision: 72134 Log: make sure to close file Modified: python/trunk/Lib/test/test_aifc.py Modified: python/trunk/Lib/test/test_aifc.py ============================================================================== --- python/trunk/Lib/test/test_aifc.py (original) +++ python/trunk/Lib/test/test_aifc.py Thu Apr 30 02:06:33 2009 @@ -27,7 +27,7 @@ def test_skipunknown(self): #Issue 2245 #This file contains chunk types aifc doesn't recognize. - f = aifc.open(self.sndfilepath) + self.f = aifc.open(self.sndfilepath) def test_params(self): f = self.f = aifc.open(self.sndfilepath) From buildbot at python.org Thu Apr 30 02:20:40 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 30 Apr 2009 00:20:40 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu trunk Message-ID: <20090430002040.E98EF1E4226@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%20trunk/builds/1213 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: benjamin.peterson,georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_time make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Thu Apr 30 02:23:11 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 30 Apr 2009 02:23:11 +0200 (CEST) Subject: [Python-checkins] r72135 - python/trunk/Lib/aifc.py Message-ID: <20090430002311.7748A1E401E@bag.python.org> Author: benjamin.peterson Date: Thu Apr 30 02:23:11 2009 New Revision: 72135 Log: prevent ref cycles by removing bound method on close() Modified: python/trunk/Lib/aifc.py Modified: python/trunk/Lib/aifc.py ============================================================================== --- python/trunk/Lib/aifc.py (original) +++ python/trunk/Lib/aifc.py Thu Apr 30 02:23:11 2009 @@ -732,6 +732,8 @@ if self._comp: self._comp.CloseCompressor() self._comp = None + # Prevent ref cycles + self._convert = None self._file.flush() self._file = None From python-checkins at python.org Thu Apr 30 02:30:09 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 30 Apr 2009 02:30:09 +0200 (CEST) Subject: [Python-checkins] r72136 - in python/branches/py3k: Lib/aifc.py Message-ID: <20090430003009.4C46F1E41C8@bag.python.org> Author: benjamin.peterson Date: Thu Apr 30 02:30:08 2009 New Revision: 72136 Log: Merged revisions 72135 via svnmerge from svn+ssh://pythondev at svn.python.org/python/trunk ........ r72135 | benjamin.peterson | 2009-04-29 19:23:11 -0500 (Wed, 29 Apr 2009) | 1 line prevent ref cycles by removing bound method on close() ........ Modified: python/branches/py3k/ (props changed) python/branches/py3k/Lib/aifc.py Modified: python/branches/py3k/Lib/aifc.py ============================================================================== --- python/branches/py3k/Lib/aifc.py (original) +++ python/branches/py3k/Lib/aifc.py Thu Apr 30 02:30:08 2009 @@ -690,6 +690,8 @@ self._datalength != self._datawritten or \ self._marklength: self._patchheader() + # Prevent ref cycles + self._convert = None self._file.flush() self._file = None From buildbot at python.org Thu Apr 30 02:53:12 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 30 Apr 2009 00:53:12 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu 3.x Message-ID: <20090430005312.4E78C1E4065@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%203.x/builds/845 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_os make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Thu Apr 30 02:58:58 2009 From: python-checkins at python.org (eric.smith) Date: Thu, 30 Apr 2009 02:58:58 +0200 (CEST) Subject: [Python-checkins] r72137 - in python/trunk: Include/complexobject.h Lib/test/test_complex.py Misc/NEWS Objects/complexobject.c Objects/stringlib/formatter.h Python/formatter_string.c Python/formatter_unicode.c Message-ID: <20090430005858.C888C1E404E@bag.python.org> Author: eric.smith Date: Thu Apr 30 02:58:58 2009 New Revision: 72137 Log: Issue #1588: Add complex.__format__. Modified: python/trunk/Include/complexobject.h python/trunk/Lib/test/test_complex.py python/trunk/Misc/NEWS python/trunk/Objects/complexobject.c python/trunk/Objects/stringlib/formatter.h python/trunk/Python/formatter_string.c python/trunk/Python/formatter_unicode.c Modified: python/trunk/Include/complexobject.h ============================================================================== --- python/trunk/Include/complexobject.h (original) +++ python/trunk/Include/complexobject.h Thu Apr 30 02:58:58 2009 @@ -54,6 +54,12 @@ PyAPI_FUNC(double) PyComplex_ImagAsDouble(PyObject *op); PyAPI_FUNC(Py_complex) PyComplex_AsCComplex(PyObject *op); +/* Format the object based on the format_spec, as defined in PEP 3101 + (Advanced String Formatting). */ +PyAPI_FUNC(PyObject *) _PyComplex_FormatAdvanced(PyObject *obj, + char *format_spec, + Py_ssize_t format_spec_len); + #ifdef __cplusplus } #endif Modified: python/trunk/Lib/test/test_complex.py ============================================================================== --- python/trunk/Lib/test/test_complex.py (original) +++ python/trunk/Lib/test/test_complex.py Thu Apr 30 02:58:58 2009 @@ -458,7 +458,66 @@ self.assertFloatsAreIdentical(0.0 + z.imag, 0.0 + roundtrip.imag) + def test_format(self): + # empty format string is same as str() + self.assertEqual(format(1+3j, ''), str(1+3j)) + self.assertEqual(format(1.5+3.5j, ''), str(1.5+3.5j)) + self.assertEqual(format(3j, ''), str(3j)) + self.assertEqual(format(3.2j, ''), str(3.2j)) + self.assertEqual(format(3+0j, ''), str(3+0j)) + self.assertEqual(format(3.2+0j, ''), str(3.2+0j)) + self.assertEqual(format(1+3j, 'g'), '1+3j') + self.assertEqual(format(3j, 'g'), '0+3j') + self.assertEqual(format(1.5+3.5j, 'g'), '1.5+3.5j') + + self.assertEqual(format(1.5+3.5j, '+g'), '+1.5+3.5j') + self.assertEqual(format(1.5-3.5j, '+g'), '+1.5-3.5j') + self.assertEqual(format(1.5-3.5j, '-g'), '1.5-3.5j') + self.assertEqual(format(1.5+3.5j, ' g'), ' 1.5+3.5j') + self.assertEqual(format(1.5-3.5j, ' g'), ' 1.5-3.5j') + self.assertEqual(format(-1.5+3.5j, ' g'), '-1.5+3.5j') + self.assertEqual(format(-1.5-3.5j, ' g'), '-1.5-3.5j') + + self.assertEqual(format(-1.5-3.5e-20j, 'g'), '-1.5-3.5e-20j') + self.assertEqual(format(-1.5-3.5j, 'f'), '-1.500000-3.500000j') + self.assertEqual(format(-1.5-3.5j, 'F'), '-1.500000-3.500000j') + self.assertEqual(format(-1.5-3.5j, 'e'), '-1.500000e+00-3.500000e+00j') + self.assertEqual(format(-1.5-3.5j, '.2e'), '-1.50e+00-3.50e+00j') + self.assertEqual(format(-1.5-3.5j, '.2E'), '-1.50E+00-3.50E+00j') + self.assertEqual(format(-1.5e10-3.5e5j, '.2G'), '-1.5E+10-3.5E+05j') + + self.assertEqual(format(1.5+3j, '<20g'), '1.5+3j ') + self.assertEqual(format(1.5+3j, '*<20g'), '1.5+3j**************') + self.assertEqual(format(1.5+3j, '>20g'), ' 1.5+3j') + self.assertEqual(format(1.5+3j, '^20g'), ' 1.5+3j ') + self.assertEqual(format(1.5+3j, '<20'), '(1.5+3j) ') + self.assertEqual(format(1.5+3j, '>20'), ' (1.5+3j)') + self.assertEqual(format(1.5+3j, '^20'), ' (1.5+3j) ') + self.assertEqual(format(1.123-3.123j, '^20.2'), ' (1.1-3.1j) ') + + self.assertEqual(format(1.5+3j, '<20.2f'), '1.50+3.00j ') + self.assertEqual(format(1.5e20+3j, '<20.2f'), '150000000000000000000.00+3.00j') + self.assertEqual(format(1.5e20+3j, '>40.2f'), ' 150000000000000000000.00+3.00j') + self.assertEqual(format(1.5e20+3j, '^40,.2f'), ' 150,000,000,000,000,000,000.00+3.00j ') + self.assertEqual(format(1.5e21+3j, '^40,.2f'), ' 1,500,000,000,000,000,000,000.00+3.00j ') + self.assertEqual(format(1.5e21+3000j, ',.2f'), '1,500,000,000,000,000,000,000.00+3,000.00j') + + # alternate is invalid + self.assertRaises(ValueError, (1.5+0.5j).__format__, '#f') + + # zero padding is invalid + self.assertRaises(ValueError, (1.5+0.5j).__format__, '010f') + + # '=' alignment is invalid + self.assertRaises(ValueError, (1.5+3j).__format__, '=20') + + # integer presentation types are an error + for t in 'bcdoxX': + self.assertRaises(ValueError, (1.5+0.5j).__format__, t) + + # make sure everything works in ''.format() + self.assertEqual('*{0:.3f}*'.format(3.14159+2.71828j), '*3.142+2.718j*') def test_main(): test_support.run_unittest(ComplexTest) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Thu Apr 30 02:58:58 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #1588: Add complex.__format__. For example, + format(complex(1, 2./3), '.5') now produces a sensible result. + - Issue #5864: Fix empty format code formatting for floats so that it never gives more than the requested number of significant digits. @@ -45,7 +48,7 @@ some builtin types. - Issue #1869: fix a couple of minor round() issues. round(5e15+1) - was giving 5e15+2; round(-0.0) was losing the sign of the zero. + was giving 5e15+2; round(-0.0) was losing the sign of the zero. - Issue #5759: float() didn't call __float__ on str subclasses. Modified: python/trunk/Objects/complexobject.c ============================================================================== --- python/trunk/Objects/complexobject.c (original) +++ python/trunk/Objects/complexobject.c Thu Apr 30 02:58:58 2009 @@ -838,6 +838,41 @@ return Py_BuildValue("(dd)", c.real, c.imag); } +PyDoc_STRVAR(complex__format__doc, +"complex.__format__() -> str\n" +"\n" +"Converts to a string according to format_spec."); + +static PyObject * +complex__format__(PyObject* self, PyObject* args) +{ + PyObject *format_spec; + + if (!PyArg_ParseTuple(args, "O:__format__", &format_spec)) + return NULL; + if (PyBytes_Check(format_spec)) + return _PyComplex_FormatAdvanced(self, + PyBytes_AS_STRING(format_spec), + PyBytes_GET_SIZE(format_spec)); + if (PyUnicode_Check(format_spec)) { + /* Convert format_spec to a str */ + PyObject *result; + PyObject *str_spec = PyObject_Str(format_spec); + + if (str_spec == NULL) + return NULL; + + result = _PyComplex_FormatAdvanced(self, + PyBytes_AS_STRING(str_spec), + PyBytes_GET_SIZE(str_spec)); + + Py_DECREF(str_spec); + return result; + } + PyErr_SetString(PyExc_TypeError, "__format__ requires str or unicode"); + return NULL; +} + #if 0 static PyObject * complex_is_finite(PyObject *self) @@ -862,6 +897,8 @@ complex_is_finite_doc}, #endif {"__getnewargs__", (PyCFunction)complex_getnewargs, METH_NOARGS}, + {"__format__", (PyCFunction)complex__format__, + METH_VARARGS, complex__format__doc}, {NULL, NULL} /* sentinel */ }; Modified: python/trunk/Objects/stringlib/formatter.h ============================================================================== --- python/trunk/Objects/stringlib/formatter.h (original) +++ python/trunk/Objects/stringlib/formatter.h Thu Apr 30 02:58:58 2009 @@ -11,6 +11,7 @@ FORMAT_STRING FORMAT_LONG FORMAT_FLOAT + FORMAT_COMPLEX to be whatever you want the public names of these functions to be. These are the only non-static functions defined here. */ @@ -261,7 +262,54 @@ return 1; } -#if defined FORMAT_FLOAT || defined FORMAT_LONG +/* Calculate the padding needed. */ +static void +calc_padding(Py_ssize_t nchars, Py_ssize_t width, STRINGLIB_CHAR align, + Py_ssize_t *n_lpadding, Py_ssize_t *n_rpadding, + Py_ssize_t *n_total) +{ + if (width >= 0) { + if (nchars > width) + *n_total = nchars; + else + *n_total = width; + } + else { + /* not specified, use all of the chars and no more */ + *n_total = nchars; + } + + /* figure out how much leading space we need, based on the + aligning */ + if (align == '>') + *n_lpadding = *n_total - nchars; + else if (align == '^') + *n_lpadding = (*n_total - nchars) / 2; + else + *n_lpadding = 0; + + *n_rpadding = *n_total - nchars - *n_lpadding; +} + +/* Do the padding, and return a pointer to where the caller-supplied + content goes. */ +static STRINGLIB_CHAR * +fill_padding(STRINGLIB_CHAR *p, Py_ssize_t nchars, STRINGLIB_CHAR fill_char, + Py_ssize_t n_lpadding, Py_ssize_t n_rpadding) +{ + /* Pad on left. */ + if (n_lpadding) + STRINGLIB_FILL(p, fill_char, n_lpadding); + + /* Pad on right. */ + if (n_rpadding) + STRINGLIB_FILL(p + nchars + n_lpadding, fill_char, n_rpadding); + + /* Pointer to the user content. */ + return p + n_lpadding; +} + +#if defined FORMAT_FLOAT || defined FORMAT_LONG || defined FORMAT_COMPLEX /************************************************************************/ /*********** common routines for numeric formatting *********************/ /************************************************************************/ @@ -304,6 +352,7 @@ the n_grouped_digits width. */ } NumberFieldWidths; + /* Given a number of the form: digits[remainder] where ptr points to the start and end points to the end, find where @@ -564,7 +613,7 @@ } } -#endif /* FORMAT_FLOAT || FORMAT_LONG */ +#endif /* FORMAT_FLOAT || FORMAT_LONG || FORMAT_COMPLEX */ /************************************************************************/ /*********** string formatting ******************************************/ @@ -573,10 +622,10 @@ static PyObject * format_string_internal(PyObject *value, const InternalFormatSpec *format) { - Py_ssize_t width; /* total field width */ Py_ssize_t lpad; - STRINGLIB_CHAR *dst; - STRINGLIB_CHAR *src = STRINGLIB_STR(value); + Py_ssize_t rpad; + Py_ssize_t total; + STRINGLIB_CHAR *p; Py_ssize_t len = STRINGLIB_LEN(value); PyObject *result = NULL; @@ -609,56 +658,20 @@ len = format->precision; } - if (format->width >= 0) { - width = format->width; - - /* but use at least len characters */ - if (len > width) { - width = len; - } - } - else { - /* not specified, use all of the chars and no more */ - width = len; - } + calc_padding(len, format->width, format->align, &lpad, &rpad, &total); /* allocate the resulting string */ - result = STRINGLIB_NEW(NULL, width); + result = STRINGLIB_NEW(NULL, total); if (result == NULL) goto done; - /* now write into that space */ - dst = STRINGLIB_STR(result); + /* Write into that space. First the padding. */ + p = fill_padding(STRINGLIB_STR(result), len, + format->fill_char=='\0'?' ':format->fill_char, + lpad, rpad); - /* figure out how much leading space we need, based on the - aligning */ - if (format->align == '>') - lpad = width - len; - else if (format->align == '^') - lpad = (width - len) / 2; - else - lpad = 0; - - /* if right aligning, increment the destination allow space on the - left */ - memcpy(dst + lpad, src, len * sizeof(STRINGLIB_CHAR)); - - /* do any padding */ - if (width > len) { - STRINGLIB_CHAR fill_char = format->fill_char; - if (fill_char == '\0') { - /* use the default, if not specified */ - fill_char = ' '; - } - - /* pad on left */ - if (lpad) - STRINGLIB_FILL(dst, fill_char, lpad); - - /* pad on right */ - if (width - len - lpad) - STRINGLIB_FILL(dst + len + lpad, fill_char, width - len - lpad); - } + /* Then the source string. */ + memcpy(p, STRINGLIB_STR(value), len * sizeof(STRINGLIB_CHAR)); done: return result; @@ -998,6 +1011,231 @@ #endif /* FORMAT_FLOAT */ /************************************************************************/ +/*********** complex formatting *****************************************/ +/************************************************************************/ + +#ifdef FORMAT_COMPLEX + +static PyObject * +format_complex_internal(PyObject *value, + const InternalFormatSpec *format) +{ + double re; + double im; + char *re_buf = NULL; /* buffer returned from PyOS_double_to_string */ + char *im_buf = NULL; /* buffer returned from PyOS_double_to_string */ + + InternalFormatSpec tmp_format = *format; + Py_ssize_t n_re_digits; + Py_ssize_t n_im_digits; + Py_ssize_t n_re_remainder; + Py_ssize_t n_im_remainder; + Py_ssize_t n_re_total; + Py_ssize_t n_im_total; + int re_has_decimal; + int im_has_decimal; + Py_ssize_t precision = format->precision; + STRINGLIB_CHAR type = format->type; + STRINGLIB_CHAR *p_re; + STRINGLIB_CHAR *p_im; + NumberFieldWidths re_spec; + NumberFieldWidths im_spec; + int flags = 0; + PyObject *result = NULL; + STRINGLIB_CHAR *p; + STRINGLIB_CHAR re_sign_char = '\0'; + STRINGLIB_CHAR im_sign_char = '\0'; + int re_float_type; /* Used to see if we have a nan, inf, or regular float. */ + int im_float_type; + int add_parens = 0; + int skip_re = 0; + Py_ssize_t lpad; + Py_ssize_t rpad; + Py_ssize_t total; + +#if STRINGLIB_IS_UNICODE + Py_UNICODE *re_unicode_tmp = NULL; + Py_UNICODE *im_unicode_tmp = NULL; +#endif + + /* Locale settings, either from the actual locale or + from a hard-code pseudo-locale */ + LocaleInfo locale; + + /* Alternate is not allowed on complex. */ + if (format->alternate) { + PyErr_SetString(PyExc_ValueError, + "Alternate form (#) not allowed in complex format " + "specifier"); + goto done; + } + + /* Neither is zero pading. */ + if (format->fill_char == '0') { + PyErr_SetString(PyExc_ValueError, + "Zero padding is not allowed in complex format " + "specifier"); + goto done; + } + + /* Neither is '=' alignment . */ + if (format->align == '=') { + PyErr_SetString(PyExc_ValueError, + "'=' alignment flag is not allowed in complex format " + "specifier"); + goto done; + } + + re = PyComplex_RealAsDouble(value); + if (re == -1.0 && PyErr_Occurred()) + goto done; + im = PyComplex_ImagAsDouble(value); + if (im == -1.0 && PyErr_Occurred()) + goto done; + + if (type == '\0') { + /* Omitted type specifier. Should be like str(self). */ + type = 'g'; + add_parens = 1; + if (re == 0.0) + skip_re = 1; + } + + if (type == 'n') + /* 'n' is the same as 'g', except for the locale used to + format the result. We take care of that later. */ + type = 'g'; + + /* 'F' is the same as 'f', per the PEP */ + if (type == 'F') + type = 'f'; + + if (precision < 0) + precision = 6; + + /* Cast "type", because if we're in unicode we need to pass a + 8-bit char. This is safe, because we've restricted what "type" + can be. */ + re_buf = PyOS_double_to_string(re, (char)type, precision, flags, + &re_float_type); + if (re_buf == NULL) + goto done; + im_buf = PyOS_double_to_string(im, (char)type, precision, flags, + &im_float_type); + if (im_buf == NULL) + goto done; + + n_re_digits = strlen(re_buf); + n_im_digits = strlen(im_buf); + + /* Since there is no unicode version of PyOS_double_to_string, + just use the 8 bit version and then convert to unicode. */ +#if STRINGLIB_IS_UNICODE + re_unicode_tmp = (Py_UNICODE*)PyMem_Malloc((n_re_digits)*sizeof(Py_UNICODE)); + if (re_unicode_tmp == NULL) { + PyErr_NoMemory(); + goto done; + } + strtounicode(re_unicode_tmp, re_buf, n_re_digits); + p_re = re_unicode_tmp; + + im_unicode_tmp = (Py_UNICODE*)PyMem_Malloc((n_im_digits)*sizeof(Py_UNICODE)); + if (im_unicode_tmp == NULL) { + PyErr_NoMemory(); + goto done; + } + strtounicode(im_unicode_tmp, im_buf, n_im_digits); + p_im = im_unicode_tmp; +#else + p_re = re_buf; + p_im = im_buf; +#endif + + /* Is a sign character present in the output? If so, remember it + and skip it */ + if (*p_re == '-') { + re_sign_char = *p_re; + ++p_re; + --n_re_digits; + } + if (*p_im == '-') { + im_sign_char = *p_im; + ++p_im; + --n_im_digits; + } + + /* Determine if we have any "remainder" (after the digits, might include + decimal or exponent or both (or neither)) */ + parse_number(p_re, n_re_digits, &n_re_remainder, &re_has_decimal); + parse_number(p_im, n_im_digits, &n_im_remainder, &im_has_decimal); + + /* Determine the grouping, separator, and decimal point, if any. */ + get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE : + (format->thousands_separators ? + LT_DEFAULT_LOCALE : + LT_NO_LOCALE), + &locale); + + /* Turn off any padding. We'll do it later after we've composed + the numbers without padding. */ + tmp_format.fill_char = '\0'; + tmp_format.align = '\0'; + tmp_format.width = -1; + + /* Calculate how much memory we'll need. */ + n_re_total = calc_number_widths(&re_spec, 0, re_sign_char, p_re, + n_re_digits, n_re_remainder, + re_has_decimal, &locale, &tmp_format); + + /* Same formatting, but always include a sign. */ + tmp_format.sign = '+'; + n_im_total = calc_number_widths(&im_spec, 0, im_sign_char, p_im, + n_im_digits, n_im_remainder, + im_has_decimal, &locale, &tmp_format); + + if (skip_re) + n_re_total = 0; + + /* Add 1 for the 'j', and optionally 2 for parens. */ + calc_padding(n_re_total + n_im_total + 1 + add_parens * 2, + format->width, format->align, &lpad, &rpad, &total); + + result = STRINGLIB_NEW(NULL, total); + if (result == NULL) + goto done; + + /* Populate the memory. First, the padding. */ + p = fill_padding(STRINGLIB_STR(result), + n_re_total + n_im_total + 1 + add_parens * 2, + format->fill_char=='\0' ? ' ' : format->fill_char, + lpad, rpad); + + if (add_parens) + *p++ = '('; + + if (!skip_re) { + fill_number(p, &re_spec, p_re, n_re_digits, NULL, 0, &locale, 0); + p += n_re_total; + } + fill_number(p, &im_spec, p_im, n_im_digits, NULL, 0, &locale, 0); + p += n_im_total; + *p++ = 'j'; + + if (add_parens) + *p++ = ')'; + +done: + PyMem_Free(re_buf); + PyMem_Free(im_buf); +#if STRINGLIB_IS_UNICODE + PyMem_Free(re_unicode_tmp); + PyMem_Free(im_unicode_tmp); +#endif + return result; +} +#endif /* FORMAT_COMPLEX */ + +/************************************************************************/ /*********** built in formatters ****************************************/ /************************************************************************/ PyObject * @@ -1196,3 +1434,50 @@ return result; } #endif /* FORMAT_FLOAT */ + +#ifdef FORMAT_COMPLEX +PyObject * +FORMAT_COMPLEX(PyObject *obj, + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len) +{ + PyObject *result = NULL; + InternalFormatSpec format; + + /* check for the special case of zero length format spec, make + it equivalent to str(obj) */ + if (format_spec_len == 0) { + result = STRINGLIB_TOSTR(obj); + goto done; + } + + /* parse the format_spec */ + if (!parse_internal_render_format_spec(format_spec, + format_spec_len, + &format, '\0')) + goto done; + + /* type conversion? */ + switch (format.type) { + case '\0': /* No format code: like 'g', but with at least one decimal. */ + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': + case 'n': + /* no conversion, already a complex. do the formatting */ + result = format_complex_internal(obj, &format); + break; + + default: + /* unknown */ + unknown_presentation_type(format.type, obj->ob_type->tp_name); + goto done; + } + +done: + return result; +} +#endif /* FORMAT_COMPLEX */ Modified: python/trunk/Python/formatter_string.c ============================================================================== --- python/trunk/Python/formatter_string.c (original) +++ python/trunk/Python/formatter_string.c Thu Apr 30 02:58:58 2009 @@ -6,9 +6,10 @@ #include "Python.h" #include "../Objects/stringlib/stringdefs.h" -#define FORMAT_STRING _PyBytes_FormatAdvanced -#define FORMAT_LONG _PyLong_FormatAdvanced -#define FORMAT_INT _PyInt_FormatAdvanced -#define FORMAT_FLOAT _PyFloat_FormatAdvanced +#define FORMAT_STRING _PyBytes_FormatAdvanced +#define FORMAT_LONG _PyLong_FormatAdvanced +#define FORMAT_INT _PyInt_FormatAdvanced +#define FORMAT_FLOAT _PyFloat_FormatAdvanced +#define FORMAT_COMPLEX _PyComplex_FormatAdvanced #include "../Objects/stringlib/formatter.h" Modified: python/trunk/Python/formatter_unicode.c ============================================================================== --- python/trunk/Python/formatter_unicode.c (original) +++ python/trunk/Python/formatter_unicode.c Thu Apr 30 02:58:58 2009 @@ -9,9 +9,9 @@ #define FORMAT_STRING _PyUnicode_FormatAdvanced -/* don't define FORMAT_LONG and FORMAT_FLOAT, since we can live - with only the string versions of those. The builtin format() - will convert them to unicode. */ +/* don't define FORMAT_LONG, FORMAT_FLOAT, and FORMAT_COMPLEX, since + we can live with only the string versions of those. The builtin + format() will convert them to unicode. */ #include "../Objects/stringlib/formatter.h" From python-checkins at python.org Thu Apr 30 02:59:30 2009 From: python-checkins at python.org (eric.smith) Date: Thu, 30 Apr 2009 02:59:30 +0200 (CEST) Subject: [Python-checkins] r72138 - python/branches/release26-maint Message-ID: <20090430005930.108031E404E@bag.python.org> Author: eric.smith Date: Thu Apr 30 02:59:29 2009 New Revision: 72138 Log: Blocked revisions 72137 via svnmerge ........ r72137 | eric.smith | 2009-04-29 20:58:58 -0400 (Wed, 29 Apr 2009) | 1 line Issue #1588: Add complex.__format__. ........ Modified: python/branches/release26-maint/ (props changed) From python-checkins at python.org Thu Apr 30 02:59:58 2009 From: python-checkins at python.org (eric.smith) Date: Thu, 30 Apr 2009 02:59:58 +0200 (CEST) Subject: [Python-checkins] r72139 - python/branches/py3k Message-ID: <20090430005958.6A6531E404E@bag.python.org> Author: eric.smith Date: Thu Apr 30 02:59:58 2009 New Revision: 72139 Log: Blocked revisions 72137 via svnmerge ........ r72137 | eric.smith | 2009-04-29 20:58:58 -0400 (Wed, 29 Apr 2009) | 1 line Issue #1588: Add complex.__format__. ........ Modified: python/branches/py3k/ (props changed) From python-checkins at python.org Thu Apr 30 03:00:35 2009 From: python-checkins at python.org (eric.smith) Date: Thu, 30 Apr 2009 03:00:35 +0200 (CEST) Subject: [Python-checkins] r72140 - in python/branches/py3k: Include/complexobject.h Lib/test/test_complex.py Misc/NEWS Objects/complexobject.c Objects/stringlib/formatter.h Python/formatter_unicode.c Message-ID: <20090430010035.CD82D1E414F@bag.python.org> Author: eric.smith Date: Thu Apr 30 03:00:33 2009 New Revision: 72140 Log: Issue #1588: Add complex.__format__. Modified: python/branches/py3k/Include/complexobject.h python/branches/py3k/Lib/test/test_complex.py python/branches/py3k/Misc/NEWS python/branches/py3k/Objects/complexobject.c python/branches/py3k/Objects/stringlib/formatter.h python/branches/py3k/Python/formatter_unicode.c Modified: python/branches/py3k/Include/complexobject.h ============================================================================== --- python/branches/py3k/Include/complexobject.h (original) +++ python/branches/py3k/Include/complexobject.h Thu Apr 30 03:00:33 2009 @@ -54,6 +54,12 @@ PyAPI_FUNC(double) PyComplex_ImagAsDouble(PyObject *op); PyAPI_FUNC(Py_complex) PyComplex_AsCComplex(PyObject *op); +/* Format the object based on the format_spec, as defined in PEP 3101 + (Advanced String Formatting). */ +PyAPI_FUNC(PyObject *) _PyComplex_FormatAdvanced(PyObject *obj, + Py_UNICODE *format_spec, + Py_ssize_t format_spec_len); + #ifdef __cplusplus } #endif 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 Thu Apr 30 03:00:33 2009 @@ -436,7 +436,66 @@ self.assertFloatsAreIdentical(0.0 + z.imag, 0.0 + roundtrip.imag) + def test_format(self): + # empty format string is same as str() + self.assertEqual(format(1+3j, ''), str(1+3j)) + self.assertEqual(format(1.5+3.5j, ''), str(1.5+3.5j)) + self.assertEqual(format(3j, ''), str(3j)) + self.assertEqual(format(3.2j, ''), str(3.2j)) + self.assertEqual(format(3+0j, ''), str(3+0j)) + self.assertEqual(format(3.2+0j, ''), str(3.2+0j)) + self.assertEqual(format(1+3j, 'g'), '1+3j') + self.assertEqual(format(3j, 'g'), '0+3j') + self.assertEqual(format(1.5+3.5j, 'g'), '1.5+3.5j') + + self.assertEqual(format(1.5+3.5j, '+g'), '+1.5+3.5j') + self.assertEqual(format(1.5-3.5j, '+g'), '+1.5-3.5j') + self.assertEqual(format(1.5-3.5j, '-g'), '1.5-3.5j') + self.assertEqual(format(1.5+3.5j, ' g'), ' 1.5+3.5j') + self.assertEqual(format(1.5-3.5j, ' g'), ' 1.5-3.5j') + self.assertEqual(format(-1.5+3.5j, ' g'), '-1.5+3.5j') + self.assertEqual(format(-1.5-3.5j, ' g'), '-1.5-3.5j') + + self.assertEqual(format(-1.5-3.5e-20j, 'g'), '-1.5-3.5e-20j') + self.assertEqual(format(-1.5-3.5j, 'f'), '-1.500000-3.500000j') + self.assertEqual(format(-1.5-3.5j, 'F'), '-1.500000-3.500000j') + self.assertEqual(format(-1.5-3.5j, 'e'), '-1.500000e+00-3.500000e+00j') + self.assertEqual(format(-1.5-3.5j, '.2e'), '-1.50e+00-3.50e+00j') + self.assertEqual(format(-1.5-3.5j, '.2E'), '-1.50E+00-3.50E+00j') + self.assertEqual(format(-1.5e10-3.5e5j, '.2G'), '-1.5E+10-3.5E+05j') + + self.assertEqual(format(1.5+3j, '<20g'), '1.5+3j ') + self.assertEqual(format(1.5+3j, '*<20g'), '1.5+3j**************') + self.assertEqual(format(1.5+3j, '>20g'), ' 1.5+3j') + self.assertEqual(format(1.5+3j, '^20g'), ' 1.5+3j ') + self.assertEqual(format(1.5+3j, '<20'), '(1.5+3j) ') + self.assertEqual(format(1.5+3j, '>20'), ' (1.5+3j)') + self.assertEqual(format(1.5+3j, '^20'), ' (1.5+3j) ') + self.assertEqual(format(1.123-3.123j, '^20.2'), ' (1.1-3.1j) ') + + self.assertEqual(format(1.5+3j, '<20.2f'), '1.50+3.00j ') + self.assertEqual(format(1.5e20+3j, '<20.2f'), '150000000000000000000.00+3.00j') + self.assertEqual(format(1.5e20+3j, '>40.2f'), ' 150000000000000000000.00+3.00j') + self.assertEqual(format(1.5e20+3j, '^40,.2f'), ' 150,000,000,000,000,000,000.00+3.00j ') + self.assertEqual(format(1.5e21+3j, '^40,.2f'), ' 1,500,000,000,000,000,000,000.00+3.00j ') + self.assertEqual(format(1.5e21+3000j, ',.2f'), '1,500,000,000,000,000,000,000.00+3,000.00j') + + # alternate is invalid + self.assertRaises(ValueError, (1.5+0.5j).__format__, '#f') + + # zero padding is invalid + self.assertRaises(ValueError, (1.5+0.5j).__format__, '010f') + + # '=' alignment is invalid + self.assertRaises(ValueError, (1.5+3j).__format__, '=20') + + # integer presentation types are an error + for t in 'bcdoxX': + self.assertRaises(ValueError, (1.5+0.5j).__format__, t) + + # make sure everything works in ''.format() + self.assertEqual('*{0:.3f}*'.format(3.14159+2.71828j), '*3.142+2.718j*') def test_main(): support.run_unittest(ComplexTest) Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Apr 30 03:00:33 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #1588: Add complex.__format__. For example, + format(complex(1, 2./3), '.5') now produces a sensible result. + - Issue #5864: Fix empty format code formatting for floats so that it never gives more than the requested number of significant digits. Modified: python/branches/py3k/Objects/complexobject.c ============================================================================== --- python/branches/py3k/Objects/complexobject.c (original) +++ python/branches/py3k/Objects/complexobject.c Thu Apr 30 03:00:33 2009 @@ -681,6 +681,23 @@ return Py_BuildValue("(dd)", c.real, c.imag); } +PyDoc_STRVAR(complex__format__doc, +"complex.__format__() -> str\n" +"\n" +"Converts to a string according to format_spec."); + +static PyObject * +complex__format__(PyObject* self, PyObject* args) +{ + PyObject *format_spec; + + if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) + return NULL; + return _PyComplex_FormatAdvanced(self, + PyUnicode_AS_UNICODE(format_spec), + PyUnicode_GET_SIZE(format_spec)); +} + #if 0 static PyObject * complex_is_finite(PyObject *self) @@ -705,6 +722,8 @@ complex_is_finite_doc}, #endif {"__getnewargs__", (PyCFunction)complex_getnewargs, METH_NOARGS}, + {"__format__", (PyCFunction)complex__format__, + METH_VARARGS, complex__format__doc}, {NULL, NULL} /* sentinel */ }; Modified: python/branches/py3k/Objects/stringlib/formatter.h ============================================================================== --- python/branches/py3k/Objects/stringlib/formatter.h (original) +++ python/branches/py3k/Objects/stringlib/formatter.h Thu Apr 30 03:00:33 2009 @@ -11,6 +11,7 @@ FORMAT_STRING FORMAT_LONG FORMAT_FLOAT + FORMAT_COMPLEX to be whatever you want the public names of these functions to be. These are the only non-static functions defined here. */ @@ -261,7 +262,54 @@ return 1; } -#if defined FORMAT_FLOAT || defined FORMAT_LONG +/* Calculate the padding needed. */ +static void +calc_padding(Py_ssize_t nchars, Py_ssize_t width, STRINGLIB_CHAR align, + Py_ssize_t *n_lpadding, Py_ssize_t *n_rpadding, + Py_ssize_t *n_total) +{ + if (width >= 0) { + if (nchars > width) + *n_total = nchars; + else + *n_total = width; + } + else { + /* not specified, use all of the chars and no more */ + *n_total = nchars; + } + + /* figure out how much leading space we need, based on the + aligning */ + if (align == '>') + *n_lpadding = *n_total - nchars; + else if (align == '^') + *n_lpadding = (*n_total - nchars) / 2; + else + *n_lpadding = 0; + + *n_rpadding = *n_total - nchars - *n_lpadding; +} + +/* Do the padding, and return a pointer to where the caller-supplied + content goes. */ +static STRINGLIB_CHAR * +fill_padding(STRINGLIB_CHAR *p, Py_ssize_t nchars, STRINGLIB_CHAR fill_char, + Py_ssize_t n_lpadding, Py_ssize_t n_rpadding) +{ + /* Pad on left. */ + if (n_lpadding) + STRINGLIB_FILL(p, fill_char, n_lpadding); + + /* Pad on right. */ + if (n_rpadding) + STRINGLIB_FILL(p + nchars + n_lpadding, fill_char, n_rpadding); + + /* Pointer to the user content. */ + return p + n_lpadding; +} + +#if defined FORMAT_FLOAT || defined FORMAT_LONG || defined FORMAT_COMPLEX /************************************************************************/ /*********** common routines for numeric formatting *********************/ /************************************************************************/ @@ -304,6 +352,7 @@ the n_grouped_digits width. */ } NumberFieldWidths; + /* Given a number of the form: digits[remainder] where ptr points to the start and end points to the end, find where @@ -564,7 +613,7 @@ } } -#endif /* FORMAT_FLOAT || FORMAT_LONG */ +#endif /* FORMAT_FLOAT || FORMAT_LONG || FORMAT_COMPLEX */ /************************************************************************/ /*********** string formatting ******************************************/ @@ -573,10 +622,10 @@ static PyObject * format_string_internal(PyObject *value, const InternalFormatSpec *format) { - Py_ssize_t width; /* total field width */ Py_ssize_t lpad; - STRINGLIB_CHAR *dst; - STRINGLIB_CHAR *src = STRINGLIB_STR(value); + Py_ssize_t rpad; + Py_ssize_t total; + STRINGLIB_CHAR *p; Py_ssize_t len = STRINGLIB_LEN(value); PyObject *result = NULL; @@ -609,56 +658,20 @@ len = format->precision; } - if (format->width >= 0) { - width = format->width; - - /* but use at least len characters */ - if (len > width) { - width = len; - } - } - else { - /* not specified, use all of the chars and no more */ - width = len; - } + calc_padding(len, format->width, format->align, &lpad, &rpad, &total); /* allocate the resulting string */ - result = STRINGLIB_NEW(NULL, width); + result = STRINGLIB_NEW(NULL, total); if (result == NULL) goto done; - /* now write into that space */ - dst = STRINGLIB_STR(result); + /* Write into that space. First the padding. */ + p = fill_padding(STRINGLIB_STR(result), len, + format->fill_char=='\0'?' ':format->fill_char, + lpad, rpad); - /* figure out how much leading space we need, based on the - aligning */ - if (format->align == '>') - lpad = width - len; - else if (format->align == '^') - lpad = (width - len) / 2; - else - lpad = 0; - - /* if right aligning, increment the destination allow space on the - left */ - memcpy(dst + lpad, src, len * sizeof(STRINGLIB_CHAR)); - - /* do any padding */ - if (width > len) { - STRINGLIB_CHAR fill_char = format->fill_char; - if (fill_char == '\0') { - /* use the default, if not specified */ - fill_char = ' '; - } - - /* pad on left */ - if (lpad) - STRINGLIB_FILL(dst, fill_char, lpad); - - /* pad on right */ - if (width - len - lpad) - STRINGLIB_FILL(dst + len + lpad, fill_char, width - len - lpad); - } + /* Then the source string. */ + memcpy(p, STRINGLIB_STR(value), len * sizeof(STRINGLIB_CHAR)); done: return result; @@ -998,6 +1011,231 @@ #endif /* FORMAT_FLOAT */ /************************************************************************/ +/*********** complex formatting *****************************************/ +/************************************************************************/ + +#ifdef FORMAT_COMPLEX + +static PyObject * +format_complex_internal(PyObject *value, + const InternalFormatSpec *format) +{ + double re; + double im; + char *re_buf = NULL; /* buffer returned from PyOS_double_to_string */ + char *im_buf = NULL; /* buffer returned from PyOS_double_to_string */ + + InternalFormatSpec tmp_format = *format; + Py_ssize_t n_re_digits; + Py_ssize_t n_im_digits; + Py_ssize_t n_re_remainder; + Py_ssize_t n_im_remainder; + Py_ssize_t n_re_total; + Py_ssize_t n_im_total; + int re_has_decimal; + int im_has_decimal; + Py_ssize_t precision = format->precision; + STRINGLIB_CHAR type = format->type; + STRINGLIB_CHAR *p_re; + STRINGLIB_CHAR *p_im; + NumberFieldWidths re_spec; + NumberFieldWidths im_spec; + int flags = 0; + PyObject *result = NULL; + STRINGLIB_CHAR *p; + STRINGLIB_CHAR re_sign_char = '\0'; + STRINGLIB_CHAR im_sign_char = '\0'; + int re_float_type; /* Used to see if we have a nan, inf, or regular float. */ + int im_float_type; + int add_parens = 0; + int skip_re = 0; + Py_ssize_t lpad; + Py_ssize_t rpad; + Py_ssize_t total; + +#if STRINGLIB_IS_UNICODE + Py_UNICODE *re_unicode_tmp = NULL; + Py_UNICODE *im_unicode_tmp = NULL; +#endif + + /* Locale settings, either from the actual locale or + from a hard-code pseudo-locale */ + LocaleInfo locale; + + /* Alternate is not allowed on complex. */ + if (format->alternate) { + PyErr_SetString(PyExc_ValueError, + "Alternate form (#) not allowed in complex format " + "specifier"); + goto done; + } + + /* Neither is zero pading. */ + if (format->fill_char == '0') { + PyErr_SetString(PyExc_ValueError, + "Zero padding is not allowed in complex format " + "specifier"); + goto done; + } + + /* Neither is '=' alignment . */ + if (format->align == '=') { + PyErr_SetString(PyExc_ValueError, + "'=' alignment flag is not allowed in complex format " + "specifier"); + goto done; + } + + re = PyComplex_RealAsDouble(value); + if (re == -1.0 && PyErr_Occurred()) + goto done; + im = PyComplex_ImagAsDouble(value); + if (im == -1.0 && PyErr_Occurred()) + goto done; + + if (type == '\0') { + /* Omitted type specifier. Should be like str(self). */ + type = 'g'; + add_parens = 1; + if (re == 0.0) + skip_re = 1; + } + + if (type == 'n') + /* 'n' is the same as 'g', except for the locale used to + format the result. We take care of that later. */ + type = 'g'; + + /* 'F' is the same as 'f', per the PEP */ + if (type == 'F') + type = 'f'; + + if (precision < 0) + precision = 6; + + /* Cast "type", because if we're in unicode we need to pass a + 8-bit char. This is safe, because we've restricted what "type" + can be. */ + re_buf = PyOS_double_to_string(re, (char)type, precision, flags, + &re_float_type); + if (re_buf == NULL) + goto done; + im_buf = PyOS_double_to_string(im, (char)type, precision, flags, + &im_float_type); + if (im_buf == NULL) + goto done; + + n_re_digits = strlen(re_buf); + n_im_digits = strlen(im_buf); + + /* Since there is no unicode version of PyOS_double_to_string, + just use the 8 bit version and then convert to unicode. */ +#if STRINGLIB_IS_UNICODE + re_unicode_tmp = (Py_UNICODE*)PyMem_Malloc((n_re_digits)*sizeof(Py_UNICODE)); + if (re_unicode_tmp == NULL) { + PyErr_NoMemory(); + goto done; + } + strtounicode(re_unicode_tmp, re_buf, n_re_digits); + p_re = re_unicode_tmp; + + im_unicode_tmp = (Py_UNICODE*)PyMem_Malloc((n_im_digits)*sizeof(Py_UNICODE)); + if (im_unicode_tmp == NULL) { + PyErr_NoMemory(); + goto done; + } + strtounicode(im_unicode_tmp, im_buf, n_im_digits); + p_im = im_unicode_tmp; +#else + p_re = re_buf; + p_im = im_buf; +#endif + + /* Is a sign character present in the output? If so, remember it + and skip it */ + if (*p_re == '-') { + re_sign_char = *p_re; + ++p_re; + --n_re_digits; + } + if (*p_im == '-') { + im_sign_char = *p_im; + ++p_im; + --n_im_digits; + } + + /* Determine if we have any "remainder" (after the digits, might include + decimal or exponent or both (or neither)) */ + parse_number(p_re, n_re_digits, &n_re_remainder, &re_has_decimal); + parse_number(p_im, n_im_digits, &n_im_remainder, &im_has_decimal); + + /* Determine the grouping, separator, and decimal point, if any. */ + get_locale_info(format->type == 'n' ? LT_CURRENT_LOCALE : + (format->thousands_separators ? + LT_DEFAULT_LOCALE : + LT_NO_LOCALE), + &locale); + + /* Turn off any padding. We'll do it later after we've composed + the numbers without padding. */ + tmp_format.fill_char = '\0'; + tmp_format.align = '\0'; + tmp_format.width = -1; + + /* Calculate how much memory we'll need. */ + n_re_total = calc_number_widths(&re_spec, 0, re_sign_char, p_re, + n_re_digits, n_re_remainder, + re_has_decimal, &locale, &tmp_format); + + /* Same formatting, but always include a sign. */ + tmp_format.sign = '+'; + n_im_total = calc_number_widths(&im_spec, 0, im_sign_char, p_im, + n_im_digits, n_im_remainder, + im_has_decimal, &locale, &tmp_format); + + if (skip_re) + n_re_total = 0; + + /* Add 1 for the 'j', and optionally 2 for parens. */ + calc_padding(n_re_total + n_im_total + 1 + add_parens * 2, + format->width, format->align, &lpad, &rpad, &total); + + result = STRINGLIB_NEW(NULL, total); + if (result == NULL) + goto done; + + /* Populate the memory. First, the padding. */ + p = fill_padding(STRINGLIB_STR(result), + n_re_total + n_im_total + 1 + add_parens * 2, + format->fill_char=='\0' ? ' ' : format->fill_char, + lpad, rpad); + + if (add_parens) + *p++ = '('; + + if (!skip_re) { + fill_number(p, &re_spec, p_re, n_re_digits, NULL, 0, &locale, 0); + p += n_re_total; + } + fill_number(p, &im_spec, p_im, n_im_digits, NULL, 0, &locale, 0); + p += n_im_total; + *p++ = 'j'; + + if (add_parens) + *p++ = ')'; + +done: + PyMem_Free(re_buf); + PyMem_Free(im_buf); +#if STRINGLIB_IS_UNICODE + PyMem_Free(re_unicode_tmp); + PyMem_Free(im_unicode_tmp); +#endif + return result; +} +#endif /* FORMAT_COMPLEX */ + +/************************************************************************/ /*********** built in formatters ****************************************/ /************************************************************************/ PyObject * @@ -1196,3 +1434,50 @@ return result; } #endif /* FORMAT_FLOAT */ + +#ifdef FORMAT_COMPLEX +PyObject * +FORMAT_COMPLEX(PyObject *obj, + STRINGLIB_CHAR *format_spec, + Py_ssize_t format_spec_len) +{ + PyObject *result = NULL; + InternalFormatSpec format; + + /* check for the special case of zero length format spec, make + it equivalent to str(obj) */ + if (format_spec_len == 0) { + result = STRINGLIB_TOSTR(obj); + goto done; + } + + /* parse the format_spec */ + if (!parse_internal_render_format_spec(format_spec, + format_spec_len, + &format, '\0')) + goto done; + + /* type conversion? */ + switch (format.type) { + case '\0': /* No format code: like 'g', but with at least one decimal. */ + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': + case 'n': + /* no conversion, already a complex. do the formatting */ + result = format_complex_internal(obj, &format); + break; + + default: + /* unknown */ + unknown_presentation_type(format.type, obj->ob_type->tp_name); + goto done; + } + +done: + return result; +} +#endif /* FORMAT_COMPLEX */ Modified: python/branches/py3k/Python/formatter_unicode.c ============================================================================== --- python/branches/py3k/Python/formatter_unicode.c (original) +++ python/branches/py3k/Python/formatter_unicode.c Thu Apr 30 03:00:33 2009 @@ -6,8 +6,9 @@ #include "../Objects/stringlib/unicodedefs.h" -#define FORMAT_STRING _PyUnicode_FormatAdvanced -#define FORMAT_LONG _PyLong_FormatAdvanced -#define FORMAT_FLOAT _PyFloat_FormatAdvanced +#define FORMAT_STRING _PyUnicode_FormatAdvanced +#define FORMAT_LONG _PyLong_FormatAdvanced +#define FORMAT_FLOAT _PyFloat_FormatAdvanced +#define FORMAT_COMPLEX _PyComplex_FormatAdvanced #include "../Objects/stringlib/formatter.h" From python-checkins at python.org Thu Apr 30 03:01:34 2009 From: python-checkins at python.org (eric.smith) Date: Thu, 30 Apr 2009 03:01:34 +0200 (CEST) Subject: [Python-checkins] r72141 - python/branches/release30-maint Message-ID: <20090430010134.CDEB01E4223@bag.python.org> Author: eric.smith Date: Thu Apr 30 03:01:34 2009 New Revision: 72141 Log: Blocked revisions 72140 via svnmerge ........ r72140 | eric.smith | 2009-04-29 21:00:33 -0400 (Wed, 29 Apr 2009) | 1 line Issue #1588: Add complex.__format__. ........ Modified: python/branches/release30-maint/ (props changed) From buildbot at python.org Thu Apr 30 03:18:20 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 30 Apr 2009 01:18:20 +0000 Subject: [Python-checkins] buildbot failure in x86 gentoo trunk Message-ID: <20090430011820.CEF3E1E4029@bag.python.org> The Buildbot has detected a new failure of x86 gentoo trunk. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20gentoo%20trunk/builds/4902 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: norwitz-x86 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: benjamin.peterson BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_os test_time make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Thu Apr 30 03:27:07 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 30 Apr 2009 01:27:07 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable 3.x Message-ID: <20090430012708.6F8581E4029@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%203.x/builds/713 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson,mark.dickinson,r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_os test_time make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Thu Apr 30 04:08:57 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 30 Apr 2009 02:08:57 +0000 Subject: [Python-checkins] buildbot failure in i386 Ubuntu trunk Message-ID: <20090430020857.E87321E4011@bag.python.org> The Buildbot has detected a new failure of i386 Ubuntu trunk. Full details are available at: http://www.python.org/dev/buildbot/all/i386%20Ubuntu%20trunk/builds/1216 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-ubuntu-i386 Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: eric.smith BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_os ====================================================================== FAIL: test_update2 (test.test_os.EnvironTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/trunk.klose-ubuntu-i386/build/Lib/test/test_os.py", line 348, in test_update2 self.assertEquals(value, "World") AssertionError: '' != 'World' make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Thu Apr 30 04:18:36 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 30 Apr 2009 02:18:36 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090430021836.E84C31E4016@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/668 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson,mark.dickinson,r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_time ====================================================================== FAIL: test_tzset (test.test_time.TimeTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/test/test_time.py", line 166, in test_tzset self.failIfEqual(time.gmtime(xmas2002), time.localtime(xmas2002)) AssertionError: time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) == time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Thu Apr 30 04:33:52 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 30 Apr 2009 02:33:52 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.x Message-ID: <20090430023352.CC87B1E4016@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.x/builds/603 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: benjamin.peterson,mark.dickinson,r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_importlib test_posix Traceback (most recent call last): File "./Lib/test/regrtest.py", line 620, in runtest_inner File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_importlib.py", line 6, in test_main run_unittest(importlib.test.test_suite('importlib.test')) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/__init__.py", line 22, in test_suite package_tests = getattr(sys.modules[package_name], 'test_suite')() File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/source/__init__.py", line 8, in test_suite return importlib.test.test_suite('importlib.test.source', directory) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/__init__.py", line 16, in test_suite __import__(module_name, level=0) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/source/test_case_sensitivity.py", line 12, in class CaseSensitivityTest(unittest.TestCase): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/importlib/test/util.py", line 13, in case_insensitive_tests original_name = os.listdir('.')[0] IndexError: list index out of range ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/test_posix.py", line 251, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/test/support.py", line 177, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.x.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.x.loewis-sun/build/@test.getcwd/@test.getcwd' sincerely, -The Buildbot From buildbot at python.org Thu Apr 30 05:45:46 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 30 Apr 2009 03:45:46 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc 3.0 Message-ID: <20090430034546.96DE91E401D@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%203.0/builds/318 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: r.david.murray BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_posix test_subprocess ====================================================================== ERROR: test_getcwd_long_pathnames (test.test_posix.PosixTester) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_posix.py", line 252, in test_getcwd_long_pathnames support.rmtree(base_path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/support.py", line 98, in rmtree shutil.rmtree(path) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 225, in rmtree onerror(os.rmdir, path, sys.exc_info()) File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/shutil.py", line 223, in rmtree os.rmdir(path) OSError: [Errno 22] Invalid argument: '/home2/buildbot/slave/3.0.loewis-sun/build/@test.getcwd/@test.getcwd' ====================================================================== FAIL: test_executable (test.test_subprocess.ProcessTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/3.0.loewis-sun/build/Lib/test/test_subprocess.py", line 115, in test_executable self.assertEqual(p.returncode, 47) AssertionError: -6 != 47 sincerely, -The Buildbot From buildbot at python.org Thu Apr 30 06:17:41 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 30 Apr 2009 04:17:41 +0000 Subject: [Python-checkins] buildbot failure in ppc Debian unstable trunk Message-ID: <20090430041741.1E9121E425C@bag.python.org> The Buildbot has detected a new failure of ppc Debian unstable trunk. Full details are available at: http://www.python.org/dev/buildbot/all/ppc%20Debian%20unstable%20trunk/builds/437 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ppc Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: benjamin.peterson,georg.brandl BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_bsddb3 test_os make: *** [buildbottest] Error 1 sincerely, -The Buildbot From buildbot at python.org Thu Apr 30 06:44:48 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 30 Apr 2009 04:44:48 +0000 Subject: [Python-checkins] buildbot failure in sparc solaris10 gcc trunk Message-ID: <20090430044449.011BD1E401D@bag.python.org> The Buildbot has detected a new failure of sparc solaris10 gcc trunk. Full details are available at: http://www.python.org/dev/buildbot/all/sparc%20solaris10%20gcc%20trunk/builds/351 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: loewis-sun Build Reason: Build Source Stamp: [branch trunk] HEAD Blamelist: benjamin.peterson,eric.smith,georg.brandl,mark.dickinson BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_time ====================================================================== FAIL: test_tzset (test.test_time.TimeTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home2/buildbot/slave/trunk.loewis-sun/build/Lib/test/test_time.py", line 152, in test_tzset time.gmtime(xmas2002), time.localtime(xmas2002) AssertionError: time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) != time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=1, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) sincerely, -The Buildbot From python-checkins at python.org Thu Apr 30 07:04:13 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 30 Apr 2009 07:04:13 +0200 (CEST) Subject: [Python-checkins] r72142 - peps/trunk/pep-0383.txt Message-ID: <20090430050413.A205C1E401D@bag.python.org> Author: martin.v.loewis Date: Thu Apr 30 07:04:13 2009 New Revision: 72142 Log: Fix typo. Modified: peps/trunk/pep-0383.txt Modified: peps/trunk/pep-0383.txt ============================================================================== --- peps/trunk/pep-0383.txt (original) +++ peps/trunk/pep-0383.txt Thu Apr 30 07:04:13 2009 @@ -74,8 +74,8 @@ To convert non-decodable bytes, a new error handler "python-escape" is introduced, which produces these half surrogates. On encoding, the error handler converts the half surrogate back to the corresponding -byte. This error handler used used in any API that receives or produces -file names, command line arguments, or environment variables. +byte. This error handler will be used in any API that receives or +produces file names, command line arguments, or environment variables. The error handler interface is extended to allow the encode error handler to return byte strings immediately, in addition to returning From python-checkins at python.org Thu Apr 30 09:02:13 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 30 Apr 2009 09:02:13 +0200 (CEST) Subject: [Python-checkins] r72143 - peps/trunk/pep-0383.txt Message-ID: <20090430070213.A31FB1E4024@bag.python.org> Author: martin.v.loewis Date: Thu Apr 30 09:02:13 2009 New Revision: 72143 Log: Add references. Modified: peps/trunk/pep-0383.txt Modified: peps/trunk/pep-0383.txt ============================================================================== --- peps/trunk/pep-0383.txt (original) +++ peps/trunk/pep-0383.txt Thu Apr 30 09:02:13 2009 @@ -64,18 +64,19 @@ On Windows, Python uses the wide character APIs to access character-oriented APIs, allowing direct conversion of the -environmental data to Python str objects. +environmental data to Python str objects ([1]). On POSIX systems, Python currently applies the locale's encoding to convert the byte data to Unicode, failing for characters that cannot be decoded. With this PEP, non-decodable bytes will be represented as lone half surrogate codes U+DCxx. -To convert non-decodable bytes, a new error handler "python-escape" is -introduced, which produces these half surrogates. On encoding, the -error handler converts the half surrogate back to the corresponding -byte. This error handler will be used in any API that receives or -produces file names, command line arguments, or environment variables. +To convert non-decodable bytes, a new error handler ([2]) +"python-escape" is introduced, which produces these half +surrogates. On encoding, the error handler converts the half surrogate +back to the corresponding byte. This error handler will be used in any +API that receives or produces file names, command line arguments, or +environment variables. The error handler interface is extended to allow the encode error handler to return byte strings immediately, in addition to returning @@ -122,6 +123,17 @@ # fn is now a str object yield fn.encode(fse, "python-escape") +References +========== + + [1] PEP 277 + "Unicode file name support for Windows NT" + http://www.python.org/dev/peps/pep-0277/ + + [2] PEP 293 + "Codec Error Handling Callbacks" + http://www.python.org/dev/peps/pep-0293/ + Copyright ========= From python-checkins at python.org Thu Apr 30 10:06:50 2009 From: python-checkins at python.org (matthias.klose) Date: Thu, 30 Apr 2009 10:06:50 +0200 (CEST) Subject: [Python-checkins] r72144 - in python/branches/py3k: Misc/NEWS configure configure.in setup.py Message-ID: <20090430080650.5D4591E4042@bag.python.org> Author: matthias.klose Date: Thu Apr 30 10:06:49 2009 New Revision: 72144 Log: - Issue #4587: Add configure option --with-dbmliborder=db1:db2:... to specify the order that backends for the dbm extension are checked. Modified: python/branches/py3k/Misc/NEWS python/branches/py3k/configure python/branches/py3k/configure.in python/branches/py3k/setup.py Modified: python/branches/py3k/Misc/NEWS ============================================================================== --- python/branches/py3k/Misc/NEWS (original) +++ python/branches/py3k/Misc/NEWS Thu Apr 30 10:06:49 2009 @@ -880,6 +880,9 @@ Build ----- +- Issue #4587: Add configure option --with-dbmliborder=db1:db2:... to specify + the order that backends for the dbm extension are checked. + - Link the shared python library with $(MODLIBS). - Issue #5134: Silence compiler warnings when compiling sqlite with VC++. Modified: python/branches/py3k/configure ============================================================================== --- python/branches/py3k/configure (original) +++ python/branches/py3k/configure Thu Apr 30 10:06:49 2009 @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 71723 . +# From configure.in Revision: 71731 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.1. # @@ -1340,6 +1340,10 @@ --with-pydebug build with Py_DEBUG defined --with-libs='lib1 ...' link against additional libs --with-system-ffi build _ctypes module using an installed ffi library + --with-dbmliborder=db1:db2:... + order to check db backends for dbm. Valid value is a + colon separated string with the backend names + `ndbm', `gdbm' and `bdb'. --with-signal-module disable/enable signal module --with-dec-threads use DEC Alpha/OSF1 thread-safe libraries --with(out)-threads[=DIRECTORY] @@ -14087,6 +14091,33 @@ { echo "$as_me:$LINENO: result: $with_system_ffi" >&5 echo "${ECHO_T}$with_system_ffi" >&6; } +# Check for --with-dbmliborder +{ echo "$as_me:$LINENO: checking for --with-dbmliborder" >&5 +echo $ECHO_N "checking for --with-dbmliborder... $ECHO_C" >&6; } + +# Check whether --with-dbmliborder was given. +if test "${with_dbmliborder+set}" = set; then + withval=$with_dbmliborder; +if test x$with_dbmliborder = xyes +then +{ { echo "$as_me:$LINENO: error: proper usage is --with-dbmliborder=db1:db2:..." >&5 +echo "$as_me: error: proper usage is --with-dbmliborder=db1:db2:..." >&2;} + { (exit 1); exit 1; }; } +else + for db in `echo $with_dbmliborder | sed 's/:/ /g'`; do + if test x$db != xndbm && test x$db != xgdbm && test x$db != xbdb + then + { { echo "$as_me:$LINENO: error: proper usage is --with-dbmliborder=db1:db2:..." >&5 +echo "$as_me: error: proper usage is --with-dbmliborder=db1:db2:..." >&2;} + { (exit 1); exit 1; }; } + fi + done +fi +fi + +{ echo "$as_me:$LINENO: result: $with_dbmliborder" >&5 +echo "${ECHO_T}$with_dbmliborder" >&6; } + # Determine if signalmodule should be used. Modified: python/branches/py3k/configure.in ============================================================================== --- python/branches/py3k/configure.in (original) +++ python/branches/py3k/configure.in Thu Apr 30 10:06:49 2009 @@ -1837,6 +1837,24 @@ AC_MSG_RESULT($with_system_ffi) +# Check for --with-dbmliborder +AC_MSG_CHECKING(for --with-dbmliborder) +AC_ARG_WITH(dbmliborder, + AC_HELP_STRING([--with-dbmliborder=db1:db2:...], [order to check db backends for dbm. Valid value is a colon separated string with the backend names `ndbm', `gdbm' and `bdb'.]), +[ +if test x$with_dbmliborder = xyes +then +AC_MSG_ERROR([proper usage is --with-dbmliborder=db1:db2:...]) +else + for db in `echo $with_dbmliborder | sed 's/:/ /g'`; do + if test x$db != xndbm && test x$db != xgdbm && test x$db != xbdb + then + AC_MSG_ERROR([proper usage is --with-dbmliborder=db1:db2:...]) + fi + done +fi]) +AC_MSG_RESULT($with_dbmliborder) + # Determine if signalmodule should be used. AC_SUBST(USE_SIGNAL_MODULE) AC_SUBST(SIGNAL_OBJS) Modified: python/branches/py3k/setup.py ============================================================================== --- python/branches/py3k/setup.py (original) +++ python/branches/py3k/setup.py Thu Apr 30 10:06:49 2009 @@ -913,37 +913,69 @@ # The standard Unix dbm module: if platform not in ['cygwin']: - if find_file("ndbm.h", inc_dirs, []) is not None: - # Some systems have -lndbm, others don't - if self.compiler.find_library_file(lib_dirs, 'ndbm'): - ndbm_libs = ['ndbm'] - else: - ndbm_libs = [] - exts.append( Extension('_dbm', ['_dbmmodule.c'], - define_macros=[('HAVE_NDBM_H',None)], - libraries = ndbm_libs ) ) - elif self.compiler.find_library_file(lib_dirs, 'gdbm'): - gdbm_libs = ['gdbm'] - if self.compiler.find_library_file(lib_dirs, 'gdbm_compat'): - gdbm_libs.append('gdbm_compat') - if find_file("gdbm/ndbm.h", inc_dirs, []) is not None: - exts.append( Extension( - '_dbm', ['_dbmmodule.c'], - define_macros=[('HAVE_GDBM_NDBM_H',None)], - libraries = gdbm_libs ) ) - elif find_file("gdbm-ndbm.h", inc_dirs, []) is not None: - exts.append( Extension( - '_dbm', ['_dbmmodule.c'], - define_macros=[('HAVE_GDBM_DASH_NDBM_H',None)], - libraries = gdbm_libs ) ) - elif db_incs is not None: - exts.append( Extension('_dbm', ['_dbmmodule.c'], - library_dirs=dblib_dir, - runtime_library_dirs=dblib_dir, - include_dirs=db_incs, - define_macros=[('HAVE_BERKDB_H',None), - ('DB_DBM_HSEARCH',None)], - libraries=dblibs)) + config_args = [arg.strip("'") + for arg in sysconfig.get_config_var("CONFIG_ARGS").split()] + dbm_args = [arg.split('=')[-1] for arg in config_args + if arg.startswith('--with-dbmliborder=')] + if dbm_args: + dbm_order = dbm_args[-1].split(":") + else: + dbm_order = "ndbm:gdbm:bdb".split(":") + dbmext = None + for cand in dbm_order: + if cand == "ndbm": + if find_file("ndbm.h", inc_dirs, []) is not None: + # Some systems have -lndbm, others don't + if self.compiler.find_library_file(lib_dirs, 'ndbm'): + ndbm_libs = ['ndbm'] + else: + ndbm_libs = [] + print("building dbm using ndbm") + dbmext = Extension('_dbm', ['_dbmmodule.c'], + define_macros=[ + ('HAVE_NDBM_H',None), + ], + libraries=ndbm_libs) + break + + elif cand == "gdbm": + if self.compiler.find_library_file(lib_dirs, 'gdbm'): + gdbm_libs = ['gdbm'] + if self.compiler.find_library_file(lib_dirs, 'gdbm_compat'): + gdbm_libs.append('gdbm_compat') + if find_file("gdbm/ndbm.h", inc_dirs, []) is not None: + print("building dbm using gdbm") + dbmext = Extension( + '_dbm', ['_dbmmodule.c'], + define_macros=[ + ('HAVE_GDBM_NDBM_H', None), + ], + libraries = gdbm_libs) + break + if find_file("gdbm-ndbm.h", inc_dirs, []) is not None: + print("building dbm using gdbm") + dbmext = Extension( + '_dbm', ['_dbmmodule.c'], + define_macros=[ + ('HAVE_GDBM_DASH_NDBM_H', None), + ], + libraries = gdbm_libs) + break + elif cand == "bdb": + if db_incs is not None: + print("building dbm using bdb") + dbmext = Extension('_dbm', ['_dbmmodule.c'], + library_dirs=dblib_dir, + runtime_library_dirs=dblib_dir, + include_dirs=db_incs, + define_macros=[ + ('HAVE_BERKDB_H', None), + ('DB_DBM_HSEARCH', None), + ], + libraries=dblibs) + break + if dbmext is not None: + exts.append(dbmext) else: missing.append('_dbm') From python-checkins at python.org Thu Apr 30 10:34:04 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 30 Apr 2009 10:34:04 +0200 (CEST) Subject: [Python-checkins] r72145 - peps/trunk/pep-0383.txt Message-ID: <20090430083404.E349A1E4036@bag.python.org> Author: martin.v.loewis Date: Thu Apr 30 10:34:04 2009 New Revision: 72145 Log: Add discussion of error handlers proposed by Glen Linderman. Modified: peps/trunk/pep-0383.txt Modified: peps/trunk/pep-0383.txt ============================================================================== --- peps/trunk/pep-0383.txt (original) +++ peps/trunk/pep-0383.txt Thu Apr 30 10:34:04 2009 @@ -80,7 +80,8 @@ The error handler interface is extended to allow the encode error handler to return byte strings immediately, in addition to returning -Unicode strings which then get encoded again. +Unicode strings which then get encoded again (also see the discussion +below). If the locale's encoding is UTF-8, the file system encoding is set to a new encoding "utf-8b", as the regular UTF-8 codec would not @@ -123,6 +124,17 @@ # fn is now a str object yield fn.encode(fse, "python-escape") +The encode error handler interface presently requires replacement +Unicode to be provide in lieu of the non-encodable Unicode from the +source string. It promptly encodes that replacement Unicode. In some +error handlers, such as the python-escape proposed here, it is simpler +and more efficient for the error handler to provide a pre-encoded +replacement byte string, rather than forcing it to calculating Unicode +from which the encoder would create the desired bytes. In fact, with +python-escape, there are required byte sequences which cannot be +generated from replacement Unicode. + + References ========== From buildbot at python.org Thu Apr 30 10:48:43 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 30 Apr 2009 08:48:43 +0000 Subject: [Python-checkins] buildbot failure in ia64 Ubuntu 3.x Message-ID: <20090430084844.3D2CA1E425A@bag.python.org> The Buildbot has detected a new failure of ia64 Ubuntu 3.x. Full details are available at: http://www.python.org/dev/buildbot/all/ia64%20Ubuntu%203.x/builds/670 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: klose-debian-ia64 Build Reason: Build Source Stamp: [branch branches/py3k] HEAD Blamelist: matthias.klose BUILD FAILED: failed test Excerpt from the test logfile: 2 tests failed: test_os test_time ====================================================================== FAIL: test_update2 (test.test_os.EnvironTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/test/test_os.py", line 382, in test_update2 self.assertEquals(value, "World") AssertionError: '' != 'World' ====================================================================== FAIL: test_tzset (test.test_time.TimeTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/pybot/buildarea/3.x.klose-debian-ia64/build/Lib/test/test_time.py", line 166, in test_tzset self.failIfEqual(time.gmtime(xmas2002), time.localtime(xmas2002)) AssertionError: time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) == time.struct_time(tm_year=2002, tm_mon=12, tm_mday=25, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=359, tm_isdst=0) make: *** [buildbottest] Error 1 sincerely, -The Buildbot From python-checkins at python.org Thu Apr 30 11:05:01 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 30 Apr 2009 11:05:01 +0200 (CEST) Subject: [Python-checkins] r72146 - peps/trunk/pep-0382.txt Message-ID: <20090430090501.10D691E4021@bag.python.org> Author: martin.v.loewis Date: Thu Apr 30 11:05:00 2009 New Revision: 72146 Log: Rename proposed files from .pkg into .pth. Drop claims that this extends the .pkg mechanism. Modified: peps/trunk/pep-0382.txt Modified: peps/trunk/pep-0382.txt ============================================================================== --- peps/trunk/pep-0382.txt (original) +++ peps/trunk/pep-0382.txt Thu Apr 30 11:05:00 2009 @@ -49,8 +49,8 @@ first. As a consequence, the package's ``__init__.py`` cannot practically define any names as it depends on the order of the package fragments on sys.path which portion is imported first. As a special -feature, extend_path reads files named ``*.pkg`` which allow to -declare additional portions. +feature, extend_path reads files named ``.pkg`` which +allow to declare additional portions. setuptools provides a similar function pkg_resources.declare_namespace that is used in the form:: @@ -91,29 +91,27 @@ Rather than using an imperative mechanism for importing packages, a declarative approach is proposed here, as an extension to the existing -``*.pkg`` mechanism. +``*.pth`` mechanism available on the top-level python path. -The import statement is extended so that it directly considers ``*.pkg`` -files during import; a directory is considered a package if it either -contains a file named __init__.py, or a file whose name ends with -".pkg". +The import statement is extended so that it directly considers +``*.pth`` files during import; a directory is considered a package if +it either contains a file named __init__.py, or a file whose name ends +with ".pth". Unlike .pth files on the top level, lines starting with +"import" are not supported in per-package .pth files. -In addition, the format of the ``*.pkg`` file is extended: a line with +In addition, the format of the ``*.pth`` file is extended: a line with the single character ``*`` indicates that the entire sys.path will be searched for portions of the namespace package at the time the namespace packages is imported. Importing a package will immediately compute the package's __path__; -the ``*.pkg`` files are not considered anymore after the initial import. -If a ``*.pkg`` package contains an asterisk, this asterisk is prepended -to the package's __path__ to indicate that the package is a namespace -package (and that thus further extensions to sys.path might also -want to extend __path__). At most one such asterisk gets prepended -to the path. In addition, the (possibly dotted) names of all namespace -packages are added to the set sys.namespace_packages. - -extend_path will be extended to recognize namespace packages according -to this PEP, and avoid adding directories twice to __path__. +the ``*.pth`` files are not considered anymore after the initial +import. If a ``*.pth`` package contains an asterisk, this asterisk is +prepended to the package's __path__ to indicate that the package is a +namespace package (and that thus further extensions to sys.path might +also want to extend __path__). At most one such asterisk gets +prepended to the path. In addition, the (possibly dotted) names of all +namespace packages are added to the set sys.namespace_packages. No other change to the importing mechanism is made; searching modules (including __init__.py) will continue to stop at the first module @@ -122,22 +120,22 @@ 1. sys.path is search for a directory foo, or a file foo.. If a file is found, it is treated as a module, and imported. - 2. if it is a directory, it checks for \*.pkg files. If it finds + 2. if it is a directory, it checks for \*.pth files. If it finds any, a package is created, and its __path__ is extended. 3. The __init__ module is imported; this import will search the __path__ that got computed already. - 4. If neither a \*.pkg file nor an __init__.py was found, the + 4. If neither a \*.pth file nor an __init__.py was found, the directory is skipped, and search for the module/package continues. Discussion ========== -With the addition of ``*.pkg`` files to the import mechanism, namespace +With the addition of ``*.pth`` files to the import mechanism, namespace packages can stop filling out the namespace package's __init__.py. As a consequence, extend_path and declare_namespace become obsolete. -It is recommended that distributions put a file .pkg +It is recommended that distributions put a file .pth into their namespace packages, with a single asterisk. This allows vendor packages to install multiple portions of namespace package into a single directory, with no risk of overlapping files. @@ -160,9 +158,6 @@ users of this feature are encouraged to comment on this particular question. -It also has been proposed to rename the extension from .pkg to -something else. - Copyright ========= From python-checkins at python.org Thu Apr 30 11:24:24 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 30 Apr 2009 11:24:24 +0200 (CEST) Subject: [Python-checkins] r72147 - peps/trunk/pep-0383.txt Message-ID: <20090430092424.997F91E4036@bag.python.org> Author: martin.v.loewis Date: Thu Apr 30 11:24:24 2009 New Revision: 72147 Log: Add more discussion. Modified: peps/trunk/pep-0383.txt Modified: peps/trunk/pep-0383.txt ============================================================================== --- peps/trunk/pep-0383.txt (original) +++ peps/trunk/pep-0383.txt Thu Apr 30 11:24:24 2009 @@ -104,7 +104,10 @@ get converted back to bytes with the python-escape error handler also. Encoding the data with the locale's encoding and the (default) strict error handler will raise an exception, encoding them with UTF-8 -will produce non-sensical data. +will produce non-sensical data. + +Data obtained from other sources may conflict with data produced +by this PEP. Dealing with such conflicts is out of scope of the PEP. For most applications, we assume that they eventually pass data received from a system interface back into the same system @@ -134,6 +137,11 @@ python-escape, there are required byte sequences which cannot be generated from replacement Unicode. +A few alternative approaches have been proposed: + +* create a new string subclass that supports embedded bytes +* use different escape schemes, such as escaping with a NUL + character, or mapping to infrequent characters. References ========== From nnorwitz at gmail.com Thu Apr 30 11:35:44 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 30 Apr 2009 05:35:44 -0400 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20090430093544.GA26929@python.psfb.org> More important issues: ---------------------- test_ssl leaked [0, 0, -403] references, sum=-403 Less important issues: ---------------------- test_cmd_line leaked [0, -25, 0] references, sum=-25 test_smtplib leaked [7, -118, 0] references, sum=-111 test_sys leaked [-42, 42, -42] references, sum=-42 test_threading leaked [48, 48, 48] references, sum=144 test_urllib2_localnet leaked [282, -276, 3] references, sum=9 From python-checkins at python.org Thu Apr 30 11:50:17 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 30 Apr 2009 11:50:17 +0200 (CEST) Subject: [Python-checkins] r72148 - peps/trunk/pep-0383.txt Message-ID: <20090430095017.4C5531E4042@bag.python.org> Author: martin.v.loewis Date: Thu Apr 30 11:50:16 2009 New Revision: 72148 Log: Restrict escapable bytes into the 128..255 range. Modified: peps/trunk/pep-0383.txt Modified: peps/trunk/pep-0383.txt ============================================================================== --- peps/trunk/pep-0383.txt (original) +++ peps/trunk/pep-0383.txt Thu Apr 30 11:50:16 2009 @@ -68,8 +68,9 @@ On POSIX systems, Python currently applies the locale's encoding to convert the byte data to Unicode, failing for characters that cannot -be decoded. With this PEP, non-decodable bytes will be represented as -lone half surrogate codes U+DCxx. +be decoded. With this PEP, non-decodable bytes >128 will be +represented as lone half surrogate codes U+DC80..U+DCFF. Bytes below +128 will produce exceptions; see the discussion below. To convert non-decodable bytes, a new error handler ([2]) "python-escape" is introduced, which produces these half @@ -109,6 +110,11 @@ Data obtained from other sources may conflict with data produced by this PEP. Dealing with such conflicts is out of scope of the PEP. +Encodings that are not compatible with ASCII are not supported by +this specification; bytes in the ASCII range that fail to decode +will cause an exception. It is widely agreed that such encodings +should not be used as locale charsets. + For most applications, we assume that they eventually pass data received from a system interface back into the same system interfaces. For example, an application invoking os.listdir() will From python-checkins at python.org Thu Apr 30 14:42:33 2009 From: python-checkins at python.org (r.david.murray) Date: Thu, 30 Apr 2009 14:42:33 +0200 (CEST) Subject: [Python-checkins] r72149 - python/trunk/Doc/library/turtle.rst Message-ID: <20090430124233.180E81E4021@bag.python.org> Author: r.david.murray Date: Thu Apr 30 14:42:32 2009 New Revision: 72149 Log: Make the turtle.rst doctests pass. I have a feeling there should be more cleanup, but I don't know now to kill turtles. Especially unexpected ones... ;) Modified: python/trunk/Doc/library/turtle.rst Modified: python/trunk/Doc/library/turtle.rst ============================================================================== --- python/trunk/Doc/library/turtle.rst (original) +++ python/trunk/Doc/library/turtle.rst Thu Apr 30 14:42:32 2009 @@ -6,6 +6,11 @@ :synopsis: Turtle graphics for Tk .. sectionauthor:: Gregor Lingl +.. testsetup:: default + + from turtle import * + turtle = Turtle() + Introduction ============ @@ -223,14 +228,16 @@ Move the turtle forward by the specified *distance*, in the direction the turtle is headed. - >>> turtle.position() - (0.00, 0.00) - >>> turtle.forward(25) - >>> turtle.position() - (25.00,0.00) - >>> turtle.forward(-75) - >>> turtle.position() - (-50.00,0.00) + .. doctest:: + + >>> turtle.position() + (0.00,0.00) + >>> turtle.forward(25) + >>> turtle.position() + (25.00,0.00) + >>> turtle.forward(-75) + >>> turtle.position() + (-50.00,0.00) .. function:: back(distance) @@ -242,11 +249,18 @@ Move the turtle backward by *distance*, opposite to the direction the turtle is headed. Do not change the turtle's heading. - >>> turtle.position() - (0.00, 0.00) - >>> turtle.backward(30) - >>> turtle.position() - (-30.00, 0.00) + .. doctest:: + :hide: + + >>> turtle.goto(0, 0) + + .. doctest:: + + >>> turtle.position() + (0.00,0.00) + >>> turtle.backward(30) + >>> turtle.position() + (-30.00,0.00) .. function:: right(angle) @@ -258,11 +272,18 @@ can be set via the :func:`degrees` and :func:`radians` functions.) Angle orientation depends on the turtle mode, see :func:`mode`. - >>> turtle.heading() - 22.0 - >>> turtle.right(45) - >>> turtle.heading() - 337.0 + .. doctest:: + :hide: + + >>> turtle.setheading(22) + + .. doctest:: + + >>> turtle.heading() + 22.0 + >>> turtle.right(45) + >>> turtle.heading() + 337.0 .. function:: left(angle) @@ -274,37 +295,52 @@ can be set via the :func:`degrees` and :func:`radians` functions.) Angle orientation depends on the turtle mode, see :func:`mode`. - >>> turtle.heading() - 22.0 - >>> turtle.left(45) - >>> turtle.heading() - 67.0 + .. doctest:: + :hide: + + >>> turtle.setheading(22) + + .. doctest:: + + >>> turtle.heading() + 22.0 + >>> turtle.left(45) + >>> turtle.heading() + 67.0 + .. function:: goto(x, y=None) setpos(x, y=None) setposition(x, y=None) - :param x: a number or a pair/vector of numbers - :param y: a number or ``None`` + :param x: a number or a pair/vector of numbers + :param y: a number or ``None`` - If *y* is ``None``, *x* must be a pair of coordinates or a :class:`Vec2D` - (e.g. as returned by :func:`pos`). + If *y* is ``None``, *x* must be a pair of coordinates or a :class:`Vec2D` + (e.g. as returned by :func:`pos`). - Move turtle to an absolute position. If the pen is down, draw line. Do - not change the turtle's orientation. + Move turtle to an absolute position. If the pen is down, draw line. Do + not change the turtle's orientation. - >>> tp = turtle.pos() - >>> tp - (0.00, 0.00) - >>> turtle.setpos(60,30) - >>> turtle.pos() - (60.00,30.00) - >>> turtle.setpos((20,80)) - >>> turtle.pos() - (20.00,80.00) - >>> turtle.setpos(tp) - >>> turtle.pos() - (0.00,0.00) + .. doctest:: + :hide: + + >>> turtle.goto(0, 0) + + .. doctest:: + + >>> tp = turtle.pos() + >>> tp + (0.00,0.00) + >>> turtle.setpos(60,30) + >>> turtle.pos() + (60.00,30.00) + >>> turtle.setpos((20,80)) + >>> turtle.pos() + (20.00,80.00) + >>> turtle.setpos(tp) + >>> turtle.pos() + (0.00,0.00) .. function:: setx(x) @@ -314,11 +350,18 @@ Set the turtle's first coordinate to *x*, leave second coordinate unchanged. - >>> turtle.position() - (0.00, 240.00) - >>> turtle.setx(10) - >>> turtle.position() - (10.00, 240.00) + .. doctest:: + :hide: + + >>> turtle.goto(0, 240) + + .. doctest:: + + >>> turtle.position() + (0.00,240.00) + >>> turtle.setx(10) + >>> turtle.position() + (10.00,240.00) .. function:: sety(y) @@ -327,11 +370,18 @@ Set the turtle's second coordinate to *y*, leave first coordinate unchanged. - >>> turtle.position() - (0.00, 40.00) - >>> turtle.sety(-10) - >>> turtle.position() - (0.00, -10.00) + .. doctest:: + :hide: + + >>> turtle.goto(0, 40) + + .. doctest:: + + >>> turtle.position() + (0.00,40.00) + >>> turtle.sety(-10) + >>> turtle.position() + (0.00,-10.00) .. function:: setheading(to_angle) @@ -351,9 +401,11 @@ 270 - south 270 - west =================== ==================== - >>> turtle.setheading(90) - >>> turtle.heading() - 90 + .. doctest:: + + >>> turtle.setheading(90) + >>> turtle.heading() + 90.0 .. function:: home() @@ -361,6 +413,24 @@ Move turtle to the origin -- coordinates (0,0) -- and set its heading to its start-orientation (which depends on the mode, see :func:`mode`). + .. doctest:: + :hide: + + >>> turtle.setheading(90) + >>> turtle.goto(0, -10) + + .. doctest:: + + >>> turtle.heading() + 90.0 + >>> turtle.position() + (0.00,-10.00) + >>> turtle.home() + >>> turtle.position() + (0.00,0.00) + >>> turtle.heading() + 0.0 + .. function:: circle(radius, extent=None, steps=None) @@ -380,8 +450,23 @@ determines the number of steps to use. If not given, it will be calculated automatically. May be used to draw regular polygons. - >>> turtle.circle(50) - >>> turtle.circle(120, 180) # draw a semicircle + .. doctest:: + + >>> turtle.home() + >>> turtle.position() + (0.00,0.00) + >>> turtle.heading() + 0.0 + >>> turtle.circle(50) + >>> turtle.position() + (-0.00,0.00) + >>> turtle.heading() + 0.0 + >>> turtle.circle(120, 180) # draw a semicircle + >>> turtle.position() + (0.00,240.00) + >>> turtle.heading() + 180.0 .. function:: dot(size=None, *color) @@ -392,8 +477,16 @@ Draw a circular dot with diameter *size*, using *color*. If *size* is not given, the maximum of pensize+4 and 2*pensize is used. - >>> turtle.dot() - >>> turtle.fd(50); turtle.dot(20, "blue"); turtle.fd(50) + + .. doctest:: + + >>> turtle.home() + >>> turtle.dot() + >>> turtle.fd(50); turtle.dot(20, "blue"); turtle.fd(50) + >>> turtle.position() + (100.00,-0.00) + >>> turtle.heading() + 0.0 .. function:: stamp() @@ -402,10 +495,12 @@ position. Return a stamp_id for that stamp, which can be used to delete it by calling ``clearstamp(stamp_id)``. - >>> turtle.color("blue") - >>> turtle.stamp() - 13 - >>> turtle.fd(50) + .. doctest:: + + >>> turtle.color("blue") + >>> turtle.stamp() + 11 + >>> turtle.fd(50) .. function:: clearstamp(stampid) @@ -415,10 +510,18 @@ Delete stamp with given *stampid*. - >>> turtle.color("blue") - >>> astamp = turtle.stamp() - >>> turtle.fd(50) - >>> turtle.clearstamp(astamp) + .. doctest:: + + >>> turtle.position() + (150.00,-0.00) + >>> turtle.color("blue") + >>> astamp = turtle.stamp() + >>> turtle.fd(50) + >>> turtle.position() + (200.00,-0.00) + >>> turtle.clearstamp(astamp) + >>> turtle.position() + (200.00,-0.00) .. function:: clearstamps(n=None) @@ -429,11 +532,21 @@ all stamps, if *n* > 0 delete first *n* stamps, else if *n* < 0 delete last *n* stamps. - >>> for i in range(8): - ... turtle.stamp(); turtle.fd(30) - >>> turtle.clearstamps(2) - >>> turtle.clearstamps(-2) - >>> turtle.clearstamps() + .. doctest:: + + >>> for i in range(8): + ... turtle.stamp(); turtle.fd(30) + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + >>> turtle.clearstamps(2) + >>> turtle.clearstamps(-2) + >>> turtle.clearstamps() .. function:: undo() @@ -441,11 +554,13 @@ Undo (repeatedly) the last turtle action(s). Number of available undo actions is determined by the size of the undobuffer. - >>> for i in range(4): - ... turtle.fd(50); turtle.lt(80) - ... - >>> for i in range(8): - ... turtle.undo() + .. doctest:: + + >>> for i in range(4): + ... turtle.fd(50); turtle.lt(80) + ... + >>> for i in range(8): + ... turtle.undo() .. function:: speed(speed=None) @@ -471,7 +586,16 @@ place. forward/back makes turtle jump and likewise left/right make the turtle turn instantly. - >>> turtle.speed(3) + .. doctest:: + + >>> turtle.speed() + 3 + >>> turtle.speed('normal') + >>> turtle.speed() + 6 + >>> turtle.speed(9) + >>> turtle.speed() + 9 Tell Turtle's state @@ -482,8 +606,10 @@ Return the turtle's current location (x,y) (as a :class:`Vec2D` vector). - >>> turtle.pos() - (0.00, 240.00) + .. doctest:: + + >>> turtle.pos() + (440.00,-0.00) .. function:: towards(x, y=None) @@ -495,32 +621,41 @@ by (x,y), the vector or the other turtle. This depends on the turtle's start orientation which depends on the mode - "standard"/"world" or "logo"). - >>> turtle.pos() - (10.00, 10.00) - >>> turtle.towards(0,0) - 225.0 + .. doctest:: + + >>> turtle.goto(10, 10) + >>> turtle.towards(0,0) + 225.0 .. function:: xcor() Return the turtle's x coordinate. - >>> reset() - >>> turtle.left(60) - >>> turtle.forward(100) - >>> print turtle.xcor() - 50.0 + .. doctest:: + + >>> turtle.home() + >>> turtle.left(50) + >>> turtle.forward(100) + >>> turtle.pos() + (64.28,76.60) + >>> print turtle.xcor() + 64.2787609687 .. function:: ycor() Return the turtle's y coordinate. - >>> reset() - >>> turtle.left(60) - >>> turtle.forward(100) - >>> print turtle.ycor() - 86.6025403784 + .. doctest:: + + >>> turtle.home() + >>> turtle.left(60) + >>> turtle.forward(100) + >>> print turtle.pos() + (50.00,86.60) + >>> print turtle.ycor() + 86.6025403784 .. function:: heading() @@ -528,9 +663,12 @@ Return the turtle's current heading (value depends on the turtle mode, see :func:`mode`). - >>> turtle.left(67) - >>> turtle.heading() - 67.0 + .. doctest:: + + >>> turtle.home() + >>> turtle.left(67) + >>> turtle.heading() + 67.0 .. function:: distance(x, y=None) @@ -541,14 +679,17 @@ Return the distance from the turtle to (x,y), the given vector, or the given other turtle, in turtle step units. - >>> turtle.pos() - (0.00, 0.00) - >>> turtle.distance(30,40) - 50.0 - >>> joe = Turtle() - >>> joe.forward(77) - >>> turtle.distance(joe) - 77.0 + .. doctest:: + + >>> turtle.home() + >>> turtle.distance(30,40) + 50.0 + >>> turtle.distance((30,40)) + 50.0 + >>> joe = Turtle() + >>> joe.forward(77) + >>> turtle.distance(joe) + 77.0 Settings for measurement @@ -561,12 +702,18 @@ Set angle measurement units, i.e. set number of "degrees" for a full circle. Default value is 360 degrees. - >>> turtle.left(90) - >>> turtle.heading() - 90 - >>> turtle.degrees(400.0) # angle measurement in gon - >>> turtle.heading() - 100 + .. doctest:: + + >>> turtle.home() + >>> turtle.left(90) + >>> turtle.heading() + 90.0 + >>> turtle.degrees(400.0) # angle measurement in gon + >>> turtle.heading() + 100.0 + >>> turtle.degrees(360) + >>> turtle.heading() + 90.0 .. function:: radians() @@ -574,11 +721,20 @@ Set the angle measurement units to radians. Equivalent to ``degrees(2*math.pi)``. - >>> turtle.heading() - 90 - >>> turtle.radians() - >>> turtle.heading() - 1.5707963267948966 + .. doctest:: + + >>> turtle.home() + >>> turtle.left(90) + >>> turtle.heading() + 90.0 + >>> turtle.radians() + >>> turtle.heading() + 1.5707963267948966 + + .. doctest:: + :hide: + + >>> turtle.degrees(360) Pen control @@ -610,9 +766,11 @@ "auto" and turtleshape is a polygon, that polygon is drawn with the same line thickness. If no argument is given, the current pensize is returned. - >>> turtle.pensize() - 1 - >>> turtle.pensize(10) # from here on lines of width 10 are drawn + .. doctest:: + + >>> turtle.pensize() + 1 + >>> turtle.pensize(10) # from here on lines of width 10 are drawn .. function:: pen(pen=None, **pendict) @@ -634,40 +792,45 @@ * "outline": positive number * "tilt": number - This dicionary can be used as argument for a subsequent call to :func:`pen` + This dictionary can be used as argument for a subsequent call to :func:`pen` to restore the former pen-state. Moreover one or more of these attributes can be provided as keyword-arguments. This can be used to set several pen attributes in one statement. - >>> turtle.pen(fillcolor="black", pencolor="red", pensize=10) - >>> turtle.pen() - {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1, - 'pencolor': 'red', 'pendown': True, 'fillcolor': 'black', - 'stretchfactor': (1,1), 'speed': 3} - >>> penstate=turtle.pen() - >>> turtle.color("yellow","") - >>> turtle.penup() - >>> turtle.pen() - {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1, - 'pencolor': 'yellow', 'pendown': False, 'fillcolor': '', - 'stretchfactor': (1,1), 'speed': 3} - >>> p.pen(penstate, fillcolor="green") - >>> p.pen() - {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1, - 'pencolor': 'red', 'pendown': True, 'fillcolor': 'green', - 'stretchfactor': (1,1), 'speed': 3} + .. doctest:: + :options: +NORMALIZE_WHITESPACE + + >>> turtle.pen(fillcolor="black", pencolor="red", pensize=10) + >>> sorted(turtle.pen().items()) + [('fillcolor', 'black'), ('outline', 1), ('pencolor', 'red'), + ('pendown', True), ('pensize', 10), ('resizemode', 'noresize'), + ('shown', True), ('speed', 9), ('stretchfactor', (1, 1)), ('tilt', 0)] + >>> penstate=turtle.pen() + >>> turtle.color("yellow", "") + >>> turtle.penup() + >>> sorted(turtle.pen().items()) + [('fillcolor', ''), ('outline', 1), ('pencolor', 'yellow'), + ('pendown', False), ('pensize', 10), ('resizemode', 'noresize'), + ('shown', True), ('speed', 9), ('stretchfactor', (1, 1)), ('tilt', 0)] + >>> turtle.pen(penstate, fillcolor="green") + >>> sorted(turtle.pen().items()) + [('fillcolor', 'green'), ('outline', 1), ('pencolor', 'red'), + ('pendown', True), ('pensize', 10), ('resizemode', 'noresize'), + ('shown', True), ('speed', 9), ('stretchfactor', (1, 1)), ('tilt', 0)] .. function:: isdown() Return ``True`` if pen is down, ``False`` if it's up. - >>> turtle.penup() - >>> turtle.isdown() - False - >>> turtle.pendown() - >>> turtle.isdown() - True + .. doctest:: + + >>> turtle.penup() + >>> turtle.isdown() + False + >>> turtle.pendown() + >>> turtle.isdown() + True Color control @@ -680,8 +843,8 @@ Four input formats are allowed: ``pencolor()`` - Return the current pencolor as color specification string, possibly in - hex-number format (see example). May be used as input to another + Return the current pencolor as color specification string or + as a tuple (see example). May be used as input to another color/pencolor/fillcolor call. ``pencolor(colorstring)`` @@ -700,11 +863,25 @@ If turtleshape is a polygon, the outline of that polygon is drawn with the newly set pencolor. - >>> turtle.pencolor("brown") - >>> tup = (0.2, 0.8, 0.55) - >>> turtle.pencolor(tup) - >>> turtle.pencolor() - "#33cc8c" + .. doctest:: + + >>> colormode() + 1.0 + >>> turtle.pencolor() + 'red' + >>> turtle.pencolor("brown") + >>> turtle.pencolor() + 'brown' + >>> tup = (0.2, 0.8, 0.55) + >>> turtle.pencolor(tup) + >>> turtle.pencolor() + (0.20000000000000001, 0.80000000000000004, 0.5490196078431373) + >>> colormode(255) + >>> turtle.pencolor() + (51, 204, 140) + >>> turtle.pencolor('#32c18f') + >>> turtle.pencolor() + (50, 193, 143) .. function:: fillcolor(*args) @@ -714,8 +891,8 @@ Four input formats are allowed: ``fillcolor()`` - Return the current fillcolor as color specification string, possibly in - hex-number format (see example). May be used as input to another + Return the current fillcolor as color specification string, possibly + in tuple format (see example). May be used as input to another color/pencolor/fillcolor call. ``fillcolor(colorstring)`` @@ -734,10 +911,20 @@ If turtleshape is a polygon, the interior of that polygon is drawn with the newly set fillcolor. - >>> turtle.fillcolor("violet") - >>> col = turtle.pencolor() - >>> turtle.fillcolor(col) - >>> turtle.fillcolor(0, .5, 0) + .. doctest:: + + >>> turtle.fillcolor("violet") + >>> turtle.fillcolor() + 'violet' + >>> col = turtle.pencolor() + >>> col + (50, 193, 143) + >>> turtle.fillcolor(col) + >>> turtle.fillcolor() + (50, 193, 143) + >>> turtle.fillcolor('#ffffff') + >>> turtle.fillcolor() + (255, 255, 255) .. function:: color(*args) @@ -749,7 +936,7 @@ ``color()`` Return the current pencolor and the current fillcolor as a pair of color - specification strings as returned by :func:`pencolor` and + specification strings or tuples as returned by :func:`pencolor` and :func:`fillcolor`. ``color(colorstring)``, ``color((r,g,b))``, ``color(r,g,b)`` @@ -763,13 +950,14 @@ If turtleshape is a polygon, outline and interior of that polygon is drawn with the newly set colors. - >>> turtle.color("red", "green") - >>> turtle.color() - ("red", "green") - >>> colormode(255) - >>> color((40, 80, 120), (160, 200, 240)) - >>> color() - ("#285078", "#a0c8f0") + .. doctest:: + + >>> turtle.color("red", "green") + >>> turtle.color() + ('red', 'green') + >>> color("#285078", "#a0c8f0") + >>> color() + ((40, 80, 120), (160, 200, 240)) See also: Screen method :func:`colormode`. @@ -778,6 +966,11 @@ Filling ~~~~~~~ +.. doctest:: + :hide: + + >>> turtle.home() + .. function:: fill(flag) :param flag: True/False (or 1/0 respectively) @@ -786,29 +979,33 @@ ``fill(False)`` when done. When used without argument: return fillstate (``True`` if filling, ``False`` else). - >>> turtle.fill(True) - >>> for _ in range(3): - ... turtle.forward(100) - ... turtle.left(120) - ... - >>> turtle.fill(False) + .. doctest:: + + >>> turtle.fill(True) + >>> for _ in range(3): + ... turtle.forward(100) + ... turtle.left(120) + ... + >>> turtle.fill(False) .. function:: begin_fill() Call just before drawing a shape to be filled. Equivalent to ``fill(True)``. - >>> turtle.color("black", "red") - >>> turtle.begin_fill() - >>> turtle.circle(60) - >>> turtle.end_fill() - .. function:: end_fill() Fill the shape drawn after the last call to :func:`begin_fill`. Equivalent to ``fill(False)``. + .. doctest:: + + >>> turtle.color("black", "red") + >>> turtle.begin_fill() + >>> turtle.circle(80) + >>> turtle.end_fill() + More drawing control ~~~~~~~~~~~~~~~~~~~~ @@ -818,15 +1015,19 @@ Delete the turtle's drawings from the screen, re-center the turtle and set variables to the default values. - >>> turtle.position() - (0.00,-22.00) - >>> turtle.heading() - 100.0 - >>> turtle.reset() - >>> turtle.position() - (0.00,0.00) - >>> turtle.heading() - 0.0 + .. doctest:: + + >>> turtle.goto(0,-22) + >>> turtle.left(100) + >>> turtle.position() + (0.00,-22.00) + >>> turtle.heading() + 100.0 + >>> turtle.reset() + >>> turtle.position() + (0.00,0.00) + >>> turtle.heading() + 0.0 .. function:: clear() @@ -857,15 +1058,6 @@ Visibility ~~~~~~~~~~ -.. function:: showturtle() - st() - - Make the turtle visible. - - >>> turtle.hideturtle() - >>> turtle.showturtle() - - .. function:: hideturtle() ht() @@ -873,7 +1065,19 @@ middle of doing some complex drawing, because hiding the turtle speeds up the drawing observably. - >>> turtle.hideturtle() + .. doctest:: + + >>> turtle.hideturtle() + + +.. function:: showturtle() + st() + + Make the turtle visible. + + .. doctest:: + + >>> turtle.showturtle() .. function:: isvisible() @@ -881,8 +1085,11 @@ Return True if the Turtle is shown, False if it's hidden. >>> turtle.hideturtle() - >>> print turtle.isvisible(): + >>> turtle.isvisible() False + >>> turtle.showturtle() + >>> turtle.isvisible() + True Appearance @@ -898,11 +1105,13 @@ "turtle", "circle", "square", "triangle", "classic". To learn about how to deal with shapes see Screen method :func:`register_shape`. - >>> turtle.shape() - "arrow" - >>> turtle.shape("turtle") - >>> turtle.shape() - "turtle" + .. doctest:: + + >>> turtle.shape() + 'classic' + >>> turtle.shape("turtle") + >>> turtle.shape() + 'turtle' .. function:: resizemode(rmode=None) @@ -921,9 +1130,13 @@ resizemode("user") is called by :func:`shapesize` when used with arguments. - >>> turtle.resizemode("noresize") - >>> turtle.resizemode() - "noresize" + .. doctest:: + + >>> turtle.resizemode() + 'noresize' + >>> turtle.resizemode("auto") + >>> turtle.resizemode() + 'auto' .. function:: shapesize(stretch_wid=None, stretch_len=None, outline=None) @@ -939,9 +1152,17 @@ stretchfactor in direction of its orientation, *outline* determines the width of the shapes's outline. - >>> turtle.resizemode("user") - >>> turtle.shapesize(5, 5, 12) - >>> turtle.shapesize(outline=8) + .. doctest:: + + >>> turtle.shapesize() + (1, 1, 1) + >>> turtle.resizemode("user") + >>> turtle.shapesize(5, 5, 12) + >>> turtle.shapesize() + (5, 5, 12) + >>> turtle.shapesize(outline=8) + >>> turtle.shapesize() + (5, 5, 8) .. function:: tilt(angle) @@ -951,12 +1172,15 @@ Rotate the turtleshape by *angle* from its current tilt-angle, but do *not* change the turtle's heading (direction of movement). - >>> turtle.shape("circle") - >>> turtle.shapesize(5,2) - >>> turtle.tilt(30) - >>> turtle.fd(50) - >>> turtle.tilt(30) - >>> turtle.fd(50) + .. doctest:: + + >>> turtle.reset() + >>> turtle.shape("circle") + >>> turtle.shapesize(5,2) + >>> turtle.tilt(30) + >>> turtle.fd(50) + >>> turtle.tilt(30) + >>> turtle.fd(50) .. function:: settiltangle(angle) @@ -967,14 +1191,15 @@ regardless of its current tilt-angle. *Do not* change the turtle's heading (direction of movement). - >>> turtle.shape("circle") - >>> turtle.shapesize(5,2) - >>> turtle.settiltangle(45) - >>> stamp() - >>> turtle.fd(50) - >>> turtle.settiltangle(-45) - >>> stamp() - >>> turtle.fd(50) + .. doctest:: + + >>> turtle.reset() + >>> turtle.shape("circle") + >>> turtle.shapesize(5,2) + >>> turtle.settiltangle(45) + >>> turtle.fd(50) + >>> turtle.settiltangle(-45) + >>> turtle.fd(50) .. function:: tiltangle() @@ -982,11 +1207,14 @@ Return the current tilt-angle, i.e. the angle between the orientation of the turtleshape and the heading of the turtle (its direction of movement). - >>> turtle.shape("circle") - >>> turtle.shapesize(5,2) - >>> turtle.tilt(45) - >>> turtle.tiltangle() - 45 + .. doctest:: + + >>> turtle.reset() + >>> turtle.shape("circle") + >>> turtle.shapesize(5,2) + >>> turtle.tilt(45) + >>> turtle.tiltangle() + 45.0 Using events @@ -1004,11 +1232,13 @@ existing bindings are removed. Example for the anonymous turtle, i.e. the procedural way: - >>> def turn(x, y): - ... left(180) - ... - >>> onclick(turn) # Now clicking into the turtle will turn it. - >>> onclick(None) # event-binding will be removed + .. doctest:: + + >>> def turn(x, y): + ... left(180) + ... + >>> onclick(turn) # Now clicking into the turtle will turn it. + >>> onclick(None) # event-binding will be removed .. function:: onrelease(fun, btn=1, add=None) @@ -1022,15 +1252,17 @@ Bind *fun* to mouse-button-release events on this turtle. If *fun* is ``None``, existing bindings are removed. - >>> class MyTurtle(Turtle): - ... def glow(self,x,y): - ... self.fillcolor("red") - ... def unglow(self,x,y): - ... self.fillcolor("") - ... - >>> turtle = MyTurtle() - >>> turtle.onclick(turtle.glow) # clicking on turtle turns fillcolor red, - >>> turtle.onrelease(turtle.unglow) # releasing turns it to transparent. + .. doctest:: + + >>> class MyTurtle(Turtle): + ... def glow(self,x,y): + ... self.fillcolor("red") + ... def unglow(self,x,y): + ... self.fillcolor("") + ... + >>> turtle = MyTurtle() + >>> turtle.onclick(turtle.glow) # clicking on turtle turns fillcolor red, + >>> turtle.onrelease(turtle.unglow) # releasing turns it to transparent. .. function:: ondrag(fun, btn=1, add=None) @@ -1047,9 +1279,12 @@ Remark: Every sequence of mouse-move-events on a turtle is preceded by a mouse-click event on that turtle. - >>> turtle.ondrag(turtle.goto) - # Subsequently, clicking and dragging the Turtle will move it across - # the screen thereby producing handdrawings (if pen is down). + .. doctest:: + + >>> turtle.ondrag(turtle.goto) + + Subsequently, clicking and dragging the Turtle will move it across + the screen thereby producing handdrawings (if pen is down). Special Turtle methods @@ -1071,8 +1306,18 @@ Return the last recorded polygon. - >>> p = turtle.get_poly() - >>> turtle.register_shape("myFavouriteShape", p) + .. doctest:: + + >>> turtle.home() + >>> turtle.begin_poly() + >>> turtle.fd(100) + >>> turtle.left(20) + >>> turtle.fd(30) + >>> turtle.left(60) + >>> turtle.fd(50) + >>> turtle.end_poly() + >>> p = turtle.get_poly() + >>> register_shape("myFavouriteShape", p) .. function:: clone() @@ -1080,8 +1325,10 @@ Create and return a clone of the turtle with same position, heading and turtle properties. - >>> mick = Turtle() - >>> joe = mick.clone() + .. doctest:: + + >>> mick = Turtle() + >>> joe = mick.clone() .. function:: getturtle() @@ -1089,12 +1336,12 @@ Return the Turtle object itself. Only reasonable use: as a function to return the "anonymous turtle": - >>> pet = getturtle() - >>> pet.fd(50) - >>> pet - - >>> turtles() - [] + .. doctest:: + + >>> pet = getturtle() + >>> pet.fd(50) + >>> pet + .. function:: getscreen() @@ -1102,10 +1349,12 @@ Return the :class:`TurtleScreen` object the turtle is drawing on. TurtleScreen methods can then be called for that object. - >>> ts = turtle.getscreen() - >>> ts - - >>> ts.bgcolor("pink") + .. doctest:: + + >>> ts = turtle.getscreen() + >>> ts + + >>> ts.bgcolor("pink") .. function:: setundobuffer(size) @@ -1117,15 +1366,19 @@ that can be undone by the :func:`undo` method/function. If *size* is ``None``, the undobuffer is disabled. - >>> turtle.setundobuffer(42) + .. doctest:: + + >>> turtle.setundobuffer(42) .. function:: undobufferentries() Return number of entries in the undobuffer. - >>> while undobufferentries(): - ... undo() + .. doctest:: + + >>> while undobufferentries(): + ... undo() .. function:: tracer(flag=None, delay=None) @@ -1158,16 +1411,20 @@ For example: - >>> s = Shape("compound") - >>> poly1 = ((0,0),(10,-5),(0,10),(-10,-5)) - >>> s.addcomponent(poly1, "red", "blue") - >>> poly2 = ((0,0),(10,-5),(-10,-5)) - >>> s.addcomponent(poly2, "blue", "red") + .. doctest:: + + >>> s = Shape("compound") + >>> poly1 = ((0,0),(10,-5),(0,10),(-10,-5)) + >>> s.addcomponent(poly1, "red", "blue") + >>> poly2 = ((0,0),(10,-5),(-10,-5)) + >>> s.addcomponent(poly2, "blue", "red") 3. Now add the Shape to the Screen's shapelist and use it: - >>> register_shape("myshape", s) - >>> shape("myshape") + .. doctest:: + + >>> register_shape("myshape", s) + >>> shape("myshape") .. note:: @@ -1183,6 +1440,10 @@ Most of the examples in this section refer to a TurtleScreen instance called ``screen``. +.. doctest:: + :hide: + + >>> screen = Screen() Window control -------------- @@ -1194,12 +1455,14 @@ Set or return background color of the TurtleScreen. - >>> screen.bgcolor("orange") - >>> screen.bgcolor() - "orange" - >>> screen.bgcolor(0.5,0,0.5) - >>> screen.bgcolor() - "#800080" + .. doctest:: + + >>> screen.bgcolor("orange") + >>> screen.bgcolor() + 'orange' + >>> screen.bgcolor("#800080") + >>> screen.bgcolor() + (128, 0, 128) .. function:: bgpic(picname=None) @@ -1209,13 +1472,13 @@ Set background image or return name of current backgroundimage. If *picname* is a filename, set the corresponding image as background. If *picname* is ``"nopic"``, delete background image, if present. If *picname* is ``None``, - return the filename of the current backgroundimage. + return the filename of the current backgroundimage. :: - >>> screen.bgpic() - "nopic" - >>> screen.bgpic("landscape.gif") - >>> screen.bgpic() - "landscape.gif" + >>> screen.bgpic() + 'nopic' + >>> screen.bgpic("landscape.gif") + >>> screen.bgpic() + "landscape.gif" .. function:: clear() @@ -1254,8 +1517,13 @@ method, one can make visible those parts of a drawing which were outside the canvas before. - >>> turtle.screensize(2000,1500) - # e.g. to search for an erroneously escaped turtle ;-) + >>> screen.screensize() + (400, 300) + >>> screen.screensize(2000,1500) + >>> screen.screensize() + (2000, 1500) + + e.g. to search for an erroneously escaped turtle ;-) .. function:: setworldcoordinates(llx, lly, urx, ury) @@ -1272,13 +1540,22 @@ **ATTENTION**: in user-defined coordinate systems angles may appear distorted. - >>> screen.reset() - >>> screen.setworldcoordinates(-50,-7.5,50,7.5) - >>> for _ in range(72): - ... left(10) - ... - >>> for _ in range(8): - ... left(45); fd(2) # a regular octagon + .. doctest:: + + >>> screen.reset() + >>> screen.setworldcoordinates(-50,-7.5,50,7.5) + >>> for _ in range(72): + ... left(10) + ... + >>> for _ in range(8): + ... left(45); fd(2) # a regular octagon + + .. doctest:: + :hide: + + >>> screen.reset() + >>> for t in turtles(): + ... t.reset() Animation control @@ -1294,9 +1571,13 @@ Optional argument: - >>> screen.delay(15) - >>> screen.delay() - 15 + .. doctest:: + + >>> screen.delay() + 10 + >>> screen.delay(5) + >>> screen.delay() + 5 .. function:: tracer(n=None, delay=None) @@ -1309,12 +1590,14 @@ used to accelerate the drawing of complex graphics.) Second argument sets delay value (see :func:`delay`). - >>> screen.tracer(8, 25) - >>> dist = 2 - >>> for i in range(200): - ... fd(dist) - ... rt(90) - ... dist += 2 + .. doctest:: + + >>> screen.tracer(8, 25) + >>> dist = 2 + >>> for i in range(200): + ... fd(dist) + ... rt(90) + ... dist += 2 .. function:: update() @@ -1342,12 +1625,14 @@ are removed. Remark: in order to be able to register key-events, TurtleScreen must have the focus. (See method :func:`listen`.) - >>> def f(): - ... fd(50) - ... lt(60) - ... - >>> screen.onkey(f, "Up") - >>> screen.listen() + .. doctest:: + + >>> def f(): + ... fd(50) + ... lt(60) + ... + >>> screen.onkey(f, "Up") + >>> screen.listen() .. function:: onclick(fun, btn=1, add=None) @@ -1365,10 +1650,11 @@ Example for a TurtleScreen instance named ``screen`` and a Turtle instance named turtle: - >>> screen.onclick(turtle.goto) - # Subsequently clicking into the TurtleScreen will - # make the turtle move to the clicked point. - >>> screen.onclick(None) # remove event binding again + .. doctest:: + + >>> screen.onclick(turtle.goto) # Subsequently clicking into the TurtleScreen will + >>> # make the turtle move to the clicked point. + >>> screen.onclick(None) # remove event binding again .. note:: This TurtleScreen method is available as a global function only under the @@ -1383,14 +1669,16 @@ Install a timer that calls *fun* after *t* milliseconds. - >>> running = True - >>> def f(): - if running: - fd(50) - lt(60) - screen.ontimer(f, 250) - >>> f() ### makes the turtle marching around - >>> running = False + .. doctest:: + + >>> running = True + >>> def f(): + ... if running: + ... fd(50) + ... lt(60) + ... screen.ontimer(f, 250) + >>> f() ### makes the turtle march around + >>> running = False Settings and special methods @@ -1415,9 +1703,11 @@ "logo" upward (north) clockwise ============ ========================= =================== - >>> mode("logo") # resets turtle heading to north - >>> mode() - "logo" + .. doctest:: + + >>> mode("logo") # resets turtle heading to north + >>> mode() + 'logo' .. function:: colormode(cmode=None) @@ -1427,10 +1717,19 @@ Return the colormode or set it to 1.0 or 255. Subsequently *r*, *g*, *b* values of color triples have to be in the range 0..\ *cmode*. - >>> screen.colormode() - 1.0 - >>> screen.colormode(255) - >>> turtle.pencolor(240,160,80) + .. doctest:: + + >>> screen.colormode(1) + >>> turtle.pencolor(240, 160, 80) + Traceback (most recent call last): + ... + TurtleGraphicsError: bad color sequence: (240, 160, 80) + >>> screen.colormode() + 1.0 + >>> screen.colormode(255) + >>> screen.colormode() + 255 + >>> turtle.pencolor(240,160,80) .. function:: getcanvas() @@ -1438,17 +1737,21 @@ Return the Canvas of this TurtleScreen. Useful for insiders who know what to do with a Tkinter Canvas. - >>> cv = screen.getcanvas() - >>> cv - + .. doctest:: + + >>> cv = screen.getcanvas() + >>> cv + .. function:: getshapes() Return a list of names of all currently available turtle shapes. - >>> screen.getshapes() - ["arrow", "blank", "circle", ..., "turtle"] + .. doctest:: + + >>> screen.getshapes() + ['arrow', 'blank', 'circle', ..., 'turtle'] .. function:: register_shape(name, shape=None) @@ -1457,7 +1760,9 @@ There are three different ways to call this function: (1) *name* is the name of a gif-file and *shape* is ``None``: Install the - corresponding image shape. + corresponding image shape. :: + + >>> screen.register_shape("turtle.gif") .. note:: Image shapes *do not* rotate when turning the turtle, so they do not @@ -1466,38 +1771,41 @@ (2) *name* is an arbitrary string and *shape* is a tuple of pairs of coordinates: Install the corresponding polygon shape. + .. doctest:: + + >>> screen.register_shape("triangle", ((5,-3), (0,5), (-5,-3))) + (3) *name* is an arbitrary string and shape is a (compound) :class:`Shape` object: Install the corresponding compound shape. Add a turtle shape to TurtleScreen's shapelist. Only thusly registered shapes can be used by issuing the command ``shape(shapename)``. - >>> screen.register_shape("turtle.gif") - >>> screen.register_shape("triangle", ((5,-3), (0,5), (-5,-3))) - .. function:: turtles() Return the list of turtles on the screen. - >>> for turtle in screen.turtles() - ... turtle.color("red") + .. doctest:: + + >>> for turtle in screen.turtles(): + ... turtle.color("red") .. function:: window_height() - Return the height of the turtle window. + Return the height of the turtle window. :: - >>> screen.window_height() - 480 + >>> screen.window_height() + 480 .. function:: window_width() - Return the width of the turtle window. + Return the width of the turtle window. :: - >>> screen.window_width() - 640 + >>> screen.window_width() + 640 .. _screenspecific: @@ -1539,10 +1847,12 @@ edge of the screen, if negative from the bottom edge, if None, center window vertically - >>> screen.setup (width=200, height=200, startx=0, starty=0) - # sets window to 200x200 pixels, in upper left of screen - >>> screen.setup(width=.75, height=0.5, startx=None, starty=None) - # sets window to 75% of screen by 50% of screen and centers + .. doctest:: + + >>> screen.setup (width=200, height=200, startx=0, starty=0) + >>> # sets window to 200x200 pixels, in upper left of screen + >>> screen.setup(width=.75, height=0.5, startx=None, starty=None) + >>> # sets window to 75% of screen by 50% of screen and centers .. function:: title(titlestring) @@ -1552,7 +1862,9 @@ Set title of turtle window to *titlestring*. - >>> screen.title("Welcome to the turtle zoo!") + .. doctest:: + + >>> screen.title("Welcome to the turtle zoo!") The public classes of the module :mod:`turtle` @@ -1565,14 +1877,14 @@ :param canvas: a :class:`Tkinter.Canvas`, a :class:`ScrolledCanvas` or a :class:`TurtleScreen` - Create a turtle. The turtle has all methods described above as "methods of - Turtle/RawTurtle". + Create a turtle. The turtle has all methods described above as "methods of + Turtle/RawTurtle". .. class:: Turtle() - Subclass of RawTurtle, has the same interface but draws on a default - :class:`Screen` object created automatically when needed for the first time. + Subclass of RawTurtle, has the same interface but draws on a default + :class:`Screen` object created automatically when needed for the first time. .. class:: TurtleScreen(cv) @@ -1620,10 +1932,12 @@ Example: - >>> poly = ((0,0),(10,-5),(0,10),(-10,-5)) - >>> s = Shape("compound") - >>> s.addcomponent(poly, "red", "blue") - # .. add more components and then use register_shape() + .. doctest:: + + >>> poly = ((0,0),(10,-5),(0,10),(-10,-5)) + >>> s = Shape("compound") + >>> s.addcomponent(poly, "red", "blue") + >>> # ... add more components and then use register_shape() See :ref:`compoundshapes`. @@ -1889,3 +2203,22 @@ +----------------+------------------------------+-----------------------+ Have fun! + +.. doctest:: + :hide: + + >>> for turtle in turtles(): + ... turtle.reset() + >>> turtle.penup() + >>> turtle.goto(-200,25) + >>> turtle.pendown() + >>> turtle.write("No one expects the Spanish Inquisition!", + ... font=("Arial", 20, "normal")) + >>> turtle.penup() + >>> turtle.goto(-100,-50) + >>> turtle.pendown() + >>> turtle.write("Our two chief Turtles are...", + ... font=("Arial", 16, "normal")) + >>> turtle.penup() + >>> turtle.goto(-450,-75) + >>> turtle.write(str(turtles())) From python-checkins at python.org Thu Apr 30 17:56:46 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 30 Apr 2009 17:56:46 +0200 (CEST) Subject: [Python-checkins] r72150 - peps/trunk/pep-0383.txt Message-ID: <20090430155646.DFD201E4063@bag.python.org> Author: martin.v.loewis Date: Thu Apr 30 17:56:46 2009 New Revision: 72150 Log: Explain why \0 escaping is bad. Modified: peps/trunk/pep-0383.txt Modified: peps/trunk/pep-0383.txt ============================================================================== --- peps/trunk/pep-0383.txt (original) +++ peps/trunk/pep-0383.txt Thu Apr 30 17:56:46 2009 @@ -149,6 +149,14 @@ * use different escape schemes, such as escaping with a NUL character, or mapping to infrequent characters. +Of these proposals, the approach of escaping each byte XX +with the sequence U+0000 U+00XX has the disadvantage that +encoding to UTF-8 will introduce a NUL byte in the UTF-8 +sequence. As a consequence, C libraries may interpret this +as a string termination, even though the string continues. +In particular, the gtk libraries will truncate text in this +case; other libraries may show similar problems. + References ========== From python-checkins at python.org Thu Apr 30 18:24:33 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 30 Apr 2009 18:24:33 +0200 (CEST) Subject: [Python-checkins] r72151 - peps/trunk/pep-0383.txt Message-ID: <20090430162433.4CF431E4063@bag.python.org> Author: martin.v.loewis Date: Thu Apr 30 18:24:32 2009 New Revision: 72151 Log: Recommend that external libraries also support the PEP. Modified: peps/trunk/pep-0383.txt Modified: peps/trunk/pep-0383.txt ============================================================================== --- peps/trunk/pep-0383.txt (original) +++ peps/trunk/pep-0383.txt Thu Apr 30 18:24:32 2009 @@ -97,6 +97,9 @@ affected by this specification. They are neither enhanced nor deprecated. +External libraries that operate on file names (such as GUI file +chosers) should also encode them according to the PEP. + Discussion ========== From python-checkins at python.org Thu Apr 30 18:25:22 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 30 Apr 2009 18:25:22 +0200 (CEST) Subject: [Python-checkins] r72152 - peps/trunk/pep-0383.txt Message-ID: <20090430162522.75EAD1E4063@bag.python.org> Author: martin.v.loewis Date: Thu Apr 30 18:25:22 2009 New Revision: 72152 Log: Mark PEP as accepted. Modified: peps/trunk/pep-0383.txt Modified: peps/trunk/pep-0383.txt ============================================================================== --- peps/trunk/pep-0383.txt (original) +++ peps/trunk/pep-0383.txt Thu Apr 30 18:25:22 2009 @@ -3,7 +3,7 @@ Version: $Revision$ Last-Modified: $Date$ Author: Martin v. L?wis -Status: Draft +Status: Accepted Type: Standards Track Content-Type: text/x-rst Created: 22-Apr-2009 From python-checkins at python.org Thu Apr 30 19:21:17 2009 From: python-checkins at python.org (martin.v.loewis) Date: Thu, 30 Apr 2009 19:21:17 +0200 (CEST) Subject: [Python-checkins] r72153 - python/branches/pep-0383 Message-ID: <20090430172117.8195B1E4036@bag.python.org> Author: martin.v.loewis Date: Thu Apr 30 19:21:17 2009 New Revision: 72153 Log: Branch to implement PEP 383. Added: python/branches/pep-0383/ - copied from r72152, /python/branches/py3k/ From buildbot at python.org Thu Apr 30 22:28:05 2009 From: buildbot at python.org (buildbot at python.org) Date: Thu, 30 Apr 2009 20:28:05 +0000 Subject: [Python-checkins] buildbot failure in x86 XP-4 3.0 Message-ID: <20090430202805.944D61E4021@bag.python.org> The Buildbot has detected a new failure of x86 XP-4 3.0. Full details are available at: http://www.python.org/dev/buildbot/all/x86%20XP-4%203.0/builds/263 Buildbot URL: http://www.python.org/dev/buildbot/all/ Buildslave for this Build: bolen-windows Build Reason: The web-page 'rebuild' button was pressed by 'David Bolen': Freed up problem with Tools directory removal Build Source Stamp: [branch branches/release30-maint] HEAD Blamelist: eric.smith BUILD FAILED: failed test Excerpt from the test logfile: 1 test failed: test_memoryio ====================================================================== FAIL: test_newline_none (test.test_memoryio.PyStringIOTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\3.0.bolen-windows\build\lib\test\test_memoryio.py", line 381, in test_newline_none self.assertEqual(memio.readlines(), ["hello\n", "hi\n"]) AssertionError: ['hello\n', '\n', 'hi\n', '\n'] != ['hello\n', 'hi\n'] ====================================================================== FAIL: test_newline_none (test.test_memoryio.CStringIOTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\cygwin\home\db3l\buildarea\3.0.bolen-windows\build\lib\test\test_memoryio.py", line 381, in test_newline_none self.assertEqual(memio.readlines(), ["hello\n", "hi\n"]) AssertionError: ['hello\n', '\n', '\n', 'hi\n', '\n', '\n'] != ['hello\n', 'hi\n'] sincerely, -The Buildbot From nnorwitz at gmail.com Thu Apr 30 23:26:04 2009 From: nnorwitz at gmail.com (Neal Norwitz) Date: Thu, 30 Apr 2009 17:26:04 -0400 Subject: [Python-checkins] Python Regression Test Failures refleak (1) Message-ID: <20090430212604.GA3476@python.psfb.org> More important issues: ---------------------- test_pydoc leaked [-21, 0, 0] references, sum=-21 Less important issues: ---------------------- test_cmd_line leaked [25, 0, 0] references, sum=25 test_smtplib leaked [0, 0, -88] references, sum=-88 test_socketserver leaked [-84, 0, 0] references, sum=-84 test_ssl leaked [0, -403, 403] references, sum=0 test_sys leaked [42, -42, 42] references, sum=42 test_threading leaked [48, 48, 44] references, sum=140 test_urllib2_localnet leaked [3, 3, 286] references, sum=292 From python-checkins at python.org Thu Apr 30 23:27:18 2009 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 30 Apr 2009 23:27:18 +0200 (CEST) Subject: [Python-checkins] r72154 - peps/trunk/pep-0375.txt Message-ID: <20090430212718.30A121E4170@bag.python.org> Author: benjamin.peterson Date: Thu Apr 30 23:27:17 2009 New Revision: 72154 Log: move beta back Modified: peps/trunk/pep-0375.txt Modified: peps/trunk/pep-0375.txt ============================================================================== --- peps/trunk/pep-0375.txt (original) +++ peps/trunk/pep-0375.txt Thu Apr 30 23:27:17 2009 @@ -36,7 +36,7 @@ - 3.1a1 March 7, 2009 - 3.1a2 April 4, 2009 -- 3.1b1 May 2, 2009 +- 3.1b1 May 6, 2009 - 3.1rc1 May 30, 2009 - 3.1rc2 June 13, 2009 - 3.1 final June 27, 2009